mirror of
				https://github.com/impact-eintr/netstack.git
				synced 2025-10-26 22:20:21 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			284 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			284 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package stack
 | ||
| 
 | ||
| import (
 | ||
| 	"netstack/sleep"
 | ||
| 	"netstack/tcpip"
 | ||
| 	"netstack/tcpip/buffer"
 | ||
| 	"netstack/waiter"
 | ||
| 	"sync"
 | ||
| )
 | ||
| 
 | ||
| const (
 | ||
| 	CapabilityChecksumOffload LinkEndpointCapabilities = 1 << iota
 | ||
| 	CapabilityResolutionRequired
 | ||
| 	CapabilitySaveRestore
 | ||
| 	CapabilityDisconnectOK
 | ||
| 	CapabilityLoopback
 | ||
| )
 | ||
| 
 | ||
| // ====================链路层相关==============================
 | ||
| 
 | ||
| // 所谓 io 就是数据的输入输出,对于网卡来说就是接收或发送数据,
 | ||
| // 接收意味着对以太网帧解封装和提交给网络层,发送意味着对上层数据的封装和写入网卡
 | ||
| 
 | ||
| // 链路层接口
 | ||
| type LinkEndpoint interface {
 | ||
| 	// MTU是此端点的最大传输单位。这通常由支持物理网络决定;
 | ||
| 	// 当这种物理网络不存在时,限制通常为64k,其中包括IP数据包的最大大小。
 | ||
| 	MTU() uint32
 | ||
| 
 | ||
| 	// Capabilities返回链路层端点支持的功能集。
 | ||
| 	Capabilities() LinkEndpointCapabilities
 | ||
| 
 | ||
| 	// MaxHeaderLength 返回数据链接(和较低级别的图层组合)标头可以具有的最大大小。
 | ||
| 	// 较高级别使用此信息来保留它们正在构建的数据包前面预留空间。
 | ||
| 	MaxHeaderLength() uint16
 | ||
| 
 | ||
| 	// 本地链路层地址
 | ||
| 	LinkAddress() tcpip.LinkAddress
 | ||
| 
 | ||
| 	// 要参与透明桥接,LinkEndpoint实现应调用eth.Encode,
 | ||
| 	// 并将header.EthernetFields.SrcAddr设置为r.LocalLinkAddress(如果已提供)。
 | ||
| 	WritePacket(r *Route, hdr buffer.Prependable, payload buffer.VectorisedView,
 | ||
| 		protocol tcpip.NetworkProtocolNumber) *tcpip.Error
 | ||
| 
 | ||
| 	// Attach 将数据链路层端点附加到协议栈的网络层调度程序。
 | ||
| 	Attach(dispatcher NetworkDispatcher)
 | ||
| 
 | ||
| 	// 是否已经添加了网络层调度器
 | ||
| 	IsAttached() bool
 | ||
| }
 | ||
| 
 | ||
| // LinkAddressResolver 是对可以解析链接地址的 NetworkProtocol 的扩展 其实就是ARP
 | ||
| type LinkAddressResolver interface {
 | ||
| 	LinkAddressRequest(addr, localAddr tcpip.Address, linkEP LinkEndpoint) *tcpip.Error
 | ||
| 
 | ||
| 	ResolveStaticAddress(addr tcpip.Address) (tcpip.LinkAddress, bool)
 | ||
| 
 | ||
| 	LinkAddressProtocol() tcpip.NetworkProtocolNumber
 | ||
| }
 | ||
| 
 | ||
| // A LinkAddressCache caches link addresses.
 | ||
| type LinkAddressCache interface {
 | ||
| 	// CheckLocalAddress determines if the given local address exists, and if it
 | ||
| 	// does not exist.
 | ||
| 	CheckLocalAddress(nicid tcpip.NICID, protocol tcpip.NetworkProtocolNumber, addr tcpip.Address) tcpip.NICID
 | ||
| 
 | ||
| 	// AddLinkAddress adds a link address to the cache.
 | ||
| 	AddLinkAddress(nicid tcpip.NICID, addr tcpip.Address, linkAddr tcpip.LinkAddress)
 | ||
| 
 | ||
| 	// GetLinkAddress looks up the cache to translate address to link address (e.g. IP -> MAC).
 | ||
| 	// If the LinkEndpoint requests address resolution and there is a LinkAddressResolver
 | ||
| 	// registered with the network protocol, the cache attempts to resolve the address
 | ||
| 	// and returns ErrWouldBlock. Waker is notified when address resolution is
 | ||
| 	// complete (success or not).
 | ||
| 	//
 | ||
| 	// If address resolution is required, ErrNoLinkAddress and a notification channel is
 | ||
| 	// returned for the top level caller to block. Channel is closed once address resolution
 | ||
| 	// is complete (success or not).
 | ||
| 	GetLinkAddress(nicid tcpip.NICID, addr, localAddr tcpip.Address, protocol tcpip.NetworkProtocolNumber, w *sleep.Waker) (tcpip.LinkAddress, <-chan struct{}, *tcpip.Error)
 | ||
| 
 | ||
| 	// RemoveWaker removes a waker that has been added in GetLinkAddress().
 | ||
| 	RemoveWaker(nicid tcpip.NICID, addr tcpip.Address, waker *sleep.Waker)
 | ||
| }
 | ||
| 
 | ||
| type NetworkDispatcher interface {
 | ||
| 	DeliverNetworkPacket(linkEP LinkEndpoint, dstLinkAddr, srcLinkAddr tcpip.LinkAddress,
 | ||
| 		protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView)
 | ||
| }
 | ||
| 
 | ||
| type LinkEndpointCapabilities uint
 | ||
| 
 | ||
| // TransportProtocolFactory 传输层实现工厂
 | ||
| type TransportProtocolFactory func() TransportProtocol
 | ||
| 
 | ||
| // NetworkProtocolFactory 网络层实现工厂
 | ||
| type NetworkProtocolFactory func() NetworkProtocol
 | ||
| 
 | ||
| var (
 | ||
| 	// 以下两个map需要在init函数中注册
 | ||
| 	// 传输层协议的注册存储结构
 | ||
| 	transportProtocols = make(map[string]TransportProtocolFactory)
 | ||
| 	// 网络层协议的注册存储结构
 | ||
| 	networkProtocols = make(map[string]NetworkProtocolFactory)
 | ||
| 
 | ||
| 	linkEPMu           sync.RWMutex
 | ||
| 	nextLinkEndpointID tcpip.LinkEndpointID = 1
 | ||
| 	linkEndpoints                           = make(map[tcpip.LinkEndpointID]LinkEndpoint) // 设备注册表 设备号:设备实现
 | ||
| )
 | ||
| 
 | ||
| // ==============================网络层相关==============================
 | ||
| type NetworkProtocol interface {
 | ||
| 	// 网络协议版本号
 | ||
| 	Number() tcpip.NetworkProtocolNumber
 | ||
| 
 | ||
| 	// MinimumPacketSize returns the minimum valid packet size of this
 | ||
| 	// network protocol. The stack automatically drops any packets smaller
 | ||
| 	// than this targeted at this protocol.
 | ||
| 	MinimumPacketSize() int
 | ||
| 
 | ||
| 	// ParsePorts returns the source and destination addresses stored in a
 | ||
| 	// packet of this protocol.
 | ||
| 	ParseAddresses(v buffer.View) (src, dst tcpip.Address)
 | ||
| 
 | ||
| 	// 新建一个网络终端 比如 ipv4 或者 ipv6 的一个实现
 | ||
| 	NewEndpoint(nicid tcpip.NICID, addr tcpip.Address, linkAddrCache LinkAddressCache,
 | ||
| 		dispatcher TransportDispatcher, sender LinkEndpoint) (NetworkEndpoint, *tcpip.Error)
 | ||
| 
 | ||
| 	// SetOption allows enabling/disabling protocol specific features.
 | ||
| 	// SetOption returns an error if the option is not supported or the
 | ||
| 	// provided option value is invalid.
 | ||
| 	SetOption(option interface{}) *tcpip.Error
 | ||
| 
 | ||
| 	// Option allows retrieving protocol specific option values.
 | ||
| 	// Option returns an error if the option is not supported or the
 | ||
| 	// provided option value is invalid.
 | ||
| 	Option(option interface{}) *tcpip.Error
 | ||
| }
 | ||
