Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1155 → Rev 3545

/programs/develop/libraries/network/network.asm
28,8 → 28,8
mov [mem.realloc], ecx
mov [dll.load], edx
mov [DNSrequestID], 1
stdcall edx, @IMPORT
ret 4
xor eax, eax
ret
 
;;===========================================================================;;
;; in_addr_t __stdcall inet_addr(__in const char* hostname); ;;
257,7 → 257,7
ret
 
struct __gai_reqdata
socket dd ?
socketnum dd ?
; external code should not look on rest of this structure,
; it is internal for getaddrinfo_start/process/abort
reqid dw ? ; DNS request ID
279,7 → 279,7
;;---------------------------------------------------------------------------;;
;> first parameter (optional) = host name ;;
;> second parameter (optional) = service name (decimal number for now) ;;
;> third parameter (optional) = hints for socket type ;;
;> third parameter (optional) = hints for socketnum type ;;
;> fourth parameter = pointer to result (head of L1-list) ;;
;;---------------------------------------------------------------------------;;
;< eax = 0 on success / one of EAI_ codes on error ;;
425,14 → 425,14
jecxz @f
cmp [ecx+addrinfo.ai_family], edi
jz @f
cmp [ecx+addrinfo.ai_family], PF_INET
cmp [ecx+addrinfo.ai_family], AF_INET4
jnz .ret
@@:
; 1e. Valid combinations for ai_socktype/ai_protocol: 0/0 for any or
; SOCK_STREAM/IPPROTO_TCP, SOCK_DGRAM/IPPROTO_UDP
; (raw sockets are not yet supported by the kernel)
; (raw socketnums are not yet supported by the kernel)
xor edx, edx ; assume 0=any if no hints
jecxz .socket_type_ok
jecxz .socketnum_type_ok
mov edx, [ecx+addrinfo.ai_socktype]
mov esi, [ecx+addrinfo.ai_protocol]
; 1f. Test for ai_socktype=0 and ai_protocol=0.
439,16 → 439,16
test edx, edx
jnz .check_socktype
test esi, esi
jz .socket_type_ok
jz .socketnum_type_ok
; 1g. ai_socktype=0, ai_protocol is nonzero.
push EAI_SERVICE
pop eax
inc edx ; edx = SOCK_STREAM
cmp esi, IPPROTO_TCP
jz .socket_type_ok
jz .socketnum_type_ok
inc edx ; edx = SOCK_DGRAM
cmp esi, IPPROTO_UDP
jz .socket_type_ok
jz .socketnum_type_ok
.ret:
; Restore saved registers, destroy stack frame and return.
mov esp, ebp
464,16 → 464,16
cmp edx, SOCK_DGRAM
jnz .ret
test esi, esi
jz .socket_type_ok
jz .socketnum_type_ok
cmp esi, IPPROTO_UDP
jz .socket_type_ok
jz .socketnum_type_ok
jmp .ret
.check_tcp:
test esi, esi
jz .socket_type_ok
jz .socketnum_type_ok
cmp esi, IPPROTO_TCP
jnz .ret
.socket_type_ok:
.socketnum_type_ok:
mov [ebx+__gai_reqdata.socktype], dl
; 2. Resolve service.
; 2a. If no name is given, remember value -1.
513,7 → 513,7
; 3. Process host name.
mov esi, [.hostname]
; 3a. If hostname is not given,
; use localhost for active sockets and INADDR_ANY for passive sockets.
; use localhost for active socketnums and INADDR_ANY for passive socketnums.
mov eax, 0x0100007F ; 127.0.0.1 in network byte order
test byte [ebx+__gai_reqdata.flags], AI_PASSIVE
jz @f
675,25 → 675,43
mov eax, 0x01000100
stosd
; 7. Get DNS server address.
mcall 52, 13
xchg esi, eax ; put server address to esi
; 8. Open UDP socket to DNS server, port 53.
mcall 53, 0, 0, 53
mcall 76, API_IPv4 + 4 ; protocol IP=0, device number=0, function=get DNS address
cmp eax, -1
je .ret.dnserr
mov esi, eax ; put server address to esi
; 8. Open UDP socketnum to DNS server, port 53.
; 8a. Create new socketnum.
mcall 75, 0, AF_INET4, SOCK_DGRAM
cmp eax, -1 ; error?
jz .ret.dnserr
xchg ecx, eax ; put socket handle to ecx
mov ecx, eax ; put socketnum handle to ecx
; 8b. Create sockaddr structure on the stack.
push 0
push 0 ; sin_zero
push esi ; sin_addr
push AF_INET4 + (53 shl 24)
; sin_family and sin_port in network byte order
; 8c. Connect.
mcall 75, 4, , esp, sizeof.sockaddr_in
; 8d. Restore the stack, undo 8b.
add esp, esi
; 8e. Check result.
cmp eax, -1
jz .ret.close
; 9. Send DNS request packet.
sub edi, esp ; get packet length
mcall 53, 4, , edi, esp
mov esi, edi
xor edi, edi
mcall 75, 6, , esp
cmp eax, -1
jz .ret.close
mov eax, [.reqdata]
mov [eax+__gai_reqdata.socket], ecx
mov [eax+__gai_reqdata.socketnum], ecx
push -1
pop eax ; return status: more processing required
jmp .ret.dns
.ret.close:
mcall 53, 1
mcall 75, 1
.ret.dnserr:
push EAI_AGAIN
pop eax
741,9 → 759,11
push ebx esi edi
mov edi, [.reqdata]
; 2. Read UDP datagram.
mov ecx, [edi+__gai_reqdata.socket]
mcall 53, 11, , , 512
; 3. Ignore events for other sockets (return if no data read)
mov ecx, [edi+__gai_reqdata.socketnum]
push edi
mcall 75, 7, , , 512, 0
pop edi
; 3. Ignore events for other socketnums (return if no data read)
test eax, eax
jz .ret.more_processing_required
; 4. Sanity check: discard too short packets.
898,11 → 918,11
@@:
pop eax
.ret.close:
; 15. Close socket.
; 15. Close socketnum.
push eax
mov ecx, [.reqdata]
mov ecx, [ecx+__gai_reqdata.socket]
mcall 53, 1
mov ecx, [ecx+__gai_reqdata.socketnum]
mcall 75, 1
pop eax
; 16. Restore used registers, destroy stack frame and return.
.ret:
1150,13 → 1170,12
; 4. Fill struct addrinfo.
mov eax, [ebx+__gai_reqdata.flags]
mov [edi+addrinfo.ai_flags], eax
mov byte [edi+addrinfo.ai_family], PF_INET
mov byte [edi+addrinfo.ai_family], AF_INET4
mov byte [edi+addrinfo.ai_addrlen], sizeof.sockaddr_in
lea ecx, [edi+sizeof.addrinfo]
mov [edi+addrinfo.ai_addr], ecx
; 5. Fill struct sockaddr_in.
mov byte [ecx+sockaddr_in.sin_len], sizeof.sockaddr_in
mov byte [ecx+sockaddr_in.sin_family], PF_INET
mov byte [ecx+sockaddr_in.sin_family], AF_INET4
pop eax
mov [ecx+sockaddr_in.sin_addr], eax
; 6. Append new item to the list.
1170,7 → 1189,7
ret
 
