* one check moved so that early received FIN packet does not eat tail of data

* changes in state of TCP socket now notify socket's owner

git-svn-id: svn://kolibrios.org@1181 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
CleverMouse 2009-09-27 11:48:00 +00:00
parent 456168f5b2
commit a864f1a57e

View File

@ -692,6 +692,36 @@ proc tcpStateMachine stdcall, sockAddr:DWORD
ret ret
endp endp
;***************************************************************************
; Function
; signal_network_event
;
; Description
; Signals about network event to socket owner
; This is a kernel function, called from TCP handler
;
; Socket/TCB address in ebx
;***************************************************************************
proc signal_network_event
push ecx esi eax
mov eax, [ebx + 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
.found_pid:
shl ecx, 8
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event
pop eax esi ecx
ret
endp
proc stateTCB_LISTEN stdcall, sockAddr:DWORD proc stateTCB_LISTEN stdcall, sockAddr:DWORD
; In this case, we are expecting a SYN packet ; In this case, we are expecting a SYN packet
@ -723,6 +753,7 @@ proc stateTCB_LISTEN stdcall, sockAddr:DWORD
cmp ax, NO_BUFFER cmp ax, NO_BUFFER
je .exit je .exit
push ebx
push eax push eax
mov bl, TH_SYN + TH_ACK mov bl, TH_SYN + TH_ACK
xor ecx, ecx xor ecx, ecx
@ -741,8 +772,10 @@ proc stateTCB_LISTEN stdcall, sockAddr:DWORD
pop ebx pop ebx
call queue call queue
pop ebx
mov esi, [sockAddr] mov esi, [sockAddr]
mov [esi + SOCKET.TCBState], TCB_SYN_RECEIVED mov [esi + SOCKET.TCBState], TCB_SYN_RECEIVED
call signal_network_event
; increment SND.NXT in socket ; increment SND.NXT in socket
add esi, SOCKET.SND_NXT add esi, SOCKET.SND_NXT
@ -774,6 +807,7 @@ proc stateTCB_SYN_SENT stdcall, sockAddr:DWORD
push TH_ACK push TH_ACK
.send: .send:
call signal_network_event
; Store the recv.nxt field ; Store the recv.nxt field
mov eax, [edx + 20 + TCP_PACKET.SequenceNumber] mov eax, [edx + 20 + TCP_PACKET.SequenceNumber]
@ -825,7 +859,7 @@ proc stateTCB_SYN_RECEIVED stdcall, sockAddr:DWORD
pop [ebx + SOCKET.RemoteIP] [ebx + SOCKET.RemotePort] pop [ebx + SOCKET.RemoteIP] [ebx + SOCKET.RemotePort]
mov [ebx + SOCKET.TCBState], TCB_LISTEN mov [ebx + SOCKET.TCBState], TCB_LISTEN
jmp .exit jmp .signal
.check_ack: .check_ack:
; Look at control flags - expecting an ACK ; Look at control flags - expecting an ACK
@ -833,6 +867,8 @@ proc stateTCB_SYN_RECEIVED stdcall, sockAddr:DWORD
jz .exit jz .exit
mov [ebx + SOCKET.TCBState], TCB_ESTABLISHED mov [ebx + SOCKET.TCBState], TCB_ESTABLISHED
.signal:
call signal_network_event
.exit: .exit:
ret ret
@ -843,6 +879,15 @@ proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
; Here we are expecting data, or a request to close ; Here we are expecting data, or a request to close
; OR both... ; OR both...
; Ignore all packets with sequnce number other than next expected
; recv.nxt is in dword [edx+24], in inet format
; recv seq is in [sktAddr]+56, in inet format
; just do a comparision
mov eax, [ebx + SOCKET.RCV_NXT]
cmp eax, [edx + 20 + TCP_PACKET.SequenceNumber]
jne .exit
; Did we receive a FIN or RST? ; Did we receive a FIN or RST?
test [edx + 20 + TCP_PACKET.Flags], TH_FIN test [edx + 20 + TCP_PACKET.Flags], TH_FIN
jz .check_ack jz .check_ack
@ -878,6 +923,7 @@ proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
@@: ; Send an ACK to that fin, and enter closewait state @@: ; Send an ACK to that fin, and enter closewait state
mov [ebx + SOCKET.TCBState], TCB_CLOSE_WAIT mov [ebx + SOCKET.TCBState], TCB_CLOSE_WAIT
call signal_network_event
lea esi, [ebx + SOCKET.RCV_NXT] lea esi, [ebx + SOCKET.RCV_NXT]
mov eax, [esi] ; save original mov eax, [esi] ; save original
call inc_inet_esi call inc_inet_esi
@ -900,21 +946,6 @@ proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
mov [ebx + SOCKET.wndsizeTimer], 1 mov [ebx + SOCKET.wndsizeTimer], 1
@@: ; OK, here is the deal @@: ; OK, here is the deal
; My recv.nct field holds the seq of the expected next rec byte
; if the recevied sequence number is not equal to this, do not
; increment the recv.nxt field, do not copy data - just send a
; repeat ack.
; recv.nxt is in dword [edx+24], in inet format
; recv seq is in [sktAddr]+56, in inet format
; just do a comparision
mov ecx, [ebx + SOCKET.RCV_NXT]
cmp [ebx + SOCKET.TCBState], TCB_CLOSE_WAIT
jne @f
mov ecx, eax
@@: cmp ecx, [edx + 20 + TCP_PACKET.SequenceNumber]
jne .ack
; Read the data bytes, store in socket buffer ; Read the data bytes, store in socket buffer
@ -935,7 +966,7 @@ proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
pop ebx pop ebx
push ecx push ecx
push [ebx + SOCKET.PID] ; get socket owner PID push ebx
mov eax, [ebx + SOCKET.rxDataCount] mov eax, [ebx + SOCKET.rxDataCount]
add eax, ecx add eax, ecx
cmp eax, SOCKETBUFFSIZE - SOCKETHEADERSIZE cmp eax, SOCKETBUFFSIZE - SOCKETHEADERSIZE
@ -955,21 +986,8 @@ proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
mov [ebx + SOCKET.lock], 0 ; release mutex mov [ebx + SOCKET.lock], 0 ; release mutex
; flag an event to the application ; flag an event to the application
pop eax pop ebx
mov ecx, 1 call signal_network_event
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
.found_pid:
shl ecx, 8
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event
pop ecx pop ecx