| 
 | ||
| // NetworkEndpoint是需要由网络层协议(例如,ipv4,ipv6)的端点实现的接口
 | ||
| type NetworkEndpoint interface {
 | ||
| 	// DefaultTTL is the default time-to-live value (or hop limit, in ipv6)
 | ||
| 	// for this endpoint.
 | ||
| 	DefaultTTL() uint8
 | ||
| 
 | ||
| 	// MTU is the maximum transmission unit for this endpoint. This is
 | ||
| 	// generally calculated as the MTU of the underlying data link endpoint
 | ||
| 	// minus the network endpoint max header length.
 | ||
| 	MTU() uint32
 | ||
| 
 | ||
| 	// Capabilities returns the set of capabilities supported by the
 | ||
| 	// underlying link-layer endpoint.
 | ||
| 	Capabilities() LinkEndpointCapabilities
 | ||
| 
 | ||
| 	// MaxHeaderLength returns the maximum size the network (and lower
 | ||
| 	// level layers combined) headers can have. Higher levels use this
 | ||
| 	// information to reserve space in the front of the packets they're
 | ||
| 	// building.
 | ||
| 	MaxHeaderLength() uint16
 | ||
| 
 | ||
| 	// WritePacket writes a packet to the given destination address and
 | ||
| 	// protocol.
 | ||
| 	WritePacket(r *Route, hdr buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error
 | ||
| 
 | ||
| 	// ID returns the network protocol endpoint ID.
 | ||
| 	ID() *NetworkEndpointID
 | ||
| 
 | ||
| 	// NICID returns the id of the NIC this endpoint belongs to.
 | ||
| 	NICID() tcpip.NICID
 | ||
| 
 | ||
| 	// HandlePacket is called by the link layer when new packets arrive to
 | ||
| 	// this network endpoint.
 | ||
| 	HandlePacket(r *Route, vv buffer.VectorisedView)
 | ||
| 
 | ||
| 	// Close is called when the endpoint is reomved from a stack.
 | ||
| 	Close()
 | ||
| }
 | ||
| 
 | ||
| type NetworkEndpointID struct {
 | ||
| 	LocalAddress tcpip.Address
 | ||
| }
 | ||
| 
 | ||
| // ==============================传输层相关==============================
 | ||
| 
 | ||
| // TransportEndpointID 是某个传输层实现的标识
 | ||
| type TransportEndpointID struct {
 | ||
| 	LocalPort     uint16
 | ||
| 	LocalAddress  tcpip.Address
 | ||
| 	RemotePort    uint16
 | ||
| 	RemoteAddress tcpip.Address
 | ||
| }
 | ||
| 
 | ||
| // ControlType 是网络层控制消息的类型
 | ||
| type ControlType int
 | ||
| 
 | ||
| const (
 | ||
| 	ControlPacketTooBig ControlType = iota
 | ||
| 	ControlPortUnreachable
 | ||
| 	ControlUnknown
 | ||
| )
 | ||
| 
 | ||
| // TransportEndpoint 传输层实现接口
 | ||
| type TransportEndpoint interface {
 | ||
| 	HandlePacket(r *Route, id TransportEndpointID, vv buffer.VectorisedView)
 | ||
| 	HandleControlPacket(id TransportEndpointID, typ ControlType, extra uint32, vv buffer.VectorisedView)
 | ||
| }
 | ||
| 
 | ||
| // TransportProtocol 传输层协议 TCP OR UDP
 | ||
| type TransportProtocol interface {
 | ||
| 	// Number returns the transport protocol number.
 | ||
| 	Number() tcpip.TransportProtocolNumber
 | ||
| 
 | ||
| 	// NewEndpoint creates a new endpoint of the transport protocol.
 | ||
| 	NewEndpoint(stack *Stack, netProto tcpip.NetworkProtocolNumber, waitQueue *waiter.Queue) (tcpip.Endpoint, *tcpip.Error)
 | ||
| 
 | ||
| 	// MinimumPacketSize returns the minimum valid packet size of this
 | ||
| 	// transport protocol. The stack automatically drops any packets smaller
 | ||
| 	// than this targeted at this protocol.
 | ||
| 	MinimumPacketSize() int
 | ||
| 
 | ||
| 	// ParsePorts returns the source and destination ports stored in a
 | ||
| 	// packet of this protocol.
 | ||
| 	ParsePorts(v buffer.View) (src, dst uint16, err *tcpip.Error)
 | ||
| 
 | ||
| 	// HandleUnknownDestinationPacket handles packets targeted at this
 | ||
| 	// protocol but that don't match any existing endpoint. For example,
 | ||
| 	// it is targeted at a port that have no listeners.
 | ||
| 	//
 | ||
| 	// The return value indicates whether the packet was well-formed (for
 | ||
| 	// stats purposes only).
 | ||
| 	HandleUnknownDestinationPacket(r *Route, id TransportEndpointID, vv buffer.VectorisedView) bool
 | ||
| 
 | ||
| 	// SetOption allows enabling/disabling protocol specific features.
 | ||
| 	// SetOption returns an error if the option is not supported or the
 | ||
| 	// provided option value is invalid.
 | ||
| 	SetOption(option interface{}) *tcpip.Error
 | ||
| 
 | ||
| 	// Option allows retrieving protocol specific option values.
 | ||
| 	// Option returns an error if the option is not supported or the
 | ||
| 	// provided option value is invalid.
 | ||
| 	Option(option interface{}) *tcpip.Error
 | ||
| }
 | ||
| 
 | ||
| // TransportDispatcher 传输层调度器
 | ||
| type TransportDispatcher interface {
 | ||
| 	// DeliverTransportPacket delivers packets to the appropriate
 | ||
| 	// transport protocol endpoint.
 | ||
| 	DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolNumber, vv buffer.VectorisedView)
 | ||
| 
 | ||
| 	// DeliverTransportControlPacket delivers control packets to the
 | ||
| 	// appropriate transport protocol endpoint.
 | ||
| 	DeliverTransportControlPacket(local, remote tcpip.Address, net tcpip.NetworkProtocolNumber,
 | ||
| 		trans tcpip.TransportProtocolNumber, typ ControlType, extra uint32, vv buffer.VectorisedView)
 | ||
| }
 | ||
