mongoose/docs/net.adoc
Marko Mikulicic f443c64341 Temporarily disable appdash from docker-compose
Until I read the doc and find how to limit the retention,
otherwise it just eats all my ram and cpu and things start to fall
apart.

PUBLISHED_FROM=eb33fb44736f07b992270689217aca4af70513ff
2016-05-15 22:07:04 +03:00

500 lines
15 KiB
Plaintext

=== Core: TCP/UDP/SSL
NOTE: Mongoose manager is single threaded. It does not protect
its data structures by mutexes, therefore all functions that are dealing
with particular event manager should be called from the same thread,
with exception of `mg_broadcast()` function. It is fine to have different
event managers handled by different threads.
==== struct mg_str
[source,c]
----
struct mg_str {
const char *p; /* Memory chunk pointer */
size_t len; /* Memory chunk length */
};
----
Describes chunk of memory
==== struct mg_mgr
[source,c]
----
struct mg_mgr {
struct mg_connection *active_connections;
const char *hexdump_file; /* Debug hexdump file path */
#ifndef MG_DISABLE_SOCKETPAIR
sock_t ctl[2]; /* Socketpair for mg_wakeup() */
#endif
void *user_data; /* User data */
void *mgr_data; /* Implementation-specific event manager's data. */
#ifdef MG_ENABLE_JAVASCRIPT
struct v7 *v7;
#endif
};
----
Mongoose event manager.
==== struct mg_connection
[source,c]
----
struct mg_connection {
struct mg_connection *next, *prev; /* mg_mgr::active_connections linkage */
struct mg_connection *listener; /* Set only for accept()-ed connections */
struct mg_mgr *mgr; /* Pointer to containing manager */
sock_t sock; /* Socket to the remote peer */
int err;
union socket_address sa; /* Remote peer address */
size_t recv_mbuf_limit; /* Max size of recv buffer */
struct mbuf recv_mbuf; /* Received data */
struct mbuf send_mbuf; /* Data scheduled for sending */
SSL *ssl;
SSL_CTX *ssl_ctx;
time_t last_io_time; /* Timestamp of the last socket IO */
double ev_timer_time; /* Timestamp of the future MG_EV_TIMER */
mg_event_handler_t proto_handler; /* Protocol-specific event handler */
void *proto_data; /* Protocol-specific data */
void (*proto_data_destructor)(void *proto_data);
mg_event_handler_t handler; /* Event handler function */
void *user_data; /* User-specific data */
union {
void *v;
/*
* the C standard is fussy about fitting function pointers into
* void pointers, since some archs might have fat pointers for functions.
*/
mg_event_handler_t f;
} priv_1; /* Used by mg_enable_multithreading() */
void *priv_2; /* Used by mg_enable_multithreading() */
void *mgr_data; /* Implementation-specific event manager's data. */
unsigned long flags;
/* Flags set by Mongoose */
#define MG_F_LISTENING (1 << 0) /* This connection is listening */
#define MG_F_UDP (1 << 1) /* This connection is UDP */
#define MG_F_RESOLVING (1 << 2) /* Waiting for async resolver */
#define MG_F_CONNECTING (1 << 3) /* connect() call in progress */
#define MG_F_SSL_HANDSHAKE_DONE (1 << 4) /* SSL specific */
#define MG_F_WANT_READ (1 << 5) /* SSL specific */
#define MG_F_WANT_WRITE (1 << 6) /* SSL specific */
#define MG_F_IS_WEBSOCKET (1 << 7) /* 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_USER_1 (1 << 20) /* Flags left for application */
#define MG_F_USER_2 (1 << 21)
#define MG_F_USER_3 (1 << 22)
#define MG_F_USER_4 (1 << 23)
#define MG_F_USER_5 (1 << 24)
#define MG_F_USER_6 (1 << 25)
};
----
Mongoose connection.
==== struct mg_add_sock_opts
[source,c]
----
struct mg_add_sock_opts {
void *user_data; /* Initial value for connection's user_data */
unsigned int flags; /* Initial connection flags */
const char **error_string; /* Placeholder for the error string */
};
----
Optional parameters to `mg_add_sock_opt()`.
`flags` is an initial `struct mg_connection::flags` bitmask to set,
see `MG_F_*` flags definitions.
==== struct mg_bind_opts
[source,c]
----
struct mg_bind_opts {
void *user_data; /* Initial value for connection's user_data */
unsigned int flags; /* Extra connection flags */
const char **error_string; /* Placeholder for the error string */
#ifdef MG_ENABLE_SSL
/* SSL settings. */
const char *ssl_cert; /* Server certificate to present to clients */
const char *ssl_ca_cert; /* Verify client certificates with this CA bundle */
#endif
};
----
Optional parameters to `mg_bind_opt()`.
`flags` is an initial `struct mg_connection::flags` bitmask to set,
see `MG_F_*` flags definitions.
==== struct mg_connect_opts
[source,c]
----
struct mg_connect_opts {
void *user_data; /* Initial value for connection's user_data */
unsigned int flags; /* Extra connection flags */
const char **error_string; /* Placeholder for the error string */
#ifdef MG_ENABLE_SSL
/* SSL settings. */
const char *ssl_cert; /* Client certificate to present to the server */
const char *ssl_ca_cert; /* Verify server certificate using this CA bundle */
/*
* Server name verification. If ssl_ca_cert is set and the certificate has
* passed verification, its subject will be verified against this string.
* By default (if ssl_server_name is NULL) hostname part of the address will
* be used. Wildcard matching is supported. A special value of "*" disables
* name verification.
*/
const char *ssl_server_name;
#endif
};
----
Optional parameters to `mg_connect_opt()`
==== mg_mgr_init()
[source,c]
----
void mg_mgr_init(struct mg_mgr *mgr, void *user_data);
----
Initialize Mongoose manager. Side effect: ignores SIGPIPE signal.
`mgr->user_data` field will be initialized with `user_data` parameter.
That is an arbitrary pointer, where user code can associate some data
with the particular Mongoose manager. For example, a C++ wrapper class
could be written, in which case `user_data` can hold a pointer to the
class instance.
==== mg_mgr_free()
[source,c]
----
void mg_mgr_free(struct mg_mgr *);
----
De-initializes Mongoose manager.
Close and deallocate all active connections.
==== mg_mgr_poll()
[source,c]
----
time_t mg_mgr_poll(struct mg_mgr *, int milli);
----
This function performs the actual IO, and must be called in a loop
(an event loop). Returns the current timestamp.
`milli` is the maximum number of milliseconds to sleep.
`mg_mgr_poll()` checks all connection for IO readiness. If at least one
of the connections is IO-ready, `mg_mgr_poll()` triggers respective
event handlers and returns.
==== mg_broadcast()
[source,c]
----
void mg_broadcast(struct mg_mgr *, mg_event_handler_t func, void *, size_t);
----
Pass a message of a given length to all connections.
Must be called from a thread that does NOT call `mg_mgr_poll()`.
Note that `mg_broadcast()` is the only function
that can be, and must be, called from a different (non-IO) thread.
`func` callback function will be called by the IO thread for each
connection. When called, event would be `MG_EV_POLL`, and message will
be passed as `ev_data` pointer. Maximum message size is capped
by `MG_CTL_MSG_MESSAGE_SIZE` which is set to 8192 bytes.
==== mg_next()
[source,c]
----
struct mg_connection *mg_next(struct mg_mgr *, struct mg_connection *);
----
Iterate over all active connections.
Returns next connection from the list
of active connections, or `NULL` if there is no more connections. Below
is the iteration idiom:
```c
for (c = mg_next(srv, NULL); c != NULL; c = mg_next(srv, c)) {
// Do something with connection `c`
}
```
==== mg_add_sock()
[source,c]
----
struct mg_connection *mg_add_sock(struct mg_mgr *, sock_t, mg_event_handler_t);
----
Create a connection, associate it with the given socket and event handler,
and add it to the manager.
For more options see the `mg_add_sock_opt` variant.
==== mg_add_sock_opt()
[source,c]
----
struct mg_connection *mg_add_sock_opt(struct mg_mgr *, sock_t,
mg_event_handler_t,
struct mg_add_sock_opts);
----
Create a connection, associate it with the given socket and event handler,
and add to the manager.
See the `mg_add_sock_opts` structure for a description of the options.
==== mg_bind()
[source,c]
----
struct mg_connection *mg_bind(struct mg_mgr *, const char *,
mg_event_handler_t);
----
Create listening connection.
See `mg_bind_opt` for full documentation.
==== mg_bind_opt()
[source,c]
----
struct mg_connection *mg_bind_opt(struct mg_mgr *mgr, const char *address,
mg_event_handler_t handler,
struct mg_bind_opts opts);
----
Create listening connection.
`address` parameter tells which address to bind to. It's format is the same
as for the `mg_connect()` call, where `HOST` part is optional. `address`
can be just a port number, e.g. `:8000`. To bind to a specific interface,
an IP address can be specified, e.g. `1.2.3.4:8000`. By default, a TCP
connection is created. To create UDP connection, prepend `udp://` prefix,
e.g. `udp://:8000`. To summarize, `address` paramer has following format:
`[PROTO://][IP_ADDRESS]:PORT`, where `PROTO` could be `tcp` or `udp`.
See the `mg_bind_opts` structure for a description of the optional
parameters.
Return a new listening connection, or `NULL` on error.
NOTE: Connection remains owned by the manager, do not free().
==== mg_connect()
[source,c]
----
struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *address,
mg_event_handler_t handler);
----
Connect to a remote host.
See `mg_connect_opt()` for full documentation.
==== mg_connect_opt()
[source,c]
----
struct mg_connection *mg_connect_opt(struct mg_mgr *mgr, const char *address,
mg_event_handler_t handler,
struct mg_connect_opts opts);
----
Connect to a remote host.
`address` format is `[PROTO://]HOST:PORT`. `PROTO` could be `tcp` or `udp`.
`HOST` could be an IP address,
IPv6 address (if Mongoose is compiled with `-DMG_ENABLE_IPV6`), or a host
name. If `HOST` is a name, Mongoose will resolve it asynchronously. Examples
of valid addresses: `google.com:80`, `udp://1.2.3.4:53`, `10.0.0.1:443`,
`[::1]:80`
See the `mg_connect_opts` structure for a description of the optional
parameters.
Returns a new outbound connection, or `NULL` on error.
NOTE: Connection remains owned by the manager, do not free().
NOTE: To enable IPv6 addresses, `-DMG_ENABLE_IPV6` should be specified
in the compilation flags.
NOTE: New connection will receive `MG_EV_CONNECT` as it's first event
which will report connect success status.
If asynchronous resolution fail, or `connect()` syscall fail for whatever
reason (e.g. with `ECONNREFUSED` or `ENETUNREACH`), then `MG_EV_CONNECT`
event report failure. Code example below:
```c
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
int connect_status;
switch (ev) {
case MG_EV_CONNECT:
connect_status = * (int *) ev_data;
if (connect_status == 0) {
// Success
} else {
// Error
printf("connect() error: %s\n", strerror(connect_status));
}
break;
...
}
}
...
mg_connect(mgr, "my_site.com:80", ev_handler);
```
==== mg_set_ssl()
[source,c]
----
const char *mg_set_ssl(struct mg_connection *nc, const char *cert,
const char *ca_cert);
----
Enable SSL for a given connection.
`cert` is a server certificate file name for a listening connection,
or a client certificate file name for an outgoing connection.
Certificate files must be in PEM format. Server certificate file
must contain a certificate, concatenated with a private key, optionally
concatenated with parameters.
`ca_cert` is a CA certificate, or NULL if peer verification is not
required.
Return: NULL on success, or error message on error.
==== mg_send()
[source,c]
----
void mg_send(struct mg_connection *, const void *buf, int len);
----
Send data to the connection.
Note that sending functions do not actually push data to the socket.
They just append data to the output buffer. MG_EV_SEND will be delivered when
the data has actually been pushed out.
==== mg_printf()
[source,c]
----
int mg_printf(struct mg_connection *, const char *fmt, ...);
----
Send `printf`-style formatted data to the connection.
See `mg_send` for more details on send semantics.
==== mg_vprintf()
[source,c]
----
int mg_vprintf(struct mg_connection *, const char *fmt, va_list ap);
----
Same as `mg_printf()`, but takes `va_list ap` as an argument.
==== mg_socketpair()
[source,c]
----
int mg_socketpair(sock_t[2], int sock_type);
----
Create a socket pair.
`sock_type` can be either `SOCK_STREAM` or `SOCK_DGRAM`.
Return 0 on failure, 1 on success.
==== mg_check_ip_acl()
[source,c]
----
int mg_check_ip_acl(const char *acl, uint32_t remote_ip);
----
Verify given IP address against the ACL.
`remote_ip` - an IPv4 address to check, in host byte order
`acl` - a comma separated list of IP subnets: `x.x.x.x/x` or `x.x.x.x`.
Each subnet is
prepended by either a - or a + sign. A plus sign means allow, where a
minus sign means deny. If a subnet mask is omitted, such as `-1.2.3.4`,
this means to deny only that single IP address.
Subnet masks may vary from 0 to 32, inclusive. The default setting
is to allow all accesses. On each request the full list is traversed,
and the last match wins. Example:
`-0.0.0.0/0,+192.168/16` - deny all acccesses, only allow 192.168/16 subnet
To learn more about subnet masks, see the
link:https://en.wikipedia.org/wiki/Subnetwork[Wikipedia page on Subnetwork]
Return -1 if ACL is malformed, 0 if address is disallowed, 1 if allowed.
==== mg_enable_multithreading()
[source,c]
----
void mg_enable_multithreading(struct mg_connection *nc);
----
Enable multi-threaded handling for the given listening connection `nc`.
For each accepted connection, Mongoose will create a separate thread
and run event handler in that thread. Thus, if an event hanler is doing
a blocking call or some long computation, that will not slow down
other connections.
==== mg_enable_javascript()
[source,c]
----
enum v7_err mg_enable_javascript(struct mg_mgr *m, struct v7 *v7,
const char *init_js_file_name);
----
Enable server-side JavaScript scripting.
Requires `-DMG_ENABLE_JAVASCRIPT` compilation flag, and V7 engine sources.
v7 instance must not be destroyed during manager's lifetime.
Return V7 error.
==== mg_set_timer()
[source,c]
----
double mg_set_timer(struct mg_connection *c, double timestamp);
----
Schedule MG_EV_TIMER event to be delivered at `timestamp` time.
`timestamp` is a UNIX time (a number of seconds since Epoch). It is
`double` instead of `time_t` to allow for sub-second precision.
Return the old timer value.
Example: set connect timeout to 1.5 seconds:
```
c = mg_connect(&mgr, "cesanta.com", ev_handler);
mg_set_timer(c, mg_time() + 1.5);
...
void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
switch (ev) {
case MG_EV_CONNECT:
mg_set_timer(c, 0); // Clear connect timer
break;
case MG_EV_TIMER:
log("Connect timeout");
c->flags |= MG_F_CLOSE_IMMEDIATELY;
break;
```
==== mg_time()
[source,c]
----
double mg_time();
----
A sub-second precision version of time().