C SIGFOX CALLBACK  0.0.1
A Sigfox Callback program writtent in C
mongoose.h
1 /*
2  * Copyright (c) 2004-2013 Sergey Lyubka
3  * Copyright (c) 2013-2015 Cesanta Software Limited
4  * All rights reserved
5  *
6  * This software is dual-licensed: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation. For the terms of this
9  * license, see <http://www.gnu.org/licenses/>.
10  *
11  * You are free to use this software under the terms of the GNU General
12  * Public License, but WITHOUT ANY WARRANTY; without even the implied
13  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  *
16  * Alternatively, you can license this software under a commercial
17  * license, as set out in <https://www.cesanta.com/license>.
18  */
19 
20 #ifndef CS_MONGOOSE_SRC_COMMON_H_
21 #define CS_MONGOOSE_SRC_COMMON_H_
22 
23 #define MG_VERSION "6.4"
24 
25 /* Local tweaks, applied before any of Mongoose's own headers. */
26 #ifdef MG_LOCALS
27 #include <mg_locals.h>
28 #endif
29 
30 #if defined(MG_ENABLE_DEBUG) && !defined(CS_ENABLE_DEBUG)
31 #define CS_ENABLE_DEBUG
32 #endif
33 #if defined(MG_DISABLE_STDIO) && !defined(CS_DISABLE_STDIO)
34 #define CS_DISABLE_STDIO
35 #elif defined(CS_DISABLE_STDIO) && !defined(MG_DISABLE_STDIO)
36 #define MG_DISABLE_STDIO
37 #endif
38 
39 /* All of the below features depend on filesystem access, disable them. */
40 #ifdef MG_DISABLE_FILESYSTEM
41 #ifndef MG_DISABLE_DAV
42 #define MG_DISABLE_DAV
43 #endif
44 #ifndef MG_DISABLE_CGI
45 #define MG_DISABLE_CGI
46 #endif
47 #ifndef MG_DISABLE_DIRECTORY_LISTING
48 #define MG_DISABLE_DIRECTORY_LISTING
49 #endif
50 #ifndef MG_DISABLE_DAV
51 #define MG_DISABLE_DAV
52 #endif
53 #endif /* MG_DISABLE_FILESYSTEM */
54 
55 #ifdef MG_NO_BSD_SOCKETS
56 #ifndef MG_DISABLE_SYNC_RESOLVER
57 #define MG_DISABLE_SYNC_RESOLVER
58 #endif
59 #ifndef MG_DISABLE_SOCKETPAIR
60 #define MG_DISABLE_SOCKETPAIR
61 #endif
62 #endif /* MG_NO_BSD_SOCKETS */
63 
64 
65 #endif /* CS_MONGOOSE_SRC_COMMON_H_ */
66 #ifndef CS_COMMON_PLATFORM_H_
67 #define CS_COMMON_PLATFORM_H_
68 
69 /*
70  * For the "custom" platform, includes and dependencies can be
71  * provided through mg_locals.h.
72  */
73 #define CS_P_CUSTOM 0
74 #define CS_P_UNIX 1
75 #define CS_P_WINDOWS 2
76 #define CS_P_ESP_LWIP 3
77 #define CS_P_CC3200 4
78 #define CS_P_MSP432 5
79 
80 /* If not specified explicitly, we guess platform by defines. */
81 #ifndef CS_PLATFORM
82 
83 #if defined(TARGET_IS_MSP432P4XX) || defined(__MSP432P401R__)
84 
85 #define CS_PLATFORM CS_P_MSP432
86 #elif defined(cc3200)
87 #define CS_PLATFORM CS_P_CC3200
88 #elif defined(__unix__) || defined(__APPLE__)
89 #define CS_PLATFORM CS_P_UNIX
90 #elif defined(_WIN32)
91 #define CS_PLATFORM CS_P_WINDOWS
92 #endif
93 
94 #ifndef CS_PLATFORM
95 #error "CS_PLATFORM is not specified and we couldn't guess it."
96 #endif
97 
98 #endif /* !defined(CS_PLATFORM) */
99 
100 
101 /* Common stuff */
102 
103 #ifdef __GNUC__
104 #define NORETURN __attribute__((noreturn))
105 #define UNUSED __attribute__((unused))
106 #define NOINLINE __attribute__((noinline))
107 #define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
108 #else
109 #define NORETURN
110 #define UNUSED
111 #define NOINLINE
112 #define WARN_UNUSED_RESULT
113 #endif /* __GNUC__ */
114 
115 #ifndef ARRAY_SIZE
116 #define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
117 #endif
118 
119 #endif /* CS_COMMON_PLATFORM_H_ */
120 #ifndef CS_COMMON_PLATFORMS_PLATFORM_WINDOWS_H_
121 #define CS_COMMON_PLATFORMS_PLATFORM_WINDOWS_H_
122 #if CS_PLATFORM == CS_P_WINDOWS
123 
124 /*
125  * MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
126  * MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
127  * MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
128  * MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
129  * MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008)
130  * MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005)
131  * MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio 2003)
132  * MSVC++ 7.0 _MSC_VER == 1300
133  * MSVC++ 6.0 _MSC_VER == 1200
134  * MSVC++ 5.0 _MSC_VER == 1100
135  */
136 #ifdef _MSC_VER
137 #pragma warning(disable : 4127) /* FD_SET() emits warning, disable it */
138 #pragma warning(disable : 4204) /* missing c99 support */
139 #endif
140 
141 #include <assert.h>
142 #include <direct.h>
143 #include <errno.h>
144 #include <fcntl.h>
145 #include <io.h>
146 #include <limits.h>
147 #include <signal.h>
148 #include <stddef.h>
149 #include <stdio.h>
150 #include <stdlib.h>
151 #include <sys/stat.h>
152 #include <time.h>
153 
154 #define random() rand()
155 #ifdef _MSC_VER
156 #pragma comment(lib, "ws2_32.lib") /* Linking with winsock library */
157 #endif
158 
159 #include <winsock2.h>
160 #include <ws2tcpip.h>
161 #include <windows.h>
162 #include <process.h>
163 
164 #ifndef EINPROGRESS
165 #define EINPROGRESS WSAEINPROGRESS
166 #endif
167 #ifndef EWOULDBLOCK
168 #define EWOULDBLOCK WSAEWOULDBLOCK
169 #endif
170 #ifndef __func__
171 #define STRX(x) #x
172 #define STR(x) STRX(x)
173 #define __func__ __FILE__ ":" STR(__LINE__)
174 #endif
175 #define snprintf _snprintf
176 #define fileno _fileno
177 #define vsnprintf _vsnprintf
178 #define sleep(x) Sleep((x) *1000)
179 #define to64(x) _atoi64(x)
180 #define popen(x, y) _popen((x), (y))
181 #define pclose(x) _pclose(x)
182 #define rmdir _rmdir
183 #if defined(_MSC_VER) && _MSC_VER >= 1400
184 #define fseeko(x, y, z) _fseeki64((x), (y), (z))
185 #else
186 #define fseeko(x, y, z) fseek((x), (y), (z))
187 #endif
188 #define random() rand()
189 typedef int socklen_t;
190 typedef signed char int8_t;
191 typedef unsigned char uint8_t;
192 typedef int int32_t;
193 typedef unsigned int uint32_t;
194 typedef short int16_t;
195 typedef unsigned short uint16_t;
196 typedef __int64 int64_t;
197 typedef unsigned __int64 uint64_t;
198 typedef SOCKET sock_t;
199 typedef uint32_t in_addr_t;
200 #ifndef UINT16_MAX
201 #define UINT16_MAX 65535
202 #endif
203 #ifndef UINT32_MAX
204 #define UINT32_MAX 4294967295
205 #endif
206 #ifndef pid_t
207 #define pid_t HANDLE
208 #endif
209 #define INT64_FMT "I64d"
210 #define INT64_X_FMT "I64x"
211 #define SIZE_T_FMT "Iu"
212 #ifdef __MINGW32__
213 typedef struct stat cs_stat_t;
214 #else
215 typedef struct _stati64 cs_stat_t;
216 #endif
217 #ifndef S_ISDIR
218 #define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR)
219 #endif
220 #ifndef S_ISREG
221 #define S_ISREG(x) (((x) &_S_IFMT) == _S_IFREG)
222 #endif
223 #define DIRSEP '\\'
224 
225 /* POSIX opendir/closedir/readdir API for Windows. */
226 struct dirent {
227  char d_name[MAX_PATH];
228 };
229 
230 typedef struct DIR {
231  HANDLE handle;
232  WIN32_FIND_DATAW info;
233  struct dirent result;
234 } DIR;
235 
236 DIR *opendir(const char *name);
237 int closedir(DIR *dir);
238 struct dirent *readdir(DIR *dir);
239 
240 #ifndef va_copy
241 #ifdef __va_copy
242 #define va_copy __va_copy
243 #else
244 #define va_copy(x, y) (x) = (y)
245 #endif
246 #endif
247 
248 #ifndef MG_MAX_HTTP_REQUEST_SIZE
249 #define MG_MAX_HTTP_REQUEST_SIZE 8192
250 #endif
251 
252 #ifndef MG_MAX_HTTP_SEND_MBUF
253 #define MG_MAX_HTTP_SEND_MBUF 4096
254 #endif
255 
256 #ifndef MG_MAX_HTTP_HEADERS
257 #define MG_MAX_HTTP_HEADERS 40
258 #endif
259 
260 #endif /* CS_PLATFORM == CS_P_WINDOWS */
261 #endif /* CS_COMMON_PLATFORMS_PLATFORM_WINDOWS_H_ */
262 #ifndef CS_COMMON_PLATFORMS_PLATFORM_UNIX_H_
263 #define CS_COMMON_PLATFORMS_PLATFORM_UNIX_H_
264 #if CS_PLATFORM == CS_P_UNIX
265 
266 #ifndef _XOPEN_SOURCE
267 #define _XOPEN_SOURCE 600
268 #endif
269 
270 /* <inttypes.h> wants this for C++ */
271 #ifndef __STDC_FORMAT_MACROS
272 #define __STDC_FORMAT_MACROS
273 #endif
274 
275 /* C++ wants that for INT64_MAX */
276 #ifndef __STDC_LIMIT_MACROS
277 #define __STDC_LIMIT_MACROS
278 #endif
279 
280 /* Enable fseeko() and ftello() functions */
281 #ifndef _LARGEFILE_SOURCE
282 #define _LARGEFILE_SOURCE
283 #endif
284 
285 /* Enable 64-bit file offsets */
286 #ifndef _FILE_OFFSET_BITS
287 #define _FILE_OFFSET_BITS 64
288 #endif
289 
290 #include <arpa/inet.h>
291 #include <assert.h>
292 #include <ctype.h>
293 #include <dirent.h>
294 #include <errno.h>
295 #include <fcntl.h>
296 #include <inttypes.h>
297 #include <limits.h>
298 #include <math.h>
299 #include <netdb.h>
300 #include <netinet/in.h>
301 #include <pthread.h>
302 #include <signal.h>
303 #include <stdarg.h>
304 #include <stdio.h>
305 #include <stdlib.h>
306 #include <string.h>
307 #include <sys/socket.h>
308 #include <sys/select.h>
309 #include <sys/stat.h>
310 #include <sys/time.h>
311 #include <sys/types.h>
312 #include <unistd.h>
313 
314 /*
315  * osx correctly avoids defining strtoll when compiling in strict ansi mode.
316  * We require strtoll, and if your embedded pre-c99 compiler lacks one, please
317  * implement a shim.
318  */
319 #if !(defined(__DARWIN_C_LEVEL) && __DARWIN_C_LEVEL >= 200809L)
320 long long strtoll(const char *, char **, int);
321 #endif
322 
323 typedef int sock_t;
324 #define INVALID_SOCKET (-1)
325 #define SIZE_T_FMT "zu"
326 typedef struct stat cs_stat_t;
327 #define DIRSEP '/'
328 #define to64(x) strtoll(x, NULL, 10)
329 #define INT64_FMT PRId64
330 #define INT64_X_FMT PRIx64
331 #define __cdecl
332 
333 #ifndef va_copy
334 #ifdef __va_copy
335 #define va_copy __va_copy
336 #else
337 #define va_copy(x, y) (x) = (y)
338 #endif
339 #endif
340 
341 #define closesocket(x) close(x)
342 
343 #ifndef MG_MAX_HTTP_REQUEST_SIZE
344 #define MG_MAX_HTTP_REQUEST_SIZE 8192
345 #endif
346 
347 #ifndef MG_MAX_HTTP_SEND_MBUF
348 #define MG_MAX_HTTP_SEND_MBUF 4096
349 #endif
350 
351 #ifndef MG_MAX_HTTP_HEADERS
352 #define MG_MAX_HTTP_HEADERS 40
353 #endif
354 
355 #endif /* CS_PLATFORM == CS_P_UNIX */
356 #endif /* CS_COMMON_PLATFORMS_PLATFORM_UNIX_H_ */
357 #ifndef CS_COMMON_PLATFORMS_PLATFORM_ESP_LWIP_H_
358 #define CS_COMMON_PLATFORMS_PLATFORM_ESP_LWIP_H_
359 #if CS_PLATFORM == CS_P_ESP_LWIP
360 
361 #include <assert.h>
362 #include <ctype.h>
363 #include <fcntl.h>
364 #include <inttypes.h>
365 #include <string.h>
366 #include <sys/stat.h>
367 #include <sys/time.h>
368 
369 #include <lwip/err.h>
370 #include <lwip/ip_addr.h>
371 #include <lwip/inet.h>
372 #include <lwip/netdb.h>
373 #include <lwip/dns.h>
374 
375 #ifndef LWIP_PROVIDE_ERRNO
376 #include <errno.h>
377 #endif
378 
379 #define LWIP_TIMEVAL_PRIVATE 0
380 
381 #if LWIP_SOCKET
382 #include <lwip/sockets.h>
383 #define SOMAXCONN 10
384 #else
385 /* We really need the definitions from sockets.h. */
386 #undef LWIP_SOCKET
387 #define LWIP_SOCKET 1
388 #include <lwip/sockets.h>
389 #undef LWIP_SOCKET
390 #define LWIP_SOCKET 0
391 #endif
392 
393 typedef int sock_t;
394 #define INVALID_SOCKET (-1)
395 #define SIZE_T_FMT "u"
396 typedef struct stat cs_stat_t;
397 #define DIRSEP '/'
398 #define to64(x) strtoll(x, NULL, 10)
399 #define INT64_FMT PRId64
400 #define INT64_X_FMT PRIx64
401 #define __cdecl
402 
403 unsigned long os_random(void);
404 #define random os_random
405 
406 #endif /* CS_PLATFORM == CS_P_ESP_LWIP */
407 #endif /* CS_COMMON_PLATFORMS_PLATFORM_ESP_LWIP_H_ */
408 /*
409  * Copyright (c) 2014-2016 Cesanta Software Limited
410  * All rights reserved
411  */
412 
413 #ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_
414 #define CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_
415 #if CS_PLATFORM == CS_P_CC3200
416 
417 #include <assert.h>
418 #include <ctype.h>
419 #include <errno.h>
420 #include <inttypes.h>
421 #include <stdint.h>
422 #include <string.h>
423 #include <time.h>
424 
425 #ifndef __TI_COMPILER_VERSION__
426 #include <fcntl.h>
427 #include <sys/time.h>
428 #endif
429 
430 #define MG_SOCKET_SIMPLELINK 1
431 #define MG_DISABLE_SOCKETPAIR 1
432 #define MG_DISABLE_SYNC_RESOLVER 1
433 #define MG_DISABLE_POPEN 1
434 #define MG_DISABLE_CGI 1
435 /* Only SPIFFS supports directories, SLFS does not. */
436 #ifndef CC3200_FS_SPIFFS
437 #define MG_DISABLE_DAV 1
438 #define MG_DISABLE_DIRECTORY_LISTING 1
439 #endif
440 
441 
442 typedef int sock_t;
443 #define INVALID_SOCKET (-1)
444 #define SIZE_T_FMT "u"
445 typedef struct stat cs_stat_t;
446 #define DIRSEP '/'
447 #define to64(x) strtoll(x, NULL, 10)
448 #define INT64_FMT PRId64
449 #define INT64_X_FMT PRIx64
450 #define __cdecl
451 
452 #define fileno(x) -1
453 
454 /* Some functions we implement for Mongoose. */
455 
456 #ifdef __TI_COMPILER_VERSION__
457 struct SlTimeval_t;
458 #define timeval SlTimeval_t
459 int gettimeofday(struct timeval *t, void *tz);
460 #endif
461 
462 long int random(void);
463 
464 /* TI's libc does not have stat & friends, add them. */
465 #ifdef __TI_COMPILER_VERSION__
466 
467 #include <file.h>
468 
469 typedef unsigned int mode_t;
470 typedef size_t _off_t;
471 typedef long ssize_t;
472 
473 struct stat {
474  int st_ino;
475  mode_t st_mode;
476  int st_nlink;
477  time_t st_mtime;
478  off_t st_size;
479 };
480 
481 int _stat(const char *pathname, struct stat *st);
482 #define stat(a, b) _stat(a, b)
483 
484 #define __S_IFMT 0170000
485 
486 #define __S_IFDIR 0040000
487 #define __S_IFCHR 0020000
488 #define __S_IFREG 0100000
489 
490 #define __S_ISTYPE(mode, mask) (((mode) &__S_IFMT) == (mask))
491 
492 #define S_IFDIR __S_IFDIR
493 #define S_IFCHR __S_IFCHR
494 #define S_IFREG __S_IFREG
495 #define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR)
496 #define S_ISREG(mode) __S_ISTYPE((mode), __S_IFREG)
497 
498 /* As of 5.2.7, TI compiler does not support va_copy() yet. */
499 #define va_copy(apc, ap) ((apc) = (ap))
500 
501 #endif /* __TI_COMPILER_VERSION__ */
502 
503 #ifdef CC3200_FS_SPIFFS
504 #include <common/spiffs/spiffs.h>
505 
506 typedef struct {
507  spiffs_DIR dh;
508  struct spiffs_dirent de;
509 } DIR;
510 
511 #define d_name name
512 #define dirent spiffs_dirent
513 
514 DIR *opendir(const char *dir_name);
515 int closedir(DIR *dir);
516 struct dirent *readdir(DIR *dir);
517 #endif /* CC3200_FS_SPIFFS */
518 
519 #ifdef CC3200_FS_SLFS
520 #define MG_FS_SLFS
521 #endif
522 
523 #endif /* CS_PLATFORM == CS_P_CC3200 */
524 #endif /* CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_ */
525 /*
526  * Copyright (c) 2014-2016 Cesanta Software Limited
527  * All rights reserved
528  */
529 
530 #ifndef CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_
531 #define CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_
532 #if CS_PLATFORM == CS_P_MSP432
533 
534 #include <assert.h>
535 #include <ctype.h>
536 #include <errno.h>
537 #include <inttypes.h>
538 #include <stdint.h>
539 #include <string.h>
540 #include <time.h>
541 
542 #ifndef __TI_COMPILER_VERSION__
543 #include <fcntl.h>
544 #include <sys/time.h>
545 #endif
546 
547 #define MG_SOCKET_SIMPLELINK 1
548 #define MG_DISABLE_SOCKETPAIR 1
549 #define MG_DISABLE_SYNC_RESOLVER 1
550 #define MG_DISABLE_POPEN 1
551 #define MG_DISABLE_CGI 1
552 #define MG_DISABLE_DAV 1
553 #define MG_DISABLE_DIRECTORY_LISTING 1
554 
555 
556 typedef int sock_t;
557 #define INVALID_SOCKET (-1)
558 #define SIZE_T_FMT "u"
559 typedef struct stat cs_stat_t;
560 #define DIRSEP '/'
561 #define to64(x) strtoll(x, NULL, 10)
562 #define INT64_FMT PRId64
563 #define INT64_X_FMT PRIx64
564 #define __cdecl
565 
566 #define fileno(x) -1
567 
568 /* Some functions we implement for Mongoose. */
569 
570 #ifdef __TI_COMPILER_VERSION__
571 struct SlTimeval_t;
572 #define timeval SlTimeval_t
573 int gettimeofday(struct timeval *t, void *tz);
574 #endif
575 
576 long int random(void);
577 
578 /* TI's libc does not have stat & friends, add them. */
579 #ifdef __TI_COMPILER_VERSION__
580 
581 #include <file.h>
582 
583 typedef unsigned int mode_t;
584 typedef size_t _off_t;
585 typedef long ssize_t;
586 
587 struct stat {
588  int st_ino;
589  mode_t st_mode;
590  int st_nlink;
591  time_t st_mtime;
592  off_t st_size;
593 };
594 
595 int _stat(const char *pathname, struct stat *st);
596 #define stat(a, b) _stat(a, b)
597 
598 #define __S_IFMT 0170000
599 
600 #define __S_IFDIR 0040000
601 #define __S_IFCHR 0020000
602 #define __S_IFREG 0100000
603 
604 #define __S_ISTYPE(mode, mask) (((mode) &__S_IFMT) == (mask))
605 
606 #define S_IFDIR __S_IFDIR
607 #define S_IFCHR __S_IFCHR
608 #define S_IFREG __S_IFREG
609 #define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR)
610 #define S_ISREG(mode) __S_ISTYPE((mode), __S_IFREG)
611 
612 /* As of 5.2.7, TI compiler does not support va_copy() yet. */
613 #define va_copy(apc, ap) ((apc) = (ap))
614 
615 #endif /* __TI_COMPILER_VERSION__ */
616 
617 #endif /* CS_PLATFORM == CS_P_MSP432 */
618 #endif /* CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_ */
619 /*
620  * Copyright (c) 2014-2016 Cesanta Software Limited
621  * All rights reserved
622  */
623 
624 #ifndef CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_
625 #define CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_
626 
627 /* If simplelink.h is already included, all bets are off. */
628 #if defined(MG_SOCKET_SIMPLELINK) && !defined(__SIMPLELINK_H__)
629 
630 #include <stdbool.h>
631 
632 #ifndef __TI_COMPILER_VERSION__
633 #undef __CONCAT
634 #undef FD_CLR
635 #undef FD_ISSET
636 #undef FD_SET
637 #undef FD_SETSIZE
638 #undef FD_ZERO
639 #undef fd_set
640 #endif
641 
642 /* We want to disable SL_INC_STD_BSD_API_NAMING, so we include user.h ourselves
643  * and undef it. */
644 #define PROVISIONING_API_H_
645 #include <simplelink/user.h>
646 #undef PROVISIONING_API_H_
647 #undef SL_INC_STD_BSD_API_NAMING
648 
649 #include <simplelink/include/simplelink.h>
650 
651 /* Now define only the subset of the BSD API that we use.
652  * Notably, close(), read() and write() are not defined. */
653 #define AF_INET SL_AF_INET
654 
655 #define socklen_t SlSocklen_t
656 #define sockaddr SlSockAddr_t
657 #define sockaddr_in SlSockAddrIn_t
658 #define in_addr SlInAddr_t
659 
660 #define SOCK_STREAM SL_SOCK_STREAM
661 #define SOCK_DGRAM SL_SOCK_DGRAM
662 
663 #define FD_SET SL_FD_SET
664 #define FD_CLR SL_FD_CLR
665 #define FD_ISSET SL_FD_ISSET
666 #define FD_ZERO SL_FD_ZERO
667 #define fd_set SlFdSet_t
668 
669 #define htonl sl_Htonl
670 #define ntohl sl_Ntohl
671 #define htons sl_Htons
672 #define ntohs sl_Ntohs
673 
674 #define accept sl_Accept
675 #define closesocket sl_Close
676 #define bind sl_Bind
677 #define connect sl_Connect
678 #define listen sl_Listen
679 #define recv sl_Recv
680 #define recvfrom sl_RecvFrom
681 #define send sl_Send
682 #define sendto sl_SendTo
683 #define socket sl_Socket
684 
685 #define select(nfds, rfds, wfds, efds, tout) \
686  sl_Select((nfds), (rfds), (wfds), (efds), (struct SlTimeval_t *)(tout))
687 
688 #ifndef EACCES
689 #define EACCES SL_EACCES
690 #endif
691 #ifndef EAFNOSUPPORT
692 #define EAFNOSUPPORT SL_EAFNOSUPPORT
693 #endif
694 #ifndef EAGAIN
695 #define EAGAIN SL_EAGAIN
696 #endif
697 #ifndef EBADF
698 #define EBADF SL_EBADF
699 #endif
700 #ifndef EINVAL
701 #define EINVAL SL_EINVAL
702 #endif
703 #ifndef ENOMEM
704 #define ENOMEM SL_ENOMEM
705 #endif
706 #ifndef EWOULDBLOCK
707 #define EWOULDBLOCK SL_EWOULDBLOCK
708 #endif
709 
710 #define SOMAXCONN 8
711 
712 const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
713 char *inet_ntoa(struct in_addr in);
714 int inet_pton(int af, const char *src, void *dst);
715 
716 struct mg_mgr;
717 
718 typedef void (*mg_init_cb)(struct mg_mgr *mgr);
719 bool mg_start_task(int priority, int stack_size, mg_init_cb mg_init);
720 
721 void mg_run_in_task(void (*cb)(struct mg_mgr *mgr, void *arg), void *cb_arg);
722 
723 int sl_fs_init();
724 
725 #endif /* defined(MG_SOCKET_SIMPLELINK) && !defined(__SIMPLELINK_H__) */
726 
727 #endif /* CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_ */
728 /*
729  * Copyright (c) 2014-2016 Cesanta Software Limited
730  * All rights reserved
731  */
732 
733 #ifndef CS_COMMON_CS_DBG_H_
734 #define CS_COMMON_CS_DBG_H_
735 
736 enum cs_log_level {
737  LL_NONE = -1,
738  LL_ERROR = 0,
739  LL_WARN = 1,
740  LL_INFO = 2,
741  LL_DEBUG = 3,
742  LL_VERBOSE_DEBUG = 4,
743 
744  _LL_MIN = -2,
745  _LL_MAX = 5,
746 };
747 
748 void cs_log_set_level(enum cs_log_level level);
749 
750 #ifndef CS_DISABLE_STDIO
751 
752 #include <stdio.h>
753 
754 void cs_log_set_file(FILE *file);
755 
756 extern enum cs_log_level cs_log_level;
757 void cs_log_print_prefix(const char *func);
758 void cs_log_printf(const char *fmt, ...);
759 
760 #define LOG(l, x) \
761  if (cs_log_level >= l) { \
762  cs_log_print_prefix(__func__); \
763  cs_log_printf x; \
764  }
765 
766 #ifndef CS_NDEBUG
767 
768 #define DBG(x) \
769  if (cs_log_level >= LL_VERBOSE_DEBUG) { \
770  cs_log_print_prefix(__func__); \
771  cs_log_printf x; \
772  }
773 
774 #else /* NDEBUG */
775 
776 #define DBG(x)
777 
778 #endif
779 
780 #else /* CS_DISABLE_STDIO */
781 
782 #define LOG(l, x)
783 #define DBG(x)
784 
785 #endif
786 
787 #endif /* CS_COMMON_CS_DBG_H_ */
788 /*
789  * Copyright (c) 2014-2016 Cesanta Software Limited
790  * All rights reserved
791  */
792 
793 #ifndef CS_COMMON_CS_TIME_H_
794 #define CS_COMMON_CS_TIME_H_
795 
796 /* Sub-second granularity time(). */
797 double cs_time();
798 
799 #endif /* CS_COMMON_CS_TIME_H_ */
800 /*
801  * Copyright (c) 2015 Cesanta Software Limited
802  * All rights reserved
803  */
804 
805 /*
806  * === Memory Buffers
807  *
808  * Mbufs are mutable/growing memory buffers, like C++ strings.
809  * Mbuf can append data to the end of a buffer, or insert data into arbitrary
810  * position in the middle of a buffer. The buffer grows automatically when
811  * needed.
812  */
813 
814 #ifndef CS_COMMON_MBUF_H_
815 #define CS_COMMON_MBUF_H_
816 
817 #if defined(__cplusplus)
818 extern "C" {
819 #endif
820 
821 #include <stdlib.h>
822 
823 #ifndef MBUF_SIZE_MULTIPLIER
824 #define MBUF_SIZE_MULTIPLIER 1.5
825 #endif
826 
827 /* Memory buffer descriptor */
828 struct mbuf {
829  char *buf; /* Buffer pointer */
830  size_t len; /* Data length. Data is located between offset 0 and len. */
831  size_t size; /* Buffer size allocated by realloc(1). Must be >= len */
832 };
833 
834 /*
835  * Initialize an Mbuf.
836  * `initial_capacity` specifies the initial capacity of the mbuf.
837  */
838 void mbuf_init(struct mbuf *, size_t initial_capacity);
839 
840 /* Free the space allocated for the mbuffer and resets the mbuf structure. */
841 void mbuf_free(struct mbuf *);
842 
843 /*
844  * Appends data to the Mbuf.
845  *
846  * Return the number of bytes appended, or 0 if out of memory.
847  */
848 size_t mbuf_append(struct mbuf *, const void *data, size_t data_size);
849 
850 /*
851  * Insert data at a specified offset in the Mbuf.
852  *
853  * Existing data will be shifted forwards and the buffer will
854  * be grown if necessary.
855  * Return the number of bytes inserted.
856  */
857 size_t mbuf_insert(struct mbuf *, size_t, const void *, size_t);
858 
859 /* Remove `data_size` bytes from the beginning of the buffer. */
860 void mbuf_remove(struct mbuf *, size_t data_size);
861 
862 /*
863  * Resize an Mbuf.
864  *
865  * If `new_size` is smaller than buffer's `len`, the
866  * resize is not performed.
867  */
868 void mbuf_resize(struct mbuf *, size_t new_size);
869 
870 /* Shrink an Mbuf by resizing its `size` to `len`. */
871 void mbuf_trim(struct mbuf *);
872 
873 #if defined(__cplusplus)
874 }
875 #endif /* __cplusplus */
876 
877 #endif /* CS_COMMON_MBUF_H_ */
878 /*
879  * Copyright (c) 2014 Cesanta Software Limited
880  * All rights reserved
881  */
882 
883 #ifndef CS_COMMON_SHA1_H_
884 #define CS_COMMON_SHA1_H_
885 
886 #ifndef DISABLE_SHA1
887 
888 
889 #ifdef __cplusplus
890 extern "C" {
891 #endif /* __cplusplus */
892 
893 typedef struct {
894  uint32_t state[5];
895  uint32_t count[2];
896  unsigned char buffer[64];
897 } cs_sha1_ctx;
898 
899 void cs_sha1_init(cs_sha1_ctx *);
900 void cs_sha1_update(cs_sha1_ctx *, const unsigned char *data, uint32_t len);
901 void cs_sha1_final(unsigned char digest[20], cs_sha1_ctx *);
902 void cs_hmac_sha1(const unsigned char *key, size_t key_len,
903  const unsigned char *text, size_t text_len,
904  unsigned char out[20]);
905 #ifdef __cplusplus
906 }
907 #endif /* __cplusplus */
908 
909 #endif /* DISABLE_SHA1 */
910 
911 #endif /* CS_COMMON_SHA1_H_ */
912 /*
913  * Copyright (c) 2014 Cesanta Software Limited
914  * All rights reserved
915  */
916 
917 #ifndef CS_COMMON_MD5_H_
918 #define CS_COMMON_MD5_H_
919 
920 
921 #ifdef __cplusplus
922 extern "C" {
923 #endif /* __cplusplus */
924 
925 typedef struct MD5Context {
926  uint32_t buf[4];
927  uint32_t bits[2];
928  unsigned char in[64];
929 } MD5_CTX;
930 
931 void MD5_Init(MD5_CTX *c);
932 void MD5_Update(MD5_CTX *c, const unsigned char *data, size_t len);
933 void MD5_Final(unsigned char *md, MD5_CTX *c);
934 
935 /*
936  * Return stringified MD5 hash for NULL terminated list of strings.
937  * Example:
938  *
939  * char buf[33];
940  * cs_md5(buf, "foo", "bar", NULL);
941  */
942 char *cs_md5(char buf[33], ...);
943 
944 /*
945  * Stringify binary data. Output buffer size must be 2 * size_of_input + 1
946  * because each byte of input takes 2 bytes in string representation
947  * plus 1 byte for the terminating \0 character.
948  */
949 void cs_to_hex(char *to, const unsigned char *p, size_t len);
950 
951 #ifdef __cplusplus
952 }
953 #endif /* __cplusplus */
954 
955 #endif /* CS_COMMON_MD5_H_ */
956 /*
957  * Copyright (c) 2014 Cesanta Software Limited
958  * All rights reserved
959  */
960 
961 #ifndef CS_COMMON_BASE64_H_
962 #define CS_COMMON_BASE64_H_
963 
964 #ifndef DISABLE_BASE64
965 
966 #include <stdio.h>
967 
968 #ifdef __cplusplus
969 extern "C" {
970 #endif
971 
972 typedef void (*cs_base64_putc_t)(char, void *);
973 
975  /* cannot call it putc because it's a macro on some environments */
976  cs_base64_putc_t b64_putc;
977  unsigned char chunk[3];
978  int chunk_size;
979  void *user_data;
980 };
981 
982 void cs_base64_init(struct cs_base64_ctx *ctx, cs_base64_putc_t putc,
983  void *user_data);
984 void cs_base64_update(struct cs_base64_ctx *ctx, const char *str, size_t len);
985 void cs_base64_finish(struct cs_base64_ctx *ctx);
986 
987 void cs_base64_encode(const unsigned char *src, int src_len, char *dst);
988 void cs_fprint_base64(FILE *f, const unsigned char *src, int src_len);
989 int cs_base64_decode(const unsigned char *s, int len, char *dst);
990 
991 #ifdef __cplusplus
992 }
993 #endif
994 
995 #endif /* DISABLE_BASE64 */
996 
997 #endif /* CS_COMMON_BASE64_H_ */
998 /*
999  * Copyright (c) 2015 Cesanta Software Limited
1000  * All rights reserved
1001  */
1002 
1003 #ifndef CS_COMMON_STR_UTIL_H_
1004 #define CS_COMMON_STR_UTIL_H_
1005 
1006 #include <stdarg.h>
1007 #include <stdlib.h>
1008 
1009 #ifdef __cplusplus
1010 extern "C" {
1011 #endif
1012 
1013 size_t c_strnlen(const char *s, size_t maxlen);
1014 int c_snprintf(char *buf, size_t buf_size, const char *format, ...);
1015 int c_vsnprintf(char *buf, size_t buf_size, const char *format, va_list ap);
1016 /*
1017  * Find the first occurrence of find in s, where the search is limited to the
1018  * first slen characters of s.
1019  */
1020 const char *c_strnstr(const char *s, const char *find, size_t slen);
1021 
1022 #ifdef __cplusplus
1023 }
1024 #endif
1025 
1026 #endif /* CS_COMMON_STR_UTIL_H_ */
1027 /*
1028  * Copyright (c) 2004-2013 Sergey Lyubka <valenok@gmail.com>
1029  * Copyright (c) 2013 Cesanta Software Limited
1030  * All rights reserved
1031  *
1032  * This library is dual-licensed: you can redistribute it and/or modify
1033  * it under the terms of the GNU General Public License version 2 as
1034  * published by the Free Software Foundation. For the terms of this
1035  * license, see <http: *www.gnu.org/licenses/>.
1036  *
1037  * You are free to use this library under the terms of the GNU General
1038  * Public License, but WITHOUT ANY WARRANTY; without even the implied
1039  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1040  * See the GNU General Public License for more details.
1041  *
1042  * Alternatively, you can license this library under a commercial
1043  * license, as set out in <http://cesanta.com/products.html>.
1044  */
1045 
1046 #ifndef CS_MONGOOSE_DEPS_FROZEN_FROZEN_H_
1047 #define CS_MONGOOSE_DEPS_FROZEN_FROZEN_H_
1048 
1049 #ifdef __cplusplus
1050 extern "C" {
1051 #endif /* __cplusplus */
1052 
1053 #include <stdarg.h>
1054 
1055 enum json_type {
1056  JSON_TYPE_EOF = 0, /* End of parsed tokens marker */
1057  JSON_TYPE_STRING = 1,
1058  JSON_TYPE_NUMBER = 2,
1059  JSON_TYPE_OBJECT = 3,
1060  JSON_TYPE_TRUE = 4,
1061  JSON_TYPE_FALSE = 5,
1062  JSON_TYPE_NULL = 6,
1063  JSON_TYPE_ARRAY = 7
1064 };
1065 
1066 struct json_token {
1067  const char *ptr; /* Points to the beginning of the token */
1068  int len; /* Token length */
1069  int num_desc; /* For arrays and object, total number of descendants */
1070  enum json_type type; /* Type of the token, possible values above */
1071 };
1072 
1073 /* Error codes */
1074 #define JSON_STRING_INVALID -1
1075 #define JSON_STRING_INCOMPLETE -2
1076 #define JSON_TOKEN_ARRAY_TOO_SMALL -3
1077 
1078 int parse_json(const char *json_string, int json_string_length,
1079  struct json_token *tokens_array, int size_of_tokens_array);
1080 struct json_token *parse_json2(const char *json_string, int string_length);
1081 struct json_token *find_json_token(struct json_token *toks, const char *path);
1082 
1083 int json_emit_long(char *buf, int buf_len, long value);
1084 int json_emit_double(char *buf, int buf_len, double value);
1085 int json_emit_quoted_str(char *buf, int buf_len, const char *str, int len);
1086 int json_emit_unquoted_str(char *buf, int buf_len, const char *str, int len);
1087 int json_emit(char *buf, int buf_len, const char *fmt, ...);
1088 int json_emit_va(char *buf, int buf_len, const char *fmt, va_list);
1089 
1090 #ifdef __cplusplus
1091 }
1092 #endif /* __cplusplus */
1093 
1094 #endif /* CS_MONGOOSE_DEPS_FROZEN_FROZEN_H_ */
1095 /*
1096  * Copyright (c) 2014-2016 Cesanta Software Limited
1097  * All rights reserved
1098  */
1099 
1100 #ifndef CS_COMMON_CS_DIRENT_H_
1101 #define CS_COMMON_CS_DIRENT_H_
1102 
1103 #ifdef CS_ENABLE_SPIFFS
1104 
1105 #include <spiffs.h>
1106 
1107 typedef struct {
1108  spiffs_DIR dh;
1109  struct spiffs_dirent de;
1110 } DIR;
1111 
1112 #define d_name name
1113 #define dirent spiffs_dirent
1114 
1115 int rmdir(const char *path);
1116 int mkdir(const char *path, mode_t mode);
1117 
1118 #endif
1119 
1120 #if defined(_WIN32) || defined(CS_ENABLE_SPIFFS)
1121 DIR *opendir(const char *dir_name);
1122 int closedir(DIR *dir);
1123 struct dirent *readdir(DIR *dir);
1124 #endif
1125 
1126 #endif /* CS_COMMON_CS_DIRENT_H_ */
1127 /*
1128  * Copyright (c) 2014 Cesanta Software Limited
1129  * All rights reserved
1130  * This software is dual-licensed: you can redistribute it and/or modify
1131  * it under the terms of the GNU General Public License version 2 as
1132  * published by the Free Software Foundation. For the terms of this
1133  * license, see <http://www.gnu.org/licenses/>.
1134  *
1135  * You are free to use this software under the terms of the GNU General
1136  * Public License, but WITHOUT ANY WARRANTY; without even the implied
1137  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1138  * See the GNU General Public License for more details.
1139  *
1140  * Alternatively, you can license this software under a commercial
1141  * license, as set out in <https://www.cesanta.com/license>.
1142  */
1143 
1144 /*
1145  * === Core: TCP/UDP/SSL
1146  *
1147  * NOTE: Mongoose manager is single threaded. It does not protect
1148  * its data structures by mutexes, therefore all functions that are dealing
1149  * with particular event manager should be called from the same thread,
1150  * with exception of `mg_broadcast()` function. It is fine to have different
1151  * event managers handled by different threads.
1152  */
1153 
1154 #ifndef CS_MONGOOSE_SRC_NET_H_
1155 #define CS_MONGOOSE_SRC_NET_H_
1156 
1157 #ifdef MG_ENABLE_JAVASCRIPT
1158 #define EXCLUDE_COMMON
1159 #include <v7.h>
1160 #endif
1161 
1162 
1163 #ifdef MG_ENABLE_SSL
1164 #ifdef __APPLE__
1165 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1166 #endif
1167 #include <openssl/ssl.h>
1168 #else
1169 typedef void *SSL;
1170 typedef void *SSL_CTX;
1171 #endif
1172 
1173 #ifndef MG_VPRINTF_BUFFER_SIZE
1174 #define MG_VPRINTF_BUFFER_SIZE 100
1175 #endif
1176 
1177 #ifdef MG_USE_READ_WRITE
1178 #define MG_RECV_FUNC(s, b, l, f) read(s, b, l)
1179 #define MG_SEND_FUNC(s, b, l, f) write(s, b, l)
1180 #else
1181 #define MG_RECV_FUNC(s, b, l, f) recv(s, b, l, f)
1182 #define MG_SEND_FUNC(s, b, l, f) send(s, b, l, f)
1183 #endif
1184 
1185 #ifdef __cplusplus
1186 extern "C" {
1187 #endif /* __cplusplus */
1188 
1190  struct sockaddr sa;
1191  struct sockaddr_in sin;
1192 #ifdef MG_ENABLE_IPV6
1193  struct sockaddr_in6 sin6;
1194 #else
1195  struct sockaddr sin6;
1196 #endif
1197 };
1198 
1199 /* Describes chunk of memory */
1200 struct mg_str {
1201  const char *p; /* Memory chunk pointer */
1202  size_t len; /* Memory chunk length */
1203 };
1204 
1205 struct mg_connection;
1206 
1207 /*
1208  * Callback function (event handler) prototype, must be defined by user.
1209  * Mongoose calls event handler, passing events defined below.
1210  */
1211 typedef void (*mg_event_handler_t)(struct mg_connection *, int ev, void *);
1212 
1213 /* Events. Meaning of event parameter (evp) is given in the comment. */
1214 #define MG_EV_POLL 0 /* Sent to each connection on each mg_mgr_poll() call */
1215 #define MG_EV_ACCEPT 1 /* New connection accepted. union socket_address * */
1216 #define MG_EV_CONNECT 2 /* connect() succeeded or failed. int * */
1217 #define MG_EV_RECV 3 /* Data has benn received. int *num_bytes */
1218 #define MG_EV_SEND 4 /* Data has been written to a socket. int *num_bytes */
1219 #define MG_EV_CLOSE 5 /* Connection is closed. NULL */
1220 #define MG_EV_TIMER 6 /* now >= conn->ev_timer_time. double * */
1221 
1222 /*
1223  * Mongoose event manager.
1224  */
1225 struct mg_mgr {
1226  struct mg_connection *active_connections;
1227  const char *hexdump_file; /* Debug hexdump file path */
1228 #ifndef MG_DISABLE_SOCKETPAIR
1229  sock_t ctl[2]; /* Socketpair for mg_wakeup() */
1230 #endif
1231  void *user_data; /* User data */
1232  void *mgr_data; /* Implementation-specific event manager's data. */
1233 #ifdef MG_ENABLE_JAVASCRIPT
1234  struct v7 *v7;
1235 #endif
1236 };
1237 
1238 /*
1239  * Mongoose connection.
1240  */
1242  struct mg_connection *next, *prev; /* mg_mgr::active_connections linkage */
1243  struct mg_connection *listener; /* Set only for accept()-ed connections */
1244  struct mg_mgr *mgr; /* Pointer to containing manager */
1245 
1246  sock_t sock; /* Socket to the remote peer */
1247  int err;
1248  union socket_address sa; /* Remote peer address */
1249  size_t recv_mbuf_limit; /* Max size of recv buffer */
1250  struct mbuf recv_mbuf; /* Received data */
1251  struct mbuf send_mbuf; /* Data scheduled for sending */
1252  SSL *ssl;
1253  SSL_CTX *ssl_ctx;
1254  time_t last_io_time; /* Timestamp of the last socket IO */
1255  double ev_timer_time; /* Timestamp of the future MG_EV_TIMER */
1256  mg_event_handler_t proto_handler; /* Protocol-specific event handler */
1257  void *proto_data; /* Protocol-specific data */
1258  void (*proto_data_destructor)(void *proto_data);
1259  mg_event_handler_t handler; /* Event handler function */
1260  void *user_data; /* User-specific data */
1261  union {
1262  void *v;
1263  /*
1264  * the C standard is fussy about fitting function pointers into
1265  * void pointers, since some archs might have fat pointers for functions.
1266  */
1267  mg_event_handler_t f;
1268  } priv_1; /* Used by mg_enable_multithreading() */
1269  void *priv_2; /* Used by mg_enable_multithreading() */
1270  void *mgr_data; /* Implementation-specific event manager's data. */
1271  unsigned long flags;
1272 /* Flags set by Mongoose */
1273 #define MG_F_LISTENING (1 << 0) /* This connection is listening */
1274 #define MG_F_UDP (1 << 1) /* This connection is UDP */
1275 #define MG_F_RESOLVING (1 << 2) /* Waiting for async resolver */
1276 #define MG_F_CONNECTING (1 << 3) /* connect() call in progress */
1277 #define MG_F_SSL_HANDSHAKE_DONE (1 << 4) /* SSL specific */
1278 #define MG_F_WANT_READ (1 << 5) /* SSL specific */
1279 #define MG_F_WANT_WRITE (1 << 6) /* SSL specific */
1280 #define MG_F_IS_WEBSOCKET (1 << 7) /* Websocket specific */
1281 
1282 /* Flags that are settable by user */
1283 #define MG_F_SEND_AND_CLOSE (1 << 10) /* Push remaining data and close */
1284 #define MG_F_CLOSE_IMMEDIATELY (1 << 11) /* Disconnect */
1285 #define MG_F_WEBSOCKET_NO_DEFRAG (1 << 12) /* Websocket specific */
1286 #define MG_F_DELETE_CHUNK (1 << 13) /* HTTP specific */
1287 
1288 #define MG_F_USER_1 (1 << 20) /* Flags left for application */
1289 #define MG_F_USER_2 (1 << 21)
1290 #define MG_F_USER_3 (1 << 22)
1291 #define MG_F_USER_4 (1 << 23)
1292 #define MG_F_USER_5 (1 << 24)
1293 #define MG_F_USER_6 (1 << 25)
1294 };
1295 
1296 /*
1297  * Initialize Mongoose manager. Side effect: ignores SIGPIPE signal.
1298  * `mgr->user_data` field will be initialized with `user_data` parameter.
1299  * That is an arbitrary pointer, where user code can associate some data
1300  * with the particular Mongoose manager. For example, a C++ wrapper class
1301  * could be written, in which case `user_data` can hold a pointer to the
1302  * class instance.
1303  */
1304 void mg_mgr_init(struct mg_mgr *mgr, void *user_data);
1305 
1306 /*
1307  * De-initializes Mongoose manager.
1308  *
1309  * Close and deallocate all active connections.
1310  */
1311 void mg_mgr_free(struct mg_mgr *);
1312 
1313 /*
1314  * This function performs the actual IO, and must be called in a loop
1315  * (an event loop). Returns the current timestamp.
1316  * `milli` is the maximum number of milliseconds to sleep.
1317  * `mg_mgr_poll()` checks all connection for IO readiness. If at least one
1318  * of the connections is IO-ready, `mg_mgr_poll()` triggers respective
1319  * event handlers and returns.
1320  */
1321 time_t mg_mgr_poll(struct mg_mgr *, int milli);
1322 
1323 #ifndef MG_DISABLE_SOCKETPAIR
1324 /*
1325  * Pass a message of a given length to all connections.
1326  *
1327  * Must be called from a thread that does NOT call `mg_mgr_poll()`.
1328  * Note that `mg_broadcast()` is the only function
1329  * that can be, and must be, called from a different (non-IO) thread.
1330  *
1331  * `func` callback function will be called by the IO thread for each
1332  * connection. When called, event would be `MG_EV_POLL`, and message will
1333  * be passed as `ev_data` pointer. Maximum message size is capped
1334  * by `MG_CTL_MSG_MESSAGE_SIZE` which is set to 8192 bytes.
1335  */
1336 void mg_broadcast(struct mg_mgr *, mg_event_handler_t func, void *, size_t);
1337 #endif
1338 
1339 /*
1340  * Iterate over all active connections.
1341  *
1342  * Returns next connection from the list
1343  * of active connections, or `NULL` if there is no more connections. Below
1344  * is the iteration idiom:
1345  *
1346  * ```c
1347  * for (c = mg_next(srv, NULL); c != NULL; c = mg_next(srv, c)) {
1348  * // Do something with connection `c`
1349  * }
1350  * ```
1351  */
1352 struct mg_connection *mg_next(struct mg_mgr *, struct mg_connection *);
1353 
1354 /*
1355  * Optional parameters to `mg_add_sock_opt()`.
1356  *
1357  * `flags` is an initial `struct mg_connection::flags` bitmask to set,
1358  * see `MG_F_*` flags definitions.
1359  */
1361  void *user_data; /* Initial value for connection's user_data */
1362  unsigned int flags; /* Initial connection flags */
1363  const char **error_string; /* Placeholder for the error string */
1364 };
1365 
1366 /*
1367  * Create a connection, associate it with the given socket and event handler,
1368  * and add it to the manager.
1369  *
1370  * For more options see the `mg_add_sock_opt` variant.
1371  */
1372 struct mg_connection *mg_add_sock(struct mg_mgr *, sock_t, mg_event_handler_t);
1373 
1374 /*
1375  * Create a connection, associate it with the given socket and event handler,
1376  * and add to the manager.
1377  *
1378  * See the `mg_add_sock_opts` structure for a description of the options.
1379  */
1380 struct mg_connection *mg_add_sock_opt(struct mg_mgr *, sock_t,
1381  mg_event_handler_t,
1382  struct mg_add_sock_opts);
1383 
1384 /*
1385  * Optional parameters to `mg_bind_opt()`.
1386  *
1387  * `flags` is an initial `struct mg_connection::flags` bitmask to set,
1388  * see `MG_F_*` flags definitions.
1389  */
1391  void *user_data; /* Initial value for connection's user_data */
1392  unsigned int flags; /* Extra connection flags */
1393  const char **error_string; /* Placeholder for the error string */
1394 #ifdef MG_ENABLE_SSL
1395  /* SSL settings. */
1396  const char *ssl_cert; /* Server certificate to present to clients */
1397  const char *ssl_ca_cert; /* Verify client certificates with this CA bundle */
1398 #endif
1399 };
1400 
1401 /*
1402  * Create listening connection.
1403  *
1404  * See `mg_bind_opt` for full documentation.
1405  */
1406 struct mg_connection *mg_bind(struct mg_mgr *, const char *,
1407  mg_event_handler_t);
1408 /*
1409  * Create listening connection.
1410  *
1411  * `address` parameter tells which address to bind to. It's format is the same
1412  * as for the `mg_connect()` call, where `HOST` part is optional. `address`
1413  * can be just a port number, e.g. `:8000`. To bind to a specific interface,
1414  * an IP address can be specified, e.g. `1.2.3.4:8000`. By default, a TCP
1415  * connection is created. To create UDP connection, prepend `udp://` prefix,
1416  * e.g. `udp://:8000`. To summarize, `address` paramer has following format:
1417  * `[PROTO://][IP_ADDRESS]:PORT`, where `PROTO` could be `tcp` or `udp`.
1418  *
1419  * See the `mg_bind_opts` structure for a description of the optional
1420  * parameters.
1421  *
1422  * Return a new listening connection, or `NULL` on error.
1423  * NOTE: Connection remains owned by the manager, do not free().
1424  */
1425 struct mg_connection *mg_bind_opt(struct mg_mgr *mgr, const char *address,
1426  mg_event_handler_t handler,
1427  struct mg_bind_opts opts);
1428 
1429 /* Optional parameters to `mg_connect_opt()` */
1431  void *user_data; /* Initial value for connection's user_data */
1432  unsigned int flags; /* Extra connection flags */
1433  const char **error_string; /* Placeholder for the error string */
1434 #ifdef MG_ENABLE_SSL
1435  /* SSL settings. */
1436  const char *ssl_cert; /* Client certificate to present to the server */
1437  const char *ssl_ca_cert; /* Verify server certificate using this CA bundle */
1438 
1439  /*
1440  * Server name verification. If ssl_ca_cert is set and the certificate has
1441  * passed verification, its subject will be verified against this string.
1442  * By default (if ssl_server_name is NULL) hostname part of the address will
1443  * be used. Wildcard matching is supported. A special value of "*" disables
1444  * name verification.
1445  */
1446  const char *ssl_server_name;
1447 #endif
1448 };
1449 
1450 /*
1451  * Connect to a remote host.
1452  *
1453  * See `mg_connect_opt()` for full documentation.
1454  */
1455 struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *address,
1456  mg_event_handler_t handler);
1457 
1458 /*
1459  * Connect to a remote host.
1460  *
1461  * `address` format is `[PROTO://]HOST:PORT`. `PROTO` could be `tcp` or `udp`.
1462  * `HOST` could be an IP address,
1463  * IPv6 address (if Mongoose is compiled with `-DMG_ENABLE_IPV6`), or a host
1464  * name. If `HOST` is a name, Mongoose will resolve it asynchronously. Examples
1465  * of valid addresses: `google.com:80`, `udp://1.2.3.4:53`, `10.0.0.1:443`,
1466  * `[::1]:80`
1467  *
1468  * See the `mg_connect_opts` structure for a description of the optional
1469  * parameters.
1470  *
1471  * Returns a new outbound connection, or `NULL` on error.
1472  *
1473  * NOTE: Connection remains owned by the manager, do not free().
1474  *
1475  * NOTE: To enable IPv6 addresses, `-DMG_ENABLE_IPV6` should be specified
1476  * in the compilation flags.
1477  *
1478  * NOTE: New connection will receive `MG_EV_CONNECT` as it's first event
1479  * which will report connect success status.
1480  * If asynchronous resolution fail, or `connect()` syscall fail for whatever
1481  * reason (e.g. with `ECONNREFUSED` or `ENETUNREACH`), then `MG_EV_CONNECT`
1482  * event report failure. Code example below:
1483  *
1484  * ```c
1485  * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
1486  * int connect_status;
1487  *
1488  * switch (ev) {
1489  * case MG_EV_CONNECT:
1490  * connect_status = * (int *) ev_data;
1491  * if (connect_status == 0) {
1492  * // Success
1493  * } else {
1494  * // Error
1495  * printf("connect() error: %s\n", strerror(connect_status));
1496  * }
1497  * break;
1498  * ...
1499  * }
1500  * }
1501  *
1502  * ...
1503  * mg_connect(mgr, "my_site.com:80", ev_handler);
1504  * ```
1505  */
1506 struct mg_connection *mg_connect_opt(struct mg_mgr *mgr, const char *address,
1507  mg_event_handler_t handler,
1508  struct mg_connect_opts opts);
1509 
1510 /*
1511  * Enable SSL for a given connection.
1512  * `cert` is a server certificate file name for a listening connection,
1513  * or a client certificate file name for an outgoing connection.
1514  * Certificate files must be in PEM format. Server certificate file
1515  * must contain a certificate, concatenated with a private key, optionally
1516  * concatenated with parameters.
1517  * `ca_cert` is a CA certificate, or NULL if peer verification is not
1518  * required.
1519  * Return: NULL on success, or error message on error.
1520  */
1521 const char *mg_set_ssl(struct mg_connection *nc, const char *cert,
1522  const char *ca_cert);
1523 
1524 /*
1525  * Send data to the connection.
1526  *
1527  * Note that sending functions do not actually push data to the socket.
1528  * They just append data to the output buffer. MG_EV_SEND will be delivered when
1529  * the data has actually been pushed out.
1530  */
1531 void mg_send(struct mg_connection *, const void *buf, int len);
1532 
1533 /* Enables format string warnings for mg_printf */
1534 #if defined(__GNUC__)
1535 __attribute__((format(printf, 2, 3)))
1536 #endif
1537 /* don't separate from mg_printf declaration */
1538 
1539 /*
1540  * Send `printf`-style formatted data to the connection.
1541  *
1542  * See `mg_send` for more details on send semantics.
1543  */
1544 int mg_printf(struct mg_connection *, const char *fmt, ...);
1545 
1546 /* Same as `mg_printf()`, but takes `va_list ap` as an argument. */
1547 int mg_vprintf(struct mg_connection *, const char *fmt, va_list ap);
1548 
1549 /*
1550  * Create a socket pair.
1551  * `sock_type` can be either `SOCK_STREAM` or `SOCK_DGRAM`.
1552  * Return 0 on failure, 1 on success.
1553  */
1554 int mg_socketpair(sock_t[2], int sock_type);
1555 
1556 /*
1557  * Convert domain name into IP address.
1558  *
1559  * This is a utility function. If compilation flags have
1560  * `-DMG_ENABLE_GETADDRINFO`, then `getaddrinfo()` call is used for name
1561  * resolution. Otherwise, `gethostbyname()` is used.
1562  *
1563  * CAUTION: this function can block.
1564  * Return 1 on success, 0 on failure.
1565  */
1566 #ifndef MG_DISABLE_SYNC_RESOLVER
1567 int mg_resolve(const char *domain_name, char *ip_addr_buf, size_t buf_len);
1568 #endif
1569 
1570 /*
1571  * Verify given IP address against the ACL.
1572  *
1573  * `remote_ip` - an IPv4 address to check, in host byte order
1574  * `acl` - a comma separated list of IP subnets: `x.x.x.x/x` or `x.x.x.x`.
1575  * Each subnet is
1576  * prepended by either a - or a + sign. A plus sign means allow, where a
1577  * minus sign means deny. If a subnet mask is omitted, such as `-1.2.3.4`,
1578  * this means to deny only that single IP address.
1579  * Subnet masks may vary from 0 to 32, inclusive. The default setting
1580  * is to allow all accesses. On each request the full list is traversed,
1581  * and the last match wins. Example:
1582  *
1583  * `-0.0.0.0/0,+192.168/16` - deny all acccesses, only allow 192.168/16 subnet
1584  *
1585  * To learn more about subnet masks, see the
1586  * link:https://en.wikipedia.org/wiki/Subnetwork[Wikipedia page on Subnetwork]
1587  *
1588  * Return -1 if ACL is malformed, 0 if address is disallowed, 1 if allowed.
1589  */
1590 int mg_check_ip_acl(const char *acl, uint32_t remote_ip);
1591 
1592 /*
1593  * Enable multi-threaded handling for the given listening connection `nc`.
1594  * For each accepted connection, Mongoose will create a separate thread
1595  * and run event handler in that thread. Thus, if an event hanler is doing
1596  * a blocking call or some long computation, that will not slow down
1597  * other connections.
1598  */
1599 void mg_enable_multithreading(struct mg_connection *nc);
1600 
1601 #ifdef MG_ENABLE_JAVASCRIPT
1602 /*
1603  * Enable server-side JavaScript scripting.
1604  * Requires `-DMG_ENABLE_JAVASCRIPT` compilation flag, and V7 engine sources.
1605  * v7 instance must not be destroyed during manager's lifetime.
1606  * Return V7 error.
1607  */
1608 enum v7_err mg_enable_javascript(struct mg_mgr *m, struct v7 *v7,
1609  const char *init_js_file_name);
1610 #endif
1611 
1612 /*
1613  * Schedule MG_EV_TIMER event to be delivered at `timestamp` time.
1614  * `timestamp` is a UNIX time (a number of seconds since Epoch). It is
1615  * `double` instead of `time_t` to allow for sub-second precision.
1616  * Return the old timer value.
1617  *
1618  * Example: set connect timeout to 1.5 seconds:
1619  *
1620  * ```
1621  * c = mg_connect(&mgr, "cesanta.com", ev_handler);
1622  * mg_set_timer(c, mg_time() + 1.5);
1623  * ...
1624  *
1625  * void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
1626  * switch (ev) {
1627  * case MG_EV_CONNECT:
1628  * mg_set_timer(c, 0); // Clear connect timer
1629  * break;
1630  * case MG_EV_TIMER:
1631  * log("Connect timeout");
1632  * c->flags |= MG_F_CLOSE_IMMEDIATELY;
1633  * break;
1634  * ```
1635  */
1636 double mg_set_timer(struct mg_connection *c, double timestamp);
1637 
1638 /*
1639  * A sub-second precision version of time().
1640  */
1641 double mg_time();
1642 
1643 #ifdef __cplusplus
1644 }
1645 #endif /* __cplusplus */
1646 
1647 #endif /* CS_MONGOOSE_SRC_NET_H_ */
1648 /*
1649  * Copyright (c) 2014-2016 Cesanta Software Limited
1650  * All rights reserved
1651  */
1652 
1653 #ifndef CS_MONGOOSE_SRC_NET_IF_H_
1654 #define CS_MONGOOSE_SRC_NET_IF_H_
1655 
1656 /*
1657  * Internal async networking core interface.
1658  * Consists of calls made by the core, which should not block,
1659  * and callbacks back into the core ("..._cb").
1660  * Callbacks may (will) cause methods to be invoked from within,
1661  * but methods are not allowed to invoke callbacks inline.
1662  *
1663  * Implementation must ensure that only one callback is invoked at any time.
1664  */
1665 
1666 /* Request that a TCP connection is made to the specified address. */
1667 void mg_if_connect_tcp(struct mg_connection *nc,
1668  const union socket_address *sa);
1669 /* Open a UDP socket. Doesn't actually connect anything. */
1670 void mg_if_connect_udp(struct mg_connection *nc);
1671 /* Callback invoked by connect methods. err = 0 -> ok, != 0 -> error. */
1672 void mg_if_connect_cb(struct mg_connection *nc, int err);
1673 
1674 /* Set up a listening TCP socket on a given address. rv = 0 -> ok. */
1675 int mg_if_listen_tcp(struct mg_connection *nc, union socket_address *sa);
1676 
1677 /*
1678  * Deliver a new TCP connection. Returns NULL in case on error (unable to
1679  * create connection, in which case interface state should be discarded.
1680  * This is phase 1 of the two-phase process - MG_EV_ACCEPT will be delivered
1681  * when mg_if_accept_tcp_cb is invoked.
1682  */
1683 struct mg_connection *mg_if_accept_new_conn(struct mg_connection *lc);
1684 void mg_if_accept_tcp_cb(struct mg_connection *nc, union socket_address *sa,
1685  size_t sa_len);
1686 
1687 /* Request that a "listening" UDP socket be created. */
1688 int mg_if_listen_udp(struct mg_connection *nc, union socket_address *sa);
1689 
1690 /* Send functions for TCP and UDP. Sent data is copied before return. */
1691 void mg_if_tcp_send(struct mg_connection *nc, const void *buf, size_t len);
1692 void mg_if_udp_send(struct mg_connection *nc, const void *buf, size_t len);
1693 /* Callback that reports that data has been put on the wire. */
1694 void mg_if_sent_cb(struct mg_connection *nc, int num_sent);
1695 
1696 /*
1697  * Receive callback.
1698  * buf must be heap-allocated and ownership is transferred to the core.
1699  * Core will acknowledge consumption by calling mg_if_recved.
1700  */
1701 void mg_if_recv_tcp_cb(struct mg_connection *nc, void *buf, int len);
1702 void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len,
1703  union socket_address *sa, size_t sa_len);
1704 void mg_if_recved(struct mg_connection *nc, size_t len);
1705 
1706 /* Deliver a POLL event to the connection. */
1707 void mg_if_poll(struct mg_connection *nc, time_t now);
1708 
1709 /* Deliver a TIMER event to the connection. */
1710 void mg_if_timer(struct mg_connection *c, double now);
1711 
1712 /* Perform interface-related connection initialization. Return 1 on success. */
1713 int mg_if_create_conn(struct mg_connection *nc);
1714 
1715 /* Perform interface-related cleanup on connection before destruction. */
1716 void mg_if_destroy_conn(struct mg_connection *nc);
1717 
1718 void mg_close_conn(struct mg_connection *nc);
1719 
1720 /* Put connection's address into *sa, local (remote = 0) or remote. */
1721 void mg_if_get_conn_addr(struct mg_connection *nc, int remote,
1722  union socket_address *sa);
1723 
1724 /* Associate a socket to a connection. */
1725 void mg_sock_set(struct mg_connection *nc, sock_t sock);
1726 
1727 #endif /* CS_MONGOOSE_SRC_NET_IF_H_ */
1728 /*
1729  * Copyright (c) 2014 Cesanta Software Limited
1730  * All rights reserved
1731  */
1732 
1733 /*
1734  * === URI
1735  */
1736 
1737 #ifndef CS_MONGOOSE_SRC_URI_H_
1738 #define CS_MONGOOSE_SRC_URI_H_
1739 
1740 
1741 #ifdef __cplusplus
1742 extern "C" {
1743 #endif /* __cplusplus */
1744 
1745 /*
1746  * Parses an URI and fills string chunks with locations of the respective
1747  * uri components within the input uri string. NULL pointers will be
1748  * ignored.
1749  *
1750  * General syntax:
1751  *
1752  * [scheme://[user_info@]]host[:port][/path][?query][#fragment]
1753  *
1754  * Example:
1755  *
1756  * foo.com:80
1757  * tcp://foo.com:1234
1758  * http://foo.com:80/bar?baz=1
1759  * https://user:pw@foo.com:443/blah
1760  *
1761  * `path` will include the leading slash. `query` won't include the leading `?`.
1762  * `host` can contain embedded colons if surrounded by square brackets in order
1763  * to support IPv6 literal addresses.
1764  *
1765  *
1766  * Returns 0 on success, -1 on error.
1767  */
1768 int mg_parse_uri(struct mg_str uri, struct mg_str *scheme,
1769  struct mg_str *user_info, struct mg_str *host,
1770  unsigned int *port, struct mg_str *path, struct mg_str *query,
1771  struct mg_str *fragment);
1772 
1773 int mg_normalize_uri_path(const struct mg_str *in, struct mg_str *out);
1774 
1775 #ifdef __cplusplus
1776 }
1777 #endif /* __cplusplus */
1778 #endif /* CS_MONGOOSE_SRC_URI_H_ */
1779 /*
1780  * Copyright (c) 2014 Cesanta Software Limited
1781  * All rights reserved
1782  */
1783 
1784 /*
1785  * === Utilities
1786  */
1787 
1788 #ifndef CS_MONGOOSE_SRC_UTIL_H_
1789 #define CS_MONGOOSE_SRC_UTIL_H_
1790 
1791 #include <stdio.h>
1792 
1793 
1794 #ifdef __cplusplus
1795 extern "C" {
1796 #endif /* __cplusplus */
1797 
1798 #ifndef MAX_PATH_SIZE
1799 #define MAX_PATH_SIZE 500
1800 #endif
1801 
1802 /*
1803  * Fetch substring from input string `s`, `end` into `v`.
1804  * Skips initial delimiter characters. Records first non-delimiter character
1805  * as the beginning of substring `v`. Then scans the rest of the string
1806  * until a delimiter character or end-of-string is found.
1807  * `delimiters` is a 0-terminated string containing delimiter characters.
1808  * Either one of `delimiters` or `end_string` terminates the search.
1809  * Return an `s` pointer, advanced forward where parsing stopped.
1810  */
1811 const char *mg_skip(const char *s, const char *end_string,
1812  const char *delimiters, struct mg_str *v);
1813 
1814 /*
1815  * Cross-platform version of `strncasecmp()`.
1816  */
1817 int mg_ncasecmp(const char *s1, const char *s2, size_t len);
1818 
1819 /*
1820  * Cross-platform version of `strcasecmp()`.
1821  */
1822 int mg_casecmp(const char *s1, const char *s2);
1823 
1824 /*
1825  * Cross-platform version of `strcmp()` where where first string is
1826  * specified by `struct mg_str`.
1827  */
1828 int mg_vcmp(const struct mg_str *str2, const char *str1);
1829 
1830 /*
1831  * Cross-platform version of `strncasecmp()` where first string is
1832  * specified by `struct mg_str`.
1833  */
1834 int mg_vcasecmp(const struct mg_str *str2, const char *str1);
1835 
1836 /*
1837  * Decode base64-encoded string `s`, `len` into the destination `dst`.
1838  * Destination has to have enough space to hold decoded buffer.
1839  * Decoding stops either when all string has been decoded, or invalid
1840  * character appeared.
1841  * Destination is '\0'-terminated.
1842  * Return number of decoded characters. On success, that should be equal to
1843  * `len`. On error (invalid character) the return value is smaller then `len`.
1844  */
1845 int mg_base64_decode(const unsigned char *s, int len, char *dst);
1846 
1847 /*
1848  * Base64-encode chunk of memory `src`, `src_len` into the destination `dst`.
1849  * Destination has to have enough space to hold encoded buffer.
1850  * Destination is '\0'-terminated.
1851  */
1852 void mg_base64_encode(const unsigned char *src, int src_len, char *dst);
1853 
1854 #ifndef MG_DISABLE_FILESYSTEM
1855 /*
1856  * Perform a 64-bit `stat()` call against given file.
1857  *
1858  * `path` should be UTF8 encoded.
1859  *
1860  * Return value is the same as for `stat()` syscall.
1861  */
1862 int mg_stat(const char *path, cs_stat_t *st);
1863 
1864 /*
1865  * Open the given file and return a file stream.
1866  *
1867  * `path` and `mode` should be UTF8 encoded.
1868  *
1869  * Return value is the same as for the `fopen()` call.
1870  */
1871 FILE *mg_fopen(const char *path, const char *mode);
1872 
1873 /*
1874  * Open the given file and return a file stream.
1875  *
1876  * `path` should be UTF8 encoded.
1877  *
1878  * Return value is the same as for the `open()` syscall.
1879  */
1880 int mg_open(const char *path, int flag, int mode);
1881 #endif /* MG_DISABLE_FILESYSTEM */
1882 
1883 #if defined(_WIN32) && !defined(MG_ENABLE_THREADS)
1884 #define MG_ENABLE_THREADS
1885 #endif
1886 
1887 #ifdef MG_ENABLE_THREADS
1888 /*
1889  * Start a new detached thread.
1890  * Arguments and semantic is the same as pthead's `pthread_create()`.
1891  * `thread_func` is a thread function, `thread_func_param` is a parameter
1892  * that is passed to the thread function.
1893  */
1894 void *mg_start_thread(void *(*thread_func)(void *), void *thread_func_param);
1895 #endif
1896 
1897 void mg_set_close_on_exec(sock_t);
1898 
1899 #define MG_SOCK_STRINGIFY_IP 1
1900 #define MG_SOCK_STRINGIFY_PORT 2
1901 #define MG_SOCK_STRINGIFY_REMOTE 4
1902 /*
1903  * Convert connection's local or remote address into string.
1904  *
1905  * The `flags` parameter is a bit mask that controls the behavior,
1906  * see `MG_SOCK_STRINGIFY_*` definitions.
1907  *
1908  * - MG_SOCK_STRINGIFY_IP - print IP address
1909  * - MG_SOCK_STRINGIFY_PORT - print port number
1910  * - MG_SOCK_STRINGIFY_REMOTE - print remote peer's IP/port, not local address
1911  *
1912  * If both port number and IP address are printed, they are separated by `:`.
1913  * If compiled with `-DMG_ENABLE_IPV6`, IPv6 addresses are supported.
1914  */
1915 void mg_conn_addr_to_str(struct mg_connection *nc, char *buf, size_t len,
1916  int flags);
1917 #ifndef MG_DISABLE_SOCKET_IF /* Legacy interface. */
1918 void mg_sock_to_str(sock_t sock, char *buf, size_t len, int flags);
1919 #endif
1920 
1921 /*
1922  * Convert socket's address into string.
1923  *
1924  * `flags` is MG_SOCK_STRINGIFY_IP and/or MG_SOCK_STRINGIFY_PORT.
1925  */
1926 void mg_sock_addr_to_str(const union socket_address *sa, char *buf, size_t len,
1927  int flags);
1928 
1929 /*
1930  * Generates human-readable hexdump of memory chunk.
1931  *
1932  * Takes a memory buffer `buf` of length `len` and creates a hex dump of that
1933  * buffer in `dst`. Generated output is a-la hexdump(1).
1934  * Return length of generated string, excluding terminating `\0`. If returned
1935  * length is bigger than `dst_len`, overflow bytes are discarded.
1936  */
1937 int mg_hexdump(const void *buf, int len, char *dst, int dst_len);
1938 
1939 /*
1940  * Generates human-readable hexdump of the data sent or received by connection.
1941  * `path` is a file name where hexdump should be written. `num_bytes` is
1942  * a number of bytes sent/received. `ev` is one of the `MG_*` events sent to
1943  * an event handler. This function is supposed to be called from the
1944  * event handler.
1945  */
1946 void mg_hexdump_connection(struct mg_connection *nc, const char *path,
1947  const void *buf, int num_bytes, int ev);
1948 /*
1949  * Print message to buffer. If buffer is large enough to hold the message,
1950  * return buffer. If buffer is to small, allocate large enough buffer on heap,
1951  * and return allocated buffer.
1952  * This is a supposed use case:
1953  *
1954  * char buf[5], *p = buf;
1955  * p = mg_avprintf(&p, sizeof(buf), "%s", "hi there");
1956  * use_p_somehow(p);
1957  * if (p != buf) {
1958  * free(p);
1959  * }
1960  *
1961  * The purpose of this is to avoid malloc-ing if generated strings are small.
1962  */
1963 int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap);
1964 
1965 /*
1966  * Return true if target platform is big endian.
1967  */
1968 int mg_is_big_endian(void);
1969 
1970 /*
1971  * A helper function for traversing a comma separated list of values.
1972  * It returns a list pointer shifted to the next value, or NULL if the end
1973  * of the list found.
1974  * Value is stored in val vector. If value has form "x=y", then eq_val
1975  * vector is initialized to point to the "y" part, and val vector length
1976  * is adjusted to point only to "x".
1977  * If list is just a comma separated list of entries, like "aa,bb,cc" then
1978  * `eq_val` will contain zero-length string.
1979  *
1980  * The purpose of this function is to parse comma separated string without
1981  * any copying/memory allocation.
1982  */
1983 const char *mg_next_comma_list_entry(const char *list, struct mg_str *val,
1984  struct mg_str *eq_val);
1985 
1986 /*
1987  * Match 0-terminated string (mg_match_prefix) or string with given length
1988  * mg_match_prefix_n against a glob pattern.
1989  * Match is case-insensitive. Return number of bytes matched, or -1 if no match.
1990  */
1991 int mg_match_prefix(const char *pattern, int pattern_len, const char *str);
1992 int mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str);
1993 
1994 /*
1995  * A helper function for creating mg_str struct from plain C string.
1996  * `NULL` is allowed and becomes `{NULL, 0}`.
1997  */
1998 struct mg_str mg_mk_str(const char *s);
1999 
2000 /* Macro for initializing mg_str. */
2001 #define MG_MK_STR(str_literal) \
2002  { str_literal, sizeof(str_literal) - 1 }
2003 
2004 #ifdef __cplusplus
2005 }
2006 #endif /* __cplusplus */
2007 #endif /* CS_MONGOOSE_SRC_UTIL_H_ */
2008 /*
2009  * Copyright (c) 2014 Cesanta Software Limited
2010  * All rights reserved
2011  */
2012 
2013 /*
2014  * === HTTP + Websocket
2015  */
2016 
2017 #ifndef CS_MONGOOSE_SRC_HTTP_H_
2018 #define CS_MONGOOSE_SRC_HTTP_H_
2019 
2020 
2021 #ifdef __cplusplus
2022 extern "C" {
2023 #endif /* __cplusplus */
2024 
2025 #ifndef MG_MAX_HTTP_HEADERS
2026 #define MG_MAX_HTTP_HEADERS 20
2027 #endif
2028 
2029 #ifndef MG_MAX_HTTP_REQUEST_SIZE
2030 #define MG_MAX_HTTP_REQUEST_SIZE 1024
2031 #endif
2032 
2033 #ifndef MG_MAX_PATH
2034 #ifdef PATH_MAX
2035 #define MG_MAX_PATH PATH_MAX
2036 #else
2037 #define MG_MAX_PATH 256
2038 #endif
2039 #endif
2040 
2041 #ifndef MG_MAX_HTTP_SEND_MBUF
2042 #define MG_MAX_HTTP_SEND_MBUF 1024
2043 #endif
2044 
2045 #ifndef MG_WEBSOCKET_PING_INTERVAL_SECONDS
2046 #define MG_WEBSOCKET_PING_INTERVAL_SECONDS 5
2047 #endif
2048 
2049 #ifndef MG_CGI_ENVIRONMENT_SIZE
2050 #define MG_CGI_ENVIRONMENT_SIZE 8192
2051 #endif
2052 
2053 #ifndef MG_MAX_CGI_ENVIR_VARS
2054 #define MG_MAX_CGI_ENVIR_VARS 64
2055 #endif
2056 
2057 #ifndef MG_ENV_EXPORT_TO_CGI
2058 #define MG_ENV_EXPORT_TO_CGI "MONGOOSE_CGI"
2059 #endif
2060 
2061 /* HTTP message */
2063  struct mg_str message; /* Whole message: request line + headers + body */
2064 
2065  /* HTTP Request line (or HTTP response line) */
2066  struct mg_str method; /* "GET" */
2067  struct mg_str uri; /* "/my_file.html" */
2068  struct mg_str proto; /* "HTTP/1.1" -- for both request and response */
2069 
2070  /* For responses, code and response status message are set */
2071  int resp_code;
2072  struct mg_str resp_status_msg;
2073 
2074  /*
2075  * Query-string part of the URI. For example, for HTTP request
2076  * GET /foo/bar?param1=val1&param2=val2
2077  * | uri | query_string |
2078  *
2079  * Note that question mark character doesn't belong neither to the uri,
2080  * nor to the query_string
2081  */
2082  struct mg_str query_string;
2083 
2084  /* Headers */
2085  struct mg_str header_names[MG_MAX_HTTP_HEADERS];
2086  struct mg_str header_values[MG_MAX_HTTP_HEADERS];
2087 
2088  /* Message body */
2089  struct mg_str body; /* Zero-length for requests with no body */
2090 };
2091 
2092 /* WebSocket message */
2094  unsigned char *data;
2095  size_t size;
2096  unsigned char flags;
2097 };
2098 
2099 /* HTTP multipart part */
2101  const char *file_name;
2102  const char *var_name;
2103  struct mg_str data;
2104  int status; /* <0 on error */
2105  void *user_data;
2106 };
2107 
2108 /* HTTP and websocket events. void *ev_data is described in a comment. */
2109 #define MG_EV_HTTP_REQUEST 100 /* struct http_message * */
2110 #define MG_EV_HTTP_REPLY 101 /* struct http_message * */
2111 #define MG_EV_HTTP_CHUNK 102 /* struct http_message * */
2112 #define MG_EV_SSI_CALL 105 /* char * */
2113 
2114 #define MG_EV_WEBSOCKET_HANDSHAKE_REQUEST 111 /* NULL */
2115 #define MG_EV_WEBSOCKET_HANDSHAKE_DONE 112 /* NULL */
2116 #define MG_EV_WEBSOCKET_FRAME 113 /* struct websocket_message * */
2117 #define MG_EV_WEBSOCKET_CONTROL_FRAME 114 /* struct websocket_message * */
2118 
2119 #ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
2120 #define MG_EV_HTTP_MULTIPART_REQUEST 121 /* struct http_message */
2121 #define MG_EV_HTTP_PART_BEGIN 122 /* struct mg_http_multipart_part */
2122 #define MG_EV_HTTP_PART_DATA 123 /* struct mg_http_multipart_part */
2123 #define MG_EV_HTTP_PART_END 124 /* struct mg_http_multipart_part */
2124 #endif
2125 
2126 /*
2127  * Attach built-in HTTP event handler to the given connection.
2128  * User-defined event handler will receive following extra events:
2129  *
2130  * - MG_EV_HTTP_REQUEST: HTTP request has arrived. Parsed HTTP request
2131  * is passed as
2132  * `struct http_message` through the handler's `void *ev_data` pointer.
2133  * - MG_EV_HTTP_MULTIPART_REQUEST: A multipart POST request has received.
2134  * This event is sent before body is parsed. After this user
2135  * should expect a sequence of MG_EV_HTTP_PART_BEGIN/DATA/END requests.
2136  * This is also the last time when headers and other request fields are
2137  * accessible.
2138  * - MG_EV_HTTP_REPLY: HTTP reply has arrived. Parsed HTTP reply is passed as
2139  * `struct http_message` through the handler's `void *ev_data` pointer.
2140  * - MG_EV_HTTP_CHUNK: HTTP chunked-encoding chunk has arrived.
2141  * Parsed HTTP reply is passed as `struct http_message` through the
2142  * handler's `void *ev_data` pointer. `http_message::body` would contain
2143  * incomplete, reassembled HTTP body.
2144  * It will grow with every new chunk arrived, and
2145  * potentially can consume a lot of memory. An event handler may process
2146  * the body as chunks are coming, and signal Mongoose to delete processed
2147  * body by setting `MG_F_DELETE_CHUNK` in `mg_connection::flags`. When
2148  * the last zero chunk is received,
2149  * Mongoose sends `MG_EV_HTTP_REPLY` event with
2150  * full reassembled body (if handler did not signal to delete chunks) or
2151  * with empty body (if handler did signal to delete chunks).
2152  * - MG_EV_WEBSOCKET_HANDSHAKE_REQUEST: server has received websocket handshake
2153  * request. `ev_data` contains parsed HTTP request.
2154  * - MG_EV_WEBSOCKET_HANDSHAKE_DONE: server has completed Websocket handshake.
2155  * `ev_data` is `NULL`.
2156  * - MG_EV_WEBSOCKET_FRAME: new websocket frame has arrived. `ev_data` is
2157  * `struct websocket_message *`
2158  * - MG_EV_HTTP_PART_BEGIN: new part of multipart message is started,
2159  * extra parameters are passed in mg_http_multipart_part
2160  * - MG_EV_HTTP_PART_DATA: new portion of data from multiparted message
2161  * no additional headers are available, only data and data size
2162  * - MG_EV_HTTP_PART_END: final boundary received, analogue to maybe used to
2163  * find the end of packet
2164  * Note: Mongoose should be compiled with MG_ENABLE_HTTP_STREAMING_MULTIPART
2165  * to enable MG_EV_HTTP_MULTIPART_REQUEST, MG_EV_HTTP_REQUEST_END,
2166  * MG_EV_HTTP_REQUEST_CANCEL, MG_EV_HTTP_PART_BEGIN, MG_EV_HTTP_PART_DATA,
2167  * MG_EV_HTTP_PART_END constants
2168  */
2169 void mg_set_protocol_http_websocket(struct mg_connection *nc);
2170 
2171 /*
2172  * Send websocket handshake to the server.
2173  *
2174  * `nc` must be a valid connection, connected to a server. `uri` is an URI
2175  * to fetch, extra_headers` is extra HTTP headers to send or `NULL`.
2176  *
2177  * This function is intended to be used by websocket client.
2178  *
2179  * Note that the Host header is mandatory in HTTP/1.1 and must be
2180  * included in `extra_headers`. `mg_send_websocket_handshake2` offers
2181  * a better API for that.
2182  *
2183  * Deprecated in favour of `mg_send_websocket_handshake2`
2184  */
2185 void mg_send_websocket_handshake(struct mg_connection *nc, const char *uri,
2186  const char *extra_headers);
2187 
2188 /*
2189  * Send websocket handshake to the server.
2190  *
2191  * `nc` must be a valid connection, connected to a server. `uri` is an URI
2192  * to fetch, `host` goes into the `Host` header, `protocol` goes into the
2193  * `Sec-WebSocket-Proto` header (NULL to omit), extra_headers` is extra HTTP
2194  * headers to send or `NULL`.
2195  *
2196  * This function is intended to be used by websocket client.
2197  */
2198 void mg_send_websocket_handshake2(struct mg_connection *nc, const char *path,
2199  const char *host, const char *protocol,
2200  const char *extra_headers);
2201 
2202 /*
2203  * Helper function that creates an outbound WebSocket connection.
2204  *
2205  * `url` is a URL to connect to. It must be properly URL-encoded, e.g. have
2206  * no spaces, etc. By default, `mg_connect_ws()` sends Connection and
2207  * Host headers. `extra_headers` is an extra HTTP headers to send, e.g.
2208  * `"User-Agent: my-app\r\n"`.
2209  * If `protocol` is not NULL, then a `Sec-WebSocket-Protocol` header is sent.
2210  *
2211  * Examples:
2212  *
2213  * ```c
2214  * nc1 = mg_connect_ws(mgr, ev_handler_1, "ws://echo.websocket.org", NULL,
2215  * NULL);
2216  * nc2 = mg_connect_ws(mgr, ev_handler_1, "wss://echo.websocket.org", NULL,
2217  * NULL);
2218  * nc3 = mg_connect_ws(mgr, ev_handler_1, "ws://api.cesanta.com",
2219  * "clubby.cesanta.com", NULL);
2220  * ```
2221  */
2222 struct mg_connection *mg_connect_ws(struct mg_mgr *mgr,
2223  mg_event_handler_t event_handler,
2224  const char *url, const char *protocol,
2225  const char *extra_headers);
2226 
2227 /*
2228  * Helper function that creates an outbound WebSocket connection
2229  *
2230  * Mostly identical to mg_connect_ws, but allows to provide extra parameters
2231  * (for example, SSL parameters
2232  */
2233 struct mg_connection *mg_connect_ws_opt(struct mg_mgr *mgr,
2234  mg_event_handler_t ev_handler,
2235  struct mg_connect_opts opts,
2236  const char *url, const char *protocol,
2237  const char *extra_headers);
2238 
2239 /*
2240  * Send websocket frame to the remote end.
2241  *
2242  * `op_and_flags` specifies frame's type, one of:
2243  *
2244  * - WEBSOCKET_OP_CONTINUE
2245  * - WEBSOCKET_OP_TEXT
2246  * - WEBSOCKET_OP_BINARY
2247  * - WEBSOCKET_OP_CLOSE
2248  * - WEBSOCKET_OP_PING
2249  * - WEBSOCKET_OP_PONG
2250  *
2251  * Orred with one of the flags:
2252  *
2253  * - WEBSOCKET_DONT_FIN: Don't set the FIN flag on the frame to be sent.
2254  *
2255  * `data` and `data_len` contain frame data.
2256  */
2257 void mg_send_websocket_frame(struct mg_connection *nc, int op_and_flags,
2258  const void *data, size_t data_len);
2259 
2260 /*
2261  * Send multiple websocket frames.
2262  *
2263  * Like `mg_send_websocket_frame()`, but composes a frame from multiple buffers.
2264  */
2265 void mg_send_websocket_framev(struct mg_connection *nc, int op_and_flags,
2266  const struct mg_str *strings, int num_strings);
2267 
2268 /*
2269  * Send websocket frame to the remote end.
2270  *
2271  * Like `mg_send_websocket_frame()`, but allows to create formatted message
2272  * with `printf()`-like semantics.
2273  */
2274 void mg_printf_websocket_frame(struct mg_connection *nc, int op_and_flags,
2275  const char *fmt, ...);
2276 
2277 /*
2278  * Send buffer `buf` of size `len` to the client using chunked HTTP encoding.
2279  * This function first sends buffer size as hex number + newline, then
2280  * buffer itself, then newline. For example,
2281  * `mg_send_http_chunk(nc, "foo", 3)` whill append `3\r\nfoo\r\n` string to
2282  * the `nc->send_mbuf` output IO buffer.
2283  *
2284  * NOTE: HTTP header "Transfer-Encoding: chunked" should be sent prior to
2285  * using this function.
2286  *
2287  * NOTE: do not forget to send empty chunk at the end of the response,
2288  * to tell the client that everything was sent. Example:
2289  *
2290  * ```
2291  * mg_printf_http_chunk(nc, "%s", "my response!");
2292  * mg_send_http_chunk(nc, "", 0); // Tell the client we're finished
2293  * ```
2294  */
2295 void mg_send_http_chunk(struct mg_connection *nc, const char *buf, size_t len);
2296 
2297 /*
2298  * Send printf-formatted HTTP chunk.
2299  * Functionality is similar to `mg_send_http_chunk()`.
2300  */
2301 void mg_printf_http_chunk(struct mg_connection *nc, const char *fmt, ...);
2302 
2303 /*
2304  * Send response status line.
2305  * If `extra_headers` is not NULL, then `extra_headers` are also sent
2306  * after the reponse line. `extra_headers` must NOT end end with new line.
2307  * Example:
2308  *
2309  * mg_send_response_line(nc, 200, "Access-Control-Allow-Origin: *");
2310  *
2311  * Will result in:
2312  *
2313  * HTTP/1.1 200 OK\r\n
2314  * Access-Control-Allow-Origin: *\r\n
2315  */
2316 void mg_send_response_line(struct mg_connection *c, int status_code,
2317  const char *extra_headers);
2318 
2319 /*
2320  * Send response line and headers.
2321  * This function sends response line with the `status_code`, and automatically
2322  * sends one header: either "Content-Length", or "Transfer-Encoding".
2323  * If `content_length` is negative, then "Transfer-Encoding: chunked" header
2324  * is sent, otherwise, "Content-Length" header is sent.
2325  *
2326  * NOTE: If `Transfer-Encoding` is `chunked`, then message body must be sent
2327  * using `mg_send_http_chunk()` or `mg_printf_http_chunk()` functions.
2328  * Otherwise, `mg_send()` or `mg_printf()` must be used.
2329  * Extra headers could be set through `extra_headers` - and note `extra_headers`
2330  * must NOT be terminated by a new line.
2331  */
2332 void mg_send_head(struct mg_connection *n, int status_code,
2333  int64_t content_length, const char *extra_headers);
2334 
2335 /*
2336  * Send printf-formatted HTTP chunk, escaping HTML tags.
2337  */
2338 void mg_printf_html_escape(struct mg_connection *nc, const char *fmt, ...);
2339 
2340 /* Websocket opcodes, from http://tools.ietf.org/html/rfc6455 */
2341 #define WEBSOCKET_OP_CONTINUE 0
2342 #define WEBSOCKET_OP_TEXT 1
2343 #define WEBSOCKET_OP_BINARY 2
2344 #define WEBSOCKET_OP_CLOSE 8
2345 #define WEBSOCKET_OP_PING 9
2346 #define WEBSOCKET_OP_PONG 10
2347 
2348 /*
2349  * If set causes the FIN flag to not be set on outbound
2350  * frames. This enables sending multiple fragments of a single
2351  * logical message.
2352  *
2353  * The WebSocket protocol mandates that if the FIN flag of a data
2354  * frame is not set, the next frame must be a WEBSOCKET_OP_CONTINUE.
2355  * The last frame must have the FIN bit set.
2356  *
2357  * Note that mongoose will automatically defragment incoming messages,
2358  * so this flag is used only on outbound messages.
2359  */
2360 #define WEBSOCKET_DONT_FIN 0x100
2361 
2362 /*
2363  * Parse a HTTP message.
2364  *
2365  * `is_req` should be set to 1 if parsing request, 0 if reply.
2366  *
2367  * Return number of bytes parsed. If HTTP message is
2368  * incomplete, `0` is returned. On parse error, negative number is returned.
2369  */
2370 int mg_parse_http(const char *s, int n, struct http_message *hm, int is_req);
2371 
2372 /*
2373  * Search and return header `name` in parsed HTTP message `hm`.
2374  * If header is not found, NULL is returned. Example:
2375  *
2376  * struct mg_str *host_hdr = mg_get_http_header(hm, "Host");
2377  */
2378 struct mg_str *mg_get_http_header(struct http_message *hm, const char *name);
2379 
2380 /*
2381  * Parse HTTP header `hdr`. Find variable `var_name` and store it's value
2382  * in the buffer `buf`, `buf_size`. Return 0 if variable not found, non-zero
2383  * otherwise.
2384  *
2385  * This function is supposed to parse
2386  * cookies, authentication headers, etcetera. Example (error handling omitted):
2387  *
2388  * char user[20];
2389  * struct mg_str *hdr = mg_get_http_header(hm, "Authorization");
2390  * mg_http_parse_header(hdr, "username", user, sizeof(user));
2391  *
2392  * Return length of the variable's value. If buffer is not large enough,
2393  * or variable not found, 0 is returned.
2394  */
2395 int mg_http_parse_header(struct mg_str *hdr, const char *var_name, char *buf,
2396  size_t buf_size);
2397 
2398 /*
2399  * Parse buffer `buf`, `buf_len` that contains multipart form data chunks.
2400  * Store chunk name in a `var_name`, `var_name_len` buffer.
2401  * If a chunk is an uploaded file, then `file_name`, `file_name_len` is
2402  * filled with an uploaded file name. `chunk`, `chunk_len`
2403  * points to the chunk data.
2404  *
2405  * Return: number of bytes to skip to the next chunk, or 0 if there are
2406  * no more chunks.
2407  *
2408  * Usage example:
2409  *
2410  * ```c
2411  * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
2412  * switch(ev) {
2413  * case MG_EV_HTTP_REQUEST: {
2414  * struct http_message *hm = (struct http_message *) ev_data;
2415  * char var_name[100], file_name[100];
2416  * const char *chunk;
2417  * size_t chunk_len, n1, n2;
2418  *
2419  * n1 = n2 = 0;
2420  * while ((n2 = mg_parse_multipart(hm->body.p + n1,
2421  * hm->body.len - n1,
2422  * var_name, sizeof(var_name),
2423  * file_name, sizeof(file_name),
2424  * &chunk, &chunk_len)) > 0) {
2425  * printf("var: %s, file_name: %s, size: %d, chunk: [%.*s]\n",
2426  * var_name, file_name, (int) chunk_len,
2427  * (int) chunk_len, chunk);
2428  * n1 += n2;
2429  * }
2430  * }
2431  * break;
2432  * ```
2433  */
2434 size_t mg_parse_multipart(const char *buf, size_t buf_len, char *var_name,
2435  size_t var_name_len, char *file_name,
2436  size_t file_name_len, const char **chunk,
2437  size_t *chunk_len);
2438 
2439 /*
2440  * Fetch an HTTP form variable.
2441  *
2442  * Fetch a variable `name` from a `buf` into a buffer specified by
2443  * `dst`, `dst_len`. Destination is always zero-terminated. Return length
2444  * of a fetched variable. If not found, 0 is returned. `buf` must be
2445  * valid url-encoded buffer. If destination is too small, `-1` is returned.
2446  */
2447 int mg_get_http_var(const struct mg_str *buf, const char *name, char *dst,
2448  size_t dst_len);
2449 
2450 /*
2451  * Decode URL-encoded string.
2452  *
2453  * Source string is specified by (`src`, `src_len`), and destination is
2454  * (`dst`, `dst_len`). If `is_form_url_encoded` is non-zero, then
2455  * `+` character is decoded as a blank space character. This function
2456  * guarantees to `\0`-terminate the destination. If destination is too small,
2457  * then source string is partially decoded and `-1` is returned. Otherwise,
2458  * a length of decoded string is returned, not counting final `\0`.
2459  */
2460 int mg_url_decode(const char *src, int src_len, char *dst, int dst_len,
2461  int is_form_url_encoded);
2462 
2463 /* Create Digest authentication header for client request. */
2464 int mg_http_create_digest_auth_header(char *buf, size_t buf_len,
2465  const char *method, const char *uri,
2466  const char *auth_domain, const char *user,
2467  const char *passwd);
2468 
2469 /*
2470  * Helper function that creates outbound HTTP connection.
2471  *
2472  * `url` is a URL to fetch. It must be properly URL-encoded, e.g. have
2473  * no spaces, etc. By default, `mg_connect_http()` sends Connection and
2474  * Host headers. `extra_headers` is an extra HTTP headers to send, e.g.
2475  * `"User-Agent: my-app\r\n"`.
2476  * If `post_data` is NULL, then GET request is created. Otherwise, POST request
2477  * is created with the specified POST data. Note that if the data being posted
2478  * is a form submission, the `Content-Type` header should be set accordingly
2479  * (see example below).
2480  *
2481  * Examples:
2482  *
2483  * ```c
2484  * nc1 = mg_connect_http(mgr, ev_handler_1, "http://www.google.com", NULL,
2485  * NULL);
2486  * nc2 = mg_connect_http(mgr, ev_handler_1, "https://github.com", NULL, NULL);
2487  * nc3 = mg_connect_http(
2488  * mgr, ev_handler_1, "my_server:8000/form_submit/",
2489  * "Content-Type: application/x-www-form-urlencoded\r\n",
2490  * "var_1=value_1&var_2=value_2");
2491  * ```
2492  */
2493 struct mg_connection *mg_connect_http(struct mg_mgr *mgr,
2494  mg_event_handler_t event_handler,
2495  const char *url,
2496  const char *extra_headers,
2497  const char *post_data);
2498 
2499 /*
2500  * Helper function that creates outbound HTTP connection.
2501  *
2502  * Mostly identical to mg_connect_http, but allows to provide extra parameters
2503  * (for example, SSL parameters
2504  */
2505 struct mg_connection *mg_connect_http_opt(struct mg_mgr *mgr,
2506  mg_event_handler_t ev_handler,
2507  struct mg_connect_opts opts,
2508  const char *url,
2509  const char *extra_headers,
2510  const char *post_data);
2511 /*
2512  * This structure defines how `mg_serve_http()` works.
2513  * Best practice is to set only required settings, and leave the rest as NULL.
2514  */
2516  /* Path to web root directory */
2517  const char *document_root;
2518 
2519  /* List of index files. Default is "" */
2520  const char *index_files;
2521 
2522  /*
2523  * Leave as NULL to disable authentication.
2524  * To enable directory protection with authentication, set this to ".htpasswd"
2525  * Then, creating ".htpasswd" file in any directory automatically protects
2526  * it with digest authentication.
2527  * Use `mongoose` web server binary, or `htdigest` Apache utility to
2528  * create/manipulate passwords file.
2529  * Make sure `auth_domain` is set to a valid domain name.
2530  */
2531  const char *per_directory_auth_file;
2532 
2533  /* Authorization domain (domain name of this web server) */
2534  const char *auth_domain;
2535 
2536  /*
2537  * Leave as NULL to disable authentication.
2538  * Normally, only selected directories in the document root are protected.
2539  * If absolutely every access to the web server needs to be authenticated,
2540  * regardless of the URI, set this option to the path to the passwords file.
2541  * Format of that file is the same as ".htpasswd" file. Make sure that file
2542  * is located outside document root to prevent people fetching it.
2543  */
2544  const char *global_auth_file;
2545 
2546  /* Set to "no" to disable directory listing. Enabled by default. */
2547  const char *enable_directory_listing;
2548 
2549  /* SSI files pattern. If not set, "**.shtml$|**.shtm$" is used. */
2550  const char *ssi_pattern;
2551 
2552  /* IP ACL. By default, NULL, meaning all IPs are allowed to connect */
2553  const char *ip_acl;
2554 
2555  /* URL rewrites.
2556  *
2557  * Comma-separated list of `uri_pattern=file_or_directory_path` rewrites.
2558  * When HTTP request is received, Mongoose constructs a file name from the
2559  * requested URI by combining `document_root` and the URI. However, if the
2560  * rewrite option is used and `uri_pattern` matches requested URI, then
2561  * `document_root` is ignored. Instead, `file_or_directory_path` is used,
2562  * which should be a full path name or a path relative to the web server's
2563  * current working directory. Note that `uri_pattern`, as all Mongoose
2564  * patterns, is a prefix pattern.
2565  *
2566  * If uri_pattern starts with `@` symbol, then Mongoose compares it with the
2567  * HOST header of the request. If they are equal, Mongoose sets document root
2568  * to `file_or_directory_path`, implementing virtual hosts support.
2569  * Example: `@foo.com=/document/root/for/foo.com`
2570  *
2571  * If `uri_pattern` starts with `%` symbol, then Mongoose compares it with
2572  * the listening port. If they match, then Mongoose issues a 301 redirect.
2573  * For example, to redirect all HTTP requests to the
2574  * HTTPS port, do `%80=https://my.site.com`. Note that the request URI is
2575  * automatically appended to the redirect location.
2576  */
2577  const char *url_rewrites;
2578 
2579  /* DAV document root. If NULL, DAV requests are going to fail. */
2580  const char *dav_document_root;
2581 
2582  /*
2583  * DAV passwords file. If NULL, DAV requests are going to fail.
2584  * If passwords file is set to "-", then DAV auth is disabled.
2585  */
2586  const char *dav_auth_file;
2587 
2588  /* Glob pattern for the files to hide. */
2589  const char *hidden_file_pattern;
2590 
2591  /* Set to non-NULL to enable CGI, e.g. **.cgi$|**.php$" */
2592  const char *cgi_file_pattern;
2593 
2594  /* If not NULL, ignore CGI script hashbang and use this interpreter */
2595  const char *cgi_interpreter;
2596 
2597  /*
2598  * Comma-separated list of Content-Type overrides for path suffixes, e.g.
2599  * ".txt=text/plain; charset=utf-8,.c=text/plain"
2600  */
2601  const char *custom_mime_types;
2602 
2603  /*
2604  * Extra HTTP headers to add to each server response.
2605  * Example: to enable CORS, set this to "Access-Control-Allow-Origin: *".
2606  */
2607  const char *extra_headers;
2608 };
2609 
2610 /*
2611  * Serve given HTTP request according to the `options`.
2612  *
2613  * Example code snippet:
2614  *
2615  * ```c
2616  * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
2617  * struct http_message *hm = (struct http_message *) ev_data;
2618  * struct mg_serve_http_opts opts = { .document_root = "/var/www" }; // C99
2619  *
2620  * switch (ev) {
2621  * case MG_EV_HTTP_REQUEST:
2622  * mg_serve_http(nc, hm, opts);
2623  * break;
2624  * default:
2625  * break;
2626  * }
2627  * }
2628  * ```
2629  */
2630 void mg_serve_http(struct mg_connection *nc, struct http_message *hm,
2631  struct mg_serve_http_opts opts);
2632 
2633 /*
2634  * Register callback for specified http endpoint
2635  * Note: if callback is registered it is called instead of
2636  * callback provided in mg_bind
2637  *
2638  * Example code snippet:
2639  *
2640  * ```c
2641  * static void handle_hello1(struct mg_connection *nc, int ev, void *ev_data) {
2642  * (void) ev; (void) ev_data;
2643  * mg_printf(nc, "HTTP/1.0 200 OK\r\n\r\n[I am Hello1]");
2644  * nc->flags |= MG_F_SEND_AND_CLOSE;
2645  * }
2646  *
2647  * static void handle_hello1(struct mg_connection *nc, int ev, void *ev_data) {
2648  * (void) ev; (void) ev_data;
2649  * mg_printf(nc, "HTTP/1.0 200 OK\r\n\r\n[I am Hello2]");
2650  * nc->flags |= MG_F_SEND_AND_CLOSE;
2651  * }
2652  *
2653  * void init() {
2654  * nc = mg_bind(&mgr, local_addr, cb1);
2655  * mg_register_http_endpoint(nc, "/hello1", handle_hello1);
2656  * mg_register_http_endpoint(nc, "/hello1/hello2", handle_hello2);
2657  * }
2658  * ```
2659  */
2660 void mg_register_http_endpoint(struct mg_connection *nc, const char *uri_path,
2661  mg_event_handler_t handler);
2662 
2663 #ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
2664 
2665 /* Callback prototype for `mg_file_upload_handler()`. */
2666 typedef struct mg_str (*mg_fu_fname_fn)(struct mg_connection *nc,
2667  struct mg_str fname);
2668 
2669 /*
2670  * File upload handler.
2671  * This handler can be used to implement file uploads with minimum code.
2672  * This handler will process MG_EV_HTTP_PART_* events and store file data into
2673  * a local file.
2674  * `local_name_fn` will be invoked with whatever name was provided by the client
2675  * and will expect the name of the local file to open. Return value of NULL will
2676  * abort file upload (client will get a "403 Forbidden" response). If non-null,
2677  * the returned string must be heap-allocated and will be freed by the caller.
2678  * Exception: it is ok to return the same string verbatim.
2679  *
2680  * Example:
2681  *
2682  * ```c
2683  * struct mg_str upload_fname(struct mg_connection *nc, struct mg_str fname) {
2684  * // Just return the same filename. Do not actually do this except in test!
2685  * // fname is user-controlled and needs to be sanitized.
2686  * return fname;
2687  * }
2688  * void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
2689  * switch (ev) {
2690  * ...
2691  * case MG_EV_HTTP_PART_BEGIN:
2692  * case MG_EV_HTTP_PART_DATA:
2693  * case MG_EV_HTTP_PART_END:
2694  * mg_file_upload_handler(nc, ev, ev_data, upload_fname);
2695  * break;
2696  * }
2697  * }
2698  * ```
2699  */
2700 void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data,
2701  mg_fu_fname_fn local_name_fn);
2702 #endif /* MG_ENABLE_HTTP_STREAMING_MULTIPART */
2703 
2704 #ifdef __cplusplus
2705 }
2706 #endif /* __cplusplus */
2707 #endif /* CS_MONGOOSE_SRC_HTTP_H_ */
2708 /*
2709  * Copyright (c) 2014 Cesanta Software Limited
2710  * All rights reserved
2711  */
2712 
2713 /*
2714  * === JSON-RPC
2715  */
2716 
2717 #ifndef CS_MONGOOSE_SRC_JSON_RPC_H_
2718 #define CS_MONGOOSE_SRC_JSON_RPC_H_
2719 
2720 #ifdef __cplusplus
2721 extern "C" {
2722 #endif /* __cplusplus */
2723 
2724 /* JSON-RPC request */
2726  struct json_token *message; /* Whole RPC message */
2727  struct json_token *id; /* Message ID */
2728  struct json_token *method; /* Method name */
2729  struct json_token *params; /* Method params */
2730 };
2731 
2732 /* JSON-RPC response */
2734  struct json_token *message; /* Whole RPC message */
2735  struct json_token *id; /* Message ID */
2736  struct json_token *result; /* Remote call result */
2737 };
2738 
2739 /* JSON-RPC error */
2741  struct json_token *message; /* Whole RPC message */
2742  struct json_token *id; /* Message ID */
2743  struct json_token *error_code; /* error.code */
2744  struct json_token *error_message; /* error.message */
2745  struct json_token *error_data; /* error.data, can be NULL */
2746 };
2747 
2748 /*
2749  * Parse JSON-RPC reply contained in `buf`, `len` into JSON tokens array
2750  * `toks`, `max_toks`. If buffer contains valid reply, `reply` structure is
2751  * populated. The result of RPC call is located in `reply.result`. On error,
2752  * `error` structure is populated. Returns: the result of calling
2753  * `parse_json(buf, len, toks, max_toks)`:
2754  *
2755  * On success, an offset inside `json_string` is returned
2756  * where parsing has finished. On failure, a negative number is
2757  * returned, one of:
2758  *
2759  * - `#define JSON_STRING_INVALID -1`
2760  * - `#define JSON_STRING_INCOMPLETE -2`
2761  * - `#define JSON_TOKEN_ARRAY_TOO_SMALL -3`
2762  */
2763 int mg_rpc_parse_reply(const char *buf, int len, struct json_token *toks,
2764  int max_toks, struct mg_rpc_reply *,
2765  struct mg_rpc_error *);
2766 
2767 /*
2768  * Create JSON-RPC request in a given buffer.
2769  *
2770  * Return length of the request, which
2771  * can be larger then `len` that indicates an overflow.
2772  * `params_fmt` format string should conform to `json_emit()` API,
2773  * see https://github.com/cesanta/frozen
2774  */
2775 int mg_rpc_create_request(char *buf, int len, const char *method,
2776  const char *id, const char *params_fmt, ...);
2777 
2778 /*
2779  * Create JSON-RPC reply in a given buffer.
2780  *
2781  * Return length of the reply, which
2782  * can be larger then `len` that indicates an overflow.
2783  * `result_fmt` format string should conform to `json_emit()` API,
2784  * see https://github.com/cesanta/frozen
2785  */
2786 int mg_rpc_create_reply(char *buf, int len, const struct mg_rpc_request *req,
2787  const char *result_fmt, ...);
2788 
2789 /*
2790  * Create JSON-RPC error reply in a given buffer.
2791  *
2792  * Return length of the error, which
2793  * can be larger then `len` that indicates an overflow.
2794  * `fmt` format string should conform to `json_emit()` API,
2795  * see https://github.com/cesanta/frozen
2796  */
2797 int mg_rpc_create_error(char *buf, int len, struct mg_rpc_request *req,
2798  int code, const char *message, const char *fmt, ...);
2799 
2800 /* JSON-RPC standard error codes */
2801 #define JSON_RPC_PARSE_ERROR (-32700)
2802 #define JSON_RPC_INVALID_REQUEST_ERROR (-32600)
2803 #define JSON_RPC_METHOD_NOT_FOUND_ERROR (-32601)
2804 #define JSON_RPC_INVALID_PARAMS_ERROR (-32602)
2805 #define JSON_RPC_INTERNAL_ERROR (-32603)
2806 #define JSON_RPC_SERVER_ERROR (-32000)
2807 
2808 /*
2809  * Create JSON-RPC error in a given buffer.
2810  *
2811  * Return length of the error, which
2812  * can be larger then `len` that indicates an overflow. See
2813  * JSON_RPC_*_ERROR definitions for standard error values:
2814  *
2815  * - `#define JSON_RPC_PARSE_ERROR (-32700)`
2816  * - `#define JSON_RPC_INVALID_REQUEST_ERROR (-32600)`
2817  * - `#define JSON_RPC_METHOD_NOT_FOUND_ERROR (-32601)`
2818  * - `#define JSON_RPC_INVALID_PARAMS_ERROR (-32602)`
2819  * - `#define JSON_RPC_INTERNAL_ERROR (-32603)`
2820  * - `#define JSON_RPC_SERVER_ERROR (-32000)`
2821  */
2822 int mg_rpc_create_std_error(char *buf, int len, struct mg_rpc_request *req,
2823  int code);
2824 
2825 typedef int (*mg_rpc_handler_t)(char *buf, int len, struct mg_rpc_request *req);
2826 
2827 /*
2828  * Dispatches a JSON-RPC request.
2829  *
2830  * Parses JSON-RPC request contained in `buf`, `len`.
2831  * Then, dispatches the request to the correct handler method.
2832  * Valid method names should be specified in NULL
2833  * terminated array `methods`, and corresponding handlers in `handlers`.
2834  * Result is put in `dst`, `dst_len`. Return: length of the result, which
2835  * can be larger then `dst_len` that indicates an overflow.
2836  * Overflown bytes are not written to the buffer.
2837  * If method is not found, an error is automatically generated.
2838  */
2839 int mg_rpc_dispatch(const char *buf, int, char *dst, int dst_len,
2840  const char **methods, mg_rpc_handler_t *handlers);
2841 
2842 #ifdef __cplusplus
2843 }
2844 #endif /* __cplusplus */
2845 #endif /* CS_MONGOOSE_SRC_JSON_RPC_H_ */
2846 /*
2847  * Copyright (c) 2014 Cesanta Software Limited
2848  * All rights reserved
2849  * This software is dual-licensed: you can redistribute it and/or modify
2850  * it under the terms of the GNU General Public License version 2 as
2851  * published by the Free Software Foundation. For the terms of this
2852  * license, see <http://www.gnu.org/licenses/>.
2853  *
2854  * You are free to use this software under the terms of the GNU General
2855  * Public License, but WITHOUT ANY WARRANTY; without even the implied
2856  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
2857  * See the GNU General Public License for more details.
2858  *
2859  * Alternatively, you can license this software under a commercial
2860  * license, as set out in <https://www.cesanta.com/license>.
2861  */
2862 
2863 /*
2864  * === MQTT
2865  */
2866 
2867 #ifndef CS_MONGOOSE_SRC_MQTT_H_
2868 #define CS_MONGOOSE_SRC_MQTT_H_
2869 
2870 
2872  int cmd;
2873  struct mg_str payload;
2874  int qos;
2875  uint8_t connack_ret_code; /* connack */
2876  uint16_t message_id; /* puback */
2877  char *topic;
2878 };
2879 
2881  const char *topic;
2882  uint8_t qos;
2883 };
2884 
2886  unsigned char flags; /* connection flags */
2887  uint16_t keep_alive;
2888  const char *will_topic;
2889  const char *will_message;
2890  const char *user_name;
2891  const char *password;
2892 };
2893 
2894 /* Message types */
2895 #define MG_MQTT_CMD_CONNECT 1
2896 #define MG_MQTT_CMD_CONNACK 2
2897 #define MG_MQTT_CMD_PUBLISH 3
2898 #define MG_MQTT_CMD_PUBACK 4
2899 #define MG_MQTT_CMD_PUBREC 5
2900 #define MG_MQTT_CMD_PUBREL 6
2901 #define MG_MQTT_CMD_PUBCOMP 7
2902 #define MG_MQTT_CMD_SUBSCRIBE 8
2903 #define MG_MQTT_CMD_SUBACK 9
2904 #define MG_MQTT_CMD_UNSUBSCRIBE 10
2905 #define MG_MQTT_CMD_UNSUBACK 11
2906 #define MG_MQTT_CMD_PINGREQ 12
2907 #define MG_MQTT_CMD_PINGRESP 13
2908 #define MG_MQTT_CMD_DISCONNECT 14
2909 
2910 /* MQTT event types */
2911 #define MG_MQTT_EVENT_BASE 200
2912 #define MG_EV_MQTT_CONNECT (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_CONNECT)
2913 #define MG_EV_MQTT_CONNACK (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_CONNACK)
2914 #define MG_EV_MQTT_PUBLISH (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBLISH)
2915 #define MG_EV_MQTT_PUBACK (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBACK)
2916 #define MG_EV_MQTT_PUBREC (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBREC)
2917 #define MG_EV_MQTT_PUBREL (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBREL)
2918 #define MG_EV_MQTT_PUBCOMP (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBCOMP)
2919 #define MG_EV_MQTT_SUBSCRIBE (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_SUBSCRIBE)
2920 #define MG_EV_MQTT_SUBACK (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_SUBACK)
2921 #define MG_EV_MQTT_UNSUBSCRIBE (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_UNSUBSCRIBE)
2922 #define MG_EV_MQTT_UNSUBACK (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_UNSUBACK)
2923 #define MG_EV_MQTT_PINGREQ (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PINGREQ)
2924 #define MG_EV_MQTT_PINGRESP (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PINGRESP)
2925 #define MG_EV_MQTT_DISCONNECT (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_DISCONNECT)
2926 
2927 /* Message flags */
2928 #define MG_MQTT_RETAIN 0x1
2929 #define MG_MQTT_DUP 0x4
2930 #define MG_MQTT_QOS(qos) ((qos) << 1)
2931 #define MG_MQTT_GET_QOS(flags) (((flags) &0x6) >> 1)
2932 #define MG_MQTT_SET_QOS(flags, qos) (flags) = ((flags) & ~0x6) | ((qos) << 1)
2933 
2934 /* Connection flags */
2935 #define MG_MQTT_CLEAN_SESSION 0x02
2936 #define MG_MQTT_HAS_WILL 0x04
2937 #define MG_MQTT_WILL_RETAIN 0x20
2938 #define MG_MQTT_HAS_PASSWORD 0x40
2939 #define MG_MQTT_HAS_USER_NAME 0x80
2940 #define MG_MQTT_GET_WILL_QOS(flags) (((flags) &0x18) >> 3)
2941 #define MG_MQTT_SET_WILL_QOS(flags, qos) \
2942  (flags) = ((flags) & ~0x18) | ((qos) << 3)
2943 
2944 /* CONNACK return codes */
2945 #define MG_EV_MQTT_CONNACK_ACCEPTED 0
2946 #define MG_EV_MQTT_CONNACK_UNACCEPTABLE_VERSION 1
2947 #define MG_EV_MQTT_CONNACK_IDENTIFIER_REJECTED 2
2948 #define MG_EV_MQTT_CONNACK_SERVER_UNAVAILABLE 3
2949 #define MG_EV_MQTT_CONNACK_BAD_AUTH 4
2950 #define MG_EV_MQTT_CONNACK_NOT_AUTHORIZED 5
2951 
2952 #ifdef __cplusplus
2953 extern "C" {
2954 #endif /* __cplusplus */
2955 
2956 /*
2957  * Attach built-in MQTT event handler to the given connection.
2958  *
2959  * The user-defined event handler will receive following extra events:
2960  *
2961  * - MG_EV_MQTT_CONNACK
2962  * - MG_EV_MQTT_PUBLISH
2963  * - MG_EV_MQTT_PUBACK
2964  * - MG_EV_MQTT_PUBREC
2965  * - MG_EV_MQTT_PUBREL
2966  * - MG_EV_MQTT_PUBCOMP
2967  * - MG_EV_MQTT_SUBACK
2968  */
2969 void mg_set_protocol_mqtt(struct mg_connection *nc);
2970 
2971 /* Send MQTT handshake. */
2972 void mg_send_mqtt_handshake(struct mg_connection *nc, const char *client_id);
2973 
2974 /* Send MQTT handshake with optional parameters. */
2975 void mg_send_mqtt_handshake_opt(struct mg_connection *nc, const char *client_id,
2977 
2978 /* Publish a message to a given topic. */
2979 void mg_mqtt_publish(struct mg_connection *nc, const char *topic,
2980  uint16_t message_id, int flags, const void *data,
2981  size_t len);
2982 
2983 /* Subscribe to a bunch of topics. */
2984 void mg_mqtt_subscribe(struct mg_connection *nc,
2985  const struct mg_mqtt_topic_expression *topics,
2986  size_t topics_len, uint16_t message_id);
2987 
2988 /* Unsubscribe from a bunch of topics. */
2989 void mg_mqtt_unsubscribe(struct mg_connection *nc, char **topics,
2990  size_t topics_len, uint16_t message_id);
2991 
2992 /* Send a DISCONNECT command. */
2993 void mg_mqtt_disconnect(struct mg_connection *nc);
2994 
2995 /* Send a CONNACK command with a given `return_code`. */
2996 void mg_mqtt_connack(struct mg_connection *nc, uint8_t return_code);
2997 
2998 /* Send a PUBACK command with a given `message_id`. */
2999 void mg_mqtt_puback(struct mg_connection *nc, uint16_t message_id);
3000 
3001 /* Send a PUBREC command with a given `message_id`. */
3002 void mg_mqtt_pubrec(struct mg_connection *nc, uint16_t message_id);
3003 
3004 /* Send a PUBREL command with a given `message_id`. */
3005 void mg_mqtt_pubrel(struct mg_connection *nc, uint16_t message_id);
3006 
3007 /* Send a PUBCOMP command with a given `message_id`. */
3008 void mg_mqtt_pubcomp(struct mg_connection *nc, uint16_t message_id);
3009 
3010 /*
3011  * Send a SUBACK command with a given `message_id`
3012  * and a sequence of granted QoSs.
3013  */
3014 void mg_mqtt_suback(struct mg_connection *nc, uint8_t *qoss, size_t qoss_len,
3015  uint16_t message_id);
3016 
3017 /* Send a UNSUBACK command with a given `message_id`. */
3018 void mg_mqtt_unsuback(struct mg_connection *nc, uint16_t message_id);
3019 
3020 /* Send a PINGREQ command. */
3021 void mg_mqtt_ping(struct mg_connection *nc);
3022 
3023 /* Send a PINGRESP command. */
3024 void mg_mqtt_pong(struct mg_connection *nc);
3025 
3026 /*
3027  * Extract the next topic expression from a SUBSCRIBE command payload.
3028  *
3029  * Topic expression name will point to a string in the payload buffer.
3030  * Return the pos of the next topic expression or -1 when the list
3031  * of topics is exhausted.
3032  */
3033 int mg_mqtt_next_subscribe_topic(struct mg_mqtt_message *msg,
3034  struct mg_str *topic, uint8_t *qos, int pos);
3035 
3036 #ifdef __cplusplus
3037 }
3038 #endif /* __cplusplus */
3039 
3040 #endif /* CS_MONGOOSE_SRC_MQTT_H_ */
3041 /*
3042  * Copyright (c) 2014 Cesanta Software Limited
3043  * All rights reserved
3044  * This software is dual-licensed: you can redistribute it and/or modify
3045  * it under the terms of the GNU General Public License version 2 as
3046  * published by the Free Software Foundation. For the terms of this
3047  * license, see <http://www.gnu.org/licenses/>.
3048  *
3049  * You are free to use this software under the terms of the GNU General
3050  * Public License, but WITHOUT ANY WARRANTY; without even the implied
3051  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
3052  * See the GNU General Public License for more details.
3053  *
3054  * Alternatively, you can license this software under a commercial
3055  * license, as set out in <https://www.cesanta.com/license>.
3056  */
3057 
3058 /*
3059  * === MQTT Broker
3060  */
3061 
3062 #ifndef CS_MONGOOSE_SRC_MQTT_BROKER_H_
3063 #define CS_MONGOOSE_SRC_MQTT_BROKER_H_
3064 
3065 #ifdef MG_ENABLE_MQTT_BROKER
3066 
3067 
3068 #ifdef __cplusplus
3069 extern "C" {
3070 #endif /* __cplusplus */
3071 
3072 #define MG_MQTT_MAX_SESSION_SUBSCRIPTIONS 512;
3073 
3074 struct mg_mqtt_broker;
3075 
3076 /* MQTT session (Broker side). */
3077 struct mg_mqtt_session {
3078  struct mg_mqtt_broker *brk; /* Broker */
3079  struct mg_mqtt_session *next, *prev; /* mg_mqtt_broker::sessions linkage */
3080  struct mg_connection *nc; /* Connection with the client */
3081  size_t num_subscriptions; /* Size of `subscriptions` array */
3082  struct mg_mqtt_topic_expression *subscriptions;
3083  void *user_data; /* User data */
3084 };
3085 
3086 /* MQTT broker. */
3087 struct mg_mqtt_broker {
3088  struct mg_mqtt_session *sessions; /* Session list */
3089  void *user_data; /* User data */
3090 };
3091 
3092 /* Initialize a MQTT broker. */
3093 void mg_mqtt_broker_init(struct mg_mqtt_broker *brk, void *user_data);
3094 
3095 /*
3096  * Process a MQTT broker message.
3097  *
3098  * Listening connection expects a pointer to an initialized `mg_mqtt_broker`
3099  * structure in the `user_data` field.
3100  *
3101  * Basic usage:
3102  *
3103  * ```c
3104  * mg_mqtt_broker_init(&brk, NULL);
3105  *
3106  * if ((nc = mg_bind(&mgr, address, mg_mqtt_broker)) == NULL) {
3107  * // fail;
3108  * }
3109  * nc->user_data = &brk;
3110  * ```
3111  *
3112  * New incoming connections will receive a `mg_mqtt_session` structure
3113  * in the connection `user_data`. The original `user_data` will be stored
3114  * in the `user_data` field of the session structure. This allows the user
3115  * handler to store user data before `mg_mqtt_broker` creates the session.
3116  *
3117  * Since only the MG_EV_ACCEPT message is processed by the listening socket,
3118  * for most events the `user_data` will thus point to a `mg_mqtt_session`.
3119  */
3120 void mg_mqtt_broker(struct mg_connection *brk, int ev, void *data);
3121 
3122 /*
3123  * Iterate over all mqtt sessions connections. Example:
3124  *
3125  * ```c
3126  * struct mg_mqtt_session *s;
3127  * for (s = mg_mqtt_next(brk, NULL); s != NULL; s = mg_mqtt_next(brk, s)) {
3128  * // Do something
3129  * }
3130  * ```
3131  */
3132 struct mg_mqtt_session *mg_mqtt_next(struct mg_mqtt_broker *brk,
3133  struct mg_mqtt_session *s);
3134 
3135 #ifdef __cplusplus
3136 }
3137 #endif /* __cplusplus */
3138 
3139 #endif /* MG_ENABLE_MQTT_BROKER */
3140 #endif /* CS_MONGOOSE_SRC_MQTT_BROKER_H_ */
3141 /*
3142  * Copyright (c) 2014 Cesanta Software Limited
3143  * All rights reserved
3144  */
3145 
3146 /*
3147  * === DNS
3148  */
3149 
3150 #ifndef CS_MONGOOSE_SRC_DNS_H_
3151 #define CS_MONGOOSE_SRC_DNS_H_
3152 
3153 
3154 #ifdef __cplusplus
3155 extern "C" {
3156 #endif /* __cplusplus */
3157 
3158 #define MG_DNS_A_RECORD 0x01 /* Lookup IP address */
3159 #define MG_DNS_CNAME_RECORD 0x05 /* Lookup CNAME */
3160 #define MG_DNS_AAAA_RECORD 0x1c /* Lookup IPv6 address */
3161 #define MG_DNS_MX_RECORD 0x0f /* Lookup mail server for domain */
3162 
3163 #define MG_MAX_DNS_QUESTIONS 32
3164 #define MG_MAX_DNS_ANSWERS 32
3165 
3166 #define MG_DNS_MESSAGE 100 /* High-level DNS message event */
3167 
3168 enum mg_dns_resource_record_kind {
3169  MG_DNS_INVALID_RECORD = 0,
3170  MG_DNS_QUESTION,
3171  MG_DNS_ANSWER
3172 };
3173 
3174 /* DNS resource record. */
3176  struct mg_str name; /* buffer with compressed name */
3177  int rtype;
3178  int rclass;
3179  int ttl;
3180  enum mg_dns_resource_record_kind kind;
3181  struct mg_str rdata; /* protocol data (can be a compressed name) */
3182 };
3183 
3184 /* DNS message (request and response). */
3186  struct mg_str pkt; /* packet body */
3187  uint16_t flags;
3188  uint16_t transaction_id;
3189  int num_questions;
3190  int num_answers;
3191  struct mg_dns_resource_record questions[MG_MAX_DNS_QUESTIONS];
3192  struct mg_dns_resource_record answers[MG_MAX_DNS_ANSWERS];
3193 };
3194 
3195 struct mg_dns_resource_record *mg_dns_next_record(
3196  struct mg_dns_message *msg, int query, struct mg_dns_resource_record *prev);
3197 
3198 /*
3199  * Parse the record data from a DNS resource record.
3200  *
3201  * - A: struct in_addr *ina
3202  * - AAAA: struct in6_addr *ina
3203  * - CNAME: char buffer
3204  *
3205  * Returns -1 on error.
3206  *
3207  * TODO(mkm): MX
3208  */
3209 int mg_dns_parse_record_data(struct mg_dns_message *msg,
3210  struct mg_dns_resource_record *rr, void *data,
3211  size_t data_len);
3212 
3213 /*
3214  * Send a DNS query to the remote end.
3215  */
3216 void mg_send_dns_query(struct mg_connection *nc, const char *name,
3217  int query_type);
3218 
3219 /*
3220  * Insert a DNS header to an IO buffer.
3221  *
3222  * Return number of bytes inserted.
3223  */
3224 int mg_dns_insert_header(struct mbuf *io, size_t pos,
3225  struct mg_dns_message *msg);
3226 
3227 /*
3228  * Append already encoded body from an existing message.
3229  *
3230  * This is useful when generating a DNS reply message which includes
3231  * all question records.
3232  *
3233  * Return number of appened bytes.
3234  */
3235 int mg_dns_copy_body(struct mbuf *io, struct mg_dns_message *msg);
3236 
3237 /*
3238  * Encode and append a DNS resource record to an IO buffer.
3239  *
3240  * The record metadata is taken from the `rr` parameter, while the name and data
3241  * are taken from the parameters, encoded in the appropriate format depending on
3242  * record type, and stored in the IO buffer. The encoded values might contain
3243  * offsets within the IO buffer. It's thus important that the IO buffer doesn't
3244  * get trimmed while a sequence of records are encoded while preparing a DNS
3245  *reply.
3246  *
3247  * This function doesn't update the `name` and `rdata` pointers in the `rr`
3248  *struct
3249  * because they might be invalidated as soon as the IO buffer grows again.
3250  *
3251  * Return the number of bytes appened or -1 in case of error.
3252  */
3253 int mg_dns_encode_record(struct mbuf *io, struct mg_dns_resource_record *rr,
3254  const char *name, size_t nlen, const void *rdata,
3255  size_t rlen);
3256 
3257 /* Low-level: parses a DNS response. */
3258 int mg_parse_dns(const char *buf, int len, struct mg_dns_message *msg);
3259 
3260 /*
3261  * Uncompress a DNS compressed name.
3262  *
3263  * The containing dns message is required because the compressed encoding
3264  * and reference suffixes present elsewhere in the packet.
3265  *
3266  * If name is less than `dst_len` characters long, the remainder
3267  * of `dst` is terminated with `\0' characters. Otherwise, `dst` is not
3268  *terminated.
3269  *
3270  * If `dst_len` is 0 `dst` can be NULL.
3271  * Return the uncompressed name length.
3272  */
3273 size_t mg_dns_uncompress_name(struct mg_dns_message *msg, struct mg_str *name,
3274  char *dst, int dst_len);
3275 
3276 /*
3277  * Attach built-in DNS event handler to the given listening connection.
3278  *
3279  * DNS event handler parses incoming UDP packets, treating them as DNS
3280  * requests. If incoming packet gets successfully parsed by the DNS event
3281  * handler, a user event handler will receive `MG_DNS_REQUEST` event, with
3282  * `ev_data` pointing to the parsed `struct mg_dns_message`.
3283  *
3284  * See
3285  * [captive_dns_server](https://github.com/cesanta/mongoose/tree/master/examples/captive_dns_server)
3286  * example on how to handle DNS request and send DNS reply.
3287  */
3288 void mg_set_protocol_dns(struct mg_connection *nc);
3289 
3290 #ifdef __cplusplus
3291 }
3292 #endif /* __cplusplus */
3293 #endif /* CS_MONGOOSE_SRC_DNS_H_ */
3294 /*
3295  * Copyright (c) 2014 Cesanta Software Limited
3296  * All rights reserved
3297  */
3298 
3299 /*
3300  * === DNS server
3301  *
3302  * Disabled by default; enable with `-DMG_ENABLE_DNS_SERVER`.
3303  */
3304 
3305 #ifndef CS_MONGOOSE_SRC_DNS_SERVER_H_
3306 #define CS_MONGOOSE_SRC_DNS_SERVER_H_
3307 
3308 #ifdef MG_ENABLE_DNS_SERVER
3309 
3310 
3311 #ifdef __cplusplus
3312 extern "C" {
3313 #endif /* __cplusplus */
3314 
3315 #define MG_DNS_SERVER_DEFAULT_TTL 3600
3316 
3317 struct mg_dns_reply {
3318  struct mg_dns_message *msg;
3319  struct mbuf *io;
3320  size_t start;
3321 };
3322 
3323 /*
3324  * Create a DNS reply.
3325  *
3326  * The reply will be based on an existing query message `msg`.
3327  * The query body will be appended to the output buffer.
3328  * "reply + recursion allowed" will be added to the message flags and
3329  * message's num_answers will be set to 0.
3330  *
3331  * Answer records can be appended with `mg_dns_send_reply` or by lower
3332  * level function defined in the DNS API.
3333  *
3334  * In order to send the reply use `mg_dns_send_reply`.
3335  * It's possible to use a connection's send buffer as reply buffers,
3336  * and it will work for both UDP and TCP connections.
3337  *
3338  * Example:
3339  *
3340  * ```c
3341  * reply = mg_dns_create_reply(&nc->send_mbuf, msg);
3342  * for (i = 0; i < msg->num_questions; i++) {
3343  * rr = &msg->questions[i];
3344  * if (rr->rtype == MG_DNS_A_RECORD) {
3345  * mg_dns_reply_record(&reply, rr, 3600, &dummy_ip_addr, 4);
3346  * }
3347  * }
3348  * mg_dns_send_reply(nc, &reply);
3349  * ```
3350  */
3351 struct mg_dns_reply mg_dns_create_reply(struct mbuf *io,
3352  struct mg_dns_message *msg);
3353 
3354 /*
3355  * Append a DNS reply record to the IO buffer and to the DNS message.
3356  *
3357  * The message num_answers field will be incremented. It's caller's duty
3358  * to ensure num_answers is propertly initialized.
3359  *
3360  * Returns -1 on error.
3361  */
3362 int mg_dns_reply_record(struct mg_dns_reply *reply,
3363  struct mg_dns_resource_record *question,
3364  const char *name, int rtype, int ttl, const void *rdata,
3365  size_t rdata_len);
3366 
3367 /*
3368  * Send a DNS reply through a connection.
3369  *
3370  * The DNS data is stored in an IO buffer pointed by reply structure in `r`.
3371  * This function mutates the content of that buffer in order to ensure that
3372  * the DNS header reflects size and flags of the mssage, that might have been
3373  * updated either with `mg_dns_reply_record` or by direct manipulation of
3374  * `r->message`.
3375  *
3376  * Once sent, the IO buffer will be trimmed unless the reply IO buffer
3377  * is the connection's send buffer and the connection is not in UDP mode.
3378  */
3379 void mg_dns_send_reply(struct mg_connection *nc, struct mg_dns_reply *r);
3380 
3381 #ifdef __cplusplus
3382 }
3383 #endif /* __cplusplus */
3384 
3385 #endif /* MG_ENABLE_DNS_SERVER */
3386 #endif /* CS_MONGOOSE_SRC_DNS_SERVER_H_ */
3387 /*
3388  * Copyright (c) 2014 Cesanta Software Limited
3389  * All rights reserved
3390  */
3391 
3392 /*
3393  * === Asynchronouns DNS resolver
3394  */
3395 
3396 #ifndef CS_MONGOOSE_SRC_RESOLV_H_
3397 #define CS_MONGOOSE_SRC_RESOLV_H_
3398 
3399 
3400 #ifdef __cplusplus
3401 extern "C" {
3402 #endif /* __cplusplus */
3403 
3404 enum mg_resolve_err {
3405  MG_RESOLVE_OK = 0,
3406  MG_RESOLVE_NO_ANSWERS = 1,
3407  MG_RESOLVE_EXCEEDED_RETRY_COUNT = 2,
3408  MG_RESOLVE_TIMEOUT = 3
3409 };
3410 
3411 typedef void (*mg_resolve_callback_t)(struct mg_dns_message *dns_message,
3412  void *user_data, enum mg_resolve_err);
3413 
3414 /* Options for `mg_resolve_async_opt`. */
3416  const char *nameserver_url;
3417  int max_retries; /* defaults to 2 if zero */
3418  int timeout; /* in seconds; defaults to 5 if zero */
3419  int accept_literal; /* pseudo-resolve literal ipv4 and ipv6 addrs */
3420  int only_literal; /* only resolves literal addrs; sync cb invocation */
3421  struct mg_connection **dns_conn; /* return DNS connection */
3422 };
3423 
3424 /* See `mg_resolve_async_opt()` */
3425 int mg_resolve_async(struct mg_mgr *mgr, const char *name, int query,
3426  mg_resolve_callback_t cb, void *data);
3427 
3428 /*
3429  * Resolved a DNS name asynchronously.
3430  *
3431  * Upon successful resolution, the user callback will be invoked
3432  * with the full DNS response message and a pointer to the user's
3433  * context `data`.
3434  *
3435  * In case of timeout while performing the resolution the callback
3436  * will receive a NULL `msg`.
3437  *
3438  * The DNS answers can be extracted with `mg_next_record` and
3439  * `mg_dns_parse_record_data`:
3440  *
3441  * [source,c]
3442  * ----
3443  * struct in_addr ina;
3444  * struct mg_dns_resource_record *rr = mg_next_record(msg, MG_DNS_A_RECORD,
3445  * NULL);
3446  * mg_dns_parse_record_data(msg, rr, &ina, sizeof(ina));
3447  * ----
3448  */
3449 int mg_resolve_async_opt(struct mg_mgr *mgr, const char *name, int query,
3450  mg_resolve_callback_t cb, void *data,
3451  struct mg_resolve_async_opts opts);
3452 
3453 /*
3454  * Resolve a name from `/etc/hosts`.
3455  *
3456  * Returns 0 on success, -1 on failure.
3457  */
3458 int mg_resolve_from_hosts_file(const char *host, union socket_address *usa);
3459 
3460 #ifdef __cplusplus
3461 }
3462 #endif /* __cplusplus */
3463 #endif /* CS_MONGOOSE_SRC_RESOLV_H_ */
3464 /*
3465  * Copyright (c) 2015 Cesanta Software Limited
3466  * All rights reserved
3467  * This software is dual-licensed: you can redistribute it and/or modify
3468  * it under the terms of the GNU General Public License version 2 as
3469  * published by the Free Software Foundation. For the terms of this
3470  * license, see <http://www.gnu.org/licenses/>.
3471  *
3472  * You are free to use this software under the terms of the GNU General
3473  * Public License, but WITHOUT ANY WARRANTY; without even the implied
3474  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
3475  * See the GNU General Public License for more details.
3476  *
3477  * Alternatively, you can license this software under a commercial
3478  * license, as set out in <https://www.cesanta.com/license>.
3479  */
3480 
3481 /*
3482  * === CoAP
3483  *
3484  * CoAP message format:
3485  *
3486  * ```
3487  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
3488  * |Ver| T | TKL | Code | Message ID | Token (if any, TKL bytes) ...
3489  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
3490  * | Options (if any) ... |1 1 1 1 1 1 1 1| Payload (if any) ...
3491  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
3492  * ```
3493  */
3494 
3495 #ifndef CS_MONGOOSE_SRC_COAP_H_
3496 #define CS_MONGOOSE_SRC_COAP_H_
3497 
3498 #ifdef MG_ENABLE_COAP
3499 
3500 #define MG_COAP_MSG_TYPE_FIELD 0x2
3501 #define MG_COAP_CODE_CLASS_FIELD 0x4
3502 #define MG_COAP_CODE_DETAIL_FIELD 0x8
3503 #define MG_COAP_MSG_ID_FIELD 0x10
3504 #define MG_COAP_TOKEN_FIELD 0x20
3505 #define MG_COAP_OPTIOMG_FIELD 0x40
3506 #define MG_COAP_PAYLOAD_FIELD 0x80
3507 
3508 #define MG_COAP_ERROR 0x10000
3509 #define MG_COAP_FORMAT_ERROR (MG_COAP_ERROR | 0x20000)
3510 #define MG_COAP_IGNORE (MG_COAP_ERROR | 0x40000)
3511 #define MG_COAP_NOT_ENOUGH_DATA (MG_COAP_ERROR | 0x80000)
3512 #define MG_COAP_NETWORK_ERROR (MG_COAP_ERROR | 0x100000)
3513 
3514 #define MG_COAP_MSG_CON 0
3515 #define MG_COAP_MSG_NOC 1
3516 #define MG_COAP_MSG_ACK 2
3517 #define MG_COAP_MSG_RST 3
3518 #define MG_COAP_MSG_MAX 3
3519 
3520 #define MG_COAP_CODECLASS_REQUEST 0
3521 #define MG_COAP_CODECLASS_RESP_OK 2
3522 #define MG_COAP_CODECLASS_CLIENT_ERR 4
3523 #define MG_COAP_CODECLASS_SRV_ERR 5
3524 
3525 #define MG_COAP_EVENT_BASE 300
3526 #define MG_EV_COAP_CON (MG_COAP_EVENT_BASE + MG_COAP_MSG_CON)
3527 #define MG_EV_COAP_NOC (MG_COAP_EVENT_BASE + MG_COAP_MSG_NOC)
3528 #define MG_EV_COAP_ACK (MG_COAP_EVENT_BASE + MG_COAP_MSG_ACK)
3529 #define MG_EV_COAP_RST (MG_COAP_EVENT_BASE + MG_COAP_MSG_RST)
3530 
3531 /*
3532  * CoAP options.
3533  * Use mg_coap_add_option and mg_coap_free_options
3534  * for creation and destruction.
3535  */
3536 struct mg_coap_option {
3537  struct mg_coap_option *next;
3538  uint32_t number;
3539  struct mg_str value;
3540 };
3541 
3542 /* CoAP message. See RFC 7252 for details. */
3543 struct mg_coap_message {
3544  uint32_t flags;
3545  uint8_t msg_type;
3546  uint8_t code_class;
3547  uint8_t code_detail;
3548  uint16_t msg_id;
3549  struct mg_str token;
3550  struct mg_coap_option *options;
3551  struct mg_str payload;
3552  struct mg_coap_option *optiomg_tail;
3553 };
3554 
3555 #ifdef __cplusplus
3556 extern "C" {
3557 #endif /* __cplusplus */
3558 
3559 /* Set CoAP protocol handler - trigger CoAP specific events */
3560 int mg_set_protocol_coap(struct mg_connection *nc);
3561 
3562 /*
3563  * Add new option to mg_coap_message structure.
3564  * Returns pointer to the newly created option.
3565  */
3566 struct mg_coap_option *mg_coap_add_option(struct mg_coap_message *cm,
3567  uint32_t number, char *value,
3568  size_t len);
3569 
3570 /*
3571  * Free the memory allocated for options,
3572  * if cm paramater doesn't contain any option does nothing.
3573  */
3574 void mg_coap_free_options(struct mg_coap_message *cm);
3575 
3576 /*
3577  * Compose CoAP message from `mg_coap_message`
3578  * and send it into `nc` connection.
3579  * Return 0 on success. On error, it is a bitmask:
3580  *
3581  * - `#define MG_COAP_ERROR 0x10000`
3582  * - `#define MG_COAP_FORMAT_ERROR (MG_COAP_ERROR | 0x20000)`
3583  * - `#define MG_COAP_IGNORE (MG_COAP_ERROR | 0x40000)`
3584  * - `#define MG_COAP_NOT_ENOUGH_DATA (MG_COAP_ERROR | 0x80000)`
3585  * - `#define MG_COAP_NETWORK_ERROR (MG_COAP_ERROR | 0x100000)`
3586  */
3587 uint32_t mg_coap_send_message(struct mg_connection *nc,
3588  struct mg_coap_message *cm);
3589 
3590 /*
3591  * Compose CoAP acknowledgement from `mg_coap_message`
3592  * and send it into `nc` connection.
3593  * Return value: see `mg_coap_send_message()`
3594  */
3595 uint32_t mg_coap_send_ack(struct mg_connection *nc, uint16_t msg_id);
3596 
3597 /*
3598  * Parse COAP message and fills mg_coap_message and returns cm->flags.
3599  * This is a helper function.
3600  *
3601  * NOTE: usually CoAP work over UDP, so lack of data means format error,
3602  * but in theory it is possible to use CoAP over TCP (according to RFC)
3603  *
3604  * The caller have to check results and treat COAP_NOT_ENOUGH_DATA according to
3605  * underlying protocol:
3606  *
3607  * - in case of UDP COAP_NOT_ENOUGH_DATA means COAP_FORMAT_ERROR,
3608  * - in case of TCP client can try to receive more data
3609  *
3610  * Return value: see `mg_coap_send_message()`
3611  */
3612 uint32_t mg_coap_parse(struct mbuf *io, struct mg_coap_message *cm);
3613 
3614 /*
3615  * Composes CoAP message from mg_coap_message structure.
3616  * This is a helper function.
3617  * Return value: see `mg_coap_send_message()`
3618  */
3619 uint32_t mg_coap_compose(struct mg_coap_message *cm, struct mbuf *io);
3620 
3621 #ifdef __cplusplus
3622 }
3623 #endif /* __cplusplus */
3624 
3625 #endif /* MG_ENABLE_COAP */
3626 
3627 #endif /* CS_MONGOOSE_SRC_COAP_H_ */
Definition: mongoose.h:3185
Definition: mongoose.h:3175
Definition: mongoose.h:2725
Definition: mongoose.h:2093
Definition: mongoose.h:2885
Definition: mongoose.h:2733
Definition: mongoose.h:2515
Definition: mongoose.h:974
Definition: mongoose.h:1360
Definition: mongoose.h:1390
Definition: mongoose.h:893
Definition: mongoose.h:1200
Definition: mongoose.h:2740
Definition: mongoose.h:925
Definition: mongoose.h:1189
Definition: mongoose.h:1225
Definition: mongoose.h:2062
Definition: mongoose.h:1430
Definition: mongoose.h:828
Definition: mongoose.h:1066
Definition: mongoose.h:2871
Definition: mongoose.h:1241
Definition: mongoose.h:3415
Definition: mongoose.h:2100
Definition: mongoose.h:2880