Deleted Added
full compact
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 ---