--- Merging r4718 through r4752 from branches/v0.5-dhtmods

Added ZeroConf for OSX.
Changes for Relay Support.

Summary of Changes:
libbitdht
----------
 * added Relay Flags to bdNode::setNodeDhtMode()
 * added dropRelayServers() / pingRelayServers() functions for mode switches
 * added utility function:  bdFriendList::findPeersWithFlags()
 * added utility function:  bdSpace::clean_node_flags(uint32_t flags)
 * added RelayMode to ConnectManager.
 * added failedConnection callback when in Server Mode.
 * added incomplete udpproxylayer code. (not compiled)

libretroshare
-------------
 * added Configuration to p3BitDht for storing Relay Settings. (bit Hackish!)
 * added RelayHandler & getRelayReceiver() - to outsource some Relay functions.
 * + RelayHandler_InstallRelayConnection() & RelayHandler_LogFailedProxyAttempt()
 * added RelayServer, Mode and RelayAllowance to external DHT interface.
 * added p3PeerMgr::getGpgId() for ZeroConf usage.
 * updated parts of pqiassist virtual interfaces.
 * added Bandwidth storage to udprelay.
 * modified the way Relay Slots are allocated to match GUI interface.
 * ZeroConf now working on OSX.
 * added ZeroConf to OSX compilation.
 * extended rsDht interface to expose Relay configuration.

retroshare-gui
--------------
 * added Relay configuration panel.




git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@4753 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2012-01-06 15:33:51 +00:00
commit ac6f0fcfe4
35 changed files with 3620 additions and 113 deletions

View File

@ -86,6 +86,13 @@ void bdConnectManager::setConnectionOptions(uint32_t allowedModes, uint32_t flag
}
/* Setup Relay Mode */
void bdConnectManager::setRelayMode(uint32_t mode)
{
mRelayMode = mode;
}
void bdConnectManager::shutdownConnections()
{
#ifdef DEBUG_NODE_CONNECTION
@ -2085,6 +2092,15 @@ int bdConnectManager::recvedConnectionRequest(bdId *id, bdId *srcConnAddr, bdId
/* remove connection */
bdConnectManager::cleanConnectionBySender(id, srcConnAddr, destConnAddr);
/* WILL NEED CALLBACK FOR FAILED PROXY ATTEMPT - TO SUPPORT RELAYS PROPERLY
* NODE needs to know PEERS to potentially WHITELIST!
*/
if (mRelayMode == BITDHT_RELAYS_SERVER)
{
callbackConnect(&(conn->mSrcId),&(conn->mProxyId),&(conn->mDestId),
conn->mMode, conn->mPoint, param, BITDHT_CONNECT_CB_AUTH,
BITDHT_CONNECT_ERROR_NOADDRESS);
}
}
}
else

View File

@ -255,6 +255,9 @@ class bdConnectManager
int recvedConnectionStart(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode, int delayOrBandwidth);
int recvedConnectionAck(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode);
/* setup Relay Mode */
void setRelayMode(uint32_t mode);
private:
std::map<bdProxyTuple, bdConnection> mConnections;
@ -263,6 +266,8 @@ class bdConnectManager
uint32_t mConfigAllowedModes;
bool mConfigAutoProxy;
uint32_t mRelayMode;
/****************************** Connection Code (in bdconnection.cc) ****************************/
private:

View File

@ -159,6 +159,33 @@ bool bdFriendList::findPeerEntry(const bdNodeId *id, bdFriendEntry &entry)
}
bool bdFriendList::findPeersWithFlags(uint32_t flags, std::list<bdNodeId> &peerList)
{
#ifdef DEBUG_FRIENDLIST
std::cerr << "bdFriendList::findPeersWithFlags(" << flags << ")";
std::cerr << std::endl;
#endif
/* see if it exists... */
std::map<bdNodeId, bdFriendEntry>::iterator it;
for(it = mPeers.begin(); it != mPeers.end(); it++)
{
/* if they have ALL of the flags we specified */
if ((it->second.getPeerFlags() & flags) == flags)
{
#ifdef DEBUG_FRIENDLIST
std::cerr << "bdFriendList::findPeersWithFlags() Found: ";
bdStdPrintNodeId(std::cerr, id);
std::cerr << std::endl;
#endif
peerList.push_back(it->second.mPeerId.id);
}
}
return (peerList.size() > 0);
}
bool bdFriendList::print(std::ostream &out)
{
time_t now = time(NULL);

View File

@ -77,6 +77,7 @@ bool updatePeer(const bdId *id, uint32_t flags);
bool removePeer(const bdNodeId *id);
bool findPeerEntry(const bdNodeId *id, bdFriendEntry &entry);
bool findPeersWithFlags(uint32_t flags, std::list<bdNodeId> &peerList);
bool print(std::ostream &out);
private:

View File

@ -109,19 +109,20 @@ virtual void bdPrintNodeId(std::ostream &out, const bdNodeId *a) = 0;
// DHT MODES
#define BITDHT_MODE_TRAFFIC_MASK 0x00000f00
#define BITDHT_MODE_RELAY_MASK 0x0000f000
#define BITDHT_MODE_RELAYSERVER_MASK 0x0000f000
// These are not ORd - only one can apply.
#define BITDHT_MODE_TRAFFIC_DEFAULT 0x00000000
#define BITDHT_MODE_TRAFFIC_HIGH 0x00000100
#define BITDHT_MODE_TRAFFIC_MED 0x00000200
#define BITDHT_MODE_TRAFFIC_LOW 0x00000300
#define BITDHT_MODE_TRAFFIC_TRICKLE 0x00000400
#define BITDHT_MODE_TRAFFIC_DEFAULT BITDHT_MODE_TRAFFIC_LOW
// These are not ORd - only one can apply.
#define BITDHT_MODE_RELAYS_IGNORED 0x00000000
#define BITDHT_MODE_RELAYS_FLAGGED 0x00001000
#define BITDHT_MODE_RELAYS_ONLY 0x00002000
#define BITDHT_MODE_RELAYSERVERS_IGNORED 0x00001000
#define BITDHT_MODE_RELAYSERVERS_FLAGGED 0x00002000
#define BITDHT_MODE_RELAYSERVERS_ONLY 0x00003000
#define BITDHT_MODE_RELAYSERVERS_SERVER 0x00004000
/* NODE OPTIONS */
@ -303,9 +304,9 @@ class bdQuerySummary
/* Query Flags */
#define BITDHT_QFLAGS_NONE 0x0000
#define BITDHT_QFLAGS_DISGUISE 0x0001
#define BITDHT_QFLAGS_DISGUISE 0x0001 // Don't search directly for target.
#define BITDHT_QFLAGS_DO_IDLE 0x0002
#define BITDHT_QFLAGS_INTERNAL 0x0004 // runs through startup.
#define BITDHT_QFLAGS_INTERNAL 0x0004 // runs through startup. (limited callback)
#define BITDHT_QFLAGS_UPDATES 0x0008 // Do regular updates.
/* Connect Callback Flags */
@ -323,6 +324,12 @@ class bdQuerySummary
#define BITDHT_INFO_CB_TYPE_BADPEER 1
/* Relay Modes */
#define BITDHT_RELAYS_OFF 0
#define BITDHT_RELAYS_ON 1
#define BITDHT_RELAYS_ONLY 2
#define BITDHT_RELAYS_SERVER 3
class BitDhtCallback
{

View File

@ -111,46 +111,80 @@ void bdNode::setNodeOptions(uint32_t optFlags)
#define BDNODE_LOW_MSG_RATE 5
#define BDNODE_TRICKLE_MSG_RATE 3
/* So we are setting this up so you can independently update each parameter....
* if the mask is empty - it'll use the previous parameter.
*
*/
uint32_t bdNode::setNodeDhtMode(uint32_t dhtFlags)
{
std::cerr << "bdNode::setNodeDhtMode(" << dhtFlags << "), origFlags: " << mNodeDhtMode;
std::cerr << std::endl;
uint32_t origFlags = mNodeDhtMode;
mNodeDhtMode = dhtFlags;
uint32_t traffic = dhtFlags & BITDHT_MODE_TRAFFIC_MASK;
switch(traffic)
if (traffic)
{
default:
case BITDHT_MODE_TRAFFIC_DEFAULT:
case BITDHT_MODE_TRAFFIC_LOW:
mMaxAllowedMsgs = BDNODE_HIGH_MSG_RATE;
break;
case BITDHT_MODE_TRAFFIC_HIGH:
mMaxAllowedMsgs = BDNODE_LOW_MSG_RATE;
break;
case BITDHT_MODE_TRAFFIC_MED:
mMaxAllowedMsgs = BDNODE_MED_MSG_RATE;
break;
case BITDHT_MODE_TRAFFIC_TRICKLE:
mMaxAllowedMsgs = BDNODE_TRICKLE_MSG_RATE;
break;
switch(traffic)
{
default:
case BITDHT_MODE_TRAFFIC_LOW:
mMaxAllowedMsgs = BDNODE_HIGH_MSG_RATE;
break;
case BITDHT_MODE_TRAFFIC_HIGH:
mMaxAllowedMsgs = BDNODE_LOW_MSG_RATE;
break;
case BITDHT_MODE_TRAFFIC_MED:
mMaxAllowedMsgs = BDNODE_MED_MSG_RATE;
break;
case BITDHT_MODE_TRAFFIC_TRICKLE:
mMaxAllowedMsgs = BDNODE_TRICKLE_MSG_RATE;
break;
}
}
else
{
dhtFlags |= (origFlags & BITDHT_MODE_TRAFFIC_MASK);
}
uint32_t relay = dhtFlags & BITDHT_MODE_RELAY_MASK;
if (relay != (origFlags & BITDHT_MODE_RELAY_MASK))
uint32_t relay = dhtFlags & BITDHT_MODE_RELAYSERVER_MASK;
if ((relay) && (relay != (origFlags & BITDHT_MODE_RELAYSERVER_MASK)))
{
/* changed */
switch(relay)
{
default:
case BITDHT_MODE_RELAYS_IGNORED:
case BITDHT_MODE_RELAYSERVERS_IGNORED:
mRelayMode = BITDHT_RELAYS_OFF;
dropRelayServers();
break;
case BITDHT_MODE_RELAYS_FLAGGED:
case BITDHT_MODE_RELAYSERVERS_FLAGGED:
mRelayMode = BITDHT_RELAYS_ON;
pingRelayServers();
break;
case BITDHT_MODE_RELAYS_ONLY:
case BITDHT_MODE_RELAYSERVERS_ONLY:
mRelayMode = BITDHT_RELAYS_ONLY;
pingRelayServers();
break;
case BITDHT_MODE_RELAYSERVERS_SERVER:
mRelayMode = BITDHT_RELAYS_SERVER;
pingRelayServers();
break;
}
mConnMgr->setRelayMode(mRelayMode);
}
else
{
dhtFlags |= (origFlags & BITDHT_MODE_RELAYSERVER_MASK);
}
mNodeDhtMode = dhtFlags;
std::cerr << "bdNode::setNodeDhtMode() newFlags: " << mNodeDhtMode;
std::cerr << std::endl;
return dhtFlags;
}
@ -2206,5 +2240,55 @@ bdNodeNetMsg::~bdNodeNetMsg()
/**************** In/Out of Relay Mode ******************/
void bdNode::dropRelayServers()
{
/* We leave them there... just drop the flags */
uint32_t flags = BITDHT_PEER_STATUS_DHT_RELAY_SERVER;
std::list<bdNodeId> peerList;
std::list<bdNodeId>::iterator it;
mFriendList.findPeersWithFlags(flags, peerList);
for(it = peerList.begin(); it != peerList.end(); it++)
{
mFriendList.removePeer(&(*it));
}
mNodeSpace.clean_node_flags(flags);
}
void bdNode::pingRelayServers()
{
/* if Relay's have been switched on, do search/ping to locate servers */
std::cerr << "bdNode::pingRelayServers()";
std::cerr << std::endl;
bool doSearch = true;
uint32_t flags = BITDHT_PEER_STATUS_DHT_RELAY_SERVER;
std::list<bdNodeId> peerList;
std::list<bdNodeId>::iterator it;
mFriendList.findPeersWithFlags(flags, peerList);
for(it = peerList.begin(); it != peerList.end(); it++)
{
if (doSearch)
{
uint32_t qflags = BITDHT_QFLAGS_INTERNAL | BITDHT_QFLAGS_DISGUISE;
mQueryMgr->addQuery(&(*it), qflags);
std::cerr << "bdNode::pingRelayServers() Adding Internal Search for Relay Server: ";
mFns->bdPrintNodeId(std::cerr, &(*it));
std::cerr << std::endl;
}
else
{
/* try ping - if we have an address??? */
}
}
}

View File

@ -158,6 +158,9 @@ class bdNode: public bdNodePublisher
int outgoingMsg(struct sockaddr_in *addr, char *msg, int *len);
void incomingMsg(struct sockaddr_in *addr, char *msg, int len);
// For Relay Mode switching.
void dropRelayServers();
void pingRelayServers();
// Below is internal Management of incoming / outgoing messages.
private:
@ -251,7 +254,9 @@ void recvPkt(char *msg, int len, struct sockaddr_in addr);
uint32_t mNodeOptionFlags;
uint32_t mNodeDhtMode;
uint32_t mMaxAllowedMsgs;
uint32_t mRelayMode;
bdHistory mHistory; /* for understanding the DHT */

View File

@ -436,6 +436,39 @@ int bdSpace::find_exactnode(const bdId *id, bdPeer &peer)
}
int bdSpace::clean_node_flags(uint32_t flags)
{
std::cerr << "bdSpace::clean_node_flags(" << flags << ")";
std::cerr << std::endl;
int count = 0;
std::vector<bdBucket>::iterator bit;
for(bit = buckets.begin(); bit != buckets.end(); bit++)
{
std::list<bdPeer>::iterator eit;
for(eit = bit->entries.begin(); eit != bit->entries.end(); eit++)
{
if (flags & eit->mPeerFlags)
{
std::cerr << "bdSpace::clean_node_flags() Found Match: ";
mFns->bdPrintId(std::cerr, &(eit->mPeerId));
std::cerr << " withFlags: " << eit->mPeerFlags;
std::cerr << std::endl;
count++;
eit->mPeerFlags &= ~flags;
}
}
}
std::cerr << "bdSpace::clean_node_flags() Cleaned " << count << " Matching Peers";
std::cerr << std::endl;
return count;
}
#define BITDHT_ATTACHED_SEND_PERIOD 17
int bdSpace::scanOutOfDatePeers(std::list<bdId> &peerIds)

View File

@ -190,6 +190,9 @@ uint32_t calcSpaceSizeWithFlag(uint32_t withFlag);
/* special function to enable DHT localisation (i.e find peers from own network) */
bool findRandomPeerWithFlag(bdId &id, uint32_t withFlag);
/* strip out flags - to switch in/out of relay mode */
int clean_node_flags(uint32_t flags);
/* to add later */
int updateOwnId(bdNodeId *newOwnId);

View File

@ -0,0 +1,186 @@
#ifndef BITDHT_UDP_LAYER_H
#define BITDHT_UDP_LAYER_H
/*
* udp/udplayer.h
*
* BitDHT: An Flexible DHT library.
*
* Copyright 2004-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 "util/bdthreads.h"
#include "util/bdnet.h"
#include <iosfwd>
#include <list>
#include <deque>
/* careful - duplicate definitions */
//std::ostream &operator<<(std::ostream &out, const struct sockaddr_in &addr);
std::ostream &operator<<(std::ostream &out, struct sockaddr_in &addr);
bool operator==(const struct sockaddr_in &addr, const struct sockaddr_in &addr2);
bool operator<(const struct sockaddr_in &addr, const struct sockaddr_in &addr2);
std::string printPkt(void *d, int size);
std::string printPktOffset(unsigned int offset, void *d, unsigned int size);
/* UdpLayer ..... is the bottom layer which
* just sends and receives Udp packets.
*/
class UdpReceiver
{
public:
virtual ~UdpReceiver() {}
virtual int recvPkt(void *data, int size, struct sockaddr_in &from) = 0;
virtual int status(std::ostream &out) = 0;
};
class UdpPublisher
{
public:
virtual ~UdpPublisher() {}
virtual int sendPkt(const void *data, int size, const struct sockaddr_in &to, int ttl) = 0;
};
class UdpLayer: public bdThread
{
public:
UdpLayer(UdpReceiver *recv, struct sockaddr_in &local);
virtual ~UdpLayer() { return; }
int reset(struct sockaddr_in &local); /* calls join, close, openSocket */
int status(std::ostream &out);
/* setup connections */
int closeSocket();
int openSocket();
/* RsThread functions */
virtual void run(); /* called once the thread is started */
void recv_loop(); /* uses callback to UdpReceiver */
/* Higher Level Interface */
//int readPkt(void *data, int *size, struct sockaddr_in &from);
int sendPkt(const void *data, int size, const struct sockaddr_in &to, int ttl);
/* monitoring / updates */
int okay();
int tick();
/* data */
/* internals */
protected:
virtual int receiveUdpPacket(void *data, int *size, struct sockaddr_in &from);
virtual int sendUdpPacket(const void *data, int size, const struct sockaddr_in &to);
int setTTL(int t);
int getTTL();
/* low level */
private:
UdpReceiver *recv;
struct sockaddr_in laddr; /* local addr */
int errorState;
int sockfd;
int ttl;
bool stopThread;
bdMutex sockMtx;
};
/* For Testing - drops packets */
class LossyUdpLayer: public UdpLayer
{
public:
LossyUdpLayer(UdpReceiver *udpr, struct sockaddr_in &local, double frac);
virtual ~LossyUdpLayer();
protected:
virtual int receiveUdpPacket(void *data, int *size, struct sockaddr_in &from);
virtual int sendUdpPacket(const void *data, int size, const struct sockaddr_in &to);
double lossFraction;
};
class PortRange
{
public:
PortRange();
PortRange(uint16_t lp, uint16_t up);
bool inRange(uint16_t port);
uint16_t lport;
uint16_t uport;
};
/* For Testing - drops packets */
class RestrictedUdpLayer: public UdpLayer
{
public:
RestrictedUdpLayer(UdpReceiver *udpr, struct sockaddr_in &local);
virtual ~RestrictedUdpLayer();
void addRestrictedPortRange(int lp, int up);
protected:
virtual int receiveUdpPacket(void *data, int *size, struct sockaddr_in &from);
virtual int sendUdpPacket(const void *data, int size, const struct sockaddr_in &to);
std::list<PortRange> mLostPorts;
};
/* For Testing - drops packets all packets for initial minute (simulates TTL) */
class TimedUdpLayer: public UdpLayer
{
public:
TimedUdpLayer(UdpReceiver *udpr, struct sockaddr_in &local);
virtual ~TimedUdpLayer();
protected:
virtual int receiveUdpPacket(void *data, int *size, struct sockaddr_in &from);
virtual int sendUdpPacket(const void *data, int size, const struct sockaddr_in &to);
time_t mStartTime;
bool mActive;
};
#endif

View File

@ -83,7 +83,7 @@ virtual int dhtInfoCallback(const bdId *id, uint32_t type, uint32_t flags, std::
p3BitDht::p3BitDht(std::string id, pqiConnectCb *cb, p3NetMgr *nm,
UdpStack *udpstack, std::string bootstrapfile)
:pqiNetAssistConnect(id, cb), mNetMgr(nm), dhtMtx("p3BitDht")
:p3Config(CONFIG_TYPE_BITDHT), pqiNetAssistConnect(id, cb), mNetMgr(nm), dhtMtx("p3BitDht")
{
mDhtStunner = NULL;
mProxyStunner = NULL;
@ -91,6 +91,8 @@ p3BitDht::p3BitDht(std::string id, pqiConnectCb *cb, p3NetMgr *nm,
mPeerSharer = NULL;
mRelayHandler = NULL;
std::string dhtVersion = "RS51"; // should come from elsewhere!
mOwnRsId = id;
@ -131,6 +133,7 @@ p3BitDht::p3BitDht(std::string id, pqiConnectCb *cb, p3NetMgr *nm,
p3BdCallback *bdcb = new p3BdCallback(this);
mUdpBitDht->addCallback(bdcb);
#if 0
/* enable all modes */
/* Switched to only Proxy Mode - as Direct Connections can be unreliable - as they share the UDP with the DHT....
* We'll get these working properly and then if necessary get Direct further tested.
@ -141,6 +144,9 @@ p3BitDht::p3BitDht(std::string id, pqiConnectCb *cb, p3NetMgr *nm,
BITDHT_CONNECT_MODE_PROXY,
BITDHT_CONNECT_OPTION_AUTOPROXY);
#endif
setupRelayDefaults();
}
p3BitDht::~p3BitDht()
@ -162,6 +168,23 @@ void p3BitDht::setupPeerSharer(pqiNetAssistPeerShare *sharer)
mPeerSharer = sharer;
}
/* Support for Outsourced Relay Handling */
void p3BitDht::installRelayHandler(p3BitDhtRelayHandler *handler)
{
/* The Handler is mutex protected, as its installation can occur when the dht is already running */
RsStackMutex stack(dhtMtx); /********* LOCKED *********/
mRelayHandler = handler;
}
UdpRelayReceiver *p3BitDht::getRelayReceiver()
{
return mRelay;
}
void p3BitDht::start()
{
#ifdef DEBUG_BITDHT

View File

@ -28,6 +28,7 @@
#define MRK_P3_BITDHT_H
#include "pqi/pqiassist.h"
#include "pqi/p3cfgmgr.h"
#include "retroshare/rsdht.h"
#include <string>
@ -118,12 +119,27 @@ class PeerAction
/******
* Adding the ability to install alternative Handler
* for monitoring/controlling Relay Connections outside of p3bitdht.
***/
class p3BitDhtRelayHandler
{
public:
int (*mInstallRelay)(const bdId *srcId, const bdId *destId, uint32_t mode, uint32_t &bandwidth);
int (*mLogFailedConnection)(const bdId *srcId, const bdId *destId, uint32_t mode, uint32_t errcode);
};
class UdpRelayReceiver;
class UdpStunner;
class p3NetMgr;
class p3BitDht: public pqiNetAssistConnect, public RsDht
class p3BitDht: public p3Config, public pqiNetAssistConnect, public RsDht
{
public:
p3BitDht(std::string id, pqiConnectCb *cb, p3NetMgr *nm,
@ -149,6 +165,7 @@ virtual int getRelayProxies(std::list<RsDhtRelayProxy> &relayProxies);
virtual std::string getUdpAddressString();
/***********************************************************************************************
********** External RsDHT Interface (defined in libretroshare/src/retroshare/rsdht.h) *********
************************************************************************************************/
@ -251,19 +268,61 @@ void UdpConnectionFailed_locked(DhtPeerDetails *dpd);
void ReleaseProxyExclusiveMode_locked(DhtPeerDetails *dpd, bool addrChgLikely);
/*** RELAY HANDLER CODE ***/
void installRelayHandler(p3BitDhtRelayHandler *);
UdpRelayReceiver *getRelayReceiver();
int RelayHandler_InstallRelayConnection(const bdId *srcId, const bdId *destId, uint32_t mode, uint32_t &bandwidth);
int RelayHandler_LogFailedProxyAttempt(const bdId *srcId, const bdId *destId, uint32_t mode, uint32_t errcode);
/***********************************************************************************************
******************** Relay Config Stuff (TEMP - MOSTLY, in p3bitdht_relay.cc) *****************
********** External RsDHT Interface (defined in libretroshare/src/retroshare/rsdht.h) *********
************************************************************************************************/
// Interface for controlling Relays & DHT Relay Mode
virtual int getRelayServerList(std::list<std::string> &ids);
virtual int addRelayServer(std::string ids);
virtual int removeRelayServer(std::string ids);
virtual uint32_t getRelayMode();
virtual int setRelayMode(uint32_t mode);
virtual int getRelayAllowance(int classIdx, uint32_t &count, uint32_t &bandwidth);
virtual int setRelayAllowance(int classIdx, uint32_t count, uint32_t bandwidth);
private:
// Relay Handling Code / Variables (Mutex Protected).
int setupRelayDefaults();
int pushRelayServers();
std::list<std::string> mRelayServerList;
uint32_t mRelayMode;
protected:
/*****************************************************************/
/*********************** p3config ******************************/
/* Key Functions to be overloaded for Full Configuration */
virtual RsSerialiser *setupSerialiser();
virtual bool saveList(bool &cleanup, std::list<RsItem *>&);
virtual void saveDone();
virtual bool loadList(std::list<RsItem *>& load);
/*****************************************************************/
/***********************************************************************************************
************************** Internal Accounting (p3bitdht_peers.cc) ****************************
************************************************************************************************/
public:
//bool findPeer(std::string pid)
//bool dropPeer(std::string pid);
//int addFriend(const std::string pid);
//int addFriendOfFriend(const std::string pid);
//int addOther(const std::string pid);
int removePeer(const std::string pid);
// Can be used externally too.
int calculateNodeId(const std::string pid, bdNodeId *id);
private:
DhtPeerDetails *addInternalPeer_locked(const std::string pid, int type);
@ -276,7 +335,6 @@ int lookupNodeId_locked(const std::string pid, bdNodeId *id);
int lookupRsId_locked(const bdNodeId *id, std::string &pid);
int storeTranslation_locked(const std::string pid);
int removeTranslation_locked(const std::string pid);
int calculateNodeId(const std::string pid, bdNodeId *id);
UdpBitDht *mUdpBitDht; /* has own mutex, is static except for creation/destruction */
UdpStunner *mDhtStunner;
@ -289,6 +347,9 @@ int calculateNodeId(const std::string pid, bdNodeId *id);
RsMutex dhtMtx;
p3BitDhtRelayHandler *mRelayHandler;
std::string mOwnRsId;
bdNodeId mOwnDhtId;

View File

@ -198,7 +198,6 @@ std::string p3BitDht::getUdpAddressString()
********** External RsDHT Interface (defined in libretroshare/src/retroshare/rsdht.h) *********
************************************************************************************************/
void convertBdPeerToRsDhtPeer(RsDhtPeer &peer, const bdPeer &int_peer)
{
std::ostringstream out;

View File

@ -516,6 +516,13 @@ int p3BitDht::ConnectCallback(const bdId *srcId, const bdId *proxyId, const bdId
bdStdPrintId(std::cerr, destId);
std::cerr << std::endl;
#endif
/* if there is an error code - then it is just to inform us of a failed attempt */
if (errcode)
{
RelayHandler_LogFailedProxyAttempt(srcId, destId, mode, errcode);
/* END MID FAILED ATTEMPT */
return 1;
}
uint32_t bandwidth = 0;
@ -1622,7 +1629,7 @@ int p3BitDht::checkProxyAllowed(const bdId *srcId, const bdId *destId, int mode,
/* will install the Relay Here... so that we reserve the Relay Space for later.
* decide on relay bandwidth limitation as well
*/
if (installRelayConnection(srcId, destId, bandwidth))
if (RelayHandler_InstallRelayConnection(srcId, destId, mode, bandwidth))
{
#ifdef DEBUG_PEERNET
std::cerr << "p3BitDht::checkProxyAllowed() Successfully added Relay, Connection OKAY";
@ -2385,4 +2392,43 @@ void p3BitDht::ConnectionFeedback(std::string pid, int mode)
}
/***** Check for a RelayHandler... and call its functions preferentially */
int p3BitDht::RelayHandler_LogFailedProxyAttempt(const bdId *srcId, const bdId *destId, uint32_t mode, uint32_t errcode)
{
{
RsStackMutex stack(dhtMtx); /********* LOCKED *********/
if ((mRelayHandler) && (mRelayHandler->mLogFailedConnection))
{
return mRelayHandler->mLogFailedConnection(srcId, destId, mode, errcode);
}
}
/* NO standard handler */
return 0;
}
int p3BitDht::RelayHandler_InstallRelayConnection(const bdId *srcId, const bdId *destId,
uint32_t mode, uint32_t &bandwidth)
{
{
RsStackMutex stack(dhtMtx); /********* LOCKED *********/
if ((mRelayHandler) && (mRelayHandler->mInstallRelay))
{
return mRelayHandler->mInstallRelay(srcId, destId, mode, bandwidth);
}
}
/* standard handler */
return installRelayConnection(srcId, destId, bandwidth);
}

View File

@ -0,0 +1,415 @@
/*
* libretroshare/src/dht: p3bitdht.h
*
* BitDht interface for RetroShare.
*
* Copyright 2009-2011 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 2 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 "retroshare@lunamutt.com".
*
*/
#include "util/rsnet.h"
#include "dht/p3bitdht.h"
#include "tcponudp/udprelay.h"
#include "bitdht/bdstddht.h"
#include "serialiser/rsconfigitems.h"
/***********************************************************************************************
********** External RsDHT Interface for Dht-Relay Control *************************************
************************************************************************************************/
int p3BitDht::setupRelayDefaults()
{
//uint32_t mode = RSDHT_RELAY_ENABLED | RSDHT_RELAY_MODE_OFF;
uint32_t mode = RSDHT_RELAY_MODE_OFF;
setRelayMode(mode);
return 1;
}
/**** THIS IS A TEMPORARY HACK INTERFACE - UNTIL WE HAVE MORE SOFISTICATED SYSTEM
* NB: using bdNodeIds here, rather than SSL IDS.
*****/
int p3BitDht::getRelayServerList(std::list<std::string> &ids)
{
RsStackMutex stack(dhtMtx); /*********** LOCKED **********/
ids = mRelayServerList;
return 1;
}
int p3BitDht::addRelayServer(std::string id)
{
RsStackMutex stack(dhtMtx); /*********** LOCKED **********/
std::list<std::string>::iterator it;
it = std::find(mRelayServerList.begin(), mRelayServerList.end(), id);
if (it == mRelayServerList.end())
{
mRelayServerList.push_back(id);
}
IndicateConfigChanged();
return 1;
}
int p3BitDht::removeRelayServer(std::string id)
{
RsStackMutex stack(dhtMtx); /*********** LOCKED **********/
std::list<std::string>::iterator it;
it = std::find(mRelayServerList.begin(), mRelayServerList.end(), id);
if (it != mRelayServerList.end())
{
mRelayServerList.erase(it);
}
IndicateConfigChanged();
return 1;
}
int p3BitDht::pushRelayServers()
{
std::list<std::string> servers;
{
RsStackMutex stack(dhtMtx); /*********** LOCKED **********/
servers = mRelayServerList;
}
std::list<std::string>::iterator it;
for(it = servers.begin(); it != servers.end(); it++)
{
/* push it to dht */
uint32_t bdflags = BITDHT_PEER_STATUS_DHT_RELAY_SERVER;
bdId id;
bdStdLoadNodeId(&(id.id), *it);
mUdpBitDht->updateKnownPeer(&id, 0, bdflags);
}
return 1;
}
uint32_t p3BitDht::getRelayMode()
{
RsStackMutex stack(dhtMtx); /*********** LOCKED **********/
return mRelayMode;
}
int p3BitDht::setRelayMode(uint32_t mode)
{
if (mode & RSDHT_RELAY_ENABLED)
{
mUdpBitDht->ConnectionOptions(
BITDHT_CONNECT_MODE_DIRECT | BITDHT_CONNECT_MODE_PROXY | BITDHT_CONNECT_MODE_RELAY,
BITDHT_CONNECT_OPTION_AUTOPROXY);
}
else
{
mUdpBitDht->ConnectionOptions(
BITDHT_CONNECT_MODE_DIRECT | BITDHT_CONNECT_MODE_PROXY,
BITDHT_CONNECT_OPTION_AUTOPROXY);
}
int relaymode = mode & RSDHT_RELAY_MODE_MASK;
switch(relaymode)
{
case RSDHT_RELAY_MODE_OFF:
mUdpBitDht->setDhtMode(BITDHT_MODE_RELAYSERVERS_IGNORED);
break;
case RSDHT_RELAY_MODE_ON:
pushRelayServers();
mUdpBitDht->setDhtMode(BITDHT_MODE_RELAYSERVERS_FLAGGED);
break;
case RSDHT_RELAY_MODE_SERVER:
pushRelayServers();
mUdpBitDht->setDhtMode(BITDHT_MODE_RELAYSERVERS_SERVER);
break;
}
{
RsStackMutex stack(dhtMtx); /*********** LOCKED **********/
mRelayMode = mode;
}
IndicateConfigChanged();
return 1;
}
int p3BitDht::getRelayAllowance(int classIdx, uint32_t &count, uint32_t &bandwidth)
{
std::cerr << "p3BitDht::getRelayAllowance(" << classIdx << "): ";
if ((classIdx >= 0) && (classIdx < RSDHT_RELAY_NUM_CLASS))
{
count = mRelay->getRelayClassMax(classIdx);
bandwidth = mRelay->getRelayClassBandwidth(classIdx);
std::cerr << " count: " << count << " bandwidth: " << bandwidth;
std::cerr << std::endl;
return 1;
}
std::cerr << " Invalid classIdx";
std::cerr << std::endl;
return 0;
}
int p3BitDht::setRelayAllowance(int classIdx, uint32_t count, uint32_t bandwidth)
{
std::cerr << "p3BitDht::getRelayAllowance(" << classIdx << ", ";
std::cerr << ", " << count << ", " << bandwidth << ")";
std::cerr << std::endl;
int retval = mRelay->setRelayClassMax(classIdx, count, bandwidth);
IndicateConfigChanged();
return retval;
}
/***********************************************************************************************
********** External RsDHT Interface for Dht-Relay Control *************************************
************************************************************************************************/
/*****************************************************************/
/*********************** p3config ******************************/
/* Key Functions to be overloaded for Full Configuration */
RsSerialiser *p3BitDht::setupSerialiser()
{
RsSerialiser *rss = new RsSerialiser ;
rss->addSerialType(new RsGeneralConfigSerialiser());
return rss ;
}
bool p3BitDht::saveList(bool &cleanup, std::list<RsItem *> &saveList)
{
cleanup = true;
std::cerr << "p3BitDht::saveList()";
std::cerr << std::endl;
RsStackMutex stack(dhtMtx); /*********** LOCKED **********/
RsConfigKeyValueSet *config = new RsConfigKeyValueSet();
RsTlvKeyValue kv;
/* Push Relay Class Stuff */
int i;
for(i = 0; i < RSDHT_RELAY_NUM_CLASS; i++)
{
std::ostringstream keyout;
keyout << "RELAY_CLASS" << i;
std::string countkey = keyout.str() + "_COUNT";
std::string bandkey = keyout.str() + "_BANDWIDTH";
std::ostringstream countout;
std::ostringstream bandout;
countout << mRelay->getRelayClassMax(i);
bandout << mRelay->getRelayClassBandwidth(i);
kv.key = countkey;
kv.value = countout.str();
config->tlvkvs.pairs.push_back(kv);
kv.key = bandkey;
kv.value = bandout.str();
config->tlvkvs.pairs.push_back(kv);
}
/* add RelayMode */
{
std::ostringstream out;
out << mRelayMode;
kv.key = "RELAY_MODE";
kv.value = out.str();
config->tlvkvs.pairs.push_back(kv);
}
/* add Servers */
std::list<std::string>::iterator it;
for(i = 0, it = mRelayServerList.begin(); it != mRelayServerList.end(); it++, i++)
{
std::ostringstream key;
key << "RELAY_SERVER" << i;
kv.key = key.str();
kv.value = *it;
config->tlvkvs.pairs.push_back(kv);
}
std::cerr << "BITDHT Save Item:";
std::cerr << std::endl;
config->print(std::cerr, 0);
saveList.push_back(config);
return true;
}
void p3BitDht::saveDone()
{
return;
}
bool p3BitDht::loadList(std::list<RsItem *>& load)
{
std::cerr << "p3BitDht::loadList()";
std::cerr << std::endl;
if ((load.size() == 0) || (load.size() > 1))
{
/* error */
std::cerr << "p3BitDht::loadList() Error only expecting 1 item";
std::cerr << std::endl;
return false;
}
RsItem *item = load.front();
RsConfigKeyValueSet *config = dynamic_cast<RsConfigKeyValueSet *>(item);
if (!config)
{
/* error */
std::cerr << "p3BitDht::loadList() Error expecting item = config";
std::cerr << std::endl;
return false;
}
std::cerr << "BITDHT Load Item:";
std::cerr << std::endl;
config->print(std::cerr, 0);
std::list<std::string> servers;
int peers[RSDHT_RELAY_NUM_CLASS] = {0};
int bandwidth[RSDHT_RELAY_NUM_CLASS] = {0};
bool haveMode = false;
int mode = 0;
std::list<RsTlvKeyValue>::iterator it;
for(it = config->tlvkvs.pairs.begin(); it != config->tlvkvs.pairs.end(); it++)
{
std::string key = it->key;
std::string value = it->value;
if (0 == strncmp(key.c_str(), "RELAY_SERVER", 12))
{
/* add to RELAY_SERVER List */
servers.push_back(value);
std::cerr << "p3BitDht::loadList() Found Server: " << value;
std::cerr << std::endl;
}
else if (0 == strncmp(key.c_str(), "RELAY_MODE", 10))
{
mode = atoi(value.c_str());
haveMode = true;
std::cerr << "p3BitDht::loadList() Found Mode: " << mode;
std::cerr << std::endl;
}
else if (0 == strncmp(key.c_str(), "RELAY_CLASS", 11))
{
/* len check */
if (key.length() < 14)
continue;
int idx = 0;
uint32_t val = atoi(value.c_str());
switch(key[11])
{
default:
case '0':
idx = 0;
break;
case '1':
idx = 1;
break;
case '2':
idx = 2;
break;
case '3':
idx = 3;
break;
}
if (key[13] == 'C')
{
std::cerr << "p3BitDht::loadList() Found Count(" << idx << "): ";
std::cerr << val;
std::cerr << std::endl;
peers[idx] = val;
}
else
{
std::cerr << "p3BitDht::loadList() Found Bandwidth(" << idx << "): ";
std::cerr << val;
std::cerr << std::endl;
bandwidth[idx] = val;
}
}
else
{
std::cerr << "p3BitDht::loadList() Unknown Key:value: " << key;
std::cerr << ":" << value;
std::cerr << std::endl;
}
}
// Cleanup config.
delete config;
{
RsStackMutex stack(dhtMtx); /*********** LOCKED **********/
mRelayServerList = servers;
}
int i;
for(i = 0; i < RSDHT_RELAY_NUM_CLASS; i++)
{
mRelay->setRelayClassMax(i, peers[i], bandwidth[i]);
}
if (haveMode)
{
setRelayMode(mode);
}
return true;
}
/*****************************************************************/

View File

@ -74,6 +74,7 @@ SOURCES += dht/p3bitdht.cc \
dht/p3bitdht_interface.cc \
dht/p3bitdht_peers.cc \
dht/p3bitdht_peernet.cc \
dht/p3bitdht_relay.cc \
dht/connectstatebox.cc
HEADERS += tcponudp/udppeer.h \
@ -108,6 +109,7 @@ SOURCES += tcponudp/udppeer.cc \
}
test_bitdht {
# DISABLE TCP CONNECTIONS...
DEFINES *= P3CONNMGR_NO_TCP_CONNECTIONS
@ -121,7 +123,6 @@ test_bitdht {
use_blogs {
HEADERS += services/p3blogs.h
@ -307,6 +308,8 @@ mac {
HEADERS += upnp/upnputil.h
SOURCES += upnp/upnputil.c
CONFIG += zeroconf
# Beautiful Hack to fix 64bit file access.
QMAKE_CXXFLAGS *= -Dfseeko64=fseeko -Dftello64=ftello -Dfopen64=fopen -Dvstatfs64=vstatfs
@ -638,3 +641,14 @@ minimal {
services/p3gamelauncher.cc \
services/p3photoservice.cc
}
zeroconf {
HEADERS += zeroconf/p3zeroconf.h \
SOURCES += zeroconf/p3zeroconf.cc \
DEFINES *= RS_ENABLE_ZEROCONF
}

View File

@ -86,11 +86,16 @@ const uint32_t CONFIG_TYPE_HISTORY = 0x0015;
/// turtle router
const uint32_t CONFIG_TYPE_TURTLE = 0x0020;
/// dht (relay stuff mainly)
const uint32_t CONFIG_TYPE_BITDHT = 0x0030;
/* standard services */
const uint32_t CONFIG_TYPE_QBLOG = 0x0101;
const uint32_t CONFIG_TYPE_FORUMS = 0x0102;
const uint32_t CONFIG_TYPE_CHANNELS = 0x0103;
/* CACHE ID Must be at the END so that other configurations
* are loaded First (Cache Config --> Cache Loading)
*/

View File

@ -255,6 +255,22 @@ bool p3PeerMgrIMPL::getPeerName(const std::string &ssl_id, std::string &name)
return true;
}
bool p3PeerMgrIMPL::getGpgId(const std::string &ssl_id, std::string &gpgId)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
/* check for existing */
std::map<std::string, peerState>::iterator it;
it = mFriendList.find(ssl_id);
if (it == mFriendList.end())
{
return false;
}
gpgId = it->second.gpg_id;
return true;
}
bool p3PeerMgrIMPL::getFriendNetStatus(const std::string &id, peerState &state)

View File

@ -182,6 +182,7 @@ virtual bool getFriendNetStatus(const std::string &id, peerState &state) = 0;
virtual bool getOthersNetStatus(const std::string &id, peerState &state) = 0;
virtual bool getPeerName(const std::string &ssl_id, std::string &name) = 0;
virtual bool getGpgId(const std::string &sslId, std::string &gpgId) = 0;
/************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/
@ -266,6 +267,7 @@ virtual bool getFriendNetStatus(const std::string &id, peerState &state);
virtual bool getOthersNetStatus(const std::string &id, peerState &state);
virtual bool getPeerName(const std::string &ssl_id, std::string &name);
virtual bool getGpgId(const std::string &sslId, std::string &gpgId);
/************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/

View File

@ -146,26 +146,17 @@ virtual bool dropPeer(std::string id) = 0;
virtual int addBadPeer(const struct sockaddr_in &addr, uint32_t reason, uint32_t flags, uint32_t age) = 0;
virtual int addKnownPeer(const std::string &pid, const struct sockaddr_in &addr, uint32_t flags) = 0;
//virtual int addFriend(const std::string pid) = 0;
//virtual int addFriendOfFriend(const std::string pid) = 0;
//virtual int addOther(const std::string pid) = 0;
virtual void ConnectionFeedback(std::string pid, int mode) = 0;
/* extract current peer status */
virtual bool getPeerStatus(std::string id,
struct sockaddr_in &laddr, struct sockaddr_in &raddr,
uint32_t &type, uint32_t &mode) = 0;
uint32_t &type, uint32_t &mode) = 0; // DEPRECIATE.
virtual bool setAttachMode(bool on) = 0;
//virtual bool getExternalInterface(struct sockaddr_in &raddr,
// uint32_t &mode) = 0;
virtual bool setAttachMode(bool on) = 0; // FIXUP.
/***** Stats for Network / DHT *****/
virtual bool getNetworkStats(uint32_t &netsize, uint32_t &localnetsize) = 0;
virtual bool getNetworkStats(uint32_t &netsize, uint32_t &localnetsize) = 0; // DEPRECIATE.
protected:
std::string mPeerId;

View File

@ -71,6 +71,22 @@ extern RsDht *rsDht;
#define RSDHT_TOU_MODE_RELAY 3
#define RSDHT_RELAY_NUM_CLASS 4
#define RSDHT_RELAY_CLASS_ALL 0
#define RSDHT_RELAY_CLASS_GENERAL 1
#define RSDHT_RELAY_CLASS_FOF 2
#define RSDHT_RELAY_CLASS_FRIENDS 3
#define RSDHT_RELAY_MODE_MASK 0x00f0
#define RSDHT_RELAY_ENABLED 0x0001
#define RSDHT_RELAY_MODE_OFF 0x0010
#define RSDHT_RELAY_MODE_ON 0x0020
#define RSDHT_RELAY_MODE_SERVER 0x0040
class RsDhtPeer
{
@ -96,26 +112,18 @@ class RsDhtNetPeer
std::string mRsId;
uint32_t mPeerType;
uint32_t mDhtState;
//connectLogic.
std::string mConnectState;
// connect Status
uint32_t mPeerConnectState;
// connect mode
uint32_t mPeerConnectMode;
std::string mConnectState; // connectLogic.
uint32_t mPeerConnectState; // connect Status
uint32_t mPeerConnectMode; // connect mode
bool mExclusiveProxyLock;
std::string mPeerConnectProxyId;
// Req Status.
uint32_t mPeerReqState;
// Peer Cb Mgs.
std::string mCbPeerMsg;
uint32_t mPeerReqState; // Req Status.
std::string mCbPeerMsg; // Peer Cb Mgs.
};
@ -168,6 +176,19 @@ virtual int getRelayProxies(std::list<RsDhtRelayProxy> &relayProxies) = 0;
virtual std::string getUdpAddressString() = 0;
// Interface for controlling Relays & DHT Relay Mode
virtual int getRelayServerList(std::list<std::string> &ids) = 0;
virtual int addRelayServer(std::string ids) = 0;
virtual int removeRelayServer(std::string ids) = 0;
virtual uint32_t getRelayMode() = 0;
virtual int setRelayMode(uint32_t mode) = 0;
virtual int getRelayAllowance(int classIdx, uint32_t &count, uint32_t &bandwidth) = 0;
virtual int setRelayAllowance(int classIdx, uint32_t count, uint32_t bandwidth) = 0;
#if 0
virtual std::string getPeerStatusString();
virtual std::string getDhtStatusString();

View File

@ -1715,8 +1715,12 @@ RsTurtle *rsTurtle = NULL ;
#include "util/rsdir.h"
#include "util/rsrandom.h"
#include "upnp/upnphandler.h"
//#include "dht/opendhtmgr.h"
#ifdef RS_ENABLE_ZEROCONF
#include "zeroconf/p3zeroconf.h"
//#include "zeroconf/p3zcnatassist.h"
#else
#include "upnp/upnphandler.h"
#endif
#include "services/p3disc.h"
#include "services/p3msgservice.h"
@ -1879,7 +1883,6 @@ int RsServer::StartupRetroShare()
// for (std::list<std::string>::iterator sslIdsIt = sslIds.begin(); sslIdsIt != sslIds.end(); sslIdsIt++) {
// mConnMgr->addFriend(*sslIdsIt);
// }
pqiNetAssistFirewall *mUpnpMgr = new upnphandler();
//p3DhtMgr *mDhtMgr = new OpenDHTMgr(ownId, mConnMgr, RsInitConfig::configDir);
/**************************** BITDHT ***********************************/
@ -2168,7 +2171,23 @@ int RsServer::StartupRetroShare()
mNetMgr->addNetListener(mProxyStack);
#endif
#ifdef RS_ENABLE_ZEROCONF
p3ZeroConf *mZeroConf = new p3ZeroConf(
AuthGPG::getAuthGPG()->getGPGOwnId(), ownId,
mLinkMgr, mNetMgr, mPeerMgr);
mNetMgr->addNetAssistConnect(2, mZeroConf);
mNetMgr->addNetListener(mZeroConf);
// Apple's UPnP & NAT-PMP assistance.
//p3zcNatAssist *mZcNatAssist = new p3zcNatAssist();
//mNetMgr->addNetAssistFirewall(2, mZcNatAssist);
#else
// Original UPnP Interface.
pqiNetAssistFirewall *mUpnpMgr = new upnphandler();
mNetMgr->addNetAssistFirewall(1, mUpnpMgr);
#endif
/**************************************************************************/
/* need to Monitor too! */
@ -2211,6 +2230,10 @@ int RsServer::StartupRetroShare()
mConfigMgr->addConfiguration("turtle.cfg", tr);
mConfigMgr->addConfiguration("p3disc.cfg", ad);
#ifdef RS_USE_BITDHT
mConfigMgr->addConfiguration("bitdht.cfg", mBitDht);
#endif
mPluginsManager->addConfigurations(mConfigMgr) ;
ftserver->addConfiguration(mConfigMgr);

View File

@ -49,14 +49,17 @@ UdpRelayReceiver::UdpRelayReceiver(UdpPublisher *pub)
{
mClassLimit.resize(UDP_RELAY_NUM_CLASS);
mClassCount.resize(UDP_RELAY_NUM_CLASS);
mClassBandwidth.resize(UDP_RELAY_NUM_CLASS);
setRelayTotal(UDP_RELAY_DEFAULT_COUNT_ALL);
for(int i = 0; i < UDP_RELAY_NUM_CLASS; i++)
{
mClassCount[i] = 0;
mClassBandwidth[i] = 0;
}
setRelayTotal(UDP_RELAY_DEFAULT_COUNT_ALL);
/* only allocate this space once */
mTmpSendPkt = malloc(MAX_RELAY_UDP_PACKET_SIZE);
mTmpSendSize = MAX_RELAY_UDP_PACKET_SIZE;
@ -279,7 +282,7 @@ int UdpRelayReceiver::removeUdpRelay(UdpRelayAddrSet *addrSet)
}
int UdpRelayReceiver::addUdpRelay(UdpRelayAddrSet *addrSet, int relayClass, uint32_t &bandwidth)
int UdpRelayReceiver::addUdpRelay(UdpRelayAddrSet *addrSet, int &relayClass, uint32_t &bandwidth)
{
RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/
@ -288,22 +291,22 @@ int UdpRelayReceiver::addUdpRelay(UdpRelayAddrSet *addrSet, int relayClass, uint
int ok = (rit == mRelays.end());
if (!ok)
{
//#ifdef DEBUG_UDP_RELAY
#ifdef DEBUG_UDP_RELAY
std::cerr << "UdpRelayReceiver::addUdpRelay() ERROR Peer already exists!" << std::endl;
//#endif
#endif
return 0;
}
/* will install if there is space! */
if (installRelayClass_relayLocked(relayClass))
if (installRelayClass_relayLocked(relayClass, bandwidth))
{
//#ifdef DEBUG_UDP_RELAY
#ifdef DEBUG_UDP_RELAY
std::cerr << "UdpRelayReceiver::addUdpRelay() adding Relay" << std::endl;
//#endif
#endif
/* create UdpRelay */
UdpRelayProxy udpRelay(addrSet, relayClass);
UdpRelayProxy udpRelay(addrSet, relayClass, bandwidth);
UdpRelayAddrSet alt = addrSet->flippedSet();
UdpRelayProxy altUdpRelay(&alt, relayClass);
UdpRelayProxy altUdpRelay(&alt, relayClass, bandwidth);
/* must install two (A, B) & (B, A) */
mRelays[*addrSet] = udpRelay;
@ -315,9 +318,9 @@ int UdpRelayReceiver::addUdpRelay(UdpRelayAddrSet *addrSet, int relayClass, uint
return 1;
}
//#ifdef DEBUG_UDP_RELAY
#ifdef DEBUG_UDP_RELAY
std::cerr << "UdpRelayReceiver::addUdpRelay() WARNING Too many Relays!" << std::endl;
//#endif
#endif
return 0;
}
@ -359,8 +362,11 @@ int UdpRelayReceiver::removeUdpRelay_relayLocked(UdpRelayAddrSet *addrSet)
return 1;
}
/* Need some stats, to work out how many relays we are supporting */
int UdpRelayReceiver::installRelayClass_relayLocked(int classIdx)
/* Need some stats, to work out how many relays we are supporting
* modified the code to allow degrading of class ....
* so if you have too many friends, they will fill a FOF spot
*/
int UdpRelayReceiver::installRelayClass_relayLocked(int &classIdx, uint32_t &bandwidth)
{
/* check for total number of Relays */
if (mClassCount[UDP_RELAY_CLASS_ALL] >= mClassLimit[UDP_RELAY_CLASS_ALL])
@ -379,12 +385,25 @@ int UdpRelayReceiver::installRelayClass_relayLocked(int classIdx)
}
/* now check the specifics of the class */
if (mClassCount[classIdx] >= mClassLimit[classIdx])
while(mClassCount[classIdx] >= mClassLimit[classIdx])
{
std::cerr << "UdpRelayReceiver::installRelayClass() WARNING Relay Class Limit Exceeded";
std::cerr << std::endl;
std::cerr << "UdpRelayReceiver::installRelayClass() ClassIdx: " << classIdx;
std::cerr << std::endl;
std::cerr << "UdpRelayReceiver::installRelayClass() ClassLimit: " << mClassLimit[classIdx];
std::cerr << std::endl;
std::cerr << "UdpRelayReceiver::installRelayClass() Degrading Class =>: " << classIdx;
std::cerr << std::endl;
return 0;
classIdx--;
if (classIdx == 0)
{
std::cerr << "UdpRelayReceiver::installRelayClass() No Spaces Left";
std::cerr << std::endl;
return 0;
}
}
std::cerr << "UdpRelayReceiver::installRelayClass() Relay Class Ok, Count incremented";
@ -393,6 +412,7 @@ int UdpRelayReceiver::installRelayClass_relayLocked(int classIdx)
/* if we get here we can add one */
mClassCount[UDP_RELAY_CLASS_ALL]++;
mClassCount[classIdx]++;
bandwidth = mClassBandwidth[classIdx];
return 1;
}
@ -448,7 +468,7 @@ int UdpRelayReceiver::setRelayTotal(int count)
}
int UdpRelayReceiver::setRelayClassMax(int classIdx, int count)
int UdpRelayReceiver::setRelayClassMax(int classIdx, int count, int bandwidth)
{
RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/
@ -461,6 +481,7 @@ int UdpRelayReceiver::setRelayClassMax(int classIdx, int count)
}
mClassLimit[classIdx] = count;
mClassBandwidth[classIdx] = bandwidth;
return 1;
}
@ -480,6 +501,21 @@ int UdpRelayReceiver::getRelayClassMax(int classIdx)
return mClassLimit[classIdx];
}
int UdpRelayReceiver::getRelayClassBandwidth(int classIdx)
{
RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/
/* check the idx */
if ((classIdx < 0) || (classIdx >= UDP_RELAY_NUM_CLASS))
{
std::cerr << "UdpRelayReceiver::getRelayMaximum() ERROR class Idx invalid";
std::cerr << std::endl;
return 0;
}
return mClassBandwidth[classIdx];
}
int UdpRelayReceiver::getRelayCount(int classIdx)
{
RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/
@ -840,7 +876,7 @@ UdpRelayProxy::UdpRelayProxy()
mBandwidthLimit = 0;
}
UdpRelayProxy::UdpRelayProxy(UdpRelayAddrSet *addrSet, int relayClass)
UdpRelayProxy::UdpRelayProxy(UdpRelayAddrSet *addrSet, int relayClass, uint32_t bandwidth)
{
mAddrs = *addrSet;
mRelayClass = relayClass;
@ -852,18 +888,23 @@ UdpRelayProxy::UdpRelayProxy(UdpRelayAddrSet *addrSet, int relayClass)
mStartTS = time(NULL);
switch(relayClass)
mBandwidthLimit = bandwidth;
/* fallback */
if (mBandwidthLimit == 0)
{
default:
case UDP_RELAY_CLASS_GENERAL:
mBandwidthLimit = RELAY_MAX_BANDWIDTH;
break;
case UDP_RELAY_CLASS_FOF:
mBandwidthLimit = RELAY_MAX_BANDWIDTH;
break;
case UDP_RELAY_CLASS_FRIENDS:
mBandwidthLimit = RELAY_MAX_BANDWIDTH;
break;
switch(relayClass)
{
default:
case UDP_RELAY_CLASS_GENERAL:
mBandwidthLimit = RELAY_MAX_BANDWIDTH;
break;
case UDP_RELAY_CLASS_FOF:
mBandwidthLimit = RELAY_MAX_BANDWIDTH;
break;
case UDP_RELAY_CLASS_FRIENDS:
mBandwidthLimit = RELAY_MAX_BANDWIDTH;
break;
}
}
}

View File

@ -27,6 +27,7 @@
*/
#include "tcponudp/udppeer.h"
#include <retroshare/rsdht.h>
#include <vector>
class UdpRelayAddrSet;
@ -49,7 +50,7 @@ class UdpRelayProxy
{
public:
UdpRelayProxy();
UdpRelayProxy(UdpRelayAddrSet *addrSet, int relayClass);
UdpRelayProxy(UdpRelayAddrSet *addrSet, int relayClass, uint32_t bandwidth);
UdpRelayAddrSet mAddrs;
double mBandwidth;
@ -94,18 +95,19 @@ std::ostream &operator<<(std::ostream &out, const UdpRelayEnd &ure);
#define UDP_RELAY_DEFAULT_COUNT_ALL 10
#define UDP_RELAY_FRAC_GENERAL (0.2)
#define UDP_RELAY_FRAC_FOF (0.5)
#define UDP_RELAY_FRAC_FRIENDS (0.8)
#define UDP_RELAY_FRAC_FRIENDS (0.3)
#define UDP_RELAY_NUM_CLASS 4
/**** DEFINED IN EXTERNAL HEADER FILE ***/
#define UDP_RELAY_NUM_CLASS RSDHT_RELAY_NUM_CLASS
#define UDP_RELAY_CLASS_ALL 0
#define UDP_RELAY_CLASS_GENERAL 1
#define UDP_RELAY_CLASS_FOF 2
#define UDP_RELAY_CLASS_FRIENDS 3
#define UDP_RELAY_CLASS_ALL RSDHT_RELAY_CLASS_ALL
#define UDP_RELAY_CLASS_GENERAL RSDHT_RELAY_CLASS_GENERAL
#define UDP_RELAY_CLASS_FOF RSDHT_RELAY_CLASS_FOF
#define UDP_RELAY_CLASS_FRIENDS RSDHT_RELAY_CLASS_FRIENDS
// Just for some testing fun!
//#define UDP_RELAY_LIFETIME_GENERAL 180 // 3 minutes
//#define UDP_RELAY_LIFETIME_FOF 360 // 6 minutes.
//#define UDP_RELAY_LIFETIME_FOF 360 // 6 minutes.
//#define UDP_RELAY_LIFETIME_FRIENDS 720 // 12 minutes.
#define UDP_RELAY_LIFETIME_GENERAL 1800 // 30 minutes
@ -131,15 +133,16 @@ int removeUdpPeer(UdpPeer *peer);
* the end-points drop the connections
*/
int addUdpRelay(UdpRelayAddrSet *addrSet, int relayClass, uint32_t &bandwidth);
int addUdpRelay(UdpRelayAddrSet *addrSet, int &relayClass, uint32_t &bandwidth);
int removeUdpRelay(UdpRelayAddrSet *addrs);
/* Need some stats, to work out how many relays we are supporting */
int checkRelays();
int setRelayTotal(int count); /* sets all the Relay Counts (frac based on total) */
int setRelayClassMax(int classIdx, int count); /* set a specific class maximum */
int setRelayClassMax(int classIdx, int count, int bandwidth); /* set a specific class maximum */
int getRelayClassMax(int classIdx);
int getRelayClassBandwidth(int classIdx);
int getRelayCount(int classIdx); /* how many relays (of this type) do we have */
int RelayStatus(std::ostream &out);
@ -158,7 +161,7 @@ int status(std::ostream &out);
private:
int removeUdpRelay_relayLocked(UdpRelayAddrSet *addrs);
int installRelayClass_relayLocked(int classIdx);
int installRelayClass_relayLocked(int &classIdx, uint32_t &bandwidth);
int removeRelayClass_relayLocked(int classIdx);
/* Unfortunately, Due the reentrant nature of this classes activities...
@ -176,7 +179,7 @@ int status(std::ostream &out);
RsMutex relayMtx; /* for all class data (below) */
std::vector<int> mClassLimit, mClassCount;
std::vector<int> mClassLimit, mClassCount, mClassBandwidth;
std::map<struct sockaddr_in, UdpRelayEnd> mStreams; /* indexed by <dest> */
std::map<UdpRelayAddrSet, UdpRelayProxy> mRelays; /* indexed by <src,dest> */

View File

@ -0,0 +1,33 @@
The Code in this directory refers to APPLEs ZeroConf Library.
We have two classes: p3ZeroConf & p3ZeroConfNat
The first provides ZeroConf(Bonjour) discovery services.
The second provides UPnP & NAT-PMP Nat Port Forwarding.
OSX
----------------
Both should compile with no problems under OSX.
Both will be compiled by default.
p3ZeroConf is enabled by default.
p3ZeroConfNAT will become the default PortForwarding Service (once tested).
Windows
----------------
Under Windows, you require Apple's header files & library to compile.
If you are missing the libraries, you can disable their compilation in libretroshare.
Furthermore - it'll only work if the Apple DNS Service is running on the Windows PC.
p3ZeroConf will be enabled by default (if included in the compilation).
p3ZeroConfNAT will not be enabled by default.
Linux
----------------
Neither of these classes will compile or be enabled under Linux.
There is another library: Avahi - which provides ZeroConf services.
It is likely to have a totally different interface -
so it will have to be coded up separately.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,286 @@
/*
* libretroshare/src/zeroconf: p3zeroconf.h
*
* ZeroConf interface for RetroShare.
*
* Copyright 2011-2011 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 2 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 "retroshare@lunamutt.com".
*
*/
#ifndef MRK_P3_ZEROCONF_H
#define MRK_P3_ZEROCONF_H
#include "util/rswin.h"
#include "pqi/pqiassist.h"
#include "retroshare/rsdht.h"
#include <string>
#include <map>
#include "pqi/pqinetwork.h"
#include "pqi/pqimonitor.h"
#include "pqi/p3peermgr.h"
#include "util/rsthreads.h"
#include <dns_sd.h>
class zcBrowseResult
{
public:
DNSServiceFlags flags;
uint32_t interfaceIndex;
std::string serviceName;
std::string regtype;
std::string replyDomain;
};
class zcResolveResult
{
public:
zcResolveResult() { return; } // :txtRecord(NULL) { return; }
~zcResolveResult() { return; } //{ if (txtRecord) { free(txtRecord); txtRecord = NULL; } }
DNSServiceFlags flags;
uint32_t interfaceIndex;
std::string fullname;
std::string hosttarget;
uint16_t port;
uint16_t txtLen;
//unsigned char *txtRecord;
// extra results.
std::string gpgId;
std::string sslId;
};
class zcQueryResult
{
public:
zcQueryResult() { return; } //:rdata(NULL) { return; }
~zcQueryResult() {return; } //{ if (rdata) { free(rdata); rdata = NULL; } }
DNSServiceFlags flags;
uint32_t interfaceIndex;
std::string fullname;
uint16_t rrtype;
uint16_t rrclass;
uint16_t rdlen;
//void *rdata;
uint32_t ttl;
// Extra ones.
std::string sslId;
std::string gpgId;
struct sockaddr_in addr;
};
class zcLocationResult
{
public:
zcLocationResult() { return; }
zcLocationResult(std::string _gpgId, std::string _sslId)
:gpgId(_gpgId), sslId(_sslId) { return; }
std::string gpgId;
std::string sslId;
};
#define ZC_STATUS_NEW_LOCATION 1
#define ZC_STATUS_FOUND 2
#define ZC_STATUS_CONNECTED 4
#define ZC_STATUS_IPADDRESS 8
class zcLocationDetails
{
public:
std::string mSslId;
time_t mFoundTs;
uint32_t mStatus;
std::string mHostTarget;
std::string mFullName;
uint16_t mPort;
struct sockaddr_in mAddress;
time_t mAddrTs;
};
class zcPeerDetails
{
public:
std::string gpgId;
std::map<std::string, zcLocationDetails> mLocations;
};
class p3NetMgr;
class p3ZeroConf: public pqiNetAssistConnect, public pqiNetListener
{
public:
p3ZeroConf(std::string gpgid, std::string sslid, pqiConnectCb *cb, p3NetMgr *nm, p3PeerMgr *pm);
virtual ~p3ZeroConf();
/*** OVERLOADED from pqiNetListener ***/
virtual bool resetListener(struct sockaddr_in &local);
void start(); /* starts up the thread */
/* pqiNetAssist - external interface functions */
virtual int tick();
virtual void enable(bool on);
virtual void shutdown(); /* blocking call */
virtual void restart();
virtual bool getEnabled();
virtual bool getActive();
virtual bool getNetworkStats(uint32_t &netsize, uint32_t &localnetsize);
/* pqiNetAssistConnect - external interface functions */
/* add / remove peers */
virtual bool findPeer(std::string id);
virtual bool dropPeer(std::string id);
virtual int addBadPeer(const struct sockaddr_in &addr, uint32_t reason, uint32_t flags, uint32_t age);
virtual int addKnownPeer(const std::string &pid, const struct sockaddr_in &addr, uint32_t flags);
/* feedback on success failure of Connections */
virtual void ConnectionFeedback(std::string pid, int state);
/* extract current peer status */
virtual bool getPeerStatus(std::string id,
struct sockaddr_in &laddr, struct sockaddr_in &raddr,
uint32_t &type, uint32_t &mode);
virtual bool setAttachMode(bool on);
/* pqiNetAssistConnect - external interface functions */
public:
// Callbacks must be public -> so they can be accessed.
void callbackRegister(DNSServiceRef sdRef, DNSServiceFlags flags,
DNSServiceErrorType errorCode,
const char *name, const char *regtype, const char *domain);
void callbackBrowse(DNSServiceRef sdRef, DNSServiceFlags flags,
uint32_t interfaceIndex, DNSServiceErrorType errorCode,
const char *serviceName, const char *regtype, const char *replyDomain);
void callbackResolve( DNSServiceRef sdRef, DNSServiceFlags flags,
uint32_t interfaceIndex, DNSServiceErrorType errorCode,
const char *fullname, const char *hosttarget, uint16_t port,
uint16_t txtLen, const unsigned char *txtRecord);
void callbackQueryIp( DNSServiceRef sdRef, DNSServiceFlags flags,
uint32_t interfaceIndex, DNSServiceErrorType errorCode,
const char *fullname, uint16_t rrtype, uint16_t rrclass,
uint16_t rdlen, const void *rdata, uint32_t ttl);
private:
void createTxtRecord();
/* monitoring fns */
void checkServiceFDs();
void locked_checkFD(DNSServiceRef ref);
int checkResolveAction();
int checkLocationResults();
int checkQueryAction();
int checkQueryResults();
/**** THESE ARE MAINLY SEMI LOCKED.... not quite sure when the callback will happen! ***/
int locked_startRegister();
void locked_stopRegister();
int locked_startBrowse();
int locked_stopBrowse();
void locked_startResolve(uint32_t idx, std::string name,
std::string regtype, std::string domain);
int locked_checkResolvedPeer(const zcResolveResult &rr);
int locked_stopResolve();
void locked_startQueryIp(uint32_t idx, std::string fullname,
std::string gpgId, std::string sslId);
int locked_completeQueryResult(zcQueryResult &qr);
int locked_stopQueryIp();
std::string displayDNSServiceError(DNSServiceErrorType errcode);
/**************** DATA ****************/
p3NetMgr *mNetMgr;
p3PeerMgr *mPeerMgr;
RsMutex mZcMtx;
std::string mOwnGpgId;
std::string mOwnSslId;
bool mRegistered;
bool mTextOkay;
bool mPortOkay;
uint16_t mLocalPort;
std::string mTextRecord;
DNSServiceRef mRegisterRef;
DNSServiceRef mBrowseRef;
DNSServiceRef mResolveRef;
DNSServiceRef mQueryRef;
uint32_t mRegisterStatus;
uint32_t mBrowseStatus;
uint32_t mResolveStatus;
uint32_t mQueryStatus;
time_t mRegisterStatusTS;
time_t mBrowseStatusTS;
time_t mResolveStatusTS;
time_t mQueryStatusTS;
std::string mQuerySslId;
std::string mQueryGpgId;
std::list<zcBrowseResult> mBrowseResults;
std::list<zcResolveResult> mResolveResults;
std::list<zcLocationResult> mLocationResults;
std::list<zcQueryResult> mQueryResults;
time_t mMinuteTS;
std::map<std::string, zcPeerDetails> mPeerDetails;
};
#endif /* MRK_P3_ZEROCONF_H */

View File

@ -307,6 +307,7 @@ HEADERS += rshare.h \
gui/settings/SoundPage.h \
gui/settings/TransferPage.h \
gui/settings/ChatPage.h \
gui/settings/RelayPage.h \
gui/settings/AddFileAssociationDialog.h \
gui/toaster/MessageToaster.h \
gui/toaster/OnlineToaster.h \
@ -429,6 +430,7 @@ FORMS += gui/StartDialog.ui \
gui/settings/TransferPage.ui \
gui/settings/SoundPage.ui \
gui/settings/ChatPage.ui \
gui/settings/RelayPage.ui \
gui/settings/PluginItem.ui \
gui/toaster/MessageToaster.ui \
gui/toaster/OnlineToaster.ui \
@ -587,6 +589,7 @@ SOURCES += main.cpp \
gui/settings/SoundPage.cpp \
gui/settings/TransferPage.cpp \
gui/settings/ChatPage.cpp \
gui/settings/RelayPage.cpp \
gui/settings/AddFileAssociationDialog.cpp \
gui/statusbar/peerstatus.cpp \
gui/statusbar/natstatus.cpp \

View File

@ -566,7 +566,7 @@ void ForumsDialog::insertForums()
uint32_t i = 0;
uint32_t popLimit = 0;
std::multimap<uint32_t, GroupItemInfo>::reverse_iterator rit;
for(rit = popMap.rbegin(); ((rit != popMap.rend()) && (i < popCount)); rit++, i++);
for(rit = popMap.rbegin(); ((rit != popMap.rend()) && (i < popCount)); rit++, i++) ;
if (rit != popMap.rend()) {
popLimit = rit->first;
}

View File

@ -0,0 +1,278 @@
/****************************************************************
* RetroShare is distributed under the following license:
*
* Copyright (C) 2006 - 2010 RetroShare Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
#include "RelayPage.h"
#include "rshare.h"
#include <iostream>
#include <sstream>
#include <retroshare/rsiface.h>
#include <retroshare/rsfiles.h>
#include <retroshare/rspeers.h>
#include <retroshare/rsdht.h>
#include <QTimer>
RelayPage::RelayPage(QWidget * parent, Qt::WFlags flags)
: ConfigPage(parent, flags)
{
/* Invoke the Qt Designer generated object setup routine */
ui.setupUi(this);
QObject::connect(ui.noFriendSpinBox,SIGNAL(valueChanged(int)),this,SLOT(updateRelayOptions()));
QObject::connect(ui.noFOFSpinBox,SIGNAL(valueChanged(int)),this,SLOT(updateRelayOptions()));
QObject::connect(ui.noGeneralSpinBox,SIGNAL(valueChanged(int)),this,SLOT(updateRelayOptions()));
QObject::connect(ui.bandFriendSpinBox,SIGNAL(valueChanged(int)),this,SLOT(updateRelayOptions()));
QObject::connect(ui.bandFOFSpinBox,SIGNAL(valueChanged(int)),this,SLOT(updateRelayOptions()));
QObject::connect(ui.bandGeneralSpinBox,SIGNAL(valueChanged(int)),this,SLOT(updateRelayOptions()));
QObject::connect(ui.addPushButton,SIGNAL(clicked()),this,SLOT(addServer()));
QObject::connect(ui.removePushButton,SIGNAL(clicked()),this,SLOT(removeServer()));
QObject::connect(ui.DhtLineEdit,SIGNAL(textChanged(const QString &)),this,SLOT(checkKey()));
QObject::connect(ui.enableCheckBox,SIGNAL(stateChanged(int)),this,SLOT(updateEnabled()));
QObject::connect(ui.serverCheckBox,SIGNAL(stateChanged(int)),this,SLOT(updateEnabled()));
/* Hide platform specific features */
#ifdef Q_WS_WIN
#endif
}
/** Saves the changes on this page */
bool RelayPage::save(QString &errmsg)
{
int nFriends = ui.noFriendSpinBox->value();
int friendBandwidth = ui.bandFriendSpinBox->value();
int nFOF = ui.noFOFSpinBox->value();
int fofBandwidth = ui.bandFOFSpinBox->value();
int nGeneral = ui.noGeneralSpinBox->value();
int genBandwidth = ui.bandGeneralSpinBox->value();
int total = nFriends + nFOF + nGeneral;
rsDht->setRelayAllowance(RSDHT_RELAY_CLASS_ALL, total, 0);
rsDht->setRelayAllowance(RSDHT_RELAY_CLASS_FRIENDS, nFriends, 1024 * friendBandwidth);
rsDht->setRelayAllowance(RSDHT_RELAY_CLASS_FOF, nFOF, 1024 * fofBandwidth);
rsDht->setRelayAllowance(RSDHT_RELAY_CLASS_GENERAL, nGeneral, 1024 * genBandwidth);
uint32_t relayMode = 0;
if (ui.enableCheckBox->isChecked())
{
relayMode |= RSDHT_RELAY_ENABLED;
if (ui.serverCheckBox->isChecked())
{
relayMode |= RSDHT_RELAY_MODE_ON;
}
else
{
relayMode |= RSDHT_RELAY_MODE_OFF;
}
}
else
{
relayMode |= RSDHT_RELAY_MODE_OFF;
}
rsDht->setRelayMode(relayMode);
return true;
}
/** Loads the settings for this page */
void RelayPage::load()
{
uint32_t count;
uint32_t bandwidth;
rsDht->getRelayAllowance(RSDHT_RELAY_CLASS_FRIENDS, count, bandwidth);
ui.noFriendSpinBox->setValue(count);
ui.bandFriendSpinBox->setValue(bandwidth / 1000);
rsDht->getRelayAllowance(RSDHT_RELAY_CLASS_FOF, count, bandwidth);
ui.noFOFSpinBox->setValue(count);
ui.bandFOFSpinBox->setValue(bandwidth / 1000);
rsDht->getRelayAllowance(RSDHT_RELAY_CLASS_GENERAL, count, bandwidth);
ui.noGeneralSpinBox->setValue(count);
ui.bandGeneralSpinBox->setValue(bandwidth / 1000);
uint32_t relayMode = rsDht->getRelayMode();
if (relayMode & RSDHT_RELAY_ENABLED)
{
ui.enableCheckBox->setCheckState(Qt::Checked);
if ((relayMode & RSDHT_RELAY_MODE_MASK) == RSDHT_RELAY_MODE_OFF)
{
ui.serverCheckBox->setCheckState(Qt::Unchecked);
}
else
{
ui.serverCheckBox->setCheckState(Qt::Checked);
}
}
else
{
ui.enableCheckBox->setCheckState(Qt::Unchecked);
ui.serverCheckBox->setCheckState(Qt::Unchecked);
}
loadServers();
updateRelayOptions();
updateEnabled();
checkKey();
}
void RelayPage::loadServers()
{
std::list<std::string> servers;
std::list<std::string>::iterator it;
rsDht->getRelayServerList(servers);
ui.serverTreeWidget->clear();
for(it = servers.begin(); it != servers.end(); it++)
{
QTreeWidgetItem *item = new QTreeWidgetItem();
item->setData(0, Qt::DisplayRole, QString::fromStdString(*it));
ui.serverTreeWidget->addTopLevelItem(item);
}
}
void RelayPage::updateRelayOptions()
{
int nFriends = ui.noFriendSpinBox->value();
int friendBandwidth = ui.bandFriendSpinBox->value();
int nFOF = ui.noFOFSpinBox->value();
int fofBandwidth = ui.bandFOFSpinBox->value();
int nGeneral = ui.noGeneralSpinBox->value();
int genBandwidth = ui.bandGeneralSpinBox->value();
std::ostringstream tfriendout;
tfriendout << nFriends * friendBandwidth * 2;
ui.totalFriendLineEdit->setText(QString::fromStdString(tfriendout.str()));
std::ostringstream tfofout;
tfofout << nFOF * fofBandwidth * 2;
ui.totalFOFLineEdit->setText(QString::fromStdString(tfofout.str()));
std::ostringstream tgenout;
tgenout << nGeneral * genBandwidth * 2;
ui.totalGeneralLineEdit->setText(QString::fromStdString(tgenout.str()));
std::ostringstream totalout;
totalout << (nFriends * friendBandwidth
+ nFOF * fofBandwidth
+ nGeneral * genBandwidth) * 2;
ui.totalBandwidthLineEdit->setText(QString::fromStdString(totalout.str()));
std::ostringstream countout;
countout << (nFriends + nFOF + nGeneral);
ui.noTotalLineEdit->setText(QString::fromStdString(countout.str()));
}
void RelayPage::updateEnabled()
{
std::cerr << "RelayPage::updateEnabled()" << std::endl;
if (ui.enableCheckBox->isChecked())
{
ui.groupBox->setEnabled(true);
if (ui.serverCheckBox->isChecked())
{
std::cerr << "RelayPage::updateEnabled() Both Enabled" << std::endl;
ui.serverGroupBox->setEnabled(true);
}
else
{
std::cerr << "RelayPage::updateEnabled() Options Only Enabled" << std::endl;
ui.serverGroupBox->setEnabled(false);
}
}
else
{
std::cerr << "RelayPage::updateEnabled() Both Disabled" << std::endl;
ui.groupBox->setEnabled(false);
ui.serverGroupBox->setEnabled(false);
}
}
void RelayPage::checkKey()
{
std::string server = ui.DhtLineEdit->text().toStdString();
std::cerr << "RelayPage::checkKey() length: " << server.length();
std::cerr << std::endl;
if (server.length() == 40)
{
ui.keyOkBox->setChecked(Qt::Checked);
}
else
{
ui.keyOkBox->setChecked(Qt::Unchecked);
}
}
void RelayPage::addServer()
{
std::cerr << "RelayPage::addServer()";
std::cerr << std::endl;
if (!ui.keyOkBox->isChecked())
{
return;
}
std::string server = ui.DhtLineEdit->text().toStdString();
bool ok = rsDht->addRelayServer(server);
if (ok)
{
ui.DhtLineEdit->setText(QString(""));
}
loadServers();
}
void RelayPage::removeServer()
{
QTreeWidgetItem *item = ui.serverTreeWidget->currentItem();
if (item)
{
std::string server = item->data(0, Qt::DisplayRole).toString().toStdString();
rsDht->removeRelayServer(server);
}
loadServers();
}

View File

@ -0,0 +1,57 @@
/****************************************************************
* RetroShare is distributed under the following license:
*
* Copyright (C) 2006 - 2010 RetroShare Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
#ifndef RELAYPAGE_H
#define RELAYPAGE_H
# include <QtGui/QWidget>
#include "configpage.h"
#include "ui_RelayPage.h"
class RelayPage: public ConfigPage
{
Q_OBJECT
public:
RelayPage(QWidget * parent = 0, Qt::WFlags flags = 0);
~RelayPage() {}
/** Saves the changes on this page */
virtual bool save(QString &/*errmsg*/);
/** Loads the settings for this page */
virtual void load();
public slots:
void updateRelayOptions();
void updateEnabled();
void checkKey();
void addServer();
void removeServer();
void loadServers();
private:
Ui::RelayPage ui;
};
#endif //RELAYPAGE_H

View File

@ -0,0 +1,372 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>RelayPage</class>
<widget class="QWidget" name="RelayPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>486</width>
<height>360</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="enableCheckBox">
<property name="text">
<string>Enable Relay Connections</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="serverCheckBox">
<property name="text">
<string>Use Relay Servers</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="title">
<string>Relay options</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>110</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Number</string>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>6</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="3">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Bandwidth per link</string>
</property>
</widget>
</item>
<item row="0" column="4" rowspan="7">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Total Bandwidth</string>
</property>
</widget>
</item>
<item row="1" column="0" rowspan="2">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Friends</string>
</property>
</widget>
</item>
<item row="1" column="1" rowspan="2">
<widget class="QSpinBox" name="noFriendSpinBox">
<property name="minimum">
<number>3</number>
</property>
<property name="maximum">
<number>99</number>
</property>
</widget>
</item>
<item row="1" column="2" rowspan="2">
<widget class="QLabel" name="label_9">
<property name="text">
<string>x</string>
</property>
</widget>
</item>
<item row="1" column="3" rowspan="2">
<widget class="QSpinBox" name="bandFriendSpinBox">
<property name="suffix">
<string>kB/s</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item row="2" column="5">
<widget class="QLineEdit" name="totalFriendLineEdit">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0" rowspan="2">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Friends of Friends</string>
</property>
</widget>
</item>
<item row="3" column="1" rowspan="2">
<widget class="QSpinBox" name="noFOFSpinBox"/>
</item>
<item row="3" column="2" rowspan="2">
<widget class="QLabel" name="label_10">
<property name="text">
<string>x</string>
</property>
</widget>
</item>
<item row="3" column="3" rowspan="2">
<widget class="QSpinBox" name="bandFOFSpinBox">
<property name="suffix">
<string>kB/s</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item row="4" column="5">
<widget class="QLineEdit" name="totalFOFLineEdit">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0" rowspan="2">
<widget class="QLabel" name="label_7">
<property name="text">
<string>General</string>
</property>
</widget>
</item>
<item row="5" column="1" rowspan="2">
<widget class="QSpinBox" name="noGeneralSpinBox"/>
</item>
<item row="5" column="2" rowspan="2">
<widget class="QLabel" name="label_11">
<property name="text">
<string>x</string>
</property>
</widget>
</item>
<item row="5" column="3" rowspan="2">
<widget class="QSpinBox" name="bandGeneralSpinBox">
<property name="suffix">
<string>kB/s</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item row="6" column="5">
<widget class="QLineEdit" name="totalGeneralLineEdit">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="0" colspan="6">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QLineEdit" name="noTotalLineEdit">
<property name="focusPolicy">
<enum>Qt::WheelFocus</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Total:</string>
</property>
</widget>
</item>
<item row="8" column="2" colspan="2">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>123</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="8" column="5">
<widget class="QLineEdit" name="totalBandwidthLineEdit">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="serverGroupBox">
<property name="title">
<string>Relay Server Setup</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="horizontalSpacing">
<number>-1</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLineEdit" name="DhtLineEdit">
<property name="inputMask">
<string notr="true">HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH; </string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="keyOkBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string/>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="addPushButton">
<property name="text">
<string>Add Server</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QTreeWidget" name="serverTreeWidget">
<column>
<property name="text">
<string>Server Dht Key</string>
</property>
</column>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="removePushButton">
<property name="text">
<string>Remove Server</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -31,6 +31,7 @@
#include "FileAssociationsPage.h"
#include "SoundPage.h"
#include "TransferPage.h"
#include "RelayPage.h"
#include "ChatPage.h"
#include "MessagePage.h"
#include "ForumPage.h"
@ -107,8 +108,9 @@ RSettingsWin::initStackedWidget()
stackedWidget->addWidget(new GeneralPage(0));
stackedWidget->addWidget(new ServerPage());
stackedWidget->addWidget(new TransferPage());
stackedWidget->addWidget(new RelayPage() );
stackedWidget->addWidget(new DirectoriesPage());
stackedWidget->addWidget(new PluginsPage() );
stackedWidget->addWidget(new PluginsPage() );
stackedWidget->addWidget(new NotifyPage());
stackedWidget->addWidget(new CryptoPage());
stackedWidget->addWidget(new MessagePage());
@ -143,6 +145,10 @@ RSettingsWin::setNewPage(int page)
text = tr("Transfer");
pageicon->setPixmap(QPixmap(":/images/ktorrent32.png"));
break;
case Relay:
text = tr("Relay");
pageicon->setPixmap(QPixmap(":/images/server_24x24.png"));
break;
case Notify:
text = tr("Notify");
pageicon->setPixmap(QPixmap(":/images/status_unknown.png"));

View File

@ -31,7 +31,7 @@ class RSettingsWin: public QDialog, private Ui::Settings
Q_OBJECT
public:
enum PageType { LastPage = -1, General = 0, Server, Transfer,
enum PageType { LastPage = -1, General = 0, Server, Transfer,Relay,
Directories, Plugins, Notify, Security, Message, Forum, Chat, Appearance, Sound, Fileassociations };
static void showYourself(QWidget *parent, PageType page = LastPage);

View File

@ -107,6 +107,15 @@
<normaloff>:/images/ktorrent32.png</normaloff>:/images/ktorrent32.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>Relays</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/server_24x24.png</normaloff>:/images/server_24x24.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>Directories</string>