mirror of
https://github.com/impact-eintr/netstack.git
synced 2025-10-06 05:16:50 +08:00
这个仓库代码量太大了 以读为主 不写了
This commit is contained in:
@@ -1,45 +0,0 @@
|
||||
package stack
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/impact-eintr/netstack/tcpip"
|
||||
)
|
||||
|
||||
const linkAddrCacheSize = 512 // 最大缓存条目
|
||||
|
||||
// 是一个固定大小的缓存,将 IP 地址映射到链接地址
|
||||
// 条目存储在环形缓冲区中,最旧的条目首先被替换。
|
||||
// 这个结构体对于并发使用是安全的
|
||||
type linkAddrCache struct {
|
||||
// 缓存条目的有效期
|
||||
ageLimit time.Duration
|
||||
// 等待链接请求解析地址的时间
|
||||
resolutionTimeout time.Duration
|
||||
// 地址在失败前尝试解析的次数
|
||||
resolutionAttempts int
|
||||
|
||||
mu sync.Mutex
|
||||
cache map[tcpip.FullAddress]*linkAddrEntry
|
||||
next int // 下一个可用条目的数组索引
|
||||
entries [linkAddrCacheSize]linkAddrEntry
|
||||
}
|
||||
|
||||
// linkAddrCache 中的一个条目
|
||||
type linkAddrEntry struct {
|
||||
addr tcpip.FullAddress
|
||||
linkAddr tcpip.LinkAddress
|
||||
expiration time.Time
|
||||
s entryState
|
||||
}
|
||||
|
||||
// entryState 控制缓存中单个条目的状态
|
||||
type entryState int
|
||||
|
||||
const (
|
||||
incomplete entryState = iota
|
||||
ready
|
||||
failed
|
||||
expired // 失效的
|
||||
)
|
@@ -1,155 +0,0 @@
|
||||
package stack
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/impact-eintr/netstack/tcpip"
|
||||
"github.com/impact-eintr/netstack/tcpip/buffer"
|
||||
"github.com/impact-eintr/netstack/tcpip/ilist"
|
||||
)
|
||||
|
||||
type PrimaryEndpointBehavior int
|
||||
|
||||
const (
|
||||
// CanBePrimaryEndpoint 指示端点可以用作没有本地地址的新连接的主要端点。
|
||||
// 这是调用 NIC.AddAddress 时的默认值
|
||||
CanBePrimaryEndpoint PrimaryEndpointBehavior = iota
|
||||
// FirstPrimaryEndpoint 指示终点应该是第一个考虑的主要终点。
|
||||
// 如果有多个具有此行为的端点,则最近添加的端点将是第一个。
|
||||
FirstPrimaryEndpoint
|
||||
// NeverPrimaryEndpoint 指示端点不应是主要端点
|
||||
NeverPrimaryEndpoint
|
||||
)
|
||||
|
||||
// referenced 引用的
|
||||
type referencedNetworkEndpoint struct {
|
||||
ilist.Entry // 一個侵入式链表
|
||||
refs int32
|
||||
ep NetworkEndpoint
|
||||
nic *NIC
|
||||
protocol tcpip.NetworkProtocolNumber
|
||||
|
||||
// 如果为此协议启用了链接地址解析,则设置 linkCache。 否则设置为零。
|
||||
linkCache LinkAddressCache
|
||||
// holdInsertRef 受 NIC 的互斥锁保护。 它指示引用计数是否由于端点的插入而偏向 1。
|
||||
// 当在 NIC 上调用 RemoveAddress 时,它会重置为 false。
|
||||
holdsInserRef bool
|
||||
}
|
||||
|
||||
// 代表一个网卡对象 network interface controller
|
||||
type NIC struct {
|
||||
stack *Stack
|
||||
// 每个网卡唯一的标识号
|
||||
id tcpip.NICID
|
||||
// 网卡名 可有可无
|
||||
name string
|
||||
// 链路层端
|
||||
linkEP LinkEndpoint
|
||||
// 传输层的解复用
|
||||
demux *transportDemuxer
|
||||
|
||||
mu sync.RWMutex
|
||||
spoofing bool
|
||||
// 是指一台机器的网卡能够接收所有经过它的数据流,而不论其目的地址是否是它。
|
||||
promiscuous bool
|
||||
primary map[tcpip.NetworkProtocolNumber]*ilist.List
|
||||
// 网络层端的记录
|
||||
endpoints map[NetworkEndpointID]*referencedNetworkEndpoint
|
||||
// 子网的记录
|
||||
subnets []tcpip.Subnet
|
||||
}
|
||||
|
||||
// 根据参数新建一个NIC
|
||||
func newNIC(stack *Stack, id tcpip.NICID, name string, ep LinkEndpoint) *NIC {
|
||||
return &NIC{
|
||||
stack: stack,
|
||||
id: id,
|
||||
name: name,
|
||||
linkEP: ep,
|
||||
demux: newTransportDemuxer(stack),
|
||||
primary: make(map[tcpip.NetworkProtocolNumber]*ilist.List),
|
||||
endpoints: make(map[NetworkEndpointID]*referencedNetworkEndpoint),
|
||||
}
|
||||
}
|
||||
|
||||
type NetworkEndpointID struct {
|
||||
LocalAddress tcpip.Address
|
||||
}
|
||||
|
||||
// 添加当前的NIC到链路层设备,激活该NIC
|
||||
func (n *NIC) attachLinkEndpint() {
|
||||
n.linkEP.Attach(n)
|
||||
}
|
||||
|
||||
// 在NIC上添加addr地址 注册和初始化网络层协议
|
||||
// 相当于给网卡添加ip地址
|
||||
func (n *NIC) addAddressLocked(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address,
|
||||
peb PrimaryEndpointBehavior, replace bool) (*referencedNetworkEndpoint, *tcpip.Error) {
|
||||
// 查看是否支持该协议 若不支持则返回错误
|
||||
netProto, ok := n.stack.networkProtocols[protocol]
|
||||
if !ok {
|
||||
return nil, tcpip.ErrUnknowProtocol
|
||||
}
|
||||
|
||||
// 比如netProto是ipv4 就会调用ipv4,NewEndpoint,新建一个网络层端
|
||||
ep, err := netProto.NewEndpoint(n.id, addr, n.stack, n, n.linkEP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 获取网络层id 即ip地址
|
||||
id := *ep.ID()
|
||||
if ref, ok := n.endpoints[id]; ok {
|
||||
// 不是替换,且该id不存在,返回错误
|
||||
if !replace {
|
||||
return nil, tcpip.ErrDuplicateAddress // duplicate 复制的
|
||||
}
|
||||
n.removeEndpointLocked(ref)
|
||||
}
|
||||
|
||||
ref := &referencedNetworkEndpoint{
|
||||
refs: 1,
|
||||
ep: ep,
|
||||
nic: n,
|
||||
protocol: protocol,
|
||||
holdsInserRef: true,
|
||||
}
|
||||
|
||||
// 检测是否需要进行地址解析
|
||||
// 如果此协议存在链接地址解析,则设置缓存
|
||||
if n.linkEP.Capabilities()&CapabilityResolutionRequired != 0 {
|
||||
if _, ok := n.stack.linkAddrResolvers[protocol]; ok {
|
||||
ref.linkCache = n.stack
|
||||
}
|
||||
}
|
||||
|
||||
// 注册该网络端
|
||||
n.endpoints[id] = ref
|
||||
|
||||
l, ok := n.primary[protocol]
|
||||
if !ok {
|
||||
l = &ilist.List{}
|
||||
n.primary[protocol] = l
|
||||
}
|
||||
switch peb {
|
||||
case CanBePrimaryEndpoint:
|
||||
l.PushBack(ref)
|
||||
case FirstPrimaryEndpoint:
|
||||
l.PushFront(ref)
|
||||
}
|
||||
return ref, nil
|
||||
|
||||
}
|
||||
|
||||
// DeliverTransportPacket 将数据包传送到适当的传输协议端点。
|
||||
func (n *NIC) DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolNumber,
|
||||
vv buffer.VectorisedView) {
|
||||
|
||||
}
|
||||
|
||||
// DeliverTransportControlPacket 将控制数据包传送到适当的传输协议端点。
|
||||
func (n *NIC) DeliverTransportControlPacket(local, remote tcpip.Address,
|
||||
net tcpip.NetworkProtocolNumber, trans tcpip.TransportProtocolNumber,
|
||||
typ ControlType, extra uint32, vv buffer.VectorisedView) {
|
||||
|
||||
}
|
@@ -1,197 +0,0 @@
|
||||
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)
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
package stack
|
||||
|
||||
import "github.com/impact-eintr/netstack/tcpip"
|
||||
|
||||
// 贯穿整个协议栈的路由,也就是在链路层和网络层都可以路由
|
||||
// 如果目标地址是链路层地址,那么在链路层路由
|
||||
// 如果目标地址是网络层地址,那么在网络层路由
|
||||
type Route struct {
|
||||
// 远端网络层地址 ipv4 or ipv6
|
||||
RemoteAddress tcpip.Address
|
||||
|
||||
// 远端网卡MAC地址
|
||||
RemoteLinkAddress tcpip.LinkAddress
|
||||
|
||||
// 本地网络层地址
|
||||
LocalAddress tcpip.Address
|
||||
|
||||
// 本地网卡MAC地址
|
||||
LocalLinkAddress tcpip.LinkAddress
|
||||
|
||||
// 下一跳网络层地址
|
||||
NextHop tcpip.Address
|
||||
|
||||
// 网络层协议号
|
||||
NextProto tcpip.NetworkProtocolNumber
|
||||
|
||||
// 相关的网络终端
|
||||
ref *referencedNetworkEndpoint
|
||||
}
|
@@ -1,154 +0,0 @@
|
||||
package stack
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/impact-eintr/netstack/sleep"
|
||||
"github.com/impact-eintr/netstack/tcpip"
|
||||
"github.com/impact-eintr/netstack/tcpip/buffer"
|
||||
"github.com/impact-eintr/netstack/tcpip/ports"
|
||||
"github.com/impact-eintr/netstack/tcpip/seqnum"
|
||||
)
|
||||
|
||||
type transportProtocolState struct {
|
||||
proto TransportProtocol
|
||||
defaultHandler func(*Route, TransportEndpointID, buffer.VectorisedView) bool
|
||||
}
|
||||
|
||||
// Stack 是一个网络堆栈,包含所有支持的协议、NIC 和路由表
|
||||
type Stack struct {
|
||||
transportProtocols map[tcpip.TransportProtocolNumber]*transportProtocolState
|
||||
networkProtocols map[tcpip.NetworkProtocolNumber]NetworkProtocol
|
||||
linkAddrResolvers map[tcpip.NetworkProtocolNumber]LinkAddressResolver
|
||||
|
||||
demux *transportDemuxer
|
||||
|
||||
stats tcpip.Stats
|
||||
|
||||
linkAddrCache *linkAddrCache
|
||||
|
||||
mu sync.RWMutex
|
||||
nics map[tcpip.NICID]*NIC
|
||||
forwarding bool
|
||||
|
||||
// route 是用户通过 SetRouteTable() 传入的路由表,Find Route() 使用它来构建特定目的地的路由
|
||||
routeTable []tcpip.Route
|
||||
|
||||
*ports.PortManager
|
||||
// 如果不是 nil,则任何新端点每次收到 TCP 段时都会调用此探测函数
|
||||
tcpProbeFunc TCPProbeFunc
|
||||
// 用于生成用户可见的时间
|
||||
clock tcpip.Clock
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
Clock tcpip.Clock
|
||||
Stats tcpip.Stats
|
||||
}
|
||||
|
||||
// TCPProbeFunc 是要传递给 stack.AddTCPProbe 的 TCP 探测函数的预期函数类型
|
||||
type TCPProbeFunc func(s TCPEndpointState)
|
||||
|
||||
// TCPEndpointState 是 TCP 端点内部状态的副本
|
||||
type TCPEndpointState struct {
|
||||
ID TCPEndpointID // ID 是端点的 TransportEndpointID 的副本
|
||||
SegTime time.Time // SegTime 表示收到该段的绝对时间
|
||||
RcvBufSize int // RcvBufSize 是端点的接收套接字缓冲区的大小
|
||||
RcvBufUsed bool // RcvBufUsed 是端点的接收套接字缓冲区中实际保存的字节数
|
||||
RcvClosed bool // RcvClosed 如果为真,表示端点已经关闭读取
|
||||
SendTSOk bool // SendOk 用于指示何时协商了 TS 选项。当 sendOk 为真时,每个非 RST 段都应根据 RFC 7323#section-1.1 携带 TS
|
||||
|
||||
// 应该在时间戳的TSEcr 字段中为端点发送的未来段发送的时间戳。当此端点接收到新段时,如果需要,将更新此字段
|
||||
RecentTS uint32
|
||||
// TSOffset 是添加到时间戳选项中 TSVal 字段值的随机偏移量
|
||||
TSOffset uint32
|
||||
|
||||
// 如果对等方在 SYN/SYN-ACK 中发送 TCPSACKPermitted 选项,则 SACKPermitted 设置为 true
|
||||
SACKPermitted bool
|
||||
SACK TCPSACKInfo // SACK 保存该端点的 TCP SACK 相关信息
|
||||
SndBufSize int // SndBufSize 是套接字发送缓冲区的大小
|
||||
SndBufUsed bool // SndBufUsed 是端点的发送套接字缓冲区中实际发送的字节数
|
||||
SndClosed bool // SndClosed 表示端点已关闭发送
|
||||
|
||||
sndBufInQueue seqnum.Size // SndBufInQueue 是发送队列中的字节数
|
||||
|
||||
// PacketTooBigCount 用于通知主协程收到“数据包太大”控制数据包的次数
|
||||
PacketTooBigCount int
|
||||
|
||||
SndMTU int // SndMTU 是在收到的控制数据包中看到的最小 MTU
|
||||
Receiver TCPReceiverState
|
||||
Sender TCPSenderState
|
||||
}
|
||||
|
||||
type TCPReceiverState struct {
|
||||
}
|
||||
|
||||
type TCPSenderState struct {
|
||||
}
|
||||
|
||||
// 根据nic id和linkEP id来创建和注册一个网卡对象
|
||||
func (s *Stack) CreateNIC(id tcpip.NICID, linkEP tcpip.LinkEndpointID) *tcpip.Error {
|
||||
return s.createNIC(id, "", linkEP, true)
|
||||
}
|
||||
|
||||
func (s *Stack) CreateNamedNIC(id tcpip.NICID, name string, linkEP tcpip.LinkEndpointID) *tcpip.Error {
|
||||
return s.createNIC(id, name, linkEP, true)
|
||||
}
|
||||
|
||||
func (s *Stack) CreateDisableNamedNIC(id tcpip.NICID, name string, linkEP tcpip.LinkEndpointID) *tcpip.Error {
|
||||
return s.createNIC(id, name, linkEP, false)
|
||||
}
|
||||
|
||||
// 新建一个网卡对象,并且激活它,激活的意思就是准备好从网卡中读取和写入数据
|
||||
func (s *Stack) createNIC(id tcpip.NICID, name string, linkEP tcpip.LinkEndpointID, enabled bool) *tcpip.Error {
|
||||
ep := FindLinkEndpoint(linkEP)
|
||||
if ep == nil {
|
||||
return tcpip.ErrBadLinkEndpoint
|
||||
}
|
||||
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if _, ok := s.nics[id]; ok {
|
||||
|
||||
}
|
||||
|
||||
n := newNIC(s, id, name, ep)
|
||||
|
||||
s.nics[id] = n
|
||||
if enabled {
|
||||
n.attachLinkEndpoint()
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// CheckLocalAddress 确定给定的本地地址是否存在
|
||||
func (s *Stack) CahceLocalAddress(nicid tcpip.NICID, protocol tcpip.NetworkProtocolNumber,
|
||||
addr tcpip.Address) tcpip.NICID
|
||||
|
||||
// AddLinkAddress 向缓存添加链接地址
|
||||
func (s *Stack) AddLinkAddress(nicid tcpip.NICID, addr tcpip.Address, linkAddr tcpip.LinkAddress)
|
||||
|
||||
// GetLinkAddress 查找缓存以将地址转换为链接地址(例如 IP -> MAC)。
|
||||
// 如果 LinkEndpoint 请求地址解析并且存在使用网络协议注册的 Link Address Resolver,则缓存尝试解析地址并返回 EWouldBlock。
|
||||
// 如果需要地址解析,则返回 ErrNoLinkAddress 和通知通道以供顶级调用方阻止。 一旦地址解析完成(成功与否),通道就会关闭。
|
||||
func (s *Stack) GetLinkAddress(nic tcpip.NICID, addr, localAddr tcpip.Address,
|
||||
protocol tcpip.NetworkProtocolNumber, ww *sleep.Waker) (tcpip.LinkAddress,
|
||||
<-chan struct{}, *tcpip.Error) {
|
||||
|
||||
}
|
||||
|
||||
// RemoveWaker 移除已在 GetLinkAddress() 中添加的唤醒器。
|
||||
func (s *Stack) RemoveWaker(nicid tcpip.NICID, addr tcpip.Address, waker *sleep.Waker) {
|
||||
|
||||
}
|
||||
|
||||
// 当NIC从物理接口接受数据包时,将调用此函数
|
||||
// 比如protocol是arp协议号 那么会找到arp.HandlePacket来处理数据报
|
||||
// protocol是ipv4协议号,那么会找到ipv4.HahndlePacket来处理数据报
|
||||
func (s *Stack) DeliverNetworkPacket(linkEP LinkEndpoint, dstLinkAddr, srcLinkAddr tcpip.LinkAddress,
|
||||
protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) {
|
||||
|
||||
}
|
@@ -1,41 +0,0 @@
|
||||
package stack
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/impact-eintr/netstack/tcpip"
|
||||
)
|
||||
|
||||
// 解复用针对传输端点的数据包 在他们被网络层解析之后
|
||||
// 它执行两级解复用 首先基于网络协议和传输协议 然后基于端点ID
|
||||
type transportDemuxer struct {
|
||||
protocol map[protocolIDs]*transportEndpoints
|
||||
}
|
||||
|
||||
// 管理给定协议的所有端点
|
||||
type transportEndpoints struct {
|
||||
mu sync.RWMutex
|
||||
endpoints map[TransportEndpointID]*transportEndpoints
|
||||
}
|
||||
|
||||
// 网络层协议号和传输层协议号的组合 当作分流器的key值
|
||||
type protocolIDs struct {
|
||||
network tcpip.NetworkProtocolNumber
|
||||
transport tcpip.TransportProtocolNumber
|
||||
}
|
||||
|
||||
// 新建一个分流器
|
||||
func newTransportDemuxer(stack *Stack) *transportDemuxer {
|
||||
d := &transportDemuxer{
|
||||
protocol: make(map[protocolIDs]*transportEndpoints),
|
||||
}
|
||||
|
||||
for netProto := range stack.networkProtocols {
|
||||
for proto := range stack.transportProtocols {
|
||||
d.protocol[protocolIDs{netProto, proto}] = &transportEndpoints{
|
||||
endpoints: make(map[TransportEndpointID]*transportEndpoints),
|
||||
}
|
||||
}
|
||||
}
|
||||
return d
|
||||
}
|
Reference in New Issue
Block a user