mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-24 23:19:29 -05:00
Significant improvements to DHT behaviour, and reconnection attempts.
* Added GUI interface for auto connect state. * Added HTTP retrieval and storage of DHT peers update. * Added code for partial recv() from DHT peers. * Disabled Chat/Disc/Udplayer/tcpstream debug output. * Added Unreachable Check to connMgr. * Added auto reconnect functions to connMgr (#define to disable). * Restructured DHT notify code... much cleaner. * DHT now flags out of date DHT results. * DHT notifies ConnMgr on any results (same or diff). * Added Fns to cleanup old udp connection. * other bugfixes. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@369 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
7b3fc2976e
commit
63828f77a8
@ -36,6 +36,8 @@ class DHTClient
|
||||
|
||||
/* initialise from file */
|
||||
virtual bool loadServers(std::string filename) = 0;
|
||||
virtual bool loadServersFromWeb(std::string storename) = 0;
|
||||
virtual bool loadServers(std::istream&) = 0;
|
||||
|
||||
/* check that its working */
|
||||
virtual bool dhtActive() = 0;
|
||||
@ -53,6 +55,8 @@ class DHTClientDummy: public DHTClient
|
||||
|
||||
/* initialise from file */
|
||||
virtual bool loadServers(std::string filename) { return true; }
|
||||
virtual bool loadServersFromWeb(std::string storename) { return true; }
|
||||
virtual bool loadServers(std::istream&) { return true; }
|
||||
|
||||
/* check that its working */
|
||||
virtual bool dhtActive() { return true; }
|
||||
|
@ -27,6 +27,9 @@
|
||||
#include "dht/opendhtstr.h"
|
||||
#include "dht/b64.h"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include "util/rsnet.h"
|
||||
|
||||
const std::string openDHT_Client = "Retroshare V0.4";
|
||||
const std::string openDHT_Agent = "RS-HTTP-V0.4";
|
||||
@ -43,8 +46,12 @@ bool OpenDHTClient::loadServers(std::string filename)
|
||||
/* open the file */
|
||||
std::ifstream file(filename.c_str());
|
||||
|
||||
/* chew first line */
|
||||
file.ignore(1024, '\n');
|
||||
|
||||
return loadServers(file);
|
||||
}
|
||||
|
||||
bool OpenDHTClient::loadServers(std::istream &instr)
|
||||
{
|
||||
|
||||
std::string line;
|
||||
char number[1024];
|
||||
@ -55,10 +62,13 @@ bool OpenDHTClient::loadServers(std::string filename)
|
||||
mServers.clear();
|
||||
dhtMutex.unlock(); /**** UNLOCK ****/
|
||||
|
||||
while((!file.eof()) && (!file.fail()))
|
||||
/* chew first line */
|
||||
instr.ignore(1024, '\n');
|
||||
|
||||
while((!instr.eof()) && (!instr.fail()))
|
||||
{
|
||||
line = "";
|
||||
getline(file, line);
|
||||
getline(instr, line);
|
||||
|
||||
if (3 == sscanf(line.c_str(), "%1023s %1023s %1023s", number, ipaddr, dnsname))
|
||||
{
|
||||
@ -92,7 +102,69 @@ bool OpenDHTClient::loadServers(std::string filename)
|
||||
dhtMutex.unlock(); /**** UNLOCK ****/
|
||||
}
|
||||
|
||||
return true;
|
||||
dhtMutex.lock(); /**** LOCK ****/
|
||||
uint32_t count = mServers.size();
|
||||
dhtMutex.unlock(); /**** UNLOCK ****/
|
||||
|
||||
return (count >= MIN_DHT_SERVERS);
|
||||
}
|
||||
|
||||
/******* refresh Servers from WebPage ******/
|
||||
|
||||
bool OpenDHTClient::loadServersFromWeb(std::string storename)
|
||||
{
|
||||
|
||||
#ifdef OPENDHT_DEBUG
|
||||
std::cerr << "OpenDHTClient::loadServersFromWeb()" << std::endl;
|
||||
#endif
|
||||
|
||||
std::string response;
|
||||
if (!openDHT_getDHTList(response))
|
||||
{
|
||||
#ifdef OPENDHT_DEBUG
|
||||
std::cerr << "OpenDHTClient::loadServersFromWeb() Web GET failed" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string::size_type i;
|
||||
if (std::string::npos == (i = response.find("\r\n\r\n")))
|
||||
{
|
||||
#ifdef OPENDHT_DEBUG
|
||||
std::cerr << "OpenDHTClient::loadServersFromWeb() Failed to Find Content" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
/* now step past 4 chars */
|
||||
i += 4;
|
||||
|
||||
std::string content(response, i, response.length() - i);
|
||||
|
||||
#ifdef OPENDHT_DEBUG
|
||||
std::cerr << "OpenDHTClient::loadServersFromWeb() Content:" << std::endl;
|
||||
std::cerr << content << std::endl;
|
||||
std::cerr << "<== OpenDHTClient::loadServersFromWeb() Content" << std::endl;
|
||||
#endif
|
||||
|
||||
std::istringstream iss(content);
|
||||
|
||||
if (loadServers(iss))
|
||||
{
|
||||
#ifdef OPENDHT_DEBUG
|
||||
std::cerr << "OpenDHTClient::loadServersFromWeb() Saving WebData to: ";
|
||||
std::cerr << storename << std::endl;
|
||||
#endif
|
||||
/* save the data to file - replacing old data */
|
||||
std::ofstream ofstr(storename.c_str());
|
||||
ofstr << content;
|
||||
ofstr.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -439,11 +511,119 @@ bool OpenDHTClient::openDHT_sendMessage(std::string msg, std::string &response)
|
||||
/* now wait for the response */
|
||||
sleep(1);
|
||||
|
||||
int recvsize = 10240; /* 10kb */
|
||||
void *inbuf = malloc(recvsize);
|
||||
size = recv(sockfd, inbuf, recvsize, 0);
|
||||
int recvsize = 51200; /* 50kb */
|
||||
char *inbuf = (char *) malloc(recvsize);
|
||||
uint32_t idx = 0;
|
||||
while(0 < (size = recv(sockfd, &(inbuf[idx]), recvsize - idx, 0)))
|
||||
{
|
||||
std::cerr << "OpenDHTClient::openDHT_sendMessage()";
|
||||
std::cerr << " Recvd Chunk:" << size;
|
||||
std::cerr << std::endl;
|
||||
|
||||
response = (char *) inbuf;
|
||||
idx += size;
|
||||
}
|
||||
|
||||
std::cerr << "OpenDHTClient::openDHT_sendMessage()";
|
||||
std::cerr << " Recvd Msg:" << idx;
|
||||
|
||||
response = std::string(inbuf, idx);
|
||||
free(inbuf);
|
||||
|
||||
/* print it out */
|
||||
std::cerr << "HTTP response *******************" << std::endl;
|
||||
std::cerr << response;
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "HTTP response *******************" << std::endl;
|
||||
|
||||
close(sockfd);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenDHTClient::openDHT_getDHTList(std::string &response)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
std::string host = "www.opendht.org";
|
||||
uint16_t port = 80;
|
||||
|
||||
sockaddr_clear(&addr);
|
||||
|
||||
/* lookup the address */
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
if (!LookupDNSAddr(host, addr))
|
||||
{
|
||||
/* no address */
|
||||
std::cerr << "OpenDHTClient::openDHT_getDHTList()";
|
||||
std::cerr << " ERROR: No Address";
|
||||
std::cerr << std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cerr << "OpenDHTClient::openDHT_getDHTList()";
|
||||
std::cerr << " Connecting to:" << host << ":" << port;
|
||||
std::cerr << " (" << inet_ntoa(addr.sin_addr) << ":" << ntohs(addr.sin_port) << ")";
|
||||
std::cerr << std::endl;
|
||||
|
||||
/* create request */
|
||||
std::string putheader = createHttpHeaderGET(host, port, "servers.txt", openDHT_Agent, 0);
|
||||
|
||||
/* open a socket */
|
||||
int sockfd = unix_socket(PF_INET, SOCK_STREAM, 0);
|
||||
|
||||
/* connect */
|
||||
int err = unix_connect(sockfd, (struct sockaddr *) &addr, sizeof(addr));
|
||||
if (err)
|
||||
{
|
||||
unix_close(sockfd);
|
||||
std::cerr << "OpenDHTClient::openDHT_getDHTList()";
|
||||
std::cerr << " ERROR: Failed to Connect";
|
||||
std::cerr << std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cerr << "HTTP message *******************" << std::endl;
|
||||
std::cerr << putheader;
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "HTTP message *******************" << std::endl;
|
||||
|
||||
/* send data */
|
||||
int sendsize = strlen(putheader.c_str());
|
||||
int size = send(sockfd, putheader.c_str(), sendsize, 0);
|
||||
if (sendsize != size)
|
||||
{
|
||||
unix_close(sockfd);
|
||||
std::cerr << "OpenDHTClient::openDHT_getDHTList()";
|
||||
std::cerr << " ERROR: Failed to Send(1)";
|
||||
std::cerr << std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
std::cerr << "OpenDHTClient::openDHT_getDHTList()";
|
||||
std::cerr << " Send(1):" << size;
|
||||
std::cerr << std::endl;
|
||||
|
||||
/* now wait for the response */
|
||||
sleep(1);
|
||||
|
||||
int recvsize = 51200; /* 50kb */
|
||||
char *inbuf = (char *) malloc(recvsize);
|
||||
uint32_t idx = 0;
|
||||
while(0 < (size = recv(sockfd, &(inbuf[idx]), recvsize - idx, 0)))
|
||||
{
|
||||
std::cerr << "OpenDHTClient::openDHT_getDHTList()";
|
||||
std::cerr << " Recvd Chunk:" << size;
|
||||
std::cerr << std::endl;
|
||||
|
||||
idx += size;
|
||||
}
|
||||
|
||||
std::cerr << "OpenDHTClient::openDHT_getDHTList()";
|
||||
std::cerr << " Recvd Msg:" << idx;
|
||||
|
||||
response = std::string(inbuf, idx);
|
||||
free(inbuf);
|
||||
|
||||
/* print it out */
|
||||
|
@ -56,6 +56,9 @@ virtual bool searchKey(std::string key, std::list<std::string> &values);
|
||||
|
||||
/* Fns accessing data */
|
||||
virtual bool loadServers(std::string filename);
|
||||
virtual bool loadServersFromWeb(std::string storefname);
|
||||
virtual bool loadServers(std::istream&);
|
||||
|
||||
virtual bool dhtActive();
|
||||
|
||||
private:
|
||||
@ -67,6 +70,7 @@ void setServerFailed(std::string host);
|
||||
|
||||
/* generic send msg */
|
||||
bool openDHT_sendMessage(std::string msg, std::string &response);
|
||||
bool openDHT_getDHTList(std::string &response);
|
||||
|
||||
RsMutex dhtMutex;
|
||||
std::map<std::string, dhtServer> mServers;
|
||||
|
@ -116,7 +116,11 @@ bool OpenDHTMgr::init()
|
||||
}
|
||||
filename += "servers.txt";
|
||||
|
||||
return mClient -> loadServers(filename);
|
||||
if (!mClient -> loadServersFromWeb(filename))
|
||||
{
|
||||
return mClient -> loadServers(filename);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenDHTMgr::shutdown()
|
||||
|
@ -43,6 +43,20 @@ std::string createHttpHeader(std::string host, uint16_t port, std::string agent,
|
||||
return req.str();
|
||||
};
|
||||
|
||||
std::string createHttpHeaderGET(std::string host, uint16_t port, std::string page, std::string agent, uint32_t length)
|
||||
{
|
||||
std::ostringstream req;
|
||||
|
||||
req << "GET /" << page << " HTTP/1.0\r\n";
|
||||
req << "Host: " << host << ":" << port << "\r\n";
|
||||
req << "User-Agent: " << agent << "\r\n";
|
||||
//req << "Content-Type: text/xml\r\n";
|
||||
//req << "Content-Length: " << length << "\r\n";
|
||||
req << "\r\n";
|
||||
|
||||
return req.str();
|
||||
};
|
||||
|
||||
std::string createOpenDHT_put(std::string key, std::string value, uint32_t ttl, std::string client)
|
||||
{
|
||||
std::ostringstream req;
|
||||
|
@ -32,6 +32,9 @@
|
||||
std::string createHttpHeader(std::string host, uint16_t port,
|
||||
std::string agent, uint32_t length);
|
||||
|
||||
std::string createHttpHeaderGET(std::string host, uint16_t port,
|
||||
std::string page, std::string agent, uint32_t length);
|
||||
|
||||
std::string createOpenDHT_put(std::string key, std::string value,
|
||||
uint32_t ttl, std::string client);
|
||||
|
||||
|
@ -48,8 +48,12 @@ const uint32_t MAX_UPNP_INIT = 60; /* seconds UPnP timeout */
|
||||
#define CONN_DEBUG 1
|
||||
#define P3CONNMGR_NO_TCP_CONNECTIONS 1
|
||||
|
||||
/****
|
||||
* #define P3CONNMGR_NO_AUTO_CONNECTION 1
|
||||
***/
|
||||
|
||||
const uint32_t P3CONNMGR_TCP_DEFAULT_DELAY = 10; /* 10 Seconds should be enough! */
|
||||
const uint32_t P3CONNMGR_UDP_DHT_DELAY = 300; /* 5 minutes */
|
||||
const uint32_t P3CONNMGR_UDP_DHT_DELAY = 300 + 60; /* 5 minutes FIND + 1 minute for DHT POST */
|
||||
const uint32_t P3CONNMGR_UDP_PROXY_DELAY = 30; /* 30 seconds */
|
||||
|
||||
void printConnectState(peerConnectState &peer);
|
||||
@ -72,10 +76,11 @@ peerConnectState::peerConnectState()
|
||||
:id("unknown"),
|
||||
netMode(RS_NET_MODE_UNKNOWN), visState(RS_VIS_STATE_STD),
|
||||
lastcontact(0),
|
||||
|
||||
lastavailable(0),
|
||||
lastattempt(0),
|
||||
name("nameless"), state(0), actions(0),
|
||||
source(0),
|
||||
inConnAttempt(0), lastattempt(0)
|
||||
inConnAttempt(0)
|
||||
{
|
||||
sockaddr_clear(&localaddr);
|
||||
sockaddr_clear(&serveraddr);
|
||||
@ -241,10 +246,6 @@ void p3ConnectMgr::netStartup()
|
||||
|
||||
switch(ownState.netMode & RS_NET_MODE_TRYMODE)
|
||||
{
|
||||
case RS_NET_MODE_TRY_UPNP:
|
||||
ownState.netMode |= RS_NET_MODE_UDP;
|
||||
mNetStatus = RS_NET_UPNP_INIT;
|
||||
break;
|
||||
|
||||
case RS_NET_MODE_TRY_EXT: /* v similar to UDP */
|
||||
ownState.netMode |= RS_NET_MODE_EXT;
|
||||
@ -256,11 +257,15 @@ void p3ConnectMgr::netStartup()
|
||||
break;
|
||||
|
||||
case RS_NET_MODE_TRY_UDP:
|
||||
default:
|
||||
ownState.netMode |= RS_NET_MODE_UDP;
|
||||
mNetStatus = RS_NET_UDP_SETUP;
|
||||
break;
|
||||
|
||||
case RS_NET_MODE_TRY_UPNP:
|
||||
default:
|
||||
ownState.netMode |= RS_NET_MODE_UDP;
|
||||
mNetStatus = RS_NET_UPNP_INIT;
|
||||
break;
|
||||
}
|
||||
connMtx.unlock(); /* UNLOCK MUTEX */
|
||||
}
|
||||
@ -269,10 +274,78 @@ void p3ConnectMgr::netStartup()
|
||||
void p3ConnectMgr::tick()
|
||||
{
|
||||
netTick();
|
||||
statusTick();
|
||||
tickMonitors();
|
||||
|
||||
}
|
||||
|
||||
#define MAX_AVAIL_PERIOD 900 // 15 minutes
|
||||
#define MIN_RETRY_PERIOD 1900 // just over 30 minutes. (DHT retry period)
|
||||
|
||||
void p3ConnectMgr::statusTick()
|
||||
{
|
||||
/* iterate through peers ...
|
||||
* if been available for long time ... remove flag
|
||||
* if last attempt a while - retryConnect.
|
||||
* etc.
|
||||
*/
|
||||
|
||||
#ifdef CONN_DEBUG
|
||||
//std::cerr << "p3ConnectMgr::statusTick()" << std::endl;
|
||||
#endif
|
||||
std::list<std::string> retryIds;
|
||||
std::list<std::string>::iterator it2;
|
||||
|
||||
time_t now = time(NULL);
|
||||
time_t oldavail = now - MAX_AVAIL_PERIOD;
|
||||
time_t retry = now - MIN_RETRY_PERIOD;
|
||||
|
||||
{
|
||||
RsStackMutex stack(connMtx); /****** LOCK MUTEX ******/
|
||||
std::map<std::string, peerConnectState>::iterator it;
|
||||
for(it = mFriendList.begin(); it != mFriendList.end(); it++)
|
||||
{
|
||||
if (it->second.state & RS_PEER_S_CONNECTED)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((it->second.state & RS_PEER_S_ONLINE) &&
|
||||
(it->second.lastavailable < oldavail))
|
||||
{
|
||||
#ifdef CONN_DEBUG
|
||||
std::cerr << "p3ConnectMgr::statusTick() ONLINE TIMEOUT for: ";
|
||||
std::cerr << it->first;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
it->second.state &= (~RS_PEER_S_ONLINE);
|
||||
}
|
||||
|
||||
if (it->second.lastattempt < retry)
|
||||
{
|
||||
retryIds.push_back(it->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef P3CONNMGR_NO_AUTO_CONNECTION
|
||||
|
||||
for(it2 = retryIds.begin(); it2 != retryIds.end(); it2++)
|
||||
{
|
||||
#ifdef CONN_DEBUG
|
||||
std::cerr << "p3ConnectMgr::statusTick() RETRY TIMEOUT for: ";
|
||||
std::cerr << *it2;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* retry it! */
|
||||
retryConnect(*it2);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
void p3ConnectMgr::netTick()
|
||||
{
|
||||
|
||||
@ -481,6 +554,7 @@ void p3ConnectMgr::netUdpCheck()
|
||||
if (mUpnpAddrValid || (ownState.netMode == RS_NET_MODE_EXT))
|
||||
{
|
||||
mode |= RS_NET_CONN_TCP_EXTERNAL;
|
||||
mode |= RS_NET_CONN_UDP_DHT_SYNC;
|
||||
}
|
||||
else if (extAddrStable)
|
||||
{
|
||||
@ -496,7 +570,8 @@ void p3ConnectMgr::netUdpCheck()
|
||||
std::cerr << "netMode => RS_NET_MODE_UNREACHABLE";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
ownState.netMode = RS_NET_MODE_UNREACHABLE;
|
||||
ownState.netMode &= ~(RS_NET_MODE_ACTUAL);
|
||||
ownState.netMode |= RS_NET_MODE_UNREACHABLE;
|
||||
tou_stunkeepalive(0);
|
||||
}
|
||||
|
||||
@ -514,9 +589,87 @@ void p3ConnectMgr::netUdpCheck()
|
||||
/* mode = 0 for error */
|
||||
mDhtMgr->setExternalInterface(iaddr, extAddr, mode);
|
||||
}
|
||||
|
||||
/* flag unreachables! */
|
||||
if ((extValid) && (!extAddrStable))
|
||||
{
|
||||
netUnreachableCheck();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void p3ConnectMgr::netUnreachableCheck()
|
||||
{
|
||||
#ifdef CONN_DEBUG
|
||||
std::cerr << "p3ConnectMgr::netUnreachableCheck()" << std::endl;
|
||||
#endif
|
||||
std::map<std::string, peerConnectState>::iterator it;
|
||||
|
||||
connMtx.lock(); /* LOCK MUTEX */
|
||||
for(it = mFriendList.begin(); it != mFriendList.end(); it++)
|
||||
{
|
||||
/* get last contact detail */
|
||||
if (it->second.state & RS_PEER_S_CONNECTED)
|
||||
{
|
||||
#ifdef CONN_DEBUG
|
||||
std::cerr << "NUC() Ignoring Connected Peer" << std::endl;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
peerAddrInfo details;
|
||||
switch(it->second.source)
|
||||
{
|
||||
case RS_CB_DHT:
|
||||
details = it->second.dht;
|
||||
#ifdef CONN_DEBUG
|
||||
std::cerr << "NUC() Using DHT data" << std::endl;
|
||||
#endif
|
||||
break;
|
||||
case RS_CB_DISC:
|
||||
details = it->second.disc;
|
||||
#ifdef CONN_DEBUG
|
||||
std::cerr << "NUC() Using DISC data" << std::endl;
|
||||
#endif
|
||||
break;
|
||||
case RS_CB_PERSON:
|
||||
details = it->second.peer;
|
||||
#ifdef CONN_DEBUG
|
||||
std::cerr << "NUC() Using PEER data" << std::endl;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
std::cerr << "NUC() Peer: " << it->first << std::endl;
|
||||
|
||||
/* Determine Reachability (only advisory) */
|
||||
// if (ownState.netMode == RS_NET_MODE_UNREACHABLE) // MUST BE TRUE!
|
||||
{
|
||||
if (details.type & RS_NET_CONN_TCP_EXTERNAL)
|
||||
{
|
||||
/* reachable! */
|
||||
it->second.state &= (~RS_PEER_S_UNREACHABLE);
|
||||
#ifdef CONN_DEBUG
|
||||
std::cerr << "NUC() Peer EXT TCP - reachable" << std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unreachable */
|
||||
it->second.state |= RS_PEER_S_UNREACHABLE;
|
||||
#ifdef CONN_DEBUG
|
||||
std::cerr << "NUC() Peer !EXT TCP - unreachable" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
connMtx.unlock(); /* UNLOCK MUTEX */
|
||||
}
|
||||
|
||||
|
||||
/******************************* UDP MAINTAINANCE ********************************
|
||||
* Interaction with the UDP is mainly for determining the External Port.
|
||||
@ -1136,6 +1289,7 @@ bool p3ConnectMgr::connectResult(std::string id, bool success, uint32_t flags)
|
||||
* From various sources
|
||||
*/
|
||||
|
||||
|
||||
void p3ConnectMgr::peerStatus(std::string id,
|
||||
struct sockaddr_in laddr, struct sockaddr_in raddr,
|
||||
uint32_t type, uint32_t flags, uint32_t source)
|
||||
@ -1178,13 +1332,14 @@ void p3ConnectMgr::peerStatus(std::string id,
|
||||
std::cerr << std::endl;
|
||||
|
||||
/* update the status */
|
||||
time_t now = time(NULL);
|
||||
|
||||
peerAddrInfo details;
|
||||
details.type = type;
|
||||
details.found = true;
|
||||
details.laddr = laddr;
|
||||
details.raddr = raddr;
|
||||
details.ts = time(NULL);
|
||||
details.ts = now;
|
||||
|
||||
/* if source is DHT */
|
||||
if (source == RS_CB_DHT)
|
||||
@ -1198,6 +1353,7 @@ void p3ConnectMgr::peerStatus(std::string id,
|
||||
|
||||
/* If we get a info -> then they are online */
|
||||
it->second.state |= RS_PEER_S_ONLINE;
|
||||
it->second.lastavailable = now;
|
||||
}
|
||||
else if (source == RS_CB_DISC)
|
||||
{
|
||||
@ -1212,6 +1368,7 @@ void p3ConnectMgr::peerStatus(std::string id,
|
||||
{
|
||||
it->second.actions |= RS_PEER_ONLINE;
|
||||
it->second.state |= RS_PEER_S_ONLINE;
|
||||
it->second.lastavailable = now;
|
||||
mStatusChanged = true;
|
||||
}
|
||||
|
||||
@ -1231,7 +1388,9 @@ void p3ConnectMgr::peerStatus(std::string id,
|
||||
|
||||
it->second.localaddr = laddr;
|
||||
it->second.serveraddr = raddr;
|
||||
|
||||
it->second.state |= RS_PEER_S_ONLINE;
|
||||
it->second.lastavailable = now;
|
||||
|
||||
/* must be online to recv info (should be connected too!)
|
||||
* but no need for action as should be connected already
|
||||
@ -1274,7 +1433,7 @@ void p3ConnectMgr::peerStatus(std::string id,
|
||||
}
|
||||
|
||||
/* Determine Reachability (only advisory) */
|
||||
if (ownState.netMode == RS_NET_MODE_UDP)
|
||||
if (ownState.netMode & RS_NET_MODE_UDP)
|
||||
{
|
||||
if ((details.type & RS_NET_CONN_UDP_DHT_SYNC) ||
|
||||
(details.type & RS_NET_CONN_TCP_EXTERNAL))
|
||||
@ -1288,7 +1447,7 @@ void p3ConnectMgr::peerStatus(std::string id,
|
||||
it->second.state |= RS_PEER_S_UNREACHABLE;
|
||||
}
|
||||
}
|
||||
else if (ownState.netMode == RS_NET_MODE_UNREACHABLE)
|
||||
else if (ownState.netMode & RS_NET_MODE_UNREACHABLE)
|
||||
{
|
||||
if (details.type & RS_NET_CONN_TCP_EXTERNAL)
|
||||
{
|
||||
@ -1339,6 +1498,7 @@ void p3ConnectMgr::peerStatus(std::string id,
|
||||
std::cerr << " source: " << source;
|
||||
std::cerr << std::endl;
|
||||
|
||||
#ifndef P3CONNMGR_NO_AUTO_CONNECTION
|
||||
|
||||
#ifndef P3CONNMGR_NO_TCP_CONNECTIONS
|
||||
|
||||
@ -1430,7 +1590,16 @@ void p3ConnectMgr::peerStatus(std::string id,
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // P3CONNMGR_NO_TCP_CONNECTIONS
|
||||
|
||||
/* notify if they say we can, or we cannot connect ! */
|
||||
if (details.type & RS_NET_CONN_UDP_DHT_SYNC)
|
||||
{
|
||||
retryConnectNotify(id);
|
||||
}
|
||||
|
||||
#endif // P3CONNMGR_NO_AUTO_CONNECTION
|
||||
|
||||
|
||||
if (it->second.inConnAttempt)
|
||||
{
|
||||
@ -1471,6 +1640,22 @@ void p3ConnectMgr::peerConnectRequest(std::string id, struct sockaddr_in radd
|
||||
std::cerr << " source: " << source;
|
||||
std::cerr << std::endl;
|
||||
|
||||
/******************** TCP PART *****************************/
|
||||
|
||||
std::cerr << "p3ConnectMgr::peerConnectRequest() Try TCP first";
|
||||
std::cerr << std::endl;
|
||||
|
||||
retryConnectTCP(id);
|
||||
|
||||
/******************** UDP PART *****************************/
|
||||
|
||||
if (ownState.netMode & RS_NET_MODE_UNREACHABLE)
|
||||
{
|
||||
std::cerr << "p3ConnectMgr::peerConnectRequest() Unreachable - no UDP connection";
|
||||
std::cerr << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
/* look up the id */
|
||||
std::map<std::string, peerConnectState>::iterator it;
|
||||
connMtx.lock(); /* LOCK MUTEX */
|
||||
@ -1502,6 +1687,7 @@ void p3ConnectMgr::peerConnectRequest(std::string id, struct sockaddr_in radd
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
time_t now = time(NULL);
|
||||
/* this is a UDP connection request (DHT only for the moment!) */
|
||||
if (isValidNet(&(raddr.sin_addr)))
|
||||
@ -1825,9 +2011,18 @@ bool p3ConnectMgr::addNeighbour(std::string id)
|
||||
/*******************************************************************/
|
||||
/*************** External Control ****************/
|
||||
bool p3ConnectMgr::retryConnect(std::string id)
|
||||
{
|
||||
retryConnectTCP(id);
|
||||
retryConnectNotify(id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool p3ConnectMgr::retryConnectTCP(std::string id)
|
||||
{
|
||||
/* push addresses onto stack */
|
||||
std::cerr << "p3ConnectMgr::retryConnect()";
|
||||
std::cerr << "p3ConnectMgr::retryConnectTCP()";
|
||||
std::cerr << " id: " << id;
|
||||
std::cerr << std::endl;
|
||||
|
||||
@ -1838,7 +2033,7 @@ bool p3ConnectMgr::retryConnect(std::string id)
|
||||
|
||||
if (mFriendList.end() == (it = mFriendList.find(id)))
|
||||
{
|
||||
std::cerr << "p3ConnectMgr::retryConnect() Peer is not Friend";
|
||||
std::cerr << "p3ConnectMgr::retryConnectTCP() Peer is not Friend";
|
||||
std::cerr << std::endl;
|
||||
return false;
|
||||
}
|
||||
@ -1846,7 +2041,7 @@ bool p3ConnectMgr::retryConnect(std::string id)
|
||||
/* if already connected -> done */
|
||||
if (it->second.state & RS_PEER_S_CONNECTED)
|
||||
{
|
||||
std::cerr << "p3ConnectMgr::retryConnect() Peer Already Connected";
|
||||
std::cerr << "p3ConnectMgr::retryConnectTCP() Peer Already Connected";
|
||||
std::cerr << std::endl;
|
||||
return true;
|
||||
}
|
||||
@ -1867,7 +2062,7 @@ bool p3ConnectMgr::retryConnect(std::string id)
|
||||
&(it->second.localaddr.sin_addr))))
|
||||
|
||||
{
|
||||
std::cerr << "p3ConnectMgr::retryConnect() Local Address Valid: ";
|
||||
std::cerr << "p3ConnectMgr::retryConnectTCP() Local Address Valid: ";
|
||||
std::cerr << inet_ntoa(it->second.localaddr.sin_addr);
|
||||
std::cerr << ":" << ntohs(it->second.localaddr.sin_port);
|
||||
std::cerr << std::endl;
|
||||
@ -1892,7 +2087,7 @@ bool p3ConnectMgr::retryConnect(std::string id)
|
||||
|
||||
if (!localExists)
|
||||
{
|
||||
std::cerr << "p3ConnectMgr::retryConnect() Adding Local Addr to Queue";
|
||||
std::cerr << "p3ConnectMgr::retryConnectTCP() Adding Local Addr to Queue";
|
||||
std::cerr << std::endl;
|
||||
|
||||
/* add the local address */
|
||||
@ -1905,16 +2100,19 @@ bool p3ConnectMgr::retryConnect(std::string id)
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "p3ConnectMgr::retryConnect() Local Addr already in Queue";
|
||||
std::cerr << "p3ConnectMgr::retryConnectTCP() Local Addr already in Queue";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/* otherwise try external ... (should check flags) */
|
||||
if ((isValidNet(&(it->second.serveraddr.sin_addr))) &&
|
||||
(it->second.netMode = RS_NET_MODE_EXT))
|
||||
//if ((isValidNet(&(it->second.serveraddr.sin_addr))) &&
|
||||
// (it->second.netMode = RS_NET_MODE_EXT))
|
||||
|
||||
/* always try external */
|
||||
if (isValidNet(&(it->second.serveraddr.sin_addr)))
|
||||
{
|
||||
std::cerr << "p3ConnectMgr::retryConnect() Ext Address Valid (+EXT Flag): ";
|
||||
std::cerr << "p3ConnectMgr::retryConnectTCP() Ext Address Valid: ";
|
||||
std::cerr << inet_ntoa(it->second.serveraddr.sin_addr);
|
||||
std::cerr << ":" << ntohs(it->second.serveraddr.sin_port);
|
||||
std::cerr << std::endl;
|
||||
@ -1940,7 +2138,7 @@ bool p3ConnectMgr::retryConnect(std::string id)
|
||||
|
||||
if (!remoteExists)
|
||||
{
|
||||
std::cerr << "p3ConnectMgr::retryConnect() Adding Ext Addr to Queue";
|
||||
std::cerr << "p3ConnectMgr::retryConnectTCP() Adding Ext Addr to Queue";
|
||||
std::cerr << std::endl;
|
||||
|
||||
/* add the remote address */
|
||||
@ -1953,27 +2151,15 @@ bool p3ConnectMgr::retryConnect(std::string id)
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "p3ConnectMgr::retryConnect() Ext Addr already in Queue";
|
||||
std::cerr << "p3ConnectMgr::retryConnectTCP() Ext Addr already in Queue";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (it->second.netMode == RS_NET_MODE_UDP)
|
||||
{
|
||||
std::cerr << "p3ConnectMgr::retryConnect() trying UDP connection!";
|
||||
std::cerr << " id: " << id;
|
||||
std::cerr << std::endl;
|
||||
#endif // P3CONNMGR_NO_TCP_CONNECTIONS
|
||||
|
||||
/* attempt UDP connection */
|
||||
mDhtMgr->notifyPeer(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "p3ConnectMgr::retryConnect() EXT/UNREACHABLE so not trying UDP connection!";
|
||||
std::cerr << " id: " << id;
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
/* flag as last attempt to prevent loop */
|
||||
it->second.lastattempt = time(NULL);
|
||||
|
||||
if (it->second.inConnAttempt)
|
||||
{
|
||||
@ -1984,7 +2170,7 @@ bool p3ConnectMgr::retryConnect(std::string id)
|
||||
/* start a connection attempt */
|
||||
if (it->second.connAddrs.size() > 0)
|
||||
{
|
||||
std::cerr << "p3ConnectMgr::retryConnect() Started CONNECT ATTEMPT! ";
|
||||
std::cerr << "p3ConnectMgr::retryConnectTCP() Started CONNECT ATTEMPT! ";
|
||||
std::cerr << " id: " << id;
|
||||
std::cerr << std::endl;
|
||||
|
||||
@ -1993,7 +2179,7 @@ bool p3ConnectMgr::retryConnect(std::string id)
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "p3ConnectMgr::retryConnect() No addr suitable for CONNECT ATTEMPT! ";
|
||||
std::cerr << "p3ConnectMgr::retryConnectTCP() No addr suitable for CONNECT ATTEMPT! ";
|
||||
std::cerr << " id: " << id;
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
@ -2001,6 +2187,58 @@ bool p3ConnectMgr::retryConnect(std::string id)
|
||||
}
|
||||
|
||||
|
||||
bool p3ConnectMgr::retryConnectNotify(std::string id)
|
||||
{
|
||||
/* push addresses onto stack */
|
||||
std::cerr << "p3ConnectMgr::retryConnectNotify()";
|
||||
std::cerr << " id: " << id;
|
||||
std::cerr << std::endl;
|
||||
|
||||
/* look up the id */
|
||||
std::map<std::string, peerConnectState>::iterator it;
|
||||
connMtx.lock(); /* LOCK MUTEX */
|
||||
connMtx.unlock(); /* UNLOCK MUTEX */
|
||||
|
||||
if (mFriendList.end() == (it = mFriendList.find(id)))
|
||||
{
|
||||
std::cerr << "p3ConnectMgr::retryConnectNotify() Peer is not Friend";
|
||||
std::cerr << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* if already connected -> done */
|
||||
if (it->second.state & RS_PEER_S_CONNECTED)
|
||||
{
|
||||
std::cerr << "p3ConnectMgr::retryConnectNotify() Peer Already Connected";
|
||||
std::cerr << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* flag as last attempt to prevent loop */
|
||||
it->second.lastattempt = time(NULL);
|
||||
|
||||
if (ownState.netMode & RS_NET_MODE_UNREACHABLE)
|
||||
{
|
||||
std::cerr << "p3ConnectMgr::retryConnectNotify() UNREACHABLE so no Notify!";
|
||||
std::cerr << " id: " << id;
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "p3ConnectMgr::retryConnectNotify() Notifying Peer";
|
||||
std::cerr << " id: " << id;
|
||||
std::cerr << std::endl;
|
||||
|
||||
/* attempt UDP connection */
|
||||
mDhtMgr->notifyPeer(id);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool p3ConnectMgr::setLocalAddress(std::string id, struct sockaddr_in addr)
|
||||
{
|
||||
|
@ -126,6 +126,8 @@ class peerConnectState
|
||||
time_t lastcontact;
|
||||
|
||||
/***** Below here not stored permanently *****/
|
||||
time_t lastavailable;
|
||||
time_t lastattempt;
|
||||
|
||||
std::string name;
|
||||
|
||||
@ -139,7 +141,6 @@ class peerConnectState
|
||||
|
||||
/* a list of connect attempts to make (in order) */
|
||||
bool inConnAttempt;
|
||||
time_t lastattempt;
|
||||
peerConnectAddress currentConnAddr;
|
||||
std::list<peerConnectAddress> connAddrs;
|
||||
|
||||
@ -216,6 +217,7 @@ bool connectResult(std::string id, bool success, uint32_t flags);
|
||||
protected:
|
||||
|
||||
/* Internal Functions */
|
||||
void statusTick();
|
||||
void netTick();
|
||||
void netStartup();
|
||||
|
||||
@ -236,6 +238,7 @@ void netUpnpInit();
|
||||
void netUpnpCheck();
|
||||
|
||||
void netUdpCheck();
|
||||
void netUnreachableCheck();
|
||||
|
||||
/* Udp / Stun functions */
|
||||
bool udpInternalAddress(struct sockaddr_in iaddr);
|
||||
@ -249,6 +252,9 @@ void stunCollect(std::string id, struct sockaddr_in addr, uint32_t flags);
|
||||
/* monitor control */
|
||||
void tickMonitors();
|
||||
|
||||
/* connect attempts */
|
||||
bool retryConnectTCP(std::string id);
|
||||
bool retryConnectNotify(std::string id);
|
||||
|
||||
/* temporary for testing */
|
||||
virtual void loadConfiguration() { return; }
|
||||
|
@ -66,8 +66,8 @@
|
||||
#define DHT_DEFAULT_WAITTIME 1 /* Std sleep break period */
|
||||
|
||||
/* TTLs for DHTs posts */
|
||||
#define DHT_TTL_PUBLISH (DHT_PUBLISH_PERIOD + 30)
|
||||
#define DHT_TTL_NOTIFY DHT_NOTIFY_PERIOD
|
||||
#define DHT_TTL_PUBLISH (DHT_PUBLISH_PERIOD + 120) // for a little overlap.
|
||||
#define DHT_TTL_NOTIFY (DHT_NOTIFY_PERIOD + 60) // for time to find it...
|
||||
|
||||
|
||||
void printDhtPeerEntry(dhtPeerEntry *ent, std::ostream &out);
|
||||
@ -185,45 +185,41 @@ bool p3DhtMgr::setExternalInterface(
|
||||
/* add / remove peers */
|
||||
bool p3DhtMgr::findPeer(std::string id)
|
||||
{
|
||||
dhtMtx.lock(); /* LOCK MUTEX */
|
||||
RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/
|
||||
|
||||
mDhtModifications = true;
|
||||
|
||||
std::map<std::string, dhtPeerEntry>::iterator it;
|
||||
it = peers.find(id);
|
||||
if (it == peers.end())
|
||||
if (it != peers.end())
|
||||
{
|
||||
/* if they are not in the list -> add */
|
||||
dhtPeerEntry ent;
|
||||
ent.id = id;
|
||||
ent.state = DHT_PEER_INIT;
|
||||
ent.type = DHT_ADDR_INVALID;
|
||||
ent.lastTS = 0;
|
||||
|
||||
ent.notifyPending = 0;
|
||||
ent.notifyTS = 0;
|
||||
|
||||
/* fill in hashes */
|
||||
ent.hash1 = RsUtil::HashId(id, false);
|
||||
ent.hash2 = RsUtil::HashId(id, true);
|
||||
|
||||
/* other fields don't matter */
|
||||
|
||||
peers[id] = ent;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ignore */
|
||||
return true;
|
||||
}
|
||||
|
||||
dhtMtx.unlock(); /* UNLOCK MUTEX */
|
||||
/* if they are not in the list -> add */
|
||||
dhtPeerEntry ent;
|
||||
ent.id = id;
|
||||
ent.state = DHT_PEER_INIT;
|
||||
ent.type = DHT_ADDR_INVALID;
|
||||
ent.lastTS = 0;
|
||||
|
||||
ent.notifyPending = 0;
|
||||
ent.notifyTS = 0;
|
||||
|
||||
/* fill in hashes */
|
||||
ent.hash1 = RsUtil::HashId(id, false);
|
||||
ent.hash2 = RsUtil::HashId(id, true);
|
||||
|
||||
/* other fields don't matter */
|
||||
|
||||
peers[id] = ent;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3DhtMgr::dropPeer(std::string id)
|
||||
{
|
||||
dhtMtx.lock(); /* LOCK MUTEX */
|
||||
RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/
|
||||
|
||||
mDhtModifications = true;
|
||||
|
||||
@ -232,15 +228,11 @@ bool p3DhtMgr::dropPeer(std::string id)
|
||||
it = peers.find(id);
|
||||
if (it == peers.end())
|
||||
{
|
||||
/* ignore */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* remove */
|
||||
peers.erase(it);
|
||||
return false;
|
||||
}
|
||||
|
||||
dhtMtx.unlock(); /* UNLOCK MUTEX */
|
||||
/* remove */
|
||||
peers.erase(it);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -248,31 +240,46 @@ bool p3DhtMgr::dropPeer(std::string id)
|
||||
/* post DHT key saying we should connect */
|
||||
bool p3DhtMgr::notifyPeer(std::string id)
|
||||
{
|
||||
dhtMtx.lock(); /* LOCK MUTEX */
|
||||
RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/
|
||||
#ifdef DHT_DEBUG
|
||||
std::cerr << "p3DhtMgr::notifyPeer() " << id << std::endl;
|
||||
#endif
|
||||
|
||||
mDhtModifications = true;
|
||||
|
||||
/* once we are connected ... don't worry about them anymore */
|
||||
std::map<std::string, dhtPeerEntry>::iterator it;
|
||||
it = peers.find(id);
|
||||
bool ret = true;
|
||||
if (it == peers.end())
|
||||
{
|
||||
/* ignore */
|
||||
ret = false;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
||||
time_t now = time(NULL);
|
||||
|
||||
if (now - it->second.notifyTS < 2 * DHT_NOTIFY_PERIOD)
|
||||
{
|
||||
it->second.notifyPending = RS_CONNECT_ACTIVE;
|
||||
it->second.notifyTS = time(NULL);
|
||||
/* drop the notify (too soon) */
|
||||
#ifdef DHT_DEBUG
|
||||
std::cerr << "p3DhtMgr::notifyPeer() TO SOON - DROPPING" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
dhtMtx.unlock(); /* UNLOCK MUTEX */
|
||||
it->second.notifyPending = RS_CONNECT_ACTIVE;
|
||||
it->second.notifyTS = time(NULL);
|
||||
|
||||
return ret;
|
||||
/* Trigger search if not found! */
|
||||
if (it->second.state != DHT_PEER_FOUND)
|
||||
{
|
||||
#ifdef DHT_DEBUG
|
||||
std::cerr << "p3DhtMgr::notifyPeer() PEER NOT FOUND - Trigger search" << std::endl;
|
||||
#endif
|
||||
it->second.lastTS = 0;
|
||||
}
|
||||
|
||||
mDhtModifications = true; /* no wait! */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* extract current peer status */
|
||||
bool p3DhtMgr::getPeerStatus(std::string id,
|
||||
struct sockaddr_in &laddr,
|
||||
@ -680,12 +687,12 @@ int p3DhtMgr::checkPeerDHTKeys()
|
||||
return repeatPeriod;
|
||||
}
|
||||
|
||||
/* update timestamp */
|
||||
/* update timestamp
|
||||
* clear FOUND or INIT state.
|
||||
* */
|
||||
|
||||
pit->second.lastTS = now;
|
||||
if (pit->second.state == DHT_PEER_INIT)
|
||||
{
|
||||
pit->second.state = DHT_PEER_SEARCH;
|
||||
}
|
||||
pit->second.state = DHT_PEER_SEARCH;
|
||||
|
||||
dhtPeerEntry peer = (pit->second);
|
||||
|
||||
@ -705,8 +712,12 @@ int p3DhtMgr::checkNotifyDHT()
|
||||
std::cerr << "p3DhtMgr::checkNotifyDHT()" << std::endl;
|
||||
#endif
|
||||
/* now loop through the peers */
|
||||
uint32_t notifyType = 0;
|
||||
dhtPeerEntry peer;
|
||||
dhtPeerEntry own;
|
||||
|
||||
dhtMtx.lock(); /* LOCK MUTEX */
|
||||
{
|
||||
RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/
|
||||
|
||||
/* iterate through and find min time and suitable candidate */
|
||||
std::map<std::string, dhtPeerEntry>::iterator it;
|
||||
@ -716,46 +727,68 @@ int p3DhtMgr::checkNotifyDHT()
|
||||
/* find the first with a notify flag */
|
||||
for(it = peers.begin(); it != peers.end(); it++)
|
||||
{
|
||||
if ((it->second.state == DHT_PEER_FOUND) &&
|
||||
(it->second.notifyPending == RS_CONNECT_ACTIVE))
|
||||
if (it->second.notifyPending)
|
||||
{
|
||||
break;
|
||||
if (it->second.state == DHT_PEER_FOUND)
|
||||
{
|
||||
notifyType = it->second.notifyPending;
|
||||
break;
|
||||
}
|
||||
|
||||
/* if very old drop it */
|
||||
if (now - it->second.notifyTS > DHT_NOTIFY_PERIOD)
|
||||
{
|
||||
#ifdef DHT_DEBUG
|
||||
std::cerr << "p3DhtMgr::checkNotifyDHT() Dropping OLD Notify: ";
|
||||
std::cerr << it->first << std::endl;
|
||||
#endif
|
||||
it->second.notifyPending = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* now have - peer to handle */
|
||||
if (it == peers.end())
|
||||
{
|
||||
dhtMtx.unlock(); /* UNLOCK MUTEX */
|
||||
return repeatPeriod;
|
||||
}
|
||||
|
||||
#ifdef DHT_DEBUG
|
||||
std::cerr << "p3DhtMgr::checkNotifyDHT() Notify From: ";
|
||||
std::cerr << it->first << std::endl;
|
||||
#endif
|
||||
|
||||
/* update timestamp */
|
||||
it->second.notifyTS = now;
|
||||
it->second.notifyPending = 0;
|
||||
|
||||
dhtPeerEntry peer = (it->second);
|
||||
dhtPeerEntry own = ownEntry;
|
||||
peer = (it->second);
|
||||
own = ownEntry;
|
||||
|
||||
dhtMtx.unlock(); /* UNLOCK MUTEX */
|
||||
} /******* UNLOCK ******/
|
||||
|
||||
/* publish notification (publish Our Id)
|
||||
* We publish the connection attempt on peers hash,
|
||||
* using our alternative hash..
|
||||
* */
|
||||
|
||||
if (dhtNotify(peer.hash1, own.hash2, ""))
|
||||
if (notifyType == RS_CONNECT_ACTIVE)
|
||||
{
|
||||
/* feedback to say we started it! */
|
||||
#ifdef P3DHTMGR_USE_LOCAL_UDP_CONN
|
||||
connCb->peerConnectRequest(peer.id, peer.laddr, RS_CB_DHT);
|
||||
#else
|
||||
connCb->peerConnectRequest(peer.id, peer.raddr, RS_CB_DHT);
|
||||
/* publish notification (publish Our Id)
|
||||
* We publish the connection attempt on peers hash,
|
||||
* using our alternative hash..
|
||||
* */
|
||||
#ifdef DHT_DEBUG
|
||||
std::cerr << "p3DhtMgr::checkNotifyDHT() Posting Active Notify";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
dhtNotify(peer.hash1, own.hash2, "");
|
||||
}
|
||||
|
||||
/* feedback to say we started it! */
|
||||
#ifdef P3DHTMGR_USE_LOCAL_UDP_CONN
|
||||
connCb->peerConnectRequest(peer.id, peer.laddr, RS_CB_DHT);
|
||||
#else
|
||||
connCb->peerConnectRequest(peer.id, peer.raddr, RS_CB_DHT);
|
||||
#endif
|
||||
|
||||
repeatPeriod = DHT_MIN_PERIOD;
|
||||
return repeatPeriod;
|
||||
return DHT_MIN_PERIOD;
|
||||
}
|
||||
|
||||
|
||||
@ -1239,14 +1272,13 @@ bool p3DhtMgr::resultDHT(std::string key, std::string value)
|
||||
|
||||
bool p3DhtMgr::dhtResultNotify(std::string idhash)
|
||||
{
|
||||
dhtMtx.lock(); /* LOCK MUTEX */
|
||||
RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/
|
||||
|
||||
#ifdef DHT_DEBUG
|
||||
std::cerr << "p3DhtMgr::dhtResultNotify() from idhash: ";
|
||||
std::cerr << RsUtil::BinToHex(idhash) << std::endl;
|
||||
#endif
|
||||
std::map<std::string, dhtPeerEntry>::iterator it;
|
||||
bool doNotify = false;
|
||||
time_t now = time(NULL);
|
||||
|
||||
/* if notify - we must match on the second hash */
|
||||
@ -1254,7 +1286,6 @@ bool p3DhtMgr::dhtResultNotify(std::string idhash)
|
||||
|
||||
/* update data */
|
||||
std::string peerid;
|
||||
struct sockaddr_in raddr, laddr;
|
||||
|
||||
if (it != peers.end())
|
||||
{
|
||||
@ -1263,22 +1294,14 @@ bool p3DhtMgr::dhtResultNotify(std::string idhash)
|
||||
#endif
|
||||
/* delay callback -> if they are not found */
|
||||
it->second.notifyTS = now;
|
||||
it->second.notifyPending = RS_CONNECT_PASSIVE;
|
||||
mDhtModifications = true; /* no wait! */
|
||||
|
||||
if (it->second.state != DHT_PEER_FOUND)
|
||||
{
|
||||
doNotify = false;
|
||||
it->second.notifyPending = RS_CONNECT_PASSIVE;
|
||||
/* flag for immediate search */
|
||||
mDhtModifications = true; /* no wait! */
|
||||
it->second.lastTS = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
doNotify = true;
|
||||
it->second.notifyPending = 0;
|
||||
peerid = (it->second).id;
|
||||
raddr = (it->second).raddr;
|
||||
laddr = (it->second).laddr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1288,18 +1311,6 @@ bool p3DhtMgr::dhtResultNotify(std::string idhash)
|
||||
#endif
|
||||
}
|
||||
|
||||
dhtMtx.unlock(); /* UNLOCK MUTEX */
|
||||
|
||||
/* do callback */
|
||||
if (doNotify)
|
||||
{
|
||||
#ifdef P3DHTMGR_USE_LOCAL_UDP_CONN
|
||||
connCb->peerConnectRequest(peerid, laddr, RS_CB_DHT);
|
||||
#else
|
||||
connCb->peerConnectRequest(peerid, raddr, RS_CB_DHT);
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1316,7 +1327,6 @@ bool p3DhtMgr::dhtResultSearch(std::string idhash,
|
||||
#endif
|
||||
std::map<std::string, dhtPeerEntry>::iterator it;
|
||||
bool doCb = false;
|
||||
bool doNotify = false;
|
||||
bool doStun = false;
|
||||
uint32_t stunFlags = 0;
|
||||
time_t now = time(NULL);
|
||||
@ -1334,39 +1344,25 @@ bool p3DhtMgr::dhtResultSearch(std::string idhash,
|
||||
#endif
|
||||
it->second.lastTS = now;
|
||||
|
||||
/* has it changed??? */
|
||||
if ((it->second.state != DHT_PEER_FOUND) ||
|
||||
(0 != sockaddr_cmp(it->second.laddr,laddr)) ||
|
||||
(0 != sockaddr_cmp(it->second.raddr,raddr)) ||
|
||||
(it->second.type != type))
|
||||
/* Do callback all the time */
|
||||
ent = it->second;
|
||||
doCb = true;
|
||||
|
||||
/* update info .... always */
|
||||
it->second.state = DHT_PEER_FOUND;
|
||||
it->second.laddr = laddr;
|
||||
it->second.raddr = raddr;
|
||||
it->second.type = type;
|
||||
|
||||
if (it->second.notifyPending)
|
||||
{
|
||||
it->second.state = DHT_PEER_FOUND;
|
||||
it->second.laddr = laddr;
|
||||
it->second.raddr = raddr;
|
||||
it->second.type = type;
|
||||
ent = it->second;
|
||||
doCb = true;
|
||||
/* no wait if we have pendingNotification */
|
||||
mDhtModifications = true;
|
||||
}
|
||||
|
||||
/* do we have a pending notify */
|
||||
if ((it->second.state == DHT_PEER_FOUND) &&
|
||||
(it->second.notifyPending == RS_CONNECT_PASSIVE))
|
||||
{
|
||||
it->second.notifyPending = 0;
|
||||
doNotify = true;
|
||||
}
|
||||
|
||||
/* if stun not happy yet - doStun as well..
|
||||
* as the DHT doesn't know if the Stun is happy - send
|
||||
* it through always!
|
||||
* if ((mDhtState != DHT_STATE_OFF) &&
|
||||
* (mDhtState != DHT_STATE_ACTIVE))
|
||||
*/
|
||||
if (mDhtState != DHT_STATE_OFF)
|
||||
{
|
||||
doStun = true;
|
||||
stunFlags = RS_STUN_FRIEND | RS_STUN_ONLINE;
|
||||
}
|
||||
/* do Stun always */
|
||||
doStun = true;
|
||||
stunFlags = RS_STUN_FRIEND | RS_STUN_ONLINE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1381,21 +1377,10 @@ bool p3DhtMgr::dhtResultSearch(std::string idhash,
|
||||
|
||||
dhtMtx.unlock(); /* UNLOCK MUTEX */
|
||||
|
||||
/* if changed - do callback */
|
||||
if (doCb)
|
||||
{
|
||||
connCb->peerStatus(ent.id,
|
||||
ent.laddr, ent.raddr,
|
||||
connCb->peerStatus(ent.id, ent.laddr, ent.raddr,
|
||||
ent.type, 0, RS_CB_DHT);
|
||||
//ent.type, RS_CB_LOCAL_ADDR | RS_CB_REMOTE_ADDR, RS_CB_DHT);
|
||||
if (doNotify)
|
||||
{
|
||||
#ifdef P3DHTMGR_USE_LOCAL_UDP_CONN
|
||||
connCb->peerConnectRequest(ent.id, ent.laddr, RS_CB_DHT);
|
||||
#else
|
||||
connCb->peerConnectRequest(ent.id, ent.raddr, RS_CB_DHT);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (doStun)
|
||||
|
@ -101,6 +101,7 @@ class RsPeerDetails
|
||||
|
||||
/* basic stats */
|
||||
uint32_t lastConnect; /* how long ago */
|
||||
std::string autoconnect;
|
||||
uint32_t connectPeriod;
|
||||
};
|
||||
|
||||
|
@ -325,6 +325,40 @@ bool p3Peers::getPeerDetails(std::string id, RsPeerDetails &d)
|
||||
d.visState |= RS_VS_DHT_ON;
|
||||
}
|
||||
|
||||
|
||||
/* Finally determine AutoConnect Status */
|
||||
std::ostringstream autostr;
|
||||
if (pcs.inConnAttempt)
|
||||
{
|
||||
/*
|
||||
*/
|
||||
autostr << "Trying ";
|
||||
switch(pcs.currentConnAddr.type)
|
||||
{
|
||||
case RS_NET_CONN_TCP_LOCAL:
|
||||
autostr << "TCP (Local)";
|
||||
break;
|
||||
case RS_NET_CONN_TCP_EXTERNAL:
|
||||
autostr << "TCP (External)";
|
||||
break;
|
||||
case RS_NET_CONN_UDP_DHT_SYNC:
|
||||
autostr << "UDP (ETA: ";
|
||||
autostr << 360 - (time(NULL) - pcs.currentConnAddr.ts);
|
||||
autostr << ")";
|
||||
break;
|
||||
default:
|
||||
autostr << "Unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
autostr << "Idle";
|
||||
}
|
||||
|
||||
d.autoconnect = autostr.str();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,9 @@
|
||||
|
||||
#include "services/p3chatservice.h"
|
||||
|
||||
#define CHAT_DEBUG 1
|
||||
/****
|
||||
* #define CHAT_DEBUG 1
|
||||
****/
|
||||
|
||||
/************ NOTE *********************************
|
||||
* This Service is so simple that there is no
|
||||
|
@ -59,7 +59,9 @@ const uint32_t P3DISC_FLAGS_PEER_ONLINE = 0x0010;
|
||||
const uint32_t P3DISC_FLAGS_OWN_DETAILS = 0x0020;
|
||||
|
||||
|
||||
#define P3DISC_DEBUG 1
|
||||
/*****
|
||||
* #define P3DISC_DEBUG 1
|
||||
****/
|
||||
|
||||
/*********** NOTE ***************
|
||||
*
|
||||
|
@ -39,7 +39,6 @@
|
||||
/*
|
||||
* #define DEBUG_TCP_STREAM 1
|
||||
*/
|
||||
#define DEBUG_TCP_STREAM 1
|
||||
|
||||
/*
|
||||
*#define DEBUG_TCP_STREAM_EXTRA 1
|
||||
|
@ -403,6 +403,7 @@ int tou_close(int sockfd)
|
||||
|
||||
/* shut it down */
|
||||
tous->tcp->close();
|
||||
udps->removeUdpPeer(tous->tcp);
|
||||
delete tous->tcp;
|
||||
}
|
||||
|
||||
|
@ -44,9 +44,9 @@
|
||||
#include <errno.h>
|
||||
*/
|
||||
|
||||
/*
|
||||
*/ #define DEBUG_UDP_LAYER 1
|
||||
/**/
|
||||
/***
|
||||
* #define DEBUG_UDP_LAYER 1
|
||||
***/
|
||||
|
||||
static const int UDP_DEF_TTL = 64;
|
||||
|
||||
|
@ -189,6 +189,30 @@ int UdpSorter::addUdpPeer(UdpPeer *peer, const struct sockaddr_in &raddr)
|
||||
return ok;
|
||||
}
|
||||
|
||||
int UdpSorter::removeUdpPeer(UdpPeer *peer)
|
||||
{
|
||||
RsStackMutex stack(sortMtx); /********** LOCK MUTEX *********/
|
||||
|
||||
/* check for duplicate */
|
||||
std::map<struct sockaddr_in, UdpPeer *>::iterator it;
|
||||
for(it = streams.begin(); it != streams.end(); it++)
|
||||
{
|
||||
if (it->second == peer)
|
||||
{
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::removeUdpPeer() SUCCESS" << std::endl;
|
||||
#endif
|
||||
streams.erase(it);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_UDP_SORTER
|
||||
std::cerr << "UdpSorter::removeUdpPeer() ERROR" << std::endl;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************* STUN Handling ********************************/
|
||||
|
||||
|
@ -71,6 +71,7 @@ virtual ~UdpSorter() { return; }
|
||||
|
||||
/* add a TCPonUDP stream */
|
||||
int addUdpPeer(UdpPeer *peer, const struct sockaddr_in &raddr);
|
||||
int removeUdpPeer(UdpPeer *peer);
|
||||
|
||||
bool setStunKeepAlive(uint32_t required);
|
||||
bool addStunPeer(const struct sockaddr_in &remote, const char *peerid);
|
||||
|
@ -164,6 +164,8 @@ void PeersDialog::insertPeers()
|
||||
QTreeWidget *peerWidget = ui.peertreeWidget;
|
||||
QTreeWidgetItem *oldSelect = getCurrentPeer();
|
||||
QTreeWidgetItem *newSelect = NULL;
|
||||
time_t now = time(NULL);
|
||||
|
||||
std::string oldId;
|
||||
if (oldSelect)
|
||||
{
|
||||
@ -200,7 +202,7 @@ void PeersDialog::insertPeers()
|
||||
item -> setText(2, QString::fromStdString(detail.name));
|
||||
|
||||
/* (2) Auto Connect */
|
||||
item -> setText(3, QString::fromStdString("Yes"));
|
||||
item -> setText(3, QString::fromStdString(detail.autoconnect));
|
||||
|
||||
/* (3) Trust Level */
|
||||
item -> setText(4,QString::fromStdString(
|
||||
@ -219,7 +221,7 @@ void PeersDialog::insertPeers()
|
||||
/* less important ones */
|
||||
/* () Last Contact */
|
||||
item -> setText(6,QString::fromStdString(
|
||||
RsPeerLastConnectString(detail.lastConnect)));
|
||||
RsPeerLastConnectString(now - detail.lastConnect)));
|
||||
|
||||
/* () Org */
|
||||
item -> setText(7, QString::fromStdString(detail.org));
|
||||
@ -271,7 +273,7 @@ void PeersDialog::insertPeers()
|
||||
}
|
||||
else
|
||||
{
|
||||
if (detail.lastConnect < 10000)
|
||||
if (now - detail.lastConnect < 3600)
|
||||
{
|
||||
for(i = 1; i < 12; i++)
|
||||
{
|
||||
|
@ -101,6 +101,7 @@ class RsPeerDetails
|
||||
|
||||
/* basic stats */
|
||||
uint32_t lastConnect; /* how long ago */
|
||||
std::string autoconnect;
|
||||
uint32_t connectPeriod;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user