mirror of
https://github.com/cesanta/mongoose.git
synced 2024-12-27 06:51:04 +08:00
Fix #1888: add %I *printf specifier for IP address. Remove mg_ntoa, mg_straddr
This commit is contained in:
parent
89fb3a3d6e
commit
b01989f041
@ -687,27 +687,6 @@ Usage example:
|
||||
mg_printf(c, "Hello, %s!", "world"); // Add "Hello, world!" to output buffer
|
||||
```
|
||||
|
||||
### mg\_straddr
|
||||
|
||||
```c
|
||||
char *mg_straddr(struct mg_addr *addr, char *buf, size_t len);
|
||||
```
|
||||
|
||||
Write stringified IP address, associated with given connection to `buf` (maximum size `len`)
|
||||
|
||||
Parameters:
|
||||
- `addr` - A address pointer
|
||||
- `buf` - A pointer to a buffer that will hold stringified address
|
||||
- `len` - A buffer size
|
||||
|
||||
Return value: `buf` value
|
||||
|
||||
Usage example:
|
||||
|
||||
```c
|
||||
char buf[100];
|
||||
LOG(LL_INFO, ("%s", mg_straddr(&c->peer, buf, sizeof(buf))));
|
||||
```
|
||||
|
||||
### mg\_wrapfd()
|
||||
|
||||
@ -2610,6 +2589,7 @@ Supported format specifiers:
|
||||
- `q` - expect `char *`, outputs JSON-escaped string (extension)
|
||||
- `Q` - expect `char *`, outputs double-quoted JSON-escaped string (extension)
|
||||
- `H` - expect `int`, `void *`, outputs double-quoted hex string (extension)
|
||||
- `I` - expect `int` (4 or 6), `void *`, outputs IP address (extension)
|
||||
- `V` - expect `int`, `void *`, outputs double-quoted base64 string (extension)
|
||||
- `M` - expect `mg_pfn_t`, calls another print function (extension)
|
||||
- `g`, `f` - expect `double`
|
||||
@ -2638,6 +2618,7 @@ mg_snprintf(buf, sizeof(buf), "%05x", 123); // 00123
|
||||
mg_snprintf(buf, sizeof(buf), "%%-%3s", "a"); // %- a
|
||||
mg_snprintf(buf, sizeof(buf), "hi, %Q", "a"); // hi, "a"
|
||||
mg_snprintf(buf, sizeof(buf), "r: %M, %d", f,1,2,7); // r: 3, 7
|
||||
mg_snprintf(buf, sizeof(buf), "%I", 4, "abcd"); // 97.98.99.100
|
||||
|
||||
// Printing sub-function for %M specifier. Grabs two int parameters
|
||||
size_t f(void (*out)(char, void *), void *ptr, va_list *ap) {
|
||||
@ -2754,28 +2735,6 @@ if (mg_aton(mg_str("127.0.0.1"), &addr)) {
|
||||
}
|
||||
```
|
||||
|
||||
### mg\_ntoa()
|
||||
|
||||
```c
|
||||
char *mg_ntoa(const struct mg_addr *addr, char *buf, size_t len);
|
||||
```
|
||||
|
||||
Stringify IP address `ipaddr` into a buffer `buf`, `len`
|
||||
|
||||
Parameters:
|
||||
- `addr` - Address to stringify
|
||||
- `buf` - Pointer to output buffer
|
||||
- `len` - Output buffer size
|
||||
|
||||
Return value: `buf` value
|
||||
|
||||
Usage example:
|
||||
|
||||
```c
|
||||
char buf[100];
|
||||
mg_ntoa(&c->peer, buf, sizeof(buf));
|
||||
```
|
||||
|
||||
## JSON
|
||||
|
||||
Note that Mongoose's printing functions support non-standard format specifiers `%Q` and `%M`,
|
||||
|
@ -35,14 +35,12 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
mg_printf(c, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
|
||||
mg_http_printf_chunk(c, "ID PROTO TYPE LOCAL REMOTE\n");
|
||||
for (struct mg_connection *t = c->mgr->conns; t != NULL; t = t->next) {
|
||||
char loc[40], rem[40];
|
||||
mg_http_printf_chunk(c, "%-3lu %4s %s %-15s %s\n", t->id,
|
||||
mg_http_printf_chunk(c, "%-3lu %4s %s %I %I\n", t->id,
|
||||
t->is_udp ? "UDP" : "TCP",
|
||||
t->is_listening ? "LISTENING"
|
||||
: t->is_accepted ? "ACCEPTED "
|
||||
: "CONNECTED",
|
||||
mg_straddr(&t->loc, loc, sizeof(loc)),
|
||||
mg_straddr(&t->rem, rem, sizeof(rem)));
|
||||
4, &t->loc.ip, 4, &t->rem.ip);
|
||||
}
|
||||
mg_http_printf_chunk(c, ""); // Don't forget the last empty chunk
|
||||
} else if (mg_http_match_uri(hm, "/api/f2/*")) {
|
||||
|
@ -42,6 +42,42 @@ static size_t pcap_rx(void *buf, size_t len, void *userdata) {
|
||||
return received;
|
||||
}
|
||||
|
||||
static void fn2(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
if (ev == MG_EV_HTTP_MSG) {
|
||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||
MG_DEBUG(("Got response (%d) %.*s...", (int) hm->message.len, 12,
|
||||
hm->message.ptr));
|
||||
c->is_closing = 1;
|
||||
} else if (ev == MG_EV_CONNECT) {
|
||||
mg_printf(c, "GET %s HTTP/1.1\r\n\r\n", mg_url_uri((char *) fn_data));
|
||||
} else if (ev == MG_EV_CLOSE) {
|
||||
free(fn_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
if (ev == MG_EV_HTTP_MSG) {
|
||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||
if (mg_http_match_uri(hm, "/api/debug")) {
|
||||
int level = mg_json_get_long(hm->body, "$.level", MG_LL_DEBUG);
|
||||
mg_log_set(level);
|
||||
mg_http_reply(c, 200, "", "Debug level set to %d\n", level);
|
||||
} else if (mg_http_match_uri(hm, "/api/url")) {
|
||||
char *url = mg_json_get_str(hm->body, "$.url");
|
||||
if (url == NULL) {
|
||||
mg_http_reply(c, 200, NULL, "no url, rl %d\r\n", (int) c->recv.len);
|
||||
} else {
|
||||
mg_http_connect(c->mgr, url, fn2, url);
|
||||
mg_http_reply(c, 200, NULL, "ok\r\n");
|
||||
}
|
||||
} else {
|
||||
mg_http_reply(c, 200, NULL, "%.*s\r\n", (int) hm->message.len,
|
||||
hm->message.ptr);
|
||||
}
|
||||
}
|
||||
(void) ev_data, (void) fn_data;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
const char *iface = "lo0"; // Network iface
|
||||
const char *mac = "02:00:01:02:03:77"; // MAC address
|
||||
@ -92,8 +128,9 @@ int main(int argc, char *argv[]) {
|
||||
signal(SIGINT, signal_handler);
|
||||
signal(SIGTERM, signal_handler);
|
||||
|
||||
struct mg_mgr mgr; // Event manager
|
||||
mg_mgr_init(&mgr); // Initialise event manager
|
||||
struct mg_mgr mgr; // Event manager
|
||||
mg_mgr_init(&mgr); // Initialise event manager
|
||||
mg_log_set(MG_LL_DEBUG); // Set log level
|
||||
|
||||
struct mip_driver driver = {.tx = pcap_tx, .up = pcap_up, .rx = pcap_rx};
|
||||
struct mip_if mif = {.use_dhcp = true, .driver = &driver, .driver_data = ph};
|
||||
@ -102,8 +139,9 @@ int main(int argc, char *argv[]) {
|
||||
mip_init(&mgr, &mif);
|
||||
MG_INFO(("Init done, starting main loop"));
|
||||
|
||||
extern void device_dashboard_fn(struct mg_connection *, int, void *, void *);
|
||||
mg_http_listen(&mgr, "http://0.0.0.0:8000", device_dashboard_fn, &mgr);
|
||||
// extern void device_dashboard_fn(struct mg_connection *, int, void *, void
|
||||
// *);
|
||||
mg_http_listen(&mgr, "http://0.0.0.0:8000", fn, &mgr);
|
||||
|
||||
while (s_signo == 0) mg_mgr_poll(&mgr, 100); // Infinite event loop
|
||||
|
||||
|
@ -24,14 +24,12 @@ static void wcb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
mg_printf(c, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
|
||||
mg_http_printf_chunk(c, "ID PROTO TYPE LOCAL REMOTE\n");
|
||||
for (struct mg_connection *t = c->mgr->conns; t != NULL; t = t->next) {
|
||||
char loc[40], rem[40];
|
||||
mg_http_printf_chunk(c, "%-3lu %4s %s %-15s %s\n", t->id,
|
||||
mg_http_printf_chunk(c, "%-3lu %4s %s %I %I\n", t->id,
|
||||
t->is_udp ? "UDP" : "TCP",
|
||||
t->is_listening ? "LISTENING"
|
||||
: t->is_accepted ? "ACCEPTED "
|
||||
: "CONNECTED",
|
||||
mg_straddr(&t->loc, loc, sizeof(loc)),
|
||||
mg_straddr(&t->rem, rem, sizeof(rem)));
|
||||
4, &t->loc.ip, 4, &t->rem.ip);
|
||||
}
|
||||
mg_http_printf_chunk(c, ""); // Don't forget the last empty chunk
|
||||
} else {
|
||||
|
66
mongoose.c
66
mongoose.c
@ -271,11 +271,11 @@ static void dns_cb(struct mg_connection *c, int ev, void *ev_data,
|
||||
if (dm.txnid != d->txnid) continue;
|
||||
if (d->c->is_resolving) {
|
||||
if (dm.resolved) {
|
||||
char buf[100];
|
||||
dm.addr.port = d->c->rem.port; // Save port
|
||||
d->c->rem = dm.addr; // Copy resolved address
|
||||
MG_DEBUG(("%lu %s is %s", d->c->id, dm.name,
|
||||
mg_ntoa(&d->c->rem, buf, sizeof(buf))));
|
||||
MG_DEBUG(
|
||||
("%lu %s is %I", d->c->id, dm.name, d->c->rem.is_ip6 ? 16 : 4,
|
||||
d->c->rem.is_ip6 ? &d->c->rem.ip6 : (void *) &d->c->rem.ip));
|
||||
mg_connect_resolved(d->c);
|
||||
#if MG_ENABLE_IPV6
|
||||
} else if (dm.addr.is_ip6 == false && dm.name[0] != '\0' &&
|
||||
@ -351,7 +351,6 @@ static void mg_sendnsreq(struct mg_connection *c, struct mg_str *name, int ms,
|
||||
mg_error(c, "resolve OOM");
|
||||
} else {
|
||||
struct dns_data *reqs = (struct dns_data *) c->mgr->active_dns_requests;
|
||||
char buf[100];
|
||||
d->txnid = reqs ? (uint16_t) (reqs->txnid + 1) : 1;
|
||||
d->next = (struct dns_data *) c->mgr->active_dns_requests;
|
||||
c->mgr->active_dns_requests = d;
|
||||
@ -359,7 +358,7 @@ static void mg_sendnsreq(struct mg_connection *c, struct mg_str *name, int ms,
|
||||
d->c = c;
|
||||
c->is_resolving = 1;
|
||||
MG_VERBOSE(("%lu resolving %.*s @ %s, txnid %hu", c->id, (int) name->len,
|
||||
name->ptr, mg_ntoa(&dnsc->c->rem, buf, sizeof(buf)), d->txnid));
|
||||
name->ptr, &dnsc->url, d->txnid));
|
||||
if (!mg_dns_send(dnsc->c, name, d->txnid, ipv6)) {
|
||||
mg_error(dnsc->c, "DNS send");
|
||||
}
|
||||
@ -412,6 +411,7 @@ void mg_error(struct mg_connection *c, const char *fmt, ...) {
|
||||
|
||||
|
||||
|
||||
|
||||
static void mg_pfn_iobuf_private(char ch, void *param, bool expand) {
|
||||
struct mg_iobuf *io = (struct mg_iobuf *) param;
|
||||
if (expand && io->len + 2 > io->size) mg_iobuf_resize(io, io->len + 2);
|
||||
@ -720,6 +720,20 @@ size_t mg_vxprintf(void (*out)(char, void *), void *param, const char *fmt,
|
||||
n += scpy(out, param, (char *) &hex[p[j] & 15], 1);
|
||||
}
|
||||
n += scpy(out, param, (char *) &dquote, 1);
|
||||
} else if (c == 'I') {
|
||||
// Print IPv4 or IPv6 address
|
||||
size_t len = (size_t) va_arg(*ap, int); // Length 16 means IPv6 address
|
||||
uint8_t *buf = va_arg(*ap, uint8_t *); // Pointer to the IP address
|
||||
if (len == 6) {
|
||||
uint16_t *p = (uint16_t *) buf;
|
||||
n += mg_xprintf(out, param, "%x:%x:%x:%x:%x:%x:%x:%x", mg_htons(p[0]),
|
||||
mg_htons(p[1]), mg_htons(p[2]), mg_htons(p[3]),
|
||||
mg_htons(p[4]), mg_htons(p[5]), mg_htons(p[6]),
|
||||
mg_htons(p[7]));
|
||||
} else {
|
||||
n += mg_xprintf(out, param, "%d.%d.%d.%d", (int) buf[0], (int) buf[1],
|
||||
(int) buf[2], (int) buf[3]);
|
||||
}
|
||||
} else if (c == 'V') {
|
||||
// Print base64-encoded double-quoted string
|
||||
size_t len = (size_t) va_arg(*ap, int);
|
||||
@ -3313,29 +3327,6 @@ size_t mg_printf(struct mg_connection *c, const char *fmt, ...) {
|
||||
return len;
|
||||
}
|
||||
|
||||
char *mg_straddr(struct mg_addr *a, char *buf, size_t len) {
|
||||
char tmp[40];
|
||||
const char *fmt = a->is_ip6 ? "[%s]:%d" : "%s:%d";
|
||||
mg_ntoa(a, tmp, sizeof(tmp));
|
||||
mg_snprintf(buf, len, fmt, tmp, (int) mg_ntohs(a->port));
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *mg_ntoa(const struct mg_addr *addr, char *buf, size_t len) {
|
||||
if (addr->is_ip6) {
|
||||
uint16_t *p = (uint16_t *) addr->ip6;
|
||||
mg_snprintf(buf, len, "%x:%x:%x:%x:%x:%x:%x:%x", mg_htons(p[0]),
|
||||
mg_htons(p[1]), mg_htons(p[2]), mg_htons(p[3]), mg_htons(p[4]),
|
||||
mg_htons(p[5]), mg_htons(p[6]), mg_htons(p[7]));
|
||||
} else {
|
||||
uint8_t p[4];
|
||||
memcpy(p, &addr->ip, sizeof(p));
|
||||
mg_snprintf(buf, len, "%d.%d.%d.%d", (int) p[0], (int) p[1], (int) p[2],
|
||||
(int) p[3]);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
static bool mg_atonl(struct mg_str str, struct mg_addr *addr) {
|
||||
if (mg_vcasecmp(&str, "localhost") != 0) return false;
|
||||
addr->ip = mg_htonl(0x7f000001);
|
||||
@ -4063,16 +4054,10 @@ static void iolog(struct mg_connection *c, char *buf, long n, bool r) {
|
||||
} else if (n > 0) {
|
||||
if (c->is_hexdumping) {
|
||||
union usa usa;
|
||||
char t1[50], t2[50];
|
||||
socklen_t slen = sizeof(usa.sin);
|
||||
struct mg_addr a;
|
||||
memset(&usa, 0, sizeof(usa));
|
||||
memset(&a, 0, sizeof(a));
|
||||
if (getsockname(FD(c), &usa.sa, &slen) < 0) (void) 0; // Ignore result
|
||||
tomgaddr(&usa, &a, c->rem.is_ip6);
|
||||
MG_INFO(("\n-- %lu %s %s %s %s %ld", c->id,
|
||||
mg_straddr(&a, t1, sizeof(t1)), r ? "<-" : "->",
|
||||
mg_straddr(&c->rem, t2, sizeof(t2)), c->label, n));
|
||||
MG_INFO(("\n-- %lu %I %s %I %s %ld", c->id, 4, &usa.sin.sin_addr,
|
||||
r ? "<-" : "->", 4, &c->rem.ip, c->label, n));
|
||||
|
||||
mg_hexdump(buf, (size_t) n);
|
||||
}
|
||||
@ -4327,7 +4312,7 @@ void mg_connect_resolved(struct mg_connection *c) {
|
||||
if ((rc = connect(FD(c), &usa.sa, slen)) == 0) {
|
||||
mg_call(c, MG_EV_CONNECT, NULL);
|
||||
} else if (mg_sock_would_block()) {
|
||||
MG_DEBUG(("%lu %p -> %x:%hu pend", c->id, c->fd, mg_ntohl(c->rem.ip),
|
||||
MG_DEBUG(("%lu %p -> %I:%hu pend", c->id, c->fd, 4, &c->rem.ip,
|
||||
mg_ntohs(c->rem.port)));
|
||||
c->is_connecting = 1;
|
||||
} else {
|
||||
@ -4370,9 +4355,7 @@ static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
|
||||
MG_ERROR(("%lu OOM", lsn->id));
|
||||
closesocket(fd);
|
||||
} else {
|
||||
// char buf[40];
|
||||
tomgaddr(&usa, &c->rem, sa_len != sizeof(usa.sin));
|
||||
// mg_straddr(&c->rem, buf, sizeof(buf));
|
||||
LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
|
||||
c->fd = S2PTR(fd);
|
||||
MG_EPOLL_ADD(c);
|
||||
@ -4385,9 +4368,8 @@ static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
|
||||
c->pfn_data = lsn->pfn_data;
|
||||
c->fn = lsn->fn;
|
||||
c->fn_data = lsn->fn_data;
|
||||
MG_DEBUG(("%lu %p accepted %x.%hu -> %x.%hu", c->id, c->fd,
|
||||
mg_ntohl(c->rem.ip), mg_ntohs(c->rem.port), mg_ntohl(c->loc.ip),
|
||||
mg_ntohs(c->loc.port)));
|
||||
MG_DEBUG(("%lu %p accepted %I.%hu -> %I.%hu", c->id, c->fd, 4, &c->rem.ip,
|
||||
mg_ntohs(c->rem.port), 4, &c->loc.ip, mg_ntohs(c->loc.port)));
|
||||
mg_call(c, MG_EV_OPEN, NULL);
|
||||
mg_call(c, MG_EV_ACCEPT, NULL);
|
||||
}
|
||||
|
@ -1088,9 +1088,7 @@ void mg_connect_resolved(struct mg_connection *);
|
||||
bool mg_send(struct mg_connection *, const void *, size_t);
|
||||
size_t mg_printf(struct mg_connection *, const char *fmt, ...);
|
||||
size_t mg_vprintf(struct mg_connection *, const char *fmt, va_list *ap);
|
||||
char *mg_straddr(struct mg_addr *, char *, size_t);
|
||||
bool mg_aton(struct mg_str str, struct mg_addr *addr);
|
||||
char *mg_ntoa(const struct mg_addr *addr, char *buf, size_t len);
|
||||
int mg_mkpipe(struct mg_mgr *, mg_event_handler_t, void *, bool udp);
|
||||
|
||||
// These functions are used to integrate with custom network stacks
|
||||
|
@ -159,11 +159,11 @@ static void dns_cb(struct mg_connection *c, int ev, void *ev_data,
|
||||
if (dm.txnid != d->txnid) continue;
|
||||
if (d->c->is_resolving) {
|
||||
if (dm.resolved) {
|
||||
char buf[100];
|
||||
dm.addr.port = d->c->rem.port; // Save port
|
||||
d->c->rem = dm.addr; // Copy resolved address
|
||||
MG_DEBUG(("%lu %s is %s", d->c->id, dm.name,
|
||||
mg_ntoa(&d->c->rem, buf, sizeof(buf))));
|
||||
MG_DEBUG(
|
||||
("%lu %s is %I", d->c->id, dm.name, d->c->rem.is_ip6 ? 16 : 4,
|
||||
d->c->rem.is_ip6 ? &d->c->rem.ip6 : (void *) &d->c->rem.ip));
|
||||
mg_connect_resolved(d->c);
|
||||
#if MG_ENABLE_IPV6
|
||||
} else if (dm.addr.is_ip6 == false && dm.name[0] != '\0' &&
|
||||
@ -239,7 +239,6 @@ static void mg_sendnsreq(struct mg_connection *c, struct mg_str *name, int ms,
|
||||
mg_error(c, "resolve OOM");
|
||||
} else {
|
||||
struct dns_data *reqs = (struct dns_data *) c->mgr->active_dns_requests;
|
||||
char buf[100];
|
||||
d->txnid = reqs ? (uint16_t) (reqs->txnid + 1) : 1;
|
||||
d->next = (struct dns_data *) c->mgr->active_dns_requests;
|
||||
c->mgr->active_dns_requests = d;
|
||||
@ -247,7 +246,7 @@ static void mg_sendnsreq(struct mg_connection *c, struct mg_str *name, int ms,
|
||||
d->c = c;
|
||||
c->is_resolving = 1;
|
||||
MG_VERBOSE(("%lu resolving %.*s @ %s, txnid %hu", c->id, (int) name->len,
|
||||
name->ptr, mg_ntoa(&dnsc->c->rem, buf, sizeof(buf)), d->txnid));
|
||||
name->ptr, &dnsc->url, d->txnid));
|
||||
if (!mg_dns_send(dnsc->c, name, d->txnid, ipv6)) {
|
||||
mg_error(dnsc->c, "DNS send");
|
||||
}
|
||||
|
15
src/fmt.c
15
src/fmt.c
@ -1,5 +1,6 @@
|
||||
#include "fmt.h"
|
||||
#include "iobuf.h"
|
||||
#include "util.h"
|
||||
|
||||
static void mg_pfn_iobuf_private(char ch, void *param, bool expand) {
|
||||
struct mg_iobuf *io = (struct mg_iobuf *) param;
|
||||
@ -309,6 +310,20 @@ size_t mg_vxprintf(void (*out)(char, void *), void *param, const char *fmt,
|
||||
n += scpy(out, param, (char *) &hex[p[j] & 15], 1);
|
||||
}
|
||||
n += scpy(out, param, (char *) &dquote, 1);
|
||||
} else if (c == 'I') {
|
||||
// Print IPv4 or IPv6 address
|
||||
size_t len = (size_t) va_arg(*ap, int); // Length 16 means IPv6 address
|
||||
uint8_t *buf = va_arg(*ap, uint8_t *); // Pointer to the IP address
|
||||
if (len == 6) {
|
||||
uint16_t *p = (uint16_t *) buf;
|
||||
n += mg_xprintf(out, param, "%x:%x:%x:%x:%x:%x:%x:%x", mg_htons(p[0]),
|
||||
mg_htons(p[1]), mg_htons(p[2]), mg_htons(p[3]),
|
||||
mg_htons(p[4]), mg_htons(p[5]), mg_htons(p[6]),
|
||||
mg_htons(p[7]));
|
||||
} else {
|
||||
n += mg_xprintf(out, param, "%d.%d.%d.%d", (int) buf[0], (int) buf[1],
|
||||
(int) buf[2], (int) buf[3]);
|
||||
}
|
||||
} else if (c == 'V') {
|
||||
// Print base64-encoded double-quoted string
|
||||
size_t len = (size_t) va_arg(*ap, int);
|
||||
|
23
src/net.c
23
src/net.c
@ -20,29 +20,6 @@ size_t mg_printf(struct mg_connection *c, const char *fmt, ...) {
|
||||
return len;
|
||||
}
|
||||
|
||||
char *mg_straddr(struct mg_addr *a, char *buf, size_t len) {
|
||||
char tmp[40];
|
||||
const char *fmt = a->is_ip6 ? "[%s]:%d" : "%s:%d";
|
||||
mg_ntoa(a, tmp, sizeof(tmp));
|
||||
mg_snprintf(buf, len, fmt, tmp, (int) mg_ntohs(a->port));
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *mg_ntoa(const struct mg_addr *addr, char *buf, size_t len) {
|
||||
if (addr->is_ip6) {
|
||||
uint16_t *p = (uint16_t *) addr->ip6;
|
||||
mg_snprintf(buf, len, "%x:%x:%x:%x:%x:%x:%x:%x", mg_htons(p[0]),
|
||||
mg_htons(p[1]), mg_htons(p[2]), mg_htons(p[3]), mg_htons(p[4]),
|
||||
mg_htons(p[5]), mg_htons(p[6]), mg_htons(p[7]));
|
||||
} else {
|
||||
uint8_t p[4];
|
||||
memcpy(p, &addr->ip, sizeof(p));
|
||||
mg_snprintf(buf, len, "%d.%d.%d.%d", (int) p[0], (int) p[1], (int) p[2],
|
||||
(int) p[3]);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
static bool mg_atonl(struct mg_str str, struct mg_addr *addr) {
|
||||
if (mg_vcasecmp(&str, "localhost") != 0) return false;
|
||||
addr->ip = mg_htonl(0x7f000001);
|
||||
|
@ -87,9 +87,7 @@ void mg_connect_resolved(struct mg_connection *);
|
||||
bool mg_send(struct mg_connection *, const void *, size_t);
|
||||
size_t mg_printf(struct mg_connection *, const char *fmt, ...);
|
||||
size_t mg_vprintf(struct mg_connection *, const char *fmt, va_list *ap);
|
||||
char *mg_straddr(struct mg_addr *, char *, size_t);
|
||||
bool mg_aton(struct mg_str str, struct mg_addr *addr);
|
||||
char *mg_ntoa(const struct mg_addr *addr, char *buf, size_t len);
|
||||
int mg_mkpipe(struct mg_mgr *, mg_event_handler_t, void *, bool udp);
|
||||
|
||||
// These functions are used to integrate with custom network stacks
|
||||
|
19
src/sock.c
19
src/sock.c
@ -99,16 +99,10 @@ static void iolog(struct mg_connection *c, char *buf, long n, bool r) {
|
||||
} else if (n > 0) {
|
||||
if (c->is_hexdumping) {
|
||||
union usa usa;
|
||||
char t1[50], t2[50];
|
||||
socklen_t slen = sizeof(usa.sin);
|
||||
struct mg_addr a;
|
||||
memset(&usa, 0, sizeof(usa));
|
||||
memset(&a, 0, sizeof(a));
|
||||
if (getsockname(FD(c), &usa.sa, &slen) < 0) (void) 0; // Ignore result
|
||||
tomgaddr(&usa, &a, c->rem.is_ip6);
|
||||
MG_INFO(("\n-- %lu %s %s %s %s %ld", c->id,
|
||||
mg_straddr(&a, t1, sizeof(t1)), r ? "<-" : "->",
|
||||
mg_straddr(&c->rem, t2, sizeof(t2)), c->label, n));
|
||||
MG_INFO(("\n-- %lu %I %s %I %s %ld", c->id, 4, &usa.sin.sin_addr,
|
||||
r ? "<-" : "->", 4, &c->rem.ip, c->label, n));
|
||||
|
||||
mg_hexdump(buf, (size_t) n);
|
||||
}
|
||||
@ -363,7 +357,7 @@ void mg_connect_resolved(struct mg_connection *c) {
|
||||
if ((rc = connect(FD(c), &usa.sa, slen)) == 0) {
|
||||
mg_call(c, MG_EV_CONNECT, NULL);
|
||||
} else if (mg_sock_would_block()) {
|
||||
MG_DEBUG(("%lu %p -> %x:%hu pend", c->id, c->fd, mg_ntohl(c->rem.ip),
|
||||
MG_DEBUG(("%lu %p -> %I:%hu pend", c->id, c->fd, 4, &c->rem.ip,
|
||||
mg_ntohs(c->rem.port)));
|
||||
c->is_connecting = 1;
|
||||
} else {
|
||||
@ -406,9 +400,7 @@ static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
|
||||
MG_ERROR(("%lu OOM", lsn->id));
|
||||
closesocket(fd);
|
||||
} else {
|
||||
// char buf[40];
|
||||
tomgaddr(&usa, &c->rem, sa_len != sizeof(usa.sin));
|
||||
// mg_straddr(&c->rem, buf, sizeof(buf));
|
||||
LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
|
||||
c->fd = S2PTR(fd);
|
||||
MG_EPOLL_ADD(c);
|
||||
@ -421,9 +413,8 @@ static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
|
||||
c->pfn_data = lsn->pfn_data;
|
||||
c->fn = lsn->fn;
|
||||
c->fn_data = lsn->fn_data;
|
||||
MG_DEBUG(("%lu %p accepted %x.%hu -> %x.%hu", c->id, c->fd,
|
||||
mg_ntohl(c->rem.ip), mg_ntohs(c->rem.port), mg_ntohl(c->loc.ip),
|
||||
mg_ntohs(c->loc.port)));
|
||||
MG_DEBUG(("%lu %p accepted %I.%hu -> %I.%hu", c->id, c->fd, 4, &c->rem.ip,
|
||||
mg_ntohs(c->rem.port), 4, &c->loc.ip, mg_ntohs(c->loc.port)));
|
||||
mg_call(c, MG_EV_OPEN, NULL);
|
||||
mg_call(c, MG_EV_ACCEPT, NULL);
|
||||
}
|
||||
|
@ -1637,6 +1637,15 @@ static void test_str(void) {
|
||||
ASSERT(strcmp(tmp, "01") == 0);
|
||||
ASSERT(tmp[2] == '\0');
|
||||
}
|
||||
|
||||
{
|
||||
char buf[100];
|
||||
struct mg_addr a = {0, mg_htonl(0x10111213), {1, 100, 33}, false};
|
||||
ASSERT(mg_snprintf(buf, sizeof(buf), "%I", 4, &a.ip) == 11);
|
||||
ASSERT(strcmp(buf, "16.17.18.19") == 0);
|
||||
ASSERT(mg_snprintf(buf, sizeof(buf), "%I", 6, &a.ip6) == 20);
|
||||
ASSERT(strcmp(buf, "164:2100:0:0:0:0:0:0") == 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void fn1(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
@ -1729,7 +1738,6 @@ static void test_util(void) {
|
||||
ASSERT(mg_aton(mg_str("127.0.0.1"), &a) == true);
|
||||
ASSERT(a.is_ip6 == false);
|
||||
ASSERT(a.ip == mg_htonl(0x7f000001));
|
||||
ASSERT(strcmp(mg_ntoa(&a, buf, sizeof(buf)), "127.0.0.1") == 0);
|
||||
|
||||
ASSERT(mg_aton(mg_str("1:2:3:4:5:6:7:8"), &a) == true);
|
||||
ASSERT(a.is_ip6 == true);
|
||||
|
Loading…
x
Reference in New Issue
Block a user