More comments and stats in TCP code.

git-svn-id: svn://kolibrios.org@6476 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2016-08-15 18:06:19 +00:00
parent b4e2367e09
commit 58663b49dd
6 changed files with 458 additions and 231 deletions

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;; ;; ;;
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; Part of the TCP/IP network stack for KolibriOS ;; ;; Part of the TCP/IP network stack for KolibriOS ;;
@ -73,8 +73,8 @@ struct TCP_SOCKET IP_SOCKET
SND_UNA dd ? ; sequence number of unack'ed sent Packets SND_UNA dd ? ; sequence number of unack'ed sent Packets
SND_NXT dd ? ; next send sequence number to use SND_NXT dd ? ; next send sequence number to use
SND_UP dd ? ; urgent pointer SND_UP dd ? ; urgent pointer
SND_WL1 dd ? ; window minus one SND_WL1 dd ? ; the sequence number of the last segment used to update the send window
SND_WL2 dd ? ; SND_WL2 dd ? ; the acknowledgment number of the last segment used to update the send window
ISS dd ? ; initial send sequence number ISS dd ? ; initial send sequence number
SND_WND dd ? ; send window SND_WND dd ? ; send window

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;; ;; ;;
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; STACK.INC ;; ;; STACK.INC ;;
@ -91,6 +91,7 @@ SO_REUSEADDR = 1 shl 6
SO_REUSEPORT = 1 shl 7 SO_REUSEPORT = 1 shl 7
SO_USELOOPBACK = 1 shl 8 SO_USELOOPBACK = 1 shl 8
SO_BINDTODEVICE = 1 shl 9 SO_BINDTODEVICE = 1 shl 9
SO_LINGER = 1 shl 10
SO_NONBLOCK = 1 shl 31 SO_NONBLOCK = 1 shl 31
@ -131,11 +132,12 @@ EINVAL = 11
EMSGSIZE = 12 EMSGSIZE = 12
ENOMEM = 18 ENOMEM = 18
EADDRINUSE = 20 EADDRINUSE = 20
ECONNREFUSED = 61 EADDRNOTAVAIL = 21
ECONNRESET = 52 ECONNRESET = 52
ECONNABORTED = 53
EISCONN = 56 EISCONN = 56
ETIMEDOUT = 60 ETIMEDOUT = 60
ECONNABORTED = 53 ECONNREFUSED = 61
; Api protocol numbers ; Api protocol numbers
API_ETH = 0 API_ETH = 0

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;; ;; ;;
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; Part of the TCP/IP network stack for KolibriOS ;; ;; Part of the TCP/IP network stack for KolibriOS ;;
@ -27,7 +27,7 @@ TCPS_FIN_WAIT_1 = 6
TCPS_CLOSING = 7 TCPS_CLOSING = 7
TCPS_LAST_ACK = 8 TCPS_LAST_ACK = 8
TCPS_FIN_WAIT_2 = 9 TCPS_FIN_WAIT_2 = 9
TCPS_TIMED_WAIT = 10 TCPS_TIME_WAIT = 10
; Socket Flags ; Socket Flags
TF_ACKNOW = 1 shl 0 ; ack peer immediately TF_ACKNOW = 1 shl 0 ; ack peer immediately
@ -92,18 +92,12 @@ TCP_mss_default = 1480 ; default max segment size
TCP_RTT_SHIFT = 3 TCP_RTT_SHIFT = 3
TCP_RTTVAR_SHIFT = 2 TCP_RTTVAR_SHIFT = 2
; bits used by tcp_input and tcp_output
TCP_BIT_NEEDOUTPUT = 1 shl 0
TCP_BIT_TIMESTAMP = 1 shl 1
TCP_BIT_DROPSOCKET = 1 shl 2
TCP_BIT_FIN_IS_ACKED = 1 shl 3
TCP_BIT_SENDALOT = 1 shl 0
TCP_PAWS_IDLE = 24*24*60*60*100 ; 24 days, in 1/100 seconds TCP_PAWS_IDLE = 24*24*60*60*100 ; 24 days, in 1/100 seconds
TCP_QUEUE_SIZE = 50 TCP_QUEUE_SIZE = 50
TCP_ISSINCR = 128000
struct TCP_header struct TCP_header
SourcePort dw ? SourcePort dw ?

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,8 @@
$Revision$ $Revision$
TCP_BIT_SENDALOT = 1 shl 0
;-----------------------------------------------------------------; ;-----------------------------------------------------------------;
; ; ; ;
; tcp_output ; ; tcp_output ;
@ -64,16 +66,22 @@ endl
.again: .again:
mov [temp_bits], 0 mov [temp_bits], 0
mov ebx, [eax + TCP_SOCKET.SND_NXT] ; calculate offset (71) ; Calculate offset
sub ebx, [eax + TCP_SOCKET.SND_UNA] ;
mov ecx, [eax + TCP_SOCKET.SND_WND] ; determine window mov ebx, [eax + TCP_SOCKET.SND_NXT]
cmp ecx, [eax + TCP_SOCKET.SND_CWND] ; sub ebx, [eax + TCP_SOCKET.SND_UNA]
jb @f ;
mov ecx, [eax + TCP_SOCKET.SND_CWND] ;
@@: ;
call tcp_outflags ; flags in dl ; Determine window
mov ecx, [eax + TCP_SOCKET.SND_WND]
cmp ecx, [eax + TCP_SOCKET.SND_CWND]
jb @f
mov ecx, [eax + TCP_SOCKET.SND_CWND]
@@:
; get flags in dl
call tcp_outflags
;------------------------ ;------------------------
; data being forced out ? ; data being forced out ?
@ -105,7 +113,7 @@ endl
.no_force: .no_force:
;-------------------------------- ;--------------------------------
; Calculate how much data to send (106) ; Calculate how much data to send
mov esi, [eax + STREAM_SOCKET.snd.size] mov esi, [eax + STREAM_SOCKET.snd.size]
cmp esi, ecx cmp esi, ecx
@ -115,24 +123,28 @@ endl
sub esi, ebx sub esi, ebx
;------------------------ ;------------------------
; check for window shrink (107) ; check for window shrink
; If FIN has been set, but not ACKed, but we havent been called to retransmit, esi will be -1 ; If FIN has been sent, but not ACKed, but we havent been called to retransmit, esi will be -1
; Otherwise, window shrank after we sent into it. ; Otherwise, window shrank after we sent into it.
jae .not_persist jae .not_persist
; enter persist state ; enter persist state
xor esi, esi xor esi, esi
; If window shrank to 0 ; If window shrank to 0
test ecx, ecx test ecx, ecx
jnz @f jnz @f
; cancel pending retransmit ; cancel pending retransmit
and [eax + TCP_SOCKET.timer_flags], not timer_flag_retransmission and [eax + TCP_SOCKET.timer_flags], not timer_flag_retransmission
; pull SND_NXT back to (closed) window, We will enter persist state below. ; pull SND_NXT back to (closed) window, We will enter persist state below.
push [eax + TCP_SOCKET.SND_UNA] push [eax + TCP_SOCKET.SND_UNA]
pop [eax + TCP_SOCKET.SND_NXT] pop [eax + TCP_SOCKET.SND_NXT]
@@: @@:
@ -142,7 +154,7 @@ endl
.not_persist: .not_persist:
;--------------------------- ;---------------------------
; Send one segment at a time (124) ; Send one segment at a time
cmp esi, [eax + TCP_SOCKET.t_maxseg] cmp esi, [eax + TCP_SOCKET.t_maxseg]
jbe @f jbe @f
@ -151,7 +163,7 @@ endl
@@: @@:
;-------------------------------------------- ;--------------------------------------------
; Turn of FIN flag if send buffer not emptied (128) ; Turn of FIN flag if send buffer not emptied
mov edi, [eax + TCP_SOCKET.SND_NXT] mov edi, [eax + TCP_SOCKET.SND_NXT]
add edi, esi add edi, esi
@ -162,13 +174,13 @@ endl
@@: @@:
;------------------------------- ;-------------------------------
; calculate window advertisement (130) ; calculate window advertisement
mov ecx, SOCKET_BUFFER_SIZE mov ecx, SOCKET_BUFFER_SIZE
sub ecx, [eax + STREAM_SOCKET.rcv.size] sub ecx, [eax + STREAM_SOCKET.rcv.size]
;------------------------------ ;------------------------------
; Sender silly window avoidance (131) ; Sender silly window avoidance
test esi, esi test esi, esi
jz .len_zero jz .len_zero
@ -203,7 +215,7 @@ endl
.len_zero: .len_zero:
;---------------------------------------- ;----------------------------------------
; Check if a window update should be sent (154) ; Check if a window update should be sent
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: window=%d\n", ecx DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: window=%d\n", ecx
@ -227,9 +239,10 @@ endl
sub ebx, [eax + TCP_SOCKET.RCV_ADV] sub ebx, [eax + TCP_SOCKET.RCV_ADV]
add ebx, [eax + TCP_SOCKET.RCV_NXT] add ebx, [eax + TCP_SOCKET.RCV_NXT]
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: we can increase window by %d bytes\n", ebx
mov edi, [eax + TCP_SOCKET.t_maxseg] mov edi, [eax + TCP_SOCKET.t_maxseg]
shl edi, 1 shl edi, 1
cmp ebx, edi cmp ebx, edi
jae .send jae .send
@ -240,7 +253,9 @@ endl
.no_window: .no_window:
;-------------------------- ;--------------------------
; Should a segment be sent? (174) ; Should a segment be sent?
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: Should a segment be sent?\n"
test [eax + TCP_SOCKET.t_flags], TF_ACKNOW ; we need to ACK test [eax + TCP_SOCKET.t_flags], TF_ACKNOW ; we need to ACK
jnz .send jnz .send
@ -252,20 +267,24 @@ endl
cmp ebx, [eax + TCP_SOCKET.SND_UNA] cmp ebx, [eax + TCP_SOCKET.SND_UNA]
ja .send ja .send
test dl, TH_FIN ; Do we need to send a FIN according to our state?
jz .enter_persist ; no reason to send, enter persist state
; FIN was set, only send if not already sent, or on retransmit test dl, TH_FIN
jz .enter_persist ; no reason to send, enter persist state
; Do so if we didnt do it already
test [eax + TCP_SOCKET.t_flags], TF_SENTFIN test [eax + TCP_SOCKET.t_flags], TF_SENTFIN
jz .send jz .send
; Or when we need to retransmit the FIN
mov ebx, [eax + TCP_SOCKET.SND_NXT] mov ebx, [eax + TCP_SOCKET.SND_NXT]
cmp ebx, [eax + TCP_SOCKET.SND_UNA] cmp ebx, [eax + TCP_SOCKET.SND_UNA]
je .send je .send
;-------------------- ;--------------------
; Enter persist state (191) ; Enter persist state
.enter_persist: .enter_persist:
@ -284,7 +303,7 @@ endl
@@: @@:
;---------------------------- ;----------------------------
; No reason to send a segment (219) ; No reason to send a segment
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: No reason to send a segment\n" DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: No reason to send a segment\n"
@ -300,7 +319,7 @@ endl
;----------------------------------------------- ;-----------------------------------------------
; ;
; Send a segment (222) ; Send a segment
; ;
; eax = socket pointer ; eax = socket pointer
; esi = data len ; esi = data len
@ -391,7 +410,7 @@ endl
; esi = data len ; esi = data len
;--------------------------------------------- ;---------------------------------------------
; check if we dont exceed the max segment size (270) ; check if we dont exceed the max segment size
add esi, edi ; total TCP segment size add esi, edi ; total TCP segment size
cmp esi, [eax + TCP_SOCKET.t_maxseg] cmp esi, [eax + TCP_SOCKET.t_maxseg]
@ -402,6 +421,7 @@ endl
.no_overflow: .no_overflow:
; Update stats ; Update stats
test esi, esi test esi, esi
jz .zero_data jz .zero_data
@ -482,25 +502,25 @@ endl
; Start by pushing all TCP header values in reverse order on stack ; Start by pushing all TCP header values in reverse order on stack
; (essentially, creating the tcp header on the stack!) ; (essentially, creating the tcp header on the stack!)
pushw 0 ; .UrgentPointer dw ? pushw 0 ; UrgentPointer
pushw 0 ; .Checksum dw ? pushw 0 ; Checksum
pushw bx ; .Window dw ? pushw bx ; Window
shl edi, 2 ; .DataOffset db ? only 4 left-most bits shl edi, 2 ; DataOffset
shl dx, 8 shl dx, 8
or dx, di ; .Flags db ? or dx, di ; Flags
pushw dx pushw dx
shr edi, 2 ; .DataOffset db ? shr edi, 2 ; DataOffset
push [eax + TCP_SOCKET.RCV_NXT] ; .AckNumber dd ? push [eax + TCP_SOCKET.RCV_NXT] ; AckNumber
ntohd [esp] ntohd [esp]
push [eax + TCP_SOCKET.SND_NXT] ; .SequenceNumber dd ? push [eax + TCP_SOCKET.SND_NXT] ; SequenceNumber
ntohd [esp] ntohd [esp]
push [eax + TCP_SOCKET.RemotePort] ; .DestinationPort dw ? push [eax + TCP_SOCKET.RemotePort] ; DestinationPort
push [eax + TCP_SOCKET.LocalPort] ; .SourcePort dw ? push [eax + TCP_SOCKET.LocalPort] ; SourcePort
push edi ; header size push edi ; header size
;--------------------- ;---------------------
; Create the IP packet ; Create the IP packet
@ -558,8 +578,8 @@ endl
pop ecx ; full packet size pop ecx ; full packet size
mov eax, [esp + 8] ; socket ptr mov eax, [esp + 8] ; socket ptr
;---------------------------------- ;----------------------------
; initialize retransmit timer (400) ; initialize retransmit timer
;TODO: check t_force and persist ;TODO: check t_force and persist
@ -584,6 +604,7 @@ endl
@@: @@:
; set retransmission timer if not already set, and not doing an ACK or keepalive probe ; set retransmission timer if not already set, and not doing an ACK or keepalive probe
test [eax + TCP_SOCKET.timer_flags], timer_flag_retransmission test [eax + TCP_SOCKET.timer_flags], timer_flag_retransmission
jnz .retransmit_set jnz .retransmit_set
@ -598,7 +619,6 @@ endl
jz .retransmit_set jz .retransmit_set
and [eax + TCP_SOCKET.timer_flags], not timer_flag_persist and [eax + TCP_SOCKET.timer_flags], not timer_flag_persist
mov [eax + TCP_SOCKET.t_rxtshift], 0 mov [eax + TCP_SOCKET.t_rxtshift], 0
.retransmit_set: .retransmit_set:
;-------------------- ;--------------------
@ -642,10 +662,12 @@ endl
@@: @@:
; update last ack sent ; update last ack sent
push [eax + TCP_SOCKET.RCV_NXT] push [eax + TCP_SOCKET.RCV_NXT]
pop [eax + TCP_SOCKET.last_ack_sent] pop [eax + TCP_SOCKET.last_ack_sent]
; clear the ACK flags ; clear the ACK flags
and [eax + TCP_SOCKET.t_flags], not (TF_ACKNOW + TF_DELACK) and [eax + TCP_SOCKET.t_flags], not (TF_ACKNOW + TF_DELACK)
;-------------- ;--------------

