mirror of
https://git.proxmox.com/git/wasi-libc
synced 2025-06-05 01:45:38 +00:00
![]() Hello, While experimenting with the `wasm32-wasip2` target and CPython, I discovered an issue with the `getaddrinfo()` implementation: it fails to resolve the provided service into a port number, causing `sin_port` to always be set to 0. This issue leads to failures in network-related functions that rely on `getaddrinfo()`, such as Python's `urllib3` library, which passes the result directly to `connect()`. This results in connection attempts using a port value of 0, which naturally fails. ### Minimal example to reproduce the problem ```c #include <arpa/inet.h> #include <netdb.h> #include <stdio.h> int main(void) { struct addrinfo *res = NULL; getaddrinfo("google.com", "443", NULL, &res); for (struct addrinfo *i = res; i != NULL; i = i->ai_next) { char str[INET6_ADDRSTRLEN]; if (i->ai_addr->sa_family == AF_INET) { struct sockaddr_in *p = (struct sockaddr_in *)i->ai_addr; int port = ntohs(p->sin_port); printf("%s: %i\n", inet_ntop(AF_INET, &p->sin_addr, str, sizeof(str)), port); } else if (i->ai_addr->sa_family == AF_INET6) { struct sockaddr_in6 *p = (struct sockaddr_in6 *)i->ai_addr; int port = ntohs(p->sin6_port); printf("%s: %i\n", inet_ntop(AF_INET6, &p->sin6_addr, str, sizeof(str)), port); } } return 0; } ``` ``` $ /opt/wasi-sdk/bin/clang -target wasm32-wasip2 -o foo foo.c $ wasmtime run -S allow-ip-name-lookup=y foo 216.58.211.238: 0 2a00:1450:4026:808::200e: 0 ``` Expected output: ``` 216.58.211.238: 443 2a00:1450:4026:808::200e: 443 ``` ### Root Cause The root cause is that `getaddrinfo()` does not correctly translate the provided service into a port number. As described in the `getaddrinfo()` man [page](https://man7.org/linux/man-pages/man3/getaddrinfo.3.html), the function should: > service sets the port in each returned address structure. If this argument is a service name (see [services(5)](https://man7.org/linux/man-pages/man5/services.5.html)), it is translated to the corresponding port number. This argument can also be specified as a decimal number, which is simply converted to binary. If service is NULL, then the port number of the returned socket addresses will be left uninitialized. ### Proposed Fix This pull request addresses the issue by implementing the following behavior for `getaddrinfo()`: * If the service is `NULL`, the port number in the returned socket addresses remains uninitialized. * The value is converted to an integer and validated if the service is numeric. The PR does not currently add support for translating named services into port numbers because `getservbyname()` has not been implemented. In cases where a named service is provided, the `EAI_NONAME` error code is returned. |
||
---|---|---|
.. | ||
clocks | ||
cloudlibc | ||
crt | ||
getpid | ||
headers | ||
mman | ||
signal | ||
sources | ||
README.md |
WASI libc "bottom half".
The WASI libc "bottom half" is conceptually the lower half of a traditional libc implementation, consisting of C interfaces to the low-level WASI syscalls.
This implementation is partially derived from the "bottom half" of cloudlibc, revision 8835639f27fc42d32096d59d294a0bbb857dc368.
This implementation includes preopen functionality, which emulates POSIX APIs
accepting absolute paths by translating them into pre-opened directory handles
and relative paths that can be opened with openat
. This technique is inspired
by libpreopen, however the implementation here is designed to be built into
libc rather than to be a layer on top of libc.
The WASI libc lower half currently depends on the dlmalloc component.