Bugfixes for #2937 (receive window calculation).

Disabled interrupts while in TCP_input or TCP_output to prevent deadlock.

git-svn-id: svn://kolibrios.org@2942 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2012-08-27 22:47:10 +00:00
parent ac776f502e
commit 51263819d7
2 changed files with 32 additions and 14 deletions

View File

@ -34,11 +34,14 @@ $Revision$
align 4 align 4
TCP_input: TCP_input:
pushfd
cli
DEBUGF 1,"TCP_input: size=%u\n", ecx DEBUGF 1,"TCP_input: size=%u\n", ecx
; First, record the current time ; First, record the current time
mov eax, [timer_ticks] ; in 1/100 seconds mov eax, [timer_ticks] ; in 1/100 seconds
mov [esp+4], eax mov [esp+8], eax
; then, re-calculate the checksum (if not already done by hw) ; then, re-calculate the checksum (if not already done by hw)
; test [ebx + NET_DEVICE.hwacc], HWACC_TCP_IPv4_IN ; test [ebx + NET_DEVICE.hwacc], HWACC_TCP_IPv4_IN
@ -214,7 +217,6 @@ TCP_input:
movzx eax, word[esi+2] movzx eax, word[esi+2]
rol ax, 8 rol ax, 8
DEBUGF 1,"TCP_input: Maxseg=%u\n", ax DEBUGF 1,"TCP_input: Maxseg=%u\n", ax
mov [ebx + TCP_SOCKET.t_maxseg], eax mov [ebx + TCP_SOCKET.t_maxseg], eax
@@: @@:
@ -330,7 +332,7 @@ TCP_input:
test [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP test [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP
jz .no_timestamp_rtt jz .no_timestamp_rtt
mov eax, [esp + 4] ; timestamp when this segment was received mov eax, [esp + 4+4] ; timestamp when this segment was received
sub eax, [ebx + TCP_SOCKET.ts_ecr] sub eax, [ebx + TCP_SOCKET.ts_ecr]
inc eax inc eax
call TCP_xmit_timer call TCP_xmit_timer
@ -417,15 +419,18 @@ TCP_input:
; Calculate receive window size ; Calculate receive window size
push edx
mov eax, SOCKETBUFFSIZE mov eax, SOCKETBUFFSIZE
sub eax, [ebx + STREAM_SOCKET.rcv.size] sub eax, [ebx + STREAM_SOCKET.rcv.size]
mov edx, [ebx + TCP_SOCKET.RCV_ADV] mov edx, [ebx + TCP_SOCKET.RCV_ADV]
sub edx, [ebx + TCP_SOCKET.RCV_NXT] sub edx, [ebx + TCP_SOCKET.RCV_NXT]
cmp eax, edx cmp eax, edx
ja @f jg @f
mov eax, edx mov eax, edx
@@: @@:
DEBUGF 1,"Receive window size=%d\n", ax
mov [ebx + TCP_SOCKET.RCV_WND], ax mov [ebx + TCP_SOCKET.RCV_WND], ax
pop edx
; If listen or Syn sent, go to that specific code right away ; If listen or Syn sent, go to that specific code right away
@ -462,14 +467,14 @@ TCP_input:
mov eax, [ebx + TCP_SOCKET.RCV_NXT] mov eax, [ebx + TCP_SOCKET.RCV_NXT]
sub eax, [edx + TCP_header.SequenceNumber] sub eax, [edx + TCP_header.SequenceNumber]
jbe .no_duplicate jle .no_duplicate
DEBUGF 1,"TCP_input: %u bytes duplicate data!\n", eax DEBUGF 1,"TCP_input: %u bytes duplicate data!\n", eax
test [edx + TCP_header.Flags], TH_SYN test [edx + TCP_header.Flags], TH_SYN
jz .no_dup_syn jz .no_dup_syn
; remove duplicate syn DEBUGF 1,"TCP_input: got duplicate syn\n"
and [edx + TCP_header.Flags], not (TH_SYN) and [edx + TCP_header.Flags], not (TH_SYN)
inc [edx + TCP_header.SequenceNumber] inc [edx + TCP_header.SequenceNumber]
@ -511,7 +516,7 @@ TCP_input:
sub ecx, eax sub ecx, eax
sub [edx + TCP_header.UrgentPointer], ax sub [edx + TCP_header.UrgentPointer], ax
ja @f jg @f
and [edx + TCP_header.Flags], not (TH_URG) and [edx + TCP_header.Flags], not (TH_URG)
mov [edx + TCP_header.UrgentPointer], 0 mov [edx + TCP_header.UrgentPointer], 0
@@: @@:
@ -540,11 +545,13 @@ TCP_input:
add eax, ecx add eax, ecx
sub eax, [ebx + TCP_SOCKET.RCV_NXT] sub eax, [ebx + TCP_SOCKET.RCV_NXT]
sub ax, [ebx + TCP_SOCKET.RCV_WND] ; eax now holds the number of bytes to drop sub ax, [ebx + TCP_SOCKET.RCV_WND] ; eax now holds the number of bytes to drop
jbe .no_excess_data jle .no_excess_data
DEBUGF 1,"%d bytes beyond right edge of window\n", eax
;;; TODO: update stats ;;; TODO: update stats
cmp eax, ecx cmp eax, ecx
jb .dont_drop_all jl .dont_drop_all
; If a new connection request is received while in TIME_WAIT, drop the old connection and start over, ; If a new connection request is received while in TIME_WAIT, drop the old connection and start over,
; if the sequence numbers are above the previous ones ; if the sequence numbers are above the previous ones
@ -552,9 +559,9 @@ TCP_input:
jz .no_new_request jz .no_new_request
cmp [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT cmp [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT
jne .no_new_request jne .no_new_request
mov edx, [ebx + TCP_SOCKET.RCV_NXT] ; mov edx, [ebx + TCP_SOCKET.RCV_NXT]
cmp edx, [edx + TCP_header.SequenceNumber] ; cmp edx, [edx + TCP_header.SequenceNumber]
add edx, 64000 ; TCP_ISSINCR ; add edx, 64000 ; TCP_ISSINCR FIXME
mov eax, ebx mov eax, ebx
call TCP_close call TCP_close
jmp .findpcb ; FIXME: skip code for unscaling window, ... jmp .findpcb ; FIXME: skip code for unscaling window, ...
@ -595,7 +602,7 @@ TCP_input:
sub eax, ecx sub eax, ecx
jae .no_timestamp jae .no_timestamp
mov eax, [esp + 4] ; tcp_now mov eax, [esp + 4+4] ; tcp_now
mov [ebx + TCP_SOCKET.ts_recent_age], eax mov [ebx + TCP_SOCKET.ts_recent_age], eax
mov eax, [ebx + TCP_SOCKET.ts_val] mov eax, [ebx + TCP_SOCKET.ts_val]
mov [ebx + TCP_SOCKET.ts_recent], eax mov [ebx + TCP_SOCKET.ts_recent], eax
@ -844,7 +851,7 @@ TCP_input:
test [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP test [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP
jne .timestamp_not_present jne .timestamp_not_present
mov eax, [esp+4] mov eax, [esp+4+4]
sub eax, [ebx + TCP_SOCKET.ts_ecr] sub eax, [ebx + TCP_SOCKET.ts_ecr]
inc eax inc eax
call TCP_xmit_timer call TCP_xmit_timer
@ -1457,8 +1464,10 @@ align 4
.dumpit: .dumpit:
DEBUGF 1,"TCP_input: dumping\n" DEBUGF 1,"TCP_input: dumping\n"
popf
call kernel_free call kernel_free
add esp, 4 add esp, 4
ret ret
@ -1502,8 +1511,10 @@ align 4
.drop_no_socket: .drop_no_socket:
DEBUGF 1,"TCP_input: Drop (no socket)\n" DEBUGF 1,"TCP_input: Drop (no socket)\n"
popf
call kernel_free call kernel_free
add esp, 4 add esp, 4
ret ret
.drop_with_reset_no_socket: .drop_with_reset_no_socket:

View File

@ -28,6 +28,9 @@ $Revision$
align 4 align 4
TCP_output: TCP_output:
pushf
cli
DEBUGF 1,"TCP_output: socket=%x\n", eax DEBUGF 1,"TCP_output: socket=%x\n", eax
pusha pusha
@ -276,6 +279,7 @@ TCP_output:
call mutex_unlock call mutex_unlock
popa popa
popf
ret ret
@ -567,6 +571,7 @@ TCP_send:
DEBUGF 1,"TCP_send: success!\n" DEBUGF 1,"TCP_send: success!\n"
xor eax, eax xor eax, eax
popf
ret ret
@ -585,6 +590,7 @@ TCP_send:
DEBUGF 1,"TCP_send: IP error\n" DEBUGF 1,"TCP_send: IP error\n"
or eax, -1 or eax, -1
popf
ret ret
.send_error: .send_error:
@ -593,6 +599,7 @@ TCP_send:
DEBUGF 1,"TCP_send: sending failed\n" DEBUGF 1,"TCP_send: sending failed\n"
or eax, -2 or eax, -2
popf
ret ret