forked from KolibriOS/kolibrios
Updates in TCP code of net branch
git-svn-id: svn://kolibrios.org@1533 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
b2bef64328
commit
b90d3b7f56
@ -506,16 +506,18 @@ ARP_IP_to_MAC:
|
|||||||
|
|
||||||
;; TODO: check if driver could transmit packet
|
;; TODO: check if driver could transmit packet
|
||||||
|
|
||||||
pop eax
|
pop esi
|
||||||
imul eax, ARP_ENTRY.size
|
imul esi, ARP_ENTRY.size
|
||||||
add eax, ARP_table
|
add esi, ARP_table
|
||||||
|
|
||||||
mov ecx, 25
|
mov ecx, 25
|
||||||
.wait_loop:
|
.wait_loop:
|
||||||
cmp [eax + ARP_ENTRY.Status], 1
|
cmp [esi + ARP_ENTRY.Status], 1
|
||||||
je .got_it
|
je .got_it
|
||||||
|
push esi
|
||||||
mov esi, 10
|
mov esi, 10
|
||||||
call delay_ms
|
call delay_ms
|
||||||
|
pop esi
|
||||||
loop .wait_loop
|
loop .wait_loop
|
||||||
|
|
||||||
mov eax, -2 ; request send
|
mov eax, -2 ; request send
|
||||||
|
@ -169,6 +169,7 @@ struc RING_BUFFER {
|
|||||||
.read_ptr dd ? ; Read pointer
|
.read_ptr dd ? ; Read pointer
|
||||||
.write_ptr dd ? ; Write pointer
|
.write_ptr dd ? ; Write pointer
|
||||||
.size dd ? ; Number of bytes buffered
|
.size dd ? ; Number of bytes buffered
|
||||||
|
.end:
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual at 0
|
virtual at 0
|
||||||
@ -179,10 +180,9 @@ end virtual
|
|||||||
|
|
||||||
virtual at TCP_SOCKET.end
|
virtual at TCP_SOCKET.end
|
||||||
|
|
||||||
rcv RING_BUFFER
|
|
||||||
snd RING_BUFFER
|
|
||||||
|
|
||||||
STREAM_SOCKET:
|
STREAM_SOCKET:
|
||||||
|
.rcv rd RING_BUFFER.end/4
|
||||||
|
.snd rd RING_BUFFER.end/4
|
||||||
.end:
|
.end:
|
||||||
|
|
||||||
end virtual
|
end virtual
|
||||||
@ -221,21 +221,12 @@ macro SOCKET_init {
|
|||||||
mov ecx, 4
|
mov ecx, 4
|
||||||
rep stosd
|
rep stosd
|
||||||
|
|
||||||
;--- for random port --
|
|
||||||
|
|
||||||
mov al, 0x0 ; set up 1s timer
|
|
||||||
out 0x70, al
|
|
||||||
in al, 0x71
|
|
||||||
|
|
||||||
;----------------------
|
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
pseudo_random eax
|
pseudo_random eax
|
||||||
cmp ax, MIN_EPHEMERAL_PORT
|
cmp ax, MIN_EPHEMERAL_PORT
|
||||||
jl @r
|
jl @r
|
||||||
cmp ax, MAX_EPHEMERAL_PORT
|
cmp ax, MAX_EPHEMERAL_PORT
|
||||||
jg @r
|
jg @r
|
||||||
|
|
||||||
mov [last_UDP_port], ax
|
mov [last_UDP_port], ax
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
@ -244,7 +235,6 @@ macro SOCKET_init {
|
|||||||
jl @r
|
jl @r
|
||||||
cmp ax, MAX_EPHEMERAL_PORT
|
cmp ax, MAX_EPHEMERAL_PORT
|
||||||
jg @r
|
jg @r
|
||||||
|
|
||||||
mov [last_TCP_port], ax
|
mov [last_TCP_port], ax
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -318,22 +308,13 @@ SOCKET_open:
|
|||||||
cmp edx, IP_PROTO_TCP
|
cmp edx, IP_PROTO_TCP
|
||||||
jnz .no_stream
|
jnz .no_stream
|
||||||
|
|
||||||
mov esi, eax
|
mov ebx, eax
|
||||||
stdcall kernel_alloc, SOCKET_MAXDATA
|
|
||||||
mov [esi + rcv.start_ptr], eax
|
|
||||||
mov [esi + rcv.write_ptr], eax
|
|
||||||
mov [esi + rcv.read_ptr], eax
|
|
||||||
mov [esi + rcv.size], 0
|
|
||||||
add eax, SOCKET_MAXDATA
|
|
||||||
mov [esi + rcv.end_ptr], eax
|
|
||||||
|
|
||||||
stdcall kernel_alloc, SOCKET_MAXDATA
|
lea eax, [ebx + STREAM_SOCKET.snd]
|
||||||
mov [esi + snd.start_ptr], eax
|
call SOCKET_ring_create
|
||||||
mov [esi + snd.write_ptr], eax
|
|
||||||
mov [esi + snd.read_ptr], eax
|
lea eax, [ebx + STREAM_SOCKET.rcv]
|
||||||
mov [esi + snd.size], 0
|
call SOCKET_ring_create
|
||||||
add eax, SOCKET_MAXDATA
|
|
||||||
mov [esi + snd.end_ptr], eax
|
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -497,9 +478,11 @@ SOCKET_connect:
|
|||||||
mov ebx, [TCP_sequence_num]
|
mov ebx, [TCP_sequence_num]
|
||||||
add [TCP_sequence_num], 6400
|
add [TCP_sequence_num], 6400
|
||||||
mov [eax + TCP_SOCKET.ISS], ebx
|
mov [eax + TCP_SOCKET.ISS], ebx
|
||||||
mov [eax + TCP_SOCKET.timer_keepalive], 120 ; 120*640ms => 75,6 seconds
|
mov [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init
|
||||||
|
|
||||||
;;;; mov [ebx + TCP_SOCKET.timer_retransmission],
|
TCP_sendseqinit eax
|
||||||
|
|
||||||
|
;;;; mov [ebx + TCP_SOCKET.timer_retransmission], ;; todo: create macro to set retransmission timer
|
||||||
|
|
||||||
push eax
|
push eax
|
||||||
call TCP_output
|
call TCP_output
|
||||||
@ -671,6 +654,9 @@ SOCKET_receive:
|
|||||||
call SOCKET_num_to_ptr
|
call SOCKET_num_to_ptr
|
||||||
jz s_error
|
jz s_error
|
||||||
|
|
||||||
|
cmp [eax + SOCKET.Type], IP_PROTO_TCP ;;;;;;;;
|
||||||
|
je .tcp
|
||||||
|
|
||||||
mov ebx, esi
|
mov ebx, esi
|
||||||
get_from_queue (eax + SOCKET_QUEUE_LOCATION),\
|
get_from_queue (eax + SOCKET_QUEUE_LOCATION),\
|
||||||
SOCKET_QUEUE_SIZE,\
|
SOCKET_QUEUE_SIZE,\
|
||||||
@ -707,9 +693,17 @@ SOCKET_receive:
|
|||||||
.nd:
|
.nd:
|
||||||
; remove the packet ;;; TODO: only if it is empty!!
|
; remove the packet ;;; TODO: only if it is empty!!
|
||||||
|
|
||||||
;;;; call TCP_output ; only if it is tcp
|
|
||||||
|
|
||||||
call kernel_free
|
call kernel_free
|
||||||
|
ret
|
||||||
|
|
||||||
|
.tcp:
|
||||||
|
|
||||||
|
mov ecx, esi
|
||||||
|
mov edi, edx
|
||||||
|
add eax, STREAM_SOCKET.rcv
|
||||||
|
call SOCKET_ring_read
|
||||||
|
|
||||||
|
mov dword[esp+32], ecx ; return number of bytes copied in ebx
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -787,8 +781,13 @@ SOCKET_send:
|
|||||||
jz s_error
|
jz s_error
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
;;;; TODO: queue the data
|
|
||||||
|
|
||||||
|
push eax
|
||||||
|
mov ecx, esi
|
||||||
|
mov esi, edx
|
||||||
|
add eax, STREAM_SOCKET.snd
|
||||||
|
call SOCKET_ring_write
|
||||||
|
pop eax
|
||||||
call TCP_output
|
call TCP_output
|
||||||
|
|
||||||
mov [esp+32], eax
|
mov [esp+32], eax
|
||||||
@ -1028,58 +1027,86 @@ SOCKET_input:
|
|||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;--------------------------
|
||||||
|
;
|
||||||
|
; eax = ptr to ring struct (just a buffer of the right size)
|
||||||
|
;
|
||||||
|
align 4
|
||||||
|
SOCKET_ring_create:
|
||||||
|
|
||||||
|
mov esi, eax
|
||||||
|
stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW
|
||||||
|
|
||||||
|
DEBUGF 1,"SOCKET_ring_created: %x\n", eax
|
||||||
|
mov [esi + RING_BUFFER.start_ptr], eax
|
||||||
|
mov [esi + RING_BUFFER.write_ptr], eax
|
||||||
|
mov [esi + RING_BUFFER.read_ptr], eax
|
||||||
|
mov [esi + RING_BUFFER.size], 0
|
||||||
|
add eax, SOCKET_MAXDATA
|
||||||
|
mov [esi + RING_BUFFER.end_ptr], eax
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
;
|
;
|
||||||
; SOCKET_ring_add
|
; SOCKET_ring_write
|
||||||
;
|
;
|
||||||
; Adds data to a stream socket
|
; Adds data to a stream socket, and updates write pointer and size
|
||||||
;
|
;
|
||||||
; IN: eax = ptr to ring struct
|
; IN: eax = ptr to ring struct
|
||||||
; ecx = data size
|
; ecx = data size
|
||||||
; esi = ptr to data
|
; esi = ptr to data
|
||||||
;
|
;
|
||||||
; OUT: eax = number of bytes stored
|
; OUT: ecx = number of bytes stored
|
||||||
;
|
;
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
align 4
|
align 4
|
||||||
SOCKET_ring_add:
|
SOCKET_ring_write:
|
||||||
|
|
||||||
DEBUGF 1,"SOCKET_ring_add: ringbuff=%x ptr=%x size=%u\n", eax, esi, ecx
|
DEBUGF 1,"SOCKET_ring_write: ringbuff=%x ptr=%x size=%u\n", eax, esi, ecx
|
||||||
|
|
||||||
mov edi, [eax + RING_BUFFER.size]
|
add [eax + RING_BUFFER.size], ecx
|
||||||
add edi, ecx
|
cmp [eax + RING_BUFFER.size], SOCKET_MAXDATA
|
||||||
cmp edi, SOCKET_MAXDATA
|
|
||||||
jg .too_large
|
jg .too_large
|
||||||
|
|
||||||
mov [eax + RING_BUFFER.size], edi ; update size
|
|
||||||
.copy:
|
.copy:
|
||||||
push ecx ;<<<< 1
|
mov edi, [eax + RING_BUFFER.write_ptr]
|
||||||
mov edi, [eax + RING_BUFFER.write_ptr] ; set write ptr in edi
|
DEBUGF 2,"Copying %u bytes from %x to %x\n", ecx, esi, edi
|
||||||
add [eax + RING_BUFFER.write_ptr], ecx ; update write pointer
|
|
||||||
mov edx, [eax + RING_BUFFER.end_ptr]
|
|
||||||
cmp edx, [eax + RING_BUFFER.write_ptr]
|
|
||||||
jg .copy_in_2
|
|
||||||
je .wrap_write_ptr
|
|
||||||
|
|
||||||
.copy_more:
|
|
||||||
push ecx
|
push ecx
|
||||||
and ecx, 3
|
shr ecx, 1
|
||||||
rep movsb
|
jnc .nb
|
||||||
pop ecx
|
movsb
|
||||||
shr ecx, 2
|
.nb:
|
||||||
|
shr ecx, 1
|
||||||
|
jnc .nw
|
||||||
|
movsw
|
||||||
|
.nw:
|
||||||
|
test ecx, ecx
|
||||||
|
jz .nd
|
||||||
rep movsd
|
rep movsd
|
||||||
pop ecx ; >>>> 1/2
|
.nd:
|
||||||
DEBUGF 2,"Copied %u bytes\n", ecx
|
pop ecx
|
||||||
|
|
||||||
|
cmp edi, [eax + RING_BUFFER.end_ptr]
|
||||||
|
jge .wrap
|
||||||
|
mov [eax + RING_BUFFER.write_ptr], edi
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.wrap:
|
||||||
|
sub edi, SOCKET_MAXDATA
|
||||||
|
mov [eax + RING_BUFFER.write_ptr], edi
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.too_large:
|
.too_large:
|
||||||
mov ecx, SOCKET_MAXDATA ; calculate number of bytes available in buffer
|
mov ecx, SOCKET_MAXDATA ; calculate number of bytes available in buffer
|
||||||
sub ecx, [eax + RING_BUFFER.size]
|
sub ecx, [eax + RING_BUFFER.size]
|
||||||
jz .full
|
jge .full
|
||||||
|
|
||||||
mov [eax + RING_BUFFER.size], SOCKET_MAXDATA ; update size, we will fill buffer completely
|
mov [eax + RING_BUFFER.size], SOCKET_MAXDATA ; update size, we will fill buffer completely
|
||||||
|
|
||||||
jmp .copy
|
jmp .copy
|
||||||
|
|
||||||
.full:
|
.full:
|
||||||
@ -1087,87 +1114,56 @@ SOCKET_ring_add:
|
|||||||
xor ecx, ecx
|
xor ecx, ecx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.copy_in_2:
|
|
||||||
DEBUGF 1,"Copying in 2 passes\n"
|
|
||||||
|
|
||||||
mov edx, ecx
|
|
||||||
mov ecx, [eax + RING_BUFFER.end_ptr] ; find number of bytes till end of buffer
|
|
||||||
sub ecx, edi
|
|
||||||
sub edx, ecx
|
|
||||||
push edx ; <<<< 2
|
|
||||||
|
|
||||||
mov edi, [eax + RING_BUFFER.start_ptr]
|
|
||||||
call .copy_more
|
|
||||||
|
|
||||||
.wrap_write_ptr:
|
|
||||||
sub [eax + RING_BUFFER.write_ptr], SOCKET_MAXDATA ; update write pointer
|
|
||||||
jmp .copy_more
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
;
|
;
|
||||||
; SOCKET_ring_read
|
; SOCKET_ring_read
|
||||||
;
|
;
|
||||||
; reads the data, but let the data remain in the buffer
|
; reads the data, BUT DOES NOT CLEAR IT FROM MEMORY YET
|
||||||
;
|
;
|
||||||
; IN: eax = ptr to ring struct
|
; IN: eax = ptr to ring struct
|
||||||
; ecx = buffer size
|
; ecx = buffer size
|
||||||
; edi = ptr to buffer
|
; edi = ptr to buffer
|
||||||
;
|
;
|
||||||
; OUT: eax = number of bytes read
|
; OUT: ecx = number of bytes read
|
||||||
;
|
;
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
align 4
|
align 4
|
||||||
SOCKET_ring_read:
|
SOCKET_ring_read:
|
||||||
|
|
||||||
DEBUGF 1,"SOCKET_ring_read: ringbuff=%x ptr=%x size=%u\n", eax, esi, ecx
|
DEBUGF 1,"SOCKET_ring_read: ringbuff=%x ptr=%x size=%u\n", eax, edi, ecx
|
||||||
|
|
||||||
cmp [eax + RING_BUFFER.size], ecx ; update size
|
cmp ecx, [eax + RING_BUFFER.size]
|
||||||
jl .too_large
|
jg .less_data
|
||||||
|
|
||||||
mov esi, [eax + RING_BUFFER.read_ptr] ; update read ptr
|
|
||||||
.copy:
|
.copy:
|
||||||
push ecx ;<<<< 1
|
mov esi, [eax + RING_BUFFER.read_ptr]
|
||||||
mov edx, [eax + RING_BUFFER.read_ptr]
|
|
||||||
add edx, ecx
|
|
||||||
cmp edx, [eax + RING_BUFFER.end_ptr]
|
|
||||||
jg .copy_in_2
|
|
||||||
|
|
||||||
.copy_more:
|
DEBUGF 2,"Copying %u bytes from %x to %x\n", ecx, esi, edi
|
||||||
push ecx
|
push ecx
|
||||||
and ecx, 3
|
shr ecx, 1
|
||||||
rep movsb
|
jnc .nb
|
||||||
pop ecx
|
movsb
|
||||||
shr ecx, 2
|
.nb:
|
||||||
|
shr ecx, 1
|
||||||
|
jnc .nw
|
||||||
|
movsw
|
||||||
|
.nw:
|
||||||
|
test ecx, ecx
|
||||||
|
jz .nd
|
||||||
rep movsd
|
rep movsd
|
||||||
pop ecx ; >>>> 1/2
|
.nd:
|
||||||
DEBUGF 2,"Copied %u bytes\n", ecx
|
pop ecx
|
||||||
|
|
||||||
|
; .no_data_at_all:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.too_large:
|
.less_data:
|
||||||
mov ecx, [eax + RING_BUFFER.size]
|
mov ecx, [eax + RING_BUFFER.size]
|
||||||
|
test ecx, ecx
|
||||||
|
; jz .no_data_at_all
|
||||||
jmp .copy
|
jmp .copy
|
||||||
|
|
||||||
.full:
|
|
||||||
DEBUGF 2,"Ring buffer is full!\n"
|
|
||||||
xor ecx, ecx
|
|
||||||
ret
|
|
||||||
|
|
||||||
.copy_in_2:
|
|
||||||
DEBUGF 1,"Copying in 2 passes\n"
|
|
||||||
|
|
||||||
mov edx, ecx
|
|
||||||
mov ecx, [eax + RING_BUFFER.end_ptr] ; find number of bytes till end of buffer
|
|
||||||
sub ecx, edi
|
|
||||||
sub edx, ecx
|
|
||||||
push edx ; <<<< 2
|
|
||||||
|
|
||||||
mov esi, [eax + RING_BUFFER.start_ptr]
|
|
||||||
call .copy_more
|
|
||||||
|
|
||||||
|
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
;
|
;
|
||||||
@ -1186,26 +1182,19 @@ SOCKET_ring_free:
|
|||||||
|
|
||||||
DEBUGF 1,"Trying to free %u bytes of data from ring %x\n", ecx, eax
|
DEBUGF 1,"Trying to free %u bytes of data from ring %x\n", ecx, eax
|
||||||
|
|
||||||
cmp ecx, [eax + RING_BUFFER.size]
|
|
||||||
jle .go_for_it
|
|
||||||
|
|
||||||
cmp ecx, SOCKET_MAXDATA ;;;;
|
|
||||||
jg .moron_input
|
|
||||||
|
|
||||||
mov ecx, [eax + RING_BUFFER.size]
|
|
||||||
|
|
||||||
.go_for_it:
|
|
||||||
sub [eax + RING_BUFFER.size], ecx
|
sub [eax + RING_BUFFER.size], ecx
|
||||||
|
jl .sumthinwong
|
||||||
add [eax + RING_BUFFER.read_ptr], ecx
|
add [eax + RING_BUFFER.read_ptr], ecx
|
||||||
|
|
||||||
mov edx, [eax + RING_BUFFER.end_ptr]
|
mov edx, [eax + RING_BUFFER.end_ptr]
|
||||||
cmp [eax + RING_BUFFER.read_ptr], edx
|
cmp [eax + RING_BUFFER.read_ptr], edx
|
||||||
jl @f
|
jl @f
|
||||||
sub [eax + RING_BUFFER.read_ptr], SOCKET_MAXDATA ;;;;;
|
sub [eax + RING_BUFFER.read_ptr], SOCKET_MAXDATA
|
||||||
@@:
|
@@:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.moron_input:
|
.sumthinwong: ; we could free all available bytes, but that would be stupid, i guess..
|
||||||
|
add [eax + RING_BUFFER.size], ecx
|
||||||
xor ecx, ecx
|
xor ecx, ecx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -1371,8 +1360,8 @@ SOCKET_free:
|
|||||||
cmp [eax + SOCKET.Type], IP_PROTO_TCP
|
cmp [eax + SOCKET.Type], IP_PROTO_TCP
|
||||||
jnz .no_stream
|
jnz .no_stream
|
||||||
|
|
||||||
stdcall kernel_free, [eax + rcv.start_ptr]
|
stdcall kernel_free, [eax + STREAM_SOCKET.rcv + RING_BUFFER.start_ptr]
|
||||||
stdcall kernel_free, [eax + snd.start_ptr]
|
stdcall kernel_free, [eax + STREAM_SOCKET.snd + RING_BUFFER.start_ptr]
|
||||||
.no_stream:
|
.no_stream:
|
||||||
|
|
||||||
push eax ; this will be passed to kernel_free
|
push eax ; this will be passed to kernel_free
|
||||||
@ -1400,9 +1389,9 @@ SOCKET_free:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
; socket nr in ebx
|
; IN: socket nr in ebx
|
||||||
; new socket nr in eax
|
; OUT: socket nr in eax
|
||||||
; preserver edx
|
; preserves edx
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
SOCKET_fork:
|
SOCKET_fork:
|
||||||
@ -1440,7 +1429,7 @@ SOCKET_fork:
|
|||||||
; Get socket structure address by its number
|
; Get socket structure address by its number
|
||||||
;
|
;
|
||||||
; IN: ecx = socket number
|
; IN: ecx = socket number
|
||||||
; OUT: ecx = 0 on error, socket ptr otherwise
|
; OUT: eax = 0 on error, socket ptr otherwise
|
||||||
; ZF = set on error
|
; ZF = set on error
|
||||||
;
|
;
|
||||||
;---------------------------------------------------
|
;---------------------------------------------------
|
||||||
|
@ -266,6 +266,30 @@ macro TCP_checksum IP1, IP2 {
|
|||||||
} ; returns in dx only
|
} ; returns in dx only
|
||||||
|
|
||||||
|
|
||||||
|
macro TCP_sendseqinit ptr {
|
||||||
|
|
||||||
|
push edi ;;;; i dont like this static use of edi
|
||||||
|
mov edi, [ptr + TCP_SOCKET.ISS]
|
||||||
|
mov [ptr + TCP_SOCKET.SND_UP], edi
|
||||||
|
mov [ptr + TCP_SOCKET.SND_MAX], edi
|
||||||
|
mov [ptr + TCP_SOCKET.SND_NXT], edi
|
||||||
|
mov [ptr + TCP_SOCKET.SND_UNA], edi
|
||||||
|
pop edi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
macro TCP_rcvseqinit ptr {
|
||||||
|
|
||||||
|
push edi
|
||||||
|
mov edi, [ptr + TCP_SOCKET.IRS]
|
||||||
|
inc edi
|
||||||
|
mov [ptr + TCP_SOCKET.RCV_NXT], edi
|
||||||
|
mov [ptr + TCP_SOCKET.RCV_ADV], edi
|
||||||
|
pop edi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
;
|
;
|
||||||
@ -420,7 +444,7 @@ TCP_input:
|
|||||||
;-----------------------------------
|
;-----------------------------------
|
||||||
; Is this socket a listening socket?
|
; Is this socket a listening socket?
|
||||||
|
|
||||||
; test [ebx + SOCKET.options], SO_ACCEPTCON
|
test [ebx + SOCKET.options], SO_ACCEPTCON
|
||||||
; jnz .listening_socket ;;;;; TODO
|
; jnz .listening_socket ;;;;; TODO
|
||||||
|
|
||||||
;-------------------------------------
|
;-------------------------------------
|
||||||
@ -477,7 +501,7 @@ TCP_input:
|
|||||||
|
|
||||||
movzx eax, word[edi+2]
|
movzx eax, word[edi+2]
|
||||||
rol ax, 8
|
rol ax, 8
|
||||||
DEBUGF 1,"Maxseg: %u", ax
|
DEBUGF 1,"Maxseg: %u\n", ax
|
||||||
|
|
||||||
mov [ebx + TCP_SOCKET.t_maxseg], eax
|
mov [ebx + TCP_SOCKET.t_maxseg], eax
|
||||||
|
|
||||||
@ -493,7 +517,7 @@ TCP_input:
|
|||||||
test [edx + TCP_segment.Flags], TH_SYN
|
test [edx + TCP_segment.Flags], TH_SYN
|
||||||
jz @f
|
jz @f
|
||||||
|
|
||||||
DEBUGF 1,"Got window option"
|
DEBUGF 1,"Got window option\n"
|
||||||
|
|
||||||
;;;;;
|
;;;;;
|
||||||
@@:
|
@@:
|
||||||
@ -505,7 +529,7 @@ TCP_input:
|
|||||||
cmp byte [edi+1], 10
|
cmp byte [edi+1], 10
|
||||||
jne .no_options
|
jne .no_options
|
||||||
|
|
||||||
DEBUGF 1,"Got timestamp option"
|
DEBUGF 1,"Got timestamp option\n"
|
||||||
|
|
||||||
;;;;;
|
;;;;;
|
||||||
|
|
||||||
@ -532,19 +556,29 @@ TCP_input:
|
|||||||
cmp [ebx + TCP_SOCKET.t_state], TCB_ESTABLISHED
|
cmp [ebx + TCP_SOCKET.t_state], TCB_ESTABLISHED
|
||||||
jnz .not_uni_xfer
|
jnz .not_uni_xfer
|
||||||
|
|
||||||
|
DEBUGF 1,"1\n"
|
||||||
|
|
||||||
test [edx + TCP_segment.Flags], TH_SYN + TH_FIN + TH_RST + TH_URG
|
test [edx + TCP_segment.Flags], TH_SYN + TH_FIN + TH_RST + TH_URG
|
||||||
jnz .not_uni_xfer
|
jnz .not_uni_xfer
|
||||||
|
|
||||||
|
DEBUGF 1,"2\n"
|
||||||
|
|
||||||
test [edx + TCP_segment.Flags], TH_ACK
|
test [edx + TCP_segment.Flags], TH_ACK
|
||||||
jz .not_uni_xfer
|
jz .not_uni_xfer
|
||||||
|
|
||||||
|
DEBUGF 1,"3\n"
|
||||||
|
|
||||||
mov eax, [edx + TCP_segment.SequenceNumber]
|
mov eax, [edx + TCP_segment.SequenceNumber]
|
||||||
cmp eax, [ebx + TCP_SOCKET.RCV_NXT]
|
cmp eax, [ebx + TCP_SOCKET.RCV_NXT]
|
||||||
jne .not_uni_xfer
|
jne .not_uni_xfer
|
||||||
|
|
||||||
movzx eax, [edx + TCP_segment.Window] ;;;;; (should use pre-calculated value isntead: todo: figure out where to store it)
|
DEBUGF 1,"4\n"
|
||||||
cmp eax, [ebx + TCP_SOCKET.SND_WND]
|
|
||||||
jne .not_uni_xfer
|
;; movzx eax, [edx + TCP_segment.Window] ;;;;; (should use pre-calculated value isntead: todo: figure out where to store it)
|
||||||
|
;; cmp eax, [ebx + TCP_SOCKET.SND_WND]
|
||||||
|
;; jne .not_uni_xfer
|
||||||
|
|
||||||
|
DEBUGF 1,"5\n"
|
||||||
|
|
||||||
mov eax, [ebx + TCP_SOCKET.SND_NXT]
|
mov eax, [ebx + TCP_SOCKET.SND_NXT]
|
||||||
cmp eax, [ebx + TCP_SOCKET.SND_MAX]
|
cmp eax, [ebx + TCP_SOCKET.SND_MAX]
|
||||||
@ -584,7 +618,7 @@ TCP_input:
|
|||||||
; Delete acknowledged bytes from send buffer
|
; Delete acknowledged bytes from send buffer
|
||||||
; notice how ecx already holds number of bytes ack-ed
|
; notice how ecx already holds number of bytes ack-ed
|
||||||
|
|
||||||
lea eax, [ebx + snd]
|
lea eax, [ebx + STREAM_SOCKET.snd]
|
||||||
call SOCKET_ring_free
|
call SOCKET_ring_free
|
||||||
|
|
||||||
; Stop retransmit timer
|
; Stop retransmit timer
|
||||||
@ -620,8 +654,11 @@ TCP_input:
|
|||||||
DEBUGF 1,"header prediction: we are receiver\nreceiving %u bytes of data\n", ecx
|
DEBUGF 1,"header prediction: we are receiver\nreceiving %u bytes of data\n", ecx
|
||||||
|
|
||||||
add esi, edx
|
add esi, edx
|
||||||
lea eax, [ebx + rcv]
|
lea eax, [ebx + STREAM_SOCKET.rcv]
|
||||||
call SOCKET_ring_add ; Add the data to the socket buffer
|
call SOCKET_ring_write ; Add the data to the socket buffer
|
||||||
|
|
||||||
|
mov eax, ebx
|
||||||
|
call SOCKET_notify_owner
|
||||||
|
|
||||||
add [ebx + TCP_SOCKET.RCV_NXT], ecx ; Update sequence number with number of bytes we have copied
|
add [ebx + TCP_SOCKET.RCV_NXT], ecx ; Update sequence number with number of bytes we have copied
|
||||||
or [ebx + TCP_SOCKET.t_flags], TF_DELACK ; Set delayed ack flag
|
or [ebx + TCP_SOCKET.t_flags], TF_DELACK ; Set delayed ack flag
|
||||||
@ -633,18 +670,13 @@ TCP_input:
|
|||||||
|
|
||||||
.not_uni_xfer:
|
.not_uni_xfer:
|
||||||
|
|
||||||
DEBUGF 1,"Header prediction failed\n"
|
DEBUGF 1,"Header prediction failed\n" ; time to do it the "slow" way :)
|
||||||
|
|
||||||
;------------------------------
|
;------------------------------
|
||||||
; Calculate receive window size
|
; Calculate receive window size
|
||||||
|
|
||||||
;;;;
|
;;;;
|
||||||
|
|
||||||
;-------------------------
|
|
||||||
; TCP slow input procedure
|
|
||||||
|
|
||||||
DEBUGF 1,"TCP slow input procedure\n"
|
|
||||||
|
|
||||||
cmp [ebx + TCP_SOCKET.t_state], TCB_LISTEN
|
cmp [ebx + TCP_SOCKET.t_state], TCB_LISTEN
|
||||||
je .LISTEN
|
je .LISTEN
|
||||||
|
|
||||||
@ -654,7 +686,7 @@ TCP_input:
|
|||||||
;--------------------------------------------
|
;--------------------------------------------
|
||||||
; Protection Against Wrapped Sequence Numbers
|
; Protection Against Wrapped Sequence Numbers
|
||||||
|
|
||||||
; First, check timestamp if present
|
; First, check if timestamp is present
|
||||||
|
|
||||||
;;;; TODO
|
;;;; TODO
|
||||||
|
|
||||||
@ -681,7 +713,9 @@ align 4
|
|||||||
test [edx + TCP_segment.Flags], TH_SYN
|
test [edx + TCP_segment.Flags], TH_SYN
|
||||||
jz .drop
|
jz .drop
|
||||||
|
|
||||||
; TODO: find sender ip address somewhere!
|
cmp esi, 0xffffff ; destination ip = 255.255.255.255 ?
|
||||||
|
jz .drop
|
||||||
|
|
||||||
; TODO: check if it's a broadcast or multicast, and drop if so
|
; TODO: check if it's a broadcast or multicast, and drop if so
|
||||||
|
|
||||||
call SOCKET_fork
|
call SOCKET_fork
|
||||||
@ -706,7 +740,6 @@ align 4
|
|||||||
mov [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval
|
mov [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval
|
||||||
|
|
||||||
mov ebx, eax
|
mov ebx, eax
|
||||||
|
|
||||||
jmp .trim_then_step6
|
jmp .trim_then_step6
|
||||||
|
|
||||||
|
|
||||||
@ -725,11 +758,9 @@ align 4
|
|||||||
cmp eax, [ebx + TCP_SOCKET.ISS]
|
cmp eax, [ebx + TCP_SOCKET.ISS]
|
||||||
jle .drop_with_reset
|
jle .drop_with_reset
|
||||||
|
|
||||||
DEBUGF 1,"snd_max = %x\n", [ebx + TCP_SOCKET.SND_MAX] ;;; TODO: set this, but where?
|
|
||||||
|
|
||||||
; mov eax, [edx + TCP_segment.AckNumber]
|
; mov eax, [edx + TCP_segment.AckNumber]
|
||||||
;; cmp eax, [ebx + TCP_SOCKET.SND_MAX]
|
cmp eax, [ebx + TCP_SOCKET.SND_MAX]
|
||||||
;; jg .drop_with_reset
|
jg .drop_with_reset
|
||||||
@@:
|
@@:
|
||||||
|
|
||||||
test [edx + TCP_segment.Flags], TH_RST
|
test [edx + TCP_segment.Flags], TH_RST
|
||||||
@ -767,7 +798,7 @@ align 4
|
|||||||
push [edx + TCP_segment.SequenceNumber]
|
push [edx + TCP_segment.SequenceNumber]
|
||||||
pop [ebx + TCP_SOCKET.IRS]
|
pop [ebx + TCP_SOCKET.IRS]
|
||||||
|
|
||||||
;;; TODO: tcp_rcvseqinit
|
TCP_rcvseqinit ebx
|
||||||
|
|
||||||
mov [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
|
mov [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
|
||||||
|
|
||||||
@ -781,7 +812,7 @@ align 4
|
|||||||
DEBUGF 1,"TCP: active open\n"
|
DEBUGF 1,"TCP: active open\n"
|
||||||
|
|
||||||
; TODO: update stats
|
; TODO: update stats
|
||||||
; TODO: set socket state to connected
|
; TODO: set general socket state to connected
|
||||||
|
|
||||||
mov [ebx + TCP_SOCKET.t_state], TCB_ESTABLISHED
|
mov [ebx + TCP_SOCKET.t_state], TCB_ESTABLISHED
|
||||||
|
|
||||||
@ -821,16 +852,16 @@ align 4
|
|||||||
|
|
||||||
.trim_then_step6:
|
.trim_then_step6:
|
||||||
|
|
||||||
DEBUGF 1,"Trimming window\n"
|
|
||||||
|
|
||||||
;----------------------------
|
;----------------------------
|
||||||
; trim any data not in window
|
; trim any data not in window
|
||||||
|
|
||||||
|
DEBUGF 1,"Trimming window\n"
|
||||||
|
|
||||||
mov eax, [ebx + TCP_SOCKET.RCV_NXT]
|
mov eax, [ebx + TCP_SOCKET.RCV_NXT]
|
||||||
sub eax, [edx + TCP_segment.SequenceNumber]
|
sub eax, [edx + TCP_segment.SequenceNumber]
|
||||||
|
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .no_drop
|
jz .no_duplicate
|
||||||
|
|
||||||
test [edx + TCP_segment.Flags], TH_SYN
|
test [edx + TCP_segment.Flags], TH_SYN
|
||||||
jz .no_drop
|
jz .no_drop
|
||||||
@ -848,10 +879,10 @@ align 4
|
|||||||
|
|
||||||
and [edx + TCP_segment.Flags], not (TH_URG)
|
and [edx + TCP_segment.Flags], not (TH_URG)
|
||||||
dec eax
|
dec eax
|
||||||
|
jz .no_duplicate
|
||||||
.no_drop:
|
.no_drop:
|
||||||
|
|
||||||
DEBUGF 1,"Going to drop %u bytes of data", eax
|
DEBUGF 1,"Going to drop %u out of %u bytes\n", eax, ecx
|
||||||
|
|
||||||
; eax holds number of bytes to drop
|
; eax holds number of bytes to drop
|
||||||
|
|
||||||
@ -895,7 +926,7 @@ align 4
|
|||||||
|
|
||||||
.duplicate:
|
.duplicate:
|
||||||
|
|
||||||
DEBUGF 1,"Duplicate received"
|
DEBUGF 1,"Duplicate received\n"
|
||||||
|
|
||||||
;----------------------------------------
|
;----------------------------------------
|
||||||
; Update statistics for duplicate packets
|
; Update statistics for duplicate packets
|
||||||
@ -924,7 +955,7 @@ align 4
|
|||||||
; Handle data that arrives after process terminates
|
; Handle data that arrives after process terminates
|
||||||
|
|
||||||
cmp [ebx + SOCKET.PID], 0
|
cmp [ebx + SOCKET.PID], 0
|
||||||
jge @f
|
jg @f
|
||||||
|
|
||||||
cmp [ebx + TCP_SOCKET.t_state], TCB_CLOSE_WAIT
|
cmp [ebx + TCP_SOCKET.t_state], TCB_CLOSE_WAIT
|
||||||
jle @f
|
jle @f
|
||||||
@ -936,7 +967,6 @@ align 4
|
|||||||
;;; update stats
|
;;; update stats
|
||||||
|
|
||||||
jmp .drop_with_reset
|
jmp .drop_with_reset
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
|
|
||||||
;----------------------------------------
|
;----------------------------------------
|
||||||
@ -1039,16 +1069,22 @@ align 4
|
|||||||
jg .ack_dup
|
jg .ack_dup
|
||||||
jl .ack_nodup
|
jl .ack_nodup
|
||||||
|
|
||||||
|
DEBUGF 1,"TCP state = syn received"
|
||||||
|
|
||||||
;;;;;
|
;;;;;
|
||||||
|
|
||||||
.ack_dup:
|
.ack_dup:
|
||||||
|
|
||||||
|
DEBUGF 1,"Duplicate ACK"
|
||||||
|
|
||||||
;;;;
|
;;;;
|
||||||
|
|
||||||
.ack_nodup:
|
.ack_nodup:
|
||||||
|
|
||||||
;;;; 887
|
;;;; 887
|
||||||
|
|
||||||
|
DEBUGF 1,"New ACK"
|
||||||
|
|
||||||
;-------------------------------------------------
|
;-------------------------------------------------
|
||||||
; If the congestion window was inflated to account
|
; If the congestion window was inflated to account
|
||||||
; for the other side's cached packets, retrace it
|
; for the other side's cached packets, retrace it
|
||||||
@ -1069,7 +1105,6 @@ align 4
|
|||||||
mov [ebx + TCP_SOCKET.timer_retransmission], 120 ;;;; TODO: correct this value
|
mov [ebx + TCP_SOCKET.timer_retransmission], 120 ;;;; TODO: correct this value
|
||||||
.all_outstanding:
|
.all_outstanding:
|
||||||
|
|
||||||
|
|
||||||
;-------------------------------------------
|
;-------------------------------------------
|
||||||
; Open congestion window in response to ACKs
|
; Open congestion window in response to ACKs
|
||||||
|
|
||||||
@ -1079,9 +1114,9 @@ align 4
|
|||||||
;------------------------------------------
|
;------------------------------------------
|
||||||
; Remove acknowledged data from send buffer
|
; Remove acknowledged data from send buffer
|
||||||
|
|
||||||
lea eax, [ebx + snd]
|
xor ecx, ecx ;;;;;;
|
||||||
mov ecx, ecx ;;;; 943 - 956
|
lea eax, [ebx + STREAM_SOCKET.snd]
|
||||||
call SOCKET_ring_free
|
call SOCKET_ring_free ;;;; 943 - 956
|
||||||
|
|
||||||
;---------------------------------------
|
;---------------------------------------
|
||||||
; Wake up process waiting on send buffer
|
; Wake up process waiting on send buffer
|
||||||
@ -1196,7 +1231,7 @@ align 4
|
|||||||
;;; 1040-1050
|
;;; 1040-1050
|
||||||
|
|
||||||
movzx eax, [edx + TCP_segment.UrgentPointer]
|
movzx eax, [edx + TCP_segment.UrgentPointer]
|
||||||
add eax, [ebx + rcv.size]
|
add eax, [ebx + STREAM_SOCKET.rcv + RING_BUFFER.size]
|
||||||
cmp eax, SOCKET_MAXDATA
|
cmp eax, SOCKET_MAXDATA
|
||||||
jle .not_urgent
|
jle .not_urgent
|
||||||
|
|
||||||
@ -1216,17 +1251,35 @@ align 4
|
|||||||
|
|
||||||
.do_data:
|
.do_data:
|
||||||
|
|
||||||
DEBUGF 1,"TCP: do data:\n"
|
DEBUGF 1,"TCP: do data\n"
|
||||||
|
|
||||||
test [edx + TCP_segment.Flags], TH_FIN
|
test [edx + TCP_segment.Flags], TH_FIN
|
||||||
jnz .process_fin
|
jnz .process_fin
|
||||||
|
|
||||||
test [ebx + TCP_SOCKET.t_state], TCB_FIN_WAIT_1
|
cmp [ebx + TCP_SOCKET.t_state], TCB_FIN_WAIT_1
|
||||||
jge .dont_do_data
|
jge .dont_do_data
|
||||||
|
|
||||||
|
test ecx, ecx
|
||||||
|
jz .final_processing
|
||||||
|
|
||||||
DEBUGF 1,"Processing data in segment\n"
|
DEBUGF 1,"Processing data in segment\n"
|
||||||
|
|
||||||
;;; NOW, process the data
|
;; TODO: check if data is in sequence !
|
||||||
|
|
||||||
|
movzx eax, [edx + TCP_segment.DataOffset] ;;; todo: remember this in.. edi ?
|
||||||
|
and eax, 0xf0
|
||||||
|
shr al, 2
|
||||||
|
|
||||||
|
lea esi, [edx + eax]
|
||||||
|
|
||||||
|
or [ebx + TCP_SOCKET.t_flags], TF_DELACK
|
||||||
|
add [ebx + TCP_SOCKET.RCV_NXT], ecx ;;; right ?
|
||||||
|
|
||||||
|
lea eax, [ebx + STREAM_SOCKET.rcv]
|
||||||
|
call SOCKET_ring_write
|
||||||
|
|
||||||
|
mov eax, ebx
|
||||||
|
call SOCKET_notify_owner
|
||||||
|
|
||||||
jmp .final_processing
|
jmp .final_processing
|
||||||
|
|
||||||
@ -1248,25 +1301,32 @@ align 4
|
|||||||
dd .no_fin ;TCB_CLOSED
|
dd .no_fin ;TCB_CLOSED
|
||||||
dd .no_fin ;TCB_LISTEN
|
dd .no_fin ;TCB_LISTEN
|
||||||
dd .no_fin ;TCB_SYN_SENT
|
dd .no_fin ;TCB_SYN_SENT
|
||||||
dd ._1131 ;TCB_SYN_RECEIVED
|
dd .fin_syn_est ;TCB_SYN_RECEIVED
|
||||||
dd ._1131 ;TCB_ESTABLISHED
|
dd .fin_syn_est ;TCB_ESTABLISHED
|
||||||
dd .no_fin ;TCB_CLOSE_WAIT
|
dd .no_fin ;TCB_CLOSE_WAIT
|
||||||
dd ._1139 ;TCB_FIN_WAIT_1
|
dd .fin_wait1 ;TCB_FIN_WAIT_1
|
||||||
dd .no_fin ;TCB_CLOSING
|
dd .no_fin ;TCB_CLOSING
|
||||||
dd .no_fin ;TCB_LAST_ACK
|
dd .no_fin ;TCB_LAST_ACK
|
||||||
dd ._1147 ;TCB_FIN_WAIT_2
|
dd .fin_wait2 ;TCB_FIN_WAIT_2
|
||||||
dd ._1156 ;TCB_TIMED_WAIT
|
dd .fin_timed ;TCB_TIMED_WAIT
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
._1131:
|
.fin_syn_est:
|
||||||
|
|
||||||
._1139:
|
jmp .final_processing
|
||||||
|
|
||||||
._1147:
|
.fin_wait1:
|
||||||
|
|
||||||
._1156:
|
jmp .final_processing
|
||||||
|
|
||||||
|
.fin_wait2:
|
||||||
|
|
||||||
|
jmp .final_processing
|
||||||
|
|
||||||
|
.fin_timed:
|
||||||
|
|
||||||
|
jmp .final_processing
|
||||||
|
|
||||||
.no_fin:
|
.no_fin:
|
||||||
|
|
||||||
@ -1277,6 +1337,8 @@ align 4
|
|||||||
|
|
||||||
DEBUGF 1,"Final processing\n"
|
DEBUGF 1,"Final processing\n"
|
||||||
|
|
||||||
|
mov [ebx + SOCKET.lock], 0
|
||||||
|
|
||||||
;;; if debug enabled, output packet
|
;;; if debug enabled, output packet
|
||||||
|
|
||||||
;test ;;;needoutput = 1
|
;test ;;;needoutput = 1
|
||||||
@ -1285,7 +1347,6 @@ align 4
|
|||||||
test [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
|
test [ebx + TCP_SOCKET.t_flags], TF_ACKNOW
|
||||||
jnz .ack_now
|
jnz .ack_now
|
||||||
|
|
||||||
mov [ebx + SOCKET.lock], 0
|
|
||||||
call kernel_free
|
call kernel_free
|
||||||
add esp, 4
|
add esp, 4
|
||||||
ret
|
ret
|
||||||
@ -1299,7 +1360,6 @@ align 4
|
|||||||
call TCP_output
|
call TCP_output
|
||||||
pop ebx
|
pop ebx
|
||||||
|
|
||||||
mov [ebx + SOCKET.lock], 0
|
|
||||||
call kernel_free
|
call kernel_free
|
||||||
add esp, 4
|
add esp, 4
|
||||||
ret
|
ret
|
||||||
@ -1322,7 +1382,6 @@ align 4
|
|||||||
call TCP_output
|
call TCP_output
|
||||||
pop ebx
|
pop ebx
|
||||||
|
|
||||||
mov [ebx + SOCKET.lock], 0
|
|
||||||
call kernel_free
|
call kernel_free
|
||||||
add esp, 4
|
add esp, 4
|
||||||
ret
|
ret
|
||||||
@ -1347,25 +1406,28 @@ align 4
|
|||||||
test [edx + TCP_segment.Flags], TH_SYN
|
test [edx + TCP_segment.Flags], TH_SYN
|
||||||
jnz .respond_syn
|
jnz .respond_syn
|
||||||
|
|
||||||
mov [ebx + SOCKET.lock], 0
|
|
||||||
call kernel_free
|
call kernel_free
|
||||||
add esp, 4
|
add esp, 4
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.respond_ack:
|
.respond_ack:
|
||||||
|
|
||||||
;;;;
|
mov dl, TH_RST
|
||||||
|
|
||||||
|
push ebx
|
||||||
call TCP_respond_segment
|
call TCP_respond_segment
|
||||||
|
pop ebx
|
||||||
|
|
||||||
jmp .destroy_new_socket
|
jmp .destroy_new_socket
|
||||||
|
|
||||||
|
|
||||||
.respond_syn:
|
.respond_syn:
|
||||||
|
|
||||||
;;;;
|
mov dl, TH_RST + TH_ACK
|
||||||
|
|
||||||
call TCP_respond_segment
|
push ebx
|
||||||
|
call TCP_respond_socket
|
||||||
|
pop ebx
|
||||||
|
|
||||||
jmp .destroy_new_socket
|
jmp .destroy_new_socket
|
||||||
|
|
||||||
@ -1383,7 +1445,6 @@ align 4
|
|||||||
|
|
||||||
;;;; kill the newly created socket
|
;;;; kill the newly created socket
|
||||||
|
|
||||||
mov [ebx + SOCKET.lock], 0
|
|
||||||
call kernel_free
|
call kernel_free
|
||||||
add esp, 4
|
add esp, 4
|
||||||
ret
|
ret
|
||||||
@ -1473,7 +1534,7 @@ TCP_output:
|
|||||||
test ecx, ecx
|
test ecx, ecx
|
||||||
jnz .no_zero_window
|
jnz .no_zero_window
|
||||||
|
|
||||||
cmp ebx, [eax + snd.size]
|
cmp ebx, [eax + STREAM_SOCKET.snd + RING_BUFFER.size]
|
||||||
jge @f
|
jge @f
|
||||||
|
|
||||||
and dl, not (TH_FIN) ; clear the FIN flag ??? how can it be set before?
|
and dl, not (TH_FIN) ; clear the FIN flag ??? how can it be set before?
|
||||||
@ -1491,7 +1552,7 @@ TCP_output:
|
|||||||
|
|
||||||
;;;106
|
;;;106
|
||||||
|
|
||||||
mov esi, [eax + snd.size]
|
mov esi, [eax + STREAM_SOCKET.snd + RING_BUFFER.size]
|
||||||
cmp esi, ecx
|
cmp esi, ecx
|
||||||
jl @f
|
jl @f
|
||||||
mov esi, ecx
|
mov esi, ecx
|
||||||
@ -1536,7 +1597,7 @@ TCP_output:
|
|||||||
mov edi, [eax + TCP_SOCKET.SND_NXT]
|
mov edi, [eax + TCP_SOCKET.SND_NXT]
|
||||||
add edi, esi ; len
|
add edi, esi ; len
|
||||||
sub edi, [eax + TCP_SOCKET.SND_UNA]
|
sub edi, [eax + TCP_SOCKET.SND_UNA]
|
||||||
add edi, [eax + snd.size]
|
add edi, [eax + STREAM_SOCKET.snd + RING_BUFFER.size]
|
||||||
cmp edi, 0
|
cmp edi, 0
|
||||||
jle @f
|
jle @f
|
||||||
|
|
||||||
@ -1549,7 +1610,7 @@ TCP_output:
|
|||||||
; From now on, ecx will be the window we advertise to the other end
|
; From now on, ecx will be the window we advertise to the other end
|
||||||
|
|
||||||
mov ecx, SOCKET_MAXDATA
|
mov ecx, SOCKET_MAXDATA
|
||||||
sub ecx, [eax + rcv.size]
|
sub ecx, [eax + STREAM_SOCKET.rcv + RING_BUFFER.size]
|
||||||
|
|
||||||
;------------------------------
|
;------------------------------
|
||||||
; Sender silly window avoidance
|
; Sender silly window avoidance
|
||||||
@ -1706,7 +1767,11 @@ TCP_output:
|
|||||||
; edi = header size
|
; edi = header size
|
||||||
; esi = snd ring buff ptr
|
; esi = snd ring buff ptr
|
||||||
|
|
||||||
xor ecx, ecx ;;;;;
|
mov ecx, [eax + STREAM_SOCKET.snd + RING_BUFFER.size]
|
||||||
|
cmp ecx, [eax + TCP_SOCKET.t_maxseg] ;;; right?
|
||||||
|
jle @f
|
||||||
|
mov ecx, [eax + TCP_SOCKET.t_maxseg]
|
||||||
|
@@:
|
||||||
add ecx, edi ; total TCP segment size
|
add ecx, edi ; total TCP segment size
|
||||||
|
|
||||||
; Start by pushing all TCP header values in reverse order on stack
|
; Start by pushing all TCP header values in reverse order on stack
|
||||||
@ -1733,13 +1798,11 @@ TCP_output:
|
|||||||
push [eax + TCP_SOCKET.LocalPort] ; .SourcePort dw ?
|
push [eax + TCP_SOCKET.LocalPort] ; .SourcePort dw ?
|
||||||
ntohlw [esp]
|
ntohlw [esp]
|
||||||
|
|
||||||
push edi ; header size
|
push edi ; header size
|
||||||
|
|
||||||
; Create the IP packet
|
; Create the IP packet
|
||||||
mov ebx, [eax + IP_SOCKET.LocalIP] ; source ip
|
mov ebx, [eax + IP_SOCKET.LocalIP] ; source ip
|
||||||
mov eax, [eax + IP_SOCKET.RemoteIP] ; dest ip
|
mov eax, [eax + IP_SOCKET.RemoteIP] ; dest ip
|
||||||
; mov ecx, ; data length
|
|
||||||
; mov dx, ; fragment id
|
|
||||||
mov di, IP_PROTO_TCP shl 8 + 128
|
mov di, IP_PROTO_TCP shl 8 + 128
|
||||||
call IPv4_output
|
call IPv4_output
|
||||||
jz .fail
|
jz .fail
|
||||||
@ -1747,25 +1810,23 @@ TCP_output:
|
|||||||
;-----------------------------------------
|
;-----------------------------------------
|
||||||
; Move TCP header from stack to TCP packet
|
; Move TCP header from stack to TCP packet
|
||||||
|
|
||||||
; pop ecx ; header size
|
push ecx
|
||||||
; mov esi, esp
|
mov ecx, [esp+4]
|
||||||
; add esp, ecx
|
lea esi, [esp+4+4]
|
||||||
; shr ecx, 2
|
|
||||||
; rep movsd
|
|
||||||
|
|
||||||
mov ecx, [esp]
|
|
||||||
lea esi, [esp+4]
|
|
||||||
shr ecx, 2
|
shr ecx, 2
|
||||||
rep movsd
|
rep movsd
|
||||||
|
pop ecx ; full TCP packet size
|
||||||
|
|
||||||
pop ecx
|
pop esi ; headersize
|
||||||
add esp, ecx
|
add esp, esi
|
||||||
|
|
||||||
mov [esp + 4+4], edx ; packet size
|
|
||||||
mov [esp + 4], eax ; packet ptr
|
mov [esp + 4], eax ; packet ptr
|
||||||
|
mov [esp + 4+4], edx ; packet size
|
||||||
|
|
||||||
mov edx, edi
|
mov edx, edi ; begin of data
|
||||||
sub edx, ecx
|
sub edx, esi ; begin of packet (edi = begin of data)
|
||||||
|
push ecx
|
||||||
|
sub ecx, esi ; data size
|
||||||
|
|
||||||
;--------------
|
;--------------
|
||||||
; Copy the data
|
; Copy the data
|
||||||
@ -1774,15 +1835,33 @@ TCP_output:
|
|||||||
; ecx = buffer size
|
; ecx = buffer size
|
||||||
; edi = ptr to buffer
|
; edi = ptr to buffer
|
||||||
|
|
||||||
mov eax, [esp] ; socket ptr
|
mov eax, [esp+4] ; socket ptr
|
||||||
push ecx edx
|
push edx
|
||||||
add eax, snd
|
add eax, STREAM_SOCKET.snd
|
||||||
call SOCKET_ring_read
|
call SOCKET_ring_read
|
||||||
pop esi ecx
|
pop esi ecx
|
||||||
pop eax
|
pop eax
|
||||||
|
|
||||||
;-------------------------------------------------------------
|
test [esi + TCP_segment.Flags], TH_SYN + TH_FIN
|
||||||
; Create the checksum (we have already pushed IPs onto stack)
|
jz @f
|
||||||
|
inc [eax + TCP_SOCKET.SND_NXT]
|
||||||
|
;;; TODO: update sentfin flag
|
||||||
|
@@:
|
||||||
|
|
||||||
|
;; add [eax + TCP_SOCKET.SND_NXT], ecx
|
||||||
|
|
||||||
|
mov edx, [eax + TCP_SOCKET.SND_NXT]
|
||||||
|
cmp edx, [eax + TCP_SOCKET.SND_MAX]
|
||||||
|
jle @f
|
||||||
|
mov [eax + TCP_SOCKET.SND_MAX], edx
|
||||||
|
|
||||||
|
;;;; TODO: time transmission (420)
|
||||||
|
@@:
|
||||||
|
|
||||||
|
;;; TODO: set retransmission timer
|
||||||
|
|
||||||
|
;--------------------
|
||||||
|
; Create the checksum
|
||||||
|
|
||||||
DEBUGF 1,"checksum: ptr=%x size=%u\n", esi, ecx
|
DEBUGF 1,"checksum: ptr=%x size=%u\n", esi, ecx
|
||||||
|
|
||||||
@ -1969,10 +2048,9 @@ TCP_respond_segment:
|
|||||||
mov ecx, TCP_segment.Data
|
mov ecx, TCP_segment.Data
|
||||||
mov di , IP_PROTO_TCP shl 8 + 128
|
mov di , IP_PROTO_TCP shl 8 + 128
|
||||||
call IPv4_output
|
call IPv4_output
|
||||||
test edi, edi
|
|
||||||
jz .error
|
jz .error
|
||||||
|
|
||||||
pop esi cx
|
pop esi cx
|
||||||
|
|
||||||
push edx eax
|
push edx eax
|
||||||
|
|
||||||
;---------------------------------------------------
|
;---------------------------------------------------
|
||||||
|
Loading…
Reference in New Issue
Block a user