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} \
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
@BIND9_MAKE_RULES@
......
......@@ -39,6 +39,7 @@
#include <dns/rdataset.h>
#include <dns/compress.h>
#include <dns/db.h>
#include <dns/message.h>
#include <sys/types.h>
#include <sys/socket.h>
......@@ -55,10 +56,16 @@ isc_mem_t *mctx = NULL;
isc_boolean_t want_stats = ISC_FALSE;
dns_db_t *db;
/*
* For debugging only... XXX
*/
void dump_packet(unsigned char *buf, u_int len);
static inline isc_boolean_t
CHECKRESULT(dns_result_t result, char *msg)
{
if ((result) != DNS_R_SUCCESS) {
printf("%s: %s\n", (msg), dns_result_totext(result));
return (ISC_TRUE);
}
return (ISC_FALSE);
}
static void
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
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
......@@ -103,19 +133,12 @@ resolve_packet(dns_db_t *db, isc_buffer_t *source, isc_buffer_t *target);
static dns_result_t
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 target;
dns_result_t result;
isc_region_t txr;
dump_packet(rxr->base, rxr->length);
/*
* Set up the temporary output buffer.
*/
isc_buffer_init(&target, t + reslen, sizeof(t) - reslen,
ISC_BUFFERTYPE_BINARY);
dns_message_t *message, *reply;
/*
* 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)
ISC_BUFFERTYPE_BINARY);
isc_buffer_add(&source, rxr->length);
result = resolve_packet(db, &source, &target);
if (result != DNS_R_SUCCESS)
result = dns_message_create(mctx, &message, DNS_MESSAGE_INTENT_PARSE);
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);
}
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
*/
isc_buffer_used(&target, &txr);
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);
}
memcpy(txr.base + reslen, t + reslen, txr.length);
rxr->base = txr.base;
......@@ -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);
fflush(stdout);
dump_packet(rxr->base + reslen, rxr->length - reslen);
if (want_stats)
isc_mem_stats(mctx, stdout);
dns_message_destroy(&reply);
return (DNS_R_SUCCESS);
}
......
......@@ -42,61 +42,32 @@
#include <dns/rdataset.h>
#include <dns/compress.h>
#include <dns/db.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;
#include <dns/message.h>
void
dump_packet(unsigned char *buf, u_int len);
dump_packet(isc_mem_t *mctx, unsigned char *buf, u_int len);
dns_result_t
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);
#define CHECKRESULT(result, msg) \
{ \
if ((result) != DNS_R_SUCCESS) { \
printf("%s: %s\n", (msg), dns_result_totext(result)); \
return; \
} \
}
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;
char t[5000]; /* XXX */
dns_message_t message;
dns_message_t *message;
dns_result_t result;
isc_buffer_t source, target;
isc_buffer_t source;
unsigned int i;
rdcount = 0;
rlcount = 0;
ncount = 0;
for (i = 0 ; i < len ; /* */ ) {
fprintf(stdout, "%02x", buf[i]);
if ((++i % 20) == 0)
......@@ -110,13 +81,17 @@ dump_packet(unsigned char *buf, u_int len)
isc_buffer_init(&source, buf, len, ISC_BUFFERTYPE_BINARY);
isc_buffer_add(&source, len);
isc_buffer_init(&target, t, sizeof(t), ISC_BUFFERTYPE_BINARY);
getmessage(&message, &source, &target);
result = printmessage(&message);
if (result != DNS_R_SUCCESS)
printf("printmessage() failed: %s\n",
dns_result_totext(result));
result = dns_message_create(mctx, &message, DNS_MESSAGE_INTENT_PARSE);
CHECKRESULT(result, "dns_message_create failed");
result = dns_message_parse(message, &source);
CHECKRESULT(result, "dns_message_parse failed");
result = printmessage(message);
CHECKRESULT(result, "printmessage() failed");
dns_message_destroy(&message);
}
static isc_uint16_t
......@@ -133,13 +108,13 @@ getshort(isc_buffer_t *buffer) {
}
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_compress_t cctx;
dns_result_t result;
unsigned int count;
dns_message_t message;
dns_name_t name;
isc_uint16_t qtype;
isc_uint16_t qclass;
......
......@@ -39,10 +39,7 @@
#include <dns/message.h>
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);
static inline void
......@@ -69,6 +66,7 @@ print_wirename(isc_region_t *name) {
}
#endif
#ifndef NOMAIN
static int
fromhex(char c) {
if (c >= '0' && c <= '9')
......@@ -82,6 +80,7 @@ fromhex(char c) {
exit(3);
/* NOTREACHED */
}
#endif
static char *opcodetext[] = {
"QUERY",
......@@ -260,7 +259,6 @@ main(int argc, char *argv[]) {
unsigned char b[1000];
char s[1000];
dns_message_t *message;
dns_message_t *message2;
dns_result_t result;
isc_mem_t *mctx;
......
......@@ -110,6 +110,8 @@ typedef struct {
unsigned int from_to_wire : 2;
unsigned int reserved;
isc_buffer_t *buffer;
isc_mem_t *mctx;
ISC_LIST(isc_dynbuffer_t) scratchpad;
ISC_LIST(dns_msgblock_t) names;
......@@ -221,11 +223,35 @@ dns_message_renderbegin(dns_message_t *msg, isc_buffer_t *buffer);
* Requires:
*
* 'msg' be valid.
*
* buffer != NULL.
*
* buffer is empty.
*/
dns_result_t
dns_message_renderreserve(dns_message_t *msg, isc_buffer_t *buffer,
unsigned int space);
dns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer);
/*
* 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.
*
......@@ -233,6 +259,8 @@ dns_message_renderreserve(dns_message_t *msg, isc_buffer_t *buffer,
*
* 'msg' be valid.
*
* dns_message_renderbegin() was called.
*
* Returns:
*
* DNS_R_SUCCESS -- all is well.
......@@ -248,6 +276,8 @@ dns_message_renderrelease(dns_message_t *msg, unsigned int space);
*
* 'msg' be valid.
*
* dns_message_renderbegin() was called.
*
* Returns:
*
* DNS_R_SUCCESS -- all is well.
......@@ -255,9 +285,8 @@ dns_message_renderrelease(dns_message_t *msg, unsigned int space);
*/
dns_result_t
dns_message_rendersection(dns_message_t *msg, isc_buffer_t *buffer,
dns_section_t section, unsigned int priority,
unsigned int flags);
dns_message_rendersection(dns_message_t *msg, dns_section_t section,
unsigned int priority, unsigned int flags);
/*
* Render all names, rdatalists, etc from the given section at the
* specified priority or higher.
......@@ -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
* block.
*
* dns_message_renderbegin() was called.
*
* Returns:
* DNS_R_SUCCESS -- all records were written, and there are
* no more records for this section.
......@@ -280,7 +311,7 @@ dns_message_rendersection(dns_message_t *msg, isc_buffer_t *buffer,
*/
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
* '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);
*
* 'msg' be a valid message.
*
* dns_message_renderbegin() was called.
*
* Returns:
*
* DNS_R_SUCCESS -- all is well.
......
......@@ -345,6 +345,8 @@ msginit(dns_message_t *m)
m->nextrdata = NULL;
m->nextrdataset = NULL;
m->nextrdatalist = NULL;
m->buffer = NULL;
}
/*
......@@ -992,17 +994,69 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source)
dns_result_t
dns_message_renderbegin(dns_message_t *msg, isc_buffer_t *buffer)
{
isc_region_t r;
REQUIRE(VALID_MESSAGE(msg));
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_message_renderrelease(dns_message_t *msg, unsigned int space)
{
REQUIRE(VALID_MESSAGE(msg));
REQUIRE(msg->buffer != NULL);
if (msg->reserved < space)
return (DNS_R_NOSPACE);
......@@ -1013,13 +1067,12 @@ dns_message_renderrelease(dns_message_t *msg, unsigned int space)
}
dns_result_t
dns_message_renderreserve(dns_message_t *msg, isc_buffer_t *buffer,
unsigned int space)
dns_message_renderreserve(dns_message_t *msg, unsigned int space)
{
isc_region_t r;
REQUIRE(VALID_MESSAGE(msg));
REQUIRE(buffer != NULL);
REQUIRE(msg->buffer != NULL);
/*
* "space" can be positive or negative. If it is negative we are
......@@ -1027,7 +1080,7 @@ dns_message_renderreserve(dns_message_t *msg, isc_buffer_t *buffer,
* requesting more space to be reserved.
*/
isc_buffer_available(buffer, &r);
isc_buffer_available(msg->buffer, &r);
if (r.length < (space + msg->reserved))
return (DNS_R_NOSPACE);
......@@ -1037,12 +1090,11 @@ dns_message_renderreserve(dns_message_t *msg, isc_buffer_t *buffer,
}
dns_result_t
dns_message_rendersection(dns_message_t *msg, isc_buffer_t *buffer,
dns_section_t section, unsigned int priority,
unsigned int flags)
dns_message_rendersection(dns_message_t *msg, dns_section_t section,
unsigned int priority, unsigned int flags)
{
REQUIRE(VALID_MESSAGE(msg));
REQUIRE(buffer != NULL);
REQUIRE(msg->buffer != NULL);
REQUIRE(VALID_NAMED_SECTION(section));
/* XXX implement */
......@@ -1050,10 +1102,12 @@ dns_message_rendersection(dns_message_t *msg, isc_buffer_t *buffer,
}
dns_result_t
dns_message_renderend(dns_message_t *msg, isc_buffer_t *buffer)
dns_message_renderend(dns_message_t *msg)
{
REQUIRE(VALID_MESSAGE(msg));
REQUIRE(buffer != NULL);
REQUIRE(msg->buffer != NULL);
msg->buffer = NULL; /* forget about this buffer only on success XXX */
/* XXX implement */
return (ISC_R_NOTIMPLEMENTED);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment