dnscrypto-proxy: Update to release 1.3.0
[tomato.git] / release / src / router / dnscrypt / src / plugins / example-ldns-forward-after-nxdomain / example-ldns-forward-after-nxdomain.c
blob0226d2f79a8479a166c277b0e87c51161a23dfe8
2 #include <dnscrypt/plugin.h>
3 #include <ldns/ldns.h>
5 DCPLUGIN_MAIN(__FILE__);
7 typedef struct Forwarder_ {
8 ldns_resolver *resolver;
9 } Forwarder;
11 const char *
12 dcplugin_description(DCPlugin * const dcplugin)
14 return "Resolve a name without dnscrypt after an NXDOMAIN response";
17 const char *
18 dcplugin_long_description(DCPlugin * const dcplugin)
20 return
21 "Example usage:\n"
22 "\n"
23 "# dnscrypt-proxy --plugin \\\n"
24 " libdcplugin_example_ldns_forward_after_nxdomain.la,/etc/resolv.conf";
27 int
28 dcplugin_init(DCPlugin * const dcplugin, int argc, char *argv[])
30 Forwarder *forwarder;
31 const char *resolver_conf = NULL;
33 forwarder = calloc(1U, sizeof *forwarder);
34 dcplugin_set_user_data(dcplugin, forwarder);
35 if (forwarder == NULL) {
36 return -1;
38 if (argc > 1) {
39 resolver_conf = argv[1];
41 if (ldns_resolver_new_frm_file(&forwarder->resolver, resolver_conf)
42 != LDNS_STATUS_OK) {
43 return -1;
45 ldns_resolver_set_retry(forwarder->resolver, 1);
46 ldns_resolver_set_timeout(forwarder->resolver, (struct timeval) {
47 .tv_sec = 2, .tv_usec = 0
48 });
49 return 0;
52 int
53 dcplugin_destroy(DCPlugin *dcplugin)
55 Forwarder *forwarder = dcplugin_get_user_data(dcplugin);
57 if (forwarder == NULL) {
58 return 0;
60 ldns_resolver_deep_free(forwarder->resolver);
61 free(forwarder);
63 return 0;
66 DCPluginSyncFilterResult
67 dcplugin_sync_post_filter(DCPlugin *dcplugin, DCPluginDNSPacket *dcp_packet)
69 Forwarder *forwarder = dcplugin_get_user_data(dcplugin);
70 ldns_pkt *query = NULL;
71 ldns_pkt *response = NULL;
72 uint8_t *query_wire = dcplugin_get_wire_data(dcp_packet);
73 uint8_t *response_wire = NULL;
74 size_t response_wire_len;
76 if (LDNS_RCODE_WIRE(query_wire) != LDNS_RCODE_NXDOMAIN) {
77 return DCP_SYNC_FILTER_RESULT_OK;
79 LDNS_AA_CLR(query_wire);
80 LDNS_QR_CLR(query_wire);
81 LDNS_TC_CLR(query_wire);
82 ldns_wire2pkt(&query, query_wire, dcplugin_get_wire_data_len(dcp_packet));
83 ldns_pkt_set_edns_data(query, ldns_rdf_new_frm_str(LDNS_RDF_TYPE_HEX, ""));
84 ldns_send(&response, forwarder->resolver, query);
85 ldns_pkt_free(query);
86 ldns_pkt2wire(&response_wire, response, &response_wire_len);
87 ldns_pkt_free(response);
88 if (response_wire_len > dcplugin_get_wire_data_max_len(dcp_packet)) {
89 free(response_wire);
90 return DCP_SYNC_FILTER_RESULT_ERROR;
92 dcplugin_set_wire_data(dcp_packet, response_wire, response_wire_len);
93 free(response_wire);
95 return DCP_SYNC_FILTER_RESULT_OK;