From 52570e69c524b039dc281740a7979106f6b14c63 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Sat, 26 Mar 2022 22:41:32 -0500 Subject: [PATCH] socket address no longer query for information --- core/conv.onyx | 34 ++++++++++------------ core/net/net.onyx | 55 ++++++++++++++++++++++++------------ src/onyx_runtime.c | 70 +++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 114 insertions(+), 45 deletions(-) diff --git a/core/conv.onyx b/core/conv.onyx index f9042243..6b83af10 100644 --- a/core/conv.onyx +++ b/core/conv.onyx @@ -489,29 +489,23 @@ format_any :: (output: ^Format_Output, formatting: ^Format, v: any) { } } - case i16, u16 { - value := *(cast(^i16) v.data); - - ibuf : [128] u8; - istr := i64_to_str(~~value, formatting.base, ~~ibuf, min_length=formatting.minimum_width); - output->write(istr); - } - - case i32, u32 { - value := *(cast(^i32) v.data); + int_case :: macro (T: type_expr) { + case T { + value := *(cast(^T) v.data); - ibuf : [128] u8; - istr := i64_to_str(~~value, formatting.base, ~~ibuf, min_length=formatting.minimum_width); - output->write(istr); + ibuf : [128] u8; + istr := i64_to_str(~~value, formatting.base, ~~ibuf, min_length=formatting.minimum_width); + output->write(istr); + } } - case i64, u64 { - value := *(cast(^i64) v.data); - - ibuf : [128] u8; - istr := i64_to_str(~~value, formatting.base, ~~ibuf); - output->write(istr); - } + int_case(i8); + int_case(i16); + int_case(u16); + int_case(i32); + int_case(u32); + int_case(i64); + int_case(u64); case f32 { value := *(cast(^f32) v.data); diff --git a/core/net/net.onyx b/core/net/net.onyx index 82bf9b04..bec97988 100644 --- a/core/net/net.onyx +++ b/core/net/net.onyx @@ -16,9 +16,11 @@ Socket :: struct { accept :: socket_accept connect :: socket_connect send :: socket_send + sendto :: socket_sendto sendall :: socket_sendall recv :: socket_recv recv_into :: socket_recv_into + recvfrom :: socket_recvfrom } SocketError :: enum { @@ -43,20 +45,21 @@ SocketSetting :: enum { NonBlocking :: 0x01; } -Socket_Address :: struct { - Handle :: #distinct u64 - addr: Handle; +// This structure is twenty bytes in size to accommodate IPV6 addresses. +Socket_Address :: struct #size 20 { + family: u16; + port: u16; + addr: u32; - 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; - } + addr_as_str :: (use this: ^Socket_Address, allocator := context.allocator) -> str { + out: [64] u8; + str_addr := conv.format(out, "{}.{}.{}.{}", + (addr >> 24) & 0xff, + (addr >> 16) & 0xff, + (addr >> 8) & 0xff, + (addr >> 0) & 0xff); - get_port :: (s: ^Socket_Address) -> u32 { - return __net_address_get_port(s.addr); + return string.alloc_copy(str_addr, allocator=allocator); } } @@ -99,7 +102,7 @@ socket_listen :: (s: ^Socket, backlog := 32) { socket_accept :: (s: ^Socket) -> (Socket, Socket_Address) { new_socket: Socket; new_addr: Socket_Address; - new_socket.handle = __net_accept(s.handle, ^new_addr.addr); + new_socket.handle = __net_accept(s.handle, ^new_addr); if new_socket.handle >= 0 { new_socket.vtable = ^__net_socket_vtable; @@ -132,6 +135,12 @@ socket_send :: (s: ^Socket, data: [] u8) -> i32 { return sent; } +socket_sendto :: (s: ^Socket, data: [] u8, addr: ^Socket_Address) -> i32 { + sent := __net_sendto(s.handle, data, addr); + if sent < 0 { s.vtable = null; } + return sent; +} + socket_sendall :: (s: ^Socket, data: [] u8) { to_send := data; @@ -166,6 +175,17 @@ socket_recv_into :: (s: ^Socket, buffer: [] u8) -> i32 { return received; } +socket_recvfrom :: (s: ^Socket, buffer: [] u8) -> (Socket_Address, i32) { + would_block: bool; + sa: Socket_Address; + + received := __net_recvfrom(s.handle, buffer, ^sa, ^would_block); + if received < 0 && !would_block do s.vtable = null; + if would_block do return sa, 0; + + return sa, received; +} + #local __net_socket_vtable := io.Stream_Vtable.{ read = (use s: ^Socket, buffer: [] u8) -> (io.Error, u32) { if handle == 0 do return .BadFile, 0; @@ -199,14 +219,13 @@ 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, out_address: ^Socket_Address.Handle) -> Socket.Handle --- + #package __net_accept :: (handle: Socket.Handle, out_address: ^Socket_Address) -> 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, async_would_block: ^bool) -> i32 --- + #package __net_sendto :: (handle: Socket.Handle, data: [] u8, addr: ^Socket_Address) -> i32 --- + #package __net_recv :: (handle: Socket.Handle, data: [] u8, async_would_block: ^bool) -> i32 --- + #package __net_recvfrom :: (handle: Socket.Handle, data: [] u8, out_recv_addr: ^Socket_Address, async_would_block: ^bool) -> i32 --- #package __net_poll_recv :: (handle: [] Socket.Handle, timeout: i32, out_recv_indicies: ^i32) -> 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; diff --git a/src/onyx_runtime.c b/src/onyx_runtime.c index 41577ee9..d78f8b44 100644 --- a/src/onyx_runtime.c +++ b/src/onyx_runtime.c @@ -797,6 +797,12 @@ ONYX_DEF(__time, (), (WASM_I64)) { // // Networking // +struct onyx_socket_addr { + unsigned short family; + unsigned short port; + unsigned int addr; +}; + ONYX_DEF(__net_create_socket, (WASM_I32, WASM_I32, WASM_I32), (WASM_I32)) { #ifdef _BH_LINUX @@ -895,13 +901,17 @@ ONYX_DEF(__net_listen, (WASM_I32, WASM_I32), ()) { ONYX_DEF(__net_accept, (WASM_I32, WASM_I32), (WASM_I32)) { #ifdef _BH_LINUX - struct sockaddr_in *client_addr = malloc(sizeof(*client_addr)); - int client_len = sizeof(*client_addr); - memset(client_addr, 0, client_len); + struct sockaddr_in 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); + + struct onyx_socket_addr* out_addr = (struct onyx_socket_addr *) ONYX_PTR(params->data[1].of.i32); + out_addr->family = client_addr.sin_family; + out_addr->port = ntohs(client_addr.sin_port); + out_addr->addr = ntohl(client_addr.sin_addr.s_addr); - *(i64 *) ONYX_PTR(params->data[1].of.i32) = (i64) client_addr; results->data[0] = WASM_I32_VAL(client_socket); #endif @@ -950,6 +960,25 @@ ONYX_DEF(__net_send, (WASM_I32, WASM_I32, WASM_I32), (WASM_I32)) { return NULL; } +ONYX_DEF(__net_sendto, (WASM_I32, WASM_I32, WASM_I32, WASM_I32), (WASM_I32)) { + #ifdef _BH_LINUX + struct sockaddr_in dest_addr; + int dest_addr_len = sizeof(dest_addr); + memset(&dest_addr, 0, dest_addr_len); + + struct onyx_socket_addr *o_addr = (struct onyx_socket_addr *) ONYX_PTR(params->data[3].of.i32); + dest_addr.sin_family = AF_INET; // TODO: See other comments related to AF_NET above. + dest_addr.sin_port = htons(o_addr->port); + dest_addr.sin_addr.s_addr = htonl(o_addr->addr); + + // TODO: The flags at the end should be controllable. + int sent = sendto(params->data[0].of.i32, ONYX_PTR(params->data[1].of.i32), params->data[2].of.i32, MSG_NOSIGNAL, &dest_addr, dest_addr_len); + results->data[0] = WASM_I32_VAL(sent); + #endif + + return NULL; +} + ONYX_DEF(__net_recv, (WASM_I32, WASM_I32, WASM_I32, WASM_I32), (WASM_I32)) { *(i32 *) ONYX_PTR(params->data[3].of.i32) = 0; @@ -968,6 +997,33 @@ ONYX_DEF(__net_recv, (WASM_I32, WASM_I32, WASM_I32, WASM_I32), (WASM_I32)) { return NULL; } +ONYX_DEF(__net_recvfrom, (WASM_I32, WASM_I32, WASM_I32, WASM_I32, WASM_I32), (WASM_I32)) { + *(i32 *) ONYX_PTR(params->data[4].of.i32) = 0; + + #ifdef _BH_LINUX + struct onyx_socket_addr *out_addr = (struct onyx_socket_addr *) ONYX_PTR(params->data[3].of.i32); + + struct sockaddr_in client_addr; + int socket_len = sizeof(client_addr); + memset(&client_addr, 0, socket_len); + + int received = recvfrom(params->data[0].of.i32, ONYX_PTR(params->data[1].of.i32), params->data[2].of.i32, 0, &client_addr, &socket_len); + out_addr->family = client_addr.sin_family; + out_addr->port = ntohs(client_addr.sin_port); + out_addr->addr = ntohl(client_addr.sin_addr.s_addr); + + results->data[0] = WASM_I32_VAL(received); + + if (received < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + *(i32 *) ONYX_PTR(params->data[3].of.i32) = 1; + } + } + #endif + + return NULL; +} + ONYX_DEF(__net_poll_recv, (WASM_I32, WASM_I32, WASM_I32, WASM_I32), (WASM_I32)) { #ifdef _BH_LINUX int i, res, cursor; @@ -1106,10 +1162,10 @@ ONYX_LIBRARY { ONYX_FUNC(__net_accept) ONYX_FUNC(__net_connect) ONYX_FUNC(__net_send) + ONYX_FUNC(__net_sendto) ONYX_FUNC(__net_recv) + ONYX_FUNC(__net_recvfrom) ONYX_FUNC(__net_poll_recv) - ONYX_FUNC(__net_address_get_address) - ONYX_FUNC(__net_address_get_port) ONYX_FUNC(__cptr_make) ONYX_FUNC(__cptr_read) -- 2.25.1