1 #include "config.h"
2 #include "ldapdns.h"
3 #include "ip.h"
4 #include "env.h"
5 
6 static int udp53 = -1;
7 #ifdef HAVE_IPV6
8 static int using_6 = 0;
9 #endif
10 
tp_close(dns_ctx * c)11 void tp_close(dns_ctx *c)
12 {
13 	/* we NEVER close the UDP connections */
14 }
tp_housekeeping(long * now)15 void inline tp_housekeeping(long *now)
16 {
17 	/* there is no housekeeping for UDP */
18 }
tp_initialize(void)19 void tp_initialize(void)
20 {
21 	char *x;
22 	char ip[IP_LEN];
23 	int port;
24 
25 	x = env_get("IP");
26 	if (!x)
27 		x = "0.0.0.0";
28 	if (!ipv4_scan(x, ip)) {
29 #ifdef HAVE_IPV6
30 		if (ipv6_scan(x, ip))
31 			using_6 = 1;
32 		else
33 #endif
34 		fatal("cannot parse IP: %s", x);
35 	}
36 
37 #ifdef HAVE_IPV6
38 	if (using_6)
39 		udp53 = socket_udp6();
40 	else
41 #endif
42 	udp53 = socket_udp4();
43 	if (udp53 == -1)
44 		cfatal("socket_udp4: %s");
45 	x = env_get("PORT");
46 	if (!x)
47 		port = 53;
48 	else {
49 		port = atoi(x);
50 		if (port < 1)
51 			fatal("cannot parse PORT: %s", x);
52 		if (port != 53)
53 			warning("running on non-standard port: %d", port);
54 	}
55 
56 #ifdef HAVE_IPV6
57 	if (using_6) {
58 		if (socket_bind6_reuse(udp53, ip, port) == -1)
59 			cfatal("socket_bind4_reuse: %s");
60 	} else
61 #endif
62 	if (socket_bind4_reuse(udp53, ip, port) == -1)
63 		cfatal("socket_bind4_reuse: %s");
64 
65 	ndelay_off(udp53);
66 	socket_tryreservein(udp53, 65536);
67 
68 	/* we NEVER allow axfr over udp... */
69 	ldapdns.axfr_base = 0;
70 	/* or allow updates... */
71 	ldapdns.update = 0;
72 }
tp_write(dns_ctx * c)73 int inline tp_write(dns_ctx *c)
74 {
75 	if (clen(c->response) > 512)
76 		response_tc(c);
77 	/* if this were to fail, it would be because the kernel buffers
78 	 * cannot support a single UDP packet... in which case it's a kernel
79 	 * problem.
80 	 */
81 #ifdef HAVE_IPV6
82 	if (using_6)
83 		socket_send6(c->sock,
84 			caddr(c->response),
85 			clen(c->response),
86 			c->ip,
87 			c->port);
88 	else
89 #endif
90 	socket_send4(c->sock,
91 		caddr(c->response),
92 		clen(c->response),
93 		c->ip,
94 		c->port);
95 	return 1;
96 }
tp_read(dns_ctx * c)97 int inline tp_read(dns_ctx *c)
98 {
99 	int len;
100 
101 	do {
102 #ifdef HAVE_IPV6
103 		if (using_6)
104 			len = socket_recv6(udp53,
105 					c->request_buf,
106 					512,
107 					c->ip,
108 					&c->port);
109 		else
110 #endif
111 		len = socket_recv4(udp53,
112 				c->request_buf,
113 				512,
114 				c->ip,
115 				&c->port);
116 		/* infinite if 0 hangs up */
117 		if (len == -1) {
118 			if (errno == EBADF || errno == EINVAL || errno == EFAULT)
119 				cfatal("read failed(%d): %s", udp53);
120 		}
121 	} while (len <= 0);
122 	if (len >= 512)
123 		return 0;
124 
125 	/* never allow axfr over UDP */
126 	c->axfr_base = 0;
127 	c->update = 0;
128 
129 	c->sock = udp53;
130 	c->request_pos = 0;
131 	c->request_len = len;
132 	return 1;
133 }
134 
135