Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1253 → Rev 1254

/kernel/branches/net/network/socket.inc
43,12 → 43,15
.RemotePort dw ? ; In INET byte order
 
.backlog dw ? ; Backlog
.OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state)
.OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state)
.TCBState dd ? ; TCB state
.TCBTimer dd ? ; TCB timer (seconds)
.ISS dd ? ; initial send sequence
.IRS dd ? ; initial receive sequence
; .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
 
; Transmission control block
.state dd ? ; TCB state
.timer dd ? ; TCB timer (seconds)
.ISS dd ? ; initial send sequence number
.IRS dd ? ; initial receive sequence number
.SND_UNA dd ? ; sequence number of unack'ed sent Packets
.SND_NXT dd ? ; next send sequence number to use
.SND_WND dd ? ; send window
56,7 → 59,6
.RCV_WND dd ? ; receive window
.SEG_LEN dd ? ; segment length
.SEG_WND dd ? ; segment window
.wndsizeTimer dd ? ; window size timer
 
.flags db ? ; packet flags
 
121,36 → 123,33
ret
 
 
;-----------------------------------------------------------------------------
;-----------------------------------------------
;
; Socket API (function 74)
;
;-----------------------------------------------------------------------------
;-----------------------------------------------
 
align 4
sys_socket:
and ebx, 0x000000FF ; should i remove this line ?
cmp bl , 7 ; highest possible number
jg s_error
lea ebx, [.table + 4*ebx]
jmp dword [ebx]
 
test bl, bl
jz socket_open ; 0
dec bl
jz socket_close ; 1
dec bl
jz socket_bind ; 2
dec bl
jz socket_listen ; 3
dec bl
jz socket_connect ; 4
dec bl
jz socket_accept ; 5
dec bl
jz socket_send ; 6
dec bl
jz socket_recv ; 7
dec bl
; jz socket_get_opt ; 8
dec bl
; jz socket_set_opt ; 9
.table:
dd socket_open ; 0
dd socket_close ; 1
dd socket_bind ; 2
dd socket_listen ; 3
dd socket_connect ; 4
dd socket_accept ; 5
dd socket_send ; 6
dd socket_recv ; 7
; dd socket_get_opt ; 8
; dd socket_set_opt ; 9
 
 
s_error:
mov dword [esp+32],-1
 
157,8 → 156,6
ret
 
 
 
 
;-----------------------------------------------
;
; SOCKET_open
186,6 → 183,8
stdcall net_socket_addr_to_num, eax
DEBUGF 1,", socketnumber: %u\n", eax
 
; TODO: if it is txcp socket, set state to TCB_CLOSED
 
mov [esp+32], eax
 
ret
231,7 → 230,6
 
; TODO: write code here
 
 
mov dword [esp+32],0
ret
 
295,7 → 293,7
cmp eax, -1
jz s_error
 
cmp esi, 2
cmp esi, 8
jl s_error
 
cmp word [edx], AF_INET4
305,15 → 303,9
 
.af_inet4:
 
cmp esi, 8
jl s_error
 
cmp [eax + SOCKET_head.Type], IP_PROTO_UDP
je .udp
 
cmp [eax + SOCKET_head.Type], IP_PROTO_ICMP
je .icmp
 
cmp [eax + SOCKET_head.Type], IP_PROTO_TCP
je .tcp
 
332,92 → 324,49
mov dword [esp+32],0
ret
 
.icmp:
 
; TODO: write code here
.tcp:
; TODO: set sequence number to random value
 
ret
 
; fill in remote port and IP
 
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 0 ; Reset the window timer.
; TODO: figure out WTF this is
mov bx , word [edx + 2]
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort], bx
DEBUGF 1,"remote port: %x ",bx
 
.tcp:
mov ebx, dword [edx + 4]
mov [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], ebx
 
;local sockAddr dd ?
; check if local port and IP is ok
 
; cmp esi, SOCKET_PASSIVE
; jne .skip_port_check
;
; push ebx
; mov eax, ebx
; xchg al, ah
; mov ebx, net_sockets
;
; .next_socket:
; mov ebx, [ebx + SOCKET.NextPtr]
; or ebx, ebx
; jz .last_socket
; cmp [ebx + SOCKET.TCBState], TCB_LISTEN
; jne .next_socket
; cmp [ebx + SOCKET.LocalPort], ax
; jne .next_socket
;
; xchg al, ah
; DEBUGF 1, "K : error: port %u is listened by 0x%x\n", ax, ebx
; pop ebx
; jmp .error
;
; .last_socket:
; pop ebx
;
; .skip_port_check:
cmp [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP], 0
jne @f
push [IP_LIST] ; device zero = default
pop [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP]
@@:
 
; mov [eax + SOCKET.wndsizeTimer], 0 ; Reset the window timer.
;
; xchg bh, bl
; mov [eax + SOCKET.LocalPort], bx
; xchg ch, cl
; mov [eax + SOCKET.RemotePort], cx
; mov [eax + SOCKET.OrigRemotePort], cx
; mov ebx, [IP_LIST]
; mov [eax + SOCKET.LocalIP], ebx
; mov [eax + SOCKET.RemoteIP], edx
; mov [eax + SOCKET.OrigRemoteIP], edx
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], 0
jne @f
 
; mov ebx, TCB_LISTEN
; cmp esi, SOCKET_PASSIVE
; je @f
; mov ebx, TCB_SYN_SENT
; @@: mov [eax + SOCKET.TCBState], ebx ; Indicate the state of the TCB
mov ecx, [eax + SOCKET_head.Type]
call socket_find_port
test bx, bx
jz s_error
 
; cmp ebx, TCB_LISTEN
; je .exit
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], bx
@@:
 
; Now, if we are in active mode, then we have to send a SYN to the specified remote port
; mov eax, EMPTY_QUEUE
; call dequeue
; cmp ax, NO_BUFFER
; je .exit
 
; push eax
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_SENT
; now say hello to the remote tcp socket
 
; mov bl, TH_SYN
; xor ecx, ecx
; stdcall build_tcp_Packet, [sockAddr]
mov bl, TH_SYN
call TCP_send_ack
 
; mov eax, NET1OUT_QUEUE
; mov edx, [IP_LIST]
; mov ecx, [sockAddr]
; cmp edx, [ecx + SOCKET.RemoteIP]
; jne .not_local
; mov eax, IPIN_QUEUE
 
; .not_local:
; Send it.
; pop ebx
; call queue
 
.exit:
xor eax, eax
mov dword [esp+32],0
ret
 
 
442,6 → 391,12
cmp eax, -1
jz s_error
 
cmp word [eax + SOCKET_head.Domain], AF_INET4
jne s_error
 
cmp [eax + SOCKET_head.Type], IP_PROTO_TCP
jne s_error
 
cmp edx, MAX_backlog
jl .ok
mov dx , 20
448,9 → 403,8
.ok:
 
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog], dx
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LISTEN
 
; TODO: insert code for active connections like TCP
 
mov dword [esp+32], 0
ret
 
569,98 → 523,44
ret
 
.tcp:
; first, remove all resend entries for this socket
 
if 1 = 0
;local sockAddr dd ?
 
; DEBUGF 1, "K : socket_close_tcp (0x%x)\n", ebx
; first, remove any resend entries
pusha
 
mov esi, resendQ
mov ecx, 0
 
.next_resendq:
cmp ecx, NUMRESENDENTRIES
je .last_resendq ; None left
cmp [esi + 4], ebx
je @f ; found one
inc ecx
add esi, 8
jmp .next_resendq
 
@@: mov dword[esi + 4], 0
inc ecx
add esi, 8
jmp .next_resendq
 
.last_resendq:
popa
 
mov ebx, eax
; mov [sockAddr], eax
 
cmp [eax + SOCKET.TCBState], TCB_LISTEN
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LISTEN
je .destroy_tcb
cmp [eax + SOCKET.TCBState], TCB_SYN_SENT
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_SENT
je .destroy_tcb
 
; Now construct the response, and queue for sending by IP
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .error
 
push eax
 
mov bl, TH_FIN
xor ecx, ecx
xor esi, esi
stdcall build_tcp_Packet, [sockAddr]
call TCP_send_ack
 
mov ebx, [sockAddr]
; increament SND.NXT in socket
lea esi, [ebx + SOCKET.SND_NXT]
call inc_inet_esi
lea esi, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT]
inc_INET esi
 
; Get the socket state
mov eax, [ebx + SOCKET.TCBState]
cmp eax, TCB_SYN_RECEIVED
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED
je .fin_wait_1
cmp eax, TCB_ESTABLISHED
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED
je .fin_wait_1
 
; assume CLOSE WAIT
; Send a fin, then enter last-ack state
mov [ebx + SOCKET.TCBState], TCB_LAST_ACK
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LAST_ACK
jmp .send
 
.fin_wait_1:
; Send a fin, then enter finwait2 state
mov [ebx + SOCKET.TCBState], TCB_FIN_WAIT_1
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_FIN_WAIT_1
 
.send:
mov eax, NET1OUT_QUEUE
mov edx, [IP_LIST]
; mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
 
.not_local:
; Send it.
pop ebx
call queue
jmp .exit
;;;;;
 
 
.destroy_tcb:
 
stdcall net_socket_free, eax
 
end if
 
.exit:
mov dword [esp+32],0
ret
 
735,6 → 635,7
; OUT: -1 on error
;
;-----------------------------------------------
 
align 4
socket_send:
 
749,7 → 650,6
 
jmp s_error
 
;---------
.af_inet4:
DEBUGF 1,"Socket type:%u\n", [eax + SOCKET_head.Type]:4
 
763,7 → 663,6
je .raw
 
jmp s_error
;--------
 
.udp:
 
792,10 → 691,27
 
.tcp:
 
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort],0
jne @f
 
push esi
mov ecx, [eax + SOCKET_head.Type]
call socket_find_port
test bx, bx
pop esi
je s_error
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], bx
 
@@:
 
mov ecx, esi
mov esi, edx
 
call TCP_socket_send
 
mov [esp+32], eax
ret
 
;--------
.raw:
cmp [eax + SOCKET_head.Protocol], IP_PROTO_IP
je .raw_ip
804,11 → 720,12
je .raw_icmp
 
jmp s_error
;--------
 
 
.raw_ip:
 
;;;;;;
 
mov [esp+32], eax
ret