Merged v0.5-netupgrade branch back into the trunk ( --- Merging r4410 through r4465 into '.' )

This brings lots of improvements:
 * UDP Connection Code - this it the majority of the new code.
 * Simplification of p3ConnectMgr => p3LinkMgr, p3PeerMgr & p3NetMgr.
 * Notifications of Failed Connection Attempts
 * Addition of a "Getting Started Guide".
 



git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@4466 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2011-07-18 09:25:15 +00:00
commit 69c14461cb
108 changed files with 16142 additions and 5985 deletions

File diff suppressed because it is too large Load Diff

View File

@ -42,7 +42,7 @@ class bdNodePublisher;
#define BITDHT_CONNREQUEST_EXTCONNECT 4
#define BITDHT_CONNREQUEST_DONE 5
#define BITDHT_CONNREQUEST_TIMEOUT_CONNECT 30
#define BITDHT_CONNREQUEST_TIMEOUT_CONNECT 180 // MAKE THIS LARGE - SHOULD NEVER HAPPEN.
#define BITDHT_CONNREQUEST_TIMEOUT_INPROGRESS 30
#define BITDHT_CONNREQUEST_MAX_AGE 60
@ -54,9 +54,9 @@ class bdNodePublisher;
#define BITDHT_CONNECTION_COMPLETED 5
#define BD_CONNECTION_START_RETRY_PERIOD 5 // Should only take a couple of seconds to get reply.
#define BD_CONNECTION_START_RETRY_PERIOD 3 // Should only take a couple of seconds to get reply.
#define BD_CONNECTION_START_MAX_RETRY 3
#define BD_CONNECTION_MAX_TIMEOUT 45
#define BD_CONNECTION_MAX_TIMEOUT 20 /* should be quick */
@ -85,22 +85,22 @@ class bdConnection
/** Functions to tweak the connection status */
// User initialised Connection.
int ConnectionSetup(bdId *proxyId, bdId *srcConnAddr, bdId *destConnAddr, int mode);
int ConnectionSetup(bdId *proxyId, bdId *srcConnAddr, bdId *destConnAddr, int mode, int delay);
int ConnectionSetupDirect(bdId *destId, bdId *srcConnAddr);
// Initialise a new Connection. (receiving a Connection Request)
int ConnectionRequestDirect(bdId *id, bdId *srcConnAddr, bdId *destConnAddr);
int ConnectionRequestProxy(bdId *id, bdId *srcConnAddr, bdNodeId *ownId, bdId *destConnAddr, int mode);
int ConnectionRequestProxy(bdId *id, bdId *srcConnAddr, bdNodeId *ownId, bdId *destConnAddr, int mode, int delay);
int ConnectionRequestEnd(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode);
// Setup Finishing Stage, (receiving a Connection Reply).
int upgradeProxyConnectionToFinish(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode, int status);
int upgradeProxyConnectionToFinish(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode, int delay, int status);
int AuthoriseDirectConnection(bdId *srcId, bdId *proxyId, bdId *destId, int mode, int loc);
int AuthoriseProxyConnection(bdId *srcId, bdId *proxyId, bdId *destId, int mode, int loc);
int AuthoriseEndConnection(bdId *srcId, bdId *proxyId, bdId *destId, int mode, int loc);
int AuthoriseProxyConnection(bdId *srcId, bdId *proxyId, bdId *destId, int mode, int loc, int bandwidth);
int AuthoriseEndConnection(bdId *srcId, bdId *proxyId, bdId *destId, int mode, int loc, int delay);
int CompleteConnection(bdId *id, bdId *srcConnAddr, bdId *destConnAddr);
int CompleteConnection(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int bandwidth, int delay);
int checkForDefaultConnectAddress();
@ -124,6 +124,8 @@ class bdConnection
bdId mDestConnAddr;
int mBandwidth;
int mMaxDelay;
time_t mConnectionStartTS;
/* START/ACK Finishing ****/
time_t mLastStart; /* timer for retries */
@ -142,7 +144,7 @@ class bdConnectionRequest
{
public:
int setupDirectConnection(struct sockaddr_in *laddr, bdNodeId *target);
int setupProxyConnection(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode);
int setupProxyConnection(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t delay);
int addGoodProxy(const bdId *srcId);
int checkGoodProxyPeer(const bdId *Id);
@ -157,6 +159,8 @@ class bdConnectionRequest
time_t mPauseTS;
uint32_t mErrCode;
int mDelay;
time_t mRequestTS; // reference Time for mDelay.
std::list<bdId> mGoodProxies;
std::list<bdId> mPotentialProxies;
@ -199,9 +203,9 @@ class bdConnectManager
/* Connections: Initiation */
int requestConnection(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t start);
int requestConnection(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t delay, uint32_t start);
int requestConnection_direct(struct sockaddr_in *laddr, bdNodeId *target);
int requestConnection_proxy(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode);
int requestConnection_proxy(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t delay);
int killConnectionRequest(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode);
@ -217,12 +221,12 @@ class bdConnectManager
// internal Callback -> normally continues to callbackConnect().
void callbackConnectRequest(bdId *srcId, bdId *proxyId, bdId *destId,
int mode, int point, int cbtype, int errcode);
int mode, int point, int param, int cbtype, int errcode);
/* Connections: Outgoing */
int startConnectionAttempt(bdId *proxyId, bdId *srcConnAddr, bdId *destConnAddr, int mode);
void AuthConnectionOk(bdId *srcId, bdId *proxyId, bdId *destId, int mode, int loc);
int startConnectionAttempt(bdId *proxyId, bdId *srcConnAddr, bdId *destConnAddr, int mode, int delay);
void AuthConnectionOk(bdId *srcId, bdId *proxyId, bdId *destId, int mode, int loc, int bandwidth, int delay);
void AuthConnectionNo(bdId *srcId, bdId *proxyId, bdId *destId, int mode, int loc, int errcode);
void iterateConnections();
@ -243,12 +247,12 @@ class bdConnectManager
// Overloaded Generalised Connection Callback.
virtual void callbackConnect(bdId *srcId, bdId *proxyId, bdId *destId,
int mode, int point, int cbtype, int errcode);
int mode, int point, int param, int cbtype, int errcode);
/* Connections: */
int recvedConnectionRequest(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode);
int recvedConnectionReply(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode, int status);
int recvedConnectionStart(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode, int bandwidth);
int recvedConnectionRequest(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode, int delay);
int recvedConnectionReply(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode, int delay, int status);
int recvedConnectionStart(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode, int delayOrBandwidth);
int recvedConnectionAck(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode);
private:

View File

@ -302,7 +302,7 @@ virtual int dhtValueCallback(const bdNodeId *id, std::string key, uint32_t statu
// connection callback. Not required for basic behaviour, but forced for initial development.
virtual int dhtConnectCallback(const bdId *srcId, const bdId *proxyId, const bdId *destId,
uint32_t mode, uint32_t point, uint32_t cbtype, uint32_t errcode) = 0; /* { return 0; } */
uint32_t mode, uint32_t point, uint32_t param, uint32_t cbtype, uint32_t errcode) = 0; /* { return 0; } */
};
@ -317,8 +317,9 @@ virtual void removeFindNode(bdNodeId *id) = 0;
virtual void findDhtValue(bdNodeId *id, std::string key, uint32_t mode) = 0;
/***** Connections Requests *****/
virtual void ConnectionRequest(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t start) = 0;
virtual void ConnectionAuth(bdId *srcId, bdId *proxyId, bdId *destId, uint32_t mode, uint32_t loc, uint32_t answer) = 0;
virtual bool ConnectionRequest(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t delay, uint32_t start) = 0;
virtual void ConnectionAuth(bdId *srcId, bdId *proxyId, bdId *destId, uint32_t mode, uint32_t loc,
uint32_t bandwidth, uint32_t delay, uint32_t answer) = 0;
virtual void ConnectionOptions(uint32_t allowedModes, uint32_t flags) = 0;

View File

@ -63,7 +63,7 @@
// This is eventually what we want.
//#define LOCAL_NET_FLAG (BITDHT_PEER_STATUS_DHT_ENGINE_VERSION)
#define QUERY_UPDATE_PERIOD 59 // just under one minute... as that gets called every minute...
#define QUERY_UPDATE_PERIOD 8 // under refresh period - so it'll happen at the MAX_REFRESH_PERIOD
bdNodeManager::bdNodeManager(bdNodeId *id, std::string dhtVersion, std::string bootfile, bdDhtFunctions *fns)
@ -1255,22 +1255,22 @@ int bdDebugCallback::dhtValueCallback(const bdNodeId *id, std::string key, uint3
void bdNodeManager::ConnectionRequest(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t start)
bool bdNodeManager::ConnectionRequest(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t delay, uint32_t start)
{
std::cerr << "bdNodeManager::ConnectionRequest()";
std::cerr << std::endl;
mConnMgr->requestConnection(laddr, target, mode, start);
return mConnMgr->requestConnection(laddr, target, mode, delay, start);
}
void bdNodeManager::ConnectionAuth(bdId *srcId, bdId *proxyId, bdId *destId, uint32_t mode, uint32_t loc, uint32_t answer)
void bdNodeManager::ConnectionAuth(bdId *srcId, bdId *proxyId, bdId *destId, uint32_t mode, uint32_t loc, uint32_t bandwidth, uint32_t delay, uint32_t answer)
{
std::cerr << "bdNodeManager::ConnectionAuth()";
std::cerr << std::endl;
if (answer == BITDHT_CONNECT_ANSWER_OKAY)
{
mConnMgr->AuthConnectionOk(srcId, proxyId, destId, mode, loc);
mConnMgr->AuthConnectionOk(srcId, proxyId, destId, mode, loc, bandwidth, delay);
}
else
{
@ -1287,7 +1287,7 @@ void bdNodeManager::ConnectionOptions(uint32_t allowedModes, uint32_t flags)
/***** Connections Requests *****/
// Overloaded from bdnode for external node callback.
void bdNodeManager::callbackConnect(bdId *srcId, bdId *proxyId, bdId *destId, int mode, int point, int cbtype, int errcode)
void bdNodeManager::callbackConnect(bdId *srcId, bdId *proxyId, bdId *destId, int mode, int point, int param, int cbtype, int errcode)
{
std::cerr << "bdNodeManager::callbackConnect()";
std::cerr << std::endl;
@ -1298,13 +1298,13 @@ void bdNodeManager::callbackConnect(bdId *srcId, bdId *proxyId, bdId *destId, in
std::list<BitDhtCallback *>::iterator it;
for(it = mCallbacks.begin(); it != mCallbacks.end(); it++)
{
(*it)->dhtConnectCallback(srcId, proxyId, destId, mode, point, cbtype, errcode);
(*it)->dhtConnectCallback(srcId, proxyId, destId, mode, point, param, cbtype, errcode);
}
return;
}
int bdDebugCallback::dhtConnectCallback(const bdId *srcId, const bdId *proxyId, const bdId *destId,
uint32_t mode, uint32_t point, uint32_t cbtype, uint32_t errcode)
uint32_t mode, uint32_t point, uint32_t param, uint32_t cbtype, uint32_t errcode)
{
#ifdef DEBUG_MGR
std::cerr << "bdDebugCallback::dhtConnectCallback() Type: " << cbtype;
@ -1316,6 +1316,7 @@ int bdDebugCallback::dhtConnectCallback(const bdId *srcId, const bdId *proxyId,
std::cerr << " destId: ";
bdStdPrintId(std::cerr, destId);
std::cerr << " mode: " << mode;
std::cerr << " param: " << param;
std::cerr << " point: " << point << std::endl;
#endif

View File

@ -121,9 +121,9 @@ virtual int getDhtQueries(std::map<bdNodeId, bdQueryStatus> &queries);
virtual int getDhtQueryStatus(const bdNodeId *id, bdQuerySummary &query);
/***** Connection Interface ****/
virtual void ConnectionRequest(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t start);
virtual bool ConnectionRequest(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t delay, uint32_t start);
virtual void ConnectionAuth(bdId *srcId, bdId *proxyId, bdId *destId,
uint32_t mode, uint32_t loc, uint32_t answer);
uint32_t mode, uint32_t loc, uint32_t bandwidth, uint32_t delay, uint32_t answer);
virtual void ConnectionOptions(uint32_t allowedModes, uint32_t flags);
@ -139,7 +139,7 @@ virtual uint32_t statsBDVersionSize(); /* same version as us! */
virtual void addPeer(const bdId *id, uint32_t peerflags);
// Overloaded from bdnode for external node callback.
virtual void callbackConnect(bdId *srcId, bdId *proxyId, bdId *destId,
int mode, int point, int cbtype, int errcode);
int mode, int point, int param, int cbtype, int errcode);
int isBitDhtPacket(char *data, int size, struct sockaddr_in &from);
private:
@ -188,7 +188,7 @@ class bdDebugCallback: public BitDhtCallback
virtual int dhtPeerCallback(const bdId *id, uint32_t status);
virtual int dhtValueCallback(const bdNodeId *id, std::string key, uint32_t status);
virtual int dhtConnectCallback(const bdId *srcId, const bdId *proxyId, const bdId *destId,
uint32_t mode, uint32_t point, uint32_t cbtype, uint32_t errcode);
uint32_t mode, uint32_t point, uint32_t param, uint32_t cbtype, uint32_t errcode);
};

View File

@ -963,7 +963,7 @@ int bitdht_find_node_msg(bdToken *tid, bdNodeId *id, bdNodeId *target,
*/
int bitdht_connect_genmsg(bdToken *tid, bdNodeId *id, int msgtype, bdId *src, bdId *dest, int mode, int status, char *msg, int avail)
int bitdht_connect_genmsg(bdToken *tid, bdNodeId *id, int msgtype, bdId *src, bdId *dest, int mode, int param, int status, char *msg, int avail)
{
#ifdef DEBUG_MSGS
fprintf(stderr, "bitdht_connect_genmsg()\n");
@ -983,34 +983,17 @@ int bitdht_connect_genmsg(bdToken *tid, bdNodeId *id, int msgtype, bdId *src, bd
be_node *typenode = be_create_int(msgtype);
be_node *statusnode = be_create_int(status);
be_node *modenode = be_create_int(mode);
be_node *paramnode = be_create_int(param);
be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len);
be_node *yqrnode = be_create_str("q");
be_node *cmdnode = be_create_str("connect");
#if 0
be_node *modenode = NULL;
switch(mode)
{
case BITDHT_CONNECT_MODE_DIRECT:
modenode = be_create_str("d");
break;
case BITDHT_CONNECT_MODE_PROXY:
modenode = be_create_str("p");
break;
case BITDHT_CONNECT_MODE_RELAY:
modenode = be_create_str("r");
break;
default:
modenode = be_create_str("u");
break;
}
#endif
be_add_keypair(iddict, "id", idnode);
be_add_keypair(iddict, "src", srcnode);
be_add_keypair(iddict, "dest", destnode);
be_add_keypair(iddict, "mode", modenode);
be_add_keypair(iddict, "param", paramnode);
be_add_keypair(iddict, "status", statusnode);
be_add_keypair(iddict, "type", typenode);

View File

@ -93,7 +93,7 @@ int bitdht_reply_announce_msg(bdToken *tid, bdNodeId *id,
// Extensions.
int bitdht_connect_genmsg(bdToken *tid, bdNodeId *id, int msgtype, bdId *src, bdId *dest, int mode, int status, char *msg, int avail);
int bitdht_connect_genmsg(bdToken *tid, bdNodeId *id, int msgtype, bdId *src, bdId *dest, int mode, int param, int status, char *msg, int avail);
//int response_peers_message()

View File

@ -380,14 +380,14 @@ void bdNode::send_query(bdId *id, bdNodeId *targetNodeId)
}
void bdNode::send_connect_msg(bdId *id, int msgtype, bdId *srcAddr, bdId *destAddr, int mode, int status)
void bdNode::send_connect_msg(bdId *id, int msgtype, bdId *srcAddr, bdId *destAddr, int mode, int param, int status)
{
/* push out query */
bdToken transId;
genNewTransId(&transId);
//registerOutgoingMsg(&id, &transId, BITDHT_MSG_TYPE_FIND_NODE);
msgout_connect_genmsg(id, &transId, msgtype, srcAddr, destAddr, mode, status);
msgout_connect_genmsg(id, &transId, msgtype, srcAddr, destAddr, mode, param, status);
#ifdef DEBUG_NODE_MSGS
std::cerr << "bdNode::send_connect_msg() to: ";
@ -465,7 +465,7 @@ void bdNode::addPeer(const bdId *id, uint32_t peerflags)
mConnMgr->updatePotentialConnectionProxy(id, peerflags);
//#define DISPLAY_BITDHTNODES 1
#define DISPLAY_BITDHTNODES 1
#ifdef DISPLAY_BITDHTNODES
/* TEMP to extract IDS for BloomFilter */
if (peerflags & BITDHT_PEER_STATUS_DHT_ENGINE)
@ -1190,12 +1190,14 @@ void bdNode::recvPkt(char *msg, int len, struct sockaddr_in addr)
bdId connSrcAddr;
bdId connDestAddr;
uint32_t connMode;
uint32_t connParam = 0;
uint32_t connStatus;
uint32_t connType;
be_node *be_ConnSrcAddr = NULL;
be_node *be_ConnDestAddr = NULL;
be_node *be_ConnMode = NULL;
be_node *be_ConnParam = NULL;
be_node *be_ConnStatus = NULL;
be_node *be_ConnType = NULL;
if (beType == BITDHT_MSG_TYPE_CONNECT)
@ -1236,6 +1238,18 @@ void bdNode::recvPkt(char *msg, int len, struct sockaddr_in addr)
return;
}
/* Param */
be_ConnParam = beMsgGetDictNode(be_data, "param");
if (!be_ConnParam)
{
#ifdef DEBUG_NODE_PARSE
std::cerr << "bdNode::recvPkt() CONNECT Missing Param. Dropping Msg";
std::cerr << std::endl;
#endif
be_free(node);
return;
}
/* Status */
be_ConnStatus = beMsgGetDictNode(be_data, "status");
if (!be_ConnStatus)
@ -1276,6 +1290,11 @@ void bdNode::recvPkt(char *msg, int len, struct sockaddr_in addr)
beMsgGetUInt32(be_ConnMode, &connMode);
}
if (be_ConnParam)
{
beMsgGetUInt32(be_ConnParam, &connParam);
}
if (be_ConnStatus)
{
beMsgGetUInt32(be_ConnStatus, &connStatus);
@ -1409,7 +1428,7 @@ void bdNode::recvPkt(char *msg, int len, struct sockaddr_in addr)
//#endif
msgin_connect_genmsg(&srcId, &transId, connType,
&connSrcAddr, &connDestAddr,
connMode, connStatus);
connMode, connParam, connStatus);
break;
}
default:
@ -1788,7 +1807,7 @@ std::string getConnectMsgType(int msgtype)
}
}
void bdNode::msgout_connect_genmsg(bdId *id, bdToken *transId, int msgtype, bdId *srcAddr, bdId *destAddr, int mode, int status)
void bdNode::msgout_connect_genmsg(bdId *id, bdToken *transId, int msgtype, bdId *srcAddr, bdId *destAddr, int mode, int param, int status)
{
std::cerr << "bdConnectManager::msgout_connect_genmsg() Type: " << getConnectMsgType(msgtype);
std::cerr << " TransId: ";
@ -1800,6 +1819,7 @@ void bdNode::msgout_connect_genmsg(bdId *id, bdToken *transId, int msgtype, bdId
std::cerr << " DestAddr: ";
mFns->bdPrintId(std::cerr, destAddr);
std::cerr << " Mode: " << mode;
std::cerr << " Param: " << param;
std::cerr << " Status: " << status;
std::cerr << std::endl;
#ifdef DEBUG_NODE_MSGOUT
@ -1828,13 +1848,13 @@ void bdNode::msgout_connect_genmsg(bdId *id, bdToken *transId, int msgtype, bdId
char msg[10240];
int avail = 10240;
int blen = bitdht_connect_genmsg(transId, &(mOwnId), msgtype, srcAddr, destAddr, mode, status, msg, avail-1);
int blen = bitdht_connect_genmsg(transId, &(mOwnId), msgtype, srcAddr, destAddr, mode, param, status, msg, avail-1);
sendPkt(msg, blen, id->addr);
}
void bdNode::msgin_connect_genmsg(bdId *id, bdToken *transId, int msgtype,
bdId *srcAddr, bdId *destAddr, int mode, int status)
bdId *srcAddr, bdId *destAddr, int mode, int param, int status)
{
std::list<bdId>::iterator it;
@ -1848,6 +1868,7 @@ void bdNode::msgin_connect_genmsg(bdId *id, bdToken *transId, int msgtype,
std::cerr << " DestAddr: ";
mFns->bdPrintId(std::cerr, destAddr);
std::cerr << " Mode: " << mode;
std::cerr << " Param: " << param;
std::cerr << " Status: " << status;
std::cerr << std::endl;
#ifdef DEBUG_NODE_MSGS
@ -1864,21 +1885,21 @@ void bdNode::msgin_connect_genmsg(bdId *id, bdToken *transId, int msgtype,
mAccount.incCounter(BDACCOUNT_MSG_CONNECTREQUEST, false);
mConnMgr->recvedConnectionRequest(id, srcAddr, destAddr, mode);
mConnMgr->recvedConnectionRequest(id, srcAddr, destAddr, mode, param);
break;
case BITDHT_MSG_TYPE_CONNECT_REPLY:
peerflags = BITDHT_PEER_STATUS_RECV_CONNECT_MSG;
mAccount.incCounter(BDACCOUNT_MSG_CONNECTREPLY, false);
mConnMgr->recvedConnectionReply(id, srcAddr, destAddr, mode, status);
mConnMgr->recvedConnectionReply(id, srcAddr, destAddr, mode, param, status);
break;
case BITDHT_MSG_TYPE_CONNECT_START:
peerflags = BITDHT_PEER_STATUS_RECV_CONNECT_MSG;
mAccount.incCounter(BDACCOUNT_MSG_CONNECTSTART, false);
mConnMgr->recvedConnectionStart(id, srcAddr, destAddr, mode, status);
mConnMgr->recvedConnectionStart(id, srcAddr, destAddr, mode, param);
break;
case BITDHT_MSG_TYPE_CONNECT_ACK:

View File

@ -102,11 +102,11 @@ class bdNodePublisher
virtual void send_ping(bdId *id) = 0; /* message out */
virtual void send_query(bdId *id, bdNodeId *targetNodeId) = 0; /* message out */
virtual void send_connect_msg(bdId *id, int msgtype,
bdId *srcAddr, bdId *destAddr, int mode, int status) = 0;
bdId *srcAddr, bdId *destAddr, int mode, int param, int status) = 0;
// internal Callback -> normally continues to callbackConnect().
virtual void callbackConnect(bdId *srcId, bdId *proxyId, bdId *destId,
int mode, int point, int cbtype, int errcode) = 0;
int mode, int point, int param, int cbtype, int errcode) = 0;
};
@ -145,11 +145,11 @@ class bdNode: public bdNodePublisher
virtual void send_ping(bdId *id); /* message out */
virtual void send_query(bdId *id, bdNodeId *targetNodeId); /* message out */
virtual void send_connect_msg(bdId *id, int msgtype,
bdId *srcAddr, bdId *destAddr, int mode, int status);
bdId *srcAddr, bdId *destAddr, int mode, int param, int status);
// This is implemented in bdManager.
// virtual void callbackConnect(bdId *srcId, bdId *proxyId, bdId *destId,
// int mode, int point, int cbtype, int errcode);
// int mode, int point, int param, int cbtype, int errcode);
/* interaction with outside world (Accessed by controller to deliver us msgs) */
int outgoingMsg(struct sockaddr_in *addr, char *msg, int *len);
@ -200,9 +200,9 @@ void recvPkt(char *msg, int len, struct sockaddr_in addr);
void msgin_reply_post(bdId *id, bdToken *transId);
void msgout_connect_genmsg(bdId *id, bdToken *transId, int msgtype,
bdId *srcAddr, bdId *destAddr, int mode, int status);
bdId *srcAddr, bdId *destAddr, int mode, int param, int status);
void msgin_connect_genmsg(bdId *id, bdToken *transId, int msgtype,
bdId *srcAddr, bdId *destAddr, int mode, int status);
bdId *srcAddr, bdId *destAddr, int mode, int param, int status);

View File

@ -101,9 +101,13 @@ bool bdQuery::result(std::list<bdId> &answer)
sit = mClosest.begin();
eit = mClosest.upper_bound(mLimit);
int i = 0;
for(; sit != eit; sit++, i++)
for(; sit != eit; sit++)
{
answer.push_back(sit->second.mPeerId);
if ((sit->second).mLastRecvTime != 0)
{
answer.push_back(sit->second.mPeerId);
i++;
}
}
return (i > 0);
}
@ -252,7 +256,8 @@ int bdQuery::nextQuery(bdId &id, bdNodeId &targetNodeId)
/* check if we found the node */
if (mClosest.size() > 0)
{
if ((mClosest.begin()->second).mPeerId.id == mId)
if (((mClosest.begin()->second).mPeerId.id == mId) &&
((mClosest.begin()->second).mLastRecvTime != 0))
{
mState = BITDHT_QUERY_SUCCESS;
}

View File

@ -50,9 +50,10 @@
#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" // Full Connections
//#define BITDHT_VERSION "02" // Full DHT implementation.
//#define BITDHT_VERSION "00" // First Release of BitDHT with Connections (Proxy Support + Dht Stun)
#define BITDHT_VERSION "01" // Testing Connections
//#define BITDHT_VERSION "02" // Completed? Full Connections
//#define BITDHT_VERSION "04" // Full DHT implementation.?
/*************************************/
@ -125,20 +126,21 @@ void UdpBitDht::removeCallback(BitDhtCallback *cb)
mBitDhtManager->removeCallback(cb);
}
void UdpBitDht::ConnectionRequest(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t start)
bool UdpBitDht::ConnectionRequest(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t delay, uint32_t start)
{
bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/
mBitDhtManager->ConnectionRequest(laddr, target, mode, start);
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 answer)
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, answer);
mBitDhtManager->ConnectionAuth(srcId, proxyId, destId, mode, loc, bandwidth, delay, answer);
}
void UdpBitDht::ConnectionOptions(uint32_t allowedModes, uint32_t flags)

View File

@ -68,8 +68,9 @@ virtual void addCallback(BitDhtCallback *cb);
virtual void removeCallback(BitDhtCallback *cb);
/***** Connections Requests *****/
virtual void ConnectionRequest(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t start);
virtual void ConnectionAuth(bdId *srcId, bdId *proxyId, bdId *destId, uint32_t mode, uint32_t loc, uint32_t answer);
virtual bool ConnectionRequest(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t delay, uint32_t start);
virtual void ConnectionAuth(bdId *srcId, bdId *proxyId, bdId *destId, uint32_t mode, uint32_t loc,
uint32_t bandwidth, uint32_t delay, uint32_t answer);
virtual void ConnectionOptions(uint32_t allowedModes, uint32_t flags);
/***** Get Results Details *****/

View File

@ -75,10 +75,17 @@ UdpLayer *UdpStack::getUdpLayer() /* for testing only */
return udpLayer;
}
bool UdpStack::getLocalAddress(struct sockaddr_in &local)
{
local = laddr;
return true;
}
bool UdpStack::resetAddress(struct sockaddr_in &local)
{
std::cerr << "UdpStack::resetAddress(" << local << ")";
std::cerr << std::endl;
laddr = local;
return udpLayer->reset(local);
}

View File

@ -78,6 +78,7 @@ virtual ~UdpStack() { return; }
UdpLayer *getUdpLayer(); /* for testing only */
bool getLocalAddress(struct sockaddr_in &local);
bool resetAddress(struct sockaddr_in &local);

View File

@ -23,7 +23,8 @@
#include "dbase/cachestrapper.h"
#include "serialiser/rsconfigitems.h"
#include "pqi/p3connmgr.h"
#include "pqi/p3linkmgr.h"
#include "pqi/p3peermgr.h"
#include "util/rsdir.h"
#include <iostream>
@ -542,8 +543,8 @@ void CacheStore::locked_storeCacheEntry(const CacheData &data)
*
********************************* CacheStrapper ********************************/
CacheStrapper::CacheStrapper(p3ConnectMgr *cm)
:p3Config(CONFIG_TYPE_CACHE), mConnMgr(cm), csMtx("CacheStrapper")
CacheStrapper::CacheStrapper(p3LinkMgr *lm)
:p3Config(CONFIG_TYPE_CACHE), mLinkMgr(lm), csMtx("CacheStrapper")
{
return;
}
@ -595,7 +596,7 @@ void CacheStrapper::refreshCache(const CacheData &data)
std::list<std::string> ids;
std::list<std::string>::iterator it;
mConnMgr->getOnlineList(ids);
mLinkMgr->getOnlineList(ids);
RsStackMutex stack(csMtx); /******* LOCK STACK MUTEX *********/
for(it = ids.begin(); it != ids.end(); it++)
@ -607,7 +608,7 @@ void CacheStrapper::refreshCache(const CacheData &data)
mCacheUpdates.push_back(std::make_pair(*it, data));
}
mCacheUpdates.push_back(std::make_pair(mConnMgr->getOwnId(), data));
mCacheUpdates.push_back(std::make_pair(mLinkMgr->getOwnId(), data));
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
}
@ -688,7 +689,7 @@ void CacheStrapper::listCaches(std::ostream &out)
{
/* can overwrite for more control! */
std::map<uint16_t, CachePair>::iterator it;
out << "CacheStrapper::listCaches() [" << mConnMgr->getOwnId();
out << "CacheStrapper::listCaches() [" << mLinkMgr->getOwnId();
out << "] " << " Total Caches: " << caches.size();
out << std::endl;
for(it = caches.begin(); it != caches.end(); it++)
@ -781,7 +782,7 @@ bool CacheStrapper::saveList(bool &cleanup, std::list<RsItem *>& saveData)
std::list<CacheData>::iterator cit;
std::list<CacheData> ownCaches;
std::list<CacheData> remoteCaches;
std::string ownId = mConnMgr->getOwnId();
std::string ownId = mLinkMgr->getOwnId();
std::map<uint16_t, CachePair>::iterator it;
for(it = caches.begin(); it != caches.end(); it++)
@ -861,11 +862,11 @@ bool CacheStrapper::loadList(std::list<RsItem *>& load)
#endif
std::list<CacheData> ownCaches;
std::list<CacheData> remoteCaches;
std::string ownId = mConnMgr->getOwnId();
std::string ownId = mLinkMgr->getOwnId();
peerConnectState ownState;
mConnMgr->getOwnNetStatus(ownState);
std::string ownName = ownState.name+" ("+ownState.location+")";
//peerConnectState ownState;
//mPeerMgr->getOwnNetStatus(ownState);
//std::string ownName = ownState.name+" ("+ownState.location+")";
std::map<std::string, std::list<std::string> > saveFiles;
std::map<std::string, std::list<std::string> >::iterator sit;
@ -885,6 +886,7 @@ bool CacheStrapper::loadList(std::list<RsItem *>& load)
cd.pid = rscc->pid;
#if 0
if(cd.pid == ownId)
{
cd.pname = ownName;
@ -892,9 +894,10 @@ bool CacheStrapper::loadList(std::list<RsItem *>& load)
else
{
peerConnectState pca;
mConnMgr->getFriendNetStatus(rscc->pid, pca);
mPeerMgr->getFriendNetStatus(rscc->pid, pca);
cd.pname = pca.name+" ("+pca.location+")";
}
#endif
cd.cid.type = rscc->cachetypeid;
cd.cid.subid = rscc->cachesubid;

View File

@ -92,7 +92,7 @@ class CacheData
public:
RsPeerId pid; /// peer id
std::string pname; /// peer name (can be used by cachestore)
/// REMOVED as a WASTE to look it up everywhere! std::string pname; /// peer name (can be used by cachestore)
CacheId cid; /// cache id
std::string path; /// file system path where physical cache data is located
std::string name;
@ -408,6 +408,9 @@ bool operator<(const CachePair &a, const CachePair &b);
* CacheStrapper: maintains a set of CacheSources, and CacheStores,
* queries and updates as new information arrives.
*/
class p3LinkMgr;
class CacheStrapper: public pqiMonitor, public p3Config
{
public:
@ -416,7 +419,7 @@ class CacheStrapper: public pqiMonitor, public p3Config
* @param cm handle used by strapper for getting peer connection information (online peers, sslids...)
* @return
*/
CacheStrapper(p3ConnectMgr *cm);
CacheStrapper(p3LinkMgr *lm);
virtual ~CacheStrapper() { return; }
/************* from pqiMonitor *******************/
@ -489,7 +492,7 @@ virtual bool loadList(std::list<RsItem *>& load);
private:
/* these are static - so shouldn't need mutex */
p3ConnectMgr *mConnMgr;
p3LinkMgr *mLinkMgr;
std::map<uint16_t, CachePair> caches;

View File

@ -435,7 +435,7 @@ bool FileIndexMonitor::loadLocalCache(const CacheData &data) /* called with sto
std::cerr << std::endl;
#endif
fi.root->row = 0;
fi.root->name = data.pname ;
fi.root->name = data.pid; // XXX Hack here - TODO
}
else
{

View File

@ -24,12 +24,12 @@
#include "dbase/fistore.h"
#include "retroshare/rsexpr.h"
#include "serialiser/rsserviceids.h"
#include "pqi/p3connmgr.h"
#include "pqi/p3peermgr.h"
FileIndexStore::FileIndexStore(CacheStrapper *cs, CacheTransfer *cft,
NotifyBase *cb_in,p3ConnectMgr *cnmgr, RsPeerId ownid, std::string cachedir)
NotifyBase *cb_in,p3PeerMgr *cnmgr, RsPeerId ownid, std::string cachedir)
:CacheStore(RS_SERVICE_TYPE_FILE_INDEX, false, cs, cft, cachedir),
localId(ownid), localindex(NULL), cb(cb_in),mConnMgr(cnmgr)
localId(ownid), localindex(NULL), cb(cb_in),mPeerMgr(cnmgr)
{
return;
}
@ -83,7 +83,7 @@ int FileIndexStore::loadCache(const CacheData &data)
FileIndex *finew = new FileIndex(data.pid);
if(mConnMgr->isFriend(data.pid))
if(mPeerMgr->isFriend(data.pid))
{
// We discard file lists from non friends. This is the place to remove file lists of deleted friends
// from the cache. Doing this, the file list still shows in a session where we deleted a friend, but will be removed
@ -95,7 +95,7 @@ int FileIndexStore::loadCache(const CacheData &data)
std::cerr << "FileIndexStore::loadCache() Succeeded!" << std::endl;
#endif
/* set the name */
finew->root->name = data.pname;
finew->root->name = data.pid; // HACK HERE TODO XXX. name;
if (local)
{

View File

@ -34,7 +34,7 @@
*
*/
class p3ConnectMgr ;
class p3PeerMgr ;
#include "dbase/findex.h"
#include "dbase/cachestrapper.h"
@ -65,7 +65,7 @@ class FileIndexStore: public CacheStore
{
public:
FileIndexStore(CacheStrapper *cs, CacheTransfer *cft, NotifyBase *cb_in,p3ConnectMgr *cmgr, RsPeerId ownid, std::string cachedir);
FileIndexStore(CacheStrapper *cs, CacheTransfer *cft, NotifyBase *cb_in,p3PeerMgr *pmgr, RsPeerId ownid, std::string cachedir);
virtual ~FileIndexStore();
/* virtual functions overloaded by cache implementor */
@ -96,7 +96,7 @@ virtual int loadCache(const CacheData &data); /* actual load, once data availa
FileIndex *localindex;
NotifyBase *cb;
p3ConnectMgr *mConnMgr ;
p3PeerMgr *mPeerMgr ;
};

View File

@ -0,0 +1,994 @@
/*
* libretroshare/src/dht: connectstatebox.cc
*
* RetroShare DHT C++ Interface.
*
* 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".
*
*/
#include "dht/connectstatebox.h"
#include "retroshare/rsconfig.h"
#include "util/rsrandom.h"
#include <iostream>
#include <sstream>
/**
*
* #define TESTING_PERIODS 1
*
**/
/* Have made the PROXY Attempts + MAX_TIME much larger,
* have have potential for this to take a while.
*/
#ifdef TESTING_PERIODS
#define FAILED_WAIT_TIME (1800) // 5 minutes.
#define TCP_WAIT_TIME (10) // 1/6 minutes.
#define DIRECT_MAX_WAIT_TIME (30) // 1/6 minutes.
#define PROXY_BASE_WAIT_TIME (30) // 1/6 minutes.
#define PROXY_MAX_WAIT_TIME (120) // 1/6 minutes.
#define RELAY_MAX_WAIT_TIME (30) // 1/6 minutes.
#define REVERSE_WAIT_TIME (30) // 1/2 minutes.
#define MAX_DIRECT_ATTEMPTS (3)
#define MAX_PROXY_ATTEMPTS (10)
#define MAX_RELAY_ATTEMPTS (3)
#define MAX_DIRECT_FAILED_ATTEMPTS (1)
#define MAX_PROXY_FAILED_ATTEMPTS (2)
#define MAX_RELAY_FAILED_ATTEMPTS (1)
#else
#define FAILED_WAIT_TIME (1800) // 30 minutes.
#define TCP_WAIT_TIME (30) // 1 minutes.
#define DIRECT_MAX_WAIT_TIME (60) // 1 minutes.
#define PROXY_BASE_WAIT_TIME (30) // 1/2 minutes.
#define PROXY_MAX_WAIT_TIME (120) // 1 minutes.
#define RELAY_MAX_WAIT_TIME (60) // 1 minutes.
#define REVERSE_WAIT_TIME (300) // 5 minutes.
#define MAX_DIRECT_ATTEMPTS (5)
#define MAX_PROXY_ATTEMPTS (10)
#define MAX_RELAY_ATTEMPTS (5)
#define MAX_DIRECT_FAILED_ATTEMPTS (3)
#define MAX_PROXY_FAILED_ATTEMPTS (3)
#define MAX_RELAY_FAILED_ATTEMPTS (3)
#endif
PeerConnectStateBox::PeerConnectStateBox()
{
//mPeerId = id;
time_t now = time(NULL);
mState = CSB_START;
mNetState = CSB_NETSTATE_UNKNOWN;
mStateTS = now;
mNoAttempts = 0;
mNoFailedAttempts = 0;
mNextAttemptTS = now;
mAttemptLength = 0;
}
std::string NetStateAsString(uint32_t netstate)
{
std::string str;
switch(netstate)
{
case CSB_NETSTATE_FORWARD:
str = "Forwarded";
break;
case CSB_NETSTATE_STABLENAT:
str = "StableNat";
break;
case CSB_NETSTATE_EXCLUSIVENAT:
str = "ExclusiveNat";
break;
case CSB_NETSTATE_FIREWALLED:
str = "Firewalled";
break;
default:
str = "Unknown NetState";
break;
}
return str;
}
std::string StateAsString(uint32_t state)
{
std::string str;
switch(state)
{
case CSB_START:
str = "Start";
break;
case CSB_TCP_WAIT:
str = "TCP Wait";
break;
case CSB_DIRECT_ATTEMPT:
str = "Direct Attempt";
break;
case CSB_DIRECT_WAIT:
str = "Direct Wait";
break;
case CSB_PROXY_ATTEMPT:
str = "Proxy Attempt:";
break;
case CSB_PROXY_WAIT:
str = "Proxy Wait:";
break;
case CSB_RELAY_ATTEMPT:
str = "Relay Attempt:";
break;
case CSB_RELAY_WAIT:
str = "Relay Wait:";
break;
case CSB_REVERSE_WAIT:
str = "Reverse Wait:";
break;
case CSB_FAILED_WAIT:
str = "Failed Wait:";
break;
case CSB_CONNECTED:
str = "Connected:";
break;
default:
str = "Unknown State";
break;
}
return str;
}
std::string UpdateAsString(uint32_t update)
{
std::string str;
switch(update)
{
case CSB_UPDATE_NONE:
str = "none";
break;
case CSB_UPDATE_CONNECTED:
str = "Connected";
break;
case CSB_UPDATE_DISCONNECTED:
str = "Disconnected";
break;
case CSB_UPDATE_AUTH_DENIED:
str = "Auth Denied";
break;
case CSB_UPDATE_FAILED_ATTEMPT:
str = "Failed Attempt:";
break;
case CSB_UPDATE_MODE_UNAVAILABLE:
str = "Mode Unavailable:";
break;
default:
str = "Unknown Update";
break;
}
return str;
}
void PeerConnectStateBox::errorMsg(std::ostream &out, std::string msg, uint32_t updateParam)
{
out << "PeerConnectStateBox::ERROR " << msg;
out << " NetState: " << NetStateAsString(mNetState);
out << " State: " << StateAsString(mState);
out << " Update: " << UpdateAsString(updateParam);
out << " for peer: " << mPeerId;
out << std::endl;
}
void PeerConnectStateBox::stateMsg(std::ostream &out, std::string msg, uint32_t updateParam)
{
out << "PeerConnectStateBox::MSG " << msg;
out << " NetState: " << NetStateAsString(mNetState);
out << " State: " << StateAsString(mState);
out << " Update: " << UpdateAsString(updateParam);
out << " for peer: " << mPeerId;
out << std::endl;
}
std::string PeerConnectStateBox::connectState() const
{
std::string str = StateAsString(mState);
std::ostringstream out;
time_t now = time(NULL);
out << str << "(" << mNoAttempts << "/" << mNoFailedAttempts << ") for " << now - mStateTS << " secs";
if ( (mState == CSB_CONNECTED) || (mState == CSB_DIRECT_ATTEMPT) ||
(mState == CSB_PROXY_ATTEMPT) || (mState == CSB_RELAY_ATTEMPT) ||
(mState == CSB_FAILED_WAIT) )
{
out << " Last Attempt: " << mAttemptLength;
}
else
{
out << " LA: " << mAttemptLength;
out << " NextAttempt: " << mNextAttemptTS - now;
}
return out.str();
}
uint32_t convertNetStateToInternal(uint32_t netmode, uint32_t nathole, uint32_t nattype)
{
uint32_t connNet = CSB_NETSTATE_UNKNOWN;
if (netmode == RSNET_NETWORK_EXTERNALIP)
{
connNet = CSB_NETSTATE_FORWARD;
}
else if ((nathole != RSNET_NATHOLE_UNKNOWN) && (nathole != RSNET_NATHOLE_NONE))
{
connNet = CSB_NETSTATE_FORWARD;
}
else if (netmode == RSNET_NETWORK_BEHINDNAT)
{
if ((nattype == RSNET_NATTYPE_RESTRICTED_CONE) ||
(nattype == RSNET_NATTYPE_FULL_CONE))
{
connNet = CSB_NETSTATE_STABLENAT;
}
else if (nattype == RSNET_NATTYPE_DETERM_SYM)
{
connNet = CSB_NETSTATE_EXCLUSIVENAT;
}
else
{
connNet = CSB_NETSTATE_FIREWALLED;
}
}
return connNet;
}
bool shouldUseProxyPortInternal(uint32_t netstate)
{
if (netstate == CSB_NETSTATE_FORWARD)
{
return false;
}
return true;
}
bool PeerConnectStateBox::shouldUseProxyPort(uint32_t netmode, uint32_t nathole, uint32_t nattype)
{
uint32_t netstate = convertNetStateToInternal(netmode, nathole, nattype);
return shouldUseProxyPortInternal(netstate);
}
uint32_t PeerConnectStateBox::calcNetState(uint32_t netmode, uint32_t nathole, uint32_t nattype)
{
uint32_t netstate = convertNetStateToInternal(netmode, nathole, nattype);
return netstate;
}
uint32_t PeerConnectStateBox::connectCb(uint32_t cbtype, uint32_t netmode, uint32_t nathole, uint32_t nattype)
{
uint32_t netstate = convertNetStateToInternal(netmode, nathole, nattype);
std::cerr << "PeerConnectStateBox::connectCb(";
if (cbtype == CSB_CONNECT_DIRECT)
{
std::cerr << "DIRECT";
}
else
{
std::cerr << "UNREACHABLE";
}
std::cerr << "," << NetStateAsString(netstate) << ")";
std::cerr << std::endl;
if (netstate != mNetState)
{
std::cerr << "PeerConnectStateBox::connectCb() WARNING Changing NetState from: ";
std::cerr << " from: " << NetStateAsString(mNetState);
std::cerr << " to: " << NetStateAsString(netstate);
std::cerr << " for peer: " << mPeerId;
std::cerr << std::endl;
mNetState = netstate;
}
if (cbtype == CSB_CONNECT_DIRECT)
{
return connectCb_direct();
}
else
{
return connectCb_unreachable();
}
}
uint32_t PeerConnectStateBox::connectCb_direct()
{
uint32_t retval = 0;
time_t now = time(NULL);
switch(mState)
{
case CSB_DIRECT_ATTEMPT:
{
errorMsg(std::cerr, "mState == DIRECT_ATTEMPT", 0);
retval = CSB_ACTION_WAIT;
}
break;
case CSB_PROXY_ATTEMPT:
{
errorMsg(std::cerr, "mState == PROXY_ATTEMPT", 0);
retval = CSB_ACTION_WAIT;
}
break;
case CSB_RELAY_ATTEMPT:
{
errorMsg(std::cerr, "mState == RELAY_ATTEMPT", 0);
retval = CSB_ACTION_WAIT;
}
break;
case CSB_FAILED_WAIT:
{
/* if too soon */
//if (now - mStateTS < FAILED_WAIT_TIME)
if (mNextAttemptTS > now)
{
/* same state */
retval = CSB_ACTION_WAIT;
break;
}
} /* FALLTHROUGH TO START CASE */
default:
case CSB_REVERSE_WAIT:
case CSB_PROXY_WAIT:
case CSB_RELAY_WAIT:
{
if (mState != CSB_FAILED_WAIT)
{
/* ERROR */
errorMsg(std::cerr, "mState != FAILED_WAIT", 0);
}
} /* FALLTHROUGH TO START CASE */
case CSB_START:
{
/* starting up the connection */
mState = CSB_TCP_WAIT;
retval = CSB_ACTION_TCP_CONN;
mStateTS = now;
mNoAttempts = 0;
mNoFailedAttempts = 0;
mNextAttemptTS = now + TCP_WAIT_TIME;
}
break;
case CSB_TCP_WAIT:
{
/* if too soon */
//if (now - mStateTS < TCP_WAIT_TIME)
if (mNextAttemptTS > now)
{
/* same state */
retval = CSB_ACTION_WAIT;
}
else
{
/* try again */
mState = CSB_DIRECT_ATTEMPT;
retval = CSB_ACTION_DIRECT_CONN | CSB_ACTION_DHT_PORT;
mStateTS = now;
mNoAttempts = 0;
mNoFailedAttempts = 0;
}
}
break;
case CSB_DIRECT_WAIT:
{
/* if too soon */
//if (now - mStateTS < DIRECT_WAIT_TIME)
if (mNextAttemptTS > now)
{
/* same state */
retval = CSB_ACTION_WAIT;
}
else if ((mNoAttempts >= MAX_DIRECT_ATTEMPTS) ||
(mNoFailedAttempts >= MAX_DIRECT_FAILED_ATTEMPTS))
{
/* if too many attempts */
/* no RELAY attempt => FAILED_WAIT */
mState = CSB_FAILED_WAIT;
retval = CSB_ACTION_WAIT;
mStateTS = now;
mNoAttempts = 0;
mNoFailedAttempts = 0;
mNextAttemptTS = now + FAILED_WAIT_TIME;
}
else
{
/* try again */
mState = CSB_DIRECT_ATTEMPT;
retval = CSB_ACTION_DIRECT_CONN | CSB_ACTION_DHT_PORT;
mStateTS = now;
mNoAttempts++;
}
}
break;
case CSB_CONNECTED:
{
retval = CSB_ACTION_WAIT;
}
break;
}
return retval;
}
uint32_t PeerConnectStateBox::connectCb_unreachable()
{
uint32_t retval = 0;
uint32_t proxyPortMode = CSB_ACTION_PROXY_PORT;
if (!shouldUseProxyPortInternal(mNetState))
{
proxyPortMode = CSB_ACTION_DHT_PORT;
}
time_t now = time(NULL);
switch(mState)
{
case CSB_DIRECT_ATTEMPT:
{
errorMsg(std::cerr, "mState == DIRECT_ATTEMPT", 0);
retval = CSB_ACTION_WAIT;
}
break;
case CSB_PROXY_ATTEMPT:
{
errorMsg(std::cerr, "mState == PROXY_ATTEMPT", 0);
retval = CSB_ACTION_WAIT;
}
break;
case CSB_RELAY_ATTEMPT:
{
errorMsg(std::cerr, "mState == RELAY_ATTEMPT", 0);
retval = CSB_ACTION_WAIT;
}
break;
case CSB_FAILED_WAIT:
{
/* if too soon */
//if (now - mStateTS < FAILED_WAIT_TIME)
if (mNextAttemptTS > now)
{
/* same state */
stateMsg(std::cerr, "too soon, no action", 0);
retval = CSB_ACTION_WAIT;
break;
}
} /* FALLTHROUGH TO START CASE */
default:
case CSB_DIRECT_WAIT:
{
if (mState != CSB_FAILED_WAIT)
{
/* ERROR */
errorMsg(std::cerr, "mState != FAILED_WAIT", 0);
}
} /* FALLTHROUGH TO START CASE */
case CSB_START:
{
/* starting up the connection */
mState = CSB_TCP_WAIT;
retval = CSB_ACTION_WAIT; /* NO POINT TRYING A TCP_CONN */
mStateTS = now;
mNoAttempts = 0;
mNoFailedAttempts = 0;
mNextAttemptTS = now + TCP_WAIT_TIME;
}
break;
case CSB_TCP_WAIT:
{
/* if too soon */
if (mNextAttemptTS > now)
{
/* same state */
retval = CSB_ACTION_WAIT;
}
else
{
/* starting up the connection */
if (mState != CSB_NETSTATE_FIREWALLED)
{
stateMsg(std::cerr, "not Firewalled => PROXY_ATTEMPT", 0);
mState = CSB_PROXY_ATTEMPT;
retval = CSB_ACTION_PROXY_CONN | proxyPortMode;
}
else
{
stateMsg(std::cerr, "Firewalled => RELAY_ATTEMPT", 0);
mState = CSB_RELAY_ATTEMPT;
retval = CSB_ACTION_RELAY_CONN | CSB_ACTION_DHT_PORT;
}
mStateTS = now;
mNoAttempts = 0;
mNoFailedAttempts = 0;
}
}
break;
case CSB_PROXY_WAIT:
{
/* if too soon */
if (mNextAttemptTS > now)
{
/* same state */
stateMsg(std::cerr, "too soon, no action", 0);
retval = CSB_ACTION_WAIT;
}
else if ((mNoAttempts >= MAX_PROXY_ATTEMPTS) ||
(mNoFailedAttempts >= MAX_PROXY_FAILED_ATTEMPTS))
{
/* if too many attempts */
/* switch to RELAY attempt */
stateMsg(std::cerr, "too many PROXY => RELAY_ATTEMPT", 0);
mState = CSB_RELAY_ATTEMPT;
retval = CSB_ACTION_RELAY_CONN | CSB_ACTION_DHT_PORT;
mStateTS = now;
mNoAttempts = 0;
mNoFailedAttempts = 0;
}
else
{
/* try again */
stateMsg(std::cerr, "PROXY_ATTEMPT try again", 0);
mState = CSB_PROXY_ATTEMPT;
retval = CSB_ACTION_PROXY_CONN | proxyPortMode;
mStateTS = now;
mNoAttempts++;
}
}
break;
case CSB_REVERSE_WAIT:
{
/* if too soon */
//if (now - mStateTS < REVERSE_WAIT_TIME)
if (mNextAttemptTS > now)
{
/* same state */
stateMsg(std::cerr, "too soon, no action", 0);
retval = CSB_ACTION_WAIT;
}
else
{
stateMsg(std::cerr, "timeout => RELAY_ATTEMPT", 0);
/* switch to RELAY attempt */
mState = CSB_RELAY_ATTEMPT;
retval = CSB_ACTION_RELAY_CONN | CSB_ACTION_DHT_PORT;
mStateTS = now;
mNoAttempts = 0;
mNoFailedAttempts = 0;
}
}
break;
case CSB_RELAY_WAIT:
{
/* if too soon */
if (mNextAttemptTS > now)
{
/* same state */
stateMsg(std::cerr, "too soon, no action", 0);
retval = CSB_ACTION_WAIT;
}
else if ((mNoAttempts >= MAX_RELAY_ATTEMPTS) ||
(mNoFailedAttempts >= MAX_RELAY_FAILED_ATTEMPTS))
{
/* if too many attempts */
/* switch to RELAY attempt */
stateMsg(std::cerr, "too many RELAY => FAILED_WAIT", 0);
mState = CSB_FAILED_WAIT;
retval = CSB_ACTION_WAIT;
mStateTS = now;
mNoAttempts = 0;
mNoFailedAttempts = 0;
mNextAttemptTS = now + FAILED_WAIT_TIME;
}
else
{
/* try again */
stateMsg(std::cerr, "RELAY_ATTEMPT try again", 0);
mState = CSB_RELAY_ATTEMPT;
retval = CSB_ACTION_RELAY_CONN | CSB_ACTION_DHT_PORT;
mStateTS = now;
mNoAttempts++;
}
}
break;
case CSB_CONNECTED:
{
stateMsg(std::cerr, "connected => no action", 0);
retval = CSB_ACTION_WAIT;
}
break;
}
return retval;
}
uint32_t PeerConnectStateBox::updateCb(uint32_t update)
{
/* The Error Callback doesn't trigger another connection.
* but can change the connection state
*
* Possible Errors:
* 1) AUTH DENIED. (fatal)
* 2) MODE UNAVILABLE
* 3) RETRY ATTEMPT
* 4) FAILED ATTEMPT
* 5) CONNECTION
* 6) DISCONNECTED.
*
* Fitting these into the states:
case CSB_START:
CONNECTION => CSB_CONNECTED
error if: AUTH DENIED, MODE UNAVAILABLE, FAILED ATTEMPT, RETRY ATTEMPT, DISCONNECTED
case CSB_CONNECTED:
CONNECTION => CSB_CONNECTED
DISCONNECTED => CSB_START
error if: AUTH DENIED, MODE UNAVAILABLE, FAILED ATTEMPT, RETRY ATTEMPT
case CSB_FAILED_WAIT:
CONNECTION => CSB_CONNECTED
error if: AUTH DENIED, MODE UNAVAILABLE, FAILED ATTEMPT, RETRY ATTEMPT, DISCONNECTED
case CSB_REVERSE_WAIT:
CONNECTION => CSB_CONNECTED
error if: AUTH DENIED, MODE UNAVAILABLE, FAILED ATTEMPT, RETRY ATTEMPT, DISCONNECTED
case CSB_DIRECT_ATTEMPT:
CONNECTION => CSB_CONNECTED
AUTH DENIED => CSB_FAILED_WAIT
FAILED ATTEMPT => stay here.
RETRY ATTEMPT => stay here
MODE UNAVAILABLE - probably error => CSB_FAILED_WAIT
error if: MODE UNAVAILABLE, DISCONNECTED
case CSB_PROXY_ATTEMPT:
CONNECTION => CSB_CONNECTED
AUTH DENIED => CSB_FAILED_WAIT
FAILED ATTEMPT => stay here.
RETRY ATTEMPT => stay here
MODE_UNAVAILABLE => CSB_REVERSE_WAIT | CSB_RELAY_ATTEMPT
error if: DISCONNECTED
case CSB_RELAY_ATTEMPT:
CONNECTION => CSB_CONNECTED
AUTH DENIED => CSB_FAILED_WAIT
FAILED ATTEMPT => stay here.
RETRY ATTEMPT => stay here
MODE_UNAVAILABLE => CSB_FAILED_WAIT
error if: DISCONNECTED
case CSB_DIRECT_WAIT:
CONNECTION => CSB_CONNECTED
error if: AUTH DENIED, MODE UNAVAILABLE, FAILED ATTEMPT, RETRY ATTEMPT, DISCONNECTED
case CSB_PROXY_WAIT:
CONNECTION => CSB_CONNECTED
error if: AUTH_DENIED, MODE UNAVAILABLE, FAILED ATTEMPT, RETRY ATTEMPT, DISCONNECTED
case CSB_RELAY_ATTEMPT:
CONNECTION => CSB_CONNECTED
error if: AUTH_DENIED, MODE UNAVAILABLE, FAILED ATTEMPT, RETRY ATTEMPT, DISCONNECTED
*/
/* DO Connect / Disconnect Updates ... very specific! */
time_t now = time(NULL);
switch(update)
{
case CSB_UPDATE_CONNECTED:
{
if ((mState == CSB_DIRECT_ATTEMPT) || (mState == CSB_PROXY_ATTEMPT) || (mState == CSB_PROXY_ATTEMPT))
{
mAttemptLength = now - mStateTS;
}
else
{
mAttemptLength = 0;
}
stateMsg(std::cerr, "=> CONNECTED", update);
mState = CSB_CONNECTED;
mStateTS = now;
return 0;
}
break;
case CSB_UPDATE_DISCONNECTED:
{
if (mState != CSB_CONNECTED)
{
/* ERROR, ignore (as already in disconnected state) */
errorMsg(std::cerr, "mState != CSB_CONNECTED", update);
}
else
{
stateMsg(std::cerr, "=> START", update);
/* move to START state */
mState = CSB_START;
mStateTS = now;
return 1;
}
return 0;
}
break;
}
/* Now catch errors for feedback when we should be WAITING */
switch(mState)
{
default:
case CSB_DIRECT_WAIT:
case CSB_PROXY_WAIT:
case CSB_RELAY_WAIT:
case CSB_REVERSE_WAIT:
case CSB_FAILED_WAIT:
case CSB_START:
case CSB_CONNECTED: /* impossible */
{
/* ERROR */
/* shouldn't receive anything here! */
errorMsg(std::cerr, "shouldnt get anything", update);
return 0;
}
break;
case CSB_DIRECT_ATTEMPT:
case CSB_PROXY_ATTEMPT:
case CSB_RELAY_ATTEMPT:
{
/* OKAY */
}
break;
}
switch(update)
{
/* if AUTH_DENIED ... => FAILED_WAIT */
case CSB_UPDATE_AUTH_DENIED:
{
stateMsg(std::cerr, "=> FAILED WAIT", update);
mState = CSB_FAILED_WAIT;
mStateTS = now;
mAttemptLength = now - mStateTS;
mNextAttemptTS = now + FAILED_WAIT_TIME;
return 1;
}
break;
/* if standard FAIL => stay where we are */
case CSB_UPDATE_RETRY_ATTEMPT:
{
stateMsg(std::cerr, "RETRY FAIL => switch to wait state", update);
mAttemptLength = now - mStateTS;
switch(mState)
{
case CSB_DIRECT_ATTEMPT:
mState = CSB_DIRECT_WAIT;
mStateTS = now;
mNextAttemptTS = now + RSRandom::random_u32() % DIRECT_MAX_WAIT_TIME;
break;
case CSB_PROXY_ATTEMPT:
mState = CSB_PROXY_WAIT;
mStateTS = now;
mNextAttemptTS = now + PROXY_BASE_WAIT_TIME + (RSRandom::random_u32() % (PROXY_MAX_WAIT_TIME - PROXY_BASE_WAIT_TIME));
break;
case CSB_RELAY_ATTEMPT:
mState = CSB_RELAY_WAIT;
mStateTS = now;
mNextAttemptTS = now + RSRandom::random_u32() % RELAY_MAX_WAIT_TIME;
break;
default:
stateMsg(std::cerr, "RETRY FAIL, but unusual state", update);
break;
}
return 1;
}
/* if standard FAIL => stay where we are */
case CSB_UPDATE_FAILED_ATTEMPT:
{
stateMsg(std::cerr, "STANDARD FAIL => switch to wait state", update);
mNoFailedAttempts++;
mAttemptLength = now - mStateTS;
switch(mState)
{
case CSB_DIRECT_ATTEMPT:
mState = CSB_DIRECT_WAIT;
mStateTS = now;
mNextAttemptTS = now + RSRandom::random_u32() % DIRECT_MAX_WAIT_TIME;
break;
case CSB_PROXY_ATTEMPT:
mState = CSB_PROXY_WAIT;
mStateTS = now;
mNextAttemptTS = now + PROXY_BASE_WAIT_TIME + (RSRandom::random_u32() % (PROXY_MAX_WAIT_TIME - PROXY_BASE_WAIT_TIME));
break;
case CSB_RELAY_ATTEMPT:
mState = CSB_RELAY_WAIT;
mStateTS = now;
mNextAttemptTS = now + RSRandom::random_u32() % RELAY_MAX_WAIT_TIME;
break;
default:
stateMsg(std::cerr, "STANDARD FAIL, but unusual state", update);
break;
}
return 1;
}
break;
/* finally MODE_UNAVAILABLE */
case CSB_UPDATE_MODE_UNAVAILABLE:
{
mAttemptLength = now - mStateTS;
if (mState == CSB_PROXY_ATTEMPT)
{
if (mNetState == CSB_NETSTATE_FORWARD)
{
stateMsg(std::cerr, "as FORWARDED => REVERSE_WAIT", update);
mState = CSB_REVERSE_WAIT;
mStateTS = now;
mNextAttemptTS = now + REVERSE_WAIT_TIME;
}
else
{
stateMsg(std::cerr, "as !FORWARDED => RELAY_ATTEMPT", update);
mState = CSB_RELAY_WAIT;
mNoAttempts = 0;
mStateTS = now;
mNextAttemptTS = now + RSRandom::random_u32() % RELAY_MAX_WAIT_TIME;
}
return 1;
}
else
{
stateMsg(std::cerr, "MODE UNAVAIL => FAILED_WAIT", update);
mState = CSB_FAILED_WAIT;
mStateTS = now;
mNextAttemptTS = now + FAILED_WAIT_TIME;
if ((mState == CSB_DIRECT_ATTEMPT)
|| (mState == CSB_PROXY_ATTEMPT))
{
/* OKAY */
return 1;
}
else
{
/* ERROR */
errorMsg(std::cerr, "strange MODE", update);
return 0;
}
}
}
break;
default:
{
/* ERROR */
errorMsg(std::cerr, "impossible default", update);
}
break;
}
/* if we get here... ERROR */
errorMsg(std::cerr, "if we get here => ERROR", update);
return 0;
}
bool PeerConnectStateBox::storeProxyPortChoice(uint32_t flags, bool useProxyPort)
{
mProxyPortFlags = flags;
mProxyPortChoice = useProxyPort;
mProxyPortTS = time(NULL);
return useProxyPort;
}
bool PeerConnectStateBox::getProxyPortChoice()
{
time_t now = time(NULL);
std::cerr << "PeerConnectStateBox::getProxyPortChoice() Using ConnectLogic Info from: ";
std::cerr << now-mProxyPortTS << " ago. Flags: " << mProxyPortFlags;
std::cerr << " UseProxyPort? " << mProxyPortChoice;
std::cerr << std::endl;
return mProxyPortChoice;
}

View File

@ -0,0 +1,124 @@
#ifndef CONNECT_STATUS_BOX_H
#define CONNECT_STATUS_BOX_H
/*
* libretroshare/src/dht: connectstatebox.h
*
* RetroShare DHT C++ Interface.
*
* 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".
*
*/
/* a connect state box */
#define CSB_START 1
#define CSB_TCP_WAIT 2
#define CSB_DIRECT_ATTEMPT 3
#define CSB_DIRECT_WAIT 4
#define CSB_PROXY_ATTEMPT 5
#define CSB_PROXY_WAIT 6
#define CSB_RELAY_ATTEMPT 7
#define CSB_RELAY_WAIT 8
#define CSB_REVERSE_WAIT 9
#define CSB_FAILED_WAIT 10
#define CSB_CONNECTED 11
#define CSB_NETSTATE_UNKNOWN 0
#define CSB_NETSTATE_FORWARD 1
#define CSB_NETSTATE_STABLENAT 2
#define CSB_NETSTATE_EXCLUSIVENAT 3
#define CSB_NETSTATE_FIREWALLED 4
#define CSB_CONNECT_DIRECT 1
#define CSB_CONNECT_UNREACHABLE 2
/* return values */
#define CSB_ACTION_MASK_MODE 0x00ff
#define CSB_ACTION_MASK_PORT 0xff00
#define CSB_ACTION_WAIT 0x0001
#define CSB_ACTION_TCP_CONN 0x0002
#define CSB_ACTION_DIRECT_CONN 0x0004
#define CSB_ACTION_PROXY_CONN 0x0008
#define CSB_ACTION_RELAY_CONN 0x0010
#define CSB_ACTION_DHT_PORT 0x0100
#define CSB_ACTION_PROXY_PORT 0x0200
/* update input */
#define CSB_UPDATE_NONE 0x0000
#define CSB_UPDATE_CONNECTED 0x0001
#define CSB_UPDATE_DISCONNECTED 0x0002
#define CSB_UPDATE_AUTH_DENIED 0x0003
#define CSB_UPDATE_RETRY_ATTEMPT 0x0004
#define CSB_UPDATE_FAILED_ATTEMPT 0x0005
#define CSB_UPDATE_MODE_UNAVAILABLE 0x0006
#include <iosfwd>
#include <string>
#include <stdlib.h>
#include <time.h>
#include <inttypes.h>
class PeerConnectStateBox
{
public:
PeerConnectStateBox();
uint32_t connectCb(uint32_t cbtype, uint32_t netmode, uint32_t nathole, uint32_t nattype);
uint32_t updateCb(uint32_t updateType);
bool shouldUseProxyPort(uint32_t netmode, uint32_t nathole, uint32_t nattype);
uint32_t calcNetState(uint32_t netmode, uint32_t nathole, uint32_t nattype);
std::string connectState() const;
std::string mPeerId;
bool storeProxyPortChoice(uint32_t flags, bool useProxyPort);
bool getProxyPortChoice();
private:
uint32_t connectCb_direct();
uint32_t connectCb_unreachable();
void errorMsg(std::ostream &out, std::string msg, uint32_t updateParam);
void stateMsg(std::ostream &out, std::string msg, uint32_t updateParam);
uint32_t mState;
uint32_t mNetState;
time_t mStateTS;
uint32_t mNoAttempts;
uint32_t mNoFailedAttempts;
time_t mNextAttemptTS;
time_t mAttemptLength;
// ProxyPort Storage.
uint32_t mProxyPortFlags;
bool mProxyPortChoice;
time_t mProxyPortTS;
};
#endif

View File

@ -27,7 +27,6 @@
#include "dht/p3bitdht.h"
#include "bitdht/bdstddht.h"
#include "pqi/p3connmgr.h"
#include "tcponudp/udprelay.h"
#include "tcponudp/udpstunner.h"
@ -66,9 +65,9 @@ virtual int dhtValueCallback(const bdNodeId *id, std::string key, uint32_t statu
}
virtual int dhtConnectCallback(const bdId *srcId, const bdId *proxyId, const bdId *destId,
uint32_t mode, uint32_t point, uint32_t cbtype, uint32_t errcode)
uint32_t mode, uint32_t point, uint32_t param, uint32_t cbtype, uint32_t errcode)
{
return 0;
return mParent->ConnectCallback(srcId, proxyId, destId, mode, point, param, cbtype, errcode);
}
private:
@ -77,15 +76,16 @@ virtual int dhtConnectCallback(const bdId *srcId, const bdId *proxyId, const bdI
};
p3BitDht::p3BitDht(std::string id, pqiConnectCb *cb, UdpStack *udpstack, std::string bootstrapfile)
:pqiNetAssistConnect(id, cb), dhtMtx("p3BitDht")
p3BitDht::p3BitDht(std::string id, pqiConnectCb *cb, p3NetMgr *nm,
UdpStack *udpstack, std::string bootstrapfile)
:pqiNetAssistConnect(id, cb), mNetMgr(nm), dhtMtx("p3BitDht")
{
mDhtStunner = NULL;
mProxyStunner = NULL;
mRelay = NULL;
std::string dhtVersion = "RS51"; // should come from elsewhere!
bdNodeId ownId;
mOwnRsId = id;
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::p3BitDht()" << std::endl;
@ -98,13 +98,13 @@ p3BitDht::p3BitDht(std::string id, pqiConnectCb *cb, UdpStack *udpstack, std::st
#endif
/* setup ownId */
storeTranslation(id);
lookupNodeId(id, &ownId);
storeTranslation_locked(id);
lookupNodeId_locked(id, &mOwnDhtId);
#ifdef DEBUG_BITDHT
std::cerr << "Own NodeId: ";
bdStdPrintNodeId(std::cerr, &ownId);
bdStdPrintNodeId(std::cerr, &mOwnDhtId);
std::cerr << std::endl;
#endif
@ -117,13 +117,19 @@ p3BitDht::p3BitDht(std::string id, pqiConnectCb *cb, UdpStack *udpstack, std::st
#endif
/* create dht */
mUdpBitDht = new UdpBitDht(udpstack, &ownId, dhtVersion, bootstrapfile, stdfns);
mUdpBitDht = new UdpBitDht(udpstack, &mOwnDhtId, dhtVersion, bootstrapfile, stdfns);
udpstack->addReceiver(mUdpBitDht);
/* setup callback to here */
p3BdCallback *bdcb = new p3BdCallback(this);
mUdpBitDht->addCallback(bdcb);
/* enable all modes */
mUdpBitDht->ConnectionOptions(
// BITDHT_CONNECT_MODE_DIRECT | BITDHT_CONNECT_MODE_PROXY | BITDHT_CONNECT_MODE_RELAY,
BITDHT_CONNECT_MODE_DIRECT | BITDHT_CONNECT_MODE_PROXY,
BITDHT_CONNECT_OPTION_AUTOPROXY);
}
p3BitDht::~p3BitDht()
@ -200,6 +206,7 @@ bool p3BitDht::getNetworkStats(uint32_t &netsize, uint32_t &localnetsize)
return true;
}
#if 0
/* pqiNetAssistConnect - external interface functions */
/* add / remove peers */
bool p3BitDht::findPeer(std::string pid)
@ -281,6 +288,9 @@ bool p3BitDht::dropPeer(std::string pid)
return true ;
}
#endif
/* extract current peer status */
bool p3BitDht::getPeerStatus(std::string id,
struct sockaddr_in &laddr, struct sockaddr_in &raddr,
@ -309,396 +319,3 @@ bool p3BitDht::getExternalInterface(struct sockaddr_in &raddr,
}
/* Adding a little bit of fixed test...
* This allows us to ensure that only compatible peers will find each other
*/
const uint8_t RS_DHT_VERSION_LEN = 17;
const uint8_t rs_dht_version_data[RS_DHT_VERSION_LEN] = "RS_VERSION_0.5.1";
/******************** Conversion Functions **************************/
int p3BitDht::calculateNodeId(const std::string pid, bdNodeId *id)
{
/* generate node id from pid */
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::calculateNodeId() " << pid;
#endif
/* use a hash to make it impossible to reverse */
uint8_t sha_hash[SHA_DIGEST_LENGTH];
memset(sha_hash,0,SHA_DIGEST_LENGTH*sizeof(uint8_t)) ;
SHA_CTX *sha_ctx = new SHA_CTX;
SHA1_Init(sha_ctx);
SHA1_Update(sha_ctx, rs_dht_version_data, RS_DHT_VERSION_LEN);
SHA1_Update(sha_ctx, pid.c_str(), pid.length());
SHA1_Final(sha_hash, sha_ctx);
for(int i = 0; i < SHA_DIGEST_LENGTH && (i < BITDHT_KEY_LEN); i++)
{
id->data[i] = sha_hash[i];
}
delete sha_ctx;
#ifdef DEBUG_BITDHT
std::cerr << " => ";
bdStdPrintNodeId(std::cerr, id);
std::cerr << std::endl;
#endif
return 1;
}
int p3BitDht::lookupNodeId(const std::string pid, bdNodeId *id)
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::lookupNodeId() for : " << pid;
std::cerr << std::endl;
#endif
RsStackMutex stack(dhtMtx);
std::map<std::string, bdNodeId>::iterator it;
it = mTransToNodeId.find(pid);
if (it == mTransToNodeId.end())
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::lookupNodeId() failed";
std::cerr << std::endl;
#endif
return 0;
}
*id = it->second;
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::lookupNodeId() Found NodeId: ";
bdStdPrintNodeId(std::cerr, id);
std::cerr << std::endl;
#endif
return 1;
}
int p3BitDht::lookupRsId(const bdNodeId *id, std::string &pid)
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::lookupRsId() for : ";
bdStdPrintNodeId(std::cerr, id);
std::cerr << std::endl;
#endif
RsStackMutex stack(dhtMtx);
std::map<bdNodeId, std::string>::iterator nit;
nit = mTransToRsId.find(*id);
if (nit == mTransToRsId.end())
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::lookupRsId() failed";
std::cerr << std::endl;
#endif
return 0;
}
pid = nit->second;
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::lookupRsId() Found Matching RsId: " << pid;
std::cerr << std::endl;
#endif
return 1;
}
int p3BitDht::storeTranslation(const std::string pid)
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::storeTranslation(" << pid << ")";
std::cerr << std::endl;
#endif
bdNodeId nid;
calculateNodeId(pid, &nid);
RsStackMutex stack(dhtMtx);
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::storeTranslation() Converts to NodeId: ";
bdStdPrintNodeId(std::cerr, &(nid));
std::cerr << std::endl;
#endif
mTransToNodeId[pid] = nid;
mTransToRsId[nid] = pid;
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::storeTranslation() Success";
std::cerr << std::endl;
#endif
return 1;
}
int p3BitDht::removeTranslation(const std::string pid)
{
RsStackMutex stack(dhtMtx);
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::removeTranslation(" << pid << ")";
std::cerr << std::endl;
#endif
std::map<std::string, bdNodeId>::iterator it = mTransToNodeId.find(pid);
it = mTransToNodeId.find(pid);
if (it == mTransToNodeId.end())
{
std::cerr << "p3BitDht::removeTranslation() ERROR MISSING TransToNodeId";
std::cerr << std::endl;
/* missing */
return 0;
}
bdNodeId nid = it->second;
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::removeTranslation() Found Translation: NodeId: ";
bdStdPrintNodeId(std::cerr, &(nid));
std::cerr << std::endl;
#endif
std::map<bdNodeId, std::string>::iterator nit;
nit = mTransToRsId.find(nid);
if (nit == mTransToRsId.end())
{
std::cerr << "p3BitDht::removeTranslation() ERROR MISSING TransToRsId";
std::cerr << std::endl;
/* inconsistent!!! */
return 0;
}
mTransToNodeId.erase(it);
mTransToRsId.erase(nit);
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::removeTranslation() SUCCESS";
std::cerr << std::endl;
#endif
return 1;
}
/********************** Callback Functions **************************/
uint32_t translatebdcbflgs(uint32_t peerflags);
int p3BitDht::NodeCallback(const bdId *id, uint32_t peerflags)
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::NodeCallback()";
std::cerr << std::endl;
#endif
// XXX THIS IS A BAD HACK TO PREVENT connection attempt to MEDIASENTRY (dht spies)
// peers... These peers appear to masquerade as your OwnNodeId!!!!
// which means peers could attempt to connect too?? not sure about this?
// Anyway they don't appear to REPLY to FIND_NODE requests...
// So if we ignore these peers, we'll only get the true RS peers!
// This should be fixed by a collaborative IP filter system,
// EACH peer identifies dodgey IP (ones spoofing yourself), and shares them
// This are distributed around RS via a service, and the UDP ignores
// all comms from these sources. (AT a low level).
if (peerflags != BITDHT_PEER_STATUS_RECV_NODES)
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::NodeCallback() Ignoring !FIND_NODE callback from:";
bdStdPrintNodeId(std::cerr, &(id->id));
std::cerr << " flags: " << peerflags;
std::cerr << std::endl;
#endif
return 0;
}
/* is it one that we are interested in? */
std::string pid;
/* check for translation */
if (lookupRsId(&(id->id), pid))
{
#ifdef DEBUG_BITDHT
/* we found it ... do callback to p3connmgr */
std::cerr << "p3BitDht::NodeCallback() FOUND NODE!!!: ";
bdStdPrintNodeId(std::cerr, &(id->id));
std::cerr << "-> " << pid << " flags: " << peerflags;
std::cerr << std::endl;
#endif
/* send status info to p3connmgr */
pqiIpAddress dhtpeer;
dhtpeer.mSrc = RS_CB_DHT;
dhtpeer.mSeenTime = time(NULL);
dhtpeer.mAddr = id->addr;
pqiIpAddrSet addrs;
addrs.updateExtAddrs(dhtpeer);
uint32_t type = RS_NET_CONN_UDP_DHT_SYNC;
uint32_t flags = translatebdcbflgs(peerflags);
uint32_t source = RS_CB_DHT;
mConnCb->peerStatus(pid, addrs, type, flags, source);
return 1;
}
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::NodeCallback() FAILED TO FIND NODE: ";
bdStdPrintNodeId(std::cerr, &(id->id));
std::cerr << std::endl;
#endif
return 0;
}
uint32_t translatebdcbflgs(uint32_t peerflags)
{
uint32_t outflags = 0;
outflags |= RS_NET_FLAGS_ONLINE;
return outflags;
#if 0
// The input flags.
#define BITDHT_PEER_STATUS_RECV_PONG 0x00000001
#define BITDHT_PEER_STATUS_RECV_NODES 0x00000002
#define BITDHT_PEER_STATUS_RECV_HASHES 0x00000004
#define BITDHT_PEER_STATUS_DHT_ENGINE 0x00000100
#define BITDHT_PEER_STATUS_DHT_APPL 0x00000200
#define BITDHT_PEER_STATUS_DHT_VERSION 0x00000400
if (peerflags & ONLINE)
{
outflags |= RS_NET_FLAGS_ONLINE;
}
if (peerflags & ONLINE)
{
outflags |= RS_NET_FLAGS_EXTERNAL_ADDR | RS_NET_FLAGS_STABLE_UDP;
}
#endif
}
int p3BitDht::PeerCallback(const bdId *id, uint32_t status)
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::PeerCallback() bdId: ";
bdStdPrintId(std::cerr, id);
std::cerr << std::endl;
#endif
/* is it one that we are interested in? */
std::string pid;
/* check for translation */
if (lookupRsId(&(id->id), pid))
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::PeerCallback() => RsId: ";
std::cerr << pid << " status: " << status;
std::cerr << " NOOP for NOW";
std::cerr << std::endl;
#endif
bool connect = false;
switch(status)
{
case BITDHT_MGR_QUERY_FAILURE:
/* do nothing */
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::PeerCallback() QUERY FAILURE ... do nothin ";
std::cerr << std::endl;
#endif
break;
case BITDHT_MGR_QUERY_PEER_OFFLINE:
/* do nothing */
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::PeerCallback() QUERY PEER OFFLINE ... do nothin ";
std::cerr << std::endl;
#endif
break;
case BITDHT_MGR_QUERY_PEER_UNREACHABLE:
/* do nothing */
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::PeerCallback() QUERY PEER UNREACHABLE ... flag? / do nothin ";
std::cerr << std::endl;
#endif
break;
case BITDHT_MGR_QUERY_PEER_ONLINE:
/* do something */
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::PeerCallback() QUERY PEER ONLINE ... try udp connection";
std::cerr << std::endl;
#endif
connect = true;
break;
}
if (connect)
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::PeerCallback() mConnCb->peerConnectRequest()";
std::cerr << std::endl;
#endif
mConnCb->peerConnectRequest(pid, id->addr, RS_CB_DHT);
return 1;
}
else
{
return 0;
}
}
else
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::PeerCallback()";
std::cerr << " FAILED TO TRANSLATE ID ";
std::cerr << " status: " << status;
std::cerr << " NOOP for NOW";
std::cerr << std::endl;
#endif
}
return 0;
}
int p3BitDht::ValueCallback(const bdNodeId *id, std::string key, uint32_t status)
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::ValueCallback() NOOP for NOW";
std::cerr << std::endl;
#endif
/* ignore for now */
return 0;
}

View File

@ -40,24 +40,91 @@
#include "udp/udpbitdht.h"
#include "bitdht/bdiface.h"
#include "dht/connectstatebox.h"
class DhtPeerDetails
{
public:
uint32_t mPeerType;
bdId mDhtId;
std::string mRsId;
/* direct from the DHT! */
uint32_t mDhtState; // One of RSDHT_PEERDHT_[...]
time_t mDhtUpdateTS;
/* internal state */
PeerConnectStateBox mConnectLogic;
/* Actual Connection Status */
uint32_t mPeerConnectState; // One of RSDHT_PEERCONN_
std::string mPeerConnectMsg;
uint32_t mPeerConnectMode;
bdId mPeerConnectPeerId;
bdId mPeerConnectProxyId;
struct sockaddr_in mPeerConnectAddr;
uint32_t mPeerConnectPoint;
time_t mPeerConnectUdpTS;
time_t mPeerConnectTS;
time_t mPeerConnectClosedTS;
bool mExclusiveProxyLock;
/* keeping the PeerCbMsg, as we will need it for debugging */
/* don't think this data is ever used for decisions??? */
/* Connection Request Status */
std::string mPeerReqStatusMsg;
uint32_t mPeerReqState;
uint32_t mPeerReqMode;
bdId mPeerReqProxyId;
time_t mPeerReqTS;
/* Callback Info */
std::string mPeerCbMsg;
uint32_t mPeerCbMode;
uint32_t mPeerCbPoint;
bdId mPeerCbProxyId;
bdId mPeerCbDestId;
time_t mPeerCbTS;
};
#define PEERNET_ACTION_TYPE_CONNECT 1
#define PEERNET_ACTION_TYPE_AUTHORISE 2
#define PEERNET_ACTION_TYPE_START 3
#define PEERNET_ACTION_TYPE_RESTARTREQ 4
#define PEERNET_ACTION_TYPE_KILLREQ 5
#define PEERNET_ACTION_TYPE_TCPATTEMPT 6
class PeerAction
{
public:
uint32_t mType;
bdId mSrcId;
bdId mProxyId;
bdId mDestId;
uint32_t mMode;
uint32_t mPoint;
uint32_t mAnswer;
uint32_t mDelayOrBandwidth;
};
class UdpRelayReceiver;
class UdpStunner;
class p3NetMgr;
class p3BitDht: public pqiNetAssistConnect, public RsDht
{
public:
p3BitDht(std::string id, pqiConnectCb *cb,
p3BitDht(std::string id, pqiConnectCb *cb, p3NetMgr *nm,
UdpStack *udpstack, std::string bootstrapfile);
@ -91,6 +158,7 @@ virtual int getRelayProxies(std::list<RsDhtRelayProxy> &relayProxies);
void start(); /* starts up the bitdht thread */
/* pqiNetAssist - external interface functions */
virtual int tick();
virtual void enable(bool on);
virtual void shutdown(); /* blocking call */
virtual void restart();
@ -105,6 +173,9 @@ virtual bool getNetworkStats(uint32_t &netsize, uint32_t &localnetsize);
virtual bool findPeer(std::string id);
virtual bool dropPeer(std::string id);
/* 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,
@ -117,34 +188,104 @@ virtual bool getExternalInterface(struct sockaddr_in &raddr,
* hould all be removed from NetAssist?
*/
/* pqiNetAssistConnect - external interface functions */
/***********************************************************************************************
****************************** Connections (p3bitdht_peernet.cc) ******************************
************************************************************************************************/
/* Feedback from RS Upper Layers */
//virtual void ConnectionFeedback(std::string pid, int state);
/* Callback functions - from bitdht */
int NodeCallback(const bdId *id, uint32_t peerflags);
int PeerCallback(const bdId *id, uint32_t status);
int ValueCallback(const bdNodeId *id, std::string key, uint32_t status);
int ConnectCallback(const bdId *srcId, const bdId *proxyId, const bdId *destId,
uint32_t mode, uint32_t point, uint32_t param, uint32_t cbtype, uint32_t errcode);
int OnlinePeerCallback_locked(const bdId *id, uint32_t status, DhtPeerDetails *dpd);
int UnreachablePeerCallback_locked(const bdId *id, uint32_t status, DhtPeerDetails *dpd);
//int tick();
int minuteTick();
int doActions();
int checkProxyAllowed(const bdId *srcId, const bdId *destId, int mode, uint32_t &bandwidth);
int checkConnectionAllowed(const bdId *peerId, int mode);
void initiateConnection(const bdId *srcId, const bdId *proxyId, const bdId *destId, uint32_t mode, uint32_t loc, uint32_t delayOrBandwidth);
int installRelayConnection(const bdId *srcId, const bdId *destId, uint32_t &bandwidth);
int removeRelayConnection(const bdId *srcId, const bdId *destId);
void monitorConnections();
void ConnectCallout(const std::string &peerId, struct sockaddr_in addr, uint32_t connectMode);
void ConnectCalloutTCPAttempt(const std::string &peerId, struct sockaddr_in addr);
void ConnectCalloutDirectOrProxy(const std::string &peerId, struct sockaddr_in raddr, uint32_t connectFlags, uint32_t delay);
void ConnectCalloutRelay(const std::string &peerId, struct sockaddr_in srcaddr,
struct sockaddr_in proxyaddr, struct sockaddr_in destaddr,
uint32_t connectMode, uint32_t bandwidth);
void Feedback_Connected(std::string pid);
void Feedback_ConnectionFailed(std::string pid);
void Feedback_ConnectionClosed(std::string pid);
void UdpConnectionFailed_locked(DhtPeerDetails *dpd);
void ReleaseProxyExclusiveMode_locked(DhtPeerDetails *dpd, bool addrChgLikely);
/***********************************************************************************************
************************** 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);
private:
/* translation stuff */
int calculateNodeId(const std::string pid, bdNodeId *id);
int lookupNodeId(const std::string pid, bdNodeId *id);
int lookupRsId(const bdNodeId *id, std::string &pid);
int storeTranslation(const std::string pid);
int removeTranslation(const std::string pid);
DhtPeerDetails *addInternalPeer_locked(const std::string pid, int type);
int removeInternalPeer_locked(const std::string pid);
DhtPeerDetails *findInternalDhtPeer_locked(const bdNodeId *id, int type);
DhtPeerDetails *findInternalRsPeer_locked(const std::string &pid);
bool havePeerTranslation_locked(const std::string &pid);
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;
UdpStunner *mProxyStunner;
UdpRelayReceiver *mRelay;
p3NetMgr *mNetMgr;
RsMutex dhtMtx;
std::string mOwnRsId;
bdNodeId mOwnDhtId;
time_t mMinuteTS;
/* translation maps */
std::map<std::string, bdNodeId> mTransToNodeId;
std::map<bdNodeId, std::string> mTransToRsId;
std::map<std::string, DhtPeerDetails> mPeers;
std::map<bdNodeId, DhtPeerDetails> mPeers;
std::map<bdNodeId, DhtPeerDetails> mFailedPeers;
/* Connection Action Queue */
std::list<PeerAction> mActions;
};
#endif /* MRK_P3_BITDHT_H */

View File

@ -69,10 +69,10 @@ int p3BitDht::getDhtPeers(int lvl, std::list<RsDhtPeer> &peers)
int p3BitDht::getNetPeerList(std::list<std::string> &peerIds)
{
RsStackMutex stack(dhtMtx); /*********** LOCKED **********/
std::map<std::string, DhtPeerDetails>::iterator it;
std::map<bdNodeId, DhtPeerDetails>::iterator it;
for(it = mPeers.begin(); it != mPeers.end(); it++)
{
peerIds.push_back(it->first);
peerIds.push_back(it->second.mRsId);
}
return 1;
@ -83,14 +83,13 @@ int p3BitDht::getNetPeerStatus(std::string peerId, RsDhtNetPeer &status)
RsStackMutex stack(dhtMtx); /*********** LOCKED **********/
std::map<std::string, DhtPeerDetails>::iterator it;
it = mPeers.find(peerId);
if (it == mPeers.end())
DhtPeerDetails *dpd = findInternalRsPeer_locked(peerId);
if (!dpd)
{
return 0;
}
convertDhtPeerDetailsToRsDhtNetPeer(status, it->second);
convertDhtPeerDetailsToRsDhtNetPeer(status, *dpd);
return 1;
}
@ -180,23 +179,59 @@ void convertDhtPeerDetailsToRsDhtNetPeer(RsDhtNetPeer &status, const DhtPeerDeta
status.mDhtId = out.str();
status.mRsId = details.mRsId;
status.mDhtState = details.mDhtState;
status.mConnectState = details.mConnectLogic.connectState();
status.mPeerReqState = details.mPeerReqState;
status.mExclusiveProxyLock = details.mExclusiveProxyLock;
status.mPeerConnectState = details.mPeerConnectState;
switch(details.mPeerConnectMode)
{
default:
case BITDHT_CONNECT_MODE_DIRECT:
status.mPeerConnectMode = RSDHT_TOU_MODE_DIRECT;
break;
case BITDHT_CONNECT_MODE_PROXY:
status.mPeerConnectMode = RSDHT_TOU_MODE_PROXY;
break;
case BITDHT_CONNECT_MODE_RELAY:
status.mPeerConnectMode = RSDHT_TOU_MODE_RELAY;
break;
}
//status.mPeerConnectProxyId = details.mPeerConnectProxyId;
std::ostringstream out2;
bdStdPrintId(out2, &(details.mPeerConnectProxyId));
status.mPeerConnectProxyId = out2.str();
status.mCbPeerMsg = details.mPeerCbMsg;
return;
}
void convertUdpRelayEndtoRsDhtRelayEnd(RsDhtRelayEnd &end, const UdpRelayEnd &int_end)
{
std::ostringstream addr;
addr << rs_inet_ntoa(int_end.mLocalAddr.sin_addr) << ":" << ntohs(int_end.mLocalAddr.sin_port);
end.mLocalAddr = addr.str();
{
std::ostringstream addr;
addr << rs_inet_ntoa(int_end.mLocalAddr.sin_addr) << ":" << ntohs(int_end.mLocalAddr.sin_port);
end.mLocalAddr = addr.str();
}
addr.clear();
addr << rs_inet_ntoa(int_end.mProxyAddr.sin_addr) << ":" << ntohs(int_end.mProxyAddr.sin_port);
end.mProxyAddr = addr.str();
{
std::ostringstream addr;
addr << rs_inet_ntoa(int_end.mProxyAddr.sin_addr) << ":" << ntohs(int_end.mProxyAddr.sin_port);
end.mProxyAddr = addr.str();
}
addr.clear();
addr << rs_inet_ntoa(int_end.mRemoteAddr.sin_addr) << ":" << ntohs(int_end.mRemoteAddr.sin_port);
end.mRemoteAddr = addr.str();
{
std::ostringstream addr;
addr << rs_inet_ntoa(int_end.mRemoteAddr.sin_addr) << ":" << ntohs(int_end.mRemoteAddr.sin_port);
end.mRemoteAddr = addr.str();
}
end.mCreateTS = 0;
return;
@ -204,13 +239,17 @@ void convertUdpRelayEndtoRsDhtRelayEnd(RsDhtRelayEnd &end, const UdpRelayEnd &in
void convertUdpRelayProxytoRsDhtRelayProxy(RsDhtRelayProxy &proxy, const UdpRelayProxy &int_proxy)
{
std::ostringstream addr;
addr << rs_inet_ntoa(int_proxy.mAddrs.mSrcAddr.sin_addr) << ":" << ntohs(int_proxy.mAddrs.mSrcAddr.sin_port);
proxy.mSrcAddr = addr.str();
{
std::ostringstream addr;
addr << rs_inet_ntoa(int_proxy.mAddrs.mSrcAddr.sin_addr) << ":" << ntohs(int_proxy.mAddrs.mSrcAddr.sin_port);
proxy.mSrcAddr = addr.str();
}
addr.clear();
addr << rs_inet_ntoa(int_proxy.mAddrs.mDestAddr.sin_addr) << ":" << ntohs(int_proxy.mAddrs.mDestAddr.sin_port);
proxy.mDestAddr = addr.str();
{
std::ostringstream addr;
addr << rs_inet_ntoa(int_proxy.mAddrs.mDestAddr.sin_addr) << ":" << ntohs(int_proxy.mAddrs.mDestAddr.sin_port);
proxy.mDestAddr = addr.str();
}
proxy.mBandwidth = int_proxy.mBandwidth;
proxy.mRelayClass = int_proxy.mRelayClass;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,543 @@
/*
* libretroshare/src/dht: p3bitdht.h
*
* BitDht interface for RetroShare.
*
* Copyright 2009-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 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 "dht/p3bitdht.h"
#include "bitdht/bdstddht.h"
#include "tcponudp/udprelay.h"
#include "tcponudp/udpstunner.h"
#include <openssl/sha.h>
/***
*
* #define DEBUG_BITDHT 1
* #define DEBUG_BITDHT_TRANSLATE 1
*
**/
/******************************************************************************************
********************************* Existing Interface *************************************
******************************************************************************************/
/* pqiNetAssistConnect - external interface functions */
/* add / remove peers */
/*****
* At the moment, findPeer, dropPeer are the only way that peer info enters the dht.
* This will obviously change, and we will have a list of Friends and FoF,
* but for now we need to expect that this function will add unknown pids.
*
*/
#define USE_OLD_DHT_INTERFACE 1
bool p3BitDht::findPeer(std::string pid)
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::findPeer(" << pid << ")";
std::cerr << std::endl;
#endif
DhtPeerDetails *dpd = findInternalRsPeer_locked(pid);
if (!dpd)
{
dpd = addInternalPeer_locked(pid, RSDHT_PEERTYPE_FRIEND);
if (!dpd)
{
/* ERROR */
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::findPeer() ERROR installing InternalPeer";
std::cerr << std::endl;
#endif
return false;
}
/* new entry... what do we need to set? */
dpd->mDhtState = RSDHT_PEERDHT_SEARCHING;
/* NEW INIT FROM peernet */
//bdsockaddr_clear(&(dpd->mDhtAddr));
//dpd->mDhtStatusMsg = "Just Added";
dpd->mDhtState = RSDHT_PEERDHT_SEARCHING;
dpd->mDhtUpdateTS = time(NULL);
dpd->mPeerReqStatusMsg = "Just Added";
dpd->mPeerReqState = RSDHT_PEERREQ_STOPPED;
dpd->mPeerReqMode = 0;
//dpd->mPeerReqProxyId;
dpd->mPeerReqTS = time(NULL);
dpd->mExclusiveProxyLock = false;
dpd->mPeerCbMsg = "No CB Yet";
dpd->mPeerCbMode = 0;
dpd->mPeerCbPoint = 0;
//dpd->mPeerCbProxyId = 0;
//dpd->mPeerCbDestId = 0;
dpd->mPeerCbTS = 0;
dpd->mPeerConnectState = RSDHT_PEERCONN_DISCONNECTED;
dpd->mPeerConnectMsg = "Disconnected";
//dpd->mPeerConnectFd = 0;
dpd->mPeerConnectMode = 0;
//dpd->mPeerConnectProxyId;
dpd->mPeerConnectPoint = 0;
dpd->mPeerConnectUdpTS = 0;
dpd->mPeerConnectTS = 0;
dpd->mPeerConnectClosedTS = 0;
bdsockaddr_clear(&(dpd->mPeerConnectAddr));
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::findPeer() Installed new DhtPeer with pid => NodeId: ";
bdStdPrintNodeId(std::cerr, &(dpd->mDhtId.id));
std::cerr << std::endl;
#endif
}
else
{
/* old entry */
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::findPeer() Reactivating DhtPeer with pid => NodeId: ";
bdStdPrintNodeId(std::cerr, &(dpd->mDhtId.id));
std::cerr << std::endl;
#endif
if (dpd->mDhtState != RSDHT_PEERDHT_NOT_ACTIVE)
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::findPeer() WARNING DhtState is Already Active!";
bdStdPrintNodeId(std::cerr, &(dpd->mDhtId.id));
std::cerr << std::endl;
#endif
}
else
{
/* flag as searching */
dpd->mDhtState = RSDHT_PEERDHT_SEARCHING;
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::findPeer() Marking Old Peer as SEARCHING";
std::cerr << std::endl;
#endif
}
}
bdNodeId nid = dpd->mDhtId.id;
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::findPeer() calling AddFindNode() with pid => NodeId: ";
bdStdPrintNodeId(std::cerr, &nid);
std::cerr << std::endl;
#endif
/* add in peer */
mUdpBitDht->addFindNode(&nid, BITDHT_QFLAGS_DO_IDLE | BITDHT_QFLAGS_UPDATES);
return true ;
}
bool p3BitDht::dropPeer(std::string pid)
{
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::dropPeer(" << pid << ")";
std::cerr << std::endl;
#endif
DhtPeerDetails *dpd = findInternalRsPeer_locked(pid);
if (!dpd)
{
/* ERROR */
return false;
}
/* flag as searching */
dpd->mDhtState = RSDHT_PEERDHT_NOT_ACTIVE;
bdNodeId nid = dpd->mDhtId.id;
#ifdef DEBUG_BITDHT
std::cerr << "p3BitDht::dropPeer() calling removeFindNode() with pid => NodeId: ";
bdStdPrintNodeId(std::cerr, &nid);
std::cerr << std::endl;
#endif
/* remove in peer */
mUdpBitDht->removeFindNode(&nid);
/* not removing from translation */
return true ;
}
/******************************************************************************************
********************************* Basic Peer Details *************************************
******************************************************************************************/
int p3BitDht::addFriend(const std::string pid)
{
RsStackMutex stack(dhtMtx); /********* LOCKED *********/
return (NULL != addInternalPeer_locked(pid, RSDHT_PEERTYPE_FRIEND));
}
int p3BitDht::addFriendOfFriend(const std::string pid)
{
RsStackMutex stack(dhtMtx); /********* LOCKED *********/
return (NULL != addInternalPeer_locked(pid, RSDHT_PEERTYPE_FOF));
}
int p3BitDht::addOther(const std::string pid)
{
RsStackMutex stack(dhtMtx); /********* LOCKED *********/
return (NULL != addInternalPeer_locked(pid, RSDHT_PEERTYPE_OTHER));
}
int p3BitDht::removePeer(const std::string pid)
{
RsStackMutex stack(dhtMtx); /********* LOCKED *********/
return removeInternalPeer_locked(pid);
}
/******************************************************************************************
********************************* Basic Peer Details *************************************
******************************************************************************************/
DhtPeerDetails *p3BitDht::addInternalPeer_locked(const std::string pid, int type)
{
/* create the data structure */
if (!havePeerTranslation_locked(pid))
{
storeTranslation_locked(pid);
}
bdNodeId id;
if (!lookupNodeId_locked(pid, &id))
{
return 0;
}
DhtPeerDetails *dpd = findInternalDhtPeer_locked(&id, RSDHT_PEERTYPE_ANY);
if (!dpd)
{
DhtPeerDetails newdpd;
mPeers[id] = newdpd;
dpd = findInternalDhtPeer_locked(&id, RSDHT_PEERTYPE_ANY);
}
/* what do we need to reset? */
dpd->mPeerType = type;
dpd->mDhtId.id = id;
dpd->mRsId = pid;
return dpd;
}
int p3BitDht::removeInternalPeer_locked(const std::string pid)
{
bdNodeId id;
if (!lookupNodeId_locked(pid, &id))
{
return 0;
}
std::map<bdNodeId, DhtPeerDetails>::iterator it = mPeers.find(id);
if (it == mPeers.end())
{
return 0;
}
mPeers.erase(it);
// remove the translation?
removeTranslation_locked(pid);
return 1;
}
/* indexed by bdNodeId, as this is the more used call interface */
DhtPeerDetails *p3BitDht::findInternalDhtPeer_locked(const bdNodeId *id, int type)
{
std::map<bdNodeId, DhtPeerDetails>::iterator it = mPeers.find(*id);
if (it == mPeers.end())
{
return NULL;
}
if (type)
{
if (it->second.mPeerType != type)
{
return NULL;
}
}
return &(it->second);
}
/* interface to get with alt id */
DhtPeerDetails *p3BitDht::findInternalRsPeer_locked(const std::string &pid)
{
/* create the data structure */
if (!havePeerTranslation_locked(pid))
{
return NULL;
}
bdNodeId id;
if (!lookupNodeId_locked(pid, &id))
{
return NULL;
}
DhtPeerDetails *dpd = findInternalDhtPeer_locked(&id,RSDHT_PEERTYPE_ANY);
return dpd;
}
/******************************************************************************************
*************************** Fundamental Node Translation *********************************
******************************************************************************************/
bool p3BitDht::havePeerTranslation_locked(const std::string &pid)
{
#ifdef DEBUG_BITDHT_TRANSLATE
std::cerr << "p3BitDht::havePeerTranslation_locked() for : " << pid;
std::cerr << std::endl;
#endif
std::map<std::string, bdNodeId>::iterator it;
it = mTransToNodeId.find(pid);
if (it == mTransToNodeId.end())
{
#ifdef DEBUG_BITDHT_TRANSLATE
std::cerr << "p3BitDht::havePeerTranslation_locked() failed Missing translation";
std::cerr << std::endl;
#endif
return false;
}
#ifdef DEBUG_BITDHT_TRANSLATE
std::cerr << "p3BitDht::havePeerTranslation_locked() Found NodeId: ";
bdStdPrintNodeId(std::cerr, &(it->second));
std::cerr << std::endl;
#endif
return true;
}
int p3BitDht::lookupNodeId_locked(const std::string pid, bdNodeId *id)
{
#ifdef DEBUG_BITDHT_TRANSLATE
std::cerr << "p3BitDht::lookupNodeId_locked() for : " << pid;
std::cerr << std::endl;
#endif
std::map<std::string, bdNodeId>::iterator it;
it = mTransToNodeId.find(pid);
if (it == mTransToNodeId.end())
{
#ifdef DEBUG_BITDHT_TRANSLATE
std::cerr << "p3BitDht::lookupNodeId_locked() failed";
std::cerr << std::endl;
#endif
return 0;
}
*id = it->second;
#ifdef DEBUG_BITDHT_TRANSLATE
std::cerr << "p3BitDht::lookupNodeId_locked() Found NodeId: ";
bdStdPrintNodeId(std::cerr, id);
std::cerr << std::endl;
#endif
return 1;
}
int p3BitDht::lookupRsId_locked(const bdNodeId *id, std::string &pid)
{
#ifdef DEBUG_BITDHT_TRANSLATE
std::cerr << "p3BitDht::lookupRsId_locked() for : ";
bdStdPrintNodeId(std::cerr, id);
std::cerr << std::endl;
#endif
std::map<bdNodeId, std::string>::iterator nit;
nit = mTransToRsId.find(*id);
if (nit == mTransToRsId.end())
{
#ifdef DEBUG_BITDHT_TRANSLATE
std::cerr << "p3BitDht::lookupRsId_locked() failed";
std::cerr << std::endl;
#endif
return 0;
}
pid = nit->second;
#ifdef DEBUG_BITDHT_TRANSLATE
std::cerr << "p3BitDht::lookupRsId_locked() Found Matching RsId: " << pid;
std::cerr << std::endl;
#endif
return 1;
}
int p3BitDht::storeTranslation_locked(const std::string pid)
{
std::cerr << "p3BitDht::storeTranslation_locked(" << pid << ")";
std::cerr << std::endl;
#ifdef DEBUG_BITDHT_TRANSLATE
#endif
bdNodeId nid;
calculateNodeId(pid, &nid);
std::cerr << "p3BitDht::storeTranslation_locked() Converts to NodeId: ";
bdStdPrintNodeId(std::cerr, &(nid));
std::cerr << std::endl;
#ifdef DEBUG_BITDHT_TRANSLATE
#endif
mTransToNodeId[pid] = nid;
mTransToRsId[nid] = pid;
std::cerr << "p3BitDht::storeTranslation_locked() Success";
std::cerr << std::endl;
#ifdef DEBUG_BITDHT_TRANSLATE
#endif
return 1;
}
int p3BitDht::removeTranslation_locked(const std::string pid)
{
#ifdef DEBUG_BITDHT_TRANSLATE
std::cerr << "p3BitDht::removeTranslation_locked(" << pid << ")";
std::cerr << std::endl;
#endif
std::map<std::string, bdNodeId>::iterator it = mTransToNodeId.find(pid);
it = mTransToNodeId.find(pid);
if (it == mTransToNodeId.end())
{
std::cerr << "p3BitDht::removeTranslation_locked() ERROR MISSING TransToNodeId";
std::cerr << std::endl;
/* missing */
return 0;
}
bdNodeId nid = it->second;
#ifdef DEBUG_BITDHT_TRANSLATE
std::cerr << "p3BitDht::removeTranslation_locked() Found Translation: NodeId: ";
bdStdPrintNodeId(std::cerr, &(nid));
std::cerr << std::endl;
#endif
std::map<bdNodeId, std::string>::iterator nit;
nit = mTransToRsId.find(nid);
if (nit == mTransToRsId.end())
{
std::cerr << "p3BitDht::removeTranslation_locked() ERROR MISSING TransToRsId";
std::cerr << std::endl;
/* inconsistent!!! */
return 0;
}
mTransToNodeId.erase(it);
mTransToRsId.erase(nit);
#ifdef DEBUG_BITDHT_TRANSLATE
std::cerr << "p3BitDht::removeTranslation_locked() SUCCESS";
std::cerr << std::endl;
#endif
return 1;
}
/* Adding a little bit of fixed text...
* This allows us to ensure that only compatible peers will find each other
*/
const uint8_t RS_DHT_VERSION_LEN = 17;
const uint8_t rs_dht_version_data[RS_DHT_VERSION_LEN] = "RS_VERSION_0.5.1";
/******************** Conversion Functions **************************/
int p3BitDht::calculateNodeId(const std::string pid, bdNodeId *id)
{
/* generate node id from pid */
#ifdef DEBUG_BITDHT_TRANSLATE
std::cerr << "p3BitDht::calculateNodeId() " << pid;
#endif
/* use a hash to make it impossible to reverse */
uint8_t sha_hash[SHA_DIGEST_LENGTH];
memset(sha_hash,0,SHA_DIGEST_LENGTH*sizeof(uint8_t)) ;
SHA_CTX *sha_ctx = new SHA_CTX;
SHA1_Init(sha_ctx);
SHA1_Update(sha_ctx, rs_dht_version_data, RS_DHT_VERSION_LEN);
SHA1_Update(sha_ctx, pid.c_str(), pid.length());
SHA1_Final(sha_hash, sha_ctx);
for(int i = 0; i < SHA_DIGEST_LENGTH && (i < BITDHT_KEY_LEN); i++)
{
id->data[i] = sha_hash[i];
}
delete sha_ctx;
#ifdef DEBUG_BITDHT_TRANSLATE
std::cerr << " => ";
bdStdPrintNodeId(std::cerr, id);
std::cerr << std::endl;
#endif
return 1;
}

View File

@ -0,0 +1,63 @@
/*
* libretroshare/src/dht: stunaddrassist.h
*
* BitDht 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 STUN_ADDR_ASSIST_H
#define STUN_ADDR_ASSIST_H
#include "pqi/pqiassist.h"
#include "tcponudp/udpstunner.h"
class stunAddrAssist: public pqiAddrAssist
{
public:
stunAddrAssist(UdpStunner *stunner)
{
mStunner = stunner;
}
virtual bool getExternalAddr(struct sockaddr_in &remote, uint8_t &stable)
{
return mStunner->externalAddr(remote, stable);
}
virtual int tick()
{
return mStunner->tick();
}
virtual void setRefreshPeriod(int32_t period)
{
return mStunner->setTargetStunPeriod(period);
}
private:
UdpStunner *mStunner;
};
#endif

View File

@ -52,7 +52,7 @@
#include "util/rsdir.h"
#include "pqi/p3connmgr.h"
#include "pqi/p3linkmgr.h"
#include "pqi/pqinotify.h"
#include "retroshare/rsiface.h"
@ -1150,7 +1150,7 @@ bool ftController::FileRequest(const std::string& fname, const std::string& has
std::cerr << std::endl;
#endif
(dit->second)->mTransfer->addFileSource(*it);
setPeerState(dit->second->mTransfer, *it, rate, mConnMgr->isOnline(*it));
setPeerState(dit->second->mTransfer, *it, rate, mLinkMgr->isOnline(*it));
IndicateConfigChanged(); /* new peer for transfer -> save */
}
@ -1245,7 +1245,7 @@ bool ftController::FileRequest(const std::string& fname, const std::string& has
std::cerr << "ftController::FileRequest() adding peer: " << *it;
std::cerr << std::endl;
#endif
setPeerState(tm, *it, rate, mConnMgr->isOnline(*it));
setPeerState(tm, *it, rate, mLinkMgr->isOnline(*it));
}
/* add structures into the accessible data. Needs to be locked */
@ -1273,7 +1273,7 @@ bool ftController::FileRequest(const std::string& fname, const std::string& has
bool ftController::setPeerState(ftTransferModule *tm, std::string id, uint32_t maxrate, bool online)
{
if (id == mConnMgr->getOwnId())
if (id == mLinkMgr->getOwnId())
{
#ifdef CONTROL_DEBUG
std::cerr << "ftController::setPeerState() is Self";

View File

@ -30,9 +30,9 @@
//#define DB_DEBUG 1
ftFiStore::ftFiStore(CacheStrapper *cs, CacheTransfer *cft, NotifyBase *cb_in,p3ConnectMgr *cnmgr,
ftFiStore::ftFiStore(CacheStrapper *cs, CacheTransfer *cft, NotifyBase *cb_in,p3PeerMgr *pm,
RsPeerId ownid, std::string cachedir)
:FileIndexStore(cs, cft, cb_in,cnmgr, ownid, cachedir)
:FileIndexStore(cs, cft, cb_in, pm, ownid, cachedir)
{
return;
}
@ -366,8 +366,8 @@ void ftFiMonitor::setSharedDirectories(const std::list<SharedDirInfo>& dirList)
ftCacheStrapper::ftCacheStrapper(p3ConnectMgr *cm)
:CacheStrapper(cm)
ftCacheStrapper::ftCacheStrapper(p3LinkMgr *lm)
:CacheStrapper(lm)
{
return;
}

View File

@ -33,7 +33,9 @@
* So they work in the ft world.
*/
class p3ConnectMgr ;
class p3LinkMgr ;
class p3PeerMgr ;
#include "ft/ftsearch.h"
#include "pqi/p3cfgmgr.h"
@ -46,8 +48,7 @@ class p3ConnectMgr ;
class ftFiStore: public FileIndexStore, public ftSearch
{
public:
ftFiStore(CacheStrapper *cs, CacheTransfer *cft, NotifyBase *cb_in,
p3ConnectMgr *,
ftFiStore(CacheStrapper *cs, CacheTransfer *cft, NotifyBase *cb_in, p3PeerMgr *pm,
RsPeerId ownid, std::string cachedir);
/* overloaded search function */
@ -89,7 +90,7 @@ virtual bool loadList(std::list<RsItem *>& load);
class ftCacheStrapper: public CacheStrapper, public ftSearch
{
public:
ftCacheStrapper(p3ConnectMgr *cm);
ftCacheStrapper(p3LinkMgr *cm);
/* overloaded search function */
virtual bool search(const std::string &hash, uint32_t hintflags, FileInfo &info) const;

View File

@ -44,7 +44,7 @@ const int ftserverzone = 29539;
#include "ft/ftdbase.h"
#include "pqi/pqi.h"
#include "pqi/p3connmgr.h"
#include "pqi/p3linkmgr.h"
#include "serialiser/rsserviceids.h"
@ -57,15 +57,15 @@ const int ftserverzone = 29539;
***/
/* Setup */
ftServer::ftServer(p3ConnectMgr *connMgr)
ftServer::ftServer(p3PeerMgr *pm, p3LinkMgr *lm)
: mP3iface(NULL),
mConnMgr(connMgr),
mLinkMgr(lm), mPeerMgr(pm),
mCacheStrapper(NULL),
mFiStore(NULL), mFiMon(NULL),
mFtController(NULL), mFtExtra(NULL),
mFtDataplex(NULL), mFtSearch(NULL), srvMutex("ftServer")
{
mCacheStrapper = new ftCacheStrapper(connMgr);
mCacheStrapper = new ftCacheStrapper(lm);
}
void ftServer::setConfigDirectory(std::string path)
@ -101,8 +101,8 @@ void ftServer::addConfigComponents(p3ConfigMgr *mgr)
std::string ftServer::OwnId()
{
std::string ownId;
if (mConnMgr)
ownId = mConnMgr->getOwnId();
if (mLinkMgr)
ownId = mLinkMgr->getOwnId();
return ownId;
}
@ -113,7 +113,7 @@ void ftServer::SetupFtServer(NotifyBase *cb)
/* setup FiStore/Monitor */
std::string localcachedir = mConfigPath + "/cache/local";
std::string remotecachedir = mConfigPath + "/cache/remote";
std::string ownId = mConnMgr->getOwnId();
std::string ownId = mLinkMgr->getOwnId();
/* search/extras List */
mFtExtra = new ftExtraList();
@ -131,7 +131,7 @@ void ftServer::SetupFtServer(NotifyBase *cb)
/* Make Cache Source/Store */
mFiStore = new ftFiStore(mCacheStrapper, mFtController, cb,mConnMgr, ownId, remotecachedir);
mFiStore = new ftFiStore(mCacheStrapper, mFtController, cb, mPeerMgr, ownId, remotecachedir);
mFiMon = new ftFiMonitor(mCacheStrapper,cb, localcachedir, ownId,mConfigPath);
/* now add the set to the cachestrapper */
@ -144,8 +144,8 @@ void ftServer::SetupFtServer(NotifyBase *cb)
mFtSearch->addSearchMode(mFiMon, RS_FILE_HINTS_LOCAL);
mFtSearch->addSearchMode(mFiStore, RS_FILE_HINTS_REMOTE);
mConnMgr->addMonitor(mFtController);
mConnMgr->addMonitor(mCacheStrapper);
mLinkMgr->addMonitor(mFtController);
mLinkMgr->addMonitor(mCacheStrapper);
return;
}
@ -1052,9 +1052,6 @@ bool ftServer::handleCacheData()
/* these go to the CacheStrapper! */
CacheData data;
data.pid = ci->PeerId();
peerConnectState pca;
mConnMgr->getFriendNetStatus(ci->PeerId(), pca);
data.pname = pca.name;
data.cid = CacheId(ci->cacheType, ci->cacheSubId);
data.path = ci->file.path;
data.name = ci->file.name;

View File

@ -69,6 +69,9 @@ class p3turtle;
class ftDwlQueue;
class p3PeerMgr;
class p3LinkMgr;
class ftServer: public RsFiles, public ftDataSend, public RsThread
{
@ -78,7 +81,7 @@ class ftServer: public RsFiles, public ftDataSend, public RsThread
/******************** Setup ************************************/
/***************************************************************/
ftServer(p3ConnectMgr *connMgr);
ftServer(p3PeerMgr *peerMgr, p3LinkMgr *linkMgr);
/* Assign important variables */
void setConfigDirectory(std::string path);
@ -264,9 +267,11 @@ bool loadConfigMap(std::map<std::string, std::string> &configMap);
* as each component is protected independently.
*/
P3Interface *mP3iface; /* XXX THIS NEEDS PROTECTION */
p3ConnectMgr *mConnMgr;
P3Interface *mP3iface; /* XXX THIS NEEDS PROTECTION */
p3PeerMgr *mPeerMgr;
p3LinkMgr *mLinkMgr;
ftCacheStrapper *mCacheStrapper;
ftFiStore *mFiStore;
ftFiMonitor *mFiMon;

View File

@ -64,9 +64,15 @@ debug {
bitdht {
HEADERS += dht/p3bitdht.h
HEADERS += dht/p3bitdht.h \
dht/connectstatebox.h \
dht/stunaddrassist.h
SOURCES += dht/p3bitdht.cc \
dht/p3bitdht_interface.cc
dht/p3bitdht_interface.cc \
dht/p3bitdht_peers.cc \
dht/p3bitdht_peernet.cc \
dht/connectstatebox.cc
HEADERS += tcponudp/udppeer.h \
tcponudp/bio_tou.h \
@ -140,7 +146,8 @@ PUBLIC_HEADERS = retroshare/rsblogs.h \
retroshare/rsstatus.h \
retroshare/rsturtle.h \
retroshare/rstypes.h \
retroshare/rsdht.h
retroshare/rsdht.h \
retroshare/rsconfig.h
HEADERS += plugins/pluginmanager.h \
plugins/dlfcn_win32.h \
@ -331,7 +338,9 @@ HEADERS += pqi/authssl.h \
pqi/authgpg.h \
pqi/cleanupxpgp.h \
pqi/p3cfgmgr.h \
pqi/p3connmgr.h \
pqi/p3peermgr.h \
pqi/p3linkmgr.h \
pqi/p3netmgr.h \
pqi/p3dhtmgr.h \
pqi/p3notify.h \
pqi/p3upnpmgr.h \
@ -360,14 +369,16 @@ HEADERS += pqi/authssl.h \
pqi/pqissludp.h \
pqi/pqistore.h \
pqi/pqistreamer.h \
pqi/sslfns.h
pqi/sslfns.h \
pqi/pqinetstatebox.h
HEADERS += rsserver/p3discovery.h \
rsserver/p3face.h \
rsserver/p3msgs.h \
rsserver/p3peers.h \
rsserver/p3photo.h \
rsserver/p3status.h
rsserver/p3status.h \
rsserver/p3serverconfig.h
HEADERS += serialiser/rsbaseitems.h \
serialiser/rsbaseserial.h \
@ -452,7 +463,9 @@ SOURCES += pqi/authgpg.cc \
pqi/authssl.cc \
pqi/cleanupxpgp.cc \
pqi/p3cfgmgr.cc \
pqi/p3connmgr.cc \
pqi/p3peermgr.cc \
pqi/p3linkmgr.cc \
pqi/p3netmgr.cc \
pqi/p3dhtmgr.cc \
pqi/p3notify.cc \
pqi/pqiarchive.cc \
@ -473,7 +486,8 @@ SOURCES += pqi/authgpg.cc \
pqi/pqissludp.cc \
pqi/pqistore.cc \
pqi/pqistreamer.cc \
pqi/sslfns.cc
pqi/sslfns.cc \
pqi/pqinetstatebox.cc
SOURCES += rsserver/p3discovery.cc \
rsserver/p3face-config.cc \
@ -486,7 +500,8 @@ SOURCES += rsserver/p3discovery.cc \
rsserver/rsiface.cc \
rsserver/rsinit.cc \
rsserver/rsloginhandler.cc \
rsserver/rstypes.cc
rsserver/rstypes.cc \
rsserver/p3serverconfig.cc
SOURCES += plugins/pluginmanager.cc \
plugins/dlfcn_win32.cc \

View File

@ -28,7 +28,7 @@ std::string RsPluginManager::_remote_cache_dir ;
std::vector<std::string> RsPluginManager::_plugin_directories ;
ftServer *RsPluginManager::_ftserver = NULL ;
p3ConnectMgr *RsPluginManager::_connectmgr = NULL ;
p3LinkMgr *RsPluginManager::_linkmgr = NULL ;
typedef RsPlugin *(*RetroSharePluginEntry)(void) ;
RsPluginHandler *rsPlugins ;
@ -215,10 +215,10 @@ bool RsPluginManager::loadPlugin(const std::string& plugin_name)
}
}
p3ConnectMgr *RsPluginManager::getConnectMgr() const
p3LinkMgr *RsPluginManager::getLinkMgr() const
{
assert(_connectmgr != NULL) ;
return _connectmgr ;
assert(_linkmgr != NULL) ;
return _linkmgr ;
}
ftServer *RsPluginManager::getFileServer() const
{

View File

@ -8,7 +8,7 @@
class p3ConfigMgr ;
class p3ServiceServer ;
class p3ConnectMgr ;
class p3LinkMgr ;
struct PluginInfo
{
@ -38,7 +38,7 @@ class RsPluginManager: public RsPluginHandler, public p3Config
virtual const std::string& getLocalCacheDir() const ;
virtual const std::string& getRemoteCacheDir() const ;
virtual ftServer *getFileServer() const ;
virtual p3ConnectMgr *getConnectMgr() const ;
virtual p3LinkMgr *getLinkMgr() const ;
// ---------------- Derived from p3Config -------------------//
//
@ -55,7 +55,7 @@ class RsPluginManager: public RsPluginHandler, public p3Config
static bool acceptablePluginName(const std::string& s) ;
static void setCacheDirectories(const std::string& local,const std::string& remote) ;
static void setFileServer(ftServer *ft) { _ftserver = ft ; }
static void setConnectMgr(p3ConnectMgr *cm) { _connectmgr = cm ; }
static void setLinkMgr(p3LinkMgr *cm) { _linkmgr = cm ; }
void loadPlugins(const std::vector<std::string>& plugin_directories) ;
@ -72,7 +72,7 @@ class RsPluginManager: public RsPluginHandler, public p3Config
static std::string _remote_cache_dir ;
static std::string _local_cache_dir ;
static ftServer *_ftserver ;
static p3ConnectMgr *_connectmgr ;
static p3LinkMgr *_linkmgr ;
static std::vector<std::string> _plugin_directories ;
};

View File

@ -34,7 +34,6 @@
#include "pqinetwork.h"
#include "authgpg.h"
#include "pqi/p3connmgr.h"
#include "serialiser/rsconfigitems.h"
#include "util/rsdir.h"
@ -54,7 +53,7 @@
* #define AUTHSSL_DEBUG 1
***/
// initialisation du pointeur de singleton <20> z<>ro
// initialisation du pointeur de singleton
static AuthSSL *instance_ssl = NULL;
/* hidden function - for testing purposes() */
@ -824,8 +823,15 @@ static int verify_x509_callback(int preverify_ok, X509_STORE_CTX *ctx)
std::cerr << "static verify_x509_callback called.";
std::cerr << std::endl;
#endif
return AuthSSL::getAuthSSL()->VerifyX509Callback(preverify_ok, ctx);
int verify = AuthSSL::getAuthSSL()->VerifyX509Callback(preverify_ok, ctx);
if (!verify)
{
/* Process as FAILED Certificate */
/* Start as INCOMING, as outgoing is already captured */
AuthSSL::getAuthSSL()->FailedCertificate(X509_STORE_CTX_get_current_cert(ctx), true);
}
return verify;
}
int AuthSSLimpl::VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx)
@ -1136,14 +1142,67 @@ bool AuthSSLimpl::decrypt(void *&out, int &outlen, const void *in, int inlen)
/* store for discovery */
bool AuthSSLimpl::FailedCertificate(X509 *x509, bool incoming)
{
(void) incoming; /* remove unused parameter warning */
std::string peerId = "UnknownSSLID";
if(!getX509id(x509, peerId))
{
std::cerr << "AuthSSLimpl::FailedCertificate() ERROR cannot extract X509id from certificate";
std::cerr << std::endl;
}
std::string gpgid = getX509CNString(x509->cert_info->issuer);
std::string sslcn = getX509CNString(x509->cert_info->subject);
std::cerr << "AuthSSLimpl::FailedCertificate() ";
if (incoming)
{
std::cerr << " Incoming from: ";
}
else
{
std::cerr << " Outgoing to: ";
}
std::cerr << "GpgId: " << gpgid << " SSLcn: " << sslcn << " peerId: " << peerId;
std::cerr << std::endl;
uint32_t notifyType = 0;
/* if auths -> store */
if (AuthX509WithGPG(x509))
{
std::cerr << "AuthSSLimpl::FailedCertificate() Cert Checked Out, so passing to Notify";
std::cerr << std::endl;
if (incoming)
{
notifyType = RS_FEED_ITEM_SEC_CONNECT_ATTEMPT;
}
else
{
notifyType = RS_FEED_ITEM_SEC_AUTH_DENIED;
}
getPqiNotify()->AddFeedItem(notifyType, gpgid, peerId, sslcn);
LocalStoreCert(x509);
return true;
}
else
{
/* unknown peer! */
if (incoming)
{
notifyType = RS_FEED_ITEM_SEC_UNKNOWN_IN;
}
else
{
notifyType = RS_FEED_ITEM_SEC_UNKNOWN_OUT;
}
getPqiNotify()->AddFeedItem(notifyType, gpgid, peerId, sslcn);
}
return false;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,454 +0,0 @@
/*
* libretroshare/src/pqi: p3connmgr.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2007-2008 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_PQI_CONNECTION_MANAGER_HEADER
#define MRK_PQI_CONNECTION_MANAGER_HEADER
#include "pqi/pqimonitor.h"
#include "pqi/pqiipset.h"
//#include "pqi/p3dhtmgr.h"
//#include "pqi/p3upnpmgr.h"
#include "pqi/pqiassist.h"
#include "pqi/p3cfgmgr.h"
#include "util/rsthreads.h"
class ExtAddrFinder ;
class DNSResolver ;
/* RS_VIS_STATE_XXXX
* determines how public this peer wants to be...
*
* STD = advertise to Peers / DHT checking etc
* GRAY = share with friends / but not DHT
* DARK = hidden from all
* BROWN? = hidden from friends / but on DHT
*/
const uint32_t RS_VIS_STATE_NODISC = 0x0001;
const uint32_t RS_VIS_STATE_NODHT = 0x0002;
const uint32_t RS_VIS_STATE_STD = 0x0000;
const uint32_t RS_VIS_STATE_GRAY = RS_VIS_STATE_NODHT;
const uint32_t RS_VIS_STATE_DARK = RS_VIS_STATE_NODISC | RS_VIS_STATE_NODHT;
const uint32_t RS_VIS_STATE_BROWN = RS_VIS_STATE_NODISC;
/* Startup Modes (confirmed later) */
const uint32_t RS_NET_MODE_TRYMODE = 0x00f0;
const uint32_t RS_NET_MODE_TRY_EXT = 0x0010;
const uint32_t RS_NET_MODE_TRY_UPNP = 0x0020;
const uint32_t RS_NET_MODE_TRY_UDP = 0x0040;
/* Actual State */
const uint32_t RS_NET_MODE_ACTUAL = 0x000f;
const uint32_t RS_NET_MODE_UNKNOWN = 0x0000;
const uint32_t RS_NET_MODE_EXT = 0x0001;
const uint32_t RS_NET_MODE_UPNP = 0x0002;
const uint32_t RS_NET_MODE_UDP = 0x0004;
const uint32_t RS_NET_MODE_UNREACHABLE = 0x0008;
/* order of attempts ... */
const uint32_t RS_NET_CONN_TCP_ALL = 0x000f;
const uint32_t RS_NET_CONN_UDP_ALL = 0x00f0;
const uint32_t RS_NET_CONN_TUNNEL = 0x0f00;
const uint32_t RS_NET_CONN_TCP_LOCAL = 0x0001;
const uint32_t RS_NET_CONN_TCP_EXTERNAL = 0x0002;
const uint32_t RS_NET_CONN_TCP_UNKNOW_TOPOLOGY = 0x0004;
const uint32_t RS_NET_CONN_UDP_DHT_SYNC = 0x0010;
const uint32_t RS_NET_CONN_UDP_PEER_SYNC = 0x0020; /* coming soon */
/* extra flags */
// not sure if needed yet.
//const uint32_t RS_NET_CONN_PEERAGE = 0x0f00;
//const uint32_t RS_NET_CONN_SERVER = 0x0100; /* TCP only */
//const uint32_t RS_NET_CONN_PEER = 0x0200; /* all UDP */
/* flags of peerStatus */
const uint32_t RS_NET_FLAGS_USE_DISC = 0x0001;
const uint32_t RS_NET_FLAGS_USE_DHT = 0x0002;
const uint32_t RS_NET_FLAGS_ONLINE = 0x0004;
const uint32_t RS_NET_FLAGS_EXTERNAL_ADDR = 0x0008;
const uint32_t RS_NET_FLAGS_STABLE_UDP = 0x0010;
const uint32_t RS_NET_FLAGS_TRUSTS_ME = 0x0020;
const uint32_t RS_TCP_STD_TIMEOUT_PERIOD = 5; /* 5 seconds! */
class peerAddrInfo
{
public:
peerAddrInfo(); /* init */
bool found;
uint32_t type;
pqiIpAddrSet addrs;
time_t ts;
};
class peerConnectAddress
{
public:
peerConnectAddress(); /* init */
struct sockaddr_in addr;
uint32_t delay; /* to stop simultaneous connects */
uint32_t period; /* UDP only */
uint32_t type;
time_t ts;
};
class peerConnectState
{
public:
peerConnectState(); /* init */
std::string id;
std::string gpg_id;
uint32_t netMode; /* EXT / UPNP / UDP / INVALID */
uint32_t visState; /* STD, GRAY, DARK */
struct sockaddr_in localaddr, serveraddr;
//used to store current ip (for config and connection management)
struct sockaddr_in currentlocaladdr; /* Mandatory */
struct sockaddr_in currentserveraddr; /* Mandatory */
std::string dyndns;
time_t lastcontact;
/* list of addresses from various sources */
pqiIpAddrSet ipAddrs;
/***** Below here not stored permanently *****/
uint32_t connecttype; // RS_NET_CONN_TCP_ALL / RS_NET_CONN_UDP_ALL
time_t lastavailable;
time_t lastattempt;
std::string name;
std::string location;
uint32_t state;
uint32_t actions;
uint32_t source; /* most current source */
peerAddrInfo dht;
peerAddrInfo disc;
peerAddrInfo peer;
/* a list of connect attempts to make (in order) */
bool inConnAttempt;
peerConnectAddress currentConnAddrAttempt;
std::list<peerConnectAddress> connAddrs;
};
class pqiNetStatus
{
public:
pqiNetStatus();
bool mLocalAddrOk; // Local address is not loopback.
bool mExtAddrOk; // have external address.
bool mExtAddrStableOk; // stable external address.
bool mUpnpOk; // upnp is ok.
bool mDhtOk; // dht is ok.
uint32_t mDhtNetworkSize;
uint32_t mDhtRsNetworkSize;
struct sockaddr_in mLocalAddr; // percieved ext addr.
struct sockaddr_in mExtAddr; // percieved ext addr.
bool mResetReq; // Not Used yet!.
void print(std::ostream &out);
bool NetOk() // minimum to believe network is okay.`
{
return (mLocalAddrOk && mExtAddrOk);
}
};
class p3tunnel;
class RsPeerGroupItem;
class RsGroupInfo;
std::string textPeerConnectState(peerConnectState &state);
class p3ConnectMgr: public pqiConnectCb, public p3Config
{
public:
p3ConnectMgr();
void tick();
/*************** Setup ***************************/
void addNetAssistConnect(uint32_t type, pqiNetAssistConnect *);
void addNetAssistFirewall(uint32_t type, pqiNetAssistFirewall *);
void addNetListener(pqiNetListener *listener);
bool checkNetAddress(); /* check our address is sensible */
/*************** External Control ****************/
bool shutdown(); /* blocking shutdown call */
bool retryConnect(const std::string &id);
bool getUPnPState();
bool getUPnPEnabled();
bool getDHTEnabled();
bool getDHTStats(uint32_t &netsize, uint32_t &localnetsize);
bool getIPServersEnabled();
void setIPServersEnabled(bool b) ;
void getIPServersList(std::list<std::string>& ip_servers) ;
void setTunnelConnection(bool b);
bool getTunnelConnection();
bool getNetStatusLocalOk();
bool getNetStatusUpnpOk();
bool getNetStatusDhtOk();
bool getNetStatusStunOk();
bool getNetStatusExtraAddressCheckOk();
bool getUpnpExtAddress(struct sockaddr_in &addr);
bool getExtFinderAddress(struct sockaddr_in &addr);
void getNetStatus(pqiNetStatus &status);
void setOwnNetConfig(uint32_t netMode, uint32_t visState);
bool setLocalAddress(const std::string &id, struct sockaddr_in addr);
bool setExtAddress(const std::string &id, struct sockaddr_in addr);
bool setDynDNS(const std::string &id, const std::string &dyndns);
bool updateAddressList(const std::string& id, const pqiIpAddrSet &addrs);
bool setNetworkMode(const std::string &id, uint32_t netMode);
bool setVisState(const std::string &id, uint32_t visState);
bool setLocation(const std::string &pid, const std::string &location);//location is shown in the gui to differentiate ssl certs
/* add/remove friends */
bool addFriend(const std::string &ssl_id, const std::string &gpg_id, uint32_t netMode = RS_NET_MODE_UDP,
uint32_t visState = RS_VIS_STATE_STD , time_t lastContact = 0);
bool removeFriend(const std::string &ssl_id);
bool addNeighbour(const std::string&);
/*************** External Control ****************/
/* access to network details (called through Monitor) */
const std::string getOwnId();
bool getOwnNetStatus(peerConnectState &state);
bool isFriend(const std::string &ssl_id);
bool isOnline(const std::string &ssl_id);
bool getFriendNetStatus(const std::string &id, peerConnectState &state);
bool getOthersNetStatus(const std::string &id, peerConnectState &state);
void getOnlineList(std::list<std::string> &ssl_peers);
void getFriendList(std::list<std::string> &ssl_peers);
//void getOthersList(std::list<std::string> &peers); /deprecated
bool getPeerCount (unsigned int *pnFriendCount, unsigned int *pnOnlineCount, bool ssl);
/**************** handle monitors *****************/
void addMonitor(pqiMonitor *mon);
void removeMonitor(pqiMonitor *mon);
/******* overloaded from pqiConnectCb *************/
virtual void peerStatus(std::string id, const pqiIpAddrSet &addrs,
uint32_t type, uint32_t flags, uint32_t source);
virtual void peerConnectRequest(std::string id,
struct sockaddr_in raddr, uint32_t source);
//virtual void stunStatus(std::string id, struct sockaddr_in raddr, uint32_t type, uint32_t flags);
/****************** Connections *******************/
bool connectAttempt(const std::string &id, struct sockaddr_in &addr,
uint32_t &delay, uint32_t &period, uint32_t &type);
bool connectResult(const std::string &id, bool success, uint32_t flags, struct sockaddr_in remote_peer_address);
/******************** Groups **********************/
bool addGroup(RsGroupInfo &groupInfo);
bool editGroup(const std::string &groupId, RsGroupInfo &groupInfo);
bool removeGroup(const std::string &groupId);
bool getGroupInfo(const std::string &groupId, RsGroupInfo &groupInfo);
bool getGroupInfoList(std::list<RsGroupInfo> &groupInfoList);
bool assignPeersToGroup(const std::string &groupId, const std::list<std::string> &peerIds, bool assign);
protected:
/****************** Internal Interface *******************/
virtual bool enableNetAssistFirewall(bool on);
virtual bool netAssistFirewallEnabled();
virtual bool netAssistFirewallActive();
virtual bool netAssistFirewallShutdown();
virtual bool enableNetAssistConnect(bool on);
virtual bool netAssistConnectEnabled();
virtual bool netAssistConnectActive();
virtual bool netAssistConnectShutdown();
virtual bool netAssistConnectStats(uint32_t &netsize, uint32_t &localnetsize);
/* Assist Firewall */
bool netAssistExtAddress(struct sockaddr_in &extAddr);
bool netAssistFirewallPorts(uint16_t iport, uint16_t eport);
/* Assist Connect */
virtual bool netAssistFriend(std::string id, bool on);
virtual bool netAssistSetAddress( struct sockaddr_in &laddr,
struct sockaddr_in &eaddr,
uint32_t mode);
/* Internal Functions */
void netReset();
void statusTick();
void netTick();
void netStartup();
/* startup the bits */
void netDhtInit();
void netUdpInit();
void netStunInit();
void netInit();
void netExtInit();
void netExtCheck();
void netUpnpInit();
void netUpnpCheck();
void netUnreachableCheck();
void networkConsistencyCheck();
/* monitor control */
void tickMonitors();
/* connect attempts UDP */
bool retryConnectUDP(const std::string &id, struct sockaddr_in &rUdpAddr);
/* connect attempts TCP */
bool retryConnectTCP(const std::string &id);
void locked_ConnectAttempt_CurrentAddresses(peerConnectState *peer);
void locked_ConnectAttempt_HistoricalAddresses(peerConnectState *peer);
void locked_ConnectAttempt_AddDynDNS(peerConnectState *peer);
void locked_ConnectAttempt_AddTunnel(peerConnectState *peer);
bool locked_ConnectAttempt_Complete(peerConnectState *peer);
bool locked_CheckPotentialAddr(struct sockaddr_in *addr, time_t age);
bool addAddressIfUnique(std::list<peerConnectAddress> &addrList,
peerConnectAddress &pca);
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);
/*****************************************************************/
//void setupOwnNetConfig(RsPeerConfigItem *item);
//void addPeer(RsPeerConfigItem *item);
private:
// These should have there own Mutex Protection,
//p3tunnel *mP3tunnel;
ExtAddrFinder *mExtAddrFinder ;
DNSResolver *mDNSResolver ;
/* These are considered static from a MUTEX perspective */
std::map<uint32_t, pqiNetAssistFirewall *> mFwAgents;
std::map<uint32_t, pqiNetAssistConnect *> mDhts;
std::list<pqiNetListener *> mNetListeners;
RsMutex connMtx; /* protects below */
void netStatusReset_locked();
uint32_t mRetryPeriod;
time_t mNetInitTS;
uint32_t mNetStatus;
bool mStatusChanged;
std::list<pqiMonitor *> clients;
bool mUseExtAddrFinder;
bool mAllowTunnelConnection;
/* external Address determination */
//bool mUpnpAddrValid, mStunAddrValid;
//struct sockaddr_in mUpnpExtAddr;
/* network status flags (read by rsiface) */
pqiNetStatus mNetFlags;
pqiNetStatus mOldNetFlags;
peerConnectState mOwnState;
std::map<std::string, peerConnectState> mFriendList;
std::map<std::string, peerConnectState> mOthersList;
std::list<RsPeerGroupItem *> groupList;
uint32_t lastGroupId;
std::list<RsItem *> saveCleanupList; /* TEMPORARY LIST WHEN SAVING */
/* relatively static list of banned ip addresses */
std::list<struct in_addr> mBannedIpList;
};
#endif // MRK_PQI_CONNECTION_MANAGER_HEADER

View File

@ -29,7 +29,8 @@
#include <openssl/sha.h>
#include "pqi/p3dhtmgr.h"
#include "pqi/p3connmgr.h"
#include "pqi/p3peermgr.h"
#include "pqi/p3linkmgr.h"
#include "util/rsprint.h"
#include "util/rsdebug.h"
@ -941,9 +942,9 @@ int p3DhtMgr::checkNotifyDHT()
/* feedback to say we started it! */
#ifdef P3DHTMGR_USE_LOCAL_UDP_CONN
mConnCb->peerConnectRequest(peer.id, peer.laddr, RS_CB_DHT);
mConnCb->peerConnectRequest(peer.id, peer.laddr,peer.laddr,peer.laddr, RS_CB_DHT, 0, 0,0);
#else
mConnCb->peerConnectRequest(peer.id, peer.raddr, RS_CB_DHT);
mConnCb->peerConnectRequest(peer.id, peer.raddr,peer.laddr,peer.laddr, RS_CB_DHT, 0, 0, 0);
#endif
return DHT_MIN_PERIOD;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,350 @@
/*
* libretroshare/src/pqi: p3linkmgr.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2007-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_PQI_LINK_MANAGER_HEADER
#define MRK_PQI_LINK_MANAGER_HEADER
#include "pqi/pqimonitor.h"
#include "pqi/pqiipset.h"
//#include "pqi/p3dhtmgr.h"
//#include "pqi/p3upnpmgr.h"
#include "pqi/pqiassist.h"
#include "pqi/p3cfgmgr.h"
#include "util/rsthreads.h"
class ExtAddrFinder ;
class DNSResolver ;
/* order of attempts ... */
const uint32_t RS_NET_CONN_TCP_ALL = 0x000f;
const uint32_t RS_NET_CONN_UDP_ALL = 0x00f0;
const uint32_t RS_NET_CONN_TUNNEL = 0x0f00;
const uint32_t RS_NET_CONN_TCP_LOCAL = 0x0001;
const uint32_t RS_NET_CONN_TCP_EXTERNAL = 0x0002;
const uint32_t RS_NET_CONN_TCP_UNKNOW_TOPOLOGY = 0x0004;
const uint32_t RS_NET_CONN_UDP_DHT_SYNC = 0x0010;
const uint32_t RS_NET_CONN_UDP_PEER_SYNC = 0x0020; /* coming soon */
/* extra flags */
// not sure if needed yet.
//const uint32_t RS_NET_CONN_PEERAGE = 0x0f00;
//const uint32_t RS_NET_CONN_SERVER = 0x0100; /* TCP only */
//const uint32_t RS_NET_CONN_PEER = 0x0200; /* all UDP */
const uint32_t RS_TCP_STD_TIMEOUT_PERIOD = 5; /* 5 seconds! */
class peerAddrInfo
{
public:
peerAddrInfo(); /* init */
bool found;
uint32_t type;
pqiIpAddrSet addrs;
time_t ts;
};
class peerConnectAddress
{
public:
peerConnectAddress(); /* init */
struct sockaddr_in addr;
uint32_t delay; /* to stop simultaneous connects */
uint32_t period; /* UDP only */
uint32_t type;
uint32_t flags; /* CB FLAGS defined in pqimonitor.h */
time_t ts;
// Extra Parameters for Relay connections.
struct sockaddr_in proxyaddr;
struct sockaddr_in srcaddr;
uint32_t bandwidth;
};
class peerConnectState
{
public:
peerConnectState(); /* init */
std::string id;
//std::string gpg_id;
//uint32_t netMode; /* EXT / UPNP / UDP / INVALID */
//uint32_t visState; /* STD, GRAY, DARK */
//struct sockaddr_in localaddr, serveraddr;
//used to store current ip (for config and connection management)
//struct sockaddr_in currentlocaladdr; /* Mandatory */
//struct sockaddr_in currentserveraddr; /* Mandatory */
//std::string dyndns;
/* list of addresses from various sources */
//pqiIpAddrSet ipAddrs;
/***** Below here not stored permanently *****/
bool dhtVisible;
//time_t lastcontact;
uint32_t connecttype; // RS_NET_CONN_TCP_ALL / RS_NET_CONN_UDP_ALL
time_t lastavailable;
time_t lastattempt;
std::string name;
//std::string location;
uint32_t state;
uint32_t actions;
uint32_t source; /* most current source */
peerAddrInfo dht;
peerAddrInfo disc;
peerAddrInfo peer;
/* a list of connect attempts to make (in order) */
bool inConnAttempt;
peerConnectAddress currentConnAddrAttempt;
std::list<peerConnectAddress> connAddrs;
};
class p3tunnel;
class RsPeerGroupItem;
class RsGroupInfo;
class p3PeerMgr;
class p3NetMgr;
class p3PeerMgrIMPL;
class p3NetMgrIMPL;
std::string textPeerConnectState(peerConnectState &state);
/*******
* Virtual Interface to allow testing
*
*/
class p3LinkMgr: public pqiConnectCb
{
public:
p3LinkMgr() { return; }
virtual ~p3LinkMgr() { return; }
virtual const std::string getOwnId() = 0;
virtual bool isOnline(const std::string &ssl_id) = 0;
virtual void getOnlineList(std::list<std::string> &ssl_peers) = 0;
/**************** handle monitors *****************/
virtual void addMonitor(pqiMonitor *mon) = 0;
virtual void removeMonitor(pqiMonitor *mon) = 0;
/****************** Connections *******************/
virtual bool connectAttempt(const std::string &id, struct sockaddr_in &raddr,
struct sockaddr_in &proxyaddr, struct sockaddr_in &srcaddr,
uint32_t &delay, uint32_t &period, uint32_t &type, uint32_t &flags, uint32_t &bandwidth) = 0;
virtual bool connectResult(const std::string &id, bool success, uint32_t flags, struct sockaddr_in remote_peer_address) = 0;
virtual bool retryConnect(const std::string &id) = 0;
/* Network Addresses */
virtual bool setLocalAddress(struct sockaddr_in addr) = 0;
virtual struct sockaddr_in getLocalAddress() = 0;
/************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/
virtual void getFriendList(std::list<std::string> &ssl_peers) = 0; // ONLY used by p3peers.cc USE p3PeerMgr instead.
virtual int getOnlineCount() = 0; // ONLY used by p3peers.cc
virtual int getFriendCount() = 0; // ONLY used by p3serverconfig.cc & p3peers.cc
virtual bool getFriendNetStatus(const std::string &id, peerConnectState &state) = 0; // ONLY used by p3peers.cc
virtual void setTunnelConnection(bool b) = 0; // ONLY used by p3peermgr.cc & p3peers.cc MOVE => p3PeerMgr
virtual bool getTunnelConnection() = 0; // ONLY used by p3peermgr.cc & p3peers.cc MOVE => p3PeerMgr
/******* overloaded from pqiConnectCb *************/
// THESE MUSTn't BE specfied HERE - as overloaded from pqiConnectCb.
//virtual void peerStatus(std::string id, const pqiIpAddrSet &addrs,
// uint32_t type, uint32_t flags, uint32_t source) = 0;
//virtual void peerConnectRequest(std::string id, struct sockaddr_in raddr,
// struct sockaddr_in proxyaddr, struct sockaddr_in srcaddr,
// uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth) = 0;
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
};
class p3LinkMgrIMPL: public p3LinkMgr
{
public:
/************************************************************************************************/
/* EXTERNAL INTERFACE */
/************************************************************************************************/
virtual const std::string getOwnId();
virtual bool isOnline(const std::string &ssl_id);
virtual void getOnlineList(std::list<std::string> &ssl_peers);
/**************** handle monitors *****************/
virtual void addMonitor(pqiMonitor *mon);
virtual void removeMonitor(pqiMonitor *mon);
/****************** Connections *******************/
virtual bool connectAttempt(const std::string &id, struct sockaddr_in &raddr,
struct sockaddr_in &proxyaddr, struct sockaddr_in &srcaddr,
uint32_t &delay, uint32_t &period, uint32_t &type, uint32_t &flags, uint32_t &bandwidth);
virtual bool connectResult(const std::string &id, bool success, uint32_t flags, struct sockaddr_in remote_peer_address);
virtual bool retryConnect(const std::string &id);
/* Network Addresses */
virtual bool setLocalAddress(struct sockaddr_in addr);
virtual struct sockaddr_in getLocalAddress();
/******* overloaded from pqiConnectCb *************/
virtual void peerStatus(std::string id, const pqiIpAddrSet &addrs,
uint32_t type, uint32_t flags, uint32_t source);
virtual void peerConnectRequest(std::string id, struct sockaddr_in raddr,
struct sockaddr_in proxyaddr, struct sockaddr_in srcaddr,
uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth);
/************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/
virtual void getFriendList(std::list<std::string> &ssl_peers); // ONLY used by p3peers.cc USE p3PeerMgr instead.
virtual int getOnlineCount(); // ONLY used by p3peers.cc
virtual int getFriendCount(); // ONLY used by p3serverconfig.cc & p3peers.cc
virtual bool getFriendNetStatus(const std::string &id, peerConnectState &state); // ONLY used by p3peers.cc
virtual void setTunnelConnection(bool b); // ONLY used by p3peermgr.cc & p3peers.cc MOVE => p3PeerMgr
virtual bool getTunnelConnection(); // ONLY used by p3peermgr.cc & p3peers.cc MOVE => p3PeerMgr
/************************************************************************************************/
/* Extra IMPL Functions (used by p3PeerMgr, p3NetMgr + Setup) */
/************************************************************************************************/
p3LinkMgrIMPL(p3PeerMgrIMPL *peerMgr, p3NetMgrIMPL *netMgr);
void tick();
/* THIS COULD BE ADDED TO INTERFACE */
void setFriendVisibility(const std::string &id, bool isVisible);
/* add/remove friends */
int addFriend(const std::string &ssl_id, bool isVisible);
int removeFriend(const std::string &ssl_id);
void printPeerLists(std::ostream &out);
protected:
/* THESE CAN PROBABLY BE REMOVED */
//bool shutdown(); /* blocking shutdown call */
//bool getOwnNetStatus(peerConnectState &state);
protected:
/****************** Internal Interface *******************/
/* Internal Functions */
void statusTick();
/* monitor control */
void tickMonitors();
/* connect attempts UDP */
bool tryConnectUDP(const std::string &id, struct sockaddr_in &rUdpAddr,
struct sockaddr_in &proxyaddr, struct sockaddr_in &srcaddr,
uint32_t flags, uint32_t delay, uint32_t bandwidth);
/* connect attempts TCP */
bool retryConnectTCP(const std::string &id);
void locked_ConnectAttempt_SpecificAddress(peerConnectState *peer, struct sockaddr_in *remoteAddr);
void locked_ConnectAttempt_CurrentAddresses(peerConnectState *peer, struct sockaddr_in *localAddr, struct sockaddr_in *serverAddr);
void locked_ConnectAttempt_HistoricalAddresses(peerConnectState *peer, const pqiIpAddrSet &ipAddrs);
void locked_ConnectAttempt_AddDynDNS(peerConnectState *peer, std::string dyndns, uint16_t dynPort);
void locked_ConnectAttempt_AddTunnel(peerConnectState *peer);
bool locked_ConnectAttempt_Complete(peerConnectState *peer);
bool locked_CheckPotentialAddr(const struct sockaddr_in *addr, time_t age);
bool addAddressIfUnique(std::list<peerConnectAddress> &addrList, peerConnectAddress &pca, bool pushFront);
private:
// These should have there own Mutex Protection,
//p3tunnel *mP3tunnel;
DNSResolver *mDNSResolver ;
p3PeerMgrIMPL *mPeerMgr;
p3NetMgrIMPL *mNetMgr;
RsMutex mLinkMtx; /* protects below */
uint32_t mRetryPeriod;
bool mStatusChanged;
struct sockaddr_in mLocalAddress;
std::list<pqiMonitor *> clients;
bool mAllowTunnelConnection;
/* external Address determination */
//bool mUpnpAddrValid, mStunAddrValid;
//struct sockaddr_in mUpnpExtAddr;
//peerConnectState mOwnState;
std::map<std::string, peerConnectState> mFriendList;
std::map<std::string, peerConnectState> mOthersList;
std::list<RsPeerGroupItem *> groupList;
uint32_t lastGroupId;
/* relatively static list of banned ip addresses */
std::list<struct in_addr> mBannedIpList;
};
#endif // MRK_PQI_LINK_MANAGER_HEADER

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,348 @@
/*
* libretroshare/src/pqi: p3netmgr.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2007-2008 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_PQI_NET_MANAGER_HEADER
#define MRK_PQI_NET_MANAGER_HEADER
#include "pqi/pqimonitor.h"
#include "pqi/pqiipset.h"
//#include "pqi/p3dhtmgr.h"
//#include "pqi/p3upnpmgr.h"
#include "pqi/pqiassist.h"
#include "pqi/pqinetstatebox.h"
#include "pqi/p3cfgmgr.h"
#include "util/rsthreads.h"
class ExtAddrFinder ;
class DNSResolver ;
/* RS_VIS_STATE_XXXX
* determines how public this peer wants to be...
*
* STD = advertise to Peers / DHT checking etc
* GRAY = share with friends / but not DHT
* DARK = hidden from all
* BROWN? = hidden from friends / but on DHT
*/
class pqiNetStatus
{
public:
pqiNetStatus();
bool mLocalAddrOk; // Local address is not loopback.
bool mExtAddrOk; // have external address.
bool mExtAddrStableOk; // stable external address.
bool mUpnpOk; // upnp is ok.
bool mDhtOk; // dht is ok.
uint32_t mDhtNetworkSize;
uint32_t mDhtRsNetworkSize;
struct sockaddr_in mLocalAddr; // percieved ext addr.
struct sockaddr_in mExtAddr; // percieved ext addr.
bool mResetReq; // Not Used yet!.
void print(std::ostream &out);
bool NetOk() // minimum to believe network is okay.`
{
return (mLocalAddrOk && mExtAddrOk);
}
};
class p3PeerMgr;
class p3LinkMgr;
class p3PeerMgrIMPL;
class p3LinkMgrIMPL;
class rsUdpStack;
class UdpStunner;
class p3BitDht;
class UdpRelayReceiver;
#define NETMGR_DHT_FEEDBACK_CONNECTED 0x0001
#define NETMGR_DHT_FEEDBACK_CONN_FAILED 0x0002
#define NETMGR_DHT_FEEDBACK_CONN_CLOSED 0x0003
/**********
* p3NetMgr Interface....
* This allows a drop-in replacement for testing.
*/
class p3NetMgr
{
public:
p3NetMgr() { return; }
virtual ~p3NetMgr() { return; }
/*************** External Control ****************/
// Setup Network State.
virtual bool setNetworkMode(uint32_t netMode) = 0;
virtual bool setVisState(uint32_t visState) = 0;
// Switch DHT On/Off.
virtual bool netAssistFriend(std::string id, bool on) = 0;
virtual bool netAssistStatusUpdate(std::string id, int mode) = 0;
/* Get Network State */
virtual uint32_t getNetStateMode() = 0;
virtual uint32_t getNetworkMode() = 0;
virtual uint32_t getNatTypeMode() = 0;
virtual uint32_t getNatHoleMode() = 0;
virtual uint32_t getConnectModes() = 0;
/* Shut It Down! */
virtual bool shutdown() = 0; /* blocking shutdown call */
/************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/
// THESE SHOULD BE MOVED TO p3PeerMgr (as it controls the config).
// The functional object should be transformed into a NetAssistFirewall object.
// ONLY USED by p3peers.cc & p3peermgr.cc
virtual bool getIPServersEnabled() = 0;
virtual void setIPServersEnabled(bool b) = 0;
virtual void getIPServersList(std::list<std::string>& ip_servers) = 0;
// ONLY USED by p3face-config.cc WHICH WILL BE REMOVED.
virtual void getNetStatus(pqiNetStatus &status) = 0;
virtual bool getUPnPState() = 0;
virtual bool getUPnPEnabled() = 0;
virtual bool getDHTEnabled() = 0;
/************************************************************************************************/
/************************************************************************************************/
/************************************************************************************************/
/************************************************************************************************/
};
class p3NetMgrIMPL: public p3NetMgr
{
public:
p3NetMgrIMPL();
/************************************************************************************************/
/* EXTERNAL INTERFACE */
/************************************************************************************************/
/*************** External Control ****************/
// Setup Network State.
virtual bool setNetworkMode(uint32_t netMode);
virtual bool setVisState(uint32_t visState);
// Switch DHT On/Off.
virtual bool netAssistFriend(std::string id, bool on);
virtual bool netAssistStatusUpdate(std::string id, int mode);
/* Get Network State */
virtual uint32_t getNetStateMode();
virtual uint32_t getNetworkMode();
virtual uint32_t getNatTypeMode();
virtual uint32_t getNatHoleMode();
virtual uint32_t getConnectModes();
/* Shut It Down! */
virtual bool shutdown(); /* blocking shutdown call */
/************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/
// THESE SHOULD BE MOVED TO p3PeerMgr (as it controls the config).
// The functional object should be transformed into a NetAssistFirewall object.
// ONLY USED by p3peers.cc & p3peermgr.cc
virtual bool getIPServersEnabled();
virtual void setIPServersEnabled(bool b);
virtual void getIPServersList(std::list<std::string>& ip_servers);
// ONLY USED by p3face-config.cc WHICH WILL BE REMOVED.
virtual void getNetStatus(pqiNetStatus &status);
virtual bool getUPnPState();
virtual bool getUPnPEnabled();
virtual bool getDHTEnabled();
/************************************************************************************************/
/* Extra IMPL Functions (used by p3PeerMgr, p3NetMgr + Setup) */
/************************************************************************************************/
void setManagers(p3PeerMgr *peerMgr, p3LinkMgr *linkMgr);
void setAddrAssist(pqiAddrAssist *dhtStun, pqiAddrAssist *proxyStun);
void tick();
// THESE MIGHT BE ADDED TO INTERFACE.
bool setLocalAddress(struct sockaddr_in addr);
bool setExtAddress(struct sockaddr_in addr);
/*************** Setup ***************************/
void addNetAssistConnect(uint32_t type, pqiNetAssistConnect *);
void addNetAssistFirewall(uint32_t type, pqiNetAssistFirewall *);
void addNetListener(pqiNetListener *listener);
// SHOULD MAKE THIS PROTECTED.
bool checkNetAddress(); /* check our address is sensible */
protected:
void slowTick();
/* THESE FUNCTIONS ARE ON_LONGER EXTERNAL - CAN THEY BE REMOVED? */
//bool getDHTStats(uint32_t &netsize, uint32_t &localnetsize);
//bool getNetStatusLocalOk();
//bool getNetStatusUpnpOk();
//bool getNetStatusDhtOk();
//bool getNetStatusStunOk();
//bool getNetStatusExtraAddressCheckOk();
//bool getUpnpExtAddress(struct sockaddr_in &addr);
//bool getExtFinderAddress(struct sockaddr_in &addr);
//void setOwnNetConfig(uint32_t netMode, uint32_t visState);
protected:
/****************** Internal Interface *******************/
bool enableNetAssistFirewall(bool on);
bool netAssistFirewallEnabled();
bool netAssistFirewallActive();
bool netAssistFirewallShutdown();
bool enableNetAssistConnect(bool on);
bool netAssistConnectEnabled();
bool netAssistConnectActive();
bool netAssistConnectShutdown();
bool netAssistConnectStats(uint32_t &netsize, uint32_t &localnetsize);
void netAssistConnectTick();
/* Assist Firewall */
bool netAssistExtAddress(struct sockaddr_in &extAddr);
bool netAssistFirewallPorts(uint16_t iport, uint16_t eport);
/* Assist Connect */
//virtual bool netAssistFriend(std::string id, bool on); (PUBLIC)
bool netAssistSetAddress( struct sockaddr_in &laddr,
struct sockaddr_in &eaddr,
uint32_t mode);
/* Internal Functions */
void netReset();
void statusTick();
void netTick();
void netStartup();
/* startup the bits */
void netDhtInit();
void netUdpInit();
void netStunInit();
void netInit();
void netExtInit();
void netExtCheck();
void netUpnpInit();
void netUpnpCheck();
void netUnreachableCheck();
/* net state via NetStateBox */
void updateNetStateBox_temporal();
void updateNetStateBox_startup();
void updateNetStateBox_reset();
void updateNatSetting();
private:
// These should have there own Mutex Protection,
ExtAddrFinder *mExtAddrFinder ;
/* These are considered static from a MUTEX perspective */
std::map<uint32_t, pqiNetAssistFirewall *> mFwAgents;
std::map<uint32_t, pqiNetAssistConnect *> mDhts;
std::list<pqiNetListener *> mNetListeners;
p3PeerMgr *mPeerMgr;
p3LinkMgr *mLinkMgr;
//p3BitDht *mBitDht;
pqiAddrAssist *mDhtStunner;
pqiAddrAssist *mProxyStunner;
RsMutex mNetMtx; /* protects below */
void netStatusReset_locked();
struct sockaddr_in mLocalAddr;
struct sockaddr_in mExtAddr;
uint32_t mNetMode;
uint32_t mVisState;
time_t mNetInitTS;
uint32_t mNetStatus;
bool mStatusChanged;
bool mUseExtAddrFinder;
/* network status flags (read by rsiface) */
pqiNetStatus mNetFlags;
pqiNetStatus mOldNetFlags;
// Improved NetStatusBox, which uses the Stunners!
pqiNetStateBox mNetStateBox;
time_t mLastSlowTickTime;
uint32_t mOldNatType;
uint32_t mOldNatHole;
};
#endif // MRK_PQI_NET_MANAGER_HEADER

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,316 @@
/*
* libretroshare/src/pqi: p3peermgr.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2007-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_PQI_PEER_MANAGER_HEADER
#define MRK_PQI_PEER_MANAGER_HEADER
#include "pqi/pqimonitor.h"
#include "pqi/pqiipset.h"
#include "pqi/pqiassist.h"
#include "pqi/p3cfgmgr.h"
#include "util/rsthreads.h"
/* RS_VIS_STATE_XXXX
* determines how public this peer wants to be...
*
* STD = advertise to Peers / DHT checking etc
* GRAY = share with friends / but not DHT
* DARK = hidden from all
* BROWN? = hidden from friends / but on DHT
*/
const uint32_t RS_VIS_STATE_NODISC = 0x0001;
const uint32_t RS_VIS_STATE_NODHT = 0x0002;
const uint32_t RS_VIS_STATE_STD = 0x0000;
const uint32_t RS_VIS_STATE_GRAY = RS_VIS_STATE_NODHT;
const uint32_t RS_VIS_STATE_DARK = RS_VIS_STATE_NODISC | RS_VIS_STATE_NODHT;
const uint32_t RS_VIS_STATE_BROWN = RS_VIS_STATE_NODISC;
/* Startup Modes (confirmed later) */
const uint32_t RS_NET_MODE_TRYMODE = 0x00f0;
const uint32_t RS_NET_MODE_TRY_EXT = 0x0010;
const uint32_t RS_NET_MODE_TRY_UPNP = 0x0020;
const uint32_t RS_NET_MODE_TRY_UDP = 0x0040;
/* Actual State */
const uint32_t RS_NET_MODE_ACTUAL = 0x000f;
const uint32_t RS_NET_MODE_UNKNOWN = 0x0000;
const uint32_t RS_NET_MODE_EXT = 0x0001;
const uint32_t RS_NET_MODE_UPNP = 0x0002;
const uint32_t RS_NET_MODE_UDP = 0x0004;
const uint32_t RS_NET_MODE_UNREACHABLE = 0x0008;
/* flags of peerStatus */
const uint32_t RS_NET_FLAGS_USE_DISC = 0x0001;
const uint32_t RS_NET_FLAGS_USE_DHT = 0x0002;
const uint32_t RS_NET_FLAGS_ONLINE = 0x0004;
const uint32_t RS_NET_FLAGS_EXTERNAL_ADDR = 0x0008;
const uint32_t RS_NET_FLAGS_STABLE_UDP = 0x0010;
const uint32_t RS_NET_FLAGS_TRUSTS_ME = 0x0020;
class peerState
{
public:
peerState(); /* init */
std::string id;
std::string gpg_id;
uint32_t netMode; /* EXT / UPNP / UDP / INVALID */
uint32_t visState; /* STD, GRAY, DARK */
struct sockaddr_in localaddr;
struct sockaddr_in serveraddr;
std::string dyndns;
time_t lastcontact;
/* list of addresses from various sources */
pqiIpAddrSet ipAddrs;
std::string location;
std::string name;
};
class RsPeerGroupItem;
class RsGroupInfo;
std::string textPeerState(peerState &state);
class p3LinkMgr;
class p3NetMgr;
class p3LinkMgrIMPL;
class p3NetMgrIMPL;
class p3PeerMgr
{
public:
p3PeerMgr() { return; }
virtual ~p3PeerMgr() { return; }
virtual bool addFriend(const std::string &ssl_id, const std::string &gpg_id, uint32_t netMode = RS_NET_MODE_UDP,
uint32_t visState = RS_VIS_STATE_STD , time_t lastContact = 0) = 0;
virtual bool removeFriend(const std::string &ssl_id) = 0;
virtual bool isFriend(const std::string &ssl_id) = 0;
/******************** Groups **********************/
/* This is solely used by p3peers - makes sense */
virtual bool addGroup(RsGroupInfo &groupInfo) = 0;
virtual bool editGroup(const std::string &groupId, RsGroupInfo &groupInfo) = 0;
virtual bool removeGroup(const std::string &groupId) = 0;
virtual bool getGroupInfo(const std::string &groupId, RsGroupInfo &groupInfo) = 0;
virtual bool getGroupInfoList(std::list<RsGroupInfo> &groupInfoList) = 0;
virtual bool assignPeersToGroup(const std::string &groupId, const std::list<std::string> &peerIds, bool assign) = 0;
/**************** Set Net Info ****************/
/*
* These functions are used by:
* 1) p3linkmgr
* 2) p3peers - reasonable
* 3) p3disc - reasonable
*/
virtual bool setLocalAddress(const std::string &id, struct sockaddr_in addr) = 0;
virtual bool setExtAddress(const std::string &id, struct sockaddr_in addr) = 0;
virtual bool setDynDNS(const std::string &id, const std::string &dyndns) = 0;
virtual bool setNetworkMode(const std::string &id, uint32_t netMode) = 0;
virtual bool setVisState(const std::string &id, uint32_t visState) = 0;
virtual bool setLocation(const std::string &pid, const std::string &location) = 0;
virtual bool updateCurrentAddress(const std::string& id, const pqiIpAddress &addr) = 0;
virtual bool updateLastContact(const std::string& id) = 0;
virtual bool updateAddressList(const std::string& id, const pqiIpAddrSet &addrs) = 0;
/**************** Net Status Info ****************/
/*
* MUST RATIONALISE THE DATA FROM THESE FUNCTIONS
* These functions are used by:
* 1) p3face-config ... to remove!
* 2) p3peers - reasonable
* 3) p3disc - reasonable
*/
virtual bool getOwnNetStatus(peerState &state) = 0;
virtual bool getFriendNetStatus(const std::string &id, peerState &state) = 0;
virtual bool getOthersNetStatus(const std::string &id, peerState &state) = 0;
/************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/
// Single Use Function... shouldn't be here. used by p3serverconfig.cc
virtual bool haveOnceConnected() = 0;
/*************************************************************************************************/
/*************************************************************************************************/
/*************************************************************************************************/
/*************************************************************************************************/
};
class p3PeerMgrIMPL: public p3PeerMgr, public p3Config
{
public:
/************************************************************************************************/
/* EXTERNAL INTERFACE */
/************************************************************************************************/
virtual bool addFriend(const std::string &ssl_id, const std::string &gpg_id, uint32_t netMode = RS_NET_MODE_UDP,
uint32_t visState = RS_VIS_STATE_STD , time_t lastContact = 0);
virtual bool removeFriend(const std::string &ssl_id);
virtual bool isFriend(const std::string &ssl_id);
/******************** Groups **********************/
/* This is solely used by p3peers - makes sense */
virtual bool addGroup(RsGroupInfo &groupInfo);
virtual bool editGroup(const std::string &groupId, RsGroupInfo &groupInfo);
virtual bool removeGroup(const std::string &groupId);
virtual bool getGroupInfo(const std::string &groupId, RsGroupInfo &groupInfo);
virtual bool getGroupInfoList(std::list<RsGroupInfo> &groupInfoList);
virtual bool assignPeersToGroup(const std::string &groupId, const std::list<std::string> &peerIds, bool assign);
/**************** Set Net Info ****************/
/*
* These functions are used by:
* 1) p3linkmgr
* 2) p3peers - reasonable
* 3) p3disc - reasonable
*/
virtual bool setLocalAddress(const std::string &id, struct sockaddr_in addr);
virtual bool setExtAddress(const std::string &id, struct sockaddr_in addr);
virtual bool setDynDNS(const std::string &id, const std::string &dyndns);
virtual bool setNetworkMode(const std::string &id, uint32_t netMode);
virtual bool setVisState(const std::string &id, uint32_t visState);
virtual bool setLocation(const std::string &pid, const std::string &location);
virtual bool updateCurrentAddress(const std::string& id, const pqiIpAddress &addr);
virtual bool updateLastContact(const std::string& id);
virtual bool updateAddressList(const std::string& id, const pqiIpAddrSet &addrs);
/**************** Net Status Info ****************/
/*
* MUST RATIONALISE THE DATA FROM THESE FUNCTIONS
* These functions are used by:
* 1) p3face-config ... to remove!
* 2) p3peers - reasonable
* 3) p3disc - reasonable
*/
virtual bool getOwnNetStatus(peerState &state);
virtual bool getFriendNetStatus(const std::string &id, peerState &state);
virtual bool getOthersNetStatus(const std::string &id, peerState &state);
/************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/
// Single Use Function... shouldn't be here. used by p3serverconfig.cc
virtual bool haveOnceConnected();
/************************************************************************************************/
/* Extra IMPL Functions (used by p3LinkMgr, p3NetMgr + Setup) */
/************************************************************************************************/
p3PeerMgrIMPL();
void setManagers(p3LinkMgrIMPL *linkMgr, p3NetMgrIMPL *netMgr);
void tick();
const std::string getOwnId();
void setOwnNetworkMode(uint32_t netMode);
void setOwnVisState(uint32_t visState);
int getConnectAddresses(const std::string &id,
struct sockaddr_in &lAddr, struct sockaddr_in &eAddr,
pqiIpAddrSet &histAddrs, std::string &dyndns);
protected:
/* Internal Functions */
void printPeerLists(std::ostream &out);
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);
/*****************************************************************/
/* other important managers */
p3LinkMgrIMPL *mLinkMgr;
p3NetMgrIMPL *mNetMgr;
private:
RsMutex mPeerMtx; /* protects below */
bool mStatusChanged;
std::list<pqiMonitor *> clients;
peerState mOwnState;
std::map<std::string, peerState> mFriendList;
std::map<std::string, peerState> mOthersList;
std::list<RsPeerGroupItem *> groupList;
uint32_t lastGroupId;
std::list<RsItem *> saveCleanupList; /* TEMPORARY LIST WHEN SAVING */
};
#endif // MRK_PQI_PEER_MANAGER_HEADER

View File

@ -229,6 +229,11 @@ static const int NET_CONNECT_FAILED = 5;
static const uint32_t NET_PARAM_CONNECT_DELAY = 1;
static const uint32_t NET_PARAM_CONNECT_PERIOD = 2;
static const uint32_t NET_PARAM_CONNECT_TIMEOUT = 3;
static const uint32_t NET_PARAM_CONNECT_FLAGS = 4;
static const uint32_t NET_PARAM_CONNECT_BANDWIDTH = 5;
static const uint32_t NET_PARAM_CONNECT_PROXY = 6;
static const uint32_t NET_PARAM_CONNECT_SOURCE = 7;
/*!
@ -265,6 +270,7 @@ virtual std::string PeerId() { return peerId; }
virtual int getConnectAddress(struct sockaddr_in &raddr) = 0;
virtual bool connect_parameter(uint32_t type, uint32_t value) = 0;
virtual bool connect_additional_address(uint32_t type, struct sockaddr_in *addr) { return false; } // only needed by udp.
protected:
PQInterface *parent() { return p; }

View File

@ -79,6 +79,24 @@ virtual bool getExternalAddress(struct sockaddr_in &addr) = 0;
};
/* this is for the Stunners
*
*
*/
class pqiAddrAssist
{
public:
pqiAddrAssist() { return; }
virtual ~pqiAddrAssist() { return; }
virtual bool getExternalAddr(struct sockaddr_in &remote, uint8_t &stable) = 0;
virtual void setRefreshPeriod(int32_t period) = 0;
virtual int tick() = 0; /* for internal accounting */
};
class pqiNetAssistConnect: public pqiNetAssist
@ -94,10 +112,14 @@ class pqiNetAssistConnect: public pqiNetAssist
* for the DHT, and must be non-blocking and return quickly
*/
virtual int tick() = 0; /* for internal accounting */
/* add / remove peers */
virtual bool findPeer(std::string id) = 0;
virtual bool dropPeer(std::string id) = 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,

View File

@ -65,14 +65,33 @@ const uint32_t RS_STUN_FRIEND = 0x0020;
const uint32_t RS_STUN_FRIEND_OF_FRIEND = 0x0040;
// for the old p3dhtmgr - amazed it still compiles ;)
#define RS_CONNECT_PASSIVE 1
#define RS_CONNECT_ACTIVE 2
#define RS_CB_DHT 1 /* from dht */
#define RS_CB_DISC 2 /* from peers */
#define RS_CB_PERSON 3 /* from connection */
#define RS_CB_PROXY 4 /* via proxy */
#define RS_CB_DHT 0x0001 /* from dht */
#define RS_CB_DISC 0x0002 /* from peers */
#define RS_CB_PERSON 0x0003 /* from connection */
#define RS_CB_PROXY 0x0004 /* via proxy */
#define RS_CB_FLAG_MASK_MODE 0x00ff
#define RS_CB_FLAG_MASK_ORDER 0xff00
#define RS_CB_FLAG_MODE_TCP 0x0001
#define RS_CB_FLAG_MODE_UDP_DIRECT 0x0002
#define RS_CB_FLAG_MODE_UDP_PROXY 0x0004
#define RS_CB_FLAG_MODE_UDP_RELAY 0x0008
#define RS_CB_FLAG_ORDER_UNSPEC 0x0100
#define RS_CB_FLAG_ORDER_PASSIVE 0x0200
#define RS_CB_FLAG_ORDER_ACTIVE 0x0400
#define RSUDP_NUM_TOU_RECVERS 3
#define RSUDP_TOU_RECVER_DIRECT_IDX 0
#define RSUDP_TOU_RECVER_PROXY_IDX 1
#define RSUDP_TOU_RECVER_RELAY_IDX 2
class pqipeer
@ -84,7 +103,7 @@ uint32_t state;
uint32_t actions;
};
class p3ConnectMgr;
class p3LinkMgr;
/*!
* This class should be implemented
@ -96,13 +115,13 @@ class p3ConnectMgr;
class pqiMonitor
{
public:
pqiMonitor() :mConnMgr(NULL) { return; }
pqiMonitor() :mLinkMgr(NULL) { return; }
virtual ~pqiMonitor() { return; }
/*!
* passes a handle the retroshare connection manager
*/
void setConnectionMgr(p3ConnectMgr *cm) { mConnMgr = cm; }
void setLinkMgr(p3LinkMgr *lm) { mLinkMgr = lm; }
/*!
* this serves as a call back function for server which has
@ -124,7 +143,7 @@ virtual void statusChanged() {};
//virtual void peerStatus(std::string id, uint32_t mode) = 0;
protected:
p3ConnectMgr *mConnMgr;
p3LinkMgr *mLinkMgr;
};
@ -137,8 +156,9 @@ virtual ~pqiConnectCb() { return; }
virtual void peerStatus(std::string id, const pqiIpAddrSet &addrs,
uint32_t type, uint32_t flags, uint32_t source) = 0;
virtual void peerConnectRequest(std::string id,
struct sockaddr_in raddr, uint32_t source) = 0;
virtual void peerConnectRequest(std::string id, struct sockaddr_in raddr,
struct sockaddr_in proxyaddr, struct sockaddr_in srcaddr,
uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth) = 0;
//virtual void stunStatus(std::string id, struct sockaddr_in raddr, uint32_t type, uint32_t flags) = 0;
};

View File

@ -0,0 +1,737 @@
#include "retroshare/rsconfig.h"
#include "util/rsnet.h"
#include "pqi/pqinetstatebox.h"
#include "time.h"
#include <sstream>
// External Interface.
void pqiNetStateBox::setAddressStunDht(struct sockaddr_in *addr, bool stable)
{
if ((!mStunDhtSet) || (mStunDhtStable != stable) ||
(addr->sin_addr.s_addr != mStunDhtAddr.sin_addr.s_addr) ||
(addr->sin_port != mStunDhtAddr.sin_port))
{
mStunDhtSet = true;
mStunDhtStable = stable;
mStunDhtAddr = *addr;
mStatusOkay = false;
}
mStunDhtTS = time(NULL);
}
void pqiNetStateBox::setAddressStunProxy(struct sockaddr_in *addr, bool stable)
{
if ((!mStunProxySet) || (mStunProxyStable != stable) ||
(addr->sin_addr.s_addr != mStunProxyAddr.sin_addr.s_addr) ||
(addr->sin_port != mStunProxyAddr.sin_port))
{
if (addr->sin_addr.s_addr == mStunProxyAddr.sin_addr.s_addr)
{
if (mStunProxyStable != stable)
{
mStunProxySemiStable = true;
}
}
else
{
mStunProxySemiStable = false; // change of address - must trigger this again!
}
mStunProxySet = true;
mStunProxyStable = stable;
mStunProxyAddr = *addr;
mStatusOkay = false;
}
mStunProxyTS = time(NULL);
}
void pqiNetStateBox::setAddressUPnP(bool active, struct sockaddr_in *addr)
{
if ((!mUPnPSet) || (mUPnPActive != active) ||
(addr->sin_addr.s_addr != mUPnPAddr.sin_addr.s_addr) ||
(addr->sin_port != mUPnPAddr.sin_port))
{
mUPnPSet = true;
mUPnPAddr = *addr;
mUPnPActive = active;
mStatusOkay = false;
}
mUPnPTS = time(NULL);
}
void pqiNetStateBox::setAddressNatPMP(bool active, struct sockaddr_in *addr)
{
if ((!mNatPMPSet) || (mNatPMPActive != active) ||
(addr->sin_addr.s_addr != mNatPMPAddr.sin_addr.s_addr) ||
(addr->sin_port != mNatPMPAddr.sin_port))
{
mNatPMPSet = true;
mNatPMPAddr = *addr;
mNatPMPActive = active;
mStatusOkay = false;
}
mNatPMPTS = time(NULL);
}
void pqiNetStateBox::setAddressWebIP(bool active, struct sockaddr_in *addr)
{
if ((!mWebIPSet) || (mWebIPActive != active) ||
(addr->sin_addr.s_addr != mWebIPAddr.sin_addr.s_addr) ||
(addr->sin_port != mWebIPAddr.sin_port))
{
mWebIPSet = true;
mWebIPAddr = *addr;
mWebIPActive = active;
mStatusOkay = false;
}
mWebIPTS = time(NULL);
}
void pqiNetStateBox::setDhtState(bool on, bool active)
{
if ((!mDhtSet) || (mDhtActive != active) || (mDhtOn != on))
{
mDhtSet = true;
mDhtActive = active;
mDhtOn = on;
mStatusOkay = false;
}
mDhtTS = time(NULL);
}
/* Extract Net State */
uint32_t pqiNetStateBox::getNetworkMode()
{
updateNetState();
return mNetworkMode;
}
uint32_t pqiNetStateBox::getNatTypeMode()
{
updateNetState();
return mNatTypeMode;
}
uint32_t pqiNetStateBox::getNatHoleMode()
{
updateNetState();
return mNatHoleMode;
}
uint32_t pqiNetStateBox::getConnectModes()
{
updateNetState();
return mConnectModes;
}
uint32_t pqiNetStateBox::getNetStateMode()
{
updateNetState();
return mNetStateMode;
}
/******************************** Internal Workings *******************************/
pqiNetStateBox::pqiNetStateBox()
{
reset();
}
void pqiNetStateBox::reset()
{
mStatusOkay = false;
//time_t mStatusTS;
mNetworkMode = RSNET_NETWORK_UNKNOWN;
mNatTypeMode = RSNET_NATTYPE_UNKNOWN;
mNatHoleMode = RSNET_NATHOLE_UNKNOWN;
mConnectModes = RSNET_CONNECT_NONE;
mNetStateMode = RSNET_NETSTATE_BAD_UNKNOWN;
/* Parameters set externally */
mStunDhtSet = false;
time_t mStunDhtTS = 0;
bool mStunDhtStable = false;
//struct sockaddr_in mStunDhtAddr;
mStunProxySet = false;
mStunProxySemiStable = false;
time_t mStunProxyTS = 0;
bool mStunProxyStable = false;
//struct sockaddr_in mStunProxyAddr;
mUPnPSet = false;
mUPnPActive = false;
//struct sockaddr_in mUPnPAddr;
mNatPMPSet = false;
mNatPMPActive = false;
//struct sockaddr_in mNatPMPAddr;
mWebIPSet = false;
mWebIPActive = false;
//struct sockaddr_in mWebIPAddr;
mPortForwardedSet = false;
mPortForwarded = 0;
mDhtSet = false;
mDhtActive = false;
mDhtOn = false;
}
#define NETSTATE_PARAM_TIMEOUT 600
#define NETSTATE_TIMEOUT 60
/* check/update Net State */
int pqiNetStateBox::statusOkay()
{
if (!mStatusOkay)
{
return 0;
}
time_t now = time(NULL);
if (now - mStatusTS > NETSTATE_TIMEOUT)
{
return 0;
}
return 1;
}
int pqiNetStateBox::updateNetState()
{
if (!statusOkay())
{
determineNetworkState();
}
return 1;
}
void pqiNetStateBox::clearOldNetworkData()
{
/* check if any measurements are too old to consider */
time_t now = time(NULL);
if (now - mStunProxyTS > NETSTATE_PARAM_TIMEOUT)
{
mStunProxySet = false;
}
if (now - mStunDhtTS > NETSTATE_PARAM_TIMEOUT)
{
mStunDhtSet = false;
}
}
void pqiNetStateBox::determineNetworkState()
{
clearOldNetworkData();
time_t now = time(NULL);
/* now we use the remaining valid input to determine network state */
/* Most important Factor is whether we have DHT(STUN) info to ID connection */
if (mDhtActive)
{
/* firstly lets try to identify OFFLINE / UNKNOWN */
if ((!mStunProxySet) || (!mStunDhtSet))
{
mNetworkMode = RSNET_NETWORK_UNKNOWN;
// Assume these.
mNatTypeMode = RSNET_NATTYPE_UNKNOWN;
mNatHoleMode = RSNET_NATHOLE_NONE;
mNetStateMode = RSNET_NETSTATE_BAD_UNKNOWN;
//mExtAddress = .... unknown;
//mExtAddrStable = false;
}
else // Both Are Set!
{
if (!mStunDhtStable)
{
//mExtAddress = mStunDhtExtAddress;
//mExtAddrStable = false;
if (mStunProxySemiStable)
{
/* I'm guessing this will be a common mode for modern NAT/Firewalls.
* a DETERMINISTIC SYMMETRIC NAT.... This is likely to be the
* next iteration on the RESTRICTED CONE firewall described below.
* If you Stun fast, it looks like a SYMMETRIC NAT, but if you let
* the NAT timeout, you get back your original port so it looks like
* a RESTRICTED CONE nat...
*
* This kind of NAT is passable, if you only attempt one connection at
* a time, and are careful about it!
*
* NB: The StunDht port will never get this mode.
* It has unsolicited traffic which triggers SYM mode
*
*/
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
mNatTypeMode = RSNET_NATTYPE_DETERM_SYM;
mNatHoleMode = RSNET_NATHOLE_NONE;
mNetStateMode = RSNET_NETSTATE_WARNING_NATTED;
}
else if (!mStunProxyStable)
{
/* both unstable, Symmetric NAT, Firewalled, No UDP Hole */
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
mNatTypeMode = RSNET_NATTYPE_SYMMETRIC;
mNatHoleMode = RSNET_NATHOLE_NONE;
mNetStateMode = RSNET_NETSTATE_BAD_NATSYM;
}
else
{
/* if DhtStun Unstable, but ProxyStable, then we have
* an interesting case. This is close to a Debian Firewall
* I tested in the past....
*
* The big difference between DhtStun and ProxyStun is
* that Dht Port receives unsolicated packets,
* while Proxy Port always sends an outgoing one first.
*
* In the case of the debian firewall, the unsolicated pkts
* caused the outgoing port to change.
*
* We will label this difference RESTRICTED vs FULL CONE,
* but that label is really fully accurate. (gray area).
*/
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
mNatTypeMode = RSNET_NATTYPE_RESTRICTED_CONE;
mNatHoleMode = RSNET_NATHOLE_NONE;
mNetStateMode = RSNET_NETSTATE_WARNING_NATTED;
}
}
else // Dht Stable.
{
/* DHT Stable port can be caused by:
* 1) Forwarded Port (UPNP, NATPMP, FORWARDED)
* 2) FULL CONE NAT.
* 3) EXT Port.
* Must look at Proxy Stability.
* - if Proxy Unstable, then must be forwarded port.
* - if Proxy Stable, then we cannot tell.
* -> Must use User Info (Upnp, PMP, Forwarded Flag).
* -> Also possible to be EXT Port (Check against iface)
*/
//mExtAddress = mStunDhtExtAddress;
//mExtAddrStable = true;
// Initial Fallback Guess at firewall state.
if (mStunProxySemiStable)
{
/* must be a forwarded port/ext or something similar */
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
mNatTypeMode = RSNET_NATTYPE_DETERM_SYM;
mNatHoleMode = RSNET_NATHOLE_FORWARDED;
mNetStateMode = RSNET_NETSTATE_GOOD;
}
else if (!mStunProxyStable)
{
/* must be a forwarded port/ext or something similar */
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
mNatTypeMode = RSNET_NATTYPE_SYMMETRIC;
mNatHoleMode = RSNET_NATHOLE_FORWARDED;
mNetStateMode = RSNET_NETSTATE_GOOD;
}
else
{
/* fallback is FULL CONE NAT */
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
mNatTypeMode = RSNET_NATTYPE_FULL_CONE;
mNatHoleMode = RSNET_NATHOLE_NONE;
mNetStateMode = RSNET_NETSTATE_WARNING_NATTED;
}
if (mUPnPActive)
{
// This Mode is OKAY.
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
// Use Fallback Guess.
//mNatTypeMode = RSNET_NATTYPE_UNKNOWN;
mNatHoleMode = RSNET_NATHOLE_UPNP;
mNetStateMode = RSNET_NETSTATE_GOOD;
//mExtAddress = ... from UPnP, should match StunDht.
//mExtAddrStable = true;
}
else if (mNatPMPActive)
{
// This Mode is OKAY.
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
// Use Fallback Guess.
//mNatTypeMode = RSNET_NATTYPE_UNKNOWN;
mNatHoleMode = RSNET_NATHOLE_NATPMP;
mNetStateMode = RSNET_NETSTATE_GOOD;
//mExtAddress = ... from NatPMP, should match NatPMP
//mExtAddrStable = true;
}
else
{
bool isExtAddress = false;
if (isExtAddress)
{
mNetworkMode = RSNET_NETWORK_EXTERNALIP;
mNatTypeMode = RSNET_NATTYPE_NONE;
mNatHoleMode = RSNET_NATHOLE_NONE;
mNetStateMode = RSNET_NETSTATE_GOOD;
//mExtAddrStable = true;
}
else if (mPortForwardedSet)
{
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
// Use Fallback Guess.
//mNatTypeMode = RSNET_NATTYPE_UNKNOWN;
mNatHoleMode = RSNET_NATHOLE_FORWARDED;
mNetStateMode = RSNET_NETSTATE_ADV_FORWARD;
//mExtAddrStable = true; // Probably, makin assumption.
}
else
{
/* At this point, we go with the fallback guesses */
}
}
}
}
}
else // DHT Inactive, must use other means...
{
/* If we get here we are dealing with a silly peer in "DarkMode".
* We have to primarily rely on the feedback from UPnP, PMP or WebSite "WhatsMyIp".
* This is in the "Advanced" Settings and liable to be set wrong.
* but thats the users fault!
*/
if (mUPnPActive)
{
// This Mode is OKAY.
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
mNatTypeMode = RSNET_NATTYPE_UNKNOWN;
mNatHoleMode = RSNET_NATHOLE_UPNP;
//mExtAddress = ... from UPnP.
//mExtAddrStable = true;
mNetStateMode = RSNET_NETSTATE_WARNING_NODHT;
}
else if (mNatPMPActive)
{
// This Mode is OKAY.
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
mNatTypeMode = RSNET_NATTYPE_UNKNOWN;
mNatHoleMode = RSNET_NATHOLE_NATPMP;
//mExtAddress = ... from NatPMP.
//mExtAddrStable = true;
mNetStateMode = RSNET_NETSTATE_WARNING_NODHT;
}
else
{
/* if we reach this point, we really need a Web "WhatsMyIp" Check of our Ext Ip Address. */
/* Check for the possibility of an EXT address ... */
bool isExtAddress = false;
//mExtAddress = ... from WhatsMyIp.
if (isExtAddress)
{
mNetworkMode = RSNET_NETWORK_EXTERNALIP;
mNatTypeMode = RSNET_NATTYPE_NONE;
mNatHoleMode = RSNET_NATHOLE_NONE;
//mExtAddrStable = true;
mNetStateMode = RSNET_NETSTATE_WARNING_NODHT;
}
else if (mPortForwardedSet)
{
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
mNatTypeMode = RSNET_NATTYPE_UNKNOWN;
mNatHoleMode = RSNET_NATHOLE_FORWARDED;
//mExtAddrStable = true; // Probably, makin assumption.
mNetStateMode = RSNET_NETSTATE_WARNING_NODHT;
}
else
{
/* At this point we must assume firewalled.
* These people have destroyed the possibility of making connections ;(
* Should WARN about this.
*/
mNetworkMode = RSNET_NETWORK_BEHINDNAT;
mNatTypeMode = RSNET_NATTYPE_UNKNOWN;
mNatHoleMode = RSNET_NATHOLE_NONE;
mNetStateMode = RSNET_NETSTATE_BAD_NODHT_NAT;
//mExtAddrStable = false; // Unlikely to be stable.
}
}
}
workoutNetworkMode();
/* say that things are okay */
mStatusOkay = true;
mStatusTS = now;
}
/* based on calculated settings, what is the network mode
*/
void pqiNetStateBox::workoutNetworkMode()
{
/* connectModes are dependent on the other modes */
mConnectModes = RSNET_CONNECT_NONE;
switch(mNetworkMode)
{
case RSNET_NETWORK_UNKNOWN:
case RSNET_NETWORK_OFFLINE:
case RSNET_NETWORK_LOCALNET:
/* nothing here */
break;
case RSNET_NETWORK_EXTERNALIP:
mConnectModes = RSNET_CONNECT_OUTGOING_TCP;
mConnectModes |= RSNET_CONNECT_ACCEPT_TCP;
if (mDhtActive)
{
mConnectModes |= RSNET_CONNECT_DIRECT_UDP;
/* if open port. don't want PROXY or RELAY connect
* because we should be able to do direct with EVERYONE.
* Ability to do Proxy is dependent on FIREWALL status.
* Technically could do RELAY, but disable both.
*/
//mConnectModes |= RSNET_CONNECT_PROXY_UDP;
//mConnectModes |= RSNET_CONNECT_RELAY_UDP;
}
break;
case RSNET_NETWORK_BEHINDNAT:
mConnectModes = RSNET_CONNECT_OUTGOING_TCP;
/* we're okay if there's a NAT HOLE */
if ((mNatHoleMode == RSNET_NATHOLE_UPNP) ||
(mNatHoleMode == RSNET_NATHOLE_NATPMP) ||
(mNatHoleMode == RSNET_NATHOLE_FORWARDED))
{
mConnectModes |= RSNET_CONNECT_ACCEPT_TCP;
if (mDhtActive)
{
mConnectModes |= RSNET_CONNECT_DIRECT_UDP;
/* dont want PROXY | RELAY with open ports */
}
}
else
{
/* If behind NAT without NATHOLE, this is where RELAY | PROXY
* are useful. We Flag DIRECT connections, cos we can do these
* with peers with Open Ports. (but not with other NATted peers).
*/
if (mDhtActive)
{
mConnectModes |= RSNET_CONNECT_DIRECT_UDP;
mConnectModes |= RSNET_CONNECT_RELAY_UDP;
if ((mNatTypeMode == RSNET_NATTYPE_RESTRICTED_CONE) ||
(mNatTypeMode == RSNET_NATTYPE_FULL_CONE) ||
(mNatTypeMode == RSNET_NATTYPE_DETERM_SYM))
{
mConnectModes |= RSNET_CONNECT_PROXY_UDP;
}
}
}
break;
}
}
std::string NetStateNetworkModeString(uint32_t netMode)
{
std::string str;
switch(netMode)
{
default:
case RSNET_NETWORK_UNKNOWN:
str = "Unknown NetState";
break;
case RSNET_NETWORK_OFFLINE:
str = "Offline";
break;
case RSNET_NETWORK_LOCALNET:
str = "Local Net";
break;
case RSNET_NETWORK_BEHINDNAT:
str = "Behind NAT";
break;
case RSNET_NETWORK_EXTERNALIP:
str = "External IP";
break;
}
return str;
}
std::string NetStateNatTypeString(uint32_t natType)
{
std::string str;
switch(natType)
{
default:
case RSNET_NATTYPE_UNKNOWN:
str = "UNKNOWN NAT STATE";
break;
case RSNET_NATTYPE_SYMMETRIC:
str = "SYMMETRIC NAT";
break;
case RSNET_NATTYPE_DETERM_SYM:
str = "DETERMINISTIC SYM NAT";
break;
case RSNET_NATTYPE_RESTRICTED_CONE:
str = "RESTRICTED CONE NAT";
break;
case RSNET_NATTYPE_FULL_CONE:
str = "FULL CONE NAT";
break;
case RSNET_NATTYPE_OTHER:
str = "OTHER NAT";
break;
case RSNET_NATTYPE_NONE:
str = "NO NAT";
break;
}
return str;
}
std::string NetStateNatHoleString(uint32_t natHole)
{
std::string str;
switch(natHole)
{
default:
case RSNET_NATHOLE_UNKNOWN:
str = "UNKNOWN NAT HOLE STATUS";
break;
case RSNET_NATHOLE_NONE:
str = "NO NAT HOLE";
break;
case RSNET_NATHOLE_UPNP:
str = "UPNP FORWARD";
break;
case RSNET_NATHOLE_NATPMP:
str = "NATPMP FORWARD";
break;
case RSNET_NATHOLE_FORWARDED:
str = "MANUAL FORWARD";
break;
}
return str;
}
std::string NetStateConnectModesString(uint32_t connect)
{
std::ostringstream connOut;
if (connect & RSNET_CONNECT_OUTGOING_TCP)
{
connOut << "TCP_OUT ";
}
if (connect & RSNET_CONNECT_ACCEPT_TCP)
{
connOut << "TCP_IN ";
}
if (connect & RSNET_CONNECT_DIRECT_UDP)
{
connOut << "DIRECT_UDP ";
}
if (connect & RSNET_CONNECT_PROXY_UDP)
{
connOut << "PROXY_UDP ";
}
if (connect & RSNET_CONNECT_RELAY_UDP)
{
connOut << "RELAY_UDP ";
}
return connOut.str();
}
std::string NetStateNetStateString(uint32_t netstate)
{
std::string str;
switch(netstate)
{
case RSNET_NETSTATE_BAD_UNKNOWN:
str = "NET BAD: Unknown State";
break;
case RSNET_NETSTATE_BAD_OFFLINE:
str = "NET BAD: Offline";
break;
case RSNET_NETSTATE_BAD_NATSYM:
str = "NET BAD: Behind Symmetric NAT";
break;
case RSNET_NETSTATE_BAD_NODHT_NAT:
str = "NET BAD: Behind NAT & No DHT";
break;
case RSNET_NETSTATE_WARNING_RESTART:
str = "NET WARNING: NET Restart";
break;
case RSNET_NETSTATE_WARNING_NATTED:
str = "NET WARNING: Behind NAT";
break;
case RSNET_NETSTATE_WARNING_NODHT:
str = "NET WARNING: No DHT";
break;
case RSNET_NETSTATE_GOOD:
str = "NET STATE GOOD!";
break;
case RSNET_NETSTATE_ADV_FORWARD:
str = "CAUTION: UNVERIFABLE FORWARD!";
break;
case RSNET_NETSTATE_ADV_DARK_FORWARD:
str = "CAUTION: UNVERIFABLE FORWARD & NO DHT";
break;
}
return str;
}

View File

@ -0,0 +1,105 @@
#ifndef PQI_NET_STATUS_BOX_H
#define PQI_NET_STATUS_BOX_H
/* a little state box to determine network status */
#include <string>
#include <list>
#include "bitdht/bdiface.h"
/*** Network state
* Want this to be all encompassing.
*
*/
class pqiNetStateBox
{
public:
pqiNetStateBox();
void reset();
/* input network bits */
void setAddressStunDht(struct sockaddr_in *, bool stable);
void setAddressStunProxy(struct sockaddr_in *, bool stable);
void setAddressUPnP(bool active, struct sockaddr_in *addr);
void setAddressNatPMP(bool active, struct sockaddr_in *addr);
void setAddressWebIP(bool active, struct sockaddr_in *addr);
void setDhtState(bool dhtOn, bool dhtActive);
uint32_t getNetStateMode();
uint32_t getNetworkMode();
uint32_t getNatTypeMode();
uint32_t getNatHoleMode();
uint32_t getConnectModes();
private:
/* calculate network state */
void clearOldNetworkData();
void determineNetworkState();
int statusOkay();
int updateNetState();
/* more internal fns */
void workoutNetworkMode();
bool mStatusOkay;
time_t mStatusTS;
uint32_t mNetworkMode;
uint32_t mNatTypeMode;
uint32_t mNatHoleMode;
uint32_t mConnectModes;
uint32_t mNetStateMode;
/* Parameters set externally */
bool mStunDhtSet;
time_t mStunDhtTS;
bool mStunDhtStable;
struct sockaddr_in mStunDhtAddr;
bool mStunProxySet;
time_t mStunProxyTS;
bool mStunProxyStable;
bool mStunProxySemiStable;
struct sockaddr_in mStunProxyAddr;
bool mDhtSet;
time_t mDhtTS;
bool mDhtOn;
bool mDhtActive;
bool mUPnPSet;
struct sockaddr_in mUPnPAddr;
bool mUPnPActive;
time_t mUPnPTS;
bool mNatPMPSet;
struct sockaddr_in mNatPMPAddr;
bool mNatPMPActive;
time_t mNatPMPTS;
bool mWebIPSet;
struct sockaddr_in mWebIPAddr;
bool mWebIPActive;
time_t mWebIPTS;
bool mPortForwardedSet;
uint16_t mPortForwarded;
};
std::string NetStateNetStateString(uint32_t netstate);
std::string NetStateConnectModesString(uint32_t connect);
std::string NetStateNatHoleString(uint32_t natHole);
std::string NetStateNatTypeString(uint32_t natType);
std::string NetStateNetworkModeString(uint32_t netMode);
#endif

View File

@ -654,7 +654,7 @@ bool getPreferredInterface(struct in_addr &prefAddr) // returns best addr.
return false;
}
bool sameNet(struct in_addr *addr, struct in_addr *addr2)
bool sameNet(const struct in_addr *addr, const struct in_addr *addr2)
{
#ifdef NET_DEBUG
std::cerr << "sameNet: " << rs_inet_ntoa(*addr);

View File

@ -108,7 +108,7 @@ bool getLocalInterfaces(std::list<struct in_addr> &addrs); // returns all possib
// checks (addr1 & 255.255.255.0) == (addr2 & 255.255.255.0)
bool isSameSubnet(struct in_addr *addr1, struct in_addr *addr2);
bool sameNet(struct in_addr *addr, struct in_addr *addr2);
bool sameNet(const struct in_addr *addr, const struct in_addr *addr2);
in_addr_t pqi_inet_netof(struct in_addr addr); // our implementation.

View File

@ -268,7 +268,8 @@ int pqiperson::notifyEvent(NetInterface *ni, int newState)
"CONNECT_FAILED->marking so!");
active = false;
activepqi = NULL;
} else {
} else
{
pqioutput(PQL_WARNING, pqipersonzone,
"CONNECT_FAILED-> from an unactive connection, don't flag the peer as not connected, just try next attempt !");
}
@ -279,7 +280,7 @@ int pqiperson::notifyEvent(NetInterface *ni, int newState)
"CONNECT_FAILED+NOT active -> try connect again");
}
/* notify up (But not if we are actually active: rtn -1 case above) */
/* notify up */
if (pqipg)
{
struct sockaddr_in raddr;
@ -377,18 +378,23 @@ int pqiperson::stoplistening()
return 1;
}
int pqiperson::connect(uint32_t type, struct sockaddr_in raddr, uint32_t delay, uint32_t period, uint32_t timeout)
int pqiperson::connect(uint32_t type, struct sockaddr_in raddr,
struct sockaddr_in &proxyaddr, struct sockaddr_in &srcaddr,
uint32_t delay, uint32_t period, uint32_t timeout, uint32_t flags, uint32_t bandwidth)
{
#ifdef PERSON_DEBUG
{
std::ostringstream out;
out << "pqiperson::connect() Id: " << PeerId();
out << " type: " << type;
out << " addr: " << rs_inet_ntoa(raddr.sin_addr);
out << ":" << ntohs(raddr.sin_port);
out << " addr: " << rs_inet_ntoa(raddr.sin_addr) << ":" << ntohs(raddr.sin_port);
out << " proxyaddr: " << rs_inet_ntoa(proxyaddr.sin_addr) << ":" << ntohs(proxyaddr.sin_port);
out << " srcaddr: " << rs_inet_ntoa(srcaddr.sin_addr) << ":" << ntohs(srcaddr.sin_port);
out << " delay: " << delay;
out << " period: " << period;
out << " timeout: " << timeout;
out << " flags: " << flags;
out << " bandwidth: " << bandwidth;
out << std::endl;
std::cerr << out.str();
//pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
@ -415,6 +421,9 @@ int pqiperson::connect(uint32_t type, struct sockaddr_in raddr, uint32_t delay,
return 0;
}
std::cerr << "pqiperson::connect() WARNING, resetting for new connection attempt" << std::endl;
#ifdef PERSON_DEBUG
#endif
/* set the parameters */
(it->second)->reset();
@ -424,8 +433,13 @@ int pqiperson::connect(uint32_t type, struct sockaddr_in raddr, uint32_t delay,
(it->second)->connect_parameter(NET_PARAM_CONNECT_DELAY, delay);
(it->second)->connect_parameter(NET_PARAM_CONNECT_PERIOD, period);
(it->second)->connect_parameter(NET_PARAM_CONNECT_TIMEOUT, timeout);
(it->second)->connect_parameter(NET_PARAM_CONNECT_FLAGS, flags);
(it->second)->connect_parameter(NET_PARAM_CONNECT_BANDWIDTH, bandwidth);
(it->second)->connect(raddr);
(it->second)->connect_additional_address(NET_PARAM_CONNECT_PROXY, &proxyaddr);
(it->second)->connect_additional_address(NET_PARAM_CONNECT_SOURCE, &srcaddr);
(it->second)->connect(raddr);
// flag if we started a new connectionAttempt.
inConnectAttempt = true;

View File

@ -71,6 +71,10 @@ virtual int stoplistening() { return ni -> stoplistening(); }
virtual int reset() { return ni -> reset(); }
virtual int disconnect() { return ni -> reset(); }
virtual bool connect_parameter(uint32_t type, uint32_t value) { return ni -> connect_parameter(type, value);}
virtual bool connect_additional_address(uint32_t type, struct sockaddr_in *addr) { return ni -> connect_additional_address(type, addr);}
virtual int getConnectAddress(struct sockaddr_in &raddr){ return ni->getConnectAddress(raddr); }
// get the contact from the net side!
@ -106,7 +110,11 @@ virtual ~pqiperson(); // must clean up children.
int reset();
int listen();
int stoplistening();
int connect(uint32_t type, struct sockaddr_in raddr, uint32_t delay, uint32_t period, uint32_t timeout);
int connect(uint32_t type, struct sockaddr_in raddr,
struct sockaddr_in &proxyaddr, struct sockaddr_in &srcaddr,
uint32_t delay, uint32_t period, uint32_t timeout, uint32_t flags, uint32_t bandwidth);
int receiveHeartbeat();
// add in connection method.
int addChildInterface(uint32_t type, pqiconnect *pqi);

View File

@ -24,7 +24,7 @@
*/
#include "pqi/pqipersongrp.h"
#include "pqi/p3connmgr.h"
#include "pqi/p3linkmgr.h"
#include "util/rsdebug.h"
#include <sstream>
@ -185,11 +185,10 @@ int pqipersongrp::init_listener()
{
/* extract details from
*/
peerConnectState state;
mConnMgr->getOwnNetStatus(state);
struct sockaddr_in laddr = mLinkMgr->getLocalAddress();
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
pqil = createListener(state.currentlocaladdr);
pqil = createListener(laddr);
}
return 1;
}
@ -325,19 +324,19 @@ void pqipersongrp::statusChanged()
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
/* get address from p3connmgr */
if (!mConnMgr) {
if (!mLinkMgr) {
return;
}
/* check for active connections and start waiting id's */
std::list<std::string> peers;
mConnMgr->getFriendList(peers);
mLinkMgr->getFriendList(peers);
/* count connection attempts */
std::list<std::string>::iterator peer;
for (peer = peers.begin(); peer != peers.end(); peer++) {
peerConnectState state;
if (mConnMgr->getFriendNetStatus(*peer, state) == false) {
if (mLinkMgr->getFriendNetStatus(*peer, state) == false) {
continue;
}
@ -382,9 +381,9 @@ int pqipersongrp::addPeer(std::string id)
pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone, out.str());
}
#ifdef PGRP_DEBUG
std::cerr << " pqipersongrp::addPeer() id: " << id;
std::cerr << "pqipersongrp::addPeer() id: " << id;
std::cerr << std::endl;
#ifdef PGRP_DEBUG
#endif
SearchModule *sm = NULL;
@ -395,6 +394,10 @@ int pqipersongrp::addPeer(std::string id)
{
pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone,
"pqipersongrp::addPeer() Peer already in Use!");
std::cerr << " pqipersongrp::addPeer() ERROR Peer already in use! id: " << id;
std::cerr << std::endl;
return -1;
}
@ -420,9 +423,9 @@ int pqipersongrp::removePeer(std::string id)
std::map<std::string, SearchModule *>::iterator it;
#ifdef PGRP_DEBUG
std::cerr << " pqipersongrp::removePeer() id: " << id;
std::cerr << std::endl;
#endif
std::cerr << "pqipersongrp::removePeer() id: " << id;
std::cerr << std::endl;
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
@ -439,6 +442,11 @@ int pqipersongrp::removePeer(std::string id)
delete p;
mods.erase(it);
}
else
{
std::cerr << " pqipersongrp::removePeer() ERROR doesn't exist! id: " << id;
std::cerr << std::endl;
}
return 1;
}
@ -484,10 +492,12 @@ int pqipersongrp::connectPeer(std::string id
std::cerr << std::endl;
#endif
{ RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (id == mConnMgr->getOwnId()) {
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (id == mLinkMgr->getOwnId())
{
std::cerr << "pqipersongrp::connectPeer() ERROR Failed, connecting to own id." << std::endl;
#ifdef PGRP_DEBUG
std::cerr << "pqipersongrp::connectPeer() Failed, connecting to own id." << std::endl;
#endif
return 0;
}
@ -503,7 +513,7 @@ int pqipersongrp::connectPeer(std::string id
/* get address from p3connmgr */
if (!mConnMgr)
if (!mLinkMgr)
return 0;
#ifdef WINDOWS_SYS
@ -538,8 +548,13 @@ int pqipersongrp::connectPeer(std::string id
uint32_t period;
uint32_t timeout;
uint32_t type;
uint32_t flags;
if (!mConnMgr->connectAttempt(id, addr, delay, period, type))
struct sockaddr_in proxyaddr;
struct sockaddr_in srcaddr;
uint32_t bandwidth;
if (!mLinkMgr->connectAttempt(id, addr, proxyaddr, srcaddr, delay, period, type, flags, bandwidth))
{
#ifdef PGRP_DEBUG
std::cerr << " pqipersongrp::connectPeer() No Net Address";
@ -554,6 +569,7 @@ int pqipersongrp::connectPeer(std::string id
std::cerr << " delay: " << delay;
std::cerr << " period: " << period;
std::cerr << " type: " << type;
std::cerr << " flags: " << flags;
std::cerr << std::endl;
#endif
@ -595,7 +611,7 @@ int pqipersongrp::connectPeer(std::string id
return 0;
}
p->connect(ptype, addr, delay, period, timeout);
p->connect(ptype, addr, proxyaddr, srcaddr, delay, period, timeout, flags, bandwidth);
} /* UNLOCKED */
@ -621,10 +637,10 @@ bool pqipersongrp::notifyConnect(std::string id, uint32_t ptype, bool success
}
if (mConnMgr)
mConnMgr->connectResult(id, success, type, raddr);
if (mLinkMgr)
mLinkMgr->connectResult(id, success, type, raddr);
return (NULL != mConnMgr);
return (NULL != mLinkMgr);
}
/******************************** DUMMY Specific features ***************************/

View File

@ -42,6 +42,8 @@
#include "pqi/pqissllistener.h"
#include "pqi/p3linkmgr.h"
const int pqisslzone = 37714;
/*********
@ -92,7 +94,7 @@ static const int PQISSL_SSL_CONNECT_TIMEOUT = 30;
*
*/
pqissl::pqissl(pqissllistener *l, PQInterface *parent, p3ConnectMgr *cm)
pqissl::pqissl(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm)
:NetBinInterface(parent, parent->PeerId()),
waiting(WAITING_NOT), active(false), certvalid(false),
sslmode(PQISSL_ACTIVE), ssl_connection(NULL), sockfd(-1),
@ -102,7 +104,7 @@ pqissl::pqissl(pqissllistener *l, PQInterface *parent, p3ConnectMgr *cm)
net_attempt(0), net_failure(0), net_unreachable(0),
sameLAN(false), n_read_zero(0), mReadZeroTS(0),
mConnectDelay(0), mConnectTS(0),
mConnectTimeout(0), mTimeoutTS(0), mConnMgr(cm)
mConnectTimeout(0), mTimeoutTS(0), mLinkMgr(lm)
{
/* set address to zero */
@ -1107,6 +1109,9 @@ int pqissl::SSL_Connection_Complete()
int pqissl::Extract_Failed_SSL_Certificate()
{
std::cerr << "pqissl::Extract_Failed_SSL_Certificate() FAILED Connection due to Security Issues";
std::cerr << std::endl;
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::Extract_Failed_SSL_Certificate()");
@ -1117,12 +1122,19 @@ int pqissl::Extract_Failed_SSL_Certificate()
{
rslog(RSL_WARNING, pqisslzone,
"pqissl::Extract_Failed_SSL_Certificate() Peer Didnt Give Cert");
std::cerr << "pqissl::Extract_Failed_SSL_Certificate() ERROR Peer Didn't Give Us Certificate";
std::cerr << std::endl;
return -1;
}
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::Extract_Failed_SSL_Certificate() Have Peer Cert - Registering");
std::cerr << "pqissl::Extract_Failed_SSL_Certificate() Passing FAILED Cert to AuthSSL for analysis";
std::cerr << std::endl;
// save certificate... (and ip locations)
// false for outgoing....
// we actually connected to remote_addr,
@ -1307,9 +1319,8 @@ int pqissl::accept(SSL *ssl, int fd, struct sockaddr_in foreign_addr) // initiat
/* check whether it is on the same LAN */
peerConnectState details;
mConnMgr->getOwnNetStatus(details);
sameLAN = isSameSubnet(&(remote_addr.sin_addr), &(details.currentlocaladdr.sin_addr));
struct sockaddr_in localaddr = mLinkMgr->getLocalAddress();
sameLAN = isSameSubnet(&(remote_addr.sin_addr), &(localaddr.sin_addr));
{
std::ostringstream out;
@ -1317,7 +1328,7 @@ int pqissl::accept(SSL *ssl, int fd, struct sockaddr_in foreign_addr) // initiat
out << std::endl;
out << "\t\tchecking for same LAN";
out << std::endl;
out << "\t localaddr: " << rs_inet_ntoa(details.currentlocaladdr.sin_addr);
out << "\t localaddr: " << rs_inet_ntoa(localaddr.sin_addr);
out << std::endl;
out << "\t remoteaddr: " << rs_inet_ntoa(remote_addr.sin_addr);
out << std::endl;

View File

@ -37,9 +37,6 @@
#include <map>
#include "pqi/pqi_base.h"
#include "pqi/p3connmgr.h"
#include "pqi/authssl.h"
#define WAITING_NOT 0
@ -85,12 +82,13 @@ class pqissl;
class cert;
class pqissllistener;
class p3LinkMgr;
class pqissl: public NetBinInterface
{
public:
pqissl(pqissllistener *l, PQInterface *parent,
p3ConnectMgr *cm);
p3LinkMgr *lm);
virtual ~pqissl();
// NetInterface
@ -200,7 +198,7 @@ virtual int net_internal_fcntl_nonblock(int fd) { return unix_fcntl_nonblock(fd)
uint32_t mConnectTimeout;
time_t mTimeoutTS;
p3ConnectMgr *mConnMgr;
p3LinkMgr *mLinkMgr;
private:
// ssl only fns.

View File

@ -32,6 +32,8 @@
#include "pqi/pqinetwork.h"
#include "pqi/sslfns.h"
#include "pqi/p3peermgr.h"
#include <errno.h>
#include <openssl/err.h>
@ -56,8 +58,8 @@ const int pqissllistenzone = 49787;
*/
pqissllistenbase::pqissllistenbase(struct sockaddr_in addr, p3ConnectMgr *cm)
:laddr(addr), active(false), mConnMgr(cm)
pqissllistenbase::pqissllistenbase(struct sockaddr_in addr, p3PeerMgr *pm)
:laddr(addr), active(false), mPeerMgr(pm)
{
if (!(AuthSSL::getAuthSSL()-> active())) {
@ -504,11 +506,17 @@ int pqissllistenbase::Extract_Failed_SSL_Certificate(SSL *ssl, struct sockaddr_
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone,
"pqissllistenbase::Extract_Failed_SSL_Certificate()");
std::cerr << "pqissllistenbase::Extract_Failed_SSL_Certificate() FAILED CONNECTION due to security!";
std::cerr << std::endl;
// Get the Peer Certificate....
X509 *peercert = SSL_get_peer_certificate(ssl);
if (peercert == NULL)
{
std::cerr << "pqissllistenbase::Extract_Failed_SSL_Certificate() ERROR, Peer didn't give Cert!";
std::cerr << std::endl;
pqioutput(PQL_WARNING, pqissllistenzone,
"pqissllistenbase::Extract_Failed_SSL_Certificate() Peer Didnt Give Cert");
return -1;
@ -517,6 +525,9 @@ int pqissllistenbase::Extract_Failed_SSL_Certificate(SSL *ssl, struct sockaddr_
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone,
"pqissllistenbase::Extract_Failed_SSL_Certificate() Have Peer Cert - Registering");
std::cerr << "pqissllistenbase::Extract_Failed_SSL_Certificate() Passing Cert to AuthSSL() for analysis";
std::cerr << std::endl;
// save certificate... (and ip locations)
// false for outgoing....
AuthSSL::getAuthSSL()->FailedCertificate(peercert, true);
@ -562,8 +573,8 @@ int pqissllistenbase::continueaccepts()
*
*/
pqissllistener::pqissllistener(struct sockaddr_in addr, p3ConnectMgr *cm)
:pqissllistenbase(addr, cm)
pqissllistener::pqissllistener(struct sockaddr_in addr, p3PeerMgr *lm)
:pqissllistenbase(addr, lm)
{
return;
}
@ -729,8 +740,8 @@ int pqissllistener::completeConnection(int fd, SSL *ssl, struct sockaddr_in &rem
AuthSSL::getAuthSSL()->CheckCertificate(newPeerId, peercert);
/* now need to get GPG id too */
std::string pgpid = getX509CNString(peercert->cert_info->issuer);
mConnMgr->addFriend(newPeerId, pgpid);
std::string pgpid = getX509CNString(peercert->cert_info->issuer);
mPeerMgr->addFriend(newPeerId, pgpid);
X509_free(peercert);
return -1;

View File

@ -45,13 +45,14 @@
*/
class pqissl;
class p3PeerMgr;
class pqissllistenbase: public pqilistener
{
public:
pqissllistenbase(struct sockaddr_in addr, p3ConnectMgr *cm);
pqissllistenbase(struct sockaddr_in addr, p3PeerMgr *pm);
virtual ~pqissllistenbase();
/*************************************/
@ -88,7 +89,7 @@ int Extract_Failed_SSL_Certificate(SSL *ssl, struct sockaddr_in *inaddr);
protected:
p3ConnectMgr *mConnMgr;
p3PeerMgr *mPeerMgr;
};
@ -97,7 +98,7 @@ class pqissllistener: public pqissllistenbase
{
public:
pqissllistener(struct sockaddr_in addr, p3ConnectMgr *cm);
pqissllistener(struct sockaddr_in addr, p3PeerMgr *pm);
virtual ~pqissllistener();
int addlistenaddr(std::string id, pqissl *acc);

View File

@ -53,7 +53,7 @@ const int pqipersongrpzone = 354;
pqilistener * pqisslpersongrp::createListener(struct sockaddr_in laddr)
{
pqilistener *listener = new pqissllistener(laddr, mConnMgr);
pqilistener *listener = new pqissllistener(laddr, mPeerMgr);
return listener;
}
@ -66,7 +66,7 @@ pqiperson * pqisslpersongrp::createPerson(std::string id, pqilistener *listener)
}
pqiperson *pqip = new pqiperson(id, this);
pqissl *pqis = new pqissl((pqissllistener *) listener, pqip, mConnMgr);
pqissl *pqis = new pqissl((pqissllistener *) listener, pqip, mLinkMgr);
/* construct the serialiser ....
* Needs:
@ -85,7 +85,7 @@ pqiperson * pqisslpersongrp::createPerson(std::string id, pqilistener *listener)
pqip -> addChildInterface(PQI_CONNECT_TCP, pqisc);
#ifndef PQI_DISABLE_TUNNEL
pqissltunnel *pqitun = new pqissltunnel(pqip, mConnMgr);
pqissltunnel *pqitun = new pqissltunnel(pqip, mLinkMgr);
RsSerialiser *rss3 = new RsSerialiser();
rss3->addSerialType(new RsFileItemSerialiser());
@ -96,18 +96,18 @@ pqiperson * pqisslpersongrp::createPerson(std::string id, pqilistener *listener)
#endif
#ifndef PQI_DISABLE_UDP
pqissludp *pqius = new pqissludp(pqip, mConnMgr);
pqissludp *pqius = new pqissludp(pqip, mLinkMgr);
RsSerialiser *rss2 = new RsSerialiser();
rss2->addSerialType(new RsFileItemSerialiser());
rss2->addSerialType(new RsCacheItemSerialiser());
rss2->addSerialType(new RsServiceSerialiser());
RsSerialiser *rss2 = new RsSerialiser();
rss2->addSerialType(new RsFileItemSerialiser());
rss2->addSerialType(new RsCacheItemSerialiser());
rss2->addSerialType(new RsServiceSerialiser());
pqiconnect *pqiusc = new pqiconnect(rss2, pqius);
pqiconnect *pqiusc = new pqiconnect(rss2, pqius);
// add a ssl + proxy interface.
// Add Proxy First.
pqip -> addChildInterface(PQI_CONNECT_UDP, pqiusc);
// add a ssl + proxy interface.
// Add Proxy First.
pqip -> addChildInterface(PQI_CONNECT_UDP, pqiusc);
#endif
return pqip;

View File

@ -30,11 +30,13 @@
#include "pqi/pqipersongrp.h"
class p3PeerMgr;
class pqisslpersongrp: public pqipersongrp
{
public:
pqisslpersongrp(SecurityPolicy *pol, unsigned long flags)
:pqipersongrp(pol, flags) { return; }
pqisslpersongrp(SecurityPolicy *pol, unsigned long flags, p3PeerMgr *pm)
:pqipersongrp(pol, flags), mPeerMgr(pm) { return; }
protected:
@ -42,6 +44,10 @@ class pqisslpersongrp: public pqipersongrp
virtual pqilistener *createListener(struct sockaddr_in laddr);
virtual pqiperson *createPerson(std::string id, pqilistener *listener);
/********* FUNCTIONS to OVERLOAD for specialisation ********/
private:
p3PeerMgr *mPeerMgr;
};

View File

@ -29,6 +29,7 @@
#include "pqi/pqissltunnel.h"
#include "pqi/pqinetwork.h"
#include "pqi/p3linkmgr.h"
//#include "services/p3tunnel.h"
@ -90,8 +91,8 @@ const int pqisslzone = 37714;
*
*/
pqissltunnel::pqissltunnel(PQInterface *parent, p3ConnectMgr *cm, p3tunnel *p3t)
:NetBinInterface(parent, parent->PeerId()), mConnMgr(cm)
pqissltunnel::pqissltunnel(PQInterface *parent, p3LinkMgr *cm, p3tunnel *p3t)
:NetBinInterface(parent, parent->PeerId()), mLinkMgr(cm)
{
active = false;
waiting = TUNNEL_WAITING_NOT;
@ -277,7 +278,7 @@ int pqissltunnel::tick()
std::cerr << "pqissltunnel::tick() attempt to connect through a normal tcp or udp connection." << std::endl;
#endif
last_normal_connection_attempt_time = time(NULL);
mConnMgr->retryConnect(parent()->PeerId());
mLinkMgr->retryConnect(parent()->PeerId());
}
if (active && ((time(NULL) - last_ping_send_time) > TUNNEL_REPEAT_PING_TIME)) {
@ -378,7 +379,7 @@ void pqissltunnel::spam_handshake()
std::cerr << "pqissltunnel::spam_handshake() starting to spam handshake tunnel packet." << std::endl;
#endif
std::list<std::string> peers;
mConnMgr->getOnlineList(peers);
mLinkMgr->getOnlineList(peers);
std::list<std::string>::iterator it = peers.begin();
while (it != peers.end()) {
//send a handshake to the destination through the relay
@ -424,14 +425,14 @@ void pqissltunnel::IncommingHanshakePacket(std::string incRelayPeerId) {
last_packet_time = time(NULL);
std::string message = "pqissltunnel::IncommingHanshakePacket() mConnMgr->isOnline(parent()->PeerId() : ";
if (mConnMgr->isOnline(parent()->PeerId())) {
if (mLinkMgr->isOnline(parent()->PeerId())) {
message += "true";
} else {
message += "false";
}
rslog(RSL_DEBUG_BASIC, pqisslzone, message);
if (active || mConnMgr->isOnline(parent()->PeerId())) {
if (active || mLinkMgr->isOnline(parent()->PeerId())) {
//connection is already active, or peer is already online don't do nothing
return;
}
@ -549,7 +550,7 @@ bool pqissltunnel::moretoread()
bool pqissltunnel::cansend()
{
if (!mConnMgr->isOnline(relayPeerId)) {
if (!mLinkMgr->isOnline(relayPeerId)) {
reset();
return false;
}

View File

@ -36,8 +36,6 @@
#include "pqi/pqi_base.h"
#include "pqi/p3connmgr.h"
#include "services/p3tunnel.h"
#include "pqi/authssl.h"
@ -66,6 +64,8 @@ class cert;
class pqissltunnellistener;
class p3LinkMgr;
struct data_with_length {
int length;
void *data;
@ -74,7 +74,7 @@ struct data_with_length {
class pqissltunnel: public NetBinInterface
{
public:
pqissltunnel(PQInterface *parent, p3ConnectMgr *cm, p3tunnel *p3t);
pqissltunnel(PQInterface *parent, p3LinkMgr *cm, p3tunnel *p3t);
virtual ~pqissltunnel();
// NetInterface
@ -129,7 +129,7 @@ private:
/* Need Certificate specific functions here! */
time_t mConnectTS;
p3ConnectMgr *mConnMgr;
p3LinkMgr *mLinkMgr;
p3tunnel *mP3tunnel;

View File

@ -41,6 +41,8 @@
#include "util/rsdebug.h"
#include "util/rsnet.h"
#include "pqi/p3linkmgr.h"
const int pqissludpzone = 3144;
/* a final timeout, to ensure this never blocks completely
@ -52,8 +54,8 @@ static const uint32_t PQI_SSLUDP_DEF_CONN_PERIOD = 300; /* 5 minutes? */
/********** PQI SSL UDP STUFF **************************************/
pqissludp::pqissludp(PQInterface *parent, p3ConnectMgr *cm)
:pqissl(NULL, parent, cm), tou_bio(NULL),
pqissludp::pqissludp(PQInterface *parent, p3LinkMgr *lm)
:pqissl(NULL, parent, lm), tou_bio(NULL),
listen_checktime(0), mConnectPeriod(PQI_SSLUDP_DEF_CONN_PERIOD)
{
sockaddr_clear(&remote_addr);
@ -86,6 +88,8 @@ pqissludp::~pqissludp()
int pqissludp::reset()
{
/* reset for next time.*/
mConnectFlags = 0;
mConnectPeriod = PQI_SSLUDP_DEF_CONN_PERIOD;
return pqissl::reset();
}
@ -101,7 +105,26 @@ int pqissludp::attach()
{
// IN THE IMPROVED TOU LIBRARY, we need to be careful with the tou_socket PARAMETERS.
// For now, this should do!
sockfd = tou_socket(0,TOU_RECEIVER_TYPE_UDPPEER,0);
sockfd = -1;
if (mConnectFlags & RS_CB_FLAG_MODE_UDP_DIRECT)
{
sockfd = tou_socket(RSUDP_TOU_RECVER_DIRECT_IDX,TOU_RECEIVER_TYPE_UDPPEER,0);
}
else if (mConnectFlags & RS_CB_FLAG_MODE_UDP_PROXY)
{
sockfd = tou_socket(RSUDP_TOU_RECVER_PROXY_IDX,TOU_RECEIVER_TYPE_UDPPEER,0);
}
else if (mConnectFlags & RS_CB_FLAG_MODE_UDP_RELAY)
{
sockfd = tou_socket(RSUDP_TOU_RECVER_RELAY_IDX,TOU_RECEIVER_TYPE_UDPRELAY,0);
}
else
{
std::cerr << "pqissludp::attach() ERROR unknown Connect Mode" << std::endl;
sockfd = -1;
}
if (0 > sockfd)
{
rslog(RSL_WARNING, pqissludpzone,
@ -129,14 +152,25 @@ int pqissludp::Initiate_Connection()
"pqissludp::Initiate_Connection() Attempting Outgoing Connection....");
/* decide if we're active or passive */
if (PeerId() < mConnMgr->getOwnId())
if (mConnectFlags & RS_CB_FLAG_ORDER_ACTIVE)
{
sslmode = PQISSL_ACTIVE;
}
else
else if (mConnectFlags & RS_CB_FLAG_ORDER_PASSIVE)
{
sslmode = PQISSL_PASSIVE;
}
else // likely UNSPEC - use old method to decide.
{
if (PeerId() < mLinkMgr->getOwnId())
{
sslmode = PQISSL_ACTIVE;
}
else
{
sslmode = PQISSL_PASSIVE;
}
}
if (waiting != WAITING_DELAY)
{
@ -192,8 +226,21 @@ int pqissludp::Initiate_Connection()
//std::cerr << " Connect Period is:" << mConnectPeriod << std::endl;
/* <===================== UDP Difference *******************/
if (0 != (err = tou_connect(sockfd, (struct sockaddr *) &remote_addr,
sizeof(remote_addr), mConnectPeriod)))
if (mConnectFlags & RS_CB_FLAG_MODE_UDP_DIRECT)
{
err = tou_connect(sockfd, (struct sockaddr *) &remote_addr, sizeof(remote_addr), mConnectPeriod);
}
else if (mConnectFlags & RS_CB_FLAG_MODE_UDP_PROXY)
{
err = tou_connect(sockfd, (struct sockaddr *) &remote_addr, sizeof(remote_addr), mConnectPeriod);
}
else if (mConnectFlags & RS_CB_FLAG_MODE_UDP_RELAY)
{
tou_connect_via_relay(sockfd, &(mConnectSrcAddr), &(mConnectProxyAddr), &(remote_addr));
}
if (0 != err)
/* <===================== UDP Difference *******************/
{
int tou_err = tou_errno(sockfd);
@ -417,9 +464,58 @@ bool pqissludp::connect_parameter(uint32_t type, uint32_t value)
mConnectPeriod = value;
return true;
}
else if (type == NET_PARAM_CONNECT_FLAGS)
{
std::ostringstream out;
out << "pqissludp::connect_parameter() Peer: " << PeerId() << " FLAGS: " << value;
rslog(RSL_WARNING, pqissludpzone, out.str());
mConnectFlags = value;
return true;
}
else if (type == NET_PARAM_CONNECT_BANDWIDTH)
{
std::ostringstream out;
out << "pqissludp::connect_parameter() Peer: " << PeerId() << " BANDWIDTH: " << value;
rslog(RSL_WARNING, pqissludpzone, out.str());
mConnectFlags = value;
return true;
}
return pqissl::connect_parameter(type, value);
}
bool pqissludp::connect_additional_address(uint32_t type, struct sockaddr_in *addr)
{
struct sockaddr_in mConnectProxyAddr;
struct sockaddr_in mConnectSrcAddr;
if (type == NET_PARAM_CONNECT_PROXY)
{
std::ostringstream out;
out << "pqissludp::connect_parameter() Peer: " << PeerId() << " PROXYADDR: ";
out << rs_inet_ntoa(addr->sin_addr) << ":" << ntohs(addr->sin_port);
rslog(RSL_WARNING, pqissludpzone, out.str());
mConnectProxyAddr = *addr;
std::cerr << out.str() << std::endl;
return true;
}
else if (type == NET_PARAM_CONNECT_SOURCE)
{
std::ostringstream out;
out << "pqissludp::connect_parameter() Peer: " << PeerId() << " SRCADDR: ";
out << rs_inet_ntoa(addr->sin_addr) << ":" << ntohs(addr->sin_port);
rslog(RSL_WARNING, pqissludpzone, out.str());
mConnectSrcAddr = *addr;
std::cerr << out.str() << std::endl;
return true;
}
return pqissl::connect_additional_address(type, addr);
}
/********** PQI STREAMER OVERLOADING *********************************/
bool pqissludp::moretoread()

View File

@ -55,7 +55,7 @@ class cert;
class pqissludp: public pqissl
{
public:
pqissludp(PQInterface *parent, p3ConnectMgr *cm);
pqissludp(PQInterface *parent, p3LinkMgr *lm);
virtual ~pqissludp();
@ -67,6 +67,7 @@ virtual int tick();
virtual int reset();
virtual bool connect_parameter(uint32_t type, uint32_t value);
virtual bool connect_additional_address(uint32_t type, struct sockaddr_in *addr);
// BinInterface.
// These are reimplemented.
@ -99,6 +100,11 @@ private:
long listen_checktime;
uint32_t mConnectPeriod;
uint32_t mConnectFlags;
uint32_t mConnectBandwidth;
struct sockaddr_in mConnectProxyAddr;
struct sockaddr_in mConnectSrcAddr;
};
#endif // MRK_PQI_SSL_UDP_HEADER

View File

@ -0,0 +1,242 @@
#ifndef RETROSHARE_CONFIG_GUI_INTERFACE_H
#define RETROSHARE_CONFIG_GUI_INTERFACE_H
/*
* libretroshare/src/retroshare: rsconfig.h
*
* RetroShare C++ Interface.
*
* 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".
*
*/
#include <inttypes.h>
#include <string>
#include <list>
/* The New Config Interface Class */
class RsServerConfig;
extern RsServerConfig *rsConfig;
#define RSNET_NETWORK_UNKNOWN 1
#define RSNET_NETWORK_RESTARTING 2
#define RSNET_NETWORK_OFFLINE 3
#define RSNET_NETWORK_LOCALNET 4
#define RSNET_NETWORK_BEHINDNAT 5
#define RSNET_NETWORK_EXTERNALIP 6
// WHAT TYPE OF FIREWALL?
#define RSNET_NATTYPE_NONE 1
#define RSNET_NATTYPE_UNKNOWN 2
#define RSNET_NATTYPE_SYMMETRIC 3
#define RSNET_NATTYPE_DETERM_SYM 4
#define RSNET_NATTYPE_RESTRICTED_CONE 5
#define RSNET_NATTYPE_FULL_CONE 6
#define RSNET_NATTYPE_OTHER 7
// WHAT TYPE OF HOLE?
#define RSNET_NATHOLE_UNKNOWN 0
#define RSNET_NATHOLE_NONE 1
#define RSNET_NATHOLE_UPNP 2
#define RSNET_NATHOLE_NATPMP 3
#define RSNET_NATHOLE_FORWARDED 4
// Types of Connections.
#define RSNET_CONNECT_NONE 0x0000
#define RSNET_CONNECT_ACCEPT_TCP 0x0001
#define RSNET_CONNECT_OUTGOING_TCP 0x0002
#define RSNET_CONNECT_DIRECT_UDP 0x0100
#define RSNET_CONNECT_PROXY_UDP 0x0200
#define RSNET_CONNECT_RELAY_UDP 0x0400
// net state (good, okay, bad)
// BAD. (RED)
#define RSNET_NETSTATE_BAD_UNKNOWN 1
#define RSNET_NETSTATE_BAD_OFFLINE 2
#define RSNET_NETSTATE_BAD_NATSYM 3
#define RSNET_NETSTATE_BAD_NODHT_NAT 4
// CAUTION. (ORANGE)
#define RSNET_NETSTATE_WARNING_RESTART 5
#define RSNET_NETSTATE_WARNING_NATTED 6
#define RSNET_NETSTATE_WARNING_NODHT 7
// GOOD (GREEN)
// NAT with forwarded port, or EXT port.
#define RSNET_NETSTATE_GOOD 8
// ADVANCED MODE (BLUE)
// If the user knows what they are doing... we cannot confirm this.
#define RSNET_NETSTATE_ADV_FORWARD 9
#define RSNET_NETSTATE_ADV_DARK_FORWARD 10
/* matched to the uPnP states */
#define UPNP_STATE_UNINITIALISED 0
#define UPNP_STATE_UNAVAILABILE 1
#define UPNP_STATE_READY 2
#define UPNP_STATE_FAILED_TCP 3
#define UPNP_STATE_FAILED_UDP 4
#define UPNP_STATE_ACTIVE 5
/************************** Indicate How experienced the RsUser is... based on Friends / Firewall status ******/
#define RSCONFIG_USER_LEVEL_NEW 0x0001 /* no friends */
#define RSCONFIG_USER_LEVEL_BASIC 0x0002 /* no connections */
#define RSCONFIG_USER_LEVEL_CASUAL 0x0003 /* firewalled */
#define RSCONFIG_USER_LEVEL_POWER 0x0004 /* good! */
#define RSCONFIG_USER_LEVEL_OVERRIDE 0x0005 /* forced to POWER level */
class RsConfigStartup
{
public:
RsConfigStartup()
{
promptAtBoot = 1;
}
int promptAtBoot; /* popup the password prompt */
};
class RsConfigDataRates
{
public:
RsConfigDataRates()
{
maxDownloadDataRate = 0;
maxUploadDataRate = 0;
maxIndivDataRate = 0;
}
int maxDownloadDataRate; /* kb */
int maxUploadDataRate; /* kb */
int maxIndivDataRate; /* kb */
};
class RsConfigNetStatus
{
public:
RsConfigNetStatus()
{
localPort = extPort = 0 ;
firewalled = forwardPort = false ;
DHTActive = uPnPActive = netLocalOk = netUpnpOk = netDhtOk = netStunOk = netExtraAddressOk = false ;
uPnPState = DHTPeers = 0 ;
}
std::string ownId;
std::string ownName;
std::string localAddr;
int localPort;
std::string extAddr;
int extPort;
std::string extName;
bool firewalled;
bool forwardPort;
/* older data types */
bool DHTActive;
bool uPnPActive;
int uPnPState;
int DHTPeers;
/* Flags for Network Status */
bool netLocalOk; /* That we've talked to someone! */
bool netUpnpOk; /* upnp is enabled and active */
bool netDhtOk; /* response from dht */
bool netStunOk; /* recvd stun / udp packets */
bool netExtraAddressOk; /* recvd ip address with external finder*/
uint32_t netDhtNetSize; /* response from dht */
uint32_t netDhtRsNetSize; /* response from dht */
};
/*********
* This is a new style RsConfig Interface.
* It should contain much of the information for the Options/Config Window.
*
* To start with, I'm going to move the stuff from RsIface::RsConfig into here.
*
*/
class RsServerConfig
{
public:
RsServerConfig() { return; }
virtual ~RsServerConfig() { return; }
/* From RsIface::RsConfig */
// Implemented Only this one!
virtual int getConfigNetStatus(RsConfigNetStatus &status) = 0;
// NOT IMPLEMENTED YET!
//virtual int getConfigStartup(RsConfigStartup &params) = 0;
//virtual int getConfigDataRates(RsConfigDataRates &params) = 0;
/* From RsInit */
// NOT IMPLEMENTED YET!
//virtual std::string RsConfigDirectory() = 0;
//virtual std::string RsConfigKeysDirectory() = 0;
//virtual std::string RsProfileConfigDirectory() = 0;
//virtual bool getStartMinimised() = 0;
//virtual std::string getRetroShareLink() = 0;
//virtual bool getAutoLogin() = 0;
//virtual void setAutoLogin(bool autoLogin) = 0;
//virtual bool RsClearAutoLogin() = 0;
//virtual std::string getRetroshareDataDirectory() = 0;
/* New Stuff */
virtual uint32_t getUserLevel() = 0;
virtual uint32_t getNetState() = 0;
virtual uint32_t getNetworkMode() = 0;
virtual uint32_t getNatTypeMode() = 0;
virtual uint32_t getNatHoleMode() = 0;
virtual uint32_t getConnectModes() = 0;
};
#endif

View File

@ -39,11 +39,38 @@ extern RsDht *rsDht;
//std::ostream &operator<<(std::ostream &out, const RsPhotoDetails &detail);
#define RS_DHT_NETSTART_NETWORKMODE 0x0001
#define RS_DHT_NETSTART_NATTYPE 0x0002
#define RS_DHT_NETSTART_NATHOLE 0x0003
#define RS_DHT_NETSTART_CONNECTMODES 0x0004
#define RS_DHT_NETSTART_NETSTATE 0x0005
#define RSDHT_NETSTART_NETWORKMODE 0x0001
#define RSDHT_NETSTART_NATTYPE 0x0002
#define RSDHT_NETSTART_NATHOLE 0x0003
#define RSDHT_NETSTART_CONNECTMODES 0x0004
#define RSDHT_NETSTART_NETSTATE 0x0005
#define RSDHT_PEERTYPE_ANY 0x0000
#define RSDHT_PEERTYPE_OTHER 0x0001
#define RSDHT_PEERTYPE_FOF 0x0002
#define RSDHT_PEERTYPE_FRIEND 0x0003
#define RSDHT_PEERDHT_NOT_ACTIVE 0x0000
#define RSDHT_PEERDHT_SEARCHING 0x0001
#define RSDHT_PEERDHT_FAILURE 0x0002
#define RSDHT_PEERDHT_OFFLINE 0x0003
#define RSDHT_PEERDHT_UNREACHABLE 0x0004
#define RSDHT_PEERDHT_ONLINE 0x0005
#define RSDHT_PEERCONN_DISCONNECTED 1
#define RSDHT_PEERCONN_UDP_STARTED 2
#define RSDHT_PEERCONN_CONNECTED 3
#define RSDHT_PEERREQ_STOPPED 1
#define RSDHT_PEERREQ_RUNNING 2
#define RSDHT_TOU_MODE_DIRECT 1
#define RSDHT_TOU_MODE_PROXY 2
#define RSDHT_TOU_MODE_RELAY 3
class RsDhtPeer
{
@ -68,6 +95,26 @@ class RsDhtNetPeer
std::string mDhtId;
std::string mRsId;
uint32_t mDhtState;
//connectLogic.
std::string mConnectState;
// connect Status
uint32_t mPeerConnectState;
// connect mode
uint32_t mPeerConnectMode;
bool mExclusiveProxyLock;
std::string mPeerConnectProxyId;
// Req Status.
uint32_t mPeerReqState;
// Peer Cb Mgs.
std::string mCbPeerMsg;
};
class RsDhtRelayEnd

View File

@ -62,11 +62,17 @@ const uint32_t RS_FEED_TYPE_BLOG = 0x0080;
const uint32_t RS_FEED_TYPE_CHAT = 0x0100;
const uint32_t RS_FEED_TYPE_MSG = 0x0200;
const uint32_t RS_FEED_TYPE_FILES = 0x0400;
const uint32_t RS_FEED_TYPE_SECURITY = 0x0800;
const uint32_t RS_FEED_ITEM_PEER_CONNECT = RS_FEED_TYPE_PEER | 0x0001;
const uint32_t RS_FEED_ITEM_PEER_DISCONNECT = RS_FEED_TYPE_PEER | 0x0002;
const uint32_t RS_FEED_ITEM_PEER_NEW = RS_FEED_TYPE_PEER | 0x0003;
const uint32_t RS_FEED_ITEM_PEER_HELLO = RS_FEED_TYPE_PEER | 0x0004;
const uint32_t RS_FEED_ITEM_PEER_HELLO = RS_FEED_TYPE_PEER | 0x0003;
const uint32_t RS_FEED_ITEM_PEER_NEW = RS_FEED_TYPE_PEER | 0x0004;
const uint32_t RS_FEED_ITEM_SEC_CONNECT_ATTEMPT = RS_FEED_TYPE_SECURITY | 0x0001;
const uint32_t RS_FEED_ITEM_SEC_AUTH_DENIED = RS_FEED_TYPE_SECURITY | 0x0002;
const uint32_t RS_FEED_ITEM_SEC_UNKNOWN_IN = RS_FEED_TYPE_SECURITY | 0x0003;
const uint32_t RS_FEED_ITEM_SEC_UNKNOWN_OUT = RS_FEED_TYPE_SECURITY | 0x0004;
const uint32_t RS_FEED_ITEM_CHAN_NEW = RS_FEED_TYPE_CHAN | 0x0001;
const uint32_t RS_FEED_ITEM_CHAN_UPDATE = RS_FEED_TYPE_CHAN | 0x0002;

View File

@ -34,7 +34,7 @@ class RsPluginHandler ;
extern RsPluginHandler *rsPlugins ;
class p3Service ;
class p3ConnectMgr ;
class p3LinkMgr ;
class MainPage ;
class QIcon ;
class QString ;
@ -86,7 +86,7 @@ class RsPluginHandler
virtual const std::string& getLocalCacheDir() const =0;
virtual const std::string& getRemoteCacheDir() const =0;
virtual ftServer *getFileServer() const = 0;
virtual p3ConnectMgr *getConnectMgr() const = 0;
virtual p3LinkMgr *getLinkMgr() const = 0;
};

View File

@ -38,6 +38,9 @@ const int p3facemsgzone = 11453;
#include <sys/time.h>
#include <time.h>
#include "pqi/p3peermgr.h"
#include "pqi/p3netmgr.h"
/****************************************/
/* RsIface Config */
@ -106,18 +109,18 @@ int RsServer::UpdateAllConfig()
config.ownId = AuthSSL::getAuthSSL()->OwnId();
config.ownName = AuthGPG::getAuthGPG()->getGPGOwnName();
peerConnectState pstate;
mConnMgr->getOwnNetStatus(pstate);
peerState pstate;
mPeerMgr->getOwnNetStatus(pstate);
/* ports */
config.localAddr = rs_inet_ntoa(pstate.currentlocaladdr.sin_addr);
config.localPort = ntohs(pstate.currentlocaladdr.sin_port);
config.localAddr = rs_inet_ntoa(pstate.localaddr.sin_addr);
config.localPort = ntohs(pstate.localaddr.sin_port);
config.firewalled = true;
config.forwardPort = true;
config.extAddr = rs_inet_ntoa(pstate.currentserveraddr.sin_addr);
config.extPort = ntohs(pstate.currentserveraddr.sin_port);
config.extAddr = rs_inet_ntoa(pstate.serveraddr.sin_addr);
config.extPort = ntohs(pstate.serveraddr.sin_port);
/* data rates */
config.maxDownloadDataRate = (int) pqih -> getMaxRate(true); /* kb */
@ -128,7 +131,7 @@ int RsServer::UpdateAllConfig()
/* update network configuration */
pqiNetStatus status;
mConnMgr->getNetStatus(status);
mNetMgr->getNetStatus(status);
config.netLocalOk = status.mLocalAddrOk;
config.netUpnpOk = status.mUpnpOk;
@ -141,10 +144,10 @@ int RsServer::UpdateAllConfig()
/* update DHT/UPnP config */
config.uPnPState = mConnMgr->getUPnPState();
config.uPnPActive = mConnMgr->getUPnPEnabled();
config.uPnPState = mNetMgr->getUPnPState();
config.uPnPActive = mNetMgr->getUPnPEnabled();
config.DHTPeers = 20;
config.DHTActive = mConnMgr->getDHTEnabled();
config.DHTActive = mNetMgr->getDHTEnabled();
/* Notify of Changes */
// iface.setChanged(RsIface::Config);
@ -175,7 +178,7 @@ void RsServer::rsGlobalShutDown()
// TODO: cache should also clean up old files
ConfigFinalSave(); // save configuration before exit
mConnMgr->shutdown(); /* Handles UPnP */
mNetMgr->shutdown(); /* Handles UPnP */
join();
ftserver->StopThreads();

View File

@ -35,6 +35,11 @@
#include <sys/time.h>
#include <time.h>
#include "pqi/p3peermgr.h"
#include "pqi/p3linkmgr.h"
#include "pqi/p3netmgr.h"
/****
#define DEBUG_TICK 1
****/
@ -44,7 +49,9 @@ RsServer::RsServer(RsIface &i, NotifyBase &callback)
{
ftserver = NULL;
mConnMgr = NULL;
mPeerMgr = NULL;
mLinkMgr = NULL;
mNetMgr = NULL;
pqih = NULL;
@ -144,8 +151,10 @@ void RsServer::run()
unlockRsCore();
/* tick the connection Manager */
mConnMgr->tick();
/* tick the Managers */
mPeerMgr->tick();
mLinkMgr->tick();
mNetMgr->tick();
/******************************** RUN SERVER *****************/
/* adjust tick rate depending on whether there is more.

View File

@ -31,7 +31,6 @@
//#include "pqi/pqissl.h"
#include "pqi/p3cfgmgr.h"
#include "pqi/p3connmgr.h"
#include "pqi/pqipersongrp.h"
#include "retroshare/rsiface.h"
@ -46,6 +45,11 @@
#include "services/p3channels.h"
#include "services/p3forums.h"
class p3PeerMgrIMPL;
class p3LinkMgrIMPL;
class p3NetMgrIMPL;
/* The Main Interface Class - for controlling the server */
/* The init functions are actually Defined in p3face-startup.cc
@ -150,7 +154,9 @@ class RsServer: public RsControl, public RsThread
//filedexserver *server;
ftServer *ftserver;
p3ConnectMgr *mConnMgr;
p3PeerMgrIMPL *mPeerMgr;
p3LinkMgrIMPL *mLinkMgr;
p3NetMgrIMPL *mNetMgr;
pqipersongrp *pqih;

View File

@ -25,7 +25,11 @@
#include "rsserver/p3peers.h"
#include "rsserver/p3face.h"
#include "pqi/p3connmgr.h"
#include "pqi/p3linkmgr.h"
#include "pqi/p3peermgr.h"
#include "pqi/p3netmgr.h"
#include "pqi/authssl.h"
#include "pqi/authgpg.h"
#include "retroshare/rsinit.h"
@ -123,8 +127,8 @@ std::string RsPeerLastConnectString(uint32_t lastConnect)
}
p3Peers::p3Peers(p3ConnectMgr *cm)
:mConnMgr(cm)
p3Peers::p3Peers(p3LinkMgr *lm, p3PeerMgr *pm, p3NetMgr *nm)
:mLinkMgr(lm), mPeerMgr(pm), mNetMgr(nm)
{
return;
}
@ -176,7 +180,7 @@ bool p3Peers::getOnlineList(std::list<std::string> &ids)
#endif
/* get from mConnectMgr */
mConnMgr->getOnlineList(ids);
mLinkMgr->getOnlineList(ids);
return true;
}
@ -187,7 +191,7 @@ bool p3Peers::getFriendList(std::list<std::string> &ids)
#endif
/* get from mConnectMgr */
mConnMgr->getFriendList(ids);
mLinkMgr->getFriendList(ids);
return true;
}
@ -208,9 +212,15 @@ bool p3Peers::getPeerCount (unsigned int *pnFriendCount, unsigned int *pnOnlineC
#ifdef P3PEERS_DEBUG
std::cerr << "p3Peers::getPeerCount()" << std::endl;
#endif
/* get from mConnectMgr */
return mConnMgr->getPeerCount(pnFriendCount, pnOnlineCount, ssl);
// This is no longer accurate!
*pnFriendCount = mLinkMgr->getFriendCount();
*pnOnlineCount = mLinkMgr->getOnlineCount();
/* get from mConnectMgr */
//return mConnMgr->getPeerCount(pnFriendCount, pnOnlineCount, ssl);
return true;
}
bool p3Peers::isOnline(const std::string &id)
@ -221,7 +231,7 @@ bool p3Peers::isOnline(const std::string &id)
/* get from mConnectMgr */
peerConnectState state;
if (mConnMgr->getFriendNetStatus(id, state) &&
if (mLinkMgr->getFriendNetStatus(id, state) &&
(state.state & RS_PEER_S_CONNECTED))
{
return true;
@ -236,23 +246,9 @@ bool p3Peers::isFriend(const std::string &ssl_id)
#endif
/* get from mConnectMgr */
return mConnMgr->isFriend(ssl_id);
return mPeerMgr->isFriend(ssl_id);
}
#if 0
static struct sockaddr_in getPreferredAddress( const struct sockaddr_in& addr1,time_t ts1,
const struct sockaddr_in& addr2,time_t ts2,
const struct sockaddr_in& addr3,time_t ts3)
{
time_t ts = ts1 ;
struct sockaddr_in addr = addr1 ;
if(ts2 > ts && strcmp(rs_inet_ntoa(addr2.sin_addr),"0.0.0.0")) { ts = ts2 ; addr = addr2 ; }
if(ts3 > ts && strcmp(rs_inet_ntoa(addr3.sin_addr),"0.0.0.0")) { ts = ts3 ; addr = addr3 ; }
return addr ;
}
#endif
bool p3Peers::getPeerDetails(const std::string &id, RsPeerDetails &d)
{
@ -261,8 +257,8 @@ bool p3Peers::getPeerDetails(const std::string &id, RsPeerDetails &d)
#endif
//first, check if it's a gpg or a ssl id.
std::string sOwnId = AuthSSL::getAuthSSL()->OwnId();
peerConnectState pcs;
if (id != sOwnId && !mConnMgr->getFriendNetStatus(id, pcs)) {
peerState ps;
if (id != sOwnId && !mPeerMgr->getFriendNetStatus(id, ps)) {
//assume is not SSL, because every ssl_id has got a friend correspondance in mConnMgr
#ifdef P3PEERS_DEBUG
std::cerr << "p3Peers::getPeerDetails() got a gpg id and is returning GPG details only for id : " << id << std::endl;
@ -275,62 +271,51 @@ bool p3Peers::getPeerDetails(const std::string &id, RsPeerDetails &d)
#endif
if (id == sOwnId) {
mConnMgr->getOwnNetStatus(pcs);
pcs.gpg_id = AuthGPG::getAuthGPG()->getGPGOwnId();
mPeerMgr->getOwnNetStatus(ps);
ps.gpg_id = AuthGPG::getAuthGPG()->getGPGOwnId();
}
/* get from gpg (first), to fill in the sign and trust details */
/* don't retrun now, we've got fill in the ssl and connection info */
this->getGPGDetails(pcs.gpg_id, d);
this->getGPGDetails(ps.gpg_id, d);
d.isOnlyGPGdetail = false;
//get the ssl details
d.id = id;
d.location = pcs.location;
d.location = ps.location;
/* generate */
d.authcode = "AUTHCODE";
/* fill from pcs */
d.localAddr = rs_inet_ntoa(pcs.currentlocaladdr.sin_addr);
d.localPort = ntohs(pcs.currentlocaladdr.sin_port);
d.extAddr = rs_inet_ntoa(pcs.currentserveraddr.sin_addr);
d.extPort = ntohs(pcs.currentserveraddr.sin_port);
d.dyndns = pcs.dyndns;
d.lastConnect = pcs.lastcontact;
d.localAddr = rs_inet_ntoa(ps.localaddr.sin_addr);
d.localPort = ntohs(ps.localaddr.sin_port);
d.extAddr = rs_inet_ntoa(ps.serveraddr.sin_addr);
d.extPort = ntohs(ps.serveraddr.sin_port);
d.dyndns = ps.dyndns;
d.lastConnect = ps.lastcontact;
d.connectPeriod = 0;
std::list<pqiIpAddress>::iterator it;
for(it = pcs.ipAddrs.mLocal.mAddrs.begin();
it != pcs.ipAddrs.mLocal.mAddrs.end(); it++)
for(it = ps.ipAddrs.mLocal.mAddrs.begin();
it != ps.ipAddrs.mLocal.mAddrs.end(); it++)
{
std::ostringstream toto;
toto << ntohs(it->mAddr.sin_port) << " " << (time(NULL) - it->mSeenTime) << " sec";
d.ipAddressList.push_back("L:" + std::string(rs_inet_ntoa(it->mAddr.sin_addr)) + ":" + toto.str());
}
for(it = pcs.ipAddrs.mExt.mAddrs.begin();
it != pcs.ipAddrs.mExt.mAddrs.end(); it++)
for(it = ps.ipAddrs.mExt.mAddrs.begin();
it != ps.ipAddrs.mExt.mAddrs.end(); it++)
{
std::ostringstream toto;
toto << ntohs(it->mAddr.sin_port) << " " << (time(NULL) - it->mSeenTime) << " sec";
d.ipAddressList.push_back("E:" + std::string(rs_inet_ntoa(it->mAddr.sin_addr)) + ":" + toto.str());
}
/* Translate */
d.state = 0;
if (pcs.state & RS_PEER_S_FRIEND)
d.state |= RS_PEER_STATE_FRIEND;
if (pcs.state & RS_PEER_S_ONLINE)
d.state |= RS_PEER_STATE_ONLINE;
if (pcs.state & RS_PEER_S_CONNECTED)
d.state |= RS_PEER_STATE_CONNECTED;
if (pcs.state & RS_PEER_S_UNREACHABLE)
d.state |= RS_PEER_STATE_UNREACHABLE;
switch(pcs.netMode & RS_NET_MODE_ACTUAL)
switch(ps.netMode & RS_NET_MODE_ACTUAL)
{
case RS_NET_MODE_EXT:
d.netMode = RS_NETMODE_EXT;
@ -347,12 +332,13 @@ bool p3Peers::getPeerDetails(const std::string &id, RsPeerDetails &d)
d.netMode = RS_NETMODE_UNREACHABLE;
break;
}
if (pcs.netMode & RS_NET_MODE_TRY_EXT)
if (ps.netMode & RS_NET_MODE_TRY_EXT)
{
d.tryNetMode = RS_NETMODE_EXT;
}
else if (pcs.netMode & RS_NET_MODE_TRY_UPNP)
else if (ps.netMode & RS_NET_MODE_TRY_UPNP)
{
d.tryNetMode = RS_NETMODE_UPNP;
}
@ -360,17 +346,44 @@ bool p3Peers::getPeerDetails(const std::string &id, RsPeerDetails &d)
{
d.tryNetMode = RS_NETMODE_UDP;
}
d.visState = 0;
if (!(pcs.visState & RS_VIS_STATE_NODISC))
if (!(ps.visState & RS_VIS_STATE_NODISC))
{
d.visState |= RS_VS_DISC_ON;
}
if (!(pcs.visState & RS_VIS_STATE_NODHT))
if (!(ps.visState & RS_VIS_STATE_NODHT))
{
d.visState |= RS_VS_DHT_ON;
}
/* Translate */
peerConnectState pcs;
if (!mLinkMgr->getFriendNetStatus(id, pcs))
{
std::cerr << "p3Peers::getPeerDetails() ERROR No Link Information : " << id << std::endl;
return true;
}
#ifdef P3PEERS_DEBUG
std::cerr << "p3Peers::getPeerDetails() got a SSL id and is returning SSL and GPG details for id : " << id << std::endl;
#endif
d.state = 0;
if (pcs.state & RS_PEER_S_FRIEND)
d.state |= RS_PEER_STATE_FRIEND;
if (pcs.state & RS_PEER_S_ONLINE)
d.state |= RS_PEER_STATE_ONLINE;
if (pcs.state & RS_PEER_S_CONNECTED)
d.state |= RS_PEER_STATE_CONNECTED;
if (pcs.state & RS_PEER_S_UNREACHABLE)
d.state |= RS_PEER_STATE_UNREACHABLE;
/* Finally determine AutoConnect Status */
@ -443,8 +456,8 @@ std::string p3Peers::getPeerName(const std::string &ssl_or_gpg_id)
if (ssl_or_gpg_id == AuthSSL::getAuthSSL()->OwnId()) {
return AuthGPG::getAuthGPG()->getGPGOwnName();
}
peerConnectState pcs;
if (mConnMgr->getFriendNetStatus(ssl_or_gpg_id, pcs)) {
peerState pcs;
if (mPeerMgr->getFriendNetStatus(ssl_or_gpg_id, pcs)) {
#ifdef P3PEERS_DEBUG
std::cerr << "p3Peers::getPeerName() got a ssl id. Name is : " << pcs.name << std::endl;
#endif
@ -507,14 +520,14 @@ bool p3Peers::getSSLChildListOfGPGId(const std::string &gpg_id, std::list<std::s
}
//let's roll throush the friends
std::list<std::string> friendsIds;
mConnMgr->getFriendList(friendsIds);
peerConnectState pcs;
mLinkMgr->getFriendList(friendsIds);
peerState pcs;
for (std::list<std::string>::iterator it = friendsIds.begin(); it != friendsIds.end(); it++)
{
#ifdef P3PEERS_DEBUG
std::cerr << "p3Peers::getSSLChildListOfGPGId() iterating over friends id : " << *it << std::endl;
#endif
if (mConnMgr->getFriendNetStatus(*it, pcs) && pcs.gpg_id == gpg_id) {
if (mPeerMgr->getFriendNetStatus(*it, pcs) && pcs.gpg_id == gpg_id) {
#ifdef P3PEERS_DEBUG
std::cerr << "p3Peers::getSSLChildListOfGPGId() adding ssl id : " << pcs.id << std::endl;
#endif
@ -528,16 +541,16 @@ bool p3Peers::cleanUnusedLocations()
{
// Obtain all current locations of each GPG friend.
//
std::map<std::string,std::list<peerConnectState> > friends_info ;
std::map<std::string,std::list<peerState> > friends_info ;
std::list<std::string> friendSSLIds ;
mConnMgr->getFriendList(friendSSLIds);
mLinkMgr->getFriendList(friendSSLIds);
for(std::list<std::string>::const_iterator it(friendSSLIds.begin());it!=friendSSLIds.end();++it)
{
peerConnectState pcs;
peerState pcs;
if(mConnMgr->getFriendNetStatus(*it, pcs))
if(mPeerMgr->getFriendNetStatus(*it, pcs))
friends_info[pcs.gpg_id].push_back(pcs) ;
}
@ -549,20 +562,20 @@ bool p3Peers::cleanUnusedLocations()
std::list<std::string> locations_to_remove ;
for(std::map<std::string,std::list<peerConnectState> >::iterator it(friends_info.begin());it!=friends_info.end();++it)
for(std::map<std::string,std::list<peerState> >::iterator it(friends_info.begin());it!=friends_info.end();++it)
{
std::list<peerConnectState>& locations_list(it->second) ;
std::list<peerState>& locations_list(it->second) ;
int size = locations_list.size() ;
std::cerr << " GPG id: " << it->first << std::endl ;
for(std::list<peerConnectState>::const_iterator itloc(locations_list.begin());itloc!=locations_list.end();++itloc)
for(std::list<peerState>::const_iterator itloc(locations_list.begin());itloc!=locations_list.end();++itloc)
std::cerr << " Location " << (*itloc).id << ", last contact " << now - (*itloc).lastcontact << " seconds ago" << std::endl ;
// Remove any location that is dummy. Update the list, such that we only look into non dummy friends later.
//
for(std::list<peerConnectState>::iterator itloc(locations_list.begin());itloc!=locations_list.end();)
for(std::list<peerState>::iterator itloc(locations_list.begin());itloc!=locations_list.end();)
if(size > 1 && isDummyFriend((*itloc).id))
{
locations_to_remove.push_back((*itloc).id) ;
@ -570,7 +583,7 @@ bool p3Peers::cleanUnusedLocations()
std::cerr << " Removing dummy location: " << (*itloc).id << std::endl ;
std::list<peerConnectState>::iterator tmp(itloc) ;
std::list<peerState>::iterator tmp(itloc) ;
++tmp ;
locations_list.erase(itloc) ;
itloc=tmp ;
@ -578,7 +591,7 @@ bool p3Peers::cleanUnusedLocations()
else
++itloc ;
for(std::list<peerConnectState>::const_iterator itloc(locations_list.begin());itloc!=locations_list.end();++itloc)
for(std::list<peerState>::const_iterator itloc(locations_list.begin());itloc!=locations_list.end();++itloc)
if(size > 1 && now > (*itloc).lastcontact + MAX_TIME_KEEP_LOCATION_WITHOUT_CONTACT)
{
locations_to_remove.push_back((*itloc).id) ;
@ -628,8 +641,8 @@ std::string p3Peers::getGPGId(const std::string &sslid_or_gpgid)
if (sslid_or_gpgid == AuthSSL::getAuthSSL()->OwnId()) {
return AuthGPG::getAuthGPG()->getGPGOwnId();
}
peerConnectState pcs;
if (mConnMgr->getFriendNetStatus(sslid_or_gpgid, pcs) || mConnMgr->getOthersNetStatus(sslid_or_gpgid, pcs)) {
peerState pcs;
if (mPeerMgr->getFriendNetStatus(sslid_or_gpgid, pcs) || mPeerMgr->getOthersNetStatus(sslid_or_gpgid, pcs)) {
return pcs.gpg_id;
} else {
if ( AuthGPG::getAuthGPG()->isGPGId(sslid_or_gpgid)) {
@ -653,7 +666,7 @@ bool p3Peers::addFriend(const std::string &id, const std::string &gpg_id)
if (id == gpg_id || id == "") {
return addDummyFriend(gpg_id);
} else {
return mConnMgr->addFriend(id, gpg_id);
return mPeerMgr->addFriend(id, gpg_id);
}
}
@ -664,8 +677,8 @@ bool p3Peers::addDummyFriend(const std::string &gpg_id)
#endif
std::string dummy_ssl_id = "dummy"+ gpg_id;
//check if this gpg_id already got a dummy friend
if (!mConnMgr->isFriend(dummy_ssl_id)) {
return mConnMgr->addFriend(dummy_ssl_id, gpg_id);
if (!mPeerMgr->isFriend(dummy_ssl_id)) {
return mPeerMgr->addFriend(dummy_ssl_id, gpg_id);
} else {
#ifdef P3PEERS_DEBUG
std::cerr << "p3Peers::addDummyFriend() dummy friend already exists for gpg_id : " << gpg_id << std::endl;
@ -706,7 +719,7 @@ bool p3Peers::removeFriend(const std::string &ssl_or_gpgid)
AuthGPG::getAuthGPG()->setAcceptToConnectGPGCertificate(ssl_or_gpgid, false);
//will remove if it's a ssl id
mConnMgr->removeFriend(ssl_or_gpgid);
mPeerMgr->removeFriend(ssl_or_gpgid);
return true;
}
@ -718,16 +731,16 @@ bool p3Peers::connectAttempt(const std::string &id)
std::cerr << "p3Peers::connectAttempt() " << id << std::endl;
#endif
return mConnMgr->retryConnect(id);
return mLinkMgr->retryConnect(id);
}
void p3Peers::getIPServersList(std::list<std::string>& ip_servers)
{
mConnMgr->getIPServersList(ip_servers) ;
mNetMgr->getIPServersList(ip_servers) ;
}
void p3Peers::allowServerIPDetermination(bool b)
{
mConnMgr->setIPServersEnabled(b) ;
mNetMgr->setIPServersEnabled(b) ;
}
void p3Peers::allowTunnelConnection(bool b)
@ -735,12 +748,12 @@ void p3Peers::allowTunnelConnection(bool b)
#ifdef P3PEERS_DEBUG
std::cerr << "p3Peers::allowTunnelConnection() set tunnel to : " << b << std::endl;
#endif
mConnMgr->setTunnelConnection(b) ;
mLinkMgr->setTunnelConnection(b) ;
}
bool p3Peers::getAllowServerIPDetermination()
{
return mConnMgr->getIPServersEnabled() ;
return mNetMgr->getIPServersEnabled() ;
}
bool p3Peers::getAllowTunnelConnection()
@ -748,7 +761,7 @@ bool p3Peers::getAllowTunnelConnection()
#ifdef P3PEERS_DEBUG
std::cerr << "p3Peers::getAllowTunnelConnection() tunnel is : " << mConnMgr->getTunnelConnection() << std::endl;
#endif
return mConnMgr->getTunnelConnection() ;
return mLinkMgr->getTunnelConnection() ;
}
bool p3Peers::setLocalAddress(const std::string &id, const std::string &addr_str, uint16_t port)
@ -771,7 +784,7 @@ bool p3Peers::setLocalAddress(const std::string &id, const std::string &addr_st
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART *******************/
{
return mConnMgr->setLocalAddress(id, addr);
return mPeerMgr->setLocalAddress(id, addr);
}
return false;
}
@ -782,7 +795,7 @@ bool p3Peers::setLocation(const std::string &ssl_id, const std::string &locatio
std::cerr << "p3Peers::setLocation() " << ssl_id << std::endl;
#endif
return mConnMgr->setLocation(ssl_id, location);
return mPeerMgr->setLocation(ssl_id, location);
}
bool p3Peers::setExtAddress(const std::string &id, const std::string &addr_str, uint16_t port)
{
@ -804,7 +817,7 @@ bool p3Peers::setExtAddress(const std::string &id, const std::string &addr_str,
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART *******************/
{
return mConnMgr->setExtAddress(id, addr);
return mPeerMgr->setExtAddress(id, addr);
}
return false;
}
@ -814,7 +827,7 @@ bool p3Peers::setDynDNS(const std::string &id, const std::string &dyndns)
#ifdef P3PEERS_DEBUG
std::cerr << "p3Peers::setDynDNS() called with id: " << id << " dyndns: " << dyndns <<std::endl;
#endif
return mConnMgr->setDynDNS(id, dyndns);
return mPeerMgr->setDynDNS(id, dyndns);
}
bool p3Peers::setNetworkMode(const std::string &id, uint32_t extNetMode)
@ -843,7 +856,7 @@ bool p3Peers::setNetworkMode(const std::string &id, uint32_t extNetMode)
break;
}
return mConnMgr->setNetworkMode(id, netMode);
return mPeerMgr->setNetworkMode(id, netMode);
}
@ -861,7 +874,7 @@ p3Peers::setVisState(const std::string &id, uint32_t extVisState)
if (!(extVisState & RS_VS_DISC_ON))
visState |= RS_VIS_STATE_NODISC;
return mConnMgr->setVisState(id, visState);
return mPeerMgr->setVisState(id, visState);
}
//===========================================================================
@ -1189,7 +1202,7 @@ bool p3Peers::setAcceptToConnectGPGCertificate(const std::string &gpg_id, bool
std::list<std::string> sslFriends;
this->getSSLChildListOfGPGId(gpg_id, sslFriends);
for (std::list<std::string>::iterator it = sslFriends.begin(); it != sslFriends.end(); it++) {
mConnMgr->removeFriend(*it);
mPeerMgr->removeFriend(*it);
}
return AuthGPG::getAuthGPG()->setAcceptToConnectGPGCertificate(gpg_id, acceptance);
}
@ -1253,7 +1266,7 @@ bool p3Peers::addGroup(RsGroupInfo &groupInfo)
std::cerr << "p3Peers::addGroup()" << std::endl;
#endif
return mConnMgr->addGroup(groupInfo);
return mPeerMgr->addGroup(groupInfo);
}
bool p3Peers::editGroup(const std::string &groupId, RsGroupInfo &groupInfo)
@ -1262,7 +1275,7 @@ bool p3Peers::editGroup(const std::string &groupId, RsGroupInfo &groupInfo)
std::cerr << "p3Peers::editGroup()" << std::endl;
#endif
return mConnMgr->editGroup(groupId, groupInfo);
return mPeerMgr->editGroup(groupId, groupInfo);
}
bool p3Peers::removeGroup(const std::string &groupId)
@ -1271,7 +1284,7 @@ bool p3Peers::removeGroup(const std::string &groupId)
std::cerr << "p3Peers::removeGroup()" << std::endl;
#endif
return mConnMgr->removeGroup(groupId);
return mPeerMgr->removeGroup(groupId);
}
bool p3Peers::getGroupInfo(const std::string &groupId, RsGroupInfo &groupInfo)
@ -1280,7 +1293,7 @@ bool p3Peers::getGroupInfo(const std::string &groupId, RsGroupInfo &groupInfo)
std::cerr << "p3Peers::getGroupInfo()" << std::endl;
#endif
return mConnMgr->getGroupInfo(groupId, groupInfo);
return mPeerMgr->getGroupInfo(groupId, groupInfo);
}
bool p3Peers::getGroupInfoList(std::list<RsGroupInfo> &groupInfoList)
@ -1289,7 +1302,7 @@ bool p3Peers::getGroupInfoList(std::list<RsGroupInfo> &groupInfoList)
std::cerr << "p3Peers::getGroupInfoList()" << std::endl;
#endif
return mConnMgr->getGroupInfoList(groupInfoList);
return mPeerMgr->getGroupInfoList(groupInfoList);
}
bool p3Peers::assignPeerToGroup(const std::string &groupId, const std::string &peerId, bool assign)
@ -1306,7 +1319,7 @@ bool p3Peers::assignPeersToGroup(const std::string &groupId, const std::list<std
std::cerr << "p3Peers::assignPeersToGroup()" << std::endl;
#endif
return mConnMgr->assignPeersToGroup(groupId, peerIds, assign);
return mPeerMgr->assignPeersToGroup(groupId, peerIds, assign);
}

View File

@ -27,13 +27,16 @@
*/
#include "retroshare/rspeers.h"
#include "pqi/p3connmgr.h"
class p3LinkMgr;
class p3PeerMgr;
class p3NetMgr;
class p3Peers: public RsPeers
{
public:
p3Peers(p3ConnectMgr *cm);
p3Peers(p3LinkMgr *lm, p3PeerMgr *pm, p3NetMgr *nm);
virtual ~p3Peers() { return; }
/* Updates ... */
@ -115,7 +118,10 @@ virtual bool assignPeersToGroup(const std::string &groupId, const std::list<std:
private:
p3ConnectMgr *mConnMgr;
p3LinkMgr *mLinkMgr;
p3PeerMgr *mPeerMgr;
p3NetMgr *mNetMgr;
};
#endif

View File

@ -0,0 +1,208 @@
/*
* libretroshare/src/rsserver: p3serverconfig.h
*
* RetroShare C++ Interface.
*
* 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".
*
*/
#include "rsserver/p3serverconfig.h"
RsServerConfig *rsConfig = NULL;
p3ServerConfig::p3ServerConfig(p3PeerMgr *peerMgr, p3LinkMgr *linkMgr, p3NetMgr *netMgr)
:configMtx("p3ServerConfig")
{
mPeerMgr = peerMgr;
mLinkMgr = linkMgr;
mNetMgr = netMgr;
mUserLevel = RSCONFIG_USER_LEVEL_NEW; /* START LEVEL */
rsConfig = this;
}
p3ServerConfig::~p3ServerConfig()
{
return;
}
/* From RsIface::RsConfig */
int p3ServerConfig::getConfigNetStatus(RsConfigNetStatus &status)
{
return 0;
}
int p3ServerConfig::getConfigStartup(RsConfigStartup &params)
{
return 0;
}
int p3ServerConfig::getConfigDataRates(RsConfigDataRates &params)
{
return 0;
}
/* From RsInit */
std::string p3ServerConfig::RsConfigDirectory()
{
return std::string();
}
std::string p3ServerConfig::RsConfigKeysDirectory()
{
return std::string();
}
std::string p3ServerConfig::RsProfileConfigDirectory()
{
return std::string();
}
bool p3ServerConfig::getStartMinimised()
{
return 0;
}
std::string p3ServerConfig::getRetroShareLink()
{
return std::string();
}
bool p3ServerConfig::getAutoLogin()
{
return 0;
}
void p3ServerConfig::setAutoLogin(bool autoLogin)
{
return;
}
bool p3ServerConfig::RsClearAutoLogin()
{
return 0;
}
std::string p3ServerConfig::getRetroshareDataDirectory()
{
return std::string();
}
/* New Stuff */
uint32_t p3ServerConfig::getUserLevel()
{
uint32_t userLevel = RSCONFIG_USER_LEVEL_NEW;
{
RsStackMutex stack(configMtx); /******* LOCKED MUTEX *****/
uint32_t userLevel = mUserLevel;
}
switch(userLevel)
{
case RSCONFIG_USER_LEVEL_OVERRIDE:
break;
#define MIN_BASIC_FRIENDS 2
// FALL THROUGH EVERYTHING.
default:
case RSCONFIG_USER_LEVEL_NEW:
{
if (mLinkMgr->getFriendCount() > MIN_BASIC_FRIENDS)
{
userLevel = RSCONFIG_USER_LEVEL_BASIC;
}
}
case RSCONFIG_USER_LEVEL_BASIC:
{
/* check that we have some lastConnect > 0 */
if (mPeerMgr->haveOnceConnected())
{
userLevel = RSCONFIG_USER_LEVEL_CASUAL;
}
}
case RSCONFIG_USER_LEVEL_CASUAL:
case RSCONFIG_USER_LEVEL_POWER:
{
/* check that the firewall is open */
uint32_t netMode = mNetMgr->getNetworkMode();
uint32_t firewallMode = mNetMgr->getNatHoleMode();
if ((RSNET_NETWORK_EXTERNALIP == netMode) ||
((RSNET_NETWORK_BEHINDNAT == netMode) &&
((RSNET_NATHOLE_UPNP == firewallMode) ||
(RSNET_NATHOLE_NATPMP == firewallMode) ||
(RSNET_NATHOLE_FORWARDED == firewallMode))))
{
userLevel = RSCONFIG_USER_LEVEL_POWER;
}
}
break; /* for all */
}
{
RsStackMutex stack(configMtx); /******* LOCKED MUTEX *****/
mUserLevel = userLevel;
}
return userLevel;
}
uint32_t p3ServerConfig::getNetState()
{
return mNetMgr->getNetStateMode();
}
uint32_t p3ServerConfig::getNetworkMode()
{
return mNetMgr->getNetworkMode();
}
uint32_t p3ServerConfig::getNatTypeMode()
{
return mNetMgr->getNatTypeMode();
}
uint32_t p3ServerConfig::getNatHoleMode()
{
return mNetMgr->getNatHoleMode();
}
uint32_t p3ServerConfig::getConnectModes()
{
return mNetMgr->getConnectModes();
}

View File

@ -0,0 +1,86 @@
#ifndef LIBRETROSHARE_CONFIG_IMPLEMENTATION_H
#define LIBRETROSHARE_CONFIG_IMPLEMENTATION_H
/*
* libretroshare/src/rsserver: p3serverconfig.h
*
* RetroShare C++ Interface.
*
* 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".
*
*/
#include "retroshare/rsconfig.h"
#include "pqi/p3peermgr.h"
#include "pqi/p3linkmgr.h"
#include "pqi/p3netmgr.h"
class p3ServerConfig: public RsServerConfig
{
public:
p3ServerConfig(p3PeerMgr *peerMgr, p3LinkMgr *linkMgr, p3NetMgr *netMgr);
virtual ~p3ServerConfig();
/* From RsIface::RsConfig */
virtual int getConfigNetStatus(RsConfigNetStatus &status);
virtual int getConfigStartup(RsConfigStartup &params);
virtual int getConfigDataRates(RsConfigDataRates &params);
/* From RsInit */
virtual std::string RsConfigDirectory();
virtual std::string RsConfigKeysDirectory();
virtual std::string RsProfileConfigDirectory();
virtual bool getStartMinimised();
virtual std::string getRetroShareLink();
virtual bool getAutoLogin();
virtual void setAutoLogin(bool autoLogin);
virtual bool RsClearAutoLogin();
virtual std::string getRetroshareDataDirectory();
/* New Stuff */
virtual uint32_t getUserLevel();
virtual uint32_t getNetState();
virtual uint32_t getNetworkMode();
virtual uint32_t getNatTypeMode();
virtual uint32_t getNatHoleMode();
virtual uint32_t getConnectModes();
/********************* ABOVE is RsConfig Interface *******/
private:
p3PeerMgr *mPeerMgr;
p3LinkMgr *mLinkMgr;
p3NetMgr *mNetMgr;
RsMutex configMtx;
uint32_t mUserLevel; // store last one... will later be a config Item too.
};
#endif

View File

@ -1698,7 +1698,8 @@ RsTurtle *rsTurtle = NULL ;
#include "util/rsdebug.h"
#include "util/rsdir.h"
#include "util/rsrandom.h"
#include "upnp/upnphandler.h"
//#include "dht/opendhtmgr.h"
@ -1731,15 +1732,25 @@ RsTurtle *rsTurtle = NULL ;
#include "rsserver/p3discovery.h"
#include "rsserver/p3photo.h"
#include "rsserver/p3status.h"
#include "rsserver/p3serverconfig.h"
#include "retroshare/rsgame.h"
#include "pqi/p3notify.h" // HACK - moved to pqi for compilation order.
#include "pqi/p3peermgr.h"
#include "pqi/p3linkmgr.h"
#include "pqi/p3netmgr.h"
#include "tcponudp/tou.h"
#include "tcponudp/rsudpstack.h"
#ifdef RS_USE_BITDHT
#include "dht/p3bitdht.h"
#include "dht/stunaddrassist.h"
#include "udp/udpstack.h"
#include "tcponudp/udppeer.h"
#include "tcponudp/udprelay.h"
@ -1823,8 +1834,13 @@ int RsServer::StartupRetroShare()
/* Setup Notify Early - So we can use it. */
rsNotify = new p3Notify();
mConnMgr = new p3ConnectMgr();
mPeerMgr = new p3PeerMgrIMPL();
mNetMgr = new p3NetMgrIMPL();
mLinkMgr = new p3LinkMgrIMPL(mPeerMgr, mNetMgr);
mPeerMgr->setManagers(mLinkMgr, mNetMgr);
mNetMgr->setManagers(mPeerMgr, mLinkMgr);
//load all the SSL certs as friends
// std::list<std::string> sslIds;
// AuthSSL::getAuthSSL()->getAuthenticatedList(sslIds);
@ -1840,7 +1856,7 @@ int RsServer::StartupRetroShare()
struct sockaddr_in tmpladdr;
sockaddr_clear(&tmpladdr);
tmpladdr.sin_port = htons(RsInitConfig::port);
rsUdpStack *mUdpStack = new rsUdpStack(tmpladdr);
rsUdpStack *mDhtStack = new rsUdpStack(tmpladdr);
#ifdef RS_USE_BITDHT
@ -1889,59 +1905,58 @@ int RsServer::StartupRetroShare()
/* construct the rest of the stack, important to build them in the correct order! */
/* MOST OF THIS IS COMMENTED OUT UNTIL THE REST OF libretroshare IS READY FOR IT! */
UdpSubReceiver *udpReceivers[3];
int udpTypes[3];
UdpSubReceiver *udpReceivers[RSUDP_NUM_TOU_RECVERS];
int udpTypes[RSUDP_NUM_TOU_RECVERS];
// FIRST DHT STUNNER.
UdpStunner *mDhtStunner = new UdpStunner(mUdpStack);
mDhtStunner->setTargetStunPeriod(0); /* passive */
//mDhtStunner->setTargetStunPeriod(300); /* slow (5mins) */
mUdpStack->addReceiver(mDhtStunner);
UdpStunner *mDhtStunner = new UdpStunner(mDhtStack);
mDhtStunner->setTargetStunPeriod(300); /* slow (5mins) */
mDhtStack->addReceiver(mDhtStunner);
// NEXT BITDHT.
p3BitDht *mBitDht = new p3BitDht(ownId, mConnMgr, mUdpStack, bootstrapfile);
p3BitDht *mBitDht = new p3BitDht(ownId, mLinkMgr, mNetMgr, mDhtStack, bootstrapfile);
/* install external Pointer for Interface */
rsDht = mBitDht;
// NEXT THE RELAY (NEED to keep a reference for installing RELAYS)
UdpRelayReceiver *mRelayRecver = new UdpRelayReceiver(mUdpStack);
udpReceivers[2] = mRelayRecver; /* RELAY Connections (DHT Port) */
udpTypes[2] = TOU_RECEIVER_TYPE_UDPRELAY;
mUdpStack->addReceiver(udpReceivers[2]);
UdpRelayReceiver *mRelay = new UdpRelayReceiver(mDhtStack);
udpReceivers[RSUDP_TOU_RECVER_RELAY_IDX] = mRelay; /* RELAY Connections (DHT Port) */
udpTypes[RSUDP_TOU_RECVER_RELAY_IDX] = TOU_RECEIVER_TYPE_UDPRELAY;
mDhtStack->addReceiver(udpReceivers[RSUDP_TOU_RECVER_RELAY_IDX]);
// LAST ON THIS STACK IS STANDARD DIRECT TOU
udpReceivers[0] = new UdpPeerReceiver(mUdpStack); /* standard DIRECT Connections (DHT Port) */
udpTypes[0] = TOU_RECEIVER_TYPE_UDPPEER;
mUdpStack->addReceiver(udpReceivers[0]);
udpReceivers[RSUDP_TOU_RECVER_DIRECT_IDX] = new UdpPeerReceiver(mDhtStack); /* standard DIRECT Connections (DHT Port) */
udpTypes[RSUDP_TOU_RECVER_DIRECT_IDX] = TOU_RECEIVER_TYPE_UDPPEER;
mDhtStack->addReceiver(udpReceivers[RSUDP_TOU_RECVER_DIRECT_IDX]);
// NOW WE BUILD THE SECOND STACK.
// Create the Second UdpStack... Port should be random (but openable!).
//struct sockaddr_in sndladdr;
//sockaddr_clear(&sndladdr);
//sndladdr.sin_port = htons(RsInitConfig::port + 1111);
//rsUdpStack *mUdpProxyStack = new rsUdpStack(sndladdr);
// XXX TODO
#define MIN_RANDOM_PORT 10000
#define MAX_RANDOM_PORT 30000
struct sockaddr_in sndladdr;
sockaddr_clear(&sndladdr);
uint16_t rndport = MIN_RANDOM_PORT + RSRandom::random_u32() % (MAX_RANDOM_PORT - MIN_RANDOM_PORT);
sndladdr.sin_port = htons(RsInitConfig::port);
rsFixedUdpStack *mProxyStack = new rsFixedUdpStack(sndladdr);
// FIRSTLY THE PROXY STUNNER.
//UdpStunner *mProxyStunner = new UdpStunner(mUdpProxyStack);
// USE DEFAULT PERIOD... mDhtStunner->setTargetStunPeriod(300); /* slow (5mins) */
//mUdpStack->addReceiver(mDhtStunner);
UdpStunner *mProxyStunner = new UdpStunner(mProxyStack);
mProxyStunner->setTargetStunPeriod(300); /* slow (5mins) */
mProxyStack->addReceiver(mProxyStunner);
// FINALLY THE PROXY UDP CONNECTIONS
//udpReceivers[1] = new UdpPeerReceiver(mUdpProxyStack); /* PROXY Connections (Alt UDP Port) */
//udpTypes[1] = TOU_RECEIVER_TYPE_UDPPEER;
//mUdpProxyStack->addReceiver(udpReceivers[1]);
udpReceivers[RSUDP_TOU_RECVER_PROXY_IDX] = new UdpPeerReceiver(mProxyStack); /* PROXY Connections (Alt UDP Port) */
udpTypes[RSUDP_TOU_RECVER_PROXY_IDX] = TOU_RECEIVER_TYPE_UDPPEER;
mProxyStack->addReceiver(udpReceivers[RSUDP_TOU_RECVER_PROXY_IDX]);
// REAL INITIALISATION - WITH THREE MODES
tou_init((void **) udpReceivers, udpTypes, RSUDP_NUM_TOU_RECVERS);
mBitDht->setupConnectBits(mDhtStunner, mProxyStunner, mRelay);
// NOW WE CAN PASS THE RECEIVERS TO TOU.
// temp initialisation of only the DIRECT TOU.
tou_init((void **) udpReceivers, udpTypes, 1);
// REAL INITIALISATION - WITH THREE MODES - FOR LATER.
//tou_init((void **) udpReceivers, udpTypes, 3);
//mBitDht->setupConnectBits(mDhtStunner, mProxyStunner, mRelayRecver);
mBitDht->setupConnectBits(mDhtStunner, NULL, mRelayRecver);
mNetMgr->setAddrAssist(new stunAddrAssist(mDhtStunner), new stunAddrAssist(mProxyStunner));
#else
/* install NULL Pointer for rsDht Interface */
rsDht = NULL;
@ -1952,24 +1967,25 @@ int RsServer::StartupRetroShare()
SecurityPolicy *none = secpolicy_create();
pqih = new pqisslpersongrp(none, flags);
pqih = new pqisslpersongrp(none, flags, mPeerMgr);
//pqih = new pqipersongrpDummy(none, flags);
/****** New Ft Server **** !!! */
ftserver = new ftServer(mConnMgr);
ftserver->setP3Interface(pqih);
ftserver = new ftServer(mPeerMgr, mLinkMgr);
ftserver->setP3Interface(pqih);
ftserver->setConfigDirectory(RsInitConfig::configDir);
ftserver->SetupFtServer(&(getNotify()));
CacheStrapper *mCacheStrapper = ftserver->getCacheStrapper();
CacheTransfer *mCacheTransfer = ftserver->getCacheTransfer();
/* setup any extra bits (Default Paths) */
ftserver->setPartialsDirectory(emergencyPartialsDir);
ftserver->setDownloadDirectory(emergencySaveDir);
/* setup any extra bits (Default Paths) */
ftserver->setPartialsDirectory(emergencyPartialsDir);
ftserver->setDownloadDirectory(emergencySaveDir);
/* This should be set by config ... there is no default */
//ftserver->setSharedDirectories(fileList);
//ftserver->setSharedDirectories(fileList);
rsFiles = ftserver;
@ -2006,18 +2022,18 @@ int RsServer::StartupRetroShare()
//
mPluginsManager->setCacheDirectories(localcachedir,remotecachedir) ;
mPluginsManager->setFileServer(ftserver) ;
mPluginsManager->setConnectMgr(mConnMgr) ;
mPluginsManager->setLinkMgr(mLinkMgr) ;
// Now load the plugins. This parses the available SO/DLL files for known symbols.
//
mPluginsManager->loadPlugins(plugins_directories) ;
/* create Services */
ad = new p3disc(mConnMgr, pqih);
ad = new p3disc(mPeerMgr, mLinkMgr, pqih);
#ifndef MINIMAL_LIBRS
msgSrv = new p3MsgService(mConnMgr);
chatSrv = new p3ChatService(mConnMgr);
mStatusSrv = new p3StatusService(mConnMgr);
msgSrv = new p3MsgService(mLinkMgr);
chatSrv = new p3ChatService(mLinkMgr);
mStatusSrv = new p3StatusService(mLinkMgr);
#endif // MINIMAL_LIBRS
#ifndef PQI_DISABLE_TUNNEL
@ -2026,7 +2042,7 @@ int RsServer::StartupRetroShare()
mConnMgr->setP3tunnel(tn);
#endif
p3turtle *tr = new p3turtle(mConnMgr,ftserver) ;
p3turtle *tr = new p3turtle(mLinkMgr,ftserver) ;
rsTurtle = tr ;
pqih -> addService(tr);
ftserver->connectToTurtleRouter(tr) ;
@ -2064,7 +2080,7 @@ int RsServer::StartupRetroShare()
mPluginsManager->registerCacheServices() ;
#ifndef RS_RELEASE
p3GameLauncher *gameLauncher = new p3GameLauncher(mConnMgr);
p3GameLauncher *gameLauncher = new p3GameLauncher(mLinkMgr);
pqih -> addService(gameLauncher);
p3PhotoService *photoService = new p3PhotoService(RS_SERVICE_TYPE_PHOTO, /* .... for photo service */
@ -2079,26 +2095,28 @@ int RsServer::StartupRetroShare()
/**************************************************************************/
#ifdef RS_USE_BITDHT
mConnMgr->addNetAssistConnect(1, mBitDht);
mConnMgr->addNetListener(mUdpStack);
mNetMgr->addNetAssistConnect(1, mBitDht);
mNetMgr->addNetListener(mDhtStack);
mNetMgr->addNetListener(mProxyStack);
#endif
mConnMgr->addNetAssistFirewall(1, mUpnpMgr);
mNetMgr->addNetAssistFirewall(1, mUpnpMgr);
/**************************************************************************/
/* need to Monitor too! */
mConnMgr->addMonitor(pqih);
mConnMgr->addMonitor(mCacheStrapper);
mConnMgr->addMonitor(ad);
mLinkMgr->addMonitor(pqih);
mLinkMgr->addMonitor(mCacheStrapper);
mLinkMgr->addMonitor(ad);
#ifndef MINIMAL_LIBRS
mConnMgr->addMonitor(msgSrv);
mConnMgr->addMonitor(mStatusSrv);
mConnMgr->addMonitor(chatSrv);
mLinkMgr->addMonitor(msgSrv);
mLinkMgr->addMonitor(mStatusSrv);
mLinkMgr->addMonitor(chatSrv);
#endif // MINIMAL_LIBRS
/* must also add the controller as a Monitor...
* a little hack to get it to work.
*/
mConnMgr->addMonitor(((ftController *) mCacheTransfer));
mLinkMgr->addMonitor(((ftController *) mCacheTransfer));
/**************************************************************************/
@ -2108,7 +2126,7 @@ int RsServer::StartupRetroShare()
mConfigMgr->addConfiguration("gpg_prefs.cfg", (AuthGPGimpl *) AuthGPG::getAuthGPG());
mConfigMgr->loadConfiguration();
mConfigMgr->addConfiguration("peers.cfg", mConnMgr);
mConfigMgr->addConfiguration("peers.cfg", mPeerMgr);
mConfigMgr->addConfiguration("general.cfg", mGeneralConfig);
mConfigMgr->addConfiguration("cache.cfg", mCacheStrapper);
#ifndef MINIMAL_LIBRS
@ -2165,12 +2183,14 @@ int RsServer::StartupRetroShare()
// universal
laddr.sin_addr.s_addr = inet_addr(RsInitConfig::inet);
mConnMgr->setLocalAddress(ownId, laddr);
mPeerMgr->setLocalAddress(ownId, laddr);
}
if (RsInitConfig::forceExtPort)
{
mConnMgr->setOwnNetConfig(RS_NET_MODE_EXT, RS_VIS_STATE_STD);
mPeerMgr->setOwnNetworkMode(RS_NET_MODE_EXT);
mPeerMgr->setOwnVisState(RS_VIS_STATE_STD);
}
#if 0
@ -2186,14 +2206,14 @@ int RsServer::StartupRetroShare()
}
#endif
mConnMgr -> checkNetAddress();
mNetMgr -> checkNetAddress();
/**************************************************************************/
/* startup (stuff dependent on Ids/peers is after this point) */
/**************************************************************************/
pqih->init_listener();
mConnMgr->addNetListener(pqih); /* add listener so we can reset all sockets later */
mNetMgr->addNetListener(pqih); /* add listener so we can reset all sockets later */
@ -2280,8 +2300,9 @@ int RsServer::StartupRetroShare()
/* Setup GUI Interfaces. */
rsPeers = new p3Peers(mConnMgr);
rsPeers = new p3Peers(mLinkMgr, mPeerMgr, mNetMgr);
rsDisc = new p3Discovery(ad);
rsConfig = new p3ServerConfig(mPeerMgr, mLinkMgr, mNetMgr);
#ifndef MINIMAL_LIBRS
rsMsgs = new p3Msgs(msgSrv, chatSrv);

View File

@ -28,6 +28,7 @@
#include "pqi/pqibin.h"
#include "pqi/pqinotify.h"
#include "pqi/pqistore.h"
#include "pqi/p3linkmgr.h"
#include "services/p3chatservice.h"
@ -41,8 +42,8 @@
*
*/
p3ChatService::p3ChatService(p3ConnectMgr *cm)
:p3Service(RS_SERVICE_TYPE_CHAT), p3Config(CONFIG_TYPE_CHAT), mChatMtx("p3ChatService"), mConnMgr(cm)
p3ChatService::p3ChatService(p3LinkMgr *lm)
:p3Service(RS_SERVICE_TYPE_CHAT), p3Config(CONFIG_TYPE_CHAT), mChatMtx("p3ChatService"), mLinkMgr(lm)
{
addSerialType(new RsChatSerialiser());
@ -72,10 +73,10 @@ int p3ChatService::sendPublicChat(std::wstring &msg)
std::list<std::string> ids;
std::list<std::string>::iterator it;
mConnMgr->getOnlineList(ids);
mLinkMgr->getOnlineList(ids);
/* add in own id -> so get reflection */
ids.push_back(mConnMgr->getOwnId());
ids.push_back(mLinkMgr->getOwnId());
#ifdef CHAT_DEBUG
std::cerr << "p3ChatService::sendChat()";
@ -156,7 +157,7 @@ class p3ChatService::AvatarInfo
void p3ChatService::sendGroupChatStatusString(const std::string& status_string)
{
std::list<std::string> ids;
mConnMgr->getOnlineList(ids);
mLinkMgr->getOnlineList(ids);
#ifdef CHAT_DEBUG
std::cerr << "p3ChatService::sendChat(): sending group chat status string: " << status_string << std::endl ;
@ -235,7 +236,7 @@ bool p3ChatService::sendPrivateChat(std::string &id, std::wstring &msg)
ci->recvTime = ci->sendTime;
ci->message = msg;
if (!mConnMgr->isOnline(id)) {
if (!mLinkMgr->isOnline(id)) {
/* peer is offline, add to outgoing list */
{
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
@ -690,7 +691,7 @@ void p3ChatService::setOwnCustomStateString(const std::string& s)
for(std::map<std::string,StateStringInfo>::iterator it(_state_strings.begin());it!=_state_strings.end();++it)
it->second._own_is_new = true ;
mConnMgr->getOnlineList(onlineList);
mLinkMgr->getOnlineList(onlineList);
}
rsicontrol->getNotify().notifyOwnStatusMessageChanged() ;
@ -1022,7 +1023,7 @@ bool p3ChatService::saveList(bool& cleanup, std::list<RsItem*>& list)
if(_own_avatar != NULL)
{
RsChatAvatarItem *ci = makeOwnAvatarItem() ;
ci->PeerId(mConnMgr->getOwnId());
ci->PeerId(mLinkMgr->getOwnId());
list.push_back(ci) ;
}

View File

@ -32,9 +32,10 @@
#include "serialiser/rsmsgitems.h"
#include "services/p3service.h"
#include "pqi/p3connmgr.h"
#include "retroshare/rsmsgs.h"
class p3LinkMgr;
//!The basic Chat service.
/**
*
@ -45,7 +46,7 @@
class p3ChatService: public p3Service, public p3Config, public pqiMonitor
{
public:
p3ChatService(p3ConnectMgr *cm);
p3ChatService(p3LinkMgr *cm);
/***** overloaded from p3Service *****/
/*!
@ -199,7 +200,7 @@ class p3ChatService: public p3Service, public p3Config, public pqiMonitor
RsChatAvatarItem *makeOwnAvatarItem() ;
RsChatStatusItem *makeOwnCustomStateStringItem() ;
p3ConnectMgr *mConnMgr;
p3LinkMgr *mLinkMgr;
std::list<RsChatMsgItem *> publicList;
std::list<RsChatMsgItem *> privateIncomingList;

View File

@ -29,9 +29,11 @@
#include "retroshare/rspeers.h"
#include "services/p3disc.h"
#include "pqi/p3peermgr.h"
#include "pqi/p3linkmgr.h"
#include "pqi/authssl.h"
#include "pqi/authgpg.h"
#include "pqi/p3connmgr.h"
#include <iostream>
#include <errno.h>
@ -82,10 +84,10 @@ const uint32_t P3DISC_FLAGS_ASK_VERSION = 0x0080;
******************************************************************************************
*****************************************************************************************/
p3disc::p3disc(p3ConnectMgr *cm, pqipersongrp *pqih)
p3disc::p3disc(p3PeerMgr *pm, p3LinkMgr *lm, pqipersongrp *pqih)
:p3Service(RS_SERVICE_TYPE_DISC),
p3Config(CONFIG_TYPE_P3DISC),
mConnMgr(cm),
mPeerMgr(pm), mLinkMgr(lm),
mPqiPersonGrp(pqih), mDiscMtx("p3disc")
{
RsStackMutex stack(mDiscMtx); /********** STACK LOCKED MTX ******/
@ -114,7 +116,7 @@ int p3disc::tick()
#endif
lastSentHeartbeatTime = time(NULL);
std::list <std::string> peers;
mConnMgr->getOnlineList(peers);
mLinkMgr->getOnlineList(peers);
for (std::list<std::string>::const_iterator pit = peers.begin(); pit != peers.end(); ++pit) {
sendHeartbeat(*pit);
}
@ -132,8 +134,8 @@ int p3disc::handleIncoming()
#endif
// if off discard item.
peerConnectState detail;
if (!mConnMgr->getOwnNetStatus(detail) || (detail.visState & RS_VIS_STATE_NODISC))
peerState detail;
if (!mPeerMgr->getOwnNetStatus(detail) || (detail.visState & RS_VIS_STATE_NODISC))
{
while(NULL != (item = recvItem()))
{
@ -288,8 +290,8 @@ void p3disc::sendAllInfoToJustConnectedPeer(const std::string &id)
/* send them a list of all friend's details */
for(friendIdsIt = friendIds.begin(); friendIdsIt != friendIds.end(); friendIdsIt++) {
/* get details */
peerConnectState detail;
if (!mConnMgr->getFriendNetStatus(*friendIdsIt, detail)) {
peerState detail;
if (!mPeerMgr->getFriendNetStatus(*friendIdsIt, detail)) {
/* major error! */
continue;
}
@ -368,8 +370,8 @@ RsDiscReply *p3disc::createDiscReply(const std::string &to, const std::string &a
// if off discard item.
peerConnectState detail;
if (!mConnMgr->getOwnNetStatus(detail) || (detail.visState & RS_VIS_STATE_NODISC)) {
peerState detail;
if (!mPeerMgr->getOwnNetStatus(detail) || (detail.visState & RS_VIS_STATE_NODISC)) {
return NULL;
}
@ -405,8 +407,8 @@ RsDiscReply *p3disc::createDiscReply(const std::string &to, const std::string &a
if(sslChilds.size() == 1 || to != *sslChildIt) // We don't send info to a peer about itself, when there are more than one ssl children,
{ // but we allow sending info about peers with the same GPG id. When there is only one ssl child,
// we must send it to transfer the signers of the gpg key. The receiver is skipping the own id.
peerConnectState detail;
if (!mConnMgr->getFriendNetStatus(*sslChildIt, detail)
peerState detail;
if (!mPeerMgr->getFriendNetStatus(*sslChildIt, detail)
|| detail.visState & RS_VIS_STATE_NODISC)
{
#ifdef P3DISC_DEBUG
@ -430,8 +432,8 @@ RsDiscReply *p3disc::createDiscReply(const std::string &to, const std::string &a
rsPeerNetItem.netMode = detail.netMode;
rsPeerNetItem.visState = detail.visState;
rsPeerNetItem.lastContact = detail.lastcontact;
rsPeerNetItem.currentlocaladdr = detail.currentlocaladdr;
rsPeerNetItem.currentremoteaddr = detail.currentserveraddr;
rsPeerNetItem.currentlocaladdr = detail.localaddr;
rsPeerNetItem.currentremoteaddr = detail.serveraddr;
rsPeerNetItem.dyndns = detail.dyndns;
detail.ipAddrs.mLocal.loadTlv(rsPeerNetItem.localAddrList);
detail.ipAddrs.mExt.loadTlv(rsPeerNetItem.extAddrList);
@ -452,8 +454,8 @@ RsDiscReply *p3disc::createDiscReply(const std::string &to, const std::string &a
//send own details
if (about == rsPeers->getGPGOwnId())
{
peerConnectState detail;
if (mConnMgr->getOwnNetStatus(detail))
peerState detail;
if (mPeerMgr->getOwnNetStatus(detail))
{
shouldWeSendGPGKey = true;
RsPeerNetItem rsPeerNetItem ;
@ -464,8 +466,8 @@ RsDiscReply *p3disc::createDiscReply(const std::string &to, const std::string &a
rsPeerNetItem.netMode = detail.netMode;
rsPeerNetItem.visState = detail.visState;
rsPeerNetItem.lastContact = time(NULL);
rsPeerNetItem.currentlocaladdr = detail.currentlocaladdr;
rsPeerNetItem.currentremoteaddr = detail.currentserveraddr;
rsPeerNetItem.currentlocaladdr = detail.localaddr;
rsPeerNetItem.currentremoteaddr = detail.serveraddr;
rsPeerNetItem.dyndns = detail.dyndns;
detail.ipAddrs.mLocal.loadTlv(rsPeerNetItem.localAddrList);
detail.ipAddrs.mExt.loadTlv(rsPeerNetItem.extAddrList);
@ -534,8 +536,8 @@ void p3disc::askInfoToAllPeers(std::string about)
#endif
peerConnectState connectState;
if (!mConnMgr->getFriendNetStatus(about, connectState)) // || (connectState.visState & RS_VIS_STATE_NODISC)) {
peerState connectState;
if (!mPeerMgr->getFriendNetStatus(about, connectState)) // || (connectState.visState & RS_VIS_STATE_NODISC)) {
{
#ifdef P3DISC_DEBUG
std::cerr << "p3disc::askInfoToAllPeers() friend disc is off, don't send the request." << std::endl;
@ -551,7 +553,7 @@ void p3disc::askInfoToAllPeers(std::string about)
}
// if off discard item.
if (!mConnMgr->getOwnNetStatus(connectState) || (connectState.visState & RS_VIS_STATE_NODISC)) {
if (!mPeerMgr->getOwnNetStatus(connectState) || (connectState.visState & RS_VIS_STATE_NODISC)) {
#ifdef P3DISC_DEBUG
std::cerr << "p3disc::askInfoToAllPeers() no gpg id found" << std::endl;
#endif
@ -644,7 +646,7 @@ void p3disc::recvPeerDetails(RsDiscReply *item, const std::string &certGpgId)
#ifdef P3DISC_DEBUG
std::cerr << "--> Adding to friends list " << pitem->pid << " - " << pitem->gpg_id << std::endl;
#endif
mConnMgr->addFriend(pitem->pid, pitem->gpg_id, pitem->netMode, 0, 0);
mPeerMgr->addFriend(pitem->pid, pitem->gpg_id, pitem->netMode, 0, 0);
RsPeerDetails storedDetails;
// Update if know this peer
@ -660,9 +662,9 @@ void p3disc::recvPeerDetails(RsDiscReply *item, const std::string &certGpgId)
std::cerr << " -> network mode: " << pitem->netMode << std::endl;
std::cerr << " -> location: " << pitem->location << std::endl;
#endif
mConnMgr->setNetworkMode(pitem->pid, pitem->netMode);
mPeerMgr->setNetworkMode(pitem->pid, pitem->netMode);
}
mConnMgr->setLocation(pitem->pid, pitem->location);
mPeerMgr->setLocation(pitem->pid, pitem->location);
// The info from the peer itself is ultimately trustable, so we can override some info,
// such as:
@ -683,10 +685,10 @@ void p3disc::recvPeerDetails(RsDiscReply *item, const std::string &certGpgId)
// When the peer sends his own list of IPs, the info replaces the existing info, because the
// peer is the primary source of his own IPs.
mConnMgr->setLocalAddress(pitem->pid, pitem->currentlocaladdr);
mConnMgr->setExtAddress(pitem->pid, pitem->currentremoteaddr);
pitem->visState &= ~RS_VIS_STATE_NODISC ;
mConnMgr->setVisState(pitem->pid, pitem->visState);
mPeerMgr->setLocalAddress(pitem->pid, pitem->currentlocaladdr);
mPeerMgr->setExtAddress(pitem->pid, pitem->currentremoteaddr);
//pitem->visState &= ~RS_VIS_STATE_NODISC ;
mPeerMgr->setVisState(pitem->pid, pitem->visState);
}
}
else
@ -706,9 +708,9 @@ void p3disc::recvPeerDetails(RsDiscReply *item, const std::string &certGpgId)
#endif
// allways update address list and dns, except if it's ours
if (pitem->dyndns != "")
mConnMgr->setDynDNS(pitem->pid, pitem->dyndns);
mPeerMgr->setDynDNS(pitem->pid, pitem->dyndns);
mConnMgr->updateAddressList(pitem->pid, addrsFromPeer);
mPeerMgr->updateAddressList(pitem->pid, addrsFromPeer);
}
#ifdef P3DISC_DEBUG
else
@ -818,7 +820,7 @@ AuthGPGOperation *p3disc::getGPGOperation()
while (!sendIdList.empty()) {
std::map<std::string, std::list<std::string> >::iterator sendIdIt = sendIdList.begin();
if (!sendIdIt->second.empty() && mConnMgr->isOnline(sendIdIt->first)) {
if (!sendIdIt->second.empty() && mLinkMgr->isOnline(sendIdIt->first)) {
std::string gpgId = sendIdIt->second.front();
sendIdIt->second.pop_front();

View File

@ -72,7 +72,8 @@ class autoneighbour: public autoserver
};
class p3ConnectMgr;
class p3PeerMgr;
class p3LinkMgr;
class p3disc: public p3Service, public pqiMonitor, public p3Config, public AuthGPGService
@ -80,7 +81,7 @@ class p3disc: public p3Service, public pqiMonitor, public p3Config, public AuthG
public:
p3disc(p3ConnectMgr *cm, pqipersongrp *persGrp);
p3disc(p3PeerMgr *pm, p3LinkMgr *lm, pqipersongrp *persGrp);
/************* from pqiMonitor *******************/
virtual void statusChange(const std::list<pqipeer> &plist);
@ -141,9 +142,11 @@ int idServers();
private:
p3ConnectMgr *mConnMgr;
pqipersongrp *mPqiPersonGrp;
time_t lastSentHeartbeatTime;
p3PeerMgr *mPeerMgr;
p3LinkMgr *mLinkMgr;
pqipersongrp *mPqiPersonGrp;
time_t lastSentHeartbeatTime;
/* data */
RsMutex mDiscMtx;

View File

@ -26,7 +26,7 @@
#include "services/p3gamelauncher.h"
#include "services/p3gameservice.h"
#include "util/rsdebug.h"
#include "pqi/p3connmgr.h"
#include "pqi/p3linkmgr.h"
#include <sstream>
#include <iomanip>
@ -109,9 +109,9 @@ const uint32_t RS_GAME_MSG_REJECT = 6; /* ANY -> ANY */
const int p3gamezone = 1745;
p3GameLauncher::p3GameLauncher(p3ConnectMgr *connMgr)
p3GameLauncher::p3GameLauncher(p3LinkMgr *lm)
:p3Service(RS_SERVICE_TYPE_GAME_LAUNCHER),
mConnMgr(connMgr)
mLinkMgr(lm)
{
#ifdef GAME_DEBUG
std::cerr << "p3GameLauncher::p3GameLauncher()";
@ -119,7 +119,7 @@ p3GameLauncher::p3GameLauncher(p3ConnectMgr *connMgr)
#endif
addSerialType(new RsGameSerialiser());
mOwnId = mConnMgr->getOwnId();
mOwnId = mLinkMgr->getOwnId();
}
int p3GameLauncher::tick()

View File

@ -39,7 +39,7 @@
#include "serialiser/rsgameitems.h"
#include "retroshare/rsgame.h"
class p3ConnectMgr;
class p3LinkMgr;
class gameAvail
@ -76,7 +76,7 @@ class p3GameService;
class p3GameLauncher: public p3Service, public RsGameLauncher
{
public:
p3GameLauncher(p3ConnectMgr *connMgr);
p3GameLauncher(p3LinkMgr *lm);
/***** EXTERNAL RsGameLauncher Interface *******/
/* server commands */
@ -144,7 +144,7 @@ bool checkGameProperties(uint16_t serviceId, uint16_t players);
std::map<uint16_t, p3GameService *> gameList;
std::map<std::string, gameStatus> gamesCurrent;
p3ConnectMgr *mConnMgr;
p3LinkMgr *mLinkMgr;
std::string mOwnId;
};

View File

@ -28,7 +28,7 @@
#include "pqi/pqibin.h"
#include "pqi/pqiarchive.h"
#include "pqi/p3connmgr.h"
#include "pqi/p3linkmgr.h"
#include "services/p3msgservice.h"
#include "pqi/pqinotify.h"
@ -54,14 +54,14 @@ const int msgservicezone = 54319;
*/
p3MsgService::p3MsgService(p3ConnectMgr *cm)
p3MsgService::p3MsgService(p3LinkMgr *lm)
:p3Service(RS_SERVICE_TYPE_MSG), p3Config(CONFIG_TYPE_MSGS),
mConnMgr(cm), mMsgMtx("p3MsgService"), msgChanged(1), mMsgUniqueId(1)
mLinkMgr(lm), mMsgMtx("p3MsgService"), msgChanged(1), mMsgUniqueId(1)
{
addSerialType(new RsMsgSerialiser());
/* Initialize standard tag types */
if(cm)
if(lm)
initStandardTagTypes();
}
@ -133,7 +133,7 @@ void p3MsgService::processMsg(RsMsgItem *mi)
RsStackMutex stack(mMsgMtx); /*** STACK LOCKED MTX ***/
if (mi -> PeerId() == mConnMgr->getOwnId())
if (mi -> PeerId() == mLinkMgr->getOwnId())
{
/* from the loopback device */
mi -> msgFlags |= RS_MSG_FLAGS_OUTGOING;
@ -207,7 +207,7 @@ int p3MsgService::checkOutgoingMessages()
bool changed = false ;
{
const std::string ownId = mConnMgr->getOwnId();
const std::string ownId = mLinkMgr->getOwnId();
std::list<uint32_t>::iterator it;
std::list<uint32_t> toErase;
@ -225,7 +225,7 @@ int p3MsgService::checkOutgoingMessages()
peerConnectState pstate;
bool toSend = false;
if (mConnMgr->getFriendNetStatus(pid, pstate))
if (mLinkMgr->isOnline(pid))
{
if (pstate.state & RS_PEER_S_CONNECTED)
{
@ -353,7 +353,7 @@ static void getStandardTagTypes(MsgTagType &tags)
void p3MsgService::initStandardTagTypes()
{
bool bChanged = false;
std::string ownId = mConnMgr->getOwnId();
std::string ownId = mLinkMgr->getOwnId();
MsgTagType tags;
getStandardTagTypes(tags);
@ -507,7 +507,7 @@ void p3MsgService::loadWelcomeMsg()
/* Load Welcome Message */
RsMsgItem *msg = new RsMsgItem();
//msg -> PeerId(mConnMgr->getOwnId());
//msg -> PeerId(mLinkMgr->getOwnId());
msg -> sendTime = time(NULL);
msg -> recvTime = time(NULL);
@ -796,7 +796,7 @@ bool p3MsgService::setMsgParentId(uint32_t msgId, uint32_t msgParentId)
{
if (msgParentId) {
RsMsgParentId* msp = new RsMsgParentId();
msp->PeerId (mConnMgr->getOwnId());
msp->PeerId (mLinkMgr->getOwnId());
msp->msgId = msgId;
msp->msgParentId = msgParentId;
mParentId.insert(std::pair<uint32_t, RsMsgParentId*>(msgId, msp));
@ -842,7 +842,7 @@ int p3MsgService::sendMessage(RsMsgItem *item)
/* STORE MsgID */
msgOutgoing[item->msgId] = item;
if (item->PeerId() != mConnMgr->getOwnId()) {
if (item->PeerId() != mLinkMgr->getOwnId()) {
/* not to the loopback device */
RsMsgSrcId* msi = new RsMsgSrcId();
msi->msgId = item->msgId;
@ -891,7 +891,7 @@ bool p3MsgService::MessageSend(MessageInfo &info)
}
/* send to ourselves as well */
RsMsgItem *msg = initMIRsMsg(info, mConnMgr->getOwnId());
RsMsgItem *msg = initMIRsMsg(info, mLinkMgr->getOwnId());
if (msg)
{
/* use processMsg to get the new msgId */
@ -909,7 +909,7 @@ bool p3MsgService::MessageSend(MessageInfo &info)
bool p3MsgService::MessageToDraft(MessageInfo &info, const std::string &msgParentId)
{
RsMsgItem *msg = initMIRsMsg(info, mConnMgr->getOwnId());
RsMsgItem *msg = initMIRsMsg(info, mLinkMgr->getOwnId());
if (msg)
{
uint32_t msgId = 0;
@ -992,7 +992,7 @@ bool p3MsgService::setMessageTagType(uint32_t tagId, std::string& text, uint32
/* new tag */
RsMsgTagType* tagType = new RsMsgTagType();
tagType->PeerId (mConnMgr->getOwnId());
tagType->PeerId (mLinkMgr->getOwnId());
tagType->rgb_color = rgb_color;
tagType->tagId = tagId;
tagType->text = text;
@ -1136,7 +1136,7 @@ bool p3MsgService::setMessageTag(const std::string &msgId, uint32_t tagId, bool
if (set) {
/* new msg */
RsMsgTags* tag = new RsMsgTags();
tag->PeerId (mConnMgr->getOwnId());
tag->PeerId (mLinkMgr->getOwnId());
tag->msgId = mid;
tag->tagIds.push_back(tagId);
@ -1280,7 +1280,7 @@ void p3MsgService::initRsMI(RsMsgItem *msg, MessageInfo &mi)
/* translate flags, if we sent it... outgoing */
if ((msg->msgFlags & RS_MSG_FLAGS_OUTGOING)
|| (msg->PeerId() == mConnMgr->getOwnId()))
|| (msg->PeerId() == mLinkMgr->getOwnId()))
{
mi.msgflags |= RS_MSG_OUTGOING;
}
@ -1379,7 +1379,7 @@ void p3MsgService::initRsMIS(RsMsgItem *msg, MsgInfoSummary &mis)
/* translate flags, if we sent it... outgoing */
if ((msg->msgFlags & RS_MSG_FLAGS_OUTGOING)
|| (msg->PeerId() == mConnMgr->getOwnId()))
|| (msg->PeerId() == mLinkMgr->getOwnId()))
{
mis.msgflags |= RS_MSG_OUTGOING;
}
@ -1456,7 +1456,7 @@ RsMsgItem *p3MsgService::initMIRsMsg(MessageInfo &info, std::string to)
}
/* We don't fill in bcc (unless to ourselves) */
if (to == mConnMgr->getOwnId())
if (to == mLinkMgr->getOwnId())
{
for(pit = info.msgbcc.begin(); pit != info.msgbcc.end(); pit++)
{

View File

@ -43,12 +43,12 @@
#include "serialiser/rsmsgitems.h"
#include "util/rsthreads.h"
class p3ConnectMgr;
class p3LinkMgr;
class p3MsgService: public p3Service, public p3Config, public pqiMonitor
{
public:
p3MsgService(p3ConnectMgr *cm);
p3MsgService(p3LinkMgr *lm);
/* External Interface */
bool MsgsChanged(); /* should update display */
@ -113,7 +113,7 @@ RsMsgItem *initMIRsMsg(MessageInfo &info, std::string to);
void initStandardTagTypes();
p3ConnectMgr *mConnMgr;
p3LinkMgr *mLinkMgr;
/* Mutex Required for stuff below */

View File

@ -27,8 +27,10 @@
#include "services/p3portservice.h"
#include "serialiser/rsserviceids.h"
p3PortService::p3PortService(p3ConnectMgr *cm)
:p3Service(RS_SERVICE_TYPE_PORT), mConnMgr(cm), mEnabled(false)
#include "pqi/p3linkmgr.h"
p3PortService::p3PortService(p3LinkMgr *lm)
:p3Service(RS_SERVICE_TYPE_PORT), mLinkMgr(lm), mEnabled(false)
{
/* For Version 1, we'll just use the very simple RsRawItem packets
* which are handled in the RsServiceSerialiser

View File

@ -59,13 +59,14 @@
#include "serialiser/rsbaseitems.h"
#include "services/p3service.h"
#include "pqi/p3connmgr.h"
class p3LinkMgr;
class p3PortService: public p3Service
{
public:
p3PortService(p3ConnectMgr *cm);
p3PortService(p3LinkMgr *lm);
/* example setup functions */
bool enablePortForwarding(uint32_t port, std::string peerId);
@ -75,7 +76,7 @@ virtual int tick();
private:
p3ConnectMgr *mConnMgr;
p3LinkMgr *mLinkMgr;
bool mEnabled;
bool mPeerOnline;

View File

@ -32,6 +32,8 @@
#include <list>
#include <string>
#include "pqi/p3linkmgr.h"
std::ostream& operator<<(std::ostream& out, const StatusInfo& si)
{
out << "StatusInfo: " << std::endl;
@ -43,8 +45,8 @@ std::ostream& operator<<(std::ostream& out, const StatusInfo& si)
RsStatus *rsStatus = NULL;
p3StatusService::p3StatusService(p3ConnectMgr *cm)
:p3Service(RS_SERVICE_TYPE_STATUS), p3Config(CONFIG_TYPE_STATUS), mConnMgr(cm), mStatusMtx("p3StatusService")
p3StatusService::p3StatusService(p3LinkMgr *cm)
:p3Service(RS_SERVICE_TYPE_STATUS), p3Config(CONFIG_TYPE_STATUS), mLinkMgr(cm), mStatusMtx("p3StatusService")
{
addSerialType(new RsStatusSerialiser());
@ -61,7 +63,7 @@ bool p3StatusService::getOwnStatus(StatusInfo& statusInfo)
#endif
std::map<std::string, StatusInfo>::iterator it;
std::string ownId = mConnMgr->getOwnId();
std::string ownId = mLinkMgr->getOwnId();
RsStackMutex stack(mStatusMtx);
it = mStatusInfoMap.find(ownId);
@ -128,7 +130,7 @@ bool p3StatusService::sendStatus(const std::string &id, uint32_t status)
{
RsStackMutex stack(mStatusMtx);
statusInfo.id = mConnMgr->getOwnId();
statusInfo.id = mLinkMgr->getOwnId();
statusInfo.status = status;
// don't save inactive status
@ -148,7 +150,7 @@ bool p3StatusService::sendStatus(const std::string &id, uint32_t status)
}
if (id.empty()) {
mConnMgr->getOnlineList(onlineList);
mLinkMgr->getOnlineList(onlineList);
} else {
onlineList.push_back(id);
}
@ -257,11 +259,11 @@ bool p3StatusService::saveList(bool& cleanup, std::list<RsItem*>& ilist){
{
RsStackMutex stack(mStatusMtx);
it = mStatusInfoMap.find(mConnMgr->getOwnId());
it = mStatusInfoMap.find(mLinkMgr->getOwnId());
if(it == mStatusInfoMap.end()){
std::cerr << "p3StatusService::saveList() :" << "Did not find your status"
<< mConnMgr->getOwnId() << std::endl;
<< mLinkMgr->getOwnId() << std::endl;
delete own_status;
return false;
}
@ -295,14 +297,14 @@ bool p3StatusService::loadList(std::list<RsItem*>& load){
if(own_status != NULL){
own_info.id = mConnMgr->getOwnId();
own_info.id = mLinkMgr->getOwnId();
own_info.status = own_status->status;
own_info.time_stamp = own_status->sendTime;
delete own_status;
{
RsStackMutex stack(mStatusMtx);
std::pair<std::string, StatusInfo> pr(mConnMgr->getOwnId(), own_info);
std::pair<std::string, StatusInfo> pr(mLinkMgr->getOwnId(), own_info);
mStatusInfoMap.insert(pr);
}

View File

@ -32,7 +32,10 @@
#include "serialiser/rsstatusitems.h"
#include "retroshare/rsstatus.h"
#include "services/p3service.h"
#include "pqi/p3connmgr.h"
#include "pqi/p3cfgmgr.h"
#include "pqi/pqimonitor.h"
class p3LinkMgr;
//! handles standard status messages (busy, away, online, offline) set by user
/*!
@ -45,7 +48,7 @@ class p3StatusService: public p3Service, public p3Config, public pqiMonitor
{
public:
p3StatusService(p3ConnectMgr* );
p3StatusService(p3LinkMgr *lm);
virtual ~p3StatusService();
/***** overloaded from p3Service *****/
@ -90,7 +93,7 @@ virtual bool loadList(std::list<RsItem*>& load);
virtual void receiveStatusQueue();
p3ConnectMgr *mConnMgr;
p3LinkMgr *mLinkMgr;
std::map<std::string, StatusInfo> mStatusInfoMap;

View File

@ -38,6 +38,7 @@
class UdpStack
{
public:
rsUdpStack(int testmode, struct sockaddr_in &local) { return; }
UdpStack(struct sockaddr_in &local) { return; }
/* from pqiNetListener */
@ -57,6 +58,9 @@ class rsUdpStack: public UdpStack, public pqiNetListener
rsUdpStack(struct sockaddr_in &local)
:UdpStack(local) { return; }
rsUdpStack(int testmode, struct sockaddr_in &local)
:UdpStack(testmode, local) { return; }
/* from pqiNetListener */
virtual bool resetListener(struct sockaddr_in &local)
{
@ -69,4 +73,30 @@ virtual bool resetListener(struct sockaddr_in &local)
};
class rsFixedUdpStack: public UdpStack, public pqiNetListener
{
public:
rsFixedUdpStack(struct sockaddr_in &local)
:UdpStack(local) { return; }
rsFixedUdpStack(int testmode, struct sockaddr_in &local)
:UdpStack(testmode, local) { return; }
/* from pqiNetListener */
virtual bool resetListener(struct sockaddr_in &local)
{
struct sockaddr_in addr;
getLocalAddress(addr);
// The const_cast below is not so nice but without it, the compiler can't
// find the correct operator<<(). No idea why!
std::cerr << "rsFixedUdpStack::resetListener(" << const_cast<const struct sockaddr_in &>(local) << ")";
std::cerr << " Resetting with original addr: " << const_cast<const struct sockaddr_in &>(addr);
std::cerr << std::endl;
return resetAddress(addr);
}
};
#endif

View File

@ -213,10 +213,12 @@ int UdpRelayReceiver::checkRelays()
std::cerr << " using bandwidth: " << rit->second.mBandwidth;
std::cerr << std::endl;
if (rit->second.mBandwidth > RELAY_MAX_BANDWIDTH)
if (rit->second.mBandwidth > rit->second.mBandwidthLimit)
{
std::cerr << "UdpRelayReceiver::checkRelays()";
std::cerr << "Dropping Relay due to excessive Bandwidth: " << rit->first;
std::cerr << "UdpRelayReceiver::checkRelays() ";
std::cerr << "Dropping Relay due to excessive Bandwidth: " << rit->second.mBandwidth;
std::cerr << " Exceeding Limit: " << rit->second.mBandwidthLimit;
std::cerr << " Relay: " << rit->first;
std::cerr << std::endl;
/* if exceeding bandwidth -> drop */
@ -225,11 +227,39 @@ int UdpRelayReceiver::checkRelays()
else if (now - rit->second.mLastTS > RELAY_TIMEOUT)
{
/* if haven't transmitted for ages -> drop */
std::cerr << "UdpRelayReceiver::checkRelays()";
std::cerr << "UdpRelayReceiver::checkRelays() ";
std::cerr << "Dropping Relay due to Timeout: " << rit->first;
std::cerr << std::endl;
eraseList.push_back(rit->first);
}
else
{
/* check the length of the relay - we will drop them after a certain amount of time */
int lifetime = 0;
switch(rit->second.mRelayClass)
{
default:
case UDP_RELAY_CLASS_GENERAL:
lifetime = UDP_RELAY_LIFETIME_GENERAL;
break;
case UDP_RELAY_CLASS_FOF:
lifetime = UDP_RELAY_LIFETIME_FOF;
break;
case UDP_RELAY_CLASS_FRIENDS:
lifetime = UDP_RELAY_LIFETIME_FRIENDS;
break;
}
if (now - rit->second.mStartTS > lifetime)
{
std::cerr << "UdpRelayReceiver::checkRelays() ";
std::cerr << "Dropping Relay due to Passing Lifetime Limit: " << lifetime;
std::cerr << " for class: " << rit->second.mRelayClass;
std::cerr << " Relay: " << rit->first;
std::cerr << std::endl;
eraseList.push_back(rit->first);
}
}
}
std::list<UdpRelayAddrSet>::iterator it;
@ -249,7 +279,7 @@ int UdpRelayReceiver::removeUdpRelay(UdpRelayAddrSet *addrSet)
}
int UdpRelayReceiver::addUdpRelay(UdpRelayAddrSet *addrSet, int relayClass)
int UdpRelayReceiver::addUdpRelay(UdpRelayAddrSet *addrSet, int relayClass, uint32_t &bandwidth)
{
RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/
@ -279,6 +309,9 @@ int UdpRelayReceiver::addUdpRelay(UdpRelayAddrSet *addrSet, int relayClass)
mRelays[*addrSet] = udpRelay;
mRelays[alt] = altUdpRelay;
/* grab bandwidth from one set */
bandwidth = altUdpRelay.mBandwidthLimit;
return 1;
}
@ -799,6 +832,9 @@ UdpRelayProxy::UdpRelayProxy()
mLastBandwidthTS = 0;
mLastTS = time(NULL); // Must be set here, otherwise Proxy Timesout before anything can happen!
mRelayClass = 0;
mStartTS = time(NULL);
mBandwidthLimit = 0;
}
UdpRelayProxy::UdpRelayProxy(UdpRelayAddrSet *addrSet, int relayClass)
@ -810,6 +846,22 @@ UdpRelayProxy::UdpRelayProxy(UdpRelayAddrSet *addrSet, int relayClass)
mDataSize = 0;
mLastBandwidthTS = 0;
mLastTS = time(NULL);
mStartTS = time(NULL);
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;
}
}
UdpRelayEnd::UdpRelayEnd()

View File

@ -57,6 +57,9 @@ class UdpRelayProxy
time_t mLastBandwidthTS;
time_t mLastTS;
time_t mStartTS;
double mBandwidthLimit;
int mRelayClass;
};
@ -100,6 +103,15 @@ std::ostream &operator<<(std::ostream &out, const UdpRelayEnd &ure);
#define UDP_RELAY_CLASS_FOF 2
#define UDP_RELAY_CLASS_FRIENDS 3
// 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_FRIENDS 720 // 12 minutes.
#define UDP_RELAY_LIFETIME_GENERAL 1800 // 30 minutes
#define UDP_RELAY_LIFETIME_FOF 3600 // 1 Hour.
#define UDP_RELAY_LIFETIME_FRIENDS 7200 // 2 Hour.
#define STD_RELAY_TTL 64
class UdpRelayReceiver: public UdpSubReceiver
@ -119,7 +131,7 @@ int removeUdpPeer(UdpPeer *peer);
* the end-points drop the connections
*/
int addUdpRelay(UdpRelayAddrSet *addrs, int classIdx);
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 */

View File

@ -23,19 +23,22 @@
*
*/
#include "udpstunner.h"
#include "tcponudp/udpstunner.h"
#include <iostream>
#include <sstream>
#include "util/rsrandom.h"
#include "util/rsprint.h"
static const int STUN_TTL = 64;
#define TOU_STUN_MIN_PEERS 5
#define TOU_STUN_MIN_PEERS 20
/*
* #define DEBUG_UDP_STUNNER 1
* #define DEBUG_UDP_STUNNER_FILTER 1
*/
//#define DEBUG_UDP_STUNNER 1
const int32_t TOU_STUN_MAX_FAIL_COUNT = 3; /* 3 tries (could be higher?) */
@ -54,6 +57,9 @@ UdpStunner::UdpStunner(UdpPublisher *pub)
{
#ifdef UDPSTUN_ALLOW_LOCALNET
mAcceptLocalNet = false;
mSimExclusiveNat = false;
mSimSymmetricNat = false;
mSimUnstableExt = false;
#endif
@ -63,6 +69,10 @@ UdpStunner::UdpStunner(UdpPublisher *pub)
mSuccessRate = 0.0;
mTargetStunPeriod = TOU_STUN_DEFAULT_TARGET_RATE;
mExclusiveMode = false;
mExclusiveModeTS = 0;
mForceRestun = false;
return;
}
@ -76,21 +86,135 @@ void UdpStunner::SetAcceptLocalNet()
mAcceptLocalNet = true;
}
#endif
void UdpStunner::setTargetStunPeriod(uint32_t sec_per_stun)
// For Local Testing Only (Releases should have the #define disabled)
void UdpStunner::SimExclusiveNat()
{
RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/
if (sec_per_stun == 0)
mSimExclusiveNat = true;
mSimUnstableExt = true;
}
void UdpStunner::SimSymmetricNat()
{
RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/
mSimSymmetricNat = true;
mSimUnstableExt = true;
}
#endif
int UdpStunner::grabExclusiveMode() /* returns seconds since last send/recv */
{
RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/
#ifdef DEBUG_UDP_STUNNER_FILTER
std::cerr << "UdpStunner::setExclusiveMode();
std::cerr << std::endl;
#endif
if (mExclusiveMode)
{
mPassiveStunMode = true;
#ifdef DEBUG_UDP_STUNNER_FILTER
std::cerr << "UdpStunner::setExclusiveMode() FAILED;
std::cerr << std::endl;
#endif
return 0;
}
time_t now = time(NULL);
mExclusiveMode = true;
mExclusiveModeTS = now;
int lastcomms = mStunLastRecvAny;
if (mStunLastSendAny > lastcomms)
{
lastcomms = mStunLastSendAny;
}
int commsage = now - lastcomms;
/* cannot return 0, as this indicates error */
if (commsage == 0)
{
commsage = 1;
}
#ifdef DEBUG_UDP_STUNNER_FILTER
std::cerr << "UdpStunner::setExclusiveMode() SUCCESS. last comms: " << commsage;
std::cerr << " ago";
std::cerr << std::endl;
#endif
return commsage;
}
int UdpStunner::releaseExclusiveMode(bool forceStun)
{
RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/
if (!mExclusiveMode)
{
#ifdef DEBUG_UDP_STUNNER_FILTER
std::cerr << "UdpStunner::cancelExclusiveMode() ERROR, not in exclusive Mode";
std::cerr << std::endl;
#endif
return 0;
}
time_t now = time(NULL);
mExclusiveMode = false;
if (forceStun)
{
mForceRestun = true;
}
#ifdef UDPSTUN_ALLOW_LOCALNET
/* if we are simulating an exclusive NAT, then immediately after we release - it'll become unstable.
* In reality, it will only become unstable if we have tried a UDP connection.
* so we use the forceStun parameter (which is true when a UDP connection has been tried).
*/
if ((mSimExclusiveNat) && (forceStun))
{
mSimUnstableExt = true;
}
#endif
#ifdef DEBUG_UDP_STUNNER_FILTER
std::cerr << "UdpStunner::cancelExclusiveMode() Canceled. Was in ExclusiveMode for: " << now - mExclusiveModeTS;
std::cerr << " secs";
std::cerr << std::endl;
#endif
return 1;
}
void UdpStunner::setTargetStunPeriod(int32_t sec_per_stun)
{
RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/
if (sec_per_stun < 0)
{
mPassiveStunMode = false;
mTargetStunPeriod = TOU_STUN_DEFAULT_TARGET_RATE;
}
else
{
mPassiveStunMode = false;
if (sec_per_stun == 0)
{
mPassiveStunMode = true;
}
else
{
mPassiveStunMode = false;
}
mTargetStunPeriod = sec_per_stun;
}
mTargetStunPeriod = sec_per_stun;
}
@ -98,7 +222,7 @@ void UdpStunner::setTargetStunPeriod(uint32_t sec_per_stun)
int UdpStunner::recvPkt(void *data, int size, struct sockaddr_in &from)
{
/* print packet information */
#ifdef DEBUG_UDP_STUNNER
#ifdef DEBUG_UDP_STUNNER_FILTER
std::cerr << "UdpStunner::recvPkt(" << size << ") from: " << from;
std::cerr << std::endl;
#endif
@ -109,7 +233,7 @@ int UdpStunner::recvPkt(void *data, int size, struct sockaddr_in &from)
if (UdpStun_isStunPacket(data, size))
{
mStunLastRecvAny = time(NULL);
#ifdef DEBUG_UDP_STUNNER
#ifdef DEBUG_UDP_STUNNER_FILTER
std::cerr << "UdpStunner::recvPkt() is Stun Packet";
std::cerr << std::endl;
#endif
@ -153,6 +277,9 @@ int UdpStunner::tick()
if (checkStunDesired())
{
attemptStun();
#ifdef DEBUG_UDP_STUNNER
status(std::cerr);
#endif
}
return 1;
@ -225,12 +352,23 @@ bool UdpStunner::externalAddr(struct sockaddr_in &external, uint8_t &stable)
if (eaddrKnown)
{
/* address timeout */
if (time(NULL) - eaddrTime > (mTargetStunPeriod * 2))
/* address timeout
* no timeout if in exclusive mode
*/
if ((time(NULL) - eaddrTime > (mTargetStunPeriod * 2)) && (!mExclusiveMode))
{
std::cerr << "UdpStunner::externalAddr() eaddr expired";
std::cerr << std::endl;
eaddrKnown = false;
return false;
}
/* Force Restun is triggered after an Exclusive Mode... as Ext Address is likely to have changed
* Until the Restun has got an address - we act as if we don't have an external address
*/
if (mForceRestun)
{
return false;
}
@ -247,6 +385,7 @@ bool UdpStunner::externalAddr(struct sockaddr_in &external, uint8_t &stable)
std::cerr << std::endl;
#endif
return true;
}
#ifdef DEBUG_UDP_STUNNER
@ -331,7 +470,7 @@ bool UdpStun_response(void *stun_pkt, int size, struct sockaddr_in &addr)
addr.sin_port = ((uint16_t *) stun_pkt)[11];
#ifdef DEBUG_UDP_STUNNER
#ifdef DEBUG_UDP_STUNNER_FILTER
std::ostringstream out;
out << "UdpStunner::response() Recvd a Stun Response, ext_addr: ";
out << inet_ntoa(addr.sin_addr) << ":" << ntohs(addr.sin_port);
@ -390,14 +529,14 @@ void *UdpStun_generate_stun_reply(struct sockaddr_in *stun_addr, int *len)
bool UdpStun_isStunPacket(void *data, int size)
{
#ifdef DEBUG_UDP_STUNNER
#ifdef DEBUG_UDP_STUNNER_FILTER
std::cerr << "UdpStunner::isStunPacket() ?";
std::cerr << std::endl;
#endif
if (size < 20)
{
#ifdef DEBUG_UDP_STUNNER
#ifdef DEBUG_UDP_STUNNER_FILTER
std::cerr << "UdpStunner::isStunPacket() (size < 20) -> false";
std::cerr << std::endl;
#endif
@ -408,7 +547,7 @@ bool UdpStun_isStunPacket(void *data, int size)
uint16_t pktsize = ntohs(((uint16_t *) data)[1]);
if (size != pktsize)
{
#ifdef DEBUG_UDP_STUNNER
#ifdef DEBUG_UDP_STUNNER_FILTER
std::cerr << "UdpStunner::isStunPacket() (size != pktsize) -> false";
std::cerr << std::endl;
#endif
@ -417,7 +556,7 @@ bool UdpStun_isStunPacket(void *data, int size)
if ((size == 20) && (0x0001 == ntohs(((uint16_t *) data)[0])))
{
#ifdef DEBUG_UDP_STUNNER
#ifdef DEBUG_UDP_STUNNER_FILTER
std::cerr << "UdpStunner::isStunPacket() (size=20 & data[0]=0x0001) -> true";
std::cerr << std::endl;
#endif
@ -427,7 +566,7 @@ bool UdpStun_isStunPacket(void *data, int size)
if ((size == 28) && (0x0101 == ntohs(((uint16_t *) data)[0])))
{
#ifdef DEBUG_UDP_STUNNER
#ifdef DEBUG_UDP_STUNNER_FILTER
std::cerr << "UdpStunner::isStunPacket() (size=28 & data[0]=0x0101) -> true";
std::cerr << std::endl;
#endif
@ -537,13 +676,28 @@ bool UdpStunner::checkStunDesired()
return false; /* all good */
}
if (mExclusiveMode)
{
return false; /* no pings in exclusive mode */
}
if (mForceRestun)
{
return true;
}
if (!eaddrKnown)
{
/* check properly! (this will limit it to two successful stuns) */
if (!locked_checkExternalAddress())
{
#ifdef DEBUG_UDP_STUNNER
std::cerr << "UdpStunner::checkStunDesired() YES, we don't have extAddr Yet";
std::cerr << std::endl;
std::cerr << "UdpStunner::checkStunDesired() YES, we don't have extAddr Yet";
std::cerr << std::endl;
#endif
return true; /* want our external address */
return true; /* want our external address */
}
}
/* check if we need to send one now */
@ -554,8 +708,11 @@ bool UdpStunner::checkStunDesired()
* if we have 100% success rate, then we can delay until exactly TARGET RATE.
* if we have 0% success rate, then try at double TARGET RATE.
*
* generalised to a rate_scale parameter below...
*/
double stunPeriod = (mTargetStunPeriod / 2.0) * (1.0 + mSuccessRate);
#define RATE_SCALE (3.0)
double stunPeriod = (mTargetStunPeriod / (RATE_SCALE)) * (1.0 + mSuccessRate * (RATE_SCALE - 1.0));
time_t nextStun = mStunLastRecvResp + (int) stunPeriod;
#ifdef DEBUG_UDP_STUNNER
@ -679,6 +836,23 @@ bool UdpStunner::locked_recvdStun(const struct sockaddr_in &remote, const str
std::cerr << out.str() << std::endl;
#endif
#ifdef UDPSTUN_ALLOW_LOCALNET
struct sockaddr_in fakeExtaddr = extaddr;
if (mSimUnstableExt)
{
std::cerr << "UdpStunner::locked_recvdStun() TEST SIM UNSTABLE EXT: Forcing Port to be wrong to sim an ExclusiveNat";
std::cerr << std::endl;
#define UNSTABLE_PORT_RANGE 100
fakeExtaddr.sin_port = htons(ntohs(fakeExtaddr.sin_port) - (UNSTABLE_PORT_RANGE / 2) + RSRandom::random_u32() % UNSTABLE_PORT_RANGE);
if (!mSimSymmetricNat)
{
mSimUnstableExt = false;
}
}
#endif
bool found = true;
std::list<TouStunPeer>::iterator it;
for(it = mStunList.begin(); it != mStunList.end(); it++)
@ -687,7 +861,11 @@ bool UdpStunner::locked_recvdStun(const struct sockaddr_in &remote, const str
(remote.sin_port == it->remote.sin_port))
{
it->failCount = 0;
#ifdef UDPSTUN_ALLOW_LOCALNET
it->eaddr = fakeExtaddr;
#else
it->eaddr = extaddr;
#endif
it->response = true;
found = true;
@ -695,6 +873,12 @@ bool UdpStunner::locked_recvdStun(const struct sockaddr_in &remote, const str
}
}
/* We've received a Stun, so the ForceStun can be cancelled */
if (found)
{
mForceRestun = false;
}
/* if not found.. should we add it back in? */
/* How do we calculate the success rate?
@ -722,7 +906,10 @@ bool UdpStunner::locked_recvdStun(const struct sockaddr_in &remote, const str
locked_printStunList();
#endif
locked_checkExternalAddress();
if (!mExclusiveMode)
{
locked_checkExternalAddress();
}
return found;
}

View File

@ -68,9 +68,12 @@ class TouStunPeer
};
/*
* FOR TESTING ONLY.
* #define UDPSTUN_ALLOW_LOCALNET 1
*/
#define UDPSTUN_ALLOW_LOCALNET 1
class UdpStunner: public UdpSubReceiver
{
public:
@ -81,9 +84,15 @@ virtual ~UdpStunner() { return; }
#ifdef UDPSTUN_ALLOW_LOCALNET
// For Local Testing Mode.
void SetAcceptLocalNet();
void SimExclusiveNat();
void SimSymmetricNat();
#endif
void setTargetStunPeriod(uint32_t sec_per_stun);
int grabExclusiveMode(); /* returns seconds since last send/recv */
int releaseExclusiveMode(bool forceStun);
void setTargetStunPeriod(int32_t sec_per_stun);
bool addStunPeer(const struct sockaddr_in &remote, const char *peerid);
bool getStunPeer(int idx, std::string &id,
struct sockaddr_in &remote, struct sockaddr_in &eaddr,
@ -135,12 +144,20 @@ bool locked_checkExternalAddress();
#ifdef UDPSTUN_ALLOW_LOCALNET
// For Local Testing Mode.
bool mAcceptLocalNet;
bool mSimUnstableExt;
bool mSimExclusiveNat;
bool mSimSymmetricNat;
#endif
bool mPassiveStunMode;
uint32_t mTargetStunPeriod;
double mSuccessRate;
bool mExclusiveMode; /* when this is switched on, the stunner stays silent (and extAddr is maintained) */
time_t mExclusiveModeTS;
bool mForceRestun;
};
/* generic stun functions */

View File

@ -37,7 +37,7 @@
#include "retroshare/rsfiles.h"
#include "pqi/authssl.h"
#include "pqi/p3connmgr.h"
#include "pqi/p3linkmgr.h"
#include "pqi/pqinotify.h"
#include "ft/ftserver.h"
@ -87,8 +87,8 @@ static const time_t TUNNEL_CLEANING_LAPS_TIME = 10 ; /// clean tunnels every
static const uint32_t MAX_TUNNEL_REQS_PER_SECOND= 1 ; /// maximum number of tunnel requests issued per second. Was 0.5 before
static const uint32_t MAX_ALLOWED_SR_IN_CACHE = 120 ; /// maximum number of search requests allowed in cache. That makes 2 per sec.
p3turtle::p3turtle(p3ConnectMgr *cm,ftServer *fs)
:p3Service(RS_SERVICE_TYPE_TURTLE), p3Config(CONFIG_TYPE_TURTLE), mConnMgr(cm), mTurtleMtx("p3turtle")
p3turtle::p3turtle(p3LinkMgr *lm,ftServer *fs)
:p3Service(RS_SERVICE_TYPE_TURTLE), p3Config(CONFIG_TYPE_TURTLE), mLinkMgr(lm), mTurtleMtx("p3turtle")
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
@ -474,7 +474,7 @@ void p3turtle::locked_closeTunnel(TurtleTunnelId tid,std::vector<std::pair<Turtl
std::cerr << "p3turtle: Closing tunnel " << (void*)tid << std::endl ;
#endif
if(it->second.local_src == mConnMgr->getOwnId()) // this is a starting tunnel. We thus remove
if(it->second.local_src == mLinkMgr->getOwnId()) // this is a starting tunnel. We thus remove
// - the virtual peer from the vpid list
// - the tunnel id from the file hash
// - the virtual peer from the file sources in the file transfer controller.
@ -516,7 +516,7 @@ void p3turtle::locked_closeTunnel(TurtleTunnelId tid,std::vector<std::pair<Turtl
++i ;
}
}
else if(it->second.local_dst == mConnMgr->getOwnId()) // This is a ending tunnel. We also remove the virtual peer id
else if(it->second.local_dst == mLinkMgr->getOwnId()) // This is a ending tunnel. We also remove the virtual peer id
{
#ifdef P3TURTLE_DEBUG
std::cerr << " Tunnel is a ending point. Also removing associated outgoing hash." ;
@ -625,7 +625,7 @@ uint32_t p3turtle::generatePersonalFilePrint(const TurtleFileHash& hash,bool b)
// The only important thing is that the saem couple (hash,SSL id) produces the same tunnel
// id. The result uses a boolean to allow generating non symmetric tunnel ids.
std::string buff(hash + mConnMgr->getOwnId()) ;
std::string buff(hash + mLinkMgr->getOwnId()) ;
uint32_t res = 0 ;
uint32_t decal = 0 ;
@ -733,7 +733,7 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item)
// If it's not for us, perform a local search. If something found, forward the search result back.
if(item->PeerId() != mConnMgr->getOwnId())
if(item->PeerId() != mLinkMgr->getOwnId())
{
#ifdef P3TURTLE_DEBUG
std::cerr << " Request not from us. Performing local search" << std::endl ;
@ -797,7 +797,7 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item)
if(item->depth < TURTLE_MAX_SEARCH_DEPTH || random_bypass)
{
std::list<std::string> onlineIds ;
mConnMgr->getOnlineList(onlineIds);
mLinkMgr->getOnlineList(onlineIds);
#ifdef P3TURTLE_DEBUG
std::cerr << " Looking for online peers" << std::endl ;
#endif
@ -846,7 +846,7 @@ void p3turtle::handleSearchResult(RsTurtleSearchResultItem *item)
++(item->depth) ; // increase depth
if(it->second.origin == mConnMgr->getOwnId())
if(it->second.origin == mLinkMgr->getOwnId())
returnSearchResult(item) ; // Yes, so send upward.
else
{ // Nope, so forward it back.
@ -906,7 +906,7 @@ void p3turtle::routeGenericTunnelItem(RsTurtleGenericTunnelItem *item)
// Let's figure out whether this packet is for us or not.
if(direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT && tunnel.local_src != mConnMgr->getOwnId())
if(direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT && tunnel.local_src != mLinkMgr->getOwnId())
{
#ifdef P3TURTLE_DEBUG
std::cerr << " Forwarding generic item to peer " << tunnel.local_src << std::endl ;
@ -919,7 +919,7 @@ void p3turtle::routeGenericTunnelItem(RsTurtleGenericTunnelItem *item)
return ;
}
if(direction == RsTurtleGenericTunnelItem::DIRECTION_SERVER && tunnel.local_dst != mConnMgr->getOwnId())
if(direction == RsTurtleGenericTunnelItem::DIRECTION_SERVER && tunnel.local_dst != mLinkMgr->getOwnId())
{
#ifdef P3TURTLE_DEBUG
std::cerr << " Forwarding generic item to peer " << tunnel.local_dst << std::endl ;
@ -1321,7 +1321,7 @@ void p3turtle::sendChunkMapRequest(const std::string& peerId,const std::string&
RsTurtleFileMapRequestItem *item = new RsTurtleFileMapRequestItem ;
item->tunnel_id = tunnel_id ;
std::string ownid = mConnMgr->getOwnId() ;
std::string ownid = mLinkMgr->getOwnId() ;
if(tunnel.local_src == ownid)
{
@ -1368,7 +1368,7 @@ void p3turtle::sendChunkMap(const std::string& peerId,const std::string& ,const
item->tunnel_id = tunnel_id ;
item->compressed_map = cmap ;
std::string ownid = mConnMgr->getOwnId() ;
std::string ownid = mLinkMgr->getOwnId() ;
if(tunnel.local_src == ownid)
{
@ -1491,9 +1491,9 @@ bool p3turtle::isOnline(const std::string& peer_id) const
TurtleRequestId p3turtle::diggTunnel(const TurtleFileHash& hash)
{
#ifdef P3TURTLE_DEBUG
std::cerr << "DiggTunnel: performing tunnel request. OwnId = " << mConnMgr->getOwnId() << " for hash=" << hash << std::endl ;
std::cerr << "DiggTunnel: performing tunnel request. OwnId = " << mLinkMgr->getOwnId() << " for hash=" << hash << std::endl ;
#endif
while(mConnMgr->getOwnId() == "")
while(mLinkMgr->getOwnId() == "")
{
std::cerr << "... waiting for connect manager to form own id." << std::endl ;
#ifdef WIN32
@ -1517,7 +1517,7 @@ TurtleRequestId p3turtle::diggTunnel(const TurtleFileHash& hash)
//
RsTurtleOpenTunnelItem *item = new RsTurtleOpenTunnelItem ;
item->PeerId(mConnMgr->getOwnId()) ;
item->PeerId(mLinkMgr->getOwnId()) ;
item->file_hash = hash ;
item->request_id = id ;
item->partial_tunnel_id = generatePersonalFilePrint(hash,true) ;
@ -1651,7 +1651,7 @@ void p3turtle::handleTunnelRequest(RsTurtleOpenTunnelItem *item)
bool found = false ;
FileInfo info ;
if(item->PeerId() != mConnMgr->getOwnId())
if(item->PeerId() != mLinkMgr->getOwnId())
{
#ifdef P3TURTLE_DEBUG
std::cerr << " Request not from us. Performing local search" << std::endl ;
@ -1681,7 +1681,7 @@ void p3turtle::handleTunnelRequest(RsTurtleOpenTunnelItem *item)
TurtleTunnel tt ;
tt.local_src = item->PeerId() ;
tt.hash = item->file_hash ;
tt.local_dst = mConnMgr->getOwnId() ; // this means us
tt.local_dst = mLinkMgr->getOwnId() ; // this means us
tt.time_stamp = time(NULL) ;
tt.transfered_bytes = 0 ;
tt.speed_Bps = 0.0f ;
@ -1712,7 +1712,7 @@ void p3turtle::handleTunnelRequest(RsTurtleOpenTunnelItem *item)
if(item->depth < TURTLE_MAX_SEARCH_DEPTH || random_bypass)
{
std::list<std::string> onlineIds ;
mConnMgr->getOnlineList(onlineIds);
mLinkMgr->getOnlineList(onlineIds);
#ifdef P3TURTLE_DEBUG
std::cerr << " Forwarding tunnel request: Looking for online peers" << std::endl ;
#endif
@ -1804,7 +1804,7 @@ void p3turtle::handleTunnelResult(RsTurtleTunnelOkItem *item)
// Is this result's target actually ours ?
if(it->second.origin == mConnMgr->getOwnId())
if(it->second.origin == mLinkMgr->getOwnId())
{
#ifdef P3TURTLE_DEBUG
std::cerr << " Tunnel starting point. Storing id=" << (void*)item->tunnel_id << " for hash (unknown) and tunnel request id " << it->second.origin << std::endl;
@ -1949,9 +1949,9 @@ TurtleRequestId p3turtle::turtleSearch(const std::string& string_to_match)
RsTurtleStringSearchRequestItem *item = new RsTurtleStringSearchRequestItem ;
#ifdef P3TURTLE_DEBUG
std::cerr << "performing search. OwnId = " << mConnMgr->getOwnId() << std::endl ;
std::cerr << "performing search. OwnId = " << mLinkMgr->getOwnId() << std::endl ;
#endif
while(mConnMgr->getOwnId() == "")
while(mLinkMgr->getOwnId() == "")
{
std::cerr << "... waitting for connect manager to form own id." << std::endl ;
#ifdef WIN32
@ -1961,7 +1961,7 @@ TurtleRequestId p3turtle::turtleSearch(const std::string& string_to_match)
#endif
}
item->PeerId(mConnMgr->getOwnId()) ;
item->PeerId(mLinkMgr->getOwnId()) ;
item->match_string = string_to_match ;
item->request_id = id ;
item->depth = 0 ;
@ -1985,9 +1985,9 @@ TurtleRequestId p3turtle::turtleSearch(const LinearizedExpression& expr)
RsTurtleRegExpSearchRequestItem *item = new RsTurtleRegExpSearchRequestItem ;
#ifdef P3TURTLE_DEBUG
std::cerr << "performing search. OwnId = " << mConnMgr->getOwnId() << std::endl ;
std::cerr << "performing search. OwnId = " << mLinkMgr->getOwnId() << std::endl ;
#endif
while(mConnMgr->getOwnId() == "")
while(mLinkMgr->getOwnId() == "")
{
std::cerr << "... waitting for connect manager to form own id." << std::endl ;
#ifdef WIN32
@ -1997,7 +1997,7 @@ TurtleRequestId p3turtle::turtleSearch(const LinearizedExpression& expr)
#endif
}
item->PeerId(mConnMgr->getOwnId()) ;
item->PeerId(mLinkMgr->getOwnId()) ;
item->expr = expr ;
item->request_id = id ;
item->depth = 0 ;

View File

@ -153,7 +153,7 @@
//#define TUNNEL_STATISTICS
class ftServer ;
class p3ConnectMgr;
class p3LinkMgr;
class ftDataMultiplex;
class RsSerialiser;
@ -214,7 +214,7 @@ class TurtleFileHashInfo
class p3turtle: public p3Service, /*public pqiMonitor,*/ public RsTurtle,/* public ftSearch */ public p3Config
{
public:
p3turtle(p3ConnectMgr *cm,ftServer *m);
p3turtle(p3LinkMgr *lm,ftServer *m);
// Lauches a search request through the pipes, and immediately returns
// the request id, which will be further used by the gui to store results
@ -371,7 +371,7 @@ class p3turtle: public p3Service, /*public pqiMonitor,*/ public RsTurtle,/* publ
//--------------------------- Local variables --------------------------------//
/* data */
p3ConnectMgr *mConnMgr;
p3LinkMgr *mLinkMgr;
ftServer *_ft_server ;
ftController *_ft_controller ;

View File

@ -346,9 +346,11 @@ HEADERS += rshare.h \
gui/feeds/SubFileItem.h \
gui/feeds/SubDestItem.h \
gui/feeds/AttachFileItem.h \
gui/feeds/SecurityItem.h \
gui/connect/ConnectFriendWizard.h \
gui/groups/CreateGroup.h \
gui/dht/DhtWindow.h
gui/dht/DhtWindow.h \
gui/GetStartedDialog.h
FORMS += gui/StartDialog.ui \
@ -427,11 +429,13 @@ FORMS += gui/StartDialog.ui \
gui/feeds/SubFileItem.ui \
gui/feeds/SubDestItem.ui \
gui/feeds/AttachFileItem.ui \
gui/feeds/SecurityItem.ui \
gui/im_history/ImHistoryBrowser.ui \
gui/groups/CreateGroup.ui \
gui/common/GroupTreeWidget.ui \
gui/style/StyleDialog.ui \
gui/dht/DhtWindow.ui
gui/dht/DhtWindow.ui \
gui/GetStartedDialog.ui
SOURCES += main.cpp \
rshare.cpp \
@ -585,9 +589,11 @@ SOURCES += main.cpp \
gui/feeds/SubFileItem.cpp \
gui/feeds/SubDestItem.cpp \
gui/feeds/AttachFileItem.cpp \
gui/feeds/SecurityItem.cpp \
gui/connect/ConnectFriendWizard.cpp \
gui/groups/CreateGroup.cpp \
gui/dht/DhtWindow.cpp
gui/dht/DhtWindow.cpp \
gui/GetStartedDialog.cpp
RESOURCES += gui/images.qrc lang/lang.qrc gui/help/content/content.qrc

View File

@ -0,0 +1,171 @@
/****************************************************************
* RetroShare is distributed under the following license:
*
* Copyright (C) 2011, drbob
*
* 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 "gui/GetStartedDialog.h"
#include "retroshare/rsconfig.h"
#include "gui/RsAutoUpdatePage.h"
#include <iostream>
/** Constructor */
GetStartedDialog::GetStartedDialog(QWidget *parent)
: MainPage(parent)
{
/* Invoke the Qt Designer generated object setup routine */
ui.setupUi(this);
/* we use a flag to setup the GettingStarted Flags, so that RS has a bit of time to initialise itself
*/
mFirstShow = true;
connect(ui.inviteCheckBox, SIGNAL(stateChanged( int )), this, SLOT(tickInviteChanged()));
connect(ui.addCheckBox, SIGNAL(stateChanged( int )), this, SLOT(tickAddChanged()));
connect(ui.connectCheckBox, SIGNAL(stateChanged( int )), this, SLOT(tickConnectChanged()));
connect(ui.firewallCheckBox, SIGNAL(stateChanged( int )), this, SLOT(tickFirewallChanged()));
/* Hide platform specific features */
#ifdef Q_WS_WIN
#endif
}
GetStartedDialog::~GetStartedDialog()
{
}
void GetStartedDialog::changeEvent(QEvent *e)
{
switch (e->type()) {
case QEvent::LanguageChange:
ui.retranslateUi(this);
break;
default:
break;
}
}
void GetStartedDialog::showEvent ( QShowEvent * event )
{
/* do nothing if locked, or not visible */
if (RsAutoUpdatePage::eventsLocked() == true)
{
std::cerr << "GetStartedDialog::showEvent() events Are Locked" << std::endl;
return;
}
if ((mFirstShow) && (rsConfig))
{
RsAutoUpdatePage::lockAllEvents();
updateFromUserLevel();
mFirstShow = false;
RsAutoUpdatePage::unlockAllEvents() ;
}
}
void GetStartedDialog::updateFromUserLevel()
{
uint32_t userLevel = RSCONFIG_USER_LEVEL_NEW;
userLevel = rsConfig->getUserLevel();
ui.inviteCheckBox->setChecked(false);
ui.addCheckBox->setChecked(false);
ui.connectCheckBox->setChecked(false);
ui.firewallCheckBox->setChecked(false);
switch(userLevel)
{
// FALLS THROUGH EVERYWHERE.
case RSCONFIG_USER_LEVEL_POWER:
case RSCONFIG_USER_LEVEL_OVERRIDE:
ui.firewallCheckBox->setChecked(true);
case RSCONFIG_USER_LEVEL_CASUAL:
ui.connectCheckBox->setChecked(true);
case RSCONFIG_USER_LEVEL_BASIC:
ui.addCheckBox->setChecked(true);
ui.inviteCheckBox->setChecked(true);
default:
case RSCONFIG_USER_LEVEL_NEW:
break;
}
/* will this auto trigger changes? */
}
void GetStartedDialog::tickInviteChanged()
{
if (ui.inviteCheckBox->isChecked())
{
ui.inviteTextBrowser->setVisible(false);
}
else
{
ui.inviteTextBrowser->setVisible(true);
}
}
void GetStartedDialog::tickAddChanged()
{
if (ui.addCheckBox->isChecked())
{
ui.addTextBrowser->setVisible(false);
}
else
{
ui.addTextBrowser->setVisible(true);
}
}
void GetStartedDialog::tickConnectChanged()
{
if (ui.connectCheckBox->isChecked())
{
ui.connectTextBrowser->setVisible(false);
}
else
{
ui.connectTextBrowser->setVisible(true);
}
}
void GetStartedDialog::tickFirewallChanged()
{
if (ui.firewallCheckBox->isChecked())
{
ui.firewallTextBrowser->setVisible(false);
}
else
{
ui.firewallTextBrowser->setVisible(true);
}
}

View File

@ -0,0 +1,68 @@
/****************************************************************
* RetroShare is distributed under the following license:
*
* Copyright (C) 2011, drbob
*
* 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 _GETTING_STARTED_DIALOG_H
#define _GETTING_STARTED_DIALOG_H
//#include <retroshare/rstypes.h>
#include "ui_GetStartedDialog.h"
#include "mainpage.h"
class GetStartedDialog : public MainPage
{
Q_OBJECT
public:
/** Default Constructor */
GetStartedDialog(QWidget *parent = 0);
/** Default Destructor */
~GetStartedDialog();
/*** signals: ***/
protected:
// Overloaded to get first show!
virtual void showEvent ( QShowEvent * event );
virtual void changeEvent(QEvent *e);
private slots:
void tickInviteChanged();
void tickAddChanged();
void tickConnectChanged();
void tickFirewallChanged();
private:
void updateFromUserLevel();
bool mFirstShow;
private:
/** Qt Designer generated object */
Ui::GetStartedDialog ui;
};
#endif

View File

@ -0,0 +1,865 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GetStartedDialog</class>
<widget class="QWidget" name="GetStartedDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>709</width>
<height>688</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Button">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>208</red>
<green>208</green>
<blue>208</blue>
</color>
</brush>
</colorrole>
<colorrole role="Light">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Midlight">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>247</red>
<green>247</green>
<blue>247</blue>
</color>
</brush>
</colorrole>
<colorrole role="Dark">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>104</red>
<green>104</green>
<blue>104</blue>
</color>
</brush>
</colorrole>
<colorrole role="Mid">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>139</red>
<green>139</green>
<blue>139</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="BrightText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>240</red>
<green>240</green>
<blue>240</blue>
</color>
</brush>
</colorrole>
<colorrole role="Shadow">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Highlight">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
<colorrole role="HighlightedText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Link">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="LinkVisited">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="AlternateBase">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>231</red>
<green>231</green>
<blue>231</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Button">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>208</red>
<green>208</green>
<blue>208</blue>
</color>
</brush>
</colorrole>
<colorrole role="Light">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Midlight">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>247</red>
<green>247</green>
<blue>247</blue>
</color>
</brush>
</colorrole>
<colorrole role="Dark">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>104</red>
<green>104</green>
<blue>104</blue>
</color>
</brush>
</colorrole>
<colorrole role="Mid">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>139</red>
<green>139</green>
<blue>139</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="BrightText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>240</red>
<green>240</green>
<blue>240</blue>
</color>
</brush>
</colorrole>
<colorrole role="Shadow">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Highlight">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>192</red>
<green>192</green>
<blue>192</blue>
</color>
</brush>
</colorrole>
<colorrole role="HighlightedText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Link">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="LinkVisited">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="AlternateBase">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>231</red>
<green>231</green>
<blue>231</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Button">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>208</red>
<green>208</green>
<blue>208</blue>
</color>
</brush>
</colorrole>
<colorrole role="Light">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Midlight">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>247</red>
<green>247</green>
<blue>247</blue>
</color>
</brush>
</colorrole>
<colorrole role="Dark">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>104</red>
<green>104</green>
<blue>104</blue>
</color>
</brush>
</colorrole>
<colorrole role="Mid">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>139</red>
<green>139</green>
<blue>139</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="BrightText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>240</red>
<green>240</green>
<blue>240</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>240</red>
<green>240</green>
<blue>240</blue>
</color>
</brush>
</colorrole>
<colorrole role="Shadow">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Highlight">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
<colorrole role="HighlightedText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Link">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="LinkVisited">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="AlternateBase">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>231</red>
<green>231</green>
<blue>231</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>8</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
<underline>false</underline>
<strikeout>false</strikeout>
</font>
</property>
<property name="contextMenuPolicy">
<enum>Qt::NoContextMenu</enum>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="GetStartedTab">
<attribute name="title">
<string>Getting Started</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>675</width>
<height>637</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="spacing">
<number>0</number>
</property>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QCheckBox" name="inviteCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>2</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>Invite Friends</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Launch Friend Wizard</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QTextBrowser" name="inviteTextBrowser">
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Arial'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:14pt;&quot;&gt;Invite You friends to Join Retroshare.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:14pt;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:14pt;&quot;&gt;Send them an Email with your Certificate.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:14pt;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:14pt;&quot;&gt;Get them to send you their Certificate in Return.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QCheckBox" name="addCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>2</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>Add Your Friends to Retroshare</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="pushButton_4">
<property name="text">
<string>Launch Friend Wizard</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QTextBrowser" name="addTextBrowser">
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Arial'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:14pt;&quot;&gt;Add you Friends to Retroshare.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:14pt;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:14pt;&quot;&gt;When you receive their certificate, &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:14pt;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:14pt;&quot;&gt;Past it into the Box and click Okay.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_2">
<property name="horizontalSpacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QCheckBox" name="connectCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>2</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>Connect To Friends</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="pushButton_2">
<property name="text">
<string>Launch Friend Wizard</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QTextBrowser" name="connectTextBrowser">
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Arial'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:14pt;&quot;&gt;Be Online at the same time&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:14pt;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:14pt;&quot;&gt;And Retroshare will Automatically connect you together!&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:14pt;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:14pt;&quot;&gt;If it never works... check the FAQ for more hints&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QCheckBox" name="firewallCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>2</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>Advanced: Open Firewall Port</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="pushButton_3">
<property name="text">
<string>Launch Friend Wizard</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QTextBrowser" name="firewallTextBrowser">
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Arial'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:14pt;&quot;&gt;If you want High Speed Transfers and to become a Power User.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:14pt;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:14pt;&quot;&gt;You need an Open External Port, so your friends can connect directly to you.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:14pt;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:14pt;&quot;&gt;The easiest way to do this is to Enable the Option on you Router.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:14pt;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:14pt;&quot;&gt;More Help is Here:&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="FAQTab">
<attribute name="title">
<string>Frequently Asked Questions</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QTextBrowser" name="textBrowser">
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Arial'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;1-1_What.E2.80.99s_so_great_about_RetroShare_Instant_Messenger_anyways.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-1 Whats so great about RetroShare anyways?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;RetroShare combines Chatting and Instant Messaging with your friends and filesharing. You have only connections to your trusted friends, not to every peer, so it is secure and safe. All is serverless, opensource and encrypted. You can search for files, which all your friends share. With turtle hopping even the friends of your friends can provide files while staying connected only to your trusted direct neighboring friends. Channels allow sending messages and recommending files to select groups of friends. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;1-2_Why_would_I_want_to_share_using_RetroShare_Instant_Messenger.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-2 Why would I want to share using RetroShare?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;RetroShare Instant Messenger allows you to share information and files with only the people you want to allow. We use it to access information when away from home, and to share stuff with friends. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;1-3_What_is_a_Friends-to-Friends_network.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-3 What is a Friends-to-Friends network?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Friend to Friend (F2F) is the new paradigm after peer-to-peer (P2P). While P2P connected you for sharing with neighbors all over the world, F2F maintains connections only to your trusted friends as neighbors. See the Wikipedia for F2F, linked in our Link-Section. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;1-4_How_many_people_are_required_for_a_working_RetroShare_friendslist_network.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-4 How many people are required for a working RetroShare friendslist network?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Because RetroShare Instant Messenger is a private filesharing network, it doesn't really matter how many people use RetroShare, the network will function well with only a couple of friends in the Messenger. Of course, the amount of material and the network availability both improve as your friendlist grows. Remember that a RetroShare connection allows direct secure communication only between the two peers/friends, and no one else. The amount of available shared files increases as you Instant Message with RetroShare to more and more friends. As you connect to more people the AutoDiscovery system introduces you to the friends of friends. You can accept or deny to connect to friends of friends (one hop only is offered!!) This allows the network to expand and develop if you have not enough friends to be your trusted friends. But it is recommended to tell all your friends to Chat with RetroShare, because then you have enough trusted direct friends and do not rely on friends of friends to keep the network up. Just tell your friends and commit each other to be constant online with RetroShare, then you have always only trusted friends online. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;1-5_How_can_I_make_sure_I_have_the_best_connection_possible.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-5 How can I make sure I have the best connection possible?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Once you have swapped your PQI-Certificate with your friend and both AUTHenticated the friend (and if port and IP and firewall and router settings are okay) you connect automatically each online-session with your friend. Just make this set up once and you always connect automatically to your friend again in a secure and serverless way. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;1-6_How_can_RetroShare_claim_the_best_possible_connection_speed.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-6 How can RetroShare claim the best possible connection speed?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;You have really great download speeds at RetroShare, as they are private, encrypted and direct connections. The transfer from you to your friends depends of course on your upload speed. So ask your provider how fast you can upload. And: You can set in options the upload speed and the maximum speed for a transfer for a single friend. So have a look there to increase the bandwidth and ask your friend as well to grant you more speed as set by default. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;1-7_Is_RetroShare_safe_and_secure.3F_Does_anyone_else_know.2C_what_I.C2.B4m_sharing.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-7 Is RetroShare safe and secure? Does anyone else know, what I´m sharing?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Of Course RetroShare is safe and secure ;). The more you have only trusted friends in your list (the more, the better), the safer is the connection to your neighbor. Quick Answer: This Chat Messenger is private and secure, but it is not anonymous, as you see all the files of your trusted friends - and so they do. Because, RetroShare is a private network. Only you and your peers can see which files you are sharing. Every peer must be authenticated and approved before a connection will take place, and all communication is also encrypted using standard openSSL techniques. RetroShare is, however, not an anonymous file-sharing network. Your friends know who you are, and what you are sharing. No one else on the network can see this information. The friends of your peers also know of your existence, and can attempt to connect to you through the Auto-Discovery system. Your security is primarily dependent on the reliability of the people you connect to. Connect to trustworthy people and your files will be safe. Allow anyone to connect - who knows what will happen. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;1-8_Why_should_I_maintain_another_IM-Network.2C_when_I.27m_barely_able_to_keep_my_ICQ.2FMSN.2FGTalk_contacts_in_sync.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-8 Why should I maintain another IM-Network, when I'm barely able to keep my ICQ/MSN/GTalk contacts in sync?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;RetroShare is more than just an instant messenger like MSN or Yahoo, it is also a private p2p file sharing network. You can share files with your friends and you can search through your friends files as well. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;1-9_Is_there_a_plugin_for_the_Telepathy_framework_or_Pidgin.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-9 Is there a plugin for the Telepathy framework or Pidgin?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Not yet! Maybe you wanna start coding? :-) &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;Getting_Connected.&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:x-large; font-weight:600;&quot;&gt;G&lt;/span&gt;&lt;span style=&quot; font-size:x-large; font-weight:600;&quot;&gt;etting Connected.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;2-1_Where_can_I_download_RetroShare.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-1 Where can I download RetroShare?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;http://retroshare.sourceforge.net/downloads.html&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://retroshare.sourceforge.net/downloads.html&lt;/span&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;2-2_How_do_you_install_RetroShare.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-2 How do you install RetroShare?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;This varies on different operating systems. See this guide: &lt;a href=&quot;http://retroshare.sourceforge.net/wiki/index.php/Documentation:Installation_Guide&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;InstallGuide&lt;/span&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;2-3_Why_won.27t_it_connect.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-3 Why won't it connect?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;You may not be able to connect for several reasons. To connect to someone you must add them to your friends list and they also must add you. If you do not both add each other then you will not connect. Also, make sure both of your firewall settings are correct in the settings. For more help post a message on the Sourceforge project forum. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;2-4_Can_I_connect_from_behind_a_Firewall.3F_How_Do_I_set_the_Firewall.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-4 Can I connect from behind a Firewall? How Do I set the Firewall?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Yes you can, if UPnP is working you will not need to perform any extra steps. Currently this only works on Linux. Otherwise see 2-5 for how to setup port forwarding on your firewall/NAT. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;2-5_How_do_I_enable_Port_Forwarding_in_my_Router.2FNAT.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-5 How do I enable Port Forwarding in my Router/NAT?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The default port is 7812. This port on the router needs to be forwarded to your PC running RetroShare. Also, you can change the network setting in RetroShare to &amp;quot;External (Forwarded) Port&amp;quot;. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;2-7_How_do_I_connect_to_a_Friend.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-7 How do I connect to a Friend?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Send them your certificate. Import their certificate. If UPnP is working and OpenDHT is working you should be able to connect. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;2-8_Which_certificate_must_I_send.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-8 Which certificate must I send?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Your certificate. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;2-9_How_do_I_get_a_RetroShare_Certificate&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-9 How do I get a RetroShare Certificate&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;A certificate is generated for each user when they start up the program for the first time. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;2-10_Auto-Login_doesn.27t_do_anything_on_Linux&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-10 Auto-Login doesn't do anything on Linux&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Auto-Login is a Windows only feature at the moment. &lt;/p&gt;
&lt;hr /&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;DOWNLOADING_.26_SHARING&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:x-large; font-weight:600;&quot;&gt;D&lt;/span&gt;&lt;span style=&quot; font-size:x-large; font-weight:600;&quot;&gt;OWNLOADING &amp;amp; SHARING&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;3-1_Who_should_I_get_to_sign_my_Certificate.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-1 Who should I get to sign my Certificate?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Your friends who trust you and have verified that your certificate is yours should sign your certificate. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;3-2_Why_if_my_friends_Certificate_is_not_approved_by_RetroShare.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-2 Why if my friends Certificate is not approved by RetroShare?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;3-3_Should_I_Sign_this_Certificate.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-3 Should I Sign this Certificate?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Only sign certificates if you are able to verify that the certificate belongs to the person you think it does. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;3-4_How_do_you_verify_a_certificate.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-4 How do you verify a certificate?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;If you transfer the certificate via a USB drive you can verify the certificate. Also, if you were to verify the checksum of the certificate in person or over the phone with the person if you recognize their voice. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;3-5_Does_my_friend_need_RetroShare_to_receive_files.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-5 Does my friend need RetroShare to receive files?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Yes. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;3-6_How_do_I_know_if_another_RetroShare_Friend_has_shared_something_for_me.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-6 How do I know if another RetroShare Friend has shared something for me?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Your friends shared files will be listed in the right side of the &amp;quot;Files&amp;quot; tab. There may be a slight delay in updating this list. You may need to click on the pluses to expand folders that your friend has to see all the files in them. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;3-7_How_do_I_send_a_file_to_someone_on_my_contact_list.3F_What_if_it_is_over_2_GB.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-7 How do I send a file to someone on my contact list? What if it is over 2 GB?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Files over 2GB have some issues. These issues will be fixed in a future release of RetroShare (as of 8/5/2008). &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;3-8_Does_RetroShare_support_resuming_for_transfered_files.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-8 Does RetroShare support resuming for transfered files?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Yes. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;3-9_Can_I_download_the_same_file_from_several_users.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-9 Can I download the same file from several users?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Yes. RetroShare searches through all your friends files looking for a matching file hash. Once it finds a friend that has a file with a matching hash it will begin downloading the file from that friend. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The new version (as of Aug 14th, 2008) (we're working on it now) will support downloading from multiple friends in parallel. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;3-10_How_fast_is_the_upload_and_download_speed.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-10 How fast is the upload and download speed?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Depends on your connection and other traffic, but it is usually limited by the upload capacity of the user uploading. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;3-12_What_can_I_share_using_RetroShare.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-12 What can I share using RetroShare?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;You can share any file type with RetroShare: Pictures, videos and documents. &lt;/p&gt;
&lt;hr /&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;TECHNICAL&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:x-large; font-weight:600;&quot;&gt;T&lt;/span&gt;&lt;span style=&quot; font-size:x-large; font-weight:600;&quot;&gt;ECHNICAL&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;4-1_How_does_RetroShare_know_my_friend.27s_IP_address_and_port.3F_Why_don.27t_I_need_a_static_IP_address.3F_What_is_DHT_for.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-1 How does RetroShare know my friend's IP address and port? Why don't I need a static IP address? What is DHT for?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Prior to version 0.5, RetroShare posted your IP/port information to a &lt;a href=&quot;http://en.wikipedia.org/wiki/Distributed_hash_table&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Distributed Hash Table&lt;/span&gt;&lt;/a&gt; (DHT), which other users in your network could query to obtain your IP/port. That DHT network has since become unreliable and as of version 0.5 RetroShare no longer uses it. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Retroshare clients now propagate IP/port updates through the F2F network. Provided there is at least one node with an address that has not changed since you last connected, you will be able to connect to that node and be provided with the IP/port updates for any common nodes that have changed. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Smaller networks with no static IPs may experience problems with this system. If you remain offline for too long it's possible for none of your friends to still be using the same IP/port when you try to reconnect to them. Future versions of RetroShare will remedy this problem (DDNS support has been &lt;a href=&quot;http://retroshare.sourceforge.net/forum/viewtopic.php?p=3594#p3594&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;added to the dev. trunk&lt;/span&gt;&lt;/a&gt; and it only takes one node set up with DDNS to stabilise a network) but if you are experiencing reconnection problems now then see the &lt;a href=&quot;http://retroshare.sourceforge.net/wiki/index.php/Dynamic_IP_Address_Troubleshooting&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;troubleshooting page&lt;/span&gt;&lt;/a&gt; for work-arounds. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;4-2_What_is_turtle_F2F.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-2 What is turtle F2F?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Turtle F2F allows you to download files from a friend's friend's computer by relaying the request via your common trusted friend. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;4-3_How_does_the_security.2Fprivacy_work.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-3 How does the security/privacy work?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;TODO &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;4-4_What_does_.22Trust.22_mean_in_RetroShare.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-4 What does &amp;quot;Trust&amp;quot; mean in RetroShare?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;TODO &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;4-5_What_is_the_AUTH.28enticate.29_Code_for.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-5 What is the AUTH(enticate) Code for?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;This is no longer used. The AUTH code was a 4 character Hexadecimal number derived from your certificate. It was designed as extra Authentication for your friends. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;4-6_Is_RetroShare_Open_Source.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-6 Is RetroShare Open Source?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The licensing scheme for the different parts of RetroShare is: &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;openSSL :BSD style KadC :GPL + exception (asked author for exception) threads :LGPL RetroShare LIbrary :LGPL RetroShare GUI + QT :GPL + exception. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;4-7_Where_have_you_released_the_source_code.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-7 Where have you released the source code?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Latest sources are available on Sourceforge at &lt;a href=&quot;http://sourceforge.net/project/showfiles.php?group_id=178712&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://sourceforge.net/project/showfiles.php?group_id=178712&lt;/span&gt;&lt;/a&gt; &lt;/p&gt;
&lt;hr /&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;MISCELLANEOUS&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:x-large; font-weight:600;&quot;&gt;M&lt;/span&gt;&lt;span style=&quot; font-size:x-large; font-weight:600;&quot;&gt;ISCELLANEOUS&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;5-1_Is_Jabber_XMPP_used_for_the_Message_transfer_protocol.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;5&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-1 Is Jabber XMPP used for the Message transfer protocol?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;No. The messenger uses a proprietary protocol. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;5-2_Could_other_Services_be_provided_over_this_type_of_Private_Network.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;5&lt;/span&gt;&lt;span style=&quot; font-size:large; font-weight:600;&quot;&gt;-2 Could other Services be provided over this type of Private Network?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Yes. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;Why_are_your_mailing-lists_and_your_website_in_english.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:x-large; font-weight:600;&quot;&gt;W&lt;/span&gt;&lt;span style=&quot; font-size:x-large; font-weight:600;&quot;&gt;hy are your mailing-lists and your website in english? &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;RetroShare's developers come from all around the world and english is the only language they can use to communicate together. Although great care is given to the translation of RetroShare in various languages, maintaining translations of our website costs too much more time than we can afford. &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a name=&quot;What_to_do_if_I_can.27t_find_an_answer_to_my_question_here.3F&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-size:x-large; font-weight:600;&quot;&gt;W&lt;/span&gt;&lt;span style=&quot; font-size:x-large; font-weight:600;&quot;&gt;hat to do if I can't find an answer to my question here? &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Have a look at the &lt;a href=&quot;http://retroshare.sourceforge.net/wiki/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Wiki&lt;/span&gt;&lt;/a&gt;. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Search the &lt;a href=&quot;http://retroshare.sourceforge.net/forum/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;forums&lt;/span&gt;&lt;/a&gt; for your question. There are many solutions to problems on using our programs. &lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;If your question still was not answered, post it on the forums or mail a fitting &lt;a href=&quot;http://sourceforge.net/mail/?group_id=178712&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;mailing-list&lt;/span&gt;&lt;/a&gt;. &lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="images.qrc"/>
</resources>
<connections/>
</ui>

Some files were not shown because too many files have changed in this diff Show More