Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1255 → Rev 1256

/kernel/branches/net/network/socket.inc
43,6 → 43,11
.RemotePort dw ? ; In INET byte order
 
.backlog dw ? ; Backlog
.backlog_cur dw ? ; current size of queue for un-accept-ed connections
.last_ack_number dd ? ; used only to let application know that ACK has been received
; todo: may be use SND_UNA instead
; todo: may be use events which allow additional information instead
; todo: may be count acknowledged bytes (at least it has obvious sense)
; .OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state)
; .OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state)
.wndsizeTimer dd ? ; window size timer
132,7 → 137,7
align 4
sys_socket:
and ebx, 0x000000FF ; should i remove this line ?
cmp bl , 7 ; highest possible number
cmp bl , 8 ; highest possible number
jg s_error
lea ebx, [.table + 4*ebx]
jmp dword [ebx]
146,7 → 151,7
dd socket_accept ; 5
dd socket_send ; 6
dd socket_recv ; 7
; dd socket_get_opt ; 8
dd socket_get_opt ; 8
; dd socket_set_opt ; 9
 
 
398,8 → 403,8
jne s_error
 
cmp edx, MAX_backlog
jl .ok
mov dx , 20
jb .ok
mov dx , MAX_backlog
.ok:
 
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog], dx
448,35 → 453,22
 
.tcp:
 
cmp [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog], 0
jz s_error
 
call net_socket_alloc
or eax, eax
jz s_error
mov edi, eax
 
dec [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog]
 
mov ecx, (SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.end+3)/4
push esi edi
rep movsd
pop edi esi
 
mov [edi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog], 0
 
; TODO: fill in structure in ecx
 
mov [esi + SOCKET_head.end + IPv4_SOCKET.RemoteIP], 0
mov [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort], 0
 
stdcall net_socket_addr_to_num, edi
lea ebx, [esi + SOCKET_head.lock]
call wait_mutex
movzx eax, [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur]
test eax, eax
jz .unlock_err
dec [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur]
mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.end + (eax-1)*4]
mov [esi + SOCKET_head.lock], 0
stdcall net_socket_addr_to_num, eax
mov [esp+32], eax
 
ret
.unlock_err:
mov [esi + SOCKET_head.lock], 0
jmp s_error
 
 
 
;-----------------------------------------------
;
; SOCKET_close
753,6 → 745,47
mov [esp+32], eax
ret
 
;-----------------------------------------------
;
; SOCKET_send
;
;
; IN: socket number in ecx
; edx points to the options:
; dd level, optname, optval, optlen
; OUT: -1 on error
;
; At moment, uses only pseudo-optname -2 for get last_ack_number for TCP.
; TODO: find best way to notify that send()'ed data were acknowledged
;
;-----------------------------------------------
socket_get_opt:
cmp dword [edx], IP_PROTO_TCP
jnz .unknown
cmp dword [edx+4], -2
jnz .unknown
mov eax, [edx+12]
test eax, eax
jz .fail
cmp dword [eax], 4
mov dword [eax], 4
jb .fail
stdcall net_socket_num_to_addr, ecx
test eax, eax
jz .fail
; todo: check that eax is really TCP socket
mov ecx, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.last_ack_number]
mov eax, [edx+8]
test eax, eax
jz @f
mov [eax], ecx
@@:
xor eax, eax
ret
.fail:
.unknown:
or eax, -1
ret
 
 
;-----------------------------------------------
872,12 → 905,13
push ecx ; size
push esi ; data_ptr
mov esi, esp
add_to_queue (eax + 2048), SOCKET_QUEUE_SIZE, 3*4, .full
add_to_queue (eax + 2048), SOCKET_QUEUE_SIZE, 3*4, notify_network_event.full
DEBUGF 1,"Queued packet successfully\n"
add esp, 4*3
 
mov [eax + SOCKET_head.lock], 0
 
notify_network_event:
; flag an event to the application
mov edx, [eax + SOCKET_head.PID] ; get socket owner PID
mov ecx, 1
907,7 → 941,6
 
 
 
 
; Allocate memory for socket data and put new socket into the list
; Newly created socket is initialized with calling PID and number and
; put into beginning of list (which is a fastest way).
/kernel/branches/net/network/stack.inc
77,23 → 77,23
 
macro inc_INET reg {
 
inc byte [reg + 3]
add byte [reg + 3], 1
adc byte [reg + 2], 0
adc byte [reg + 1], 0
adc byte [reg + 0], 0
adc byte [reg], 0
 
}
 
 
macro add_INET reg {
 
add byte [reg + 3], cl
adc byte [reg + 2], ch
adc byte [reg + 1], 0
adc byte [reg], 0
rol ecx, 16
adc byte [reg + 3], ch
adc byte [reg + 2], cl
add byte [reg + 1], cl
adc byte [reg], ch
rol ecx, 16
adc byte [reg + 1], ch
adc byte [reg + 0], cl
 
}
 
include "queue.inc"
/kernel/branches/net/network/tcp.inc
360,6 → 360,7
; add eax, ecx ;
 
mov eax, [edx + TCP_Packet.AckNumber]
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.last_ack_number], eax
;---------
 
cmp [TCP_OUT_QUEUE], 0
615,32 → 616,58
; Look at control flags
test [edx + TCP_Packet.Flags], TH_SYN
jz .exit
; Exit if backlog queue is full
mov ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur]
cmp ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog]
jae .exit
; Allocate new socket
push esi
call net_socket_alloc
pop esi
test eax, eax
jz .exit
; Copy structure from current socket to new, including lock
push esi edi
lea esi, [ebx + SOCKET_head.PID] ; yes, PID must also be copied
lea edi, [eax + SOCKET_head.PID]
mov ecx, ((SOCKET_head.end - SOCKET_head.PID) + IPv4_SOCKET.end + TCP_SOCKET.end + 3)/4
rep movsd
pop edi esi
; Push pointer to new socket to queue
movzx ecx, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur]
inc [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur]
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.end + ecx*4], eax
 
; We have a SYN. update the socket with this IP Packets details,
; And send a response
 
mov [ebx + SOCKET_head.end + IPv4_SOCKET.RemoteIP], esi ; IP source address
mov ax, [edx + TCP_Packet.SourcePort]
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort], ax
mov eax, [edx + TCP_Packet.SequenceNumber]
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.IRS], eax
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT], eax
lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
mov [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], esi ; IP source address
mov cx, [edx + TCP_Packet.SourcePort]
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort], cx
mov ecx, [edx + TCP_Packet.SequenceNumber]
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.IRS], ecx
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT], ecx
lea esi, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT]
inc_INET esi ; RCV.NXT
mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.ISS]
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT], eax
mov ecx, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.ISS]
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT], ecx
 
mov [eax + SOCKET_head.lock], 0
mov [ebx + SOCKET_head.lock], 0
 
push eax
; Now construct the response
mov bl, TH_SYN + TH_ACK
call TCP_send_ack
pop eax
 
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED
call notify_network_event
 
; increment SND.NXT in socket
lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
lea esi, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
inc_INET esi
ret
 
.exit:
mov [ebx + SOCKET_head.lock], 0
721,6 → 748,8
jz .exit
 
mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED
mov eax, ebx
call notify_network_event
 
.exit:
mov [ebx + SOCKET_head.lock], 0