Browse Source

- 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

Evan Hunt 15 years ago
parent
commit
392839e604

+ 1 - 1
src/bin/parkinglot/Makefile.am

@@ -1,5 +1,5 @@
 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

+ 9 - 0
src/bin/parkinglot/common.h

@@ -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:

+ 26 - 150
src/bin/parkinglot/main.cc

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

+ 158 - 0
src/bin/parkinglot/parkinglot.cc

@@ -0,0 +1,158 @@
+// 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);
+    }
+}

+ 39 - 0
src/bin/parkinglot/parkinglot.h

@@ -0,0 +1,39 @@
+// 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:

+ 5 - 3
src/bin/parkinglot/zoneset.h

@@ -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++