Blame
Date:
Sat Aug 1 09:01:52 2020 UTC
Message:
move extended RCODE's out of the RCODE section those are only 0x00 through 0x0F make a section that shows extended RCODE's that are added to a EDNS0 tag.
0001
2020-06-30
pjp
/*
0002
2020-06-30
pjp
* Copyright (c) 2020 Peter J. Philipp
0003
2020-06-30
pjp
* All rights reserved.
0004
2020-06-30
pjp
*
0005
2020-06-30
pjp
* Redistribution and use in source and binary forms, with or without
0006
2020-06-30
pjp
* modification, are permitted provided that the following conditions
0007
2020-06-30
pjp
* are met:
0008
2020-06-30
pjp
* 1. Redistributions of source code must retain the above copyright
0009
2020-06-30
pjp
* notice, this list of conditions and the following disclaimer.
0010
2020-06-30
pjp
* 2. Redistributions in binary form must reproduce the above copyright
0011
2020-06-30
pjp
* notice, this list of conditions and the following disclaimer in the
0012
2020-06-30
pjp
* documentation and/or other materials provided with the distribution.
0013
2020-06-30
pjp
* 3. The name of the author may not be used to endorse or promote products
0014
2020-06-30
pjp
* derived from this software without specific prior written permission
0015
2020-06-30
pjp
*
0016
2020-06-30
pjp
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0017
2020-06-30
pjp
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0018
2020-06-30
pjp
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0019
2020-06-30
pjp
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0020
2020-06-30
pjp
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0021
2020-06-30
pjp
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0022
2020-06-30
pjp
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0023
2020-06-30
pjp
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0024
2020-06-30
pjp
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0025
2020-06-30
pjp
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0026
2020-06-30
pjp
*
0027
2020-06-30
pjp
*/
0028
2020-06-30
pjp
0029
2020-06-30
pjp
/*
0030
2020-07-30
pjp
* $Id: forward.c,v 1.40 2020/07/30 05:14:29 pjp Exp $
0031
2020-06-30
pjp
*/
0032
2020-06-30
pjp
0033
2020-06-30
pjp
#include <sys/types.h>
0034
2020-06-30
pjp
#include <sys/socket.h>
0035
2020-06-30
pjp
#include <sys/uio.h>
0036
2020-06-30
pjp
#include <sys/select.h>
0037
2020-07-10
pjp
#include <sys/mman.h>
0038
2020-07-10
pjp
#include <sys/resource.h>
0039
2020-06-30
pjp
0040
2020-06-30
pjp
#include <netinet/in.h>
0041
2020-07-21
pjp
#include <netinet/udp.h>
0042
2020-07-21
pjp
#include <netinet/ip.h>
0043
2020-07-21
pjp
#include <netinet/ip6.h>
0044
2020-06-30
pjp
#include <arpa/inet.h>
0045
2020-06-30
pjp
#include <netdb.h>
0046
2020-06-30
pjp
0047
2020-06-30
pjp
#include <stdio.h>
0048
2020-06-30
pjp
#include <stdlib.h>
0049
2020-06-30
pjp
#include <stdint.h>
0050
2020-06-30
pjp
#include <string.h>
0051
2020-06-30
pjp
#include <errno.h>
0052
2020-06-30
pjp
#include <syslog.h>
0053
2020-07-16
pjp
#include <ctype.h>
0054
2020-06-30
pjp
0055
2020-06-30
pjp
#include <unistd.h>
0056
2020-07-10
pjp
#include <fcntl.h>
0057
2020-06-30
pjp
0058
2020-06-30
pjp
#ifdef __linux__
0059
2020-06-30
pjp
#include <grp.h>
0060
2020-06-30
pjp
#define __USE_BSD 1
0061
2020-06-30
pjp
#include <endian.h>
0062
2020-06-30
pjp
#include <bsd/stdlib.h>
0063
2020-06-30
pjp
#include <bsd/string.h>
0064
2020-06-30
pjp
#include <bsd/unistd.h>
0065
2020-06-30
pjp
#include <bsd/sys/queue.h>
0066
2020-06-30
pjp
#define __unused
0067
2020-06-30
pjp
#include <bsd/sys/tree.h>
0068
2020-06-30
pjp
#include <bsd/sys/endian.h>
0069
2020-06-30
pjp
#include "imsg.h"
0070
2020-06-30
pjp
#else /* not linux */
0071
2020-06-30
pjp
#include <sys/queue.h>
0072
2020-06-30
pjp
#include <sys/tree.h>
0073
2020-06-30
pjp
#ifdef __FreeBSD__
0074
2020-06-30
pjp
#include <sys/endian.h>
0075
2020-06-30
pjp
#include "imsg.h"
0076
2020-06-30
pjp
#else
0077
2020-06-30
pjp
#include <imsg.h>
0078
2020-06-30
pjp
#endif /* __FreeBSD__ */
0079
2020-06-30
pjp
#endif /* __linux__ */
0080
2020-06-30
pjp
0081
2020-06-30
pjp
#ifndef NTOHS
0082
2020-06-30
pjp
#include "endian.h"
0083
2020-06-30
pjp
#endif
0084
2020-06-30
pjp
0085
2020-07-03
pjp
#include <openssl/hmac.h>
0086
2020-07-03
pjp
0087
2020-06-30
pjp
#include "ddd-dns.h"
0088
2020-06-30
pjp
#include "ddd-db.h"
0089
2020-06-30
pjp
0090
2020-07-04
pjp
TAILQ_HEAD(forwardentrys, forwardentry) forwardhead;
0091
2020-06-30
pjp
0092
2020-07-04
pjp
struct forwardentry {
0093
2020-06-30
pjp
char name[INET6_ADDRSTRLEN];
0094
2020-06-30
pjp
int family;
0095
2020-07-01
pjp
struct sockaddr_storage host;
0096
2020-06-30
pjp
uint16_t destport;
0097
2020-06-30
pjp
char *tsigkey;
0098
2020-07-03
pjp
int active;
0099
2020-07-04
pjp
TAILQ_ENTRY(forwardentry) forward_entry;
0100
2020-06-30
pjp
} *fw2, *fwp;
0101
2020-06-30
pjp
0102
2020-07-01
pjp
SLIST_HEAD(, forwardqueue) fwqhead;
0103
2020-06-30
pjp
0104
2020-07-04
pjp
struct forwardqueue {
0105
2020-07-16
pjp
char orig_dnsname[DNS_MAXNAME]; /* what we reply with */
0106
2020-07-16
pjp
char dnsname[DNS_MAXNAME]; /* the request name */
0107
2020-07-16
pjp
char dnsnamelen; /* the len of dnsname */
0108
2020-07-03
pjp
uint32_t longid; /* a long identifier */
0109
2020-07-03
pjp
time_t time; /* time created */
0110
2020-07-03
pjp
struct sockaddr_storage host; /* remote host to query */
0111
2020-07-03
pjp
uint16_t id; /* new id to query */
0112
2020-07-03
pjp
uint16_t port; /* remote port to query */
0113
2020-07-03
pjp
struct sockaddr_in oldhost4; /* old v4 host source */
0114
2020-07-03
pjp
struct sockaddr_in6 oldhost6; /* old v6 host source */
0115
2020-07-03
pjp
uint16_t oldid; /* old id source */
0116
2020-07-03
pjp
uint16_t oldport; /* the old port */
0117
2020-07-03
pjp
int oldfamily; /* old family */
0118
2020-07-03
pjp
int oldsel; /* this indicates which sock */
0119
2020-07-03
pjp
int so; /* open connected socket */
0120
2020-07-03
pjp
int returnso; /* return socket (TCP) */
0121
2020-07-03
pjp
int istcp; /* whether we're tcp */
0122
2020-07-03
pjp
int family; /* our family */
0123
2020-07-03
pjp
char *tsigkey; /* which key we use for query */
0124
2020-07-03
pjp
uint64_t tsigtimefudge; /* passed tsigtimefudge */
0125
2020-07-03
pjp
char mac[32]; /* passed mac from query */
0126
2020-07-03
pjp
int haveoldmac; /* do we have an old mac? */
0127
2020-07-03
pjp
char oldkeyname[256]; /* old key name */
0128
2020-07-03
pjp
int oldkeynamelen; /* old key name len */
0129
2020-07-03
pjp
char oldmac[32]; /* old mac */
0130
2020-07-04
pjp
struct forwardentry *cur_forwardentry; /* current forwardentry */
0131
2020-07-08
pjp
int dnssecok; /* DNSSEC in anwers */
0132
2020-07-03
pjp
SLIST_ENTRY(forwardqueue) entries; /* next entry */
0133
2020-07-01
pjp
} *fwq1, *fwq2, *fwqp;
0134
2020-07-01
pjp
0135
2020-07-03
pjp
void init_forward(void);
0136
2020-07-03
pjp
int insert_forward(int, struct sockaddr_storage *, uint16_t, char *);
0137
2020-07-03
pjp
void forwardloop(ddDB *, struct cfg *, struct imsgbuf *, struct imsgbuf *);
0138
2020-07-06
pjp
void forwardthis(ddDB *, struct cfg *, int, struct sforward *);
0139
2020-07-03
pjp
void sendit(struct forwardqueue *, struct sforward *);
0140
2020-07-06
pjp
void returnit(ddDB *, struct cfg *, struct forwardqueue *, char *, int, struct imsgbuf *);
0141
2020-07-03
pjp
struct tsig * check_tsig(char *, int, char *);
0142
2020-07-10
pjp
void fwdparseloop(struct imsgbuf *, struct imsgbuf *, struct cfg *);
0143
2020-07-04
pjp
void changeforwarder(struct forwardqueue *);
0144
2020-07-04
pjp
void stirforwarders(void);
0145
2020-07-21
pjp
int rawsend(int, char *, uint16_t, struct sockaddr_in *, int, struct cfg *);
0146
2020-07-21
pjp
int rawsend6(int, char *, uint16_t, struct sockaddr_in6 *, int, struct cfg *);
0147
2020-07-03
pjp
0148
2020-07-21
pjp
extern uint16_t udp_cksum(u_int16_t *, uint16_t, struct ip *, struct udphdr *);
0149
2020-07-21
pjp
extern uint16_t udp_cksum6(u_int16_t *, uint16_t, struct ip6_hdr *, struct udphdr *);
0150
2020-07-03
pjp
extern void dolog(int, char *, ...);
0151
2020-07-06
pjp
extern void pack(char *, char *, int);
0152
2020-07-03
pjp
extern void pack16(char *, u_int16_t);
0153
2020-07-10
pjp
extern void pack32(char *, u_int32_t);
0154
2020-07-03
pjp
extern uint16_t unpack16(char *);
0155
2020-07-03
pjp
extern uint32_t unpack32(char *);
0156
2020-07-03
pjp
extern void ddd_shutdown(void);
0157
2020-07-03
pjp
extern int additional_opt(struct question *, char *, int, int);
0158
2020-07-03
pjp
extern int additional_tsig(struct question *, char *, int, int, int, int, HMAC_CTX *);
0159
2020-07-03
pjp
extern struct question *build_question(char *, int, int, char *);
0160
2020-07-03
pjp
extern struct question *build_fake_question(char *, int, u_int16_t, char *, int);
0161
2020-07-03
pjp
extern int free_question(struct question *);
0162
2020-07-03
pjp
extern char * dns_label(char *, int *);
0163
2020-07-03
pjp
extern int find_tsig_key(char *, int, char *, int);
0164
2020-07-03
pjp
extern int memcasecmp(u_char *, u_char *, int);
0165
2020-07-03
pjp
extern char * expand_compression(u_char *, u_char *, u_char *, u_char *, int *, int);
0166
2020-07-08
pjp
extern int expire_rr(ddDB *, char *, int, u_int16_t, time_t);
0167
2020-07-08
pjp
extern int expire_db(ddDB *, int);
0168
2020-07-06
pjp
extern void build_reply(struct sreply *, int, char *, int, struct question *, struct sockaddr *, socklen_t, struct rbtree *, struct rbtree *, u_int8_t, int, int, char *);
0169
2020-07-06
pjp
extern struct rbtree * Lookup_zone(ddDB *, char *, int, int, int);
0170
2020-07-06
pjp
extern struct rbtree * lookup_zone(ddDB *, struct question *, int *, int *, char *, int);
0171
2020-07-12
pjp
extern int cacheit(u_char *, u_char *, u_char *, struct imsgbuf *, struct imsgbuf *, struct cfg *);
0172
2020-07-03
pjp
0173
2020-07-21
pjp
extern int reply_a(struct sreply *, int *, ddDB *);
0174
2020-07-21
pjp
extern int reply_aaaa(struct sreply *, int *, ddDB *);
0175
2020-07-21
pjp
extern int reply_any(struct sreply *, int *, ddDB *);
0176
2020-07-21
pjp
extern int reply_cname(struct sreply *, int *, ddDB *);
0177
2020-07-21
pjp
extern int reply_notify(struct sreply *, int *, ddDB *);
0178
2020-07-21
pjp
extern int reply_soa(struct sreply *, int *, ddDB *);
0179
2020-07-21
pjp
extern int reply_mx(struct sreply *, int *, ddDB *);
0180
2020-07-21
pjp
extern int reply_naptr(struct sreply *, int *, ddDB *);
0181
2020-07-21
pjp
extern int reply_ns(struct sreply *, int *, ddDB *);
0182
2020-07-21
pjp
extern int reply_ptr(struct sreply *, int *, ddDB *);
0183
2020-07-21
pjp
extern int reply_srv(struct sreply *, int *, ddDB *);
0184
2020-07-21
pjp
extern int reply_sshfp(struct sreply *, int *, ddDB *);
0185
2020-07-21
pjp
extern int reply_tlsa(struct sreply *, int *,ddDB *);
0186
2020-07-21
pjp
extern int reply_txt(struct sreply *, int *, ddDB *);
0187
2020-07-21
pjp
extern int reply_rrsig(struct sreply *, int *, ddDB *);
0188
2020-07-21
pjp
extern int reply_dnskey(struct sreply *, int *, ddDB *);
0189
2020-07-21
pjp
extern int reply_ds(struct sreply *, int *, ddDB *);
0190
2020-07-21
pjp
extern int reply_nsec(struct sreply *, int *, ddDB *);
0191
2020-07-21
pjp
extern int reply_nsec3(struct sreply *, int *, ddDB *);
0192
2020-07-21
pjp
extern int reply_nsec3param(struct sreply *, int *, ddDB *);
0193
2020-07-21
pjp
extern int reply_generic(struct sreply *, int *, ddDB *);
0194
2020-07-15
pjp
extern struct rbtree * create_rr(ddDB *, char *, int, int, void *, uint32_t, uint16_t);
0195
2020-07-08
pjp
extern void flag_rr(struct rbtree *rbt);
0196
2020-07-10
pjp
extern struct rbtree * find_rrset(ddDB *, char *, int);
0197
2020-07-16
pjp
extern int randomize_dnsname(char *buf, int len);
0198
2020-07-16
pjp
extern int lower_dnsname(char *buf, int len);
0199
2020-07-03
pjp
0200
2020-07-06
pjp
/*
0201
2020-07-06
pjp
* XXX everything but txt and naptr, works...
0202
2020-07-06
pjp
*/
0203
2020-07-06
pjp
0204
2020-07-06
pjp
static struct reply_logic rlogic[] = {
0205
2020-07-06
pjp
/* { DNS_TYPE_A, DNS_TYPE_CNAME, BUILD_CNAME, reply_cname }, */
0206
2020-07-06
pjp
/* { DNS_TYPE_A, DNS_TYPE_NS, BUILD_OTHER, reply_ns }, */
0207
2020-07-06
pjp
{ DNS_TYPE_A, DNS_TYPE_A, BUILD_OTHER, reply_a },
0208
2020-07-06
pjp
/* { DNS_TYPE_AAAA, DNS_TYPE_CNAME, BUILD_CNAME, reply_cname }, */
0209
2020-07-06
pjp
/* { DNS_TYPE_AAAA, DNS_TYPE_NS, BUILD_OTHER, reply_ns }, */
0210
2020-07-06
pjp
{ DNS_TYPE_AAAA, DNS_TYPE_AAAA, BUILD_OTHER, reply_aaaa },
0211
2020-07-06
pjp
{ DNS_TYPE_DNSKEY, DNS_TYPE_DNSKEY, BUILD_OTHER, reply_dnskey },
0212
2020-07-06
pjp
{ DNS_TYPE_SOA, DNS_TYPE_SOA, BUILD_OTHER, reply_soa },
0213
2020-07-06
pjp
{ DNS_TYPE_SOA, DNS_TYPE_NS, BUILD_OTHER, reply_ns },
0214
2020-07-06
pjp
/* { DNS_TYPE_MX, DNS_TYPE_CNAME, BUILD_CNAME, reply_cname }, */
0215
2020-07-06
pjp
/* { DNS_TYPE_MX, DNS_TYPE_NS, BUILD_OTHER, reply_ns }, */
0216
2020-07-06
pjp
{ DNS_TYPE_MX, DNS_TYPE_MX, BUILD_OTHER, reply_mx },
0217
2020-07-06
pjp
/* { DNS_TYPE_TXT, DNS_TYPE_TXT, BUILD_OTHER, reply_txt }, */
0218
2020-07-06
pjp
{ DNS_TYPE_NS, DNS_TYPE_NS, BUILD_OTHER, reply_ns },
0219
2020-07-06
pjp
{ DNS_TYPE_ANY, DNS_TYPE_ANY, BUILD_OTHER, reply_any },
0220
2020-07-06
pjp
{ DNS_TYPE_DS, DNS_TYPE_DS, BUILD_OTHER, reply_ds },
0221
2020-07-06
pjp
{ DNS_TYPE_SSHFP, DNS_TYPE_SSHFP, BUILD_OTHER, reply_sshfp },
0222
2020-07-06
pjp
{ DNS_TYPE_TLSA, DNS_TYPE_TLSA, BUILD_OTHER, reply_tlsa },
0223
2020-07-06
pjp
{ DNS_TYPE_SRV, DNS_TYPE_SRV, BUILD_OTHER, reply_srv },
0224
2020-07-06
pjp
{ DNS_TYPE_CNAME, DNS_TYPE_CNAME, BUILD_OTHER, reply_cname },
0225
2020-07-06
pjp
{ DNS_TYPE_CNAME, DNS_TYPE_NS, BUILD_OTHER, reply_ns },
0226
2020-07-06
pjp
{ DNS_TYPE_NSEC3PARAM, DNS_TYPE_NSEC3PARAM, BUILD_OTHER, reply_nsec3param },
0227
2020-07-06
pjp
/* { DNS_TYPE_PTR, DNS_TYPE_CNAME, BUILD_CNAME, reply_cname }, */
0228
2020-07-06
pjp
/* { DNS_TYPE_PTR, DNS_TYPE_NS, BUILD_OTHER, reply_ns }, */
0229
2020-07-06
pjp
{ DNS_TYPE_PTR, DNS_TYPE_PTR, BUILD_OTHER, reply_ptr },
0230
2020-07-06
pjp
/* { DNS_TYPE_NAPTR, DNS_TYPE_NAPTR, BUILD_OTHER, reply_naptr }, */
0231
2020-07-06
pjp
{ DNS_TYPE_NSEC3, DNS_TYPE_NSEC3, BUILD_OTHER, reply_nsec3 },
0232
2020-07-06
pjp
{ DNS_TYPE_NSEC, DNS_TYPE_NSEC, BUILD_OTHER, reply_nsec },
0233
2020-07-06
pjp
{ DNS_TYPE_RRSIG, DNS_TYPE_RRSIG, BUILD_OTHER, reply_rrsig },
0234
2020-07-06
pjp
{ 0, 0, 0, NULL }
0235
2020-07-06
pjp
};
0236
2020-07-06
pjp
0237
2020-07-06
pjp
0238
2020-07-03
pjp
extern int debug, verbose;
0239
2020-07-03
pjp
extern int tsig;
0240
2020-07-03
pjp
extern int dnssec;
0241
2020-07-06
pjp
extern int cache;
0242
2020-07-11
pjp
extern int forward;
0243
2020-07-17
pjp
extern int strictx20i;
0244
2020-07-03
pjp
0245
2020-07-03
pjp
0246
2020-07-03
pjp
/*
0247
2020-07-04
pjp
* INIT_FORWARD - initialize the forward linked lists
0248
2020-07-03
pjp
*/
0249
2020-07-03
pjp
0250
2020-06-30
pjp
void
0251
2020-06-30
pjp
init_forward(void)
0252
2020-06-30
pjp
{
0253
2020-07-04
pjp
TAILQ_INIT(&forwardhead);
0254
2020-07-01
pjp
SLIST_INIT(&fwqhead);
0255
2020-06-30
pjp
return;
0256
2020-06-30
pjp
}
0257
2020-06-30
pjp
0258
2020-06-30
pjp
/*
0259
2020-06-30
pjp
* INSERT_FORWARD - insert into the forward slist
0260
2020-06-30
pjp
*/
0261
2020-06-30
pjp
0262
2020-06-30
pjp
int
0263
2020-07-03
pjp
insert_forward(int family, struct sockaddr_storage *ip, uint16_t port, char *tsigkey)
0264
2020-06-30
pjp
{
0265
2020-07-04
pjp
static int active = 0;
0266
2020-07-04
pjp
0267
2020-07-01
pjp
fw2 = calloc(1, sizeof(struct forwardentry));
0268
2020-07-01
pjp
if (fw2 == NULL) {
0269
2020-07-01
pjp
dolog(LOG_INFO, "calloc: %s\n", strerror(errno));
0270
2020-07-01
pjp
return 1;
0271
2020-07-01
pjp
}
0272
2020-07-01
pjp
0273
2020-07-03
pjp
fw2->family = family;
0274
2020-07-03
pjp
0275
2020-07-03
pjp
switch (fw2->family) {
0276
2020-07-01
pjp
case AF_INET:
0277
2020-07-04
pjp
inet_ntop(AF_INET, &((struct sockaddr_in *)ip)->sin_addr, fw2->name, sizeof(fw2->name));
0278
2020-07-01
pjp
break;
0279
2020-07-01
pjp
case AF_INET6:
0280
2020-07-04
pjp
inet_ntop(AF_INET6, &((struct sockaddr_in6 *)ip)->sin6_addr, fw2->name, sizeof(fw2->name));
0281
2020-07-01
pjp
break;
0282
2020-07-01
pjp
}
0283
2020-07-01
pjp
0284
2020-07-01
pjp
memcpy(&fw2->host, ip, sizeof(struct sockaddr_storage));
0285
2020-07-01
pjp
fw2->destport = port;
0286
2020-07-01
pjp
0287
2020-07-01
pjp
if (strcmp(tsigkey, "NOKEY") == 0)
0288
2020-07-01
pjp
fw2->tsigkey = NULL;
0289
2020-07-01
pjp
else {
0290
2020-07-01
pjp
fw2->tsigkey = strdup(tsigkey);
0291
2020-07-01
pjp
if (fw2->tsigkey == NULL) {
0292
2020-07-01
pjp
dolog(LOG_INFO, "strdup: %s\n", strerror(errno));
0293
2020-07-01
pjp
return 1;
0294
2020-07-01
pjp
}
0295
2020-07-01
pjp
}
0296
2020-07-03
pjp
0297
2020-07-04
pjp
if (! active)
0298
2020-07-04
pjp
fw2->active = 1;
0299
2020-07-04
pjp
0300
2020-07-04
pjp
active = 1;
0301
2020-07-01
pjp
0302
2020-07-04
pjp
TAILQ_INSERT_HEAD(&forwardhead, fw2, forward_entry);
0303
2020-07-01
pjp
0304
2020-06-30
pjp
return (0);
0305
2020-06-30
pjp
}
0306
2020-06-30
pjp
0307
2020-06-30
pjp
void
0308
2020-07-03
pjp
forwardloop(ddDB *db, struct cfg *cfg, struct imsgbuf *ibuf, struct imsgbuf *cortex)
0309
2020-06-30
pjp
{
0310
2020-07-03
pjp
struct timeval tv;
0311
2020-06-30
pjp
struct imsg imsg;
0312
2020-07-10
pjp
struct imsgbuf parse_ibuf, biparse_ibuf, *pibuf, *bpibuf;
0313
2020-07-10
pjp
struct rr_imsg *ri;
0314
2020-07-10
pjp
struct sf_imsg *sf;
0315
2020-07-03
pjp
0316
2020-07-03
pjp
char *buf;
0317
2020-07-10
pjp
char *rdata;
0318
2020-07-10
pjp
struct rbtree *rbt = NULL;
0319
2020-07-03
pjp
0320
2020-06-30
pjp
int max, sel;
0321
2020-07-03
pjp
int len, need;
0322
2020-07-03
pjp
int pi[2];
0323
2020-07-10
pjp
int bipi[2];
0324
2020-07-08
pjp
int i, count;
0325
2020-07-04
pjp
u_int packetcount = 0;
0326
2020-07-03
pjp
0327
2020-06-30
pjp
ssize_t n, datalen;
0328
2020-06-30
pjp
fd_set rset;
0329
2020-07-03
pjp
pid_t pid;
0330
2020-06-30
pjp
0331
2020-07-10
pjp
char *ptr;
0332
2020-07-10
pjp
0333
2020-07-10
pjp
ptr = cfg->shptr;
0334
2020-07-10
pjp
0335
2020-07-11
pjp
forward = 0; /* in this process we don't need forward on */
0336
2020-07-08
pjp
dolog(LOG_INFO, "FORWARD: expired %d records from non-forwarding DB\n", expire_db(db, 1));
0337
2020-07-08
pjp
0338
2020-07-03
pjp
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, PF_UNSPEC, &pi[0]) < 0) {
0339
2020-07-03
pjp
dolog(LOG_INFO, "socketpair() failed\n");
0340
2020-07-03
pjp
ddd_shutdown();
0341
2020-07-03
pjp
exit(1);
0342
2020-07-03
pjp
}
0343
2020-07-10
pjp
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, PF_UNSPEC, &bipi[0]) < 0) {
0344
2020-07-10
pjp
dolog(LOG_INFO, "socketpair() failed\n");
0345
2020-07-10
pjp
ddd_shutdown();
0346
2020-07-10
pjp
exit(1);
0347
2020-07-10
pjp
}
0348
2020-07-03
pjp
0349
2020-07-03
pjp
pid = fork();
0350
2020-07-03
pjp
switch (pid) {
0351
2020-07-03
pjp
case -1:
0352
2020-07-03
pjp
dolog(LOG_INFO, "fork() failed\n");
0353
2020-07-03
pjp
ddd_shutdown();
0354
2020-07-03
pjp
exit(1);
0355
2020-07-03
pjp
case 0:
0356
2020-07-14
pjp
#ifndef __OpenBSD__
0357
2020-07-14
pjp
/* OpenBSD has minherit() */
0358
2020-07-14
pjp
if (munmap(cfg->shptr, cfg->shptrsize) == -1) {
0359
2020-07-14
pjp
dolog(LOG_INFO, "unmapping shptr failed: %s\n", \
0360
2020-07-14
pjp
strerror(errno));
0361
2020-07-14
pjp
}
0362
2020-07-14
pjp
#endif
0363
2020-07-14
pjp
cfg->shptrsize = 0;
0364
2020-07-03
pjp
0365
2020-07-03
pjp
close(ibuf->fd);
0366
2020-07-03
pjp
close(cortex->fd);
0367
2020-07-03
pjp
close(pi[1]);
0368
2020-07-10
pjp
close(bipi[1]);
0369
2020-07-03
pjp
imsg_init(&parse_ibuf, pi[0]);
0370
2020-07-10
pjp
imsg_init(&biparse_ibuf, bipi[0]);
0371
2020-07-10
pjp
0372
2020-07-03
pjp
setproctitle("forward parse engine");
0373
2020-07-10
pjp
fwdparseloop(&parse_ibuf, &biparse_ibuf, cfg);
0374
2020-07-03
pjp
/* NOTREACHED */
0375
2020-07-03
pjp
0376
2020-07-03
pjp
break;
0377
2020-07-03
pjp
default:
0378
2020-07-03
pjp
close(pi[0]);
0379
2020-07-10
pjp
close(bipi[0]);
0380
2020-07-03
pjp
imsg_init(&parse_ibuf, pi[1]);
0381
2020-07-10
pjp
imsg_init(&biparse_ibuf, bipi[1]);
0382
2020-07-03
pjp
0383
2020-07-03
pjp
pibuf = &parse_ibuf;
0384
2020-07-10
pjp
bpibuf = &biparse_ibuf;
0385
2020-07-03
pjp
break;
0386
2020-07-03
pjp
}
0387
2020-07-03
pjp
0388
2020-07-03
pjp
buf = calloc(1, (0xffff + 2));
0389
2020-07-03
pjp
if (buf == NULL) {
0390
2020-07-03
pjp
dolog(LOG_INFO, "calloc: %s\n", strerror(errno));
0391
2020-07-03
pjp
ddd_shutdown();
0392
2020-07-03
pjp
exit(1);
0393
2020-07-03
pjp
}
0394
2020-07-04
pjp
0395
2020-06-30
pjp
for (;;) {
0396
2020-07-04
pjp
/*
0397
2020-07-04
pjp
* due to our strategy (which kinda sucks) stir some
0398
2020-07-04
pjp
* entropy into the active forwarder
0399
2020-07-04
pjp
*/
0400
2020-07-04
pjp
if (packetcount++ && packetcount % 1000 == 0)
0401
2020-07-04
pjp
stirforwarders();
0402
2020-07-04
pjp
0403
2020-06-30
pjp
FD_ZERO(&rset);
0404
2020-06-30
pjp
FD_SET(ibuf->fd, &rset);
0405
2020-06-30
pjp
if (ibuf->fd > max)
0406
2020-06-30
pjp
max = ibuf->fd;
0407
2020-07-10
pjp
FD_SET(bpibuf->fd, &rset);
0408
2020-07-10
pjp
if (bpibuf->fd > max)
0409
2020-07-10
pjp
max = bpibuf->fd;
0410
2020-06-30
pjp
0411
2020-07-03
pjp
SLIST_FOREACH(fwq1, &fwqhead, entries) {
0412
2020-07-03
pjp
if (fwq1->so > max)
0413
2020-07-03
pjp
max = fwq1->so;
0414
2020-07-03
pjp
0415
2020-07-03
pjp
FD_SET(fwq1->so, &rset);
0416
2020-07-03
pjp
}
0417
2020-07-03
pjp
0418
2020-07-08
pjp
/*
0419
2020-07-08
pjp
* set a timeout for idle periods, which we'll use to expire
0420
2020-07-08
pjp
* the db
0421
2020-07-08
pjp
*/
0422
2020-07-08
pjp
0423
2020-07-08
pjp
tv.tv_sec = 10;
0424
2020-07-08
pjp
tv.tv_usec = 0;
0425
2020-07-08
pjp
0426
2020-07-08
pjp
sel = select(max + 1, &rset, NULL, NULL, &tv);
0427
2020-06-30
pjp
if (sel == -1) {
0428
2020-07-10
pjp
dolog(LOG_INFO, "select error\n");
0429
2020-06-30
pjp
continue;
0430
2020-06-30
pjp
}
0431
2020-07-08
pjp
if (sel == 0) {
0432
2020-07-08
pjp
if (cache) {
0433
2020-07-08
pjp
count = expire_db(db, 0);
0434
2020-07-08
pjp
if (count)
0435
2020-07-08
pjp
dolog(LOG_INFO, "Forward CACHE expire_db: expired %d RR's\n", count);
0436
2020-07-08
pjp
}
0437
2020-07-08
pjp
continue;
0438
2020-07-08
pjp
}
0439
2020-06-30
pjp
0440
2020-07-10
pjp
0441
2020-07-03
pjp
SLIST_FOREACH_SAFE(fwq1, &fwqhead, entries, fwqp) {
0442
2020-07-03
pjp
if (FD_ISSET(fwq1->so, &rset)) {
0443
2020-07-03
pjp
if (fwq1->istcp) {
0444
2020-07-03
pjp
tv.tv_sec = 2;
0445
2020-07-03
pjp
tv.tv_usec = 0;
0446
2020-07-03
pjp
0447
2020-07-03
pjp
if (setsockopt(fwq1->so, SOL_SOCKET, SO_RCVTIMEO, &tv,
0448
2020-07-03
pjp
sizeof(tv)) < 0) {
0449
2020-07-03
pjp
goto drop;
0450
2020-07-03
pjp
}
0451
2020-07-03
pjp
0452
2020-07-03
pjp
len = recv(fwq1->so, buf, 2, MSG_WAITALL);
0453
2020-07-03
pjp
if (len <= 0)
0454
2020-07-03
pjp
goto drop;
0455
2020-07-03
pjp
0456
2020-07-03
pjp
need = ntohs(unpack16(buf));
0457
2020-07-08
pjp
len = recv(fwq1->so, buf, need, MSG_WAITALL | MSG_PEEK);
0458
2020-07-03
pjp
if (len <= 0)
0459
2020-07-03
pjp
goto drop;
0460
2020-07-03
pjp
0461
2020-07-06
pjp
returnit(db, cfg, fwq1, buf, len, pibuf);
0462
2020-07-03
pjp
} else {
0463
2020-07-03
pjp
len = recv(fwq1->so, buf, 0xffff, 0);
0464
2020-07-03
pjp
if (len < 0)
0465
2020-07-03
pjp
goto drop;
0466
2020-07-03
pjp
0467
2020-07-06
pjp
returnit(db, cfg, fwq1, buf, len, pibuf);
0468
2020-07-03
pjp
}
0469
2020-07-03
pjp
0470
2020-07-03
pjp
drop:
0471
2020-07-03
pjp
0472
2020-07-03
pjp
SLIST_REMOVE(&fwqhead, fwq1, forwardqueue, entries);
0473
2020-07-03
pjp
close(fwq1->so);
0474
2020-07-08
pjp
fwq1->so = -1;
0475
2020-07-08
pjp
0476
2020-07-03
pjp
if (fwq1->returnso != -1)
0477
2020-07-03
pjp
close(fwq2->returnso);
0478
2020-07-03
pjp
0479
2020-07-03
pjp
if (fwq1->tsigkey)
0480
2020-07-03
pjp
free(fwq1->tsigkey);
0481
2020-07-03
pjp
0482
2020-07-03
pjp
free(fwq1);
0483
2020-07-03
pjp
0484
2020-07-03
pjp
}
0485
2020-07-03
pjp
}
0486
2020-07-03
pjp
0487
2020-07-10
pjp
if (FD_ISSET(ibuf->fd, &rset)) {
0488
2020-06-30
pjp
if ((n = imsg_read(ibuf)) < 0 && errno != EAGAIN) {
0489
2020-06-30
pjp
dolog(LOG_ERR, "imsg read failure %s\n", strerror(errno));
0490
2020-06-30
pjp
continue;
0491
2020-06-30
pjp
}
0492
2020-07-15
pjp
0493
2020-06-30
pjp
if (n == 0) {
0494
2020-06-30
pjp
/* child died? */
0495
2020-07-08
pjp
dolog(LOG_INFO, "sigpipe on child? forward process exiting.\n");
0496
2020-06-30
pjp
exit(1);
0497
2020-06-30
pjp
}
0498
2020-06-30
pjp
0499
2020-06-30
pjp
for (;;) {
0500
2020-07-10
pjp
errno = 0;
0501
2020-07-10
pjp
if ((n = imsg_get(ibuf, &imsg)) <= 0) {
0502
2020-07-10
pjp
if (n != 0)
0503
2020-07-10
pjp
dolog(LOG_ERR, "imsg read error: %s\n", strerror(errno));
0504
2020-06-30
pjp
break;
0505
2020-06-30
pjp
} else {
0506
2020-06-30
pjp
if (n == 0)
0507
2020-06-30
pjp
break;
0508
2020-06-30
pjp
0509
2020-06-30
pjp
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
0510
2020-07-10
pjp
if (datalen != sizeof(int)) {
0511
2020-06-30
pjp
imsg_free(&imsg);
0512
2020-07-10
pjp
break;
0513
2020-06-30
pjp
}
0514
2020-06-30
pjp
0515
2020-06-30
pjp
switch(imsg.hdr.type) {
0516
2020-06-30
pjp
case IMSG_FORWARD_UDP:
0517
2020-07-03
pjp
#if DEBUG
0518
2020-06-30
pjp
dolog(LOG_INFO, "received UDP message from mainloop\n");
0519
2020-07-03
pjp
#endif
0520
2020-07-10
pjp
if (datalen != sizeof(int))
0521
2020-07-10
pjp
break;
0522
2020-07-10
pjp
0523
2020-07-10
pjp
memcpy(&i, imsg.data, sizeof(i));
0524
2020-07-10
pjp
0525
2020-07-10
pjp
0526
2020-07-12
pjp
sf = (struct sf_imsg *)&ptr[0];
0527
2020-07-10
pjp
sf = &sf[i];
0528
2020-07-10
pjp
0529
2020-07-10
pjp
rdata = malloc(sizeof(struct sforward));
0530
2020-07-10
pjp
if (rdata == NULL) {
0531
2020-07-10
pjp
dolog(LOG_ERR, " cache insertion failed\n");
0532
2020-07-10
pjp
imsg_free(&imsg);
0533
2020-07-10
pjp
break;
0534
2020-07-10
pjp
}
0535
2020-07-10
pjp
0536
2020-07-12
pjp
memcpy(rdata, &sf->u.s.sf, sizeof(struct sforward));
0537
2020-07-10
pjp
0538
2020-07-10
pjp
0539
2020-07-10
pjp
forwardthis(db, cfg, -1, (struct sforward *)rdata);
0540
2020-07-10
pjp
free(rdata);
0541
2020-07-10
pjp
/* aquire lock */
0542
2020-07-12
pjp
while (ptr[cfg->shptrsize - 16] == '*')
0543
2020-07-10
pjp
usleep(arc4random() % 300);
0544
2020-07-12
pjp
ptr[cfg->shptrsize - 16] = '*';
0545
2020-07-10
pjp
0546
2020-07-12
pjp
sf->u.s.read = 1;
0547
2020-07-10
pjp
0548
2020-07-12
pjp
ptr[cfg->shptrsize - 16] = ' '; /* release */
0549
2020-07-10
pjp
0550
2020-06-30
pjp
break;
0551
2020-06-30
pjp
0552
2020-06-30
pjp
case IMSG_FORWARD_TCP:
0553
2020-07-03
pjp
#if DEBUG
0554
2020-06-30
pjp
dolog(LOG_INFO, "received TCP message and descriptor\n");
0555
2020-07-03
pjp
#endif
0556
2020-07-10
pjp
if (datalen != sizeof(int))
0557
2020-07-10
pjp
break;
0558
2020-07-10
pjp
0559
2020-07-10
pjp
memcpy(&i, imsg.data, sizeof(i));
0560
2020-07-10
pjp
0561
2020-07-12
pjp
sf = (struct sf_imsg *)&ptr[0];
0562
2020-07-10
pjp
sf = &sf[i];
0563
2020-07-10
pjp
0564
2020-07-10
pjp
rdata = malloc(sizeof(struct sforward));
0565
2020-07-10
pjp
if (rdata == NULL) {
0566
2020-07-10
pjp
dolog(LOG_ERR, " cache insertion failed\n");
0567
2020-07-10
pjp
imsg_free(&imsg);
0568
2020-07-10
pjp
break;
0569
2020-07-10
pjp
}
0570
2020-07-10
pjp
0571
2020-07-12
pjp
memcpy(rdata, &sf->u.s.sf, sizeof(struct sforward));
0572
2020-07-10
pjp
forwardthis(db, cfg, imsg.fd, (struct sforward *)rdata);
0573
2020-07-10
pjp
free(rdata);
0574
2020-07-10
pjp
/* aquire lock */
0575
2020-07-12
pjp
while (ptr[cfg->shptrsize - 16] == '*')
0576
2020-07-10
pjp
usleep(arc4random() % 300);
0577
2020-07-12
pjp
ptr[cfg->shptrsize - 16] = '*';
0578
2020-07-10
pjp
0579
2020-07-12
pjp
sf->u.s.read = 1;
0580
2020-07-10
pjp
0581
2020-07-12
pjp
ptr[cfg->shptrsize - 16] = ' '; /* release */
0582
2020-06-30
pjp
break;
0583
2020-06-30
pjp
}
0584
2020-06-30
pjp
0585
2020-06-30
pjp
imsg_free(&imsg);
0586
2020-06-30
pjp
}
0587
2020-07-10
pjp
0588
2020-07-10
pjp
continue;
0589
2020-06-30
pjp
} /* for (;;) */
0590
2020-06-30
pjp
} /* FD_ISSET... */
0591
2020-07-01
pjp
0592
2020-07-10
pjp
if (FD_ISSET(bpibuf->fd, &rset)) {
0593
2020-07-10
pjp
if ((n = imsg_read(bpibuf)) < 0 && errno != EAGAIN) {
0594
2020-07-10
pjp
dolog(LOG_ERR, "imsg read failure %s\n", strerror(errno));
0595
2020-07-10
pjp
continue;
0596
2020-07-10
pjp
}
0597
2020-07-10
pjp
if (n == 0) {
0598
2020-07-10
pjp
/* child died? */
0599
2020-07-10
pjp
dolog(LOG_INFO, "sigpipe on child? forward process biparse.ibuf exiting.\n");
0600
2020-07-10
pjp
exit(1);
0601
2020-07-10
pjp
}
0602
2020-07-10
pjp
0603
2020-07-10
pjp
for (;;) {
0604
2020-07-10
pjp
if ((n = imsg_get(bpibuf, &imsg)) < 0) {
0605
2020-07-10
pjp
dolog(LOG_ERR, "imsg read error 2: %s\n", strerror(errno));
0606
2020-07-10
pjp
break;
0607
2020-07-10
pjp
} else {
0608
2020-07-10
pjp
if (n == 0)
0609
2020-07-10
pjp
break;
0610
2020-07-10
pjp
0611
2020-07-10
pjp
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
0612
2020-07-10
pjp
0613
2020-07-10
pjp
switch(imsg.hdr.type) {
0614
2020-07-10
pjp
case IMSG_RR_ATTACHED:
0615
2020-07-10
pjp
if (datalen != sizeof(int))
0616
2020-07-10
pjp
break;
0617
2020-07-10
pjp
0618
2020-07-10
pjp
memcpy(&i, imsg.data, sizeof(i));
0619
2020-07-10
pjp
0620
2020-07-12
pjp
while (cfg->shptr2[cfg->shptr2size - 16] == '*')
0621
2020-07-10
pjp
usleep(arc4random() % 300);
0622
2020-07-10
pjp
0623
2020-07-12
pjp
cfg->shptr2[cfg->shptr2size - 16] = '*';
0624
2020-07-12
pjp
ri = (struct rr_imsg *)&cfg->shptr2[0];
0625
2020-07-10
pjp
for (i = 0; i < SHAREDMEMSIZE; i++, ri++) {
0626
2020-07-12
pjp
if (unpack32((char *)&ri->u.s.read) == 0) {
0627
2020-07-12
pjp
rdata = malloc(ri->rri_rr.buflen);
0628
2020-07-10
pjp
if (rdata == NULL) {
0629
2020-07-10
pjp
dolog(LOG_ERR, " cache insertion failed\n");
0630
2020-07-12
pjp
pack32((char *)&ri->u.s.read, 1);
0631
2020-07-10
pjp
continue;
0632
2020-07-10
pjp
}
0633
2020-07-10
pjp
0634
2020-07-12
pjp
memcpy(rdata, &ri->rri_rr.un, ri->rri_rr.buflen);
0635
2020-07-10
pjp
0636
2020-07-16
pjp
if (lower_dnsname(ri->rri_rr.name, ri->rri_rr.namelen) == -1) {
0637
2020-07-16
pjp
dolog(LOG_INFO, "lower_dnsname failed\n");
0638
2020-07-16
pjp
free (rdata);
0639
2020-07-16
pjp
pack32((char *)&ri->u.s.read, 1);
0640
2020-07-16
pjp
continue;
0641
2020-07-16
pjp
}
0642
2020-07-16
pjp
0643
2020-07-12
pjp
if ((rbt = create_rr(db, ri->rri_rr.name,
0644
2020-07-12
pjp
ri->rri_rr.namelen, ri->rri_rr.rrtype,
0645
2020-07-15
pjp
(void *)rdata, ri->rri_rr.ttl, ri->rri_rr.buflen)) == NULL) {
0646
2020-07-10
pjp
dolog(LOG_ERR, "cache insertion failed 2\n");
0647
2020-07-10
pjp
free(rdata);
0648
2020-07-12
pjp
pack32((char *)&ri->u.s.read, 1);
0649
2020-07-10
pjp
continue;
0650
2020-07-10
pjp
}
0651
2020-07-18
pjp
0652
2020-07-18
pjp
if (unpack32((char *)&ri->rri_rr.authentic) == 1)
0653
2020-07-18
pjp
flag_rr(rbt);
0654
2020-07-10
pjp
0655
2020-07-12
pjp
pack32((char *)&ri->u.s.read, 1);
0656
2020-07-12
pjp
} /* if */
0657
2020-07-10
pjp
} /* for */
0658
2020-07-12
pjp
cfg->shptr2[cfg->shptr2size - 16] = ' ';
0659
2020-07-10
pjp
0660
2020-07-10
pjp
break;
0661
2020-07-10
pjp
0662
2020-07-10
pjp
default:
0663
2020-07-10
pjp
break;
0664
2020-07-10
pjp
}
0665
2020-07-10
pjp
imsg_free(&imsg);
0666
2020-07-10
pjp
break;
0667
2020-07-10
pjp
} /* if */
0668
2020-07-10
pjp
} /* for (;;) */
0669
2020-07-10
pjp
} /* FD_ISSET...bpibuf */
0670
2020-07-10
pjp
0671
2020-07-10
pjp
} /* for (;;) */
0672
2020-07-10
pjp
0673
2020-07-03
pjp
/* NOTREACHED */
0674
2020-07-01
pjp
}
0675
2020-07-01
pjp
0676
2020-07-01
pjp
void
0677
2020-07-06
pjp
forwardthis(ddDB *db, struct cfg *cfg, int so, struct sforward *sforward)
0678
2020-07-01
pjp
{
0679
2020-07-06
pjp
struct question *q;
0680
2020-07-06
pjp
struct sreply sreply;
0681
2020-07-06
pjp
struct reply_logic *rl = NULL;
0682
2020-07-06
pjp
struct sockaddr_storage *from = NULL;
0683
2020-07-06
pjp
struct dns_header *dh;
0684
2020-07-06
pjp
struct rbtree *rbt = NULL;
0685
2020-07-06
pjp
0686
2020-07-06
pjp
char buf[512];
0687
2020-07-06
pjp
char replystring[DNS_MAXNAME + 1];
0688
2020-07-16
pjp
char savednsname[DNS_MAXNAME];
0689
2020-07-06
pjp
static char *replybuf = NULL;
0690
2020-07-06
pjp
int len, slen;
0691
2020-07-06
pjp
0692
2020-07-06
pjp
int fromlen, returnval, lzerrno;
0693
2020-07-06
pjp
int istcp = (so == -1 ? 0 : 1);
0694
2020-07-21
pjp
int sretlen;
0695
2020-07-06
pjp
0696
2020-07-03
pjp
int found = 0;
0697
2020-07-01
pjp
time_t now;
0698
2020-07-01
pjp
char *p;
0699
2020-07-03
pjp
socklen_t namelen;
0700
2020-07-08
pjp
time_t highexpire;
0701
2020-07-06
pjp
0702
2020-07-08
pjp
#if __OpenBSD__
0703
2020-07-08
pjp
highexpire = 67768036191673199;
0704
2020-07-08
pjp
#else
0705
2020-07-08
pjp
highexpire = 2147483647;
0706
2020-07-08
pjp
#endif
0707
2020-07-08
pjp
0708
2020-07-06
pjp
if (replybuf == NULL) {
0709
2020-07-06
pjp
replybuf = calloc(1, 0xffff + 2);
0710
2020-07-06
pjp
if (replybuf == NULL) {
0711
2020-07-06
pjp
dolog(LOG_INFO, "calloc: %s\n", strerror(errno));
0712
2020-07-06
pjp
ddd_shutdown();
0713
2020-07-06
pjp
exit(1);
0714
2020-07-06
pjp
}
0715
2020-07-06
pjp
} else
0716
2020-07-06
pjp
memset(replybuf, 0, 0xffff + 2);
0717
2020-07-01
pjp
0718
2020-07-01
pjp
now = time(NULL);
0719
2020-07-03
pjp
p = sforward->buf;
0720
2020-07-01
pjp
0721
2020-07-01
pjp
SLIST_FOREACH_SAFE(fwq1, &fwqhead, entries, fwq2) {
0722
2020-07-01
pjp
if (difftime(now, fwq1->time) > 15) {
0723
2020-07-01
pjp
SLIST_REMOVE(&fwqhead, fwq1, forwardqueue, entries);
0724
2020-07-08
pjp
if (fwq1->returnso != -1) {
0725
2020-07-03
pjp
close(fwq1->returnso);
0726
2020-07-08
pjp
fwq1->returnso = -1;
0727
2020-07-08
pjp
}
0728
2020-07-08
pjp
if (fwq1->so != -1)
0729
2020-07-08
pjp
close(fwq1->so);
0730
2020-07-08
pjp
0731
2020-07-03
pjp
if (fwq1->tsigkey)
0732
2020-07-03
pjp
free(fwq1->tsigkey);
0733
2020-07-03
pjp
free(fwq1);
0734
2020-07-01
pjp
continue;
0735
2020-07-01
pjp
}
0736
2020-07-01
pjp
0737
2020-07-03
pjp
found = 0;
0738
2020-07-03
pjp
switch (fwq1->oldfamily) {
0739
2020-07-03
pjp
case AF_INET:
0740
2020-07-03
pjp
if (memcmp(&fwq1->oldhost4.sin_addr.s_addr,
0741
2020-07-03
pjp
&sforward->from4.sin_addr.s_addr,
0742
2020-07-03
pjp
sizeof(struct in_addr)) == 0 &&
0743
2020-07-03
pjp
fwq1->oldport == sforward->rport &&
0744
2020-07-03
pjp
fwq1->oldid == sforward->header.id) {
0745
2020-07-03
pjp
/* found, break... */
0746
2020-07-03
pjp
found = 1;
0747
2020-07-03
pjp
}
0748
2020-07-01
pjp
break;
0749
2020-07-03
pjp
case AF_INET6:
0750
2020-07-03
pjp
if (memcmp(&fwq1->oldhost6.sin6_addr,
0751
2020-07-03
pjp
&sforward->from6.sin6_addr, 16) == 0 &&
0752
2020-07-03
pjp
fwq1->oldport == sforward->rport &&
0753
2020-07-03
pjp
fwq1->oldid == sforward->header.id) {
0754
2020-07-03
pjp
/* found, break... */
0755
2020-07-03
pjp
found = 1;
0756
2020-07-03
pjp
}
0757
2020-07-03
pjp
break;
0758
2020-07-01
pjp
}
0759
2020-07-03
pjp
0760
2020-07-03
pjp
if (found)
0761
2020-07-03
pjp
break;
0762
2020-06-30
pjp
}
0763
2020-06-30
pjp
0764
2020-07-01
pjp
if (fwq1 == NULL) {
0765
2020-07-06
pjp
int count;
0766
2020-07-06
pjp
0767
2020-07-06
pjp
if (! cache)
0768
2020-07-06
pjp
goto newqueue;
0769
2020-07-16
pjp
0770
2020-07-16
pjp
/* set our name to lower case for db work */
0771
2020-07-16
pjp
memcpy(&savednsname, sforward->buf, sforward->buflen);
0772
2020-07-16
pjp
if (lower_dnsname(sforward->buf, sforward->buflen) == -1) {
0773
2020-07-16
pjp
dolog(LOG_INFO, "lower_dnsname failed, drop\n");
0774
2020-07-16
pjp
return;
0775
2020-07-16
pjp
}
0776
2020-07-06
pjp
0777
2020-07-06
pjp
/* check cache and expire it, then send if it remains */
0778
2020-07-06
pjp
if ((count = expire_rr(db, sforward->buf, sforward->buflen,
0779
2020-07-08
pjp
ntohs(sforward->type), now)) != 0) {
0780
2020-07-08
pjp
dolog(LOG_INFO, "Forward CACHE expired %d records\n", count);
0781
2020-07-10
pjp
rbt = find_rrset(db, sforward->buf, sforward->buflen);
0782
2020-07-10
pjp
if (rbt == NULL) {
0783
2020-07-10
pjp
dolog(LOG_INFO, "no such record in our cache, skip\n");
0784
2020-07-10
pjp
goto newqueue;
0785
2020-07-10
pjp
}
0786
2020-07-06
pjp
}
0787
2020-07-06
pjp
/* sforward->type is in netbyte order */
0788
2020-07-06
pjp
if (Lookup_zone(db, sforward->buf, sforward->buflen,
0789
2020-07-06
pjp
ntohs(sforward->type), 0) != NULL) {
0790
2020-07-06
pjp
/* we have a cache */
0791
2020-07-06
pjp
/* build a pseudo question packet */
0792
2020-07-06
pjp
dh = (struct dns_header *)&buf[0];
0793
2020-07-06
pjp
pack16((char *)&dh->id, sforward->header.id);
0794
2020-07-06
pjp
p = (char *)&dh[1];
0795
2020-07-06
pjp
0796
2020-07-16
pjp
/* make sure we reply as it was given */
0797
2020-07-16
pjp
pack(p, savednsname, sforward->buflen);
0798
2020-07-06
pjp
p += sforward->buflen;
0799
2020-07-06
pjp
pack16(p, sforward->type);
0800
2020-07-06
pjp
p += sizeof(uint16_t);
0801
2020-07-06
pjp
pack16(p, htons(DNS_CLASS_IN));
0802
2020-07-06
pjp
p += sizeof(uint16_t);
0803
2020-07-06
pjp
0804
2020-07-06
pjp
len = (p - buf);
0805
2020-07-06
pjp
/* pseudo question packet done */
0806
2020-07-06
pjp
0807
2020-07-06
pjp
switch (sforward->family) {
0808
2020-07-06
pjp
case AF_INET:
0809
2020-07-06
pjp
from = (struct sockaddr_storage *)&sforward->from4;
0810
2020-07-06
pjp
fromlen = sizeof(struct sockaddr_in);
0811
2020-07-06
pjp
break;
0812
2020-07-06
pjp
case AF_INET6:
0813
2020-07-06
pjp
from = (struct sockaddr_storage *)&sforward->from6;
0814
2020-07-06
pjp
fromlen = sizeof(struct sockaddr_in6);
0815
2020-07-06
pjp
break;
0816
2020-07-06
pjp
default:
0817
2020-07-06
pjp
dolog(LOG_INFO, "unknown address family, drop\n");
0818
2020-07-06
pjp
return;
0819
2020-07-06
pjp
}
0820
2020-07-06
pjp
0821
2020-07-06
pjp
if (sforward->havemac)
0822
2020-07-16
pjp
q = build_fake_question(savednsname, sforward->buflen,
0823
2020-07-06
pjp
sforward->type, sforward->tsigname,
0824
2020-07-06
pjp
sforward->tsignamelen);
0825
2020-07-06
pjp
else
0826
2020-07-16
pjp
q = build_fake_question(savednsname, sforward->buflen,
0827
2020-07-06
pjp
sforward->type, NULL, 0);
0828
2020-07-06
pjp
0829
2020-07-06
pjp
0830
2020-07-06
pjp
if (q == NULL) {
0831
2020-07-06
pjp
dolog(LOG_INFO, "build_fake_question failed\n");
0832
2020-07-06
pjp
goto newqueue;
0833
2020-07-06
pjp
}
0834
2020-07-06
pjp
0835
2020-07-06
pjp
q->aa = 0;
0836
2020-07-06
pjp
q->rd = 1;
0837
2020-07-06
pjp
0838
2020-07-06
pjp
rbt = lookup_zone(db, q, &returnval, &lzerrno, (char *)&replystring, sizeof(replystring));
0839
2020-07-06
pjp
if (rbt == NULL) {
0840
2020-07-06
pjp
dolog(LOG_INFO, "lookup_zone failed\n");
0841
2020-07-20
pjp
free_question(q);
0842
2020-07-06
pjp
goto newqueue;
0843
2020-07-06
pjp
}
0844
2020-07-06
pjp
0845
2020-07-06
pjp
q->edns0len = sforward->edns0len;
0846
2020-07-08
pjp
if (dnssec && sforward->dnssecok)
0847
2020-07-08
pjp
q->dnssecok = 1;
0848
2020-07-06
pjp
0849
2020-07-20
pjp
/* we have a cache but it's not DNSSEC'ed */
0850
2020-07-20
pjp
if (q->dnssecok && ! (rbt->flags & RBT_DNSSEC)) {
0851
2020-07-20
pjp
/* expire the record and grab it anew */
0852
2020-07-20
pjp
expire_rr(db, sforward->buf, sforward->buflen,
0853
2020-07-20
pjp
ntohs(sforward->type), highexpire);
0854
2020-07-20
pjp
free_question(q);
0855
2020-07-20
pjp
goto newqueue;
0856
2020-07-20
pjp
}
0857
2020-07-20
pjp
0858
2020-07-21
pjp
q->rawsocket = 1;
0859
2020-07-06
pjp
build_reply(&sreply,
0860
2020-07-21
pjp
(istcp ? so : -1), buf, len, q,
0861
2020-07-21
pjp
(struct sockaddr *)from, fromlen,
0862
2020-07-06
pjp
rbt, NULL, 0xff, istcp, 0, replybuf);
0863
2020-07-06
pjp
0864
2020-07-06
pjp
0865
2020-07-06
pjp
/* from delphinusdnsd.c */
0866
2020-07-06
pjp
for (rl = &rlogic[0]; rl->rrtype != 0; rl++) {
0867
2020-07-06
pjp
if (rl->rrtype == ntohs(q->hdr->qtype)) {
0868
2020-07-21
pjp
slen = (*rl->reply)(&sreply, &sretlen, cfg->db);
0869
2020-07-21
pjp
switch (from->ss_family) {
0870
2020-07-21
pjp
case AF_INET:
0871
2020-07-21
pjp
rawsend(cfg->raw[0], sreply.replybuf, sretlen, &sforward->from4, sforward->oldsel, cfg);
0872
2020-07-21
pjp
break;
0873
2020-07-21
pjp
case AF_INET6:
0874
2020-07-21
pjp
rawsend6(cfg->raw[1], sreply.replybuf, sretlen, &sforward->from6, sforward->oldsel, cfg);
0875
2020-07-21
pjp
break;
0876
2020-07-21
pjp
}
0877
2020-07-06
pjp
if (slen < 0) {
0878
2020-07-08
pjp
/*
0879
2020-07-08
pjp
* we may have a non-dnssec answer cached without RRSIG
0880
2020-07-08
pjp
* at this point the rl->reply will fail.. expire it
0881
2020-07-08
pjp
* and fill it with dnssec data if available
0882
2020-07-08
pjp
*/
0883
2020-07-10
pjp
expire_rr(db, q->hdr->name, q->hdr->namelen,
0884
2020-07-10
pjp
ntohs(q->hdr->qtype), highexpire);
0885
2020-07-10
pjp
free_question(q);
0886
2020-07-10
pjp
goto newqueue;
0887
2020-07-10
pjp
}
0888
2020-07-10
pjp
break;
0889
2020-07-10
pjp
} /* if rl->rrtype == */
0890
2020-07-10
pjp
}
0891
2020-07-10
pjp
0892
2020-07-10
pjp
if (rl->rrtype == 0) {
0893
2020-07-15
pjp
/* https://en.wikipedia.org/wiki/List_of_DNS_record_types */
0894
2020-07-15
pjp
switch (ntohs(q->hdr->qtype)) {
0895
2020-07-15
pjp
/* FALLTHROUGH for all listed */
0896
2020-07-15
pjp
case 18: /* AFSDB */ case 42: /* APL */ case 257: /* CAA */
0897
2020-07-15
pjp
case 60: /* CDNSKEY */ case 59: /* CDS */ case 37: /* CERT */
0898
2020-07-15
pjp
case 62: /* CSYNC */ case 49: /* DHCID */ case 39: /* DNAME */
0899
2020-07-15
pjp
case 108: /* EUI48 */ case 109: /* EUI64 */ case 13: /* HINFO */
0900
2020-07-15
pjp
case 55: /* HIP */ case 45: /* IPSECKEY */ case 25: /* KEY */
0901
2020-07-15
pjp
case 36: /* KX */ case 29: /* LOC */ case 61: /* OPENPGPKEY */
0902
2020-07-15
pjp
case 17: /* RP */ case 24: /* SIG */ case 53: /* SMIMEA */
0903
2020-07-15
pjp
case 249: /* TKEY */ case 256: /* URI */
0904
2020-07-15
pjp
#if DEBUG
0905
2020-07-15
pjp
dolog(LOG_INFO, "replying generic RR %d\n",
0906
2020-07-15
pjp
ntohs(q->hdr->qtype));
0907
2020-07-15
pjp
#endif
0908
2020-07-21
pjp
if (reply_generic(&sreply, &sretlen, cfg->db) < 0) {
0909
2020-07-15
pjp
expire_rr(db, q->hdr->name, q->hdr->namelen,
0910
2020-07-15
pjp
ntohs(q->hdr->qtype), highexpire);
0911
2020-07-15
pjp
free_question(q);
0912
2020-07-15
pjp
goto newqueue;
0913
2020-07-15
pjp
}
0914
2020-07-23
pjp
switch (from->ss_family) {
0915
2020-07-23
pjp
case AF_INET:
0916
2020-07-23
pjp
rawsend(cfg->raw[0], sreply.replybuf, sretlen, &sforward->from4, sforward->oldsel, cfg);
0917
2020-07-23
pjp
break;
0918
2020-07-23
pjp
case AF_INET6:
0919
2020-07-23
pjp
rawsend6(cfg->raw[1], sreply.replybuf, sretlen, &sforward->from6, sforward->oldsel, cfg);
0920
2020-07-23
pjp
break;
0921
2020-07-23
pjp
}
0922
2020-07-23
pjp
0923
2020-07-15
pjp
0924
2020-07-15
pjp
break;
0925
2020-07-15
pjp
default:
0926
2020-07-15
pjp
dolog(LOG_INFO,
0927
2020-07-15
pjp
"no answer in our cache, skip to newqueue\n");
0928
2020-07-15
pjp
free_question(q);
0929
2020-07-15
pjp
goto newqueue;
0930
2020-07-15
pjp
break;
0931
2020-07-15
pjp
}
0932
2020-07-15
pjp
0933
2020-07-15
pjp
/* NOTREACHED */
0934
2020-07-08
pjp
}
0935
2020-07-08
pjp
0936
2020-07-08
pjp
free_question(q);
0937
2020-07-06
pjp
/* at this point we return everythign is done */
0938
2020-07-06
pjp
return;
0939
2020-07-06
pjp
}
0940
2020-07-06
pjp
0941
2020-07-01
pjp
/* create a new queue and send it */
0942
2020-07-06
pjp
newqueue:
0943
2020-07-16
pjp
/*
0944
2020-07-16
pjp
* we're out of cache territory, let's mutilate our
0945
2020-07-16
pjp
* our dns question a little bit...
0946
2020-07-16
pjp
*/
0947
2020-07-03
pjp
0948
2020-07-16
pjp
0949
2020-07-04
pjp
TAILQ_FOREACH(fw2, &forwardhead, forward_entry) {
0950
2020-07-03
pjp
if (fw2->active == 1)
0951
2020-07-03
pjp
break;
0952
2020-07-03
pjp
}
0953
2020-07-03
pjp
0954
2020-07-03
pjp
if (fw2 == NULL) {
0955
2020-07-04
pjp
TAILQ_FOREACH(fwp, &forwardhead, forward_entry) {
0956
2020-07-03
pjp
if (fwp != fw2) {
0957
2020-07-03
pjp
fw2 = fwp;
0958
2020-07-03
pjp
fw2->active = 1;
0959
2020-07-03
pjp
break;
0960
2020-07-03
pjp
}
0961
2020-07-03
pjp
}
0962
2020-07-03
pjp
0963
2020-07-03
pjp
if (fw2 == NULL) {
0964
2020-07-03
pjp
dolog(LOG_INFO, "FORWARD: no suitable destinations found\n");
0965
2020-07-03
pjp
return;
0966
2020-07-03
pjp
}
0967
2020-07-03
pjp
0968
2020-07-03
pjp
}
0969
2020-07-01
pjp
0970
2020-07-03
pjp
fwq1 = calloc(1, sizeof(struct forwardqueue));
0971
2020-07-03
pjp
if (fwq1 == NULL) {
0972
2020-07-03
pjp
dolog(LOG_INFO, "calloc: %s\n", strerror(errno));
0973
2020-07-03
pjp
return;
0974
2020-07-03
pjp
}
0975
2020-07-16
pjp
memcpy(&fwq1->orig_dnsname, sforward->buf, sforward->buflen);
0976
2020-07-16
pjp
0977
2020-07-16
pjp
if (randomize_dnsname(sforward->buf, sforward->buflen) == -1) {
0978
2020-07-16
pjp
dolog(LOG_INFO, "randomize_dnsname failed\n");
0979
2020-07-16
pjp
free (fwq1);
0980
2020-07-16
pjp
return;
0981
2020-07-16
pjp
}
0982
2020-07-16
pjp
0983
2020-07-16
pjp
memcpy(&fwq1->dnsname, sforward->buf, sforward->buflen);
0984
2020-07-16
pjp
fwq1->dnsnamelen = sforward->buflen;
0985
2020-07-16
pjp
0986
2020-07-03
pjp
fwq1->oldfamily = sforward->family;
0987
2020-07-03
pjp
fwq1->oldsel = sforward->oldsel;
0988
2020-07-03
pjp
0989
2020-07-03
pjp
switch (sforward->family) {
0990
2020-07-03
pjp
case AF_INET:
0991
2020-07-03
pjp
memcpy(&fwq1->oldhost4, &sforward->from4, sizeof(struct sockaddr_in));
0992
2020-07-03
pjp
break;
0993
2020-07-03
pjp
case AF_INET6:
0994
2020-07-14
pjp
memcpy(&fwq1->oldhost6, &sforward->from6, sizeof(struct sockaddr_in6));
0995
2020-07-03
pjp
break;
0996
2020-07-03
pjp
}
0997
2020-07-03
pjp
0998
2020-07-03
pjp
fwq1->oldport = sforward->rport;
0999
2020-07-03
pjp
fwq1->oldid = sforward->header.id;
1000
2020-07-03
pjp
1001
2020-07-03
pjp
fwq1->port = fw2->destport;
1002
2020-07-04
pjp
fwq1->cur_forwardentry = fw2;
1003
2020-07-03
pjp
fwq1->longid = arc4random();
1004
2020-07-03
pjp
fwq1->id = fwq1->longid % 0xffff;
1005
2020-07-03
pjp
fwq1->time = now;
1006
2020-07-03
pjp
if (so == -1)
1007
2020-07-03
pjp
fwq1->istcp = 0;
1008
2020-07-03
pjp
else
1009
2020-07-03
pjp
fwq1->istcp = 1;
1010
2020-07-03
pjp
1011
2020-07-03
pjp
1012
2020-07-03
pjp
memcpy((char *)&fwq1->host, (char *)&fw2->host, sizeof(struct sockaddr_storage));
1013
2020-07-03
pjp
1014
2020-07-03
pjp
fwq1->family = fw2->family;
1015
2020-07-03
pjp
if (fw2->tsigkey) {
1016
2020-07-03
pjp
fwq1->tsigkey = strdup(fw2->tsigkey);
1017
2020-07-03
pjp
if (fwq1->tsigkey == NULL) {
1018
2020-07-03
pjp
dolog(LOG_ERR, "FORWARD strdup: %s\n", strerror(errno));
1019
2020-07-03
pjp
free(fwq1);
1020
2020-07-03
pjp
return;
1021
2020-07-03
pjp
}
1022
2020-07-03
pjp
} else
1023
2020-07-03
pjp
fwq1->tsigkey = NULL;
1024
2020-07-03
pjp
1025
2020-07-03
pjp
/* connect the UDP sockets */
1026
2020-07-03
pjp
1027
2020-07-03
pjp
fwq1->so = socket(fw2->family, (fwq1->istcp != 1) ? SOCK_DGRAM : SOCK_STREAM, 0);
1028
2020-07-03
pjp
if (fwq1->so < 0) {
1029
2020-07-03
pjp
dolog(LOG_ERR, "FORWARD socket: %s\n", strerror(errno));
1030
2020-07-03
pjp
if (fwq1->tsigkey)
1031
2020-07-03
pjp
free(fwq1->tsigkey);
1032
2020-07-03
pjp
free(fwq1);
1033
2020-07-03
pjp
return;
1034
2020-07-03
pjp
}
1035
2020-07-03
pjp
1036
2020-07-03
pjp
namelen = (fw2->family == AF_INET) ? sizeof(struct sockaddr_in) \
1037
2020-07-03
pjp
: sizeof(struct sockaddr_in6);
1038
2020-07-03
pjp
1039
2020-07-03
pjp
if (connect(fwq1->so, (struct sockaddr *)&fwq1->host, namelen) < 0) {
1040
2020-07-03
pjp
dolog(LOG_ERR, "FORWARD can't connect: %s\n", strerror(errno));
1041
2020-07-04
pjp
1042
2020-07-04
pjp
changeforwarder(fwq1);
1043
2020-07-04
pjp
1044
2020-07-03
pjp
if (fwq1->tsigkey)
1045
2020-07-03
pjp
free(fwq1->tsigkey);
1046
2020-07-03
pjp
1047
2020-07-03
pjp
free(fwq1);
1048
2020-07-03
pjp
return;
1049
2020-07-03
pjp
}
1050
2020-07-03
pjp
1051
2020-07-03
pjp
fwq1->returnso = so;
1052
2020-07-03
pjp
1053
2020-07-03
pjp
/* are we TSIG'ed? save key and mac */
1054
2020-07-03
pjp
if (sforward->havemac) {
1055
2020-07-03
pjp
fwq1->haveoldmac = 1;
1056
2020-07-03
pjp
memcpy(&fwq1->oldkeyname, &sforward->tsigname, sizeof(fwq1->oldkeyname));
1057
2020-07-03
pjp
fwq1->oldkeynamelen = sforward->tsignamelen;
1058
2020-07-03
pjp
memcpy(&fwq1->oldmac, &sforward->mac, sizeof(fwq1->oldmac));
1059
2020-07-03
pjp
fwq1->tsigtimefudge = sforward->tsigtimefudge;
1060
2020-07-03
pjp
} else
1061
2020-07-03
pjp
fwq1->haveoldmac = 0;
1062
2020-07-03
pjp
1063
2020-07-03
pjp
SLIST_INSERT_HEAD(&fwqhead, fwq1, entries);
1064
2020-07-03
pjp
1065
2020-07-03
pjp
sendit(fwq1, sforward);
1066
2020-07-01
pjp
} else {
1067
2020-07-01
pjp
/* resend this one */
1068
2020-07-01
pjp
1069
2020-07-01
pjp
fwq1->time = now;
1070
2020-07-03
pjp
sendit(fwq1, sforward);
1071
2020-07-01
pjp
}
1072
2020-07-01
pjp
1073
2020-07-03
pjp
return;
1074
2020-07-03
pjp
}
1075
2020-07-03
pjp
1076
2020-07-03
pjp
void
1077
2020-07-03
pjp
sendit(struct forwardqueue *fwq, struct sforward *sforward)
1078
2020-07-03
pjp
{
1079
2020-07-03
pjp
struct dns_header *dh;
1080
2020-07-03
pjp
struct question *q;
1081
2020-07-16
pjp
1082
2020-07-03
pjp
char *buf, *p, *packet;
1083
2020-07-03
pjp
char *tsigname;
1084
2020-07-16
pjp
1085
2020-07-03
pjp
int len = 0, outlen;
1086
2020-07-03
pjp
int tsignamelen = 0;
1087
2020-07-03
pjp
1088
2020-07-03
pjp
buf = calloc(1, (0xffff + 2));
1089
2020-07-03
pjp
if (buf == NULL) {
1090
2020-07-03
pjp
dolog(LOG_INFO, "calloc: %s\n", strerror(errno));
1091
2020-07-03
pjp
return;
1092
2020-07-03
pjp
}
1093
2020-07-03
pjp
1094
2020-07-03
pjp
if (fwq->tsigkey) {
1095
2020-07-03
pjp
tsigname = dns_label(fwq->tsigkey, &tsignamelen);
1096
2020-07-03
pjp
if (tsigname == NULL) {
1097
2020-07-03
pjp
dolog(LOG_INFO, "dns_label failed\n");
1098
2020-07-03
pjp
free(buf);
1099
2020-07-03
pjp
return;
1100
2020-07-03
pjp
}
1101
2020-07-03
pjp
} else {
1102
2020-07-03
pjp
tsigname = NULL;
1103
2020-07-03
pjp
tsignamelen = 0;
1104
2020-07-03
pjp
}
1105
2020-07-03
pjp
1106
2020-07-16
pjp
q = build_fake_question(fwq->orig_dnsname, fwq->dnsnamelen, sforward->type, tsigname, tsignamelen);
1107
2020-07-03
pjp
1108
2020-07-03
pjp
if (q == NULL) {
1109
2020-07-03
pjp
dolog(LOG_INFO, "build_fake_question failed\n");
1110
2020-07-03
pjp
free(buf);
1111
2020-07-03
pjp
return;
1112
2020-07-03
pjp
}
1113
2020-07-03
pjp
1114
2020-07-03
pjp
q->edns0len = sforward->edns0len;
1115
2020-07-10
pjp
if (q->edns0len > 16384)
1116
2020-07-10
pjp
q->edns0len = 16384;
1117
2020-07-01
pjp
1118
2020-07-03
pjp
if (fwq->istcp == 1) {
1119
2020-07-03
pjp
p = &buf[2];
1120
2020-07-03
pjp
} else
1121
2020-07-03
pjp
p = &buf[0];
1122
2020-07-03
pjp
1123
2020-07-03
pjp
packet = p;
1124
2020-07-03
pjp
dh = (struct dns_header *)p;
1125
2020-07-03
pjp
1126
2020-07-03
pjp
memcpy((char *)dh, (char *)&sforward->header, sizeof(struct dns_header));
1127
2020-07-03
pjp
dh->id = htons(fwq->id);
1128
2020-07-03
pjp
dh->question = htons(1);
1129
2020-07-03
pjp
dh->answer = 0; dh->nsrr = 0; dh->additional = htons(1);
1130
2020-07-03
pjp
1131
2020-07-03
pjp
memset((char *)&dh->query, 0, sizeof(dh->query));
1132
2020-07-03
pjp
1133
2020-07-03
pjp
SET_DNS_QUERY(dh);
1134
2020-07-03
pjp
SET_DNS_RECURSION(dh);
1135
2020-07-03
pjp
HTONS(dh->query);
1136
2020-07-03
pjp
1137
2020-07-03
pjp
p += sizeof(struct dns_header);
1138
2020-07-03
pjp
len += sizeof(struct dns_header);
1139
2020-07-03
pjp
1140
2020-07-03
pjp
memcpy(p, sforward->buf, sforward->buflen);
1141
2020-07-03
pjp
p += sforward->buflen;
1142
2020-07-03
pjp
len += sforward->buflen;
1143
2020-07-03
pjp
1144
2020-07-03
pjp
pack16(p, sforward->type);
1145
2020-07-03
pjp
p += 2;
1146
2020-07-03
pjp
pack16(p, sforward->class);
1147
2020-07-03
pjp
1148
2020-07-03
pjp
p += 2;
1149
2020-07-03
pjp
len += 4; /* type and class */
1150
2020-07-03
pjp
1151
2020-07-03
pjp
/* additionals */
1152
2020-07-03
pjp
1153
2020-07-08
pjp
if (dnssec && sforward->dnssecok) {
1154
2020-07-03
pjp
q->dnssecok = 1;
1155
2020-07-08
pjp
}
1156
2020-07-03
pjp
1157
2020-07-03
pjp
outlen = additional_opt(q, packet, 0xffff, len);
1158
2020-07-03
pjp
len = outlen;
1159
2020-07-03
pjp
1160
2020-07-03
pjp
if (tsigname) {
1161
2020-07-03
pjp
outlen = additional_tsig(q, packet, 0xffff, len, 1, 0, NULL);
1162
2020-07-03
pjp
dh->additional = htons(2);
1163
2020-07-03
pjp
}
1164
2020-07-03
pjp
1165
2020-07-03
pjp
memcpy(&fwq->mac, &q->tsig.tsigmac, 32);
1166
2020-07-03
pjp
1167
2020-07-03
pjp
len = outlen;
1168
2020-07-03
pjp
p = packet + outlen;
1169
2020-07-03
pjp
1170
2020-07-03
pjp
if (fwq->istcp == 1) {
1171
2020-07-03
pjp
pack16(buf, htons(len));
1172
2020-07-08
pjp
if (fwq->so != -1 && send(fwq->so, buf, len + 2, 0) < 0) {
1173
2020-07-04
pjp
dolog(LOG_INFO, "send() failed changing forwarder: %s\n", strerror(errno));
1174
2020-07-04
pjp
changeforwarder(fwq);
1175
2020-07-04
pjp
}
1176
2020-07-04
pjp
} else {
1177
2020-07-08
pjp
if (fwq->so != -1 && send(fwq->so, buf, len, 0) < 0) {
1178
2020-07-04
pjp
dolog(LOG_INFO, "send() failed (udp) changing forwarder %s\n", strerror(errno));
1179
2020-07-04
pjp
changeforwarder(fwq);
1180
2020-07-04
pjp
}
1181
2020-07-04
pjp
}
1182
2020-07-03
pjp
1183
2020-07-03
pjp
1184
2020-07-03
pjp
free(buf);
1185
2020-07-03
pjp
free_question(q);
1186
2020-07-03
pjp
1187
2020-07-03
pjp
return;
1188
2020-07-03
pjp
}
1189
2020-07-03
pjp
1190
2020-07-03
pjp
void
1191
2020-07-06
pjp
returnit(ddDB *db, struct cfg *cfg, struct forwardqueue *fwq, char *rbuf, int rlen, struct imsgbuf *ibuf)
1192
2020-07-03
pjp
{
1193
2020-07-03
pjp
struct timeval tv;
1194
2020-07-03
pjp
struct dns_header *dh;
1195
2020-07-03
pjp
struct question *q;
1196
2020-07-14
pjp
static struct pkt_imsg *pi = NULL;
1197
2020-07-14
pjp
struct pkt_imsg *pi0;
1198
2020-07-03
pjp
struct imsg imsg;
1199
2020-07-03
pjp
1200
2020-07-06
pjp
static char *buf = NULL;
1201
2020-07-10
pjp
char *p;
1202
2020-07-03
pjp
1203
2020-07-08
pjp
int so;
1204
2020-07-10
pjp
int i; /* = v/r */
1205
2020-07-10
pjp
int sel, rc;
1206
2020-07-03
pjp
int len = 0;
1207
2020-07-03
pjp
int outlen;
1208
2020-07-03
pjp
1209
2020-07-03
pjp
fd_set rset;
1210
2020-07-03
pjp
ssize_t n, datalen;
1211
2020-07-03
pjp
1212
2020-07-03
pjp
if (buf == NULL) {
1213
2020-07-06
pjp
buf = calloc(1, 0xffff + 2);
1214
2020-07-06
pjp
if (buf == NULL) {
1215
2020-07-06
pjp
dolog(LOG_INFO, "calloc: %s\n", strerror(errno));
1216
2020-07-06
pjp
return;
1217
2020-07-06
pjp
}
1218
2020-07-06
pjp
} else
1219
2020-07-06
pjp
memset(buf, 0, 0xffff + 2);
1220
2020-07-03
pjp
1221
2020-07-03
pjp
if (fwq->istcp == 1) {
1222
2020-07-03
pjp
p = &buf[2];
1223
2020-07-03
pjp
len = 2;
1224
2020-07-03
pjp
} else {
1225
2020-07-03
pjp
p = buf;
1226
2020-07-21
pjp
so = -1;
1227
2020-07-03
pjp
}
1228
2020-07-03
pjp
1229
2020-07-03
pjp
if (rlen <= sizeof(struct dns_header)) {
1230
2020-07-03
pjp
dolog(LOG_INFO, "FORWARD returnit, returned packet is too small");
1231
2020-07-03
pjp
return;
1232
2020-07-03
pjp
}
1233
2020-07-03
pjp
1234
2020-07-03
pjp
memcpy(p, rbuf, rlen);
1235
2020-07-03
pjp
dh = (struct dns_header *)p;
1236
2020-07-03
pjp
1237
2020-07-03
pjp
if (! (ntohs(dh->query) & DNS_REPLY)) {
1238
2020-07-03
pjp
dolog(LOG_INFO, "FORWARD returnit, returned packet is not a reply\n");
1239
2020-07-03
pjp
return;
1240
2020-07-03
pjp
}
1241
2020-07-03
pjp
1242
2020-07-03
pjp
if (dh->id != htons(fwq->id)) {
1243
2020-07-03
pjp
/* returned packet ID does not match */
1244
2020-07-03
pjp
dolog(LOG_INFO, "FORWARD returnit, returned packet ID does not match %d vs %d\n", ntohs(dh->id), fwq->id);
1245
2020-07-03
pjp
return;
1246
2020-07-03
pjp
}
1247
2020-07-03
pjp
1248
2020-07-16
pjp
if (rlen < (sizeof(struct dns_header) + fwq->dnsnamelen)) {
1249
2020-07-16
pjp
/* the packet size can't fit the question name */
1250
2020-07-16
pjp
dolog(LOG_INFO, "FORWARD returnit, question name can't fit in packet thus it gets dropped\n");
1251
2020-07-16
pjp
return;
1252
2020-07-16
pjp
} else {
1253
2020-07-17
pjp
if (strictx20i) {
1254
2020-07-17
pjp
if (memcmp((char *)&dh[1], fwq->dnsname, fwq->dnsnamelen) != 0) {
1255
2020-07-17
pjp
dolog(LOG_INFO, "reply for a question we didn't send, drop\n");
1256
2020-07-17
pjp
return;
1257
2020-07-17
pjp
}
1258
2020-07-17
pjp
} else {
1259
2020-07-17
pjp
if (memcasecmp((char *)&dh[1], fwq->dnsname, fwq->dnsnamelen) != 0) {
1260
2020-07-17
pjp
dolog(LOG_INFO, "reply for a question we didn't send, drop\n");
1261
2020-07-17
pjp
return;
1262
2020-07-17
pjp
}
1263
2020-07-17
pjp
1264
2020-07-16
pjp
}
1265
2020-07-16
pjp
}
1266
2020-07-16
pjp
1267
2020-07-16
pjp
1268
2020-07-14
pjp
/* send it on to our sandbox */
1269
2020-07-14
pjp
if (pi == NULL) {
1270
2020-07-14
pjp
pi = (struct pkt_imsg *)calloc(1, sizeof(struct pkt_imsg));
1271
2020-07-14
pjp
if (pi == NULL) {
1272
2020-07-14
pjp
dolog(LOG_INFO, "calloc: %s\n", strerror(errno));
1273
2020-07-14
pjp
return;
1274
2020-07-14
pjp
}
1275
2020-07-14
pjp
} else {
1276
2020-07-14
pjp
memset(pi, 0, sizeof(struct pkt_imsg));
1277
2020-07-14
pjp
}
1278
2020-07-14
pjp
1279
2020-07-14
pjp
memcpy(&pi->pkt_s.mac, &fwq->mac, sizeof(pi->pkt_s.mac));
1280
2020-07-14
pjp
1281
2020-07-08
pjp
if (fwq->istcp) {
1282
2020-07-14
pjp
pack32((char *)&pi->pkt_s.buflen, rlen);
1283
2020-07-08
pjp
} else {
1284
2020-07-14
pjp
if (rlen > (sizeof(struct pkt_imsg) - sizeof(pi->pkt_s))) {
1285
2020-07-14
pjp
dolog(LOG_INFO, "can't send UDP packet to parser, too big\n");
1286
2020-07-03
pjp
return;
1287
2020-07-03
pjp
}
1288
2020-07-08
pjp
1289
2020-07-14
pjp
memcpy(&pi->pkt_s.buf, p, rlen);
1290
2020-07-14
pjp
pack32((char *)&pi->pkt_s.buflen, rlen);
1291
2020-07-08
pjp
}
1292
2020-07-08
pjp
1293
2020-07-08
pjp
if (fwq->tsigkey)
1294
2020-07-14
pjp
pack32((char *)&pi->pkt_s.tsigcheck, 1);
1295
2020-07-11
pjp
else
1296
2020-07-14
pjp
pack32((char *)&pi->pkt_s.tsigcheck, 0);
1297
2020-07-03
pjp
1298
2020-07-08
pjp
if (cache)
1299
2020-07-14
pjp
pack32((char *)&pi->pkt_s.cache, 1);
1300
2020-07-08
pjp
else
1301
2020-07-14
pjp
pack32((char *)&pi->pkt_s.cache, 0);
1302
2020-07-08
pjp
1303
2020-07-08
pjp
if (fwq->istcp)
1304
2020-07-14
pjp
pack32((char *)&pi->pkt_s.istcp, 1);
1305
2020-07-08
pjp
else
1306
2020-07-14
pjp
pack32((char *)&pi->pkt_s.istcp, 0);
1307
2020-07-10
pjp
1308
2020-07-10
pjp
/* lock */
1309
2020-07-14
pjp
while (cfg->shptr3[cfg->shptr3size - 16] == '*')
1310
2020-07-10
pjp
usleep(arc4random() % 300);
1311
2020-07-08
pjp
1312
2020-07-14
pjp
cfg->shptr3[cfg->shptr3size - 16] = '*';
1313
2020-07-10
pjp
1314
2020-07-14
pjp
pi0 = (struct pkt_imsg *)&cfg->shptr3[0];
1315
2020-07-14
pjp
for (i = 0; i < SHAREDMEMSIZE3; i++, pi0++) {
1316
2020-07-14
pjp
if (unpack32((char *)&pi0->pkt_s.read) == 1) {
1317
2020-07-14
pjp
memcpy(pi0, pi, sizeof(struct pkt_imsg));
1318
2020-07-14
pjp
pack32((char *)&pi0->pkt_s.read, 0);
1319
2020-07-10
pjp
break;
1320
2020-07-10
pjp
}
1321
2020-07-10
pjp
}
1322
2020-07-10
pjp
1323
2020-07-10
pjp
if (imsg_compose(ibuf, IMSG_PARSE_MESSAGE, 0, 0, (fwq->istcp == 1) ? fwq->so : -1, &i, sizeof(i)) < 0) {
1324
2020-07-08
pjp
dolog(LOG_INFO, "imsg_compose: %s\n", strerror(errno));
1325
2020-07-14
pjp
cfg->shptr3[cfg->shptr3size - 16] = ' ';
1326
2020-07-08
pjp
return;
1327
2020-07-08
pjp
}
1328
2020-07-08
pjp
msgbuf_write(&ibuf->w);
1329
2020-07-10
pjp
1330
2020-07-14
pjp
cfg->shptr3[cfg->shptr3size - 16] = ' ';
1331
2020-07-08
pjp
1332
2020-07-08
pjp
for (;;) {
1333
2020-07-03
pjp
FD_ZERO(&rset);
1334
2020-07-03
pjp
FD_SET(ibuf->fd, &rset);
1335
2020-07-03
pjp
1336
2020-07-08
pjp
tv.tv_sec = 4;
1337
2020-07-03
pjp
tv.tv_usec = 0;
1338
2020-07-03
pjp
1339
2020-07-03
pjp
sel = select(ibuf->fd + 1, &rset, NULL, NULL, &tv);
1340
2020-07-03
pjp
1341
2020-07-03
pjp
if (sel < 0) {
1342
2020-07-03
pjp
dolog(LOG_ERR, "returnit internal error around select, drop\n");
1343
2020-07-08
pjp
continue;
1344
2020-07-03
pjp
}
1345
2020-07-03
pjp
if (sel == 0) {
1346
2020-07-03
pjp
dolog(LOG_ERR, "returnit internal error around select (timeout), drop\n");
1347
2020-07-10
pjp
return;
1348
2020-07-03
pjp
}
1349
2020-07-03
pjp
1350
2020-07-08
pjp
if (FD_ISSET(ibuf->fd, &rset)) {
1351
2020-07-10
pjp
if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) {
1352
2020-07-08
pjp
dolog(LOG_ERR, "returnit internal error around imsg_read, drop\n");
1353
2020-07-08
pjp
continue;
1354
2020-07-08
pjp
}
1355
2020-07-08
pjp
if (n == 0) {
1356
2020-07-08
pjp
dolog(LOG_INFO, "imsg peer died? shutting down\n");
1357
2020-07-08
pjp
ddd_shutdown();
1358
2020-07-08
pjp
exit(1);
1359
2020-07-08
pjp
}
1360
2020-07-08
pjp
1361
2020-07-08
pjp
} else {
1362
2020-07-08
pjp
/* the ibuf has no selectable fd */
1363
2020-07-08
pjp
continue;
1364
2020-07-03
pjp
}
1365
2020-07-08
pjp
1366
2020-07-03
pjp
1367
2020-07-03
pjp
for (;;) {
1368
2020-07-03
pjp
if ((n = imsg_get(ibuf, &imsg)) == -1) {
1369
2020-07-08
pjp
dolog(LOG_ERR, "returnit internal error around imsg_get, drop\n");
1370
2020-07-08
pjp
break;
1371
2020-07-03
pjp
}
1372
2020-07-03
pjp
if (n == 0) {
1373
2020-07-08
pjp
#if DEBUG
1374
2020-07-08
pjp
dolog(LOG_INFO, "n == 0, odd...\n");
1375
2020-07-08
pjp
#endif
1376
2020-07-08
pjp
break;
1377
2020-07-03
pjp
}
1378
2020-07-08
pjp
1379
2020-07-03
pjp
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
1380
2020-07-03
pjp
switch (imsg.hdr.type) {
1381
2020-07-10
pjp
case IMSG_PARSEERROR_MESSAGE:
1382
2020-07-10
pjp
if (datalen != sizeof(int)) {
1383
2020-07-11
pjp
dolog(LOG_ERR, "bad parsereply message, drop\n");
1384
2020-07-10
pjp
imsg_free(&imsg);
1385
2020-07-10
pjp
return;
1386
2020-07-10
pjp
}
1387
2020-07-08
pjp
1388
2020-07-10
pjp
memcpy(&rc, imsg.data, datalen);
1389
2020-07-08
pjp
1390
2020-07-10
pjp
if (rc != PARSE_RETURN_ACK) {
1391
2020-07-10
pjp
dolog(LOG_ERR, "returnit parser did not ACK this (%d), drop\n", rc);
1392
2020-07-10
pjp
imsg_free(&imsg);
1393
2020-07-10
pjp
return;
1394
2020-07-10
pjp
}
1395
2020-07-08
pjp
1396
2020-07-10
pjp
imsg_free(&imsg);
1397
2020-07-10
pjp
break;
1398
2020-07-10
pjp
case IMSG_PARSEREPLY_MESSAGE:
1399
2020-07-03
pjp
1400
2020-07-10
pjp
if (datalen != sizeof(int)) {
1401
2020-07-10
pjp
dolog(LOG_ERR, "bad parsereply message, drop\n");
1402
2020-07-10
pjp
imsg_free(&imsg);
1403
2020-07-10
pjp
return;
1404
2020-07-10
pjp
}
1405
2020-07-03
pjp
1406
2020-07-10
pjp
memcpy(&i, imsg.data, sizeof(int));
1407
2020-07-06
pjp
1408
2020-07-10
pjp
/* lock */
1409
2020-07-14
pjp
while (cfg->shptr3[cfg->shptr3size - 16] == '*')
1410
2020-07-10
pjp
usleep(arc4random() % 300);
1411
2020-07-06
pjp
1412
2020-07-14
pjp
cfg->shptr3[cfg->shptr3size - 16] = '*';
1413
2020-07-06
pjp
1414
2020-07-14
pjp
pi0 = (struct pkt_imsg *)&cfg->shptr3[0];
1415
2020-07-14
pjp
pi0 = &pi0[i];
1416
2020-07-06
pjp
1417
2020-07-14
pjp
memcpy(pi, pi0, sizeof(struct pkt_imsg));
1418
2020-07-06
pjp
1419
2020-07-14
pjp
pack32((char *)&pi0->pkt_s.read, 1);
1420
2020-07-14
pjp
cfg->shptr3[cfg->shptr3size - 16] = ' ';
1421
2020-07-10
pjp
1422
2020-07-10
pjp
if (fwq->istcp == 1)
1423
2020-07-10
pjp
fwq->so = imsg.fd;
1424
2020-07-10
pjp
1425
2020-07-08
pjp
imsg_free(&imsg);
1426
2020-07-10
pjp
goto endimsg;
1427
2020-07-08
pjp
break;
1428
2020-07-08
pjp
default:
1429
2020-07-08
pjp
dolog(LOG_INFO, "received unexpected IMSG\n");
1430
2020-07-08
pjp
imsg_free(&imsg);
1431
2020-07-08
pjp
break;
1432
2020-07-08
pjp
}
1433
2020-07-03
pjp
1434
2020-07-10
pjp
/* back to select */
1435
2020-07-08
pjp
break;
1436
2020-07-08
pjp
} /* for (;;) */
1437
2020-07-08
pjp
} /* for (;;) */
1438
2020-07-03
pjp
1439
2020-07-08
pjp
endimsg:
1440
2020-07-08
pjp
1441
2020-07-14
pjp
if (fwq->tsigkey && (unpack32((char *)&pi->pkt_s.tsig.have_tsig) == 0 \
1442
2020-07-14
pjp
|| unpack32((char *)&pi->pkt_s.tsig.tsigverified) == 0)) {
1443
2020-07-14
pjp
dolog(LOG_INFO, "FORWARD returnit, TSIG didn't check out error code = %d\n", unpack32((char *)&pi->pkt_s.tsig.tsigerrorcode));
1444
2020-07-08
pjp
return;
1445
2020-07-08
pjp
}
1446
2020-07-06
pjp
1447
2020-07-14
pjp
if (unpack32((char *)&pi->pkt_s.tsig.have_tsig) == 1) {
1448
2020-07-11
pjp
NTOHS(dh->additional);
1449
2020-07-11
pjp
if (dh->additional > 0)
1450
2020-07-11
pjp
dh->additional--;
1451
2020-07-11
pjp
HTONS(dh->additional);
1452
2020-07-11
pjp
}
1453
2020-07-03
pjp
1454
2020-07-14
pjp
if (unpack32((char *)&pi->pkt_s.tsigcheck) == 1)
1455
2020-07-14
pjp
rlen = unpack32((char *)&pi->pkt_s.tsig.tsigoffset);
1456
2020-07-06
pjp
1457
2020-07-08
pjp
1458
2020-07-03
pjp
/* add new tsig if needed */
1459
2020-07-03
pjp
pack16((char *)&dh->id, fwq->oldid);
1460
2020-07-03
pjp
1461
2020-07-03
pjp
NTOHS(dh->query);
1462
2020-07-06
pjp
dh->query &= ~(DNS_AUTH); /* take AA answers out */
1463
2020-07-03
pjp
SET_DNS_RECURSION(dh);
1464
2020-07-03
pjp
SET_DNS_RECURSION_AVAIL(dh);
1465
2020-07-03
pjp
HTONS(dh->query);
1466
2020-07-16
pjp
1467
2020-07-16
pjp
/* restore any possible 0x20 caseings, must be after TSIG checks */
1468
2020-07-16
pjp
memcpy((char *)&dh[1], fwq->orig_dnsname, fwq->dnsnamelen);
1469
2020-07-03
pjp
1470
2020-07-03
pjp
if (fwq->haveoldmac) {
1471
2020-07-16
pjp
q = build_fake_question(fwq->orig_dnsname, fwq->dnsnamelen, DNS_TYPE_A, fwq->oldkeyname, fwq->oldkeynamelen);
1472
2020-07-03
pjp
1473
2020-07-03
pjp
if (q == NULL) {
1474
2020-07-03
pjp
dolog(LOG_INFO, "build_fake_question failed\n");
1475
2020-07-03
pjp
return;
1476
2020-07-03
pjp
}
1477
2020-07-03
pjp
1478
2020-07-03
pjp
memcpy(&q->tsig.tsigmac, &fwq->oldmac, 32);
1479
2020-07-03
pjp
q->tsig.tsigmaclen = 32;
1480
2020-07-03
pjp
q->tsig.tsigalglen = 13;
1481
2020-07-03
pjp
q->tsig.tsigerrorcode = 0;
1482
2020-07-03
pjp
q->tsig.tsigorigid = fwq->oldid;
1483
2020-07-03
pjp
q->tsig.have_tsig = 1;
1484
2020-07-03
pjp
q->tsig.tsig_timefudge = fwq->tsigtimefudge;
1485
2020-07-03
pjp
1486
2020-07-03
pjp
outlen = additional_tsig(q, p, 0xffff, rlen, 0, 0, NULL);
1487
2020-07-03
pjp
if (outlen == rlen) {
1488
2020-07-03
pjp
dolog(LOG_INFO, "additional tsig failed\n");
1489
2020-07-03
pjp
} else {
1490
2020-07-03
pjp
rlen = outlen;
1491
2020-07-03
pjp
1492
2020-07-03
pjp
NTOHS(dh->additional);
1493
2020-07-03
pjp
dh->additional++;
1494
2020-07-03
pjp
HTONS(dh->additional);
1495
2020-07-03
pjp
1496
2020-07-03
pjp
free_question(q);
1497
2020-07-03
pjp
}
1498
2020-07-03
pjp
}
1499
2020-07-03
pjp
1500
2020-07-03
pjp
len += rlen;
1501
2020-07-03
pjp
1502
2020-07-03
pjp
if (fwq->istcp == 1) {
1503
2020-07-03
pjp
pack16(buf, htons(rlen));
1504
2020-07-08
pjp
if (send(fwq->returnso, buf, len, 0) != len)
1505
2020-07-03
pjp
dolog(LOG_INFO, "send(): %s\n", strerror(errno));
1506
2020-07-08
pjp
close(fwq->returnso); /* only close the tcp stream */
1507
2020-07-03
pjp
fwq->returnso = -1;
1508
2020-07-03
pjp
1509
2020-07-03
pjp
} else {
1510
2020-07-03
pjp
1511
2020-07-03
pjp
switch (fwq->oldfamily) {
1512
2020-07-03
pjp
case AF_INET:
1513
2020-07-21
pjp
rawsend(cfg->raw[0], buf, len, &fwq->oldhost4, fwq->oldsel, cfg);
1514
2020-07-03
pjp
break;
1515
2020-07-14
pjp
case AF_INET6:
1516
2020-07-21
pjp
rawsend6(cfg->raw[1], buf, len, &fwq->oldhost6, fwq->oldsel, cfg);
1517
2020-07-03
pjp
break;
1518
2020-07-03
pjp
}
1519
2020-07-03
pjp
}
1520
2020-07-03
pjp
1521
2020-07-03
pjp
return;
1522
2020-07-03
pjp
}
1523
2020-07-03
pjp
1524
2020-07-03
pjp
struct tsig *
1525
2020-07-03
pjp
check_tsig(char *buf, int len, char *mac)
1526
2020-07-03
pjp
{
1527
2020-07-03
pjp
char pseudo_packet[4096]; /* for tsig */
1528
2020-07-03
pjp
char expand[DNS_MAXNAME + 1];
1529
2020-07-03
pjp
u_int rollback, i, j;
1530
2020-07-03
pjp
u_int16_t type, rdlen;
1531
2020-07-03
pjp
u_int32_t ttl;
1532
2020-07-03
pjp
u_int64_t timefudge;
1533
2020-07-03
pjp
int elen = 0;
1534
2020-07-03
pjp
int additional;
1535
2020-07-03
pjp
1536
2020-07-03
pjp
char *o, *pb;
1537
2020-07-03
pjp
1538
2020-07-03
pjp
struct dns_tsigrr *tsigrr = NULL;
1539
2020-07-03
pjp
struct dns_optrr *opt = NULL;
1540
2020-07-11
pjp
struct dns_header *hdr;
1541
2020-07-03
pjp
struct tsig *rtsig;
1542
2020-07-03
pjp
1543
2020-07-03
pjp
1544
2020-07-11
pjp
hdr = (struct dns_header *)&buf[0];
1545
2020-07-11
pjp
1546
2020-07-03
pjp
rtsig = (void *)calloc(1, sizeof(struct tsig));
1547
2020-07-03
pjp
if (rtsig == NULL) {
1548
2020-07-03
pjp
dolog(LOG_INFO, "calloc: %s\n", strerror(errno));
1549
2020-07-03
pjp
return NULL;
1550
2020-07-03
pjp
}
1551
2020-07-03
pjp
1552
2020-07-11
pjp
rtsig->tsigoffset = len;
1553
2020-07-11
pjp
1554
2020-07-03
pjp
rollback = i = sizeof(struct dns_header);
1555
2020-07-03
pjp
/* the name is parsed here */
1556
2020-07-03
pjp
elen = 0;
1557
2020-07-03
pjp
memset(&expand, 0, sizeof(expand));
1558
2020-07-03
pjp
pb = expand_compression((u_char *)&buf[i], (u_char *)buf, (u_char *)&buf[len], (u_char *)&expand, &elen, sizeof(expand));
1559
2020-07-03
pjp
if (pb == NULL) {
1560
2020-07-03
pjp
dolog(LOG_INFO, "expand_compression() failed -2\n");
1561
2020-07-03
pjp
free(rtsig);
1562
2020-07-03
pjp
return NULL;
1563
2020-07-03
pjp
}
1564
2020-07-03
pjp
i = (pb - buf);
1565
2020-07-03
pjp
if (i > len) {
1566
2020-07-03
pjp
free(rtsig);
1567
2020-07-03
pjp
return NULL;
1568
2020-07-03
pjp
}
1569
2020-07-03
pjp
1570
2020-07-03
pjp
i += (2 * sizeof(u_int16_t)); /* type,class */
1571
2020-07-03
pjp
1572
2020-07-03
pjp
/* skip any payloads other than additional */
1573
2020-07-03
pjp
1574
2020-07-03
pjp
additional = ntohs(hdr->additional);
1575
2020-07-03
pjp
j = ntohs(hdr->answer) + ntohs(hdr->nsrr) + ntohs(hdr->additional);
1576
2020-07-03
pjp
1577
2020-07-03
pjp
for (;j > 0; j--) {
1578
2020-07-03
pjp
rollback = i;
1579
2020-07-03
pjp
/* the name is parsed here */
1580
2020-07-03
pjp
elen = 0;
1581
2020-07-03
pjp
memset(&expand, 0, sizeof(expand));
1582
2020-07-03
pjp
pb = expand_compression((u_char *)&buf[i], (u_char *)buf, (u_char *)&buf[len], (u_char *)&expand, &elen, sizeof(expand));
1583
2020-07-03
pjp
if (pb == NULL) {
1584
2020-07-03
pjp
dolog(LOG_INFO, "expand_compression() failed -1\n");
1585
2020-07-03
pjp
free(rtsig);
1586
2020-07-03
pjp
return NULL;
1587
2020-07-03
pjp
}
1588
2020-07-03
pjp
i = (pb - buf);
1589
2020-07-03
pjp
if (i > len) {
1590
2020-07-03
pjp
free(rtsig);
1591
2020-07-03
pjp
return NULL;
1592
2020-07-03
pjp
}
1593
2020-07-03
pjp
1594
2020-07-03
pjp
type = ntohs(unpack16(&buf[i]));
1595
2020-07-03
pjp
if (type == DNS_TYPE_OPT || type == DNS_TYPE_TSIG) {
1596
2020-07-03
pjp
i = rollback;
1597
2020-07-03
pjp
break;
1598
2020-07-03
pjp
}
1599
2020-07-03
pjp
1600
2020-07-03
pjp
i += 8; /* skip type, class, ttl */
1601
2020-07-03
pjp
if (i > len) {
1602
2020-07-03
pjp
free(rtsig);
1603
2020-07-03
pjp
return NULL;
1604
2020-07-03
pjp
}
1605
2020-07-03
pjp
1606
2020-07-03
pjp
rdlen = unpack16(&buf[i]);
1607
2020-07-03
pjp
i += 2; /* skip rdlen */
1608
2020-07-03
pjp
i += ntohs(rdlen); /* skip rdata, next */
1609
2020-07-03
pjp
1610
2020-07-03
pjp
if (i > len) {
1611
2020-07-03
pjp
free(rtsig);
1612
2020-07-03
pjp
return NULL;
1613
2020-07-03
pjp
}
1614
2020-07-03
pjp
}
1615
2020-07-03
pjp
1616
2020-07-03
pjp
1617
2020-07-03
pjp
/* check for edns0 opt rr */
1618
2020-07-03
pjp
do {
1619
2020-07-03
pjp
/* if we don't have an additional section, break */
1620
2020-07-03
pjp
if (additional < 1)
1621
2020-07-03
pjp
break;
1622
2020-07-03
pjp
1623
2020-07-03
pjp
rollback = i;
1624
2020-07-03
pjp
1625
2020-07-03
pjp
/* check that the minimum optrr fits */
1626
2020-07-03
pjp
/* 10 */
1627
2020-07-03
pjp
if (i + sizeof(struct dns_optrr) > len) {
1628
2020-07-03
pjp
i = rollback;
1629
2020-07-03
pjp
break;
1630
2020-07-03
pjp
}
1631
2020-07-03
pjp
1632
2020-07-03
pjp
opt = (struct dns_optrr *)&buf[i];
1633
2020-07-03
pjp
if (opt->name[0] != 0) {
1634
2020-07-03
pjp
i = rollback;
1635
2020-07-03
pjp
break;
1636
2020-07-03
pjp
}
1637
2020-07-03
pjp
1638
2020-07-03
pjp
if (ntohs(opt->type) != DNS_TYPE_OPT) {
1639
2020-07-03
pjp
i = rollback;
1640
2020-07-03
pjp
break;
1641
2020-07-03
pjp
}
1642
2020-07-03
pjp
1643
2020-07-03
pjp
/* RFC 3225 */
1644
2020-07-03
pjp
ttl = ntohl(opt->ttl);
1645
2020-07-03
pjp
1646
2020-07-03
pjp
i += 11 + ntohs(opt->rdlen);
1647
2020-07-03
pjp
if (i > len) {
1648
2020-07-03
pjp
free(rtsig);
1649
2020-07-03
pjp
return NULL;
1650
2020-07-03
pjp
}
1651
2020-07-03
pjp
additional--;
1652
2020-07-03
pjp
} while (0);
1653
2020-07-03
pjp
/* check for TSIG rr */
1654
2020-07-03
pjp
do {
1655
2020-07-03
pjp
u_int16_t val16, tsigerror, tsigotherlen;
1656
2020-07-03
pjp
u_int16_t fudge;
1657
2020-07-03
pjp
u_int32_t val32;
1658
2020-07-03
pjp
int elen, tsignamelen;
1659
2020-07-03
pjp
char tsigkey[512];
1660
2020-07-03
pjp
u_char sha256[32];
1661
2020-07-03
pjp
u_int shasize = sizeof(sha256);
1662
2020-07-03
pjp
time_t now, tsigtime;
1663
2020-07-03
pjp
int pseudolen1, pseudolen2, ppoffset = 0;
1664
2020-07-03
pjp
int pseudolen3 , pseudolen4;
1665
2020-07-03
pjp
1666
2020-07-03
pjp
rtsig->have_tsig = 0;
1667
2020-07-03
pjp
rtsig->tsigerrorcode = 1;
1668
2020-07-03
pjp
1669
2020-07-03
pjp
/* if we don't have an additional section, break */
1670
2020-07-03
pjp
if (additional < 1) {
1671
2020-07-03
pjp
break;
1672
2020-07-03
pjp
}
1673
2020-07-03
pjp
1674
2020-07-03
pjp
memset(rtsig->tsigkey, 0, sizeof(rtsig->tsigkey));
1675
2020-07-03
pjp
memset(rtsig->tsigalg, 0, sizeof(rtsig->tsigalg));
1676
2020-07-03
pjp
memset(rtsig->tsigmac, 0, sizeof(rtsig->tsigmac));
1677
2020-07-03
pjp
rtsig->tsigkeylen = rtsig->tsigalglen = rtsig->tsigmaclen = 0;
1678
2020-07-03
pjp
1679
2020-07-03
pjp
/* the key name is parsed here */
1680
2020-07-03
pjp
rollback = i;
1681
2020-07-03
pjp
rtsig->tsigoffset = i;
1682
2020-07-03
pjp
1683
2020-07-03
pjp
elen = 0;
1684
2020-07-03
pjp
memset(&expand, 0, sizeof(expand));
1685
2020-07-03
pjp
pb = expand_compression((u_char *)&buf[i], (u_char *)buf, (u_char *)&buf[len], (u_char *)&expand, &elen, sizeof(expand));
1686
2020-07-03
pjp
if (pb == NULL) {
1687
2020-07-03
pjp
dolog(LOG_INFO, "expand_compression() failed\n");
1688
2020-07-03
pjp
free(rtsig);
1689
2020-07-03
pjp
return NULL;
1690
2020-07-03
pjp
}
1691
2020-07-03
pjp
i = (pb - buf);
1692
2020-07-03
pjp
pseudolen1 = i;
1693
2020-07-03
pjp
1694
2020-07-03
pjp
memcpy(rtsig->tsigkey, expand, elen);
1695
2020-07-03
pjp
rtsig->tsigkeylen = elen;
1696
2020-07-03
pjp
1697
2020-07-03
pjp
1698
2020-07-03
pjp
if (i + 10 > len) { /* type + class + ttl + rdlen == 10 */
1699
2020-07-03
pjp
i = rollback;
1700
2020-07-03
pjp
break;
1701
2020-07-03
pjp
}
1702
2020-07-03
pjp
1703
2020-07-03
pjp
/* type */
1704
2020-07-03
pjp
o = &buf[i];
1705
2020-07-03
pjp
val16 = unpack16(o);
1706
2020-07-03
pjp
if (ntohs(val16) != DNS_TYPE_TSIG) {
1707
2020-07-03
pjp
i = rollback;
1708
2020-07-03
pjp
break;
1709
2020-07-03
pjp
}
1710
2020-07-03
pjp
i += 2;
1711
2020-07-03
pjp
o += 2;
1712
2020-07-03
pjp
pseudolen2 = i;
1713
2020-07-03
pjp
1714
2020-07-03
pjp
rtsig->have_tsig = 1;
1715
2020-07-03
pjp
1716
2020-07-03
pjp
/* we don't have any tsig keys configured, no auth done */
1717
2020-07-03
pjp
if (tsig == 0) {
1718
2020-07-03
pjp
i = rollback;
1719
2020-07-03
pjp
break;
1720
2020-07-03
pjp
}
1721
2020-07-03
pjp
1722
2020-07-03
pjp
rtsig->tsigerrorcode = DNS_BADKEY;
1723
2020-07-03
pjp
1724
2020-07-03
pjp
/* class */
1725
2020-07-03
pjp
val16 = unpack16(o);
1726
2020-07-03
pjp
if (ntohs(val16) != DNS_CLASS_ANY) {
1727
2020-07-03
pjp
#if DEBUG
1728
2020-07-03
pjp
dolog(LOG_INFO, "TSIG not class ANY\n");
1729
2020-07-03
pjp
#endif
1730
2020-07-03
pjp
i = rollback;
1731
2020-07-03
pjp
break;
1732
2020-07-03
pjp
}
1733
2020-07-03
pjp
i += 2;
1734
2020-07-03
pjp
o += 2;
1735
2020-07-03
pjp
1736
2020-07-03
pjp
/* ttl */
1737
2020-07-03
pjp
val32 = unpack32(o);
1738
2020-07-03
pjp
if (ntohl(val32) != 0) {
1739
2020-07-03
pjp
#if DEBUG
1740
2020-07-03
pjp
dolog(LOG_INFO, "TSIG not TTL 0\n");
1741
2020-07-03
pjp
#endif
1742
2020-07-03
pjp
i = rollback;
1743
2020-07-03
pjp
break;
1744
2020-07-03
pjp
}
1745
2020-07-03
pjp
i += 4;
1746
2020-07-03
pjp
o += 4;
1747
2020-07-03
pjp
1748
2020-07-03
pjp
/* rdlen */
1749
2020-07-03
pjp
val16 = unpack16(o);
1750
2020-07-03
pjp
if (ntohs(val16) != (len - (i + 2))) {
1751
2020-07-03
pjp
#if DEBUG
1752
2020-07-03
pjp
dolog(LOG_INFO, "TSIG not matching RDLEN\n");
1753
2020-07-03
pjp
#endif
1754
2020-07-03
pjp
i = rollback;
1755
2020-07-03
pjp
break;
1756
2020-07-03
pjp
}
1757
2020-07-03
pjp
i += 2;
1758
2020-07-03
pjp
o += 2;
1759
2020-07-03
pjp
pseudolen3 = i;
1760
2020-07-03
pjp
1761
2020-07-03
pjp
/* the algorithm name is parsed here */
1762
2020-07-03
pjp
elen = 0;
1763
2020-07-03
pjp
memset(&expand, 0, sizeof(expand));
1764
2020-07-03
pjp
pb = expand_compression((u_char *)&buf[i], (u_char *)buf, (u_char *)&buf[len], (u_char *)&expand, &elen, sizeof(expand));
1765
2020-07-03
pjp
if (pb == NULL) {
1766
2020-07-03
pjp
dolog(LOG_INFO, "expand_compression() failed 2\n");
1767
2020-07-03
pjp
free(rtsig);
1768
2020-07-03
pjp
return NULL;
1769
2020-07-03
pjp
}
1770
2020-07-03
pjp
i = (pb - buf);
1771
2020-07-03
pjp
pseudolen4 = i;
1772
2020-07-03
pjp
1773
2020-07-03
pjp
memcpy(rtsig->tsigalg, expand, elen);
1774
2020-07-03
pjp
rtsig->tsigalglen = elen;
1775
2020-07-03
pjp
1776
2020-07-03
pjp
/* now check for MAC type, since it's given once again */
1777
2020-07-03
pjp
if (elen == 11) {
1778
2020-07-03
pjp
if (expand[0] != 9 ||
1779
2020-07-03
pjp
memcasecmp(&expand[1], "hmac-sha1", 9) != 0) {
1780
2020-07-03
pjp
break;
1781
2020-07-03
pjp
}
1782
2020-07-03
pjp
} else if (elen == 13) {
1783
2020-07-03
pjp
if (expand[0] != 11 ||
1784
2020-07-03
pjp
memcasecmp(&expand[1], "hmac-sha256", 11) != 0) {
1785
2020-07-03
pjp
break;
1786
2020-07-03
pjp
}
1787
2020-07-03
pjp
} else if (elen == 26) {
1788
2020-07-03
pjp
if (expand[0] != 8 ||
1789
2020-07-03
pjp
memcasecmp(&expand[1], "hmac-md5", 8) != 0) {
1790
2020-07-03
pjp
break;
1791
2020-07-03
pjp
}
1792
2020-07-03
pjp
} else {
1793
2020-07-03
pjp
break;
1794
2020-07-03
pjp
}
1795
2020-07-03
pjp
1796
2020-07-03
pjp
/*
1797
2020-07-03
pjp
* this is a delayed (moved down) check of the key, we don't
1798
2020-07-03
pjp
* know if this is a TSIG packet until we've chekced the TSIG
1799
2020-07-03
pjp
* type, that's why it's delayed...
1800
2020-07-03
pjp
*/
1801
2020-07-03
pjp
1802
2020-07-03
pjp
if ((tsignamelen = find_tsig_key(rtsig->tsigkey, rtsig->tsigkeylen, (char *)&tsigkey, sizeof(tsigkey))) < 0) {
1803
2020-07-03
pjp
/* we don't have the name configured, let it pass */
1804
2020-07-03
pjp
i = rollback;
1805
2020-07-03
pjp
break;
1806
2020-07-03
pjp
}
1807
2020-07-03
pjp
1808
2020-07-03
pjp
if (i + sizeof(struct dns_tsigrr) > len) {
1809
2020-07-03
pjp
i = rollback;
1810
2020-07-03
pjp
break;
1811
2020-07-03
pjp
}
1812
2020-07-03
pjp
1813
2020-07-03
pjp
tsigrr = (struct dns_tsigrr *)&buf[i];
1814
2020-07-03
pjp
/* XXX */
1815
2020-07-03
pjp
#ifndef __OpenBSD__
1816
2020-07-03
pjp
timefudge = be64toh(tsigrr->timefudge);
1817
2020-07-03
pjp
#else
1818
2020-07-03
pjp
timefudge = betoh64(tsigrr->timefudge);
1819
2020-07-03
pjp
#endif
1820
2020-07-03
pjp
fudge = (u_int16_t)(timefudge & 0xffff);
1821
2020-07-03
pjp
tsigtime = (u_int64_t)(timefudge >> 16);
1822
2020-07-03
pjp
1823
2020-07-03
pjp
rtsig->tsig_timefudge = tsigrr->timefudge;
1824
2020-07-03
pjp
1825
2020-07-03
pjp
i += (8 + 2); /* timefudge + macsize */
1826
2020-07-03
pjp
1827
2020-07-03
pjp
if (ntohs(tsigrr->macsize) != 32) {
1828
2020-07-03
pjp
#if DEBUG
1829
2020-07-03
pjp
dolog(LOG_INFO, "bad macsize\n");
1830
2020-07-03
pjp
#endif
1831
2020-07-03
pjp
rtsig->tsigerrorcode = DNS_BADSIG;
1832
2020-07-03
pjp
break;
1833
2020-07-03
pjp
}
1834
2020-07-03
pjp
1835
2020-07-03
pjp
i += ntohs(tsigrr->macsize);
1836
2020-07-03
pjp
1837
2020-07-03
pjp
1838
2020-07-03
pjp
/* now get the MAC from packet with length rollback */
1839
2020-07-03
pjp
NTOHS(hdr->additional);
1840
2020-07-03
pjp
hdr->additional--;
1841
2020-07-03
pjp
HTONS(hdr->additional);
1842
2020-07-03
pjp
1843
2020-07-03
pjp
/* origid */
1844
2020-07-03
pjp
o = &buf[i];
1845
2020-07-03
pjp
val16 = unpack16(o);
1846
2020-07-03
pjp
i += 2;
1847
2020-07-03
pjp
o += 2;
1848
2020-07-03
pjp
if (hdr->id != val16)
1849
2020-07-03
pjp
hdr->id = val16;
1850
2020-07-03
pjp
rtsig->tsigorigid = val16;
1851
2020-07-03
pjp
1852
2020-07-03
pjp
/* error */
1853
2020-07-03
pjp
tsigerror = unpack16(o);
1854
2020-07-03
pjp
i += 2;
1855
2020-07-03
pjp
o += 2;
1856
2020-07-03
pjp
1857
2020-07-03
pjp
/* other len */
1858
2020-07-03
pjp
tsigotherlen = unpack16(o);
1859
2020-07-03
pjp
i += 2;
1860
2020-07-03
pjp
o += 2;
1861
2020-07-03
pjp
1862
2020-07-03
pjp
ppoffset = 0;
1863
2020-07-03
pjp
1864
2020-07-03
pjp
/* check if we have a request mac, this means it's an answer */
1865
2020-07-03
pjp
if (mac) {
1866
2020-07-03
pjp
o = &pseudo_packet[ppoffset];
1867
2020-07-03
pjp
pack16(o, htons(32));
1868
2020-07-03
pjp
ppoffset += 2;
1869
2020-07-03
pjp
1870
2020-07-03
pjp
memcpy(&pseudo_packet[ppoffset], mac, 32);
1871
2020-07-03
pjp
ppoffset += 32;
1872
2020-07-03
pjp
}
1873
2020-07-03
pjp
1874
2020-07-03
pjp
memcpy(&pseudo_packet[ppoffset], buf, pseudolen1);
1875
2020-07-03
pjp
ppoffset += pseudolen1;
1876
2020-07-03
pjp
memcpy((char *)&pseudo_packet[ppoffset], &buf[pseudolen2], 6);
1877
2020-07-03
pjp
ppoffset += 6;
1878
2020-07-03
pjp
1879
2020-07-03
pjp
memcpy((char *)&pseudo_packet[ppoffset], &buf[pseudolen3], pseudolen4 - pseudolen3);
1880
2020-07-03
pjp
ppoffset += (pseudolen4 - pseudolen3);
1881
2020-07-03
pjp
1882
2020-07-03
pjp
memcpy((char *)&pseudo_packet[ppoffset], (char *)&tsigrr->timefudge, 8);
1883
2020-07-03
pjp
ppoffset += 8;
1884
2020-07-03
pjp
1885
2020-07-03
pjp
o = &pseudo_packet[ppoffset];
1886
2020-07-03
pjp
pack16(o, tsigerror);
1887
2020-07-03
pjp
ppoffset += 2;
1888
2020-07-03
pjp
o += 2;
1889
2020-07-03
pjp
1890
2020-07-03
pjp
o = &pseudo_packet[ppoffset];
1891
2020-07-03
pjp
pack16(o, tsigotherlen);
1892
2020-07-03
pjp
ppoffset += 2;
1893
2020-07-03
pjp
o += 2;
1894
2020-07-03
pjp
1895
2020-07-03
pjp
memcpy(&pseudo_packet[ppoffset], &buf[i], len - i);
1896
2020-07-03
pjp
ppoffset += (len - i);
1897
2020-07-03
pjp
1898
2020-07-03
pjp
/* check for BADTIME before the HMAC memcmp as per RFC 2845 */
1899
2020-07-03
pjp
now = time(NULL);
1900
2020-07-03
pjp
/* outside our fudge window */
1901
2020-07-03
pjp
if (tsigtime < (now - fudge) || tsigtime > (now + fudge)) {
1902
2020-07-03
pjp
#if DEBUG
1903
2020-07-03
pjp
dolog(LOG_INFO, "outside of our fudge window\n");
1904
2020-07-03
pjp
#endif
1905
2020-07-03
pjp
rtsig->tsigerrorcode = DNS_BADTIME;
1906
2020-07-03
pjp
break;
1907
2020-07-03
pjp
}
1908
2020-07-03
pjp
1909
2020-07-03
pjp
HMAC(EVP_sha256(), tsigkey, tsignamelen, (unsigned char *)pseudo_packet,
1910
2020-07-03
pjp
ppoffset, (unsigned char *)&sha256, &shasize);
1911
2020-07-03
pjp
1912
2020-07-03
pjp
1913
2020-07-03
pjp
1914
2020-07-03
pjp
#if __OpenBSD__
1915
2020-07-03
pjp
if (timingsafe_memcmp(sha256, tsigrr->mac, sizeof(sha256)) != 0) {
1916
2020-07-03
pjp
#else
1917
2020-07-03
pjp
if (memcmp(sha256, tsigrr->mac, sizeof(sha256)) != 0) {
1918
2020-07-03
pjp
#endif
1919
2020-07-03
pjp
#if DEBUG
1920
2020-07-03
pjp
dolog(LOG_INFO, "HMAC did not verify\n");
1921
2020-07-03
pjp
#endif
1922
2020-07-03
pjp
rtsig->tsigerrorcode = DNS_BADSIG;
1923
2020-07-03
pjp
break;
1924
2020-07-03
pjp
}
1925
2020-07-03
pjp
1926
2020-07-03
pjp
/* copy the mac for error coding */
1927
2020-07-03
pjp
memcpy(rtsig->tsigmac, tsigrr->mac, sizeof(rtsig->tsigmac));
1928
2020-07-03
pjp
rtsig->tsigmaclen = 32;
1929
2020-07-03
pjp
1930
2020-07-03
pjp
/* we're now authenticated */
1931
2020-07-03
pjp
rtsig->tsigerrorcode = 0;
1932
2020-07-03
pjp
rtsig->tsigverified = 1;
1933
2020-07-03
pjp
1934
2020-07-03
pjp
} while (0);
1935
2020-07-03
pjp
1936
2020-07-03
pjp
/* parse type and class from the question */
1937
2020-07-03
pjp
return (rtsig);
1938
2020-07-03
pjp
}
1939
2020-07-03
pjp
1940
2020-07-03
pjp
void
1941
2020-07-10
pjp
fwdparseloop(struct imsgbuf *ibuf, struct imsgbuf *bibuf, struct cfg *cfg)
1942
2020-07-03
pjp
{
1943
2020-07-03
pjp
int fd = ibuf->fd;
1944
2020-07-08
pjp
int sel, istcp = 0;
1945
2020-07-10
pjp
int rlen, tmp, rc, i;
1946
2020-07-03
pjp
1947
2020-07-03
pjp
struct tsig *stsig = NULL;
1948
2020-07-14
pjp
struct pkt_imsg *pi, *pi0;
1949
2020-07-03
pjp
struct imsg imsg;
1950
2020-07-03
pjp
struct dns_header *dh;
1951
2020-07-03
pjp
1952
2020-07-03
pjp
char *packet;
1953
2020-07-08
pjp
u_char *end, *estart;
1954
2020-07-03
pjp
fd_set rset;
1955
2020-07-03
pjp
ssize_t n, datalen;
1956
2020-07-10
pjp
int flags;
1957
2020-07-03
pjp
1958
2020-07-13
pjp
flags = fcntl(bibuf->fd, F_GETFL);
1959
2020-07-13
pjp
if (flags < 0) {
1960
2020-07-10
pjp
dolog(LOG_INFO, "fcntl: %s\n", strerror(errno));
1961
2020-07-13
pjp
} else {
1962
2020-07-13
pjp
flags |= O_NONBLOCK;
1963
2020-07-18
pjp
if (fcntl(bibuf->fd, F_SETFL, &flags) < 0) {
1964
2020-07-13
pjp
dolog(LOG_INFO, "fcntl: %s\n", strerror(errno));
1965
2020-07-13
pjp
}
1966
2020-07-10
pjp
}
1967
2020-07-10
pjp
1968
2020-07-03
pjp
#if __OpenBSD__
1969
2020-07-08
pjp
if (pledge("stdio sendfd recvfd", NULL) < 0) {
1970
2020-07-03
pjp
perror("pledge");
1971
2020-07-03
pjp
ddd_shutdown();
1972
2020-07-03
pjp
exit(1);
1973
2020-07-03
pjp
}
1974
2020-07-03
pjp
#endif
1975
2020-07-03
pjp
1976
2020-07-03
pjp
1977
2020-07-14
pjp
pi = (struct pkt_imsg *)calloc(1, sizeof(struct pkt_imsg));
1978
2020-07-14
pjp
if (pi == NULL) {
1979
2020-07-03
pjp
dolog(LOG_INFO, "calloc: %s\n", strerror(errno));
1980
2020-07-03
pjp
ddd_shutdown();
1981
2020-07-03
pjp
exit(1);
1982
2020-07-03
pjp
}
1983
2020-07-03
pjp
1984
2020-07-03
pjp
1985
2020-07-03
pjp
for (;;) {
1986
2020-07-03
pjp
FD_ZERO(&rset);
1987
2020-07-03
pjp
FD_SET(fd, &rset);
1988
2020-07-03
pjp
1989
2020-07-03
pjp
sel = select(fd + 1, &rset, NULL, NULL, NULL);
1990
2020-07-03
pjp
1991
2020-07-03
pjp
if (sel < 0) {
1992
2020-07-03
pjp
continue;
1993
2020-07-03
pjp
}
1994
2020-07-03
pjp
1995
2020-07-03
pjp
if (FD_ISSET(fd, &rset)) {
1996
2020-07-03
pjp
if (((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) || n == 0) {
1997
2020-07-03
pjp
continue;
1998
2020-07-03
pjp
}
1999
2020-07-03
pjp
2000
2020-07-03
pjp
for (;;) {
2001
2020-07-03
pjp
2002
2020-07-03
pjp
if ((n = imsg_get(ibuf, &imsg)) == -1) {
2003
2020-07-03
pjp
break;
2004
2020-07-03
pjp
}
2005
2020-07-03
pjp
2006
2020-07-03
pjp
if (n == 0) {
2007
2020-07-03
pjp
break;
2008
2020-07-03
pjp
}
2009
2020-07-03
pjp
2010
2020-07-03
pjp
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
2011
2020-07-08
pjp
2012
2020-07-03
pjp
switch (imsg.hdr.type) {
2013
2020-07-03
pjp
case IMSG_PARSE_MESSAGE:
2014
2020-07-03
pjp
/* XXX magic numbers */
2015
2020-07-10
pjp
if (datalen != sizeof(int)) {
2016
2020-07-10
pjp
rc = PARSE_RETURN_NAK;
2017
2020-07-10
pjp
imsg_compose(ibuf, IMSG_PARSEERROR_MESSAGE, 0, 0, imsg.fd, &rc, sizeof(int));
2018
2020-07-03
pjp
msgbuf_write(&ibuf->w);
2019
2020-07-03
pjp
break;
2020
2020-07-03
pjp
}
2021
2020-07-10
pjp
2022
2020-07-10
pjp
memcpy(&i, imsg.data, datalen);
2023
2020-07-03
pjp
2024
2020-07-10
pjp
/* lock */
2025
2020-07-14
pjp
while (cfg->shptr3[cfg->shptr3size - 16] == '*')
2026
2020-07-10
pjp
usleep(arc4random() % 300);
2027
2020-07-08
pjp
2028
2020-07-14
pjp
cfg->shptr3[cfg->shptr3size - 16] = '*';
2029
2020-07-08
pjp
2030
2020-07-14
pjp
pi0 = (struct pkt_imsg *)&cfg->shptr3[0];
2031
2020-07-14
pjp
pi0 = &pi0[i];
2032
2020-07-08
pjp
2033
2020-07-14
pjp
memcpy(pi, pi0, sizeof(struct pkt_imsg));
2034
2020-07-14
pjp
pack32((char *)&pi0->pkt_s.read, 1);
2035
2020-07-10
pjp
2036
2020-07-14
pjp
cfg->shptr3[cfg->shptr3size - 16] = ' ';
2037
2020-07-10
pjp
2038
2020-07-14
pjp
istcp = unpack32((char *)&pi->pkt_s.istcp);
2039
2020-07-10
pjp
2040
2020-07-08
pjp
if (istcp) {
2041
2020-07-14
pjp
packet = malloc(unpack32((char *)&pi->pkt_s.buflen));
2042
2020-07-08
pjp
if (packet == NULL) {
2043
2020-07-08
pjp
dolog(LOG_INFO, "malloc %s\n", strerror(errno));
2044
2020-07-10
pjp
rc = PARSE_RETURN_NAK;
2045
2020-07-08
pjp
/* send the descriptor back to them */
2046
2020-07-10
pjp
imsg_compose(ibuf, IMSG_PARSEERROR_MESSAGE, 0, 0, imsg.fd, &rc, sizeof(int));
2047
2020-07-08
pjp
msgbuf_write(&ibuf->w);
2048
2020-07-08
pjp
break;
2049
2020-07-08
pjp
}
2050
2020-07-08
pjp
2051
2020-07-14
pjp
if (recv(imsg.fd, packet, unpack32((char *)&pi->pkt_s.buflen), MSG_WAITALL) < 0) {
2052
2020-07-08
pjp
dolog(LOG_INFO, "recv in forward sandbox: %s\n", strerror(errno));
2053
2020-07-10
pjp
rc = PARSE_RETURN_NAK;
2054
2020-07-08
pjp
/* send the descriptor back to them */
2055
2020-07-10
pjp
imsg_compose(ibuf, IMSG_PARSEERROR_MESSAGE, 0, 0, imsg.fd, &rc, sizeof(int));
2056
2020-07-08
pjp
msgbuf_write(&ibuf->w);
2057
2020-07-10
pjp
free(packet);
2058
2020-07-08
pjp
break;
2059
2020-07-08
pjp
}
2060
2020-07-30
pjp
#if DEBUG
2061
2020-07-14
pjp
dolog(LOG_INFO, "received %d bytes from descriptor %d\n", unpack32((char *)&pi->pkt_s.buflen), imsg.fd);
2062
2020-07-30
pjp
#endif
2063
2020-07-08
pjp
} else
2064
2020-07-14
pjp
packet = &pi->pkt_s.buf[0];
2065
2020-07-08
pjp
2066
2020-07-08
pjp
if (istcp) {
2067
2020-07-14
pjp
tmp = unpack32((char *)&pi->pkt_s.buflen);
2068
2020-07-08
pjp
} else {
2069
2020-07-14
pjp
tmp = unpack32((char *)&pi->pkt_s.buflen);
2070
2020-07-08
pjp
}
2071
2020-07-08
pjp
2072
2020-07-08
pjp
if (tmp < sizeof(struct dns_header)) {
2073
2020-07-03
pjp
/* SEND NAK */
2074
2020-07-10
pjp
rc = PARSE_RETURN_NAK;
2075
2020-07-10
pjp
imsg_compose(ibuf, IMSG_PARSEERROR_MESSAGE, 0, 0, (istcp) ? imsg.fd : -1, &rc, sizeof(int));
2076
2020-07-03
pjp
msgbuf_write(&ibuf->w);
2077
2020-07-10
pjp
if (istcp)
2078
2020-07-10
pjp
free(packet);
2079
2020-07-03
pjp
break;
2080
2020-07-03
pjp
}
2081
2020-07-03
pjp
dh = (struct dns_header *)packet;
2082
2020-07-03
pjp
2083
2020-07-03
pjp
if (! (ntohs(dh->query) & DNS_REPLY)) {
2084
2020-07-10
pjp
rc = PARSE_RETURN_NOTAREPLY;
2085
2020-07-10
pjp
imsg_compose(ibuf, IMSG_PARSEERROR_MESSAGE, 0, 0, (istcp) ? imsg.fd : -1, &rc, sizeof(int));
2086
2020-07-03
pjp
msgbuf_write(&ibuf->w);
2087
2020-07-10
pjp
if (istcp)
2088
2020-07-10
pjp
free(packet);
2089
2020-07-03
pjp
break;
2090
2020-07-03
pjp
}
2091
2020-07-03
pjp
2092
2020-07-03
pjp
/*
2093
2020-07-03
pjp
* if questions aren't exactly 1 then reply NAK
2094
2020-07-03
pjp
*/
2095
2020-07-03
pjp
2096
2020-07-03
pjp
if (ntohs(dh->question) != 1) {
2097
2020-07-03
pjp
/*
2098
2020-07-03
pjp
* all valid answers have a
2099
2020-07-03
pjp
* question, so this is good
2100
2020-07-03
pjp
*/
2101
2020-07-10
pjp
rc = PARSE_RETURN_NOQUESTION;
2102
2020-07-10
pjp
imsg_compose(ibuf, IMSG_PARSEERROR_MESSAGE, 0, 0, (istcp) ? imsg.fd : -1, &rc, sizeof(int));
2103
2020-07-03
pjp
msgbuf_write(&ibuf->w);
2104
2020-07-10
pjp
if (istcp)
2105
2020-07-10
pjp
free(packet);
2106
2020-07-03
pjp
break;
2107
2020-07-03
pjp
}
2108
2020-07-03
pjp
/* insert parsing logic here */
2109
2020-07-03
pjp
2110
2020-07-08
pjp
/* check for cache */
2111
2020-07-14
pjp
if (unpack32((char *)&pi->pkt_s.cache)) {
2112
2020-07-08
pjp
estart = packet;
2113
2020-07-08
pjp
rlen = tmp;
2114
2020-07-08
pjp
end = &packet[rlen];
2115
2020-07-03
pjp
2116
2020-07-12
pjp
if (cacheit(packet, estart, end, ibuf, bibuf, cfg) < 0) {
2117
2020-07-10
pjp
dolog(LOG_INFO, "cacheit failed\n");
2118
2020-07-08
pjp
}
2119
2020-07-03
pjp
}
2120
2020-07-03
pjp
2121
2020-07-08
pjp
/* check to see if we tsig */
2122
2020-07-08
pjp
2123
2020-07-14
pjp
if (unpack32((char *)&pi->pkt_s.tsigcheck)) {
2124
2020-07-08
pjp
rlen = tmp;
2125
2020-07-14
pjp
stsig = check_tsig((char *)packet, rlen, pi->pkt_s.mac);
2126
2020-07-08
pjp
if (stsig == NULL) {
2127
2020-07-08
pjp
dolog(LOG_INFO, "FORWARD parser, malformed reply packet\n");
2128
2020-07-10
pjp
rc = PARSE_RETURN_MALFORMED;
2129
2020-07-03
pjp
2130
2020-07-10
pjp
imsg_compose(ibuf, IMSG_PARSEERROR_MESSAGE, 0, 0, (istcp) ? imsg.fd : -1, &rc, sizeof(int));
2131
2020-07-08
pjp
msgbuf_write(&ibuf->w);
2132
2020-07-08
pjp
2133
2020-07-10
pjp
if (istcp)
2134
2020-07-10
pjp
free(packet);
2135
2020-07-08
pjp
break;
2136
2020-07-08
pjp
}
2137
2020-07-08
pjp
2138
2020-07-14
pjp
memcpy(&pi->pkt_s.tsig, stsig, sizeof(struct tsig));
2139
2020-07-08
pjp
}
2140
2020-07-08
pjp
2141
2020-07-14
pjp
pack32((char *)&pi->pkt_s.rc, PARSE_RETURN_ACK);
2142
2020-07-10
pjp
2143
2020-07-14
pjp
while (cfg->shptr3[cfg->shptr3size - 16] == '*')
2144
2020-07-14
pjp
usleep(arc4random() % 300);
2145
2020-07-10
pjp
2146
2020-07-14
pjp
cfg->shptr3[cfg->shptr3size - 16] = '*';
2147
2020-07-14
pjp
2148
2020-07-14
pjp
pi0 = (struct pkt_imsg *)&cfg->shptr3[0];
2149
2020-07-14
pjp
for (i = 0; i < SHAREDMEMSIZE3; i++, pi0++) {
2150
2020-07-14
pjp
if (unpack32((char *)&pi0->pkt_s.read) == 1) {
2151
2020-07-14
pjp
memcpy(pi0, pi, sizeof(struct pkt_imsg));
2152
2020-07-14
pjp
pack32((char *)&pi0->pkt_s.read, 0);
2153
2020-07-10
pjp
break;
2154
2020-07-10
pjp
}
2155
2020-07-10
pjp
}
2156
2020-07-10
pjp
2157
2020-07-10
pjp
imsg_compose(ibuf, IMSG_PARSEREPLY_MESSAGE, 0, 0, (istcp) ? imsg.fd : -1, &i, sizeof(int));
2158
2020-07-03
pjp
msgbuf_write(&ibuf->w);
2159
2020-07-03
pjp
2160
2020-07-14
pjp
cfg->shptr3[cfg->shptr3size - 16] = ' ';
2161
2020-07-10
pjp
2162
2020-07-03
pjp
free(stsig);
2163
2020-07-10
pjp
2164
2020-07-10
pjp
if (istcp)
2165
2020-07-10
pjp
free(packet);
2166
2020-07-03
pjp
break;
2167
2020-07-03
pjp
} /* switch */
2168
2020-07-03
pjp
2169
2020-07-03
pjp
imsg_free(&imsg);
2170
2020-07-10
pjp
break;
2171
2020-07-03
pjp
} /* for(;;) */
2172
2020-07-03
pjp
} /* FD_ISSET */
2173
2020-07-03
pjp
} /* for(;;) */
2174
2020-07-03
pjp
2175
2020-07-03
pjp
/* NOTREACHED */
2176
2020-07-04
pjp
}
2177
2020-07-04
pjp
2178
2020-07-04
pjp
void
2179
2020-07-04
pjp
changeforwarder(struct forwardqueue *fwq)
2180
2020-07-04
pjp
{
2181
2020-07-04
pjp
fw2 = fwq->cur_forwardentry;
2182
2020-07-04
pjp
2183
2020-07-04
pjp
if ((fwp = TAILQ_PREV(fw2, forwardentrys, forward_entry)) == NULL) {
2184
2020-07-04
pjp
if ((fwp = TAILQ_NEXT(fw2, forward_entry)) == NULL) {
2185
2020-07-04
pjp
return;
2186
2020-07-04
pjp
}
2187
2020-07-04
pjp
2188
2020-07-04
pjp
fw2->active = 0;
2189
2020-07-04
pjp
fwp->active = 1;
2190
2020-07-04
pjp
} else {
2191
2020-07-04
pjp
fw2->active = 0;
2192
2020-07-04
pjp
fwp->active = 1;
2193
2020-07-04
pjp
}
2194
2020-07-04
pjp
2195
2020-07-04
pjp
return;
2196
2020-07-04
pjp
}
2197
2020-07-04
pjp
2198
2020-07-04
pjp
void
2199
2020-07-04
pjp
stirforwarders(void)
2200
2020-07-04
pjp
{
2201
2020-07-04
pjp
int randomforwarder;
2202
2020-07-04
pjp
int count = 0;
2203
2020-07-04
pjp
2204
2020-07-04
pjp
TAILQ_FOREACH(fwp, &forwardhead, forward_entry) {
2205
2020-07-04
pjp
fwp->active = 0;
2206
2020-07-04
pjp
count++;
2207
2020-07-04
pjp
}
2208
2020-07-04
pjp
2209
2020-07-04
pjp
randomforwarder = arc4random() % count;
2210
2020-07-04
pjp
2211
2020-07-04
pjp
count = 0;
2212
2020-07-04
pjp
TAILQ_FOREACH(fwp, &forwardhead, forward_entry) {
2213
2020-07-04
pjp
if (randomforwarder == count) {
2214
2020-07-04
pjp
dolog(LOG_INFO, "stirforwarders: %s is now active\n", fwp->name);
2215
2020-07-04
pjp
fwp->active = 1;
2216
2020-07-04
pjp
}
2217
2020-07-04
pjp
2218
2020-07-04
pjp
count++;
2219
2020-07-04
pjp
}
2220
2020-07-21
pjp
}
2221
2020-07-21
pjp
2222
2020-07-21
pjp
int
2223
2020-07-21
pjp
rawsend(int so, char *buf, uint16_t len, struct sockaddr_in *sin, int oldsel, struct cfg *cfg)
2224
2020-07-21
pjp
{
2225
2020-07-21
pjp
struct udphdr uh;
2226
2020-07-21
pjp
struct ip ip;
2227
2020-07-21
pjp
struct msghdr msg;
2228
2020-07-21
pjp
struct iovec iov[2];
2229
2020-07-21
pjp
2230
2020-07-21
pjp
memcpy(&ip.ip_src.s_addr, (void*)&(((struct sockaddr_in *)&cfg->ss[oldsel])->sin_addr.s_addr), sizeof(in_addr_t));
2231
2020-07-21
pjp
memcpy(&ip.ip_dst.s_addr, (void*)&sin->sin_addr, sizeof(in_addr_t));
2232
2020-07-21
pjp
ip.ip_p = IPPROTO_UDP;
2233
2020-07-21
pjp
2234
2020-07-21
pjp
memset(&uh, 0, sizeof(uh));
2235
2020-07-21
pjp
uh.uh_sport = htons(cfg->port);
2236
2020-07-21
pjp
uh.uh_dport = sin->sin_port;
2237
2020-07-21
pjp
uh.uh_ulen = htons(len + sizeof(struct udphdr));
2238
2020-07-21
pjp
uh.uh_sum = 0;
2239
2020-07-21
pjp
uh.uh_sum = udp_cksum((uint16_t *)buf, \
2240
2020-07-21
pjp
len + sizeof(struct udphdr), &ip, &uh);
2241
2020-07-21
pjp
2242
2020-07-21
pjp
memset(&msg, 0, sizeof(msg));
2243
2020-07-21
pjp
msg.msg_name = sin;
2244
2020-07-21
pjp
msg.msg_namelen = sizeof(struct sockaddr_in);
2245
2020-07-21
pjp
iov[0].iov_base = &uh;
2246
2020-07-21
pjp
iov[0].iov_len = sizeof(struct udphdr);
2247
2020-07-21
pjp
iov[1].iov_base = buf;
2248
2020-07-21
pjp
iov[1].iov_len = len;
2249
2020-07-21
pjp
msg.msg_iov = iov;
2250
2020-07-21
pjp
msg.msg_iovlen = 2;
2251
2020-07-21
pjp
2252
2020-07-21
pjp
return (sendmsg(so, &msg, 0));
2253
2020-07-21
pjp
}
2254
2020-07-21
pjp
int
2255
2020-07-21
pjp
rawsend6(int so, char *buf, uint16_t len, struct sockaddr_in6 *sin6, int oldsel, struct cfg *cfg)
2256
2020-07-21
pjp
{
2257
2020-07-21
pjp
struct udphdr uh;
2258
2020-07-21
pjp
struct ip6_hdr ip6;
2259
2020-07-21
pjp
struct msghdr msg;
2260
2020-07-21
pjp
struct iovec iov[2];
2261
2020-07-21
pjp
2262
2020-07-21
pjp
memcpy(&ip6.ip6_src, (void*)&(((struct sockaddr_in6 *)&cfg->ss[oldsel])->sin6_addr), sizeof(struct in6_addr));
2263
2020-07-21
pjp
memcpy(&ip6.ip6_dst, (void*)&sin6->sin6_addr, sizeof(struct in6_addr));
2264
2020-07-21
pjp
ip6.ip6_nxt = IPPROTO_UDP;
2265
2020-07-21
pjp
2266
2020-07-21
pjp
2267
2020-07-21
pjp
memset(&uh, 0, sizeof(uh));
2268
2020-07-21
pjp
uh.uh_sport = htons(cfg->port);
2269
2020-07-21
pjp
uh.uh_dport = sin6->sin6_port;
2270
2020-07-21
pjp
uh.uh_ulen = htons(len + sizeof(struct udphdr));
2271
2020-07-21
pjp
uh.uh_sum = 0;
2272
2020-07-21
pjp
uh.uh_sum = udp_cksum6((uint16_t *)buf, \
2273
2020-07-21
pjp
len + sizeof(struct udphdr), &ip6, &uh);
2274
2020-07-21
pjp
2275
2020-07-21
pjp
#ifdef __linux__
2276
2020-07-21
pjp
sin6->sin6_port = htons(IPPROTO_UDP);
2277
2020-07-21
pjp
#endif
2278
2020-07-21
pjp
2279
2020-07-21
pjp
memset(&msg, 0, sizeof(msg));
2280
2020-07-21
pjp
2281
2020-07-21
pjp
msg.msg_name = sin6;
2282
2020-07-21
pjp
msg.msg_namelen = sizeof(struct sockaddr_in6);
2283
2020-07-21
pjp
2284
2020-07-21
pjp
iov[0].iov_base = &uh;
2285
2020-07-21
pjp
iov[0].iov_len = sizeof(struct udphdr);
2286
2020-07-21
pjp
iov[1].iov_base = buf;
2287
2020-07-21
pjp
iov[1].iov_len = len;
2288
2020-07-21
pjp
msg.msg_iov = iov;
2289
2020-07-21
pjp
msg.msg_iovlen = 2;
2290
2020-07-21
pjp
2291
2020-07-21
pjp
return (sendmsg(so, &msg, 0));
2292
2020-06-30
pjp
}
repomaster@centroid.eu