mirror of
https://github.com/impact-eintr/netstack.git
synced 2025-10-06 05:16:50 +08:00
198 lines
8.1 KiB
Go
198 lines
8.1 KiB
Go
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)
|
||
}
|