BIND 10 exp/res-research, updated. 427a96f872e569fa6e8644351f4c887fe7df0f27 [res-research] implemented a simple query forwarder

BIND 10 source code commits bind10-changes at lists.isc.org
Thu Jun 28 20:42:16 UTC 2012


The branch, exp/res-research has been updated
       via  427a96f872e569fa6e8644351f4c887fe7df0f27 (commit)
      from  9126fa8f3d20cdd59c2fa944aa9714e663ec4ab2 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 427a96f872e569fa6e8644351f4c887fe7df0f27
Author: JINMEI Tatuya <jinmei at isc.org>
Date:   Thu Jun 28 13:41:51 2012 -0700

    [res-research] implemented a simple query forwarder

-----------------------------------------------------------------------

Summary of changes:
 exp/res-research/benchmark/Makefile.am         |    3 +-
 exp/res-research/benchmark/simple_forwarder.cc |  212 ++++++++++++++++++++++++
 exp/res-research/benchmark/simple_responder.cc |    1 -
 3 files changed, 214 insertions(+), 2 deletions(-)
 create mode 100644 exp/res-research/benchmark/simple_forwarder.cc

-----------------------------------------------------------------------
diff --git a/exp/res-research/benchmark/Makefile.am b/exp/res-research/benchmark/Makefile.am
index a56d056..96d54ae 100644
--- a/exp/res-research/benchmark/Makefile.am
+++ b/exp/res-research/benchmark/Makefile.am
@@ -8,7 +8,8 @@ endif
 
 CLEANFILES = *.gcno *.gcda
 
-noinst_PROGRAMS = simple_receiver simple_responder
+noinst_PROGRAMS = simple_receiver simple_responder simple_forwarder
 
 simple_receiver_SOURCES = simple_receiver.cc
 simple_responder_SOURCES = simple_responder.cc
