Files
netstack/tcpip/stack/registration.go
2021-09-08 21:54:54 +08:00

198 lines
8.1 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 (
"sync"
"github.com/impact-eintr/netstack/sleep"
"github.com/impact-eintr/netstack/tcpip"
"github.com/impact-eintr/netstack/tcpip/buffer"
)
// LinkEndpoint是由数据链路层协议(以太 环回 原始)实现的接口
// 并由网络层协议用于实施者的数据链路端点发送数据包
type LinkEndpoint interface {
// MTU通常是这个端点的最大传输单位 这通常由支持物理网络决定
// 当这种物理网络不存在时 限制通常是64K其中包括IP数据包的最大大小
MTU() uint32
// 返回链路层端点支持的功能集
Capabilities() LinkEndpointCapabilities
// 返回数据链接(以及更底层的层次)Header的最大大小
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(dispatcher NetworkDispatcher)
// 是否已经添加了网络调度器
IsAttached() bool
}
type LinkAddressResolver interface {
}
type LinkEndpointCapabilities uint
const (
CapabilityChecksumOffload LinkEndpointCapabilities = 1 << iota
CapabilityResolutionRequired
CapabilitySaveRestore
CapabilityDisconnectOk
CapabilityLoopback
)
var (
// 传输层协议的注册存储结构
//transportProtocols = make(map[string]TransportProtocolFactory)
// 网络层协议的注册存储结构
//networkProtocols = make(map[string]TransportProtocolFactory)
linkEPMu sync.RWMutex
nextLinkEndpointID tcpip.LinkEndpointID = 1
// 保存设备号与设备信息
linkEndpoints = make(map[tcpip.LinkEndpointID]LinkEndpoint)
)
// 链路层
// LinkAddressCache 缓存链接地址。
type LinkAddressCache interface {
// CheckLocalAddress 确定给定的本地地址是否存在
CahceLocalAddress(nicid tcpip.NICID, protocol tcpip.NetworkProtocolNumber, addr tcpip.Address) tcpip.NICID
// AddLinkAddress 向缓存添加链接地址
AddLinkAddress(nicid tcpip.NICID, addr tcpip.Address, linkAddr tcpip.LinkAddress)
// GetLinkAddress 查找缓存以将地址转换为链接地址(例如 IP -> MAC
// 如果 LinkEndpoint 请求地址解析并且存在使用网络协议注册的 Link Address Resolver则缓存尝试解析地址并返回 EWouldBlock。
// 如果需要地址解析,则返回 ErrNoLinkAddress 和通知通道以供顶级调用方阻止。 一旦地址解析完成(成功与否),通道就会关闭。
GetLinkAddress(nic tcpip.NICID, addr, localAddr tcpip.Address, protocol tcpip.NetworkProtocolNumber,
w *sleep.Waker) (tcpip.LinkAddress, <-chan struct{}, *tcpip.Error)
// RemoveWaker 移除已在 GetLinkAddress() 中添加的唤醒器。
RemoveWaker(nicid tcpip.NICID, addr tcpip.Address, waker *sleep.Waker)
}
// 注册一个链路层设备
func RegisterLinkEndpoint(linkEP LinkEndpoint) tcpip.LinkEndpointID {
linkEPMu.Lock()
defer linkEPMu.Unlock()
v := nextLinkEndpointID
nextLinkEndpointID++
// 进行注册
linkEndpoints[v] = linkEP
return v
}
// 根据ID找到网卡设备
func FindLinkEndpoint(id tcpip.LinkEndpointID) LinkEndpoint {
linkEPMu.RLock()
defer linkEPMu.RUnlock()
return linkEndpoints[id]
}
// 网络层
// ControlType 是网络控制消息的类型
type ControlType int
// 以下是 ControlType 值的允许值
const (
ControlPacketTooBig ControlType = iota
ControlPortUnreachable
ControlUnknown
)
// 需要由网络层协议(ipv4 ipv6)的端点实现的接口
type NetworkEndpoint interface {
// DefaultTTL 是此端点的默认生存时间值(或跳数限制,在 ipv6 中)
DefaultTTL() uint8
// MTU 是该端点的最大传输单元。这通常计算为底层数据链路端点的 MTU 减去网络端点最大报头长度
MTU() uint32
Capabilities() LinkEndpointCapabilities // 返回底层链路层端点支持的能力集
// MaxHeaderLength 返回网络(和较低级别的层)标头可以具有的最大大小。
// 更高层使用此信息在他们正在构建的数据包前面保留空间
MaxHeaderLength() uint16
// WritePacket 将数据包写入给定的目标地址和协议
WritePacket(r *Route, hdr buffer.Prependable, payload buffer.VectorisedView,
protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error
ID() *NetworkEndpointID // ID 返回网络协议端点 ID
NICID() tcpip.NICID
// 当新数据包到达此网络端点时,链路层会调用 HandlePacket
HandlePacket(r *Route, hdr buffer.Prependable, payload buffer.VectorisedView,
protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error
// 当端点从堆栈中移除时调用 Close
Close()
}
// NetworkProtocol 是需要由希望成为网络堆栈一部分的网络协议例如ipv4、ipv6实现的接口
type NetworkProtocol interface {
// Number 返回网络协议号
Number() tcpip.NetworkProtocolNumber
// MinimumPacketSize 返回此网络协议的最小有效数据包大小。堆栈会自动丢弃任何小于此协议的数据包
MinimumPacketSize() int
// ParsePorts 返回存储在该协议数据包中的源地址和目的地址
ParseAddresses(v buffer.View) (src, dst tcpip.Address)
// NewEndpoint 创建此协议的新端点。
NewEndpoint(cicid tcpip.NICID, addr tcpip.Address, linkAddrCache LinkAddressCache,
dispatcher TransportDispatcher, sender LinkEndpoint) (NetworkEndpoint, *tcpip.Error)
// SetOption 允许启用/禁用协议特定功能。
// 如果不支持该选项或提供的选项值无效,则 SetOption 将返回错误。
SetOption(option interface{}) *tcpip.Error
// Option 允许检索协议特定的选项值。 如果选项不受支持或提供的选项值无效则Option 返回错误。
Option(option interface{}) *tcpip.Error
}
// 包含网络协议栈用于在 数据链路层 处理数据包后将数据包传送到适当网络端点的方法。
type NetworkDispatcher interface {
// deliver 递送
DeliverNetworkPacket(linkEP LinkEndpoint, dstLinkAddr, srcLinkAddr tcpip.LinkAddress,
protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView)
}
// 传输层
type TransportEndpointID struct {
LocalPort uint16
LocalAddress tcpip.Address
RemotePort uint16
RemoteAddress tcpip.Address
}
// TransportProtocol 是需要由希望成为网络堆栈一部分的传输协议例如tcp、udp实现的接口
type TransportProtocol interface {
// Number 返回传输协议号
Number() tcpip.TransportProtocolNumber
// MinimumPacketSize 返回此网络协议的最小有效数据包大小。堆栈会自动丢弃任何小于此协议的数据包
MinimumPacketSize() int
// ParsePorts 返回存储在该协议数据包中的源端口和目的端口
ParsePorts(v buffer.View) (src, dst uint16, err *tcpip.Error)
// HandleUnknownDestinationPacket 处理以该协议为目标但不匹配任何现有端点的数据包。
// 例如,它针对没有侦听器的端口
HandleUnknowDestinationPacket(r *Route, id TransportEndpointID, vv buffer.VectorisedView) bool
// SetOption 允许启用/禁用协议特定功能。
// 如果不支持该选项或提供的选项值无效,则 SetOption 将返回错误。
SetOption(option interface{}) *tcpip.Error
// Option 允许检索协议特定的选项值。 如果选项不受支持或提供的选项值无效则Option 返回错误。
Option(option interface{}) *tcpip.Error
}
// TransportDispatcher 包含网络堆栈用于在 网络层 处理数据包后将数据包传送到适当的传输端点的方法
type TransportDispatcher interface {
// DeliverTransportPacket 将数据包传送到适当的传输协议端点。
DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolNumber, vv buffer.VectorisedView)
// DeliverTransportControlPacket 将控制数据包传送到适当的传输协议端点。
DeliverTransportControlPacket(local, remote tcpip.Address, net tcpip.NetworkProtocolNumber,
trans tcpip.TransportProtocolNumber, typ ControlType, extra uint32, vv buffer.VectorisedView)
}