Commit 392839e6 authored by Evan Hunt's avatar Evan Hunt
Browse files

- move parkinglot class to its own files

- add select loop


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/f2f200910@255 e5f2f494-b856-4b98-b285-d166d9295462
parent 335e2a12
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_srcdir)/ext
bin_PROGRAMS = parkinglot
parkinglot_SOURCES = common.cc main.cc zoneset.h
parkinglot_SOURCES = common.cc common.h main.cc zoneset.h parkinglot.cc parkinglot.h
parkinglot_LDADD = $(top_srcdir)/src/lib/dns/libdns.a $(top_srcdir)/src/lib/cc/cpp/libcc.a
......@@ -14,6 +14,9 @@
// $Id$
#ifndef __COMMON_H
#define __COMMON_H 1
#include <stdlib.h>
class FatalError : public std::exception {
......@@ -28,3 +31,9 @@ class FatalError : public std::exception {
private:
std::string msg;
};
#endif // __COMMON_H
// Local Variables:
// mode: c++
// End:
......@@ -16,6 +16,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netdb.h>
#include <stdlib.h>
......@@ -27,157 +28,18 @@
#include <dns/rrset.h>
#include <dns/message.h>
#include "common.h"
#include <cc/cpp/session.h>
#include "zoneset.h"
#include "parkinglot.h"
using namespace std;
#include "common.h"
using namespace isc::dns;
using namespace isc::dns::Rdata::IN;
using namespace isc::dns::Rdata::Generic;
using namespace std;
const string PROGRAM = "parkinglot";
const int DNSPORT = 53;
class ParkingLot {
public:
explicit ParkingLot(int port);
virtual ~ParkingLot() {};
int getSocket() { return(sock); }
void processMessage();
private:
Rdata::RdataPtr ns1, ns2, ns3, a, aaaa, soa;
ZoneSet zones;
int sock;
};
static void init_zones(ZoneSet& zones) {
zones.serve("jinmei.org");
zones.serve("nuthaven.org");
zones.serve("isc.org");
zones.serve("sisotowbell.org");
zones.serve("flame.org");
}
ParkingLot::ParkingLot(int port) {
init_zones(zones);
ns1 = Rdata::RdataPtr(new NS("ns1.parking.com"));
ns2 = Rdata::RdataPtr(new NS("ns2.parking.com"));
ns3 = Rdata::RdataPtr(new NS("ns3.parking.com"));
a = Rdata::RdataPtr(new A("127.0.0.1"));
aaaa = Rdata::RdataPtr(new AAAA("::1"));
soa = Rdata::RdataPtr(new SOA("parking.com", "noc.parking.com",
1, 1800, 900, 604800, TTL(86400)));
int s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0)
throw FatalError("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);
#ifdef HAVE_SIN_LEN
sin.sin_len = sa_len;
#endif
if (bind(s, (struct sockaddr *)&sin, sa_len) < 0)
throw FatalError("could not bind socket");
sock = s;
}
void
ParkingLot::processMessage() {
Message msg;
struct sockaddr_storage ss;
socklen_t sa_len = sizeof(ss);
struct sockaddr* sa = static_cast<struct sockaddr*>((void*)&ss);
int s = sock;
Name authors_name("authors.bind");
if (msg.getBuffer().recvFrom(s, sa, &sa_len) > 0) {
try {
msg.fromWire();
} catch (...) {
cerr << "parse failed" << endl;
return;
}
cout << "received a message:\n" << msg.toText() << endl;
if (msg.getSection(SECTION_QUESTION).size() != 1)
return;
msg.makeResponse();
msg.setAA(true);
RRsetPtr query = msg.getSection(SECTION_QUESTION)[0];
string name = query->getName().toText(true);
if (query->getName() == authors_name &&
query->getClass() == RRClass::CH,
query->getType() == RRType::TXT) {
msg.setRcode(Message::RCODE_NOERROR);
msg.addRR(SECTION_ANSWER, RR(authors_name, RRClass::CH,
RRType::TXT, TTL(0),
TXT("JINMEI Tatuya")));
msg.addRR(SECTION_ANSWER, RR(authors_name, RRClass::CH,
RRType::TXT, TTL(0),
TXT("Evan Hunt")));
msg.addRR(SECTION_ANSWER, RR(authors_name, RRClass::CH,
RRType::TXT, TTL(0),
TXT("Jeremy C. Reed")));
msg.addRR(SECTION_ANSWER, RR(authors_name, RRClass::CH,
RRType::TXT, TTL(0),
TXT("Jelte Jansen")));
// add others name here!!
msg.addRR(SECTION_AUTHORITY, RR(authors_name, RRClass::CH,
RRType::NS, TTL(0),
NS("authors.bind")));
} else if (zones.contains(name)) {
msg.setRcode(Message::RCODE_NOERROR);
RRset* nsset = new RRset(query->getName(), RRClass::IN,
RRType::NS, TTL(3600));
nsset->addRdata(ns1);
nsset->addRdata(ns2);
nsset->addRdata(ns3);
if (query->getType() == RRType::NS)
msg.addRRset(SECTION_ANSWER, RRsetPtr(nsset));
else if (query->getType() == RRType::A) {
msg.addRRset(SECTION_AUTHORITY, RRsetPtr(nsset));
RR arr(query->getName(), RRClass::IN, RRType::A, TTL(3600), a);
msg.addRR(SECTION_ANSWER, arr);
} else if (query->getType() == RRType::AAAA) {
msg.addRRset(SECTION_AUTHORITY, RRsetPtr(nsset));
RR aaaarr(query->getName(), RRClass::IN, RRType::AAAA,
TTL(3600), aaaa);
msg.addRR(SECTION_ANSWER, aaaarr);
} else {
RR soarr(query->getName(), RRClass::IN, RRType::SOA,
TTL(3600), soa);
msg.addRR(SECTION_AUTHORITY, soarr);
}
} else {
msg.setRcode(Message::RCODE_NXDOMAIN);
}
msg.toWire();
cout << "sending a response (" <<
boost::lexical_cast<string>(msg.getBuffer().getSize())
<< " bytes):\n" << msg.toText() << endl;
msg.getBuffer().sendTo(s, *sa, sa_len);
}
}
static void
usage() {
cerr << "Usage: parkinglot [-p port]" << endl;
......@@ -186,7 +48,6 @@ usage() {
int
main(int argc, char* argv[]) {
Message msg;
int ch;
int port = DNSPORT;
......@@ -208,14 +69,29 @@ main(int argc, char* argv[]) {
ParkingLot plot(port);
// initialize command channel
// ISC::CC::Session session;
// session.establish();
// session.subscribe("parkinglot");
ISC::CC::Session session;
session.establish();
session.subscribe("parkinglot");
// main server loop
fd_set fds;
int ps = plot.getSocket();
int ss = session.getSocket();
int nfds = max(ps, ss) + 1;
FD_ZERO(&fds);
FD_SET(ps, &fds);
FD_SET(ss, &fds);
cout << "server running" << endl;
while (true)
plot.processMessage();
while (true) {
int n = select(nfds, &fds, NULL, NULL, NULL);
if (n < 0)
throw FatalError("select error");
if (n != 0 && FD_ISSET(ps, &fds))
plot.processMessage();
}
return (0);
}
// 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 <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netdb.h>
#include <stdlib.h>
#include <set>
#include <iostream>
#include <dns/buffer.h>
#include <dns/name.h>
#include <dns/rrset.h>
#include <dns/message.h>
#include "common.h"
#include "parkinglot.h"
using namespace std;
using namespace isc::dns;
using namespace isc::dns::Rdata::IN;
using namespace isc::dns::Rdata::Generic;
static void init_zones(ZoneSet& zones) {
zones.serve("jinmei.org");
zones.serve("nuthaven.org");
zones.serve("isc.org");
zones.serve("sisotowbell.org");
zones.serve("flame.org");
}
ParkingLot::ParkingLot(int port) {
init_zones(zones);
ns1 = Rdata::RdataPtr(new NS("ns1.parking.com"));
ns2 = Rdata::RdataPtr(new NS("ns2.parking.com"));
ns3 = Rdata::RdataPtr(new NS("ns3.parking.com"));
a = Rdata::RdataPtr(new A("127.0.0.1"));
aaaa = Rdata::RdataPtr(new AAAA("::1"));
soa = Rdata::RdataPtr(new SOA("parking.com", "noc.parking.com",
1, 1800, 900, 604800, TTL(86400)));
int s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s < 0)
throw FatalError("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);
#ifdef HAVE_SIN_LEN
sin.sin_len = sa_len;
#endif
if (bind(s, (struct sockaddr *)&sin, sa_len) < 0)
throw FatalError("could not bind socket");
sock = s;
}
void
ParkingLot::processMessage() {
Name authors_name("authors.bind");
struct sockaddr_storage ss;
socklen_t sa_len = sizeof(ss);
struct sockaddr* sa = static_cast<struct sockaddr*>((void*)&ss);
int s = sock;
Message msg;
if (msg.getBuffer().recvFrom(s, sa, &sa_len) > 0) {
try {
msg.fromWire();
} catch (...) {
cerr << "parse failed" << endl;
return;
}
cout << "received a message:\n" << msg.toText() << endl;
if (msg.getSection(SECTION_QUESTION).size() != 1)
return;
msg.makeResponse();
msg.setAA(true);
RRsetPtr query = msg.getSection(SECTION_QUESTION)[0];
string name = query->getName().toText(true);
if (query->getName() == authors_name &&
query->getClass() == RRClass::CH,
query->getType() == RRType::TXT) {
msg.setRcode(Message::RCODE_NOERROR);
msg.addRR(SECTION_ANSWER, RR(authors_name, RRClass::CH,
RRType::TXT, TTL(0),
TXT("JINMEI Tatuya")));
msg.addRR(SECTION_ANSWER, RR(authors_name, RRClass::CH,
RRType::TXT, TTL(0),
TXT("Evan Hunt")));
// add others name here!!
msg.addRR(SECTION_AUTHORITY, RR(authors_name, RRClass::CH,
RRType::NS, TTL(0),
NS("authors.bind")));
} else if (zones.contains(name)) {
msg.setRcode(Message::RCODE_NOERROR);
RRset* nsset = new RRset(query->getName(), RRClass::IN,
RRType::NS, TTL(3600));
nsset->addRdata(ns1);
nsset->addRdata(ns2);
nsset->addRdata(ns3);
if (query->getType() == RRType::NS)
msg.addRRset(SECTION_ANSWER, RRsetPtr(nsset));
else if (query->getType() == RRType::A) {
msg.addRRset(SECTION_AUTHORITY, RRsetPtr(nsset));
RR arr(query->getName(), RRClass::IN, RRType::A, TTL(3600), a);
msg.addRR(SECTION_ANSWER, arr);
} else if (query->getType() == RRType::AAAA) {
msg.addRRset(SECTION_AUTHORITY, RRsetPtr(nsset));
RR aaaarr(query->getName(), RRClass::IN, RRType::AAAA,
TTL(3600), aaaa);
msg.addRR(SECTION_ANSWER, aaaarr);
} else {
RR soarr(query->getName(), RRClass::IN, RRType::SOA,
TTL(3600), soa);
msg.addRR(SECTION_AUTHORITY, soarr);
}
} else {
msg.setRcode(Message::RCODE_NXDOMAIN);
}
msg.toWire();
cout << "sending a response (" <<
boost::lexical_cast<string>(msg.getBuffer().getSize())
<< " bytes):\n" << msg.toText() << endl;
msg.getBuffer().sendTo(s, *sa, sa_len);
}
}
// 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$
#ifndef __PARKINGLOT_H
#define __PARKINGLOT_H 1
#include "zoneset.h"
class ParkingLot {
public:
explicit ParkingLot(int port);
virtual ~ParkingLot() {};
int getSocket() { return(sock); }
void processMessage();
private:
isc::dns::Rdata::RdataPtr ns1, ns2, ns3, a, aaaa, soa;
ZoneSet zones;
int sock;
};
#endif // __PARKINGLOT_H
// Local Variables:
// mode: c++
// End:
......@@ -14,8 +14,10 @@
// $Id$
#ifndef __ZONELIST_H
#define __ZONELIST_H 1
#ifndef __ZONESET_H
#define __ZONESET_H 1
#include <set>
class ZoneSet : std::set<std::string> {
public:
......@@ -25,7 +27,7 @@ class ZoneSet : std::set<std::string> {
}
};
#endif // __ZONELIST_H
#endif // __ZONESET_H
// Local Variables:
// mode: c++
......
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