mirror of
https://github.com/impact-eintr/netstack.git
synced 2025-10-07 22:01:17 +08:00
tcp太痛苦了 功能好多流程还都杂糅在一起
This commit is contained in:
@@ -4,28 +4,17 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
go func() {
|
conn, 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
|
|
||||||
}
|
|
||||||
log.Println("连接建立")
|
|
||||||
conn.Write([]byte("helloworld"))
|
|
||||||
log.Println("发送了数据")
|
|
||||||
//buf := make([]byte, 1024)
|
|
||||||
//conn.Read(buf)
|
|
||||||
conn.Close()
|
|
||||||
}()
|
|
||||||
|
|
||||||
t := time.NewTimer(1000 * time.Millisecond)
|
|
||||||
select {
|
|
||||||
case <-t.C:
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
//buf := make([]byte, 1024)
|
||||||
|
//conn.Read(buf)
|
||||||
|
if err = conn.Close(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -222,7 +222,7 @@ func (l *listenContext) createEndpointAndPerformHandshake(s *segment, opts *head
|
|||||||
irs := s.sequenceNumber
|
irs := s.sequenceNumber
|
||||||
cookie := l.createCookie(s.id, irs, encodeMSS(opts.MSS))
|
cookie := l.createCookie(s.id, irs, encodeMSS(opts.MSS))
|
||||||
logger.GetInstance().Info(logger.HANDSHAKE, func() {
|
logger.GetInstance().Info(logger.HANDSHAKE, func() {
|
||||||
log.Println("收到一个远端握手申请", irs, "客户端请携带 标记 iss", cookie)
|
log.Println("收到一个远端握手申请 SYN seq=", irs, "客户端请携带 标记 iss ", cookie, "+1")
|
||||||
})
|
})
|
||||||
ep, err := l.createConnectedEndpoint(s, cookie, irs, opts)
|
ep, err := l.createConnectedEndpoint(s, cookie, irs, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -95,11 +95,11 @@ func (h *handshake) resetState() *tcpip.Error {
|
|||||||
}
|
}
|
||||||
// 初始化状态为 SynSent
|
// 初始化状态为 SynSent
|
||||||
h.state = handshakeSynSent
|
h.state = handshakeSynSent
|
||||||
log.Println("收到 syn 同步报文 设置tcp状态为 [sent]")
|
|
||||||
h.flags = flagSyn
|
h.flags = flagSyn
|
||||||
h.ackNum = 0
|
h.ackNum = 0
|
||||||
h.mss = 0
|
h.mss = 0
|
||||||
h.iss = seqnum.Value(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)
|
h.iss = seqnum.Value(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)
|
||||||
|
log.Println("收到 syn 同步报文 设置tcp状态为 [sent]")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -109,7 +109,6 @@ func (h *handshake) resetState() *tcpip.Error {
|
|||||||
func (h *handshake) resetToSynRcvd(iss seqnum.Value, irs seqnum.Value, opts *header.TCPSynOptions) {
|
func (h *handshake) resetToSynRcvd(iss seqnum.Value, irs seqnum.Value, opts *header.TCPSynOptions) {
|
||||||
h.active = false
|
h.active = false
|
||||||
h.state = handshakeSynRcvd
|
h.state = handshakeSynRcvd
|
||||||
log.Println("发送 syn|ack 确认报文 设置tcp状态为 [rcvd]")
|
|
||||||
h.flags = flagSyn | flagAck
|
h.flags = flagSyn | flagAck
|
||||||
h.iss = iss
|
h.iss = iss
|
||||||
h.ackNum = irs + 1 // NOTE ACK = synNum + 1
|
h.ackNum = irs + 1 // NOTE ACK = synNum + 1
|
||||||
@@ -448,7 +447,7 @@ func sendTCP(r *stack.Route, id stack.TransportEndpointID, data buffer.Vectorise
|
|||||||
r.Stats().TCP.ResetsSent.Increment()
|
r.Stats().TCP.ResetsSent.Increment()
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("send tcp %s segment to %s, seq: %d, ack: %d, rcvWnd: %d",
|
log.Printf("send tcp %s segment to %s, seq: |%d|, ack: %d, rcvWnd: %d",
|
||||||
flagString(flags), fmt.Sprintf("%s:%d", id.RemoteAddress, id.RemotePort),
|
flagString(flags), fmt.Sprintf("%s:%d", id.RemoteAddress, id.RemotePort),
|
||||||
seq, ack, rcvWnd)
|
seq, ack, rcvWnd)
|
||||||
|
|
||||||
@@ -538,7 +537,7 @@ func (e *endpoint) handleSegments() *tcpip.Error {
|
|||||||
// 处理tcp数据段,同时给接收器和发送器
|
// 处理tcp数据段,同时给接收器和发送器
|
||||||
// 为何要给发送器传接收到的数据段呢?主要是为了滑动窗口的滑动和拥塞控制处理
|
// 为何要给发送器传接收到的数据段呢?主要是为了滑动窗口的滑动和拥塞控制处理
|
||||||
e.rcv.handleRcvdSegment(s)
|
e.rcv.handleRcvdSegment(s)
|
||||||
//e.snd.handleRcvdSegment(s)
|
e.snd.handleRcvdSegment(s)
|
||||||
}
|
}
|
||||||
s.decRef() // 该segment处理完成
|
s.decRef() // 该segment处理完成
|
||||||
}
|
}
|
||||||
|
@@ -599,7 +599,7 @@ func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, vv
|
|||||||
if _, err := e.GetRemoteAddress(); err != nil {
|
if _, err := e.GetRemoteAddress(); err != nil {
|
||||||
prifix = "监听者"
|
prifix = "监听者"
|
||||||
}
|
}
|
||||||
log.Printf(prifix+"收到 tcp [%s] 报文片段 from %s, seq: %d, ack: %d",
|
log.Printf(prifix+"收到 tcp [%s] 报文片段 from %s, seq: %d, ack: |%d|",
|
||||||
flagString(s.flags), fmt.Sprintf("%s:%d", s.id.RemoteAddress, s.id.RemotePort),
|
flagString(s.flags), fmt.Sprintf("%s:%d", s.id.RemoteAddress, s.id.RemotePort),
|
||||||
s.sequenceNumber, s.ackNumber)
|
s.sequenceNumber, s.ackNumber)
|
||||||
|
|
||||||
|
@@ -24,7 +24,7 @@ type receiver struct {
|
|||||||
func newReceiver(ep *endpoint, irs seqnum.Value, rcvWnd seqnum.Size, rcvWndScale uint8) *receiver {
|
func newReceiver(ep *endpoint, irs seqnum.Value, rcvWnd seqnum.Size, rcvWndScale uint8) *receiver {
|
||||||
r := &receiver{
|
r := &receiver{
|
||||||
ep: ep,
|
ep: ep,
|
||||||
rcvNxt: irs + 1,
|
rcvNxt: irs + 1, // 成功建立连接后期望读取的第一个字节序号
|
||||||
rcvAcc: irs.Add(rcvWnd + 1),
|
rcvAcc: irs.Add(rcvWnd + 1),
|
||||||
rcvWndScale: rcvWndScale,
|
rcvWndScale: rcvWndScale,
|
||||||
}
|
}
|
||||||
@@ -78,7 +78,6 @@ func (r *receiver) consumeSegment(s *segment, segSeq seqnum.Value, segLen seqnum
|
|||||||
r.rcvNxt = segSeq.Add(segLen)
|
r.rcvNxt = segSeq.Add(segLen)
|
||||||
logger.GetInstance().Info(logger.TCP, func() {
|
logger.GetInstance().Info(logger.TCP, func() {
|
||||||
})
|
})
|
||||||
log.Println("下一个期望接收的字节序列号", r.rcvNxt)
|
|
||||||
|
|
||||||
// 如果收到 fin 报文
|
// 如果收到 fin 报文
|
||||||
if s.flagIsSet(flagFin) {
|
if s.flagIsSet(flagFin) {
|
||||||
@@ -86,7 +85,7 @@ func (r *receiver) consumeSegment(s *segment, segSeq seqnum.Value, segLen seqnum
|
|||||||
r.rcvNxt++
|
r.rcvNxt++
|
||||||
|
|
||||||
// 收到 fin,立即回复 ack
|
// 收到 fin,立即回复 ack
|
||||||
r.ep.snd.sendAck()
|
r.ep.snd.sendAck() // FIXME 不应该是 seq+2 捏
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package tcp
|
package tcp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"netstack/tcpip"
|
"netstack/tcpip"
|
||||||
"netstack/tcpip/buffer"
|
"netstack/tcpip/buffer"
|
||||||
"netstack/tcpip/seqnum"
|
"netstack/tcpip/seqnum"
|
||||||
@@ -66,7 +67,9 @@ func newSender(ep *endpoint, iss, irs seqnum.Value, sndWnd seqnum.Size, mss uint
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *sender) sendAck() {
|
func (s *sender) sendAck() {
|
||||||
s.sendSegment(buffer.VectorisedView{}, flagAck, s.sndNxt)
|
log.Println("发送字节序", s.sndNxt)
|
||||||
|
s.sendSegment(buffer.VectorisedView{}, flagAck, s.sndNxt) // seq = cookies+1 ack ack|fin.seq+1
|
||||||
|
s.sendSegment(buffer.VectorisedView{}, flagFin, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendSegment sends a new segment containing the given payload, flags and
|
// sendSegment sends a new segment containing the given payload, flags and
|
||||||
@@ -85,3 +88,15 @@ func (s *sender) sendSegment(data buffer.VectorisedView, flags byte, seq seqnum.
|
|||||||
|
|
||||||
return s.ep.sendRaw(data, flags, seq, rcvNxt, rcvWnd)
|
return s.ep.sendRaw(data, flags, seq, rcvNxt, rcvWnd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 收到段时调用 handleRcvdSegment 它负责更新与发送相关的状态
|
||||||
|
func (s *sender) handleRcvdSegment(seg *segment) {
|
||||||
|
// 现在某些待处理数据已被确认,或者窗口打开,或者由于快速恢复期间出现重复的ack而导致拥塞窗口膨胀,
|
||||||
|
// 因此发送更多数据。如果需要,这也将重新启用重传计时器。
|
||||||
|
s.sendData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送数据段,最终调用 sendSegment 来发送
|
||||||
|
func (s *sender) sendData() {
|
||||||
|
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user