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 
29 
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 
127 
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 struct lws_dll { /* abstract */
175  struct lws_dll *prev;
176  struct lws_dll *next;
177 };
178 
179 /*
180  * these all point to the composed list objects... you have to use the
181  * lws_container_of() helper to recover the start of the containing struct
182  */
183 
184 LWS_VISIBLE LWS_EXTERN void
185 lws_dll_add_front(struct lws_dll *d, struct lws_dll *phead);
186 
187 LWS_VISIBLE LWS_EXTERN void
188 lws_dll_remove(struct lws_dll *d);
189 
190 struct lws_dll_lws { /* typed as struct lws * */
191  struct lws_dll_lws *prev;
192  struct lws_dll_lws *next;
193 };
194 
195 #define lws_dll_is_null(___dll) (!(___dll)->prev && !(___dll)->next)
196 
197 static LWS_INLINE void
198 lws_dll_lws_add_front(struct lws_dll_lws *_a, struct lws_dll_lws *_head)
199 {
200  lws_dll_add_front((struct lws_dll *)_a, (struct lws_dll *)_head);
201 }
202 
203 static LWS_INLINE void
204 lws_dll_lws_remove(struct lws_dll_lws *_a)
205 {
206  lws_dll_remove((struct lws_dll *)_a);
207 }
208 
209 /*
210  * these are safe against the current container object getting deleted,
211  * since the hold his next in a temp and go to that next. ___tmp is
212  * the temp.
213  */
214 
215 #define lws_start_foreach_dll_safe(___type, ___it, ___tmp, ___start) \
216 { \
217  ___type ___it = ___start; \
218  while (___it) { \
219  ___type ___tmp = (___it)->next;
220 
221 #define lws_end_foreach_dll_safe(___it, ___tmp) \
222  ___it = ___tmp; \
223  } \
224 }
225 
226 #define lws_start_foreach_dll(___type, ___it, ___start) \
227 { \
228  ___type ___it = ___start; \
229  while (___it) {
230 
231 #define lws_end_foreach_dll(___it) \
232  ___it = (___it)->next; \
233  } \
234 }
235 
236 struct lws_buflist;
237 
248 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
249 lws_buflist_append_segment(struct lws_buflist **head, const uint8_t *buf,
250  size_t len);
261 LWS_VISIBLE LWS_EXTERN size_t
262 lws_buflist_next_segment_len(struct lws_buflist **head, uint8_t **buf);
278 LWS_VISIBLE LWS_EXTERN int
279 lws_buflist_use_segment(struct lws_buflist **head, size_t len);
288 LWS_VISIBLE LWS_EXTERN void
289 lws_buflist_destroy_all_segments(struct lws_buflist **head);
290 
291 void
292 lws_buflist_describe(struct lws_buflist **head, void *id);
293 
303 #define lws_ptr_diff(head, tail) \
304  ((int)((char *)(head) - (char *)(tail)))
305 
317 LWS_VISIBLE LWS_EXTERN int
318 lws_snprintf(char *str, size_t size, const char *format, ...) LWS_FORMAT(3);
319 
330 LWS_VISIBLE LWS_EXTERN char *
331 lws_strncpy(char *dest, const char *src, size_t size);
332 
344 LWS_VISIBLE LWS_EXTERN int
345 lws_get_random(struct lws_context *context, void *buf, int len);
353 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
354 lws_daemonize(const char *_lock_path);
360 LWS_VISIBLE LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT
362 
369 LWS_VISIBLE LWS_EXTERN void *
370 lws_wsi_user(struct lws *wsi);
371 
382 LWS_VISIBLE LWS_EXTERN void
383 lws_set_wsi_user(struct lws *wsi, void *user);
384 
407 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
408 lws_parse_uri(char *p, const char **prot, const char **ads, int *port,
409  const char **path);
427 LWS_VISIBLE LWS_EXTERN const char *
428 lws_cmdline_option(int argc, const char **argv, const char *val);
429 
433 LWS_VISIBLE LWS_EXTERN unsigned long
434 lws_now_secs(void);
435 
439 LWS_VISIBLE LWS_EXTERN lws_usec_t
440 lws_now_usecs(void);
441 
459 LWS_VISIBLE LWS_EXTERN int
460 lws_compare_time_t(struct lws_context *context, time_t t1, time_t t2);
461 
471 LWS_VISIBLE LWS_EXTERN struct lws_context * LWS_WARN_UNUSED_RESULT
472 lws_get_context(const struct lws *wsi);
473 
483 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
484 lws_get_vhost_listen_port(struct lws_vhost *vhost);
485 
495 LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
496 lws_get_count_threads(struct lws_context *context);
497 
505 LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT
506 lws_get_parent(const struct lws *wsi);
507 
514 LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT
515 lws_get_child(const struct lws *wsi);
516 
529 LWS_VISIBLE LWS_EXTERN void
530 lws_get_effective_uid_gid(struct lws_context *context, int *uid, int *gid);
531 
539 LWS_VISIBLE LWS_EXTERN const struct lws_udp * LWS_WARN_UNUSED_RESULT
540 lws_get_udp(const struct lws *wsi);
541 
542 LWS_VISIBLE LWS_EXTERN void *
543 lws_get_opaque_parent_data(const struct lws *wsi);
544 
545 LWS_VISIBLE LWS_EXTERN void
546 lws_set_opaque_parent_data(struct lws *wsi, void *data);
547 
548 LWS_VISIBLE LWS_EXTERN int
549 lws_get_child_pending_on_writable(const struct lws *wsi);
550 
551 LWS_VISIBLE LWS_EXTERN void
552 lws_clear_child_pending_on_writable(struct lws *wsi);
553 
554 LWS_VISIBLE LWS_EXTERN int
555 lws_get_close_length(struct lws *wsi);
556 
557 LWS_VISIBLE LWS_EXTERN unsigned char *
558 lws_get_close_payload(struct lws *wsi);
559 
570 LWS_VISIBLE LWS_EXTERN
571 struct lws *lws_get_network_wsi(struct lws *wsi);
572 
580 LWS_VISIBLE LWS_EXTERN void
581 lws_set_allocator(void *(*realloc)(void *ptr, size_t size, const char *reason));
582 
583 enum {
584  /*
585  * Flags for enable and disable rxflow with reason bitmap and with
586  * backwards-compatible single bool
587  */
588  LWS_RXFLOW_REASON_USER_BOOL = (1 << 0),
589  LWS_RXFLOW_REASON_HTTP_RXBUFFER = (1 << 6),
590  LWS_RXFLOW_REASON_H2_PPS_PENDING = (1 << 7),
591 
592  LWS_RXFLOW_REASON_APPLIES = (1 << 14),
593  LWS_RXFLOW_REASON_APPLIES_ENABLE_BIT = (1 << 13),
594  LWS_RXFLOW_REASON_APPLIES_ENABLE = LWS_RXFLOW_REASON_APPLIES |
595  LWS_RXFLOW_REASON_APPLIES_ENABLE_BIT,
596  LWS_RXFLOW_REASON_APPLIES_DISABLE = LWS_RXFLOW_REASON_APPLIES,
597  LWS_RXFLOW_REASON_FLAG_PROCESS_NOW = (1 << 12),
598 
599 };
600 
620 LWS_VISIBLE LWS_EXTERN int
621 lws_rx_flow_control(struct lws *wsi, int enable);
622 
632 LWS_VISIBLE LWS_EXTERN void
633 lws_rx_flow_allow_all_protocol(const struct lws_context *context,
634  const struct lws_protocols *protocol);
635 
655 LWS_VISIBLE LWS_EXTERN size_t
656 lws_remaining_packet_payload(struct lws *wsi);
657 
658 
659 
668 LWS_VISIBLE LWS_EXTERN int
669 lws_is_ssl(struct lws *wsi);
674 LWS_VISIBLE LWS_EXTERN int
675 lws_is_cgi(struct lws *wsi);
676 
688 LWS_VISIBLE LWS_EXTERN int
689 lws_open(const char *__file, int __oflag, ...);
690 
691 struct lws_wifi_scan { /* generic wlan scan item */
692  struct lws_wifi_scan *next;
693  char ssid[32];
694  int32_t rssi; /* divide by .count to get db */
695  uint8_t bssid[6];
696  uint8_t count;
697  uint8_t channel;
698  uint8_t authmode;
699 };
700 
701 #if defined(LWS_WITH_TLS) && !defined(LWS_WITH_MBEDTLS)
702 
708 LWS_VISIBLE LWS_EXTERN SSL*
709 lws_get_ssl(struct lws *wsi);
710 #endif
711 
743 #ifdef LWS_WITH_SMTP
744 
746 enum lwsgs_smtp_states {
747  LGSSMTP_IDLE,
748  LGSSMTP_CONNECTING,
749  LGSSMTP_CONNECTED,
750  LGSSMTP_SENT_HELO,
751  LGSSMTP_SENT_FROM,
752  LGSSMTP_SENT_TO,
753  LGSSMTP_SENT_DATA,
754  LGSSMTP_SENT_BODY,
755  LGSSMTP_SENT_QUIT,
756 };
757 
759 struct lws_email {
760  void *data;
762  uv_loop_t *loop;
765  char email_smtp_ip[32];
766  char email_helo[32];
767  char email_from[100];
768  char email_to[100];
770  unsigned int max_content_size;
773  /* Fill all the callbacks before init */
774 
775  int (*on_next)(struct lws_email *email);
780  int (*on_sent)(struct lws_email *email);
785  int (*on_get_body)(struct lws_email *email, char *buf, int len);
791  /* private things */
792  uv_timer_t timeout_email;
793  enum lwsgs_smtp_states estate;
794  uv_connect_t email_connect_req;
795  uv_tcp_t email_client;
796  time_t email_connect_started;
797  char email_buf[256];
798  char *content;
799 };
800 
810 LWS_VISIBLE LWS_EXTERN int
811 lws_email_init(struct lws_email *email, uv_loop_t *loop, int max_content);
812 
821 LWS_VISIBLE LWS_EXTERN void
822 lws_email_check(struct lws_email *email);
830 LWS_VISIBLE LWS_EXTERN void
831 lws_email_destroy(struct lws_email *email);
832 
833 #endif
834 
835 
lws_compare_time_t
LWS_VISIBLE LWS_EXTERN int lws_compare_time_t(struct lws_context *context, time_t t1, time_t t2)
lws_dll
Definition: lws-misc.h:174
lws_set_wsi_user
LWS_VISIBLE LWS_EXTERN void lws_set_wsi_user(struct lws *wsi, void *user)
lws_get_child
LWS_VISIBLE LWS_EXTERN struct lws *LWS_WARN_UNUSED_RESULT lws_get_child(const struct lws *wsi)
lws_get_count_threads
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_get_count_threads(struct lws_context *context)
lws_daemonize
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_daemonize(const char *_lock_path)
lws_parse_uri
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_rx_flow_allow_all_protocol
LWS_VISIBLE LWS_EXTERN void lws_rx_flow_allow_all_protocol(const struct lws_context *context, const struct lws_protocols *protocol)
lws_get_library_version
LWS_VISIBLE const LWS_EXTERN char *LWS_WARN_UNUSED_RESULT lws_get_library_version(void)
lws_cmdline_option
LWS_VISIBLE const LWS_EXTERN char * lws_cmdline_option(int argc, const char **argv, const char *val)
lws_dll_lws
Definition: lws-misc.h:190
lws_rx_flow_control
LWS_VISIBLE LWS_EXTERN int lws_rx_flow_control(struct lws *wsi, int enable)
lws_udp
Definition: lws-adopt.h:81
lws_buflist_use_segment
LWS_VISIBLE LWS_EXTERN int lws_buflist_use_segment(struct lws_buflist **head, size_t len)
lws_is_cgi
LWS_VISIBLE LWS_EXTERN int lws_is_cgi(struct lws *wsi)
lws_open
LWS_VISIBLE LWS_EXTERN int lws_open(const char *__file, int __oflag,...)
lws_wsi_user
LWS_VISIBLE LWS_EXTERN void * lws_wsi_user(struct lws *wsi)
lws_get_parent
LWS_VISIBLE LWS_EXTERN struct lws *LWS_WARN_UNUSED_RESULT lws_get_parent(const struct lws *wsi)
lws_snprintf
LWS_VISIBLE LWS_EXTERN int lws_snprintf(char *str, size_t size, const char *format,...) LWS_FORMAT(3)
lws_buflist_append_segment
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_get_random
LWS_VISIBLE LWS_EXTERN int lws_get_random(struct lws_context *context, void *buf, int len)
lws_remaining_packet_payload
LWS_VISIBLE LWS_EXTERN size_t lws_remaining_packet_payload(struct lws *wsi)
lws_buflist_next_segment_len
LWS_VISIBLE LWS_EXTERN size_t lws_buflist_next_segment_len(struct lws_buflist **head, uint8_t **buf)
lws_get_effective_uid_gid
LWS_VISIBLE LWS_EXTERN void lws_get_effective_uid_gid(struct lws_context *context, int *uid, int *gid)
lws_now_usecs
LWS_VISIBLE LWS_EXTERN lws_usec_t lws_now_usecs(void)
lws_strncpy
LWS_VISIBLE LWS_EXTERN char * lws_strncpy(char *dest, const char *src, size_t size)
lws_protocols
Definition: lws-protocols-plugins.h:43
lws_get_network_wsi
LWS_VISIBLE LWS_EXTERN struct lws * lws_get_network_wsi(struct lws *wsi)
lws_get_vhost_listen_port
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT lws_get_vhost_listen_port(struct lws_vhost *vhost)
lws_is_ssl
LWS_VISIBLE LWS_EXTERN int lws_is_ssl(struct lws *wsi)
lws_buflist_destroy_all_segments
LWS_VISIBLE LWS_EXTERN void lws_buflist_destroy_all_segments(struct lws_buflist **head)
lws_wifi_scan
Definition: lws-misc.h:691
lws_get_context
LWS_VISIBLE LWS_EXTERN struct lws_context *LWS_WARN_UNUSED_RESULT lws_get_context(const struct lws *wsi)
lws_get_udp
LWS_VISIBLE LWS_EXTERN const struct lws_udp *LWS_WARN_UNUSED_RESULT lws_get_udp(const struct lws *wsi)
lws_now_secs
LWS_VISIBLE LWS_EXTERN unsigned long lws_now_secs(void)
lws_set_allocator
LWS_VISIBLE LWS_EXTERN void lws_set_allocator(void *(*realloc)(void *ptr, size_t size, const char *reason))