From: Miek Gieben Date: Tue, 18 Apr 2006 09:15:49 +0000 (+0000) Subject: added 2 new function, X-Git-Tag: release-1.1.0~178 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8f5135c9c1e2211c165bca3bf3085ec86bcd86e5;p=thirdparty%2Fldns.git added 2 new function, ldns_pkt_push_rr_list and ldns_pkt_safe_push_rr_list simplify ldnsd and let it use these new functions added nsd-ldnsd.c wich only return ixfr messages on each received query --- diff --git a/Changelog b/Changelog index cb6226eb..4b848078 100644 --- a/Changelog +++ b/Changelog @@ -72,9 +72,10 @@ * ldns_rr_list_pop_rr_list(): pop multiple rr's from another rr_list * ldns_rr_list_push_rr_list(): push multiple rr's to an rr_list * ldns_rr_list_compare(): compare 2 ldns_rr_lists + * ldns_pkt_push_rr_list: rr_list equiv for rr + * ldns_pkt_safe_push_rr_list: rr_list equiv for rr Removed: - * ldns_resolver_bgsend(): was not used in 1.0.0 and is not used - now + * ldns_resolver_bgsend(): was not used in 1.0.0 and is not used now * ldns_udp_server_connect(): was faulty and isn't really part of the core ldns idea any how. * ldns_rr_list_insert_rr(): obsoleted, because not used. diff --git a/examples/Makefile.in b/examples/Makefile.in index af55b4a8..103dcbff 100644 --- a/examples/Makefile.in +++ b/examples/Makefile.in @@ -39,6 +39,7 @@ SOURCES = ldns-read-zone.c \ ldns-dpa.c \ ldns-resolver.c \ ldnsd.c \ + nsd-ldnsd.c \ ldns-keyfetcher.c \ ldns-ixfr.c \ ldns-notify.c diff --git a/examples/ldnsd.c b/examples/ldnsd.c index 70a7b733..a4fb0a11 100644 --- a/examples/ldnsd.c +++ b/examples/ldnsd.c @@ -36,14 +36,6 @@ static int udp_bind(int sock, int port, const char *my_address) addr.sin_family = AF_INET; addr.sin_port = (in_port_t)htons((uint16_t)port); addr.sin_addr.s_addr = INADDR_ANY; -// if (join_mcast(sock, &addr) == -1) { return -1; } -/* - if (join_group(sock, inet_addr(my_address), INADDR_ANY)) { - perror("setsockopt"); - } else { - fprintf(stderr, "Ok.\n"); - } -*/ return bind(sock, (struct sockaddr *)&addr, (socklen_t) sizeof(addr)); } @@ -79,7 +71,6 @@ main(int argc, char **argv) { /* arguments */ int port; - const char *zone_name; const char *zone_file; /* network */ @@ -118,8 +109,8 @@ main(int argc, char **argv) port = atoi(argv[1]); if (port < 1) { usage(stdout); + exit(EXIT_FAILURE); } - zone_name = argv[2]; zone_file = argv[3]; } @@ -139,17 +130,14 @@ main(int argc, char **argv) } else { printf("Read %u resource records in zone file\n", (unsigned int) ldns_zone_rr_count(zone)); } - fclose(zone_fp); - printf("Listening on port %d\n", port); sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { fprintf(stderr, "%s: socket(): %s\n", argv[0], strerror(errno)); exit(1); } - memset(&addr_me, 0, sizeof(addr_me)); /* bind: try all ports in that range */ @@ -169,7 +157,6 @@ main(int argc, char **argv) /* show(inbuf, nb, nn, hp, sp, ip, bp); */ - printf("Got query of %u bytes\n", (unsigned int) nb); status = ldns_wire2pkt(&query_pkt, inbuf, nb); if (status != LDNS_STATUS_OK) { @@ -187,26 +174,18 @@ main(int argc, char **argv) answer_an = get_rrset(zone, ldns_rr_owner(query_rr), ldns_rr_get_type(query_rr), ldns_rr_get_class(query_rr)); answer_pkt = ldns_pkt_new(); - answer_ns = ldns_rr_list_new(); - answer_ad = ldns_rr_list_new(); ldns_pkt_set_qr(answer_pkt, 1); ldns_pkt_set_aa(answer_pkt, 1); ldns_pkt_set_id(answer_pkt, ldns_pkt_id(query_pkt)); - /* aren't there push_rr(section) functions? */ - /* and why isn't the count automatically updated? */ - ldns_pkt_set_question(answer_pkt, answer_qr); - ldns_pkt_set_qdcount(answer_pkt, ldns_rr_list_rr_count(answer_qr)); - ldns_pkt_set_answer(answer_pkt, answer_an); - ldns_pkt_set_ancount(answer_pkt, ldns_rr_list_rr_count(answer_an)); - ldns_pkt_set_authority(answer_pkt, answer_ns); - ldns_pkt_set_nscount(answer_pkt, ldns_rr_list_rr_count(answer_ns)); - ldns_pkt_set_additional(answer_pkt, answer_ad); - ldns_pkt_set_arcount(answer_pkt, ldns_rr_list_rr_count(answer_ad)); - + ldns_pkt_push_rr_list(answer_pkt, LDNS_SECTION_QUESTION, answer_qr); + ldns_pkt_push_rr_list(answer_pkt, LDNS_SECTION_ANSWER, answer_an); + ldns_pkt_push_rr_list(answer_pkt, LDNS_SECTION_AUTHORITY, answer_ns); + ldns_pkt_push_rr_list(answer_pkt, LDNS_SECTION_ADDITIONAL, answer_ad); + status = ldns_pkt2wire(&outbuf, answer_pkt, &answer_size); printf("Answer packet size: %u bytes.\n", (unsigned int) answer_size); @@ -215,10 +194,6 @@ main(int argc, char **argv) } else { nb = (size_t) sendto(sock, outbuf, answer_size, 0, &addr_him, hislen); } - - - } - return 0; } diff --git a/examples/nsd-ldnsd.c b/examples/nsd-ldnsd.c new file mode 100644 index 00000000..b1a00c44 --- /dev/null +++ b/examples/nsd-ldnsd.c @@ -0,0 +1,161 @@ +/* + * nsd-ldnsd. Light-weight DNS daemon, which sends IXFRs + * + * Tiny dns server to show how a real one could be built. + * This version is used for NSD test, send out IXFR's only. + * + * (c) NLnet Labs, 2005, 2006 + * See the file LICENSE for the license + */ + +#include "config.h" +#include + +#include +#include + +#include +#include +#include +#include +#include + +#define INBUF_SIZE 4096 + +void usage(FILE *output) +{ + fprintf(output, "Usage: nsd-ldnsd \n"); + fprintf(output, "Listens on the specified port and answer every query with an IXFR\n"); + fprintf(output, "This is NOT a full-fledged authoritative nameserver! It is NOTHING.\n"); +} + +static int udp_bind(int sock, int port, const char *my_address) +{ + struct sockaddr_in addr; + + addr.sin_family = AF_INET; + addr.sin_port = (in_port_t)htons((uint16_t)port); + addr.sin_addr.s_addr = INADDR_ANY; + return bind(sock, (struct sockaddr *)&addr, (socklen_t) sizeof(addr)); +} + +int +main(int argc, char **argv) +{ + /* arguments */ + int port; + int soa; + ldns_rr *zone_name; + + /* network */ + int sock; + size_t nb; + struct sockaddr addr_me; + struct sockaddr addr_him; + socklen_t hislen; + const char *my_address; + uint8_t inbuf[INBUF_SIZE]; + uint8_t *outbuf; + + /* dns */ + ldns_status status; + ldns_pkt *query_pkt; + ldns_pkt *answer_pkt; + size_t answer_size; + ldns_rr *query_rr; + ldns_rr_list *answer_qr; + ldns_rr_list *answer_ns; + ldns_rr_list *answer_ad; + + /* use this to listen on specified interfaces later? */ + my_address = NULL; + + if (argc < 4) { + usage(stdout); + exit(EXIT_FAILURE); + } else { + port = atoi(argv[1]); + if (port < 1) { + usage(stdout); + exit(EXIT_FAILURE); + } + if (ldns_rr_new_frm_str(&zone_name, argv[2], 0, NULL, NULL) != + LDNS_STATUS_OK) { + usage(stdout); + exit(EXIT_FAILURE); + } + soa = atoi(argv[3]); + if (soa < 1) { + usage(stdout); + exit(EXIT_FAILURE); + } + + } + + printf("Listening on port %d\n", port); + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) { + fprintf(stderr, "%s: socket(): %s\n", argv[0], strerror(errno)); + exit(1); + } + + memset(&addr_me, 0, sizeof(addr_me)); + + /* bind: try all ports in that range */ + if (udp_bind(sock, port, my_address)) { + fprintf(stderr, "%s: cannot bind(): %s\n", argv[0], strerror(errno)); + } + + /* Done. Now receive */ + while (1) { + nb = (size_t) recvfrom(sock, inbuf, INBUF_SIZE, 0, &addr_him, &hislen); + if (nb < 1) { + fprintf(stderr, "%s: recvfrom(): %s\n", + argv[0], strerror(errno)); + exit(1); + } + + /* + show(inbuf, nb, nn, hp, sp, ip, bp); + */ + + printf("Got query of %u bytes\n", (unsigned int) nb); + status = ldns_wire2pkt(&query_pkt, inbuf, nb); + if (status != LDNS_STATUS_OK) { + printf("Got bad packet: %s\n", ldns_get_errorstr_by_id(status)); + } else { + ldns_pkt_print(stdout, query_pkt); + } + + query_rr = ldns_rr_list_rr(ldns_pkt_question(query_pkt), 0); + printf("QUERY RR: \n"); + ldns_rr_print(stdout, query_rr); + + answer_qr = ldns_rr_list_new(); + ldns_rr_list_push_rr(answer_qr, ldns_rr_clone(query_rr)); + + answer_pkt = ldns_pkt_new(); + answer_ns = ldns_rr_list_new(); + answer_ad = ldns_rr_list_new(); + + ldns_pkt_set_qr(answer_pkt, 1); + ldns_pkt_set_aa(answer_pkt, 1); + ldns_pkt_set_id(answer_pkt, ldns_pkt_id(query_pkt)); + + + + status = ldns_pkt2wire(&outbuf, answer_pkt, &answer_size); + + printf("Answer packet size: %u bytes.\n", (unsigned int) answer_size); + if (status != LDNS_STATUS_OK) { + printf("Error creating answer: %s\n", ldns_get_errorstr_by_id(status)); + } else { + nb = (size_t) sendto(sock, outbuf, answer_size, 0, &addr_him, hislen); + } + + + + } + + return 0; +} diff --git a/ldns/packet.h b/ldns/packet.h index 2ab8ec32..071c6199 100644 --- a/ldns/packet.h +++ b/ldns/packet.h @@ -662,22 +662,40 @@ void ldns_pkt_set_authority(ldns_pkt *p, ldns_rr_list *rr); /** * push an rr on a packet - * \param[in] packet packet to operatore on + * \param[in] packet packet to operate on * \param[in] section where to put it * \param[in] rr rr to push - * \return ldns_status status + * \return a boolean which is true when the rr was added */ bool ldns_pkt_push_rr(ldns_pkt *packet, ldns_pkt_section section, ldns_rr *rr); /** * push an rr on a packet, provided the RR is not there. - * \param[in] pkt packet to operatore on + * \param[in] pkt packet to operate on * \param[in] sec where to put it * \param[in] rr rr to push - * \return ldns_status status + * \return a boolean which is true when the rr was added */ bool ldns_pkt_safe_push_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr); +/** + * push a rr_list on a packet + * \param[in] packet packet to operate on + * \param[in] section where to put it + * \param[in] list the rr_list to push + * \return a boolean which is true when the rr was added + */ +bool ldns_pkt_push_rr_list(ldns_pkt *packet, ldns_pkt_section section, ldns_rr_list *list); + +/** + * push an rr_list to a packet, provided the RRs are not already there. + * \param[in] pkt packet to operate on + * \param[in] sec where to put it + * \param[in] list the rr_list to push + * \return a boolean which is true when the rr was added + */ +bool ldns_pkt_safe_push_rr_list(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr_list *list); + /** * check if a packet is empty * \param[in] p packet @@ -685,6 +703,4 @@ bool ldns_pkt_safe_push_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr); */ bool ldns_pkt_empty(ldns_pkt *p); - - #endif /* LDNS_PACKET_H */ diff --git a/packet.c b/packet.c index b18c45d4..b33448f1 100644 --- a/packet.c +++ b/packet.c @@ -664,6 +664,30 @@ ldns_pkt_safe_push_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr) return ldns_pkt_push_rr(pkt, sec, rr); } +bool +ldns_pkt_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list) +{ + size_t i; + for(i = 0; i < ldns_rr_list_rr_count(list); i++) { + if (!ldns_pkt_push_rr(p, s, ldns_rr_list_rr(list, i))) { + return false; + } + } + return true; +} + +bool +ldns_pkt_safe_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list) +{ + size_t i; + for(i = 0; i < ldns_rr_list_rr_count(list); i++) { + if (!ldns_pkt_safe_push_rr(p, s, ldns_rr_list_rr(list, i))) { + return false; + } + } + return true; +} + bool ldns_pkt_edns(const ldns_pkt *pkt) { return (ldns_pkt_edns_udp_size(pkt) > 0 ||