-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprocess_dns_req.c
114 lines (108 loc) · 3.41 KB
/
process_dns_req.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
* iothnamed: a domain name server/forwarder/proxy for the ioth
* Copyright 2021 Renzo Davoli - Federico De Marchi
* Virtualsquare & University of Bologna
*
* process_dns_req.c: process a dns query
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <netinet/in.h>
#include <iothdns.h>
#include <iothaddr.h>
#include <now.h>
#include <auth.h>
#include <cache.h>
#include <arpainetx.h>
#include <dnsheader_flags.h>
#include <process_dns_req.h>
#define FWD_PKT_TAG ((struct iothdns_pkt *) 0x1)
static int hashttl = 600;
void process_dns_req_set_hashttl(int ttl) {
if (ttl >= 0)
hashttl = ttl;
}
static struct iothdns_pkt *cb (uint8_t type, struct in6_addr *fromaddr,
struct in6_addr *baseaddr, char *pwd, struct iothdns_header *h) {
struct iothdns_pkt *rpkt = NULL;
switch (type) {
case AUTH_ERROR:
h->flags = FLAGS_EPERM(h->flags);
rpkt = iothdns_put_header(h);
break;
case AUTH_STATIC:
rpkt = cache_static_get(h);
if (rpkt == NULL) {
h->flags = FLAGS_ENOENT(h->flags);
rpkt = iothdns_put_header(h);
}
break;
case AUTH_OTIP:
h->flags = FLAGS_OK_AA(h->flags);
rpkt = iothdns_put_header(h);
if (h->qtype == IOTHDNS_TYPE_AAAA || h->qtype == IOTHDNS_TYPE_ANY) {
struct in6_addr addr = *baseaddr;
iothaddr_hash(&addr, h->qname, pwd,
iothaddr_otiptime(32, 0));
struct iothdns_rr rr = {h->qname, IOTHDNS_TYPE_AAAA, IOTHDNS_CLASS_IN, 1, 0};
iothdns_put_rr(IOTHDNS_SEC_ANSWER, rpkt, &rr);
iothdns_put_aaaa(rpkt, &addr);
}
break;
case AUTH_HASH:
h->flags = FLAGS_OK_AA(h->flags);
rpkt = iothdns_put_header(h);
if (h->qtype == IOTHDNS_TYPE_AAAA || h->qtype == IOTHDNS_TYPE_ANY) {
struct in6_addr addr = *baseaddr;
iothaddr_hash(&addr, h->qname, NULL, 0);
struct iothdns_rr rr = {h->qname, IOTHDNS_TYPE_AAAA, IOTHDNS_CLASS_IN, hashttl, 0};
iothdns_put_rr(IOTHDNS_SEC_ANSWER, rpkt, &rr);
iothdns_put_aaaa(rpkt, &addr);
if (auth_isactive(AUTH_HREV) && auth_hashrev_check(&addr, fromaddr)) {
time_t nowtime = now();
char buf[INET6_REVSTRLEN];
cache_hrev_add(inet_ntor(AF_INET6, &addr, buf, INET6_REVSTRLEN), IOTHDNS_TYPE_PTR, nowtime + hashttl, h->qname);
}
}
break;
case AUTH_CACHE:
rpkt = cache_get(h);
break;
case AUTH_HREV:
if (h->qtype == IOTHDNS_TYPE_PTR) {
rpkt = cache_hrev_get(h);
if (rpkt == NULL) {
h->flags = FLAGS_ENOENT(h->flags);
rpkt = iothdns_put_header(h);
}
}
break;
case AUTH_FWD:
rpkt = FWD_PKT_TAG;
break;
}
return rpkt;
}
struct iothdns_pkt *process_dns_req(struct iothdns_header *h, struct in6_addr *fromaddr) {
struct iothdns_header rh = *h;
struct iothdns_pkt *rpkt = auth_process_req(&rh, fromaddr, cb);
if (rpkt == FWD_PKT_TAG)
return NULL;
if (rpkt == NULL) {
h->flags = FLAGS_EPERM(h->flags);
rpkt = iothdns_put_header(h);
}
return rpkt;
}