1 #include "uwsgi.h"
2
3 extern struct uwsgi_server uwsgi;
4
5 static int connect_to_unix(char *, int, int);
6 static int connect_to_tcp(char *, int, int, int);
7 static int connect_to_udp(char *, int);
8
uwsgi_socket_setup_protocol(struct uwsgi_socket * uwsgi_sock,char * protocol)9 void uwsgi_socket_setup_protocol(struct uwsgi_socket *uwsgi_sock, char *protocol) {
10 if (!protocol) protocol = "uwsgi";
11 struct uwsgi_protocol *up = uwsgi.protocols;
12 while(up) {
13 if (!strcmp(protocol, up->name)) {
14 up->func(uwsgi_sock);
15 return;
16 }
17 up = up->next;
18 }
19
20 uwsgi_log("unable to find protocol %s\n", protocol);
21 exit(1);
22 }
23
24
uwsgi_socket_strcmp(char * sock1,char * sock2)25 static int uwsgi_socket_strcmp(char *sock1, char *sock2) {
26 size_t sock1_len = strlen(sock1);
27 size_t sock2_len = strlen(sock2);
28
29 if (!uwsgi_starts_with(sock1, sock1_len, "0.0.0.0:", 8)) {
30 sock1 += 7;
31 sock1_len = strlen(sock1);
32 }
33
34 if (!uwsgi_starts_with(sock2, sock2_len, "0.0.0.0:", 8)) {
35 sock2 += 7;
36 sock2_len = strlen(sock2);
37 }
38
39 return uwsgi_strncmp(sock1, sock1_len, sock2, sock2_len);
40 }
41
uwsgi_getsockname(int fd)42 char *uwsgi_getsockname(int fd) {
43
44 socklen_t socket_type_len = sizeof(struct sockaddr_un);
45 union uwsgi_sockaddr usa;
46 union uwsgi_sockaddr_ptr gsa;
47 char computed_port[6];
48 char ipv4a[INET_ADDRSTRLEN + 1];
49
50 gsa.sa = (struct sockaddr *) &usa;
51
52 if (!getsockname(fd, gsa.sa, &socket_type_len)) {
53 if (gsa.sa->sa_family == AF_UNIX) {
54 if (usa.sa_un.sun_path[0] == 0) {
55 return uwsgi_concat2("@", usa.sa_un.sun_path + 1);
56 }
57 else {
58 return uwsgi_str(usa.sa_un.sun_path);
59 }
60 }
61 else {
62 memset(ipv4a, 0, INET_ADDRSTRLEN + 1);
63 memset(computed_port, 0, 6);
64 if (snprintf(computed_port, 6, "%d", ntohs(gsa.sa_in->sin_port)) > 0) {
65 if (inet_ntop(AF_INET, (const void *) &gsa.sa_in->sin_addr.s_addr, ipv4a, INET_ADDRSTRLEN)) {
66 if (!strcmp("0.0.0.0", ipv4a)) {
67 return uwsgi_concat2(":", computed_port);
68 }
69 else {
70 return uwsgi_concat3(ipv4a, ":", computed_port);
71 }
72 }
73 }
74 }
75 }
76 return NULL;
77 }
78
create_server_socket(int domain,int type)79 static int create_server_socket(int domain, int type) {
80 int serverfd = socket(domain, type, 0);
81 if (serverfd < 0) {
82 uwsgi_error("socket()");
83 uwsgi_nuclear_blast();
84 return -1;
85 }
86
87 if (uwsgi.close_on_exec2 && fcntl(serverfd, F_SETFD, FD_CLOEXEC) < 0)
88 uwsgi_error("fcntl()");
89
90 if (domain != AF_UNIX) {
91 int reuse = 1;
92 if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, (const void *) &reuse, sizeof(int)) < 0) {
93 uwsgi_error("SO_REUSEADDR setsockopt()");
94 uwsgi_nuclear_blast();
95 return -1;
96 }
97 }
98
99 if (type == SOCK_STREAM) {
100 if (uwsgi.so_sndbuf) {
101 socklen_t sndbuf = (socklen_t) uwsgi.so_sndbuf;
102 if (setsockopt(serverfd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(socklen_t)) < 0) {
103 uwsgi_error("SO_SNDBUF setsockopt()");
104 uwsgi_nuclear_blast();
105 return -1;
106 }
107 }
108
109 if (uwsgi.so_rcvbuf) {
110 socklen_t rcvbuf = (socklen_t) uwsgi.so_rcvbuf;
111 if (setsockopt(serverfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(socklen_t)) < 0) {
112 uwsgi_error("SO_RCVBUF setsockopt()");
113 uwsgi_nuclear_blast();
114 return -1;
115 }
116 }
117
118 #ifdef __linux__
119 long somaxconn = uwsgi_num_from_file("/proc/sys/net/core/somaxconn", 1);
120 if (somaxconn > 0 && uwsgi.listen_queue > somaxconn) {
121 uwsgi_log("Listen queue size is greater than the system max net.core.somaxconn (%li).\n", somaxconn);
122 uwsgi_nuclear_blast();
123 return -1;
124 }
125 #endif
126 }
127
128 return serverfd;
129 }
130
bind_to_unix_dgram(char * socket_name)131 int bind_to_unix_dgram(char *socket_name) {
132
133 int serverfd;
134 struct sockaddr_un *uws_addr;
135 socklen_t len;
136
137 serverfd = create_server_socket(AF_UNIX, SOCK_DGRAM);
138 if (serverfd < 0) return -1;
139
140 if (unlink(socket_name) != 0 && errno != ENOENT) {
141 uwsgi_error("error removing unix socket, unlink()");
142 }
143
144 uws_addr = uwsgi_calloc(sizeof(struct sockaddr_un));
145 uws_addr->sun_family = AF_UNIX;
146
147 memcpy(uws_addr->sun_path, socket_name, UMIN(strlen(socket_name), 102));
148 len = strlen(socket_name);
149
150 #ifdef __HAIKU__
151 if (bind(serverfd, (struct sockaddr *) uws_addr, sizeof(struct sockaddr_un))) {
152 #else
153 if (bind(serverfd, (struct sockaddr *) uws_addr, len + ((void *) uws_addr->sun_path - (void *) uws_addr)) != 0) {
154 #endif
155 uwsgi_error("bind()");
156 uwsgi_nuclear_blast();
157 return -1;
158 }
159
160 return serverfd;
161 }
162
163 int bind_to_unix(char *socket_name, int listen_queue, int chmod_socket, int abstract_socket) {
164
165 int serverfd;
166 struct sockaddr_un *uws_addr;
167 socklen_t len;
168
169 // leave 1 byte for abstract namespace (108 linux -> 104 bsd/mac)
170 if (strlen(socket_name) > 102) {
171 uwsgi_log("invalid socket name\n");
172 uwsgi_nuclear_blast();
173 return -1;
174 }
175
176 if (socket_name[0] == '@') {
177 abstract_socket = 1;
178 }
179 else if (strlen(socket_name) > 1 && socket_name[0] == '\\' && socket_name[1] == '0') {
180 abstract_socket = 1;
181 }
182
183 uws_addr = malloc(sizeof(struct sockaddr_un));
184 if (uws_addr == NULL) {
185 uwsgi_error("malloc()");
186 uwsgi_nuclear_blast();
187 return -1;
188 }
189
190 memset(uws_addr, 0, sizeof(struct sockaddr_un));
191 serverfd = create_server_socket(AF_UNIX, SOCK_STREAM);
192 if (serverfd < 0) {
193 free(uws_addr);
194 return -1;
195 }
196 if (abstract_socket == 0) {
197 if (unlink(socket_name) != 0 && errno != ENOENT) {
198 uwsgi_error("error removing unix socket, unlink()");
199 }
200 }
201
202 if (abstract_socket == 1) {
203 uwsgi_log("setting abstract socket mode (warning: only Linux supports this)\n");
204 }
205
206 uws_addr->sun_family = AF_UNIX;
207 if (socket_name[0] == '@') {
208 memcpy(uws_addr->sun_path + abstract_socket, socket_name + 1, UMIN(strlen(socket_name + 1), 101));
209 len = strlen(socket_name) + 1;
210 }
211 else if (strlen(socket_name) > 1 && socket_name[0] == '\\' && socket_name[1] == '0') {
212 memcpy(uws_addr->sun_path + abstract_socket, socket_name + 2, UMIN(strlen(socket_name + 2), 101));
213 len = strlen(socket_name + 1) + 1;
214
215 }
216 else if (abstract_socket) {
217 memcpy(uws_addr->sun_path + 1, socket_name, UMIN(strlen(socket_name), 101));
218 len = strlen(socket_name) + 1;
219 }
220 else {
221 memcpy(uws_addr->sun_path + abstract_socket, socket_name, UMIN(strlen(socket_name), 102));
222 len = strlen(socket_name);
223 }
224
225 #ifdef __HAIKU__
226 if (bind(serverfd, (struct sockaddr *) uws_addr, sizeof(struct sockaddr_un))) {
227 #else
228 if (bind(serverfd, (struct sockaddr *) uws_addr, len + ((void *) uws_addr->sun_path - (void *) uws_addr)) != 0) {
229 #endif
230 uwsgi_error("bind()");
231 uwsgi_nuclear_blast();
232 return -1;
233 }
234
235 if (listen(serverfd, listen_queue) != 0) {
236 uwsgi_error("listen()");
237 uwsgi_nuclear_blast();
238 return -1;
239 }
240
241 // chmod unix socket for lazy users
242 if (chmod_socket == 1 && abstract_socket == 0) {
243 if (uwsgi.chmod_socket_value) {
244 if (chmod(socket_name, uwsgi.chmod_socket_value) != 0) {
245 uwsgi_error("chmod()");
246 }
247 }
248 else {
249 uwsgi_log("chmod() socket to 666 for lazy and brave users\n");
250 if (chmod(socket_name, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) != 0) {
251 uwsgi_error("chmod()");
252 }
253 }
254 }
255
256 free(uws_addr);
257
258 return serverfd;
259 }
260
261 int bind_to_udp(char *socket_name, int multicast, int broadcast) {
262 int serverfd;
263 struct sockaddr_in uws_addr;
264 char *udp_port;
265 int bcast = 1;
266
267 struct ip_mreq mc;
268
269 udp_port = strchr(socket_name, ':');
270 if (udp_port == NULL) {
271 return -1;
272 }
273
274 udp_port[0] = 0;
275
276 if (socket_name[0] == 0 && multicast) {
277 uwsgi_log("invalid multicast address\n");
278 return -1;
279 }
280 memset(&uws_addr, 0, sizeof(struct sockaddr_in));
281 uws_addr.sin_family = AF_INET;
282 uws_addr.sin_port = htons(atoi(udp_port + 1));
283
284 if (!broadcast && !multicast) {
285 char quad[4];
286 char *first_part = strchr(socket_name, '.');
287 if (first_part && first_part - socket_name < 4) {
288 memset(quad, 0, 4);
289 memcpy(quad, socket_name, first_part - socket_name);
290 if (atoi(quad) >= 224 && atoi(quad) <= 239) {
291 multicast = 1;
292 }
293 }
294 if (!strcmp(socket_name, "255.255.255.255")) {
295 broadcast = 1;
296 }
297 }
298
299 if (broadcast) {
300 uws_addr.sin_addr.s_addr = INADDR_BROADCAST;
301 }
302 else if (socket_name[0] != 0) {
303 uws_addr.sin_addr.s_addr = inet_addr(socket_name);
304 }
305 else {
306 uws_addr.sin_addr.s_addr = INADDR_ANY;
307 }
308
309
310 serverfd = create_server_socket(AF_INET, SOCK_DGRAM);
311 if (serverfd < 0) return -1;
312
313 if (multicast) {
314 // if multicast is enabled remember to bind to INADDR_ANY
315 uws_addr.sin_addr.s_addr = INADDR_ANY;
316 mc.imr_multiaddr.s_addr = inet_addr(socket_name);
317 mc.imr_interface.s_addr = INADDR_ANY;
318 }
319
320 if (broadcast) {
321 if (setsockopt(serverfd, SOL_SOCKET, SO_BROADCAST, &bcast, sizeof(bcast))) {
322 perror("setsockopt");
323 close(serverfd);
324 return -1;
325 }
326 }
327
328 if (bind(serverfd, (struct sockaddr *) &uws_addr, sizeof(uws_addr)) != 0) {
329 uwsgi_error("bind()");
330 close(serverfd);
331 return -1;
332 }
333
334 if (multicast) {
335 uwsgi_log("[uwsgi-mcast] joining multicast group: %s:%d\n", socket_name, ntohs(uws_addr.sin_port));
336 if (setsockopt(serverfd, IPPROTO_IP, IP_MULTICAST_LOOP, &uwsgi.multicast_loop, sizeof(uwsgi.multicast_loop))) {
337 uwsgi_error("setsockopt()");
338 }
339
340 if (setsockopt(serverfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mc, sizeof(mc))) {
341 uwsgi_error("setsockopt()");
342 }
343
344 if (setsockopt(serverfd, IPPROTO_IP, IP_MULTICAST_TTL, &uwsgi.multicast_ttl, sizeof(uwsgi.multicast_ttl))) {
345 uwsgi_error("setsockopt()");
346 }
347
348 }
349
350 udp_port[0] = ':';
351 return serverfd;
352
353 }
354
355 static int uwsgi_connect_do(char *socket_name, int timeout, int async) {
356 char *tcp_port = strchr(socket_name, ':');
357
358 if (tcp_port) {
359 tcp_port[0] = 0;
360 tcp_port++;
361 return connect_to_tcp(socket_name, atoi(tcp_port), timeout, async);
362 }
363
364 return connect_to_unix(socket_name, timeout, async);
365 }
366
367 int uwsgi_connectn(char *socket_name, uint16_t len, int timeout, int async) {
368 char *zeroed_socket_name = uwsgi_concat2n(socket_name, len, "", 0);
369 int fd = uwsgi_connect_do(zeroed_socket_name, timeout, async);
370 free(zeroed_socket_name);
371 return fd;
372 }
373
374 int uwsgi_connect(char *socket_name, int timeout, int async) {
375 char *zeroed_socket_name = uwsgi_str(socket_name);
376 int fd = uwsgi_connect_do(zeroed_socket_name, timeout, async);
377 free(zeroed_socket_name);
378 return fd;
379 }
380
381 int uwsgi_connect_udp(char *socket_name) {
382 int fd = -1;
383 char *zeroed_socket_name = uwsgi_str(socket_name);
384 char *udp_port = strchr(zeroed_socket_name, ':');
385 if (!udp_port) goto end;
386 *udp_port = 0;
387 udp_port++;
388 fd = connect_to_udp(zeroed_socket_name, atoi(udp_port));
389 end:
390 free(zeroed_socket_name);
391 return fd;
392 }
393
394 static int connect_to_unix(char *socket_name, int timeout, int async) {
395
396 struct pollfd uwsgi_poll;
397 struct sockaddr_un uws_addr;
398 socklen_t un_size = sizeof(struct sockaddr_un);
399
400 memset(&uws_addr, 0, sizeof(struct sockaddr_un));
401
402 uws_addr.sun_family = AF_UNIX;
403
404 if (socket_name[0] == '@') {
405 un_size = sizeof(uws_addr.sun_family) + strlen(socket_name) + 1;
406 memcpy(uws_addr.sun_path + 1, socket_name + 1, UMIN(strlen(socket_name + 1), 101));
407 }
408 else if (strlen(socket_name) > 1 && socket_name[0] == '\\' && socket_name[1] == '0') {
409 un_size = sizeof(uws_addr.sun_family) + strlen(socket_name + 1) + 1;
410 memcpy(uws_addr.sun_path + 1, socket_name + 2, UMIN(strlen(socket_name + 2), 101));
411 }
412 else {
413 memcpy(uws_addr.sun_path, socket_name, UMIN(strlen(socket_name), 102));
414 }
415
416 #if defined(__linux__) && defined(SOCK_NONBLOCK) && !defined(OBSOLETE_LINUX_KERNEL)
417 uwsgi_poll.fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
418 #else
419 uwsgi_poll.fd = socket(AF_UNIX, SOCK_STREAM, 0);
420 #endif
421 if (uwsgi_poll.fd < 0) {
422 uwsgi_error("socket()");
423 return -1;
424 }
425
426 uwsgi_poll.events = POLLIN;
427
428 if (timed_connect(&uwsgi_poll, (const struct sockaddr *) &uws_addr, un_size, timeout, async)) {
429 // avoid error storm
430 //uwsgi_error("connect()");
431 close(uwsgi_poll.fd);
432 return -1;
433 }
434
435 return uwsgi_poll.fd;
436
437 }
438
439 static int connect_to_tcp(char *socket_name, int port, int timeout, int async) {
440
441 struct pollfd uwsgi_poll;
442 struct sockaddr_in uws_addr;
443
444 memset(&uws_addr, 0, sizeof(struct sockaddr_in));
445
446 uws_addr.sin_family = AF_INET;
447 uws_addr.sin_port = htons(port);
448
449 if (socket_name[0] == 0) {
450 uws_addr.sin_addr.s_addr = INADDR_ANY;
451 }
452 else {
453 uws_addr.sin_addr.s_addr = inet_addr(socket_name);
454 }
455
456 #if defined(__linux__) && defined(SOCK_NONBLOCK) && !defined(OBSOLETE_LINUX_KERNEL)
457 uwsgi_poll.fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
458 #else
459 uwsgi_poll.fd = socket(AF_INET, SOCK_STREAM, 0);
460 #endif
461 if (uwsgi_poll.fd < 0) {
462 uwsgi_error("connect_to_tcp()/socket()");
463 return -1;
464 }
465
466 uwsgi_poll.events = POLLIN;
467
468 if (timed_connect(&uwsgi_poll, (const struct sockaddr *) &uws_addr, sizeof(struct sockaddr_in), timeout, async)) {
469 //uwsgi_error("connect()");
470 close(uwsgi_poll.fd);
471 return -1;
472 }
473
474 return uwsgi_poll.fd;
475
476 }
477
478 static int connect_to_udp(char *socket_name, int port) {
479
480 struct sockaddr_in uws_addr;
481 memset(&uws_addr, 0, sizeof(struct sockaddr_in));
482
483 uws_addr.sin_family = AF_INET;
484 uws_addr.sin_port = htons(port);
485
486 if (socket_name[0] == 0) {
487 uws_addr.sin_addr.s_addr = INADDR_ANY;
488 }
489 else {
490 uws_addr.sin_addr.s_addr = inet_addr(socket_name);
491 }
492
493 int fd = socket(AF_INET, SOCK_DGRAM, 0);
494 if (fd < 0) {
495 uwsgi_error("connect_to_udp()/socket()");
496 return -1;
497 }
498
499 if (connect(fd, (const struct sockaddr *) &uws_addr, sizeof(struct sockaddr_in))) {
500 close(fd);
501 return -1;
502 }
503
504 return fd;
505
506 }
507
508
509
510 char *generate_socket_name(char *socket_name) {
511
512 char *asterisk = strchr(socket_name, '*');
513
514 char *tcp_port;
515 int i;
516 char *ptr = socket_name;
517
518 // ltrim spaces
519
520 for (i = 0; i < (int) strlen(socket_name); i++) {
521 if (isspace((int) socket_name[i])) {
522 ptr++;
523 }
524 else {
525 break;
526 }
527 }
528
529 socket_name = ptr;
530
531 if (socket_name[0] == 0) {
532 uwsgi_log("invalid/empty uwsgi socket name\n");
533 exit(1);
534 }
535
536 tcp_port = strchr(socket_name, ':');
537 if (!tcp_port)
538 return socket_name;
539
540 if (asterisk) {
541
542 #ifndef UWSGI_HAS_IFADDRS
543 uwsgi_log("your system does not support ifaddrs subsystem\n");
544 #else
545 char *new_socket;
546
547 #ifdef UWSGI_DEBUG
548 uwsgi_log("generate_socket_name(%s)\n", socket_name);
549 #endif
550 // get all the AF_INET addresses available
551 struct ifaddrs *ifap = NULL, *ifa, *ifaf;
552 if (getifaddrs(&ifap)) {
553 uwsgi_error("getifaddrs()");
554 uwsgi_nuclear_blast();
555 }
556
557 // here socket_name will be truncated
558 asterisk[0] = 0;
559
560 #ifdef UWSGI_DEBUG
561 uwsgi_log("asterisk found\n");
562 #endif
563
564 char new_addr[16];
565 struct sockaddr_in *sin;
566 ifa = ifap;
567 while (ifa) {
568 memset(new_addr, 0, 16);
569 if (!ifa->ifa_addr) goto next;
570 sin = (struct sockaddr_in *) ifa->ifa_addr;
571 if (inet_ntop(AF_INET, (void *) &sin->sin_addr.s_addr, new_addr, 16)) {
572 if (!strncmp(socket_name, new_addr, strlen(socket_name))) {
573 asterisk[0] = '*';
574 new_socket = uwsgi_concat3(new_addr, ":", tcp_port + 1);
575 uwsgi_log("[uwsgi-autoip] found %s for %s on interface %s\n", new_socket, socket_name, ifa->ifa_name);
576 freeifaddrs(ifap);
577 return new_socket;
578 }
579
580 }
581
582 next:
583 ifaf = ifa;
584 ifa = ifaf->ifa_next;
585
586 }
587
588 uwsgi_log("unable to find a valid socket address\n");
589 #endif
590 uwsgi_nuclear_blast();
591 }
592 return socket_name;
593 }
594
595 socklen_t socket_to_un_addr(char *socket_name, struct sockaddr_un * sun_addr) {
596
597 size_t len = strlen(socket_name);
598
599 if (len > 102) {
600 uwsgi_log("invalid UNIX socket address: %s\n", socket_name);
601 uwsgi_nuclear_blast();
602 }
603
604 memset(sun_addr, 0, sizeof(struct sockaddr_un));
605
606 sun_addr->sun_family = AF_UNIX;
607
608 // abstract socket
609 if (socket_name[0] == '@') {
610 memcpy(sun_addr->sun_path + 1, socket_name + 1, UMIN(len - 1, 101));
611 len = strlen(socket_name) + 1;
612 }
613 else if (len > 1 && socket_name[0] == '\\' && socket_name[1] == '0') {
614 memcpy(sun_addr->sun_path + 1, socket_name + 2, UMIN(len - 2, 101));
615 len = strlen(socket_name + 1) + 1;
616 }
617 else {
618 memcpy(sun_addr->sun_path, socket_name, UMIN(len, 102));
619 }
620
621 return sizeof(sun_addr->sun_family) + len;
622 }
623
624 socklen_t socket_to_in_addr(char *socket_name, char *port, int portn, struct sockaddr_in *sin_addr) {
625
626 memset(sin_addr, 0, sizeof(struct sockaddr_in));
627
628 sin_addr->sin_family = AF_INET;
629 if (port) {
630 *port = 0;
631 sin_addr->sin_port = htons(atoi(port + 1));
632 }
633 else {
634 sin_addr->sin_port = htons(portn);
635 }
636
637 if (socket_name[0] == 0) {
638 sin_addr->sin_addr.s_addr = INADDR_ANY;
639 }
640 else {
641 char *resolved = uwsgi_resolve_ip(socket_name);
642 if (resolved) {
643 sin_addr->sin_addr.s_addr = inet_addr(resolved);
644 }
645 else {
646 sin_addr->sin_addr.s_addr = inet_addr(socket_name);
647 }
648 }
649
650 if (port) {
651 *port = ':';
652 }
653
654 return sizeof(struct sockaddr_in);
655
656 }
657
658 int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
659
660 int serverfd;
661 #ifdef AF_INET6
662 struct sockaddr_in6 uws_addr;
663 #else
664 struct sockaddr_in uws_addr;
665 #endif
666 int family = AF_INET;
667 socklen_t addr_len = sizeof(struct sockaddr_in);
668
669 #ifdef AF_INET6
670 if (socket_name[0] == '[' && tcp_port[-1] == ']') {
671 family = AF_INET6;
672 socket_to_in_addr6(socket_name, tcp_port, 0, &uws_addr);
673 addr_len = sizeof(struct sockaddr_in6);
674 }
675 else {
676 #endif
677 socket_to_in_addr(socket_name, tcp_port, 0, (struct sockaddr_in *) &uws_addr);
678 #ifdef AF_INET6
679 }
680 #endif
681
682
683 serverfd = create_server_socket(family, SOCK_STREAM);
684 if (serverfd < 0) return -1;
685
686 #ifdef __linux__
687 #ifndef IP_FREEBIND
688 #define IP_FREEBIND 15
689 #endif
690 if (uwsgi.freebind) {
691 if (setsockopt(serverfd, SOL_IP, IP_FREEBIND, (const void *) &uwsgi.freebind, sizeof(int)) < 0) {
692 uwsgi_error("IP_FREEBIND setsockopt()");
693 uwsgi_nuclear_blast();
694 return -1;
695 }
696 }
697 #endif
698
699 if (uwsgi.reuse_port) {
700 #ifdef SO_REUSEPORT
701 if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEPORT, (const void *) &uwsgi.reuse_port, sizeof(int)) < 0) {
702 uwsgi_error("SO_REUSEPORT setsockopt()");
703 uwsgi_nuclear_blast();
704 return -1;
705 }
706 #else
707 uwsgi_log("!!! your system does not support SO_REUSEPORT !!!\n");
708 #endif
709 }
710
711 if (uwsgi.tcp_fast_open) {
712 #ifdef TCP_FASTOPEN
713
714 #ifndef SOL_TCP
715 #define SOL_TCP IPPROTO_TCP
716 #endif
717
718 if (setsockopt(serverfd, SOL_TCP, TCP_FASTOPEN, (const void *) &uwsgi.tcp_fast_open, sizeof(int)) < 0) {
719 uwsgi_error("TCP_FASTOPEN setsockopt()");
720 }
721 else {
722 uwsgi_log("TCP_FASTOPEN enabled on %s\n", socket_name);
723 }
724 #else
725 uwsgi_log("!!! your system does not support TCP_FASTOPEN !!!\n");
726 #endif
727 }
728
729 if (uwsgi.so_send_timeout) {
730 struct timeval tv;
731 tv.tv_sec = uwsgi.so_send_timeout;
732 tv.tv_usec = 0;
733 if (setsockopt(serverfd, SOL_SOCKET, SO_SNDTIMEO, (const void *) &tv, sizeof(struct timeval)) < 0) {
734 uwsgi_error("SO_SNDTIMEO setsockopt()");
735 uwsgi_nuclear_blast();
736 return -1;
737 }
738 }
739
740 if (!uwsgi.no_defer_accept) {
741
742 #ifdef __linux__
743 if (setsockopt(serverfd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &uwsgi.socket_timeout, sizeof(int))) {
744 uwsgi_error("TCP_DEFER_ACCEPT setsockopt()");
745 }
746 // OSX has no SO_ACCEPTFILTER !!!
747 #elif defined(__freebsd__)
748 struct accept_filter_arg afa;
749 strcpy(afa.af_name, "dataready");
750 afa.af_arg[0] = 0;
751 if (setsockopt(serverfd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(struct accept_filter_arg))) {
752 uwsgi_error("SO_ACCEPTFILTER setsockopt()");
753 }
754 #endif
755
756 }
757
758 if (uwsgi.so_keepalive) {
759 if (setsockopt(serverfd, SOL_SOCKET, SO_KEEPALIVE, &uwsgi.so_keepalive, sizeof(int))) {
760 uwsgi_error("SO_KEEPALIVE setsockopt()");
761 }
762 }
763
764
765 if (bind(serverfd, (struct sockaddr *) &uws_addr, addr_len) != 0) {
766 if (errno == EADDRINUSE) {
767 uwsgi_log("probably another instance of uWSGI is running on the same address (%s).\n", socket_name);
768 }
769 uwsgi_error("bind()");
770 uwsgi_nuclear_blast();
771 return -1;
772 }
773
774 if (listen(serverfd, listen_queue) != 0) {
775 uwsgi_error("listen()");
776 uwsgi_nuclear_blast();
777 return -1;
778 }
779
780
781 if (tcp_port)
782 tcp_port[0] = ':';
783
784 return serverfd;
785 }
786
787 // set non-blocking socket
788 void uwsgi_socket_nb(int fd) {
789 int arg;
790
791 arg = fcntl(fd, F_GETFL, NULL);
792 if (arg < 0) {
793 uwsgi_error("fcntl()");
794 return;
795 }
796 arg |= O_NONBLOCK;
797 if (fcntl(fd, F_SETFL, arg) < 0) {
798 uwsgi_error("fcntl()");
799 return;
800 }
801
802 }
803
804 // set blocking socket
805 void uwsgi_socket_b(int fd) {
806 int arg;
807
808 arg = fcntl(fd, F_GETFL, NULL);
809 if (arg < 0) {
810 uwsgi_error("fcntl()");
811 return;
812 }
813 arg &= (~O_NONBLOCK);
814 if (fcntl(fd, F_SETFL, arg) < 0) {
815 uwsgi_error("fcntl()");
816 return;
817 }
818
819 }
820
821
822 int timed_connect(struct pollfd *fdpoll, const struct sockaddr *addr, int addr_size, int timeout, int async) {
823
824 int ret;
825 int soopt = 0;
826 socklen_t solen = sizeof(int);
827 int cnt;
828 /* set non-blocking socket */
829
830 #if defined(__linux__) && defined(SOCK_NONBLOCK) && !defined(OBSOLETE_LINUX_KERNEL)
831 // hmm, nothing to do, as we are already non-blocking
832 #else
833 int arg = fcntl(fdpoll->fd, F_GETFL, NULL);
834 if (arg < 0) {
835 uwsgi_error("fcntl()");
836 return -1;
837 }
838 arg |= O_NONBLOCK;
839 if (fcntl(fdpoll->fd, F_SETFL, arg) < 0) {
840 uwsgi_error("fcntl()");
841 return -1;
842 }
843 #endif
844
845 #ifdef MSG_FASTOPEN
846 if (addr->sa_family == AF_INET && uwsgi.tcp_fast_open_client) {
847 ret = sendto(fdpoll->fd, "", 0, MSG_FASTOPEN, addr, addr_size);
848 }
849 else {
850 #endif
851 ret = connect(fdpoll->fd, addr, addr_size);
852 #ifdef MSG_FASTOPEN
853 }
854 #endif
855
856 if (async) {
857 if (ret < 0 && errno != EINPROGRESS) {
858 return -1;
859 }
860 return 0;
861 }
862
863
864 #if defined(__linux__) && defined(SOCK_NONBLOCK) && !defined(OBSOLETE_LINUX_KERNEL)
865 uwsgi_socket_b(fdpoll->fd);
866 #else
867 /* re-set blocking socket */
868 arg &= (~O_NONBLOCK);
869 if (fcntl(fdpoll->fd, F_SETFL, arg) < 0) {
870 uwsgi_error("fcntl()");
871 return -1;
872 }
873 #endif
874
875 if (ret < 0) {
876 /* check what happened */
877
878 // in progress ?
879 if (errno == EINPROGRESS) {
880 if (timeout < 1)
881 timeout = 3;
882 fdpoll->events = POLLOUT;
883 cnt = poll(fdpoll, 1, timeout * 1000);
884 /* check for errors */
885 if (cnt < 0 && errno != EINTR) {
886 uwsgi_error("poll()");
887 return -1;
888 }
889 /* something hapened on the socket ... */
890 else if (cnt > 0) {
891 if (getsockopt(fdpoll->fd, SOL_SOCKET, SO_ERROR, (void *) (&soopt), &solen) < 0) {
892 uwsgi_error("getsockopt()");
893 return -1;
894 }
895 /* is something bad ? */
896 if (soopt) {
897 return -1;
898 }
899 }
900 /* timeout */
901 else {
902 return -1;
903 }
904 }
905 else {
906 return -1;
907 }
908 }
909
910
911 return 0;
912
913 }
914
915 int uwsgi_count_sockets(struct uwsgi_socket *uwsgi_sock) {
916
917 int count = 0;
918 while (uwsgi_sock) {
919 count++;
920 uwsgi_sock = uwsgi_sock->next;
921 }
922
923 return count;
924 }
925
926 int uwsgi_get_socket_num(struct uwsgi_socket *uwsgi_sock) {
927
928 int count = 0;
929 struct uwsgi_socket *current_sock = uwsgi.sockets;
930
931 while (current_sock) {
932 if (uwsgi_sock == current_sock) {
933 return count;
934 }
935 count++;
936 current_sock = current_sock->next;
937 }
938
939 return -1;
940 }
941
942 int uwsgi_get_shared_socket_num(struct uwsgi_socket *uwsgi_sock) {
943
944 int count = 0;
945 struct uwsgi_socket *current_sock = uwsgi.shared_sockets;
946
947 while (current_sock) {
948 if (uwsgi_sock == current_sock) {
949 return count;
950 }
951 count++;
952 current_sock = current_sock->next;
953 }
954
955 return -1;
956 }
957
958
959 struct uwsgi_socket *uwsgi_new_shared_socket(char *name) {
960
961 struct uwsgi_socket *uwsgi_sock = uwsgi.shared_sockets, *old_uwsgi_sock;
962
963 if (!uwsgi_sock) {
964 uwsgi.shared_sockets = uwsgi_malloc(sizeof(struct uwsgi_socket));
965 uwsgi_sock = uwsgi.shared_sockets;
966 }
967 else {
968 while (uwsgi_sock) {
969 old_uwsgi_sock = uwsgi_sock;
970 uwsgi_sock = uwsgi_sock->next;
971 }
972
973 uwsgi_sock = uwsgi_malloc(sizeof(struct uwsgi_socket));
974 old_uwsgi_sock->next = uwsgi_sock;
975 }
976
977 memset(uwsgi_sock, 0, sizeof(struct uwsgi_socket));
978 uwsgi_sock->name = name;
979 uwsgi_sock->fd = -1;
980
981 return uwsgi_sock;
982 }
983
984
985 struct uwsgi_socket *uwsgi_new_socket(char *name) {
986
987 struct uwsgi_socket *uwsgi_sock = uwsgi.sockets, *old_uwsgi_sock;
988 struct sockaddr_in sin;
989 socklen_t socket_type_len;
990
991 if (!uwsgi_sock) {
992 uwsgi.sockets = uwsgi_malloc(sizeof(struct uwsgi_socket));
993 uwsgi_sock = uwsgi.sockets;
994 }
995 else {
996 while (uwsgi_sock) {
997 old_uwsgi_sock = uwsgi_sock;
998 uwsgi_sock = uwsgi_sock->next;
999 }
1000
1001 uwsgi_sock = uwsgi_malloc(sizeof(struct uwsgi_socket));
1002 old_uwsgi_sock->next = uwsgi_sock;
1003 }
1004
1005 memset(uwsgi_sock, 0, sizeof(struct uwsgi_socket));
1006 uwsgi_sock->name = name;
1007 uwsgi_sock->fd = -1;
1008
1009 if (!name)
1010 return uwsgi_sock;
1011
1012 if (name[0] == '=') {
1013 int shared_socket = atoi(uwsgi_sock->name + 1);
1014 if (shared_socket >= 0) {
1015 struct uwsgi_socket *uss = uwsgi_get_shared_socket_by_num(shared_socket);
1016 if (!uss) {
1017 uwsgi_log("unable to use shared socket %d\n", shared_socket);
1018 exit(1);
1019 }
1020 uwsgi_sock->bound = 1;
1021 uwsgi_sock->shared = 1;
1022 uwsgi_sock->from_shared = shared_socket;
1023 return uwsgi_sock;
1024 }
1025 }
1026
1027 if (!uwsgi_startswith(name, "fd://", 5)) {
1028 uwsgi_add_socket_from_fd(uwsgi_sock, atoi(name + 5));
1029 return uwsgi_sock;
1030 }
1031
1032 char *tcp_port = strrchr(name, ':');
1033 if (tcp_port) {
1034 // INET socket, check for 0 port
1035 if (tcp_port[1] == 0 || tcp_port[1] == '0') {
1036 uwsgi_sock->fd = bind_to_tcp(name, uwsgi.listen_queue, tcp_port);
1037 uwsgi_sock->family = AF_INET;
1038 uwsgi_sock->bound = 1;
1039
1040 uwsgi_sock->auto_port = 1;
1041
1042 socket_type_len = sizeof(struct sockaddr_in);
1043
1044 if (getsockname(uwsgi_sock->fd, (struct sockaddr *) &sin, &socket_type_len)) {
1045 uwsgi_error("getsockname()");
1046 exit(1);
1047 }
1048
1049
1050 char *auto_port = uwsgi_num2str(ntohs(sin.sin_port));
1051 uwsgi_sock->name = uwsgi_concat3n(name, tcp_port - name, ":", 1, auto_port, strlen(auto_port));
1052 }
1053 // is it fd 0 ?
1054 else if (tcp_port[1] == ':') {
1055 uwsgi_sock->fd = 0;
1056 uwsgi_sock->family = AF_INET;
1057 uwsgi_sock->bound = 1;
1058
1059 socket_type_len = sizeof(struct sockaddr_in);
1060
1061 if (getsockname(0, (struct sockaddr *) &sin, &socket_type_len)) {
1062 uwsgi_error("getsockname()");
1063 exit(1);
1064 }
1065
1066
1067 char *auto_port = uwsgi_num2str(ntohs(sin.sin_port));
1068 char *auto_ip = inet_ntoa(sin.sin_addr);
1069 uwsgi_sock->name = uwsgi_concat3n(auto_ip, strlen(auto_ip), ":", 1, auto_port, strlen(auto_port));
1070 free(auto_port);
1071 }
1072 }
1073
1074 return uwsgi_sock;
1075 }
1076
1077 void uwsgi_add_socket_from_fd(struct uwsgi_socket *uwsgi_sock, int fd) {
1078
1079 socklen_t socket_type_len;
1080 union uwsgi_sockaddr_ptr gsa, isa;
1081 union uwsgi_sockaddr usa;
1082 int abstract = 0;
1083
1084 memset(&usa, 0, sizeof(usa));
1085 socket_type_len = sizeof(struct sockaddr_un);
1086 gsa.sa = &usa.sa;
1087 if (!getsockname(fd, gsa.sa, &socket_type_len)) {
1088 if (socket_type_len <= 2) {
1089 // unbound socket
1090 return;
1091 }
1092 if (gsa.sa->sa_family == AF_UNIX) {
1093 if (usa.sa_un.sun_path[0] == 0)
1094 abstract = 1;
1095 // is it a zerg ?
1096 if (uwsgi_sock->name == NULL) {
1097 uwsgi_sock->fd = fd;
1098 uwsgi_sock->family = AF_UNIX;
1099 uwsgi_sock->bound = 1;
1100 uwsgi_sock->name = uwsgi_concat2(usa.sa_un.sun_path + abstract, "");
1101 if (uwsgi.zerg) {
1102 uwsgi_log("uwsgi zerg socket %d attached to UNIX address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), usa.sa_un.sun_path + abstract, uwsgi_sock->fd);
1103 }
1104 else {
1105 uwsgi_log("uwsgi socket %d attached to UNIX address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), usa.sa_un.sun_path + abstract, uwsgi_sock->fd);
1106 }
1107 return;
1108 }
1109 if (!uwsgi_startswith(uwsgi_sock->name, "fd://", 5)) {
1110 if (atoi(uwsgi_sock->name + 5) == fd) {
1111 uwsgi_sock->fd = fd;
1112 uwsgi_sock->family = AF_UNIX;
1113 uwsgi_sock->bound = 1;
1114 uwsgi_sock->name = uwsgi_str(usa.sa_un.sun_path + abstract);
1115 uwsgi_log("uwsgi socket %d inherited UNIX address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
1116 }
1117 }
1118 else if (!strcmp(usa.sa_un.sun_path + abstract, uwsgi_sock->name + abstract)) {
1119 uwsgi_sock->fd = fd;
1120 uwsgi_sock->family = AF_UNIX;
1121 uwsgi_sock->bound = 1;
1122 uwsgi_log("uwsgi socket %d inherited UNIX address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
1123 }
1124 }
1125 else if (gsa.sa->sa_family == AF_INET) {
1126 char *computed_addr;
1127 char computed_port[6];
1128 isa.sa_in = (struct sockaddr_in *) &usa;
1129 char ipv4a[INET_ADDRSTRLEN + 1];
1130 memset(ipv4a, 0, INET_ADDRSTRLEN + 1);
1131 memset(computed_port, 0, 6);
1132
1133
1134 if (snprintf(computed_port, 6, "%d", ntohs(isa.sa_in->sin_port)) > 0) {
1135 if (inet_ntop(AF_INET, (const void *) &isa.sa_in->sin_addr.s_addr, ipv4a, INET_ADDRSTRLEN)) {
1136
1137 if (!strcmp("0.0.0.0", ipv4a)) {
1138 computed_addr = uwsgi_concat2(":", computed_port);
1139 }
1140 else {
1141 computed_addr = uwsgi_concat3(ipv4a, ":", computed_port);
1142 }
1143
1144 // is it a zerg ?
1145 if (uwsgi_sock->name == NULL) {
1146 uwsgi_sock->fd = fd;
1147 uwsgi_sock->family = AF_INET;
1148 uwsgi_sock->bound = 1;
1149 uwsgi_sock->name = uwsgi_concat2(computed_addr, "");
1150 if (uwsgi.zerg) {
1151 uwsgi_log("uwsgi zerg socket %d attached to INET address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), computed_addr, uwsgi_sock->fd);
1152 }
1153 else {
1154 uwsgi_log("uwsgi socket %d attached to INET address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), computed_addr, uwsgi_sock->fd);
1155 }
1156 free(computed_addr);
1157 return;
1158 }
1159 char *asterisk = strchr(uwsgi_sock->name, '*');
1160 int match = 1;
1161 if (asterisk) {
1162 asterisk[0] = 0;
1163 match = strncmp(computed_addr, uwsgi_sock->name, strlen(uwsgi_sock->name));
1164 asterisk[0] = '*';
1165 }
1166 else {
1167 if (!uwsgi_startswith(uwsgi_sock->name, "fd://", 5)) {
1168 if (atoi(uwsgi_sock->name + 5) == fd) {
1169 uwsgi_sock->fd = fd;
1170 uwsgi_sock->family = AF_INET;
1171 uwsgi_sock->bound = 1;
1172 uwsgi_sock->name = uwsgi_str(computed_addr);
1173 uwsgi_log("uwsgi socket %d inherited INET address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
1174 match = 1;
1175 }
1176 }
1177 else {
1178 match = uwsgi_socket_strcmp(computed_addr, uwsgi_sock->name);
1179 }
1180 }
1181 if (!match) {
1182 uwsgi_sock->fd = fd;
1183 uwsgi_sock->family = AF_INET;
1184 uwsgi_sock->bound = 1;
1185 uwsgi_log("uwsgi socket %d inherited INET address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
1186 }
1187 free(computed_addr);
1188 }
1189 }
1190 }
1191 #ifdef AF_INET6
1192 else if (gsa.sa->sa_family == AF_INET6) {
1193 char *computed_addr;
1194 char computed_port[6];
1195 isa.sa_in6 = (struct sockaddr_in6 *) &usa;
1196 char ipv6a[INET6_ADDRSTRLEN + 1];
1197 memset(ipv6a, 0, INET_ADDRSTRLEN + 1);
1198 memset(computed_port, 0, 6);
1199 int match = 0;
1200
1201
1202 if (snprintf(computed_port, 6, "%d", ntohs(isa.sa_in6->sin6_port)) > 0) {
1203 if (inet_ntop(AF_INET6, (const void *) &isa.sa_in6->sin6_addr.s6_addr, ipv6a, INET6_ADDRSTRLEN)) {
1204 uwsgi_log("ipv6a = %s\n", ipv6a);
1205 if (!strcmp("::", ipv6a)) {
1206 computed_addr = uwsgi_concat2("[::]:", computed_port);
1207 }
1208 else {
1209 computed_addr = uwsgi_concat4("[", ipv6a, "]:", computed_port);
1210 }
1211 // is it a zerg ?
1212 if (uwsgi_sock->name == NULL) {
1213 uwsgi_sock->fd = fd;
1214 uwsgi_sock->family = AF_INET6;
1215 uwsgi_sock->bound = 1;
1216 uwsgi_sock->name = uwsgi_concat2(computed_addr, "");
1217 if (uwsgi.zerg) {
1218 uwsgi_log("uwsgi zerg socket %d attached to INET6 address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), computed_addr, uwsgi_sock->fd);
1219 }
1220 else {
1221 uwsgi_log("uwsgi socket %d attached to INET6 address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), computed_addr, uwsgi_sock->fd);
1222 }
1223 free(computed_addr);
1224 return;
1225 }
1226
1227 if (!uwsgi_startswith(uwsgi_sock->name, "fd://", 5)) {
1228 if (atoi(uwsgi_sock->name + 5) == fd) {
1229 uwsgi_sock->fd = fd;
1230 uwsgi_sock->family = AF_INET6;
1231 uwsgi_sock->bound = 1;
1232 uwsgi_sock->name = uwsgi_str(computed_addr);
1233 uwsgi_log("uwsgi socket %d inherited INET address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
1234 match = 1;
1235 }
1236 }
1237 else {
1238 match = strcmp(computed_addr, uwsgi_sock->name);
1239 }
1240
1241 if (!match) {
1242 uwsgi_sock->fd = fd;
1243 uwsgi_sock->family = AF_INET;
1244 uwsgi_sock->bound = 1;
1245 uwsgi_log("uwsgi socket %d inherited INET6 address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
1246 }
1247 free(computed_addr);
1248 }
1249 }
1250 }
1251
1252 #endif
1253 }
1254
1255 }
1256
1257 void uwsgi_close_all_sockets() {
1258 struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
1259
1260 while (uwsgi_sock) {
1261 if (uwsgi_sock->bound)
1262 close(uwsgi_sock->fd);
1263 uwsgi_sock = uwsgi_sock->next;
1264 }
1265 }
1266
1267 void uwsgi_shutdown_all_sockets() {
1268 uwsgi_log_verbose("shutting down all sockets...\n");
1269 struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
1270
1271 while (uwsgi_sock) {
1272 if (uwsgi_sock->bound) {
1273 shutdown(uwsgi_sock->fd, SHUT_RDWR);
1274 close(uwsgi_sock->fd);
1275 }
1276 uwsgi_sock = uwsgi_sock->next;
1277 }
1278 }
1279
1280 void uwsgi_close_all_unshared_sockets() {
1281 struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
1282
1283 while (uwsgi_sock) {
1284 if (uwsgi_sock->bound && !uwsgi_sock->shared)
1285 close(uwsgi_sock->fd);
1286 uwsgi_sock = uwsgi_sock->next;
1287 }
1288 }
1289
1290 struct uwsgi_socket *uwsgi_del_socket(struct uwsgi_socket *uwsgi_sock) {
1291
1292 struct uwsgi_socket *uwsgi_current_sock = uwsgi.sockets, *old_sock = NULL;
1293
1294 while (uwsgi_current_sock) {
1295 if (uwsgi_current_sock == uwsgi_sock) {
1296 // parent instance ?
1297 if (old_sock == NULL) {
1298 uwsgi.sockets = uwsgi_current_sock->next;
1299 free(uwsgi_current_sock);
1300 return uwsgi.sockets;
1301 }
1302 else {
1303 old_sock->next = uwsgi_current_sock->next;
1304 free(uwsgi_current_sock);
1305 return old_sock->next;
1306 }
1307
1308 }
1309
1310 old_sock = uwsgi_current_sock;
1311 uwsgi_current_sock = uwsgi_current_sock->next;
1312 }
1313
1314 return NULL;
1315 }
1316
1317
1318 int uwsgi_get_shared_socket_fd_by_num(int num) {
1319
1320 int counter = 0;
1321
1322 struct uwsgi_socket *found_sock = NULL, *uwsgi_sock = uwsgi.shared_sockets;
1323
1324 while (uwsgi_sock) {
1325 if (counter == num) {
1326 found_sock = uwsgi_sock;
1327 break;
1328 }
1329 counter++;
1330 uwsgi_sock = uwsgi_sock->next;
1331 }
1332
1333 if (found_sock) {
1334 return found_sock->fd;
1335 }
1336
1337 return -1;
1338 }
1339
1340 struct uwsgi_socket *uwsgi_get_shared_socket_by_num(int num) {
1341
1342 int counter = 0;
1343
1344 struct uwsgi_socket *found_sock = NULL, *uwsgi_sock = uwsgi.shared_sockets;
1345
1346 while (uwsgi_sock) {
1347 if (counter == num) {
1348 found_sock = uwsgi_sock;
1349 break;
1350 }
1351 counter++;
1352 uwsgi_sock = uwsgi_sock->next;
1353 }
1354
1355 if (found_sock) {
1356 return found_sock;
1357 }
1358
1359 return NULL;
1360 }
1361
1362 struct uwsgi_socket *uwsgi_get_socket_by_num(int num) {
1363
1364 int counter = 0;
1365
1366 struct uwsgi_socket *found_sock = NULL, *uwsgi_sock = uwsgi.sockets;
1367
1368 while (uwsgi_sock) {
1369 if (counter == num) {
1370 found_sock = uwsgi_sock;
1371 break;
1372 }
1373 counter++;
1374 uwsgi_sock = uwsgi_sock->next;
1375 }
1376
1377 if (found_sock) {
1378 return found_sock;
1379 }
1380
1381 return NULL;
1382 }
1383
1384
1385
1386 void uwsgi_add_sockets_to_queue(int queue, int async_id) {
1387
1388 struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
1389 while (uwsgi_sock) {
1390 if (uwsgi_sock->fd_threads && async_id > -1 && uwsgi_sock->fd_threads[async_id] > -1) {
1391 event_queue_add_fd_read(queue, uwsgi_sock->fd_threads[async_id]);
1392 }
1393 else if (uwsgi_sock->fd > -1) {
1394 event_queue_add_fd_read(queue, uwsgi_sock->fd);
1395 }
1396 uwsgi_sock = uwsgi_sock->next;
1397 }
1398
1399 }
1400
1401 void uwsgi_del_sockets_from_queue(int queue) {
1402
1403 struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
1404 while (uwsgi_sock) {
1405 if (uwsgi_sock->fd == -1)
1406 goto nextsock;
1407 event_queue_del_fd(queue, uwsgi_sock->fd, event_queue_read());
1408 nextsock:
1409 uwsgi_sock = uwsgi_sock->next;
1410 }
1411
1412 }
1413
1414 int uwsgi_is_bad_connection(int fd) {
1415
1416 int soopt = 0;
1417 socklen_t solen = sizeof(int);
1418
1419 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *) (&soopt), &solen) < 0) {
1420 return -1;
1421 }
1422
1423 // will be 0 if all ok
1424 return soopt;
1425 }
1426
1427 int uwsgi_socket_is_already_bound(char *name) {
1428 struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
1429 while (uwsgi_sock) {
1430 if (uwsgi_sock->name && !strcmp(uwsgi_sock->name, name) && uwsgi_sock->bound) {
1431 return 1;
1432 }
1433 uwsgi_sock = uwsgi_sock->next;
1434 }
1435 return 0;
1436 }
1437
1438 int uwsgi_socket_uniq(struct uwsgi_socket *list, struct uwsgi_socket *item) {
1439 int found = 0;
1440
1441 if (list == item)
1442 return 0;
1443 struct uwsgi_socket *uwsgi_sock = list;
1444 while (uwsgi_sock && uwsgi_sock != item) {
1445 if (uwsgi_sock->fd == -1)
1446 goto nextsock;
1447 if (!strcmp(uwsgi_sock->name, item->name)) {
1448 found = 1;
1449 break;
1450 }
1451 nextsock:
1452 uwsgi_sock = uwsgi_sock->next;
1453 }
1454 return found;
1455 }
1456
1457 void uwsgi_manage_zerg(int fd, int num_sockets, int *sockets) {
1458 struct sockaddr_un zsun;
1459 socklen_t zsun_len = sizeof(struct sockaddr_un);
1460
1461 int zerg_client = accept(fd, (struct sockaddr *) &zsun, &zsun_len);
1462 if (zerg_client < 0) {
1463 uwsgi_error("zerg: accept()");
1464 return;
1465 }
1466
1467 if (!num_sockets) {
1468 num_sockets = uwsgi_count_sockets(uwsgi.sockets);
1469 }
1470
1471 struct msghdr zerg_msg;
1472 void *zerg_msg_control = uwsgi_malloc(CMSG_SPACE(sizeof(int) * num_sockets));
1473 struct iovec zerg_iov[2];
1474 struct cmsghdr *cmsg;
1475
1476 zerg_iov[0].iov_base = "uwsgi-zerg";
1477 zerg_iov[0].iov_len = 10;
1478 zerg_iov[1].iov_base = &num_sockets;
1479 zerg_iov[1].iov_len = sizeof(int);
1480
1481 zerg_msg.msg_name = NULL;
1482 zerg_msg.msg_namelen = 0;
1483
1484 zerg_msg.msg_iov = zerg_iov;
1485 zerg_msg.msg_iovlen = 2;
1486
1487 zerg_msg.msg_flags = 0;
1488 zerg_msg.msg_control = zerg_msg_control;
1489 zerg_msg.msg_controllen = CMSG_SPACE(sizeof(int) * num_sockets);
1490
1491 cmsg = CMSG_FIRSTHDR(&zerg_msg);
1492 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * num_sockets);
1493 cmsg->cmsg_level = SOL_SOCKET;
1494 cmsg->cmsg_type = SCM_RIGHTS;
1495
1496 unsigned char *zerg_fd_ptr = CMSG_DATA(cmsg);
1497
1498 if (!sockets) {
1499 struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
1500 int uniq_count = 0;
1501 while (uwsgi_sock) {
1502 if (uwsgi_sock->fd == -1)
1503 goto nextsock;
1504 if (!uwsgi_socket_uniq(uwsgi.sockets, uwsgi_sock)) {
1505 memcpy(zerg_fd_ptr, &uwsgi_sock->fd, sizeof(int));
1506 zerg_fd_ptr += sizeof(int);
1507 uniq_count++;
1508 }
1509 nextsock:
1510 uwsgi_sock = uwsgi_sock->next;
1511 }
1512 zerg_iov[1].iov_base = &uniq_count;
1513 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * uniq_count);
1514 }
1515 else {
1516 memcpy(zerg_fd_ptr, sockets, sizeof(int) * num_sockets);
1517 }
1518
1519 if (sendmsg(zerg_client, &zerg_msg, 0) < 0) {
1520 uwsgi_error("sendmsg()");
1521 }
1522
1523 free(zerg_msg_control);
1524
1525 close(zerg_client);
1526
1527 }
1528
1529
1530 #ifdef AF_INET6
1531 socklen_t socket_to_in_addr6(char *socket_name, char *port, int portn, struct sockaddr_in6 * sin_addr) {
1532
1533 memset(sin_addr, 0, sizeof(struct sockaddr_in6));
1534
1535 sin_addr->sin6_family = AF_INET6;
1536 if (port) {
1537 *port = 0;
1538 sin_addr->sin6_port = htons(atoi(port + 1));
1539 }
1540 else {
1541 sin_addr->sin6_port = htons(portn);
1542 }
1543
1544 if (!strcmp(socket_name, "[::]")) {
1545 sin_addr->sin6_addr = in6addr_any;
1546 }
1547 else {
1548 char *sanitized_sn = uwsgi_concat2n(socket_name + 1, strlen(socket_name + 1) - 1, "", 0);
1549 char *resolved = uwsgi_resolve_ip(sanitized_sn);
1550 if (resolved) {
1551 inet_pton(AF_INET6, resolved, sin_addr->sin6_addr.s6_addr);
1552 }
1553 else {
1554 inet_pton(AF_INET6, sanitized_sn, sin_addr->sin6_addr.s6_addr);
1555 }
1556 free(sanitized_sn);
1557 }
1558
1559 if (port) {
1560 *port = ':';
1561 }
1562
1563 return sizeof(struct sockaddr_in6);
1564
1565 }
1566
1567
1568 #endif
1569
1570 void uwsgi_setup_shared_sockets() {
1571 int i;
1572 struct uwsgi_socket *shared_sock = uwsgi.shared_sockets;
1573 while (shared_sock) {
1574 if (!uwsgi.is_a_reload) {
1575 char *tcp_port = strrchr(shared_sock->name, ':');
1576 int current_defer_accept = uwsgi.no_defer_accept;
1577 if (shared_sock->no_defer) {
1578 uwsgi.no_defer_accept = 1;
1579 }
1580 if (tcp_port == NULL) {
1581 shared_sock->fd = bind_to_unix(shared_sock->name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
1582 shared_sock->family = AF_UNIX;
1583 uwsgi_log("uwsgi shared socket %d bound to UNIX address %s fd %d\n", uwsgi_get_shared_socket_num(shared_sock), shared_sock->name, shared_sock->fd);
1584 if (uwsgi.chown_socket) {
1585 uwsgi_chown(shared_sock->name, uwsgi.chown_socket);
1586 }
1587 }
1588 else {
1589 #ifdef AF_INET6
1590 if (shared_sock->name[0] == '[' && tcp_port[-1] == ']') {
1591 shared_sock->fd = bind_to_tcp(shared_sock->name, uwsgi.listen_queue, tcp_port);
1592 shared_sock->family = AF_INET6;
1593 // fix socket name
1594 shared_sock->name = uwsgi_getsockname(shared_sock->fd);
1595 uwsgi_log("uwsgi shared socket %d bound to TCP6 address %s fd %d\n", uwsgi_get_shared_socket_num(shared_sock), shared_sock->name, shared_sock->fd);
1596 }
1597 else {
1598 #endif
1599 shared_sock->fd = bind_to_tcp(shared_sock->name, uwsgi.listen_queue, tcp_port);
1600 shared_sock->family = AF_INET;
1601 // fix socket name
1602 shared_sock->name = uwsgi_getsockname(shared_sock->fd);
1603 uwsgi_log("uwsgi shared socket %d bound to TCP address %s fd %d\n", uwsgi_get_shared_socket_num(shared_sock), shared_sock->name, shared_sock->fd);
1604 #ifdef AF_INET6
1605 }
1606 #endif
1607 }
1608
1609 if (shared_sock->fd < 0) {
1610 uwsgi_log("unable to create shared socket on: %s\n", shared_sock->name);
1611 exit(1);
1612 }
1613
1614 if (shared_sock->no_defer) {
1615 uwsgi.no_defer_accept = current_defer_accept;
1616 }
1617
1618 }
1619 else {
1620 for (i = 3; i < (int) uwsgi.max_fd; i++) {
1621 char *sock = uwsgi_getsockname(i);
1622 if (sock) {
1623 if (!uwsgi_socket_strcmp(sock, shared_sock->name)) {
1624 if (strchr(sock, ':')) {
1625 uwsgi_log("uwsgi shared socket %d inherited TCP address %s fd %d\n", uwsgi_get_shared_socket_num(shared_sock), sock, i);
1626 shared_sock->family = AF_INET;
1627 }
1628 else {
1629 uwsgi_log("uwsgi shared socket %d inherited UNIX address %s fd %d\n", uwsgi_get_shared_socket_num(shared_sock), sock, i);
1630 shared_sock->family = AF_UNIX;
1631 }
1632 shared_sock->fd = i;
1633 }
1634 free(sock);
1635 }
1636 }
1637 }
1638 shared_sock->bound = 1;
1639 shared_sock = shared_sock->next;
1640 }
1641
1642 struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
1643 while (uwsgi_sock) {
1644
1645 if (uwsgi_sock->shared) {
1646 shared_sock = uwsgi_get_shared_socket_by_num(uwsgi_sock->from_shared);
1647 if (!shared_sock) {
1648 uwsgi_log("unable to find shared socket %d\n", uwsgi_sock->from_shared);
1649 exit(1);
1650 }
1651 uwsgi_sock->fd = shared_sock->fd;
1652 uwsgi_sock->family = shared_sock->family;
1653 uwsgi_sock->name = shared_sock->name;
1654 uwsgi_log("uwsgi socket %d mapped to shared socket %d (%s) fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_get_shared_socket_num(shared_sock), shared_sock->name, uwsgi_sock->fd);
1655 }
1656
1657 uwsgi_sock = uwsgi_sock->next;
1658 }
1659
1660
1661 }
1662
1663 void uwsgi_map_sockets() {
1664 struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
1665 while (uwsgi_sock) {
1666 struct uwsgi_string_list *usl = uwsgi.map_socket;
1667 int enabled = 1;
1668 while (usl) {
1669
1670 char *colon = strchr(usl->value, ':');
1671 if (!colon) {
1672 uwsgi_log("invalid socket mapping, must be socket:worker[,worker...]\n");
1673 exit(1);
1674 }
1675 if ((int) uwsgi_str_num(usl->value, colon - usl->value) == uwsgi_get_socket_num(uwsgi_sock)) {
1676 enabled = 0;
1677 char *p, *ctx = NULL;
1678 uwsgi_foreach_token(colon + 1, ",", p, ctx) {
1679 int w = atoi(p);
1680 if (w < 1 || w > uwsgi.numproc) {
1681 uwsgi_log("invalid worker num: %d\n", w);
1682 exit(1);
1683 }
1684 if (w == uwsgi.mywid) {
1685 enabled = 1;
1686 uwsgi_log("mapped socket %d (%s) to worker %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi.mywid);
1687 break;
1688 }
1689 }
1690 }
1691
1692 usl = usl->next;
1693 }
1694
1695 if (!enabled) {
1696 close(uwsgi_sock->fd);
1697 uwsgi_remap_fd(uwsgi_sock->fd, "/dev/null");
1698 uwsgi_sock->disabled = 1;
1699 }
1700
1701
1702 uwsgi_sock = uwsgi_sock->next;
1703
1704 }
1705
1706 uwsgi_sock = uwsgi.sockets;
1707 while (uwsgi_sock) {
1708 if (uwsgi_sock->disabled) {
1709 uwsgi_sock = uwsgi_del_socket(uwsgi_sock);
1710 }
1711 else {
1712 uwsgi_sock = uwsgi_sock->next;
1713 }
1714 }
1715
1716 }
1717
1718 void uwsgi_bind_sockets() {
1719 socklen_t socket_type_len;
1720 union uwsgi_sockaddr usa;
1721 union uwsgi_sockaddr_ptr gsa;
1722
1723 struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
1724 while (uwsgi_sock) {
1725 if (!uwsgi_sock->bound && !uwsgi_socket_is_already_bound(uwsgi_sock->name)) {
1726 char *tcp_port = strrchr(uwsgi_sock->name, ':');
1727 int current_defer_accept = uwsgi.no_defer_accept;
1728 if (uwsgi_sock->no_defer) {
1729 uwsgi.no_defer_accept = 1;
1730 }
1731 if (tcp_port == NULL) {
1732 uwsgi_sock->fd = bind_to_unix(uwsgi_sock->name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
1733 uwsgi_sock->family = AF_UNIX;
1734 if (uwsgi.chown_socket) {
1735 uwsgi_chown(uwsgi_sock->name, uwsgi.chown_socket);
1736 }
1737 uwsgi_log("uwsgi socket %d bound to UNIX address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
1738 struct stat st;
1739 if (uwsgi_sock->name[0] != '@' && !stat(uwsgi_sock->name, &st)) {
1740 uwsgi_sock->inode = st.st_ino;
1741 }
1742 }
1743 else {
1744 #ifdef AF_INET6
1745 if (uwsgi_sock->name[0] == '[' && tcp_port[-1] == ']') {
1746 uwsgi_sock->fd = bind_to_tcp(uwsgi_sock->name, uwsgi.listen_queue, tcp_port);
1747 uwsgi_log("uwsgi socket %d bound to TCP6 address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
1748 uwsgi_sock->family = AF_INET6;
1749 }
1750 else {
1751 #endif
1752 uwsgi_sock->fd = bind_to_tcp(uwsgi_sock->name, uwsgi.listen_queue, tcp_port);
1753 uwsgi_log("uwsgi socket %d bound to TCP address %s fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
1754 uwsgi_sock->family = AF_INET;
1755 #ifdef AF_INET6
1756 }
1757 #endif
1758 }
1759
1760 if (uwsgi_sock->fd < 0 && !uwsgi_sock->per_core) {
1761 uwsgi_log("unable to create server socket on: %s\n", uwsgi_sock->name);
1762 exit(1);
1763 }
1764 uwsgi.no_defer_accept = current_defer_accept;
1765 }
1766 uwsgi_sock->bound = 1;
1767 uwsgi_sock = uwsgi_sock->next;
1768 }
1769
1770 int zero_used = 0;
1771 uwsgi_sock = uwsgi.sockets;
1772 while (uwsgi_sock) {
1773 if (uwsgi_sock->bound && uwsgi_sock->fd == 0) {
1774 zero_used = 1;
1775 break;
1776 }
1777 uwsgi_sock = uwsgi_sock->next;
1778 }
1779
1780 if (!zero_used) {
1781 socket_type_len = sizeof(struct sockaddr_un);
1782 gsa.sa = (struct sockaddr *) &usa;
1783 if (!uwsgi.skip_zero && !getsockname(0, gsa.sa, &socket_type_len)) {
1784 if (gsa.sa->sa_family == AF_UNIX) {
1785 uwsgi_sock = uwsgi_new_socket(uwsgi_getsockname(0));
1786 uwsgi_sock->family = AF_UNIX;
1787 uwsgi_sock->fd = 0;
1788 uwsgi_sock->bound = 1;
1789 uwsgi_log("uwsgi socket %d inherited UNIX address %s fd 0\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name);
1790 if (!uwsgi.is_a_reload) {
1791 if (uwsgi.chown_socket) {
1792 uwsgi_chown(uwsgi_sock->name, uwsgi.chown_socket);
1793 }
1794 if (uwsgi.chmod_socket) {
1795 if (uwsgi.chmod_socket_value) {
1796 if (chmod(uwsgi_sock->name, uwsgi.chmod_socket_value) != 0) {
1797 uwsgi_error("inherit fd0: chmod()");
1798 }
1799 }
1800 else {
1801 uwsgi_log("chmod() fd0 socket to 666 for lazy and brave users\n");
1802 if (chmod(uwsgi_sock->name, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) != 0) {
1803 uwsgi_error("inherit fd0: chmod()");
1804 }
1805 }
1806 }
1807 }
1808 }
1809 else {
1810 uwsgi_sock = uwsgi_new_socket(uwsgi_getsockname(0));
1811 uwsgi_sock->family = AF_INET;
1812 uwsgi_sock->fd = 0;
1813 uwsgi_sock->bound = 1;
1814 uwsgi_log("uwsgi socket %d inherited INET address %s fd 0\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name);
1815 }
1816 }
1817 else if (!uwsgi.honour_stdin) {
1818 int fd = open("/dev/null", O_RDONLY);
1819 if (fd < 0) {
1820 uwsgi_error_open("/dev/null");
1821 uwsgi_log("WARNING: unable to remap stdin, /dev/null not available\n");
1822 goto stdin_done;
1823 }
1824 if (fd != 0) {
1825 if (dup2(fd, 0) < 0) {
1826 uwsgi_error("dup2()");
1827 exit(1);
1828 }
1829 close(fd);
1830 }
1831 }
1832 else if (uwsgi.honour_stdin) {
1833 if (!tcgetattr(0, &uwsgi.termios)) {
1834 uwsgi.restore_tc = 1;
1835 }
1836 }
1837
1838 }
1839
1840 stdin_done:
1841
1842 // check for auto_port socket
1843 uwsgi_sock = uwsgi.sockets;
1844 while (uwsgi_sock) {
1845 if (uwsgi_sock->auto_port) {
1846 #ifdef AF_INET6
1847 if (uwsgi_sock->family == AF_INET6) {
1848 uwsgi_log("uwsgi socket %d bound to TCP6 address %s (port auto-assigned) fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
1849 }
1850 else {
1851 #endif
1852 uwsgi_log("uwsgi socket %d bound to TCP address %s (port auto-assigned) fd %d\n", uwsgi_get_socket_num(uwsgi_sock), uwsgi_sock->name, uwsgi_sock->fd);
1853 #ifdef AF_INET6
1854 }
1855 #endif
1856 }
1857 uwsgi_sock = uwsgi_sock->next;
1858 }
1859
1860
1861 }
1862
1863 void uwsgi_set_sockets_protocols() {
1864
1865 struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
1866 while (uwsgi_sock) {
1867 char *requested_protocol = uwsgi_sock->proto_name;
1868
1869 if (uwsgi_sock->lazy)
1870 goto setup_proto;
1871 if (!uwsgi_sock->bound || uwsgi_sock->fd == -1)
1872 goto nextsock;
1873 if (!uwsgi_sock->per_core) {
1874 uwsgi_sock->arg = fcntl(uwsgi_sock->fd, F_GETFL, NULL);
1875 if (uwsgi_sock->arg < 0) {
1876 uwsgi_error("fcntl()");
1877 exit(1);
1878 }
1879 uwsgi_sock->arg |= O_NONBLOCK;
1880 if (fcntl(uwsgi_sock->fd, F_SETFL, uwsgi_sock->arg) < 0) {
1881 uwsgi_error("fcntl()");
1882 exit(1);
1883 }
1884 }
1885
1886
1887 setup_proto:
1888 if (!requested_protocol) requested_protocol = uwsgi.protocol;
1889 uwsgi_socket_setup_protocol(uwsgi_sock, requested_protocol);
1890 nextsock:
1891 uwsgi_sock = uwsgi_sock->next;
1892 }
1893
1894
1895 }
1896
1897 void uwsgi_tcp_nodelay(int fd) {
1898 #ifdef TCP_NODELAY
1899 int flag = 1;
1900 if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int))) {
1901 uwsgi_error("uwsgi_tcp_nodelay()/setsockopt()");
1902 }
1903 #endif
1904 }
1905
1906 int uwsgi_accept(int server_fd) {
1907 struct sockaddr_un client_src;
1908 memset(&client_src, 0, sizeof(struct sockaddr_un));
1909 socklen_t client_src_len = 0;
1910 #if defined(__linux__) && defined(SOCK_NONBLOCK) && !defined(OBSOLETE_LINUX_KERNEL)
1911 return accept4(server_fd, (struct sockaddr *) &client_src, &client_src_len, SOCK_NONBLOCK);
1912 #elif defined(__linux__)
1913 int client_fd = accept(server_fd, (struct sockaddr *) &client_src, &client_src_len);
1914 if (client_fd >= 0) {
1915 uwsgi_socket_nb(client_fd);
1916 }
1917 return client_fd;
1918 #else
1919 return accept(server_fd, (struct sockaddr *) &client_src, &client_src_len);
1920 #endif
1921
1922
1923 }
1924
1925 struct uwsgi_protocol *uwsgi_register_protocol(char *name, void (*func)(struct uwsgi_socket *)) {
1926 struct uwsgi_protocol *old_up = NULL, *up = uwsgi.protocols;
1927 while(up) {
1928 if (!strcmp(name, up->name)) {
1929 goto found;
1930 }
1931 old_up = up;
1932 up = up->next;
1933 }
1934 up = uwsgi_calloc(sizeof(struct uwsgi_protocol));
1935 up->name = name;
1936 if (old_up) {
1937 old_up->next = up;
1938 }
1939 else {
1940 uwsgi.protocols = up;
1941 }
1942 found:
1943 up->func = func;
1944 return up;
1945 }
1946
1947 int uwsgi_socket_passcred(int fd) {
1948 #ifdef SO_PASSCRED
1949 int optval = 1;
1950 if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) < 0) {
1951 uwsgi_error("uwsgi_socket_passcred()/setsockopt()");
1952 return -1;
1953 }
1954 return 0;
1955 #else
1956 return -1;
1957 #endif
1958 }
1959
1960 void uwsgi_protocols_register() {
1961 uwsgi_register_protocol("uwsgi", uwsgi_proto_uwsgi_setup);
1962 uwsgi_register_protocol("puwsgi", uwsgi_proto_puwsgi_setup);
1963
1964 uwsgi_register_protocol("http", uwsgi_proto_http_setup);
1965 uwsgi_register_protocol("http11", uwsgi_proto_http11_setup);
1966
1967 #ifdef UWSGI_SSL
1968 uwsgi_register_protocol("suwsgi", uwsgi_proto_suwsgi_setup);
1969 uwsgi_register_protocol("https", uwsgi_proto_https_setup);
1970 #endif
1971 uwsgi_register_protocol("fastcgi", uwsgi_proto_fastcgi_setup);
1972 uwsgi_register_protocol("fastcgi-nph", uwsgi_proto_fastcgi_nph_setup);
1973
1974 uwsgi_register_protocol("scgi", uwsgi_proto_scgi_setup);
1975 uwsgi_register_protocol("scgi-nph", uwsgi_proto_scgi_nph_setup);
1976
1977 uwsgi_register_protocol("raw", uwsgi_proto_raw_setup);
1978 }
1979