LINKCC=$(CXX)
CC?=gcc
-LUA_CPPFLAGS_CONFIG ?= -I/usr/include/lua5.1
-LUA_LIBS_CONFIG ?= -llua5.1
+# Lua 5.1 settings
+#LUA_CPPFLAGS_CONFIG ?= -I/usr/include/lua5.1
+#LUA_LIBS_CONFIG ?= -llua5.1
+
+# Lua 5.0 settings
+LUA_CPPFLAGS_CONFIG=-I/usr/include/lua50
+LUA_LIBS_CONFIG=-llua50 -llualib50
# static dependencies
luaopen_string(d_lua);
lua_settop(d_lua, 0);
+#ifndef LUA_VERSION_NUM
+ if(lua_dofile(d_lua, fname.c_str()))
+#else
if(luaL_dofile(d_lua, fname.c_str()))
+#endif
throw runtime_error(string("Error loading LUA file '")+fname+"': "+ string(lua_isstring(d_lua, -1) ? lua_tostring(d_lua, -1) : "unknown error"));
lua_pushcfunction(d_lua, netmaskMatchLua);
return passthrough("prequery", remote, query, qtype, ret, res);
}
+bool PowerDNSLua::getFromTable(const std::string& key, std::string& value)
+{
+ lua_pushstring(d_lua, key.c_str()); // 4 is now '1'
+ lua_gettable(d_lua, -2); // replace by the first entry of our table we hope
+
+ bool ret=false;
+ if(!lua_isnil(d_lua, -1)) {
+ value = lua_tostring(d_lua, -1);
+ ret=true;
+ }
+ lua_pop(d_lua, 1);
+ return ret;
+}
+
+
+bool PowerDNSLua::getFromTable(const std::string& key, uint32_t& value)
+{
+ lua_pushstring(d_lua, key.c_str()); // 4 is now '1'
+ lua_gettable(d_lua, -2); // replace by the first entry of our table we hope
+
+ bool ret=false;
+ if(!lua_isnil(d_lua, -1)) {
+ value = lua_tonumber(d_lua, -1);
+ ret=true;
+ }
+ lua_pop(d_lua, 1);
+ return ret;
+}
+
+
bool PowerDNSLua::passthrough(const string& func, const ComboAddress& remote, const string& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res)
{
lua_getglobal(d_lua, func.c_str());
lua_pushnumber(d_lua, qtype.getCode() );
lua_call(d_lua, 3, 2);
- if(!lua_toboolean(d_lua, 1)) {
+ res = lua_tonumber(d_lua, 1); // new rcode
+ if(res < 0) {
// cerr << "handler did not handle"<<endl;
lua_pop(d_lua, 2);
return false;
}
+ else
+ cerr<<"res = "<<res<<endl;
/* get the result */
DNSResourceRecord rr;
ret.clear();
- // cerr<<"Think there are "<<lua_objlen(d_lua, 2)<<" records\n";
+ /* 1 2 3 4 */
+ /* stack: boolean table key row */
- /* 1 2 */
- /* stack: boolean table */
+ lua_pushnil(d_lua); /* first key */
+ while (lua_next(d_lua, 2) != 0) {
- for(unsigned int n = 0 ; n <= lua_objlen(d_lua, 2); ++n) {
- lua_pushnumber(d_lua, n); // becomes 3
- lua_gettable(d_lua, 2); // 3 gone, replaced by table[0] - which is again a table
+ uint32_t tmpnum;
+ if(!getFromTable("qtype", tmpnum))
+ rr.qtype=QType::A;
+ else
+ rr.qtype=tmpnum;
- lua_pushnumber(d_lua, 1); // 4 is now '1'
- lua_gettable(d_lua, 3); // replace by the first entry of our table we hope
-
- rr.qtype = QType((int)(lua_tonumber(d_lua, -1)));
- lua_pop(d_lua, 1);
- lua_pushnumber(d_lua, 2); // 4 is now '2'
- lua_gettable(d_lua, 3); // replace by the second entry of our table we hope
- rr.content= lua_tostring(d_lua, -1);
- lua_pop(d_lua, 1); // content
-
- lua_pushnumber(d_lua, 3); // 4 is now '3'
- lua_gettable(d_lua, 3); // replace by the second entry of our table we hope
- rr.ttl = (uint32_t)lua_tonumber(d_lua, -1);
- lua_pop(d_lua, 1); // content
-
+ getFromTable("content", rr.content);
+ if(!getFromTable("ttl", rr.ttl))
+ rr.ttl=3600;
+ if(!getFromTable("qname", rr.qname))
+ rr.qname = query;
+
+ if(!getFromTable("place", tmpnum))
+ rr.d_place = DNSResourceRecord::ANSWER;
+ else
+ rr.d_place = (DNSResourceRecord::Place) tmpnum;
+
+ /* removes 'value'; keeps 'key' for next iteration */
lua_pop(d_lua, 1); // table
// cerr<<"Adding content '"<<rr.content<<"'\n";
lua_pop(d_lua, 2);
- // printf("\nBack to C again: %s, type %d\n\n", rr.content.c_str(), rr.qtype.getCode());
-
- res=0;
-
-
return true;
}
private:
lua_State* d_lua;
bool passthrough(const string& func, const ComboAddress& remote, const string& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res);
+ bool getFromTable(const std::string& key, std::string& value);
+ bool getFromTable(const std::string& key, uint32_t& value);
bool d_failed;
};
for(; chain.first != chain.second; chain.first++) {
if(chain.first->key.fd > -1) { // don't chain onto existing chained waiter!
- // cerr<<"Orig: "<<pident.domain<<", "<<pident.remote.toString()<<", id="<<id<<endl;
- // cerr<<"Had hit: "<< chain.first->key.domain<<", "<<chain.first->key.remote.toString()<<", id="<<chain.first->key.id
- // <<", count="<<chain.first->key.chain.size()<<", origfd: "<<chain.first->key.fd<<endl;
+ cerr<<"Orig: "<<pident.domain<<", "<<pident.remote.toString()<<", id="<<id<<endl;
+ cerr<<"Had hit: "<< chain.first->key.domain<<", "<<chain.first->key.remote.toString()<<", id="<<chain.first->key.id
+ <<", count="<<chain.first->key.chain.size()<<", origfd: "<<chain.first->key.fd<<endl;
chain.first->key.chain.insert(id); // we can chain
*fd=-1; // gets used in waitEvent / sendEvent later on
int res;
- if(!g_pdl.get() || !g_pdl->prequery(dc->d_remote, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret, res))
+ if(!g_pdl.get() || !g_pdl->prequery(dc->d_remote, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret, res)) {
res = sr.beginResolve(dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_mdp.d_qclass, ret);
- if(g_pdl.get() && (res < 0 || res == RCode::NXDomain || res == RCode::ServFail)) {
- g_pdl->nxdomain(dc->d_remote, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret, res);
+ if(g_pdl.get() && (res < 0 || res == RCode::NXDomain || res == RCode::ServFail)) {
+ g_pdl->nxdomain(dc->d_remote, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret, res);
+ }
}
if(res<0) {
// resend event to everybody chained onto it
void doResends(MT_t::waiters_t::iterator& iter, PacketID resend, const string& content)
{
+
if(iter->key.chain.empty())
return;
+ cerr<<"doResends called!\n";
for(PacketID::chain_t::iterator i=iter->key.chain.begin(); i != iter->key.chain.end() ; ++i) {
resend.fd=-1;
resend.id=*i;
+ cerr<<"\tResending "<<content.size()<<" bytes for fd="<<resend.fd<<" and id="<<resend.id<<endl;
+
MT->sendEvent(resend, &content);
g_stats.chainResends++;
- // cerr<<"\tResending "<<content.size()<<" bytes for fd="<<resend.fd<<" and id="<<resend.id<<": "<< res <<endl;
}
}
Utility::gettimeofday(&g_now, 0);
g_fdm->run(&g_now);
+ Utility::gettimeofday(&g_now, 0);
if(listenOnTCP) {
if(TCPConnection::s_currentConnections > maxTcpClients) { // shutdown
print ("prequery handler called for: ", ip, domain, qtype)
ret = {}
- ret[0]= {1, "9.8.7.6", 3601};
- ret[1]= {1, "10.11.12.13", 3601};
- ret[2]= {1, "11.12.13.14", 3601};
-
+-- ret[1]= {1, "10.11.12.13", 3601};
+-- ret[2]= {1, "11.12.13.14", 3601};
if domain == "www.ds9c.nl."
then
+ ret[0]= {qtype=1, content="9.8.7.6", ttl=3601}
+ ret[1]= {qtype=1, content="1.2.3.4", ttl=3601}
print "dealing!"
- return 1, ret
+ return 0, ret
+ elseif domain == "www.baddomain.com."
+ then
+ print "dealing - nx"
+ return 3, ret
else
print "not dealing!"
- return false, ret
+ return -1, ret
end
end
print ("nxhandler called for: ", ip, domain, qtype)
ret={}
if qtype ~= 1 then return false, ret end -- only A records
- if not string.match(domain, "^www.") then return false, ret end -- only things that start with www.
+-- if not string.match(domain, "^www.") then return false, ret end -- only things that start with www.
if matchnetmask(ip, "127.0.0.1/8")
then
print "dealing"
- ret[0]={1, "127.1.2.3", 3602}
- ret[1]={15, "25 ds9a.nl", 3602}
- return 1, ret
+ ret[0]={qtype="5", content="www.webserver.com", ttl=3602}
+ ret[1]={qname="www.webserver.com", qtype="1", content="1.2.3.4", ttl=3602}
+ ret[2]={qname="webserver.com", qtype="2", content="ns1.webserver.com", place=2}
+-- ret[1]={15, "25 ds9a.nl", 3602}
+ return 0, ret
else
print "not dealing"
- return false, ret
+ return -1, ret
end
end