Preparing to implement TCP reassembly queue.

Some cleanup of tcp_input and skip checksum recalculation for loopback segments. 

git-svn-id: svn://kolibrios.org@3406 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2013-03-23 14:02:38 +00:00
parent 372fe91892
commit 4398dd7c40
4 changed files with 77 additions and 39 deletions

View File

@ -137,6 +137,8 @@ struct TCP_SOCKET IP_SOCKET
ts_ecr dd ? ; timestamp echo reply ts_ecr dd ? ; timestamp echo reply
ts_val dd ? ts_val dd ?
seg_next dd ? ; re-assembly queue
temp_bits db ? temp_bits db ?
rb 3 ; align rb 3 ; align
@ -481,7 +483,7 @@ SOCKET_connect:
.af_inet4: .af_inet4:
cmp [eax + IP_SOCKET.LocalIP], 0 cmp [eax + IP_SOCKET.LocalIP], 0
jne @f jne @f
push [IP_LIST] push [IP_LIST] ; FIXME
pop [eax + IP_SOCKET.LocalIP] pop [eax + IP_SOCKET.LocalIP]
@@: @@:

View File

@ -123,7 +123,7 @@ struct TCP_queue_entry
device_ptr dd ? device_ptr dd ?
buffer_ptr dd ? buffer_ptr dd ?
buffer_size dd ? timestamp dd ?
ends ends

View File

