From: Bert Hubert Date: Fri, 14 Apr 2006 11:26:50 +0000 (+0000) Subject: implement stunningly cool spoofing protection, plus spoofer in dnspbench X-Git-Tag: rec-3-0~54 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=35ce85764dc958c27c76894d630dc76364519733;p=pdns implement stunningly cool spoofing protection, plus spoofer in dnspbench git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@699 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- diff --git a/pdns/dnsparser.cc b/pdns/dnsparser.cc index 6f432e29d..90c2abce8 100644 --- a/pdns/dnsparser.cc +++ b/pdns/dnsparser.cc @@ -378,6 +378,7 @@ void PacketReader::getLabelFromContent(const vector& content, uint16_t& return getLabelFromContent(content, offset, ret, ++recurs); } else { + // should check for . here and replace by \. ret.append(&content.at(frompos), &content.at(frompos+labellen)); ret.append(1,'.'); frompos+=labellen; diff --git a/pdns/dnspbench.cc b/pdns/dnspbench.cc index c0af89a8f..bf164dc35 100644 --- a/pdns/dnspbench.cc +++ b/pdns/dnspbench.cc @@ -44,27 +44,32 @@ try { reportAllTypes(); -#if 0 Socket s(InterNetwork, Datagram); + + IPEndpoint rem("127.0.0.1",1232), loc("213.156.2.1", 53); + s.bind(loc); vector vpacket; - string domain="www.ds9a.nl"; + string domain="ds9a.nl"; uint16_t type=1; - for(unsigned int n=0; n < 1000000; ++n) { + for(unsigned int n=0; n < 65536; ++n) { DNSPacketWriter pw(vpacket, domain, type); pw.getHeader()->rd=1; + pw.getHeader()->qr=1; pw.getHeader()->id=n; + ARecordContent arc("1.2.3.4"); + pw.startRecord("ds9a.nl", 1, 9999, 1, DNSPacketWriter::ANSWER); + arc.toPacket(pw); pw.commit(); - IPEndpoint rem("127.0.0.1",5300); + string spacket((char*)(&*vpacket.begin()), vpacket.size()); s.sendTo(spacket, rem); } - return 0; -#endif +#if 0 vector packet; @@ -82,6 +87,7 @@ try shared_ptr regen=DNSRecordContent::unserialize(argv[1], type, record); cerr<<"Out: "<getZoneRepresentation()< > parts_t; parts_t parts; - vstringtok(parts, label, "."); + vstringtok(parts, label, "."); // XXX FIXME this should deal with escaped . // d_stuff is amount of stuff that is yet to be written out - the dnsrecordheader for example unsigned int pos=d_content.size() + d_record.size() + d_stuff; diff --git a/pdns/mtasker.cc b/pdns/mtasker.cc index 8a815378b..80fd3bab7 100644 --- a/pdns/mtasker.cc +++ b/pdns/mtasker.cc @@ -158,7 +158,7 @@ int main() \return returns -1 in case of error, 0 in case of timeout, 1 in case of an answer */ -templateint MTasker::waitEvent(const EventKey &key, EventVal *val, unsigned int timeout) +templateint MTasker::waitEvent(EventKey &key, EventVal *val, unsigned int timeout) { if(d_waiters.count(key)) { // there was already an exact same waiter return -1; @@ -180,6 +180,7 @@ templateint MTasker::waitEven if(val && d_waitstatus==Answer) *val=d_waitval; d_tid=w.tid; + key=d_eventkey; return d_waitstatus; } @@ -216,7 +217,7 @@ templateint MTasker::sendEven ucontext_t *userspace=waiter->context; d_tid=waiter->tid; // set tid - + d_eventkey=waiter->key; // pass waitEvent the exact key it was woken for d_waiters.erase(waiter); // removes the waitpoint if(swapcontext(&d_kernel,userspace)) { // swaps back to the above point 'A' perror("swapcontext in sendEvent"); diff --git a/pdns/mtasker.hh b/pdns/mtasker.hh index 5d1518907..ba358b2f3 100644 --- a/pdns/mtasker.hh +++ b/pdns/mtasker.hh @@ -50,6 +50,17 @@ private: std::queue d_runQueue; std::queue d_zombiesQueue; + + typedef std::map mthreads_t; + mthreads_t d_threads; + int d_tid; + int d_maxtid; + size_t d_stacksize; + + EventVal d_waitval; + enum {Error=-1,TimeOut=0,Answer} d_waitstatus; + +public: struct Waiter { EventKey key; @@ -58,8 +69,6 @@ private: int tid; }; - // typedef std::map waiters_t; - typedef multi_index_container< Waiter, indexed_by < @@ -70,16 +79,6 @@ private: waiters_t d_waiters; - typedef std::map mthreads_t; - mthreads_t d_threads; - int d_tid; - int d_maxtid; - size_t d_stacksize; - - EventVal d_waitval; - enum {Error=-1,TimeOut=0,Answer} d_waitstatus; - -public: //! Constructor /** Constructor with a small default stacksize. If any of your threads exceeds this stack, your application will crash. This limit applies solely to the stack, the heap is not limited in any way. If threads need to allocate a lot of data, @@ -91,7 +90,7 @@ public: } typedef void tfunc_t(void *); //!< type of the pointer that starts a thread - int waitEvent(const EventKey &key, EventVal *val=0, unsigned int timeout=0); + int waitEvent(EventKey &key, EventVal *val=0, unsigned int timeout=0); void yield(); int sendEvent(const EventKey& key, const EventVal* val=0); void getEvents(std::vector& events); @@ -103,6 +102,7 @@ public: private: static void threadWrapper(MTasker *self, tfunc_t *tf, int tid, void* val); + EventKey d_eventkey; // for waitEvent, contains exact key it was awoken for }; #include "mtasker.cc" diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 934bc6af6..95cde0532 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -127,7 +127,8 @@ static tcpserversocks_t s_tcpserversocks; static map d_tcpclientreadsocks, d_tcpclientwritesocks; -MTasker* MT; +typedef MTasker MT_t; +MT_t* MT; int asendtcp(const string& data, Socket* sock) { @@ -182,6 +183,10 @@ int arecvfrom(char *data, int len, int flags, struct sockaddr *toaddr, Utility:: if(ret > 0) { *d_len=packet.size(); memcpy(data,packet.c_str(),min(len,*d_len)); + if(pident.nearMisses > 100) { + L<d_waiters.begin(); mthread!=MT->d_waiters.end(); ++mthread) { + if(!memcmp(&mthread->key.remote.sin_addr, &pident.remote.sin_addr, sizeof(pident.remote.sin_addr))) { + mthread->key.nearMisses++; + } + } } } else diff --git a/pdns/rcpgenerator.cc b/pdns/rcpgenerator.cc index 1c7106b2e..5148f9314 100644 --- a/pdns/rcpgenerator.cc +++ b/pdns/rcpgenerator.cc @@ -97,8 +97,7 @@ void RecordTextReader::xfr8BitInt(uint8_t &val) throw RecordTextException("Overflow reading 8 bit integer from record content"); // fixme improve } - -void RecordTextReader::xfrLabel(string& val, bool) +void RecordTextReader::xfrLabel(string& val, bool) { skipSpaces(); val.clear(); diff --git a/pdns/syncres.hh b/pdns/syncres.hh index 391a4efa4..e224db358 100644 --- a/pdns/syncres.hh +++ b/pdns/syncres.hh @@ -317,7 +317,7 @@ int arecvtcp(string& data, int len, Socket* sock); struct PacketID { - PacketID() : sock(0), inNeeded(0), outPos(0) + PacketID() : sock(0), inNeeded(0), outPos(0), nearMisses(0) {} uint16_t id; // wait for a specific id/remote pair @@ -330,6 +330,8 @@ struct PacketID string outMSG; // the outgoing message that needs to be sent string::size_type outPos; // how far we are along in the outMSG + mutable uint32_t nearMisses; // number of near misses - host correct, id wrong + bool operator<(const PacketID& b) const { int ourSock= sock ? sock->getHandle() : 0;