Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4029 → Rev 4030

/kernel/trunk/network/IPv4.inc
910,6 → 910,44
ret
 
 
;-----------------------------------------------------------------
;
; IPv4_connect
;
; IN: eax = socket pointer
; OUT: eax = 0 ok / -1 error
; ebx = error code
;
;-------------------------
align 4
IPv4_connect:
 
pusha
lea ecx, [eax + SOCKET.mutex]
call mutex_lock
popa
 
; Fill in local IP
cmp [eax + IP_SOCKET.LocalIP], 0
jne @f
push [IP_LIST + 4] ; FIXME: use correct local IP
pop [eax + IP_SOCKET.LocalIP]
 
; Fill in remote IP
pushd [edx + 4]
pop [eax + IP_SOCKET.RemoteIP]
 
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
pop eax
 
lea ecx, [eax + SOCKET.mutex]
call mutex_unlock
 
xor eax, eax
ret
 
 
;---------------------------------------------------------------------------
;
; IPv4_API
/kernel/trunk/network/socket.inc
39,6 → 39,7
 
snd_proc dd ?
rcv_proc dd ?
connect_proc dd ?
 
ends
 
150,7 → 151,6
 
LocalPort dw ? ; network byte order
RemotePort dw ? ; network byte order
firstpacket db ?
 
ends
 
311,6 → 311,7
mov [eax + SOCKET.Domain], ecx
mov [eax + SOCKET.Type], edx
mov [eax + SOCKET.Protocol], esi
mov [eax + SOCKET.connect_proc], connect_notsupp
 
cmp ecx, AF_INET4
jne .no_inet4
359,6 → 360,7
mov [eax + SOCKET.Protocol], IP_PROTO_UDP
mov [eax + SOCKET.snd_proc], SOCKET_send_udp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
mov [eax + SOCKET.connect_proc], UDP_connect
ret
 
align 4
366,6 → 368,7
mov [eax + SOCKET.Protocol], IP_PROTO_TCP
mov [eax + SOCKET.snd_proc], SOCKET_send_tcp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_stream
mov [eax + SOCKET.connect_proc], TCP_connect
 
TCP_init_socket eax
ret
375,6 → 378,7
.raw_ip:
mov [eax + SOCKET.snd_proc], SOCKET_send_ip
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
mov [eax + SOCKET.connect_proc], IPv4_connect
ret
 
 
382,6 → 386,7
.raw_icmp:
mov [eax + SOCKET.snd_proc], SOCKET_send_icmp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
mov [eax + SOCKET.connect_proc], IPv4_connect
ret
 
align 4
504,9 → 509,13
test [eax + SOCKET.options], SO_ACCEPTCON
jnz .notsupp
 
cmp word [edx], AF_INET4
je .af_inet4
call [eax + SOCKET.connect_proc]
 
mov dword[esp+20], ebx
mov dword[esp+32], eax
ret
 
 
.notsupp:
mov dword[esp+20], EOPNOTSUPP
mov dword[esp+32], -1
522,180 → 531,14
mov dword[esp+32], -1
ret
 
.eisconn:
mov dword[esp+20], EISCONN
mov dword[esp+32], -1
ret
 
.af_inet4:
cmp [eax + IP_SOCKET.LocalIP], 0
jne @f
push [IP_LIST + 4] ; FIXME: use correct local IP
pop [eax + IP_SOCKET.LocalIP]
@@:
 
cmp [eax + SOCKET.Protocol], IP_PROTO_UDP
je .udp
 
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
je .tcp
 
cmp [eax + SOCKET.Protocol], IP_PROTO_IP
je .ip
 
cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP
je .ip
 
jmp .notsupp
 
align 4
.udp:
pusha
lea ecx, [eax + SOCKET.mutex]
call mutex_lock
popa
 
; Fill in remote port and IP, overwriting eventually previous values
pushw [edx + 2]
pop [eax + UDP_SOCKET.RemotePort]
 
