listen_dnsport.c (266114) | listen_dnsport.c (276605) |
---|---|
1/* 2 * services/listen_dnsport.c - listen on port 53 for incoming DNS queries. 3 * 4 * Copyright (c) 2007, NLnet Labs. All rights reserved. 5 * 6 * This software is open source. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 43 unchanged lines hidden (view full) --- 52#include "ldns/sbuffer.h" 53 54#ifdef HAVE_NETDB_H 55#include <netdb.h> 56#endif 57#include <fcntl.h> 58 59/** number of queued TCP connections for listen() */ | 1/* 2 * services/listen_dnsport.c - listen on port 53 for incoming DNS queries. 3 * 4 * Copyright (c) 2007, NLnet Labs. All rights reserved. 5 * 6 * This software is open source. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 43 unchanged lines hidden (view full) --- 52#include "ldns/sbuffer.h" 53 54#ifdef HAVE_NETDB_H 55#include <netdb.h> 56#endif 57#include <fcntl.h> 58 59/** number of queued TCP connections for listen() */ |
60#define TCP_BACKLOG 5 | 60#define TCP_BACKLOG 256 |
61 62/** 63 * Debug print of the getaddrinfo returned address. 64 * @param addr: the address returned. 65 */ 66static void 67verbose_print_addr(struct addrinfo *addr) 68{ --- 79 unchanged lines hidden (view full) --- 148 wsa_strerror(WSAGetLastError())); 149 closesocket(s); 150 *noproto = 0; 151 *inuse = 0; 152 return -1; 153#endif 154 } 155#endif /* SO_REUSEADDR */ | 61 62/** 63 * Debug print of the getaddrinfo returned address. 64 * @param addr: the address returned. 65 */ 66static void 67verbose_print_addr(struct addrinfo *addr) 68{ --- 79 unchanged lines hidden (view full) --- 148 wsa_strerror(WSAGetLastError())); 149 closesocket(s); 150 *noproto = 0; 151 *inuse = 0; 152 return -1; 153#endif 154 } 155#endif /* SO_REUSEADDR */ |
156#if defined(__linux__) && defined(SO_REUSEPORT) 157 /* Linux specific: try to set SO_REUSEPORT so that incoming | 156#ifdef SO_REUSEPORT 157 /* try to set SO_REUSEPORT so that incoming |
158 * queries are distributed evenly among the receiving threads. 159 * Each thread must have its own socket bound to the same port, 160 * with SO_REUSEPORT set on each socket. 161 */ 162 if (reuseport && *reuseport && 163 setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (void*)&on, 164 (socklen_t)sizeof(on)) < 0) { 165#ifdef ENOPROTOOPT 166 if(errno != ENOPROTOOPT || verbosity >= 3) 167 log_warn("setsockopt(.. SO_REUSEPORT ..) failed: %s", 168 strerror(errno)); 169#endif 170 /* this option is not essential, we can continue */ 171 *reuseport = 0; 172 } 173#else 174 (void)reuseport; | 158 * queries are distributed evenly among the receiving threads. 159 * Each thread must have its own socket bound to the same port, 160 * with SO_REUSEPORT set on each socket. 161 */ 162 if (reuseport && *reuseport && 163 setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (void*)&on, 164 (socklen_t)sizeof(on)) < 0) { 165#ifdef ENOPROTOOPT 166 if(errno != ENOPROTOOPT || verbosity >= 3) 167 log_warn("setsockopt(.. SO_REUSEPORT ..) failed: %s", 168 strerror(errno)); 169#endif 170 /* this option is not essential, we can continue */ 171 *reuseport = 0; 172 } 173#else 174 (void)reuseport; |
175#endif /* defined(__linux__) && defined(SO_REUSEPORT) */ | 175#endif /* defined(SO_REUSEPORT) */ |
176 } 177 if(rcv) { 178#ifdef SO_RCVBUF 179 int got; 180 socklen_t slen = (socklen_t)sizeof(got); 181# ifdef SO_RCVBUFFORCE 182 /* Linux specific: try to use root permission to override 183 * system limits on rcvbuf. The limit is stored in --- 173 unchanged lines hidden (view full) --- 357# endif 358 *noproto = 0; 359 *inuse = 0; 360 return -1; 361 } 362# endif /* IPv6 MTU */ 363 } else if(family == AF_INET) { 364# if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) | 176 } 177 if(rcv) { 178#ifdef SO_RCVBUF 179 int got; 180 socklen_t slen = (socklen_t)sizeof(got); 181# ifdef SO_RCVBUFFORCE 182 /* Linux specific: try to use root permission to override 183 * system limits on rcvbuf. The limit is stored in --- 173 unchanged lines hidden (view full) --- 357# endif 358 *noproto = 0; 359 *inuse = 0; 360 return -1; 361 } 362# endif /* IPv6 MTU */ 363 } else if(family == AF_INET) { 364# if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) |
365/* linux 3.15 has IP_PMTUDISC_OMIT, Hannes Frederic Sowa made it so that 366 * PMTU information is not accepted, but fragmentation is allowed 367 * if and only if the packet size exceeds the outgoing interface MTU 368 * (and also uses the interface mtu to determine the size of the packets). 369 * So there won't be any EMSGSIZE error. Against DNS fragmentation attacks. 370 * FreeBSD already has same semantics without setting the option. */ 371# if defined(IP_PMTUDISC_OMIT) 372 int action = IP_PMTUDISC_OMIT; 373# else |
|
365 int action = IP_PMTUDISC_DONT; | 374 int action = IP_PMTUDISC_DONT; |
375# endif |
|
366 if (setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, 367 &action, (socklen_t)sizeof(action)) < 0) { 368 log_err("setsockopt(..., IP_MTU_DISCOVER, " | 376 if (setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, 377 &action, (socklen_t)sizeof(action)) < 0) { 378 log_err("setsockopt(..., IP_MTU_DISCOVER, " |
369 "IP_PMTUDISC_DONT...) failed: %s", | 379# if defined(IP_PMTUDISC_OMIT) 380 "IP_PMTUDISC_OMIT" 381# else 382 "IP_PMTUDISC_DONT" 383# endif 384 "...) failed: %s", |
370 strerror(errno)); 371# ifndef USE_WINSOCK 372 close(s); 373# else 374 closesocket(s); 375# endif 376 *noproto = 0; 377 *inuse = 0; --- 21 unchanged lines hidden (view full) --- 399 *inuse = 0; 400#ifndef USE_WINSOCK 401#ifdef EADDRINUSE 402 *inuse = (errno == EADDRINUSE); 403 /* detect freebsd jail with no ipv6 permission */ 404 if(family==AF_INET6 && errno==EINVAL) 405 *noproto = 1; 406 else if(errno != EADDRINUSE) { | 385 strerror(errno)); 386# ifndef USE_WINSOCK 387 close(s); 388# else 389 closesocket(s); 390# endif 391 *noproto = 0; 392 *inuse = 0; --- 21 unchanged lines hidden (view full) --- 414 *inuse = 0; 415#ifndef USE_WINSOCK 416#ifdef EADDRINUSE 417 *inuse = (errno == EADDRINUSE); 418 /* detect freebsd jail with no ipv6 permission */ 419 if(family==AF_INET6 && errno==EINVAL) 420 *noproto = 1; 421 else if(errno != EADDRINUSE) { |
407 log_err("can't bind socket: %s", strerror(errno)); 408 log_addr(0, "failed address", | 422 log_err_addr("can't bind socket", strerror(errno), |
409 (struct sockaddr_storage*)addr, addrlen); 410 } 411#endif /* EADDRINUSE */ 412 close(s); 413#else /* USE_WINSOCK */ 414 if(WSAGetLastError() != WSAEADDRINUSE && 415 WSAGetLastError() != WSAEADDRNOTAVAIL) { | 423 (struct sockaddr_storage*)addr, addrlen); 424 } 425#endif /* EADDRINUSE */ 426 close(s); 427#else /* USE_WINSOCK */ 428 if(WSAGetLastError() != WSAEADDRINUSE && 429 WSAGetLastError() != WSAEADDRNOTAVAIL) { |
416 log_err("can't bind socket: %s", 417 wsa_strerror(WSAGetLastError())); 418 log_addr(0, "failed address", | 430 log_err_addr("can't bind socket", 431 wsa_strerror(WSAGetLastError()), |
419 (struct sockaddr_storage*)addr, addrlen); 420 } 421 closesocket(s); 422#endif 423 return -1; 424 } 425 if(!fd_set_nonblock(s)) { 426 *noproto = 0; --- 46 unchanged lines hidden (view full) --- 473#else 474 log_err("setsockopt(.. SO_REUSEADDR ..) failed: %s", 475 wsa_strerror(WSAGetLastError())); 476 closesocket(s); 477#endif 478 return -1; 479 } 480#endif /* SO_REUSEADDR */ | 432 (struct sockaddr_storage*)addr, addrlen); 433 } 434 closesocket(s); 435#endif 436 return -1; 437 } 438 if(!fd_set_nonblock(s)) { 439 *noproto = 0; --- 46 unchanged lines hidden (view full) --- 486#else 487 log_err("setsockopt(.. SO_REUSEADDR ..) failed: %s", 488 wsa_strerror(WSAGetLastError())); 489 closesocket(s); 490#endif 491 return -1; 492 } 493#endif /* SO_REUSEADDR */ |
481#if defined(__linux__) && defined(SO_REUSEPORT) 482 /* Linux specific: try to set SO_REUSEPORT so that incoming | 494#ifdef SO_REUSEPORT 495 /* try to set SO_REUSEPORT so that incoming |
483 * connections are distributed evenly among the receiving threads. 484 * Each thread must have its own socket bound to the same port, 485 * with SO_REUSEPORT set on each socket. 486 */ 487 if (reuseport && *reuseport && 488 setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (void*)&on, 489 (socklen_t)sizeof(on)) < 0) { 490#ifdef ENOPROTOOPT 491 if(errno != ENOPROTOOPT || verbosity >= 3) 492 log_warn("setsockopt(.. SO_REUSEPORT ..) failed: %s", 493 strerror(errno)); 494#endif 495 /* this option is not essential, we can continue */ 496 *reuseport = 0; 497 } 498#else 499 (void)reuseport; | 496 * connections are distributed evenly among the receiving threads. 497 * Each thread must have its own socket bound to the same port, 498 * with SO_REUSEPORT set on each socket. 499 */ 500 if (reuseport && *reuseport && 501 setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (void*)&on, 502 (socklen_t)sizeof(on)) < 0) { 503#ifdef ENOPROTOOPT 504 if(errno != ENOPROTOOPT || verbosity >= 3) 505 log_warn("setsockopt(.. SO_REUSEPORT ..) failed: %s", 506 strerror(errno)); 507#endif 508 /* this option is not essential, we can continue */ 509 *reuseport = 0; 510 } 511#else 512 (void)reuseport; |
500#endif /* defined(__linux__) && defined(SO_REUSEPORT) */ | 513#endif /* defined(SO_REUSEPORT) */ |
501#if defined(IPV6_V6ONLY) 502 if(addr->ai_family == AF_INET6 && v6only) { 503 if(setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, 504 (void*)&on, (socklen_t)sizeof(on)) < 0) { 505#ifndef USE_WINSOCK 506 log_err("setsockopt(..., IPV6_V6ONLY, ...) failed: %s", 507 strerror(errno)); 508 close(s); --- 9 unchanged lines hidden (view full) --- 518 (void)v6only; 519#endif /* IPV6_V6ONLY */ 520 if(bind(s, addr->ai_addr, addr->ai_addrlen) != 0) { 521#ifndef USE_WINSOCK 522 /* detect freebsd jail with no ipv6 permission */ 523 if(addr->ai_family==AF_INET6 && errno==EINVAL) 524 *noproto = 1; 525 else { | 514#if defined(IPV6_V6ONLY) 515 if(addr->ai_family == AF_INET6 && v6only) { 516 if(setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, 517 (void*)&on, (socklen_t)sizeof(on)) < 0) { 518#ifndef USE_WINSOCK 519 log_err("setsockopt(..., IPV6_V6ONLY, ...) failed: %s", 520 strerror(errno)); 521 close(s); --- 9 unchanged lines hidden (view full) --- 531 (void)v6only; 532#endif /* IPV6_V6ONLY */ 533 if(bind(s, addr->ai_addr, addr->ai_addrlen) != 0) { 534#ifndef USE_WINSOCK 535 /* detect freebsd jail with no ipv6 permission */ 536 if(addr->ai_family==AF_INET6 && errno==EINVAL) 537 *noproto = 1; 538 else { |
526 log_err("can't bind socket: %s", strerror(errno)); 527 log_addr(0, "failed address", | 539 log_err_addr("can't bind socket", strerror(errno), |
528 (struct sockaddr_storage*)addr->ai_addr, 529 addr->ai_addrlen); 530 } 531 close(s); 532#else | 540 (struct sockaddr_storage*)addr->ai_addr, 541 addr->ai_addrlen); 542 } 543 close(s); 544#else |
533 log_err("can't bind socket: %s", 534 wsa_strerror(WSAGetLastError())); 535 log_addr(0, "failed address", | 545 log_err_addr("can't bind socket", 546 wsa_strerror(WSAGetLastError()), |
536 (struct sockaddr_storage*)addr->ai_addr, 537 addr->ai_addrlen); 538 closesocket(s); 539#endif 540 return -1; 541 } 542 if(!fd_set_nonblock(s)) { 543#ifndef USE_WINSOCK --- 288 unchanged lines hidden (view full) --- 832 item->next = front->cps; 833 front->cps = item; 834 return 1; 835} 836 837struct listen_dnsport* 838listen_create(struct comm_base* base, struct listen_port* ports, 839 size_t bufsize, int tcp_accept_count, void* sslctx, | 547 (struct sockaddr_storage*)addr->ai_addr, 548 addr->ai_addrlen); 549 closesocket(s); 550#endif 551 return -1; 552 } 553 if(!fd_set_nonblock(s)) { 554#ifndef USE_WINSOCK --- 288 unchanged lines hidden (view full) --- 843 item->next = front->cps; 844 front->cps = item; 845 return 1; 846} 847 848struct listen_dnsport* 849listen_create(struct comm_base* base, struct listen_port* ports, 850 size_t bufsize, int tcp_accept_count, void* sslctx, |
840 comm_point_callback_t* cb, void *cb_arg) | 851 struct dt_env* dtenv, comm_point_callback_t* cb, void *cb_arg) |
841{ 842 struct listen_dnsport* front = (struct listen_dnsport*) 843 malloc(sizeof(struct listen_dnsport)); 844 if(!front) 845 return NULL; 846 front->cps = NULL; 847 front->udp_buff = sldns_buffer_new(bufsize); 848 if(!front->udp_buff) { --- 17 unchanged lines hidden (view full) --- 866 } else if(ports->ftype == listen_type_udpancil) 867 cp = comm_point_create_udp_ancil(base, ports->fd, 868 front->udp_buff, cb, cb_arg); 869 if(!cp) { 870 log_err("can't create commpoint"); 871 listen_delete(front); 872 return NULL; 873 } | 852{ 853 struct listen_dnsport* front = (struct listen_dnsport*) 854 malloc(sizeof(struct listen_dnsport)); 855 if(!front) 856 return NULL; 857 front->cps = NULL; 858 front->udp_buff = sldns_buffer_new(bufsize); 859 if(!front->udp_buff) { --- 17 unchanged lines hidden (view full) --- 877 } else if(ports->ftype == listen_type_udpancil) 878 cp = comm_point_create_udp_ancil(base, ports->fd, 879 front->udp_buff, cb, cb_arg); 880 if(!cp) { 881 log_err("can't create commpoint"); 882 listen_delete(front); 883 return NULL; 884 } |
885 cp->dtenv = dtenv; |
|
874 cp->do_not_close = 1; 875 if(!listen_cp_insert(cp, front)) { 876 log_err("malloc failed"); 877 comm_point_delete(cp); 878 listen_delete(front); 879 return NULL; 880 } 881 ports = ports->next; --- 169 unchanged lines hidden --- | 886 cp->do_not_close = 1; 887 if(!listen_cp_insert(cp, front)) { 888 log_err("malloc failed"); 889 comm_point_delete(cp); 890 listen_delete(front); 891 return NULL; 892 } 893 ports = ports->next; --- 169 unchanged lines hidden --- |