summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/notify-dns-slaves.c75
1 files changed, 59 insertions, 16 deletions
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 (&copy->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;