added ability to get the connected address and port
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 18 Jan 2022 22:11:34 +0000 (16:11 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 18 Jan 2022 22:11:34 +0000 (16:11 -0600)
core/net/net.onyx
modules/onyx_runtime/onyx_runtime.c

index f39bee3e1da2f14d3fed2b4ea990c127800c8d67..c46740f93a96e911ce34d5ee61cc369fbdac7299 100644 (file)
@@ -43,6 +43,23 @@ SocketSetting :: enum {
     NonBlocking :: 0x01;
 }
 
+Socket_Address :: struct {
+    Handle :: #distinct u64
+    addr: Handle;
+
+    get_address :: (s: ^Socket_Address, allocator := context.allocator) -> [] u8 {
+        buf: [256] u8;
+        addr_len := __net_address_get_address(s.addr, buf);
+        
+        ret := memory.copy_slice(buf[0 .. addr_len], allocator=allocator);
+        return ret;
+    }
+
+    get_port :: (s: ^Socket_Address) -> u32 {
+        return __net_address_get_port(s.addr);
+    }
+}
+
 socket_create :: (domain: SocketDomain, type: SocketType) -> (Socket, SocketError) {
     s: Socket;
 
@@ -79,14 +96,16 @@ socket_listen :: (s: ^Socket, backlog := 32) {
     __net_listen(s.handle, backlog);
 }
 
-socket_accept :: (s: ^Socket) -> Socket {
+socket_accept :: (s: ^Socket) -> (Socket, Socket_Address) {
     new_socket: Socket;
-    new_socket.handle = __net_accept(s.handle);
+    new_addr: Socket_Address;
+    new_socket.handle = __net_accept(s.handle, ^new_addr.addr);
+
     if new_socket.handle >= 0 {
         new_socket.vtable = ^__net_socket_vtable;
     }
 
-    return new_socket;
+    return new_socket, new_addr;
 }
 
 socket_poll_all :: (changed: ^[] ^Socket, timeout: i32, sockets: [] ^Socket) {
@@ -174,11 +193,14 @@ socket_recv_into :: (s: ^Socket, buffer: [] u8) -> i32 {
     #package __net_setting       :: (handle: Socket.Handle, setting: SocketSetting, value: i32) -> void ---
     #package __net_bind          :: (handle: Socket.Handle, port: u16)    -> bool ---
     #package __net_listen        :: (handle: Socket.Handle, backlog: i32) -> void ---
-    #package __net_accept        :: (handle: Socket.Handle)               -> Socket.Handle ---  // This should also return the address, but in what format?
+    #package __net_accept        :: (handle: Socket.Handle, out_address: ^Socket_Address.Handle) -> Socket.Handle ---
     #package __net_connect       :: (handle: Socket.Handle, host: str, port: u16) -> SocketError ---
     #package __net_send          :: (handle: Socket.Handle, data: [] u8)  -> i32 ---
     #package __net_recv          :: (handle: Socket.Handle, data: [] u8)  -> i32 ---
     #package __net_poll_recv     :: (handle: [] Socket.Handle, timeout: i32, out_recv: ^Socket.Handle) -> i32 ---
+
+    #package __net_address_get_address :: (address: Socket_Address.Handle, out_buffer: [] u8) -> i32 ---
+    #package __net_address_get_port    :: (address: Socket_Address.Handle) -> i32 ---
 }
 
 #operator >= macro (a, b: Socket.Handle) => cast(u32) a >= cast(u32) b;
index 9034873523f6f166d4725980f253d017ae08fc1b..91c570635c741ee6980d6565b1dad7ad7a6cf683 100644 (file)
     #include <sys/types.h>
     #include <dlfcn.h>
     #include <dirent.h>
+    #include <arpa/inet.h>
     #include <netdb.h>
     #include <netinet/in.h>
+    #include <sys/socket.h>
     #include <poll.h>
 #endif
 
@@ -892,13 +894,15 @@ ONYX_DEF(__net_listen, (WASM_I32, WASM_I32), ()) {
     return NULL;
 }
 
-ONYX_DEF(__net_accept, (WASM_I32), (WASM_I32)) {
+ONYX_DEF(__net_accept, (WASM_I32, WASM_I32), (WASM_I32)) {
     #ifdef _BH_LINUX
-    struct sockaddr_in client_addr;
-    int client_len = sizeof(client_addr);
+    struct sockaddr_in *client_addr = malloc(sizeof(*client_addr));
+    int client_len = sizeof(*client_addr);
+    memset(client_addr, 0, client_len);
 
-    int client_socket = accept(params->data[0].of.i32, &client_addr, &client_len);
+    int client_socket = accept(params->data[0].of.i32, client_addr, &client_len);
 
+    *(i64 *) ONYX_PTR(params->data[1].of.i32) = (i64) client_addr;
     results->data[0] = WASM_I32_VAL(client_socket);
     #endif
 
@@ -986,6 +990,30 @@ ONYX_DEF(__net_poll_recv, (WASM_I32, WASM_I32, WASM_I32, WASM_I32), (WASM_I32))
     return NULL;
 }
 
+ONYX_DEF(__net_address_get_address, (WASM_I64, WASM_I32, WASM_I32), (WASM_I32)) {
+    int maximum_length = params->data[2].of.i32;
+    int address_len = 0;
+
+    struct sockaddr_in *addr = (struct sockaddr_in *) params->data[0].of.i64;
+    if (addr == NULL) goto done;
+
+    char *address = inet_ntoa(addr->sin_addr);
+    if (address) address_len = strnlen(address, maximum_length);
+
+    memcpy(ONYX_PTR(params->data[1].of.i32), address, address_len);
+
+done:
+    results->data[0] = WASM_I32_VAL(address_len);
+    return NULL;
+}
+
+ONYX_DEF(__net_address_get_port, (WASM_I64), (WASM_I32)) {
+    struct sockaddr_in *addr = (struct sockaddr_in *) params->data[0].of.i64;
+    if (addr == NULL) results->data[0] = WASM_I32_VAL(-1);
+    else              results->data[0] = WASM_I32_VAL(addr->sin_port);
+    return NULL;
+}
+
 
 ONYX_LIBRARY {
     ONYX_FUNC(__file_open_impl)
@@ -1029,6 +1057,8 @@ ONYX_LIBRARY {
     ONYX_FUNC(__net_send)
     ONYX_FUNC(__net_recv)
     ONYX_FUNC(__net_poll_recv)
+    ONYX_FUNC(__net_address_get_address)
+    ONYX_FUNC(__net_address_get_port)
 
     NULL
 };