TCP: advertise correct window, small updates and bugfixes

git-svn-id: svn://kolibrios.org@4347 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2013-12-13 12:20:53 +00:00
parent df6a761ad4
commit bf755d6cbd
4 changed files with 93 additions and 67 deletions

View File

@ -141,10 +141,6 @@ struct TCP_SOCKET IP_SOCKET
seg_next dd ? ; re-assembly queue
temp_bits db ?
rb 3 ; align
ends
struct UDP_SOCKET IP_SOCKET

View File

@ -110,7 +110,7 @@ SS_MORETOCOME = 0x4000
SS_BLOCKED = 0x8000
SOCKET_MAXDATA = 4096*32 ; must be 4096*(power of 2) where 'power of 2' is at least 8
SOCKET_MAXDATA = 4096*8 ; must be 4096*(power of 2) where 'power of 2' is at least 8
MAX_backlog = 20 ; maximum backlog for stream sockets
; Error Codes

View File

@ -83,6 +83,7 @@ proc TCP_process_input
locals
dataoffset dd ?
timestamp dd ?
temp_bits db ?
endl
xor esi, esi
@ -218,7 +219,7 @@ endl
;---------------------------
; disable all temporary bits
mov [ebx + TCP_SOCKET.temp_bits], 0
mov [temp_bits], 0
;---------------------------------------
; unscale the window into a 32 bit value
@ -252,7 +253,7 @@ endl
mov ebx, eax
mov [ebx + TCP_SOCKET.temp_bits], TCP_BIT_DROPSOCKET ;;; FIXME: should we take over bits from previous socket?
mov [temp_bits], TCP_BIT_DROPSOCKET
push dword [edi + 4] ; Ipv4 destination addres
pop [ebx + IP_SOCKET.LocalIP]
@ -378,7 +379,7 @@ endl
mov [ebx + TCP_SOCKET.ts_val], eax
lodsd ; timestamp echo reply
mov [ebx + TCP_SOCKET.ts_ecr], eax
or [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP
or [temp_bits], TCP_BIT_TIMESTAMP
; Since we have a timestamp, lets do the paws test right away!
@ -483,7 +484,7 @@ endl
; Update RTT estimators
test [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP
test [temp_bits], TCP_BIT_TIMESTAMP
jz .no_timestamp_rtt
mov eax, [timestamp]
sub eax, [ebx + TCP_SOCKET.ts_ecr]
@ -713,16 +714,16 @@ endl
;;; TODO: update stats
.dont_drop_all:
;;; TODO: update stats
DEBUGF 1, "Trimming %u bytes from the right of the window\n"
DEBUGF DEBUG_NETWORK_VERBOSE, "Trimming %u bytes from the right of the window\n"
sub ecx, eax ; remove data from the right side of window (decrease data length)
and [ebx + TCP_SOCKET.t_flags], not (TH_PUSH or TH_FIN)
and [edx + TCP_header.Flags], not (TH_PUSH or TH_FIN)
.no_excess_data:
;-----------------
; Record timestamp
; If last ACK falls within this segments sequence numbers, record its timestamp
test [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP
test [temp_bits], TCP_BIT_TIMESTAMP
jz .no_timestamp
mov eax, [ebx + TCP_SOCKET.last_ack_sent]
sub eax, [edx + TCP_header.SequenceNumber]
@ -1004,11 +1005,11 @@ endl
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: acceptable ACK for %u bytes\n", edi
;------------------------------------------
; RTT measurements and retransmission timer (912-926)
; RTT measurements and retransmission timer
; If we have a timestamp, update smoothed RTT
test [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP
test [temp_bits], TCP_BIT_TIMESTAMP
jz .timestamp_not_present
mov eax, [timestamp]
sub eax, [ebx + TCP_SOCKET.ts_ecr]
@ -1039,7 +1040,7 @@ endl
cmp eax, [edx + TCP_header.AckNumber]
jne .more_data
and [ebx + TCP_SOCKET.timer_flags], not timer_flag_retransmission
or [ebx + TCP_SOCKET.temp_bits], TCP_BIT_NEEDOUTPUT
or [temp_bits], TCP_BIT_NEEDOUTPUT
jmp .no_restart
.more_data:
test [ebx + TCP_SOCKET.timer_flags], timer_flag_persist
@ -1241,7 +1242,7 @@ align 4
TCP_rcvseqinit ebx
mov [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED
mov [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval ;;;; macro
or [ebx + TCP_SOCKET.timer_flags], timer_flag_keepalive
@ -1251,7 +1252,7 @@ align 4
lea eax, [ebx + STREAM_SOCKET.rcv]
call SOCKET_ring_create
and [ebx + TCP_SOCKET.temp_bits], not TCP_BIT_DROPSOCKET
and [temp_bits], not TCP_BIT_DROPSOCKET
pusha
mov eax, ebx
@ -1431,7 +1432,7 @@ align 4
push [edx + TCP_header.AckNumber]
pop [ebx + TCP_SOCKET.SND_WL2]
or [ebx + TCP_SOCKET.temp_bits], TCP_BIT_NEEDOUTPUT
or [temp_bits], TCP_BIT_NEEDOUTPUT
.no_window_update:
@ -1521,7 +1522,6 @@ align 4
; Generate ACK immediately, to let the other end know that a segment was received out of order,
; and to tell it what sequence number is expected. This aids the fast-retransmit algorithm.
or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
.data_done:
;---------------
@ -1540,7 +1540,7 @@ align 4
mov eax, ebx
call SOCKET_cant_recv_more
mov [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
inc [ebx + TCP_SOCKET.RCV_NXT]
.not_first_fin:
@ -1562,29 +1562,54 @@ align 4
dd .fin_timed ; TCPS_TIMED_WAIT
.fin_syn_est:
mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT
jmp .final_processing
.fin_wait1:
mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSING
jmp .final_processing
.fin_wait2:
mov [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT
mov eax, ebx
call TCP_cancel_timers
mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL
or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait
call SOCKET_is_disconnected
jmp .final_processing
.fin_timed:
mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL
or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait
jmp .final_processing
;-----------------
; Final processing
.final_processing:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Final processing\n"
push ebx
lea ecx, [ebx + SOCKET.mutex]
call mutex_unlock
pop eax
test [temp_bits], TCP_BIT_NEEDOUTPUT
jnz .need_output
test [eax + TCP_SOCKET.t_flags], TF_ACKNOW
jz .dumpit
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: ACK now!\n"
.need_output:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: need output\n"
call TCP_output
.dumpit:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: dumping\n"
call NET_packet_free
jmp .loop
;-----------------
; Drop the segment
.drop_after_ack:
@ -1621,34 +1646,6 @@ align 4
jnz .respond_syn
jmp .dumpit
;-----------------
; Final processing
.final_processing:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: Final processing\n"
push ebx
lea ecx, [ebx + SOCKET.mutex]
call mutex_unlock
pop eax
test [eax + TCP_SOCKET.temp_bits], TCP_BIT_NEEDOUTPUT
jnz .need_output
test [eax + TCP_SOCKET.t_flags], TF_ACKNOW
jz .dumpit
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: ACK now!\n"
.need_output:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: need output\n"
call TCP_output
.dumpit:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: dumping\n"
call NET_packet_free
jmp .loop
;---------
; Respond
@ -1709,7 +1706,7 @@ align 4
popa
.destroy_new_socket:
test [ebx + TCP_SOCKET.temp_bits], TCP_BIT_DROPSOCKET
test [temp_bits], TCP_BIT_DROPSOCKET
jz .drop_no_socket
mov eax, ebx

View File

@ -26,7 +26,11 @@ $Revision: 3289 $
;
;-----------------------------------------------------------------
align 4
TCP_output:
proc TCP_output
locals
temp_bits db ?
endl
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: socket=%x\n", eax
@ -57,7 +61,7 @@ TCP_output:
.not_idle:
.again:
mov [eax + TCP_SOCKET.temp_bits], 0
mov [temp_bits], 0
mov ebx, [eax + TCP_SOCKET.SND_NXT] ; calculate offset (71)
sub ebx, [eax + TCP_SOCKET.SND_UNA] ;
@ -145,7 +149,7 @@ TCP_output:
jbe @f
mov esi, [eax + TCP_SOCKET.t_maxseg]
or [eax + TCP_SOCKET.temp_bits], TCP_BIT_SENDALOT
or [temp_bits], TCP_BIT_SENDALOT
@@:
;--------------------------------------------
@ -406,16 +410,48 @@ TCP_send:
jbe .no_overflow
mov esi, [eax + TCP_SOCKET.t_maxseg]
or [eax + TCP_SOCKET.temp_bits], TCP_BIT_SENDALOT
or [temp_bits], TCP_BIT_SENDALOT
.no_overflow:
;----------------------------------------------------
; Calculate the receive window.
; Dont shrink window, but avoid silly window syndrome
mov ebx, SOCKET_MAXDATA
sub ebx, [eax + STREAM_SOCKET.rcv.size]
cmp ebx, SOCKET_MAXDATA/4
jae @f
cmp ebx, [eax + TCP_SOCKET.t_maxseg]
jae @f
xor ebx, ebx
@@:
cmp ebx, TCP_max_win
jbe @f
mov ebx, TCP_max_win
@@:
mov ecx, [eax + TCP_SOCKET.RCV_ADV]
sub ecx, [eax + TCP_SOCKET.RCV_NXT]
cmp ebx, ecx
ja @f
mov ebx, ecx
@@:
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: window = %u\n", ebx
mov cl, [eax + TCP_SOCKET.RCV_SCALE]
shr ebx, cl
xchg bl, bh
;-----------------------------------------------------------------
; Start by pushing all TCP header values in reverse order on stack
; (essentially, creating the tcp header on the stack!)
pushw 0 ; .UrgentPointer dw ?
pushw 0 ; .Checksum dw ?
pushw 0x00a0 ; .Window dw ? ;;;;;;; FIXME (370)
pushw bx ; .Window dw ?
shl edi, 2 ; .DataOffset db ? only 4 left-most bits
shl dx, 8
or dx, di ; .Flags db ?
@ -566,7 +602,7 @@ TCP_send:
push [eax + TCP_SOCKET.RCV_NXT]
pop [eax + TCP_SOCKET.last_ack_sent]
; and flags
; clear the ACK flags
and [eax + TCP_SOCKET.t_flags], not (TF_ACKNOW + TF_DELACK)
;--------------
@ -582,7 +618,7 @@ TCP_send:
;-----------------------------
; Check if we need more output
test [eax + TCP_SOCKET.temp_bits], TCP_BIT_SENDALOT
test [temp_bits], TCP_BIT_SENDALOT
jnz TCP_output.again
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: success!\n"
@ -622,7 +658,4 @@ TCP_send:
ret
endp