.set_socktype:
; Set ai_socktype and ai_protocol fields by given socket type.
; Set ai_socktype and ai_protocol fields by given socketnum type.
mov byte [edi+addrinfo.ai_socktype], cl
dec cl
jnz .set_udp
1185,7 → 1204,7
; Just copy port from input __gai_reqdata to output addrinfo.
push edx
mov edx, [ebx+__gai_reqdata.service]
xchg dl, dh ; convert to network byte order
xchg dl, dh ; convert to network byte order ;;;;; CHECKME
mov [edi+sizeof.addrinfo+sockaddr_in.sin_port], dx
pop edx
ret
1200,10 → 1219,10
;;===========================================================================;;
; 0. Save used registers for __stdcall.
push ebx
; 1. Allocated resources: only socket, so close it and return.
; 1. Allocated resources: only socketnum, so close it and return.
mov eax, [esp+8]
mov ecx, [eax+__gai_reqdata.socket]
mcall 53, 1
mov ecx, [eax+__gai_reqdata.socketnum]
mcall 75, 1
; 2. Restore used registers and return.
pop ebx
ret 4
1264,16 → 1283,6
getaddrinfo_abort , 'getaddrinfo_abort' , \
freeaddrinfo , 'freeaddrinfo'
 
; import from libini
align 4
@IMPORT:
 
library libini, 'libini.obj'
import libini, \
ini.get_str, 'ini_get_str', \
ini.get_int, 'ini_get_int'
 
 
section '.data' data readable writable align 16
; uninitialized data
mem.alloc dd ?