Statistics
| Branch: | Tag: | Revision:

mongoose / mongoose.c @ d6ba37dc

History | View | Annotate | Download (437 KB)

1
#include "mongoose.h"
2
#ifdef MG_MODULE_LINES
3
#line 1 "mongoose/src/internal.h"
4
#endif
5
/*
6
 * Copyright (c) 2014 Cesanta Software Limited
7
 * All rights reserved
8
 */
9

    
10
#ifndef CS_MONGOOSE_SRC_INTERNAL_H_
11
#define CS_MONGOOSE_SRC_INTERNAL_H_
12

    
13
#ifndef MG_MALLOC
14
#define MG_MALLOC malloc
15
#endif
16

    
17
#ifndef MG_CALLOC
18
#define MG_CALLOC calloc
19
#endif
20

    
21
#ifndef MG_REALLOC
22
#define MG_REALLOC realloc
23
#endif
24

    
25
#ifndef MG_FREE
26
#define MG_FREE free
27
#endif
28

    
29
#ifndef MBUF_REALLOC
30
#define MBUF_REALLOC MG_REALLOC
31
#endif
32

    
33
#ifndef MBUF_FREE
34
#define MBUF_FREE MG_FREE
35
#endif
36

    
37
#define MG_SET_PTRPTR(_ptr, _v) \
38
  do {                          \
39
    if (_ptr) *(_ptr) = _v;     \
40
  } while (0)
41

    
42
#ifndef MG_INTERNAL
43
#define MG_INTERNAL static
44
#endif
45

    
46
#ifdef PICOTCP
47
#define NO_LIBC
48
#define MG_DISABLE_PFS
49
#endif
50

    
51
/* Amalgamated: #include "mongoose/src/net.h" */
52
/* Amalgamated: #include "mongoose/src/http.h" */
53
/* Amalgamated: #include "common/cs_dbg.h" */
54

    
55
#define MG_CTL_MSG_MESSAGE_SIZE 8192
56

    
57
/* internals that need to be accessible in unit tests */
58
MG_INTERNAL struct mg_connection *mg_do_connect(struct mg_connection *nc,
59
                                                int proto,
60
                                                union socket_address *sa);
61

    
62
MG_INTERNAL int mg_parse_address(const char *str, union socket_address *sa,
63
                                 int *proto, char *host, size_t host_len);
64
MG_INTERNAL void mg_call(struct mg_connection *nc,
65
                         mg_event_handler_t ev_handler, int ev, void *ev_data);
66
void mg_forward(struct mg_connection *from, struct mg_connection *to);
67
MG_INTERNAL void mg_add_conn(struct mg_mgr *mgr, struct mg_connection *c);
68
MG_INTERNAL void mg_remove_conn(struct mg_connection *c);
69
MG_INTERNAL struct mg_connection *mg_create_connection(
70
    struct mg_mgr *mgr, mg_event_handler_t callback,
71
    struct mg_add_sock_opts opts);
72
#ifdef _WIN32
73
/* Retur value is the same as for MultiByteToWideChar. */
74
int to_wchar(const char *path, wchar_t *wbuf, size_t wbuf_len);
75
#endif
76

    
77
struct ctl_msg {
78
  mg_event_handler_t callback;
79
  char message[MG_CTL_MSG_MESSAGE_SIZE];
80
};
81

    
82
#if MG_ENABLE_MQTT
83
struct mg_mqtt_message;
84
MG_INTERNAL int parse_mqtt(struct mbuf *io, struct mg_mqtt_message *mm);
85
#endif
86

    
87
/* Forward declarations for testing. */
88
extern void *(*test_malloc)(size_t size);
89
extern void *(*test_calloc)(size_t count, size_t size);
90

    
91
#ifndef MIN
92
#define MIN(a, b) ((a) < (b) ? (a) : (b))
93
#endif
94

    
95
#if MG_ENABLE_HTTP
96
struct mg_serve_http_opts;
97

    
98
/*
99
 * Reassemble the content of the buffer (buf, blen) which should be
100
 * in the HTTP chunked encoding, by collapsing data chunks to the
101
 * beginning of the buffer.
102
 *
103
 * If chunks get reassembled, modify hm->body to point to the reassembled
104
 * body and fire MG_EV_HTTP_CHUNK event. If handler sets MG_F_DELETE_CHUNK
105
 * in nc->flags, delete reassembled body from the mbuf.
106
 *
107
 * Return reassembled body size.
108
 */
109
MG_INTERNAL size_t mg_handle_chunked(struct mg_connection *nc,
110
                                     struct http_message *hm, char *buf,
111
                                     size_t blen);
112

    
113
MG_INTERNAL int mg_http_common_url_parse(const char *url, const char *schema,
114
                                         const char *schema_tls, int *use_ssl,
115
                                         char **user, char **pass, char **addr,
116
                                         int *port_i, const char **path);
117

    
118
#if MG_ENABLE_FILESYSTEM
119
MG_INTERNAL int mg_uri_to_local_path(struct http_message *hm,
120
                                     const struct mg_serve_http_opts *opts,
121
                                     char **local_path,
122
                                     struct mg_str *remainder);
123
MG_INTERNAL time_t mg_parse_date_string(const char *datetime);
124
MG_INTERNAL int mg_is_not_modified(struct http_message *hm, cs_stat_t *st);
125
#endif
126
#if MG_ENABLE_HTTP_CGI
127
MG_INTERNAL void mg_handle_cgi(struct mg_connection *nc, const char *prog,
128
                               const struct mg_str *path_info,
129
                               const struct http_message *hm,
130
                               const struct mg_serve_http_opts *opts);
131
struct mg_http_proto_data_cgi;
132
MG_INTERNAL void mg_http_free_proto_data_cgi(struct mg_http_proto_data_cgi *d);
133
#endif
134
#if MG_ENABLE_HTTP_SSI
135
MG_INTERNAL void mg_handle_ssi_request(struct mg_connection *nc,
136
                                       struct http_message *hm,
137
                                       const char *path,
138
                                       const struct mg_serve_http_opts *opts);
139
#endif
140
#if MG_ENABLE_HTTP_WEBDAV
141
MG_INTERNAL int mg_is_dav_request(const struct mg_str *s);
142
MG_INTERNAL void mg_handle_propfind(struct mg_connection *nc, const char *path,
143
                                    cs_stat_t *stp, struct http_message *hm,
144
                                    struct mg_serve_http_opts *opts);
145
MG_INTERNAL void mg_handle_lock(struct mg_connection *nc, const char *path);
146
MG_INTERNAL void mg_handle_mkcol(struct mg_connection *nc, const char *path,
147
                                 struct http_message *hm);
148
MG_INTERNAL void mg_handle_move(struct mg_connection *c,
149
                                const struct mg_serve_http_opts *opts,
150
                                const char *path, struct http_message *hm);
151
MG_INTERNAL void mg_handle_delete(struct mg_connection *nc,
152
                                  const struct mg_serve_http_opts *opts,
153
                                  const char *path);
154
MG_INTERNAL void mg_handle_put(struct mg_connection *nc, const char *path,
155
                               struct http_message *hm);
156
#endif
157
#if MG_ENABLE_HTTP_WEBSOCKET
158
MG_INTERNAL void mg_ws_handler(struct mg_connection *nc, int ev, void *ev_data);
159
MG_INTERNAL void mg_ws_handshake(struct mg_connection *nc,
160
                                 const struct mg_str *key);
161
#endif
162
#endif /* MG_ENABLE_HTTP */
163

    
164
MG_INTERNAL int mg_get_errno(void);
165

    
166
MG_INTERNAL void mg_close_conn(struct mg_connection *conn);
167

    
168
MG_INTERNAL int mg_http_common_url_parse(const char *url, const char *schema,
169
                                         const char *schema_tls, int *use_ssl,
170
                                         char **user, char **pass, char **addr,
171
                                         int *port_i, const char **path);
172

    
173
#if MG_ENABLE_SNTP
174
MG_INTERNAL int mg_sntp_parse_reply(const char *buf, int len,
175
                                    struct mg_sntp_message *msg);
176
#endif
177

    
178
#endif /* CS_MONGOOSE_SRC_INTERNAL_H_ */
179
#ifdef MG_MODULE_LINES
180
#line 1 "common/cs_dbg.h"
181
#endif
182
/*
183
 * Copyright (c) 2014-2016 Cesanta Software Limited
184
 * All rights reserved
185
 */
186

    
187
#ifndef CS_COMMON_CS_DBG_H_
188
#define CS_COMMON_CS_DBG_H_
189

    
190
/* Amalgamated: #include "common/platform.h" */
191

    
192
#if CS_ENABLE_STDIO
193
#include <stdio.h>
194
#endif
195

    
196
#ifndef CS_ENABLE_DEBUG
197
#define CS_ENABLE_DEBUG 0
198
#endif
199

    
200
#ifndef CS_LOG_ENABLE_TS_DIFF
201
#define CS_LOG_ENABLE_TS_DIFF 0
202
#endif
203

    
204
#ifdef __cplusplus
205
extern "C" {
206
#endif /* __cplusplus */
207

    
208
enum cs_log_level {
209
  LL_NONE = -1,
210
  LL_ERROR = 0,
211
  LL_WARN = 1,
212
  LL_INFO = 2,
213
  LL_DEBUG = 3,
214
  LL_VERBOSE_DEBUG = 4,
215

    
216
  _LL_MIN = -2,
217
  _LL_MAX = 5,
218
};
219

    
220
void cs_log_set_level(enum cs_log_level level);
221

    
222
#if CS_ENABLE_STDIO
223

    
224
void cs_log_set_file(FILE *file);
225
extern enum cs_log_level cs_log_level;
226
void cs_log_print_prefix(const char *func);
227
void cs_log_printf(const char *fmt, ...);
228

    
229
#define LOG(l, x)                    \
230
  do {                               \
231
    if (cs_log_level >= l) {         \
232
      cs_log_print_prefix(__func__); \
233
      cs_log_printf x;               \
234
    }                                \
235
  } while (0)
236

    
237
#ifndef CS_NDEBUG
238

    
239
#define DBG(x)                              \
240
  do {                                      \
241
    if (cs_log_level >= LL_VERBOSE_DEBUG) { \
242
      cs_log_print_prefix(__func__);        \
243
      cs_log_printf x;                      \
244
    }                                       \
245
  } while (0)
246

    
247
#else /* NDEBUG */
248

    
249
#define DBG(x)
250

    
251
#endif
252

    
253
#else /* CS_ENABLE_STDIO */
254

    
255
#define LOG(l, x)
256
#define DBG(x)
257

    
258
#endif
259

    
260
#ifdef __cplusplus
261
}
262
#endif /* __cplusplus */
263

    
264
#endif /* CS_COMMON_CS_DBG_H_ */
265
#ifdef MG_MODULE_LINES
266
#line 1 "common/cs_dbg.c"
267
#endif
268
/*
269
 * Copyright (c) 2014-2016 Cesanta Software Limited
270
 * All rights reserved
271
 */
272

    
273
/* Amalgamated: #include "common/cs_dbg.h" */
274

    
275
#include <stdarg.h>
276
#include <stdio.h>
277

    
278
/* Amalgamated: #include "common/cs_time.h" */
279

    
280
enum cs_log_level cs_log_level WEAK =
281
#if CS_ENABLE_DEBUG
282
    LL_VERBOSE_DEBUG;
283
#else
284
    LL_ERROR;
285
#endif
286

    
287
#if CS_ENABLE_STDIO
288

    
289
FILE *cs_log_file WEAK = NULL;
290

    
291
#if CS_LOG_ENABLE_TS_DIFF
292
double cs_log_ts WEAK;
293
#endif
294

    
295
void cs_log_print_prefix(const char *func) WEAK;
296
void cs_log_print_prefix(const char *func) {
297
  char prefix[21];
298
  strncpy(prefix, func, 20);
299
  prefix[20] = '\0';
300
  if (cs_log_file == NULL) cs_log_file = stderr;
301
  fprintf(cs_log_file, "%-20s ", prefix);
302
#if CS_LOG_ENABLE_TS_DIFF
303
  {
304
    double now = cs_time();
305
    fprintf(cs_log_file, "%7u ", (unsigned int) ((now - cs_log_ts) * 1000000));
306
    cs_log_ts = now;
307
  }
308
#endif
309
}
310

    
311
void cs_log_printf(const char *fmt, ...) WEAK;
312
void cs_log_printf(const char *fmt, ...) {
313
  va_list ap;
314
  va_start(ap, fmt);
315
  vfprintf(cs_log_file, fmt, ap);
316
  va_end(ap);
317
  fputc('\n', cs_log_file);
318
  fflush(cs_log_file);
319
}
320

    
321
void cs_log_set_file(FILE *file) WEAK;
322
void cs_log_set_file(FILE *file) {
323
  cs_log_file = file;
324
}
325

    
326
#endif /* CS_ENABLE_STDIO */
327

    
328
void cs_log_set_level(enum cs_log_level level) WEAK;
329
void cs_log_set_level(enum cs_log_level level) {
330
  cs_log_level = level;
331
#if CS_LOG_ENABLE_TS_DIFF && CS_ENABLE_STDIO
332
  cs_log_ts = cs_time();
333
#endif
334
}
335
#ifdef MG_MODULE_LINES
336
#line 1 "common/base64.c"
337
#endif
338
/*
339
 * Copyright (c) 2014 Cesanta Software Limited
340
 * All rights reserved
341
 */
342

    
343
#ifndef EXCLUDE_COMMON
344

    
345
/* Amalgamated: #include "common/base64.h" */
346

    
347
#include <string.h>
348

    
349
/* Amalgamated: #include "common/cs_dbg.h" */
350

    
351
/* ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ */
352

    
353
#define NUM_UPPERCASES ('Z' - 'A' + 1)
354
#define NUM_LETTERS (NUM_UPPERCASES * 2)
355
#define NUM_DIGITS ('9' - '0' + 1)
356

    
357
/*
358
 * Emit a base64 code char.
359
 *
360
 * Doesn't use memory, thus it's safe to use to safely dump memory in crashdumps
361
 */
362
static void cs_base64_emit_code(struct cs_base64_ctx *ctx, int v) {
363
  if (v < NUM_UPPERCASES) {
364
    ctx->b64_putc(v + 'A', ctx->user_data);
365
  } else if (v < (NUM_LETTERS)) {
366
    ctx->b64_putc(v - NUM_UPPERCASES + 'a', ctx->user_data);
367
  } else if (v < (NUM_LETTERS + NUM_DIGITS)) {
368
    ctx->b64_putc(v - NUM_LETTERS + '0', ctx->user_data);
369
  } else {
370
    ctx->b64_putc(v - NUM_LETTERS - NUM_DIGITS == 0 ? '+' : '/',
371
                  ctx->user_data);
372
  }
373
}
374

    
375
static void cs_base64_emit_chunk(struct cs_base64_ctx *ctx) {
376
  int a, b, c;
377

    
378
  a = ctx->chunk[0];
379
  b = ctx->chunk[1];
380
  c = ctx->chunk[2];
381

    
382
  cs_base64_emit_code(ctx, a >> 2);
383
  cs_base64_emit_code(ctx, ((a & 3) << 4) | (b >> 4));
384
  if (ctx->chunk_size > 1) {
385
    cs_base64_emit_code(ctx, (b & 15) << 2 | (c >> 6));
386
  }
387
  if (ctx->chunk_size > 2) {
388
    cs_base64_emit_code(ctx, c & 63);
389
  }
390
}
391

    
392
void cs_base64_init(struct cs_base64_ctx *ctx, cs_base64_putc_t b64_putc,
393
                    void *user_data) {
394
  ctx->chunk_size = 0;
395
  ctx->b64_putc = b64_putc;
396
  ctx->user_data = user_data;
397
}
398

    
399
void cs_base64_update(struct cs_base64_ctx *ctx, const char *str, size_t len) {
400
  const unsigned char *src = (const unsigned char *) str;
401
  size_t i;
402
  for (i = 0; i < len; i++) {
403
    ctx->chunk[ctx->chunk_size++] = src[i];
404
    if (ctx->chunk_size == 3) {
405
      cs_base64_emit_chunk(ctx);
406
      ctx->chunk_size = 0;
407
    }
408
  }
409
}
410

    
411
void cs_base64_finish(struct cs_base64_ctx *ctx) {
412
  if (ctx->chunk_size > 0) {
413
    int i;
414
    memset(&ctx->chunk[ctx->chunk_size], 0, 3 - ctx->chunk_size);
415
    cs_base64_emit_chunk(ctx);
416
    for (i = 0; i < (3 - ctx->chunk_size); i++) {
417
      ctx->b64_putc('=', ctx->user_data);
418
    }
419
  }
420
}
421

    
422
#define BASE64_ENCODE_BODY                                                \
423
  static const char *b64 =                                                \
424
      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; \
425
  int i, j, a, b, c;                                                      \
426
                                                                          \
427
  for (i = j = 0; i < src_len; i += 3) {                                  \
428
    a = src[i];                                                           \
429
    b = i + 1 >= src_len ? 0 : src[i + 1];                                \
430
    c = i + 2 >= src_len ? 0 : src[i + 2];                                \
431
                                                                          \
432
    BASE64_OUT(b64[a >> 2]);                                              \
433
    BASE64_OUT(b64[((a & 3) << 4) | (b >> 4)]);                           \
434
    if (i + 1 < src_len) {                                                \
435
      BASE64_OUT(b64[(b & 15) << 2 | (c >> 6)]);                          \
436
    }                                                                     \
437
    if (i + 2 < src_len) {                                                \
438
      BASE64_OUT(b64[c & 63]);                                            \
439
    }                                                                     \
440
  }                                                                       \
441
                                                                          \
442
  while (j % 4 != 0) {                                                    \
443
    BASE64_OUT('=');                                                      \
444
  }                                                                       \
445
  BASE64_FLUSH()
446

    
447
#define BASE64_OUT(ch) \
448
  do {                 \
449
    dst[j++] = (ch);   \
450
  } while (0)
451

    
452
#define BASE64_FLUSH() \
453
  do {                 \
454
    dst[j++] = '\0';   \
455
  } while (0)
456

    
457
void cs_base64_encode(const unsigned char *src, int src_len, char *dst) {
458
  BASE64_ENCODE_BODY;
459
}
460

    
461
#undef BASE64_OUT
462
#undef BASE64_FLUSH
463

    
464
#if CS_ENABLE_STDIO
465
#define BASE64_OUT(ch)      \
466
  do {                      \
467
    fprintf(f, "%c", (ch)); \
468
    j++;                    \
469
  } while (0)
470

    
471
#define BASE64_FLUSH()
472

    
473
void cs_fprint_base64(FILE *f, const unsigned char *src, int src_len) {
474
  BASE64_ENCODE_BODY;
475
}
476

    
477
#undef BASE64_OUT
478
#undef BASE64_FLUSH
479
#endif /* CS_ENABLE_STDIO */
480

    
481
/* Convert one byte of encoded base64 input stream to 6-bit chunk */
482
static unsigned char from_b64(unsigned char ch) {
483
  /* Inverse lookup map */
484
  static const unsigned char tab[128] = {
485
      255, 255, 255, 255,
486
      255, 255, 255, 255, /*  0 */
487
      255, 255, 255, 255,
488
      255, 255, 255, 255, /*  8 */
489
      255, 255, 255, 255,
490
      255, 255, 255, 255, /*  16 */
491
      255, 255, 255, 255,
492
      255, 255, 255, 255, /*  24 */
493
      255, 255, 255, 255,
494
      255, 255, 255, 255, /*  32 */
495
      255, 255, 255, 62,
496
      255, 255, 255, 63, /*  40 */
497
      52,  53,  54,  55,
498
      56,  57,  58,  59, /*  48 */
499
      60,  61,  255, 255,
500
      255, 200, 255, 255, /*  56   '=' is 200, on index 61 */
501
      255, 0,   1,   2,
502
      3,   4,   5,   6, /*  64 */
503
      7,   8,   9,   10,
504
      11,  12,  13,  14, /*  72 */
505
      15,  16,  17,  18,
506
      19,  20,  21,  22, /*  80 */
507
      23,  24,  25,  255,
508
      255, 255, 255, 255, /*  88 */
509
      255, 26,  27,  28,
510
      29,  30,  31,  32, /*  96 */
511
      33,  34,  35,  36,
512
      37,  38,  39,  40, /*  104 */
513
      41,  42,  43,  44,
514
      45,  46,  47,  48, /*  112 */
515
      49,  50,  51,  255,
516
      255, 255, 255, 255, /*  120 */
517
  };
518
  return tab[ch & 127];
519
}
520

    
521
int cs_base64_decode(const unsigned char *s, int len, char *dst, int *dec_len) {
522
  unsigned char a, b, c, d;
523
  int orig_len = len;
524
  char *orig_dst = dst;
525
  while (len >= 4 && (a = from_b64(s[0])) != 255 &&
526
         (b = from_b64(s[1])) != 255 && (c = from_b64(s[2])) != 255 &&
527
         (d = from_b64(s[3])) != 255) {
528
    s += 4;
529
    len -= 4;
530
    if (a == 200 || b == 200) break; /* '=' can't be there */
531
    *dst++ = a << 2 | b >> 4;
532
    if (c == 200) break;
533
    *dst++ = b << 4 | c >> 2;
534
    if (d == 200) break;
535
    *dst++ = c << 6 | d;
536
  }
537
  *dst = 0;
538
  if (dec_len != NULL) *dec_len = (dst - orig_dst);
539
  return orig_len - len;
540
}
541

    
542
#endif /* EXCLUDE_COMMON */
543
#ifdef MG_MODULE_LINES
544
#line 1 "common/cs_dirent.h"
545
#endif
546
/*
547
 * Copyright (c) 2014-2016 Cesanta Software Limited
548
 * All rights reserved
549
 */
550

    
551
#ifndef CS_COMMON_CS_DIRENT_H_
552
#define CS_COMMON_CS_DIRENT_H_
553

    
554
#include <limits.h>
555

    
556
/* Amalgamated: #include "common/platform.h" */
557

    
558
#ifdef __cplusplus
559
extern "C" {
560
#endif /* __cplusplus */
561

    
562
#ifdef CS_DEFINE_DIRENT
563
typedef struct { int dummy; } DIR;
564

    
565
struct dirent {
566
  int d_ino;
567
#ifdef _WIN32
568
  char d_name[MAX_PATH];
569
#else
570
  /* TODO(rojer): Use PATH_MAX but make sure it's sane on every platform */
571
  char d_name[256];
572
#endif
573
};
574

    
575
DIR *opendir(const char *dir_name);
576
int closedir(DIR *dir);
577
struct dirent *readdir(DIR *dir);
578
#endif /* CS_DEFINE_DIRENT */
579

    
580
#ifdef __cplusplus
581
}
582
#endif /* __cplusplus */
583

    
584
#endif /* CS_COMMON_CS_DIRENT_H_ */
585
#ifdef MG_MODULE_LINES
586
#line 1 "common/cs_dirent.c"
587
#endif
588
/*
589
 * Copyright (c) 2015 Cesanta Software Limited
590
 * All rights reserved
591
 */
592

    
593
#ifndef EXCLUDE_COMMON
594

    
595
/* Amalgamated: #include "common/cs_dirent.h" */
596

    
597
/*
598
 * This file contains POSIX opendir/closedir/readdir API implementation
599
 * for systems which do not natively support it (e.g. Windows).
600
 */
601

    
602
#ifndef MG_FREE
603
#define MG_FREE free
604
#endif
605

    
606
#ifndef MG_MALLOC
607
#define MG_MALLOC malloc
608
#endif
609

    
610
#ifdef _WIN32
611
struct win32_dir {
612
  DIR d;
613
  HANDLE handle;
614
  WIN32_FIND_DATAW info;
615
  struct dirent result;
616
};
617

    
618
DIR *opendir(const char *name) {
619
  struct win32_dir *dir = NULL;
620
  wchar_t wpath[MAX_PATH];
621
  DWORD attrs;
622

    
623
  if (name == NULL) {
624
    SetLastError(ERROR_BAD_ARGUMENTS);
625
  } else if ((dir = (struct win32_dir *) MG_MALLOC(sizeof(*dir))) == NULL) {
626
    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
627
  } else {
628
    to_wchar(name, wpath, ARRAY_SIZE(wpath));
629
    attrs = GetFileAttributesW(wpath);
630
    if (attrs != 0xFFFFFFFF && (attrs & FILE_ATTRIBUTE_DIRECTORY)) {
631
      (void) wcscat(wpath, L"\\*");
632
      dir->handle = FindFirstFileW(wpath, &dir->info);
633
      dir->result.d_name[0] = '\0';
634
    } else {
635
      MG_FREE(dir);
636
      dir = NULL;
637
    }
638
  }
639

    
640
  return (DIR *) dir;
641
}
642

    
643
int closedir(DIR *d) {
644
  struct win32_dir *dir = (struct win32_dir *) d;
645
  int result = 0;
646

    
647
  if (dir != NULL) {
648
    if (dir->handle != INVALID_HANDLE_VALUE)
649
      result = FindClose(dir->handle) ? 0 : -1;
650
    MG_FREE(dir);
651
  } else {
652
    result = -1;
653
    SetLastError(ERROR_BAD_ARGUMENTS);
654
  }
655

    
656
  return result;
657
}
658

    
659
struct dirent *readdir(DIR *d) {
660
  struct win32_dir *dir = (struct win32_dir *) d;
661
  struct dirent *result = NULL;
662

    
663
  if (dir) {
664
    memset(&dir->result, 0, sizeof(dir->result));
665
    if (dir->handle != INVALID_HANDLE_VALUE) {
666
      result = &dir->result;
667
      (void) WideCharToMultiByte(CP_UTF8, 0, dir->info.cFileName, -1,
668
                                 result->d_name, sizeof(result->d_name), NULL,
669
                                 NULL);
670

    
671
      if (!FindNextFileW(dir->handle, &dir->info)) {
672
        (void) FindClose(dir->handle);
673
        dir->handle = INVALID_HANDLE_VALUE;
674
      }
675

    
676
    } else {
677
      SetLastError(ERROR_FILE_NOT_FOUND);
678
    }
679
  } else {
680
    SetLastError(ERROR_BAD_ARGUMENTS);
681
  }
682

    
683
  return result;
684
}
685
#endif
686

    
687
#endif /* EXCLUDE_COMMON */
688

    
689
/* ISO C requires a translation unit to contain at least one declaration */
690
typedef int cs_dirent_dummy;
691
#ifdef MG_MODULE_LINES
692
#line 1 "common/cs_time.c"
693
#endif
694
/*
695
 * Copyright (c) 2014-2016 Cesanta Software Limited
696
 * All rights reserved
697
 */
698

    
699
/* Amalgamated: #include "common/cs_time.h" */
700

    
701
#ifndef _WIN32
702
#include <stddef.h>
703
/*
704
 * There is no sys/time.h on ARMCC.
705
 */
706
#if !(defined(__ARMCC_VERSION) || defined(__ICCARM__)) && \
707
    !defined(__TI_COMPILER_VERSION__) &&                  \
708
    (!defined(CS_PLATFORM) || CS_PLATFORM != CS_P_NXP_LPC)
709
#include <sys/time.h>
710
#endif
711
#else
712
#include <windows.h>
713
#endif
714

    
715
double cs_time(void) WEAK;
716
double cs_time(void) {
717
  double now;
718
#ifndef _WIN32
719
  struct timeval tv;
720
  if (gettimeofday(&tv, NULL /* tz */) != 0) return 0;
721
  now = (double) tv.tv_sec + (((double) tv.tv_usec) / 1000000.0);
722
#else
723
  SYSTEMTIME sysnow;
724
  FILETIME ftime;
725
  GetLocalTime(&sysnow);
726
  SystemTimeToFileTime(&sysnow, &ftime);
727
  /*
728
   * 1. VC 6.0 doesn't support conversion uint64 -> double, so, using int64
729
   * This should not cause a problems in this (21th) century
730
   * 2. Windows FILETIME is a number of 100-nanosecond intervals since January
731
   * 1, 1601 while time_t is a number of _seconds_ since January 1, 1970 UTC,
732
   * thus, we need to convert to seconds and adjust amount (subtract 11644473600
733
   * seconds)
734
   */
735
  now = (double) (((int64_t) ftime.dwLowDateTime +
736
                   ((int64_t) ftime.dwHighDateTime << 32)) /
737
                  10000000.0) -
738
        11644473600;
739
#endif /* _WIN32 */
740
  return now;
741
}
742
#ifdef MG_MODULE_LINES
743
#line 1 "common/cs_endian.h"
744
#endif
745
/*
746
 * Copyright (c) 2014-2016 Cesanta Software Limited
747
 * All rights reserved
748
 */
749

    
750
#ifndef CS_COMMON_CS_ENDIAN_H_
751
#define CS_COMMON_CS_ENDIAN_H_
752

    
753
/*
754
 * clang with std=-c99 uses __LITTLE_ENDIAN, by default
755
 * while for ex, RTOS gcc - LITTLE_ENDIAN, by default
756
 * it depends on __USE_BSD, but let's have everything
757
 */
758
#if !defined(BYTE_ORDER) && defined(__BYTE_ORDER)
759
#define BYTE_ORDER __BYTE_ORDER
760
#ifndef LITTLE_ENDIAN
761
#define LITTLE_ENDIAN __LITTLE_ENDIAN
762
#endif /* LITTLE_ENDIAN */
763
#ifndef BIG_ENDIAN
764
#define BIG_ENDIAN __LITTLE_ENDIAN
765
#endif /* BIG_ENDIAN */
766
#endif /* BYTE_ORDER */
767

    
768
#endif /* CS_COMMON_CS_ENDIAN_H_ */
769
#ifdef MG_MODULE_LINES
770
#line 1 "common/md5.c"
771
#endif
772
/*
773
 * This code implements the MD5 message-digest algorithm.
774
 * The algorithm is due to Ron Rivest.  This code was
775
 * written by Colin Plumb in 1993, no copyright is claimed.
776
 * This code is in the public domain; do with it what you wish.
777
 *
778
 * Equivalent code is available from RSA Data Security, Inc.
779
 * This code has been tested against that, and is equivalent,
780
 * except that you don't need to include two pages of legalese
781
 * with every copy.
782
 *
783
 * To compute the message digest of a chunk of bytes, declare an
784
 * MD5Context structure, pass it to MD5Init, call MD5Update as
785
 * needed on buffers full of bytes, and then call MD5Final, which
786
 * will fill a supplied 16-byte array with the digest.
787
 */
788

    
789
/* Amalgamated: #include "common/md5.h" */
790
/* Amalgamated: #include "common/str_util.h" */
791

    
792
#if !defined(EXCLUDE_COMMON)
793
#if !DISABLE_MD5
794

    
795
/* Amalgamated: #include "common/cs_endian.h" */
796

    
797
static void byteReverse(unsigned char *buf, unsigned longs) {
798
/* Forrest: MD5 expect LITTLE_ENDIAN, swap if BIG_ENDIAN */
799
#if BYTE_ORDER == BIG_ENDIAN
800
  do {
801
    uint32_t t = (uint32_t)((unsigned) buf[3] << 8 | buf[2]) << 16 |
802
                 ((unsigned) buf[1] << 8 | buf[0]);
803
    *(uint32_t *) buf = t;
804
    buf += 4;
805
  } while (--longs);
806
#else
807
  (void) buf;
808
  (void) longs;
809
#endif
810
}
811

    
812
#define F1(x, y, z) (z ^ (x & (y ^ z)))
813
#define F2(x, y, z) F1(z, x, y)
814
#define F3(x, y, z) (x ^ y ^ z)
815
#define F4(x, y, z) (y ^ (x | ~z))
816

    
817
#define MD5STEP(f, w, x, y, z, data, s) \
818
  (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x)
819

    
820
/*
821
 * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
822
 * initialization constants.
823
 */
824
void MD5_Init(MD5_CTX *ctx) {
825
  ctx->buf[0] = 0x67452301;
826
  ctx->buf[1] = 0xefcdab89;
827
  ctx->buf[2] = 0x98badcfe;
828
  ctx->buf[3] = 0x10325476;
829

    
830
  ctx->bits[0] = 0;
831
  ctx->bits[1] = 0;
832
}
833

    
834
static void MD5Transform(uint32_t buf[4], uint32_t const in[16]) {
835
  register uint32_t a, b, c, d;
836

    
837
  a = buf[0];
838
  b = buf[1];
839
  c = buf[2];
840
  d = buf[3];
841

    
842
  MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
843
  MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
844
  MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
845
  MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
846
  MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
847
  MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
848
  MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
849
  MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
850
  MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
851
  MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
852
  MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
853
  MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
854
  MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
855
  MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
856
  MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
857
  MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
858

    
859
  MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
860
  MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
861
  MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
862
  MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
863
  MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
864
  MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
865
  MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
866
  MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
867
  MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
868
  MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
869
  MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
870
  MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
871
  MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
872
  MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
873
  MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
874
  MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
875

    
876
  MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
877
  MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
878
  MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
879
  MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
880
  MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
881
  MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
882
  MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
883
  MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
884
  MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
885
  MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
886
  MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
887
  MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
888
  MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
889
  MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
890
  MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
891
  MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
892

    
893
  MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
894
  MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
895
  MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
896
  MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
897
  MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
898
  MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
899
  MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
900
  MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
901
  MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
902
  MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
903
  MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
904
  MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
905
  MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
906
  MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
907
  MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
908
  MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
909

    
910
  buf[0] += a;
911
  buf[1] += b;
912
  buf[2] += c;
913
  buf[3] += d;
914
}
915

    
916
void MD5_Update(MD5_CTX *ctx, const unsigned char *buf, size_t len) {
917
  uint32_t t;
918

    
919
  t = ctx->bits[0];
920
  if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) ctx->bits[1]++;
921
  ctx->bits[1] += (uint32_t) len >> 29;
922

    
923
  t = (t >> 3) & 0x3f;
924

    
925
  if (t) {
926
    unsigned char *p = (unsigned char *) ctx->in + t;
927

    
928
    t = 64 - t;
929
    if (len < t) {
930
      memcpy(p, buf, len);
931
      return;
932
    }
933
    memcpy(p, buf, t);
934
    byteReverse(ctx->in, 16);
935
    MD5Transform(ctx->buf, (uint32_t *) ctx->in);
936
    buf += t;
937
    len -= t;
938
  }
939

    
940
  while (len >= 64) {
941
    memcpy(ctx->in, buf, 64);
942
    byteReverse(ctx->in, 16);
943
    MD5Transform(ctx->buf, (uint32_t *) ctx->in);
944
    buf += 64;
945
    len -= 64;
946
  }
947

    
948
  memcpy(ctx->in, buf, len);
949
}
950

    
951
void MD5_Final(unsigned char digest[16], MD5_CTX *ctx) {
952
  unsigned count;
953
  unsigned char *p;
954
  uint32_t *a;
955

    
956
  count = (ctx->bits[0] >> 3) & 0x3F;
957

    
958
  p = ctx->in + count;
959
  *p++ = 0x80;
960
  count = 64 - 1 - count;
961
  if (count < 8) {
962
    memset(p, 0, count);
963
    byteReverse(ctx->in, 16);
964
    MD5Transform(ctx->buf, (uint32_t *) ctx->in);
965
    memset(ctx->in, 0, 56);
966
  } else {
967
    memset(p, 0, count - 8);
968
  }
969
  byteReverse(ctx->in, 14);
970

    
971
  a = (uint32_t *) ctx->in;
972
  a[14] = ctx->bits[0];
973
  a[15] = ctx->bits[1];
974

    
975
  MD5Transform(ctx->buf, (uint32_t *) ctx->in);
976
  byteReverse((unsigned char *) ctx->buf, 4);
977
  memcpy(digest, ctx->buf, 16);
978
  memset((char *) ctx, 0, sizeof(*ctx));
979
}
980
#endif /* DISABLE_MD5 */
981

    
982
char *cs_md5(char buf[33], ...) {
983
  unsigned char hash[16];
984
  const unsigned char *p;
985
  va_list ap;
986
  MD5_CTX ctx;
987

    
988
  MD5_Init(&ctx);
989

    
990
  va_start(ap, buf);
991
  while ((p = va_arg(ap, const unsigned char *) ) != NULL) {
992
    size_t len = va_arg(ap, size_t);
993
    MD5_Update(&ctx, p, len);
994
  }
995
  va_end(ap);
996

    
997
  MD5_Final(hash, &ctx);
998
  cs_to_hex(buf, hash, sizeof(hash));
999

    
1000
  return buf;
1001
}
1002

    
1003
#endif /* EXCLUDE_COMMON */
1004
#ifdef MG_MODULE_LINES
1005
#line 1 "common/mbuf.c"
1006
#endif
1007
/*
1008
 * Copyright (c) 2014 Cesanta Software Limited
1009
 * All rights reserved
1010
 */
1011

    
1012
#ifndef EXCLUDE_COMMON
1013

    
1014
#include <assert.h>
1015
#include <string.h>
1016
/* Amalgamated: #include "common/mbuf.h" */
1017

    
1018
#ifndef MBUF_REALLOC
1019
#define MBUF_REALLOC realloc
1020
#endif
1021

    
1022
#ifndef MBUF_FREE
1023
#define MBUF_FREE free
1024
#endif
1025

    
1026
void mbuf_init(struct mbuf *mbuf, size_t initial_size) WEAK;
1027
void mbuf_init(struct mbuf *mbuf, size_t initial_size) {
1028
  mbuf->len = mbuf->size = 0;
1029
  mbuf->buf = NULL;
1030
  mbuf_resize(mbuf, initial_size);
1031
}
1032

    
1033
void mbuf_free(struct mbuf *mbuf) WEAK;
1034
void mbuf_free(struct mbuf *mbuf) {
1035
  if (mbuf->buf != NULL) {
1036
    MBUF_FREE(mbuf->buf);
1037
    mbuf_init(mbuf, 0);
1038
  }
1039
}
1040

    
1041
void mbuf_resize(struct mbuf *a, size_t new_size) WEAK;
1042
void mbuf_resize(struct mbuf *a, size_t new_size) {
1043
  if (new_size > a->size || (new_size < a->size && new_size >= a->len)) {
1044
    char *buf = (char *) MBUF_REALLOC(a->buf, new_size);
1045
    /*
1046
     * In case realloc fails, there's not much we can do, except keep things as
1047
     * they are. Note that NULL is a valid return value from realloc when
1048
     * size == 0, but that is covered too.
1049
     */
1050
    if (buf == NULL && new_size != 0) return;
1051
    a->buf = buf;
1052
    a->size = new_size;
1053
  }
1054
}
1055

    
1056
void mbuf_trim(struct mbuf *mbuf) WEAK;
1057
void mbuf_trim(struct mbuf *mbuf) {
1058
  mbuf_resize(mbuf, mbuf->len);
1059
}
1060

    
1061
size_t mbuf_insert(struct mbuf *a, size_t off, const void *buf, size_t) WEAK;
1062
size_t mbuf_insert(struct mbuf *a, size_t off, const void *buf, size_t len) {
1063
  char *p = NULL;
1064

    
1065
  assert(a != NULL);
1066
  assert(a->len <= a->size);
1067
  assert(off <= a->len);
1068

    
1069
  /* check overflow */
1070
  if (~(size_t) 0 - (size_t) a->buf < len) return 0;
1071

    
1072
  if (a->len + len <= a->size) {
1073
    memmove(a->buf + off + len, a->buf + off, a->len - off);
1074
    if (buf != NULL) {
1075
      memcpy(a->buf + off, buf, len);
1076
    }
1077
    a->len += len;
1078
  } else {
1079
    size_t new_size = (size_t)((a->len + len) * MBUF_SIZE_MULTIPLIER);
1080
    if ((p = (char *) MBUF_REALLOC(a->buf, new_size)) != NULL) {
1081
      a->buf = p;
1082
      memmove(a->buf + off + len, a->buf + off, a->len - off);
1083
      if (buf != NULL) memcpy(a->buf + off, buf, len);
1084
      a->len += len;
1085
      a->size = new_size;
1086
    } else {
1087
      len = 0;
1088
    }
1089
  }
1090

    
1091
  return len;
1092
}
1093

    
1094
size_t mbuf_append(struct mbuf *a, const void *buf, size_t len) WEAK;
1095
size_t mbuf_append(struct mbuf *a, const void *buf, size_t len) {
1096
  return mbuf_insert(a, a->len, buf, len);
1097
}
1098

    
1099
void mbuf_remove(struct mbuf *mb, size_t n) WEAK;
1100
void mbuf_remove(struct mbuf *mb, size_t n) {
1101
  if (n > 0 && n <= mb->len) {
1102
    memmove(mb->buf, mb->buf + n, mb->len - n);
1103
    mb->len -= n;
1104
  }
1105
}
1106

    
1107
#endif /* EXCLUDE_COMMON */
1108
#ifdef MG_MODULE_LINES
1109
#line 1 "common/mg_str.c"
1110
#endif
1111
/*
1112
 * Copyright (c) 2014-2016 Cesanta Software Limited
1113
 * All rights reserved
1114
 */
1115

    
1116
/* Amalgamated: #include "common/mg_str.h" */
1117

    
1118
#include <stdlib.h>
1119
#include <string.h>
1120

    
1121
int mg_ncasecmp(const char *s1, const char *s2, size_t len) WEAK;
1122

    
1123
struct mg_str mg_mk_str(const char *s) WEAK;
1124
struct mg_str mg_mk_str(const char *s) {
1125
  struct mg_str ret = {s, 0};
1126
  if (s != NULL) ret.len = strlen(s);
1127
  return ret;
1128
}
1129

    
1130
struct mg_str mg_mk_str_n(const char *s, size_t len) WEAK;
1131
struct mg_str mg_mk_str_n(const char *s, size_t len) {
1132
  struct mg_str ret = {s, len};
1133
  return ret;
1134
}
1135

    
1136
int mg_vcmp(const struct mg_str *str1, const char *str2) WEAK;
1137
int mg_vcmp(const struct mg_str *str1, const char *str2) {
1138
  size_t n2 = strlen(str2), n1 = str1->len;
1139
  int r = memcmp(str1->p, str2, (n1 < n2) ? n1 : n2);
1140
  if (r == 0) {
1141
    return n1 - n2;
1142
  }
1143
  return r;
1144
}
1145

    
1146
int mg_vcasecmp(const struct mg_str *str1, const char *str2) WEAK;
1147
int mg_vcasecmp(const struct mg_str *str1, const char *str2) {
1148
  size_t n2 = strlen(str2), n1 = str1->len;
1149
  int r = mg_ncasecmp(str1->p, str2, (n1 < n2) ? n1 : n2);
1150
  if (r == 0) {
1151
    return n1 - n2;
1152
  }
1153
  return r;
1154
}
1155

    
1156
struct mg_str mg_strdup(const struct mg_str s) WEAK;
1157
struct mg_str mg_strdup(const struct mg_str s) {
1158
  struct mg_str r = {NULL, 0};
1159
  if (s.len > 0 && s.p != NULL) {
1160
    r.p = (char *) malloc(s.len);
1161
    if (r.p != NULL) {
1162
      memcpy((char *) r.p, s.p, s.len);
1163
      r.len = s.len;
1164
    }
1165
  }
1166
  return r;
1167
}
1168

    
1169
int mg_strcmp(const struct mg_str str1, const struct mg_str str2) WEAK;
1170
int mg_strcmp(const struct mg_str str1, const struct mg_str str2) {
1171
  size_t i = 0;
1172
  while (i < str1.len && i < str2.len) {
1173
    if (str1.p[i] < str2.p[i]) return -1;
1174
    if (str1.p[i] > str2.p[i]) return 1;
1175
    i++;
1176
  }
1177
  if (i < str1.len) return 1;
1178
  if (i < str2.len) return -1;
1179
  return 0;
1180
}
1181

    
1182
int mg_strncmp(const struct mg_str, const struct mg_str, size_t n) WEAK;
1183
int mg_strncmp(const struct mg_str str1, const struct mg_str str2, size_t n) {
1184
  struct mg_str s1 = str1;
1185
  struct mg_str s2 = str2;
1186

    
1187
  if (s1.len > n) {
1188
    s1.len = n;
1189
  }
1190
  if (s2.len > n) {
1191
    s2.len = n;
1192
  }
1193
  return mg_strcmp(s1, s2);
1194
}
1195
#ifdef MG_MODULE_LINES
1196
#line 1 "common/sha1.c"
1197
#endif
1198
/* Copyright(c) By Steve Reid <steve@edmweb.com> */
1199
/* 100% Public Domain */
1200

    
1201
/* Amalgamated: #include "common/sha1.h" */
1202

    
1203
#if !DISABLE_SHA1 && !defined(EXCLUDE_COMMON)
1204

    
1205
/* Amalgamated: #include "common/cs_endian.h" */
1206

    
1207
#define SHA1HANDSOFF
1208
#if defined(__sun)
1209
/* Amalgamated: #include "common/solarisfixes.h" */
1210
#endif
1211

    
1212
union char64long16 {
1213
  unsigned char c[64];
1214
  uint32_t l[16];
1215
};
1216

    
1217
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
1218

    
1219
static uint32_t blk0(union char64long16 *block, int i) {
1220
/* Forrest: SHA expect BIG_ENDIAN, swap if LITTLE_ENDIAN */
1221
#if BYTE_ORDER == LITTLE_ENDIAN
1222
  block->l[i] =
1223
      (rol(block->l[i], 24) & 0xFF00FF00) | (rol(block->l[i], 8) & 0x00FF00FF);
1224
#endif
1225
  return block->l[i];
1226
}
1227

    
1228
/* Avoid redefine warning (ARM /usr/include/sys/ucontext.h define R0~R4) */
1229
#undef blk
1230
#undef R0
1231
#undef R1
1232
#undef R2
1233
#undef R3
1234
#undef R4
1235

    
1236
#define blk(i)                                                               \
1237
  (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ block->l[(i + 8) & 15] ^ \
1238
                              block->l[(i + 2) & 15] ^ block->l[i & 15],     \
1239
                          1))
1240
#define R0(v, w, x, y, z, i)                                          \
1241
  z += ((w & (x ^ y)) ^ y) + blk0(block, i) + 0x5A827999 + rol(v, 5); \
1242
  w = rol(w, 30);
1243
#define R1(v, w, x, y, z, i)                                  \
1244
  z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
1245
  w = rol(w, 30);
1246
#define R2(v, w, x, y, z, i)                          \
1247
  z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); \
1248
  w = rol(w, 30);
1249
#define R3(v, w, x, y, z, i)                                        \
1250
  z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
1251
  w = rol(w, 30);
1252
#define R4(v, w, x, y, z, i)                          \
1253
  z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
1254
  w = rol(w, 30);
1255

    
1256
void cs_sha1_transform(uint32_t state[5], const unsigned char buffer[64]) {
1257
  uint32_t a, b, c, d, e;
1258
  union char64long16 block[1];
1259

    
1260
  memcpy(block, buffer, 64);
1261
  a = state[0];
1262
  b = state[1];
1263
  c = state[2];
1264
  d = state[3];
1265
  e = state[4];
1266
  R0(a, b, c, d, e, 0);
1267
  R0(e, a, b, c, d, 1);
1268
  R0(d, e, a, b, c, 2);
1269
  R0(c, d, e, a, b, 3);
1270
  R0(b, c, d, e, a, 4);
1271
  R0(a, b, c, d, e, 5);
1272
  R0(e, a, b, c, d, 6);
1273
  R0(d, e, a, b, c, 7);
1274
  R0(c, d, e, a, b, 8);
1275
  R0(b, c, d, e, a, 9);
1276
  R0(a, b, c, d, e, 10);
1277
  R0(e, a, b, c, d, 11);
1278
  R0(d, e, a, b, c, 12);
1279
  R0(c, d, e, a, b, 13);
1280
  R0(b, c, d, e, a, 14);
1281
  R0(a, b, c, d, e, 15);
1282
  R1(e, a, b, c, d, 16);
1283
  R1(d, e, a, b, c, 17);
1284
  R1(c, d, e, a, b, 18);
1285
  R1(b, c, d, e, a, 19);
1286
  R2(a, b, c, d, e, 20);
1287
  R2(e, a, b, c, d, 21);
1288
  R2(d, e, a, b, c, 22);
1289
  R2(c, d, e, a, b, 23);
1290
  R2(b, c, d, e, a, 24);
1291
  R2(a, b, c, d, e, 25);
1292
  R2(e, a, b, c, d, 26);
1293
  R2(d, e, a, b, c, 27);
1294
  R2(c, d, e, a, b, 28);
1295
  R2(b, c, d, e, a, 29);
1296
  R2(a, b, c, d, e, 30);
1297
  R2(e, a, b, c, d, 31);
1298
  R2(d, e, a, b, c, 32);
1299
  R2(c, d, e, a, b, 33);
1300
  R2(b, c, d, e, a, 34);
1301
  R2(a, b, c, d, e, 35);
1302
  R2(e, a, b, c, d, 36);
1303
  R2(d, e, a, b, c, 37);
1304
  R2(c, d, e, a, b, 38);
1305
  R2(b, c, d, e, a, 39);
1306
  R3(a, b, c, d, e, 40);
1307
  R3(e, a, b, c, d, 41);
1308
  R3(d, e, a, b, c, 42);
1309
  R3(c, d, e, a, b, 43);
1310
  R3(b, c, d, e, a, 44);
1311
  R3(a, b, c, d, e, 45);
1312
  R3(e, a, b, c, d, 46);
1313
  R3(d, e, a, b, c, 47);
1314
  R3(c, d, e, a, b, 48);
1315
  R3(b, c, d, e, a, 49);
1316
  R3(a, b, c, d, e, 50);
1317
  R3(e, a, b, c, d, 51);
1318
  R3(d, e, a, b, c, 52);
1319
  R3(c, d, e, a, b, 53);
1320
  R3(b, c, d, e, a, 54);
1321
  R3(a, b, c, d, e, 55);
1322
  R3(e, a, b, c, d, 56);
1323
  R3(d, e, a, b, c, 57);
1324
  R3(c, d, e, a, b, 58);
1325
  R3(b, c, d, e, a, 59);
1326
  R4(a, b, c, d, e, 60);
1327
  R4(e, a, b, c, d, 61);
1328
  R4(d, e, a, b, c, 62);
1329
  R4(c, d, e, a, b, 63);
1330
  R4(b, c, d, e, a, 64);
1331
  R4(a, b, c, d, e, 65);
1332
  R4(e, a, b, c, d, 66);
1333
  R4(d, e, a, b, c, 67);
1334
  R4(c, d, e, a, b, 68);
1335
  R4(b, c, d, e, a, 69);
1336
  R4(a, b, c, d, e, 70);
1337
  R4(e, a, b, c, d, 71);
1338
  R4(d, e, a, b, c, 72);
1339
  R4(c, d, e, a, b, 73);
1340
  R4(b, c, d, e, a, 74);
1341
  R4(a, b, c, d, e, 75);
1342
  R4(e, a, b, c, d, 76);
1343
  R4(d, e, a, b, c, 77);
1344
  R4(c, d, e, a, b, 78);
1345
  R4(b, c, d, e, a, 79);
1346
  state[0] += a;
1347
  state[1] += b;
1348
  state[2] += c;
1349
  state[3] += d;
1350
  state[4] += e;
1351
  /* Erase working structures. The order of operations is important,
1352
   * used to ensure that compiler doesn't optimize those out. */
1353
  memset(block, 0, sizeof(block));
1354
  a = b = c = d = e = 0;
1355
  (void) a;
1356
  (void) b;
1357
  (void) c;
1358
  (void) d;
1359
  (void) e;
1360
}
1361

    
1362
void cs_sha1_init(cs_sha1_ctx *context) {
1363
  context->state[0] = 0x67452301;
1364
  context->state[1] = 0xEFCDAB89;
1365
  context->state[2] = 0x98BADCFE;
1366
  context->state[3] = 0x10325476;
1367
  context->state[4] = 0xC3D2E1F0;
1368
  context->count[0] = context->count[1] = 0;
1369
}
1370

    
1371
void cs_sha1_update(cs_sha1_ctx *context, const unsigned char *data,
1372
                    uint32_t len) {
1373
  uint32_t i, j;
1374

    
1375
  j = context->count[0];
1376
  if ((context->count[0] += len << 3) < j) context->count[1]++;
1377
  context->count[1] += (len >> 29);
1378
  j = (j >> 3) & 63;
1379
  if ((j + len) > 63) {
1380
    memcpy(&context->buffer[j], data, (i = 64 - j));
1381
    cs_sha1_transform(context->state, context->buffer);
1382
    for (; i + 63 < len; i += 64) {
1383
      cs_sha1_transform(context->state, &data[i]);
1384
    }
1385
    j = 0;
1386
  } else
1387
    i = 0;
1388
  memcpy(&context->buffer[j], &data[i], len - i);
1389
}
1390

    
1391
void cs_sha1_final(unsigned char digest[20], cs_sha1_ctx *context) {
1392
  unsigned i;
1393
  unsigned char finalcount[8], c;
1394

    
1395
  for (i = 0; i < 8; i++) {
1396
    finalcount[i] = (unsigned char) ((context->count[(i >= 4 ? 0 : 1)] >>
1397
                                      ((3 - (i & 3)) * 8)) &
1398
                                     255);
1399
  }
1400
  c = 0200;
1401
  cs_sha1_update(context, &c, 1);
1402
  while ((context->count[0] & 504) != 448) {
1403
    c = 0000;
1404
    cs_sha1_update(context, &c, 1);
1405
  }
1406
  cs_sha1_update(context, finalcount, 8);
1407
  for (i = 0; i < 20; i++) {
1408
    digest[i] =
1409
        (unsigned char) ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
1410
  }
1411
  memset(context, '\0', sizeof(*context));
1412
  memset(&finalcount, '\0', sizeof(finalcount));
1413
}
1414

    
1415
void cs_hmac_sha1(const unsigned char *key, size_t keylen,
1416
                  const unsigned char *data, size_t datalen,
1417
                  unsigned char out[20]) {
1418
  cs_sha1_ctx ctx;
1419
  unsigned char buf1[64], buf2[64], tmp_key[20], i;
1420

    
1421
  if (keylen > sizeof(buf1)) {
1422
    cs_sha1_init(&ctx);
1423
    cs_sha1_update(&ctx, key, keylen);
1424
    cs_sha1_final(tmp_key, &ctx);
1425
    key = tmp_key;
1426
    keylen = sizeof(tmp_key);
1427
  }
1428

    
1429
  memset(buf1, 0, sizeof(buf1));
1430
  memset(buf2, 0, sizeof(buf2));
1431
  memcpy(buf1, key, keylen);
1432
  memcpy(buf2, key, keylen);
1433

    
1434
  for (i = 0; i < sizeof(buf1); i++) {
1435
    buf1[i] ^= 0x36;
1436
    buf2[i] ^= 0x5c;
1437
  }
1438

    
1439
  cs_sha1_init(&ctx);
1440
  cs_sha1_update(&ctx, buf1, sizeof(buf1));
1441
  cs_sha1_update(&ctx, data, datalen);
1442
  cs_sha1_final(out, &ctx);
1443

    
1444
  cs_sha1_init(&ctx);
1445
  cs_sha1_update(&ctx, buf2, sizeof(buf2));
1446
  cs_sha1_update(&ctx, out, 20);
1447
  cs_sha1_final(out, &ctx);
1448
}
1449

    
1450
#endif /* EXCLUDE_COMMON */
1451
#ifdef MG_MODULE_LINES
1452
#line 1 "common/str_util.c"
1453
#endif
1454
/*
1455
 * Copyright (c) 2015 Cesanta Software Limited
1456
 * All rights reserved
1457
 */
1458

    
1459
#ifndef EXCLUDE_COMMON
1460

    
1461
/* Amalgamated: #include "common/platform.h" */
1462
/* Amalgamated: #include "common/str_util.h" */
1463

    
1464
#ifndef C_DISABLE_BUILTIN_SNPRINTF
1465
#define C_DISABLE_BUILTIN_SNPRINTF 0
1466
#endif
1467

    
1468
#ifndef MG_MALLOC
1469
#define MG_MALLOC malloc
1470
#endif
1471

    
1472
#ifndef MG_FREE
1473
#define MG_FREE free
1474
#endif
1475

    
1476
size_t c_strnlen(const char *s, size_t maxlen) WEAK;
1477
size_t c_strnlen(const char *s, size_t maxlen) {
1478
  size_t l = 0;
1479
  for (; l < maxlen && s[l] != '\0'; l++) {
1480
  }
1481
  return l;
1482
}
1483

    
1484
#define C_SNPRINTF_APPEND_CHAR(ch)       \
1485
  do {                                   \
1486
    if (i < (int) buf_size) buf[i] = ch; \
1487
    i++;                                 \
1488
  } while (0)
1489

    
1490
#define C_SNPRINTF_FLAG_ZERO 1
1491

    
1492
#if C_DISABLE_BUILTIN_SNPRINTF
1493
int c_vsnprintf(char *buf, size_t buf_size, const char *fmt, va_list ap) WEAK;
1494
int c_vsnprintf(char *buf, size_t buf_size, const char *fmt, va_list ap) {
1495
  return vsnprintf(buf, buf_size, fmt, ap);
1496
}
1497
#else
1498
static int c_itoa(char *buf, size_t buf_size, int64_t num, int base, int flags,
1499
                  int field_width) {
1500
  char tmp[40];
1501
  int i = 0, k = 0, neg = 0;
1502

    
1503
  if (num < 0) {
1504
    neg++;
1505
    num = -num;
1506
  }
1507

    
1508
  /* Print into temporary buffer - in reverse order */
1509
  do {
1510
    int rem = num % base;
1511
    if (rem < 10) {
1512
      tmp[k++] = '0' + rem;
1513
    } else {
1514
      tmp[k++] = 'a' + (rem - 10);
1515
    }
1516
    num /= base;
1517
  } while (num > 0);
1518

    
1519
  /* Zero padding */
1520
  if (flags && C_SNPRINTF_FLAG_ZERO) {
1521
    while (k < field_width && k < (int) sizeof(tmp) - 1) {
1522
      tmp[k++] = '0';
1523
    }
1524
  }
1525

    
1526
  /* And sign */
1527
  if (neg) {
1528
    tmp[k++] = '-';
1529
  }
1530

    
1531
  /* Now output */
1532
  while (--k >= 0) {
1533
    C_SNPRINTF_APPEND_CHAR(tmp[k]);
1534
  }
1535

    
1536
  return i;
1537
}
1538

    
1539
int c_vsnprintf(char *buf, size_t buf_size, const char *fmt, va_list ap) WEAK;
1540
int c_vsnprintf(char *buf, size_t buf_size, const char *fmt, va_list ap) {
1541
  int ch, i = 0, len_mod, flags, precision, field_width;
1542

    
1543
  while ((ch = *fmt++) != '\0') {
1544
    if (ch != '%') {
1545
      C_SNPRINTF_APPEND_CHAR(ch);
1546
    } else {
1547
      /*
1548
       * Conversion specification:
1549
       *   zero or more flags (one of: # 0 - <space> + ')
1550
       *   an optional minimum  field  width (digits)
1551
       *   an  optional precision (. followed by digits, or *)
1552
       *   an optional length modifier (one of: hh h l ll L q j z t)
1553
       *   conversion specifier (one of: d i o u x X e E f F g G a A c s p n)
1554
       */
1555
      flags = field_width = precision = len_mod = 0;
1556

    
1557
      /* Flags. only zero-pad flag is supported. */
1558
      if (*fmt == '0') {
1559
        flags |= C_SNPRINTF_FLAG_ZERO;
1560
      }
1561

    
1562
      /* Field width */
1563
      while (*fmt >= '0' && *fmt <= '9') {
1564
        field_width *= 10;
1565
        field_width += *fmt++ - '0';
1566
      }
1567
      /* Dynamic field width */
1568
      if (*fmt == '*') {
1569
        field_width = va_arg(ap, int);
1570
        fmt++;
1571
      }
1572

    
1573
      /* Precision */
1574
      if (*fmt == '.') {
1575
        fmt++;
1576
        if (*fmt == '*') {
1577
          precision = va_arg(ap, int);
1578
          fmt++;
1579
        } else {
1580
          while (*fmt >= '0' && *fmt <= '9') {
1581
            precision *= 10;
1582
            precision += *fmt++ - '0';
1583
          }
1584
        }
1585
      }
1586

    
1587
      /* Length modifier */
1588
      switch (*fmt) {
1589
        case 'h':
1590
        case 'l':
1591
        case 'L':
1592
        case 'I':
1593
        case 'q':
1594
        case 'j':
1595
        case 'z':
1596
        case 't':
1597
          len_mod = *fmt++;
1598
          if (*fmt == 'h') {
1599
            len_mod = 'H';
1600
            fmt++;
1601
          }
1602
          if (*fmt == 'l') {
1603
            len_mod = 'q';
1604
            fmt++;
1605
          }
1606
          break;
1607
      }
1608

    
1609
      ch = *fmt++;
1610
      if (ch == 's') {
1611
        const char *s = va_arg(ap, const char *); /* Always fetch parameter */
1612
        int j;
1613
        int pad = field_width - (precision >= 0 ? c_strnlen(s, precision) : 0);
1614
        for (j = 0; j < pad; j++) {
1615
          C_SNPRINTF_APPEND_CHAR(' ');
1616
        }
1617

    
1618
        /* `s` may be NULL in case of %.*s */
1619
        if (s != NULL) {
1620
          /* Ignore negative and 0 precisions */
1621
          for (j = 0; (precision <= 0 || j < precision) && s[j] != '\0'; j++) {
1622
            C_SNPRINTF_APPEND_CHAR(s[j]);
1623
          }
1624
        }
1625
      } else if (ch == 'c') {
1626
        ch = va_arg(ap, int); /* Always fetch parameter */
1627
        C_SNPRINTF_APPEND_CHAR(ch);
1628
      } else if (ch == 'd' && len_mod == 0) {
1629
        i += c_itoa(buf + i, buf_size - i, va_arg(ap, int), 10, flags,
1630
                    field_width);
1631
      } else if (ch == 'd' && len_mod == 'l') {
1632
        i += c_itoa(buf + i, buf_size - i, va_arg(ap, long), 10, flags,
1633
                    field_width);
1634
#ifdef SSIZE_MAX
1635
      } else if (ch == 'd' && len_mod == 'z') {
1636
        i += c_itoa(buf + i, buf_size - i, va_arg(ap, ssize_t), 10, flags,
1637
                    field_width);
1638
#endif
1639
      } else if (ch == 'd' && len_mod == 'q') {
1640
        i += c_itoa(buf + i, buf_size - i, va_arg(ap, int64_t), 10, flags,
1641
                    field_width);
1642
      } else if ((ch == 'x' || ch == 'u') && len_mod == 0) {
1643
        i += c_itoa(buf + i, buf_size - i, va_arg(ap, unsigned),
1644
                    ch == 'x' ? 16 : 10, flags, field_width);
1645
      } else if ((ch == 'x' || ch == 'u') && len_mod == 'l') {
1646
        i += c_itoa(buf + i, buf_size - i, va_arg(ap, unsigned long),
1647
                    ch == 'x' ? 16 : 10, flags, field_width);
1648
      } else if ((ch == 'x' || ch == 'u') && len_mod == 'z') {
1649
        i += c_itoa(buf + i, buf_size - i, va_arg(ap, size_t),
1650
                    ch == 'x' ? 16 : 10, flags, field_width);
1651
      } else if (ch == 'p') {
1652
        unsigned long num = (unsigned long) (uintptr_t) va_arg(ap, void *);
1653
        C_SNPRINTF_APPEND_CHAR('0');
1654
        C_SNPRINTF_APPEND_CHAR('x');
1655
        i += c_itoa(buf + i, buf_size - i, num, 16, flags, 0);
1656
      } else {
1657
#ifndef NO_LIBC
1658
        /*
1659
         * TODO(lsm): abort is not nice in a library, remove it
1660
         * Also, ESP8266 SDK doesn't have it
1661
         */
1662
        abort();
1663
#endif
1664
      }
1665
    }
1666
  }
1667

    
1668
  /* Zero-terminate the result */
1669
  if (buf_size > 0) {
1670
    buf[i < (int) buf_size ? i : (int) buf_size - 1] = '\0';
1671
  }
1672

    
1673
  return i;
1674
}
1675
#endif
1676

    
1677
int c_snprintf(char *buf, size_t buf_size, const char *fmt, ...) WEAK;
1678
int c_snprintf(char *buf, size_t buf_size, const char *fmt, ...) {
1679
  int result;
1680
  va_list ap;
1681
  va_start(ap, fmt);
1682
  result = c_vsnprintf(buf, buf_size, fmt, ap);
1683
  va_end(ap);
1684
  return result;
1685
}
1686

    
1687
#ifdef _WIN32
1688
int to_wchar(const char *path, wchar_t *wbuf, size_t wbuf_len) {
1689
  int ret;
1690
  char buf[MAX_PATH * 2], buf2[MAX_PATH * 2], *p;
1691

    
1692
  strncpy(buf, path, sizeof(buf));
1693
  buf[sizeof(buf) - 1] = '\0';
1694

    
1695
  /* Trim trailing slashes. Leave backslash for paths like "X:\" */
1696
  p = buf + strlen(buf) - 1;
1697
  while (p > buf && p[-1] != ':' && (p[0] == '\\' || p[0] == '/')) *p-- = '\0';
1698

    
1699
  memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
1700
  ret = MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int) wbuf_len);
1701

    
1702
  /*
1703
   * Convert back to Unicode. If doubly-converted string does not match the
1704
   * original, something is fishy, reject.
1705
   */
1706
  WideCharToMultiByte(CP_UTF8, 0, wbuf, (int) wbuf_len, buf2, sizeof(buf2),
1707
                      NULL, NULL);
1708
  if (strcmp(buf, buf2) != 0) {
1709
    wbuf[0] = L'\0';
1710
    ret = 0;
1711
  }
1712

    
1713
  return ret;
1714
}
1715
#endif /* _WIN32 */
1716

    
1717
/* The simplest O(mn) algorithm. Better implementation are GPLed */
1718
const char *c_strnstr(const char *s, const char *find, size_t slen) WEAK;
1719
const char *c_strnstr(const char *s, const char *find, size_t slen) {
1720
  size_t find_length = strlen(find);
1721
  size_t i;
1722

    
1723
  for (i = 0; i < slen; i++) {
1724
    if (i + find_length > slen) {
1725
      return NULL;
1726
    }
1727

    
1728
    if (strncmp(&s[i], find, find_length) == 0) {
1729
      return &s[i];
1730
    }
1731
  }
1732

    
1733
  return NULL;
1734
}
1735

    
1736
#if CS_ENABLE_STRDUP
1737
char *strdup(const char *src) WEAK;
1738
char *strdup(const char *src) {
1739
  size_t len = strlen(src) + 1;
1740
  char *ret = malloc(len);
1741
  if (ret != NULL) {
1742
    strcpy(ret, src);
1743
  }
1744
  return ret;
1745
}
1746
#endif
1747

    
1748
void cs_to_hex(char *to, const unsigned char *p, size_t len) WEAK;
1749
void cs_to_hex(char *to, const unsigned char *p, size_t len) {
1750
  static const char *hex = "0123456789abcdef";
1751

    
1752
  for (; len--; p++) {
1753
    *to++ = hex[p[0] >> 4];
1754
    *to++ = hex[p[0] & 0x0f];
1755
  }
1756
  *to = '\0';
1757
}
1758

    
1759
static int fourbit(int ch) {
1760
  if (ch >= '0' && ch <= '9') {
1761
    return ch - '0';
1762
  } else if (ch >= 'a' && ch <= 'f') {
1763
    return ch - 'a' + 10;
1764
  } else if (ch >= 'A' && ch <= 'F') {
1765
    return ch - 'A' + 10;
1766
  }
1767
  return 0;
1768
}
1769

    
1770
void cs_from_hex(char *to, const char *p, size_t len) WEAK;
1771
void cs_from_hex(char *to, const char *p, size_t len) {
1772
  size_t i;
1773

    
1774
  for (i = 0; i < len; i += 2) {
1775
    *to++ = (fourbit(p[i]) << 4) + fourbit(p[i + 1]);
1776
  }
1777
  *to = '\0';
1778
}
1779

    
1780
#if CS_ENABLE_TO64
1781
int64_t cs_to64(const char *s) WEAK;
1782
int64_t cs_to64(const char *s) {
1783
  int64_t result = 0;
1784
  int64_t neg = 1;
1785
  while (*s && isspace((unsigned char) *s)) s++;
1786
  if (*s == '-') {
1787
    neg = -1;
1788
    s++;
1789
  }
1790
  while (isdigit((unsigned char) *s)) {
1791
    result *= 10;
1792
    result += (*s - '0');
1793
    s++;
1794
  }
1795
  return result * neg;
1796
}
1797
#endif
1798

    
1799
static int str_util_lowercase(const char *s) {
1800
  return tolower(*(const unsigned char *) s);
1801
}
1802

    
1803
int mg_ncasecmp(const char *s1, const char *s2, size_t len) WEAK;
1804
int mg_ncasecmp(const char *s1, const char *s2, size_t len) {
1805
  int diff = 0;
1806

    
1807
  if (len > 0) do {
1808
      diff = str_util_lowercase(s1++) - str_util_lowercase(s2++);
1809
    } while (diff == 0 && s1[-1] != '\0' && --len > 0);
1810

    
1811
  return diff;
1812
}
1813

    
1814
int mg_casecmp(const char *s1, const char *s2) WEAK;
1815
int mg_casecmp(const char *s1, const char *s2) {
1816
  return mg_ncasecmp(s1, s2, (size_t) ~0);
1817
}
1818

    
1819
int mg_asprintf(char **buf, size_t size, const char *fmt, ...) WEAK;
1820
int mg_asprintf(char **buf, size_t size, const char *fmt, ...) {
1821
  int ret;
1822
  va_list ap;
1823
  va_start(ap, fmt);
1824
  ret = mg_avprintf(buf, size, fmt, ap);
1825
  va_end(ap);
1826
  return ret;
1827
}
1828

    
1829
int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap) WEAK;
1830
int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap) {
1831
  va_list ap_copy;
1832
  int len;
1833

    
1834
  va_copy(ap_copy, ap);
1835
  len = vsnprintf(*buf, size, fmt, ap_copy);
1836
  va_end(ap_copy);
1837

    
1838
  if (len < 0) {
1839
    /* eCos and Windows are not standard-compliant and return -1 when
1840
     * the buffer is too small. Keep allocating larger buffers until we
1841
     * succeed or out of memory. */
1842
    *buf = NULL; /* LCOV_EXCL_START */
1843
    while (len < 0) {
1844
      MG_FREE(*buf);
1845
      size *= 2;
1846
      if ((*buf = (char *) MG_MALLOC(size)) == NULL) break;
1847
      va_copy(ap_copy, ap);
1848
      len = vsnprintf(*buf, size, fmt, ap_copy);
1849
      va_end(ap_copy);
1850
    }
1851
    /* LCOV_EXCL_STOP */
1852
  } else if (len >= (int) size) {
1853
    /* Standard-compliant code path. Allocate a buffer that is large enough. */
1854
    if ((*buf = (char *) MG_MALLOC(len + 1)) == NULL) {
1855
      len = -1; /* LCOV_EXCL_LINE */
1856
    } else {    /* LCOV_EXCL_LINE */
1857
      va_copy(ap_copy, ap);
1858
      len = vsnprintf(*buf, len + 1, fmt, ap_copy);
1859
      va_end(ap_copy);
1860
    }
1861
  }
1862

    
1863
  return len;
1864
}
1865

    
1866
#endif /* EXCLUDE_COMMON */
1867
#ifdef MG_MODULE_LINES
1868
#line 1 "mongoose/src/tun.h"
1869
#endif
1870
/*
1871
 * Copyright (c) 2014-2016 Cesanta Software Limited
1872
 * All rights reserved
1873
 */
1874

    
1875
#ifndef CS_MONGOOSE_SRC_TUN_H_
1876
#define CS_MONGOOSE_SRC_TUN_H_
1877

    
1878
#if MG_ENABLE_TUN
1879

    
1880
/* Amalgamated: #include "mongoose/src/net.h" */
1881
/* Amalgamated: #include "common/mg_str.h" */
1882

    
1883
#ifndef MG_TUN_RECONNECT_INTERVAL
1884
#define MG_TUN_RECONNECT_INTERVAL 1
1885
#endif
1886

    
1887
#define MG_TUN_PROTO_NAME "mg_tun"
1888

    
1889
#define MG_TUN_DATA_FRAME 0x0
1890
#define MG_TUN_F_END_STREAM 0x1
1891

    
1892
/*
1893
 * MG TUN frame format is loosely based on HTTP/2.
1894
 * However since the communication happens via WebSocket
1895
 * there is no need to encode the frame length, since that's
1896
 * solved by WebSocket framing.
1897
 *
1898
 * TODO(mkm): Detailed description of the protocol.
1899
 */
1900
struct mg_tun_frame {
1901
  uint8_t type;
1902
  uint8_t flags;
1903
  uint32_t stream_id; /* opaque stream identifier */
1904
  struct mg_str body;
1905
};
1906

    
1907
struct mg_tun_ssl_opts {
1908
#if MG_ENABLE_SSL
1909
  const char *ssl_cert;
1910
  const char *ssl_key;
1911
  const char *ssl_ca_cert;
1912
#else
1913
  int dummy; /* some compilers don't like empty structs */
1914
#endif
1915
};
1916

    
1917
struct mg_tun_client {
1918
  struct mg_mgr *mgr;
1919
  struct mg_iface *iface;
1920
  const char *disp_url;
1921
  struct mg_tun_ssl_opts ssl;
1922

    
1923
  uint32_t last_stream_id; /* stream id of most recently accepted connection */
1924

    
1925
  struct mg_connection *disp;
1926
  struct mg_connection *listener;
1927
  struct mg_connection *reconnect;
1928
};
1929

    
1930
#ifdef __cplusplus
1931
extern "C" {
1932
#endif /* __cplusplus */
1933

    
1934
struct mg_connection *mg_tun_bind_opt(struct mg_mgr *mgr,
1935
                                      const char *dispatcher,
1936
                                      mg_event_handler_t handler,
1937
                                      struct mg_bind_opts opts);
1938

    
1939
int mg_tun_parse_frame(void *data, size_t len, struct mg_tun_frame *frame);
1940

    
1941
void mg_tun_send_frame(struct mg_connection *ws, uint32_t stream_id,
1942
                       uint8_t type, uint8_t flags, struct mg_str msg);
1943

    
1944
void mg_tun_destroy_client(struct mg_tun_client *client);
1945

    
1946
#ifdef __cplusplus
1947
}
1948
#endif /* __cplusplus */
1949

    
1950
#endif /* MG_ENABLE_TUN */
1951

    
1952
#endif /* CS_MONGOOSE_SRC_TUN_H_ */
1953
#ifdef MG_MODULE_LINES
1954
#line 1 "mongoose/src/net.c"
1955
#endif
1956
/*
1957
 * Copyright (c) 2014 Cesanta Software Limited
1958
 * All rights reserved
1959
 *
1960
 * This software is dual-licensed: you can redistribute it and/or modify
1961
 * it under the terms of the GNU General Public License version 2 as
1962
 * published by the Free Software Foundation. For the terms of this
1963
 * license, see <http://www.gnu.org/licenses/>.
1964
 *
1965
 * You are free to use this software under the terms of the GNU General
1966
 * Public License, but WITHOUT ANY WARRANTY; without even the implied
1967
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1968
 * See the GNU General Public License for more details.
1969
 *
1970
 * Alternatively, you can license this software under a commercial
1971
 * license, as set out in <https://www.cesanta.com/license>.
1972
 */
1973

    
1974
/* Amalgamated: #include "common/cs_time.h" */
1975
/* Amalgamated: #include "mongoose/src/dns.h" */
1976
/* Amalgamated: #include "mongoose/src/internal.h" */
1977
/* Amalgamated: #include "mongoose/src/resolv.h" */
1978
/* Amalgamated: #include "mongoose/src/util.h" */
1979
/* Amalgamated: #include "mongoose/src/tun.h" */
1980

    
1981
#define MG_MAX_HOST_LEN 200
1982

    
1983
#define MG_COPY_COMMON_CONNECTION_OPTIONS(dst, src) \
1984
  memcpy(dst, src, sizeof(*dst));
1985

    
1986
/* Which flags can be pre-set by the user at connection creation time. */
1987
#define _MG_ALLOWED_CONNECT_FLAGS_MASK                                   \
1988
  (MG_F_USER_1 | MG_F_USER_2 | MG_F_USER_3 | MG_F_USER_4 | MG_F_USER_5 | \
1989
   MG_F_USER_6 | MG_F_WEBSOCKET_NO_DEFRAG | MG_F_ENABLE_BROADCAST)
1990
/* Which flags should be modifiable by user's callbacks. */
1991
#define _MG_CALLBACK_MODIFIABLE_FLAGS_MASK                               \
1992
  (MG_F_USER_1 | MG_F_USER_2 | MG_F_USER_3 | MG_F_USER_4 | MG_F_USER_5 | \
1993
   MG_F_USER_6 | MG_F_WEBSOCKET_NO_DEFRAG | MG_F_SEND_AND_CLOSE |        \
1994
   MG_F_CLOSE_IMMEDIATELY | MG_F_IS_WEBSOCKET | MG_F_DELETE_CHUNK)
1995

    
1996
#ifndef intptr_t
1997
#define intptr_t long
1998
#endif
1999

    
2000
MG_INTERNAL void mg_add_conn(struct mg_mgr *mgr, struct mg_connection *c) {
2001
  DBG(("%p %p", mgr, c));
2002
  c->mgr = mgr;
2003
  c->next = mgr->active_connections;
2004
  mgr->active_connections = c;
2005
  c->prev = NULL;
2006
  if (c->next != NULL) c->next->prev = c;
2007
  if (c->sock != INVALID_SOCKET) {
2008
    c->iface->vtable->add_conn(c);
2009
  }
2010
}
2011

    
2012
MG_INTERNAL void mg_remove_conn(struct mg_connection *conn) {
2013
  if (conn->prev == NULL) conn->mgr->active_connections = conn->next;
2014
  if (conn->prev) conn->prev->next = conn->next;
2015
  if (conn->next) conn->next->prev = conn->prev;
2016
  conn->iface->vtable->remove_conn(conn);
2017
}
2018

    
2019
MG_INTERNAL void mg_call(struct mg_connection *nc,
2020
                         mg_event_handler_t ev_handler, int ev, void *ev_data) {
2021
  if (ev_handler == NULL) {
2022
    /*
2023
     * If protocol handler is specified, call it. Otherwise, call user-specified
2024
     * event handler.
2025
     */
2026
    ev_handler = nc->proto_handler ? nc->proto_handler : nc->handler;
2027
  }
2028
  if (ev != MG_EV_POLL) {
2029
    DBG(("%p %s ev=%d ev_data=%p flags=%lu rmbl=%d smbl=%d", nc,
2030
         ev_handler == nc->handler ? "user" : "proto", ev, ev_data, nc->flags,
2031
         (int) nc->recv_mbuf.len, (int) nc->send_mbuf.len));
2032
  }
2033

    
2034
#if !defined(NO_LIBC) && MG_ENABLE_HEXDUMP
2035
  /* LCOV_EXCL_START */
2036
  if (nc->mgr->hexdump_file != NULL && ev != MG_EV_POLL &&
2037
      ev != MG_EV_SEND /* handled separately */) {
2038
    if (ev == MG_EV_RECV) {
2039
      mg_hexdump_connection(nc, nc->mgr->hexdump_file, nc->recv_mbuf.buf,
2040
                            *(int *) ev_data, ev);
2041
    } else {
2042
      mg_hexdump_connection(nc, nc->mgr->hexdump_file, NULL, 0, ev);
2043
    }
2044
  }
2045
/* LCOV_EXCL_STOP */
2046
#endif
2047
  if (ev_handler != NULL) {
2048
    unsigned long flags_before = nc->flags;
2049
    size_t recv_mbuf_before = nc->recv_mbuf.len, recved;
2050
    ev_handler(nc, ev, ev_data);
2051
    recved = (recv_mbuf_before - nc->recv_mbuf.len);
2052
    /* Prevent user handler from fiddling with system flags. */
2053
    if (ev_handler == nc->handler && nc->flags != flags_before) {
2054
      nc->flags = (flags_before & ~_MG_CALLBACK_MODIFIABLE_FLAGS_MASK) |
2055
                  (nc->flags & _MG_CALLBACK_MODIFIABLE_FLAGS_MASK);
2056
    }
2057
    if (recved > 0 && !(nc->flags & MG_F_UDP)) {
2058
      nc->iface->vtable->recved(nc, recved);
2059
    }
2060
  }
2061
  if (ev != MG_EV_POLL) {
2062
    DBG(("%p after %s flags=%lu rmbl=%d smbl=%d", nc,
2063
         ev_handler == nc->handler ? "user" : "proto", nc->flags,
2064
         (int) nc->recv_mbuf.len, (int) nc->send_mbuf.len));
2065
  }
2066
}
2067

    
2068
void mg_if_timer(struct mg_connection *c, double now) {
2069
  if (c->ev_timer_time > 0 && now >= c->ev_timer_time) {
2070
    double old_value = c->ev_timer_time;
2071
    mg_call(c, NULL, MG_EV_TIMER, &now);
2072
    /*
2073
     * To prevent timer firing all the time, reset the timer after delivery.
2074
     * However, in case user sets it to new value, do not reset.
2075
     */
2076
    if (c->ev_timer_time == old_value) {
2077
      c->ev_timer_time = 0;
2078
    }
2079
  }
2080
}
2081

    
2082
void mg_if_poll(struct mg_connection *nc, time_t now) {
2083
  if (!(nc->flags & MG_F_SSL) || (nc->flags & MG_F_SSL_HANDSHAKE_DONE)) {
2084
    mg_call(nc, NULL, MG_EV_POLL, &now);
2085
  }
2086
}
2087

    
2088
static void mg_destroy_conn(struct mg_connection *conn, int destroy_if) {
2089
  if (destroy_if) conn->iface->vtable->destroy_conn(conn);
2090
  if (conn->proto_data != NULL && conn->proto_data_destructor != NULL) {
2091
    conn->proto_data_destructor(conn->proto_data);
2092
  }
2093
#if MG_ENABLE_SSL
2094
  mg_ssl_if_conn_free(conn);
2095
#endif
2096
  mbuf_free(&conn->recv_mbuf);
2097
  mbuf_free(&conn->send_mbuf);
2098

    
2099
  memset(conn, 0, sizeof(*conn));
2100
  MG_FREE(conn);
2101
}
2102

    
2103
void mg_close_conn(struct mg_connection *conn) {
2104
  DBG(("%p %lu %d", conn, conn->flags, conn->sock));
2105
  mg_remove_conn(conn);
2106
  conn->iface->vtable->destroy_conn(conn);
2107
  mg_call(conn, NULL, MG_EV_CLOSE, NULL);
2108
  mg_destroy_conn(conn, 0 /* destroy_if */);
2109
}
2110

    
2111
void mg_mgr_init(struct mg_mgr *m, void *user_data) {
2112
  struct mg_mgr_init_opts opts;
2113
  memset(&opts, 0, sizeof(opts));
2114
  mg_mgr_init_opt(m, user_data, opts);
2115
}
2116

    
2117
void mg_mgr_init_opt(struct mg_mgr *m, void *user_data,
2118
                     struct mg_mgr_init_opts opts) {
2119
  memset(m, 0, sizeof(*m));
2120
#if MG_ENABLE_BROADCAST
2121
  m->ctl[0] = m->ctl[1] = INVALID_SOCKET;
2122
#endif
2123
  m->user_data = user_data;
2124

    
2125
#ifdef _WIN32
2126
  {
2127
    WSADATA data;
2128
    WSAStartup(MAKEWORD(2, 2), &data);
2129
  }
2130
#elif defined(__unix__)
2131
  /* Ignore SIGPIPE signal, so if client cancels the request, it
2132
   * won't kill the whole process. */
2133
  signal(SIGPIPE, SIG_IGN);
2134
#endif
2135

    
2136
#if MG_ENABLE_SSL
2137
  {
2138
    static int init_done;
2139
    if (!init_done) {
2140
      mg_ssl_if_init();
2141
      init_done++;
2142
    }
2143
  }
2144
#endif
2145
  {
2146
    int i;
2147
    if (opts.num_ifaces == 0) {
2148
      opts.num_ifaces = mg_num_ifaces;
2149
      opts.ifaces = mg_ifaces;
2150
    }
2151
    if (opts.main_iface != NULL) {
2152
      opts.ifaces[MG_MAIN_IFACE] = opts.main_iface;
2153
    }
2154
    m->num_ifaces = opts.num_ifaces;
2155
    m->ifaces =
2156
        (struct mg_iface **) MG_MALLOC(sizeof(*m->ifaces) * opts.num_ifaces);
2157
    for (i = 0; i < mg_num_ifaces; i++) {
2158
      m->ifaces[i] = mg_if_create_iface(opts.ifaces[i], m);
2159
      m->ifaces[i]->vtable->init(m->ifaces[i]);
2160
    }
2161
  }
2162
  DBG(("=================================="));
2163
  DBG(("init mgr=%p", m));
2164
}
2165

    
2166
#if MG_ENABLE_JAVASCRIPT
2167
static enum v7_err mg_send_js(struct v7 *v7, v7_val_t *res) {
2168
  v7_val_t arg0 = v7_arg(v7, 0);
2169
  v7_val_t arg1 = v7_arg(v7, 1);
2170
  struct mg_connection *c = (struct mg_connection *) v7_get_ptr(v7, arg0);
2171
  size_t len = 0;
2172

    
2173
  if (v7_is_string(arg1)) {
2174
    const char *data = v7_get_string(v7, &arg1, &len);
2175
    mg_send(c, data, len);
2176
  }
2177

    
2178
  *res = v7_mk_number(v7, len);
2179

    
2180
  return V7_OK;
2181
}
2182

    
2183
enum v7_err mg_enable_javascript(struct mg_mgr *m, struct v7 *v7,
2184
                                 const char *init_file_name) {
2185
  v7_val_t v;
2186
  m->v7 = v7;
2187
  v7_set_method(v7, v7_get_global(v7), "mg_send", mg_send_js);
2188
  return v7_exec_file(v7, init_file_name, &v);
2189
}
2190
#endif
2191

    
2192
void mg_mgr_free(struct mg_mgr *m) {
2193
  struct mg_connection *conn, *tmp_conn;
2194

    
2195
  DBG(("%p", m));
2196
  if (m == NULL) return;
2197
  /* Do one last poll, see https://github.com/cesanta/mongoose/issues/286 */
2198
  mg_mgr_poll(m, 0);
2199

    
2200
#if MG_ENABLE_BROADCAST
2201
  if (m->ctl[0] != INVALID_SOCKET) closesocket(m->ctl[0]);
2202
  if (m->ctl[1] != INVALID_SOCKET) closesocket(m->ctl[1]);
2203
  m->ctl[0] = m->ctl[1] = INVALID_SOCKET;
2204
#endif
2205

    
2206
  for (conn = m->active_connections; conn != NULL; conn = tmp_conn) {
2207
    tmp_conn = conn->next;
2208
    mg_close_conn(conn);
2209
  }
2210

    
2211
  {
2212
    int i;
2213
    for (i = 0; i < m->num_ifaces; i++) {
2214
      m->ifaces[i]->vtable->free(m->ifaces[i]);
2215
      MG_FREE(m->ifaces[i]);
2216
    }
2217
    MG_FREE(m->ifaces);
2218
  }
2219
}
2220

    
2221
time_t mg_mgr_poll(struct mg_mgr *m, int timeout_ms) {
2222
  int i;
2223
  time_t now = 0; /* oh GCC, seriously ? */
2224

    
2225
  if (m->num_ifaces == 0) {
2226
    LOG(LL_ERROR, ("cannot poll: no interfaces"));
2227
    return 0;
2228
  }
2229

    
2230
  for (i = 0; i < m->num_ifaces; i++) {
2231
    now = m->ifaces[i]->vtable->poll(m->ifaces[i], timeout_ms);
2232
  }
2233
  return now;
2234
}
2235

    
2236
int mg_vprintf(struct mg_connection *nc, const char *fmt, va_list ap) {
2237
  char mem[MG_VPRINTF_BUFFER_SIZE], *buf = mem;
2238
  int len;
2239

    
2240
  if ((len = mg_avprintf(&buf, sizeof(mem), fmt, ap)) > 0) {
2241
    mg_send(nc, buf, len);
2242
  }
2243
  if (buf != mem && buf != NULL) {
2244
    MG_FREE(buf); /* LCOV_EXCL_LINE */
2245
  }               /* LCOV_EXCL_LINE */
2246

    
2247
  return len;
2248
}
2249

    
2250
int mg_printf(struct mg_connection *conn, const char *fmt, ...) {
2251
  int len;
2252
  va_list ap;
2253
  va_start(ap, fmt);
2254
  len = mg_vprintf(conn, fmt, ap);
2255
  va_end(ap);
2256
  return len;
2257
}
2258

    
2259
#if MG_ENABLE_SYNC_RESOLVER
2260
/* TODO(lsm): use non-blocking resolver */
2261
static int mg_resolve2(const char *host, struct in_addr *ina) {
2262
#if MG_ENABLE_GETADDRINFO
2263
  int rv = 0;
2264
  struct addrinfo hints, *servinfo, *p;
2265
  struct sockaddr_in *h = NULL;
2266
  memset(&hints, 0, sizeof hints);
2267
  hints.ai_family = AF_INET;
2268
  hints.ai_socktype = SOCK_STREAM;
2269
  if ((rv = getaddrinfo(host, NULL, NULL, &servinfo)) != 0) {
2270
    DBG(("getaddrinfo(%s) failed: %s", host, strerror(mg_get_errno())));
2271
    return 0;
2272
  }
2273
  for (p = servinfo; p != NULL; p = p->ai_next) {
2274
    memcpy(&h, &p->ai_addr, sizeof(struct sockaddr_in *));
2275
    memcpy(ina, &h->sin_addr, sizeof(ina));
2276
  }
2277
  freeaddrinfo(servinfo);
2278
  return 1;
2279
#else
2280
  struct hostent *he;
2281
  if ((he = gethostbyname(host)) == NULL) {
2282
    DBG(("gethostbyname(%s) failed: %s", host, strerror(mg_get_errno())));
2283
  } else {
2284
    memcpy(ina, he->h_addr_list[0], sizeof(*ina));
2285
    return 1;
2286
  }
2287
  return 0;
2288
#endif /* MG_ENABLE_GETADDRINFO */
2289
}
2290

    
2291
int mg_resolve(const char *host, char *buf, size_t n) {
2292
  struct in_addr ad;
2293
  return mg_resolve2(host, &ad) ? snprintf(buf, n, "%s", inet_ntoa(ad)) : 0;
2294
}
2295
#endif /* MG_ENABLE_SYNC_RESOLVER */
2296

    
2297
MG_INTERNAL struct mg_connection *mg_create_connection_base(
2298
    struct mg_mgr *mgr, mg_event_handler_t callback,
2299
    struct mg_add_sock_opts opts) {
2300
  struct mg_connection *conn;
2301

    
2302
  if ((conn = (struct mg_connection *) MG_CALLOC(1, sizeof(*conn))) != NULL) {
2303
    conn->sock = INVALID_SOCKET;
2304
    conn->handler = callback;
2305
    conn->mgr = mgr;
2306
    conn->last_io_time = (time_t) mg_time();
2307
    conn->iface =
2308
        (opts.iface != NULL ? opts.iface : mgr->ifaces[MG_MAIN_IFACE]);
2309
    conn->flags = opts.flags & _MG_ALLOWED_CONNECT_FLAGS_MASK;
2310
    conn->user_data = opts.user_data;
2311
    /*
2312
     * SIZE_MAX is defined as a long long constant in
2313
     * system headers on some platforms and so it
2314
     * doesn't compile with pedantic ansi flags.
2315
     */
2316
    conn->recv_mbuf_limit = ~0;
2317
  } else {
2318
    MG_SET_PTRPTR(opts.error_string, "failed to create connection");
2319
  }
2320

    
2321
  return conn;
2322
}
2323

    
2324
MG_INTERNAL struct mg_connection *mg_create_connection(
2325
    struct mg_mgr *mgr, mg_event_handler_t callback,
2326
    struct mg_add_sock_opts opts) {
2327
  struct mg_connection *conn = mg_create_connection_base(mgr, callback, opts);
2328

    
2329
  if (conn != NULL && !conn->iface->vtable->create_conn(conn)) {
2330
    MG_FREE(conn);
2331
    conn = NULL;
2332
  }
2333
  if (conn == NULL) {
2334
    MG_SET_PTRPTR(opts.error_string, "failed to init connection");
2335
  }
2336

    
2337
  return conn;
2338
}
2339

    
2340
/*
2341
 * Address format: [PROTO://][HOST]:PORT
2342
 *
2343
 * HOST could be IPv4/IPv6 address or a host name.
2344
 * `host` is a destination buffer to hold parsed HOST part. Shoud be at least
2345
 * MG_MAX_HOST_LEN bytes long.
2346
 * `proto` is a returned socket type, either SOCK_STREAM or SOCK_DGRAM
2347
 *
2348
 * Return:
2349
 *   -1   on parse error
2350
 *    0   if HOST needs DNS lookup
2351
 *   >0   length of the address string
2352
 */
2353
MG_INTERNAL int mg_parse_address(const char *str, union socket_address *sa,
2354
                                 int *proto, char *host, size_t host_len) {
2355
  unsigned int a, b, c, d, port = 0;
2356
  int ch, len = 0;
2357
#if MG_ENABLE_IPV6
2358
  char buf[100];
2359
#endif
2360

    
2361
  /*
2362
   * MacOS needs that. If we do not zero it, subsequent bind() will fail.
2363
   * Also, all-zeroes in the socket address means binding to all addresses
2364
   * for both IPv4 and IPv6 (INADDR_ANY and IN6ADDR_ANY_INIT).
2365
   */
2366
  memset(sa, 0, sizeof(*sa));
2367
  sa->sin.sin_family = AF_INET;
2368

    
2369
  *proto = SOCK_STREAM;
2370

    
2371
  if (strncmp(str, "udp://", 6) == 0) {
2372
    str += 6;
2373
    *proto = SOCK_DGRAM;
2374
  } else if (strncmp(str, "tcp://", 6) == 0) {
2375
    str += 6;
2376
  }
2377

    
2378
  if (sscanf(str, "%u.%u.%u.%u:%u%n", &a, &b, &c, &d, &port, &len) == 5) {
2379
    /* Bind to a specific IPv4 address, e.g. 192.168.1.5:8080 */
2380
    sa->sin.sin_addr.s_addr =
2381
        htonl(((uint32_t) a << 24) | ((uint32_t) b << 16) | c << 8 | d);
2382
    sa->sin.sin_port = htons((uint16_t) port);
2383
#if MG_ENABLE_IPV6
2384
  } else if (sscanf(str, "[%99[^]]]:%u%n", buf, &port, &len) == 2 &&
2385
             inet_pton(AF_INET6, buf, &sa->sin6.sin6_addr)) {
2386
    /* IPv6 address, e.g. [3ffe:2a00:100:7031::1]:8080 */
2387
    sa->sin6.sin6_family = AF_INET6;
2388
    sa->sin.sin_port = htons((uint16_t) port);
2389
#endif
2390
#if MG_ENABLE_ASYNC_RESOLVER
2391
  } else if (strlen(str) < host_len &&
2392
             sscanf(str, "%[^ :]:%u%n", host, &port, &len) == 2) {
2393
    sa->sin.sin_port = htons((uint16_t) port);
2394
    if (mg_resolve_from_hosts_file(host, sa) != 0) {
2395
      /*
2396
       * if resolving from hosts file failed and the host
2397
       * we are trying to resolve is `localhost` - we should
2398
       * try to resolve it using `gethostbyname` and do not try
2399
       * to resolve it via DNS server if gethostbyname has failed too
2400
       */
2401
      if (mg_ncasecmp(host, "localhost", 9) != 0) {
2402
        return 0;
2403
      }
2404

    
2405
#if MG_ENABLE_SYNC_RESOLVER
2406
      if (!mg_resolve2(host, &sa->sin.sin_addr)) {
2407
        return -1;
2408
      }
2409
#else
2410
      return -1;
2411
#endif
2412
    }
2413
#endif
2414
  } else if (sscanf(str, ":%u%n", &port, &len) == 1 ||
2415
             sscanf(str, "%u%n", &port, &len) == 1) {
2416
    /* If only port is specified, bind to IPv4, INADDR_ANY */
2417
    sa->sin.sin_port = htons((uint16_t) port);
2418
  } else {
2419
    return -1;
2420
  }
2421

    
2422
  /* Required for MG_ENABLE_ASYNC_RESOLVER=0 */
2423
  (void) host;
2424
  (void) host_len;
2425

    
2426
  ch = str[len]; /* Character that follows the address */
2427
  return port < 0xffffUL && (ch == '\0' || ch == ',' || isspace(ch)) ? len : -1;
2428
}
2429

    
2430
struct mg_connection *mg_if_accept_new_conn(struct mg_connection *lc) {
2431
  struct mg_add_sock_opts opts;
2432
  struct mg_connection *nc;
2433
  memset(&opts, 0, sizeof(opts));
2434
  nc = mg_create_connection(lc->mgr, lc->handler, opts);
2435
  if (nc == NULL) return NULL;
2436
  nc->listener = lc;
2437
  nc->proto_handler = lc->proto_handler;
2438
  nc->user_data = lc->user_data;
2439
  nc->recv_mbuf_limit = lc->recv_mbuf_limit;
2440
  nc->iface = lc->iface;
2441
  if (lc->flags & MG_F_SSL) nc->flags |= MG_F_SSL;
2442
  mg_add_conn(nc->mgr, nc);
2443
  DBG(("%p %p %d %d", lc, nc, nc->sock, (int) nc->flags));
2444
  return nc;
2445
}
2446

    
2447
void mg_if_accept_tcp_cb(struct mg_connection *nc, union socket_address *sa,
2448
                         size_t sa_len) {
2449
  (void) sa_len;
2450
  nc->sa = *sa;
2451
  mg_call(nc, NULL, MG_EV_ACCEPT, &nc->sa);
2452
}
2453

    
2454
void mg_send(struct mg_connection *nc, const void *buf, int len) {
2455
  nc->last_io_time = (time_t) mg_time();
2456
  if (nc->flags & MG_F_UDP) {
2457
    nc->iface->vtable->udp_send(nc, buf, len);
2458
  } else {
2459
    nc->iface->vtable->tcp_send(nc, buf, len);
2460
  }
2461
#if !defined(NO_LIBC) && MG_ENABLE_HEXDUMP
2462
  if (nc->mgr && nc->mgr->hexdump_file != NULL) {
2463
    mg_hexdump_connection(nc, nc->mgr->hexdump_file, buf, len, MG_EV_SEND);
2464
  }
2465
#endif
2466
}
2467

    
2468
void mg_if_sent_cb(struct mg_connection *nc, int num_sent) {
2469
  if (num_sent < 0) {
2470
    nc->flags |= MG_F_CLOSE_IMMEDIATELY;
2471
  }
2472
  mg_call(nc, NULL, MG_EV_SEND, &num_sent);
2473
}
2474

    
2475
MG_INTERNAL void mg_recv_common(struct mg_connection *nc, void *buf, int len,
2476
                                int own) {
2477
  DBG(("%p %d %u", nc, len, (unsigned int) nc->recv_mbuf.len));
2478
  if (nc->flags & MG_F_CLOSE_IMMEDIATELY) {
2479
    DBG(("%p discarded %d bytes", nc, len));
2480
    /*
2481
     * This connection will not survive next poll. Do not deliver events,
2482
     * send data to /dev/null without acking.
2483
     */
2484
    if (own) {
2485
      MG_FREE(buf);
2486
    }
2487
    return;
2488
  }
2489
  nc->last_io_time = (time_t) mg_time();
2490
  if (!own) {
2491
    mbuf_append(&nc->recv_mbuf, buf, len);
2492
  } else if (nc->recv_mbuf.len == 0) {
2493
    /* Adopt buf as recv_mbuf's backing store. */
2494
    mbuf_free(&nc->recv_mbuf);
2495
    nc->recv_mbuf.buf = (char *) buf;
2496
    nc->recv_mbuf.size = nc->recv_mbuf.len = len;
2497
  } else {
2498
    mbuf_append(&nc->recv_mbuf, buf, len);
2499
    MG_FREE(buf);
2500
  }
2501
  mg_call(nc, NULL, MG_EV_RECV, &len);
2502
}
2503

    
2504
void mg_if_recv_tcp_cb(struct mg_connection *nc, void *buf, int len, int own) {
2505
  mg_recv_common(nc, buf, len, own);
2506
}
2507

    
2508
void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len,
2509
                       union socket_address *sa, size_t sa_len) {
2510
  assert(nc->flags & MG_F_UDP);
2511
  DBG(("%p %u", nc, (unsigned int) len));
2512
  if (nc->flags & MG_F_LISTENING) {
2513
    struct mg_connection *lc = nc;
2514
    /*
2515
     * Do we have an existing connection for this source?
2516
     * This is very inefficient for long connection lists.
2517
     */
2518
    for (nc = mg_next(lc->mgr, NULL); nc != NULL; nc = mg_next(lc->mgr, nc)) {
2519
      if (memcmp(&nc->sa.sa, &sa->sa, sa_len) == 0 && nc->listener == lc) {
2520
        break;
2521
      }
2522
    }
2523
    if (nc == NULL) {
2524
      struct mg_add_sock_opts opts;
2525
      memset(&opts, 0, sizeof(opts));
2526
      /* Create fake connection w/out sock initialization */
2527
      nc = mg_create_connection_base(lc->mgr, lc->handler, opts);
2528
      if (nc != NULL) {
2529
        nc->sock = lc->sock;
2530
        nc->listener = lc;
2531
        nc->sa = *sa;
2532
        nc->proto_handler = lc->proto_handler;
2533
        nc->user_data = lc->user_data;
2534
        nc->recv_mbuf_limit = lc->recv_mbuf_limit;
2535
        nc->flags = MG_F_UDP;
2536
        /*
2537
         * Long-lived UDP "connections" i.e. interactions that involve more
2538
         * than one request and response are rare, most are transactional:
2539
         * response is sent and the "connection" is closed. Or - should be.
2540
         * But users (including ourselves) tend to forget about that part,
2541
         * because UDP is connectionless and one does not think about
2542
         * processing a UDP request as handling a connection that needs to be
2543
         * closed. Thus, we begin with SEND_AND_CLOSE flag set, which should
2544
         * be a reasonable default for most use cases, but it is possible to
2545
         * turn it off the connection should be kept alive after processing.
2546
         */
2547
        nc->flags |= MG_F_SEND_AND_CLOSE;
2548
        mg_add_conn(lc->mgr, nc);
2549
        mg_call(nc, NULL, MG_EV_ACCEPT, &nc->sa);
2550
      } else {
2551
        DBG(("OOM"));
2552
        /* No return here, we still need to drop on the floor */
2553
      }
2554
    }
2555
  }
2556
  if (nc != NULL) {
2557
    mg_recv_common(nc, buf, len, 1);
2558
  } else {
2559
    /* Drop on the floor. */
2560
    MG_FREE(buf);
2561
    nc->iface->vtable->recved(nc, len);
2562
  }
2563
}
2564

    
2565
/*
2566
 * Schedules an async connect for a resolved address and proto.
2567
 * Called from two places: `mg_connect_opt()` and from async resolver.
2568
 * When called from the async resolver, it must trigger `MG_EV_CONNECT` event
2569
 * with a failure flag to indicate connection failure.
2570
 */
2571
MG_INTERNAL struct mg_connection *mg_do_connect(struct mg_connection *nc,
2572
                                                int proto,
2573
                                                union socket_address *sa) {
2574
  DBG(("%p %s://%s:%hu", nc, proto == SOCK_DGRAM ? "udp" : "tcp",
2575
       inet_ntoa(sa->sin.sin_addr), ntohs(sa->sin.sin_port)));
2576

    
2577
  nc->flags |= MG_F_CONNECTING;
2578
  if (proto == SOCK_DGRAM) {
2579
    nc->iface->vtable->connect_udp(nc);
2580
  } else {
2581
    nc->iface->vtable->connect_tcp(nc, sa);
2582
  }
2583
  mg_add_conn(nc->mgr, nc);
2584
  return nc;
2585
}
2586

    
2587
void mg_if_connect_cb(struct mg_connection *nc, int err) {
2588
  DBG(("%p connect, err=%d", nc, err));
2589
  nc->flags &= ~MG_F_CONNECTING;
2590
  if (err != 0) {
2591
    nc->flags |= MG_F_CLOSE_IMMEDIATELY;
2592
  }
2593
  mg_call(nc, NULL, MG_EV_CONNECT, &err);
2594
}
2595

    
2596
#if MG_ENABLE_ASYNC_RESOLVER
2597
/*
2598
 * Callback for the async resolver on mg_connect_opt() call.
2599
 * Main task of this function is to trigger MG_EV_CONNECT event with
2600
 *    either failure (and dealloc the connection)
2601
 *    or success (and proceed with connect()
2602
 */
2603
static void resolve_cb(struct mg_dns_message *msg, void *data,
2604
                       enum mg_resolve_err e) {
2605
  struct mg_connection *nc = (struct mg_connection *) data;
2606
  int i;
2607
  int failure = -1;
2608

    
2609
  nc->flags &= ~MG_F_RESOLVING;
2610
  if (msg != NULL) {
2611
    /*
2612
     * Take the first DNS A answer and run...
2613
     */
2614
    for (i = 0; i < msg->num_answers; i++) {
2615
      if (msg->answers[i].rtype == MG_DNS_A_RECORD) {
2616
        /*
2617
         * Async resolver guarantees that there is at least one answer.
2618
         * TODO(lsm): handle IPv6 answers too
2619
         */
2620
        mg_dns_parse_record_data(msg, &msg->answers[i], &nc->sa.sin.sin_addr,
2621
                                 4);
2622
        mg_do_connect(nc, nc->flags & MG_F_UDP ? SOCK_DGRAM : SOCK_STREAM,
2623
                      &nc->sa);
2624
        return;
2625
      }
2626
    }
2627
  }
2628

    
2629
  if (e == MG_RESOLVE_TIMEOUT) {
2630
    double now = mg_time();
2631
    mg_call(nc, NULL, MG_EV_TIMER, &now);
2632
  }
2633

    
2634
  /*
2635
   * If we get there was no MG_DNS_A_RECORD in the answer
2636
   */
2637
  mg_call(nc, NULL, MG_EV_CONNECT, &failure);
2638
  mg_call(nc, NULL, MG_EV_CLOSE, NULL);
2639
  mg_destroy_conn(nc, 1 /* destroy_if */);
2640
}
2641
#endif
2642

    
2643
struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *address,
2644
                                 mg_event_handler_t callback) {
2645
  struct mg_connect_opts opts;
2646
  memset(&opts, 0, sizeof(opts));
2647
  return mg_connect_opt(mgr, address, callback, opts);
2648
}
2649

    
2650
struct mg_connection *mg_connect_opt(struct mg_mgr *mgr, const char *address,
2651
                                     mg_event_handler_t callback,
2652
                                     struct mg_connect_opts opts) {
2653
  struct mg_connection *nc = NULL;
2654
  int proto, rc;
2655
  struct mg_add_sock_opts add_sock_opts;
2656
  char host[MG_MAX_HOST_LEN];
2657

    
2658
  MG_COPY_COMMON_CONNECTION_OPTIONS(&add_sock_opts, &opts);
2659

    
2660
  if ((nc = mg_create_connection(mgr, callback, add_sock_opts)) == NULL) {
2661
    return NULL;
2662
  }
2663

    
2664
  if ((rc = mg_parse_address(address, &nc->sa, &proto, host, sizeof(host))) <
2665
      0) {
2666
    /* Address is malformed */
2667
    MG_SET_PTRPTR(opts.error_string, "cannot parse address");
2668
    mg_destroy_conn(nc, 1 /* destroy_if */);
2669
    return NULL;
2670
  }
2671

    
2672
  nc->flags |= opts.flags & _MG_ALLOWED_CONNECT_FLAGS_MASK;
2673
  nc->flags |= (proto == SOCK_DGRAM) ? MG_F_UDP : 0;
2674
  nc->user_data = opts.user_data;
2675

    
2676
#if MG_ENABLE_SSL
2677
  DBG(("%p %s %s,%s,%s", nc, address, (opts.ssl_cert ? opts.ssl_cert : "-"),
2678
       (opts.ssl_key ? opts.ssl_key : "-"),
2679
       (opts.ssl_ca_cert ? opts.ssl_ca_cert : "-")));
2680

    
2681
  if (opts.ssl_cert != NULL || opts.ssl_ca_cert != NULL) {
2682
    const char *err_msg = NULL;
2683
    struct mg_ssl_if_conn_params params;
2684
    if (nc->flags & MG_F_UDP) {
2685
      MG_SET_PTRPTR(opts.error_string, "SSL for UDP is not supported");
2686
      mg_destroy_conn(nc, 1 /* destroy_if */);
2687
      return NULL;
2688
    }
2689
    memset(&params, 0, sizeof(params));
2690
    params.cert = opts.ssl_cert;
2691
    params.key = opts.ssl_key;
2692
    params.ca_cert = opts.ssl_ca_cert;
2693
    params.cipher_suites = opts.ssl_cipher_suites;
2694
    if (opts.ssl_ca_cert != NULL) {
2695
      if (opts.ssl_server_name != NULL) {
2696
        if (strcmp(opts.ssl_server_name, "*") != 0) {
2697
          params.server_name = opts.ssl_server_name;
2698
        }
2699
      } else if (rc == 0) { /* If it's a DNS name, use host. */
2700
        params.server_name = host;
2701
      }
2702
    }
2703
    if (mg_ssl_if_conn_init(nc, &params, &err_msg) != MG_SSL_OK) {
2704
      MG_SET_PTRPTR(opts.error_string, err_msg);
2705
      mg_destroy_conn(nc, 1 /* destroy_if */);
2706
      return NULL;
2707
    }
2708
    nc->flags |= MG_F_SSL;
2709
  }
2710
#endif /* MG_ENABLE_SSL */
2711

    
2712
  if (rc == 0) {
2713
#if MG_ENABLE_ASYNC_RESOLVER
2714
    /*
2715
     * DNS resolution is required for host.
2716
     * mg_parse_address() fills port in nc->sa, which we pass to resolve_cb()
2717
     */
2718
    struct mg_connection *dns_conn = NULL;
2719
    struct mg_resolve_async_opts o;
2720
    memset(&o, 0, sizeof(o));
2721
    o.dns_conn = &dns_conn;
2722
    if (mg_resolve_async_opt(nc->mgr, host, MG_DNS_A_RECORD, resolve_cb, nc,
2723
                             o) != 0) {
2724
      MG_SET_PTRPTR(opts.error_string, "cannot schedule DNS lookup");
2725
      mg_destroy_conn(nc, 1 /* destroy_if */);
2726
      return NULL;
2727
    }
2728
    nc->priv_2 = dns_conn;
2729
    nc->flags |= MG_F_RESOLVING;
2730
    return nc;
2731
#else
2732
    MG_SET_PTRPTR(opts.error_string, "Resolver is disabled");
2733
    mg_destroy_conn(nc, 1 /* destroy_if */);
2734
    return NULL;
2735
#endif
2736
  } else {
2737
    /* Address is parsed and resolved to IP. proceed with connect() */
2738
    return mg_do_connect(nc, proto, &nc->sa);
2739
  }
2740
}
2741

    
2742
struct mg_connection *mg_bind(struct mg_mgr *srv, const char *address,
2743
                              mg_event_handler_t event_handler) {
2744
  struct mg_bind_opts opts;
2745
  memset(&opts, 0, sizeof(opts));
2746
  return mg_bind_opt(srv, address, event_handler, opts);
2747
}
2748

    
2749
struct mg_connection *mg_bind_opt(struct mg_mgr *mgr, const char *address,
2750
                                  mg_event_handler_t callback,
2751
                                  struct mg_bind_opts opts) {
2752
  union socket_address sa;
2753
  struct mg_connection *nc = NULL;
2754
  int proto, rc;
2755
  struct mg_add_sock_opts add_sock_opts;
2756
  char host[MG_MAX_HOST_LEN];
2757

    
2758
  MG_COPY_COMMON_CONNECTION_OPTIONS(&add_sock_opts, &opts);
2759

    
2760
#if MG_ENABLE_TUN
2761
  if (mg_strncmp(mg_mk_str(address), mg_mk_str("ws://"), 5) == 0 ||
2762
      mg_strncmp(mg_mk_str(address), mg_mk_str("wss://"), 6) == 0) {
2763
    return mg_tun_bind_opt(mgr, address, callback, opts);
2764
  }
2765
#endif
2766

    
2767
  if (mg_parse_address(address, &sa, &proto, host, sizeof(host)) <= 0) {
2768
    MG_SET_PTRPTR(opts.error_string, "cannot parse address");
2769
    return NULL;
2770
  }
2771

    
2772
  nc = mg_create_connection(mgr, callback, add_sock_opts);
2773
  if (nc == NULL) {
2774
    return NULL;
2775
  }
2776

    
2777
  nc->sa = sa;
2778
  nc->flags |= MG_F_LISTENING;
2779
  if (proto == SOCK_DGRAM) nc->flags |= MG_F_UDP;
2780

    
2781
#if MG_ENABLE_SSL
2782
  DBG(("%p %s %s,%s,%s", nc, address, (opts.ssl_cert ? opts.ssl_cert : "-"),
2783
       (opts.ssl_key ? opts.ssl_key : "-"),
2784
       (opts.ssl_ca_cert ? opts.ssl_ca_cert : "-")));
2785

    
2786
  if (opts.ssl_cert != NULL || opts.ssl_ca_cert != NULL) {
2787
    const char *err_msg = NULL;
2788
    struct mg_ssl_if_conn_params params;
2789
    if (nc->flags & MG_F_UDP) {
2790
      MG_SET_PTRPTR(opts.error_string, "SSL for UDP is not supported");
2791
      mg_destroy_conn(nc, 1 /* destroy_if */);
2792
      return NULL;
2793
    }
2794
    memset(&params, 0, sizeof(params));
2795
    params.cert = opts.ssl_cert;
2796
    params.key = opts.ssl_key;
2797
    params.ca_cert = opts.ssl_ca_cert;
2798
    params.cipher_suites = opts.ssl_cipher_suites;
2799
    if (mg_ssl_if_conn_init(nc, &params, &err_msg) != MG_SSL_OK) {
2800
      MG_SET_PTRPTR(opts.error_string, err_msg);
2801
      mg_destroy_conn(nc, 1 /* destroy_if */);
2802
      return NULL;
2803
    }
2804
    nc->flags |= MG_F_SSL;
2805
  }
2806
#endif /* MG_ENABLE_SSL */
2807

    
2808
  if (nc->flags & MG_F_UDP) {
2809
    rc = nc->iface->vtable->listen_udp(nc, &nc->sa);
2810
  } else {
2811
    rc = nc->iface->vtable->listen_tcp(nc, &nc->sa);
2812
  }
2813
  if (rc != 0) {
2814
    DBG(("Failed to open listener: %d", rc));
2815
    MG_SET_PTRPTR(opts.error_string, "failed to open listener");
2816
    mg_destroy_conn(nc, 1 /* destroy_if */);
2817
    return NULL;
2818
  }
2819
  mg_add_conn(nc->mgr, nc);
2820

    
2821
  return nc;
2822
}
2823

    
2824
struct mg_connection *mg_next(struct mg_mgr *s, struct mg_connection *conn) {
2825
  return conn == NULL ? s->active_connections : conn->next;
2826
}
2827

    
2828
#if MG_ENABLE_BROADCAST
2829
void mg_broadcast(struct mg_mgr *mgr, mg_event_handler_t cb, void *data,
2830
                  size_t len) {
2831
  struct ctl_msg ctl_msg;
2832

    
2833
  /*
2834
   * Mongoose manager has a socketpair, `struct mg_mgr::ctl`,
2835
   * where `mg_broadcast()` pushes the message.
2836
   * `mg_mgr_poll()` wakes up, reads a message from the socket pair, and calls
2837
   * specified callback for each connection. Thus the callback function executes
2838
   * in event manager thread.
2839
   */
2840
  if (mgr->ctl[0] != INVALID_SOCKET && data != NULL &&
2841
      len < sizeof(ctl_msg.message)) {
2842
    size_t dummy;
2843

    
2844
    ctl_msg.callback = cb;
2845
    memcpy(ctl_msg.message, data, len);
2846
    dummy = MG_SEND_FUNC(mgr->ctl[0], (char *) &ctl_msg,
2847
                         offsetof(struct ctl_msg, message) + len, 0);
2848
    dummy = MG_RECV_FUNC(mgr->ctl[0], (char *) &len, 1, 0);
2849
    (void) dummy; /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509 */
2850
  }
2851
}
2852
#endif /* MG_ENABLE_BROADCAST */
2853

    
2854
static int isbyte(int n) {
2855
  return n >= 0 && n <= 255;
2856
}
2857

    
2858
static int parse_net(const char *spec, uint32_t *net, uint32_t *mask) {
2859
  int n, a, b, c, d, slash = 32, len = 0;
2860

    
2861
  if ((sscanf(spec, "%d.%d.%d.%d/%d%n", &a, &b, &c, &d, &slash, &n) == 5 ||
2862
       sscanf(spec, "%d.%d.%d.%d%n", &a, &b, &c, &d, &n) == 4) &&
2863
      isbyte(a) && isbyte(b) && isbyte(c) && isbyte(d) && slash >= 0 &&
2864
      slash < 33) {
2865
    len = n;
2866
    *net =
2867
        ((uint32_t) a << 24) | ((uint32_t) b << 16) | ((uint32_t) c << 8) | d;
2868
    *mask = slash ? 0xffffffffU << (32 - slash) : 0;
2869
  }
2870

    
2871
  return len;
2872
}
2873

    
2874
int mg_check_ip_acl(const char *acl, uint32_t remote_ip) {
2875
  int allowed, flag;
2876
  uint32_t net, mask;
2877
  struct mg_str vec;
2878

    
2879
  /* If any ACL is set, deny by default */
2880
  allowed = (acl == NULL || *acl == '\0') ? '+' : '-';
2881

    
2882
  while ((acl = mg_next_comma_list_entry(acl, &vec, NULL)) != NULL) {
2883
    flag = vec.p[0];
2884
    if ((flag != '+' && flag != '-') ||
2885
        parse_net(&vec.p[1], &net, &mask) == 0) {
2886
      return -1;
2887
    }
2888

    
2889
    if (net == (remote_ip & mask)) {
2890
      allowed = flag;
2891
    }
2892
  }
2893

    
2894
  DBG(("%08x %c", remote_ip, allowed));
2895
  return allowed == '+';
2896
}
2897

    
2898
/* Move data from one connection to another */
2899
void mg_forward(struct mg_connection *from, struct mg_connection *to) {
2900
  mg_send(to, from->recv_mbuf.buf, from->recv_mbuf.len);
2901
  mbuf_remove(&from->recv_mbuf, from->recv_mbuf.len);
2902
}
2903

    
2904
double mg_set_timer(struct mg_connection *c, double timestamp) {
2905
  double result = c->ev_timer_time;
2906
  c->ev_timer_time = timestamp;
2907
  /*
2908
   * If this connection is resolving, it's not in the list of active
2909
   * connections, so not processed yet. It has a DNS resolver connection
2910
   * linked to it. Set up a timer for the DNS connection.
2911
   */
2912
  DBG(("%p %p %d -> %lu", c, c->priv_2, c->flags & MG_F_RESOLVING,
2913
       (unsigned long) timestamp));
2914
  if ((c->flags & MG_F_RESOLVING) && c->priv_2 != NULL) {
2915
    ((struct mg_connection *) c->priv_2)->ev_timer_time = timestamp;
2916
  }
2917
  return result;
2918
}
2919

    
2920
void mg_sock_set(struct mg_connection *nc, sock_t sock) {
2921
  if (sock != INVALID_SOCKET) {
2922
    nc->iface->vtable->sock_set(nc, sock);
2923
  }
2924
}
2925

    
2926
void mg_if_get_conn_addr(struct mg_connection *nc, int remote,
2927
                         union socket_address *sa) {
2928
  nc->iface->vtable->get_conn_addr(nc, remote, sa);
2929
}
2930

    
2931
struct mg_connection *mg_add_sock_opt(struct mg_mgr *s, sock_t sock,
2932
                                      mg_event_handler_t callback,
2933
                                      struct mg_add_sock_opts opts) {
2934
  struct mg_connection *nc = mg_create_connection_base(s, callback, opts);
2935
  if (nc != NULL) {
2936
    mg_sock_set(nc, sock);
2937
    mg_add_conn(nc->mgr, nc);
2938
  }
2939
  return nc;
2940
}
2941

    
2942
struct mg_connection *mg_add_sock(struct mg_mgr *s, sock_t sock,
2943
                                  mg_event_handler_t callback) {
2944
  struct mg_add_sock_opts opts;
2945
  memset(&opts, 0, sizeof(opts));
2946
  return mg_add_sock_opt(s, sock, callback, opts);
2947
}
2948

    
2949
double mg_time(void) {
2950
  return cs_time();
2951
}
2952
#ifdef MG_MODULE_LINES
2953
#line 1 "mongoose/src/net_if_socket.h"
2954
#endif
2955
/*
2956
 * Copyright (c) 2014-2016 Cesanta Software Limited
2957
 * All rights reserved
2958
 */
2959

    
2960
#ifndef CS_MONGOOSE_SRC_NET_IF_SOCKET_H_
2961
#define CS_MONGOOSE_SRC_NET_IF_SOCKET_H_
2962

    
2963
/* Amalgamated: #include "mongoose/src/net_if.h" */
2964

    
2965
#ifdef __cplusplus
2966
extern "C" {
2967
#endif /* __cplusplus */
2968

    
2969
#ifndef MG_ENABLE_NET_IF_SOCKET
2970
#define MG_ENABLE_NET_IF_SOCKET MG_NET_IF == MG_NET_IF_SOCKET
2971
#endif
2972

    
2973
extern struct mg_iface_vtable mg_socket_iface_vtable;
2974

    
2975
#ifdef __cplusplus
2976
}
2977
#endif /* __cplusplus */
2978

    
2979
#endif /* CS_MONGOOSE_SRC_NET_IF_SOCKET_H_ */
2980
#ifdef MG_MODULE_LINES
2981
#line 1 "mongoose/src/net_if_tun.h"
2982
#endif
2983
/*
2984
 * Copyright (c) 2014-2016 Cesanta Software Limited
2985
 * All rights reserved
2986
 */
2987

    
2988
#ifndef CS_MONGOOSE_SRC_NET_IF_TUN_H_
2989
#define CS_MONGOOSE_SRC_NET_IF_TUN_H_
2990

    
2991
#if MG_ENABLE_TUN
2992

    
2993
/* Amalgamated: #include "mongoose/src/net_if.h" */
2994

    
2995
struct mg_tun_client;
2996

    
2997
#ifdef __cplusplus
2998
extern "C" {
2999
#endif /* __cplusplus */
3000

    
3001
extern struct mg_iface_vtable mg_tun_iface_vtable;
3002

    
3003
struct mg_connection *mg_tun_if_find_conn(struct mg_tun_client *client,
3004
                                          uint32_t stream_id);
3005

    
3006
#ifdef __cplusplus
3007
}
3008
#endif /* __cplusplus */
3009

    
3010
#endif /* MG_ENABLE_TUN */
3011

    
3012
#endif /* CS_MONGOOSE_SRC_NET_IF_TUN_H_ */
3013
#ifdef MG_MODULE_LINES
3014
#line 1 "mongoose/src/net_if.c"
3015
#endif
3016
/* Amalgamated: #include "mongoose/src/net_if.h" */
3017
/* Amalgamated: #include "mongoose/src/internal.h" */
3018
/* Amalgamated: #include "mongoose/src/net_if_socket.h" */
3019
/* Amalgamated: #include "mongoose/src/net_if_tun.h" */
3020

    
3021
extern struct mg_iface_vtable mg_default_iface_vtable;
3022

    
3023
#if MG_ENABLE_TUN
3024
struct mg_iface_vtable *mg_ifaces[] = {&mg_default_iface_vtable,
3025
                                       &mg_tun_iface_vtable};
3026
#else
3027
struct mg_iface_vtable *mg_ifaces[] = {&mg_default_iface_vtable};
3028
#endif
3029

    
3030
int mg_num_ifaces = (int) (sizeof(mg_ifaces) / sizeof(mg_ifaces[0]));
3031

    
3032
struct mg_iface *mg_if_create_iface(struct mg_iface_vtable *vtable,
3033
                                    struct mg_mgr *mgr) {
3034
  struct mg_iface *iface = (struct mg_iface *) MG_CALLOC(1, sizeof(*iface));
3035
  iface->mgr = mgr;
3036
  iface->data = NULL;
3037
  iface->vtable = vtable;
3038
  return iface;
3039
}
3040

    
3041
struct mg_iface *mg_find_iface(struct mg_mgr *mgr,
3042
                               struct mg_iface_vtable *vtable,
3043
                               struct mg_iface *from) {
3044
  int i = 0;
3045
  if (from != NULL) {
3046
    for (i = 0; i < mgr->num_ifaces; i++) {
3047
      if (mgr->ifaces[i] == from) {
3048
        i++;
3049
        break;
3050
      }
3051
    }
3052
  }
3053

    
3054
  for (; i < mgr->num_ifaces; i++) {
3055
    if (mgr->ifaces[i]->vtable == vtable) {
3056
      return mgr->ifaces[i];
3057
    }
3058
  }
3059
  return NULL;
3060
}
3061
#ifdef MG_MODULE_LINES
3062
#line 1 "mongoose/src/net_if_socket.c"
3063
#endif
3064
/*
3065
 * Copyright (c) 2014-2016 Cesanta Software Limited
3066
 * All rights reserved
3067
 */
3068

    
3069
#if MG_ENABLE_NET_IF_SOCKET
3070

    
3071
/* Amalgamated: #include "mongoose/src/net_if_socket.h" */
3072
/* Amalgamated: #include "mongoose/src/internal.h" */
3073
/* Amalgamated: #include "mongoose/src/util.h" */
3074

    
3075
#define MG_TCP_RECV_BUFFER_SIZE 1024
3076
#define MG_UDP_RECV_BUFFER_SIZE 1500
3077

    
3078
static sock_t mg_open_listening_socket(union socket_address *sa, int type,
3079
                                       int proto);
3080
#if MG_ENABLE_SSL
3081
static void mg_ssl_begin(struct mg_connection *nc);
3082
#endif
3083

    
3084
void mg_set_non_blocking_mode(sock_t sock) {
3085
#ifdef _WIN32
3086
  unsigned long on = 1;
3087
  ioctlsocket(sock, FIONBIO, &on);
3088
#else
3089
  int flags = fcntl(sock, F_GETFL, 0);
3090
  fcntl(sock, F_SETFL, flags | O_NONBLOCK);
3091
#endif
3092
}
3093

    
3094
static int mg_is_error(int n) {
3095
  int err = mg_get_errno();
3096
  return (n < 0 && err != EINPROGRESS && err != EWOULDBLOCK
3097
#ifndef WINCE
3098
          && err != EAGAIN && err != EINTR
3099
#endif
3100
#ifdef _WIN32
3101
          && WSAGetLastError() != WSAEINTR &&
3102
          WSAGetLastError() != WSAEWOULDBLOCK
3103
#endif
3104
          );
3105
}
3106

    
3107
void mg_socket_if_connect_tcp(struct mg_connection *nc,
3108
                              const union socket_address *sa) {
3109
  int rc, proto = 0;
3110
  nc->sock = socket(AF_INET, SOCK_STREAM, proto);
3111
  if (nc->sock == INVALID_SOCKET) {
3112
    nc->err = mg_get_errno() ? mg_get_errno() : 1;
3113
    return;
3114
  }
3115
#if !defined(MG_ESP8266)
3116
  mg_set_non_blocking_mode(nc->sock);
3117
#endif
3118
  rc = connect(nc->sock, &sa->sa, sizeof(sa->sin));
3119
  nc->err = mg_is_error(rc) ? mg_get_errno() : 0;
3120
  DBG(("%p sock %d rc %d errno %d err %d", nc, nc->sock, rc, mg_get_errno(),
3121
       nc->err));
3122
}
3123

    
3124
void mg_socket_if_connect_udp(struct mg_connection *nc) {
3125
  nc->sock = socket(AF_INET, SOCK_DGRAM, 0);
3126
  if (nc->sock == INVALID_SOCKET) {
3127
    nc->err = mg_get_errno() ? mg_get_errno() : 1;
3128
    return;
3129
  }
3130
  if (nc->flags & MG_F_ENABLE_BROADCAST) {
3131
    int optval = 1;
3132
    setsockopt(nc->sock, SOL_SOCKET, SO_BROADCAST, (const char *) &optval,
3133
               sizeof(optval));
3134
  }
3135
  nc->err = 0;
3136
}
3137

    
3138
int mg_socket_if_listen_tcp(struct mg_connection *nc,
3139
                            union socket_address *sa) {
3140
  int proto = 0;
3141
  sock_t sock = mg_open_listening_socket(sa, SOCK_STREAM, proto);
3142
  if (sock == INVALID_SOCKET) {
3143
    return (mg_get_errno() ? mg_get_errno() : 1);
3144
  }
3145
  mg_sock_set(nc, sock);
3146
  return 0;
3147
}
3148

    
3149
int mg_socket_if_listen_udp(struct mg_connection *nc,
3150
                            union socket_address *sa) {
3151
  sock_t sock = mg_open_listening_socket(sa, SOCK_DGRAM, 0);
3152
  if (sock == INVALID_SOCKET) return (mg_get_errno() ? mg_get_errno() : 1);
3153
  mg_sock_set(nc, sock);
3154
  return 0;
3155
}
3156

    
3157
void mg_socket_if_tcp_send(struct mg_connection *nc, const void *buf,
3158
                           size_t len) {
3159
  mbuf_append(&nc->send_mbuf, buf, len);
3160
}
3161

    
3162
void mg_socket_if_udp_send(struct mg_connection *nc, const void *buf,
3163
                           size_t len) {
3164
  mbuf_append(&nc->send_mbuf, buf, len);
3165
}
3166

    
3167
void mg_socket_if_recved(struct mg_connection *nc, size_t len) {
3168
  (void) nc;
3169
  (void) len;
3170
}
3171

    
3172
int mg_socket_if_create_conn(struct mg_connection *nc) {
3173
  (void) nc;
3174
  return 1;
3175
}
3176

    
3177
void mg_socket_if_destroy_conn(struct mg_connection *nc) {
3178
  if (nc->sock == INVALID_SOCKET) return;
3179
  if (!(nc->flags & MG_F_UDP)) {
3180
    closesocket(nc->sock);
3181
  } else {
3182
    /* Only close outgoing UDP sockets or listeners. */
3183
    if (nc->listener == NULL) closesocket(nc->sock);
3184
  }
3185
  nc->sock = INVALID_SOCKET;
3186
}
3187

    
3188
static int mg_accept_conn(struct mg_connection *lc) {
3189
  struct mg_connection *nc;
3190
  union socket_address sa;
3191
  socklen_t sa_len = sizeof(sa);
3192
  /* NOTE(lsm): on Windows, sock is always > FD_SETSIZE */
3193
  sock_t sock = accept(lc->sock, &sa.sa, &sa_len);
3194
  if (sock == INVALID_SOCKET) {
3195
    if (mg_is_error(-1)) DBG(("%p: failed to accept: %d", lc, mg_get_errno()));
3196
    return 0;
3197
  }
3198
  nc = mg_if_accept_new_conn(lc);
3199
  if (nc == NULL) {
3200
    closesocket(sock);
3201
    return 0;
3202
  }
3203
  DBG(("%p conn from %s:%d", nc, inet_ntoa(sa.sin.sin_addr),
3204
       ntohs(sa.sin.sin_port)));
3205
  mg_sock_set(nc, sock);
3206
#if MG_ENABLE_SSL
3207
  if (lc->flags & MG_F_SSL) {
3208
    if (mg_ssl_if_conn_accept(nc, lc) != MG_SSL_OK) mg_close_conn(nc);
3209
  } else
3210
#endif
3211
  {
3212
    mg_if_accept_tcp_cb(nc, &sa, sa_len);
3213
  }
3214
  return 1;
3215
}
3216

    
3217
/* 'sa' must be an initialized address to bind to */
3218
static sock_t mg_open_listening_socket(union socket_address *sa, int type,
3219
                                       int proto) {
3220
  socklen_t sa_len =
3221
      (sa->sa.sa_family == AF_INET) ? sizeof(sa->sin) : sizeof(sa->sin6);
3222
  sock_t sock = INVALID_SOCKET;
3223
#if !MG_LWIP
3224
  int on = 1;
3225
#endif
3226

    
3227
  if ((sock = socket(sa->sa.sa_family, type, proto)) != INVALID_SOCKET &&
3228
#if !MG_LWIP /* LWIP doesn't support either */
3229
#if defined(_WIN32) && defined(SO_EXCLUSIVEADDRUSE) && !defined(WINCE)
3230
      /* "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE" http://goo.gl/RmrFTm */
3231
      !setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (void *) &on,
3232
                  sizeof(on)) &&
3233
#endif
3234

    
3235
#if !defined(_WIN32) || !defined(SO_EXCLUSIVEADDRUSE)
3236
      /*
3237
       * SO_RESUSEADDR is not enabled on Windows because the semantics of
3238
       * SO_REUSEADDR on UNIX and Windows is different. On Windows,
3239
       * SO_REUSEADDR allows to bind a socket to a port without error even if
3240
       * the port is already open by another program. This is not the behavior
3241
       * SO_REUSEADDR was designed for, and leads to hard-to-track failure
3242
       * scenarios. Therefore, SO_REUSEADDR was disabled on Windows unless
3243
       * SO_EXCLUSIVEADDRUSE is supported and set on a socket.
3244
       */
3245
      !setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &on, sizeof(on)) &&
3246
#endif
3247
#endif /* !MG_LWIP */
3248

    
3249
      !bind(sock, &sa->sa, sa_len) &&
3250
      (type == SOCK_DGRAM || listen(sock, SOMAXCONN) == 0)) {
3251
#if !MG_LWIP
3252
    mg_set_non_blocking_mode(sock);
3253
    /* In case port was set to 0, get the real port number */
3254
    (void) getsockname(sock, &sa->sa, &sa_len);
3255
#endif
3256
  } else if (sock != INVALID_SOCKET) {
3257
    closesocket(sock);
3258
    sock = INVALID_SOCKET;
3259
  }
3260

    
3261
  return sock;
3262
}
3263

    
3264
static void mg_write_to_socket(struct mg_connection *nc) {
3265
  struct mbuf *io = &nc->send_mbuf;
3266
  int n = 0;
3267

    
3268
#if MG_LWIP
3269
  /* With LWIP we don't know if the socket is ready */
3270
  if (io->len == 0) return;
3271
#endif
3272

    
3273
  assert(io->len > 0);
3274

    
3275
  if (nc->flags & MG_F_UDP) {
3276
    int n =
3277
        sendto(nc->sock, io->buf, io->len, 0, &nc->sa.sa, sizeof(nc->sa.sin));
3278
    DBG(("%p %d %d %d %s:%hu", nc, nc->sock, n, mg_get_errno(),
3279
         inet_ntoa(nc->sa.sin.sin_addr), ntohs(nc->sa.sin.sin_port)));
3280
    if (n > 0) {
3281
      mbuf_remove(io, n);
3282
      mg_if_sent_cb(nc, n);
3283
    }
3284
    return;
3285
  }
3286

    
3287
#if MG_ENABLE_SSL
3288
  if (nc->flags & MG_F_SSL) {
3289
    if (nc->flags & MG_F_SSL_HANDSHAKE_DONE) {
3290
      n = mg_ssl_if_write(nc, io->buf, io->len);
3291
      DBG(("%p %d bytes -> %d (SSL)", nc, n, nc->sock));
3292
      if (n < 0) {
3293
        if (n != MG_SSL_WANT_READ && n != MG_SSL_WANT_WRITE) {
3294
          nc->flags |= MG_F_CLOSE_IMMEDIATELY;
3295
        }
3296
        return;
3297
      } else {
3298
        /* Successful SSL operation, clear off SSL wait flags */
3299
        nc->flags &= ~(MG_F_WANT_READ | MG_F_WANT_WRITE);
3300
      }
3301
    } else {
3302
      mg_ssl_begin(nc);
3303
      return;
3304
    }
3305
  } else
3306
#endif
3307
  {
3308
    n = (int) MG_SEND_FUNC(nc->sock, io->buf, io->len, 0);
3309
    DBG(("%p %d bytes -> %d", nc, n, nc->sock));
3310
    if (n < 0 && mg_is_error(n)) {
3311
      /* Something went wrong, drop the connection. */
3312
      nc->flags |= MG_F_CLOSE_IMMEDIATELY;
3313
      return;
3314
    }
3315
  }
3316

    
3317
  if (n > 0) {
3318
    mbuf_remove(io, n);
3319
    mg_if_sent_cb(nc, n);
3320
  }
3321
}
3322

    
3323
MG_INTERNAL size_t recv_avail_size(struct mg_connection *conn, size_t max) {
3324
  size_t avail;
3325
  if (conn->recv_mbuf_limit < conn->recv_mbuf.len) return 0;
3326
  avail = conn->recv_mbuf_limit - conn->recv_mbuf.len;
3327
  return avail > max ? max : avail;
3328
}
3329

    
3330
static void mg_handle_tcp_read(struct mg_connection *conn) {
3331
  int n = 0;
3332
  char *buf = (char *) MG_MALLOC(MG_TCP_RECV_BUFFER_SIZE);
3333

    
3334
  if (buf == NULL) {
3335
    DBG(("OOM"));
3336
    return;
3337
  }
3338

    
3339
#if MG_ENABLE_SSL
3340
  if (conn->flags & MG_F_SSL) {
3341
    if (conn->flags & MG_F_SSL_HANDSHAKE_DONE) {
3342
      /* SSL library may have more bytes ready to read than we ask to read.
3343
       * Therefore, read in a loop until we read everything. Without the loop,
3344
       * we skip to the next select() cycle which can just timeout. */
3345
      while ((n = mg_ssl_if_read(conn, buf, MG_TCP_RECV_BUFFER_SIZE)) > 0) {
3346
        DBG(("%p %d bytes <- %d (SSL)", conn, n, conn->sock));
3347
        mg_if_recv_tcp_cb(conn, buf, n, 1 /* own */);
3348
        buf = NULL;
3349
        if (conn->flags & MG_F_CLOSE_IMMEDIATELY) break;
3350
        /* buf has been freed, we need a new one. */
3351
        buf = (char *) MG_MALLOC(MG_TCP_RECV_BUFFER_SIZE);
3352
        if (buf == NULL) break;
3353
      }
3354
      MG_FREE(buf);
3355
      if (n < 0 && n != MG_SSL_WANT_READ) conn->flags |= MG_F_CLOSE_IMMEDIATELY;
3356
    } else {
3357
      MG_FREE(buf);
3358
      mg_ssl_begin(conn);
3359
      return;
3360
    }
3361
  } else
3362
#endif
3363
  {
3364
    n = (int) MG_RECV_FUNC(conn->sock, buf,
3365
                           recv_avail_size(conn, MG_TCP_RECV_BUFFER_SIZE), 0);
3366
    DBG(("%p %d bytes (PLAIN) <- %d", conn, n, conn->sock));
3367
    if (n > 0) {
3368
      mg_if_recv_tcp_cb(conn, buf, n, 1 /* own */);
3369
    } else {
3370
      MG_FREE(buf);
3371
    }
3372
    if (n == 0) {
3373
      /* Orderly shutdown of the socket, try flushing output. */
3374
      conn->flags |= MG_F_SEND_AND_CLOSE;
3375
    } else if (mg_is_error(n)) {
3376
      conn->flags |= MG_F_CLOSE_IMMEDIATELY;
3377
    }
3378
  }
3379
}
3380

    
3381
static int mg_recvfrom(struct mg_connection *nc, union socket_address *sa,
3382
                       socklen_t *sa_len, char **buf) {
3383
  int n;
3384
  *buf = (char *) MG_MALLOC(MG_UDP_RECV_BUFFER_SIZE);
3385
  if (*buf == NULL) {
3386
    DBG(("Out of memory"));
3387
    return -ENOMEM;
3388
  }
3389
  n = recvfrom(nc->sock, *buf, MG_UDP_RECV_BUFFER_SIZE, 0, &sa->sa, sa_len);
3390
  if (n <= 0) {
3391
    DBG(("%p recvfrom: %s", nc, strerror(mg_get_errno())));
3392
    MG_FREE(*buf);
3393
  }
3394
  return n;
3395
}
3396

    
3397
static void mg_handle_udp_read(struct mg_connection *nc) {
3398
  char *buf = NULL;
3399
  union socket_address sa;
3400
  socklen_t sa_len = sizeof(sa);
3401
  int n = mg_recvfrom(nc, &sa, &sa_len, &buf);
3402
  DBG(("%p %d bytes from %s:%d", nc, n, inet_ntoa(nc->sa.sin.sin_addr),
3403
       ntohs(nc->sa.sin.sin_port)));
3404
  mg_if_recv_udp_cb(nc, buf, n, &sa, sa_len);
3405
}
3406

    
3407
#if MG_ENABLE_SSL
3408
static void mg_ssl_begin(struct mg_connection *nc) {
3409
  int server_side = (nc->listener != NULL);
3410
  enum mg_ssl_if_result res = mg_ssl_if_handshake(nc);
3411
  DBG(("%p %d res %d", nc, server_side, res));
3412

    
3413
  if (res == MG_SSL_OK) {
3414
    nc->flags |= MG_F_SSL_HANDSHAKE_DONE;
3415
    nc->flags &= ~(MG_F_WANT_READ | MG_F_WANT_WRITE);
3416

    
3417
    if (server_side) {
3418
      union socket_address sa;
3419
      socklen_t sa_len = sizeof(sa);
3420
      (void) getpeername(nc->sock, &sa.sa, &sa_len);
3421
      mg_if_accept_tcp_cb(nc, &sa, sa_len);
3422
    } else {
3423
      mg_if_connect_cb(nc, 0);
3424
    }
3425
  } else if (res != MG_SSL_WANT_READ && res != MG_SSL_WANT_WRITE) {
3426
    if (!server_side) {
3427
      mg_if_connect_cb(nc, res);
3428
    }
3429
    nc->flags |= MG_F_CLOSE_IMMEDIATELY;
3430
  }
3431
}
3432
#endif /* MG_ENABLE_SSL */
3433

    
3434
#define _MG_F_FD_CAN_READ 1
3435
#define _MG_F_FD_CAN_WRITE 1 << 1
3436
#define _MG_F_FD_ERROR 1 << 2
3437

    
3438
void mg_mgr_handle_conn(struct mg_connection *nc, int fd_flags, double now) {
3439
  int worth_logging =
3440
      fd_flags != 0 || (nc->flags & (MG_F_WANT_READ | MG_F_WANT_WRITE));
3441
  if (worth_logging) {
3442
    DBG(("%p fd=%d fd_flags=%d nc_flags=%lu rmbl=%d smbl=%d", nc, nc->sock,
3443
         fd_flags, nc->flags, (int) nc->recv_mbuf.len,
3444
         (int) nc->send_mbuf.len));
3445
  }
3446

    
3447
  if (nc->flags & MG_F_CONNECTING) {
3448
    if (fd_flags != 0) {
3449
      int err = 0;
3450
#if !defined(MG_ESP8266)
3451
      if (!(nc->flags & MG_F_UDP)) {
3452
        socklen_t len = sizeof(err);
3453
        int ret =
3454
            getsockopt(nc->sock, SOL_SOCKET, SO_ERROR, (char *) &err, &len);
3455
        if (ret != 0) {
3456
          err = 1;
3457
        } else if (err == EAGAIN || err == EWOULDBLOCK) {
3458
          err = 0;
3459
        }
3460
      }
3461
#else
3462
      /*
3463
       * On ESP8266 we use blocking connect.
3464
       */
3465
      err = nc->err;
3466
#endif
3467
#if MG_ENABLE_SSL
3468
      if ((nc->flags & MG_F_SSL) && err == 0) {
3469
        mg_ssl_begin(nc);
3470
      } else {
3471
        mg_if_connect_cb(nc, err);
3472
      }
3473
#else
3474
      mg_if_connect_cb(nc, err);
3475
#endif
3476
    } else if (nc->err != 0) {
3477
      mg_if_connect_cb(nc, nc->err);
3478
    }
3479
  }
3480

    
3481
  if (fd_flags & _MG_F_FD_CAN_READ) {
3482
    if (nc->flags & MG_F_UDP) {
3483
      mg_handle_udp_read(nc);
3484
    } else {
3485
      if (nc->flags & MG_F_LISTENING) {
3486
        /*
3487
         * We're not looping here, and accepting just one connection at
3488
         * a time. The reason is that eCos does not respect non-blocking
3489
         * flag on a listening socket and hangs in a loop.
3490
         */
3491
        mg_accept_conn(nc);
3492
      } else {
3493
        mg_handle_tcp_read(nc);
3494
      }
3495
    }
3496
  }
3497

    
3498
  if (!(nc->flags & MG_F_CLOSE_IMMEDIATELY)) {
3499
    if ((fd_flags & _MG_F_FD_CAN_WRITE) && nc->send_mbuf.len > 0) {
3500
      mg_write_to_socket(nc);
3501
    }
3502
    mg_if_poll(nc, (time_t) now);
3503
    mg_if_timer(nc, now);
3504
  }
3505

    
3506
  if (worth_logging) {
3507
    DBG(("%p after fd=%d nc_flags=%lu rmbl=%d smbl=%d", nc, nc->sock, nc->flags,
3508
         (int) nc->recv_mbuf.len, (int) nc->send_mbuf.len));
3509
  }
3510
}
3511

    
3512
#if MG_ENABLE_BROADCAST
3513
static void mg_mgr_handle_ctl_sock(struct mg_mgr *mgr) {
3514
  struct ctl_msg ctl_msg;
3515
  int len =
3516
      (int) MG_RECV_FUNC(mgr->ctl[1], (char *) &ctl_msg, sizeof(ctl_msg), 0);
3517
  size_t dummy = MG_SEND_FUNC(mgr->ctl[1], ctl_msg.message, 1, 0);
3518
  DBG(("read %d from ctl socket", len));
3519
  (void) dummy; /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509 */
3520
  if (len >= (int) sizeof(ctl_msg.callback) && ctl_msg.callback != NULL) {
3521
    struct mg_connection *nc;
3522
    for (nc = mg_next(mgr, NULL); nc != NULL; nc = mg_next(mgr, nc)) {
3523
      ctl_msg.callback(nc, MG_EV_POLL, ctl_msg.message);
3524
    }
3525
  }
3526
}
3527
#endif
3528

    
3529
/* Associate a socket to a connection. */
3530
void mg_socket_if_sock_set(struct mg_connection *nc, sock_t sock) {
3531
  mg_set_non_blocking_mode(sock);
3532
  mg_set_close_on_exec(sock);
3533
  nc->sock = sock;
3534
  DBG(("%p %d", nc, sock));
3535
}
3536

    
3537
void mg_socket_if_init(struct mg_iface *iface) {
3538
  (void) iface;
3539
  DBG(("%p using select()", iface->mgr));
3540
#if MG_ENABLE_BROADCAST
3541
  do {
3542
    mg_socketpair(iface->mgr->ctl, SOCK_DGRAM);
3543
  } while (iface->mgr->ctl[0] == INVALID_SOCKET);
3544
#endif
3545
}
3546

    
3547
void mg_socket_if_free(struct mg_iface *iface) {
3548
  (void) iface;
3549
}
3550

    
3551
void mg_socket_if_add_conn(struct mg_connection *nc) {
3552
  (void) nc;
3553
}
3554

    
3555
void mg_socket_if_remove_conn(struct mg_connection *nc) {
3556
  (void) nc;
3557
}
3558

    
3559
void mg_add_to_set(sock_t sock, fd_set *set, sock_t *max_fd) {
3560
  if (sock != INVALID_SOCKET
3561
#ifdef __unix__
3562
      && sock < (sock_t) FD_SETSIZE
3563
#endif
3564
      ) {
3565
    FD_SET(sock, set);
3566
    if (*max_fd == INVALID_SOCKET || sock > *max_fd) {
3567
      *max_fd = sock;
3568
    }
3569
  }
3570
}
3571

    
3572
time_t mg_socket_if_poll(struct mg_iface *iface, int timeout_ms) {
3573
  struct mg_mgr *mgr = iface->mgr;
3574
  double now = mg_time();
3575
  double min_timer;
3576
  struct mg_connection *nc, *tmp;
3577
  struct timeval tv;
3578
  fd_set read_set, write_set, err_set;
3579
  sock_t max_fd = INVALID_SOCKET;
3580
  int num_fds, num_ev, num_timers = 0;
3581
#ifdef __unix__
3582
  int try_dup = 1;
3583
#endif
3584

    
3585
  FD_ZERO(&read_set);
3586
  FD_ZERO(&write_set);
3587
  FD_ZERO(&err_set);
3588
#if MG_ENABLE_BROADCAST
3589
  mg_add_to_set(mgr->ctl[1], &read_set, &max_fd);
3590
#endif
3591

    
3592
  /*
3593
   * Note: it is ok to have connections with sock == INVALID_SOCKET in the list,
3594
   * e.g. timer-only "connections".
3595
   */
3596
  min_timer = 0;
3597
  for (nc = mgr->active_connections, num_fds = 0; nc != NULL; nc = tmp) {
3598
    tmp = nc->next;
3599

    
3600
    if (nc->sock != INVALID_SOCKET) {
3601
      num_fds++;
3602

    
3603
#ifdef __unix__
3604
      /* A hack to make sure all our file descriptos fit into FD_SETSIZE. */
3605
      if (nc->sock >= (sock_t) FD_SETSIZE && try_dup) {
3606
        int new_sock = dup(nc->sock);
3607
        if (new_sock >= 0 && new_sock < (sock_t) FD_SETSIZE) {
3608
          closesocket(nc->sock);
3609
          DBG(("new sock %d -> %d", nc->sock, new_sock));
3610
          nc->sock = new_sock;
3611
        } else {
3612
          try_dup = 0;
3613
        }
3614
      }
3615
#endif
3616

    
3617
      if (!(nc->flags & MG_F_WANT_WRITE) &&
3618
          nc->recv_mbuf.len < nc->recv_mbuf_limit &&
3619
          (!(nc->flags & MG_F_UDP) || nc->listener == NULL)) {
3620
        mg_add_to_set(nc->sock, &read_set, &max_fd);
3621
      }
3622

    
3623
      if (((nc->flags & MG_F_CONNECTING) && !(nc->flags & MG_F_WANT_READ)) ||
3624
          (nc->send_mbuf.len > 0 && !(nc->flags & MG_F_CONNECTING))) {
3625
        mg_add_to_set(nc->sock, &write_set, &max_fd);
3626
        mg_add_to_set(nc->sock, &err_set, &max_fd);
3627
      }
3628
    }
3629

    
3630
    if (nc->ev_timer_time > 0) {
3631
      if (num_timers == 0 || nc->ev_timer_time < min_timer) {
3632
        min_timer = nc->ev_timer_time;
3633
      }
3634
      num_timers++;
3635
    }
3636
  }
3637

    
3638
  /*
3639
   * If there is a timer to be fired earlier than the requested timeout,
3640
   * adjust the timeout.
3641
   */
3642
  if (num_timers > 0) {
3643
    double timer_timeout_ms = (min_timer - mg_time()) * 1000 + 1 /* rounding */;
3644
    if (timer_timeout_ms < timeout_ms) {
3645
      timeout_ms = (int) timer_timeout_ms;
3646
    }
3647
  }
3648
  if (timeout_ms < 0) timeout_ms = 0;
3649

    
3650
  tv.tv_sec = timeout_ms / 1000;
3651
  tv.tv_usec = (timeout_ms % 1000) * 1000;
3652

    
3653
  num_ev = select((int) max_fd + 1, &read_set, &write_set, &err_set, &tv);
3654
  now = mg_time();
3655
#if 0
3656
  DBG(("select @ %ld num_ev=%d of %d, timeout=%d", (long) now, num_ev, num_fds,
3657
       timeout_ms));
3658
#endif
3659

    
3660
#if MG_ENABLE_BROADCAST
3661
  if (num_ev > 0 && mgr->ctl[1] != INVALID_SOCKET &&
3662
      FD_ISSET(mgr->ctl[1], &read_set)) {
3663
    mg_mgr_handle_ctl_sock(mgr);
3664
  }
3665
#endif
3666

    
3667
  for (nc = mgr->active_connections; nc != NULL; nc = tmp) {
3668
    int fd_flags = 0;
3669
    if (nc->sock != INVALID_SOCKET) {
3670
      if (num_ev > 0) {
3671
        fd_flags = (FD_ISSET(nc->sock, &read_set) &&
3672
                            (!(nc->flags & MG_F_UDP) || nc->listener == NULL)
3673
                        ? _MG_F_FD_CAN_READ
3674
                        : 0) |
3675
                   (FD_ISSET(nc->sock, &write_set) ? _MG_F_FD_CAN_WRITE : 0) |
3676
                   (FD_ISSET(nc->sock, &err_set) ? _MG_F_FD_ERROR : 0);
3677
      }
3678
#if MG_LWIP
3679
      /* With LWIP socket emulation layer, we don't get write events for UDP */
3680
      if ((nc->flags & MG_F_UDP) && nc->listener == NULL) {
3681
        fd_flags |= _MG_F_FD_CAN_WRITE;
3682
      }
3683
#endif
3684
    }
3685
    tmp = nc->next;
3686
    mg_mgr_handle_conn(nc, fd_flags, now);
3687
  }
3688

    
3689
  for (nc = mgr->active_connections; nc != NULL; nc = tmp) {
3690
    tmp = nc->next;
3691
    if ((nc->flags & MG_F_CLOSE_IMMEDIATELY) ||
3692
        (nc->send_mbuf.len == 0 && (nc->flags & MG_F_SEND_AND_CLOSE))) {
3693
      mg_close_conn(nc);
3694
    }
3695
  }
3696

    
3697
  return (time_t) now;
3698
}
3699

    
3700
#if MG_ENABLE_BROADCAST
3701
int mg_socketpair(sock_t sp[2], int sock_type) {
3702
  union socket_address sa;
3703
  sock_t sock;
3704
  socklen_t len = sizeof(sa.sin);
3705
  int ret = 0;
3706

    
3707
  sock = sp[0] = sp[1] = INVALID_SOCKET;
3708

    
3709
  (void) memset(&sa, 0, sizeof(sa));
3710
  sa.sin.sin_family = AF_INET;
3711
  sa.sin.sin_port = htons(0);
3712
  sa.sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */
3713

    
3714
  if ((sock = socket(AF_INET, sock_type, 0)) == INVALID_SOCKET) {
3715
  } else if (bind(sock, &sa.sa, len) != 0) {
3716
  } else if (sock_type == SOCK_STREAM && listen(sock, 1) != 0) {
3717
  } else if (getsockname(sock, &sa.sa, &len) != 0) {
3718
  } else if ((sp[0] = socket(AF_INET, sock_type, 0)) == INVALID_SOCKET) {
3719
  } else if (connect(sp[0], &sa.sa, len) != 0) {
3720
  } else if (sock_type == SOCK_DGRAM &&
3721
             (getsockname(sp[0], &sa.sa, &len) != 0 ||
3722
              connect(sock, &sa.sa, len) != 0)) {
3723
  } else if ((sp[1] = (sock_type == SOCK_DGRAM ? sock
3724
                                               : accept(sock, &sa.sa, &len))) ==
3725
             INVALID_SOCKET) {
3726
  } else {
3727
    mg_set_close_on_exec(sp[0]);
3728
    mg_set_close_on_exec(sp[1]);
3729
    if (sock_type == SOCK_STREAM) closesocket(sock);
3730
    ret = 1;
3731
  }
3732

    
3733
  if (!ret) {
3734
    if (sp[0] != INVALID_SOCKET) closesocket(sp[0]);
3735
    if (sp[1] != INVALID_SOCKET) closesocket(sp[1]);
3736
    if (sock != INVALID_SOCKET) closesocket(sock);
3737
    sock = sp[0] = sp[1] = INVALID_SOCKET;
3738
  }
3739

    
3740
  return ret;
3741
}
3742
#endif /* MG_ENABLE_BROADCAST */
3743

    
3744
static void mg_sock_get_addr(sock_t sock, int remote,
3745
                             union socket_address *sa) {
3746
  socklen_t slen = sizeof(*sa);
3747
  memset(sa, 0, slen);
3748
  if (remote) {
3749
    getpeername(sock, &sa->sa, &slen);
3750
  } else {
3751
    getsockname(sock, &sa->sa, &slen);
3752
  }
3753
}
3754

    
3755
void mg_sock_to_str(sock_t sock, char *buf, size_t len, int flags) {
3756
  union socket_address sa;
3757
  mg_sock_get_addr(sock, flags & MG_SOCK_STRINGIFY_REMOTE, &sa);
3758
  mg_sock_addr_to_str(&sa, buf, len, flags);
3759
}
3760

    
3761
void mg_socket_if_get_conn_addr(struct mg_connection *nc, int remote,
3762
                                union socket_address *sa) {
3763
  mg_sock_get_addr(nc->sock, remote, sa);
3764
}
3765

    
3766
/* clang-format off */
3767
#define MG_SOCKET_IFACE_VTABLE                                          \
3768
  {                                                                     \
3769
    mg_socket_if_init,                                                  \
3770
    mg_socket_if_free,                                                  \
3771
    mg_socket_if_add_conn,                                              \
3772
    mg_socket_if_remove_conn,                                           \
3773
    mg_socket_if_poll,                                                  \
3774
    mg_socket_if_listen_tcp,                                            \
3775
    mg_socket_if_listen_udp,                                            \
3776
    mg_socket_if_connect_tcp,                                           \
3777
    mg_socket_if_connect_udp,                                           \
3778
    mg_socket_if_tcp_send,                                              \
3779
    mg_socket_if_udp_send,                                              \
3780
    mg_socket_if_recved,                                                \
3781
    mg_socket_if_create_conn,                                           \
3782
    mg_socket_if_destroy_conn,                                          \
3783
    mg_socket_if_sock_set,                                              \
3784
    mg_socket_if_get_conn_addr,                                         \
3785
  }
3786
/* clang-format on */
3787

    
3788
struct mg_iface_vtable mg_socket_iface_vtable = MG_SOCKET_IFACE_VTABLE;
3789
#if MG_NET_IF == MG_NET_IF_SOCKET
3790
struct mg_iface_vtable mg_default_iface_vtable = MG_SOCKET_IFACE_VTABLE;
3791
#endif
3792

    
3793
#endif /* MG_ENABLE_NET_IF_SOCKET */
3794
#ifdef MG_MODULE_LINES
3795
#line 1 "mongoose/src/net_if_tun.c"
3796
#endif
3797
/*
3798
 * Copyright (c) 2014-2016 Cesanta Software Limited
3799
 * All rights reserved
3800
 */
3801

    
3802
#if MG_ENABLE_TUN
3803

    
3804
/* Amalgamated: #include "common/cs_dbg.h" */
3805
/* Amalgamated: #include "common/cs_time.h" */
3806
/* Amalgamated: #include "mongoose/src/internal.h" */
3807
/* Amalgamated: #include "mongoose/src/net_if_tun.h" */
3808
/* Amalgamated: #include "mongoose/src/tun.h" */
3809
/* Amalgamated: #include "mongoose/src/util.h" */
3810

    
3811
#define MG_TCP_RECV_BUFFER_SIZE 1024
3812
#define MG_UDP_RECV_BUFFER_SIZE 1500
3813

    
3814
void mg_tun_if_connect_tcp(struct mg_connection *nc,
3815
                           const union socket_address *sa) {
3816
  (void) nc;
3817
  (void) sa;
3818
}
3819

    
3820
void mg_tun_if_connect_udp(struct mg_connection *nc) {
3821
  (void) nc;
3822
}
3823

    
3824
int mg_tun_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) {
3825
  (void) nc;
3826
  (void) sa;
3827
  return 0;
3828
}
3829

    
3830
int mg_tun_if_listen_udp(struct mg_connection *nc, union socket_address *sa) {
3831
  (void) nc;
3832
  (void) sa;
3833
  return -1;
3834
}
3835

    
3836
void mg_tun_if_tcp_send(struct mg_connection *nc, const void *buf, size_t len) {
3837
  struct mg_tun_client *client = (struct mg_tun_client *) nc->iface->data;
3838
  uint32_t stream_id = (uint32_t)(uintptr_t) nc->mgr_data;
3839
  struct mg_str msg = {(char *) buf, len};
3840
#if MG_ENABLE_HEXDUMP
3841
  char hex[512];
3842
  mg_hexdump(buf, len, hex, sizeof(hex));
3843
  LOG(LL_DEBUG, ("sending to stream %zu:\n%s", stream_id, hex));
3844
#endif
3845

    
3846
  mg_tun_send_frame(client->disp, stream_id, MG_TUN_DATA_FRAME, 0, msg);
3847
}
3848

    
3849
void mg_tun_if_udp_send(struct mg_connection *nc, const void *buf, size_t len) {
3850
  (void) nc;
3851
  (void) buf;
3852
  (void) len;
3853
}
3854

    
3855
void mg_tun_if_recved(struct mg_connection *nc, size_t len) {
3856
  (void) nc;
3857
  (void) len;
3858
}
3859

    
3860
int mg_tun_if_create_conn(struct mg_connection *nc) {
3861
  (void) nc;
3862
  return 1;
3863
}
3864

    
3865
void mg_tun_if_destroy_conn(struct mg_connection *nc) {
3866
  struct mg_tun_client *client = (struct mg_tun_client *) nc->iface->data;
3867

    
3868
  if (nc->flags & MG_F_LISTENING) {
3869
    mg_tun_destroy_client(client);
3870
  } else if (client->disp) {
3871
    uint32_t stream_id = (uint32_t)(uintptr_t) nc->mgr_data;
3872
    struct mg_str msg = {NULL, 0};
3873

    
3874
    LOG(LL_DEBUG, ("closing %zu:", stream_id));
3875
    mg_tun_send_frame(client->disp, stream_id, MG_TUN_DATA_FRAME,
3876
                      MG_TUN_F_END_STREAM, msg);
3877
  }
3878
}
3879

    
3880
/* Associate a socket to a connection. */
3881
void mg_tun_if_sock_set(struct mg_connection *nc, sock_t sock) {
3882
  (void) nc;
3883
  (void) sock;
3884
}
3885

    
3886
void mg_tun_if_init(struct mg_iface *iface) {
3887
  (void) iface;
3888
}
3889

    
3890
void mg_tun_if_free(struct mg_iface *iface) {
3891
  (void) iface;
3892
}
3893

    
3894
void mg_tun_if_add_conn(struct mg_connection *nc) {
3895
  nc->sock = INVALID_SOCKET;
3896
}
3897

    
3898
void mg_tun_if_remove_conn(struct mg_connection *nc) {
3899
  (void) nc;
3900
}
3901

    
3902
time_t mg_tun_if_poll(struct mg_iface *iface, int timeout_ms) {
3903
  (void) iface;
3904
  (void) timeout_ms;
3905
  return (time_t) cs_time();
3906
}
3907

    
3908
void mg_tun_if_get_conn_addr(struct mg_connection *nc, int remote,
3909
                             union socket_address *sa) {
3910
  (void) nc;
3911
  (void) remote;
3912
  (void) sa;
3913
}
3914

    
3915
struct mg_connection *mg_tun_if_find_conn(struct mg_tun_client *client,
3916
                                          uint32_t stream_id) {
3917
  struct mg_connection *nc = NULL;
3918

    
3919
  for (nc = client->mgr->active_connections; nc != NULL; nc = nc->next) {
3920
    if (nc->iface != client->iface || (nc->flags & MG_F_LISTENING)) {
3921
      continue;
3922
    }
3923
    if (stream_id == (uint32_t)(uintptr_t) nc->mgr_data) {
3924
      return nc;
3925
    }
3926
  }
3927

    
3928
  if (stream_id > client->last_stream_id) {
3929
    /* create a new connection */
3930
    LOG(LL_DEBUG, ("new stream 0x%lx, accepting", stream_id));
3931
    nc = mg_if_accept_new_conn(client->listener);
3932
    nc->mgr_data = (void *) (uintptr_t) stream_id;
3933
    client->last_stream_id = stream_id;
3934
  } else {
3935
    LOG(LL_DEBUG, ("Ignoring stream 0x%lx (last_stream_id 0x%lx)", stream_id,
3936
                   client->last_stream_id));
3937
  }
3938

    
3939
  return nc;
3940
}
3941

    
3942
/* clang-format off */
3943
#define MG_TUN_IFACE_VTABLE                                             \
3944
  {                                                                     \
3945
    mg_tun_if_init,                                                     \
3946
    mg_tun_if_free,                                                     \
3947
    mg_tun_if_add_conn,                                                 \
3948
    mg_tun_if_remove_conn,                                              \
3949
    mg_tun_if_poll,                                                     \
3950
    mg_tun_if_listen_tcp,                                               \
3951
    mg_tun_if_listen_udp,                                               \
3952
    mg_tun_if_connect_tcp,                                              \
3953
    mg_tun_if_connect_udp,                                              \
3954
    mg_tun_if_tcp_send,                                                 \
3955
    mg_tun_if_udp_send,                                                 \
3956
    mg_tun_if_recved,                                                   \
3957
    mg_tun_if_create_conn,                                              \
3958
    mg_tun_if_destroy_conn,                                             \
3959
    mg_tun_if_sock_set,                                                 \
3960
    mg_tun_if_get_conn_addr,                                            \
3961
  }
3962
/* clang-format on */
3963

    
3964
struct mg_iface_vtable mg_tun_iface_vtable = MG_TUN_IFACE_VTABLE;
3965

    
3966
#endif /* MG_ENABLE_TUN */
3967
#ifdef MG_MODULE_LINES
3968
#line 1 "mongoose/src/ssl_if_openssl.c"
3969
#endif
3970
/*
3971
 * Copyright (c) 2014-2016 Cesanta Software Limited
3972
 * All rights reserved
3973
 */
3974

    
3975
#if MG_ENABLE_SSL && MG_SSL_IF == MG_SSL_IF_OPENSSL
3976

    
3977
#ifdef __APPLE__
3978
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
3979
#endif
3980

    
3981
#include <openssl/ssl.h>
3982

    
3983
struct mg_ssl_if_ctx {
3984
  SSL *ssl;
3985
  SSL_CTX *ssl_ctx;
3986
};
3987

    
3988
void mg_ssl_if_init() {
3989
  SSL_library_init();
3990
}
3991

    
3992
enum mg_ssl_if_result mg_ssl_if_conn_accept(struct mg_connection *nc,
3993
                                            struct mg_connection *lc) {
3994
  struct mg_ssl_if_ctx *ctx =
3995
      (struct mg_ssl_if_ctx *) MG_CALLOC(1, sizeof(*ctx));
3996
  struct mg_ssl_if_ctx *lc_ctx = (struct mg_ssl_if_ctx *) lc->ssl_if_data;
3997
  nc->ssl_if_data = ctx;
3998
  if (ctx == NULL || lc_ctx == NULL) return MG_SSL_ERROR;
3999
  ctx->ssl_ctx = lc_ctx->ssl_ctx;
4000
  if ((ctx->ssl = SSL_new(ctx->ssl_ctx)) == NULL) {
4001
    return MG_SSL_ERROR;
4002
  }
4003
  return MG_SSL_OK;
4004
}
4005

    
4006
static enum mg_ssl_if_result mg_use_cert(SSL_CTX *ctx, const char *cert,
4007
                                         const char *key, const char **err_msg);
4008
static enum mg_ssl_if_result mg_use_ca_cert(SSL_CTX *ctx, const char *cert);
4009
static enum mg_ssl_if_result mg_set_cipher_list(SSL_CTX *ctx, const char *cl);
4010

    
4011
enum mg_ssl_if_result mg_ssl_if_conn_init(
4012
    struct mg_connection *nc, const struct mg_ssl_if_conn_params *params,
4013
    const char **err_msg) {
4014
  struct mg_ssl_if_ctx *ctx =
4015
      (struct mg_ssl_if_ctx *) MG_CALLOC(1, sizeof(*ctx));
4016
  DBG(("%p %s,%s,%s", nc, (params->cert ? params->cert : ""),
4017
       (params->key ? params->key : ""),
4018
       (params->ca_cert ? params->ca_cert : "")));
4019
  if (ctx == NULL) {
4020
    MG_SET_PTRPTR(err_msg, "Out of memory");
4021
    return MG_SSL_ERROR;
4022
  }
4023
  nc->ssl_if_data = ctx;
4024
  if (nc->flags & MG_F_LISTENING) {
4025
    ctx->ssl_ctx = SSL_CTX_new(SSLv23_server_method());
4026
  } else {
4027
    ctx->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
4028
  }
4029
  if (ctx->ssl_ctx == NULL) {
4030
    MG_SET_PTRPTR(err_msg, "Failed to create SSL context");
4031
    return MG_SSL_ERROR;
4032
  }
4033

    
4034
  if (params->cert != NULL &&
4035
      mg_use_cert(ctx->ssl_ctx, params->cert, params->key, err_msg) !=
4036
          MG_SSL_OK) {
4037
    return MG_SSL_ERROR;
4038
  }
4039

    
4040
  if (params->ca_cert != NULL &&
4041
      mg_use_ca_cert(ctx->ssl_ctx, params->ca_cert) != MG_SSL_OK) {
4042
    MG_SET_PTRPTR(err_msg, "Invalid SSL CA cert");
4043
    return MG_SSL_ERROR;
4044
  }
4045

    
4046
  if (params->server_name != NULL) {
4047
#ifdef KR_VERSION
4048
    SSL_CTX_kr_set_verify_name(ctx->ssl_ctx, params->server_name);
4049
#else
4050
/* TODO(rojer): Implement server name verification on OpenSSL. */
4051
#endif
4052
  }
4053

    
4054
  if (mg_set_cipher_list(ctx->ssl_ctx, params->cipher_suites) != MG_SSL_OK) {
4055
    MG_SET_PTRPTR(err_msg, "Invalid cipher suite list");
4056
    return MG_SSL_ERROR;
4057
  }
4058

    
4059
  if (!(nc->flags & MG_F_LISTENING) &&
4060
      (ctx->ssl = SSL_new(ctx->ssl_ctx)) == NULL) {
4061
    MG_SET_PTRPTR(err_msg, "Failed to create SSL session");
4062
    return MG_SSL_ERROR;
4063
  }
4064

    
4065
  nc->flags |= MG_F_SSL;
4066

    
4067
  return MG_SSL_OK;
4068
}
4069

    
4070
static enum mg_ssl_if_result mg_ssl_if_ssl_err(struct mg_connection *nc,
4071
                                               int res) {
4072
  struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *) nc->ssl_if_data;
4073
  int err = SSL_get_error(ctx->ssl, res);
4074
  if (err == SSL_ERROR_WANT_READ) return MG_SSL_WANT_READ;
4075
  if (err == SSL_ERROR_WANT_WRITE) return MG_SSL_WANT_WRITE;
4076
  DBG(("%p %p SSL error: %d %d", nc, ctx->ssl_ctx, res, err));
4077
  nc->err = err;
4078
  return MG_SSL_ERROR;
4079
}
4080

    
4081
enum mg_ssl_if_result mg_ssl_if_handshake(struct mg_connection *nc) {
4082
  struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *) nc->ssl_if_data;
4083
  int server_side = (nc->listener != NULL);
4084
  int res;
4085
  /* If descriptor is not yet set, do it now. */
4086
  if (SSL_get_fd(ctx->ssl) < 0) {
4087
    if (SSL_set_fd(ctx->ssl, nc->sock) != 1) return MG_SSL_ERROR;
4088
  }
4089
  res = server_side ? SSL_accept(ctx->ssl) : SSL_connect(ctx->ssl);
4090
  if (res != 1) return mg_ssl_if_ssl_err(nc, res);
4091
  return MG_SSL_OK;
4092
}
4093

    
4094
int mg_ssl_if_read(struct mg_connection *nc, void *buf, size_t buf_size) {
4095
  struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *) nc->ssl_if_data;
4096
  int n = SSL_read(ctx->ssl, buf, buf_size);
4097
  DBG(("%p %d -> %d", nc, (int) buf_size, n));
4098
  if (n < 0) return mg_ssl_if_ssl_err(nc, n);
4099
  if (n == 0) nc->flags |= MG_F_CLOSE_IMMEDIATELY;
4100
  return n;
4101
}
4102

    
4103
int mg_ssl_if_write(struct mg_connection *nc, const void *data, size_t len) {
4104
  struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *) nc->ssl_if_data;
4105
  int n = SSL_write(ctx->ssl, data, len);
4106
  DBG(("%p %d -> %d", nc, (int) len, n));
4107
  if (n <= 0) return mg_ssl_if_ssl_err(nc, n);
4108
  return n;
4109
}
4110

    
4111
void mg_ssl_if_conn_free(struct mg_connection *nc) {
4112
  struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *) nc->ssl_if_data;
4113
  if (ctx == NULL) return;
4114
  nc->ssl_if_data = NULL;
4115
  if (ctx->ssl != NULL) SSL_free(ctx->ssl);
4116
  if (ctx->ssl_ctx != NULL && nc->listener == NULL) SSL_CTX_free(ctx->ssl_ctx);
4117
  memset(ctx, 0, sizeof(*ctx));
4118
  MG_FREE(ctx);
4119
}
4120

    
4121
/*
4122
 * Cipher suite options used for TLS negotiation.
4123
 * https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations
4124
 */
4125
static const char mg_s_cipher_list[] =
4126
#if defined(MG_SSL_CRYPTO_MODERN)
4127
    "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:"
4128
    "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:"
4129
    "DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:"
4130
    "ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:"
4131
    "ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:"
4132
    "ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:"
4133
    "DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:"
4134
    "DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:"
4135
    "!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK"
4136
#elif defined(MG_SSL_CRYPTO_OLD)
4137
    "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:"
4138
    "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:"
4139
    "DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:"
4140
    "ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:"
4141
    "ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:"
4142
    "ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:"
4143
    "DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:"
4144
    "DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:"
4145
    "ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:"
4146
    "AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:"
4147
    "HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:"
4148
    "!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"
4149
#else /* Default - intermediate. */
4150
    "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:"
4151
    "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:"
4152
    "DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:"
4153
    "ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:"
4154
    "ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:"
4155
    "ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:"
4156
    "DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:"
4157
    "DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:"
4158
    "AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:"
4159
    "DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:"
4160
    "!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"
4161
#endif
4162
    ;
4163

    
4164
/*
4165
 * Default DH params for PFS cipher negotiation. This is a 2048-bit group.
4166
 * Will be used if none are provided by the user in the certificate file.
4167
 */
4168
#if !MG_DISABLE_PFS && !defined(KR_VERSION)
4169
static const char mg_s_default_dh_params[] =
4170
    "\
4171
-----BEGIN DH PARAMETERS-----\n\
4172
MIIBCAKCAQEAlvbgD/qh9znWIlGFcV0zdltD7rq8FeShIqIhkQ0C7hYFThrBvF2E\n\
4173
Z9bmgaP+sfQwGpVlv9mtaWjvERbu6mEG7JTkgmVUJrUt/wiRzwTaCXBqZkdUO8Tq\n\
4174
+E6VOEQAilstG90ikN1Tfo+K6+X68XkRUIlgawBTKuvKVwBhuvlqTGerOtnXWnrt\n\
4175
ym//hd3cd5PBYGBix0i7oR4xdghvfR2WLVu0LgdThTBb6XP7gLd19cQ1JuBtAajZ\n\
4176
wMuPn7qlUkEFDIkAZy59/Hue/H2Q2vU/JsvVhHWCQBL4F1ofEAt50il6ZxR1QfFK\n\
4177
9VGKDC4oOgm9DlxwwBoC2FjqmvQlqVV3kwIBAg==\n\
4178
-----END DH PARAMETERS-----\n";
4179
#endif
4180

    
4181
static enum mg_ssl_if_result mg_use_ca_cert(SSL_CTX *ctx, const char *cert) {
4182
  if (cert == NULL || strcmp(cert, "*") == 0) {
4183
    return MG_SSL_OK;
4184
  }
4185
  SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
4186
  return SSL_CTX_load_verify_locations(ctx, cert, NULL) == 1 ? MG_SSL_OK
4187
                                                             : MG_SSL_ERROR;
4188
}
4189

    
4190
static enum mg_ssl_if_result mg_use_cert(SSL_CTX *ctx, const char *cert,
4191
                                         const char *key,
4192
                                         const char **err_msg) {
4193
  if (key == NULL) key = cert;
4194
  if (cert == NULL || cert[0] == '\0' || key == NULL || key[0] == '\0') {
4195
    return MG_SSL_OK;
4196
  } else if (SSL_CTX_use_certificate_file(ctx, cert, 1) == 0) {
4197
    MG_SET_PTRPTR(err_msg, "Invalid SSL cert");
4198
    return MG_SSL_ERROR;
4199
  } else if (SSL_CTX_use_PrivateKey_file(ctx, key, 1) == 0) {
4200
    MG_SET_PTRPTR(err_msg, "Invalid SSL key");
4201
    return MG_SSL_ERROR;
4202
  } else if (SSL_CTX_use_certificate_chain_file(ctx, cert) == 0) {
4203
    MG_SET_PTRPTR(err_msg, "Invalid CA bundle");
4204
    return MG_SSL_ERROR;
4205
  } else {
4206
    SSL_CTX_set_mode(ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
4207
#if !MG_DISABLE_PFS && !defined(KR_VERSION)
4208
    BIO *bio = NULL;
4209
    DH *dh = NULL;
4210

    
4211
    /* Try to read DH parameters from the cert/key file. */
4212
    bio = BIO_new_file(cert, "r");
4213
    if (bio != NULL) {
4214
      dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
4215
      BIO_free(bio);
4216
    }
4217
    /*
4218
     * If there are no DH params in the file, fall back to hard-coded ones.
4219
     * Not ideal, but better than nothing.
4220
     */
4221
    if (dh == NULL) {
4222
      bio = BIO_new_mem_buf((void *) mg_s_default_dh_params, -1);
4223
      dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
4224
      BIO_free(bio);
4225
    }
4226
    if (dh != NULL) {
4227
      SSL_CTX_set_tmp_dh(ctx, dh);
4228
      SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
4229
      DH_free(dh);
4230
    }
4231
#if OPENSSL_VERSION_NUMBER > 0x10002000L
4232
    SSL_CTX_set_ecdh_auto(ctx, 1);
4233
#endif
4234
#endif
4235
  }
4236
  return MG_SSL_OK;
4237
}
4238

    
4239
static enum mg_ssl_if_result mg_set_cipher_list(SSL_CTX *ctx, const char *cl) {
4240
  return (SSL_CTX_set_cipher_list(ctx, cl ? cl : mg_s_cipher_list) == 1
4241
              ? MG_SSL_OK
4242
              : MG_SSL_ERROR);
4243
}
4244

    
4245
const char *mg_set_ssl(struct mg_connection *nc, const char *cert,
4246
                       const char *ca_cert) {
4247
  const char *err_msg = NULL;
4248
  struct mg_ssl_if_conn_params params;
4249
  memset(&params, 0, sizeof(params));
4250
  params.cert = cert;
4251
  params.ca_cert = ca_cert;
4252
  if (mg_ssl_if_conn_init(nc, &params, &err_msg) != MG_SSL_OK) {
4253
    return err_msg;
4254
  }
4255
  return NULL;
4256
}
4257

    
4258
#endif /* MG_ENABLE_SSL && MG_SSL_IF == MG_SSL_IF_OPENSSL */
4259
#ifdef MG_MODULE_LINES
4260
#line 1 "mongoose/src/ssl_if_mbedtls.c"
4261
#endif
4262
/*
4263
 * Copyright (c) 2014-2016 Cesanta Software Limited
4264
 * All rights reserved
4265
 */
4266

    
4267
#if MG_ENABLE_SSL && MG_SSL_IF == MG_SSL_IF_MBEDTLS
4268

    
4269
#include <mbedtls/debug.h>
4270
#include <mbedtls/ecp.h>
4271
#include <mbedtls/platform.h>
4272
#include <mbedtls/ssl.h>
4273
#include <mbedtls/x509_crt.h>
4274

    
4275
static void mg_ssl_mbed_log(void *ctx, int level, const char *file, int line,
4276
                            const char *str) {
4277
  enum cs_log_level cs_level;
4278
  switch (level) {
4279
    case 1:
4280
      cs_level = LL_ERROR;
4281
      break;
4282
    case 2:
4283
    case 3:
4284
      cs_level = LL_DEBUG;
4285
      break;
4286
    default:
4287
      cs_level = LL_VERBOSE_DEBUG;
4288
  }
4289
  /* mbedTLS passes strings with \n at the end, strip it. */
4290
  LOG(cs_level, ("%p %.*s", ctx, (int) (strlen(str) - 1), str));
4291
  (void) file;
4292
  (void) line;
4293
}
4294

    
4295
struct mg_ssl_if_ctx {
4296
  mbedtls_ssl_config *conf;
4297
  mbedtls_ssl_context *ssl;
4298
  mbedtls_x509_crt *cert;
4299
  mbedtls_pk_context *key;
4300
  mbedtls_x509_crt *ca_cert;
4301
  struct mbuf cipher_suites;
4302
};
4303

    
4304
/* Must be provided by the platform. ctx is struct mg_connection. */
4305
extern int mg_ssl_if_mbed_random(void *ctx, unsigned char *buf, size_t len);
4306

    
4307
void mg_ssl_if_init() {
4308
}
4309

    
4310
enum mg_ssl_if_result mg_ssl_if_conn_accept(struct mg_connection *nc,
4311
                                            struct mg_connection *lc) {
4312
  struct mg_ssl_if_ctx *ctx =
4313
      (struct mg_ssl_if_ctx *) MG_CALLOC(1, sizeof(*ctx));
4314
  struct mg_ssl_if_ctx *lc_ctx = (struct mg_ssl_if_ctx *) lc->ssl_if_data;
4315
  nc->ssl_if_data = ctx;
4316
  if (ctx == NULL || lc_ctx == NULL) return MG_SSL_ERROR;
4317
  ctx->ssl = MG_CALLOC(1, sizeof(*ctx->ssl));
4318
  if (mbedtls_ssl_setup(ctx->ssl, lc_ctx->conf) != 0) {
4319
    return MG_SSL_ERROR;
4320
  }
4321
  return MG_SSL_OK;
4322
}
4323

    
4324
static enum mg_ssl_if_result mg_use_cert(struct mg_ssl_if_ctx *ctx,
4325
                                         const char *cert, const char *key,
4326
                                         const char **err_msg);
4327
static enum mg_ssl_if_result mg_use_ca_cert(struct mg_ssl_if_ctx *ctx,
4328
                                            const char *cert);
4329
static enum mg_ssl_if_result mg_set_cipher_list(struct mg_ssl_if_ctx *ctx,
4330
                                                const char *ciphers);
4331

    
4332
enum mg_ssl_if_result mg_ssl_if_conn_init(
4333
    struct mg_connection *nc, const struct mg_ssl_if_conn_params *params,
4334
    const char **err_msg) {
4335
  struct mg_ssl_if_ctx *ctx =
4336
      (struct mg_ssl_if_ctx *) MG_CALLOC(1, sizeof(*ctx));
4337
  DBG(("%p %s,%s,%s", nc, (params->cert ? params->cert : ""),
4338
       (params->key ? params->key : ""),
4339
       (params->ca_cert ? params->ca_cert : "")));
4340

    
4341
  if (ctx == NULL) {
4342
    MG_SET_PTRPTR(err_msg, "Out of memory");
4343
    return MG_SSL_ERROR;
4344
  }
4345
  nc->ssl_if_data = ctx;
4346
  ctx->conf = MG_CALLOC(1, sizeof(*ctx->conf));
4347
  mbuf_init(&ctx->cipher_suites, 0);
4348
  mbedtls_ssl_config_init(ctx->conf);
4349
  mbedtls_ssl_conf_dbg(ctx->conf, mg_ssl_mbed_log, nc);
4350
  if (mbedtls_ssl_config_defaults(
4351
          ctx->conf, (nc->flags & MG_F_LISTENING ? MBEDTLS_SSL_IS_SERVER
4352
                                                 : MBEDTLS_SSL_IS_CLIENT),
4353
          MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT) != 0) {
4354
    MG_SET_PTRPTR(err_msg, "Failed to init SSL config");
4355
    return MG_SSL_ERROR;
4356
  }
4357
  /* TLS 1.2 and up */
4358
  mbedtls_ssl_conf_min_version(ctx->conf, MBEDTLS_SSL_MAJOR_VERSION_3,
4359
                               MBEDTLS_SSL_MINOR_VERSION_3);
4360
  mbedtls_ssl_conf_rng(ctx->conf, mg_ssl_if_mbed_random, nc);
4361

    
4362
  if (params->cert != NULL &&
4363
      mg_use_cert(ctx, params->cert, params->key, err_msg) != MG_SSL_OK) {
4364
    return MG_SSL_ERROR;
4365
  }
4366

    
4367
  if (params->ca_cert != NULL &&
4368
      mg_use_ca_cert(ctx, params->ca_cert) != MG_SSL_OK) {
4369
    MG_SET_PTRPTR(err_msg, "Invalid SSL CA cert");
4370
    return MG_SSL_ERROR;
4371
  }
4372

    
4373
  if (mg_set_cipher_list(ctx, params->cipher_suites) != MG_SSL_OK) {
4374
    MG_SET_PTRPTR(err_msg, "Invalid cipher suite list");
4375
    return MG_SSL_ERROR;
4376
  }
4377

    
4378
  if (!(nc->flags & MG_F_LISTENING)) {
4379
    ctx->ssl = MG_CALLOC(1, sizeof(*ctx->ssl));
4380
    mbedtls_ssl_init(ctx->ssl);
4381
    if (mbedtls_ssl_setup(ctx->ssl, ctx->conf) != 0) {
4382
      MG_SET_PTRPTR(err_msg, "Failed to create SSL session");
4383
      return MG_SSL_ERROR;
4384
    }
4385
    if (params->server_name != NULL &&
4386
        mbedtls_ssl_set_hostname(ctx->ssl, params->server_name) != 0) {
4387
      return MG_SSL_ERROR;
4388
    }
4389
  }
4390

    
4391
  nc->flags |= MG_F_SSL;
4392

    
4393
  return MG_SSL_OK;
4394
}
4395

    
4396
#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL
4397
int ssl_socket_send(void *ctx, const unsigned char *buf, size_t len);
4398
int ssl_socket_recv(void *ctx, unsigned char *buf, size_t len);
4399
#else
4400
static int ssl_socket_send(void *ctx, const unsigned char *buf, size_t len) {
4401
  struct mg_connection *nc = (struct mg_connection *) ctx;
4402
  int n = (int) MG_SEND_FUNC(nc->sock, buf, len, 0);
4403
  LOG(LL_DEBUG, ("%p %d -> %d", nc, (int) len, n));
4404
  if (n >= 0) return n;
4405
  n = mg_get_errno();
4406
  return ((n == EAGAIN || n == EINPROGRESS) ? MBEDTLS_ERR_SSL_WANT_WRITE : -1);
4407
}
4408

    
4409
static int ssl_socket_recv(void *ctx, unsigned char *buf, size_t len) {
4410
  struct mg_connection *nc = (struct mg_connection *) ctx;
4411
  int n = (int) MG_RECV_FUNC(nc->sock, buf, len, 0);
4412
  LOG(LL_DEBUG, ("%p %d <- %d", nc, (int) len, n));
4413
  if (n >= 0) return n;
4414
  n = mg_get_errno();
4415
  return ((n == EAGAIN || n == EINPROGRESS) ? MBEDTLS_ERR_SSL_WANT_READ : -1);
4416
}
4417
#endif
4418

    
4419
static enum mg_ssl_if_result mg_ssl_if_mbed_err(struct mg_connection *nc,
4420
                                                int ret) {
4421
  if (ret == MBEDTLS_ERR_SSL_WANT_READ) return MG_SSL_WANT_READ;
4422
  if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) return MG_SSL_WANT_WRITE;
4423
  if (ret !=
4424
      MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { /* CLOSE_NOTIFY = Normal shutdown */
4425
    LOG(LL_ERROR, ("%p SSL error: %d", nc, ret));
4426
  }
4427
  nc->err = ret;
4428
  nc->flags |= MG_F_CLOSE_IMMEDIATELY;
4429
  return MG_SSL_ERROR;
4430
}
4431

    
4432
static void mg_ssl_if_mbed_free_certs_and_keys(struct mg_ssl_if_ctx *ctx) {
4433
  if (ctx->cert != NULL) {
4434
    mbedtls_x509_crt_free(ctx->cert);
4435
    MG_FREE(ctx->cert);
4436
    ctx->cert = NULL;
4437
    mbedtls_pk_free(ctx->key);
4438
    MG_FREE(ctx->key);
4439
    ctx->key = NULL;
4440
  }
4441
  if (ctx->ca_cert != NULL) {
4442
    mbedtls_ssl_conf_ca_chain(ctx->conf, NULL, NULL);
4443
    mbedtls_x509_crt_free(ctx->ca_cert);
4444
    MG_FREE(ctx->ca_cert);
4445
    ctx->ca_cert = NULL;
4446
  }
4447
}
4448

    
4449
enum mg_ssl_if_result mg_ssl_if_handshake(struct mg_connection *nc) {
4450
  struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *) nc->ssl_if_data;
4451
  int err;
4452
  /* If bio is not yet set, do it now. */
4453
  if (ctx->ssl->p_bio == NULL) {
4454
    mbedtls_ssl_set_bio(ctx->ssl, nc, ssl_socket_send, ssl_socket_recv, NULL);
4455
  }
4456
  err = mbedtls_ssl_handshake(ctx->ssl);
4457
  if (err != 0) return mg_ssl_if_mbed_err(nc, err);
4458
#ifdef MG_SSL_IF_MBEDTLS_FREE_CERTS
4459
  /*
4460
   * Free the peer certificate, we don't need it after handshake.
4461
   * Note that this effectively disables renegotiation.
4462
   */
4463
  mbedtls_x509_crt_free(ctx->ssl->session->peer_cert);
4464
  mbedtls_free(ctx->ssl->session->peer_cert);
4465
  ctx->ssl->session->peer_cert = NULL;
4466
  /* On a client connection we can also free our own and CA certs. */
4467
  if (nc->listener == NULL) {
4468
    if (ctx->conf->key_cert != NULL) {
4469
      /* Note that this assumes one key_cert entry, which matches our init. */
4470
      MG_FREE(ctx->conf->key_cert);
4471
      ctx->conf->key_cert = NULL;
4472
    }
4473
    mbedtls_ssl_conf_ca_chain(ctx->conf, NULL, NULL);
4474
    mg_ssl_if_mbed_free_certs_and_keys(ctx);
4475
  }
4476
#endif
4477
  return MG_SSL_OK;
4478
}
4479

    
4480
int mg_ssl_if_read(struct mg_connection *nc, void *buf, size_t buf_size) {
4481
  struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *) nc->ssl_if_data;
4482
  int n = mbedtls_ssl_read(ctx->ssl, buf, buf_size);
4483
  DBG(("%p %d -> %d", nc, (int) buf_size, n));
4484
  if (n < 0) return mg_ssl_if_mbed_err(nc, n);
4485
  if (n == 0) nc->flags |= MG_F_CLOSE_IMMEDIATELY;
4486
  return n;
4487
}
4488

    
4489
int mg_ssl_if_write(struct mg_connection *nc, const void *data, size_t len) {
4490
  struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *) nc->ssl_if_data;
4491
  int n = mbedtls_ssl_write(ctx->ssl, data, len);
4492
  DBG(("%p %d -> %d", nc, (int) len, n));
4493
  if (n < 0) return mg_ssl_if_mbed_err(nc, n);
4494
  return n;
4495
}
4496

    
4497
void mg_ssl_if_conn_free(struct mg_connection *nc) {
4498
  struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *) nc->ssl_if_data;
4499
  if (ctx == NULL) return;
4500
  nc->ssl_if_data = NULL;
4501
  if (ctx->ssl != NULL) {
4502
    mbedtls_ssl_free(ctx->ssl);
4503
    MG_FREE(ctx->ssl);
4504
  }
4505
  mg_ssl_if_mbed_free_certs_and_keys(ctx);
4506
  if (ctx->conf != NULL) {
4507
    mbedtls_ssl_config_free(ctx->conf);
4508
    MG_FREE(ctx->conf);
4509
  }
4510
  mbuf_free(&ctx->cipher_suites);
4511
  memset(ctx, 0, sizeof(*ctx));
4512
  MG_FREE(ctx);
4513
}
4514

    
4515
static enum mg_ssl_if_result mg_use_ca_cert(struct mg_ssl_if_ctx *ctx,
4516
                                            const char *ca_cert) {
4517
  if (ca_cert == NULL || strcmp(ca_cert, "*") == 0) {
4518
    return MG_SSL_OK;
4519
  }
4520
  ctx->ca_cert = MG_CALLOC(1, sizeof(*ctx->ca_cert));
4521
  mbedtls_x509_crt_init(ctx->ca_cert);
4522
  if (mbedtls_x509_crt_parse_file(ctx->ca_cert, ca_cert) != 0) {
4523
    return MG_SSL_ERROR;
4524
  }
4525
  mbedtls_ssl_conf_ca_chain(ctx->conf, ctx->ca_cert, NULL);
4526
  mbedtls_ssl_conf_authmode(ctx->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
4527
  return MG_SSL_OK;
4528
}
4529

    
4530
static enum mg_ssl_if_result mg_use_cert(struct mg_ssl_if_ctx *ctx,
4531
                                         const char *cert, const char *key,
4532
                                         const char **err_msg) {
4533
  if (key == NULL) key = cert;
4534
  if (cert == NULL || cert[0] == '\0' || key == NULL || key[0] == '\0') {
4535
    return MG_SSL_OK;
4536
  }
4537
  ctx->cert = MG_CALLOC(1, sizeof(*ctx->cert));
4538
  mbedtls_x509_crt_init(ctx->cert);
4539
  ctx->key = MG_CALLOC(1, sizeof(*ctx->key));
4540
  mbedtls_pk_init(ctx->key);
4541
  if (mbedtls_x509_crt_parse_file(ctx->cert, cert) != 0) {
4542
    MG_SET_PTRPTR(err_msg, "Invalid SSL cert");
4543
    return MG_SSL_ERROR;
4544
  }
4545
  if (mbedtls_pk_parse_keyfile(ctx->key, key, NULL) != 0) {
4546
    MG_SET_PTRPTR(err_msg, "Invalid SSL key");
4547
    return MG_SSL_ERROR;
4548
  }
4549
  if (mbedtls_ssl_conf_own_cert(ctx->conf, ctx->cert, ctx->key) != 0) {
4550
    MG_SET_PTRPTR(err_msg, "Invalid SSL key or cert");
4551
    return MG_SSL_ERROR;
4552
  }
4553
  return MG_SSL_OK;
4554
}
4555

    
4556
static const int mg_s_cipher_list[] = {
4557
    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
4558
    MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
4559
    MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
4560
    MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
4561
    MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
4562
    MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
4563
    MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
4564
    MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
4565
    MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
4566
    MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
4567
    MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256,
4568
    MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256,
4569
    MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, 0};
4570

    
4571
/*
4572
 * Ciphers can be specified as a colon-separated list of cipher suite names.
4573
 * These can be found in
4574
 * https://github.com/ARMmbed/mbedtls/blob/development/library/ssl_ciphersuites.c#L267
4575
 * E.g.: TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-256-CCM
4576
 */
4577
static enum mg_ssl_if_result mg_set_cipher_list(struct mg_ssl_if_ctx *ctx,
4578
                                                const char *ciphers) {
4579
  if (ciphers != NULL) {
4580
    int l, id;
4581
    const char *s = ciphers;
4582
    char *e, tmp[50];
4583
    while (s != NULL) {
4584
      e = strchr(s, ':');
4585
      l = (e != NULL ? (e - s) : (int) strlen(s));
4586
      strncpy(tmp, s, l);
4587
      tmp[l] = '\0';
4588
      id = mbedtls_ssl_get_ciphersuite_id(tmp);
4589
      DBG(("%s -> %04x", tmp, id));
4590
      if (id != 0) {
4591
        mbuf_append(&ctx->cipher_suites, &id, sizeof(id));
4592
      }
4593
      s = (e != NULL ? e + 1 : NULL);
4594
    }
4595
    if (ctx->cipher_suites.len == 0) return MG_SSL_ERROR;
4596
    id = 0;
4597
    mbuf_append(&ctx->cipher_suites, &id, sizeof(id));
4598
    mbedtls_ssl_conf_ciphersuites(ctx->conf,
4599
                                  (const int *) ctx->cipher_suites.buf);
4600
  } else {
4601
    mbedtls_ssl_conf_ciphersuites(ctx->conf, mg_s_cipher_list);
4602
  }
4603
  return MG_SSL_OK;
4604
}
4605

    
4606
const char *mg_set_ssl(struct mg_connection *nc, const char *cert,
4607
                       const char *ca_cert) {
4608
  const char *err_msg = NULL;
4609
  struct mg_ssl_if_conn_params params;
4610
  memset(&params, 0, sizeof(params));
4611
  params.cert = cert;
4612
  params.ca_cert = ca_cert;
4613
  if (mg_ssl_if_conn_init(nc, &params, &err_msg) != MG_SSL_OK) {
4614
    return err_msg;
4615
  }
4616
  return NULL;
4617
}
4618

    
4619
/* Lazy RNG. Warning: it would be a bad idea to do this in production! */
4620
#ifdef MG_SSL_MBED_DUMMY_RANDOM
4621
int mg_ssl_if_mbed_random(void *ctx, unsigned char *buf, size_t len) {
4622
  (void) ctx;
4623
  while (len--) *buf++ = rand();
4624
  return 0;
4625
}
4626
#endif
4627

    
4628
#endif /* MG_ENABLE_SSL && MG_SSL_IF == MG_SSL_IF_MBEDTLS */
4629
#ifdef MG_MODULE_LINES
4630
#line 1 "mongoose/src/uri.c"
4631
#endif
4632
/*
4633
 * Copyright (c) 2014 Cesanta Software Limited
4634
 * All rights reserved
4635
 */
4636

    
4637
/* Amalgamated: #include "mongoose/src/internal.h" */
4638
/* Amalgamated: #include "mongoose/src/uri.h" */
4639

    
4640
/*
4641
 * scan string until `sep`, keeping track of component boundaries in `res`.
4642
 *
4643
 * `p` will point to the char after the separator or it will be `end`.
4644
 */
4645
static void parse_uri_component(const char **p, const char *end, char sep,
4646
                                struct mg_str *res) {
4647
  res->p = *p;
4648
  for (; *p < end; (*p)++) {
4649
    if (**p == sep) {
4650
      break;
4651
    }
4652
  }
4653
  res->len = (*p) - res->p;
4654
  if (*p < end) (*p)++;
4655
}
4656

    
4657
int mg_parse_uri(struct mg_str uri, struct mg_str *scheme,
4658
                 struct mg_str *user_info, struct mg_str *host,
4659
                 unsigned int *port, struct mg_str *path, struct mg_str *query,
4660
                 struct mg_str *fragment) {
4661
  struct mg_str rscheme = {0, 0}, ruser_info = {0, 0}, rhost = {0, 0},
4662
                rpath = {0, 0}, rquery = {0, 0}, rfragment = {0, 0};
4663
  unsigned int rport = 0;
4664
  enum {
4665
    P_START,
4666
    P_SCHEME_OR_PORT,
4667
    P_USER_INFO,
4668
    P_HOST,
4669
    P_PORT,
4670
    P_REST
4671
  } state = P_START;
4672

    
4673
  const char *p = uri.p, *end = p + uri.len;
4674
  while (p < end) {
4675
    switch (state) {
4676
      case P_START:
4677
        /*
4678
         * expecting on of:
4679
         * - `scheme://xxxx`
4680
         * - `xxxx:port`
4681
         * - `xxxx/path`
4682
         */
4683
        for (; p < end; p++) {
4684
          if (*p == ':') {
4685
            state = P_SCHEME_OR_PORT;
4686
            break;
4687
          } else if (*p == '/') {
4688
            state = P_REST;
4689
            break;
4690
          }
4691
        }
4692
        if (state == P_START || state == P_REST) {
4693
          rhost.p = uri.p;
4694
          rhost.len = p - uri.p;
4695
        }
4696
        break;
4697
      case P_SCHEME_OR_PORT:
4698
        if (end - p >= 3 && strncmp(p, "://", 3) == 0) {
4699
          rscheme.p = uri.p;
4700
          rscheme.len = p - uri.p;
4701
          state = P_USER_INFO;
4702
          p += 2; /* point to last separator char */
4703
        } else {
4704
          rhost.p = uri.p;
4705
          rhost.len = p - uri.p;
4706
          state = P_PORT;
4707
        }
4708
        break;
4709
      case P_USER_INFO:
4710
        p++;
4711
        ruser_info.p = p;
4712
        for (; p < end; p++) {
4713
          if (*p == '@') {
4714
            state = P_HOST;
4715
            break;
4716
          } else if (*p == '/') {
4717
            break;
4718
          }
4719
        }
4720
        if (p == end || *p == '/') {
4721
          /* backtrack and parse as host */
4722
          state = P_HOST;
4723
          p = ruser_info.p;
4724
        }
4725
        ruser_info.len = p - ruser_info.p;
4726
        break;
4727
      case P_HOST:
4728
        if (*p == '@') p++;
4729
        rhost.p = p;
4730
        for (; p < end; p++) {
4731
          if (*p == ':') {
4732
            state = P_PORT;
4733
            break;
4734
          } else if (*p == '/') {
4735
            state = P_REST;
4736
            break;
4737
          }
4738
        }
4739
        rhost.len = p - rhost.p;
4740
        break;
4741
      case P_PORT:
4742
        p++;
4743
        for (; p < end; p++) {
4744
          if (*p == '/') {
4745
            state = P_REST;
4746
            break;
4747
          }
4748
          rport *= 10;
4749
          rport += *p - '0';
4750
        }
4751
        break;
4752
      case P_REST:
4753
        /* `p` points to separator. `path` includes the separator */
4754
        parse_uri_component(&p, end, '?', &rpath);
4755
        parse_uri_component(&p, end, '#', &rquery);
4756
        parse_uri_component(&p, end, '\0', &rfragment);
4757
        break;
4758
    }
4759
  }
4760

    
4761
  if (scheme != 0) *scheme = rscheme;
4762
  if (user_info != 0) *user_info = ruser_info;
4763
  if (host != 0) *host = rhost;
4764
  if (port != 0) *port = rport;
4765
  if (path != 0) *path = rpath;
4766
  if (query != 0) *query = rquery;
4767
  if (fragment != 0) *fragment = rfragment;
4768

    
4769
  return 0;
4770
}
4771

    
4772
/* Normalize the URI path. Remove/resolve "." and "..". */
4773
int mg_normalize_uri_path(const struct mg_str *in, struct mg_str *out) {
4774
  const char *s = in->p, *se = s + in->len;
4775
  char *cp = (char *) out->p, *d;
4776

    
4777
  if (in->len == 0 || *s != '/') {
4778
    out->len = 0;
4779
    return 0;
4780
  }
4781

    
4782
  d = cp;
4783

    
4784
  while (s < se) {
4785
    const char *next = s;
4786
    struct mg_str component;
4787
    parse_uri_component(&next, se, '/', &component);
4788
    if (mg_vcmp(&component, ".") == 0) {
4789
      /* Yum. */
4790
    } else if (mg_vcmp(&component, "..") == 0) {
4791
      /* Backtrack to previous slash. */
4792
      if (d > cp + 1 && *(d - 1) == '/') d--;
4793
      while (d > cp && *(d - 1) != '/') d--;
4794
    } else {
4795
      memmove(d, s, next - s);
4796
      d += next - s;
4797
    }
4798
    s = next;
4799
  }
4800
  if (d == cp) *d++ = '/';
4801

    
4802
  out->p = cp;
4803
  out->len = d - cp;
4804
  return 1;
4805
}
4806
#ifdef MG_MODULE_LINES
4807
#line 1 "mongoose/src/http.c"