]> jfr.im git - solanum.git/blame - ircd/dns.c
Add .travis.yml
[solanum.git] / ircd / dns.c
CommitLineData
7d2852b4
AC
1/*
2 * dns.c: An interface to the resolver module in authd
3 * (based somewhat on ircd-ratbox dns.c)
4 *
5 * Copyright (C) 2005 Aaron Sethman <androsyn@ratbox.org>
6 * Copyright (C) 2005-2012 ircd-ratbox development team
7 * Copyright (C) 2016 William Pitcock <nenolod@dereferenced.org>
8 *
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.
13 *
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.
18 *
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
22 * USA
23 */
24
25#include <stdinc.h>
26#include <ratbox_lib.h>
1d997451 27#include <client.h>
7d2852b4
AC
28#include <ircd_defs.h>
29#include <parse.h>
30#include <dns.h>
31#include <match.h>
32#include <logger.h>
33#include <s_conf.h>
34#include <client.h>
35#include <send.h>
36#include <numeric.h>
37#include <msg.h>
38
39#define DNS_IDTABLE_SIZE 0x2000
40
1bf29198
AC
41#define DNS_HOST_IPV4 ((char)'4')
42#define DNS_HOST_IPV6 ((char)'6')
43#define DNS_REVERSE_IPV4 ((char)'R')
44#define DNS_REVERSE_IPV6 ((char)'S')
7d2852b4 45
1bf29198 46static void submit_dns(uint16_t id, char type, const char *addr);
7d2852b4 47
7d2852b4
AC
48struct dnsreq
49{
50 DNSCB callback;
51 void *data;
52};
53
54static struct dnsreq querytable[DNS_IDTABLE_SIZE];
55
56static uint16_t
57assign_dns_id(void)
58{
59 static uint16_t id = 1;
60 int loopcnt = 0;
61 while(1)
62 {
63 if(++loopcnt > DNS_IDTABLE_SIZE)
64 return 0;
65 if(id < DNS_IDTABLE_SIZE - 1 || id == 0)
66 id++;
67 else
68 id = 1;
69 if(querytable[id].callback == NULL)
70 break;
71 }
72 return (id);
73}
74
7d2852b4
AC
75static void
76handle_dns_failure(uint16_t xid)
77{
78 struct dnsreq *req;
79
80 req = &querytable[xid];
81 if(req->callback == NULL)
82 return;
83
84 req->callback("FAILED", 0, 0, req->data);
85 req->callback = NULL;
86 req->data = NULL;
87}
88
89void
90cancel_lookup(uint16_t xid)
91{
92 querytable[xid].callback = NULL;
93 querytable[xid].data = NULL;
94}
95
96uint16_t
97lookup_hostname(const char *hostname, int aftype, DNSCB callback, void *data)
98{
99 struct dnsreq *req;
100 int aft;
101 uint16_t nid;
102 check_authd();
103 nid = assign_dns_id();
104 if((nid = assign_dns_id()) == 0)
105 return 0;
106
107 req = &querytable[nid];
108
109 req->callback = callback;
110 req->data = data;
111
112#ifdef RB_IPV6
113 if(aftype == AF_INET6)
114 aft = 6;
115 else
116#endif
117 aft = 4;
118
1bf29198 119 submit_dns(nid, aft == 4 ? DNS_HOST_IPV4 : DNS_HOST_IPV6, hostname);
7d2852b4
AC
120 return (nid);
121}
122
123uint16_t
124lookup_ip(const char *addr, int aftype, DNSCB callback, void *data)
125{
126 struct dnsreq *req;
127 int aft;
128 uint16_t nid;
129 check_authd();
130
131 if((nid = assign_dns_id()) == 0)
132 return 0;
133
134 req = &querytable[nid];
135
136 req->callback = callback;
137 req->data = data;
138
139#ifdef RB_IPV6
140 if(aftype == AF_INET6)
141 aft = 6;
142 else
143#endif
144 aft = 4;
145
1bf29198 146 submit_dns(nid, aft == 4 ? DNS_REVERSE_IPV4 : DNS_REVERSE_IPV6, addr);
7d2852b4
AC
147 return (nid);
148}
149
fb7d74ef 150void
1bf29198 151dns_results_callback(const char *callid, const char *status, const char *type, const char *results)
7d2852b4
AC
152{
153 struct dnsreq *req;
154 uint16_t nid;
155 int st;
156 int aft;
157 long lnid = strtol(callid, NULL, 16);
158
159 if(lnid > DNS_IDTABLE_SIZE || lnid == 0)
160 return;
161 nid = (uint16_t)lnid;
162 req = &querytable[nid];
1bf29198
AC
163 st = *status == 'O';
164 aft = *type == '6' || *type == 'S' ? 6 : 4;
7d2852b4
AC
165 if(req->callback == NULL)
166 {
167 /* got cancelled..oh well */
168 req->data = NULL;
169 return;
170 }
171#ifdef RB_IPV6
172 if(aft == 6)
173 aft = AF_INET6;
174 else
175#endif
176 aft = AF_INET;
177
178 req->callback(results, st, aft, req->data);
179 req->callback = NULL;
180 req->data = NULL;
181}
182
7d2852b4
AC
183void
184report_dns_servers(struct Client *source_p)
185{
186#if 0
187 rb_dlink_node *ptr;
188 RB_DLINK_FOREACH(ptr, nameservers.head)
189 {
190 sendto_one_numeric(source_p, RPL_STATSDEBUG, "A %s", (char *)ptr->data);
191 }
192#endif
193}
194
7d2852b4 195static void
1bf29198 196submit_dns(uint16_t nid, char type, const char *addr)
7d2852b4
AC
197{
198 if(authd_helper == NULL)
199 {
200 handle_dns_failure(nid);
201 return;
202 }
1bf29198 203 rb_helper_write(authd_helper, "D %x %c %s", nid, type, addr);
7d2852b4 204}