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 |
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; |