36 #include <dns/result.h>
156 #if defined (NSUPDATE)
157 #if defined (DNS_ZONE_LOOKUP)
171 typedef struct dhcp_ddns_ns {
172 struct dhcp_ddns_ns *next;
176 dns_clientresevent_t *eventp;
180 dns_rdataset_t *rdataset;
181 dns_rdatatype_t rdtype;
183 struct in_addr addrs[DHCP_MAXNS];
184 struct in6_addr addrs6[DHCP_MAXNS];
207 dhcp_ddns_ns_t *dns_outstanding_ns = NULL;
225 add_to_ns_queue(dhcp_ddns_ns_t *ns_cb)
227 ns_cb->next = dns_outstanding_ns;
228 dns_outstanding_ns = ns_cb;
233 remove_from_ns_queue(dhcp_ddns_ns_t *ns_cb)
235 dhcp_ddns_ns_t **foo;
237 foo = &dns_outstanding_ns;
243 foo = &((*foo)->next);
249 find_in_ns_queue(dhcp_ddns_ns_t *ns_cb)
251 dhcp_ddns_ns_t *temp_cb;
252 int in_len, temp_len;
254 in_len = strlen(ns_cb->zname);
256 for(temp_cb = dns_outstanding_ns;
258 temp_cb = temp_cb->next) {
259 temp_len = strlen(temp_cb->zname);
260 if (temp_len > in_len)
262 if (strcmp(temp_cb->zname,
263 ns_cb->zname + (in_len - temp_len)) == 0)
264 return(ISC_R_SUCCESS);
266 return(ISC_R_NOTFOUND);
269 void cache_found_zone (dhcp_ddns_ns_t *);
272 void ddns_interlude(isc_task_t *, isc_event_t *);
274 #if defined (TRACING)
310 #define TRACE_PTR_LEN 8
312 typedef struct dhcp_ddns_map {
313 char old_pointer[TRACE_PTR_LEN];
315 struct dhcp_ddns_map *next;
319 static dhcp_ddns_map_t *ddns_map;
331 trace_ddns_input_write(
dhcp_ddns_cb_t *ddns_cb, isc_result_t result)
334 u_int32_t old_result;
335 char old_pointer[TRACE_PTR_LEN];
337 old_result = htonl((u_int32_t)result);
338 memset(old_pointer, 0, TRACE_PTR_LEN);
339 memcpy(old_pointer, &ddns_cb,
sizeof(ddns_cb));
341 iov[0].
len =
sizeof(old_result);
342 iov[0].
buf = (
char *)&old_result;
343 iov[1].
len = TRACE_PTR_LEN;
344 iov[1].
buf = old_pointer;
355 trace_ddns_input_read(
trace_type_t *ttype,
unsigned length,
358 u_int32_t old_result;
359 char old_pointer[TRACE_PTR_LEN];
360 dns_clientupdateevent_t *eventp;
362 dhcp_ddns_map_t *ddns_map_ptr;
364 if (length < (
sizeof(old_result) + TRACE_PTR_LEN)) {
365 log_error(
"trace_ddns_input_read: data too short");
369 memcpy(&old_result, buf,
sizeof(old_result));
370 memcpy(old_pointer, buf +
sizeof(old_result), TRACE_PTR_LEN);
373 for (ddns_map_ptr = ddns_map;
374 ddns_map_ptr != NULL;
375 ddns_map_ptr = ddns_map_ptr->next) {
376 if ((ddns_map_ptr->new_pointer != NULL) &&
377 memcmp(ddns_map_ptr->old_pointer,
378 old_pointer, TRACE_PTR_LEN) == 0) {
379 new_pointer = ddns_map_ptr->new_pointer;
380 ddns_map_ptr->new_pointer = NULL;
381 memset(ddns_map_ptr->old_pointer, 0, TRACE_PTR_LEN);
385 if (ddns_map_ptr == NULL) {
386 log_error(
"trace_dns_input_read: unable to map cb pointer");
390 eventp = (dns_clientupdateevent_t *)
396 sizeof(dns_clientupdateevent_t));
397 if (eventp == NULL) {
398 log_error(
"trace_ddns_input_read: unable to allocate event");
401 eventp->result = ntohl(old_result);
432 trace_ddns_output_write(dns_client_t *client, dns_rdataclass_t rdclass,
433 dns_name_t *zonename, dns_namelist_t *prerequisites,
434 dns_namelist_t *updates, isc_sockaddrlist_t *
servers,
435 dns_tsec_t *tsec,
unsigned int options,
436 isc_task_t *task, isc_taskaction_t action,
void *arg,
437 dns_clientupdatetrans_t **transp)
440 u_int32_t old_result;
441 char old_pointer[TRACE_PTR_LEN];
442 dhcp_ddns_map_t *ddns_map_ptr;
451 if (result != ISC_R_SUCCESS) {
452 log_error(
"trace_ddns_output_write: no input found");
453 return (ISC_R_FAILURE);
455 if (buflen < (
sizeof(old_result) + TRACE_PTR_LEN)) {
456 log_error(
"trace_ddns_output_write: data too short");
458 return (ISC_R_FAILURE);
460 memcpy(&old_result, inbuf,
sizeof(old_result));
461 result = ntohl(old_result);
462 memcpy(old_pointer, inbuf +
sizeof(old_result), TRACE_PTR_LEN);
466 for (ddns_map_ptr = ddns_map;
467 ddns_map_ptr != NULL;
468 ddns_map_ptr = ddns_map_ptr->next) {
469 if (ddns_map_ptr->new_pointer == NULL) {
478 if (ddns_map_ptr == NULL) {
479 ddns_map_ptr =
dmalloc(
sizeof(*ddns_map_ptr),
MDL);
480 if (ddns_map_ptr == NULL) {
482 "unable to allocate map entry");
483 return(ISC_R_FAILURE);
485 ddns_map_ptr->next = ddns_map;
486 ddns_map = ddns_map_ptr;
489 memcpy(ddns_map_ptr->old_pointer, old_pointer, TRACE_PTR_LEN);
490 ddns_map_ptr->new_pointer = arg;
494 result = dns_client_startupdate(client, rdclass, zonename,
495 prerequisites, updates,
496 servers, tsec, options,
497 task, action, arg, transp);
503 old_result = htonl((u_int32_t)result);
504 memset(old_pointer, 0, TRACE_PTR_LEN);
505 memcpy(old_pointer, &arg,
sizeof(arg));
506 iov[0].
len =
sizeof(old_result);
507 iov[0].
buf = (
char *)&old_result;
508 iov[1].
len = TRACE_PTR_LEN;
509 iov[1].
buf = old_pointer;
513 iov[2].
buf = (
char *)arg;
522 trace_ddns_output_read(
trace_type_t *ttype,
unsigned length,
525 log_error(
"unaccounted for ddns output.");
537 trace_ddns_output_read,
538 trace_ddns_output_stop,
MDL);
540 trace_ddns_input_read,
541 trace_ddns_input_stop,
MDL);
545 #define ddns_update trace_ddns_output_write
547 #define ddns_update dns_client_startupdate
550 #define zone_resolve dns_client_startresolve
562 ddns_cb =
dmalloc(
sizeof(*ddns_cb), file, line);
563 if (ddns_cb != NULL) {
570 #if defined (DEBUG_DNS_UPDATES)
571 log_info(
"%s(%d): Allocating ddns_cb=%p", file, line, ddns_cb);
580 #if defined (DEBUG_DNS_UPDATES)
581 log_info(
"%s(%d): freeing ddns_cb=%p", file, line, ddns_cb);
588 if (ddns_cb->
zone != NULL) {
594 log_error(
"Impossible memory leak at %s:%d (attempt to free "
595 "DDNS Control Block before transaction).",
MDL);
597 dfree(ddns_cb, file, line);
619 return ISC_R_NOTFOUND;
625 if ((!zone -> key -> name ||
627 (!zone -> key -> algorithm ||
628 strlen (zone -> key -> algorithm) >
NS_MAXDNAME) ||
630 (!zone -> key -> key) ||
631 (zone -> key -> key -> len == 0)) {
637 return ISC_R_NOMEMORY;
639 memset (tkey, 0,
sizeof *tkey);
640 tkey -> data =
dmalloc (zone -> key -> key -> len,
MDL);
645 strcpy (tkey -> name, zone -> key -> name);
646 strcpy (tkey -> alg, zone -> key -> algorithm);
647 memcpy (tkey -> data,
648 zone -> key -> key -> value, zone -> key -> key -> len);
649 tkey -> len = zone -> key -> key -> len;
651 return ISC_R_SUCCESS;
668 dns_zone_hash_lookup(&tz, dns_zone_hash, zone->
name, 0,
MDL);
670 dns_zone_hash_delete(dns_zone_hash, tz->
name, 0,
MDL);
675 return (ISC_R_SUCCESS);
683 dns_zone_hash_lookup (&tz,
684 dns_zone_hash, zone ->
name, 0,
MDL);
687 return ISC_R_SUCCESS;
690 dns_zone_hash_delete (dns_zone_hash,
696 return ISC_R_NOMEMORY;
699 dns_zone_hash_add (dns_zone_hash, zone ->
name, 0, zone,
MDL);
700 return ISC_R_SUCCESS;
706 char *tname = (
char *)0;
710 return ISC_R_NOTFOUND;
713 if (name [len - 1] !=
'.') {
716 return ISC_R_NOMEMORY;
717 strcpy (tname, name);
722 if (!dns_zone_hash_lookup (zone, dns_zone_hash, name, 0,
MDL))
723 status = ISC_R_NOTFOUND;
724 else if ((*zone)->timeout && (*zone)->timeout <
cur_time) {
725 dns_zone_hash_delete(dns_zone_hash, (*zone)->name, 0,
MDL);
727 status = ISC_R_NOTFOUND;
729 status = ISC_R_SUCCESS;
743 if ((ptr == NULL) || (*ptr == NULL)) {
744 log_error(
"%s(%d): null pointer", file, line);
745 #if defined (POINTER_DEBUG)
759 if (dns_zone->
refcnt < 0) {
760 log_error(
"%s(%d): negative refcnt!", file, line);
761 #if defined (DEBUG_RC_HISTORY)
762 dump_rc_history(dns_zone);
764 #if defined (POINTER_DEBUG)
774 omapi_auth_key_dereference(&dns_zone->
key, file, line);
783 dfree(dns_zone, file, line);
787 #if defined (NSUPDATE)
788 #if defined (DNS_ZONE_LOOKUP)
795 zone_addr_to_ns(dhcp_ddns_ns_t *ns_cb,
796 dns_rdataset_t *rdataset)
800 dns_rdata_in_aaaa_t aaaa;
802 dns_rdata_init(&rdata);
803 dns_rdataset_current(rdataset, &rdata);
804 switch (rdataset->type) {
805 case dns_rdatatype_a:
806 (void) dns_rdata_tostruct(&rdata, &a, NULL);
807 memcpy(&ns_cb->addrs[ns_cb->num_addrs], &a.in_addr, 4);
809 dns_rdata_freestruct(&a);
811 case dns_rdatatype_aaaa:
812 (void) dns_rdata_tostruct(&rdata, &aaaa, NULL);
813 memcpy(&ns_cb->addrs6[ns_cb->num_addrs6], &aaaa.in6_addr, 16);
815 dns_rdata_freestruct(&aaaa);
821 if ((ns_cb->ttl == 0) || (ns_cb->ttl > rdataset->ttl))
822 ns_cb->ttl = rdataset->ttl;
857 find_zone_addrs(isc_task_t *taskp,
860 dns_clientresevent_t *ddns_event = (dns_clientresevent_t *)eventp;
861 dhcp_ddns_ns_t *ns_cb = (dhcp_ddns_ns_t *)eventp->ev_arg;
862 dns_name_t *ns_name = NULL;
863 dns_rdataset_t *rdataset;
866 dns_rdata_t rdata = DNS_RDATA_INIT;
871 dns_client_destroyrestrans(&ns_cb->transaction);
878 if (ddns_event->result == ISC_R_SUCCESS) {
880 for (
name = ISC_LIST_HEAD(ddns_event->answerlist);
884 for (rdataset = ISC_LIST_HEAD(
name->list);
886 rdataset = ISC_LIST_NEXT(rdataset, link)) {
888 for (result = dns_rdataset_first(rdataset);
889 result == ISC_R_SUCCESS;
890 result = dns_rdataset_next(rdataset)) {
893 zone_addr_to_ns(ns_cb, rdataset);
898 if (ns_cb->num_addrs +
910 for (ns_name = ns_cb->ns_name;
912 ns_name = ISC_LIST_NEXT(ns_name, link)) {
914 if (ns_name == ns_cb->ns_name) {
916 rdataset = ns_cb->rdataset;
918 rdataset = ISC_LIST_HEAD(ns_name->list);
923 rdataset = ISC_LIST_NEXT(rdataset, link)) {
925 if (rdataset->type != dns_rdatatype_ns)
927 dns_rdata_init(&rdata);
929 if (rdataset == ns_cb->rdataset) {
931 if (ns_cb->rdtype == dns_rdatatype_a) {
932 ns_cb->rdtype = dns_rdatatype_aaaa;
934 ns_cb->rdtype = dns_rdatatype_a;
935 if (dns_rdataset_next(rdataset) !=
940 if ((!dns_rdataset_isassociated(rdataset)) ||
941 (dns_rdataset_first(rdataset) !=
946 dns_rdataset_current(rdataset, &rdata);
947 if (dns_rdata_tostruct(&rdata, &ns, NULL) !=
952 ns_cb->ns_name = ns_name;
953 ns_cb->rdataset = rdataset;
959 DNS_CLIENTRESOPT_NODNSSEC,
963 &ns_cb->transaction);
966 dns_rdata_freestruct(&ns);
968 if (result == ISC_R_SUCCESS)
975 log_error(
"find_zone_ns: unable to continue "
978 isc_result_totext(result));
995 if ((ns_cb->num_addrs != 0) ||
996 (ns_cb->num_addrs6 != 0))
997 cache_found_zone(ns_cb);
1000 &ns_cb->eventp->answerlist);
1001 isc_event_free((isc_event_t **)&ns_cb->eventp);
1003 remove_from_ns_queue(ns_cb);
1011 &ddns_event->answerlist);
1012 isc_event_free(&eventp);
1025 find_zone_ns(isc_task_t *taskp,
1026 isc_event_t *eventp)
1028 dns_clientresevent_t *ddns_event = (dns_clientresevent_t *)eventp;
1029 dhcp_ddns_ns_t *ns_cb = (dhcp_ddns_ns_t *)eventp->ev_arg;
1030 dns_fixedname_t zname0;
1031 dns_name_t *zname = NULL, *ns_name = NULL;
1032 dns_rdataset_t *rdataset;
1033 isc_result_t result;
1034 dns_rdata_t rdata = DNS_RDATA_INIT;
1038 dns_client_destroyrestrans(&ns_cb->transaction);
1040 if (ddns_event->result != ISC_R_SUCCESS) {
1044 ns_cb->zname = strchr(ns_cb->zname,
'.');
1045 if ((ns_cb->zname == NULL) ||
1046 (ns_cb->zname[1] == 0)) {
1056 != ISC_R_SUCCESS) ||
1058 zname, dns_rdataclass_in,
1060 DNS_CLIENTRESOPT_NODNSSEC,
1064 &ns_cb->transaction))
1065 != ISC_R_SUCCESS)) {
1066 log_error(
"find_zone_ns: Unable to build "
1067 "name or start resolve: %s %s",
1069 isc_result_totext(result));
1076 &ddns_event->answerlist);
1077 isc_event_free(&eventp);
1084 ns_cb->eventp = ddns_event;
1085 for (ns_name = ISC_LIST_HEAD(ddns_event->answerlist);
1087 ns_name = ISC_LIST_NEXT(ns_name, link)) {
1089 for (rdataset = ISC_LIST_HEAD(ns_name->list);
1091 rdataset = ISC_LIST_NEXT(rdataset, link)) {
1093 if (rdataset->type != dns_rdatatype_ns)
1096 if ((!dns_rdataset_isassociated(rdataset)) ||
1097 (dns_rdataset_first(rdataset) !=
1101 dns_rdataset_current(rdataset, &rdata);
1102 if (dns_rdata_tostruct(&rdata, &ns, NULL) !=
1107 ns_cb->ns_name = ns_name;
1108 ns_cb->rdataset = rdataset;
1111 result = zone_resolve(
dhcp_gbl_ctx.dnsclient, &ns.name,
1114 DNS_CLIENTRESOPT_NODNSSEC,
1118 &ns_cb->transaction);
1121 dns_rdata_freestruct(&ns);
1123 if (result == ISC_R_SUCCESS)
1130 log_error(
"find_zone_ns: unable to continue "
1133 isc_result_totext(result));
1149 &ddns_event->answerlist);
1150 isc_event_free(&eventp);
1152 remove_from_ns_queue(ns_cb);
1171 isc_result_t status = ISC_R_NOTFOUND;
1172 dhcp_ddns_ns_t *ns_cb;
1173 dns_fixedname_t zname0;
1174 dns_name_t *zname = NULL;
1182 if (ns_cb == NULL) {
1183 log_error(
"find_zone_start: unable to allocate cb");
1184 return(ISC_R_FAILURE);
1186 ns_cb->rdtype = dns_rdatatype_a;
1194 ns_cb->zname = (
char *)ns_cb->oname.data;
1200 if (find_in_ns_queue(ns_cb) == ISC_R_SUCCESS) {
1203 return (ISC_R_SUCCESS);
1210 != ISC_R_SUCCESS) ||
1212 zname, dns_rdataclass_in,
1214 DNS_CLIENTRESOPT_NODNSSEC,
1218 &ns_cb->transaction))
1219 != ISC_R_SUCCESS)) {
1220 log_error(
"find_zone_start: Unable to build "
1221 "name or start resolve: %s %s",
1223 isc_result_totext(status));
1231 add_to_ns_queue(ns_cb);
1241 isc_result_t status = ISC_R_NOTFOUND;
1245 struct in_addr zone_addr;
1246 struct in6_addr zone_addr6;
1256 if ((np == NULL) || (*np ==
'\0')) {
1265 if (status == ISC_R_SUCCESS)
1268 np = strchr(np,
'.');
1274 if (status != ISC_R_SUCCESS)
1283 return (ISC_R_FAILURE);
1289 return (ISC_R_NOSPACE);
1293 memset (&nsaddrs, 0,
sizeof nsaddrs);
1302 if (ip + 4 > nsaddrs.len)
1304 memcpy(&zone_addr, &nsaddrs.data[ip], 4);
1305 isc_sockaddr_fromin(&ddns_cb->
zone_addrs[ix],
1324 if (ip + 16 > nsaddrs.len)
1326 memcpy(&zone_addr6, &nsaddrs.data[ip], 16);
1327 isc_sockaddr_fromin6(&ddns_cb->
zone_addrs[ix],
1346 if (ip + 4 > nsaddrs.len)
1348 memcpy(&zone_addr, &nsaddrs.data[ip], 4);
1349 isc_sockaddr_fromin(&ddns_cb->
zone_addrs[ix],
1368 if (ip + 16 > nsaddrs.len)
1370 memcpy(&zone_addr6, &nsaddrs.data[ip], 16);
1371 isc_sockaddr_fromin6(&ddns_cb->
zone_addrs[ix],
1386 return ISC_R_SUCCESS;
1397 if ((zone == NULL) || (*zone == NULL)) {
1398 log_info(
"Null argument to repudiate zone");
1406 #if defined (DNS_ZONE_LOOKUP)
1407 void cache_found_zone(dhcp_ddns_ns_t *ns_cb)
1410 int len, remove_zone = 0;
1435 len = strlen(ns_cb->zname);
1437 if (zone->
name == NULL) {
1442 strcpy(zone->
name, ns_cb->zname);
1443 if (zone->
name[len-1] !=
'.') {
1444 zone->
name[len] =
'.';
1445 zone->
name[len+1] = 0;
1451 if (ns_cb->num_addrs != 0) {
1452 len = ns_cb->num_addrs *
sizeof(
struct in_addr);
1456 if (remove_zone == 1)
1465 if (ns_cb->num_addrs6 != 0) {
1466 len = ns_cb->num_addrs6 *
sizeof(
struct in6_addr);
1470 if (remove_zone == 1)
1514 const u_int8_t *identifier,
1518 isc_sha256_t sha256;
1519 unsigned char buf[ISC_SHA256_DIGESTLENGTH];
1520 unsigned char fwd_buf[256];
1521 unsigned fwd_buflen = 0;
1524 if (type < 0 || type > 65535)
1530 while(fwd_buf[fwd_buflen] != 0) {
1531 fwd_buflen += fwd_buf[fwd_buflen] + 1;
1536 ISC_SHA256_DIGESTLENGTH + 2 + 1,
1539 id->
data =
id->buffer->data;
1548 isc_sha256_init(&sha256);
1549 isc_sha256_update(&sha256, identifier, id_len);
1550 isc_sha256_update(&sha256, fwd_buf, fwd_buflen);
1551 isc_sha256_final(buf, &sha256);
1553 memcpy(id->
buffer->
data + 3, &buf, ISC_SHA256_DIGESTLENGTH);
1555 id->len = ISC_SHA256_DIGESTLENGTH + 2 + 1;
1583 const u_int8_t *
data,
1587 unsigned char buf[ISC_MD5_DIGESTLENGTH];
1592 if (type < 0 || type > 65535)
1600 (ISC_MD5_DIGESTLENGTH * 2) + 4,
MDL))
1602 id->
data =
id->buffer->data;
1609 id->buffer->data[0] = ISC_MD5_DIGESTLENGTH * 2 + 2;
1612 id->buffer->data[1] =
"0123456789abcdef"[(type >> 4) & 0xf];
1617 id->buffer->data[2] =
"0123456789abcdef"[type % 15];
1621 isc_md5_update(&md5, data, len);
1622 isc_md5_final(&md5, buf);
1625 for (i = 0; i < ISC_MD5_DIGESTLENGTH; i++) {
1626 id->buffer->data[i * 2 + 3] =
1627 "0123456789abcdef"[(buf[i] >> 4) & 0xf];
1628 id->buffer->data[i * 2 + 4] =
1629 "0123456789abcdef"[buf[i] & 0xf];
1632 id->len = ISC_MD5_DIGESTLENGTH * 2 + 3;
1633 id->buffer->data[
id->len] = 0;
1641 const u_int8_t *identifier,
1645 return get_std_dhcid(ddns_cb, type, identifier, id_len);
1647 return get_int_dhcid(ddns_cb, type, identifier, id_len);
1676 return(ISC_R_FAILURE);
1683 dhcid->
len = leaseid->
len + 1;
1689 return(ISC_R_SUCCESS);
1701 make_dns_dataset(dns_rdataclass_t dataclass,
1702 dns_rdatatype_t datatype,
1704 unsigned char *data,
1708 dns_rdata_t *rdata = &dataspace->
rdata;
1709 dns_rdatalist_t *rdatalist = &dataspace->
rdatalist;
1710 dns_rdataset_t *rdataset = &dataspace->
rdataset;
1712 isc_region_t region;
1715 dns_rdata_init(rdata);
1719 rdata->flags = DNS_RDATA_UPDATE;
1720 rdata->type = datatype;
1721 rdata->rdclass = dataclass;
1724 case dns_rdatatype_a:
1725 case dns_rdatatype_aaaa:
1726 case dns_rdatatype_txt:
1727 case dns_rdatatype_dhcid:
1728 case dns_rdatatype_ptr:
1732 region.length = datalen;
1733 dns_rdata_fromregion(rdata, dataclass, datatype,
1743 dns_rdatalist_init(rdatalist);
1744 rdatalist->type = datatype;
1745 rdatalist->rdclass = dataclass;
1746 rdatalist->ttl = ttl;
1747 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
1750 dns_rdataset_init(rdataset);
1751 dns_rdatalist_tordataset(rdatalist, rdataset);
1753 return(ISC_R_SUCCESS);
1783 isc_result_t result;
1788 result = make_dns_dataset(dns_rdataclass_none,
1790 dataspace, NULL, 0, 0);
1793 result = make_dns_dataset(dns_rdataclass_none,
1795 dataspace, NULL, 0, 0);
1797 if (result != ISC_R_SUCCESS) {
1800 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
1805 result = make_dns_dataset(dns_rdataclass_in, ddns_cb->
address_type,
1809 if (result != ISC_R_SUCCESS) {
1812 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
1816 result = make_dns_dataset(dns_rdataclass_in, ddns_cb->
dhcid_class,
1820 if (result != ISC_R_SUCCESS) {
1823 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
1825 return(ISC_R_SUCCESS);
1862 isc_result_t result = ISC_R_SUCCESS;
1871 result = make_dns_dataset(dns_rdataclass_in, ddns_cb->
dhcid_class,
1875 if (result != ISC_R_SUCCESS) {
1878 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
1883 result = make_dns_dataset(dns_rdataclass_any,
1885 dataspace, NULL, 0, 0);
1886 if (result != ISC_R_SUCCESS) {
1889 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
1893 result = make_dns_dataset(dns_rdataclass_in, ddns_cb->
dhcid_class,
1897 if (result != ISC_R_SUCCESS) {
1900 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
1906 result = make_dns_dataset(dns_rdataclass_any, ddns_cb->
address_type,
1907 dataspace, NULL, 0, 0);
1908 if (result != ISC_R_SUCCESS) {
1911 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
1915 result = make_dns_dataset(dns_rdataclass_in, ddns_cb->
address_type,
1919 if (result != ISC_R_SUCCESS) {
1922 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
1924 return(ISC_R_SUCCESS);
1955 isc_result_t result = ISC_R_SUCCESS;
1959 result = make_dns_dataset(dns_rdataclass_in, ddns_cb->
dhcid_class,
1963 if (result != ISC_R_SUCCESS) {
1966 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
1971 result = make_dns_dataset(dns_rdataclass_none, ddns_cb->
address_type,
1975 if (result != ISC_R_SUCCESS) {
1978 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
1980 return(ISC_R_SUCCESS);
2002 isc_result_t result;
2006 result = make_dns_dataset(dns_rdataclass_none, dns_rdatatype_a,
2007 dataspace, NULL, 0, 0);
2008 if (result != ISC_R_SUCCESS) {
2011 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2015 result = make_dns_dataset(dns_rdataclass_none, dns_rdatatype_aaaa,
2016 dataspace, NULL, 0, 0);
2017 if (result != ISC_R_SUCCESS) {
2020 ISC_LIST_APPEND(pname->list, &dataspace->
rdataset, link);
2025 result = make_dns_dataset(dns_rdataclass_none, ddns_cb->
dhcid_class,
2029 if (result != ISC_R_SUCCESS) {
2032 ISC_LIST_APPEND(uname->list, &dataspace->
rdataset, link);
2034 return(ISC_R_SUCCESS);
2042 void ddns_interlude(isc_task_t *taskp,
2043 isc_event_t *eventp)
2046 dns_clientupdateevent_t *ddns_event = (dns_clientupdateevent_t *)eventp;
2047 isc_result_t eresult = ddns_event->result;
2048 isc_result_t result;
2052 isc_event_free(&eventp);
2054 #if defined (TRACING)
2056 trace_ddns_input_write(ddns_cb, eresult);
2060 #if defined (DEBUG_DNS_UPDATES)
2065 dns_client_destroyupdatetrans(&ddns_cb->
transaction);
2069 if ((eresult == ISC_R_CANCELED) ||
2071 #if defined (DEBUG_DNS_UPDATES)
2072 log_info(
"DDNS: completeing transaction cancellation cb=%p, "
2074 ddns_cb, ddns_cb->
flags, isc_result_totext(eresult));
2077 log_info(
"DDNS: cleaning up lease pointer for a cancel "
2085 ddns_cb->
cur_func(ddns_cb, eresult);
2089 if (ddns_cb->
next_op != NULL) {
2098 if ((eresult == DNS_R_NOTAUTH) ||
2099 (eresult == DNS_R_NOTZONE)) {
2103 log_error(
"DDNS: bad zone information, repudiating zone %s",
2109 ISC_LINK_INIT(&ddns_cb->
zone_addrs[i], link);
2119 if (result != ISC_R_SUCCESS) {
2122 log_info(
"DDNS: Failed to retry after zone failure");
2123 ddns_cb->
cur_func(ddns_cb, result);
2128 ddns_cb->
cur_func(ddns_cb, eresult);
2143 isc_result_t result;
2144 dns_tsec_t *tsec_key = NULL;
2146 unsigned char *clientname;
2148 dns_namelist_t prereqlist, updatelist;
2149 dns_fixedname_t zname0, pname0, uname0;
2150 dns_name_t *zname = NULL, *pname, *uname;
2152 isc_sockaddrlist_t *zlist = NULL;
2174 if (ddns_cb->
zone == NULL) {
2176 #if defined (DNS_ZONE_LOOKUP)
2177 if (result == ISC_R_NOTFOUND) {
2196 if (result != ISC_R_SUCCESS)
2205 if (ddns_cb->
zone) {
2208 if (result != ISC_R_SUCCESS) {
2209 log_error(
"Unable to build name for zone for "
2210 "fwd update: %s %s",
2212 isc_result_totext(result));
2222 if (ddns_cb->
zone->
key != NULL) {
2230 if (tsec_key == NULL) {
2231 log_error(
"No tsec for use with key %s",
2239 != ISC_R_SUCCESS) ||
2241 != ISC_R_SUCCESS)) {
2242 log_error(
"Unable to build name for fwd update: %s %s",
2243 clientname, isc_result_totext(result));
2249 if (dataspace == NULL) {
2250 log_error(
"Unable to allocate memory for fwd update");
2251 result = ISC_R_NOMEMORY;
2255 ISC_LIST_INIT(prereqlist);
2256 ISC_LIST_INIT(updatelist);
2258 switch(ddns_cb->
state) {
2260 result = ddns_modify_fwd_add1(ddns_cb, dataspace,
2262 if (result != ISC_R_SUCCESS) {
2265 ISC_LIST_APPEND(prereqlist, pname, link);
2268 result = ddns_modify_fwd_add2(ddns_cb, dataspace,
2270 if (result != ISC_R_SUCCESS) {
2279 ISC_LIST_APPEND(prereqlist, pname, link);
2284 result = ddns_modify_fwd_rem1(ddns_cb, dataspace,
2286 if (result != ISC_R_SUCCESS) {
2289 ISC_LIST_APPEND(prereqlist, pname, link);
2292 result = ddns_modify_fwd_rem2(ddns_cb, dataspace,
2294 if (result != ISC_R_SUCCESS) {
2297 ISC_LIST_APPEND(prereqlist, pname, link);
2301 log_error(
"Invalid operation in ddns code.");
2311 ISC_LIST_APPEND(updatelist, uname, link);
2315 dns_rdataclass_in, zname,
2316 &prereqlist, &updatelist,
2318 DNS_CLIENTRESOPT_ALLOWRUN,
2323 if (result == ISC_R_FAMILYNOSUPPORT) {
2324 log_info(
"Unable to perform DDNS update, "
2325 "address family not supported");
2328 #if defined (DEBUG_DNS_UPDATES)
2333 #if defined (DEBUG_DNS_UPDATES)
2334 if (result != ISC_R_SUCCESS) {
2335 log_info(
"DDNS: %s(%d): error in ddns_modify_fwd %s for %p",
2336 file, line, isc_result_totext(result), ddns_cb);
2340 if (dataspace != NULL) {
2342 sizeof(*dataspace) * 4);
2351 isc_result_t result;
2352 dns_tsec_t *tsec_key = NULL;
2353 unsigned char *ptrname;
2355 dns_namelist_t updatelist;
2356 dns_fixedname_t zname0, uname0;
2357 dns_name_t *zname = NULL, *uname;
2358 isc_sockaddrlist_t *zlist = NULL;
2359 unsigned char buf[256];
2371 #if defined (DNS_ZONE_LOOKUP)
2372 if (result == ISC_R_NOTFOUND) {
2377 if (find_zone_start(ddns_cb,
FIND_REVERSE) == ISC_R_SUCCESS) {
2390 if (result != ISC_R_SUCCESS)
2394 if ((result == ISC_R_SUCCESS) &&
2398 if (result != ISC_R_SUCCESS) {
2399 log_error(
"Unable to build name for zone for "
2400 "fwd update: %s %s",
2402 isc_result_totext(result));
2416 if ((ddns_cb->
zone != NULL) && (ddns_cb->
zone->
key != NULL)) {
2418 if (tsec_key == NULL) {
2419 log_error(
"No tsec for use with key %s",
2431 log_error(
"Unable to build name for fwd update: %s %s",
2432 ptrname, isc_result_totext(result));
2442 if (dataspace == NULL) {
2443 log_error(
"Unable to allocate memory for fwd update");
2444 result = ISC_R_NOMEMORY;
2448 ISC_LIST_INIT(updatelist);
2455 result = make_dns_dataset(dns_rdataclass_any, dns_rdatatype_ptr,
2456 &dataspace[0], NULL, 0, 0);
2457 if (result != ISC_R_SUCCESS) {
2460 ISC_LIST_APPEND(uname->list, &dataspace[0].
rdataset, link);
2511 while (buf[buflen] != 0) {
2512 buflen += buf[buflen] + 1;
2516 result = make_dns_dataset(dns_rdataclass_in,
2519 buf, buflen, ddns_cb->
ttl);
2520 if (result != ISC_R_SUCCESS) {
2523 ISC_LIST_APPEND(uname->list, &dataspace[1].
rdataset, link);
2526 ISC_LIST_APPEND(updatelist, uname, link);
2535 result = ddns_update((dns_client_t *)
dhcp_gbl_ctx.dnsclient,
2536 dns_rdataclass_in, zname,
2539 DNS_CLIENTRESOPT_ALLOWRUN,
2541 ddns_interlude, (
void *)ddns_cb,
2543 if (result == ISC_R_FAMILYNOSUPPORT) {
2544 log_info(
"Unable to perform DDNS update, "
2545 "address family not supported");
2548 #if defined (DEBUG_DNS_UPDATES)
2553 #if defined (DEBUG_DNS_UPDATES)
2554 if (result != ISC_R_SUCCESS) {
2555 log_info(
"DDNS: %s(%d): error in ddns_modify_ptr %s for %p",
2556 file, line, isc_result_totext(result), ddns_cb);
2560 if (dataspace != NULL) {
2562 sizeof(*dataspace) * 2);
2571 dns_client_cancelupdate((dns_clientupdatetrans_t *)
2574 ddns_cb->
lease = NULL;
2576 #if defined (DEBUG_DNS_UPDATES)
2577 log_info(
"DDNS: %s(%d): cancelling transaction for %p",
2578 file, line, ddns_cb);
void tkey_free(ns_tsig_key **)
#define rc_register(file, line, reference, addr, refcnt, d, f)
dns_rdatalist_t rdatalist
#define DDNS_PRINT_INBOUND
struct binding_scope * global_scope
isc_result_t find_tsig_key(ns_tsig_key **, const char *, struct dns_zone *)
unsigned char zone_name[DHCP_MAXDNS_WIRE]
#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)
void * dmalloc(unsigned, const char *, int)
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]
isc_result_t trace_write_packet_iov(trace_type_t *, int, trace_iov_t *, const char *, int)
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__
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
#define DHCP_R_INVALIDKEY
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
#define DHCP_R_KEY_UNKNOWN
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)
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_CONFLICT_OVERRIDE
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__
#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)
isc_result_t trace_get_packet(trace_type_t **, unsigned *, char **)
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_ADD_FW_YXDHCID
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)
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_REM_FW_NXRR
#define HASH_FUNCTIONS(name, bufarg, type, hashtype, ref, deref, hasher)
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)