From 0287f5c75bf0289b2d90afac3a5b6845bd074a30 Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Thu, 26 Jul 2012 14:54:57 +0000 Subject: [PATCH] Bugfixes & further development of TCP_output git-svn-id: svn://kolibrios.org@2890 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/branches/net/network/socket.inc | 10 +- kernel/branches/net/network/tcp_input.inc | 4 +- kernel/branches/net/network/tcp_output.inc | 115 ++++++++++++--------- kernel/branches/net/network/tcp_subr.inc | 10 +- kernel/branches/net/network/udp.inc | 8 +- 5 files changed, 87 insertions(+), 60 deletions(-) diff --git a/kernel/branches/net/network/socket.inc b/kernel/branches/net/network/socket.inc index c65a1d64c8..a796825cef 100644 --- a/kernel/branches/net/network/socket.inc +++ b/kernel/branches/net/network/socket.inc @@ -68,7 +68,7 @@ struct TCP_SOCKET IP_SOCKET ; send sequence SND_UNA dd ? ; sequence number of unack'ed sent Packets SND_NXT dd ? ; next send sequence number to use - SND_UP dd ? + SND_UP dd ? ; urgent pointer SND_WL1 dd ? ; window minus one SND_WL2 dd ? ; ISS dd ? ; initial send sequence number @@ -77,7 +77,7 @@ struct TCP_SOCKET IP_SOCKET ; receive sequence RCV_WND dw ? ; receive window RCV_NXT dd ? ; next receive sequence number to use - RCV_UP dd ? + RCV_UP dd ? ; urgent pointer IRS dd ? ; initial receive sequence number ;--------------------- @@ -130,6 +130,10 @@ struct TCP_SOCKET IP_SOCKET timer_keepalive dw ? ; keepalive/syn timeout timer_timed_wait dw ? ; also used as 2msl timer +; extra + + sendalot db ? + ends struct UDP_SOCKET IP_SOCKET @@ -696,7 +700,7 @@ SOCKET_close: cmp [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED ; state must be LISTEN, SYN_SENT or CLOSED jb .free - call TCP_drop + call TCP_usrclosed mov dword [esp+32], 0 ret diff --git a/kernel/branches/net/network/tcp_input.inc b/kernel/branches/net/network/tcp_input.inc index 4c8e6f9984..ee41418f52 100644 --- a/kernel/branches/net/network/tcp_input.inc +++ b/kernel/branches/net/network/tcp_input.inc @@ -133,6 +133,8 @@ TCP_input: .found_socket: ; ebx now contains the socketpointer DEBUGF 1,"Socket ptr: %x\n", ebx +; update stats + inc [TCP_segments_rx] ; FIXME: correct interface? ;---------------------------- ; Check if socket isnt closed @@ -1055,7 +1057,7 @@ align 4 ;;; TODO: update stats - DEBUGF 1,"We have an acceptable ACK of %x bytes\n", edi + DEBUGF 1,"We have an acceptable ACK of %u bytes\n", edi diff --git a/kernel/branches/net/network/tcp_output.inc b/kernel/branches/net/network/tcp_output.inc index db45bc516a..2436317bc2 100644 --- a/kernel/branches/net/network/tcp_output.inc +++ b/kernel/branches/net/network/tcp_output.inc @@ -26,15 +26,10 @@ $Revision$ ; ;----------------------------------------------------------------- align 4 -TCP_sendalot: - DEBUGF 1,"TCP_sendalot\n" - pop eax -;align 4 TCP_output: DEBUGF 1,"TCP_output, socket: %x\n", eax - ; We'll detect the length of the data to be transmitted, and flags to be used ; If there is some data, or any critical controls to send (SYN / RST), then transmit ; Otherwise, investigate further @@ -55,6 +50,8 @@ TCP_output: .not_idle: .again: + mov [eax + TCP_SOCKET.sendalot], 0 + mov ebx, [eax + TCP_SOCKET.SND_NXT] ; calculate offset (71) sub ebx, [eax + TCP_SOCKET.SND_UNA] ; @@ -82,7 +79,7 @@ TCP_output: cmp ebx, [eax + STREAM_SOCKET.snd.size] jae @f - and dl, not (TH_FIN) ; clear the FIN flag ??? how can it be set before? + and dl, not (TH_FIN) @@: inc ecx @@ -139,8 +136,7 @@ TCP_output: jbe @f mov esi, [eax + TCP_SOCKET.t_maxseg] - push eax - push dword TCP_sendalot + inc [eax + TCP_SOCKET.sendalot] @@: ;-------------------------------------------- @@ -149,9 +145,8 @@ TCP_output: mov edi, [eax + TCP_SOCKET.SND_NXT] add edi, esi sub edi, [eax + TCP_SOCKET.SND_UNA] - sub edi, [eax + STREAM_SOCKET.snd.size] - jns @f - + cmp edi, [eax + STREAM_SOCKET.snd.size] + jae @f and dl, not (TH_FIN) @@: @@ -171,13 +166,17 @@ TCP_output: cmp esi, [eax + TCP_SOCKET.t_maxseg] je TCP_send - test [eax + TCP_SOCKET.t_flags], TF_NODELAY - jnz @f - ; TODO: if not 'idle', skip to next codeblock - @@: - add ebx, esi + add ebx, esi ; offset + length cmp ebx, [eax + STREAM_SOCKET.snd.size] - jae TCP_send + jb @f + + test [eax + TCP_SOCKET.t_flags], TF_NODELAY + jnz TCP_send + + mov ebx, [eax + TCP_SOCKET.SND_MAX] + cmp ebx, [eax + TCP_SOCKET.SND_UNA] + je TCP_send + @@: test [eax + TCP_SOCKET.t_force], -1 ;;; jnz TCP_send @@ -238,7 +237,7 @@ TCP_output: ; FIN was set, only send if not already sent, or on retransmit test [eax + TCP_SOCKET.t_flags], TF_SENTFIN - jnz TCP_send + jz TCP_send mov ebx, [eax + TCP_SOCKET.SND_NXT] cmp ebx, [eax + TCP_SOCKET.SND_UNA] @@ -296,11 +295,9 @@ TCP_send: DEBUGF 1,"TCP_send socket=%x length=%u flags=%x\n", eax, esi, dl + push eax ; save socket ptr mov edi, sizeof.TCP_header ; edi will contain headersize - sub esp, 8 ; create some space on stack - push eax ; save socket pointer - ;------------------------------------ ; Send options with first SYN segment @@ -379,9 +376,7 @@ TCP_send: jbe .no_overflow mov esi, [eax + TCP_SOCKET.t_maxseg] -;; push eax -;; push dword TCP_sendalot - + inc [eax + TCP_SOCKET.sendalot] .no_overflow: ;----------------------------------------------------------------- @@ -409,7 +404,7 @@ TCP_send: push [eax + TCP_SOCKET.LocalPort] ; .SourcePort dw ? ntohw [esp] - push edi ; header size + push edi ; header size ;--------------------- ; Create the IP packet @@ -427,17 +422,17 @@ TCP_send: ; Move TCP header from stack to TCP packet push ecx - mov ecx, [esp+4] - lea esi, [esp+4+4] - shr ecx, 2 + mov ecx, [esp + 4] + lea esi, [esp + 8] + shr ecx, 2 ; count is in bytes, we will work with dwords rep movsd - pop ecx ; full TCP packet size + pop ecx ; full TCP packet size - pop esi ; headersize - add esp, esi + pop esi ; headersize + add esp, esi ; remove it from stack - mov [esp + 4], eax ; packet ptr - mov [esp + 4+4], edx ; packet size + push edx ; packet size for send proc + push eax ; packet ptr for send proc mov edx, edi ; begin of data sub edx, esi ; begin of packet (edi = begin of data) @@ -451,7 +446,7 @@ TCP_send: ; ecx = buffer size ; edi = ptr to buffer - mov eax, [esp + 4] ; get socket ptr + mov eax, [esp + 12] ; get socket ptr add [eax + TCP_SOCKET.SND_NXT], ecx ; update sequence number push edx @@ -462,7 +457,8 @@ TCP_send: .nodata: pop esi ; begin of data pop ecx ; full packet size - pop eax ; socket ptr + mov eax, [esp + 8] + ;---------------------------------- ; update sequence number and timers (400) @@ -496,10 +492,9 @@ TCP_send: mov [eax + TCP_SOCKET.timer_retransmission], dx cmp [eax + TCP_SOCKET.timer_persist], 0 - jne @f + jne .retransmit_set mov [eax + TCP_SOCKET.timer_persist], 0 mov [eax + TCP_SOCKET.t_rxtshift], 0 - @@: .retransmit_set: @@ -511,18 +506,32 @@ TCP_send: TCP_checksum (eax + IP_SOCKET.LocalIP), (eax + IP_SOCKET.RemoteIP) mov [esi + TCP_header.Checksum], dx -; unlock socket - - pusha - lea ecx, [eax + SOCKET.mutex] - call mutex_unlock - popa - ;---------------- ; Send the packet DEBUGF 1,"Sending TCP Packet to device %x\n", ebx call [ebx + NET_DEVICE.transmit] + jnz .send_error + pop eax + + inc [TCP_segments_tx] ; FIXME: correct interface? + +;;; TODO: (485) + + push [eax + TCP_SOCKET.RCV_NXT] + pop [eax + TCP_SOCKET.last_ack_sent] + + and [eax + TCP_SOCKET.t_flags], not (TF_ACKNOW + TF_DELACK) + + cmp [eax + TCP_SOCKET.sendalot], 0 + jne TCP_output.again + +; unlock socket + lea ecx, [eax + SOCKET.mutex] + call mutex_unlock + DEBUGF 1,"TCP_output: success!\n" + + xor eax, eax ret @@ -530,19 +539,29 @@ TCP_send: pop ecx add esp, ecx pop eax - add esp, 8 mov [eax + TCP_SOCKET.timer_retransmission], TCP_time_re_min - pusha +; unlock socket lea ecx, [eax + SOCKET.mutex] call mutex_unlock - popa - DEBUGF 1,"TCP_output: IP error\n" + + or eax, -1 + ret + + .send_error: + pop eax +; unlock socket + lea ecx, [eax + SOCKET.mutex] + call mutex_unlock + DEBUGF 1,"TCP_output: sending failed\n" + + or eax, -2 ret + diff --git a/kernel/branches/net/network/tcp_subr.inc b/kernel/branches/net/network/tcp_subr.inc index a44f20f4fa..f5019e8af8 100644 --- a/kernel/branches/net/network/tcp_subr.inc +++ b/kernel/branches/net/network/tcp_subr.inc @@ -201,7 +201,7 @@ TCP_close: align 4 TCP_disconnect: - DEBUGF 1,"TCP_disconnect\n" + DEBUGF 1,"TCP_disconnect socket=%x\n", eax cmp [eax + TCP_SOCKET.t_state], TCPS_ESTABLISHED jb TCP_close @@ -227,6 +227,8 @@ TCP_disconnect: align 4 TCP_usrclosed: + DEBUGF 1,"TCP_usrclosed socket=%x\n", eax + push ebx mov ebx, [eax + TCP_SOCKET.t_state] mov ebx, dword [.switch + ebx*4] @@ -297,9 +299,9 @@ TCP_outflags: db TH_SYN + TH_ACK ; TCPS_SYN_RECEIVED db TH_ACK ; TCPS_ESTABLISHED db TH_ACK ; TCPS_CLOSE_WAIT - db TH_SYN + TH_ACK ; TCPS_FIN_WAIT_1 - db TH_SYN + TH_ACK ; TCPS_CLOSING - db TH_SYN + TH_ACK ; TCPS_LAST_ACK + db TH_FIN + TH_ACK ; TCPS_FIN_WAIT_1 + db TH_FIN + TH_ACK ; TCPS_CLOSING + db TH_FIN + TH_ACK ; TCPS_LAST_ACK db TH_ACK ; TCPS_FIN_WAIT_2 db TH_ACK ; TCPS_TIMED_WAIT diff --git a/kernel/branches/net/network/udp.inc b/kernel/branches/net/network/udp.inc index 2360607e1f..c069b6eb89 100644 --- a/kernel/branches/net/network/udp.inc +++ b/kernel/branches/net/network/udp.inc @@ -235,7 +235,7 @@ UDP_output: DEBUGF 1,"UDP_output: socket:%x, bytes: %u, data ptr: %x\n", eax, ecx, esi mov dx, [eax + UDP_SOCKET.RemotePort] - DEBUGF 1,"remote port: %u\n", dx + DEBUGF 1,"UDP_output: remote port: %u, ", dx rol dx, 8 rol edx, 16 mov dx, [eax + UDP_SOCKET.LocalPort] @@ -273,11 +273,11 @@ UDP_output: ; Checksum mov esi, edi mov [edi + UDP_header.Checksum], 0 - UDP_checksum (edi-4), (edi-8) ; TODO: fix this, IPv4 packet could have options.. + UDP_checksum (edi-4), (edi-8) ; FIXME: IPv4 packet could have options.. - inc [UDP_PACKETS_TX] + inc [UDP_PACKETS_TX] ; FIXME: correct device? - DEBUGF 1,"Sending UDP Packet to device %x\n", ebx + DEBUGF 1,"UDP_output: sending to device %x\n", ebx call [ebx + NET_DEVICE.transmit] ret