forked from KolibriOS/kolibrios
rewrote TCP option parser, added SACK, moved connection accepter to run before option parser.
git-svn-id: svn://kolibrios.org@2954 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
eaebc59a11
commit
c10e7c783c
@ -159,7 +159,35 @@ TCP_input:
|
|||||||
; Are we accepting incoming connections?
|
; Are we accepting incoming connections?
|
||||||
|
|
||||||
test [ebx + SOCKET.options], SO_ACCEPTCON
|
test [ebx + SOCKET.options], SO_ACCEPTCON
|
||||||
jnz .accept_connection
|
jz .no_accept
|
||||||
|
|
||||||
|
DEBUGF 1,"TCP_input: Accepting new connection\n"
|
||||||
|
|
||||||
|
pusha
|
||||||
|
lea ecx, [ebx + SOCKET.mutex]
|
||||||
|
call mutex_unlock
|
||||||
|
popa
|
||||||
|
|
||||||
|
push ecx edx esi edi ;;;
|
||||||
|
call SOCKET_fork
|
||||||
|
pop edi esi edx ecx
|
||||||
|
|
||||||
|
test eax, eax
|
||||||
|
jz .drop_no_socket
|
||||||
|
|
||||||
|
mov ebx, eax
|
||||||
|
|
||||||
|
mov [ebx + TCP_SOCKET.temp_bits], TCP_BIT_DROPSOCKET ;;; FIXME: should we take over bits from previous socket?
|
||||||
|
|
||||||
|
push dword [edi + 4] ; Ipv4 destination addres
|
||||||
|
pop [ebx + IP_SOCKET.LocalIP]
|
||||||
|
|
||||||
|
push [edx + TCP_header.DestinationPort]
|
||||||
|
pop [ebx + TCP_SOCKET.LocalPort]
|
||||||
|
|
||||||
|
mov [ebx + TCP_SOCKET.t_state], TCPS_LISTEN
|
||||||
|
.no_accept:
|
||||||
|
|
||||||
|
|
||||||
;-------------------------------------
|
;-------------------------------------
|
||||||
; Reset idle timer and keepalive timer
|
; Reset idle timer and keepalive timer
|
||||||
@ -170,85 +198,108 @@ TCP_input:
|
|||||||
;--------------------
|
;--------------------
|
||||||
; Process TCP options
|
; Process TCP options
|
||||||
|
|
||||||
movzx eax, [edx + TCP_header.DataOffset]
|
push ecx
|
||||||
cmp eax, sizeof.TCP_header ; Does header contain any options?
|
|
||||||
|
movzx ecx, [edx + TCP_header.DataOffset]
|
||||||
|
cmp ecx, sizeof.TCP_header ; Does header contain any options?
|
||||||
je .no_options
|
je .no_options
|
||||||
|
|
||||||
DEBUGF 1,"TCP_input: Segment has options\n"
|
DEBUGF 1,"TCP_input: Segment has options\n"
|
||||||
|
|
||||||
cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN ; no options when in listen state
|
;;; FIXME: for LISTEN, options should be called after we determined route, we need it for MSS
|
||||||
jz .not_uni_xfer ; also no header prediction
|
;;; cmp [ebx + TCP_SOCKET.t_state], TCPS_LISTEN ; no options when in listen state
|
||||||
|
;;; jz .not_uni_xfer ; also no header prediction
|
||||||
|
|
||||||
add eax, edx
|
add ecx, edx
|
||||||
lea esi, [edx + sizeof.TCP_header]
|
lea esi, [edx + sizeof.TCP_header]
|
||||||
|
|
||||||
.opt_loop:
|
.opt_loop:
|
||||||
cmp esi, eax ; are we scanning outside of header?
|
cmp esi, ecx ; are we scanning outside of header?
|
||||||
jae .no_options
|
jae .no_options
|
||||||
|
lodsb
|
||||||
cmp byte [esi], TCP_OPT_EOL ; end of option list?
|
cmp al, TCP_OPT_EOL ; end of option list?
|
||||||
jz .no_options
|
je .no_options
|
||||||
|
cmp al, TCP_OPT_NOP
|
||||||
cmp byte [esi], TCP_OPT_NOP ; nop ?
|
je .opt_loop
|
||||||
jz .opt_nop
|
cmp al, TCP_OPT_MAXSEG
|
||||||
|
|
||||||
cmp byte [esi], TCP_OPT_MAXSEG
|
|
||||||
je .opt_maxseg
|
je .opt_maxseg
|
||||||
|
cmp al, TCP_OPT_WINDOW
|
||||||
cmp byte [esi], TCP_OPT_WINDOW
|
|
||||||
je .opt_window
|
je .opt_window
|
||||||
|
cmp al, TCP_OPT_SACK_PERMIT
|
||||||
cmp byte [esi], TCP_OPT_TIMESTAMP
|
je .opt_sack_permit
|
||||||
|
; cmp al, TCP_OPT_SACK
|
||||||
|
; je .opt_sack
|
||||||
|
cmp al, TCP_OPT_TIMESTAMP
|
||||||
je .opt_timestamp
|
je .opt_timestamp
|
||||||
|
DEBUGF 1,"TCP_input: unknown option:%u\n", al
|
||||||
jmp .no_options ; If we reach here, some unknown options were received, skip them all!
|
jmp .no_options ; If we reach here, some unknown options were received, skip them all!
|
||||||
|
|
||||||
.opt_nop:
|
|
||||||
inc esi
|
|
||||||
jmp .opt_loop
|
|
||||||
|
|
||||||
.opt_maxseg:
|
.opt_maxseg:
|
||||||
cmp byte [esi+1], 4
|
lodsb
|
||||||
|
cmp al, 4
|
||||||
jne .no_options ; error occured, ignore all options!
|
jne .no_options ; error occured, ignore all options!
|
||||||
|
|
||||||
test [edx + TCP_header.Flags], TH_SYN
|
test [edx + TCP_header.Flags], TH_SYN
|
||||||
jz @f
|
jz @f
|
||||||
|
|
||||||
movzx eax, word[esi+2]
|
lodsw
|
||||||
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
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
add esi, 4
|
|
||||||
jmp .opt_loop
|
jmp .opt_loop
|
||||||
|
|
||||||
|
|
||||||
.opt_window:
|
.opt_window:
|
||||||
cmp byte [esi+1], 3
|
lodsb
|
||||||
|
cmp al, 3
|
||||||
jne .no_options
|
jne .no_options
|
||||||
|
|
||||||
test [edx + TCP_header.Flags], TH_SYN
|
test [edx + TCP_header.Flags], TH_SYN
|
||||||
jz @f
|
jz @f
|
||||||
|
|
||||||
DEBUGF 1,"TCP_input: Got window option\n"
|
DEBUGF 1,"TCP_input: Got window scale option\n"
|
||||||
|
or [ebx + TCP_SOCKET.t_flags], TF_RCVD_SCALE
|
||||||
|
|
||||||
|
lodsb
|
||||||
|
mov [ebx + TCP_SOCKET.SND_SCALE], al
|
||||||
|
;;;;; TODO
|
||||||
|
|
||||||
|
@@:
|
||||||
|
jmp .opt_loop
|
||||||
|
|
||||||
|
|
||||||
|
.opt_sack_permit:
|
||||||
|
lodsb
|
||||||
|
cmp al, 2
|
||||||
|
jne .no_options
|
||||||
|
|
||||||
|
test [edx + TCP_header.Flags], TH_SYN
|
||||||
|
jz @f
|
||||||
|
|
||||||
|
DEBUGF 1,"TCP_input: Selective Acknowledgement permitted\n"
|
||||||
|
or [ebx + TCP_SOCKET.t_flags], TF_SACK_PERMIT
|
||||||
|
|
||||||
;;;;;
|
|
||||||
@@:
|
@@:
|
||||||
add esi, 3
|
|
||||||
jmp .opt_loop
|
jmp .opt_loop
|
||||||
|
|
||||||
|
|
||||||
.opt_timestamp:
|
.opt_timestamp:
|
||||||
cmp byte [esi+1], 10 ; length must be 10
|
lodsb
|
||||||
|
cmp al, 10 ; length must be 10
|
||||||
jne .no_options
|
jne .no_options
|
||||||
|
|
||||||
DEBUGF 1,"TCP_input: Got timestamp option\n"
|
DEBUGF 1,"TCP_input: Got timestamp option\n"
|
||||||
|
|
||||||
push dword [esi + 2] ; timestamp
|
test [edx + TCP_header.Flags], TH_SYN
|
||||||
pop [ebx + TCP_SOCKET.ts_val]
|
jz @f
|
||||||
push dword [esi + 6] ; timestamp echo reply
|
or [ebx + TCP_SOCKET.t_flags], TF_RCVD_TSTMP
|
||||||
pop [ebx + TCP_SOCKET.ts_ecr]
|
@@:
|
||||||
|
|
||||||
|
lodsd
|
||||||
|
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 [ebx + TCP_SOCKET.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!
|
||||||
@ -264,19 +315,19 @@ TCP_input:
|
|||||||
|
|
||||||
DEBUGF 1,"TCP_input: PAWS: detected an old segment\n"
|
DEBUGF 1,"TCP_input: PAWS: detected an old segment\n"
|
||||||
|
|
||||||
mov eax, [esp+4+4] ; tcp_now
|
mov eax, [esp+4+4+4] ; tcp_now
|
||||||
sub eax, [ebx + TCP_SOCKET.ts_recent_age]
|
sub eax, [ebx + TCP_SOCKET.ts_recent_age]
|
||||||
cmp eax, TCP_PAWS_IDLE
|
cmp eax, TCP_PAWS_IDLE
|
||||||
jle .drop_after_ack ; TODO: update stats
|
jle .drop_after_ack ; TODO: update stats
|
||||||
|
|
||||||
mov [ebx + TCP_SOCKET.ts_recent], 0 ; timestamp was invalid, fix it.
|
mov [ebx + TCP_SOCKET.ts_recent], 0 ; timestamp was invalid, fix it.
|
||||||
.no_paws:
|
.no_paws:
|
||||||
|
|
||||||
add esi, 10
|
|
||||||
jmp .opt_loop
|
jmp .opt_loop
|
||||||
|
|
||||||
.no_options:
|
.no_options:
|
||||||
|
|
||||||
|
pop ecx
|
||||||
|
|
||||||
;-----------------------------------------------------------------------
|
;-----------------------------------------------------------------------
|
||||||
; Time to do some header prediction (Original Principle by Van Jacobson)
|
; Time to do some header prediction (Original Principle by Van Jacobson)
|
||||||
|
|
||||||
@ -1038,37 +1089,8 @@ TCP_input:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
;-------------
|
|
||||||
; Passive Open
|
|
||||||
|
|
||||||
align 4
|
|
||||||
|
|
||||||
.accept_connection:
|
|
||||||
|
|
||||||
DEBUGF 1,"TCP_input: Accepting new connection\n"
|
|
||||||
|
|
||||||
pusha
|
|
||||||
lea ecx, [ebx + SOCKET.mutex]
|
|
||||||
call mutex_unlock
|
|
||||||
popa
|
|
||||||
|
|
||||||
push ecx edx esi edi ;;;
|
|
||||||
call SOCKET_fork
|
|
||||||
pop edi esi edx ecx
|
|
||||||
|
|
||||||
test eax, eax
|
|
||||||
jz .drop
|
|
||||||
|
|
||||||
mov [eax + TCP_SOCKET.temp_bits], TCP_BIT_DROPSOCKET ;;; FIXME: should we take over bits from previous socket?
|
|
||||||
|
|
||||||
push dword [edi + 4] ; Ipv4 destination addres
|
|
||||||
pop [eax + IP_SOCKET.LocalIP]
|
|
||||||
|
|
||||||
push [edx + TCP_header.DestinationPort]
|
|
||||||
pop [eax + TCP_SOCKET.LocalPort]
|
|
||||||
|
|
||||||
mov [eax + TCP_SOCKET.t_state], TCPS_LISTEN
|
|
||||||
mov ebx, eax
|
|
||||||
|
|
||||||
.LISTEN:
|
.LISTEN:
|
||||||
|
|
||||||
@ -1262,17 +1284,13 @@ align 4
|
|||||||
ja .no_window_update
|
ja .no_window_update
|
||||||
@@:
|
@@:
|
||||||
|
|
||||||
mov eax, [ebx + TCP_SOCKET.SND_WL2]
|
|
||||||
cmp eax, [edx + TCP_header.AckNumber]
|
|
||||||
jne .no_window_update
|
|
||||||
|
|
||||||
mov eax, dword [edx + TCP_header.Window]
|
mov eax, dword [edx + TCP_header.Window]
|
||||||
cmp eax, [ebx + TCP_SOCKET.SND_WND]
|
cmp eax, [ebx + TCP_SOCKET.SND_WND]
|
||||||
jbe .no_window_update
|
jbe .no_window_update
|
||||||
|
|
||||||
.update_window:
|
.update_window:
|
||||||
|
|
||||||
;;; TODO: Keep track of pure window updates
|
;;; TODO: update stats (Keep track of pure window updates)
|
||||||
|
|
||||||
mov eax, dword [edx + TCP_header.Window]
|
mov eax, dword [edx + TCP_header.Window]
|
||||||
cmp eax, [ebx + TCP_SOCKET.max_sndwnd]
|
cmp eax, [ebx + TCP_SOCKET.max_sndwnd]
|
||||||
@ -1293,12 +1311,6 @@ align 4
|
|||||||
|
|
||||||
.no_window_update:
|
.no_window_update:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;-----------------
|
;-----------------
|
||||||
; process URG flag
|
; process URG flag
|
||||||
|
|
||||||
@ -1464,6 +1476,7 @@ align 4
|
|||||||
DEBUGF 1,"TCP_input: ACK now!\n"
|
DEBUGF 1,"TCP_input: ACK now!\n"
|
||||||
|
|
||||||
.need_output:
|
.need_output:
|
||||||
|
DEBUGF 1,"TCP_input: need output\n"
|
||||||
call TCP_output
|
call TCP_output
|
||||||
|
|
||||||
.dumpit:
|
.dumpit:
|
||||||
|
Loading…
Reference in New Issue
Block a user