| 
 | ||
| // RegisterTransportProtocolFactory 注册一个新的传输层协议工厂
 | ||
| func RegisterTransportProtocolFactory(name string, p TransportProtocolFactory) {
 | ||
| 	transportProtocols[name] = p
 | ||
| }
 | ||
| 
 | ||
| // RegisterNetworkProtocolFactory 注册一个新的网络协议工厂
 | ||
| func RegisterNetworkProtocolFactory(name string, p NetworkProtocolFactory) {
 | ||
| 	networkProtocols[name] = p
 | ||
| }
 | ||
| 
 | ||
| // RegisterLinkEndpoint 注册一个链路层设备
 | ||
| func RegisterLinkEndpoint(linkEP LinkEndpoint) tcpip.LinkEndpointID {
 | ||
| 	linkEPMu.Lock()
 | ||
| 	defer linkEPMu.Unlock()
 | ||
| 
 | ||
| 	v := nextLinkEndpointID
 | ||
| 	nextLinkEndpointID++
 | ||
| 
 | ||
| 	linkEndpoints[v] = linkEP
 | ||
| 
 | ||
| 	return v
 | ||
| }
 | ||
| 
 | ||
| func FindLinkEndpoint(id tcpip.LinkEndpointID) LinkEndpoint {
 | ||
| 	linkEPMu.RLock()
 | ||
| 	defer linkEPMu.RUnlock()
 | ||
| 
 | ||
| 	return linkEndpoints[id]
 | ||
| }
 | 
