added basic communication between FriendServer and its clients

This commit is contained in:
csoler 2021-10-30 15:50:28 +02:00
parent d948086b5e
commit ffa28000e3
8 changed files with 165 additions and 12 deletions

View File

@ -21,19 +21,60 @@
******************************************************************************/
#include "pqi/pqithreadstreamer.h"
#include "retroshare/rspeers.h"
#include "fsclient.h"
#include "fsbio.h"
FsClient::FsClient(const std::string& address)
: mServerAddress(address)
bool FsClient::requestFriends(const std::string& address,uint16_t port,uint32_t reqs,std::map<std::string,bool>& friend_certificates)
{
// send our own certificate to publish and expects response frmo the server , decrypts it and reutnrs friend list
RsFriendServerClientPublishItem *pitem = new RsFriendServerClientPublishItem();
pitem->n_requested_friends = reqs;
pitem->long_invite = rsPeers->GetRetroshareInvite();
std::list<RsItem*> response;
sendItem(address,port,pitem,response);
// now decode the response
friend_certificates.clear();
for(auto item:response)
{
auto *encrypted_response_item = dynamic_cast<RsFriendServerEncryptedServerResponseItem*>(item);
if(!encrypted_response_item)
{
delete item;
continue;
}
// For now, also handle unencrypted response items. Will be disabled in production
auto *response_item = dynamic_cast<RsFriendServerServerResponseItem*>(item);
if(!response_item)
{
delete item;
continue;
}
for(const auto& it:response_item->friend_invites)
friend_certificates.insert(it);
}
return friend_certificates.size();
}
bool FsClient::sendItem(RsItem *item)
bool FsClient::sendItem(const std::string& address,uint16_t port,RsItem *item,std::list<RsItem*>& response)
{
// open a connection
RsDbg() << "Sending item to friend server at \"" << address << ":" << port ;
int CreateSocket = 0,n = 0;
char dataReceived[1024];
struct sockaddr_in ipOfServer;
@ -47,8 +88,8 @@ bool FsClient::sendItem(RsItem *item)
}
ipOfServer.sin_family = AF_INET;
ipOfServer.sin_port = htons(2017);
ipOfServer.sin_addr.s_addr = inet_addr("127.0.0.1");
ipOfServer.sin_port = htons(port);
ipOfServer.sin_addr.s_addr = inet_addr(address.c_str());
if(connect(CreateSocket, (struct sockaddr *)&ipOfServer, sizeof(ipOfServer))<0)
{
@ -89,7 +130,7 @@ bool FsClient::sendItem(RsItem *item)
if(!item)
{
rstime::rs_usleep(1000*200);
std::this_thread::sleep_for(std::chrono::milliseconds(200));
continue;
}

View File

@ -28,11 +28,11 @@
class FsClient
{
public:
FsClient(const std::string& address);
FsClient() {}
bool sendItem(RsItem *item);
bool requestFriends(const std::string& address,uint16_t port,uint32_t reqs,std::map<std::string,bool>& friend_certificates);
private:
std::string mServerAddress;
bool sendItem(const std::string &address, uint16_t port, RsItem *item, std::list<RsItem *> &response);
};

View File

@ -1,7 +1,24 @@
#include <cmath>
#include "fsmanager.h"
#include "fsclient.h"
RsFriendServer *rsFriendServer = nullptr;
static const rstime_t MIN_DELAY_BETWEEN_FS_REQUESTS = 30;
static const rstime_t MAX_DELAY_BETWEEN_FS_REQUESTS = 3600;
static const uint32_t DEFAULT_FRIENDS_TO_REQUEST = 10;
static const std::string DEFAULT_FRIEND_SERVER_ADDRESS = "127.0.0.1";
static const uint16_t DEFAULT_FRIEND_SERVER_PORT = 2017;
FriendServerManager::FriendServerManager()
{
mLastFriendReqestCampain = 0;
mFriendsToRequest = DEFAULT_FRIENDS_TO_REQUEST;
mServerAddress = DEFAULT_FRIEND_SERVER_ADDRESS;
mServerPort = DEFAULT_FRIEND_SERVER_PORT;
}
void FriendServerManager::startServer()
{
if(!isRunning())
@ -41,4 +58,53 @@ void FriendServerManager::threadTick()
{
std::cerr << "Ticking FriendServerManager..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(2));
// Check for requests. Compute how much to wait based on how many friends we have already
std::vector<RsPgpId> friends;
rsPeers->getPgpFriendList(friends);
// log-scale interpolation of the delay between two requests.
if(mFriendsToRequest == 0 || mFriendsToRequest < friends.size())
{
RsErr() << "No friends to request! This is unexpected. Returning." << std::endl;
return;
}
// This formula makes RS wait much longuer between two requests to the server when the number of friends is close the
// wanted number
// Delay for 0 friends: 30 secs.
// Delay for 1 friends: 30 secs.
// Delay for 2 friends: 32 secs.
// Delay for 3 friends: 35 secs.
// Delay for 4 friends: 44 secs.
// Delay for 5 friends: 66 secs.
// Delay for 6 friends: 121 secs.
// Delay for 7 friends: 258 secs.
// Delay for 8 friends: 603 secs.
// Delay for 9 friends: 1466 secs.
RsDbg() << friends.size() << " friends already, " << mFriendsToRequest << " friends to request";
double s = (friends.size() < mFriendsToRequest)? ( (mFriendsToRequest - friends.size())/(double)mFriendsToRequest) : 1.0;
rstime_t delay_for_request = MIN_DELAY_BETWEEN_FS_REQUESTS + (int)floor(exp(-1*s + log(MAX_DELAY_BETWEEN_FS_REQUESTS)*(1.0-s)));
std::cerr << "Delay for " << friends.size() << " friends: " << delay_for_request << " secs." << std::endl;
rstime_t now = time(nullptr);
if(mLastFriendReqestCampain + delay_for_request < now)
{
std::cerr << "Requesting new friends to friend server..." << std::endl;
std::map<std::string,bool> friend_certificates;
FsClient().requestFriends(mServerAddress,mServerPort,mFriendsToRequest,friend_certificates); // blocking call
std::cerr << "Got the following list of friend certificates:" << std::endl;
for(const auto& it:friend_certificates)
std::cerr << it.first << " : " << it.second << std::endl;
}
}

View File

@ -15,11 +15,14 @@ struct FriendServerPeerInfo
};
uint32_t status ;
rstime_t received_TS;
};
class FriendServerManager: public RsFriendServer, public RsTickingThread
{
public:
FriendServerManager();
virtual void startServer() override ;
virtual void stopServer() override ;
@ -27,11 +30,15 @@ public:
virtual void setServerAddress(const std::string&,uint16_t) override ;
virtual void setFriendsToRequest(uint32_t) override ;
virtual uint32_t friendsToRequest() override { return mFriendsToRequest ; }
virtual uint16_t friendsServerPort() override { return mServerPort ; }
virtual std::string friendsServerAddress() override { return mServerAddress ; }
protected:
virtual void threadTick() override;
private:
uint32_t mFriendsToRequest;
rstime_t mLastFriendReqestCampain;
// encode the current list of friends obtained through the friendserver and their status

View File

@ -29,6 +29,10 @@ public:
virtual void checkServerAddress_async(const std::string& addr,uint16_t, const std::function<void (const std::string& address,bool result_status)>& callback) =0;
virtual void setServerAddress(const std::string&,uint16_t) =0;
virtual void setFriendsToRequest(uint32_t) =0;
virtual uint32_t friendsToRequest() =0;
virtual uint16_t friendsServerPort() =0;
virtual std::string friendsServerAddress() =0;
};
extern RsFriendServer *rsFriendServer;

View File

@ -40,12 +40,28 @@ FriendServerControl::FriendServerControl(QWidget *parent)
/* Invoke the Qt Designer generated object setup routine */
setupUi(this);
if(!rsFriendServer)
{
setEnabled(false);
return;
}
mConnectionCheckTimer = new QTimer;
// init values
torServerFriendsToRequest_SB->setValue(rsFriendServer->friendsToRequest());
torServerAddress_LE->setText(QString::fromStdString(rsFriendServer->friendsServerAddress().c_str()));
torServerPort_SB->setValue(rsFriendServer->friendsServerPort());
// connect slignals/slots
QObject::connect(friendServerOnOff_CB,SIGNAL(toggled(bool)),this,SLOT(onOnOffClick(bool)));
QObject::connect(mConnectionCheckTimer,SIGNAL(timeout()),this,SLOT(checkServerAddress()));
QObject::connect(torServerFriendsToRequest_SB,SIGNAL(valueChanged(int)),this,SLOT(onFriendsToRequestChanged(int)));
QObject::connect(torServerAddress_LE,SIGNAL(textChanged(const QString&)),this,SLOT(onOnionAddressEdit(const QString&)));
QObject::connect(mConnectionCheckTimer,SIGNAL(timeout()),this,SLOT(checkServerAddress()));
mCheckingServerMovie = new QMovie(":/images/loader/circleball-16.gif");
serverStatusCheckResult_LB->setMovie(mCheckingServerMovie);
@ -65,6 +81,21 @@ void FriendServerControl::onOnOffClick(bool b)
else
rsFriendServer->stopServer();
}
void FriendServerControl::onOnionPortEdit(int)
{
// Setup timer to auto-check the friend server address
mConnectionCheckTimer->setSingleShot(true);
mConnectionCheckTimer->setInterval(5000); // check in 5 secs unless something is changed in the mean time.
mConnectionCheckTimer->start();
if(mCheckingServerMovie->fileName() != QString(":/images/loader/circleball-16.gif" ))
{
mCheckingServerMovie->setFileName(":/images/loader/circleball-16.gif");
mCheckingServerMovie->start();
}
}
void FriendServerControl::onOnionAddressEdit(const QString&)
{

View File

@ -35,10 +35,11 @@ public:
protected slots:
void onOnOffClick(bool b);
void onOnionAddressEdit(const QString&);
void onOnionPortEdit(int);
void onNbFriendsToRequestsChanged(int n);
void checkServerAddress();
private:
void checkServerAddress();
void updateFriendServerStatusIcon(bool ok);
QTimer *mConnectionCheckTimer;

View File

@ -72,6 +72,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>127.0.0.1</string>
</property>
</widget>
</item>
<item>
@ -108,7 +111,7 @@
<number>65536</number>
</property>
<property name="value">
<number>1729</number>
<number>2017</number>
</property>
</widget>
</item>