forked from KolibriOS/kolibrios
Updated SOCKET_listen and SOCKET_accept so they can actually work now.
Changed SOCKET_alloc so that it returns better socket numbers. git-svn-id: svn://kolibrios.org@1543 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
445f854cae
commit
5b0ea56111
@ -24,7 +24,7 @@ $Revision$
|
|||||||
|
|
||||||
|
|
||||||
struct queue
|
struct queue
|
||||||
.size dd ? ; number of queued packets in thsi queue
|
.size dd ? ; number of queued packets in this queue
|
||||||
.w_ptr dd ? ; current writing pointer in queue
|
.w_ptr dd ? ; current writing pointer in queue
|
||||||
.r_ptr dd ? ; current reading pointer
|
.r_ptr dd ? ; current reading pointer
|
||||||
.data:
|
.data:
|
||||||
|
@ -28,12 +28,13 @@ virtual at 0
|
|||||||
|
|
||||||
.PID dd ? ; application process id
|
.PID dd ? ; application process id
|
||||||
.Domain dd ? ; INET/UNIX/..
|
.Domain dd ? ; INET/UNIX/..
|
||||||
.Type dd ? ; RAW/UDP/TCP/...
|
.Type dd ? ; RAW/STREAM/DGRAP
|
||||||
.Protocol dd ? ; ICMP/IPv4/ARP/
|
.Protocol dd ? ; ICMP/IPv4/ARP/TCP/UDP
|
||||||
.errorcode dd ?
|
; .errorcode dd ?
|
||||||
|
|
||||||
.options dd ?
|
.options dd ?
|
||||||
.state dd ?
|
.state dd ?
|
||||||
|
.backlog dw ? ; how many incomming connections that can be queued
|
||||||
|
|
||||||
.snd_proc dd ?
|
.snd_proc dd ?
|
||||||
.rcv_proc dd ?
|
.rcv_proc dd ?
|
||||||
@ -61,9 +62,6 @@ virtual at IP_SOCKET.end
|
|||||||
.LocalPort dw ?
|
.LocalPort dw ?
|
||||||
.RemotePort dw ?
|
.RemotePort dw ?
|
||||||
|
|
||||||
.backlog dw ? ; Backlog
|
|
||||||
.backlog_cur dw ? ; current size of queue for un-accept-ed connections
|
|
||||||
|
|
||||||
.OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state)
|
.OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state)
|
||||||
.OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state)
|
.OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state)
|
||||||
|
|
||||||
@ -190,7 +188,6 @@ virtual at TCP_SOCKET.end
|
|||||||
|
|
||||||
end virtual
|
end virtual
|
||||||
|
|
||||||
|
|
||||||
struct socket_queue_entry
|
struct socket_queue_entry
|
||||||
.data_ptr dd ?
|
.data_ptr dd ?
|
||||||
.buf_ptr dd ?
|
.buf_ptr dd ?
|
||||||
@ -203,10 +200,11 @@ SOCKETBUFFSIZE equ 4096 ; in bytes
|
|||||||
|
|
||||||
SOCKET_QUEUE_SIZE equ 10 ; maximum number ofincoming packets queued for 1 socket
|
SOCKET_QUEUE_SIZE equ 10 ; maximum number ofincoming packets queued for 1 socket
|
||||||
; the incoming packet queue for sockets is placed in the socket struct itself, at this location from start
|
; the incoming packet queue for sockets is placed in the socket struct itself, at this location from start
|
||||||
SOCKET_QUEUE_LOCATION equ SOCKETBUFFSIZE - SOCKET_QUEUE_SIZE*socket_queue_entry.size - queue.data
|
SOCKET_QUEUE_LOCATION equ (SOCKETBUFFSIZE - SOCKET_QUEUE_SIZE*socket_queue_entry.size - queue.data)
|
||||||
|
|
||||||
uglobal
|
uglobal
|
||||||
net_sockets rd 4
|
net_sockets rd 4
|
||||||
|
last_socket_num dd ?
|
||||||
last_UDP_port dw ? ; These values give the number of the last used ephemeral port
|
last_UDP_port dw ? ; These values give the number of the last used ephemeral port
|
||||||
last_TCP_port dw ? ;
|
last_TCP_port dw ? ;
|
||||||
endg
|
endg
|
||||||
@ -221,7 +219,7 @@ macro SOCKET_init {
|
|||||||
|
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
mov edi, net_sockets
|
mov edi, net_sockets
|
||||||
mov ecx, 4
|
mov ecx, 5
|
||||||
rep stosd
|
rep stosd
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
@ -303,9 +301,6 @@ SOCKET_open:
|
|||||||
cmp ecx, AF_INET4
|
cmp ecx, AF_INET4
|
||||||
jne .no_inet4
|
jne .no_inet4
|
||||||
|
|
||||||
push [IP_LIST]
|
|
||||||
pop [eax + IP_SOCKET.LocalIP] ; fill in local ip number
|
|
||||||
|
|
||||||
cmp edx, SOCK_DGRAM
|
cmp edx, SOCK_DGRAM
|
||||||
je .udp
|
je .udp
|
||||||
|
|
||||||
@ -320,8 +315,8 @@ SOCKET_open:
|
|||||||
|
|
||||||
align 4
|
align 4
|
||||||
.raw:
|
.raw:
|
||||||
; test esi, esi ; IP_PROTO_IP
|
test esi, esi ; IP_PROTO_IP
|
||||||
; jz .ip
|
jz .ip
|
||||||
|
|
||||||
cmp esi, IP_PROTO_ICMP
|
cmp esi, IP_PROTO_ICMP
|
||||||
je .icmp
|
je .icmp
|
||||||
@ -337,61 +332,29 @@ align 4
|
|||||||
align 4
|
align 4
|
||||||
.udp:
|
.udp:
|
||||||
mov [eax + SOCKET.Protocol], IP_PROTO_UDP
|
mov [eax + SOCKET.Protocol], IP_PROTO_UDP
|
||||||
|
|
||||||
call SOCKET_find_port ; fill in a local port number, application may change it later, or use this one
|
|
||||||
|
|
||||||
push eax
|
|
||||||
init_queue (eax + SOCKET_QUEUE_LOCATION)
|
|
||||||
pop eax
|
|
||||||
|
|
||||||
mov [eax + SOCKET.snd_proc], SOCKET_send_udp
|
mov [eax + SOCKET.snd_proc], SOCKET_send_udp
|
||||||
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
|
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
.tcp:
|
.tcp:
|
||||||
mov [eax + SOCKET.Protocol], IP_PROTO_TCP
|
mov [eax + SOCKET.Protocol], IP_PROTO_TCP
|
||||||
|
mov [eax + SOCKET.snd_proc], SOCKET_send_tcp
|
||||||
call SOCKET_find_port ; fill in a local port number, application may change it later, or use this one
|
mov [eax + SOCKET.rcv_proc], SOCKET_receive_tcp
|
||||||
|
|
||||||
mov ebx, eax
|
|
||||||
|
|
||||||
lea eax, [ebx + STREAM_SOCKET.snd]
|
|
||||||
call SOCKET_ring_create
|
|
||||||
|
|
||||||
lea eax, [ebx + STREAM_SOCKET.rcv]
|
|
||||||
call SOCKET_ring_create
|
|
||||||
|
|
||||||
mov [ebx + SOCKET.snd_proc], SOCKET_send_tcp
|
|
||||||
mov [ebx + SOCKET.rcv_proc], SOCKET_receive_tcp
|
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
;align 4
|
align 4
|
||||||
; .ip:
|
.ip:
|
||||||
;
|
mov [eax + SOCKET.snd_proc], SOCKET_send_ip
|
||||||
; push eax
|
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
|
||||||
; init_queue (eax + SOCKET_QUEUE_LOCATION)
|
ret
|
||||||
; pop eax
|
|
||||||
;
|
|
||||||
; mov [eax + SOCKET.snd_proc], SOCKET_send_ip
|
|
||||||
; mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
|
|
||||||
;
|
|
||||||
; ret
|
|
||||||
|
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
.icmp:
|
.icmp:
|
||||||
|
|
||||||
push eax
|
|
||||||
init_queue (eax + SOCKET_QUEUE_LOCATION)
|
|
||||||
pop eax
|
|
||||||
|
|
||||||
mov [eax + SOCKET.snd_proc], SOCKET_send_icmp
|
mov [eax + SOCKET.snd_proc], SOCKET_send_icmp
|
||||||
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
|
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
@ -426,7 +389,6 @@ SOCKET_bind:
|
|||||||
jmp s_error
|
jmp s_error
|
||||||
|
|
||||||
.af_unix:
|
.af_unix:
|
||||||
|
|
||||||
; TODO: write code here
|
; TODO: write code here
|
||||||
|
|
||||||
mov dword [esp+32], 0
|
mov dword [esp+32], 0
|
||||||
@ -439,17 +401,11 @@ SOCKET_bind:
|
|||||||
cmp esi, 6
|
cmp esi, 6
|
||||||
jl s_error
|
jl s_error
|
||||||
|
|
||||||
mov bx, word [edx + 2]
|
push word [edx + 2]
|
||||||
test bx, bx
|
pop word [eax + UDP_SOCKET.LocalPort]
|
||||||
jz .use_preset_port
|
|
||||||
|
|
||||||
call SOCKET_check_port
|
push dword [edx + 4]
|
||||||
jz s_error
|
pop [eax + IP_SOCKET.LocalIP]
|
||||||
|
|
||||||
DEBUGF 1,"using local port: %u\n", bx
|
|
||||||
mov word [eax + UDP_SOCKET.LocalPort], bx
|
|
||||||
|
|
||||||
.use_preset_port:
|
|
||||||
|
|
||||||
DEBUGF 1,"local ip: %u.%u.%u.%u\n",\
|
DEBUGF 1,"local ip: %u.%u.%u.%u\n",\
|
||||||
[eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\
|
[eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\
|
||||||
@ -488,6 +444,11 @@ SOCKET_connect:
|
|||||||
jmp s_error
|
jmp s_error
|
||||||
|
|
||||||
.af_inet4:
|
.af_inet4:
|
||||||
|
cmp [eax + IP_SOCKET.LocalIP], 0
|
||||||
|
jne @f
|
||||||
|
push [IP_LIST]
|
||||||
|
pop [eax + IP_SOCKET.LocalIP]
|
||||||
|
@@:
|
||||||
|
|
||||||
cmp [eax + SOCKET.Protocol], IP_PROTO_UDP
|
cmp [eax + SOCKET.Protocol], IP_PROTO_UDP
|
||||||
je .udp
|
je .udp
|
||||||
@ -505,15 +466,27 @@ SOCKET_connect:
|
|||||||
|
|
||||||
align 4
|
align 4
|
||||||
.udp:
|
.udp:
|
||||||
mov bx , word [edx + 2]
|
lea ebx, [eax + SOCKET.lock]
|
||||||
mov word [eax + UDP_SOCKET.RemotePort], bx
|
call wait_mutex
|
||||||
|
|
||||||
|
push word [edx + 2]
|
||||||
|
pop [eax + UDP_SOCKET.RemotePort]
|
||||||
|
|
||||||
|
push dword [edx + 4]
|
||||||
|
pop [eax + IP_SOCKET.RemoteIP]
|
||||||
|
|
||||||
|
cmp [eax + UDP_SOCKET.LocalPort], 0
|
||||||
|
jne @f
|
||||||
|
call SOCKET_find_port
|
||||||
|
@@:
|
||||||
|
|
||||||
mov [eax + UDP_SOCKET.firstpacket], 0
|
mov [eax + UDP_SOCKET.firstpacket], 0
|
||||||
DEBUGF 1,"remote port: %u\n",bx
|
|
||||||
|
|
||||||
mov ebx, dword [edx + 4]
|
push eax
|
||||||
mov dword [eax + IP_SOCKET.RemoteIP], ebx
|
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
|
||||||
DEBUGF 1,"remote ip: %u.%u.%u.%u\n",[edx+4]:1,[edx+5]:1,[edx+6]:1,[edx+7]:1
|
pop eax
|
||||||
|
|
||||||
|
mov [eax + SOCKET.lock], 0
|
||||||
mov dword [esp+32], 0
|
mov dword [esp+32], 0
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -522,16 +495,17 @@ align 4
|
|||||||
lea ebx, [eax + SOCKET.lock]
|
lea ebx, [eax + SOCKET.lock]
|
||||||
call wait_mutex
|
call wait_mutex
|
||||||
|
|
||||||
; fill in remote port and IP
|
push word [edx + 2]
|
||||||
|
pop [eax + TCP_SOCKET.RemotePort]
|
||||||
|
|
||||||
mov bx , word [edx + 2]
|
push dword [edx + 4]
|
||||||
mov [eax + TCP_SOCKET.RemotePort], bx
|
pop [eax + IP_SOCKET.RemoteIP]
|
||||||
DEBUGF 1,"remote port: %u\n", bx
|
|
||||||
|
|
||||||
mov ebx, dword [edx + 4]
|
cmp [eax + TCP_SOCKET.LocalPort], 0
|
||||||
mov [eax + IP_SOCKET.RemoteIP], ebx
|
jne @f
|
||||||
|
call SOCKET_find_port
|
||||||
|
@@:
|
||||||
|
|
||||||
;;;;;
|
|
||||||
mov [eax + TCP_SOCKET.timer_persist], 0
|
mov [eax + TCP_SOCKET.timer_persist], 0
|
||||||
mov [eax + TCP_SOCKET.t_state], TCB_SYN_SENT
|
mov [eax + TCP_SOCKET.t_state], TCB_SYN_SENT
|
||||||
mov ebx, [TCP_sequence_num]
|
mov ebx, [TCP_sequence_num]
|
||||||
@ -541,23 +515,38 @@ align 4
|
|||||||
|
|
||||||
TCP_sendseqinit eax
|
TCP_sendseqinit eax
|
||||||
|
|
||||||
;;;; mov [ebx + TCP_SOCKET.timer_retransmission], ;; todo: create macro to set retransmission timer
|
; mov [ebx + TCP_SOCKET.timer_retransmission], ;; todo: create macro to set retransmission timer
|
||||||
|
|
||||||
push eax
|
push eax
|
||||||
call TCP_output
|
call TCP_output
|
||||||
pop eax
|
pop eax
|
||||||
|
|
||||||
mov [eax + SOCKET.lock], 0
|
mov ebx, eax
|
||||||
|
|
||||||
mov dword [esp+32], 0 ; success!
|
lea eax, [ebx + STREAM_SOCKET.snd]
|
||||||
|
call SOCKET_ring_create
|
||||||
|
|
||||||
|
lea eax, [ebx + STREAM_SOCKET.rcv]
|
||||||
|
call SOCKET_ring_create
|
||||||
|
|
||||||
|
mov [ebx + SOCKET.lock], 0
|
||||||
|
mov dword [esp+32], 0
|
||||||
ret
|
ret
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
.ip:
|
.ip:
|
||||||
|
lea ebx, [eax + SOCKET.lock]
|
||||||
|
call wait_mutex
|
||||||
|
|
||||||
push dword [edx + 4]
|
push dword [edx + 4]
|
||||||
pop dword [eax + IP_SOCKET.RemoteIP]
|
pop dword [eax + IP_SOCKET.RemoteIP]
|
||||||
|
|
||||||
mov dword [esp+32], 0 ; success!
|
push eax
|
||||||
|
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
|
||||||
|
pop eax
|
||||||
|
|
||||||
|
mov [eax + SOCKET.lock], 0
|
||||||
|
mov dword [esp+32], 0
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
@ -584,16 +573,27 @@ SOCKET_listen:
|
|||||||
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
|
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
|
||||||
jne s_error
|
jne s_error
|
||||||
|
|
||||||
; TODO: check local port number
|
cmp [eax + TCP_SOCKET.LocalPort], 0
|
||||||
|
je s_error
|
||||||
|
|
||||||
|
cmp [eax + IP_SOCKET.LocalIP], 0
|
||||||
|
jne @f
|
||||||
|
push [IP_LIST]
|
||||||
|
pop [eax + IP_SOCKET.LocalIP]
|
||||||
|
@@:
|
||||||
|
|
||||||
cmp edx, MAX_backlog
|
cmp edx, MAX_backlog
|
||||||
jle .ok
|
jle @f
|
||||||
mov edx, MAX_backlog
|
mov edx, MAX_backlog
|
||||||
.ok:
|
@@:
|
||||||
|
|
||||||
mov [eax + TCP_SOCKET.backlog], dx
|
mov [eax + SOCKET.backlog], dx
|
||||||
|
or [eax + SOCKET.options], SO_ACCEPTCON
|
||||||
mov [eax + TCP_SOCKET.t_state], TCB_LISTEN
|
mov [eax + TCP_SOCKET.t_state], TCB_LISTEN
|
||||||
or [eax + SOCKET.options], SO_ACCEPTCON ;;;; TODO: set socket state to listen
|
|
||||||
|
push eax
|
||||||
|
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up sockets queue
|
||||||
|
pop eax
|
||||||
|
|
||||||
mov dword [esp+32], 0
|
mov dword [esp+32], 0
|
||||||
|
|
||||||
@ -618,40 +618,23 @@ SOCKET_accept:
|
|||||||
call SOCKET_num_to_ptr
|
call SOCKET_num_to_ptr
|
||||||
jz s_error
|
jz s_error
|
||||||
|
|
||||||
|
test [eax + SOCKET.options], SO_ACCEPTCON
|
||||||
|
jz s_error
|
||||||
|
|
||||||
cmp word [eax + SOCKET.Domain], AF_INET4
|
cmp word [eax + SOCKET.Domain], AF_INET4
|
||||||
je .af_inet4
|
jne s_error
|
||||||
|
|
||||||
jmp s_error
|
|
||||||
|
|
||||||
.af_inet4:
|
|
||||||
|
|
||||||
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
|
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
|
||||||
je .tcp
|
jne s_error
|
||||||
|
|
||||||
jmp s_error
|
get_from_queue (eax + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, s_error
|
||||||
|
|
||||||
.tcp:
|
|
||||||
|
|
||||||
lea ebx, [eax + SOCKET.lock]
|
|
||||||
call wait_mutex
|
|
||||||
|
|
||||||
movzx ebx, [eax + TCP_SOCKET.backlog_cur]
|
|
||||||
test ebx, ebx
|
|
||||||
jz .unlock_err
|
|
||||||
|
|
||||||
dec [eax + TCP_SOCKET.backlog_cur] ;;;;
|
|
||||||
mov eax, [eax + TCP_SOCKET.end + (ebx-1)*4] ;;;;;
|
|
||||||
mov [eax + SOCKET.lock], 0 ;;;;
|
|
||||||
mov dword [esp+32], 0 ;;;;
|
|
||||||
|
|
||||||
call TCP_output ;;;;;
|
|
||||||
|
|
||||||
|
mov eax, [esi]
|
||||||
|
call SOCKET_ptr_to_num
|
||||||
|
jz s_error
|
||||||
|
mov dword [esp+32], eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.unlock_err:
|
|
||||||
mov [eax + SOCKET.lock], 0
|
|
||||||
jmp s_error
|
|
||||||
|
|
||||||
|
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
;
|
;
|
||||||
@ -838,18 +821,18 @@ SOCKET_send_tcp:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
;align 4
|
align 4
|
||||||
;SOCKET_send_ip:
|
SOCKET_send_ip:
|
||||||
;
|
|
||||||
; DEBUGF 1,"type: IP\n"
|
DEBUGF 1,"type: IP\n"
|
||||||
;
|
|
||||||
; mov ecx, esi
|
mov ecx, esi
|
||||||
; mov esi, edx
|
mov esi, edx
|
||||||
;
|
|
||||||
; call IPv4_output_raw
|
call IPv4_output_raw
|
||||||
;
|
|
||||||
; mov dword [esp+32], eax
|
mov dword [esp+32], eax
|
||||||
; ret
|
ret
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
SOCKET_send_icmp:
|
SOCKET_send_icmp:
|
||||||
@ -1109,8 +1092,12 @@ SOCKET_input:
|
|||||||
align 4
|
align 4
|
||||||
SOCKET_ring_create:
|
SOCKET_ring_create:
|
||||||
|
|
||||||
|
push esi
|
||||||
mov esi, eax
|
mov esi, eax
|
||||||
|
|
||||||
|
push edx
|
||||||
stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW
|
stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW
|
||||||
|
pop edx
|
||||||
|
|
||||||
DEBUGF 1,"SOCKET_ring_created: %x\n", eax
|
DEBUGF 1,"SOCKET_ring_created: %x\n", eax
|
||||||
mov [esi + RING_BUFFER.start_ptr], eax
|
mov [esi + RING_BUFFER.start_ptr], eax
|
||||||
@ -1119,6 +1106,8 @@ SOCKET_ring_create:
|
|||||||
mov [esi + RING_BUFFER.size], 0
|
mov [esi + RING_BUFFER.size], 0
|
||||||
add eax, SOCKET_MAXDATA
|
add eax, SOCKET_MAXDATA
|
||||||
mov [esi + RING_BUFFER.end_ptr], eax
|
mov [esi + RING_BUFFER.end_ptr], eax
|
||||||
|
mov eax, esi
|
||||||
|
pop esi
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -1291,7 +1280,7 @@ SOCKET_notify_owner:
|
|||||||
call SOCKET_check
|
call SOCKET_check
|
||||||
jz .error
|
jz .error
|
||||||
|
|
||||||
push ecx esi
|
push eax ecx esi
|
||||||
|
|
||||||
; socket exists, now try to flag an event to the application
|
; socket exists, now try to flag an event to the application
|
||||||
|
|
||||||
@ -1319,7 +1308,7 @@ SOCKET_notify_owner:
|
|||||||
DEBUGF 1,"SOCKET_notify_owner: succes!\n"
|
DEBUGF 1,"SOCKET_notify_owner: succes!\n"
|
||||||
|
|
||||||
.error2:
|
.error2:
|
||||||
pop esi ecx
|
pop esi ecx eax
|
||||||
|
|
||||||
.error:
|
.error:
|
||||||
|
|
||||||
@ -1363,9 +1352,12 @@ SOCKET_alloc:
|
|||||||
mov [eax + SOCKET.rcv_proc], s_error
|
mov [eax + SOCKET.rcv_proc], s_error
|
||||||
|
|
||||||
; find first free socket number and use it
|
; find first free socket number and use it
|
||||||
xor ecx, ecx
|
mov ecx, [last_socket_num]
|
||||||
.next_socket_number:
|
.next_socket_number:
|
||||||
inc ecx
|
inc ecx
|
||||||
|
jz .next_socket_number ; avoid socket nr 0
|
||||||
|
cmp ecx, -1
|
||||||
|
je .next_socket_number ; avoid socket nr -1
|
||||||
mov ebx, net_sockets
|
mov ebx, net_sockets
|
||||||
.next_socket:
|
.next_socket:
|
||||||
mov ebx, [ebx + SOCKET.NextPtr]
|
mov ebx, [ebx + SOCKET.NextPtr]
|
||||||
@ -1377,6 +1369,7 @@ SOCKET_alloc:
|
|||||||
jmp .next_socket_number
|
jmp .next_socket_number
|
||||||
|
|
||||||
.last_socket:
|
.last_socket:
|
||||||
|
mov [last_socket_num], ecx
|
||||||
mov [eax + SOCKET.Number], ecx
|
mov [eax + SOCKET.Number], ecx
|
||||||
DEBUGF 1, "SOCKET_alloc: number=%u\n", ecx
|
DEBUGF 1, "SOCKET_alloc: number=%u\n", ecx
|
||||||
mov edi, ecx
|
mov edi, ecx
|
||||||
@ -1469,39 +1462,57 @@ SOCKET_free:
|
|||||||
.error:
|
.error:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
;------------------------------------
|
||||||
|
;
|
||||||
|
; SOCKET_fork
|
||||||
|
;
|
||||||
|
; Create a child socket
|
||||||
|
;
|
||||||
; IN: socket nr in ebx
|
; IN: socket nr in ebx
|
||||||
; OUT: socket nr in eax
|
; OUT: child socket nr in eax
|
||||||
; preserves edx
|
;
|
||||||
|
;-----------------------------------
|
||||||
align 4
|
align 4
|
||||||
SOCKET_fork:
|
SOCKET_fork:
|
||||||
|
|
||||||
;; Exit if backlog queue is full
|
DEBUGF 1,"SOCKET_fork: %x\n", ebx
|
||||||
; mov ax, [ebx + TCP_SOCKET.backlog_cur]
|
|
||||||
; cmp ax, [ebx + TCP_SOCKET.backlog]
|
; Exit if backlog queue is full
|
||||||
; jae .exit
|
mov eax, [ebx + SOCKET_QUEUE_LOCATION + queue.size]
|
||||||
|
cmp ax, [ebx + SOCKET.backlog]
|
||||||
|
jge .fail
|
||||||
|
|
||||||
; Allocate new socket
|
; Allocate new socket
|
||||||
call SOCKET_alloc
|
call SOCKET_alloc
|
||||||
;;; jz .fail
|
jz .fail
|
||||||
|
|
||||||
; Copy structure from current socket to new, (including lock!)
|
push esi ecx edi
|
||||||
; We start at PID to reserve the socket num, and the 2 pointers at beginning of socket
|
push eax
|
||||||
lea esi, [edx + SOCKET.PID]
|
mov esi, esp
|
||||||
|
add_to_queue (ebx + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .fail2
|
||||||
|
pop eax
|
||||||
|
|
||||||
|
; Copy structure from current socket to new
|
||||||
|
; We start at PID to preserve the socket num, and the 2 pointers at beginning of socket
|
||||||
|
lea esi, [ebx + SOCKET.PID]
|
||||||
lea edi, [eax + SOCKET.PID]
|
lea edi, [eax + SOCKET.PID]
|
||||||
mov ecx, (TCP_SOCKET.end - SOCKET.PID + 3)/4
|
mov ecx, (SOCKET_QUEUE_LOCATION - SOCKET.PID + 3)/4
|
||||||
rep movsd
|
rep movsd
|
||||||
|
|
||||||
;; Push pointer to new socket to queue
|
and [eax + SOCKET.options], not SO_ACCEPTCON
|
||||||
; movzx ecx, [ebx + TCP_SOCKET.backlog_cur]
|
|
||||||
; inc [ebx + TCP_SOCKET.backlog_cur]
|
|
||||||
; mov [ebx + TCP_SOCKET.end + ecx*4], eax
|
|
||||||
|
|
||||||
;;;; mov [eax + IP_SOCKET.RemoteIP], esi ; IP source address
|
call SOCKET_notify_owner
|
||||||
|
pop edi ecx esi
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
.fail2:
|
||||||
|
add esp, 4+4+4
|
||||||
|
.fail:
|
||||||
|
DEBUGF 1,"SOCKET_fork: failed\n"
|
||||||
|
xor eax, eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
;---------------------------------------------------
|
;---------------------------------------------------
|
||||||
;
|
;
|
||||||
|
@ -74,7 +74,7 @@ SOCKET_MAXDATA equ 4096*32 ; must be 4096*(power of 2) where 'power of 2' is at
|
|||||||
NET_TYPE_ETH equ 1
|
NET_TYPE_ETH equ 1
|
||||||
NET_TYPE_SLIP equ 2
|
NET_TYPE_SLIP equ 2
|
||||||
|
|
||||||
MAX_backlog equ 20 ; backlog for stream sockets
|
MAX_backlog equ 20 ; maximum backlog for stream sockets
|
||||||
|
|
||||||
|
|
||||||
virtual at 0
|
virtual at 0
|
||||||
@ -112,7 +112,7 @@ macro pseudo_random reg {
|
|||||||
rol reg, 9
|
rol reg, 9
|
||||||
}
|
}
|
||||||
|
|
||||||
macro ntohld reg {
|
macro ntohd reg {
|
||||||
|
|
||||||
rol word reg, 8
|
rol word reg, 8
|
||||||
rol dword reg, 16
|
rol dword reg, 16
|
||||||
@ -120,7 +120,7 @@ macro ntohld reg {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro ntohlw reg {
|
macro ntohw reg {
|
||||||
|
|
||||||
rol word reg, 8
|
rol word reg, 8
|
||||||
|
|
||||||
|
@ -356,13 +356,13 @@ TCP_input:
|
|||||||
;-------------------------------------------
|
;-------------------------------------------
|
||||||
; Convert Big-endian values to little endian
|
; Convert Big-endian values to little endian
|
||||||
|
|
||||||
ntohld [edx + TCP_segment.SequenceNumber]
|
ntohd [edx + TCP_segment.SequenceNumber]
|
||||||
ntohld [edx + TCP_segment.AckNumber]
|
ntohd [edx + TCP_segment.AckNumber]
|
||||||
|
|
||||||
ntohlw [edx + TCP_segment.Window]
|
ntohw [edx + TCP_segment.Window]
|
||||||
ntohlw [edx + TCP_segment.UrgentPointer]
|
ntohw [edx + TCP_segment.UrgentPointer]
|
||||||
ntohlw [edx + TCP_segment.SourcePort]
|
ntohw [edx + TCP_segment.SourcePort]
|
||||||
ntohlw [edx + TCP_segment.DestinationPort]
|
ntohw [edx + TCP_segment.DestinationPort]
|
||||||
|
|
||||||
;------------------------------------------------------------
|
;------------------------------------------------------------
|
||||||
; Next thing to do is find the TCB (thus, the socket pointer)
|
; Next thing to do is find the TCB (thus, the socket pointer)
|
||||||
@ -378,7 +378,10 @@ TCP_input:
|
|||||||
or ebx, ebx
|
or ebx, ebx
|
||||||
jz .drop_with_reset
|
jz .drop_with_reset
|
||||||
|
|
||||||
cmp [ebx + SOCKET.Protocol], IP_PROTO_TCP ;;; We should also check if family is AF_INET
|
cmp [ebx + SOCKET.Domain], AF_INET4
|
||||||
|
jne .socket_loop
|
||||||
|
|
||||||
|
cmp [ebx + SOCKET.Protocol], IP_PROTO_TCP
|
||||||
jne .socket_loop
|
jne .socket_loop
|
||||||
|
|
||||||
mov ax, [edx + TCP_segment.DestinationPort]
|
mov ax, [edx + TCP_segment.DestinationPort]
|
||||||
@ -386,7 +389,7 @@ TCP_input:
|
|||||||
jne .socket_loop
|
jne .socket_loop
|
||||||
|
|
||||||
mov eax, [ebx + IP_SOCKET.RemoteIP]
|
mov eax, [ebx + IP_SOCKET.RemoteIP]
|
||||||
cmp eax, edi ; sender IP
|
cmp eax, edi ; edi is source ip from packet
|
||||||
je @f
|
je @f
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jnz .socket_loop
|
jnz .socket_loop
|
||||||
@ -417,22 +420,39 @@ TCP_input:
|
|||||||
|
|
||||||
DEBUGF 1,"Socket locked\n"
|
DEBUGF 1,"Socket locked\n"
|
||||||
|
|
||||||
;----------------------------------------------------------------------------------------
|
;---------------------------------------
|
||||||
; unscale the window into a 32 bit value (notice that SND_SCALE must be initialised to 0)
|
; unscale the window into a 32 bit value
|
||||||
|
|
||||||
movzx eax, [edx + TCP_segment.Window]
|
movzx eax, [edx + TCP_segment.Window]
|
||||||
push ecx
|
push ecx
|
||||||
mov cl, [ebx + TCP_SOCKET.SND_SCALE]
|
mov cl, [ebx + TCP_SOCKET.SND_SCALE]
|
||||||
shl eax, cl
|
shl eax, cl
|
||||||
|
mov dword [edx + TCP_segment.Window], eax ; word after window is checksum, we dont need checksum anymore
|
||||||
pop ecx
|
pop ecx
|
||||||
|
|
||||||
;;;; do something with eax
|
|
||||||
|
|
||||||
;-----------------------------------
|
;-----------------------------------
|
||||||
; 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
|
jz .no_listening_socket
|
||||||
|
|
||||||
|
call SOCKET_fork
|
||||||
|
jz .drop
|
||||||
|
|
||||||
|
push [edx + TCP_segment.DestinationPort]
|
||||||
|
pop [eax + TCP_SOCKET.LocalPort]
|
||||||
|
|
||||||
|
push [edx - IPv4_Packet.DataOrOptional + IPv4_Packet.DestinationAddress] ;;; FIXME
|
||||||
|
pop [eax + IP_SOCKET.LocalIP]
|
||||||
|
|
||||||
|
push [edx - IPv4_Packet.DataOrOptional + IPv4_Packet.SourceAddress] ;;; FIXME
|
||||||
|
pop [eax + IP_SOCKET.RemoteIP]
|
||||||
|
|
||||||
|
mov [eax + TCP_SOCKET.t_state], TCB_LISTEN
|
||||||
|
|
||||||
|
jmp .not_uni_xfer
|
||||||
|
|
||||||
|
.no_listening_socket:
|
||||||
|
|
||||||
;-------------------------------------
|
;-------------------------------------
|
||||||
; Reset idle timer and keepalive timer
|
; Reset idle timer and keepalive timer
|
||||||
@ -449,7 +469,7 @@ TCP_input:
|
|||||||
DEBUGF 1,"Segment has options\n"
|
DEBUGF 1,"Segment has options\n"
|
||||||
|
|
||||||
cmp [ebx + TCP_SOCKET.t_state], TCB_LISTEN ; no options when in listen state
|
cmp [ebx + TCP_SOCKET.t_state], TCB_LISTEN ; no options when in listen state
|
||||||
jz .no_options
|
jz .not_uni_xfer ; also no header prediction
|
||||||
|
|
||||||
lea edi, [edx + TCP_segment.Data]
|
lea edi, [edx + TCP_segment.Data]
|
||||||
lea eax, [edx + esi]
|
lea eax, [edx + esi]
|
||||||
@ -553,7 +573,7 @@ TCP_input:
|
|||||||
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 instead: todo: figure out where to store it)
|
mov eax, dword [edx + TCP_segment.Window]
|
||||||
cmp eax, [ebx + TCP_SOCKET.SND_WND]
|
cmp eax, [ebx + TCP_SOCKET.SND_WND]
|
||||||
jne .not_uni_xfer
|
jne .not_uni_xfer
|
||||||
|
|
||||||
@ -687,7 +707,7 @@ align 4
|
|||||||
|
|
||||||
DEBUGF 1,"TCP state: listen\n"
|
DEBUGF 1,"TCP state: listen\n"
|
||||||
|
|
||||||
test [edx + TCP_segment.Flags], TH_RST
|
test [edx + TCP_segment.Flags], TH_RST ;;; TODO: kill new socket on error
|
||||||
jnz .drop
|
jnz .drop
|
||||||
|
|
||||||
test [edx + TCP_segment.Flags], TH_ACK
|
test [edx + TCP_segment.Flags], TH_ACK
|
||||||
@ -696,14 +716,9 @@ align 4
|
|||||||
test [edx + TCP_segment.Flags], TH_SYN
|
test [edx + TCP_segment.Flags], TH_SYN
|
||||||
jz .drop
|
jz .drop
|
||||||
|
|
||||||
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
|
|
||||||
jz .drop ; if we could not open a new connection, drop segment (;;;; should we send RST too?)
|
|
||||||
|
|
||||||
;-----------------------
|
;-----------------------
|
||||||
; Fill in some variables
|
; Fill in some variables
|
||||||
|
|
||||||
@ -718,11 +733,23 @@ align 4
|
|||||||
push [eax + TCP_SOCKET.ISS]
|
push [eax + TCP_SOCKET.ISS]
|
||||||
pop [eax + TCP_SOCKET.SND_NXT]
|
pop [eax + TCP_SOCKET.SND_NXT]
|
||||||
|
|
||||||
|
TCP_sendseqinit eax
|
||||||
|
TCP_rcvseqinit eax
|
||||||
|
|
||||||
mov [eax + TCP_SOCKET.t_state], TCB_SYN_RECEIVED
|
mov [eax + TCP_SOCKET.t_state], TCB_SYN_RECEIVED
|
||||||
mov [eax + TCP_SOCKET.t_flags], TF_ACKNOW
|
mov [eax + TCP_SOCKET.t_flags], TF_ACKNOW
|
||||||
mov [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval
|
mov [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval ;;;; macro
|
||||||
|
|
||||||
mov ebx, eax
|
add eax, STREAM_SOCKET.snd
|
||||||
|
call SOCKET_ring_create
|
||||||
|
|
||||||
|
add eax, STREAM_SOCKET.rcv - STREAM_SOCKET.snd
|
||||||
|
call SOCKET_ring_create
|
||||||
|
|
||||||
|
sub eax, STREAM_SOCKET.rcv
|
||||||
|
|
||||||
|
mov [eax + SOCKET.lock], 0
|
||||||
|
mov ebx, eax ; if there is data, it must arrive in this new socket!
|
||||||
jmp .trim_then_step6
|
jmp .trim_then_step6
|
||||||
|
|
||||||
|
|
||||||
@ -830,9 +857,6 @@ align 4
|
|||||||
jmp .step6
|
jmp .step6
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.trim_then_step6:
|
.trim_then_step6:
|
||||||
|
|
||||||
;----------------------------
|
;----------------------------
|
||||||
@ -1083,7 +1107,7 @@ align 4
|
|||||||
mov eax, [ebx + TCP_SOCKET.SND_MAX]
|
mov eax, [ebx + TCP_SOCKET.SND_MAX]
|
||||||
cmp eax, [edx + TCP_segment.AckNumber]
|
cmp eax, [edx + TCP_segment.AckNumber]
|
||||||
je .all_outstanding
|
je .all_outstanding
|
||||||
mov [ebx + TCP_SOCKET.timer_retransmission], 120 ;;;; TODO: correct this value
|
mov [ebx + TCP_SOCKET.timer_retransmission], 120 ;;;; TODO: correct this value (use a macro for it)
|
||||||
.all_outstanding:
|
.all_outstanding:
|
||||||
|
|
||||||
;-------------------------------------------
|
;-------------------------------------------
|
||||||
@ -1182,7 +1206,7 @@ align 4
|
|||||||
jg .no_window_update
|
jg .no_window_update
|
||||||
@@:
|
@@:
|
||||||
|
|
||||||
mov eax, [ebx + TCP_SOCKET.SND_WL2] ;;;;
|
mov eax, [ebx + TCP_SOCKET.SND_WL2]
|
||||||
cmp eax, [edx + TCP_segment.AckNumber]
|
cmp eax, [edx + TCP_segment.AckNumber]
|
||||||
jne .no_window_update
|
jne .no_window_update
|
||||||
|
|
||||||
@ -1212,7 +1236,7 @@ align 4
|
|||||||
;
|
;
|
||||||
; @@:
|
; @@:
|
||||||
|
|
||||||
movzx eax, [edx + TCP_segment.Window] ;;; FIXME: use pre-calculated value instead!
|
mov eax, dword [edx + TCP_segment.Window]
|
||||||
cmp eax, [ebx + TCP_SOCKET.max_sndwnd]
|
cmp eax, [ebx + TCP_SOCKET.max_sndwnd]
|
||||||
jle @f
|
jle @f
|
||||||
mov [ebx + TCP_SOCKET.max_sndwnd], eax
|
mov [ebx + TCP_SOCKET.max_sndwnd], eax
|
||||||
@ -1288,7 +1312,7 @@ align 4
|
|||||||
lea esi, [edx + eax]
|
lea esi, [edx + eax]
|
||||||
|
|
||||||
or [ebx + TCP_SOCKET.t_flags], TF_DELACK
|
or [ebx + TCP_SOCKET.t_flags], TF_DELACK
|
||||||
add [ebx + TCP_SOCKET.RCV_NXT], ecx ;;; right ?
|
add [ebx + TCP_SOCKET.RCV_NXT], ecx
|
||||||
|
|
||||||
lea eax, [ebx + STREAM_SOCKET.rcv]
|
lea eax, [ebx + STREAM_SOCKET.rcv]
|
||||||
call SOCKET_ring_write
|
call SOCKET_ring_write
|
||||||
@ -1558,7 +1582,7 @@ TCP_output:
|
|||||||
|
|
||||||
.no_zero_window:
|
.no_zero_window:
|
||||||
|
|
||||||
mov [eax + TCP_SOCKET.timer_persist], 0 ;;;;
|
mov [eax + TCP_SOCKET.timer_persist], 0
|
||||||
mov [eax + TCP_SOCKET.t_rxtshift], 0
|
mov [eax + TCP_SOCKET.t_rxtshift], 0
|
||||||
|
|
||||||
.no_persist_timeout:
|
.no_persist_timeout:
|
||||||
@ -1800,16 +1824,16 @@ TCP_output:
|
|||||||
shr edi, 2 ; .DataOffset db ? ;;;;
|
shr edi, 2 ; .DataOffset db ? ;;;;
|
||||||
|
|
||||||
push [eax + TCP_SOCKET.RCV_NXT] ; .AckNumber dd ?
|
push [eax + TCP_SOCKET.RCV_NXT] ; .AckNumber dd ?
|
||||||
ntohld [esp]
|
ntohd [esp]
|
||||||
|
|
||||||
push [eax + TCP_SOCKET.SND_NXT] ; .SequenceNumber dd ?
|
push [eax + TCP_SOCKET.SND_NXT] ; .SequenceNumber dd ?
|
||||||
ntohld [esp]
|
ntohd [esp]
|
||||||
|
|
||||||
push [eax + TCP_SOCKET.RemotePort] ; .DestinationPort dw ?
|
push [eax + TCP_SOCKET.RemotePort] ; .DestinationPort dw ?
|
||||||
ntohlw [esp]
|
ntohw [esp]
|
||||||
|
|
||||||
push [eax + TCP_SOCKET.LocalPort] ; .SourcePort dw ?
|
push [eax + TCP_SOCKET.LocalPort] ; .SourcePort dw ?
|
||||||
ntohlw [esp]
|
ntohw [esp]
|
||||||
|
|
||||||
push edi ; header size
|
push edi ; header size
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user