diff --git a/kernel/trunk/network/socket.inc b/kernel/trunk/network/socket.inc index 11fe51795d..fd1d373f41 100644 --- a/kernel/trunk/network/socket.inc +++ b/kernel/trunk/network/socket.inc @@ -141,10 +141,6 @@ struct TCP_SOCKET IP_SOCKET seg_next dd ? ; re-assembly queue - temp_bits db ? - rb 3 ; align - - ends struct UDP_SOCKET IP_SOCKET diff --git a/kernel/trunk/network/stack.inc b/kernel/trunk/network/stack.inc index f7820b1d73..a2fd1daa84 100644 --- a/kernel/trunk/network/stack.inc +++ b/kernel/trunk/network/stack.inc @@ -110,7 +110,7 @@ SS_MORETOCOME = 0x4000 SS_BLOCKED = 0x8000 -SOCKET_MAXDATA = 4096*32 ; must be 4096*(power of 2) where 'power of 2' is at least 8 +SOCKET_MAXDATA = 4096*8 ; must be 4096*(power of 2) where 'power of 2' is at least 8 MAX_backlog = 20 ; maximum backlog for stream sockets ; Error Codes diff --git a/kernel/trunk/network/tcp_input.inc b/kernel/trunk/network/tcp_input.inc index 5bc89e723b..1042136aa5 100644 --- a/kernel/trunk/network/tcp_input.inc +++ b/kernel/trunk/network/tcp_input.inc @@ -83,6 +83,7 @@ proc TCP_process_input locals dataoffset dd ? timestamp dd ? + temp_bits db ? endl xor esi, esi @@ -218,7 +219,7 @@ endl ;--------------------------- ; disable all temporary bits - mov [ebx + TCP_SOCKET.temp_bits], 0 + mov [temp_bits], 0 ;--------------------------------------- ; unscale the window into a 32 bit value @@ -252,7 +253,7 @@ endl mov ebx, eax - mov [ebx + TCP_SOCKET.temp_bits], TCP_BIT_DROPSOCKET ;;; FIXME: should we take over bits from previous socket? + mov [temp_bits], TCP_BIT_DROPSOCKET push dword [edi + 4] ; Ipv4 destination addres pop [ebx + IP_SOCKET.LocalIP] @@ -378,7 +379,7 @@ endl mov [ebx + TCP_SOCKET.ts_val], eax lodsd ; timestamp echo reply mov [ebx + TCP_SOCKET.ts_ecr], eax - or [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP + or [temp_bits], TCP_BIT_TIMESTAMP ; Since we have a timestamp, lets do the paws test right away! @@ -483,7 +484,7 @@ endl ; Update RTT estimators - test [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP + test [temp_bits], TCP_BIT_TIMESTAMP jz .no_timestamp_rtt mov eax, [timestamp] sub eax, [ebx + TCP_SOCKET.ts_ecr] @@ -713,16 +714,16 @@ endl ;;; TODO: update stats .dont_drop_all: ;;; TODO: update stats - DEBUGF 1, "Trimming %u bytes from the right of the window\n" + DEBUGF DEBUG_NETWORK_VERBOSE, "Trimming %u bytes from the right of the window\n" sub ecx, eax ; remove data from the right side of window (decrease data length) - and [ebx + TCP_SOCKET.t_flags], not (TH_PUSH or TH_FIN) + and [edx + TCP_header.Flags], not (TH_PUSH or TH_FIN) .no_excess_data: ;----------------- ; Record timestamp ; If last ACK falls within this segments sequence numbers, record its timestamp - test [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP + test [temp_bits], TCP_BIT_TIMESTAMP jz .no_timestamp mov eax, [ebx + TCP_SOCKET.last_ack_sent] sub eax, [edx + TCP_header.SequenceNumber] @@ -1004,11 +1005,11 @@ endl DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: acceptable ACK for %u bytes\n", edi ;------------------------------------------ -; RTT measurements and retransmission timer (912-926) +; RTT measurements and retransmission timer ; If we have a timestamp, update smoothed RTT - test [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP + test [temp_bits], TCP_BIT_TIMESTAMP jz .timestamp_not_present mov eax, [timestamp] sub eax, [ebx + TCP_SOCKET.ts_ecr] @@ -1039,7 +1040,7 @@ endl cmp eax, [edx + TCP_header.AckNumber] jne .more_data and [ebx + TCP_SOCKET.timer_flags], not timer_flag_retransmission - or [ebx + TCP_SOCKET.temp_bits], TCP_BIT_NEEDOUTPUT + or [temp_bits], TCP_BIT_NEEDOUTPUT jmp .no_restart .more_data: test [ebx + TCP_SOCKET.timer_flags], timer_flag_persist @@ -1241,7 +1242,7 @@ align 4 TCP_rcvseqinit ebx mov [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED - mov [ebx + TCP_SOCKET.t_flags], TF_ACKNOW + or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval ;;;; macro or [ebx + TCP_SOCKET.timer_flags], timer_flag_keepalive @@ -1251,7 +1252,7 @@ align 4 lea eax, [ebx + STREAM_SOCKET.rcv] call SOCKET_ring_create - and [ebx + TCP_SOCKET.temp_bits], not TCP_BIT_DROPSOCKET + and [temp_bits], not TCP_BIT_DROPSOCKET pusha mov eax, ebx @@ -1431,7 +1432,7 @@ align 4 push [edx + TCP_header.AckNumber] pop [ebx + TCP_SOCKET.SND_WL2] - or [ebx + TCP_SOCKET.temp_bits], TCP_BIT_NEEDOUTPUT + or [temp_bits], TCP_BIT_NEEDOUTPUT .no_window_update: @@ -1521,7 +1522,6 @@ align 4 ; Generate ACK immediately, to let the other end know that a segment was received out of order, ; and to tell it what sequence number is expected. This aids the fast-retransmit algorithm. or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW - .data_done: ;--------------- @@ -1540,7 +1540,7 @@ align 4 mov eax, ebx call SOCKET_cant_recv_more - mov [ebx + TCP_SOCKET.t_flags], TF_ACKNOW + or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW inc [ebx + TCP_SOCKET.RCV_NXT] .not_first_fin: @@ -1562,29 +1562,54 @@ align 4 dd .fin_timed ; TCPS_TIMED_WAIT .fin_syn_est: - mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT jmp .final_processing .fin_wait1: - mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSING jmp .final_processing .fin_wait2: - mov [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT mov eax, ebx call TCP_cancel_timers - mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL - or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait call SOCKET_is_disconnected - jmp .final_processing .fin_timed: mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait - jmp .final_processing + +;----------------- +; Final processing + + .final_processing: + DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Final processing\n" + + push ebx + lea ecx, [ebx + SOCKET.mutex] + call mutex_unlock + pop eax + + test [temp_bits], TCP_BIT_NEEDOUTPUT + jnz .need_output + + test [eax + TCP_SOCKET.t_flags], TF_ACKNOW + jz .dumpit + DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: ACK now!\n" + + .need_output: + DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: need output\n" + call TCP_output + + .dumpit: + DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: dumping\n" + + call NET_packet_free + jmp .loop + + +;----------------- +; Drop the segment .drop_after_ack: @@ -1621,34 +1646,6 @@ align 4 jnz .respond_syn jmp .dumpit -;----------------- -; Final processing - - .final_processing: - DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Final processing\n" - - push ebx - lea ecx, [ebx + SOCKET.mutex] - call mutex_unlock - pop eax - - test [eax + TCP_SOCKET.temp_bits], TCP_BIT_NEEDOUTPUT - jnz .need_output - - test [eax + TCP_SOCKET.t_flags], TF_ACKNOW - jz .dumpit - DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: ACK now!\n" - - .need_output: - DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: need output\n" - call TCP_output - - .dumpit: - DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: dumping\n" - - call NET_packet_free - jmp .loop - ;--------- ; Respond @@ -1709,7 +1706,7 @@ align 4 popa .destroy_new_socket: - test [ebx + TCP_SOCKET.temp_bits], TCP_BIT_DROPSOCKET + test [temp_bits], TCP_BIT_DROPSOCKET jz .drop_no_socket mov eax, ebx diff --git a/kernel/trunk/network/tcp_output.inc b/kernel/trunk/network/tcp_output.inc index bad57c87a5..43c4f6bc0a 100644 --- a/kernel/trunk/network/tcp_output.inc +++ b/kernel/trunk/network/tcp_output.inc @@ -26,7 +26,11 @@ $Revision: 3289 $ ; ;----------------------------------------------------------------- align 4 -TCP_output: +proc TCP_output + +locals + temp_bits db ? +endl DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: socket=%x\n", eax @@ -57,7 +61,7 @@ TCP_output: .not_idle: .again: - mov [eax + TCP_SOCKET.temp_bits], 0 + mov [temp_bits], 0 mov ebx, [eax + TCP_SOCKET.SND_NXT] ; calculate offset (71) sub ebx, [eax + TCP_SOCKET.SND_UNA] ; @@ -145,7 +149,7 @@ TCP_output: jbe @f mov esi, [eax + TCP_SOCKET.t_maxseg] - or [eax + TCP_SOCKET.temp_bits], TCP_BIT_SENDALOT + or [temp_bits], TCP_BIT_SENDALOT @@: ;-------------------------------------------- @@ -406,16 +410,48 @@ TCP_send: jbe .no_overflow mov esi, [eax + TCP_SOCKET.t_maxseg] - or [eax + TCP_SOCKET.temp_bits], TCP_BIT_SENDALOT + or [temp_bits], TCP_BIT_SENDALOT .no_overflow: +;---------------------------------------------------- +; Calculate the receive window. +; Dont shrink window, but avoid silly window syndrome + + mov ebx, SOCKET_MAXDATA + sub ebx, [eax + STREAM_SOCKET.rcv.size] + + cmp ebx, SOCKET_MAXDATA/4 + jae @f + cmp ebx, [eax + TCP_SOCKET.t_maxseg] + jae @f + xor ebx, ebx + @@: + + cmp ebx, TCP_max_win + jbe @f + mov ebx, TCP_max_win + @@: + + mov ecx, [eax + TCP_SOCKET.RCV_ADV] + sub ecx, [eax + TCP_SOCKET.RCV_NXT] + cmp ebx, ecx + ja @f + mov ebx, ecx + @@: + + DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: window = %u\n", ebx + + mov cl, [eax + TCP_SOCKET.RCV_SCALE] + shr ebx, cl + xchg bl, bh + ;----------------------------------------------------------------- ; Start by pushing all TCP header values in reverse order on stack ; (essentially, creating the tcp header on the stack!) pushw 0 ; .UrgentPointer dw ? pushw 0 ; .Checksum dw ? - pushw 0x00a0 ; .Window dw ? ;;;;;;; FIXME (370) + pushw bx ; .Window dw ? shl edi, 2 ; .DataOffset db ? only 4 left-most bits shl dx, 8 or dx, di ; .Flags db ? @@ -566,7 +602,7 @@ TCP_send: push [eax + TCP_SOCKET.RCV_NXT] pop [eax + TCP_SOCKET.last_ack_sent] -; and flags +; clear the ACK flags and [eax + TCP_SOCKET.t_flags], not (TF_ACKNOW + TF_DELACK) ;-------------- @@ -582,7 +618,7 @@ TCP_send: ;----------------------------- ; Check if we need more output - test [eax + TCP_SOCKET.temp_bits], TCP_BIT_SENDALOT + test [temp_bits], TCP_BIT_SENDALOT jnz TCP_output.again DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: success!\n" @@ -622,7 +658,4 @@ TCP_send: ret - - - - +endp \ No newline at end of file