* 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.
ldns-dpa.c \
ldns-resolver.c \
ldnsd.c \
+ nsd-ldnsd.c \
ldns-keyfetcher.c \
ldns-ixfr.c \
ldns-notify.c
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));
}
{
/* arguments */
int port;
- const char *zone_name;
const char *zone_file;
/* network */
port = atoi(argv[1]);
if (port < 1) {
usage(stdout);
+ exit(EXIT_FAILURE);
}
- zone_name = argv[2];
zone_file = argv[3];
}
} 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 */
/*
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) {
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);
} else {
nb = (size_t) sendto(sock, outbuf, answer_size, 0, &addr_him, hislen);
}
-
-
-
}
-
return 0;
}
--- /dev/null
+/*
+ * 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 <ldns/dns.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <netinet/udp.h>
+#include <netinet/igmp.h>
+#include <errno.h>
+
+#define INBUF_SIZE 4096
+
+void usage(FILE *output)
+{
+ fprintf(output, "Usage: nsd-ldnsd <port> <zone> <soa-serial>\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;
+}
/**
* 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
*/
bool ldns_pkt_empty(ldns_pkt *p);
-
-
#endif /* LDNS_PACKET_H */
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 ||