src/server/daemon/httplistener.c

changeset 446
240ed6f945ca
parent 445
834351da593b
child 449
a28a5ccc894b
equal deleted inserted replaced
445:834351da593b 446:240ed6f945ca
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 }

mercurial