Blame
Date:
Sat Nov 8 20:28:31 2014 UTC
Message:
0.9.0 is the last version of Wildcarddnsd, the succeeding project is called Delphinusdnsd and will have its first release around November 15th, 2015. The new project page is at http://delphinusdns.centroid.eu.
0001
2010-05-26
pbug
/*
0002
2014-04-13
pjp
* Copyright (c) 2010-2014 Peter J. Philipp
0003
2010-04-15
pbug
* All rights reserved.
0004
2010-04-15
pbug
*
0005
2010-04-15
pbug
* Redistribution and use in source and binary forms, with or without
0006
2010-04-15
pbug
* modification, are permitted provided that the following conditions
0007
2010-04-15
pbug
* are met:
0008
2010-04-15
pbug
* 1. Redistributions of source code must retain the above copyright
0009
2010-04-15
pbug
* notice, this list of conditions and the following disclaimer.
0010
2010-04-15
pbug
* 2. Redistributions in binary form must reproduce the above copyright
0011
2010-04-15
pbug
* notice, this list of conditions and the following disclaimer in the
0012
2010-04-15
pbug
* documentation and/or other materials provided with the distribution.
0013
2010-04-15
pbug
* 3. The name of the author may not be used to endorse or promote products
0014
2010-04-15
pbug
* derived from this software without specific prior written permission
0015
2010-04-15
pbug
*
0016
2010-04-15
pbug
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0017
2010-04-15
pbug
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0018
2010-04-15
pbug
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0019
2010-04-15
pbug
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0020
2010-04-15
pbug
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0021
2010-04-15
pbug
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0022
2010-04-15
pbug
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0023
2010-04-15
pbug
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0024
2010-04-15
pbug
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0025
2010-04-15
pbug
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0026
2010-04-15
pbug
*
0027
2010-04-15
pbug
*/
0028
2010-04-15
pbug
#include "include.h"
0029
2010-04-15
pbug
#include "dns.h"
0030
2010-04-15
pbug
#include "db.h"
0031
2010-04-15
pbug
0032
2014-05-18
pjp
extern struct question *build_fake_question(char *, int, u_int16_t);
0033
2014-05-18
pjp
extern struct question *build_question(char *, int);
0034
2014-05-18
pjp
extern void build_reply(struct sreply *, int, char *, int, struct question *, struct sockaddr *, socklen_t, struct domain *, struct domain *, u_int8_t, int, int, struct recurses *);
0035
2014-05-18
pjp
extern void dolog(int, char *, ...);
0036
2014-05-18
pjp
extern int free_question(struct question *);
0037
2014-05-18
pjp
extern int get_soa(DB *, struct question *, struct domain *, int);
0038
2014-05-18
pjp
extern in_addr_t getmask(int);
0039
2014-05-18
pjp
extern int getmask6(int, struct sockaddr_in6 *);
0040
2014-05-18
pjp
extern int lookup_zone(DB *, struct question *, struct domain *, int *, char *, int);
0041
2014-05-18
pjp
extern int memcasecmp(u_char *, u_char *, int);
0042
2014-05-18
pjp
extern void reply_a(struct sreply *, DB *);
0043
2014-05-18
pjp
extern void reply_aaaa(struct sreply *, DB *);
0044
2014-05-18
pjp
extern void reply_cname(struct sreply *);
0045
2014-05-18
pjp
extern void reply_mx(struct sreply *, DB *);
0046
2014-05-18
pjp
extern void reply_ns(struct sreply *, DB *);
0047
2014-05-18
pjp
extern void reply_noerror(struct sreply *);
0048
2014-05-18
pjp
extern void reply_nxdomain(struct sreply *);
0049
2014-05-18
pjp
extern void reply_ptr(struct sreply *);
0050
2014-05-18
pjp
extern void reply_soa(struct sreply *);
0051
2014-05-18
pjp
extern void reply_txt(struct sreply *sreply);
0052
2014-05-18
pjp
extern void slave_shutdown(void);
0053
2014-05-18
pjp
extern void update_db(DB *, struct domain *);
0054
2010-04-15
pbug
0055
2014-05-18
pjp
int contains(u_char *, u_char *);
0056
2014-05-18
pjp
void init_recurse(void);
0057
2014-05-18
pjp
int insert_recurse(char *, char *);
0058
2014-05-18
pjp
int fakerecurse(DB *, struct recurses *, struct ns *, int);
0059
2014-05-18
pjp
int find_recurse(struct sockaddr_storage *, int);
0060
2014-05-18
pjp
int level(u_char *);
0061
2014-05-18
pjp
int lookup_a(DB *, struct recurses *, struct ns *);
0062
2014-05-18
pjp
int lookup_aaaa(DB *, struct recurses *, struct ns *);
0063
2014-05-18
pjp
int lookup_ns(DB *, struct recurses *);
0064
2014-05-18
pjp
int negative_cache(DB *, struct recurses *);
0065
2014-05-18
pjp
int netlookup(DB *, struct recurses *);
0066
2014-05-18
pjp
int netlookup6(DB *, struct recurses *);
0067
2014-05-18
pjp
void recurseloop(int, int *, DB *);
0068
2014-05-18
pjp
int recurse_parse(DB *, struct recurses *, u_char *, u_int16_t);
0069
2014-05-18
pjp
void reply_raw(DB *, struct recurses *, struct domain *, int *);
0070
2014-05-18
pjp
void reply_raw_cname(DB *, struct recurses *, struct domain *, int *);
0071
2014-05-18
pjp
void reply_raw_noerror(DB *, struct recurses *, struct domain *, int *);
0072
2014-05-18
pjp
void reply_raw_nxdomain(DB *, struct recurses *, struct domain *, int *);
0073
2014-05-18
pjp
void remove_zone(DB *, struct domain *);
0074
2010-11-06
pbug
0075
2013-02-16
pjp
extern int debug, verbose;
0076
2011-04-12
pbug
0077
2010-09-28
pbug
#ifndef MIN
0078
2010-09-28
pbug
#define MIN(a,b) ((a < b) ? a : b)
0079
2010-09-28
pbug
#endif
0080
2010-09-28
pbug
0081
2010-04-15
pbug
SLIST_HEAD(listhead, recurseentry) recursehead;
0082
2010-04-15
pbug
0083
2014-05-01
pjp
static struct recurseentry {
0084
2010-04-15
pbug
char name[INET6_ADDRSTRLEN];
0085
2010-04-15
pbug
int family;
0086
2010-04-15
pbug
struct sockaddr_storage hostmask;
0087
2010-04-15
pbug
struct sockaddr_storage netmask;
0088
2010-04-15
pbug
u_int8_t prefixlen;
0089
2014-05-01
pjp
SLIST_ENTRY(recurseentry) recurse_entry;
0090
2014-05-01
pjp
} *rn2, *rnp;
0091
2010-04-15
pbug
0092
2010-04-15
pbug
0093
2014-09-27
pjp
static const char rcsid[] = "$Id: recurse.c,v 1.45 2014/09/27 17:38:28 pjp Exp $";
0094
2010-04-15
pbug
0095
2010-04-15
pbug
/*
0096
2010-04-15
pbug
* INIT_RECURSE - initialize the recurse singly linked list
0097
2010-04-15
pbug
*/
0098
2010-04-15
pbug
0099
2010-04-15
pbug
void
0100
2010-04-15
pbug
init_recurse(void)
0101
2010-04-15
pbug
{
0102
2010-04-15
pbug
SLIST_INIT(&recursehead);
0103
2010-04-15
pbug
return;
0104
2010-04-15
pbug
}
0105
2010-04-15
pbug
0106
2010-04-15
pbug
/*
0107
2010-04-15
pbug
* INSERT_RECURSE - insert an address and prefixlen into the recurse slist
0108
2010-04-15
pbug
*/
0109
2010-04-15
pbug
0110
2010-04-15
pbug
int
0111
2010-04-15
pbug
insert_recurse(char *address, char *prefixlen)
0112
2010-04-15
pbug
{
0113
2010-04-15
pbug
struct sockaddr_in *sin;
0114
2010-04-15
pbug
struct sockaddr_in6 *sin6;
0115
2010-04-15
pbug
int pnum;
0116
2010-04-15
pbug
int ret;
0117
2010-04-15
pbug
0118
2010-04-15
pbug
pnum = atoi(prefixlen);
0119
2010-04-15
pbug
rn2 = malloc(sizeof(struct recurseentry)); /* Insert after. */
0120
2010-04-15
pbug
0121
2010-04-15
pbug
if (strchr(address, ':') != NULL) {
0122
2010-04-15
pbug
rn2->family = AF_INET6;
0123
2010-04-15
pbug
sin6 = (struct sockaddr_in6 *)&rn2->hostmask;
0124
2010-04-15
pbug
if ((ret = inet_pton(AF_INET6, address, &sin6->sin6_addr.s6_addr)) != 1)
0125
2010-04-15
pbug
return (-1);
0126
2010-04-15
pbug
sin6->sin6_family = AF_INET6;
0127
2010-04-15
pbug
sin6 = (struct sockaddr_in6 *)&rn2->netmask;
0128
2010-04-15
pbug
sin6->sin6_family = AF_INET6;
0129
2010-04-15
pbug
if (getmask6(pnum, sin6) < 0)
0130
2010-04-15
pbug
return(-1);
0131
2010-04-15
pbug
rn2->prefixlen = pnum;
0132
2010-04-15
pbug
} else {
0133
2010-04-15
pbug
0134
2010-04-15
pbug
rn2->family = AF_INET;
0135
2010-04-15
pbug
sin = (struct sockaddr_in *)&rn2->hostmask;
0136
2010-04-15
pbug
sin->sin_family = AF_INET;
0137
2010-04-15
pbug
sin->sin_addr.s_addr = inet_addr(address);
0138
2010-04-15
pbug
sin = (struct sockaddr_in *)&rn2->netmask;
0139
2010-04-15
pbug
sin->sin_family = AF_INET;
0140
2010-04-15
pbug
sin->sin_addr.s_addr = getmask(pnum);
0141
2010-04-15
pbug
rn2->prefixlen = pnum;
0142
2010-04-15
pbug
0143
2010-04-15
pbug
}
0144
2010-04-15
pbug
0145
2014-05-01
pjp
SLIST_INSERT_HEAD(&recursehead, rn2, recurse_entry);
0146
2010-04-15
pbug
0147
2010-04-15
pbug
return (0);
0148
2010-04-15
pbug
}
0149
2010-04-15
pbug
0150
2010-04-15
pbug
/*
0151
2010-04-15
pbug
* FIND_RECURSE - walk the recurse list and find the correponding network
0152
2010-04-15
pbug
* if a network matches return 1, if no match is found return
0153
2010-04-15
pbug
* 0.
0154
2010-04-15
pbug
*/
0155
2010-04-15
pbug
0156
2010-04-15
pbug
int
0157
2010-04-15
pbug
find_recurse(struct sockaddr_storage *sst, int family)
0158
2010-04-15
pbug
{
0159
2010-04-15
pbug
struct sockaddr_in *sin, *sin0;
0160
2010-04-15
pbug
struct sockaddr_in6 *sin6, *sin60, *sin61;
0161
2010-04-15
pbug
u_int32_t hostmask, netmask;
0162
2010-04-15
pbug
u_int32_t a;
0163
2010-04-15
pbug
#ifdef __amd64
0164
2010-04-15
pbug
u_int64_t *hm[2], *nm[2], *a6[2];
0165
2010-04-15
pbug
#else
0166
2010-04-15
pbug
u_int32_t *hm[4], *nm[4], *a6[4];
0167
2010-04-15
pbug
#endif
0168
2010-04-15
pbug
0169
2014-05-01
pjp
SLIST_FOREACH(rnp, &recursehead, recurse_entry) {
0170
2010-04-15
pbug
if (rnp->family == AF_INET) {
0171
2010-04-15
pbug
if (family != AF_INET)
0172
2010-04-15
pbug
continue;
0173
2010-04-15
pbug
sin = (struct sockaddr_in *)sst;
0174
2010-04-15
pbug
a = sin->sin_addr.s_addr;
0175
2010-04-15
pbug
sin = (struct sockaddr_in *)&rnp->hostmask;
0176
2010-04-15
pbug
sin0 = (struct sockaddr_in *)&rnp->netmask;
0177
2010-04-15
pbug
hostmask = sin->sin_addr.s_addr;
0178
2010-04-15
pbug
netmask = sin0->sin_addr.s_addr;
0179
2010-04-15
pbug
if ((hostmask & netmask) == (a & netmask)) {
0180
2010-04-15
pbug
return (1);
0181
2010-04-15
pbug
} /* if hostmask */
0182
2010-04-15
pbug
} else if (rnp->family == AF_INET6) {
0183
2010-04-15
pbug
if (family != AF_INET6)
0184
2010-04-15
pbug
continue;
0185
2010-04-15
pbug
sin6 = (struct sockaddr_in6 *)sst;
0186
2010-04-15
pbug
sin60 = (struct sockaddr_in6 *)&rnp->hostmask;
0187
2010-04-15
pbug
sin61 = (struct sockaddr_in6 *)&rnp->netmask;
0188
2010-04-15
pbug
#ifdef __amd64
0189
2010-04-15
pbug
/*
0190
2010-04-15
pbug
* If this is on a 64 bit machine, we'll benefit
0191
2010-04-15
pbug
* by using 64 bit registers, this should make it
0192
2010-04-15
pbug
* a tad faster...
0193
2010-04-15
pbug
*/
0194
2010-04-15
pbug
hm[0] = (u_int64_t *)&sin60->sin6_addr.s6_addr;
0195
2010-04-15
pbug
hm[1] = (hm[0] + 1);
0196
2010-04-15
pbug
nm[0] = (u_int64_t *)&sin61->sin6_addr.s6_addr;
0197
2010-04-15
pbug
nm[1] = (nm[0] + 1);
0198
2010-04-15
pbug
a6[0] = (u_int64_t *)&sin6->sin6_addr.s6_addr;
0199
2010-04-15
pbug
a6[1] = (a6[0] + 1);
0200
2010-04-15
pbug
if ( ((*hm[0] & *nm[0]) == (*a6[0] & *nm[0]))&&
0201
2010-04-15
pbug
((*hm[1] & *nm[1]) == (*a6[1] & *nm[1]))) {
0202
2010-04-15
pbug
#else
0203
2010-04-15
pbug
hm[0] = (u_int32_t *)&sin60->sin6_addr.s6_addr;
0204
2010-04-15
pbug
hm[1] = (hm[0] + 1); hm[2] = (hm[1] + 1);
0205
2010-04-15
pbug
hm[3] = (hm[2] + 1);
0206
2010-04-15
pbug
nm[0] = (u_int32_t *)&sin61->sin6_addr.s6_addr;
0207
2010-04-15
pbug
nm[1] = (nm[0] + 1); nm[2] = (nm[1] + 1);
0208
2010-04-15
pbug
nm[3] = (nm[2] + 1);
0209
2010-04-15
pbug
a6[0] = (u_int32_t *)&sin6->sin6_addr.s6_addr;
0210
2010-04-15
pbug
a6[1] = (a6[0] + 1); a6[2] = (a6[1] + 1);
0211
2010-04-15
pbug
a6[3] = (a6[2] + 1);
0212
2010-04-15
pbug
0213
2010-04-15
pbug
if ( ((*hm[0] & *nm[0]) == (*a6[0] & *nm[0]))&&
0214
2010-04-15
pbug
((*hm[1] & *nm[1]) == (*a6[1] & *nm[1]))&&
0215
2010-04-15
pbug
((*hm[2] & *nm[2]) == (*a6[2] & *nm[2]))&&
0216
2010-04-15
pbug
((*hm[3] & *nm[3]) == (*a6[3] & *nm[3]))) {
0217
2010-04-15
pbug
#endif
0218
2010-04-15
pbug
0219
2010-04-15
pbug
return (1);
0220
2010-04-15
pbug
} /* if ip6 address */
0221
2010-04-15
pbug
0222
2010-04-15
pbug
} /* if AF_INET6 */
0223
2010-04-15
pbug
} /* SLIST */
0224
2010-04-15
pbug
0225
2010-04-15
pbug
return (0);
0226
2010-04-15
pbug
}
0227
2010-04-15
pbug
0228
2010-04-15
pbug
void
0229
2010-04-15
pbug
recurseloop(int sp, int *raw, DB *db)
0230
2010-04-15
pbug
{
0231
2010-04-15
pbug
int sel, ret;
0232
2010-09-24
pbug
int maxso, len;
0233
2010-10-11
pbug
socklen_t slen = sizeof(struct sockaddr_storage);
0234
2010-04-15
pbug
fd_set rset;
0235
2010-04-15
pbug
struct timeval tv;
0236
2010-04-15
pbug
struct srecurseheader rh;
0237
2010-09-15
pbug
struct domain sd;
0238
2010-09-15
pbug
struct dns_header *dh;
0239
2010-10-11
pbug
struct sockaddr_storage ssin;
0240
2010-10-11
pbug
struct sockaddr_in *sin;
0241
2010-10-11
pbug
struct sockaddr_in6 *sin6;
0242
2010-04-15
pbug
0243
2010-09-15
pbug
int type, lzerrno, wildcard = 0;
0244
2010-09-15
pbug
0245
2010-09-15
pbug
char fakereplystring[DNS_MAXNAME + 1];
0246
2010-09-15
pbug
char buf[2048];
0247
2010-11-09
pbug
char address[INET6_ADDRSTRLEN];
0248
2010-04-15
pbug
0249
2010-05-26
pbug
SLIST_INIT(&recurseshead);
0250
2010-05-26
pbug
0251
2010-04-15
pbug
for (;;) {
0252
2010-09-21
pbug
/*
0253
2010-09-21
pbug
* launch all fakesr requests
0254
2010-09-21
pbug
*/
0255
2014-05-01
pjp
SLIST_FOREACH(sr1, &recurseshead, recurses_entry) {
0256
2010-09-21
pbug
if (sr1->isfake && !sr1->launched) {
0257
2013-02-16
pjp
dolog(LOG_DEBUG, "launching question (fakesr) for %s", sr1->question->hdr->name);
0258
2010-09-21
pbug
sr1->launched = 1;
0259
2010-09-21
pbug
type = lookup_zone(db, sr1->question, &sd, &lzerrno, (char *)fakereplystring, wildcard);
0260
2010-09-21
pbug
if (type < 0) {
0261
2010-09-24
pbug
netlookup(db, sr1);
0262
2010-09-21
pbug
} else {
0263
2014-05-01
pjp
SLIST_REMOVE(&recurseshead, sr1, recurses, recurses_entry);
0264
2010-09-21
pbug
sr1->callback->hascallback--;
0265
2010-09-21
pbug
free_question(sr1->question);
0266
2010-09-21
pbug
free(sr1);
0267
2010-09-21
pbug
}
0268
2010-09-21
pbug
}
0269
2010-09-26
pbug
0270
2010-09-26
pbug
/*
0271
2010-09-26
pbug
* while we're going through the list to look for
0272
2010-09-26
pbug
* fakesr launches we may as well expire recurses
0273
2010-09-26
pbug
* that have timed out (> 10 seconds)
0274
2010-09-26
pbug
*/
0275
2010-09-28
pbug
if (difftime(time(NULL), sr1->received) >= 30) {
0276
2010-10-03
pbug
/* only remove if we don't have any callbacks
0277
2010-10-03
pbug
* outstanding...
0278
2010-10-03
pbug
*/
0279
2010-10-03
pbug
if (! sr1->hascallback) {
0280
2013-02-16
pjp
dolog(LOG_DEBUG, "removing recurses struct");
0281
2014-05-01
pjp
SLIST_REMOVE(&recurseshead, sr1, recurses, recurses_entry);
0282
2010-10-03
pbug
if (sr1->so != -1) {
0283
2010-10-03
pbug
if (close(sr1->so) < 0)
0284
2013-02-16
pjp
dolog(LOG_ERR, "close: %m");
0285
2010-10-03
pbug
sr1->so = -1;
0286
2010-10-03
pbug
}
0287
2010-10-03
pbug
0288
2010-10-03
pbug
if (sr1->callback)
0289
2010-10-03
pbug
sr1->callback->hascallback--;
0290
2010-09-26
pbug
0291
2010-10-03
pbug
free_question(sr1->question);
0292
2010-10-03
pbug
free(sr1);
0293
2010-10-03
pbug
}
0294
2010-09-26
pbug
}
0295
2010-09-21
pbug
}
0296
2010-04-15
pbug
FD_ZERO(&rset);
0297
2010-04-15
pbug
0298
2010-09-15
pbug
maxso = sp;
0299
2010-04-15
pbug
FD_SET(sp, &rset);
0300
2010-04-15
pbug
0301
2010-09-15
pbug
/* XXX remember recurseshead is for struct recurses */
0302
2014-05-01
pjp
SLIST_FOREACH(sr1, &recurseshead, recurses_entry) {
0303
2010-09-19
pbug
if (sr1->so != -1) {
0304
2010-09-19
pbug
if (maxso < sr1->so)
0305
2010-09-19
pbug
maxso = sr1->so;
0306
2010-09-15
pbug
0307
2010-09-19
pbug
FD_SET(sr1->so, &rset);
0308
2010-09-19
pbug
}
0309
2010-09-15
pbug
}
0310
2010-09-15
pbug
0311
2010-04-15
pbug
tv.tv_sec = 1;
0312
2010-04-15
pbug
tv.tv_usec = 0;
0313
2010-09-15
pbug
sel = select(maxso + 1, &rset, NULL, NULL, &tv);
0314
2010-04-15
pbug
if (sel < 0) {
0315
2013-02-16
pjp
dolog(LOG_INFO, "select: %m");
0316
2010-04-15
pbug
continue;
0317
2010-04-15
pbug
} else if (sel == 0) {
0318
2010-04-15
pbug
/* timeout */
0319
2010-04-15
pbug
continue;
0320
2010-04-15
pbug
}
0321
2010-04-15
pbug
0322
2010-04-15
pbug
if (FD_ISSET(sp, &rset)) {
0323
2010-04-15
pbug
ret = recv(sp, (char *)&rh, sizeof(rh), 0);
0324
2010-04-15
pbug
if (ret < 0) {
0325
2013-02-16
pjp
dolog(LOG_INFO, "recv: %m");
0326
2010-04-15
pbug
continue;
0327
2010-04-15
pbug
}
0328
2010-04-15
pbug
0329
2010-09-15
pbug
/* place request on struct recurses linked list */
0330
2010-09-15
pbug
0331
2010-09-15
pbug
sr = calloc(sizeof(struct recurses), 1);
0332
2010-09-15
pbug
if (sr == NULL) {
0333
2013-02-16
pjp
dolog(LOG_ERR, "calloc: %m");
0334
2010-09-15
pbug
continue;
0335
2010-09-15
pbug
}
0336
2010-09-15
pbug
0337
2010-09-15
pbug
memcpy(&sr->query, &rh.buf, 512);
0338
2010-09-15
pbug
sr->len = rh.len;
0339
2010-09-15
pbug
sr->af = rh.af;
0340
2010-09-15
pbug
sr->proto = rh.proto;
0341
2010-09-15
pbug
sr->so = -1;
0342
2010-09-18
pbug
sr->callback = NULL;
0343
2010-09-19
pbug
sr->hascallback = 0;
0344
2010-09-18
pbug
sr->isfake = 0;
0345
2010-09-25
pbug
sr->packetcount = 0;
0346
2010-09-28
pbug
sr->lookrecord = NULL;
0347
2010-09-15
pbug
memcpy(&sr->source, &rh.source, sizeof(struct sockaddr_storage));
0348
2010-09-15
pbug
memcpy(&sr->dest, &rh.dest, sizeof(struct sockaddr_storage));
0349
2010-09-15
pbug
sr->received = time(NULL);
0350
2010-09-15
pbug
0351
2010-09-15
pbug
sr->question = build_question(sr->query, sr->len);
0352
2010-09-15
pbug
if (sr->question == NULL) {
0353
2013-02-16
pjp
dolog(LOG_ERR, "malformed question in recurse.c");
0354
2010-09-15
pbug
free(sr);
0355
2010-09-15
pbug
continue;
0356
2010-09-15
pbug
}
0357
2010-09-15
pbug
0358
2010-09-15
pbug
type = lookup_zone(db, sr->question, &sd, &lzerrno, (char *)fakereplystring, wildcard);
0359
2010-09-15
pbug
if (type < 0) {
0360
2010-09-25
pbug
if (lzerrno == ERR_NOERROR &&
0361
2010-09-25
pbug
(sd.flags & DOMAIN_NEGATIVE_CACHE) ==
0362
2010-09-25
pbug
DOMAIN_NEGATIVE_CACHE) {
0363
2010-09-25
pbug
0364
2010-09-25
pbug
reply_raw_nxdomain(db, sr, &sd, raw);
0365
2010-09-25
pbug
free_question(sr->question);
0366
2010-09-25
pbug
free(sr);
0367
2010-09-25
pbug
continue;
0368
2010-09-25
pbug
0369
2010-09-25
pbug
}
0370
2010-09-24
pbug
if (netlookup(db, sr) < 0)
0371
2010-09-24
pbug
continue;
0372
2010-09-15
pbug
0373
2014-05-01
pjp
SLIST_INSERT_HEAD(&recurseshead, sr, recurses_entry);
0374
2010-09-17
pbug
} else {
0375
2013-02-16
pjp
dolog(LOG_DEBUG, "we had the record in our cache, reply action");
0376
2010-09-21
pbug
/* check if zone is expired */
0377
2010-09-19
pbug
0378
2010-09-21
pbug
if ((! (sd.flags & DOMAIN_STATIC_ZONE)) &&
0379
2010-09-21
pbug
(sd.created + sd.ttl < time(NULL))) {
0380
2010-09-21
pbug
remove_zone(db, &sd);
0381
2010-09-21
pbug
0382
2010-09-21
pbug
/* continue with netlookup */
0383
2010-09-21
pbug
0384
2010-09-21
pbug
if (netlookup(db, sr) < 0)
0385
2010-09-21
pbug
continue;
0386
2010-09-21
pbug
0387
2014-05-01
pjp
SLIST_INSERT_HEAD(&recurseshead, sr, recurses_entry);
0388
2010-09-21
pbug
continue;
0389
2010-09-21
pbug
}
0390
2010-09-21
pbug
0391
2010-09-26
pbug
if (type == DNS_TYPE_CNAME)
0392
2010-09-26
pbug
reply_raw_cname(db, sr, &sd, raw);
0393
2010-09-26
pbug
else
0394
2010-09-26
pbug
reply_raw(db, sr, &sd, raw);
0395
2010-09-26
pbug
0396
2010-09-19
pbug
free_question(sr->question);
0397
2010-09-19
pbug
free(sr);
0398
2010-09-15
pbug
continue;
0399
2010-05-26
pbug
}
0400
2010-09-15
pbug
0401
2010-09-15
pbug
} /* FD_ISSET(sp) */
0402
2010-09-15
pbug
0403
2014-05-01
pjp
SLIST_FOREACH(sr1, &recurseshead, recurses_entry) {
0404
2010-09-19
pbug
if (sr1->so != -1 && FD_ISSET(sr1->so, &rset)) {
0405
2010-09-15
pbug
/*
0406
2010-09-15
pbug
* we got a reply from the nameserver we
0407
2010-09-15
pbug
* queried, now we must parse the input
0408
2010-09-15
pbug
*/
0409
2010-09-15
pbug
0410
2010-10-11
pbug
slen = sizeof(struct sockaddr_storage);
0411
2010-10-11
pbug
if ((len = recvfrom(sr1->so, buf, sizeof(buf), 0, (struct sockaddr *)&ssin, &slen)) < 0) {
0412
2010-09-26
pbug
if (errno != EWOULDBLOCK)
0413
2013-02-16
pjp
dolog(LOG_ERR, "recvfrom: %m");
0414
2010-09-15
pbug
continue;
0415
2010-09-15
pbug
}
0416
2010-09-15
pbug
0417
2010-09-17
pbug
#if 1
0418
2010-09-15
pbug
/* XXX do some checking of expected IP address */
0419
2010-10-11
pbug
0420
2010-10-11
pbug
switch (ssin.ss_family) {
0421
2010-10-11
pbug
case AF_INET:
0422
2010-10-11
pbug
sin = (struct sockaddr_in *)&ssin;
0423
2010-10-11
pbug
if (sin->sin_addr.s_addr != sr1->a[0]) {
0424
2013-02-16
pjp
dolog(LOG_ERR, "return address is not from right nameserver");
0425
2010-10-11
pbug
continue;
0426
2010-10-11
pbug
}
0427
2010-11-09
pbug
break;
0428
2010-10-11
pbug
case AF_INET6:
0429
2010-10-11
pbug
sin6 = (struct sockaddr_in6*)&ssin;
0430
2010-10-11
pbug
if (memcmp((char *)&sin6->sin6_addr, (char *)&sr1->aaaa[0], sizeof(struct in6_addr)) != 0) {
0431
2010-11-09
pbug
inet_ntop(AF_INET6, &sin6->sin6_addr, address, sizeof(address));
0432
2010-10-11
pbug
0433
2013-02-16
pjp
dolog(LOG_ERR, "return IPv6 address (%s) is not from right nameserver", address);
0434
2010-10-11
pbug
continue;
0435
2010-10-11
pbug
}
0436
2010-11-09
pbug
break;
0437
2010-09-15
pbug
}
0438
2010-09-17
pbug
#endif
0439
2010-09-15
pbug
0440
2010-09-15
pbug
if (len < sizeof(struct dns_header)) {
0441
2013-02-16
pjp
dolog(LOG_ERR, "size malformed on reply len=%d", len);
0442
2010-09-15
pbug
/* on error, we just go out and wait for the real ID, this sucks! XXX */
0443
2010-09-15
pbug
continue;
0444
2010-09-15
pbug
}
0445
2010-09-15
pbug
0446
2010-09-15
pbug
dh = (struct dns_header*)&buf[0];
0447
2010-09-15
pbug
0448
2010-09-15
pbug
if (ntohs(dh->id) != sr1->id) {
0449
2013-02-16
pjp
dolog(LOG_ERR, "unexpected dns ID (%u != %u)", ntohs(dh->id), sr1->id);
0450
2010-09-15
pbug
/* on error, we just go out and wait for the real ID, this sucks! XXX */
0451
2010-09-15
pbug
continue;
0452
2010-09-15
pbug
}
0453
2010-09-15
pbug
0454
2010-09-15
pbug
if (! (ntohs(dh->query) & DNS_REPLY)) {
0455
2013-02-16
pjp
dolog(LOG_ERR, "reply is not a DNS reply");
0456
2010-09-15
pbug
continue;
0457
2010-09-15
pbug
}
0458
2010-09-15
pbug
0459
2010-09-15
pbug
/* XXX */
0460
2010-09-15
pbug
0461
2010-09-26
pbug
if (close(sr1->so) < 0)
0462
2013-02-16
pjp
dolog(LOG_ERR, "close: %m");
0463
2010-09-26
pbug
0464
2010-09-17
pbug
sr1->so = -1;
0465
2010-09-17
pbug
0466
2010-09-15
pbug
if (ntohs(dh->query) & DNS_NAMEERR) {
0467
2010-09-15
pbug
negative_cache(db, sr1);
0468
2013-02-16
pjp
dolog(LOG_DEBUG, "added negative cache for domain \"%s\"", sr1->question->converted_name);
0469
2010-09-15
pbug
/* reply negatively */
0470
2010-09-25
pbug
reply_raw_nxdomain(db, sr1, &sd, raw);
0471
2010-09-15
pbug
goto remove;
0472
2010-09-15
pbug
}
0473
2010-09-15
pbug
0474
2010-09-25
pbug
sr1->authoritative = 0;
0475
2010-09-24
pbug
recurse_parse(db, sr1, (u_char*)&buf, len);
0476
2010-09-15
pbug
0477
2010-09-25
pbug
/* check if we're flooding anything */
0478
2010-09-25
pbug
if (sr1->packetcount > 50) {
0479
2013-02-16
pjp
dolog(LOG_ERR, "packetcount is over 50, I think I'm flooding something, abort()");
0480
2011-04-12
pbug
slave_shutdown();
0481
2010-09-25
pbug
abort();
0482
2010-09-25
pbug
}
0483
2010-09-25
pbug
0484
2010-09-18
pbug
type = lookup_zone(db, sr1->question, &sd, &lzerrno, (char *)fakereplystring, wildcard);
0485
2010-09-17
pbug
if (type < 0) {
0486
2013-02-16
pjp
dolog(LOG_DEBUG, "lookup_zone failed, doing netlookup");
0487
2010-09-25
pbug
0488
2010-09-25
pbug
if (sr1->authoritative == DNS_TYPE_NS &&
0489
2010-09-25
pbug
netlookup(db, sr1) < 0) {
0490
2013-02-16
pjp
dolog(LOG_DEBUG, "subsequent netlookup failed");
0491
2010-09-25
pbug
0492
2010-09-17
pbug
}
0493
2010-09-19
pbug
0494
2010-09-25
pbug
if (sr1->authoritative == DNS_TYPE_SOA) {
0495
2013-02-16
pjp
dolog(LOG_DEBUG, "got an authoritative SOA answer, we'd reply an SOA here");
0496
2010-09-25
pbug
memset(&sd, 0, sizeof(struct domain));
0497
2010-09-25
pbug
get_soa(db, sr1->question, &sd, wildcard);
0498
2010-09-25
pbug
0499
2010-09-25
pbug
reply_raw_noerror(db, sr, &sd, raw);
0500
2010-09-25
pbug
if (sr1->callback)
0501
2010-09-25
pbug
sr1->callback->hascallback--;
0502
2010-09-25
pbug
goto remove;
0503
2010-09-25
pbug
}
0504
2010-09-25
pbug
0505
2010-09-19
pbug
continue;
0506
2010-09-17
pbug
} else {
0507
2010-09-17
pbug
/* we've found the record we're looking
0508
2010-09-17
pbug
* for do something with it..
0509
2010-09-17
pbug
*/
0510
2010-09-17
pbug
0511
2010-09-18
pbug
if (sr1->isfake) {
0512
2010-09-18
pbug
/* do another netlookup with the callback */
0513
2013-02-16
pjp
dolog(LOG_DEBUG, "sr is fake, doing netlookup on the callback");
0514
2010-09-18
pbug
0515
2010-09-18
pbug
if (netlookup(db, sr1->callback) < 0) {
0516
2013-02-16
pjp
dolog(LOG_DEBUG, "callback netlookup failed");
0517
2010-09-18
pbug
}
0518
2010-09-18
pbug
0519
2010-09-19
pbug
sr1->callback->hascallback--;
0520
2010-09-19
pbug
/* XXX continue; */
0521
2010-09-19
pbug
0522
2010-09-19
pbug
0523
2010-09-19
pbug
} else {
0524
2010-09-26
pbug
if (type == DNS_TYPE_CNAME)
0525
2010-09-26
pbug
reply_raw_cname(db, sr, &sd, raw);
0526
2010-09-26
pbug
else
0527
2010-09-26
pbug
reply_raw(db, sr1, &sd, raw);
0528
2010-09-19
pbug
}
0529
2010-09-17
pbug
}
0530
2010-09-15
pbug
remove:
0531
2010-09-19
pbug
/* only remove if we don't have any callbacks
0532
2010-09-19
pbug
* outstanding...
0533
2010-09-19
pbug
*/
0534
2010-09-19
pbug
if (! sr1->hascallback) {
0535
2014-05-01
pjp
SLIST_REMOVE(&recurseshead, sr1, recurses, recurses_entry);
0536
2010-09-19
pbug
free_question(sr1->question);
0537
2010-09-19
pbug
free(sr1);
0538
2010-09-19
pbug
}
0539
2010-09-15
pbug
0540
2010-09-15
pbug
} /* FD_ISSET(sr1->so */
0541
2010-09-15
pbug
} /* SLIST_FOREACH(sr... */
0542
2010-09-15
pbug
0543
2010-09-15
pbug
#if 0
0544
2010-05-26
pbug
/*
0545
2010-05-26
pbug
I drew this on a notepad one night, I think that's supposed to how
0546
2010-05-26
pbug
it shoudl go...
0547
2010-05-26
pbug
0548
2010-05-26
pbug
+----------------+ +--------------------------+
0549
2010-05-26
pbug
| | | |
0550
2010-05-26
pbug
| v v |
0551
2010-05-26
pbug
| -------------------- select ------------------- |
0552
2010-05-26
pbug
| || || |
0553
2010-05-26
pbug
| || || |
0554
2010-05-26
pbug
| +----+ +----+ |
0555
2010-05-26
pbug
| | | take request | | parse reply |
0556
2010-05-26
pbug
| +----+ from authoritative +----+ and insert |
0557
2010-05-26
pbug
| || side / new record |
0558
2010-05-26
pbug
| || / |
0559
2010-05-26
pbug
| || / |
0560
2010-05-26
pbug
| || +---------------+ |
0561
2010-05-26
pbug
| || / |
0562
2010-05-26
pbug
| || / bad or expired |
0563
2010-05-26
pbug
| +----+=====================>+----+ lookup record |
0564
2010-05-26
pbug
| | | lookup name in db | | on the net |
0565
2010-05-26
pbug
| +----+ +----+-------------------+
0566
2010-05-26
pbug
| ||
0567
2010-05-26
pbug
| || good
0568
2010-05-26
pbug
| ||
0569
2010-05-26
pbug
| +----+
0570
2010-05-26
pbug
| | | reply
0571
2010-05-26
pbug
| +----+
0572
2010-05-26
pbug
| ||
0573
2010-05-26
pbug
| ||
0574
2010-05-26
pbug
| ||
0575
2010-05-26
pbug
| +----+
0576
2010-05-26
pbug
+--------| | cleanup
0577
2010-05-26
pbug
+----+
0578
2010-05-26
pbug
0579
2010-05-26
pbug
*/
0580
2010-05-26
pbug
0581
2010-05-26
pbug
#endif
0582
2010-05-26
pbug
0583
2010-05-26
pbug
0584
2010-09-15
pbug
} /* for(;;) */
0585
2010-09-15
pbug
0586
2010-09-15
pbug
/* NOTREACHED */
0587
2010-09-15
pbug
}
0588
2010-09-15
pbug
0589
2010-09-15
pbug
/*
0590
2010-09-15
pbug
* LOOKUP_NS - given an address try to look up the nameservers anywhere along
0591
2010-09-15
pbug
* its path. return number of servers reachable or -1 on error.
0592
2010-09-15
pbug
*/
0593
2010-09-15
pbug
0594
2010-09-15
pbug
int
0595
2010-09-15
pbug
lookup_ns(DB *db, struct recurses *sr)
0596
2010-09-15
pbug
{
0597
2010-09-15
pbug
int ret, plen, i;
0598
2010-09-15
pbug
int onemore = 0;
0599
2010-09-15
pbug
char *p;
0600
2010-09-15
pbug
0601
2010-09-15
pbug
DBT key, data;
0602
2010-09-15
pbug
0603
2010-09-15
pbug
struct domain *sd, mydomain;
0604
2010-09-15
pbug
0605
2010-09-15
pbug
p = sr->question->hdr->name;
0606
2010-09-15
pbug
plen = sr->question->hdr->namelen;
0607
2010-09-15
pbug
0608
2010-09-15
pbug
do {
0609
2010-09-15
pbug
again:
0610
2010-09-15
pbug
memset(&key, 0, sizeof(key));
0611
2010-09-15
pbug
memset(&data, 0, sizeof(data));
0612
2010-09-15
pbug
0613
2010-09-15
pbug
key.data = (char *)p;
0614
2010-09-15
pbug
key.size = plen;
0615
2010-09-15
pbug
0616
2010-09-15
pbug
data.data = NULL;
0617
2010-09-15
pbug
data.size = 0;
0618
2010-09-15
pbug
0619
2010-09-15
pbug
ret = db->get(db, NULL, &key, &data, 0);
0620
2010-09-15
pbug
if (ret != 0) {
0621
2010-09-15
pbug
if (*p != 0) {
0622
2010-09-15
pbug
plen -= (*p + 1);
0623
2010-09-15
pbug
p = (p + (*p + 1));
0624
2010-09-15
pbug
sr->indicator++;
0625
2010-09-15
pbug
}
0626
2010-09-15
pbug
0627
2010-09-15
pbug
/* XXX this is different from lookup_zone(), not
0628
2010-09-15
pbug
* sure how it even works there...
0629
2010-09-15
pbug
*/
0630
2010-09-15
pbug
if (*p == 0 && ! onemore) {
0631
2010-09-15
pbug
plen = 1;
0632
2010-09-15
pbug
onemore = 1;
0633
2010-09-15
pbug
sr->indicator++;
0634
2010-09-15
pbug
goto again; /* XXX */
0635
2010-09-15
pbug
}
0636
2010-09-15
pbug
} else {
0637
2010-09-15
pbug
/* we have a lookup */
0638
2010-09-15
pbug
0639
2010-09-15
pbug
if (data.size != sizeof(struct domain)) {
0640
2013-02-16
pjp
dolog(LOG_ERR, "btree db is damaged");
0641
2010-09-15
pbug
return (-1);
0642
2010-09-15
pbug
}
0643
2010-09-15
pbug
0644
2010-09-15
pbug
#if 0
0645
2013-02-16
pjp
dolog(LOG_DEBUG, "we gots a lookup, yay!\n");
0646
2010-09-15
pbug
#endif
0647
2010-09-15
pbug
0648
2010-09-28
pbug
/*
0649
2010-09-28
pbug
* record which record we used
0650
2010-09-28
pbug
*/
0651
2010-09-15
pbug
0652
2011-04-19
pbug
sr->lookrecord = (u_char *)p;
0653
2010-09-28
pbug
0654
2010-09-15
pbug
memcpy((char *)&mydomain, (char *)data.data, sizeof(struct domain));
0655
2010-09-15
pbug
sd = (struct domain *)&mydomain;
0656
2010-09-15
pbug
0657
2010-09-15
pbug
/*
0658
2010-09-15
pbug
* If we're not a static zone (like hints) and we're
0659
2010-09-15
pbug
* expired then we go on to the next indicator..
0660
2010-09-21
pbug
* .. but first we must remove this zone...
0661
2010-09-15
pbug
*/
0662
2010-09-15
pbug
if ((! (sd->flags & DOMAIN_STATIC_ZONE)) &&
0663
2010-09-15
pbug
(time(NULL) > (sd->created + sd->ttl))) {
0664
2010-09-21
pbug
0665
2010-09-21
pbug
remove_zone(db, sd);
0666
2010-09-15
pbug
0667
2010-09-15
pbug
if (*p != 0) {
0668
2010-09-15
pbug
plen -= (*p + 1);
0669
2010-09-15
pbug
p = (p + (*p + 1));
0670
2010-09-15
pbug
sr->indicator++;
0671
2010-09-15
pbug
continue;
0672
2010-09-15
pbug
} else {
0673
2010-09-15
pbug
return (-1);
0674
2010-09-15
pbug
}
0675
2010-09-15
pbug
}
0676
2010-09-15
pbug
/*
0677
2010-09-15
pbug
* If we have a negative cache, then just return with
0678
2010-09-15
pbug
* error.
0679
2010-09-15
pbug
*/
0680
2010-09-15
pbug
if ((sd->flags & DOMAIN_NEGATIVE_CACHE) &&
0681
2010-09-15
pbug
(time(NULL) <= (sd->created + sd->ttl))) {
0682
2010-09-15
pbug
return (-1);
0683
2010-09-15
pbug
}
0684
2010-09-15
pbug
0685
2010-09-30
pbug
sr->aaaa_count = 0;
0686
2010-09-15
pbug
sr->a_count = 0;
0687
2010-09-15
pbug
sr->a_ptr = 0;
0688
2010-09-15
pbug
0689
2010-09-15
pbug
for (i = 0; i < sd->ns_count; i++) {
0690
2010-09-30
pbug
if (sr->af == AF_INET6) {
0691
2011-09-19
pbug
if (lookup_aaaa(db, sr, &sd->ns[(sd->ns_ptr + i) % sd->ns_count] ) < 0)
0692
2010-09-30
pbug
continue;
0693
2010-09-30
pbug
sr->aaaa_count++;
0694
2010-09-30
pbug
} else {
0695
2011-09-19
pbug
if (lookup_a(db, sr, &sd->ns[(sd->ns_ptr + i) % sd->ns_count] ) < 0)
0696
2010-09-30
pbug
continue;
0697
2010-09-30
pbug
sr->a_count++;
0698
2010-09-30
pbug
}
0699
2010-09-15
pbug
}
0700
2010-09-15
pbug
0701
2010-09-21
pbug
if (sd->ns_count)
0702
2010-09-21
pbug
sd->ns_ptr = (sd->ns_ptr + 1) % sd->ns_count;
0703
2010-09-21
pbug
else
0704
2010-09-21
pbug
sd->ns_ptr = 0;
0705
2010-09-21
pbug
0706
2010-09-15
pbug
update_db(db, sd);
0707
2010-09-15
pbug
0708
2010-09-15
pbug
break;
0709
2010-09-15
pbug
}
0710
2010-09-15
pbug
0711
2010-09-15
pbug
} while (*p != 0 && ret != 0);
0712
2010-09-15
pbug
0713
2010-09-17
pbug
#if 1
0714
2013-02-16
pjp
dolog(LOG_DEBUG, "got %d addresses for %s, indicator %d\n", sr->a_count, sr->question->hdr->name, sr->indicator);
0715
2010-09-15
pbug
0716
2010-09-15
pbug
#endif
0717
2010-09-15
pbug
0718
2010-09-30
pbug
return ((sr->af == AF_INET6) ? sr->aaaa_count : sr->a_count);
0719
2010-09-15
pbug
}
0720
2010-09-15
pbug
0721
2010-09-15
pbug
0722
2010-09-15
pbug
/*
0723
2010-09-15
pbug
* LOOKUP_A - given a path, lookup the A record in that record
0724
2010-09-15
pbug
*
0725
2010-09-15
pbug
*/
0726
2010-09-15
pbug
0727
2010-09-15
pbug
int
0728
2010-09-15
pbug
lookup_a(DB *db, struct recurses *sr, struct ns *ns)
0729
2010-09-15
pbug
{
0730
2010-09-15
pbug
int ret, plen;
0731
2010-09-15
pbug
char *p;
0732
2010-09-15
pbug
0733
2010-09-15
pbug
DBT key, data;
0734
2010-09-15
pbug
0735
2010-09-19
pbug
struct domain *sd, sdomain;
0736
2010-09-18
pbug
int found = 0;
0737
2010-09-15
pbug
0738
2010-09-15
pbug
p = ns->nsserver;
0739
2010-09-15
pbug
plen = ns->nslen;
0740
2010-09-15
pbug
0741
2010-09-15
pbug
memset(&key, 0, sizeof(key));
0742
2010-09-15
pbug
memset(&data, 0, sizeof(data));
0743
2010-09-15
pbug
0744
2010-09-15
pbug
key.data = (char *)p;
0745
2010-09-15
pbug
key.size = plen;
0746
2010-09-15
pbug
0747
2010-09-15
pbug
data.data = NULL;
0748
2010-09-15
pbug
data.size = 0;
0749
2010-09-15
pbug
0750
2010-09-18
pbug
found = 0;
0751
2010-09-15
pbug
0752
2010-09-18
pbug
ret = db->get(db, NULL, &key, &data, 0);
0753
2010-09-15
pbug
if (ret == 0) {
0754
2010-09-15
pbug
if (data.size != sizeof(struct domain)) {
0755
2013-02-16
pjp
dolog(LOG_ERR, "btree db is damaged");
0756
2010-09-15
pbug
return (-1);
0757
2010-09-15
pbug
}
0758
2010-09-15
pbug
0759
2010-09-19
pbug
memcpy((char*)&sdomain, data.data, sizeof(struct domain));
0760
2010-09-19
pbug
sd = &sdomain;
0761
2010-09-16
pbug
0762
2010-09-18
pbug
if ((sd->flags & DOMAIN_HAVE_A) == DOMAIN_HAVE_A) {
0763
2010-09-18
pbug
memcpy((char *)&sr->a[sr->a_count], (char *)&sd->a[0], sizeof(in_addr_t));
0764
2010-09-19
pbug
sd->a_count++;
0765
2010-09-18
pbug
found = 1;
0766
2010-09-19
pbug
0767
2010-09-18
pbug
}
0768
2010-09-18
pbug
}
0769
2010-09-18
pbug
0770
2010-09-18
pbug
if (! found) {
0771
2013-02-16
pjp
dolog(LOG_DEBUG, "calling fakerecurse");
0772
2010-09-28
pbug
fakerecurse(db, sr, ns, DNS_TYPE_A);
0773
2010-09-16
pbug
return (-1);
0774
2010-09-18
pbug
}
0775
2010-09-16
pbug
0776
2010-09-16
pbug
return (0);
0777
2010-09-16
pbug
}
0778
2010-09-16
pbug
0779
2010-09-16
pbug
/*
0780
2010-09-16
pbug
* NEGATIVE_CACHE - cache a lookup as negative (NXDOMAIN)
0781
2010-09-16
pbug
*
0782
2010-09-16
pbug
*/
0783
2010-09-16
pbug
0784
2010-09-16
pbug
int
0785
2010-09-16
pbug
negative_cache(DB *db, struct recurses *sr)
0786
2010-09-16
pbug
{
0787
2010-09-16
pbug
struct domain sd;
0788
2010-09-16
pbug
0789
2010-09-16
pbug
memset(&sd, 0, sizeof(sd));
0790
2010-09-16
pbug
0791
2010-09-16
pbug
sd.zonelen = sr->question->hdr->namelen;
0792
2010-09-16
pbug
0793
2011-09-19
pbug
memcpy((char *)&sd.zone, (char *)sr->question->hdr->name, sd.zonelen);
0794
2010-09-16
pbug
0795
2010-09-16
pbug
#if __linux__
0796
2011-09-19
pbug
strncpy((char *)&sd.zonename, (char *)sr->question->converted_name, DNS_MAXNAME);
0797
2010-09-16
pbug
sd.zonename[DNS_MAXNAME] = 0;
0798
2010-09-16
pbug
#else
0799
2011-09-19
pbug
strlcpy((char *)&sd.zonename, (char *)sr->question->converted_name, DNS_MAXNAME + 1);
0800
2010-09-16
pbug
#endif
0801
2010-09-16
pbug
0802
2010-09-16
pbug
sd.created = time(NULL);
0803
2010-09-16
pbug
sd.ttl = NEGATIVE_CACHE_TIME; /* 10 minutes */
0804
2010-09-16
pbug
0805
2010-09-16
pbug
sd.flags |= DOMAIN_NEGATIVE_CACHE;
0806
2010-09-16
pbug
0807
2010-09-16
pbug
update_db(db, &sd);
0808
2010-09-16
pbug
0809
2010-09-16
pbug
return (0);
0810
2010-09-16
pbug
}
0811
2010-09-16
pbug
0812
2010-09-16
pbug
/*
0813
2010-09-16
pbug
* RECURSE_PARSE - based on compress_label.
0814
2010-09-16
pbug
*
0815
2010-09-16
pbug
*/
0816
2010-09-16
pbug
0817
2010-09-16
pbug
int
0818
2010-09-16
pbug
recurse_parse(DB *db, struct recurses *sr, u_char *buf, u_int16_t offset)
0819
2010-09-16
pbug
{
0820
2010-09-16
pbug
u_char *label[256]; /* should be enough */
0821
2010-09-19
pbug
static u_char converted_name[256][256];
0822
2010-09-17
pbug
u_int8_t cn_len[256];
0823
2010-09-16
pbug
u_char *end = &buf[offset];
0824
2010-09-17
pbug
int update;
0825
2010-09-25
pbug
int rrcount[3]; /* RR count answer, authoritative, additional */
0826
2010-09-25
pbug
int pointer = 0; /* default answer */
0827
2010-09-26
pbug
int txtlen;
0828
2010-09-17
pbug
0829
2010-09-17
pbug
char abuf[INET6_ADDRSTRLEN];
0830
2010-09-17
pbug
0831
2010-09-17
pbug
DBT key, data;
0832
2010-09-17
pbug
0833
2010-09-17
pbug
struct domain sdomain;
0834
2010-09-25
pbug
struct dns_header *dh;
0835
2010-09-16
pbug
struct question {
0836
2010-09-16
pbug
u_int16_t type;
0837
2010-09-16
pbug
u_int16_t class;
0838
2010-09-16
pbug
} __attribute__((packed));
0839
2010-09-16
pbug
struct answer {
0840
2010-09-16
pbug
u_int16_t type;
0841
2010-09-16
pbug
u_int16_t class;
0842
2010-09-16
pbug
u_int32_t ttl;
0843
2010-09-16
pbug
u_int16_t rdlength;
0844
2010-09-16
pbug
} __attribute__((packed));
0845
2010-09-23
pbug
struct mysoa {
0846
2010-09-16
pbug
u_int32_t serial;
0847
2010-09-16
pbug
u_int32_t refresh;
0848
2010-09-16
pbug
u_int32_t retry;
0849
2010-09-16
pbug
u_int32_t expire;
0850
2010-09-16
pbug
u_int32_t minttl;
0851
2010-09-16
pbug
} __attribute__((packed));
0852
2010-09-16
pbug
0853
2010-09-16
pbug
struct answer *a;
0854
2010-09-23
pbug
struct mysoa *mysoa;
0855
2010-09-23
pbug
struct soa *soa;
0856
2010-09-28
pbug
struct ns ns;
0857
2010-09-16
pbug
0858
2010-09-16
pbug
u_int i, j, k;
0859
2010-09-16
pbug
u_int16_t *compressor;
0860
2010-09-16
pbug
u_int16_t c;
0861
2010-09-26
pbug
u_int16_t *preference;
0862
2010-09-16
pbug
0863
2010-09-16
pbug
int found = 0;
0864
2010-09-16
pbug
0865
2010-09-16
pbug
u_char *p, *q, *r;
0866
2010-09-16
pbug
0867
2010-09-25
pbug
dh = (struct dns_header*)&buf[0];
0868
2010-09-25
pbug
rrcount[pointer++] = ntohs(dh->answer);
0869
2010-09-25
pbug
rrcount[pointer++] = ntohs(dh->nsrr);
0870
2010-09-25
pbug
rrcount[pointer++] = ntohs(dh->additional);
0871
2010-09-25
pbug
0872
2010-09-25
pbug
pointer = 0;
0873
2010-09-25
pbug
while (rrcount[pointer] == 0) {
0874
2010-09-25
pbug
pointer++;
0875
2010-09-25
pbug
if (pointer > 2)
0876
2010-09-25
pbug
return (-1);
0877
2010-09-25
pbug
}
0878
2010-09-25
pbug
0879
2010-09-16
pbug
p = &buf[sizeof(struct dns_header)];
0880
2010-09-16
pbug
label[0] = p;
0881
2010-09-16
pbug
0882
2010-09-16
pbug
while (p <= end && *p) {
0883
2010-09-16
pbug
p += *p;
0884
2010-09-16
pbug
p++;
0885
2010-09-16
pbug
}
0886
2010-09-15
pbug
0887
2010-09-16
pbug
/*
0888
2010-09-16
pbug
* the question label was bogus, we'll just get out of there, return 0
0889
2010-09-16
pbug
*/
0890
2010-09-16
pbug
0891
2010-09-16
pbug
if (p > end)
0892
2010-09-16
pbug
return (-1);
0893
2010-09-16
pbug
0894
2010-09-16
pbug
p += sizeof(struct question);
0895
2010-09-16
pbug
p++; /* one more */
0896
2010-09-16
pbug
/* start of answer/additional/authoritative */
0897
2010-09-16
pbug
0898
2010-09-16
pbug
for (i = 1; i < 100; i++) {
0899
2010-09-16
pbug
label[i] = p;
0900
2010-09-16
pbug
0901
2010-09-16
pbug
while (p <= end && *p) {
0902
2010-09-16
pbug
if ((*p & 0xc0) == 0xc0) {
0903
2010-09-16
pbug
p++;
0904
2010-09-16
pbug
break;
0905
2010-09-16
pbug
}
0906
2010-09-16
pbug
p += *p;
0907
2010-09-16
pbug
p++;
0908
2010-09-16
pbug
0909
2010-09-16
pbug
if (p > end)
0910
2010-09-16
pbug
goto end;
0911
2010-09-16
pbug
}
0912
2010-09-16
pbug
0913
2010-09-16
pbug
p++; /* one more */
0914
2010-09-16
pbug
0915
2010-09-16
pbug
0916
2010-09-16
pbug
a = (struct answer *)p;
0917
2010-09-16
pbug
p += sizeof(struct answer);
0918
2010-09-16
pbug
0919
2011-02-28
pbug
if (p > end)
0920
2011-02-28
pbug
goto end;
0921
2011-02-28
pbug
0922
2010-09-16
pbug
switch (ntohs(a->type)) {
0923
2010-09-16
pbug
case DNS_TYPE_A:
0924
2010-09-16
pbug
p += sizeof(in_addr_t);
0925
2010-09-16
pbug
break;
0926
2010-09-16
pbug
case DNS_TYPE_AAAA:
0927
2010-09-16
pbug
p += 16; /* sizeof 4 * 32 bit */
0928
2010-09-16
pbug
break;
0929
2010-09-16
pbug
case DNS_TYPE_TXT:
0930
2010-09-16
pbug
p += *p;
0931
2010-09-16
pbug
p++;
0932
2010-09-16
pbug
break;
0933
2010-09-16
pbug
case DNS_TYPE_MX:
0934
2010-09-16
pbug
p += sizeof(u_int16_t); /* mx_priority */
0935
2010-09-16
pbug
/* FALLTHROUGH */
0936
2010-09-16
pbug
case DNS_TYPE_NS:
0937
2010-09-16
pbug
case DNS_TYPE_PTR:
0938
2010-09-16
pbug
case DNS_TYPE_CNAME:
0939
2010-09-16
pbug
label[++i] = p;
0940
2010-09-16
pbug
while (p <= end && *p) {
0941
2010-09-16
pbug
if ((*p & 0xc0) == 0xc0) {
0942
2010-09-16
pbug
p++;
0943
2010-09-16
pbug
break;
0944
2010-09-16
pbug
}
0945
2010-09-16
pbug
p += *p;
0946
2010-09-16
pbug
p++;
0947
2010-09-16
pbug
0948
2010-09-16
pbug
if (p > end)
0949
2010-09-16
pbug
goto end;
0950
2010-09-16
pbug
}
0951
2010-09-16
pbug
0952
2010-09-16
pbug
p++; /* one more */
0953
2010-09-16
pbug
break;
0954
2010-09-16
pbug
case DNS_TYPE_SOA:
0955
2010-09-16
pbug
/* nsserver */
0956
2010-09-16
pbug
label[++i] = p;
0957
2010-09-16
pbug
while (p <= end && *p) {
0958
2010-09-16
pbug
if ((*p & 0xc0) == 0xc0) {
0959
2010-09-16
pbug
p++;
0960
2010-09-16
pbug
break;
0961
2010-09-16
pbug
}
0962
2010-09-16
pbug
p += *p;
0963
2010-09-16
pbug
p++;
0964
2010-09-16
pbug
if (p > end)
0965
2010-09-16
pbug
goto end;
0966
2010-09-16
pbug
}
0967
2010-09-16
pbug
0968
2010-09-16
pbug
p++; /* one more */
0969
2010-09-16
pbug
0970
2010-09-16
pbug
if (p > end)
0971
2010-09-16
pbug
goto end;
0972
2010-09-16
pbug
0973
2010-09-16
pbug
/* responsible person */
0974
2010-09-16
pbug
label[++i] = p;
0975
2010-09-16
pbug
while (p <= end && *p) {
0976
2010-09-16
pbug
if ((*p & 0xc0) == 0xc0) {
0977
2010-09-16
pbug
p++;
0978
2010-09-16
pbug
break;
0979
2010-09-16
pbug
}
0980
2010-09-16
pbug
p += *p;
0981
2010-09-16
pbug
p++;
0982
2010-09-16
pbug
}
0983
2010-09-16
pbug
0984
2010-09-16
pbug
p++; /* one more */
0985
2010-09-16
pbug
0986
2010-09-16
pbug
if (p > end)
0987
2010-09-16
pbug
goto end;
0988
2010-09-16
pbug
0989
2010-09-23
pbug
p += sizeof(struct mysoa); /* advance struct soa */
0990
2010-09-16
pbug
0991
2010-09-16
pbug
break;
0992
2010-09-16
pbug
default:
0993
2010-09-16
pbug
break;
0994
2010-09-16
pbug
/* XXX */
0995
2010-09-16
pbug
} /* switch */
0996
2010-09-16
pbug
0997
2010-09-16
pbug
if (p >= end)
0998
2010-09-16
pbug
break;
0999
2010-09-16
pbug
} /* for (i *) */
1000
2010-09-16
pbug
1001
2010-09-16
pbug
/*
1002
2010-09-16
pbug
* go through our list of labels and expand them from possible
1003
2010-09-16
pbug
* compression, then we make our next pass..
1004
2010-09-16
pbug
*/
1005
2010-09-16
pbug
1006
2010-09-16
pbug
for (j = 0; j <= i; j++) {
1007
2010-09-16
pbug
q = converted_name[j];
1008
2010-09-16
pbug
p = label[j];
1009
2010-09-16
pbug
again:
1010
2010-09-16
pbug
for (; *p ; p += *p, p++) {
1011
2010-09-16
pbug
if ((*p & 0xc0) == 0xc0)
1012
2010-09-16
pbug
break;
1013
2010-09-16
pbug
1014
2010-09-16
pbug
r = (p + 1);
1015
2010-09-16
pbug
1016
2010-09-16
pbug
*q++ = *p;
1017
2010-09-16
pbug
1018
2010-09-16
pbug
for (k = 0; k < *p; k++)
1019
2010-09-16
pbug
*q++ = tolower(r[k]);
1020
2010-09-16
pbug
}
1021
2010-09-16
pbug
1022
2010-09-16
pbug
if ((*p & 0xc0) == 0xc0) {
1023
2010-09-16
pbug
compressor = (u_int16_t *)p;
1024
2010-09-16
pbug
c = (ntohs(*compressor) & ~(0xc000));
1025
2010-09-16
pbug
for (k = 0; k <= i; k++) {
1026
2010-09-16
pbug
found = 0;
1027
2010-09-16
pbug
for (r = label[k]; *r; r += *r, r++) {
1028
2010-09-16
pbug
if (r - buf == c) {
1029
2010-09-16
pbug
p = r;
1030
2010-09-16
pbug
found = 1;
1031
2010-09-16
pbug
}
1032
2010-09-16
pbug
1033
2010-09-16
pbug
1034
2010-09-16
pbug
/*
1035
2010-09-16
pbug
* we're searching for an offset in
1036
2010-09-16
pbug
* non-compressed form, but we
1037
2010-09-16
pbug
* encountered compression, so we
1038
2010-09-16
pbug
* break and go to the next label
1039
2010-09-16
pbug
*/
1040
2010-09-16
pbug
1041
2010-09-16
pbug
if ((*r & 0xc0) == 0xc0) {
1042
2010-09-16
pbug
break;
1043
2010-09-16
pbug
}
1044
2010-09-16
pbug
}
1045
2010-09-16
pbug
1046
2010-09-16
pbug
if (found) {
1047
2010-09-16
pbug
/*
1048
2010-09-16
pbug
* pretend we found a match but we
1049
2010-09-16
pbug
* have compression inside pointing
1050
2010-09-16
pbug
* down, then break this, it's corrupt
1051
2010-09-16
pbug
* it's a possible loop attempt
1052
2010-09-16
pbug
*/
1053
2010-09-16
pbug
if ((*r & 0xc0) == 0xc0) {
1054
2010-09-16
pbug
compressor = (u_int16_t *)r;
1055
2010-09-16
pbug
if ((ntohs(*compressor) & ~0xc000) >= c)
1056
2010-09-16
pbug
break;
1057
2010-09-16
pbug
}
1058
2010-09-16
pbug
1059
2010-09-16
pbug
goto again;
1060
2010-09-16
pbug
}
1061
2010-09-16
pbug
}
1062
2010-09-16
pbug
1063
2010-09-16
pbug
/*
1064
2010-09-16
pbug
* if we fall through the for loop, we didn't find the
1065
2010-09-16
pbug
* recursive label... corrupt.
1066
2010-09-16
pbug
*/
1067
2010-09-16
pbug
1068
2013-02-16
pjp
dolog(LOG_ERR, "corrupt compression");
1069
2010-09-16
pbug
return (-1);
1070
2010-09-16
pbug
}
1071
2010-09-16
pbug
1072
2010-09-16
pbug
*q++ = '\0'; /* don't forget this */
1073
2010-09-17
pbug
cn_len[j] = (q - converted_name[j]);
1074
2010-09-16
pbug
1075
2010-09-16
pbug
} /* for (j .. */
1076
2010-09-16
pbug
1077
2010-09-17
pbug
#if 0
1078
2010-09-16
pbug
for (j = 0; j <= i; j++) {
1079
2013-02-16
pjp
dolog(LOG_DEBUG, "%s with length %u", converted_name[j], cn_len[j]);
1080
2010-09-16
pbug
}
1081
2010-09-17
pbug
#endif
1082
2010-09-16
pbug
1083
2010-09-17
pbug
p = &buf[sizeof(struct dns_header)];
1084
2010-09-17
pbug
label[0] = p;
1085
2010-09-17
pbug
1086
2010-09-17
pbug
while (p <= end && *p) {
1087
2010-09-17
pbug
p += *p;
1088
2010-09-17
pbug
p++;
1089
2010-09-17
pbug
}
1090
2010-09-17
pbug
1091
2010-09-17
pbug
/*
1092
2010-09-17
pbug
* the question label was bogus, we'll just get out of there, return 0
1093
2010-09-17
pbug
*/
1094
2010-09-17
pbug
1095
2010-09-17
pbug
if (p > end)
1096
2010-09-17
pbug
return (-1);
1097
2010-09-17
pbug
1098
2010-09-17
pbug
p += sizeof(struct question);
1099
2010-09-17
pbug
p++; /* one more */
1100
2010-09-17
pbug
/* start of answer/additional/authoritative */
1101
2010-09-17
pbug
1102
2010-09-17
pbug
for (i = 1; i < 100; i++) {
1103
2010-09-17
pbug
label[i] = p;
1104
2010-09-17
pbug
1105
2010-09-17
pbug
while (p <= end && *p) {
1106
2010-09-17
pbug
if ((*p & 0xc0) == 0xc0) {
1107
2010-09-17
pbug
p++;
1108
2010-09-17
pbug
break;
1109
2010-09-17
pbug
}
1110
2010-09-17
pbug
p += *p;
1111
2010-09-17
pbug
p++;
1112
2010-09-17
pbug
1113
2010-09-17
pbug
if (p > end)
1114
2010-09-17
pbug
goto end;
1115
2010-09-17
pbug
}
1116
2010-09-17
pbug
1117
2010-09-17
pbug
p++; /* one more */
1118
2010-09-17
pbug
1119
2010-09-17
pbug
1120
2010-09-17
pbug
a = (struct answer *)p;
1121
2010-09-17
pbug
p += sizeof(struct answer);
1122
2010-09-17
pbug
1123
2010-09-17
pbug
/* load our record */
1124
2010-09-17
pbug
memset(&key, 0, sizeof(key));
1125
2010-09-17
pbug
memset(&data, 0, sizeof(data));
1126
2010-09-17
pbug
1127
2010-09-17
pbug
key.data = (char *)converted_name[i];
1128
2010-09-17
pbug
key.size = cn_len[i];
1129
2010-09-17
pbug
1130
2010-09-17
pbug
data.data = NULL;
1131
2010-09-17
pbug
data.size = 0;
1132
2010-09-17
pbug
1133
2010-09-17
pbug
memset((char *)&sdomain, 0, sizeof(struct domain));
1134
2010-09-17
pbug
if (db->get(db, NULL, &key, &data, 0) == 0) {
1135
2010-09-17
pbug
if (data.size != sizeof(struct domain)) {
1136
2013-02-16
pjp
dolog(LOG_INFO, "damaged btree database");
1137
2010-09-17
pbug
return -1;
1138
2010-09-17
pbug
}
1139
2010-09-17
pbug
1140
2010-09-17
pbug
memcpy((char *)&sdomain, (char *)data.data, data.size);
1141
2010-09-17
pbug
1142
2010-09-17
pbug
}
1143
2010-09-17
pbug
1144
2010-09-17
pbug
1145
2010-09-17
pbug
if (sdomain.zone == NULL) {
1146
2011-09-19
pbug
memcpy(&sdomain.zone, converted_name[i], cn_len[i]);
1147
2010-09-17
pbug
sdomain.zonelen = cn_len[i];
1148
2010-09-17
pbug
}
1149
2010-09-17
pbug
1150
2010-09-17
pbug
1151
2010-09-17
pbug
switch (ntohs(a->type)) {
1152
2010-09-17
pbug
case DNS_TYPE_A:
1153
2010-09-17
pbug
/*
1154
2010-09-17
pbug
* scan addresses in this struct domain and check if
1155
2010-09-17
pbug
* this one exists already...
1156
2010-09-17
pbug
*/
1157
2010-09-17
pbug
1158
2010-09-17
pbug
update = 1;
1159
2010-09-17
pbug
for (j = 0; j < sdomain.a_count; j++) {
1160
2010-09-17
pbug
if (memcmp(&sdomain.a[j], p, sizeof(in_addr_t)) == 0) {
1161
2010-09-19
pbug
#if 0
1162
2013-02-16
pjp
dolog(LOG_INFO, "record exists already");
1163
2010-09-19
pbug
#endif
1164
2010-09-17
pbug
update = 0;
1165
2010-09-17
pbug
}
1166
2010-09-17
pbug
}
1167
2010-09-17
pbug
1168
2010-09-17
pbug
if (j >= RECORD_COUNT) {
1169
2013-02-16
pjp
dolog(LOG_INFO, "db can't hold any more records\n");
1170
2010-09-17
pbug
update = 0;
1171
2010-09-17
pbug
}
1172
2010-09-28
pbug
1173
2010-09-28
pbug
/*
1174
2010-09-28
pbug
* check if we're a 2nd level domain or higher and
1175
2010-09-28
pbug
* if we were directly querying the zone...
1176
2010-09-28
pbug
*/
1177
2010-09-17
pbug
1178
2010-09-17
pbug
if (update) {
1179
2010-09-28
pbug
if (level(sr->lookrecord) > 1) {
1180
2010-09-28
pbug
if (!contains(sr->lookrecord, converted_name[i])) {
1181
2010-09-28
pbug
memcpy(ns.nsserver, converted_name[i], cn_len[i]);
1182
2010-09-28
pbug
ns.nslen = cn_len[i];
1183
2010-09-28
pbug
1184
2010-09-28
pbug
fakerecurse(db, sr, &ns, DNS_TYPE_A);
1185
2010-09-28
pbug
update = 0;
1186
2010-09-28
pbug
}
1187
2010-09-28
pbug
}
1188
2010-09-28
pbug
}
1189
2010-09-28
pbug
1190
2010-09-28
pbug
1191
2010-09-28
pbug
if (update) {
1192
2010-09-17
pbug
memcpy(&sdomain.a[j], p, sizeof(in_addr_t));
1193
2010-09-17
pbug
sdomain.a_count++;
1194
2010-09-19
pbug
sdomain.region[j] = 0xff;
1195
2010-09-17
pbug
sdomain.a_ptr = 0;
1196
2010-09-17
pbug
sdomain.flags |= DOMAIN_HAVE_A;
1197
2010-09-17
pbug
sdomain.flags &= ~(DOMAIN_NEGATIVE_CACHE);
1198
2010-09-17
pbug
sdomain.created = time(NULL);
1199
2010-09-17
pbug
sdomain.ttl = ntohl(a->ttl);
1200
2010-09-17
pbug
1201
2010-09-17
pbug
if (! (sdomain.flags & DOMAIN_STATIC_ZONE)) {
1202
2010-09-17
pbug
update_db(db, &sdomain);
1203
2010-09-17
pbug
inet_ntop(AF_INET, p, abuf, sizeof(abuf));
1204
2013-02-16
pjp
dolog(LOG_DEBUG, "updateing zone %s with address %s ttl= %u, lookrecord = %s", converted_name[i], abuf, sdomain.ttl, sr->lookrecord);
1205
2010-09-17
pbug
}
1206
2010-10-03
pbug
}
1207
2010-09-17
pbug
1208
2010-09-17
pbug
p += sizeof(in_addr_t);
1209
2010-09-25
pbug
if (pointer > 2) {
1210
2013-02-16
pjp
dolog(LOG_ERR, "there is more records than indicated in the header!!!");
1211
2010-09-25
pbug
return (-1);
1212
2010-09-25
pbug
}
1213
2010-09-25
pbug
rrcount[pointer]--;
1214
2010-09-25
pbug
if (rrcount[pointer] == 0)
1215
2010-09-25
pbug
pointer++;
1216
2010-09-25
pbug
1217
2010-09-25
pbug
break;
1218
2010-09-25
pbug
case DNS_TYPE_AAAA:
1219
2010-09-25
pbug
/*
1220
2010-09-25
pbug
* scan addresses in this struct domain and check if
1221
2010-09-25
pbug
* this one exists already...
1222
2010-09-25
pbug
*/
1223
2010-09-25
pbug
1224
2010-09-25
pbug
update = 1;
1225
2010-09-25
pbug
for (j = 0; j < sdomain.aaaa_count; j++) {
1226
2011-09-19
pbug
if (memcmp(&sdomain.aaaa[j], p, sizeof(struct in6_addr)) == 0) {
1227
2010-09-25
pbug
#if 0
1228
2013-02-16
pjp
dolog(LOG_INFO, "record exists already");
1229
2010-09-25
pbug
#endif
1230
2010-09-25
pbug
update = 0;
1231
2010-09-25
pbug
}
1232
2010-09-25
pbug
}
1233
2010-09-25
pbug
1234
2010-09-25
pbug
if (j >= RECORD_COUNT) {
1235
2013-02-16
pjp
dolog(LOG_INFO, "db can't hold any more records\n");
1236
2010-09-25
pbug
update = 0;
1237
2010-09-25
pbug
}
1238
2010-09-25
pbug
1239
2010-09-28
pbug
/*
1240
2010-09-28
pbug
* check if we're a 2nd level domain or higher and
1241
2010-09-28
pbug
* if we were directly querying the zone...
1242
2010-09-28
pbug
*/
1243
2010-09-28
pbug
1244
2010-09-25
pbug
if (update) {
1245
2010-09-28
pbug
if (level(sr->lookrecord) > 1) {
1246
2010-09-28
pbug
if (!contains(sr->lookrecord, converted_name[i])) {
1247
2010-09-28
pbug
memcpy(ns.nsserver, converted_name[i], cn_len[i]);
1248
2010-09-28
pbug
ns.nslen = cn_len[i];
1249
2010-09-28
pbug
1250
2010-09-28
pbug
fakerecurse(db, sr, &ns, DNS_TYPE_AAAA);
1251
2010-09-28
pbug
update = 0;
1252
2010-09-28
pbug
}
1253
2010-09-28
pbug
}
1254
2010-09-28
pbug
}
1255
2010-09-28
pbug
1256
2010-09-28
pbug
if (update) {
1257
2011-09-19
pbug
memcpy(&sdomain.aaaa[j], p, sizeof(struct in6_addr));
1258
2010-09-25
pbug
sdomain.aaaa_count++;
1259
2010-09-25
pbug
sdomain.aaaa_ptr = 0;
1260
2010-09-25
pbug
sdomain.flags |= DOMAIN_HAVE_AAAA;
1261
2010-09-25
pbug
sdomain.flags &= ~(DOMAIN_NEGATIVE_CACHE);
1262
2010-09-25
pbug
sdomain.created = time(NULL);
1263
2010-09-25
pbug
sdomain.ttl = ntohl(a->ttl);
1264
2010-09-25
pbug
1265
2010-09-25
pbug
if (! (sdomain.flags & DOMAIN_STATIC_ZONE)) {
1266
2010-09-25
pbug
update_db(db, &sdomain);
1267
2010-09-25
pbug
inet_ntop(AF_INET6, p, abuf, sizeof(abuf));
1268
2013-02-16
pjp
dolog(LOG_DEBUG, "updateing zone %s with address %s ttl= %u\n", converted_name[i], abuf, sdomain.ttl);
1269
2010-09-25
pbug
}
1270
2010-10-03
pbug
}
1271
2010-09-25
pbug
1272
2010-09-25
pbug
if (pointer > 2) {
1273
2013-02-16
pjp
dolog(LOG_ERR, "there is more records than indicated in the header!!!");
1274
2010-09-25
pbug
return (-1);
1275
2010-09-25
pbug
}
1276
2010-09-25
pbug
rrcount[pointer]--;
1277
2010-09-25
pbug
if (rrcount[pointer] == 0)
1278
2010-09-25
pbug
pointer++;
1279
2010-09-25
pbug
1280
2010-09-17
pbug
p += 16; /* sizeof 4 * 32 bit */
1281
2010-09-17
pbug
break;
1282
2010-09-17
pbug
case DNS_TYPE_TXT:
1283
2010-09-26
pbug
txtlen = (*p);
1284
2011-09-19
pbug
1285
2011-09-19
pbug
memcpy(&sdomain.txt, (p + 1), txtlen);
1286
2010-09-26
pbug
sdomain.txtlen = txtlen;
1287
2010-09-26
pbug
1288
2010-09-26
pbug
sdomain.flags |= DOMAIN_HAVE_TXT;
1289
2010-09-26
pbug
sdomain.flags &= ~(DOMAIN_NEGATIVE_CACHE);
1290
2010-09-26
pbug
sdomain.created = time(NULL);
1291
2010-09-26
pbug
sdomain.ttl = ntohl(a->ttl);
1292
2010-09-26
pbug
1293
2010-09-26
pbug
if (! (sdomain.flags & DOMAIN_STATIC_ZONE)) {
1294
2010-09-26
pbug
update_db(db, &sdomain);
1295
2010-09-26
pbug
}
1296
2010-09-26
pbug
1297
2010-09-26
pbug
if (pointer > 2) {
1298
2013-02-16
pjp
dolog(LOG_ERR, "there is more records than indicated in the header!!!");
1299
2010-09-26
pbug
return (-1);
1300
2010-09-26
pbug
}
1301
2010-09-26
pbug
1302
2010-09-26
pbug
rrcount[pointer]--;
1303
2010-09-26
pbug
if (rrcount[pointer] == 0)
1304
2010-09-26
pbug
pointer++;
1305
2010-09-26
pbug
1306
2010-09-26
pbug
1307
2010-09-17
pbug
p += *p;
1308
2010-09-17
pbug
p++;
1309
2010-09-17
pbug
break;
1310
2010-09-17
pbug
case DNS_TYPE_MX:
1311
2010-09-26
pbug
preference = (u_int16_t *)p;
1312
2010-09-17
pbug
p += sizeof(u_int16_t); /* mx_priority */
1313
2010-09-17
pbug
/* FALLTHROUGH */
1314
2010-09-17
pbug
case DNS_TYPE_NS:
1315
2010-09-17
pbug
case DNS_TYPE_PTR:
1316
2010-09-17
pbug
case DNS_TYPE_CNAME:
1317
2010-09-17
pbug
label[++i] = p;
1318
2010-09-17
pbug
while (p <= end && *p) {
1319
2010-09-17
pbug
if ((*p & 0xc0) == 0xc0) {
1320
2010-09-17
pbug
p++;
1321
2010-09-17
pbug
break;
1322
2010-09-17
pbug
}
1323
2010-09-17
pbug
p += *p;
1324
2010-09-17
pbug
p++;
1325
2010-09-17
pbug
1326
2010-09-17
pbug
if (p > end)
1327
2010-09-17
pbug
goto end;
1328
2010-09-17
pbug
}
1329
2010-09-17
pbug
1330
2010-09-26
pbug
if (ntohs(a->type) == DNS_TYPE_CNAME) {
1331
2010-09-28
pbug
/*
1332
2010-09-28
pbug
* we check this as well as the A and AAAA
1333
2010-09-28
pbug
* types since it may be possible to glue
1334
2010-09-28
pbug
* a CNAME instead of an A and thus poison
1335
2010-09-28
pbug
* our cache...
1336
2010-09-28
pbug
*/
1337
2010-09-28
pbug
if (level(sr->lookrecord) > 1) {
1338
2010-09-28
pbug
if (!contains(sr->lookrecord, converted_name[i - 1])) {
1339
2010-09-28
pbug
1340
2010-09-28
pbug
memcpy(ns.nsserver, converted_name[i - 1], cn_len[i - 1]);
1341
2010-09-28
pbug
ns.nslen = cn_len[i];
1342
2010-09-28
pbug
1343
2010-09-28
pbug
fakerecurse(db, sr, &ns, DNS_TYPE_A);
1344
2010-09-28
pbug
rrcount[pointer]--;
1345
2010-09-28
pbug
if (rrcount[pointer] == 0)
1346
2010-09-28
pbug
pointer++;
1347
2010-09-28
pbug
p++;
1348
2010-09-28
pbug
break;
1349
2010-09-28
pbug
}
1350
2010-09-28
pbug
}
1351
2010-09-26
pbug
1352
2011-09-19
pbug
memcpy(&sdomain.cname, converted_name[i], cn_len[i]);
1353
2010-09-26
pbug
sdomain.cnamelen = cn_len[i];
1354
2010-09-26
pbug
1355
2010-09-26
pbug
sdomain.flags |= DOMAIN_HAVE_CNAME;
1356
2010-09-26
pbug
sdomain.flags &= ~(DOMAIN_NEGATIVE_CACHE);
1357
2010-09-26
pbug
sdomain.created = time(NULL);
1358
2010-09-26
pbug
sdomain.ttl = ntohl(a->ttl);
1359
2010-09-26
pbug
1360
2010-09-26
pbug
if (! (sdomain.flags & DOMAIN_STATIC_ZONE)) {
1361
2010-09-26
pbug
update_db(db, &sdomain);
1362
2010-09-26
pbug
#if 1
1363
2013-02-16
pjp
dolog(LOG_DEBUG, "updateing zone %s with PTR name %s ttl= %u\n", converted_name[i - 1], converted_name[i], sdomain.ttl);
1364
2010-09-26
pbug
#endif
1365
2010-09-26
pbug
}
1366
2010-09-26
pbug
1367
2010-09-26
pbug
if (pointer > 2) {
1368
2013-02-16
pjp
dolog(LOG_ERR, "there is more records than indicated in the header!!!");
1369
2010-09-26
pbug
return (-1);
1370
2010-09-26
pbug
}
1371
2010-09-26
pbug
1372
2010-09-26
pbug
rrcount[pointer]--;
1373
2010-09-26
pbug
if (rrcount[pointer] == 0)
1374
2010-09-26
pbug
pointer++;
1375
2010-09-26
pbug
} else if (ntohs(a->type) == DNS_TYPE_PTR) {
1376
2011-09-19
pbug
memcpy(&sdomain.ptr, converted_name[i], cn_len[i]);
1377
2010-09-26
pbug
sdomain.ptrlen = cn_len[i];
1378
2010-09-26
pbug
1379
2010-09-26
pbug
sdomain.flags |= DOMAIN_HAVE_PTR;
1380
2010-09-26
pbug
sdomain.flags &= ~(DOMAIN_NEGATIVE_CACHE);
1381
2010-09-26
pbug
sdomain.created = time(NULL);
1382
2010-09-26
pbug
sdomain.ttl = ntohl(a->ttl);
1383
2010-09-26
pbug
1384
2010-09-26
pbug
if (! (sdomain.flags & DOMAIN_STATIC_ZONE)) {
1385
2010-09-26
pbug
update_db(db, &sdomain);
1386
2010-09-26
pbug
#if 1
1387
2013-02-16
pjp
dolog(LOG_DEBUG, "updateing zone %s with PTR name %s ttl= %u\n", converted_name[i - 1], converted_name[i], sdomain.ttl);
1388
2010-09-26
pbug
#endif
1389
2010-09-26
pbug
}
1390
2010-09-26
pbug
1391
2010-09-26
pbug
if (pointer > 2) {
1392
2013-02-16
pjp
dolog(LOG_ERR, "there is more records than indicated in the header!!!");
1393
2010-09-26
pbug
return (-1);
1394
2010-09-26
pbug
}
1395
2010-09-26
pbug
1396
2010-09-26
pbug
rrcount[pointer]--;
1397
2010-09-26
pbug
if (rrcount[pointer] == 0)
1398
2010-09-26
pbug
pointer++;
1399
2010-09-26
pbug
} else if (ntohs(a->type) == DNS_TYPE_NS) {
1400
2010-09-17
pbug
update = 1;
1401
2010-09-17
pbug
for (j = 0; j < sdomain.ns_count; j++) {
1402
2011-09-19
pbug
if (memcasecmp((u_char *)sdomain.ns[j].nsserver, (u_char *)converted_name[i], MIN(cn_len[i], sdomain.ns[j].nslen)) == 0) {
1403
2010-09-17
pbug
#if 0
1404
2013-02-16
pjp
dolog(LOG_INFO, "record exists already");
1405
2010-09-17
pbug
#endif
1406
2010-09-17
pbug
update = 0;
1407
2010-09-17
pbug
}
1408
2010-09-17
pbug
}
1409
2010-09-17
pbug
1410
2010-09-17
pbug
if (j >= RECORD_COUNT) {
1411
2013-02-16
pjp
dolog(LOG_INFO, "db can't hold any more records\n");
1412
2010-09-17
pbug
update = 0;
1413
2010-09-17
pbug
}
1414
2010-09-17
pbug
1415
2010-09-17
pbug
if (update) {
1416
2011-09-19
pbug
memcpy(sdomain.ns[j].nsserver, converted_name[i], cn_len[i]);
1417
2011-09-19
pbug
sdomain.ns[j].nslen = cn_len[i];
1418
2010-09-17
pbug
1419
2010-09-17
pbug
sdomain.ns_count++;
1420
2010-09-17
pbug
sdomain.ns_ptr = 0;
1421
2010-09-17
pbug
sdomain.flags |= DOMAIN_HAVE_NS;
1422
2010-09-17
pbug
sdomain.flags &= ~(DOMAIN_NEGATIVE_CACHE);
1423
2010-09-17
pbug
sdomain.created = time(NULL);
1424
2010-09-17
pbug
sdomain.ttl = ntohl(a->ttl);
1425
2010-09-17
pbug
1426
2010-09-17
pbug
if (! (sdomain.flags & DOMAIN_STATIC_ZONE)) {
1427
2010-09-17
pbug
update_db(db, &sdomain);
1428
2010-09-17
pbug
#if 0
1429
2013-02-16
pjp
dolog(LOG_DEBUG, "updateing zone %s with NS name %s ttl= %u\n", converted_name[i - 1], converted_name[i], sdomain.ttl);
1430
2010-09-17
pbug
#endif
1431
2010-09-17
pbug
}
1432
2010-09-17
pbug
} /* if update */
1433
2010-09-25
pbug
if (pointer > 2) {
1434
2013-02-16
pjp
dolog(LOG_ERR, "there is more records than indicated in the header!!!");
1435
2010-09-25
pbug
return (-1);
1436
2010-09-25
pbug
}
1437
2010-09-17
pbug
1438
2010-09-25
pbug
rrcount[pointer]--;
1439
2010-09-25
pbug
if (pointer == 1) /* authoritative */
1440
2010-09-25
pbug
sr->authoritative = DNS_TYPE_NS;
1441
2010-09-25
pbug
if (rrcount[pointer] == 0)
1442
2010-09-25
pbug
pointer++;
1443
2010-09-25
pbug
1444
2010-09-26
pbug
} else if (ntohs(a->type) == DNS_TYPE_MX) {
1445
2010-09-26
pbug
update = 1;
1446
2010-09-26
pbug
for (j = 0; j < sdomain.mx_count; j++) {
1447
2011-09-19
pbug
if (memcasecmp((u_char *)sdomain.mx[j].exchange, (u_char *)converted_name[i], MIN(cn_len[i], sdomain.mx[j].exchangelen)) == 0) {
1448
2010-09-26
pbug
update = 0;
1449
2010-09-26
pbug
}
1450
2010-09-26
pbug
}
1451
2010-09-26
pbug
1452
2010-09-26
pbug
if (j >= RECORD_COUNT) {
1453
2013-02-16
pjp
dolog(LOG_INFO, "db can't hold any more records\n");
1454
2010-09-26
pbug
update = 0;
1455
2010-09-26
pbug
}
1456
2010-09-26
pbug
1457
2010-09-26
pbug
if (update) {
1458
2011-09-19
pbug
memcpy(&sdomain.mx[j].exchange, converted_name[i], cn_len[i]);
1459
2011-09-19
pbug
sdomain.mx[j].exchangelen = cn_len[i];
1460
2011-09-19
pbug
sdomain.mx[j].preference = ntohs(*preference);
1461
2010-09-26
pbug
1462
2010-09-26
pbug
sdomain.mx_count++;
1463
2010-09-26
pbug
sdomain.mx_ptr = 0;
1464
2010-09-26
pbug
sdomain.flags |= DOMAIN_HAVE_MX;
1465
2010-09-26
pbug
sdomain.flags &= ~(DOMAIN_NEGATIVE_CACHE);
1466
2010-09-26
pbug
sdomain.created = time(NULL);
1467
2010-09-26
pbug
sdomain.ttl = ntohl(a->ttl);
1468
2010-09-26
pbug
1469
2010-09-26
pbug
if (! (sdomain.flags & DOMAIN_STATIC_ZONE)) {
1470
2010-09-26
pbug
update_db(db, &sdomain);
1471
2010-09-26
pbug
#if 0
1472
2013-02-16
pjp
dolog(LOG_DEBUG, "updateing zone %s with MX name %s ttl= %u\n", converted_name[i - 1], converted_name[i], sdomain.ttl);
1473
2010-09-26
pbug
#endif
1474
2010-09-26
pbug
}
1475
2010-09-26
pbug
} /* if update */
1476
2010-09-26
pbug
if (pointer > 2) {
1477
2013-02-16
pjp
dolog(LOG_ERR, "there is more records than indicated in the header!!!");
1478
2010-09-26
pbug
return (-1);
1479
2010-09-26
pbug
}
1480
2010-09-26
pbug
1481
2010-09-26
pbug
rrcount[pointer]--;
1482
2010-09-26
pbug
#if 0
1483
2010-09-26
pbug
if (pointer == 1) /* authoritative */
1484
2010-09-26
pbug
sr->authoritative = DNS_TYPE_MX;
1485
2010-09-26
pbug
#endif
1486
2010-09-26
pbug
if (rrcount[pointer] == 0)
1487
2010-09-26
pbug
pointer++;
1488
2010-09-26
pbug
1489
2010-09-17
pbug
} /* if type ns */
1490
2010-09-17
pbug
1491
2010-09-17
pbug
p++; /* one more */
1492
2010-09-17
pbug
break;
1493
2010-09-17
pbug
case DNS_TYPE_SOA:
1494
2010-09-17
pbug
/* nsserver */
1495
2010-09-17
pbug
label[++i] = p;
1496
2010-09-17
pbug
while (p <= end && *p) {
1497
2010-09-17
pbug
if ((*p & 0xc0) == 0xc0) {
1498
2010-09-17
pbug
p++;
1499
2010-09-17
pbug
break;
1500
2010-09-17
pbug
}
1501
2010-09-17
pbug
p += *p;
1502
2010-09-17
pbug
p++;
1503
2010-09-17
pbug
if (p > end)
1504
2010-09-17
pbug
goto end;
1505
2010-09-17
pbug
}
1506
2010-09-17
pbug
1507
2010-09-17
pbug
p++; /* one more */
1508
2010-09-17
pbug
1509
2010-09-17
pbug
if (p > end)
1510
2010-09-17
pbug
goto end;
1511
2010-09-17
pbug
1512
2010-09-17
pbug
/* responsible person */
1513
2010-09-17
pbug
label[++i] = p;
1514
2010-09-17
pbug
while (p <= end && *p) {
1515
2010-09-17
pbug
if ((*p & 0xc0) == 0xc0) {
1516
2010-09-17
pbug
p++;
1517
2010-09-17
pbug
break;
1518
2010-09-17
pbug
}
1519
2010-09-17
pbug
p += *p;
1520
2010-09-17
pbug
p++;
1521
2010-09-17
pbug
}
1522
2010-09-17
pbug
1523
2010-09-17
pbug
p++; /* one more */
1524
2010-09-17
pbug
1525
2010-09-17
pbug
if (p > end)
1526
2010-09-17
pbug
goto end;
1527
2010-09-17
pbug
1528
2010-09-23
pbug
mysoa = (struct mysoa *)p;
1529
2010-09-23
pbug
p += sizeof(struct mysoa); /* advance struct soa */
1530
2010-09-17
pbug
1531
2010-09-23
pbug
/* malloc struct soa */
1532
2010-09-23
pbug
1533
2010-09-23
pbug
soa = malloc(sizeof(struct soa));
1534
2010-09-23
pbug
if (soa == NULL) {
1535
2013-02-16
pjp
dolog(LOG_ERR, "malloc: %m");
1536
2010-09-23
pbug
return (-1);
1537
2010-09-23
pbug
}
1538
2010-09-23
pbug
1539
2010-09-23
pbug
memcpy(soa->nsserver, converted_name[i - 1], cn_len[i - 1]);
1540
2010-09-23
pbug
soa->nsserver_len = cn_len[i - 1];
1541
2010-09-23
pbug
memcpy(soa->responsible_person, converted_name[i], cn_len[i]);
1542
2010-09-23
pbug
soa->rp_len = cn_len[i];
1543
2010-09-25
pbug
soa->serial = ntohl(mysoa->serial);
1544
2010-09-25
pbug
soa->refresh = ntohl(mysoa->refresh);
1545
2010-09-25
pbug
soa->retry = ntohl(mysoa->retry);
1546
2010-09-25
pbug
soa->expire = ntohl(mysoa->expire);
1547
2010-09-25
pbug
soa->minttl = ntohl(mysoa->minttl);
1548
2010-09-23
pbug
1549
2011-09-19
pbug
memcpy(&sdomain.soa, soa, sizeof(sdomain.soa));
1550
2011-09-19
pbug
free(soa);
1551
2011-09-19
pbug
1552
2010-09-23
pbug
sdomain.flags |= DOMAIN_HAVE_SOA;
1553
2010-09-23
pbug
sdomain.created = time(NULL);
1554
2010-09-25
pbug
sdomain.ttl = htonl(a->ttl);
1555
2010-09-23
pbug
1556
2010-09-23
pbug
if (! (sdomain.flags & DOMAIN_STATIC_ZONE)) {
1557
2010-09-23
pbug
update_db(db, &sdomain);
1558
2010-09-23
pbug
}
1559
2010-09-23
pbug
1560
2010-09-25
pbug
if (pointer > 2) {
1561
2013-02-16
pjp
dolog(LOG_ERR, "there is more records than indicated in the header!!!");
1562
2010-09-25
pbug
return (-1);
1563
2010-09-25
pbug
}
1564
2010-09-25
pbug
1565
2010-09-25
pbug
rrcount[pointer]--;
1566
2010-09-25
pbug
if (pointer == 1) /* authoritative */
1567
2010-09-25
pbug
sr->authoritative = DNS_TYPE_SOA;
1568
2010-09-25
pbug
if (rrcount[pointer] == 0)
1569
2010-09-25
pbug
pointer++;
1570
2010-09-25
pbug
1571
2010-09-25
pbug
1572
2010-09-17
pbug
break;
1573
2010-09-17
pbug
default:
1574
2010-09-17
pbug
break;
1575
2010-09-17
pbug
/* XXX */
1576
2010-09-17
pbug
} /* switch */
1577
2010-09-17
pbug
1578
2010-09-17
pbug
if (p >= end)
1579
2010-09-17
pbug
break;
1580
2010-09-17
pbug
} /* for (i *) */
1581
2010-09-17
pbug
1582
2010-09-17
pbug
1583
2010-09-15
pbug
return (0);
1584
2010-09-16
pbug
1585
2010-09-16
pbug
end:
1586
2013-02-16
pjp
dolog(LOG_DEBUG, "mangled input packet");
1587
2010-09-16
pbug
return (-1);
1588
2010-09-16
pbug
1589
2010-09-17
pbug
}
1590
2010-09-17
pbug
1591
2010-09-17
pbug
1592
2010-09-17
pbug
/*
1593
2010-09-17
pbug
* NETLOOKUP - do a internet lookup of the requested internet record
1594
2010-09-17
pbug
*
1595
2010-09-17
pbug
*/
1596
2010-09-17
pbug
1597
2010-09-17
pbug
int
1598
2010-09-17
pbug
netlookup(DB *db, struct recurses *sr)
1599
2010-09-17
pbug
{
1600
2010-09-17
pbug
struct sockaddr_in sin;
1601
2010-09-17
pbug
struct dns_header *dh;
1602
2010-09-17
pbug
1603
2010-09-17
pbug
char buf[2048];
1604
2010-09-26
pbug
int flag;
1605
2010-09-17
pbug
1606
2010-09-17
pbug
1607
2010-09-17
pbug
/* do the network stuff then */
1608
2010-09-17
pbug
/* XXX should be IPv6 ready */
1609
2010-09-30
pbug
1610
2010-09-30
pbug
if (sr->af == AF_INET6)
1611
2010-09-30
pbug
return (netlookup6(db, sr));
1612
2010-09-30
pbug
1613
2010-09-26
pbug
if (sr->so != -1) {
1614
2010-09-26
pbug
if (close(sr->so) < 0)
1615
2013-02-16
pjp
dolog(LOG_ERR, "close: %m");
1616
2010-09-26
pbug
}
1617
2010-09-26
pbug
1618
2010-09-17
pbug
sr->so = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
1619
2010-09-17
pbug
if (sr->so < 0) {
1620
2013-02-16
pjp
dolog(LOG_ERR, "socket: %m");
1621
2010-09-19
pbug
sr->so = -1;
1622
2010-09-17
pbug
return (-1);
1623
2010-09-17
pbug
}
1624
2010-09-17
pbug
1625
2014-09-27
pjp
sr->port = arc4random() & 0xffff;
1626
2010-09-17
pbug
/*
1627
2010-09-17
pbug
* we have to avoid picking servers already
1628
2010-09-17
pbug
* running ..
1629
2010-09-17
pbug
*/
1630
2010-09-17
pbug
if (sr->port < 1024)
1631
2010-09-17
pbug
sr->port += 1024;
1632
2010-09-17
pbug
1633
2014-09-27
pjp
sr->id = arc4random() & 0xffff;
1634
2010-09-17
pbug
1635
2010-09-17
pbug
memset(&sin, 0, sizeof(sin));
1636
2010-09-17
pbug
sin.sin_family = AF_INET;
1637
2010-09-17
pbug
sin.sin_port = htons(sr->port);
1638
2010-09-17
pbug
sin.sin_addr.s_addr = INADDR_ANY;
1639
2010-09-17
pbug
1640
2010-09-17
pbug
if (bind(sr->so, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
1641
2013-02-16
pjp
dolog(LOG_ERR, "bind: %m");
1642
2010-09-26
pbug
if (close(sr->so) < 0) {
1643
2013-02-16
pjp
dolog(LOG_ERR, "close: %m");
1644
2010-09-26
pbug
}
1645
2010-09-19
pbug
sr->so = -1;
1646
2010-09-17
pbug
return (-1);
1647
2010-09-17
pbug
}
1648
2010-09-17
pbug
1649
2010-09-26
pbug
/*
1650
2010-09-26
pbug
* make this socket nonblocking
1651
2010-09-26
pbug
*/
1652
2010-09-26
pbug
1653
2010-09-26
pbug
if ((flag = fcntl(sr->so, F_GETFL)) < 0) {
1654
2013-02-16
pjp
dolog(LOG_INFO, "fcntl 3: %m");
1655
2010-09-26
pbug
}
1656
2010-09-26
pbug
flag |= O_NONBLOCK;
1657
2010-09-26
pbug
if (fcntl(sr->so, F_SETFL, flag) < 0) {
1658
2013-02-16
pjp
dolog(LOG_INFO, "fcntl 4: %m");
1659
2010-09-26
pbug
}
1660
2010-09-26
pbug
1661
2010-09-17
pbug
if (lookup_ns(db, sr) <= 0) {
1662
2013-02-16
pjp
dolog(LOG_ERR, "can't establish any servers to reach for zone \"%s\"", sr->question->converted_name);
1663
2010-09-26
pbug
if (close(sr->so) < 0) {
1664
2013-02-16
pjp
dolog(LOG_ERR, "close: %m");
1665
2010-09-26
pbug
}
1666
2010-09-19
pbug
sr->so = -1;
1667
2010-09-17
pbug
return (-1);
1668
2010-09-17
pbug
}
1669
2010-09-17
pbug
1670
2010-09-17
pbug
memset(&sin, 0, sizeof(sin));
1671
2010-09-17
pbug
sin.sin_family = AF_INET;
1672
2010-09-17
pbug
sin.sin_port = htons(53);
1673
2010-09-17
pbug
1674
2010-09-17
pbug
sin.sin_addr.s_addr = sr->a[0];
1675
2010-09-17
pbug
1676
2010-09-17
pbug
/* XXX we use buf here in order to preserve
1677
2010-09-17
pbug
* the state of query...
1678
2010-09-17
pbug
*/
1679
2010-09-17
pbug
memcpy(buf, sr->query, sr->len);
1680
2010-09-17
pbug
dh = (struct dns_header *)&buf[0];
1681
2010-09-17
pbug
NTOHS(dh->query);
1682
2010-09-17
pbug
UNSET_DNS_RECURSION(dh);
1683
2010-09-17
pbug
HTONS(dh->query);
1684
2010-09-17
pbug
dh->id = htons(sr->id);
1685
2010-09-17
pbug
1686
2010-09-17
pbug
#if 1
1687
2013-02-16
pjp
dolog(LOG_INFO, "sending request with id %u\n", sr->id);
1688
2010-09-17
pbug
1689
2010-09-17
pbug
#endif
1690
2010-09-17
pbug
1691
2010-09-17
pbug
if (sendto(sr->so, buf, sr->len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
1692
2013-02-16
pjp
dolog(LOG_ERR, "sendto: %m");
1693
2010-09-26
pbug
if (close(sr->so) < 0) {
1694
2013-02-16
pjp
dolog(LOG_ERR, "close: %m");
1695
2010-09-26
pbug
}
1696
2010-09-19
pbug
sr->so = -1;
1697
2010-09-17
pbug
return (-1);
1698
2010-09-17
pbug
}
1699
2010-09-17
pbug
1700
2010-09-17
pbug
sr->sent_last_query = time(NULL);
1701
2010-09-25
pbug
sr->packetcount++;
1702
2010-09-17
pbug
1703
2010-09-17
pbug
1704
2010-09-18
pbug
return (0);
1705
2010-09-18
pbug
}
1706
2010-09-18
pbug
1707
2010-09-18
pbug
/*
1708
2010-09-18
pbug
* FAKERECURSE - create a fake query of type A, for a nameserver that has
1709
2010-09-18
pbug
* no glued A record, attach a callback to the struct recurses
1710
2010-09-18
pbug
* that did the initiation for this...
1711
2010-09-18
pbug
*/
1712
2010-09-18
pbug
1713
2010-09-18
pbug
int
1714
2010-09-28
pbug
fakerecurse(DB *db, struct recurses *sr, struct ns *ns, int type)
1715
2010-09-18
pbug
{
1716
2010-09-18
pbug
struct recurses *fakesr;
1717
2010-09-18
pbug
struct dns_header *dh;
1718
2010-09-18
pbug
1719
2010-09-18
pbug
char *p;
1720
2010-09-19
pbug
1721
2010-09-18
pbug
int len;
1722
2010-09-19
pbug
u_int16_t *qtype, *qclass;
1723
2010-09-18
pbug
1724
2010-09-21
pbug
/* check if we have already started a fakerecurse on the same name */
1725
2010-09-19
pbug
1726
2014-05-01
pjp
SLIST_FOREACH(sr2, &recurseshead, recurses_entry) {
1727
2010-09-28
pbug
if (memcasecmp((u_char *)ns->nsserver, (u_char *)sr2->question->hdr->name, MIN(ns->nslen, sr2->question->hdr->namelen)) == 0) {
1728
2013-02-16
pjp
dolog(LOG_INFO, "already have a fakerecurse structure with name %s, drop\n", ns->nsserver);
1729
2010-09-21
pbug
return (-1);
1730
2010-09-21
pbug
}
1731
2010-09-21
pbug
}
1732
2010-09-21
pbug
1733
2010-09-21
pbug
1734
2010-09-18
pbug
/* place request on struct recurses linked list */
1735
2010-09-18
pbug
1736
2010-09-18
pbug
fakesr = calloc(sizeof(struct recurses), 1);
1737
2010-09-18
pbug
if (fakesr == NULL) {
1738
2013-02-16
pjp
dolog(LOG_ERR, "calloc: %m");
1739
2010-09-18
pbug
return (-1);
1740
2010-09-18
pbug
}
1741
2010-09-18
pbug
1742
2010-09-18
pbug
1743
2010-09-18
pbug
fakesr->af = sr->af;
1744
2010-09-18
pbug
fakesr->proto = sr->proto;
1745
2010-09-18
pbug
fakesr->so = -1;
1746
2010-09-18
pbug
fakesr->callback = sr;
1747
2010-09-19
pbug
sr->hascallback++;
1748
2010-09-19
pbug
fakesr->hascallback = 0;
1749
2010-09-18
pbug
fakesr->isfake = 1;
1750
2010-09-21
pbug
fakesr->launched = 0;
1751
2010-09-18
pbug
fakesr->received = time(NULL);
1752
2010-09-25
pbug
fakesr->packetcount = 0;
1753
2010-09-28
pbug
fakesr->lookrecord = NULL;
1754
2010-09-18
pbug
1755
2010-09-28
pbug
fakesr->question = build_fake_question(ns->nsserver, ns->nslen, htons(type));
1756
2010-09-18
pbug
if (fakesr->question == NULL) {
1757
2013-02-16
pjp
dolog(LOG_ERR, "malformed question in recurse.c");
1758
2010-09-18
pbug
free(fakesr);
1759
2010-09-18
pbug
return (-1);
1760
2010-09-18
pbug
}
1761
2010-09-18
pbug
1762
2010-09-18
pbug
/* construct the question packet */
1763
2010-09-18
pbug
1764
2010-09-18
pbug
len = sizeof(struct dns_header);
1765
2010-09-18
pbug
dh = (struct dns_header *)fakesr->query;
1766
2010-09-18
pbug
dh->id = htons(1);
1767
2010-09-18
pbug
SET_DNS_QUERY(dh);
1768
2010-09-18
pbug
HTONS(dh->query);
1769
2010-09-18
pbug
dh->question = htons(1);
1770
2010-09-18
pbug
dh->answer = 0;
1771
2010-09-18
pbug
dh->nsrr = 0;
1772
2010-09-18
pbug
dh->additional = 0;
1773
2010-09-18
pbug
1774
2010-09-18
pbug
p = (char *)&fakesr->query[len];
1775
2010-09-18
pbug
memcpy(p, ns->nsserver, ns->nslen);
1776
2010-09-18
pbug
len += ns->nslen;
1777
2010-09-19
pbug
qtype = (u_int16_t *)&fakesr->query[len];
1778
2010-09-19
pbug
*qtype = fakesr->question->hdr->qtype;
1779
2010-09-18
pbug
len += sizeof(u_int16_t);
1780
2010-09-19
pbug
qclass = (u_int16_t *)&fakesr->query[len];
1781
2010-09-19
pbug
*qclass = fakesr->question->hdr->qclass;
1782
2010-09-18
pbug
len += sizeof(u_int16_t);
1783
2010-09-18
pbug
1784
2010-09-18
pbug
fakesr->len = len;
1785
2010-09-18
pbug
1786
2014-05-01
pjp
SLIST_INSERT_HEAD(&recurseshead, fakesr, recurses_entry);
1787
2010-09-19
pbug
1788
2010-09-19
pbug
return (0);
1789
2010-09-19
pbug
}
1790
2010-09-19
pbug
1791
2010-09-23
pbug
/*
1792
2010-09-23
pbug
* REPLY_RAW -
1793
2010-09-23
pbug
*
1794
2010-09-23
pbug
*
1795
2010-09-23
pbug
*/
1796
2010-09-23
pbug
1797
2010-09-19
pbug
void
1798
2010-09-19
pbug
reply_raw(DB *db, struct recurses *sr, struct domain *sd, int *raw)
1799
2010-09-19
pbug
{
1800
2010-09-19
pbug
int so;
1801
2010-09-19
pbug
struct sreply sreply;
1802
2010-09-19
pbug
1803
2013-02-16
pjp
dolog(LOG_DEBUG, "reply_raw called");
1804
2010-09-19
pbug
1805
2010-09-19
pbug
switch (sr->af) {
1806
2010-09-19
pbug
case AF_INET:
1807
2010-09-19
pbug
so = raw[0];
1808
2010-09-19
pbug
break;
1809
2010-09-19
pbug
case AF_INET6:
1810
2010-09-19
pbug
so = raw[1];
1811
2010-09-19
pbug
break;
1812
2010-09-19
pbug
default:
1813
2013-02-16
pjp
dolog(LOG_ERR, "reply_raw(): unknown address family in struct recurses");
1814
2010-09-19
pbug
return;
1815
2010-09-19
pbug
}
1816
2010-09-19
pbug
1817
2010-09-21
pbug
switch (sr->proto) {
1818
2010-09-21
pbug
case IPPROTO_UDP:
1819
2010-09-21
pbug
break;
1820
2010-09-21
pbug
default:
1821
2013-02-16
pjp
dolog(LOG_ERR, "reply_raw(): can't do any protocol other than udp right now");
1822
2010-09-21
pbug
return;
1823
2010-09-21
pbug
}
1824
2010-09-21
pbug
1825
2010-09-19
pbug
build_reply(&sreply, so, sr->query, sr->len, sr->question, NULL, 0, sd, NULL, 0xff, 0, 0, sr);
1826
2010-09-19
pbug
1827
2010-09-19
pbug
switch (ntohs(sr->question->hdr->qtype)) {
1828
2010-09-19
pbug
case DNS_TYPE_A:
1829
2010-09-19
pbug
reply_a(&sreply, db);
1830
2010-09-19
pbug
break;
1831
2010-09-25
pbug
case DNS_TYPE_AAAA:
1832
2010-09-25
pbug
reply_aaaa(&sreply, db);
1833
2010-09-25
pbug
break;
1834
2010-09-25
pbug
case DNS_TYPE_NS:
1835
2010-09-25
pbug
reply_ns(&sreply, db);
1836
2010-09-25
pbug
break;
1837
2010-09-26
pbug
case DNS_TYPE_PTR:
1838
2010-09-26
pbug
reply_ptr(&sreply);
1839
2010-09-26
pbug
break;
1840
2010-09-26
pbug
case DNS_TYPE_MX:
1841
2010-09-26
pbug
reply_mx(&sreply, db);
1842
2010-09-26
pbug
break;
1843
2010-09-26
pbug
case DNS_TYPE_SOA:
1844
2010-09-26
pbug
reply_soa(&sreply);
1845
2010-09-26
pbug
break;
1846
2010-09-26
pbug
case DNS_TYPE_CNAME:
1847
2010-09-26
pbug
reply_cname(&sreply);
1848
2010-09-26
pbug
break;
1849
2010-09-26
pbug
case DNS_TYPE_TXT:
1850
2010-09-26
pbug
reply_txt(&sreply);
1851
2010-09-26
pbug
break;
1852
2010-09-19
pbug
default:
1853
2013-02-16
pjp
dolog(LOG_ERR, "other types have not been implemented yet");
1854
2010-09-19
pbug
break;
1855
2010-09-19
pbug
}
1856
2010-09-19
pbug
1857
2010-09-19
pbug
return;
1858
2010-09-21
pbug
}
1859
2010-09-21
pbug
1860
2010-09-26
pbug
void
1861
2010-09-26
pbug
reply_raw_cname(DB *db, struct recurses *sr, struct domain *sd, int *raw)
1862
2010-09-26
pbug
{
1863
2010-09-26
pbug
int so;
1864
2010-09-26
pbug
struct sreply sreply;
1865
2010-09-26
pbug
1866
2013-02-16
pjp
dolog(LOG_DEBUG, "reply_raw called");
1867
2010-09-26
pbug
1868
2010-09-26
pbug
switch (sr->af) {
1869
2010-09-26
pbug
case AF_INET:
1870
2010-09-26
pbug
so = raw[0];
1871
2010-09-26
pbug
break;
1872
2010-09-26
pbug
case AF_INET6:
1873
2010-09-26
pbug
so = raw[1];
1874
2010-09-26
pbug
break;
1875
2010-09-26
pbug
default:
1876
2013-02-16
pjp
dolog(LOG_ERR, "reply_raw_cname(): unknown address family in struct recurses");
1877
2010-09-26
pbug
return;
1878
2010-09-26
pbug
}
1879
2010-09-26
pbug
1880
2010-09-26
pbug
switch (sr->proto) {
1881
2010-09-26
pbug
case IPPROTO_UDP:
1882
2010-09-26
pbug
break;
1883
2010-09-26
pbug
default:
1884
2013-02-16
pjp
dolog(LOG_ERR, "reply_raw_cname(): can't do any protocol other than udp right now");
1885
2010-09-26
pbug
return;
1886
2010-09-26
pbug
}
1887
2010-09-26
pbug
1888
2010-09-26
pbug
build_reply(&sreply, so, sr->query, sr->len, sr->question, NULL, 0, sd, NULL, 0xff, 0, 0, sr);
1889
2010-09-26
pbug
1890
2010-09-26
pbug
reply_cname(&sreply);
1891
2010-09-26
pbug
1892
2010-09-26
pbug
return;
1893
2010-09-26
pbug
}
1894
2010-09-26
pbug
1895
2010-09-21
pbug
/*
1896
2010-09-21
pbug
* REMOVE_ZONE - remove a zone from the database (it probably expired)
1897
2010-09-21
pbug
*
1898
2010-09-21
pbug
*
1899
2010-09-21
pbug
*/
1900
2010-09-21
pbug
1901
2010-09-21
pbug
void
1902
2010-09-21
pbug
remove_zone(DB *db, struct domain *sd)
1903
2010-09-21
pbug
{
1904
2010-09-21
pbug
DBT key;
1905
2010-09-21
pbug
char *zone;
1906
2010-09-21
pbug
int zonelen;
1907
2010-09-21
pbug
1908
2010-09-21
pbug
zone = sd->zone;
1909
2010-09-21
pbug
zonelen = sd->zonelen;
1910
2010-09-21
pbug
1911
2010-09-25
pbug
key.data = (char *)zone;
1912
2010-09-25
pbug
key.size = zonelen;
1913
2010-09-25
pbug
1914
2010-09-25
pbug
if (db->del(db, NULL, &key, 0) != 0) {
1915
2013-02-16
pjp
dolog(LOG_ERR, "could not delete zone %s: %m", zone);
1916
2010-09-25
pbug
}
1917
2010-09-21
pbug
1918
2013-02-16
pjp
dolog(LOG_DEBUG, "deleting zone %s\n", zone);
1919
2010-09-25
pbug
1920
2010-09-25
pbug
free(zone);
1921
2010-09-25
pbug
1922
2010-09-25
pbug
return;
1923
2010-09-25
pbug
}
1924
2010-09-25
pbug
1925
2010-09-25
pbug
void
1926
2010-09-25
pbug
reply_raw_noerror(DB *db, struct recurses *sr, struct domain *sd, int *raw)
1927
2010-09-25
pbug
{
1928
2010-09-25
pbug
int so;
1929
2010-09-25
pbug
struct sreply sreply;
1930
2010-09-25
pbug
1931
2013-02-16
pjp
dolog(LOG_DEBUG, "reply_raw_noerror called");
1932
2010-09-25
pbug
1933
2010-09-25
pbug
switch (sr->af) {
1934
2010-09-25
pbug
case AF_INET:
1935
2010-09-25
pbug
so = raw[0];
1936
2010-09-25
pbug
break;
1937
2010-09-25
pbug
case AF_INET6:
1938
2010-09-25
pbug
so = raw[1];
1939
2010-09-25
pbug
break;
1940
2010-09-25
pbug
default:
1941
2013-02-16
pjp
dolog(LOG_ERR, "reply_raw_noerror(): unknown address family in struct recurses");
1942
2010-09-25
pbug
return;
1943
2010-09-21
pbug
}
1944
2010-09-25
pbug
1945
2010-09-25
pbug
switch (sr->proto) {
1946
2010-09-25
pbug
case IPPROTO_UDP:
1947
2010-09-25
pbug
break;
1948
2010-09-25
pbug
default:
1949
2013-02-16
pjp
dolog(LOG_ERR, "reply_raw_noerror(): can't do any protocol other than udp right now");
1950
2010-09-25
pbug
return;
1951
2010-09-21
pbug
}
1952
2010-09-25
pbug
1953
2010-09-25
pbug
build_reply(&sreply, so, sr->query, sr->len, sr->question, NULL, 0, sd, NULL, 0xff, 0, 0, sr);
1954
2010-09-25
pbug
1955
2010-09-25
pbug
reply_noerror(&sreply);
1956
2010-09-25
pbug
1957
2010-09-25
pbug
return;
1958
2010-09-25
pbug
}
1959
2010-09-25
pbug
1960
2010-09-25
pbug
void
1961
2010-09-25
pbug
reply_raw_nxdomain(DB *db, struct recurses *sr, struct domain *sd, int *raw)
1962
2010-09-25
pbug
{
1963
2010-09-25
pbug
int so;
1964
2010-09-25
pbug
struct sreply sreply;
1965
2010-09-25
pbug
1966
2013-02-16
pjp
dolog(LOG_DEBUG, "reply_raw_nxdomain called");
1967
2010-09-25
pbug
1968
2010-09-25
pbug
switch (sr->af) {
1969
2010-09-25
pbug
case AF_INET:
1970
2010-09-25
pbug
so = raw[0];
1971
2010-09-25
pbug
break;
1972
2010-09-25
pbug
case AF_INET6:
1973
2010-09-25
pbug
so = raw[1];
1974
2010-09-25
pbug
break;
1975
2010-09-25
pbug
default:
1976
2013-02-16
pjp
dolog(LOG_ERR, "reply_raw_nxdomain(): unknown address family in struct recurses");
1977
2010-09-25
pbug
return;
1978
2010-09-25
pbug
}
1979
2010-09-25
pbug
1980
2010-09-25
pbug
switch (sr->proto) {
1981
2010-09-25
pbug
case IPPROTO_UDP:
1982
2010-09-25
pbug
break;
1983
2010-09-25
pbug
default:
1984
2013-02-16
pjp
dolog(LOG_ERR, "reply_raw_nxdomain(): can't do any protocol other than udp right now");
1985
2010-09-25
pbug
return;
1986
2010-09-25
pbug
}
1987
2010-09-25
pbug
1988
2010-09-25
pbug
build_reply(&sreply, so, sr->query, sr->len, sr->question, NULL, 0, sd, NULL, 0xff, 0, 0, sr);
1989
2010-09-25
pbug
1990
2010-09-25
pbug
reply_nxdomain(&sreply);
1991
2010-09-25
pbug
1992
2010-09-25
pbug
return;
1993
2010-09-28
pbug
}
1994
2010-09-28
pbug
1995
2010-09-28
pbug
1996
2010-09-28
pbug
/*
1997
2010-09-28
pbug
* LEVEL - traverse a domain name and count how many levels it has
1998
2010-09-28
pbug
* first level is a TLD, then a 2nd level domain and so on.
1999
2010-09-28
pbug
*/
2000
2010-09-28
pbug
2001
2010-09-28
pbug
int
2002
2010-09-28
pbug
level(u_char *p)
2003
2010-09-28
pbug
{
2004
2010-09-28
pbug
int level = 0;
2005
2010-09-28
pbug
2006
2010-09-28
pbug
while (*p) {
2007
2010-09-28
pbug
level++;
2008
2010-09-28
pbug
p += ((*p) + 1);
2009
2010-09-28
pbug
}
2010
2010-09-28
pbug
2011
2010-09-28
pbug
return (level);
2012
2010-09-28
pbug
}
2013
2010-09-28
pbug
2014
2010-09-28
pbug
/*
2015
2010-09-28
pbug
* CONTAINS - check if domain name A is contained in domain name B
2016
2010-09-28
pbug
*
2017
2010-09-28
pbug
*/
2018
2010-09-28
pbug
2019
2010-09-28
pbug
int
2020
2010-09-28
pbug
contains(u_char *a, u_char *b)
2021
2010-09-28
pbug
{
2022
2010-09-28
pbug
u_char *p = a;
2023
2010-09-28
pbug
u_char *q = b;
2024
2010-09-28
pbug
u_int plen = 0, qlen = 0;
2025
2010-09-28
pbug
2026
2010-09-28
pbug
while (*p) {
2027
2010-09-28
pbug
plen += (*p) + 1;
2028
2010-09-28
pbug
p += ((*p) + 1);
2029
2010-09-28
pbug
}
2030
2010-09-28
pbug
2031
2010-09-28
pbug
while (*q) {
2032
2010-09-28
pbug
qlen += ((*q) + 1);
2033
2010-09-28
pbug
q += ((*q) + 1);
2034
2010-09-28
pbug
}
2035
2010-09-28
pbug
2036
2010-09-28
pbug
p = a;
2037
2010-09-28
pbug
q = b;
2038
2010-09-28
pbug
2039
2010-09-28
pbug
while (*q) {
2040
2011-04-19
pbug
if ((plen == qlen) && memcasecmp((u_char *)p, (u_char *)q, qlen) == 0)
2041
2010-09-28
pbug
return (1);
2042
2010-09-28
pbug
2043
2010-09-28
pbug
qlen -= ((*q) + 1);
2044
2010-09-28
pbug
q += ((*q) + 1);
2045
2010-09-30
pbug
}
2046
2010-09-30
pbug
2047
2010-09-30
pbug
return (0);
2048
2010-09-30
pbug
}
2049
2010-09-30
pbug
2050
2010-09-30
pbug
/*
2051
2010-09-30
pbug
* NETLOOKUP6 - do an ipv6 lookup of the requested internet record
2052
2010-09-30
pbug
*
2053
2010-09-30
pbug
*/
2054
2010-09-30
pbug
2055
2010-09-30
pbug
int
2056
2010-09-30
pbug
netlookup6(DB *db, struct recurses *sr)
2057
2010-09-30
pbug
{
2058
2010-09-30
pbug
struct sockaddr_in6 sin6;
2059
2010-09-30
pbug
struct dns_header *dh;
2060
2010-09-30
pbug
2061
2010-09-30
pbug
char buf[2048];
2062
2010-09-30
pbug
int flag;
2063
2010-09-30
pbug
2064
2010-09-30
pbug
if (sr->so != -1) {
2065
2010-09-30
pbug
if (close(sr->so) < 0)
2066
2013-02-16
pjp
dolog(LOG_ERR, "close: %m");
2067
2010-09-30
pbug
}
2068
2010-09-30
pbug
2069
2010-09-30
pbug
sr->so = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
2070
2010-09-30
pbug
if (sr->so < 0) {
2071
2013-02-16
pjp
dolog(LOG_ERR, "socket6: %m");
2072
2010-09-30
pbug
sr->so = -1;
2073
2010-09-30
pbug
return (-1);
2074
2010-09-30
pbug
}
2075
2010-09-30
pbug
2076
2014-09-27
pjp
sr->port = arc4random() & 0xffff;
2077
2010-09-30
pbug
/*
2078
2010-09-30
pbug
* we have to avoid picking servers already
2079
2010-09-30
pbug
* running ..
2080
2010-09-30
pbug
*/
2081
2010-09-30
pbug
if (sr->port < 1024)
2082
2010-09-30
pbug
sr->port += 1024;
2083
2010-09-30
pbug
2084
2014-09-27
pjp
sr->id = arc4random() & 0xffff;
2085
2010-09-30
pbug
2086
2010-09-30
pbug
memset(&sin6, 0, sizeof(sin6));
2087
2010-09-30
pbug
sin6.sin6_family = AF_INET6;
2088
2010-09-30
pbug
sin6.sin6_port = htons(sr->port);
2089
2010-10-06
pbug
#ifndef __linux__
2090
2010-10-05
pbug
sin6.sin6_len = sizeof(struct sockaddr_in6);
2091
2010-10-06
pbug
#endif
2092
2010-09-30
pbug
2093
2010-09-30
pbug
if (bind(sr->so, (struct sockaddr *)&sin6, sizeof(sin6)) < 0) {
2094
2013-02-16
pjp
dolog(LOG_ERR, "bind: %m");
2095
2010-09-30
pbug
if (close(sr->so) < 0) {
2096
2013-02-16
pjp
dolog(LOG_ERR, "close: %m");
2097
2010-09-30
pbug
}
2098
2010-09-30
pbug
sr->so = -1;
2099
2010-09-30
pbug
return (-1);
2100
2010-09-30
pbug
}
2101
2010-09-30
pbug
2102
2010-09-30
pbug
/*
2103
2010-09-30
pbug
* make this socket nonblocking
2104
2010-09-30
pbug
*/
2105
2010-09-30
pbug
2106
2010-09-30
pbug
if ((flag = fcntl(sr->so, F_GETFL)) < 0) {
2107
2013-02-16
pjp
dolog(LOG_INFO, "fcntl 3: %m");
2108
2010-09-30
pbug
}
2109
2010-09-30
pbug
flag |= O_NONBLOCK;
2110
2010-09-30
pbug
if (fcntl(sr->so, F_SETFL, flag) < 0) {
2111
2013-02-16
pjp
dolog(LOG_INFO, "fcntl 4: %m");
2112
2010-09-30
pbug
}
2113
2010-09-30
pbug
2114
2010-09-30
pbug
if (lookup_ns(db, sr) <= 0) {
2115
2013-02-16
pjp
dolog(LOG_ERR, "can't establish any servers to reach for zone \"%s\"", sr->question->converted_name);
2116
2010-09-30
pbug
if (close(sr->so) < 0) {
2117
2013-02-16
pjp
dolog(LOG_ERR, "close: %m");
2118
2010-09-30
pbug
}
2119
2010-09-30
pbug
sr->so = -1;
2120
2010-09-30
pbug
return (-1);
2121
2010-09-30
pbug
}
2122
2010-09-30
pbug
2123
2010-09-30
pbug
memset(&sin6, 0, sizeof(sin6));
2124
2010-09-30
pbug
sin6.sin6_family = AF_INET6;
2125
2010-09-30
pbug
sin6.sin6_port = htons(53);
2126
2010-09-30
pbug
2127
2010-10-05
pbug
/* pjp */
2128
2010-10-05
pbug
memcpy((char *)&sin6.sin6_addr, (char *)&sr->aaaa[0], sizeof(struct in6_addr));
2129
2010-09-30
pbug
2130
2010-09-30
pbug
/* XXX we use buf here in order to preserve
2131
2010-09-30
pbug
* the state of query...
2132
2010-09-30
pbug
*/
2133
2010-09-30
pbug
memcpy(buf, sr->query, sr->len);
2134
2010-09-30
pbug
dh = (struct dns_header *)&buf[0];
2135
2010-09-30
pbug
NTOHS(dh->query);
2136
2010-09-30
pbug
UNSET_DNS_RECURSION(dh);
2137
2010-09-30
pbug
HTONS(dh->query);
2138
2010-09-30
pbug
dh->id = htons(sr->id);
2139
2010-09-30
pbug
2140
2010-09-30
pbug
#if 1
2141
2013-02-16
pjp
dolog(LOG_INFO, "sending request with id %u\n", sr->id);
2142
2010-09-30
pbug
2143
2010-09-30
pbug
#endif
2144
2010-09-30
pbug
2145
2010-09-30
pbug
if (sendto(sr->so, buf, sr->len, 0, (struct sockaddr *)&sin6, sizeof(sin6)) < 0) {
2146
2013-02-16
pjp
dolog(LOG_ERR, "sendto6: %m");
2147
2010-09-30
pbug
if (close(sr->so) < 0) {
2148
2013-02-16
pjp
dolog(LOG_ERR, "close: %m");
2149
2010-09-30
pbug
}
2150
2010-09-30
pbug
sr->so = -1;
2151
2010-09-30
pbug
return (-1);
2152
2010-09-30
pbug
}
2153
2010-09-30
pbug
2154
2010-09-30
pbug
sr->sent_last_query = time(NULL);
2155
2010-09-30
pbug
sr->packetcount++;
2156
2010-09-30
pbug
2157
2010-09-30
pbug
2158
2010-09-30
pbug
return (0);
2159
2010-09-30
pbug
}
2160
2010-09-30
pbug
2161
2010-09-30
pbug
/*
2162
2010-09-30
pbug
* LOOKUP_AAAA - given a path, lookup the AAAA record in that record
2163
2010-09-30
pbug
*
2164
2010-09-30
pbug
*/
2165
2010-09-30
pbug
2166
2010-09-30
pbug
int
2167
2010-09-30
pbug
lookup_aaaa(DB *db, struct recurses *sr, struct ns *ns)
2168
2010-09-30
pbug
{
2169
2010-09-30
pbug
int ret, plen;
2170
2010-09-30
pbug
char *p;
2171
2010-09-30
pbug
2172
2010-09-30
pbug
DBT key, data;
2173
2010-09-30
pbug
2174
2010-09-30
pbug
struct domain *sd, sdomain;
2175
2010-09-30
pbug
int found = 0;
2176
2010-09-30
pbug
2177
2010-09-30
pbug
p = ns->nsserver;
2178
2010-09-30
pbug
plen = ns->nslen;
2179
2010-09-30
pbug
2180
2010-09-30
pbug
memset(&key, 0, sizeof(key));
2181
2010-09-30
pbug
memset(&data, 0, sizeof(data));
2182
2010-09-30
pbug
2183
2010-09-30
pbug
key.data = (char *)p;
2184
2010-09-30
pbug
key.size = plen;
2185
2010-09-30
pbug
2186
2010-09-30
pbug
data.data = NULL;
2187
2010-09-30
pbug
data.size = 0;
2188
2010-09-30
pbug
2189
2010-09-30
pbug
found = 0;
2190
2010-09-30
pbug
2191
2010-09-30
pbug
ret = db->get(db, NULL, &key, &data, 0);
2192
2010-09-30
pbug
if (ret == 0) {
2193
2010-09-30
pbug
if (data.size != sizeof(struct domain)) {
2194
2013-02-16
pjp
dolog(LOG_ERR, "btree db is damaged");
2195
2010-09-30
pbug
return (-1);
2196
2010-09-30
pbug
}
2197
2010-09-30
pbug
2198
2010-09-30
pbug
memcpy((char*)&sdomain, data.data, sizeof(struct domain));
2199
2010-09-30
pbug
sd = &sdomain;
2200
2010-09-30
pbug
2201
2010-09-30
pbug
if ((sd->flags & DOMAIN_HAVE_AAAA) == DOMAIN_HAVE_AAAA) {
2202
2011-09-19
pbug
memcpy((char *)&sr->aaaa[sr->aaaa_count], (char *)&sd->aaaa[0], sizeof(struct in6_addr));
2203
2010-09-30
pbug
sd->a_count++;
2204
2010-09-30
pbug
found = 1;
2205
2010-09-30
pbug
2206
2010-09-30
pbug
}
2207
2010-09-30
pbug
}
2208
2010-09-30
pbug
2209
2010-09-30
pbug
if (! found) {
2210
2013-02-16
pjp
dolog(LOG_DEBUG, "calling fakerecurse");
2211
2010-09-30
pbug
fakerecurse(db, sr, ns, DNS_TYPE_AAAA);
2212
2010-09-30
pbug
return (-1);
2213
2010-09-28
pbug
}
2214
2010-09-28
pbug
2215
2010-09-28
pbug
return (0);
2216
2010-04-15
pbug
}
repomaster@centroid.eu