35#include <dns/result.h>
158 dns_name_t *pname, dns_name_t *uname);
160#if defined (NSUPDATE)
161#if defined (DNS_ZONE_LOOKUP)
175typedef struct dhcp_ddns_ns {
176 struct dhcp_ddns_ns *next;
180 dns_clientresevent_t *eventp;
184 dns_rdataset_t *rdataset;
185 dns_rdatatype_t rdtype;
211dhcp_ddns_ns_t *dns_outstanding_ns = NULL;
229add_to_ns_queue(dhcp_ddns_ns_t *ns_cb)
231 ns_cb->next = dns_outstanding_ns;
232 dns_outstanding_ns = ns_cb;
237remove_from_ns_queue(dhcp_ddns_ns_t *ns_cb)
239 dhcp_ddns_ns_t **foo;
241 foo = &dns_outstanding_ns;
247 foo = &((*foo)->next);
253find_in_ns_queue(dhcp_ddns_ns_t *ns_cb)
255 dhcp_ddns_ns_t *temp_cb;
256 int in_len, temp_len;
258 in_len = strlen(ns_cb->zname);
260 for(temp_cb = dns_outstanding_ns;
262 temp_cb = temp_cb->next) {
263 temp_len = strlen(temp_cb->zname);
264 if (temp_len > in_len)
266 if (strcmp(temp_cb->zname,
267 ns_cb->zname + (in_len - temp_len)) == 0)
270 return(ISC_R_NOTFOUND);
273void cache_found_zone (dhcp_ddns_ns_t *);
276void ddns_interlude(isc_task_t *, isc_event_t *);
314#define TRACE_PTR_LEN 8
316typedef struct dhcp_ddns_map {
317 char old_pointer[TRACE_PTR_LEN];
319 struct dhcp_ddns_map *next;
323static dhcp_ddns_map_t *ddns_map;
335trace_ddns_input_write(
dhcp_ddns_cb_t *ddns_cb, isc_result_t result)
338 u_int32_t old_result;
339 char old_pointer[TRACE_PTR_LEN];
341 old_result = htonl((u_int32_t)result);
342 memset(old_pointer, 0, TRACE_PTR_LEN);
343 memcpy(old_pointer, &ddns_cb,
sizeof(ddns_cb));
345 iov[0].
len =
sizeof(old_result);
346 iov[0].
buf = (
char *)&old_result;
347 iov[1].
len = TRACE_PTR_LEN;
348 iov[1].
buf = old_pointer;
359trace_ddns_input_read(
trace_type_t *ttype,
unsigned length,
362 u_int32_t old_result;
363 char old_pointer[TRACE_PTR_LEN];
364 dns_clientupdateevent_t *eventp;
366 dhcp_ddns_map_t *ddns_map_ptr;
368 if (length < (
sizeof(old_result) + TRACE_PTR_LEN)) {
369 log_error(
"trace_ddns_input_read: data too short");
373 memcpy(&old_result, buf,
sizeof(old_result));
374 memcpy(old_pointer, buf +
sizeof(old_result), TRACE_PTR_LEN);
377 for (ddns_map_ptr = ddns_map;
378 ddns_map_ptr != NULL;
379 ddns_map_ptr = ddns_map_ptr->next) {
380 if ((ddns_map_ptr->new_pointer != NULL) &&
381 memcmp(ddns_map_ptr->old_pointer,
382 old_pointer, TRACE_PTR_LEN) == 0) {
383 new_pointer = ddns_map_ptr->new_pointer;
384 ddns_map_ptr->new_pointer = NULL;
385 memset(ddns_map_ptr->old_pointer, 0, TRACE_PTR_LEN);
389 if (ddns_map_ptr == NULL) {
390 log_error(
"trace_dns_input_read: unable to map cb pointer");
394 eventp = (dns_clientupdateevent_t *)
400 sizeof(dns_clientupdateevent_t));
401 if (eventp == NULL) {
402 log_error(
"trace_ddns_input_read: unable to allocate event");
405 eventp->result = ntohl(old_result);
408 ddns_interlude(
dhcp_gbl_ctx.task, (isc_event_t *)eventp);
436trace_ddns_output_write(dns_client_t *client, dns_rdataclass_t rdclass,
437 dns_name_t *zonename, dns_namelist_t *prerequisites,
438 dns_namelist_t *updates, isc_sockaddrlist_t *
servers,
439 dns_tsec_t *tsec,
unsigned int options,
440 isc_task_t *task, isc_taskaction_t action,
void *arg,
441 dns_clientupdatetrans_t **transp)
444 u_int32_t old_result;
445 char old_pointer[TRACE_PTR_LEN];
446 dhcp_ddns_map_t *ddns_map_ptr;
456 log_error(
"trace_ddns_output_write: no input found");
457 return (ISC_R_FAILURE);
459 if (buflen < (
sizeof(old_result) + TRACE_PTR_LEN)) {
460 log_error(
"trace_ddns_output_write: data too short");
462 return (ISC_R_FAILURE);
464 memcpy(&old_result, inbuf,
sizeof(old_result));
465 result = ntohl(old_result);
466 memcpy(old_pointer, inbuf +
sizeof(old_result), TRACE_PTR_LEN);
470 for (ddns_map_ptr = ddns_map;
471 ddns_map_ptr != NULL;
472 ddns_map_ptr = ddns_map_ptr->next) {
473 if (ddns_map_ptr->new_pointer == NULL) {
482 if (ddns_map_ptr == NULL) {
483 ddns_map_ptr =
dmalloc(
sizeof(*ddns_map_ptr),
MDL);
484 if (ddns_map_ptr == NULL) {
486 "unable to allocate map entry");
487 return(ISC_R_FAILURE);
489 ddns_map_ptr->next = ddns_map;
490 ddns_map = ddns_map_ptr;
493 memcpy(ddns_map_ptr->old_pointer, old_pointer, TRACE_PTR_LEN);
494 ddns_map_ptr->new_pointer = arg;
498 result = dns_client_startupdate(client, rdclass, zonename,
499 prerequisites, updates,
501 task, action, arg, transp);
507 old_result = htonl((u_int32_t)result);
508 memset(old_pointer, 0, TRACE_PTR_LEN);
509 memcpy(old_pointer, &arg,
sizeof(arg));
510 iov[0].
len =
sizeof(old_result);
511 iov[0].
buf = (
char *)&old_result;
512 iov[1].
len = TRACE_PTR_LEN;
513 iov[1].
buf = old_pointer;
517 iov[2].
buf = (
char *)arg;
526trace_ddns_output_read(
trace_type_t *ttype,
unsigned length,
529 log_error(
"unaccounted for ddns output.");
541 trace_ddns_output_read,
542 trace_ddns_output_stop,
MDL);
544 trace_ddns_input_read,
545 trace_ddns_input_stop,
MDL);
549#define ddns_update trace_ddns_output_write
551#define ddns_update dns_client_startupdate
554#define zone_resolve dns_client_startresolve
567 if (ddns_cb != NULL) {
574#if defined (DEBUG_DNS_UPDATES)
584#if defined (DEBUG_DNS_UPDATES)
592 if (ddns_cb->
zone != NULL) {
598 log_error(
"Impossible memory leak at %s:%d (attempt to free "
599 "DDNS Control Block before transaction).",
MDL);
604 log_error(
"Possible memory leak at %s:%d (attempt to free "
605 "DDNS Control Block before fxed6_ia).",
MDL);
645 dns_zone_hash_lookup (&tz,
658 return ISC_R_NOMEMORY;
668 char *tname = (
char *)0;
672 return ISC_R_NOTFOUND;
675 if (
name [len - 1] !=
'.') {
678 return ISC_R_NOMEMORY;
679 strcpy (tname,
name);
685 status = ISC_R_NOTFOUND;
686 else if ((*zone)->timeout && (*zone)->timeout <
cur_time) {
689 status = ISC_R_NOTFOUND;
705 if ((ptr == NULL) || (*ptr == NULL)) {
707#if defined (POINTER_DEBUG)
723#if defined (DEBUG_RC_HISTORY)
726#if defined (POINTER_DEBUG)
749#if defined (NSUPDATE)
750#if defined (DNS_ZONE_LOOKUP)
757zone_addr_to_ns(dhcp_ddns_ns_t *ns_cb,
758 dns_rdataset_t *rdataset)
762 dns_rdata_in_aaaa_t aaaa;
764 dns_rdata_init(&rdata);
765 dns_rdataset_current(rdataset, &rdata);
766 switch (rdataset->type) {
767 case dns_rdatatype_a:
768 (void) dns_rdata_tostruct(&rdata, &a, NULL);
769 memcpy(&ns_cb->addrs[ns_cb->num_addrs], &a.in_addr, 4);
771 dns_rdata_freestruct(&a);
773 case dns_rdatatype_aaaa:
774 (void) dns_rdata_tostruct(&rdata, &aaaa, NULL);
775 memcpy(&ns_cb->addrs6[ns_cb->num_addrs6], &aaaa.in6_addr, 16);
777 dns_rdata_freestruct(&aaaa);
783 if ((ns_cb->ttl == 0) || (ns_cb->ttl > rdataset->ttl))
784 ns_cb->ttl = rdataset->ttl;
819find_zone_addrs(isc_task_t *taskp,
822 dns_clientresevent_t *ddns_event = (dns_clientresevent_t *)eventp;
823 dhcp_ddns_ns_t *ns_cb = (dhcp_ddns_ns_t *)eventp->ev_arg;
824 dns_name_t *ns_name = NULL;
825 dns_rdataset_t *rdataset;
828 dns_rdata_t rdata = DNS_RDATA_INIT;
833 dns_client_destroyrestrans(&ns_cb->transaction);
842 for (
name = ISC_LIST_HEAD(ddns_event->answerlist);
846 for (rdataset = ISC_LIST_HEAD(
name->list);
848 rdataset = ISC_LIST_NEXT(rdataset, link)) {
850 for (result = dns_rdataset_first(rdataset);
852 result = dns_rdataset_next(rdataset)) {
855 zone_addr_to_ns(ns_cb, rdataset);
860 if (ns_cb->num_addrs +
872 for (ns_name = ns_cb->ns_name;
874 ns_name = ISC_LIST_NEXT(ns_name, link)) {
876 if (ns_name == ns_cb->ns_name) {
878 rdataset = ns_cb->rdataset;
880 rdataset = ISC_LIST_HEAD(ns_name->list);
885 rdataset = ISC_LIST_NEXT(rdataset, link)) {
887 if (rdataset->type != dns_rdatatype_ns)
889 dns_rdata_init(&rdata);
891 if (rdataset == ns_cb->rdataset) {
893 if (ns_cb->rdtype == dns_rdatatype_a) {
894 ns_cb->rdtype = dns_rdatatype_aaaa;
896 ns_cb->rdtype = dns_rdatatype_a;
897 if (dns_rdataset_next(rdataset) !=
902 if ((!dns_rdataset_isassociated(rdataset)) ||
903 (dns_rdataset_first(rdataset) !=
908 dns_rdataset_current(rdataset, &rdata);
909 if (dns_rdata_tostruct(&rdata, &ns, NULL) !=
914 ns_cb->ns_name = ns_name;
915 ns_cb->rdataset = rdataset;
921 DNS_CLIENTRESOPT_NODNSSEC,
925 &ns_cb->transaction);
928 dns_rdata_freestruct(&ns);
937 log_error(
"find_zone_ns: unable to continue "
940 isc_result_totext(result));
957 if ((ns_cb->num_addrs != 0) ||
958 (ns_cb->num_addrs6 != 0))
959 cache_found_zone(ns_cb);
962 &ns_cb->eventp->answerlist);
963 isc_event_free((isc_event_t **)&ns_cb->eventp);
965 remove_from_ns_queue(ns_cb);
973 &ddns_event->answerlist);
974 isc_event_free(&eventp);
987find_zone_ns(isc_task_t *taskp,
990 dns_clientresevent_t *ddns_event = (dns_clientresevent_t *)eventp;
991 dhcp_ddns_ns_t *ns_cb = (dhcp_ddns_ns_t *)eventp->ev_arg;
992 dns_fixedname_t zname0;
993 dns_name_t *zname = NULL, *ns_name = NULL;
994 dns_rdataset_t *rdataset;
996 dns_rdata_t rdata = DNS_RDATA_INIT;
1000 dns_client_destroyrestrans(&ns_cb->transaction);
1006 ns_cb->zname = strchr(ns_cb->zname,
'.');
1007 if ((ns_cb->zname == NULL) ||
1008 (ns_cb->zname[1] == 0)) {
1020 zname, dns_rdataclass_in,
1022 DNS_CLIENTRESOPT_NODNSSEC,
1026 &ns_cb->transaction))
1028 log_error(
"find_zone_ns: Unable to build "
1029 "name or start resolve: %s %s",
1031 isc_result_totext(result));
1038 &ddns_event->answerlist);
1039 isc_event_free(&eventp);
1046 ns_cb->eventp = ddns_event;
1047 for (ns_name = ISC_LIST_HEAD(ddns_event->answerlist);
1049 ns_name = ISC_LIST_NEXT(ns_name, link)) {
1051 for (rdataset = ISC_LIST_HEAD(ns_name->list);
1053 rdataset = ISC_LIST_NEXT(rdataset, link)) {
1055 if (rdataset->type != dns_rdatatype_ns)
1058 if ((!dns_rdataset_isassociated(rdataset)) ||
1059 (dns_rdataset_first(rdataset) !=
1063 dns_rdataset_current(rdataset, &rdata);
1064 if (dns_rdata_tostruct(&rdata, &ns, NULL) !=
1069 ns_cb->ns_name = ns_name;
1070 ns_cb->rdataset = rdataset;
1073 result = zone_resolve(
dhcp_gbl_ctx.dnsclient, &ns.name,
1076 DNS_CLIENTRESOPT_NODNSSEC,
1080 &ns_cb->transaction);
1083 dns_rdata_freestruct(&ns);
1092 log_error(
"find_zone_ns: unable to continue "
1095 isc_result_totext(result));
1111 &ddns_event->answerlist);
1112 isc_event_free(&eventp);
1114 remove_from_ns_queue(ns_cb);
1133 isc_result_t status = ISC_R_NOTFOUND;
1134 dhcp_ddns_ns_t *ns_cb;
1135 dns_fixedname_t zname0;
1136 dns_name_t *zname = NULL;
1144 if (ns_cb == NULL) {
1145 log_error(
"find_zone_start: unable to allocate cb");
1146 return(ISC_R_FAILURE);
1148 ns_cb->rdtype = dns_rdatatype_a;
1156 ns_cb->zname = (
char *)ns_cb->oname.data;
1174 zname, dns_rdataclass_in,
1176 DNS_CLIENTRESOPT_NODNSSEC,
1180 &ns_cb->transaction))
1182 log_error(
"find_zone_start: Unable to build "
1183 "name or start resolve: %s %s",
1185 isc_result_totext(status));
1193 add_to_ns_queue(ns_cb);
1203 isc_result_t status = ISC_R_NOTFOUND;
1207 struct in_addr zone_addr;
1208 struct in6_addr zone_addr6;
1218 if ((np == NULL) || (*np ==
'\0')) {
1230 np = strchr(np,
'.');
1245 return (ISC_R_FAILURE);
1249 if (strlen(zone->name) >=
sizeof(ddns_cb->
zone_name)) {
1251 return (ISC_R_NOSPACE);
1253 strcpy((
char *)&ddns_cb->
zone_name[0], zone->name);
1255 memset (&nsaddrs, 0,
sizeof nsaddrs);
1258 if (zone->primary) {
1261 zone->primary,
MDL)) {
1264 if (
ip + 4 > nsaddrs.len)
1266 memcpy(&zone_addr, &nsaddrs.data[
ip], 4);
1267 isc_sockaddr_fromin(&ddns_cb->
zone_addrs[ix],
1280 if (zone->primary6) {
1283 zone->primary6,
MDL)) {
1286 if (
ip + 16 > nsaddrs.len)
1288 memcpy(&zone_addr6, &nsaddrs.data[
ip], 16);
1289 isc_sockaddr_fromin6(&ddns_cb->
zone_addrs[ix],
1302 if (zone->secondary) {
1305 zone->secondary,
MDL)) {
1308 if (
ip + 4 > nsaddrs.len)
1310 memcpy(&zone_addr, &nsaddrs.data[
ip], 4);
1311 isc_sockaddr_fromin(&ddns_cb->
zone_addrs[ix],
1324 if (zone->secondary6) {
1327 zone->secondary6,
MDL)) {
1330 if (
ip + 16 > nsaddrs.len)
1332 memcpy(&zone_addr6, &nsaddrs.data[
ip], 16);
1333 isc_sockaddr_fromin6(&ddns_cb->
zone_addrs[ix],
1359 if ((zone == NULL) || (*zone == NULL)) {
1360 log_info(
"Null argument to repudiate zone");
1368#if defined (DNS_ZONE_LOOKUP)
1369void cache_found_zone(dhcp_ddns_ns_t *ns_cb)
1372 int len, remove_zone = 0;
1398 len = strlen(ns_cb->zname);
1400 if (zone->
name == NULL) {
1405 strcpy(zone->
name, ns_cb->zname);
1406 if (zone->
name[len-1] !=
'.') {
1407 zone->
name[len] =
'.';
1408 zone->
name[len+1] = 0;
1414 if (ns_cb->num_addrs != 0) {
1415 len = ns_cb->num_addrs *
sizeof(
struct in_addr);
1419 if (remove_zone == 1)
1420 remove_dns_zone(zone);
1428 if (ns_cb->num_addrs6 != 0) {
1429 len = ns_cb->num_addrs6 *
sizeof(
struct in6_addr);
1433 if (remove_zone == 1)
1434 remove_dns_zone(zone);
1477 const u_int8_t *identifier,
1481 isc_sha256_t sha256;
1482 unsigned char buf[ISC_SHA256_DIGESTLENGTH];
1483 unsigned char fwd_buf[256];
1484 unsigned fwd_buflen = 0;
1487 if (type < 0 || type > 65535)
1493 while(fwd_buf[fwd_buflen] != 0) {
1494 fwd_buflen += fwd_buf[fwd_buflen] + 1;
1499 ISC_SHA256_DIGESTLENGTH + 2 + 1,
1502 id->
data =
id->buffer->data;
1511 isc_sha256_init(&sha256);
1512 isc_sha256_update(&sha256, identifier, id_len);
1513 isc_sha256_update(&sha256, fwd_buf, fwd_buflen);
1514 isc_sha256_final(buf, &sha256);
1516 memcpy(id->
buffer->
data + 3, &buf, ISC_SHA256_DIGESTLENGTH);
1518 id->len = ISC_SHA256_DIGESTLENGTH + 2 + 1;
1546 const u_int8_t *
data,
1550 unsigned char buf[ISC_MD5_DIGESTLENGTH];
1555 if (type < 0 || type > 65535)
1563 (ISC_MD5_DIGESTLENGTH * 2) + 4,
MDL))
1565 id->
data =
id->buffer->data;
1572 id->buffer->data[0] = ISC_MD5_DIGESTLENGTH * 2 + 2;
1575 id->buffer->data[1] =
"0123456789abcdef"[(type >> 4) & 0xf];
1580 id->buffer->data[2] =
"0123456789abcdef"[type % 15];
1584 isc_md5_update(&md5,
data,
len);
1585 isc_md5_final(&md5, buf);
1588 for (i = 0; i < ISC_MD5_DIGESTLENGTH; i++) {
1589 id->buffer->data[i * 2 + 3] =
1590 "0123456789abcdef"[(buf[i] >> 4) & 0xf];
1591 id->buffer->data[i * 2 + 4] =
1592 "0123456789abcdef"[buf[i] & 0xf];
1595 id->len = ISC_MD5_DIGESTLENGTH * 2 + 3;
1596 id->buffer->data[
id->len] = 0;
1604 const u_int8_t *identifier,
1608 return get_std_dhcid(ddns_cb, type, identifier, id_len);
1610 return get_int_dhcid(ddns_cb, type, identifier, id_len);
1639 return(ISC_R_FAILURE);
1646 dhcid->
len = leaseid->
len + 1;
1664make_dns_dataset(dns_rdataclass_t dataclass,
1665 dns_rdatatype_t datatype,
1667 unsigned char *
data,
1671 dns_rdata_t *rdata = &dataspace->
rdata;
1672 dns_rdatalist_t *rdatalist = &dataspace->
rdatalist;
1673 dns_rdataset_t *rdataset = &dataspace->
rdataset;
1675 isc_region_t region;
1678 dns_rdata_init(rdata);
1682 rdata->flags = DNS_RDATA_UPDATE;
1683 rdata->type = datatype;
1684 rdata->rdclass = dataclass;
1687 case dns_rdatatype_a:
1688 case dns_rdatatype_aaaa:
1689 case dns_rdatatype_txt:
1690 case dns_rdatatype_dhcid:
1691 case dns_rdatatype_ptr:
1695 region.length = datalen;
1696 dns_rdata_fromregion(rdata, dataclass, datatype,
1706 dns_rdatalist_init(rdatalist);
1707 rdatalist->type = datatype;
1708 rdatalist->rdclass = dataclass;
1709 rdatalist->ttl = ttl;
1710 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
1713 dns_rdataset_init(rdataset);
1714 dns_rdatalist_tordataset(rdatalist, rdataset);
1719#if defined (DEBUG_DNS_UPDATES)
1720static void log_call(
char *text, dns_name_t* pname, dns_name_t* uname) {
1724 dns_name_format(pname, buf1, 512);
1730 dns_name_format(uname, buf2, 512);
1735 log_info (
"DDNS: %s: pname:[%s] uname:[%s]", text, buf1, buf2);
1767 isc_result_t result;
1769#if defined (DEBUG_DNS_UPDATES)
1770 log_call(
"build_fwd_add1", pname, uname);
1776 result = make_dns_dataset(dns_rdataclass_none,
1778 dataspace, NULL, 0, 0);
1781 result = make_dns_dataset(dns_rdataclass_none,
1783 dataspace, NULL, 0, 0);
1788 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
1793 result = make_dns_dataset(dns_rdataclass_in, ddns_cb->
address_type,
1800 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
1804 result = make_dns_dataset(dns_rdataclass_in, ddns_cb->
dhcid_class,
1811 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
1862#if defined (DEBUG_DNS_UPDATES)
1863 log_call(
"build_fwd_add2", pname, uname);
1878 unsigned char *match_id = NULL;
1879 int match_id_len = 0;
1880 int match_class = dns_rdataclass_any;
1882 match_id = (
unsigned char*)(ddns_cb->
dhcid.
data);
1884 match_class = dns_rdataclass_in;
1887 result = make_dns_dataset(match_class,
1890 match_id, match_id_len, 0);
1894 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
1899 result = make_dns_dataset(dns_rdataclass_any,
1901 dataspace, NULL, 0, 0);
1905 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
1909 result = make_dns_dataset(dns_rdataclass_in,
1917 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
1923 result = make_dns_dataset(dns_rdataclass_any, ddns_cb->
address_type,
1924 dataspace, NULL, 0, 0);
1928 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
1932 result = make_dns_dataset(dns_rdataclass_in, ddns_cb->
address_type,
1939 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
1979#if defined (DEBUG_DNS_UPDATES)
1980 log_call(
"build_fwd_add3", pname, uname);
1984 result = make_dns_dataset(dns_rdataclass_none,
1986 dataspace, NULL, 0, 0);
1990 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
1994 result = make_dns_dataset(dns_rdataclass_none,
1996 dataspace, NULL, 0, 0);
2000 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2004 result = make_dns_dataset(dns_rdataclass_any,
2006 dataspace, NULL, 0, 0);
2010 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2015 result = make_dns_dataset(dns_rdataclass_in, ddns_cb->
address_type,
2022 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
2026 result = make_dns_dataset(dns_rdataclass_in, ddns_cb->
dhcid_class,
2033 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
2073#if defined (DEBUG_DNS_UPDATES)
2074 log_call(
"build_fwd_add3_other", pname, uname);
2085 result = make_dns_dataset(dns_rdataclass_none,
2087 dataspace, NULL, 0, 0);
2092 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2097 result = make_dns_dataset(dns_rdataclass_any,
2099 dataspace, NULL, 0, 0);
2103 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2108 result = make_dns_dataset(dns_rdataclass_any,
2110 dataspace, NULL, 0, 0);
2114 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
2118 result = make_dns_dataset(dns_rdataclass_in, ddns_cb->
address_type,
2125 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
2129 result = make_dns_dataset(dns_rdataclass_in, ddns_cb->
dhcid_class,
2136 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
2166#if defined (DEBUG_DNS_UPDATES)
2167 log_call(
"build_fwd_rem1", pname, uname);
2179 unsigned char *match_id = NULL;
2180 int match_id_len = 0;
2181 int match_class = dns_rdataclass_any;
2183 match_id = (
unsigned char*)(ddns_cb->
dhcid.
data);
2185 match_class = dns_rdataclass_in;
2188 result = make_dns_dataset(match_class,
2191 match_id, match_id_len, 0);
2195 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2201 result = make_dns_dataset(dns_rdataclass_none, ddns_cb->
address_type,
2208 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
2231 isc_result_t result;
2232 unsigned char *match_id = NULL;
2233 int match_id_len = 0;
2234 int match_class = dns_rdataclass_any;
2236#if defined (DEBUG_DNS_UPDATES)
2237 log_call(
"build_fwd_rem2", pname, uname);
2242 result = make_dns_dataset(dns_rdataclass_none, dns_rdatatype_a,
2243 dataspace, NULL, 0, 0);
2247 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2251 result = make_dns_dataset(dns_rdataclass_none, dns_rdatatype_aaaa,
2252 dataspace, NULL, 0, 0);
2256 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2265 match_id = (
unsigned char*)(ddns_cb->
dhcid.
data);
2267 match_class = dns_rdataclass_none;
2270 result = make_dns_dataset(match_class, ddns_cb->
dhcid_class,
2272 match_id, match_id_len, 0);
2276 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
2303 isc_result_t result;
2304 unsigned char *match_id = NULL;
2305 int match_id_len = 0;
2306 int match_class = dns_rdataclass_any;
2308#if defined (DEBUG_DNS_UPDATES)
2309 log_call(
"build_fwd_rem2_dsmm", pname, uname);
2314 result = make_dns_dataset(dns_rdataclass_none,
2316 dataspace, NULL, 0, 0);
2320 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2329 match_id = (
unsigned char*)(ddns_cb->
dhcid.
data);
2331 match_class = dns_rdataclass_none;
2334 result = make_dns_dataset(match_class, ddns_cb->
dhcid_class,
2336 match_id, match_id_len, 0);
2340 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
2366 isc_result_t result;
2368#if defined (DEBUG_DNS_UPDATES)
2369 log_call(
"build_fwd_rem2_dsmm_other", pname, uname);
2374 result = make_dns_dataset(dns_rdataclass_none, ddns_cb->
dhcid_class,
2375 dataspace, NULL, 0, 0);
2379 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2383 result = make_dns_dataset(dns_rdataclass_any,
2385 dataspace, NULL, 0, 0);
2389 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2394 result = make_dns_dataset(dns_rdataclass_none, ddns_cb->
address_type,
2401 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
2411void ddns_interlude(isc_task_t *taskp,
2412 isc_event_t *eventp)
2415 dns_clientupdateevent_t *ddns_event = (dns_clientupdateevent_t *)eventp;
2416 isc_result_t eresult = ddns_event->result;
2417 isc_result_t result;
2421 isc_event_free(&eventp);
2423#if defined (TRACING)
2425 trace_ddns_input_write(ddns_cb, eresult);
2429#if defined (DEBUG_DNS_UPDATES)
2434 dns_client_destroyupdatetrans(&ddns_cb->
transaction);
2438 if ((eresult == ISC_R_CANCELED) ||
2440#if defined (DEBUG_DNS_UPDATES)
2441 log_info(
"DDNS: completeing transaction cancellation cb=%p, "
2443 ddns_cb, ddns_cb->
flags, isc_result_totext(eresult));
2446 log_info(
"DDNS: cleaning up lease pointer for a cancel "
2454 ddns_cb->
cur_func(ddns_cb, eresult);
2458 if (ddns_cb->
next_op != NULL) {
2467 if ((eresult == DNS_R_NOTAUTH) ||
2468 (eresult == DNS_R_NOTZONE)) {
2472 log_error(
"DDNS: bad zone information, repudiating zone %s",
2478 ISC_LINK_INIT(&ddns_cb->
zone_addrs[i], link);
2491 log_info(
"DDNS: Failed to retry after zone failure");
2492 ddns_cb->
cur_func(ddns_cb, result);
2497 ddns_cb->
cur_func(ddns_cb, eresult);
2512 isc_result_t result;
2513 dns_tsec_t *tsec_key = NULL;
2515#if defined (DEBUG_DNS_UPDATES)
2519 unsigned char *clientname;
2521 dns_namelist_t prereqlist, updatelist;
2522 dns_fixedname_t zname0, pname0, uname0;
2523 dns_name_t *zname = NULL, *pname, *uname;
2525 isc_sockaddrlist_t *zlist = NULL;
2528 result = dns_client_init();
2553 if (ddns_cb->
zone == NULL) {
2555#if defined (DNS_ZONE_LOOKUP)
2556 if (result == ISC_R_NOTFOUND) {
2584 if (ddns_cb->
zone) {
2588 log_error(
"Unable to build name for zone for "
2589 "fwd update: %s %s",
2591 isc_result_totext(result));
2601 if (ddns_cb->
zone->
key != NULL) {
2609 if (tsec_key == NULL) {
2610 log_error(
"No tsec for use with key %s",
2621 log_error(
"Unable to build name for fwd update: %s %s",
2622 clientname, isc_result_totext(result));
2627 dataspace = isc_mem_get(
dhcp_gbl_ctx.mctx,
sizeof(*dataspace) * 4);
2628 if (dataspace == NULL) {
2629 log_error(
"Unable to allocate memory for fwd update");
2630 result = ISC_R_NOMEMORY;
2634 ISC_LIST_INIT(prereqlist);
2635 ISC_LIST_INIT(updatelist);
2637 switch(ddns_cb->
state) {
2639 result = build_fwd_add1(ddns_cb, dataspace, pname, uname);
2643 ISC_LIST_APPEND(prereqlist, pname, link);
2647 result = build_fwd_add2(ddns_cb, dataspace, pname, uname);
2657 ISC_LIST_APPEND(prereqlist, pname, link);
2666 builder = build_dsmm_fwd_add3_other;
2668 builder = build_dsmm_fwd_add3;
2671 result = (*builder)(ddns_cb, dataspace, pname, uname);
2676 ISC_LIST_APPEND(prereqlist, pname, link);
2681 result = build_fwd_rem1(ddns_cb, dataspace, pname, uname);
2685 ISC_LIST_APPEND(prereqlist, pname, link);
2692 builder = build_fwd_rem2_dsmm;
2694 builder = build_fwd_rem2;
2697 result = (*builder)(ddns_cb, dataspace, pname, uname);
2700 ISC_LIST_APPEND(prereqlist, pname, link);
2705 result = build_fwd_rem2_dsmm_other(ddns_cb, dataspace,
2709 ISC_LIST_APPEND(prereqlist, pname, link);
2714 log_error(
"ddns_modify_fwd: Invalid state: %d", ddns_cb->state);
2724 ISC_LIST_APPEND(updatelist, uname, link);
2728 dns_rdataclass_in, zname,
2729 &prereqlist, &updatelist,
2731 DNS_CLIENTUPDOPT_ALLOWRUN,
2735 &ddns_cb->transaction);
2736 if (result == ISC_R_FAMILYNOSUPPORT) {
2737 log_info(
"Unable to perform DDNS update, "
2738 "address family not supported");
2741#if defined (DEBUG_DNS_UPDATES)
2746#if defined (DEBUG_DNS_UPDATES)
2748 log_info(
"DDNS: %s(%d): error in ddns_modify_fwd %s for %p",
2749 file,
line, isc_result_totext(result), ddns_cb);
2753 if (dataspace != NULL) {
2755 sizeof(*dataspace) * 4);
2764 isc_result_t result;
2765 dns_tsec_t *tsec_key = NULL;
2766 unsigned char *ptrname;
2768 dns_namelist_t updatelist;
2769 dns_fixedname_t zname0, uname0;
2770 dns_name_t *zname = NULL, *uname;
2771 isc_sockaddrlist_t *zlist = NULL;
2772 unsigned char buf[256];
2775#if defined (DEBUG_DNS_UPDATES)
2780 result = dns_client_init();
2794#if defined (DNS_ZONE_LOOKUP)
2795 if (result == ISC_R_NOTFOUND) {
2822 log_error(
"Unable to build name for zone for "
2823 "fwd update: %s %s",
2825 isc_result_totext(result));
2839 if ((ddns_cb->
zone != NULL) && (ddns_cb->
zone->
key != NULL)) {
2841 if (tsec_key == NULL) {
2842 log_error(
"No tsec for use with key %s",
2854 log_error(
"Unable to build name for fwd update: %s %s",
2855 ptrname, isc_result_totext(result));
2864 dataspace = isc_mem_get(
dhcp_gbl_ctx.mctx,
sizeof(*dataspace) * 2);
2865 if (dataspace == NULL) {
2866 log_error(
"Unable to allocate memory for fwd update");
2867 result = ISC_R_NOMEMORY;
2871 ISC_LIST_INIT(updatelist);
2878 result = make_dns_dataset(dns_rdataclass_any, dns_rdatatype_ptr,
2879 &dataspace[0], NULL, 0, 0);
2883 ISC_LIST_APPEND(uname->list, &dataspace[0].rdataset, link);
2898 while (buf[buflen] != 0) {
2899 buflen += buf[buflen] + 1;
2903 result = make_dns_dataset(dns_rdataclass_in,
2906 buf, buflen, ddns_cb->
ttl);
2910 ISC_LIST_APPEND(uname->list, &dataspace[1].rdataset, link);
2913 ISC_LIST_APPEND(updatelist, uname, link);
2922 result = ddns_update((dns_client_t *)
dhcp_gbl_ctx.dnsclient,
2923 dns_rdataclass_in, zname,
2926 DNS_CLIENTUPDOPT_ALLOWRUN,
2928 ddns_interlude, (
void *)ddns_cb,
2929 &ddns_cb->transaction);
2930 if (result == ISC_R_FAMILYNOSUPPORT) {
2931 log_info(
"Unable to perform DDNS update, "
2932 "address family not supported");
2935#if defined (DEBUG_DNS_UPDATES)
2940#if defined (DEBUG_DNS_UPDATES)
2942 log_info(
"DDNS: %s(%d): error in ddns_modify_ptr %s for %p",
2943 file,
line, isc_result_totext(result), ddns_cb);
2947 if (dataspace != NULL) {
2949 sizeof(*dataspace) * 2);
2958 dns_client_cancelupdate((dns_clientupdatetrans_t *)
2961 ddns_cb->
lease = NULL;
2963#if defined (DEBUG_DNS_UPDATES)
2964 log_info(
"DDNS: %s(%d): cancelling transaction for %p",
2974#if defined (NSUPDATE)
2975#if defined (DEBUG_DNS_UPDATES)
2984 static LabeledInt ints[] = {
2996 LabeledInt* li = ints;
2997 while (li->val != -1 && li->val != state) {
3005add_nstring(
char **orig,
char *max,
char *add,
int add_len) {
3006 if (*orig && (*orig + add_len < max)) {
3007 strncpy(*orig, add, add_len);
3017add_string(
char **orig,
char *max,
char *add) {
3018 return (add_nstring(orig, max, add, strlen(add)));
3041 isc_result_t result)
3044 char *s = obuf, *end = &obuf[
sizeof(obuf)-2];
3046 const char *result_str;
3048 sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
3051 log_info(
"DDNS reply: id ptr %p, result: %s",
3060 memset(obuf, 0, 1024);
3062 en =
"DDNS request: id ptr ";
3063 if (s + strlen(en) + 16 < end) {
3072 switch (ddns_cb->
state) {
3079 if (s + strlen(en) + strlen(ddns_address) +
3081 sprintf(s,
" %s %s for %.*s", en, ddns_address,
3094 sprintf(s,
" %s %.*s for %.*s", en,
3107 if (s + strlen(en) < end) {
3108 sprintf(s,
"%s", en);
3117 if (s + strlen(en) + strlen((
char *)ddns_cb->
zone_name) < end) {
3118 sprintf(s,
"%s%s", en, ddns_cb->
zone_name);
3125 if (ddns_cb->
dhcid_class == dns_rdatatype_dhcid) {
3127 if (add_string(&s, end,
"dhcid: [")) {
3134 int ret = add_string(&s, end, idbuf);
3141 if (add_string(&s, end,
"]")) {
3147 int skip_length_byte = (ddns_cb->
dhcid.
len > 0 ? 1 : 0);
3148 if (add_string (&s, end,
"txt: [") ||
3149 add_nstring (&s, end,
3150 (
char *)ddns_cb->
dhcid.
data + skip_length_byte,
3151 ddns_cb->
dhcid.
len - skip_length_byte) ||
3152 add_string (&s, end,
"]")) {
3158 if (s + strlen(en) + 10 < end) {
3159 sprintf(s,
"%s%ld", en, ddns_cb->
ttl);
3166 result_str = isc_result_totext(result);
3167 if (s + strlen(en) + strlen(result_str) < end) {
3168 sprintf(s,
"%s%s", en, result_str);
#define rc_register(file, line, reference, addr, refcnt, d, f)
int buffer_allocate(struct buffer **ptr, unsigned len, const char *file, int line)
void data_string_forget(struct data_string *data, const char *file, int line)
int dns_zone_reference(struct dns_zone **ptr, struct dns_zone *bp, const char *file, int line)
int dns_zone_allocate(struct dns_zone **ptr, const char *file, int line)
void data_string_copy(struct data_string *dest, const struct data_string *src, const char *file, int line)
int option_cache_allocate(struct option_cache **cptr, const char *file, int line)
int option_cache_dereference(struct option_cache **ptr, const char *file, int line)
char * buf_to_hex(const unsigned char *s, unsigned len, const char *file, int line)
void putUShort(unsigned char *, u_int32_t)
void putUChar(unsigned char *, u_int32_t)
void repudiate_zone(struct dns_zone **)
#define DDNS_GUARD_ID_MUST_MATCH
#define DDNS_INCLUDE_RRSET
#define DNS_ZONE_INACTIVE
isc_result_t find_cached_zone(dhcp_ddns_cb_t *, int)
struct dhcp_ddns_cb dhcp_ddns_cb_t
void dhcid_tolease(struct data_string *, struct data_string *)
void ddns_cancel(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
#define DDNS_STATE_REM_FW_NXRR
#define DDNS_STATE_ADD_FW_YXDHCID
isc_result_t ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
#define DDNS_STATE_REM_PTR
struct hash_table dns_zone_hash_t
#define DDNS_STATE_ADD_FW_NXDOMAIN
#define DDNS_STATE_ADD_PTR
isc_result_t dhcid_fromlease(struct data_string *, struct data_string *)
char * ddns_state_name(int state)
void ddns_cb_forget_zone(dhcp_ddns_cb_t *ddns_cb)
#define DDNS_STATE_DSMM_FW_ADD3
void trace_ddns_init(void)
#define DDNS_STATE_REM_FW_YXDHCID
void forget_zone(struct dns_zone **)
#define DDNS_PRINT_OUTBOUND
isc_result_t ddns_modify_ptr(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
#define DDNS_STATE_CLEANUP
dhcp_ddns_cb_t * ddns_cb_alloc(const char *file, int line)
void print_dns_status(int, struct dhcp_ddns_cb *, isc_result_t)
#define DDNS_PRINT_INBOUND
#define DDNS_OTHER_GUARD_IS_DYNAMIC
int get_dhcid(dhcp_ddns_cb_t *, int, const u_int8_t *, unsigned)
#define DDNS_CONFLICT_DETECTION
#define DDNS_STATE_REM_FW_DSMM_OTHER
void ddns_cb_free(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
#define DDNS_DUAL_STACK_MIXED_MODE
struct server_list * servers
struct dhcp_ddns_rdata dhcp_ddns_data_t
isc_result_t(* builder_func_t)(dhcp_ddns_cb_t *ddns_cb, dhcp_ddns_data_t *dataspace, dns_name_t *pname, dns_name_t *uname)
isc_result_t dns_zone_lookup(struct dns_zone **zone, const char *name)
isc_result_t remove_dns_zone(struct dns_zone *zone)
isc_result_t enter_dns_zone(struct dns_zone *zone)
int dns_zone_dereference(struct dns_zone **ptr, const char *file, int line)
dns_zone_hash_t * dns_zone_hash
unsigned do_case_hash(const void *, unsigned, unsigned)
#define HASH_FUNCTIONS(name, bufarg, type, hashtype, ref, deref, hasher)
const char * piaddr(const struct iaddr addr)
isc_result_t dhcp_isc_name(unsigned char *namestr, dns_fixedname_t *namefix, dns_name_t **name)
dhcp_context_t dhcp_gbl_ctx
int MRns_name_pton(const char *src, u_char *dst, size_t dstsiz)
void * dmalloc(size_t, const char *, int)
void dfree(void *, const char *, int)
int log_error(const char *,...) __attribute__((__format__(__printf__
int int log_info(const char *,...) __attribute__((__format__(__printf__
#define DHCP_R_INVALIDARG
const unsigned char * data
dns_rdataclass_t other_dhcid_class
isc_sockaddr_t zone_addrs[DHCP_MAXNS]
struct data_string fwd_name
dns_rdataclass_t dhcid_class
struct data_string rev_name
unsigned char zone_name[DHCP_MAXDNS_WIRE]
struct dhcp_ddns_cb * next_op
isc_sockaddrlist_t zone_server_list
dns_rdatalist_t rdatalist
struct option_cache * secondary6
struct option_cache * secondary
struct option_cache * primary
struct option_cache * primary6
struct trace_iov trace_iov_t
trace_type_t * trace_type_register(const char *, void *, void(*)(trace_type_t *, unsigned, char *), void(*)(trace_type_t *), const char *, int)
isc_result_t trace_get_packet(trace_type_t **, unsigned *, char **)
struct trace_type trace_type_t
isc_result_t trace_write_packet_iov(trace_type_t *, int, trace_iov_t *, const char *, int)
int evaluate_option_cache(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct option_cache *oc, const char *file, int line)
struct binding_scope * global_scope