Commit b5ac8153 authored by Evan Hunt's avatar Evan Hunt
Browse files

modularizing


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/f2f200910@171 e5f2f494-b856-4b98-b285-d166d9295462
parent 1e70a814
AM_CPPFLAGS = -I$(top_srcdir)/src/lib
bin_PROGRAMS = parkinglot
parkinglot_SOURCES = main.cc
parkinglot_SOURCES = common.cc main.cc
parkinglot_LDADD = $(top_srcdir)/src/lib/dns/libdns.a
// Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// $Id$
#include <iostream>
#include "common.h"
extern const std::string PROGRAM;
void
fatal(const char* format, ...) {
va_list args;
fprintf(stderr, "%s: fatal: ", PROGRAM);
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
putc('\n', stderr);
exit(1);
}
// Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// $Id$
void
fatal(const char* format, ...);
......@@ -26,51 +26,68 @@
#include <dns/rrset.h>
#include <dns/message.h>
#include "common.h"
using std::string;
using std::pair;
using isc::dns::RRset;
using isc::dns::Name;
using isc::dns::TTL;
using isc::dns::RRsetPtr;
using isc::dns::RRType;
using isc::dns::RRClass;
using isc::dns::Message;
using namespace isc::dns;
using isc::dns::Rdata::IN::A;
using isc::dns::Rdata::IN::AAAA;
using isc::dns::Rdata::Generic::NS;
const string PROGRAM = "parkinglot";
const int DNSPORT = 53;
static void
start_server(int s, const struct addrinfo *res)
{
if (bind(s, res->ai_addr, res->ai_addrlen) < 0)
return;
// Create Database
typedef pair<string, string> dnskey_t;
std::map<dnskey_t, std::string> dnsdb;
dnsdb.insert(pair<dnskey_t, string>(dnskey_t("www.jinmei.org", "A"),
"149.20.54.162"));
dnsdb.insert(pair<dnskey_t, string>(dnskey_t("www.jinmei.org", "AAAA"),
"2001:4f8:3:36::162"));
dnsdb.insert(pair<dnskey_t, string>(dnskey_t("www.isc.org", "A"),
"149.20.64.42"));
dnsdb.insert(pair<dnskey_t, string>(dnskey_t("www.isc.org", "AAAA"),
"2001:4f8:0:2::d"));
dnsdb.insert(pair<dnskey_t, string>(dnskey_t("isc.org", "NS"),
"sfba.sns-pb.isc.org."));
int cc;
struct sockaddr_storage ss;
struct sockaddr* sa;
socklen_t sa_len;
while (1) {
Message msg;
usage() {
std::cerr << "Usage: parkinglot [-p port]" << std::endl;
exit(1);
}
typedef pair<string, string> Key;
typedef pair<Key, string> Record;
typedef std::map<Key, string> DnsDB;
DnsDB dnsdb;
static void
init_db() {
// populate database
dnsdb.insert(Record(Key("www.jinmei.org", "A"), "149.20.54.162"));
dnsdb.insert(Record(Key("www.jinmei.org", "AAAA"), "2001:4f8:3:36::162"));
dnsdb.insert(Record(Key("www.isc.org", "A"), "149.20.64.42"));
dnsdb.insert(Record(Key("www.isc.org", "AAAA"), "2001:4f8:0:2::d"));
dnsdb.insert(Record(Key("isc.org", "NS"), "sfba.sns-pb.isc.org."));
}
sa_len = sizeof(ss);
sa = static_cast<struct sockaddr*>((void*)&ss);
cc = msg.getBuffer().recvFrom(s, sa, &sa_len);
static int
start_server(int port) {
int s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0)
fatal("failed to open socket");
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(port);
socklen_t sa_len = sizeof(sin);
struct sockaddr* sa = static_cast<struct sockaddr*>((void*)&sin);
if (bind(s, sa, sa_len) < 0)
return (-1);
return (s);
}
static void
run_server(int s) {
while (true) {
Message msg;
struct sockaddr_storage ss;
socklen_t sa_len = sizeof(ss);
struct sockaddr* sa = static_cast<struct sockaddr*>((void*)&ss);
int cc = msg.getBuffer().recvFrom(s, sa, &sa_len);
if (cc > 0) {
try {
msg.fromWire();
......@@ -87,19 +104,19 @@ start_server(int s, const struct addrinfo *res)
msg.setAA(true);
RRsetPtr query = msg.getSection(isc::dns::SECTION_QUESTION)[0];
std::map<dnskey_t, string>::const_iterator it;
isc::dns::Rdata::RDATAPTR rdatap;
DnsDB::const_iterator it;
isc::dns::Rdata::RdataPtr rdatap;
it = dnsdb.find(dnskey_t(query->getName().toText(true),
query->getType().toText()));
it = dnsdb.find(Key(query->getName().toText(true),
query->getType().toText()));
if (it != dnsdb.end()) {
// XXX: this code logic is NOT clean. should revisit API.
if (query->getType() == RRType::A) {
rdatap = isc::dns::Rdata::RDATAPTR(new A(it->second));
rdatap = isc::dns::Rdata::RdataPtr(new A(it->second));
} else if (query->getType() == RRType::AAAA) {
rdatap = isc::dns::Rdata::RDATAPTR(new AAAA(it->second));
rdatap = isc::dns::Rdata::RdataPtr(new AAAA(it->second));
} else if (query->getType() == RRType::NS) {
rdatap = isc::dns::Rdata::RDATAPTR(new NS(it->second));
rdatap = isc::dns::Rdata::RdataPtr(new NS(it->second));
}
msg.setRcode(Message::RCODE_NOERROR);
......@@ -107,7 +124,7 @@ start_server(int s, const struct addrinfo *res)
RRset* rrset = new RRset(query->getName(), query->getClass(),
query->getType(), TTL(3600));
rrset->addRdata(rdatap);
msg.addRrset(isc::dns::SECTION_ANSWER, RRsetPtr(rrset));
msg.addRRset(isc::dns::SECTION_ANSWER, RRsetPtr(rrset));
} else {
msg.setRcode(Message::RCODE_NXDOMAIN);
// should add SOA to the authority section, but not implemented.
......@@ -127,88 +144,31 @@ main(int argc, char* argv[])
{
Message msg;
int ch;
const char* server_address = "127.0.0.1";
const char* type_name = "A";
const char* port = "53";
bool receive_mode = false;
int port = DNSPORT;
bool err = false;
while ((ch = getopt(argc, argv, "p:rs:t:")) != -1) {
while ((ch = getopt(argc, argv, "p:")) != -1) {
switch (ch) {
case 'p':
port = optarg;
break;
case 'r':
receive_mode = true;
break;
case 's':
server_address = optarg;
break;
case 't':
type_name = optarg;
port = atoi(optarg);
break;
case '?':
default:
err = true;
}
}
argc -= optind;
argv += optind;
if (err || (argc - optind) > 0)
usage();
if (argc < 1 && !receive_mode) {
std::cerr << "usage: "
"dnsmessage-test [-s server_address] [-t qtype] qname\n"
<< std::endl;
return (1);
}
struct addrinfo hints, *res;
int e;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = receive_mode ? AI_PASSIVE : 0;
e = getaddrinfo(server_address, port, &hints, &res);
if (e != 0) {
std::cerr << "getaddrinfo failed: " << gai_strerror(e) << std::endl;
return (1);
}
int s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (s < 0) {
std::cerr << "failed to open socket" << std::endl;
return (1);
}
// initialize DNS database
init_db();
if (receive_mode) {
start_server(s, res);
} else {
msg.setQid(42); // can be omitted, then QID will be 0
msg.setRD(true);
msg.addQuestion(Name(argv[0]), RRClass::IN, RRType(type_name));
msg.toWire();
std::cout << "sending a query (" <<
boost::lexical_cast<string>(msg.getBuffer().getSize())
<< " bytes):\n" << msg.toText() << std::endl;
msg.getBuffer().sendTo(s, *res->ai_addr, res->ai_addrlen);
Message rmsg;
struct sockaddr_storage ss;
struct sockaddr* sa;
socklen_t sa_len;
sa_len = sizeof(ss);
sa = static_cast<struct sockaddr*>((void*)&ss);
if (rmsg.getBuffer().recvFrom(s, sa, &sa_len) > 0) {
try {
rmsg.fromWire();
std::cout << "received a response (" <<
boost::lexical_cast<string>(rmsg.getBuffer().getSize())
<< " bytes):\n" << rmsg.toText() << std::endl;
} catch (...) {
std::cerr << "parse failed" << std::endl;
}
}
}
// start the server
int s = start_server(port);
freeaddrinfo(res);
// main server loop
run_server(s);
return (0);
}
Supports Markdown
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