Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
mongoose
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
esp
mongoose
Commits
e1a9ad7f
Commit
e1a9ad7f
authored
Nov 10, 2016
by
Marko Mikulicic
Committed by
Cesanta Bot
Nov 10, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Overload `mg_bind` to bind to tunnel
PUBLISHED_FROM=f554cc63dfea12455fe5e428c6ce5f3152774f8e
parent
296affc6
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
135 additions
and
118 deletions
+135
-118
struct_mg_bind_opts.md
docs/c-api/net.h/struct_mg_bind_opts.md
+5
-2
tun.c
examples/tun/tun.c
+2
-9
mongoose.c
mongoose.c
+123
-33
mongoose.h
mongoose.h
+5
-74
No files found.
docs/c-api/net.h/struct_mg_bind_opts.md
View file @
e1a9ad7f
...
@@ -10,11 +10,14 @@ signature: |
...
@@ -10,11 +10,14 @@ signature: |
struct mg_iface *iface; /* Interface instance */
struct mg_iface *iface; /* Interface instance */
#if MG_ENABLE_SSL
#if MG_ENABLE_SSL
/* SSL settings. */
/* 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.
const char *ssl_key; /* Private key corresponding to the certificate.
If ssl_cert is set but ssl_key is not, ssl_cert
If ssl_cert is set but ssl_key is not, ssl_cert
is used. */
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
#endif
};
};
---
---
...
...
examples/tun/tun.c
View file @
e1a9ad7f
#include "mongoose.h"
#include "mongoose.h"
static
const
char
*
s_local_port
=
":8001"
;
static
const
char
*
s_local_port
=
":8001"
;
static
const
char
*
s_dispatcher
=
"ws://localhost:8000"
;
static
const
char
*
s_dispatcher
=
"ws://foo:bar@localhost:8000"
;
static
const
char
*
s_user
=
"foo"
;
static
const
char
*
s_pass
=
"bar"
;
void
ev_handler
(
struct
mg_connection
*
nc
,
int
ev
,
void
*
ev_data
)
{
void
ev_handler
(
struct
mg_connection
*
nc
,
int
ev
,
void
*
ev_data
)
{
struct
http_message
*
hm
=
(
struct
http_message
*
)
ev_data
;
struct
http_message
*
hm
=
(
struct
http_message
*
)
ev_data
;
...
@@ -41,15 +39,10 @@ int main(int argc, char **argv) {
...
@@ -41,15 +39,10 @@ int main(int argc, char **argv) {
s_local_port
=
argv
[
++
i
];
s_local_port
=
argv
[
++
i
];
}
else
if
(
strcmp
(
argv
[
i
],
"-d"
)
==
0
)
{
}
else
if
(
strcmp
(
argv
[
i
],
"-d"
)
==
0
)
{
s_dispatcher
=
argv
[
++
i
];
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
))
==
if
((
nc
=
mg_bind
(
&
mgr
,
s_dispatcher
,
ev_handler
))
==
NULL
)
{
NULL
)
{
fprintf
(
stderr
,
"Cannot create tunneled listening socket on [%s]
\n
"
,
fprintf
(
stderr
,
"Cannot create tunneled listening socket on [%s]
\n
"
,
s_dispatcher
);
s_dispatcher
);
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
...
...
mongoose.c
View file @
e1a9ad7f
...
@@ -1796,6 +1796,87 @@ int64_t cs_to64(const char *s) {
...
@@ -1796,6 +1796,87 @@ int64_t cs_to64(const char *s) {
#endif
/* EXCLUDE_COMMON */
#endif
/* EXCLUDE_COMMON */
#ifdef MG_MODULE_LINES
#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"
#line 1 "mongoose/src/net.c"
#endif
#endif
/*
/*
...
@@ -1821,6 +1902,7 @@ int64_t cs_to64(const char *s) {
...
@@ -1821,6 +1902,7 @@ int64_t cs_to64(const char *s) {
/* Amalgamated: #include "mongoose/src/internal.h" */
/* Amalgamated: #include "mongoose/src/internal.h" */
/* Amalgamated: #include "mongoose/src/resolv.h" */
/* Amalgamated: #include "mongoose/src/resolv.h" */
/* Amalgamated: #include "mongoose/src/util.h" */
/* Amalgamated: #include "mongoose/src/util.h" */
/* Amalgamated: #include "mongoose/src/tun.h" */
#define MG_MAX_HOST_LEN 200
#define MG_MAX_HOST_LEN 200
...
@@ -2797,6 +2879,13 @@ struct mg_connection *mg_bind_opt(struct mg_mgr *mgr, const char *address,
...
@@ -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
);
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
)
{
if
(
mg_parse_address
(
address
,
&
sa
,
&
proto
,
host
,
sizeof
(
host
))
<=
0
)
{
MG_SET_PTRPTR
(
opts
.
error_string
,
"cannot parse address"
);
MG_SET_PTRPTR
(
opts
.
error_string
,
"cannot parse address"
);
return
NULL
;
return
NULL
;
...
@@ -10676,13 +10765,12 @@ static void mg_tun_reconnect(struct mg_tun_client *client);
...
@@ -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
,
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
,
const
char
*
user
,
const
char
*
pass
)
{
struct
mg_tun_ssl_opts
ssl
)
{
client
->
mgr
=
mgr
;
client
->
mgr
=
mgr
;
client
->
iface
=
iface
;
client
->
iface
=
iface
;
client
->
disp_url
=
dispatcher
;
client
->
disp_url
=
dispatcher
;
client
->
user
=
user
;
client
->
pass
=
pass
;
client
->
last_stream_id
=
0
;
client
->
last_stream_id
=
0
;
client
->
ssl
=
ssl
;
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 */
...
@@ -10787,24 +10875,23 @@ static void mg_tun_client_handler(struct mg_connection *nc, int ev,
...
@@ -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
)
{
static
void
mg_tun_do_reconnect
(
struct
mg_tun_client
*
client
)
{
struct
mg_connection
*
dc
;
struct
mg_connection
*
dc
;
struct
mbuf
headers
;
struct
mg_connect_opts
opts
;
mbuf_init
(
&
headers
,
0
);
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 */
/* HTTP/Websocket listener */
mg_basic_auth_header
(
client
->
user
,
client
->
pass
,
&
headers
);
if
((
dc
=
mg_connect_ws_opt
(
client
->
mgr
,
mg_tun_client_handler
,
opts
,
mbuf_append
(
&
headers
,
""
,
1
);
/* nul terminate */
client
->
disp_url
,
"mg_tun"
,
NULL
))
==
NULL
)
{
if
((
dc
=
mg_connect_ws
(
client
->
mgr
,
mg_tun_client_handler
,
client
->
disp_url
,
"mg_tun"
,
headers
.
buf
))
==
NULL
)
{
LOG
(
LL_ERROR
,
LOG
(
LL_ERROR
,
(
"Cannot connect to WS server on addr [%s]
\n
"
,
client
->
disp_url
));
(
"Cannot connect to WS server on addr [%s]
\n
"
,
client
->
disp_url
));
goto
clea
n
;
retur
n
;
}
}
client
->
disp
=
dc
;
client
->
disp
=
dc
;
dc
->
user_data
=
client
;
dc
->
user_data
=
client
;
clean:
mbuf_free
(
&
headers
);
}
}
void
mg_tun_reconnect_ev_handler
(
struct
mg_connection
*
nc
,
int
ev
,
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) {
...
@@ -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
,
static
struct
mg_tun_client
*
mg_tun_create_client
(
struct
mg_mgr
*
mgr
,
const
char
*
dispatcher
,
const
char
*
dispatcher
,
const
char
*
user
,
struct
mg_tun_ssl_opts
ssl
)
{
const
char
*
pass
)
{
struct
mg_tun_client
*
client
=
NULL
;
struct
mg_tun_client
*
client
=
NULL
;
struct
mg_iface
*
iface
=
mg_find_iface
(
mgr
,
&
mg_tun_iface_vtable
,
NULL
);
struct
mg_iface
*
iface
=
mg_find_iface
(
mgr
,
&
mg_tun_iface_vtable
,
NULL
);
if
(
iface
==
NULL
)
{
if
(
iface
==
NULL
)
{
...
@@ -10840,39 +10926,43 @@ static struct mg_tun_client *mg_tun_create_client(struct mg_mgr *mgr,
...
@@ -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
));
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
;
iface
->
data
=
client
;
mg_tun_do_reconnect
(
client
);
mg_tun_do_reconnect
(
client
);
return
client
;
return
client
;
}
}
static
struct
mg_connection
*
mg_tuna_do_bind
(
struct
mg_tun_client
*
client
,
static
struct
mg_connection
*
mg_tun_do_bind
(
struct
mg_tun_client
*
client
,
mg_event_handler_t
handler
)
{
mg_event_handler_t
handler
,
struct
mg_bind_opts
opts
)
{
struct
mg_connection
*
lc
;
struct
mg_connection
*
lc
;
struct
mg_bind_opts
opts
;
const
char
*
err
;
memset
(
&
opts
,
0
,
sizeof
(
opts
));
opts
.
iface
=
client
->
iface
;
opts
.
iface
=
client
->
iface
;
opts
.
error_string
=
&
err
;
lc
=
mg_bind_opt
(
client
->
mgr
,
":1234"
/* dummy port */
,
handler
,
opts
);
lc
=
mg_bind_opt
(
client
->
mgr
,
":1234"
/* dummy port */
,
handler
,
opts
);
if
(
lc
==
NULL
)
{
LOG
(
LL_ERROR
,
(
"Cannot bind: %s"
,
err
));
}
client
->
listener
=
lc
;
client
->
listener
=
lc
;
return
lc
;
return
lc
;
}
}
struct
mg_connection
*
mg_tuna_bind
(
struct
mg_mgr
*
mgr
,
struct
mg_connection
*
mg_tun_bind_opt
(
struct
mg_mgr
*
mgr
,
mg_event_handler_t
handler
,
const
char
*
dispatcher
,
const
char
*
dispatcher
,
const
char
*
user
,
mg_event_handler_t
handler
,
const
char
*
pass
)
{
struct
mg_bind_opts
opts
)
{
struct
mg_tun_client
*
client
=
#if MG_ENABLE_SSL
mg_tun_create_client
(
mgr
,
dispatcher
,
user
,
pass
);
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
)
{
if
(
client
==
NULL
)
{
return
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
)
{
int
mg_tun_parse_frame
(
void
*
data
,
size_t
len
,
struct
mg_tun_frame
*
frame
)
{
...
...
mongoose.h
View file @
e1a9ad7f
...
@@ -3221,11 +3221,14 @@ struct mg_bind_opts {
...
@@ -3221,11 +3221,14 @@ struct mg_bind_opts {
struct
mg_iface
*
iface
;
/* Interface instance */
struct
mg_iface
*
iface
;
/* Interface instance */
#if MG_ENABLE_SSL
#if MG_ENABLE_SSL
/* SSL settings. */
/* 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.
const
char
*
ssl_key
;
/* Private key corresponding to the certificate.
If ssl_cert is set but ssl_key is not, ssl_cert
If ssl_cert is set but ssl_key is not, ssl_cert
is used. */
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
#endif
};
};
...
@@ -5540,75 +5543,3 @@ uint32_t mg_coap_compose(struct mg_coap_message *cm, struct mbuf *io);
...
@@ -5540,75 +5543,3 @@ uint32_t mg_coap_compose(struct mg_coap_message *cm, struct mbuf *io);
#endif
/* MG_ENABLE_COAP */
#endif
/* MG_ENABLE_COAP */
#endif
/* CS_MONGOOSE_SRC_COAP_H_ */
#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_ */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment