mirror of
https://github.com/impact-eintr/netstack.git
synced 2025-10-06 21:32:59 +08:00
google永远的神
This commit is contained in:
4
sleep/sleep_unsafe.go
Normal file
4
sleep/sleep_unsafe.go
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
package sleep
|
||||||
|
|
||||||
|
type Waker struct {
|
||||||
|
}
|
@@ -4,20 +4,26 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/impact-eintr/netstack/tcpip"
|
"github.com/impact-eintr/netstack/tcpip"
|
||||||
|
"github.com/impact-eintr/netstack/tcpip/buffer"
|
||||||
"github.com/impact-eintr/netstack/tcpip/ilist"
|
"github.com/impact-eintr/netstack/tcpip/ilist"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// referenced 引用的
|
||||||
type referencedNetworkEndpoint struct {
|
type referencedNetworkEndpoint struct {
|
||||||
//ilist.Entry
|
ilist.Entry // 一個侵入式链表
|
||||||
//refs int32
|
refs int32
|
||||||
//ep NetworkEndpoint
|
ep NetworkEndpoint
|
||||||
//nic *NIC
|
nic *NIC
|
||||||
//protocol tcpip.NetworkProtocolNumber
|
protocol tcpip.NetworkProtocolNumber
|
||||||
//linkCache LinkAddressCache
|
|
||||||
//holdsInserRef bool
|
// 如果为此协议启用了链接地址解析,则设置 linkCache。 否则设置为零。
|
||||||
|
linkCache LinkAddressCache
|
||||||
|
// holdInsertRef 受 NIC 的互斥锁保护。 它指示引用计数是否由于端点的插入而偏向 1。
|
||||||
|
// 当在 NIC 上调用 RemoveAddress 时,它会重置为 false。
|
||||||
|
holdsInserRef bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// 代表一个网卡对象
|
// 代表一个网卡对象 network interface controller
|
||||||
type NIC struct {
|
type NIC struct {
|
||||||
stack *Stack
|
stack *Stack
|
||||||
// 每个网卡唯一的标识号
|
// 每个网卡唯一的标识号
|
||||||
@@ -55,3 +61,63 @@ func newNIC(stack *Stack, id tcpip.NICID, name string, ep LinkEndpoint) *NIC {
|
|||||||
type NetworkEndpointID struct {
|
type NetworkEndpointID struct {
|
||||||
LocalAddress tcpip.Address
|
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 {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册该网络端
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
|
||||||
|
}
|
||||||
|
@@ -3,6 +3,7 @@ package stack
|
|||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/impact-eintr/netstack/sleep"
|
||||||
"github.com/impact-eintr/netstack/tcpip"
|
"github.com/impact-eintr/netstack/tcpip"
|
||||||
"github.com/impact-eintr/netstack/tcpip/buffer"
|
"github.com/impact-eintr/netstack/tcpip/buffer"
|
||||||
)
|
)
|
||||||
@@ -36,6 +37,9 @@ type LinkEndpoint interface {
|
|||||||
IsAttached() bool
|
IsAttached() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LinkAddressResolver interface {
|
||||||
|
}
|
||||||
|
|
||||||
type LinkEndpointCapabilities uint
|
type LinkEndpointCapabilities uint
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -49,7 +53,7 @@ const (
|
|||||||
var (
|
var (
|
||||||
// 传输层协议的注册存储结构
|
// 传输层协议的注册存储结构
|
||||||
//transportProtocols = make(map[string]TransportProtocolFactory)
|
//transportProtocols = make(map[string]TransportProtocolFactory)
|
||||||
// 网络层协议的出册存储结构
|
// 网络层协议的注册存储结构
|
||||||
//networkProtocols = make(map[string]TransportProtocolFactory)
|
//networkProtocols = make(map[string]TransportProtocolFactory)
|
||||||
linkEPMu sync.RWMutex
|
linkEPMu sync.RWMutex
|
||||||
nextLinkEndpointID tcpip.LinkEndpointID = 1
|
nextLinkEndpointID tcpip.LinkEndpointID = 1
|
||||||
@@ -57,6 +61,23 @@ var (
|
|||||||
linkEndpoints = make(map[tcpip.LinkEndpointID]LinkEndpoint)
|
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 {
|
func RegisterLinkEndpoint(linkEP LinkEndpoint) tcpip.LinkEndpointID {
|
||||||
linkEPMu.Lock()
|
linkEPMu.Lock()
|
||||||
@@ -71,20 +92,64 @@ func RegisterLinkEndpoint(linkEP LinkEndpoint) tcpip.LinkEndpointID {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type TransportProtocol interface {
|
// 根据ID找到网卡设备
|
||||||
|
func FindLinkEndpoint(id tcpip.LinkEndpointID) LinkEndpoint {
|
||||||
|
linkEPMu.RLock()
|
||||||
|
defer linkEPMu.RUnlock()
|
||||||
|
return linkEndpoints[id]
|
||||||
}
|
}
|
||||||
|
|
||||||
type TransportEndpointID struct {
|
// 网络层
|
||||||
LocalPort uint16
|
|
||||||
LocalAddress tcpip.Address
|
// ControlType 是网络控制消息的类型
|
||||||
RemotePort uint16
|
type ControlType int
|
||||||
RemoteAddress tcpip.Address
|
|
||||||
|
// 以下是 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 {
|
type NetworkProtocol interface {
|
||||||
//Number() tcpip.NetworkProtocolNumber
|
// Number 返回网络协议号
|
||||||
//MinimumPacketSize() int
|
Number() tcpip.NetworkProtocolNumber
|
||||||
//ParseAddresses(v buffer.View) (src, dst tcpip.Address)
|
// 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
|
||||||
}
|
}
|
||||||
|
|
||||||
// 包含网络协议栈用于在 数据链路层 处理数据包后将数据包传送到适当网络端点的方法。
|
// 包含网络协议栈用于在 数据链路层 处理数据包后将数据包传送到适当网络端点的方法。
|
||||||
@@ -94,5 +159,39 @@ type NetworkDispatcher interface {
|
|||||||
protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView)
|
protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView)
|
||||||
}
|
}
|
||||||
|
|
||||||
type LinkAddressResolver interface {
|
// 传输层
|
||||||
|
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
|
@@ -4,6 +4,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/impact-eintr/netstack/sleep"
|
||||||
"github.com/impact-eintr/netstack/tcpip"
|
"github.com/impact-eintr/netstack/tcpip"
|
||||||
"github.com/impact-eintr/netstack/tcpip/buffer"
|
"github.com/impact-eintr/netstack/tcpip/buffer"
|
||||||
"github.com/impact-eintr/netstack/tcpip/ports"
|
"github.com/impact-eintr/netstack/tcpip/ports"
|
||||||
@@ -15,6 +16,7 @@ type transportProtocolState struct {
|
|||||||
defaultHandler func(*Route, TransportEndpointID, buffer.VectorisedView) bool
|
defaultHandler func(*Route, TransportEndpointID, buffer.VectorisedView) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stack 是一个网络堆栈,包含所有支持的协议、NIC 和路由表
|
||||||
type Stack struct {
|
type Stack struct {
|
||||||
transportProtocols map[tcpip.TransportProtocolNumber]*transportProtocolState
|
transportProtocols map[tcpip.TransportProtocolNumber]*transportProtocolState
|
||||||
networkProtocols map[tcpip.NetworkProtocolNumber]NetworkProtocol
|
networkProtocols map[tcpip.NetworkProtocolNumber]NetworkProtocol
|
||||||
@@ -30,11 +32,14 @@ type Stack struct {
|
|||||||
nics map[tcpip.NICID]*NIC
|
nics map[tcpip.NICID]*NIC
|
||||||
forwarding bool
|
forwarding bool
|
||||||
|
|
||||||
|
// route 是用户通过 SetRouteTable() 传入的路由表,Find Route() 使用它来构建特定目的地的路由
|
||||||
routeTable []tcpip.Route
|
routeTable []tcpip.Route
|
||||||
|
|
||||||
*ports.PortManager
|
*ports.PortManager
|
||||||
|
// 如果不是 nil,则任何新端点每次收到 TCP 段时都会调用此探测函数
|
||||||
tcpProbeFunc TCPProbeFunc
|
tcpProbeFunc TCPProbeFunc
|
||||||
clock tcpip.Clock
|
// 用于生成用户可见的时间
|
||||||
|
clock tcpip.Clock
|
||||||
}
|
}
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
@@ -86,3 +91,64 @@ type TCPSenderState struct {
|
|||||||
func (s *Stack) CreateNIC(id tcpip.NICID, linkEP tcpip.LinkEndpointID) *tcpip.Error {
|
func (s *Stack) CreateNIC(id tcpip.NICID, linkEP tcpip.LinkEndpointID) *tcpip.Error {
|
||||||
return s.createNIC(id, "", linkEP, true)
|
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) {
|
||||||
|
|
||||||
|
}
|
||||||
|
@@ -23,3 +23,19 @@ type protocolIDs struct {
|
|||||||
network tcpip.NetworkProtocolNumber
|
network tcpip.NetworkProtocolNumber
|
||||||
transport tcpip.TransportProtocolNumber
|
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
|
||||||
|
}
|
||||||
|
@@ -21,13 +21,13 @@ func (err *Error) IgnoreStats() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrUnknowProtovol = &Error{msg: "unknown protocol"}
|
ErrUnknowProtocol = &Error{msg: "unknown protocol"}
|
||||||
ErrUnknowNICID = &Error{msg: "unknown nic id"}
|
ErrUnknowNICID = &Error{msg: "unknown nic id"}
|
||||||
ErrUnknowProtocolOption = &Error{msg: "unknown option for protocol"}
|
ErrUnknowProtocolOption = &Error{msg: "unknown option for protocol"}
|
||||||
ErrDuplicateNICID = &Error{msg: "duplicate nic id"}
|
ErrDuplicateNICID = &Error{msg: "duplicate nic id"}
|
||||||
ErrDuplicateAddress = &Error{msg: "duplicate address"}
|
ErrDuplicateAddress = &Error{msg: "duplicate address"}
|
||||||
ErrNoRoute = &Error{msg: "no route"}
|
ErrNoRoute = &Error{msg: "no route"}
|
||||||
ErrBadLinkEndPoint = &Error{msg: "bad link layer endpoint"}
|
ErrBadLinkEndpoint = &Error{msg: "bad link layer endpoint"}
|
||||||
ErrAlreadyBound = &Error{msg: "endpoint already bound", ignoreStats: true}
|
ErrAlreadyBound = &Error{msg: "endpoint already bound", ignoreStats: true}
|
||||||
ErrInvalidEndpointState = &Error{msg: "endpoint is in invalid state"}
|
ErrInvalidEndpointState = &Error{msg: "endpoint is in invalid state"}
|
||||||
ErrAlreadyConnecting = &Error{msg: "endpoint is already connecting", ignoreStats: true}
|
ErrAlreadyConnecting = &Error{msg: "endpoint is already connecting", ignoreStats: true}
|
||||||
@@ -91,7 +91,10 @@ func ParseMACAddress(s string) (LinkAddress, error) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NetworkProtocolNumber 是网络协议的编号。
|
||||||
type NetworkProtocolNumber uint32
|
type NetworkProtocolNumber uint32
|
||||||
|
|
||||||
|
// TransportProtocolNumber 是传输协议的编号
|
||||||
type TransportProtocolNumber uint32
|
type TransportProtocolNumber uint32
|
||||||
|
|
||||||
type Address string
|
type Address string
|
||||||
|
Reference in New Issue
Block a user