clean-whitespace.patch
[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 LWS_OPENSSL_SUPPORT
25 SSL_CTX *ssl_ctx;
26 int use_ssl;
27 #endif
28
29 void
30 libwebsocket_close_and_free_session(struct libwebsocket *wsi)
31 {
32         int n;
33
34         if ((unsigned long)wsi < LWS_MAX_PROTOCOLS)
35                 return;
36
37         n = wsi->state;
38
39         wsi->state = WSI_STATE_DEAD_SOCKET;
40
41         if (wsi->protocol->callback && n == WSI_STATE_ESTABLISHED)
42                 wsi->protocol->callback(wsi, LWS_CALLBACK_CLOSED,
43                                                       wsi->user_space, NULL, 0);
44
45         for (n = 0; n < WSI_TOKEN_COUNT; n++)
46                 if (wsi->utf8_token[n].token)
47                         free(wsi->utf8_token[n].token);
48
49 /*      fprintf(stderr, "closing fd=%d\n", wsi->sock); */
50
51 #ifdef LWS_OPENSSL_SUPPORT
52         if (use_ssl) {
53                 n = SSL_get_fd(wsi->ssl);
54                 SSL_shutdown(wsi->ssl);
55                 close(n);
56                 SSL_free(wsi->ssl);
57         } else {
58 #endif
59                 shutdown(wsi->sock, SHUT_RDWR);
60                 close(wsi->sock);
61 #ifdef LWS_OPENSSL_SUPPORT
62         }
63 #endif
64         if (wsi->user_space)
65                 free(wsi->user_space);
66
67         free(wsi);
68 }
69
70 static int
71 libwebsocket_poll_connections(struct libwebsocket_context *this)
72 {
73         unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + MAX_BROADCAST_PAYLOAD +
74                                                   LWS_SEND_BUFFER_POST_PADDING];
75         int client = this->count_protocols + 1;
76         struct libwebsocket *wsi;
77         int n;
78         size_t len;
79
80         /* check for activity on client sockets */
81
82         for (; client < this->fds_count; client++) {
83
84                 /* handle session socket closed */
85
86                 if (this->fds[client].revents & (POLLERR | POLLHUP)) {
87
88                         debug("Session Socket %d %p (fd=%d) dead\n",
89                                   client, this->wsi[client], this->fds[client]);
90
91                         libwebsocket_close_and_free_session(this->wsi[client]);
92                         goto nuke_this;
93                 }
94
95                 /* any incoming data ready? */
96
97                 if (!(this->fds[client].revents & POLLIN))
98                         continue;
99
100                 /* broadcast? */
101
102                 if ((unsigned long)this->wsi[client] < LWS_MAX_PROTOCOLS) {
103
104                         /* get the issued broadcast payload from the socket */
105
106                         len = read(this->fds[client].fd,
107                                    buf + LWS_SEND_BUFFER_PRE_PADDING,
108                                    MAX_BROADCAST_PAYLOAD);
109
110                         if (len < 0) {
111                                 fprintf(stderr,
112                                            "Error reading broadcast payload\n");
113                                 continue;
114                         }
115
116                         /* broadcast it to all guys with this protocol index */
117
118                         for (n = this->count_protocols + 1;
119                                                      n < this->fds_count; n++) {
120
121                                 wsi = this->wsi[n];
122
123                                 if ((unsigned long)wsi < LWS_MAX_PROTOCOLS)
124                                         continue;
125
126                                 /*
127                                  * never broadcast to non-established
128                                  * connection
129                                  */
130
131                                 if (wsi->state != WSI_STATE_ESTABLISHED)
132                                         continue;
133
134                                 /*
135                                  * only broadcast to connections using
136                                  * the requested protocol
137                                  */
138
139                                 if (wsi->protocol->protocol_index !=
140                                           (int)(unsigned long)this->wsi[client])
141                                         continue;
142
143                                 /* broadcast it to this connection */
144
145                                 wsi->protocol->callback(wsi,
146                                         LWS_CALLBACK_BROADCAST,
147                                         wsi->user_space,
148                                         buf + LWS_SEND_BUFFER_PRE_PADDING, len);
149                         }
150
151                         continue;
152                 }
153
154 #ifdef LWS_OPENSSL_SUPPORT
155                 if (this->use_ssl)
156                         n = SSL_read(this->wsi[client]->ssl, buf, sizeof buf);
157                 else
158 #endif
159                         n = recv(this->fds[client].fd, buf, sizeof buf, 0);
160
161                 if (n < 0) {
162                         fprintf(stderr, "Socket read returned %d\n", n);
163                         continue;
164                 }
165                 if (!n) {
166                         libwebsocket_close_and_free_session(this->wsi[client]);
167                         goto nuke_this;
168                 }
169
170                 /* service incoming data */
171
172                 if (libwebsocket_read(this->wsi[client], buf, n) >= 0)
173                         continue;
174
175                 /*
176                  * it closed and nuked wsi[client], so remove the
177                  * socket handle and wsi from our service list
178                  */
179 nuke_this:
180
181                 debug("nuking wsi %p, fsd_count = %d\n",
182                                         this->wsi[client], this->fds_count - 1);
183
184                 this->fds_count--;
185                 for (n = client; n < this->fds_count; n++) {
186                         this->fds[n] = this->fds[n + 1];
187                         this->wsi[n] = this->wsi[n + 1];
188                 }
189                 break;
190         }
191
192         return 0;
193 }
194
195
196
197 /**
198  * libwebsocket_create_server() - Create the listening websockets server
199  * @port:       Port to listen on
200  * @protocols:  Array of structures listing supported protocols and a protocol-
201  *              specific callback for each one.  The list is ended with an
202  *              entry that has a NULL callback pointer.
203  *              It's not const because we write the owning_server member
204  * @ssl_cert_filepath:  If libwebsockets was compiled to use ssl, and you want
205  *                      to listen using SSL, set to the filepath to fetch the
206  *                      server cert from, otherwise NULL for unencrypted
207  * @ssl_private_key_filepath: filepath to private key if wanting SSL mode,
208  *                      else ignored
209  * @gid:        group id to change to after setting listen socket, or -1.
210  * @uid:        user id to change to after setting listen socket, or -1.
211  *
212  *      This function creates the listening socket and takes care
213  *      of all initialization in one step.
214  *
215  *      After initialization, it forks a thread that will sits in a service loop
216  *      and returns to the caller.  The actual service actions are performed by
217  *      user code in a per-protocol callback from the appropriate one selected
218  *      by the client from the list in @protocols.
219  *
220  *      The protocol callback functions are called for a handful of events
221  *      including http requests coming in, websocket connections becoming
222  *      established, and data arriving; it's also called periodically to allow
223  *      async transmission.
224  *
225  *      HTTP requests are sent always to the FIRST protocol in @protocol, since
226  *      at that time websocket protocol has not been negotiated.  Other
227  *      protocols after the first one never see any HTTP callack activity.
228  *
229  *      The server created is a simple http server by default; part of the
230  *      websocket standard is upgrading this http connection to a websocket one.
231  *
232  *      This allows the same server to provide files like scripts and favicon /
233  *      images or whatever over http and dynamic data over websockets all in
234  *      one place; they're all handled in the user callback.
235  */
236
237 int libwebsocket_create_server(int port,
238                                struct libwebsocket_protocols *protocols,
239                                const char *ssl_cert_filepath,
240                                const char *ssl_private_key_filepath,
241                                int gid, int uid)
242 {
243         int n;
244         int client;
245         int sockfd;
246         int fd;
247         unsigned int clilen;
248         struct sockaddr_in serv_addr, cli_addr;
249         int opt = 1;
250         struct libwebsocket_context *this = NULL;
251         unsigned int slen;
252
253 #ifdef LWS_OPENSSL_SUPPORT
254         SSL_METHOD *method;
255         char ssl_err_buf[512];
256
257         use_ssl = ssl_cert_filepath != NULL && ssl_private_key_filepath != NULL;
258         if (use_ssl)
259                 fprintf(stderr, " Compiled with SSL support, using it\n");
260         else
261                 fprintf(stderr, " Compiled with SSL support, not using it\n");
262
263 #else
264         if (ssl_cert_filepath != NULL && ssl_private_key_filepath != NULL) {
265                 fprintf(stderr, " Not compiled for OpenSSl support!\n");
266                 return -1;
267         }
268         fprintf(stderr, " Compiled without SSL support, serving unencrypted\n");
269 #endif
270
271 #ifdef LWS_OPENSSL_SUPPORT
272         if (use_ssl) {
273                 SSL_library_init();
274
275                 OpenSSL_add_all_algorithms();
276                 SSL_load_error_strings();
277
278                 /*
279                  * Firefox insists on SSLv23 not SSLv3
280                  * Konq disables SSLv2 by default now, SSLv23 works
281                  */
282
283                 method = (SSL_METHOD *)SSLv23_server_method();
284                 if (!method) {
285                         fprintf(stderr, "problem creating ssl method: %s\n",
286                                 ERR_error_string(ERR_get_error(), ssl_err_buf));
287                         return -1;
288                 }
289                 ssl_ctx = SSL_CTX_new(method);  /* create context */
290                 if (!ssl_ctx) {
291                         printf("problem creating ssl context: %s\n",
292                                 ERR_error_string(ERR_get_error(), ssl_err_buf));
293                         return -1;
294                 }
295                 /* set the local certificate from CertFile */
296                 n = SSL_CTX_use_certificate_file(ssl_ctx,
297                                         ssl_cert_filepath, SSL_FILETYPE_PEM);
298                 if (n != 1) {
299                         fprintf(stderr, "problem getting cert '%s': %s\n",
300                                 ssl_cert_filepath,
301                                 ERR_error_string(ERR_get_error(), ssl_err_buf));
302                         return -1;
303                 }
304                 /* set the private key from KeyFile */
305                 if (SSL_CTX_use_PrivateKey_file(ssl_ctx,
306                                                 ssl_private_key_filepath,
307                                                 SSL_FILETYPE_PEM) != 1) {
308                         fprintf(stderr, "ssl problem getting key '%s': %s\n",
309                                                 ssl_private_key_filepath,
310                                 ERR_error_string(ERR_get_error(), ssl_err_buf));
311                         return -1;
312                 }
313                 /* verify private key */
314                 if (!SSL_CTX_check_private_key(ssl_ctx)) {
315                         fprintf(stderr, "Private SSL key doesn't match cert\n");
316                         return -1;
317                 }
318
319                 /* SSL is happy and has a cert it's content with */
320         }
321 #endif
322
323         this = malloc(sizeof(struct libwebsocket_context));
324
325         /* set up our external listening socket we serve on */
326
327         sockfd = socket(AF_INET, SOCK_STREAM, 0);
328         if (sockfd < 0) {
329                 fprintf(stderr, "ERROR opening socket");
330                 return -1;
331         }
332
333         /* allow us to restart even if old sockets in TIME_WAIT */
334         setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
335
336         bzero((char *) &serv_addr, sizeof(serv_addr));
337         serv_addr.sin_family = AF_INET;
338         serv_addr.sin_addr.s_addr = INADDR_ANY;
339         serv_addr.sin_port = htons(port);
340
341         n = bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
342         if (n < 0) {
343                 fprintf(stderr, "ERROR on binding to port %d (%d %d)\n",
344                                                                 port, n, errno);
345                 return -1;
346         }
347
348         /* drop any root privs for this process */
349
350         if (gid != -1)
351                 if (setgid(gid))
352                         fprintf(stderr, "setgid: %s\n", strerror(errno));
353         if (uid != -1)
354                 if (setuid(uid))
355                         fprintf(stderr, "setuid: %s\n", strerror(errno));
356
357         /*
358          * prepare the poll() fd array... it's like this
359          *
360          * [0] = external listening socket
361          * [1 .. this->count_protocols] = per-protocol broadcast sockets
362          * [this->count_protocols + 1 ... this->fds_count-1] = connection skts
363          */
364
365         this->fds_count = 1;
366         this->fds[0].fd = sockfd;
367         this->fds[0].events = POLLIN;
368         this->count_protocols = 0;
369 #ifdef LWS_OPENSSL_SUPPORT
370         this->use_ssl = use_ssl;
371 #endif
372
373         listen(sockfd, 5);
374         fprintf(stderr, " Listening on port %d\n", port);
375
376         /* set up our internal broadcast trigger sockets per-protocol */
377
378         for (; protocols[this->count_protocols].callback;
379                                                       this->count_protocols++) {
380                 protocols[this->count_protocols].owning_server = this;
381                 protocols[this->count_protocols].protocol_index =
382                                                           this->count_protocols;
383
384                 fd = socket(AF_INET, SOCK_STREAM, 0);
385                 if (fd < 0) {
386                         fprintf(stderr, "ERROR opening socket");
387                         return -1;
388                 }
389
390                 /* allow us to restart even if old sockets in TIME_WAIT */
391                 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
392
393                 bzero((char *) &serv_addr, sizeof(serv_addr));
394                 serv_addr.sin_family = AF_INET;
395                 serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
396                 serv_addr.sin_port = 0; /* pick the port for us */
397
398                 n = bind(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
399                 if (n < 0) {
400                         fprintf(stderr, "ERROR on binding to port %d (%d %d)\n",
401                                                                 port, n, errno);
402                         return -1;
403                 }
404
405                 slen = sizeof cli_addr;
406                 n = getsockname(fd, (struct sockaddr *)&cli_addr, &slen);
407                 if (n < 0) {
408                         fprintf(stderr, "getsockname failed\n");
409                         return -1;
410                 }
411                 protocols[this->count_protocols].broadcast_socket_port =
412                                                        ntohs(cli_addr.sin_port);
413                 listen(fd, 5);
414
415                 debug("  Protocol %s broadcast socket %d\n",
416                                 protocols[this->count_protocols].name,
417                                                       ntohs(cli_addr.sin_port));
418
419                 this->fds[this->fds_count].fd = fd;
420                 this->fds[this->fds_count].events = POLLIN;
421                 /* wsi only exists for connections, not broadcast listener */
422                 this->wsi[this->fds_count] = NULL;
423                 this->fds_count++;
424         }
425
426
427         /*
428          * We will enter out poll and service loop now, just before that
429          * fork and return to caller for the main thread of execution
430          */
431
432         n = fork();
433         if (n < 0) {
434                 fprintf(stderr, "Failed to fork websocket poll loop\n");
435                 return -1;
436         }
437         if (n) {
438                 /* original process context */
439
440                 /*
441                  * before we return to caller, we set up per-protocol
442                  * broadcast sockets connected to the server ready to use
443                  */
444
445                 /* give server fork a chance to start up */
446                 usleep(500000);
447
448                 for (client = 1; client < this->count_protocols + 1; client++) {
449                         fd = socket(AF_INET, SOCK_STREAM, 0);
450                         if (fd < 0) {
451                                 fprintf(stderr, "Unable to create socket\n");
452                                 return -1;
453                         }
454                         cli_addr.sin_family = AF_INET;
455                         cli_addr.sin_port = htons(
456                                    protocols[client - 1].broadcast_socket_port);
457                         cli_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
458                         n = connect(fd, (struct sockaddr *)&cli_addr,
459                                                                sizeof cli_addr);
460                         if (n < 0) {
461                                 fprintf(stderr, "Unable to connect to "
462                                                 "broadcast socket %d, %s\n",
463                                                 client, strerror(errno));
464                                 return -1;
465                         }
466
467                         protocols[client - 1].broadcast_socket_user_fd = fd;
468                 }
469
470                 fprintf(stderr, "libwebsocket poll process forked\n");
471
472                 return 0;
473         }
474
475         /* we want a SIGHUP when our parent goes down */
476         prctl(PR_SET_PDEATHSIG, SIGHUP);
477
478         /* in this forked process, sit and service websocket connections */
479
480         while (1) {
481
482                 n = poll(this->fds, this->fds_count, 1000);
483
484                 if (n < 0 || this->fds[0].revents & (POLLERR | POLLHUP)) {
485                         fprintf(stderr, "Listen Socket dead\n");
486                         goto fatal;
487                 }
488                 if (n == 0) /* poll timeout */
489                         continue;
490
491                 /* handle accept on listening socket? */
492
493                 for (client = 0; client < this->count_protocols + 1; client++) {
494
495                         if (!this->fds[client].revents & POLLIN)
496                                 continue;
497
498                         /* listen socket got an unencrypted connection... */
499
500                         clilen = sizeof(cli_addr);
501                         fd  = accept(this->fds[client].fd,
502                                      (struct sockaddr *)&cli_addr, &clilen);
503                         if (fd < 0) {
504                                 fprintf(stderr, "ERROR on accept");
505                                 continue;
506                         }
507
508                         if (this->fds_count >= MAX_CLIENTS) {
509                                 fprintf(stderr, "too busy");
510                                 close(fd);
511                                 continue;
512                         }
513
514                         if (client) {
515                                 /*
516                                  * accepting a connection to broadcast socket
517                                  * set wsi to be protocol index not pointer
518                                  */
519
520                                 this->wsi[this->fds_count] =
521                                       (struct libwebsocket *)(long)(client - 1);
522
523                                 goto fill_in_fds;
524                         }
525
526                         /* accepting connection to main listener */
527
528                         this->wsi[this->fds_count] =
529                                             malloc(sizeof(struct libwebsocket));
530                         if (!this->wsi[this->fds_count])
531                                 return -1;
532
533         #ifdef LWS_OPENSSL_SUPPORT
534                         if (this->use_ssl) {
535
536                                 this->wsi[this->fds_count]->ssl =
537                                                                SSL_new(ssl_ctx);
538                                 if (this->wsi[this->fds_count]->ssl == NULL) {
539                                         fprintf(stderr, "SSL_new failed: %s\n",
540                                             ERR_error_string(SSL_get_error(
541                                             this->wsi[this->fds_count]->ssl, 0),
542                                                                          NULL));
543                                         free(this->wsi[this->fds_count]);
544                                         continue;
545                                 }
546
547                                 SSL_set_fd(this->wsi[this->fds_count]->ssl, fd);
548
549                                 n = SSL_accept(this->wsi[this->fds_count]->ssl);
550                                 if (n != 1) {
551                                         /*
552                                          * browsers seem to probe with various
553                                          * ssl params which fail then retry
554                                          * and succeed
555                                          */
556                                         debug("SSL_accept failed skt %u: %s\n",
557                                               fd,
558                                               ERR_error_string(SSL_get_error(
559                                               this->wsi[this->fds_count]->ssl,
560                                                                      n), NULL));
561                                         SSL_free(
562                                                this->wsi[this->fds_count]->ssl);
563                                         free(this->wsi[this->fds_count]);
564                                         continue;
565                                 }
566                                 debug("accepted new SSL conn  "
567                                       "port %u on fd=%d SSL ver %s\n",
568                                         ntohs(cli_addr.sin_port), fd,
569                                           SSL_get_version(this->wsi[
570                                                         this->fds_count]->ssl));
571
572                         } else
573         #endif
574                                 debug("accepted new conn  port %u on fd=%d\n",
575                                                   ntohs(cli_addr.sin_port), fd);
576
577                         /* intialize the instance struct */
578
579                         this->wsi[this->fds_count]->sock = fd;
580                         this->wsi[this->fds_count]->state = WSI_STATE_HTTP;
581                         this->wsi[this->fds_count]->name_buffer_pos = 0;
582
583                         for (n = 0; n < WSI_TOKEN_COUNT; n++) {
584                                 this->wsi[this->fds_count]->
585                                                      utf8_token[n].token = NULL;
586                                 this->wsi[this->fds_count]->
587                                                     utf8_token[n].token_len = 0;
588                         }
589
590                         /*
591                          * these can only be set once the protocol is known
592                          * we set an unestablished connection's protocol pointer
593                          * to the start of the supported list, so it can look
594                          * for matching ones during the handshake
595                          */
596                         this->wsi[this->fds_count]->protocol = protocols;
597                         this->wsi[this->fds_count]->user_space = NULL;
598
599                         /*
600                          * Default protocol is 76
601                          * After 76, there's a header specified to inform which
602                          * draft the client wants, when that's seen we modify
603                          * the individual connection's spec revision accordingly
604                          */
605                         this->wsi[this->fds_count]->ietf_spec_revision = 76;
606
607 fill_in_fds:
608
609                         /*
610                          * make sure NO events are seen yet on this new socket
611                          * (otherwise we inherit old fds[client].revents from
612                          * previous socket there and die mysteriously! )
613                          */
614                         this->fds[this->fds_count].revents = 0;
615
616                         this->fds[this->fds_count].events = POLLIN;
617                         this->fds[this->fds_count++].fd = fd;
618
619                 }
620
621
622                 /* service anything incoming on websocket connection */
623
624                 libwebsocket_poll_connections(this);
625         }
626
627 fatal:
628
629         /* close listening skt and per-protocol broadcast sockets */
630         for (client = 0; client < this->fds_count; client++)
631                 close(this->fds[0].fd);
632
633 #ifdef LWS_OPENSSL_SUPPORT
634         SSL_CTX_free(ssl_ctx);
635 #endif
636         kill(0, SIGTERM);
637
638         if (this)
639                 free(this);
640
641         return 0;
642 }
643
644 /**
645  * libwebsockets_get_protocol() - Returns a protocol pointer from a websocket
646  *                                connection.
647  * @wsi:        pointer to struct websocket you want to know the protocol of
648  *
649  *
650  *      This is useful to get the protocol to broadcast back to from inside
651  * the callback.
652  */
653
654 const struct libwebsocket_protocols *
655 libwebsockets_get_protocol(struct libwebsocket *wsi)
656 {
657         return wsi->protocol;
658 }
659
660 /**
661  * libwebsockets_broadcast() - Sends a buffer to rthe callback for all active
662  *                                connections of the given protocol.
663  * @protocol:   pointer to the protocol you will broadcast to all members of
664  * @buf:  buffer containing the data to be broadcase.  NOTE: this has to be
665  *              allocated with LWS_SEND_BUFFER_PRE_PADDING valid bytes before
666  *              the pointer and LWS_SEND_BUFFER_POST_PADDING afterwards in the
667  *              case you are calling this function from callback context.
668  * @len:        length of payload data in buf, starting from buf.
669  *
670  *      This function allows bulk sending of a packet to every connection using
671  * the given protocol.  It does not send the data directly; instead it calls
672  * the callback with a reason type of LWS_CALLBACK_BROADCAST.  If the callback
673  * wants to actually send the data for that connection, the callback itself
674  * should call libwebsocket_write().
675  *
676  * libwebsockets_broadcast() can be called from another fork context without
677  * having to take any care about data visibility between the processes, it'll
678  * "just work".
679  */
680
681
682 int
683 libwebsockets_broadcast(const struct libwebsocket_protocols *protocol,
684                                                  unsigned char *buf, size_t len)
685 {
686         struct libwebsocket_context *this = protocol->owning_server;
687         int n;
688
689         if (!protocol->broadcast_socket_user_fd) {
690                 /*
691                  * we are being called from poll thread context
692                  * eg, from a callback.  In that case don't use sockets for
693                  * broadcast IPC (since we can't open a socket connection to
694                  * a socket listening on our own thread) but directly do the
695                  * send action.
696                  *
697                  * Locking is not needed because we are by definition being
698                  * called in the poll thread context and are serialized.
699                  */
700
701                 for (n = this->count_protocols + 1; n < this->fds_count; n++) {
702
703                         if ((unsigned long)this->wsi[n] < LWS_MAX_PROTOCOLS)
704                                 continue;
705
706                         /* never broadcast to non-established connection */
707
708                         if (this->wsi[n]->state != WSI_STATE_ESTABLISHED)
709                                 continue;
710
711                         /* only broadcast to guys using requested protocol */
712
713                         if (this->wsi[n]->protocol != protocol)
714                                 continue;
715
716                         this->wsi[n]->protocol->callback(this->wsi[n],
717                                          LWS_CALLBACK_BROADCAST,
718                                          this->wsi[n]->user_space,
719                                          buf, len);
720                 }
721
722                 return 0;
723         }
724
725         /*
726          * We're being called from a different process context than the server
727          * loop.  Instead of broadcasting directly, we send our
728          * payload on a socket to do the IPC; the server process will serialize
729          * the broadcast action in its main poll() loop.
730          *
731          * There's one broadcast socket listening for each protocol supported
732          * set up when the websocket server initializes
733          */
734
735         n = send(protocol->broadcast_socket_user_fd, buf, len, 0);
736
737         return n;
738 }