+simple_forwarder_SOURCES = simple_forwarder.cc
diff --git a/exp/res-research/benchmark/simple_forwarder.cc b/exp/res-research/benchmark/simple_forwarder.cc
new file mode 100644
index 0000000..9630e2b
--- /dev/null
+++ b/exp/res-research/benchmark/simple_forwarder.cc
@@ -0,0 +1,212 @@
+// Copyright (C) 2012  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.
+
+#include <util/io/sockaddr_util.h>
+
+#include <iostream>
+
+#include <cassert>
+#include <cstdlib>
+#include <csignal>
+#include <cstdio>
+#include <cstring>
+#include <unistd.h>
+
+#include <sys/select.h>
+#include <sys/errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+using namespace std;
+using namespace isc::util::io::internal;
+
+namespace {
+unsigned long recv_count = 0;
+unsigned long resp_count = 0;
+
+void
+sigterm_handler(int) {
+    cout << recv_count << " packets received, " << resp_count
+         << " responded" << endl;
+    exit(0);
+}
+
+void
+usage() {
+    cout << "usage: simple_forwarder [-p port] [-P fwd_port] [-s size] [-S addr]\n";
+    cout << "       -p port: specifies the receiving port (default 5300)\n";
+    cout << "       -s size: specifies the size of responses (default 512)\n";
+    cout << "       -P port: specifies the remote port for forwarding "
+        "(default 5301)\n";
+    cout << "       -S addr: specifies the remote address for forwarding "
+        "(default 127.0.0.1)\n";
+}
+}
+
+int
+main(int argc, char** argv) {
+    int ch;
+    const char* recvport = "5300";
+    const char* fwdport = "5301";
+    const char* fwdaddr = "127.0.0.1";
+    size_t resp_size = 512;
+    while ((ch = getopt(argc, argv, "hp:P:s:S:")) != -1) {
+        switch (ch) {
+        case 'p':
+            recvport = optarg;
+            break;
+        case 'P':
+            fwdport = optarg;
+            break;
+        case 's':
+            resp_size = atoi(optarg);
+            break;
+        case 'S':
+            fwdaddr = optarg;
+            break;
+        case 'h':
+            usage();
+            break;
+        }
+    }
+
+    argc -= optind;
+    argv += optind;
+    if (argc != 0) {
+        usage();
+    }
+
+    struct addrinfo hints;
+    struct addrinfo* res;
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = AF_INET;
+    hints.ai_socktype = SOCK_DGRAM;
+    hints.ai_protocol = IPPROTO_UDP;
+    hints.ai_flags = AI_NUMERICSERV | AI_PASSIVE;
+    const int error = getaddrinfo(NULL, recvport, &hints, &res);
+    if (error != 0) {
+        cerr << "getaddrinfo failed: " << gai_strerror(error) << endl;
+        return (1);
+    }
+    const int s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+    if (s < 0) {
+        cout << "socket failed " << strerror(errno) << endl;
+        return (1);
+    }
+    if (bind(s, res->ai_addr, res->ai_addrlen) != 0) {
+        cout << "bind failed " << strerror(errno) << endl;
+        return (1);
+    }
+    freeaddrinfo(res);
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = SOCK_DGRAM;
+    hints.ai_protocol = IPPROTO_UDP;
+    hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
+    const int error2 = getaddrinfo(fwdaddr, fwdport, &hints, &res);
+    if (error2 != 0) {
+        cerr << "getaddrinfo failed for forward addr/port: "
+             << gai_strerror(error) << endl;
+        return (1);
+    }
+    const int s_fwd = socket(res->ai_family, res->ai_socktype,
+                             res->ai_protocol);
+    if (s_fwd < 0) {
+        cout << "socket failed " << strerror(errno) << endl;
+        return (1);
+    }
+    if (bind(s_fwd, res->ai_addr, res->ai_addrlen) != 0) {
+        cout << "bind failed " << strerror(errno) << endl;
+        return (1);
+    }
+    struct sockaddr_storage fwd_ss;
+    memcpy(&fwd_ss, res->ai_addr, res->ai_addrlen);
+    const socklen_t fwd_salen = res->ai_addrlen;
+    freeaddrinfo(res);
+
+    signal(SIGTERM, sigterm_handler);
+    signal(SIGINT, sigterm_handler);
+
+    struct sockaddr_storage from_ss;
+    struct sockaddr_storage from_fwd_ss;
+    uint8_t recvbuf[4096];
+    assert(sizeof(recvbuf) >= resp_size);
+
+    fd_set fdset_base;
+    FD_ZERO(&fdset_base);
+    FD_SET(s, &fdset_base);
+    FD_SET(s_fwd, &fdset_base);
+    const int max_fd = std::max(s, s_fwd);
+    while (true) {
+        fd_set fdset = fdset_base;
+        const int n = select(max_fd + 1, &fdset, NULL, NULL, NULL);
+        if (n == -1) {
+            cout << "select failed " << strerror(errno) << endl;
+            return (1);
+        }
+
+        struct sockaddr* from = convertSockAddr(&from_ss);
+        socklen_t fromlen = sizeof(from_ss);
+        struct sockaddr* from_fwd = convertSockAddr(&from_fwd_ss);
+        socklen_t fromfwd_len = sizeof(from_fwd_ss);
+
+        if (FD_ISSET(s_fwd, &fdset)) {
+            // If we get a response from the "remote server", send it back
+            // to the client
+            int cc = recvfrom(s_fwd, recvbuf, sizeof(recvbuf), 0,
+                              from_fwd, &fromfwd_len);
+            if (cc <= 0) {
+                cout << "unexpected empty result on recvfrom" << endl;
+                return (1);
+            }
+            cc = sendto(s, recvbuf, resp_size, 0, from, fromlen);
+            if (cc < 0 || cc != resp_size) {
+                cout << "unexpected result on sendto" << endl;
+                return (1);
+            }
+            ++resp_count;
+        }
+
+        // This is a "normal query" from a client
+        if (FD_ISSET(s, &fdset)) {
+            int cc = recvfrom(s, recvbuf, sizeof(recvbuf), 0,
+                              from, &fromlen);
+            if (cc <= 0) {
+                cout << "unexpected empty result on recvfrom" << endl;
+                return (1);
+            }
+            ++recv_count;
+
+            // emulating "90% cache hit": 10% of queries are forwarded, and
+            // the rest are responded immediately.
+            if ((recv_count % 10) == 9) {
+                cc = sendto(s, recvbuf, cc, 0, convertSockAddr(&fwd_ss),
+                            fwd_salen);
+                if (cc < 0) {
+                    cout << "unexpected result on sendto for forward" << endl;
+                    return (1);
+                }
+            } else {
+                cc = sendto(s, recvbuf, resp_size, 0, from, fromlen);
+                if (cc < 0 || cc != resp_size) {
+                    cout << "unexpected result on sendto" << endl;
+                    return (1);
+                }
+            }
+        }
+    }
+    return (0);
+}
diff --git a/exp/res-research/benchmark/simple_responder.cc b/exp/res-research/benchmark/simple_responder.cc
index b64b864..1a5ada4 100644
--- a/exp/res-research/benchmark/simple_responder.cc
+++ b/exp/res-research/benchmark/simple_responder.cc
@@ -21,7 +21,6 @@
 #include <cstring>
 #include <unistd.h>
 
-#include <sys/select.h>
 #include <sys/errno.h>
 #include <sys/types.h>
 #include <sys/socket.h>



More information about the bind10-changes mailing list