Make captive portal work on Linux

This commit is contained in:
Sergey Lyubka 2021-11-23 17:52:54 +00:00
parent 7a707cc64b
commit 922e1ce529
3 changed files with 11 additions and 6 deletions

View File

@ -21,9 +21,12 @@ uint8_t answer[] = {
};
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
if (ev == MG_EV_READ) {
if (ev == MG_EV_OPEN) {
c->is_hexdumping = 1;
} else if (ev == MG_EV_READ) {
struct mg_dns_rr rr; // Parse first question, offset 12 is header size
size_t n = mg_dns_parse_rr(c->recv.buf, c->recv.len, 12, true, &rr);
LOG(LL_INFO, ("DNS request parsed, result=%d", (int) n));
if (n > 0) {
char buf[512];
struct mg_dns_header *h = (struct mg_dns_header *) buf;
@ -34,7 +37,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
h->flags = mg_htons(0x8400); // Authoritative response
memcpy(buf + sizeof(*h), c->recv.buf + sizeof(*h), n); // Copy question
memcpy(buf + sizeof(*h) + n, answer, sizeof(answer)); // And answer
mg_send(c, buf, sizeof(buf)); // And send it!
mg_send(c, buf, 12 + n + sizeof(answer)); // And send it!
}
mg_iobuf_del(&c->recv, 0, c->recv.len);
}

View File

@ -2943,9 +2943,9 @@ static struct mg_connection *alloc_conn(struct mg_mgr *mgr, bool is_client,
static long mg_sock_send(struct mg_connection *c, const void *buf, size_t len) {
long n;
#if defined(_WIN32)
#if !defined(__APPLE__)
// See #1338, #1382. On Windows, UDP send() can fail despite connected.
// Use sendto() instead. But not UNIX: e.g. on Mac we'll get EISCONN
// Use sendto() instead. But not on Mac - we'll get EISCONN
if (c->is_udp) {
union usa usa;
socklen_t slen = tousa(&c->peer, &usa);
@ -2955,6 +2955,7 @@ static long mg_sock_send(struct mg_connection *c, const void *buf, size_t len) {
{
n = send(FD(c), (char *) buf, len, MSG_NONBLOCKING);
}
LOG(LL_INFO, ("%ld %d %s", n, errno, strerror(errno)));
return n == 0 ? -1 : n < 0 && mg_sock_would_block() ? 0 : n;
}

View File

@ -101,9 +101,9 @@ static struct mg_connection *alloc_conn(struct mg_mgr *mgr, bool is_client,
static long mg_sock_send(struct mg_connection *c, const void *buf, size_t len) {
long n;
#if defined(_WIN32)
#if !defined(__APPLE__)
// See #1338, #1382. On Windows, UDP send() can fail despite connected.
// Use sendto() instead. But not UNIX: e.g. on Mac we'll get EISCONN
// Use sendto() instead. But not on Mac - we'll get EISCONN
if (c->is_udp) {
union usa usa;
socklen_t slen = tousa(&c->peer, &usa);
@ -113,6 +113,7 @@ static long mg_sock_send(struct mg_connection *c, const void *buf, size_t len) {
{
n = send(FD(c), (char *) buf, len, MSG_NONBLOCKING);
}
LOG(LL_INFO, ("%ld %d %s", n, errno, strerror(errno)));
return n == 0 ? -1 : n < 0 && mg_sock_would_block() ? 0 : n;
}