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