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