Updated SOCKET_listen and SOCKET_accept so they can actually work now.

Changed SOCKET_alloc so that it returns better socket numbers.

git-svn-id: svn://kolibrios.org@1543 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2010-07-31 19:44:17 +00:00
parent 445f854cae
commit 5b0ea56111
4 changed files with 220 additions and 185 deletions

View File

@ -24,7 +24,7 @@ $Revision$
struct queue struct queue
.size dd ? ; number of queued packets in thsi queue .size dd ? ; number of queued packets in this queue
.w_ptr dd ? ; current writing pointer in queue .w_ptr dd ? ; current writing pointer in queue
.r_ptr dd ? ; current reading pointer .r_ptr dd ? ; current reading pointer
.data: .data:

View File

@ -28,12 +28,13 @@ virtual at 0
.PID dd ? ; application process id .PID dd ? ; application process id
.Domain dd ? ; INET/UNIX/.. .Domain dd ? ; INET/UNIX/..
.Type dd ? ; RAW/UDP/TCP/... .Type dd ? ; RAW/STREAM/DGRAP
.Protocol dd ? ; ICMP/IPv4/ARP/ .Protocol dd ? ; ICMP/IPv4/ARP/TCP/UDP
.errorcode dd ? ; .errorcode dd ?
.options dd ? .options dd ?
.state dd ? .state dd ?
.backlog dw ? ; how many incomming connections that can be queued
.snd_proc dd ? .snd_proc dd ?
.rcv_proc dd ? .rcv_proc dd ?
@ -61,9 +62,6 @@ virtual at IP_SOCKET.end
.LocalPort dw ? .LocalPort dw ?
.RemotePort dw ? .RemotePort dw ?
.backlog dw ? ; Backlog
.backlog_cur dw ? ; current size of queue for un-accept-ed connections
.OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state) .OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state)
.OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state) .OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state)
@ -190,7 +188,6 @@ virtual at TCP_SOCKET.end
end virtual end virtual
struct socket_queue_entry struct socket_queue_entry
.data_ptr dd ? .data_ptr dd ?
.buf_ptr dd ? .buf_ptr dd ?
@ -203,10 +200,11 @@ 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 ; 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*socket_queue_entry.size - queue.data SOCKET_QUEUE_LOCATION equ (SOCKETBUFFSIZE - SOCKET_QUEUE_SIZE*socket_queue_entry.size - queue.data)
uglobal uglobal
net_sockets rd 4 net_sockets rd 4
last_socket_num dd ?
last_UDP_port dw ? ; These values give the number of the last used ephemeral port last_UDP_port dw ? ; These values give the number of the last used ephemeral port
last_TCP_port dw ? ; last_TCP_port dw ? ;
endg endg
@ -221,7 +219,7 @@ macro SOCKET_init {
xor eax, eax xor eax, eax
mov edi, net_sockets mov edi, net_sockets
mov ecx, 4 mov ecx, 5
rep stosd rep stosd
@@: @@:
@ -303,9 +301,6 @@ SOCKET_open:
cmp ecx, AF_INET4 cmp ecx, AF_INET4
jne .no_inet4 jne .no_inet4
push [IP_LIST]
pop [eax + IP_SOCKET.LocalIP] ; fill in local ip number
cmp edx, SOCK_DGRAM cmp edx, SOCK_DGRAM
je .udp je .udp
@ -320,8 +315,8 @@ SOCKET_open:
align 4 align 4
.raw: .raw:
; test esi, esi ; IP_PROTO_IP test esi, esi ; IP_PROTO_IP
; jz .ip jz .ip
cmp esi, IP_PROTO_ICMP cmp esi, IP_PROTO_ICMP
je .icmp je .icmp
@ -337,61 +332,29 @@ align 4
align 4 align 4
.udp: .udp:
mov [eax + SOCKET.Protocol], IP_PROTO_UDP mov [eax + SOCKET.Protocol], IP_PROTO_UDP
call SOCKET_find_port ; fill in a local port number, application may change it later, or use this one
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION)
pop eax
mov [eax + SOCKET.snd_proc], SOCKET_send_udp mov [eax + SOCKET.snd_proc], SOCKET_send_udp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
ret ret
align 4 align 4
.tcp: .tcp:
mov [eax + SOCKET.Protocol], IP_PROTO_TCP mov [eax + SOCKET.Protocol], IP_PROTO_TCP
mov [eax + SOCKET.snd_proc], SOCKET_send_tcp
call SOCKET_find_port ; fill in a local port number, application may change it later, or use this one mov [eax + SOCKET.rcv_proc], SOCKET_receive_tcp
mov ebx, eax
lea eax, [ebx + STREAM_SOCKET.snd]
call SOCKET_ring_create
lea eax, [ebx + STREAM_SOCKET.rcv]
call SOCKET_ring_create
mov [ebx + SOCKET.snd_proc], SOCKET_send_tcp
mov [ebx + SOCKET.rcv_proc], SOCKET_receive_tcp
ret ret
;align 4 align 4
; .ip: .ip:
; mov [eax + SOCKET.snd_proc], SOCKET_send_ip
; push eax mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
; init_queue (eax + SOCKET_QUEUE_LOCATION) ret
; pop eax
;
; mov [eax + SOCKET.snd_proc], SOCKET_send_ip
; mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
;
; ret
align 4 align 4
.icmp: .icmp:
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION)
pop eax
mov [eax + SOCKET.snd_proc], SOCKET_send_icmp mov [eax + SOCKET.snd_proc], SOCKET_send_icmp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
ret ret
@ -426,7 +389,6 @@ SOCKET_bind:
jmp s_error jmp s_error
.af_unix: .af_unix:
; TODO: write code here ; TODO: write code here
mov dword [esp+32], 0 mov dword [esp+32], 0
@ -439,17 +401,11 @@ SOCKET_bind:
cmp esi, 6 cmp esi, 6
jl s_error jl s_error
mov bx, word [edx + 2] push word [edx + 2]
test bx, bx pop word [eax + UDP_SOCKET.LocalPort]
jz .use_preset_port
call SOCKET_check_port push dword [edx + 4]
jz s_error pop [eax + IP_SOCKET.LocalIP]
DEBUGF 1,"using local port: %u\n", bx
mov word [eax + UDP_SOCKET.LocalPort], bx
.use_preset_port:
DEBUGF 1,"local ip: %u.%u.%u.%u\n",\ 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 + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\
@ -488,6 +444,11 @@ SOCKET_connect:
jmp s_error jmp s_error
.af_inet4: .af_inet4:
cmp [eax + IP_SOCKET.LocalIP], 0
jne @f
push [IP_LIST]
pop [eax + IP_SOCKET.LocalIP]
@@:
cmp [eax + SOCKET.Protocol], IP_PROTO_UDP cmp [eax + SOCKET.Protocol], IP_PROTO_UDP
je .udp je .udp
@ -505,15 +466,27 @@ SOCKET_connect:
align 4 align 4
.udp: .udp:
mov bx , word [edx + 2] lea ebx, [eax + SOCKET.lock]
mov word [eax + UDP_SOCKET.RemotePort], bx call wait_mutex
push word [edx + 2]
pop [eax + UDP_SOCKET.RemotePort]
push dword [edx + 4]
pop [eax + IP_SOCKET.RemoteIP]
cmp [eax + UDP_SOCKET.LocalPort], 0
jne @f
call SOCKET_find_port
@@:
mov [eax + UDP_SOCKET.firstpacket], 0 mov [eax + UDP_SOCKET.firstpacket], 0
DEBUGF 1,"remote port: %u\n",bx
mov ebx, dword [edx + 4] push eax
mov dword [eax + IP_SOCKET.RemoteIP], ebx init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
DEBUGF 1,"remote ip: %u.%u.%u.%u\n",[edx+4]:1,[edx+5]:1,[edx+6]:1,[edx+7]:1 pop eax
mov [eax + SOCKET.lock], 0
mov dword [esp+32], 0 mov dword [esp+32], 0
ret ret
@ -522,16 +495,17 @@ align 4
lea ebx, [eax + SOCKET.lock] lea ebx, [eax + SOCKET.lock]
call wait_mutex call wait_mutex
; fill in remote port and IP push word [edx + 2]
pop [eax + TCP_SOCKET.RemotePort]
mov bx , word [edx + 2] push dword [edx + 4]
mov [eax + TCP_SOCKET.RemotePort], bx pop [eax + IP_SOCKET.RemoteIP]
DEBUGF 1,"remote port: %u\n", bx
mov ebx, dword [edx + 4] cmp [eax + TCP_SOCKET.LocalPort], 0
mov [eax + IP_SOCKET.RemoteIP], ebx jne @f
call SOCKET_find_port
@@:
;;;;;
mov [eax + TCP_SOCKET.timer_persist], 0 mov [eax + TCP_SOCKET.timer_persist], 0
mov [eax + TCP_SOCKET.t_state], TCB_SYN_SENT mov [eax + TCP_SOCKET.t_state], TCB_SYN_SENT
mov ebx, [TCP_sequence_num] mov ebx, [TCP_sequence_num]
@ -541,23 +515,38 @@ align 4
TCP_sendseqinit eax TCP_sendseqinit eax
;;;; mov [ebx + TCP_SOCKET.timer_retransmission], ;; todo: create macro to set retransmission timer ; mov [ebx + TCP_SOCKET.timer_retransmission], ;; todo: create macro to set retransmission timer
push eax push eax
call TCP_output call TCP_output
pop eax pop eax
mov [eax + SOCKET.lock], 0 mov ebx, eax
mov dword [esp+32], 0 ; success! lea eax, [ebx + STREAM_SOCKET.snd]
call SOCKET_ring_create
lea eax, [ebx + STREAM_SOCKET.rcv]
call SOCKET_ring_create
mov [ebx + SOCKET.lock], 0
mov dword [esp+32], 0
ret ret
align 4 align 4
.ip: .ip:
lea ebx, [eax + SOCKET.lock]
call wait_mutex
push dword [edx + 4] push dword [edx + 4]
pop dword [eax + IP_SOCKET.RemoteIP] pop dword [eax + IP_SOCKET.RemoteIP]
mov dword [esp+32], 0 ; success! 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 ret
@ -584,16 +573,27 @@ SOCKET_listen:
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
jne s_error jne s_error
; TODO: check local port number 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 edx, MAX_backlog cmp edx, MAX_backlog
jle .ok jle @f
mov edx, MAX_backlog mov edx, MAX_backlog
.ok: @@:
mov [eax + TCP_SOCKET.backlog], dx mov [eax + SOCKET.backlog], dx
or [eax + SOCKET.options], SO_ACCEPTCON
mov [eax + TCP_SOCKET.t_state], TCB_LISTEN mov [eax + TCP_SOCKET.t_state], TCB_LISTEN
or [eax + SOCKET.options], SO_ACCEPTCON ;;;; TODO: set socket state to listen
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up sockets queue
pop eax
mov dword [esp+32], 0 mov dword [esp+32], 0
@ -618,40 +618,23 @@ SOCKET_accept:
call SOCKET_num_to_ptr call SOCKET_num_to_ptr
jz s_error jz s_error
test [eax + SOCKET.options], SO_ACCEPTCON
jz s_error
cmp word [eax + SOCKET.Domain], AF_INET4 cmp word [eax + SOCKET.Domain], AF_INET4
je .af_inet4 jne s_error
jmp s_error
.af_inet4:
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
je .tcp jne s_error
jmp s_error get_from_queue (eax + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, s_error
.tcp:
lea ebx, [eax + SOCKET.lock]
call wait_mutex
movzx ebx, [eax + TCP_SOCKET.backlog_cur]
test ebx, ebx
jz .unlock_err
dec [eax + TCP_SOCKET.backlog_cur] ;;;;
mov eax, [eax + TCP_SOCKET.end + (ebx-1)*4] ;;;;;
mov [eax + SOCKET.lock], 0 ;;;;
mov dword [esp+32], 0 ;;;;
call TCP_output ;;;;;
mov eax, [esi]
call SOCKET_ptr_to_num
jz s_error
mov dword [esp+32], eax
ret ret
.unlock_err:
mov [eax + SOCKET.lock], 0
jmp s_error
;----------------------------------------------------------------- ;-----------------------------------------------------------------
; ;
@ -838,18 +821,18 @@ SOCKET_send_tcp:
ret ret
;align 4 align 4
;SOCKET_send_ip: SOCKET_send_ip:
;
; DEBUGF 1,"type: IP\n" DEBUGF 1,"type: IP\n"
;
; mov ecx, esi mov ecx, esi
; mov esi, edx mov esi, edx
;
; call IPv4_output_raw call IPv4_output_raw
;
; mov dword [esp+32], eax mov dword [esp+32], eax
; ret ret
align 4 align 4
SOCKET_send_icmp: SOCKET_send_icmp:
@ -1109,8 +1092,12 @@ SOCKET_input:
align 4 align 4
SOCKET_ring_create: SOCKET_ring_create:
push esi
mov esi, eax mov esi, eax
push edx
stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW
pop edx
DEBUGF 1,"SOCKET_ring_created: %x\n", eax DEBUGF 1,"SOCKET_ring_created: %x\n", eax
mov [esi + RING_BUFFER.start_ptr], eax mov [esi + RING_BUFFER.start_ptr], eax
@ -1119,6 +1106,8 @@ SOCKET_ring_create:
mov [esi + RING_BUFFER.size], 0 mov [esi + RING_BUFFER.size], 0
add eax, SOCKET_MAXDATA add eax, SOCKET_MAXDATA
mov [esi + RING_BUFFER.end_ptr], eax mov [esi + RING_BUFFER.end_ptr], eax
mov eax, esi
pop esi
ret ret
@ -1291,7 +1280,7 @@ SOCKET_notify_owner:
call SOCKET_check call SOCKET_check
jz .error jz .error
push ecx esi push eax ecx esi
; socket exists, now try to flag an event to the application ; socket exists, now try to flag an event to the application
@ -1319,7 +1308,7 @@ SOCKET_notify_owner:
DEBUGF 1,"SOCKET_notify_owner: succes!\n" DEBUGF 1,"SOCKET_notify_owner: succes!\n"
.error2: .error2:
pop esi ecx pop esi ecx eax
.error: .error:
@ -1363,9 +1352,12 @@ SOCKET_alloc:
mov [eax + SOCKET.rcv_proc], s_error mov [eax + SOCKET.rcv_proc], s_error
; find first free socket number and use it ; find first free socket number and use it
xor ecx, ecx mov ecx, [last_socket_num]
.next_socket_number: .next_socket_number:
inc ecx inc ecx
jz .next_socket_number ; avoid socket nr 0
cmp ecx, -1
je .next_socket_number ; avoid socket nr -1
mov ebx, net_sockets mov ebx, net_sockets
.next_socket: .next_socket:
mov ebx, [ebx + SOCKET.NextPtr] mov ebx, [ebx + SOCKET.NextPtr]
@ -1377,6 +1369,7 @@ SOCKET_alloc:
jmp .next_socket_number jmp .next_socket_number
.last_socket: .last_socket:
mov [last_socket_num], ecx
mov [eax + SOCKET.Number], ecx mov [eax + SOCKET.Number], ecx
DEBUGF 1, "SOCKET_alloc: number=%u\n", ecx DEBUGF 1, "SOCKET_alloc: number=%u\n", ecx
mov edi, ecx mov edi, ecx
@ -1469,39 +1462,57 @@ SOCKET_free:
.error: .error:
ret ret
;------------------------------------
;
; SOCKET_fork
;
; Create a child socket
;
; IN: socket nr in ebx ; IN: socket nr in ebx
; OUT: socket nr in eax ; OUT: child socket nr in eax
; preserves edx ;
;-----------------------------------
align 4 align 4
SOCKET_fork: SOCKET_fork:
;; Exit if backlog queue is full DEBUGF 1,"SOCKET_fork: %x\n", ebx
; mov ax, [ebx + TCP_SOCKET.backlog_cur]
; cmp ax, [ebx + TCP_SOCKET.backlog] ; Exit if backlog queue is full
; jae .exit mov eax, [ebx + SOCKET_QUEUE_LOCATION + queue.size]
cmp ax, [ebx + SOCKET.backlog]
jge .fail
; Allocate new socket ; Allocate new socket
call SOCKET_alloc call SOCKET_alloc
;;; jz .fail jz .fail
; Copy structure from current socket to new, (including lock!) push esi ecx edi
; We start at PID to reserve the socket num, and the 2 pointers at beginning of socket push eax
lea esi, [edx + SOCKET.PID] 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] lea edi, [eax + SOCKET.PID]
mov ecx, (TCP_SOCKET.end - SOCKET.PID + 3)/4 mov ecx, (SOCKET_QUEUE_LOCATION - SOCKET.PID + 3)/4
rep movsd rep movsd
;; Push pointer to new socket to queue and [eax + SOCKET.options], not SO_ACCEPTCON
; movzx ecx, [ebx + TCP_SOCKET.backlog_cur]
; inc [ebx + TCP_SOCKET.backlog_cur]
; mov [ebx + TCP_SOCKET.end + ecx*4], eax
;;;; mov [eax + IP_SOCKET.RemoteIP], esi ; IP source address call SOCKET_notify_owner
pop edi ecx esi
ret ret
.fail2:
add esp, 4+4+4
.fail:
DEBUGF 1,"SOCKET_fork: failed\n"
xor eax, eax
ret
;--------------------------------------------------- ;---------------------------------------------------
; ;

