📄 message.c
字号:
REQUIRE(msg->cursors[section] != NULL); *name = msg->cursors[section];}isc_result_tdns_message_findname(dns_message_t *msg, dns_section_t section, dns_name_t *target, dns_rdatatype_t type, dns_rdatatype_t covers, dns_name_t **name, dns_rdataset_t **rdataset){ dns_name_t *foundname; isc_result_t result; /* * XXX These requirements are probably too intensive, especially * where things can be NULL, but as they are they ensure that if * something is NON-NULL, indicating that the caller expects it * to be filled in, that we can in fact fill it in. */ REQUIRE(msg != NULL); REQUIRE(VALID_SECTION(section)); REQUIRE(target != NULL); if (name != NULL) REQUIRE(*name == NULL); if (type == dns_rdatatype_any) { REQUIRE(rdataset == NULL); } else { if (rdataset != NULL) REQUIRE(*rdataset == NULL); } result = findname(&foundname, target, &msg->sections[section]); if (result == ISC_R_NOTFOUND) return (DNS_R_NXDOMAIN); else if (result != ISC_R_SUCCESS) return (result); if (name != NULL) *name = foundname; /* * And now look for the type. */ if (type == dns_rdatatype_any) return (ISC_R_SUCCESS); result = dns_message_findtype(foundname, type, covers, rdataset); if (result == ISC_R_NOTFOUND) return (DNS_R_NXRRSET); return (result);}voiddns_message_movename(dns_message_t *msg, dns_name_t *name, dns_section_t fromsection, dns_section_t tosection){ REQUIRE(msg != NULL); REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER); REQUIRE(name != NULL); REQUIRE(VALID_NAMED_SECTION(fromsection)); REQUIRE(VALID_NAMED_SECTION(tosection)); /* * Unlink the name from the old section */ ISC_LIST_UNLINK(msg->sections[fromsection], name, link); ISC_LIST_APPEND(msg->sections[tosection], name, link);}voiddns_message_addname(dns_message_t *msg, dns_name_t *name, dns_section_t section){ REQUIRE(msg != NULL); REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER); REQUIRE(name != NULL); REQUIRE(VALID_NAMED_SECTION(section)); ISC_LIST_APPEND(msg->sections[section], name, link);}isc_result_tdns_message_gettempname(dns_message_t *msg, dns_name_t **item) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(item != NULL && *item == NULL); *item = isc_mempool_get(msg->namepool); if (*item == NULL) return (ISC_R_NOMEMORY); dns_name_init(*item, NULL); return (ISC_R_SUCCESS);}isc_result_tdns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(item != NULL && *item == NULL); *item = newoffsets(msg); if (*item == NULL) return (ISC_R_NOMEMORY); return (ISC_R_SUCCESS);}isc_result_tdns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(item != NULL && *item == NULL); *item = newrdata(msg); if (*item == NULL) return (ISC_R_NOMEMORY); return (ISC_R_SUCCESS);}isc_result_tdns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(item != NULL && *item == NULL); *item = isc_mempool_get(msg->rdspool); if (*item == NULL) return (ISC_R_NOMEMORY); dns_rdataset_init(*item); return (ISC_R_SUCCESS);}isc_result_tdns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(item != NULL && *item == NULL); *item = newrdatalist(msg); if (*item == NULL) return (ISC_R_NOMEMORY); return (ISC_R_SUCCESS);}voiddns_message_puttempname(dns_message_t *msg, dns_name_t **item) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(item != NULL && *item != NULL); if (dns_name_dynamic(*item)) dns_name_free(*item, msg->mctx); isc_mempool_put(msg->namepool, *item); *item = NULL;}voiddns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(item != NULL && *item != NULL); releaserdata(msg, *item); *item = NULL;}voiddns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(item != NULL && *item != NULL); REQUIRE(!dns_rdataset_isassociated(*item)); isc_mempool_put(msg->rdspool, *item); *item = NULL;}voiddns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(item != NULL && *item != NULL); releaserdatalist(msg, *item); *item = NULL;}isc_result_tdns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp, unsigned int *flagsp){ isc_region_t r; isc_buffer_t buffer; dns_messageid_t id; unsigned int flags; REQUIRE(source != NULL); buffer = *source; isc_buffer_remainingregion(&buffer, &r); if (r.length < DNS_MESSAGE_HEADERLEN) return (ISC_R_UNEXPECTEDEND); id = isc_buffer_getuint16(&buffer); flags = isc_buffer_getuint16(&buffer); flags &= DNS_MESSAGE_FLAG_MASK; if (flagsp != NULL) *flagsp = flags; if (idp != NULL) *idp = id; return (ISC_R_SUCCESS);}isc_result_tdns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section) { unsigned int first_section; isc_result_t result; REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE((msg->flags & DNS_MESSAGEFLAG_QR) == 0); if (!msg->header_ok) return (DNS_R_FORMERR); if (msg->opcode != dns_opcode_query && msg->opcode != dns_opcode_notify) want_question_section = ISC_FALSE; if (want_question_section) { if (!msg->question_ok) return (DNS_R_FORMERR); first_section = DNS_SECTION_ANSWER; } else first_section = DNS_SECTION_QUESTION; msg->from_to_wire = DNS_MESSAGE_INTENTRENDER; msgresetnames(msg, first_section); msgresetopt(msg); msgresetsigs(msg, ISC_TRUE); msginitprivate(msg); /* * We now clear most flags and then set QR, ensuring that the * reply's flags will be in a reasonable state. */ msg->flags &= DNS_MESSAGE_REPLYPRESERVE; msg->flags |= DNS_MESSAGEFLAG_QR; /* * This saves the query TSIG status, if the query was signed, and * reserves space in the reply for the TSIG. */ if (msg->tsigkey != NULL) { unsigned int otherlen = 0; msg->querytsigstatus = msg->tsigstatus; msg->tsigstatus = dns_rcode_noerror; if (msg->querytsigstatus == dns_tsigerror_badtime) otherlen = 6; msg->sig_reserved = spacefortsig(msg->tsigkey, otherlen); result = dns_message_renderreserve(msg, msg->sig_reserved); if (result != ISC_R_SUCCESS) { msg->sig_reserved = 0; return (result); } } if (msg->saved.base != NULL) { msg->query.base = msg->saved.base; msg->query.length = msg->saved.length; msg->free_query = msg->free_saved; msg->saved.base = NULL; msg->saved.length = 0; msg->free_saved = 0; } return (ISC_R_SUCCESS);}dns_rdataset_t *dns_message_getopt(dns_message_t *msg) { /* * Get the OPT record for 'msg'. */ REQUIRE(DNS_MESSAGE_VALID(msg)); return (msg->opt);}isc_result_tdns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; /* * Set the OPT record for 'msg'. */ /* * The space required for an OPT record is: * * 1 byte for the name * 2 bytes for the type * 2 bytes for the class * 4 bytes for the ttl * 2 bytes for the rdata length * --------------------------------- * 11 bytes * * plus the length of the rdata. */ REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(opt->type == dns_rdatatype_opt); REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER); REQUIRE(msg->state == DNS_SECTION_ANY); msgresetopt(msg); result = dns_rdataset_first(opt); if (result != ISC_R_SUCCESS) goto cleanup; dns_rdataset_current(opt, &rdata); msg->opt_reserved = 11 + rdata.length; result = dns_message_renderreserve(msg, msg->opt_reserved); if (result != ISC_R_SUCCESS) { msg->opt_reserved = 0; goto cleanup; } msg->opt = opt; return (ISC_R_SUCCESS); cleanup: dns_message_puttemprdataset(msg, &opt); return (result);}dns_rdataset_t *dns_message_gettsig(dns_message_t *msg, dns_name_t **owner) { /* * Get the TSIG record and owner for 'msg'. */ REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(owner == NULL || *owner == NULL); if (owner != NULL) *owner = msg->tsigname; return (msg->tsig);}isc_result_tdns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key) { isc_result_t result; /* * Set the TSIG key for 'msg' */ REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(msg->state == DNS_SECTION_ANY); if (key == NULL && msg->tsigkey != NULL) { if (msg->sig_reserved != 0) { dns_message_renderrelease(msg, msg->sig_reserved); msg->sig_reserved = 0; } dns_tsigkey_detach(&msg->tsigkey); } if (key != NULL) { REQUIRE(msg->tsigkey == NULL && msg->sig0key == NULL); dns_tsigkey_attach(key, &msg->tsigkey); if (msg->from_to_wire == DNS_MESSAGE_INTENTRENDER) { msg->sig_reserved = spacefortsig(msg->tsigkey, 0); result = dns_message_renderreserve(msg, msg->sig_reserved); if (result != ISC_R_SUCCESS) { dns_tsigkey_detach(&msg->tsigkey); msg->sig_reserved = 0; return (result); } } } return (ISC_R_SUCCESS);}dns_tsigkey_t *dns_message_gettsigkey(dns_message_t *msg) { /* * Get the TSIG key for 'msg' */ REQUIRE(DNS_MESSAGE_VALID(msg)); return (msg->tsigkey);}isc_result_tdns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig) { dns_rdata_t *rdata = NULL; dns_rdatalist_t *list = NULL; dns_rdataset_t *set = NULL; isc_buffer_t *buf = NULL; isc_region_t r; isc_result_t result; REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(msg->querytsig == NULL); if (querytsig == NULL) return (ISC_R_SUCCESS); result = dns_message_gettemprdata(msg, &rdata); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_message_gettemprdatalist(msg, &list); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_message_gettemprdataset(msg, &set); if (result != ISC_R_SUCCESS) goto cleanup; isc_buffer_usedregion(querytsig, &r); result = isc_buffer_allocate(msg->mctx, &buf, r.length); if (result != ISC_R_SUCCESS) goto cleanup; isc_buffer_putmem(buf, r.base, r.length); isc_buffer_usedregion(buf, &r); dns_rdata_init(rdata); dns_rdata_fromregion(rdata, dns_rdataclass_any, dns_rdatatype_tsig, &r); dns_message_takebuffer(msg, &buf); ISC_LIST_INIT(list->rdata); ISC_LIST_APPEND(list->rdata, rdata, link); result = dns_rdatalist_tordataset(list, set); if (result != ISC_R_SUCCESS) goto cleanup; msg->querytsig = set; return (result); cleanup: if (rdata != NULL) dns_message_puttemprdata(msg, &rdata); if (list != NULL) dns_message_puttemprdatalist(msg, &list); if (set != NULL) dns_message_puttemprdataset(msg, &set); return (ISC_R_NOMEMORY);}isc_result_tdns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t **querytsig) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; isc_region_t r; REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(mctx != NULL); REQUIRE(querytsig != NULL && *querytsig == NULL); if (msg->tsig == NULL) return (ISC_R_SUCCESS); result = dns_rdataset_first(msg->tsig); if (result != ISC_R_SUCCESS) return (result); dns_rdataset_current(msg->tsig, &rdata); dns_rdata_toregion(&rdata, &r); result = isc_buffer_allocate(mctx, querytsig, r.length); if (result != ISC_R_SUCCESS) return (result); isc_buffer_putmem(*querytsig, r.base, r.length); return (ISC_R_SUCCESS);}dns_rdataset_t *dns_message_getsig0(dns_message_t *msg, dns_name_t **owner) { /* * Get the SIG(0) record for 'msg'. */ REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(owner == NULL || *owner == NULL); if (msg->sig0 != NULL && owner != NULL) { /* If dns_message_getsig0 is called on a rendered message * after the SIG(0) has been applied, we need to return the * root name, not NULL. */ if (msg->sig0name == NULL) *owner = dns_rootname; else *owner = msg->sig0name; } return (msg->sig0);}isc_result_tdns_message_setsig0key(dns_message_t *msg, dst_key_t *key) { isc_region_t r; unsigned int x; isc_result_t result; /* * Set the SIG(0) key for 'msg' */ /* * The space required for an SIG(0) record is: * * 1 byte for the name * 2 bytes for the type * 2 bytes for the class * 4 bytes for the ttl * 2 bytes for the type covered * 1 byte for the algorithm * 1 bytes for the labels * 4 bytes for the original ttl * 4 bytes for the s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -