[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