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