Skip to content

Commit 306b9b8

Browse files
Add support for ephemeral ports (#136)
1 parent 461d02e commit 306b9b8

4 files changed

Lines changed: 46 additions & 14 deletions

File tree

src/bsd.c

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Authored by Alex Hultman, 2018-2019.
2+
* Authored by Alex Hultman, 2018-2021.
33
* Intellectual property of third-party.
44
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -107,15 +107,27 @@ void internal_finalize_bsd_addr(struct bsd_addr_t *addr) {
107107
if (addr->mem.ss_family == AF_INET6) {
108108
addr->ip = (char *) &((struct sockaddr_in6 *) addr)->sin6_addr;
109109
addr->ip_length = sizeof(struct in6_addr);
110+
addr->port = ntohs(((struct sockaddr_in6 *) addr)->sin6_port);
110111
} else if (addr->mem.ss_family == AF_INET) {
111112
addr->ip = (char *) &((struct sockaddr_in *) addr)->sin_addr;
112113
addr->ip_length = sizeof(struct in_addr);
114+
addr->port = ntohs(((struct sockaddr_in *) addr)->sin_port);
113115
} else {
114116
addr->ip_length = 0;
117+
addr->port = -1;
115118
}
116119
}
117120

118-
int bsd_socket_addr(LIBUS_SOCKET_DESCRIPTOR fd, struct bsd_addr_t *addr) {
121+
int bsd_local_addr(LIBUS_SOCKET_DESCRIPTOR fd, struct bsd_addr_t *addr) {
122+
addr->len = sizeof(addr->mem);
123+
if (getsockname(fd, (struct sockaddr *) &addr->mem, &addr->len)) {
124+
return -1;
125+
}
126+
internal_finalize_bsd_addr(addr);
127+
return 0;
128+
}
129+
130+
int bsd_remote_addr(LIBUS_SOCKET_DESCRIPTOR fd, struct bsd_addr_t *addr) {
119131
addr->len = sizeof(addr->mem);
120132
if (getpeername(fd, (struct sockaddr *) &addr->mem, &addr->len)) {
121133
return -1;
@@ -132,6 +144,10 @@ int bsd_addr_get_ip_length(struct bsd_addr_t *addr) {
132144
return addr->ip_length;
133145
}
134146

147+
int bsd_addr_get_port(struct bsd_addr_t *addr) {
148+
return addr->port;
149+
}
150+
135151
// called by dispatch_ready_poll
136152
LIBUS_SOCKET_DESCRIPTOR bsd_accept_socket(LIBUS_SOCKET_DESCRIPTOR fd, struct bsd_addr_t *addr) {
137153
LIBUS_SOCKET_DESCRIPTOR accepted_fd;
@@ -228,17 +244,18 @@ LIBUS_SOCKET_DESCRIPTOR bsd_create_listen_socket(const char *host, int port, int
228244
return LIBUS_SOCKET_ERROR;
229245
}
230246

231-
/* Always enable SO_REUSEPORT and SO_REUSEADDR _unless_ options specify otherwise */
247+
if (port != 0) {
248+
/* Otherwise, always enable SO_REUSEPORT and SO_REUSEADDR _unless_ options specify otherwise */
232249
#if /*defined(__linux) &&*/ defined(SO_REUSEPORT)
233-
if (!(options & LIBUS_LISTEN_EXCLUSIVE_PORT)) {
234-
int optval = 1;
235-
setsockopt(listenFd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
236-
}
250+
if (!(options & LIBUS_LISTEN_EXCLUSIVE_PORT)) {
251+
int optval = 1;
252+
setsockopt(listenFd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
253+
}
237254
#endif
238-
239-
int enabled = 1;
240-
setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR, (SETSOCKOPT_PTR_TYPE) &enabled, sizeof(enabled));
241-
255+
int enabled = 1;
256+
setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR, (SETSOCKOPT_PTR_TYPE) &enabled, sizeof(enabled));
257+
}
258+
242259
#ifdef IPV6_V6ONLY
243260
int disabled = 0;
244261
setsockopt(listenFd, IPPROTO_IPV6, IPV6_V6ONLY, (SETSOCKOPT_PTR_TYPE) &disabled, sizeof(disabled));

src/internal/networking/bsd.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct bsd_addr_t {
4545
socklen_t len;
4646
char *ip;
4747
int ip_length;
48+
int port;
4849
};
4950

5051
LIBUS_SOCKET_DESCRIPTOR apple_no_sigpipe(LIBUS_SOCKET_DESCRIPTOR fd);
@@ -59,12 +60,14 @@ void bsd_shutdown_socket_read(LIBUS_SOCKET_DESCRIPTOR fd);
5960

6061
void internal_finalize_bsd_addr(struct bsd_addr_t *addr);
6162

62-
int bsd_socket_addr(LIBUS_SOCKET_DESCRIPTOR fd, struct bsd_addr_t *addr);
63+
int bsd_local_addr(LIBUS_SOCKET_DESCRIPTOR fd, struct bsd_addr_t *addr);
64+
int bsd_remote_addr(LIBUS_SOCKET_DESCRIPTOR fd, struct bsd_addr_t *addr);
6365

6466
char *bsd_addr_get_ip(struct bsd_addr_t *addr);
65-
6667
int bsd_addr_get_ip_length(struct bsd_addr_t *addr);
6768

69+
int bsd_addr_get_port(struct bsd_addr_t *addr);
70+
6871
// called by dispatch_ready_poll
6972
LIBUS_SOCKET_DESCRIPTOR bsd_accept_socket(LIBUS_SOCKET_DESCRIPTOR fd, struct bsd_addr_t *addr);
7073

src/libusockets.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,9 @@ WIN32_EXPORT int us_socket_is_closed(int ssl, struct us_socket_t *s);
251251
/* Immediately closes the socket */
252252
WIN32_EXPORT struct us_socket_t *us_socket_close(int ssl, struct us_socket_t *s, int code, void *reason);
253253

254+
/* Returns local port or -1 on failure. */
255+
WIN32_EXPORT int us_socket_local_port(int ssl, struct us_socket_t *s);
256+
254257
/* Copy remote (IP) address of socket, or fail with zero length. */
255258
WIN32_EXPORT void us_socket_remote_address(int ssl, struct us_socket_t *s, char *buf, int *length);
256259

src/socket.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,23 @@
2222

2323
/* Shared with SSL */
2424

25+
int us_socket_local_port(int ssl, struct us_socket_t *s) {
26+
struct bsd_addr_t addr;
27+
if (bsd_local_addr(us_poll_fd(&s->p), &addr)) {
28+
return -1;
29+
} else {
30+
return bsd_addr_get_port(&addr);
31+
}
32+
}
33+
2534
void us_socket_shutdown_read(int ssl, struct us_socket_t *s) {
2635
/* This syscall is idempotent so no extra check is needed */
2736
bsd_shutdown_socket_read(us_poll_fd((struct us_poll_t *) s));
2837
}
2938

3039
void us_socket_remote_address(int ssl, struct us_socket_t *s, char *buf, int *length) {
3140
struct bsd_addr_t addr;
32-
if (bsd_socket_addr(us_poll_fd(&s->p), &addr) || *length < bsd_addr_get_ip_length(&addr)) {
41+
if (bsd_remote_addr(us_poll_fd(&s->p), &addr) || *length < bsd_addr_get_ip_length(&addr)) {
3342
*length = 0;
3443
} else {
3544
*length = bsd_addr_get_ip_length(&addr);

0 commit comments

Comments
 (0)