int knot_zone_tree_get_less_or_equal(knot_zone_tree_t *tree, const knot_dname_t *owner, knot_node_t **found, knot_node_t **previous) { if (tree == NULL || owner == NULL || found == NULL || previous == NULL) { return KNOT_EINVAL; } char lf[DNAME_LFT_MAXLEN]; dname_lf(lf, owner, sizeof(lf)); value_t *fval = NULL; int ret = hattrie_find_leq(tree, lf+1, *lf, &fval); if (fval) *found = (knot_node_t *)(*fval); int exact_match = 0; if (ret == 0) { *previous = knot_node_get_previous(*found); exact_match = 1; } else if (ret < 0) { *previous = *found; *found = NULL; } else if (ret > 0) { /* node is before first node in the trie */ *previous = knot_node_get_previous(*found); /* left of leftmost node is the rightmost node */ *found = NULL; } /* Check if previous node is not an empty non-terminal. */ if (knot_node_rrset_count(*previous) == 0) { *previous = knot_node_get_previous(*previous); } dbg_zone_exec_detail( char *name = knot_dname_to_str(owner); char *name_f = (*found != NULL) ? knot_dname_to_str(knot_node_owner(*found)) : "none"; dbg_zone_detail("Searched for owner %s in zone tree.\n", name); dbg_zone_detail("Exact match: %d\n", exact_match); dbg_zone_detail("Found node: %p: %s.\n", *found, name_f); dbg_zone_detail("Previous node: %p.\n", *previous); free(name); if (*found != NULL) { free(name_f); } );
static void ztree_iter_data(knot_node_t **node, void *data) { struct ztree_iter *it = (struct ztree_iter*)data; knot_dname_t *owner = (*node)->owner; if (owner != ORDER[it->i]) { it->ret = KNOT_ERROR; char *exp_s = knot_dname_to_str(ORDER[it->i]); char *owner_s = knot_dname_to_str(owner); diag("ztree: at index: %u expected '%s' got '%s'\n", it->i, exp_s, owner_s); free(exp_s); free(owner_s); } ++it->i; }
static int knot_tsig_check_key(const knot_rrset_t *tsig_rr, const knot_tsig_key_t *tsig_key) { if (tsig_rr == NULL || tsig_key == NULL) { return KNOT_EINVAL; } const knot_dname_t *tsig_name = tsig_rr->owner; if (!tsig_name) { return KNOT_EMALF; } char *name = knot_dname_to_str(tsig_name); if (!name) { return KNOT_EMALF; } if (knot_dname_cmp(tsig_name, tsig_key->name) != 0) { /*!< \todo which error. */ dbg_tsig("TSIG: unknown key: %s\n", name); free(name); return KNOT_TSIG_EBADKEY; } free(name); return KNOT_EOK; }
static int yp_dname_to_txt( BIN_TXT_PARAMS) { char *name = knot_dname_to_str(txt, bin, *txt_len); if (name == NULL) { return KNOT_EINVAL; } *txt_len = strlen(txt); return KNOT_EOK; }
/** Retrieve hint list. */ static int pack_hint(const char *k, void *v, void *baton) { char nsname_str[KNOT_DNAME_MAXLEN] = {'\0'}; knot_dname_to_str(nsname_str, (const uint8_t *)k, sizeof(nsname_str)); JsonNode *root_node = baton; JsonNode *addr_list = pack_addrs((pack_t *)v); if (!addr_list) { return kr_error(ENOMEM); } json_append_member(root_node, nsname_str, addr_list); return kr_ok(); }
/*! * \brief Tries to add RRSet to the response. * * This function tries to convert the RRSet to wire format and add it to the * wire format of the response and if successful, adds the RRSet to the given * list (and updates its size). If the RRSet did not fit into the available * space (\a max_size), it is omitted as a whole and the TC bit may be set * (according to \a tc). * * \param rrsets Lists of RRSets to which this RRSet should be added. * \param rrset_count Number of RRSets in the list. * \param resp Response structure where the RRSet should be added. * \param max_size Maximum available space in wire format of the response. * \param rrset RRSet to add. * \param tc Set to <> 0 if omitting the RRSet should cause the TC bit to be * set in the response. * * \return Count of RRs added to the response or KNOT_ESPACE if the RRSet did * not fit in the available space. */ static int knot_response_try_add_rrset(const knot_rrset_t **rrsets, short *rrset_count, knot_packet_t *resp, size_t max_size, const knot_rrset_t *rrset, int tc) { //short size = knot_response_rrset_size(rrset, &resp->compression); dbg_response_exec( char *name = knot_dname_to_str(rrset->owner); dbg_response_verb("\nAdding RRSet with owner %s and type %u: \n", name, rrset->type); free(name); );
static int str_zone( const knot_dname_t *zone, char *buff, size_t buff_len) { if (knot_dname_to_str(buff, zone, buff_len) == NULL) { return KNOT_EINVAL; } // Replace possible slashes with underscores. replace_slashes(buff, true); return KNOT_EOK; }
void knot_zone_deep_free(knot_zone_t **zone) { if (zone == NULL || *zone == NULL) { return; } if ((*zone)->contents && !knot_zone_contents_gen_is_old((*zone)->contents)) { // zone is in the middle of an update, report dbg_zone("Destroying zone that is in the middle of an " "update.\n"); } dbg_zone_exec( char *name = knot_dname_to_str((*zone)->name); dbg_zone("Destroying zone %p, name: %s.\n", *zone, name); free(name); );
static int str_char( const knot_dname_t *zone, char *buff, size_t buff_len, uint8_t index1, uint8_t index2) { if (knot_dname_to_str(buff, zone, buff_len) == NULL) { return KNOT_EINVAL; } // Remove the trailing dot. size_t zone_len = strlen(buff); assert(zone_len > 0); buff[zone_len--] = '\0'; // Get the block length. size_t len = index2 - index1 + 1; // Check for out of scope block. if (index1 >= zone_len) { buff[0] = '\0'; return KNOT_EOK; } // Check for partial block. if (index2 >= zone_len) { len = zone_len - index1; } // Copy the block. memmove(buff, buff + index1, len); buff[len] = '\0'; // Replace possible slashes with underscores. replace_slashes(buff, false); return KNOT_EOK; }
static int rosedb_list(struct cache *cache, MDB_txn *txn, int argc, char *argv[]) { MDB_cursor *cursor = cursor_acquire(txn, cache->dbi); MDB_val key, data; char dname_str[KNOT_DNAME_MAXLEN] = {'\0'}; char type_str[16] = { '\0' }; int ret = mdb_cursor_get(cursor, &key, &data, MDB_FIRST); while (ret == 0) { struct entry entry; unpack_entry(&data, &entry); knot_dname_to_str(dname_str, key.mv_data, sizeof(dname_str)); knot_rrtype_to_string(entry.data.type, type_str, sizeof(type_str)); printf("%s\t%s RDATA=%zuB\t%s\t%s\n", dname_str, type_str, knot_rdataset_size(&entry.data.rrs), entry.threat_code, entry.syslog_ip); ret = mdb_cursor_get(cursor, &key, &data, MDB_NEXT); } cursor_release(cursor); return KNOT_EOK; }
static int rosedb_log_message(char *stream, size_t *maxlen, knot_pkt_t *pkt, const char *threat_code, struct query_data *qdata) { char dname_buf[KNOT_DNAME_MAXLEN] = {'\0'}; struct sockaddr_storage addr; socklen_t addr_len = sizeof(addr); time_t now = time(NULL); struct tm tm; gmtime_r(&now, &tm); /* Field 1 Timestamp (UTC). */ STREAM_WRITE(stream, maxlen, strftime, "%Y-%m-%d %H:%M:%S\t", &tm); /* Field 2/3 Remote, local address. */ const struct sockaddr *remote = (const struct sockaddr *)qdata->param->remote; memcpy(&addr, remote, sockaddr_len(remote)); int client_port = sockaddr_port(&addr); sockaddr_port_set(&addr, 0); STREAM_WRITE(stream, maxlen, sockaddr_tostr, &addr); STREAM_WRITE(stream, maxlen, snprintf, "\t"); getsockname(qdata->param->socket, (struct sockaddr *)&addr, &addr_len); int server_port = sockaddr_port(&addr); sockaddr_port_set(&addr, 0); STREAM_WRITE(stream, maxlen, sockaddr_tostr, &addr); STREAM_WRITE(stream, maxlen, snprintf, "\t"); /* Field 4/5 Local, remote port. */ STREAM_WRITE(stream, maxlen, snprintf, "%d\t%d\t", client_port, server_port); /* Field 6 Threat ID. */ STREAM_WRITE(stream, maxlen, snprintf, "%s\t", threat_code); /* Field 7 - 13 NULL */ STREAM_WRITE(stream, maxlen, snprintf, "\t\t\t\t\t\t\t"); /* Field 14 QNAME */ knot_dname_to_str(dname_buf, knot_pkt_qname(qdata->query), sizeof(dname_buf)); STREAM_WRITE(stream, maxlen, snprintf, "%s\t", dname_buf); /* Field 15 Resolution (0 = local, 1 = lookup)*/ STREAM_WRITE(stream, maxlen, snprintf, "0\t"); /* Field 16 RDATA. * - Return randomly RDATA in the answer section (probabilistic rotation). * - Empty if no answer. */ const knot_pktsection_t *ans = knot_pkt_section(pkt, KNOT_ANSWER); if (ans->count > 0) { const knot_rrset_t *rr = &ans->rr[knot_random_uint16_t() % ans->count]; int ret = knot_rrset_txt_dump_data(rr, 0, stream, *maxlen, &KNOT_DUMP_STYLE_DEFAULT); if (ret < 0) { return ret; } stream_skip(&stream, maxlen, ret); } STREAM_WRITE(stream, maxlen, snprintf, "\t"); /* Field 17 Connection type. */ STREAM_WRITE(stream, maxlen, snprintf, "%s\t", net_is_connected(qdata->param->socket) ? "TCP" : "UDP"); /* Field 18 Query type. */ char type_str[16] = { '\0' }; knot_rrtype_to_string(knot_pkt_qtype(qdata->query), type_str, sizeof(type_str)); STREAM_WRITE(stream, maxlen, snprintf, "%s\t", type_str); /* Field 19 First authority. */ const knot_pktsection_t *ns = knot_pkt_section(pkt, KNOT_AUTHORITY); if (ns->count > 0 && ns->rr[0].type == KNOT_RRTYPE_NS) { const knot_dname_t *label = knot_ns_name(&ns->rr[0].rrs, 0); memset(dname_buf, 0, sizeof(dname_buf)); memcpy(dname_buf, label + 1, *label); STREAM_WRITE(stream, maxlen, snprintf, "%s", dname_buf); } return KNOT_EOK; }
int notify_process_request(knot_nameserver_t *ns, knot_packet_t *notify, sockaddr_t *from, uint8_t *buffer, size_t *size) { /*! \todo Most of this function is identical to xfrin_transfer_needed() * - it will be fine to merge the code somehow. */ if (notify == NULL || ns == NULL || buffer == NULL || size == NULL || from == NULL) { dbg_notify("notify: invalid parameters for %s()\n", "notify_process_request"); return KNOT_EINVAL; } int ret = KNOT_EOK; dbg_notify("notify: parsing rest of the packet\n"); if (notify->parsed < notify->size) { if (knot_packet_parse_rest(notify, 0) != KNOT_EOK) { dbg_notify("notify: failed to parse NOTIFY query\n"); knot_ns_error_response_from_query(ns, notify, KNOT_RCODE_FORMERR, buffer, size); return KNOT_EOK; } } // check if it makes sense - if the QTYPE is SOA if (knot_packet_qtype(notify) != KNOT_RRTYPE_SOA) { // send back FORMERR knot_ns_error_response_from_query(ns, notify, KNOT_RCODE_FORMERR, buffer, size); return KNOT_EOK; } // create NOTIFY response dbg_notify("notify: creating response\n"); ret = notify_create_response(notify, buffer, size); if (ret != KNOT_EOK) { dbg_notify("notify: failed to create NOTIFY response\n"); knot_ns_error_response_from_query(ns, notify, KNOT_RCODE_SERVFAIL, buffer, size); return KNOT_EOK; } /* Process notification. */ ret = KNOT_ENOZONE; unsigned serial = 0; const knot_dname_t *qname = knot_packet_qname(notify); rcu_read_lock(); /* z */ const knot_zone_t *z = knot_zonedb_find_zone_for_name(ns->zone_db, qname); if (z != NULL) { ret = notify_check_and_schedule(ns, z, from); const knot_rrset_t *soa_rr = NULL; soa_rr = knot_packet_answer_rrset(notify, 0); if (soa_rr && knot_rrset_type(soa_rr) == KNOT_RRTYPE_SOA) { serial = knot_rrset_rdata_soa_serial(soa_rr); } } rcu_read_unlock(); int rcode = KNOT_RCODE_NOERROR; switch (ret) { case KNOT_ENOZONE: rcode = KNOT_RCODE_NOTAUTH; break; case KNOT_EACCES: rcode = KNOT_RCODE_REFUSED; break; default: break; } /* Format resulting log message. */ char *qstr = knot_dname_to_str(qname); char *fromstr = xfr_remote_str(from, NULL); if (rcode != KNOT_RCODE_NOERROR) { knot_ns_error_response_from_query(ns, notify, KNOT_RCODE_REFUSED, buffer, size); log_server_warning(NOTIFY_MSG "%s\n", qstr, fromstr, knot_strerror(ret)); ret = KNOT_EOK; /* Send response. */ } else { log_server_info(NOTIFY_MSG NOTIFY_XMSG "\n", qstr, fromstr, serial); } free(qstr); free(fromstr); return ret; }