recv() may not return all data
[profile/ivi/libwebsockets.git] / lib / libwebsockets.c
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 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 #ifdef WIN32
25
26 #else
27 #include <ifaddrs.h>
28 #include <sys/un.h>
29 #endif
30
31 #ifdef LWS_OPENSSL_SUPPORT
32 int openssl_websocket_private_data_index;
33 #endif
34
35 /*
36  * In-place str to lower case
37  */
38
39 static void
40 strtolower(char *s)
41 {
42         while (*s) {
43                 *s = tolower(*s);
44                 s++;
45         }
46 }
47
48 /* file descriptor hash management */
49
50 struct libwebsocket *
51 wsi_from_fd(struct libwebsocket_context *context, int fd)
52 {
53         int h = LWS_FD_HASH(fd);
54         int n = 0;
55
56         for (n = 0; n < context->fd_hashtable[h].length; n++)
57                 if (context->fd_hashtable[h].wsi[n]->sock == fd)
58                         return context->fd_hashtable[h].wsi[n];
59
60         return NULL;
61 }
62
63 int
64 insert_wsi(struct libwebsocket_context *context, struct libwebsocket *wsi)
65 {
66         int h = LWS_FD_HASH(wsi->sock);
67
68         if (context->fd_hashtable[h].length == MAX_CLIENTS - 1) {
69                 fprintf(stderr, "hash table overflow\n");
70                 return 1;
71         }
72
73         context->fd_hashtable[h].wsi[context->fd_hashtable[h].length++] = wsi;
74
75         return 0;
76 }
77
78 int
79 delete_from_fd(struct libwebsocket_context *context, int fd)
80 {
81         int h = LWS_FD_HASH(fd);
82         int n = 0;
83
84         for (n = 0; n < context->fd_hashtable[h].length; n++)
85                 if (context->fd_hashtable[h].wsi[n]->sock == fd) {
86                         while (n < context->fd_hashtable[h].length) {
87                                 context->fd_hashtable[h].wsi[n] =
88                                             context->fd_hashtable[h].wsi[n + 1];
89                                 n++;
90                         }
91                         context->fd_hashtable[h].length--;
92
93                         return 0;
94                 }
95
96         fprintf(stderr, "Failed to find fd %d requested for "
97                                                    "delete in hashtable\n", fd);
98         return 1;
99 }
100
101 #ifdef LWS_OPENSSL_SUPPORT
102 static void
103 libwebsockets_decode_ssl_error(void)
104 {
105         char buf[256];
106         u_long err;
107
108         while ((err = ERR_get_error()) != 0) {
109                 ERR_error_string_n(err, buf, sizeof(buf));
110                 fprintf(stderr, "*** %s\n", buf);
111         }
112 }
113 #endif
114
115
116 static int
117 interface_to_sa(const char* ifname, struct sockaddr_in *addr, size_t addrlen)
118 {
119         int rc = -1;
120 #ifdef WIN32
121         // TODO
122 #else
123         struct ifaddrs *ifr;
124         struct ifaddrs *ifc;
125         struct sockaddr_in *sin;
126
127         getifaddrs(&ifr);
128         for (ifc = ifr; ifc != NULL; ifc = ifc->ifa_next) {
129                 if (strcmp(ifc->ifa_name, ifname))
130                         continue;
131                 if (ifc->ifa_addr == NULL)
132                         continue;
133                 sin = (struct sockaddr_in *)ifc->ifa_addr;
134                 if (sin->sin_family != AF_INET)
135                         continue;
136                 memcpy(addr, sin, addrlen);
137                 rc = 0; 
138         }
139
140         freeifaddrs(ifr);
141 #endif
142         return rc;
143 }
144
145 void
146 libwebsocket_close_and_free_session(struct libwebsocket_context *context,
147                          struct libwebsocket *wsi, enum lws_close_status reason)
148 {
149         int n;
150         int old_state;
151         unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 +
152                                                   LWS_SEND_BUFFER_POST_PADDING];
153         int ret;
154         int m;
155         struct lws_tokens eff_buf;
156
157         if (!wsi)
158                 return;
159
160         old_state = wsi->state;
161
162         if (old_state == WSI_STATE_DEAD_SOCKET)
163                 return;
164
165         wsi->close_reason = reason;
166
167         /*
168          * flush any tx pending from extensions, since we may send close packet
169          * if there are problems with send, just nuke the connection
170          */
171
172         ret = 1;
173         while (ret == 1) {
174
175                 /* default to nobody has more to spill */
176
177                 ret = 0;
178                 eff_buf.token = NULL;
179                 eff_buf.token_len = 0;
180
181                 /* show every extension the new incoming data */
182
183                 for (n = 0; n < wsi->count_active_extensions; n++) {
184                         m = wsi->active_extensions[n]->callback(
185                                         wsi->protocol->owning_server,
186                                         wsi->active_extensions[n], wsi,
187                                         LWS_EXT_CALLBACK_FLUSH_PENDING_TX,
188                                    wsi->active_extensions_user[n], &eff_buf, 0);
189                         if (m < 0) {
190                                 fprintf(stderr, "Extension reports "
191                                                                "fatal error\n");
192                                 goto just_kill_connection;
193                         }
194                         if (m)
195                                 /*
196                                  * at least one extension told us he has more
197                                  * to spill, so we will go around again after
198                                  */
199                                 ret = 1;
200                 }
201
202                 /* assuming they left us something to send, send it */
203
204                 if (eff_buf.token_len)
205                         if (lws_issue_raw(wsi, (unsigned char *)eff_buf.token,
206                                                              eff_buf.token_len))
207                                 goto just_kill_connection;
208         }
209
210         /*
211          * signal we are closing, libsocket_write will
212          * add any necessary version-specific stuff.  If the write fails,
213          * no worries we are closing anyway.  If we didn't initiate this
214          * close, then our state has been changed to
215          * WSI_STATE_RETURNED_CLOSE_ALREADY and we will skip this.
216          *
217          * Likewise if it's a second call to close this connection after we
218          * sent the close indication to the peer already, we are in state
219          * WSI_STATE_AWAITING_CLOSE_ACK and will skip doing this a second time.
220          */
221
222         if (old_state == WSI_STATE_ESTABLISHED &&
223                                           reason != LWS_CLOSE_STATUS_NOSTATUS) {
224                 n = libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING],
225                                                             0, LWS_WRITE_CLOSE);
226                 if (!n) {
227                         /*
228                          * we have sent a nice protocol level indication we
229                          * now wish to close, we should not send anything more
230                          */
231
232                         wsi->state = WSI_STATE_AWAITING_CLOSE_ACK;
233
234                         /* and we should wait for a reply for a bit */
235
236                         libwebsocket_set_timeout(wsi,
237                                                   PENDING_TIMEOUT_CLOSE_ACK, 5);
238
239                         fprintf(stderr, "sent close indication, awaiting ack\n");
240
241                         return;
242                 }
243
244                 /* else, the send failed and we should just hang up */
245         }
246
247 just_kill_connection:
248         /*
249          * we won't be servicing or receiving anything further from this guy
250          * remove this fd from wsi mapping hashtable
251          */
252
253         delete_from_fd(context, wsi->sock);
254
255         /* delete it from the internal poll list if still present */
256
257         for (n = 0; n < context->fds_count; n++) {
258                 if (context->fds[n].fd != wsi->sock)
259                         continue;
260                 while (n < context->fds_count - 1) {
261                         context->fds[n] = context->fds[n + 1];
262                         n++;
263                 }
264                 context->fds_count--;
265                 /* we only have to deal with one */
266                 n = context->fds_count;
267         }
268
269         /* remove also from external POLL support via protocol 0 */
270
271         context->protocols[0].callback(context, wsi,
272                     LWS_CALLBACK_DEL_POLL_FD, (void *)(long)wsi->sock, NULL, 0);
273
274         wsi->state = WSI_STATE_DEAD_SOCKET;
275
276         /* tell the user it's all over for this guy */
277
278         if (wsi->protocol && wsi->protocol->callback &&
279                                              old_state == WSI_STATE_ESTABLISHED)
280                 wsi->protocol->callback(context, wsi, LWS_CALLBACK_CLOSED,
281                                                       wsi->user_space, NULL, 0);
282
283         /* deallocate any active extension contexts */
284
285         for (n = 0; n < wsi->count_active_extensions; n++) {
286                 if (!wsi->active_extensions[n]->callback)
287                         continue;
288
289                 wsi->active_extensions[n]->callback(context,
290                         wsi->active_extensions[n], wsi,
291                                 LWS_EXT_CALLBACK_DESTROY,
292                                        wsi->active_extensions_user[n], NULL, 0);
293
294                 free(wsi->active_extensions_user[n]);
295         }
296
297         /* free up his parsing allocations */
298
299         for (n = 0; n < WSI_TOKEN_COUNT; n++)
300                 if (wsi->utf8_token[n].token)
301                         free(wsi->utf8_token[n].token);
302
303 /*      fprintf(stderr, "closing fd=%d\n", wsi->sock); */
304
305 #ifdef LWS_OPENSSL_SUPPORT
306         if (wsi->ssl) {
307                 n = SSL_get_fd(wsi->ssl);
308                 SSL_shutdown(wsi->ssl);
309 #ifdef WIN32
310                 closesocket(n);
311 #else
312                 close(n);
313 #endif
314                 SSL_free(wsi->ssl);
315         } else {
316 #endif
317                 shutdown(wsi->sock, SHUT_RDWR);
318 #ifdef WIN32
319                 closesocket(wsi->sock);
320 #else
321                 close(wsi->sock);
322 #endif
323 #ifdef LWS_OPENSSL_SUPPORT
324         }
325 #endif
326         if (wsi->user_space)
327                 free(wsi->user_space);
328
329         free(wsi);
330 }
331
332 /**
333  * libwebsockets_hangup_on_client() - Server calls to terminate client
334  *                                      connection
335  * @context:    libwebsockets context
336  * @fd:         Connection socket descriptor
337  */
338
339 void
340 libwebsockets_hangup_on_client(struct libwebsocket_context *context, int fd)
341 {
342         struct libwebsocket *wsi = wsi_from_fd(context, fd);
343
344         if (wsi == NULL)
345                 return;
346
347         libwebsocket_close_and_free_session(context, wsi,
348                                                      LWS_CLOSE_STATUS_NOSTATUS);
349 }
350
351
352 /**
353  * libwebsockets_get_peer_addresses() - Get client address information
354  * @fd:         Connection socket descriptor
355  * @name:       Buffer to take client address name
356  * @name_len:   Length of client address name buffer
357  * @rip:        Buffer to take client address IP qotted quad
358  * @rip_len:    Length of client address IP buffer
359  *
360  *      This function fills in @name and @rip with the name and IP of
361  *      the client connected with socket descriptor @fd.  Names may be
362  *      truncated if there is not enough room.  If either cannot be
363  *      determined, they will be returned as valid zero-length strings.
364  */
365
366 void
367 libwebsockets_get_peer_addresses(int fd, char *name, int name_len,
368                                         char *rip, int rip_len)
369 {
370         unsigned int len;
371         struct sockaddr_in sin;
372         struct hostent *host;
373         struct hostent *host1;
374         char ip[128];
375         unsigned char *p;
376         int n;
377         struct sockaddr_un *un;
378
379         rip[0] = '\0';
380         name[0] = '\0';
381
382         len = sizeof sin;
383         if (getpeername(fd, (struct sockaddr *) &sin, &len) < 0) {
384                 perror("getpeername");
385                 return;
386         }
387                 
388         host = gethostbyaddr((char *) &sin.sin_addr, sizeof sin.sin_addr,
389                                                                        AF_INET);
390         if (host == NULL) {
391                 perror("gethostbyaddr");
392                 return;
393         }
394
395         strncpy(name, host->h_name, name_len);
396         name[name_len - 1] = '\0';
397
398         host1 = gethostbyname(host->h_name);
399         if (host1 == NULL)
400                 return;
401         p = (unsigned char *)host1;
402         n = 0;
403         while (p != NULL) {
404                 p = (unsigned char *)host1->h_addr_list[n++];
405                 if (p == NULL)
406                         continue;
407                 if ((host1->h_addrtype != AF_INET)
408 #ifdef AF_LOCAL
409                         && (host1->h_addrtype != AF_LOCAL)
410 #endif
411                         )
412                         continue;
413
414                 if (host1->h_addrtype == AF_INET)
415                         sprintf(ip, "%u.%u.%u.%u", p[0], p[1], p[2], p[3]);
416 #ifdef AF_LOCAL
417                 else {
418                         un = (struct sockaddr_un *)p;
419                         strncpy(ip, un->sun_path, sizeof(ip) -1);
420                         ip[sizeof(ip) - 1] = '\0';
421                 }
422 #endif
423                 p = NULL;
424                 strncpy(rip, ip, rip_len);
425                 rip[rip_len - 1] = '\0';
426         }
427 }
428
429 int libwebsockets_get_random(struct libwebsocket_context *context,
430                                                              void *buf, int len)
431 {
432         int n;
433         char *p = buf;
434
435 #ifdef WIN32
436         for (n = 0; n < len; n++)
437                 p[n] = (unsigned char)rand();
438 #else
439         n = read(context->fd_random, p, len);
440 #endif
441
442         return n;
443 }
444
445 unsigned char *
446 libwebsockets_SHA1(const unsigned char *d, size_t n, unsigned char *md)
447 {
448         return SHA1(d, n, md);
449 }
450
451 void libwebsockets_00_spaceout(char *key, int spaces, int seed)
452 {
453         char *p;
454         
455         key++;
456         while (spaces--) {
457                 if (*key && (seed & 1))
458                         key++;
459                 seed >>= 1;
460                 
461                 p = key + strlen(key);
462                 while (p >= key) {
463                         p[1] = p[0];
464                         p--;
465                 }
466                 *key++ = ' ';
467         }
468 }
469
470 void libwebsockets_00_spam(char *key, int count, int seed)
471 {
472         char *p;
473
474         key++;
475         while (count--) {
476                 
477                 if (*key && (seed & 1))
478                         key++;
479                 seed >>= 1;
480
481                 p = key + strlen(key);
482                 while (p >= key) {
483                         p[1] = p[0];
484                         p--;
485                 }
486                 *key++ = 0x21 + ((seed & 0xffff) % 15);
487                 /* 4 would use it up too fast.. not like it matters */
488                 seed >>= 1;
489         }
490 }
491
492 int lws_send_pipe_choked(struct libwebsocket *wsi)
493 {
494         struct pollfd fds;
495
496         fds.fd = wsi->sock;
497         fds.events = POLLOUT;
498         fds.revents = 0;
499
500         if (poll(&fds, 1, 0) != 1)
501                 return 1;
502
503         if ((fds.revents & POLLOUT) == 0)
504                 return 1;
505
506         /* okay to send another packet without blocking */
507
508         return 0;
509 }
510
511 static int
512 lws_handle_POLLOUT_event(struct libwebsocket_context *context,
513                                 struct libwebsocket *wsi, struct pollfd *pollfd)
514 {
515         struct lws_tokens eff_buf;
516         int n;
517         int ret;
518         int m;
519
520         if (!wsi->extension_data_pending)
521                 goto user_service;
522
523         /*
524          * check in on the active extensions, see if they
525          * had pending stuff to spill... they need to get the
526          * first look-in otherwise sequence will be disordered
527          *
528          * NULL, zero-length eff_buf means just spill pending
529          */
530
531         ret = 1;
532         while (ret == 1) {
533
534                 /* default to nobody has more to spill */
535
536                 ret = 0;
537                 eff_buf.token = NULL;
538                 eff_buf.token_len = 0;
539
540                 /* give every extension a chance to spill */
541
542                 for (n = 0; n < wsi->count_active_extensions; n++) {
543                         m = wsi->active_extensions[n]->callback(
544                                 wsi->protocol->owning_server,
545                                 wsi->active_extensions[n], wsi,
546                                         LWS_EXT_CALLBACK_PACKET_TX_PRESEND,
547                                    wsi->active_extensions_user[n], &eff_buf, 0);
548                         if (m < 0) {
549                                 fprintf(stderr, "extension reports fatal error\n");
550                                 return -1;
551                         }
552                         if (m)
553                                 /*
554                                  * at least one extension told us he has more
555                                  * to spill, so we will go around again after
556                                  */
557                                 ret = 1;
558                 }
559
560                 /* assuming they gave us something to send, send it */
561
562                 if (eff_buf.token_len) {
563                         if (lws_issue_raw(wsi, (unsigned char *)eff_buf.token,
564                                                              eff_buf.token_len))
565                                 return -1;
566                 } else
567                         continue;
568
569                 /* no extension has more to spill */
570
571                 if (!ret)
572                         continue;
573
574                 /*
575                  * There's more to spill from an extension, but we just sent
576                  * something... did that leave the pipe choked?
577                  */
578
579                 if (!lws_send_pipe_choked(wsi))
580                         /* no we could add more */
581                         continue;
582
583                 fprintf(stderr, "choked in POLLOUT service\n");
584
585                 /*
586                  * Yes, he's choked.  Leave the POLLOUT masked on so we will
587                  * come back here when he is unchoked.  Don't call the user
588                  * callback to enforce ordering of spilling, he'll get called
589                  * when we come back here and there's nothing more to spill.
590                  */
591
592                 return 0;
593         }
594
595         wsi->extension_data_pending = 0;
596
597 user_service:
598         /* one shot */
599
600         pollfd->events &= ~POLLOUT;
601
602         /* external POLL support via protocol 0 */
603         context->protocols[0].callback(context, wsi,
604                 LWS_CALLBACK_CLEAR_MODE_POLL_FD,
605                 (void *)(long)wsi->sock, NULL, POLLOUT);
606
607         if (wsi->mode == LWS_CONNMODE_WS_CLIENT)
608                 n = LWS_CALLBACK_CLIENT_WRITEABLE;
609         else
610                 n = LWS_CALLBACK_SERVER_WRITEABLE;
611
612         wsi->protocol->callback(context, wsi, n, wsi->user_space, NULL, 0);
613
614         return 0;
615 }
616
617 static ssize_t
618 libwebsocket_recv(int sock, void *buf, size_t len, int flags)
619 {
620         int n, ret = 0;
621
622         while ((len > 0) && (n = recv(sock, (char *)buf + ret, len,
623                         flags)) > 0) {
624                 ret += n;
625                 len -= n;
626         }
627
628         return ret;
629 }
630
631 /**
632  * libwebsocket_service_fd() - Service polled socket with something waiting
633  * @context:    Websocket context
634  * @pollfd:     The pollfd entry describing the socket fd and which events
635  *              happened.
636  *
637  *      This function closes any active connections and then frees the
638  *      context.  After calling this, any further use of the context is
639  *      undefined.
640  */
641
642 int
643 libwebsocket_service_fd(struct libwebsocket_context *context,
644                                                           struct pollfd *pollfd)
645 {
646         unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 1 + MAX_BROADCAST_PAYLOAD +
647                                                   LWS_SEND_BUFFER_POST_PADDING];
648         struct libwebsocket *wsi;
649         struct libwebsocket *new_wsi;
650         int n;
651         int m;
652         size_t len;
653         int accept_fd;
654         unsigned int clilen;
655         struct sockaddr_in cli_addr;
656         struct timeval tv;
657         static const char magic_websocket_guid[] =
658                                          "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
659         static const char magic_websocket_04_masking_guid[] =
660                                          "61AC5F19-FBBA-4540-B96F-6561F1AB40A8";
661         char hash[20];
662         char pkt[1024];
663         char *p = &pkt[0];
664         const char *pc;
665         const char *c;
666         int more = 1;
667         int okay = 0;
668         char ext_name[128];
669         struct lws_tokens eff_buf;
670         int ext_count = 0;
671         struct libwebsocket_extension *ext;
672         int opt = 1;
673
674 #ifdef LWS_OPENSSL_SUPPORT
675         char ssl_err_buf[512];
676 #endif
677         /*
678          * you can call us with pollfd = NULL to just allow the once-per-second
679          * global timeout checks; if less than a second since the last check
680          * it returns immediately then.
681          */
682
683         gettimeofday(&tv, NULL);
684
685         if (context->last_timeout_check_s != tv.tv_sec) {
686                 context->last_timeout_check_s = tv.tv_sec;
687
688                 /* global timeout check once per second */
689
690                 for (n = 0; n < context->fds_count; n++) {
691                         wsi = wsi_from_fd(context, context->fds[n].fd);
692                         if (!wsi->pending_timeout)
693                                 continue;
694
695                         /*
696                          * if we went beyond the allowed time, kill the
697                          * connection
698                          */
699
700                         if (tv.tv_sec > wsi->pending_timeout_limit) {
701                                 fprintf(stderr, "TIMEDOUT WAITING\n");
702                                 libwebsocket_close_and_free_session(context,
703                                                 wsi, LWS_CLOSE_STATUS_NOSTATUS);
704                         }
705                 }
706         }
707
708         /* just here for timeout management? */
709
710         if (pollfd == NULL)
711                 return 0;
712
713         /* no, here to service a socket descriptor */
714
715         wsi = wsi_from_fd(context, pollfd->fd);
716
717         if (wsi == NULL)
718                 return 1;
719
720         switch (wsi->mode) {
721         case LWS_CONNMODE_SERVER_LISTENER:
722
723                 /* pollin means a client has connected to us then */
724
725                 if (!pollfd->revents & POLLIN)
726                         break;
727
728                 /* listen socket got an unencrypted connection... */
729
730                 clilen = sizeof(cli_addr);
731                 accept_fd  = accept(pollfd->fd, (struct sockaddr *)&cli_addr,
732                                                                        &clilen);
733                 if (accept_fd < 0) {
734                         fprintf(stderr, "ERROR on accept");
735                         break;
736                 }
737
738                 /* Disable Nagle */
739                 opt = 1;
740                 setsockopt(accept_fd, IPPROTO_TCP, TCP_NODELAY, &opt,
741                                 sizeof(opt));
742
743                 if (context->fds_count >= MAX_CLIENTS) {
744                         fprintf(stderr, "too busy to accept new client\n");
745 #ifdef WIN32
746                         closesocket(accept_fd);
747 #else
748                         close(accept_fd);
749 #endif
750                         break;
751                 }
752
753                 /*
754                  * look at who we connected to and give user code a chance
755                  * to reject based on client IP.  There's no protocol selected
756                  * yet so we issue this to protocols[0]
757                  */
758
759                 if ((context->protocols[0].callback)(context, wsi,
760                                 LWS_CALLBACK_FILTER_NETWORK_CONNECTION,
761                                              (void*)(long)accept_fd, NULL, 0)) {
762                         fprintf(stderr, "Callback denied network connection\n");
763 #ifdef WIN32
764                         closesocket(accept_fd);
765 #else
766                         close(accept_fd);
767 #endif
768                         break;
769                 }
770
771                 /* accepting connection to main listener */
772
773                 new_wsi = malloc(sizeof(struct libwebsocket));
774                 if (new_wsi == NULL) {
775                         fprintf(stderr, "Out of memory for new connection\n");
776                         break;
777                 }
778
779                 memset(new_wsi, 0, sizeof (struct libwebsocket));
780                 new_wsi->sock = accept_fd;
781                 new_wsi->count_active_extensions = 0;
782                 new_wsi->pending_timeout = NO_PENDING_TIMEOUT;
783
784 #ifdef LWS_OPENSSL_SUPPORT
785                 new_wsi->ssl = NULL;
786
787                 if (context->use_ssl) {
788
789                         new_wsi->ssl = SSL_new(context->ssl_ctx);
790                         if (new_wsi->ssl == NULL) {
791                                 fprintf(stderr, "SSL_new failed: %s\n",
792                                     ERR_error_string(SSL_get_error(
793                                     new_wsi->ssl, 0), NULL));
794                                     libwebsockets_decode_ssl_error();
795                                 free(new_wsi);
796                                 break;
797                         }
798
799                         SSL_set_fd(new_wsi->ssl, accept_fd);
800
801                         n = SSL_accept(new_wsi->ssl);
802                         if (n != 1) {
803                                 /*
804                                  * browsers seem to probe with various
805                                  * ssl params which fail then retry
806                                  * and succeed
807                                  */
808                                 debug("SSL_accept failed skt %u: %s\n",
809                                       pollfd->fd,
810                                       ERR_error_string(SSL_get_error(
811                                       new_wsi->ssl, n), NULL));
812                                 SSL_free(
813                                        new_wsi->ssl);
814                                 free(new_wsi);
815                                 break;
816                         }
817                         
818                         debug("accepted new SSL conn  "
819                               "port %u on fd=%d SSL ver %s\n",
820                                 ntohs(cli_addr.sin_port), accept_fd,
821                                   SSL_get_version(new_wsi->ssl));
822
823                 } else
824 #endif
825                         debug("accepted new conn  port %u on fd=%d\n",
826                                           ntohs(cli_addr.sin_port), accept_fd);
827
828                 /* intialize the instance struct */
829
830                 new_wsi->state = WSI_STATE_HTTP;
831                 new_wsi->name_buffer_pos = 0;
832                 new_wsi->mode = LWS_CONNMODE_WS_SERVING;
833
834                 for (n = 0; n < WSI_TOKEN_COUNT; n++) {
835                         new_wsi->utf8_token[n].token = NULL;
836                         new_wsi->utf8_token[n].token_len = 0;
837                 }
838
839                 /*
840                  * these can only be set once the protocol is known
841                  * we set an unestablished connection's protocol pointer
842                  * to the start of the supported list, so it can look
843                  * for matching ones during the handshake
844                  */
845                 new_wsi->protocol = context->protocols;
846                 new_wsi->user_space = NULL;
847
848                 /*
849                  * Default protocol is 76 / 00
850                  * After 76, there's a header specified to inform which
851                  * draft the client wants, when that's seen we modify
852                  * the individual connection's spec revision accordingly
853                  */
854                 new_wsi->ietf_spec_revision = 0;
855
856                 insert_wsi(context, new_wsi);
857
858                 /*
859                  * make sure NO events are seen yet on this new socket
860                  * (otherwise we inherit old fds[client].revents from
861                  * previous socket there and die mysteriously! )
862                  */
863                 context->fds[context->fds_count].revents = 0;
864
865                 context->fds[context->fds_count].events = POLLIN;
866                 context->fds[context->fds_count++].fd = accept_fd;
867
868                 /* external POLL support via protocol 0 */
869                 context->protocols[0].callback(context, new_wsi,
870                         LWS_CALLBACK_ADD_POLL_FD,
871                         (void *)(long)accept_fd, NULL, POLLIN);
872
873                 break;
874
875         case LWS_CONNMODE_BROADCAST_PROXY_LISTENER:
876
877                 /* as we are listening, POLLIN means accept() is needed */
878         
879                 if (!pollfd->revents & POLLIN)
880                         break;
881
882                 /* listen socket got an unencrypted connection... */
883
884                 clilen = sizeof(cli_addr);
885                 accept_fd  = accept(pollfd->fd, (struct sockaddr *)&cli_addr,
886                                                                        &clilen);
887                 if (accept_fd < 0) {
888                         fprintf(stderr, "ERROR on accept");
889                         break;
890                 }
891
892                 if (context->fds_count >= MAX_CLIENTS) {
893                         fprintf(stderr, "too busy to accept new broadcast "
894                                                               "proxy client\n");
895 #ifdef WIN32
896                         closesocket(accept_fd);
897 #else
898                         close(accept_fd);
899 #endif
900                         break;
901                 }
902
903                 /* create a dummy wsi for the connection and add it */
904
905                 new_wsi = malloc(sizeof(struct libwebsocket));
906                 memset(new_wsi, 0, sizeof (struct libwebsocket));
907                 new_wsi->sock = accept_fd;
908                 new_wsi->mode = LWS_CONNMODE_BROADCAST_PROXY;
909                 new_wsi->state = WSI_STATE_ESTABLISHED;
910                 new_wsi->count_active_extensions = 0;
911                 /* note which protocol we are proxying */
912                 new_wsi->protocol_index_for_broadcast_proxy =
913                                         wsi->protocol_index_for_broadcast_proxy;
914                 insert_wsi(context, new_wsi);
915
916                 /* add connected socket to internal poll array */
917
918                 context->fds[context->fds_count].revents = 0;
919                 context->fds[context->fds_count].events = POLLIN;
920                 context->fds[context->fds_count++].fd = accept_fd;
921
922                 /* external POLL support via protocol 0 */
923                 context->protocols[0].callback(context, new_wsi,
924                         LWS_CALLBACK_ADD_POLL_FD,
925                         (void *)(long)accept_fd, NULL, POLLIN);
926
927                 break;
928
929         case LWS_CONNMODE_BROADCAST_PROXY:
930
931                 /* handle session socket closed */
932
933                 if (pollfd->revents & (POLLERR | POLLHUP)) {
934
935                         debug("Session Socket %p (fd=%d) dead\n",
936                                 (void *)wsi, pollfd->fd);
937
938                         libwebsocket_close_and_free_session(context, wsi,
939                                                        LWS_CLOSE_STATUS_NORMAL);
940                         return 1;
941                 }
942
943                 /*
944                  * either extension code with stuff to spill, or the user code,
945                  * requested a callback when it was OK to write
946                  */
947
948                 if (pollfd->revents & POLLOUT)
949                         if (lws_handle_POLLOUT_event(context, wsi, pollfd) < 0) {
950                                 libwebsocket_close_and_free_session(context, wsi,
951                                                        LWS_CLOSE_STATUS_NORMAL);
952                                 return 1;
953                         }
954
955                 /* any incoming data ready? */
956
957                 if (!(pollfd->revents & POLLIN))
958                         break;
959
960                 /* get the issued broadcast payload from the socket */
961
962                 len = read(pollfd->fd, buf + LWS_SEND_BUFFER_PRE_PADDING,
963                                                          MAX_BROADCAST_PAYLOAD);
964                 if (len < 0) {
965                         fprintf(stderr, "Error reading broadcast payload\n");
966                         break;
967                 }
968
969                 /* broadcast it to all guys with this protocol index */
970
971                 for (n = 0; n < FD_HASHTABLE_MODULUS; n++) {
972
973                         for (m = 0; m < context->fd_hashtable[n].length; m++) {
974
975                                 new_wsi = context->fd_hashtable[n].wsi[m];
976
977                                 /* only to clients we are serving to */
978
979                                 if (new_wsi->mode != LWS_CONNMODE_WS_SERVING)
980                                         continue;
981
982                                 /*
983                                  * never broadcast to non-established
984                                  * connection
985                                  */
986
987                                 if (new_wsi->state != WSI_STATE_ESTABLISHED)
988                                         continue;
989
990                                 /*
991                                  * only broadcast to connections using
992                                  * the requested protocol
993                                  */
994
995                                 if (new_wsi->protocol->protocol_index !=
996                                         wsi->protocol_index_for_broadcast_proxy)
997                                         continue;
998
999                                 /* broadcast it to this connection */
1000
1001                                 new_wsi->protocol->callback(context, new_wsi,
1002                                         LWS_CALLBACK_BROADCAST,
1003                                         new_wsi->user_space,
1004                                         buf + LWS_SEND_BUFFER_PRE_PADDING, len);
1005                         }
1006                 }
1007                 break;
1008
1009         case LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY:
1010
1011                 /* handle proxy hung up on us */
1012
1013                 if (pollfd->revents & (POLLERR | POLLHUP)) {
1014
1015                         fprintf(stderr, "Proxy connection %p (fd=%d) dead\n",
1016                                 (void *)wsi, pollfd->fd);
1017
1018                         libwebsocket_close_and_free_session(context, wsi,
1019                                                      LWS_CLOSE_STATUS_NOSTATUS);
1020                         return 1;
1021                 }
1022
1023                 n = libwebsocket_recv(wsi->sock, pkt, sizeof pkt, 0);
1024                 if (n < 0) {
1025                         libwebsocket_close_and_free_session(context, wsi,
1026                                                      LWS_CLOSE_STATUS_NOSTATUS);
1027                         fprintf(stderr, "ERROR reading from proxy socket\n");
1028                         return 1;
1029                 }
1030
1031                 pkt[13] = '\0';
1032                 if (strcmp(pkt, "HTTP/1.0 200 ") != 0) {
1033                         libwebsocket_close_and_free_session(context, wsi,
1034                                                      LWS_CLOSE_STATUS_NOSTATUS);
1035                         fprintf(stderr, "ERROR from proxy: %s\n", pkt);
1036                         return 1;
1037                 }
1038
1039                 /* clear his proxy connection timeout */
1040
1041                 libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
1042
1043                 /* fallthru */
1044
1045         case LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE:
1046
1047         #ifdef LWS_OPENSSL_SUPPORT
1048                 if (wsi->use_ssl) {
1049
1050                         wsi->ssl = SSL_new(context->ssl_client_ctx);
1051                         wsi->client_bio = BIO_new_socket(wsi->sock,
1052                                                                    BIO_NOCLOSE);
1053                         SSL_set_bio(wsi->ssl, wsi->client_bio, wsi->client_bio);
1054
1055                         SSL_set_ex_data(wsi->ssl,
1056                                         openssl_websocket_private_data_index,
1057                                                                        context);
1058
1059                         if (SSL_connect(wsi->ssl) <= 0) {
1060                                 fprintf(stderr, "SSL connect error %s\n",
1061                                         ERR_error_string(ERR_get_error(),
1062                                                                   ssl_err_buf));
1063                                 libwebsocket_close_and_free_session(context, wsi,
1064                                                      LWS_CLOSE_STATUS_NOSTATUS);
1065                                 return 1;
1066                         }
1067
1068                         n = SSL_get_verify_result(wsi->ssl);
1069                         if ((n != X509_V_OK) && (
1070                                 n != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
1071                                                            wsi->use_ssl != 2)) {
1072
1073                                 fprintf(stderr, "server's cert didn't "
1074                                                            "look good %d\n", n);
1075                                 libwebsocket_close_and_free_session(context,
1076                                                 wsi, LWS_CLOSE_STATUS_NOSTATUS);
1077                                 return 1;
1078                         }
1079                 } else {
1080                         wsi->ssl = NULL;
1081         #endif
1082
1083
1084         #ifdef LWS_OPENSSL_SUPPORT
1085                 }
1086         #endif
1087
1088                 /*
1089                  * create the random key
1090                  */
1091
1092                 n = libwebsockets_get_random(context, hash, 16);
1093                 if (n != 16) {
1094                         fprintf(stderr, "Unable to read from random dev %s\n",
1095                                                         SYSTEM_RANDOM_FILEPATH);
1096                         free(wsi->c_path);
1097                         free(wsi->c_host);
1098                         if (wsi->c_origin)
1099                                 free(wsi->c_origin);
1100                         if (wsi->c_protocol)
1101                                 free(wsi->c_protocol);
1102                         libwebsocket_close_and_free_session(context, wsi,
1103                                                      LWS_CLOSE_STATUS_NOSTATUS);
1104                         return 1;
1105                 }
1106
1107                 lws_b64_encode_string(hash, 16, wsi->key_b64,
1108                                                            sizeof wsi->key_b64);
1109
1110                 /*
1111                  * 00 example client handshake
1112                  *
1113                  * GET /socket.io/websocket HTTP/1.1
1114                  * Upgrade: WebSocket
1115                  * Connection: Upgrade
1116                  * Host: 127.0.0.1:9999
1117                  * Origin: http://127.0.0.1
1118                  * Sec-WebSocket-Key1: 1 0 2#0W 9 89 7  92 ^
1119                  * Sec-WebSocket-Key2: 7 7Y 4328 B2v[8(z1
1120                  * Cookie: socketio=websocket
1121                  * 
1122                  * (Á®Ä0¶†≥
1123                  * 
1124                  * 04 example client handshake
1125                  *
1126                  * GET /chat HTTP/1.1
1127                  * Host: server.example.com
1128                  * Upgrade: websocket
1129                  * Connection: Upgrade
1130                  * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
1131                  * Sec-WebSocket-Origin: http://example.com
1132                  * Sec-WebSocket-Protocol: chat, superchat
1133                  * Sec-WebSocket-Version: 4
1134                  */
1135
1136                 p += sprintf(p, "GET %s HTTP/1.1\x0d\x0a", wsi->c_path);
1137
1138                 if (wsi->ietf_spec_revision == 0) {
1139                         unsigned char spaces_1, spaces_2;
1140                         unsigned int max_1, max_2;
1141                         unsigned int num_1, num_2;
1142                         unsigned long product_1, product_2;
1143                         char key_1[40];
1144                         char key_2[40];
1145                         unsigned int seed;
1146                         unsigned int count;
1147                         char challenge[16];
1148
1149                         libwebsockets_get_random(context, &spaces_1,
1150                                                                   sizeof(char));
1151                         libwebsockets_get_random(context, &spaces_2,
1152                                                                   sizeof(char));
1153                         
1154                         spaces_1 = (spaces_1 % 12) + 1;
1155                         spaces_2 = (spaces_2 % 12) + 1;
1156                         
1157                         max_1 = 4294967295 / spaces_1;
1158                         max_2 = 4294967295 / spaces_2;
1159
1160                         libwebsockets_get_random(context, &num_1, sizeof(int));
1161                         libwebsockets_get_random(context, &num_2, sizeof(int));
1162                         
1163                         num_1 = (num_1 % max_1);
1164                         num_2 = (num_2 % max_2);
1165                         
1166                         challenge[0] = num_1 >> 24;
1167                         challenge[1] = num_1 >> 16;
1168                         challenge[2] = num_1 >> 8;
1169                         challenge[3] = num_1;
1170                         challenge[4] = num_2 >> 24;
1171                         challenge[5] = num_2 >> 16;
1172                         challenge[6] = num_2 >> 8;
1173                         challenge[7] = num_2;
1174                         
1175                         product_1 = num_1 * spaces_1;
1176                         product_2 = num_2 * spaces_2;
1177                         
1178                         sprintf(key_1, "%lu", product_1);
1179                         sprintf(key_2, "%lu", product_2);
1180
1181                         libwebsockets_get_random(context, &seed, sizeof(int));
1182                         libwebsockets_get_random(context, &count, sizeof(int));
1183                         
1184                         libwebsockets_00_spam(key_1, (count % 12) + 1, seed);
1185                         
1186                         libwebsockets_get_random(context, &seed, sizeof(int));
1187                         libwebsockets_get_random(context, &count, sizeof(int));
1188                         
1189                         libwebsockets_00_spam(key_2, (count % 12) + 1, seed);
1190                         
1191                         libwebsockets_get_random(context, &seed, sizeof(int));
1192                         
1193                         libwebsockets_00_spaceout(key_1, spaces_1, seed);
1194                         libwebsockets_00_spaceout(key_2, spaces_2, seed >> 16);
1195                         
1196                         p += sprintf(p, "Upgrade: WebSocket\x0d\x0a"
1197                                 "Connection: Upgrade\x0d\x0aHost: %s\x0d\x0a",
1198                                 wsi->c_host);
1199                         if (wsi->c_origin)
1200                                 p += sprintf(p, "Origin: %s\x0d\x0a",
1201                                 wsi->c_origin);
1202                         
1203                         if (wsi->c_protocol)
1204                                 p += sprintf(p, "Sec-WebSocket-Protocol: %s"
1205                                                  "\x0d\x0a", wsi->c_protocol);
1206                         
1207                         p += sprintf(p, "Sec-WebSocket-Key1: %s\x0d\x0a",
1208                                 key_1);
1209                         p += sprintf(p, "Sec-WebSocket-Key2: %s\x0d\x0a",
1210                                 key_2);
1211
1212                         /* give userland a chance to append, eg, cookies */
1213                         
1214                         context->protocols[0].callback(context, wsi,
1215                                 LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,
1216                                         NULL, &p, (pkt + sizeof(pkt)) - p - 12);
1217
1218                         p += sprintf(p, "\x0d\x0a");
1219
1220                         if (libwebsockets_get_random(context, p, 8) != 8)
1221                                 return -1;
1222                         memcpy(&challenge[8], p, 8);
1223                         p += 8;
1224                         
1225                         /* precompute what we want to see from the server */
1226                         
1227                         MD5((unsigned char *)challenge, 16,
1228                            (unsigned char *)wsi->initial_handshake_hash_base64);
1229                         
1230                         goto issue_hdr;
1231                 }
1232
1233                 p += sprintf(p, "Host: %s\x0d\x0a", wsi->c_host);
1234                 p += sprintf(p, "Upgrade: websocket\x0d\x0a");
1235                 p += sprintf(p, "Connection: Upgrade\x0d\x0a"
1236                                         "Sec-WebSocket-Key: ");
1237                 strcpy(p, wsi->key_b64);
1238                 p += strlen(wsi->key_b64);
1239                 p += sprintf(p, "\x0d\x0a");
1240                 if (wsi->c_origin)
1241                         p += sprintf(p, "Sec-WebSocket-Origin: %s\x0d\x0a",
1242                                                                  wsi->c_origin);
1243                 if (wsi->c_protocol)
1244                         p += sprintf(p, "Sec-WebSocket-Protocol: %s\x0d\x0a",
1245                                                                wsi->c_protocol);
1246
1247                 /* tell the server what extensions we could support */
1248
1249                 p += sprintf(p, "Sec-WebSocket-Extensions: ");
1250
1251                 ext =context->extensions;
1252                 while (ext && ext->callback) {
1253
1254                         n = 0;
1255                         n = context->protocols[0].callback(context, wsi,
1256                                 LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED,
1257                                         wsi->user_space, (char *)ext->name, 0);
1258
1259                         /*
1260                          * zero return from callback means
1261                          * go ahead and allow the extension,
1262                          * it's what we get if the callback is
1263                          * unhandled
1264                          */
1265
1266                         if (n) {
1267                                 ext++;
1268                                 continue;
1269                         }
1270
1271                         /* apply it */
1272                         
1273                         if (ext_count)
1274                                 *p++ = ',';
1275                         p += sprintf(p, "%s", ext->name);
1276                         ext_count++;
1277
1278                         ext++;
1279                 }
1280
1281                 p += sprintf(p, "\x0d\x0a");
1282
1283                 if (wsi->ietf_spec_revision)
1284                         p += sprintf(p, "Sec-WebSocket-Version: %d\x0d\x0a",
1285                                                        wsi->ietf_spec_revision); 
1286
1287                 /* give userland a chance to append, eg, cookies */
1288                 
1289                 context->protocols[0].callback(context, wsi,
1290                         LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,
1291                         NULL, &p, (pkt + sizeof(pkt)) - p - 12);
1292                 
1293                 p += sprintf(p, "\x0d\x0a");
1294
1295                 /* prepare the expected server accept response */
1296
1297                 strcpy((char *)buf, wsi->key_b64);
1298                 strcpy((char *)&buf[strlen((char *)buf)], magic_websocket_guid);
1299
1300                 SHA1(buf, strlen((char *)buf), (unsigned char *)hash);
1301
1302                 lws_b64_encode_string(hash, 20,
1303                                 wsi->initial_handshake_hash_base64,
1304                                      sizeof wsi->initial_handshake_hash_base64);
1305
1306 issue_hdr:
1307                 
1308                 /* done with these now */
1309                 
1310                 free(wsi->c_path);
1311                 free(wsi->c_host);
1312                 if (wsi->c_origin)
1313                         free(wsi->c_origin);
1314
1315                 /* send our request to the server */
1316
1317         #ifdef LWS_OPENSSL_SUPPORT
1318                 if (wsi->use_ssl)
1319                         n = SSL_write(wsi->ssl, pkt, p - pkt);
1320                 else
1321         #endif
1322                         n = send(wsi->sock, pkt, p - pkt, 0);
1323
1324                 if (n < 0) {
1325                         fprintf(stderr, "ERROR writing to client socket\n");
1326                         libwebsocket_close_and_free_session(context, wsi,
1327                                                      LWS_CLOSE_STATUS_NOSTATUS);
1328                         return 1;
1329                 }
1330
1331                 wsi->parser_state = WSI_TOKEN_NAME_PART;
1332                 wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY;
1333                 libwebsocket_set_timeout(wsi,
1334                                 PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE, 5);
1335
1336                 break;
1337
1338         case LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY:
1339
1340                 /* handle server hung up on us */
1341
1342                 if (pollfd->revents & (POLLERR | POLLHUP)) {
1343
1344                         fprintf(stderr, "Server connection %p (fd=%d) dead\n",
1345                                 (void *)wsi, pollfd->fd);
1346
1347                         goto bail3;
1348                 }
1349
1350
1351                 /* interpret the server response */
1352
1353                 /*
1354                  *  HTTP/1.1 101 Switching Protocols
1355                  *  Upgrade: websocket
1356                  *  Connection: Upgrade
1357                  *  Sec-WebSocket-Accept: me89jWimTRKTWwrS3aRrL53YZSo=
1358                  *  Sec-WebSocket-Nonce: AQIDBAUGBwgJCgsMDQ4PEC==
1359                  *  Sec-WebSocket-Protocol: chat
1360                  */
1361
1362         #ifdef LWS_OPENSSL_SUPPORT
1363                 if (wsi->use_ssl)
1364                         len = SSL_read(wsi->ssl, pkt, sizeof pkt);
1365                 else
1366         #endif
1367                 len = libwebsocket_recv(wsi->sock, pkt, sizeof pkt, 0);
1368
1369                 if (len < 0) {
1370                         fprintf(stderr,
1371                                   "libwebsocket_client_handshake read error\n");
1372                         goto bail3;
1373                 }
1374
1375                 p = pkt;
1376                 for (n = 0; n < len; n++)
1377                         libwebsocket_parse(wsi, *p++);
1378
1379                 if (wsi->parser_state != WSI_PARSING_COMPLETE) {
1380                         fprintf(stderr, "libwebsocket_client_handshake "
1381                                         "server response failed parsing\n");
1382                         goto bail3;
1383                 }
1384
1385                 /*
1386                  * 00 / 76 -->
1387                  *
1388                  * HTTP/1.1 101 WebSocket Protocol Handshake
1389                  * Upgrade: WebSocket
1390                  * Connection: Upgrade
1391                  * Sec-WebSocket-Origin: http://127.0.0.1
1392                  * Sec-WebSocket-Location: ws://127.0.0.1:9999/socket.io/websocket
1393                  *
1394                  * xxxxxxxxxxxxxxxx
1395                  */
1396                 
1397                 if (wsi->ietf_spec_revision == 0) {
1398                         if (!wsi->utf8_token[WSI_TOKEN_HTTP].token_len ||
1399                             !wsi->utf8_token[WSI_TOKEN_UPGRADE].token_len ||
1400                             !wsi->utf8_token[WSI_TOKEN_CHALLENGE].token_len ||
1401                             !wsi->utf8_token[WSI_TOKEN_CONNECTION].token_len ||
1402                             (!wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len &&
1403                             wsi->c_protocol != NULL)) {
1404                                 fprintf(stderr, "libwebsocket_client_handshake "
1405                                                 "missing required header(s)\n");
1406                                 pkt[len] = '\0';
1407                                 fprintf(stderr, "%s", pkt);
1408                                 goto bail3;
1409                         }
1410                         
1411                         strtolower(wsi->utf8_token[WSI_TOKEN_HTTP].token);
1412                         if (strcmp(wsi->utf8_token[WSI_TOKEN_HTTP].token,
1413                                 "101 websocket protocol handshake")) {
1414                                 fprintf(stderr, "libwebsocket_client_handshake "
1415                                         "server sent bad HTTP response '%s'\n",
1416                                         wsi->utf8_token[WSI_TOKEN_HTTP].token);
1417                                 goto bail3;
1418                         }
1419                         
1420                         if (wsi->utf8_token[WSI_TOKEN_CHALLENGE].token_len <
1421                                                                            16) {
1422                                 fprintf(stderr, "libwebsocket_client_handshake "
1423                                         "challenge reply too short %d\n",
1424                                         wsi->utf8_token[
1425                                                 WSI_TOKEN_CHALLENGE].token_len);
1426                                 pkt[len] = '\0';
1427                                 fprintf(stderr, "%s", pkt);
1428                                 goto bail3;
1429                                 
1430                         }
1431                         
1432                         goto select_protocol;
1433                 }
1434                 
1435                 /*
1436                  * well, what the server sent looked reasonable for syntax.
1437                  * Now let's confirm it sent all the necessary headers
1438                  */
1439
1440                  if (!wsi->utf8_token[WSI_TOKEN_HTTP].token_len ||
1441                         !wsi->utf8_token[WSI_TOKEN_UPGRADE].token_len ||
1442                         !wsi->utf8_token[WSI_TOKEN_CONNECTION].token_len ||
1443                         !wsi->utf8_token[WSI_TOKEN_ACCEPT].token_len ||
1444                         (!wsi->utf8_token[WSI_TOKEN_NONCE].token_len &&
1445                                            wsi->ietf_spec_revision == 4) ||
1446                         (!wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len &&
1447                                                      wsi->c_protocol != NULL)) {
1448                         fprintf(stderr, "libwebsocket_client_handshake "
1449                                                 "missing required header(s)\n");
1450                         pkt[len] = '\0';
1451                         fprintf(stderr, "%s", pkt);
1452                         goto bail3;
1453                 }
1454
1455                 /*
1456                  * Everything seems to be there, now take a closer look at what
1457                  * is in each header
1458                  */
1459
1460                 strtolower(wsi->utf8_token[WSI_TOKEN_HTTP].token);
1461                 if (strcmp(wsi->utf8_token[WSI_TOKEN_HTTP].token,
1462                                                    "101 switching protocols")) {
1463                         fprintf(stderr, "libwebsocket_client_handshake "
1464                                         "server sent bad HTTP response '%s'\n",
1465                                          wsi->utf8_token[WSI_TOKEN_HTTP].token);
1466                         goto bail3;
1467                 }
1468
1469                 strtolower(wsi->utf8_token[WSI_TOKEN_UPGRADE].token);
1470                 if (strcmp(wsi->utf8_token[WSI_TOKEN_UPGRADE].token,
1471                                                                  "websocket")) {
1472                         fprintf(stderr, "libwebsocket_client_handshake server "
1473                                         "sent bad Upgrade header '%s'\n",
1474                                       wsi->utf8_token[WSI_TOKEN_UPGRADE].token);
1475                         goto bail3;
1476                 }
1477
1478                 strtolower(wsi->utf8_token[WSI_TOKEN_CONNECTION].token);
1479                 if (strcmp(wsi->utf8_token[WSI_TOKEN_CONNECTION].token,
1480                                                                    "upgrade")) {
1481                         fprintf(stderr, "libwebsocket_client_handshake server "
1482                                         "sent bad Connection hdr '%s'\n",
1483                                    wsi->utf8_token[WSI_TOKEN_CONNECTION].token);
1484                         goto bail3;
1485                 }
1486
1487 select_protocol:
1488                 pc = wsi->c_protocol;
1489
1490                 /*
1491                  * confirm the protocol the server wants to talk was in the list
1492                  * of protocols we offered
1493                  */
1494
1495                 if (!wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len) {
1496
1497                         /*
1498                          * no protocol name to work from,
1499                          * default to first protocol
1500                          */
1501                         wsi->protocol = &context->protocols[0];
1502
1503                         free(wsi->c_protocol);
1504
1505                         goto check_accept;
1506                 }
1507
1508                 while (*pc && !okay) {
1509                         if ((!strncmp(pc,
1510                                 wsi->utf8_token[WSI_TOKEN_PROTOCOL].token,
1511                            wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len)) &&
1512                  (pc[wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len] == ',' ||
1513                    pc[wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len] == '\0')) {
1514                                 okay = 1;
1515                                 continue;
1516                         }
1517                         while (*pc && *pc != ',')
1518                                 pc++;
1519                         while (*pc && *pc != ' ')
1520                                 pc++;
1521                 }
1522
1523                 /* done with him now */
1524
1525                 if (wsi->c_protocol)
1526                         free(wsi->c_protocol);
1527
1528
1529                 if (!okay) {
1530                         fprintf(stderr, "libwebsocket_client_handshake server "
1531                                                 "sent bad protocol '%s'\n",
1532                                      wsi->utf8_token[WSI_TOKEN_PROTOCOL].token);
1533                         goto bail2;
1534                 }
1535
1536                 /*
1537                  * identify the selected protocol struct and set it
1538                  */
1539                 n = 0;
1540                 wsi->protocol = NULL;
1541                 while (context->protocols[n].callback) {
1542                         if (strcmp(wsi->utf8_token[WSI_TOKEN_PROTOCOL].token,
1543                                                context->protocols[n].name) == 0)
1544                                 wsi->protocol = &context->protocols[n];
1545                         n++;
1546                 }
1547
1548                 if (wsi->protocol == NULL) {
1549                         fprintf(stderr, "libwebsocket_client_handshake server "
1550                                         "requested protocol '%s', which we "
1551                                         "said we supported but we don't!\n",
1552                                      wsi->utf8_token[WSI_TOKEN_PROTOCOL].token);
1553                         goto bail2;
1554                 }
1555
1556
1557                 /* instantiate the accepted extensions */
1558
1559                 if (!wsi->utf8_token[WSI_TOKEN_EXTENSIONS].token_len)
1560                         goto check_accept;
1561
1562                 /*
1563                  * break down the list of server accepted extensions
1564                  * and go through matching them or identifying bogons
1565                  */
1566
1567                 c = wsi->utf8_token[WSI_TOKEN_EXTENSIONS].token;
1568                 n = 0;
1569                 while (more) {
1570                         
1571                         if (*c && *c != ',') {
1572                                 ext_name[n] = *c++;
1573                                 if (n < sizeof(ext_name) - 1)
1574                                         n++;
1575                                 continue;
1576                         }
1577                         ext_name[n] = '\0';
1578                         if (!*c)
1579                                 more = 0;
1580
1581                         /* check we actually support it */
1582
1583                         n = 0;
1584                         ext = wsi->protocol->owning_server->extensions;
1585                         while (ext && ext->callback) {
1586
1587                                 if (strcmp(ext_name, ext->name)) {
1588                                         ext++;
1589                                         continue;
1590                                 }
1591
1592                                 n = 1;
1593
1594                                 /* instantiate the extension on this conn */
1595
1596                                 wsi->active_extensions_user[
1597                                         wsi->count_active_extensions] =
1598                                              malloc(ext->per_session_data_size);
1599                                 wsi->active_extensions[
1600                                           wsi->count_active_extensions] = ext;
1601
1602                                 /* allow him to construct his context */
1603
1604                                 ext->callback(wsi->protocol->owning_server,
1605                                         ext, wsi,
1606                                            LWS_EXT_CALLBACK_CLIENT_CONSTRUCT,
1607                                                 wsi->active_extensions_user[
1608                                                  wsi->count_active_extensions],
1609                                                                        NULL, 0);
1610
1611                                 wsi->count_active_extensions++;
1612
1613                                 ext++;
1614                         }
1615
1616                         if (n == 0) {
1617                                 fprintf(stderr, "Server said we should use"
1618                                       "an unknown extension '%s'!\n", ext_name);
1619                                 goto bail2;
1620                         }
1621
1622                         n = 0;
1623                 }
1624
1625
1626         check_accept:
1627
1628                 if (wsi->ietf_spec_revision == 0) {
1629                         
1630                         if (memcmp(wsi->initial_handshake_hash_base64,
1631                               wsi->utf8_token[WSI_TOKEN_CHALLENGE].token, 16)) {
1632                                 fprintf(stderr, "libwebsocket_client_handshake "
1633                                                "failed 00 challenge compare\n");        
1634                                         pkt[len] = '\0';
1635                                         fprintf(stderr, "%s", pkt);
1636                                         goto bail2;
1637                         }
1638                         
1639                         goto accept_ok;
1640                 }
1641
1642                 /*
1643                  * Confirm his accept token is the one we precomputed
1644                  */
1645
1646                 if (strcmp(wsi->utf8_token[WSI_TOKEN_ACCEPT].token,
1647                                           wsi->initial_handshake_hash_base64)) {
1648                         fprintf(stderr, "libwebsocket_client_handshake server "
1649                                 "sent bad ACCEPT '%s' vs computed '%s'\n",
1650                                 wsi->utf8_token[WSI_TOKEN_ACCEPT].token,
1651                                             wsi->initial_handshake_hash_base64);
1652                         goto bail2;
1653                 }
1654
1655                 if (wsi->ietf_spec_revision == 4) {
1656                         /*
1657                          * Calculate the 04 masking key to use when
1658                          * sending data to server
1659                          */
1660
1661                         strcpy((char *)buf, wsi->key_b64);
1662                         p = (char *)buf + strlen(wsi->key_b64);
1663                         strcpy(p, wsi->utf8_token[WSI_TOKEN_NONCE].token);
1664                         p += wsi->utf8_token[WSI_TOKEN_NONCE].token_len;
1665                         strcpy(p, magic_websocket_04_masking_guid);
1666                         SHA1(buf, strlen((char *)buf), wsi->masking_key_04);
1667                 }
1668 accept_ok:
1669
1670                 /* allocate the per-connection user memory (if any) */
1671
1672                 if (wsi->protocol->per_session_data_size) {
1673                         wsi->user_space = malloc(
1674                                           wsi->protocol->per_session_data_size);
1675                         if (wsi->user_space  == NULL) {
1676                                 fprintf(stderr, "Out of memory for "
1677                                                            "conn user space\n");
1678                                 goto bail2;
1679                         }
1680                 } else
1681                         wsi->user_space = NULL;
1682
1683                 /* clear his proxy connection timeout */
1684
1685                 libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
1686
1687                 /* mark him as being alive */
1688
1689                 wsi->state = WSI_STATE_ESTABLISHED;
1690                 wsi->mode = LWS_CONNMODE_WS_CLIENT;
1691
1692                 fprintf(stderr, "handshake OK for protocol %s\n",
1693                                                            wsi->protocol->name);
1694
1695                 /* call him back to inform him he is up */
1696
1697                 wsi->protocol->callback(context, wsi,
1698                                  LWS_CALLBACK_CLIENT_ESTABLISHED,
1699                                  wsi->user_space,
1700                                  NULL, 0);
1701
1702                 break;
1703
1704 bail3:
1705                 if (wsi->c_protocol)
1706                         free(wsi->c_protocol);
1707
1708 bail2:
1709                 libwebsocket_close_and_free_session(context, wsi,
1710                                                      LWS_CLOSE_STATUS_NOSTATUS);
1711                 return 1;
1712                 
1713
1714         case LWS_CONNMODE_WS_SERVING:
1715         case LWS_CONNMODE_WS_CLIENT:
1716
1717                 /* handle session socket closed */
1718
1719                 if (pollfd->revents & (POLLERR | POLLHUP)) {
1720
1721                         fprintf(stderr, "Session Socket %p (fd=%d) dead\n",
1722                                 (void *)wsi, pollfd->fd);
1723
1724                         libwebsocket_close_and_free_session(context, wsi,
1725                                                      LWS_CLOSE_STATUS_NOSTATUS);
1726                         return 1;
1727                 }
1728
1729                 /* the guy requested a callback when it was OK to write */
1730
1731                 if ((pollfd->revents & POLLOUT) &&
1732                                             wsi->state == WSI_STATE_ESTABLISHED)
1733                         if (lws_handle_POLLOUT_event(context, wsi,
1734                                                                   pollfd) < 0) {
1735                                 libwebsocket_close_and_free_session(
1736                                          context, wsi, LWS_CLOSE_STATUS_NORMAL);
1737                                 return 1;
1738                         }
1739
1740
1741                 /* any incoming data ready? */
1742
1743                 if (!(pollfd->revents & POLLIN))
1744                         break;
1745
1746 #ifdef LWS_OPENSSL_SUPPORT
1747                 if (wsi->ssl)
1748                         eff_buf.token_len = SSL_read(wsi->ssl, buf, sizeof buf);
1749                 else
1750 #endif
1751                         eff_buf.token_len =
1752                                         libwebsocket_recv(pollfd->fd, buf,
1753                                         sizeof buf, 0);
1754
1755                 if (eff_buf.token_len < 0) {
1756                         fprintf(stderr, "Socket read returned %d\n",
1757                                                             eff_buf.token_len);
1758                         break;
1759                 }
1760                 if (!eff_buf.token_len) {
1761                         libwebsocket_close_and_free_session(context, wsi,
1762                                                      LWS_CLOSE_STATUS_NOSTATUS);
1763                         return 1;
1764                 }
1765
1766                 /*
1767                  * give any active extensions a chance to munge the buffer
1768                  * before parse.  We pass in a pointer to an lws_tokens struct
1769                  * prepared with the default buffer and content length that's in
1770                  * there.  Rather than rewrite the default buffer, extensions
1771                  * that expect to grow the buffer can adapt .token to
1772                  * point to their own per-connection buffer in the extension
1773                  * user allocation.  By default with no extensions or no
1774                  * extension callback handling, just the normal input buffer is
1775                  * used then so it is efficient.
1776                  */
1777
1778                 eff_buf.token = (char *)buf;
1779
1780                 more = 1;
1781                 while (more) {
1782
1783                         more = 0;
1784
1785                         for (n = 0; n < wsi->count_active_extensions; n++) {
1786                                 m = wsi->active_extensions[n]->callback(context,
1787                                         wsi->active_extensions[n], wsi,
1788                                         LWS_EXT_CALLBACK_PACKET_RX_PREPARSE,
1789                                         wsi->active_extensions_user[n],
1790                                                                    &eff_buf, 0);
1791                                 if (m < 0) {
1792                                         fprintf(stderr, "Extension reports fatal error\n");
1793                                         libwebsocket_close_and_free_session(context, wsi,
1794                                                              LWS_CLOSE_STATUS_NOSTATUS);
1795                                         return 1;
1796                                 }
1797                                 if (m)
1798                                         more = 1;
1799                         }
1800
1801                         /* service incoming data */
1802
1803                         if (eff_buf.token_len) {
1804                                 n = libwebsocket_read(context, wsi,
1805                                      (unsigned char *)eff_buf.token, eff_buf.token_len);
1806                                 if (n < 0)
1807                                         /* we closed wsi */
1808                                         return 1;
1809                         }
1810
1811                         eff_buf.token = NULL;
1812                         eff_buf.token_len = 0;
1813                 }
1814                 break;
1815         }
1816
1817         return 0;
1818 }
1819
1820
1821 /**
1822  * libwebsocket_context_destroy() - Destroy the websocket context
1823  * @context:    Websocket context
1824  *
1825  *      This function closes any active connections and then frees the
1826  *      context.  After calling this, any further use of the context is
1827  *      undefined.
1828  */
1829 void
1830 libwebsocket_context_destroy(struct libwebsocket_context *context)
1831 {
1832         int n;
1833         int m;
1834         struct libwebsocket *wsi;
1835
1836         for (n = 0; n < FD_HASHTABLE_MODULUS; n++)
1837                 for (m = 0; m < context->fd_hashtable[n].length; m++) {
1838                         wsi = context->fd_hashtable[n].wsi[m];
1839                         libwebsocket_close_and_free_session(context, wsi,
1840                                                     LWS_CLOSE_STATUS_GOINGAWAY);
1841                 }
1842
1843 #ifdef WIN32
1844 #else
1845         close(context->fd_random);
1846 #endif
1847
1848 #ifdef LWS_OPENSSL_SUPPORT
1849         if (context->ssl_ctx)
1850                 SSL_CTX_free(context->ssl_ctx);
1851         if (context->ssl_client_ctx)
1852                 SSL_CTX_free(context->ssl_client_ctx);
1853 #endif
1854
1855         free(context);
1856
1857 #ifdef WIN32
1858         WSACleanup();
1859 #endif
1860 }
1861
1862 /**
1863  * libwebsocket_service() - Service any pending websocket activity
1864  * @context:    Websocket context
1865  * @timeout_ms: Timeout for poll; 0 means return immediately if nothing needed
1866  *              service otherwise block and service immediately, returning
1867  *              after the timeout if nothing needed service.
1868  *
1869  *      This function deals with any pending websocket traffic, for three
1870  *      kinds of event.  It handles these events on both server and client
1871  *      types of connection the same.
1872  *
1873  *      1) Accept new connections to our context's server
1874  *
1875  *      2) Perform pending broadcast writes initiated from other forked
1876  *         processes (effectively serializing asynchronous broadcasts)
1877  *
1878  *      3) Call the receive callback for incoming frame data received by
1879  *          server or client connections.
1880  *
1881  *      You need to call this service function periodically to all the above
1882  *      functions to happen; if your application is single-threaded you can
1883  *      just call it in your main event loop.
1884  *
1885  *      Alternatively you can fork a new process that asynchronously handles
1886  *      calling this service in a loop.  In that case you are happy if this
1887  *      call blocks your thread until it needs to take care of something and
1888  *      would call it with a large nonzero timeout.  Your loop then takes no
1889  *      CPU while there is nothing happening.
1890  *
1891  *      If you are calling it in a single-threaded app, you don't want it to
1892  *      wait around blocking other things in your loop from happening, so you
1893  *      would call it with a timeout_ms of 0, so it returns immediately if
1894  *      nothing is pending, or as soon as it services whatever was pending.
1895  */
1896
1897
1898 int
1899 libwebsocket_service(struct libwebsocket_context *context, int timeout_ms)
1900 {
1901         int n;
1902
1903         /* stay dead once we are dead */
1904
1905         if (context == NULL)
1906                 return 1;
1907
1908         /* wait for something to need service */
1909
1910         n = poll(context->fds, context->fds_count, timeout_ms);
1911         if (n == 0) /* poll timeout */
1912                 return 0;
1913
1914         if (n < 0) {
1915                 /*
1916                 fprintf(stderr, "Listen Socket dead\n");
1917                 */
1918                 return 1;
1919         }
1920
1921         /* handle accept on listening socket? */
1922
1923         for (n = 0; n < context->fds_count; n++)
1924                 if (context->fds[n].revents)
1925                         libwebsocket_service_fd(context, &context->fds[n]);
1926
1927         return 0;
1928 }
1929
1930 /**
1931  * libwebsocket_callback_on_writable() - Request a callback when this socket
1932  *                                       becomes able to be written to without
1933  *                                       blocking
1934  *
1935  * @context:    libwebsockets context
1936  * @wsi:        Websocket connection instance to get callback for
1937  */
1938
1939 int
1940 libwebsocket_callback_on_writable(struct libwebsocket_context *context,
1941                                                        struct libwebsocket *wsi)
1942 {
1943         int n;
1944
1945         for (n = 0; n < context->fds_count; n++)
1946                 if (context->fds[n].fd == wsi->sock) {
1947                         context->fds[n].events |= POLLOUT;
1948                         n = context->fds_count;
1949                 }
1950
1951         /* external POLL support via protocol 0 */
1952         context->protocols[0].callback(context, wsi,
1953                 LWS_CALLBACK_SET_MODE_POLL_FD,
1954                 (void *)(long)wsi->sock, NULL, POLLOUT);
1955
1956         return 1;
1957 }
1958
1959 /**
1960  * libwebsocket_callback_on_writable_all_protocol() - Request a callback for
1961  *                      all connections using the given protocol when it
1962  *                      becomes possible to write to each socket without
1963  *                      blocking in turn.
1964  *
1965  * @protocol:   Protocol whose connections will get callbacks
1966  */
1967
1968 int
1969 libwebsocket_callback_on_writable_all_protocol(
1970                                   const struct libwebsocket_protocols *protocol)
1971 {
1972         struct libwebsocket_context *context = protocol->owning_server;
1973         int n;
1974         int m;
1975         struct libwebsocket *wsi;
1976
1977         for (n = 0; n < FD_HASHTABLE_MODULUS; n++) {
1978
1979                 for (m = 0; m < context->fd_hashtable[n].length; m++) {
1980
1981                         wsi = context->fd_hashtable[n].wsi[m];
1982
1983                         if (wsi->protocol == protocol)
1984                                 libwebsocket_callback_on_writable(context, wsi);
1985                 }
1986         }
1987
1988         return 0;
1989 }
1990
1991 /**
1992  * libwebsocket_set_timeout() - marks the wsi as subject to a timeout
1993  *
1994  * You will not need this unless you are doing something special
1995  *
1996  * @wsi:        Websocket connection instance
1997  * @reason:     timeout reason
1998  * @secs:       how many seconds
1999  */
2000
2001 void
2002 libwebsocket_set_timeout(struct libwebsocket *wsi,
2003                                           enum pending_timeout reason, int secs)
2004 {
2005         struct timeval tv;
2006
2007         gettimeofday(&tv, NULL);
2008
2009         wsi->pending_timeout_limit = tv.tv_sec + secs;
2010         wsi->pending_timeout = reason;
2011 }
2012
2013
2014 /**
2015  * libwebsocket_get_socket_fd() - returns the socket file descriptor
2016  *
2017  * You will not need this unless you are doing something special
2018  *
2019  * @wsi:        Websocket connection instance
2020  */
2021
2022 int
2023 libwebsocket_get_socket_fd(struct libwebsocket *wsi)
2024 {
2025         return wsi->sock;
2026 }
2027
2028 /**
2029  * libwebsocket_rx_flow_control() - Enable and disable socket servicing for
2030  *                              receieved packets.
2031  *
2032  * If the output side of a server process becomes choked, this allows flow
2033  * control for the input side.
2034  *
2035  * @wsi:        Websocket connection instance to get callback for
2036  * @enable:     0 = disable read servicing for this connection, 1 = enable
2037  */
2038
2039 int
2040 libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable)
2041 {
2042         struct libwebsocket_context *context = wsi->protocol->owning_server;
2043         int n;
2044
2045         for (n = 0; n < context->fds_count; n++)
2046                 if (context->fds[n].fd == wsi->sock) {
2047                         if (enable)
2048                                 context->fds[n].events |= POLLIN;
2049                         else
2050                                 context->fds[n].events &= ~POLLIN;
2051
2052                         return 0;
2053                 }
2054
2055         if (enable)
2056                 /* external POLL support via protocol 0 */
2057                 context->protocols[0].callback(context, wsi,
2058                         LWS_CALLBACK_SET_MODE_POLL_FD,
2059                         (void *)(long)wsi->sock, NULL, POLLIN);
2060         else
2061                 /* external POLL support via protocol 0 */
2062                 context->protocols[0].callback(context, wsi,
2063                         LWS_CALLBACK_CLEAR_MODE_POLL_FD,
2064                         (void *)(long)wsi->sock, NULL, POLLIN);
2065
2066
2067         fprintf(stderr, "libwebsocket_callback_on_writable "
2068                                                      "unable to find socket\n");
2069         return 1;
2070 }
2071
2072 /**
2073  * libwebsocket_canonical_hostname() - returns this host's hostname
2074  *
2075  * This is typically used by client code to fill in the host parameter
2076  * when making a client connection.  You can only call it after the context
2077  * has been created.
2078  *
2079  * @context:    Websocket context
2080  */
2081
2082
2083 extern const char *
2084 libwebsocket_canonical_hostname(struct libwebsocket_context *context)
2085 {
2086         return (const char *)context->canonical_hostname;
2087 }
2088
2089
2090 static void sigpipe_handler(int x)
2091 {
2092 }
2093
2094 #ifdef LWS_OPENSSL_SUPPORT
2095 static int
2096 OpenSSL_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
2097 {
2098
2099         SSL *ssl;
2100         int n;
2101         struct libwebsocket_context *context;
2102
2103         ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
2104                 SSL_get_ex_data_X509_STORE_CTX_idx());
2105
2106         /*
2107          * !!! nasty openssl requires the index to come as a library-scope
2108          * static
2109          */
2110         context = SSL_get_ex_data(ssl, openssl_websocket_private_data_index);
2111         
2112         n = context->protocols[0].callback(NULL, NULL,
2113                 LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION,
2114                                                    x509_ctx, ssl, preverify_ok);
2115
2116         /* convert return code from 0 = OK to 1 = OK */
2117
2118         if (!n)
2119                 n = 1;
2120         else
2121                 n = 0;
2122
2123         return n;
2124 }
2125 #endif
2126
2127
2128 /**
2129  * libwebsocket_create_context() - Create the websocket handler
2130  * @port:       Port to listen on... you can use 0 to suppress listening on
2131  *              any port, that's what you want if you are not running a
2132  *              websocket server at all but just using it as a client
2133  * @interf:  NULL to bind the listen socket to all interfaces, or the
2134  *              interface name, eg, "eth2"
2135  * @protocols:  Array of structures listing supported protocols and a protocol-
2136  *              specific callback for each one.  The list is ended with an
2137  *              entry that has a NULL callback pointer.
2138  *              It's not const because we write the owning_server member
2139  * @extensions: NULL or array of libwebsocket_extension structs listing the
2140  *              extensions this context supports
2141  * @ssl_cert_filepath:  If libwebsockets was compiled to use ssl, and you want
2142  *                      to listen using SSL, set to the filepath to fetch the
2143  *                      server cert from, otherwise NULL for unencrypted
2144  * @ssl_private_key_filepath: filepath to private key if wanting SSL mode,
2145  *                      else ignored
2146  * @gid:        group id to change to after setting listen socket, or -1.
2147  * @uid:        user id to change to after setting listen socket, or -1.
2148  * @options:    0, or LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK
2149  *
2150  *      This function creates the listening socket and takes care
2151  *      of all initialization in one step.
2152  *
2153  *      After initialization, it returns a struct libwebsocket_context * that
2154  *      represents this server.  After calling, user code needs to take care
2155  *      of calling libwebsocket_service() with the context pointer to get the
2156  *      server's sockets serviced.  This can be done in the same process context
2157  *      or a forked process, or another thread,
2158  *
2159  *      The protocol callback functions are called for a handful of events
2160  *      including http requests coming in, websocket connections becoming
2161  *      established, and data arriving; it's also called periodically to allow
2162  *      async transmission.
2163  *
2164  *      HTTP requests are sent always to the FIRST protocol in @protocol, since
2165  *      at that time websocket protocol has not been negotiated.  Other
2166  *      protocols after the first one never see any HTTP callack activity.
2167  *
2168  *      The server created is a simple http server by default; part of the
2169  *      websocket standard is upgrading this http connection to a websocket one.
2170  *
2171  *      This allows the same server to provide files like scripts and favicon /
2172  *      images or whatever over http and dynamic data over websockets all in
2173  *      one place; they're all handled in the user callback.
2174  */
2175
2176 struct libwebsocket_context *
2177 libwebsocket_create_context(int port, const char *interf,
2178                                struct libwebsocket_protocols *protocols,
2179                                struct libwebsocket_extension *extensions,
2180                                const char *ssl_cert_filepath,
2181                                const char *ssl_private_key_filepath,
2182                                int gid, int uid, unsigned int options)
2183 {
2184         int n;
2185         int sockfd = 0;
2186         int fd;
2187         struct sockaddr_in serv_addr, cli_addr;
2188         int opt = 1;
2189         struct libwebsocket_context *context = NULL;
2190         unsigned int slen;
2191         char *p;
2192         char hostname[1024];
2193         struct hostent *he;
2194         struct libwebsocket *wsi;
2195
2196 #ifdef LWS_OPENSSL_SUPPORT
2197         SSL_METHOD *method;
2198         char ssl_err_buf[512];
2199 #endif
2200
2201 #ifdef _WIN32
2202         {
2203                 WORD wVersionRequested;
2204                 WSADATA wsaData;
2205                 int err;
2206
2207                 /* Use the MAKEWORD(lowbyte, highbyte) macro from Windef.h */
2208                 wVersionRequested = MAKEWORD(2, 2);
2209
2210                 err = WSAStartup(wVersionRequested, &wsaData);
2211                 if (err != 0) {
2212                         /* Tell the user that we could not find a usable */
2213                         /* Winsock DLL.                                  */
2214                         fprintf(stderr, "WSAStartup failed with error: %d\n",
2215                                                                            err);
2216                         return NULL;
2217                 }
2218         }
2219 #endif
2220
2221
2222         context = malloc(sizeof(struct libwebsocket_context));
2223         if (!context) {
2224                 fprintf(stderr, "No memory for websocket context\n");
2225                 return NULL;
2226         }
2227         context->protocols = protocols;
2228         context->listen_port = port;
2229         context->http_proxy_port = 0;
2230         context->http_proxy_address[0] = '\0';
2231         context->options = options;
2232         context->fds_count = 0;
2233         context->extensions = extensions;
2234
2235 #ifdef WIN32
2236         context->fd_random = 0;
2237 #else
2238         context->fd_random = open(SYSTEM_RANDOM_FILEPATH, O_RDONLY);
2239         if (context->fd_random < 0) {
2240                 fprintf(stderr, "Unable to open random device %s %d\n",
2241                                     SYSTEM_RANDOM_FILEPATH, context->fd_random);
2242                 return NULL;
2243         }
2244 #endif
2245
2246 #ifdef LWS_OPENSSL_SUPPORT
2247         context->use_ssl = 0;
2248         context->ssl_ctx = NULL;
2249         context->ssl_client_ctx = NULL;
2250         openssl_websocket_private_data_index = 0;
2251 #endif
2252         /* find canonical hostname */
2253
2254         hostname[(sizeof hostname) - 1] = '\0';
2255         gethostname(hostname, (sizeof hostname) - 1);
2256         he = gethostbyname(hostname);
2257         if (he) {
2258                 strncpy(context->canonical_hostname, he->h_name,
2259                                         sizeof context->canonical_hostname - 1);
2260                 context->canonical_hostname[
2261                                 sizeof context->canonical_hostname - 1] = '\0';
2262         } else
2263                 strncpy(context->canonical_hostname, hostname,
2264                                         sizeof context->canonical_hostname - 1);
2265
2266         /* split the proxy ads:port if given */
2267
2268         p = getenv("http_proxy");
2269         if (p) {
2270                 strncpy(context->http_proxy_address, p,
2271                                         sizeof context->http_proxy_address - 1);
2272                 context->http_proxy_address[
2273                                  sizeof context->http_proxy_address - 1] = '\0';
2274
2275                 p = strchr(context->http_proxy_address, ':');
2276                 if (p == NULL) {
2277                         fprintf(stderr, "http_proxy needs to be ads:port\n");
2278                         return NULL;
2279                 }
2280                 *p = '\0';
2281                 context->http_proxy_port = atoi(p + 1);
2282
2283                 fprintf(stderr, "Using proxy %s:%u\n",
2284                                 context->http_proxy_address,
2285                                                       context->http_proxy_port);
2286         }
2287
2288         if (port) {
2289
2290 #ifdef LWS_OPENSSL_SUPPORT
2291                 context->use_ssl = ssl_cert_filepath != NULL &&
2292                                                ssl_private_key_filepath != NULL;
2293                 if (context->use_ssl)
2294                         fprintf(stderr, " Compiled with SSL support, "
2295                                                                   "using it\n");
2296                 else
2297                         fprintf(stderr, " Compiled with SSL support, "
2298                                                               "not using it\n");
2299
2300 #else
2301                 if (ssl_cert_filepath != NULL &&
2302                                              ssl_private_key_filepath != NULL) {
2303                         fprintf(stderr, " Not compiled for OpenSSl support!\n");
2304                         return NULL;
2305                 }
2306                 fprintf(stderr, " Compiled without SSL support, "
2307                                                        "serving unencrypted\n");
2308 #endif
2309         }
2310
2311         /* ignore SIGPIPE */
2312 #ifdef WIN32
2313 #else
2314         signal(SIGPIPE, sigpipe_handler);
2315 #endif
2316
2317
2318 #ifdef LWS_OPENSSL_SUPPORT
2319
2320         /* basic openssl init */
2321
2322         SSL_library_init();
2323
2324         OpenSSL_add_all_algorithms();
2325         SSL_load_error_strings();
2326
2327         openssl_websocket_private_data_index =
2328                 SSL_get_ex_new_index(0, "libwebsockets", NULL, NULL, NULL);
2329
2330         /*
2331          * Firefox insists on SSLv23 not SSLv3
2332          * Konq disables SSLv2 by default now, SSLv23 works
2333          */
2334
2335         method = (SSL_METHOD *)SSLv23_server_method();
2336         if (!method) {
2337                 fprintf(stderr, "problem creating ssl method: %s\n",
2338                         ERR_error_string(ERR_get_error(), ssl_err_buf));
2339                 return NULL;
2340         }
2341         context->ssl_ctx = SSL_CTX_new(method); /* create context */
2342         if (!context->ssl_ctx) {
2343                 fprintf(stderr, "problem creating ssl context: %s\n",
2344                         ERR_error_string(ERR_get_error(), ssl_err_buf));
2345                 return NULL;
2346         }
2347
2348         /* client context */
2349         if (port == CONTEXT_PORT_NO_LISTEN)
2350         {
2351                 method = (SSL_METHOD *)SSLv23_client_method();
2352                 if (!method) {
2353                         fprintf(stderr, "problem creating ssl method: %s\n",
2354                                 ERR_error_string(ERR_get_error(), ssl_err_buf));
2355                         return NULL;
2356                 }
2357                 /* create context */
2358                 context->ssl_client_ctx = SSL_CTX_new(method);
2359                 if (!context->ssl_client_ctx) {
2360                         fprintf(stderr, "problem creating ssl context: %s\n",
2361                                 ERR_error_string(ERR_get_error(), ssl_err_buf));
2362                         return NULL;
2363                 }
2364
2365                 /* openssl init for cert verification (for client sockets) */
2366
2367                 if (!SSL_CTX_load_verify_locations(
2368                                         context->ssl_client_ctx, NULL,
2369                                                       LWS_OPENSSL_CLIENT_CERTS))
2370                         fprintf(stderr,
2371                             "Unable to load SSL Client certs from %s "
2372                             "(set by --with-client-cert-dir= in configure) -- "
2373                                 " client ssl isn't going to work",
2374                                                       LWS_OPENSSL_CLIENT_CERTS);
2375
2376                 /*
2377                  * callback allowing user code to load extra verification certs
2378                  * helping the client to verify server identity
2379                  */
2380
2381                 context->protocols[0].callback(context, NULL,
2382                         LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS,
2383                         context->ssl_client_ctx, NULL, 0);
2384         }
2385         /* as a server, are we requiring clients to identify themselves? */
2386
2387         if (options & LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT) {
2388
2389                 /* absolutely require the client cert */
2390                 
2391                 SSL_CTX_set_verify(context->ssl_ctx,
2392                        SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2393                                                        OpenSSL_verify_callback);
2394
2395                 /*
2396                  * give user code a chance to load certs into the server
2397                  * allowing it to verify incoming client certs
2398                  */
2399
2400                 context->protocols[0].callback(context, NULL,
2401                         LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS,
2402                                                      context->ssl_ctx, NULL, 0);
2403         }
2404
2405         if (context->use_ssl) {
2406
2407                 /* openssl init for server sockets */
2408
2409                 /* set the local certificate from CertFile */
2410                 n = SSL_CTX_use_certificate_file(context->ssl_ctx,
2411                                         ssl_cert_filepath, SSL_FILETYPE_PEM);
2412                 if (n != 1) {
2413                         fprintf(stderr, "problem getting cert '%s': %s\n",
2414                                 ssl_cert_filepath,
2415                                 ERR_error_string(ERR_get_error(), ssl_err_buf));
2416                         return NULL;
2417                 }
2418                 /* set the private key from KeyFile */
2419                 if (SSL_CTX_use_PrivateKey_file(context->ssl_ctx,
2420                              ssl_private_key_filepath, SSL_FILETYPE_PEM) != 1) {
2421                         fprintf(stderr, "ssl problem getting key '%s': %s\n",
2422                                                 ssl_private_key_filepath,
2423                                 ERR_error_string(ERR_get_error(), ssl_err_buf));
2424                         return NULL;
2425                 }
2426                 /* verify private key */
2427                 if (!SSL_CTX_check_private_key(context->ssl_ctx)) {
2428                         fprintf(stderr, "Private SSL key doesn't match cert\n");
2429                         return NULL;
2430                 }
2431
2432                 /* SSL is happy and has a cert it's content with */
2433         }
2434 #endif
2435
2436         /* selftest */
2437
2438         if (lws_b64_selftest())
2439                 return NULL;
2440
2441         /* fd hashtable init */
2442
2443         for (n = 0; n < FD_HASHTABLE_MODULUS; n++)
2444                 context->fd_hashtable[n].length = 0;
2445
2446         /* set up our external listening socket we serve on */
2447
2448         if (port) {
2449
2450                 sockfd = socket(AF_INET, SOCK_STREAM, 0);
2451                 if (sockfd < 0) {
2452                         fprintf(stderr, "ERROR opening socket");
2453                         return NULL;
2454                 }
2455
2456                 /* allow us to restart even if old sockets in TIME_WAIT */
2457                 setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
2458
2459
2460                 /* Disable Nagle */
2461                 opt = 1;
2462                 setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
2463
2464                 bzero((char *) &serv_addr, sizeof(serv_addr));
2465                 serv_addr.sin_family = AF_INET;
2466                 if (interf == NULL)
2467                         serv_addr.sin_addr.s_addr = INADDR_ANY;
2468                 else
2469                         interface_to_sa(interf, &serv_addr,
2470                                                 sizeof(serv_addr));
2471                 serv_addr.sin_port = htons(port);
2472
2473                 n = bind(sockfd, (struct sockaddr *) &serv_addr,
2474                                                              sizeof(serv_addr));
2475                 if (n < 0) {
2476                         fprintf(stderr, "ERROR on binding to port %d (%d %d)\n",
2477                                                                 port, n, errno);
2478                         return NULL;
2479                 }
2480
2481                 wsi = malloc(sizeof(struct libwebsocket));
2482                 memset(wsi, 0, sizeof (struct libwebsocket));
2483                 wsi->sock = sockfd;
2484                 wsi->count_active_extensions = 0;
2485                 wsi->mode = LWS_CONNMODE_SERVER_LISTENER;
2486                 insert_wsi(context, wsi);
2487
2488                 listen(sockfd, 5);
2489                 fprintf(stderr, " Listening on port %d\n", port);
2490
2491                 /* list in the internal poll array */
2492                 
2493                 context->fds[context->fds_count].fd = sockfd;
2494                 context->fds[context->fds_count++].events = POLLIN;
2495
2496                 /* external POLL support via protocol 0 */
2497                 context->protocols[0].callback(context, wsi,
2498                         LWS_CALLBACK_ADD_POLL_FD,
2499                         (void *)(long)sockfd, NULL, POLLIN);
2500
2501         }
2502
2503         /* drop any root privs for this process */
2504 #ifdef WIN32
2505 #else
2506         if (gid != -1)
2507                 if (setgid(gid))
2508                         fprintf(stderr, "setgid: %s\n", strerror(errno));
2509         if (uid != -1)
2510                 if (setuid(uid))
2511                         fprintf(stderr, "setuid: %s\n", strerror(errno));
2512 #endif
2513
2514         /* set up our internal broadcast trigger sockets per-protocol */
2515
2516         for (context->count_protocols = 0;
2517                         protocols[context->count_protocols].callback;
2518                                                    context->count_protocols++) {
2519                 protocols[context->count_protocols].owning_server = context;
2520                 protocols[context->count_protocols].protocol_index =
2521                                                        context->count_protocols;
2522
2523                 fd = socket(AF_INET, SOCK_STREAM, 0);
2524                 if (fd < 0) {
2525                         fprintf(stderr, "ERROR opening socket");
2526                         return NULL;
2527                 }
2528
2529                 /* allow us to restart even if old sockets in TIME_WAIT */
2530                 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
2531
2532                 bzero((char *) &serv_addr, sizeof(serv_addr));
2533                 serv_addr.sin_family = AF_INET;
2534                 serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
2535                 serv_addr.sin_port = 0; /* pick the port for us */
2536
2537                 n = bind(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
2538                 if (n < 0) {
2539                         fprintf(stderr, "ERROR on binding to port %d (%d %d)\n",
2540                                                                 port, n, errno);
2541                         return NULL;
2542                 }
2543
2544                 slen = sizeof cli_addr;
2545                 n = getsockname(fd, (struct sockaddr *)&cli_addr, &slen);
2546                 if (n < 0) {
2547                         fprintf(stderr, "getsockname failed\n");
2548                         return NULL;
2549                 }
2550                 protocols[context->count_protocols].broadcast_socket_port =
2551                                                        ntohs(cli_addr.sin_port);
2552                 listen(fd, 5);
2553
2554                 debug("  Protocol %s broadcast socket %d\n",
2555                                 protocols[context->count_protocols].name,
2556                                                       ntohs(cli_addr.sin_port));
2557
2558                 /* dummy wsi per broadcast proxy socket */
2559
2560                 wsi = malloc(sizeof(struct libwebsocket));
2561                 memset(wsi, 0, sizeof (struct libwebsocket));
2562                 wsi->sock = fd;
2563                 wsi->mode = LWS_CONNMODE_BROADCAST_PROXY_LISTENER;
2564                 wsi->count_active_extensions = 0;
2565                 /* note which protocol we are proxying */
2566                 wsi->protocol_index_for_broadcast_proxy =
2567                                                        context->count_protocols;
2568                 insert_wsi(context, wsi);
2569
2570                 /* list in internal poll array */
2571
2572                 context->fds[context->fds_count].fd = fd;
2573                 context->fds[context->fds_count].events = POLLIN;
2574                 context->fds[context->fds_count].revents = 0;
2575                 context->fds_count++;
2576
2577                 /* external POLL support via protocol 0 */
2578                 context->protocols[0].callback(context, wsi,
2579                         LWS_CALLBACK_ADD_POLL_FD,
2580                         (void *)(long)fd, NULL, POLLIN);
2581         }
2582
2583         return context;
2584 }
2585
2586
2587 #ifndef LWS_NO_FORK
2588
2589 /**
2590  * libwebsockets_fork_service_loop() - Optional helper function forks off
2591  *                                a process for the websocket server loop.
2592  *                              You don't have to use this but if not, you
2593  *                              have to make sure you are calling
2594  *                              libwebsocket_service periodically to service
2595  *                              the websocket traffic
2596  * @context:    server context returned by creation function
2597  */
2598
2599 int
2600 libwebsockets_fork_service_loop(struct libwebsocket_context *context)
2601 {
2602         int fd;
2603         struct sockaddr_in cli_addr;
2604         int n;
2605         int p;
2606
2607         n = fork();
2608         if (n < 0)
2609                 return n;
2610
2611         if (!n) {
2612
2613                 /* main process context */
2614
2615                 /*
2616                  * set up the proxy sockets to allow broadcast from
2617                  * service process context
2618                  */
2619
2620                 for (p = 0; p < context->count_protocols; p++) {
2621                         fd = socket(AF_INET, SOCK_STREAM, 0);
2622                         if (fd < 0) {
2623                                 fprintf(stderr, "Unable to create socket\n");
2624                                 return -1;
2625                         }
2626                         cli_addr.sin_family = AF_INET;
2627                         cli_addr.sin_port = htons(
2628                              context->protocols[p].broadcast_socket_port);
2629                         cli_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
2630                         n = connect(fd, (struct sockaddr *)&cli_addr,
2631                                                                sizeof cli_addr);
2632                         if (n < 0) {
2633                                 fprintf(stderr, "Unable to connect to "
2634                                                 "broadcast socket %d, %s\n",
2635                                                 n, strerror(errno));
2636                                 return -1;
2637                         }
2638
2639                         context->protocols[p].broadcast_socket_user_fd = fd;
2640                 }
2641
2642                 return 0;
2643         }
2644
2645         /* we want a SIGHUP when our parent goes down */
2646         prctl(PR_SET_PDEATHSIG, SIGHUP);
2647
2648         /* in this forked process, sit and service websocket connections */
2649
2650         while (1)
2651                 if (libwebsocket_service(context, 1000))
2652                         return -1;
2653
2654         return 0;
2655 }
2656
2657 #endif
2658
2659 /**
2660  * libwebsockets_get_protocol() - Returns a protocol pointer from a websocket
2661  *                                connection.
2662  * @wsi:        pointer to struct websocket you want to know the protocol of
2663  *
2664  *
2665  *      This is useful to get the protocol to broadcast back to from inside
2666  * the callback.
2667  */
2668
2669 const struct libwebsocket_protocols *
2670 libwebsockets_get_protocol(struct libwebsocket *wsi)
2671 {
2672         return wsi->protocol;
2673 }
2674
2675 /**
2676  * libwebsockets_broadcast() - Sends a buffer to the callback for all active
2677  *                                connections of the given protocol.
2678  * @protocol:   pointer to the protocol you will broadcast to all members of
2679  * @buf:  buffer containing the data to be broadcase.  NOTE: this has to be
2680  *              allocated with LWS_SEND_BUFFER_PRE_PADDING valid bytes before
2681  *              the pointer and LWS_SEND_BUFFER_POST_PADDING afterwards in the
2682  *              case you are calling this function from callback context.
2683  * @len:        length of payload data in buf, starting from buf.
2684  *
2685  *      This function allows bulk sending of a packet to every connection using
2686  * the given protocol.  It does not send the data directly; instead it calls
2687  * the callback with a reason type of LWS_CALLBACK_BROADCAST.  If the callback
2688  * wants to actually send the data for that connection, the callback itself
2689  * should call libwebsocket_write().
2690  *
2691  * libwebsockets_broadcast() can be called from another fork context without
2692  * having to take any care about data visibility between the processes, it'll
2693  * "just work".
2694  */
2695
2696
2697 int
2698 libwebsockets_broadcast(const struct libwebsocket_protocols *protocol,
2699                                                  unsigned char *buf, size_t len)
2700 {
2701         struct libwebsocket_context *context = protocol->owning_server;
2702         int n;
2703         int m;
2704         struct libwebsocket * wsi;
2705
2706         if (!protocol->broadcast_socket_user_fd) {
2707                 /*
2708                  * We are either running unforked / flat, or we are being
2709                  * called from poll thread context
2710                  * eg, from a callback.  In that case don't use sockets for
2711                  * broadcast IPC (since we can't open a socket connection to
2712                  * a socket listening on our own thread) but directly do the
2713                  * send action.
2714                  *
2715                  * Locking is not needed because we are by definition being
2716                  * called in the poll thread context and are serialized.
2717                  */
2718
2719                 for (n = 0; n < FD_HASHTABLE_MODULUS; n++) {
2720
2721                         for (m = 0; m < context->fd_hashtable[n].length; m++) {
2722
2723                                 wsi = context->fd_hashtable[n].wsi[m];
2724
2725                                 if (wsi->mode != LWS_CONNMODE_WS_SERVING)
2726                                         continue;
2727
2728                                 /*
2729                                  * never broadcast to
2730                                  * non-established connections
2731                                  */
2732                                 if (wsi->state != WSI_STATE_ESTABLISHED)
2733                                         continue;
2734
2735                                 /* only broadcast to guys using
2736                                  * requested protocol
2737                                  */
2738                                 if (wsi->protocol != protocol)
2739                                         continue;
2740
2741                                 wsi->protocol->callback(context, wsi,
2742                                          LWS_CALLBACK_BROADCAST,
2743                                          wsi->user_space,
2744                                          buf, len);
2745                         }
2746                 }
2747
2748                 return 0;
2749         }
2750
2751         /*
2752          * We're being called from a different process context than the server
2753          * loop.  Instead of broadcasting directly, we send our
2754          * payload on a socket to do the IPC; the server process will serialize
2755          * the broadcast action in its main poll() loop.
2756          *
2757          * There's one broadcast socket listening for each protocol supported
2758          * set up when the websocket server initializes
2759          */
2760
2761         n = send(protocol->broadcast_socket_user_fd, buf, len, MSG_NOSIGNAL);
2762
2763         return n;
2764 }
2765
2766 int
2767 libwebsocket_is_final_fragment(struct libwebsocket *wsi)
2768 {
2769         return wsi->final;
2770 }