libwebsockets
Lightweight C library for HTML5 websockets
lws-misc.h
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  */
24 
30 
44 #define lws_start_foreach_ll(type, it, start)\
45 { \
46  type it = start; \
47  while (it) {
48 
59 #define lws_end_foreach_ll(it, nxt) \
60  it = it->nxt; \
61  } \
62 }
63 
79 #define lws_start_foreach_ll_safe(type, it, start, nxt)\
80 { \
81  type it = start; \
82  while (it) { \
83  type next_##it = it->nxt;
84 
95 #define lws_end_foreach_ll_safe(it) \
96  it = next_##it; \
97  } \
98 }
99 
116 #define lws_start_foreach_llp(type, it, start)\
117 { \
118  type it = &(start); \
119  while (*(it)) {
120 
121 #define lws_start_foreach_llp_safe(type, it, start, nxt)\
122 { \
123  type it = &(start); \
124  type next; \
125  while (*(it)) { \
126  next = &((*(it))->nxt); \
127 
128 
138 #define lws_end_foreach_llp(it, nxt) \
139  it = &(*(it))->nxt; \
140  } \
141 }
142 
143 #define lws_end_foreach_llp_safe(it) \
144  it = next; \
145  } \
146 }
147 
148 #define lws_ll_fwd_insert(\
149  ___new_object, /* pointer to new object */ \
150  ___m_list, /* member for next list object ptr */ \
151  ___list_head /* list head */ \
152  ) {\
153  ___new_object->___m_list = ___list_head; \
154  ___list_head = ___new_object; \
155  }
156 
157 #define lws_ll_fwd_remove(\
158  ___type, /* type of listed object */ \
159  ___m_list, /* member for next list object ptr */ \
160  ___target, /* object to remove from list */ \
161  ___list_head /* list head */ \
162  ) { \
163  lws_start_foreach_llp(___type **, ___ppss, ___list_head) { \
164  if (*___ppss == ___target) { \
165  *___ppss = ___target->___m_list; \
166  break; \
167  } \
168  } lws_end_foreach_llp(___ppss, ___m_list); \
169  }
170 
171 /*
172  * doubly linked-list
173  */
174 
175 #if defined (LWS_WITH_DEPRECATED_LWS_DLL)
176 
177 /*
178  * This is going away in v4.1. You can set the cmake option above to keep it
179  * around temporarily. Migrate your stuff to the more capable and robust
180  * lws_dll2 below
181  */
182 
183 struct lws_dll {
184  struct lws_dll *prev;
185  struct lws_dll *next;
186 };
187 
188 /*
189  * these all point to the composed list objects... you have to use the
190  * lws_container_of() helper to recover the start of the containing struct
191  */
192 
193 #define lws_dll_add_front lws_dll_add_head
194 
195 LWS_VISIBLE LWS_EXTERN void
196 lws_dll_add_head(struct lws_dll *d, struct lws_dll *phead);
197 
198 LWS_VISIBLE LWS_EXTERN void
199 lws_dll_add_tail(struct lws_dll *d, struct lws_dll *phead);
200 
201 LWS_VISIBLE LWS_EXTERN void
202 lws_dll_insert(struct lws_dll *d, struct lws_dll *target,
203  struct lws_dll *phead, int before);
204 
205 static LWS_INLINE struct lws_dll *
206 lws_dll_get_head(struct lws_dll *phead) { return phead->next; }
207 
208 static LWS_INLINE struct lws_dll *
209 lws_dll_get_tail(struct lws_dll *phead) { return phead->prev; }
210 
211 /*
212  * caution, this doesn't track the tail in the head struct. Use
213  * lws_dll_remove_track_tail() instead of this if you want tail tracking. Using
214  * this means you can't use lws_dll_add_tail() amd
215  */
216 LWS_VISIBLE LWS_EXTERN void
217 lws_dll_remove(struct lws_dll *d) LWS_WARN_DEPRECATED;
218 
219 LWS_VISIBLE LWS_EXTERN void
220 lws_dll_remove_track_tail(struct lws_dll *d, struct lws_dll *phead);
221 
222 /* another way to do lws_start_foreach_dll_safe() on a list via a cb */
223 
224 LWS_VISIBLE LWS_EXTERN int
225 lws_dll_foreach_safe(struct lws_dll *phead, void *user,
226  int (*cb)(struct lws_dll *d, void *user));
227 
228 #define lws_dll_is_detached(___dll, __head) \
229  (!(___dll)->prev && !(___dll)->next && (__head)->prev != (___dll))
230 
231 #endif
232 
233 /*
234  * lws_dll2_owner / lws_dll2 : more capable version of lws_dll. Differences:
235  *
236  * - there's an explicit lws_dll2_owner struct which holds head, tail and
237  * count of members.
238  *
239  * - list members all hold a pointer to their owner. So user code does not
240  * have to track anything about exactly what lws_dll2_owner list the object
241  * is a member of.
242  *
243  * - you can use lws_dll unless you want the member count or the ability to
244  * not track exactly which list it's on.
245  *
246  * - layout is compatible with lws_dll (but lws_dll apis will not update the
247  * new stuff)
248  */
249 
250 
251 struct lws_dll2;
252 struct lws_dll2_owner;
253 
254 typedef struct lws_dll2 {
255  struct lws_dll2 *prev;
256  struct lws_dll2 *next;
257  struct lws_dll2_owner *owner;
258 } lws_dll2_t;
259 
260 typedef struct lws_dll2_owner {
261  struct lws_dll2 *tail;
262  struct lws_dll2 *head;
263 
264  uint32_t count;
266 
267 static LWS_INLINE int
268 lws_dll2_is_detached(const struct lws_dll2 *d) { return !d->owner; }
269 
270 static LWS_INLINE const struct lws_dll2_owner *
271 lws_dll2_owner(const struct lws_dll2 *d) { return d->owner; }
272 
273 static LWS_INLINE struct lws_dll2 *
274 lws_dll2_get_head(struct lws_dll2_owner *owner) { return owner->head; }
275 
276 static LWS_INLINE struct lws_dll2 *
277 lws_dll2_get_tail(struct lws_dll2_owner *owner) { return owner->tail; }
278 
279 LWS_VISIBLE LWS_EXTERN void
280 lws_dll2_add_head(struct lws_dll2 *d, struct lws_dll2_owner *owner);
281 
282 LWS_VISIBLE LWS_EXTERN void
283 lws_dll2_add_tail(struct lws_dll2 *d, struct lws_dll2_owner *owner);
284 
285 LWS_VISIBLE LWS_EXTERN void
286 lws_dll2_remove(struct lws_dll2 *d);
287 
288 LWS_VISIBLE LWS_EXTERN int
289 lws_dll2_foreach_safe(struct lws_dll2_owner *owner, void *user,
290  int (*cb)(struct lws_dll2 *d, void *user));
291 
292 LWS_VISIBLE LWS_EXTERN void
293 lws_dll2_clear(struct lws_dll2 *d);
294 
295 LWS_VISIBLE LWS_EXTERN void
296 lws_dll2_owner_clear(struct lws_dll2_owner *d);
297 
298 LWS_VISIBLE LWS_EXTERN void
299 lws_dll2_add_before(struct lws_dll2 *d, struct lws_dll2 *after);
300 
301 LWS_VISIBLE LWS_EXTERN void
302 lws_dll2_add_sorted(lws_dll2_t *d, lws_dll2_owner_t *own,
303  int (*compare)(const lws_dll2_t *d, const lws_dll2_t *i));
304 
305 #if defined(_DEBUG)
306 void
307 lws_dll2_describe(struct lws_dll2_owner *owner, const char *desc);
308 #else
309 #define lws_dll2_describe(x, y)
310 #endif
311 
312 /*
313  * these are safe against the current container object getting deleted,
314  * since the hold his next in a temp and go to that next. ___tmp is
315  * the temp.
316  */
317 
318 #define lws_start_foreach_dll_safe(___type, ___it, ___tmp, ___start) \
319 { \
320  ___type ___it = ___start; \
321  while (___it) { \
322  ___type ___tmp = (___it)->next;
323 
324 #define lws_end_foreach_dll_safe(___it, ___tmp) \
325  ___it = ___tmp; \
326  } \
327 }
328 
329 #define lws_start_foreach_dll(___type, ___it, ___start) \
330 { \
331  ___type ___it = ___start; \
332  while (___it) {
333 
334 #define lws_end_foreach_dll(___it) \
335  ___it = (___it)->next; \
336  } \
337 }
338 
339 struct lws_buflist;
340 
351 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
352 lws_buflist_append_segment(struct lws_buflist **head, const uint8_t *buf,
353  size_t len);
364 LWS_VISIBLE LWS_EXTERN size_t
365 lws_buflist_next_segment_len(struct lws_buflist **head, uint8_t **buf);
366 
382 LWS_VISIBLE LWS_EXTERN int
383 lws_buflist_use_segment(struct lws_buflist **head, size_t len);
384 
393 LWS_VISIBLE LWS_EXTERN void
394 lws_buflist_destroy_all_segments(struct lws_buflist **head);
395 
406 LWS_VISIBLE LWS_EXTERN void
407 lws_buflist_describe(struct lws_buflist **head, void *id, const char *reason);
408 
418 #define lws_ptr_diff(head, tail) \
419  ((int)((char *)(head) - (char *)(tail)))
420 
432 LWS_VISIBLE LWS_EXTERN int
433 lws_snprintf(char *str, size_t size, const char *format, ...) LWS_FORMAT(3);
434 
445 LWS_VISIBLE LWS_EXTERN char *
446 lws_strncpy(char *dest, const char *src, size_t size);
447 
464 LWS_VISIBLE LWS_EXTERN int
465 lws_hex_to_byte_array(const char *h, uint8_t *dest, int max);
466 
467 /*
468  * lws_timingsafe_bcmp(): constant time memcmp
469  *
470  * \param a: first buffer
471  * \param b: second buffer
472  * \param len: count of bytes to compare
473  *
474  * Return 0 if the two buffers are the same, else nonzero.
475  *
476  * Always compares all of the buffer before returning, so it can't be used as
477  * a timing oracle.
478  */
479 
480 LWS_VISIBLE LWS_EXTERN int
481 lws_timingsafe_bcmp(const void *a, const void *b, uint32_t len);
482 
493 LWS_VISIBLE LWS_EXTERN int
494 lws_get_random(struct lws_context *context, void *buf, int len);
502 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
503 lws_daemonize(const char *_lock_path);
509 LWS_VISIBLE LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT
511 
518 LWS_VISIBLE LWS_EXTERN void *
519 lws_wsi_user(struct lws *wsi);
520 
531 LWS_VISIBLE LWS_EXTERN void
532 lws_set_wsi_user(struct lws *wsi, void *user);
533 
556 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
557 lws_parse_uri(char *p, const char **prot, const char **ads, int *port,
558  const char **path);
576 LWS_VISIBLE LWS_EXTERN const char *
577 lws_cmdline_option(int argc, const char **argv, const char *val);
578 
582 LWS_VISIBLE LWS_EXTERN unsigned long
583 lws_now_secs(void);
584 
588 LWS_VISIBLE LWS_EXTERN lws_usec_t
589 lws_now_usecs(void);
590 
600 LWS_VISIBLE LWS_EXTERN struct lws_context * LWS_WARN_UNUSED_RESULT
601 lws_get_context(const struct lws *wsi);
602 
612 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
613 lws_get_vhost_listen_port(struct lws_vhost *vhost);
614 
624 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
625 lws_get_count_threads(struct lws_context *context);
626 
634 LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT
635 lws_get_parent(const struct lws *wsi);
636 
643 LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT
644 lws_get_child(const struct lws *wsi);
645 
658 LWS_VISIBLE LWS_EXTERN void
659 lws_get_effective_uid_gid(struct lws_context *context, int *uid, int *gid);
660 
668 LWS_VISIBLE LWS_EXTERN const struct lws_udp * LWS_WARN_UNUSED_RESULT
669 lws_get_udp(const struct lws *wsi);
670 
671 LWS_VISIBLE LWS_EXTERN void *
672 lws_get_opaque_parent_data(const struct lws *wsi);
673 
674 LWS_VISIBLE LWS_EXTERN void
675 lws_set_opaque_parent_data(struct lws *wsi, void *data);
676 
677 LWS_VISIBLE LWS_EXTERN void *
678 lws_get_opaque_user_data(const struct lws *wsi);
679 
680 LWS_VISIBLE LWS_EXTERN void
681 lws_set_opaque_user_data(struct lws *wsi, void *data);
682 
683 LWS_VISIBLE LWS_EXTERN int
684 lws_get_child_pending_on_writable(const struct lws *wsi);
685 
686 LWS_VISIBLE LWS_EXTERN void
687 lws_clear_child_pending_on_writable(struct lws *wsi);
688 
689 LWS_VISIBLE LWS_EXTERN int
690 lws_get_close_length(struct lws *wsi);
691 
692 LWS_VISIBLE LWS_EXTERN unsigned char *
693 lws_get_close_payload(struct lws *wsi);
694 
705 LWS_VISIBLE LWS_EXTERN
706 struct lws *lws_get_network_wsi(struct lws *wsi);
707 
715 LWS_VISIBLE LWS_EXTERN void
716 lws_set_allocator(void *(*realloc)(void *ptr, size_t size, const char *reason));
717 
718 enum {
719  /*
720  * Flags for enable and disable rxflow with reason bitmap and with
721  * backwards-compatible single bool
722  */
723  LWS_RXFLOW_REASON_USER_BOOL = (1 << 0),
724  LWS_RXFLOW_REASON_HTTP_RXBUFFER = (1 << 6),
725  LWS_RXFLOW_REASON_H2_PPS_PENDING = (1 << 7),
726 
727  LWS_RXFLOW_REASON_APPLIES = (1 << 14),
728  LWS_RXFLOW_REASON_APPLIES_ENABLE_BIT = (1 << 13),
729  LWS_RXFLOW_REASON_APPLIES_ENABLE = LWS_RXFLOW_REASON_APPLIES |
730  LWS_RXFLOW_REASON_APPLIES_ENABLE_BIT,
731  LWS_RXFLOW_REASON_APPLIES_DISABLE = LWS_RXFLOW_REASON_APPLIES,
732  LWS_RXFLOW_REASON_FLAG_PROCESS_NOW = (1 << 12),
733 
734 };
735 
755 LWS_VISIBLE LWS_EXTERN int
756 lws_rx_flow_control(struct lws *wsi, int enable);
757 
767 LWS_VISIBLE LWS_EXTERN void
768 lws_rx_flow_allow_all_protocol(const struct lws_context *context,
769  const struct lws_protocols *protocol);
770 
790 LWS_VISIBLE LWS_EXTERN size_t
791 lws_remaining_packet_payload(struct lws *wsi);
792 
793 #if defined(LWS_WITH_DIR)
794 
795 typedef enum {
796  LDOT_UNKNOWN,
797  LDOT_FILE,
798  LDOT_DIR,
799  LDOT_LINK,
800  LDOT_FIFO,
801  LDOTT_SOCKET,
802  LDOT_CHAR,
803  LDOT_BLOCK
804 } lws_dir_obj_type_t;
805 
806 struct lws_dir_entry {
807  const char *name;
808  lws_dir_obj_type_t type;
809 };
810 
811 typedef int
812 lws_dir_callback_function(const char *dirpath, void *user,
813  struct lws_dir_entry *lde);
814 
827 LWS_VISIBLE LWS_EXTERN int
828 lws_dir(const char *dirpath, void *user, lws_dir_callback_function cb);
829 #endif
830 
846 size_t lws_get_allocated_heap(void);
847 
856 LWS_VISIBLE LWS_EXTERN int
857 lws_is_ssl(struct lws *wsi);
863 LWS_VISIBLE LWS_EXTERN int
864 lws_is_cgi(struct lws *wsi);
865 
876 LWS_VISIBLE LWS_EXTERN int
877 lws_open(const char *__file, int __oflag, ...);
878 
879 struct lws_wifi_scan { /* generic wlan scan item */
880  struct lws_wifi_scan *next;
881  char ssid[32];
882  int32_t rssi; /* divide by .count to get db */
883  uint8_t bssid[6];
884  uint8_t count;
885  uint8_t channel;
886  uint8_t authmode;
887 };
888 
889 #if defined(LWS_WITH_TLS) && !defined(LWS_WITH_MBEDTLS)
890 
896 LWS_VISIBLE LWS_EXTERN SSL*
897 lws_get_ssl(struct lws *wsi);
898 #endif
899 
900 LWS_VISIBLE LWS_EXTERN void
901 lws_explicit_bzero(void *p, size_t len);
902 
903 typedef struct lws_humanize_unit {
904  const char *name; /* array ends with NULL name */
905  uint64_t factor;
907 
908 LWS_VISIBLE LWS_EXTERN const lws_humanize_unit_t humanize_schema_si[];
909 LWS_VISIBLE LWS_EXTERN const lws_humanize_unit_t humanize_schema_si_bytes[];
910 LWS_VISIBLE LWS_EXTERN const lws_humanize_unit_t humanize_schema_us[];
911 
933 LWS_VISIBLE LWS_EXTERN int
934 lws_humanize(char *buf, int len, uint64_t value,
935  const lws_humanize_unit_t *schema);
936 
937 
938 LWS_VISIBLE LWS_EXTERN void
939 lws_ser_wu16be(uint8_t *b, uint16_t u);
940 
941 LWS_VISIBLE LWS_EXTERN void
942 lws_ser_wu32be(uint8_t *b, uint32_t u32);
943 
944 LWS_VISIBLE LWS_EXTERN void
945 lws_ser_wu64be(uint8_t *b, uint64_t u64);
946 
947 LWS_VISIBLE LWS_EXTERN uint16_t
948 lws_ser_ru16be(const uint8_t *b);
949 
950 LWS_VISIBLE LWS_EXTERN uint32_t
951 lws_ser_ru32be(const uint8_t *b);
952 
953 LWS_VISIBLE LWS_EXTERN uint64_t
954 lws_ser_ru64be(const uint8_t *b);
955 
956 int
957 lws_vbi_encode(uint64_t value, void *buf);
958 
959 int
960 lws_vbi_decode(const void *buf, uint64_t *value, size_t len);
961 
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_daemonize(const char *_lock_path)
LWS_VISIBLE LWS_EXTERN const char * lws_cmdline_option(int argc, const char **argv, const char *val)
Definition: lws-misc.h:903
LWS_VISIBLE LWS_EXTERN size_t lws_remaining_packet_payload(struct lws *wsi)
LWS_VISIBLE LWS_EXTERN struct lws *LWS_WARN_UNUSED_RESULT lws_get_parent(const struct lws *wsi)
LWS_VISIBLE LWS_EXTERN void lws_rx_flow_allow_all_protocol(const struct lws_context *context, const struct lws_protocols *protocol)
LWS_VISIBLE LWS_EXTERN const char *LWS_WARN_UNUSED_RESULT lws_get_library_version(void)
LWS_VISIBLE LWS_EXTERN struct lws_context *LWS_WARN_UNUSED_RESULT lws_get_context(const struct lws *wsi)
LWS_VISIBLE LWS_EXTERN int lws_snprintf(char *str, size_t size, const char *format,...) LWS_FORMAT(3)
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_buflist_append_segment(struct lws_buflist **head, const uint8_t *buf, size_t len)
Definition: lws-misc.h:260
Definition: lws-misc.h:879
LWS_VISIBLE LWS_EXTERN void lws_get_effective_uid_gid(struct lws_context *context, int *uid, int *gid)
LWS_VISIBLE LWS_EXTERN size_t lws_buflist_next_segment_len(struct lws_buflist **head, uint8_t **buf)
LWS_VISIBLE LWS_EXTERN struct lws * lws_get_network_wsi(struct lws *wsi)
LWS_VISIBLE LWS_EXTERN struct lws *LWS_WARN_UNUSED_RESULT lws_get_child(const struct lws *wsi)
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_get_count_threads(struct lws_context *context)
LWS_VISIBLE LWS_EXTERN void lws_buflist_describe(struct lws_buflist **head, void *id, const char *reason)
Definition: lws-adopt.h:83
LWS_VISIBLE LWS_EXTERN void * lws_wsi_user(struct lws *wsi)
LWS_VISIBLE LWS_EXTERN unsigned long lws_now_secs(void)
LWS_VISIBLE LWS_EXTERN int lws_open(const char *__file, int __oflag,...)
LWS_VISIBLE LWS_EXTERN int lws_humanize(char *buf, int len, uint64_t value, const lws_humanize_unit_t *schema)
Definition: lws-misc.h:254
LWS_VISIBLE LWS_EXTERN int lws_hex_to_byte_array(const char *h, uint8_t *dest, int max)
Definition: lws-protocols-plugins.h:44
LWS_VISIBLE LWS_EXTERN int lws_get_random(struct lws_context *context, void *buf, int len)
LWS_VISIBLE LWS_EXTERN int lws_rx_flow_control(struct lws *wsi, int enable)
LWS_VISIBLE LWS_EXTERN void lws_set_allocator(void *(*realloc)(void *ptr, size_t size, const char *reason))
LWS_VISIBLE LWS_EXTERN int lws_buflist_use_segment(struct lws_buflist **head, size_t len)
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_parse_uri(char *p, const char **prot, const char **ads, int *port, const char **path)
LWS_VISIBLE LWS_EXTERN int lws_is_cgi(struct lws *wsi)
LWS_VISIBLE LWS_EXTERN char * lws_strncpy(char *dest, const char *src, size_t size)
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_get_vhost_listen_port(struct lws_vhost *vhost)
LWS_VISIBLE LWS_EXTERN int lws_is_ssl(struct lws *wsi)
LWS_VISIBLE LWS_EXTERN const struct lws_udp *LWS_WARN_UNUSED_RESULT lws_get_udp(const struct lws *wsi)
LWS_VISIBLE LWS_EXTERN void lws_set_wsi_user(struct lws *wsi, void *user)
LWS_VISIBLE LWS_EXTERN void lws_buflist_destroy_all_segments(struct lws_buflist **head)
LWS_VISIBLE LWS_EXTERN lws_usec_t lws_now_usecs(void)
size_t lws_get_allocated_heap(void)