2 #include <dnscrypt/plugin.h>
5 DCPLUGIN_MAIN(__FILE__
);
7 typedef struct Forwarder_
{
8 ldns_resolver
*resolver
;
12 dcplugin_description(DCPlugin
* const dcplugin
)
14 return "Resolve a name without dnscrypt after an NXDOMAIN response";
18 dcplugin_long_description(DCPlugin
* const dcplugin
)
23 "# dnscrypt-proxy --plugin \\\n"
24 " libdcplugin_example_ldns_forward_after_nxdomain.la,/etc/resolv.conf";
28 dcplugin_init(DCPlugin
* const dcplugin
, int argc
, char *argv
[])
31 const char *resolver_conf
= NULL
;
33 forwarder
= calloc(1U, sizeof *forwarder
);
34 dcplugin_set_user_data(dcplugin
, forwarder
);
35 if (forwarder
== NULL
) {
39 resolver_conf
= argv
[1];
41 if (ldns_resolver_new_frm_file(&forwarder
->resolver
, resolver_conf
)
45 ldns_resolver_set_retry(forwarder
->resolver
, 1);
46 ldns_resolver_set_timeout(forwarder
->resolver
, (struct timeval
) {
47 .tv_sec
= 2, .tv_usec
= 0
53 dcplugin_destroy(DCPlugin
*dcplugin
)
55 Forwarder
*forwarder
= dcplugin_get_user_data(dcplugin
);
57 if (forwarder
== NULL
) {
60 ldns_resolver_deep_free(forwarder
->resolver
);
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
);
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
)) {
90 return DCP_SYNC_FILTER_RESULT_ERROR
;
92 dcplugin_set_wire_data(dcp_packet
, response_wire
, response_wire_len
);
95 return DCP_SYNC_FILTER_RESULT_OK
;