]> gitweb.ps.run Git - chirp/blob - ext/mongoose.c
a76a12713ad1f7386382173fcf8a0a7077132ea3
[chirp] / ext / mongoose.c
1 // Copyright (c) 2004-2013 Sergey Lyubka
2 // Copyright (c) 2013-2022 Cesanta Software Limited
3 // All rights reserved
4 //
5 // This software is dual-licensed: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License version 2 as
7 // published by the Free Software Foundation. For the terms of this
8 // license, see http://www.gnu.org/licenses/
9 //
10 // You are free to use this software under the terms of the GNU General
11 // Public License, but WITHOUT ANY WARRANTY; without even the implied
12 // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 // See the GNU General Public License for more details.
14 //
15 // Alternatively, you can license this software under a commercial
16 // license, as set out in https://www.mongoose.ws/licensing/
17 //
18 // SPDX-License-Identifier: GPL-2.0-only or commercial
19
20 #include "mongoose.h"
21
22 #ifdef MG_ENABLE_LINES
23 #line 1 "src/base64.c"
24 #endif
25
26
27
28 static int mg_b64idx(int c) {
29   if (c < 26) {
30     return c + 'A';
31   } else if (c < 52) {
32     return c - 26 + 'a';
33   } else if (c < 62) {
34     return c - 52 + '0';
35   } else {
36     return c == 62 ? '+' : '/';
37   }
38 }
39
40 static int mg_b64rev(int c) {
41   if (c >= 'A' && c <= 'Z') {
42     return c - 'A';
43   } else if (c >= 'a' && c <= 'z') {
44     return c + 26 - 'a';
45   } else if (c >= '0' && c <= '9') {
46     return c + 52 - '0';
47   } else if (c == '+') {
48     return 62;
49   } else if (c == '/') {
50     return 63;
51   } else if (c == '=') {
52     return 64;
53   } else {
54     return -1;
55   }
56 }
57
58 int mg_base64_update(unsigned char ch, char *to, int n) {
59   int rem = (n & 3) % 3;
60   if (rem == 0) {
61     to[n] = (char) mg_b64idx(ch >> 2);
62     to[++n] = (char) ((ch & 3) << 4);
63   } else if (rem == 1) {
64     to[n] = (char) mg_b64idx(to[n] | (ch >> 4));
65     to[++n] = (char) ((ch & 15) << 2);
66   } else {
67     to[n] = (char) mg_b64idx(to[n] | (ch >> 6));
68     to[++n] = (char) mg_b64idx(ch & 63);
69     n++;
70   }
71   return n;
72 }
73
74 int mg_base64_final(char *to, int n) {
75   int saved = n;
76   // printf("---[%.*s]\n", n, to);
77   if (n & 3) n = mg_base64_update(0, to, n);
78   if ((saved & 3) == 2) n--;
79   // printf("    %d[%.*s]\n", n, n, to);
80   while (n & 3) to[n++] = '=';
81   to[n] = '\0';
82   return n;
83 }
84
85 int mg_base64_encode(const unsigned char *p, int n, char *to) {
86   int i, len = 0;
87   for (i = 0; i < n; i++) len = mg_base64_update(p[i], to, len);
88   len = mg_base64_final(to, len);
89   return len;
90 }
91
92 int mg_base64_decode(const char *src, int n, char *dst) {
93   const char *end = src == NULL ? NULL : src + n;  // Cannot add to NULL
94   int len = 0;
95   while (src != NULL && src + 3 < end) {
96     int a = mg_b64rev(src[0]), b = mg_b64rev(src[1]), c = mg_b64rev(src[2]),
97         d = mg_b64rev(src[3]);
98     if (a == 64 || a < 0 || b == 64 || b < 0 || c < 0 || d < 0) return 0;
99     dst[len++] = (char) ((a << 2) | (b >> 4));
100     if (src[2] != '=') {
101       dst[len++] = (char) ((b << 4) | (c >> 2));
102       if (src[3] != '=') dst[len++] = (char) ((c << 6) | d);
103     }
104     src += 4;
105   }
106   dst[len] = '\0';
107   return len;
108 }
109
110 #ifdef MG_ENABLE_LINES
111 #line 1 "src/dns.c"
112 #endif
113
114
115
116
117
118
119
120
121 struct dns_data {
122   struct dns_data *next;
123   struct mg_connection *c;
124   uint64_t expire;
125   uint16_t txnid;
126 };
127
128 static void mg_sendnsreq(struct mg_connection *, struct mg_str *, int,
129                          struct mg_dns *, bool);
130
131 static void mg_dns_free(struct mg_connection *c, struct dns_data *d) {
132   LIST_DELETE(struct dns_data,
133               (struct dns_data **) &c->mgr->active_dns_requests, d);
134   free(d);
135 }
136
137 void mg_resolve_cancel(struct mg_connection *c) {
138   struct dns_data *tmp, *d = (struct dns_data *) c->mgr->active_dns_requests;
139   for (; d != NULL; d = tmp) {
140     tmp = d->next;
141     if (d->c == c) mg_dns_free(c, d);
142   }
143 }
144
145 static size_t mg_dns_parse_name_depth(const uint8_t *s, size_t len, size_t ofs,
146                                       char *to, size_t tolen, size_t j,
147                                       int depth) {
148   size_t i = 0;
149   if (tolen > 0 && depth == 0) to[0] = '\0';
150   if (depth > 5) return 0;
151   // MG_INFO(("ofs %lx %x %x", (unsigned long) ofs, s[ofs], s[ofs + 1]));
152   while (ofs + i + 1 < len) {
153     size_t n = s[ofs + i];
154     if (n == 0) {
155       i++;
156       break;
157     }
158     if (n & 0xc0) {
159       size_t ptr = (((n & 0x3f) << 8) | s[ofs + i + 1]);  // 12 is hdr len
160       // MG_INFO(("PTR %lx", (unsigned long) ptr));
161       if (ptr + 1 < len && (s[ptr] & 0xc0) == 0 &&
162           mg_dns_parse_name_depth(s, len, ptr, to, tolen, j, depth + 1) == 0)
163         return 0;
164       i += 2;
165       break;
166     }
167     if (ofs + i + n + 1 >= len) return 0;
168     if (j > 0) {
169       if (j < tolen) to[j] = '.';
170       j++;
171     }
172     if (j + n < tolen) memcpy(&to[j], &s[ofs + i + 1], n);
173     j += n;
174     i += n + 1;
175     if (j < tolen) to[j] = '\0';  // Zero-terminate this chunk
176     // MG_INFO(("--> [%s]", to));
177   }
178   if (tolen > 0) to[tolen - 1] = '\0';  // Make sure make sure it is nul-term
179   return i;
180 }
181
182 static size_t mg_dns_parse_name(const uint8_t *s, size_t n, size_t ofs,
183                                 char *dst, size_t dstlen) {
184   return mg_dns_parse_name_depth(s, n, ofs, dst, dstlen, 0, 0);
185 }
186
187 size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
188                        bool is_question, struct mg_dns_rr *rr) {
189   const uint8_t *s = buf + ofs, *e = &buf[len];
190
191   memset(rr, 0, sizeof(*rr));
192   if (len < sizeof(struct mg_dns_header)) return 0;  // Too small
193   if (len > 512) return 0;  //  Too large, we don't expect that
194   if (s >= e) return 0;     //  Overflow
195
196   if ((rr->nlen = (uint16_t) mg_dns_parse_name(buf, len, ofs, NULL, 0)) == 0)
197     return 0;
198   s += rr->nlen + 4;
199   if (s > e) return 0;
200   rr->atype = (uint16_t) (((uint16_t) s[-4] << 8) | s[-3]);
201   rr->aclass = (uint16_t) (((uint16_t) s[-2] << 8) | s[-1]);
202   if (is_question) return (size_t) (rr->nlen + 4);
203
204   s += 6;
205   if (s > e) return 0;
206   rr->alen = (uint16_t) (((uint16_t) s[-2] << 8) | s[-1]);
207   if (s + rr->alen > e) return 0;
208   return (size_t) (rr->nlen + rr->alen + 10);
209 }
210
211 bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *dm) {
212   const struct mg_dns_header *h = (struct mg_dns_header *) buf;
213   struct mg_dns_rr rr;
214   size_t i, n, ofs = sizeof(*h);
215   memset(dm, 0, sizeof(*dm));
216
217   if (len < sizeof(*h)) return 0;                // Too small, headers dont fit
218   if (mg_ntohs(h->num_questions) > 1) return 0;  // Sanity
219   if (mg_ntohs(h->num_answers) > 10) return 0;   // Sanity
220   dm->txnid = mg_ntohs(h->txnid);
221
222   for (i = 0; i < mg_ntohs(h->num_questions); i++) {
223     if ((n = mg_dns_parse_rr(buf, len, ofs, true, &rr)) == 0) return false;
224     // MG_INFO(("Q %lu %lu %hu/%hu", ofs, n, rr.atype, rr.aclass));
225     ofs += n;
226   }
227   for (i = 0; i < mg_ntohs(h->num_answers); i++) {
228     if ((n = mg_dns_parse_rr(buf, len, ofs, false, &rr)) == 0) return false;
229     // MG_INFO(("A -- %lu %lu %hu/%hu %s", ofs, n, rr.atype, rr.aclass,
230     // dm->name));
231     mg_dns_parse_name(buf, len, ofs, dm->name, sizeof(dm->name));
232     ofs += n;
233
234     if (rr.alen == 4 && rr.atype == 1 && rr.aclass == 1) {
235       dm->addr.is_ip6 = false;
236       memcpy(&dm->addr.ip, &buf[ofs - 4], 4);
237       dm->resolved = true;
238       break;  // Return success
239     } else if (rr.alen == 16 && rr.atype == 28 && rr.aclass == 1) {
240       dm->addr.is_ip6 = true;
241       memcpy(&dm->addr.ip, &buf[ofs - 16], 16);
242       dm->resolved = true;
243       break;  // Return success
244     }
245   }
246   return true;
247 }
248
249 static void dns_cb(struct mg_connection *c, int ev, void *ev_data,
250                    void *fn_data) {
251   struct dns_data *d, *tmp;
252   if (ev == MG_EV_POLL) {
253     uint64_t now = *(uint64_t *) ev_data;
254     for (d = (struct dns_data *) c->mgr->active_dns_requests; d != NULL;
255          d = tmp) {
256       tmp = d->next;
257       // MG_DEBUG ("%lu %lu dns poll", d->expire, now));
258       if (now > d->expire) mg_error(d->c, "DNS timeout");
259     }
260   } else if (ev == MG_EV_READ) {
261     struct mg_dns_message dm;
262     int resolved = 0;
263     if (mg_dns_parse(c->recv.buf, c->recv.len, &dm) == false) {
264       MG_ERROR(("Unexpected DNS response:"));
265       mg_hexdump(c->recv.buf, c->recv.len);
266     } else {
267       // MG_VERBOSE(("%s %d", dm.name, dm.resolved));
268       for (d = (struct dns_data *) c->mgr->active_dns_requests; d != NULL;
269            d = tmp) {
270         tmp = d->next;
271         // MG_INFO(("d %p %hu %hu", d, d->txnid, dm.txnid));
272         if (dm.txnid != d->txnid) continue;
273         if (d->c->is_resolving) {
274           if (dm.resolved) {
275             dm.addr.port = d->c->rem.port;  // Save port
276             d->c->rem = dm.addr;            // Copy resolved address
277             MG_DEBUG(
278                 ("%lu %s is %M", d->c->id, dm.name, mg_print_ip, &d->c->rem));
279             mg_connect_resolved(d->c);
280 #if MG_ENABLE_IPV6
281           } else if (dm.addr.is_ip6 == false && dm.name[0] != '\0' &&
282                      c->mgr->use_dns6 == false) {
283             struct mg_str x = mg_str(dm.name);
284             mg_sendnsreq(d->c, &x, c->mgr->dnstimeout, &c->mgr->dns6, true);
285 #endif
286           } else {
287             mg_error(d->c, "%s DNS lookup failed", dm.name);
288           }
289         } else {
290           MG_ERROR(("%lu already resolved", d->c->id));
291         }
292         mg_dns_free(c, d);
293         resolved = 1;
294       }
295     }
296     if (!resolved) MG_ERROR(("stray DNS reply"));
297     c->recv.len = 0;
298   } else if (ev == MG_EV_CLOSE) {
299     for (d = (struct dns_data *) c->mgr->active_dns_requests; d != NULL;
300          d = tmp) {
301       tmp = d->next;
302       mg_error(d->c, "DNS error");
303       mg_dns_free(c, d);
304     }
305   }
306   (void) fn_data;
307 }
308
309 static bool mg_dns_send(struct mg_connection *c, const struct mg_str *name,
310                         uint16_t txnid, bool ipv6) {
311   struct {
312     struct mg_dns_header header;
313     uint8_t data[256];
314   } pkt;
315   size_t i, n;
316   memset(&pkt, 0, sizeof(pkt));
317   pkt.header.txnid = mg_htons(txnid);
318   pkt.header.flags = mg_htons(0x100);
319   pkt.header.num_questions = mg_htons(1);
320   for (i = n = 0; i < sizeof(pkt.data) - 5; i++) {
321     if (name->ptr[i] == '.' || i >= name->len) {
322       pkt.data[n] = (uint8_t) (i - n);
323       memcpy(&pkt.data[n + 1], name->ptr + n, i - n);
324       n = i + 1;
325     }
326     if (i >= name->len) break;
327   }
328   memcpy(&pkt.data[n], "\x00\x00\x01\x00\x01", 5);  // A query
329   n += 5;
330   if (ipv6) pkt.data[n - 3] = 0x1c;  // AAAA query
331   // memcpy(&pkt.data[n], "\xc0\x0c\x00\x1c\x00\x01", 6);  // AAAA query
332   // n += 6;
333   return mg_send(c, &pkt, sizeof(pkt.header) + n);
334 }
335
336 static void mg_sendnsreq(struct mg_connection *c, struct mg_str *name, int ms,
337                          struct mg_dns *dnsc, bool ipv6) {
338   struct dns_data *d = NULL;
339   if (dnsc->url == NULL) {
340     mg_error(c, "DNS server URL is NULL. Call mg_mgr_init()");
341   } else if (dnsc->c == NULL) {
342     dnsc->c = mg_connect(c->mgr, dnsc->url, NULL, NULL);
343     if (dnsc->c != NULL) {
344       dnsc->c->pfn = dns_cb;
345       // dnsc->c->is_hexdumping = 1;
346     }
347   }
348   if (dnsc->c == NULL) {
349     mg_error(c, "resolver");
350   } else if ((d = (struct dns_data *) calloc(1, sizeof(*d))) == NULL) {
351     mg_error(c, "resolve OOM");
352   } else {
353     struct dns_data *reqs = (struct dns_data *) c->mgr->active_dns_requests;
354     d->txnid = reqs ? (uint16_t) (reqs->txnid + 1) : 1;
355     d->next = (struct dns_data *) c->mgr->active_dns_requests;
356     c->mgr->active_dns_requests = d;
357     d->expire = mg_millis() + (uint64_t) ms;
358     d->c = c;
359     c->is_resolving = 1;
360     MG_VERBOSE(("%lu resolving %.*s @ %s, txnid %hu", c->id, (int) name->len,
361                 name->ptr, dnsc->url, d->txnid));
362     if (!mg_dns_send(dnsc->c, name, d->txnid, ipv6)) {
363       mg_error(dnsc->c, "DNS send");
364     }
365   }
366 }
367
368 void mg_resolve(struct mg_connection *c, const char *url) {
369   struct mg_str host = mg_url_host(url);
370   c->rem.port = mg_htons(mg_url_port(url));
371   if (mg_aton(host, &c->rem)) {
372     // host is an IP address, do not fire name resolution
373     mg_connect_resolved(c);
374   } else {
375     // host is not an IP, send DNS resolution request
376     struct mg_dns *dns = c->mgr->use_dns6 ? &c->mgr->dns6 : &c->mgr->dns4;
377     mg_sendnsreq(c, &host, c->mgr->dnstimeout, dns, c->mgr->use_dns6);
378   }
379 }
380
381 #ifdef MG_ENABLE_LINES
382 #line 1 "src/event.c"
383 #endif
384
385
386
387
388
389 void mg_call(struct mg_connection *c, int ev, void *ev_data) {
390   // Run user-defined handler first, in order to give it an ability
391   // to intercept processing (e.g. clean input buffer) before the
392   // protocol handler kicks in
393   if (c->fn != NULL) c->fn(c, ev, ev_data, c->fn_data);
394   if (c->pfn != NULL) c->pfn(c, ev, ev_data, c->pfn_data);
395 }
396
397 void mg_error(struct mg_connection *c, const char *fmt, ...) {
398   char buf[64];
399   va_list ap;
400   va_start(ap, fmt);
401   mg_vsnprintf(buf, sizeof(buf), fmt, &ap);
402   va_end(ap);
403   MG_ERROR(("%lu %p %s", c->id, c->fd, buf));
404   c->is_closing = 1;             // Set is_closing before sending MG_EV_CALL
405   mg_call(c, MG_EV_ERROR, buf);  // Let user handler to override it
406 }
407
408 #ifdef MG_ENABLE_LINES
409 #line 1 "src/fmt.c"
410 #endif
411
412
413
414
415 static bool is_digit(int c) {
416   return c >= '0' && c <= '9';
417 }
418
419 static int addexp(char *buf, int e, int sign) {
420   int n = 0;
421   buf[n++] = 'e';
422   buf[n++] = (char) sign;
423   if (e > 400) return 0;
424   if (e < 10) buf[n++] = '0';
425   if (e >= 100) buf[n++] = (char) (e / 100 + '0'), e -= 100 * (e / 100);
426   if (e >= 10) buf[n++] = (char) (e / 10 + '0'), e -= 10 * (e / 10);
427   buf[n++] = (char) (e + '0');
428   return n;
429 }
430
431 static int xisinf(double x) {
432   union {
433     double f;
434     uint64_t u;
435   } ieee754 = {x};
436   return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
437          ((unsigned) ieee754.u == 0);
438 }
439
440 static int xisnan(double x) {
441   union {
442     double f;
443     uint64_t u;
444   } ieee754 = {x};
445   return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) +
446              ((unsigned) ieee754.u != 0) >
447          0x7ff00000;
448 }
449
450 static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width, bool tz) {
451   char buf[40];
452   int i, s = 0, n = 0, e = 0;
453   double t, mul, saved;
454   if (d == 0.0) return mg_snprintf(dst, dstlen, "%s", "0");
455   if (xisinf(d)) return mg_snprintf(dst, dstlen, "%s", d > 0 ? "inf" : "-inf");
456   if (xisnan(d)) return mg_snprintf(dst, dstlen, "%s", "nan");
457   if (d < 0.0) d = -d, buf[s++] = '-';
458
459   // Round
460   saved = d;
461   mul = 1.0;
462   while (d >= 10.0 && d / mul >= 10.0) mul *= 10.0;
463   while (d <= 1.0 && d / mul <= 1.0) mul /= 10.0;
464   for (i = 0, t = mul * 5; i < width; i++) t /= 10.0;
465   d += t;
466   // Calculate exponent, and 'mul' for scientific representation
467   mul = 1.0;
468   while (d >= 10.0 && d / mul >= 10.0) mul *= 10.0, e++;
469   while (d < 1.0 && d / mul < 1.0) mul /= 10.0, e--;
470   // printf(" --> %g %d %g %g\n", saved, e, t, mul);
471
472   if (e >= width && width > 1) {
473     n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width, tz);
474     // printf(" --> %.*g %d [%.*s]\n", 10, d / t, e, n, buf);
475     n += addexp(buf + s + n, e, '+');
476     return mg_snprintf(dst, dstlen, "%.*s", n, buf);
477   } else if (e <= -width && width > 1) {
478     n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width, tz);
479     // printf(" --> %.*g %d [%.*s]\n", 10, d / mul, e, n, buf);
480     n += addexp(buf + s + n, -e, '-');
481     return mg_snprintf(dst, dstlen, "%.*s", n, buf);
482   } else {
483     for (i = 0, t = mul; t >= 1.0 && s + n < (int) sizeof(buf); i++) {
484       int ch = (int) (d / t);
485       if (n > 0 || ch > 0) buf[s + n++] = (char) (ch + '0');
486       d -= ch * t;
487       t /= 10.0;
488     }
489     // printf(" --> [%g] -> %g %g (%d) [%.*s]\n", saved, d, t, n, s + n, buf);
490     if (n == 0) buf[s++] = '0';
491     while (t >= 1.0 && n + s < (int) sizeof(buf)) buf[n++] = '0', t /= 10.0;
492     if (s + n < (int) sizeof(buf)) buf[n + s++] = '.';
493     // printf(" 1--> [%g] -> [%.*s]\n", saved, s + n, buf);
494     for (i = 0, t = 0.1; s + n < (int) sizeof(buf) && n < width; i++) {
495       int ch = (int) (d / t);
496       buf[s + n++] = (char) (ch + '0');
497       d -= ch * t;
498       t /= 10.0;
499     }
500   }
501   while (tz && n > 0 && buf[s + n - 1] == '0') n--;  // Trim trailing zeroes
502   if (n > 0 && buf[s + n - 1] == '.') n--;           // Trim trailing dot
503   n += s;
504   if (n >= (int) sizeof(buf)) n = (int) sizeof(buf) - 1;
505   buf[n] = '\0';
506   return mg_snprintf(dst, dstlen, "%s", buf);
507 }
508
509 static size_t mg_lld(char *buf, int64_t val, bool is_signed, bool is_hex) {
510   const char *letters = "0123456789abcdef";
511   uint64_t v = (uint64_t) val;
512   size_t s = 0, n, i;
513   if (is_signed && val < 0) buf[s++] = '-', v = (uint64_t) (-val);
514   // This loop prints a number in reverse order. I guess this is because we
515   // write numbers from right to left: least significant digit comes last.
516   // Maybe because we use Arabic numbers, and Arabs write RTL?
517   if (is_hex) {
518     for (n = 0; v; v >>= 4) buf[s + n++] = letters[v & 15];
519   } else {
520     for (n = 0; v; v /= 10) buf[s + n++] = letters[v % 10];
521   }
522   // Reverse a string
523   for (i = 0; i < n / 2; i++) {
524     char t = buf[s + i];
525     buf[s + i] = buf[s + n - i - 1], buf[s + n - i - 1] = t;
526   }
527   if (val == 0) buf[n++] = '0';  // Handle special case
528   return n + s;
529 }
530
531 static size_t scpy(void (*out)(char, void *), void *ptr, char *buf,
532                           size_t len) {
533   size_t i = 0;
534   while (i < len && buf[i] != '\0') out(buf[i++], ptr);
535   return i;
536 }
537
538 size_t mg_xprintf(void (*out)(char, void *), void *ptr, const char *fmt, ...) {
539   size_t len = 0;
540   va_list ap;
541   va_start(ap, fmt);
542   len = mg_vxprintf(out, ptr, fmt, &ap);
543   va_end(ap);
544   return len;
545 }
546
547 size_t mg_vxprintf(void (*out)(char, void *), void *param, const char *fmt,
548                    va_list *ap) {
549   size_t i = 0, n = 0;
550   while (fmt[i] != '\0') {
551     if (fmt[i] == '%') {
552       size_t j, k, x = 0, is_long = 0, w = 0 /* width */, pr = ~0U /* prec */;
553       char pad = ' ', minus = 0, c = fmt[++i];
554       if (c == '#') x++, c = fmt[++i];
555       if (c == '-') minus++, c = fmt[++i];
556       if (c == '0') pad = '0', c = fmt[++i];
557       while (is_digit(c)) w *= 10, w += (size_t) (c - '0'), c = fmt[++i];
558       if (c == '.') {
559         c = fmt[++i];
560         if (c == '*') {
561           pr = (size_t) va_arg(*ap, int);
562           c = fmt[++i];
563         } else {
564           pr = 0;
565           while (is_digit(c)) pr *= 10, pr += (size_t) (c - '0'), c = fmt[++i];
566         }
567       }
568       while (c == 'h') c = fmt[++i];  // Treat h and hh as int
569       if (c == 'l') {
570         is_long++, c = fmt[++i];
571         if (c == 'l') is_long++, c = fmt[++i];
572       }
573       if (c == 'p') x = 1, is_long = 1;
574       if (c == 'd' || c == 'u' || c == 'x' || c == 'X' || c == 'p' ||
575           c == 'g' || c == 'f') {
576         bool s = (c == 'd'), h = (c == 'x' || c == 'X' || c == 'p');
577         char tmp[40];
578         size_t xl = x ? 2 : 0;
579         if (c == 'g' || c == 'f') {
580           double v = va_arg(*ap, double);
581           if (pr == ~0U) pr = 6;
582           k = mg_dtoa(tmp, sizeof(tmp), v, (int) pr, c == 'g');
583         } else if (is_long == 2) {
584           int64_t v = va_arg(*ap, int64_t);
585           k = mg_lld(tmp, v, s, h);
586         } else if (is_long == 1) {
587           long v = va_arg(*ap, long);
588           k = mg_lld(tmp, s ? (int64_t) v : (int64_t) (unsigned long) v, s, h);
589         } else {
590           int v = va_arg(*ap, int);
591           k = mg_lld(tmp, s ? (int64_t) v : (int64_t) (unsigned) v, s, h);
592         }
593         for (j = 0; j < xl && w > 0; j++) w--;
594         for (j = 0; pad == ' ' && !minus && k < w && j + k < w; j++)
595           n += scpy(out, param, &pad, 1);
596         n += scpy(out, param, (char *) "0x", xl);
597         for (j = 0; pad == '0' && k < w && j + k < w; j++)
598           n += scpy(out, param, &pad, 1);
599         n += scpy(out, param, tmp, k);
600         for (j = 0; pad == ' ' && minus && k < w && j + k < w; j++)
601           n += scpy(out, param, &pad, 1);
602       } else if (c == 'm' || c == 'M') {
603         mg_pm_t f = va_arg(*ap, mg_pm_t);
604         if (c == 'm') out('"', param);
605         n += f(out, param, ap);
606         if (c == 'm') n += 2, out('"', param);
607       } else if (c == 'c') {
608         int ch = va_arg(*ap, int);
609         out((char) ch, param);
610         n++;
611       } else if (c == 's') {
612         char *p = va_arg(*ap, char *);
613         if (pr == ~0U) pr = p == NULL ? 0 : strlen(p);
614         for (j = 0; !minus && pr < w && j + pr < w; j++)
615           n += scpy(out, param, &pad, 1);
616         n += scpy(out, param, p, pr);
617         for (j = 0; minus && pr < w && j + pr < w; j++)
618           n += scpy(out, param, &pad, 1);
619       } else if (c == '%') {
620         out('%', param);
621         n++;
622       } else {
623         out('%', param);
624         out(c, param);
625         n += 2;
626       }
627       i++;
628     } else {
629       out(fmt[i], param), n++, i++;
630     }
631   }
632   return n;
633 }
634
635 #ifdef MG_ENABLE_LINES
636 #line 1 "src/fs.c"
637 #endif
638
639
640
641 struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags) {
642   struct mg_fd *fd = (struct mg_fd *) calloc(1, sizeof(*fd));
643   if (fd != NULL) {
644     fd->fd = fs->op(path, flags);
645     fd->fs = fs;
646     if (fd->fd == NULL) {
647       free(fd);
648       fd = NULL;
649     }
650   }
651   return fd;
652 }
653
654 void mg_fs_close(struct mg_fd *fd) {
655   if (fd != NULL) {
656     fd->fs->cl(fd->fd);
657     free(fd);
658   }
659 }
660
661 char *mg_file_read(struct mg_fs *fs, const char *path, size_t *sizep) {
662   struct mg_fd *fd;
663   char *data = NULL;
664   size_t size = 0;
665   fs->st(path, &size, NULL);
666   if ((fd = mg_fs_open(fs, path, MG_FS_READ)) != NULL) {
667     data = (char *) calloc(1, size + 1);
668     if (data != NULL) {
669       if (fs->rd(fd->fd, data, size) != size) {
670         free(data);
671         data = NULL;
672       } else {
673         data[size] = '\0';
674         if (sizep != NULL) *sizep = size;
675       }
676     }
677     mg_fs_close(fd);
678   }
679   return data;
680 }
681
682 bool mg_file_write(struct mg_fs *fs, const char *path, const void *buf,
683                    size_t len) {
684   bool result = false;
685   struct mg_fd *fd;
686   char tmp[MG_PATH_MAX];
687   mg_snprintf(tmp, sizeof(tmp), "%s..%d", path, rand());
688   if ((fd = mg_fs_open(fs, tmp, MG_FS_WRITE)) != NULL) {
689     result = fs->wr(fd->fd, buf, len) == len;
690     mg_fs_close(fd);
691     if (result) {
692       fs->rm(path);
693       fs->mv(tmp, path);
694     } else {
695       fs->rm(tmp);
696     }
697   }
698   return result;
699 }
700
701 bool mg_file_printf(struct mg_fs *fs, const char *path, const char *fmt, ...) {
702   va_list ap;
703   char *data;
704   bool result = false;
705   va_start(ap, fmt);
706   data = mg_vmprintf(fmt, &ap);
707   va_end(ap);
708   result = mg_file_write(fs, path, data, strlen(data));
709   free(data);
710   return result;
711 }
712
713 #ifdef MG_ENABLE_LINES
714 #line 1 "src/fs_fat.c"
715 #endif
716
717
718
719 #if MG_ENABLE_FATFS
720 #include <ff.h>
721
722 static int mg_days_from_epoch(int y, int m, int d) {
723   y -= m <= 2;
724   int era = y / 400;
725   int yoe = y - era * 400;
726   int doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + d - 1;
727   int doe = yoe * 365 + yoe / 4 - yoe / 100 + doy;
728   return era * 146097 + doe - 719468;
729 }
730
731 static time_t mg_timegm(const struct tm *t) {
732   int year = t->tm_year + 1900;
733   int month = t->tm_mon;  // 0-11
734   if (month > 11) {
735     year += month / 12;
736     month %= 12;
737   } else if (month < 0) {
738     int years_diff = (11 - month) / 12;
739     year -= years_diff;
740     month += 12 * years_diff;
741   }
742   int x = mg_days_from_epoch(year, month + 1, t->tm_mday);
743   return 60 * (60 * (24L * x + t->tm_hour) + t->tm_min) + t->tm_sec;
744 }
745
746 static time_t ff_time_to_epoch(uint16_t fdate, uint16_t ftime) {
747   struct tm tm;
748   memset(&tm, 0, sizeof(struct tm));
749   tm.tm_sec = (ftime << 1) & 0x3e;
750   tm.tm_min = ((ftime >> 5) & 0x3f);
751   tm.tm_hour = ((ftime >> 11) & 0x1f);
752   tm.tm_mday = (fdate & 0x1f);
753   tm.tm_mon = ((fdate >> 5) & 0x0f) - 1;
754   tm.tm_year = ((fdate >> 9) & 0x7f) + 80;
755   return mg_timegm(&tm);
756 }
757
758 static int ff_stat(const char *path, size_t *size, time_t *mtime) {
759   FILINFO fi;
760   if (path[0] == '\0') {
761     if (size) *size = 0;
762     if (mtime) *mtime = 0;
763     return MG_FS_DIR;
764   } else if (f_stat(path, &fi) == 0) {
765     if (size) *size = (size_t) fi.fsize;
766     if (mtime) *mtime = ff_time_to_epoch(fi.fdate, fi.ftime);
767     return MG_FS_READ | MG_FS_WRITE | ((fi.fattrib & AM_DIR) ? MG_FS_DIR : 0);
768   } else {
769     return 0;
770   }
771 }
772
773 static void ff_list(const char *dir, void (*fn)(const char *, void *),
774                     void *userdata) {
775   DIR d;
776   FILINFO fi;
777   if (f_opendir(&d, dir) == FR_OK) {
778     while (f_readdir(&d, &fi) == FR_OK && fi.fname[0] != '\0') {
779       if (!strcmp(fi.fname, ".") || !strcmp(fi.fname, "..")) continue;
780       fn(fi.fname, userdata);
781     }
782     f_closedir(&d);
783   }
784 }
785
786 static void *ff_open(const char *path, int flags) {
787   FIL f;
788   unsigned char mode = FA_READ;
789   if (flags & MG_FS_WRITE) mode |= FA_WRITE | FA_OPEN_ALWAYS | FA_OPEN_APPEND;
790   if (f_open(&f, path, mode) == 0) {
791     FIL *fp;
792     if ((fp = calloc(1, sizeof(*fp))) != NULL) {
793       memcpy(fp, &f, sizeof(*fp));
794       return fp;
795     }
796   }
797   return NULL;
798 }
799
800 static void ff_close(void *fp) {
801   if (fp != NULL) {
802     f_close((FIL *) fp);
803     free(fp);
804   }
805 }
806
807 static size_t ff_read(void *fp, void *buf, size_t len) {
808   UINT n = 0, misalign = ((size_t) buf) & 3;
809   if (misalign) {
810     char aligned[4];
811     f_read((FIL *) fp, aligned, len > misalign ? misalign : len, &n);
812     memcpy(buf, aligned, n);
813   } else {
814     f_read((FIL *) fp, buf, len, &n);
815   }
816   return n;
817 }
818
819 static size_t ff_write(void *fp, const void *buf, size_t len) {
820   UINT n = 0;
821   return f_write((FIL *) fp, (char *) buf, len, &n) == FR_OK ? n : 0;
822 }
823
824 static size_t ff_seek(void *fp, size_t offset) {
825   f_lseek((FIL *) fp, offset);
826   return offset;
827 }
828
829 static bool ff_rename(const char *from, const char *to) {
830   return f_rename(from, to) == FR_OK;
831 }
832
833 static bool ff_remove(const char *path) {
834   return f_unlink(path) == FR_OK;
835 }
836
837 static bool ff_mkdir(const char *path) {
838   return f_mkdir(path) == FR_OK;
839 }
840
841 struct mg_fs mg_fs_fat = {ff_stat,  ff_list, ff_open,   ff_close,  ff_read,
842                           ff_write, ff_seek, ff_rename, ff_remove, ff_mkdir};
843 #endif
844
845 #ifdef MG_ENABLE_LINES
846 #line 1 "src/fs_packed.c"
847 #endif
848
849
850
851
852 struct packed_file {
853   const char *data;
854   size_t size;
855   size_t pos;
856 };
857
858 const char *mg_unpack(const char *path, size_t *size, time_t *mtime);
859 const char *mg_unlist(size_t no);
860
861 #if MG_ENABLE_PACKED_FS
862 #else
863 const char *mg_unpack(const char *path, size_t *size, time_t *mtime) {
864   (void) path, (void) size, (void) mtime;
865   return NULL;
866 }
867 const char *mg_unlist(size_t no) {
868   (void) no;
869   return NULL;
870 }
871 #endif
872
873 static int is_dir_prefix(const char *prefix, size_t n, const char *path) {
874   // MG_INFO(("[%.*s] [%s] %c", (int) n, prefix, path, path[n]));
875   return n < strlen(path) && strncmp(prefix, path, n) == 0 &&
876          (n == 0 || path[n] == '/' || path[n - 1] == '/');
877 }
878
879 static int packed_stat(const char *path, size_t *size, time_t *mtime) {
880   const char *p;
881   size_t i, n = strlen(path);
882   if (mg_unpack(path, size, mtime)) return MG_FS_READ;  // Regular file
883   // Scan all files. If `path` is a dir prefix for any of them, it's a dir
884   for (i = 0; (p = mg_unlist(i)) != NULL; i++) {
885     if (is_dir_prefix(path, n, p)) return MG_FS_DIR;
886   }
887   return 0;
888 }
889
890 static void packed_list(const char *dir, void (*fn)(const char *, void *),
891                         void *userdata) {
892   char buf[MG_PATH_MAX], tmp[sizeof(buf)];
893   const char *path, *begin, *end;
894   size_t i, n = strlen(dir);
895   tmp[0] = '\0';  // Previously listed entry
896   for (i = 0; (path = mg_unlist(i)) != NULL; i++) {
897     if (!is_dir_prefix(dir, n, path)) continue;
898     begin = &path[n + 1];
899     end = strchr(begin, '/');
900     if (end == NULL) end = begin + strlen(begin);
901     mg_snprintf(buf, sizeof(buf), "%.*s", (int) (end - begin), begin);
902     buf[sizeof(buf) - 1] = '\0';
903     // If this entry has been already listed, skip
904     // NOTE: we're assuming that file list is sorted alphabetically
905     if (strcmp(buf, tmp) == 0) continue;
906     fn(buf, userdata);  // Not yet listed, call user function
907     strcpy(tmp, buf);   // And save this entry as listed
908   }
909 }
910
911 static void *packed_open(const char *path, int flags) {
912   size_t size = 0;
913   const char *data = mg_unpack(path, &size, NULL);
914   struct packed_file *fp = NULL;
915   if (data == NULL) return NULL;
916   if (flags & MG_FS_WRITE) return NULL;
917   if ((fp = (struct packed_file *) calloc(1, sizeof(*fp))) != NULL) {
918     fp->size = size;
919     fp->data = data;
920   }
921   return (void *) fp;
922 }
923
924 static void packed_close(void *fp) {
925   if (fp != NULL) free(fp);
926 }
927
928 static size_t packed_read(void *fd, void *buf, size_t len) {
929   struct packed_file *fp = (struct packed_file *) fd;
930   if (fp->pos + len > fp->size) len = fp->size - fp->pos;
931   memcpy(buf, &fp->data[fp->pos], len);
932   fp->pos += len;
933   return len;
934 }
935
936 static size_t packed_write(void *fd, const void *buf, size_t len) {
937   (void) fd, (void) buf, (void) len;
938   return 0;
939 }
940
941 static size_t packed_seek(void *fd, size_t offset) {
942   struct packed_file *fp = (struct packed_file *) fd;
943   fp->pos = offset;
944   if (fp->pos > fp->size) fp->pos = fp->size;
945   return fp->pos;
946 }
947
948 static bool packed_rename(const char *from, const char *to) {
949   (void) from, (void) to;
950   return false;
951 }
952
953 static bool packed_remove(const char *path) {
954   (void) path;
955   return false;
956 }
957
958 static bool packed_mkdir(const char *path) {
959   (void) path;
960   return false;
961 }
962
963 struct mg_fs mg_fs_packed = {
964     packed_stat,  packed_list, packed_open,   packed_close,  packed_read,
965     packed_write, packed_seek, packed_rename, packed_remove, packed_mkdir};
966
967 #ifdef MG_ENABLE_LINES
968 #line 1 "src/fs_posix.c"
969 #endif
970
971
972 #if MG_ENABLE_FILE
973
974 #ifndef MG_STAT_STRUCT
975 #define MG_STAT_STRUCT stat
976 #endif
977
978 #ifndef MG_STAT_FUNC
979 #define MG_STAT_FUNC stat
980 #endif
981
982 static int p_stat(const char *path, size_t *size, time_t *mtime) {
983 #if !defined(S_ISDIR)
984   MG_ERROR(("stat() API is not supported. %p %p %p", path, size, mtime));
985   return 0;
986 #else
987 #if MG_ARCH == MG_ARCH_WIN32
988   struct _stati64 st;
989   wchar_t tmp[MG_PATH_MAX];
990   MultiByteToWideChar(CP_UTF8, 0, path, -1, tmp, sizeof(tmp) / sizeof(tmp[0]));
991   if (_wstati64(tmp, &st) != 0) return 0;
992   // If path is a symlink, windows reports 0 in st.st_size.
993   // Get a real file size by opening it and jumping to the end
994   if (st.st_size == 0 && (st.st_mode & _S_IFREG)) {
995     FILE *fp = _wfopen(tmp, L"rb");
996     if (fp != NULL) {
997       fseek(fp, 0, SEEK_END);
998       if (ftell(fp) > 0) st.st_size = ftell(fp); // Use _ftelli64 on win10+
999       fclose(fp);
1000     }
1001   }
1002 #else
1003   struct MG_STAT_STRUCT st;
1004   if (MG_STAT_FUNC(path, &st) != 0) return 0;
1005 #endif
1006   if (size) *size = (size_t) st.st_size;
1007   if (mtime) *mtime = st.st_mtime;
1008   return MG_FS_READ | MG_FS_WRITE | (S_ISDIR(st.st_mode) ? MG_FS_DIR : 0);
1009 #endif
1010 }
1011
1012 #if MG_ARCH == MG_ARCH_WIN32
1013 struct dirent {
1014   char d_name[MAX_PATH];
1015 };
1016
1017 typedef struct win32_dir {
1018   HANDLE handle;
1019   WIN32_FIND_DATAW info;
1020   struct dirent result;
1021 } DIR;
1022
1023 int gettimeofday(struct timeval *tv, void *tz) {
1024   FILETIME ft;
1025   unsigned __int64 tmpres = 0;
1026
1027   if (tv != NULL) {
1028     GetSystemTimeAsFileTime(&ft);
1029     tmpres |= ft.dwHighDateTime;
1030     tmpres <<= 32;
1031     tmpres |= ft.dwLowDateTime;
1032     tmpres /= 10;  // convert into microseconds
1033     tmpres -= (int64_t) 11644473600000000;
1034     tv->tv_sec = (long) (tmpres / 1000000UL);
1035     tv->tv_usec = (long) (tmpres % 1000000UL);
1036   }
1037   (void) tz;
1038   return 0;
1039 }
1040
1041 static int to_wchar(const char *path, wchar_t *wbuf, size_t wbuf_len) {
1042   int ret;
1043   char buf[MAX_PATH * 2], buf2[MAX_PATH * 2], *p;
1044   strncpy(buf, path, sizeof(buf));
1045   buf[sizeof(buf) - 1] = '\0';
1046   // Trim trailing slashes. Leave backslash for paths like "X:\"
1047   p = buf + strlen(buf) - 1;
1048   while (p > buf && p[-1] != ':' && (p[0] == '\\' || p[0] == '/')) *p-- = '\0';
1049   memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
1050   ret = MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int) wbuf_len);
1051   // Convert back to Unicode. If doubly-converted string does not match the
1052   // original, something is fishy, reject.
1053   WideCharToMultiByte(CP_UTF8, 0, wbuf, (int) wbuf_len, buf2, sizeof(buf2),
1054                       NULL, NULL);
1055   if (strcmp(buf, buf2) != 0) {
1056     wbuf[0] = L'\0';
1057     ret = 0;
1058   }
1059   return ret;
1060 }
1061
1062 DIR *opendir(const char *name) {
1063   DIR *d = NULL;
1064   wchar_t wpath[MAX_PATH];
1065   DWORD attrs;
1066
1067   if (name == NULL) {
1068     SetLastError(ERROR_BAD_ARGUMENTS);
1069   } else if ((d = (DIR *) calloc(1, sizeof(*d))) == NULL) {
1070     SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1071   } else {
1072     to_wchar(name, wpath, sizeof(wpath) / sizeof(wpath[0]));
1073     attrs = GetFileAttributesW(wpath);
1074     if (attrs != 0Xffffffff && (attrs & FILE_ATTRIBUTE_DIRECTORY)) {
1075       (void) wcscat(wpath, L"\\*");
1076       d->handle = FindFirstFileW(wpath, &d->info);
1077       d->result.d_name[0] = '\0';
1078     } else {
1079       free(d);
1080       d = NULL;
1081     }
1082   }
1083   return d;
1084 }
1085
1086 int closedir(DIR *d) {
1087   int result = 0;
1088   if (d != NULL) {
1089     if (d->handle != INVALID_HANDLE_VALUE)
1090       result = FindClose(d->handle) ? 0 : -1;
1091     free(d);
1092   } else {
1093     result = -1;
1094     SetLastError(ERROR_BAD_ARGUMENTS);
1095   }
1096   return result;
1097 }
1098
1099 struct dirent *readdir(DIR *d) {
1100   struct dirent *result = NULL;
1101   if (d != NULL) {
1102     memset(&d->result, 0, sizeof(d->result));
1103     if (d->handle != INVALID_HANDLE_VALUE) {
1104       result = &d->result;
1105       WideCharToMultiByte(CP_UTF8, 0, d->info.cFileName, -1, result->d_name,
1106                           sizeof(result->d_name), NULL, NULL);
1107       if (!FindNextFileW(d->handle, &d->info)) {
1108         FindClose(d->handle);
1109         d->handle = INVALID_HANDLE_VALUE;
1110       }
1111     } else {
1112       SetLastError(ERROR_FILE_NOT_FOUND);
1113     }
1114   } else {
1115     SetLastError(ERROR_BAD_ARGUMENTS);
1116   }
1117   return result;
1118 }
1119 #endif
1120
1121 static void p_list(const char *dir, void (*fn)(const char *, void *),
1122                    void *userdata) {
1123 #if MG_ENABLE_DIRLIST
1124   struct dirent *dp;
1125   DIR *dirp;
1126   if ((dirp = (opendir(dir))) == NULL) return;
1127   while ((dp = readdir(dirp)) != NULL) {
1128     if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue;
1129     fn(dp->d_name, userdata);
1130   }
1131   closedir(dirp);
1132 #else
1133   (void) dir, (void) fn, (void) userdata;
1134 #endif
1135 }
1136
1137 static void *p_open(const char *path, int flags) {
1138   const char *mode = flags == MG_FS_READ ? "rb" : "a+b";
1139 #if MG_ARCH == MG_ARCH_WIN32
1140   wchar_t b1[MG_PATH_MAX], b2[10];
1141   MultiByteToWideChar(CP_UTF8, 0, path, -1, b1, sizeof(b1) / sizeof(b1[0]));
1142   MultiByteToWideChar(CP_UTF8, 0, mode, -1, b2, sizeof(b2) / sizeof(b2[0]));
1143   return (void *) _wfopen(b1, b2);
1144 #else
1145   return (void *) fopen(path, mode);
1146 #endif
1147 }
1148
1149 static void p_close(void *fp) {
1150   fclose((FILE *) fp);
1151 }
1152
1153 static size_t p_read(void *fp, void *buf, size_t len) {
1154   return fread(buf, 1, len, (FILE *) fp);
1155 }
1156
1157 static size_t p_write(void *fp, const void *buf, size_t len) {
1158   return fwrite(buf, 1, len, (FILE *) fp);
1159 }
1160
1161 static size_t p_seek(void *fp, size_t offset) {
1162 #if (defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64) ||  \
1163     (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || \
1164     (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600)
1165   if (fseeko((FILE *) fp, (off_t) offset, SEEK_SET) != 0) (void) 0;
1166 #else
1167   if (fseek((FILE *) fp, (long) offset, SEEK_SET) != 0) (void) 0;
1168 #endif
1169   return (size_t) ftell((FILE *) fp);
1170 }
1171
1172 static bool p_rename(const char *from, const char *to) {
1173   return rename(from, to) == 0;
1174 }
1175
1176 static bool p_remove(const char *path) {
1177   return remove(path) == 0;
1178 }
1179
1180 static bool p_mkdir(const char *path) {
1181   return mkdir(path, 0775) == 0;
1182 }
1183
1184 #else
1185
1186 static int p_stat(const char *path, size_t *size, time_t *mtime) {
1187   (void) path, (void) size, (void) mtime;
1188   return 0;
1189 }
1190 static void p_list(const char *path, void (*fn)(const char *, void *),
1191                    void *userdata) {
1192   (void) path, (void) fn, (void) userdata;
1193 }
1194 static void *p_open(const char *path, int flags) {
1195   (void) path, (void) flags;
1196   return NULL;
1197 }
1198 static void p_close(void *fp) {
1199   (void) fp;
1200 }
1201 static size_t p_read(void *fd, void *buf, size_t len) {
1202   (void) fd, (void) buf, (void) len;
1203   return 0;
1204 }
1205 static size_t p_write(void *fd, const void *buf, size_t len) {
1206   (void) fd, (void) buf, (void) len;
1207   return 0;
1208 }
1209 static size_t p_seek(void *fd, size_t offset) {
1210   (void) fd, (void) offset;
1211   return (size_t) ~0;
1212 }
1213 static bool p_rename(const char *from, const char *to) {
1214   (void) from, (void) to;
1215   return false;
1216 }
1217 static bool p_remove(const char *path) {
1218   (void) path;
1219   return false;
1220 }
1221 static bool p_mkdir(const char *path) {
1222   (void) path;
1223   return false;
1224 }
1225 #endif
1226
1227 struct mg_fs mg_fs_posix = {p_stat,  p_list, p_open,   p_close,  p_read,
1228                             p_write, p_seek, p_rename, p_remove, p_mkdir};
1229
1230 #ifdef MG_ENABLE_LINES
1231 #line 1 "src/http.c"
1232 #endif
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246 bool mg_to_size_t(struct mg_str str, size_t *val);
1247 bool mg_to_size_t(struct mg_str str, size_t *val) {
1248   size_t i = 0, max = (size_t) -1, max2 = max / 10, result = 0, ndigits = 0;
1249   while (i < str.len && (str.ptr[i] == ' ' || str.ptr[i] == '\t')) i++;
1250   if (i < str.len && str.ptr[i] == '-') return false;
1251   while (i < str.len && str.ptr[i] >= '0' && str.ptr[i] <= '9') {
1252     size_t digit = (size_t) (str.ptr[i] - '0');
1253     if (result > max2) return false;  // Overflow
1254     result *= 10;
1255     if (result > max - digit) return false;  // Overflow
1256     result += digit;
1257     i++, ndigits++;
1258   }
1259   while (i < str.len && (str.ptr[i] == ' ' || str.ptr[i] == '\t')) i++;
1260   if (ndigits == 0) return false;  // #2322: Content-Length = 1 * DIGIT
1261   if (i != str.len) return false;  // Ditto
1262   *val = (size_t) result;
1263   return true;
1264 }
1265
1266 // Chunk deletion marker is the MSB in the "processed" counter
1267 #define MG_DMARK ((size_t) 1 << (sizeof(size_t) * 8 - 1))
1268
1269 // Multipart POST example:
1270 // --xyz
1271 // Content-Disposition: form-data; name="val"
1272 //
1273 // abcdef
1274 // --xyz
1275 // Content-Disposition: form-data; name="foo"; filename="a.txt"
1276 // Content-Type: text/plain
1277 //
1278 // hello world
1279 //
1280 // --xyz--
1281 size_t mg_http_next_multipart(struct mg_str body, size_t ofs,
1282                               struct mg_http_part *part) {
1283   struct mg_str cd = mg_str_n("Content-Disposition", 19);
1284   const char *s = body.ptr;
1285   size_t b = ofs, h1, h2, b1, b2, max = body.len;
1286
1287   // Init part params
1288   if (part != NULL) part->name = part->filename = part->body = mg_str_n(0, 0);
1289
1290   // Skip boundary
1291   while (b + 2 < max && s[b] != '\r' && s[b + 1] != '\n') b++;
1292   if (b <= ofs || b + 2 >= max) return 0;
1293   // MG_INFO(("B: %zu %zu [%.*s]", ofs, b - ofs, (int) (b - ofs), s));
1294
1295   // Skip headers
1296   h1 = h2 = b + 2;
1297   for (;;) {
1298     while (h2 + 2 < max && s[h2] != '\r' && s[h2 + 1] != '\n') h2++;
1299     if (h2 == h1) break;
1300     if (h2 + 2 >= max) return 0;
1301     // MG_INFO(("Header: [%.*s]", (int) (h2 - h1), &s[h1]));
1302     if (part != NULL && h1 + cd.len + 2 < h2 && s[h1 + cd.len] == ':' &&
1303         mg_ncasecmp(&s[h1], cd.ptr, cd.len) == 0) {
1304       struct mg_str v = mg_str_n(&s[h1 + cd.len + 2], h2 - (h1 + cd.len + 2));
1305       part->name = mg_http_get_header_var(v, mg_str_n("name", 4));
1306       part->filename = mg_http_get_header_var(v, mg_str_n("filename", 8));
1307     }
1308     h1 = h2 = h2 + 2;
1309   }
1310   b1 = b2 = h2 + 2;
1311   while (b2 + 2 + (b - ofs) + 2 < max && !(s[b2] == '\r' && s[b2 + 1] == '\n' &&
1312                                            memcmp(&s[b2 + 2], s, b - ofs) == 0))
1313     b2++;
1314
1315   if (b2 + 2 >= max) return 0;
1316   if (part != NULL) part->body = mg_str_n(&s[b1], b2 - b1);
1317   // MG_INFO(("Body: [%.*s]", (int) (b2 - b1), &s[b1]));
1318   return b2 + 2;
1319 }
1320
1321 void mg_http_bauth(struct mg_connection *c, const char *user,
1322                    const char *pass) {
1323   struct mg_str u = mg_str(user), p = mg_str(pass);
1324   size_t need = c->send.len + 36 + (u.len + p.len) * 2;
1325   if (c->send.size < need) mg_iobuf_resize(&c->send, need);
1326   if (c->send.size >= need) {
1327     int i, n = 0;
1328     char *buf = (char *) &c->send.buf[c->send.len];
1329     memcpy(buf, "Authorization: Basic ", 21);  // DON'T use mg_send!
1330     for (i = 0; i < (int) u.len; i++) {
1331       n = mg_base64_update(((unsigned char *) u.ptr)[i], buf + 21, n);
1332     }
1333     if (p.len > 0) {
1334       n = mg_base64_update(':', buf + 21, n);
1335       for (i = 0; i < (int) p.len; i++) {
1336         n = mg_base64_update(((unsigned char *) p.ptr)[i], buf + 21, n);
1337       }
1338     }
1339     n = mg_base64_final(buf + 21, n);
1340     c->send.len += 21 + (size_t) n + 2;
1341     memcpy(&c->send.buf[c->send.len - 2], "\r\n", 2);
1342   } else {
1343     MG_ERROR(("%lu oom %d->%d ", c->id, (int) c->send.size, (int) need));
1344   }
1345 }
1346
1347 struct mg_str mg_http_var(struct mg_str buf, struct mg_str name) {
1348   struct mg_str k, v, result = mg_str_n(NULL, 0);
1349   while (mg_split(&buf, &k, &v, '&')) {
1350     if (name.len == k.len && mg_ncasecmp(name.ptr, k.ptr, k.len) == 0) {
1351       result = v;
1352       break;
1353     }
1354   }
1355   return result;
1356 }
1357
1358 int mg_http_get_var(const struct mg_str *buf, const char *name, char *dst,
1359                     size_t dst_len) {
1360   int len;
1361   if (dst == NULL || dst_len == 0) {
1362     len = -2;  // Bad destination
1363   } else if (buf->ptr == NULL || name == NULL || buf->len == 0) {
1364     len = -1;  // Bad source
1365     dst[0] = '\0';
1366   } else {
1367     struct mg_str v = mg_http_var(*buf, mg_str(name));
1368     if (v.ptr == NULL) {
1369       len = -4;  // Name does not exist
1370     } else {
1371       len = mg_url_decode(v.ptr, v.len, dst, dst_len, 1);
1372       if (len < 0) len = -3;  // Failed to decode
1373     }
1374   }
1375   return len;
1376 }
1377
1378 static bool isx(int c) {
1379   return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
1380          (c >= 'A' && c <= 'F');
1381 }
1382
1383 int mg_url_decode(const char *src, size_t src_len, char *dst, size_t dst_len,
1384                   int is_form_url_encoded) {
1385   size_t i, j;
1386   for (i = j = 0; i < src_len && j + 1 < dst_len; i++, j++) {
1387     if (src[i] == '%') {
1388       // Use `i + 2 < src_len`, not `i < src_len - 2`, note small src_len
1389       if (i + 2 < src_len && isx(src[i + 1]) && isx(src[i + 2])) {
1390         mg_unhex(src + i + 1, 2, (uint8_t *) &dst[j]);
1391         i += 2;
1392       } else {
1393         return -1;
1394       }
1395     } else if (is_form_url_encoded && src[i] == '+') {
1396       dst[j] = ' ';
1397     } else {
1398       dst[j] = src[i];
1399     }
1400   }
1401   if (j < dst_len) dst[j] = '\0';  // Null-terminate the destination
1402   return i >= src_len && j < dst_len ? (int) j : -1;
1403 }
1404
1405 static bool isok(uint8_t c) {
1406   return c == '\n' || c == '\r' || c >= ' ';
1407 }
1408
1409 int mg_http_get_request_len(const unsigned char *buf, size_t buf_len) {
1410   size_t i;
1411   for (i = 0; i < buf_len; i++) {
1412     if (!isok(buf[i])) return -1;
1413     if ((i > 0 && buf[i] == '\n' && buf[i - 1] == '\n') ||
1414         (i > 3 && buf[i] == '\n' && buf[i - 1] == '\r' && buf[i - 2] == '\n'))
1415       return (int) i + 1;
1416   }
1417   return 0;
1418 }
1419 struct mg_str *mg_http_get_header(struct mg_http_message *h, const char *name) {
1420   size_t i, n = strlen(name), max = sizeof(h->headers) / sizeof(h->headers[0]);
1421   for (i = 0; i < max && h->headers[i].name.len > 0; i++) {
1422     struct mg_str *k = &h->headers[i].name, *v = &h->headers[i].value;
1423     if (n == k->len && mg_ncasecmp(k->ptr, name, n) == 0) return v;
1424   }
1425   return NULL;
1426 }
1427
1428 // Get character length. Used to parse method, URI, headers
1429 static size_t clen(const char *s) {
1430   uint8_t c = *(uint8_t *) s;
1431   if (c > ' ' && c < '~') return 1;  // Usual ascii printed char
1432   if ((c & 0xe0) == 0xc0) return 2;  // 2-byte UTF8
1433   if ((c & 0xf0) == 0xe0) return 3;  // 3-byte UTF8
1434   if ((c & 0xf8) == 0xf0) return 4;  // 4-byte UTF8
1435   return 0;
1436 }
1437
1438 // Skip until the newline. Return advanced `s`, or NULL on error
1439 static const char *skiptorn(const char *s, const char *end, struct mg_str *v) {
1440   v->ptr = s;
1441   while (s < end && s[0] != '\n' && s[0] != '\r') s++, v->len++;  // To newline
1442   if (s >= end || (s[0] == '\r' && s[1] != '\n')) return NULL;    // Stray \r
1443   if (s < end && s[0] == '\r') s++;                               // Skip \r
1444   if (s >= end || *s++ != '\n') return NULL;                      // Skip \n
1445   return s;
1446 }
1447
1448 static bool mg_http_parse_headers(const char *s, const char *end,
1449                                   struct mg_http_header *h, size_t max_hdrs) {
1450   size_t i, n;
1451   for (i = 0; i < max_hdrs; i++) {
1452     struct mg_str k = {NULL, 0}, v = {NULL, 0};
1453     if (s >= end) return false;
1454     if (s[0] == '\n' || (s[0] == '\r' && s[1] == '\n')) break;
1455     k.ptr = s;
1456     while (s < end && s[0] != ':' && (n = clen(s)) > 0) s += n, k.len += n;
1457     if (k.len == 0) return false;               // Empty name
1458     if (s >= end || *s++ != ':') return false;  // Invalid, not followed by :
1459     while (s < end && s[0] == ' ') s++;         // Skip spaces
1460     if ((s = skiptorn(s, end, &v)) == NULL) return false;
1461     while (v.len > 0 && v.ptr[v.len - 1] == ' ') v.len--;  // Trim spaces
1462     // MG_INFO(("--HH [%.*s] [%.*s]", (int) k.len, k.ptr, (int) v.len, v.ptr));
1463     h[i].name = k, h[i].value = v;  // Success. Assign values
1464   }
1465   return true;
1466 }
1467
1468 int mg_http_parse(const char *s, size_t len, struct mg_http_message *hm) {
1469   int is_response, req_len = mg_http_get_request_len((unsigned char *) s, len);
1470   const char *end = s == NULL ? NULL : s + req_len, *qs;  // Cannot add to NULL
1471   struct mg_str *cl;
1472   size_t n;
1473
1474   memset(hm, 0, sizeof(*hm));
1475   if (req_len <= 0) return req_len;
1476
1477   hm->message.ptr = hm->head.ptr = s;
1478   hm->body.ptr = end;
1479   hm->head.len = (size_t) req_len;
1480   hm->chunk.ptr = end;
1481   hm->message.len = hm->body.len = (size_t) ~0;  // Set body length to infinite
1482
1483   // Parse request line
1484   hm->method.ptr = s;
1485   while (s < end && (n = clen(s)) > 0) s += n, hm->method.len += n;
1486   while (s < end && s[0] == ' ') s++;  // Skip spaces
1487   hm->uri.ptr = s;
1488   while (s < end && (n = clen(s)) > 0) s += n, hm->uri.len += n;
1489   while (s < end && s[0] == ' ') s++;  // Skip spaces
1490   if ((s = skiptorn(s, end, &hm->proto)) == NULL) return false;
1491
1492   // Sanity check. Allow protocol/reason to be empty
1493   if (hm->method.len == 0 || hm->uri.len == 0) return -1;
1494
1495   // If URI contains '?' character, setup query string
1496   if ((qs = (const char *) memchr(hm->uri.ptr, '?', hm->uri.len)) != NULL) {
1497     hm->query.ptr = qs + 1;
1498     hm->query.len = (size_t) (&hm->uri.ptr[hm->uri.len] - (qs + 1));
1499     hm->uri.len = (size_t) (qs - hm->uri.ptr);
1500   }
1501
1502   if (!mg_http_parse_headers(s, end, hm->headers,
1503                              sizeof(hm->headers) / sizeof(hm->headers[0])))
1504     return -1;  // error when parsing
1505   if ((cl = mg_http_get_header(hm, "Content-Length")) != NULL) {
1506     if (mg_to_size_t(*cl, &hm->body.len) == false) return -1;
1507     hm->message.len = (size_t) req_len + hm->body.len;
1508   }
1509
1510   // mg_http_parse() is used to parse both HTTP requests and HTTP
1511   // responses. If HTTP response does not have Content-Length set, then
1512   // body is read until socket is closed, i.e. body.len is infinite (~0).
1513   //
1514   // For HTTP requests though, according to
1515   // http://tools.ietf.org/html/rfc7231#section-8.1.3,
1516   // only POST and PUT methods have defined body semantics.
1517   // Therefore, if Content-Length is not specified and methods are
1518   // not one of PUT or POST, set body length to 0.
1519   //
1520   // So, if it is HTTP request, and Content-Length is not set,
1521   // and method is not (PUT or POST) then reset body length to zero.
1522   is_response = mg_ncasecmp(hm->method.ptr, "HTTP/", 5) == 0;
1523   if (hm->body.len == (size_t) ~0 && !is_response &&
1524       mg_vcasecmp(&hm->method, "PUT") != 0 &&
1525       mg_vcasecmp(&hm->method, "POST") != 0) {
1526     hm->body.len = 0;
1527     hm->message.len = (size_t) req_len;
1528   }
1529
1530   // The 204 (No content) responses also have 0 body length
1531   if (hm->body.len == (size_t) ~0 && is_response &&
1532       mg_vcasecmp(&hm->uri, "204") == 0) {
1533     hm->body.len = 0;
1534     hm->message.len = (size_t) req_len;
1535   }
1536   if (hm->message.len < (size_t) req_len) return -1; // Overflow protection
1537
1538   return req_len;
1539 }
1540
1541 static void mg_http_vprintf_chunk(struct mg_connection *c, const char *fmt,
1542                                   va_list *ap) {
1543   size_t len = c->send.len;
1544   mg_send(c, "        \r\n", 10);
1545   mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
1546   if (c->send.len >= len + 10) {
1547     mg_snprintf((char *) c->send.buf + len, 9, "%08lx", c->send.len - len - 10);
1548     c->send.buf[len + 8] = '\r';
1549     if (c->send.len == len + 10) c->is_resp = 0;  // Last chunk, reset marker
1550   }
1551   mg_send(c, "\r\n", 2);
1552 }
1553
1554 void mg_http_printf_chunk(struct mg_connection *c, const char *fmt, ...) {
1555   va_list ap;
1556   va_start(ap, fmt);
1557   mg_http_vprintf_chunk(c, fmt, &ap);
1558   va_end(ap);
1559 }
1560
1561 void mg_http_write_chunk(struct mg_connection *c, const char *buf, size_t len) {
1562   mg_printf(c, "%lx\r\n", (unsigned long) len);
1563   mg_send(c, buf, len);
1564   mg_send(c, "\r\n", 2);
1565   if (len == 0) c->is_resp = 0;
1566 }
1567
1568 // clang-format off
1569 static const char *mg_http_status_code_str(int status_code) {
1570   switch (status_code) {
1571     case 100: return "Continue";
1572     case 101: return "Switching Protocols";
1573     case 102: return "Processing";
1574     case 200: return "OK";
1575     case 201: return "Created";
1576     case 202: return "Accepted";
1577     case 203: return "Non-authoritative Information";
1578     case 204: return "No Content";
1579     case 205: return "Reset Content";
1580     case 206: return "Partial Content";
1581     case 207: return "Multi-Status";
1582     case 208: return "Already Reported";
1583     case 226: return "IM Used";
1584     case 300: return "Multiple Choices";
1585     case 301: return "Moved Permanently";
1586     case 302: return "Found";
1587     case 303: return "See Other";
1588     case 304: return "Not Modified";
1589     case 305: return "Use Proxy";
1590     case 307: return "Temporary Redirect";
1591     case 308: return "Permanent Redirect";
1592     case 400: return "Bad Request";
1593     case 401: return "Unauthorized";
1594     case 402: return "Payment Required";
1595     case 403: return "Forbidden";
1596     case 404: return "Not Found";
1597     case 405: return "Method Not Allowed";
1598     case 406: return "Not Acceptable";
1599     case 407: return "Proxy Authentication Required";
1600     case 408: return "Request Timeout";
1601     case 409: return "Conflict";
1602     case 410: return "Gone";
1603     case 411: return "Length Required";
1604     case 412: return "Precondition Failed";
1605     case 413: return "Payload Too Large";
1606     case 414: return "Request-URI Too Long";
1607     case 415: return "Unsupported Media Type";
1608     case 416: return "Requested Range Not Satisfiable";
1609     case 417: return "Expectation Failed";
1610     case 418: return "I'm a teapot";
1611     case 421: return "Misdirected Request";
1612     case 422: return "Unprocessable Entity";
1613     case 423: return "Locked";
1614     case 424: return "Failed Dependency";
1615     case 426: return "Upgrade Required";
1616     case 428: return "Precondition Required";
1617     case 429: return "Too Many Requests";
1618     case 431: return "Request Header Fields Too Large";
1619     case 444: return "Connection Closed Without Response";
1620     case 451: return "Unavailable For Legal Reasons";
1621     case 499: return "Client Closed Request";
1622     case 500: return "Internal Server Error";
1623     case 501: return "Not Implemented";
1624     case 502: return "Bad Gateway";
1625     case 503: return "Service Unavailable";
1626     case 504: return "Gateway Timeout";
1627     case 505: return "HTTP Version Not Supported";
1628     case 506: return "Variant Also Negotiates";
1629     case 507: return "Insufficient Storage";
1630     case 508: return "Loop Detected";
1631     case 510: return "Not Extended";
1632     case 511: return "Network Authentication Required";
1633     case 599: return "Network Connect Timeout Error";
1634     default: return "";
1635   }
1636 }
1637 // clang-format on
1638
1639 void mg_http_reply(struct mg_connection *c, int code, const char *headers,
1640                    const char *fmt, ...) {
1641   va_list ap;
1642   size_t len;
1643   mg_printf(c, "HTTP/1.1 %d %s\r\n%sContent-Length:            \r\n\r\n", code,
1644             mg_http_status_code_str(code), headers == NULL ? "" : headers);
1645   len = c->send.len;
1646   va_start(ap, fmt);
1647   mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, &ap);
1648   va_end(ap);
1649   if (c->send.len > 16) {
1650     size_t n = mg_snprintf((char *) &c->send.buf[len - 15], 11, "%-10lu",
1651                            (unsigned long) (c->send.len - len));
1652     c->send.buf[len - 15 + n] = ' ';  // Change ending 0 to space
1653   }
1654   c->is_resp = 0;
1655 }
1656
1657 static void http_cb(struct mg_connection *, int, void *, void *);
1658 static void restore_http_cb(struct mg_connection *c) {
1659   mg_fs_close((struct mg_fd *) c->pfn_data);
1660   c->pfn_data = NULL;
1661   c->pfn = http_cb;
1662   c->is_resp = 0;
1663 }
1664
1665 char *mg_http_etag(char *buf, size_t len, size_t size, time_t mtime);
1666 char *mg_http_etag(char *buf, size_t len, size_t size, time_t mtime) {
1667   mg_snprintf(buf, len, "\"%lld.%lld\"", (int64_t) mtime, (int64_t) size);
1668   return buf;
1669 }
1670
1671 static void static_cb(struct mg_connection *c, int ev, void *ev_data,
1672                       void *fn_data) {
1673   if (ev == MG_EV_WRITE || ev == MG_EV_POLL) {
1674     struct mg_fd *fd = (struct mg_fd *) fn_data;
1675     // Read to send IO buffer directly, avoid extra on-stack buffer
1676     size_t n, max = MG_IO_SIZE, space;
1677     size_t *cl = (size_t *) &c->data[(sizeof(c->data) - sizeof(size_t)) /
1678                                      sizeof(size_t) * sizeof(size_t)];
1679     if (c->send.size < max) mg_iobuf_resize(&c->send, max);
1680     if (c->send.len >= c->send.size) return;  // Rate limit
1681     if ((space = c->send.size - c->send.len) > *cl) space = *cl;
1682     n = fd->fs->rd(fd->fd, c->send.buf + c->send.len, space);
1683     c->send.len += n;
1684     *cl -= n;
1685     if (n == 0) restore_http_cb(c);
1686   } else if (ev == MG_EV_CLOSE) {
1687     restore_http_cb(c);
1688   }
1689   (void) ev_data;
1690 }
1691
1692 // Known mime types. Keep it outside guess_content_type() function, since
1693 // some environments don't like it defined there.
1694 // clang-format off
1695 static struct mg_str s_known_types[] = {
1696     MG_C_STR("html"), MG_C_STR("text/html; charset=utf-8"),
1697     MG_C_STR("htm"), MG_C_STR("text/html; charset=utf-8"),
1698     MG_C_STR("css"), MG_C_STR("text/css; charset=utf-8"),
1699     MG_C_STR("js"), MG_C_STR("text/javascript; charset=utf-8"),
1700     MG_C_STR("gif"), MG_C_STR("image/gif"),
1701     MG_C_STR("png"), MG_C_STR("image/png"),
1702     MG_C_STR("jpg"), MG_C_STR("image/jpeg"),
1703     MG_C_STR("jpeg"), MG_C_STR("image/jpeg"),
1704     MG_C_STR("woff"), MG_C_STR("font/woff"),
1705     MG_C_STR("ttf"), MG_C_STR("font/ttf"),
1706     MG_C_STR("svg"), MG_C_STR("image/svg+xml"),
1707     MG_C_STR("txt"), MG_C_STR("text/plain; charset=utf-8"),
1708     MG_C_STR("avi"), MG_C_STR("video/x-msvideo"),
1709     MG_C_STR("csv"), MG_C_STR("text/csv"),
1710     MG_C_STR("doc"), MG_C_STR("application/msword"),
1711     MG_C_STR("exe"), MG_C_STR("application/octet-stream"),
1712     MG_C_STR("gz"), MG_C_STR("application/gzip"),
1713     MG_C_STR("ico"), MG_C_STR("image/x-icon"),
1714     MG_C_STR("json"), MG_C_STR("application/json"),
1715     MG_C_STR("mov"), MG_C_STR("video/quicktime"),
1716     MG_C_STR("mp3"), MG_C_STR("audio/mpeg"),
1717     MG_C_STR("mp4"), MG_C_STR("video/mp4"),
1718     MG_C_STR("mpeg"), MG_C_STR("video/mpeg"),
1719     MG_C_STR("pdf"), MG_C_STR("application/pdf"),
1720     MG_C_STR("shtml"), MG_C_STR("text/html; charset=utf-8"),
1721     MG_C_STR("tgz"), MG_C_STR("application/tar-gz"),
1722     MG_C_STR("wav"), MG_C_STR("audio/wav"),
1723     MG_C_STR("webp"), MG_C_STR("image/webp"),
1724     MG_C_STR("zip"), MG_C_STR("application/zip"),
1725     MG_C_STR("3gp"), MG_C_STR("video/3gpp"),
1726     {0, 0},
1727 };
1728 // clang-format on
1729
1730 static struct mg_str guess_content_type(struct mg_str path, const char *extra) {
1731   struct mg_str k, v, s = mg_str(extra);
1732   size_t i = 0;
1733
1734   // Shrink path to its extension only
1735   while (i < path.len && path.ptr[path.len - i - 1] != '.') i++;
1736   path.ptr += path.len - i;
1737   path.len = i;
1738
1739   // Process user-provided mime type overrides, if any
1740   while (mg_commalist(&s, &k, &v)) {
1741     if (mg_strcmp(path, k) == 0) return v;
1742   }
1743
1744   // Process built-in mime types
1745   for (i = 0; s_known_types[i].ptr != NULL; i += 2) {
1746     if (mg_strcmp(path, s_known_types[i]) == 0) return s_known_types[i + 1];
1747   }
1748
1749   return mg_str("text/plain; charset=utf-8");
1750 }
1751
1752 static int getrange(struct mg_str *s, size_t *a, size_t *b) {
1753   size_t i, numparsed = 0;
1754   for (i = 0; i + 6 < s->len; i++) {
1755     struct mg_str k, v = mg_str_n(s->ptr + i + 6, s->len - i - 6);
1756     if (memcmp(&s->ptr[i], "bytes=", 6) != 0) continue;
1757     if (mg_split(&v, &k, NULL, '-')) {
1758       if (mg_to_size_t(k, a)) numparsed++;
1759       if (v.len > 0 && mg_to_size_t(v, b)) numparsed++;
1760     } else {
1761       if (mg_to_size_t(v, a)) numparsed++;
1762     }
1763     break;
1764   }
1765   return (int) numparsed;
1766 }
1767
1768 void mg_http_serve_file(struct mg_connection *c, struct mg_http_message *hm,
1769                         const char *path,
1770                         const struct mg_http_serve_opts *opts) {
1771   char etag[64], tmp[MG_PATH_MAX];
1772   struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
1773   struct mg_fd *fd = NULL;
1774   size_t size = 0;
1775   time_t mtime = 0;
1776   struct mg_str *inm = NULL;
1777   struct mg_str mime = guess_content_type(mg_str(path), opts->mime_types);
1778   bool gzip = false;
1779
1780   if (path != NULL) {
1781     // If a browser sends us "Accept-Encoding: gzip", try to open .gz first
1782     struct mg_str *ae = mg_http_get_header(hm, "Accept-Encoding");
1783     if (ae != NULL && mg_strstr(*ae, mg_str("gzip")) != NULL) {
1784       mg_snprintf(tmp, sizeof(tmp), "%s.gz", path);
1785       fd = mg_fs_open(fs, tmp, MG_FS_READ);
1786       if (fd != NULL) gzip = true, path = tmp;
1787     }
1788     // No luck opening .gz? Open what we've told to open
1789     if (fd == NULL) fd = mg_fs_open(fs, path, MG_FS_READ);
1790   }
1791
1792   // Failed to open, and page404 is configured? Open it, then
1793   if (fd == NULL && opts->page404 != NULL) {
1794     fd = mg_fs_open(fs, opts->page404, MG_FS_READ);
1795     mime = guess_content_type(mg_str(path), opts->mime_types);
1796     path = opts->page404;
1797   }
1798
1799   if (fd == NULL || fs->st(path, &size, &mtime) == 0) {
1800     mg_http_reply(c, 404, opts->extra_headers, "Not found\n");
1801     mg_fs_close(fd);
1802     // NOTE: mg_http_etag() call should go first!
1803   } else if (mg_http_etag(etag, sizeof(etag), size, mtime) != NULL &&
1804              (inm = mg_http_get_header(hm, "If-None-Match")) != NULL &&
1805              mg_vcasecmp(inm, etag) == 0) {
1806     mg_fs_close(fd);
1807     mg_http_reply(c, 304, opts->extra_headers, "");
1808   } else {
1809     int n, status = 200;
1810     char range[100];
1811     size_t r1 = 0, r2 = 0, cl = size;
1812
1813     // Handle Range header
1814     struct mg_str *rh = mg_http_get_header(hm, "Range");
1815     range[0] = '\0';
1816     if (rh != NULL && (n = getrange(rh, &r1, &r2)) > 0) {
1817       // If range is specified like "400-", set second limit to content len
1818       if (n == 1) r2 = cl - 1;
1819       if (r1 > r2 || r2 >= cl) {
1820         status = 416;
1821         cl = 0;
1822         mg_snprintf(range, sizeof(range), "Content-Range: bytes */%lld\r\n",
1823                     (int64_t) size);
1824       } else {
1825         status = 206;
1826         cl = r2 - r1 + 1;
1827         mg_snprintf(range, sizeof(range),
1828                     "Content-Range: bytes %llu-%llu/%llu\r\n", (uint64_t) r1,
1829                     (uint64_t) (r1 + cl - 1), (uint64_t) size);
1830         fs->sk(fd->fd, r1);
1831       }
1832     }
1833     mg_printf(c,
1834               "HTTP/1.1 %d %s\r\n"
1835               "Content-Type: %.*s\r\n"
1836               "Etag: %s\r\n"
1837               "Content-Length: %llu\r\n"
1838               "%s%s%s\r\n",
1839               status, mg_http_status_code_str(status), (int) mime.len, mime.ptr,
1840               etag, (uint64_t) cl, gzip ? "Content-Encoding: gzip\r\n" : "",
1841               range, opts->extra_headers ? opts->extra_headers : "");
1842     if (mg_vcasecmp(&hm->method, "HEAD") == 0) {
1843       c->is_draining = 1;
1844       c->is_resp = 0;
1845       mg_fs_close(fd);
1846     } else {
1847       // Track to-be-sent content length at the end of c->data, aligned
1848       size_t *clp = (size_t *) &c->data[(sizeof(c->data) - sizeof(size_t)) /
1849                                         sizeof(size_t) * sizeof(size_t)];
1850       c->pfn = static_cb;
1851       c->pfn_data = fd;
1852       *clp = cl;
1853     }
1854   }
1855 }
1856
1857 struct printdirentrydata {
1858   struct mg_connection *c;
1859   struct mg_http_message *hm;
1860   const struct mg_http_serve_opts *opts;
1861   const char *dir;
1862 };
1863
1864 #if MG_ENABLE_DIRLIST
1865 static void printdirentry(const char *name, void *userdata) {
1866   struct printdirentrydata *d = (struct printdirentrydata *) userdata;
1867   struct mg_fs *fs = d->opts->fs == NULL ? &mg_fs_posix : d->opts->fs;
1868   size_t size = 0;
1869   time_t t = 0;
1870   char path[MG_PATH_MAX], sz[40], mod[40];
1871   int flags, n = 0;
1872
1873   // MG_DEBUG(("[%s] [%s]", d->dir, name));
1874   if (mg_snprintf(path, sizeof(path), "%s%c%s", d->dir, '/', name) >
1875       sizeof(path)) {
1876     MG_ERROR(("%s truncated", name));
1877   } else if ((flags = fs->st(path, &size, &t)) == 0) {
1878     MG_ERROR(("%lu stat(%s): %d", d->c->id, path, errno));
1879   } else {
1880     const char *slash = flags & MG_FS_DIR ? "/" : "";
1881     if (flags & MG_FS_DIR) {
1882       mg_snprintf(sz, sizeof(sz), "%s", "[DIR]");
1883     } else {
1884       mg_snprintf(sz, sizeof(sz), "%lld", (uint64_t) size);
1885     }
1886 #if defined(MG_HTTP_DIRLIST_TIME_FMT)
1887     {
1888       char time_str[40];
1889       struct tm *time_info = localtime(&t);
1890       strftime(time_str, sizeof time_str, "%Y/%m/%d %H:%M:%S", time_info);
1891       mg_snprintf(mod, sizeof(mod), "%s", time_str);
1892     }
1893 #else
1894     mg_snprintf(mod, sizeof(mod), "%lu", (unsigned long) t);
1895 #endif
1896     n = (int) mg_url_encode(name, strlen(name), path, sizeof(path));
1897     mg_printf(d->c,
1898               "  <tr><td><a href=\"%.*s%s\">%s%s</a></td>"
1899               "<td name=%lu>%s</td><td name=%lld>%s</td></tr>\n",
1900               n, path, slash, name, slash, (unsigned long) t, mod,
1901               flags & MG_FS_DIR ? (int64_t) -1 : (int64_t) size, sz);
1902   }
1903 }
1904
1905 static void listdir(struct mg_connection *c, struct mg_http_message *hm,
1906                     const struct mg_http_serve_opts *opts, char *dir) {
1907   const char *sort_js_code =
1908       "<script>function srt(tb, sc, so, d) {"
1909       "var tr = Array.prototype.slice.call(tb.rows, 0),"
1910       "tr = tr.sort(function (a, b) { var c1 = a.cells[sc], c2 = b.cells[sc],"
1911       "n1 = c1.getAttribute('name'), n2 = c2.getAttribute('name'), "
1912       "t1 = a.cells[2].getAttribute('name'), "
1913       "t2 = b.cells[2].getAttribute('name'); "
1914       "return so * (t1 < 0 && t2 >= 0 ? -1 : t2 < 0 && t1 >= 0 ? 1 : "
1915       "n1 ? parseInt(n2) - parseInt(n1) : "
1916       "c1.textContent.trim().localeCompare(c2.textContent.trim())); });";
1917   const char *sort_js_code2 =
1918       "for (var i = 0; i < tr.length; i++) tb.appendChild(tr[i]); "
1919       "if (!d) window.location.hash = ('sc=' + sc + '&so=' + so); "
1920       "};"
1921       "window.onload = function() {"
1922       "var tb = document.getElementById('tb');"
1923       "var m = /sc=([012]).so=(1|-1)/.exec(window.location.hash) || [0, 2, 1];"
1924       "var sc = m[1], so = m[2]; document.onclick = function(ev) { "
1925       "var c = ev.target.rel; if (c) {if (c == sc) so *= -1; srt(tb, c, so); "
1926       "sc = c; ev.preventDefault();}};"
1927       "srt(tb, sc, so, true);"
1928       "}"
1929       "</script>";
1930   struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
1931   struct printdirentrydata d = {c, hm, opts, dir};
1932   char tmp[10], buf[MG_PATH_MAX];
1933   size_t off, n;
1934   int len = mg_url_decode(hm->uri.ptr, hm->uri.len, buf, sizeof(buf), 0);
1935   struct mg_str uri = len > 0 ? mg_str_n(buf, (size_t) len) : hm->uri;
1936
1937   mg_printf(c,
1938             "HTTP/1.1 200 OK\r\n"
1939             "Content-Type: text/html; charset=utf-8\r\n"
1940             "%s"
1941             "Content-Length:         \r\n\r\n",
1942             opts->extra_headers == NULL ? "" : opts->extra_headers);
1943   off = c->send.len;  // Start of body
1944   mg_printf(c,
1945             "<!DOCTYPE html><html><head><title>Index of %.*s</title>%s%s"
1946             "<style>th,td {text-align: left; padding-right: 1em; "
1947             "font-family: monospace; }</style></head>"
1948             "<body><h1>Index of %.*s</h1><table cellpadding=\"0\"><thead>"
1949             "<tr><th><a href=\"#\" rel=\"0\">Name</a></th><th>"
1950             "<a href=\"#\" rel=\"1\">Modified</a></th>"
1951             "<th><a href=\"#\" rel=\"2\">Size</a></th></tr>"
1952             "<tr><td colspan=\"3\"><hr></td></tr>"
1953             "</thead>"
1954             "<tbody id=\"tb\">\n",
1955             (int) uri.len, uri.ptr, sort_js_code, sort_js_code2, (int) uri.len,
1956             uri.ptr);
1957   mg_printf(c, "%s",
1958             "  <tr><td><a href=\"..\">..</a></td>"
1959             "<td name=-1></td><td name=-1>[DIR]</td></tr>\n");
1960
1961   fs->ls(dir, printdirentry, &d);
1962   mg_printf(c,
1963             "</tbody><tfoot><tr><td colspan=\"3\"><hr></td></tr></tfoot>"
1964             "</table><address>Mongoose v.%s</address></body></html>\n",
1965             MG_VERSION);
1966   n = mg_snprintf(tmp, sizeof(tmp), "%lu", (unsigned long) (c->send.len - off));
1967   if (n > sizeof(tmp)) n = 0;
1968   memcpy(c->send.buf + off - 12, tmp, n);  // Set content length
1969   c->is_resp = 0;                          // Mark response end
1970 }
1971 #endif
1972
1973 // Resolve requested file into `path` and return its fs->st() result
1974 static int uri_to_path2(struct mg_connection *c, struct mg_http_message *hm,
1975                         struct mg_fs *fs, struct mg_str url, struct mg_str dir,
1976                         char *path, size_t path_size) {
1977   int flags, tmp;
1978   // Append URI to the root_dir, and sanitize it
1979   size_t n = mg_snprintf(path, path_size, "%.*s", (int) dir.len, dir.ptr);
1980   if (n + 2 >= path_size) {
1981     mg_http_reply(c, 400, "", "Exceeded path size");
1982     return -1;
1983   }
1984   path[path_size - 1] = '\0';
1985   // Terminate root dir with slash
1986   if (n > 0 && path[n - 1] != '/') path[n++] = '/', path[n] = '\0';
1987   if (url.len < hm->uri.len) {
1988     mg_url_decode(hm->uri.ptr + url.len, hm->uri.len - url.len, path + n,
1989                   path_size - n, 0);
1990   }
1991   path[path_size - 1] = '\0';  // Double-check
1992   if (!mg_path_is_sane(path)) {
1993     mg_http_reply(c, 400, "", "Invalid path");
1994     return -1;
1995   }
1996   n = strlen(path);
1997   while (n > 1 && path[n - 1] == '/') path[--n] = 0;  // Trim trailing slashes
1998   flags = mg_vcmp(&hm->uri, "/") == 0 ? MG_FS_DIR : fs->st(path, NULL, NULL);
1999   MG_VERBOSE(("%lu %.*s -> %s %d", c->id, (int) hm->uri.len, hm->uri.ptr, path,
2000               flags));
2001   if (flags == 0) {
2002     // Do nothing - let's caller decide
2003   } else if ((flags & MG_FS_DIR) && hm->uri.len > 0 &&
2004              hm->uri.ptr[hm->uri.len - 1] != '/') {
2005     mg_printf(c,
2006               "HTTP/1.1 301 Moved\r\n"
2007               "Location: %.*s/\r\n"
2008               "Content-Length: 0\r\n"
2009               "\r\n",
2010               (int) hm->uri.len, hm->uri.ptr);
2011     c->is_resp = 0;
2012     flags = -1;
2013   } else if (flags & MG_FS_DIR) {
2014     if (((mg_snprintf(path + n, path_size - n, "/" MG_HTTP_INDEX) > 0 &&
2015           (tmp = fs->st(path, NULL, NULL)) != 0) ||
2016          (mg_snprintf(path + n, path_size - n, "/index.shtml") > 0 &&
2017           (tmp = fs->st(path, NULL, NULL)) != 0))) {
2018       flags = tmp;
2019     } else if ((mg_snprintf(path + n, path_size - n, "/" MG_HTTP_INDEX ".gz") >
2020                     0 &&
2021                 (tmp = fs->st(path, NULL, NULL)) !=
2022                     0)) {  // check for gzipped index
2023       flags = tmp;
2024       path[n + 1 + strlen(MG_HTTP_INDEX)] =
2025           '\0';  // Remove appended .gz in index file name
2026     } else {
2027       path[n] = '\0';  // Remove appended index file name
2028     }
2029   }
2030   return flags;
2031 }
2032
2033 static int uri_to_path(struct mg_connection *c, struct mg_http_message *hm,
2034                        const struct mg_http_serve_opts *opts, char *path,
2035                        size_t path_size) {
2036   struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
2037   struct mg_str k, v, s = mg_str(opts->root_dir), u = {0, 0}, p = {0, 0};
2038   while (mg_commalist(&s, &k, &v)) {
2039     if (v.len == 0) v = k, k = mg_str("/"), u = k, p = v;
2040     if (hm->uri.len < k.len) continue;
2041     if (mg_strcmp(k, mg_str_n(hm->uri.ptr, k.len)) != 0) continue;
2042     u = k, p = v;
2043   }
2044   return uri_to_path2(c, hm, fs, u, p, path, path_size);
2045 }
2046
2047 void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
2048                        const struct mg_http_serve_opts *opts) {
2049   char path[MG_PATH_MAX];
2050   const char *sp = opts->ssi_pattern;
2051   int flags = uri_to_path(c, hm, opts, path, sizeof(path));
2052   if (flags < 0) {
2053     // Do nothing: the response has already been sent by uri_to_path()
2054   } else if (flags & MG_FS_DIR) {
2055 #if MG_ENABLE_DIRLIST
2056     listdir(c, hm, opts, path);
2057 #else
2058     mg_http_reply(c, 403, "", "Forbidden\n");
2059 #endif
2060   } else if (flags && sp != NULL &&
2061              mg_globmatch(sp, strlen(sp), path, strlen(path))) {
2062     mg_http_serve_ssi(c, opts->root_dir, path);
2063   } else {
2064     mg_http_serve_file(c, hm, path, opts);
2065   }
2066 }
2067
2068 static bool mg_is_url_safe(int c) {
2069   return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
2070          (c >= 'A' && c <= 'Z') || c == '.' || c == '_' || c == '-' || c == '~';
2071 }
2072
2073 size_t mg_url_encode(const char *s, size_t sl, char *buf, size_t len) {
2074   size_t i, n = 0;
2075   for (i = 0; i < sl; i++) {
2076     int c = *(unsigned char *) &s[i];
2077     if (n + 4 >= len) return 0;
2078     if (mg_is_url_safe(c)) {
2079       buf[n++] = s[i];
2080     } else {
2081       buf[n++] = '%';
2082       mg_hex(&s[i], 1, &buf[n]);
2083       n += 2;
2084     }
2085   }
2086   if (len > 0 && n < len - 1) buf[n] = '\0';  // Null-terminate the destination
2087   if (len > 0) buf[len - 1] = '\0';           // Always.
2088   return n;
2089 }
2090
2091 void mg_http_creds(struct mg_http_message *hm, char *user, size_t userlen,
2092                    char *pass, size_t passlen) {
2093   struct mg_str *v = mg_http_get_header(hm, "Authorization");
2094   user[0] = pass[0] = '\0';
2095   if (v != NULL && v->len > 6 && memcmp(v->ptr, "Basic ", 6) == 0) {
2096     char buf[256];
2097     int n = mg_base64_decode(v->ptr + 6, (int) v->len - 6, buf);
2098     const char *p = (const char *) memchr(buf, ':', n > 0 ? (size_t) n : 0);
2099     if (p != NULL) {
2100       mg_snprintf(user, userlen, "%.*s", (int) (p - buf), buf);
2101       mg_snprintf(pass, passlen, "%.*s", n - (int) (p - buf) - 1, p + 1);
2102     }
2103   } else if (v != NULL && v->len > 7 && memcmp(v->ptr, "Bearer ", 7) == 0) {
2104     mg_snprintf(pass, passlen, "%.*s", (int) v->len - 7, v->ptr + 7);
2105   } else if ((v = mg_http_get_header(hm, "Cookie")) != NULL) {
2106     struct mg_str t = mg_http_get_header_var(*v, mg_str_n("access_token", 12));
2107     if (t.len > 0) mg_snprintf(pass, passlen, "%.*s", (int) t.len, t.ptr);
2108   } else {
2109     mg_http_get_var(&hm->query, "access_token", pass, passlen);
2110   }
2111 }
2112
2113 static struct mg_str stripquotes(struct mg_str s) {
2114   return s.len > 1 && s.ptr[0] == '"' && s.ptr[s.len - 1] == '"'
2115              ? mg_str_n(s.ptr + 1, s.len - 2)
2116              : s;
2117 }
2118
2119 struct mg_str mg_http_get_header_var(struct mg_str s, struct mg_str v) {
2120   size_t i;
2121   for (i = 0; v.len > 0 && i + v.len + 2 < s.len; i++) {
2122     if (s.ptr[i + v.len] == '=' && memcmp(&s.ptr[i], v.ptr, v.len) == 0) {
2123       const char *p = &s.ptr[i + v.len + 1], *b = p, *x = &s.ptr[s.len];
2124       int q = p < x && *p == '"' ? 1 : 0;
2125       while (p < x &&
2126              (q ? p == b || *p != '"' : *p != ';' && *p != ' ' && *p != ','))
2127         p++;
2128       // MG_INFO(("[%.*s] [%.*s] [%.*s]", (int) s.len, s.ptr, (int) v.len,
2129       // v.ptr, (int) (p - b), b));
2130       return stripquotes(mg_str_n(b, (size_t) (p - b + q)));
2131     }
2132   }
2133   return mg_str_n(NULL, 0);
2134 }
2135
2136 bool mg_http_match_uri(const struct mg_http_message *hm, const char *glob) {
2137   return mg_match(hm->uri, mg_str(glob), NULL);
2138 }
2139
2140 long mg_http_upload(struct mg_connection *c, struct mg_http_message *hm,
2141                     struct mg_fs *fs, const char *path, size_t max_size) {
2142   char buf[20] = "0";
2143   long res = 0, offset;
2144   mg_http_get_var(&hm->query, "offset", buf, sizeof(buf));
2145   offset = strtol(buf, NULL, 0);
2146   if (hm->body.len == 0) {
2147     mg_http_reply(c, 200, "", "%ld", res);  // Nothing to write
2148   } else {
2149     struct mg_fd *fd;
2150     size_t current_size = 0;
2151     MG_DEBUG(("%s -> %d bytes @ %ld", path, (int) hm->body.len, offset));
2152     if (offset == 0) fs->rm(path);  // If offset if 0, truncate file
2153     fs->st(path, &current_size, NULL);
2154     if (offset < 0) {
2155       mg_http_reply(c, 400, "", "offset required");
2156       res = -1;
2157     } else if (offset > 0 && current_size != (size_t) offset) {
2158       mg_http_reply(c, 400, "", "%s: offset mismatch", path);
2159       res = -2;
2160     } else if ((size_t) offset + hm->body.len > max_size) {
2161       mg_http_reply(c, 400, "", "%s: over max size of %lu", path,
2162                     (unsigned long) max_size);
2163       res = -3;
2164     } else if ((fd = mg_fs_open(fs, path, MG_FS_WRITE)) == NULL) {
2165       mg_http_reply(c, 400, "", "open(%s): %d", path, errno);
2166       res = -4;
2167     } else {
2168       res = offset + (long) fs->wr(fd->fd, hm->body.ptr, hm->body.len);
2169       mg_fs_close(fd);
2170       mg_http_reply(c, 200, "", "%ld", res);
2171     }
2172   }
2173   return res;
2174 }
2175
2176 int mg_http_status(const struct mg_http_message *hm) {
2177   return atoi(hm->uri.ptr);
2178 }
2179
2180 // If a server sends data to the client using chunked encoding, Mongoose strips
2181 // off the chunking prefix (hex length and \r\n) and suffix (\r\n), appends the
2182 // stripped data to the body, and fires the MG_EV_HTTP_CHUNK event.  When zero
2183 // chunk is received, we fire MG_EV_HTTP_MSG, and the body already has all
2184 // chunking prefixes/suffixes stripped.
2185 //
2186 // If a server sends data without chunked encoding, we also fire a series of
2187 // MG_EV_HTTP_CHUNK events for every received piece of data, and then we fire
2188 // MG_EV_HTTP_MSG event in the end.
2189 //
2190 // We track total processed length in the c->pfn_data, which is a void *
2191 // pointer: we store a size_t value there.
2192 static bool getchunk(struct mg_str s, size_t *prefixlen, size_t *datalen) {
2193   size_t i = 0, n;
2194   while (i < s.len && s.ptr[i] != '\r' && s.ptr[i] != '\n') i++;
2195   n = mg_unhexn(s.ptr, i);
2196   // MG_INFO(("%d %d", (int) (i + n + 4), (int) s.len));
2197   if (s.len < i + n + 4) return false;  // Chunk not yet fully buffered
2198   if (s.ptr[i] != '\r' || s.ptr[i + 1] != '\n') return false;
2199   if (s.ptr[i + n + 2] != '\r' || s.ptr[i + n + 3] != '\n') return false;
2200   *prefixlen = i + 2;
2201   *datalen = n;
2202   return true;
2203 }
2204
2205 static bool mg_is_chunked(struct mg_http_message *hm) {
2206   const char *needle = "chunked";
2207   struct mg_str *te = mg_http_get_header(hm, "Transfer-Encoding");
2208   return te != NULL && mg_vcasecmp(te, needle) == 0;
2209 }
2210
2211 void mg_http_delete_chunk(struct mg_connection *c, struct mg_http_message *hm) {
2212   size_t ofs = (size_t) (hm->chunk.ptr - (char *) c->recv.buf);
2213   mg_iobuf_del(&c->recv, ofs, hm->chunk.len);
2214   c->pfn_data = (void *) ((size_t) c->pfn_data | MG_DMARK);
2215 }
2216
2217 static void deliver_chunked_chunks(struct mg_connection *c, size_t hlen,
2218                                    struct mg_http_message *hm, bool *next) {
2219   //  |  ... headers ... | HEXNUM\r\n ..data.. \r\n | ......
2220   //  +------------------+--------------------------+----
2221   //  |      hlen        |           chunk1         | ......
2222   char *buf = (char *) &c->recv.buf[hlen], *p = buf;
2223   size_t len = c->recv.len - hlen;
2224   size_t processed = ((size_t) c->pfn_data) & ~MG_DMARK;
2225   size_t mark, pl, dl, del = 0, ofs = 0;
2226   bool last = false;
2227   if (processed <= len) len -= processed, buf += processed;
2228   while (!last && getchunk(mg_str_n(buf + ofs, len - ofs), &pl, &dl)) {
2229     size_t saved = c->recv.len;
2230     memmove(p + processed, buf + ofs + pl, dl);
2231     // MG_INFO(("P2 [%.*s]", (int) (processed + dl), p));
2232     hm->chunk = mg_str_n(p + processed, dl);
2233     mg_call(c, MG_EV_HTTP_CHUNK, hm);
2234     ofs += pl + dl + 2, del += pl + 2;  // 2 is for \r\n suffix
2235     processed += dl;
2236     if (c->recv.len != saved) processed -= dl, buf -= dl;
2237     // mg_hexdump(c->recv.buf, hlen + processed);
2238     last = (dl == 0);
2239   }
2240   mg_iobuf_del(&c->recv, hlen + processed, del);
2241   mark = ((size_t) c->pfn_data) & MG_DMARK;
2242   c->pfn_data = (void *) (processed | mark);
2243   if (last) {
2244     hm->body.len = processed;
2245     hm->message.len = hlen + processed;
2246     c->pfn_data = NULL;
2247     if (mark) mg_iobuf_del(&c->recv, 0, hlen), *next = true;
2248     // MG_INFO(("LAST, mark: %lx", mark));
2249     // mg_hexdump(c->recv.buf, c->recv.len);
2250   }
2251 }
2252
2253 static void deliver_normal_chunks(struct mg_connection *c, size_t hlen,
2254                                   struct mg_http_message *hm, bool *next) {
2255   size_t left, processed = ((size_t) c->pfn_data) & ~MG_DMARK;
2256   size_t deleted = ((size_t) c->pfn_data) & MG_DMARK;
2257   hm->chunk = mg_str_n((char *) &c->recv.buf[hlen], c->recv.len - hlen);
2258   if (processed <= hm->chunk.len && !deleted) {
2259     hm->chunk.len -= processed;
2260     hm->chunk.ptr += processed;
2261   }
2262   left = hm->body.len < processed ? 0 : hm->body.len - processed;
2263   if (hm->chunk.len > left) hm->chunk.len = left;
2264   if (hm->chunk.len > 0) mg_call(c, MG_EV_HTTP_CHUNK, hm);
2265   processed += hm->chunk.len;
2266   deleted = ((size_t) c->pfn_data) & MG_DMARK;  // Re-evaluate after user call
2267   if (processed >= hm->body.len) {              // Last, 0-len chunk
2268     hm->chunk.len = 0;                          // Reset length
2269     mg_call(c, MG_EV_HTTP_CHUNK, hm);           // Call user handler
2270     c->pfn_data = NULL;                         // Reset processed counter
2271     if (processed && deleted) mg_iobuf_del(&c->recv, 0, hlen), *next = true;
2272   } else {
2273     c->pfn_data = (void *) (processed | deleted);  // if it is set
2274   }
2275 }
2276
2277 static void http_cb(struct mg_connection *c, int ev, void *evd, void *fnd) {
2278   if (ev == MG_EV_READ || ev == MG_EV_CLOSE) {
2279     struct mg_http_message hm;
2280     while (c->recv.buf != NULL && c->recv.len > 0) {
2281       bool next = false;
2282       int hlen = mg_http_parse((char *) c->recv.buf, c->recv.len, &hm);
2283       if (hlen < 0) {
2284         mg_error(c, "HTTP parse:\n%.*s", (int) c->recv.len, c->recv.buf);
2285         break;
2286       }
2287       if (c->is_resp) break;           // Response is still generated
2288       if (hlen == 0) break;            // Request is not buffered yet
2289       if (ev == MG_EV_CLOSE) {         // If client did not set Content-Length
2290         hm.message.len = c->recv.len;  // and closes now, deliver a MSG
2291         hm.body.len = hm.message.len - (size_t) (hm.body.ptr - hm.message.ptr);
2292       }
2293       if (mg_is_chunked(&hm)) {
2294         deliver_chunked_chunks(c, (size_t) hlen, &hm, &next);
2295       } else {
2296         deliver_normal_chunks(c, (size_t) hlen, &hm, &next);
2297       }
2298       if (next) continue;  // Chunks & request were deleted
2299       //  Chunk events are delivered. If we have full body, deliver MSG
2300       if (c->recv.len < hm.message.len) break;
2301       if (c->is_accepted) c->is_resp = 1;  // Start generating response
2302       mg_call(c, MG_EV_HTTP_MSG, &hm);     // User handler can clear is_resp
2303       mg_iobuf_del(&c->recv, 0, hm.message.len);
2304     }
2305   }
2306   (void) evd, (void) fnd;
2307 }
2308
2309 static void mg_hfn(struct mg_connection *c, int ev, void *ev_data, void *fnd) {
2310   if (ev == MG_EV_HTTP_MSG) {
2311     struct mg_http_message *hm = (struct mg_http_message *) ev_data;
2312     if (mg_http_match_uri(hm, "/quit")) {
2313       mg_http_reply(c, 200, "", "ok\n");
2314       c->is_draining = 1;
2315       c->data[0] = 'X';
2316     } else if (mg_http_match_uri(hm, "/debug")) {
2317       int level = (int) mg_json_get_long(hm->body, "$.level", MG_LL_DEBUG);
2318       mg_log_set(level);
2319       mg_http_reply(c, 200, "", "Debug level set to %d\n", level);
2320     } else {
2321       mg_http_reply(c, 200, "", "hi\n");
2322     }
2323   } else if (ev == MG_EV_CLOSE) {
2324     if (c->data[0] == 'X') *(bool *) fnd = true;
2325   }
2326 }
2327
2328 void mg_hello(const char *url) {
2329   struct mg_mgr mgr;
2330   bool done = false;
2331   mg_mgr_init(&mgr);
2332   if (mg_http_listen(&mgr, url, mg_hfn, &done) == NULL) done = true;
2333   while (done == false) mg_mgr_poll(&mgr, 100);
2334   mg_mgr_free(&mgr);
2335 }
2336
2337 struct mg_connection *mg_http_connect(struct mg_mgr *mgr, const char *url,
2338                                       mg_event_handler_t fn, void *fn_data) {
2339   struct mg_connection *c = mg_connect(mgr, url, fn, fn_data);
2340   if (c != NULL) c->pfn = http_cb;
2341   return c;
2342 }
2343
2344 struct mg_connection *mg_http_listen(struct mg_mgr *mgr, const char *url,
2345                                      mg_event_handler_t fn, void *fn_data) {
2346   struct mg_connection *c = mg_listen(mgr, url, fn, fn_data);
2347   if (c != NULL) c->pfn = http_cb;
2348   return c;
2349 }
2350
2351 #ifdef MG_ENABLE_LINES
2352 #line 1 "src/iobuf.c"
2353 #endif
2354
2355
2356
2357
2358 // Not using memset for zeroing memory, cause it can be dropped by compiler
2359 // See https://github.com/cesanta/mongoose/pull/1265
2360 static void zeromem(volatile unsigned char *buf, size_t len) {
2361   if (buf != NULL) {
2362     while (len--) *buf++ = 0;
2363   }
2364 }
2365
2366 static size_t roundup(size_t size, size_t align) {
2367   return align == 0 ? size : (size + align - 1) / align * align;
2368 }
2369
2370 int mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) {
2371   int ok = 1;
2372   new_size = roundup(new_size, io->align);
2373   if (new_size == 0) {
2374     zeromem(io->buf, io->size);
2375     free(io->buf);
2376     io->buf = NULL;
2377     io->len = io->size = 0;
2378   } else if (new_size != io->size) {
2379     // NOTE(lsm): do not use realloc here. Use calloc/free only, to ease the
2380     // porting to some obscure platforms like FreeRTOS
2381     void *p = calloc(1, new_size);
2382     if (p != NULL) {
2383       size_t len = new_size < io->len ? new_size : io->len;
2384       if (len > 0 && io->buf != NULL) memmove(p, io->buf, len);
2385       zeromem(io->buf, io->size);
2386       free(io->buf);
2387       io->buf = (unsigned char *) p;
2388       io->size = new_size;
2389     } else {
2390       ok = 0;
2391       MG_ERROR(("%lld->%lld", (uint64_t) io->size, (uint64_t) new_size));
2392     }
2393   }
2394   return ok;
2395 }
2396
2397 int mg_iobuf_init(struct mg_iobuf *io, size_t size, size_t align) {
2398   io->buf = NULL;
2399   io->align = align;
2400   io->size = io->len = 0;
2401   return mg_iobuf_resize(io, size);
2402 }
2403
2404 size_t mg_iobuf_add(struct mg_iobuf *io, size_t ofs, const void *buf,
2405                     size_t len) {
2406   size_t new_size = roundup(io->len + len, io->align);
2407   mg_iobuf_resize(io, new_size);      // Attempt to resize
2408   if (new_size != io->size) len = 0;  // Resize failure, append nothing
2409   if (ofs < io->len) memmove(io->buf + ofs + len, io->buf + ofs, io->len - ofs);
2410   if (buf != NULL) memmove(io->buf + ofs, buf, len);
2411   if (ofs > io->len) io->len += ofs - io->len;
2412   io->len += len;
2413   return len;
2414 }
2415
2416 size_t mg_iobuf_del(struct mg_iobuf *io, size_t ofs, size_t len) {
2417   if (ofs > io->len) ofs = io->len;
2418   if (ofs + len > io->len) len = io->len - ofs;
2419   if (io->buf) memmove(io->buf + ofs, io->buf + ofs + len, io->len - ofs - len);
2420   if (io->buf) zeromem(io->buf + io->len - len, len);
2421   io->len -= len;
2422   return len;
2423 }
2424
2425 void mg_iobuf_free(struct mg_iobuf *io) {
2426   mg_iobuf_resize(io, 0);
2427 }
2428
2429 #ifdef MG_ENABLE_LINES
2430 #line 1 "src/json.c"
2431 #endif
2432
2433
2434
2435
2436 static const char *escapeseq(int esc) {
2437   return esc ? "\b\f\n\r\t\\\"" : "bfnrt\\\"";
2438 }
2439
2440 static char json_esc(int c, int esc) {
2441   const char *p, *esc1 = escapeseq(esc), *esc2 = escapeseq(!esc);
2442   for (p = esc1; *p != '\0'; p++) {
2443     if (*p == c) return esc2[p - esc1];
2444   }
2445   return 0;
2446 }
2447
2448 static int mg_pass_string(const char *s, int len) {
2449   int i;
2450   for (i = 0; i < len; i++) {
2451     if (s[i] == '\\' && i + 1 < len && json_esc(s[i + 1], 1)) {
2452       i++;
2453     } else if (s[i] == '\0') {
2454       return MG_JSON_INVALID;
2455     } else if (s[i] == '"') {
2456       return i;
2457     }
2458   }
2459   return MG_JSON_INVALID;
2460 }
2461
2462 static double mg_atod(const char *p, int len, int *numlen) {
2463   double d = 0.0;
2464   int i = 0, sign = 1;
2465
2466   // Sign
2467   if (i < len && *p == '-') {
2468     sign = -1, i++;
2469   } else if (i < len && *p == '+') {
2470     i++;
2471   }
2472
2473   // Decimal
2474   for (; i < len && p[i] >= '0' && p[i] <= '9'; i++) {
2475     d *= 10.0;
2476     d += p[i] - '0';
2477   }
2478   d *= sign;
2479
2480   // Fractional
2481   if (i < len && p[i] == '.') {
2482     double frac = 0.0, base = 0.1;
2483     i++;
2484     for (; i < len && p[i] >= '0' && p[i] <= '9'; i++) {
2485       frac += base * (p[i] - '0');
2486       base /= 10.0;
2487     }
2488     d += frac * sign;
2489   }
2490
2491   // Exponential
2492   if (i < len && (p[i] == 'e' || p[i] == 'E')) {
2493     int j, exp = 0, minus = 0;
2494     i++;
2495     if (i < len && p[i] == '-') minus = 1, i++;
2496     if (i < len && p[i] == '+') i++;
2497     while (i < len && p[i] >= '0' && p[i] <= '9' && exp < 308)
2498       exp = exp * 10 + (p[i++] - '0');
2499     if (minus) exp = -exp;
2500     for (j = 0; j < exp; j++) d *= 10.0;
2501     for (j = 0; j < -exp; j++) d /= 10.0;
2502   }
2503
2504   if (numlen != NULL) *numlen = i;
2505   return d;
2506 }
2507
2508 int mg_json_get(struct mg_str json, const char *path, int *toklen) {
2509   const char *s = json.ptr;
2510   int len = (int) json.len;
2511   enum { S_VALUE, S_KEY, S_COLON, S_COMMA_OR_EOO } expecting = S_VALUE;
2512   unsigned char nesting[MG_JSON_MAX_DEPTH];
2513   int i = 0;             // Current offset in `s`
2514   int j = 0;             // Offset in `s` we're looking for (return value)
2515   int depth = 0;         // Current depth (nesting level)
2516   int ed = 0;            // Expected depth
2517   int pos = 1;           // Current position in `path`
2518   int ci = -1, ei = -1;  // Current and expected index in array
2519
2520   if (toklen) *toklen = 0;
2521   if (path[0] != '$') return MG_JSON_INVALID;
2522
2523 #define MG_CHECKRET(x)                                  \
2524   do {                                                  \
2525     if (depth == ed && path[pos] == '\0' && ci == ei) { \
2526       if (toklen) *toklen = i - j + 1;                  \
2527       return j;                                         \
2528     }                                                   \
2529   } while (0)
2530
2531 // In the ascii table, the distance between `[` and `]` is 2.
2532 // Ditto for `{` and `}`. Hence +2 in the code below.
2533 #define MG_EOO(x)                                            \
2534   do {                                                       \
2535     if (depth == ed && ci != ei) return MG_JSON_NOT_FOUND;   \
2536     if (c != nesting[depth - 1] + 2) return MG_JSON_INVALID; \
2537     depth--;                                                 \
2538     MG_CHECKRET(x);                                          \
2539   } while (0)
2540
2541   for (i = 0; i < len; i++) {
2542     unsigned char c = ((unsigned char *) s)[i];
2543     if (c == ' ' || c == '\t' || c == '\n' || c == '\r') continue;
2544     switch (expecting) {
2545       case S_VALUE:
2546         // p("V %s [%.*s] %d %d %d %d\n", path, pos, path, depth, ed, ci, ei);
2547         if (depth == ed) j = i;
2548         if (c == '{') {
2549           if (depth >= (int) sizeof(nesting)) return MG_JSON_TOO_DEEP;
2550           if (depth == ed && path[pos] == '.' && ci == ei) {
2551             // If we start the object, reset array indices
2552             ed++, pos++, ci = ei = -1;
2553           }
2554           nesting[depth++] = c;
2555           expecting = S_KEY;
2556           break;
2557         } else if (c == '[') {
2558           if (depth >= (int) sizeof(nesting)) return MG_JSON_TOO_DEEP;
2559           if (depth == ed && path[pos] == '[' && ei == ci) {
2560             ed++, pos++, ci = 0;
2561             for (ei = 0; path[pos] != ']' && path[pos] != '\0'; pos++) {
2562               ei *= 10;
2563               ei += path[pos] - '0';
2564             }
2565             if (path[pos] != 0) pos++;
2566           }
2567           nesting[depth++] = c;
2568           break;
2569         } else if (c == ']' && depth > 0) {  // Empty array
2570           MG_EOO(']');
2571         } else if (c == 't' && i + 3 < len && memcmp(&s[i], "true", 4) == 0) {
2572           i += 3;
2573         } else if (c == 'n' && i + 3 < len && memcmp(&s[i], "null", 4) == 0) {
2574           i += 3;
2575         } else if (c == 'f' && i + 4 < len && memcmp(&s[i], "false", 5) == 0) {
2576           i += 4;
2577         } else if (c == '-' || ((c >= '0' && c <= '9'))) {
2578           int numlen = 0;
2579           mg_atod(&s[i], len - i, &numlen);
2580           i += numlen - 1;
2581         } else if (c == '"') {
2582           int n = mg_pass_string(&s[i + 1], len - i - 1);
2583           if (n < 0) return n;
2584           i += n + 1;
2585         } else {
2586           return MG_JSON_INVALID;
2587         }
2588         MG_CHECKRET('V');
2589         if (depth == ed && ei >= 0) ci++;
2590         expecting = S_COMMA_OR_EOO;
2591         break;
2592
2593       case S_KEY:
2594         if (c == '"') {
2595           int n = mg_pass_string(&s[i + 1], len - i - 1);
2596           if (n < 0) return n;
2597           if (i + 1 + n >= len) return MG_JSON_NOT_FOUND;
2598           if (depth < ed) return MG_JSON_NOT_FOUND;
2599           if (depth == ed && path[pos - 1] != '.') return MG_JSON_NOT_FOUND;
2600           // printf("K %s [%.*s] [%.*s] %d %d %d %d %d\n", path, pos, path, n,
2601           //        &s[i + 1], n, depth, ed, ci, ei);
2602           //  NOTE(cpq): in the check sequence below is important.
2603           //  strncmp() must go first: it fails fast if the remaining length of
2604           //  the path is smaller than `n`.
2605           if (depth == ed && path[pos - 1] == '.' &&
2606               strncmp(&s[i + 1], &path[pos], (size_t) n) == 0 &&
2607               (path[pos + n] == '\0' || path[pos + n] == '.' ||
2608                path[pos + n] == '[')) {
2609             pos += n;
2610           }
2611           i += n + 1;
2612           expecting = S_COLON;
2613         } else if (c == '}') {  // Empty object
2614           MG_EOO('}');
2615           expecting = S_COMMA_OR_EOO;
2616           if (depth == ed && ei >= 0) ci++;
2617         } else {
2618           return MG_JSON_INVALID;
2619         }
2620         break;
2621
2622       case S_COLON:
2623         if (c == ':') {
2624           expecting = S_VALUE;
2625         } else {
2626           return MG_JSON_INVALID;
2627         }
2628         break;
2629
2630       case S_COMMA_OR_EOO:
2631         if (depth <= 0) {
2632           return MG_JSON_INVALID;
2633         } else if (c == ',') {
2634           expecting = (nesting[depth - 1] == '{') ? S_KEY : S_VALUE;
2635         } else if (c == ']' || c == '}') {
2636           if (depth == ed && c == '}' && path[pos - 1] == '.')
2637             return MG_JSON_NOT_FOUND;
2638           if (depth == ed && c == ']' && path[pos - 1] == ',')
2639             return MG_JSON_NOT_FOUND;
2640           MG_EOO('O');
2641           if (depth == ed && ei >= 0) ci++;
2642         } else {
2643           return MG_JSON_INVALID;
2644         }
2645         break;
2646     }
2647   }
2648   return MG_JSON_NOT_FOUND;
2649 }
2650
2651 bool mg_json_get_num(struct mg_str json, const char *path, double *v) {
2652   int n, toklen, found = 0;
2653   if ((n = mg_json_get(json, path, &toklen)) >= 0 &&
2654       (json.ptr[n] == '-' || (json.ptr[n] >= '0' && json.ptr[n] <= '9'))) {
2655     if (v != NULL) *v = mg_atod(json.ptr + n, toklen, NULL);
2656     found = 1;
2657   }
2658   return found;
2659 }
2660
2661 bool mg_json_get_bool(struct mg_str json, const char *path, bool *v) {
2662   int found = 0, off = mg_json_get(json, path, NULL);
2663   if (off >= 0 && (json.ptr[off] == 't' || json.ptr[off] == 'f')) {
2664     if (v != NULL) *v = json.ptr[off] == 't';
2665     found = 1;
2666   }
2667   return found;
2668 }
2669
2670 bool mg_json_unescape(struct mg_str s, char *to, size_t n) {
2671   size_t i, j;
2672   for (i = 0, j = 0; i < s.len && j < n; i++, j++) {
2673     if (s.ptr[i] == '\\' && i + 5 < s.len && s.ptr[i + 1] == 'u') {
2674       //  \uXXXX escape. We could process a simple one-byte chars
2675       // \u00xx from the ASCII range. More complex chars would require
2676       // dragging in a UTF8 library, which is too much for us
2677       if (s.ptr[i + 2] != '0' || s.ptr[i + 3] != '0') return false;  // Give up
2678       ((unsigned char *) to)[j] = (unsigned char) mg_unhexn(s.ptr + i + 4, 2);
2679
2680       i += 5;
2681     } else if (s.ptr[i] == '\\' && i + 1 < s.len) {
2682       char c = json_esc(s.ptr[i + 1], 0);
2683       if (c == 0) return false;
2684       to[j] = c;
2685       i++;
2686     } else {
2687       to[j] = s.ptr[i];
2688     }
2689   }
2690   if (j >= n) return false;
2691   if (n > 0) to[j] = '\0';
2692   return true;
2693 }
2694
2695 char *mg_json_get_str(struct mg_str json, const char *path) {
2696   char *result = NULL;
2697   int len = 0, off = mg_json_get(json, path, &len);
2698   if (off >= 0 && len > 1 && json.ptr[off] == '"') {
2699     if ((result = (char *) calloc(1, (size_t) len)) != NULL &&
2700         !mg_json_unescape(mg_str_n(json.ptr + off + 1, (size_t) (len - 2)),
2701                           result, (size_t) len)) {
2702       free(result);
2703       result = NULL;
2704     }
2705   }
2706   return result;
2707 }
2708
2709 char *mg_json_get_b64(struct mg_str json, const char *path, int *slen) {
2710   char *result = NULL;
2711   int len = 0, off = mg_json_get(json, path, &len);
2712   if (off >= 0 && json.ptr[off] == '"' && len > 1 &&
2713       (result = (char *) calloc(1, (size_t) len)) != NULL) {
2714     int k = mg_base64_decode(json.ptr + off + 1, len - 2, result);
2715     if (slen != NULL) *slen = k;
2716   }
2717   return result;
2718 }
2719
2720 char *mg_json_get_hex(struct mg_str json, const char *path, int *slen) {
2721   char *result = NULL;
2722   int len = 0, off = mg_json_get(json, path, &len);
2723   if (off >= 0 && json.ptr[off] == '"' && len > 1 &&
2724       (result = (char *) calloc(1, (size_t) len / 2)) != NULL) {
2725     mg_unhex(json.ptr + off + 1, (size_t) (len - 2), (uint8_t *) result);
2726     result[len / 2 - 1] = '\0';
2727     if (slen != NULL) *slen = len / 2 - 1;
2728   }
2729   return result;
2730 }
2731
2732 long mg_json_get_long(struct mg_str json, const char *path, long dflt) {
2733   double dv;
2734   long result = dflt;
2735   if (mg_json_get_num(json, path, &dv)) result = (long) dv;
2736   return result;
2737 }
2738
2739 #ifdef MG_ENABLE_LINES
2740 #line 1 "src/log.c"
2741 #endif
2742
2743
2744
2745
2746
2747 static int s_level = MG_LL_INFO;
2748 static mg_pfn_t s_log_func = mg_pfn_stdout;
2749 static void *s_log_func_param = NULL;
2750
2751 void mg_log_set_fn(mg_pfn_t fn, void *param) {
2752   s_log_func = fn;
2753   s_log_func_param = param;
2754 }
2755
2756 static void logc(unsigned char c) {
2757   s_log_func((char) c, s_log_func_param);
2758 }
2759
2760 static void logs(const char *buf, size_t len) {
2761   size_t i;
2762   for (i = 0; i < len; i++) logc(((unsigned char *) buf)[i]);
2763 }
2764
2765 void mg_log_set(int log_level) {
2766   MG_DEBUG(("Setting log level to %d", log_level));
2767   s_level = log_level;
2768 }
2769
2770 bool mg_log_prefix(int level, const char *file, int line, const char *fname) {
2771   if (level <= s_level) {
2772     const char *p = strrchr(file, '/');
2773     char buf[41];
2774     size_t n;
2775     if (p == NULL) p = strrchr(file, '\\');
2776     n = mg_snprintf(buf, sizeof(buf), "%-6llx %d %s:%d:%s", mg_millis(), level,
2777                     p == NULL ? file : p + 1, line, fname);
2778     if (n > sizeof(buf) - 2) n = sizeof(buf) - 2;
2779     while (n < sizeof(buf)) buf[n++] = ' ';
2780     logs(buf, n - 1);
2781     return true;
2782   } else {
2783     return false;
2784   }
2785 }
2786
2787 void mg_log(const char *fmt, ...) {
2788   va_list ap;
2789   va_start(ap, fmt);
2790   mg_vxprintf(s_log_func, s_log_func_param, fmt, &ap);
2791   va_end(ap);
2792   logs("\r\n", 2);
2793 }
2794
2795 static unsigned char nibble(unsigned c) {
2796   return (unsigned char) (c < 10 ? c + '0' : c + 'W');
2797 }
2798
2799 #define ISPRINT(x) ((x) >= ' ' && (x) <= '~')
2800 void mg_hexdump(const void *buf, size_t len) {
2801   const unsigned char *p = (const unsigned char *) buf;
2802   unsigned char ascii[16], alen = 0;
2803   size_t i;
2804   for (i = 0; i < len; i++) {
2805     if ((i % 16) == 0) {
2806       // Print buffered ascii chars
2807       if (i > 0) logs("  ", 2), logs((char *) ascii, 16), logc('\n'), alen = 0;
2808       // Print hex address, then \t
2809       logc(nibble((i >> 12) & 15)), logc(nibble((i >> 8) & 15)),
2810           logc(nibble((i >> 4) & 15)), logc('0'), logs("   ", 3);
2811     }
2812     logc(nibble(p[i] >> 4)), logc(nibble(p[i] & 15));  // Two nibbles, e.g. c5
2813     logc(' ');                                         // Space after hex number
2814     ascii[alen++] = ISPRINT(p[i]) ? p[i] : '.';        // Add to the ascii buf
2815   }
2816   while (alen < 16) logs("   ", 3), ascii[alen++] = ' ';
2817   logs("  ", 2), logs((char *) ascii, 16), logc('\n');
2818 }
2819
2820 #ifdef MG_ENABLE_LINES
2821 #line 1 "src/md5.c"
2822 #endif
2823
2824
2825
2826 #if defined(MG_ENABLE_MD5) && MG_ENABLE_MD5
2827
2828 static void mg_byte_reverse(unsigned char *buf, unsigned longs) {
2829   if (MG_BIG_ENDIAN) {
2830     do {
2831       uint32_t t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
2832                    ((unsigned) buf[1] << 8 | buf[0]);
2833       *(uint32_t *) buf = t;
2834       buf += 4;
2835     } while (--longs);
2836   } else {
2837     (void) buf, (void) longs;  // Little endian. Do nothing
2838   }
2839 }
2840
2841 #define F1(x, y, z) (z ^ (x & (y ^ z)))
2842 #define F2(x, y, z) F1(z, x, y)
2843 #define F3(x, y, z) (x ^ y ^ z)
2844 #define F4(x, y, z) (y ^ (x | ~z))
2845
2846 #define MD5STEP(f, w, x, y, z, data, s) \
2847   (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x)
2848
2849 /*
2850  * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
2851  * initialization constants.
2852  */
2853 void mg_md5_init(mg_md5_ctx *ctx) {
2854   ctx->buf[0] = 0x67452301;
2855   ctx->buf[1] = 0xefcdab89;
2856   ctx->buf[2] = 0x98badcfe;
2857   ctx->buf[3] = 0x10325476;
2858
2859   ctx->bits[0] = 0;
2860   ctx->bits[1] = 0;
2861 }
2862
2863 static void mg_md5_transform(uint32_t buf[4], uint32_t const in[16]) {
2864   uint32_t a, b, c, d;
2865
2866   a = buf[0];
2867   b = buf[1];
2868   c = buf[2];
2869   d = buf[3];
2870
2871   MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
2872   MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
2873   MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
2874   MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
2875   MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
2876   MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
2877   MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
2878   MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
2879   MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
2880   MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
2881   MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
2882   MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
2883   MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
2884   MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
2885   MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
2886   MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
2887
2888   MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
2889   MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
2890   MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
2891   MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
2892   MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
2893   MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
2894   MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
2895   MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
2896   MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
2897   MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
2898   MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
2899   MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
2900   MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
2901   MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
2902   MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
2903   MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
2904
2905   MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
2906   MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
2907   MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
2908   MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
2909   MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
2910   MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
2911   MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
2912   MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
2913   MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
2914   MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
2915   MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
2916   MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
2917   MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
2918   MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
2919   MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
2920   MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
2921
2922   MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
2923   MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
2924   MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
2925   MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
2926   MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
2927   MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
2928   MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
2929   MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
2930   MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
2931   MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
2932   MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
2933   MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
2934   MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
2935   MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
2936   MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
2937   MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
2938
2939   buf[0] += a;
2940   buf[1] += b;
2941   buf[2] += c;
2942   buf[3] += d;
2943 }
2944
2945 void mg_md5_update(mg_md5_ctx *ctx, const unsigned char *buf, size_t len) {
2946   uint32_t t;
2947
2948   t = ctx->bits[0];
2949   if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) ctx->bits[1]++;
2950   ctx->bits[1] += (uint32_t) len >> 29;
2951
2952   t = (t >> 3) & 0x3f;
2953
2954   if (t) {
2955     unsigned char *p = (unsigned char *) ctx->in + t;
2956
2957     t = 64 - t;
2958     if (len < t) {
2959       memcpy(p, buf, len);
2960       return;
2961     }
2962     memcpy(p, buf, t);
2963     mg_byte_reverse(ctx->in, 16);
2964     mg_md5_transform(ctx->buf, (uint32_t *) ctx->in);
2965     buf += t;
2966     len -= t;
2967   }
2968
2969   while (len >= 64) {
2970     memcpy(ctx->in, buf, 64);
2971     mg_byte_reverse(ctx->in, 16);
2972     mg_md5_transform(ctx->buf, (uint32_t *) ctx->in);
2973     buf += 64;
2974     len -= 64;
2975   }
2976
2977   memcpy(ctx->in, buf, len);
2978 }
2979
2980 void mg_md5_final(mg_md5_ctx *ctx, unsigned char digest[16]) {
2981   unsigned count;
2982   unsigned char *p;
2983   uint32_t *a;
2984
2985   count = (ctx->bits[0] >> 3) & 0x3F;
2986
2987   p = ctx->in + count;
2988   *p++ = 0x80;
2989   count = 64 - 1 - count;
2990   if (count < 8) {
2991     memset(p, 0, count);
2992     mg_byte_reverse(ctx->in, 16);
2993     mg_md5_transform(ctx->buf, (uint32_t *) ctx->in);
2994     memset(ctx->in, 0, 56);
2995   } else {
2996     memset(p, 0, count - 8);
2997   }
2998   mg_byte_reverse(ctx->in, 14);
2999
3000   a = (uint32_t *) ctx->in;
3001   a[14] = ctx->bits[0];
3002   a[15] = ctx->bits[1];
3003
3004   mg_md5_transform(ctx->buf, (uint32_t *) ctx->in);
3005   mg_byte_reverse((unsigned char *) ctx->buf, 4);
3006   memcpy(digest, ctx->buf, 16);
3007   memset((char *) ctx, 0, sizeof(*ctx));
3008 }
3009 #endif
3010
3011 #ifdef MG_ENABLE_LINES
3012 #line 1 "src/mqtt.c"
3013 #endif
3014
3015
3016
3017
3018
3019
3020
3021
3022 #define MQTT_CLEAN_SESSION 0x02
3023 #define MQTT_HAS_WILL 0x04
3024 #define MQTT_WILL_RETAIN 0x20
3025 #define MQTT_HAS_PASSWORD 0x40
3026 #define MQTT_HAS_USER_NAME 0x80
3027
3028 struct mg_mqtt_pmap {
3029   uint8_t id;
3030   uint8_t type;
3031 };
3032
3033 static const struct mg_mqtt_pmap s_prop_map[] = {
3034     {MQTT_PROP_PAYLOAD_FORMAT_INDICATOR, MQTT_PROP_TYPE_BYTE},
3035     {MQTT_PROP_MESSAGE_EXPIRY_INTERVAL, MQTT_PROP_TYPE_INT},
3036     {MQTT_PROP_CONTENT_TYPE, MQTT_PROP_TYPE_STRING},
3037     {MQTT_PROP_RESPONSE_TOPIC, MQTT_PROP_TYPE_STRING},
3038     {MQTT_PROP_CORRELATION_DATA, MQTT_PROP_TYPE_BINARY_DATA},
3039     {MQTT_PROP_SUBSCRIPTION_IDENTIFIER, MQTT_PROP_TYPE_VARIABLE_INT},
3040     {MQTT_PROP_SESSION_EXPIRY_INTERVAL, MQTT_PROP_TYPE_INT},
3041     {MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER, MQTT_PROP_TYPE_STRING},
3042     {MQTT_PROP_SERVER_KEEP_ALIVE, MQTT_PROP_TYPE_SHORT},
3043     {MQTT_PROP_AUTHENTICATION_METHOD, MQTT_PROP_TYPE_STRING},
3044     {MQTT_PROP_AUTHENTICATION_DATA, MQTT_PROP_TYPE_BINARY_DATA},
3045     {MQTT_PROP_REQUEST_PROBLEM_INFORMATION, MQTT_PROP_TYPE_BYTE},
3046     {MQTT_PROP_WILL_DELAY_INTERVAL, MQTT_PROP_TYPE_INT},
3047     {MQTT_PROP_REQUEST_RESPONSE_INFORMATION, MQTT_PROP_TYPE_BYTE},
3048     {MQTT_PROP_RESPONSE_INFORMATION, MQTT_PROP_TYPE_STRING},
3049     {MQTT_PROP_SERVER_REFERENCE, MQTT_PROP_TYPE_STRING},
3050     {MQTT_PROP_REASON_STRING, MQTT_PROP_TYPE_STRING},
3051     {MQTT_PROP_RECEIVE_MAXIMUM, MQTT_PROP_TYPE_SHORT},
3052     {MQTT_PROP_TOPIC_ALIAS_MAXIMUM, MQTT_PROP_TYPE_SHORT},
3053     {MQTT_PROP_TOPIC_ALIAS, MQTT_PROP_TYPE_SHORT},
3054     {MQTT_PROP_MAXIMUM_QOS, MQTT_PROP_TYPE_BYTE},
3055     {MQTT_PROP_RETAIN_AVAILABLE, MQTT_PROP_TYPE_BYTE},
3056     {MQTT_PROP_USER_PROPERTY, MQTT_PROP_TYPE_STRING_PAIR},
3057     {MQTT_PROP_MAXIMUM_PACKET_SIZE, MQTT_PROP_TYPE_INT},
3058     {MQTT_PROP_WILDCARD_SUBSCRIPTION_AVAILABLE, MQTT_PROP_TYPE_BYTE},
3059     {MQTT_PROP_SUBSCRIPTION_IDENTIFIER_AVAILABLE, MQTT_PROP_TYPE_BYTE},
3060     {MQTT_PROP_SHARED_SUBSCRIPTION_AVAILABLE, MQTT_PROP_TYPE_BYTE}};
3061
3062 void mg_mqtt_send_header(struct mg_connection *c, uint8_t cmd, uint8_t flags,
3063                          uint32_t len) {
3064   uint8_t buf[1 + sizeof(len)], *vlen = &buf[1];
3065   buf[0] = (uint8_t) ((cmd << 4) | flags);
3066   do {
3067     *vlen = len % 0x80;
3068     len /= 0x80;
3069     if (len > 0) *vlen |= 0x80;
3070     vlen++;
3071   } while (len > 0 && vlen < &buf[sizeof(buf)]);
3072   mg_send(c, buf, (size_t) (vlen - buf));
3073 }
3074
3075 static void mg_send_u16(struct mg_connection *c, uint16_t value) {
3076   mg_send(c, &value, sizeof(value));
3077 }
3078
3079 static void mg_send_u32(struct mg_connection *c, uint32_t value) {
3080   mg_send(c, &value, sizeof(value));
3081 }
3082
3083 static uint8_t varint_size(size_t length) {
3084   uint8_t bytes_needed = 0;
3085   do {
3086     bytes_needed++;
3087     length /= 0x80;
3088   } while (length > 0);
3089   return bytes_needed;
3090 }
3091
3092 static size_t encode_varint(uint8_t *buf, size_t value) {
3093   size_t len = 0;
3094
3095   do {
3096     uint8_t byte = (uint8_t) (value % 128);
3097     value /= 128;
3098     if (value > 0) byte |= 0x80;
3099     buf[len++] = byte;
3100   } while (value > 0);
3101
3102   return len;
3103 }
3104
3105 static size_t decode_varint(const uint8_t *buf, size_t len, size_t *value) {
3106   size_t multiplier = 1, offset;
3107   *value = 0;
3108
3109   for (offset = 0; offset < 4 && offset < len; offset++) {
3110     uint8_t encoded_byte = buf[offset];
3111     *value += (encoded_byte & 0x7f) * multiplier;
3112     multiplier *= 128;
3113
3114     if ((encoded_byte & 0x80) == 0) return offset + 1;
3115   }
3116
3117   return 0;
3118 }
3119
3120 static int mqtt_prop_type_by_id(uint8_t prop_id) {
3121   size_t i, num_properties = sizeof(s_prop_map) / sizeof(s_prop_map[0]);
3122   for (i = 0; i < num_properties; ++i) {
3123     if (s_prop_map[i].id == prop_id) return s_prop_map[i].type;
3124   }
3125   return -1;  // Property ID not found
3126 }
3127
3128 // Returns the size of the properties section, without the
3129 // size of the content's length
3130 static size_t get_properties_length(struct mg_mqtt_prop *props, size_t count) {
3131   size_t i, size = 0;
3132   for (i = 0; i < count; i++) {
3133     size++;  // identifier
3134     switch (mqtt_prop_type_by_id(props[i].id)) {
3135       case MQTT_PROP_TYPE_STRING_PAIR:
3136         size += (uint32_t) (props[i].val.len + props[i].key.len +
3137                             2 * sizeof(uint16_t));
3138         break;
3139       case MQTT_PROP_TYPE_STRING:
3140         size += (uint32_t) (props[i].val.len + sizeof(uint16_t));
3141         break;
3142       case MQTT_PROP_TYPE_BINARY_DATA:
3143         size += (uint32_t) (props[i].val.len + sizeof(uint16_t));
3144         break;
3145       case MQTT_PROP_TYPE_VARIABLE_INT:
3146         size += varint_size((uint32_t) props[i].iv);
3147         break;
3148       case MQTT_PROP_TYPE_INT:
3149         size += (uint32_t) sizeof(uint32_t);
3150         break;
3151       case MQTT_PROP_TYPE_SHORT:
3152         size += (uint32_t) sizeof(uint16_t);
3153         break;
3154       case MQTT_PROP_TYPE_BYTE:
3155         size += (uint32_t) sizeof(uint8_t);
3156         break;
3157       default:
3158         return size;  // cannot parse further down
3159     }
3160   }
3161
3162   return size;
3163 }
3164
3165 // returns the entire size of the properties section, including the
3166 // size of the variable length of the content
3167 static size_t get_props_size(struct mg_mqtt_prop *props, size_t count) {
3168   size_t size = get_properties_length(props, count);
3169   size += varint_size(size);
3170   return size;
3171 }
3172
3173 static void mg_send_mqtt_properties(struct mg_connection *c,
3174                                     struct mg_mqtt_prop *props, size_t nprops) {
3175   size_t total_size = get_properties_length(props, nprops);
3176   uint8_t buf_v[4] = {0, 0, 0, 0};
3177   uint8_t buf[4] = {0, 0, 0, 0};
3178   size_t i, len = encode_varint(buf, total_size);
3179
3180   mg_send(c, buf, (size_t) len);
3181   for (i = 0; i < nprops; i++) {
3182     mg_send(c, &props[i].id, sizeof(props[i].id));
3183     switch (mqtt_prop_type_by_id(props[i].id)) {
3184       case MQTT_PROP_TYPE_STRING_PAIR:
3185         mg_send_u16(c, mg_htons((uint16_t) props[i].key.len));
3186         mg_send(c, props[i].key.ptr, props[i].key.len);
3187         mg_send_u16(c, mg_htons((uint16_t) props[i].val.len));
3188         mg_send(c, props[i].val.ptr, props[i].val.len);
3189         break;
3190       case MQTT_PROP_TYPE_BYTE:
3191         mg_send(c, &props[i].iv, sizeof(uint8_t));
3192         break;
3193       case MQTT_PROP_TYPE_SHORT:
3194         mg_send_u16(c, mg_htons((uint16_t) props[i].iv));
3195         break;
3196       case MQTT_PROP_TYPE_INT:
3197         mg_send_u32(c, mg_htonl((uint32_t) props[i].iv));
3198         break;
3199       case MQTT_PROP_TYPE_STRING:
3200         mg_send_u16(c, mg_htons((uint16_t) props[i].val.len));
3201         mg_send(c, props[i].val.ptr, props[i].val.len);
3202         break;
3203       case MQTT_PROP_TYPE_BINARY_DATA:
3204         mg_send_u16(c, mg_htons((uint16_t) props[i].val.len));
3205         mg_send(c, props[i].val.ptr, props[i].val.len);
3206         break;
3207       case MQTT_PROP_TYPE_VARIABLE_INT:
3208         len = encode_varint(buf_v, props[i].iv);
3209         mg_send(c, buf_v, (size_t) len);
3210         break;
3211     }
3212   }
3213 }
3214
3215 size_t mg_mqtt_next_prop(struct mg_mqtt_message *msg, struct mg_mqtt_prop *prop,
3216                          size_t ofs) {
3217   uint8_t *i = (uint8_t *) msg->dgram.ptr + msg->props_start + ofs;
3218   uint8_t *end = (uint8_t *) msg->dgram.ptr + msg->dgram.len;
3219   size_t new_pos = ofs, len;
3220   prop->id = i[0];
3221
3222   if (ofs >= msg->dgram.len || ofs >= msg->props_start + msg->props_size)
3223     return 0;
3224   i++, new_pos++;
3225
3226   switch (mqtt_prop_type_by_id(prop->id)) {
3227     case MQTT_PROP_TYPE_STRING_PAIR:
3228       prop->key.len = (uint16_t) ((((uint16_t) i[0]) << 8) | i[1]);
3229       prop->key.ptr = (char *) i + 2;
3230       i += 2 + prop->key.len;
3231       prop->val.len = (uint16_t) ((((uint16_t) i[0]) << 8) | i[1]);
3232       prop->val.ptr = (char *) i + 2;
3233       new_pos += 2 * sizeof(uint16_t) + prop->val.len + prop->key.len;
3234       break;
3235     case MQTT_PROP_TYPE_BYTE:
3236       prop->iv = (uint8_t) i[0];
3237       new_pos++;
3238       break;
3239     case MQTT_PROP_TYPE_SHORT:
3240       prop->iv = (uint16_t) ((((uint16_t) i[0]) << 8) | i[1]);
3241       new_pos += sizeof(uint16_t);
3242       break;
3243     case MQTT_PROP_TYPE_INT:
3244       prop->iv = ((uint32_t) i[0] << 24) | ((uint32_t) i[1] << 16) |
3245                  ((uint32_t) i[2] << 8) | i[3];
3246       new_pos += sizeof(uint32_t);
3247       break;
3248     case MQTT_PROP_TYPE_STRING:
3249       prop->val.len = (uint16_t) ((((uint16_t) i[0]) << 8) | i[1]);
3250       prop->val.ptr = (char *) i + 2;
3251       new_pos += 2 + prop->val.len;
3252       break;
3253     case MQTT_PROP_TYPE_BINARY_DATA:
3254       prop->val.len = (uint16_t) ((((uint16_t) i[0]) << 8) | i[1]);
3255       prop->val.ptr = (char *) i + 2;
3256       new_pos += 2 + prop->val.len;
3257       break;
3258     case MQTT_PROP_TYPE_VARIABLE_INT:
3259       len = decode_varint(i, (size_t) (end - i), (size_t *) &prop->iv);
3260       new_pos = (!len) ? 0 : new_pos + len;
3261       break;
3262     default:
3263       new_pos = 0;
3264   }
3265
3266   return new_pos;
3267 }
3268
3269 void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts) {
3270   char rnd[10], client_id[21];
3271   struct mg_str cid = opts->client_id;
3272   size_t total_len = 7 + 1 + 2 + 2;
3273   uint8_t hdr[8] = {0, 4, 'M', 'Q', 'T', 'T', opts->version, 0};
3274
3275   if (cid.len == 0) {
3276     mg_random(rnd, sizeof(rnd));
3277     mg_hex(rnd, sizeof(rnd), client_id);
3278     client_id[sizeof(client_id) - 1] = '\0';
3279     cid = mg_str(client_id);
3280   }
3281
3282   if (hdr[6] == 0) hdr[6] = 4;  // If version is not set, use 4 (3.1.1)
3283   c->is_mqtt5 = hdr[6] == 5;    // Set version 5 flag
3284   hdr[7] = (uint8_t) ((opts->qos & 3) << 3);  // Connection flags
3285   if (opts->user.len > 0) {
3286     total_len += 2 + (uint32_t) opts->user.len;
3287     hdr[7] |= MQTT_HAS_USER_NAME;
3288   }
3289   if (opts->pass.len > 0) {
3290     total_len += 2 + (uint32_t) opts->pass.len;
3291     hdr[7] |= MQTT_HAS_PASSWORD;
3292   }
3293   if (opts->topic.len > 0 && opts->message.len > 0) {
3294     total_len += 4 + (uint32_t) opts->topic.len + (uint32_t) opts->message.len;
3295     hdr[7] |= MQTT_HAS_WILL;
3296   }
3297   if (opts->clean || cid.len == 0) hdr[7] |= MQTT_CLEAN_SESSION;
3298   if (opts->retain) hdr[7] |= MQTT_WILL_RETAIN;
3299   total_len += (uint32_t) cid.len;
3300   if (c->is_mqtt5) {
3301     total_len += get_props_size(opts->props, opts->num_props);
3302     if (hdr[7] & MQTT_HAS_WILL)
3303       total_len += get_props_size(opts->will_props, opts->num_will_props);
3304   }
3305
3306   mg_mqtt_send_header(c, MQTT_CMD_CONNECT, 0, (uint32_t) total_len);
3307   mg_send(c, hdr, sizeof(hdr));
3308   // keepalive == 0 means "do not disconnect us!"
3309   mg_send_u16(c, mg_htons((uint16_t) opts->keepalive));
3310
3311   if (c->is_mqtt5) mg_send_mqtt_properties(c, opts->props, opts->num_props);
3312
3313   mg_send_u16(c, mg_htons((uint16_t) cid.len));
3314   mg_send(c, cid.ptr, cid.len);
3315
3316   if (hdr[7] & MQTT_HAS_WILL) {
3317     if (c->is_mqtt5)
3318       mg_send_mqtt_properties(c, opts->will_props, opts->num_will_props);
3319
3320     mg_send_u16(c, mg_htons((uint16_t) opts->topic.len));
3321     mg_send(c, opts->topic.ptr, opts->topic.len);
3322     mg_send_u16(c, mg_htons((uint16_t) opts->message.len));
3323     mg_send(c, opts->message.ptr, opts->message.len);
3324   }
3325   if (opts->user.len > 0) {
3326     mg_send_u16(c, mg_htons((uint16_t) opts->user.len));
3327     mg_send(c, opts->user.ptr, opts->user.len);
3328   }
3329   if (opts->pass.len > 0) {
3330     mg_send_u16(c, mg_htons((uint16_t) opts->pass.len));
3331     mg_send(c, opts->pass.ptr, opts->pass.len);
3332   }
3333 }
3334
3335 void mg_mqtt_pub(struct mg_connection *c, const struct mg_mqtt_opts *opts) {
3336   uint8_t flags = (uint8_t) (((opts->qos & 3) << 1) | (opts->retain ? 1 : 0));
3337   size_t len = 2 + opts->topic.len + opts->message.len;
3338   MG_DEBUG(("%lu [%.*s] -> [%.*s]", c->id, (int) opts->topic.len,
3339             (char *) opts->topic.ptr, (int) opts->message.len,
3340             (char *) opts->message.ptr));
3341   if (opts->qos > 0) len += 2;
3342   if (c->is_mqtt5) len += get_props_size(opts->props, opts->num_props);
3343
3344   mg_mqtt_send_header(c, MQTT_CMD_PUBLISH, flags, (uint32_t) len);
3345   mg_send_u16(c, mg_htons((uint16_t) opts->topic.len));
3346   mg_send(c, opts->topic.ptr, opts->topic.len);
3347   if (opts->qos > 0) {
3348     if (++c->mgr->mqtt_id == 0) ++c->mgr->mqtt_id;
3349     mg_send_u16(c, mg_htons(c->mgr->mqtt_id));
3350   }
3351
3352   if (c->is_mqtt5) mg_send_mqtt_properties(c, opts->props, opts->num_props);
3353
3354   mg_send(c, opts->message.ptr, opts->message.len);
3355 }
3356
3357 void mg_mqtt_sub(struct mg_connection *c, const struct mg_mqtt_opts *opts) {
3358   uint8_t qos_ = opts->qos & 3;
3359   size_t plen = c->is_mqtt5 ? get_props_size(opts->props, opts->num_props) : 0;
3360   size_t len = 2 + opts->topic.len + 2 + 1 + plen;
3361
3362   mg_mqtt_send_header(c, MQTT_CMD_SUBSCRIBE, 2, (uint32_t) len);
3363   if (++c->mgr->mqtt_id == 0) ++c->mgr->mqtt_id;
3364   mg_send_u16(c, mg_htons(c->mgr->mqtt_id));
3365   if (c->is_mqtt5) mg_send_mqtt_properties(c, opts->props, opts->num_props);
3366
3367   mg_send_u16(c, mg_htons((uint16_t) opts->topic.len));
3368   mg_send(c, opts->topic.ptr, opts->topic.len);
3369   mg_send(c, &qos_, sizeof(qos_));
3370 }
3371
3372 int mg_mqtt_parse(const uint8_t *buf, size_t len, uint8_t version,
3373                   struct mg_mqtt_message *m) {
3374   uint8_t lc = 0, *p, *end;
3375   uint32_t n = 0, len_len = 0;
3376
3377   memset(m, 0, sizeof(*m));
3378   m->dgram.ptr = (char *) buf;
3379   if (len < 2) return MQTT_INCOMPLETE;
3380   m->cmd = (uint8_t) (buf[0] >> 4);
3381   m->qos = (buf[0] >> 1) & 3;
3382
3383   n = len_len = 0;
3384   p = (uint8_t *) buf + 1;
3385   while ((size_t) (p - buf) < len) {
3386     lc = *((uint8_t *) p++);
3387     n += (uint32_t) ((lc & 0x7f) << 7 * len_len);
3388     len_len++;
3389     if (!(lc & 0x80)) break;
3390     if (len_len >= 4) return MQTT_MALFORMED;
3391   }
3392   end = p + n;
3393   if ((lc & 0x80) || (end > buf + len)) return MQTT_INCOMPLETE;
3394   m->dgram.len = (size_t) (end - buf);
3395
3396   switch (m->cmd) {
3397     case MQTT_CMD_CONNACK:
3398       if (end - p < 2) return MQTT_MALFORMED;
3399       m->ack = p[1];
3400       break;
3401     case MQTT_CMD_PUBACK:
3402     case MQTT_CMD_PUBREC:
3403     case MQTT_CMD_PUBREL:
3404     case MQTT_CMD_PUBCOMP:
3405     case MQTT_CMD_SUBSCRIBE:
3406     case MQTT_CMD_SUBACK:
3407     case MQTT_CMD_UNSUBSCRIBE:
3408     case MQTT_CMD_UNSUBACK:
3409       if (p + 2 > end) return MQTT_MALFORMED;
3410       m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
3411       p += 2;
3412       break;
3413     case MQTT_CMD_PUBLISH: {
3414       if (p + 2 > end) return MQTT_MALFORMED;
3415       m->topic.len = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
3416       m->topic.ptr = (char *) p + 2;
3417       p += 2 + m->topic.len;
3418       if (p > end) return MQTT_MALFORMED;
3419       if (m->qos > 0) {
3420         if (p + 2 > end) return MQTT_MALFORMED;
3421         m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
3422         p += 2;
3423       }
3424       if (p > end) return MQTT_MALFORMED;
3425       if (version == 5 && p + 2 < end) {
3426         len_len = (uint32_t) decode_varint(p, (size_t) (end - p), &m->props_size);
3427         if (!len_len) return MQTT_MALFORMED;
3428         m->props_start = (size_t) (p + len_len - buf);
3429         p += len_len + m->props_size;
3430       }
3431       if (p > end) return MQTT_MALFORMED;
3432       m->data.ptr = (char *) p;
3433       m->data.len = (size_t) (end - p);
3434       break;
3435     }
3436     default:
3437       break;
3438   }
3439   return MQTT_OK;
3440 }
3441
3442 static void mqtt_cb(struct mg_connection *c, int ev, void *ev_data,
3443                     void *fn_data) {
3444   if (ev == MG_EV_READ) {
3445     for (;;) {
3446       uint8_t version = c->is_mqtt5 ? 5 : 4;
3447       struct mg_mqtt_message mm;
3448       int rc = mg_mqtt_parse(c->recv.buf, c->recv.len, version, &mm);
3449       if (rc == MQTT_MALFORMED) {
3450         MG_ERROR(("%lu MQTT malformed message", c->id));
3451         c->is_closing = 1;
3452         break;
3453       } else if (rc == MQTT_OK) {
3454         MG_VERBOSE(("%lu MQTT CMD %d len %d [%.*s]", c->id, mm.cmd,
3455                     (int) mm.dgram.len, (int) mm.data.len, mm.data.ptr));
3456         switch (mm.cmd) {
3457           case MQTT_CMD_CONNACK:
3458             mg_call(c, MG_EV_MQTT_OPEN, &mm.ack);
3459             if (mm.ack == 0) {
3460               MG_DEBUG(("%lu Connected", c->id));
3461             } else {
3462               MG_ERROR(("%lu MQTT auth failed, code %d", c->id, mm.ack));
3463               c->is_closing = 1;
3464             }
3465             break;
3466           case MQTT_CMD_PUBLISH: {
3467             MG_DEBUG(("%lu [%.*s] -> [%.*s]", c->id, (int) mm.topic.len,
3468                       mm.topic.ptr, (int) mm.data.len, mm.data.ptr));
3469             if (mm.qos > 0) {
3470               uint16_t id = mg_ntohs(mm.id);
3471               uint32_t remaining_len = sizeof(id);
3472               if (c->is_mqtt5) remaining_len += 2;  // 3.4.2
3473
3474               mg_mqtt_send_header(
3475                   c,
3476                   (uint8_t) (mm.qos == 2 ? MQTT_CMD_PUBREC : MQTT_CMD_PUBACK),
3477                   0, remaining_len);
3478               mg_send(c, &id, sizeof(id));
3479
3480               if (c->is_mqtt5) {
3481                 uint16_t zero = 0;
3482                 mg_send(c, &zero, sizeof(zero));
3483               }
3484             }
3485             mg_call(c, MG_EV_MQTT_MSG, &mm);  // let the app handle qos stuff
3486             break;
3487           }
3488           case MQTT_CMD_PUBREC: {  // MQTT5: 3.5.2-1 TODO(): variable header rc
3489             uint16_t id = mg_ntohs(mm.id);
3490             uint32_t remaining_len = sizeof(id);  // MQTT5 3.6.2-1
3491             mg_mqtt_send_header(c, MQTT_CMD_PUBREL, 2, remaining_len);
3492             mg_send(c, &id, sizeof(id));  // MQTT5 3.6.1-1, flags = 2
3493             break;
3494           }
3495           case MQTT_CMD_PUBREL: {  // MQTT5: 3.6.2-1 TODO(): variable header rc
3496             uint16_t id = mg_ntohs(mm.id);
3497             uint32_t remaining_len = sizeof(id);  // MQTT5 3.7.2-1
3498             mg_mqtt_send_header(c, MQTT_CMD_PUBCOMP, 0, remaining_len);
3499             mg_send(c, &id, sizeof(id));
3500             break;
3501           }
3502         }
3503         mg_call(c, MG_EV_MQTT_CMD, &mm);
3504         mg_iobuf_del(&c->recv, 0, mm.dgram.len);
3505       } else {
3506         break;
3507       }
3508     }
3509   }
3510   (void) ev_data;
3511   (void) fn_data;
3512 }
3513
3514 void mg_mqtt_ping(struct mg_connection *nc) {
3515   mg_mqtt_send_header(nc, MQTT_CMD_PINGREQ, 0, 0);
3516 }
3517
3518 void mg_mqtt_pong(struct mg_connection *nc) {
3519   mg_mqtt_send_header(nc, MQTT_CMD_PINGRESP, 0, 0);
3520 }
3521
3522 void mg_mqtt_disconnect(struct mg_connection *c,
3523                         const struct mg_mqtt_opts *opts) {
3524   size_t len = 0;
3525   if (c->is_mqtt5) len = 1 + get_props_size(opts->props, opts->num_props);
3526   mg_mqtt_send_header(c, MQTT_CMD_DISCONNECT, 0, (uint32_t) len);
3527
3528   if (c->is_mqtt5) {
3529     uint8_t zero = 0;
3530     mg_send(c, &zero, sizeof(zero));  // reason code
3531     mg_send_mqtt_properties(c, opts->props, opts->num_props);
3532   }
3533 }
3534
3535 struct mg_connection *mg_mqtt_connect(struct mg_mgr *mgr, const char *url,
3536                                       const struct mg_mqtt_opts *opts,
3537                                       mg_event_handler_t fn, void *fn_data) {
3538   struct mg_connection *c = mg_connect(mgr, url, fn, fn_data);
3539   if (c != NULL) {
3540     struct mg_mqtt_opts empty;
3541     memset(&empty, 0, sizeof(empty));
3542     mg_mqtt_login(c, opts == NULL ? &empty : opts);
3543     c->pfn = mqtt_cb;
3544   }
3545   return c;
3546 }
3547
3548 struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url,
3549                                      mg_event_handler_t fn, void *fn_data) {
3550   struct mg_connection *c = mg_listen(mgr, url, fn, fn_data);
3551   if (c != NULL) c->pfn = mqtt_cb, c->pfn_data = mgr;
3552   return c;
3553 }
3554
3555 #ifdef MG_ENABLE_LINES
3556 #line 1 "src/net.c"
3557 #endif
3558
3559
3560
3561
3562
3563
3564
3565
3566 size_t mg_vprintf(struct mg_connection *c, const char *fmt, va_list *ap) {
3567   size_t old = c->send.len;
3568   mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
3569   return c->send.len - old;
3570 }
3571
3572 size_t mg_printf(struct mg_connection *c, const char *fmt, ...) {
3573   size_t len = 0;
3574   va_list ap;
3575   va_start(ap, fmt);
3576   len = mg_vprintf(c, fmt, &ap);
3577   va_end(ap);
3578   return len;
3579 }
3580
3581 static bool mg_atonl(struct mg_str str, struct mg_addr *addr) {
3582   uint32_t localhost = mg_htonl(0x7f000001);
3583   if (mg_vcasecmp(&str, "localhost") != 0) return false;
3584   memcpy(addr->ip, &localhost, sizeof(uint32_t));
3585   addr->is_ip6 = false;
3586   return true;
3587 }
3588
3589 static bool mg_atone(struct mg_str str, struct mg_addr *addr) {
3590   if (str.len > 0) return false;
3591   memset(addr->ip, 0, sizeof(addr->ip));
3592   addr->is_ip6 = false;
3593   return true;
3594 }
3595
3596 static bool mg_aton4(struct mg_str str, struct mg_addr *addr) {
3597   uint8_t data[4] = {0, 0, 0, 0};
3598   size_t i, num_dots = 0;
3599   for (i = 0; i < str.len; i++) {
3600     if (str.ptr[i] >= '0' && str.ptr[i] <= '9') {
3601       int octet = data[num_dots] * 10 + (str.ptr[i] - '0');
3602       if (octet > 255) return false;
3603       data[num_dots] = (uint8_t) octet;
3604     } else if (str.ptr[i] == '.') {
3605       if (num_dots >= 3 || i == 0 || str.ptr[i - 1] == '.') return false;
3606       num_dots++;
3607     } else {
3608       return false;
3609     }
3610   }
3611   if (num_dots != 3 || str.ptr[i - 1] == '.') return false;
3612   memcpy(&addr->ip, data, sizeof(data));
3613   addr->is_ip6 = false;
3614   return true;
3615 }
3616
3617 static bool mg_v4mapped(struct mg_str str, struct mg_addr *addr) {
3618   int i;
3619   uint32_t ipv4;
3620   if (str.len < 14) return false;
3621   if (str.ptr[0] != ':' || str.ptr[1] != ':' || str.ptr[6] != ':') return false;
3622   for (i = 2; i < 6; i++) {
3623     if (str.ptr[i] != 'f' && str.ptr[i] != 'F') return false;
3624   }
3625   // struct mg_str s = mg_str_n(&str.ptr[7], str.len - 7);
3626   if (!mg_aton4(mg_str_n(&str.ptr[7], str.len - 7), addr)) return false;
3627   memcpy(&ipv4, addr->ip, sizeof(ipv4));
3628   memset(addr->ip, 0, sizeof(addr->ip));
3629   addr->ip[10] = addr->ip[11] = 255;
3630   memcpy(&addr->ip[12], &ipv4, 4);
3631   addr->is_ip6 = true;
3632   return true;
3633 }
3634
3635 static bool mg_aton6(struct mg_str str, struct mg_addr *addr) {
3636   size_t i, j = 0, n = 0, dc = 42;
3637   if (str.len > 2 && str.ptr[0] == '[') str.ptr++, str.len -= 2;
3638   if (mg_v4mapped(str, addr)) return true;
3639   for (i = 0; i < str.len; i++) {
3640     if ((str.ptr[i] >= '0' && str.ptr[i] <= '9') ||
3641         (str.ptr[i] >= 'a' && str.ptr[i] <= 'f') ||
3642         (str.ptr[i] >= 'A' && str.ptr[i] <= 'F')) {
3643       unsigned long val;
3644       if (i > j + 3) return false;
3645       // MG_DEBUG(("%zu %zu [%.*s]", i, j, (int) (i - j + 1), &str.ptr[j]));
3646       val = mg_unhexn(&str.ptr[j], i - j + 1);
3647       addr->ip[n] = (uint8_t) ((val >> 8) & 255);
3648       addr->ip[n + 1] = (uint8_t) (val & 255);
3649     } else if (str.ptr[i] == ':') {
3650       j = i + 1;
3651       if (i > 0 && str.ptr[i - 1] == ':') {
3652         dc = n;  // Double colon
3653         if (i > 1 && str.ptr[i - 2] == ':') return false;
3654       } else if (i > 0) {
3655         n += 2;
3656       }
3657       if (n > 14) return false;
3658       addr->ip[n] = addr->ip[n + 1] = 0;  // For trailing ::
3659     } else {
3660       return false;
3661     }
3662   }
3663   if (n < 14 && dc == 42) return false;
3664   if (n < 14) {
3665     memmove(&addr->ip[dc + (14 - n)], &addr->ip[dc], n - dc + 2);
3666     memset(&addr->ip[dc], 0, 14 - n);
3667   }
3668
3669   addr->is_ip6 = true;
3670   return true;
3671 }
3672
3673 bool mg_aton(struct mg_str str, struct mg_addr *addr) {
3674   // MG_INFO(("[%.*s]", (int) str.len, str.ptr));
3675   return mg_atone(str, addr) || mg_atonl(str, addr) || mg_aton4(str, addr) ||
3676          mg_aton6(str, addr);
3677 }
3678
3679 struct mg_connection *mg_alloc_conn(struct mg_mgr *mgr) {
3680   struct mg_connection *c =
3681       (struct mg_connection *) calloc(1, sizeof(*c) + mgr->extraconnsize);
3682   if (c != NULL) {
3683     c->mgr = mgr;
3684     c->send.align = c->recv.align = MG_IO_SIZE;
3685     c->id = ++mgr->nextid;
3686   }
3687   return c;
3688 }
3689
3690 void mg_close_conn(struct mg_connection *c) {
3691   mg_resolve_cancel(c);  // Close any pending DNS query
3692   LIST_DELETE(struct mg_connection, &c->mgr->conns, c);
3693   if (c == c->mgr->dns4.c) c->mgr->dns4.c = NULL;
3694   if (c == c->mgr->dns6.c) c->mgr->dns6.c = NULL;
3695   // Order of operations is important. `MG_EV_CLOSE` event must be fired
3696   // before we deallocate received data, see #1331
3697   mg_call(c, MG_EV_CLOSE, NULL);
3698   MG_DEBUG(("%lu %p closed", c->id, c->fd));
3699
3700   mg_tls_free(c);
3701   mg_iobuf_free(&c->recv);
3702   mg_iobuf_free(&c->send);
3703   memset(c, 0, sizeof(*c));
3704   free(c);
3705 }
3706
3707 struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *url,
3708                                  mg_event_handler_t fn, void *fn_data) {
3709   struct mg_connection *c = NULL;
3710   if (url == NULL || url[0] == '\0') {
3711     MG_ERROR(("null url"));
3712   } else if ((c = mg_alloc_conn(mgr)) == NULL) {
3713     MG_ERROR(("OOM"));
3714   } else {
3715     LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
3716     c->is_udp = (strncmp(url, "udp:", 4) == 0);
3717     c->fd = (void *) (size_t) MG_INVALID_SOCKET;
3718     c->fn = fn;
3719     c->is_client = true;
3720     c->fn_data = fn_data;
3721     MG_DEBUG(("%lu %p %s", c->id, c->fd, url));
3722     mg_call(c, MG_EV_OPEN, (void *) url);
3723     mg_resolve(c, url);
3724     if (mg_url_is_ssl(url)) {
3725       struct mg_str host = mg_url_host(url);
3726       mg_tls_init(c, host);
3727     }
3728   }
3729   return c;
3730 }
3731
3732 struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url,
3733                                 mg_event_handler_t fn, void *fn_data) {
3734   struct mg_connection *c = NULL;
3735   if ((c = mg_alloc_conn(mgr)) == NULL) {
3736     MG_ERROR(("OOM %s", url));
3737   } else if (!mg_open_listener(c, url)) {
3738     MG_ERROR(("Failed: %s, errno %d", url, errno));
3739     free(c);
3740     c = NULL;
3741   } else {
3742     c->is_listening = 1;
3743     c->is_udp = strncmp(url, "udp:", 4) == 0;
3744     LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
3745     c->fn = fn;
3746     c->fn_data = fn_data;
3747     mg_call(c, MG_EV_OPEN, NULL);
3748     if (mg_url_is_ssl(url)) c->is_tls = 1; // Accepted connection must
3749     MG_DEBUG(("%lu %p %s", c->id, c->fd, url));
3750   }
3751   return c;
3752 }
3753
3754 struct mg_connection *mg_wrapfd(struct mg_mgr *mgr, int fd,
3755                                 mg_event_handler_t fn, void *fn_data) {
3756   struct mg_connection *c = mg_alloc_conn(mgr);
3757   if (c != NULL) {
3758     c->fd = (void *) (size_t) fd;
3759     c->fn = fn;
3760     c->fn_data = fn_data;
3761     MG_EPOLL_ADD(c);
3762     mg_call(c, MG_EV_OPEN, NULL);
3763     LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
3764   }
3765   return c;
3766 }
3767
3768 struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds,
3769                               unsigned flags, void (*fn)(void *), void *arg) {
3770   struct mg_timer *t = (struct mg_timer *) calloc(1, sizeof(*t));
3771   if (t != NULL) {
3772     mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg);
3773     t->id = mgr->timerid++;
3774   }
3775   return t;
3776 }
3777
3778 void mg_mgr_free(struct mg_mgr *mgr) {
3779   struct mg_connection *c;
3780   struct mg_timer *tmp, *t = mgr->timers;
3781   while (t != NULL) tmp = t->next, free(t), t = tmp;
3782   mgr->timers = NULL;  // Important. Next call to poll won't touch timers
3783   for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1;
3784   mg_mgr_poll(mgr, 0);
3785 #if MG_ENABLE_FREERTOS_TCP
3786   FreeRTOS_DeleteSocketSet(mgr->ss);
3787 #endif
3788   MG_DEBUG(("All connections closed"));
3789 #if MG_ENABLE_EPOLL
3790   if (mgr->epoll_fd >= 0) close(mgr->epoll_fd), mgr->epoll_fd = -1;
3791 #endif
3792   mg_tls_ctx_free(mgr);
3793 }
3794
3795 void mg_mgr_init(struct mg_mgr *mgr) {
3796   memset(mgr, 0, sizeof(*mgr));
3797 #if MG_ENABLE_EPOLL
3798   if ((mgr->epoll_fd = epoll_create1(0)) < 0) MG_ERROR(("epoll: %d", errno));
3799 #else
3800   mgr->epoll_fd = -1;
3801 #endif
3802 #if MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK
3803   // clang-format off
3804   { WSADATA data; WSAStartup(MAKEWORD(2, 2), &data); }
3805   // clang-format on
3806 #elif MG_ENABLE_FREERTOS_TCP
3807   mgr->ss = FreeRTOS_CreateSocketSet();
3808 #elif defined(__unix) || defined(__unix__) || defined(__APPLE__)
3809   // Ignore SIGPIPE signal, so if client cancels the request, it
3810   // won't kill the whole process.
3811   signal(SIGPIPE, SIG_IGN);
3812 #endif
3813   mgr->dnstimeout = 3000;
3814   mgr->dns4.url = "udp://8.8.8.8:53";
3815   mgr->dns6.url = "udp://[2001:4860:4860::8888]:53";
3816 }
3817
3818 #ifdef MG_ENABLE_LINES
3819 #line 1 "src/net_builtin.c"
3820 #endif
3821
3822
3823 #if defined(MG_ENABLE_TCPIP) && MG_ENABLE_TCPIP
3824 #define MG_EPHEMERAL_PORT_BASE 32768
3825 #define PDIFF(a, b) ((size_t) (((char *) (b)) - ((char *) (a))))
3826
3827 #ifndef MIP_TCP_KEEPALIVE_MS
3828 #define MIP_TCP_KEEPALIVE_MS 45000  // TCP keep-alive period, ms
3829 #endif
3830
3831 #define MIP_TCP_ACK_MS 150    // Timeout for ACKing
3832 #define MIP_TCP_ARP_MS 100    // Timeout for ARP response
3833 #define MIP_TCP_SYN_MS 15000  // Timeout for connection establishment
3834 #define MIP_TCP_FIN_MS 1000   // Timeout for closing connection
3835
3836 struct connstate {
3837   uint32_t seq, ack;           // TCP seq/ack counters
3838   uint64_t timer;              // TCP keep-alive / ACK timer
3839   uint8_t mac[6];              // Peer MAC address
3840   uint8_t ttype;               // Timer type. 0: ack, 1: keep-alive
3841 #define MIP_TTYPE_KEEPALIVE 0  // Connection is idle for long, send keepalive
3842 #define MIP_TTYPE_ACK 1        // Peer sent us data, we have to ack it soon
3843 #define MIP_TTYPE_ARP 2        // ARP resolve sent, waiting for response
3844 #define MIP_TTYPE_SYN 3        // SYN sent, waiting for response
3845 #define MIP_TTYPE_FIN 4  // FIN sent, waiting until terminating the connection
3846   uint8_t tmiss;         // Number of keep-alive misses
3847   struct mg_iobuf raw;   // For TLS only. Incoming raw data
3848 };
3849
3850 #pragma pack(push, 1)
3851
3852 struct lcp {
3853   uint8_t addr, ctrl, proto[2], code, id, len[2];
3854 };
3855
3856 struct eth {
3857   uint8_t dst[6];  // Destination MAC address
3858   uint8_t src[6];  // Source MAC address
3859   uint16_t type;   // Ethernet type
3860 };
3861
3862 struct ip {
3863   uint8_t ver;    // Version
3864   uint8_t tos;    // Unused
3865   uint16_t len;   // Length
3866   uint16_t id;    // Unused
3867   uint16_t frag;  // Fragmentation
3868   uint8_t ttl;    // Time to live
3869   uint8_t proto;  // Upper level protocol
3870   uint16_t csum;  // Checksum
3871   uint32_t src;   // Source IP
3872   uint32_t dst;   // Destination IP
3873 };
3874
3875 struct ip6 {
3876   uint8_t ver;      // Version
3877   uint8_t opts[3];  // Options
3878   uint16_t len;     // Length
3879   uint8_t proto;    // Upper level protocol
3880   uint8_t ttl;      // Time to live
3881   uint8_t src[16];  // Source IP
3882   uint8_t dst[16];  // Destination IP
3883 };
3884
3885 struct icmp {
3886   uint8_t type;
3887   uint8_t code;
3888   uint16_t csum;
3889 };
3890
3891 struct arp {
3892   uint16_t fmt;    // Format of hardware address
3893   uint16_t pro;    // Format of protocol address
3894   uint8_t hlen;    // Length of hardware address
3895   uint8_t plen;    // Length of protocol address
3896   uint16_t op;     // Operation
3897   uint8_t sha[6];  // Sender hardware address
3898   uint32_t spa;    // Sender protocol address
3899   uint8_t tha[6];  // Target hardware address
3900   uint32_t tpa;    // Target protocol address
3901 };
3902
3903 struct tcp {
3904   uint16_t sport;  // Source port
3905   uint16_t dport;  // Destination port
3906   uint32_t seq;    // Sequence number
3907   uint32_t ack;    // Acknowledgement number
3908   uint8_t off;     // Data offset
3909   uint8_t flags;   // TCP flags
3910 #define TH_FIN 0x01
3911 #define TH_SYN 0x02
3912 #define TH_RST 0x04
3913 #define TH_PUSH 0x08
3914 #define TH_ACK 0x10
3915 #define TH_URG 0x20
3916 #define TH_ECE 0x40
3917 #define TH_CWR 0x80
3918   uint16_t win;   // Window
3919   uint16_t csum;  // Checksum
3920   uint16_t urp;   // Urgent pointer
3921 };
3922
3923 struct udp {
3924   uint16_t sport;  // Source port
3925   uint16_t dport;  // Destination port
3926   uint16_t len;    // UDP length
3927   uint16_t csum;   // UDP checksum
3928 };
3929
3930 struct dhcp {
3931   uint8_t op, htype, hlen, hops;
3932   uint32_t xid;
3933   uint16_t secs, flags;
3934   uint32_t ciaddr, yiaddr, siaddr, giaddr;
3935   uint8_t hwaddr[208];
3936   uint32_t magic;
3937   uint8_t options[32];
3938 };
3939
3940 #pragma pack(pop)
3941
3942 struct pkt {
3943   struct mg_str raw;  // Raw packet data
3944   struct mg_str pay;  // Payload data
3945   struct eth *eth;
3946   struct llc *llc;
3947   struct arp *arp;
3948   struct ip *ip;
3949   struct ip6 *ip6;
3950   struct icmp *icmp;
3951   struct tcp *tcp;
3952   struct udp *udp;
3953   struct dhcp *dhcp;
3954 };
3955
3956 static void send_syn(struct mg_connection *c);
3957
3958 static void mkpay(struct pkt *pkt, void *p) {
3959   pkt->pay =
3960       mg_str_n((char *) p, (size_t) (&pkt->raw.ptr[pkt->raw.len] - (char *) p));
3961 }
3962
3963 static uint32_t csumup(uint32_t sum, const void *buf, size_t len) {
3964   const uint8_t *p = (const uint8_t *) buf;
3965   for (size_t i = 0; i < len; i++) sum += i & 1 ? p[i] : (uint32_t) (p[i] << 8);
3966   return sum;
3967 }
3968
3969 static uint16_t csumfin(uint32_t sum) {
3970   while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16);
3971   return mg_htons(~sum & 0xffff);
3972 }
3973
3974 static uint16_t ipcsum(const void *buf, size_t len) {
3975   uint32_t sum = csumup(0, buf, len);
3976   return csumfin(sum);
3977 }
3978
3979 static void settmout(struct mg_connection *c, uint8_t type) {
3980   struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
3981   struct connstate *s = (struct connstate *) (c + 1);
3982   unsigned n = type == MIP_TTYPE_ACK   ? MIP_TCP_ACK_MS
3983                : type == MIP_TTYPE_ARP ? MIP_TCP_ARP_MS
3984                : type == MIP_TTYPE_SYN ? MIP_TCP_SYN_MS
3985                : type == MIP_TTYPE_FIN ? MIP_TCP_FIN_MS
3986                                        : MIP_TCP_KEEPALIVE_MS;
3987   s->timer = ifp->now + n;
3988   s->ttype = type;
3989   MG_VERBOSE(("%lu %d -> %llx", c->id, type, s->timer));
3990 }
3991
3992 static size_t ether_output(struct mg_tcpip_if *ifp, size_t len) {
3993   // size_t min = 64;  // Pad short frames to 64 bytes (minimum Ethernet size)
3994   // if (len < min) memset(ifp->tx.ptr + len, 0, min - len), len = min;
3995   // mg_hexdump(ifp->tx.ptr, len);
3996   size_t n = ifp->driver->tx(ifp->tx.ptr, len, ifp);
3997   if (n == len) ifp->nsent++;
3998   return n;
3999 }
4000
4001 static void arp_ask(struct mg_tcpip_if *ifp, uint32_t ip) {
4002   struct eth *eth = (struct eth *) ifp->tx.ptr;
4003   struct arp *arp = (struct arp *) (eth + 1);
4004   memset(eth->dst, 255, sizeof(eth->dst));
4005   memcpy(eth->src, ifp->mac, sizeof(eth->src));
4006   eth->type = mg_htons(0x806);
4007   memset(arp, 0, sizeof(*arp));
4008   arp->fmt = mg_htons(1), arp->pro = mg_htons(0x800), arp->hlen = 6,
4009   arp->plen = 4;
4010   arp->op = mg_htons(1), arp->tpa = ip, arp->spa = ifp->ip;
4011   memcpy(arp->sha, ifp->mac, sizeof(arp->sha));
4012   ether_output(ifp, PDIFF(eth, arp + 1));
4013 }
4014
4015 static void onstatechange(struct mg_tcpip_if *ifp) {
4016   if (ifp->state == MG_TCPIP_STATE_READY) {
4017     MG_INFO(("READY, IP: %M", mg_print_ip4, &ifp->ip));
4018     MG_INFO(("       GW: %M", mg_print_ip4, &ifp->gw));
4019     MG_INFO(("      MAC: %M", mg_print_mac, &ifp->mac));
4020     arp_ask(ifp, ifp->gw);
4021   } else if (ifp->state == MG_TCPIP_STATE_UP) {
4022     MG_ERROR(("Link up"));
4023     srand((unsigned int) mg_millis());
4024   } else if (ifp->state == MG_TCPIP_STATE_DOWN) {
4025     MG_ERROR(("Link down"));
4026   }
4027 }
4028
4029 static struct ip *tx_ip(struct mg_tcpip_if *ifp, uint8_t *mac_dst,
4030                         uint8_t proto, uint32_t ip_src, uint32_t ip_dst,
4031                         size_t plen) {
4032   struct eth *eth = (struct eth *) ifp->tx.ptr;
4033   struct ip *ip = (struct ip *) (eth + 1);
4034   memcpy(eth->dst, mac_dst, sizeof(eth->dst));
4035   memcpy(eth->src, ifp->mac, sizeof(eth->src));  // Use our MAC
4036   eth->type = mg_htons(0x800);
4037   memset(ip, 0, sizeof(*ip));
4038   ip->ver = 0x45;   // Version 4, header length 5 words
4039   ip->frag = 0x40;  // Don't fragment
4040   ip->len = mg_htons((uint16_t) (sizeof(*ip) + plen));
4041   ip->ttl = 64;
4042   ip->proto = proto;
4043   ip->src = ip_src;
4044   ip->dst = ip_dst;
4045   ip->csum = ipcsum(ip, sizeof(*ip));
4046   return ip;
4047 }
4048
4049 static void tx_udp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src,
4050                    uint16_t sport, uint32_t ip_dst, uint16_t dport,
4051                    const void *buf, size_t len) {
4052   struct ip *ip =
4053       tx_ip(ifp, mac_dst, 17, ip_src, ip_dst, len + sizeof(struct udp));
4054   struct udp *udp = (struct udp *) (ip + 1);
4055   // MG_DEBUG(("UDP XX LEN %d %d", (int) len, (int) ifp->tx.len));
4056   udp->sport = sport;
4057   udp->dport = dport;
4058   udp->len = mg_htons((uint16_t) (sizeof(*udp) + len));
4059   udp->csum = 0;
4060   uint32_t cs = csumup(0, udp, sizeof(*udp));
4061   cs = csumup(cs, buf, len);
4062   cs = csumup(cs, &ip->src, sizeof(ip->src));
4063   cs = csumup(cs, &ip->dst, sizeof(ip->dst));
4064   cs += (uint32_t) (ip->proto + sizeof(*udp) + len);
4065   udp->csum = csumfin(cs);
4066   memmove(udp + 1, buf, len);
4067   // MG_DEBUG(("UDP LEN %d %d", (int) len, (int) ifp->frame_len));
4068   ether_output(ifp, sizeof(struct eth) + sizeof(*ip) + sizeof(*udp) + len);
4069 }
4070
4071 static void tx_dhcp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src,
4072                     uint32_t ip_dst, uint8_t *opts, size_t optslen,
4073                     bool ciaddr) {
4074   // https://datatracker.ietf.org/doc/html/rfc2132#section-9.6
4075   struct dhcp dhcp = {1, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, {0}, 0, {0}};
4076   dhcp.magic = mg_htonl(0x63825363);
4077   memcpy(&dhcp.hwaddr, ifp->mac, sizeof(ifp->mac));
4078   memcpy(&dhcp.xid, ifp->mac + 2, sizeof(dhcp.xid));
4079   memcpy(&dhcp.options, opts, optslen);
4080   if (ciaddr) dhcp.ciaddr = ip_src;
4081   tx_udp(ifp, mac_dst, ip_src, mg_htons(68), ip_dst, mg_htons(67), &dhcp,
4082          sizeof(dhcp));
4083 }
4084
4085 static const uint8_t broadcast[] = {255, 255, 255, 255, 255, 255};
4086
4087 // RFC-2131 #4.3.6, #4.4.1
4088 static void tx_dhcp_request_sel(struct mg_tcpip_if *ifp, uint32_t ip_req,
4089                                 uint32_t ip_srv) {
4090   uint8_t opts[] = {
4091       53, 1, 3,                 // Type: DHCP request
4092       55, 2, 1,   3,            // GW and mask
4093       12, 3, 'm', 'i', 'p',     // Host name: "mip"
4094       54, 4, 0,   0,   0,   0,  // DHCP server ID
4095       50, 4, 0,   0,   0,   0,  // Requested IP
4096       255                       // End of options
4097   };
4098   memcpy(opts + 14, &ip_srv, sizeof(ip_srv));
4099   memcpy(opts + 20, &ip_req, sizeof(ip_req));
4100   tx_dhcp(ifp, (uint8_t *) broadcast, 0, 0xffffffff, opts, sizeof(opts), false);
4101   MG_DEBUG(("DHCP req sent"));
4102 }
4103
4104 // RFC-2131 #4.3.6, #4.4.5 (renewing: unicast, rebinding: bcast)
4105 static void tx_dhcp_request_re(struct mg_tcpip_if *ifp, uint8_t *mac_dst,
4106                                uint32_t ip_src, uint32_t ip_dst) {
4107   uint8_t opts[] = {
4108       53, 1, 3,  // Type: DHCP request
4109       255        // End of options
4110   };
4111   tx_dhcp(ifp, mac_dst, ip_src, ip_dst, opts, sizeof(opts), true);
4112   MG_DEBUG(("DHCP req sent"));
4113 }
4114
4115 static void tx_dhcp_discover(struct mg_tcpip_if *ifp) {
4116   uint8_t opts[] = {
4117       53, 1, 1,     // Type: DHCP discover
4118       55, 2, 1, 3,  // Parameters: ip, mask
4119       255           // End of options
4120   };
4121   tx_dhcp(ifp, (uint8_t *) broadcast, 0, 0xffffffff, opts, sizeof(opts), false);
4122   MG_DEBUG(("DHCP discover sent. Our MAC: %M", mg_print_mac, ifp->mac));
4123 }
4124
4125 static struct mg_connection *getpeer(struct mg_mgr *mgr, struct pkt *pkt,
4126                                      bool lsn) {
4127   struct mg_connection *c = NULL;
4128   for (c = mgr->conns; c != NULL; c = c->next) {
4129     if (c->is_arplooking && pkt->arp &&
4130         memcmp(&pkt->arp->spa, c->rem.ip, sizeof(pkt->arp->spa)) == 0)
4131       break;
4132     if (c->is_udp && pkt->udp && c->loc.port == pkt->udp->dport) break;
4133     if (!c->is_udp && pkt->tcp && c->loc.port == pkt->tcp->dport &&
4134         lsn == c->is_listening && (lsn || c->rem.port == pkt->tcp->sport))
4135       break;
4136   }
4137   return c;
4138 }
4139
4140 static void rx_arp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
4141   if (pkt->arp->op == mg_htons(1) && pkt->arp->tpa == ifp->ip) {
4142     // ARP request. Make a response, then send
4143     // MG_DEBUG(("ARP op %d %M: %M", mg_ntohs(pkt->arp->op), mg_print_ip4,
4144     //          &pkt->arp->spa, mg_print_ip4, &pkt->arp->tpa));
4145     struct eth *eth = (struct eth *) ifp->tx.ptr;
4146     struct arp *arp = (struct arp *) (eth + 1);
4147     memcpy(eth->dst, pkt->eth->src, sizeof(eth->dst));
4148     memcpy(eth->src, ifp->mac, sizeof(eth->src));
4149     eth->type = mg_htons(0x806);
4150     *arp = *pkt->arp;
4151     arp->op = mg_htons(2);
4152     memcpy(arp->tha, pkt->arp->sha, sizeof(pkt->arp->tha));
4153     memcpy(arp->sha, ifp->mac, sizeof(pkt->arp->sha));
4154     arp->tpa = pkt->arp->spa;
4155     arp->spa = ifp->ip;
4156     MG_DEBUG(("ARP: tell %M we're %M", mg_print_ip4, &arp->tpa, mg_print_mac,
4157               &ifp->mac));
4158     ether_output(ifp, PDIFF(eth, arp + 1));
4159   } else if (pkt->arp->op == mg_htons(2)) {
4160     if (memcmp(pkt->arp->tha, ifp->mac, sizeof(pkt->arp->tha)) != 0) return;
4161     if (pkt->arp->spa == ifp->gw) {
4162       // Got response for the GW ARP request. Set ifp->gwmac
4163       memcpy(ifp->gwmac, pkt->arp->sha, sizeof(ifp->gwmac));
4164     } else {
4165       struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
4166       if (c != NULL && c->is_arplooking) {
4167         struct connstate *s = (struct connstate *) (c + 1);
4168         memcpy(s->mac, pkt->arp->sha, sizeof(s->mac));
4169         MG_DEBUG(("%lu ARP resolved %M -> %M", c->id, mg_print_ip4, c->rem.ip,
4170                   mg_print_mac, s->mac));
4171         c->is_arplooking = 0;
4172         send_syn(c);
4173         settmout(c, MIP_TTYPE_SYN);
4174       }
4175     }
4176   }
4177 }
4178
4179 static void rx_icmp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
4180   // MG_DEBUG(("ICMP %d", (int) len));
4181   if (pkt->icmp->type == 8 && pkt->ip != NULL && pkt->ip->dst == ifp->ip) {
4182     size_t hlen = sizeof(struct eth) + sizeof(struct ip) + sizeof(struct icmp);
4183     size_t space = ifp->tx.len - hlen, plen = pkt->pay.len;
4184     if (plen > space) plen = space;
4185     struct ip *ip = tx_ip(ifp, pkt->eth->src, 1, ifp->ip, pkt->ip->src,
4186                           sizeof(struct icmp) + plen);
4187     struct icmp *icmp = (struct icmp *) (ip + 1);
4188     memset(icmp, 0, sizeof(*icmp));        // Set csum to 0
4189     memcpy(icmp + 1, pkt->pay.ptr, plen);  // Copy RX payload to TX
4190     icmp->csum = ipcsum(icmp, sizeof(*icmp) + plen);
4191     ether_output(ifp, hlen + plen);
4192   }
4193 }
4194
4195 static void rx_dhcp_client(struct mg_tcpip_if *ifp, struct pkt *pkt) {
4196   uint32_t ip = 0, gw = 0, mask = 0, lease = 0;
4197   uint8_t msgtype = 0, state = ifp->state;
4198   // perform size check first, then access fields
4199   uint8_t *p = pkt->dhcp->options,
4200           *end = (uint8_t *) &pkt->raw.ptr[pkt->raw.len];
4201   if (end < (uint8_t *) (pkt->dhcp + 1)) return;
4202   if (memcmp(&pkt->dhcp->xid, ifp->mac + 2, sizeof(pkt->dhcp->xid))) return;
4203   while (p + 1 < end && p[0] != 255) {  // Parse options RFC-1533 #9
4204     if (p[0] == 1 && p[1] == sizeof(ifp->mask) && p + 6 < end) {  // Mask
4205       memcpy(&mask, p + 2, sizeof(mask));
4206     } else if (p[0] == 3 && p[1] == sizeof(ifp->gw) && p + 6 < end) {  // GW
4207       memcpy(&gw, p + 2, sizeof(gw));
4208       ip = pkt->dhcp->yiaddr;
4209     } else if (p[0] == 51 && p[1] == 4 && p + 6 < end) {  // Lease
4210       memcpy(&lease, p + 2, sizeof(lease));
4211       lease = mg_ntohl(lease);
4212     } else if (p[0] == 53 && p[1] == 1 && p + 6 < end) {  // Msg Type
4213       msgtype = p[2];
4214     }
4215     p += p[1] + 2;
4216   }
4217   // Process message type, RFC-1533 (9.4); RFC-2131 (3.1, 4)
4218   if (msgtype == 6 && ifp->ip == ip) {  // DHCPNACK, release IP
4219     ifp->state = MG_TCPIP_STATE_UP, ifp->ip = 0;
4220   } else if (msgtype == 2 && ifp->state == MG_TCPIP_STATE_UP && ip && gw &&
4221              lease) {                                 // DHCPOFFER
4222     tx_dhcp_request_sel(ifp, ip, pkt->dhcp->siaddr);  // select IP, (4.4.1)
4223     ifp->state = MG_TCPIP_STATE_REQ;                  // REQUESTING state
4224   } else if (msgtype == 5) {                          // DHCPACK
4225     if (ifp->state == MG_TCPIP_STATE_REQ && ip && gw && lease) {  // got an IP
4226       ifp->lease_expire = ifp->now + lease * 1000;
4227       MG_INFO(("Lease: %u sec (%lld)", lease, ifp->lease_expire / 1000));
4228       // assume DHCP server = router until ARP resolves
4229       memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac));
4230       ifp->ip = ip, ifp->gw = gw, ifp->mask = mask;
4231       ifp->state = MG_TCPIP_STATE_READY;  // BOUND state
4232       uint64_t rand;
4233       mg_random(&rand, sizeof(rand));
4234       srand((unsigned int) (rand + mg_millis()));
4235     } else if (ifp->state == MG_TCPIP_STATE_READY && ifp->ip == ip) {  // renew
4236       ifp->lease_expire = ifp->now + lease * 1000;
4237       MG_INFO(("Lease: %u sec (%lld)", lease, ifp->lease_expire / 1000));
4238     }  // TODO(): accept provided T1/T2 and store server IP for renewal (4.4)
4239   }
4240   if (ifp->state != state) onstatechange(ifp);
4241 }
4242
4243 // Simple DHCP server that assigns a next IP address: ifp->ip + 1
4244 static void rx_dhcp_server(struct mg_tcpip_if *ifp, struct pkt *pkt) {
4245   uint8_t op = 0, *p = pkt->dhcp->options,
4246           *end = (uint8_t *) &pkt->raw.ptr[pkt->raw.len];
4247   if (end < (uint8_t *) (pkt->dhcp + 1)) return;
4248   // struct dhcp *req = pkt->dhcp;
4249   struct dhcp res = {2, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, {0}, 0, {0}};
4250   res.yiaddr = ifp->ip;
4251   ((uint8_t *) (&res.yiaddr))[3]++;                // Offer our IP + 1
4252   while (p + 1 < end && p[0] != 255) {             // Parse options
4253     if (p[0] == 53 && p[1] == 1 && p + 2 < end) {  // Message type
4254       op = p[2];
4255     }
4256     p += p[1] + 2;
4257   }
4258   if (op == 1 || op == 3) {         // DHCP Discover or DHCP Request
4259     uint8_t msg = op == 1 ? 2 : 5;  // Message type: DHCP OFFER or DHCP ACK
4260     uint8_t opts[] = {
4261         53, 1, msg,                 // Message type
4262         1,  4, 0,   0,   0,   0,    // Subnet mask
4263         54, 4, 0,   0,   0,   0,    // Server ID
4264         12, 3, 'm', 'i', 'p',       // Host name: "mip"
4265         51, 4, 255, 255, 255, 255,  // Lease time
4266         255                         // End of options
4267     };
4268     memcpy(&res.hwaddr, pkt->dhcp->hwaddr, 6);
4269     memcpy(opts + 5, &ifp->mask, sizeof(ifp->mask));
4270     memcpy(opts + 11, &ifp->ip, sizeof(ifp->ip));
4271     memcpy(&res.options, opts, sizeof(opts));
4272     res.magic = pkt->dhcp->magic;
4273     res.xid = pkt->dhcp->xid;
4274     // memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac));
4275     tx_udp(ifp, pkt->eth->src, ifp->ip, mg_htons(67),
4276            op == 1 ? ~0U : res.yiaddr, mg_htons(68), &res, sizeof(res));
4277   }
4278 }
4279
4280 static void rx_udp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
4281   struct mg_connection *c = getpeer(ifp->mgr, pkt, true);
4282   if (c == NULL) {
4283     // No UDP listener on this port. Should send ICMP, but keep silent.
4284   } else {
4285     c->rem.port = pkt->udp->sport;
4286     memcpy(c->rem.ip, &pkt->ip->src, sizeof(uint32_t));
4287     struct connstate *s = (struct connstate *) (c + 1);
4288     memcpy(s->mac, pkt->eth->src, sizeof(s->mac));
4289     if (c->recv.len >= MG_MAX_RECV_SIZE) {
4290       mg_error(c, "max_recv_buf_size reached");
4291     } else if (c->recv.size - c->recv.len < pkt->pay.len &&
4292                !mg_iobuf_resize(&c->recv, c->recv.len + pkt->pay.len)) {
4293       mg_error(c, "oom");
4294     } else {
4295       memcpy(&c->recv.buf[c->recv.len], pkt->pay.ptr, pkt->pay.len);
4296       c->recv.len += pkt->pay.len;
4297       mg_call(c, MG_EV_READ, &pkt->pay.len);
4298     }
4299   }
4300 }
4301
4302 static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *dst_mac, uint32_t dst_ip,
4303                      uint8_t flags, uint16_t sport, uint16_t dport,
4304                      uint32_t seq, uint32_t ack, const void *buf, size_t len) {
4305   struct ip *ip =
4306       tx_ip(ifp, dst_mac, 6, ifp->ip, dst_ip, sizeof(struct tcp) + len);
4307   struct tcp *tcp = (struct tcp *) (ip + 1);
4308   memset(tcp, 0, sizeof(*tcp));
4309   if (buf != NULL && len) memmove(tcp + 1, buf, len);
4310   tcp->sport = sport;
4311   tcp->dport = dport;
4312   tcp->seq = seq;
4313   tcp->ack = ack;
4314   tcp->flags = flags;
4315   tcp->win = mg_htons(8192);
4316   tcp->off = (uint8_t) (sizeof(*tcp) / 4 << 4);
4317   uint32_t cs = 0;
4318   uint16_t n = (uint16_t) (sizeof(*tcp) + len);
4319   uint8_t pseudo[] = {0, ip->proto, (uint8_t) (n >> 8), (uint8_t) (n & 255)};
4320   cs = csumup(cs, tcp, n);
4321   cs = csumup(cs, &ip->src, sizeof(ip->src));
4322   cs = csumup(cs, &ip->dst, sizeof(ip->dst));
4323   cs = csumup(cs, pseudo, sizeof(pseudo));
4324   tcp->csum = csumfin(cs);
4325   MG_VERBOSE(("TCP %M:%hu -> %M:%hu fl %x len %u", mg_print_ip4, &ip->src,
4326               mg_ntohs(tcp->sport), mg_print_ip4, &ip->dst,
4327               mg_ntohs(tcp->dport), tcp->flags, (int) len));
4328   // mg_hexdump(ifp->tx.ptr, PDIFF(ifp->tx.ptr, tcp + 1) + len);
4329   return ether_output(ifp, PDIFF(ifp->tx.ptr, tcp + 1) + len);
4330 }
4331
4332 static size_t tx_tcp_pkt(struct mg_tcpip_if *ifp, struct pkt *pkt,
4333                          uint8_t flags, uint32_t seq, const void *buf,
4334                          size_t len) {
4335   uint32_t delta = (pkt->tcp->flags & (TH_SYN | TH_FIN)) ? 1 : 0;
4336   return tx_tcp(ifp, pkt->eth->src, pkt->ip->src, flags, pkt->tcp->dport,
4337                 pkt->tcp->sport, seq, mg_htonl(mg_ntohl(pkt->tcp->seq) + delta),
4338                 buf, len);
4339 }
4340
4341 static struct mg_connection *accept_conn(struct mg_connection *lsn,
4342                                          struct pkt *pkt) {
4343   struct mg_connection *c = mg_alloc_conn(lsn->mgr);
4344   if (c == NULL) {
4345     MG_ERROR(("OOM"));
4346     return NULL;
4347   }
4348   struct connstate *s = (struct connstate *) (c + 1);
4349   s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq);
4350   memcpy(s->mac, pkt->eth->src, sizeof(s->mac));
4351   settmout(c, MIP_TTYPE_KEEPALIVE);
4352   memcpy(c->rem.ip, &pkt->ip->src, sizeof(uint32_t));
4353   c->rem.port = pkt->tcp->sport;
4354   MG_DEBUG(("%lu accepted %M", c->id, mg_print_ip_port, &c->rem));
4355   LIST_ADD_HEAD(struct mg_connection, &lsn->mgr->conns, c);
4356   c->is_accepted = 1;
4357   c->is_hexdumping = lsn->is_hexdumping;
4358   c->pfn = lsn->pfn;
4359   c->loc = lsn->loc;
4360   c->pfn_data = lsn->pfn_data;
4361   c->fn = lsn->fn;
4362   c->fn_data = lsn->fn_data;
4363   mg_call(c, MG_EV_OPEN, NULL);
4364   mg_call(c, MG_EV_ACCEPT, NULL);
4365   if (lsn->is_tls) mg_tls_init(c, mg_str(""));
4366   return c;
4367 }
4368
4369 long mg_io_send(struct mg_connection *c, const void *buf, size_t len) {
4370   struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
4371   struct connstate *s = (struct connstate *) (c + 1);
4372   uint32_t rem_ip;
4373   memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t));
4374   if (c->is_udp) {
4375     size_t max_headers_len = 14 + 24 /* max IP */ + 8 /* UDP */;
4376     if (len + max_headers_len > ifp->tx.len) {
4377       len = ifp->tx.len - max_headers_len;
4378     }
4379     tx_udp(ifp, s->mac, ifp->ip, c->loc.port, rem_ip, c->rem.port, buf, len);
4380   } else {
4381     size_t max_headers_len = 14 + 24 /* max IP */ + 60 /* max TCP */;
4382     if (len + max_headers_len > ifp->tx.len)
4383       len = ifp->tx.len - max_headers_len;
4384     if (tx_tcp(ifp, s->mac, rem_ip, TH_PUSH | TH_ACK, c->loc.port, c->rem.port,
4385                mg_htonl(s->seq), mg_htonl(s->ack), buf, len) > 0) {
4386       s->seq += (uint32_t) len;
4387       if (s->ttype == MIP_TTYPE_ACK) settmout(c, MIP_TTYPE_KEEPALIVE);
4388     } else {
4389       return MG_IO_ERR;
4390     }
4391   }
4392   return (long) len;
4393 }
4394
4395 long mg_io_recv(struct mg_connection *c, void *buf, size_t len) {
4396   struct connstate *s = (struct connstate *) (c + 1);
4397   if (s->raw.len == 0) return MG_IO_WAIT;
4398   if (len > s->raw.len) len = s->raw.len;
4399   memcpy(buf, s->raw.buf, len);
4400   mg_iobuf_del(&s->raw, 0, len);
4401   return (long) len;
4402 }
4403
4404 static void read_conn(struct mg_connection *c, struct pkt *pkt) {
4405   struct connstate *s = (struct connstate *) (c + 1);
4406   struct mg_iobuf *io = c->is_tls ? &s->raw : &c->recv;
4407   uint32_t seq = mg_ntohl(pkt->tcp->seq);
4408   s->raw.align = c->recv.align;
4409   uint32_t rem_ip;
4410   memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t));
4411   if (pkt->tcp->flags & TH_FIN) {
4412     // If we initiated the closure, we reply with ACK upon receiving FIN
4413     // If we didn't initiate it, we reply with FIN as part of the normal TCP
4414     // closure process
4415     uint8_t flags = TH_ACK;
4416     s->ack = (uint32_t) (mg_htonl(pkt->tcp->seq) + pkt->pay.len + 1);
4417     if (c->is_draining && s->ttype == MIP_TTYPE_FIN) {
4418       if (s->seq == mg_htonl(pkt->tcp->ack))
4419         // Checking for simultaneous closure
4420         s->seq++;
4421       else
4422         s->seq = mg_htonl(pkt->tcp->ack);
4423     } else {
4424       flags |= TH_FIN;
4425       c->is_draining = 1;
4426       settmout(c, MIP_TTYPE_FIN);
4427     }
4428     tx_tcp((struct mg_tcpip_if *) c->mgr->priv, s->mac, rem_ip, flags,
4429            c->loc.port, c->rem.port, mg_htonl(s->seq), mg_htonl(s->ack), "", 0);
4430   } else if (pkt->pay.len == 0) {
4431     // TODO(cpq): handle this peer's ACK
4432   } else if (seq != s->ack) {
4433     uint32_t ack = (uint32_t) (mg_htonl(pkt->tcp->seq) + pkt->pay.len);
4434     if (s->ack == ack) {
4435       MG_VERBOSE(("ignoring duplicate pkt"));
4436     } else {
4437       MG_VERBOSE(("SEQ != ACK: %x %x %x", seq, s->ack, ack));
4438       tx_tcp((struct mg_tcpip_if *) c->mgr->priv, s->mac, rem_ip, TH_ACK,
4439              c->loc.port, c->rem.port, mg_htonl(s->seq), mg_htonl(s->ack), "",
4440              0);
4441     }
4442   } else if (io->size - io->len < pkt->pay.len &&
4443              !mg_iobuf_resize(io, io->len + pkt->pay.len)) {
4444     mg_error(c, "oom");
4445   } else {
4446     // Copy TCP payload into the IO buffer. If the connection is plain text,
4447     // we copy to c->recv. If the connection is TLS, this data is encrypted,
4448     // therefore we copy that encrypted data to the s->raw iobuffer instead,
4449     // and then call mg_tls_recv() to decrypt it. NOTE: mg_tls_recv() will
4450     // call back mg_io_recv() which grabs raw data from s->raw
4451     memcpy(&io->buf[io->len], pkt->pay.ptr, pkt->pay.len);
4452     io->len += pkt->pay.len;
4453
4454     MG_VERBOSE(("%lu SEQ %x -> %x", c->id, mg_htonl(pkt->tcp->seq), s->ack));
4455     // Advance ACK counter
4456     s->ack = (uint32_t) (mg_htonl(pkt->tcp->seq) + pkt->pay.len);
4457 #if 0
4458     // Send ACK immediately
4459     uint32_t rem_ip;
4460     memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t));
4461     MG_DEBUG(("  imm ACK", c->id, mg_htonl(pkt->tcp->seq), s->ack));
4462     tx_tcp((struct mg_tcpip_if *) c->mgr->priv, s->mac, rem_ip, TH_ACK, c->loc.port,
4463            c->rem.port, mg_htonl(s->seq), mg_htonl(s->ack), "", 0);
4464 #else
4465     // if not already running, setup a timer to send an ACK later
4466     if (s->ttype != MIP_TTYPE_ACK) settmout(c, MIP_TTYPE_ACK);
4467 #endif
4468
4469     if (c->is_tls) {
4470       // TLS connection. Make room for decrypted data in c->recv
4471       io = &c->recv;
4472       if (io->size - io->len < pkt->pay.len &&
4473           !mg_iobuf_resize(io, io->len + pkt->pay.len)) {
4474         mg_error(c, "oom");
4475       } else {
4476         // Decrypt data directly into c->recv
4477         long n = mg_tls_recv(c, &io->buf[io->len], io->size - io->len);
4478         if (n == MG_IO_ERR) {
4479           mg_error(c, "TLS recv error");
4480         } else if (n > 0) {
4481           // Decrypted successfully - trigger MG_EV_READ
4482           io->len += (size_t) n;
4483           mg_call(c, MG_EV_READ, &n);
4484         }
4485       }
4486     } else {
4487       // Plain text connection, data is already in c->recv, trigger
4488       // MG_EV_READ
4489       mg_call(c, MG_EV_READ, &pkt->pay.len);
4490     }
4491   }
4492 }
4493
4494 static void rx_tcp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
4495   struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
4496   struct connstate *s = c == NULL ? NULL : (struct connstate *) (c + 1);
4497 #if 0
4498   MG_INFO(("%lu %hhu %d", c ? c->id : 0, pkt->tcp->flags, (int) pkt->pay.len));
4499 #endif
4500   if (c != NULL && c->is_connecting && pkt->tcp->flags & (TH_SYN | TH_ACK)) {
4501     s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq) + 1;
4502     tx_tcp_pkt(ifp, pkt, TH_ACK, pkt->tcp->ack, NULL, 0);
4503     c->is_connecting = 0;  // Client connected
4504     settmout(c, MIP_TTYPE_KEEPALIVE);
4505     mg_call(c, MG_EV_CONNECT, NULL);  // Let user know
4506   } else if (c != NULL && c->is_connecting) {
4507     // mg_hexdump(pkt->raw.ptr, pkt->raw.len);
4508     tx_tcp_pkt(ifp, pkt, TH_RST | TH_ACK, pkt->tcp->ack, NULL, 0);
4509   } else if (c != NULL && pkt->tcp->flags & TH_RST) {
4510     mg_error(c, "peer RST");  // RFC-1122 4.2.2.13
4511   } else if (c != NULL) {
4512 #if 0
4513     MG_DEBUG(("%lu %d %M:%hu -> %M:%hu", c->id, (int) pkt->raw.len,
4514               mg_print_ip4, &pkt->ip->src, mg_ntohs(pkt->tcp->sport),
4515               mg_print_ip4, &pkt->ip->dst, mg_ntohs(pkt->tcp->dport)));
4516     mg_hexdump(pkt->pay.ptr, pkt->pay.len);
4517 #endif
4518     s->tmiss = 0;                         // Reset missed keep-alive counter
4519     if (s->ttype == MIP_TTYPE_KEEPALIVE)  // Advance keep-alive timer
4520       settmout(c,
4521                MIP_TTYPE_KEEPALIVE);  // unless a former ACK timeout is pending
4522     read_conn(c, pkt);  // Override timer with ACK timeout if needed
4523   } else if ((c = getpeer(ifp->mgr, pkt, true)) == NULL) {
4524     tx_tcp_pkt(ifp, pkt, TH_RST | TH_ACK, pkt->tcp->ack, NULL, 0);
4525   } else if (pkt->tcp->flags & TH_RST) {
4526     if (c->is_accepted) mg_error(c, "peer RST");  // RFC-1122 4.2.2.13
4527     // ignore RST if not connected
4528   } else if (pkt->tcp->flags & TH_SYN) {
4529     // Use peer's source port as ISN, in order to recognise the handshake
4530     uint32_t isn = mg_htonl((uint32_t) mg_ntohs(pkt->tcp->sport));
4531     tx_tcp_pkt(ifp, pkt, TH_SYN | TH_ACK, isn, NULL, 0);
4532   } else if (pkt->tcp->flags & TH_FIN) {
4533     tx_tcp_pkt(ifp, pkt, TH_FIN | TH_ACK, pkt->tcp->ack, NULL, 0);
4534   } else if (mg_htonl(pkt->tcp->ack) == mg_htons(pkt->tcp->sport) + 1U) {
4535     accept_conn(c, pkt);
4536   } else if (!c->is_accepted) {  // no peer
4537     tx_tcp_pkt(ifp, pkt, TH_RST | TH_ACK, pkt->tcp->ack, NULL, 0);
4538   } else {
4539     // MG_VERBOSE(("dropped silently.."));
4540   }
4541 }
4542
4543 static void rx_ip(struct mg_tcpip_if *ifp, struct pkt *pkt) {
4544   if (pkt->ip->proto == 1) {
4545     pkt->icmp = (struct icmp *) (pkt->ip + 1);
4546     if (pkt->pay.len < sizeof(*pkt->icmp)) return;
4547     mkpay(pkt, pkt->icmp + 1);
4548     rx_icmp(ifp, pkt);
4549   } else if (pkt->ip->proto == 17) {
4550     pkt->udp = (struct udp *) (pkt->ip + 1);
4551     if (pkt->pay.len < sizeof(*pkt->udp)) return;
4552     mkpay(pkt, pkt->udp + 1);
4553     MG_VERBOSE(("UDP %M:%hu -> %M:%hu len %u", mg_print_ip4, &pkt->ip->src,
4554                 mg_ntohs(pkt->udp->sport), mg_print_ip4, &pkt->ip->dst,
4555                 mg_ntohs(pkt->udp->dport), (int) pkt->pay.len));
4556     if (ifp->enable_dhcp_client && pkt->udp->dport == mg_htons(68)) {
4557       pkt->dhcp = (struct dhcp *) (pkt->udp + 1);
4558       mkpay(pkt, pkt->dhcp + 1);
4559       rx_dhcp_client(ifp, pkt);
4560     } else if (ifp->enable_dhcp_server && pkt->udp->dport == mg_htons(67)) {
4561       pkt->dhcp = (struct dhcp *) (pkt->udp + 1);
4562       mkpay(pkt, pkt->dhcp + 1);
4563       rx_dhcp_server(ifp, pkt);
4564     } else {
4565       rx_udp(ifp, pkt);
4566     }
4567   } else if (pkt->ip->proto == 6) {
4568     pkt->tcp = (struct tcp *) (pkt->ip + 1);
4569     if (pkt->pay.len < sizeof(*pkt->tcp)) return;
4570     mkpay(pkt, pkt->tcp + 1);
4571     uint16_t iplen = mg_ntohs(pkt->ip->len);
4572     uint16_t off = (uint16_t) (sizeof(*pkt->ip) + ((pkt->tcp->off >> 4) * 4U));
4573     if (iplen >= off) pkt->pay.len = (size_t) (iplen - off);
4574     MG_VERBOSE(("TCP %M:%hu -> %M:%hu len %u", mg_print_ip4, &pkt->ip->src,
4575                 mg_ntohs(pkt->tcp->sport), mg_print_ip4, &pkt->ip->dst,
4576                 mg_ntohs(pkt->tcp->dport), (int) pkt->pay.len));
4577     rx_tcp(ifp, pkt);
4578   }
4579 }
4580
4581 static void rx_ip6(struct mg_tcpip_if *ifp, struct pkt *pkt) {
4582   // MG_DEBUG(("IP %d", (int) len));
4583   if (pkt->ip6->proto == 1 || pkt->ip6->proto == 58) {
4584     pkt->icmp = (struct icmp *) (pkt->ip6 + 1);
4585     if (pkt->pay.len < sizeof(*pkt->icmp)) return;
4586     mkpay(pkt, pkt->icmp + 1);
4587     rx_icmp(ifp, pkt);
4588   } else if (pkt->ip6->proto == 17) {
4589     pkt->udp = (struct udp *) (pkt->ip6 + 1);
4590     if (pkt->pay.len < sizeof(*pkt->udp)) return;
4591     // MG_DEBUG(("  UDP %u %u -> %u", len, mg_htons(udp->sport),
4592     // mg_htons(udp->dport)));
4593     mkpay(pkt, pkt->udp + 1);
4594   }
4595 }
4596
4597 static void mg_tcpip_rx(struct mg_tcpip_if *ifp, void *buf, size_t len) {
4598   struct pkt pkt;
4599   memset(&pkt, 0, sizeof(pkt));
4600   pkt.raw.ptr = (char *) buf;
4601   pkt.raw.len = len;
4602   pkt.eth = (struct eth *) buf;
4603   // mg_hexdump(buf, len > 16 ? 16: len);
4604   if (pkt.raw.len < sizeof(*pkt.eth)) return;  // Truncated - runt?
4605   if (ifp->enable_mac_check &&
4606       memcmp(pkt.eth->dst, ifp->mac, sizeof(pkt.eth->dst)) != 0 &&
4607       memcmp(pkt.eth->dst, broadcast, sizeof(pkt.eth->dst)) != 0)
4608     return;
4609   if (ifp->enable_crc32_check && len > 4) {
4610     len -= 4;  // TODO(scaprile): check on bigendian
4611     uint32_t crc = mg_crc32(0, (const char *) buf, len);
4612     if (memcmp((void *) ((size_t) buf + len), &crc, sizeof(crc))) return;
4613   }
4614   if (pkt.eth->type == mg_htons(0x806)) {
4615     pkt.arp = (struct arp *) (pkt.eth + 1);
4616     if (sizeof(*pkt.eth) + sizeof(*pkt.arp) > pkt.raw.len) return;  // Truncated
4617     rx_arp(ifp, &pkt);
4618   } else if (pkt.eth->type == mg_htons(0x86dd)) {
4619     pkt.ip6 = (struct ip6 *) (pkt.eth + 1);
4620     if (pkt.raw.len < sizeof(*pkt.eth) + sizeof(*pkt.ip6)) return;  // Truncated
4621     if ((pkt.ip6->ver >> 4) != 0x6) return;                         // Not IP
4622     mkpay(&pkt, pkt.ip6 + 1);
4623     rx_ip6(ifp, &pkt);
4624   } else if (pkt.eth->type == mg_htons(0x800)) {
4625     pkt.ip = (struct ip *) (pkt.eth + 1);
4626     if (pkt.raw.len < sizeof(*pkt.eth) + sizeof(*pkt.ip)) return;  // Truncated
4627     // Truncate frame to what IP header tells us
4628     if ((size_t) mg_ntohs(pkt.ip->len) + sizeof(struct eth) < pkt.raw.len) {
4629       pkt.raw.len = (size_t) mg_ntohs(pkt.ip->len) + sizeof(struct eth);
4630     }
4631     if (pkt.raw.len < sizeof(*pkt.eth) + sizeof(*pkt.ip)) return;  // Truncated
4632     if ((pkt.ip->ver >> 4) != 4) return;                           // Not IP
4633     mkpay(&pkt, pkt.ip + 1);
4634     rx_ip(ifp, &pkt);
4635   } else {
4636     MG_DEBUG(("Unknown eth type %x", mg_htons(pkt.eth->type)));
4637     //mg_hexdump(buf, len >= 32 ? 32 : len);
4638   }
4639 }
4640
4641 static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t uptime_ms) {
4642   if (ifp == NULL || ifp->driver == NULL) return;
4643   bool expired_1000ms = mg_timer_expired(&ifp->timer_1000ms, 1000, uptime_ms);
4644   ifp->now = uptime_ms;
4645
4646   // Handle physical interface up/down status
4647   if (expired_1000ms && ifp->driver->up) {
4648     bool up = ifp->driver->up(ifp);
4649     bool current = ifp->state != MG_TCPIP_STATE_DOWN;
4650     if (up != current) {
4651       ifp->state = up == false               ? MG_TCPIP_STATE_DOWN
4652                    : ifp->enable_dhcp_client ? MG_TCPIP_STATE_UP
4653                                              : MG_TCPIP_STATE_READY;
4654       if (!up && ifp->enable_dhcp_client) ifp->ip = 0;
4655       onstatechange(ifp);
4656     }
4657   }
4658   if (ifp->state == MG_TCPIP_STATE_DOWN) return;
4659
4660   // DHCP RFC-2131 (4.4)
4661   if (ifp->state == MG_TCPIP_STATE_UP && expired_1000ms) {
4662     tx_dhcp_discover(ifp);  // INIT (4.4.1)
4663   } else if (expired_1000ms && ifp->state == MG_TCPIP_STATE_READY &&
4664              ifp->lease_expire > 0) {  // BOUND / RENEWING / REBINDING
4665     if (ifp->now >= ifp->lease_expire) {
4666       ifp->state = MG_TCPIP_STATE_UP, ifp->ip = 0;  // expired, release IP
4667       onstatechange(ifp);
4668     } else if (ifp->now + 30UL * 60UL * 1000UL > ifp->lease_expire &&
4669                ((ifp->now / 1000) % 60) == 0) {
4670       // hack: 30 min before deadline, try to rebind (4.3.6) every min
4671       tx_dhcp_request_re(ifp, (uint8_t *) broadcast, ifp->ip, 0xffffffff);
4672     }  // TODO(): Handle T1 (RENEWING) and T2 (REBINDING) (4.4.5)
4673   }
4674
4675   // Read data from the network
4676   if (ifp->driver->rx != NULL) {  // Polling driver. We must call it
4677     size_t len =
4678         ifp->driver->rx(ifp->recv_queue.buf, ifp->recv_queue.size, ifp);
4679     if (len > 0) mg_tcpip_rx(ifp, ifp->recv_queue.buf, len);
4680   } else {  // Interrupt-based driver. Fills recv queue itself
4681     char *buf;
4682     size_t len = mg_queue_next(&ifp->recv_queue, &buf);
4683     if (len > 0) {
4684       mg_tcpip_rx(ifp, buf, len);
4685       mg_queue_del(&ifp->recv_queue, len);
4686     }
4687   }
4688
4689   // Process timeouts
4690   for (struct mg_connection *c = ifp->mgr->conns; c != NULL; c = c->next) {
4691     if (c->is_udp || c->is_listening || c->is_resolving) continue;
4692     struct connstate *s = (struct connstate *) (c + 1);
4693     uint32_t rem_ip;
4694     memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t));
4695     if (uptime_ms > s->timer) {
4696       if (s->ttype == MIP_TTYPE_ACK) {
4697         MG_VERBOSE(("%lu ack %x %x", c->id, s->seq, s->ack));
4698         tx_tcp(ifp, s->mac, rem_ip, TH_ACK, c->loc.port, c->rem.port,
4699                mg_htonl(s->seq), mg_htonl(s->ack), "", 0);
4700       } else if (s->ttype == MIP_TTYPE_ARP) {
4701         mg_error(c, "ARP timeout");
4702       } else if (s->ttype == MIP_TTYPE_SYN) {
4703         mg_error(c, "Connection timeout");
4704       } else if (s->ttype == MIP_TTYPE_FIN) {
4705         c->is_closing = 1;
4706         continue;
4707       } else {
4708         if (s->tmiss++ > 2) {
4709           mg_error(c, "keepalive");
4710         } else {
4711           MG_VERBOSE(("%lu keepalive", c->id));
4712           tx_tcp(ifp, s->mac, rem_ip, TH_ACK, c->loc.port, c->rem.port,
4713                  mg_htonl(s->seq - 1), mg_htonl(s->ack), "", 0);
4714         }
4715       }
4716
4717       settmout(c, MIP_TTYPE_KEEPALIVE);
4718     }
4719   }
4720 }
4721
4722 // This function executes in interrupt context, thus it should copy data
4723 // somewhere fast. Note that newlib's malloc is not thread safe, thus use
4724 // our lock-free queue with preallocated buffer to copy data and return asap
4725 void mg_tcpip_qwrite(void *buf, size_t len, struct mg_tcpip_if *ifp) {
4726   char *p;
4727   if (mg_queue_book(&ifp->recv_queue, &p, len) >= len) {
4728     memcpy(p, buf, len);
4729     mg_queue_add(&ifp->recv_queue, len);
4730     ifp->nrecv++;
4731   } else {
4732     ifp->ndrop++;
4733   }
4734 }
4735
4736 void mg_tcpip_init(struct mg_mgr *mgr, struct mg_tcpip_if *ifp) {
4737   // If MAC address is not set, make a random one
4738   if (ifp->mac[0] == 0 && ifp->mac[1] == 0 && ifp->mac[2] == 0 &&
4739       ifp->mac[3] == 0 && ifp->mac[4] == 0 && ifp->mac[5] == 0) {
4740     ifp->mac[0] = 0x02;  // Locally administered, unicast
4741     mg_random(&ifp->mac[1], sizeof(ifp->mac) - 1);
4742     MG_INFO(("MAC not set. Generated random: %M", mg_print_mac, ifp->mac));
4743   }
4744
4745   if (ifp->driver->init && !ifp->driver->init(ifp)) {
4746     MG_ERROR(("driver init failed"));
4747   } else {
4748     size_t framesize = 1540;
4749     ifp->tx.ptr = (char *) calloc(1, framesize), ifp->tx.len = framesize;
4750     if (ifp->recv_queue.size == 0)
4751       ifp->recv_queue.size = ifp->driver->rx ? framesize : 8192;
4752     ifp->recv_queue.buf = (char *) calloc(1, ifp->recv_queue.size);
4753     ifp->timer_1000ms = mg_millis();
4754     mgr->priv = ifp;
4755     ifp->mgr = mgr;
4756     mgr->extraconnsize = sizeof(struct connstate);
4757     if (ifp->ip == 0) ifp->enable_dhcp_client = true;
4758     memset(ifp->gwmac, 255, sizeof(ifp->gwmac));  // Set to broadcast
4759     mg_random(&ifp->eport, sizeof(ifp->eport));   // Random from 0 to 65535
4760     ifp->eport |= MG_EPHEMERAL_PORT_BASE;         // Random from
4761                                            // MG_EPHEMERAL_PORT_BASE to 65535
4762     if (ifp->tx.ptr == NULL || ifp->recv_queue.buf == NULL) MG_ERROR(("OOM"));
4763   }
4764 }
4765
4766 void mg_tcpip_free(struct mg_tcpip_if *ifp) {
4767   free(ifp->recv_queue.buf);
4768   free((char *) ifp->tx.ptr);
4769 }
4770
4771 int mg_mkpipe(struct mg_mgr *m, mg_event_handler_t fn, void *d, bool udp) {
4772   (void) m, (void) fn, (void) d, (void) udp;
4773   MG_ERROR(("Not implemented"));
4774   return -1;
4775 }
4776
4777 static void send_syn(struct mg_connection *c) {
4778   struct connstate *s = (struct connstate *) (c + 1);
4779   uint32_t isn = mg_htonl((uint32_t) mg_ntohs(c->loc.port));
4780   struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
4781   uint32_t rem_ip;
4782   memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t));
4783   tx_tcp(ifp, s->mac, rem_ip, TH_SYN, c->loc.port, c->rem.port, isn, 0, NULL,
4784          0);
4785 }
4786
4787 void mg_connect_resolved(struct mg_connection *c) {
4788   struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
4789   uint32_t rem_ip;
4790   memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t));
4791   c->is_resolving = 0;
4792   if (ifp->eport < MG_EPHEMERAL_PORT_BASE) ifp->eport = MG_EPHEMERAL_PORT_BASE;
4793   memcpy(c->loc.ip, &ifp->ip, sizeof(uint32_t));
4794   c->loc.port = mg_htons(ifp->eport++);
4795   MG_DEBUG(("%lu %M -> %M", c->id, mg_print_ip_port, &c->loc, mg_print_ip_port,
4796             &c->rem));
4797   mg_call(c, MG_EV_RESOLVE, NULL);
4798   if (((rem_ip & ifp->mask) == (ifp->ip & ifp->mask))) {
4799     // If we're in the same LAN, fire an ARP lookup.
4800     MG_DEBUG(("%lu ARP lookup...", c->id));
4801     arp_ask(ifp, rem_ip);
4802     settmout(c, MIP_TTYPE_ARP);
4803     c->is_arplooking = 1;
4804     c->is_connecting = 1;
4805   } else if (rem_ip == (ifp->ip | ~ifp->mask)) {
4806     struct connstate *s = (struct connstate *) (c + 1);
4807     memset(s->mac, 0xFF, sizeof(s->mac));  // local broadcast
4808   } else if ((*((uint8_t *) &rem_ip) & 0xE0) == 0xE0) {
4809     struct connstate *s = (struct connstate *) (c + 1);  // 224 to 239, E0 to EF
4810     uint8_t mcastp[3] = {0x01, 0x00, 0x5E};              // multicast group
4811     memcpy(s->mac, mcastp, 3);
4812     memcpy(s->mac + 3, ((uint8_t *) &rem_ip) + 1, 3);  // 23 LSb
4813     s->mac[3] &= 0x7F;
4814   } else {
4815     struct connstate *s = (struct connstate *) (c + 1);
4816     memcpy(s->mac, ifp->gwmac, sizeof(ifp->gwmac));
4817     if (c->is_udp) {
4818       mg_call(c, MG_EV_CONNECT, NULL);
4819     } else {
4820       send_syn(c);
4821       settmout(c, MIP_TTYPE_SYN);
4822       c->is_connecting = 1;
4823     }
4824   }
4825 }
4826
4827 bool mg_open_listener(struct mg_connection *c, const char *url) {
4828   c->loc.port = mg_htons(mg_url_port(url));
4829   return true;
4830 }
4831
4832 static void write_conn(struct mg_connection *c) {
4833   long len = c->is_tls ? mg_tls_send(c, c->send.buf, c->send.len)
4834                        : mg_io_send(c, c->send.buf, c->send.len);
4835   if (len > 0) {
4836     mg_iobuf_del(&c->send, 0, (size_t) len);
4837     mg_call(c, MG_EV_WRITE, &len);
4838   }
4839 }
4840
4841 static void init_closure(struct mg_connection *c) {
4842   struct connstate *s = (struct connstate *) (c + 1);
4843   if (c->is_udp == false && c->is_listening == false &&
4844       c->is_connecting == false) {  // For TCP conns,
4845     struct mg_tcpip_if *ifp =
4846         (struct mg_tcpip_if *) c->mgr->priv;  // send TCP FIN
4847     uint32_t rem_ip;
4848     memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t));
4849     tx_tcp(ifp, s->mac, rem_ip, TH_FIN | TH_ACK, c->loc.port, c->rem.port,
4850            mg_htonl(s->seq), mg_htonl(s->ack), NULL, 0);
4851     settmout(c, MIP_TTYPE_FIN);
4852   }
4853 }
4854
4855 static void close_conn(struct mg_connection *c) {
4856   struct connstate *s = (struct connstate *) (c + 1);
4857   mg_iobuf_free(&s->raw);  // For TLS connections, release raw data
4858   mg_close_conn(c);
4859 }
4860
4861 static bool can_write(struct mg_connection *c) {
4862   return c->is_connecting == 0 && c->is_resolving == 0 && c->send.len > 0 &&
4863          c->is_tls_hs == 0 && c->is_arplooking == 0;
4864 }
4865
4866 void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
4867   struct mg_connection *c, *tmp;
4868   uint64_t now = mg_millis();
4869   mg_tcpip_poll((struct mg_tcpip_if *) mgr->priv, now);
4870   mg_timer_poll(&mgr->timers, now);
4871   for (c = mgr->conns; c != NULL; c = tmp) {
4872     tmp = c->next;
4873     struct connstate *s = (struct connstate *) (c + 1);
4874     mg_call(c, MG_EV_POLL, &now);
4875     MG_VERBOSE(("%lu .. %c%c%c%c%c", c->id, c->is_tls ? 'T' : 't',
4876                 c->is_connecting ? 'C' : 'c', c->is_tls_hs ? 'H' : 'h',
4877                 c->is_resolving ? 'R' : 'r', c->is_closing ? 'C' : 'c'));
4878     if (c->is_tls_hs) mg_tls_handshake(c);
4879     if (can_write(c)) write_conn(c);
4880     if (c->is_draining && c->send.len == 0 && s->ttype != MIP_TTYPE_FIN)
4881       init_closure(c);
4882     if (c->is_closing) close_conn(c);
4883   }
4884   (void) ms;
4885 }
4886
4887 bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
4888   struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
4889   bool res = false;
4890   uint32_t rem_ip;
4891   memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t));
4892   if (ifp->ip == 0 || ifp->state != MG_TCPIP_STATE_READY) {
4893     mg_error(c, "net down");
4894   } else if (c->is_udp) {
4895     struct connstate *s = (struct connstate *) (c + 1);
4896     tx_udp(ifp, s->mac, ifp->ip, c->loc.port, rem_ip, c->rem.port, buf, len);
4897     res = true;
4898   } else {
4899     res = mg_iobuf_add(&c->send, c->send.len, buf, len);
4900   }
4901   return res;
4902 }
4903 #endif  // MG_ENABLE_TCPIP
4904
4905 #ifdef MG_ENABLE_LINES
4906 #line 1 "src/printf.c"
4907 #endif
4908
4909
4910
4911
4912 size_t mg_queue_vprintf(struct mg_queue *q, const char *fmt, va_list *ap) {
4913   size_t len = mg_snprintf(NULL, 0, fmt, ap);
4914   char *buf;
4915   if (len == 0 || mg_queue_book(q, &buf, len + 1) < len + 1) {
4916     len = 0;  // Nah. Not enough space
4917   } else {
4918     len = mg_vsnprintf((char *) buf, len + 1, fmt, ap);
4919     mg_queue_add(q, len);
4920   }
4921   return len;
4922 }
4923
4924 size_t mg_queue_printf(struct mg_queue *q, const char *fmt, ...) {
4925   va_list ap;
4926   size_t len;
4927   va_start(ap, fmt);
4928   len = mg_queue_vprintf(q, fmt, &ap);
4929   va_end(ap);
4930   return len;
4931 }
4932
4933 static void mg_pfn_iobuf_private(char ch, void *param, bool expand) {
4934   struct mg_iobuf *io = (struct mg_iobuf *) param;
4935   if (expand && io->len + 2 > io->size) mg_iobuf_resize(io, io->len + 2);
4936   if (io->len + 2 <= io->size) {
4937     io->buf[io->len++] = (uint8_t) ch;
4938     io->buf[io->len] = 0;
4939   } else if (io->len < io->size) {
4940     io->buf[io->len++] = 0;  // Guarantee to 0-terminate
4941   }
4942 }
4943
4944 static void mg_putchar_iobuf_static(char ch, void *param) {
4945   mg_pfn_iobuf_private(ch, param, false);
4946 }
4947
4948 void mg_pfn_iobuf(char ch, void *param) {
4949   mg_pfn_iobuf_private(ch, param, true);
4950 }
4951
4952 size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap) {
4953   struct mg_iobuf io = {(uint8_t *) buf, len, 0, 0};
4954   size_t n = mg_vxprintf(mg_putchar_iobuf_static, &io, fmt, ap);
4955   if (n < len) buf[n] = '\0';
4956   return n;
4957 }
4958
4959 size_t mg_snprintf(char *buf, size_t len, const char *fmt, ...) {
4960   va_list ap;
4961   size_t n;
4962   va_start(ap, fmt);
4963   n = mg_vsnprintf(buf, len, fmt, &ap);
4964   va_end(ap);
4965   return n;
4966 }
4967
4968 char *mg_vmprintf(const char *fmt, va_list *ap) {
4969   struct mg_iobuf io = {0, 0, 0, 256};
4970   mg_vxprintf(mg_pfn_iobuf, &io, fmt, ap);
4971   return (char *) io.buf;
4972 }
4973
4974 char *mg_mprintf(const char *fmt, ...) {
4975   char *s;
4976   va_list ap;
4977   va_start(ap, fmt);
4978   s = mg_vmprintf(fmt, &ap);
4979   va_end(ap);
4980   return s;
4981 }
4982
4983 void mg_pfn_stdout(char c, void *param) {
4984   putchar(c);
4985   (void) param;
4986 }
4987
4988 static size_t print_ip4(void (*out)(char, void *), void *arg, uint8_t *p) {
4989   return mg_xprintf(out, arg, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
4990 }
4991
4992 static size_t print_ip6(void (*out)(char, void *), void *arg, uint16_t *p) {
4993   return mg_xprintf(out, arg, "[%x:%x:%x:%x:%x:%x:%x:%x]", mg_ntohs(p[0]),
4994                     mg_ntohs(p[1]), mg_ntohs(p[2]), mg_ntohs(p[3]),
4995                     mg_ntohs(p[4]), mg_ntohs(p[5]), mg_ntohs(p[6]),
4996                     mg_ntohs(p[7]));
4997 }
4998
4999 size_t mg_print_ip4(void (*out)(char, void *), void *arg, va_list *ap) {
5000   uint8_t *p = va_arg(*ap, uint8_t *);
5001   return print_ip4(out, arg, p);
5002 }
5003
5004 size_t mg_print_ip6(void (*out)(char, void *), void *arg, va_list *ap) {
5005   uint16_t *p = va_arg(*ap, uint16_t *);
5006   return print_ip6(out, arg, p);
5007 }
5008
5009 size_t mg_print_ip(void (*out)(char, void *), void *arg, va_list *ap) {
5010   struct mg_addr *addr = va_arg(*ap, struct mg_addr *);
5011   if (addr->is_ip6) return print_ip6(out, arg, (uint16_t *) addr->ip);
5012   return print_ip4(out, arg, (uint8_t *) &addr->ip);
5013 }
5014
5015 size_t mg_print_ip_port(void (*out)(char, void *), void *arg, va_list *ap) {
5016   struct mg_addr *a = va_arg(*ap, struct mg_addr *);
5017   return mg_xprintf(out, arg, "%M:%hu", mg_print_ip, a, mg_ntohs(a->port));
5018 }
5019
5020 size_t mg_print_mac(void (*out)(char, void *), void *arg, va_list *ap) {
5021   uint8_t *p = va_arg(*ap, uint8_t *);
5022   return mg_xprintf(out, arg, "%02x:%02x:%02x:%02x:%02x:%02x", p[0], p[1], p[2],
5023                     p[3], p[4], p[5]);
5024 }
5025
5026 static char mg_esc(int c, bool esc) {
5027   const char *p, *esc1 = "\b\f\n\r\t\\\"", *esc2 = "bfnrt\\\"";
5028   for (p = esc ? esc1 : esc2; *p != '\0'; p++) {
5029     if (*p == c) return esc ? esc2[p - esc1] : esc1[p - esc2];
5030   }
5031   return 0;
5032 }
5033
5034 static char mg_escape(int c) {
5035   return mg_esc(c, true);
5036 }
5037
5038 static size_t qcpy(void (*out)(char, void *), void *ptr, char *buf,
5039                    size_t len) {
5040   size_t i = 0, extra = 0;
5041   for (i = 0; i < len && buf[i] != '\0'; i++) {
5042     char c = mg_escape(buf[i]);
5043     if (c) {
5044       out('\\', ptr), out(c, ptr), extra++;
5045     } else {
5046       out(buf[i], ptr);
5047     }
5048   }
5049   return i + extra;
5050 }
5051
5052 static size_t bcpy(void (*out)(char, void *), void *arg, uint8_t *buf,
5053                    size_t len) {
5054   size_t i, j, n = 0;
5055   const char *t =
5056       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
5057   for (i = 0; i < len; i += 3) {
5058     uint8_t c1 = buf[i], c2 = i + 1 < len ? buf[i + 1] : 0,
5059             c3 = i + 2 < len ? buf[i + 2] : 0;
5060     char tmp[4] = {t[c1 >> 2], t[(c1 & 3) << 4 | (c2 >> 4)], '=', '='};
5061     if (i + 1 < len) tmp[2] = t[(c2 & 15) << 2 | (c3 >> 6)];
5062     if (i + 2 < len) tmp[3] = t[c3 & 63];
5063     for (j = 0; j < sizeof(tmp) && tmp[j] != '\0'; j++) out(tmp[j], arg);
5064     n += j;
5065   }
5066   return n;
5067 }
5068
5069 size_t mg_print_hex(void (*out)(char, void *), void *arg, va_list *ap) {
5070   size_t bl = (size_t) va_arg(*ap, int);
5071   uint8_t *p = va_arg(*ap, uint8_t *);
5072   const char *hex = "0123456789abcdef";
5073   size_t j;
5074   for (j = 0; j < bl; j++) {
5075     out(hex[(p[j] >> 4) & 0x0F], arg);
5076     out(hex[p[j] & 0x0F], arg);
5077   }
5078   return 2 * bl;
5079 }
5080 size_t mg_print_base64(void (*out)(char, void *), void *arg, va_list *ap) {
5081   size_t len = (size_t) va_arg(*ap, int);
5082   uint8_t *buf = va_arg(*ap, uint8_t *);
5083   return bcpy(out, arg, buf, len);
5084 }
5085
5086 size_t mg_print_esc(void (*out)(char, void *), void *arg, va_list *ap) {
5087   size_t len = (size_t) va_arg(*ap, int);
5088   char *p = va_arg(*ap, char *);
5089   if (len == 0) len = p == NULL ? 0 : strlen(p);
5090   return qcpy(out, arg, p, len);
5091 }
5092
5093 #ifdef MG_ENABLE_LINES
5094 #line 1 "src/queue.c"
5095 #endif
5096
5097
5098
5099 #if defined(__GNUC__) || defined(__clang__)
5100 #define MG_MEMORY_BARRIER() __sync_synchronize()
5101 #elif defined(_MSC_VER) && _MSC_VER >= 1700
5102 #define MG_MEMORY_BARRIER() MemoryBarrier()
5103 #elif !defined(MG_MEMORY_BARRIER)
5104 #define MG_MEMORY_BARRIER()
5105 #endif
5106
5107 // Every message in a queue is prepended by a 32-bit message length (ML).
5108 // If ML is 0, then it is the end, and reader must wrap to the beginning.
5109 //
5110 //  Queue when q->tail <= q->head:
5111 //  |----- free -----| ML | message1 | ML | message2 |  ----- free ------|
5112 //  ^                ^                               ^                   ^
5113 // buf              tail                            head                len
5114 //
5115 //  Queue when q->tail > q->head:
5116 //  | ML | message2 |----- free ------| ML | message1 | 0 |---- free ----|
5117 //  ^               ^                 ^                                  ^
5118 // buf             head              tail                               len
5119
5120 void mg_queue_init(struct mg_queue *q, char *buf, size_t size) {
5121   q->size = size;
5122   q->buf = buf;
5123   q->head = q->tail = 0;
5124 }
5125
5126 static size_t mg_queue_read_len(struct mg_queue *q) {
5127   uint32_t n = 0;
5128   MG_MEMORY_BARRIER();
5129   memcpy(&n, q->buf + q->tail, sizeof(n));
5130   assert(q->tail + n + sizeof(n) <= q->size);
5131   return n;
5132 }
5133
5134 static void mg_queue_write_len(struct mg_queue *q, size_t len) {
5135   uint32_t n = (uint32_t) len;
5136   memcpy(q->buf + q->head, &n, sizeof(n));
5137   MG_MEMORY_BARRIER();
5138 }
5139
5140 size_t mg_queue_book(struct mg_queue *q, char **buf, size_t len) {
5141   size_t space = 0, hs = sizeof(uint32_t) * 2;  // *2 is for the 0 marker
5142   if (q->head >= q->tail && q->head + len + hs <= q->size) {
5143     space = q->size - q->head - hs;  // There is enough space
5144   } else if (q->head >= q->tail && q->tail > hs) {
5145     mg_queue_write_len(q, 0);  // Not enough space ahead
5146     q->head = 0;               // Wrap head to the beginning
5147   }
5148   if (q->head + hs + len < q->tail) space = q->tail - q->head - hs;
5149   if (buf != NULL) *buf = q->buf + q->head + sizeof(uint32_t);
5150   return space;
5151 }
5152
5153 size_t mg_queue_next(struct mg_queue *q, char **buf) {
5154   size_t len = 0;
5155   if (q->tail != q->head) {
5156     len = mg_queue_read_len(q);
5157     if (len == 0) {  // Zero (head wrapped) ?
5158       q->tail = 0;   // Reset tail to the start
5159       if (q->head > q->tail) len = mg_queue_read_len(q);  // Read again
5160     }
5161   }
5162   if (buf != NULL) *buf = q->buf + q->tail + sizeof(uint32_t);
5163   assert(q->tail + len <= q->size);
5164   return len;
5165 }
5166
5167 void mg_queue_add(struct mg_queue *q, size_t len) {
5168   assert(len > 0);
5169   mg_queue_write_len(q, len);
5170   assert(q->head + sizeof(uint32_t) * 2 + len <= q->size);
5171   q->head += len + sizeof(uint32_t);
5172 }
5173
5174 void mg_queue_del(struct mg_queue *q, size_t len) {
5175   q->tail += len + sizeof(uint32_t);
5176   assert(q->tail + sizeof(uint32_t) <= q->size);
5177 }
5178
5179 #ifdef MG_ENABLE_LINES
5180 #line 1 "src/rpc.c"
5181 #endif
5182
5183
5184
5185 void mg_rpc_add(struct mg_rpc **head, struct mg_str method,
5186                 void (*fn)(struct mg_rpc_req *), void *fn_data) {
5187   struct mg_rpc *rpc = (struct mg_rpc *) calloc(1, sizeof(*rpc));
5188   if (rpc != NULL) {
5189     rpc->method = mg_strdup(method), rpc->fn = fn, rpc->fn_data = fn_data;
5190     rpc->next = *head, *head = rpc;
5191   }
5192 }
5193
5194 void mg_rpc_del(struct mg_rpc **head, void (*fn)(struct mg_rpc_req *)) {
5195   struct mg_rpc *r;
5196   while ((r = *head) != NULL) {
5197     if (r->fn == fn || fn == NULL) {
5198       *head = r->next;
5199       free((void *) r->method.ptr);
5200       free(r);
5201     } else {
5202       head = &(*head)->next;
5203     }
5204   }
5205 }
5206
5207 static void mg_rpc_call(struct mg_rpc_req *r, struct mg_str method) {
5208   struct mg_rpc *h = r->head == NULL ? NULL : *r->head;
5209   while (h != NULL && !mg_match(method, h->method, NULL)) h = h->next;
5210   if (h != NULL) {
5211     r->rpc = h;
5212     h->fn(r);
5213   } else {
5214     mg_rpc_err(r, -32601, "\"%.*s not found\"", (int) method.len, method.ptr);
5215   }
5216 }
5217
5218 void mg_rpc_process(struct mg_rpc_req *r) {
5219   int len, off = mg_json_get(r->frame, "$.method", &len);
5220   if (off > 0 && r->frame.ptr[off] == '"') {
5221     struct mg_str method = mg_str_n(&r->frame.ptr[off + 1], (size_t) len - 2);
5222     mg_rpc_call(r, method);
5223   } else if ((off = mg_json_get(r->frame, "$.result", &len)) > 0 ||
5224              (off = mg_json_get(r->frame, "$.error", &len)) > 0) {
5225     mg_rpc_call(r, mg_str(""));  // JSON response! call "" method handler
5226   } else {
5227     mg_rpc_err(r, -32700, "%m", mg_print_esc, (int) r->frame.len,
5228                r->frame.ptr);  // Invalid
5229   }
5230 }
5231
5232 void mg_rpc_vok(struct mg_rpc_req *r, const char *fmt, va_list *ap) {
5233   int len, off = mg_json_get(r->frame, "$.id", &len);
5234   if (off > 0) {
5235     mg_xprintf(r->pfn, r->pfn_data, "{%m:%.*s,%m:", mg_print_esc, 0, "id", len,
5236                &r->frame.ptr[off], mg_print_esc, 0, "result");
5237     mg_vxprintf(r->pfn, r->pfn_data, fmt == NULL ? "null" : fmt, ap);
5238     mg_xprintf(r->pfn, r->pfn_data, "}");
5239   }
5240 }
5241
5242 void mg_rpc_ok(struct mg_rpc_req *r, const char *fmt, ...) {
5243   va_list ap;
5244   va_start(ap, fmt);
5245   mg_rpc_vok(r, fmt, &ap);
5246   va_end(ap);
5247 }
5248
5249 void mg_rpc_verr(struct mg_rpc_req *r, int code, const char *fmt, va_list *ap) {
5250   int len, off = mg_json_get(r->frame, "$.id", &len);
5251   mg_xprintf(r->pfn, r->pfn_data, "{");
5252   if (off > 0) {
5253     mg_xprintf(r->pfn, r->pfn_data, "%m:%.*s,", mg_print_esc, 0, "id", len,
5254                &r->frame.ptr[off]);
5255   }
5256   mg_xprintf(r->pfn, r->pfn_data, "%m:{%m:%d,%m:", mg_print_esc, 0, "error",
5257              mg_print_esc, 0, "code", code, mg_print_esc, 0, "message");
5258   mg_vxprintf(r->pfn, r->pfn_data, fmt == NULL ? "null" : fmt, ap);
5259   mg_xprintf(r->pfn, r->pfn_data, "}}");
5260 }
5261
5262 void mg_rpc_err(struct mg_rpc_req *r, int code, const char *fmt, ...) {
5263   va_list ap;
5264   va_start(ap, fmt);
5265   mg_rpc_verr(r, code, fmt, &ap);
5266   va_end(ap);
5267 }
5268
5269 static size_t print_methods(mg_pfn_t pfn, void *pfn_data, va_list *ap) {
5270   struct mg_rpc *h, **head = (struct mg_rpc **) va_arg(*ap, void **);
5271   size_t len = 0;
5272   for (h = *head; h != NULL; h = h->next) {
5273     if (h->method.len == 0) continue;  // Ignore response handler
5274     len += mg_xprintf(pfn, pfn_data, "%s%m", h == *head ? "" : ",",
5275                       mg_print_esc, (int) h->method.len, h->method.ptr);
5276   }
5277   return len;
5278 }
5279
5280 void mg_rpc_list(struct mg_rpc_req *r) {
5281   mg_rpc_ok(r, "[%M]", print_methods, r->head);
5282 }
5283
5284 #ifdef MG_ENABLE_LINES
5285 #line 1 "src/sha1.c"
5286 #endif
5287 /* Copyright(c) By Steve Reid <steve@edmweb.com> */
5288 /* 100% Public Domain */
5289
5290
5291
5292 union char64long16 {
5293   unsigned char c[64];
5294   uint32_t l[16];
5295 };
5296
5297 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
5298
5299 static uint32_t blk0(union char64long16 *block, int i) {
5300   if (MG_BIG_ENDIAN) {
5301   } else {
5302     block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) |
5303                   (rol(block->l[i], 8) & 0x00FF00FF);
5304   }
5305   return block->l[i];
5306 }
5307
5308 /* Avoid redefine warning (ARM /usr/include/sys/ucontext.h define R0~R4) */
5309 #undef blk
5310 #undef R0
5311 #undef R1
5312 #undef R2
5313 #undef R3
5314 #undef R4
5315
5316 #define blk(i)                                                               \
5317   (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ block->l[(i + 8) & 15] ^ \
5318                               block->l[(i + 2) & 15] ^ block->l[i & 15],     \
5319                           1))
5320 #define R0(v, w, x, y, z, i)                                          \
5321   z += ((w & (x ^ y)) ^ y) + blk0(block, i) + 0x5A827999 + rol(v, 5); \
5322   w = rol(w, 30);
5323 #define R1(v, w, x, y, z, i)                                  \
5324   z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
5325   w = rol(w, 30);
5326 #define R2(v, w, x, y, z, i)                          \
5327   z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); \
5328   w = rol(w, 30);
5329 #define R3(v, w, x, y, z, i)                                        \
5330   z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
5331   w = rol(w, 30);
5332 #define R4(v, w, x, y, z, i)                          \
5333   z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
5334   w = rol(w, 30);
5335
5336 static void mg_sha1_transform(uint32_t state[5],
5337                               const unsigned char *buffer) {
5338   uint32_t a, b, c, d, e;
5339   union char64long16 block[1];
5340
5341   memcpy(block, buffer, 64);
5342   a = state[0];
5343   b = state[1];
5344   c = state[2];
5345   d = state[3];
5346   e = state[4];
5347   R0(a, b, c, d, e, 0);
5348   R0(e, a, b, c, d, 1);
5349   R0(d, e, a, b, c, 2);
5350   R0(c, d, e, a, b, 3);
5351   R0(b, c, d, e, a, 4);
5352   R0(a, b, c, d, e, 5);
5353   R0(e, a, b, c, d, 6);
5354   R0(d, e, a, b, c, 7);
5355   R0(c, d, e, a, b, 8);
5356   R0(b, c, d, e, a, 9);
5357   R0(a, b, c, d, e, 10);
5358   R0(e, a, b, c, d, 11);
5359   R0(d, e, a, b, c, 12);
5360   R0(c, d, e, a, b, 13);
5361   R0(b, c, d, e, a, 14);
5362   R0(a, b, c, d, e, 15);
5363   R1(e, a, b, c, d, 16);
5364   R1(d, e, a, b, c, 17);
5365   R1(c, d, e, a, b, 18);
5366   R1(b, c, d, e, a, 19);
5367   R2(a, b, c, d, e, 20);
5368   R2(e, a, b, c, d, 21);
5369   R2(d, e, a, b, c, 22);
5370   R2(c, d, e, a, b, 23);
5371   R2(b, c, d, e, a, 24);
5372   R2(a, b, c, d, e, 25);
5373   R2(e, a, b, c, d, 26);
5374   R2(d, e, a, b, c, 27);
5375   R2(c, d, e, a, b, 28);
5376   R2(b, c, d, e, a, 29);
5377   R2(a, b, c, d, e, 30);
5378   R2(e, a, b, c, d, 31);
5379   R2(d, e, a, b, c, 32);
5380   R2(c, d, e, a, b, 33);
5381   R2(b, c, d, e, a, 34);
5382   R2(a, b, c, d, e, 35);
5383   R2(e, a, b, c, d, 36);
5384   R2(d, e, a, b, c, 37);
5385   R2(c, d, e, a, b, 38);
5386   R2(b, c, d, e, a, 39);
5387   R3(a, b, c, d, e, 40);
5388   R3(e, a, b, c, d, 41);
5389   R3(d, e, a, b, c, 42);
5390   R3(c, d, e, a, b, 43);
5391   R3(b, c, d, e, a, 44);
5392   R3(a, b, c, d, e, 45);
5393   R3(e, a, b, c, d, 46);
5394   R3(d, e, a, b, c, 47);
5395   R3(c, d, e, a, b, 48);
5396   R3(b, c, d, e, a, 49);
5397   R3(a, b, c, d, e, 50);
5398   R3(e, a, b, c, d, 51);
5399   R3(d, e, a, b, c, 52);
5400   R3(c, d, e, a, b, 53);
5401   R3(b, c, d, e, a, 54);
5402   R3(a, b, c, d, e, 55);
5403   R3(e, a, b, c, d, 56);
5404   R3(d, e, a, b, c, 57);
5405   R3(c, d, e, a, b, 58);
5406   R3(b, c, d, e, a, 59);
5407   R4(a, b, c, d, e, 60);
5408   R4(e, a, b, c, d, 61);
5409   R4(d, e, a, b, c, 62);
5410   R4(c, d, e, a, b, 63);
5411   R4(b, c, d, e, a, 64);
5412   R4(a, b, c, d, e, 65);
5413   R4(e, a, b, c, d, 66);
5414   R4(d, e, a, b, c, 67);
5415   R4(c, d, e, a, b, 68);
5416   R4(b, c, d, e, a, 69);
5417   R4(a, b, c, d, e, 70);
5418   R4(e, a, b, c, d, 71);
5419   R4(d, e, a, b, c, 72);
5420   R4(c, d, e, a, b, 73);
5421   R4(b, c, d, e, a, 74);
5422   R4(a, b, c, d, e, 75);
5423   R4(e, a, b, c, d, 76);
5424   R4(d, e, a, b, c, 77);
5425   R4(c, d, e, a, b, 78);
5426   R4(b, c, d, e, a, 79);
5427   state[0] += a;
5428   state[1] += b;
5429   state[2] += c;
5430   state[3] += d;
5431   state[4] += e;
5432   /* Erase working structures. The order of operations is important,
5433    * used to ensure that compiler doesn't optimize those out. */
5434   memset(block, 0, sizeof(block));
5435   a = b = c = d = e = 0;
5436   (void) a;
5437   (void) b;
5438   (void) c;
5439   (void) d;
5440   (void) e;
5441 }
5442
5443 void mg_sha1_init(mg_sha1_ctx *context) {
5444   context->state[0] = 0x67452301;
5445   context->state[1] = 0xEFCDAB89;
5446   context->state[2] = 0x98BADCFE;
5447   context->state[3] = 0x10325476;
5448   context->state[4] = 0xC3D2E1F0;
5449   context->count[0] = context->count[1] = 0;
5450 }
5451
5452 void mg_sha1_update(mg_sha1_ctx *context, const unsigned char *data,
5453                     size_t len) {
5454   size_t i, j;
5455
5456   j = context->count[0];
5457   if ((context->count[0] += (uint32_t) len << 3) < j) context->count[1]++;
5458   context->count[1] += (uint32_t) (len >> 29);
5459   j = (j >> 3) & 63;
5460   if ((j + len) > 63) {
5461     memcpy(&context->buffer[j], data, (i = 64 - j));
5462     mg_sha1_transform(context->state, context->buffer);
5463     for (; i + 63 < len; i += 64) {
5464       mg_sha1_transform(context->state, &data[i]);
5465     }
5466     j = 0;
5467   } else
5468     i = 0;
5469   memcpy(&context->buffer[j], &data[i], len - i);
5470 }
5471
5472 void mg_sha1_final(unsigned char digest[20], mg_sha1_ctx *context) {
5473   unsigned i;
5474   unsigned char finalcount[8], c;
5475
5476   for (i = 0; i < 8; i++) {
5477     finalcount[i] = (unsigned char) ((context->count[(i >= 4 ? 0 : 1)] >>
5478                                       ((3 - (i & 3)) * 8)) &
5479                                      255);
5480   }
5481   c = 0200;
5482   mg_sha1_update(context, &c, 1);
5483   while ((context->count[0] & 504) != 448) {
5484     c = 0000;
5485     mg_sha1_update(context, &c, 1);
5486   }
5487   mg_sha1_update(context, finalcount, 8);
5488   for (i = 0; i < 20; i++) {
5489     digest[i] =
5490         (unsigned char) ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
5491   }
5492   memset(context, '\0', sizeof(*context));
5493   memset(&finalcount, '\0', sizeof(finalcount));
5494 }
5495
5496 #ifdef MG_ENABLE_LINES
5497 #line 1 "src/sntp.c"
5498 #endif
5499
5500
5501
5502
5503
5504
5505 #define SNTP_TIME_OFFSET 2208988800U  // (1970 - 1900) in seconds
5506 #define SNTP_MAX_FRAC 4294967295.0    // 2 ** 32 - 1
5507
5508 static int64_t gettimestamp(const uint32_t *data) {
5509   uint32_t sec = mg_ntohl(data[0]), frac = mg_ntohl(data[1]);
5510   if (sec) sec -= SNTP_TIME_OFFSET;
5511   return ((int64_t) sec) * 1000 + (int64_t) (frac / SNTP_MAX_FRAC * 1000.0);
5512 }
5513
5514 int64_t mg_sntp_parse(const unsigned char *buf, size_t len) {
5515   int64_t res = -1;
5516   int mode = len > 0 ? buf[0] & 7 : 0;
5517   int version = len > 0 ? (buf[0] >> 3) & 7 : 0;
5518   if (len < 48) {
5519     MG_ERROR(("%s", "corrupt packet"));
5520   } else if (mode != 4 && mode != 5) {
5521     MG_ERROR(("%s", "not a server reply"));
5522   } else if (buf[1] == 0) {
5523     MG_ERROR(("%s", "server sent a kiss of death"));
5524   } else if (version == 4 || version == 3) {
5525     // int64_t ref = gettimestamp((uint32_t *) &buf[16]);
5526     int64_t t0 = gettimestamp((uint32_t *) &buf[24]);
5527     int64_t t1 = gettimestamp((uint32_t *) &buf[32]);
5528     int64_t t2 = gettimestamp((uint32_t *) &buf[40]);
5529     int64_t t3 = (int64_t) mg_millis();
5530     int64_t delta = (t3 - t0) - (t2 - t1);
5531     MG_VERBOSE(("%lld %lld %lld %lld delta:%lld", t0, t1, t2, t3, delta));
5532     res = t2 + delta / 2;
5533   } else {
5534     MG_ERROR(("unexpected version: %d", version));
5535   }
5536   return res;
5537 }
5538
5539 static void sntp_cb(struct mg_connection *c, int ev, void *evd, void *fnd) {
5540   if (ev == MG_EV_READ) {
5541     int64_t milliseconds = mg_sntp_parse(c->recv.buf, c->recv.len);
5542     if (milliseconds > 0) {
5543       MG_INFO(("%lu got time: %lld ms from epoch", c->id, milliseconds));
5544       mg_call(c, MG_EV_SNTP_TIME, (uint64_t *) &milliseconds);
5545       MG_VERBOSE(("%u.%u", (unsigned) (milliseconds / 1000),
5546                   (unsigned) (milliseconds % 1000)));
5547     }
5548     mg_iobuf_del(&c->recv, 0, c->recv.len);  // Free receive buffer
5549   } else if (ev == MG_EV_CONNECT) {
5550     mg_sntp_request(c);
5551   } else if (ev == MG_EV_CLOSE) {
5552   }
5553   (void) fnd;
5554   (void) evd;
5555 }
5556
5557 void mg_sntp_request(struct mg_connection *c) {
5558   if (c->is_resolving) {
5559     MG_ERROR(("%lu wait until resolved", c->id));
5560   } else {
5561     int64_t now = (int64_t) mg_millis();  // Use int64_t, for vc98
5562     uint8_t buf[48] = {0};
5563     uint32_t *t = (uint32_t *) &buf[40];
5564     double frac = ((double) (now % 1000)) / 1000.0 * SNTP_MAX_FRAC;
5565     buf[0] = (0 << 6) | (4 << 3) | 3;
5566     t[0] = mg_htonl((uint32_t) (now / 1000) + SNTP_TIME_OFFSET);
5567     t[1] = mg_htonl((uint32_t) frac);
5568     mg_send(c, buf, sizeof(buf));
5569   }
5570 }
5571
5572 struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr, const char *url,
5573                                       mg_event_handler_t fn, void *fnd) {
5574   struct mg_connection *c = NULL;
5575   if (url == NULL) url = "udp://time.google.com:123";
5576   if ((c = mg_connect(mgr, url, fn, fnd)) != NULL) c->pfn = sntp_cb;
5577   return c;
5578 }
5579
5580 #ifdef MG_ENABLE_LINES
5581 #line 1 "src/sock.c"
5582 #endif
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594 #if MG_ENABLE_SOCKET
5595
5596 #ifndef closesocket
5597 #define closesocket(x) close(x)
5598 #endif
5599
5600 #define FD(c_) ((MG_SOCKET_TYPE) (size_t) (c_)->fd)
5601 #define S2PTR(s_) ((void *) (size_t) (s_))
5602
5603 #ifndef MSG_NONBLOCKING
5604 #define MSG_NONBLOCKING 0
5605 #endif
5606
5607 #ifndef AF_INET6
5608 #define AF_INET6 10
5609 #endif
5610
5611 #ifndef MG_SOCK_ERR
5612 #define MG_SOCK_ERR(errcode) ((errcode) < 0 ? errno : 0)
5613 #endif
5614
5615 #ifndef MG_SOCK_INTR
5616 #define MG_SOCK_INTR(fd) (fd == MG_INVALID_SOCKET && MG_SOCK_ERR(-1) == EINTR)
5617 #endif
5618
5619 #ifndef MG_SOCK_PENDING
5620 #define MG_SOCK_PENDING(errcode) \
5621   (((errcode) < 0) && (errno == EINPROGRESS || errno == EWOULDBLOCK))
5622 #endif
5623
5624 #ifndef MG_SOCK_RESET
5625 #define MG_SOCK_RESET(errcode) \
5626   (((errcode) < 0) && (errno == EPIPE || errno == ECONNRESET))
5627 #endif
5628
5629 union usa {
5630   struct sockaddr sa;
5631   struct sockaddr_in sin;
5632 #if MG_ENABLE_IPV6
5633   struct sockaddr_in6 sin6;
5634 #endif
5635 };
5636
5637 static socklen_t tousa(struct mg_addr *a, union usa *usa) {
5638   socklen_t len = sizeof(usa->sin);
5639   memset(usa, 0, sizeof(*usa));
5640   usa->sin.sin_family = AF_INET;
5641   usa->sin.sin_port = a->port;
5642   memcpy(&usa->sin.sin_addr, a->ip, sizeof(uint32_t));
5643 #if MG_ENABLE_IPV6
5644   if (a->is_ip6) {
5645     usa->sin.sin_family = AF_INET6;
5646     usa->sin6.sin6_port = a->port;
5647     memcpy(&usa->sin6.sin6_addr, a->ip, sizeof(a->ip));
5648     len = sizeof(usa->sin6);
5649   }
5650 #endif
5651   return len;
5652 }
5653
5654 static void tomgaddr(union usa *usa, struct mg_addr *a, bool is_ip6) {
5655   a->is_ip6 = is_ip6;
5656   a->port = usa->sin.sin_port;
5657   memcpy(&a->ip, &usa->sin.sin_addr, sizeof(uint32_t));
5658 #if MG_ENABLE_IPV6
5659   if (is_ip6) {
5660     memcpy(a->ip, &usa->sin6.sin6_addr, sizeof(a->ip));
5661     a->port = usa->sin6.sin6_port;
5662   }
5663 #endif
5664 }
5665
5666 static void setlocaddr(MG_SOCKET_TYPE fd, struct mg_addr *addr) {
5667   union usa usa;
5668   socklen_t n = sizeof(usa);
5669   if (getsockname(fd, &usa.sa, &n) == 0) {
5670     tomgaddr(&usa, addr, n != sizeof(usa.sin));
5671   }
5672 }
5673
5674 static void iolog(struct mg_connection *c, char *buf, long n, bool r) {
5675   if (n == MG_IO_WAIT) {
5676     // Do nothing
5677   } else if (n <= 0) {
5678     c->is_closing = 1;  // Termination. Don't call mg_error(): #1529
5679   } else if (n > 0) {
5680     if (c->is_hexdumping) {
5681       union usa usa;
5682       socklen_t slen = sizeof(usa.sin);
5683       if (getsockname(FD(c), &usa.sa, &slen) < 0) (void) 0;  // Ignore result
5684       MG_INFO(("\n-- %lu %M %s %M %ld", c->id, mg_print_ip_port, &c->loc,
5685                r ? "<-" : "->", mg_print_ip_port, &c->rem, n));
5686
5687       mg_hexdump(buf, (size_t) n);
5688     }
5689     if (r) {
5690       c->recv.len += (size_t) n;
5691       mg_call(c, MG_EV_READ, &n);
5692     } else {
5693       mg_iobuf_del(&c->send, 0, (size_t) n);
5694       // if (c->send.len == 0) mg_iobuf_resize(&c->send, 0);
5695       if (c->send.len == 0) {
5696         MG_EPOLL_MOD(c, 0);
5697       }
5698       mg_call(c, MG_EV_WRITE, &n);
5699     }
5700   }
5701 }
5702
5703 long mg_io_send(struct mg_connection *c, const void *buf, size_t len) {
5704   long n;
5705   if (c->is_udp) {
5706     union usa usa;
5707     socklen_t slen = tousa(&c->rem, &usa);
5708     n = sendto(FD(c), (char *) buf, len, 0, &usa.sa, slen);
5709     if (n > 0) setlocaddr(FD(c), &c->loc);
5710   } else {
5711     n = send(FD(c), (char *) buf, len, MSG_NONBLOCKING);
5712   }
5713   if (MG_SOCK_PENDING(n)) return MG_IO_WAIT;
5714   if (MG_SOCK_RESET(n)) return MG_IO_RESET;
5715   if (n <= 0) return MG_IO_ERR;
5716   return n;
5717 }
5718
5719 bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
5720   if (c->is_udp) {
5721     long n = mg_io_send(c, buf, len);
5722     MG_DEBUG(("%lu %p %d:%d %ld err %d", c->id, c->fd, (int) c->send.len,
5723               (int) c->recv.len, n, MG_SOCK_ERR(n)));
5724     iolog(c, (char *) buf, n, false);
5725     return n > 0;
5726   } else {
5727     return mg_iobuf_add(&c->send, c->send.len, buf, len);
5728   }
5729 }
5730
5731 static void mg_set_non_blocking_mode(MG_SOCKET_TYPE fd) {
5732 #if defined(MG_CUSTOM_NONBLOCK)
5733   MG_CUSTOM_NONBLOCK(fd);
5734 #elif MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK
5735   unsigned long on = 1;
5736   ioctlsocket(fd, FIONBIO, &on);
5737 #elif MG_ENABLE_RL
5738   unsigned long on = 1;
5739   ioctlsocket(fd, FIONBIO, &on);
5740 #elif MG_ENABLE_FREERTOS_TCP
5741   const BaseType_t off = 0;
5742   if (setsockopt(fd, 0, FREERTOS_SO_RCVTIMEO, &off, sizeof(off)) != 0) (void) 0;
5743   if (setsockopt(fd, 0, FREERTOS_SO_SNDTIMEO, &off, sizeof(off)) != 0) (void) 0;
5744 #elif MG_ENABLE_LWIP
5745   lwip_fcntl(fd, F_SETFL, O_NONBLOCK);
5746 #elif MG_ARCH == MG_ARCH_AZURERTOS
5747   fcntl(fd, F_SETFL, O_NONBLOCK);
5748 #elif MG_ARCH == MG_ARCH_TIRTOS
5749   int val = 0;
5750   setsockopt(fd, SOL_SOCKET, SO_BLOCKING, &val, sizeof(val));
5751   // SPRU524J section 3.3.3 page 63, SO_SNDLOWAT
5752   int sz = sizeof(val);
5753   getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &val, &sz);
5754   val /= 2;  // set send low-water mark at half send buffer size
5755   setsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, &val, sizeof(val));
5756 #else
5757   fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);  // Non-blocking mode
5758   fcntl(fd, F_SETFD, FD_CLOEXEC);                          // Set close-on-exec
5759 #endif
5760 }
5761
5762 bool mg_open_listener(struct mg_connection *c, const char *url) {
5763   MG_SOCKET_TYPE fd = MG_INVALID_SOCKET;
5764   bool success = false;
5765   c->loc.port = mg_htons(mg_url_port(url));
5766   if (!mg_aton(mg_url_host(url), &c->loc)) {
5767     MG_ERROR(("invalid listening URL: %s", url));
5768   } else {
5769     union usa usa;
5770     socklen_t slen = tousa(&c->loc, &usa);
5771     int rc, on = 1, af = c->loc.is_ip6 ? AF_INET6 : AF_INET;
5772     int type = strncmp(url, "udp:", 4) == 0 ? SOCK_DGRAM : SOCK_STREAM;
5773     int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
5774     (void) on;
5775
5776     if ((fd = socket(af, type, proto)) == MG_INVALID_SOCKET) {
5777       MG_ERROR(("socket: %d", MG_SOCK_ERR(-1)));
5778 #if defined(SO_EXCLUSIVEADDRUSE)
5779     } else if ((rc = setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
5780                                 (char *) &on, sizeof(on))) != 0) {
5781       // "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE"
5782       MG_ERROR(("setsockopt(SO_EXCLUSIVEADDRUSE): %d %d", on, MG_SOCK_ERR(rc)));
5783 #elif defined(SO_REUSEADDR) && (!defined(LWIP_SOCKET) || SO_REUSE)
5784     } else if ((rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on,
5785                                 sizeof(on))) != 0) {
5786       // 1. SO_REUSEADDR semantics on UNIX and Windows is different.  On
5787       // Windows, SO_REUSEADDR allows to bind a socket to a port without error
5788       // even if the port is already open by another program. This is not the
5789       // behavior SO_REUSEADDR was designed for, and leads to hard-to-track
5790       // failure scenarios.
5791       //
5792       // 2. For LWIP, SO_REUSEADDR should be explicitly enabled by defining
5793       // SO_REUSE = 1 in lwipopts.h, otherwise the code below will compile but
5794       // won't work! (setsockopt will return EINVAL)
5795       MG_ERROR(("setsockopt(SO_REUSEADDR): %d", MG_SOCK_ERR(rc)));
5796 #endif
5797 #if defined(IPV6_V6ONLY)
5798     } else if (c->loc.is_ip6 &&
5799                (rc = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &on,
5800                                 sizeof(on))) != 0) {
5801       // See #2089. Allow to bind v4 and v6 sockets on the same port
5802       MG_ERROR(("setsockopt(IPV6_V6ONLY): %d", MG_SOCK_ERR(rc)));
5803 #endif
5804     } else if ((rc = bind(fd, &usa.sa, slen)) != 0) {
5805       MG_ERROR(("bind: %d", MG_SOCK_ERR(rc)));
5806     } else if ((type == SOCK_STREAM &&
5807                 (rc = listen(fd, MG_SOCK_LISTEN_BACKLOG_SIZE)) != 0)) {
5808       // NOTE(lsm): FreeRTOS uses backlog value as a connection limit
5809       // In case port was set to 0, get the real port number
5810       MG_ERROR(("listen: %d", MG_SOCK_ERR(rc)));
5811     } else {
5812       setlocaddr(fd, &c->loc);
5813       mg_set_non_blocking_mode(fd);
5814       c->fd = S2PTR(fd);
5815       MG_EPOLL_ADD(c);
5816       success = true;
5817     }
5818   }
5819   if (success == false && fd != MG_INVALID_SOCKET) closesocket(fd);
5820   return success;
5821 }
5822
5823 long mg_io_recv(struct mg_connection *c, void *buf, size_t len) {
5824   long n = 0;
5825   if (c->is_udp) {
5826     union usa usa;
5827     socklen_t slen = tousa(&c->rem, &usa);
5828     n = recvfrom(FD(c), (char *) buf, len, 0, &usa.sa, &slen);
5829     if (n > 0) tomgaddr(&usa, &c->rem, slen != sizeof(usa.sin));
5830   } else {
5831     n = recv(FD(c), (char *) buf, len, MSG_NONBLOCKING);
5832   }
5833   if (MG_SOCK_PENDING(n)) return MG_IO_WAIT;
5834   if (MG_SOCK_RESET(n)) return MG_IO_RESET;
5835   if (n <= 0) return MG_IO_ERR;
5836   return n;
5837 }
5838
5839 // NOTE(lsm): do only one iteration of reads, cause some systems
5840 // (e.g. FreeRTOS stack) return 0 instead of -1/EWOULDBLOCK when no data
5841 static void read_conn(struct mg_connection *c) {
5842   long n = -1;
5843   if (c->recv.len >= MG_MAX_RECV_SIZE) {
5844     mg_error(c, "max_recv_buf_size reached");
5845   } else if (c->recv.size <= c->recv.len &&
5846              !mg_iobuf_resize(&c->recv, c->recv.size + MG_IO_SIZE)) {
5847     mg_error(c, "oom");
5848   } else {
5849     char *buf = (char *) &c->recv.buf[c->recv.len];
5850     size_t len = c->recv.size - c->recv.len;
5851     n = c->is_tls ? mg_tls_recv(c, buf, len) : mg_io_recv(c, buf, len);
5852     MG_DEBUG(("%lu %p snd %ld/%ld rcv %ld/%ld n=%ld err=%d", c->id, c->fd,
5853               (long) c->send.len, (long) c->send.size, (long) c->recv.len,
5854               (long) c->recv.size, n, MG_SOCK_ERR(n)));
5855     iolog(c, buf, n, true);
5856   }
5857 }
5858
5859 static void write_conn(struct mg_connection *c) {
5860   char *buf = (char *) c->send.buf;
5861   size_t len = c->send.len;
5862   long n = c->is_tls ? mg_tls_send(c, buf, len) : mg_io_send(c, buf, len);
5863   MG_DEBUG(("%lu %p snd %ld/%ld rcv %ld/%ld n=%ld err=%d", c->id, c->fd,
5864             (long) c->send.len, (long) c->send.size, (long) c->recv.len,
5865             (long) c->recv.size, n, MG_SOCK_ERR(n)));
5866   iolog(c, buf, n, false);
5867 }
5868
5869 static void close_conn(struct mg_connection *c) {
5870   if (FD(c) != MG_INVALID_SOCKET) {
5871 #if MG_ENABLE_EPOLL
5872     epoll_ctl(c->mgr->epoll_fd, EPOLL_CTL_DEL, FD(c), NULL);
5873 #endif
5874     closesocket(FD(c));
5875 #if MG_ENABLE_FREERTOS_TCP
5876     FreeRTOS_FD_CLR(c->fd, c->mgr->ss, eSELECT_ALL);
5877 #endif
5878   }
5879   mg_close_conn(c);
5880 }
5881
5882 static void connect_conn(struct mg_connection *c) {
5883   union usa usa;
5884   socklen_t n = sizeof(usa);
5885   // Use getpeername() to test whether we have connected
5886   if (getpeername(FD(c), &usa.sa, &n) == 0) {
5887     c->is_connecting = 0;
5888     mg_call(c, MG_EV_CONNECT, NULL);
5889     MG_EPOLL_MOD(c, 0);
5890     if (c->is_tls_hs) mg_tls_handshake(c);
5891   } else {
5892     mg_error(c, "socket error");
5893   }
5894 }
5895
5896 static void setsockopts(struct mg_connection *c) {
5897 #if MG_ENABLE_FREERTOS_TCP || MG_ARCH == MG_ARCH_AZURERTOS || \
5898     MG_ARCH == MG_ARCH_TIRTOS
5899   (void) c;
5900 #else
5901   int on = 1;
5902 #if !defined(SOL_TCP)
5903 #define SOL_TCP IPPROTO_TCP
5904 #endif
5905   if (setsockopt(FD(c), SOL_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) != 0)
5906     (void) 0;
5907   if (setsockopt(FD(c), SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof(on)) !=
5908       0)
5909     (void) 0;
5910 #endif
5911 }
5912
5913 void mg_connect_resolved(struct mg_connection *c) {
5914   int type = c->is_udp ? SOCK_DGRAM : SOCK_STREAM;
5915   int rc, af = c->rem.is_ip6 ? AF_INET6 : AF_INET;  // c->rem has resolved IP
5916   c->fd = S2PTR(socket(af, type, 0));               // Create outbound socket
5917   c->is_resolving = 0;                              // Clear resolving flag
5918   if (FD(c) == MG_INVALID_SOCKET) {
5919     mg_error(c, "socket(): %d", MG_SOCK_ERR(-1));
5920   } else if (c->is_udp) {
5921     MG_EPOLL_ADD(c);
5922 #if MG_ARCH == MG_ARCH_TIRTOS
5923     union usa usa;  // TI-RTOS NDK requires binding to receive on UDP sockets
5924     socklen_t slen = tousa(&c->loc, &usa);
5925     if ((rc = bind(c->fd, &usa.sa, slen)) != 0)
5926       MG_ERROR(("bind: %d", MG_SOCK_ERR(rc)));
5927 #endif
5928     mg_call(c, MG_EV_RESOLVE, NULL);
5929     mg_call(c, MG_EV_CONNECT, NULL);
5930   } else {
5931     union usa usa;
5932     socklen_t slen = tousa(&c->rem, &usa);
5933     mg_set_non_blocking_mode(FD(c));
5934     setsockopts(c);
5935     MG_EPOLL_ADD(c);
5936     mg_call(c, MG_EV_RESOLVE, NULL);
5937     rc = connect(FD(c), &usa.sa, slen);  // Attempt to connect
5938     if (rc == 0) {                       // Success
5939       mg_call(c, MG_EV_CONNECT, NULL);   // Send MG_EV_CONNECT to the user
5940     } else if (MG_SOCK_PENDING(rc)) {    // Need to wait for TCP handshake
5941       MG_DEBUG(("%lu %p -> %M pend", c->id, c->fd, mg_print_ip_port, &c->rem));
5942       c->is_connecting = 1;
5943     } else {
5944       mg_error(c, "connect: %d", MG_SOCK_ERR(rc));
5945     }
5946   }
5947 }
5948
5949 static MG_SOCKET_TYPE raccept(MG_SOCKET_TYPE sock, union usa *usa,
5950                               socklen_t *len) {
5951   MG_SOCKET_TYPE fd = MG_INVALID_SOCKET;
5952   do {
5953     memset(usa, 0, sizeof(*usa));
5954     fd = accept(sock, &usa->sa, len);
5955   } while (MG_SOCK_INTR(fd));
5956   return fd;
5957 }
5958
5959 static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
5960   struct mg_connection *c = NULL;
5961   union usa usa;
5962   socklen_t sa_len = sizeof(usa);
5963   MG_SOCKET_TYPE fd = raccept(FD(lsn), &usa, &sa_len);
5964   if (fd == MG_INVALID_SOCKET) {
5965 #if MG_ARCH == MG_ARCH_AZURERTOS
5966     // AzureRTOS, in non-block socket mode can mark listening socket readable
5967     // even it is not. See comment for 'select' func implementation in
5968     // nx_bsd.c That's not an error, just should try later
5969     if (errno != EAGAIN)
5970 #endif
5971       MG_ERROR(("%lu accept failed, errno %d", lsn->id, MG_SOCK_ERR(-1)));
5972 #if (MG_ARCH != MG_ARCH_WIN32) && !MG_ENABLE_FREERTOS_TCP && \
5973     (MG_ARCH != MG_ARCH_TIRTOS) && !MG_ENABLE_POLL && !MG_ENABLE_EPOLL
5974   } else if ((long) fd >= FD_SETSIZE) {
5975     MG_ERROR(("%ld > %ld", (long) fd, (long) FD_SETSIZE));
5976     closesocket(fd);
5977 #endif
5978   } else if ((c = mg_alloc_conn(mgr)) == NULL) {
5979     MG_ERROR(("%lu OOM", lsn->id));
5980     closesocket(fd);
5981   } else {
5982     tomgaddr(&usa, &c->rem, sa_len != sizeof(usa.sin));
5983     LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
5984     c->fd = S2PTR(fd);
5985     MG_EPOLL_ADD(c);
5986     mg_set_non_blocking_mode(FD(c));
5987     setsockopts(c);
5988     c->is_accepted = 1;
5989     c->is_hexdumping = lsn->is_hexdumping;
5990     c->loc = lsn->loc;
5991     c->pfn = lsn->pfn;
5992     c->pfn_data = lsn->pfn_data;
5993     c->fn = lsn->fn;
5994     c->fn_data = lsn->fn_data;
5995     MG_DEBUG(("%lu %p accepted %M -> %M", c->id, c->fd, mg_print_ip_port,
5996               &c->rem, mg_print_ip_port, &c->loc));
5997     mg_call(c, MG_EV_OPEN, NULL);
5998     mg_call(c, MG_EV_ACCEPT, NULL);
5999     if (lsn->is_tls) mg_tls_init(c, mg_str(""));
6000   }
6001 }
6002
6003 static bool can_read(const struct mg_connection *c) {
6004   return c->is_full == false;
6005 }
6006
6007 static bool can_write(const struct mg_connection *c) {
6008   return c->is_connecting || (c->send.len > 0 && c->is_tls_hs == 0);
6009 }
6010
6011 static bool skip_iotest(const struct mg_connection *c) {
6012   return (c->is_closing || c->is_resolving || FD(c) == MG_INVALID_SOCKET) ||
6013          (can_read(c) == false && can_write(c) == false);
6014 }
6015
6016 static void mg_iotest(struct mg_mgr *mgr, int ms) {
6017 #if MG_ENABLE_FREERTOS_TCP
6018   struct mg_connection *c;
6019   for (c = mgr->conns; c != NULL; c = c->next) {
6020     c->is_readable = c->is_writable = 0;
6021     if (skip_iotest(c)) continue;
6022     if (can_read(c))
6023       FreeRTOS_FD_SET(c->fd, mgr->ss, eSELECT_READ | eSELECT_EXCEPT);
6024     if (can_write(c)) FreeRTOS_FD_SET(c->fd, mgr->ss, eSELECT_WRITE);
6025   }
6026   FreeRTOS_select(mgr->ss, pdMS_TO_TICKS(ms));
6027   for (c = mgr->conns; c != NULL; c = c->next) {
6028     EventBits_t bits = FreeRTOS_FD_ISSET(c->fd, mgr->ss);
6029     c->is_readable = bits & (eSELECT_READ | eSELECT_EXCEPT) ? 1U : 0;
6030     c->is_writable = bits & eSELECT_WRITE ? 1U : 0;
6031     if (c->fd != MG_INVALID_SOCKET)
6032       FreeRTOS_FD_CLR(c->fd, mgr->ss,
6033                       eSELECT_READ | eSELECT_EXCEPT | eSELECT_WRITE);
6034   }
6035 #elif MG_ENABLE_EPOLL
6036   size_t max = 1;
6037   for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) {
6038     c->is_readable = c->is_writable = 0;
6039     if (mg_tls_pending(c) > 0) ms = 1, c->is_readable = 1;
6040     if (can_write(c)) MG_EPOLL_MOD(c, 1);
6041     max++;
6042   }
6043   struct epoll_event *evs = (struct epoll_event *) alloca(max * sizeof(evs[0]));
6044   int n = epoll_wait(mgr->epoll_fd, evs, (int) max, ms);
6045   for (int i = 0; i < n; i++) {
6046     struct mg_connection *c = (struct mg_connection *) evs[i].data.ptr;
6047     if (evs[i].events & EPOLLERR) {
6048       mg_error(c, "socket error");
6049     } else if (c->is_readable == 0) {
6050       bool rd = evs[i].events & (EPOLLIN | EPOLLHUP);
6051       bool wr = evs[i].events & EPOLLOUT;
6052       c->is_readable = can_read(c) && rd ? 1U : 0;
6053       c->is_writable = can_write(c) && wr ? 1U : 0;
6054     }
6055   }
6056   (void) skip_iotest;
6057 #elif MG_ENABLE_POLL
6058   nfds_t n = 0;
6059   for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) n++;
6060   struct pollfd *fds = (struct pollfd *) alloca(n * sizeof(fds[0]));
6061   memset(fds, 0, n * sizeof(fds[0]));
6062   n = 0;
6063   for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) {
6064     c->is_readable = c->is_writable = 0;
6065     if (skip_iotest(c)) {
6066       // Socket not valid, ignore
6067     } else if (mg_tls_pending(c) > 0) {
6068       ms = 1;  // Don't wait if TLS is ready
6069     } else {
6070       fds[n].fd = FD(c);
6071       if (can_read(c)) fds[n].events |= POLLIN;
6072       if (can_write(c)) fds[n].events |= POLLOUT;
6073       n++;
6074     }
6075   }
6076
6077   // MG_INFO(("poll n=%d ms=%d", (int) n, ms));
6078   if (poll(fds, n, ms) < 0) {
6079 #if MG_ARCH == MG_ARCH_WIN32
6080     if (n == 0) Sleep(ms);  // On Windows, poll fails if no sockets
6081 #endif
6082     memset(fds, 0, n * sizeof(fds[0]));
6083   }
6084   n = 0;
6085   for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) {
6086     if (skip_iotest(c)) {
6087       // Socket not valid, ignore
6088     } else if (mg_tls_pending(c) > 0) {
6089       c->is_readable = 1;
6090     } else {
6091       if (fds[n].revents & POLLERR) {
6092         mg_error(c, "socket error");
6093       } else {
6094         c->is_readable =
6095             (unsigned) (fds[n].revents & (POLLIN | POLLHUP) ? 1 : 0);
6096         c->is_writable = (unsigned) (fds[n].revents & POLLOUT ? 1 : 0);
6097       }
6098       n++;
6099     }
6100   }
6101 #else
6102   struct timeval tv = {ms / 1000, (ms % 1000) * 1000}, tv_zero = {0, 0}, *tvp;
6103   struct mg_connection *c;
6104   fd_set rset, wset, eset;
6105   MG_SOCKET_TYPE maxfd = 0;
6106   int rc;
6107
6108   FD_ZERO(&rset);
6109   FD_ZERO(&wset);
6110   FD_ZERO(&eset);
6111   tvp = ms < 0 ? NULL : &tv;
6112   for (c = mgr->conns; c != NULL; c = c->next) {
6113     c->is_readable = c->is_writable = 0;
6114     if (skip_iotest(c)) continue;
6115     FD_SET(FD(c), &eset);
6116     if (can_read(c)) FD_SET(FD(c), &rset);
6117     if (can_write(c)) FD_SET(FD(c), &wset);
6118     if (mg_tls_pending(c) > 0) tvp = &tv_zero;
6119     if (FD(c) > maxfd) maxfd = FD(c);
6120   }
6121
6122   if ((rc = select((int) maxfd + 1, &rset, &wset, &eset, tvp)) < 0) {
6123 #if MG_ARCH == MG_ARCH_WIN32
6124     if (maxfd == 0) Sleep(ms);  // On Windows, select fails if no sockets
6125 #else
6126     MG_ERROR(("select: %d %d", rc, MG_SOCK_ERR(rc)));
6127 #endif
6128     FD_ZERO(&rset);
6129     FD_ZERO(&wset);
6130     FD_ZERO(&eset);
6131   }
6132
6133   for (c = mgr->conns; c != NULL; c = c->next) {
6134     if (FD(c) != MG_INVALID_SOCKET && FD_ISSET(FD(c), &eset)) {
6135       mg_error(c, "socket error");
6136     } else {
6137       c->is_readable = FD(c) != MG_INVALID_SOCKET && FD_ISSET(FD(c), &rset);
6138       c->is_writable = FD(c) != MG_INVALID_SOCKET && FD_ISSET(FD(c), &wset);
6139       if (mg_tls_pending(c) > 0) c->is_readable = 1;
6140     }
6141   }
6142 #endif
6143 }
6144
6145 void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
6146   struct mg_connection *c, *tmp;
6147   uint64_t now;
6148
6149   mg_iotest(mgr, ms);
6150   now = mg_millis();
6151   mg_timer_poll(&mgr->timers, now);
6152
6153   for (c = mgr->conns; c != NULL; c = tmp) {
6154     bool is_resp = c->is_resp;
6155     tmp = c->next;
6156     mg_call(c, MG_EV_POLL, &now);
6157     if (is_resp && !c->is_resp) {
6158       long n = 0;
6159       mg_call(c, MG_EV_READ, &n);
6160     }
6161     MG_VERBOSE(("%lu %c%c %c%c%c%c%c", c->id, c->is_readable ? 'r' : '-',
6162                 c->is_writable ? 'w' : '-', c->is_tls ? 'T' : 't',
6163                 c->is_connecting ? 'C' : 'c', c->is_tls_hs ? 'H' : 'h',
6164                 c->is_resolving ? 'R' : 'r', c->is_closing ? 'C' : 'c'));
6165     if (c->is_resolving || c->is_closing) {
6166       // Do nothing
6167     } else if (c->is_listening && c->is_udp == 0) {
6168       if (c->is_readable) accept_conn(mgr, c);
6169     } else if (c->is_connecting) {
6170       if (c->is_readable || c->is_writable) connect_conn(c);
6171     } else if (c->is_tls_hs) {
6172       if ((c->is_readable || c->is_writable)) mg_tls_handshake(c);
6173     } else {
6174       if (c->is_readable) read_conn(c);
6175       if (c->is_writable) write_conn(c);
6176     }
6177
6178     if (c->is_draining && c->send.len == 0) c->is_closing = 1;
6179     if (c->is_closing) close_conn(c);
6180   }
6181 }
6182 #endif
6183
6184 #ifdef MG_ENABLE_LINES
6185 #line 1 "src/ssi.c"
6186 #endif
6187
6188
6189
6190
6191 #ifndef MG_MAX_SSI_DEPTH
6192 #define MG_MAX_SSI_DEPTH 5
6193 #endif
6194
6195 #ifndef MG_SSI_BUFSIZ
6196 #define MG_SSI_BUFSIZ 1024
6197 #endif
6198
6199 #if MG_ENABLE_SSI
6200 static char *mg_ssi(const char *path, const char *root, int depth) {
6201   struct mg_iobuf b = {NULL, 0, 0, MG_IO_SIZE};
6202   FILE *fp = fopen(path, "rb");
6203   if (fp != NULL) {
6204     char buf[MG_SSI_BUFSIZ], arg[sizeof(buf)];
6205     int ch, intag = 0;
6206     size_t len = 0;
6207     buf[0] = arg[0] = '\0';
6208     while ((ch = fgetc(fp)) != EOF) {
6209       if (intag && ch == '>' && buf[len - 1] == '-' && buf[len - 2] == '-') {
6210         buf[len++] = (char) (ch & 0xff);
6211         buf[len] = '\0';
6212         if (sscanf(buf, "<!--#include file=\"%[^\"]", arg)) {
6213           char tmp[MG_PATH_MAX + MG_SSI_BUFSIZ + 10],
6214               *p = (char *) path + strlen(path), *data;
6215           while (p > path && p[-1] != MG_DIRSEP && p[-1] != '/') p--;
6216           mg_snprintf(tmp, sizeof(tmp), "%.*s%s", (int) (p - path), path, arg);
6217           if (depth < MG_MAX_SSI_DEPTH &&
6218               (data = mg_ssi(tmp, root, depth + 1)) != NULL) {
6219             mg_iobuf_add(&b, b.len, data, strlen(data));
6220             free(data);
6221           } else {
6222             MG_ERROR(("%s: file=%s error or too deep", path, arg));
6223           }
6224         } else if (sscanf(buf, "<!--#include virtual=\"%[^\"]", arg)) {
6225           char tmp[MG_PATH_MAX + MG_SSI_BUFSIZ + 10], *data;
6226           mg_snprintf(tmp, sizeof(tmp), "%s%s", root, arg);
6227           if (depth < MG_MAX_SSI_DEPTH &&
6228               (data = mg_ssi(tmp, root, depth + 1)) != NULL) {
6229             mg_iobuf_add(&b, b.len, data, strlen(data));
6230             free(data);
6231           } else {
6232             MG_ERROR(("%s: virtual=%s error or too deep", path, arg));
6233           }
6234         } else {
6235           // Unknown SSI tag
6236           MG_ERROR(("Unknown SSI tag: %.*s", (int) len, buf));
6237           mg_iobuf_add(&b, b.len, buf, len);
6238         }
6239         intag = 0;
6240         len = 0;
6241       } else if (ch == '<') {
6242         intag = 1;
6243         if (len > 0) mg_iobuf_add(&b, b.len, buf, len);
6244         len = 0;
6245         buf[len++] = (char) (ch & 0xff);
6246       } else if (intag) {
6247         if (len == 5 && strncmp(buf, "<!--#", 5) != 0) {
6248           intag = 0;
6249         } else if (len >= sizeof(buf) - 2) {
6250           MG_ERROR(("%s: SSI tag is too large", path));
6251           len = 0;
6252         }
6253         buf[len++] = (char) (ch & 0xff);
6254       } else {
6255         buf[len++] = (char) (ch & 0xff);
6256         if (len >= sizeof(buf)) {
6257           mg_iobuf_add(&b, b.len, buf, len);
6258           len = 0;
6259         }
6260       }
6261     }
6262     if (len > 0) mg_iobuf_add(&b, b.len, buf, len);
6263     if (b.len > 0) mg_iobuf_add(&b, b.len, "", 1);  // nul-terminate
6264     fclose(fp);
6265   }
6266   (void) depth;
6267   (void) root;
6268   return (char *) b.buf;
6269 }
6270
6271 void mg_http_serve_ssi(struct mg_connection *c, const char *root,
6272                        const char *fullpath) {
6273   const char *headers = "Content-Type: text/html; charset=utf-8\r\n";
6274   char *data = mg_ssi(fullpath, root, 0);
6275   mg_http_reply(c, 200, headers, "%s", data == NULL ? "" : data);
6276   free(data);
6277 }
6278 #else
6279 void mg_http_serve_ssi(struct mg_connection *c, const char *root,
6280                        const char *fullpath) {
6281   mg_http_reply(c, 501, NULL, "SSI not enabled");
6282   (void) root, (void) fullpath;
6283 }
6284 #endif
6285
6286 #ifdef MG_ENABLE_LINES
6287 #line 1 "src/str.c"
6288 #endif
6289
6290
6291 struct mg_str mg_str_s(const char *s) {
6292   struct mg_str str = {s, s == NULL ? 0 : strlen(s)};
6293   return str;
6294 }
6295
6296 struct mg_str mg_str_n(const char *s, size_t n) {
6297   struct mg_str str = {s, n};
6298   return str;
6299 }
6300
6301 int mg_lower(const char *s) {
6302   int c = *s;
6303   if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
6304   return c;
6305 }
6306
6307 int mg_ncasecmp(const char *s1, const char *s2, size_t len) {
6308   int diff = 0;
6309   if (len > 0) do {
6310       diff = mg_lower(s1++) - mg_lower(s2++);
6311     } while (diff == 0 && s1[-1] != '\0' && --len > 0);
6312   return diff;
6313 }
6314
6315 int mg_casecmp(const char *s1, const char *s2) {
6316   return mg_ncasecmp(s1, s2, (size_t) ~0);
6317 }
6318
6319 int mg_vcmp(const struct mg_str *s1, const char *s2) {
6320   size_t n2 = strlen(s2), n1 = s1->len;
6321   int r = strncmp(s1->ptr, s2, (n1 < n2) ? n1 : n2);
6322   if (r == 0) return (int) (n1 - n2);
6323   return r;
6324 }
6325
6326 int mg_vcasecmp(const struct mg_str *str1, const char *str2) {
6327   size_t n2 = strlen(str2), n1 = str1->len;
6328   int r = mg_ncasecmp(str1->ptr, str2, (n1 < n2) ? n1 : n2);
6329   if (r == 0) return (int) (n1 - n2);
6330   return r;
6331 }
6332
6333 struct mg_str mg_strdup(const struct mg_str s) {
6334   struct mg_str r = {NULL, 0};
6335   if (s.len > 0 && s.ptr != NULL) {
6336     char *sc = (char *) calloc(1, s.len + 1);
6337     if (sc != NULL) {
6338       memcpy(sc, s.ptr, s.len);
6339       sc[s.len] = '\0';
6340       r.ptr = sc;
6341       r.len = s.len;
6342     }
6343   }
6344   return r;
6345 }
6346
6347 int mg_strcmp(const struct mg_str str1, const struct mg_str str2) {
6348   size_t i = 0;
6349   while (i < str1.len && i < str2.len) {
6350     int c1 = str1.ptr[i];
6351     int c2 = str2.ptr[i];
6352     if (c1 < c2) return -1;
6353     if (c1 > c2) return 1;
6354     i++;
6355   }
6356   if (i < str1.len) return 1;
6357   if (i < str2.len) return -1;
6358   return 0;
6359 }
6360
6361 const char *mg_strstr(const struct mg_str haystack,
6362                       const struct mg_str needle) {
6363   size_t i;
6364   if (needle.len > haystack.len) return NULL;
6365   if (needle.len == 0) return haystack.ptr;
6366   for (i = 0; i <= haystack.len - needle.len; i++) {
6367     if (memcmp(haystack.ptr + i, needle.ptr, needle.len) == 0) {
6368       return haystack.ptr + i;
6369     }
6370   }
6371   return NULL;
6372 }
6373
6374 static bool is_space(int c) {
6375   return c == ' ' || c == '\r' || c == '\n' || c == '\t';
6376 }
6377
6378 struct mg_str mg_strstrip(struct mg_str s) {
6379   while (s.len > 0 && is_space((int) *s.ptr)) s.ptr++, s.len--;
6380   while (s.len > 0 && is_space((int) *(s.ptr + s.len - 1))) s.len--;
6381   return s;
6382 }
6383
6384 bool mg_match(struct mg_str s, struct mg_str p, struct mg_str *caps) {
6385   size_t i = 0, j = 0, ni = 0, nj = 0;
6386   if (caps) caps->ptr = NULL, caps->len = 0;
6387   while (i < p.len || j < s.len) {
6388     if (i < p.len && j < s.len && (p.ptr[i] == '?' || s.ptr[j] == p.ptr[i])) {
6389       if (caps == NULL) {
6390       } else if (p.ptr[i] == '?') {
6391         caps->ptr = &s.ptr[j], caps->len = 1;     // Finalize `?` cap
6392         caps++, caps->ptr = NULL, caps->len = 0;  // Init next cap
6393       } else if (caps->ptr != NULL && caps->len == 0) {
6394         caps->len = (size_t) (&s.ptr[j] - caps->ptr);  // Finalize current cap
6395         caps++, caps->len = 0, caps->ptr = NULL;       // Init next cap
6396       }
6397       i++, j++;
6398     } else if (i < p.len && (p.ptr[i] == '*' || p.ptr[i] == '#')) {
6399       if (caps && !caps->ptr) caps->len = 0, caps->ptr = &s.ptr[j];  // Init cap
6400       ni = i++, nj = j + 1;
6401     } else if (nj > 0 && nj <= s.len && (p.ptr[ni] == '#' || s.ptr[j] != '/')) {
6402       i = ni, j = nj;
6403       if (caps && caps->ptr == NULL && caps->len == 0) {
6404         caps--, caps->len = 0;  // Restart previous cap
6405       }
6406     } else {
6407       return false;
6408     }
6409   }
6410   if (caps && caps->ptr && caps->len == 0) {
6411     caps->len = (size_t) (&s.ptr[j] - caps->ptr);
6412   }
6413   return true;
6414 }
6415
6416 bool mg_globmatch(const char *s1, size_t n1, const char *s2, size_t n2) {
6417   return mg_match(mg_str_n(s2, n2), mg_str_n(s1, n1), NULL);
6418 }
6419
6420 static size_t mg_nce(const char *s, size_t n, size_t ofs, size_t *koff,
6421                      size_t *klen, size_t *voff, size_t *vlen, char delim) {
6422   size_t kvlen, kl;
6423   for (kvlen = 0; ofs + kvlen < n && s[ofs + kvlen] != delim;) kvlen++;
6424   for (kl = 0; kl < kvlen && s[ofs + kl] != '=';) kl++;
6425   if (koff != NULL) *koff = ofs;
6426   if (klen != NULL) *klen = kl;
6427   if (voff != NULL) *voff = kl < kvlen ? ofs + kl + 1 : 0;
6428   if (vlen != NULL) *vlen = kl < kvlen ? kvlen - kl - 1 : 0;
6429   ofs += kvlen + 1;
6430   return ofs > n ? n : ofs;
6431 }
6432
6433 bool mg_split(struct mg_str *s, struct mg_str *k, struct mg_str *v, char sep) {
6434   size_t koff = 0, klen = 0, voff = 0, vlen = 0, off = 0;
6435   if (s->ptr == NULL || s->len == 0) return 0;
6436   off = mg_nce(s->ptr, s->len, 0, &koff, &klen, &voff, &vlen, sep);
6437   if (k != NULL) *k = mg_str_n(s->ptr + koff, klen);
6438   if (v != NULL) *v = mg_str_n(s->ptr + voff, vlen);
6439   *s = mg_str_n(s->ptr + off, s->len - off);
6440   return off > 0;
6441 }
6442
6443 bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v) {
6444   return mg_split(s, k, v, ',');
6445 }
6446
6447 char *mg_hex(const void *buf, size_t len, char *to) {
6448   const unsigned char *p = (const unsigned char *) buf;
6449   const char *hex = "0123456789abcdef";
6450   size_t i = 0;
6451   for (; len--; p++) {
6452     to[i++] = hex[p[0] >> 4];
6453     to[i++] = hex[p[0] & 0x0f];
6454   }
6455   to[i] = '\0';
6456   return to;
6457 }
6458
6459 static unsigned char mg_unhex_nimble(unsigned char c) {
6460   return (c >= '0' && c <= '9')   ? (unsigned char) (c - '0')
6461          : (c >= 'A' && c <= 'F') ? (unsigned char) (c - '7')
6462                                   : (unsigned char) (c - 'W');
6463 }
6464
6465 unsigned long mg_unhexn(const char *s, size_t len) {
6466   unsigned long i = 0, v = 0;
6467   for (i = 0; i < len; i++) v <<= 4, v |= mg_unhex_nimble(((uint8_t *) s)[i]);
6468   return v;
6469 }
6470
6471 void mg_unhex(const char *buf, size_t len, unsigned char *to) {
6472   size_t i;
6473   for (i = 0; i < len; i += 2) {
6474     to[i >> 1] = (unsigned char) mg_unhexn(&buf[i], 2);
6475   }
6476 }
6477
6478 bool mg_path_is_sane(const char *path) {
6479   const char *s = path;
6480   for (; s[0] != '\0'; s++) {
6481     if (s == path || s[0] == '/' || s[0] == '\\') {  // Subdir?
6482       if (s[1] == '.' && s[2] == '.') return false;  // Starts with ..
6483     }
6484   }
6485   return true;
6486 }
6487
6488 #ifdef MG_ENABLE_LINES
6489 #line 1 "src/timer.c"
6490 #endif
6491
6492
6493
6494 #define MG_TIMER_CALLED 4
6495
6496 void mg_timer_init(struct mg_timer **head, struct mg_timer *t, uint64_t ms,
6497                    unsigned flags, void (*fn)(void *), void *arg) {
6498   t->id = 0, t->period_ms = ms, t->expire = 0;
6499   t->flags = flags, t->fn = fn, t->arg = arg, t->next = *head;
6500   *head = t;
6501 }
6502
6503 void mg_timer_free(struct mg_timer **head, struct mg_timer *t) {
6504   while (*head && *head != t) head = &(*head)->next;
6505   if (*head) *head = t->next;
6506 }
6507
6508 // t: expiration time, prd: period, now: current time. Return true if expired
6509 bool mg_timer_expired(uint64_t *t, uint64_t prd, uint64_t now) {
6510   if (now + prd < *t) *t = 0;                    // Time wrapped? Reset timer
6511   if (*t == 0) *t = now + prd;                   // Firt poll? Set expiration
6512   if (*t > now) return false;                    // Not expired yet, return
6513   *t = (now - *t) > prd ? now + prd : *t + prd;  // Next expiration time
6514   return true;                                   // Expired, return true
6515 }
6516
6517 void mg_timer_poll(struct mg_timer **head, uint64_t now_ms) {
6518   struct mg_timer *t, *tmp;
6519   for (t = *head; t != NULL; t = tmp) {
6520     bool once = t->expire == 0 && (t->flags & MG_TIMER_RUN_NOW) &&
6521                 !(t->flags & MG_TIMER_CALLED);  // Handle MG_TIMER_NOW only once
6522     bool expired = mg_timer_expired(&t->expire, t->period_ms, now_ms);
6523     tmp = t->next;
6524     if (!once && !expired) continue;
6525     if ((t->flags & MG_TIMER_REPEAT) || !(t->flags & MG_TIMER_CALLED)) {
6526       t->fn(t->arg);
6527     }
6528     t->flags |= MG_TIMER_CALLED;
6529   }
6530 }
6531
6532 #ifdef MG_ENABLE_LINES
6533 #line 1 "src/tls_builtin.c"
6534 #endif
6535
6536
6537 #if MG_TLS == MG_TLS_BUILTIN
6538 struct tls_data {
6539   struct mg_iobuf send;
6540   struct mg_iobuf recv;
6541 };
6542
6543 #define MG_LOAD_BE16(p) ((uint16_t) ((MG_U8P(p)[0] << 8U) | MG_U8P(p)[1]))
6544 #define TLS_HDR_SIZE 5  // 1 byte type, 2 bytes version, 2 bytes len
6545
6546 static inline bool mg_is_big_endian(void) {
6547   int v = 1;
6548   return *(unsigned char *) &v == 1;
6549 }
6550 static inline uint16_t mg_swap16(uint16_t v) {
6551   return (uint16_t) ((v << 8U) | (v >> 8U));
6552 }
6553 static inline uint32_t mg_swap32(uint32_t v) {
6554   return (v >> 24) | (v >> 8 & 0xff00) | (v << 8 & 0xff0000) | (v << 24);
6555 }
6556 static inline uint64_t mg_swap64(uint64_t v) {
6557   return (((uint64_t) mg_swap32((uint32_t) v)) << 32) |
6558          mg_swap32((uint32_t) (v >> 32));
6559 }
6560 static inline uint16_t mg_be16(uint16_t v) {
6561   return mg_is_big_endian() ? mg_swap16(v) : v;
6562 }
6563 static inline uint32_t mg_be32(uint32_t v) {
6564   return mg_is_big_endian() ? mg_swap32(v) : v;
6565 }
6566
6567 static inline void add8(struct mg_iobuf *io, uint8_t data) {
6568   mg_iobuf_add(io, io->len, &data, sizeof(data));
6569 }
6570 static inline void add16(struct mg_iobuf *io, uint16_t data) {
6571   data = mg_htons(data);
6572   mg_iobuf_add(io, io->len, &data, sizeof(data));
6573 }
6574 static inline void add32(struct mg_iobuf *io, uint32_t data) {
6575   data = mg_htonl(data);
6576   mg_iobuf_add(io, io->len, &data, sizeof(data));
6577 }
6578
6579 void mg_tls_init(struct mg_connection *c, struct mg_str hostname) {
6580   struct tls_data *tls = (struct tls_data *) calloc(1, sizeof(struct tls_data));
6581   if (tls != NULL) {
6582     tls->send.align = tls->recv.align = MG_IO_SIZE;
6583     c->tls = tls;
6584     c->is_tls = c->is_tls_hs = 1;
6585   } else {
6586     mg_error(c, "tls oom");
6587   }
6588   (void) hostname;
6589 }
6590 void mg_tls_free(struct mg_connection *c) {
6591   struct tls_data *tls = c->tls;
6592   if (tls != NULL) {
6593     mg_iobuf_free(&tls->send);
6594     mg_iobuf_free(&tls->recv);
6595   }
6596   free(c->tls);
6597   c->tls = NULL;
6598 }
6599 long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
6600   (void) c, (void) buf, (void) len;
6601   // MG_INFO(("BBBBBBBB"));
6602   return -1;
6603 }
6604 long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
6605   (void) c, (void) buf, (void) len;
6606   char tmp[8192];
6607   long n = mg_io_recv(c, tmp, sizeof(tmp));
6608   if (n > 0) mg_hexdump(tmp, (size_t) n);
6609   MG_INFO(("AAAAAAAA"));
6610   return -1;
6611   // struct mg_tls *tls = (struct mg_tls *) c->tls;
6612   // long n = mbedtls_ssl_read(&tls->ssl, (unsigned char *) buf, len);
6613   // if (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE)
6614   //   return MG_IO_WAIT;
6615   // if (n <= 0) return MG_IO_ERR;
6616   // return n;
6617 }
6618 size_t mg_tls_pending(struct mg_connection *c) {
6619   (void) c;
6620   return 0;
6621 }
6622 void mg_tls_handshake(struct mg_connection *c) {
6623   struct tls_data *tls = c->tls;
6624   struct mg_iobuf *rio = &tls->recv;
6625   struct mg_iobuf *wio = &tls->send;
6626   // Pull data from TCP
6627   for (;;) {
6628     mg_iobuf_resize(rio, rio->len + 1);
6629     long n = mg_io_recv(c, &rio->buf[rio->len], rio->size - rio->len);
6630     if (n > 0) {
6631       rio->len += (size_t) n;
6632     } else if (n == MG_IO_WAIT) {
6633       break;
6634     } else {
6635       mg_error(c, "IO err");
6636       return;
6637     }
6638   }
6639   // Look if we've pulled everything
6640   if (rio->len < TLS_HDR_SIZE) return;
6641   uint8_t record_type = rio->buf[0];
6642   uint16_t record_len = MG_LOAD_BE16(rio->buf + 3);
6643   uint16_t record_version = MG_LOAD_BE16(rio->buf + 1);
6644   if (record_type != 22) {
6645     mg_error(c, "no 22");
6646     return;
6647   }
6648   if (rio->len < (size_t) TLS_HDR_SIZE + record_len) return;
6649   // Got full hello
6650   // struct tls_hello *hello = (struct tls_hello *) (hdr + 1);
6651   MG_INFO(("CT=%d V=%hx L=%hu", record_type, record_version, record_len));
6652   mg_hexdump(rio->buf, rio->len);
6653
6654   // Send response. Server Hello
6655   size_t ofs = wio->len;
6656   add8(wio, 22), add16(wio, 0x303), add16(wio, 0);  // Layer: type, ver, len
6657   add8(wio, 2), add8(wio, 0), add16(wio, 0), add16(wio, 0x304);  // Hello
6658   mg_iobuf_add(wio, wio->len, NULL, 32);                         // 32 random
6659   mg_random(wio->buf + wio->len - 32, 32);                       // bytes
6660   add8(wio, 0);                                                  // Session ID
6661   add16(wio, 0x1301);  // Cipher: TLS_AES_128_GCM_SHA256
6662   add8(wio, 0);        // Compression method: 0
6663   add16(wio, 46);      // Extensions length
6664   add16(wio, 43), add16(wio, 2), add16(wio, 0x304);  // extension: TLS 1.3
6665   add16(wio, 51), add16(wio, 36), add16(wio, 29), add16(wio, 32);  // keyshare
6666   mg_iobuf_add(wio, wio->len, NULL, 32);                           // 32 random
6667   mg_random(wio->buf + wio->len - 32, 32);                         // bytes
6668   *(uint16_t *) &wio->buf[ofs + 3] = mg_be16((uint16_t) (wio->len - ofs - 5));
6669   *(uint16_t *) &wio->buf[ofs + 7] = mg_be16((uint16_t) (wio->len - ofs - 9));
6670
6671   // Change cipher. Cipher's payload is an encypted app data
6672   // ofs = wio->len;
6673   add8(wio, 20), add16(wio, 0x303);  // Layer: type, version
6674   add16(wio, 1), add8(wio, 1);
6675
6676   ofs = wio->len;                                   // Application data
6677   add8(wio, 23), add16(wio, 0x303), add16(wio, 5);  // Layer: type, version
6678   // mg_iobuf_add(wio, wio->len, "\x01\x02\x03\x04\x05", 5);
6679   add8(wio, 22);                                       // handshake message
6680   add8(wio, 8);                                        // encrypted extensions
6681   add8(wio, 0), add16(wio, 2), add16(wio, 0);          // empty 2 bytes
6682   add8(wio, 11);                                       // certificate message
6683   add8(wio, 0), add16(wio, 4), add32(wio, 0x1020304);  // len
6684   *(uint16_t *) &wio->buf[ofs + 3] = mg_be16((uint16_t)(wio->len - ofs - 5));
6685
6686   mg_io_send(c, wio->buf, wio->len);
6687   wio->len = 0;
6688
6689   rio->len = 0;
6690   c->is_tls_hs = 0;
6691   mg_error(c, "doh");
6692 }
6693 void mg_tls_ctx_free(struct mg_mgr *mgr) {
6694   mgr->tls_ctx = NULL;
6695 }
6696 void mg_tls_ctx_init(struct mg_mgr *mgr, const struct mg_tls_opts *opts) {
6697   (void) opts, (void) mgr;
6698 }
6699 #endif
6700
6701 #ifdef MG_ENABLE_LINES
6702 #line 1 "src/tls_dummy.c"
6703 #endif
6704
6705
6706 #if MG_TLS == MG_TLS_NONE
6707 void mg_tls_init(struct mg_connection *c, struct mg_str hostname) {
6708   (void) hostname;
6709   mg_error(c, "TLS is not enabled");
6710 }
6711 void mg_tls_handshake(struct mg_connection *c) {
6712   (void) c;
6713 }
6714 void mg_tls_free(struct mg_connection *c) {
6715   (void) c;
6716 }
6717 long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
6718   return c == NULL || buf == NULL || len == 0 ? 0 : -1;
6719 }
6720 long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
6721   return c == NULL || buf == NULL || len == 0 ? 0 : -1;
6722 }
6723 size_t mg_tls_pending(struct mg_connection *c) {
6724   (void) c;
6725   return 0;
6726 }
6727 void mg_tls_ctx_free(struct mg_mgr *mgr) {
6728   mgr->tls_ctx = NULL;
6729 }
6730 void mg_tls_ctx_init(struct mg_mgr *mgr, const struct mg_tls_opts *opts) {
6731   (void) opts, (void) mgr;
6732 }
6733 #endif
6734
6735 #ifdef MG_ENABLE_LINES
6736 #line 1 "src/tls_mbed.c"
6737 #endif
6738
6739
6740
6741
6742 #if MG_TLS == MG_TLS_MBED
6743
6744 #if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000
6745 #define MGRNG , rng_get, NULL
6746 #else
6747 #define MGRNG
6748 #endif
6749
6750 void mg_tls_free(struct mg_connection *c) {
6751   struct mg_tls *tls = (struct mg_tls *) c->tls;
6752   if (tls != NULL) {
6753     mbedtls_ssl_free(&tls->ssl);
6754     mbedtls_ssl_config_free(&tls->conf);
6755     free(tls);
6756     c->tls = NULL;
6757   }
6758 }
6759
6760 static int mg_net_send(void *ctx, const unsigned char *buf, size_t len) {
6761   long n = mg_io_send((struct mg_connection *) ctx, buf, len);
6762   MG_VERBOSE(("%lu n=%ld e=%d", ((struct mg_connection *) ctx)->id, n, errno));
6763   if (n == MG_IO_WAIT) return MBEDTLS_ERR_SSL_WANT_WRITE;
6764   if (n == MG_IO_RESET) return MBEDTLS_ERR_NET_CONN_RESET;
6765   if (n == MG_IO_ERR) return MBEDTLS_ERR_NET_SEND_FAILED;
6766   return (int) n;
6767 }
6768
6769 static int mg_net_recv(void *ctx, unsigned char *buf, size_t len) {
6770   long n = mg_io_recv((struct mg_connection *) ctx, buf, len);
6771   MG_VERBOSE(("%lu n=%ld", ((struct mg_connection *) ctx)->id, n));
6772   if (n == MG_IO_WAIT) return MBEDTLS_ERR_SSL_WANT_WRITE;
6773   if (n == MG_IO_RESET) return MBEDTLS_ERR_NET_CONN_RESET;
6774   if (n == MG_IO_ERR) return MBEDTLS_ERR_NET_RECV_FAILED;
6775   return (int) n;
6776 }
6777
6778 void mg_tls_handshake(struct mg_connection *c) {
6779   struct mg_tls *tls = (struct mg_tls *) c->tls;
6780   int rc = mbedtls_ssl_handshake(&tls->ssl);
6781   if (rc == 0) {  // Success
6782     MG_DEBUG(("%lu success", c->id));
6783     c->is_tls_hs = 0;
6784     mg_call(c, MG_EV_TLS_HS, NULL);
6785   } else if (rc == MBEDTLS_ERR_SSL_WANT_READ ||
6786              rc == MBEDTLS_ERR_SSL_WANT_WRITE) {  // Still pending
6787     MG_VERBOSE(("%lu pending, %d%d %d (-%#x)", c->id, c->is_connecting,
6788                 c->is_tls_hs, rc, -rc));
6789   } else {
6790     mg_error(c, "TLS handshake: -%#x", -rc);  // Error
6791   }
6792 }
6793
6794 static int mbed_rng(void *ctx, unsigned char *buf, size_t len) {
6795   mg_random(buf, len);
6796   (void) ctx;
6797   return 0;
6798 }
6799
6800 static void debug_cb(void *c, int lev, const char *s, int n, const char *s2) {
6801   n = (int) strlen(s2) - 1;
6802   MG_INFO(("%lu %d %.*s", ((struct mg_connection *) c)->id, lev, n, s2));
6803   (void) s;
6804 }
6805
6806 #ifdef MBEDTLS_SSL_SESSION_TICKETS
6807 static int rng_get(void *p_rng, unsigned char *buf, size_t len) {
6808   (void) p_rng;
6809   mg_random(buf, len);
6810   return 0;
6811 }
6812 #endif
6813
6814 void mg_tls_init(struct mg_connection *c, struct mg_str hostname) {
6815   struct mg_tls_ctx *ctx = (struct mg_tls_ctx *) c->mgr->tls_ctx;
6816   struct mg_tls *tls = (struct mg_tls *) calloc(1, sizeof(*tls));
6817   int rc = 0;
6818
6819   c->tls = tls;
6820   if (c->tls == NULL) {
6821     mg_error(c, "TLS OOM");
6822     goto fail;
6823   }
6824
6825   MG_DEBUG(("%lu Setting TLS", c->id));
6826   mbedtls_ssl_init(&tls->ssl);
6827   mbedtls_ssl_config_init(&tls->conf);
6828   mbedtls_ssl_conf_dbg(&tls->conf, debug_cb, c);
6829 #if defined(MG_MBEDTLS_DEBUG_LEVEL)
6830   mbedtls_debug_set_threshold(MG_MBEDTLS_DEBUG_LEVEL);
6831 #endif
6832   if ((rc = mbedtls_ssl_config_defaults(
6833            &tls->conf,
6834            c->is_client ? MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER,
6835            MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
6836     mg_error(c, "tls defaults %#x", -rc);
6837     goto fail;
6838   }
6839   mbedtls_ssl_conf_rng(&tls->conf, mbed_rng, c);
6840
6841   if (c->is_client && ctx->client_ca.version) {
6842     mbedtls_ssl_conf_ca_chain(&tls->conf, &ctx->client_ca, NULL);
6843     mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
6844     if (hostname.ptr != NULL && hostname.ptr[0] != '\0') {
6845       struct mg_addr addr;
6846       if (!mg_aton(hostname, &addr)) {  // if srvname is not an IP address
6847         char *host = mg_mprintf("%.*s", (int) hostname.len, hostname.ptr);
6848         mbedtls_ssl_set_hostname(&tls->ssl, host);
6849         free(host);
6850       }
6851     }
6852   } else if (!c->is_client && ctx->server_ca.version) {
6853     mbedtls_ssl_conf_ca_chain(&tls->conf, &ctx->server_ca, NULL);
6854     mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
6855   } else {
6856     mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_NONE);
6857   }
6858   if (c->is_client && ctx->client_cert.version &&
6859       (rc = mbedtls_ssl_conf_own_cert(&tls->conf, &ctx->client_cert,
6860                                       &ctx->client_key)) != 0) {
6861     mg_error(c, "own cert %#x", -rc);
6862     goto fail;
6863   }
6864   if (!c->is_client && ctx->server_cert.version &&
6865       (rc = mbedtls_ssl_conf_own_cert(&tls->conf, &ctx->server_cert,
6866                                       &ctx->server_key)) != 0) {
6867     mg_error(c, "own cert %#x", -rc);
6868     goto fail;
6869   }
6870 #ifdef MBEDTLS_SSL_SESSION_TICKETS
6871   mbedtls_ssl_conf_session_tickets_cb(&tls->conf, mbedtls_ssl_ticket_write,
6872                                       mbedtls_ssl_ticket_parse,
6873                                       &ctx->ticket_ctx);
6874 #endif
6875
6876   if ((rc = mbedtls_ssl_setup(&tls->ssl, &tls->conf)) != 0) {
6877     mg_error(c, "setup err %#x", -rc);
6878     goto fail;
6879   }
6880
6881   c->tls = tls;
6882   c->is_tls = 1;
6883   c->is_tls_hs = 1;
6884   mbedtls_ssl_set_bio(&tls->ssl, c, mg_net_send, mg_net_recv, 0);
6885   if (c->is_client && c->is_resolving == 0 && c->is_connecting == 0) {
6886     mg_tls_handshake(c);
6887   }
6888   return;
6889 fail:
6890   mg_tls_free(c);
6891 }
6892
6893 size_t mg_tls_pending(struct mg_connection *c) {
6894   struct mg_tls *tls = (struct mg_tls *) c->tls;
6895   return tls == NULL ? 0 : mbedtls_ssl_get_bytes_avail(&tls->ssl);
6896 }
6897
6898 long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
6899   struct mg_tls *tls = (struct mg_tls *) c->tls;
6900   long n = mbedtls_ssl_read(&tls->ssl, (unsigned char *) buf, len);
6901   if (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE)
6902     return MG_IO_WAIT;
6903   if (n <= 0) return MG_IO_ERR;
6904   return n;
6905 }
6906
6907 long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
6908   struct mg_tls *tls = (struct mg_tls *) c->tls;
6909   long n = mbedtls_ssl_write(&tls->ssl, (unsigned char *) buf, len);
6910   if (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE)
6911     return MG_IO_WAIT;
6912   if (n <= 0) return MG_IO_ERR;
6913   return n;
6914 }
6915
6916 static bool load_cert(struct mg_str str, mbedtls_x509_crt *p) {
6917   int rc;
6918   if (str.ptr == NULL || str.ptr[0] == '\0' || str.ptr[0] == '*') return true;
6919   if (str.ptr[0] == '-') str.len++;  // PEM, include trailing NUL
6920   if ((rc = mbedtls_x509_crt_parse(p, (uint8_t *) str.ptr, str.len)) != 0) {
6921     MG_ERROR(("cert err %#x", -rc));
6922     return false;
6923   }
6924   return true;
6925 }
6926
6927 static bool load_key(struct mg_str str, mbedtls_pk_context *p) {
6928   int rc;
6929   if (str.ptr == NULL || str.ptr[0] == '\0' || str.ptr[0] == '*') return true;
6930   if (str.ptr[0] == '-') str.len++;  // PEM, include trailing NUL
6931   if ((rc = mbedtls_pk_parse_key(p, (uint8_t *) str.ptr, str.len, NULL,
6932                                  0 MGRNG)) != 0) {
6933     MG_ERROR(("key err %#x", -rc));
6934     return false;
6935   }
6936   return true;
6937 }
6938
6939 void mg_tls_ctx_init(struct mg_mgr *mgr, const struct mg_tls_opts *opts) {
6940   struct mg_tls_ctx *ctx = (struct mg_tls_ctx *) calloc(1, sizeof(*ctx));
6941   if (ctx == NULL) goto fail;
6942   MG_DEBUG(("Setting up TLS context"));
6943
6944 #if defined(MG_MBEDTLS_DEBUG_LEVEL)
6945   mbedtls_debug_set_threshold(MG_MBEDTLS_DEBUG_LEVEL);
6946 #endif
6947
6948   if (!load_cert(opts->client_ca, &ctx->client_ca)) goto fail;
6949   if (!load_cert(opts->server_ca, &ctx->server_ca)) goto fail;
6950   if (!load_cert(opts->client_cert, &ctx->client_cert)) goto fail;
6951   if (!load_cert(opts->server_cert, &ctx->server_cert)) goto fail;
6952   if (!load_key(opts->server_key, &ctx->server_key)) goto fail;
6953   if (!load_key(opts->client_key, &ctx->client_key)) goto fail;
6954
6955 #ifdef MBEDTLS_SSL_SESSION_TICKETS
6956   {
6957     int rc;
6958     mbedtls_ssl_ticket_init(&ctx->ticket_ctx);
6959     if ((rc = mbedtls_ssl_ticket_setup(&ctx->ticket_ctx, rng_get, NULL,
6960                                        MBEDTLS_CIPHER_AES_128_GCM, 86400)) !=
6961         0) {
6962       MG_ERROR(("setup session tickets err %#x", -rc));
6963       goto fail;
6964     }
6965   }
6966 #endif
6967   mgr->tls_ctx = ctx;
6968   return;
6969 fail:
6970   mg_tls_ctx_free(mgr);
6971 }
6972
6973 void mg_tls_ctx_free(struct mg_mgr *mgr) {
6974   struct mg_tls_ctx *ctx = (struct mg_tls_ctx *) mgr->tls_ctx;
6975   if (ctx != NULL) {
6976     mbedtls_x509_crt_free(&ctx->server_cert);
6977     mbedtls_pk_free(&ctx->server_key);
6978     mbedtls_x509_crt_free(&ctx->client_cert);
6979     mbedtls_pk_free(&ctx->client_key);
6980     mbedtls_x509_crt_free(&ctx->client_ca);
6981     mbedtls_x509_crt_free(&ctx->server_ca);
6982 #ifdef MBEDTLS_SSL_SESSION_TICKETS
6983     mbedtls_ssl_ticket_free(&ctx->ticket_ctx);
6984 #endif
6985     free(ctx);
6986     mgr->tls_ctx = NULL;
6987   }
6988 }
6989 #endif
6990
6991 #ifdef MG_ENABLE_LINES
6992 #line 1 "src/tls_openssl.c"
6993 #endif
6994
6995
6996
6997 #if MG_TLS == MG_TLS_OPENSSL
6998 static int mg_tls_err(struct mg_tls *tls, int res) {
6999   int err = SSL_get_error(tls->ssl, res);
7000   // We've just fetched the last error from the queue.
7001   // Now we need to clear the error queue. If we do not, then the following
7002   // can happen (actually reported):
7003   //  - A new connection is accept()-ed with cert error (e.g. self-signed cert)
7004   //  - Since all accept()-ed connections share listener's context,
7005   //  - *ALL* SSL accepted connection report read error on the next poll cycle.
7006   //    Thus a single errored connection can close all the rest, unrelated ones.
7007   // Clearing the error keeps the shared SSL_CTX in an OK state.
7008
7009   if (err != 0) ERR_print_errors_fp(stderr);
7010   ERR_clear_error();
7011   if (err == SSL_ERROR_WANT_READ) return 0;
7012   if (err == SSL_ERROR_WANT_WRITE) return 0;
7013   return err;
7014 }
7015
7016 static STACK_OF(X509_INFO) * load_ca_certs(const char *ca, int ca_len) {
7017   BIO *ca_bio = BIO_new_mem_buf(ca, ca_len);
7018   if (!ca_bio) return NULL;
7019   STACK_OF(X509_INFO) *certs = PEM_X509_INFO_read_bio(ca_bio, NULL, NULL, NULL);
7020   BIO_free(ca_bio);
7021   return certs;
7022 }
7023
7024 static bool add_ca_certs(SSL_CTX *ctx, STACK_OF(X509_INFO) * certs) {
7025   X509_STORE *cert_store = SSL_CTX_get_cert_store(ctx);
7026   for (int i = 0; i < sk_X509_INFO_num(certs); i++) {
7027     X509_INFO *cert_info = sk_X509_INFO_value(certs, i);
7028     if (cert_info->x509 && !X509_STORE_add_cert(cert_store, cert_info->x509))
7029       return false;
7030   }
7031   return true;
7032 }
7033
7034 static EVP_PKEY *load_key(const char *key, int key_len) {
7035   BIO *key_bio = BIO_new_mem_buf(key, key_len);
7036   if (!key_bio) return NULL;
7037   EVP_PKEY *priv_key = PEM_read_bio_PrivateKey(key_bio, NULL, 0, NULL);
7038   BIO_free(key_bio);
7039   return priv_key;
7040 }
7041
7042 static X509 *load_cert(const char *cert, int cert_len) {
7043   BIO *cert_bio = BIO_new_mem_buf(cert, cert_len);
7044   if (!cert_bio) return NULL;
7045   X509 *x509 = PEM_read_bio_X509(cert_bio, NULL, 0, NULL);
7046   BIO_free(cert_bio);
7047   return x509;
7048 }
7049
7050 void mg_tls_init(struct mg_connection *c, struct mg_str hostname) {
7051   struct mg_tls_ctx *ctx = (struct mg_tls_ctx *) c->mgr->tls_ctx;
7052   struct mg_tls *tls = (struct mg_tls *) calloc(1, sizeof(*tls));
7053
7054   if (ctx == NULL) {
7055     mg_error(c, "TLS context not initialized");
7056     goto fail;
7057   }
7058
7059   if (tls == NULL) {
7060     mg_error(c, "TLS OOM");
7061     goto fail;
7062   }
7063
7064   tls->ctx = c->is_client ? SSL_CTX_new(TLS_client_method())
7065                           : SSL_CTX_new(TLS_server_method());
7066   if ((tls->ssl = SSL_new(tls->ctx)) == NULL) {
7067     mg_error(c, "SSL_new");
7068     goto fail;
7069   }
7070
7071   SSL_set_min_proto_version(tls->ssl, TLS1_2_VERSION);
7072
7073 #ifdef MG_ENABLE_OPENSSL_NO_COMPRESSION
7074   SSL_set_options(tls->ssl, SSL_OP_NO_COMPRESSION);
7075 #endif
7076 #ifdef MG_ENABLE_OPENSSL_CIPHER_SERVER_PREFERENCE
7077   SSL_set_options(tls->ssl, SSL_OP_CIPHER_SERVER_PREFERENCE);
7078 #endif
7079
7080   if (c->is_client) {
7081     if (ctx->client_ca) {
7082       SSL_set_verify(tls->ssl,
7083                      SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
7084       if (!add_ca_certs(tls->ctx, ctx->client_ca)) goto fail;
7085     }
7086     if (ctx->client_cert && ctx->client_key) {
7087       if (SSL_use_certificate(tls->ssl, ctx->client_cert) != 1) {
7088         mg_error(c, "SSL_CTX_use_certificate");
7089         goto fail;
7090       }
7091       if (SSL_use_PrivateKey(tls->ssl, ctx->client_key) != 1) {
7092         mg_error(c, "SSL_CTX_use_PrivateKey");
7093         goto fail;
7094       }
7095     }
7096   } else {
7097     if (ctx->server_ca) {
7098       SSL_set_verify(tls->ssl,
7099                      SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
7100       if (!add_ca_certs(tls->ctx, ctx->server_ca)) goto fail;
7101     }
7102     if (ctx->server_cert && ctx->server_key) {
7103       if (SSL_use_certificate(tls->ssl, ctx->server_cert) != 1) {
7104         mg_error(c, "SSL_CTX_use_certificate");
7105         goto fail;
7106       }
7107       if (SSL_use_PrivateKey(tls->ssl, ctx->server_key) != 1) {
7108         mg_error(c, "SSL_CTX_use_PrivateKey");
7109         goto fail;
7110       }
7111     }
7112   }
7113
7114   SSL_set_mode(tls->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
7115 #if OPENSSL_VERSION_NUMBER > 0x10002000L
7116   SSL_set_ecdh_auto(tls->ssl, 1);
7117 #endif
7118
7119 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
7120   if (c->is_client && hostname.ptr && hostname.ptr[0] != '\0') {
7121     char *s = mg_mprintf("%.*s", (int) hostname.len, hostname.ptr);
7122     SSL_set1_host(tls->ssl, s);
7123     SSL_set_tlsext_host_name(tls->ssl, s);
7124     free(s);
7125   }
7126 #endif
7127
7128   c->tls = tls;
7129   c->is_tls = 1;
7130   c->is_tls_hs = 1;
7131   if (c->is_client && c->is_resolving == 0 && c->is_connecting == 0) {
7132     mg_tls_handshake(c);
7133   }
7134   MG_DEBUG(("%lu SSL %s OK", c->id, c->is_accepted ? "accept" : "client"));
7135   return;
7136
7137 fail:
7138   c->is_closing = 1;
7139   free(tls);
7140 }
7141
7142 void mg_tls_handshake(struct mg_connection *c) {
7143   struct mg_tls *tls = (struct mg_tls *) c->tls;
7144   int rc;
7145   SSL_set_fd(tls->ssl, (int) (size_t) c->fd);
7146   rc = c->is_client ? SSL_connect(tls->ssl) : SSL_accept(tls->ssl);
7147   if (rc == 1) {
7148     MG_DEBUG(("%lu success", c->id));
7149     c->is_tls_hs = 0;
7150     mg_call(c, MG_EV_TLS_HS, NULL);
7151   } else {
7152     int code = mg_tls_err(tls, rc);
7153     if (code != 0) mg_error(c, "tls hs: rc %d, err %d", rc, code);
7154   }
7155 }
7156
7157 void mg_tls_free(struct mg_connection *c) {
7158   struct mg_tls *tls = (struct mg_tls *) c->tls;
7159   if (tls == NULL) return;
7160   SSL_free(tls->ssl);
7161   SSL_CTX_free(tls->ctx);
7162   free(tls);
7163   c->tls = NULL;
7164 }
7165
7166 size_t mg_tls_pending(struct mg_connection *c) {
7167   struct mg_tls *tls = (struct mg_tls *) c->tls;
7168   return tls == NULL ? 0 : (size_t) SSL_pending(tls->ssl);
7169 }
7170
7171 long mg_tls_recv(struct mg_connection *c, void *buf, size_t len) {
7172   struct mg_tls *tls = (struct mg_tls *) c->tls;
7173   int n = SSL_read(tls->ssl, buf, (int) len);
7174   if (n < 0 && mg_tls_err(tls, n) == 0) return MG_IO_WAIT;
7175   if (n <= 0) return MG_IO_ERR;
7176   return n;
7177 }
7178
7179 long mg_tls_send(struct mg_connection *c, const void *buf, size_t len) {
7180   struct mg_tls *tls = (struct mg_tls *) c->tls;
7181   int n = SSL_write(tls->ssl, buf, (int) len);
7182   if (n < 0 && mg_tls_err(tls, n) == 0) return MG_IO_WAIT;
7183   if (n <= 0) return MG_IO_ERR;
7184   return n;
7185 }
7186
7187 void mg_tls_ctx_free(struct mg_mgr *mgr) {
7188   struct mg_tls_ctx *ctx = (struct mg_tls_ctx *) mgr->tls_ctx;
7189   if (ctx) {
7190     if (ctx->server_cert) X509_free(ctx->server_cert);
7191     if (ctx->server_key) EVP_PKEY_free(ctx->server_key);
7192     if (ctx->server_ca)
7193       sk_X509_INFO_pop_free(ctx->server_ca, X509_INFO_free);
7194     if (ctx->client_cert) X509_free(ctx->client_cert);
7195     if (ctx->client_key) EVP_PKEY_free(ctx->client_key);
7196     if (ctx->client_ca)
7197       sk_X509_INFO_pop_free(ctx->client_ca, X509_INFO_free);
7198     free(ctx);
7199     mgr->tls_ctx = NULL;
7200   }
7201 }
7202
7203 void mg_tls_ctx_init(struct mg_mgr *mgr, const struct mg_tls_opts *opts) {
7204   static unsigned char s_initialised = 0;
7205   if (!s_initialised) {
7206     SSL_library_init();
7207     s_initialised++;
7208   }
7209
7210   struct mg_tls_ctx *ctx = (struct mg_tls_ctx *) calloc(1, sizeof(*ctx));
7211   if (ctx == NULL) return;
7212
7213   if (opts->server_cert.ptr && opts->server_cert.ptr[0] != '\0') {
7214     struct mg_str key = opts->server_key;
7215     if (!key.ptr) key = opts->server_cert;
7216     if (!(ctx->server_cert =
7217               load_cert(opts->server_cert.ptr, (int) opts->server_cert.len)))
7218       goto fail;
7219     if (!(ctx->server_key = load_key(key.ptr, (int) key.len))) goto fail;
7220   }
7221
7222   if (opts->server_ca.ptr && opts->server_ca.ptr[0] != '\0') {
7223     if (!(ctx->server_ca =
7224               load_ca_certs(opts->server_ca.ptr, (int) opts->server_ca.len)))
7225       goto fail;
7226   }
7227
7228   if (opts->client_cert.ptr && opts->client_cert.ptr[0] != '\0') {
7229     struct mg_str key = opts->client_key;
7230     if (!key.ptr) key = opts->client_cert;
7231     if (!(ctx->client_cert =
7232               load_cert(opts->client_cert.ptr, (int) opts->client_cert.len)))
7233       goto fail;
7234     if (!(ctx->client_key = load_key(key.ptr, (int) key.len))) goto fail;
7235   }
7236
7237   if (opts->client_ca.ptr && opts->client_ca.ptr[0] != '\0') {
7238     if (!(ctx->client_ca =
7239               load_ca_certs(opts->client_ca.ptr, (int) opts->client_ca.len)))
7240       goto fail;
7241   }
7242
7243   mgr->tls_ctx = ctx;
7244   return;
7245 fail:
7246   MG_ERROR(("TLS ctx init error"));
7247   mg_tls_ctx_free(mgr);
7248 }
7249
7250 #endif
7251
7252 #ifdef MG_ENABLE_LINES
7253 #line 1 "src/url.c"
7254 #endif
7255
7256
7257 struct url {
7258   size_t key, user, pass, host, port, uri, end;
7259 };
7260
7261 int mg_url_is_ssl(const char *url) {
7262   return strncmp(url, "wss:", 4) == 0 || strncmp(url, "https:", 6) == 0 ||
7263          strncmp(url, "mqtts:", 6) == 0 || strncmp(url, "ssl:", 4) == 0 ||
7264          strncmp(url, "tls:", 4) == 0;
7265 }
7266
7267 static struct url urlparse(const char *url) {
7268   size_t i;
7269   struct url u;
7270   memset(&u, 0, sizeof(u));
7271   for (i = 0; url[i] != '\0'; i++) {
7272     if (url[i] == '/' && i > 0 && u.host == 0 && url[i - 1] == '/') {
7273       u.host = i + 1;
7274       u.port = 0;
7275     } else if (url[i] == ']') {
7276       u.port = 0;  // IPv6 URLs, like http://[::1]/bar
7277     } else if (url[i] == ':' && u.port == 0 && u.uri == 0) {
7278       u.port = i + 1;
7279     } else if (url[i] == '@' && u.user == 0 && u.pass == 0 && u.uri == 0) {
7280       u.user = u.host;
7281       u.pass = u.port;
7282       u.host = i + 1;
7283       u.port = 0;
7284     } else if (url[i] == '/' && u.host && u.uri == 0) {
7285       u.uri = i;
7286     }
7287   }
7288   u.end = i;
7289 #if 0
7290   printf("[%s] %d %d %d %d %d\n", url, u.user, u.pass, u.host, u.port, u.uri);
7291 #endif
7292   return u;
7293 }
7294
7295 struct mg_str mg_url_host(const char *url) {
7296   struct url u = urlparse(url);
7297   size_t n = u.port  ? u.port - u.host - 1
7298              : u.uri ? u.uri - u.host
7299                      : u.end - u.host;
7300   struct mg_str s = mg_str_n(url + u.host, n);
7301   return s;
7302 }
7303
7304 const char *mg_url_uri(const char *url) {
7305   struct url u = urlparse(url);
7306   return u.uri ? url + u.uri : "/";
7307 }
7308
7309 unsigned short mg_url_port(const char *url) {
7310   struct url u = urlparse(url);
7311   unsigned short port = 0;
7312   if (strncmp(url, "http:", 5) == 0 || strncmp(url, "ws:", 3) == 0) port = 80;
7313   if (strncmp(url, "wss:", 4) == 0 || strncmp(url, "https:", 6) == 0)
7314     port = 443;
7315   if (strncmp(url, "mqtt:", 5) == 0) port = 1883;
7316   if (strncmp(url, "mqtts:", 6) == 0) port = 8883;
7317   if (u.port) port = (unsigned short) atoi(url + u.port);
7318   return port;
7319 }
7320
7321 struct mg_str mg_url_user(const char *url) {
7322   struct url u = urlparse(url);
7323   struct mg_str s = mg_str("");
7324   if (u.user && (u.pass || u.host)) {
7325     size_t n = u.pass ? u.pass - u.user - 1 : u.host - u.user - 1;
7326     s = mg_str_n(url + u.user, n);
7327   }
7328   return s;
7329 }
7330
7331 struct mg_str mg_url_pass(const char *url) {
7332   struct url u = urlparse(url);
7333   struct mg_str s = mg_str_n("", 0UL);
7334   if (u.pass && u.host) {
7335     size_t n = u.host - u.pass - 1;
7336     s = mg_str_n(url + u.pass, n);
7337   }
7338   return s;
7339 }
7340
7341 #ifdef MG_ENABLE_LINES
7342 #line 1 "src/util.c"
7343 #endif
7344
7345
7346 #if MG_ENABLE_CUSTOM_RANDOM
7347 #else
7348 void mg_random(void *buf, size_t len) {
7349   bool done = false;
7350   unsigned char *p = (unsigned char *) buf;
7351 #if MG_ARCH == MG_ARCH_ESP32
7352   while (len--) *p++ = (unsigned char) (esp_random() & 255);
7353   done = true;
7354 #elif MG_ARCH == MG_ARCH_WIN32
7355 #elif MG_ARCH == MG_ARCH_UNIX
7356   FILE *fp = fopen("/dev/urandom", "rb");
7357   if (fp != NULL) {
7358     if (fread(buf, 1, len, fp) == len) done = true;
7359     fclose(fp);
7360   }
7361 #endif
7362   // If everything above did not work, fallback to a pseudo random generator
7363   while (!done && len--) *p++ = (unsigned char) (rand() & 255);
7364 }
7365 #endif
7366
7367 char *mg_random_str(char *buf, size_t len) {
7368   size_t i;
7369   mg_random(buf, len);
7370   for (i = 0; i < len; i++) {
7371     uint8_t c = ((uint8_t *) buf)[i] % 62U;
7372     buf[i] = i == len - 1 ? (char) '\0'            // 0-terminate last byte
7373              : c < 26     ? (char) ('a' + c)       // lowercase
7374              : c < 52     ? (char) ('A' + c - 26)  // uppercase
7375                           : (char) ('0' + c - 52);     // numeric
7376   }
7377   return buf;
7378 }
7379
7380 uint32_t mg_ntohl(uint32_t net) {
7381   uint8_t data[4] = {0, 0, 0, 0};
7382   memcpy(&data, &net, sizeof(data));
7383   return (((uint32_t) data[3]) << 0) | (((uint32_t) data[2]) << 8) |
7384          (((uint32_t) data[1]) << 16) | (((uint32_t) data[0]) << 24);
7385 }
7386
7387 uint16_t mg_ntohs(uint16_t net) {
7388   uint8_t data[2] = {0, 0};
7389   memcpy(&data, &net, sizeof(data));
7390   return (uint16_t) ((uint16_t) data[1] | (((uint16_t) data[0]) << 8));
7391 }
7392
7393 uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len) {
7394   static const uint32_t crclut[16] = {
7395       // table for polynomial 0xEDB88320 (reflected)
7396       0x00000000, 0x1DB71064, 0x3B6E20C8, 0x26D930AC, 0x76DC4190, 0x6B6B51F4,
7397       0x4DB26158, 0x5005713C, 0xEDB88320, 0xF00F9344, 0xD6D6A3E8, 0xCB61B38C,
7398       0x9B64C2B0, 0x86D3D2D4, 0xA00AE278, 0xBDBDF21C};
7399   crc = ~crc;
7400   while (len--) {
7401     uint8_t byte = *(uint8_t *) buf++;
7402     crc = crclut[(crc ^ byte) & 0x0F] ^ (crc >> 4);
7403     crc = crclut[(crc ^ (byte >> 4)) & 0x0F] ^ (crc >> 4);
7404   }
7405   return ~crc;
7406 }
7407
7408 static int isbyte(int n) {
7409   return n >= 0 && n <= 255;
7410 }
7411
7412 static int parse_net(const char *spec, uint32_t *net, uint32_t *mask) {
7413   int n, a, b, c, d, slash = 32, len = 0;
7414   if ((sscanf(spec, "%d.%d.%d.%d/%d%n", &a, &b, &c, &d, &slash, &n) == 5 ||
7415        sscanf(spec, "%d.%d.%d.%d%n", &a, &b, &c, &d, &n) == 4) &&
7416       isbyte(a) && isbyte(b) && isbyte(c) && isbyte(d) && slash >= 0 &&
7417       slash < 33) {
7418     len = n;
7419     *net = ((uint32_t) a << 24) | ((uint32_t) b << 16) | ((uint32_t) c << 8) |
7420            (uint32_t) d;
7421     *mask = slash ? (uint32_t) (0xffffffffU << (32 - slash)) : (uint32_t) 0;
7422   }
7423   return len;
7424 }
7425
7426 int mg_check_ip_acl(struct mg_str acl, struct mg_addr *remote_ip) {
7427   struct mg_str k, v;
7428   int allowed = acl.len == 0 ? '+' : '-';  // If any ACL is set, deny by default
7429   uint32_t remote_ip4;
7430   if (remote_ip->is_ip6) {
7431     return -1;  // TODO(): handle IPv6 ACL and addresses
7432   } else {  // IPv4
7433     memcpy((void *) &remote_ip4, remote_ip->ip, sizeof(remote_ip4));
7434     while (mg_commalist(&acl, &k, &v)) {
7435       uint32_t net, mask;
7436       if (k.ptr[0] != '+' && k.ptr[0] != '-') return -1;
7437       if (parse_net(&k.ptr[1], &net, &mask) == 0) return -2;
7438       if ((mg_ntohl(remote_ip4) & mask) == net) allowed = k.ptr[0];
7439     }
7440   }
7441   return allowed == '+';
7442 }
7443
7444 #if MG_ENABLE_CUSTOM_MILLIS
7445 #else
7446 uint64_t mg_millis(void) {
7447 #if MG_ARCH == MG_ARCH_WIN32
7448   return GetTickCount();
7449 #elif MG_ARCH == MG_ARCH_RP2040
7450   return time_us_64() / 1000;
7451 #elif MG_ARCH == MG_ARCH_ESP32
7452   return esp_timer_get_time() / 1000;
7453 #elif MG_ARCH == MG_ARCH_ESP8266 || MG_ARCH == MG_ARCH_FREERTOS
7454   return xTaskGetTickCount() * portTICK_PERIOD_MS;
7455 #elif MG_ARCH == MG_ARCH_AZURERTOS
7456   return tx_time_get() * (1000 /* MS per SEC */ / TX_TIMER_TICKS_PER_SECOND);
7457 #elif MG_ARCH == MG_ARCH_TIRTOS
7458   return (uint64_t) Clock_getTicks();
7459 #elif MG_ARCH == MG_ARCH_ZEPHYR
7460   return (uint64_t) k_uptime_get();
7461 #elif MG_ARCH == MG_ARCH_CMSIS_RTOS1
7462   return (uint64_t) rt_time_get();
7463 #elif MG_ARCH == MG_ARCH_CMSIS_RTOS2
7464   return (uint64_t) ((osKernelGetTickCount() * 1000) / osKernelGetTickFreq());
7465 #elif MG_ARCH == MG_ARCH_RTTHREAD
7466   return (uint64_t) ((rt_tick_get() * 1000) / RT_TICK_PER_SECOND);
7467 #elif MG_ARCH == MG_ARCH_UNIX && defined(__APPLE__)
7468   // Apple CLOCK_MONOTONIC_RAW is equivalent to CLOCK_BOOTTIME on linux
7469   // Apple CLOCK_UPTIME_RAW is equivalent to CLOCK_MONOTONIC_RAW on linux
7470   return clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / 1000000;
7471 #elif MG_ARCH == MG_ARCH_UNIX
7472   struct timespec ts = {0, 0};
7473   // See #1615 - prefer monotonic clock
7474 #if defined(CLOCK_MONOTONIC_RAW)
7475   // Raw hardware-based time that is not subject to NTP adjustment
7476   clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
7477 #elif defined(CLOCK_MONOTONIC)
7478   // Affected by the incremental adjustments performed by adjtime and NTP
7479   clock_gettime(CLOCK_MONOTONIC, &ts);
7480 #else
7481   // Affected by discontinuous jumps in the system time and by the incremental
7482   // adjustments performed by adjtime and NTP
7483   clock_gettime(CLOCK_REALTIME, &ts);
7484 #endif
7485   return ((uint64_t) ts.tv_sec * 1000 + (uint64_t) ts.tv_nsec / 1000000);
7486 #elif defined(ARDUINO)
7487   return (uint64_t) millis();
7488 #else
7489   return (uint64_t) (time(NULL) * 1000);
7490 #endif
7491 }
7492 #endif
7493
7494 #ifdef MG_ENABLE_LINES
7495 #line 1 "src/ws.c"
7496 #endif
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508 struct ws_msg {
7509   uint8_t flags;
7510   size_t header_len;
7511   size_t data_len;
7512 };
7513
7514 size_t mg_ws_vprintf(struct mg_connection *c, int op, const char *fmt,
7515                      va_list *ap) {
7516   size_t len = c->send.len;
7517   size_t n = mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
7518   mg_ws_wrap(c, c->send.len - len, op);
7519   return n;
7520 }
7521
7522 size_t mg_ws_printf(struct mg_connection *c, int op, const char *fmt, ...) {
7523   size_t len = 0;
7524   va_list ap;
7525   va_start(ap, fmt);
7526   len = mg_ws_vprintf(c, op, fmt, &ap);
7527   va_end(ap);
7528   return len;
7529 }
7530
7531 static void ws_handshake(struct mg_connection *c, const struct mg_str *wskey,
7532                          const struct mg_str *wsproto, const char *fmt,
7533                          va_list *ap) {
7534   const char *magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
7535   unsigned char sha[20], b64_sha[30];
7536
7537   mg_sha1_ctx sha_ctx;
7538   mg_sha1_init(&sha_ctx);
7539   mg_sha1_update(&sha_ctx, (unsigned char *) wskey->ptr, wskey->len);
7540   mg_sha1_update(&sha_ctx, (unsigned char *) magic, 36);
7541   mg_sha1_final(sha, &sha_ctx);
7542   mg_base64_encode(sha, sizeof(sha), (char *) b64_sha);
7543   mg_xprintf(mg_pfn_iobuf, &c->send,
7544              "HTTP/1.1 101 Switching Protocols\r\n"
7545              "Upgrade: websocket\r\n"
7546              "Connection: Upgrade\r\n"
7547              "Sec-WebSocket-Accept: %s\r\n",
7548              b64_sha);
7549   if (fmt != NULL) mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
7550   if (wsproto != NULL) {
7551     mg_printf(c, "Sec-WebSocket-Protocol: %.*s\r\n", (int) wsproto->len,
7552               wsproto->ptr);
7553   }
7554   mg_send(c, "\r\n", 2);
7555 }
7556
7557 static uint32_t be32(const uint8_t *p) {
7558   return (((uint32_t) p[3]) << 0) | (((uint32_t) p[2]) << 8) |
7559          (((uint32_t) p[1]) << 16) | (((uint32_t) p[0]) << 24);
7560 }
7561
7562 static size_t ws_process(uint8_t *buf, size_t len, struct ws_msg *msg) {
7563   size_t i, n = 0, mask_len = 0;
7564   memset(msg, 0, sizeof(*msg));
7565   if (len >= 2) {
7566     n = buf[1] & 0x7f;                // Frame length
7567     mask_len = buf[1] & 128 ? 4 : 0;  // last bit is a mask bit
7568     msg->flags = buf[0];
7569     if (n < 126 && len >= mask_len) {
7570       msg->data_len = n;
7571       msg->header_len = 2 + mask_len;
7572     } else if (n == 126 && len >= 4 + mask_len) {
7573       msg->header_len = 4 + mask_len;
7574       msg->data_len = (((size_t) buf[2]) << 8) | buf[3];
7575     } else if (len >= 10 + mask_len) {
7576       msg->header_len = 10 + mask_len;
7577       msg->data_len =
7578           (size_t) (((uint64_t) be32(buf + 2) << 32) + be32(buf + 6));
7579     }
7580   }
7581   // Sanity check, and integer overflow protection for the boundary check below
7582   // data_len should not be larger than 1 Gb
7583   if (msg->data_len > 1024 * 1024 * 1024) return 0;
7584   if (msg->header_len + msg->data_len > len) return 0;
7585   if (mask_len > 0) {
7586     uint8_t *p = buf + msg->header_len, *m = p - mask_len;
7587     for (i = 0; i < msg->data_len; i++) p[i] ^= m[i & 3];
7588   }
7589   return msg->header_len + msg->data_len;
7590 }
7591
7592 static size_t mkhdr(size_t len, int op, bool is_client, uint8_t *buf) {
7593   size_t n = 0;
7594   buf[0] = (uint8_t) (op | 128);
7595   if (len < 126) {
7596     buf[1] = (unsigned char) len;
7597     n = 2;
7598   } else if (len < 65536) {
7599     uint16_t tmp = mg_htons((uint16_t) len);
7600     buf[1] = 126;
7601     memcpy(&buf[2], &tmp, sizeof(tmp));
7602     n = 4;
7603   } else {
7604     uint32_t tmp;
7605     buf[1] = 127;
7606     tmp = mg_htonl((uint32_t) (((uint64_t) len) >> 32));
7607     memcpy(&buf[2], &tmp, sizeof(tmp));
7608     tmp = mg_htonl((uint32_t) (len & 0xffffffffU));
7609     memcpy(&buf[6], &tmp, sizeof(tmp));
7610     n = 10;
7611   }
7612   if (is_client) {
7613     buf[1] |= 1 << 7;  // Set masking flag
7614     mg_random(&buf[n], 4);
7615     n += 4;
7616   }
7617   return n;
7618 }
7619
7620 static void mg_ws_mask(struct mg_connection *c, size_t len) {
7621   if (c->is_client && c->send.buf != NULL) {
7622     size_t i;
7623     uint8_t *p = c->send.buf + c->send.len - len, *mask = p - 4;
7624     for (i = 0; i < len; i++) p[i] ^= mask[i & 3];
7625   }
7626 }
7627
7628 size_t mg_ws_send(struct mg_connection *c, const void *buf, size_t len,
7629                   int op) {
7630   uint8_t header[14];
7631   size_t header_len = mkhdr(len, op, c->is_client, header);
7632   mg_send(c, header, header_len);
7633   MG_VERBOSE(("WS out: %d [%.*s]", (int) len, (int) len, buf));
7634   mg_send(c, buf, len);
7635   mg_ws_mask(c, len);
7636   return header_len + len;
7637 }
7638
7639 static bool mg_ws_client_handshake(struct mg_connection *c) {
7640   int n = mg_http_get_request_len(c->recv.buf, c->recv.len);
7641   if (n < 0) {
7642     mg_error(c, "not http");  // Some just, not an HTTP request
7643   } else if (n > 0) {
7644     if (n < 15 || memcmp(c->recv.buf + 9, "101", 3) != 0) {
7645       mg_error(c, "ws handshake error");
7646     } else {
7647       struct mg_http_message hm;
7648       if (mg_http_parse((char *) c->recv.buf, c->recv.len, &hm)) {
7649         c->is_websocket = 1;
7650         mg_call(c, MG_EV_WS_OPEN, &hm);
7651       } else {
7652         mg_error(c, "ws handshake error");
7653       }
7654     }
7655     mg_iobuf_del(&c->recv, 0, (size_t) n);
7656   } else {
7657     return true;  // Request is not yet received, quit event handler
7658   }
7659   return false;  // Continue event handler
7660 }
7661
7662 static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data,
7663                      void *fn_data) {
7664   struct ws_msg msg;
7665   size_t ofs = (size_t) c->pfn_data;
7666
7667   // assert(ofs < c->recv.len);
7668   if (ev == MG_EV_READ) {
7669     if (c->is_client && !c->is_websocket && mg_ws_client_handshake(c)) return;
7670
7671     while (ws_process(c->recv.buf + ofs, c->recv.len - ofs, &msg) > 0) {
7672       char *s = (char *) c->recv.buf + ofs + msg.header_len;
7673       struct mg_ws_message m = {{s, msg.data_len}, msg.flags};
7674       size_t len = msg.header_len + msg.data_len;
7675       uint8_t final = msg.flags & 128, op = msg.flags & 15;
7676       // MG_VERBOSE ("fin %d op %d len %d [%.*s]", final, op,
7677       //                       (int) m.data.len, (int) m.data.len, m.data.ptr));
7678       switch (op) {
7679         case WEBSOCKET_OP_CONTINUE:
7680           mg_call(c, MG_EV_WS_CTL, &m);
7681           break;
7682         case WEBSOCKET_OP_PING:
7683           MG_DEBUG(("%s", "WS PONG"));
7684           mg_ws_send(c, s, msg.data_len, WEBSOCKET_OP_PONG);
7685           mg_call(c, MG_EV_WS_CTL, &m);
7686           break;
7687         case WEBSOCKET_OP_PONG:
7688           mg_call(c, MG_EV_WS_CTL, &m);
7689           break;
7690         case WEBSOCKET_OP_TEXT:
7691         case WEBSOCKET_OP_BINARY:
7692           if (final) mg_call(c, MG_EV_WS_MSG, &m);
7693           break;
7694         case WEBSOCKET_OP_CLOSE:
7695           MG_DEBUG(("%lu WS CLOSE", c->id));
7696           mg_call(c, MG_EV_WS_CTL, &m);
7697           // Echo the payload of the received CLOSE message back to the sender
7698           mg_ws_send(c, m.data.ptr, m.data.len, WEBSOCKET_OP_CLOSE);
7699           c->is_draining = 1;
7700           break;
7701         default:
7702           // Per RFC6455, close conn when an unknown op is recvd
7703           mg_error(c, "unknown WS op %d", op);
7704           break;
7705       }
7706
7707       // Handle fragmented frames: strip header, keep in c->recv
7708       if (final == 0 || op == 0) {
7709         if (op) ofs++, len--, msg.header_len--;       // First frame
7710         mg_iobuf_del(&c->recv, ofs, msg.header_len);  // Strip header
7711         len -= msg.header_len;
7712         ofs += len;
7713         c->pfn_data = (void *) ofs;
7714         // MG_INFO(("FRAG %d [%.*s]", (int) ofs, (int) ofs, c->recv.buf));
7715       }
7716       // Remove non-fragmented frame
7717       if (final && op) mg_iobuf_del(&c->recv, ofs, len);
7718       // Last chunk of the fragmented frame
7719       if (final && !op) {
7720         m.flags = c->recv.buf[0];
7721         m.data = mg_str_n((char *) &c->recv.buf[1], (size_t) (ofs - 1));
7722         mg_call(c, MG_EV_WS_MSG, &m);
7723         mg_iobuf_del(&c->recv, 0, ofs);
7724         ofs = 0;
7725         c->pfn_data = NULL;
7726       }
7727     }
7728   }
7729   (void) fn_data;
7730   (void) ev_data;
7731 }
7732
7733 struct mg_connection *mg_ws_connect(struct mg_mgr *mgr, const char *url,
7734                                     mg_event_handler_t fn, void *fn_data,
7735                                     const char *fmt, ...) {
7736   struct mg_connection *c = mg_connect(mgr, url, fn, fn_data);
7737   if (c != NULL) {
7738     char nonce[16], key[30];
7739     struct mg_str host = mg_url_host(url);
7740     mg_random(nonce, sizeof(nonce));
7741     mg_base64_encode((unsigned char *) nonce, sizeof(nonce), key);
7742     mg_xprintf(mg_pfn_iobuf, &c->send,
7743                "GET %s HTTP/1.1\r\n"
7744                "Upgrade: websocket\r\n"
7745                "Host: %.*s\r\n"
7746                "Connection: Upgrade\r\n"
7747                "Sec-WebSocket-Version: 13\r\n"
7748                "Sec-WebSocket-Key: %s\r\n",
7749                mg_url_uri(url), (int) host.len, host.ptr, key);
7750     if (fmt != NULL) {
7751       va_list ap;
7752       va_start(ap, fmt);
7753       mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, &ap);
7754       va_end(ap);
7755     }
7756     mg_xprintf(mg_pfn_iobuf, &c->send, "\r\n");
7757     c->pfn = mg_ws_cb;
7758     c->pfn_data = NULL;
7759   }
7760   return c;
7761 }
7762
7763 void mg_ws_upgrade(struct mg_connection *c, struct mg_http_message *hm,
7764                    const char *fmt, ...) {
7765   struct mg_str *wskey = mg_http_get_header(hm, "Sec-WebSocket-Key");
7766   c->pfn = mg_ws_cb;
7767   c->pfn_data = NULL;
7768   if (wskey == NULL) {
7769     mg_http_reply(c, 426, "", "WS upgrade expected\n");
7770     c->is_draining = 1;
7771   } else {
7772     struct mg_str *wsproto = mg_http_get_header(hm, "Sec-WebSocket-Protocol");
7773     va_list ap;
7774     va_start(ap, fmt);
7775     ws_handshake(c, wskey, wsproto, fmt, &ap);
7776     va_end(ap);
7777     c->is_websocket = 1;
7778     c->is_resp = 0;
7779     mg_call(c, MG_EV_WS_OPEN, hm);
7780   }
7781 }
7782
7783 size_t mg_ws_wrap(struct mg_connection *c, size_t len, int op) {
7784   uint8_t header[14], *p;
7785   size_t header_len = mkhdr(len, op, c->is_client, header);
7786
7787   // NOTE: order of operations is important!
7788   mg_iobuf_add(&c->send, c->send.len, NULL, header_len);
7789   p = &c->send.buf[c->send.len - len];         // p points to data
7790   memmove(p, p - header_len, len);             // Shift data
7791   memcpy(p - header_len, header, header_len);  // Prepend header
7792   mg_ws_mask(c, len);                          // Mask data
7793
7794   return c->send.len;
7795 }
7796
7797 #ifdef MG_ENABLE_LINES
7798 #line 1 "src/drivers/rt1020.c"
7799 #endif
7800
7801
7802 /*
7803  * Todo
7804  * This driver doesn't support 10M line autoconfiguration yet.
7805  * Packets aren't sent if the link negociated 10M line.
7806  * todo: MAC back auto reconfiguration.
7807  */
7808
7809 #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_IMXRT1020)
7810 struct imx_rt1020_enet {
7811 volatile uint32_t RESERVED0, EIR, EIMR, RESERVED1, RDAR, TDAR, RESERVED2[3], ECR, RESERVED3[6], MMFR, MSCR, RESERVED4[7], MIBC, RESERVED5[7], RCR, RESERVED6[15], TCR, RESERVED7[7], PALR, PAUR, OPD, TXIC0, TXIC1, TXIC2, RESERVED8, RXIC0, RXIC1, RXIC2, RESERVED9[3], IAUR, IALR, GAUR, GALR, RESERVED10[7], TFWR, RESERVED11[14], RDSR, TDSR, MRBR[2], RSFL, RSEM, RAEM, RAFL, TSEM, TAEM, TAFL, TIPG, FTRL, RESERVED12[3], TACC, RACC, RESERVED13[15], RMON_T_PACKETS, RMON_T_BC_PKT, RMON_T_MC_PKT, RMON_T_CRC_ALIGN, RMON_T_UNDERSIZE, RMON_T_OVERSIZE, RMON_T_FRAG, RMON_T_JAB, RMON_T_COL, RMON_T_P64, RMON_T_P65TO127, RMON_T_P128TO255, RMON_T_P256TO511, RMON_T_P512TO1023, RMON_T_P1024TO2048, RMON_T_GTE2048, RMON_T_OCTETS, IEEE_T_DROP, IEEE_T_FRAME_OK, IEEE_T_1COL, IEEE_T_MCOL, IEEE_T_DEF, IEEE_T_LCOL, IEEE_T_EXCOL, IEEE_T_MACERR, IEEE_T_CSERR, IEEE_T_SQE, IEEE_T_FDXFC, IEEE_T_OCTETS_OK, RESERVED14[3], RMON_R_PACKETS, RMON_R_BC_PKT, RMON_R_MC_PKT, RMON_R_CRC_ALIGN, RMON_R_UNDERSIZE, RMON_R_OVERSIZE, RMON_R_FRAG, RMON_R_JAB, RESERVED15, RMON_R_P64, RMON_R_P65TO127, RMON_R_P128TO255, RMON_R_P256TO511, RMON_R_P512TO1023, RMON_R_P1024TO2047, RMON_R_GTE2048, RMON_R_OCTETS, IEEE_R_DROP, IEEE_R_FRAME_OK, IEEE_R_CRC, IEEE_R_ALIGN, IEEE_R_MACERR, IEEE_R_FDXFC, IEEE_R_OCTETS_OK, RESERVED16[71], ATCR, ATVR, ATOFF, ATPER, ATCOR, ATINC, ATSTMP, RESERVED17[122], TGSR, TCSR0, TCCR0, TCSR1, TCCR1, TCSR2, TCCR2, TCSR3;
7812 };
7813
7814 #undef ENET
7815 #define ENET ((struct imx_rt1020_enet *) (uintptr_t) 0x402D8000u)
7816
7817 #undef BIT
7818 #define BIT(x) ((uint32_t) 1 << (x))
7819
7820 #define ENET_RXBUFF_SIZE 1536 // 1522 Buffer must be 64bits aligned
7821 #define ENET_TXBUFF_SIZE 1536 // 1522 hence set to 0x600 (1536)
7822 #define ENET_RXBD_NUM          (4)
7823 #define ENET_TXBD_NUM          (4)
7824
7825 const uint32_t EIMR_RX_ERR = 0x2400000;              // Intr mask RXF+EBERR
7826
7827 void ETH_IRQHandler(void);
7828 static bool mg_tcpip_driver_imxrt1020_init(struct mg_tcpip_if *ifp);
7829 static void wait_phy_complete(void);
7830 static struct mg_tcpip_if *s_ifp;                         // MIP interface
7831
7832 static size_t mg_tcpip_driver_imxrt1020_tx(const void *, size_t , struct mg_tcpip_if *);
7833 static bool mg_tcpip_driver_imxrt1020_up(struct mg_tcpip_if *ifp);
7834
7835 enum { IMXRT1020_PHY_ADDR = 0x02, IMXRT1020_PHY_BCR = 0, IMXRT1020_PHY_BSR = 1 };     // PHY constants
7836
7837 void delay(uint32_t);
7838 void delay (uint32_t di) {
7839   volatile int dno = 0; // Prevent optimization
7840   for (uint32_t i = 0; i < di; i++)
7841     for (int j=0; j<20; j++) // PLLx20 (500 MHz/24MHz)
7842       dno++;
7843 }
7844
7845 static void wait_phy_complete(void) {
7846   delay(0x00010000);
7847   const uint32_t delay_max = 0x00100000;
7848   uint32_t delay_cnt = 0;
7849   while (!(ENET->EIR & BIT(23)) && (delay_cnt < delay_max))
7850   {delay_cnt++;}
7851   ENET->EIR |= BIT(23); // MII interrupt clear
7852 }
7853
7854 static uint32_t imxrt1020_eth_read_phy(uint8_t addr, uint8_t reg) {
7855   ENET->EIR |= BIT(23); // MII interrupt clear
7856   uint32_t mask_phy_adr_reg = 0x1f; // 0b00011111: Ensure we write 5 bits (Phy address & register)
7857   uint32_t phy_transaction = 0x00;
7858   phy_transaction = (0x1 << 30) \
7859                   | (0x2 << 28) \
7860                   | ((uint32_t)(addr & mask_phy_adr_reg) << 23) \
7861                   | ((uint32_t)(reg & mask_phy_adr_reg)  << 18) \
7862                   | (0x2 << 16);
7863
7864   ENET->MMFR = phy_transaction;
7865   wait_phy_complete();
7866
7867   return (ENET->MMFR & 0x0000ffff);
7868 }
7869
7870 static void imxrt1020_eth_write_phy(uint8_t addr, uint8_t reg, uint32_t val) {
7871   ENET->EIR |= BIT(23); // MII interrupt clear
7872   uint8_t mask_phy_adr_reg = 0x1f; // 0b00011111: Ensure we write 5 bits (Phy address & register)
7873   uint32_t mask_phy_data = 0x0000ffff; // Ensure we write 16 bits (data)
7874   addr &= mask_phy_adr_reg;
7875   reg &= mask_phy_adr_reg;
7876   val &= mask_phy_data;
7877   uint32_t phy_transaction = 0x00;
7878   phy_transaction = (uint32_t)(0x1 << 30) \
7879                   | (uint32_t)(0x1 << 28) \
7880                   | (uint32_t)(addr << 23) \
7881                   | (uint32_t)(reg  << 18) \
7882                   | (uint32_t)(0x2 << 16) \
7883                   | (uint32_t)(val);
7884   ENET->MMFR = phy_transaction;
7885   wait_phy_complete();
7886 }
7887
7888 // FEC RX/TX descriptors (Enhanced descriptor not enabled)
7889 // Descriptor buffer structure, little endian
7890
7891 typedef struct enet_bd_struct_def
7892 {
7893     uint16_t length;  // Data length
7894     uint16_t control; // Control and status
7895     uint32_t *buffer; // Data ptr
7896 } enet_bd_struct_t;
7897
7898 // Descriptor and buffer globals, in non-cached area, 64 bits aligned.
7899
7900 __attribute__((section("NonCacheable,\"aw\",%nobits @"))) enet_bd_struct_t rx_buffer_descriptor[(ENET_RXBD_NUM)] __attribute__((aligned((64U))));
7901 __attribute__((section("NonCacheable,\"aw\",%nobits @"))) enet_bd_struct_t tx_buffer_descriptor[(ENET_TXBD_NUM)] __attribute__((aligned((64U))));
7902
7903 uint8_t rx_data_buffer[(ENET_RXBD_NUM)][((unsigned int)(((ENET_RXBUFF_SIZE)) + (((64U))-1U)) & (unsigned int)(~(unsigned int)(((64U))-1U)))] __attribute__((aligned((64U))));
7904 uint8_t tx_data_buffer[(ENET_TXBD_NUM)][((unsigned int)(((ENET_TXBUFF_SIZE)) + (((64U))-1U)) & (unsigned int)(~(unsigned int)(((64U))-1U)))] __attribute__((aligned((64U))));
7905
7906 // Initialise driver imx_rt1020
7907
7908 // static bool mg_tcpip_driver_imxrt1020_init(uint8_t *mac, void *data) { // VO
7909 static bool mg_tcpip_driver_imxrt1020_init(struct mg_tcpip_if *ifp) {
7910
7911   struct mg_tcpip_driver_imxrt1020_data *d = (struct mg_tcpip_driver_imxrt1020_data *) ifp->driver_data;
7912   s_ifp = ifp;
7913
7914   // ENET Reset, wait complete
7915   ENET->ECR |= BIT(0);
7916   while((ENET->ECR & BIT(0)) != 0) {}
7917
7918   // Re-latches the pin strapping pin values
7919   ENET->ECR |= BIT(0);
7920   while((ENET->ECR & BIT(0)) != 0) {}
7921
7922   // Setup MII/RMII MDC clock divider (<= 2.5MHz).
7923   ENET->MSCR = 0x130; // HOLDTIME 2 clk, Preamble enable, MDC MII_Speed Div 0x30
7924   imxrt1020_eth_write_phy(IMXRT1020_PHY_ADDR, IMXRT1020_PHY_BCR, 0x8000); // PHY W @0x00 D=0x8000 Soft reset
7925   while (imxrt1020_eth_read_phy(IMXRT1020_PHY_ADDR, IMXRT1020_PHY_BSR) & BIT(15)) {delay(0x5000);} // Wait finished poll 10ms
7926
7927   // PHY: Start Link
7928   {
7929     imxrt1020_eth_write_phy(IMXRT1020_PHY_ADDR, IMXRT1020_PHY_BCR, 0x1200); // PHY W @0x00 D=0x1200 Autonego enable + start
7930     imxrt1020_eth_write_phy(IMXRT1020_PHY_ADDR, 0x1f, 0x8180);    // PHY W @0x1f D=0x8180 Ref clock 50 MHz at XI input
7931
7932     uint32_t bcr = imxrt1020_eth_read_phy(IMXRT1020_PHY_ADDR, IMXRT1020_PHY_BCR);
7933     bcr &= ~BIT(10); // Isolation -> Normal
7934     imxrt1020_eth_write_phy(IMXRT1020_PHY_ADDR, IMXRT1020_PHY_BCR, bcr);
7935   }
7936
7937   // Disable ENET
7938   ENET->ECR = 0x0; //  Disable before configuration
7939
7940   // Configure ENET
7941   ENET->RCR = 0x05ee0104; // #CRCFWD=0 (CRC kept in frame) + RMII + MII Enable
7942   
7943   ENET->TCR = BIT(8) | BIT(2); // Addins (MAC address from PAUR+PALR) + Full duplex enable
7944   //ENET->TFWR = BIT(8); // Store And Forward Enable, 64 bytes (minimize tx latency)
7945
7946   // Configure descriptors and buffers
7947   // RX
7948   for (int i = 0; i < ENET_RXBD_NUM; i++) {
7949     // Wrap last descriptor buffer ptr
7950     rx_buffer_descriptor[i].control = (BIT(15) | ((i<(ENET_RXBD_NUM-1))?0:BIT(13))); // E+(W*)
7951     rx_buffer_descriptor[i].buffer = (uint32_t *)rx_data_buffer[i];
7952   }
7953
7954   // TX
7955   for (int i = 0; i < ENET_TXBD_NUM; i++) {
7956     // Wrap last descriptor buffer ptr
7957     tx_buffer_descriptor[i].control = ((i<(ENET_RXBD_NUM-1))?0:BIT(13)) | BIT(10); // (W*)+TC
7958     tx_buffer_descriptor[i].buffer = (uint32_t *)tx_data_buffer[i];
7959   }
7960
7961   // Continue ENET configuration
7962   ENET->RDSR = (uint32_t)(uintptr_t)rx_buffer_descriptor;
7963   ENET->TDSR = (uint32_t)(uintptr_t)tx_buffer_descriptor;
7964   ENET->MRBR[0] = ENET_RXBUFF_SIZE; // Same size for RX/TX buffers
7965
7966   // MAC address filtering (bytes in reversed order)
7967   ENET->PAUR = ((uint32_t) ifp->mac[4] << 24U) | (uint32_t) ifp->mac[5] << 16U;
7968   ENET->PALR = (uint32_t) (ifp->mac[0] << 24U) | ((uint32_t) ifp->mac[1] << 16U) |
7969                  ((uint32_t) ifp->mac[2] << 8U) | ifp->mac[3];
7970
7971   // Init Hash tables (mac filtering)
7972   ENET->IAUR = 0; // Unicast
7973   ENET->IALR = 0;
7974   ENET->GAUR = 0; // Multicast
7975   ENET->GALR = 0;
7976
7977   // Set ENET Online
7978   ENET->ECR |= BIT(8); // ENET Set Little-endian + (FEC buffer desc.)
7979   ENET->ECR |= BIT(1); // Enable
7980
7981   // Set interrupt mask
7982   ENET->EIMR = EIMR_RX_ERR;
7983
7984   // RX Descriptor activation
7985   ENET->RDAR = BIT(24); // Activate Receive Descriptor
7986   return true;
7987 }
7988
7989 // Transmit frame
7990 static uint32_t s_rt1020_txno;
7991
7992 static size_t mg_tcpip_driver_imxrt1020_tx(const void *buf, size_t len, struct mg_tcpip_if *ifp) {
7993
7994   if (len > sizeof(tx_data_buffer[ENET_TXBD_NUM])) {
7995   //  MG_ERROR(("Frame too big, %ld", (long) len));
7996     len = 0;  // Frame is too big
7997   } else if ((tx_buffer_descriptor[s_rt1020_txno].control & BIT(15))) {
7998   MG_ERROR(("No free descriptors"));
7999     // printf("D0 %lx SR %lx\n", (long) s_txdesc[0][0], (long) ETH->DMASR);
8000     len = 0;  // All descriptors are busy, fail
8001   } else {
8002     memcpy(tx_data_buffer[s_rt1020_txno], buf, len);     // Copy data
8003     tx_buffer_descriptor[s_rt1020_txno].length = (uint16_t) len;  // Set data len
8004     tx_buffer_descriptor[s_rt1020_txno].control |= (uint16_t)(BIT(10)); // TC (transmit CRC)
8005     //  tx_buffer_descriptor[s_rt1020_txno].control &= (uint16_t)(BIT(14) | BIT(12)); // Own doesn't affect HW
8006     tx_buffer_descriptor[s_rt1020_txno].control |= (uint16_t)(BIT(15) | BIT(11)); // R+L (ready+last)
8007     ENET->TDAR = BIT(24); // Descriptor updated. Hand over to DMA.
8008     // INFO
8009     // Relevant Descriptor bits: 15(R)  Ready
8010     //                           11(L)  last in frame
8011     //                           10(TC) transmis CRC
8012     // __DSB(); // ARM errata 838869 Cortex-M4, M4F, M7, M7F: "store immediate overlapping
8013                 // exception" return might vector to incorrect interrupt.
8014     if (++s_rt1020_txno >= ENET_TXBD_NUM) s_rt1020_txno = 0;
8015   }
8016   (void) ifp;
8017   return len;
8018 }
8019
8020 // IRQ (RX)
8021 static uint32_t s_rt1020_rxno;
8022
8023 void ENET_IRQHandler(void) {
8024   ENET->EIMR = 0;           // Mask interrupts.
8025   uint32_t eir = ENET->EIR; // Read EIR
8026   ENET->EIR = 0xffffffff;   // Clear interrupts
8027
8028   if (eir & EIMR_RX_ERR) // Global mask used
8029   {
8030     if (rx_buffer_descriptor[s_rt1020_rxno].control & BIT(15)) {
8031       ENET->EIMR = EIMR_RX_ERR; // Enable interrupts
8032       return;  // Empty? -> exit.
8033     }
8034     // Read inframes
8035     else { // Frame received, loop
8036       for (uint32_t i = 0; i < 10; i++) {  // read as they arrive but not forever
8037         if (rx_buffer_descriptor[s_rt1020_rxno].control & BIT(15)) break;  // exit when done
8038         // Process if CRC OK and frame not truncated
8039         if (!(rx_buffer_descriptor[s_rt1020_rxno].control & (BIT(2) | BIT(0)))) {
8040           uint32_t len = (rx_buffer_descriptor[s_rt1020_rxno].length);
8041           mg_tcpip_qwrite(rx_buffer_descriptor[s_rt1020_rxno].buffer, len > 4 ? len - 4 : len, s_ifp);
8042         }
8043         rx_buffer_descriptor[s_rt1020_rxno].control |= BIT(15); // Inform DMA RX is empty
8044         if (++s_rt1020_rxno >= ENET_RXBD_NUM) s_rt1020_rxno = 0;
8045       }
8046     }
8047   }
8048   ENET->EIMR = EIMR_RX_ERR; // Enable interrupts
8049 }
8050
8051 // Up/down status
8052 static bool mg_tcpip_driver_imxrt1020_up(struct mg_tcpip_if *ifp) {
8053   uint32_t bsr = imxrt1020_eth_read_phy(IMXRT1020_PHY_ADDR, IMXRT1020_PHY_BSR);
8054   (void) ifp;
8055   return bsr & BIT(2) ? 1 : 0;
8056 }
8057
8058 // API
8059 struct mg_tcpip_driver mg_tcpip_driver_imxrt1020 = {
8060   mg_tcpip_driver_imxrt1020_init, mg_tcpip_driver_imxrt1020_tx, NULL,
8061   mg_tcpip_driver_imxrt1020_up};
8062
8063 #endif
8064
8065 #ifdef MG_ENABLE_LINES
8066 #line 1 "src/drivers/same54.c"
8067 #endif
8068
8069
8070 #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_SAME54) && \
8071     MG_ENABLE_DRIVER_SAME54
8072
8073 #include <sam.h>
8074
8075 #undef BIT
8076 #define BIT(x) ((uint32_t) 1 << (x))
8077 #define ETH_PKT_SIZE 1536  // Max frame size
8078 #define ETH_DESC_CNT 4     // Descriptors count
8079 #define ETH_DS 2           // Descriptor size (words)
8080
8081 static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE];
8082 static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE];
8083 static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS];  // RX descriptors
8084 static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS];  // TX descriptors
8085 static uint8_t s_txno;                           // Current TX descriptor
8086 static uint8_t s_rxno;                           // Current RX descriptor
8087
8088 static struct mg_tcpip_if *s_ifp;  // MIP interface
8089 enum { PHY_ADDR = 0, PHY_BCR = 0, PHY_BSR = 1 };
8090
8091 #define PHY_BCR_DUPLEX_MODE_Msk BIT(8)
8092 #define PHY_BCR_SPEED_Msk BIT(13)
8093 #define PHY_BSR_LINK_STATUS_Msk BIT(2)
8094
8095 static uint16_t eth_read_phy(uint8_t addr, uint8_t reg) {
8096   GMAC_REGS->GMAC_MAN = GMAC_MAN_CLTTO_Msk |
8097                         GMAC_MAN_OP(2) |  // Setting the read operation
8098                         GMAC_MAN_WTN(2) | GMAC_MAN_PHYA(addr) |  // PHY address
8099                         GMAC_MAN_REGA(reg);  // Setting the register
8100   while (!(GMAC_REGS->GMAC_NSR & GMAC_NSR_IDLE_Msk)) (void) 0;
8101   return GMAC_REGS->GMAC_MAN & GMAC_MAN_DATA_Msk;  // Getting the read value
8102 }
8103
8104 #if 0
8105 static void eth_write_phy(uint8_t addr, uint8_t reg, uint16_t val) {
8106   GMAC_REGS->GMAC_MAN = GMAC_MAN_CLTTO_Msk | GMAC_MAN_OP(1) |   // Setting the write operation
8107                         GMAC_MAN_WTN(2) | GMAC_MAN_PHYA(addr) | // PHY address
8108                         GMAC_MAN_REGA(reg) | GMAC_MAN_DATA(val);  // Setting the register
8109   while (!(GMAC_REGS->GMAC_NSR & GMAC_NSR_IDLE_Msk)); // Waiting until the write op is complete
8110 }
8111 #endif
8112
8113 int get_clock_rate(struct mg_tcpip_driver_same54_data *d) {
8114   if (d && d->mdc_cr >= 0 && d->mdc_cr <= 5) {
8115     return d->mdc_cr;
8116   } else {
8117     // get MCLK from GCLK_GENERATOR 0
8118     uint32_t div = 512;
8119     uint32_t mclk;
8120     if (!(GCLK_REGS->GCLK_GENCTRL[0] & GCLK_GENCTRL_DIVSEL_Msk)) {
8121       div = ((GCLK_REGS->GCLK_GENCTRL[0] & 0x00FF0000) >> 16);
8122       if (div == 0) div = 1;
8123     }
8124     switch (GCLK_REGS->GCLK_GENCTRL[0] & GCLK_GENCTRL_SRC_Msk) {
8125       case GCLK_GENCTRL_SRC_XOSC0_Val:
8126         mclk = 32000000UL; /* 32MHz */
8127         break;
8128       case GCLK_GENCTRL_SRC_XOSC1_Val:
8129         mclk = 32000000UL; /* 32MHz */
8130         break;
8131       case GCLK_GENCTRL_SRC_OSCULP32K_Val:
8132         mclk = 32000UL;
8133         break;
8134       case GCLK_GENCTRL_SRC_XOSC32K_Val:
8135         mclk = 32000UL;
8136         break;
8137       case GCLK_GENCTRL_SRC_DFLL_Val:
8138         mclk = 48000000UL; /* 48MHz */
8139         break;
8140       case GCLK_GENCTRL_SRC_DPLL0_Val:
8141         mclk = 200000000UL; /* 200MHz */
8142         break;
8143       case GCLK_GENCTRL_SRC_DPLL1_Val:
8144         mclk = 200000000UL; /* 200MHz */
8145         break;
8146       default:
8147         mclk = 200000000UL; /* 200MHz */
8148     }
8149
8150     mclk /= div;
8151     uint8_t crs[] = {0, 1, 2, 3, 4, 5};          // GMAC->NCFGR::CLK values
8152     uint8_t dividers[] = {8, 16, 32, 48, 64, 128};  // Respective CLK dividers
8153     for (int i = 0; i < 6; i++) {
8154       if (mclk / dividers[i] <= 2375000UL /* 2.5MHz - 5% */) {
8155         return crs[i];
8156       }
8157     }
8158
8159     return 5;
8160   }
8161 }
8162
8163 static bool mg_tcpip_driver_same54_init(struct mg_tcpip_if *ifp) {
8164   struct mg_tcpip_driver_same54_data *d =
8165       (struct mg_tcpip_driver_same54_data *) ifp->driver_data;
8166   s_ifp = ifp;
8167
8168   MCLK_REGS->MCLK_APBCMASK |= MCLK_APBCMASK_GMAC_Msk;
8169   MCLK_REGS->MCLK_AHBMASK |= MCLK_AHBMASK_GMAC_Msk;
8170   GMAC_REGS->GMAC_NCFGR = GMAC_NCFGR_CLK(get_clock_rate(d));  // Set MDC divider
8171   GMAC_REGS->GMAC_NCR = 0;                            // Disable RX & TX
8172   GMAC_REGS->GMAC_NCR |= GMAC_NCR_MPE_Msk;            // Enable MDC & MDIO
8173
8174   for (int i = 0; i < ETH_DESC_CNT; i++) {   // Init TX descriptors
8175     s_txdesc[i][0] = (uint32_t) s_txbuf[i];  // Point to data buffer
8176     s_txdesc[i][1] = BIT(31);                // OWN bit
8177   }
8178   s_txdesc[ETH_DESC_CNT - 1][1] |= BIT(30);  // Last tx descriptor - wrap
8179
8180   GMAC_REGS->GMAC_DCFGR = GMAC_DCFGR_DRBS(0x18);  // DMA recv buf 1536
8181   for (int i = 0; i < ETH_DESC_CNT; i++) {        // Init RX descriptors
8182     s_rxdesc[i][0] = (uint32_t) s_rxbuf[i];       // Address of the data buffer
8183     s_rxdesc[i][1] = 0;                           // Clear status
8184   }
8185   s_rxdesc[ETH_DESC_CNT - 1][0] |= BIT(1);  // Last rx descriptor - wrap
8186
8187   GMAC_REGS->GMAC_TBQB = (uint32_t) s_txdesc;  // about the descriptor addresses
8188   GMAC_REGS->GMAC_RBQB = (uint32_t) s_rxdesc;  // Let the controller know
8189
8190   GMAC_REGS->SA[0].GMAC_SAB =
8191       MG_U32(ifp->mac[3], ifp->mac[2], ifp->mac[1], ifp->mac[0]);
8192   GMAC_REGS->SA[0].GMAC_SAT = MG_U32(0, 0, ifp->mac[5], ifp->mac[4]);
8193
8194   GMAC_REGS->GMAC_UR &= ~GMAC_UR_MII_Msk;  // Disable MII, use RMII
8195   GMAC_REGS->GMAC_NCFGR |= GMAC_NCFGR_MAXFS_Msk | GMAC_NCFGR_MTIHEN_Msk |
8196                            GMAC_NCFGR_EFRHD_Msk | GMAC_NCFGR_CAF_Msk;
8197   GMAC_REGS->GMAC_TSR = GMAC_TSR_HRESP_Msk | GMAC_TSR_UND_Msk |
8198                         GMAC_TSR_TXCOMP_Msk | GMAC_TSR_TFC_Msk |
8199                         GMAC_TSR_TXGO_Msk | GMAC_TSR_RLE_Msk |
8200                         GMAC_TSR_COL_Msk | GMAC_TSR_UBR_Msk;
8201   GMAC_REGS->GMAC_RSR = GMAC_RSR_HNO_Msk | GMAC_RSR_RXOVR_Msk |
8202                         GMAC_RSR_REC_Msk | GMAC_RSR_BNA_Msk;
8203   GMAC_REGS->GMAC_IDR = ~0U;  // Disable interrupts, then enable required
8204   GMAC_REGS->GMAC_IER = GMAC_IER_HRESP_Msk | GMAC_IER_ROVR_Msk |
8205                         GMAC_IER_TCOMP_Msk | GMAC_IER_TFC_Msk |
8206                         GMAC_IER_RLEX_Msk | GMAC_IER_TUR_Msk |
8207                         GMAC_IER_RXUBR_Msk | GMAC_IER_RCOMP_Msk;
8208   GMAC_REGS->GMAC_NCR |= GMAC_NCR_TXEN_Msk | GMAC_NCR_RXEN_Msk;
8209   NVIC_EnableIRQ(GMAC_IRQn);
8210
8211   return true;
8212 }
8213
8214 static size_t mg_tcpip_driver_same54_tx(const void *buf, size_t len,
8215                                         struct mg_tcpip_if *ifp) {
8216   if (len > sizeof(s_txbuf[s_txno])) {
8217     MG_ERROR(("Frame too big, %ld", (long) len));
8218     len = 0;  // Frame is too big
8219   } else if ((s_txdesc[s_txno][1] & BIT(31)) == 0) {
8220     ifp->nerr++;
8221     MG_ERROR(("No free descriptors"));
8222     len = 0;  // All descriptors are busy, fail
8223   } else {
8224     uint32_t status = len | BIT(15);  // Frame length, last chunk
8225     if (s_txno == ETH_DESC_CNT - 1) status |= BIT(30);  // wrap
8226     memcpy(s_txbuf[s_txno], buf, len);                  // Copy data
8227     s_txdesc[s_txno][1] = status;
8228     if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
8229   }
8230   __DSB();  // Ensure descriptors have been written
8231   GMAC_REGS->GMAC_NCR |= GMAC_NCR_TSTART_Msk;  // Enable transmission
8232   return len;
8233 }
8234
8235 static bool mg_tcpip_driver_same54_up(struct mg_tcpip_if *ifp) {
8236   uint16_t bsr = eth_read_phy(PHY_ADDR, PHY_BSR);
8237   bool up = bsr & PHY_BSR_LINK_STATUS_Msk ? 1 : 0;
8238
8239   // If PHY is ready, update NCFGR accordingly
8240   if (ifp->state == MG_TCPIP_STATE_DOWN && up) {
8241     uint16_t bcr = eth_read_phy(PHY_ADDR, PHY_BCR);
8242     bool fd = bcr & PHY_BCR_DUPLEX_MODE_Msk ? 1 : 0;
8243     bool spd = bcr & PHY_BCR_SPEED_Msk ? 1 : 0;
8244     GMAC_REGS->GMAC_NCFGR |= GMAC_NCFGR_SPD(spd) | GMAC_NCFGR_FD(fd);
8245   }
8246
8247   return up;
8248 }
8249
8250 void GMAC_Handler(void);
8251 void GMAC_Handler(void) {
8252   uint32_t isr = GMAC_REGS->GMAC_ISR;
8253   uint32_t rsr = GMAC_REGS->GMAC_RSR;
8254   uint32_t tsr = GMAC_REGS->GMAC_TSR;
8255   if (isr & GMAC_ISR_RCOMP_Msk) {
8256     if (rsr & GMAC_ISR_RCOMP_Msk) {
8257       for (uint8_t i = 0; i < ETH_DESC_CNT; i++) {
8258         if ((s_rxdesc[s_rxno][0] & BIT(0)) == 0) break;
8259         size_t len = s_rxdesc[s_rxno][1] & (BIT(13) - 1);
8260         mg_tcpip_qwrite(s_rxbuf[s_rxno], len, s_ifp);
8261         s_rxdesc[s_rxno][0] &= ~BIT(0);  // Disown
8262         if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
8263       }
8264     }
8265   }
8266
8267   if ((tsr & (GMAC_TSR_HRESP_Msk | GMAC_TSR_UND_Msk | GMAC_TSR_TXCOMP_Msk |
8268               GMAC_TSR_TFC_Msk | GMAC_TSR_TXGO_Msk | GMAC_TSR_RLE_Msk |
8269               GMAC_TSR_COL_Msk | GMAC_TSR_UBR_Msk)) != 0) {
8270     // MG_INFO((" --> %#x %#x", s_txdesc[s_txno][1], tsr));
8271     if (!(s_txdesc[s_txno][1] & BIT(31))) s_txdesc[s_txno][1] |= BIT(31);
8272   }
8273
8274   GMAC_REGS->GMAC_RSR = rsr;
8275   GMAC_REGS->GMAC_TSR = tsr;
8276 }
8277
8278 struct mg_tcpip_driver mg_tcpip_driver_same54 = {
8279     mg_tcpip_driver_same54_init, mg_tcpip_driver_same54_tx, NULL,
8280     mg_tcpip_driver_same54_up};
8281 #endif
8282
8283 #ifdef MG_ENABLE_LINES
8284 #line 1 "src/drivers/stm32.c"
8285 #endif
8286
8287
8288 #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_STM32) && MG_ENABLE_DRIVER_STM32
8289 struct stm32_eth {
8290   volatile uint32_t MACCR, MACFFR, MACHTHR, MACHTLR, MACMIIAR, MACMIIDR, MACFCR,
8291       MACVLANTR, RESERVED0[2], MACRWUFFR, MACPMTCSR, RESERVED1, MACDBGR, MACSR,
8292       MACIMR, MACA0HR, MACA0LR, MACA1HR, MACA1LR, MACA2HR, MACA2LR, MACA3HR,
8293       MACA3LR, RESERVED2[40], MMCCR, MMCRIR, MMCTIR, MMCRIMR, MMCTIMR,
8294       RESERVED3[14], MMCTGFSCCR, MMCTGFMSCCR, RESERVED4[5], MMCTGFCR,
8295       RESERVED5[10], MMCRFCECR, MMCRFAECR, RESERVED6[10], MMCRGUFCR,
8296       RESERVED7[334], PTPTSCR, PTPSSIR, PTPTSHR, PTPTSLR, PTPTSHUR, PTPTSLUR,
8297       PTPTSAR, PTPTTHR, PTPTTLR, RESERVED8, PTPTSSR, PTPPPSCR, RESERVED9[564],
8298       DMABMR, DMATPDR, DMARPDR, DMARDLAR, DMATDLAR, DMASR, DMAOMR, DMAIER,
8299       DMAMFBOCR, DMARSWTR, RESERVED10[8], DMACHTDR, DMACHRDR, DMACHTBAR,
8300       DMACHRBAR;
8301 };
8302 #undef ETH
8303 #define ETH ((struct stm32_eth *) (uintptr_t) 0x40028000)
8304
8305 #undef DSB
8306 #if defined(__CC_ARM)
8307 #define DSB() __dsb(0xF)
8308 #elif defined(__ARMCC_VERSION)
8309 #define DSB() __builtin_arm_dsb(0xF)
8310 #elif defined(__GNUC__) && defined(__arm__) && defined(__thumb__)
8311 #define DSB() asm("DSB 0xF")
8312 #elif defined(__ICCARM__)
8313 #define DSB() __iar_builtin_DSB()
8314 #else
8315 #define DSB()
8316 #endif
8317
8318 #undef BIT
8319 #define BIT(x) ((uint32_t) 1 << (x))
8320 #define ETH_PKT_SIZE 1540  // Max frame size
8321 #define ETH_DESC_CNT 4     // Descriptors count
8322 #define ETH_DS 4           // Descriptor size (words)
8323
8324 static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS];      // RX descriptors
8325 static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS];      // TX descriptors
8326 static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE];  // RX ethernet buffers
8327 static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE];  // TX ethernet buffers
8328 static uint8_t s_txno;                               // Current TX descriptor
8329 static uint8_t s_rxno;                               // Current RX descriptor
8330
8331 static struct mg_tcpip_if *s_ifp;  // MIP interface
8332 enum { PHY_ADDR = 0, PHY_BCR = 0, PHY_BSR = 1, PHY_CSCR = 31 };
8333
8334 static uint32_t eth_read_phy(uint8_t addr, uint8_t reg) {
8335   ETH->MACMIIAR &= (7 << 2);
8336   ETH->MACMIIAR |= ((uint32_t) addr << 11) | ((uint32_t) reg << 6);
8337   ETH->MACMIIAR |= BIT(0);
8338   while (ETH->MACMIIAR & BIT(0)) (void) 0;
8339   return ETH->MACMIIDR;
8340 }
8341
8342 static void eth_write_phy(uint8_t addr, uint8_t reg, uint32_t val) {
8343   ETH->MACMIIDR = val;
8344   ETH->MACMIIAR &= (7 << 2);
8345   ETH->MACMIIAR |= ((uint32_t) addr << 11) | ((uint32_t) reg << 6) | BIT(1);
8346   ETH->MACMIIAR |= BIT(0);
8347   while (ETH->MACMIIAR & BIT(0)) (void) 0;
8348 }
8349
8350 static uint32_t get_hclk(void) {
8351   struct rcc {
8352     volatile uint32_t CR, PLLCFGR, CFGR;
8353   } *rcc = (struct rcc *) 0x40023800;
8354   uint32_t clk = 0, hsi = 16000000 /* 16 MHz */, hse = 8000000 /* 8MHz */;
8355
8356   if (rcc->CFGR & (1 << 2)) {
8357     clk = hse;
8358   } else if (rcc->CFGR & (1 << 3)) {
8359     uint32_t vco, m, n, p;
8360     m = (rcc->PLLCFGR & (0x3f << 0)) >> 0;
8361     n = (rcc->PLLCFGR & (0x1ff << 6)) >> 6;
8362     p = (((rcc->PLLCFGR & (3 << 16)) >> 16) + 1) * 2;
8363     clk = (rcc->PLLCFGR & (1 << 22)) ? hse : hsi;
8364     vco = (uint32_t) ((uint64_t) clk * n / m);
8365     clk = vco / p;
8366   } else {
8367     clk = hsi;
8368   }
8369   uint32_t hpre = (rcc->CFGR & (15 << 4)) >> 4;
8370   if (hpre < 8) return clk;
8371
8372   uint8_t ahbptab[8] = {1, 2, 3, 4, 6, 7, 8, 9};  // log2(div)
8373   return ((uint32_t) clk) >> ahbptab[hpre - 8];
8374 }
8375
8376 //  Guess CR from HCLK. MDC clock is generated from HCLK (AHB); as per 802.3,
8377 //  it must not exceed 2.5MHz As the AHB clock can be (and usually is) derived
8378 //  from the HSI (internal RC), and it can go above specs, the datasheets
8379 //  specify a range of frequencies and activate one of a series of dividers to
8380 //  keep the MDC clock safely below 2.5MHz. We guess a divider setting based on
8381 //  HCLK with a +5% drift. If the user uses a different clock from our
8382 //  defaults, needs to set the macros on top Valid for STM32F74xxx/75xxx
8383 //  (38.8.1) and STM32F42xxx/43xxx (33.8.1) (both 4.5% worst case drift)
8384 static int guess_mdc_cr(void) {
8385   uint8_t crs[] = {2, 3, 0, 1, 4, 5};          // ETH->MACMIIAR::CR values
8386   uint8_t div[] = {16, 26, 42, 62, 102, 124};  // Respective HCLK dividers
8387   uint32_t hclk = get_hclk();                  // Guess system HCLK
8388   int result = -1;                             // Invalid CR value
8389   if (hclk < 25000000) {
8390     MG_ERROR(("HCLK too low"));
8391   } else {
8392     for (int i = 0; i < 6; i++) {
8393       if (hclk / div[i] <= 2375000UL /* 2.5MHz - 5% */) {
8394         result = crs[i];
8395         break;
8396       }
8397     }
8398     if (result < 0) MG_ERROR(("HCLK too high"));
8399   }
8400   MG_DEBUG(("HCLK: %u, CR: %d", hclk, result));
8401   return result;
8402 }
8403
8404 static bool mg_tcpip_driver_stm32_init(struct mg_tcpip_if *ifp) {
8405   struct mg_tcpip_driver_stm32_data *d =
8406       (struct mg_tcpip_driver_stm32_data *) ifp->driver_data;
8407   s_ifp = ifp;
8408
8409   // Init RX descriptors
8410   for (int i = 0; i < ETH_DESC_CNT; i++) {
8411     s_rxdesc[i][0] = BIT(31);                            // Own
8412     s_rxdesc[i][1] = sizeof(s_rxbuf[i]) | BIT(14);       // 2nd address chained
8413     s_rxdesc[i][2] = (uint32_t) (uintptr_t) s_rxbuf[i];  // Point to data buffer
8414     s_rxdesc[i][3] =
8415         (uint32_t) (uintptr_t) s_rxdesc[(i + 1) % ETH_DESC_CNT];  // Chain
8416   }
8417
8418   // Init TX descriptors
8419   for (int i = 0; i < ETH_DESC_CNT; i++) {
8420     s_txdesc[i][2] = (uint32_t) (uintptr_t) s_txbuf[i];  // Buf pointer
8421     s_txdesc[i][3] =
8422         (uint32_t) (uintptr_t) s_txdesc[(i + 1) % ETH_DESC_CNT];  // Chain
8423   }
8424
8425   ETH->DMABMR |= BIT(0);                         // Software reset
8426   while ((ETH->DMABMR & BIT(0)) != 0) (void) 0;  // Wait until done
8427
8428   // Set MDC clock divider. If user told us the value, use it. Otherwise, guess
8429   int cr = (d == NULL || d->mdc_cr < 0) ? guess_mdc_cr() : d->mdc_cr;
8430   ETH->MACMIIAR = ((uint32_t) cr & 7) << 2;
8431
8432   // NOTE(cpq): we do not use extended descriptor bit 7, and do not use
8433   // hardware checksum. Therefore, descriptor size is 4, not 8
8434   // ETH->DMABMR = BIT(13) | BIT(16) | BIT(22) | BIT(23) | BIT(25);
8435   ETH->MACIMR = BIT(3) | BIT(9);  // Mask timestamp & PMT IT
8436   ETH->MACFCR = BIT(7);           // Disable zero quarta pause
8437   // ETH->MACFFR = BIT(31);                            // Receive all
8438   eth_write_phy(PHY_ADDR, PHY_BCR, BIT(15));           // Reset PHY
8439   eth_write_phy(PHY_ADDR, PHY_BCR, BIT(12));           // Set autonegotiation
8440   ETH->DMARDLAR = (uint32_t) (uintptr_t) s_rxdesc;     // RX descriptors
8441   ETH->DMATDLAR = (uint32_t) (uintptr_t) s_txdesc;     // RX descriptors
8442   ETH->DMAIER = BIT(6) | BIT(16);                      // RIE, NISE
8443   ETH->MACCR = BIT(2) | BIT(3) | BIT(11) | BIT(14);    // RE, TE, Duplex, Fast
8444   ETH->DMAOMR = BIT(1) | BIT(13) | BIT(21) | BIT(25);  // SR, ST, TSF, RSF
8445
8446   // MAC address filtering
8447   ETH->MACA0HR = ((uint32_t) ifp->mac[5] << 8U) | ifp->mac[4];
8448   ETH->MACA0LR = (uint32_t) (ifp->mac[3] << 24) |
8449                  ((uint32_t) ifp->mac[2] << 16) |
8450                  ((uint32_t) ifp->mac[1] << 8) | ifp->mac[0];
8451   return true;
8452 }
8453
8454 static size_t mg_tcpip_driver_stm32_tx(const void *buf, size_t len,
8455                                        struct mg_tcpip_if *ifp) {
8456   if (len > sizeof(s_txbuf[s_txno])) {
8457     MG_ERROR(("Frame too big, %ld", (long) len));
8458     len = 0;  // Frame is too big
8459   } else if ((s_txdesc[s_txno][0] & BIT(31))) {
8460     ifp->nerr++;
8461     MG_ERROR(("No free descriptors"));
8462     // printf("D0 %lx SR %lx\n", (long) s_txdesc[0][0], (long) ETH->DMASR);
8463     len = 0;  // All descriptors are busy, fail
8464   } else {
8465     memcpy(s_txbuf[s_txno], buf, len);     // Copy data
8466     s_txdesc[s_txno][1] = (uint32_t) len;  // Set data len
8467     s_txdesc[s_txno][0] = BIT(20) | BIT(28) | BIT(29);  // Chain,FS,LS
8468     s_txdesc[s_txno][0] |= BIT(31);  // Set OWN bit - let DMA take over
8469     if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
8470   }
8471   DSB();                         // ensure descriptors have been written
8472   ETH->DMASR = BIT(2) | BIT(5);  // Clear any prior TBUS/TUS
8473   ETH->DMATPDR = 0;              // and resume
8474   return len;
8475 }
8476
8477 static bool mg_tcpip_driver_stm32_up(struct mg_tcpip_if *ifp) {
8478   uint32_t bsr = eth_read_phy(PHY_ADDR, PHY_BSR);
8479   bool up = bsr & BIT(2) ? 1 : 0;
8480   if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) {  // link state just went up
8481     uint32_t scsr = eth_read_phy(PHY_ADDR, PHY_CSCR);
8482     uint32_t maccr = ETH->MACCR | BIT(14) | BIT(11);  // 100M, Full-duplex
8483     if ((scsr & BIT(3)) == 0) maccr &= ~BIT(14);      // 10M
8484     if ((scsr & BIT(4)) == 0) maccr &= ~BIT(11);      // Half-duplex
8485     ETH->MACCR = maccr;  // IRQ handler does not fiddle with this register
8486     MG_DEBUG(("Link is %uM %s-duplex", maccr & BIT(14) ? 100 : 10,
8487               maccr & BIT(11) ? "full" : "half"));
8488   }
8489   return up;
8490 }
8491
8492 void ETH_IRQHandler(void);
8493 void ETH_IRQHandler(void) {
8494   if (ETH->DMASR & BIT(6)) {             // Frame received, loop
8495     ETH->DMASR = BIT(16) | BIT(6);       // Clear flag
8496     for (uint32_t i = 0; i < 10; i++) {  // read as they arrive but not forever
8497       if (s_rxdesc[s_rxno][0] & BIT(31)) break;  // exit when done
8498       if (((s_rxdesc[s_rxno][0] & (BIT(8) | BIT(9))) == (BIT(8) | BIT(9))) &&
8499           !(s_rxdesc[s_rxno][0] & BIT(15))) {  // skip partial/errored frames
8500         uint32_t len = ((s_rxdesc[s_rxno][0] >> 16) & (BIT(14) - 1));
8501         //  printf("%lx %lu %lx %.8lx\n", s_rxno, len, s_rxdesc[s_rxno][0],
8502         //  ETH->DMASR);
8503         mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
8504       }
8505       s_rxdesc[s_rxno][0] = BIT(31);
8506       if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
8507     }
8508   }
8509   ETH->DMASR = BIT(7);  // Clear possible RBUS while processing
8510   ETH->DMARPDR = 0;     // and resume RX
8511 }
8512
8513 struct mg_tcpip_driver mg_tcpip_driver_stm32 = {mg_tcpip_driver_stm32_init,
8514                                                 mg_tcpip_driver_stm32_tx, NULL,
8515                                                 mg_tcpip_driver_stm32_up};
8516 #endif
8517
8518 #ifdef MG_ENABLE_LINES
8519 #line 1 "src/drivers/stm32h.c"
8520 #endif
8521
8522
8523 #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_STM32H) && \
8524     MG_ENABLE_DRIVER_STM32H
8525 struct stm32h_eth {
8526   volatile uint32_t MACCR, MACECR, MACPFR, MACWTR, MACHT0R, MACHT1R,
8527       RESERVED1[14], MACVTR, RESERVED2, MACVHTR, RESERVED3, MACVIR, MACIVIR,
8528       RESERVED4[2], MACTFCR, RESERVED5[7], MACRFCR, RESERVED6[7], MACISR,
8529       MACIER, MACRXTXSR, RESERVED7, MACPCSR, MACRWKPFR, RESERVED8[2], MACLCSR,
8530       MACLTCR, MACLETR, MAC1USTCR, RESERVED9[12], MACVR, MACDR, RESERVED10,
8531       MACHWF0R, MACHWF1R, MACHWF2R, RESERVED11[54], MACMDIOAR, MACMDIODR,
8532       RESERVED12[2], MACARPAR, RESERVED13[59], MACA0HR, MACA0LR, MACA1HR,
8533       MACA1LR, MACA2HR, MACA2LR, MACA3HR, MACA3LR, RESERVED14[248], MMCCR,
8534       MMCRIR, MMCTIR, MMCRIMR, MMCTIMR, RESERVED15[14], MMCTSCGPR, MMCTMCGPR,
8535       RESERVED16[5], MMCTPCGR, RESERVED17[10], MMCRCRCEPR, MMCRAEPR,
8536       RESERVED18[10], MMCRUPGR, RESERVED19[9], MMCTLPIMSTR, MMCTLPITCR,
8537       MMCRLPIMSTR, MMCRLPITCR, RESERVED20[65], MACL3L4C0R, MACL4A0R,
8538       RESERVED21[2], MACL3A0R0R, MACL3A1R0R, MACL3A2R0R, MACL3A3R0R,
8539       RESERVED22[4], MACL3L4C1R, MACL4A1R, RESERVED23[2], MACL3A0R1R,
8540       MACL3A1R1R, MACL3A2R1R, MACL3A3R1R, RESERVED24[108], MACTSCR, MACSSIR,
8541       MACSTSR, MACSTNR, MACSTSUR, MACSTNUR, MACTSAR, RESERVED25, MACTSSR,
8542       RESERVED26[3], MACTTSSNR, MACTTSSSR, RESERVED27[2], MACACR, RESERVED28,
8543       MACATSNR, MACATSSR, MACTSIACR, MACTSEACR, MACTSICNR, MACTSECNR,
8544       RESERVED29[4], MACPPSCR, RESERVED30[3], MACPPSTTSR, MACPPSTTNR, MACPPSIR,
8545       MACPPSWR, RESERVED31[12], MACPOCR, MACSPI0R, MACSPI1R, MACSPI2R, MACLMIR,
8546       RESERVED32[11], MTLOMR, RESERVED33[7], MTLISR, RESERVED34[55], MTLTQOMR,
8547       MTLTQUR, MTLTQDR, RESERVED35[8], MTLQICSR, MTLRQOMR, MTLRQMPOCR, MTLRQDR,
8548       RESERVED36[177], DMAMR, DMASBMR, DMAISR, DMADSR, RESERVED37[60], DMACCR,
8549       DMACTCR, DMACRCR, RESERVED38[2], DMACTDLAR, RESERVED39, DMACRDLAR,
8550       DMACTDTPR, RESERVED40, DMACRDTPR, DMACTDRLR, DMACRDRLR, DMACIER,
8551       DMACRIWTR, DMACSFCSR, RESERVED41, DMACCATDR, RESERVED42, DMACCARDR,
8552       RESERVED43, DMACCATBR, RESERVED44, DMACCARBR, DMACSR, RESERVED45[2],
8553       DMACMFCR;
8554 };
8555 #undef ETH
8556 #define ETH \
8557   ((struct stm32h_eth *) (uintptr_t) (0x40000000UL + 0x00020000UL + 0x8000UL))
8558
8559 #undef BIT
8560 #define BIT(x) ((uint32_t) 1 << (x))
8561 #define ETH_PKT_SIZE 1540  // Max frame size
8562 #define ETH_DESC_CNT 4     // Descriptors count
8563 #define ETH_DS 4           // Descriptor size (words)
8564
8565 static volatile uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS];  // RX descriptors
8566 static volatile uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS];  // TX descriptors
8567 static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE];       // RX ethernet buffers
8568 static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE];       // TX ethernet buffers
8569 static struct mg_tcpip_if *s_ifp;                         // MIP interface
8570 enum {
8571   PHY_ADDR = 0,
8572   PHY_BCR = 0,
8573   PHY_BSR = 1,
8574   PHY_CSCR = 31
8575 };  // PHY constants
8576
8577 static uint32_t eth_read_phy(uint8_t addr, uint8_t reg) {
8578   ETH->MACMDIOAR &= (0xF << 8);
8579   ETH->MACMDIOAR |= ((uint32_t) addr << 21) | ((uint32_t) reg << 16) | 3 << 2;
8580   ETH->MACMDIOAR |= BIT(0);
8581   while (ETH->MACMDIOAR & BIT(0)) (void) 0;
8582   return ETH->MACMDIODR;
8583 }
8584
8585 static void eth_write_phy(uint8_t addr, uint8_t reg, uint32_t val) {
8586   ETH->MACMDIODR = val;
8587   ETH->MACMDIOAR &= (0xF << 8);
8588   ETH->MACMDIOAR |= ((uint32_t) addr << 21) | ((uint32_t) reg << 16) | 1 << 2;
8589   ETH->MACMDIOAR |= BIT(0);
8590   while (ETH->MACMDIOAR & BIT(0)) (void) 0;
8591 }
8592
8593 static uint32_t get_hclk(void) {
8594   struct rcc {
8595     volatile uint32_t CR, HSICFGR, CRRCR, CSICFGR, CFGR, RESERVED1, D1CFGR,
8596         D2CFGR, D3CFGR, RESERVED2, PLLCKSELR, PLLCFGR, PLL1DIVR, PLL1FRACR,
8597         PLL2DIVR, PLL2FRACR, PLL3DIVR, PLL3FRACR, RESERVED3, D1CCIPR, D2CCIP1R,
8598         D2CCIP2R, D3CCIPR, RESERVED4, CIER, CIFR, CICR, RESERVED5, BDCR, CSR,
8599         RESERVED6, AHB3RSTR, AHB1RSTR, AHB2RSTR, AHB4RSTR, APB3RSTR, APB1LRSTR,
8600         APB1HRSTR, APB2RSTR, APB4RSTR, GCR, RESERVED8, D3AMR, RESERVED11[9],
8601         RSR, AHB3ENR, AHB1ENR, AHB2ENR, AHB4ENR, APB3ENR, APB1LENR, APB1HENR,
8602         APB2ENR, APB4ENR, RESERVED12, AHB3LPENR, AHB1LPENR, AHB2LPENR,
8603         AHB4LPENR, APB3LPENR, APB1LLPENR, APB1HLPENR, APB2LPENR, APB4LPENR,
8604         RESERVED13[4];
8605   } *rcc = ((struct rcc *) (0x40000000 + 0x18020000 + 0x4400));
8606   uint32_t clk = 0, hsi = 64000000 /* 64 MHz */, hse = 8000000 /* 8MHz */,
8607            csi = 4000000 /* 4MHz */;
8608   unsigned int sel = (rcc->CFGR & (7 << 3)) >> 3;
8609
8610   if (sel == 1) {
8611     clk = csi;
8612   } else if (sel == 2) {
8613     clk = hse;
8614   } else if (sel == 3) {
8615     uint32_t vco, m, n, p;
8616     unsigned int src = (rcc->PLLCKSELR & (3 << 0)) >> 0;
8617     m = ((rcc->PLLCKSELR & (0x3F << 4)) >> 4);
8618     n = ((rcc->PLL1DIVR & (0x1FF << 0)) >> 0) + 1 +
8619         ((rcc->PLLCFGR & BIT(0)) ? 1 : 0);  // round-up in fractional mode
8620     p = ((rcc->PLL1DIVR & (0x7F << 9)) >> 9) + 1;
8621     if (src == 1) {
8622       clk = csi;
8623     } else if (src == 2) {
8624       clk = hse;
8625     } else {
8626       clk = hsi;
8627       clk >>= ((rcc->CR & 3) >> 3);
8628     }
8629     vco = (uint32_t) ((uint64_t) clk * n / m);
8630     clk = vco / p;
8631   } else {
8632     clk = hsi;
8633     clk >>= ((rcc->CR & 3) >> 3);
8634   }
8635   const uint8_t cptab[12] = {1, 2, 3, 4, 6, 7, 8, 9};  // log2(div)
8636   uint32_t d1cpre = (rcc->D1CFGR & (0x0F << 8)) >> 8;
8637   if (d1cpre >= 8) clk >>= cptab[d1cpre - 8];
8638   MG_DEBUG(("D1 CLK: %u", clk));
8639   uint32_t hpre = (rcc->D1CFGR & (0x0F << 0)) >> 0;
8640   if (hpre < 8) return clk;
8641   return ((uint32_t) clk) >> cptab[hpre - 8];
8642 }
8643
8644 //  Guess CR from AHB1 clock. MDC clock is generated from the ETH peripheral
8645 //  clock (AHB1); as per 802.3, it must not exceed 2. As the AHB clock can
8646 //  be derived from HSI or CSI (internal RC) clocks, and those can go above
8647 //  specs, the datasheets specify a range of frequencies and activate one of a
8648 //  series of dividers to keep the MDC clock safely below 2.5MHz. We guess a
8649 //  divider setting based on HCLK with some drift. If the user uses a different
8650 //  clock from our defaults, needs to set the macros on top. Valid for
8651 //  STM32H74xxx/75xxx (58.11.4)(4.5% worst case drift)(CSI clock has a 7.5 %
8652 //  worst case drift @ max temp)
8653 static int guess_mdc_cr(void) {
8654   const uint8_t crs[] = {2, 3, 0, 1, 4, 5};  // ETH->MACMDIOAR::CR values
8655   const uint8_t div[] = {16, 26, 42, 62, 102, 124};  // Respective HCLK dividers
8656   uint32_t hclk = get_hclk();                        // Guess system HCLK
8657   int result = -1;                                   // Invalid CR value
8658   for (int i = 0; i < 6; i++) {
8659     if (hclk / div[i] <= 2375000UL /* 2.5MHz - 5% */) {
8660       result = crs[i];
8661       break;
8662     }
8663   }
8664   if (result < 0) MG_ERROR(("HCLK too high"));
8665   MG_DEBUG(("HCLK: %u, CR: %d", hclk, result));
8666   return result;
8667 }
8668
8669 static bool mg_tcpip_driver_stm32h_init(struct mg_tcpip_if *ifp) {
8670   struct mg_tcpip_driver_stm32h_data *d =
8671       (struct mg_tcpip_driver_stm32h_data *) ifp->driver_data;
8672   s_ifp = ifp;
8673
8674   // Init RX descriptors
8675   for (int i = 0; i < ETH_DESC_CNT; i++) {
8676     s_rxdesc[i][0] = (uint32_t) (uintptr_t) s_rxbuf[i];  // Point to data buffer
8677     s_rxdesc[i][3] = BIT(31) | BIT(30) | BIT(24);        // OWN, IOC, BUF1V
8678   }
8679
8680   // Init TX descriptors
8681   for (int i = 0; i < ETH_DESC_CNT; i++) {
8682     s_txdesc[i][0] = (uint32_t) (uintptr_t) s_txbuf[i];  // Buf pointer
8683   }
8684
8685   ETH->DMAMR |= BIT(0);                         // Software reset
8686   while ((ETH->DMAMR & BIT(0)) != 0) (void) 0;  // Wait until done
8687
8688   // Set MDC clock divider. If user told us the value, use it. Otherwise, guess
8689   int cr = (d == NULL || d->mdc_cr < 0) ? guess_mdc_cr() : d->mdc_cr;
8690   ETH->MACMDIOAR = ((uint32_t) cr & 0xF) << 8;
8691
8692   // NOTE(scaprile): We do not use timing facilities so the DMA engine does not
8693   // re-write buffer address
8694   ETH->DMAMR = 0 << 16;     // use interrupt mode 0 (58.8.1) (reset value)
8695   ETH->DMASBMR |= BIT(12);  // AAL NOTE(scaprile): is this actually needed
8696   ETH->MACIER = 0;        // Do not enable additional irq sources (reset value)
8697   ETH->MACTFCR = BIT(7);  // Disable zero-quanta pause
8698   // ETH->MACPFR = BIT(31);  // Receive all
8699   eth_write_phy(PHY_ADDR, PHY_BCR, BIT(15));  // Reset PHY
8700   eth_write_phy(PHY_ADDR, PHY_BCR, BIT(12));  // Set autonegotiation
8701   ETH->DMACRDLAR =
8702       (uint32_t) (uintptr_t) s_rxdesc;  // RX descriptors start address
8703   ETH->DMACRDRLR = ETH_DESC_CNT - 1;    // ring length
8704   ETH->DMACRDTPR =
8705       (uint32_t) (uintptr_t) &s_rxdesc[ETH_DESC_CNT -
8706                                        1];  // last valid descriptor address
8707   ETH->DMACTDLAR =
8708       (uint32_t) (uintptr_t) s_txdesc;  // TX descriptors start address
8709   ETH->DMACTDRLR = ETH_DESC_CNT - 1;    // ring length
8710   ETH->DMACTDTPR =
8711       (uint32_t) (uintptr_t) s_txdesc;  // first available descriptor address
8712   ETH->DMACCR = 0;  // DSL = 0 (contiguous descriptor table) (reset value)
8713   ETH->DMACIER = BIT(6) | BIT(15);  // RIE, NIE
8714   ETH->MACCR = BIT(0) | BIT(1) | BIT(13) | BIT(14) |
8715                BIT(15);     // RE, TE, Duplex, Fast, Reserved
8716   ETH->MTLTQOMR |= BIT(1);  // TSF
8717   ETH->MTLRQOMR |= BIT(5);  // RSF
8718   ETH->DMACTCR |= BIT(0);   // ST
8719   ETH->DMACRCR |= BIT(0);   // SR
8720
8721   // MAC address filtering
8722   ETH->MACA0HR = ((uint32_t) ifp->mac[5] << 8U) | ifp->mac[4];
8723   ETH->MACA0LR = (uint32_t) (ifp->mac[3] << 24) |
8724                  ((uint32_t) ifp->mac[2] << 16) |
8725                  ((uint32_t) ifp->mac[1] << 8) | ifp->mac[0];
8726   return true;
8727 }
8728
8729 static uint32_t s_txno;
8730 static size_t mg_tcpip_driver_stm32h_tx(const void *buf, size_t len,
8731                                         struct mg_tcpip_if *ifp) {
8732   if (len > sizeof(s_txbuf[s_txno])) {
8733     MG_ERROR(("Frame too big, %ld", (long) len));
8734     len = 0;  // Frame is too big
8735   } else if ((s_txdesc[s_txno][3] & BIT(31))) {
8736     MG_ERROR(("No free descriptors: %u %08X %08X %08X", s_txno,
8737               s_txdesc[s_txno][3], ETH->DMACSR, ETH->DMACTCR));
8738     for (int i = 0; i < ETH_DESC_CNT; i++) MG_ERROR(("%08X", s_txdesc[i][3]));
8739     len = 0;  // All descriptors are busy, fail
8740   } else {
8741     memcpy(s_txbuf[s_txno], buf, len);        // Copy data
8742     s_txdesc[s_txno][2] = (uint32_t) len;     // Set data len
8743     s_txdesc[s_txno][3] = BIT(28) | BIT(29);  // FD, LD
8744     s_txdesc[s_txno][3] |= BIT(31);           // Set OWN bit - let DMA take over
8745     if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
8746   }
8747   ETH->DMACSR |= BIT(2) | BIT(1);  // Clear any prior TBU, TPS
8748   ETH->DMACTDTPR = (uint32_t) (uintptr_t) &s_txdesc[s_txno];  // and resume
8749   return len;
8750   (void) ifp;
8751 }
8752
8753 static bool mg_tcpip_driver_stm32h_up(struct mg_tcpip_if *ifp) {
8754   uint32_t bsr = eth_read_phy(PHY_ADDR, PHY_BSR);
8755   bool up = bsr & BIT(2) ? 1 : 0;
8756   if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) {  // link state just went up
8757     uint32_t scsr = eth_read_phy(PHY_ADDR, PHY_CSCR);
8758     uint32_t maccr = ETH->MACCR | BIT(14) | BIT(13);  // 100M, Full-duplex
8759     if ((scsr & BIT(3)) == 0) maccr &= ~BIT(14);      // 10M
8760     if ((scsr & BIT(4)) == 0) maccr &= ~BIT(13);      // Half-duplex
8761     ETH->MACCR = maccr;  // IRQ handler does not fiddle with this register
8762     MG_DEBUG(("Link is %uM %s-duplex", maccr & BIT(14) ? 100 : 10,
8763               maccr & BIT(13) ? "full" : "half"));
8764   }
8765   return up;
8766 }
8767
8768 void ETH_IRQHandler(void);
8769 static uint32_t s_rxno;
8770 void ETH_IRQHandler(void) {
8771   if (ETH->DMACSR & BIT(6)) {            // Frame received, loop
8772     ETH->DMACSR = BIT(15) | BIT(6);      // Clear flag
8773     for (uint32_t i = 0; i < 10; i++) {  // read as they arrive but not forever
8774       if (s_rxdesc[s_rxno][3] & BIT(31)) break;  // exit when done
8775       if (((s_rxdesc[s_rxno][3] & (BIT(28) | BIT(29))) ==
8776            (BIT(28) | BIT(29))) &&
8777           !(s_rxdesc[s_rxno][3] & BIT(15))) {  // skip partial/errored frames
8778         uint32_t len = s_rxdesc[s_rxno][3] & (BIT(15) - 1);
8779         // MG_DEBUG(("%lx %lu %lx %08lx", s_rxno, len, s_rxdesc[s_rxno][3],
8780         // ETH->DMACSR));
8781         mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
8782       }
8783       s_rxdesc[s_rxno][3] = BIT(31) | BIT(30) | BIT(24);  // OWN, IOC, BUF1V
8784       if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
8785     }
8786   }
8787   ETH->DMACSR = BIT(7) | BIT(8);  // Clear possible RBU RPS while processing
8788   ETH->DMACRDTPR =
8789       (uint32_t) (uintptr_t) &s_rxdesc[ETH_DESC_CNT - 1];  // and resume RX
8790 }
8791
8792 struct mg_tcpip_driver mg_tcpip_driver_stm32h = {
8793     mg_tcpip_driver_stm32h_init, mg_tcpip_driver_stm32h_tx, NULL,
8794     mg_tcpip_driver_stm32h_up};
8795 #endif
8796
8797 #ifdef MG_ENABLE_LINES
8798 #line 1 "src/drivers/tm4c.c"
8799 #endif
8800
8801
8802 #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_TM4C) && MG_ENABLE_DRIVER_TM4C
8803 struct tm4c_emac {
8804   volatile uint32_t EMACCFG, EMACFRAMEFLTR, EMACHASHTBLH, EMACHASHTBLL,
8805       EMACMIIADDR, EMACMIIDATA, EMACFLOWCTL, EMACVLANTG, RESERVED0, EMACSTATUS,
8806       EMACRWUFF, EMACPMTCTLSTAT, RESERVED1[2], EMACRIS, EMACIM, EMACADDR0H,
8807       EMACADDR0L, EMACADDR1H, EMACADDR1L, EMACADDR2H, EMACADDR2L, EMACADDR3H,
8808       EMACADDR3L, RESERVED2[31], EMACWDOGTO, RESERVED3[8], EMACMMCCTRL,
8809       EMACMMCRXRIS, EMACMMCTXRIS, EMACMMCRXIM, EMACMMCTXIM, RESERVED4,
8810       EMACTXCNTGB, RESERVED5[12], EMACTXCNTSCOL, EMACTXCNTMCOL, RESERVED6[4],
8811       EMACTXOCTCNTG, RESERVED7[6], EMACRXCNTGB, RESERVED8[4], EMACRXCNTCRCERR,
8812       EMACRXCNTALGNERR, RESERVED9[10], EMACRXCNTGUNI, RESERVED10[239],
8813       EMACVLNINCREP, EMACVLANHASH, RESERVED11[93], EMACTIMSTCTRL, EMACSUBSECINC,
8814       EMACTIMSEC, EMACTIMNANO, EMACTIMSECU, EMACTIMNANOU, EMACTIMADD,
8815       EMACTARGSEC, EMACTARGNANO, EMACHWORDSEC, EMACTIMSTAT, EMACPPSCTRL,
8816       RESERVED12[12], EMACPPS0INTVL, EMACPPS0WIDTH, RESERVED13[294],
8817       EMACDMABUSMOD, EMACTXPOLLD, EMACRXPOLLD, EMACRXDLADDR, EMACTXDLADDR,
8818       EMACDMARIS, EMACDMAOPMODE, EMACDMAIM, EMACMFBOC, EMACRXINTWDT,
8819       RESERVED14[8], EMACHOSTXDESC, EMACHOSRXDESC, EMACHOSTXBA, EMACHOSRXBA,
8820       RESERVED15[218], EMACPP, EMACPC, EMACCC, RESERVED16, EMACEPHYRIS,
8821       EMACEPHYIM, EMACEPHYIMSC;
8822 };
8823 #undef EMAC
8824 #define EMAC ((struct tm4c_emac *) (uintptr_t) 0x400EC000)
8825
8826 #undef BIT
8827 #define BIT(x) ((uint32_t) 1 << (x))
8828 #define ETH_PKT_SIZE 1540  // Max frame size
8829 #define ETH_DESC_CNT 4     // Descriptors count
8830 #define ETH_DS 4           // Descriptor size (words)
8831
8832 static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS];      // RX descriptors
8833 static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS];      // TX descriptors
8834 static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE];  // RX ethernet buffers
8835 static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE];  // TX ethernet buffers
8836 static struct mg_tcpip_if *s_ifp;                    // MIP interface
8837 enum {
8838   EPHY_ADDR = 0,
8839   EPHYBMCR = 0,
8840   EPHYBMSR = 1,
8841   EPHYSTS = 16
8842 };  // PHY constants
8843
8844 static inline void tm4cspin(volatile uint32_t count) {
8845   while (count--) (void) 0;
8846 }
8847
8848 static uint32_t emac_read_phy(uint8_t addr, uint8_t reg) {
8849   EMAC->EMACMIIADDR &= (0xf << 2);
8850   EMAC->EMACMIIADDR |= ((uint32_t) addr << 11) | ((uint32_t) reg << 6);
8851   EMAC->EMACMIIADDR |= BIT(0);
8852   while (EMAC->EMACMIIADDR & BIT(0)) tm4cspin(1);
8853   return EMAC->EMACMIIDATA;
8854 }
8855
8856 static void emac_write_phy(uint8_t addr, uint8_t reg, uint32_t val) {
8857   EMAC->EMACMIIDATA = val;
8858   EMAC->EMACMIIADDR &= (0xf << 2);
8859   EMAC->EMACMIIADDR |= ((uint32_t) addr << 11) | ((uint32_t) reg << 6) | BIT(1);
8860   EMAC->EMACMIIADDR |= BIT(0);
8861   while (EMAC->EMACMIIADDR & BIT(0)) tm4cspin(1);
8862 }
8863
8864 static uint32_t get_sysclk(void) {
8865   struct sysctl {
8866     volatile uint32_t DONTCARE0[44], RSCLKCFG, DONTCARE1[43], PLLFREQ0,
8867         PLLFREQ1;
8868   } *sysctl = (struct sysctl *) 0x400FE000;
8869   uint32_t clk = 0, piosc = 16000000 /* 16 MHz */, mosc = 25000000 /* 25MHz */;
8870   if (sysctl->RSCLKCFG & (1 << 28)) {  // USEPLL
8871     uint32_t fin, vco, mdiv, n, q, psysdiv;
8872     uint32_t pllsrc = (sysctl->RSCLKCFG & (0xf << 24)) >> 24;
8873     if (pllsrc == 0) {
8874       clk = piosc;
8875     } else if (pllsrc == 3) {
8876       clk = mosc;
8877     } else {
8878       MG_ERROR(("Unsupported clock source"));
8879     }
8880     q = (sysctl->PLLFREQ1 & (0x1f << 8)) >> 8;
8881     n = (sysctl->PLLFREQ1 & (0x1f << 0)) >> 0;
8882     fin = clk / ((q + 1) * (n + 1));
8883     mdiv = (sysctl->PLLFREQ0 & (0x3ff << 0)) >>
8884            0;  // mint + (mfrac / 1024); MFRAC not supported
8885     psysdiv = (sysctl->RSCLKCFG & (0x3f << 0)) >> 0;
8886     vco = (uint32_t) ((uint64_t) fin * mdiv);
8887     return vco / (psysdiv + 1);
8888   }
8889   uint32_t oscsrc = (sysctl->RSCLKCFG & (0xf << 20)) >> 20;
8890   if (oscsrc == 0) {
8891     clk = piosc;
8892   } else if (oscsrc == 3) {
8893     clk = mosc;
8894   } else {
8895     MG_ERROR(("Unsupported clock source"));
8896   }
8897   uint32_t osysdiv = (sysctl->RSCLKCFG & (0xf << 16)) >> 16;
8898   return clk / (osysdiv + 1);
8899 }
8900
8901 //  Guess CR from SYSCLK. MDC clock is generated from SYSCLK (AHB); as per
8902 //  802.3, it must not exceed 2.5MHz (also 20.4.2.6) As the AHB clock can be
8903 //  derived from the PIOSC (internal RC), and it can go above  specs, the
8904 //  datasheets specify a range of frequencies and activate one of a series of
8905 //  dividers to keep the MDC clock safely below 2.5MHz. We guess a divider
8906 //  setting based on SYSCLK with a +5% drift. If the user uses a different clock
8907 //  from our defaults, needs to set the macros on top Valid for TM4C129x (20.7)
8908 //  (4.5% worst case drift)
8909 // The PHY receives the main oscillator (MOSC) (20.3.1)
8910 static int guess_mdc_cr(void) {
8911   uint8_t crs[] = {2, 3, 0, 1};      // EMAC->MACMIIAR::CR values
8912   uint8_t div[] = {16, 26, 42, 62};  // Respective HCLK dividers
8913   uint32_t sysclk = get_sysclk();    // Guess system SYSCLK
8914   int result = -1;                   // Invalid CR value
8915   if (sysclk < 25000000) {
8916     MG_ERROR(("SYSCLK too low"));
8917   } else {
8918     for (int i = 0; i < 4; i++) {
8919       if (sysclk / div[i] <= 2375000UL /* 2.5MHz - 5% */) {
8920         result = crs[i];
8921         break;
8922       }
8923     }
8924     if (result < 0) MG_ERROR(("SYSCLK too high"));
8925   }
8926   MG_DEBUG(("SYSCLK: %u, CR: %d", sysclk, result));
8927   return result;
8928 }
8929
8930 static bool mg_tcpip_driver_tm4c_init(struct mg_tcpip_if *ifp) {
8931   struct mg_tcpip_driver_tm4c_data *d =
8932       (struct mg_tcpip_driver_tm4c_data *) ifp->driver_data;
8933   s_ifp = ifp;
8934
8935   // Init RX descriptors
8936   for (int i = 0; i < ETH_DESC_CNT; i++) {
8937     s_rxdesc[i][0] = BIT(31);                            // Own
8938     s_rxdesc[i][1] = sizeof(s_rxbuf[i]) | BIT(14);       // 2nd address chained
8939     s_rxdesc[i][2] = (uint32_t) (uintptr_t) s_rxbuf[i];  // Point to data buffer
8940     s_rxdesc[i][3] =
8941         (uint32_t) (uintptr_t) s_rxdesc[(i + 1) % ETH_DESC_CNT];  // Chain
8942     // MG_DEBUG(("%d %p", i, s_rxdesc[i]));
8943   }
8944
8945   // Init TX descriptors
8946   for (int i = 0; i < ETH_DESC_CNT; i++) {
8947     s_txdesc[i][2] = (uint32_t) (uintptr_t) s_txbuf[i];  // Buf pointer
8948     s_txdesc[i][3] =
8949         (uint32_t) (uintptr_t) s_txdesc[(i + 1) % ETH_DESC_CNT];  // Chain
8950   }
8951
8952   EMAC->EMACDMABUSMOD |= BIT(0);                            // Software reset
8953   while ((EMAC->EMACDMABUSMOD & BIT(0)) != 0) tm4cspin(1);  // Wait until done
8954
8955   // Set MDC clock divider. If user told us the value, use it. Otherwise, guess
8956   int cr = (d == NULL || d->mdc_cr < 0) ? guess_mdc_cr() : d->mdc_cr;
8957   EMAC->EMACMIIADDR = ((uint32_t) cr & 0xf) << 2;
8958
8959   // NOTE(cpq): we do not use extended descriptor bit 7, and do not use
8960   // hardware checksum. Therefore, descriptor size is 4, not 8
8961   // EMAC->EMACDMABUSMOD = BIT(13) | BIT(16) | BIT(22) | BIT(23) | BIT(25);
8962   EMAC->EMACIM = BIT(3) | BIT(9);  // Mask timestamp & PMT IT
8963   EMAC->EMACFLOWCTL = BIT(7);      // Disable zero-quanta pause
8964   // EMAC->EMACFRAMEFLTR = BIT(31);   // Receive all
8965   // EMAC->EMACPC defaults to internal PHY (EPHY) in MMI mode
8966   emac_write_phy(EPHY_ADDR, EPHYBMCR, BIT(15));  // Reset internal PHY (EPHY)
8967   emac_write_phy(EPHY_ADDR, EPHYBMCR, BIT(12));  // Set autonegotiation
8968   EMAC->EMACRXDLADDR = (uint32_t) (uintptr_t) s_rxdesc;  // RX descriptors
8969   EMAC->EMACTXDLADDR = (uint32_t) (uintptr_t) s_txdesc;  // TX descriptors
8970   EMAC->EMACDMAIM = BIT(6) | BIT(16);                    // RIE, NIE
8971   EMAC->EMACCFG = BIT(2) | BIT(3) | BIT(11) | BIT(14);   // RE, TE, Duplex, Fast
8972   EMAC->EMACDMAOPMODE =
8973       BIT(1) | BIT(13) | BIT(21) | BIT(25);  // SR, ST, TSF, RSF
8974   EMAC->EMACADDR0H = ((uint32_t) ifp->mac[5] << 8U) | ifp->mac[4];
8975   EMAC->EMACADDR0L = (uint32_t) (ifp->mac[3] << 24) |
8976                      ((uint32_t) ifp->mac[2] << 16) |
8977                      ((uint32_t) ifp->mac[1] << 8) | ifp->mac[0];
8978   // NOTE(scaprile) There are 3 additional slots for filtering, disabled by
8979   // default. This also applies to the STM32 driver (at least for F7)
8980   return true;
8981 }
8982
8983 static uint32_t s_txno;
8984 static size_t mg_tcpip_driver_tm4c_tx(const void *buf, size_t len,
8985                                       struct mg_tcpip_if *ifp) {
8986   if (len > sizeof(s_txbuf[s_txno])) {
8987     MG_ERROR(("Frame too big, %ld", (long) len));
8988     len = 0;  // fail
8989   } else if ((s_txdesc[s_txno][0] & BIT(31))) {
8990     MG_ERROR(("No descriptors available"));
8991     // printf("D0 %lx SR %lx\n", (long) s_txdesc[0][0], (long)
8992     // EMAC->EMACDMARIS);
8993     len = 0;  // fail
8994   } else {
8995     memcpy(s_txbuf[s_txno], buf, len);     // Copy data
8996     s_txdesc[s_txno][1] = (uint32_t) len;  // Set data len
8997     s_txdesc[s_txno][0] =
8998         BIT(20) | BIT(28) | BIT(29) | BIT(30);  // Chain,FS,LS,IC
8999     s_txdesc[s_txno][0] |= BIT(31);  // Set OWN bit - let DMA take over
9000     if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
9001   }
9002   EMAC->EMACDMARIS = BIT(2) | BIT(5);  // Clear any prior TU/UNF
9003   EMAC->EMACTXPOLLD = 0;               // and resume
9004   return len;
9005   (void) ifp;
9006 }
9007
9008 static bool mg_tcpip_driver_tm4c_up(struct mg_tcpip_if *ifp) {
9009   uint32_t bmsr = emac_read_phy(EPHY_ADDR, EPHYBMSR);
9010   bool up = (bmsr & BIT(2)) ? 1 : 0;
9011   if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) {  // link state just went up
9012     uint32_t sts = emac_read_phy(EPHY_ADDR, EPHYSTS);
9013     uint32_t emaccfg = EMAC->EMACCFG | BIT(14) | BIT(11);  // 100M, Full-duplex
9014     if (sts & BIT(1)) emaccfg &= ~BIT(14);                 // 10M
9015     if ((sts & BIT(2)) == 0) emaccfg &= ~BIT(11);          // Half-duplex
9016     EMAC->EMACCFG = emaccfg;  // IRQ handler does not fiddle with this register
9017     MG_DEBUG(("Link is %uM %s-duplex", emaccfg & BIT(14) ? 100 : 10,
9018               emaccfg & BIT(11) ? "full" : "half"));
9019   }
9020   return up;
9021 }
9022
9023 void EMAC0_IRQHandler(void);
9024 static uint32_t s_rxno;
9025 void EMAC0_IRQHandler(void) {
9026   if (EMAC->EMACDMARIS & BIT(6)) {        // Frame received, loop
9027     EMAC->EMACDMARIS = BIT(16) | BIT(6);  // Clear flag
9028     for (uint32_t i = 0; i < 10; i++) {   // read as they arrive but not forever
9029       if (s_rxdesc[s_rxno][0] & BIT(31)) break;  // exit when done
9030       if (((s_rxdesc[s_rxno][0] & (BIT(8) | BIT(9))) == (BIT(8) | BIT(9))) &&
9031           !(s_rxdesc[s_rxno][0] & BIT(15))) {  // skip partial/errored frames
9032         uint32_t len = ((s_rxdesc[s_rxno][0] >> 16) & (BIT(14) - 1));
9033         //  printf("%lx %lu %lx %.8lx\n", s_rxno, len, s_rxdesc[s_rxno][0],
9034         //  EMAC->EMACDMARIS);
9035         mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
9036       }
9037       s_rxdesc[s_rxno][0] = BIT(31);
9038       if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
9039     }
9040   }
9041   EMAC->EMACDMARIS = BIT(7);  // Clear possible RU while processing
9042   EMAC->EMACRXPOLLD = 0;      // and resume RX
9043 }
9044
9045 struct mg_tcpip_driver mg_tcpip_driver_tm4c = {mg_tcpip_driver_tm4c_init,
9046                                                mg_tcpip_driver_tm4c_tx, NULL,
9047                                                mg_tcpip_driver_tm4c_up};
9048 #endif
9049
9050 #ifdef MG_ENABLE_LINES
9051 #line 1 "src/drivers/w5500.c"
9052 #endif
9053
9054
9055 #if MG_ENABLE_TCPIP
9056
9057 enum { W5500_CR = 0, W5500_S0 = 1, W5500_TX0 = 2, W5500_RX0 = 3 };
9058
9059 static void w5500_txn(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, bool wr,
9060                       void *buf, size_t len) {
9061   uint8_t *p = (uint8_t *) buf;
9062   uint8_t cmd[] = {(uint8_t) (addr >> 8), (uint8_t) (addr & 255),
9063                    (uint8_t) ((block << 3) | (wr ? 4 : 0))};
9064   s->begin(s->spi);
9065   for (size_t i = 0; i < sizeof(cmd); i++) s->txn(s->spi, cmd[i]);
9066   for (size_t i = 0; i < len; i++) {
9067     uint8_t r = s->txn(s->spi, p[i]);
9068     if (!wr) p[i] = r;
9069   }
9070   s->end(s->spi);
9071 }
9072
9073 // clang-format off
9074 static  void w5500_wn(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, void *buf, size_t len) { w5500_txn(s, block, addr, true, buf, len); }
9075 static  void w5500_w1(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, uint8_t val) { w5500_wn(s, block, addr, &val, 1); }
9076 static  void w5500_w2(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, uint16_t val) { uint8_t buf[2] = {(uint8_t) (val >> 8), (uint8_t) (val & 255)}; w5500_wn(s, block, addr, buf, sizeof(buf)); }
9077 static  void w5500_rn(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, void *buf, size_t len) { w5500_txn(s, block, addr, false, buf, len); }
9078 static  uint8_t w5500_r1(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr) { uint8_t r = 0; w5500_rn(s, block, addr, &r, 1); return r; }
9079 static  uint16_t w5500_r2(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr) { uint8_t buf[2] = {0, 0}; w5500_rn(s, block, addr, buf, sizeof(buf)); return (uint16_t) ((buf[0] << 8) | buf[1]); }
9080 // clang-format on
9081
9082 static size_t w5500_rx(void *buf, size_t buflen, struct mg_tcpip_if *ifp) {
9083   struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
9084   uint16_t r = 0, n = 0, len = (uint16_t) buflen, n2;     // Read recv len
9085   while ((n2 = w5500_r2(s, W5500_S0, 0x26)) > n) n = n2;  // Until it is stable
9086   // printf("RSR: %d\n", (int) n);
9087   if (n > 0) {
9088     uint16_t ptr = w5500_r2(s, W5500_S0, 0x28);  // Get read pointer
9089     n = w5500_r2(s, W5500_RX0, ptr);             // Read frame length
9090     if (n <= len + 2 && n > 1) {
9091       r = (uint16_t) (n - 2);
9092       w5500_rn(s, W5500_RX0, (uint16_t) (ptr + 2), buf, r);
9093     }
9094     w5500_w2(s, W5500_S0, 0x28, (uint16_t) (ptr + n));  // Advance read pointer
9095     w5500_w1(s, W5500_S0, 1, 0x40);                     // Sock0 CR -> RECV
9096     // printf("  RX_RD: tot=%u n=%u r=%u\n", n2, n, r);
9097   }
9098   return r;
9099 }
9100
9101 static size_t w5500_tx(const void *buf, size_t buflen, struct mg_tcpip_if *ifp) {
9102   struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
9103   uint16_t n = 0, len = (uint16_t) buflen;
9104   while (n < len) n = w5500_r2(s, W5500_S0, 0x20);      // Wait for space
9105   uint16_t ptr = w5500_r2(s, W5500_S0, 0x24);           // Get write pointer
9106   w5500_wn(s, W5500_TX0, ptr, (void *) buf, len);       // Write data
9107   w5500_w2(s, W5500_S0, 0x24, (uint16_t) (ptr + len));  // Advance write pointer
9108   w5500_w1(s, W5500_S0, 1, 0x20);                       // Sock0 CR -> SEND
9109   for (int i = 0; i < 40; i++) {
9110     uint8_t ir = w5500_r1(s, W5500_S0, 2);  // Read S0 IR
9111     if (ir == 0) continue;
9112     // printf("IR %d, len=%d, free=%d, ptr %d\n", ir, (int) len, (int) n, ptr);
9113     w5500_w1(s, W5500_S0, 2, ir);  // Write S0 IR: clear it!
9114     if (ir & 8) len = 0;           // Timeout. Report error
9115     if (ir & (16 | 8)) break;      // Stop on SEND_OK or timeout
9116   }
9117   return len;
9118 }
9119
9120 static bool w5500_init(struct mg_tcpip_if *ifp) {
9121   struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
9122   s->end(s->spi);
9123   w5500_w1(s, W5500_CR, 0, 0x80);     // Reset chip: CR -> 0x80
9124   w5500_w1(s, W5500_CR, 0x2e, 0);     // CR PHYCFGR -> reset
9125   w5500_w1(s, W5500_CR, 0x2e, 0xf8);  // CR PHYCFGR -> set
9126   // w5500_wn(s, W5500_CR, 9, s->mac, 6);      // Set source MAC
9127   w5500_w1(s, W5500_S0, 0x1e, 16);          // Sock0 RX buf size
9128   w5500_w1(s, W5500_S0, 0x1f, 16);          // Sock0 TX buf size
9129   w5500_w1(s, W5500_S0, 0, 4);              // Sock0 MR -> MACRAW
9130   w5500_w1(s, W5500_S0, 1, 1);              // Sock0 CR -> OPEN
9131   return w5500_r1(s, W5500_S0, 3) == 0x42;  // Sock0 SR == MACRAW
9132 }
9133
9134 static bool w5500_up(struct mg_tcpip_if *ifp) {
9135   struct mg_tcpip_spi *spi = (struct mg_tcpip_spi *) ifp->driver_data;
9136   uint8_t phycfgr = w5500_r1(spi, W5500_CR, 0x2e);
9137   return phycfgr & 1;  // Bit 0 of PHYCFGR is LNK (0 - down, 1 - up)
9138 }
9139
9140 struct mg_tcpip_driver mg_tcpip_driver_w5500 = {w5500_init, w5500_tx, w5500_rx, w5500_up};
9141 #endif