|
@@ -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);
|
|
|
}
|