diff --git a/expected/wasm32-wasip2/defined-symbols.txt b/expected/wasm32-wasip2/defined-symbols.txt index 2c3ba420..8960ca0d 100644 --- a/expected/wasm32-wasip2/defined-symbols.txt +++ b/expected/wasm32-wasip2/defined-symbols.txt @@ -309,6 +309,7 @@ __wasi_sockets_utils__map_error __wasi_sockets_utils__output_addr_validate __wasi_sockets_utils__output_addr_write __wasi_sockets_utils__parse_address +__wasi_sockets_utils__parse_port __wasi_sockets_utils__posix_family __wasi_sockets_utils__stream __wasi_sockets_utils__tcp_bind diff --git a/libc-bottom-half/headers/private/wasi/sockets_utils.h b/libc-bottom-half/headers/private/wasi/sockets_utils.h index 93cf1f45..396c6301 100644 --- a/libc-bottom-half/headers/private/wasi/sockets_utils.h +++ b/libc-bottom-half/headers/private/wasi/sockets_utils.h @@ -49,5 +49,6 @@ bool __wasi_sockets_utils__stream(udp_socket_t *socket, udp_socket_streams_t *result, network_error_code_t *error); void __wasi_sockets_utils__drop_streams(udp_socket_streams_t streams); +int __wasi_sockets_utils__parse_port(const char *port); #endif diff --git a/libc-bottom-half/sources/netdb.c b/libc-bottom-half/sources/netdb.c index c30a3967..f6b1718b 100644 --- a/libc-bottom-half/sources/netdb.c +++ b/libc-bottom-half/sources/netdb.c @@ -1,6 +1,7 @@ #include #include #include +#include #include @@ -25,6 +26,7 @@ static int map_error(ip_name_lookup_error_code_t error) } static int add_addr(ip_name_lookup_option_ip_address_t address, + in_port_t port, const struct addrinfo *restrict hint, struct addrinfo **restrict current, struct addrinfo **restrict res) @@ -51,7 +53,7 @@ static int add_addr(ip_name_lookup_option_ip_address_t address, struct sockaddr_in sockaddr = { .sin_family = AF_INET, - .sin_port = 0, + .sin_port = port, .sin_addr = { .s_addr = ip.f0 | (ip.f1 << 8) | (ip.f2 << 16) | (ip.f3 << 24) }, }; @@ -76,7 +78,7 @@ static int add_addr(ip_name_lookup_option_ip_address_t address, struct sockaddr_in6 sockaddr = { .sin6_family = AF_INET6, - .sin6_port = 0, + .sin6_port = port, .sin6_addr = { .s6_addr = { ip.f0 >> 8, @@ -152,12 +154,25 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, &error)) { ip_name_lookup_borrow_resolve_address_stream_t stream_borrow = ip_name_lookup_borrow_resolve_address_stream(stream); + // The 'serv' parameter can be either a port number or a service name. + // + // TODO wasi-sockets: If the conversion of 'serv' to a valid port + // number fails, use getservbyname() to resolve the service name to + // its corresponding port number. This can be done after the + // getservbyname function is implemented.) + int port = 0; + if (serv != NULL) { + port = __wasi_sockets_utils__parse_port(serv); + if (port < 0) { + return EAI_NONAME; + } + } while (true) { ip_name_lookup_option_ip_address_t address; if (ip_name_lookup_method_resolve_address_stream_resolve_next_address( stream_borrow, &address, &error)) { if (address.is_some) { - int error = add_addr(address, hint, + int error = add_addr(address, htons(port), hint, ¤t, res); if (error) { return error; diff --git a/libc-bottom-half/sources/sockets_utils.c b/libc-bottom-half/sources/sockets_utils.c index 4f5658a5..d98fd02a 100644 --- a/libc-bottom-half/sources/sockets_utils.c +++ b/libc-bottom-half/sources/sockets_utils.c @@ -1,4 +1,6 @@ #include +#include +#include #include @@ -460,3 +462,23 @@ bool __wasi_sockets_utils__stream( return true; } + +int __wasi_sockets_utils__parse_port(const char *restrict port_str) +{ + char *end = NULL; + errno = 0; + long port = strtol(port_str, &end, 10); + + // Check for various possible errors: + // - the input is not a valid number + // - the entire input string is not consumed + // - the number is not within the valid port range + // - the input does not start with a digit (strtol allows leading + // whitespace and optional sign) + if (errno != 0 || end == NULL || *end != '\0' || port < 0 + || port > 65535 || !isdigit(*port_str)) { + return -1; + } + + return (int)port; +}