close cover flush stored send with timeout
[platform/upstream/libwebsockets.git] / lib / libwebsockets.c
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010-2014 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
22 #include "private-libwebsockets.h"
23
24 int log_level = LLL_ERR | LLL_WARN | LLL_NOTICE;
25 static void (*lwsl_emit)(int level, const char *line) = lwsl_emit_stderr;
26
27 static const char * const log_level_names[] = {
28         "ERR",
29         "WARN",
30         "NOTICE",
31         "INFO",
32         "DEBUG",
33         "PARSER",
34         "HEADER",
35         "EXTENSION",
36         "CLIENT",
37         "LATENCY",
38 };
39
40 void
41 libwebsocket_close_and_free_session(struct libwebsocket_context *context,
42                          struct libwebsocket *wsi, enum lws_close_status reason)
43 {
44         int n, m, ret;
45         int old_state;
46         unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 +
47                                                   LWS_SEND_BUFFER_POST_PADDING];
48         struct lws_tokens eff_buf;
49
50         if (!wsi)
51                 return;
52
53         old_state = wsi->state;
54
55         if (wsi->socket_is_permanently_unusable || reason == LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY)
56                 goto just_kill_connection;
57
58         switch (old_state) {
59         case WSI_STATE_DEAD_SOCKET:
60                 return;
61
62         /* we tried the polite way... */
63         case WSI_STATE_AWAITING_CLOSE_ACK:
64                 goto just_kill_connection;
65
66         case WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE:
67                 if (wsi->truncated_send_len) {
68                         libwebsocket_callback_on_writable(context, wsi);
69                         return;
70                 }
71                 lwsl_info("wsi %p completed WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE\n", wsi);
72                 goto just_kill_connection;
73         default:
74                 if (wsi->truncated_send_len) {
75                         lwsl_info("wsi %p entering WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE\n", wsi);
76                         wsi->state = WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE;
77                         libwebsocket_set_timeout(wsi, PENDING_FLUSH_STORED_SEND_BEFORE_CLOSE, 5);
78                         return;
79                 }
80                 break;
81         }
82
83         wsi->u.ws.close_reason = reason;
84
85         if (wsi->mode == LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT ||
86                         wsi->mode == LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE) {
87
88                 context->protocols[0].callback(context, wsi,
89                         LWS_CALLBACK_CLIENT_CONNECTION_ERROR, wsi->user_space, NULL, 0);
90
91                 lws_free_header_table(wsi);
92                 goto just_kill_connection;
93         }
94
95         if (wsi->mode == LWS_CONNMODE_HTTP_SERVING)
96                 context->protocols[0].callback(context, wsi,
97                         LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0);
98
99         if (wsi->mode == LWS_CONNMODE_HTTP_SERVING_ACCEPTED) {
100                 if (wsi->u.http.fd != LWS_INVALID_FILE) {
101                         lwsl_debug("closing http file\n");
102                         compatible_file_close(wsi->u.http.fd);
103                         wsi->u.http.fd = LWS_INVALID_FILE;
104                         context->protocols[0].callback(context, wsi,
105                                 LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0);
106                 }
107         }
108
109         /*
110          * are his extensions okay with him closing?  Eg he might be a mux
111          * parent and just his ch1 aspect is closing?
112          */
113         
114         if (lws_ext_callback_for_each_active(wsi,
115                       LWS_EXT_CALLBACK_CHECK_OK_TO_REALLY_CLOSE, NULL, 0) > 0) {
116                 lwsl_ext("extension vetoed close\n");
117                 return;
118         }
119
120         /*
121          * flush any tx pending from extensions, since we may send close packet
122          * if there are problems with send, just nuke the connection
123          */
124
125         do {
126                 ret = 0;
127                 eff_buf.token = NULL;
128                 eff_buf.token_len = 0;
129
130                 /* show every extension the new incoming data */
131
132                 m = lws_ext_callback_for_each_active(wsi,
133                           LWS_EXT_CALLBACK_FLUSH_PENDING_TX, &eff_buf, 0);
134                 if (m < 0) {
135                         lwsl_ext("Extension reports fatal error\n");
136                         goto just_kill_connection;
137                 }
138                 if (m)
139                         /*
140                          * at least one extension told us he has more
141                          * to spill, so we will go around again after
142                          */
143                         ret = 1;
144
145                 /* assuming they left us something to send, send it */
146
147                 if (eff_buf.token_len)
148                         if (lws_issue_raw(wsi, (unsigned char *)eff_buf.token,
149                                       eff_buf.token_len) != eff_buf.token_len) {
150                                 lwsl_debug("close: ext spill failed\n");
151                                 goto just_kill_connection;
152                         }
153         } while (ret);
154
155         /*
156          * signal we are closing, libwebsocket_write will
157          * add any necessary version-specific stuff.  If the write fails,
158          * no worries we are closing anyway.  If we didn't initiate this
159          * close, then our state has been changed to
160          * WSI_STATE_RETURNED_CLOSE_ALREADY and we will skip this.
161          *
162          * Likewise if it's a second call to close this connection after we
163          * sent the close indication to the peer already, we are in state
164          * WSI_STATE_AWAITING_CLOSE_ACK and will skip doing this a second time.
165          */
166
167         if (old_state == WSI_STATE_ESTABLISHED &&
168             reason != LWS_CLOSE_STATUS_NOSTATUS &&
169             reason != LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY) {
170
171                 lwsl_debug("sending close indication...\n");
172
173                 /* make valgrind happy */
174                 memset(buf, 0, sizeof(buf));
175                 n = libwebsocket_write(wsi,
176                                 &buf[LWS_SEND_BUFFER_PRE_PADDING + 2],
177                                                             0, LWS_WRITE_CLOSE);
178                 if (n >= 0) {
179                         /*
180                          * we have sent a nice protocol level indication we
181                          * now wish to close, we should not send anything more
182                          */
183
184                         wsi->state = WSI_STATE_AWAITING_CLOSE_ACK;
185
186                         /*
187                          * ...and we should wait for a reply for a bit
188                          * out of politeness
189                          */
190
191                         libwebsocket_set_timeout(wsi,
192                                                   PENDING_TIMEOUT_CLOSE_ACK, 1);
193
194                         lwsl_debug("sent close indication, awaiting ack\n");
195
196                         return;
197                 }
198
199                 lwsl_info("close: sending close packet failed, hanging up\n");
200
201                 /* else, the send failed and we should just hang up */
202         }
203
204 just_kill_connection:
205
206         lwsl_debug("close: just_kill_connection\n");
207
208         /*
209          * we won't be servicing or receiving anything further from this guy
210          * delete socket from the internal poll list if still present
211          */
212
213         lws_ssl_remove_wsi_from_buffered_list(context, wsi);
214
215         remove_wsi_socket_from_fds(context, wsi);
216
217         wsi->state = WSI_STATE_DEAD_SOCKET;
218
219         lws_free2(wsi->rxflow_buffer);
220
221         if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING && wsi->u.hdr.ah) {
222                 lws_free2(wsi->u.hdr.ah);
223         }
224
225         if ((old_state == WSI_STATE_ESTABLISHED ||
226              wsi->mode == LWS_CONNMODE_WS_SERVING ||
227              wsi->mode == LWS_CONNMODE_WS_CLIENT)) {
228
229                 lws_free2(wsi->u.ws.rx_user_buffer);
230
231                 if (wsi->truncated_send_malloc) {
232                         /* not going to be completed... nuke it */
233                         lws_free2(wsi->truncated_send_malloc);
234                         wsi->truncated_send_len = 0;
235                 }
236                 if (wsi->u.ws.ping_payload_buf) {
237                         lws_free2(wsi->u.ws.ping_payload_buf);
238                         wsi->u.ws.ping_payload_alloc = 0;
239                         wsi->u.ws.ping_payload_len = 0;
240                         wsi->u.ws.ping_pending_flag = 0;
241                 }
242         }
243
244         /* tell the user it's all over for this guy */
245
246         if (wsi->protocol && wsi->protocol->callback &&
247                         ((old_state == WSI_STATE_ESTABLISHED) ||
248                          (old_state == WSI_STATE_RETURNED_CLOSE_ALREADY) ||
249                          (old_state == WSI_STATE_AWAITING_CLOSE_ACK) ||
250                          (old_state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE))) {
251                 lwsl_debug("calling back CLOSED\n");
252                 wsi->protocol->callback(context, wsi, LWS_CALLBACK_CLOSED,
253                                                       wsi->user_space, NULL, 0);
254         } else if (wsi->mode == LWS_CONNMODE_HTTP_SERVING_ACCEPTED) {
255                 lwsl_debug("calling back CLOSED_HTTP\n");
256                 context->protocols[0].callback(context, wsi,
257                         LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0 );
258         } else
259                 lwsl_debug("not calling back closed\n");
260
261         /* deallocate any active extension contexts */
262         
263         if (lws_ext_callback_for_each_active(wsi, LWS_EXT_CALLBACK_DESTROY, NULL, 0) < 0)
264                 lwsl_warn("extension destruction failed\n");
265 #ifndef LWS_NO_EXTENSIONS
266         for (n = 0; n < wsi->count_active_extensions; n++)
267                 lws_free(wsi->active_extensions_user[n]);
268 #endif
269         /*
270          * inform all extensions in case they tracked this guy out of band
271          * even though not active on him specifically
272          */
273         if (lws_ext_callback_for_each_extension_type(context, wsi,
274                        LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING, NULL, 0) < 0)
275                 lwsl_warn("ext destroy wsi failed\n");
276
277 /*      lwsl_info("closing fd=%d\n", wsi->sock); */
278
279         if (!lws_ssl_close(wsi) && wsi->sock >= 0) {
280                 n = shutdown(wsi->sock, SHUT_RDWR);
281                 if (n)
282                         lwsl_debug("closing: shutdown ret %d\n", LWS_ERRNO);
283
284                 n = compatible_close(wsi->sock);
285                 if (n)
286                         lwsl_debug("closing: close ret %d\n", LWS_ERRNO);
287         }
288
289         /* outermost destroy notification for wsi (user_space still intact) */
290         context->protocols[0].callback(context, wsi,
291                         LWS_CALLBACK_WSI_DESTROY, wsi->user_space, NULL, 0);
292
293         if (wsi->protocol && wsi->protocol->per_session_data_size &&
294             wsi->user_space && !wsi->user_space_externally_allocated)
295                 lws_free(wsi->user_space);
296
297         /* As a precaution, free the header table in case it lingered: */
298         lws_free_header_table(wsi);
299         lws_free(wsi);
300 }
301
302 LWS_VISIBLE int
303 libwebsockets_get_addresses(struct libwebsocket_context *context,
304                             void *ads, char *name, int name_len,
305                             char *rip, int rip_len)
306 {
307         struct addrinfo ai, *res;
308         void *p = NULL;
309
310         rip[0] = '\0';
311         name[0] = '\0';
312
313 #ifdef LWS_USE_IPV6
314         if (LWS_IPV6_ENABLED(context)) {
315                 if (!lws_plat_inet_ntop(AF_INET6, &((struct sockaddr_in6 *)ads)->sin6_addr, rip, rip_len)) {
316                         lwsl_err("inet_ntop", strerror(LWS_ERRNO));
317                         return -1;
318                 }
319
320                 // Strip off the IPv4 to IPv6 header if one exists
321                 if (strncmp(rip, "::ffff:", 7) == 0)
322                         memmove(rip, rip + 7, strlen(rip) - 6);
323
324                 getnameinfo((struct sockaddr *)ads,
325                                 sizeof(struct sockaddr_in6), name,
326                                                         name_len, NULL, 0, 0);
327                 
328                 return 0;
329         } else
330 #endif
331         {
332                 memset(&ai, 0, sizeof ai);
333                 ai.ai_family = PF_UNSPEC;
334                 ai.ai_socktype = SOCK_STREAM;
335                 ai.ai_flags = AI_CANONNAME;
336
337                 if (getnameinfo((struct sockaddr *)ads,
338                                 sizeof(struct sockaddr_in),
339                                 name, name_len, NULL, 0, 0))
340                         return -1;
341
342                 if (!rip)
343                         return 0;
344
345                 if (getaddrinfo(name, NULL, &ai, &res))
346                         return -1;
347
348                 while (!p && res) {
349                         switch (res->ai_family) {
350                         case AF_INET:
351                                 p = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
352                                 break;
353                         }
354
355                         res = res->ai_next;
356                 }
357         }
358
359         if (!p)
360                 return -1;
361
362         lws_plat_inet_ntop(AF_INET, p, rip, rip_len);
363
364         return 0;
365 }
366
367 /**
368  * libwebsockets_get_peer_addresses() - Get client address information
369  * @context:    Libwebsockets context
370  * @wsi:        Local struct libwebsocket associated with
371  * @fd:         Connection socket descriptor
372  * @name:       Buffer to take client address name
373  * @name_len:   Length of client address name buffer
374  * @rip:        Buffer to take client address IP dotted quad
375  * @rip_len:    Length of client address IP buffer
376  *
377  *      This function fills in @name and @rip with the name and IP of
378  *      the client connected with socket descriptor @fd.  Names may be
379  *      truncated if there is not enough room.  If either cannot be
380  *      determined, they will be returned as valid zero-length strings.
381  */
382
383 LWS_VISIBLE void
384 libwebsockets_get_peer_addresses(struct libwebsocket_context *context,
385         struct libwebsocket *wsi, int fd, char *name, int name_len,
386                                         char *rip, int rip_len)
387 {
388         socklen_t len;
389 #ifdef LWS_USE_IPV6
390         struct sockaddr_in6 sin6;
391 #endif
392         struct sockaddr_in sin4;
393         int ret = -1;
394         void *p;
395
396         rip[0] = '\0';
397         name[0] = '\0';
398
399         lws_latency_pre(context, wsi);
400
401 #ifdef LWS_USE_IPV6
402         if (LWS_IPV6_ENABLED(context)) {
403                 len = sizeof(sin6);
404                 p = &sin6;
405         } else
406 #endif
407         {
408                 len = sizeof(sin4);
409                 p = &sin4;
410         }
411
412         if (getpeername(fd, p, &len) < 0) {
413                 lwsl_warn("getpeername: %s\n", strerror(LWS_ERRNO));
414                 goto bail;
415         }
416         
417         ret = libwebsockets_get_addresses(context, p, name, name_len, rip, rip_len);
418
419 bail:
420         lws_latency(context, wsi, "libwebsockets_get_peer_addresses", ret, 1);
421 }
422
423 /**
424  * libwebsocket_context_user() - get the user data associated with the context
425  * @context: Websocket context
426  *
427  *      This returns the optional user allocation that can be attached to
428  *      the context the sockets live in at context_create time.  It's a way
429  *      to let all sockets serviced in the same context share data without
430  *      using globals statics in the user code.
431  */
432 LWS_EXTERN void *
433 libwebsocket_context_user(struct libwebsocket_context *context)
434 {
435         return context->user_space;
436 }
437
438
439 /**
440  * libwebsocket_callback_all_protocol() - Callback all connections using
441  *                              the given protocol with the given reason
442  *
443  * @protocol:   Protocol whose connections will get callbacks
444  * @reason:     Callback reason index
445  */
446
447 LWS_VISIBLE int
448 libwebsocket_callback_all_protocol(
449                 const struct libwebsocket_protocols *protocol, int reason)
450 {
451         struct libwebsocket_context *context = protocol->owning_server;
452         int n;
453         struct libwebsocket *wsi;
454
455         for (n = 0; n < context->fds_count; n++) {
456                 wsi = wsi_from_fd(context, context->fds[n].fd);
457                 if (!wsi)
458                         continue;
459                 if (wsi->protocol == protocol)
460                         protocol->callback(context, wsi,
461                                         reason, wsi->user_space, NULL, 0);
462         }
463
464         return 0;
465 }
466
467 /**
468  * libwebsocket_set_timeout() - marks the wsi as subject to a timeout
469  *
470  * You will not need this unless you are doing something special
471  *
472  * @wsi:        Websocket connection instance
473  * @reason:     timeout reason
474  * @secs:       how many seconds
475  */
476
477 LWS_VISIBLE void
478 libwebsocket_set_timeout(struct libwebsocket *wsi,
479                                           enum pending_timeout reason, int secs)
480 {
481         time_t now;
482
483         time(&now);
484
485         wsi->pending_timeout_limit = now + secs;
486         wsi->pending_timeout = reason;
487 }
488
489
490 /**
491  * libwebsocket_get_socket_fd() - returns the socket file descriptor
492  *
493  * You will not need this unless you are doing something special
494  *
495  * @wsi:        Websocket connection instance
496  */
497
498 LWS_VISIBLE int
499 libwebsocket_get_socket_fd(struct libwebsocket *wsi)
500 {
501         return wsi->sock;
502 }
503
504 #ifdef LWS_LATENCY
505 void
506 lws_latency(struct libwebsocket_context *context, struct libwebsocket *wsi,
507                                      const char *action, int ret, int completed)
508 {
509         unsigned long long u;
510         char buf[256];
511
512         u = time_in_microseconds();
513
514         if (!action) {
515                 wsi->latency_start = u;
516                 if (!wsi->action_start)
517                         wsi->action_start = u;
518                 return;
519         }
520         if (completed) {
521                 if (wsi->action_start == wsi->latency_start)
522                         sprintf(buf,
523                           "Completion first try lat %lluus: %p: ret %d: %s\n",
524                                         u - wsi->latency_start,
525                                                       (void *)wsi, ret, action);
526                 else
527                         sprintf(buf,
528                           "Completion %lluus: lat %lluus: %p: ret %d: %s\n",
529                                 u - wsi->action_start,
530                                         u - wsi->latency_start,
531                                                       (void *)wsi, ret, action);
532                 wsi->action_start = 0;
533         } else
534                 sprintf(buf, "lat %lluus: %p: ret %d: %s\n",
535                               u - wsi->latency_start, (void *)wsi, ret, action);
536
537         if (u - wsi->latency_start > context->worst_latency) {
538                 context->worst_latency = u - wsi->latency_start;
539                 strcpy(context->worst_latency_info, buf);
540         }
541         lwsl_latency("%s", buf);
542 }
543 #endif
544
545
546
547 /**
548  * libwebsocket_rx_flow_control() - Enable and disable socket servicing for
549  *                              received packets.
550  *
551  * If the output side of a server process becomes choked, this allows flow
552  * control for the input side.
553  *
554  * @wsi:        Websocket connection instance to get callback for
555  * @enable:     0 = disable read servicing for this connection, 1 = enable
556  */
557
558 LWS_VISIBLE int
559 libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable)
560 {
561         if (enable == (wsi->rxflow_change_to & LWS_RXFLOW_ALLOW))
562                 return 0;
563
564         lwsl_info("libwebsocket_rx_flow_control(0x%p, %d)\n", wsi, enable);
565         wsi->rxflow_change_to = LWS_RXFLOW_PENDING_CHANGE | !!enable;
566
567         return 0;
568 }
569
570 /**
571  * libwebsocket_rx_flow_allow_all_protocol() - Allow all connections with this protocol to receive
572  *
573  * When the user server code realizes it can accept more input, it can
574  * call this to have the RX flow restriction removed from all connections using
575  * the given protocol.
576  *
577  * @protocol:   all connections using this protocol will be allowed to receive
578  */
579
580 LWS_VISIBLE void
581 libwebsocket_rx_flow_allow_all_protocol(
582                                 const struct libwebsocket_protocols *protocol)
583 {
584         struct libwebsocket_context *context = protocol->owning_server;
585         int n;
586         struct libwebsocket *wsi;
587
588         for (n = 0; n < context->fds_count; n++) {
589                 wsi = wsi_from_fd(context, context->fds[n].fd);
590                 if (!wsi)
591                         continue;
592                 if (wsi->protocol == protocol)
593                         libwebsocket_rx_flow_control(wsi, LWS_RXFLOW_ALLOW);
594         }
595 }
596
597
598 /**
599  * libwebsocket_canonical_hostname() - returns this host's hostname
600  *
601  * This is typically used by client code to fill in the host parameter
602  * when making a client connection.  You can only call it after the context
603  * has been created.
604  *
605  * @context:    Websocket context
606  */
607 LWS_VISIBLE extern const char *
608 libwebsocket_canonical_hostname(struct libwebsocket_context *context)
609 {
610         return (const char *)context->canonical_hostname;
611 }
612
613 int user_callback_handle_rxflow(callback_function callback_function,
614                 struct libwebsocket_context *context,
615                         struct libwebsocket *wsi,
616                          enum libwebsocket_callback_reasons reason, void *user,
617                                                           void *in, size_t len)
618 {
619         int n;
620
621         n = callback_function(context, wsi, reason, user, in, len);
622         if (!n)
623                 n = _libwebsocket_rx_flow_control(wsi);
624
625         return n;
626 }
627
628
629 /**
630  * libwebsocket_set_proxy() - Setups proxy to libwebsocket_context.
631  * @context:    pointer to struct libwebsocket_context you want set proxy to
632  * @proxy: pointer to c string containing proxy in format address:port
633  *
634  * Returns 0 if proxy string was parsed and proxy was setup. 
635  * Returns -1 if @proxy is NULL or has incorrect format.
636  *
637  * This is only required if your OS does not provide the http_proxy
638  * environment variable (eg, OSX)
639  *
640  *   IMPORTANT! You should call this function right after creation of the
641  *   libwebsocket_context and before call to connect. If you call this
642  *   function after connect behavior is undefined.
643  *   This function will override proxy settings made on libwebsocket_context
644  *   creation with genenv() call.
645  */
646
647 LWS_VISIBLE int
648 libwebsocket_set_proxy(struct libwebsocket_context *context, const char *proxy)
649 {
650         char *p;
651         
652         if (!proxy)
653                 return -1;
654
655         strncpy(context->http_proxy_address, proxy,
656                                 sizeof(context->http_proxy_address) - 1);
657         context->http_proxy_address[
658                                 sizeof(context->http_proxy_address) - 1] = '\0';
659         
660         p = strchr(context->http_proxy_address, ':');
661         if (!p) {
662                 lwsl_err("http_proxy needs to be ads:port\n");
663
664                 return -1;
665         }
666         *p = '\0';
667         context->http_proxy_port = atoi(p + 1);
668         
669         lwsl_notice(" Proxy %s:%u\n", context->http_proxy_address,
670                                                 context->http_proxy_port);
671
672         return 0;
673 }
674
675 /**
676  * libwebsockets_get_protocol() - Returns a protocol pointer from a websocket
677  *                                connection.
678  * @wsi:        pointer to struct websocket you want to know the protocol of
679  *
680  *
681  *      Some apis can act on all live connections of a given protocol,
682  *      this is how you can get a pointer to the active protocol if needed.
683  */
684
685 LWS_VISIBLE const struct libwebsocket_protocols *
686 libwebsockets_get_protocol(struct libwebsocket *wsi)
687 {
688         return wsi->protocol;
689 }
690
691 LWS_VISIBLE int
692 libwebsocket_is_final_fragment(struct libwebsocket *wsi)
693 {
694         return wsi->u.ws.final;
695 }
696
697 LWS_VISIBLE unsigned char
698 libwebsocket_get_reserved_bits(struct libwebsocket *wsi)
699 {
700         return wsi->u.ws.rsv;
701 }
702
703 int
704 libwebsocket_ensure_user_space(struct libwebsocket *wsi)
705 {
706         lwsl_info("%s: %p protocol %p\n", __func__, wsi, wsi->protocol);
707         if (!wsi->protocol)
708                 return 1;
709
710         /* allocate the per-connection user memory (if any) */
711
712         if (wsi->protocol->per_session_data_size && !wsi->user_space) {
713                 wsi->user_space = lws_zalloc(wsi->protocol->per_session_data_size);
714                 if (wsi->user_space  == NULL) {
715                         lwsl_err("Out of memory for conn user space\n");
716                         return 1;
717                 }
718         } else
719                 lwsl_info("%s: %p protocol pss %u, user_space=%d\n", __func__, wsi, wsi->protocol->per_session_data_size, wsi->user_space);
720         return 0;
721 }
722
723 LWS_VISIBLE void lwsl_emit_stderr(int level, const char *line)
724 {
725         char buf[300];
726         unsigned long long now;
727         int n;
728
729         buf[0] = '\0';
730         for (n = 0; n < LLL_COUNT; n++)
731                 if (level == (1 << n)) {
732                         now = time_in_microseconds() / 100;
733                         sprintf(buf, "[%llu:%04d] %s: ", (unsigned long long) now / 10000,
734                                 (int)(now % 10000), log_level_names[n]);
735                         break;
736                 }
737
738         fprintf(stderr, "%s%s", buf, line);
739 }
740
741
742 LWS_VISIBLE void _lws_logv(int filter, const char *format, va_list vl)
743 {
744         char buf[256];
745
746         if (!(log_level & filter))
747                 return;
748
749         vsnprintf(buf, sizeof(buf), format, vl);
750         buf[sizeof(buf) - 1] = '\0';
751
752         lwsl_emit(filter, buf);
753 }
754
755 LWS_VISIBLE void _lws_log(int filter, const char *format, ...)
756 {
757         va_list ap;
758
759         va_start(ap, format);
760         _lws_logv(filter, format, ap);
761         va_end(ap);
762 }
763
764 /**
765  * lws_set_log_level() - Set the logging bitfield
766  * @level:      OR together the LLL_ debug contexts you want output from
767  * @log_emit_function:  NULL to leave it as it is, or a user-supplied
768  *                      function to perform log string emission instead of
769  *                      the default stderr one.
770  *
771  *      log level defaults to "err", "warn" and "notice" contexts enabled and
772  *      emission on stderr.
773  */
774
775 LWS_VISIBLE void lws_set_log_level(int level, void (*log_emit_function)(int level,
776                                                               const char *line))
777 {
778         log_level = level;
779         if (log_emit_function)
780                 lwsl_emit = log_emit_function;
781 }
782
783 /**
784  * lws_use_ssl() - Find out if connection is using SSL
785  * @wsi:        websocket connection to check
786  *
787  *      Returns 0 if the connection is not using SSL, 1 if using SSL and
788  *      using verified cert, and 2 if using SSL but the cert was not
789  *      checked (appears for client wsi told to skip check on connection)
790  */
791 LWS_VISIBLE int
792 lws_is_ssl(struct libwebsocket *wsi)
793 {
794 #ifdef LWS_OPENSSL_SUPPORT
795         return wsi->use_ssl;
796 #else
797         return 0;
798 #endif
799 }
800
801 /**
802  * lws_partial_buffered() - find out if lws buffered the last write
803  * @wsi:        websocket connection to check
804  *
805  * Returns 1 if you cannot use libwebsocket_write because the last
806  * write on this connection is still buffered, and can't be cleared without
807  * returning to the service loop and waiting for the connection to be
808  * writeable again.
809  * 
810  * If you will try to do >1 libwebsocket_write call inside a single
811  * WRITEABLE callback, you must check this after every write and bail if
812  * set, ask for a new writeable callback and continue writing from there.
813  * 
814  * This is never set at the start of a writeable callback, but any write
815  * may set it.
816  */
817
818 LWS_VISIBLE int
819 lws_partial_buffered(struct libwebsocket *wsi)
820 {
821         return !!wsi->truncated_send_len;       
822 }
823
824 void lws_set_protocol_write_pending(struct libwebsocket_context *context,
825                                     struct libwebsocket *wsi,
826                                     enum lws_pending_protocol_send pend)
827 {
828         lwsl_info("setting pps %d\n", pend);
829         
830         if (wsi->pps)
831                 lwsl_err("pps overwrite\n");
832         wsi->pps = pend;
833         libwebsocket_rx_flow_control(wsi, 0);
834         libwebsocket_callback_on_writable(context, wsi);
835 }
836
837 LWS_VISIBLE size_t
838 lws_get_peer_write_allowance(struct libwebsocket *wsi)
839 {
840 #ifdef LWS_USE_HTTP2
841         /* only if we are using HTTP2 on this connection */
842         if (wsi->mode != LWS_CONNMODE_HTTP2_SERVING)
843                 return -1;
844         /* user is only interested in how much he can send, or that he can't  */
845         if (wsi->u.http2.tx_credit <= 0)
846                 return 0;
847         
848         return wsi->u.http2.tx_credit;
849 #else
850         return -1;
851 #endif
852 }
853
854 LWS_VISIBLE void
855 lws_union_transition(struct libwebsocket *wsi, enum connection_mode mode)
856 {
857         memset(&wsi->u, 0, sizeof(wsi->u));
858         wsi->mode = mode;
859 }