mirror of
https://github.com/impact-eintr/netstack.git
synced 2025-10-05 21:06:50 +08:00
年轻人的第一条tcp数据 xdm终于拿到客户端送过来的数据了 果然是之前挖的坑 接收窗口初始化了个0 还以为握手没成功在重试...
This commit is contained in:
@@ -2,20 +2,25 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
go func() {
|
go func() {
|
||||||
_, err := net.Dial("tcp", "192.168.1.1:9999")
|
conn, err := net.Dial("tcp", "192.168.1.1:9999")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("err : ", err)
|
fmt.Println("err : ", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
log.Println("连接建立")
|
||||||
|
conn.Write([]byte("helloworld"))
|
||||||
|
log.Println("发送了数据")
|
||||||
|
conn.Close()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
t := time.NewTimer(500 * time.Millisecond)
|
t := time.NewTimer(1000 * time.Millisecond)
|
||||||
select {
|
select {
|
||||||
case <-t.C:
|
case <-t.C:
|
||||||
return
|
return
|
||||||
|
@@ -68,7 +68,6 @@
|
|||||||
package sleep
|
package sleep
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
@@ -233,9 +232,9 @@ func (s *Sleeper) Fetch(block bool) (id int, ok bool) {
|
|||||||
// Reassociate the waker with the sleeper. If the waker was
|
// Reassociate the waker with the sleeper. If the waker was
|
||||||
// still asserted we can return it, otherwise try the next one.
|
// still asserted we can return it, otherwise try the next one.
|
||||||
old := (*Sleeper)(atomic.SwapPointer(&w.s, usleeper(s)))
|
old := (*Sleeper)(atomic.SwapPointer(&w.s, usleeper(s)))
|
||||||
log.Println("Sleeper", unsafe.Pointer(s), "old", unsafe.Pointer(old), "&assertSleeper", unsafe.Pointer(&assertedSleeper), "w.id", w.id)
|
//log.Println("Sleeper", unsafe.Pointer(s), "old", unsafe.Pointer(old), "&assertSleeper", unsafe.Pointer(&assertedSleeper), "w.id", w.id)
|
||||||
if old == &assertedSleeper {
|
if old == &assertedSleeper {
|
||||||
log.Println("成功返回 没有阻塞")
|
//log.Println("成功返回 没有阻塞")
|
||||||
return w.id, true
|
return w.id, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -12,6 +12,7 @@ import (
|
|||||||
"netstack/tcpip/header"
|
"netstack/tcpip/header"
|
||||||
"netstack/tcpip/seqnum"
|
"netstack/tcpip/seqnum"
|
||||||
"netstack/tcpip/stack"
|
"netstack/tcpip/stack"
|
||||||
|
"netstack/waiter"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -246,18 +247,30 @@ func (l *listenContext) createEndpointAndPerformHandshake(s *segment, opts *head
|
|||||||
return ep, nil
|
return ep, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *endpoint) deliverAccepted(n *endpoint) {
|
||||||
|
e.mu.RLock()
|
||||||
|
if e.state == stateListen {
|
||||||
|
e.acceptedChan <- n
|
||||||
|
e.waiterQueue.Notify(waiter.EventIn)
|
||||||
|
} else {
|
||||||
|
n.Close()
|
||||||
|
}
|
||||||
|
e.mu.RUnlock()
|
||||||
|
}
|
||||||
|
|
||||||
// 一旦侦听端点收到SYN段,handleSynSegment就会在其自己的goroutine中调用。它负责完成握手并将新端点排队以进行接受。
|
// 一旦侦听端点收到SYN段,handleSynSegment就会在其自己的goroutine中调用。它负责完成握手并将新端点排队以进行接受。
|
||||||
// 在TCP开始使用SYN cookie接受连接之前,允许使用有限数量的这些goroutine。
|
// 在TCP开始使用SYN cookie接受连接之前,允许使用有限数量的这些goroutine。
|
||||||
func (e *endpoint) handleSynSegment(ctx *listenContext, s *segment, opts *header.TCPSynOptions) {
|
func (e *endpoint) handleSynSegment(ctx *listenContext, s *segment, opts *header.TCPSynOptions) {
|
||||||
defer decSynRcvdCount()
|
defer decSynRcvdCount()
|
||||||
defer s.decRef()
|
defer s.decRef()
|
||||||
|
|
||||||
_, err := ctx.createEndpointAndPerformHandshake(s, opts)
|
// 这里返回的 n 是一个新的tcp端: LAddr:Port+RAddr:RPort
|
||||||
|
n, err := ctx.createEndpointAndPerformHandshake(s, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 到这里,三次握手已经完成,那么分发一个新的连接
|
// 到这里,三次握手已经完成,那么分发一个新的连接
|
||||||
//e.deliverAccepted(n)
|
e.deliverAccepted(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleListenSegment is called when a listening endpoint receives a segment
|
// handleListenSegment is called when a listening endpoint receives a segment
|
||||||
|
@@ -155,6 +155,107 @@ func (h *handshake) resolveRoute() *tcpip.Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checkAck checks if the ACK number, if present, of a segment received during
|
||||||
|
// a TCP 3-way handshake is valid. If it's not, a RST segment is sent back in
|
||||||
|
// response.
|
||||||
|
func (h *handshake) checkAck(s *segment) bool {
|
||||||
|
if s.flagIsSet(flagAck) && s.ackNumber != h.iss+1 {
|
||||||
|
// RFC 793, page 36, states that a reset must be generated when
|
||||||
|
// the connection is in any non-synchronized state and an
|
||||||
|
// incoming segment acknowledges something not yet sent. The
|
||||||
|
// connection remains in the same state.
|
||||||
|
// TODO 返回一个RST报文
|
||||||
|
//ack := s.sequenceNumber.Add(s.logicalLen())
|
||||||
|
//h.ep.sendRaw(buffer.VectorisedView{}, flagRst|flagAck, s.ackNumber, ack, 0)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// synSentState 是客户端或者服务端接收到第一个握手报文的处理
|
||||||
|
// 正常情况下,如果是客户端,此时应该收到 syn+ack 报文,处理后发送 ack 报文给服务端。
|
||||||
|
// 如果是服务端,此时接收到syn报文,那么应该回复 syn+ack 报文给客户端,并设置状态为 handshakeSynRcvd。
|
||||||
|
func (h *handshake) synSentState(s *segment) *tcpip.Error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// synRcvdState handles a segment received when the TCP 3-way handshake is in
|
||||||
|
// the SYN-RCVD state.
|
||||||
|
// 正常情况下,会调用该函数来处理第三次 ack 报文
|
||||||
|
func (h *handshake) synRcvdState(s *segment) *tcpip.Error {
|
||||||
|
if s.flagIsSet(flagRst) {
|
||||||
|
// TODO 需要根据窗口返回 等理解了窗口后再写
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// 校验ack报文
|
||||||
|
if !h.checkAck(s) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果是syn报文,且序列号对应不上,那么返回 rst
|
||||||
|
if s.flagIsSet(flagSyn) && s.sequenceNumber != h.ackNum-1 {
|
||||||
|
// TODO 返回RST报文
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果时ack报文 表示三次握手已经完成
|
||||||
|
if s.flagIsSet(flagAck) {
|
||||||
|
// TODO 修改时间戳
|
||||||
|
h.state = handshakeCompleted
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 握手的时候处理tcp段
|
||||||
|
func (h *handshake) handleSegment(s *segment) *tcpip.Error {
|
||||||
|
h.sndWnd = s.window
|
||||||
|
if !s.flagIsSet(flagSyn) && h.sndWndScale > 0 {
|
||||||
|
h.sndWnd <<= uint8(h.sndWndScale)
|
||||||
|
}
|
||||||
|
log.Println(h.sndWnd)
|
||||||
|
|
||||||
|
switch h.state {
|
||||||
|
case handshakeSynRcvd:
|
||||||
|
// 正常情况下,服务端接收客户端第三次 ack 报文
|
||||||
|
return h.synRcvdState(s)
|
||||||
|
case handshakeSynSent:
|
||||||
|
// 客户端发送了syn报文后的处理
|
||||||
|
return h.synSentState(s)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// processSegments goes through the segment queue and processes up to
|
||||||
|
// maxSegmentsPerWake (if they're available).
|
||||||
|
func (h *handshake) processSegments() *tcpip.Error {
|
||||||
|
|
||||||
|
log.Println("处理握手报文")
|
||||||
|
for i := 0; i < maxSegmentsPerWake; i++ {
|
||||||
|
// 从建立中的连接队列里取一个报文段
|
||||||
|
s := h.ep.segmentQueue.dequeue()
|
||||||
|
if s == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
err := h.handleSegment(s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if h.state == handshakeCompleted {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If the queue is not empty, make sure we'll wake up in the next
|
||||||
|
// iteration.
|
||||||
|
if !h.ep.segmentQueue.empty() {
|
||||||
|
h.ep.newSegmentWaker.Assert()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// execute executes the TCP 3-way handshake.
|
// execute executes the TCP 3-way handshake.
|
||||||
// 执行tcp 3次握手,客户端和服务端都是调用该函数来实现三次握手
|
// 执行tcp 3次握手,客户端和服务端都是调用该函数来实现三次握手
|
||||||
/*
|
/*
|
||||||
@@ -216,6 +317,9 @@ func (h *handshake) execute() *tcpip.Error {
|
|||||||
|
|
||||||
case wakerForNewSegment:
|
case wakerForNewSegment:
|
||||||
// 处理握手报文
|
// 处理握手报文
|
||||||
|
if err := h.processSegments(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -353,8 +457,50 @@ func sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.Vectorise
|
|||||||
return r.WritePacket(hdr, data, ProtocolNumber, ttl)
|
return r.WritePacket(hdr, data, ProtocolNumber, ttl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 从发送队列中取出数据并发送出去
|
||||||
|
func (e *endpoint) handleWrite() *tcpip.Error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭连接的处理,最终会调用 sendData 来发送 fin 包
|
||||||
|
func (e *endpoint) handleClose() *tcpip.Error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// handleSegments 从队列中取出 tcp 段数据,然后处理它们。
|
// handleSegments 从队列中取出 tcp 段数据,然后处理它们。
|
||||||
func (e *endpoint) handleSegments() *tcpip.Error {
|
func (e *endpoint) handleSegments() *tcpip.Error {
|
||||||
|
log.Println("年轻人的第一条数据")
|
||||||
|
checkRequeue := true
|
||||||
|
for i := 0; i < maxSegmentsPerWake; i++ {
|
||||||
|
s := e.segmentQueue.dequeue()
|
||||||
|
if s == nil {
|
||||||
|
checkRequeue = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if s.flagIsSet(flagRst) {
|
||||||
|
// TODO 如果收到 rst 报文
|
||||||
|
s.decRef()
|
||||||
|
return tcpip.ErrConnectionReset
|
||||||
|
} else if s.flagIsSet(flagAck) {
|
||||||
|
// 处理正常报文
|
||||||
|
|
||||||
|
// RFC 793, page 41 states that "once in the ESTABLISHED
|
||||||
|
// state all segments must carry current acknowledgment
|
||||||
|
// information."
|
||||||
|
// 处理tcp数据段,同时给接收器和发送器
|
||||||
|
// 为何要给发送器传接收到的数据段呢?主要是为了滑动窗口的滑动和拥塞控制处理
|
||||||
|
e.rcv.handleRcvdSegment(s)
|
||||||
|
//e.snd.handleRcvdSegment(s)
|
||||||
|
}
|
||||||
|
s.decRef() // 该segment处理完成
|
||||||
|
}
|
||||||
|
// If the queue is not empty, make sure we'll wake up in the next
|
||||||
|
// iteration.
|
||||||
|
if checkRequeue && !e.segmentQueue.empty() {
|
||||||
|
e.newSegmentWaker.Assert()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO 需要添加
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,8 +513,14 @@ func (e *endpoint) protocolMainLoop(handshake bool) *tcpip.Error {
|
|||||||
w *sleep.Waker
|
w *sleep.Waker
|
||||||
f func() *tcpip.Error
|
f func() *tcpip.Error
|
||||||
}{
|
}{
|
||||||
{},
|
{
|
||||||
{},
|
w: &e.sndWaker,
|
||||||
|
f: e.handleWrite,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
w: &e.sndCloseWaker,
|
||||||
|
f: e.handleClose,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
w: &e.newSegmentWaker,
|
w: &e.newSegmentWaker,
|
||||||
f: e.handleSegments,
|
f: e.handleSegments,
|
||||||
@@ -395,7 +547,7 @@ func (e *endpoint) protocolMainLoop(handshake bool) *tcpip.Error {
|
|||||||
if err := funcs[v].f(); err != nil {
|
if err := funcs[v].f(); err != nil {
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
//e.resetConnectionLocked(err)
|
//e.resetConnectionLocked(err)
|
||||||
//// Lock released below.
|
// Lock released below.
|
||||||
//epilogue()
|
//epilogue()
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return nil
|
return nil
|
||||||
|
@@ -214,7 +214,7 @@ func (e *endpoint) Listen(backlog int) (err *tcpip.Error) {
|
|||||||
|
|
||||||
e.stack.Stats().TCP.PassiveConnectionOpenings.Increment()
|
e.stack.Stats().TCP.PassiveConnectionOpenings.Increment()
|
||||||
// tcp服务端实现的主循环,这个函数很重要,用一个goroutine来服务
|
// tcp服务端实现的主循环,这个函数很重要,用一个goroutine来服务
|
||||||
go e.protocolListenLoop(seqnum.Size(0))
|
go e.protocolListenLoop(seqnum.Size(e.receiveBufferAvailable()))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -239,6 +239,7 @@ func (e *endpoint) Accept() (tcpip.Endpoint, *waiter.Queue, *tcpip.Error) {
|
|||||||
var n *endpoint
|
var n *endpoint
|
||||||
select {
|
select {
|
||||||
case n = <-e.acceptedChan:
|
case n = <-e.acceptedChan:
|
||||||
|
log.Println("监听者进行一个新连接的分发", n.id)
|
||||||
default:
|
default:
|
||||||
return nil, nil, tcpip.ErrWouldBlock
|
return nil, nil, tcpip.ErrWouldBlock
|
||||||
}
|
}
|
||||||
@@ -384,6 +385,25 @@ func (e *endpoint) HandleControlPacket(id stack.TransportEndpointID, typ stack.C
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// receiveBufferAvailable calculates how many bytes are still available in the
|
||||||
|
// receive buffer.
|
||||||
|
// tcp流量控制:计算未被占用的接收缓存大小
|
||||||
|
func (e *endpoint) receiveBufferAvailable() int {
|
||||||
|
e.rcvListMu.Lock()
|
||||||
|
size := e.rcvBufSize
|
||||||
|
used := e.rcvBufUsed
|
||||||
|
e.rcvListMu.Unlock()
|
||||||
|
|
||||||
|
// We may use more bytes than the buffer size when the receive buffer
|
||||||
|
// shrinks.
|
||||||
|
if used >= size {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("Init Recv Windeow Size: ", size-used)
|
||||||
|
return size - used
|
||||||
|
}
|
||||||
|
|
||||||
// maybeEnableTimestamp marks the timestamp option enabled for this endpoint if
|
// maybeEnableTimestamp marks the timestamp option enabled for this endpoint if
|
||||||
// the SYN options indicate that timestamp option was negotiated. It also
|
// the SYN options indicate that timestamp option was negotiated. It also
|
||||||
// initializes the recentTS with the value provided in synOpts.TSval.
|
// initializes the recentTS with the value provided in synOpts.TSval.
|
||||||
|
@@ -1,6 +1,9 @@
|
|||||||
package tcp
|
package tcp
|
||||||
|
|
||||||
import "netstack/tcpip/seqnum"
|
import (
|
||||||
|
"log"
|
||||||
|
"netstack/tcpip/seqnum"
|
||||||
|
)
|
||||||
|
|
||||||
type receiver struct{}
|
type receiver struct{}
|
||||||
|
|
||||||
@@ -9,3 +12,11 @@ func newReceiver(ep *endpoint, irs seqnum.Value, rcvWnd seqnum.Size, rcvWndScale
|
|||||||
r := &receiver{}
|
r := &receiver{}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleRcvdSegment handles TCP segments directed at the connection managed by
|
||||||
|
// r as they arrive. It is called by the protocol main loop.
|
||||||
|
// 从 handleSegments 接收到tcp段,然后进行处理消费,所谓的消费就是将负载内容插入到接收队列中
|
||||||
|
func (r *receiver) handleRcvdSegment(s *segment) {
|
||||||
|
log.Println(s.data)
|
||||||
|
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user