28 |
28 |
29 #include "../public/nsapi.h" |
29 #include "../public/nsapi.h" |
30 |
30 |
31 #include <stdio.h> |
31 #include <stdio.h> |
32 #include <stdlib.h> |
32 #include <stdlib.h> |
33 #include <fcntl.h> |
33 |
34 #include <sys/shm.h> |
34 #include <sys/shm.h> |
35 #include <sys/types.h> |
|
36 #include <sys/ipc.h> |
35 #include <sys/ipc.h> |
37 #include <sys/socket.h> |
|
38 #include <sys/file.h> |
36 #include <sys/file.h> |
39 #include <arpa/inet.h> |
|
40 #include <netinet/in.h> |
|
41 #include <netdb.h> |
|
42 #include <stdio.h> |
37 #include <stdio.h> |
43 #include <stdlib.h> |
38 #include <stdlib.h> |
44 #include <fcntl.h> |
39 #include <fcntl.h> |
45 #include <unistd.h> |
40 #include <unistd.h> |
46 #include <strings.h> |
41 #include <strings.h> |
47 #include <stdbool.h> |
42 #include <stdbool.h> |
48 #include <signal.h> |
43 #include <signal.h> |
49 #include <pthread.h> |
44 #include <pthread.h> |
50 |
45 |
51 #include <arpa/inet.h> |
|
52 #include <netinet/in.h> |
|
53 #include <stdio.h> |
46 #include <stdio.h> |
54 #include <stdlib.h> |
47 #include <stdlib.h> |
55 #include <sys/socket.h> |
|
56 #include <unistd.h> |
|
57 |
48 |
58 |
49 |
59 #include <cx/hash_map.h> |
50 #include <cx/hash_map.h> |
60 |
51 |
61 #include "../util/atomic.h" |
52 #include "../util/atomic.h" |
267 sizeof(int)); |
258 sizeof(int)); |
268 } |
259 } |
269 #endif |
260 #endif |
270 |
261 |
271 // bind server socket to address |
262 // bind server socket to address |
272 struct sockaddr_in servaddr4; |
263 union ws_socketaddr addr; |
273 struct sockaddr_in6 servaddr6; |
|
274 struct sockaddr *servaddr; |
264 struct sockaddr *servaddr; |
275 size_t servaddr_size; |
265 size_t servaddr_size; |
276 if(ipv4) { |
266 if(ipv4) { |
277 // ipv4 |
267 // ipv4 |
278 memset(&servaddr4, 0, sizeof(servaddr4)); |
268 memset(&addr.addr4, 0, sizeof(addr.addr4)); |
279 servaddr4.sin_family = AF_INET; |
269 addr.addr4.sin_family = AF_INET; |
280 servaddr4.sin_addr.s_addr = htonl(INADDR_ANY); |
270 addr.addr4.sin_addr.s_addr = htonl(INADDR_ANY); |
281 servaddr4.sin_port = htons(conf->port); |
271 addr.addr4.sin_port = htons(conf->port); |
282 servaddr = (struct sockaddr *)&servaddr4; |
272 servaddr = (struct sockaddr *)&addr.addr4; |
283 servaddr_size = sizeof(servaddr4); |
273 servaddr_size = sizeof(addr.addr4); |
284 } else { |
274 } else { |
285 // ipv6 |
275 // ipv6 |
286 memset(&servaddr6, 0, sizeof(servaddr6)); |
276 memset(&addr.addr6, 0, sizeof(addr.addr6)); |
287 servaddr6.sin6_family = AF_INET6; |
277 addr.addr6.sin6_family = AF_INET6; |
288 servaddr6.sin6_addr = in6addr_any; |
278 addr.addr6.sin6_addr = in6addr_any; |
289 servaddr6.sin6_port = htons(conf->port); |
279 addr.addr6.sin6_port = htons(conf->port); |
290 servaddr = (struct sockaddr *)&servaddr6; |
280 servaddr = (struct sockaddr *)&addr.addr6; |
291 servaddr_size = sizeof(servaddr6); |
281 servaddr_size = sizeof(addr.addr6); |
292 } |
282 } |
293 |
283 |
294 if(bind(s, servaddr, servaddr_size)) { |
284 if(bind(s, servaddr, servaddr_size)) { |
295 log_ereport( |
285 log_ereport( |
296 LOG_FAILURE, |
286 LOG_FAILURE, |
308 close(s); |
298 close(s); |
309 return NULL; |
299 return NULL; |
310 } |
300 } |
311 ZERO(wssocket, sizeof(WSSocket)); |
301 ZERO(wssocket, sizeof(WSSocket)); |
312 wssocket->socket = s; |
302 wssocket->socket = s; |
|
303 wssocket->addr = addr; |
|
304 if(ipv4) { |
|
305 wssocket->sockaddr = (struct sockaddr *)&wssocket->addr.addr4; |
|
306 } else { |
|
307 wssocket->sockaddr = (struct sockaddr *)&wssocket->addr.addr6; |
|
308 } |
|
309 wssocket->sockaddr_size = servaddr_size; |
313 |
310 |
314 return wssocket; |
311 return wssocket; |
315 } |
312 } |
316 |
313 |
317 static WSSocket* get_socket(ListenerConfig *conf, const char *protocol) { |
314 static WSSocket* get_socket(ListenerConfig *conf, const char *protocol) { |
474 listener = listener->next; |
471 listener = listener->next; |
475 } |
472 } |
476 listener->next = next; |
473 listener->next = next; |
477 } |
474 } |
478 |
475 |
|
476 int http_listener_connect(HttpListener *listener, WSBool ipv6) { |
|
477 int domain = ipv6 ? AF_INET6 : AF_INET; |
|
478 int client = socket(domain, SOCK_STREAM, 0); |
|
479 if(client < 0) { |
|
480 return -1; |
|
481 } |
|
482 |
|
483 struct sockaddr *sockaddr; |
|
484 size_t sockaddr_size; |
|
485 if(ipv6) { |
|
486 sockaddr = listener->server_socket6->sockaddr; |
|
487 sockaddr_size = listener->server_socket6->sockaddr_size; |
|
488 } else { |
|
489 sockaddr = listener->server_socket->sockaddr; |
|
490 sockaddr_size = listener->server_socket->sockaddr_size; |
|
491 } |
|
492 |
|
493 if(connect(client, sockaddr, sockaddr_size) < 0) { |
|
494 close(client); |
|
495 return -1; |
|
496 } |
|
497 |
|
498 return client; |
|
499 } |
479 |
500 |
480 |
501 |
481 void http_listener_shutdown_acceptors(HttpListener *listener) { |
502 void http_listener_shutdown_acceptors(HttpListener *listener) { |
482 // not implemented yet |
503 // |
|
504 |
|
505 for(int i=0;i<listener->nacceptors;i++) { |
|
506 listener->acceptors[i]->exit = TRUE; |
|
507 int client4 = http_listener_connect(listener, FALSE); |
|
508 if(client4 < 0) { |
|
509 log_ereport(LOG_FAILURE, "http_listener_shutdown_acceptors: cannot connect to ipv4 server socket: %s", strerror(errno)); |
|
510 } else { |
|
511 close(client4); |
|
512 } |
|
513 |
|
514 listener->acceptors6[i]->exit = TRUE; |
|
515 int client6 = http_listener_connect(listener, TRUE); |
|
516 if(client6 < 0) { |
|
517 log_ereport(LOG_FAILURE, "http_listener_shutdown_acceptors: cannot connect to ipv6 server socket: %s", strerror(errno)); |
|
518 } else { |
|
519 close(client6); |
|
520 } |
|
521 } |
483 } |
522 } |
484 |
523 |
485 |
524 |
486 Acceptor* acceptor_new(HttpListener *listener) { |
525 Acceptor* acceptor_new(HttpListener *listener) { |
487 Acceptor *acceptor = malloc(sizeof(Acceptor)); |
526 Acceptor *acceptor = malloc(sizeof(Acceptor)); |
545 ca_ptr, |
584 ca_ptr, |
546 &length); |
585 &length); |
547 log_ereport(LOG_DEBUG, "acceptor: %p listener: %p: accept(): %d", acceptor, acceptor->listener, clientfd); |
586 log_ereport(LOG_DEBUG, "acceptor: %p listener: %p: accept(): %d", acceptor, acceptor->listener, clientfd); |
548 if (clientfd == -1) { |
587 if (clientfd == -1) { |
549 log_ereport(LOG_FAILURE, "accept %s failed: %s", acceptor->ipv6 ? "ipv6" : "ipv4", strerror(errno)); |
588 log_ereport(LOG_FAILURE, "accept %s failed: %s", acceptor->ipv6 ? "ipv6" : "ipv4", strerror(errno)); |
|
589 |
|
590 if(acceptor->exit) { |
|
591 log_ereport(LOG_VERBOSE, "acceptor thread %p: listener: %p exit", acceptor, acceptor->listener); |
|
592 break; |
|
593 } |
550 continue; |
594 continue; |
551 } |
595 } |
552 |
596 |
553 // check listener |
597 // check listener |
554 HttpListener *ls = listener; |
598 HttpListener *ls = listener; |
611 |
655 |
612 // ready for new connection |
656 // ready for new connection |
613 |
657 |
614 if(acceptor_exit || acceptor->exit) { |
658 if(acceptor_exit || acceptor->exit) { |
615 // this acceptor is outdated |
659 // this acceptor is outdated |
616 log_ereport(LOG_VERBOSE, "acceptor thread %p: exit", (void*)acceptor->tid); |
660 log_ereport(LOG_VERBOSE, "acceptor thread %p: listener: %p exit", acceptor, acceptor->listener); |
617 break; |
661 break; |
618 } |
662 } |
619 } |
663 } |
620 |
664 |
621 acceptor->running = FALSE; |
665 acceptor->running = FALSE; |
622 log_ereport(LOG_DEBUG, "acceptor: %p listener %p exit thread", acceptor, acceptor->listener); |
|
623 |
666 |
624 cfg_unref(acceptor->listener->cfg); |
667 cfg_unref(acceptor->listener->cfg); |
625 |
668 |
626 return NULL; |
669 return NULL; |
627 } |
670 } |