From bcb94f473fd6ca9c43e644e63a620576cbbe0e2c Mon Sep 17 00:00:00 2001 From: Michael Graff Date: Thu, 20 Jan 2000 00:54:27 +0000 Subject: [PATCH] create a view and all the goop associated with it. --- bin/lwresd/client.c | 96 ++++++++++++++++++++++-- bin/lwresd/client.h | 15 +++- bin/lwresd/main.c | 176 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 276 insertions(+), 11 deletions(-) diff --git a/bin/lwresd/client.c b/bin/lwresd/client.c index 20cd24c35a..ffc370ce9c 100644 --- a/bin/lwresd/client.c +++ b/bin/lwresd/client.c @@ -31,15 +31,92 @@ #include "client.h" +static void +hexdump(char *msg, void *base, size_t len) +{ + unsigned char *p; + unsigned int cnt; + + p = base; + cnt = 0; + + printf("*** %s (%u bytes @ %p)\n", msg, len, base); + + while (cnt < len) { + if (cnt % 16 == 0) + printf("%p: ", p); + else if (cnt % 8 == 0) + printf(" |"); + printf(" %02x", *p++); + cnt++; + + if (cnt % 16 == 0) + printf("\n"); + } + + if (cnt % 16 != 0) + printf("\n"); +} + static void clientmgr_can_die(clientmgr_t *cm) { + if ((cm->flags & CLIENTMGR_FLAG_SHUTTINGDOWN) == 0) + return; + if (ISC_LIST_HEAD(cm->running) != NULL) return; isc_task_detach(&cm->task); } +static void +process_request(client_t *client) +{ + clientmgr_t *cm = client->clientmgr; + lwres_lwpacket_t pkt; + lwres_buffer_t b; + isc_result_t result; + + hexdump("client request", client->buffer, client->length); + + lwres_buffer_init(&b, client->buffer, client->length); + lwres_buffer_add(&b, client->length); + + result = lwres_lwpacket_parseheader(&b, &pkt); + if (result != ISC_R_SUCCESS) { + printf("Invalid packet header received\n"); + goto restart; + } + + printf("OPCODE %08x\n", pkt.opcode); + + switch (pkt.opcode) { + case LWRES_OPCODE_GETADDRSBYNAME: + break; + case LWRES_OPCODE_GETNAMEBYADDR: + break; + case LWRES_OPCODE_NOOP: + break; + default: + printf("Unknown opcode %08x\n", pkt.opcode); + goto restart; + } + + goto restart; /* XXXMLG temporary */ + + /* + * We're working on something, so stay in the run queue. + */ + return; + + restart: + client->isidle = ISC_TRUE; + ISC_LIST_UNLINK(cm->running, client, link); + ISC_LIST_APPEND(cm->idle, client, link); + client_start_recv(cm); +} + void client_recv(isc_task_t *task, isc_event_t *ev) { @@ -60,21 +137,21 @@ client_recv(isc_task_t *task, isc_event_t *ev) /* * Go idle. */ + client->isidle = ISC_TRUE; ISC_LIST_UNLINK(cm->running, client, link); ISC_LIST_APPEND(cm->idle, client, link); clientmgr_can_die(cm); + return; } - /* - * XXXMLG Nothing to do right now, just go idle. - */ - ISC_LIST_UNLINK(cm->running, client, link); - ISC_LIST_APPEND(cm->idle, client, link); + client->length = dev->n; client_start_recv(cm); + process_request(client); + isc_event_free(&ev); } @@ -89,7 +166,12 @@ client_start_recv(clientmgr_t *cm) isc_region_t r; REQUIRE((cm->flags & CLIENTMGR_FLAG_SHUTTINGDOWN) == 0); - REQUIRE((cm->flags & CLIENTMGR_FLAG_RECVPENDING) == 0); + + /* + * If a recv is already running, don't bother. + */ + if ((cm->flags & CLIENTMGR_FLAG_RECVPENDING) != 0) + return (ISC_R_SUCCESS); /* * If we have no idle slots, just return success. @@ -97,6 +179,7 @@ client_start_recv(clientmgr_t *cm) client = ISC_LIST_HEAD(cm->idle); if (client == NULL) return (ISC_R_SUCCESS); + INSIST(client->isidle); /* * Issue the recv. If it fails, return that it did. @@ -117,6 +200,7 @@ client_start_recv(clientmgr_t *cm) * Remove the client from the idle list, and put it on the running * list. */ + client->isidle = ISC_FALSE; ISC_LIST_UNLINK(cm->idle, client, link); ISC_LIST_APPEND(cm->running, client, link); diff --git a/bin/lwresd/client.h b/bin/lwresd/client.h index a7566b31ed..278f96bb51 100644 --- a/bin/lwresd/client.h +++ b/bin/lwresd/client.h @@ -26,6 +26,12 @@ #include #include +#include +#include +#include +#include +#include + #define LWRD_EVENTCLASS ISC_EVENTCLASS(4242) #define LWRD_SHUTDOWN (LWRD_EVENTCLASS + 0x0001) @@ -34,9 +40,14 @@ typedef struct client_s client_t; typedef struct clientmgr_s clientmgr_t; struct client_s { - isc_sockaddr_t sockaddr; /* where to reply */ - clientmgr_t *clientmgr; /* our parent */ + isc_sockaddr_t sockaddr; /* where to reply */ + clientmgr_t *clientmgr; /* our parent */ unsigned char buffer[LWRES_RECVLENGTH]; /* receive buffer */ + isc_uint32_t length; /* length recv'd */ + + isc_boolean_t isidle; + + dns_view_t *view; ISC_LINK(client_t) link; }; diff --git a/bin/lwresd/main.c b/bin/lwresd/main.c index f7e4a55f64..6cdeb64f28 100644 --- a/bin/lwresd/main.c +++ b/bin/lwresd/main.c @@ -47,12 +47,151 @@ clientmgr_t *cmgr; unsigned int ntasks; /* number of tasks actually created */ +dns_view_t *view; +dns_db_t *rootdb; + +isc_taskmgr_t *taskmgr; +isc_socketmgr_t *sockmgr; +isc_timermgr_t *timermgr; + +static char root_ns[] = +";\n" +"; Internet Root Nameservers\n" +";\n" +"; Thu Sep 23 17:57:37 PDT 1999\n" +";\n" +"$TTL 518400\n" +". 518400 IN NS F.ROOT-SERVERS.NET.\n" +". 518400 IN NS B.ROOT-SERVERS.NET.\n" +". 518400 IN NS J.ROOT-SERVERS.NET.\n" +". 518400 IN NS K.ROOT-SERVERS.NET.\n" +". 518400 IN NS L.ROOT-SERVERS.NET.\n" +". 518400 IN NS M.ROOT-SERVERS.NET.\n" +". 518400 IN NS I.ROOT-SERVERS.NET.\n" +". 518400 IN NS E.ROOT-SERVERS.NET.\n" +". 518400 IN NS D.ROOT-SERVERS.NET.\n" +". 518400 IN NS A.ROOT-SERVERS.NET.\n" +". 518400 IN NS H.ROOT-SERVERS.NET.\n" +". 518400 IN NS C.ROOT-SERVERS.NET.\n" +". 518400 IN NS G.ROOT-SERVERS.NET.\n" +"F.ROOT-SERVERS.NET. 3600000 IN A 192.5.5.241\n" +"B.ROOT-SERVERS.NET. 3600000 IN A 128.9.0.107\n" +"J.ROOT-SERVERS.NET. 3600000 IN A 198.41.0.10\n" +"K.ROOT-SERVERS.NET. 3600000 IN A 193.0.14.129\n" +"L.ROOT-SERVERS.NET. 3600000 IN A 198.32.64.12\n" +"M.ROOT-SERVERS.NET. 3600000 IN A 202.12.27.33\n" +"I.ROOT-SERVERS.NET. 3600000 IN A 192.36.148.17\n" +"E.ROOT-SERVERS.NET. 3600000 IN A 192.203.230.10\n" +"D.ROOT-SERVERS.NET. 3600000 IN A 128.8.10.90\n" +"A.ROOT-SERVERS.NET. 3600000 IN A 198.41.0.4\n" +"H.ROOT-SERVERS.NET. 3600000 IN A 128.63.2.53\n" +"C.ROOT-SERVERS.NET. 3600000 IN A 192.33.4.12\n" +"G.ROOT-SERVERS.NET. 3600000 IN A 192.112.36.4\n"; + +static isc_result_t +ns_rootns_init(isc_mem_t *mctx) +{ + isc_result_t result, eresult; + isc_buffer_t source; + size_t len; + int soacount, nscount; + dns_rdatacallbacks_t callbacks; + + rootdb = NULL; + result = dns_db_create(mctx, "rbt", dns_rootname, ISC_FALSE, + dns_rdataclass_in, 0, NULL, &rootdb); + if (result != ISC_R_SUCCESS) + return (result); + + dns_rdatacallbacks_init(&callbacks); + + len = strlen(root_ns); + isc_buffer_init(&source, root_ns, len, ISC_BUFFERTYPE_TEXT); + isc_buffer_add(&source, len); + + result = dns_db_beginload(rootdb, &callbacks.add, + &callbacks.add_private); + if (result != ISC_R_SUCCESS) + return (result); + result = dns_master_loadbuffer(&source, &rootdb->origin, + &rootdb->origin, + rootdb->rdclass, ISC_FALSE, + &soacount, &nscount, &callbacks, + rootdb->mctx); + eresult = dns_db_endload(rootdb, &callbacks.add_private); + if (result == ISC_R_SUCCESS) + result = eresult; + if (result != ISC_R_SUCCESS) + goto db_detach; + + return (DNS_R_SUCCESS); + + db_detach: + dns_db_detach(&rootdb); + + return (result); +} + +static isc_result_t +create_view(isc_mem_t *mctx) +{ + dns_cache_t *cache; + isc_result_t result; + + view = NULL; + cache = NULL; + + /* + * View. + */ + result = dns_view_create(mctx, dns_rdataclass_in, "_default", &view); + if (result != ISC_R_SUCCESS) + goto out; + + /* + * Cache. + */ + result = dns_cache_create(mctx, taskmgr, timermgr, dns_rdataclass_in, + "rbt", 0, NULL, &cache); + if (result != ISC_R_SUCCESS) + goto out; + dns_view_setcache(view, cache); + dns_cache_detach(&cache); + + /* + * Resolver. + * + * XXXMLG hardwired number of tasks. + */ + result = dns_view_createresolver(view, taskmgr, 16, sockmgr, + timermgr, NULL); + if (result != ISC_R_SUCCESS) + goto out; + + result = ns_rootns_init(mctx); + if (result != ISC_R_SUCCESS) + goto out; + dns_view_sethints(view, rootdb); + + dns_view_freeze(view); + + dns_db_detach(&rootdb); + + return (ISC_R_SUCCESS); + +out: + if (view != NULL) + dns_view_detach(&view); + + dns_db_detach(&rootdb); + + return (result); +} + int main(int argc, char **argv) { isc_mem_t *mem; - isc_taskmgr_t *taskmgr; - isc_socketmgr_t *sockmgr; isc_socket_t *sock; isc_sockaddr_t localhost; struct in_addr lh_addr; @@ -63,7 +202,10 @@ main(int argc, char **argv) UNUSED(argc); UNUSED(argv); - isc_app_start(); + dns_result_register(); + + result = isc_app_start(); + INSIST(result == ISC_R_SUCCESS); mem = NULL; result = isc_mem_create(0, 0, &mem); @@ -86,6 +228,21 @@ main(int argc, char **argv) result = isc_socketmgr_create(mem, &sockmgr); INSIST(result == ISC_R_SUCCESS); + /* + * Create a timer manager. + */ + timermgr = NULL; + result = isc_timermgr_create(mem, &timermgr); + INSIST(result == ISC_R_SUCCESS); + + /* + * Initialize the DNS bits. Start by loading our built-in + * root hints. This should come from a file, eventually. + * XXXMLG + */ + result = create_view(mem); + INSIST(result == ISC_R_SUCCESS); + /* * We'll need a socket. It will be a UDP socket, and bound to * 127.0.0.1 port LWRES_UDP_PORT. @@ -135,6 +292,7 @@ main(int argc, char **argv) client[j].clientmgr = &cmgr[j]; ISC_LINK_INIT(&client[j], link); ISC_LIST_APPEND(cmgr[j].idle, &client[j], link); + client[j].isidle = ISC_TRUE; } } INSIST(i > 0); @@ -165,6 +323,11 @@ main(int argc, char **argv) printf("Sending shutdown events to task %p\n", cmgr[j].task); } + /* + * Kill off the view. + */ + dns_view_detach(&view); + /* * Wait for the tasks to all die. */ @@ -179,6 +342,8 @@ main(int argc, char **argv) isc_socket_detach(&sock); isc_socketmgr_destroy(&sockmgr); + isc_timermgr_destroy(&timermgr); + /* * Free up memory allocated. This is somewhat magical. We allocated * the client_t's in blocks, but the first task always has the @@ -198,6 +363,11 @@ main(int argc, char **argv) isc_mem_put(mem, cmgr, sizeof(clientmgr_t) * NTASKS); cmgr = NULL; + /* + * Clean up hints database. + */ + + /* * Kill the memory system. */