Commit 8ae0400b authored by Sergey Lyubka's avatar Sergey Lyubka

Added ability to set "0" as listening port. Exported local_ip and local_port to the client.

parent 037fdbcc
...@@ -275,6 +275,7 @@ struct mg_server { ...@@ -275,6 +275,7 @@ struct mg_server {
mg_handler_t error_handler; mg_handler_t error_handler;
mg_handler_t auth_handler; mg_handler_t auth_handler;
char *config_options[NUM_OPTIONS]; char *config_options[NUM_OPTIONS];
char local_ip[48];
void *server_data; void *server_data;
#ifdef MONGOOSE_USE_SSL #ifdef MONGOOSE_USE_SSL
SSL_CTX *ssl_ctx; // Server SSL context SSL_CTX *ssl_ctx; // Server SSL context
...@@ -1214,6 +1215,7 @@ static void forward_post_data(struct connection *conn) { ...@@ -1214,6 +1215,7 @@ static void forward_post_data(struct connection *conn) {
// 'sa' must be an initialized address to bind to // 'sa' must be an initialized address to bind to
static sock_t open_listening_socket(union socket_address *sa) { static sock_t open_listening_socket(union socket_address *sa) {
socklen_t len = sizeof(*sa);
sock_t on = 1, sock = INVALID_SOCKET; sock_t on = 1, sock = INVALID_SOCKET;
if ((sock = socket(sa->sa.sa_family, SOCK_STREAM, 6)) != INVALID_SOCKET && if ((sock = socket(sa->sa.sa_family, SOCK_STREAM, 6)) != INVALID_SOCKET &&
...@@ -1222,6 +1224,8 @@ static sock_t open_listening_socket(union socket_address *sa) { ...@@ -1222,6 +1224,8 @@ static sock_t open_listening_socket(union socket_address *sa) {
sizeof(sa->sin) : sizeof(sa->sa)) && sizeof(sa->sin) : sizeof(sa->sa)) &&
!listen(sock, SOMAXCONN)) { !listen(sock, SOMAXCONN)) {
set_non_blocking_mode(sock); set_non_blocking_mode(sock);
// In case port was set to 0, get the real port number
(void) getsockname(sock, &sa->sa, &len);
} else if (sock != INVALID_SOCKET) { } else if (sock != INVALID_SOCKET) {
closesocket(sock); closesocket(sock);
sock = INVALID_SOCKET; sock = INVALID_SOCKET;
...@@ -1329,6 +1333,8 @@ static struct connection *accept_new_connection(struct mg_server *server) { ...@@ -1329,6 +1333,8 @@ static struct connection *accept_new_connection(struct mg_server *server) {
sizeof(conn->mg_conn.remote_ip), &sa); sizeof(conn->mg_conn.remote_ip), &sa);
conn->mg_conn.remote_port = ntohs(sa.sin.sin_port); conn->mg_conn.remote_port = ntohs(sa.sin.sin_port);
conn->mg_conn.server_param = server->server_data; conn->mg_conn.server_param = server->server_data;
conn->mg_conn.local_ip = server->local_ip;
conn->mg_conn.local_port = ntohs(server->lsa.sin.sin_port);
LINKED_LIST_ADD_TO_FRONT(&server->active_connections, &conn->link); LINKED_LIST_ADD_TO_FRONT(&server->active_connections, &conn->link);
DBG(("added conn %p", conn)); DBG(("added conn %p", conn));
} }
...@@ -4067,7 +4073,7 @@ static int parse_port_string(const char *str, union socket_address *sa) { ...@@ -4067,7 +4073,7 @@ static int parse_port_string(const char *str, union socket_address *sa) {
port = 0; // Parsing failure. Make port invalid. port = 0; // Parsing failure. Make port invalid.
} }
return port > 0 && port < 0xffff && str[len] == '\0'; return port <= 0xffff && str[len] == '\0';
} }
const char *mg_set_option(struct mg_server *server, const char *name, const char *mg_set_option(struct mg_server *server, const char *name,
...@@ -4092,6 +4098,16 @@ const char *mg_set_option(struct mg_server *server, const char *name, ...@@ -4092,6 +4098,16 @@ const char *mg_set_option(struct mg_server *server, const char *name,
server->listening_sock = open_listening_socket(&server->lsa); server->listening_sock = open_listening_socket(&server->lsa);
if (server->listening_sock == INVALID_SOCKET) { if (server->listening_sock == INVALID_SOCKET) {
error_msg = "Cannot bind to port"; error_msg = "Cannot bind to port";
} else {
sockaddr_to_string(server->local_ip, sizeof(server->local_ip),
&server->lsa);
if (!strcmp(value, "0")) {
char buf[10];
mg_snprintf(buf, sizeof(buf), "%d",
(int) ntohs(server->lsa.sin.sin_port));
free(server->config_options[ind]);
server->config_options[ind] = mg_strdup(buf);
}
} }
#ifndef _WIN32 #ifndef _WIN32
} else if (ind == RUN_AS_USER) { } else if (ind == RUN_AS_USER) {
......
...@@ -38,6 +38,8 @@ struct mg_connection { ...@@ -38,6 +38,8 @@ struct mg_connection {
char remote_ip[48]; // Max IPv6 string length is 45 characters char remote_ip[48]; // Max IPv6 string length is 45 characters
int remote_port; // Client's port int remote_port; // Client's port
const char *local_ip; // Local IP address
int local_port; // Local port number
int num_headers; // Number of HTTP headers int num_headers; // Number of HTTP headers
struct mg_header { struct mg_header {
......
...@@ -289,7 +289,7 @@ static const char *test_parse_port_string(void) { ...@@ -289,7 +289,7 @@ static const char *test_parse_port_string(void) {
NULL NULL
}; };
static const char *invalid[] = { static const char *invalid[] = {
"0", "99999", "1k", "1.2.3", "1.2.3.4:", "1.2.3.4:2p", NULL "99999", "1k", "1.2.3", "1.2.3.4:", "1.2.3.4:2p", NULL
}; };
union socket_address sa; union socket_address sa;
int i; int i;
...@@ -301,6 +301,7 @@ static const char *test_parse_port_string(void) { ...@@ -301,6 +301,7 @@ static const char *test_parse_port_string(void) {
for (i = 0; invalid[i] != NULL; i++) { for (i = 0; invalid[i] != NULL; i++) {
ASSERT(parse_port_string(invalid[i], &sa) == 0); ASSERT(parse_port_string(invalid[i], &sa) == 0);
} }
ASSERT(parse_port_string("0", &sa) != 0);
return NULL; return NULL;
} }
...@@ -577,6 +578,14 @@ static const char *test_ssl(void) { ...@@ -577,6 +578,14 @@ static const char *test_ssl(void) {
} }
#endif #endif
static const char *test_mg_set_option(void) {
struct mg_server *server = mg_create_server(NULL);
ASSERT(mg_set_option(server, "listening_port", "0") == NULL);
ASSERT(mg_get_option(server, "listening_port")[0] != '\0');
mg_destroy_server(&server);
return NULL;
}
static const char *run_all_tests(void) { static const char *run_all_tests(void) {
RUN_TEST(test_should_keep_alive); RUN_TEST(test_should_keep_alive);
RUN_TEST(test_match_prefix); RUN_TEST(test_match_prefix);
...@@ -592,6 +601,7 @@ static const char *run_all_tests(void) { ...@@ -592,6 +601,7 @@ static const char *run_all_tests(void) {
RUN_TEST(test_parse_multipart); RUN_TEST(test_parse_multipart);
RUN_TEST(test_server); RUN_TEST(test_server);
RUN_TEST(test_mg_connect); RUN_TEST(test_mg_connect);
RUN_TEST(test_mg_set_option);
#ifdef MONGOOSE_USE_SSL #ifdef MONGOOSE_USE_SSL
RUN_TEST(test_ssl); RUN_TEST(test_ssl);
#endif #endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment