diff --git a/kernel/branches/net/network/tcp_input.inc b/kernel/branches/net/network/tcp_input.inc index bb35e2e207..6146f9bd9c 100644 --- a/kernel/branches/net/network/tcp_input.inc +++ b/kernel/branches/net/network/tcp_input.inc @@ -34,66 +34,65 @@ $Revision$ align 4 TCP_input: - DEBUGF 1,"TCP_input size=%u\n", ecx + DEBUGF 1,"TCP_input size=%u\n", ecx - and [esi + TCP_header.DataOffset], 0xf0 ; Calculate TCP segment header size (throwing away unused reserved bits in TCP header) - shr [esi + TCP_header.DataOffset], 2 - cmp [esi + TCP_header.DataOffset], sizeof.TCP_header ; Now see if it's at least the size of a standard TCP header - jb .drop_not_locked ; If not, drop the packet +; First, re-calculate the checksum -;------------------------------- -; Now, re-calculate the checksum + push ecx esi + pushw [esi + TCP_header.Checksum] + mov [esi + TCP_header.Checksum], 0 + TCP_checksum (edi), (edi+4) + pop cx ; previous checksum + cmp cx, dx + pop edx ecx + jne .drop_not_locked - push ecx esi - pushw [esi + TCP_header.Checksum] - mov [esi + TCP_header.Checksum], 0 - TCP_checksum (edi), (edi+4) - pop cx ; previous checksum - cmp cx, dx - pop edx ecx - jnz .drop_not_locked + DEBUGF 1,"Checksum ok\n" - DEBUGF 1,"Checksum ok\n" + and [edx + TCP_header.DataOffset], 0xf0 ; Calculate TCP segment header size (throwing away unused reserved bits in TCP header) + shr [edx + TCP_header.DataOffset], 2 + cmp [edx + TCP_header.DataOffset], sizeof.TCP_header ; Now see if it's at least the size of a standard TCP header + jb .drop_not_locked ; If not, drop the packet - movzx eax, [edx + TCP_header.DataOffset] - sub ecx, eax ; substract TCP header size from total segment size - jb .drop_not_locked ; If total segment size is less then the advertised header size, drop packet - DEBUGF 1,"we got %u bytes of data\n", ecx + movzx eax, [edx + TCP_header.DataOffset] + sub ecx, eax ; substract TCP header size from total segment size + jb .drop_not_locked ; If total segment size is less then the advertised header size, drop packet + DEBUGF 1,"we got %u bytes of data\n", ecx ;----------------------------------------------------------------------------------------- ; Check if this packet has a timestamp option (We do it here so we can process it quickly) - cmp eax, sizeof.TCP_header + 12 ; Timestamp option is 12 bytes - jb .no_timestamp - je .is_ok + cmp eax, sizeof.TCP_header + 12 ; Timestamp option is 12 bytes + jb .no_timestamp + je .is_ok - cmp byte [edx + sizeof.TCP_header + 12], TCP_OPT_EOL ; end of option list - jne .no_timestamp + cmp byte [edx + sizeof.TCP_header + 12], TCP_OPT_EOL ; end of option list + jne .no_timestamp .is_ok: - test [edx + TCP_header.Flags], TH_SYN ; SYN flag must not be set - jnz .no_timestamp + test [edx + TCP_header.Flags], TH_SYN ; SYN flag must not be set + jnz .no_timestamp - cmp dword [edx + sizeof.TCP_header], 0x0101080a ; Timestamp header - jne .no_timestamp + cmp dword [edx + sizeof.TCP_header], 0x0101080a ; Timestamp header + jne .no_timestamp - DEBUGF 1,"timestamp ok\n" + DEBUGF 1,"timestamp ok\n" - ; TODO: Parse the option - ; TODO: Set a Bit in the TCP to tell all options are parsed + ; TODO: Parse the option + ; TODO: Set a Bit in the TCP to tell all options are parsed .no_timestamp: ;------------------------------------------- ; Convert Big-endian values to little endian - ntohd [edx + TCP_header.SequenceNumber] - ntohd [edx + TCP_header.AckNumber] + ntohd [edx + TCP_header.SequenceNumber] + ntohd [edx + TCP_header.AckNumber] - ntohw [edx + TCP_header.Window] - ntohw [edx + TCP_header.UrgentPointer] - ntohw [edx + TCP_header.SourcePort] - ntohw [edx + TCP_header.DestinationPort] + ntohw [edx + TCP_header.Window] + ntohw [edx + TCP_header.UrgentPointer] + ntohw [edx + TCP_header.SourcePort] + ntohw [edx + TCP_header.DestinationPort] ;------------------------------------------------------------ ; Next thing to do is find the TCPS (thus, the socket pointer) @@ -102,188 +101,188 @@ TCP_input: ; (IP Packet SenderAddress = Remote IP) OR (Remote IP = 0) ; (IP Packet TCP Source Port = remote Port) OR (remote Port = 0) - mov ebx, net_sockets - mov si, [edx + TCP_header.DestinationPort] + mov ebx, net_sockets + mov si, [edx + TCP_header.DestinationPort] .socket_loop: - mov ebx, [ebx + SOCKET.NextPtr] - or ebx, ebx - jz .drop_with_reset_not_locked + mov ebx, [ebx + SOCKET.NextPtr] + or ebx, ebx + jz .drop_with_reset_not_locked - cmp [ebx + SOCKET.Domain], AF_INET4 - jne .socket_loop + cmp [ebx + SOCKET.Domain], AF_INET4 + jne .socket_loop - cmp [ebx + SOCKET.Protocol], IP_PROTO_TCP - jne .socket_loop + cmp [ebx + SOCKET.Protocol], IP_PROTO_TCP + jne .socket_loop - cmp [ebx + TCP_SOCKET.LocalPort], si - jne .socket_loop + cmp [ebx + TCP_SOCKET.LocalPort], si + jne .socket_loop - mov eax, [ebx + IP_SOCKET.RemoteIP] - cmp eax, [edi] ; Ipv4 source addres - je @f - test eax, eax - jnz .socket_loop + mov eax, [ebx + IP_SOCKET.RemoteIP] + cmp eax, [edi] ; Ipv4 source addres + je @f + test eax, eax + jnz .socket_loop @@: - mov ax, [ebx + TCP_SOCKET.RemotePort] - cmp [edx + TCP_header.SourcePort] , ax - je .found_socket - test ax, ax - jnz .socket_loop - .found_socket: ; ebx now contains the socketpointer - DEBUGF 1,"Socket ptr: %x\n", ebx + mov ax, [ebx + TCP_SOCKET.RemotePort] + cmp [edx + TCP_header.SourcePort], ax + je .found_socket + test ax, ax + jnz .socket_loop + .found_socket: ; ebx now contains the socketpointer + DEBUGF 1,"Socket ptr: %x\n", ebx ;---------------------------- ; Check if socket isnt closed - cmp [ebx + TCP_SOCKET.t_state], TCPS_CLOSED - je .drop_not_locked + cmp [ebx + TCP_SOCKET.t_state], TCPS_CLOSED + je .drop_not_locked ;---------------- ; Lock the socket - cmp [ebx + SOCKET.lock], 0 - jne .drop_not_locked ;;; HACK ! HACK ! dirty fucking HACK ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + cmp [ebx + SOCKET.lock], 0 + jne .drop_not_locked ;;; HACK ! HACK ! dirty fucking HACK ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - add ebx, SOCKET.lock - DEBUGF 1,"lock: %x\n", [ebx] - call wait_mutex - sub ebx, SOCKET.lock + add ebx, SOCKET.lock + DEBUGF 1,"lock: %x\n", [ebx] + call wait_mutex + sub ebx, SOCKET.lock - DEBUGF 1,"Socket locked\n" + DEBUGF 1,"Socket locked\n" ;--------------------------------------- ; unscale the window into a 32 bit value - movzx eax, [edx + TCP_header.Window] - push ecx - mov cl, [ebx + TCP_SOCKET.SND_SCALE] - shl eax, cl - mov dword [edx + TCP_header.Window], eax ; word after window is checksum, we dont need checksum anymore - pop ecx + movzx eax, [edx + TCP_header.Window] + push ecx + mov cl, [ebx + TCP_SOCKET.SND_SCALE] + shl eax, cl + mov dword [edx + TCP_header.Window], eax ; word after window is checksum, we dont need checksum anymore + pop ecx ;----------------------------------- ; Is this socket a listening socket? - test [ebx + SOCKET.options], SO_ACCEPTCON - jz .no_listening_socket + test [ebx + SOCKET.options], SO_ACCEPTCON + jz .no_listening_socket - DEBUGF 1,"Accepting new connection\n" + DEBUGF 1,"Accepting new connection\n" - mov [ebx + SOCKET.lock], 0 - push ecx edx esi edi ;;; - call SOCKET_fork - pop edi esi edx ecx + mov [ebx + SOCKET.lock], 0 + push ecx edx esi edi ;;; + call SOCKET_fork + pop edi esi edx ecx - test eax, eax - jz .drop + test eax, eax + jz .drop - push dword [edi + 4] ; Ipv4 destination addres - pop [eax + IP_SOCKET.LocalIP] + push dword [edi + 4] ; Ipv4 destination addres + pop [eax + IP_SOCKET.LocalIP] - push [edx + TCP_header.DestinationPort] - pop [eax + TCP_SOCKET.LocalPort] + push [edx + TCP_header.DestinationPort] + pop [eax + TCP_SOCKET.LocalPort] - mov [eax + TCP_SOCKET.t_state], TCPS_LISTEN + mov [eax + TCP_SOCKET.t_state], TCPS_LISTEN ; mov [ebx + SOCKET.lock], 0 - mov ebx, eax + mov ebx, eax - jmp .LISTEN + jmp .LISTEN .no_listening_socket: ;------------------------------------- ; Reset idle timer and keepalive timer - mov [ebx + TCP_SOCKET.t_idle], 0 - mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval + mov [ebx + TCP_SOCKET.t_idle], 0 + mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval ;-------------------- ; Process TCP options - movzx eax, [edx + TCP_header.DataOffset] - cmp eax, sizeof.TCP_header ; Does header contain any options? - je .no_options + movzx eax, [edx + TCP_header.DataOffset] + cmp eax, sizeof.TCP_header ; Does header contain any options? + je .no_options - DEBUGF 1,"Segment has options\n" + DEBUGF 1,"Segment has options\n" - cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN ; no options when in listen state - jz .not_uni_xfer ; also no header prediction + cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN ; no options when in listen state + jz .not_uni_xfer ; also no header prediction - add eax, edx - lea esi, [edx + sizeof.TCP_header] + add eax, edx + lea esi, [edx + sizeof.TCP_header] .opt_loop: - cmp esi, eax ; are we scanning outside of header? - jae .no_options + cmp esi, eax ; are we scanning outside of header? + jae .no_options - cmp byte [esi], TCP_OPT_EOL ; end of option list? - jz .no_options + cmp byte [esi], TCP_OPT_EOL ; end of option list? + jz .no_options - cmp byte [esi], TCP_OPT_NOP ; nop ? - jz .opt_nop + cmp byte [esi], TCP_OPT_NOP ; nop ? + jz .opt_nop - cmp byte [esi], TCP_OPT_MAXSEG - je .opt_maxseg + cmp byte [esi], TCP_OPT_MAXSEG + je .opt_maxseg - cmp byte [esi], TCP_OPT_WINDOW - je .opt_window + cmp byte [esi], TCP_OPT_WINDOW + je .opt_window - cmp byte [esi], TCP_OPT_TIMESTAMP - je .opt_timestamp + cmp byte [esi], TCP_OPT_TIMESTAMP + je .opt_timestamp - jmp .no_options ; If we reach here, some unknown options were received, skip them all! + jmp .no_options ; If we reach here, some unknown options were received, skip them all! .opt_nop: - inc edi - jmp .opt_loop + inc edi + jmp .opt_loop .opt_maxseg: - cmp byte [esi+1], 4 - jne .no_options ; error occured, ignore all options! + cmp byte [esi+1], 4 + jne .no_options ; error occured, ignore all options! - test [edx + TCP_header.Flags], TH_SYN - jz @f + test [edx + TCP_header.Flags], TH_SYN + jz @f - movzx eax, word[esi+2] - rol ax, 8 - DEBUGF 1,"Maxseg: %u\n", ax + movzx eax, word[esi+2] + rol ax, 8 + DEBUGF 1,"Maxseg: %u\n", ax - mov [ebx + TCP_SOCKET.t_maxseg], eax + mov [ebx + TCP_SOCKET.t_maxseg], eax @@: - add edi, 4 - jmp .opt_loop + add edi, 4 + jmp .opt_loop .opt_window: - cmp byte [esi+1], 3 - jne .no_options + cmp byte [esi+1], 3 + jne .no_options - test [edx + TCP_header.Flags], TH_SYN - jz @f + test [edx + TCP_header.Flags], TH_SYN + jz @f - DEBUGF 1,"Got window option\n" + DEBUGF 1,"Got window option\n" - ;;;;; + ;;;;; @@: - add edi, 3 - jmp .opt_loop + add edi, 3 + jmp .opt_loop .opt_timestamp: - cmp byte [esi+1], 10 - jne .no_options + cmp byte [esi+1], 10 + jne .no_options - DEBUGF 1,"Got timestamp option\n" + DEBUGF 1,"Got timestamp option\n" - ;;;;; + ;;;;; - add esi, 10 - jmp .opt_loop + add esi, 10 + jmp .opt_loop .no_options: @@ -307,26 +306,26 @@ TCP_input: ; - If the length is not 0 and the ACK didn't move, we're the receiver side of the transfer. ; If the packets are in order (data queue is empty), add the data to the socket buffer and request a delayed ACK - cmp [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED - jnz .not_uni_xfer + cmp [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED + jnz .not_uni_xfer - test [edx + TCP_header.Flags], TH_SYN + TH_FIN + TH_RST + TH_URG - jnz .not_uni_xfer + test [edx + TCP_header.Flags], TH_SYN + TH_FIN + TH_RST + TH_URG + jnz .not_uni_xfer - test [edx + TCP_header.Flags], TH_ACK - jz .not_uni_xfer + test [edx + TCP_header.Flags], TH_ACK + jz .not_uni_xfer - mov eax, [edx + TCP_header.SequenceNumber] - cmp eax, [ebx + TCP_SOCKET.RCV_NXT] - jne .not_uni_xfer + mov eax, [edx + TCP_header.SequenceNumber] + cmp eax, [ebx + TCP_SOCKET.RCV_NXT] + jne .not_uni_xfer - mov eax, dword [edx + TCP_header.Window] - cmp eax, [ebx + TCP_SOCKET.SND_WND] - jne .not_uni_xfer + mov eax, dword [edx + TCP_header.Window] + cmp eax, [ebx + TCP_SOCKET.SND_WND] + jne .not_uni_xfer - mov eax, [ebx + TCP_SOCKET.SND_NXT] - cmp eax, [ebx + TCP_SOCKET.SND_MAX] - jne .not_uni_xfer + mov eax, [ebx + TCP_SOCKET.SND_NXT] + cmp eax, [ebx + TCP_SOCKET.SND_MAX] + jne .not_uni_xfer ;--------------------------------------- ; check if we are sender in the uni-xfer @@ -334,25 +333,25 @@ TCP_input: ; If the following 4 conditions are all true, this segment is a pure ACK. ; ; - The segment contains no data. - test ecx, ecx - jnz .not_sender + test ecx, ecx + jnz .not_sender ; - The congestion window is greater than or equal to the current send window. ; This test is true only if the window is fully open, that is, the connection is not in the middle of slow start or congestion avoidance. - mov eax, [ebx + TCP_SOCKET.SND_CWND] - cmp eax, [ebx + TCP_SOCKET.SND_WND] - jb .not_uni_xfer + mov eax, [ebx + TCP_SOCKET.SND_CWND] + cmp eax, [ebx + TCP_SOCKET.SND_WND] + jb .not_uni_xfer ; - The acknowledgment field in the segment is less than or equal to the maximum sequence number sent. - mov eax, [edx + TCP_header.AckNumber] - cmp eax, [ebx + TCP_SOCKET.SND_MAX] - ja .not_uni_xfer + mov eax, [edx + TCP_header.AckNumber] + cmp eax, [ebx + TCP_SOCKET.SND_MAX] + ja .not_uni_xfer ; - The acknowledgment field in the segment is greater than the largest unacknowledged sequence number. - sub eax, [ebx + TCP_SOCKET.SND_UNA] - jbe .not_uni_xfer + sub eax, [ebx + TCP_SOCKET.SND_UNA] + jbe .not_uni_xfer - DEBUGF 1,"Header prediction: we are sender\n" + DEBUGF 1,"Header prediction: we are sender\n" ;--------------------------------- ; Packet is a pure ACK, process it @@ -362,28 +361,28 @@ TCP_input: ;;; TODO ; Delete acknowledged bytes from send buffer - pusha - mov ecx, eax - lea eax, [ebx + STREAM_SOCKET.snd] - call SOCKET_ring_free - popa + pusha + mov ecx, eax + lea eax, [ebx + STREAM_SOCKET.snd] + call SOCKET_ring_free + popa ; update window pointers - mov eax, [edx + TCP_header.AckNumber] - mov [ebx + TCP_SOCKET.SND_UNA], eax + mov eax, [edx + TCP_header.AckNumber] + mov [ebx + TCP_SOCKET.SND_UNA], eax ; Stop retransmit timer - mov [ebx + TCP_SOCKET.timer_retransmission], 0 + mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; Awaken waiting processes - mov [ebx + SOCKET.lock], 0 - mov eax, ebx - call SOCKET_notify_owner + mov [ebx + SOCKET.lock], 0 + mov eax, ebx + call SOCKET_notify_owner ; Generate more output - call TCP_output + call TCP_output - jmp .drop_not_locked + jmp .drop_not_locked ;------------------------------------------------- ; maybe we are the receiver in the uni-xfer then.. @@ -392,33 +391,33 @@ TCP_input: ; - The amount of data in the segment is greater than 0 (data count is in ecx) ; - The acknowledgment field equals the largest unacknowledged sequence number. This means no data is acknowledged by this segment. - mov eax, [edx + TCP_header.AckNumber] - cmp eax, [ebx + TCP_SOCKET.SND_UNA] - jne .not_uni_xfer + mov eax, [edx + TCP_header.AckNumber] + cmp eax, [ebx + TCP_SOCKET.SND_UNA] + jne .not_uni_xfer ; - The reassembly list of out-of-order segments for the connection is empty (seg_next equals tp). ;;; TODO - jnz .not_uni_xfer + jnz .not_uni_xfer ; Complete processing of received data - DEBUGF 1,"header prediction: we are receiver\nreceiving %u bytes of data\n", ecx + DEBUGF 1,"header prediction: we are receiver\nreceiving %u bytes of data\n", ecx - add [ebx + TCP_SOCKET.RCV_NXT], ecx ; Update sequence number with number of bytes we have copied + add [ebx + TCP_SOCKET.RCV_NXT], ecx ; Update sequence number with number of bytes we have copied - movzx esi, [edx + TCP_header.DataOffset] - add esi, edx - lea eax, [ebx + STREAM_SOCKET.rcv] - call SOCKET_ring_write ; Add the data to the socket buffer + movzx esi, [edx + TCP_header.DataOffset] + add esi, edx + lea eax, [ebx + STREAM_SOCKET.rcv] + call SOCKET_ring_write ; Add the data to the socket buffer - mov eax, ebx - call SOCKET_notify_owner + mov eax, ebx + call SOCKET_notify_owner - or [ebx + TCP_SOCKET.t_flags], TF_DELACK ; Set delayed ack flag + or [ebx + TCP_SOCKET.t_flags], TF_DELACK ; Set delayed ack flag - jmp .drop + jmp .drop @@ -430,7 +429,7 @@ TCP_input: .not_uni_xfer: - DEBUGF 1,"Header prediction failed\n" + DEBUGF 1,"Header prediction failed\n" ; Calculate receive window size @@ -444,13 +443,13 @@ TCP_input: ; mov eax, edx ; @@: - cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN - je .LISTEN + cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN + je .LISTEN - cmp [ebx + TCP_SOCKET.t_state], TCPS_SYN_SENT - je .SYN_SENT + cmp [ebx + TCP_SOCKET.t_state], TCPS_SYN_SENT + je .SYN_SENT - jmp .NOT_LISTEN_OR_SYN_SENT + jmp .NOT_LISTEN_OR_SYN_SENT @@ -460,52 +459,52 @@ TCP_input: align 4 .LISTEN: - DEBUGF 1,"TCP state: listen\n" + DEBUGF 1,"TCP state: listen\n" - test [edx + TCP_header.Flags], TH_RST ;;; TODO: kill new socket on error - jnz .drop + test [edx + TCP_header.Flags], TH_RST ;;; TODO: kill new socket on error + jnz .drop - test [edx + TCP_header.Flags], TH_ACK - jnz .drop_with_reset + test [edx + TCP_header.Flags], TH_ACK + jnz .drop_with_reset - test [edx + TCP_header.Flags], TH_SYN - jz .drop + test [edx + TCP_header.Flags], TH_SYN + jz .drop ;;; TODO: check if it's a broadcast or multicast, and drop if so - push dword [edi + 4] ; Ipv4 destination addres - pop [ebx + IP_SOCKET.RemoteIP] + push dword [edi + 4] ; Ipv4 destination addres + pop [ebx + IP_SOCKET.RemoteIP] - push [edx + TCP_header.SourcePort] - pop [ebx + TCP_SOCKET.RemotePort] + push [edx + TCP_header.SourcePort] + pop [ebx + TCP_SOCKET.RemotePort] - push [edx + TCP_header.SequenceNumber] - pop [ebx + TCP_SOCKET.IRS] + push [edx + TCP_header.SequenceNumber] + pop [ebx + TCP_SOCKET.IRS] - push [TCP_sequence_num] ;;;;; - add [TCP_sequence_num], 64000 / 2 - pop [ebx + TCP_SOCKET.ISS] + push [TCP_sequence_num] ;;;;; + add [TCP_sequence_num], 64000 / 2 + pop [ebx + TCP_SOCKET.ISS] - push [ebx + TCP_SOCKET.ISS] - pop [ebx + TCP_SOCKET.SND_NXT] + push [ebx + TCP_SOCKET.ISS] + pop [ebx + TCP_SOCKET.SND_NXT] - TCP_sendseqinit ebx - TCP_rcvseqinit ebx + TCP_sendseqinit ebx + TCP_rcvseqinit ebx - mov [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED - mov [ebx + TCP_SOCKET.t_flags], TF_ACKNOW - mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval ;;;; macro + mov [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED + mov [ebx + TCP_SOCKET.t_flags], TF_ACKNOW + mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval ;;;; macro - lea eax, [ebx + STREAM_SOCKET.snd] - call SOCKET_ring_create + lea eax, [ebx + STREAM_SOCKET.snd] + call SOCKET_ring_create - lea eax, [ebx + STREAM_SOCKET.rcv] - call SOCKET_ring_create + lea eax, [ebx + STREAM_SOCKET.rcv] + call SOCKET_ring_create ;;; call SOCKET_notify_owner - jmp .trim_then_step6 - + jmp .trim_then_step6 + @@ -521,87 +520,87 @@ align 4 align 4 .SYN_SENT: - DEBUGF 1,"TCP state: syn_sent\n" + DEBUGF 1,"TCP state: syn_sent\n" - test [edx + TCP_header.Flags], TH_ACK - jz @f + test [edx + TCP_header.Flags], TH_ACK + jz @f - mov eax, [edx + TCP_header.AckNumber] - cmp eax, [ebx + TCP_SOCKET.ISS] - jbe .drop_with_reset + mov eax, [edx + TCP_header.AckNumber] + cmp eax, [ebx + TCP_SOCKET.ISS] + jbe .drop_with_reset - cmp eax, [ebx + TCP_SOCKET.SND_MAX] - ja .drop_with_reset + cmp eax, [ebx + TCP_SOCKET.SND_MAX] + ja .drop_with_reset @@: - test [edx + TCP_header.Flags], TH_RST - jz @f + test [edx + TCP_header.Flags], TH_RST + jz @f - test [edx + TCP_header.Flags], TH_ACK - jz .drop + test [edx + TCP_header.Flags], TH_ACK + jz .drop - mov eax, ebx - mov ebx, ECONNREFUSED - call TCP_drop + mov eax, ebx + mov ebx, ECONNREFUSED + call TCP_drop - jmp .drop + jmp .drop @@: - test [edx + TCP_header.Flags], TH_SYN - jz .drop + test [edx + TCP_header.Flags], TH_SYN + jz .drop ; at this point, segment seems to be valid - test [edx + TCP_header.Flags], TH_ACK - jz .no_syn_ack + test [edx + TCP_header.Flags], TH_ACK + jz .no_syn_ack ; now, process received SYN in response to an active open - mov eax, [edx + TCP_header.AckNumber] - mov [ebx + TCP_SOCKET.SND_UNA], eax - cmp eax, [ebx + TCP_SOCKET.SND_NXT] - jbe @f - mov [ebx + TCP_SOCKET.SND_NXT], eax + mov eax, [edx + TCP_header.AckNumber] + mov [ebx + TCP_SOCKET.SND_UNA], eax + cmp eax, [ebx + TCP_SOCKET.SND_NXT] + jbe @f + mov [ebx + TCP_SOCKET.SND_NXT], eax @@: .no_syn_ack: - mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; disable retransmission + mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; disable retransmission - push [edx + TCP_header.SequenceNumber] - pop [ebx + TCP_SOCKET.IRS] + push [edx + TCP_header.SequenceNumber] + pop [ebx + TCP_SOCKET.IRS] - TCP_rcvseqinit ebx + TCP_rcvseqinit ebx - or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW + or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW - mov eax, [ebx + TCP_SOCKET.SND_UNA] - cmp eax, [ebx + TCP_SOCKET.ISS] - jbe .simultaneous_open + mov eax, [ebx + TCP_SOCKET.SND_UNA] + cmp eax, [ebx + TCP_SOCKET.ISS] + jbe .simultaneous_open - test [edx + TCP_header.Flags], TH_ACK - jz .simultaneous_open + test [edx + TCP_header.Flags], TH_ACK + jz .simultaneous_open - DEBUGF 1,"TCP: active open\n" + DEBUGF 1,"TCP: active open\n" ;;; TODO: update stats ; set socket state to connected - mov [ebx + SOCKET.state],1 ;;;; FIXME + mov [ebx + SOCKET.state],1 ;;;; FIXME - mov [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED + mov [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED ;;; TODO: check if we should scale the connection (567-572) ;;; TODO: update RTT estimators - jmp .trim_then_step6 + jmp .trim_then_step6 .simultaneous_open: - DEBUGF 1,"TCP: simultaneous open\n" + DEBUGF 1,"TCP: simultaneous open\n" ; We have received a syn but no ACK, so we are having a simultaneous open.. - mov [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED + mov [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED @@ -614,16 +613,16 @@ align 4 .trim_then_step6: - inc [edx + TCP_header.SequenceNumber] + inc [edx + TCP_header.SequenceNumber] ;;; TODO: Drop any received data that follows receive window (590) - mov eax, [edx + TCP_header.SequenceNumber] - mov [ebx + TCP_SOCKET.RCV_UP], eax - dec eax - mov [ebx + TCP_SOCKET.SND_WL1], eax + mov eax, [edx + TCP_header.SequenceNumber] + mov [ebx + TCP_SOCKET.RCV_UP], eax + dec eax + mov [ebx + TCP_SOCKET.SND_WL1], eax - jmp .ack_processed + jmp .ack_processed @@ -634,7 +633,7 @@ align 4 .NOT_LISTEN_OR_SYN_SENT: - DEBUGF 1,"Slow TCP input: not listen or syn_sent state\n" + DEBUGF 1,"Slow TCP input: not listen or syn_sent state\n" ;-------------------------------------------- ; Protection Against Wrapped Sequence Numbers @@ -659,54 +658,54 @@ align 4 ; check for duplicate data at beginning of segment - mov eax, [ebx + TCP_SOCKET.RCV_NXT] - sub eax, [edx + TCP_header.SequenceNumber] - jbe .no_duplicate + mov eax, [ebx + TCP_SOCKET.RCV_NXT] + sub eax, [edx + TCP_header.SequenceNumber] + jbe .no_duplicate - DEBUGF 1,"Uh oh.. %u bytes of duplicate data!\n", eax + DEBUGF 1,"Uh oh.. %u bytes of duplicate data!\n", eax - test [edx + TCP_header.Flags], TH_SYN - jz .no_dup_syn + test [edx + TCP_header.Flags], TH_SYN + jz .no_dup_syn ; remove duplicate syn - and [edx + TCP_header.Flags], not (TH_SYN) - inc [edx + TCP_header.SequenceNumber] + and [edx + TCP_header.Flags], not (TH_SYN) + inc [edx + TCP_header.SequenceNumber] - cmp [edx + TCP_header.UrgentPointer], 1 - jbe @f - dec [edx + TCP_header.UrgentPointer] - jmp .dup_syn + cmp [edx + TCP_header.UrgentPointer], 1 + jbe @f + dec [edx + TCP_header.UrgentPointer] + jmp .dup_syn @@: - and [edx + TCP_header.Flags], not (TH_URG) + and [edx + TCP_header.Flags], not (TH_URG) .dup_syn: - dec eax + dec eax .no_dup_syn: ; eax holds number of bytes to drop ; Check for entire duplicate packet - cmp eax, ecx - jae .duplicate + cmp eax, ecx + jae .duplicate - DEBUGF 1,"Going to drop %u out of %u bytes\n", eax, ecx + DEBUGF 1,"Going to drop %u out of %u bytes\n", eax, ecx ;;; TODO: apply figure 28.30 ; Check for duplicate FIN - test [edx + TCP_header.Flags], TH_FIN - jz @f - inc ecx - cmp eax, ecx - dec ecx - jne @f + test [edx + TCP_header.Flags], TH_FIN + jz @f + inc ecx + cmp eax, ecx + dec ecx + jne @f - mov eax, ecx - and [edx + TCP_header.Flags], not TH_FIN - or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW - jmp .no_duplicate + mov eax, ecx + and [edx + TCP_header.Flags], not TH_FIN + or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW + jmp .no_duplicate @@: ; Handle the case when a bound socket connects to itself @@ -717,73 +716,73 @@ align 4 ; This code also handles simultaneous half-open or self-connects - test eax, eax - jnz .drop_after_ack + test eax, eax + jnz .drop_after_ack - cmp [edx + TCP_header.Flags], TH_ACK - jz .drop_after_ack + cmp [edx + TCP_header.Flags], TH_ACK + jz .drop_after_ack .duplicate: - DEBUGF 1,"Duplicate received\n" + DEBUGF 1,"Duplicate received\n" ;---------------------------------------- ; Update statistics for duplicate packets ;;; TODO - jmp .drop_after_ack + jmp .drop_after_ack .no_duplicate: ;----------------------------------------------- ; Remove duplicate data and update urgent offset - add [edx + TCP_header.SequenceNumber], eax + add [edx + TCP_header.SequenceNumber], eax ;;; TODO - sub [edx + TCP_header.UrgentPointer], ax - ja @f + sub [edx + TCP_header.UrgentPointer], ax + ja @f - and [edx + TCP_header.Flags], not (TH_URG) - mov [edx + TCP_header.UrgentPointer], 0 + and [edx + TCP_header.Flags], not (TH_URG) + mov [edx + TCP_header.UrgentPointer], 0 @@: ;-------------------------------------------------- ; Handle data that arrives after process terminates - cmp [ebx + SOCKET.PID], 0 - ja @f + cmp [ebx + SOCKET.PID], 0 + ja @f - cmp [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT - jbe @f + cmp [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT + jbe @f - test ecx, ecx - jz @f + test ecx, ecx + jz @f ;;; Close the socket ;;; update stats - jmp .drop_with_reset + jmp .drop_with_reset @@: ;---------------------------------------- ; Remove data beyond right edge of window - mov eax, [edx + TCP_header.SequenceNumber] - add eax, ecx - sub eax, [ebx + TCP_SOCKET.RCV_NXT] - sub ax, [ebx + TCP_SOCKET.RCV_WND] + mov eax, [edx + TCP_header.SequenceNumber] + add eax, ecx + sub eax, [ebx + TCP_SOCKET.RCV_NXT] + sub ax, [ebx + TCP_SOCKET.RCV_WND] ; eax now holds the number of bytes to drop - jbe .no_excess_data + jbe .no_excess_data ;;; TODO: update stats - cmp eax, ecx - jb .dont_drop_all + cmp eax, ecx + jb .dont_drop_all ;;; TODO 700-736 @@ -810,54 +809,54 @@ align 4 ;------------------ ; Process RST flags - test [edx + TCP_header.Flags], TH_RST - jz .rst_skip + test [edx + TCP_header.Flags], TH_RST + jz .rst_skip - DEBUGF 1,"Got an RST flag" + DEBUGF 1,"Got an RST flag" - mov eax, [ebx + TCP_SOCKET.t_state] - shl eax, 2 - jmp dword [eax + .rst_sw_list] + mov eax, [ebx + TCP_SOCKET.t_state] + shl eax, 2 + jmp dword [eax + .rst_sw_list] .rst_sw_list: - dd .rst_skip ;TCPS_CLOSED - dd .rst_skip ;TCPS_LISTEN - dd .rst_skip ;TCPS_SYN_SENT - dd .econnrefused ;TCPS_SYN_RECEIVED - dd .econnreset ;TCPS_ESTABLISHED - dd .econnreset ;TCPS_CLOSE_WAIT - dd .econnreset ;TCPS_FIN_WAIT_1 - dd .rst_close ;TCPS_CLOSING - dd .rst_close ;TCPS_LAST_ACK - dd .econnreset ;TCPS_FIN_WAIT_2 - dd .rst_close ;TCPS_TIMED_WAIT + dd .rst_skip ;TCPS_CLOSED + dd .rst_skip ;TCPS_LISTEN + dd .rst_skip ;TCPS_SYN_SENT + dd .econnrefused ;TCPS_SYN_RECEIVED + dd .econnreset ;TCPS_ESTABLISHED + dd .econnreset ;TCPS_CLOSE_WAIT + dd .econnreset ;TCPS_FIN_WAIT_1 + dd .rst_close ;TCPS_CLOSING + dd .rst_close ;TCPS_LAST_ACK + dd .econnreset ;TCPS_FIN_WAIT_2 + dd .rst_close ;TCPS_TIMED_WAIT .econnrefused: - DEBUGF 1,"Connection refused" + DEBUGF 1,"Connection refused" - mov [ebx + SOCKET.errorcode], ECONNREFUSED - jmp .close + mov [ebx + SOCKET.errorcode], ECONNREFUSED + jmp .close .econnreset: - DEBUGF 1,"Connection reset" + DEBUGF 1,"Connection reset" - mov [ebx + SOCKET.errorcode], ECONNRESET + mov [ebx + SOCKET.errorcode], ECONNRESET .close: - DEBUGF 1,"Closing connection" + DEBUGF 1,"Closing connection" - mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSED - ;;; TODO: update stats - mov eax, ebx - call TCP_close - jmp .drop + mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSED + ;;; TODO: update stats + mov eax, ebx + call TCP_close + jmp .drop .rst_close: - DEBUGF 1,"Closing with reset\n" + DEBUGF 1,"Closing with reset\n" - mov eax, ebx - call TCP_close - jmp .drop + mov eax, ebx + call TCP_close + jmp .drop @@ -871,16 +870,16 @@ align 4 ;-------------------------------------- ; handle SYN-full and ACK-less segments - test [edx + TCP_header.Flags], TH_SYN - jz @f + test [edx + TCP_header.Flags], TH_SYN + jz @f - mov eax, ebx - mov ebx, ECONNRESET - call TCP_drop - jmp .drop_with_reset + mov eax, ebx + mov ebx, ECONNRESET + call TCP_drop + jmp .drop_with_reset - test [edx + TCP_header.Flags], TH_ACK - jz .drop + test [edx + TCP_header.Flags], TH_ACK + jz .drop @@: @@ -892,130 +891,130 @@ align 4 ;--------------- ; ACK processing - cmp [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED - jnz .no_syn_rcv + cmp [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED + jnz .no_syn_rcv - DEBUGF 1,"TCP state = syn received\n" + DEBUGF 1,"TCP state = syn received\n" - mov eax, [edx + TCP_header.AckNumber] - cmp [ebx + TCP_SOCKET.SND_UNA], eax - ja .drop_with_reset - cmp eax, [ebx + TCP_SOCKET.SND_MAX] - ja .drop_with_reset + mov eax, [edx + TCP_header.AckNumber] + cmp [ebx + TCP_SOCKET.SND_UNA], eax + ja .drop_with_reset + cmp eax, [ebx + TCP_SOCKET.SND_MAX] + ja .drop_with_reset ;;; TODO: update stats - mov eax, ebx - call SOCKET_is_connected - mov [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED + mov eax, ebx + call SOCKET_is_connected + mov [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED ; Do window scaling? - test [ebx + TCP_SOCKET.t_flags], TF_RCVD_SCALE - jz @f - test [ebx + TCP_SOCKET.t_flags], TF_REQ_SCALE - jz @f + test [ebx + TCP_SOCKET.t_flags], TF_RCVD_SCALE + jz @f + test [ebx + TCP_SOCKET.t_flags], TF_REQ_SCALE + jz @f - push word [ebx + TCP_SOCKET.requested_s_scale] ; Set send and receive scale factors to the received values - pop word [ebx + TCP_SOCKET.SND_SCALE] + push word [ebx + TCP_SOCKET.requested_s_scale] ; Set send and receive scale factors to the received values + pop word [ebx + TCP_SOCKET.SND_SCALE] @@: ;;; TODO: copy the data (if any) into the socket - mov eax, [edx + TCP_header.SequenceNumber] - dec eax - mov [ebx + TCP_SOCKET.SND_WL1], eax - jmp .not_dup_ack + mov eax, [edx + TCP_header.SequenceNumber] + dec eax + mov [ebx + TCP_SOCKET.SND_WL1], eax + jmp .not_dup_ack .no_syn_rcv: ; check for duplicate ACK - mov eax, [edx + TCP_header.AckNumber] - cmp eax, [ebx + TCP_SOCKET.SND_UNA] - ja .not_dup_ack + mov eax, [edx + TCP_header.AckNumber] + cmp eax, [ebx + TCP_SOCKET.SND_UNA] + ja .not_dup_ack - test ecx, ecx - jnz .reset_dupacks + test ecx, ecx + jnz .reset_dupacks - mov eax, dword [edx + TCP_header.Window] - cmp eax, [ebx + TCP_SOCKET.SND_WND] - jne .reset_dupacks + mov eax, dword [edx + TCP_header.Window] + cmp eax, [ebx + TCP_SOCKET.SND_WND] + jne .reset_dupacks - DEBUGF 1,"Processing a duplicate ACK..\n" + DEBUGF 1,"Processing a duplicate ACK..\n" - cmp [ebx + TCP_SOCKET.timer_retransmission], 10000 ;;;; FIXME - ja @f + cmp [ebx + TCP_SOCKET.timer_retransmission], 10000 ;;;; FIXME + ja @f - mov eax, [edx + TCP_header.AckNumber] - cmp eax, [ebx + TCP_SOCKET.SND_UNA] - je .dup_ack + mov eax, [edx + TCP_header.AckNumber] + cmp eax, [ebx + TCP_SOCKET.SND_UNA] + je .dup_ack @@: - mov [ebx + TCP_SOCKET.t_dupacks], 0 - jmp .not_dup_ack + mov [ebx + TCP_SOCKET.t_dupacks], 0 + jmp .not_dup_ack .dup_ack: - inc [ebx + TCP_SOCKET.t_dupacks] - cmp [ebx + TCP_SOCKET.t_dupacks], TCP_re_xmit_thresh - jne .no_re_xmit + inc [ebx + TCP_SOCKET.t_dupacks] + cmp [ebx + TCP_SOCKET.t_dupacks], TCP_re_xmit_thresh + jne .no_re_xmit - push [ebx + TCP_SOCKET.SND_NXT] ; >>>> + push [ebx + TCP_SOCKET.SND_NXT] ; >>>> - mov eax, [ebx + TCP_SOCKET.SND_WND] - cmp eax, [ebx + TCP_SOCKET.SND_CWND] - cmovg eax, [ebx + TCP_SOCKET.SND_CWND] - shr eax, 1 - push edx - xor edx, edx - div [ebx + TCP_SOCKET.t_maxseg] - cmp eax, 2 - jae @f - mov ax, 2 + mov eax, [ebx + TCP_SOCKET.SND_WND] + cmp eax, [ebx + TCP_SOCKET.SND_CWND] + cmovg eax, [ebx + TCP_SOCKET.SND_CWND] + shr eax, 1 + push edx + xor edx, edx + div [ebx + TCP_SOCKET.t_maxseg] + cmp eax, 2 + jae @f + mov ax, 2 @@: - mul [ebx + TCP_SOCKET.t_maxseg] - pop edx - mov [ebx + TCP_SOCKET.SND_SSTHRESH], eax + mul [ebx + TCP_SOCKET.t_maxseg] + pop edx + mov [ebx + TCP_SOCKET.SND_SSTHRESH], eax - mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; turn off retransmission timer - mov [ebx + TCP_SOCKET.t_rtt], 0 - mov eax, [edx + TCP_header.AckNumber] - mov [ebx + TCP_SOCKET.SND_NXT], eax - mov eax, [ebx + TCP_SOCKET.t_maxseg] - mov [ebx + TCP_SOCKET.SND_CWND], eax + mov [ebx + TCP_SOCKET.timer_retransmission], 0 ; turn off retransmission timer + mov [ebx + TCP_SOCKET.t_rtt], 0 + mov eax, [edx + TCP_header.AckNumber] + mov [ebx + TCP_SOCKET.SND_NXT], eax + mov eax, [ebx + TCP_SOCKET.t_maxseg] + mov [ebx + TCP_SOCKET.SND_CWND], eax - mov eax, ebx - call TCP_output ; retransmit missing segment + mov eax, ebx + call TCP_output ; retransmit missing segment - push edx - xor edx, edx - mov eax, [ebx + TCP_SOCKET.t_maxseg] - mul [ebx + TCP_SOCKET.t_dupacks] - pop edx - add eax, [ebx + TCP_SOCKET.SND_SSTHRESH] - mov [ebx + TCP_SOCKET.SND_CWND], eax + push edx + xor edx, edx + mov eax, [ebx + TCP_SOCKET.t_maxseg] + mul [ebx + TCP_SOCKET.t_dupacks] + pop edx + add eax, [ebx + TCP_SOCKET.SND_SSTHRESH] + mov [ebx + TCP_SOCKET.SND_CWND], eax - pop eax ; <<<< - cmp eax, [ebx + TCP_SOCKET.SND_NXT] - jb @f - mov [ebx + TCP_SOCKET.SND_NXT], eax + pop eax ; <<<< + cmp eax, [ebx + TCP_SOCKET.SND_NXT] + jb @f + mov [ebx + TCP_SOCKET.SND_NXT], eax @@: - jmp .drop + jmp .drop .no_re_xmit: - jbe .not_dup_ack + jbe .not_dup_ack - DEBUGF 1,"Increasing congestion window\n" + DEBUGF 1,"Increasing congestion window\n" - mov eax, [ebx + TCP_SOCKET.t_maxseg] - add [ebx + TCP_SOCKET.SND_CWND], eax + mov eax, [ebx + TCP_SOCKET.t_maxseg] + add [ebx + TCP_SOCKET.SND_CWND], eax - mov eax, ebx - call TCP_output + mov eax, ebx + call TCP_output - jmp .drop + jmp .drop @@ -1028,32 +1027,32 @@ align 4 ; If the congestion window was inflated to account ; for the other side's cached packets, retract it - mov eax, [ebx + TCP_SOCKET.SND_SSTHRESH] - cmp eax, [ebx + TCP_SOCKET.SND_CWND] - ja @f - cmp [ebx + TCP_SOCKET.t_dupacks], TCP_re_xmit_thresh - jbe @f - mov [ebx + TCP_SOCKET.SND_CWND], eax + mov eax, [ebx + TCP_SOCKET.SND_SSTHRESH] + cmp eax, [ebx + TCP_SOCKET.SND_CWND] + ja @f + cmp [ebx + TCP_SOCKET.t_dupacks], TCP_re_xmit_thresh + jbe @f + mov [ebx + TCP_SOCKET.SND_CWND], eax @@: - mov [ebx + TCP_SOCKET.t_dupacks], 0 + mov [ebx + TCP_SOCKET.t_dupacks], 0 - mov eax, [edx + TCP_header.AckNumber] - cmp eax, [ebx + TCP_SOCKET.SND_MAX] - jbe @f + mov eax, [edx + TCP_header.AckNumber] + cmp eax, [ebx + TCP_SOCKET.SND_MAX] + jbe @f - ;;; TODO: update stats - jmp .drop_after_ack + ;;; TODO: update stats + jmp .drop_after_ack @@: - mov edi, [edx + TCP_header.AckNumber] - sub edi, [ebx + TCP_SOCKET.SND_UNA] ; now we got the number of acked bytes in edi + mov edi, [edx + TCP_header.AckNumber] + sub edi, [ebx + TCP_SOCKET.SND_UNA] ; now we got the number of acked bytes in edi - ;;; TODO: update stats + ;;; TODO: update stats - DEBUGF 1,"We have an acceptable ACK of %x bytes\n", esi + DEBUGF 1,"We have an acceptable ACK of %x bytes\n", esi @@ -1063,14 +1062,14 @@ align 4 ;------------------------------------------ ; RTT measurements and retransmission timer - ;;;;; 912 - 926 + ;;;;; 912 - 926 - mov [ebx + TCP_SOCKET.timer_retransmission], 0 + mov [ebx + TCP_SOCKET.timer_retransmission], 0 - mov eax, [ebx + TCP_SOCKET.SND_MAX] - cmp eax, [edx + TCP_header.AckNumber] - je .all_outstanding - mov [ebx + TCP_SOCKET.timer_retransmission], 120 ;;;; TODO: correct this value (use a macro for it) + mov eax, [ebx + TCP_SOCKET.SND_MAX] + cmp eax, [edx + TCP_header.AckNumber] + je .all_outstanding + mov [ebx + TCP_SOCKET.timer_retransmission], 120 ;;;; TODO: correct this value (use a macro for it) .all_outstanding: @@ -1082,32 +1081,32 @@ align 4 ;------------------------------------------- ; Open congestion window in response to ACKs - mov esi, [ebx + TCP_SOCKET.SND_CWND] - mov eax, [ebx + TCP_SOCKET.t_maxseg] + mov esi, [ebx + TCP_SOCKET.SND_CWND] + mov eax, [ebx + TCP_SOCKET.t_maxseg] - cmp esi, [ebx + TCP_SOCKET.SND_SSTHRESH] - jbe @f - push edx - push eax - mul eax - div esi - pop edx - shr edx, 3 - add eax, edx - pop edx + cmp esi, [ebx + TCP_SOCKET.SND_SSTHRESH] + jbe @f + push edx + push eax + mul eax + div esi + pop edx + shr edx, 3 + add eax, edx + pop edx @@: - add esi, eax + add esi, eax - push ecx - mov cl, [ebx + TCP_SOCKET.SND_SCALE] - mov eax, TCP_max_win - shl eax, cl - pop ecx + push ecx + mov cl, [ebx + TCP_SOCKET.SND_SCALE] + mov eax, TCP_max_win + shl eax, cl + pop ecx - cmp esi, eax - cmovg esi, eax - mov [ebx + TCP_SOCKET.SND_CWND], esi + cmp esi, eax + cmovg esi, eax + mov [ebx + TCP_SOCKET.SND_CWND], esi @@ -1118,31 +1117,31 @@ align 4 ;------------------------------------------ ; Remove acknowledged data from send buffer - push ecx edx ebx - mov ecx, edi - lea eax, [ebx + STREAM_SOCKET.snd] - call SOCKET_ring_free - pop ebx - sub [ebx + TCP_SOCKET.SND_WND], ecx - pop edx ecx + push ecx edx ebx + mov ecx, edi + lea eax, [ebx + STREAM_SOCKET.snd] + call SOCKET_ring_free + pop ebx + sub [ebx + TCP_SOCKET.SND_WND], ecx + pop edx ecx ; Wake up process waiting on send buffer - mov eax, ebx - call SOCKET_notify_owner + mov eax, ebx + call SOCKET_notify_owner ; Update TCPS - mov eax, [edx + TCP_header.AckNumber] - mov [ebx + TCP_SOCKET.SND_UNA], eax + mov eax, [edx + TCP_header.AckNumber] + mov [ebx + TCP_SOCKET.SND_UNA], eax - cmp eax, [ebx + TCP_SOCKET.SND_NXT] - jb @f - mov [ebx + TCP_SOCKET.SND_NXT], eax + cmp eax, [ebx + TCP_SOCKET.SND_NXT] + jb @f + mov [ebx + TCP_SOCKET.SND_NXT], eax @@: - ;; TODO: use zero flag as 'ourfinisacked' + ;; TODO: use zero flag as 'ourfinisacked' @@ -1150,61 +1149,61 @@ align 4 ; General ACK handling complete ; Now do the state-specific ones - mov eax, [ebx + TCP_SOCKET.t_state] - jmp dword [eax*4 + .ACK_sw_list] + mov eax, [ebx + TCP_SOCKET.t_state] + jmp dword [eax*4 + .ACK_sw_list] .ACK_sw_list: - dd .ack_processed ;TCPS_CLOSED - dd .ack_processed ;TCPS_LISTEN - dd .ack_processed ;TCPS_SYN_SENT - dd .ack_processed ;TCPS_SYN_RECEIVED - dd .ack_processed ;TCPS_ESTABLISHED - dd .ack_processed ;TCPS_CLOSE_WAIT - dd .ack_fw1 ;TCPS_FIN_WAIT_1 - dd .ack_c ;TCPS_CLOSING - dd .ack_la ;TCPS_LAST_ACK - dd .ack_processed ;TCPS_FIN_WAIT_2 - dd .ack_tw ;TCPS_TIMED_WAIT + dd .ack_processed ;TCPS_CLOSED + dd .ack_processed ;TCPS_LISTEN + dd .ack_processed ;TCPS_SYN_SENT + dd .ack_processed ;TCPS_SYN_RECEIVED + dd .ack_processed ;TCPS_ESTABLISHED + dd .ack_processed ;TCPS_CLOSE_WAIT + dd .ack_fw1 ;TCPS_FIN_WAIT_1 + dd .ack_c ;TCPS_CLOSING + dd .ack_la ;TCPS_LAST_ACK + dd .ack_processed ;TCPS_FIN_WAIT_2 + dd .ack_tw ;TCPS_TIMED_WAIT .ack_fw1: - jz .ack_processed + jz .ack_processed - test [ebx + SOCKET.state], SS_CANTRCVMORE - jnz @f - mov eax, ebx - call SOCKET_is_disconnected + test [ebx + SOCKET.state], SS_CANTRCVMORE + jnz @f + mov eax, ebx + call SOCKET_is_disconnected ;;; mov [ebx + TCP_SOCKET.timer_timed_wait], TCP_time_max_idle @@: - mov [ebx + TCP_SOCKET.t_state], TCPS_FIN_WAIT_2 - jmp .ack_processed + mov [ebx + TCP_SOCKET.t_state], TCPS_FIN_WAIT_2 + jmp .ack_processed .ack_c: - jz .ack_processed + jz .ack_processed - 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 - mov eax, ebx - call SOCKET_is_disconnected - jmp .ack_processed + 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 + mov eax, ebx + call SOCKET_is_disconnected + jmp .ack_processed .ack_la: - jz .ack_processed + jz .ack_processed - mov eax, ebx - call TCP_close - jmp .drop + mov eax, ebx + call TCP_close + jmp .drop .ack_tw: - mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL - jmp .drop_after_ack + mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL + jmp .drop_after_ack @@ -1212,42 +1211,42 @@ align 4 - .reset_dupacks: ; We got a new ACK, reset duplicate ACK counter + .reset_dupacks: ; We got a new ACK, reset duplicate ACK counter - mov [ebx + TCP_SOCKET.t_dupacks], 0 + mov [ebx + TCP_SOCKET.t_dupacks], 0 - .ack_processed: ; (step 6) + .ack_processed: ; (step 6) - DEBUGF 1,"ACK processed\n" + DEBUGF 1,"ACK processed\n" ;---------------------------------------------- ; check if we need to update window information - test [edx + TCP_header.Flags], TH_ACK - jz .no_window_update + test [edx + TCP_header.Flags], TH_ACK + jz .no_window_update - mov eax, [ebx + TCP_SOCKET.SND_WL1] - cmp eax, [edx + TCP_header.SequenceNumber] - jb .update_window - ja @f + mov eax, [ebx + TCP_SOCKET.SND_WL1] + cmp eax, [edx + TCP_header.SequenceNumber] + jb .update_window + ja @f - mov eax, [ebx + TCP_SOCKET.SND_WL2] - cmp eax, [edx + TCP_header.AckNumber] - jb .update_window - ja .no_window_update + mov eax, [ebx + TCP_SOCKET.SND_WL2] + cmp eax, [edx + TCP_header.AckNumber] + jb .update_window + ja .no_window_update @@: - mov eax, [ebx + TCP_SOCKET.SND_WL2] - cmp eax, [edx + TCP_header.AckNumber] - jne .no_window_update + mov eax, [ebx + TCP_SOCKET.SND_WL2] + cmp eax, [edx + TCP_header.AckNumber] + jne .no_window_update - mov eax, dword [edx + TCP_header.Window] - cmp eax, [ebx + TCP_SOCKET.SND_WND] - jbe .no_window_update + mov eax, dword [edx + TCP_header.Window] + cmp eax, [ebx + TCP_SOCKET.SND_WND] + jbe .no_window_update .update_window: - DEBUGF 1,"Updating window\n" + DEBUGF 1,"Updating window\n" ; Keep track of pure window updates @@ -1266,20 +1265,20 @@ align 4 ; ; @@: - mov eax, dword [edx + TCP_header.Window] - cmp eax, [ebx + TCP_SOCKET.max_sndwnd] - jbe @f - mov [ebx + TCP_SOCKET.max_sndwnd], eax + mov eax, dword [edx + TCP_header.Window] + cmp eax, [ebx + TCP_SOCKET.max_sndwnd] + jbe @f + mov [ebx + TCP_SOCKET.max_sndwnd], eax @@: - mov [ebx + TCP_SOCKET.SND_WND], eax + mov [ebx + TCP_SOCKET.SND_WND], eax - push [edx + TCP_header.SequenceNumber] - pop [ebx + TCP_SOCKET.SND_WL1] + push [edx + TCP_header.SequenceNumber] + pop [ebx + TCP_SOCKET.SND_WL1] - push [edx + TCP_header.AckNumber] - pop [ebx + TCP_SOCKET.SND_WL2] + push [edx + TCP_header.AckNumber] + pop [ebx + TCP_SOCKET.SND_WL2] - ;;; needoutput = 1 + ;;; needoutput = 1 .no_window_update: @@ -1292,33 +1291,33 @@ align 4 ;----------------- ; process URG flag - test [edx + TCP_header.Flags], TH_URG - jz .not_urgent + test [edx + TCP_header.Flags], TH_URG + jz .not_urgent - cmp [edx + TCP_header.UrgentPointer], 0 - jz .not_urgent + cmp [edx + TCP_header.UrgentPointer], 0 + jz .not_urgent - cmp [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT - je .not_urgent + cmp [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT + je .not_urgent ; Ignore bogus urgent offsets - ;;; 1040-1050 + ;;; 1040-1050 - movzx eax, [edx + TCP_header.UrgentPointer] - add eax, [ebx + STREAM_SOCKET.rcv.size] - cmp eax, SOCKET_MAXDATA - jbe .not_urgent + movzx eax, [edx + TCP_header.UrgentPointer] + add eax, [ebx + STREAM_SOCKET.rcv.size] + cmp eax, SOCKET_MAXDATA + jbe .not_urgent - mov [edx + TCP_header.UrgentPointer], 0 - and [edx + TCP_header.Flags], not (TH_URG) - jmp .do_data + mov [edx + TCP_header.UrgentPointer], 0 + and [edx + TCP_header.Flags], not (TH_URG) + jmp .do_data .not_urgent: ; processing of received urgent pointer - ;;; TODO (1051-1093) + ;;; TODO (1051-1093) @@ -1332,34 +1331,34 @@ align 4 .do_data: - DEBUGF 1,"TCP: do data (%u)\n", ecx + DEBUGF 1,"TCP: do data (%u)\n", ecx - test [edx + TCP_header.Flags], TH_FIN - jnz .process_fin + test [edx + TCP_header.Flags], TH_FIN + jnz .process_fin - cmp [ebx + TCP_SOCKET.t_state], TCPS_FIN_WAIT_1 - jae .dont_do_data + cmp [ebx + TCP_SOCKET.t_state], TCPS_FIN_WAIT_1 + jae .dont_do_data - test ecx, ecx - jz .final_processing + test ecx, ecx + jz .final_processing - DEBUGF 1,"Processing data in segment\n" + DEBUGF 1,"Processing data in segment\n" ;; TODO: check if data is in sequence ! - movzx esi, [edx + TCP_header.DataOffset] - add esi, edx + movzx esi, [edx + TCP_header.DataOffset] + add esi, edx - or [ebx + TCP_SOCKET.t_flags], TF_DELACK - add [ebx + TCP_SOCKET.RCV_NXT], ecx + or [ebx + TCP_SOCKET.t_flags], TF_DELACK + add [ebx + TCP_SOCKET.RCV_NXT], ecx - lea eax, [ebx + STREAM_SOCKET.rcv] - call SOCKET_ring_write + lea eax, [ebx + STREAM_SOCKET.rcv] + call SOCKET_ring_write - mov eax, ebx - call SOCKET_notify_owner + mov eax, ebx + call SOCKET_notify_owner - jmp .final_processing + jmp .final_processing .dont_do_data: @@ -1375,63 +1374,63 @@ align 4 .process_fin: - DEBUGF 1,"Processing FIN\n" + DEBUGF 1,"Processing FIN\n" - cmp [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT - je .not_first_fin - cmp [ebx + TCP_SOCKET.t_state], TCPS_CLOSING - je .not_first_fin - cmp [ebx + TCP_SOCKET.t_state], TCPS_FIN_WAIT_2 - je .not_first_fin + cmp [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT + je .not_first_fin + cmp [ebx + TCP_SOCKET.t_state], TCPS_CLOSING + je .not_first_fin + cmp [ebx + TCP_SOCKET.t_state], TCPS_FIN_WAIT_2 + je .not_first_fin - DEBUGF 1,"First FIN for this connection\n" + DEBUGF 1,"First FIN for this connection\n" - mov eax, ebx - call SOCKET_cant_recv_more + mov eax, ebx + call SOCKET_cant_recv_more - mov [ebx + TCP_SOCKET.t_flags], TF_ACKNOW - inc [ebx + TCP_SOCKET.RCV_NXT] + mov [ebx + TCP_SOCKET.t_flags], TF_ACKNOW + inc [ebx + TCP_SOCKET.RCV_NXT] .not_first_fin: - mov eax, [ebx + TCP_SOCKET.t_state] - shl eax, 2 - jmp dword [eax + .FIN_sw_list] + mov eax, [ebx + TCP_SOCKET.t_state] + shl eax, 2 + jmp dword [eax + .FIN_sw_list] .FIN_sw_list: - dd .no_fin ;TCPS_CLOSED - dd .no_fin ;TCPS_LISTEN - dd .no_fin ;TCPS_SYN_SENT - dd .fin_syn_est ;TCPS_SYN_RECEIVED - dd .fin_syn_est ;TCPS_ESTABLISHED - dd .no_fin ;TCPS_CLOSE_WAIT - dd .fin_wait1 ;TCPS_FIN_WAIT_1 - dd .no_fin ;TCPS_CLOSING - dd .no_fin ;TCPS_LAST_ACK - dd .fin_wait2 ;TCPS_FIN_WAIT_2 - dd .fin_timed ;TCPS_TIMED_WAIT + dd .no_fin ;TCPS_CLOSED + dd .no_fin ;TCPS_LISTEN + dd .no_fin ;TCPS_SYN_SENT + dd .fin_syn_est ;TCPS_SYN_RECEIVED + dd .fin_syn_est ;TCPS_ESTABLISHED + dd .no_fin ;TCPS_CLOSE_WAIT + dd .fin_wait1 ;TCPS_FIN_WAIT_1 + dd .no_fin ;TCPS_CLOSING + dd .no_fin ;TCPS_LAST_ACK + dd .fin_wait2 ;TCPS_FIN_WAIT_2 + dd .fin_timed ;TCPS_TIMED_WAIT .fin_syn_est: - mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT - jmp .no_fin + mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT + jmp .no_fin .fin_wait1: - mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSING - jmp .no_fin + mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSING + jmp .no_fin .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 - call SOCKET_is_disconnected - jmp .no_fin + 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 + call SOCKET_is_disconnected + jmp .no_fin .fin_timed: - mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL - jmp .no_fin + mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL + jmp .no_fin .no_fin: @@ -1447,30 +1446,30 @@ align 4 .final_processing: - DEBUGF 1,"Final processing\n" + DEBUGF 1,"Final processing\n" - ;;; if debug enabled, output packet + ;;; if debug enabled, output packet - ;test needoutput, needoutput - ;jz .dumpit + ;test needoutput, needoutput + ;jz .dumpit - test [ebx + TCP_SOCKET.t_flags], TF_ACKNOW - jz .dumpit + test [ebx + TCP_SOCKET.t_flags], TF_ACKNOW + jz .dumpit - DEBUGF 1,"ACK now!\n" + DEBUGF 1,"ACK now!\n" - push ebx - mov eax, ebx - call TCP_output - pop ebx + push ebx + mov eax, ebx + call TCP_output + pop ebx .dumpit: - mov [ebx + SOCKET.lock], 0 + mov [ebx + SOCKET.lock], 0 - call kernel_free - add esp, 4 - ret + call kernel_free + add esp, 4 + ret @@ -1484,25 +1483,25 @@ align 4 align 4 .drop_after_ack: - DEBUGF 1,"Drop after ACK\n" + DEBUGF 1,"Drop after ACK\n" - test [edx + TCP_header.Flags], TH_RST - jnz .drop + test [edx + TCP_header.Flags], TH_RST + jnz .drop - and [ebx + TCP_SOCKET.t_flags], TF_ACKNOW + and [ebx + TCP_SOCKET.t_flags], TF_ACKNOW - mov [ebx + SOCKET.lock], 0 + mov [ebx + SOCKET.lock], 0 - push ebx + push ebx ; mov cl, TH_ACK ; call TCP_respond_socket - mov eax, ebx - call TCP_output - pop ebx + mov eax, ebx + call TCP_output + pop ebx - call kernel_free - add esp, 4 - ret + call kernel_free + add esp, 4 + ret @@ -1517,45 +1516,45 @@ align 4 align 4 .drop_with_reset: - mov [ebx + SOCKET.lock], 0 + mov [ebx + SOCKET.lock], 0 .drop_with_reset_not_locked: - DEBUGF 1,"Drop with reset\n" + DEBUGF 1,"Drop with reset\n" - test [edx + TCP_header.Flags], TH_RST - jnz .drop + test [edx + TCP_header.Flags], TH_RST + jnz .drop - ;;; if its a multicast/broadcast, also drop + ;;; if its a multicast/broadcast, also drop - test [edx + TCP_header.Flags], TH_ACK - jnz .respond_ack + test [edx + TCP_header.Flags], TH_ACK + jnz .respond_ack - test [edx + TCP_header.Flags], TH_SYN - jnz .respond_syn + test [edx + TCP_header.Flags], TH_SYN + jnz .respond_syn - call kernel_free - add esp, 4 - ret + call kernel_free + add esp, 4 + ret .respond_ack: - push ebx - mov cl, TH_RST - call TCP_respond_socket - pop ebx + push ebx + mov cl, TH_RST + call TCP_respond_socket + pop ebx - jmp .destroy_new_socket + jmp .destroy_new_socket .respond_syn: - push ebx - mov cl, TH_RST + TH_ACK - call TCP_respond_socket - pop ebx + push ebx + mov cl, TH_RST + TH_ACK + call TCP_respond_socket + pop ebx - jmp .destroy_new_socket + jmp .destroy_new_socket @@ -1569,18 +1568,18 @@ align 4 align 4 .drop: - mov [ebx + SOCKET.lock], 0 + mov [ebx + SOCKET.lock], 0 .drop_not_locked: - DEBUGF 1,"Dropping packet\n" + DEBUGF 1,"Dropping packet\n" - ;;;; If debugging options are enabled, output the packet somwhere + ;;;; If debugging options are enabled, output the packet somwhere .destroy_new_socket: - ;;;; kill the newly created socket + ;;;; kill the newly created socket - call kernel_free - add esp, 4 - ret \ No newline at end of file + call kernel_free + add esp, 4 + ret \ No newline at end of file diff --git a/kernel/branches/net/network/tcp_subr.inc b/kernel/branches/net/network/tcp_subr.inc index b7e5931133..e9272626b1 100644 --- a/kernel/branches/net/network/tcp_subr.inc +++ b/kernel/branches/net/network/tcp_subr.inc @@ -16,65 +16,67 @@ $Revision$ -macro TCP_checksum IP1, IP2 { +macro TCP_checksum IP1, IP2 { ;------------- ; Pseudoheader - ; protocol type - mov edx, IP_PROTO_TCP + ; protocol type + mov edx, IP_PROTO_TCP - ; source address - add dl, byte [IP1+1] - adc dh, byte [IP1+0] - adc dl, byte [IP1+3] - adc dh, byte [IP1+2] + ; source address + add dl, byte [IP1+1] + adc dh, byte [IP1+0] + adc dl, byte [IP1+3] + adc dh, byte [IP1+2] - ; destination address - adc dl, byte [IP2+1] - adc dh, byte [IP2+0] - adc dl, byte [IP2+3] - adc dh, byte [IP2+2] + ; destination address + adc dl, byte [IP2+1] + adc dh, byte [IP2+0] + adc dl, byte [IP2+3] + adc dh, byte [IP2+2] - ; size - adc dl, cl - adc dh, ch + ; size + adc dl, cl + adc dh, ch + + adc edx, 0 ;--------------------- ; Real header and data - push esi - call checksum_1 - call checksum_2 - pop esi + push esi + call checksum_1 + call checksum_2 + pop esi -} ; returns in dx only +} ; returns in dx only -macro TCP_sendseqinit ptr { +macro TCP_sendseqinit ptr { - push edi ;;;; i dont like this static use of edi - mov edi, [ptr + TCP_SOCKET.ISS] - mov [ptr + TCP_SOCKET.SND_UP], edi - mov [ptr + TCP_SOCKET.SND_MAX], edi - mov [ptr + TCP_SOCKET.SND_NXT], edi - mov [ptr + TCP_SOCKET.SND_UNA], edi - pop edi + push edi ;;;; i dont like this static use of edi + mov edi, [ptr + TCP_SOCKET.ISS] + mov [ptr + TCP_SOCKET.SND_UP], edi + mov [ptr + TCP_SOCKET.SND_MAX], edi + mov [ptr + TCP_SOCKET.SND_NXT], edi + mov [ptr + TCP_SOCKET.SND_UNA], edi + pop edi } -macro TCP_rcvseqinit ptr { +macro TCP_rcvseqinit ptr { - push edi - mov edi, [ptr + TCP_SOCKET.IRS] - inc edi - mov [ptr + TCP_SOCKET.RCV_NXT], edi - mov [ptr + TCP_SOCKET.RCV_ADV], edi - pop edi + push edi + mov edi, [ptr + TCP_SOCKET.IRS] + inc edi + mov [ptr + TCP_SOCKET.RCV_NXT], edi + mov [ptr + TCP_SOCKET.RCV_ADV], edi + pop edi } @@ -102,11 +104,11 @@ macro TCP_rcvseqinit ptr { align 4 TCP_pull_out_of_band: - DEBUGF 1,"TCP_pull_out_of_band\n" + DEBUGF 1,"TCP_pull_out_of_band\n" - ;;;; 1282-1305 + ;;;; 1282-1305 - ret + ret @@ -128,18 +130,18 @@ TCP_pull_out_of_band: align 4 TCP_drop: - DEBUGF 1,"TCP_drop\n" + DEBUGF 1,"TCP_drop\n" - cmp [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED - jb .no_syn_received + cmp [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED + jb .no_syn_received - mov [eax + TCP_SOCKET.t_state], TCPS_CLOSED + mov [eax + TCP_SOCKET.t_state], TCPS_CLOSED - call TCP_output + call TCP_output ;;; TODO: update stats - jmp TCP_close + jmp TCP_close .no_syn_received: @@ -147,7 +149,7 @@ TCP_drop: ;;; TODO: check if error code is "Connection timed out' and handle accordingly - mov [eax + SOCKET.errorcode], ebx + mov [eax + SOCKET.errorcode], ebx @@ -167,15 +169,15 @@ TCP_drop: align 4 TCP_close: - DEBUGF 1,"TCP_close\n" + DEBUGF 1,"TCP_close\n" ;;; TODO: update RTT and mean deviation ;;; TODO: update slow start threshold ;;; TODO: release connection resources - call SOCKET_is_disconnected + call SOCKET_is_disconnected - ret + ret @@ -198,26 +200,26 @@ TCP_close: align 4 TCP_outflags: - mov edx, [eax + TCP_SOCKET.t_state] - movzx edx, byte [edx + .flaglist] + mov edx, [eax + TCP_SOCKET.t_state] + movzx edx, byte [edx + .flaglist] - DEBUGF 1,"TCP_outflags, socket: %x, flags: %x\n", eax, dl + DEBUGF 1,"TCP_outflags, socket: %x, flags: %x\n", eax, dl - ret + ret .flaglist: - db TH_RST + TH_ACK ; TCPS_CLOSED - db 0 ; TCPS_LISTEN - db TH_SYN ; TCPS_SYN_SENT - 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_ACK ; TCPS_FIN_WAIT_2 - db TH_ACK ; TCPS_TIMED_WAIT + db TH_RST + TH_ACK ; TCPS_CLOSED + db 0 ; TCPS_LISTEN + db TH_SYN ; TCPS_SYN_SENT + 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_ACK ; TCPS_FIN_WAIT_2 + db TH_ACK ; TCPS_TIMED_WAIT @@ -237,69 +239,69 @@ TCP_outflags: align 4 TCP_respond_socket: - DEBUGF 1,"TCP_respond_socket\n" + DEBUGF 1,"TCP_respond_socket\n" ;--------------------- ; Create the IP packet - push cx ebx - mov eax, [ebx + IP_SOCKET.RemoteIP] - mov ebx, [ebx + IP_SOCKET.LocalIP] - mov ecx, sizeof.TCP_header - mov di , IP_PROTO_TCP shl 8 + 128 - call IPv4_output - test edi, edi - jz .error - pop esi cx - push edx eax + push cx ebx + mov eax, [ebx + IP_SOCKET.RemoteIP] + mov ebx, [ebx + IP_SOCKET.LocalIP] + mov ecx, sizeof.TCP_header + mov di , IP_PROTO_TCP shl 8 + 128 + call IPv4_output + test edi, edi + jz .error + pop esi cx + push edx eax ;----------------------------------------------- ; Fill in the TCP header by using the socket ptr - mov ax, [esi + TCP_SOCKET.LocalPort] - rol ax, 8 - stosw - mov ax, [esi + TCP_SOCKET.RemotePort] - rol ax, 8 - stosw - mov eax, [esi + TCP_SOCKET.SND_NXT] - bswap eax - stosd - mov eax, [esi + TCP_SOCKET.RCV_NXT] - bswap eax - stosd - mov al, 0x50 ; Dataoffset: 20 bytes (TCP_header.DataOffset) - stosb - mov al, cl - stosb + mov ax, [esi + TCP_SOCKET.LocalPort] + rol ax, 8 + stosw + mov ax, [esi + TCP_SOCKET.RemotePort] + rol ax, 8 + stosw + mov eax, [esi + TCP_SOCKET.SND_NXT] + bswap eax + stosd + mov eax, [esi + TCP_SOCKET.RCV_NXT] + bswap eax + stosd + mov al, 0x50 ; Dataoffset: 20 bytes (TCP_header.DataOffset) + stosb + mov al, cl + stosb ; mov ax, [esi + TCP_SOCKET.RCV_WND] ; rol ax, 8 - mov ax, 0x00a0 ;;;;;;; FIXME - stosw ; window - xor eax, eax - stosd ; checksum + urgentpointer + mov ax, 0x00a0 ;;;;;;; FIXME + stosw ; window + xor eax, eax + stosd ; checksum + urgentpointer ;--------------------- ; Fill in the checksum .checksum: - sub edi, sizeof.TCP_header - mov ecx, sizeof.TCP_header - xchg esi, edi - TCP_checksum (edi + IP_SOCKET.LocalIP), (edi + IP_SOCKET.RemoteIP) - mov [esi+TCP_header.Checksum], dx + sub edi, sizeof.TCP_header + mov ecx, sizeof.TCP_header + xchg esi, edi + TCP_checksum (edi + IP_SOCKET.LocalIP), (edi + IP_SOCKET.RemoteIP) + mov [esi+TCP_header.Checksum], dx ;-------------------- ; And send the segment - call [ebx + NET_DEVICE.transmit] - ret + call [ebx + NET_DEVICE.transmit] + ret .error: - DEBUGF 1,"TCP_respond failed\n" - add esp, 2+4 + DEBUGF 1,"TCP_respond failed\n" + add esp, 2+4 - ret + ret @@ -319,67 +321,67 @@ TCP_respond_socket: align 4 TCP_respond_segment: - DEBUGF 1,"TCP_respond_segment\n" + DEBUGF 1,"TCP_respond_segment\n" ;--------------------- ; Create the IP packet - push cx edx ebx - mov ebx, [edi + 4] - mov eax, [edi] - mov ecx, sizeof.TCP_header - mov di , IP_PROTO_TCP shl 8 + 128 - call IPv4_output - jz .error - pop ebx esi cx + push cx edx ebx + mov ebx, [edi + 4] + mov eax, [edi] + mov ecx, sizeof.TCP_header + mov di , IP_PROTO_TCP shl 8 + 128 + call IPv4_output + jz .error + pop ebx esi cx - push edx eax + push edx eax ;--------------------------------------------------- ; Fill in the TCP header by using a received segment - mov ax, [esi + TCP_header.DestinationPort] - rol ax, 8 - stosw - mov ax, [esi + TCP_header.SourcePort] - rol ax, 8 - stosw - mov eax, [esi + TCP_header.AckNumber] - bswap eax - stosd - xor eax, eax - stosd - mov al, 0x50 ; Dataoffset: 20 bytes (sizeof.TCP_header) - stosb - mov al, cl - stosb - mov ax, 1280 - rol ax, 8 - stosw ; window - xor eax, eax - stosd ; checksum + urgentpointer + mov ax, [esi + TCP_header.DestinationPort] + rol ax, 8 + stosw + mov ax, [esi + TCP_header.SourcePort] + rol ax, 8 + stosw + mov eax, [esi + TCP_header.AckNumber] + bswap eax + stosd + xor eax, eax + stosd + mov al, 0x50 ; Dataoffset: 20 bytes (sizeof.TCP_header) + stosb + mov al, cl + stosb + mov ax, 1280 + rol ax, 8 + stosw ; window + xor eax, eax + stosd ; checksum + urgentpointer ;--------------------- ; Fill in the checksum .checksum: - lea esi, [edi - sizeof.TCP_header] - mov ecx, sizeof.TCP_header - TCP_checksum (esi - sizeof.IPv4_header + IPv4_header.DestinationAddress),\ ; FIXME - (esi - sizeof.IPv4_header + IPv4_header.SourceAddress) - mov [esi+TCP_header.Checksum], dx + lea esi, [edi - sizeof.TCP_header] + mov ecx, sizeof.TCP_header + TCP_checksum (esi - sizeof.IPv4_header + IPv4_header.DestinationAddress),\ ; FIXME + (esi - sizeof.IPv4_header + IPv4_header.SourceAddress) + mov [esi+TCP_header.Checksum], dx ;-------------------- ; And send the segment - call [ebx + NET_DEVICE.transmit] - ret + call [ebx + NET_DEVICE.transmit] + ret .error: - DEBUGF 1,"TCP_respond failed\n" - add esp, 2+4 + DEBUGF 1,"TCP_respond failed\n" + add esp, 2+4 - ret + ret diff --git a/kernel/branches/net/network/udp.inc b/kernel/branches/net/network/udp.inc index 726ede8415..12a799a4f1 100644 --- a/kernel/branches/net/network/udp.inc +++ b/kernel/branches/net/network/udp.inc @@ -118,14 +118,15 @@ UDP_input: DEBUGF 1,"UDP_input, size:%u\n", ecx -; First validate, checksum + ; First validate, checksum neg [esi + UDP_header.Checksum] ; substract checksum from 0 - jz .no_checksum ; if checksum is zero, it is considered valid and we continue processing - ; otherwise, we will re-calculate the checksum and add it to this value, thus creating 0 when it is correct + jz .no_checksum ; if checksum is zero, it is considered valid + + ; otherwise, we will re-calculate the checksum and add it to this value, thus creating 0 when it is correct UDP_checksum (edi), (edi+4) - ;;; jnz .checksum_mismatch + jnz .checksum_mismatch .no_checksum: DEBUGF 1,"UDP Checksum is correct\n" @@ -287,7 +288,7 @@ UDP_output: .fail: DEBUGF 1,"UDP_output: failed\n" add esp, 4+4+8 - xor eax, eax + or eax, -1 ret