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 - 2021 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 
25 #if defined(LWS_WITH_SPAWN)
26 
27 #if defined(WIN32) || defined(_WIN32)
28 #else
29 #include <sys/wait.h>
30 #include <sys/times.h>
31 #endif
32 #endif
33 
34 #if defined(__OpenBSD__)
35 #include <sys/siginfo.h>
36 #endif
37 
44 
45 struct lws_buflist;
46 
57 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
58 lws_buflist_append_segment(struct lws_buflist **head, const uint8_t *buf,
59  size_t len);
70 LWS_VISIBLE LWS_EXTERN size_t
71 lws_buflist_next_segment_len(struct lws_buflist **head, uint8_t **buf);
72 
88 LWS_VISIBLE LWS_EXTERN size_t
89 lws_buflist_use_segment(struct lws_buflist **head, size_t len);
90 
98 LWS_VISIBLE LWS_EXTERN size_t
99 lws_buflist_total_len(struct lws_buflist **head);
100 
112 LWS_VISIBLE LWS_EXTERN int
113 lws_buflist_linear_copy(struct lws_buflist **head, size_t ofs, uint8_t *buf,
114  size_t len);
115 
132 LWS_VISIBLE LWS_EXTERN int
133 lws_buflist_linear_use(struct lws_buflist **head, uint8_t *buf, size_t len);
134 
153 LWS_VISIBLE LWS_EXTERN int
154 lws_buflist_fragment_use(struct lws_buflist **head, uint8_t *buf,
155  size_t len, char *frag_first, char *frag_fin);
156 
165 LWS_VISIBLE LWS_EXTERN void
166 lws_buflist_destroy_all_segments(struct lws_buflist **head);
167 
178 LWS_VISIBLE LWS_EXTERN void
179 lws_buflist_describe(struct lws_buflist **head, void *id, const char *reason);
180 
190 #define lws_ptr_diff(head, tail) \
191  ((int)((char *)(head) - (char *)(tail)))
192 
193 #define lws_ptr_diff_size_t(head, tail) \
194  ((size_t)(ssize_t)((char *)(head) - (char *)(tail)))
195 
207 LWS_VISIBLE LWS_EXTERN int
208 lws_snprintf(char *str, size_t size, const char *format, ...) LWS_FORMAT(3);
209 
220 LWS_VISIBLE LWS_EXTERN char *
221 lws_strncpy(char *dest, const char *src, size_t size);
222 
223 /*
224  * Variation where we want to use the smaller of two lengths, useful when the
225  * source string is not NUL terminated
226  */
227 #define lws_strnncpy(dest, src, size1, destsize) \
228  lws_strncpy(dest, src, (size_t)(size1 + 1) < (size_t)(destsize) ? \
229  (size_t)(size1 + 1) : (size_t)(destsize))
230 
244 LWS_VISIBLE LWS_EXTERN const char *
245 lws_nstrstr(const char *buf, size_t len, const char *name, size_t nl);
246 
269 LWS_VISIBLE LWS_EXTERN const char *
270 lws_json_simple_find(const char *buf, size_t len, const char *name, size_t *alen);
271 
289 LWS_VISIBLE LWS_EXTERN int
290 lws_json_simple_strcmp(const char *buf, size_t len, const char *name, const char *comp);
291 
292 
309 LWS_VISIBLE LWS_EXTERN int
310 lws_hex_to_byte_array(const char *h, uint8_t *dest, int max);
311 
323 LWS_VISIBLE LWS_EXTERN void
324 lws_hex_from_byte_array(const uint8_t *src, size_t slen, char *dest, size_t len);
325 
339 LWS_VISIBLE LWS_EXTERN int
340 lws_hex_random(struct lws_context *context, char *dest, size_t len);
341 
342 /*
343  * lws_timingsafe_bcmp(): constant time memcmp
344  *
345  * \param a: first buffer
346  * \param b: second buffer
347  * \param len: count of bytes to compare
348  *
349  * Return 0 if the two buffers are the same, else nonzero.
350  *
351  * Always compares all of the buffer before returning, so it can't be used as
352  * a timing oracle.
353  */
354 
355 LWS_VISIBLE LWS_EXTERN int
356 lws_timingsafe_bcmp(const void *a, const void *b, uint32_t len);
357 
368 LWS_VISIBLE LWS_EXTERN size_t
369 lws_get_random(struct lws_context *context, void *buf, size_t len);
377 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
378 lws_daemonize(const char *_lock_path);
384 LWS_VISIBLE LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT
386 
393 LWS_VISIBLE LWS_EXTERN void *
394 lws_wsi_user(struct lws *wsi);
395 
402 LWS_VISIBLE LWS_EXTERN int
403 lws_wsi_tsi(struct lws *wsi);
404 
415 LWS_VISIBLE LWS_EXTERN void
416 lws_set_wsi_user(struct lws *wsi, void *user);
417 
440 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
441 lws_parse_uri(char *p, const char **prot, const char **ads, int *port,
442  const char **path);
460 LWS_VISIBLE LWS_EXTERN const char *
461 lws_cmdline_option(int argc, const char **argv, const char *val);
462 
475 LWS_VISIBLE LWS_EXTERN void
476 lws_cmdline_option_handle_builtin(int argc, const char **argv,
477  struct lws_context_creation_info *info);
478 
482 LWS_VISIBLE LWS_EXTERN unsigned long
484 
488 LWS_VISIBLE LWS_EXTERN lws_usec_t
490 
500 LWS_VISIBLE LWS_EXTERN struct lws_context * LWS_WARN_UNUSED_RESULT
501 lws_get_context(const struct lws *wsi);
502 
512 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
513 lws_get_vhost_listen_port(struct lws_vhost *vhost);
514 
524 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
525 lws_get_count_threads(struct lws_context *context);
526 
534 LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT
535 lws_get_parent(const struct lws *wsi);
536 
543 LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT
544 lws_get_child(const struct lws *wsi);
545 
558 LWS_VISIBLE LWS_EXTERN void
559 lws_get_effective_uid_gid(struct lws_context *context, uid_t *uid, gid_t *gid);
560 
568 LWS_VISIBLE LWS_EXTERN const struct lws_udp * LWS_WARN_UNUSED_RESULT
569 lws_get_udp(const struct lws *wsi);
570 
571 LWS_VISIBLE LWS_EXTERN void *
572 lws_get_opaque_parent_data(const struct lws *wsi);
573 
574 LWS_VISIBLE LWS_EXTERN void
575 lws_set_opaque_parent_data(struct lws *wsi, void *data);
576 
577 LWS_VISIBLE LWS_EXTERN void *
578 lws_get_opaque_user_data(const struct lws *wsi);
579 
580 LWS_VISIBLE LWS_EXTERN void
581 lws_set_opaque_user_data(struct lws *wsi, void *data);
582 
583 LWS_VISIBLE LWS_EXTERN int
584 lws_get_child_pending_on_writable(const struct lws *wsi);
585 
586 LWS_VISIBLE LWS_EXTERN void
587 lws_clear_child_pending_on_writable(struct lws *wsi);
588 
589 LWS_VISIBLE LWS_EXTERN int
590 lws_get_close_length(struct lws *wsi);
591 
592 LWS_VISIBLE LWS_EXTERN unsigned char *
593 lws_get_close_payload(struct lws *wsi);
594 
605 LWS_VISIBLE LWS_EXTERN
606 struct lws *lws_get_network_wsi(struct lws *wsi);
607 
615 LWS_VISIBLE LWS_EXTERN void
616 lws_set_allocator(void *(*realloc)(void *ptr, size_t size, const char *reason));
617 
618 enum {
619  /*
620  * Flags for enable and disable rxflow with reason bitmap and with
621  * backwards-compatible single bool
622  */
623  LWS_RXFLOW_REASON_USER_BOOL = (1 << 0),
624  LWS_RXFLOW_REASON_HTTP_RXBUFFER = (1 << 6),
625  LWS_RXFLOW_REASON_H2_PPS_PENDING = (1 << 7),
626 
627  LWS_RXFLOW_REASON_APPLIES = (1 << 14),
628  LWS_RXFLOW_REASON_APPLIES_ENABLE_BIT = (1 << 13),
629  LWS_RXFLOW_REASON_APPLIES_ENABLE = LWS_RXFLOW_REASON_APPLIES |
630  LWS_RXFLOW_REASON_APPLIES_ENABLE_BIT,
631  LWS_RXFLOW_REASON_APPLIES_DISABLE = LWS_RXFLOW_REASON_APPLIES,
632  LWS_RXFLOW_REASON_FLAG_PROCESS_NOW = (1 << 12),
633 
634 };
635 
655 LWS_VISIBLE LWS_EXTERN int
656 lws_rx_flow_control(struct lws *wsi, int enable);
657 
667 LWS_VISIBLE LWS_EXTERN void
668 lws_rx_flow_allow_all_protocol(const struct lws_context *context,
669  const struct lws_protocols *protocol);
670 
690 LWS_VISIBLE LWS_EXTERN size_t
692 
693 #if defined(LWS_WITH_DIR)
694 
695 typedef enum {
696  LDOT_UNKNOWN,
697  LDOT_FILE,
698  LDOT_DIR,
699  LDOT_LINK,
700  LDOT_FIFO,
701  LDOTT_SOCKET,
702  LDOT_CHAR,
703  LDOT_BLOCK
704 } lws_dir_obj_type_t;
705 
706 struct lws_dir_entry {
707  const char *name;
708  lws_dir_obj_type_t type;
709 };
710 
711 typedef int
712 lws_dir_callback_function(const char *dirpath, void *user,
713  struct lws_dir_entry *lde);
714 
727 LWS_VISIBLE LWS_EXTERN int
728 lws_dir(const char *dirpath, void *user, lws_dir_callback_function cb);
729 
741 LWS_VISIBLE LWS_EXTERN int
742 lws_dir_rm_rf_cb(const char *dirpath, void *user, struct lws_dir_entry *lde);
743 
744 /*
745  * We pass every file in the base dir through a filter, and call back on the
746  * ones that match. Directories are ignored.
747  *
748  * The original path filter string may look like, eg, "sai-*.deb" or "*.txt"
749  */
750 
751 typedef int (*lws_dir_glob_cb_t)(void *data, const char *path);
752 
753 typedef struct lws_dir_glob {
754  const char *filter;
755  lws_dir_glob_cb_t cb;
756  void *user;
757 } lws_dir_glob_t;
758 
773 LWS_VISIBLE LWS_EXTERN int
774 lws_dir_glob_cb(const char *dirpath, void *user, struct lws_dir_entry *lde);
775 
776 #endif
777 
794 
801 LWS_VISIBLE LWS_EXTERN int
802 lws_get_tsi(struct lws *wsi);
803 
810 LWS_VISIBLE LWS_EXTERN int
811 lws_is_ssl(struct lws *wsi);
817 LWS_VISIBLE LWS_EXTERN int
818 lws_is_cgi(struct lws *wsi);
819 
830 LWS_VISIBLE LWS_EXTERN int
831 lws_open(const char *__file, int __oflag, ...);
832 
833 struct lws_wifi_scan { /* generic wlan scan item */
834  struct lws_wifi_scan *next;
835  char ssid[32];
836  int32_t rssi; /* divide by .count to get db */
837  uint8_t bssid[6];
838  uint8_t count;
839  uint8_t channel;
840  uint8_t authmode;
841 };
842 
843 #if defined(LWS_WITH_TLS) && !defined(LWS_WITH_MBEDTLS)
850 LWS_VISIBLE LWS_EXTERN SSL*
851 lws_get_ssl(struct lws *wsi);
852 #endif
853 
854 LWS_VISIBLE LWS_EXTERN void
855 lws_explicit_bzero(void *p, size_t len);
856 
857 typedef struct lws_humanize_unit {
858  const char *name; /* array ends with NULL name */
859  uint64_t factor;
861 
862 LWS_VISIBLE extern const lws_humanize_unit_t humanize_schema_si[7];
863 LWS_VISIBLE extern const lws_humanize_unit_t humanize_schema_si_bytes[7];
864 LWS_VISIBLE extern const lws_humanize_unit_t humanize_schema_us[8];
865 
887 LWS_VISIBLE LWS_EXTERN int
888 lws_humanize(char *buf, size_t len, uint64_t value,
889  const lws_humanize_unit_t *schema);
890 
891 LWS_VISIBLE LWS_EXTERN void
892 lws_ser_wu16be(uint8_t *b, uint16_t u);
893 
894 LWS_VISIBLE LWS_EXTERN void
895 lws_ser_wu32be(uint8_t *b, uint32_t u32);
896 
897 LWS_VISIBLE LWS_EXTERN void
898 lws_ser_wu64be(uint8_t *b, uint64_t u64);
899 
900 LWS_VISIBLE LWS_EXTERN uint16_t
901 lws_ser_ru16be(const uint8_t *b);
902 
903 LWS_VISIBLE LWS_EXTERN uint32_t
904 lws_ser_ru32be(const uint8_t *b);
905 
906 LWS_VISIBLE LWS_EXTERN uint64_t
907 lws_ser_ru64be(const uint8_t *b);
908 
909 LWS_VISIBLE LWS_EXTERN int
910 lws_vbi_encode(uint64_t value, void *buf);
911 
912 LWS_VISIBLE LWS_EXTERN int
913 lws_vbi_decode(const void *buf, uint64_t *value, size_t len);
914 
916 
917 #if defined(LWS_WITH_SPAWN)
918 
919 /* opaque internal struct */
920 struct lws_spawn_piped;
921 
922 #if defined(WIN32)
923 struct _lws_siginfo_t {
924  int retcode;
925 };
926 typedef struct _lws_siginfo_t siginfo_t;
927 #endif
928 
929 typedef void (*lsp_cb_t)(void *opaque, lws_usec_t *accounting, siginfo_t *si,
930  int we_killed_him);
931 
932 
950 struct lws_spawn_piped_info {
951  struct lws_dll2_owner *owner;
952  struct lws_vhost *vh;
953  struct lws *opt_parent;
954 
955  const char * const *exec_array;
956  const char **env_array;
957  const char *protocol_name;
958  const char *chroot_path;
959  const char *wd;
960 
961  struct lws_spawn_piped **plsp;
962 
963  void *opaque;
964 
965  lsp_cb_t reap_cb;
966 
967  lws_usec_t timeout_us;
968  int max_log_lines;
969  int tsi;
970 
971  const struct lws_role_ops *ops; /* NULL is raw file */
972 
973  uint8_t disable_ctrlc;
974 };
975 
997 LWS_VISIBLE LWS_EXTERN struct lws_spawn_piped *
998 lws_spawn_piped(const struct lws_spawn_piped_info *lspi);
999 
1000 /*
1001  * lws_spawn_piped_kill_child_process() - attempt to kill child process
1002  *
1003  * \p lsp: child object to kill
1004  *
1005  * Attempts to signal the child process in \p lsp to terminate.
1006  */
1007 LWS_VISIBLE LWS_EXTERN int
1008 lws_spawn_piped_kill_child_process(struct lws_spawn_piped *lsp);
1009 
1023 LWS_VISIBLE LWS_EXTERN void
1024 lws_spawn_stdwsi_closed(struct lws_spawn_piped *lsp, struct lws *wsi);
1025 
1036 LWS_VISIBLE LWS_EXTERN int
1037 lws_spawn_get_stdfd(struct lws *wsi);
1038 
1039 #endif
1040 
1041 struct lws_fsmount {
1042  const char *layers_path; /* where layers live */
1043  const char *overlay_path; /* where overlay instantiations live */
1044 
1045  char mp[256]; /* mountpoint path */
1046  char ovname[64]; /* unique name for mount instance */
1047  char distro[64]; /* unique name for layer source */
1048 
1049 #if defined(__linux__)
1050  const char *layers[4]; /* distro layers, like "base", "env" */
1051 #endif
1052 };
1053 
1087 LWS_VISIBLE LWS_EXTERN int
1088 lws_fsmount_mount(struct lws_fsmount *fsm);
1089 
1102 LWS_VISIBLE LWS_EXTERN int
1103 lws_fsmount_unmount(struct lws_fsmount *fsm);
LWS_VISIBLE LWS_EXTERN void lws_cmdline_option_handle_builtin(int argc, const char **argv, struct lws_context_creation_info *info)
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 void lws_buflist_describe(struct lws_buflist **head, void *id, const char *reason)
LWS_VISIBLE LWS_EXTERN int lws_open(const char *__file, int __oflag,...)
LWS_VISIBLE LWS_EXTERN int lws_wsi_tsi(struct lws *wsi)
LWS_VISIBLE LWS_EXTERN const char * lws_nstrstr(const char *buf, size_t len, const char *name, size_t nl)
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_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 void lws_get_effective_uid_gid(struct lws_context *context, uid_t *uid, gid_t *gid)
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 size_t lws_get_random(struct lws_context *context, void *buf, size_t len)
LWS_VISIBLE LWS_EXTERN int lws_buflist_linear_copy(struct lws_buflist **head, size_t ofs, uint8_t *buf, size_t len)
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 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 int lws_humanize(char *buf, size_t len, uint64_t value, const lws_humanize_unit_t *schema)
LWS_VISIBLE LWS_EXTERN const char * lws_cmdline_option(int argc, const char **argv, const char *val)
LWS_VISIBLE LWS_EXTERN size_t lws_buflist_total_len(struct lws_buflist **head)
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 size_t lws_buflist_use_segment(struct lws_buflist **head, size_t len)
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 int lws_json_simple_strcmp(const char *buf, size_t len, const char *name, const char *comp)
LWS_VISIBLE LWS_EXTERN int lws_get_tsi(struct lws *wsi)
LWS_VISIBLE LWS_EXTERN int lws_buflist_linear_use(struct lws_buflist **head, uint8_t *buf, size_t len)
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 const char * lws_json_simple_find(const char *buf, size_t len, const char *name, size_t *alen)
LWS_VISIBLE LWS_EXTERN void lws_hex_from_byte_array(const uint8_t *src, size_t slen, char *dest, size_t len)
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_fragment_use(struct lws_buflist **head, uint8_t *buf, size_t len, char *frag_first, char *frag_fin)
LWS_VISIBLE LWS_EXTERN int lws_rx_flow_control(struct lws *wsi, int enable)
LWS_VISIBLE LWS_EXTERN int lws_hex_random(struct lws_context *context, char *dest, size_t len)
LWS_VISIBLE LWS_EXTERN void lws_buflist_destroy_all_segments(struct lws_buflist **head)
Definition: lws-context-vhost.h:271
Definition: lws-dll2.h:203
Definition: lws-misc.h:1041
Definition: lws-misc.h:857
Definition: lws-protocols-plugins.h:44
Definition: lws-misc.h:833