Statistics
| Branch: | Tag: | Revision:

mongoose / mongoose.c @ 7988acbf

History | View | Annotate | Download (440 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
  if (cs_log_file == NULL) cs_log_file = stderr;
298
  fprintf(cs_log_file, "%-20s ", func);
299
#if CS_LOG_ENABLE_TS_DIFF
300
  {
301
    double now = cs_time();
302
    fprintf(cs_log_file, "%7u ", (unsigned int) ((now - cs_log_ts) * 1000000));
303
    cs_log_ts = now;
304
  }
305
#endif
306
}
307

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

    
318
void cs_log_set_file(FILE *file) WEAK;
319
void cs_log_set_file(FILE *file) {
320
  cs_log_file = file;
321
}
322

    
323
#endif /* CS_ENABLE_STDIO */
324

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

    
340
#ifndef EXCLUDE_COMMON
341

    
342
/* Amalgamated: #include "common/base64.h" */
343

    
344
#include <string.h>
345

    
346
/* Amalgamated: #include "common/cs_dbg.h" */
347

    
348
/* ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ */
349

    
350
#define NUM_UPPERCASES ('Z' - 'A' + 1)
351
#define NUM_LETTERS (NUM_UPPERCASES * 2)
352
#define NUM_DIGITS ('9' - '0' + 1)
353

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

    
372
static void cs_base64_emit_chunk(struct cs_base64_ctx *ctx) {
373
  int a, b, c;
374

    
375
  a = ctx->chunk[0];
376
  b = ctx->chunk[1];
377
  c = ctx->chunk[2];
378

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

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

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

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

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

    
444
#define BASE64_OUT(ch) \
445
  do {                 \
446
    dst[j++] = (ch);   \
447
  } while (0)
448

    
449
#define BASE64_FLUSH() \
450
  do {                 \
451
    dst[j++] = '\0';   \
452
  } while (0)
453

    
454
void cs_base64_encode(const unsigned char *src, int src_len, char *dst) {
455
  BASE64_ENCODE_BODY;
456
}
457

    
458
#undef BASE64_OUT
459
#undef BASE64_FLUSH
460

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

    
468
#define BASE64_FLUSH()
469

    
470
void cs_fprint_base64(FILE *f, const unsigned char *src, int src_len) {
471
  BASE64_ENCODE_BODY;
472
}
473

    
474
#undef BASE64_OUT
475
#undef BASE64_FLUSH
476
#endif /* CS_ENABLE_STDIO */
477

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

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

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

    
548
#ifndef CS_COMMON_CS_DIRENT_H_
549
#define CS_COMMON_CS_DIRENT_H_
550

    
551
#include <limits.h>
552

    
553
/* Amalgamated: #include "common/platform.h" */
554

    
555
#ifdef __cplusplus
556
extern "C" {
557
#endif /* __cplusplus */
558

    
559
#ifdef CS_DEFINE_DIRENT
560
typedef struct { int dummy; } DIR;
561

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

    
572
DIR *opendir(const char *dir_name);
573
int closedir(DIR *dir);
574
struct dirent *readdir(DIR *dir);
575
#endif /* CS_DEFINE_DIRENT */
576

    
577
#ifdef __cplusplus
578
}
579
#endif /* __cplusplus */
580

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

    
590
#ifndef EXCLUDE_COMMON
591

    
592
/* Amalgamated: #include "common/cs_dirent.h" */
593

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

    
599
#ifndef MG_FREE
600
#define MG_FREE free
601
#endif
602

    
603
#ifndef MG_MALLOC
604
#define MG_MALLOC malloc
605
#endif
606

    
607
#ifdef _WIN32
608
struct win32_dir {
609
  DIR d;
610
  HANDLE handle;
611
  WIN32_FIND_DATAW info;
612
  struct dirent result;
613
};
614

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

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

    
637
  return (DIR *) dir;
638
}
639

    
640
int closedir(DIR *d) {
641
  struct win32_dir *dir = (struct win32_dir *) d;
642
  int result = 0;
643

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

    
653
  return result;
654
}
655

    
656
struct dirent *readdir(DIR *d) {
657
  struct win32_dir *dir = (struct win32_dir *) d;
658
  struct dirent *result = NULL;
659

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

    
668
      if (!FindNextFileW(dir->handle, &dir->info)) {
669
        (void) FindClose(dir->handle);
670
        dir->handle = INVALID_HANDLE_VALUE;
671
      }
672

    
673
    } else {
674
      SetLastError(ERROR_FILE_NOT_FOUND);
675
    }
676
  } else {
677
    SetLastError(ERROR_BAD_ARGUMENTS);
678
  }
679

    
680
  return result;
681
}
682
#endif
683

    
684
#endif /* EXCLUDE_COMMON */
685

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

    
696
/* Amalgamated: #include "common/cs_time.h" */
697

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

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

    
747
#ifndef CS_COMMON_CS_ENDIAN_H_
748
#define CS_COMMON_CS_ENDIAN_H_
749

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

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

    
786
/* Amalgamated: #include "common/md5.h" */
787
/* Amalgamated: #include "common/str_util.h" */
788

    
789
#if !defined(EXCLUDE_COMMON)
790
#if !DISABLE_MD5
791

    
792
/* Amalgamated: #include "common/cs_endian.h" */
793

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

    
809
#define F1(x, y, z) (z ^ (x & (y ^ z)))
810
#define F2(x, y, z) F1(z, x, y)
811
#define F3(x, y, z) (x ^ y ^ z)
812
#define F4(x, y, z) (y ^ (x | ~z))
813

    
814
#define MD5STEP(f, w, x, y, z, data, s) \
815
  (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x)
816

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

    
827
  ctx->bits[0] = 0;
828
  ctx->bits[1] = 0;
829
}
830

    
831
static void MD5Transform(uint32_t buf[4], uint32_t const in[16]) {
832
  register uint32_t a, b, c, d;
833

    
834
  a = buf[0];
835
  b = buf[1];
836
  c = buf[2];
837
  d = buf[3];
838

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

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

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

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

    
907
  buf[0] += a;
908
  buf[1] += b;
909
  buf[2] += c;
910
  buf[3] += d;
911
}
912

    
913
void MD5_Update(MD5_CTX *ctx, const unsigned char *buf, size_t len) {
914
  uint32_t t;
915

    
916
  t = ctx->bits[0];
917
  if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) ctx->bits[1]++;
918
  ctx->bits[1] += (uint32_t) len >> 29;
919

    
920
  t = (t >> 3) & 0x3f;
921

    
922
  if (t) {
923
    unsigned char *p = (unsigned char *) ctx->in + t;
924

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

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

    
945
  memcpy(ctx->in, buf, len);
946
}
947

    
948
void MD5_Final(unsigned char digest[16], MD5_CTX *ctx) {
949
  unsigned count;
950
  unsigned char *p;
951
  uint32_t *a;
952

    
953
  count = (ctx->bits[0] >> 3) & 0x3F;
954

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

    
968
  a = (uint32_t *) ctx->in;
969
  a[14] = ctx->bits[0];
970
  a[15] = ctx->bits[1];
971

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

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

    
985
  MD5_Init(&ctx);
986

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

    
994
  MD5_Final(hash, &ctx);
995
  cs_to_hex(buf, hash, sizeof(hash));
996

    
997
  return buf;
998
}
999

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

    
1009
#ifndef EXCLUDE_COMMON
1010

    
1011
#include <assert.h>
1012
#include <string.h>
1013
/* Amalgamated: #include "common/mbuf.h" */
1014

    
1015
#ifndef MBUF_REALLOC
1016
#define MBUF_REALLOC realloc
1017
#endif
1018

    
1019
#ifndef MBUF_FREE
1020
#define MBUF_FREE free
1021
#endif
1022

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

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

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

    
1053
void mbuf_trim(struct mbuf *mbuf) WEAK;
1054
void mbuf_trim(struct mbuf *mbuf) {
1055
  mbuf_resize(mbuf, mbuf->len);
1056
}
1057

    
1058
size_t mbuf_insert(struct mbuf *a, size_t off, const void *buf, size_t) WEAK;
1059
size_t mbuf_insert(struct mbuf *a, size_t off, const void *buf, size_t len) {
1060
  char *p = NULL;
1061

    
1062
  assert(a != NULL);
1063
  assert(a->len <= a->size);
1064
  assert(off <= a->len);
1065

    
1066
  /* check overflow */
1067
  if (~(size_t) 0 - (size_t) a->buf < len) return 0;
1068

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

    
1088
  return len;
1089
}
1090

    
1091
size_t mbuf_append(struct mbuf *a, const void *buf, size_t len) WEAK;
1092
size_t mbuf_append(struct mbuf *a, const void *buf, size_t len) {
1093
  return mbuf_insert(a, a->len, buf, len);
1094
}
1095

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

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

    
1113
/* Amalgamated: #include "common/mg_str.h" */
1114

    
1115
#include <stdlib.h>
1116
#include <string.h>
1117

    
1118
int mg_ncasecmp(const char *s1, const char *s2, size_t len) WEAK;
1119

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

    
1127
struct mg_str mg_mk_str_n(const char *s, size_t len) WEAK;
1128
struct mg_str mg_mk_str_n(const char *s, size_t len) {
1129
  struct mg_str ret = {s, len};
1130
  return ret;
1131
}
1132

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

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

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

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

    
1179
int mg_strncmp(const struct mg_str, const struct mg_str, size_t n) WEAK;
1180
int mg_strncmp(const struct mg_str str1, const struct mg_str str2, size_t n) {
1181
  struct mg_str s1 = str1;
1182
  struct mg_str s2 = str2;
1183

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

    
1198
/* Amalgamated: #include "common/sha1.h" */
1199

    
1200
#if !DISABLE_SHA1 && !defined(EXCLUDE_COMMON)
1201

    
1202
/* Amalgamated: #include "common/cs_endian.h" */
1203

    
1204
#define SHA1HANDSOFF
1205
#if defined(__sun)
1206
/* Amalgamated: #include "common/solarisfixes.h" */
1207
#endif
1208

    
1209
union char64long16 {
1210
  unsigned char c[64];
1211
  uint32_t l[16];
1212
};
1213

    
1214
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
1215

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

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

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

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

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

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

    
1368
void cs_sha1_update(cs_sha1_ctx *context, const unsigned char *data,
1369
                    uint32_t len) {
1370
  uint32_t i, j;
1371

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

    
1388
void cs_sha1_final(unsigned char digest[20], cs_sha1_ctx *context) {
1389
  unsigned i;
1390
  unsigned char finalcount[8], c;
1391

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

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

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

    
1426
  memset(buf1, 0, sizeof(buf1));
1427
  memset(buf2, 0, sizeof(buf2));
1428
  memcpy(buf1, key, keylen);
1429
  memcpy(buf2, key, keylen);
1430

    
1431
  for (i = 0; i < sizeof(buf1); i++) {
1432
    buf1[i] ^= 0x36;
1433
    buf2[i] ^= 0x5c;
1434
  }
1435

    
1436
  cs_sha1_init(&ctx);
1437
  cs_sha1_update(&ctx, buf1, sizeof(buf1));
1438
  cs_sha1_update(&ctx, data, datalen);
1439
  cs_sha1_final(out, &ctx);
1440

    
1441
  cs_sha1_init(&ctx);
1442
  cs_sha1_update(&ctx, buf2, sizeof(buf2));
1443
  cs_sha1_update(&ctx, out, 20);
1444
  cs_sha1_final(out, &ctx);
1445
}
1446

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

    
1456
#ifndef EXCLUDE_COMMON
1457

    
1458
/* Amalgamated: #include "common/platform.h" */
1459
/* Amalgamated: #include "common/str_util.h" */
1460

    
1461
#ifndef C_DISABLE_BUILTIN_SNPRINTF
1462
#define C_DISABLE_BUILTIN_SNPRINTF 0
1463
#endif
1464

    
1465
#ifndef MG_MALLOC
1466
#define MG_MALLOC malloc
1467
#endif
1468

    
1469
#ifndef MG_FREE
1470
#define MG_FREE free
1471
#endif
1472

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

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

    
1487
#define C_SNPRINTF_FLAG_ZERO 1
1488

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

    
1500
  if (num < 0) {
1501
    neg++;
1502
    num = -num;
1503
  }
1504

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

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

    
1523
  /* And sign */
1524
  if (neg) {
1525
    tmp[k++] = '-';
1526
  }
1527

    
1528
  /* Now output */
1529
  while (--k >= 0) {
1530
    C_SNPRINTF_APPEND_CHAR(tmp[k]);
1531
  }
1532

    
1533
  return i;
1534
}
1535

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

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

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

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

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

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

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

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

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

    
1670
  return i;
1671
}
1672
#endif
1673

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

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

    
1689
  strncpy(buf, path, sizeof(buf));
1690
  buf[sizeof(buf) - 1] = '\0';
1691

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

    
1696
  memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
1697
  ret = MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int) wbuf_len);
1698

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

    
1710
  return ret;
1711
}
1712
#endif /* _WIN32 */
1713

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

    
1720
  for (i = 0; i < slen; i++) {
1721
    if (i + find_length > slen) {
1722
      return NULL;
1723
    }
1724

    
1725
    if (strncmp(&s[i], find, find_length) == 0) {
1726
      return &s[i];
1727
    }
1728
  }
1729

    
1730
  return NULL;
1731
}
1732

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

    
1745
void cs_to_hex(char *to, const unsigned char *p, size_t len) WEAK;
1746
void cs_to_hex(char *to, const unsigned char *p, size_t len) {
1747
  static const char *hex = "0123456789abcdef";
1748

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

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

    
1767
void cs_from_hex(char *to, const char *p, size_t len) WEAK;
1768
void cs_from_hex(char *to, const char *p, size_t len) {
1769
  size_t i;
1770

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

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

    
1796
static int str_util_lowercase(const char *s) {
1797
  return tolower(*(const unsigned char *) s);
1798
}
1799

    
1800
int mg_ncasecmp(const char *s1, const char *s2, size_t len) WEAK;
1801
int mg_ncasecmp(const char *s1, const char *s2, size_t len) {
1802
  int diff = 0;
1803

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

    
1808
  return diff;
1809
}
1810

    
1811
int mg_casecmp(const char *s1, const char *s2) WEAK;
1812
int mg_casecmp(const char *s1, const char *s2) {
1813
  return mg_ncasecmp(s1, s2, (size_t) ~0);
1814
}
1815

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

    
1826
int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap) WEAK;
1827
int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap) {
1828
  va_list ap_copy;
1829
  int len;
1830

    
1831
  va_copy(ap_copy, ap);
1832
  len = vsnprintf(*buf, size, fmt, ap_copy);
1833
  va_end(ap_copy);
1834

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

    
1860
  return len;
1861
}
1862

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

    
1872
#ifndef CS_MONGOOSE_SRC_TUN_H_
1873
#define CS_MONGOOSE_SRC_TUN_H_
1874

    
1875
#if MG_ENABLE_TUN
1876

    
1877
/* Amalgamated: #include "mongoose/src/net.h" */
1878
/* Amalgamated: #include "common/mg_str.h" */
1879

    
1880
#ifndef MG_TUN_RECONNECT_INTERVAL
1881
#define MG_TUN_RECONNECT_INTERVAL 1
1882
#endif
1883

    
1884
#define MG_TUN_PROTO_NAME "mg_tun"
1885

    
1886
#define MG_TUN_DATA_FRAME 0x0
1887
#define MG_TUN_F_END_STREAM 0x1
1888

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

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

    
1914
struct mg_tun_client {
1915
  struct mg_mgr *mgr;
1916
  struct mg_iface *iface;
1917
  const char *disp_url;
1918
  struct mg_tun_ssl_opts ssl;
1919

    
1920
  uint32_t last_stream_id; /* stream id of most recently accepted connection */
1921

    
1922
  struct mg_connection *disp;
1923
  struct mg_connection *listener;
1924
  struct mg_connection *reconnect;
1925
};
1926

    
1927
#ifdef __cplusplus
1928
extern "C" {
1929
#endif /* __cplusplus */
1930

    
1931
struct mg_connection *mg_tun_bind_opt(struct mg_mgr *mgr,
1932
                                      const char *dispatcher,
1933
                                      mg_event_handler_t handler,
1934
                                      struct mg_bind_opts opts);
1935

    
1936
int mg_tun_parse_frame(void *data, size_t len, struct mg_tun_frame *frame);
1937

    
1938
void mg_tun_send_frame(struct mg_connection *ws, uint32_t stream_id,
1939
                       uint8_t type, uint8_t flags, struct mg_str msg);
1940

    
1941
void mg_tun_destroy_client(struct mg_tun_client *client);
1942

    
1943
#ifdef __cplusplus
1944
}
1945
#endif /* __cplusplus */
1946

    
1947
#endif /* MG_ENABLE_TUN */
1948

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

    
1971
/* Amalgamated: #include "common/cs_time.h" */
1972
/* Amalgamated: #include "mongoose/src/dns.h" */
1973
/* Amalgamated: #include "mongoose/src/internal.h" */
1974
/* Amalgamated: #include "mongoose/src/resolv.h" */
1975
/* Amalgamated: #include "mongoose/src/util.h" */
1976
/* Amalgamated: #include "mongoose/src/tun.h" */
1977

    
1978
#define MG_MAX_HOST_LEN 200
1979

    
1980
#define MG_COPY_COMMON_CONNECTION_OPTIONS(dst, src) \
1981
  memcpy(dst, src, sizeof(*dst));
1982

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

    
1993
#ifndef intptr_t
1994
#define intptr_t long
1995
#endif
1996

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

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

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

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

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

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

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

    
2096
  memset(conn, 0, sizeof(*conn));
2097
  MG_FREE(conn);
2098
}
2099

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

    
2108
void mg_mgr_init(struct mg_mgr *m, void *user_data) {
2109
  struct mg_mgr_init_opts opts;
2110
  memset(&opts, 0, sizeof(opts));
2111
  mg_mgr_init_opt(m, user_data, opts);
2112
}
2113

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

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

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

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

    
2170
  if (v7_is_string(arg1)) {
2171
    const char *data = v7_get_string(v7, &arg1, &len);
2172
    mg_send(c, data, len);
2173
  }
2174

    
2175
  *res = v7_mk_number(v7, len);
2176

    
2177
  return V7_OK;
2178
}
2179

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

    
2189
void mg_mgr_free(struct mg_mgr *m) {
2190
  struct mg_connection *conn, *tmp_conn;
2191

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

    
2197
#if MG_ENABLE_BROADCAST
2198
  if (m->ctl[0] != INVALID_SOCKET) closesocket(m->ctl[0]);
2199
  if (m->ctl[1] != INVALID_SOCKET) closesocket(m->ctl[1]);
2200
  m->ctl[0] = m->ctl[1] = INVALID_SOCKET;
2201
#endif
2202

    
2203
  for (conn = m->active_connections; conn != NULL; conn = tmp_conn) {
2204
    tmp_conn = conn->next;
2205
    mg_close_conn(conn);
2206
  }
2207

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

    
2218
time_t mg_mgr_poll(struct mg_mgr *m, int timeout_ms) {
2219
  int i;
2220
  time_t now = 0; /* oh GCC, seriously ? */
2221

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

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

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

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

    
2244
  return len;
2245
}
2246

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

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

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

    
2294
MG_INTERNAL struct mg_connection *mg_create_connection_base(
2295
    struct mg_mgr *mgr, mg_event_handler_t callback,
2296
    struct mg_add_sock_opts opts) {
2297
  struct mg_connection *conn;
2298

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

    
2318
  return conn;
2319
}
2320

    
2321
MG_INTERNAL struct mg_connection *mg_create_connection(
2322
    struct mg_mgr *mgr, mg_event_handler_t callback,
2323
    struct mg_add_sock_opts opts) {
2324
  struct mg_connection *conn = mg_create_connection_base(mgr, callback, opts);
2325

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

    
2334
  return conn;
2335
}
2336

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

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

    
2366
  *proto = SOCK_STREAM;
2367

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

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

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

    
2419
  /* Required for MG_ENABLE_ASYNC_RESOLVER=0 */
2420
  (void) host;
2421
  (void) host_len;
2422

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

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

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

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

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

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

    
2501
void mg_if_recv_tcp_cb(struct mg_connection *nc, void *buf, int len, int own) {
2502
  mg_recv_common(nc, buf, len, own);
2503
}
2504

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

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

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

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

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

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

    
2626
  if (e == MG_RESOLVE_TIMEOUT) {
2627
    double now = mg_time();
2628
    mg_call(nc, NULL, MG_EV_TIMER, &now);
2629
  }
2630

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

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

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

    
2655
  MG_COPY_COMMON_CONNECTION_OPTIONS(&add_sock_opts, &opts);
2656

    
2657
  if ((nc = mg_create_connection(mgr, callback, add_sock_opts)) == NULL) {
2658
    return NULL;
2659
  }
2660

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

    
2669
  nc->flags |= opts.flags & _MG_ALLOWED_CONNECT_FLAGS_MASK;
2670
  nc->flags |= (proto == SOCK_DGRAM) ? MG_F_UDP : 0;
2671
  nc->user_data = opts.user_data;
2672

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

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

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

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

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

    
2755
  MG_COPY_COMMON_CONNECTION_OPTIONS(&add_sock_opts, &opts);
2756

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

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

    
2769
  nc = mg_create_connection(mgr, callback, add_sock_opts);
2770
  if (nc == NULL) {
2771
    return NULL;
2772
  }
2773

    
2774
  nc->sa = sa;
2775
  nc->flags |= MG_F_LISTENING;
2776
  if (proto == SOCK_DGRAM) nc->flags |= MG_F_UDP;
2777

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

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

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

    
2818
  return nc;
2819
}
2820

    
2821
struct mg_connection *mg_next(struct mg_mgr *s, struct mg_connection *conn) {
2822
  return conn == NULL ? s->active_connections : conn->next;
2823
}
2824

    
2825
#if MG_ENABLE_BROADCAST
2826
void mg_broadcast(struct mg_mgr *mgr, mg_event_handler_t cb, void *data,
2827
                  size_t len) {
2828
  struct ctl_msg ctl_msg;
2829

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

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

    
2851
static int isbyte(int n) {
2852
  return n >= 0 && n <= 255;
2853
}
2854

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

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

    
2868
  return len;
2869
}
2870

    
2871
int mg_check_ip_acl(const char *acl, uint32_t remote_ip) {
2872
  int allowed, flag;
2873
  uint32_t net, mask;
2874
  struct mg_str vec;
2875

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

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

    
2886
    if (net == (remote_ip & mask)) {
2887
      allowed = flag;
2888
    }
2889
  }
2890

    
2891
  DBG(("%08x %c", remote_ip, allowed));
2892
  return allowed == '+';
2893
}
2894

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

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

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

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

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

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

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

    
2957
#ifndef CS_MONGOOSE_SRC_NET_IF_SOCKET_H_
2958
#define CS_MONGOOSE_SRC_NET_IF_SOCKET_H_
2959

    
2960
/* Amalgamated: #include "mongoose/src/net_if.h" */
2961

    
2962
#ifdef __cplusplus
2963
extern "C" {
2964
#endif /* __cplusplus */
2965

    
2966
#ifndef MG_ENABLE_NET_IF_SOCKET
2967
#define MG_ENABLE_NET_IF_SOCKET MG_NET_IF == MG_NET_IF_SOCKET
2968
#endif
2969

    
2970
extern struct mg_iface_vtable mg_socket_iface_vtable;
2971

    
2972
#ifdef __cplusplus
2973
}
2974
#endif /* __cplusplus */
2975

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

    
2985
#ifndef CS_MONGOOSE_SRC_NET_IF_TUN_H_
2986
#define CS_MONGOOSE_SRC_NET_IF_TUN_H_
2987

    
2988
#if MG_ENABLE_TUN
2989

    
2990
/* Amalgamated: #include "mongoose/src/net_if.h" */
2991

    
2992
struct mg_tun_client;
2993

    
2994
#ifdef __cplusplus
2995
extern "C" {
2996
#endif /* __cplusplus */
2997

    
2998
extern struct mg_iface_vtable mg_tun_iface_vtable;
2999

    
3000
struct mg_connection *mg_tun_if_find_conn(struct mg_tun_client *client,
3001
                                          uint32_t stream_id);
3002

    
3003
#ifdef __cplusplus
3004
}
3005
#endif /* __cplusplus */
3006

    
3007
#endif /* MG_ENABLE_TUN */
3008

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

    
3018
extern struct mg_iface_vtable mg_default_iface_vtable;
3019

    
3020
#if MG_ENABLE_TUN
3021
struct mg_iface_vtable *mg_ifaces[] = {&mg_default_iface_vtable,
3022
                                       &mg_tun_iface_vtable};
3023
#else
3024
struct mg_iface_vtable *mg_ifaces[] = {&mg_default_iface_vtable};
3025
#endif
3026

    
3027
int mg_num_ifaces = (int) (sizeof(mg_ifaces) / sizeof(mg_ifaces[0]));
3028

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

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

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

    
3066
#if MG_ENABLE_NET_IF_SOCKET
3067

    
3068
/* Amalgamated: #include "mongoose/src/net_if_socket.h" */
3069
/* Amalgamated: #include "mongoose/src/internal.h" */
3070
/* Amalgamated: #include "mongoose/src/util.h" */
3071

    
3072
#define MG_TCP_RECV_BUFFER_SIZE 1024
3073
#define MG_UDP_RECV_BUFFER_SIZE 1500
3074

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

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

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

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

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

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

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

    
3154
void mg_socket_if_tcp_send(struct mg_connection *nc, const void *buf,
3155
                           size_t len) {
3156
  mbuf_append(&nc->send_mbuf, buf, len);
3157
}
3158

    
3159
void mg_socket_if_udp_send(struct mg_connection *nc, const void *buf,
3160
                           size_t len) {
3161
  mbuf_append(&nc->send_mbuf, buf, len);
3162
}
3163

    
3164
void mg_socket_if_recved(struct mg_connection *nc, size_t len) {
3165
  (void) nc;
3166
  (void) len;
3167
}
3168

    
3169
int mg_socket_if_create_conn(struct mg_connection *nc) {
3170
  (void) nc;
3171
  return 1;
3172
}
3173

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

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

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

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

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

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

    
3258
  return sock;
3259
}
3260

    
3261
static void mg_write_to_socket(struct mg_connection *nc) {
3262
  struct mbuf *io = &nc->send_mbuf;
3263
  int n = 0;
3264

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

    
3270
  assert(io->len > 0);
3271

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

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

    
3314
  if (n > 0) {
3315
    mbuf_remove(io, n);
3316
    mg_if_sent_cb(nc, n);
3317
  }
3318
}
3319

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

    
3327
static void mg_handle_tcp_read(struct mg_connection *conn) {
3328
  int n = 0;
3329
  char *buf = (char *) MG_MALLOC(MG_TCP_RECV_BUFFER_SIZE);
3330

    
3331
  if (buf == NULL) {
3332
    DBG(("OOM"));
3333
    return;
3334
  }
3335

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

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

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

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

    
3410
  if (res == MG_SSL_OK) {
3411
    nc->flags |= MG_F_SSL_HANDSHAKE_DONE;
3412
    nc->flags &= ~(MG_F_WANT_READ | MG_F_WANT_WRITE);
3413

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

    
3431
#define _MG_F_FD_CAN_READ 1
3432
#define _MG_F_FD_CAN_WRITE 1 << 1
3433
#define _MG_F_FD_ERROR 1 << 2
3434

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

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

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

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

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

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

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

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

    
3544
void mg_socket_if_free(struct mg_iface *iface) {
3545
  (void) iface;
3546
}
3547

    
3548
void mg_socket_if_add_conn(struct mg_connection *nc) {
3549
  (void) nc;
3550
}
3551

    
3552
void mg_socket_if_remove_conn(struct mg_connection *nc) {
3553
  (void) nc;
3554
}
3555

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

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

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

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

    
3597
    if (nc->sock != INVALID_SOCKET) {
3598
      num_fds++;
3599

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

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

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

    
3627
    if (nc->ev_timer_time > 0) {
3628
      if (num_timers == 0 || nc->ev_timer_time < min_timer) {
3629
        min_timer = nc->ev_timer_time;
3630
      }
3631
      num_timers++;
3632
    }
3633
  }
3634

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

    
3647
  tv.tv_sec = timeout_ms / 1000;
3648
  tv.tv_usec = (timeout_ms % 1000) * 1000;
3649

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

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

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

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

    
3694
  return (time_t) now;
3695
}
3696

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

    
3704
  sock = sp[0] = sp[1] = INVALID_SOCKET;
3705

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

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

    
3730
  if (!ret) {
3731
    if (sp[0] != INVALID_SOCKET) closesocket(sp[0]);
3732
    if (sp[1] != INVALID_SOCKET) closesocket(sp[1]);
3733
    if (sock != INVALID_SOCKET) closesocket(sock);
3734
    sock = sp[0] = sp[1] = INVALID_SOCKET;
3735
  }
3736

    
3737
  return ret;
3738
}
3739
#endif /* MG_ENABLE_BROADCAST */
3740

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

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

    
3758
void mg_socket_if_get_conn_addr(struct mg_connection *nc, int remote,
3759
                                union socket_address *sa) {
3760
  mg_sock_get_addr(nc->sock, remote, sa);
3761
}
3762

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

    
3785
struct mg_iface_vtable mg_socket_iface_vtable = MG_SOCKET_IFACE_VTABLE;
3786
#if MG_NET_IF == MG_NET_IF_SOCKET
3787
struct mg_iface_vtable mg_default_iface_vtable = MG_SOCKET_IFACE_VTABLE;
3788
#endif
3789

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

    
3799
#if MG_ENABLE_TUN
3800

    
3801
/* Amalgamated: #include "common/cs_dbg.h" */
3802
/* Amalgamated: #include "common/cs_time.h" */
3803
/* Amalgamated: #include "mongoose/src/internal.h" */
3804
/* Amalgamated: #include "mongoose/src/net_if_tun.h" */
3805
/* Amalgamated: #include "mongoose/src/tun.h" */
3806
/* Amalgamated: #include "mongoose/src/util.h" */
3807

    
3808
#define MG_TCP_RECV_BUFFER_SIZE 1024
3809
#define MG_UDP_RECV_BUFFER_SIZE 1500
3810

    
3811
void mg_tun_if_connect_tcp(struct mg_connection *nc,
3812
                           const union socket_address *sa) {
3813
  (void) nc;
3814
  (void) sa;
3815
}
3816

    
3817
void mg_tun_if_connect_udp(struct mg_connection *nc) {
3818
  (void) nc;
3819
}
3820

    
3821
int mg_tun_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) {
3822
  (void) nc;
3823
  (void) sa;
3824
  return 0;
3825
}
3826

    
3827
int mg_tun_if_listen_udp(struct mg_connection *nc, union socket_address *sa) {
3828
  (void) nc;
3829
  (void) sa;
3830
  return -1;
3831
}
3832

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

    
3843
  mg_tun_send_frame(client->disp, stream_id, MG_TUN_DATA_FRAME, 0, msg);
3844
}
3845

    
3846
void mg_tun_if_udp_send(struct mg_connection *nc, const void *buf, size_t len) {
3847
  (void) nc;
3848
  (void) buf;
3849
  (void) len;
3850
}
3851

    
3852
void mg_tun_if_recved(struct mg_connection *nc, size_t len) {
3853
  (void) nc;
3854
  (void) len;
3855
}
3856

    
3857
int mg_tun_if_create_conn(struct mg_connection *nc) {
3858
  (void) nc;
3859
  return 1;
3860
}
3861

    
3862
void mg_tun_if_destroy_conn(struct mg_connection *nc) {
3863
  struct mg_tun_client *client = (struct mg_tun_client *) nc->iface->data;
3864

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

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

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

    
3883
void mg_tun_if_init(struct mg_iface *iface) {
3884
  (void) iface;
3885
}
3886

    
3887
void mg_tun_if_free(struct mg_iface *iface) {
3888
  (void) iface;
3889
}
3890

    
3891
void mg_tun_if_add_conn(struct mg_connection *nc) {
3892
  nc->sock = INVALID_SOCKET;
3893
}
3894

    
3895
void mg_tun_if_remove_conn(struct mg_connection *nc) {
3896
  (void) nc;
3897
}
3898

    
3899
time_t mg_tun_if_poll(struct mg_iface *iface, int timeout_ms) {
3900
  (void) iface;
3901
  (void) timeout_ms;
3902
  return (time_t) cs_time();
3903
}
3904

    
3905
void mg_tun_if_get_conn_addr(struct mg_connection *nc, int remote,
3906
                             union socket_address *sa) {
3907
  (void) nc;
3908
  (void) remote;
3909
  (void) sa;
3910
}
3911

    
3912
struct mg_connection *mg_tun_if_find_conn(struct mg_tun_client *client,
3913
                                          uint32_t stream_id) {
3914
  struct mg_connection *nc = NULL;
3915

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

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

    
3936
  return nc;
3937
}
3938

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

    
3961
struct mg_iface_vtable mg_tun_iface_vtable = MG_TUN_IFACE_VTABLE;
3962

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

    
3972
#if MG_ENABLE_SSL && MG_SSL_IF == MG_SSL_IF_OPENSSL
3973

    
3974
#ifdef __APPLE__
3975
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
3976
#endif
3977

    
3978
#include <openssl/ssl.h>
3979

    
3980
struct mg_ssl_if_ctx {
3981
  SSL *ssl;
3982
  SSL_CTX *ssl_ctx;
3983
};
3984

    
3985
void mg_ssl_if_init() {
3986
  SSL_library_init();
3987
}
3988

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

    
4003
static enum mg_ssl_if_result mg_use_cert(SSL_CTX *ctx, const char *cert,
4004
                                         const char *key, const char **err_msg);
4005
static enum mg_ssl_if_result mg_use_ca_cert(SSL_CTX *ctx, const char *cert);
4006
static enum mg_ssl_if_result mg_set_cipher_list(SSL_CTX *ctx, const char *cl);
4007

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

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

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

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

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

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

    
4062
  nc->flags |= MG_F_SSL;
4063

    
4064
  return MG_SSL_OK;
4065
}
4066

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4264
#if MG_ENABLE_SSL && MG_SSL_IF == MG_SSL_IF_MBEDTLS
4265

    
4266
#include <mbedtls/debug.h>
4267
#include <mbedtls/ecp.h>
4268
#include <mbedtls/platform.h>
4269
#include <mbedtls/ssl.h>
4270
#include <mbedtls/x509_crt.h>
4271

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

    
4292
struct mg_ssl_if_ctx {
4293
  mbedtls_ssl_config *conf;
4294
  mbedtls_ssl_context *ssl;
4295
  mbedtls_x509_crt *cert;
4296
  mbedtls_pk_context *key;
4297
  mbedtls_x509_crt *ca_cert;
4298
  struct mbuf cipher_suites;
4299
};
4300

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

    
4304
void mg_ssl_if_init() {
4305
}
4306

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

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

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

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

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

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

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

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

    
4388
  nc->flags |= MG_F_SSL;
4389

    
4390
  return MG_SSL_OK;
4391
}
4392

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4634
/* Amalgamated: #include "mongoose/src/internal.h" */
4635
/* Amalgamated: #include "mongoose/src/util.h" */
4636

    
4637
#if MG_ENABLE_THREADS
4638

    
4639
static void multithreaded_ev_handler(struct mg_connection *c, int ev, void *p);
4640

    
4641
/*
4642
 * This thread function executes user event handler.
4643
 * It runs an event manager that has only one connection, until that
4644
 * connection is alive.
4645
 */
4646
static void *per_connection_thread_function(void *param) {
4647
  struct mg_connection *c = (struct mg_connection *) param;
4648
  struct mg_mgr m;
4649
  /* mgr_data can be used subsequently, store its value */
4650
  int poll_timeout = (intptr_t) c->mgr_data;
4651

    
4652
  mg_mgr_init(&m, NULL);
4653
  mg_add_conn(&m, c);
4654
  mg_call(c, NULL, MG_EV_ACCEPT, &c->sa);
4655

    
4656
  while (m.active_connections != NULL) {
4657
    mg_mgr_poll(&m, poll_timeout ? poll_timeout : 1000);
4658
  }
4659
  mg_mgr_free(&m);
4660

    
4661
  return param;
4662
}
4663

    
4664
static void link_conns(struct mg_connection *c1, struct mg_connection *c2) {
4665
  c1->priv_2 = c2;
4666
  c2->priv_2 = c1;
4667
}
4668

    
4669
static void unlink_conns(struct mg_connection *c) {
4670
  struct mg_connection *peer = (struct mg_connection *) c->priv_2;
4671
  if (peer != NULL) {
4672
    peer->flags |= MG_F_SEND_AND_CLOSE;
4673
    peer->priv_2 = NULL;
4674
  }
4675
  c->priv_2 = NULL;
4676
}
4677

    
4678
static void forwarder_ev_handler(struct mg_connection *c, int ev, void *p) {
4679
  (void) p;
4680
  if (ev == MG_EV_RECV && c->priv_2) {
4681
    mg_forward(c, (struct mg_connection *) c->priv_2);
4682
  } else if (ev == MG_EV_CLOSE) {
4683
    unlink_conns(c);
4684
  }
4685
}
4686

    
4687
static void spawn_handling_thread(struct mg_connection *nc) {
4688
  struct mg_mgr dummy;
4689
  sock_t sp[2];
4690
  struct mg_connection *c[2];
4691
  int poll_timeout;
4692
  /*
4693
   * Create a socket pair, and wrap each socket into the connection with
4694
   * dummy event manager.
4695
   * c[0] stays in this thread, c[1] goes to another thread.
4696
   */
4697
  mg_mgr_init(&dummy, NULL);
4698
  mg_socketpair(sp, SOCK_STREAM);
4699

    
4700
  c[0] = mg_add_sock(&dummy, sp[0], forwarder_ev_handler);
4701
  c[1] = mg_add_sock(&dummy, sp[1], nc->listener->priv_1.f);
4702

    
4703
  /* link_conns replaces priv_2, storing its value */
4704
  poll_timeout = (intptr_t) nc->priv_2;
4705

    
4706
  /* Interlink client connection with c[0] */
4707
  link_conns(c[0], nc);
4708

    
4709
  /*
4710
   * Switch c[0] manager from the dummy one to the real one. c[1] manager
4711
   * will be set in another thread, allocated on stack of that thread.
4712
   */
4713
  mg_add_conn(nc->mgr, c[0]);
4714

    
4715
  /*
4716
   * Dress c[1] as nc.
4717
   * TODO(lsm): code in accept_conn() looks similar. Refactor.
4718
   */
4719
  c[1]->listener = nc->listener;
4720
  c[1]->proto_handler = nc->proto_handler;
4721
  c[1]->user_data = nc->user_data;
4722
  c[1]->sa = nc->sa;
4723
  c[1]->flags = nc->flags;
4724

    
4725
  /* priv_2 is used, so, put timeout to mgr_data */
4726
  c[1]->mgr_data = (void *) (intptr_t) poll_timeout;
4727

    
4728
  mg_start_thread(per_connection_thread_function, c[1]);
4729
}
4730

    
4731
static void multithreaded_ev_handler(struct mg_connection *c, int ev, void *p) {
4732
  (void) p;
4733
  if (ev == MG_EV_ACCEPT) {
4734
    spawn_handling_thread(c);
4735
    c->handler = forwarder_ev_handler;
4736
  }
4737
}
4738

    
4739
void mg_enable_multithreading_opt(struct mg_connection *nc,
4740
                                  struct mg_multithreading_opts opts) {
4741
  /* Wrap user event handler into our multithreaded_ev_handler */
4742
  nc->priv_1.f = nc->handler;
4743
  /*
4744
   * We put timeout to `priv_2` member of the main
4745
   * (listening) connection, mt is not enabled yet,
4746
   * and this member is not used
4747
   */
4748
  nc->priv_2 = (void *) (intptr_t) opts.poll_timeout;
4749
  nc->handler = multithreaded_ev_handler;
4750
}
4751

    
4752
void mg_enable_multithreading(struct mg_connection *nc) {
4753
  struct mg_multithreading_opts opts;
4754
  memset(&opts, 0, sizeof(opts));
4755
  mg_enable_multithreading_opt(nc, opts);
4756
}
4757

    
4758
#endif
4759
#ifdef MG_MODULE_LINES
4760
#line 1 "mongoose/src/uri.c"
4761
#endif
4762
/*
4763
 * Copyright (c) 2014 Cesanta Software Limited
4764
 * All rights reserved
4765
 */
4766

    
4767
/* Amalgamated: #include "mongoose/src/internal.h" */
4768
/* Amalgamated: #include "mongoose/src/uri.h" */
4769

    
4770
/*
4771
 * scan string until `sep`, keeping track of component boundaries in `res`.
4772
 *
4773
 * `p` will point to the char after the separator or it will be `end`.
4774
 */
4775
static void parse_uri_component(const char **p, const char *end, char sep,
4776
                                struct mg_str *res) {
4777
  res->p = *p;
4778
  for (; *p < end; (*p)++) {
4779
    if (**p == sep) {
4780
      break;
4781
    }
4782
  }
4783
  res->len = (*p) - res->p;
4784
  if (*p < end) (*p)++;
4785
}
4786

    
4787
int mg_parse_uri(struct mg_str uri, struct mg_str *scheme,
4788
                 struct mg_str *user_info, struct mg_str *host,
4789
                 unsigned int *port, struct mg_str *path, struct mg_str *query,
4790
                 struct mg_str *fragment) {
4791
  struct mg_str rscheme = {0, 0}, ruser_info = {0, 0}, rhost = {0, 0},
4792
                rpath = {0, 0}, rquery = {0, 0}, rfragment = {0, 0};
4793
  unsigned int rport = 0;
4794
  enum {
4795
    P_START,
4796
    P_SCHEME_OR_PORT,
4797
    P_USER_INFO,
4798
    P_HOST,
4799
    P_PORT,
4800
    P_REST
4801
  } state = P_START;
4802

    
4803
  const char *p = uri.p, *end = p + uri.len;
4804
  while (p < end) {
4805
    switch (state) {
4806
      case P_START:
4807
        /*