diff --git a/kernel/branches/net/network/socket.inc b/kernel/branches/net/network/socket.inc index e11f6b6130..fd7b171e7f 100644 --- a/kernel/branches/net/network/socket.inc +++ b/kernel/branches/net/network/socket.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; Written by hidnplayr@kolibrios.org, ;; @@ -16,172 +16,172 @@ $Revision$ -struct SOCKET +struct SOCKET - NextPtr dd ? ; pointer to next socket in list - PrevPtr dd ? ; pointer to previous socket in list - Number dd ? ; socket number + NextPtr dd ? ; pointer to next socket in list + PrevPtr dd ? ; pointer to previous socket in list + Number dd ? ; socket number - lock dd ? ; lock mutex + lock dd ? ; lock mutex - PID dd ? ; application process id - Domain dd ? ; INET/UNIX/.. - Type dd ? ; RAW/STREAM/DGRAP - Protocol dd ? ; ICMP/IPv4/ARP/TCP/UDP - errorcode dd ? + PID dd ? ; application process id + Domain dd ? ; INET/UNIX/.. + Type dd ? ; RAW/STREAM/DGRAP + Protocol dd ? ; ICMP/IPv4/ARP/TCP/UDP + errorcode dd ? - options dd ? - state dd ? - backlog dw ? ; how many incomming connections that can be queued + options dd ? + state dd ? + backlog dw ? ; how many incomming connections that can be queued - snd_proc dd ? - rcv_proc dd ? + snd_proc dd ? + rcv_proc dd ? ends -struct IP_SOCKET SOCKET +struct IP_SOCKET SOCKET - LocalIP rd 4 - RemoteIP rd 4 + LocalIP rd 4 + RemoteIP rd 4 ends -struct TCP_SOCKET IP_SOCKET +struct TCP_SOCKET IP_SOCKET - LocalPort dw ? - RemotePort dw ? + LocalPort dw ? + RemotePort dw ? - t_state dd ? ; TCB state - t_rxtshift dd ? - t_rxtcur dd ? - t_dupacks dd ? - t_maxseg dd ? - t_force dd ? - t_flags dd ? + t_state dd ? ; TCB state + t_rxtshift dd ? + t_rxtcur dd ? + t_dupacks dd ? + t_maxseg dd ? + t_force dd ? + t_flags dd ? ;--------------- ; RFC783 page 21 ; 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_WL1 dd ? ; window minus one - SND_WL2 dd ? ; - ISS dd ? ; initial send sequence number - SND_WND dd ? ; send window + SND_UNA dd ? ; sequence number of unack'ed sent Packets + SND_NXT dd ? ; next send sequence number to use + SND_UP dd ? + SND_WL1 dd ? ; window minus one + SND_WL2 dd ? ; + ISS dd ? ; initial send sequence number + SND_WND dd ? ; send window ; receive sequence - RCV_WND dw ? ; receive window - RCV_NXT dd ? ; next receive sequence number to use - RCV_UP dd ? - IRS dd ? ; initial receive sequence number + RCV_WND dw ? ; receive window + RCV_NXT dd ? ; next receive sequence number to use + RCV_UP dd ? + IRS dd ? ; initial receive sequence number ;--------------------- ; Additional variables ; receive variables - RCV_ADV dd ? + RCV_ADV dd ? ; retransmit variables - SND_MAX dd ? + SND_MAX dd ? ; congestion control - SND_CWND dd ? - SND_SSTHRESH dd ? + SND_CWND dd ? + SND_SSTHRESH dd ? ;---------------------- ; Transmit timing stuff - t_idle dd ? - t_rtt dd ? - t_rtseq dd ? - t_srtt dd ? - t_rttvar dd ? - t_rttmin dd ? - max_sndwnd dd ? + t_idle dd ? + t_rtt dd ? + t_rtseq dd ? + t_srtt dd ? + t_rttvar dd ? + t_rttmin dd ? + max_sndwnd dd ? ;----------------- ; Out-of-band data - t_oobflags dd ? - t_iobc dd ? - t_softerror dd ? + t_oobflags dd ? + t_iobc dd ? + t_softerror dd ? ;--------- ; RFC 1323 ; the order of next 4 elements may not change - SND_SCALE db ? - RCV_SCALE db ? - requested_s_scale db ? - request_r_scale db ? + SND_SCALE db ? + RCV_SCALE db ? + requested_s_scale db ? + request_r_scale db ? - ts_recent dd ? - ts_recent_age dd ? - last_ack_sent dd ? + ts_recent dd ? + ts_recent_age dd ? + last_ack_sent dd ? ;------- ; Timers - timer_retransmission dw ? ; rexmt - timer_persist dw ? - timer_keepalive dw ? ; keepalive/syn timeout - timer_timed_wait dw ? ; also used as 2msl timer + timer_retransmission dw ? ; rexmt + timer_persist dw ? + timer_keepalive dw ? ; keepalive/syn timeout + timer_timed_wait dw ? ; also used as 2msl timer ends -struct UDP_SOCKET IP_SOCKET +struct UDP_SOCKET IP_SOCKET - LocalPort dw ? - RemotePort dw ? - firstpacket db ? + LocalPort dw ? + RemotePort dw ? + firstpacket db ? ends -struct ICMP_SOCKET IP_SOCKET +struct ICMP_SOCKET IP_SOCKET - Identifier dw ? + Identifier dw ? ends -struct RING_BUFFER +struct RING_BUFFER - start_ptr dd ? ; Pointer to start of buffer - end_ptr dd ? ; pointer to end of buffer - read_ptr dd ? ; Read pointer - write_ptr dd ? ; Write pointer - size dd ? ; Number of bytes buffered + start_ptr dd ? ; Pointer to start of buffer + end_ptr dd ? ; pointer to end of buffer + read_ptr dd ? ; Read pointer + write_ptr dd ? ; Write pointer + size dd ? ; Number of bytes buffered ends -struct STREAM_SOCKET TCP_SOCKET +struct STREAM_SOCKET TCP_SOCKET - rcv rd sizeof.RING_BUFFER/4 - snd rd sizeof.RING_BUFFER/4 + rcv RING_BUFFER + snd RING_BUFFER ends -struct socket_queue_entry +struct socket_queue_entry - data_ptr dd ? - buf_ptr dd ? - data_size dd ? + data_ptr dd ? + buf_ptr dd ? + data_size dd ? ends -SOCKETBUFFSIZE equ 4096 ; in bytes +SOCKETBUFFSIZE equ 4096 ; in bytes -SOCKET_QUEUE_SIZE equ 10 ; maximum number ofincoming packets queued for 1 socket +SOCKET_QUEUE_SIZE equ 10 ; maximum number ofincoming packets queued for 1 socket ; the incoming packet queue for sockets is placed in the socket struct itself, at this location from start -SOCKET_QUEUE_LOCATION equ (SOCKETBUFFSIZE - SOCKET_QUEUE_SIZE*sizeof.socket_queue_entry - sizeof.queue) +SOCKET_QUEUE_LOCATION equ (SOCKETBUFFSIZE - SOCKET_QUEUE_SIZE*sizeof.socket_queue_entry - sizeof.queue) uglobal - net_sockets rd 4 - last_socket_num dd ? - last_UDP_port dw ? ; These values give the number of the last used ephemeral port - last_TCP_port dw ? ; + net_sockets rd 4 + last_socket_num dd ? + last_UDP_port dw ? ; These values give the number of the last used ephemeral port + last_TCP_port dw ? ; endg @@ -190,28 +190,28 @@ endg ; SOCKET_init ; ;----------------------------------------------------------------- -macro SOCKET_init { +macro SOCKET_init { - xor eax, eax - mov edi, net_sockets - mov ecx, 5 - rep stosd + xor eax, eax + mov edi, net_sockets + mov ecx, 5 + rep stosd @@: - pseudo_random eax - cmp ax, MIN_EPHEMERAL_PORT - jb @r - cmp ax, MAX_EPHEMERAL_PORT - ja @r - mov [last_UDP_port], ax + pseudo_random eax + cmp ax, MIN_EPHEMERAL_PORT + jb @r + cmp ax, MAX_EPHEMERAL_PORT + ja @r + mov [last_UDP_port], ax @@: - pseudo_random eax - cmp ax, MIN_EPHEMERAL_PORT - jb @r - cmp ax, MAX_EPHEMERAL_PORT - ja @r - mov [last_TCP_port], ax + pseudo_random eax + cmp ax, MIN_EPHEMERAL_PORT + jb @r + cmp ax, MAX_EPHEMERAL_PORT + ja @r + mov [last_TCP_port], ax } @@ -223,34 +223,34 @@ macro SOCKET_init { ;----------------------------------------------------------------- align 16 sock_sysfn_table: - dd SOCKET_open ; 0 - dd SOCKET_close ; 1 - dd SOCKET_bind ; 2 - dd SOCKET_listen ; 3 - dd SOCKET_connect ; 4 - dd SOCKET_accept ; 5 - dd SOCKET_send ; 6 - dd SOCKET_receive ; 7 - dd SOCKET_set_opt ; 8 - dd SOCKET_get_opt ; 9 + dd SOCKET_open ; 0 + dd SOCKET_close ; 1 + dd SOCKET_bind ; 2 + dd SOCKET_listen ; 3 + dd SOCKET_connect ; 4 + dd SOCKET_accept ; 5 + dd SOCKET_send ; 6 + dd SOCKET_receive ; 7 + dd SOCKET_set_opt ; 8 + dd SOCKET_get_opt ; 9 SOCKET_SYSFUNCS = ($ - sock_sysfn_table)/4 align 4 sys_socket: - cmp ebx, SOCKET_SYSFUNCS-1 - ja @f - jmp dword [sock_sysfn_table + 4*ebx] + cmp ebx, SOCKET_SYSFUNCS-1 + ja @f + jmp dword [sock_sysfn_table + 4*ebx] @@: - cmp ebx, 255 - jz SOCKET_debug + cmp ebx, 255 + jz SOCKET_debug s_error: - DEBUGF 1,"socket error\n" - mov dword [esp+32], -1 + DEBUGF 1,"socket error\n" + mov dword [esp+32], -1 - ret + ret @@ -267,79 +267,79 @@ s_error: align 4 SOCKET_open: - DEBUGF 1,"SOCKET_open: domain: %u, type: %u protocol: %x\n", ecx, edx, esi + DEBUGF 1,"SOCKET_open: domain: %u, type: %u protocol: %x\n", ecx, edx, esi - push ecx edx esi - call SOCKET_alloc - pop esi edx ecx - jz s_error + push ecx edx esi + call SOCKET_alloc + pop esi edx ecx + jz s_error - mov [esp+32], edi ; return socketnumber + mov [esp+32], edi ; return socketnumber - mov [eax + SOCKET.Domain], ecx - mov [eax + SOCKET.Type], edx - mov [eax + SOCKET.Protocol], esi + mov [eax + SOCKET.Domain], ecx + mov [eax + SOCKET.Type], edx + mov [eax + SOCKET.Protocol], esi - cmp ecx, AF_INET4 - jne .no_inet4 + cmp ecx, AF_INET4 + jne .no_inet4 - cmp edx, SOCK_DGRAM - je .udp + cmp edx, SOCK_DGRAM + je .udp - cmp edx, SOCK_STREAM - je .tcp + cmp edx, SOCK_STREAM + je .tcp - cmp edx, SOCK_RAW - je .raw + cmp edx, SOCK_RAW + je .raw .no_inet4: - ret + ret align 4 .raw: - test esi, esi ; IP_PROTO_IP - jz .ip + test esi, esi ; IP_PROTO_IP + jz .ip - cmp esi, IP_PROTO_ICMP - je .icmp + cmp esi, IP_PROTO_ICMP + je .icmp - cmp esi, IP_PROTO_UDP - je .udp + cmp esi, IP_PROTO_UDP + je .udp - cmp esi, IP_PROTO_TCP - je .tcp + cmp esi, IP_PROTO_TCP + je .tcp - ret + ret align 4 .udp: - mov [eax + SOCKET.Protocol], IP_PROTO_UDP - mov [eax + SOCKET.snd_proc], SOCKET_send_udp - mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram - ret + mov [eax + SOCKET.Protocol], IP_PROTO_UDP + mov [eax + SOCKET.snd_proc], SOCKET_send_udp + mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram + ret align 4 .tcp: - mov [eax + SOCKET.Protocol], IP_PROTO_TCP - mov [eax + SOCKET.snd_proc], SOCKET_send_tcp - mov [eax + SOCKET.rcv_proc], SOCKET_receive_tcp + mov [eax + SOCKET.Protocol], IP_PROTO_TCP + mov [eax + SOCKET.snd_proc], SOCKET_send_tcp + mov [eax + SOCKET.rcv_proc], SOCKET_receive_tcp - mov [eax + TCP_SOCKET.t_maxseg], 1480 ;;;;; FIXME - ret + mov [eax + TCP_SOCKET.t_maxseg], 1480 ;;;;; FIXME + ret align 4 .ip: - mov [eax + SOCKET.snd_proc], SOCKET_send_ip - mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram - ret + mov [eax + SOCKET.snd_proc], SOCKET_send_ip + mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram + ret align 4 .icmp: - mov [eax + SOCKET.snd_proc], SOCKET_send_icmp - mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram - ret + mov [eax + SOCKET.snd_proc], SOCKET_send_icmp + mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram + ret @@ -356,47 +356,47 @@ align 4 align 4 SOCKET_bind: - DEBUGF 1,"socket_bind: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi + DEBUGF 1,"socket_bind: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi - call SOCKET_num_to_ptr - jz s_error + call SOCKET_num_to_ptr + jz s_error - cmp esi, 2 - jb s_error + cmp esi, 2 + jb s_error - cmp word [edx], AF_INET4 - je .af_inet4 + cmp word [edx], AF_INET4 + je .af_inet4 - cmp word [edx], AF_UNIX - je .af_unix + cmp word [edx], AF_UNIX + je .af_unix - jmp s_error + jmp s_error .af_unix: - ; TODO: write code here + ; TODO: write code here - mov dword [esp+32], 0 - ret + mov dword [esp+32], 0 + ret .af_inet4: - DEBUGF 1,"af_inet4\n" + DEBUGF 1,"af_inet4\n" - cmp esi, 6 - jb s_error + cmp esi, 6 + jb s_error - pushw [edx + 2] - pop [eax + UDP_SOCKET.LocalPort] + pushw [edx + 2] + pop [eax + UDP_SOCKET.LocalPort] - pushd [edx + 4] - pop [eax + IP_SOCKET.LocalIP] + pushd [edx + 4] + pop [eax + IP_SOCKET.LocalIP] - DEBUGF 1,"local ip: %u.%u.%u.%u\n",\ - [eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\ - [eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1 + DEBUGF 1,"local ip: %u.%u.%u.%u\n",\ + [eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\ + [eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1 - mov dword [esp+32], 0 - ret + mov dword [esp+32], 0 + ret @@ -414,124 +414,124 @@ SOCKET_bind: align 4 SOCKET_connect: - DEBUGF 1,"SOCKET_connect: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi + DEBUGF 1,"SOCKET_connect: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi - call SOCKET_num_to_ptr - jz s_error + call SOCKET_num_to_ptr + jz s_error - cmp esi, 8 - jb s_error + cmp esi, 8 + jb s_error - cmp word [edx], AF_INET4 - je .af_inet4 + cmp word [edx], AF_INET4 + je .af_inet4 - jmp s_error + jmp s_error .af_inet4: - cmp [eax + IP_SOCKET.LocalIP], 0 - jne @f - push [IP_LIST] - pop [eax + IP_SOCKET.LocalIP] + cmp [eax + IP_SOCKET.LocalIP], 0 + jne @f + push [IP_LIST] + pop [eax + IP_SOCKET.LocalIP] @@: - cmp [eax + SOCKET.Protocol], IP_PROTO_UDP - je .udp + cmp [eax + SOCKET.Protocol], IP_PROTO_UDP + je .udp - cmp [eax + SOCKET.Protocol], IP_PROTO_TCP - je .tcp + cmp [eax + SOCKET.Protocol], IP_PROTO_TCP + je .tcp - cmp [eax + SOCKET.Protocol], IP_PROTO_IP - je .ip + cmp [eax + SOCKET.Protocol], IP_PROTO_IP + je .ip - cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP - je .ip + cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP + je .ip - jmp s_error + jmp s_error align 4 .udp: - lea ebx, [eax + SOCKET.lock] - call wait_mutex + lea ebx, [eax + SOCKET.lock] + call wait_mutex - pushw [edx + 2] - pop [eax + UDP_SOCKET.RemotePort] + pushw [edx + 2] + pop [eax + UDP_SOCKET.RemotePort] - pushd [edx + 4] - pop [eax + IP_SOCKET.RemoteIP] + pushd [edx + 4] + pop [eax + IP_SOCKET.RemoteIP] - cmp [eax + UDP_SOCKET.LocalPort], 0 - jne @f - call SOCKET_find_port + cmp [eax + UDP_SOCKET.LocalPort], 0 + jne @f + call SOCKET_find_port @@: - mov [eax + UDP_SOCKET.firstpacket], 0 + mov [eax + UDP_SOCKET.firstpacket], 0 - push eax - init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue - pop eax + push eax + init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue + pop eax - mov [eax + SOCKET.lock], 0 - mov dword [esp+32], 0 - ret + mov [eax + SOCKET.lock], 0 + mov dword [esp+32], 0 + ret align 4 .tcp: - lea ebx, [eax + SOCKET.lock] - call wait_mutex + lea ebx, [eax + SOCKET.lock] + call wait_mutex - pushw [edx + 2] - pop [eax + TCP_SOCKET.RemotePort] + pushw [edx + 2] + pop [eax + TCP_SOCKET.RemotePort] - pushd [edx + 4] - pop [eax + IP_SOCKET.RemoteIP] + pushd [edx + 4] + pop [eax + IP_SOCKET.RemoteIP] - cmp [eax + TCP_SOCKET.LocalPort], 0 - jne @f - call SOCKET_find_port + cmp [eax + TCP_SOCKET.LocalPort], 0 + jne @f + call SOCKET_find_port @@: - mov [eax + TCP_SOCKET.timer_persist], 0 - mov [eax + TCP_SOCKET.t_state], TCPS_SYN_SENT - push [TCP_sequence_num] - add [TCP_sequence_num], 6400 - pop [eax + TCP_SOCKET.ISS] - mov [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init + mov [eax + TCP_SOCKET.timer_persist], 0 + mov [eax + TCP_SOCKET.t_state], TCPS_SYN_SENT + push [TCP_sequence_num] + add [TCP_sequence_num], 6400 + pop [eax + TCP_SOCKET.ISS] + mov [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init - TCP_sendseqinit eax + TCP_sendseqinit eax ; mov [ebx + TCP_SOCKET.timer_retransmission], ;; todo: create macro to set retransmission timer - mov ebx, eax + mov ebx, eax - 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 - mov [ebx + SOCKET.lock], 0 + mov [ebx + SOCKET.lock], 0 - mov eax, ebx - call TCP_output + mov eax, ebx + call TCP_output - mov dword [esp+32], 0 - ret + mov dword [esp+32], 0 + ret align 4 .ip: - lea ebx, [eax + SOCKET.lock] - call wait_mutex + lea ebx, [eax + SOCKET.lock] + call wait_mutex - pushd [edx + 4] - pop [eax + IP_SOCKET.RemoteIP] + pushd [edx + 4] + pop [eax + IP_SOCKET.RemoteIP] - push eax - init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue - pop eax + push eax + init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue + pop eax - mov [eax + SOCKET.lock], 0 - mov dword [esp+32], 0 - ret + mov [eax + SOCKET.lock], 0 + mov dword [esp+32], 0 + ret ;----------------------------------------------------------------- @@ -546,42 +546,42 @@ align 4 align 4 SOCKET_listen: - DEBUGF 1,"SOCKET_listen: socknum: %u backlog: %u\n", ecx, edx + DEBUGF 1,"SOCKET_listen: socknum: %u backlog: %u\n", ecx, edx - call SOCKET_num_to_ptr - jz s_error + call SOCKET_num_to_ptr + jz s_error - cmp [eax + SOCKET.Domain], AF_INET4 - jne s_error + cmp [eax + SOCKET.Domain], AF_INET4 + jne s_error - cmp [eax + SOCKET.Protocol], IP_PROTO_TCP - jne s_error + cmp [eax + SOCKET.Protocol], IP_PROTO_TCP + jne s_error - cmp [eax + TCP_SOCKET.LocalPort], 0 - je s_error + cmp [eax + TCP_SOCKET.LocalPort], 0 + je s_error - cmp [eax + IP_SOCKET.LocalIP], 0 - jne @f - push [IP_LIST] - pop [eax + IP_SOCKET.LocalIP] + cmp [eax + IP_SOCKET.LocalIP], 0 + jne @f + push [IP_LIST] + pop [eax + IP_SOCKET.LocalIP] @@: - cmp edx, MAX_backlog - jbe @f - mov edx, MAX_backlog + cmp edx, MAX_backlog + jbe @f + mov edx, MAX_backlog @@: - mov [eax + SOCKET.backlog], dx - or [eax + SOCKET.options], SO_ACCEPTCON - mov [eax + TCP_SOCKET.t_state], TCPS_LISTEN + mov [eax + SOCKET.backlog], dx + or [eax + SOCKET.options], SO_ACCEPTCON + mov [eax + TCP_SOCKET.t_state], TCPS_LISTEN - push eax - init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up sockets queue - pop eax + push eax + init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up sockets queue + pop eax - mov dword [esp+32], 0 + mov dword [esp+32], 0 - ret + ret ;----------------------------------------------------------------- @@ -597,27 +597,27 @@ SOCKET_listen: align 4 SOCKET_accept: - DEBUGF 1,"SOCKET_accept: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi + DEBUGF 1,"SOCKET_accept: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi - call SOCKET_num_to_ptr - jz s_error + call SOCKET_num_to_ptr + jz s_error - test [eax + SOCKET.options], SO_ACCEPTCON - jz s_error + test [eax + SOCKET.options], SO_ACCEPTCON + jz s_error - cmp [eax + SOCKET.Domain], AF_INET4 - jne s_error + cmp [eax + SOCKET.Domain], AF_INET4 + jne s_error - cmp [eax + SOCKET.Protocol], IP_PROTO_TCP - jne s_error + cmp [eax + SOCKET.Protocol], IP_PROTO_TCP + jne s_error - get_from_queue (eax + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, s_error + get_from_queue (eax + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, s_error - mov eax, [esi] - call SOCKET_ptr_to_num - jz s_error - mov [esp+32], eax - ret + mov eax, [esi] + call SOCKET_ptr_to_num + jz s_error + mov [esp+32], eax + ret ;----------------------------------------------------------------- @@ -631,42 +631,42 @@ SOCKET_accept: align 4 SOCKET_close: - DEBUGF 1,"SOCKET_close: socknum: %u\n", ecx + DEBUGF 1,"SOCKET_close: socknum: %u\n", ecx - call SOCKET_num_to_ptr - jz s_error + call SOCKET_num_to_ptr + jz s_error - cmp [eax + SOCKET.Domain], AF_INET4 - jne s_error + cmp [eax + SOCKET.Domain], AF_INET4 + jne s_error - cmp [eax + SOCKET.Protocol], IP_PROTO_UDP - je .free + cmp [eax + SOCKET.Protocol], IP_PROTO_UDP + je .free - cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP - je .free + cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP + je .free - cmp [eax + SOCKET.Protocol], IP_PROTO_IP - je .free + cmp [eax + SOCKET.Protocol], IP_PROTO_IP + je .free - cmp [eax + SOCKET.Protocol], IP_PROTO_TCP - je .tcp + cmp [eax + SOCKET.Protocol], IP_PROTO_TCP + je .tcp - jmp s_error + jmp s_error .tcp: - cmp [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED ; state must be LISTEN, SYN_SENT or CLOSED - jb .free + cmp [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED ; state must be LISTEN, SYN_SENT or CLOSED + jb .free - call TCP_output - mov dword [esp+32], 0 + call TCP_output + mov dword [esp+32], 0 - ret + ret .free: - call SOCKET_free - mov dword [esp+32], 0 + call SOCKET_free + mov dword [esp+32], 0 - ret + ret ;----------------------------------------------------------------- @@ -683,71 +683,71 @@ SOCKET_close: align 4 SOCKET_receive: - DEBUGF 1,"SOCKET_receive: socknum: %u bufaddr: %x, buflength: %u, flags: %x, ", ecx, edx, esi, edi + DEBUGF 1,"SOCKET_receive: socknum: %u bufaddr: %x, buflength: %u, flags: %x, ", ecx, edx, esi, edi - call SOCKET_num_to_ptr - jz s_error + call SOCKET_num_to_ptr + jz s_error - jmp [eax + SOCKET.rcv_proc] + jmp [eax + SOCKET.rcv_proc] align 4 SOCKET_receive_dgram: - DEBUGF 1,"SOCKET_receive: DGRAM\n" + DEBUGF 1,"SOCKET_receive: DGRAM\n" - mov ebx, esi - mov edi, edx ; addr to buffer + mov ebx, esi + mov edi, edx ; addr to buffer - get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, s_error ; destroys esi and ecx + get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, s_error ; destroys esi and ecx - mov ecx, [esi + socket_queue_entry.data_size] - DEBUGF 1,"Got %u bytes of data\n", ecx + mov ecx, [esi + socket_queue_entry.data_size] + DEBUGF 1,"Got %u bytes of data\n", ecx - cmp ecx, ebx - ja .too_small + cmp ecx, ebx + ja .too_small - push [esi + socket_queue_entry.buf_ptr] ; save the buffer addr so we can clear it later - mov esi, [esi + socket_queue_entry.data_ptr] - DEBUGF 1,"Source buffer: %x, real addr: %x\n", [esp], esi - mov [esp+32+4], ecx ; return number of bytes copied + push [esi + socket_queue_entry.buf_ptr] ; save the buffer addr so we can clear it later + mov esi, [esi + socket_queue_entry.data_ptr] + DEBUGF 1,"Source buffer: %x, real addr: %x\n", [esp], esi + mov [esp+32+4], ecx ; return number of bytes copied ; copy the data - shr ecx, 1 - jnc .nb - movsb + shr ecx, 1 + jnc .nb + movsb .nb: - shr ecx, 1 - jnc .nw - movsw + shr ecx, 1 + jnc .nw + movsw .nw: - test ecx, ecx - jz .nd - rep movsd + test ecx, ecx + jz .nd + rep movsd .nd: - call kernel_free ; remove the packet - ret + call kernel_free ; remove the packet + ret .too_small: - DEBUGF 1,"Buffer too small...\n" - jmp s_error + DEBUGF 1,"Buffer too small...\n" + jmp s_error align 4 SOCKET_receive_tcp: - DEBUGF 1,"SOCKET_receive: TCP\n" + DEBUGF 1,"SOCKET_receive: TCP\n" - mov ecx, esi - mov edi, edx - add eax, STREAM_SOCKET.rcv - call SOCKET_ring_read - call SOCKET_ring_free + mov ecx, esi + mov edi, edx + add eax, STREAM_SOCKET.rcv + call SOCKET_ring_read + call SOCKET_ring_free - mov [esp+32], ecx ; return number of bytes copied + mov [esp+32], ecx ; return number of bytes copied - ret + ret ;----------------------------------------------------------------- @@ -765,63 +765,63 @@ SOCKET_receive_tcp: align 4 SOCKET_send: - DEBUGF 1,"SOCKET_send: socknum: %u data ptr: %x, length: %u, flags: %x, ", ecx, edx, esi, edi + DEBUGF 1,"SOCKET_send: socknum: %u data ptr: %x, length: %u, flags: %x, ", ecx, edx, esi, edi - call SOCKET_num_to_ptr - jz s_error + call SOCKET_num_to_ptr + jz s_error - mov ecx, esi - mov esi, edx + mov ecx, esi + mov esi, edx - jmp [eax + SOCKET.snd_proc] + jmp [eax + SOCKET.snd_proc] align 4 SOCKET_send_udp: - DEBUGF 1,"SOCKET_send: UDP\n" + DEBUGF 1,"SOCKET_send: UDP\n" - call UDP_output + call UDP_output - mov [esp+32], eax - ret + mov [esp+32], eax + ret align 4 SOCKET_send_tcp: - DEBUGF 1,"SOCKET_send: TCP\n" + DEBUGF 1,"SOCKET_send: TCP\n" - push eax - add eax, STREAM_SOCKET.snd - call SOCKET_ring_write - pop eax + push eax + add eax, STREAM_SOCKET.snd + call SOCKET_ring_write + pop eax - call TCP_output + call TCP_output - mov [esp+32], eax - ret + mov [esp+32], eax + ret align 4 SOCKET_send_ip: - DEBUGF 1,"type: IP\n" + DEBUGF 1,"type: IP\n" - call IPv4_output_raw + call IPv4_output_raw - mov [esp+32], eax - ret + mov [esp+32], eax + ret align 4 SOCKET_send_icmp: - DEBUGF 1,"SOCKET_send: ICMP\n" + DEBUGF 1,"SOCKET_send: ICMP\n" - call ICMP_output_raw + call ICMP_output_raw - mov [esp+32], eax - ret + mov [esp+32], eax + ret @@ -843,17 +843,17 @@ SOCKET_send_icmp: align 4 SOCKET_get_opt: - DEBUGF 1,"SOCKET_get_opt\n" + DEBUGF 1,"SOCKET_get_opt\n" - call SOCKET_num_to_ptr - jz s_error + call SOCKET_num_to_ptr + jz s_error - cmp dword [edx], IP_PROTO_TCP - jne s_error - cmp dword [edx+4], -2 - je @f - cmp dword [edx+4], -3 - jne s_error + cmp dword [edx], IP_PROTO_TCP + jne s_error + cmp dword [edx+4], -2 + je @f + cmp dword [edx+4], -3 + jne s_error @@: ; mov eax, [edx+12] ; test eax, eax @@ -870,13 +870,13 @@ SOCKET_get_opt: ; jz @f ; mov ecx, [eax + TCP_SOCKET.state] @@: - mov eax, [edx+8] - test eax, eax - jz @f - mov [eax], ecx + mov eax, [edx+8] + test eax, eax + jz @f + mov [eax], ecx @@: - mov dword [esp+32], 0 - ret + mov dword [esp+32], 0 + ret @@ -884,7 +884,7 @@ SOCKET_get_opt: align 4 SOCKET_set_opt: - ret + ret @@ -902,18 +902,18 @@ SOCKET_set_opt: align 4 SOCKET_debug: - DEBUGF 1,"socket_debug\n" + DEBUGF 1,"socket_debug\n" - call SOCKET_num_to_ptr - jz s_error + call SOCKET_num_to_ptr + jz s_error - mov esi, eax - mov edi, edx - mov ecx, SOCKETBUFFSIZE/4 - rep movsd + mov esi, eax + mov edi, edx + mov ecx, SOCKETBUFFSIZE/4 + rep movsd - mov dword [esp+32], 0 - ret + mov dword [esp+32], 0 + ret ;----------------------------------------------------------------- @@ -931,49 +931,49 @@ SOCKET_debug: align 4 SOCKET_find_port: - DEBUGF 1,"SOCKET_find_port\n" + DEBUGF 1,"SOCKET_find_port\n" - push ebx esi ecx + push ebx esi ecx - cmp [eax + SOCKET.Protocol], IP_PROTO_UDP - je .udp + cmp [eax + SOCKET.Protocol], IP_PROTO_UDP + je .udp - cmp [eax + SOCKET.Protocol], IP_PROTO_TCP - je .tcp + cmp [eax + SOCKET.Protocol], IP_PROTO_TCP + je .tcp - jmp .error + jmp .error .done: - mov [eax + UDP_SOCKET.LocalPort], bx + mov [eax + UDP_SOCKET.LocalPort], bx .error: - pop ecx esi ebx - ret + pop ecx esi ebx + ret .udp: - mov bx, [last_UDP_port] - call .findit - mov [last_UDP_port], bx - jmp .done + mov bx, [last_UDP_port] + call .findit + mov [last_UDP_port], bx + jmp .done .tcp: - mov bx, [last_TCP_port] - call .findit - mov [last_TCP_port], bx - jmp .done + mov bx, [last_TCP_port] + call .findit + mov [last_TCP_port], bx + jmp .done .restart: - mov bx, MIN_EPHEMERAL_PORT + mov bx, MIN_EPHEMERAL_PORT .findit: - inc bx + inc bx - cmp bx, MAX_EPHEMERAL_PORT - jz .restart + cmp bx, MAX_EPHEMERAL_PORT + jz .restart - call SOCKET_check_port - jz .findit + call SOCKET_check_port + jz .findit - ret + ret @@ -993,30 +993,30 @@ SOCKET_find_port: align 4 SOCKET_check_port: - DEBUGF 1,"SOCKET_check_port\n" + DEBUGF 1,"SOCKET_check_port\n" - mov ecx, [eax + SOCKET.Protocol] - mov esi, net_sockets + mov ecx, [eax + SOCKET.Protocol] + mov esi, net_sockets .next_socket: - mov esi, [esi + SOCKET.NextPtr] - or esi, esi - jz .port_ok + mov esi, [esi + SOCKET.NextPtr] + or esi, esi + jz .port_ok - cmp [esi + SOCKET.Protocol], ecx - jne .next_socket + cmp [esi + SOCKET.Protocol], ecx + jne .next_socket - cmp [esi + UDP_SOCKET.LocalPort], bx - jne .next_socket + cmp [esi + UDP_SOCKET.LocalPort], bx + jne .next_socket - DEBUGF 1,"local port %u already in use\n", bx - ret + DEBUGF 1,"local port %u already in use\n", bx + ret .port_ok: - mov [eax + UDP_SOCKET.LocalPort], bx - or bx, bx ; set the zero-flag + mov [eax + UDP_SOCKET.LocalPort], bx + or bx, bx ; set the zero-flag - ret + ret @@ -1041,26 +1041,26 @@ SOCKET_check_port: align 4 SOCKET_input: - DEBUGF 1,"SOCKET_input: socket=%x, data=%x size=%u\n", eax, esi, ecx + DEBUGF 1,"SOCKET_input: socket=%x, data=%x size=%u\n", eax, esi, ecx - mov [esp+4], ecx - push esi - mov esi, esp + mov [esp+4], ecx + push esi + mov esi, esp - add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, SOCKET_input.full + add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, SOCKET_input.full - DEBUGF 1,"SOCKET_input: queued packet successfully\n" - add esp, sizeof.socket_queue_entry - mov [eax + SOCKET.lock], 0 - jmp SOCKET_notify_owner + DEBUGF 1,"SOCKET_input: queued packet successfully\n" + add esp, sizeof.socket_queue_entry + mov [eax + SOCKET.lock], 0 + jmp SOCKET_notify_owner .full: - DEBUGF 2,"SOCKET_input: socket %x is full!\n", eax - mov [eax + SOCKET.lock], 0 - call kernel_free - add esp, 8 + DEBUGF 2,"SOCKET_input: socket %x is full!\n", eax + mov [eax + SOCKET.lock], 0 + call kernel_free + add esp, 8 - ret + ret ;-------------------------- @@ -1070,24 +1070,24 @@ SOCKET_input: align 4 SOCKET_ring_create: - push esi - mov esi, eax + push esi + mov esi, eax - push edx - stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW - pop edx + push edx + stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW + pop edx - DEBUGF 1,"SOCKET_ring_created: %x\n", eax - mov [esi + RING_BUFFER.start_ptr], eax - mov [esi + RING_BUFFER.write_ptr], eax - mov [esi + RING_BUFFER.read_ptr], eax - mov [esi + RING_BUFFER.size], 0 - add eax, SOCKET_MAXDATA - mov [esi + RING_BUFFER.end_ptr], eax - mov eax, esi - pop esi + DEBUGF 1,"SOCKET_ring_created: %x\n", eax + mov [esi + RING_BUFFER.start_ptr], eax + mov [esi + RING_BUFFER.write_ptr], eax + mov [esi + RING_BUFFER.read_ptr], eax + mov [esi + RING_BUFFER.size], 0 + add eax, SOCKET_MAXDATA + mov [esi + RING_BUFFER.end_ptr], eax + mov eax, esi + pop esi - ret + ret ;----------------------------------------------------------------- ; @@ -1105,55 +1105,55 @@ SOCKET_ring_create: align 4 SOCKET_ring_write: - DEBUGF 1,"SOCKET_ring_write: ringbuff=%x ptr=%x size=%u\n", eax, esi, ecx + DEBUGF 1,"SOCKET_ring_write: ringbuff=%x ptr=%x size=%u\n", eax, esi, ecx - add [eax + RING_BUFFER.size], ecx - cmp [eax + RING_BUFFER.size], SOCKET_MAXDATA - ja .too_large + add [eax + RING_BUFFER.size], ecx + cmp [eax + RING_BUFFER.size], SOCKET_MAXDATA + ja .too_large .copy: - mov edi, [eax + RING_BUFFER.write_ptr] - DEBUGF 2,"SOCKET_ring_write: %u bytes from %x to %x\n", ecx, esi, edi + mov edi, [eax + RING_BUFFER.write_ptr] + DEBUGF 2,"SOCKET_ring_write: %u bytes from %x to %x\n", ecx, esi, edi - push ecx - shr ecx, 1 - jnc .nb - movsb + push ecx + shr ecx, 1 + jnc .nb + movsb .nb: - shr ecx, 1 - jnc .nw - movsw + shr ecx, 1 + jnc .nw + movsw .nw: - test ecx, ecx - jz .nd - rep movsd + test ecx, ecx + jz .nd + rep movsd .nd: - pop ecx + pop ecx - cmp edi, [eax + RING_BUFFER.end_ptr] - jae .wrap - mov [eax + RING_BUFFER.write_ptr], edi + cmp edi, [eax + RING_BUFFER.end_ptr] + jae .wrap + mov [eax + RING_BUFFER.write_ptr], edi - ret + ret .wrap: - sub edi, SOCKET_MAXDATA - mov [eax + RING_BUFFER.write_ptr], edi + sub edi, SOCKET_MAXDATA + mov [eax + RING_BUFFER.write_ptr], edi - ret + ret .too_large: - mov ecx, SOCKET_MAXDATA ; calculate number of bytes available in buffer - sub ecx, [eax + RING_BUFFER.size] - jae .full + mov ecx, SOCKET_MAXDATA ; calculate number of bytes available in buffer + sub ecx, [eax + RING_BUFFER.size] + jae .full - mov [eax + RING_BUFFER.size], SOCKET_MAXDATA ; update size, we will fill buffer completely - jmp .copy + mov [eax + RING_BUFFER.size], SOCKET_MAXDATA ; update size, we will fill buffer completely + jmp .copy .full: - DEBUGF 2,"SOCKET_ring_write: ring buffer is full!\n" - xor ecx, ecx - ret + DEBUGF 2,"SOCKET_ring_write: ring buffer is full!\n" + xor ecx, ecx + ret ;----------------------------------------------------------------- @@ -1172,38 +1172,38 @@ SOCKET_ring_write: align 4 SOCKET_ring_read: - DEBUGF 1,"SOCKET_ring_read: ringbuff=%x ptr=%x size=%u\n", eax, edi, ecx + DEBUGF 1,"SOCKET_ring_read: ringbuff=%x ptr=%x size=%u\n", eax, edi, ecx - cmp ecx, [eax + RING_BUFFER.size] - ja .less_data + cmp ecx, [eax + RING_BUFFER.size] + ja .less_data .copy: - mov esi, [eax + RING_BUFFER.read_ptr] + mov esi, [eax + RING_BUFFER.read_ptr] - DEBUGF 2,"SOCKET_ring_read: %u bytes from %x to %x\n", ecx, esi, edi - push ecx - shr ecx, 1 - jnc .nb - movsb + DEBUGF 2,"SOCKET_ring_read: %u bytes from %x to %x\n", ecx, esi, edi + push ecx + shr ecx, 1 + jnc .nb + movsb .nb: - shr ecx, 1 - jnc .nw - movsw + shr ecx, 1 + jnc .nw + movsw .nw: - test ecx, ecx - jz .nd - rep movsd + test ecx, ecx + jz .nd + rep movsd .nd: - pop ecx + pop ecx .no_data_at_all: - ret + ret .less_data: - mov ecx, [eax + RING_BUFFER.size] + mov ecx, [eax + RING_BUFFER.size] ; test ecx, ecx ; jz .no_data_at_all - jmp .copy + jmp .copy ;----------------------------------------------------------------- @@ -1221,23 +1221,23 @@ SOCKET_ring_read: align 4 SOCKET_ring_free: - DEBUGF 1,"SOCKET_ring_free: %u bytes from ring %x\n", ecx, eax + DEBUGF 1,"SOCKET_ring_free: %u bytes from ring %x\n", ecx, eax - sub [eax + RING_BUFFER.size], ecx - jb .sumthinwong - add [eax + RING_BUFFER.read_ptr], ecx + sub [eax + RING_BUFFER.size], ecx + jb .sumthinwong + add [eax + RING_BUFFER.read_ptr], ecx - mov edx, [eax + RING_BUFFER.end_ptr] - cmp [eax + RING_BUFFER.read_ptr], edx - jb @f - sub [eax + RING_BUFFER.read_ptr], SOCKET_MAXDATA + mov edx, [eax + RING_BUFFER.end_ptr] + cmp [eax + RING_BUFFER.read_ptr], edx + jb @f + sub [eax + RING_BUFFER.read_ptr], SOCKET_MAXDATA @@: - ret + ret - .sumthinwong: ; we could free all available bytes, but that would be stupid, i guess.. - add [eax + RING_BUFFER.size], ecx - xor ecx, ecx - ret + .sumthinwong: ; we could free all available bytes, but that would be stupid, i guess.. + add [eax + RING_BUFFER.size], ecx + xor ecx, ecx + ret ;----------------------------------------------------------------- @@ -1253,44 +1253,44 @@ SOCKET_ring_free: align 4 SOCKET_notify_owner: - DEBUGF 1,"SOCKET_notify_owner: %x\n", eax + DEBUGF 1,"SOCKET_notify_owner: %x\n", eax - call SOCKET_check - jz .error + call SOCKET_check + jz .error - push eax ecx esi + push eax ecx esi ; socket exists, now try to flag an event to the application - mov eax, [eax + SOCKET.PID] - mov ecx, 1 - mov esi, TASK_DATA + TASKDATA.pid + mov eax, [eax + SOCKET.PID] + mov ecx, 1 + mov esi, TASK_DATA + TASKDATA.pid .next_pid: - cmp [esi], eax - je .found_pid - inc ecx - add esi, 0x20 - cmp ecx, [TASK_COUNT] - jbe .next_pid + cmp [esi], eax + je .found_pid + inc ecx + add esi, 0x20 + cmp ecx, [TASK_COUNT] + jbe .next_pid ; PID not found, TODO: close socket! - jmp .error2 + jmp .error2 .found_pid: - shl ecx, 8 - or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK - mov [check_idle_semaphore], 200 + shl ecx, 8 + or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK + mov [check_idle_semaphore], 200 - DEBUGF 1,"SOCKET_notify_owner: succes!\n" + DEBUGF 1,"SOCKET_notify_owner: succes!\n" .error2: - pop esi ecx eax + pop esi ecx eax .error: - ret + ret ;-------------------------------------------------------------------- @@ -1310,73 +1310,73 @@ SOCKET_notify_owner: align 4 SOCKET_alloc: - push ebx + push ebx - stdcall kernel_alloc, SOCKETBUFFSIZE - DEBUGF 1, "SOCKET_alloc: ptr=%x\n", eax - or eax, eax - jz .exit + stdcall kernel_alloc, SOCKETBUFFSIZE + DEBUGF 1, "SOCKET_alloc: ptr=%x\n", eax + or eax, eax + jz .exit ; zero-initialize allocated memory - push eax - mov edi, eax - mov ecx, SOCKETBUFFSIZE / 4 - xor eax, eax - rep stosd - pop eax + push eax + mov edi, eax + mov ecx, SOCKETBUFFSIZE / 4 + xor eax, eax + rep stosd + pop eax ; set send-and receive procedures to return -1 - mov [eax + SOCKET.snd_proc], s_error - mov [eax + SOCKET.rcv_proc], s_error + mov [eax + SOCKET.snd_proc], s_error + mov [eax + SOCKET.rcv_proc], s_error ; find first free socket number and use it - mov edi, [last_socket_num] + mov edi, [last_socket_num] .next_socket_number: - inc edi - jz .next_socket_number ; avoid socket nr 0 - cmp edi, -1 - je .next_socket_number ; avoid socket nr -1 - mov ebx, net_sockets + inc edi + jz .next_socket_number ; avoid socket nr 0 + cmp edi, -1 + je .next_socket_number ; avoid socket nr -1 + mov ebx, net_sockets .next_socket: - mov ebx, [ebx + SOCKET.NextPtr] - test ebx, ebx - jz .last_socket + mov ebx, [ebx + SOCKET.NextPtr] + test ebx, ebx + jz .last_socket - cmp [ebx + SOCKET.Number], edi - jne .next_socket - jmp .next_socket_number + cmp [ebx + SOCKET.Number], edi + jne .next_socket + jmp .next_socket_number .last_socket: - mov [last_socket_num], edi - mov [eax + SOCKET.Number], edi - DEBUGF 1, "SOCKET_alloc: number=%u\n", edi + mov [last_socket_num], edi + mov [eax + SOCKET.Number], edi + DEBUGF 1, "SOCKET_alloc: number=%u\n", edi ; Fill in PID - mov ebx, [TASK_BASE] - mov ebx, [ebx + TASKDATA.pid] - mov [eax + SOCKET.PID], ebx + mov ebx, [TASK_BASE] + mov ebx, [ebx + TASKDATA.pid] + mov [eax + SOCKET.PID], ebx ; add socket to the list by re-arranging some pointers - mov ebx, [net_sockets + SOCKET.NextPtr] + mov ebx, [net_sockets + SOCKET.NextPtr] - mov [eax + SOCKET.PrevPtr], net_sockets - mov [eax + SOCKET.NextPtr], ebx + mov [eax + SOCKET.PrevPtr], net_sockets + mov [eax + SOCKET.NextPtr], ebx - test ebx, ebx - jz @f - add ebx, SOCKET.lock ; lock the next socket - call wait_mutex - sub ebx, SOCKET.lock - mov [ebx + SOCKET.PrevPtr], eax - mov [ebx + SOCKET.lock], 0 ; and unlock it again + test ebx, ebx + jz @f + add ebx, SOCKET.lock ; lock the next socket + call wait_mutex + sub ebx, SOCKET.lock + mov [ebx + SOCKET.PrevPtr], eax + mov [ebx + SOCKET.lock], 0 ; and unlock it again @@: - mov [net_sockets + SOCKET.NextPtr], eax - or eax, eax ; used to clear zero flag + mov [net_sockets + SOCKET.NextPtr], eax + or eax, eax ; used to clear zero flag .exit: - pop ebx + pop ebx - ret + ret ;---------------------------------------------------- @@ -1392,52 +1392,52 @@ SOCKET_alloc: align 4 SOCKET_free: - DEBUGF 1, "SOCKET_free: %x\n", eax + DEBUGF 1, "SOCKET_free: %x\n", eax - call SOCKET_check - jz .error + call SOCKET_check + jz .error - push ebx - lea ebx, [eax + SOCKET.lock] - call wait_mutex + push ebx + lea ebx, [eax + SOCKET.lock] + call wait_mutex - DEBUGF 1, "SOCKET_free: freeing socket..\n" + DEBUGF 1, "SOCKET_free: freeing socket..\n" - cmp [eax + SOCKET.Domain], AF_INET4 - jnz .no_tcp + cmp [eax + SOCKET.Domain], AF_INET4 + jnz .no_tcp - cmp [eax + SOCKET.Protocol], IP_PROTO_TCP - jnz .no_tcp + cmp [eax + SOCKET.Protocol], IP_PROTO_TCP + jnz .no_tcp - mov ebx, eax - stdcall kernel_free, [ebx + STREAM_SOCKET.rcv + RING_BUFFER.start_ptr] - stdcall kernel_free, [ebx + STREAM_SOCKET.snd + RING_BUFFER.start_ptr] - mov eax, ebx + mov ebx, eax + stdcall kernel_free, [ebx + STREAM_SOCKET.rcv.start_ptr] + stdcall kernel_free, [ebx + STREAM_SOCKET.snd.start_ptr] + mov eax, ebx .no_tcp: - push eax ; this will be passed to kernel_free - mov ebx, [eax + SOCKET.NextPtr] - mov eax, [eax + SOCKET.PrevPtr] + push eax ; this will be passed to kernel_free + mov ebx, [eax + SOCKET.NextPtr] + mov eax, [eax + SOCKET.PrevPtr] - DEBUGF 1, "SOCKET_free: linking socket %x to socket %x\n", eax, ebx + DEBUGF 1, "SOCKET_free: linking socket %x to socket %x\n", eax, ebx - test eax, eax - jz @f - mov [eax + SOCKET.NextPtr], ebx + test eax, eax + jz @f + mov [eax + SOCKET.NextPtr], ebx @@: - test ebx, ebx - jz @f - mov [ebx + SOCKET.PrevPtr], eax + test ebx, ebx + jz @f + mov [ebx + SOCKET.PrevPtr], eax @@: - call kernel_free - pop ebx + call kernel_free + pop ebx - DEBUGF 1, "SOCKET_free: success!\n" + DEBUGF 1, "SOCKET_free: success!\n" .error: - ret + ret ;------------------------------------ ; @@ -1452,41 +1452,41 @@ SOCKET_free: align 4 SOCKET_fork: - DEBUGF 1,"SOCKET_fork: %x\n", ebx + DEBUGF 1,"SOCKET_fork: %x\n", ebx ; Exit if backlog queue is full - mov eax, [ebx + SOCKET_QUEUE_LOCATION + queue.size] - cmp ax, [ebx + SOCKET.backlog] - jae .fail + mov eax, [ebx + SOCKET_QUEUE_LOCATION + queue.size] + cmp ax, [ebx + SOCKET.backlog] + jae .fail ; Allocate new socket - push ebx - call SOCKET_alloc - pop ebx - jz .fail + push ebx + call SOCKET_alloc + pop ebx + jz .fail - push eax - mov esi, esp - add_to_queue (ebx + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .fail2 - pop eax + push eax + mov esi, esp + add_to_queue (ebx + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .fail2 + pop eax ; Copy structure from current socket to new ; We start at PID to preserve the socket num, and the 2 pointers at beginning of socket - lea esi, [ebx + SOCKET.PID] - lea edi, [eax + SOCKET.PID] - mov ecx, (SOCKET_QUEUE_LOCATION - SOCKET.PID + 3)/4 - rep movsd + lea esi, [ebx + SOCKET.PID] + lea edi, [eax + SOCKET.PID] + mov ecx, (SOCKET_QUEUE_LOCATION - SOCKET.PID + 3)/4 + rep movsd - and [eax + SOCKET.options], not SO_ACCEPTCON + and [eax + SOCKET.options], not SO_ACCEPTCON - ret + ret .fail2: - add esp, 4+4+4 + add esp, 4+4+4 .fail: - DEBUGF 1,"SOCKET_fork: failed\n" - xor eax, eax - ret + DEBUGF 1,"SOCKET_fork: failed\n" + xor eax, eax + ret ;--------------------------------------------------- @@ -1503,22 +1503,22 @@ SOCKET_fork: align 4 SOCKET_num_to_ptr: - DEBUGF 1,"SOCKET_num_to_ptr: %u ", ecx + DEBUGF 1,"SOCKET_num_to_ptr: %u ", ecx - mov eax, net_sockets + mov eax, net_sockets .next_socket: - mov eax, [eax + SOCKET.NextPtr] - or eax, eax - jz .error - cmp [eax + SOCKET.Number], ecx - jne .next_socket + mov eax, [eax + SOCKET.NextPtr] + or eax, eax + jz .error + cmp [eax + SOCKET.Number], ecx + jne .next_socket - test eax, eax + test eax, eax - DEBUGF 1,"(%x)\n", eax + DEBUGF 1,"(%x)\n", eax .error: - ret + ret ;--------------------------------------------------- @@ -1535,17 +1535,17 @@ SOCKET_num_to_ptr: align 4 SOCKET_ptr_to_num: - DEBUGF 1,"SOCKET_ptr_to_num: %x ", eax + DEBUGF 1,"SOCKET_ptr_to_num: %x ", eax - call SOCKET_check - jz .error + call SOCKET_check + jz .error - mov eax, [eax + SOCKET.Number] + mov eax, [eax + SOCKET.Number] - DEBUGF 1,"(%u)\n", eax + DEBUGF 1,"(%u)\n", eax .error: - ret + ret ;--------------------------------------------------- @@ -1562,24 +1562,24 @@ SOCKET_ptr_to_num: align 4 SOCKET_check: - DEBUGF 1,"SOCKET_check: %x\n", eax + DEBUGF 1,"SOCKET_check: %x\n", eax - push ebx - mov ebx, net_sockets + push ebx + mov ebx, net_sockets .next_socket: - mov ebx, [ebx + SOCKET.NextPtr] - or ebx, ebx - jz .done - cmp ebx, eax - jnz .next_socket + mov ebx, [ebx + SOCKET.NextPtr] + or ebx, ebx + jz .done + cmp ebx, eax + jnz .next_socket .done: - mov eax, ebx - test eax, eax - pop ebx + mov eax, ebx + test eax, eax + pop ebx - ret + ret @@ -1596,15 +1596,15 @@ SOCKET_check: align 4 SOCKET_check_owner: - DEBUGF 1,"SOCKET_check_owner: %x\n", eax + DEBUGF 1,"SOCKET_check_owner: %x\n", eax - push ebx - mov ebx, [TASK_BASE] - mov ebx, [ecx + TASKDATA.pid] - cmp [eax + SOCKET.PID], ebx - pop ebx + push ebx + mov ebx, [TASK_BASE] + mov ebx, [ecx + TASKDATA.pid] + cmp [eax + SOCKET.PID], ebx + pop ebx - ret + ret @@ -1624,49 +1624,49 @@ SOCKET_check_owner: align 4 SOCKET_process_end: - DEBUGF 1,"SOCKET_process_end: %x\n", eax + DEBUGF 1,"SOCKET_process_end: %x\n", eax - push ebx - mov ebx, net_sockets + push ebx + mov ebx, net_sockets .next_socket: - mov ebx, [ebx + SOCKET.NextPtr] + mov ebx, [ebx + SOCKET.NextPtr] .test_socket: - test ebx, ebx - jz .done + test ebx, ebx + jz .done - cmp [ebx + SOCKET.PID], eax - jne .next_socket + cmp [ebx + SOCKET.PID], eax + jne .next_socket - DEBUGF 1,"closing socket %x", eax, ebx + DEBUGF 1,"closing socket %x", eax, ebx - mov [ebx + SOCKET.PID], 0 + mov [ebx + SOCKET.PID], 0 - cmp [ebx + SOCKET.Protocol], IP_PROTO_UDP - je .udp + cmp [ebx + SOCKET.Protocol], IP_PROTO_UDP + je .udp - cmp [ebx + SOCKET.Protocol], IP_PROTO_TCP - je .tcp + cmp [ebx + SOCKET.Protocol], IP_PROTO_TCP + je .tcp - jmp .next_socket ; kill all sockets for given PID + jmp .next_socket ; kill all sockets for given PID .udp: - mov eax, ebx - mov ebx, [ebx + SOCKET.NextPtr] - call SOCKET_free - jmp .test_socket + mov eax, ebx + mov ebx, [ebx + SOCKET.NextPtr] + call SOCKET_free + jmp .test_socket .tcp: - ;;; TODO + ;;; TODO - jmp .next_socket + jmp .next_socket .done: - pop ebx + pop ebx - ret + ret @@ -1684,10 +1684,10 @@ align 4 SOCKET_is_connecting: - and [eax + SOCKET.options], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING) - or [eax + SOCKET.options], SS_ISCONNECTING + and [eax + SOCKET.options], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING) + or [eax + SOCKET.options], SS_ISCONNECTING - jmp SOCKET_notify_owner + jmp SOCKET_notify_owner @@ -1704,10 +1704,10 @@ align 4 SOCKET_is_connected: - and [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING) - or [eax + SOCKET.options], SS_ISCONNECTED + and [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING) + or [eax + SOCKET.options], SS_ISCONNECTED - jmp SOCKET_notify_owner + jmp SOCKET_notify_owner @@ -1724,10 +1724,10 @@ SOCKET_is_connected: align 4 SOCKET_is_disconnecting: - and [eax + SOCKET.options], not (SS_ISCONNECTING) - or [eax + SOCKET.options], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE + and [eax + SOCKET.options], not (SS_ISCONNECTING) + or [eax + SOCKET.options], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE - jmp SOCKET_notify_owner + jmp SOCKET_notify_owner @@ -1743,10 +1743,10 @@ SOCKET_is_disconnecting: align 4 SOCKET_is_disconnected: - and [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING) - or [eax + SOCKET.options], SS_CANTRCVMORE + SS_CANTSENDMORE + and [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING) + or [eax + SOCKET.options], SS_CANTRCVMORE + SS_CANTSENDMORE - jmp SOCKET_notify_owner + jmp SOCKET_notify_owner ;----------------------------------------------------------------- @@ -1761,9 +1761,9 @@ SOCKET_is_disconnected: align 4 SOCKET_cant_recv_more: - or [eax + SOCKET.options], SS_CANTRCVMORE + or [eax + SOCKET.options], SS_CANTRCVMORE - ret + ret @@ -1779,6 +1779,6 @@ SOCKET_cant_recv_more: align 4 SOCKET_cant_send_more: - or [eax + SOCKET.options], SS_CANTSENDMORE + or [eax + SOCKET.options], SS_CANTSENDMORE - ret \ No newline at end of file + ret \ No newline at end of file diff --git a/kernel/branches/net/network/tcp.inc b/kernel/branches/net/network/tcp.inc index d788968a8c..50bee5c84b 100644 --- a/kernel/branches/net/network/tcp.inc +++ b/kernel/branches/net/network/tcp.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; Part of the tcp/ip network stack for KolibriOS ;; @@ -93,8 +93,8 @@ ends align 4 uglobal - TCP_headers_tx rd IP_MAX_INTERFACES - TCP_headers_rx rd IP_MAX_INTERFACES + TCP_headers_tx rd IP_MAX_INTERFACES + TCP_headers_rx rd IP_MAX_INTERFACES TCP_bytes_rx rq IP_MAX_INTERFACES TCP_bytes_tx rq IP_MAX_INTERFACES TCP_sequence_num dd ? diff --git a/kernel/branches/net/network/tcp_input.inc b/kernel/branches/net/network/tcp_input.inc index 2d08aa7ce6..bb35e2e207 100644 --- a/kernel/branches/net/network/tcp_input.inc +++ b/kernel/branches/net/network/tcp_input.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; Part of the tcp/ip network stack for KolibriOS ;; @@ -34,66 +34,66 @@ $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 + 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 ;------------------------------- ; 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 - jnz .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" - 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 +102,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 +307,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 +334,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 +362,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 +392,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,11 +430,11 @@ TCP_input: .not_uni_xfer: - DEBUGF 1,"Header prediction failed\n" + DEBUGF 1,"Header prediction failed\n" ; Calculate receive window size -; mov eax, [ebx + STREAM_SOCKET.rcv + RING_BUFFER.size] +; mov eax, [ebx + STREAM_SOCKET.rcv.size] ; neg eax ; add eax, SOCKETBUFFSIZE ; mov edx, [ebx + TCP_SOCKET.RCV_ADV] @@ -444,13 +444,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 +460,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 +521,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 +614,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 +634,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 +659,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 +717,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 +810,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 +871,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 +892,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 +1028,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 +1063,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 +1082,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 +1118,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 +1150,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 +1212,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 +1266,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 +1292,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 + RING_BUFFER.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 +1332,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 +1375,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 +1447,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 +1484,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 +1517,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 +1569,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_output.inc b/kernel/branches/net/network/tcp_output.inc index b07485faf1..1b08d2247c 100644 --- a/kernel/branches/net/network/tcp_output.inc +++ b/kernel/branches/net/network/tcp_output.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; Part of the tcp/ip network stack for KolibriOS ;; @@ -75,7 +75,7 @@ TCP_output: test ecx, ecx jnz .no_zero_window - cmp ebx, [eax + STREAM_SOCKET.snd + RING_BUFFER.size] + cmp ebx, [eax + STREAM_SOCKET.snd.size] jae @f and dl, not (TH_FIN) ; clear the FIN flag ??? how can it be set before? @@ -93,7 +93,7 @@ TCP_output: ;-------------------------------- ; Calculate how much data to send (106) - mov esi, [eax + STREAM_SOCKET.snd + RING_BUFFER.size] + mov esi, [eax + STREAM_SOCKET.snd.size] cmp esi, ecx jb @f mov esi, ecx @@ -146,7 +146,7 @@ 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 + RING_BUFFER.size] + sub edi, [eax + STREAM_SOCKET.snd.size] jns @f and dl, not (TH_FIN) @@ -157,7 +157,7 @@ TCP_output: ; calculate window advertisement (130) mov ecx, SOCKET_MAXDATA - sub ecx, [eax + STREAM_SOCKET.rcv + RING_BUFFER.size] + sub ecx, [eax + STREAM_SOCKET.rcv.size] ;------------------------------ ; Sender silly window avoidance (131) @@ -168,7 +168,13 @@ TCP_output: cmp esi, [eax + TCP_SOCKET.t_maxseg] je .send -;;; if (idle or TF_NODELAY) && (esi + ebx >= so_snd.sb_cc), send + test [eax + TCP_SOCKET.t_flags], TF_NODELAY + jnz @f + ; TODO: if not 'idle', skip to next codeblock + @@: + add ebx, esi + cmp ebx, [eax + STREAM_SOCKET.snd.size] + jae .send test [eax + TCP_SOCKET.t_force], -1 ;;; jnz .send @@ -190,7 +196,23 @@ TCP_output: test ecx, ecx jz .no_window -;;; TODO 167-172 + push ecx + mov cl, [eax + TCP_SOCKET.RCV_SCALE] + inc cl ; we want it *2 + mov ebx, TCP_max_win + shl ebx, cl + pop ecx + cmp ebx, ecx + cmovb ebx, ecx + + ; now ebx is TWICE the amount we can increase the window + ; (with TCP_max_win shl rcv_scale as the maximum) + + cmp ebx, [eax + TCP_SOCKET.t_maxseg] + jae .send + + ;;; cmp ebx, [eax + ] ;;; TODO: check receive buffer high water mark + ;;; jae .send .no_window: @@ -224,10 +246,18 @@ TCP_output: .enter_persist: + cmp [eax + STREAM_SOCKET.snd.size], 0 ; Data ready to send? + jne @f + cmp [eax + TCP_SOCKET.timer_retransmission], 0 + jne @f + cmp [eax + TCP_SOCKET.timer_persist], 0 ; Persist timer already expired? + jne @f + DEBUGF 1,"Entering persist state\n" - -;;; 213 - 217 + mov [eax + TCP_SOCKET.t_rxtshift], 0 + TCP_set_persist eax + @@: ;---------------------------- ; No reason to send a segment (219) @@ -260,7 +290,7 @@ TCP_output: DEBUGF 1,"Preparing to send a segment\n" - mov edi, sizeof.TCP_header ; edi will contain headersize + mov edi, sizeof.TCP_header ; edi will contain headersize sub esp, 8 ; create some space on stack push eax ; save socket pointer @@ -463,9 +493,11 @@ TCP_output: mov edx, [eax + TCP_SOCKET.t_rxtcur] mov [eax + TCP_SOCKET.timer_retransmission], dx + cmp [eax + TCP_SOCKET.timer_persist], 0 + jne @f mov [eax + TCP_SOCKET.timer_persist], 0 - mov [eax + TCP_SOCKET.t_rxtshift], 0 ;;; TODO: only do this if timer_persist was set - + mov [eax + TCP_SOCKET.t_rxtshift], 0 + @@: .retransmit_set: diff --git a/kernel/branches/net/network/tcp_subr.inc b/kernel/branches/net/network/tcp_subr.inc index 6327f509cd..b7e5931133 100644 --- a/kernel/branches/net/network/tcp_subr.inc +++ b/kernel/branches/net/network/tcp_subr.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; Part of the tcp/ip network stack for KolibriOS ;; @@ -16,65 +16,65 @@ $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 ;--------------------- ; 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 +102,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 +128,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 +147,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 +167,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 +198,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 +237,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,64 +319,86 @@ 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 \ No newline at end of file + ret + + + +macro TCP_set_persist socket { + +;int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1; +;int tt; +; +;tp->t_flags &= ~TF_PREVVALID; +; +;if (tcp_timer_active(tp, TT_REXMT)) +; panic("tcp_setpersist: retransmit pending"); +; +;; Start/restart persistance timer. +; +;TCPT_RANGESET(tt, t * tcp_backoff[tp->t_rxtshift], TCPTV_PERSMIN, TCPTV_PERSMAX); +;tcp_timer_activate(tp, TT_PERSIST, tt); +; +;if (tp->t_rxtshift < TCP_MAXRXTSHIFT) +; tp->t_rxtshift++; + +} \ No newline at end of file