src/server/daemon/httplistener.c

changeset 396
77d81f2bb9f7
parent 256
19259b6c5cf7
child 398
83234bc3bee9
equal deleted inserted replaced
395:224c4e858125 396:77d81f2bb9f7
34 #include <sys/shm.h> 34 #include <sys/shm.h>
35 #include <sys/types.h> 35 #include <sys/types.h>
36 #include <sys/ipc.h> 36 #include <sys/ipc.h>
37 #include <sys/socket.h> 37 #include <sys/socket.h>
38 #include <sys/file.h> 38 #include <sys/file.h>
39 #include <arpa/inet.h>
39 #include <netinet/in.h> 40 #include <netinet/in.h>
40 #include <netdb.h> 41 #include <netdb.h>
41 #include <stdio.h> 42 #include <stdio.h>
42 #include <stdlib.h> 43 #include <stdlib.h>
43 #include <fcntl.h> 44 #include <fcntl.h>
44 #include <unistd.h> 45 #include <unistd.h>
45 #include <strings.h> 46 #include <strings.h>
46 #include <stdbool.h> 47 #include <stdbool.h>
47 #include <pthread.h> 48 #include <pthread.h>
48 49
50 #include <arpa/inet.h>
51 #include <netinet/in.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <sys/socket.h>
55 #include <unistd.h>
56
49 #include <ucx/map.h> 57 #include <ucx/map.h>
50 58
51 #include "../util/atomic.h" 59 #include "../util/atomic.h"
52 #include "httplistener.h" 60 #include "httplistener.h"
53 #include "netsite.h" 61 #include "netsite.h"
89 newls->cfg = conf->cfg; 97 newls->cfg = conf->cfg;
90 newls->nacceptors = conf->nacceptors; 98 newls->nacceptors = conf->nacceptors;
91 newls->default_vs.vs_name = conf->vs.ptr; 99 newls->default_vs.vs_name = conf->vs.ptr;
92 newls->port = fl->port; 100 newls->port = fl->port;
93 newls->server_socket = fl->server_socket; 101 newls->server_socket = fl->server_socket;
102 newls->server_socket6 = fl->server_socket6;
94 newls->running = 1; 103 newls->running = 1;
95 newls->threadpool = NULL; 104 newls->threadpool = NULL;
96 newls->ref = 2; // 1 reference is fl->next 105 newls->ref = 2; // 1 reference is fl->next
97 106
98 newls->session_handler = fl->session_handler; // TODO 107 newls->session_handler = fl->session_handler; // TODO
109 newls->acceptors = calloc(newls->nacceptors, sizeof(void*)); 118 newls->acceptors = calloc(newls->nacceptors, sizeof(void*));
110 for (int i=0;i<newls->nacceptors;i++) { 119 for (int i=0;i<newls->nacceptors;i++) {
111 newls->acceptors[i] = acceptor_new(newls); 120 newls->acceptors[i] = acceptor_new(newls);
112 } 121 }
113 122
123 newls->acceptors6 = calloc(newls->nacceptors, sizeof(void*));
124 for (int i=0;i<newls->nacceptors;i++) {
125 newls->acceptors6[i] = acceptor_new(newls);
126 newls->acceptors6[i]->ipv6 = TRUE;
127 }
128
114 // fl hold one reference of newls 129 // fl hold one reference of newls
115 fl->next = newls; 130 fl->next = newls;
116 131
117 132
118 ucx_map_sstr_put(listener_map, newls->name, newls); 133 ucx_map_sstr_put(listener_map, newls->name, newls);
119 134
120 for (int i=0;i<newls->nacceptors;i++) { 135 for (int i=0;i<newls->nacceptors;i++) {
121 acceptor_start(newls->acceptors[i]); 136 //acceptor_start(newls->acceptors[i]);
137 acceptor_start(newls->acceptors6[i]);
122 } 138 }
123 139
124 // check if a restart is required to apply all changes 140 // check if a restart is required to apply all changes
125 141
126 if(newls->port != conf->port) { 142 if(newls->port != conf->port) {
269 285
270 286
271 ucx_map_sstr_put(listener_map, listener->name, listener); 287 ucx_map_sstr_put(listener_map, listener->name, listener);
272 288
273 struct sockaddr_in servaddr; /* server address */ 289 struct sockaddr_in servaddr; /* server address */
290 struct sockaddr_in6 servaddr6;
274 291
275 /* init address structure */ 292 /* init address structure */
276 memset(&servaddr, 0, sizeof(servaddr)); 293 memset(&servaddr, 0, sizeof(servaddr));
277 servaddr.sin_family = AF_INET; 294 servaddr.sin_family = AF_INET;
278 servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 295 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
279 servaddr.sin_port = htons(conf->port); 296 servaddr.sin_port = htons(conf->port);
297
298 memset(&servaddr6, 0, sizeof(servaddr6));
299 servaddr6.sin6_family = AF_INET6;
300 servaddr6.sin6_addr = in6addr_any;
301 servaddr6.sin6_port = htons(conf->port);
280 302
281 /* create socket */ 303 /* create socket */
282 if((listener->server_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) { 304 if((listener->server_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
283 perror("Error: http_listener_new: socket"); 305 perror("Error: http_listener_new: socket");
306 return NULL;
307 }
308
309 if((listener->server_socket6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)) == -1) {
310 perror("Error: http_listener_new: socket v6");
284 return NULL; 311 return NULL;
285 } 312 }
286 313
287 int o = 1; 314 int o = 1;
288 setsockopt( 315 setsockopt(
289 listener->server_socket, 316 listener->server_socket,
290 SOL_SOCKET, SO_REUSEADDR, 317 SOL_SOCKET, SO_REUSEADDR,
291 &o, 318 &o,
292 sizeof(int)); 319 sizeof(int));
320 o = 1;
321 setsockopt(
322 listener->server_socket6,
323 SOL_SOCKET, SO_REUSEADDR,
324 &o,
325 sizeof(int));
293 326
294 /* bind server socket to address */ 327 /* bind server socket to address */
295 if(bind(listener->server_socket, (struct sockaddr*)&servaddr, sizeof(servaddr))){ 328 if(bind(listener->server_socket, (struct sockaddr*)&servaddr, sizeof(servaddr))){
296 log_ereport(LOG_FAILURE, "http_listener_new: bind failed. Port: %d", conf->port); 329 log_ereport(LOG_FAILURE, "http_listener_new: bind failed. Port: %d", conf->port);
297 return NULL; 330 return NULL;
298 } 331 }
332
333 if(bind(listener->server_socket6, (struct sockaddr*)&servaddr6, sizeof(servaddr6))){
334 log_ereport(LOG_FAILURE, "http_listener_new: bind v6 failed. Port: %d: %s", conf->port, strerror(errno));
335 return NULL;
336 }
299 337
300 /* create acceptors */ 338 /* create acceptors */
301 listener->acceptors = calloc(listener->nacceptors, sizeof(void*)); 339 listener->acceptors = calloc(listener->nacceptors, sizeof(void*));
340 listener->acceptors6 = calloc(listener->nacceptors, sizeof(void*));
302 for (int i=0;i<listener->nacceptors;i++) { 341 for (int i=0;i<listener->nacceptors;i++) {
303 listener->acceptors[i] = acceptor_new(listener); 342 listener->acceptors[i] = acceptor_new(listener);
343 listener->acceptors6[i] = acceptor_new(listener);
344 listener->acceptors6[i]->ipv6 = TRUE;
304 } 345 }
305 346
306 return listener; 347 return listener;
307 } 348 }
308 349
314 355
315 if (listen(listener->server_socket, 256) == -1) { 356 if (listen(listener->server_socket, 256) == -1) {
316 log_ereport(LOG_FAILURE, "http_listener_start: listen failed"); 357 log_ereport(LOG_FAILURE, "http_listener_start: listen failed");
317 return -1; 358 return -1;
318 } 359 }
360 if (listen(listener->server_socket6, 256) == -1) {
361 log_ereport(LOG_FAILURE, "http_listener_start: listen failed");
362 return -1;
363 }
319 364
320 /* start acceptor threads */ 365 /* start acceptor threads */
321 for (int i=0;i<listener->nacceptors;i++) { 366 for (int i=0;i<listener->nacceptors;i++) {
322 acceptor_start(listener->acceptors[i]); 367 acceptor_start(listener->acceptors[i]);
368 acceptor_start(listener->acceptors6[i]);
323 } 369 }
324 370
325 return 0; 371 return 0;
326 } 372 }
327 373
342 388
343 389
344 Acceptor* acceptor_new(HttpListener *listener) { 390 Acceptor* acceptor_new(HttpListener *listener) {
345 Acceptor *acceptor = malloc(sizeof(Acceptor)); 391 Acceptor *acceptor = malloc(sizeof(Acceptor));
346 acceptor->listener = listener; 392 acceptor->listener = listener;
393 acceptor->ipv6 = WS_FALSE;
347 return acceptor; 394 return acceptor;
348 } 395 }
349 396
350 void acceptor_start(Acceptor *a) { 397 void acceptor_start(Acceptor *a) {
351 if(pthread_create( 398 if(pthread_create(
364 WS_ASSERT(acceptor->listener->session_handler); 411 WS_ASSERT(acceptor->listener->session_handler);
365 WS_ASSERT(acceptor->listener->session_handler->enqueue_connection); 412 WS_ASSERT(acceptor->listener->session_handler->enqueue_connection);
366 413
367 HttpListener *listener = acceptor->listener; 414 HttpListener *listener = acceptor->listener;
368 415
416 int server_socket;
417
418 ConnectionAddr ca;
419 struct sockaddr *ca_ptr;
420 socklen_t ca_length;
421 ConnectionAddrType addr_type;
422 if(acceptor->ipv6) {
423 server_socket = listener->server_socket6;
424 ca_ptr = (struct sockaddr*)&ca.address_v6;
425 ca_length = sizeof(ca.address_v6);
426 addr_type = CONN_ADDR_IPV6;
427 } else {
428 server_socket = listener->server_socket;
429 ca_ptr = (struct sockaddr*)&ca.address_v4;
430 ca_length = sizeof(ca.address_v4);
431 addr_type = CONN_ADDR_IPV4;
432 }
433
434
369 for (;;) { 435 for (;;) {
370 /* accept connections */ 436 /* accept connections */
371 struct sockaddr_in ca;
372 socklen_t length = sizeof(ca);
373 int clientfd; 437 int clientfd;
438 socklen_t length = ca_length;
374 439
375 /* accept a connection */ 440 /* accept a connection */
376 clientfd = accept( 441 clientfd = accept(
377 listener->server_socket, 442 server_socket,
378 (struct sockaddr*)&ca, 443 ca_ptr,
379 &length); 444 &length);
380 if (clientfd == -1) { 445 if (clientfd == -1) {
381 perror("Error: acceptor_thread: accept"); 446 log_ereport(LOG_FAILURE, "accept %s failed: %s", acceptor->ipv6 ? "ipv6" : "ipv4", strerror(errno));
382 continue; 447 continue;
383 } 448 }
384 449
385 // check listener 450 // check listener
386 HttpListener *ls = listener; 451 HttpListener *ls = listener;
391 } 456 }
392 457
393 /* create Connection object */ 458 /* create Connection object */
394 Connection *conn = malloc(sizeof(Connection)); 459 Connection *conn = malloc(sizeof(Connection));
395 conn->address = ca; 460 conn->address = ca;
461 conn->addr_type = addr_type;
396 conn->fd = clientfd; 462 conn->fd = clientfd;
397 conn->listener = ls; 463 conn->listener = ls;
398 conn->ssl_accepted = 0; 464 conn->ssl_accepted = 0;
399 if(ls->ssl) { 465 if(ls->ssl) {
400 // SSL connections are always non-blocking 466 // SSL connections are always non-blocking

mercurial