View File

@ -78,7 +78,7 @@ macro tcp_rcvseqinit ptr {
push edi push edi
mov edi, [ptr + TCP_SOCKET.IRS] mov edi, [ptr + TCP_SOCKET.IRS]
inc edi inc edi ; SYN ocupies a sequence number
mov [ptr + TCP_SOCKET.RCV_NXT], edi mov [ptr + TCP_SOCKET.RCV_NXT], edi
mov [ptr + TCP_SOCKET.RCV_ADV], edi mov [ptr + TCP_SOCKET.RCV_ADV], edi
pop edi pop edi
@ -216,6 +216,8 @@ tcp_close:
call socket_is_disconnected call socket_is_disconnected
call socket_free call socket_free
inc [TCPS_closed]
xor eax, eax xor eax, eax
ret ret
@ -241,7 +243,6 @@ tcp_outflags:
ret ret
.flaglist: .flaglist:
db TH_RST + TH_ACK ; TCPS_CLOSED db TH_RST + TH_ACK ; TCPS_CLOSED
db 0 ; TCPS_LISTEN db 0 ; TCPS_LISTEN
db TH_SYN ; TCPS_SYN_SENT db TH_SYN ; TCPS_SYN_SENT
@ -252,11 +253,7 @@ tcp_outflags:
db TH_FIN + TH_ACK ; TCPS_CLOSING db TH_FIN + TH_ACK ; TCPS_CLOSING
db TH_FIN + TH_ACK ; TCPS_LAST_ACK db TH_FIN + TH_ACK ; TCPS_LAST_ACK
db TH_ACK ; TCPS_FIN_WAIT_2 db TH_ACK ; TCPS_FIN_WAIT_2
db TH_ACK ; TCPS_TIMED_WAIT db TH_ACK ; TCPS_TIME_WAIT
;-----------------------------------------------------------------; ;-----------------------------------------------------------------;
@ -502,7 +499,7 @@ tcp_xmit_timer:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_xmit_timer: socket=0x%x rtt=%d0ms\n", ebx, eax DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_xmit_timer: socket=0x%x rtt=%d0ms\n", ebx, eax
;TODO: update stats inc [TCPS_rttupdated]
cmp [ebx + TCP_SOCKET.t_rtt], 0 cmp [ebx + TCP_SOCKET.t_rtt], 0
je .no_rtt_yet je .no_rtt_yet