@ -73,6 +73,7 @@ TCP_input:
align 4 align 4
TCP_process_input: TCP_process_input:
@ -81,36 +82,28 @@ TCP_process_input:
call create_event call create_event
mov [TCP_input_event], eax mov [TCP_input_event], eax
.loop: .wait:
mov eax, [TCP_input_event] mov eax, [TCP_input_event]
call wait_event call wait_event
get_from_queue TCP_queue, TCP_QUEUE_SIZE, sizeof.TCP_queue_entry, .loop .loop:
get_from_queue TCP_queue, TCP_QUEUE_SIZE, sizeof.TCP_queue_entry, .wait
push .loop push [esi + TCP_queue_entry.timestamp]
push [esi + TCP_queue_entry.buffer_size]
push [esi + TCP_queue_entry.buffer_ptr] push [esi + TCP_queue_entry.buffer_ptr]
mov ebx, [esi + TCP_queue_entry.device_ptr] mov ebx, [esi + TCP_queue_entry.device_ptr]
mov ecx, [esi + TCP_queue_entry.segment_size] mov ecx, [esi + TCP_queue_entry.segment_size]
mov edi, [esi + TCP_queue_entry.ip_ptr] mov edi, [esi + TCP_queue_entry.ip_ptr] ; ptr to ipv4 source address, followed by ipv4 destination address
mov esi, [esi + TCP_queue_entry.segment_ptr] ; change esi last mov esi, [esi + TCP_queue_entry.segment_ptr] ; change esi last
;-----------------------------------------------------------------
;
; IN: [esp] = ptr to buffer
; [esp+4] = timestamp when segment was received
; ebx = ptr to device struct
; ecx = segment size
; esi = ptr to TCP segment
; edi = ptr to ipv4 source address, followed by ipv4 dest address
;
; OUT: /
;
;-----------------------------------------------------------------
DEBUGF 1,"TCP_input: size=%u time=%d\n", ecx, [timer_ticks] DEBUGF 1,"TCP_input: size=%u time=%d\n", ecx, [timer_ticks]
mov edx, esi
cmp ebx, LOOPBACK_DEVICE
je .checksum_ok
; re-calculate the checksum (if not already done by hw) ; 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
; jnz .checksum_ok ; jnz .checksum_ok
@ -171,7 +164,7 @@ TCP_process_input:
jne .socket_loop jne .socket_loop
mov eax, [ebx + IP_SOCKET.RemoteIP] mov eax, [ebx + IP_SOCKET.RemoteIP]
cmp eax, [edi] ; Ipv4 source addres cmp eax, [edi] ; Ipv4 source address
je @f je @f
test eax, eax test eax, eax
jnz .socket_loop jnz .socket_loop
@ -580,7 +573,7 @@ TCP_process_input:
;---------------------------- ;----------------------------
; trim any data not in window ; trim any data not in window
; check for duplicate data at beginning of segment ; check for duplicate data at beginning of segment (635)
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]
@ -606,7 +599,7 @@ TCP_process_input:
dec eax dec eax
.no_dup_syn: .no_dup_syn:
; Check for entire duplicate segment ; Check for entire duplicate segment (646)
cmp eax, ecx ; eax holds number of bytes to drop, ecx is data size cmp eax, ecx ; eax holds number of bytes to drop, ecx is data size
jb .duplicate jb .duplicate
jnz @f jnz @f
@ -620,6 +613,7 @@ TCP_process_input:
; send an ACK and resynchronize and drop any data. ; send an ACK and resynchronize and drop any data.
; But keep on processing for RST or ACK ; But keep on processing for RST or ACK
DEBUGF 1, "616\n"
or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
mov eax, ecx mov eax, ecx
;TODO: update stats ;TODO: update stats
@ -639,7 +633,7 @@ TCP_process_input:
@@: @@:
;-------------------------------------------------- ;--------------------------------------------------
; Handle data that arrives after process terminates ; Handle data that arrives after process terminates (687)
.no_duplicate: .no_duplicate:
cmp [ebx + SOCKET.PID], 0 cmp [ebx + SOCKET.PID], 0
@ -693,6 +687,7 @@ TCP_process_input:
cmp eax, [ebx + TCP_SOCKET.RCV_NXT] cmp eax, [ebx + TCP_SOCKET.RCV_NXT]
jne .drop_after_ack jne .drop_after_ack
DEBUGF 1, "690\n"
or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
;;; TODO: update stats ;;; TODO: update stats
jmp .no_excess_data jmp .no_excess_data
@ -704,18 +699,6 @@ TCP_process_input:
and [ebx + TCP_SOCKET.t_flags], not (TH_PUSH or TH_FIN) and [ebx + TCP_SOCKET.t_flags], not (TH_PUSH or TH_FIN)
.no_excess_data: .no_excess_data:
;--------------------- FIXME -------------------
pusha
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
add [ebx + TCP_SOCKET.RCV_NXT], ecx ; Update sequence number with number of bytes we have copied
popa
;--------------------- FIXME --------------------
;----------------- ;-----------------
; Record timestamp (737-746) ; Record timestamp (737-746)
@ -1447,7 +1430,47 @@ align 4
jnz .final_processing jnz .final_processing
@@: @@:
; call TCP_reassemble ;;; TODO
; The segment is in order?
mov eax, [edx + TCP_header.SequenceNumber]
cmp eax, [ebx + TCP_SOCKET.RCV_NXT]
jne .out_of_order
; The reassembly queue is empty?
cmp [ebx + TCP_SOCKET.seg_next], 0
jne .out_of_order
; The connection is established?
cmp [ebx + TCP_SOCKET.t_state], TCPS_ESTABLISHED
jne .out_of_order
; Ok, lets do this.. Set delayed ACK flag and copy data into socket buffer
or [ebx + TCP_SOCKET.t_flags], TF_DELACK
pusha
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
add [ebx + TCP_SOCKET.RCV_NXT], ecx ; Update sequence number with number of bytes we have copied
popa
; Wake up the sleeping process
mov eax, ebx
call SOCKET_notify
jmp .data_done
.out_of_order:
; Uh-oh, some data is out of order, lets call TCP reassemble for help
call TCP_reassemble
DEBUGF 1, "1470\n"
or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
.data_done:
;--------------- ;---------------
; FIN processing ; FIN processing
@ -1571,7 +1594,7 @@ align 4
call kernel_free call kernel_free
add esp, 4 add esp, 4
ret jmp .loop
;--------- ;---------
; Respond ; Respond
@ -1637,4 +1660,4 @@ align 4
call kernel_free call kernel_free
add esp, 4 add esp, 4
ret jmp .loop

View File

@ -530,3 +530,16 @@ TCP_mss:
ret ret
; ebx = socket ptr
; edx = segment ptr
align 4
TCP_reassemble:
ret