Commit e690d225 authored by Michael Graff's avatar Michael Graff

Make named compile, and start on using message code. This isn't done yet.

parent 597bdfef
...@@ -37,7 +37,7 @@ LIBS = ${DEPLIBS} \ ...@@ -37,7 +37,7 @@ LIBS = ${DEPLIBS} \
TARGETS = named TARGETS = named
OBJS = server.o udpclient.o tcpclient.o wire_debug.o wire_test.o\ OBJS = server.o udpclient.o tcpclient.o wire_test.o \
zone.o configctx.o confparser.o zone.o configctx.o confparser.o
@BIND9_MAKE_RULES@ @BIND9_MAKE_RULES@
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <dns/rdataset.h> #include <dns/rdataset.h>
#include <dns/compress.h> #include <dns/compress.h>
#include <dns/db.h> #include <dns/db.h>
#include <dns/message.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
...@@ -55,10 +56,16 @@ isc_mem_t *mctx = NULL; ...@@ -55,10 +56,16 @@ isc_mem_t *mctx = NULL;
isc_boolean_t want_stats = ISC_FALSE; isc_boolean_t want_stats = ISC_FALSE;
dns_db_t *db; dns_db_t *db;
/* static inline isc_boolean_t
* For debugging only... XXX CHECKRESULT(dns_result_t result, char *msg)
*/ {
void dump_packet(unsigned char *buf, u_int len); if ((result) != DNS_R_SUCCESS) {
printf("%s: %s\n", (msg), dns_result_totext(result));
return (ISC_TRUE);
}
return (ISC_FALSE);
}
static void static void
makename(isc_mem_t *mctx, char *text, dns_name_t *name, dns_name_t *origin) { makename(isc_mem_t *mctx, char *text, dns_name_t *name, dns_name_t *origin) {
...@@ -86,10 +93,33 @@ makename(isc_mem_t *mctx, char *text, dns_name_t *name, dns_name_t *origin) { ...@@ -86,10 +93,33 @@ makename(isc_mem_t *mctx, char *text, dns_name_t *name, dns_name_t *origin) {
} }
/* /*
* XXX This will be in a .h file soon... * This is in bin/tests/wire_test.c, but should be in a debugging library.
*/ */
extern dns_result_t
printmessage(dns_message_t *);
dns_result_t
resolve_packet(isc_mem_t *mctx, dns_db_t *, dns_message_t *,
dns_message_t **, isc_buffer_t *);
dns_result_t dns_result_t
resolve_packet(dns_db_t *db, isc_buffer_t *source, isc_buffer_t *target); resolve_packet(isc_mem_t *mctx, dns_db_t *db, dns_message_t *query,
dns_message_t **reply, isc_buffer_t *target)
{
dns_message_t *message;
dns_result_t result;
result = dns_message_create(mctx, &message, DNS_MESSAGE_INTENT_RENDER);
CHECKRESULT(result, "dns_message_create failed");
message->id = query->id;
message->rcode =
result = printmessage(message);
CHECKRESULT(result, "printmessage() failed");
return (DNS_R_NOSPACE);
}
/* /*
* Process the wire format message given in r, and return a new packet to * Process the wire format message given in r, and return a new packet to
...@@ -103,19 +133,12 @@ resolve_packet(dns_db_t *db, isc_buffer_t *source, isc_buffer_t *target); ...@@ -103,19 +133,12 @@ resolve_packet(dns_db_t *db, isc_buffer_t *source, isc_buffer_t *target);
static dns_result_t static dns_result_t
dispatch(isc_mem_t *mctx, isc_region_t *rxr, unsigned int reslen) dispatch(isc_mem_t *mctx, isc_region_t *rxr, unsigned int reslen)
{ {
char t[5000]; char t[512];
isc_buffer_t source; isc_buffer_t source;
isc_buffer_t target; isc_buffer_t target;
dns_result_t result; dns_result_t result;
isc_region_t txr; isc_region_t txr;
dns_message_t *message, *reply;
dump_packet(rxr->base, rxr->length);
/*
* Set up the temporary output buffer.
*/
isc_buffer_init(&target, t + reslen, sizeof(t) - reslen,
ISC_BUFFERTYPE_BINARY);
/* /*
* Set up the input buffer from the contents of the region passed * Set up the input buffer from the contents of the region passed
...@@ -125,17 +148,43 @@ dispatch(isc_mem_t *mctx, isc_region_t *rxr, unsigned int reslen) ...@@ -125,17 +148,43 @@ dispatch(isc_mem_t *mctx, isc_region_t *rxr, unsigned int reslen)
ISC_BUFFERTYPE_BINARY); ISC_BUFFERTYPE_BINARY);
isc_buffer_add(&source, rxr->length); isc_buffer_add(&source, rxr->length);
result = resolve_packet(db, &source, &target); result = dns_message_create(mctx, &message, DNS_MESSAGE_INTENT_PARSE);
if (result != DNS_R_SUCCESS) if (CHECKRESULT(result, "dns_message_create failed")) {
return (result);
}
result = dns_message_parse(message, &source);
if (CHECKRESULT(result, "dns_message_parsed failed")) {
dns_message_destroy(&message);
return (result);
}
CHECKRESULT(result, "dns_message_parse failed");
result = printmessage(message);
if (CHECKRESULT(result, "printmessage failed")) {
dns_message_destroy(&message);
return (result); return (result);
}
isc_buffer_init(&target, t, sizeof(t), ISC_BUFFERTYPE_BINARY);
result = resolve_packet(mctx, db, message, &reply, &target);
dns_message_destroy(&message);
if (result != DNS_R_SUCCESS) {
if (reply != NULL)
dns_message_destroy(&reply);
return (result);
}
/* /*
* Copy the reply out, adjusting for reslen * Copy the reply out, adjusting for reslen
*/ */
isc_buffer_used(&target, &txr); isc_buffer_used(&target, &txr);
txr.base = isc_mem_get(mctx, txr.length + reslen); txr.base = isc_mem_get(mctx, txr.length + reslen);
if (txr.base == NULL) if (txr.base == NULL) {
dns_message_destroy(&reply);
return (DNS_R_NOMEMORY); return (DNS_R_NOMEMORY);
}
memcpy(txr.base + reslen, t + reslen, txr.length); memcpy(txr.base + reslen, t + reslen, txr.length);
rxr->base = txr.base; rxr->base = txr.base;
...@@ -144,11 +193,11 @@ dispatch(isc_mem_t *mctx, isc_region_t *rxr, unsigned int reslen) ...@@ -144,11 +193,11 @@ dispatch(isc_mem_t *mctx, isc_region_t *rxr, unsigned int reslen)
printf("Base == %p, length == %u\n", txr.base, txr.length); printf("Base == %p, length == %u\n", txr.base, txr.length);
fflush(stdout); fflush(stdout);
dump_packet(rxr->base + reslen, rxr->length - reslen);
if (want_stats) if (want_stats)
isc_mem_stats(mctx, stdout); isc_mem_stats(mctx, stdout);
dns_message_destroy(&reply);
return (DNS_R_SUCCESS); return (DNS_R_SUCCESS);
} }
......
...@@ -42,61 +42,32 @@ ...@@ -42,61 +42,32 @@
#include <dns/rdataset.h> #include <dns/rdataset.h>
#include <dns/compress.h> #include <dns/compress.h>
#include <dns/db.h> #include <dns/db.h>
#include <dns/message.h>
#define DNS_FLAG_QR 0x8000U
#define DNS_FLAG_AA 0x0400U
#define DNS_FLAG_TC 0x0200U
#define DNS_FLAG_RD 0x0100U
#define DNS_FLAG_RA 0x0080U
#define DNS_OPCODE_MASK 0x7000U
#define DNS_OPCODE_SHIFT 11
#define DNS_RCODE_MASK 0x000FU
/*
* XXX All of the following is for debugging only, and will eventually
* be in a library or removed when we really answer queries.
*/
typedef struct dns_message {
unsigned int id;
unsigned int flags;
unsigned int qcount;
unsigned int ancount;
unsigned int aucount;
unsigned int adcount;
dns_namelist_t question;
dns_namelist_t answer;
dns_namelist_t authority;
dns_namelist_t additional;
} dns_message_t;
void void
dump_packet(unsigned char *buf, u_int len); dump_packet(isc_mem_t *mctx, unsigned char *buf, u_int len);
dns_result_t dns_result_t
resolve_packet(dns_db_t *db, isc_buffer_t *source, isc_buffer_t *target); resolve_packet(dns_db_t *db, isc_buffer_t *source, isc_buffer_t *target);
/*
* in wire_test.c
*/
void getmessage(dns_message_t *message, isc_buffer_t *source,
isc_buffer_t *target);
dns_result_t printmessage(dns_message_t *message); dns_result_t printmessage(dns_message_t *message);
#define CHECKRESULT(result, msg) \
{ \
if ((result) != DNS_R_SUCCESS) { \
printf("%s: %s\n", (msg), dns_result_totext(result)); \
return; \
} \
}
void void
dump_packet(unsigned char *buf, u_int len) dump_packet(isc_mem_t *mctx, unsigned char *buf, u_int len)
{ {
extern unsigned int rdcount, rlcount, ncount; dns_message_t *message;
char t[5000]; /* XXX */
dns_message_t message;
dns_result_t result; dns_result_t result;
isc_buffer_t source, target; isc_buffer_t source;
unsigned int i; unsigned int i;
rdcount = 0;
rlcount = 0;
ncount = 0;
for (i = 0 ; i < len ; /* */ ) { for (i = 0 ; i < len ; /* */ ) {
fprintf(stdout, "%02x", buf[i]); fprintf(stdout, "%02x", buf[i]);
if ((++i % 20) == 0) if ((++i % 20) == 0)
...@@ -110,13 +81,17 @@ dump_packet(unsigned char *buf, u_int len) ...@@ -110,13 +81,17 @@ dump_packet(unsigned char *buf, u_int len)
isc_buffer_init(&source, buf, len, ISC_BUFFERTYPE_BINARY); isc_buffer_init(&source, buf, len, ISC_BUFFERTYPE_BINARY);
isc_buffer_add(&source, len); isc_buffer_add(&source, len);
isc_buffer_init(&target, t, sizeof(t), ISC_BUFFERTYPE_BINARY);
getmessage(&message, &source, &target); result = dns_message_create(mctx, &message, DNS_MESSAGE_INTENT_PARSE);
result = printmessage(&message); CHECKRESULT(result, "dns_message_create failed");
if (result != DNS_R_SUCCESS)
printf("printmessage() failed: %s\n", result = dns_message_parse(message, &source);
dns_result_totext(result)); CHECKRESULT(result, "dns_message_parse failed");
result = printmessage(message);
CHECKRESULT(result, "printmessage() failed");
dns_message_destroy(&message);
} }
static isc_uint16_t static isc_uint16_t
...@@ -133,13 +108,13 @@ getshort(isc_buffer_t *buffer) { ...@@ -133,13 +108,13 @@ getshort(isc_buffer_t *buffer) {
} }
dns_result_t dns_result_t
resolve_packet(dns_db_t *db, isc_buffer_t *source, isc_buffer_t *target) resolve_packet(dns_db_t *db, dns_message_t *query, dns_message_t **reply,
isc_buffer_t *target)
{ {
dns_decompress_t dctx; dns_decompress_t dctx;
dns_compress_t cctx; dns_compress_t cctx;
dns_result_t result; dns_result_t result;
unsigned int count; unsigned int count;
dns_message_t message;
dns_name_t name; dns_name_t name;
isc_uint16_t qtype; isc_uint16_t qtype;
isc_uint16_t qclass; isc_uint16_t qclass;
......
...@@ -39,10 +39,7 @@ ...@@ -39,10 +39,7 @@
#include <dns/message.h> #include <dns/message.h>
dns_decompress_t dctx; dns_decompress_t dctx;
unsigned int rdcount, rlcount, ncount;
void getmessage(dns_message_t *message, isc_buffer_t *source,
isc_buffer_t *target);
dns_result_t printmessage(dns_message_t *message); dns_result_t printmessage(dns_message_t *message);
static inline void static inline void
...@@ -69,6 +66,7 @@ print_wirename(isc_region_t *name) { ...@@ -69,6 +66,7 @@ print_wirename(isc_region_t *name) {
} }
#endif #endif
#ifndef NOMAIN
static int static int
fromhex(char c) { fromhex(char c) {
if (c >= '0' && c <= '9') if (c >= '0' && c <= '9')
...@@ -82,6 +80,7 @@ fromhex(char c) { ...@@ -82,6 +80,7 @@ fromhex(char c) {
exit(3); exit(3);
/* NOTREACHED */ /* NOTREACHED */
} }
#endif
static char *opcodetext[] = { static char *opcodetext[] = {
"QUERY", "QUERY",
...@@ -260,7 +259,6 @@ main(int argc, char *argv[]) { ...@@ -260,7 +259,6 @@ main(int argc, char *argv[]) {
unsigned char b[1000]; unsigned char b[1000];
char s[1000]; char s[1000];
dns_message_t *message; dns_message_t *message;
dns_message_t *message2;
dns_result_t result; dns_result_t result;
isc_mem_t *mctx; isc_mem_t *mctx;
......
...@@ -110,6 +110,8 @@ typedef struct { ...@@ -110,6 +110,8 @@ typedef struct {
unsigned int from_to_wire : 2; unsigned int from_to_wire : 2;
unsigned int reserved; unsigned int reserved;
isc_buffer_t *buffer;
isc_mem_t *mctx; isc_mem_t *mctx;
ISC_LIST(isc_dynbuffer_t) scratchpad; ISC_LIST(isc_dynbuffer_t) scratchpad;
ISC_LIST(dns_msgblock_t) names; ISC_LIST(dns_msgblock_t) names;
...@@ -221,11 +223,35 @@ dns_message_renderbegin(dns_message_t *msg, isc_buffer_t *buffer); ...@@ -221,11 +223,35 @@ dns_message_renderbegin(dns_message_t *msg, isc_buffer_t *buffer);
* Requires: * Requires:
* *
* 'msg' be valid. * 'msg' be valid.
*
* buffer != NULL.
*
* buffer is empty.
*/ */
dns_result_t dns_result_t
dns_message_renderreserve(dns_message_t *msg, isc_buffer_t *buffer, dns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer);
unsigned int space); /*
* Reset the buffer. This can be used after growing the old buffer
* on a DNS_R_NOSPACE return from most of the render functions.
*
* Requires:
*
* 'msg' be valid.
*
* dns_message_renderbegin() was called.
*
* buffer != NULL.
*
* Returns:
*
* DNS_R_NOSPACE - new buffer is too small
*
* DNS_R_SUCCESS - all is well.
*/
dns_result_t
dns_message_renderreserve(dns_message_t *msg, unsigned int space);
/* /*
* Reserve "space" bytes in the given buffer. * Reserve "space" bytes in the given buffer.
* *
...@@ -233,6 +259,8 @@ dns_message_renderreserve(dns_message_t *msg, isc_buffer_t *buffer, ...@@ -233,6 +259,8 @@ dns_message_renderreserve(dns_message_t *msg, isc_buffer_t *buffer,
* *
* 'msg' be valid. * 'msg' be valid.
* *
* dns_message_renderbegin() was called.
*
* Returns: * Returns:
* *
* DNS_R_SUCCESS -- all is well. * DNS_R_SUCCESS -- all is well.
...@@ -248,6 +276,8 @@ dns_message_renderrelease(dns_message_t *msg, unsigned int space); ...@@ -248,6 +276,8 @@ dns_message_renderrelease(dns_message_t *msg, unsigned int space);
* *
* 'msg' be valid. * 'msg' be valid.
* *
* dns_message_renderbegin() was called.
*
* Returns: * Returns:
* *
* DNS_R_SUCCESS -- all is well. * DNS_R_SUCCESS -- all is well.
...@@ -255,9 +285,8 @@ dns_message_renderrelease(dns_message_t *msg, unsigned int space); ...@@ -255,9 +285,8 @@ dns_message_renderrelease(dns_message_t *msg, unsigned int space);
*/ */
dns_result_t dns_result_t
dns_message_rendersection(dns_message_t *msg, isc_buffer_t *buffer, dns_message_rendersection(dns_message_t *msg, dns_section_t section,
dns_section_t section, unsigned int priority, unsigned int priority, unsigned int flags);
unsigned int flags);
/* /*
* Render all names, rdatalists, etc from the given section at the * Render all names, rdatalists, etc from the given section at the
* specified priority or higher. * specified priority or higher.
...@@ -270,6 +299,8 @@ dns_message_rendersection(dns_message_t *msg, isc_buffer_t *buffer, ...@@ -270,6 +299,8 @@ dns_message_rendersection(dns_message_t *msg, isc_buffer_t *buffer,
* 'buffer' be non-NULL and be initialized to point to a valid memory * 'buffer' be non-NULL and be initialized to point to a valid memory
* block. * block.
* *
* dns_message_renderbegin() was called.
*
* Returns: * Returns:
* DNS_R_SUCCESS -- all records were written, and there are * DNS_R_SUCCESS -- all records were written, and there are
* no more records for this section. * no more records for this section.
...@@ -280,7 +311,7 @@ dns_message_rendersection(dns_message_t *msg, isc_buffer_t *buffer, ...@@ -280,7 +311,7 @@ dns_message_rendersection(dns_message_t *msg, isc_buffer_t *buffer,
*/ */
dns_result_t dns_result_t
dns_message_renderend(dns_message_t *msg, isc_buffer_t *buffer); dns_message_renderend(dns_message_t *msg);
/* /*
* Finish rendering to the buffer. Note that more data can be in the * Finish rendering to the buffer. Note that more data can be in the
* 'msg' structure. Destroying the structure will free this, or in a multi- * 'msg' structure. Destroying the structure will free this, or in a multi-
...@@ -290,6 +321,8 @@ dns_message_renderend(dns_message_t *msg, isc_buffer_t *buffer); ...@@ -290,6 +321,8 @@ dns_message_renderend(dns_message_t *msg, isc_buffer_t *buffer);
* *
* 'msg' be a valid message. * 'msg' be a valid message.
* *
* dns_message_renderbegin() was called.
*
* Returns: * Returns:
* *
* DNS_R_SUCCESS -- all is well. * DNS_R_SUCCESS -- all is well.
......
...@@ -345,6 +345,8 @@ msginit(dns_message_t *m) ...@@ -345,6 +345,8 @@ msginit(dns_message_t *m)
m->nextrdata = NULL; m->nextrdata = NULL;
m->nextrdataset = NULL; m->nextrdataset = NULL;
m->nextrdatalist = NULL; m->nextrdatalist = NULL;
m->buffer = NULL;
} }
/* /*
...@@ -992,17 +994,69 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source) ...@@ -992,17 +994,69 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source)
dns_result_t dns_result_t
dns_message_renderbegin(dns_message_t *msg, isc_buffer_t *buffer) dns_message_renderbegin(dns_message_t *msg, isc_buffer_t *buffer)
{ {
isc_region_t r;
REQUIRE(VALID_MESSAGE(msg)); REQUIRE(VALID_MESSAGE(msg));
REQUIRE(buffer != NULL); REQUIRE(buffer != NULL);
REQUIRE(msg->buffer == NULL);
/* XXX implement */ /*
return (ISC_R_NOTIMPLEMENTED); * Erase the contents of this buffer.
*/
isc_buffer_clear(buffer);
/*
* Make certain there is enough for at least the header in this
* buffer.
*/
isc_buffer_available(buffer, &r);
if (r.length < DNS_MESSAGE_HEADER_LEN)
return (DNS_R_NOSPACE);
/*
* Reserve enough space for the header in this buffer.
*/
isc_buffer_add(buffer, DNS_MESSAGE_HEADER_LEN);
return (DNS_R_SUCCESS);
}
dns_result_t
dns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer)
{
isc_region_t r, rn;
REQUIRE(VALID_MESSAGE(msg));
REQUIRE(buffer != NULL);
REQUIRE(msg->buffer != NULL);
/*
* ensure that the new buffer is empty, and has enough space to
* hold the current contents.
*/
isc_buffer_clear(buffer);
isc_buffer_available(buffer, &rn);
isc_buffer_used(msg->buffer, &r);
if (rn.length < r.length)
return (DNS_R_NOSPACE);
/*
* Copy the contents from the old to the new buffer.
*/
isc_buffer_add(buffer, r.length);
memcpy(rn.base, r.base, r.length);
msg->buffer = buffer;
return (DNS_R_SUCCESS);
} }
dns_result_t dns_result_t
dns_message_renderrelease(dns_message_t *msg, unsigned int space) dns_message_renderrelease(dns_message_t *msg, unsigned int space)
{ {
REQUIRE(VALID_MESSAGE(msg)); REQUIRE(VALID_MESSAGE(msg));
REQUIRE(msg->buffer != NULL);
if (msg->reserved < space) if (msg->reserved < space)
return (DNS_R_NOSPACE); return (DNS_R_NOSPACE);
...@@ -1013,13 +1067,12 @@ dns_message_renderrelease(dns_message_t *msg, unsigned int space) ...@@ -1013,13 +1067,12 @@ dns_message_renderrelease(dns_message_t *msg, unsigned int space)
} }