aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/bun-usockets/src/bsd.c107
1 files changed, 65 insertions, 42 deletions
diff --git a/packages/bun-usockets/src/bsd.c b/packages/bun-usockets/src/bsd.c
index fc501e4d9..4d7049717 100644
--- a/packages/bun-usockets/src/bsd.c
+++ b/packages/bun-usockets/src/bsd.c
@@ -427,43 +427,12 @@ int bsd_would_block() {
#endif
}
-// return LIBUS_SOCKET_ERROR or the fd that represents listen socket
-// listen both on ipv6 and ipv4
-LIBUS_SOCKET_DESCRIPTOR bsd_create_listen_socket(const char *host, int port, int options) {
- struct addrinfo hints, *result;
- memset(&hints, 0, sizeof(struct addrinfo));
-
- hints.ai_flags = AI_PASSIVE;
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
-
- char port_string[16];
- snprintf(port_string, 16, "%d", port);
-
- if (getaddrinfo(host, port_string, &hints, &result)) {
- return LIBUS_SOCKET_ERROR;
- }
-
- LIBUS_SOCKET_DESCRIPTOR listenFd = LIBUS_SOCKET_ERROR;
- struct addrinfo *listenAddr;
- for (struct addrinfo *a = result; a && listenFd == LIBUS_SOCKET_ERROR; a = a->ai_next) {
- if (a->ai_family == AF_INET6) {
- listenFd = bsd_create_socket(a->ai_family, a->ai_socktype, a->ai_protocol);
- listenAddr = a;
- }
- }
-
- for (struct addrinfo *a = result; a && listenFd == LIBUS_SOCKET_ERROR; a = a->ai_next) {
- if (a->ai_family == AF_INET) {
- listenFd = bsd_create_socket(a->ai_family, a->ai_socktype, a->ai_protocol);
- listenAddr = a;
- }
- }
-
- if (listenFd == LIBUS_SOCKET_ERROR) {
- freeaddrinfo(result);
- return LIBUS_SOCKET_ERROR;
- }
+inline LIBUS_SOCKET_DESCRIPTOR bsd_bind_listen_fd(
+ LIBUS_SOCKET_DESCRIPTOR listenFd,
+ struct addrinfo *listenAddr,
+ int port,
+ int options
+) {
if (port != 0) {
/* Otherwise, always enable SO_REUSEPORT and SO_REUSEADDR _unless_ options specify otherwise */
@@ -487,22 +456,76 @@ LIBUS_SOCKET_DESCRIPTOR bsd_create_listen_socket(const char *host, int port, int
#endif
}
-
+
#ifdef IPV6_V6ONLY
int disabled = 0;
setsockopt(listenFd, IPPROTO_IPV6, IPV6_V6ONLY, (void *) &disabled, sizeof(disabled));
#endif
if (bind(listenFd, listenAddr->ai_addr, (socklen_t) listenAddr->ai_addrlen) || listen(listenFd, 512)) {
- bsd_close_socket(listenFd);
- freeaddrinfo(result);
return LIBUS_SOCKET_ERROR;
}
- freeaddrinfo(result);
return listenFd;
}
+// return LIBUS_SOCKET_ERROR or the fd that represents listen socket
+// listen both on ipv6 and ipv4
+LIBUS_SOCKET_DESCRIPTOR bsd_create_listen_socket(const char *host, int port, int options) {
+ struct addrinfo hints, *result;
+ memset(&hints, 0, sizeof(struct addrinfo));
+
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+
+ char port_string[16];
+ snprintf(port_string, 16, "%d", port);
+
+ if (getaddrinfo(host, port_string, &hints, &result)) {
+ return LIBUS_SOCKET_ERROR;
+ }
+
+ LIBUS_SOCKET_DESCRIPTOR listenFd = LIBUS_SOCKET_ERROR;
+ struct addrinfo *listenAddr;
+ for (struct addrinfo *a = result; a != NULL; a = a->ai_next) {
+ if (a->ai_family == AF_INET6) {
+ listenFd = bsd_create_socket(a->ai_family, a->ai_socktype, a->ai_protocol);
+ if (listenFd == LIBUS_SOCKET_ERROR) {
+ continue;
+ }
+
+ listenAddr = a;
+ if (bsd_bind_listen_fd(listenFd, listenAddr, port, options) != LIBUS_SOCKET_ERROR) {
+ freeaddrinfo(result);
+ return listenFd;
+ }
+
+ bsd_close_socket(listenFd);
+ }
+ }
+
+ for (struct addrinfo *a = result; a != NULL; a = a->ai_next) {
+ if (a->ai_family == AF_INET) {
+ listenFd = bsd_create_socket(a->ai_family, a->ai_socktype, a->ai_protocol);
+ if (listenFd == LIBUS_SOCKET_ERROR) {
+ continue;
+ }
+
+ listenAddr = a;
+ if (bsd_bind_listen_fd(listenFd, listenAddr, port, options) != LIBUS_SOCKET_ERROR) {
+ freeaddrinfo(result);
+ return listenFd;
+ }
+
+ bsd_close_socket(listenFd);
+ }
+ }
+
+ freeaddrinfo(result);
+ return LIBUS_SOCKET_ERROR;
+}
+
#ifndef _WIN32
#include <sys/un.h>
#else
@@ -768,4 +791,4 @@ LIBUS_SOCKET_DESCRIPTOR bsd_create_connect_socket_unix(const char *server_path,
}
return fd;
-} \ No newline at end of file
+}