From c00cf65b1c29b836e0c95c28b22279157585a2e7 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Tue, 10 Jun 2008 02:47:43 +0000 Subject: Add support for resolving name server to multiple ip addresses --- tools/notify-dns-slaves.c | 75 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 59 insertions(+), 16 deletions(-) (limited to 'tools') diff --git a/tools/notify-dns-slaves.c b/tools/notify-dns-slaves.c index 3a7f342..956fdac 100644 --- a/tools/notify-dns-slaves.c +++ b/tools/notify-dns-slaves.c @@ -386,7 +386,7 @@ process_all_packets (uint64_t when, void *unused) } static void -prepare_and_process (notification *notif, uint64_t when) +complete_packet (notification *notif, uint64_t when) { assert (notif); assert (SANY_TYPE (notif->address)); @@ -397,39 +397,81 @@ prepare_and_process (notification *notif, uint64_t when) notif->timeout = notif->start + TIMEOUT_INTERVAL; notif->retries = RETRIES; notif->retry = when; +} + +static notification* +duplicate_notification (notification *orig) +{ + notification *notif; + HEADER *hdr; + + assert (orig); + + notif = calloc (1, sizeof (notification)); + if (!notif) { + warningx ("out of memory"); + return NULL; + } + + memcpy (notif, orig, sizeof (notification)); + hdr = (HEADER*)notif->packet; + notif->unique = hdr->id = htons (unique_identifier++); + + /* Add it to the queue */ + notif->next = the_notifications; + the_notifications = notif; - process_all_packets (when, NULL); + return notif; } static void address_resolved (int ecode, struct addrinfo *ai, void *arg) { - notification **not, *notif; + notification **not, *notif, *copy; + char hostname[256]; + uint64_t when; + int num = 0; for (not = &the_notifications; *not; not = &(*not)->next) { notif = *not; - /* We search for the notification, in case it has been freed */ - if (notif != arg) - continue; - /* A bummer resolve */ if (ecode) { warningx ("couldn't resolve server: %s: %s", notif->server, gai_strerror (ecode)); *not = notif->next; free (notif); - break; + return; + } + + when = server_get_time (); /* A successful resolve */ - } else { - debug ("resolved address for: %s", notif->server); - memcpy (&SANY_ADDR (notif->address), ai->ai_addr, ai->ai_addrlen); - SANY_LEN (notif->address) = ai->ai_addrlen; - notif->resolved = 1; - prepare_and_process (notif, server_get_time ()); - break; + while (ai) { + if (num == 0) + copy = notif; + else + copy = duplicate_notification (notif); + + if (copy) { + memcpy (&SANY_ADDR (copy->address), ai->ai_addr, ai->ai_addrlen); + SANY_LEN (copy->address) = ai->ai_addrlen; + copy->resolved = 1; + ++num; + + if (sock_any_ntop (©->address, hostname, sizeof (hostname), SANY_OPT_NOPORT) < 0) + strcpy (hostname, "[unknown]"); + debug ("resolved address for: %s", hostname); + + complete_packet (copy, when); + } + + /* The next resolved address */ + ai = ai->ai_next; } + + process_all_packets (when, NULL); + return; } } @@ -578,7 +620,8 @@ process_notify (const char *zone, const char *server, uint64_t delay) async_resolver_queue (notif->server, "53", &hints, address_resolved, notif); } else { notif->resolved = 1; - prepare_and_process (notif, when); + complete_packet (notif, when); + process_all_packets (when, NULL); } return 0; -- cgit v1.2.3