Refactoring of socket.inc

bugfix in ETH_output when sending packets of 60 bytes
updates in TCP code

git-svn-id: svn://kolibrios.org@1536 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2010-07-30 09:09:06 +00:00
parent 9aaa131d1c
commit 718d8df6de
3 changed files with 209 additions and 226 deletions

View File

@ -167,6 +167,7 @@ ETH_output:
.adjust_size: .adjust_size:
mov edx, 60 mov edx, 60
test edx, edx ; clear zero flag
ret ret
.out_of_ram: .out_of_ram:

View File

@ -35,6 +35,9 @@ virtual at 0
.options dd ? .options dd ?
.state dd ? .state dd ?
.snd_proc dd ?
.rcv_proc dd ?
.end: .end:
end virtual end virtual
@ -261,6 +264,7 @@ s_error:
ret ret
align 4
sock_sysfn_table: sock_sysfn_table:
dd SOCKET_open ; 0 dd SOCKET_open ; 0
dd SOCKET_close ; 1 dd SOCKET_close ; 1
@ -288,7 +292,7 @@ sock_sysfn_table:
align 4 align 4
SOCKET_open: 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
call SOCKET_alloc call SOCKET_alloc
jz s_error jz s_error
@ -297,17 +301,26 @@ SOCKET_open:
mov [eax + SOCKET.Type], edx mov [eax + SOCKET.Type], edx
mov [eax + SOCKET.Protocol], esi mov [eax + SOCKET.Protocol], esi
mov [esp+32], edi mov [esp+32], edi ; return socketnumber
cmp ecx, AF_INET4 cmp ecx, AF_INET4
jnz .no_stream jne .no_inet4
push [IP_LIST] ;;;; push [IP_LIST]
pop [eax + IP_SOCKET.LocalIP] ;;;; pop [eax + IP_SOCKET.LocalIP] ; fill in local ip number
call SOCKET_find_port ; fill in a local port number, application may change it later, or use this one
cmp edx, IP_PROTO_UDP
je .udp
cmp edx, IP_PROTO_TCP cmp edx, IP_PROTO_TCP
jnz .no_stream je .tcp
.no_inet4:
ret
.tcp:
mov ebx, eax mov ebx, eax
lea eax, [ebx + STREAM_SOCKET.snd] lea eax, [ebx + STREAM_SOCKET.snd]
@ -316,13 +329,18 @@ SOCKET_open:
lea eax, [ebx + STREAM_SOCKET.rcv] lea eax, [ebx + STREAM_SOCKET.rcv]
call SOCKET_ring_create call SOCKET_ring_create
mov [ebx + SOCKET.snd_proc], SOCKET_send_tcp
mov [ebx + SOCKET.rcv_proc], SOCKET_receive_tcp
ret ret
.no_stream: .udp:
push eax
push edi
init_queue (eax + SOCKET_QUEUE_LOCATION) init_queue (eax + SOCKET_QUEUE_LOCATION)
pop edi pop eax
mov [eax + SOCKET.snd_proc], SOCKET_send_udp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_udp
ret ret
@ -375,22 +393,16 @@ SOCKET_bind:
mov bx, word [edx + 2] mov bx, word [edx + 2]
test bx, bx test bx, bx
jz .find_free jz .use_preset_port
call SOCKET_check_port call SOCKET_check_port
; test bx, bx
jz s_error
jmp .got_port
.find_free:
call SOCKET_find_port
; test bx, bx
jz s_error jz s_error
.got_port:
DEBUGF 1,"using local port: %u\n", bx DEBUGF 1,"using local port: %u\n", bx
mov word [eax + UDP_SOCKET.LocalPort], 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,\
[eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1 [eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1
@ -464,14 +476,6 @@ SOCKET_connect:
mov ebx, dword [edx + 4] mov ebx, dword [edx + 4]
mov [eax + IP_SOCKET.RemoteIP], ebx mov [eax + IP_SOCKET.RemoteIP], ebx
; check if local port and IP is ok
cmp [eax + TCP_SOCKET.LocalPort], 0
jne @f
call SOCKET_find_port
@@:
DEBUGF 1,"local port: %u\n", [eax + TCP_SOCKET.LocalPort]:2
;;;;; ;;;;;
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
@ -572,10 +576,10 @@ SOCKET_accept:
test ebx, ebx test ebx, ebx
jz .unlock_err jz .unlock_err
dec [eax + TCP_SOCKET.backlog_cur] dec [eax + TCP_SOCKET.backlog_cur] ;;;;
mov eax, [eax + TCP_SOCKET.end + (ebx-1)*4] mov eax, [eax + TCP_SOCKET.end + (ebx-1)*4] ;;;;;
mov [eax + SOCKET.lock], 0 mov [eax + SOCKET.lock], 0 ;;;;
mov dword [esp+32], 0 mov dword [esp+32], 0 ;;;;
call TCP_output ;;;;; call TCP_output ;;;;;
@ -617,17 +621,14 @@ SOCKET_close:
jmp s_error jmp s_error
.tcp: .tcp:
test [eax + TCP_SOCKET.t_state], TCB_SYN_RECEIVED ;;;;;; cmp [eax + TCP_SOCKET.t_state], TCB_SYN_RECEIVED ; state must be LISTEN, SYN_SENT or CLOSED
jz .free jl .free
;;; call TCP_output call TCP_output
mov dword [esp+32], 0
;;; mov dword [esp+32], 0 ret
;;; ret
; state must be LISTEN, SYN_SENT, CLOSED or maybe even invalid
; so, we may destroy the socket
.free: .free:
call SOCKET_free call SOCKET_free
mov dword [esp+32], 0 mov dword [esp+32], 0
@ -649,54 +650,62 @@ SOCKET_close:
align 4 align 4
SOCKET_receive: SOCKET_receive:
DEBUGF 1,"socket_receive: socknum: %u bufaddr: %x, buflength: %u, flags: %x\n", 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 call SOCKET_num_to_ptr
jz s_error jz s_error
cmp [eax + SOCKET.Type], IP_PROTO_TCP ;;;;;;;; jmp [eax + SOCKET.rcv_proc]
je .tcp
align 4
SOCKET_receive_udp:
DEBUGF 1,"type: UDP\n"
mov ebx, esi mov ebx, esi
get_from_queue (eax + SOCKET_QUEUE_LOCATION),\
SOCKET_QUEUE_SIZE,\
socket_queue_entry.size,\
s_error
; destroys esi and ecx
mov edi, edx ; addr to buffer mov edi, edx ; addr to buffer
get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, socket_queue_entry.size, s_error ; destroys esi and ecx
mov ecx, [esi + socket_queue_entry.data_size] mov ecx, [esi + socket_queue_entry.data_size]
DEBUGF 1,"Got %u bytes of data\n", ecx DEBUGF 1,"Got %u bytes of data\n", ecx
cmp ecx, ebx cmp ecx, ebx
jle .large_enough jg .too_small
DEBUGF 1,"Buffer too small...\n"
jmp s_error
.large_enough: push [esi + socket_queue_entry.buf_ptr] ; save the buffer addr so we can clear it later
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] mov esi, [esi + socket_queue_entry.data_ptr]
DEBUGF 1,"Source buffer: %x, real addr: %x\n", [esp], esi DEBUGF 1,"Source buffer: %x, real addr: %x\n", [esp], esi
mov dword[esp+32+4], ecx ; return number of bytes copied in ebx mov dword[esp+32+4], ecx ; return number of bytes copied
; copy the data ; copy the data
shr ecx, 1 shr ecx, 1
jnc .nb jnc .nb
movsb movsb
.nb: shr ecx, 1 .nb:
shr ecx, 1
jnc .nw jnc .nw
movsw movsw
.nw: test ecx, ecx .nw:
test ecx, ecx
jz .nd jz .nd
rep movsd rep movsd
.nd: .nd:
; remove the packet ;;; TODO: only if it is empty!!
call kernel_free call kernel_free ; remove the packet
ret ret
.tcp: .too_small:
DEBUGF 1,"Buffer too small...\n"
jmp s_error
align 4
SOCKET_receive_tcp:
DEBUGF 1,"type: TCP\n"
mov ecx, esi mov ecx, esi
mov edi, edx mov edi, edx
@ -704,7 +713,7 @@ SOCKET_receive:
call SOCKET_ring_read call SOCKET_ring_read
call SOCKET_ring_free call SOCKET_ring_free
mov dword[esp+32], ecx ; return number of bytes copied in ebx mov dword[esp+32], ecx ; return number of bytes copied
ret ret
@ -724,45 +733,20 @@ SOCKET_receive:
align 4 align 4
SOCKET_send: SOCKET_send:
DEBUGF 1,"socket_send: socknum: %u sockaddr: %x, length: %u, flags: %x\n", ecx, edx, esi, edi DEBUGF 1,"SOCKET_send: socknum: %u sockaddr: %x, length: %u, flags: %x, ", ecx, edx, esi, edi
call SOCKET_num_to_ptr call SOCKET_num_to_ptr
jz s_error jz s_error
cmp word [eax + SOCKET.Domain], AF_INET4 jmp [eax + SOCKET.snd_proc]
je .af_inet4
jmp s_error
.af_inet4:
DEBUGF 1,"af_inet4\n"
cmp [eax + IP_SOCKET.LocalIP], 0 align 4
jne @f SOCKET_send_udp:
mov ebx, [IP_LIST] ;;;;
mov dword [eax + IP_SOCKET.LocalIP], ebx
@@:
cmp [eax + SOCKET.Type], IP_PROTO_TCP
je .tcp
cmp [eax + SOCKET.Type], IP_PROTO_UDP
je .udp
jmp s_error
.udp:
DEBUGF 1,"type: UDP\n" DEBUGF 1,"type: UDP\n"
; check if local port is valid
cmp [eax + UDP_SOCKET.LocalPort], 0
jne @f
call SOCKET_find_port
jz s_error
; Now, send the packet
@@:
mov ecx, esi mov ecx, esi
mov esi, edx mov esi, edx
@ -771,24 +755,19 @@ SOCKET_send:
mov dword [esp+32], 0 mov dword [esp+32], 0
ret ret
.tcp:
align 4
SOCKET_send_tcp:
DEBUGF 1,"type: TCP\n" DEBUGF 1,"type: TCP\n"
; check if local port is valid
cmp [eax + TCP_SOCKET.LocalPort], 0
jne @f
call SOCKET_find_port
jz s_error
@@:
push eax push eax
mov ecx, esi mov ecx, esi
mov esi, edx mov esi, edx
add eax, STREAM_SOCKET.snd add eax, STREAM_SOCKET.snd
call SOCKET_ring_write call SOCKET_ring_write
pop eax pop eax
call TCP_output call TCP_output
mov [esp+32], eax mov [esp+32], eax
@ -814,7 +793,7 @@ SOCKET_send:
align 4 align 4
SOCKET_get_opt: SOCKET_get_opt:
DEBUGF 1,"socket_get_opt\n" DEBUGF 1,"SOCKET_get_opt\n"
call SOCKET_num_to_ptr call SOCKET_num_to_ptr
jz s_error jz s_error
@ -894,7 +873,7 @@ SOCKET_debug:
align 4 align 4
SOCKET_find_port: SOCKET_find_port:
DEBUGF 1,"socket_find_free_port\n" DEBUGF 1,"SOCKET_find_port\n"
push ebx esi ecx push ebx esi ecx
@ -956,7 +935,7 @@ SOCKET_find_port:
align 4 align 4
SOCKET_check_port: SOCKET_check_port:
DEBUGF 1,"socket_check_port\n" DEBUGF 1,"SOCKET_check_port\n"
mov ecx, [eax + SOCKET.Type] mov ecx, [eax + SOCKET.Type]
mov esi, net_sockets mov esi, net_sockets
@ -987,7 +966,7 @@ SOCKET_check_port:
; ;
; SOCKET_input ; SOCKET_input
; ;
; Updates a socket with received data ; Updates a (stateless) socket with received data
; ;
; Note: the mutex should already be set ! ; Note: the mutex should already be set !
; ;
@ -1004,16 +983,13 @@ SOCKET_check_port:
align 4 align 4
SOCKET_input: 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 dword[esp+4], ecx mov dword[esp+4], ecx
push esi push esi
mov esi, esp mov esi, esp
add_to_queue (eax + SOCKET_QUEUE_LOCATION),\ add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, socket_queue_entry.size, SOCKET_input.full
SOCKET_QUEUE_SIZE,\
socket_queue_entry.size,\
SOCKET_input.full
DEBUGF 1,"Queued packet successfully\n" DEBUGF 1,"Queued packet successfully\n"
add esp, socket_queue_entry.size add esp, socket_queue_entry.size
@ -1079,15 +1055,15 @@ SOCKET_ring_write:
shr ecx, 1 shr ecx, 1
jnc .nb jnc .nb
movsb movsb
.nb: .nb:
shr ecx, 1 shr ecx, 1
jnc .nw jnc .nw
movsw movsw
.nw: .nw:
test ecx, ecx test ecx, ecx
jz .nd jz .nd
rep movsd rep movsd
.nd: .nd:
pop ecx pop ecx
cmp edi, [eax + RING_BUFFER.end_ptr] cmp edi, [eax + RING_BUFFER.end_ptr]
@ -1145,15 +1121,15 @@ SOCKET_ring_read:
shr ecx, 1 shr ecx, 1
jnc .nb jnc .nb
movsb movsb
.nb: .nb:
shr ecx, 1 shr ecx, 1
jnc .nw jnc .nw
movsw movsw
.nw: .nw:
test ecx, ecx test ecx, ecx
jz .nd jz .nd
rep movsd rep movsd
.nd: .nd:
pop ecx pop ecx
; .no_data_at_all: ; .no_data_at_all:
@ -1181,7 +1157,7 @@ SOCKET_ring_read:
align 4 align 4
SOCKET_ring_free: SOCKET_ring_free:
DEBUGF 1,"Trying to free %u bytes of data 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 sub [eax + RING_BUFFER.size], ecx
jl .sumthinwong jl .sumthinwong
@ -1213,12 +1189,12 @@ SOCKET_ring_free:
align 4 align 4
SOCKET_notify_owner: SOCKET_notify_owner:
DEBUGF 1,"socket_notify_owner\n" DEBUGF 1,"SOCKET_notify_owner: %x\n", eax
call SOCKET_check call SOCKET_check
jz .error jz .error
push ecx eax esi push ecx esi
; socket exists, now try to flag an event to the application ; socket exists, now try to flag an event to the application
@ -1243,10 +1219,11 @@ SOCKET_notify_owner:
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK
mov [check_idle_semaphore], 200 mov [check_idle_semaphore], 200
DEBUGF 1,"owner notified\n" DEBUGF 1,"SOCKET_notify_owner: succes!\n"
.error2: .error2:
pop esi eax ecx pop esi ecx
.error: .error:
ret ret
@ -1284,18 +1261,22 @@ SOCKET_alloc:
rep stosd rep stosd
pop edi eax pop edi eax
; set send-and receive procedures to return -1
mov [eax + SOCKET.snd_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
mov ebx, net_sockets
xor ecx, ecx xor ecx, ecx
.next_socket_number: .next_socket_number:
inc ecx inc ecx
mov ebx, net_sockets
.next_socket: .next_socket:
mov ebx, [ebx + SOCKET.NextPtr] mov ebx, [ebx + SOCKET.NextPtr]
test ebx, ebx test ebx, ebx
jz .last_socket jz .last_socket
cmp [ebx + SOCKET.Number], ecx cmp [ebx + SOCKET.Number], ecx
jne .next_socket jne .next_socket
mov ebx, net_sockets
jmp .next_socket_number jmp .next_socket_number
.last_socket: .last_socket:
@ -1320,7 +1301,7 @@ SOCKET_alloc:
call wait_mutex call wait_mutex
sub ebx, SOCKET.lock sub ebx, SOCKET.lock
mov [ebx + SOCKET.PrevPtr], eax mov [ebx + SOCKET.PrevPtr], eax
mov [ebx + SOCKET.lock], 0 mov [ebx + SOCKET.lock], 0 ; and unlock it again
@@: @@:
mov [net_sockets + SOCKET.NextPtr], eax mov [net_sockets + SOCKET.NextPtr], eax
@ -1344,7 +1325,7 @@ SOCKET_alloc:
align 4 align 4
SOCKET_free: SOCKET_free:
DEBUGF 1, "socket_free: %x\n", eax DEBUGF 1, "SOCKET_free: %x\n", eax
call SOCKET_check call SOCKET_check
jz .error jz .error
@ -1356,14 +1337,16 @@ SOCKET_free:
DEBUGF 1, "freeing socket..\n" DEBUGF 1, "freeing socket..\n"
cmp [eax + SOCKET.Domain], AF_INET4 cmp [eax + SOCKET.Domain], AF_INET4
jnz .no_stream jnz .no_tcp
cmp [eax + SOCKET.Type], IP_PROTO_TCP cmp [eax + SOCKET.Type], IP_PROTO_TCP
jnz .no_stream jnz .no_tcp
stdcall kernel_free, [eax + STREAM_SOCKET.rcv + RING_BUFFER.start_ptr] mov ebx, eax
stdcall kernel_free, [eax + STREAM_SOCKET.snd + RING_BUFFER.start_ptr] stdcall kernel_free, [ebx + STREAM_SOCKET.rcv + RING_BUFFER.start_ptr]
.no_stream: stdcall kernel_free, [ebx + STREAM_SOCKET.snd + RING_BUFFER.start_ptr]
mov eax, ebx
.no_tcp:
push eax ; this will be passed to kernel_free push eax ; this will be passed to kernel_free
mov ebx, [eax + SOCKET.NextPtr] mov ebx, [eax + SOCKET.NextPtr]
@ -1437,7 +1420,7 @@ SOCKET_fork:
align 4 align 4
SOCKET_num_to_ptr: 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
@ -1469,7 +1452,7 @@ SOCKET_num_to_ptr:
align 4 align 4
SOCKET_ptr_to_num: SOCKET_ptr_to_num:
DEBUGF 1,"socket_ptr_to_num: %x ", eax DEBUGF 1,"SOCKET_ptr_to_num: %x ", eax
call SOCKET_check call SOCKET_check
jz .error jz .error
@ -1496,7 +1479,7 @@ SOCKET_ptr_to_num:
align 4 align 4
SOCKET_check: SOCKET_check:
DEBUGF 1,"socket_check\n" DEBUGF 1,"SOCKET_check: %x\n", eax
push ebx push ebx
mov ebx, net_sockets mov ebx, net_sockets
@ -1530,7 +1513,7 @@ SOCKET_check:
align 4 align 4
SOCKET_check_owner: SOCKET_check_owner:
DEBUGF 1,"socket_check_owner\n" DEBUGF 1,"SOCKET_check_owner: %x\n", eax
push ebx push ebx
mov ebx, [TASK_BASE] mov ebx, [TASK_BASE]
@ -1558,7 +1541,7 @@ SOCKET_check_owner:
align 4 align 4
SOCKET_process_end: SOCKET_process_end:
DEBUGF 1,"socket_process_end: %x\n", eax DEBUGF 1,"SOCKET_process_end: %x\n", eax
push ebx push ebx
mov ebx, net_sockets mov ebx, net_sockets

View File

@ -90,20 +90,6 @@ struct TCP_segment
.Data: ; ..or options .Data: ; ..or options
ends ends
struct tcp_in_queue_entry
.data_ptr dd ?
.data_size dd ?
.offset dd ?
.size:
ends
struct tcp_out_queue_entry
.data_ptr dd ?
.data_size dd ?
.size:
ends
align 4 align 4
uglobal uglobal
TCP_segments_tx rd IP_MAX_INTERFACES TCP_segments_tx rd IP_MAX_INTERFACES
@ -557,36 +543,24 @@ TCP_input:
cmp [ebx + TCP_SOCKET.t_state], TCB_ESTABLISHED cmp [ebx + TCP_SOCKET.t_state], TCB_ESTABLISHED
jnz .not_uni_xfer jnz .not_uni_xfer
DEBUGF 1,"1\n"
test [edx + TCP_segment.Flags], TH_SYN + TH_FIN + TH_RST + TH_URG test [edx + TCP_segment.Flags], TH_SYN + TH_FIN + TH_RST + TH_URG
jnz .not_uni_xfer jnz .not_uni_xfer
DEBUGF 1,"2\n"
test [edx + TCP_segment.Flags], TH_ACK test [edx + TCP_segment.Flags], TH_ACK
jz .not_uni_xfer jz .not_uni_xfer
DEBUGF 1,"3\n"
mov eax, [edx + TCP_segment.SequenceNumber] mov eax, [edx + TCP_segment.SequenceNumber]
cmp eax, [ebx + TCP_SOCKET.RCV_NXT] cmp eax, [ebx + TCP_SOCKET.RCV_NXT]
jne .not_uni_xfer jne .not_uni_xfer
DEBUGF 1,"4\n" movzx eax, [edx + TCP_segment.Window] ;;;;; (should use pre-calculated value instead: todo: figure out where to store it)
cmp eax, [ebx + TCP_SOCKET.SND_WND]
;; movzx eax, [edx + TCP_segment.Window] ;;;;; (should use pre-calculated value isntead: todo: figure out where to store it) jne .not_uni_xfer
;; cmp eax, [ebx + TCP_SOCKET.SND_WND]
;; jne .not_uni_xfer
DEBUGF 1,"5\n"
mov eax, [ebx + TCP_SOCKET.SND_NXT] mov eax, [ebx + TCP_SOCKET.SND_NXT]
cmp eax, [ebx + TCP_SOCKET.SND_MAX] cmp eax, [ebx + TCP_SOCKET.SND_MAX]
jne .not_uni_xfer jne .not_uni_xfer
DEBUGF 1,"6\n"
;--------------------------------------- ;---------------------------------------
; check if we are sender in the uni-xfer ; check if we are sender in the uni-xfer
@ -596,23 +570,17 @@ TCP_input:
test ecx, ecx test ecx, ecx
jnz .not_sender jnz .not_sender
DEBUGF 1,"7\n"
; - The congestion window is greater than or equal to the current send window. ; - 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. ; 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] mov eax, [ebx + TCP_SOCKET.SND_CWND]
cmp eax, [ebx + TCP_SOCKET.SND_WND] cmp eax, [ebx + TCP_SOCKET.SND_WND]
jl .not_uni_xfer jl .not_uni_xfer
DEBUGF 1,"8\n"
; - The acknowledgment field in the segment is less than or equal to the maximum sequence number sent. ; - The acknowledgment field in the segment is less than or equal to the maximum sequence number sent.
mov eax, [edx + TCP_segment.AckNumber] mov eax, [edx + TCP_segment.AckNumber]
cmp eax, [ebx + TCP_SOCKET.SND_MAX] cmp eax, [ebx + TCP_SOCKET.SND_MAX]
jg .not_uni_xfer jg .not_uni_xfer
DEBUGF 1,"9\n"
; - The acknowledgment field in the segment is greater than the largest unacknowledged sequence number. ; - The acknowledgment field in the segment is greater than the largest unacknowledged sequence number.
sub eax, [ebx + TCP_SOCKET.SND_UNA] sub eax, [ebx + TCP_SOCKET.SND_UNA]
jle .not_uni_xfer jle .not_uni_xfer
@ -625,11 +593,15 @@ TCP_input:
; Update RTT estimators ; Update RTT estimators
; Delete acknowledged bytes from send buffer ; Delete acknowledged bytes from send buffer
; notice how ecx already holds number of bytes ack-ed mov ecx, eax
lea eax, [ebx + STREAM_SOCKET.snd] lea eax, [ebx + STREAM_SOCKET.snd]
call SOCKET_ring_free call SOCKET_ring_free
; update window pointers
mov eax, [edx + TCP_segment.AckNumber]
dec eax
mov [ebx + TCP_SOCKET.SND_WL1], eax
; Stop retransmit timer ; Stop retransmit timer
mov [ebx + TCP_SOCKET.timer_ack], 0 mov [ebx + TCP_SOCKET.timer_ack], 0
@ -637,10 +609,12 @@ TCP_input:
mov eax, ebx mov eax, ebx
call SOCKET_notify_owner call SOCKET_notify_owner
; Generate more output ;; Generate more output
call TCP_output ;; mov eax, ebx
;; call TCP_output
jmp .drop ;;
;; jmp .drop
jmp .step6
;------------------------------------------------- ;-------------------------------------------------
; maybe we are the receiver in the uni-xfer then.. ; maybe we are the receiver in the uni-xfer then..
@ -648,8 +622,6 @@ TCP_input:
.not_sender: .not_sender:
; - The amount of data in the segment is greater than 0 (data count is in ecx) ; - The amount of data in the segment is greater than 0 (data count is in ecx)
DEBUGF 1,"10\n"
; - The acknowledgment field equals the largest unacknowledged sequence number. This means no data is acknowledged by this segment. ; - The acknowledgment field equals the largest unacknowledged sequence number. This means no data is acknowledged by this segment.
mov eax, [edx + TCP_segment.AckNumber] mov eax, [edx + TCP_segment.AckNumber]
cmp eax, [ebx + TCP_SOCKET.SND_UNA] cmp eax, [ebx + TCP_SOCKET.SND_UNA]
@ -1084,18 +1056,16 @@ align 4
;;;;; ;;;;;
.ack_dup:
DEBUGF 1,"Duplicate ACK\n"
;;;;
.ack_nodup: .ack_nodup:
;;;; 887
DEBUGF 1,"New ACK\n" DEBUGF 1,"New ACK\n"
.ack_dup:
;;;;
;------------------------------------------------- ;-------------------------------------------------
; If the congestion window was inflated to account ; If the congestion window was inflated to account
; for the other side's cached packets, retrace it ; for the other side's cached packets, retrace it
@ -1125,12 +1095,26 @@ align 4
;------------------------------------------ ;------------------------------------------
; Remove acknowledged data from send buffer ; Remove acknowledged data from send buffer
push ecx pusha
mov ecx, [edx + TCP_segment.AckNumber] ;;; ; Delete acknowledged bytes from send buffer
sub ecx, [ebx + TCP_SOCKET.SND_UNA] ;;; mov ecx, [edx + TCP_segment.AckNumber]
sub ecx, [ebx + TCP_SOCKET.SND_UNA]
lea eax, [ebx + STREAM_SOCKET.snd] lea eax, [ebx + STREAM_SOCKET.snd]
call SOCKET_ring_free ;;;; 943 - 956 call SOCKET_ring_free
pop ecx popa
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; code missing (943?)
mov eax, [edx + TCP_segment.AckNumber]
mov [ebx + TCP_SOCKET.SND_UNA], eax
cmp eax, [ebx + TCP_SOCKET.SND_NXT]
jl @f
mov [ebx + TCP_SOCKET.SND_NXT], eax
@@:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;--------------------------------------- ;---------------------------------------
; Wake up process waiting on send buffer ; Wake up process waiting on send buffer
@ -1156,73 +1140,89 @@ align 4
dd ._1010 ;TCB_TIMED_WAIT dd ._1010 ;TCB_TIMED_WAIT
._963: ._963:
jmp .step6 jmp .step6
._958: ._958:
jmp .step6 jmp .step6
._999: ._999:
jmp .step6 jmp .step6
._1010: ._1010:
jmp .step6 jmp .step6
.step6:
align 4
.step6:
DEBUGF 1,"step 6\n" DEBUGF 1,"step 6\n"
;-------------------------- ;----------------------------------------------
; update window information ; check if we need to update window information
test [edx + TCP_segment.Flags], TH_ACK test [edx + TCP_segment.Flags], TH_ACK
jz .no_window_update jz .no_window_update
mov eax, [ebx + TCP_SOCKET.SND_WL1] mov eax, [ebx + TCP_SOCKET.SND_WL1]
cmp eax, [edx + TCP_segment.SequenceNumber] cmp eax, [edx + TCP_segment.SequenceNumber]
jl .update_window
jg @f
;;;; 1021 mov eax, [ebx + TCP_SOCKET.SND_WL2]
cmp eax, [edx + TCP_segment.AckNumber]
jl .update_window
jg .no_window_update
@@:
mov eax, [ebx + TCP_SOCKET.SND_WL2] ;;;;
cmp eax, [edx + TCP_segment.AckNumber]
jne .no_window_update
movzx eax, [edx + TCP_segment.Window]
cmp eax, [ebx + TCP_SOCKET.SND_WND]
jle .no_window_update
.update_window:
DEBUGF 1,"Updating window\n"
;---------------------------------- ;----------------------------------
; Keep track of pure window updates ; Keep track of pure window updates
test ecx, ecx ; test ecx, ecx
jz @f ; jz @f
;
; mov eax, [ebx + TCP_SOCKET.SND_WL2]
; cmp eax, [edx + TCP_segment.AckNumber]
; jne @f
;
; ;; mov eax, tiwin
; cmp eax, [ebx + TCP_SOCKET.SND_WND]
; jle @f
;
; ;;; update stats
;
; @@:
mov eax, [ebx + TCP_SOCKET.SND_WL2] movzx eax, [edx + TCP_segment.Window] ;;; FIXME: use pre-calculated value instead!
cmp eax, [edx + TCP_segment.AckNumber]
jne @f
;; mov eax, tiwin
cmp eax, [ebx + TCP_SOCKET.SND_WND]
jle @f
;;; update stats
@@:
;; mov eax, incoming 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
@@: @@:
mov [ebx + TCP_SOCKET.SND_WND], eax mov [ebx + TCP_SOCKET.SND_WND], eax
mov eax, [edx + TCP_segment.SequenceNumber] push [edx + TCP_segment.SequenceNumber]
mov [ebx + TCP_SOCKET.SND_WL1], eax pop [ebx + TCP_SOCKET.SND_WL1]
mov eax, [edx + TCP_segment.AckNumber] push [edx + TCP_segment.AckNumber]
mov [ebx + TCP_SOCKET.SND_WL2], eax pop [ebx + TCP_SOCKET.SND_WL2]
;;; needoutput = 1 ;;; needoutput = 1
@ -1496,8 +1496,6 @@ TCP_pull_out_of_band:
; TCP_output ; TCP_output
; ;
; IN: eax = socket pointer ; IN: eax = socket pointer
;; esi = ptr to data
;; ecx = number of data bytes
; ;
; OUT: / ; OUT: /
; ;
@ -1849,11 +1847,14 @@ TCP_output:
; ecx = buffer size ; ecx = buffer size
; edi = ptr to buffer ; edi = ptr to buffer
; test ecx, ecx
mov eax, [esp+4] ; socket ptr mov eax, [esp+4] ; socket ptr
push edx add [eax + TCP_SOCKET.SND_NXT], ecx
add eax, STREAM_SOCKET.snd add eax, STREAM_SOCKET.snd
push edx
call SOCKET_ring_read call SOCKET_ring_read
pop esi ecx pop esi
pop ecx
pop eax pop eax
test [esi + TCP_segment.Flags], TH_SYN + TH_FIN test [esi + TCP_segment.Flags], TH_SYN + TH_FIN
@ -1862,8 +1863,6 @@ TCP_output:
;;; TODO: update sentfin flag ;;; TODO: update sentfin flag
@@: @@:
;; add [eax + TCP_SOCKET.SND_NXT], ecx
mov edx, [eax + TCP_SOCKET.SND_NXT] mov edx, [eax + TCP_SOCKET.SND_NXT]
cmp edx, [eax + TCP_SOCKET.SND_MAX] cmp edx, [eax + TCP_SOCKET.SND_MAX]
jle @f jle @f
@ -1893,7 +1892,7 @@ TCP_output:
.fail: .fail:
pop ecx pop ecx
add esp, ecx add esp, ecx
add esp, 4+4+8+4 add esp, 4+8
DEBUGF 1,"TCP_output: failed\n" DEBUGF 1,"TCP_output: failed\n"
ret ret