Skip to content

Commit

Permalink
implement getaddrinfo
Browse files Browse the repository at this point in the history
Signed-off-by: Joel Dice <[email protected]>
  • Loading branch information
dicej committed Dec 15, 2023
1 parent bc1b85a commit 2a61396
Showing 1 changed file with 135 additions and 4 deletions.
139 changes: 135 additions & 4 deletions libc-bottom-half/cloudlibc/src/libc/sys/socket/netdb.c
Original file line number Diff line number Diff line change
@@ -1,19 +1,150 @@
#ifdef __wasilibc_use_preview2
#include <netdb.h>
#include <errno.h>
#include <stdlib.h>
#include "__utils.h"

_Thread_local int h_errno = 0;

static int map_error(ip_name_lookup_error_code_t error)
{
switch (error) {
case NETWORK_ERROR_CODE_OUT_OF_MEMORY:
return EAI_MEMORY;
case NETWORK_ERROR_CODE_NAME_UNRESOLVABLE:
return EAI_NONAME;
case NETWORK_ERROR_CODE_TEMPORARY_RESOLVER_FAILURE:
return EAI_AGAIN;
case NETWORK_ERROR_CODE_PERMANENT_RESOLVER_FAILURE:
return EAI_FAIL;

default:
errno = __wasi_sockets_utils__map_error(error);
return EAI_SYSTEM;
}
}

int getaddrinfo(const char* restrict host, const char* restrict serv, const struct addrinfo* restrict hint, struct addrinfo** restrict res)
{
// TODO wasi-sockets
abort();
*res = NULL;
imports_string_t name = { .ptr = (uint8_t*) host, .len = strlen(host) };
ip_name_lookup_own_resolve_address_stream_t stream;
ip_name_lookup_error_code_t error;
if (ip_name_lookup_resolve_addresses(__wasi_sockets_utils__borrow_network(), &name, &stream, &error)) {
ip_name_lookup_borrow_resolve_address_stream_t stream_borrow = ip_name_lookup_borrow_resolve_address_stream(stream);
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 family;
struct sockaddr* addr;
socklen_t addrlen;
switch (address.val.tag) {
case NETWORK_IP_ADDRESS_IPV4: {
network_ipv4_address_t ip = address.val.val.ipv4;

family = PF_INET;
addrlen = sizeof(struct sockaddr_in);
addr = malloc(addrlen);
if (addr == NULL) {
freeaddrinfo(*res);
return EAI_MEMORY;
}

struct sockaddr_in sockaddr = {
.sin_family = AF_INET,
.sin_port = 0,
.sin_addr = { .s_addr = ip.f0 | (ip.f1 << 8) | (ip.f2 << 16) | (ip.f3 << 24) },
};
memcpy(addr, &sockaddr, addrlen);
break;
}
case NETWORK_IP_ADDRESS_IPV6: {
network_ipv6_address_t ip = address.val.val.ipv6;

family = PF_INET6;
addrlen = sizeof(struct sockaddr_in6);
addr = malloc(addrlen);
if (addr == NULL) {
freeaddrinfo(*res);
return EAI_MEMORY;
}

struct sockaddr_in6 sockaddr = {
.sin6_family = AF_INET6,
.sin6_port = 0,
.sin6_addr = {
.s6_addr = {
ip.f0 >> 8,
ip.f0 & 0xFF,
ip.f1 >> 8,
ip.f1 & 0xFF,
ip.f2 >> 8,
ip.f2 & 0xFF,
ip.f3 >> 8,
ip.f3 & 0xFF,
ip.f4 >> 8,
ip.f4 & 0xFF,
ip.f5 >> 8,
ip.f5 & 0xFF,
ip.f6 >> 8,
ip.f6 & 0xFF,
ip.f7 >> 8,
ip.f7 & 0xFF,
} },
.sin6_flowinfo = 0,
.sin6_scope_id = 0,
};
memcpy(addr, &sockaddr, addrlen);
break;
}
default: /* unreachable */
abort();
}

struct addrinfo* result = malloc(sizeof(struct addrinfo));
if (result == NULL) {
freeaddrinfo(*res);
return EAI_MEMORY;
}

*result = (struct addrinfo) {
.ai_family = family,
.ai_flags = 0,
.ai_socktype = SOCK_STREAM,
.ai_protocol = 0,
.ai_addrlen = addrlen,
.ai_addr = addr,
.ai_canonname = NULL,
.ai_next = *res
};
*res = result;
} else {
return 0;
}
} else if (error == NETWORK_ERROR_CODE_WOULD_BLOCK) {
ip_name_lookup_own_pollable_t pollable = ip_name_lookup_method_resolve_address_stream_subscribe(stream_borrow);
poll_borrow_pollable_t pollable_borrow = poll_borrow_pollable(pollable);
poll_method_pollable_block(pollable_borrow);
poll_pollable_drop_own(pollable);
} else {
freeaddrinfo(*res);
return map_error(error);
}
}
} else {
return map_error(error);
}
}

void freeaddrinfo(struct addrinfo* p)
{
// TODO
abort();
while (p) {
struct addrinfo* next = p->ai_next;
free(p->ai_addr);
free(p);
p = next;
}
}

int getnameinfo(const struct sockaddr* restrict sa, socklen_t salen, char* restrict host, socklen_t hostlen, char* restrict serv, socklen_t servlen, int flags)
Expand Down

0 comments on commit 2a61396

Please sign in to comment.