pushd [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
 
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
pop eax
 
lea ecx, [eax + SOCKET.mutex]
call mutex_unlock
 
call SOCKET_is_connected
 
mov dword[esp+32], 0
connect_notsupp:
xor eax, eax
dec eax
mov ebx, EOPNOTSUPP
ret
 
align 4
.tcp:
test [eax + SOCKET.state], SS_ISCONNECTED
jnz .eisconn
 
pusha
lea ecx, [eax + SOCKET.mutex]
call mutex_lock
popa
 
pushw [edx + 2]
pop [eax + TCP_SOCKET.RemotePort]
 
pushd [edx + 4]
pop [eax + IP_SOCKET.RemoteIP]
 
cmp [eax + TCP_SOCKET.LocalPort], 0
jne @f
call SOCKET_find_port
@@:
 
mov [eax + TCP_SOCKET.timer_persist], 0
mov [eax + TCP_SOCKET.t_state], TCPS_SYN_SENT
 
push [TCP_sequence_num]
add [TCP_sequence_num], 6400
pop [eax + TCP_SOCKET.ISS]
mov [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init
 
TCP_sendseqinit eax
 
mov ebx, eax
lea eax, [ebx + STREAM_SOCKET.snd]
call SOCKET_ring_create ; TODO: check if memory was available or not
 
lea eax, [ebx + STREAM_SOCKET.rcv]
call SOCKET_ring_create ; TODO: same here
 
push ebx
lea ecx, [ebx + SOCKET.mutex]
call mutex_unlock
pop eax
 
call SOCKET_is_connecting
 
push eax
call TCP_output
pop eax
 
.block:
test [eax + SOCKET.options], SO_NONBLOCK
jz .waitforit
 
mov dword[esp+32], -1
mov dword[esp+20], EINPROGRESS
ret
 
.waitforit:
push eax
stdcall timer_hs, 300, 0, .timeout, eax ; FIXME: make timeout a constant
pop ebx
mov [ebx + TCP_SOCKET.timer_connect], eax
mov eax, ebx
 
.loop:
cmp [eax + SOCKET.errorcode], 0
jne .fail
cmp [eax + TCP_SOCKET.t_state], TCPS_ESTABLISHED
je .established
 
call SOCKET_block
jmp .loop
 
.timeout:
mov eax, [esp+4]
mov [eax + SOCKET.errorcode], ETIMEDOUT
and [eax + SOCKET.state], not SS_ISCONNECTING
call SOCKET_notify.unblock
ret 4
 
.fail:
mov eax, [eax + SOCKET.errorcode]
mov [eax + SOCKET.errorcode], 0 ; Clear the error, we only need to send it to the caller once
mov [esp+20], eax
mov dword[esp+32], -1
ret
 
.established:
stdcall cancel_timer_hs, [eax + TCP_SOCKET.timer_connect]
mov dword[esp+20], EISCONN
mov dword[esp+32], 0
ret
 
 
align 4
.ip:
pusha
lea ecx, [eax + SOCKET.mutex]
call mutex_lock
popa
 
pushd [edx + 4]
pop [eax + IP_SOCKET.RemoteIP]
 
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
pop eax
 
lea ecx, [eax + SOCKET.mutex]
call mutex_unlock
 
mov dword[esp+32], 0
ret
 
 
;-----------------------------------------------------------------
;
; SOCKET_listen
/kernel/trunk/network/tcp.inc
71,6 → 71,8
TCP_time_srtt_default = 0 ;
TCP_time_max_idle = 8*TCP_time_keep_interval ; FIXME
 
TCP_time_connect = 300 ; in 1/100s (default=3s)
 
; timer constants
TCP_max_rxtshift = 12 ; max retransmissions waiting for ACK
TCP_max_keepcnt = 8 ; max keepalive probes
/kernel/trunk/network/tcp_usreq.inc
74,8 → 74,139
ret
 
 
;-------------------------
;
; TCP_connect
;
; IN: eax = socket ptr
; OUT: eax = 0 ok / -1 error
; ebx = error code
;
;-------------------------
align 4
TCP_connect:
 
test [eax + SOCKET.state], SS_ISCONNECTED
jnz .eisconn
 
push eax
lea ecx, [eax + SOCKET.mutex]
call mutex_lock
pop eax
 
; Fill in local IP
cmp [eax + IP_SOCKET.LocalIP], 0
jne @f
push [IP_LIST + 4] ; FIXME: use correct local IP
pop [eax + IP_SOCKET.LocalIP]
 
; Fill in remote port and IP
pushw [edx + 2]
pop [eax + TCP_SOCKET.RemotePort]
 
pushd [edx + 4]
pop [eax + IP_SOCKET.RemoteIP]
 
; Find a local port, if user didnt define one
cmp [eax + TCP_SOCKET.LocalPort], 0
jne @f
call SOCKET_find_port
@@:
 
; Start the TCP sequence
mov [eax + TCP_SOCKET.timer_persist], 0
mov [eax + TCP_SOCKET.t_state], TCPS_SYN_SENT
 
push [TCP_sequence_num]
add [TCP_sequence_num], 6400
pop [eax + TCP_SOCKET.ISS]
mov [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init
 
TCP_sendseqinit eax
 
mov ebx, eax
lea eax, [ebx + STREAM_SOCKET.snd]
call SOCKET_ring_create
test eax, eax
jz .nomem
 
lea eax, [ebx + STREAM_SOCKET.rcv]
call SOCKET_ring_create
test eax, eax
jz .nomem
 
push ebx
lea ecx, [ebx + SOCKET.mutex]
call mutex_unlock
pop eax
 
call SOCKET_is_connecting
 
; Now send the SYN packet to remote end
push eax
call TCP_output
pop eax
 
.block:
test [eax + SOCKET.options], SO_NONBLOCK
jz .waitforit
 
xor eax, eax
dec eax
mov ebx, EINPROGRESS
ret
 
.nomem:
xor eax, eax
dec eax
mov ebx, ENOMEM
ret
 
.eisconn:
xor eax, eax
dec eax
mov ebx, EISCONN
ret
 
.waitforit:
push eax
stdcall timer_hs, TCP_time_connect, 0, .timeout, eax
pop ebx
mov [ebx + TCP_SOCKET.timer_connect], eax
mov eax, ebx
 
.loop:
cmp [eax + SOCKET.errorcode], 0
jne .fail
cmp [eax + TCP_SOCKET.t_state], TCPS_ESTABLISHED
je .established
 
call SOCKET_block
jmp .loop
 
.timeout:
mov eax, [esp+4]
mov [eax + SOCKET.errorcode], ETIMEDOUT
and [eax + SOCKET.state], not SS_ISCONNECTING
call SOCKET_notify.unblock
ret 4
 
.fail:
mov ebx, [eax + SOCKET.errorcode]
mov [eax + SOCKET.errorcode], 0 ; Clear the error, we only need to send it to the caller once
xor eax, eax
dec eax
ret
 
.established:
stdcall cancel_timer_hs, [eax + TCP_SOCKET.timer_connect]
 
xor eax, eax
ret
 
 
 
 
;-------------------------
;
; TCP_disconnect
/kernel/trunk/network/udp.inc
182,7 → 182,7
;
; FIXME: UDP should check remote IP, but not under all circumstances!
 
cmp [eax + UDP_SOCKET.firstpacket], 0
cmp [eax + UDP_SOCKET.RemotePort], 0
je .updateport
 
cmp [eax + UDP_SOCKET.RemotePort], cx
211,8 → 211,6
 
DEBUGF DEBUG_NETWORK_VERBOSE, "UDP_input: new remote port=%x\n", cx ; FIXME: find a way to print big endian values with debugf
mov [eax + UDP_SOCKET.RemotePort], cx
inc [eax + UDP_SOCKET.firstpacket]
 
jmp .updatesock
 
.dump_:
311,6 → 309,84
 
 
 
 
;-----------------------------------------------------------------
;
; UDP_connect
;
; IN: eax = socket pointer
; OUT: eax = 0 ok / -1 error
; ebx = error code
;
;-------------------------
align 4
UDP_connect:
 
test [eax + SOCKET.state], SS_ISCONNECTED
jz @f
call UDP_disconnect
@@:
 
push eax
lea ecx, [eax + SOCKET.mutex]
call mutex_lock
pop eax
 
; Fill in local IP
cmp [eax + IP_SOCKET.LocalIP], 0
jne @f
push [IP_LIST + 4] ; FIXME: use correct local IP
pop [eax + IP_SOCKET.LocalIP]
 
; Fill in remote port and IP, overwriting eventually previous values
pushw [edx + 2]
pop [eax + UDP_SOCKET.RemotePort]
 
pushd [edx + 4]
pop [eax + IP_SOCKET.RemoteIP]
 
; Find a local port, if user didnt define one
cmp [eax + UDP_SOCKET.LocalPort], 0
jne @f
call SOCKET_find_port
@@:
 
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
pop eax
 
push eax
lea ecx, [eax + SOCKET.mutex]
call mutex_unlock
pop eax
 
call SOCKET_is_connected
 
xor eax, eax
ret
 
 
;-----------------------------------------------------------------
;
; UDP_disconnect
;
; IN: eax = socket pointer
; OUT: eax = socket pointer
;
;-------------------------
align 4
UDP_disconnect:
 
; TODO: remove the pending received data
 
call SOCKET_is_disconnected
 
ret
 
 
 
 
 
;---------------------------------------------------------------------------
;
; UDP_API