Commit 0c79fcfb authored by Dmitry Frank's avatar Dmitry Frank Committed by Cesanta Bot

Add a flag to prevent a tunnel from reconnection

Also fixed a memory leak on reconnect: previously, each reconnect was
creating a `struct mg_connection` which was never reclaimed

PUBLISHED_FROM=eefdcf557e032ac81d5ed3aba55ac912e400148e
parent 9125830d
...@@ -53,6 +53,7 @@ signature: | ...@@ -53,6 +53,7 @@ signature: |
#define MG_F_WEBSOCKET_NO_DEFRAG (1 << 12) /* Websocket specific */ #define MG_F_WEBSOCKET_NO_DEFRAG (1 << 12) /* Websocket specific */
#define MG_F_DELETE_CHUNK (1 << 13) /* HTTP specific */ #define MG_F_DELETE_CHUNK (1 << 13) /* HTTP specific */
#define MG_F_ENABLE_BROADCAST (1 << 14) /* Allow broadcast address usage */ #define MG_F_ENABLE_BROADCAST (1 << 14) /* Allow broadcast address usage */
#define MG_F_TUN_DO_NOT_RECONNECT (1 << 15) /* Don't reconnect tunnel */
#define MG_F_USER_1 (1 << 20) /* Flags left for application */ #define MG_F_USER_1 (1 << 20) /* Flags left for application */
#define MG_F_USER_2 (1 << 21) #define MG_F_USER_2 (1 << 21)
......
...@@ -1937,6 +1937,7 @@ struct mg_tun_client { ...@@ -1937,6 +1937,7 @@ struct mg_tun_client {
struct mg_connection *disp; struct mg_connection *disp;
struct mg_connection *listener; struct mg_connection *listener;
struct mg_connection *reconnect;
}; };
#ifdef __cplusplus #ifdef __cplusplus
...@@ -11207,7 +11208,7 @@ int mg_set_protocol_coap(struct mg_connection *nc) { ...@@ -11207,7 +11208,7 @@ int mg_set_protocol_coap(struct mg_connection *nc) {
/* Amalgamated: #include "mongoose/src/tun.h" */ /* Amalgamated: #include "mongoose/src/tun.h" */
/* Amalgamated: #include "mongoose/src/util.h" */ /* Amalgamated: #include "mongoose/src/util.h" */
static void mg_tun_reconnect(struct mg_tun_client *client); static void mg_tun_reconnect(struct mg_tun_client *client, int timeout);
static void mg_tun_init_client(struct mg_tun_client *client, struct mg_mgr *mgr, static void mg_tun_init_client(struct mg_tun_client *client, struct mg_mgr *mgr,
struct mg_iface *iface, const char *dispatcher, struct mg_iface *iface, const char *dispatcher,
...@@ -11220,6 +11221,7 @@ static void mg_tun_init_client(struct mg_tun_client *client, struct mg_mgr *mgr, ...@@ -11220,6 +11221,7 @@ static void mg_tun_init_client(struct mg_tun_client *client, struct mg_mgr *mgr,
client->disp = NULL; /* will be set by mg_tun_reconnect */ client->disp = NULL; /* will be set by mg_tun_reconnect */
client->listener = NULL; /* will be set by mg_do_bind */ client->listener = NULL; /* will be set by mg_do_bind */
client->reconnect = NULL; /* will be set by mg_tun_reconnect */
} }
void mg_tun_log_frame(struct mg_tun_frame *frame) { void mg_tun_log_frame(struct mg_tun_frame *frame) {
...@@ -11318,7 +11320,8 @@ static void mg_tun_client_handler(struct mg_connection *nc, int ev, ...@@ -11318,7 +11320,8 @@ static void mg_tun_client_handler(struct mg_connection *nc, int ev,
mg_tun_close_all(client); mg_tun_close_all(client);
client->disp = NULL; client->disp = NULL;
LOG(LL_INFO, ("Dispatcher connection is no more, reconnecting")); LOG(LL_INFO, ("Dispatcher connection is no more, reconnecting"));
mg_tun_reconnect(client); /* TODO(mkm): implement exp back off */
mg_tun_reconnect(client, MG_TUN_RECONNECT_INTERVAL);
} }
break; break;
} }
...@@ -11356,17 +11359,23 @@ void mg_tun_reconnect_ev_handler(struct mg_connection *nc, int ev, ...@@ -11356,17 +11359,23 @@ void mg_tun_reconnect_ev_handler(struct mg_connection *nc, int ev,
switch (ev) { switch (ev) {
case MG_EV_TIMER: case MG_EV_TIMER:
if (!(client->listener->flags & MG_F_TUN_DO_NOT_RECONNECT)) {
mg_tun_do_reconnect(client); mg_tun_do_reconnect(client);
} else {
/* Reconnecting is suppressed, we'll check again at the next poll */
mg_tun_reconnect(client, 0);
}
break; break;
} }
} }
static void mg_tun_reconnect(struct mg_tun_client *client) { static void mg_tun_reconnect(struct mg_tun_client *client, int timeout) {
struct mg_connection *nc; if (client->reconnect == NULL) {
nc = mg_add_sock(client->mgr, INVALID_SOCKET, mg_tun_reconnect_ev_handler); client->reconnect =
nc->user_data = client; mg_add_sock(client->mgr, INVALID_SOCKET, mg_tun_reconnect_ev_handler);
/* TODO(mkm): implement exp back off */ client->reconnect->user_data = client;
nc->ev_timer_time = mg_time() + MG_TUN_RECONNECT_INTERVAL; }
client->reconnect->ev_timer_time = mg_time() + timeout;
} }
static struct mg_tun_client *mg_tun_create_client(struct mg_mgr *mgr, static struct mg_tun_client *mg_tun_create_client(struct mg_mgr *mgr,
...@@ -11384,7 +11393,12 @@ static struct mg_tun_client *mg_tun_create_client(struct mg_mgr *mgr, ...@@ -11384,7 +11393,12 @@ static struct mg_tun_client *mg_tun_create_client(struct mg_mgr *mgr,
mg_tun_init_client(client, mgr, iface, dispatcher, ssl); mg_tun_init_client(client, mgr, iface, dispatcher, ssl);
iface->data = client; iface->data = client;
mg_tun_do_reconnect(client); /*
* We need to give application a chance to set MG_F_TUN_DO_NOT_RECONNECT on a
* listening connection right after mg_tun_bind_opt() returned it, so we
* should use mg_tun_reconnect() here, instead of mg_tun_do_reconnect()
*/
mg_tun_reconnect(client, 0);
return client; return client;
} }
...@@ -11403,6 +11417,10 @@ void mg_tun_destroy_client(struct mg_tun_client *client) { ...@@ -11403,6 +11417,10 @@ void mg_tun_destroy_client(struct mg_tun_client *client) {
client->disp->user_data = NULL; client->disp->user_data = NULL;
} }
if (client != NULL && client->reconnect != NULL) {
client->reconnect->flags |= MG_F_CLOSE_IMMEDIATELY;
}
if (client != NULL && client->iface != NULL) { if (client != NULL && client->iface != NULL) {
client->iface->data = NULL; client->iface->data = NULL;
} }
......
...@@ -3165,6 +3165,7 @@ struct mg_connection { ...@@ -3165,6 +3165,7 @@ struct mg_connection {
#define MG_F_WEBSOCKET_NO_DEFRAG (1 << 12) /* Websocket specific */ #define MG_F_WEBSOCKET_NO_DEFRAG (1 << 12) /* Websocket specific */
#define MG_F_DELETE_CHUNK (1 << 13) /* HTTP specific */ #define MG_F_DELETE_CHUNK (1 << 13) /* HTTP specific */
#define MG_F_ENABLE_BROADCAST (1 << 14) /* Allow broadcast address usage */ #define MG_F_ENABLE_BROADCAST (1 << 14) /* Allow broadcast address usage */
#define MG_F_TUN_DO_NOT_RECONNECT (1 << 15) /* Don't reconnect tunnel */
#define MG_F_USER_1 (1 << 20) /* Flags left for application */ #define MG_F_USER_1 (1 << 20) /* Flags left for application */
#define MG_F_USER_2 (1 << 21) #define MG_F_USER_2 (1 << 21)
......
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