jle_cpp_tk  0.0 2015-04-03 sh1:"d699093732dd5f321606d0ff7a6b63b229f1922c"
A small, safe, selft contained, soft-realtime C++ toolkit
fossa.h
1 #ifdef __AVR__
2 #include "avrsupport.h"
3 #endif
4 /*
5  * Copyright (c) 2014 Cesanta Software Limited
6  * All rights reserved
7  * This software is dual-licensed: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation. For the terms of this
10  * license, see <http://www.gnu.org/licenses/>.
11  *
12  * You are free to use this software under the terms of the GNU General
13  * Public License, but WITHOUT ANY WARRANTY; without even the implied
14  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15  * See the GNU General Public License for more details.
16  *
17  * Alternatively, you can license this software under a commercial
18  * license, as set out in <https://www.cesanta.com/license>.
19  */
20 
21 #define NS_FOSSA_VERSION "2.0.0"
22 /*
23  * Copyright (c) 2015 Cesanta Software Limited
24  * All rights reserved
25  */
26 
27 #ifndef OSDEP_HEADER_INCLUDED
28 #define OSDEP_HEADER_INCLUDED
29 
30 #if !defined(NS_DISABLE_FILESYSTEM) && defined(AVR_NOFS)
31 #define NS_DISABLE_FILESYSTEM
32 #endif
33 
34 #undef UNICODE /* Use ANSI WinAPI functions */
35 #undef _UNICODE /* Use multibyte encoding on Windows */
36 #define _MBCS /* Use multibyte encoding on Windows */
37 #define _INTEGRAL_MAX_BITS 64 /* Enable _stati64() on Windows */
38 #define _CRT_SECURE_NO_WARNINGS /* Disable deprecation warning in VS2005+ */
39 #undef WIN32_LEAN_AND_MEAN /* Let windows.h always include winsock2.h */
40 #undef _XOPEN_SOURCE
41 #define _XOPEN_SOURCE 600 /* For flockfile() on Linux */
42 #define __STDC_FORMAT_MACROS /* <inttypes.h> wants this for C++ */
43 #define __STDC_LIMIT_MACROS /* C++ wants that for INT64_MAX */
44 #ifndef _LARGEFILE_SOURCE
45 #define _LARGEFILE_SOURCE /* Enable fseeko() and ftello() functions */
46 #endif
47 #define _FILE_OFFSET_BITS 64 /* Enable 64-bit file offsets */
48 
49 #if !(defined(AVR_LIBC) || defined(PICOTCP))
50 #include <sys/types.h>
51 #include <sys/stat.h>
52 #include <fcntl.h>
53 #include <time.h>
54 #include <signal.h>
55 #endif
56 
57 #ifndef BYTE_ORDER
58 #define LITTLE_ENDIAN 0x41424344
59 #define BIG_ENDIAN 0x44434241
60 #define PDP_ENDIAN 0x42414443
61 /* TODO(lsm): fix for big-endian machines. 'ABCD' is not portable */
62 /*#define BYTE_ORDER 'ABCD'*/
63 #define BYTE_ORDER LITTLE_ENDIAN
64 #endif
65 
66 /*
67  * MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
68  * MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
69  * MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
70  * MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008)
71  * MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005)
72  * MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio 2003)
73  * MSVC++ 7.0 _MSC_VER == 1300
74  * MSVC++ 6.0 _MSC_VER == 1200
75  * MSVC++ 5.0 _MSC_VER == 1100
76  */
77 #ifdef _MSC_VER
78 #pragma warning(disable : 4127) /* FD_SET() emits warning, disable it */
79 #pragma warning(disable : 4204) /* missing c99 support */
80 #endif
81 
82 #ifdef PICOTCP
83 #define time(x) PICO_TIME()
84 #ifndef SOMAXCONN
85 #define SOMAXCONN (16)
86 #endif
87 #ifdef _POSIX_VERSION
88 #define signal(...)
89 #endif
90 #endif
91 
92 #include <assert.h>
93 #include <ctype.h>
94 #include <errno.h>
95 #include <stdarg.h>
96 #include <stddef.h>
97 #include <stdio.h>
98 #include <stdlib.h>
99 #include <string.h>
100 
101 #ifndef va_copy
102 #ifdef __va_copy
103 #define va_copy __va_copy
104 #else
105 #define va_copy(x, y) (x) = (y)
106 #endif
107 #endif
108 
109 #ifdef _WIN32
110 #ifdef _MSC_VER
111 #pragma comment(lib, "ws2_32.lib") /* Linking with winsock library */
112 #endif
113 #include <windows.h>
114 #include <process.h>
115 #ifndef EINPROGRESS
116 #define EINPROGRESS WSAEINPROGRESS
117 #endif
118 #ifndef EWOULDBLOCK
119 #define EWOULDBLOCK WSAEWOULDBLOCK
120 #endif
121 #ifndef __func__
122 #define STRX(x) #x
123 #define STR(x) STRX(x)
124 #define __func__ __FILE__ ":" STR(__LINE__)
125 #endif
126 #define snprintf _snprintf
127 #define vsnprintf _vsnprintf
128 #define sleep(x) Sleep((x) *1000)
129 #define to64(x) _atoi64(x)
130 #define popen(x, y) _popen((x), (y))
131 #define pclose(x) _pclose(x)
132 #if defined(_MSC_VER) && _MSC_VER >= 1400
133 #define fseeko(x, y, z) _fseeki64((x), (y), (z))
134 #else
135 #define fseeko(x, y, z) fseek((x), (y), (z))
136 #endif
137 typedef int socklen_t;
138 typedef unsigned char uint8_t;
139 typedef unsigned int uint32_t;
140 typedef unsigned short uint16_t;
141 typedef unsigned __int64 uint64_t;
142 typedef __int64 int64_t;
143 typedef SOCKET sock_t;
144 typedef uint32_t in_addr_t;
145 #ifndef pid_t
146 #define pid_t HANDLE
147 #endif
148 #define INT64_FMT "I64d"
149 #ifdef __MINGW32__
150 typedef struct stat ns_stat_t;
151 #else
152 typedef struct _stati64 ns_stat_t;
153 #endif
154 #ifndef S_ISDIR
155 #define S_ISDIR(x) ((x) &_S_IFDIR)
156 #endif
157 #define DIRSEP '\\'
158 
159 /* POSIX opendir/closedir/readdir API for Windows. */
160 struct dirent {
161  char d_name[MAX_PATH];
162 };
163 
164 typedef struct DIR {
165  HANDLE handle;
166  WIN32_FIND_DATAW info;
167  struct dirent result;
168 } DIR;
169 
170 DIR *opendir(const char *name);
171 int closedir(DIR *dir);
172 struct dirent *readdir(DIR *dir);
173 
174 #else /* not _WIN32 */
175 #ifndef NO_LIBC
176 #include <dirent.h>
177 #include <fcntl.h>
178 #include <netdb.h>
179 #include <pthread.h>
180 #include <unistd.h>
181 #include <arpa/inet.h> /* For inet_pton() when NS_ENABLE_IPV6 is defined */
182 #include <netinet/in.h>
183 #include <sys/socket.h>
184 #include <sys/select.h>
185 #endif
186 #include <errno.h>
187 #include <inttypes.h>
188 #include <stdarg.h>
189 #ifndef AVR_LIBC
190 #define closesocket(x) close(x)
191 #ifndef __cdecl
192 #define __cdecl
193 #endif
194 #define INVALID_SOCKET (-1)
195 #define INT64_FMT PRId64
196 #define to64(x) strtoll(x, NULL, 10)
197 typedef int sock_t;
198 typedef struct stat ns_stat_t;
199 #define DIRSEP '/'
200 #endif
201 #ifdef __APPLE__
202 int64_t strtoll(const char *str, char **endptr, int base);
203 #endif
204 #endif /* _WIN32 */
205 
206 #ifdef NS_ENABLE_DEBUG
207 #define DBG(x) \
208  do { \
209  printf("%-20s ", __func__); \
210  printf x; \
211  putchar('\n'); \
212  fflush(stdout); \
213  } while (0)
214 #else
215 #define DBG(x)
216 #endif
217 
218 #ifndef ARRAY_SIZE
219 #define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
220 #endif
221 
222 #if !defined(NO_LIBC) && !defined(NS_DISABLE_FILESYSTEM)
223 typedef FILE *c_file_t;
224 /*
225  * Cannot use fopen & Co directly and
226  * override them with -D because
227  * these overrides conflicts with
228  * functions in stdio.h
229  */
230 #define c_fopen fopen
231 #define c_fread fread
232 #define c_fwrite fwrite
233 #define c_fclose fclose
234 #define c_rename rename
235 #define c_remove remove
236 #define c_fseek fseek
237 #define c_ftell ftell
238 #define c_rewind rewind
239 #define c_ferror ferror
240 #define INVALID_FILE NULL
241 #else
242 /*
243  * TODO(alashkin): move to .h file (v7.h?)
244  */
245 c_file_t c_fopen(const char *filename, const char *mode);
246 size_t c_fread(void *ptr, size_t size, size_t count, c_file_t fd);
247 size_t c_fwrite(const void *ptr, size_t size, size_t count, c_file_t fd);
248 int c_fclose(c_file_t fd);
249 int c_rename(const char *oldname, const char *newname);
250 int c_remove(const char *filename);
251 void c_rewind(c_file_t fd);
252 int c_ferror(c_file_t fd);
253 #endif
254 
255 #endif /* OSDEP_HEADER_INCLUDED */
256 /*
257  * Copyright (c) 2015 Cesanta Software Limited
258  * All rights reserved
259  */
260 
261 /*
262  * === Memory Buffers
263  *
264  * Mbufs are mutable/growing memory buffers, like C++ strings.
265  * Mbuf can append data to the end of a buffer, or insert data into arbitrary
266  * position in the middle of a buffer. The buffer grows automatically when
267  * needed.
268  */
269 
270 #ifndef MBUF_H_INCLUDED
271 #define MBUF_H_INCLUDED
272 
273 #if defined(__cplusplus)
274 extern "C" {
275 #endif
276 
277 #include <stdlib.h>
278 
279 #ifndef MBUF_SIZE_MULTIPLIER
280 #define MBUF_SIZE_MULTIPLIER 1.5
281 #endif
282 
283 /* Memory buffer descriptor */
284 struct mbuf {
285  char *buf; /* Buffer pointer */
286  size_t len; /* Data length. Data is located between offset 0 and len. */
287  size_t size; /* Buffer size allocated by realloc(1). Must be >= len */
288 };
289 
290 /*
291  * Initialize an Mbuf.
292  * `initial_capacity` specifies the initial capacity of the mbuf.
293  */
294 void mbuf_init(struct mbuf *, size_t initial_capacity);
295 
296 /* Free the space allocated for the mbuffer and resets the mbuf structure. */
297 void mbuf_free(struct mbuf *);
298 
299 /*
300  * Appends data to the Mbuf.
301  *
302  * Return the number of bytes appended, or 0 if out of memory.
303  */
304 size_t mbuf_append(struct mbuf *, const void *data, size_t data_size);
305 
306 /*
307  * Insert data at a specified offset in the Mbuf.
308  *
309  * Existing data will be shifted forwards and the buffer will
310  * be grown if necessary.
311  * Return the number of bytes inserted.
312  */
313 size_t mbuf_insert(struct mbuf *, size_t, const void *, size_t);
314 
315 /* Remove `data_size` bytes from the beginning of the buffer. */
316 void mbuf_remove(struct mbuf *, size_t data_size);
317 
318 /*
319  * Resize an Mbuf.
320  *
321  * If `new_size` is smaller than buffer's `len`, the
322  * resize is not performed.
323  */
324 void mbuf_resize(struct mbuf *, size_t new_size);
325 
326 /* Shrink an Mbuf by resizing its `size` to `len`. */
327 void mbuf_trim(struct mbuf *);
328 
329 #if defined(__cplusplus)
330 }
331 #endif /* __cplusplus */
332 
333 #endif /* MBUF_H_INCLUDED */
334 /*
335  * Copyright (c) 2014 Cesanta Software Limited
336  * All rights reserved
337  */
338 
339 #if !defined(NS_SHA1_HEADER_INCLUDED) && !defined(DISABLE_SHA1)
340 #define NS_SHA1_HEADER_INCLUDED
341 
342 
343 #ifdef __cplusplus
344 extern "C" {
345 #endif /* __cplusplus */
346 
347 typedef struct {
348  uint32_t state[5];
349  uint32_t count[2];
350  unsigned char buffer[64];
351 } SHA1_CTX;
352 
353 void SHA1Init(SHA1_CTX *);
354 void SHA1Update(SHA1_CTX *, const unsigned char *data, uint32_t len);
355 void SHA1Final(unsigned char digest[20], SHA1_CTX *);
356 void hmac_sha1(const unsigned char *key, size_t key_len,
357  const unsigned char *text, size_t text_len,
358  unsigned char out[20]);
359 #ifdef __cplusplus
360 }
361 #endif /* __cplusplus */
362 #endif /* NS_SHA1_HEADER_INCLUDED */
363 /*
364  * Copyright (c) 2014 Cesanta Software Limited
365  * All rights reserved
366  */
367 
368 #ifndef MD5_HEADER_DEFINED
369 #define MD5_HEADER_DEFINED
370 
371 
372 #ifdef __cplusplus
373 extern "C" {
374 #endif /* __cplusplus */
375 
376 typedef struct MD5Context {
377  uint32_t buf[4];
378  uint32_t bits[2];
379  unsigned char in[64];
380 } MD5_CTX;
381 
382 void MD5_Init(MD5_CTX *c);
383 void MD5_Update(MD5_CTX *c, const unsigned char *data, size_t len);
384 void MD5_Final(unsigned char *md, MD5_CTX *c);
385 
386 #ifdef __cplusplus
387 }
388 #endif /* __cplusplus */
389 
390 #endif
391 /*
392  * Copyright (c) 2014 Cesanta Software Limited
393  * All rights reserved
394  */
395 
396 #if !defined(BASE64_H_INCLUDED) && !defined(DISABLE_BASE64)
397 #define BASE64_H_INCLUDED
398 
399 #ifdef __cplusplus
400 extern "C" {
401 #endif
402 
403 void cs_base64_encode(const unsigned char *src, int src_len, char *dst);
404 int cs_base64_decode(const unsigned char *s, int len, char *dst);
405 
406 #ifdef __cplusplus
407 }
408 #endif
409 #endif
410 /*
411  * Copyright (c) 2015 Cesanta Software Limited
412  * All rights reserved
413  */
414 
415 #ifndef STR_UTIL_H
416 #define STR_UTIL_H
417 
418 #include <stdarg.h>
419 #include <stdlib.h>
420 
421 #ifdef __cplusplus
422 extern "C" {
423 #endif
424 
425 int c_snprintf(char *buf, size_t buf_size, const char *format, ...);
426 int c_vsnprintf(char *buf, size_t buf_size, const char *format, va_list ap);
427 
428 #ifdef __cplusplus
429 }
430 #endif
431 #endif
432 /*
433  * Copyright (c) 2004-2013 Sergey Lyubka <valenok@gmail.com>
434  * Copyright (c) 2013 Cesanta Software Limited
435  * All rights reserved
436  *
437  * This library is dual-licensed: you can redistribute it and/or modify
438  * it under the terms of the GNU General Public License version 2 as
439  * published by the Free Software Foundation. For the terms of this
440  * license, see <http: *www.gnu.org/licenses/>.
441  *
442  * You are free to use this library under the terms of the GNU General
443  * Public License, but WITHOUT ANY WARRANTY; without even the implied
444  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
445  * See the GNU General Public License for more details.
446  *
447  * Alternatively, you can license this library under a commercial
448  * license, as set out in <https://www.cesanta.com/license>.
449  */
450 
451 #ifndef FROZEN_HEADER_INCLUDED
452 #define FROZEN_HEADER_INCLUDED
453 
454 #ifdef __cplusplus
455 extern "C" {
456 #endif /* __cplusplus */
457 
458 #include <stdarg.h>
459 
460 enum json_type {
461  JSON_TYPE_EOF = 0, /* End of parsed tokens marker */
462  JSON_TYPE_STRING = 1,
463  JSON_TYPE_NUMBER = 2,
464  JSON_TYPE_OBJECT = 3,
465  JSON_TYPE_TRUE = 4,
466  JSON_TYPE_FALSE = 5,
467  JSON_TYPE_NULL = 6,
468  JSON_TYPE_ARRAY = 7
469 };
470 
471 struct json_token {
472  const char *ptr; /* Points to the beginning of the token */
473  int len; /* Token length */
474  int num_desc; /* For arrays and object, total number of descendants */
475  enum json_type type; /* Type of the token, possible values above */
476 };
477 
478 /* Error codes */
479 #define JSON_STRING_INVALID -1
480 #define JSON_STRING_INCOMPLETE -2
481 #define JSON_TOKEN_ARRAY_TOO_SMALL -3
482 
483 int parse_json(const char *json_string, int json_string_length,
484  struct json_token *tokens_array, int size_of_tokens_array);
485 struct json_token *parse_json2(const char *json_string, int string_length);
486 struct json_token *find_json_token(struct json_token *toks, const char *path);
487 
488 int json_emit_long(char *buf, int buf_len, long value);
489 int json_emit_double(char *buf, int buf_len, double value);
490 int json_emit_quoted_str(char *buf, int buf_len, const char *str, int len);
491 int json_emit_unquoted_str(char *buf, int buf_len, const char *str, int len);
492 int json_emit(char *buf, int buf_len, const char *fmt, ...);
493 int json_emit_va(char *buf, int buf_len, const char *fmt, va_list);
494 
495 #ifdef __cplusplus
496 }
497 #endif /* __cplusplus */
498 
499 #endif /* FROZEN_HEADER_INCLUDED */
500 /*
501  * Copyright (c) 2014 Cesanta Software Limited
502  * All rights reserved
503  * This software is dual-licensed: you can redistribute it and/or modify
504  * it under the terms of the GNU General Public License version 2 as
505  * published by the Free Software Foundation. For the terms of this
506  * license, see <http://www.gnu.org/licenses/>.
507  *
508  * You are free to use this software under the terms of the GNU General
509  * Public License, but WITHOUT ANY WARRANTY; without even the implied
510  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
511  * See the GNU General Public License for more details.
512  *
513  * Alternatively, you can license this software under a commercial
514  * license, as set out in <https://www.cesanta.com/license>.
515  */
516 
517 /*
518  * === Core: TCP/UDP/SSL
519  *
520  * NOTE: Fossa manager is single threaded. It does not protect
521  * its data structures by mutexes, therefore all functions that are dealing
522  * with particular event manager should be called from the same thread,
523  * with exception of `mg_broadcast()` function. It is fine to have different
524  * event managers handled by different threads.
525  */
526 
527 #ifndef NS_NET_HEADER_INCLUDED
528 #define NS_NET_HEADER_INCLUDED
529 
530 
531 #ifdef NS_ENABLE_SSL
532 #ifdef __APPLE__
533 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
534 #endif
535 #include <openssl/ssl.h>
536 #else
537 typedef void *SSL;
538 typedef void *SSL_CTX;
539 #endif
540 
541 #ifdef NS_USE_READ_WRITE
542 #define NS_RECV_FUNC(s, b, l, f) read(s, b, l)
543 #define NS_SEND_FUNC(s, b, l, f) write(s, b, l)
544 #else
545 #define NS_RECV_FUNC(s, b, l, f) recv(s, b, l, f)
546 #define NS_SEND_FUNC(s, b, l, f) send(s, b, l, f)
547 #endif
548 
549 #ifdef __cplusplus
550 extern "C" {
551 #endif /* __cplusplus */
552 
554  struct sockaddr sa;
555  struct sockaddr_in sin;
556 #ifdef NS_ENABLE_IPV6
557  struct sockaddr_in6 sin6;
558 #else
559  struct sockaddr sin6;
560 #endif
561 };
562 
563 /* Describes chunk of memory */
564 struct ns_str {
565  const char *p; /* Memory chunk pointer */
566  size_t len; /* Memory chunk length */
567 };
568 
569 #define NS_STR(str_literal) \
570  { str_literal, sizeof(str_literal) - 1 }
571 
572 /*
573  * Callback function (event handler) prototype, must be defined by user.
574  * Fossa calls event handler, passing events defined below.
575  */
576 struct ns_connection;
577 typedef void (*ns_event_handler_t)(struct ns_connection *, int ev, void *);
578 
579 /* Events. Meaning of event parameter (evp) is given in the comment. */
580 #define NS_POLL 0 /* Sent to each connection on each ns_mgr_poll() call */
581 #define NS_ACCEPT 1 /* New connection accepted. union socket_address *addr */
582 #define NS_CONNECT 2 /* connect() succeeded or failed. int *success_status */
583 #define NS_RECV 3 /* Data has benn received. int *num_bytes */
584 #define NS_SEND 4 /* Data has been written to a socket. int *num_bytes */
585 #define NS_CLOSE 5 /* Connection is closed. NULL */
586 
587 /*
588  * Fossa event manager.
589  */
590 struct ns_mgr {
591  struct ns_connection *active_connections;
592  const char *hexdump_file; /* Debug hexdump file path */
593  sock_t ctl[2]; /* Socketpair for mg_wakeup() */
594  void *user_data; /* User data */
595  void *mgr_data; /* Implementation-specific event manager's data. */
596 };
597 
598 /*
599  * Fossa connection.
600  */
602  struct ns_connection *next, *prev; /* ns_mgr::active_connections linkage */
603  struct ns_connection *listener; /* Set only for accept()-ed connections */
604  struct ns_mgr *mgr; /* Pointer to containing manager */
605 
606  sock_t sock; /* Socket to the remote peer */
607  union socket_address sa; /* Remote peer address */
608  size_t recv_mbuf_limit; /* Max size of recv buffer */
609  struct mbuf recv_mbuf; /* Received data */
610  struct mbuf send_mbuf; /* Data scheduled for sending */
611  SSL *ssl;
612  SSL_CTX *ssl_ctx;
613  time_t last_io_time; /* Timestamp of the last socket IO */
614  ns_event_handler_t proto_handler; /* Protocol-specific event handler */
615  void *proto_data; /* Protocol-specific data */
616  ns_event_handler_t handler; /* Event handler function */
617  void *user_data; /* User-specific data */
618  void *mgr_data; /* Implementation-specific event manager's data. */
619 
620  unsigned long flags;
621 /* Flags set by Fossa */
622 #define NSF_LISTENING (1 << 0) /* This connection is listening */
623 #define NSF_UDP (1 << 1) /* This connection is UDP */
624 #define NSF_RESOLVING (1 << 2) /* Waiting for async resolver */
625 #define NSF_CONNECTING (1 << 3) /* connect() call in progress */
626 #define NSF_SSL_HANDSHAKE_DONE (1 << 4) /* SSL specific */
627 #define NSF_WANT_READ (1 << 5) /* SSL specific */
628 #define NSF_WANT_WRITE (1 << 6) /* SSL specific */
629 #define NSF_IS_WEBSOCKET (1 << 7) /* Websocket specific */
630 
631 /* Flags that are settable by user */
632 #define NSF_SEND_AND_CLOSE (1 << 10) /* Push remaining data and close */
633 #define NSF_DONT_SEND (1 << 11) /* Do not send data to peer */
634 #define NSF_CLOSE_IMMEDIATELY (1 << 12) /* Disconnect */
635 #define NSF_WEBSOCKET_NO_DEFRAG (1 << 13) /* Websocket specific */
636 #define NSF_DELETE_CHUNK (1 << 14) /* HTTP specific */
637 
638 #define NSF_USER_1 (1 << 20) /* Flags left for application */
639 #define NSF_USER_2 (1 << 21)
640 #define NSF_USER_3 (1 << 22)
641 #define NSF_USER_4 (1 << 23)
642 #define NSF_USER_5 (1 << 24)
643 #define NSF_USER_6 (1 << 25)
644 };
645 
646 /*
647  * Initialize Fossa manager. Side effect: ignores SIGPIPE signal.
648  * `mgr->user_data` field will be initialized with `user_data` parameter.
649  * That is an arbitrary pointer, where user code can associate some data
650  * with the particular Fossa manager. For example, a C++ wrapper class
651  * could be written, in which case `user_data` can hold a pointer to the
652  * class instance.
653  */
654 void ns_mgr_init(struct ns_mgr *mgr, void *user_data);
655 
656 /*
657  * De-initializes Fossa manager.
658  *
659  * Close and deallocate all active connections.
660  */
661 void ns_mgr_free(struct ns_mgr *);
662 
663 /*
664  * This function performs the actual IO, and must be called in a loop
665  * (an event loop). Returns the current timestamp.
666  * `milli` is the maximum number of milliseconds to sleep.
667  * `ns_mgr_poll()` checks all connection for IO readiness. If at least one
668  * of the connections is IO-ready, `ns_mgr_poll()` triggers respective
669  * event handlers and returns.
670  */
671 time_t ns_mgr_poll(struct ns_mgr *, int milli);
672 
673 /*
674  * Pass a message of a given length to all connections.
675  *
676  * Must be called from a thread that does NOT call `ns_mgr_poll()`.
677  * Note that `ns_broadcast()` is the only function
678  * that can be, and must be, called from a different (non-IO) thread.
679  *
680  * `func` callback function will be called by the IO thread for each
681  * connection. When called, event would be `NS_POLL`, and message will
682  * be passed as `ev_data` pointer. Maximum message size is capped
683  * by `NS_CTL_MSG_MESSAGE_SIZE` which is set to 8192 bytes.
684  */
685 void ns_broadcast(struct ns_mgr *, ns_event_handler_t func, void *, size_t);
686 
687 /*
688  * Iterate over all active connections.
689  *
690  * Returns next connection from the list
691  * of active connections, or `NULL` if there is no more connections. Below
692  * is the iteration idiom:
693  *
694  * [source,c]
695  * ----
696  * for (c = ns_next(srv, NULL); c != NULL; c = ns_next(srv, c)) {
697  * // Do something with connection `c`
698  * }
699  * ----
700  */
701 struct ns_connection *ns_next(struct ns_mgr *, struct ns_connection *);
702 
703 /*
704  * Optional parameters to ns_add_sock_opt()
705  * `flags` is an initial `struct ns_connection::flags` bitmask to set,
706  * see `NSF_*` flags definitions.
707  */
709  void *user_data; /* Initial value for connection's user_data */
710  unsigned int flags; /* Initial connection flags */
711  const char **error_string; /* Placeholder for the error string */
712 };
713 
714 /*
715  * Create a connection, associate it with the given socket and event handler,
716  * and add it to the manager.
717  *
718  * For more options see the `ns_add_sock_opt` variant.
719  */
720 struct ns_connection *ns_add_sock(struct ns_mgr *, sock_t, ns_event_handler_t);
721 
722 /*
723  * Create a connection, associate it with the given socket and event handler,
724  * and add to the manager.
725  *
726  * See the `ns_add_sock_opts` structure for a description of the options.
727  */
728 struct ns_connection *ns_add_sock_opt(struct ns_mgr *, sock_t,
729  ns_event_handler_t,
730  struct ns_add_sock_opts);
731 
732 /*
733  * Optional parameters to ns_bind_opt()
734  * `flags` is an initial `struct ns_connection::flags` bitmask to set,
735  * see `NSF_*` flags definitions.
736  */
737 struct ns_bind_opts {
738  void *user_data; /* Initial value for connection's user_data */
739  unsigned int flags; /* Extra connection flags */
740  const char **error_string; /* Placeholder for the error string */
741 };
742 
743 /*
744  * Create listening connection.
745  *
746  * See `ns_bind_opt` for full documentation.
747  */
748 struct ns_connection *ns_bind(struct ns_mgr *, const char *,
749  ns_event_handler_t);
750 /*
751  * Create listening connection.
752  *
753  * `address` parameter tells which address to bind to. It's format is the same
754  * as for the `ns_connect()` call, where `HOST` part is optional. `address`
755  * can be just a port number, e.g. `:8000`. To bind to a specific interface,
756  * an IP address can be specified, e.g. `1.2.3.4:8000`. By default, a TCP
757  * connection is created. To create UDP connection, prepend `udp://` prefix,
758  * e.g. `udp://:8000`. To summarize, `address` paramer has following format:
759  * `[PROTO://][IP_ADDRESS]:PORT`, where `PROTO` could be `tcp` or `udp`.
760  *
761  * See the `ns_bind_opts` structure for a description of the optional
762  * parameters.
763  *
764  * Return a new listening connection, or `NULL` on error.
765  * NOTE: Connection remains owned by the manager, do not free().
766  */
767 struct ns_connection *ns_bind_opt(struct ns_mgr *, const char *,
768  ns_event_handler_t, struct ns_bind_opts);
769 
770 /* Optional parameters to ns_connect_opt() */
772  void *user_data; /* Initial value for connection's user_data */
773  unsigned int flags; /* Extra connection flags */
774  const char **error_string; /* Placeholder for the error string */
775 };
776 
777 /*
778  * Connect to a remote host.
779  *
780  * See `ns_connect_opt()` for full documentation.
781  */
782 struct ns_connection *ns_connect(struct ns_mgr *, const char *,
783  ns_event_handler_t);
784 
785 /*
786  * Connect to a remote host.
787  *
788  * `address` format is `[PROTO://]HOST:PORT`. `PROTO` could be `tcp` or `udp`.
789  * `HOST` could be an IP address,
790  * IPv6 address (if Fossa is compiled with `-DNS_ENABLE_IPV6`), or a host name.
791  * If `HOST` is a name, Fossa will resolve it asynchronously. Examples of
792  * valid addresses: `google.com:80`, `udp://1.2.3.4:53`, `10.0.0.1:443`,
793  * `[::1]:80`
794  *
795  * See the `ns_connect_opts` structure for a description of the optional
796  * parameters.
797  *
798  * Returns a new outbound connection, or `NULL` on error.
799  *
800  * NOTE: Connection remains owned by the manager, do not free().
801  *
802  * NOTE: To enable IPv6 addresses, `-DNS_ENABLE_IPV6` should be specified
803  * in the compilation flags.
804  *
805  * NOTE: New connection will receive `NS_CONNECT` as it's first event
806  * which will report connect success status.
807  * If asynchronous resolution fail, or `connect()` syscall fail for whatever
808  * reason (e.g. with `ECONNREFUSED` or `ENETUNREACH`), then `NS_CONNECT`
809  * event report failure. Code example below:
810  *
811  * [source,c]
812  * ----
813  * static void ev_handler(struct ns_connection *nc, int ev, void *ev_data) {
814  * int connect_status;
815  *
816  * switch (ev) {
817  * case NS_CONNECT:
818  * connect_status = * (int *) ev_data;
819  * if (connect_status == 0) {
820  * // Success
821  * } else {
822  * // Error
823  * printf("connect() error: %s\n", strerror(connect_status));
824  * }
825  * break;
826  * ...
827  * }
828  * }
829  *
830  * ...
831  * ns_connect(mgr, "my_site.com:80", ev_handler);
832  * ----
833  */
834 struct ns_connection *ns_connect_opt(struct ns_mgr *, const char *,
835  ns_event_handler_t,
836  struct ns_connect_opts);
837 
838 /*
839  * Enable SSL for a given connection.
840  * `cert` is a server certificate file name for a listening connection,
841  * or a client certificate file name for an outgoing connection.
842  * Certificate files must be in PEM format. Server certificate file
843  * must contain a certificate, concatenated with a private key, optionally
844  * concatenated with parameters.
845  * `ca_cert` is a CA certificate, or NULL if peer verification is not
846  * required.
847  * Return: NULL on success, or error message on error.
848  */
849 const char *ns_set_ssl(struct ns_connection *nc, const char *cert,
850  const char *ca_cert);
851 
852 /*
853  * Send data to the connection.
854  *
855  * Return number of written bytes. Note that sending
856  * functions do not actually push data to the socket. They just append data
857  * to the output buffer. The exception is UDP connections. For UDP, data is
858  * sent immediately, and returned value indicates an actual number of bytes
859  * sent to the socket.
860  */
861 int ns_send(struct ns_connection *, const void *buf, int len);
862 
863 /*
864  * Send `printf`-style formatted data to the connection.
865  *
866  * See `ns_send` for more details on send semantics.
867  */
868 int ns_printf(struct ns_connection *, const char *fmt, ...);
869 
870 /* Same as `ns_printf()`, but takes `va_list ap` as an argument. */
871 int ns_vprintf(struct ns_connection *, const char *fmt, va_list ap);
872 
873 /*
874  * Create a socket pair.
875  * `sock_type` can be either `SOCK_STREAM` or `SOCK_DGRAM`.
876  * Return 0 on failure, 1 on success.
877  */
878 int ns_socketpair(sock_t[2], int sock_type);
879 
880 /*
881  * Convert domain name into IP address.
882  *
883  * This is a utility function. If compilation flags have
884  * `-DNS_ENABLE_GETADDRINFO`, then `getaddrinfo()` call is used for name
885  * resolution. Otherwise, `gethostbyname()` is used.
886  *
887  * CAUTION: this function can block.
888  * Return 1 on success, 0 on failure.
889  */
890 int ns_resolve(const char *domain_name, char *ip_addr_buf, size_t buf_len);
891 
892 /*
893  * Verify given IP address against the ACL.
894  *
895  * `remote_ip` - an IPv4 address to check, in host byte order
896  * `acl` - a comma separated list of IP subnets: `x.x.x.x/x` or `x.x.x.x`.
897  * Each subnet is
898  * prepended by either a - or a + sign. A plus sign means allow, where a
899  * minus sign means deny. If a subnet mask is omitted, such as `-1.2.3.4`,
900  * this means to deny only that single IP address.
901  * Subnet masks may vary from 0 to 32, inclusive. The default setting
902  * is to allow all accesses. On each request the full list is traversed,
903  * and the last match wins. Example:
904  *
905  * `-0.0.0.0/0,+192.168/16` - deny all acccesses, only allow 192.168/16 subnet
906  *
907  * To learn more about subnet masks, see the
908  * link:https://en.wikipedia.org/wiki/Subnetwork[Wikipedia page on Subnetwork]
909  *
910  * Return -1 if ACL is malformed, 0 if address is disallowed, 1 if allowed.
911  */
912 int ns_check_ip_acl(const char *acl, uint32_t remote_ip);
913 
914 #ifdef __cplusplus
915 }
916 #endif /* __cplusplus */
917 
918 #endif /* NS_NET_HEADER_INCLUDED */
919 /*
920  * Copyright (c) 2014 Cesanta Software Limited
921  * All rights reserved
922  */
923 
924 /*
925  * === Utilities
926  */
927 
928 #ifndef NS_UTIL_HEADER_DEFINED
929 #define NS_UTIL_HEADER_DEFINED
930 
931 #include <stdio.h>
932 
933 
934 #ifdef __cplusplus
935 extern "C" {
936 #endif /* __cplusplus */
937 
938 #ifndef MAX_PATH_SIZE
939 #define MAX_PATH_SIZE 500
940 #endif
941 
942 /*
943  * Fetch substring from input string `s`, `end` into `v`.
944  * Skips initial delimiter characters. Records first non-delimiter character
945  * as the beginning of substring `v`. Then scans the rest of the string
946  * until a delimiter character or end-of-string is found.
947  * `delimiters` is a 0-terminated string containing delimiter characters.
948  * Either one of `delimiters` or `end_string` terminates the search.
949  * Return an `s` pointer, advanced forward where parsing stopped.
950  */
951 const char *ns_skip(const char *s, const char *end_string,
952  const char *delimiters, struct ns_str *v);
953 
954 /*
955  * Cross-platform version of `strncasecmp()`.
956  */
957 int ns_ncasecmp(const char *s1, const char *s2, size_t len);
958 
959 /*
960  * Cross-platform version of `strcasecmp()`.
961  */
962 int ns_casecmp(const char *s1, const char *s2);
963 
964 /*
965  * Cross-platform version of `strcmp()` where where first string is
966  * specified by `struct ns_str`.
967  */
968 int ns_vcmp(const struct ns_str *str2, const char *str1);
969 
970 /*
971  * Cross-platform version of `strncasecmp()` where first string is
972  * specified by `struct ns_str`.
973  */
974 int ns_vcasecmp(const struct ns_str *str2, const char *str1);
975 
976 /*
977  * Decode base64-encoded string `s`, `len` into the destination `dst`.
978  * Destination has to have enough space to hold decoded buffer.
979  * Decoding stops either when all string has been decoded, or invalid
980  * character appeared.
981  * Destination is '\0'-terminated.
982  * Return number of decoded characters. On success, that should be equal to
983  * `len`. On error (invalid character) the return value is smaller then `len`.
984  */
985 int ns_base64_decode(const unsigned char *s, int len, char *dst);
986 
987 /*
988  * Base64-encode chunk of memory `src`, `src_len` into the destination `dst`.
989  * Destination has to have enough space to hold encoded buffer.
990  * Destination is '\0'-terminated.
991  */
992 void ns_base64_encode(const unsigned char *src, int src_len, char *dst);
993 
994 #ifndef NS_DISABLE_FILESYSTEM
995 /*
996  * Perform a 64-bit `stat()` call against given file.
997  *
998  * `path` should be UTF8 encoded.
999  *
1000  * Return value is the same as for `stat()` syscall.
1001  */
1002 int ns_stat(const char *path, ns_stat_t *st);
1003 
1004 /*
1005  * Open the given file and return a file stream.
1006  *
1007  * `path` and `mode` should be UTF8 encoded.
1008  *
1009  * Return value is the same as for the `fopen()` call.
1010  */
1011 FILE *ns_fopen(const char *path, const char *mode);
1012 
1013 /*
1014  * Open the given file and return a file stream.
1015  *
1016  * `path` should be UTF8 encoded.
1017  *
1018  * Return value is the same as for the `open()` syscall.
1019  */
1020 int ns_open(const char *path, int flag, int mode);
1021 #endif /* NS_DISABLE_FILESYSTEM */
1022 
1023 #ifdef NS_ENABLE_THREADS
1024 /*
1025  * Start a new detached thread.
1026  * Arguments and semantic is the same as pthead's `pthread_create()`.
1027  * `thread_func` is a thread function, `thread_func_param` is a parameter
1028  * that is passed to the thread function.
1029  */
1030 void *ns_start_thread(void *(*thread_func)(void *), void *thread_func_param);
1031 #endif
1032 
1033 void ns_set_close_on_exec(sock_t);
1034 
1035 #define NS_SOCK_STRINGIFY_IP 1
1036 #define NS_SOCK_STRINGIFY_PORT 2
1037 #define NS_SOCK_STRINGIFY_REMOTE 4
1038 /*
1039  * Convert socket's local or remote address into string.
1040  *
1041  * The `flags` parameter is a bit mask that controls the behavior,
1042  * see `NS_SOCK_STRINGIFY_*` definitions.
1043  *
1044  * - NS_SOCK_STRINGIFY_IP - print IP address
1045  * - NS_SOCK_STRINGIFY_PORT - print port number
1046  * - NS_SOCK_STRINGIFY_REMOTE - print remote peer's IP/port, not local address
1047  *
1048  * If both port number and IP address are printed, they are separated by `:`.
1049  * If compiled with `-DNS_ENABLE_IPV6`, IPv6 addresses are supported.
1050  */
1051 void ns_sock_to_str(sock_t sock, char *buf, size_t len, int flags);
1052 
1053 /*
1054  * Convert socket's address into string.
1055  *
1056  * `flags` is NS_SOCK_STRINGIFY_IP and/or NS_SOCK_STRINGIFY_PORT.
1057  */
1058 void ns_sock_addr_to_str(const union socket_address *sa, char *buf, size_t len,
1059  int flags);
1060 
1061 /*
1062  * Generates human-readable hexdump of memory chunk.
1063  *
1064  * Takes a memory buffer `buf` of length `len` and creates a hex dump of that
1065  * buffer in `dst`. Generated output is a-la hexdump(1).
1066  * Return length of generated string, excluding terminating `\0`. If returned
1067  * length is bigger than `dst_len`, overflow bytes are discarded.
1068  */
1069 int ns_hexdump(const void *buf, int len, char *dst, int dst_len);
1070 
1071 /*
1072  * Generates human-readable hexdump of the data sent or received by connection.
1073  * `path` is a file name where hexdump should be written. `num_bytes` is
1074  * a number of bytes sent/received. `ev` is one of the `NS_*` events sent to
1075  * an event handler. This function is supposed to be called from the
1076  * event handler.
1077  */
1078 void ns_hexdump_connection(struct ns_connection *nc, const char *path,
1079  int num_bytes, int ev);
1080 /*
1081  * Print message to buffer. If buffer is large enough to hold the message,
1082  * return buffer. If buffer is to small, allocate large enough buffer on heap,
1083  * and return allocated buffer.
1084  * This is a supposed use case:
1085  *
1086  * char buf[5], *p = buf;
1087  * p = ns_avprintf(&p, sizeof(buf), "%s", "hi there");
1088  * use_p_somehow(p);
1089  * if (p != buf) {
1090  * free(p);
1091  * }
1092  *
1093  * The purpose of this is to avoid malloc-ing if generated strings are small.
1094  */
1095 int ns_avprintf(char **buf, size_t size, const char *fmt, va_list ap);
1096 
1097 /*
1098  * Return true if target platform is big endian.
1099  */
1100 int ns_is_big_endian(void);
1101 
1102 /*
1103  * A helper function for traversing a comma separated list of values.
1104  * It returns a list pointer shifted to the next value, or NULL if the end
1105  * of the list found.
1106  * Value is stored in val vector. If value has form "x=y", then eq_val
1107  * vector is initialized to point to the "y" part, and val vector length
1108  * is adjusted to point only to "x".
1109  * If list is just a comma separated list of entries, like "aa,bb,cc" then
1110  * `eq_val` will contain zero-length string.
1111  *
1112  * The purpose of this function is to parse comma separated string without
1113  * any copying/memory allocation.
1114  */
1115 const char *ns_next_comma_list_entry(const char *list, struct ns_str *val,
1116  struct ns_str *eq_val);
1117 
1118 /*
1119  * Match 0-terminated string against a glob pattern.
1120  * Match is case-insensitive. Return number of bytes matched, or -1 if no match.
1121  */
1122 int ns_match_prefix(const char *pattern, int pattern_len, const char *str);
1123 
1124 #ifdef __cplusplus
1125 }
1126 #endif /* __cplusplus */
1127 #endif /* NS_UTIL_HEADER_DEFINED */
1128 /*
1129  * Copyright (c) 2014 Cesanta Software Limited
1130  * All rights reserved
1131  */
1132 
1133 /*
1134  * === HTTP + Websocket
1135  */
1136 
1137 #ifndef NS_HTTP_HEADER_DEFINED
1138 #define NS_HTTP_HEADER_DEFINED
1139 
1140 
1141 #ifdef __cplusplus
1142 extern "C" {
1143 #endif /* __cplusplus */
1144 
1145 #ifndef NS_MAX_HTTP_HEADERS
1146 #define NS_MAX_HTTP_HEADERS 40
1147 #endif
1148 
1149 #ifndef NS_MAX_HTTP_REQUEST_SIZE
1150 #define NS_MAX_HTTP_REQUEST_SIZE 8192
1151 #endif
1152 
1153 #ifndef NS_MAX_PATH
1154 #define NS_MAX_PATH 1024
1155 #endif
1156 
1157 #ifndef NS_MAX_HTTP_SEND_IOBUF
1158 #define NS_MAX_HTTP_SEND_IOBUF 4096
1159 #endif
1160 
1161 #ifndef NS_WEBSOCKET_PING_INTERVAL_SECONDS
1162 #define NS_WEBSOCKET_PING_INTERVAL_SECONDS 5
1163 #endif
1164 
1165 #ifndef NS_CGI_ENVIRONMENT_SIZE
1166 #define NS_CGI_ENVIRONMENT_SIZE 8192
1167 #endif
1168 
1169 #ifndef NS_MAX_CGI_ENVIR_VARS
1170 #define NS_MAX_CGI_ENVIR_VARS 64
1171 #endif
1172 
1173 #ifndef NS_ENV_EXPORT_TO_CGI
1174 #define NS_ENV_EXPORT_TO_CGI "FOSSA_CGI"
1175 #endif
1176 
1177 /* HTTP message */
1179  struct ns_str message; /* Whole message: request line + headers + body */
1180 
1181  struct ns_str proto; /* "HTTP/1.1" -- for both request and response */
1182  /* HTTP Request line (or HTTP response line) */
1183  struct ns_str method; /* "GET" */
1184  struct ns_str uri; /* "/my_file.html" */
1185  /* For responses, code and response status message are set */
1186  int resp_code;
1187  struct ns_str resp_status_msg;
1188 
1189  /*
1190  * Query-string part of the URI. For example, for HTTP request
1191  * GET /foo/bar?param1=val1&param2=val2
1192  * | uri | query_string |
1193  *
1194  * Note that question mark character doesn't belong neither to the uri,
1195  * nor to the query_string
1196  */
1197  struct ns_str query_string;
1198 
1199  /* Headers */
1200  struct ns_str header_names[NS_MAX_HTTP_HEADERS];
1201  struct ns_str header_values[NS_MAX_HTTP_HEADERS];
1202 
1203  /* Message body */
1204  struct ns_str body; /* Zero-length for requests with no body */
1205 };
1206 
1208  unsigned char *data;
1209  size_t size;
1210  unsigned char flags;
1211 };
1212 
1213 /* HTTP and websocket events. void *ev_data is described in a comment. */
1214 #define NS_HTTP_REQUEST 100 /* struct http_message * */
1215 #define NS_HTTP_REPLY 101 /* struct http_message * */
1216 #define NS_HTTP_CHUNK 102 /* struct http_message * */
1217 #define NS_SSI_CALL 105 /* char * */
1218 
1219 #define NS_WEBSOCKET_HANDSHAKE_REQUEST 111 /* NULL */
1220 #define NS_WEBSOCKET_HANDSHAKE_DONE 112 /* NULL */
1221 #define NS_WEBSOCKET_FRAME 113 /* struct websocket_message * */
1222 #define NS_WEBSOCKET_CONTROL_FRAME 114 /* struct websocket_message * */
1223 
1224 /*
1225  * Attach built-in HTTP event handler to the given connection.
1226  * User-defined event handler will receive following extra events:
1227  *
1228  * - NS_HTTP_REQUEST: HTTP request has arrived. Parsed HTTP request is passed as
1229  * `struct http_message` through the handler's `void *ev_data` pointer.
1230  * - NS_HTTP_REPLY: HTTP reply has arrived. Parsed HTTP reply is passed as
1231  * `struct http_message` through the handler's `void *ev_data` pointer.
1232  * - NS_HTTP_CHUNK: HTTP chunked-encoding chunk has arrived.
1233  * Parsed HTTP reply is passed as `struct http_message` through the
1234  * handler's `void *ev_data` pointer. `http_message::body` would contain
1235  * incomplete, reassembled HTTP body.
1236  * It will grow with every new chunk arrived, and
1237  * potentially can consume a lot of memory. An event handler may process
1238  * the body as chunks are coming, and signal Fossa to delete processed
1239  * body by setting `NSF_DELETE_CHUNK` in `ns_connection::flags`. When
1240  * the last zero chunk is received, Fossa sends `NS_HTTP_REPLY` event will
1241  * full reassembled body (if handler did not signal to delete chunks) or
1242  * with empty body (if handler did signal to delete chunks).
1243  * - NS_WEBSOCKET_HANDSHAKE_REQUEST: server has received websocket handshake
1244  * request. `ev_data` contains parsed HTTP request.
1245  * - NS_WEBSOCKET_HANDSHAKE_DONE: server has completed Websocket handshake.
1246  * `ev_data` is `NULL`.
1247  * - NS_WEBSOCKET_FRAME: new websocket frame has arrived. `ev_data` is
1248  * `struct websocket_message *`
1249  */
1250 void ns_set_protocol_http_websocket(struct ns_connection *nc);
1251 
1252 /*
1253  * Send websocket handshake to the server.
1254  *
1255  * `nc` must be a valid connection, connected to a server. `uri` is an URI
1256  * to fetch, extra_headers` is extra HTTP headers to send or `NULL`.
1257  *
1258  * This function is intended to be used by websocket client.
1259  */
1260 void ns_send_websocket_handshake(struct ns_connection *nc, const char *uri,
1261  const char *extra_headers);
1262 
1263 /*
1264  * Send websocket frame to the remote end.
1265  *
1266  * `op` specifies frame's type , one of:
1267  *
1268  * - WEBSOCKET_OP_CONTINUE
1269  * - WEBSOCKET_OP_TEXT
1270  * - WEBSOCKET_OP_BINARY
1271  * - WEBSOCKET_OP_CLOSE
1272  * - WEBSOCKET_OP_PING
1273  * - WEBSOCKET_OP_PONG
1274  * `data` and `data_len` contain frame data.
1275  */
1276 void ns_send_websocket_frame(struct ns_connection *nc, int op, const void *data,
1277  size_t data_len);
1278 
1279 /*
1280  * Send multiple websocket frames.
1281  *
1282  * Like `ns_send_websocket_frame()`, but composes a frame from multiple buffers.
1283  */
1284 void ns_send_websocket_framev(struct ns_connection *nc, int op,
1285  const struct ns_str *strings, int num_strings);
1286 
1287 /*
1288  * Send websocket frame to the remote end.
1289  *
1290  * Like `ns_send_websocket_frame()`, but allows to create formatted message
1291  * with `printf()`-like semantics.
1292  */
1293 void ns_printf_websocket_frame(struct ns_connection *nc, int op,
1294  const char *fmt, ...);
1295 
1296 /*
1297  * Send buffer `buf` of size `len` to the client using chunked HTTP encoding.
1298  * This function first sends buffer size as hex number + newline, then
1299  * buffer itself, then newline. For example,
1300  * `ns_send_http_chunk(nc, "foo", 3)` whill append `3\r\nfoo\r\n` string to
1301  * the `nc->send_mbuf` output IO buffer.
1302  *
1303  * NOTE: HTTP header "Transfer-Encoding: chunked" should be sent prior to
1304  * using this function.
1305  *
1306  * NOTE: do not forget to send empty chunk at the end of the response,
1307  * to tell the client that everything was sent. Example:
1308  *
1309  * ```
1310  * ns_printf_http_chunk(nc, "%s", "my response!");
1311  * ns_send_http_chunk(nc, "", 0); // Tell the client we're finished
1312  * ```
1313  */
1314 void ns_send_http_chunk(struct ns_connection *nc, const char *buf, size_t len);
1315 
1316 /*
1317  * Send printf-formatted HTTP chunk.
1318  * Functionality is similar to `ns_send_http_chunk()`.
1319  */
1320 void ns_printf_http_chunk(struct ns_connection *, const char *, ...);
1321 
1322 /*
1323  * Send printf-formatted HTTP chunk, escaping HTML tags.
1324  */
1325 void ns_printf_html_escape(struct ns_connection *, const char *, ...);
1326 
1327 /* Websocket opcodes, from http://tools.ietf.org/html/rfc6455 */
1328 #define WEBSOCKET_OP_CONTINUE 0
1329 #define WEBSOCKET_OP_TEXT 1
1330 #define WEBSOCKET_OP_BINARY 2
1331 #define WEBSOCKET_OP_CLOSE 8
1332 #define WEBSOCKET_OP_PING 9
1333 #define WEBSOCKET_OP_PONG 10
1334 
1335 /*
1336  * Parse a HTTP message.
1337  *
1338  * `is_req` should be set to 1 if parsing request, 0 if reply.
1339  *
1340  * Return number of bytes parsed. If HTTP message is
1341  * incomplete, `0` is returned. On parse error, negative number is returned.
1342  */
1343 int ns_parse_http(const char *s, int n, struct http_message *hm, int is_req);
1344 
1345 /*
1346  * Search and return header `name` in parsed HTTP message `hm`.
1347  * If header is not found, NULL is returned. Example:
1348  *
1349  * struct ns_str *host_hdr = ns_get_http_header(hm, "Host");
1350  */
1351 struct ns_str *ns_get_http_header(struct http_message *hm, const char *name);
1352 
1353 /*
1354  * Parse HTTP header `hdr`. Find variable `var_name` and store it's value
1355  * in the buffer `buf`, `buf_size`. Return 0 if variable not found, non-zero
1356  * otherwise.
1357  *
1358  * This function is supposed to parse
1359  * cookies, authentication headers, etcetera. Example (error handling omitted):
1360  *
1361  * char user[20];
1362  * struct ns_str *hdr = ns_get_http_header(hm, "Authorization");
1363  * ns_http_parse_header(hdr, "username", user, sizeof(user));
1364  *
1365  * Return length of the variable's value. If buffer is not large enough,
1366  * or variable not found, 0 is returned.
1367  */
1368 int ns_http_parse_header(struct ns_str *hdr, const char *var_name, char *buf,
1369  size_t buf_size);
1370 
1371 /*
1372  * Parse buffer `buf`, `buf_len` that contains multipart form data chunks.
1373  * Store chunk name in a `var_name`, `var_name_len` buffer.
1374  * If a chunk is an uploaded file, then `file_name`, `file_name_len` is
1375  * filled with an uploaded file name. `chunk`, `chunk_len`
1376  * points to the chunk data.
1377  *
1378  * Return: number of bytes to skip to the next chunk, or 0 if there are
1379  * no more chunks.
1380  *
1381  * Usage example:
1382  *
1383  * static void ev_handler(struct ns_connection *nc, int ev, void *ev_data) {
1384  * switch(ev) {
1385  * case NS_HTTP_REQUEST: {
1386  * struct http_message *hm = (struct http_message *) ev_data;
1387  * char var_name[100], file_name[100];
1388  * const char *chunk;
1389  * size_t chunk_len, n1, n2;
1390  *
1391  * n1 = n2 = 0;
1392  * while ((n2 = ns_parse_multipart(hm->body.p + n1,
1393  * hm->body.len - n1,
1394  * var_name, sizeof(var_name),
1395  * file_name, sizeof(file_name),
1396  * &chunk, &chunk_len)) > 0) {
1397  * printf("var: %s, file_name: %s, size: %d, chunk: [%.*s]\n",
1398  * var_name, file_name, (int) chunk_len,
1399  * (int) chunk_len, chunk);
1400  * n1 += n2;
1401  * }
1402  * }
1403  * break;
1404  *
1405  */
1406 size_t ns_parse_multipart(const char *buf, size_t buf_len, char *var_name,
1407  size_t var_name_len, char *file_name,
1408  size_t file_name_len, const char **chunk,
1409  size_t *chunk_len);
1410 
1411 /*
1412  * Fetch an HTTP form variable.
1413  *
1414  * Fetch a variable `name` from a `buf` into a buffer specified by
1415  * `dst`, `dst_len`. Destination is always zero-terminated. Return length
1416  * of a fetched variable. If not found, 0 is returned. `buf` must be
1417  * valid url-encoded buffer. If destination is too small, `-1` is returned.
1418  */
1419 int ns_get_http_var(const struct ns_str *, const char *, char *dst, size_t);
1420 
1421 /* Create Digest authentication header for client request. */
1422 int ns_http_create_digest_auth_header(char *buf, size_t buf_len,
1423  const char *method, const char *uri,
1424  const char *auth_domain, const char *user,
1425  const char *passwd);
1426 /*
1427  * Helper function that creates outbound HTTP connection.
1428  *
1429  * `url` is a URL to fetch. It must be properly URL-encoded, e.g. have
1430  * no spaces, etc. By default, `ns_connect_http()` sends Connection and
1431  * Host headers. `extra_headers` is an extra HTTP headers to send, e.g.
1432  * `"User-Agent: my-app\r\n"`.
1433  * If `post_data` is NULL, then GET request is created. Otherwise, POST request
1434  * is created with the specified POST data. Examples:
1435  *
1436  * [source,c]
1437  * ----
1438  * nc1 = ns_connect_http(mgr, ev_handler_1, "http://www.google.com", NULL,
1439  * NULL);
1440  * nc2 = ns_connect_http(mgr, ev_handler_1, "https://github.com", NULL, NULL);
1441  * nc3 = ns_connect_http(mgr, ev_handler_1, "my_server:8000/form_submit/",
1442  * NULL, "var_1=value_1&var_2=value_2");
1443  * ----
1444  */
1445 struct ns_connection *ns_connect_http(struct ns_mgr *,
1446  ns_event_handler_t event_handler,
1447  const char *url,
1448  const char *extra_headers,
1449  const char *post_data);
1450 
1451 /*
1452  * This structure defines how `ns_serve_http()` works.
1453  * Best practice is to set only required settings, and leave the rest as NULL.
1454  */
1456  /* Path to web root directory */
1457  const char *document_root;
1458 
1459  /* List of index files. Default is "" */
1460  const char *index_files;
1461 
1462  /*
1463  * Leave as NULL to disable authentication.
1464  * To enable directory protection with authentication, set this to ".htpasswd"
1465  * Then, creating ".htpasswd" file in any directory automatically protects
1466  * it with digest authentication.
1467  * Use `mongoose` web server binary, or `htdigest` Apache utility to
1468  * create/manipulate passwords file.
1469  * Make sure `auth_domain` is set to a valid domain name.
1470  */
1471  const char *per_directory_auth_file;
1472 
1473  /* Authorization domain (domain name of this web server) */
1474  const char *auth_domain;
1475 
1476  /*
1477  * Leave as NULL to disable authentication.
1478  * Normally, only selected directories in the document root are protected.
1479  * If absolutely every access to the web server needs to be authenticated,
1480  * regardless of the URI, set this option to the path to the passwords file.
1481  * Format of that file is the same as ".htpasswd" file. Make sure that file
1482  * is located outside document root to prevent people fetching it.
1483  */
1484  const char *global_auth_file;
1485 
1486  /* Set to "no" to disable directory listing. Enabled by default. */
1487  const char *enable_directory_listing;
1488 
1489  /* SSI files pattern. If not set, "**.shtml$|**.shtm$" is used. */
1490  const char *ssi_pattern;
1491 
1492  /* IP ACL. By default, NULL, meaning all IPs are allowed to connect */
1493  const char *ip_acl;
1494 
1495  /* URL rewrites.
1496  *
1497  * Comma-separated list of `uri_pattern=file_or_directory_path` rewrites.
1498  * When HTTP request is received, Fossa constructs a file name from the
1499  * requested URI by combining `document_root` and the URI. However, if the
1500  * rewrite option is used and `uri_pattern` matches requested URI, then
1501  * `document_root` is ignored. Instead, `file_or_directory_path` is used,
1502  * which should be a full path name or a path relative to the web server's
1503  * current working directory. Note that `uri_pattern`, as all Fossa patterns,
1504  * is a prefix pattern.
1505  *
1506  * If uri_pattern starts with `@` symbol, then Fossa compares it with the
1507  * HOST header of the request. If they are equal, Fossa sets document root
1508  * to `file_or_directory_path`, implementing virtual hosts support.
1509  */
1510  const char *url_rewrites;
1511 
1512  /* DAV document root. If NULL, DAV requests are going to fail. */
1513  const char *dav_document_root;
1514 
1515  /* Glob pattern for the files to hide. */
1516  const char *hidden_file_pattern;
1517 
1518  /* Set to non-NULL to enable CGI, e.g. **.cgi$|**.php$" */
1519  const char *cgi_file_pattern;
1520 
1521  /* If not NULL, ignore CGI script hashbang and use this interpreter */
1522  const char *cgi_interpreter;
1523 
1524  /*
1525  * Comma-separated list of Content-Type overrides for path suffixes, e.g.
1526  * ".txt=text/plain; charset=utf-8,.c=text/plain"
1527  */
1528  const char *custom_mime_types;
1529 };
1530 
1531 /*
1532  * Serve given HTTP request according to the `options`.
1533  *
1534  * Example code snippet:
1535  *
1536  * [source,c]
1537  * .web_server.c
1538  * ----
1539  * static void ev_handler(struct ns_connection *nc, int ev, void *ev_data) {
1540  * struct http_message *hm = (struct http_message *) ev_data;
1541  * struct ns_serve_http_opts opts = { .document_root = "/var/www" }; // C99
1542  *
1543  * switch (ev) {
1544  * case NS_HTTP_REQUEST:
1545  * ns_serve_http(nc, hm, opts);
1546  * break;
1547  * default:
1548  * break;
1549  * }
1550  * }
1551  * ----
1552  */
1553 void ns_serve_http(struct ns_connection *, struct http_message *,
1554  struct ns_serve_http_opts);
1555 
1556 #ifdef __cplusplus
1557 }
1558 #endif /* __cplusplus */
1559 #endif /* NS_HTTP_HEADER_DEFINED */
1560 /*
1561  * Copyright (c) 2014 Cesanta Software Limited
1562  * All rights reserved
1563  */
1564 
1565 /*
1566  * === JSON-RPC
1567  */
1568 
1569 #ifndef NS_JSON_RPC_HEADER_DEFINED
1570 #define NS_JSON_RPC_HEADER_DEFINED
1571 
1572 #ifdef __cplusplus
1573 extern "C" {
1574 #endif /* __cplusplus */
1575 
1576 /* JSON-RPC request */
1578  struct json_token *message; /* Whole RPC message */
1579  struct json_token *id; /* Message ID */
1580  struct json_token *method; /* Method name */
1581  struct json_token *params; /* Method params */
1582 };
1583 
1584 /* JSON-RPC response */
1586  struct json_token *message; /* Whole RPC message */
1587  struct json_token *id; /* Message ID */
1588  struct json_token *result; /* Remote call result */
1589 };
1590 
1591 /* JSON-RPC error */
1593  struct json_token *message; /* Whole RPC message */
1594  struct json_token *id; /* Message ID */
1595  struct json_token *error_code; /* error.code */
1596  struct json_token *error_message; /* error.message */
1597  struct json_token *error_data; /* error.data, can be NULL */
1598 };
1599 
1600 /*
1601  * Parse JSON-RPC reply contained in `buf`, `len` into JSON tokens array
1602  * `toks`, `max_toks`. If buffer contains valid reply, `reply` structure is
1603  * populated. The result of RPC call is located in `reply.result`. On error,
1604  * `error` structure is populated. Returns: the result of calling
1605  * `parse_json(buf, len, toks, max_toks)`:
1606  *
1607  * On success, an offset inside `json_string` is returned
1608  * where parsing has finished. On failure, a negative number is
1609  * returned, one of:
1610  *
1611  * - #define JSON_STRING_INVALID -1
1612  * - #define JSON_STRING_INCOMPLETE -2
1613  * - #define JSON_TOKEN_ARRAY_TOO_SMALL -3
1614  */
1615 int ns_rpc_parse_reply(const char *buf, int len, struct json_token *toks,
1616  int max_toks, struct ns_rpc_reply *,
1617  struct ns_rpc_error *);
1618 
1619 /*
1620  * Create JSON-RPC request in a given buffer.
1621  *
1622  * Return length of the request, which
1623  * can be larger then `len` that indicates an overflow.
1624  * `params_fmt` format string should conform to `json_emit()` API,
1625  * see https://github.com/cesanta/frozen
1626  */
1627 int ns_rpc_create_request(char *buf, int len, const char *method,
1628  const char *id, const char *params_fmt, ...);
1629 
1630 /*
1631  * Create JSON-RPC reply in a given buffer.
1632  *
1633  * Return length of the reply, which
1634  * can be larger then `len` that indicates an overflow.
1635  * `result_fmt` format string should conform to `json_emit()` API,
1636  * see https://github.com/cesanta/frozen
1637  */
1638 int ns_rpc_create_reply(char *buf, int len, const struct ns_rpc_request *req,
1639  const char *result_fmt, ...);
1640 
1641 /*
1642  * Create JSON-RPC error reply in a given buffer.
1643  *
1644  * Return length of the error, which
1645  * can be larger then `len` that indicates an overflow.
1646  * `fmt` format string should conform to `json_emit()` API,
1647  * see https://github.com/cesanta/frozen
1648  */
1649 int ns_rpc_create_error(char *buf, int len, struct ns_rpc_request *req,
1650  int code, const char *message, const char *fmt, ...);
1651 
1652 /* JSON-RPC standard error codes */
1653 #define JSON_RPC_PARSE_ERROR (-32700)
1654 #define JSON_RPC_INVALID_REQUEST_ERROR (-32600)
1655 #define JSON_RPC_METHOD_NOT_FOUND_ERROR (-32601)
1656 #define JSON_RPC_INVALID_PARAMS_ERROR (-32602)
1657 #define JSON_RPC_INTERNAL_ERROR (-32603)
1658 #define JSON_RPC_SERVER_ERROR (-32000)
1659 
1660 /*
1661  * Create JSON-RPC error in a given buffer.
1662  *
1663  * Return length of the error, which
1664  * can be larger then `len` that indicates an overflow. See
1665  * JSON_RPC_*_ERROR definitions for standard error values:
1666  *
1667  * - #define JSON_RPC_PARSE_ERROR (-32700)
1668  * - #define JSON_RPC_INVALID_REQUEST_ERROR (-32600)
1669  * - #define JSON_RPC_METHOD_NOT_FOUND_ERROR (-32601)
1670  * - #define JSON_RPC_INVALID_PARAMS_ERROR (-32602)
1671  * - #define JSON_RPC_INTERNAL_ERROR (-32603)
1672  * - #define JSON_RPC_SERVER_ERROR (-32000)
1673  */
1674 int ns_rpc_create_std_error(char *, int, struct ns_rpc_request *, int code);
1675 
1676 typedef int (*ns_rpc_handler_t)(char *buf, int len, struct ns_rpc_request *);
1677 
1678 /*
1679  * Dispatches a JSON-RPC request.
1680  *
1681  * Parses JSON-RPC request contained in `buf`, `len`.
1682  * Then, dispatches the request to the correct handler method.
1683  * Valid method names should be specified in NULL
1684  * terminated array `methods`, and corresponding handlers in `handlers`.
1685  * Result is put in `dst`, `dst_len`. Return: length of the result, which
1686  * can be larger then `dst_len` that indicates an overflow.
1687  * Overflown bytes are not written to the buffer.
1688  * If method is not found, an error is automatically generated.
1689  */
1690 int ns_rpc_dispatch(const char *buf, int, char *dst, int dst_len,
1691  const char **methods, ns_rpc_handler_t *handlers);
1692 
1693 #ifdef __cplusplus
1694 }
1695 #endif /* __cplusplus */
1696 #endif /* NS_JSON_RPC_HEADER_DEFINED */
1697 /*
1698  * Copyright (c) 2014 Cesanta Software Limited
1699  * All rights reserved
1700  * This software is dual-licensed: you can redistribute it and/or modify
1701  * it under the terms of the GNU General Public License version 2 as
1702  * published by the Free Software Foundation. For the terms of this
1703  * license, see <http://www.gnu.org/licenses/>.
1704  *
1705  * You are free to use this software under the terms of the GNU General
1706  * Public License, but WITHOUT ANY WARRANTY; without even the implied
1707  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1708  * See the GNU General Public License for more details.
1709  *
1710  * Alternatively, you can license this software under a commercial
1711  * license, as set out in <https://www.cesanta.com/license>.
1712  */
1713 
1714 /*
1715  * === MQTT
1716  */
1717 
1718 #ifndef NS_MQTT_HEADER_INCLUDED
1719 #define NS_MQTT_HEADER_INCLUDED
1720 
1721 
1723  int cmd;
1724  struct ns_str payload;
1725  int qos;
1726  uint8_t connack_ret_code; /* connack */
1727  uint16_t message_id; /* puback */
1728  char *topic;
1729 };
1730 
1732  const char *topic;
1733  uint8_t qos;
1734 };
1735 
1737  unsigned char flags; /* connection flags */
1738  uint16_t keep_alive;
1739  const char *will_topic;
1740  const char *will_message;
1741  const char *user_name;
1742  const char *password;
1743 };
1744 
1745 /* Message types */
1746 #define NS_MQTT_CMD_CONNECT 1
1747 #define NS_MQTT_CMD_CONNACK 2
1748 #define NS_MQTT_CMD_PUBLISH 3
1749 #define NS_MQTT_CMD_PUBACK 4
1750 #define NS_MQTT_CMD_PUBREC 5
1751 #define NS_MQTT_CMD_PUBREL 6
1752 #define NS_MQTT_CMD_PUBCOMP 7
1753 #define NS_MQTT_CMD_SUBSCRIBE 8
1754 #define NS_MQTT_CMD_SUBACK 9
1755 #define NS_MQTT_CMD_UNSUBSCRIBE 10
1756 #define NS_MQTT_CMD_UNSUBACK 11
1757 #define NS_MQTT_CMD_PINGREQ 12
1758 #define NS_MQTT_CMD_PINGRESP 13
1759 #define NS_MQTT_CMD_DISCONNECT 14
1760 
1761 /* MQTT event types */
1762 #define NS_MQTT_EVENT_BASE 200
1763 #define NS_MQTT_CONNECT (NS_MQTT_EVENT_BASE + NS_MQTT_CMD_CONNECT)
1764 #define NS_MQTT_CONNACK (NS_MQTT_EVENT_BASE + NS_MQTT_CMD_CONNACK)
1765 #define NS_MQTT_PUBLISH (NS_MQTT_EVENT_BASE + NS_MQTT_CMD_PUBLISH)
1766 #define NS_MQTT_PUBACK (NS_MQTT_EVENT_BASE + NS_MQTT_CMD_PUBACK)
1767 #define NS_MQTT_PUBREC (NS_MQTT_EVENT_BASE + NS_MQTT_CMD_PUBREC)
1768 #define NS_MQTT_PUBREL (NS_MQTT_EVENT_BASE + NS_MQTT_CMD_PUBREL)
1769 #define NS_MQTT_PUBCOMP (NS_MQTT_EVENT_BASE + NS_MQTT_CMD_PUBCOMP)
1770 #define NS_MQTT_SUBSCRIBE (NS_MQTT_EVENT_BASE + NS_MQTT_CMD_SUBSCRIBE)
1771 #define NS_MQTT_SUBACK (NS_MQTT_EVENT_BASE + NS_MQTT_CMD_SUBACK)
1772 #define NS_MQTT_UNSUBSCRIBE (NS_MQTT_EVENT_BASE + NS_MQTT_CMD_UNSUBSCRIBE)
1773 #define NS_MQTT_UNSUBACK (NS_MQTT_EVENT_BASE + NS_MQTT_CMD_UNSUBACK)
1774 #define NS_MQTT_PINGREQ (NS_MQTT_EVENT_BASE + NS_MQTT_CMD_PINGREQ)
1775 #define NS_MQTT_PINGRESP (NS_MQTT_EVENT_BASE + NS_MQTT_CMD_PINGRESP)
1776 #define NS_MQTT_DISCONNECT (NS_MQTT_EVENT_BASE + NS_MQTT_CMD_DISCONNECT)
1777 
1778 /* Message flags */
1779 #define NS_MQTT_RETAIN 0x1
1780 #define NS_MQTT_DUP 0x4
1781 #define NS_MQTT_QOS(qos) ((qos) << 1)
1782 #define NS_MQTT_GET_QOS(flags) (((flags) &0x6) >> 1)
1783 #define NS_MQTT_SET_QOS(flags, qos) (flags) = ((flags) & ~0x6) | ((qos) << 1)
1784 
1785 /* Connection flags */
1786 #define NS_MQTT_CLEAN_SESSION 0x02
1787 #define NS_MQTT_HAS_WILL 0x04
1788 #define NS_MQTT_WILL_RETAIN 0x20
1789 #define NS_MQTT_HAS_PASSWORD 0x40
1790 #define NS_MQTT_HAS_USER_NAME 0x80
1791 #define NS_MQTT_GET_WILL_QOS(flags) (((flags) &0x18) >> 3)
1792 #define NS_MQTT_SET_WILL_QOS(flags, qos) \
1793  (flags) = ((flags) & ~0x18) | ((qos) << 3)
1794 
1795 /* CONNACK return codes */
1796 #define NS_MQTT_CONNACK_ACCEPTED 0
1797 #define NS_MQTT_CONNACK_UNACCEPTABLE_VERSION 1
1798 #define NS_MQTT_CONNACK_IDENTIFIER_REJECTED 2
1799 #define NS_MQTT_CONNACK_SERVER_UNAVAILABLE 3
1800 #define NS_MQTT_CONNACK_BAD_AUTH 4
1801 #define NS_MQTT_CONNACK_NOT_AUTHORIZED 5
1802 
1803 #ifdef __cplusplus
1804 extern "C" {
1805 #endif /* __cplusplus */
1806 
1807 /*
1808  * Attach built-in MQTT event handler to the given connection.
1809  *
1810  * The user-defined event handler will receive following extra events:
1811  *
1812  * - NS_MQTT_CONNACK
1813  * - NS_MQTT_PUBLISH
1814  * - NS_MQTT_PUBACK
1815  * - NS_MQTT_PUBREC
1816  * - NS_MQTT_PUBREL
1817  * - NS_MQTT_PUBCOMP
1818  * - NS_MQTT_SUBACK
1819  */
1820 void ns_set_protocol_mqtt(struct ns_connection *);
1821 
1822 /* Send MQTT handshake. */
1823 void ns_send_mqtt_handshake(struct ns_connection *nc, const char *client_id);
1824 
1825 /* Send MQTT handshake with optional parameters. */
1826 void ns_send_mqtt_handshake_opt(struct ns_connection *, const char *client_id,
1828 
1829 /* Publish a message to a given topic. */
1830 void ns_mqtt_publish(struct ns_connection *nc, const char *topic,
1831  uint16_t message_id, int flags, const void *data,
1832  size_t len);
1833 
1834 /* Subscribe to a bunch of topics. */
1835 void ns_mqtt_subscribe(struct ns_connection *nc,
1836  const struct ns_mqtt_topic_expression *topics,
1837  size_t topics_len, uint16_t message_id);
1838 
1839 /* Unsubscribe from a bunch of topics. */
1840 void ns_mqtt_unsubscribe(struct ns_connection *nc, char **topics,
1841  size_t topics_len, uint16_t message_id);
1842 
1843 /* Send a DISCONNECT command. */
1844 void ns_mqtt_disconnect(struct ns_connection *nc);
1845 
1846 /* Send a CONNACK command with a given `return_code`. */
1847 void ns_mqtt_connack(struct ns_connection *, uint8_t);
1848 
1849 /* Send a PUBACK command with a given `message_id`. */
1850 void ns_mqtt_puback(struct ns_connection *, uint16_t);
1851 
1852 /* Send a PUBREC command with a given `message_id`. */
1853 void ns_mqtt_pubrec(struct ns_connection *, uint16_t);
1854 
1855 /* Send a PUBREL command with a given `message_id`. */
1856 void ns_mqtt_pubrel(struct ns_connection *, uint16_t);
1857 
1858 /* Send a PUBCOMP command with a given `message_id`. */
1859 void ns_mqtt_pubcomp(struct ns_connection *, uint16_t);
1860 
1861 /*
1862  * Send a SUBACK command with a given `message_id`
1863  * and a sequence of granted QoSs.
1864  */
1865 void ns_mqtt_suback(struct ns_connection *, uint8_t *, size_t, uint16_t);
1866 
1867 /* Send a UNSUBACK command with a given `message_id`. */
1868 void ns_mqtt_unsuback(struct ns_connection *, uint16_t);
1869 
1870 /* Send a PINGREQ command. */
1871 void ns_mqtt_ping(struct ns_connection *);
1872 
1873 /* Send a PINGRESP command. */
1874 void ns_mqtt_pong(struct ns_connection *);
1875 
1876 /*
1877  * Extract the next topic expression from a SUBSCRIBE command payload.
1878  *
1879  * Topic expression name will point to a string in the payload buffer.
1880  * Return the pos of the next topic expression or -1 when the list
1881  * of topics is exhausted.
1882  */
1883 int ns_mqtt_next_subscribe_topic(struct ns_mqtt_message *, struct ns_str *,
1884  uint8_t *, int);
1885 
1886 #ifdef __cplusplus
1887 }
1888 #endif /* __cplusplus */
1889 
1890 #endif /* NS_MQTT_HEADER_INCLUDED */
1891 /*
1892  * Copyright (c) 2014 Cesanta Software Limited
1893  * All rights reserved
1894  * This software is dual-licensed: you can redistribute it and/or modify
1895  * it under the terms of the GNU General Public License version 2 as
1896  * published by the Free Software Foundation. For the terms of this
1897  * license, see <http://www.gnu.org/licenses/>.
1898  *
1899  * You are free to use this software under the terms of the GNU General
1900  * Public License, but WITHOUT ANY WARRANTY; without even the implied
1901  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1902  * See the GNU General Public License for more details.
1903  *
1904  * Alternatively, you can license this software under a commercial
1905  * license, as set out in <https://www.cesanta.com/license>.
1906  */
1907 
1908 /*
1909  * === MQTT Broker
1910  */
1911 
1912 #ifndef NS_MQTT_BROKER_HEADER_INCLUDED
1913 #define NS_MQTT_BROKER_HEADER_INCLUDED
1914 
1915 #ifdef NS_ENABLE_MQTT_BROKER
1916 
1917 
1918 #ifdef __cplusplus
1919 extern "C" {
1920 #endif /* __cplusplus */
1921 
1922 #define NS_MQTT_MAX_SESSION_SUBSCRIPTIONS 512;
1923 
1924 struct ns_mqtt_broker;
1925 
1926 /* MQTT session (Broker side). */
1927 struct ns_mqtt_session {
1928  struct ns_mqtt_broker *brk; /* Broker */
1929  struct ns_mqtt_session *next, *prev; /* ns_mqtt_broker::sessions linkage */
1930  struct ns_connection *nc; /* Connection with the client */
1931  size_t num_subscriptions; /* Size of `subscriptions` array */
1932  struct ns_mqtt_topic_expression *subscriptions;
1933  void *user_data; /* User data */
1934 };
1935 
1936 /* MQTT broker. */
1937 struct ns_mqtt_broker {
1938  struct ns_mqtt_session *sessions; /* Session list */
1939  void *user_data; /* User data */
1940 };
1941 
1942 /* Initialize a MQTT broker. */
1943 void ns_mqtt_broker_init(struct ns_mqtt_broker *, void *);
1944 
1945 /*
1946  * Process a MQTT broker message.
1947  *
1948  * Listening connection expects a pointer to an initialized `ns_mqtt_broker`
1949  * structure in the `user_data` field.
1950  *
1951  * Basic usage:
1952  *
1953  * [source,c]
1954  * -----
1955  * ns_mqtt_broker_init(&brk, NULL);
1956  *
1957  * if ((nc = ns_bind(&mgr, address, ns_mqtt_broker)) == NULL) {
1958  * // fail;
1959  * }
1960  * nc->user_data = &brk;
1961  * -----
1962  *
1963  * New incoming connections will receive a `ns_mqtt_session` structure
1964  * in the connection `user_data`. The original `user_data` will be stored
1965  * in the `user_data` field of the session structure. This allows the user
1966  * handler to store user data before `ns_mqtt_broker` creates the session.
1967  *
1968  * Since only the NS_ACCEPT message is processed by the listening socket,
1969  * for most events the `user_data` will thus point to a `ns_mqtt_session`.
1970  */
1971 void ns_mqtt_broker(struct ns_connection *, int, void *);
1972 
1973 /*
1974  * Iterate over all mqtt sessions connections. Example:
1975  *
1976  * struct ns_mqtt_session *s;
1977  * for (s = ns_mqtt_next(brk, NULL); s != NULL; s = ns_mqtt_next(brk, s)) {
1978  * // Do something
1979  * }
1980  */
1981 struct ns_mqtt_session *ns_mqtt_next(struct ns_mqtt_broker *,
1982  struct ns_mqtt_session *);
1983 
1984 #ifdef __cplusplus
1985 }
1986 #endif /* __cplusplus */
1987 
1988 #endif /* NS_ENABLE_MQTT_BROKER */
1989 #endif /* NS_MQTT_HEADER_INCLUDED */
1990 /*
1991  * Copyright (c) 2014 Cesanta Software Limited
1992  * All rights reserved
1993  */
1994 
1995 /*
1996  * === DNS
1997  */
1998 
1999 #ifndef NS_DNS_HEADER_DEFINED
2000 #define NS_DNS_HEADER_DEFINED
2001 
2002 
2003 #ifdef __cplusplus
2004 extern "C" {
2005 #endif /* __cplusplus */
2006 
2007 #define NS_DNS_A_RECORD 0x01 /* Lookup IP address */
2008 #define NS_DNS_CNAME_RECORD 0x05 /* Lookup CNAME */
2009 #define NS_DNS_AAAA_RECORD 0x1c /* Lookup IPv6 address */
2010 #define NS_DNS_MX_RECORD 0x0f /* Lookup mail server for domain */
2011 
2012 #define NS_MAX_DNS_QUESTIONS 32
2013 #define NS_MAX_DNS_ANSWERS 32
2014 
2015 #define NS_DNS_MESSAGE 100 /* High-level DNS message event */
2016 
2017 enum ns_dns_resource_record_kind {
2018  NS_DNS_INVALID_RECORD = 0,
2019  NS_DNS_QUESTION,
2020  NS_DNS_ANSWER
2021 };
2022 
2023 /* DNS resource record. */
2025  struct ns_str name; /* buffer with compressed name */
2026  int rtype;
2027  int rclass;
2028  int ttl;
2029  enum ns_dns_resource_record_kind kind;
2030  struct ns_str rdata; /* protocol data (can be a compressed name) */
2031 };
2032 
2033 /* DNS message (request and response). */
2035  struct ns_str pkt; /* packet body */
2036  uint16_t flags;
2037  uint16_t transaction_id;
2038  int num_questions;
2039  int num_answers;
2040  struct ns_dns_resource_record questions[NS_MAX_DNS_QUESTIONS];
2041  struct ns_dns_resource_record answers[NS_MAX_DNS_ANSWERS];
2042 };
2043 
2044 struct ns_dns_resource_record *ns_dns_next_record(
2045  struct ns_dns_message *, int, struct ns_dns_resource_record *);
2046 
2047 /*
2048  * Parse the record data from a DNS resource record.
2049  *
2050  * - A: struct in_addr *ina
2051  * - AAAA: struct in6_addr *ina
2052  * - CNAME: char buffer
2053  *
2054  * Returns -1 on error.
2055  *
2056  * TODO(mkm): MX
2057  */
2058 int ns_dns_parse_record_data(struct ns_dns_message *,
2059  struct ns_dns_resource_record *, void *, size_t);
2060 
2061 /*
2062  * Send a DNS query to the remote end.
2063  */
2064 void ns_send_dns_query(struct ns_connection *, const char *, int);
2065 
2066 /*
2067  * Insert a DNS header to an IO buffer.
2068  *
2069  * Return number of bytes inserted.
2070  */
2071 int ns_dns_insert_header(struct mbuf *, size_t, struct ns_dns_message *);
2072 
2073 /*
2074  * Append already encoded body from an existing message.
2075  *
2076  * This is useful when generating a DNS reply message which includes
2077  * all question records.
2078  *
2079  * Return number of appened bytes.
2080  */
2081 int ns_dns_copy_body(struct mbuf *, struct ns_dns_message *);
2082 
2083 /*
2084  * Encode and append a DNS resource record to an IO buffer.
2085  *
2086  * The record metadata is taken from the `rr` parameter, while the name and data
2087  * are taken from the parameters, encoded in the appropriate format depending on
2088  * record type, and stored in the IO buffer. The encoded values might contain
2089  * offsets within the IO buffer. It's thus important that the IO buffer doesn't
2090  * get trimmed while a sequence of records are encoded while preparing a DNS
2091  *reply.
2092  *
2093  * This function doesn't update the `name` and `rdata` pointers in the `rr`
2094  *struct
2095  * because they might be invalidated as soon as the IO buffer grows again.
2096  *
2097  * Return the number of bytes appened or -1 in case of error.
2098  */
2099 int ns_dns_encode_record(struct mbuf *, struct ns_dns_resource_record *,
2100  const char *, size_t, const void *, size_t);
2101 
2102 /* Low-level: parses a DNS response. */
2103 int ns_parse_dns(const char *, int, struct ns_dns_message *);
2104 
2105 /*
2106  * Uncompress a DNS compressed name.
2107  *
2108  * The containing dns message is required because the compressed encoding
2109  * and reference suffixes present elsewhere in the packet.
2110  *
2111  * If name is less than `dst_len` characters long, the remainder
2112  * of `dst` is terminated with `\0' characters. Otherwise, `dst` is not
2113  *terminated.
2114  *
2115  * If `dst_len` is 0 `dst` can be NULL.
2116  * Return the uncompressed name length.
2117  */
2118 size_t ns_dns_uncompress_name(struct ns_dns_message *, struct ns_str *, char *,
2119  int);
2120 
2121 /*
2122  * Attach built-in DNS event handler to the given listening connection.
2123  *
2124  * DNS event handler parses incoming UDP packets, treating them as DNS
2125  * requests. If incoming packet gets successfully parsed by the DNS event
2126  * handler, a user event handler will receive `NS_DNS_REQUEST` event, with
2127  * `ev_data` pointing to the parsed `struct ns_dns_message`.
2128  *
2129  * See
2130  * https://github.com/cesanta/fossa/tree/master/examples/captive_dns_server[captive_dns_server]
2131  * example on how to handle DNS request and send DNS reply.
2132  */
2133 void ns_set_protocol_dns(struct ns_connection *);
2134 
2135 #ifdef __cplusplus
2136 }
2137 #endif /* __cplusplus */
2138 #endif /* NS_HTTP_HEADER_DEFINED */
2139 /*
2140  * Copyright (c) 2014 Cesanta Software Limited
2141  * All rights reserved
2142  */
2143 
2144 /*
2145  * === DNS server
2146  *
2147  * Disabled by default; enable with `-DNS_ENABLE_DNS_SERVER`.
2148  */
2149 
2150 #ifndef NS_DNS_SERVER_HEADER_DEFINED
2151 #define NS_DNS_SERVER_HEADER_DEFINED
2152 
2153 #ifdef NS_ENABLE_DNS_SERVER
2154 
2155 
2156 #ifdef __cplusplus
2157 extern "C" {
2158 #endif /* __cplusplus */
2159 
2160 #define NS_DNS_SERVER_DEFAULT_TTL 3600
2161 
2162 struct ns_dns_reply {
2163  struct ns_dns_message *msg;
2164  struct mbuf *io;
2165  size_t start;
2166 };
2167 
2168 /*
2169  * Create a DNS reply.
2170  *
2171  * The reply will be based on an existing query message `msg`.
2172  * The query body will be appended to the output buffer.
2173  * "reply + recursion allowed" will be added to the message flags and
2174  * message's num_answers will be set to 0.
2175  *
2176  * Answer records can be appended with `ns_dns_send_reply` or by lower
2177  * level function defined in the DNS API.
2178  *
2179  * In order to send the reply use `ns_dns_send_reply`.
2180  * It's possible to use a connection's send buffer as reply buffers,
2181  * and it will work for both UDP and TCP connections.
2182  *
2183  * Example:
2184  *
2185  * [source,c]
2186  * -----
2187  * reply = ns_dns_create_reply(&nc->send_mbuf, msg);
2188  * for (i = 0; i < msg->num_questions; i++) {
2189  * rr = &msg->questions[i];
2190  * if (rr->rtype == NS_DNS_A_RECORD) {
2191  * ns_dns_reply_record(&reply, rr, 3600, &dummy_ip_addr, 4);
2192  * }
2193  * }
2194  * ns_dns_send_reply(nc, &reply);
2195  * -----
2196  */
2197 struct ns_dns_reply ns_dns_create_reply(struct mbuf *, struct ns_dns_message *);
2198 
2199 /*
2200  * Append a DNS reply record to the IO buffer and to the DNS message.
2201  *
2202  * The message num_answers field will be incremented. It's caller's duty
2203  * to ensure num_answers is propertly initialized.
2204  *
2205  * Returns -1 on error.
2206  */
2207 int ns_dns_reply_record(struct ns_dns_reply *, struct ns_dns_resource_record *,
2208  const char *, int, int, const void *, size_t);
2209 
2210 /*
2211  * Send a DNS reply through a connection.
2212  *
2213  * The DNS data is stored in an IO buffer pointed by reply structure in `r`.
2214  * This function mutates the content of that buffer in order to ensure that
2215  * the DNS header reflects size and flags of the mssage, that might have been
2216  * updated either with `ns_dns_reply_record` or by direct manipulation of
2217  * `r->message`.
2218  *
2219  * Once sent, the IO buffer will be trimmed unless the reply IO buffer
2220  * is the connection's send buffer and the connection is not in UDP mode.
2221  */
2222 int ns_dns_send_reply(struct ns_connection *, struct ns_dns_reply *);
2223 
2224 #ifdef __cplusplus
2225 }
2226 #endif /* __cplusplus */
2227 
2228 #endif /* NS_ENABLE_DNS_SERVER */
2229 #endif /* NS_HTTP_HEADER_DEFINED */
2230 /*
2231  * Copyright (c) 2014 Cesanta Software Limited
2232  * All rights reserved
2233  */
2234 
2235 /*
2236  * === Asynchronouns DNS resolver
2237  */
2238 
2239 #ifndef NS_RESOLV_HEADER_DEFINED
2240 #define NS_RESOLV_HEADER_DEFINED
2241 
2242 
2243 #ifdef __cplusplus
2244 extern "C" {
2245 #endif /* __cplusplus */
2246 
2247 typedef void (*ns_resolve_callback_t)(struct ns_dns_message *, void *);
2248 
2249 /* Options for `ns_resolve_async_opt`. */
2251  const char *nameserver_url;
2252  int max_retries; /* defaults to 2 if zero */
2253  int timeout; /* in seconds; defaults to 5 if zero */
2254  int accept_literal; /* pseudo-resolve literal ipv4 and ipv6 addrs */
2255  int only_literal; /* only resolves literal addrs; sync cb invocation */
2256 };
2257 
2258 /* See `ns_resolve_async_opt()` */
2259 int ns_resolve_async(struct ns_mgr *, const char *, int, ns_resolve_callback_t,
2260  void *data);
2261 
2262 /*
2263  * Resolved a DNS name asynchronously.
2264  *
2265  * Upon successful resolution, the user callback will be invoked
2266  * with the full DNS response message and a pointer to the user's
2267  * context `data`.
2268  *
2269  * In case of timeout while performing the resolution the callback
2270  * will receive a NULL `msg`.
2271  *
2272  * The DNS answers can be extracted with `ns_next_record` and
2273  * `ns_dns_parse_record_data`:
2274  *
2275  * [source,c]
2276  * ----
2277  * struct in_addr ina;
2278  * struct ns_dns_resource_record *rr = ns_next_record(msg, NS_DNS_A_RECORD,
2279  * NULL);
2280  * ns_dns_parse_record_data(msg, rr, &ina, sizeof(ina));
2281  * ----
2282  */
2283 int ns_resolve_async_opt(struct ns_mgr *, const char *, int,
2284  ns_resolve_callback_t, void *data,
2285  struct ns_resolve_async_opts opts);
2286 
2287 /*
2288  * Resolve a name from `/etc/hosts`.
2289  *
2290  * Returns 0 on success, -1 on failure.
2291  */
2292 int ns_resolve_from_hosts_file(const char *host, union socket_address *usa);
2293 
2294 #ifdef __cplusplus
2295 }
2296 #endif /* __cplusplus */
2297 #endif /* NS_RESOLV_HEADER_DEFINED */
2298 /*
2299  * Copyright (c) 2015 Cesanta Software Limited
2300  * All rights reserved
2301  * This software is dual-licensed: you can redistribute it and/or modify
2302  * it under the terms of the GNU General Public License version 2 as
2303  * published by the Free Software Foundation. For the terms of this
2304  * license, see <http://www.gnu.org/licenses/>.
2305  *
2306  * You are free to use this software under the terms of the GNU General
2307  * Public License, but WITHOUT ANY WARRANTY; without even the implied
2308  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
2309  * See the GNU General Public License for more details.
2310  *
2311  * Alternatively, you can license this software under a commercial
2312  * license, as set out in <https://www.cesanta.com/license>.
2313  */
2314 
2315 /*
2316  * === CoAP
2317  *
2318  * CoAP message format:
2319  *
2320  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
2321  * |Ver| T | TKL | Code | Message ID | Token (if any, TKL bytes) ...
2322  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
2323  * | Options (if any) ... |1 1 1 1 1 1 1 1| Payload (if any) ...
2324  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
2325  */
2326 
2327 #ifndef NS_COAP_HEADER_INCLUDED
2328 #define NS_COAP_HEADER_INCLUDED
2329 
2330 #ifdef NS_ENABLE_COAP
2331 
2332 #define NS_COAP_MSG_TYPE_FIELD 0x2
2333 #define NS_COAP_CODE_CLASS_FIELD 0x4
2334 #define NS_COAP_CODE_DETAIL_FIELD 0x8
2335 #define NS_COAP_MSG_ID_FIELD 0x10
2336 #define NS_COAP_TOKEN_FIELD 0x20
2337 #define NS_COAP_OPTIONS_FIELD 0x40
2338 #define NS_COAP_PAYLOAD_FIELD 0x80
2339 
2340 #define NS_COAP_ERROR 0x10000
2341 #define NS_COAP_FORMAT_ERROR (NS_COAP_ERROR | 0x20000)
2342 #define NS_COAP_IGNORE (NS_COAP_ERROR | 0x40000)
2343 #define NS_COAP_NOT_ENOUGH_DATA (NS_COAP_ERROR | 0x80000)
2344 #define NS_COAP_NETWORK_ERROR (NS_COAP_ERROR | 0x100000)
2345 
2346 #define NS_COAP_MSG_CON 0
2347 #define NS_COAP_MSG_NOC 1
2348 #define NS_COAP_MSG_ACK 2
2349 #define NS_COAP_MSG_RST 3
2350 #define NS_COAP_MSG_MAX 3
2351 
2352 #define NS_COAP_CODECLASS_REQUEST 0
2353 #define NS_COAP_CODECLASS_RESP_OK 2
2354 #define NS_COAP_CODECLASS_CLIENT_ERR 4
2355 #define NS_COAP_CODECLASS_SRV_ERR 5
2356 
2357 #define NS_COAP_EVENT_BASE 300
2358 #define NS_COAP_CON (NS_COAP_EVENT_BASE + NS_COAP_MSG_CON)
2359 #define NS_COAP_NOC (NS_COAP_EVENT_BASE + NS_COAP_MSG_NOC)
2360 #define NS_COAP_ACK (NS_COAP_EVENT_BASE + NS_COAP_MSG_ACK)
2361 #define NS_COAP_RST (NS_COAP_EVENT_BASE + NS_COAP_MSG_RST)
2362 
2363 /*
2364  * CoAP options.
2365  * Use ns_coap_add_option and ns_coap_free_options
2366  * for creation and destruction.
2367  */
2368 struct ns_coap_option {
2369  struct ns_coap_option *next;
2370  uint32_t number;
2371  struct ns_str value;
2372 };
2373 
2374 /* CoAP message. See RFC 7252 for details. */
2375 struct ns_coap_message {
2376  uint32_t flags;
2377  uint8_t msg_type;
2378  uint8_t code_class;
2379  uint8_t code_detail;
2380  uint16_t msg_id;
2381  struct ns_str token;
2382  struct ns_coap_option *options;
2383  struct ns_str payload;
2384  struct ns_coap_option *options_tail;
2385 };
2386 
2387 #ifdef __cplusplus
2388 extern "C" {
2389 #endif /* __cplusplus */
2390 
2391 /* Set CoAP protocol handler - trigger CoAP specific events */
2392 int ns_set_protocol_coap(struct ns_connection *nc);
2393 
2394 /*
2395  * Add new option to ns_coap_message structure.
2396  * Returns pointer to the newly created option.
2397  */
2398 struct ns_coap_option *ns_coap_add_option(struct ns_coap_message *cm,
2399  uint32_t number, char *value,
2400  size_t len);
2401 
2402 /*
2403  * Free the memory allocated for options,
2404  * if cm paramater doesn't contain any option does nothing.
2405  */
2406 void ns_coap_free_options(struct ns_coap_message *cm);
2407 
2408 /*
2409  * Compose CoAP message from `ns_coap_message`
2410  * and send it into `nc` connection.
2411  * Return 0 on success. On error, it is a bitmask:
2412  *
2413  * - #define NS_COAP_ERROR 0x10000
2414  * - #define NS_COAP_FORMAT_ERROR (NS_COAP_ERROR | 0x20000)
2415  * - #define NS_COAP_IGNORE (NS_COAP_ERROR | 0x40000)
2416  * - #define NS_COAP_NOT_ENOUGH_DATA (NS_COAP_ERROR | 0x80000)
2417  * - #define NS_COAP_NETWORK_ERROR (NS_COAP_ERROR | 0x100000)
2418  */
2419 uint32_t ns_coap_send_message(struct ns_connection *nc,
2420  struct ns_coap_message *cm);
2421 
2422 /*
2423  * Compose CoAP acknowledgement from `ns_coap_message`
2424  * and send it into `nc` connection.
2425  * Return value: see `ns_coap_send_message()`
2426  */
2427 uint32_t ns_coap_send_ack(struct ns_connection *nc, uint16_t msg_id);
2428 
2429 /*
2430  * Parse COAP message and fills ns_coap_message and returns cm->flags.
2431  * This is a helper function.
2432  *
2433  * NOTE: usually CoAP work over UDP, so lack of data means format error,
2434  * but in theory it is possible to use CoAP over TCP (according to RFC)
2435  *
2436  * The caller have to check results and treat COAP_NOT_ENOUGH_DATA according to
2437  * underlying protocol:
2438  *
2439  * - in case of UDP COAP_NOT_ENOUGH_DATA means COAP_FORMAT_ERROR,
2440  * - in case of TCP client can try to recieve more data
2441  *
2442  * Return value: see `ns_coap_send_message()`
2443  */
2444 uint32_t ns_coap_parse(struct mbuf *io, struct ns_coap_message *cm);
2445 
2446 /*
2447  * Composes CoAP message from ns_coap_message structure.
2448  * This is a helper function.
2449  * Return value: see `ns_coap_send_message()`
2450  */
2451 uint32_t ns_coap_compose(struct ns_coap_message *cm, struct mbuf *io);
2452 
2453 #ifdef __cplusplus
2454 }
2455 #endif /* __cplusplus */
2456 
2457 #endif /* NS_ENABLE_COAP */
2458 
2459 #endif /* NS_COAP_HEADER_INCLUDED */
Definition: fossa.h:1207
Definition: fossa.h:1731
Definition: fossa.h:590
Definition: fossa.h:1577
Definition: fossa.h:601
Definition: fossa.h:2034
Definition: fossa.h:1455
Definition: fossa.h:376
Definition: fossa.h:2250
Definition: fossa.h:553
Definition: fossa.h:1178
Definition: fossa.h:2024
Definition: fossa.h:1722
Definition: fossa.h:1736
Definition: fossa.h:1592
Definition: fossa.h:284
Definition: fossa.h:347
Definition: fossa.h:771
Definition: fossa.h:471
Definition: fossa.h:708
Definition: fossa.h:737
Definition: fossa.h:564
Definition: fossa.h:1585