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;
{
reportAllTypes();
-#if 0
Socket s(InterNetwork, Datagram);
+
+ IPEndpoint rem("127.0.0.1",1232), loc("213.156.2.1", 53);
+ s.bind(loc);
vector<uint8_t> 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<uint8_t> packet;
shared_ptr<DNSRecordContent> regen=DNSRecordContent::unserialize(argv[1], type, record);
cerr<<"Out: "<<argv[1]<<" IN "<<argv[2]<<" "<<regen->getZoneRepresentation()<<endl;
+#endif
}
catch(exception& e)
{
{
typedef vector<pair<unsigned int, unsigned int> > 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;
\return returns -1 in case of error, 0 in case of timeout, 1 in case of an answer
*/
-template<class EventKey, class EventVal>int MTasker<EventKey,EventVal>::waitEvent(const EventKey &key, EventVal *val, unsigned int timeout)
+template<class EventKey, class EventVal>int MTasker<EventKey,EventVal>::waitEvent(EventKey &key, EventVal *val, unsigned int timeout)
{
if(d_waiters.count(key)) { // there was already an exact same waiter
return -1;
if(val && d_waitstatus==Answer)
*val=d_waitval;
d_tid=w.tid;
+ key=d_eventkey;
return d_waitstatus;
}
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");
std::queue<int> d_runQueue;
std::queue<int> d_zombiesQueue;
+
+ typedef std::map<int, ucontext_t*> 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;
int tid;
};
- // typedef std::map<EventKey,Waiter> waiters_t;
-
typedef multi_index_container<
Waiter,
indexed_by <
waiters_t d_waiters;
- typedef std::map<int, ucontext_t*> 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,
}
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<EventKey>& events);
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"
static map<int,PacketID> d_tcpclientreadsocks, d_tcpclientwritesocks;
-MTasker<PacketID,string>* MT;
+typedef MTasker<PacketID,string> MT_t;
+MT_t* MT;
int asendtcp(const string& data, Socket* sock)
{
if(ret > 0) {
*d_len=packet.size();
memcpy(data,packet.c_str(),min(len,*d_len));
+ if(pident.nearMisses > 100) {
+ L<<Logger::Error<<"Too many ("<<pident.nearMisses<<") bogus answers came in from "<<sockAddrToString((struct sockaddr_in*)toaddr, sizeof(pident.remote))<<", assuming spoof attempt."<<endl;
+ return -1;
+ }
}
return ret;
}
if(logCommonErrors)
L<<Logger::Warning<<"Discarding unexpected packet from "<<sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen)<<endl;
g_stats.unexpectedCount++;
+
+ for(MT_t::waiters_t::iterator mthread=MT->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
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();
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
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;