/** * Clean up DNS output adapter. * */ void dnsout_cleanup(dnsout_type* addns) { allocator_type* allocator = NULL; if (!addns) { return; } allocator = addns->allocator; acl_cleanup(addns->provide_xfr, allocator); acl_cleanup(addns->do_notify, allocator); tsig_cleanup(addns->tsig, allocator); allocator_deallocate(allocator, (void*) addns); allocator_cleanup(allocator); return; }
/** * Clean up DNS input adapter. * */ void dnsin_cleanup(dnsin_type* addns) { allocator_type* allocator = NULL; if (!addns) { return; } allocator = addns->allocator; acl_cleanup(addns->request_xfr, allocator); acl_cleanup(addns->allow_notify, allocator); tsig_cleanup(addns->tsig, allocator); allocator_deallocate(allocator, (void*) addns); allocator_cleanup(allocator); return; }
/*! * \brief Create a zone event query, send it, wait for the response and process it. * * \note Everything in this function is executed synchronously, returns when * the query processing is either complete or an error occurs. */ static int zone_query_execute(conf_t *conf, zone_t *zone, uint16_t pkt_type, const conf_remote_t *remote) { /* Create a memory pool for this task. */ knot_mm_t mm; mm_ctx_mempool(&mm, MM_DEFAULT_BLKSIZE); /* Create a query message. */ knot_pkt_t *query = zone_query(zone, pkt_type, &mm); if (query == NULL) { mp_delete(mm.ctx); return KNOT_ENOMEM; } /* Set EDNS section. */ int ret = prepare_edns(conf, zone, query); if (ret != KNOT_EOK) { knot_pkt_free(&query); mp_delete(mm.ctx); return ret; } /* Answer processing parameters. */ struct process_answer_param param = { .zone = zone, .conf = conf, .query = query, .remote = &remote->addr }; const knot_tsig_key_t *key = remote->key.name != NULL ? &remote->key : NULL; tsig_init(¶m.tsig_ctx, key); ret = tsig_sign_packet(¶m.tsig_ctx, query); if (ret != KNOT_EOK) { tsig_cleanup(¶m.tsig_ctx); knot_pkt_free(&query); mp_delete(mm.ctx); return ret; } /* Process the query. */ ret = zone_query_request(query, remote, ¶m, &mm); /* Cleanup. */ tsig_cleanup(¶m.tsig_ctx); knot_pkt_free(&query); mp_delete(mm.ctx); return ret; } /* @note Module specific, expects some variables set. */ #define ZONE_XFER_LOG(severity, pkt_type, msg, ...) \ if (pkt_type == KNOT_QUERY_AXFR) { \ ZONE_QUERY_LOG(severity, zone, master, "AXFR, incoming", msg, ##__VA_ARGS__); \ } else { \ ZONE_QUERY_LOG(severity, zone, master, "IXFR, incoming", msg, ##__VA_ARGS__); \ } /*! \brief Execute zone transfer request. */ static int zone_query_transfer(conf_t *conf, zone_t *zone, const conf_remote_t *master, uint16_t pkt_type) { assert(zone); assert(master); int ret = zone_query_execute(conf, zone, pkt_type, master); if (ret != KNOT_EOK) { /* IXFR failed, revert to AXFR. */ if (pkt_type == KNOT_QUERY_IXFR) { ZONE_XFER_LOG(LOG_NOTICE, pkt_type, "fallback to AXFR"); return zone_query_transfer(conf, zone, master, KNOT_QUERY_AXFR); } /* Log connection errors. */ ZONE_XFER_LOG(LOG_WARNING, pkt_type, "failed (%s)", knot_strerror(ret)); } return ret; }