diff --git a/kernel/trunk/network/socket.inc b/kernel/trunk/network/socket.inc index f997dc58b3..790edc3228 100644 --- a/kernel/trunk/network/socket.inc +++ b/kernel/trunk/network/socket.inc @@ -750,12 +750,15 @@ socket_close: ret .tcp: - call tcp_usrclosed - - test eax, eax + test [eax + SOCKET.state], SS_ISCONNECTED jz @f - call tcp_output ; If connection is not closed yet, send the FIN + test [eax + SOCKET.state], SS_ISDISCONNECTING + jnz @f + call tcp_disconnect @@: +; TODO: +; ... +; call socket_free ret @@ -2471,7 +2474,7 @@ socket_is_disconnecting: align 4 socket_is_disconnected: - DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_is_disconnected: %x\n", eax + DEBUGF 1, "SOCKET_is_disconnected: %x\n", eax and [eax + SOCKET.state], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING) or [eax + SOCKET.state], SS_CANTRCVMORE + SS_CANTSENDMORE diff --git a/kernel/trunk/network/tcp_output.inc b/kernel/trunk/network/tcp_output.inc index dbd3c579a9..fa0e5dfce2 100644 --- a/kernel/trunk/network/tcp_output.inc +++ b/kernel/trunk/network/tcp_output.inc @@ -32,7 +32,7 @@ proc tcp_output locals temp_bits db ? - window dd ? + rcv_window dd ? endl DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: socket=%x state=%u\n", eax, [eax + TCP_SOCKET.t_state] @@ -128,7 +128,7 @@ endl ; 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. - jae .not_persist + jge .not_persist ; enter persist state @@ -176,8 +176,12 @@ endl ;------------------------------- ; calculate window advertisement + xor ecx, ecx + test [eax + SOCKET.state], SS_CANTRCVMORE + jnz @f mov ecx, SOCKET_BUFFER_SIZE sub ecx, [eax + STREAM_SOCKET.rcv.size] + @@: ;------------------------------ ; Sender silly window avoidance @@ -235,7 +239,7 @@ endl add ebx, [eax + TCP_SOCKET.RCV_NXT] cmp ebx, ecx - jb @f + jl @f mov ebx, ecx @@: @@ -246,9 +250,8 @@ endl cmp ebx, edi jae .send - shl ebx, 1 -; cmp ebx, [eax + TCP_SOCKET.] ;;; TODO: check with receive buffer high water mark -; jae TCP_send + cmp ebx, SOCKET_BUFFER_SIZE/2 + jae .send .no_window: @@ -289,11 +292,8 @@ endl .enter_persist: cmp [eax + STREAM_SOCKET.snd.size], 0 ; Data ready to send? - jne @f - and [eax + TCP_SOCKET.timer_flags], not timer_flag_retransmission - jne @f - - test [eax + TCP_SOCKET.timer_flags], timer_flag_persist ; Persist timer already expired? + je @f + test [eax + TCP_SOCKET.timer_flags], timer_flag_retransmission or timer_flag_persist jnz @f DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: Entering persist state\n" @@ -485,20 +485,30 @@ endl ; Calculate the receive window. ; Dont shrink window, but avoid silly window syndrome + xor ebx, ebx + test [eax + SOCKET.state], SS_CANTRCVMORE + jnz @f mov ebx, SOCKET_BUFFER_SIZE sub ebx, [eax + STREAM_SOCKET.rcv.size] cmp ebx, SOCKET_BUFFER_SIZE/4 - jae @f + jge @f cmp ebx, [eax + TCP_SOCKET.t_maxseg] - jae @f + jge @f xor ebx, ebx @@: - cmp ebx, TCP_max_win ;;;; shl rcv_scale - jbe @f - mov ebx, TCP_max_win ;;;; shl rcv_scale + + mov cl, [eax + TCP_SOCKET.RCV_SCALE] + push eax + mov eax, TCP_max_win + shl eax, cl + cmp ebx, eax + jle @f + mov ebx, eax @@: + pop eax + mov ecx, [eax + TCP_SOCKET.RCV_ADV] sub ecx, [eax + TCP_SOCKET.RCV_NXT] @@ -507,8 +517,10 @@ endl mov ebx, ecx @@: +;; TODO URGENT POINTER + DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: window=%u\n", ebx - mov [window], ebx + mov [rcv_window], ebx mov cl, [eax + TCP_SOCKET.RCV_SCALE] shr ebx, cl @@ -668,7 +680,7 @@ endl ; update advertised receive window - mov ecx, [window] + mov ecx, [rcv_window] test ecx, ecx jz @f add ecx, [eax + TCP_SOCKET.RCV_NXT] diff --git a/kernel/trunk/network/tcp_subr.inc b/kernel/trunk/network/tcp_subr.inc index 9268cd22d5..a35a1e0d17 100644 --- a/kernel/trunk/network/tcp_subr.inc +++ b/kernel/trunk/network/tcp_subr.inc @@ -185,9 +185,22 @@ tcp_disconnect: cmp [eax + TCP_SOCKET.t_state], TCPS_ESTABLISHED jb tcp_close ; Connection not yet synchronised, just get rid of the socket -; TODO: implement LINGER + test [eax + SOCKET.options], SO_LINGER + jz .nolinger +; TODO: implement LINGER +; cmp [eax + SOCKET.so_linger], 0 +; je TCP_drop + + .nolinger: call socket_is_disconnecting + + push eax + add eax, STREAM_SOCKET.rcv + mov ecx, [eax + RING_BUFFER.size] + call socket_ring_free + pop eax + call tcp_usrclosed test eax, eax @@ -311,7 +324,7 @@ tcp_respond: cmp eax, TCP_max_win jbe .lessthanmax mov eax, TCP_max_win -.lessthanmax: + .lessthanmax: mov cl, [esi + TCP_SOCKET.RCV_SCALE] shr eax, cl