/* * bitdht/udpbitdht.cc * * BitDHT: An Flexible DHT library. * * Copyright 2010 by Robert Fernie * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License Version 3 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. * * Please report all bugs and problems to "bitdht@lunamutt.com". * */ #include "udp/udpbitdht.h" #include "bitdht/bdpeer.h" #include "bitdht/bdstore.h" #include "bitdht/bdmsgs.h" #include "bitdht/bencode.h" #include #include /* for usleep() */ #include #include #include #include "util/bdnet.h" /* * #define DEBUG_UDP_BITDHT 1 * * #define BITDHT_VERSION_ANONYMOUS 1 */ //#define DEBUG_UDP_BITDHT 1 #define BITDHT_VERSION_IDENTIFER 1 // Original RS 0.5.0/0.5.1 version, is un-numbered. //#define BITDHT_VERSION "00" // First Release of BitDHT with Connections (Proxy Support + Dht Stun) //#define BITDHT_VERSION "01" // Testing Connections (Proxy Only) #define BITDHT_VERSION "02" // Completed Relay Connections from svn 4766 //#define BITDHT_VERSION "04" // Full DHT implementation.? /*************************************/ UdpBitDht::UdpBitDht(UdpPublisher *pub, bdNodeId *id, std::string appVersion, std::string bootstrapfile, bdDhtFunctions *fns) :UdpSubReceiver(pub), dhtMtx(true), mFns(fns) { std::string usedVersion; #ifdef BITDHT_VERSION_IDENTIFER usedVersion = "BD"; usedVersion += BITDHT_VERSION; #endif usedVersion += appVersion; #ifdef BITDHT_VERSION_ANONYMOUS usedVersion = ""; /* blank it */ #endif clearDataTransferred(); /* setup nodeManager */ bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ mBitDhtManager = new bdNodeManager(id, usedVersion, bootstrapfile, fns); } UdpBitDht::~UdpBitDht() { return; } /*********** External Interface to the World ************/ /***** Functions to Call down to bdNodeManager ****/ /* Friend Tracking */ void UdpBitDht::addBadPeer(const struct sockaddr_in &addr, uint32_t source, uint32_t reason, uint32_t age) { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ mBitDhtManager->addBadPeer(addr, source, reason, age); } void UdpBitDht::updateKnownPeer(const bdId *id, uint32_t type, uint32_t flags) { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ mBitDhtManager->updateKnownPeer(id, type, flags); } /* Request DHT Peer Lookup */ /* Request Keyword Lookup */ void UdpBitDht::addFindNode(bdNodeId *id, uint32_t mode) { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ mBitDhtManager->addFindNode(id, mode); } void UdpBitDht::removeFindNode(bdNodeId *id) { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ mBitDhtManager->removeFindNode(id); } void UdpBitDht::findDhtValue(bdNodeId *id, std::string key, uint32_t mode) { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ mBitDhtManager->findDhtValue(id, key, mode); } /***** Add / Remove Callback Clients *****/ void UdpBitDht::addCallback(BitDhtCallback *cb) { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ mBitDhtManager->addCallback(cb); } void UdpBitDht::removeCallback(BitDhtCallback *cb) { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ mBitDhtManager->removeCallback(cb); } bool UdpBitDht::ConnectionRequest(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t delay, uint32_t start) { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ return mBitDhtManager->ConnectionRequest(laddr, target, mode, delay, start); } void UdpBitDht::ConnectionAuth(bdId *srcId, bdId *proxyId, bdId *destId, uint32_t mode, uint32_t loc, uint32_t bandwidth, uint32_t delay, uint32_t answer) { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ mBitDhtManager->ConnectionAuth(srcId, proxyId, destId, mode, loc, bandwidth, delay, answer); } void UdpBitDht::ConnectionOptions(uint32_t allowedModes, uint32_t flags) { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ mBitDhtManager->ConnectionOptions(allowedModes, flags); } bool UdpBitDht::setAttachMode(bool on) { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ return mBitDhtManager->setAttachMode(on); } int UdpBitDht::getDhtPeerAddress(const bdNodeId *id, struct sockaddr_in &from) { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ return mBitDhtManager->getDhtPeerAddress(id, from); } int UdpBitDht::getDhtValue(const bdNodeId *id, std::string key, std::string &value) { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ return mBitDhtManager->getDhtValue(id, key, value); } int UdpBitDht::getDhtBucket(const int idx, bdBucket &bucket) { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ return mBitDhtManager->getDhtBucket(idx, bucket); } int UdpBitDht::getDhtQueries(std::map &queries) { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ return mBitDhtManager->getDhtQueries(queries); } int UdpBitDht::getDhtQueryStatus(const bdNodeId *id, bdQuerySummary &query) { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ return mBitDhtManager->getDhtQueryStatus(id, query); } /* stats and Dht state */ int UdpBitDht:: startDht() { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ return mBitDhtManager->startDht(); } int UdpBitDht:: stopDht() { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ return mBitDhtManager->stopDht(); } int UdpBitDht::stateDht() { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ return mBitDhtManager->stateDht(); } uint32_t UdpBitDht::statsNetworkSize() { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ return mBitDhtManager->statsNetworkSize(); } uint32_t UdpBitDht::statsBDVersionSize() { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ return mBitDhtManager->statsBDVersionSize(); } uint32_t UdpBitDht::setDhtMode(uint32_t dhtFlags) { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ return mBitDhtManager->setDhtMode(dhtFlags); } /******************* Internals *************************/ /***** Iteration / Loop Management *****/ /*** Overloaded from UdpSubReceiver ***/ int UdpBitDht::recvPkt(void *data, int size, struct sockaddr_in &from) { /* pass onto bitdht */ bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ /* check packet suitability */ if (mBitDhtManager->isBitDhtPacket((char *) data, size, from)) { mReadBytes += size; mBitDhtManager->incomingMsg(&from, (char *) data, size); return 1; } return 0; } int UdpBitDht::status(std::ostream &out) { out << "UdpBitDht::status()" << std::endl; return 1; } void UdpBitDht::clearDataTransferred() { /* pass onto bitdht */ bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ mReadBytes = 0; mWriteBytes = 0; } void UdpBitDht::getDataTransferred(uint32_t &read, uint32_t &write) { { /* pass onto bitdht */ bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ read = mReadBytes; write = mWriteBytes; } clearDataTransferred(); } /*** Overloaded from iThread ***/ #define MAX_MSG_PER_TICK 100 #define TICK_PAUSE_USEC 20000 /* 20ms secs .. max messages = 50 x 100 = 5000 */ void UdpBitDht::run() { while(1) { while(tick()) { usleep(TICK_PAUSE_USEC); } { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ mBitDhtManager->iteration(); } sleep(1); } } int UdpBitDht::tick() { bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ /* pass on messages from the node */ int i = 0; char data[BITDHT_MAX_PKTSIZE]; struct sockaddr_in toAddr; int size = BITDHT_MAX_PKTSIZE; while((i < MAX_MSG_PER_TICK) && (mBitDhtManager->outgoingMsg(&toAddr, data, &size))) { #ifdef DEBUG_UDP_BITDHT std::cerr << "UdpBitDht::tick() outgoing msg(" << size << ") to " << toAddr; std::cerr << std::endl; #endif mWriteBytes += size; sendPkt(data, size, toAddr, BITDHT_TTL); // iterate i++; size = BITDHT_MAX_PKTSIZE; // reset msg size! } if (i == MAX_MSG_PER_TICK) { return 1; /* keep on ticking */ } return 0; }