Files
netstack/tcpip/stack/registration.go

284 lines
11 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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是需要由网络层协议例如ipv4ipv6的端点实现的接口
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]
}