/
reflect.c
107 lines (91 loc) · 3.43 KB
/
reflect.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
/* Copyright © 2012 Brandon L Black <blblack@gmail.com>
*
* This file is part of gdnsd.
*
* gdnsd 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 3 of the License, or
* (at your option) any later version.
*
* gdnsd 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 gdnsd. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <config.h>
#include <gdnsd/compiler.h>
#include <gdnsd/alloc.h>
#include <gdnsd/log.h>
#include <gdnsd/vscf.h>
#include "mon.h"
#include "plugapi.h"
#include "plugins.h"
#include <string.h>
#include <strings.h>
#include <inttypes.h>
#define NUM_RTYPES 4
#define RESPONSE_DNS 0 // use dns_source only
#define RESPONSE_EDNS 1 // use edns_client only
#define RESPONSE_BEST 2 // use edns_client if available, else just dns_source
#define RESPONSE_BOTH 3 // return both if edns_client available, else just dns_source
static const char* response_text[NUM_RTYPES] = {
"dns",
"edns",
"best",
"both"
};
static void plugin_reflect_load_config(vscf_data_t* config V_UNUSED)
{
gdnsd_dyn_addr_max(2, 2); // up to two (dns+edns) in any address family
}
// resource names (and numbers) are used by this plugin to choose
// one of four response types above, defaulting to "best".
static int plugin_reflect_map_res(const char* resname, const uint8_t* zone_name)
{
if (zone_name)
log_warn("plugin_reflect: zone %s: DYNC configurations which can return IP address results are DEPRECATED and will be removed in a future version!", logf_dname(zone_name));
if (!resname)
return RESPONSE_BEST;
for (unsigned i = 0; i < NUM_RTYPES; i++)
if (!strcasecmp(resname, response_text[i]))
return (int)i;
log_err("plugin_reflect: resource name '%s' invalid (must be one of 'dns', 'edns', 'best', 'both')", resname);
return -1;
}
static gdnsd_sttl_t plugin_reflect_resolve(unsigned resnum, const client_info_t* cinfo, dyn_result_t* result)
{
gdnsd_assert(resnum < NUM_RTYPES);
if (resnum == RESPONSE_BOTH || resnum == RESPONSE_DNS || (resnum == RESPONSE_BEST && !cinfo->edns_client_mask)) {
gdnsd_result_add_anysin(result, &cinfo->dns_source);
gdnsd_result_add_scope_mask(result, cinfo->edns_client_mask);
}
if (cinfo->edns_client_mask && resnum != RESPONSE_DNS) {
gdnsd_result_add_anysin(result, &cinfo->edns_client);
gdnsd_result_add_scope_mask(result, cinfo->edns_client_mask);
} else if (!cinfo->edns_client_mask && resnum == RESPONSE_EDNS) {
gdnsd_anysin_t tmpsin;
gdnsd_anysin_fromstr("0.0.0.0", 0, &tmpsin);
gdnsd_result_add_anysin(result, &tmpsin);
}
return GDNSD_STTL_TTL_MAX;
}
plugin_t plugin_reflect_funcs = {
.name = "reflect",
.config_loaded = false,
.used = false,
.load_config = plugin_reflect_load_config,
.map_res = plugin_reflect_map_res,
.pre_run = NULL,
.iothread_init = NULL,
.iothread_cleanup = NULL,
.resolve = plugin_reflect_resolve,
.add_svctype = NULL,
.add_mon_addr = NULL,
.add_mon_cname = NULL,
.init_monitors = NULL,
.start_monitors = NULL,
};