mirror of
https://github.com/cesanta/mongoose.git
synced 2025-08-06 13:37:34 +08:00
Fix #1314 - expose local port for listeners
This commit is contained in:
parent
89757388c7
commit
497b8027f5
@ -383,7 +383,7 @@ with some housekeeping information.
|
|||||||
struct mg_connection {
|
struct mg_connection {
|
||||||
struct mg_connection *next; // Linkage in struct mg_mgr :: connections
|
struct mg_connection *next; // Linkage in struct mg_mgr :: connections
|
||||||
struct mg_mgr *mgr; // Our container
|
struct mg_mgr *mgr; // Our container
|
||||||
struct mg_addr peer; // Remote peer address
|
struct mg_addr peer; // Remote address. For listeners, local address
|
||||||
void *fd; // Connected socket, or LWIP data
|
void *fd; // Connected socket, or LWIP data
|
||||||
unsigned long id; // Auto-incrementing unique connection ID
|
unsigned long id; // Auto-incrementing unique connection ID
|
||||||
struct mg_iobuf recv; // Incoming data
|
struct mg_iobuf recv; // Incoming data
|
||||||
|
28
mongoose.c
28
mongoose.c
@ -2736,22 +2736,20 @@ static void mg_set_non_blocking_mode(SOCKET fd) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SOCKET mg_open_listener(const char *url) {
|
SOCKET mg_open_listener(const char *url, struct mg_addr *addr) {
|
||||||
struct mg_addr addr;
|
|
||||||
SOCKET fd = INVALID_SOCKET;
|
SOCKET fd = INVALID_SOCKET;
|
||||||
|
memset(addr, 0, sizeof(*addr));
|
||||||
memset(&addr, 0, sizeof(addr));
|
addr->port = mg_htons(mg_url_port(url));
|
||||||
addr.port = mg_htons(mg_url_port(url));
|
if (!mg_aton(mg_url_host(url), addr)) {
|
||||||
if (!mg_aton(mg_url_host(url), &addr)) {
|
|
||||||
LOG(LL_ERROR, ("invalid listening URL: %s", url));
|
LOG(LL_ERROR, ("invalid listening URL: %s", url));
|
||||||
} else {
|
} else {
|
||||||
union usa usa = tousa(&addr);
|
union usa usa = tousa(addr);
|
||||||
int on = 1, af = AF_INET;
|
int on = 1, af = AF_INET;
|
||||||
int type = strncmp(url, "udp:", 4) == 0 ? SOCK_DGRAM : SOCK_STREAM;
|
int type = strncmp(url, "udp:", 4) == 0 ? SOCK_DGRAM : SOCK_STREAM;
|
||||||
int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
|
int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
|
||||||
socklen_t slen = sizeof(usa.sin);
|
socklen_t slen = sizeof(usa.sin);
|
||||||
#if MG_ENABLE_IPV6
|
#if MG_ENABLE_IPV6
|
||||||
if (addr.is_ip6) af = AF_INET6, slen = sizeof(usa.sin6);
|
if (addr->is_ip6) af = AF_INET6, slen = sizeof(usa.sin6);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((fd = socket(af, type, proto)) != INVALID_SOCKET &&
|
if ((fd = socket(af, type, proto)) != INVALID_SOCKET &&
|
||||||
@ -2775,6 +2773,13 @@ SOCKET mg_open_listener(const char *url) {
|
|||||||
bind(fd, &usa.sa, slen) == 0 &&
|
bind(fd, &usa.sa, slen) == 0 &&
|
||||||
// NOTE(lsm): FreeRTOS uses backlog value as a connection limit
|
// NOTE(lsm): FreeRTOS uses backlog value as a connection limit
|
||||||
(type == SOCK_DGRAM || listen(fd, 128) == 0)) {
|
(type == SOCK_DGRAM || listen(fd, 128) == 0)) {
|
||||||
|
// In case port was set to 0, get the real port number
|
||||||
|
if (getsockname(fd, &usa.sa, &slen) == 0) {
|
||||||
|
addr->port = usa.sin.sin_port;
|
||||||
|
#if MG_ENABLE_IPV6
|
||||||
|
if (addr->is_ip6) addr->port = usa.sin6.sin6_port;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
mg_set_non_blocking_mode(fd);
|
mg_set_non_blocking_mode(fd);
|
||||||
} else if (fd != INVALID_SOCKET) {
|
} else if (fd != INVALID_SOCKET) {
|
||||||
closesocket(fd);
|
closesocket(fd);
|
||||||
@ -3064,19 +3069,22 @@ struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url,
|
|||||||
mg_event_handler_t fn, void *fn_data) {
|
mg_event_handler_t fn, void *fn_data) {
|
||||||
struct mg_connection *c = NULL;
|
struct mg_connection *c = NULL;
|
||||||
bool is_udp = strncmp(url, "udp:", 4) == 0;
|
bool is_udp = strncmp(url, "udp:", 4) == 0;
|
||||||
SOCKET fd = mg_open_listener(url);
|
struct mg_addr addr;
|
||||||
|
SOCKET fd = mg_open_listener(url, &addr);
|
||||||
if (fd == INVALID_SOCKET) {
|
if (fd == INVALID_SOCKET) {
|
||||||
} else if ((c = alloc_conn(mgr, 0, fd)) == NULL) {
|
} else if ((c = alloc_conn(mgr, 0, fd)) == NULL) {
|
||||||
LOG(LL_ERROR, ("OOM %s", url));
|
LOG(LL_ERROR, ("OOM %s", url));
|
||||||
closesocket(fd);
|
closesocket(fd);
|
||||||
} else {
|
} else {
|
||||||
|
memcpy(&c->peer, &addr, sizeof(struct mg_addr));
|
||||||
c->fd = sock2ptr(fd);
|
c->fd = sock2ptr(fd);
|
||||||
c->is_listening = 1;
|
c->is_listening = 1;
|
||||||
c->is_udp = is_udp;
|
c->is_udp = is_udp;
|
||||||
LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
|
LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
|
||||||
c->fn = fn;
|
c->fn = fn;
|
||||||
c->fn_data = fn_data;
|
c->fn_data = fn_data;
|
||||||
LOG(LL_INFO, ("%lu accepting on %s", c->id, url));
|
LOG(LL_INFO,
|
||||||
|
("%lu accepting on %s (port %u)", c->id, url, mg_ntohs(c->peer.port)));
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
@ -714,7 +714,7 @@ struct mg_mgr {
|
|||||||
struct mg_connection {
|
struct mg_connection {
|
||||||
struct mg_connection *next; // Linkage in struct mg_mgr :: connections
|
struct mg_connection *next; // Linkage in struct mg_mgr :: connections
|
||||||
struct mg_mgr *mgr; // Our container
|
struct mg_mgr *mgr; // Our container
|
||||||
struct mg_addr peer; // Remote peer address
|
struct mg_addr peer; // Remote address. For listeners, local address
|
||||||
void *fd; // Connected socket, or LWIP data
|
void *fd; // Connected socket, or LWIP data
|
||||||
unsigned long id; // Auto-incrementing unique connection ID
|
unsigned long id; // Auto-incrementing unique connection ID
|
||||||
struct mg_iobuf recv; // Incoming data
|
struct mg_iobuf recv; // Incoming data
|
||||||
|
@ -32,7 +32,7 @@ struct mg_mgr {
|
|||||||
struct mg_connection {
|
struct mg_connection {
|
||||||
struct mg_connection *next; // Linkage in struct mg_mgr :: connections
|
struct mg_connection *next; // Linkage in struct mg_mgr :: connections
|
||||||
struct mg_mgr *mgr; // Our container
|
struct mg_mgr *mgr; // Our container
|
||||||
struct mg_addr peer; // Remote peer address
|
struct mg_addr peer; // Remote address. For listeners, local address
|
||||||
void *fd; // Connected socket, or LWIP data
|
void *fd; // Connected socket, or LWIP data
|
||||||
unsigned long id; // Auto-incrementing unique connection ID
|
unsigned long id; // Auto-incrementing unique connection ID
|
||||||
struct mg_iobuf recv; // Incoming data
|
struct mg_iobuf recv; // Incoming data
|
||||||
|
28
src/sock.c
28
src/sock.c
@ -130,22 +130,20 @@ static void mg_set_non_blocking_mode(SOCKET fd) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SOCKET mg_open_listener(const char *url) {
|
SOCKET mg_open_listener(const char *url, struct mg_addr *addr) {
|
||||||
struct mg_addr addr;
|
|
||||||
SOCKET fd = INVALID_SOCKET;
|
SOCKET fd = INVALID_SOCKET;
|
||||||
|
memset(addr, 0, sizeof(*addr));
|
||||||
memset(&addr, 0, sizeof(addr));
|
addr->port = mg_htons(mg_url_port(url));
|
||||||
addr.port = mg_htons(mg_url_port(url));
|
if (!mg_aton(mg_url_host(url), addr)) {
|
||||||
if (!mg_aton(mg_url_host(url), &addr)) {
|
|
||||||
LOG(LL_ERROR, ("invalid listening URL: %s", url));
|
LOG(LL_ERROR, ("invalid listening URL: %s", url));
|
||||||
} else {
|
} else {
|
||||||
union usa usa = tousa(&addr);
|
union usa usa = tousa(addr);
|
||||||
int on = 1, af = AF_INET;
|
int on = 1, af = AF_INET;
|
||||||
int type = strncmp(url, "udp:", 4) == 0 ? SOCK_DGRAM : SOCK_STREAM;
|
int type = strncmp(url, "udp:", 4) == 0 ? SOCK_DGRAM : SOCK_STREAM;
|
||||||
int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
|
int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
|
||||||
socklen_t slen = sizeof(usa.sin);
|
socklen_t slen = sizeof(usa.sin);
|
||||||
#if MG_ENABLE_IPV6
|
#if MG_ENABLE_IPV6
|
||||||
if (addr.is_ip6) af = AF_INET6, slen = sizeof(usa.sin6);
|
if (addr->is_ip6) af = AF_INET6, slen = sizeof(usa.sin6);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((fd = socket(af, type, proto)) != INVALID_SOCKET &&
|
if ((fd = socket(af, type, proto)) != INVALID_SOCKET &&
|
||||||
@ -169,6 +167,13 @@ SOCKET mg_open_listener(const char *url) {
|
|||||||
bind(fd, &usa.sa, slen) == 0 &&
|
bind(fd, &usa.sa, slen) == 0 &&
|
||||||
// NOTE(lsm): FreeRTOS uses backlog value as a connection limit
|
// NOTE(lsm): FreeRTOS uses backlog value as a connection limit
|
||||||
(type == SOCK_DGRAM || listen(fd, 128) == 0)) {
|
(type == SOCK_DGRAM || listen(fd, 128) == 0)) {
|
||||||
|
// In case port was set to 0, get the real port number
|
||||||
|
if (getsockname(fd, &usa.sa, &slen) == 0) {
|
||||||
|
addr->port = usa.sin.sin_port;
|
||||||
|
#if MG_ENABLE_IPV6
|
||||||
|
if (addr->is_ip6) addr->port = usa.sin6.sin6_port;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
mg_set_non_blocking_mode(fd);
|
mg_set_non_blocking_mode(fd);
|
||||||
} else if (fd != INVALID_SOCKET) {
|
} else if (fd != INVALID_SOCKET) {
|
||||||
closesocket(fd);
|
closesocket(fd);
|
||||||
@ -458,19 +463,22 @@ struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url,
|
|||||||
mg_event_handler_t fn, void *fn_data) {
|
mg_event_handler_t fn, void *fn_data) {
|
||||||
struct mg_connection *c = NULL;
|
struct mg_connection *c = NULL;
|
||||||
bool is_udp = strncmp(url, "udp:", 4) == 0;
|
bool is_udp = strncmp(url, "udp:", 4) == 0;
|
||||||
SOCKET fd = mg_open_listener(url);
|
struct mg_addr addr;
|
||||||
|
SOCKET fd = mg_open_listener(url, &addr);
|
||||||
if (fd == INVALID_SOCKET) {
|
if (fd == INVALID_SOCKET) {
|
||||||
} else if ((c = alloc_conn(mgr, 0, fd)) == NULL) {
|
} else if ((c = alloc_conn(mgr, 0, fd)) == NULL) {
|
||||||
LOG(LL_ERROR, ("OOM %s", url));
|
LOG(LL_ERROR, ("OOM %s", url));
|
||||||
closesocket(fd);
|
closesocket(fd);
|
||||||
} else {
|
} else {
|
||||||
|
memcpy(&c->peer, &addr, sizeof(struct mg_addr));
|
||||||
c->fd = sock2ptr(fd);
|
c->fd = sock2ptr(fd);
|
||||||
c->is_listening = 1;
|
c->is_listening = 1;
|
||||||
c->is_udp = is_udp;
|
c->is_udp = is_udp;
|
||||||
LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
|
LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
|
||||||
c->fn = fn;
|
c->fn = fn;
|
||||||
c->fn_data = fn_data;
|
c->fn_data = fn_data;
|
||||||
LOG(LL_INFO, ("%lu accepting on %s", c->id, url));
|
LOG(LL_INFO,
|
||||||
|
("%lu accepting on %s (port %u)", c->id, url, mg_ntohs(c->peer.port)));
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user