ednssubnet.cc ednssubnet.hh \
dnsdist.cc \
dnsdist-carbon.cc \
+ dnsdist-console.cc \
dnsdist-ecs.cc dnsdist-ecs.hh \
dnsdist-lua.cc \
dnsdist-lua2.cc \
--- /dev/null
+#include "dnsdist.hh"
+#include "sodcrypto.hh"
+#include <readline/readline.h>
+#include <readline/history.h>
+#include <fstream>
+#include "dolog.hh"
+
+void doClient(ComboAddress server, const std::string& command)
+{
+ cout<<"Connecting to "<<server.toStringWithPort()<<endl;
+ int fd=socket(server.sin4.sin_family, SOCK_STREAM, 0);
+ SConnect(fd, server);
+
+ SodiumNonce theirs, ours;
+ ours.init();
+
+ writen2(fd, (const char*)ours.value, sizeof(ours.value));
+ readn2(fd, (char*)theirs.value, sizeof(theirs.value));
+
+ if(!command.empty()) {
+ string response;
+ string msg=sodEncryptSym(command, g_key, ours);
+ putMsgLen32(fd, msg.length());
+ if(!msg.empty())
+ writen2(fd, msg);
+ uint32_t len;
+ getMsgLen32(fd, &len);
+ boost::scoped_array<char> resp(new char[len]);
+ readn2(fd, resp.get(), len);
+ msg.assign(resp.get(), len);
+ msg=sodDecryptSym(msg, g_key, theirs);
+ cout<<msg<<endl;
+ return;
+ }
+
+ set<string> dupper;
+ {
+ ifstream history(".dnsdist_history");
+ string line;
+ while(getline(history, line))
+ add_history(line.c_str());
+ }
+ ofstream history(".dnsdist_history", std::ios_base::app);
+ string lastline;
+ for(;;) {
+ char* sline = readline("> ");
+ rl_bind_key('\t',rl_complete);
+ if(!sline)
+ break;
+
+ string line(sline);
+ if(!line.empty() && line != lastline) {
+ add_history(sline);
+ history << sline <<endl;
+ history.flush();
+ }
+ lastline=line;
+ free(sline);
+
+ if(line=="quit")
+ break;
+
+ string response;
+ string msg=sodEncryptSym(line, g_key, ours);
+ putMsgLen32(fd, msg.length());
+ writen2(fd, msg);
+ uint32_t len;
+ if(!getMsgLen32(fd, &len) || len == 0) {
+ cout << "Connection closed by the server." << endl;
+ break;
+ }
+
+ boost::scoped_array<char> resp(new char[len]);
+ readn2(fd, resp.get(), len);
+ msg.assign(resp.get(), len);
+ msg=sodDecryptSym(msg, g_key, theirs);
+ cout<<msg<<endl;
+ }
+}
+
+void doConsole()
+{
+ set<string> dupper;
+ {
+ ifstream history(".dnsdist_history");
+ string line;
+ while(getline(history, line))
+ add_history(line.c_str());
+ }
+ ofstream history(".dnsdist_history", std::ios_base::app);
+ string lastline;
+ for(;;) {
+ char* sline = readline("> ");
+ rl_bind_key('\t',rl_complete);
+ if(!sline)
+ break;
+
+ string line(sline);
+ if(!line.empty() && line != lastline) {
+ add_history(sline);
+ history << sline <<endl;
+ history.flush();
+ }
+ lastline=line;
+ free(sline);
+
+ if(line=="quit")
+ break;
+
+ string response;
+ try {
+ std::lock_guard<std::mutex> lock(g_luamutex);
+ g_outputBuffer.clear();
+ auto ret=g_lua.executeCode<
+ boost::optional<
+ boost::variant<
+ string,
+ shared_ptr<DownstreamState>
+ >
+ >
+ >(line);
+
+ if(ret) {
+ if (const auto strValue = boost::get<shared_ptr<DownstreamState>>(&*ret)) {
+ cout<<(*strValue)->getName()<<endl;
+ }
+ else if (const auto strValue = boost::get<string>(&*ret)) {
+ cout<<*strValue<<endl;
+ }
+ }
+ else
+ cout << g_outputBuffer;
+
+ }
+ catch(const LuaContext::ExecutionErrorException& e) {
+ std::cerr << e.what() << ": ";
+ try {
+ std::rethrow_if_nested(e);
+ } catch(const std::exception& e) {
+ // e is the exception that was thrown from inside the lambda
+ std::cerr << e.what() << std::endl;
+ }
+ catch(const PDNSException& e) {
+ // e is the exception that was thrown from inside the lambda
+ std::cerr << e.reason << std::endl;
+ }
+ }
+ catch(const std::exception& e) {
+ // e is the exception that was thrown from inside the lambda
+ std::cerr << e.what() << std::endl;
+ }
+ }
+}
+/**** CARGO CULT CODE AHEAD ****/
+extern "C" {
+char* my_generator(const char* text, int state)
+{
+ string t(text);
+ vector<string> words{"showRules()", "shutdown()", "rmRule(", "mvRule(", "addACL(", "addLocal(", "setServerPolicy(", "setServerPolicyLua(",
+ "newServer(", "rmServer(", "showServers()", "show(", "newDNSName(", "newSuffixMatchNode(", "controlSocket(", "topClients(", "showResponseLatency()",
+ "newQPSLimiter(", "makeKey()", "setKey(", "testCrypto()", "addAnyTCRule()", "showServerPolicy()", "setACL(", "showACL()", "addDomainBlock(",
+ "addPoolRule(", "addQPSLimit(", "topResponses(", "topQueries(", "topRule()", "setDNSSECPool(", "setECSOverride(", "setECSSourcePrefixV4(",
+ "setECSSourcePrefixV6(", "addDelay(", "setTCPRecvTimeout(", "setTCPSendTimeout(", "setMaxTCPClientThreads(", "setMaxUDPOutstanding(" };
+ static int s_counter=0;
+ int counter=0;
+ if(!state)
+ s_counter=0;
+
+ for(auto w : words) {
+ if(boost::starts_with(w, t) && counter++ == s_counter) {
+ s_counter++;
+ return strdup(w.c_str());
+ }
+ }
+ return 0;
+}
+
+char** my_completion( const char * text , int start, int end)
+{
+ char **matches=0;
+ if (start == 0)
+ matches = rl_completion_matches ((char*)text, &my_generator);
+ else
+ rl_bind_key('\t',rl_abort);
+
+ if(!matches)
+ rl_bind_key('\t', rl_abort);
+ return matches;
+}
+}
+
+void controlClientThread(int fd, ComboAddress client)
+try
+{
+ SodiumNonce theirs;
+ readn2(fd, (char*)theirs.value, sizeof(theirs.value));
+ SodiumNonce ours;
+ ours.init();
+ writen2(fd, (char*)ours.value, sizeof(ours.value));
+
+ for(;;) {
+ uint32_t len;
+ if(!getMsgLen32(fd, &len))
+ break;
+ boost::scoped_array<char> msg(new char[len]);
+ readn2(fd, msg.get(), len);
+
+ string line(msg.get(), len);
+ line = sodDecryptSym(line, g_key, theirs);
+ // cerr<<"Have decrypted line: "<<line<<endl;
+ string response;
+ try {
+ std::lock_guard<std::mutex> lock(g_luamutex);
+ g_outputBuffer.clear();
+ auto ret=g_lua.executeCode<
+ boost::optional<
+ boost::variant<
+ string,
+ shared_ptr<DownstreamState>
+ >
+ >
+ >(line);
+
+ if(ret) {
+ if (const auto strValue = boost::get<shared_ptr<DownstreamState>>(&*ret)) {
+ response=(*strValue)->getName();
+ }
+ else if (const auto strValue = boost::get<string>(&*ret)) {
+ response=*strValue;
+ }
+ }
+ else
+ response=g_outputBuffer;
+
+ }
+ catch(const LuaContext::ExecutionErrorException& e) {
+ response = "Error: " + string(e.what()) + ": ";
+ try {
+ std::rethrow_if_nested(e);
+ } catch(const std::exception& e) {
+ // e is the exception that was thrown from inside the lambda
+ response+= string(e.what());
+ }
+ catch(const PDNSException& e) {
+ // e is the exception that was thrown from inside the lambda
+ response += string(e.reason);
+ }
+ }
+ catch(const LuaContext::SyntaxErrorException& e) {
+ response = "Error: " + string(e.what()) + ": ";
+ }
+ response = sodEncryptSym(response, g_key, ours);
+ putMsgLen32(fd, response.length());
+ writen2(fd, response.c_str(), response.length());
+ }
+ infolog("Closed control connection from %s", client.toStringWithPort());
+ close(fd);
+ fd=-1;
+}
+catch(std::exception& e)
+{
+ errlog("Got an exception in client connection from %s: %s", client.toStringWithPort(), e.what());
+ if(fd >= 0)
+ close(fd);
+}
+
string g_key;
-static void controlClientThread(int fd, ComboAddress client)
-try
-{
- SodiumNonce theirs;
- readn2(fd, (char*)theirs.value, sizeof(theirs.value));
- SodiumNonce ours;
- ours.init();
- writen2(fd, (char*)ours.value, sizeof(ours.value));
-
- for(;;) {
- uint32_t len;
- if(!getMsgLen32(fd, &len))
- break;
- boost::scoped_array<char> msg(new char[len]);
- readn2(fd, msg.get(), len);
-
- string line(msg.get(), len);
- line = sodDecryptSym(line, g_key, theirs);
- // cerr<<"Have decrypted line: "<<line<<endl;
- string response;
- try {
- std::lock_guard<std::mutex> lock(g_luamutex);
- g_outputBuffer.clear();
- auto ret=g_lua.executeCode<
- boost::optional<
- boost::variant<
- string,
- shared_ptr<DownstreamState>
- >
- >
- >(line);
-
- if(ret) {
- if (const auto strValue = boost::get<shared_ptr<DownstreamState>>(&*ret)) {
- response=(*strValue)->getName();
- }
- else if (const auto strValue = boost::get<string>(&*ret)) {
- response=*strValue;
- }
- }
- else
- response=g_outputBuffer;
-
- }
- catch(const LuaContext::ExecutionErrorException& e) {
- response = "Error: " + string(e.what()) + ": ";
- try {
- std::rethrow_if_nested(e);
- } catch(const std::exception& e) {
- // e is the exception that was thrown from inside the lambda
- response+= string(e.what());
- }
- catch(const PDNSException& e) {
- // e is the exception that was thrown from inside the lambda
- response += string(e.reason);
- }
- }
- catch(const LuaContext::SyntaxErrorException& e) {
- response = "Error: " + string(e.what()) + ": ";
- }
- response = sodEncryptSym(response, g_key, ours);
- putMsgLen32(fd, response.length());
- writen2(fd, response.c_str(), response.length());
- }
- infolog("Closed control connection from %s", client.toStringWithPort());
- close(fd);
- fd=-1;
-}
-catch(std::exception& e)
-{
- errlog("Got an exception in client connection from %s: %s", client.toStringWithPort(), e.what());
- if(fd >= 0)
- close(fd);
-}
-
void controlThread(int fd, ComboAddress local)
try
-static void doClient(ComboAddress server, const std::string& command)
-{
- cout<<"Connecting to "<<server.toStringWithPort()<<endl;
- int fd=socket(server.sin4.sin_family, SOCK_STREAM, 0);
- SConnect(fd, server);
-
- SodiumNonce theirs, ours;
- ours.init();
-
- writen2(fd, (const char*)ours.value, sizeof(ours.value));
- readn2(fd, (char*)theirs.value, sizeof(theirs.value));
-
- if(!command.empty()) {
- string response;
- string msg=sodEncryptSym(command, g_key, ours);
- putMsgLen32(fd, msg.length());
- if(!msg.empty())
- writen2(fd, msg);
- uint32_t len;
- getMsgLen32(fd, &len);
- boost::scoped_array<char> resp(new char[len]);
- readn2(fd, resp.get(), len);
- msg.assign(resp.get(), len);
- msg=sodDecryptSym(msg, g_key, theirs);
- cout<<msg<<endl;
- return;
- }
-
- set<string> dupper;
- {
- ifstream history(".dnsdist_history");
- string line;
- while(getline(history, line))
- add_history(line.c_str());
- }
- ofstream history(".dnsdist_history", std::ios_base::app);
- string lastline;
- for(;;) {
- char* sline = readline("> ");
- rl_bind_key('\t',rl_complete);
- if(!sline)
- break;
-
- string line(sline);
- if(!line.empty() && line != lastline) {
- add_history(sline);
- history << sline <<endl;
- history.flush();
- }
- lastline=line;
- free(sline);
-
- if(line=="quit")
- break;
-
- string response;
- string msg=sodEncryptSym(line, g_key, ours);
- putMsgLen32(fd, msg.length());
- writen2(fd, msg);
- uint32_t len;
- if(!getMsgLen32(fd, &len) || len == 0) {
- cout << "Connection closed by the server." << endl;
- break;
- }
-
- boost::scoped_array<char> resp(new char[len]);
- readn2(fd, resp.get(), len);
- msg.assign(resp.get(), len);
- msg=sodDecryptSym(msg, g_key, theirs);
- cout<<msg<<endl;
- }
-}
-
-static void doConsole()
-{
- set<string> dupper;
- {
- ifstream history(".dnsdist_history");
- string line;
- while(getline(history, line))
- add_history(line.c_str());
- }
- ofstream history(".dnsdist_history", std::ios_base::app);
- string lastline;
- for(;;) {
- char* sline = readline("> ");
- rl_bind_key('\t',rl_complete);
- if(!sline)
- break;
-
- string line(sline);
- if(!line.empty() && line != lastline) {
- add_history(sline);
- history << sline <<endl;
- history.flush();
- }
- lastline=line;
- free(sline);
-
- if(line=="quit")
- break;
-
- string response;
- try {
- std::lock_guard<std::mutex> lock(g_luamutex);
- g_outputBuffer.clear();
- auto ret=g_lua.executeCode<
- boost::optional<
- boost::variant<
- string,
- shared_ptr<DownstreamState>
- >
- >
- >(line);
-
- if(ret) {
- if (const auto strValue = boost::get<shared_ptr<DownstreamState>>(&*ret)) {
- cout<<(*strValue)->getName()<<endl;
- }
- else if (const auto strValue = boost::get<string>(&*ret)) {
- cout<<*strValue<<endl;
- }
- }
- else
- cout << g_outputBuffer;
-
- }
- catch(const LuaContext::ExecutionErrorException& e) {
- std::cerr << e.what() << ": ";
- try {
- std::rethrow_if_nested(e);
- } catch(const std::exception& e) {
- // e is the exception that was thrown from inside the lambda
- std::cerr << e.what() << std::endl;
- }
- catch(const PDNSException& e) {
- // e is the exception that was thrown from inside the lambda
- std::cerr << e.reason << std::endl;
- }
- }
- catch(const std::exception& e) {
- // e is the exception that was thrown from inside the lambda
- std::cerr << e.what() << std::endl;
- }
- }
-}
-
static void bindAny(int af, int sock)
{
int one = 1;
}
}
-static uid_t strToUID(const string &str)
-{
- uid_t result = 0;
- const char * cstr = str.c_str();
- struct passwd * pwd = getpwnam(cstr);
-
- if (pwd == NULL) {
- char * endptr = 0;
- long int val = strtol(cstr, &endptr, 10);
-
- if (((val == LONG_MAX || val == LLONG_MIN) && errno == ERANGE) || endptr == cstr || val <= 0) {
- warnlog("Warning: Unable to parse user ID %s", cstr);
- }
- else {
- result = val;
- }
- }
- else {
- result = pwd->pw_uid;
- }
-
- return result;
-}
-
-static gid_t strToGID(const string &str)
-{
- gid_t result = 0;
- const char * cstr = str.c_str();
- struct group * grp = getgrnam(cstr);
-
- if (grp == NULL) {
- char * endptr = 0;
- long int val = strtol(cstr, &endptr, 10);
-
- if (((val == LONG_MAX || val == LLONG_MIN) && errno == ERANGE) || endptr == cstr || val <= 0) {
- warnlog("Warning: Unable to parse group ID %s", cstr);
- }
- else {
- result = val;
- }
- }
- else {
- result = grp->gr_gid;
- }
-
- return result;
-}
-
-/**** CARGO CULT CODE AHEAD ****/
-extern "C" {
-char* my_generator(const char* text, int state)
-{
- string t(text);
- vector<string> words{"showRules()", "shutdown()", "rmRule(", "mvRule(", "addACL(", "addLocal(", "setServerPolicy(", "setServerPolicyLua(",
- "newServer(", "rmServer(", "showServers()", "show(", "newDNSName(", "newSuffixMatchNode(", "controlSocket(", "topClients(", "showResponseLatency()",
- "newQPSLimiter(", "makeKey()", "setKey(", "testCrypto()", "addAnyTCRule()", "showServerPolicy()", "setACL(", "showACL()", "addDomainBlock(",
- "addPoolRule(", "addQPSLimit(", "topResponses(", "topQueries(", "topRule()", "setDNSSECPool(", "setECSOverride(", "setECSSourcePrefixV4(",
- "setECSSourcePrefixV6(", "addDelay(", "setTCPRecvTimeout(", "setTCPSendTimeout(", "setMaxTCPClientThreads(", "setMaxUDPOutstanding(" };
- static int s_counter=0;
- int counter=0;
- if(!state)
- s_counter=0;
-
- for(auto w : words) {
- if(boost::starts_with(w, t) && counter++ == s_counter) {
- s_counter++;
- return strdup(w.c_str());
- }
- }
- return 0;
-}
-
-static char** my_completion( const char * text , int start, int end)
-{
- char **matches=0;
- if (start == 0)
- matches = rl_completion_matches ((char*)text, &my_generator);
- else
- rl_bind_key('\t',rl_abort);
-
- if(!matches)
- rl_bind_key('\t', rl_abort);
- return matches;
-}
-}
struct
{
void* tcpAcceptorThread(void* p);
void moreLua();
+void doClient(ComboAddress server, const std::string& command);
+void doConsole();
+void controlClientThread(int fd, ComboAddress client);
+extern "C" {
+char** my_completion( const char * text , int start, int end);
+}
dns.cc dns.hh \
dnsdist.cc dnsdist.hh \
dnsdist-carbon.cc \
+ dnsdist-console.cc \
dnsdist-ecs.cc dnsdist-ecs.hh \
dnsdist-lua.cc \
dnsdist-lua2.cc \
--- /dev/null
+../dnsdist-console.cc
\ No newline at end of file
#include <boost/algorithm/string.hpp>
#include "iputils.hh"
#include "dnsparser.hh"
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+
bool g_singleThreaded;
}
return seconds + useconds/1000000.0;
}
+
+
+uid_t strToUID(const string &str)
+{
+ uid_t result = 0;
+ const char * cstr = str.c_str();
+ struct passwd * pwd = getpwnam(cstr);
+
+ if (pwd == NULL) {
+ char * endptr = 0;
+ long int val = strtol(cstr, &endptr, 10);
+
+ if (((val == LONG_MAX || val == LLONG_MIN) && errno == ERANGE) || endptr == cstr || val <= 0) {
+ throw runtime_error((boost::format("Warning: Unable to parse user ID %s") % cstr).str() );
+ }
+ else {
+ result = val;
+ }
+ }
+ else {
+ result = pwd->pw_uid;
+ }
+
+ return result;
+}
+
+gid_t strToGID(const string &str)
+{
+ gid_t result = 0;
+ const char * cstr = str.c_str();
+ struct group * grp = getgrnam(cstr);
+
+ if (grp == NULL) {
+ char * endptr = 0;
+ long int val = strtol(cstr, &endptr, 10);
+
+ if (((val == LONG_MAX || val == LLONG_MIN) && errno == ERANGE) || endptr == cstr || val <= 0) {
+ throw runtime_error((boost::format("Warning: Unable to parse group ID %s") % cstr).str() );
+ }
+ else {
+ result = val;
+ }
+ }
+ else {
+ result = grp->gr_gid;
+ }
+
+ return result;
+}
+
double DiffTime(const struct timespec& first, const struct timespec& second);
double DiffTime(const struct timeval& first, const struct timeval& second);
+uid_t strToUID(const string &str);
+gid_t strToGID(const string &str);