struct {
const knot_rrset_t *key;
const struct sockaddr *addr;
+ const struct sockaddr *dst_addr;
+ const knot_pkt_t *packet;
} qsource;
struct {
unsigned rtt;
dname2str(rr.owner), rr.ttl, rr.type, #rr.rdata, rdata)
end
-
-- Module API
local kres = {
-- Constants
task->on_complete = NULL;
task->req.qsource.key = NULL;
task->req.qsource.addr = NULL;
+ task->req.qsource.dst_addr = NULL;
/* Remember query source addr */
if (addr) {
size_t addr_len = sizeof(struct sockaddr_in);
} else {
task->source.addr.ip4.sin_family = AF_UNSPEC;
}
+ /* Remember the destination address. */
+ if (handle) {
+ int addr_len = sizeof(task->source.dst_addr);
+ struct sockaddr *dst_addr = (struct sockaddr *)&task->source.dst_addr;
+ task->source.dst_addr.ip4.sin_family = AF_UNSPEC;
+ if (handle->type == UV_UDP) {
+ if (uv_udp_getsockname((uv_udp_t *)handle, dst_addr, &addr_len) == 0) {
+ task->req.qsource.dst_addr = dst_addr;
+ }
+ } else if (handle->type == UV_TCP) {
+ if (uv_tcp_getsockname((uv_tcp_t *)handle, dst_addr, &addr_len) == 0) {
+ task->req.qsource.dst_addr = dst_addr;
+ }
+ }
+ }
worker->stats.concurrent += 1;
return task;
}
}
/* Expect answer, pop if satisfied immediately */
+ request->qsource.packet = packet;
ITERATE_LAYERS(request, qry, begin, request);
+ request->qsource.packet = NULL;
if (request->state == KNOT_STATE_DONE) {
kr_rplan_pop(rplan, qry);
}
struct {
const knot_rrset_t *key;
const struct sockaddr *addr;
+ const struct sockaddr *dst_addr;
+ const knot_pkt_t *packet;
} qsource;
struct {
unsigned rtt; /**< Current upstream RTT */