package stack import ( "log" "netstack/sleep" "netstack/tcpip" "netstack/tcpip/ports" "sync" ) // TODO 需要解读 type TCPProbeFunc func(s TcpEndpointState) // TODO 需要解读 type TcpEndpointState struct { // TODO 需要添加 } type transportProtocolState struct { } // Stack 是一个网络堆栈,具有所有支持的协议、NIC 和路由表。 type Stack struct { transportProtocols map[tcpip.TransportProtocolNumber]*transportProtocolState // 各种传输层协议 networkProtocols map[tcpip.NetworkProtocolNumber]NetworkProtocol // 各种网络层协议 linkAddrResolvers map[tcpip.NetworkProtocolNumber]LinkAddressResolver // 各种传输层协议 demux *transportDemuxer // 传输层的复用器 stats tcpip.Stats // 网络栈的状态监测器 linkAddrCache *linkAddrCache // 链路层地址的缓存 mu sync.RWMutex nics map[tcpip.NICID]*NIC // 所有的网卡设备 forwarding bool // 是否正在转发 // route is the route table passed in by the user via SetRouteTable(), // it is used by FindRoute() to build a route for a specific // destination. routeTable []tcpip.Route // 路由表 *ports.PortManager // 端口管理器 // If not nil, then any new endpoints will have this probe function // invoked everytime they receive a TCP segment. tcpProbeFunc TCPProbeFunc // clock is used to generate user-visible times. clock tcpip.Clock } // Options contains optional Stack configuration. type Options struct { // Clock is an optional clock source used for timestampping packets. // // If no Clock is specified, the clock source will be time.Now. Clock tcpip.Clock // Stats are optional statistic counters. Stats tcpip.Stats } func New(network []string, transport []string, opts Options) *Stack { clock := opts.Clock if clock == nil { clock = &tcpip.StdClock{} } s := &Stack{ transportProtocols: make(map[tcpip.TransportProtocolNumber]*transportProtocolState), networkProtocols: make(map[tcpip.NetworkProtocolNumber]NetworkProtocol), linkAddrResolvers: make(map[tcpip.NetworkProtocolNumber]LinkAddressResolver), nics: make(map[tcpip.NICID]*NIC), //linkAddrCache: newLinkAddrCache(ageLimit, resolutionTimeout, resolutionAttempts), //PortManager: ports.NewPortManager(), clock: clock, stats: opts.Stats.FillIn(), } // 添加指定的网络端协议 必须已经在init中注册过 for _, name := range network { // 先检查这个网络协议是否注册过工厂方法 netProtoFactory, ok := networkProtocols[name] if !ok { continue // 没有就略过 } netProto := netProtoFactory() // 制造一个该型号协议的示实例 s.networkProtocols[netProto.Number()] = netProto // 注册该型号的网络协议 } // 添加指定的传输层协议 必已经在init中注册过 // TODO return s } func (s *Stack) Stats() tcpip.Stats { return s.stats } // SetForwarding enables or disables the packet forwarding between NICs. func (s *Stack) SetForwarding(enable bool) { // TODO: Expose via /proc/sys/net/ipv4/ip_forward. s.mu.Lock() s.forwarding = enable s.mu.Unlock() } // Forwarding returns if the packet forwarding between NICs is enabled. func (s *Stack) Forwarding() bool { // TODO: Expose via /proc/sys/net/ipv4/ip_forward. s.mu.RLock() defer s.mu.RUnlock() return s.forwarding } // SetRouteTable assigns the route table to be used by this stack. It // specifies which NIC to use for given destination address ranges. func (s *Stack) SetRouteTable(table []tcpip.Route) { s.mu.Lock() defer s.mu.Unlock() s.routeTable = table } // GetRouteTable returns the route table which is currently in use. func (s *Stack) GetRouteTable() []tcpip.Route { s.mu.Lock() defer s.mu.Unlock() return append([]tcpip.Route(nil), s.routeTable...) } func (s *Stack) CreateNIC(id tcpip.NICID, linkEP tcpip.LinkEndpointID) *tcpip.Error { return s.createNIC(id, "", linkEP, true) } // 新建一个网卡对象,并且激活它 激活就是准备好熊网卡中读取和写入数据 func (s *Stack) createNIC(id tcpip.NICID, name string, linkEP tcpip.LinkEndpointID, enable bool) *tcpip.Error { ep := FindLinkEndpoint(linkEP) if ep == nil { return tcpip.ErrBadLinkEndpoint } s.mu.Lock() defer s.mu.Unlock() // Make sure id is unique if _, ok := s.nics[id]; ok { return tcpip.ErrDuplicateNICID } n := newNIC(s, id, name, ep) s.nics[id] = n if enable { n.attachLinkEndpoint() } return nil } // 给网卡添加ip地址 func (s *Stack) AddAddress(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber, addr tcpip.Address) *tcpip.Error { return s.AddAddressWithOptions(id, protocol, addr, CanBePrimaryEndpoint) } func (s *Stack) AddAddressWithOptions(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber, addr tcpip.Address, peb PrimaryEndpointBehavior) *tcpip.Error { s.mu.RLock() defer s.mu.RUnlock() nic := s.nics[id] if nic == nil { return tcpip.ErrUnknownNICID } return nic.AddAddressWithOptions(protocol, addr, peb) } // AddSubnet adds a subnet range to the specified NIC. func (s *Stack) AddSubnet(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber, subnet tcpip.Subnet) *tcpip.Error { s.mu.RLock() defer s.mu.RUnlock() if nic, ok := s.nics[id]; ok { nic.AddSubnet(protocol, subnet) return nil } return tcpip.ErrUnknownNICID } // RemoveSubnet removes the subnet range from the specified NIC. func (s *Stack) RemoveSubnet(id tcpip.NICID, subnet tcpip.Subnet) *tcpip.Error { s.mu.RLock() defer s.mu.RUnlock() if nic, ok := s.nics[id]; ok { nic.RemoveSubnet(subnet) return nil } return tcpip.ErrUnknownNICID } // ContainsSubnet reports whether the specified NIC contains the specified // subnet. func (s *Stack) ContainsSubnet(id tcpip.NICID, subnet tcpip.Subnet) (bool, *tcpip.Error) { s.mu.RLock() defer s.mu.RUnlock() if nic, ok := s.nics[id]; ok { return nic.ContainsSubnet(subnet), nil } return false, tcpip.ErrUnknownNICID } // 路由查找实现,比如当tcp建立连接时,会用该函数得到路由信息 func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, netProto tcpip.NetworkProtocolNumber) (Route, *tcpip.Error) { s.mu.RLock() defer s.mu.RUnlock() for i := range s.routeTable { //if (id != 0 && id != s.routeTable[i].NIC) || // (len(remoteAddr) != 0 && !s.routeTable[i].Match(remoteAddr)) { // continue //} nic := s.nics[s.routeTable[i].NIC] if nic == nil { continue } var ref *referencedNetworkEndpoint if len(localAddr) != 0 { ref = nic.findEndpoint(netProto, localAddr, CanBePrimaryEndpoint) } else { ref = nic.primaryEndpoint(netProto) } if ref == nil { continue } if len(remoteAddr) == 0 { // If no remote address was provided, then the route // provided will refer to the link local address. remoteAddr = ref.ep.ID().LocalAddress // 发回自己? TODO } r := makeRoute(netProto, ref.ep.ID().LocalAddress, remoteAddr, nic.linkEP.LinkAddress(), ref) r.NextHop = s.routeTable[i].Gateway log.Println(r.LocalLinkAddress, r.LocalAddress, r.RemoteLinkAddress, r.RemoteAddress, r.NextHop) return r, nil } return Route{}, tcpip.ErrNoRoute } func (s *Stack) CheckLocalAddress(nicid tcpip.NICID, protocol tcpip.NetworkProtocolNumber, addr tcpip.Address) tcpip.NICID { return 0 } func (s *Stack) AddLinkAddress(nicid tcpip.NICID, addr tcpip.Address, linkAddr tcpip.LinkAddress) { } func (s *Stack) GetLinkAddress(nicid tcpip.NICID, addr, localAddr tcpip.Address, protocol tcpip.NetworkProtocolNumber, w *sleep.Waker) (tcpip.LinkAddress, <-chan struct{}, *tcpip.Error) { return "", nil, nil } func (s *Stack) RemoveWaker(nicid tcpip.NICID, addr tcpip.Address, waker *sleep.Waker) { }