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-2018 Andy Green <andy@warmcat.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation:
9  * version 2.1 of the License.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301 USA
20  *
21  * included from libwebsockets.h
22  */
23 
30 
43 #define lws_start_foreach_ll(type, it, start)\
44 { \
45  type it = start; \
46  while (it) {
47 
58 #define lws_end_foreach_ll(it, nxt) \
59  it = it->nxt; \
60  } \
61 }
62 
78 #define lws_start_foreach_ll_safe(type, it, start, nxt)\
79 { \
80  type it = start; \
81  while (it) { \
82  type next_##it = it->nxt;
83 
94 #define lws_end_foreach_ll_safe(it) \
95  it = next_##it; \
96  } \
97 }
98 
115 #define lws_start_foreach_llp(type, it, start)\
116 { \
117  type it = &(start); \
118  while (*(it)) {
119 
120 #define lws_start_foreach_llp_safe(type, it, start, nxt)\
121 { \
122  type it = &(start); \
123  type next; \
124  while (*(it)) { \
125  next = &((*(it))->nxt); \
126 
137 #define lws_end_foreach_llp(it, nxt) \
138  it = &(*(it))->nxt; \
139  } \
140 }
141 
142 #define lws_end_foreach_llp_safe(it) \
143  it = next; \
144  } \
145 }
146 
147 #define lws_ll_fwd_insert(\
148  ___new_object, /* pointer to new object */ \
149  ___m_list, /* member for next list object ptr */ \
150  ___list_head /* list head */ \
151  ) {\
152  ___new_object->___m_list = ___list_head; \
153  ___list_head = ___new_object; \
154  }
155 
156 #define lws_ll_fwd_remove(\
157  ___type, /* type of listed object */ \
158  ___m_list, /* member for next list object ptr */ \
159  ___target, /* object to remove from list */ \
160  ___list_head /* list head */ \
161  ) { \
162  lws_start_foreach_llp(___type **, ___ppss, ___list_head) { \
163  if (*___ppss == ___target) { \
164  *___ppss = ___target->___m_list; \
165  break; \
166  } \
167  } lws_end_foreach_llp(___ppss, ___m_list); \
168  }
169 
170 /*
171  * doubly linked-list
172  */
173 
174 #if defined (LWS_WITH_DEPRECATED_LWS_DLL)
175 
176 /*
177  * This is going away in v4.1. You can set the cmake option above to keep it
178  * around temporarily. Migrate your stuff to the more capable and robust
179  * lws_dll2 below
180  */
181 
182 struct lws_dll {
183  struct lws_dll *prev;
184  struct lws_dll *next;
185 };
186 
187 /*
188  * these all point to the composed list objects... you have to use the
189  * lws_container_of() helper to recover the start of the containing struct
190  */
191 
192 #define lws_dll_add_front lws_dll_add_head
193 
194 LWS_VISIBLE LWS_EXTERN void
195 lws_dll_add_head(struct lws_dll *d, struct lws_dll *phead);
196 
197 LWS_VISIBLE LWS_EXTERN void
198 lws_dll_add_tail(struct lws_dll *d, struct lws_dll *phead);
199 
200 LWS_VISIBLE LWS_EXTERN void
201 lws_dll_insert(struct lws_dll *d, struct lws_dll *target,
202  struct lws_dll *phead, int before);
203 
204 static LWS_INLINE struct lws_dll *
205 lws_dll_get_head(struct lws_dll *phead) { return phead->next; }
206 
207 static LWS_INLINE struct lws_dll *
208 lws_dll_get_tail(struct lws_dll *phead) { return phead->prev; }
209 
210 /*
211  * caution, this doesn't track the tail in the head struct. Use
212  * lws_dll_remove_track_tail() instead of this if you want tail tracking. Using
213  * this means you can't use lws_dll_add_tail() amd
214  */
215 LWS_VISIBLE LWS_EXTERN void
216 lws_dll_remove(struct lws_dll *d) LWS_WARN_DEPRECATED;
217 
218 LWS_VISIBLE LWS_EXTERN void
219 lws_dll_remove_track_tail(struct lws_dll *d, struct lws_dll *phead);
220 
221 /* another way to do lws_start_foreach_dll_safe() on a list via a cb */
222 
223 LWS_VISIBLE LWS_EXTERN int
224 lws_dll_foreach_safe(struct lws_dll *phead, void *user,
225  int (*cb)(struct lws_dll *d, void *user));
226 
227 #define lws_dll_is_detached(___dll, __head) \
228  (!(___dll)->prev && !(___dll)->next && (__head)->prev != (___dll))
229 
230 #endif
231 
232 /*
233  * lws_dll2_owner / lws_dll2 : more capable version of lws_dll. Differences:
234  *
235  * - there's an explicit lws_dll2_owner struct which holds head, tail and
236  * count of members.
237  *
238  * - list members all hold a pointer to their owner. So user code does not
239  * have to track anything about exactly what lws_dll2_owner list the object
240  * is a member of.
241  *
242  * - you can use lws_dll unless you want the member count or the ability to
243  * not track exactly which list it's on.
244  *
245  * - layout is compatible with lws_dll (but lws_dll apis will not update the
246  * new stuff)
247  */
248 
249 
250 struct lws_dll2;
251 struct lws_dll2_owner;
252 
253 typedef struct lws_dll2 {
254  struct lws_dll2 *prev;
255  struct lws_dll2 *next;
256  struct lws_dll2_owner *owner;
257 } lws_dll2_t;
258 
259 typedef struct lws_dll2_owner {
260  struct lws_dll2 *tail;
261  struct lws_dll2 *head;
262 
263  uint32_t count;
265 
266 static LWS_INLINE int
267 lws_dll2_is_detached(const struct lws_dll2 *d) { return !d->owner; }
268 
269 static LWS_INLINE const struct lws_dll2_owner *
270 lws_dll2_owner(const struct lws_dll2 *d) { return d->owner; }
271 
272 static LWS_INLINE struct lws_dll2 *
273 lws_dll2_get_head(struct lws_dll2_owner *owner) { return owner->head; }
274 
275 static LWS_INLINE struct lws_dll2 *
276 lws_dll2_get_tail(struct lws_dll2_owner *owner) { return owner->tail; }
277 
278 LWS_VISIBLE LWS_EXTERN void
279 lws_dll2_add_head(struct lws_dll2 *d, struct lws_dll2_owner *owner);
280 
281 LWS_VISIBLE LWS_EXTERN void
282 lws_dll2_add_tail(struct lws_dll2 *d, struct lws_dll2_owner *owner);
283 
284 LWS_VISIBLE LWS_EXTERN void
285 lws_dll2_remove(struct lws_dll2 *d);
286 
287 LWS_VISIBLE LWS_EXTERN int
288 lws_dll2_foreach_safe(struct lws_dll2_owner *owner, void *user,
289  int (*cb)(struct lws_dll2 *d, void *user));
290 
291 LWS_VISIBLE LWS_EXTERN void
292 lws_dll2_clear(struct lws_dll2 *d);
293 
294 LWS_VISIBLE LWS_EXTERN void
295 lws_dll2_owner_clear(struct lws_dll2_owner *d);
296 
297 LWS_VISIBLE LWS_EXTERN void
298 lws_dll2_add_before(struct lws_dll2 *d, struct lws_dll2 *after);
299 
300 LWS_VISIBLE LWS_EXTERN void
301 lws_dll2_add_sorted(lws_dll2_t *d, lws_dll2_owner_t *own,
302  int (*compare)(const lws_dll2_t *d, const lws_dll2_t *i));
303 
304 #if defined(_DEBUG)
305 void
306 lws_dll2_describe(struct lws_dll2_owner *owner, const char *desc);
307 #else
308 #define lws_dll2_describe(x, y)
309 #endif
310 
311 /*
312  * these are safe against the current container object getting deleted,
313  * since the hold his next in a temp and go to that next. ___tmp is
314  * the temp.
315  */
316 
317 #define lws_start_foreach_dll_safe(___type, ___it, ___tmp, ___start) \
318 { \
319  ___type ___it = ___start; \
320  while (___it) { \
321  ___type ___tmp = (___it)->next;
322 
323 #define lws_end_foreach_dll_safe(___it, ___tmp) \
324  ___it = ___tmp; \
325  } \
326 }
327 
328 #define lws_start_foreach_dll(___type, ___it, ___start) \
329 { \
330  ___type ___it = ___start; \
331  while (___it) {
332 
333 #define lws_end_foreach_dll(___it) \
334  ___it = (___it)->next; \
335  } \
336 }
337 
338 struct lws_buflist;
339 
350 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
351 lws_buflist_append_segment(struct lws_buflist **head, const uint8_t *buf,
352  size_t len);
363 LWS_VISIBLE LWS_EXTERN size_t
364 lws_buflist_next_segment_len(struct lws_buflist **head, uint8_t **buf);
365 
381 LWS_VISIBLE LWS_EXTERN int
382 lws_buflist_use_segment(struct lws_buflist **head, size_t len);
383 
392 LWS_VISIBLE LWS_EXTERN void
393 lws_buflist_destroy_all_segments(struct lws_buflist **head);
394 
395 void
396 lws_buflist_describe(struct lws_buflist **head, void *id);
397 
407 #define lws_ptr_diff(head, tail) \
408  ((int)((char *)(head) - (char *)(tail)))
409 
421 LWS_VISIBLE LWS_EXTERN int
422 lws_snprintf(char *str, size_t size, const char *format, ...) LWS_FORMAT(3);
423 
434 LWS_VISIBLE LWS_EXTERN char *
435 lws_strncpy(char *dest, const char *src, size_t size);
436 
453 LWS_VISIBLE LWS_EXTERN int
454 lws_hex_to_byte_array(const char *h, uint8_t *dest, int max);
455 
456 /*
457  * lws_timingsafe_bcmp(): constant time memcmp
458  *
459  * \param a: first buffer
460  * \param b: second buffer
461  * \param len: count of bytes to compare
462  *
463  * Return 0 if the two buffers are the same, else nonzero.
464  *
465  * Always compares all of the buffer before returning, so it can't be used as
466  * a timing oracle.
467  */
468 
469 LWS_VISIBLE LWS_EXTERN int
470 lws_timingsafe_bcmp(const void *a, const void *b, uint32_t len);
471 
482 LWS_VISIBLE LWS_EXTERN int
483 lws_get_random(struct lws_context *context, void *buf, int len);
491 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
492 lws_daemonize(const char *_lock_path);
498 LWS_VISIBLE LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT
500 
507 LWS_VISIBLE LWS_EXTERN void *
508 lws_wsi_user(struct lws *wsi);
509 
520 LWS_VISIBLE LWS_EXTERN void
521 lws_set_wsi_user(struct lws *wsi, void *user);
522 
545 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
546 lws_parse_uri(char *p, const char **prot, const char **ads, int *port,
547  const char **path);
565 LWS_VISIBLE LWS_EXTERN const char *
566 lws_cmdline_option(int argc, const char **argv, const char *val);
567 
571 LWS_VISIBLE LWS_EXTERN unsigned long
573 
577 LWS_VISIBLE LWS_EXTERN lws_usec_t
579 
589 LWS_VISIBLE LWS_EXTERN struct lws_context * LWS_WARN_UNUSED_RESULT
590 lws_get_context(const struct lws *wsi);
591 
601 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
602 lws_get_vhost_listen_port(struct lws_vhost *vhost);
603 
613 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
614 lws_get_count_threads(struct lws_context *context);
615 
623 LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT
624 lws_get_parent(const struct lws *wsi);
625 
632 LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT
633 lws_get_child(const struct lws *wsi);
634 
647 LWS_VISIBLE LWS_EXTERN void
648 lws_get_effective_uid_gid(struct lws_context *context, int *uid, int *gid);
649 
657 LWS_VISIBLE LWS_EXTERN const struct lws_udp * LWS_WARN_UNUSED_RESULT
658 lws_get_udp(const struct lws *wsi);
659 
660 LWS_VISIBLE LWS_EXTERN void *
661 lws_get_opaque_parent_data(const struct lws *wsi);
662 
663 LWS_VISIBLE LWS_EXTERN void
664 lws_set_opaque_parent_data(struct lws *wsi, void *data);
665 
666 LWS_VISIBLE LWS_EXTERN void *
667 lws_get_opaque_user_data(const struct lws *wsi);
668 
669 LWS_VISIBLE LWS_EXTERN void
670 lws_set_opaque_user_data(struct lws *wsi, void *data);
671 
672 LWS_VISIBLE LWS_EXTERN int
673 lws_get_child_pending_on_writable(const struct lws *wsi);
674 
675 LWS_VISIBLE LWS_EXTERN void
676 lws_clear_child_pending_on_writable(struct lws *wsi);
677 
678 LWS_VISIBLE LWS_EXTERN int
679 lws_get_close_length(struct lws *wsi);
680 
681 LWS_VISIBLE LWS_EXTERN unsigned char *
682 lws_get_close_payload(struct lws *wsi);
683 
694 LWS_VISIBLE LWS_EXTERN
695 struct lws *lws_get_network_wsi(struct lws *wsi);
696 
704 LWS_VISIBLE LWS_EXTERN void
705 lws_set_allocator(void *(*realloc)(void *ptr, size_t size, const char *reason));
706 
707 enum {
708  /*
709  * Flags for enable and disable rxflow with reason bitmap and with
710  * backwards-compatible single bool
711  */
712  LWS_RXFLOW_REASON_USER_BOOL = (1 << 0),
713  LWS_RXFLOW_REASON_HTTP_RXBUFFER = (1 << 6),
714  LWS_RXFLOW_REASON_H2_PPS_PENDING = (1 << 7),
715 
716  LWS_RXFLOW_REASON_APPLIES = (1 << 14),
717  LWS_RXFLOW_REASON_APPLIES_ENABLE_BIT = (1 << 13),
718  LWS_RXFLOW_REASON_APPLIES_ENABLE = LWS_RXFLOW_REASON_APPLIES |
719  LWS_RXFLOW_REASON_APPLIES_ENABLE_BIT,
720  LWS_RXFLOW_REASON_APPLIES_DISABLE = LWS_RXFLOW_REASON_APPLIES,
721  LWS_RXFLOW_REASON_FLAG_PROCESS_NOW = (1 << 12),
722 
723 };
724 
744 LWS_VISIBLE LWS_EXTERN int
745 lws_rx_flow_control(struct lws *wsi, int enable);
746 
756 LWS_VISIBLE LWS_EXTERN void
757 lws_rx_flow_allow_all_protocol(const struct lws_context *context,
758  const struct lws_protocols *protocol);
759 
779 LWS_VISIBLE LWS_EXTERN size_t
781 
782 #if defined(LWS_WITH_DIR)
783 
784 typedef enum {
785  LDOT_UNKNOWN,
786  LDOT_FILE,
787  LDOT_DIR,
788  LDOT_LINK,
789  LDOT_FIFO,
790  LDOTT_SOCKET,
791  LDOT_CHAR,
792  LDOT_BLOCK
793 } lws_dir_obj_type_t;
794 
795 struct lws_dir_entry {
796  const char *name;
797  lws_dir_obj_type_t type;
798 };
799 
800 typedef int
801 lws_dir_callback_function(const char *dirpath, void *user,
802  struct lws_dir_entry *lde);
803 
816 LWS_VISIBLE LWS_EXTERN int
817 lws_dir(const char *dirpath, void *user, lws_dir_callback_function cb);
818 #endif
819 
836 
845 LWS_VISIBLE LWS_EXTERN int
846 lws_is_ssl(struct lws *wsi);
852 LWS_VISIBLE LWS_EXTERN int
853 lws_is_cgi(struct lws *wsi);
854 
865 LWS_VISIBLE LWS_EXTERN int
866 lws_open(const char *__file, int __oflag, ...);
867 
868 struct lws_wifi_scan { /* generic wlan scan item */
869  struct lws_wifi_scan *next;
870  char ssid[32];
871  int32_t rssi; /* divide by .count to get db */
872  uint8_t bssid[6];
873  uint8_t count;
874  uint8_t channel;
875  uint8_t authmode;
876 };
877 
878 #if defined(LWS_WITH_TLS) && !defined(LWS_WITH_MBEDTLS)
885 LWS_VISIBLE LWS_EXTERN SSL*
886 lws_get_ssl(struct lws *wsi);
887 #endif
888 
889 LWS_VISIBLE LWS_EXTERN void
890 lws_explicit_bzero(void *p, size_t len);
891 
892 typedef struct lws_humanize_unit {
893  const char *name; /* array ends with NULL name */
894  uint64_t factor;
896 
897 LWS_VISIBLE LWS_EXTERN const lws_humanize_unit_t humanize_schema_si[7];
898 LWS_VISIBLE LWS_EXTERN const lws_humanize_unit_t humanize_schema_si_bytes[7];
899 LWS_VISIBLE LWS_EXTERN const lws_humanize_unit_t humanize_schema_us[8];
900 
922 LWS_VISIBLE LWS_EXTERN int
923 lws_humanize(char *buf, int len, uint64_t value,
924  const lws_humanize_unit_t *schema);
925 
LWS_VISIBLE LWS_EXTERN int lws_hex_to_byte_array(const char *h, uint8_t *dest, int max)
LWS_VISIBLE LWS_EXTERN struct lws_context *LWS_WARN_UNUSED_RESULT lws_get_context(const struct lws *wsi)
LWS_VISIBLE LWS_EXTERN int lws_open(const char *__file, int __oflag,...)
LWS_VISIBLE LWS_EXTERN lws_usec_t lws_now_usecs(void)
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_buflist_use_segment(struct lws_buflist **head, size_t len)
LWS_VISIBLE LWS_EXTERN int lws_snprintf(char *str, size_t size, const char *format,...) LWS_FORMAT(3)
LWS_VISIBLE LWS_EXTERN char * lws_strncpy(char *dest, const char *src, size_t size)
LWS_VISIBLE LWS_EXTERN int lws_is_ssl(struct lws *wsi)
LWS_VISIBLE LWS_EXTERN unsigned long lws_now_secs(void)
LWS_VISIBLE LWS_EXTERN void lws_get_effective_uid_gid(struct lws_context *context, int *uid, int *gid)
LWS_VISIBLE LWS_EXTERN int lws_is_cgi(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 int lws_get_random(struct lws_context *context, void *buf, int len)
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 size_t lws_buflist_next_segment_len(struct lws_buflist **head, uint8_t **buf)
size_t lws_get_allocated_heap(void)
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_get_count_threads(struct lws_context *context)
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_get_vhost_listen_port(struct lws_vhost *vhost)
LWS_VISIBLE LWS_EXTERN size_t lws_remaining_packet_payload(struct lws *wsi)
LWS_VISIBLE LWS_EXTERN const char * lws_cmdline_option(int argc, const char **argv, const char *val)
LWS_VISIBLE LWS_EXTERN struct lws *LWS_WARN_UNUSED_RESULT lws_get_parent(const struct lws *wsi)
LWS_VISIBLE LWS_EXTERN void lws_set_wsi_user(struct lws *wsi, void *user)
LWS_VISIBLE LWS_EXTERN int lws_humanize(char *buf, int len, uint64_t value, const lws_humanize_unit_t *schema)
LWS_VISIBLE LWS_EXTERN struct lws * lws_get_network_wsi(struct lws *wsi)
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_buflist_append_segment(struct lws_buflist **head, const uint8_t *buf, size_t len)
LWS_VISIBLE LWS_EXTERN void * lws_wsi_user(struct lws *wsi)
LWS_VISIBLE LWS_EXTERN const char *LWS_WARN_UNUSED_RESULT lws_get_library_version(void)
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_daemonize(const char *_lock_path)
LWS_VISIBLE LWS_EXTERN void lws_set_allocator(void *(*realloc)(void *ptr, size_t size, const char *reason))
LWS_VISIBLE LWS_EXTERN int lws_rx_flow_control(struct lws *wsi, int enable)
LWS_VISIBLE LWS_EXTERN void lws_buflist_destroy_all_segments(struct lws_buflist **head)
Definition: lws-misc.h:259
Definition: lws-misc.h:253
Definition: lws-misc.h:892
Definition: lws-protocols-plugins.h:43
Definition: lws-adopt.h:82
Definition: lws-misc.h:868