35 #include <dns/result.h> 158 dns_name_t *pname, dns_name_t *uname);
160 #if defined (NSUPDATE) 161 #if defined (DNS_ZONE_LOOKUP) 175 typedef 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;
211 dhcp_ddns_ns_t *dns_outstanding_ns = NULL;
229 add_to_ns_queue(dhcp_ddns_ns_t *ns_cb)
231 ns_cb->next = dns_outstanding_ns;
232 dns_outstanding_ns = ns_cb;
237 remove_from_ns_queue(dhcp_ddns_ns_t *ns_cb)
239 dhcp_ddns_ns_t **foo;
241 foo = &dns_outstanding_ns;
247 foo = &((*foo)->next);
253 find_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)
268 return(ISC_R_SUCCESS);
270 return(ISC_R_NOTFOUND);
273 void cache_found_zone (dhcp_ddns_ns_t *);
276 void ddns_interlude(isc_task_t *, isc_event_t *);
278 #if defined (TRACING) 314 #define TRACE_PTR_LEN 8 316 typedef struct dhcp_ddns_map {
317 char old_pointer[TRACE_PTR_LEN];
319 struct dhcp_ddns_map *next;
323 static dhcp_ddns_map_t *ddns_map;
335 trace_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;
359 trace_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);
436 trace_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;
455 if (result != ISC_R_SUCCESS) {
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;
526 trace_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);
637 return (ISC_R_SUCCESS);
645 dns_zone_hash_lookup (&tz,
649 return ISC_R_SUCCESS;
658 return ISC_R_NOMEMORY;
662 return ISC_R_SUCCESS;
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;
691 status = ISC_R_SUCCESS;
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) 757 zone_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;
819 find_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);
840 if (ddns_event->result == ISC_R_SUCCESS) {
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);
851 result == ISC_R_SUCCESS;
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);
930 if (result == ISC_R_SUCCESS)
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);
987 find_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);
1002 if (ddns_event->result != ISC_R_SUCCESS) {
1006 ns_cb->zname = strchr(ns_cb->zname,
'.');
1007 if ((ns_cb->zname == NULL) ||
1008 (ns_cb->zname[1] == 0)) {
1018 != ISC_R_SUCCESS) ||
1020 zname, dns_rdataclass_in,
1022 DNS_CLIENTRESOPT_NODNSSEC,
1026 &ns_cb->transaction))
1027 != ISC_R_SUCCESS)) {
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);
1085 if (result == ISC_R_SUCCESS)
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;
1162 if (find_in_ns_queue(ns_cb) == ISC_R_SUCCESS) {
1165 return (ISC_R_SUCCESS);
1172 != ISC_R_SUCCESS) ||
1174 zname, dns_rdataclass_in,
1176 DNS_CLIENTRESOPT_NODNSSEC,
1180 &ns_cb->transaction))
1181 != ISC_R_SUCCESS)) {
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')) {
1227 if (status == ISC_R_SUCCESS)
1230 np = strchr(np,
'.');
1236 if (status != ISC_R_SUCCESS)
1245 return (ISC_R_FAILURE);
1251 return (ISC_R_NOSPACE);
1255 memset (&nsaddrs, 0,
sizeof nsaddrs);
1264 if (
ip + 4 > nsaddrs.len)
1266 memcpy(&zone_addr, &nsaddrs.data[
ip], 4);
1267 isc_sockaddr_fromin(&ddns_cb->
zone_addrs[ix],
1286 if (
ip + 16 > nsaddrs.len)
1288 memcpy(&zone_addr6, &nsaddrs.data[
ip], 16);
1289 isc_sockaddr_fromin6(&ddns_cb->
zone_addrs[ix],
1308 if (
ip + 4 > nsaddrs.len)
1310 memcpy(&zone_addr, &nsaddrs.data[
ip], 4);
1311 isc_sockaddr_fromin(&ddns_cb->
zone_addrs[ix],
1330 if (
ip + 16 > nsaddrs.len)
1332 memcpy(&zone_addr6, &nsaddrs.data[
ip], 16);
1333 isc_sockaddr_fromin6(&ddns_cb->
zone_addrs[ix],
1348 return ISC_R_SUCCESS;
1359 if ((zone == NULL) || (*zone == NULL)) {
1360 log_info(
"Null argument to repudiate zone");
1368 #if defined (DNS_ZONE_LOOKUP) 1369 void cache_found_zone(dhcp_ddns_ns_t *ns_cb)
1372 int len, remove_zone = 0;
1397 len = strlen(ns_cb->zname);
1399 if (zone->
name == NULL) {
1404 strcpy(zone->
name, ns_cb->zname);
1405 if (zone->
name[len-1] !=
'.') {
1406 zone->
name[len] =
'.';
1407 zone->
name[len+1] = 0;
1413 if (ns_cb->num_addrs != 0) {
1414 len = ns_cb->num_addrs *
sizeof(
struct in_addr);
1418 if (remove_zone == 1)
1427 if (ns_cb->num_addrs6 != 0) {
1428 len = ns_cb->num_addrs6 *
sizeof(
struct in6_addr);
1432 if (remove_zone == 1)
1476 const u_int8_t *identifier,
1480 isc_sha256_t sha256;
1481 unsigned char buf[ISC_SHA256_DIGESTLENGTH];
1482 unsigned char fwd_buf[256];
1483 unsigned fwd_buflen = 0;
1486 if (type < 0 || type > 65535)
1492 while(fwd_buf[fwd_buflen] != 0) {
1493 fwd_buflen += fwd_buf[fwd_buflen] + 1;
1498 ISC_SHA256_DIGESTLENGTH + 2 + 1,
1501 id->
data =
id->buffer->data;
1510 isc_sha256_init(&sha256);
1511 isc_sha256_update(&sha256, identifier, id_len);
1512 isc_sha256_update(&sha256, fwd_buf, fwd_buflen);
1513 isc_sha256_final(buf, &sha256);
1515 memcpy(id->
buffer->
data + 3, &buf, ISC_SHA256_DIGESTLENGTH);
1517 id->len = ISC_SHA256_DIGESTLENGTH + 2 + 1;
1545 const u_int8_t *
data,
1549 unsigned char buf[ISC_MD5_DIGESTLENGTH];
1554 if (type < 0 || type > 65535)
1562 (ISC_MD5_DIGESTLENGTH * 2) + 4,
MDL))
1564 id->
data =
id->buffer->data;
1571 id->buffer->data[0] = ISC_MD5_DIGESTLENGTH * 2 + 2;
1574 id->buffer->data[1] =
"0123456789abcdef"[(type >> 4) & 0xf];
1579 id->buffer->data[2] =
"0123456789abcdef"[type % 15];
1583 isc_md5_update(&md5,
data,
len);
1584 isc_md5_final(&md5, buf);
1587 for (i = 0; i < ISC_MD5_DIGESTLENGTH; i++) {
1588 id->buffer->data[i * 2 + 3] =
1589 "0123456789abcdef"[(buf[i] >> 4) & 0xf];
1590 id->buffer->data[i * 2 + 4] =
1591 "0123456789abcdef"[buf[i] & 0xf];
1594 id->len = ISC_MD5_DIGESTLENGTH * 2 + 3;
1595 id->buffer->data[
id->len] = 0;
1603 const u_int8_t *identifier,
1607 return get_std_dhcid(ddns_cb, type, identifier, id_len);
1609 return get_int_dhcid(ddns_cb, type, identifier, id_len);
1638 return(ISC_R_FAILURE);
1645 dhcid->
len = leaseid->
len + 1;
1651 return(ISC_R_SUCCESS);
1663 make_dns_dataset(dns_rdataclass_t dataclass,
1664 dns_rdatatype_t datatype,
1666 unsigned char *
data,
1670 dns_rdata_t *rdata = &dataspace->
rdata;
1671 dns_rdatalist_t *rdatalist = &dataspace->
rdatalist;
1672 dns_rdataset_t *rdataset = &dataspace->
rdataset;
1674 isc_region_t region;
1677 dns_rdata_init(rdata);
1681 rdata->flags = DNS_RDATA_UPDATE;
1682 rdata->type = datatype;
1683 rdata->rdclass = dataclass;
1686 case dns_rdatatype_a:
1687 case dns_rdatatype_aaaa:
1688 case dns_rdatatype_txt:
1689 case dns_rdatatype_dhcid:
1690 case dns_rdatatype_ptr:
1694 region.length = datalen;
1695 dns_rdata_fromregion(rdata, dataclass, datatype,
1705 dns_rdatalist_init(rdatalist);
1706 rdatalist->type = datatype;
1707 rdatalist->rdclass = dataclass;
1708 rdatalist->ttl = ttl;
1709 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
1712 dns_rdataset_init(rdataset);
1713 dns_rdatalist_tordataset(rdatalist, rdataset);
1715 return(ISC_R_SUCCESS);
1718 #if defined (DEBUG_DNS_UPDATES) 1719 static void log_call(
char *text, dns_name_t* pname, dns_name_t* uname) {
1723 dns_name_format(pname, buf1, 512);
1729 dns_name_format(uname, buf2, 512);
1734 log_info (
"DDNS: %s: pname:[%s] uname:[%s]", text, buf1, buf2);
1766 isc_result_t result;
1768 #if defined (DEBUG_DNS_UPDATES) 1769 log_call(
"build_fwd_add1", pname, uname);
1775 result = make_dns_dataset(dns_rdataclass_none,
1777 dataspace, NULL, 0, 0);
1780 result = make_dns_dataset(dns_rdataclass_none,
1782 dataspace, NULL, 0, 0);
1784 if (result != ISC_R_SUCCESS) {
1787 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
1792 result = make_dns_dataset(dns_rdataclass_in, ddns_cb->
address_type,
1796 if (result != ISC_R_SUCCESS) {
1799 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
1803 result = make_dns_dataset(dns_rdataclass_in, ddns_cb->
dhcid_class,
1807 if (result != ISC_R_SUCCESS) {
1810 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
1812 return(ISC_R_SUCCESS);
1859 isc_result_t result = ISC_R_SUCCESS;
1861 #if defined (DEBUG_DNS_UPDATES) 1862 log_call(
"build_fwd_add2", pname, uname);
1877 unsigned char *match_id = NULL;
1878 int match_id_len = 0;
1879 int match_class = dns_rdataclass_any;
1881 match_id = (
unsigned char*)(ddns_cb->
dhcid.
data);
1883 match_class = dns_rdataclass_in;
1886 result = make_dns_dataset(match_class,
1889 match_id, match_id_len, 0);
1890 if (result != ISC_R_SUCCESS) {
1893 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
1898 result = make_dns_dataset(dns_rdataclass_any,
1900 dataspace, NULL, 0, 0);
1901 if (result != ISC_R_SUCCESS) {
1904 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
1908 result = make_dns_dataset(dns_rdataclass_in,
1913 if (result != ISC_R_SUCCESS) {
1916 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
1922 result = make_dns_dataset(dns_rdataclass_any, ddns_cb->
address_type,
1923 dataspace, NULL, 0, 0);
1924 if (result != ISC_R_SUCCESS) {
1927 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
1931 result = make_dns_dataset(dns_rdataclass_in, ddns_cb->
address_type,
1935 if (result != ISC_R_SUCCESS) {
1938 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
1940 return(ISC_R_SUCCESS);
1976 isc_result_t result = ISC_R_SUCCESS;
1978 #if defined (DEBUG_DNS_UPDATES) 1979 log_call(
"build_fwd_add3", pname, uname);
1983 result = make_dns_dataset(dns_rdataclass_none,
1985 dataspace, NULL, 0, 0);
1986 if (result != ISC_R_SUCCESS) {
1989 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
1993 result = make_dns_dataset(dns_rdataclass_none,
1995 dataspace, NULL, 0, 0);
1996 if (result != ISC_R_SUCCESS) {
1999 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2003 result = make_dns_dataset(dns_rdataclass_any,
2005 dataspace, NULL, 0, 0);
2006 if (result != ISC_R_SUCCESS) {
2009 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2014 result = make_dns_dataset(dns_rdataclass_in, ddns_cb->
address_type,
2018 if (result != ISC_R_SUCCESS) {
2021 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
2025 result = make_dns_dataset(dns_rdataclass_in, ddns_cb->
dhcid_class,
2029 if (result != ISC_R_SUCCESS) {
2032 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
2034 return(ISC_R_SUCCESS);
2070 isc_result_t result = ISC_R_SUCCESS;
2072 #if defined (DEBUG_DNS_UPDATES) 2073 log_call(
"build_fwd_add3_other", pname, uname);
2077 result = make_dns_dataset(dns_rdataclass_any,
2079 dataspace, NULL, 0, 0);
2080 if (result != ISC_R_SUCCESS) {
2083 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2088 result = make_dns_dataset(dns_rdataclass_any,
2090 dataspace, NULL, 0, 0);
2091 if (result != ISC_R_SUCCESS) {
2094 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
2098 result = make_dns_dataset(dns_rdataclass_in, ddns_cb->
address_type,
2102 if (result != ISC_R_SUCCESS) {
2105 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
2109 result = make_dns_dataset(dns_rdataclass_in, ddns_cb->
dhcid_class,
2113 if (result != ISC_R_SUCCESS) {
2116 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
2118 return(ISC_R_SUCCESS);
2144 isc_result_t result = ISC_R_SUCCESS;
2146 #if defined (DEBUG_DNS_UPDATES) 2147 log_call(
"build_fwd_rem1", pname, uname);
2159 unsigned char *match_id = NULL;
2160 int match_id_len = 0;
2161 int match_class = dns_rdataclass_any;
2163 match_id = (
unsigned char*)(ddns_cb->
dhcid.
data);
2165 match_class = dns_rdataclass_in;
2168 result = make_dns_dataset(match_class,
2171 match_id, match_id_len, 0);
2172 if (result != ISC_R_SUCCESS) {
2175 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2181 result = make_dns_dataset(dns_rdataclass_none, ddns_cb->
address_type,
2185 if (result != ISC_R_SUCCESS) {
2188 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
2190 return(ISC_R_SUCCESS);
2211 isc_result_t result;
2212 unsigned char *match_id = NULL;
2213 int match_id_len = 0;
2214 int match_class = dns_rdataclass_any;
2216 #if defined (DEBUG_DNS_UPDATES) 2217 log_call(
"build_fwd_rem2", pname, uname);
2222 result = make_dns_dataset(dns_rdataclass_none, dns_rdatatype_a,
2223 dataspace, NULL, 0, 0);
2224 if (result != ISC_R_SUCCESS) {
2227 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2231 result = make_dns_dataset(dns_rdataclass_none, dns_rdatatype_aaaa,
2232 dataspace, NULL, 0, 0);
2233 if (result != ISC_R_SUCCESS) {
2236 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2245 match_id = (
unsigned char*)(ddns_cb->
dhcid.
data);
2247 match_class = dns_rdataclass_none;
2250 result = make_dns_dataset(match_class, ddns_cb->
dhcid_class,
2252 match_id, match_id_len, 0);
2253 if (result != ISC_R_SUCCESS) {
2256 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
2258 return(ISC_R_SUCCESS);
2283 isc_result_t result;
2284 unsigned char *match_id = NULL;
2285 int match_id_len = 0;
2286 int match_class = dns_rdataclass_any;
2288 #if defined (DEBUG_DNS_UPDATES) 2289 log_call(
"build_fwd_rem2_dsmm", pname, uname);
2294 result = make_dns_dataset(dns_rdataclass_none,
2296 dataspace, NULL, 0, 0);
2297 if (result != ISC_R_SUCCESS) {
2300 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2309 match_id = (
unsigned char*)(ddns_cb->
dhcid.
data);
2311 match_class = dns_rdataclass_none;
2314 result = make_dns_dataset(match_class, ddns_cb->
dhcid_class,
2316 match_id, match_id_len, 0);
2317 if (result != ISC_R_SUCCESS) {
2320 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
2322 return(ISC_R_SUCCESS);
2346 isc_result_t result;
2348 #if defined (DEBUG_DNS_UPDATES) 2349 log_call(
"build_fwd_rem2_dsmm_other", pname, uname);
2354 result = make_dns_dataset(dns_rdataclass_none, ddns_cb->
dhcid_class,
2355 dataspace, NULL, 0, 0);
2356 if (result != ISC_R_SUCCESS) {
2359 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2363 result = make_dns_dataset(dns_rdataclass_any,
2365 dataspace, NULL, 0, 0);
2366 if (result != ISC_R_SUCCESS) {
2369 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2374 result = make_dns_dataset(dns_rdataclass_none, ddns_cb->
address_type,
2378 if (result != ISC_R_SUCCESS) {
2381 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
2383 return(ISC_R_SUCCESS);
2391 void ddns_interlude(isc_task_t *taskp,
2392 isc_event_t *eventp)
2395 dns_clientupdateevent_t *ddns_event = (dns_clientupdateevent_t *)eventp;
2396 isc_result_t eresult = ddns_event->result;
2397 isc_result_t result;
2401 isc_event_free(&eventp);
2403 #if defined (TRACING) 2405 trace_ddns_input_write(ddns_cb, eresult);
2409 #if defined (DEBUG_DNS_UPDATES) 2414 dns_client_destroyupdatetrans(&ddns_cb->
transaction);
2418 if ((eresult == ISC_R_CANCELED) ||
2420 #if defined (DEBUG_DNS_UPDATES) 2421 log_info(
"DDNS: completeing transaction cancellation cb=%p, " 2423 ddns_cb, ddns_cb->
flags, isc_result_totext(eresult));
2426 log_info(
"DDNS: cleaning up lease pointer for a cancel " 2434 ddns_cb->
cur_func(ddns_cb, eresult);
2438 if (ddns_cb->
next_op != NULL) {
2447 if ((eresult == DNS_R_NOTAUTH) ||
2448 (eresult == DNS_R_NOTZONE)) {
2452 log_error(
"DDNS: bad zone information, repudiating zone %s",
2458 ISC_LINK_INIT(&ddns_cb->
zone_addrs[i], link);
2468 if (result != ISC_R_SUCCESS) {
2471 log_info(
"DDNS: Failed to retry after zone failure");
2472 ddns_cb->
cur_func(ddns_cb, result);
2477 ddns_cb->
cur_func(ddns_cb, eresult);
2492 isc_result_t result;
2493 dns_tsec_t *tsec_key = NULL;
2495 #if defined (DEBUG_DNS_UPDATES) 2499 unsigned char *clientname;
2501 dns_namelist_t prereqlist, updatelist;
2502 dns_fixedname_t zname0, pname0, uname0;
2503 dns_name_t *zname = NULL, *pname, *uname;
2505 isc_sockaddrlist_t *zlist = NULL;
2509 if (result != ISC_R_SUCCESS) {
2533 if (ddns_cb->
zone == NULL) {
2535 #if defined (DNS_ZONE_LOOKUP) 2536 if (result == ISC_R_NOTFOUND) {
2555 if (result != ISC_R_SUCCESS)
2564 if (ddns_cb->
zone) {
2567 if (result != ISC_R_SUCCESS) {
2568 log_error(
"Unable to build name for zone for " 2569 "fwd update: %s %s",
2571 isc_result_totext(result));
2581 if (ddns_cb->
zone->
key != NULL) {
2589 if (tsec_key == NULL) {
2590 log_error(
"No tsec for use with key %s",
2598 != ISC_R_SUCCESS) ||
2600 != ISC_R_SUCCESS)) {
2601 log_error(
"Unable to build name for fwd update: %s %s",
2602 clientname, isc_result_totext(result));
2608 if (dataspace == NULL) {
2609 log_error(
"Unable to allocate memory for fwd update");
2610 result = ISC_R_NOMEMORY;
2614 ISC_LIST_INIT(prereqlist);
2615 ISC_LIST_INIT(updatelist);
2617 switch(ddns_cb->
state) {
2619 result = build_fwd_add1(ddns_cb, dataspace, pname, uname);
2620 if (result != ISC_R_SUCCESS) {
2623 ISC_LIST_APPEND(prereqlist, pname, link);
2627 result = build_fwd_add2(ddns_cb, dataspace, pname, uname);
2628 if (result != ISC_R_SUCCESS) {
2637 ISC_LIST_APPEND(prereqlist, pname, link);
2646 builder = build_dsmm_fwd_add3_other;
2648 builder = build_dsmm_fwd_add3;
2651 result = (*builder)(ddns_cb, dataspace, pname, uname);
2652 if (result != ISC_R_SUCCESS) {
2656 ISC_LIST_APPEND(prereqlist, pname, link);
2661 result = build_fwd_rem1(ddns_cb, dataspace, pname, uname);
2662 if (result != ISC_R_SUCCESS) {
2665 ISC_LIST_APPEND(prereqlist, pname, link);
2672 builder = build_fwd_rem2_dsmm;
2674 builder = build_fwd_rem2;
2677 result = (*builder)(ddns_cb, dataspace, pname, uname);
2678 if (result != ISC_R_SUCCESS) {
2680 ISC_LIST_APPEND(prereqlist, pname, link);
2685 result = build_fwd_rem2_dsmm_other(ddns_cb, dataspace,
2687 if (result != ISC_R_SUCCESS) {
2689 ISC_LIST_APPEND(prereqlist, pname, link);
2694 log_error(
"ddns_modify_fwd: Invalid state: %d", ddns_cb->state);
2704 ISC_LIST_APPEND(updatelist, uname, link);
2708 dns_rdataclass_in, zname,
2709 &prereqlist, &updatelist,
2711 DNS_CLIENTRESOPT_ALLOWRUN,
2715 &ddns_cb->transaction);
2716 if (result == ISC_R_FAMILYNOSUPPORT) {
2717 log_info(
"Unable to perform DDNS update, " 2718 "address family not supported");
2721 #if defined (DEBUG_DNS_UPDATES) 2726 #if defined (DEBUG_DNS_UPDATES) 2727 if (result != ISC_R_SUCCESS) {
2728 log_info(
"DDNS: %s(%d): error in ddns_modify_fwd %s for %p",
2729 file,
line, isc_result_totext(result), ddns_cb);
2733 if (dataspace != NULL) {
2735 sizeof(*dataspace) * 4);
2744 isc_result_t result;
2745 dns_tsec_t *tsec_key = NULL;
2746 unsigned char *ptrname;
2748 dns_namelist_t updatelist;
2749 dns_fixedname_t zname0, uname0;
2750 dns_name_t *zname = NULL, *uname;
2751 isc_sockaddrlist_t *zlist = NULL;
2752 unsigned char buf[256];
2755 #if defined (DEBUG_DNS_UPDATES) 2761 if (result != ISC_R_SUCCESS) {
2774 #if defined (DNS_ZONE_LOOKUP) 2775 if (result == ISC_R_NOTFOUND) {
2780 if (find_zone_start(ddns_cb,
FIND_REVERSE) == ISC_R_SUCCESS) {
2793 if (result != ISC_R_SUCCESS)
2797 if ((result == ISC_R_SUCCESS) &&
2801 if (result != ISC_R_SUCCESS) {
2802 log_error(
"Unable to build name for zone for " 2803 "fwd update: %s %s",
2805 isc_result_totext(result));
2819 if ((ddns_cb->
zone != NULL) && (ddns_cb->
zone->
key != NULL)) {
2821 if (tsec_key == NULL) {
2822 log_error(
"No tsec for use with key %s",
2834 log_error(
"Unable to build name for fwd update: %s %s",
2835 ptrname, isc_result_totext(result));
2845 if (dataspace == NULL) {
2846 log_error(
"Unable to allocate memory for fwd update");
2847 result = ISC_R_NOMEMORY;
2851 ISC_LIST_INIT(updatelist);
2858 result = make_dns_dataset(dns_rdataclass_any, dns_rdatatype_ptr,
2859 &dataspace[0], NULL, 0, 0);
2860 if (result != ISC_R_SUCCESS) {
2863 ISC_LIST_APPEND(uname->list, &dataspace[0].rdataset, link);
2878 while (buf[buflen] != 0) {
2879 buflen += buf[buflen] + 1;
2883 result = make_dns_dataset(dns_rdataclass_in,
2886 buf, buflen, ddns_cb->
ttl);
2887 if (result != ISC_R_SUCCESS) {
2890 ISC_LIST_APPEND(uname->list, &dataspace[1].rdataset, link);
2893 ISC_LIST_APPEND(updatelist, uname, link);
2902 result = ddns_update((dns_client_t *)
dhcp_gbl_ctx.dnsclient,
2903 dns_rdataclass_in, zname,
2906 DNS_CLIENTRESOPT_ALLOWRUN,
2908 ddns_interlude, (
void *)ddns_cb,
2909 &ddns_cb->transaction);
2910 if (result == ISC_R_FAMILYNOSUPPORT) {
2911 log_info(
"Unable to perform DDNS update, " 2912 "address family not supported");
2915 #if defined (DEBUG_DNS_UPDATES) 2920 #if defined (DEBUG_DNS_UPDATES) 2921 if (result != ISC_R_SUCCESS) {
2922 log_info(
"DDNS: %s(%d): error in ddns_modify_ptr %s for %p",
2923 file,
line, isc_result_totext(result), ddns_cb);
2927 if (dataspace != NULL) {
2929 sizeof(*dataspace) * 2);
2938 dns_client_cancelupdate((dns_clientupdatetrans_t *)
2941 ddns_cb->
lease = NULL;
2943 #if defined (DEBUG_DNS_UPDATES) 2944 log_info(
"DDNS: %s(%d): cancelling transaction for %p",
2954 #if defined (NSUPDATE) 2955 #if defined (DEBUG_DNS_UPDATES) 2964 static LabeledInt ints[] = {
2976 LabeledInt* li = ints;
2977 while (li->val != -1 && li->val != state) {
2985 add_nstring(
char **orig,
char *max,
char *add,
int add_len) {
2986 if (*orig && (*orig + add_len < max)) {
2987 strncpy(*orig, add, add_len);
2997 add_string(
char **orig,
char *max,
char *add) {
2998 return (add_nstring(orig, max, add, strlen(add)));
3021 isc_result_t result)
3024 char *s = obuf, *end = &obuf[
sizeof(obuf)-2];
3026 const char *result_str;
3028 sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
3031 log_info(
"DDNS reply: id ptr %p, result: %s",
3040 memset(obuf, 0, 1024);
3042 en =
"DDNS request: id ptr ";
3043 if (s + strlen(en) + 16 < end) {
3052 switch (ddns_cb->
state) {
3059 if (s + strlen(en) + strlen(ddns_address) +
3061 sprintf(s,
" %s %s for %.*s", en, ddns_address,
3074 sprintf(s,
" %s %.*s for %.*s", en,
3087 if (s + strlen(en) < end) {
3088 sprintf(s,
"%s", en);
3097 if (s + strlen(en) + strlen((
char *)ddns_cb->
zone_name) < end) {
3098 sprintf(s,
"%s%s", en, ddns_cb->
zone_name);
3105 if (ddns_cb->
dhcid_class == dns_rdatatype_dhcid) {
3107 if (add_string(&s, end,
"dhcid: [")) {
3114 int ret = add_string(&s, end, idbuf);
3121 if (add_string(&s, end,
"]")) {
3127 int skip_length_byte = (ddns_cb->
dhcid.
len > 0 ? 1 : 0);
3128 if (add_string (&s, end,
"txt: [") ||
3129 add_nstring (&s, end,
3130 (
char *)ddns_cb->
dhcid.
data + skip_length_byte,
3131 ddns_cb->
dhcid.
len - skip_length_byte) ||
3132 add_string (&s, end,
"]")) {
3138 if (s + strlen(en) + 10 < end) {
3139 sprintf(s,
"%s%ld", en, ddns_cb->
ttl);
3146 result_str = isc_result_totext(result);
3147 if (s + strlen(en) + strlen(result_str) < end) {
3148 sprintf(s,
"%s%s", en, result_str);
#define rc_register(file, line, reference, addr, refcnt, d, f)
dns_rdatalist_t rdatalist
#define DDNS_PRINT_INBOUND
struct binding_scope * global_scope
unsigned char zone_name[DHCP_MAXDNS_WIRE]
const char * piaddr(const struct iaddr addr)
#define DDNS_STATE_ADD_FW_NXDOMAIN
#define DDNS_PRINT_OUTBOUND
int get_dhcid(dhcp_ddns_cb_t *, int, const u_int8_t *, unsigned)
isc_result_t dhcp_isc_name(unsigned char *namestr, dns_fixedname_t *namefix, dns_name_t **name)
int option_cache_dereference(struct option_cache **ptr, const char *file, int line)
isc_result_t ddns_modify_ptr(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
dhcp_context_t dhcp_gbl_ctx
#define DDNS_STATE_REM_PTR
#define DHCP_R_INVALIDARG
isc_sockaddr_t zone_addrs[DHCP_MAXNS]
#define HASH_FUNCTIONS(name, bufarg, type, hashtype, ref, deref, hasher)
#define DDNS_GUARD_ID_MUST_MATCH
dhcp_ddns_cb_t * ddns_cb_alloc(const char *file, int line)
void data_string_forget(struct data_string *data, const char *file, int line)
void print_dns_status(int, struct dhcp_ddns_cb *, isc_result_t)
int log_error(const char *,...) __attribute__((__format__(__printf__
char * ddns_state_name(int state)
int dns_zone_reference(struct dns_zone **ptr, struct dns_zone *bp, const char *file, int line)
#define DDNS_INCLUDE_RRSET
struct option_cache * secondary6
#define DDNS_STATE_REM_FW_YXDHCID
isc_result_t enter_dns_zone(struct dns_zone *zone)
struct data_string fwd_name
void forget_zone(struct dns_zone **)
void ddns_cb_free(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
void dhcid_tolease(struct data_string *, struct data_string *)
int option_cache_allocate(struct option_cache **cptr, const char *file, int line)
struct data_string rev_name
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)
isc_result_t dns_client_init()
dns_rdataclass_t dhcid_class
#define DDNS_STATE_ADD_PTR
int buffer_allocate(struct buffer **ptr, unsigned len, const char *file, int line)
struct dhcp_ddns_cb * next_op
trace_type_t * trace_type_register(const char *, void *, void(*)(trace_type_t *, unsigned, char *), void(*)(trace_type_t *), const char *, int)
#define DDNS_OTHER_GUARD_IS_DYNAMIC
isc_result_t trace_write_packet_iov(trace_type_t *, int, trace_iov_t *, const char *, int)
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)
void dfree(void *, const char *, int)
isc_result_t dhcid_fromlease(struct data_string *, struct data_string *)
struct dhcp_ddns_cb dhcp_ddns_cb_t
void ddns_cancel(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
isc_sockaddrlist_t zone_server_list
void repudiate_zone(struct dns_zone **)
int int log_info(const char *,...) __attribute__((__format__(__printf__
void * dmalloc(size_t, const char *, int)
#define DNS_ZONE_INACTIVE
void putUChar(unsigned char *, u_int32_t)
struct option_cache * secondary
void trace_ddns_init(void)
isc_result_t remove_dns_zone(struct dns_zone *zone)
#define DDNS_DUAL_STACK_MIXED_MODE
int MRns_name_pton(const char *src, u_char *dst, size_t dstsiz)
struct option_cache * primary6
dns_zone_hash_t * dns_zone_hash
#define DDNS_STATE_REM_FW_DSMM_OTHER
isc_result_t trace_get_packet(trace_type_t **, unsigned *, char **)
#define DDNS_STATE_ADD_FW_YXDHCID
dns_rdataclass_t other_dhcid_class
struct server_list * servers
void ddns_cb_forget_zone(dhcp_ddns_cb_t *ddns_cb)
int dns_zone_allocate(struct dns_zone **ptr, const char *file, int line)
#define DDNS_CONFLICT_DETECTION
struct dhcp_ddns_rdata dhcp_ddns_data_t
isc_result_t find_cached_zone(dhcp_ddns_cb_t *, int)
void putUShort(unsigned char *, u_int32_t)
const unsigned char * data
void data_string_copy(struct data_string *dest, const struct data_string *src, const char *file, int line)
unsigned do_case_hash(const void *, unsigned, unsigned)
isc_result_t dns_zone_lookup(struct dns_zone **zone, const char *name)
#define DDNS_STATE_DSMM_FW_ADD3
#define DDNS_STATE_CLEANUP
#define DDNS_STATE_REM_FW_NXRR
char * buf_to_hex(const unsigned char *s, unsigned len, const char *file, int line)
int dns_zone_dereference(struct dns_zone **ptr, const char *file, int line)
struct option_cache * primary
isc_result_t ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)