2 * ircd-ratbox: A slightly useful ircd.
3 * adns.c: Interfaces to the adns DNS library.
5 * Copyright (C) 2001-2002 Aaron Sethman <androsyn@ratbox.org>
6 * Copyright (C) 2001-2002 Hybrid Development Team
7 * Copyright (C) 2002-2005 ircd-ratbox development team
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
24 * $Id: adns.c 22395 2006-05-07 10:23:50Z leeh $
37 #include "ircd_defs.h"
39 #include "../adns/internal.h"
43 /* void report_adns_servers(struct Client *source_p)
44 * Input: A client to send a list of DNS servers to.
46 * Side effects: Sends a list of DNS servers to source_p
49 report_adns_servers(struct Client
*source_p
)
52 char buf
[16]; /* XXX: adns only deals with ipv4 dns servers so this is okay */
53 for (x
= 0; x
< dns_state
->nservers
; x
++)
55 inetntop(AF_INET
, &dns_state
->servers
[x
].addr
.s_addr
, buf
, 16);
56 sendto_one_numeric(source_p
, RPL_STATSDEBUG
,
61 /* void delete_adns_queries(struct DNSQuery *q)
62 * Input: A pointer to the applicable DNSQuery structure.
64 * Side effects: Cancels a DNS query.
67 delete_adns_queries(struct DNSQuery
*q
)
69 if(q
!= NULL
&& q
->query
!= NULL
)
71 adns_cancel(q
->query
);
77 /* void restart_resolver(void)
80 * Side effects: Tears down any old ADNS sockets..reloads the conf
83 restart_resolver(void)
85 adns__rereadconfig(dns_state
);
88 /* void init_resolver(void)
91 * Side effects: Reads the ADNS configuration and sets up the ADNS server
92 * polling and query timeouts.
99 r
= adns_init(&dns_state
, adns_if_noautosys
, 0);
101 if(dns_state
== NULL
)
103 ilog(L_MAIN
, "Error opening /etc/resolv.conf: %s; r = %d", strerror(errno
), r
);
107 eventAddIsh("timeout_adns", timeout_adns
, NULL
, 2);
111 /* void timeout_adns(void *ptr);
114 * Side effects: Cancel any old(expired) DNS queries.
115 * Note: Called by the event code.
118 timeout_adns(void *ptr
)
120 adns_processtimeouts(dns_state
, &SystemTime
);
123 /* void dns_writeable(int fd, void *ptr)
124 * Input: An fd which has become writeable, ptr not used.
126 * Side effects: Write any queued buffers out.
127 * Note: Called by the fd system.
130 dns_writeable(int fd
, void *ptr
)
132 adns_processwriteable(dns_state
, fd
, &SystemTime
);
138 /* void dns_do_callbacks(void)
141 * Side effects: Call all the callbacks(into the ircd core) for the
142 * results of a DNS resolution.
145 dns_do_callbacks(void)
150 struct DNSQuery
*query
;
153 adns_forallqueries_begin(dns_state
);
155 while ((q
= adns_forallqueries_next(dns_state
, xr
)) != NULL
)
157 switch (adns_check(dns_state
, &q
, &answer
, xq
))
160 /* Looks like we got a winner */
161 assert(query
->callback
!= NULL
);
162 if(query
->callback
!= NULL
)
165 query
->callback(query
->ptr
, answer
);
170 /* Go into the queue again */
174 assert(query
->callback
!= NULL
);
175 if(query
->callback
!= NULL
)
177 /* Awww we failed, what a shame */
179 query
->callback(query
->ptr
, NULL
);
181 if(answer
!= NULL
&& answer
->status
== adns_s_systemfail
)
189 sendto_realops_flags(UMODE_ALL
, L_ALL
, "adns got a global system failure..attempting to restart resolver");
194 /* void dns_readable(int fd, void *ptr)
195 * Input: An fd which has become readable, ptr not used.
197 * Side effects: Read DNS responses from DNS servers.
198 * Note: Called by the fd system.
201 dns_readable(int fd
, void *ptr
)
203 adns_processreadable(dns_state
, fd
, &SystemTime
);
208 /* void dns_select(void)
211 * Side effects: Re-register ADNS fds with the fd system. Also calls the
212 * callbacks into core ircd.
217 struct adns_pollfd pollfds
[MAXFD_POLL
];
219 adns__consistency(dns_state
, 0, cc_entex
);
220 npollfds
= adns__pollfds(dns_state
, pollfds
);
221 for (i
= 0; i
< npollfds
; i
++)
224 if(pollfds
[i
].events
& ADNS_POLLIN
)
225 comm_setselect(fd
, FDLIST_SERVER
, COMM_SELECT_READ
, dns_readable
, NULL
);
226 if(pollfds
[i
].events
& ADNS_POLLOUT
)
227 comm_setselect(fd
, FDLIST_SERVICE
, COMM_SELECT_WRITE
,
228 dns_writeable
, NULL
);
232 /* int adns_gethost(const char *name, int aftype, struct DNSQuery *req);
233 * Input: A name, an address family, a DNSQuery structure.
235 * Side effects: Sets up a query structure and sends off a DNS query to
236 * the DNS server to resolve an "A"(address) entry by name.
239 adns_gethost(const char *name
, int aftype
, struct DNSQuery
*req
)
242 assert(dns_state
->nservers
> 0);
244 if(aftype
== AF_INET6
)
245 result
= adns_submit(dns_state
, name
, adns_r_addr6
, adns_qf_owner
, req
, &req
->query
);
248 result
= adns_submit(dns_state
, name
, adns_r_addr
, adns_qf_owner
, req
, &req
->query
);
253 /* int adns_getaddr(struct irc_inaddr *addr, int aftype,
254 * struct DNSQuery *req, int arpa_type);
255 * Input: An address, an address family, a DNSQuery structure.
257 * Side effects: Sets up a query entry and sends it to the DNS server to
258 * resolve an IP address to a domain name.
261 adns_getaddr(struct sockaddr
*addr
, int aftype
, struct DNSQuery
*req
)
264 int flags
= adns_r_ptr
;
265 assert(dns_state
->nservers
> 0);
267 if(addr
->sa_family
== AF_INET6
)
268 flags
= adns_r_ptr_ip6
;
270 result
= adns_submit_reverse(dns_state
,
271 (struct sockaddr
*) addr
,
273 adns_qf_owner
| adns_qf_cname_loose
|
274 adns_qf_quoteok_anshost
, req
, &req
->query
);