_public_ int knot_pkt_copy(knot_pkt_t *dst, const knot_pkt_t *src) { if (dst == NULL || src == NULL) { return KNOT_EINVAL; } if (dst->max_size < src->size) { return KNOT_ESPACE; } dst->size = src->size; memcpy(dst->wire, src->wire, dst->size); /* Copy TSIG RR back to wire. */ if (src->tsig_rr) { int ret = knot_tsig_append(dst->wire, &dst->size, dst->max_size, src->tsig_rr); if (ret != KNOT_EOK) { return ret; } } /* Invalidate arrays . */ dst->rr = NULL; dst->rr_info = NULL; dst->rrset_count = 0; dst->rrset_allocd = 0; /* @note This could be done more effectively if needed. */ return knot_pkt_parse(dst, 0); }
int knot_tsig_add(uint8_t *msg, size_t *msg_len, size_t msg_max_len, uint16_t tsig_rcode, const knot_rrset_t *tsig_rr) { /*! \todo Revise!! */ if (!msg || !msg_len || !tsig_rr) { return KNOT_EINVAL; } /*! \todo What key to use, when we do not sign? Does this even work? */ knot_rrset_t *tmp_tsig = knot_rrset_new(tsig_rr->owner, KNOT_RRTYPE_TSIG, KNOT_CLASS_ANY, NULL); if (!tmp_tsig) { dbg_tsig("TSIG: tmp_tsig = NULL\n"); return KNOT_ENOMEM; } assert(tsig_rcode != KNOT_RCODE_BADTIME); tsig_create_rdata(tmp_tsig, tsig_rdata_alg_name(tsig_rr), 0, tsig_rcode); tsig_rdata_set_time_signed(tmp_tsig, tsig_rdata_time_signed(tsig_rr)); /* Comparing to BIND it was found out that the Fudge should always be * set to the server's value. */ tsig_rdata_set_fudge(tmp_tsig, KNOT_TSIG_FUDGE_DEFAULT); /* Set original ID */ tsig_rdata_set_orig_id(tmp_tsig, knot_wire_get_id(msg)); /* Set other len. */ tsig_rdata_set_other_data(tmp_tsig, 0, 0); /* Append TSIG RR. */ int ret = knot_tsig_append(msg, msg_len, msg_max_len, tsig_rr); /* key_name already referenced in RRSet, no need to free separately. */ knot_rrset_free(&tmp_tsig, NULL); return ret; }