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