View File

@ -74,7 +74,7 @@ SOCKET_MAXDATA equ 4096*32 ; must be 4096*(power of 2) where 'power of 2' is at
NET_TYPE_ETH equ 1 NET_TYPE_ETH equ 1
NET_TYPE_SLIP equ 2 NET_TYPE_SLIP equ 2
MAX_backlog equ 20 ; backlog for stream sockets MAX_backlog equ 20 ; maximum backlog for stream sockets
virtual at 0 virtual at 0
@ -112,7 +112,7 @@ macro pseudo_random reg {
rol reg, 9 rol reg, 9
} }
macro ntohld reg { macro ntohd reg {
rol word reg, 8 rol word reg, 8
rol dword reg, 16 rol dword reg, 16
@ -120,7 +120,7 @@ macro ntohld reg {
} }
macro ntohlw reg { macro ntohw reg {
rol word reg, 8 rol word reg, 8

View File

@ -356,13 +356,13 @@ TCP_input:
;------------------------------------------- ;-------------------------------------------
; Convert Big-endian values to little endian ; Convert Big-endian values to little endian
ntohld [edx + TCP_segment.SequenceNumber] ntohd [edx + TCP_segment.SequenceNumber]
ntohld [edx + TCP_segment.AckNumber] ntohd [edx + TCP_segment.AckNumber]
ntohlw [edx + TCP_segment.Window] ntohw [edx + TCP_segment.Window]
ntohlw [edx + TCP_segment.UrgentPointer] ntohw [edx + TCP_segment.UrgentPointer]
ntohlw [edx + TCP_segment.SourcePort] ntohw [edx + TCP_segment.SourcePort]
ntohlw [edx + TCP_segment.DestinationPort] ntohw [edx + TCP_segment.DestinationPort]
;------------------------------------------------------------ ;------------------------------------------------------------
; Next thing to do is find the TCB (thus, the socket pointer) ; Next thing to do is find the TCB (thus, the socket pointer)
@ -378,7 +378,10 @@ TCP_input:
or ebx, ebx or ebx, ebx
jz .drop_with_reset jz .drop_with_reset
cmp [ebx + SOCKET.Protocol], IP_PROTO_TCP ;;; We should also check if family is AF_INET cmp [ebx + SOCKET.Domain], AF_INET4
jne .socket_loop
cmp [ebx + SOCKET.Protocol], IP_PROTO_TCP
jne .socket_loop jne .socket_loop
mov ax, [edx + TCP_segment.DestinationPort] mov ax, [edx + TCP_segment.DestinationPort]
@ -386,7 +389,7 @@ TCP_input:
jne .socket_loop jne .socket_loop
mov eax, [ebx + IP_SOCKET.RemoteIP] mov eax, [ebx + IP_SOCKET.RemoteIP]
cmp eax, edi ; sender IP cmp eax, edi ; edi is source ip from packet
je @f je @f
test eax, eax test eax, eax
jnz .socket_loop jnz .socket_loop
@ -417,22 +420,39 @@ TCP_input:
DEBUGF 1,"Socket locked\n" DEBUGF 1,"Socket locked\n"
;---------------------------------------------------------------------------------------- ;---------------------------------------
; unscale the window into a 32 bit value (notice that SND_SCALE must be initialised to 0) ; unscale the window into a 32 bit value
movzx eax, [edx + TCP_segment.Window] movzx eax, [edx + TCP_segment.Window]
push ecx push ecx
mov cl, [ebx + TCP_SOCKET.SND_SCALE] mov cl, [ebx + TCP_SOCKET.SND_SCALE]
shl eax, cl shl eax, cl
mov dword [edx + TCP_segment.Window], eax ; word after window is checksum, we dont need checksum anymore
pop ecx pop ecx
;;;; do something with eax
;----------------------------------- ;-----------------------------------
; Is this socket a listening socket? ; Is this socket a listening socket?
test [ebx + SOCKET.options], SO_ACCEPTCON test [ebx + SOCKET.options], SO_ACCEPTCON
; jnz .listening_socket ;;;;; TODO jz .no_listening_socket
call SOCKET_fork
jz .drop
push [edx + TCP_segment.DestinationPort]
pop [eax + TCP_SOCKET.LocalPort]
push [edx - IPv4_Packet.DataOrOptional + IPv4_Packet.DestinationAddress] ;;; FIXME
pop [eax + IP_SOCKET.LocalIP]
push [edx - IPv4_Packet.DataOrOptional + IPv4_Packet.SourceAddress] ;;; FIXME
pop [eax + IP_SOCKET.RemoteIP]
mov [eax + TCP_SOCKET.t_state], TCB_LISTEN
jmp .not_uni_xfer
.no_listening_socket:
;------------------------------------- ;-------------------------------------
; Reset idle timer and keepalive timer ; Reset idle timer and keepalive timer
@ -449,7 +469,7 @@ TCP_input:
DEBUGF 1,"Segment has options\n" DEBUGF 1,"Segment has options\n"
cmp [ebx + TCP_SOCKET.t_state], TCB_LISTEN ; no options when in listen state cmp [ebx + TCP_SOCKET.t_state], TCB_LISTEN ; no options when in listen state
jz .no_options jz .not_uni_xfer ; also no header prediction
lea edi, [edx + TCP_segment.Data] lea edi, [edx + TCP_segment.Data]
lea eax, [edx + esi] lea eax, [edx + esi]
@ -553,7 +573,7 @@ TCP_input:
cmp eax, [ebx + TCP_SOCKET.RCV_NXT] cmp eax, [ebx + TCP_SOCKET.RCV_NXT]
jne .not_uni_xfer jne .not_uni_xfer
movzx eax, [edx + TCP_segment.Window] ;;;;; (should use pre-calculated value instead: todo: figure out where to store it) mov eax, dword [edx + TCP_segment.Window]
cmp eax, [ebx + TCP_SOCKET.SND_WND] cmp eax, [ebx + TCP_SOCKET.SND_WND]
jne .not_uni_xfer jne .not_uni_xfer
@ -687,7 +707,7 @@ align 4
DEBUGF 1,"TCP state: listen\n" DEBUGF 1,"TCP state: listen\n"
test [edx + TCP_segment.Flags], TH_RST test [edx + TCP_segment.Flags], TH_RST ;;; TODO: kill new socket on error
jnz .drop jnz .drop
test [edx + TCP_segment.Flags], TH_ACK test [edx + TCP_segment.Flags], TH_ACK
@ -696,14 +716,9 @@ align 4
test [edx + TCP_segment.Flags], TH_SYN test [edx + TCP_segment.Flags], TH_SYN
jz .drop jz .drop
cmp esi, 0xffffff ; destination ip = 255.255.255.255 ?
jz .drop
; TODO: check if it's a broadcast or multicast, and drop if so ; TODO: check if it's a broadcast or multicast, and drop if so
call SOCKET_fork
jz .drop ; if we could not open a new connection, drop segment (;;;; should we send RST too?)
;----------------------- ;-----------------------
; Fill in some variables ; Fill in some variables
@ -718,11 +733,23 @@ align 4
push [eax + TCP_SOCKET.ISS] push [eax + TCP_SOCKET.ISS]
pop [eax + TCP_SOCKET.SND_NXT] pop [eax + TCP_SOCKET.SND_NXT]
TCP_sendseqinit eax
TCP_rcvseqinit eax
mov [eax + TCP_SOCKET.t_state], TCB_SYN_RECEIVED mov [eax + TCP_SOCKET.t_state], TCB_SYN_RECEIVED
mov [eax + TCP_SOCKET.t_flags], TF_ACKNOW mov [eax + TCP_SOCKET.t_flags], TF_ACKNOW
mov [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval mov [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval ;;;; macro
mov ebx, eax add eax, STREAM_SOCKET.snd
call SOCKET_ring_create
add eax, STREAM_SOCKET.rcv - STREAM_SOCKET.snd
call SOCKET_ring_create
sub eax, STREAM_SOCKET.rcv
mov [eax + SOCKET.lock], 0
mov ebx, eax ; if there is data, it must arrive in this new socket!
jmp .trim_then_step6 jmp .trim_then_step6
@ -830,9 +857,6 @@ align 4
jmp .step6 jmp .step6
.trim_then_step6: .trim_then_step6:
;---------------------------- ;----------------------------
@ -1083,7 +1107,7 @@ align 4
mov eax, [ebx + TCP_SOCKET.SND_MAX] mov eax, [ebx + TCP_SOCKET.SND_MAX]
cmp eax, [edx + TCP_segment.AckNumber] cmp eax, [edx + TCP_segment.AckNumber]
je .all_outstanding je .all_outstanding
mov [ebx + TCP_SOCKET.timer_retransmission], 120 ;;;; TODO: correct this value mov [ebx + TCP_SOCKET.timer_retransmission], 120 ;;;; TODO: correct this value (use a macro for it)
.all_outstanding: .all_outstanding:
;------------------------------------------- ;-------------------------------------------
@ -1182,7 +1206,7 @@ align 4
jg .no_window_update jg .no_window_update
@@: @@:
mov eax, [ebx + TCP_SOCKET.SND_WL2] ;;;; mov eax, [ebx + TCP_SOCKET.SND_WL2]
cmp eax, [edx + TCP_segment.AckNumber] cmp eax, [edx + TCP_segment.AckNumber]
jne .no_window_update jne .no_window_update
@ -1212,7 +1236,7 @@ align 4
; ;
; @@: ; @@:
movzx eax, [edx + TCP_segment.Window] ;;; FIXME: use pre-calculated value instead! mov eax, dword [edx + TCP_segment.Window]
cmp eax, [ebx + TCP_SOCKET.max_sndwnd] cmp eax, [ebx + TCP_SOCKET.max_sndwnd]
jle @f jle @f
mov [ebx + TCP_SOCKET.max_sndwnd], eax mov [ebx + TCP_SOCKET.max_sndwnd], eax
@ -1288,7 +1312,7 @@ align 4
lea esi, [edx + eax] lea esi, [edx + eax]
or [ebx + TCP_SOCKET.t_flags], TF_DELACK or [ebx + TCP_SOCKET.t_flags], TF_DELACK
add [ebx + TCP_SOCKET.RCV_NXT], ecx ;;; right ? add [ebx + TCP_SOCKET.RCV_NXT], ecx
lea eax, [ebx + STREAM_SOCKET.rcv] lea eax, [ebx + STREAM_SOCKET.rcv]
call SOCKET_ring_write call SOCKET_ring_write
@ -1558,7 +1582,7 @@ TCP_output:
.no_zero_window: .no_zero_window:
mov [eax + TCP_SOCKET.timer_persist], 0 ;;;; mov [eax + TCP_SOCKET.timer_persist], 0
mov [eax + TCP_SOCKET.t_rxtshift], 0 mov [eax + TCP_SOCKET.t_rxtshift], 0
.no_persist_timeout: .no_persist_timeout:
@ -1800,16 +1824,16 @@ TCP_output:
shr edi, 2 ; .DataOffset db ? ;;;; shr edi, 2 ; .DataOffset db ? ;;;;
push [eax + TCP_SOCKET.RCV_NXT] ; .AckNumber dd ? push [eax + TCP_SOCKET.RCV_NXT] ; .AckNumber dd ?
ntohld [esp] ntohd [esp]
push [eax + TCP_SOCKET.SND_NXT] ; .SequenceNumber dd ? push [eax + TCP_SOCKET.SND_NXT] ; .SequenceNumber dd ?
ntohld [esp] ntohd [esp]
push [eax + TCP_SOCKET.RemotePort] ; .DestinationPort dw ? push [eax + TCP_SOCKET.RemotePort] ; .DestinationPort dw ?
ntohlw [esp] ntohw [esp]
push [eax + TCP_SOCKET.LocalPort] ; .SourcePort dw ? push [eax + TCP_SOCKET.LocalPort] ; .SourcePort dw ?
ntohlw [esp] ntohw [esp]
push edi ; header size push edi ; header size