mirror of
https://github.com/impact-eintr/netstack.git
synced 2025-10-05 21:06:50 +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]
|
||
}
|