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:
drbob 2008-03-02 14:25:59 +00:00
parent 7b3fc2976e
commit 63828f77a8
20 changed files with 708 additions and 203 deletions

View file

@ -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; }

View file

@ -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 */

View file

@ -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;

View file

@ -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()

View file

@ -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;

View file

@ -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);