From: Wouter Wijngaards Date: Tue, 9 Jan 2007 12:37:33 +0000 (+0000) Subject: Added ldns-notify. Capable of including the SOA serial in a NOTIFY. X-Git-Tag: release-1.2.0~74 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dbf3fcc8d142d20c2eb7812f240e83110abeff6e;p=thirdparty%2Fldns.git Added ldns-notify. Capable of including the SOA serial in a NOTIFY. Nice example, and useful to debug NSD. --- diff --git a/examples/Makefile.in b/examples/Makefile.in index 5903e041..8cfc780a 100644 --- a/examples/Makefile.in +++ b/examples/Makefile.in @@ -43,6 +43,7 @@ SOURCES = ldns-read-zone.c \ ldns-resolver.c \ ldnsd.c \ ldns-keyfetcher.c \ + ldns-notify.c \ ldns-testns.c diff --git a/examples/ldns-notify.c b/examples/ldns-notify.c new file mode 100644 index 00000000..f159fcb0 --- /dev/null +++ b/examples/ldns-notify.c @@ -0,0 +1,303 @@ +/* + * ldns-notify.c - ldns-notify(8) + * + * Copyright (c) 2001-2005, NLnet Labs, All right reserved + * + * See LICENSE for the license + * + * send a notify packet to a server + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* ldns */ +#include "ldns/ldns.h" + +static int verbose = 1; + +static void +usage(void) +{ + fprintf(stderr, "usage: ldns-notify [other options] -z zone \n"); + fprintf(stderr, "Ldns notify utility\n\n"); + fprintf(stderr, " Supported options:\n"); + fprintf(stderr, "\t-z zone\t\tThe zone\n"); + fprintf(stderr, "\t-s version\tSOA version number to include\n"); + fprintf(stderr, "\t-y key:data\tTSIG sign the query\n"); + fprintf(stderr, "\t-p port\t\tport to use to send to\n"); + fprintf(stderr, "\t-v\t\tPrint version information\n"); + fprintf(stderr, "\t-d\t\tPrint verbose debug information\n"); + fprintf(stderr, "\t-h\t\tPrint this help information\n\n"); + fprintf(stderr, "Report bugs to \n"); + exit(1); +} + +static void +version(void) +{ + fprintf(stderr, "%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION); + fprintf(stderr, "Written by NLnet Labs.\n\n"); + fprintf(stderr, + "Copyright (C) 2001-2005 NLnet Labs. This is free software.\n" + "There is NO warranty; not even for MERCHANTABILITY or FITNESS\n" + "FOR A PARTICULAR PURPOSE.\n"); + exit(0); +} + +static void +notify_host(int s, struct addrinfo* res, uint8_t* wire, size_t wiresize, + const char* addrstr) +{ + int timeout_retry = 5; /* seconds */ + int num_retry = 15; /* times to try */ + fd_set rfds; + struct timeval tv; + int retval = 0; + ssize_t received = 0; + int got_ack = 0; + socklen_t addrlen = 0; + uint8_t replybuf[2048]; + ldns_status status; + ldns_pkt* pkt = NULL; + + while(!got_ack) { + /* send it */ + if(sendto(s, wire, wiresize, 0, res->ai_addr, res->ai_addrlen) + == -1) { + printf("warning: send to %s failed: %s\n", + addrstr, strerror(errno)); + close(s); + return; + } + + /* wait for ACK packet */ + FD_ZERO(&rfds); + FD_SET(s, &rfds); + tv.tv_sec = timeout_retry; /* seconds */ + tv.tv_usec = 0; /* microseconds */ + retval = select(s + 1, &rfds, NULL, NULL, &tv); + if (retval == -1) { + printf("error waiting for reply from %s: %s\n", + addrstr, strerror(errno)); + close(s); + return; + } + if(retval == 0) { + num_retry--; + if(num_retry == 0) { + printf("error: failed to send notify to %s.\n", + addrstr); + exit(1); + } + printf("timeout (%d s) expired, retry notify to %s.\n", + timeout_retry, addrstr); + } + if (retval == 1) { + got_ack = 1; + } + } + + /* got reply */ + addrlen = res->ai_addrlen; + received = recvfrom(s, replybuf, sizeof(replybuf), 0, + res->ai_addr, &addrlen); + res->ai_addrlen = addrlen; + + close(s); + if (received == -1) { + printf("recv %s failed: %s\n", addrstr, strerror(errno)); + return; + } + + /* check reply */ + status = ldns_wire2pkt(&pkt, replybuf, (size_t)received); + if(status != LDNS_STATUS_OK) { + int i; + printf("Could not parse reply packet: %s\n", + ldns_get_errorstr_by_id(status)); + printf("hexdump of reply: "); + for(i=0; iai_next) { + int s = socket(res->ai_family, res->ai_socktype, + res->ai_protocol); + if(s == -1) + continue; + /* send the notify */ + notify_host(s, res, wire, wiresize, argv[i]); + } + freeaddrinfo(res0); + } + + ldns_pkt_free(notify); + free(wire); + return 0; +}