mirror of
https://github.com/impact-eintr/netstack.git
synced 2025-10-06 21:32:59 +08:00
侵入式双向链表
This commit is contained in:
150
tcpip/ilist/list.go
Normal file
150
tcpip/ilist/list.go
Normal file
@@ -0,0 +1,150 @@
|
||||
// 包 ilist 提供了侵入式链表的实现
|
||||
package ilist
|
||||
|
||||
type Linker interface {
|
||||
Next() Element
|
||||
Prev() Element
|
||||
SetNext(Element)
|
||||
SetPrev(Element)
|
||||
}
|
||||
|
||||
type Element interface {
|
||||
Linker
|
||||
}
|
||||
|
||||
// ElementMapper 默认提供身份映射。
|
||||
// 如果它们不相同,则可以替换它以提供将元素映射到链接器对象的结构。
|
||||
// 在以下情况下通常不需要 ElementMapper:Linker 保持原样,Element 保持原样,
|
||||
// 或者 Linker 和 Element 是相同类型
|
||||
type ElementMapper struct{}
|
||||
|
||||
// linkerFor maps an Element to a Linker.
|
||||
// This default implementation should be inline 1d
|
||||
func (ElementMapper) linkerFor(elem Element) Linker {
|
||||
return elem
|
||||
}
|
||||
|
||||
type List struct {
|
||||
head Element
|
||||
tail Element
|
||||
}
|
||||
|
||||
func (l *List) Reset() {
|
||||
l.head = nil
|
||||
l.tail = nil
|
||||
}
|
||||
|
||||
func (l *List) Empty() bool {
|
||||
return l.head == nil
|
||||
}
|
||||
|
||||
func (l *List) Front() Element {
|
||||
return l.head
|
||||
}
|
||||
|
||||
func (l *List) Back() Element {
|
||||
return l.tail
|
||||
}
|
||||
|
||||
func (l *List) PushFront(e Element) {
|
||||
ElementMapper{}.linkerFor(e).SetPrev(nil)
|
||||
ElementMapper{}.linkerFor(e).SetNext(l.head) //当前头部作为新头部的下一个节点
|
||||
|
||||
if l.head != nil {
|
||||
ElementMapper{}.linkerFor(l.head).SetPrev(e)
|
||||
} else {
|
||||
l.tail = e
|
||||
}
|
||||
l.head = e
|
||||
}
|
||||
|
||||
func (l *List) PushBack(e Element) {
|
||||
ElementMapper{}.linkerFor(e).SetPrev(l.tail) // 当前尾部作为新尾部的上一个节点
|
||||
ElementMapper{}.linkerFor(e).SetNext(nil)
|
||||
|
||||
if l.tail != nil {
|
||||
ElementMapper{}.linkerFor(l.tail).SetNext(e)
|
||||
} else {
|
||||
l.head = e
|
||||
}
|
||||
l.tail = e
|
||||
}
|
||||
|
||||
// 将m尾插到l,然后清除m
|
||||
func (l *List) PushBackList(m *List) {
|
||||
// 如果没有
|
||||
if l.head == nil {
|
||||
l.head = m.head
|
||||
l.tail = m.tail
|
||||
} else {
|
||||
ElementMapper{}.linkerFor(l.tail).SetNext(m.head)
|
||||
ElementMapper{}.linkerFor(m.head).SetPrev(l.tail)
|
||||
l.tail = m.tail
|
||||
}
|
||||
m.head = nil
|
||||
m.tail = nil
|
||||
}
|
||||
|
||||
func (l *List) InsertAfter(b, e Element) {
|
||||
a := ElementMapper{}.linkerFor(b).Next()
|
||||
ElementMapper{}.linkerFor(e).SetNext(a)
|
||||
ElementMapper{}.linkerFor(e).SetPrev(b)
|
||||
ElementMapper{}.linkerFor(b).SetNext(e)
|
||||
|
||||
if a != nil {
|
||||
ElementMapper{}.linkerFor(a).SetPrev(e)
|
||||
} else {
|
||||
l.tail = e
|
||||
}
|
||||
}
|
||||
|
||||
func (l *List) InsertBefore(a, e Element) {
|
||||
b := ElementMapper{}.linkerFor(a).Prev()
|
||||
ElementMapper{}.linkerFor(e).SetPrev(b)
|
||||
ElementMapper{}.linkerFor(e).SetNext(a)
|
||||
ElementMapper{}.linkerFor(a).SetPrev(e)
|
||||
|
||||
if b != nil {
|
||||
ElementMapper{}.linkerFor(b).SetNext(e)
|
||||
} else {
|
||||
l.head = e
|
||||
}
|
||||
}
|
||||
|
||||
func (l *List) Remove(e Element) {
|
||||
prev := ElementMapper{}.linkerFor(e).Prev()
|
||||
next := ElementMapper{}.linkerFor(e).Next()
|
||||
|
||||
if prev != nil {
|
||||
ElementMapper{}.linkerFor(prev).SetNext(next)
|
||||
} else {
|
||||
l.tail = next
|
||||
}
|
||||
|
||||
if next != nil {
|
||||
ElementMapper{}.linkerFor(next).SetPrev(prev)
|
||||
} else {
|
||||
l.tail = prev
|
||||
}
|
||||
}
|
||||
|
||||
type Entry struct {
|
||||
next Element
|
||||
prev Element
|
||||
}
|
||||
|
||||
func (e *Entry) Next() Element {
|
||||
return e.next
|
||||
}
|
||||
|
||||
func (e *Entry) Prev() Element {
|
||||
return e.prev
|
||||
}
|
||||
|
||||
func (e *Entry) SetNext(elem Element) {
|
||||
e.next = elem
|
||||
}
|
||||
|
||||
func (e *Entry) SetPrev(elem Element) {
|
||||
e.prev = elem
|
||||
}
|
@@ -38,9 +38,6 @@ type endpoint struct {
|
||||
views []buffer.View
|
||||
dispatcher stack.NetworkDispatcher
|
||||
|
||||
// handleLocal indicates whether packets destined to itself should be
|
||||
// handled by the netstack internally (true) or be forwarded to the FD
|
||||
// endpoint (false).
|
||||
// handleLocal指示发往自身的数据包是由内部netstack处理(true)还是转发到FD端点(false)。
|
||||
// Resend packets back to netstack if destined to itself
|
||||
// Add option to redirect packet back to netstack if it's destined to itself.
|
||||
|
8
tcpip/seqnum/seqnum.go
Normal file
8
tcpip/seqnum/seqnum.go
Normal file
@@ -0,0 +1,8 @@
|
||||
// 包 seqnum 定义了 TCP 序列号的类型和方法,以便它们适合 32 位字并在发生溢出时正常工作
|
||||
package seqnum
|
||||
|
||||
// 一个序列号的值
|
||||
type Value uint32
|
||||
|
||||
// size表示一个序号窗口的大小(长度)
|
||||
type Size uint32
|
@@ -4,6 +4,7 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/impact-eintr/netstack/tcpip"
|
||||
"github.com/impact-eintr/netstack/tcpip/ilist"
|
||||
)
|
||||
|
||||
type referencedNetworkEndpoint struct {
|
||||
@@ -33,7 +34,24 @@ type NIC struct {
|
||||
promiscuous bool
|
||||
primary map[tcpip.NetworkProtocolNumber]*ilist.List
|
||||
// 网络层端的记录
|
||||
endpoints map[tcpip.NetworkEndpointID]*referencedNetworkEndpoint
|
||||
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
|
||||
}
|
||||
|
@@ -2,10 +2,12 @@ package stack
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"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 {
|
||||
@@ -45,4 +47,42 @@ 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)
|
||||
}
|
||||
|
Reference in New Issue
Block a user