mirror of
https://github.com/cesanta/mongoose.git
synced 2024-12-28 15:40:23 +08:00
Overload mg_bind
to bind to tunnel
PUBLISHED_FROM=f554cc63dfea12455fe5e428c6ce5f3152774f8e
This commit is contained in:
parent
296affc6e4
commit
e1a9ad7f82
@ -10,11 +10,14 @@ signature: |
|
||||
struct mg_iface *iface; /* Interface instance */
|
||||
#if MG_ENABLE_SSL
|
||||
/* SSL settings. */
|
||||
const char *ssl_cert; /* Server certificate to present to clients */
|
||||
const char *ssl_cert; /* Server certificate to present to clients
|
||||
* Or client certificate to present to tunnel
|
||||
* dispatcher. */
|
||||
const char *ssl_key; /* Private key corresponding to the certificate.
|
||||
If ssl_cert is set but ssl_key is not, ssl_cert
|
||||
is used. */
|
||||
const char *ssl_ca_cert; /* Verify client certificates with this CA bundle */
|
||||
const char *ssl_ca_cert; /* CA bundle used to verify client certificates or
|
||||
* tunnel dispatchers. */
|
||||
#endif
|
||||
};
|
||||
---
|
||||
|
@ -1,9 +1,7 @@
|
||||
#include "mongoose.h"
|
||||
|
||||
static const char *s_local_port = ":8001";
|
||||
static const char *s_dispatcher = "ws://localhost:8000";
|
||||
static const char *s_user = "foo";
|
||||
static const char *s_pass = "bar";
|
||||
static const char *s_dispatcher = "ws://foo:bar@localhost:8000";
|
||||
|
||||
void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
struct http_message *hm = (struct http_message *) ev_data;
|
||||
@ -41,15 +39,10 @@ int main(int argc, char **argv) {
|
||||
s_local_port = argv[++i];
|
||||
} else if (strcmp(argv[i], "-d") == 0) {
|
||||
s_dispatcher = argv[++i];
|
||||
} else if (strcmp(argv[i], "-u") == 0) {
|
||||
s_user = argv[++i];
|
||||
} else if (strcmp(argv[i], "-p") == 0) {
|
||||
s_pass = argv[++i];
|
||||
}
|
||||
}
|
||||
|
||||
if ((nc = mg_tuna_bind(&mgr, ev_handler, s_dispatcher, s_user, s_pass)) ==
|
||||
NULL) {
|
||||
if ((nc = mg_bind(&mgr, s_dispatcher, ev_handler)) == NULL) {
|
||||
fprintf(stderr, "Cannot create tunneled listening socket on [%s]\n",
|
||||
s_dispatcher);
|
||||
exit(EXIT_FAILURE);
|
||||
|
156
mongoose.c
156
mongoose.c
@ -1796,6 +1796,87 @@ int64_t cs_to64(const char *s) {
|
||||
|
||||
#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_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;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
struct mg_connection *mg_tun_bind_opt(struct mg_mgr *mgr,
|
||||
const char *dispatcher,
|
||||
mg_event_handler_t handler,
|
||||
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);
|
||||
|
||||
#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
|
||||
/*
|
||||
@ -1821,6 +1902,7 @@ int64_t cs_to64(const char *s) {
|
||||
/* Amalgamated: #include "mongoose/src/internal.h" */
|
||||
/* Amalgamated: #include "mongoose/src/resolv.h" */
|
||||
/* Amalgamated: #include "mongoose/src/util.h" */
|
||||
/* Amalgamated: #include "mongoose/src/tun.h" */
|
||||
|
||||
#define MG_MAX_HOST_LEN 200
|
||||
|
||||
@ -2797,6 +2879,13 @@ 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, callback, opts);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mg_parse_address(address, &sa, &proto, host, sizeof(host)) <= 0) {
|
||||
MG_SET_PTRPTR(opts.error_string, "cannot parse address");
|
||||
return NULL;
|
||||
@ -10676,13 +10765,12 @@ static void mg_tun_reconnect(struct mg_tun_client *client);
|
||||
|
||||
static void mg_tun_init_client(struct mg_tun_client *client, struct mg_mgr *mgr,
|
||||
struct mg_iface *iface, const char *dispatcher,
|
||||
const char *user, const char *pass) {
|
||||
struct mg_tun_ssl_opts ssl) {
|
||||
client->mgr = mgr;
|
||||
client->iface = iface;
|
||||
client->disp_url = dispatcher;
|
||||
client->user = user;
|
||||
client->pass = pass;
|
||||
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 */
|
||||
@ -10787,24 +10875,23 @@ static void mg_tun_client_handler(struct mg_connection *nc, int ev,
|
||||
|
||||
static void mg_tun_do_reconnect(struct mg_tun_client *client) {
|
||||
struct mg_connection *dc;
|
||||
struct mbuf headers;
|
||||
mbuf_init(&headers, 0);
|
||||
|
||||
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 */
|
||||
mg_basic_auth_header(client->user, client->pass, &headers);
|
||||
mbuf_append(&headers, "", 1); /* nul terminate */
|
||||
if ((dc = mg_connect_ws(client->mgr, mg_tun_client_handler, client->disp_url,
|
||||
"mg_tun", headers.buf)) == NULL) {
|
||||
if ((dc = mg_connect_ws_opt(client->mgr, mg_tun_client_handler, opts,
|
||||
client->disp_url, "mg_tun", NULL)) == NULL) {
|
||||
LOG(LL_ERROR,
|
||||
("Cannot connect to WS server on addr [%s]\n", client->disp_url));
|
||||
goto clean;
|
||||
return;
|
||||
}
|
||||
|
||||
client->disp = dc;
|
||||
dc->user_data = client;
|
||||
|
||||
clean:
|
||||
mbuf_free(&headers);
|
||||
}
|
||||
|
||||
void mg_tun_reconnect_ev_handler(struct mg_connection *nc, int ev,
|
||||
@ -10829,8 +10916,7 @@ static void mg_tun_reconnect(struct mg_tun_client *client) {
|
||||
|
||||
static struct mg_tun_client *mg_tun_create_client(struct mg_mgr *mgr,
|
||||
const char *dispatcher,
|
||||
const char *user,
|
||||
const char *pass) {
|
||||
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) {
|
||||
@ -10840,39 +10926,43 @@ static struct mg_tun_client *mg_tun_create_client(struct mg_mgr *mgr,
|
||||
}
|
||||
|
||||
client = (struct mg_tun_client *) MG_MALLOC(sizeof(*client));
|
||||
mg_tun_init_client(client, mgr, iface, dispatcher, user, pass);
|
||||
mg_tun_init_client(client, mgr, iface, dispatcher, ssl);
|
||||
iface->data = client;
|
||||
|
||||
mg_tun_do_reconnect(client);
|
||||
return client;
|
||||
}
|
||||
|
||||
static struct mg_connection *mg_tuna_do_bind(struct mg_tun_client *client,
|
||||
mg_event_handler_t handler) {
|
||||
static struct mg_connection *mg_tun_do_bind(struct mg_tun_client *client,
|
||||
mg_event_handler_t handler,
|
||||
struct mg_bind_opts opts) {
|
||||
struct mg_connection *lc;
|
||||
struct mg_bind_opts opts;
|
||||
const char *err;
|
||||
memset(&opts, 0, sizeof(opts));
|
||||
opts.iface = client->iface;
|
||||
opts.error_string = &err;
|
||||
lc = mg_bind_opt(client->mgr, ":1234" /* dummy port */, handler, opts);
|
||||
if (lc == NULL) {
|
||||
LOG(LL_ERROR, ("Cannot bind: %s", err));
|
||||
}
|
||||
client->listener = lc;
|
||||
return lc;
|
||||
}
|
||||
|
||||
struct mg_connection *mg_tuna_bind(struct mg_mgr *mgr,
|
||||
mg_event_handler_t handler,
|
||||
const char *dispatcher, const char *user,
|
||||
const char *pass) {
|
||||
struct mg_tun_client *client =
|
||||
mg_tun_create_client(mgr, dispatcher, user, pass);
|
||||
struct mg_connection *mg_tun_bind_opt(struct mg_mgr *mgr,
|
||||
const char *dispatcher,
|
||||
mg_event_handler_t handler,
|
||||
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;
|
||||
}
|
||||
return mg_tuna_do_bind(client, handler);
|
||||
#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, handler, opts);
|
||||
}
|
||||
|
||||
int mg_tun_parse_frame(void *data, size_t len, struct mg_tun_frame *frame) {
|
||||
|
79
mongoose.h
79
mongoose.h
@ -3221,11 +3221,14 @@ struct mg_bind_opts {
|
||||
struct mg_iface *iface; /* Interface instance */
|
||||
#if MG_ENABLE_SSL
|
||||
/* SSL settings. */
|
||||
const char *ssl_cert; /* Server certificate to present to clients */
|
||||
const char *ssl_cert; /* Server certificate to present to clients
|
||||
* Or client certificate to present to tunnel
|
||||
* dispatcher. */
|
||||
const char *ssl_key; /* Private key corresponding to the certificate.
|
||||
If ssl_cert is set but ssl_key is not, ssl_cert
|
||||
is used. */
|
||||
const char *ssl_ca_cert; /* Verify client certificates with this CA bundle */
|
||||
const char *ssl_ca_cert; /* CA bundle used to verify client certificates or
|
||||
* tunnel dispatchers. */
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -5540,75 +5543,3 @@ uint32_t mg_coap_compose(struct mg_coap_message *cm, struct mbuf *io);
|
||||
#endif /* MG_ENABLE_COAP */
|
||||
|
||||
#endif /* CS_MONGOOSE_SRC_COAP_H_ */
|
||||
#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_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_client {
|
||||
struct mg_mgr *mgr;
|
||||
struct mg_iface *iface;
|
||||
const char *disp_url;
|
||||
const char *user;
|
||||
const char *pass;
|
||||
|
||||
uint32_t last_stream_id; /* stream id of most recently accepted connection */
|
||||
|
||||
struct mg_connection *disp;
|
||||
struct mg_connection *listener;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
struct mg_connection *mg_tuna_bind(struct mg_mgr *mgr,
|
||||
mg_event_handler_t handler,
|
||||
const char *dispatcher, const char *user,
|
||||
const char *pass);
|
||||
|
||||
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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* MG_ENABLE_TUN */
|
||||
|
||||
#endif /* CS_MONGOOSE_SRC_TUN_H_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user