int main(int argc, char** argv)
try
{
- if(argc != 3) {
- cerr<<"Syntax: dumresp local-address number-of-threads"<<endl;
+ if(argc != 4) {
+ cerr<<"Syntax: dumresp local-address local-port number-of-threads "<<endl;
exit(EXIT_FAILURE);
}
- for(int i=1 ; i < atoi(argv[2]); ++i) {
+ for(int i=1 ; i < atoi(argv[3]); ++i) {
if(!fork())
break;
}
- Socket s(AF_INET, SOCK_DGRAM);
- ComboAddress local(argv[1], 5300);
-
+
+ ComboAddress local(argv[1], atoi(argv[2]));
+ Socket s(local.sin4.sin_family, SOCK_DGRAM);
#ifdef SO_REUSEPORT
int one=1;
if(setsockopt(s.getHandle(), SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) < 0)
#endif
s.bind(local);
+ cout<<"Bound to "<<local.toStringWithPort()<<endl;
char buffer[1500];
struct dnsheader* dh = (struct dnsheader*)buffer;
int len;
len=recvfrom(s.getHandle(), buffer, sizeof(buffer), 0, (struct sockaddr*)&rem, &socklen);
if(len < 0)
unixDie("recvfrom");
-
+ cout<<"Had packet: "<<string(buffer, len)<<endl;
+ /*
if(dh->qr)
continue;
dh->qr=1;
dh->ad=0;
+ */
if(sendto(s.getHandle(), buffer, len, 0, (struct sockaddr*)&rem, socklen) < 0)
unixDie("sendto");
#include "logger.hh"
#include "namespaces.hh"
#include "dnsparser.hh"
+#undef L
bool netmaskMatchTable(lua_State* lua, const std::string& ip)
{
return ret;
}
+
+
void pushResourceRecordsTable(lua_State* lua, const vector<DNSRecord>& records)
{
// make a table of tables
return ::getFromTable(d_lua, key, value);
}
-
PowerDNSLua::~PowerDNSLua()
{
lua_close(d_lua);
#ifndef PDNS_LUA_PDNS_HH
#define PDNS_LUA_PDNS_HH
+
#include "dns.hh"
#include "iputils.hh"
-
struct lua_State;
class PowerDNSLua
bool passthrough(const string& func, const ComboAddress& remote,const ComboAddress& local, const string& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res, bool* variable);
bool getFromTable(const std::string& key, std::string& value);
bool getFromTable(const std::string& key, uint32_t& value);
+
ComboAddress d_local;
bool d_failed;
bool d_variable;
#include "namespaces.hh"
#include "rec_channel.hh"
#include "dnsrecords.hh"
-
+#undef L
static int getRegisteredNameLua(lua_State *L) {
const char *name = luaL_checkstring(L, 1);
string regname=getRegisteredName(DNSName(name)).toString(); // hnnggg
}
+
int getFakeAAAARecords(const std::string& qname, const std::string& prefix, vector<DNSRecord>& ret)
{
int rcode=directResolve(qname, QType(QType::A), 1, ret);
return newres != -1;
}
+static bool getFromTable(lua_State *lua, const std::string &key, lua_CFunction& value)
+{
+ lua_pushstring(lua, key.c_str()); // 4 is now '1'
+ lua_gettable(lua, -2); // replace by the first entry of our table we hope
+
+ bool ret=false;
+
+ if(lua_isfunction(lua, -1)) {
+ value = lua_tocfunction(lua, -1);
+ ret=true;
+ }
+ lua_pop(lua, 1);
+ return ret;
+}
+
bool RecursorLua::passthrough(const string& func, const ComboAddress& remote, const ComboAddress& local, const DNSName& query, const QType& qtype, vector<DNSRecord>& ret,
int& res, bool* variable)
string tocall = lua_tostring(d_lua,1);
lua_remove(d_lua, 1); // the name
ret.clear();
- if(tocall == "getFakeAAAARecords") {
+ cerr<<"tocall: "<<tocall<<endl;
+ if(tocall == "udpQuestionResponse") {
+
+ string dest = lua_tostring(d_lua,1);
+ cerr<<"dest: "<<dest<<endl;
+ string uquery;
+ getFromTable("query", uquery);
+ lua_CFunction callback=0;
+ cout<<"callback get:"<<::getFromTable(d_lua, "callback", callback)<<endl;
+ cout<<"callback value: "<<(void*)callback<<endl;
+ cerr<<"query: "<<query<<endl;
+ // string followup = lua_tostring(d_lua, 3);
+ // cerr<<"followup: "<<dest<<endl;
+ lua_pop(d_lua, 3);
+
+ string answer = udpQuestionResponse(ComboAddress(dest), uquery);
+ cerr<<"Back in lua-recursor, got: '"<<answer<<"'"<<endl;
+ lua_pushcfunction(d_lua, callback);
+ lua_pushstring(d_lua, remote.toString().c_str() );
+ lua_pushstring(d_lua, query.toString().c_str() );
+ lua_pushnumber(d_lua, qtype.getCode() );
+ lua_pushstring(d_lua, answer.c_str() );
+ cerr<<"Going to call"<<endl;
+ if(lua_pcall(d_lua, 4, 3, 0)) { // NOTE! Means we always get 3 stack entries back, no matter what our lua hook returned!
+ string error=string("lua error in '"+func+"' while callback for '"+query.toString()+"|"+qtype.getName()+": ")+lua_tostring(d_lua, -1);
+ lua_pop(d_lua, 1);
+ throw runtime_error(error);
+ return false;
+ }
+ cerr<<"We called!"<<endl;
+ }
+ else if(tocall == "getFakeAAAARecords") {
string luaprefix = lua_tostring(d_lua, 2);
string luaqname = lua_tostring(d_lua,1);
lua_pop(d_lua, 2);
#include "dns.hh"
#include "iputils.hh"
#include "lua-pdns.hh"
-
+string udpQuestionResponse(const ComboAddress& dest, const string& query);
class RecursorLua : public PowerDNSLua
{
public:
bool g_singleThreaded;
+void sometests()
+{
+ vector<std::unique_ptr<int>> vec;
+ vec.push_back(make_unique<int>(12));
+}
+
int writen2(int fd, const void *buf, size_t count)
{
const char *ptr = (char*)buf;
return ret;
}
+void handleUDPQueryResponse(int fd, FDMultiplexer::funcparam_t& var)
+{
+ cerr<<"In handle UDPQueryResponse"<<endl;
+ PacketID* pident=any_cast<PacketID>(&var);
+ char resp[512];
+ int ret=recv(fd, resp, sizeof(resp), 0);
+ t_fdm->removeReadFD(fd);
+ if(ret >= 0) {
+ string data(resp, ret);
+ cerr<<"Reporting what we got ('"<<data<<"')"<<endl;
+ cerr<<"Reporting returned: "<<MT->sendEvent(*pident, &data)<<endl;
+ }
+ else {
+ cerr<<"Had some kind of error: "<<ret<<endl;
+ }
+}
+string udpQuestionResponse(const ComboAddress& dest, const string& query)
+{
+ cerr<<"In udpQuestionResponse"<<endl;
+ Socket s(dest.sin4.sin_family, SOCK_DGRAM);
+ s.setNonBlocking();
+ ComboAddress local = getQueryLocalAddress(dest.sin4.sin_family, 0);
+
+ s.bind(local);
+ s.connect(dest);
+ cerr<<"here, query="<<query<<endl;
+ s.send(query);
+
+ PacketID pident;
+ pident.sock=&s;
+ pident.type=0;
+ t_fdm->addReadFD(s.getHandle(), handleUDPQueryResponse, pident);
+
+ string data;
+ cerr<<"Entering waitEvent in udpQuestionResponse"<<endl;
+ int ret=MT->waitEvent(pident,&data, g_networkTimeoutMsec);
+ cerr<<"Got back: "<<data<<endl;
+ if(!ret || ret==-1) { // timeout
+ cerr<<"Got back some kind of error, ret="<<ret<<endl;
+ t_fdm->removeReadFD(s.getHandle());
+ }
+ else if(data.empty()) {// error, EOF or other
+
+ return data;
+ }
+
+ return data;
+}
+
+
+
vector<ComboAddress> g_localQueryAddresses4, g_localQueryAddresses6;
const ComboAddress g_local4("0.0.0.0"), g_local6("::");
throw NetworkError(string("Setsockopt failed: ")+strerror(errno));
if(::bind(d_socket,(struct sockaddr *)&local, local.getSocklen())<0)
- throw NetworkError(strerror(errno));
+ throw NetworkError("While binding: "+string(strerror(errno)));
}
#if 0
void connect(const ComboAddress &ep)
{
if(::connect(d_socket,(struct sockaddr *)&ep, ep.getSocklen()) < 0 && errno != EINPROGRESS)
- throw NetworkError(strerror(errno));
+ throw NetworkError("While connecting: "+string(strerror(errno)));
}
socklen_t remlen=sizeof(ep);
int bytes;
if((bytes=recvfrom(d_socket, d_buffer, d_buflen, 0, (sockaddr *)&ep , &remlen)) <0)
- throw NetworkError(strerror(errno));
+ throw NetworkError("After recvfrom: "+string(strerror(errno)));
dgram.assign(d_buffer,bytes);
}
int bytes;
if((bytes=recvfrom(d_socket, d_buffer, d_buflen, 0, (sockaddr *)&remote, &remlen))<0) {
if(errno!=EAGAIN) {
- throw NetworkError(strerror(errno));
+ throw NetworkError("After async recvfrom: "+string(strerror(errno)));
}
else {
return false;
void sendTo(const char* msg, unsigned int len, const ComboAddress &ep)
{
if(sendto(d_socket, msg, len, 0, (sockaddr *)&ep, ep.getSocklen())<0)
- throw NetworkError(strerror(errno));
+ throw NetworkError("After sendto: "+string(strerror(errno)));
}
+ //! For connected datagram sockets, send a datagram
+ void send(const std::string& msg)
+ {
+ if(::send(d_socket, msg.c_str(), msg.size(), 0)<0)
+ throw NetworkError("After send: "+string(strerror(errno)));
+ }
+
+
/** For datagram sockets, send a datagram to a destination
\param dgram The datagram
\param ep The intended destination of the datagram */
}
+
SyncRes::SyncRes(const struct timeval& now) : d_outqueries(0), d_tcpoutqueries(0), d_throttledqueries(0), d_timeouts(0), d_unreachables(0),
d_totUsec(0), d_doDNSSEC(false), d_now(now),
d_cacheonly(false), d_nocache(false), d_doEDNS0(false), d_lm(s_lm)