forked from KolibriOS/kolibrios
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:
parent
df6a761ad4
commit
bf755d6cbd
@ -141,10 +141,6 @@ struct TCP_SOCKET IP_SOCKET
|
|||||||
|
|
||||||
seg_next dd ? ; re-assembly queue
|
seg_next dd ? ; re-assembly queue
|
||||||
|
|
||||||
temp_bits db ?
|
|
||||||
rb 3 ; align
|
|
||||||
|
|
||||||
|
|
||||||
ends
|
ends
|
||||||
|
|
||||||
struct UDP_SOCKET IP_SOCKET
|
struct UDP_SOCKET IP_SOCKET
|
||||||
|
@ -110,7 +110,7 @@ SS_MORETOCOME = 0x4000
|
|||||||
SS_BLOCKED = 0x8000
|
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
|
MAX_backlog = 20 ; maximum backlog for stream sockets
|
||||||
|
|
||||||
; Error Codes
|
; Error Codes
|
||||||
|
@ -83,6 +83,7 @@ proc TCP_process_input
|
|||||||
locals
|
locals
|
||||||
dataoffset dd ?
|
dataoffset dd ?
|
||||||
timestamp dd ?
|
timestamp dd ?
|
||||||
|
temp_bits db ?
|
||||||
endl
|
endl
|
||||||
|
|
||||||
xor esi, esi
|
xor esi, esi
|
||||||
@ -218,7 +219,7 @@ endl
|
|||||||
;---------------------------
|
;---------------------------
|
||||||
; disable all temporary bits
|
; disable all temporary bits
|
||||||
|
|
||||||
mov [ebx + TCP_SOCKET.temp_bits], 0
|
mov [temp_bits], 0
|
||||||
|
|
||||||
;---------------------------------------
|
;---------------------------------------
|
||||||
; unscale the window into a 32 bit value
|
; unscale the window into a 32 bit value
|
||||||
@ -252,7 +253,7 @@ endl
|
|||||||
|
|
||||||
mov ebx, eax
|
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
|
push dword [edi + 4] ; Ipv4 destination addres
|
||||||
pop [ebx + IP_SOCKET.LocalIP]
|
pop [ebx + IP_SOCKET.LocalIP]
|
||||||
@ -378,7 +379,7 @@ endl
|
|||||||
mov [ebx + TCP_SOCKET.ts_val], eax
|
mov [ebx + TCP_SOCKET.ts_val], eax
|
||||||
lodsd ; timestamp echo reply
|
lodsd ; timestamp echo reply
|
||||||
mov [ebx + TCP_SOCKET.ts_ecr], eax
|
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!
|
; Since we have a timestamp, lets do the paws test right away!
|
||||||
|
|
||||||
@ -483,7 +484,7 @@ endl
|
|||||||
|
|
||||||
; Update RTT estimators
|
; Update RTT estimators
|
||||||
|
|
||||||
test [ebx + TCP_SOCKET.temp_bits], TCP_BIT_TIMESTAMP
|
test [temp_bits], TCP_BIT_TIMESTAMP
|
||||||
jz .no_timestamp_rtt
|
jz .no_timestamp_rtt
|
||||||
mov eax, [timestamp]
|
mov eax, [timestamp]
|
||||||
sub eax, [ebx + TCP_SOCKET.ts_ecr]
|
sub eax, [ebx + TCP_SOCKET.ts_ecr]
|
||||||
@ -713,16 +714,16 @@ endl
|
|||||||
;;; TODO: update stats
|
;;; TODO: update stats
|
||||||
.dont_drop_all:
|
.dont_drop_all:
|
||||||
;;; TODO: update stats
|
;;; 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)
|
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:
|
.no_excess_data:
|
||||||
|
|
||||||
;-----------------
|
;-----------------
|
||||||
; Record timestamp
|
; Record timestamp
|
||||||
|
|
||||||
; If last ACK falls within this segments sequence numbers, record its 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
|
jz .no_timestamp
|
||||||
mov eax, [ebx + TCP_SOCKET.last_ack_sent]
|
mov eax, [ebx + TCP_SOCKET.last_ack_sent]
|
||||||
sub eax, [edx + TCP_header.SequenceNumber]
|
sub eax, [edx + TCP_header.SequenceNumber]
|
||||||
@ -1004,11 +1005,11 @@ endl
|
|||||||
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: acceptable ACK for %u bytes\n", edi
|
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
|
; 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
|
jz .timestamp_not_present
|
||||||
mov eax, [timestamp]
|
mov eax, [timestamp]
|
||||||
sub eax, [ebx + TCP_SOCKET.ts_ecr]
|
sub eax, [ebx + TCP_SOCKET.ts_ecr]
|
||||||
@ -1039,7 +1040,7 @@ endl
|
|||||||
cmp eax, [edx + TCP_header.AckNumber]
|
cmp eax, [edx + TCP_header.AckNumber]
|
||||||
jne .more_data
|
jne .more_data
|
||||||
and [ebx + TCP_SOCKET.timer_flags], not timer_flag_retransmission
|
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
|
jmp .no_restart
|
||||||
.more_data:
|
.more_data:
|
||||||
test [ebx + TCP_SOCKET.timer_flags], timer_flag_persist
|
test [ebx + TCP_SOCKET.timer_flags], timer_flag_persist
|
||||||
@ -1241,7 +1242,7 @@ align 4
|
|||||||
TCP_rcvseqinit ebx
|
TCP_rcvseqinit ebx
|
||||||
|
|
||||||
mov [ebx + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED
|
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
|
mov [ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval ;;;; macro
|
||||||
or [ebx + TCP_SOCKET.timer_flags], timer_flag_keepalive
|
or [ebx + TCP_SOCKET.timer_flags], timer_flag_keepalive
|
||||||
|
|
||||||
@ -1251,7 +1252,7 @@ align 4
|
|||||||
lea eax, [ebx + STREAM_SOCKET.rcv]
|
lea eax, [ebx + STREAM_SOCKET.rcv]
|
||||||
call SOCKET_ring_create
|
call SOCKET_ring_create
|
||||||
|
|
||||||
and [ebx + TCP_SOCKET.temp_bits], not TCP_BIT_DROPSOCKET
|
and [temp_bits], not TCP_BIT_DROPSOCKET
|
||||||
|
|
||||||
pusha
|
pusha
|
||||||
mov eax, ebx
|
mov eax, ebx
|
||||||
@ -1431,7 +1432,7 @@ align 4
|
|||||||
push [edx + TCP_header.AckNumber]
|
push [edx + TCP_header.AckNumber]
|
||||||
pop [ebx + TCP_SOCKET.SND_WL2]
|
pop [ebx + TCP_SOCKET.SND_WL2]
|
||||||
|
|
||||||
or [ebx + TCP_SOCKET.temp_bits], TCP_BIT_NEEDOUTPUT
|
or [temp_bits], TCP_BIT_NEEDOUTPUT
|
||||||
|
|
||||||
.no_window_update:
|
.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,
|
; 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.
|
; and to tell it what sequence number is expected. This aids the fast-retransmit algorithm.
|
||||||
or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
|
or [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
|
||||||
|
|
||||||
.data_done:
|
.data_done:
|
||||||
|
|
||||||
;---------------
|
;---------------
|
||||||
@ -1540,7 +1540,7 @@ align 4
|
|||||||
mov eax, ebx
|
mov eax, ebx
|
||||||
call SOCKET_cant_recv_more
|
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]
|
inc [ebx + TCP_SOCKET.RCV_NXT]
|
||||||
|
|
||||||
.not_first_fin:
|
.not_first_fin:
|
||||||
@ -1562,29 +1562,54 @@ align 4
|
|||||||
dd .fin_timed ; TCPS_TIMED_WAIT
|
dd .fin_timed ; TCPS_TIMED_WAIT
|
||||||
|
|
||||||
.fin_syn_est:
|
.fin_syn_est:
|
||||||
|
|
||||||
mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT
|
mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT
|
||||||
jmp .final_processing
|
jmp .final_processing
|
||||||
|
|
||||||
.fin_wait1:
|
.fin_wait1:
|
||||||
|
|
||||||
mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSING
|
mov [ebx + TCP_SOCKET.t_state], TCPS_CLOSING
|
||||||
jmp .final_processing
|
jmp .final_processing
|
||||||
|
|
||||||
.fin_wait2:
|
.fin_wait2:
|
||||||
|
|
||||||
mov [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT
|
mov [ebx + TCP_SOCKET.t_state], TCPS_TIMED_WAIT
|
||||||
mov eax, ebx
|
mov eax, ebx
|
||||||
call TCP_cancel_timers
|
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
|
call SOCKET_is_disconnected
|
||||||
jmp .final_processing
|
|
||||||
|
|
||||||
.fin_timed:
|
.fin_timed:
|
||||||
mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL
|
mov [ebx + TCP_SOCKET.timer_timed_wait], 2 * TCP_time_MSL
|
||||||
or [ebx + TCP_SOCKET.timer_flags], timer_flag_wait
|
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:
|
.drop_after_ack:
|
||||||
@ -1621,34 +1646,6 @@ align 4
|
|||||||
jnz .respond_syn
|
jnz .respond_syn
|
||||||
jmp .dumpit
|
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
|
; Respond
|
||||||
|
|
||||||
@ -1709,7 +1706,7 @@ align 4
|
|||||||
popa
|
popa
|
||||||
|
|
||||||
.destroy_new_socket:
|
.destroy_new_socket:
|
||||||
test [ebx + TCP_SOCKET.temp_bits], TCP_BIT_DROPSOCKET
|
test [temp_bits], TCP_BIT_DROPSOCKET
|
||||||
jz .drop_no_socket
|
jz .drop_no_socket
|
||||||
|
|
||||||
mov eax, ebx
|
mov eax, ebx
|
||||||
|
@ -26,7 +26,11 @@ $Revision: 3289 $
|
|||||||
;
|
;
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
align 4
|
align 4
|
||||||
TCP_output:
|
proc TCP_output
|
||||||
|
|
||||||
|
locals
|
||||||
|
temp_bits db ?
|
||||||
|
endl
|
||||||
|
|
||||||
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: socket=%x\n", eax
|
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_output: socket=%x\n", eax
|
||||||
|
|
||||||
@ -57,7 +61,7 @@ TCP_output:
|
|||||||
|
|
||||||
.not_idle:
|
.not_idle:
|
||||||
.again:
|
.again:
|
||||||
mov [eax + TCP_SOCKET.temp_bits], 0
|
mov [temp_bits], 0
|
||||||
|
|
||||||
mov ebx, [eax + TCP_SOCKET.SND_NXT] ; calculate offset (71)
|
mov ebx, [eax + TCP_SOCKET.SND_NXT] ; calculate offset (71)
|
||||||
sub ebx, [eax + TCP_SOCKET.SND_UNA] ;
|
sub ebx, [eax + TCP_SOCKET.SND_UNA] ;
|
||||||
@ -145,7 +149,7 @@ TCP_output:
|
|||||||
jbe @f
|
jbe @f
|
||||||
|
|
||||||
mov esi, [eax + TCP_SOCKET.t_maxseg]
|
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
|
jbe .no_overflow
|
||||||
|
|
||||||
mov esi, [eax + TCP_SOCKET.t_maxseg]
|
mov esi, [eax + TCP_SOCKET.t_maxseg]
|
||||||
or [eax + TCP_SOCKET.temp_bits], TCP_BIT_SENDALOT
|
or [temp_bits], TCP_BIT_SENDALOT
|
||||||
.no_overflow:
|
.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
|
; Start by pushing all TCP header values in reverse order on stack
|
||||||
; (essentially, creating the tcp header on the stack!)
|
; (essentially, creating the tcp header on the stack!)
|
||||||
|
|
||||||
pushw 0 ; .UrgentPointer dw ?
|
pushw 0 ; .UrgentPointer dw ?
|
||||||
pushw 0 ; .Checksum 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 edi, 2 ; .DataOffset db ? only 4 left-most bits
|
||||||
shl dx, 8
|
shl dx, 8
|
||||||
or dx, di ; .Flags db ?
|
or dx, di ; .Flags db ?
|
||||||
@ -566,7 +602,7 @@ TCP_send:
|
|||||||
push [eax + TCP_SOCKET.RCV_NXT]
|
push [eax + TCP_SOCKET.RCV_NXT]
|
||||||
pop [eax + TCP_SOCKET.last_ack_sent]
|
pop [eax + TCP_SOCKET.last_ack_sent]
|
||||||
|
|
||||||
; and flags
|
; clear the ACK flags
|
||||||
and [eax + TCP_SOCKET.t_flags], not (TF_ACKNOW + TF_DELACK)
|
and [eax + TCP_SOCKET.t_flags], not (TF_ACKNOW + TF_DELACK)
|
||||||
|
|
||||||
;--------------
|
;--------------
|
||||||
@ -582,7 +618,7 @@ TCP_send:
|
|||||||
;-----------------------------
|
;-----------------------------
|
||||||
; Check if we need more output
|
; 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
|
jnz TCP_output.again
|
||||||
|
|
||||||
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: success!\n"
|
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: success!\n"
|
||||||
@ -622,7 +658,4 @@ TCP_send:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user