diff --git a/docs/c-api/net.h/struct_mg_connection.md b/docs/c-api/net.h/struct_mg_connection.md index 8c5a8b1048949d6ce1082e3b26c1259bf0d0d1d9..be69d16fd60f8d04c70a1a1c1febd3a93e026be2 100644 --- a/docs/c-api/net.h/struct_mg_connection.md +++ b/docs/c-api/net.h/struct_mg_connection.md @@ -48,12 +48,11 @@ signature: | #define MG_F_IS_WEBSOCKET (1 << 8) /* Websocket specific */ /* Flags that are settable by user */ - #define MG_F_SEND_AND_CLOSE (1 << 10) /* Push remaining data and close */ - #define MG_F_CLOSE_IMMEDIATELY (1 << 11) /* Disconnect */ - #define MG_F_WEBSOCKET_NO_DEFRAG (1 << 12) /* Websocket specific */ - #define MG_F_DELETE_CHUNK (1 << 13) /* HTTP specific */ - #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_SEND_AND_CLOSE (1 << 10) /* Push remaining data and close */ + #define MG_F_CLOSE_IMMEDIATELY (1 << 11) /* Disconnect */ + #define MG_F_WEBSOCKET_NO_DEFRAG (1 << 12) /* Websocket specific */ + #define MG_F_DELETE_CHUNK (1 << 13) /* HTTP specific */ + #define MG_F_ENABLE_BROADCAST (1 << 14) /* Allow broadcast address usage */ #define MG_F_USER_1 (1 << 20) /* Flags left for application */ #define MG_F_USER_2 (1 << 21) diff --git a/mongoose.c b/mongoose.c index e47801bbdb808387df90d3d9c0f494c6aef8d19e..5dbb9b3f7eed40625b80d6cadcfbe9d9df2c53f1 100644 --- a/mongoose.c +++ b/mongoose.c @@ -2146,93 +2146,6 @@ size_t mg_match_prefix(const char *pattern, int pattern_len, const char *str) { #endif /* EXCLUDE_COMMON */ #ifdef MG_MODULE_LINES -#line 1 "mongoose/src/tun.h" -#endif -/* - * Copyright (c) 2014-2016 Cesanta Software Limited - * All rights reserved - */ - -#ifndef CS_MONGOOSE_SRC_TUN_H_ -#define CS_MONGOOSE_SRC_TUN_H_ - -#if MG_ENABLE_TUN - -/* Amalgamated: #include "mongoose/src/net.h" */ -/* Amalgamated: #include "common/mg_str.h" */ - -#ifndef MG_TUN_RECONNECT_INTERVAL -#define MG_TUN_RECONNECT_INTERVAL 1 -#endif - -#define MG_TUN_PROTO_NAME "mg_tun" - -#define MG_TUN_DATA_FRAME 0x0 -#define MG_TUN_F_END_STREAM 0x1 - -/* - * MG TUN frame format is loosely based on HTTP/2. - * However since the communication happens via WebSocket - * there is no need to encode the frame length, since that's - * solved by WebSocket framing. - * - * TODO(mkm): Detailed description of the protocol. - */ -struct mg_tun_frame { - uint8_t type; - uint8_t flags; - uint32_t stream_id; /* opaque stream identifier */ - struct mg_str body; -}; - -struct mg_tun_ssl_opts { -#if MG_ENABLE_SSL - const char *ssl_cert; - const char *ssl_key; - const char *ssl_ca_cert; -#else - int dummy; /* some compilers don't like empty structs */ -#endif -}; - -struct mg_tun_client { - struct mg_mgr *mgr; - struct mg_iface *iface; - const char *disp_url; - struct mg_tun_ssl_opts ssl; - - uint32_t last_stream_id; /* stream id of most recently accepted connection */ - - struct mg_connection *disp; - struct mg_connection *listener; - struct mg_connection *reconnect; -}; - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -struct mg_connection *mg_tun_bind_opt(struct mg_mgr *mgr, - const char *dispatcher, - MG_CB(mg_event_handler_t handler, - void *user_data), - struct mg_bind_opts opts); - -int mg_tun_parse_frame(void *data, size_t len, struct mg_tun_frame *frame); - -void mg_tun_send_frame(struct mg_connection *ws, uint32_t stream_id, - uint8_t type, uint8_t flags, struct mg_str msg); - -void mg_tun_destroy_client(struct mg_tun_client *client); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* MG_ENABLE_TUN */ - -#endif /* CS_MONGOOSE_SRC_TUN_H_ */ -#ifdef MG_MODULE_LINES #line 1 "mongoose/src/net.c" #endif /* @@ -2257,7 +2170,6 @@ void mg_tun_destroy_client(struct mg_tun_client *client); /* Amalgamated: #include "mongoose/src/dns.h" */ /* Amalgamated: #include "mongoose/src/internal.h" */ /* Amalgamated: #include "mongoose/src/resolv.h" */ -/* Amalgamated: #include "mongoose/src/tun.h" */ /* Amalgamated: #include "mongoose/src/util.h" */ #define MG_MAX_HOST_LEN 200 @@ -3053,13 +2965,6 @@ struct mg_connection *mg_bind_opt(struct mg_mgr *mgr, const char *address, MG_COPY_COMMON_CONNECTION_OPTIONS(&add_sock_opts, &opts); -#if MG_ENABLE_TUN - if (mg_strncmp(mg_mk_str(address), mg_mk_str("ws://"), 5) == 0 || - mg_strncmp(mg_mk_str(address), mg_mk_str("wss://"), 6) == 0) { - return mg_tun_bind_opt(mgr, address, MG_CB(callback, user_data), opts); - } -#endif - if (mg_parse_address(address, &sa, &proto, host, sizeof(host)) <= 0) { MG_SET_PTRPTR(opts.error_string, "cannot parse address"); return NULL; @@ -3280,39 +3185,6 @@ extern const struct mg_iface_vtable mg_socket_iface_vtable; #endif /* CS_MONGOOSE_SRC_NET_IF_SOCKET_H_ */ #ifdef MG_MODULE_LINES -#line 1 "mongoose/src/net_if_tun.h" -#endif -/* - * Copyright (c) 2014-2016 Cesanta Software Limited - * All rights reserved - */ - -#ifndef CS_MONGOOSE_SRC_NET_IF_TUN_H_ -#define CS_MONGOOSE_SRC_NET_IF_TUN_H_ - -#if MG_ENABLE_TUN - -/* Amalgamated: #include "mongoose/src/net_if.h" */ - -struct mg_tun_client; - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -extern const struct mg_iface_vtable mg_tun_iface_vtable; - -struct mg_connection *mg_tun_if_find_conn(struct mg_tun_client *client, - uint32_t stream_id); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* MG_ENABLE_TUN */ - -#endif /* CS_MONGOOSE_SRC_NET_IF_TUN_H_ */ -#ifdef MG_MODULE_LINES #line 1 "mongoose/src/net_if_socks.h" #endif /* @@ -3343,15 +3215,11 @@ extern const struct mg_iface_vtable mg_socks_iface_vtable; /* Amalgamated: #include "mongoose/src/net_if.h" */ /* Amalgamated: #include "mongoose/src/internal.h" */ /* Amalgamated: #include "mongoose/src/net_if_socket.h" */ -/* Amalgamated: #include "mongoose/src/net_if_tun.h" */ extern const struct mg_iface_vtable mg_default_iface_vtable; const struct mg_iface_vtable *mg_ifaces[] = { &mg_default_iface_vtable, -#if MG_ENABLE_TUN - &mg_tun_iface_vtable, -#endif }; int mg_num_ifaces = (int) (sizeof(mg_ifaces) / sizeof(mg_ifaces[0])); @@ -4350,180 +4218,6 @@ struct mg_iface *mg_socks_mk_iface(struct mg_mgr *mgr, const char *proxy_addr) { #endif #ifdef MG_MODULE_LINES -#line 1 "mongoose/src/net_if_tun.c" -#endif -/* - * Copyright (c) 2014-2016 Cesanta Software Limited - * All rights reserved - */ - -#if MG_ENABLE_TUN - -/* Amalgamated: #include "common/cs_dbg.h" */ -/* Amalgamated: #include "common/cs_time.h" */ -/* Amalgamated: #include "mongoose/src/internal.h" */ -/* Amalgamated: #include "mongoose/src/net_if_tun.h" */ -/* Amalgamated: #include "mongoose/src/tun.h" */ -/* Amalgamated: #include "mongoose/src/util.h" */ - -#define MG_TCP_RECV_BUFFER_SIZE 1024 -#define MG_UDP_RECV_BUFFER_SIZE 1500 - -void mg_tun_if_connect_tcp(struct mg_connection *nc, - const union socket_address *sa) { - (void) nc; - (void) sa; -} - -void mg_tun_if_connect_udp(struct mg_connection *nc) { - (void) nc; -} - -int mg_tun_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) { - (void) nc; - (void) sa; - return 0; -} - -int mg_tun_if_listen_udp(struct mg_connection *nc, union socket_address *sa) { - (void) nc; - (void) sa; - return -1; -} - -void mg_tun_if_tcp_send(struct mg_connection *nc, const void *buf, size_t len) { - struct mg_tun_client *client = (struct mg_tun_client *) nc->iface->data; - uint32_t stream_id = (uint32_t)(uintptr_t) nc->mgr_data; - struct mg_str msg = {(char *) buf, len}; -#if MG_ENABLE_HEXDUMP - char hex[512]; - mg_hexdump(buf, len, hex, sizeof(hex)); - LOG(LL_DEBUG, ("sending to stream 0x%x:\n%s", (unsigned int) stream_id, hex)); -#endif - - mg_tun_send_frame(client->disp, stream_id, MG_TUN_DATA_FRAME, 0, msg); -} - -void mg_tun_if_udp_send(struct mg_connection *nc, const void *buf, size_t len) { - (void) nc; - (void) buf; - (void) len; -} - -void mg_tun_if_recved(struct mg_connection *nc, size_t len) { - (void) nc; - (void) len; -} - -int mg_tun_if_create_conn(struct mg_connection *nc) { - (void) nc; - return 1; -} - -void mg_tun_if_destroy_conn(struct mg_connection *nc) { - struct mg_tun_client *client = (struct mg_tun_client *) nc->iface->data; - - if (nc->flags & MG_F_LISTENING) { - mg_tun_destroy_client(client); - } else if (client->disp) { - uint32_t stream_id = (uint32_t)(uintptr_t) nc->mgr_data; - struct mg_str msg = {NULL, 0}; - - LOG(LL_DEBUG, ("closing 0x%x:", (unsigned int) stream_id)); - mg_tun_send_frame(client->disp, stream_id, MG_TUN_DATA_FRAME, - MG_TUN_F_END_STREAM, msg); - } -} - -/* Associate a socket to a connection. */ -void mg_tun_if_sock_set(struct mg_connection *nc, sock_t sock) { - (void) nc; - (void) sock; -} - -void mg_tun_if_init(struct mg_iface *iface) { - (void) iface; -} - -void mg_tun_if_free(struct mg_iface *iface) { - (void) iface; -} - -void mg_tun_if_add_conn(struct mg_connection *nc) { - nc->sock = INVALID_SOCKET; -} - -void mg_tun_if_remove_conn(struct mg_connection *nc) { - (void) nc; -} - -time_t mg_tun_if_poll(struct mg_iface *iface, int timeout_ms) { - (void) iface; - (void) timeout_ms; - return (time_t) cs_time(); -} - -void mg_tun_if_get_conn_addr(struct mg_connection *nc, int remote, - union socket_address *sa) { - (void) nc; - (void) remote; - (void) sa; -} - -struct mg_connection *mg_tun_if_find_conn(struct mg_tun_client *client, - uint32_t stream_id) { - struct mg_connection *nc = NULL; - - for (nc = client->mgr->active_connections; nc != NULL; nc = nc->next) { - if (nc->iface != client->iface || (nc->flags & MG_F_LISTENING)) { - continue; - } - if (stream_id == (uint32_t)(uintptr_t) nc->mgr_data) { - return nc; - } - } - - if (stream_id > client->last_stream_id) { - /* create a new connection */ - LOG(LL_DEBUG, ("new stream 0x%x, accepting", (unsigned int) stream_id)); - nc = mg_if_accept_new_conn(client->listener); - nc->mgr_data = (void *) (uintptr_t) stream_id; - client->last_stream_id = stream_id; - } else { - LOG(LL_DEBUG, - ("Ignoring stream 0x%x (last_stream_id 0x%x)", (unsigned int) stream_id, - (unsigned int) client->last_stream_id)); - } - - return nc; -} - -/* clang-format off */ -#define MG_TUN_IFACE_VTABLE \ - { \ - mg_tun_if_init, \ - mg_tun_if_free, \ - mg_tun_if_add_conn, \ - mg_tun_if_remove_conn, \ - mg_tun_if_poll, \ - mg_tun_if_listen_tcp, \ - mg_tun_if_listen_udp, \ - mg_tun_if_connect_tcp, \ - mg_tun_if_connect_udp, \ - mg_tun_if_tcp_send, \ - mg_tun_if_udp_send, \ - mg_tun_if_recved, \ - mg_tun_if_create_conn, \ - mg_tun_if_destroy_conn, \ - mg_tun_if_sock_set, \ - mg_tun_if_get_conn_addr, \ - } -/* clang-format on */ - -const struct mg_iface_vtable mg_tun_iface_vtable = MG_TUN_IFACE_VTABLE; - -#endif /* MG_ENABLE_TUN */ -#ifdef MG_MODULE_LINES #line 1 "mongoose/src/ssl_if_openssl.c" #endif /* @@ -12439,324 +12133,6 @@ int mg_set_protocol_coap(struct mg_connection *nc) { #endif /* MG_ENABLE_COAP */ #ifdef MG_MODULE_LINES -#line 1 "mongoose/src/tun.c" -#endif -/* - * Copyright (c) 2014 Cesanta Software Limited - * All rights reserved - */ - -#if MG_ENABLE_TUN - -/* Amalgamated: #include "common/cs_dbg.h" */ -/* Amalgamated: #include "mongoose/src/http.h" */ -/* Amalgamated: #include "mongoose/src/internal.h" */ -/* Amalgamated: #include "mongoose/src/net.h" */ -/* Amalgamated: #include "mongoose/src/net_if_tun.h" */ -/* Amalgamated: #include "mongoose/src/tun.h" */ -/* Amalgamated: #include "mongoose/src/util.h" */ - -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, - struct mg_iface *iface, const char *dispatcher, - struct mg_tun_ssl_opts ssl) { - client->mgr = mgr; - client->iface = iface; - client->disp_url = dispatcher; - client->last_stream_id = 0; - client->ssl = ssl; - - client->disp = NULL; /* will be set by mg_tun_reconnect */ - 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) { - LOG(LL_DEBUG, ("Got TUN frame: type=0x%x, flags=0x%x stream_id=0x%x, " - "len=%d", - frame->type, frame->flags, (unsigned int) frame->stream_id, - (int) frame->body.len)); -#if MG_ENABLE_HEXDUMP - { - char hex[512]; - mg_hexdump(frame->body.p, frame->body.len, hex, sizeof(hex) - 1); - hex[sizeof(hex) - 1] = '\0'; - LOG(LL_DEBUG, ("body:\n%s", hex)); - } -#else - LOG(LL_DEBUG, ("body: '%.*s'", (int) frame->body.len, frame->body.p)); -#endif -} - -static void mg_tun_close_all(struct mg_tun_client *client) { - struct mg_connection *nc; - for (nc = client->mgr->active_connections; nc != NULL; nc = nc->next) { - if (nc->iface == client->iface && !(nc->flags & MG_F_LISTENING)) { - LOG(LL_DEBUG, ("Closing tunneled connection %p", nc)); - nc->flags |= MG_F_CLOSE_IMMEDIATELY; - /* mg_close_conn(nc); */ - } - } -} - -static void mg_tun_client_handler(struct mg_connection *nc, int ev, - void *ev_data MG_UD_ARG(void *user_data)) { -#if !MG_ENABLE_CALLBACK_USERDATA - void *user_data = nc->user_data; -#else - (void) nc; -#endif - struct mg_tun_client *client = (struct mg_tun_client *) user_data; - - switch (ev) { - case MG_EV_CONNECT: { - int err = *(int *) ev_data; - - if (err) { - LOG(LL_ERROR, ("Cannot connect to the tunnel dispatcher: %d", err)); - } else { - LOG(LL_INFO, ("Connected to the tunnel dispatcher")); - } - break; - } - case MG_EV_HTTP_REPLY: { - struct http_message *hm = (struct http_message *) ev_data; - - if (hm->resp_code != 200) { - LOG(LL_ERROR, - ("Tunnel dispatcher reply non-OK status code %d", hm->resp_code)); - } - break; - } - case MG_EV_WEBSOCKET_HANDSHAKE_DONE: { - LOG(LL_INFO, ("Tunnel dispatcher handshake done")); - break; - } - case MG_EV_WEBSOCKET_FRAME: { - struct websocket_message *wm = (struct websocket_message *) ev_data; - struct mg_connection *tc; - struct mg_tun_frame frame; - - if (mg_tun_parse_frame(wm->data, wm->size, &frame) == -1) { - LOG(LL_ERROR, ("Got invalid tun frame dropping")); - break; - } - - mg_tun_log_frame(&frame); - - tc = mg_tun_if_find_conn(client, frame.stream_id); - if (tc == NULL) { - if (frame.body.len > 0) { - LOG(LL_DEBUG, ("Got frame after receiving end has been closed")); - } - break; - } - if (frame.body.len > 0) { - mg_if_recv_tcp_cb(tc, (void *) frame.body.p, frame.body.len, - 0 /* own */); - } - if (frame.flags & MG_TUN_F_END_STREAM) { - LOG(LL_DEBUG, ("Closing tunneled connection because got end of stream " - "from other end")); - tc->flags |= MG_F_CLOSE_IMMEDIATELY; - mg_close_conn(tc); - } - break; - } - case MG_EV_CLOSE: { - LOG(LL_DEBUG, ("Closing all tunneled connections")); - /* - * The client might have been already freed when the listening socket is - * closed. - */ - if (client != NULL) { - mg_tun_close_all(client); - client->disp = NULL; - LOG(LL_INFO, ("Dispatcher connection is no more, reconnecting")); - /* TODO(mkm): implement exp back off */ - mg_tun_reconnect(client, MG_TUN_RECONNECT_INTERVAL); - } - break; - } - default: - break; - } -} - -static void mg_tun_do_reconnect(struct mg_tun_client *client) { - struct mg_connection *dc; - struct mg_connect_opts opts; - memset(&opts, 0, sizeof(opts)); -#if MG_ENABLE_SSL - opts.ssl_cert = client->ssl.ssl_cert; - opts.ssl_key = client->ssl.ssl_key; - opts.ssl_ca_cert = client->ssl.ssl_ca_cert; -#endif - /* HTTP/Websocket listener */ - if ((dc = mg_connect_ws_opt(client->mgr, MG_CB(mg_tun_client_handler, client), - opts, client->disp_url, MG_TUN_PROTO_NAME, - NULL)) == NULL) { - LOG(LL_ERROR, - ("Cannot connect to WS server on addr [%s]\n", client->disp_url)); - return; - } - - client->disp = dc; -#if !MG_ENABLE_CALLBACK_USERDATA - dc->user_data = client; -#endif -} - -void mg_tun_reconnect_ev_handler(struct mg_connection *nc, int ev, - void *ev_data MG_UD_ARG(void *user_data)) { -#if !MG_ENABLE_CALLBACK_USERDATA - void *user_data = nc->user_data; -#else - (void) nc; -#endif - struct mg_tun_client *client = (struct mg_tun_client *) user_data; - (void) ev_data; - - switch (ev) { - case MG_EV_TIMER: - if (!(client->listener->flags & MG_F_TUN_DO_NOT_RECONNECT)) { - mg_tun_do_reconnect(client); - } else { - /* Reconnecting is suppressed, we'll check again at the next poll */ - mg_tun_reconnect(client, 0); - } - break; - } -} - -static void mg_tun_reconnect(struct mg_tun_client *client, int timeout) { - if (client->reconnect == NULL) { - client->reconnect = mg_add_sock(client->mgr, INVALID_SOCKET, - MG_CB(mg_tun_reconnect_ev_handler, client)); -#if !MG_ENABLE_CALLBACK_USERDATA - client->reconnect->user_data = client; -#endif - } - client->reconnect->ev_timer_time = mg_time() + timeout; -} - -static struct mg_tun_client *mg_tun_create_client(struct mg_mgr *mgr, - const char *dispatcher, - struct mg_tun_ssl_opts ssl) { - struct mg_tun_client *client = NULL; - struct mg_iface *iface = mg_find_iface(mgr, &mg_tun_iface_vtable, NULL); - if (iface == NULL) { - LOG(LL_ERROR, ("The tun feature requires the manager to have a tun " - "interface enabled")); - return NULL; - } - - client = (struct mg_tun_client *) MG_MALLOC(sizeof(*client)); - mg_tun_init_client(client, mgr, iface, dispatcher, ssl); - iface->data = 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; -} - -void mg_tun_destroy_client(struct mg_tun_client *client) { - /* - * NOTE: - * `client` is NULL in case of OOM - * `client->disp` is NULL if connection failed - * `client->iface is NULL is `mg_find_iface` failed - */ - - if (client != NULL && client->disp != NULL) { - /* the dispatcher connection handler will in turn close all tunnels */ - client->disp->flags |= MG_F_CLOSE_IMMEDIATELY; - /* this is used as a signal to other tun handlers that the party is over */ - client->disp->user_data = NULL; - } - - if (client != NULL && client->reconnect != NULL) { - client->reconnect->flags |= MG_F_CLOSE_IMMEDIATELY; - } - - if (client != NULL && client->iface != NULL) { - client->iface->data = NULL; - } - - MG_FREE(client); -} - -static struct mg_connection *mg_tun_do_bind(struct mg_tun_client *client, - MG_CB(mg_event_handler_t handler, - void *user_data), - struct mg_bind_opts opts) { - struct mg_connection *lc; - opts.iface = client->iface; - lc = mg_bind_opt(client->mgr, ":1234" /* dummy port */, - MG_CB(handler, user_data), opts); - client->listener = lc; - return lc; -} - -struct mg_connection *mg_tun_bind_opt(struct mg_mgr *mgr, - const char *dispatcher, - MG_CB(mg_event_handler_t handler, - void *user_data), - struct mg_bind_opts opts) { -#if MG_ENABLE_SSL - struct mg_tun_ssl_opts ssl = {opts.ssl_cert, opts.ssl_key, opts.ssl_ca_cert}; -#else - struct mg_tun_ssl_opts ssl = {0}; -#endif - struct mg_tun_client *client = mg_tun_create_client(mgr, dispatcher, ssl); - if (client == NULL) { - return NULL; - } -#if MG_ENABLE_SSL - /* these options don't make sense in the local mouth of the tunnel */ - opts.ssl_cert = NULL; - opts.ssl_key = NULL; - opts.ssl_ca_cert = NULL; -#endif - return mg_tun_do_bind(client, MG_CB(handler, user_data), opts); -} - -int mg_tun_parse_frame(void *data, size_t len, struct mg_tun_frame *frame) { - const size_t header_size = sizeof(uint32_t) + sizeof(uint8_t) * 2; - if (len < header_size) { - return -1; - } - - frame->type = *(uint8_t *) (data); - frame->flags = *(uint8_t *) ((char *) data + 1); - memcpy(&frame->stream_id, (char *) data + 2, sizeof(uint32_t)); - frame->stream_id = ntohl(frame->stream_id); - frame->body.p = (char *) data + header_size; - frame->body.len = len - header_size; - return 0; -} - -void mg_tun_send_frame(struct mg_connection *ws, uint32_t stream_id, - uint8_t type, uint8_t flags, struct mg_str msg) { - stream_id = htonl(stream_id); - { - struct mg_str parts[] = { - {(char *) &type, sizeof(type)}, - {(char *) &flags, sizeof(flags)}, - {(char *) &stream_id, sizeof(stream_id)}, - {msg.p, msg.len} /* vc6 doesn't like just `msg` here */}; - mg_send_websocket_framev(ws, WEBSOCKET_OP_BINARY, parts, - sizeof(parts) / sizeof(parts[0])); - } -} - -#endif /* MG_ENABLE_TUN */ -#ifdef MG_MODULE_LINES #line 1 "mongoose/src/sntp.c" #endif /* diff --git a/mongoose.h b/mongoose.h index b6905447066df169808f307cf54f858664926606..64676ba4318ccaca123ebd998b87e30b80930a6b 100644 --- a/mongoose.h +++ b/mongoose.h @@ -3157,10 +3157,6 @@ struct { \ (CS_PLATFORM == CS_P_WINDOWS || CS_PLATFORM == CS_P_UNIX) #endif -#ifndef MG_ENABLE_TUN -#define MG_ENABLE_TUN MG_ENABLE_HTTP_WEBSOCKET -#endif - #ifndef MG_ENABLE_SNTP #define MG_ENABLE_SNTP 0 #endif @@ -3519,12 +3515,11 @@ struct mg_connection { #define MG_F_IS_WEBSOCKET (1 << 8) /* Websocket specific */ /* Flags that are settable by user */ -#define MG_F_SEND_AND_CLOSE (1 << 10) /* Push remaining data and close */ -#define MG_F_CLOSE_IMMEDIATELY (1 << 11) /* Disconnect */ -#define MG_F_WEBSOCKET_NO_DEFRAG (1 << 12) /* Websocket specific */ -#define MG_F_DELETE_CHUNK (1 << 13) /* HTTP specific */ -#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_SEND_AND_CLOSE (1 << 10) /* Push remaining data and close */ +#define MG_F_CLOSE_IMMEDIATELY (1 << 11) /* Disconnect */ +#define MG_F_WEBSOCKET_NO_DEFRAG (1 << 12) /* Websocket specific */ +#define MG_F_DELETE_CHUNK (1 << 13) /* HTTP specific */ +#define MG_F_ENABLE_BROADCAST (1 << 14) /* Allow broadcast address usage */ #define MG_F_USER_1 (1 << 20) /* Flags left for application */ #define MG_F_USER_2 (1 << 21) diff --git a/src/features.h b/src/features.h index a0bd14de0e005086301279c3a45db44494ba166e..515242d276ab67c30c71510891eae966419182d4 100644 --- a/src/features.h +++ b/src/features.h @@ -153,10 +153,6 @@ (CS_PLATFORM == CS_P_WINDOWS || CS_PLATFORM == CS_P_UNIX) #endif -#ifndef MG_ENABLE_TUN -#define MG_ENABLE_TUN MG_ENABLE_HTTP_WEBSOCKET -#endif - #ifndef MG_ENABLE_SNTP #define MG_ENABLE_SNTP 0 #endif diff --git a/src/modules.mk b/src/modules.mk index f68f4adbef9f742f70a1b82be98ebf1e5ae03ffb..93c3539d46cddd6a66cad354b78ea6c618b37096 100644 --- a/src/modules.mk +++ b/src/modules.mk @@ -59,15 +59,12 @@ SOURCES = $(COMMON)/mg_mem.h \ $(COMMON)/mbuf.c \ $(COMMON)/mg_str.c \ $(COMMON)/str_util.c \ - tun.h \ net.c \ net_if_socket.h \ - net_if_tun.h \ net_if_socks.h \ net_if.c \ net_if_socket.c \ net_if_socks.c \ - net_if_tun.c \ ssl_if_openssl.c \ ssl_if_mbedtls.c \ uri.c \ @@ -83,7 +80,6 @@ SOURCES = $(COMMON)/mg_mem.h \ dns_server.c \ resolv.c \ coap.c \ - tun.c \ sntp.c \ socks.c \ $(COMMON)/platforms/cc3200/cc3200_libc.c \ diff --git a/src/net.c b/src/net.c index efd6d6204f3697ef76032be94d46f5eff2dd0b51..e7496b72f30581d011684c5a9c1cda31534d438d 100644 --- a/src/net.c +++ b/src/net.c @@ -20,7 +20,6 @@ #include "mongoose/src/dns.h" #include "mongoose/src/internal.h" #include "mongoose/src/resolv.h" -#include "mongoose/src/tun.h" #include "mongoose/src/util.h" #define MG_MAX_HOST_LEN 200 @@ -816,13 +815,6 @@ struct mg_connection *mg_bind_opt(struct mg_mgr *mgr, const char *address, MG_COPY_COMMON_CONNECTION_OPTIONS(&add_sock_opts, &opts); -#if MG_ENABLE_TUN - if (mg_strncmp(mg_mk_str(address), mg_mk_str("ws://"), 5) == 0 || - mg_strncmp(mg_mk_str(address), mg_mk_str("wss://"), 6) == 0) { - return mg_tun_bind_opt(mgr, address, MG_CB(callback, user_data), opts); - } -#endif - if (mg_parse_address(address, &sa, &proto, host, sizeof(host)) <= 0) { MG_SET_PTRPTR(opts.error_string, "cannot parse address"); return NULL; diff --git a/src/net.h b/src/net.h index dab38eeb8fbd861bd77fe4c3e59dbe82bfa4cebd..1ecb869c30174efdbec4f692615e0f4b66bd8cf2 100644 --- a/src/net.h +++ b/src/net.h @@ -141,12 +141,11 @@ struct mg_connection { #define MG_F_IS_WEBSOCKET (1 << 8) /* Websocket specific */ /* Flags that are settable by user */ -#define MG_F_SEND_AND_CLOSE (1 << 10) /* Push remaining data and close */ -#define MG_F_CLOSE_IMMEDIATELY (1 << 11) /* Disconnect */ -#define MG_F_WEBSOCKET_NO_DEFRAG (1 << 12) /* Websocket specific */ -#define MG_F_DELETE_CHUNK (1 << 13) /* HTTP specific */ -#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_SEND_AND_CLOSE (1 << 10) /* Push remaining data and close */ +#define MG_F_CLOSE_IMMEDIATELY (1 << 11) /* Disconnect */ +#define MG_F_WEBSOCKET_NO_DEFRAG (1 << 12) /* Websocket specific */ +#define MG_F_DELETE_CHUNK (1 << 13) /* HTTP specific */ +#define MG_F_ENABLE_BROADCAST (1 << 14) /* Allow broadcast address usage */ #define MG_F_USER_1 (1 << 20) /* Flags left for application */ #define MG_F_USER_2 (1 << 21) diff --git a/src/net_if.c b/src/net_if.c index 1c979666b87962f50239cdb6a8696618735d7b7b..fee459949efe1519e102f24bdbd2e0caec911c3a 100644 --- a/src/net_if.c +++ b/src/net_if.c @@ -1,15 +1,11 @@ #include "mongoose/src/net_if.h" #include "mongoose/src/internal.h" #include "mongoose/src/net_if_socket.h" -#include "mongoose/src/net_if_tun.h" extern const struct mg_iface_vtable mg_default_iface_vtable; const struct mg_iface_vtable *mg_ifaces[] = { &mg_default_iface_vtable, -#if MG_ENABLE_TUN - &mg_tun_iface_vtable, -#endif }; int mg_num_ifaces = (int) (sizeof(mg_ifaces) / sizeof(mg_ifaces[0])); diff --git a/src/net_if_tun.c b/src/net_if_tun.c deleted file mode 100644 index 9785eb8503a38bda49dc0a808d88b19d4eb33b0f..0000000000000000000000000000000000000000 --- a/src/net_if_tun.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2014-2016 Cesanta Software Limited - * All rights reserved - */ - -#if MG_ENABLE_TUN - -#include "common/cs_dbg.h" -#include "common/cs_time.h" -#include "mongoose/src/internal.h" -#include "mongoose/src/net_if_tun.h" -#include "mongoose/src/tun.h" -#include "mongoose/src/util.h" - -#define MG_TCP_RECV_BUFFER_SIZE 1024 -#define MG_UDP_RECV_BUFFER_SIZE 1500 - -void mg_tun_if_connect_tcp(struct mg_connection *nc, - const union socket_address *sa) { - (void) nc; - (void) sa; -} - -void mg_tun_if_connect_udp(struct mg_connection *nc) { - (void) nc; -} - -int mg_tun_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) { - (void) nc; - (void) sa; - return 0; -} - -int mg_tun_if_listen_udp(struct mg_connection *nc, union socket_address *sa) { - (void) nc; - (void) sa; - return -1; -} - -void mg_tun_if_tcp_send(struct mg_connection *nc, const void *buf, size_t len) { - struct mg_tun_client *client = (struct mg_tun_client *) nc->iface->data; - uint32_t stream_id = (uint32_t)(uintptr_t) nc->mgr_data; - struct mg_str msg = {(char *) buf, len}; -#if MG_ENABLE_HEXDUMP - char hex[512]; - mg_hexdump(buf, len, hex, sizeof(hex)); - LOG(LL_DEBUG, ("sending to stream 0x%x:\n%s", (unsigned int) stream_id, hex)); -#endif - - mg_tun_send_frame(client->disp, stream_id, MG_TUN_DATA_FRAME, 0, msg); -} - -void mg_tun_if_udp_send(struct mg_connection *nc, const void *buf, size_t len) { - (void) nc; - (void) buf; - (void) len; -} - -void mg_tun_if_recved(struct mg_connection *nc, size_t len) { - (void) nc; - (void) len; -} - -int mg_tun_if_create_conn(struct mg_connection *nc) { - (void) nc; - return 1; -} - -void mg_tun_if_destroy_conn(struct mg_connection *nc) { - struct mg_tun_client *client = (struct mg_tun_client *) nc->iface->data; - - if (nc->flags & MG_F_LISTENING) { - mg_tun_destroy_client(client); - } else if (client->disp) { - uint32_t stream_id = (uint32_t)(uintptr_t) nc->mgr_data; - struct mg_str msg = {NULL, 0}; - - LOG(LL_DEBUG, ("closing 0x%x:", (unsigned int) stream_id)); - mg_tun_send_frame(client->disp, stream_id, MG_TUN_DATA_FRAME, - MG_TUN_F_END_STREAM, msg); - } -} - -/* Associate a socket to a connection. */ -void mg_tun_if_sock_set(struct mg_connection *nc, sock_t sock) { - (void) nc; - (void) sock; -} - -void mg_tun_if_init(struct mg_iface *iface) { - (void) iface; -} - -void mg_tun_if_free(struct mg_iface *iface) { - (void) iface; -} - -void mg_tun_if_add_conn(struct mg_connection *nc) { - nc->sock = INVALID_SOCKET; -} - -void mg_tun_if_remove_conn(struct mg_connection *nc) { - (void) nc; -} - -time_t mg_tun_if_poll(struct mg_iface *iface, int timeout_ms) { - (void) iface; - (void) timeout_ms; - return (time_t) cs_time(); -} - -void mg_tun_if_get_conn_addr(struct mg_connection *nc, int remote, - union socket_address *sa) { - (void) nc; - (void) remote; - (void) sa; -} - -struct mg_connection *mg_tun_if_find_conn(struct mg_tun_client *client, - uint32_t stream_id) { - struct mg_connection *nc = NULL; - - for (nc = client->mgr->active_connections; nc != NULL; nc = nc->next) { - if (nc->iface != client->iface || (nc->flags & MG_F_LISTENING)) { - continue; - } - if (stream_id == (uint32_t)(uintptr_t) nc->mgr_data) { - return nc; - } - } - - if (stream_id > client->last_stream_id) { - /* create a new connection */ - LOG(LL_DEBUG, ("new stream 0x%x, accepting", (unsigned int) stream_id)); - nc = mg_if_accept_new_conn(client->listener); - nc->mgr_data = (void *) (uintptr_t) stream_id; - client->last_stream_id = stream_id; - } else { - LOG(LL_DEBUG, - ("Ignoring stream 0x%x (last_stream_id 0x%x)", (unsigned int) stream_id, - (unsigned int) client->last_stream_id)); - } - - return nc; -} - -/* clang-format off */ -#define MG_TUN_IFACE_VTABLE \ - { \ - mg_tun_if_init, \ - mg_tun_if_free, \ - mg_tun_if_add_conn, \ - mg_tun_if_remove_conn, \ - mg_tun_if_poll, \ - mg_tun_if_listen_tcp, \ - mg_tun_if_listen_udp, \ - mg_tun_if_connect_tcp, \ - mg_tun_if_connect_udp, \ - mg_tun_if_tcp_send, \ - mg_tun_if_udp_send, \ - mg_tun_if_recved, \ - mg_tun_if_create_conn, \ - mg_tun_if_destroy_conn, \ - mg_tun_if_sock_set, \ - mg_tun_if_get_conn_addr, \ - } -/* clang-format on */ - -const struct mg_iface_vtable mg_tun_iface_vtable = MG_TUN_IFACE_VTABLE; - -#endif /* MG_ENABLE_TUN */ diff --git a/src/net_if_tun.h b/src/net_if_tun.h deleted file mode 100644 index f9830cc0569939efa01d92d10ec4046cd56c8eea..0000000000000000000000000000000000000000 --- a/src/net_if_tun.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2014-2016 Cesanta Software Limited - * All rights reserved - */ - -#ifndef CS_MONGOOSE_SRC_NET_IF_TUN_H_ -#define CS_MONGOOSE_SRC_NET_IF_TUN_H_ - -#if MG_ENABLE_TUN - -#include "mongoose/src/net_if.h" - -struct mg_tun_client; - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -extern const struct mg_iface_vtable mg_tun_iface_vtable; - -struct mg_connection *mg_tun_if_find_conn(struct mg_tun_client *client, - uint32_t stream_id); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* MG_ENABLE_TUN */ - -#endif /* CS_MONGOOSE_SRC_NET_IF_TUN_H_ */ diff --git a/src/tun.c b/src/tun.c deleted file mode 100644 index da52ce765f45223d9c43cb3137b45dc60f2ad441..0000000000000000000000000000000000000000 --- a/src/tun.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright (c) 2014 Cesanta Software Limited - * All rights reserved - */ - -#if MG_ENABLE_TUN - -#include "common/cs_dbg.h" -#include "mongoose/src/http.h" -#include "mongoose/src/internal.h" -#include "mongoose/src/net.h" -#include "mongoose/src/net_if_tun.h" -#include "mongoose/src/tun.h" -#include "mongoose/src/util.h" - -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, - struct mg_iface *iface, const char *dispatcher, - struct mg_tun_ssl_opts ssl) { - client->mgr = mgr; - client->iface = iface; - client->disp_url = dispatcher; - client->last_stream_id = 0; - client->ssl = ssl; - - client->disp = NULL; /* will be set by mg_tun_reconnect */ - 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) { - LOG(LL_DEBUG, ("Got TUN frame: type=0x%x, flags=0x%x stream_id=0x%x, " - "len=%d", - frame->type, frame->flags, (unsigned int) frame->stream_id, - (int) frame->body.len)); -#if MG_ENABLE_HEXDUMP - { - char hex[512]; - mg_hexdump(frame->body.p, frame->body.len, hex, sizeof(hex) - 1); - hex[sizeof(hex) - 1] = '\0'; - LOG(LL_DEBUG, ("body:\n%s", hex)); - } -#else - LOG(LL_DEBUG, ("body: '%.*s'", (int) frame->body.len, frame->body.p)); -#endif -} - -static void mg_tun_close_all(struct mg_tun_client *client) { - struct mg_connection *nc; - for (nc = client->mgr->active_connections; nc != NULL; nc = nc->next) { - if (nc->iface == client->iface && !(nc->flags & MG_F_LISTENING)) { - LOG(LL_DEBUG, ("Closing tunneled connection %p", nc)); - nc->flags |= MG_F_CLOSE_IMMEDIATELY; - /* mg_close_conn(nc); */ - } - } -} - -static void mg_tun_client_handler(struct mg_connection *nc, int ev, - void *ev_data MG_UD_ARG(void *user_data)) { -#if !MG_ENABLE_CALLBACK_USERDATA - void *user_data = nc->user_data; -#else - (void) nc; -#endif - struct mg_tun_client *client = (struct mg_tun_client *) user_data; - - switch (ev) { - case MG_EV_CONNECT: { - int err = *(int *) ev_data; - - if (err) { - LOG(LL_ERROR, ("Cannot connect to the tunnel dispatcher: %d", err)); - } else { - LOG(LL_INFO, ("Connected to the tunnel dispatcher")); - } - break; - } - case MG_EV_HTTP_REPLY: { - struct http_message *hm = (struct http_message *) ev_data; - - if (hm->resp_code != 200) { - LOG(LL_ERROR, - ("Tunnel dispatcher reply non-OK status code %d", hm->resp_code)); - } - break; - } - case MG_EV_WEBSOCKET_HANDSHAKE_DONE: { - LOG(LL_INFO, ("Tunnel dispatcher handshake done")); - break; - } - case MG_EV_WEBSOCKET_FRAME: { - struct websocket_message *wm = (struct websocket_message *) ev_data; - struct mg_connection *tc; - struct mg_tun_frame frame; - - if (mg_tun_parse_frame(wm->data, wm->size, &frame) == -1) { - LOG(LL_ERROR, ("Got invalid tun frame dropping")); - break; - } - - mg_tun_log_frame(&frame); - - tc = mg_tun_if_find_conn(client, frame.stream_id); - if (tc == NULL) { - if (frame.body.len > 0) { - LOG(LL_DEBUG, ("Got frame after receiving end has been closed")); - } - break; - } - if (frame.body.len > 0) { - mg_if_recv_tcp_cb(tc, (void *) frame.body.p, frame.body.len, - 0 /* own */); - } - if (frame.flags & MG_TUN_F_END_STREAM) { - LOG(LL_DEBUG, ("Closing tunneled connection because got end of stream " - "from other end")); - tc->flags |= MG_F_CLOSE_IMMEDIATELY; - mg_close_conn(tc); - } - break; - } - case MG_EV_CLOSE: { - LOG(LL_DEBUG, ("Closing all tunneled connections")); - /* - * The client might have been already freed when the listening socket is - * closed. - */ - if (client != NULL) { - mg_tun_close_all(client); - client->disp = NULL; - LOG(LL_INFO, ("Dispatcher connection is no more, reconnecting")); - /* TODO(mkm): implement exp back off */ - mg_tun_reconnect(client, MG_TUN_RECONNECT_INTERVAL); - } - break; - } - default: - break; - } -} - -static void mg_tun_do_reconnect(struct mg_tun_client *client) { - struct mg_connection *dc; - struct mg_connect_opts opts; - memset(&opts, 0, sizeof(opts)); -#if MG_ENABLE_SSL - opts.ssl_cert = client->ssl.ssl_cert; - opts.ssl_key = client->ssl.ssl_key; - opts.ssl_ca_cert = client->ssl.ssl_ca_cert; -#endif - /* HTTP/Websocket listener */ - if ((dc = mg_connect_ws_opt(client->mgr, MG_CB(mg_tun_client_handler, client), - opts, client->disp_url, MG_TUN_PROTO_NAME, - NULL)) == NULL) { - LOG(LL_ERROR, - ("Cannot connect to WS server on addr [%s]\n", client->disp_url)); - return; - } - - client->disp = dc; -#if !MG_ENABLE_CALLBACK_USERDATA - dc->user_data = client; -#endif -} - -void mg_tun_reconnect_ev_handler(struct mg_connection *nc, int ev, - void *ev_data MG_UD_ARG(void *user_data)) { -#if !MG_ENABLE_CALLBACK_USERDATA - void *user_data = nc->user_data; -#else - (void) nc; -#endif - struct mg_tun_client *client = (struct mg_tun_client *) user_data; - (void) ev_data; - - switch (ev) { - case MG_EV_TIMER: - if (!(client->listener->flags & MG_F_TUN_DO_NOT_RECONNECT)) { - mg_tun_do_reconnect(client); - } else { - /* Reconnecting is suppressed, we'll check again at the next poll */ - mg_tun_reconnect(client, 0); - } - break; - } -} - -static void mg_tun_reconnect(struct mg_tun_client *client, int timeout) { - if (client->reconnect == NULL) { - client->reconnect = mg_add_sock(client->mgr, INVALID_SOCKET, - MG_CB(mg_tun_reconnect_ev_handler, client)); -#if !MG_ENABLE_CALLBACK_USERDATA - client->reconnect->user_data = client; -#endif - } - client->reconnect->ev_timer_time = mg_time() + timeout; -} - -static struct mg_tun_client *mg_tun_create_client(struct mg_mgr *mgr, - const char *dispatcher, - struct mg_tun_ssl_opts ssl) { - struct mg_tun_client *client = NULL; - struct mg_iface *iface = mg_find_iface(mgr, &mg_tun_iface_vtable, NULL); - if (iface == NULL) { - LOG(LL_ERROR, ("The tun feature requires the manager to have a tun " - "interface enabled")); - return NULL; - } - - client = (struct mg_tun_client *) MG_MALLOC(sizeof(*client)); - mg_tun_init_client(client, mgr, iface, dispatcher, ssl); - iface->data = 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; -} - -void mg_tun_destroy_client(struct mg_tun_client *client) { - /* - * NOTE: - * `client` is NULL in case of OOM - * `client->disp` is NULL if connection failed - * `client->iface is NULL is `mg_find_iface` failed - */ - - if (client != NULL && client->disp != NULL) { - /* the dispatcher connection handler will in turn close all tunnels */ - client->disp->flags |= MG_F_CLOSE_IMMEDIATELY; - /* this is used as a signal to other tun handlers that the party is over */ - client->disp->user_data = NULL; - } - - if (client != NULL && client->reconnect != NULL) { - client->reconnect->flags |= MG_F_CLOSE_IMMEDIATELY; - } - - if (client != NULL && client->iface != NULL) { - client->iface->data = NULL; - } - - MG_FREE(client); -} - -static struct mg_connection *mg_tun_do_bind(struct mg_tun_client *client, - MG_CB(mg_event_handler_t handler, - void *user_data), - struct mg_bind_opts opts) { - struct mg_connection *lc; - opts.iface = client->iface; - lc = mg_bind_opt(client->mgr, ":1234" /* dummy port */, - MG_CB(handler, user_data), opts); - client->listener = lc; - return lc; -} - -struct mg_connection *mg_tun_bind_opt(struct mg_mgr *mgr, - const char *dispatcher, - MG_CB(mg_event_handler_t handler, - void *user_data), - struct mg_bind_opts opts) { -#if MG_ENABLE_SSL - struct mg_tun_ssl_opts ssl = {opts.ssl_cert, opts.ssl_key, opts.ssl_ca_cert}; -#else - struct mg_tun_ssl_opts ssl = {0}; -#endif - struct mg_tun_client *client = mg_tun_create_client(mgr, dispatcher, ssl); - if (client == NULL) { - return NULL; - } -#if MG_ENABLE_SSL - /* these options don't make sense in the local mouth of the tunnel */ - opts.ssl_cert = NULL; - opts.ssl_key = NULL; - opts.ssl_ca_cert = NULL; -#endif - return mg_tun_do_bind(client, MG_CB(handler, user_data), opts); -} - -int mg_tun_parse_frame(void *data, size_t len, struct mg_tun_frame *frame) { - const size_t header_size = sizeof(uint32_t) + sizeof(uint8_t) * 2; - if (len < header_size) { - return -1; - } - - frame->type = *(uint8_t *) (data); - frame->flags = *(uint8_t *) ((char *) data + 1); - memcpy(&frame->stream_id, (char *) data + 2, sizeof(uint32_t)); - frame->stream_id = ntohl(frame->stream_id); - frame->body.p = (char *) data + header_size; - frame->body.len = len - header_size; - return 0; -} - -void mg_tun_send_frame(struct mg_connection *ws, uint32_t stream_id, - uint8_t type, uint8_t flags, struct mg_str msg) { - stream_id = htonl(stream_id); - { - struct mg_str parts[] = { - {(char *) &type, sizeof(type)}, - {(char *) &flags, sizeof(flags)}, - {(char *) &stream_id, sizeof(stream_id)}, - {msg.p, msg.len} /* vc6 doesn't like just `msg` here */}; - mg_send_websocket_framev(ws, WEBSOCKET_OP_BINARY, parts, - sizeof(parts) / sizeof(parts[0])); - } -} - -#endif /* MG_ENABLE_TUN */ diff --git a/src/tun.h b/src/tun.h deleted file mode 100644 index d305b0b3a6169f8112f4dccea0aeca0a845f7eb4..0000000000000000000000000000000000000000 --- a/src/tun.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2014-2016 Cesanta Software Limited - * All rights reserved - */ - -#ifndef CS_MONGOOSE_SRC_TUN_H_ -#define CS_MONGOOSE_SRC_TUN_H_ - -#if MG_ENABLE_TUN - -#include "mongoose/src/net.h" -#include "common/mg_str.h" - -#ifndef MG_TUN_RECONNECT_INTERVAL -#define MG_TUN_RECONNECT_INTERVAL 1 -#endif - -#define MG_TUN_PROTO_NAME "mg_tun" - -#define MG_TUN_DATA_FRAME 0x0 -#define MG_TUN_F_END_STREAM 0x1 - -/* - * MG TUN frame format is loosely based on HTTP/2. - * However since the communication happens via WebSocket - * there is no need to encode the frame length, since that's - * solved by WebSocket framing. - * - * TODO(mkm): Detailed description of the protocol. - */ -struct mg_tun_frame { - uint8_t type; - uint8_t flags; - uint32_t stream_id; /* opaque stream identifier */ - struct mg_str body; -}; - -struct mg_tun_ssl_opts { -#if MG_ENABLE_SSL - const char *ssl_cert; - const char *ssl_key; - const char *ssl_ca_cert; -#else - int dummy; /* some compilers don't like empty structs */ -#endif -}; - -struct mg_tun_client { - struct mg_mgr *mgr; - struct mg_iface *iface; - const char *disp_url; - struct mg_tun_ssl_opts ssl; - - uint32_t last_stream_id; /* stream id of most recently accepted connection */ - - struct mg_connection *disp; - struct mg_connection *listener; - struct mg_connection *reconnect; -}; - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -struct mg_connection *mg_tun_bind_opt(struct mg_mgr *mgr, - const char *dispatcher, - MG_CB(mg_event_handler_t handler, - void *user_data), - struct mg_bind_opts opts); - -int mg_tun_parse_frame(void *data, size_t len, struct mg_tun_frame *frame); - -void mg_tun_send_frame(struct mg_connection *ws, uint32_t stream_id, - uint8_t type, uint8_t flags, struct mg_str msg); - -void mg_tun_destroy_client(struct mg_tun_client *client); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* MG_ENABLE_TUN */ - -#endif /* CS_MONGOOSE_SRC_TUN_H_ */ diff --git a/test/Makefile b/test/Makefile index 96f463e290210b9d926e993ba46bb351d70f1bb4..ecdc5ec989d3dbc3bfdcdb39b9fd2c7fe68296d2 100644 --- a/test/Makefile +++ b/test/Makefile @@ -3,7 +3,7 @@ PROG = unit_test REPO_ROOT ?= ../../ SRC_DIR = ../src -TEST_SOURCES = unit_test.c $(REPO_ROOT)/common/test_util.c $(REPO_ROOT)/tuna/dispatcher.c +TEST_SOURCES = unit_test.c $(REPO_ROOT)/common/test_util.c AMALGAMATED_SOURCES = ../mongoose.c KRYPTON_PATH = $(REPO_ROOT)/krypton # or Krypton, or mbedTLS diff --git a/test/unit_test.c b/test/unit_test.c index 084afa18d6f2e044843eb285939ed49018b4835b..9fdd7b77682c9fbcc56f2b961abc2771a22e12ea 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -20,7 +20,6 @@ #include "unit_test.h" #include "common/test_util.h" #include "common/cs_md5.h" -#include "tuna/dispatcher.h" #if defined(_MSC_VER) && _MSC_VER >= 1900 #include <crtdbg.h> @@ -3816,44 +3815,6 @@ void tunnel_client_test_handler(struct mg_connection *nc, int ev, } } -/* - * NOTE(mkm): this test requires compiling the unit_test.c file with - * //tuna/dispatcher.c . - * Windows test runner doesn't use a makefile that's checked in - * and I can't shave this yak now. - * This doesn't mean the tunnel is not supposed to work on windows; there - * is no fundamental reason it shouldn't, but obviously we should shave - * the yak and make it testable there as well. - */ -#ifndef _WIN32 -static const char *test_tunnel(void) { - struct mg_connection *client, *server; - struct mg_mgr mgr; - int sentinel = 0; - mg_mgr_init(&mgr, NULL); - - mg_tund_bind(&mgr, "localhost:4321"); - - server = mg_bind(&mgr, "ws://localhost:4321", tunnel_server_test_handler); - mg_set_protocol_http_websocket(server); - /* - * Connection happens only at the next poll (because we need to give the app - * a chance to set MG_F_TUN_DO_NOT_RECONNECT), so let's poll once - */ - mg_mgr_poll(&mgr, 1); - mg_mgr_poll(&mgr, 1); - client = mg_connect_http(&mgr, tunnel_client_test_handler, - "http://localhost:4321/foo", NULL, NULL); - client->user_data = (void *) &sentinel; - - poll_until(&mgr, 1, c_int_eq, &sentinel, (void *) 1); - ASSERT_EQ(sentinel, 1); - - mg_mgr_free(&mgr); - return NULL; -} -#endif - static const char *test_http_chunk(void) { struct mg_connection nc; init_test_connection(&nc); @@ -5544,9 +5505,6 @@ static const char *run_tests(const char *filter, double *total_elapsed) { RUN_TEST(test_hexdump_file); RUN_TEST(test_basic_auth_helpers); RUN_TEST(test_http_auth); -#ifndef _WIN32 - RUN_TEST(test_tunnel); -#endif #if MG_ENABLE_SSL RUN_TEST(test_ssl); #ifdef OPENSSL_VERSION_NUMBER