[svn] commit: r1204 - in /branches/jelte-tcp: ./ src/bin/auth/auth_srv.cc src/bin/auth/auth_srv.h src/bin/auth/main.cc

BIND 10 source code commits bind10-changes at lists.isc.org
Mon Mar 8 14:50:44 UTC 2010


Author: jelte
Date: Mon Mar  8 14:50:43 2010
New Revision: 1204

Log:
basic 'lowlevel' tcp support
(there's also the asio solution from jinmei, but i had made this on the train this weekend, once we decide on which version to use we'll remove the other one)

Added:
    branches/jelte-tcp/
      - copied from r1203, trunk/
Modified:
    branches/jelte-tcp/src/bin/auth/auth_srv.cc
    branches/jelte-tcp/src/bin/auth/auth_srv.h
    branches/jelte-tcp/src/bin/auth/main.cc

Modified: branches/jelte-tcp/src/bin/auth/auth_srv.cc
==============================================================================
--- branches/jelte-tcp/src/bin/auth/auth_srv.cc (original)
+++ branches/jelte-tcp/src/bin/auth/auth_srv.cc Mon Mar  8 14:50:43 2010
@@ -17,6 +17,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/select.h>
+#include <arpa/inet.h>
 #include <netinet/in.h>
 #include <netdb.h>
 #include <stdlib.h>
@@ -86,7 +87,7 @@
 }
 
 void
-AuthSrv::processMessage(const int fd)
+AuthSrv::processMessageUDP(const int fd)
 {
     struct sockaddr_storage ss;
     socklen_t sa_len = sizeof(ss);
@@ -134,6 +135,84 @@
     }
 }
 
+void
+AuthSrv::processMessageTCP(const int fd)
+{
+    struct sockaddr_storage ss;
+    socklen_t sa_len = sizeof(ss);
+    struct sockaddr* sa = static_cast<struct sockaddr*>((void*)&ss);
+    char sizebuf[2];
+    char* recvbuf;
+    int cc;
+    int ts = accept(fd, sa, &sa_len);
+
+    cout << "[XX] process TCP" << endl;
+    cc = recv(ts, sizebuf, 2, 0);
+    cout << "[XX] got: " << cc << endl;
+    uint16_t size, size_n;
+    memcpy(&size_n, sizebuf, 2);
+    size = ntohs(size_n);
+    cout << "[XX] got: " << size << endl;
+
+    recvbuf = (char*) malloc(size);
+    cc = 0;
+    while (cc < size) {
+        cout << "[XX] cc now: " << cc << " of " << size << endl;
+        cc += recv(ts, recvbuf + cc, size - cc, 0);
+    }
+    Message msg(Message::PARSE);
+    InputBuffer buffer(recvbuf, cc);
+
+    //free(recvbuf);
+
+    try {
+        msg.fromWire(buffer);
+    } catch (...) {
+        cerr << "[AuthSrv] parse failed" << endl;
+        return;
+    }
+
+    cout << "[AuthSrv] received a message:\n" << msg.toText() << endl;
+
+    if (msg.getRRCount(Section::QUESTION()) != 1) {
+        return;
+    }
+
+    bool dnssec_ok = msg.isDNSSECSupported();
+
+    msg.makeResponse();
+    msg.setHeaderFlag(MessageFlag::AA());
+    msg.setRcode(Rcode::NOERROR());
+    msg.setDNSSECSupported(dnssec_ok);
+    msg.setUDPSize(4096);
+
+    Query query(msg, dnssec_ok);
+    impl_->data_sources.doQuery(query);
+
+    OutputBuffer obuffer(4096);
+    MessageRenderer renderer(obuffer);
+    msg.toWire(renderer);
+    cout << "sending a response (" <<
+        boost::lexical_cast<string>(obuffer.getLength())
+              << " bytes):\n" << msg.toText() << endl;
+    size = obuffer.getLength();
+    size_n = htons(size);
+    if (send(ts, &size_n, 2, 0) == 2) {
+        int sent = 0;
+        while (sent < obuffer.getLength()) {
+            cc = send(ts, obuffer.getData(), obuffer.getLength(), 0);
+            if (cc == -1) {
+                cerr << "[AuthSrv] error in sending TCP response message" << endl;
+            }
+            sent += cc;
+        }
+        // TODO: we don't check for more queries on the stream atm
+        close(ts);
+    } else {
+        cerr << "[AuthSrv] error in sending TCP response message size" << endl;
+    }
+}
+
 ElementPtr
 AuthSrv::setDbFile(const isc::data::ElementPtr config)
 {

Modified: branches/jelte-tcp/src/bin/auth/auth_srv.h
==============================================================================
--- branches/jelte-tcp/src/bin/auth/auth_srv.h (original)
+++ branches/jelte-tcp/src/bin/auth/auth_srv.h Mon Mar  8 14:50:43 2010
@@ -38,7 +38,8 @@
     explicit AuthSrv();
     ~AuthSrv();
     //@}
-    void processMessage(int fd);
+    void processMessageUDP(int fd);
+    void processMessageTCP(int fd);
     void serve(std::string zone_name);
     isc::data::ElementPtr setDbFile(const isc::data::ElementPtr config);
     isc::data::ElementPtr updateConfig(isc::data::ElementPtr config);

Modified: branches/jelte-tcp/src/bin/auth/main.cc
==============================================================================
--- branches/jelte-tcp/src/bin/auth/main.cc (original)
+++ branches/jelte-tcp/src/bin/auth/main.cc Mon Mar  8 14:50:43 2010
@@ -84,7 +84,7 @@
 }
 
 static int
-getSocket(int af, const char* port) {
+getUDPSocket(int af, const char* port) {
     struct addrinfo hints, *res;
 
     memset(&hints, 0, sizeof(hints));
@@ -121,12 +121,63 @@
     return (s);
 }
 
+static int
+getTCPSocket(int af, const char* port) {
+    struct addrinfo hints, *res;
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = af;
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_flags = AI_PASSIVE;
+    hints.ai_protocol = IPPROTO_TCP;
+
+    int error = getaddrinfo(NULL, port, &hints, &res);
+    if (error != 0) {
+        cerr << "getaddrinfo failed: " << gai_strerror(error);
+        return (-1);
+    }
+
+    int s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+    if (s < 0) {
+        cerr << "failed to open socket" << endl;
+        return (-1);
+    }
+
+    int on = 1;
+    if (af == AF_INET6) {
+        if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) {
+            cerr << "couldn't set IPV6_V6ONLY socket option" << endl;
+        }
+    }
+
+    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
+        cerr << "couldn't set SO_REUSEADDR socket option" << endl;
+    }
+
+    if (bind(s, res->ai_addr, res->ai_addrlen) < 0) {
+        cerr << "binding socket failure" << endl;
+        close(s);
+        return (-1);
+    }
+
+    listen(s, 100);
+    return (s);
+}
+
+void
+closeSocket(int sock)
+{
+    if (sock != -1) {
+        close(sock);
+    }
+}
+
 int
 main(int argc, char* argv[]) {
     int ch;
     const char* port = DNSPORT;
     bool ipv4_only = false, ipv6_only = false;
-    int ps4 = -1, ps6 = -1;
+    int ups4 = -1, ups6 = -1, tps4 = -1, tps6 = -1;
 
     while ((ch = getopt(argc, argv, "46p:")) != -1) {
         switch (ch) {
@@ -154,17 +205,28 @@
         usage();
     }
     if (!ipv6_only) {
-        ps4 = getSocket(AF_INET, port);
-        if (ps4 < 0) {
+        ups4 = getUDPSocket(AF_INET, port);
+        if (ups4 < 0) {
             exit(1);
         }
+        tps4 = getTCPSocket(AF_INET, port);
+        if (tps4 < 0) {
+            closeSocket(ups4);
+            exit(1);
+        }
     }
     if (!ipv4_only) {
-        ps6 = getSocket(AF_INET6, port);
-        if (ps6 < 0) {
-            if (ps4 < 0) {
-                close(ps4);
-            }
+        ups6 = getUDPSocket(AF_INET6, port);
+        if (ups6 < 0) {
+            closeSocket(ups4);
+            closeSocket(ups6);
+            exit(1);
+        }
+        tps6 = getTCPSocket(AF_INET6, port);
+        if (tps6 < 0) {
+            closeSocket(ups4);
+            closeSocket(ups6);
+            closeSocket(tps4);
             exit(1);
         }
     }
@@ -187,17 +249,23 @@
         // main server loop
         fd_set fds;
         int ss = cs.getSocket();
-        int nfds = max(max(ps4, ps6), ss) + 1;
+        int nfds = max(max(max(max(ups4, ups6), tps4), tps6), ss) + 1;
         int counter = 0;
 
         cout << "Server started." << endl;
         while (true) {
             FD_ZERO(&fds);
-            if (ps4 >= 0) {
-                FD_SET(ps4, &fds);
-            }
-            if (ps6 >= 0) {
-                FD_SET(ps6, &fds);
+            if (ups4 >= 0) {
+                FD_SET(ups4, &fds);
+            }
+            if (ups6 >= 0) {
+                FD_SET(ups6, &fds);
+            }
+            if (tps4 >= 0) {
+                FD_SET(tps4, &fds);
+            }
+            if (tps6 >= 0) {
+                FD_SET(tps6, &fds);
             }
             FD_SET(ss, &fds);
 
@@ -206,13 +274,21 @@
                 throw FatalError("select error");
             }
 
-            if (ps4 >= 0 && FD_ISSET(ps4, &fds)) {
+            if (ups4 >= 0 && FD_ISSET(ups4, &fds)) {
                 ++counter;
-                auth_server->processMessage(ps4);
-            }
-            if (ps6 >= 0 && FD_ISSET(ps6, &fds)) {
+                auth_server->processMessageUDP(ups4);
+            }
+            if (ups6 >= 0 && FD_ISSET(ups6, &fds)) {
                 ++counter;
-                auth_server->processMessage(ps6);
+                auth_server->processMessageUDP(ups6);
+            }
+            if (tps4 >= 0 && FD_ISSET(tps4, &fds)) {
+                ++counter;
+                auth_server->processMessageTCP(tps4);
+            }
+            if (tps6 >= 0 && FD_ISSET(tps6, &fds)) {
+                ++counter;
+                auth_server->processMessageTCP(tps6);
             }
     
             if (FD_ISSET(ss, &fds)) {
@@ -224,11 +300,11 @@
         ret = 1;
     }
 
-    if (ps4 >= 0) {
-        close(ps4);
-    }
-    if (ps6 >= 0) {
-        close(ps6);
+    if (ups4 >= 0) {
+        close(ups4);
+    }
+    if (ups6 >= 0) {
+        close(ups6);
     }
     delete auth_server;
     return (ret);




More information about the bind10-changes mailing list