1 /* Copyright © 2012 Brandon L Black <blblack@gmail.com>
2  *
3  * This file is part of gdnsd.
4  *
5  * gdnsd is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * gdnsd is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with gdnsd.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19 
20 #include <config.h>
21 #include <gdnsd/net.h>
22 #include "net.h"
23 
24 #include <gdnsd/log.h>
25 
26 #include <sys/types.h>
27 #include <sys/socket.h>
28 #include <netinet/in.h>
29 #include <arpa/inet.h>
30 #include <netdb.h>
31 #include <string.h>
32 #include <unistd.h>
33 
34 /* network utils */
35 
36 static int tcp_proto = 0;
37 static int udp_proto = 0;
38 static bool reuseport_ok = false;
39 
gdnsd_init_net(void)40 void gdnsd_init_net(void) {
41     static bool has_run = false;
42     if(has_run)
43         log_fatal("BUG: gdnsd_init_net() should only be called once!");
44     else
45         has_run = true;
46 
47     struct protoent* pe;
48 
49     // cppcheck-suppress getprotobynameCalled (init time, no threads)
50     pe = getprotobyname("tcp");
51     if(!pe)
52         log_fatal("getprotobyname('tcp') failed");
53     tcp_proto = pe->p_proto;
54 
55     // cppcheck-suppress getprotobynameCalled (init time, no threads)
56     pe = getprotobyname("udp");
57     if(!pe)
58         log_fatal("getprotobyname('udp') failed");
59     udp_proto = pe->p_proto;
60 
61 #ifdef SO_REUSEPORT
62     const int sock_rp = socket(PF_INET, SOCK_DGRAM, udp_proto);
63     if(sock_rp > -1) {
64         const int opt_one = 1;
65         if(!setsockopt(sock_rp, SOL_SOCKET, SO_REUSEPORT, &opt_one, sizeof opt_one))
66             reuseport_ok = true;
67         close(sock_rp);
68     }
69 #endif
70 }
71 
gdnsd_getproto_udp(void)72 int gdnsd_getproto_udp(void) { return udp_proto; }
gdnsd_getproto_tcp(void)73 int gdnsd_getproto_tcp(void) { return tcp_proto; }
gdnsd_reuseport_ok(void)74 bool gdnsd_reuseport_ok(void) { return reuseport_ok; }
75