#include "config.h"
#include "ldapdns.h"
#include "ip.h"
#include "env.h"
static int udp53 = -1;
#ifdef HAVE_IPV6
static int using_6 = 0;
#endif
void tp_close(dns_ctx *c)
{
/* we NEVER close the UDP connections */
}
void inline tp_housekeeping(long *now)
{
/* there is no housekeeping for UDP */
}
void tp_initialize(void)
{
char *x;
char ip[IP_LEN];
int port;
x = env_get("IP");
if (!x)
x = "0.0.0.0";
if (!ipv4_scan(x, ip)) {
#ifdef HAVE_IPV6
if (ipv6_scan(x, ip))
using_6 = 1;
else
#endif
fatal("cannot parse IP: %s", x);
}
#ifdef HAVE_IPV6
if (using_6)
udp53 = socket_udp6();
else
#endif
udp53 = socket_udp4();
if (udp53 == -1)
cfatal("socket_udp4: %s");
x = env_get("PORT");
if (!x)
port = 53;
else {
port = atoi(x);
if (port < 1)
fatal("cannot parse PORT: %s", x);
if (port != 53)
warning("running on non-standard port: %d", port);
}
#ifdef HAVE_IPV6
if (using_6) {
if (socket_bind6_reuse(udp53, ip, port) == -1)
cfatal("socket_bind4_reuse: %s");
} else
#endif
if (socket_bind4_reuse(udp53, ip, port) == -1)
cfatal("socket_bind4_reuse: %s");
ndelay_off(udp53);
socket_tryreservein(udp53, 65536);
/* we NEVER allow axfr over udp... */
ldapdns.axfr_base = 0;
/* or allow updates... */
ldapdns.update = 0;
}
int inline tp_write(dns_ctx *c)
{
if (clen(c->response) > 512)
response_tc(c);
/* if this were to fail, it would be because the kernel buffers
* cannot support a single UDP packet... in which case it's a kernel
* problem.
*/
#ifdef HAVE_IPV6
if (using_6)
socket_send6(c->sock,
caddr(c->response),
clen(c->response),
c->ip,
c->port);
else
#endif
socket_send4(c->sock,
caddr(c->response),
clen(c->response),
c->ip,
c->port);
return 1;
}
int inline tp_read(dns_ctx *c)
{
int len;
do {
#ifdef HAVE_IPV6
if (using_6)
len = socket_recv6(udp53,
c->request_buf,
512,
c->ip,
&c->port);
else
#endif
len = socket_recv4(udp53,
c->request_buf,
512,
c->ip,
&c->port);
/* infinite if 0 hangs up */
if (len == -1) {
if (errno == EBADF || errno == EINVAL || errno == EFAULT)
cfatal("read failed(%d): %s", udp53);
}
} while (len <= 0);
if (len >= 512)
return 0;
/* never allow axfr over UDP */
c->axfr_base = 0;
c->update = 0;
c->sock = udp53;
c->request_pos = 0;
c->request_len = len;
return 1;
}
syntax highlighted by Code2HTML, v. 0.9.1