Merge branch 'master' of https://github.com/myfingerhurt/RetroShare into myfingerhurt-webui-PR1014

This commit is contained in:
Gioacchino Mazzurco 2017-09-15 08:25:30 +02:00
commit 016cafdd23
2 changed files with 518 additions and 293 deletions

View File

@ -32,6 +32,11 @@
#include "Operators.h" #include "Operators.h"
#include "ApiTypes.h" #include "ApiTypes.h"
//#include "util/rsdebug.h"
//static struct RsLog::logInfo peersHandlerInfo = {RsLog::Default, "peersHandler"};
//#define peerhandlerzone &peersHandlerInfo
namespace resource_api namespace resource_api
{ {
@ -45,37 +50,38 @@ namespace resource_api
void peerDetailsToStream(StreamBase& stream, RsPeerDetails& details) void peerDetailsToStream(StreamBase& stream, RsPeerDetails& details)
{ {
std::string nodeType_string; std::string nodeType_string;
if(details.isHiddenNode) if(details.isHiddenNode)
{ {
switch (details.hiddenType) switch (details.hiddenType)
{ {
case RS_HIDDEN_TYPE_I2P: case RS_HIDDEN_TYPE_I2P:
nodeType_string = "I2P"; nodeType_string = "I2P";
break; break;
case RS_HIDDEN_TYPE_TOR: case RS_HIDDEN_TYPE_TOR:
nodeType_string = "TOR"; nodeType_string = "TOR";
break; break;
case RS_HIDDEN_TYPE_NONE: case RS_HIDDEN_TYPE_NONE:
nodeType_string = "None"; nodeType_string = "None";
break; break;
case RS_HIDDEN_TYPE_UNKNOWN: case RS_HIDDEN_TYPE_UNKNOWN:
nodeType_string = "Unknown"; nodeType_string = "Unknown";
break; break;
default: default:
nodeType_string = "Undefined"; nodeType_string = "Undefined";
} }
}else{ }else{
nodeType_string = "Normal"; nodeType_string = "Normal";
} }
stream stream
<< makeKeyValueReference("peer_id", details.id) << makeKeyValueReference("pgp_id" , details.gpg_id)
<< makeKeyValueReference("name", details.name) << makeKeyValueReference("peer_id" , details.id)
<< makeKeyValueReference("location", details.location) << makeKeyValueReference("name" , details.name)
<< makeKeyValueReference("pgp_id", details.gpg_id) << makeKeyValueReference("location" , details.location)
<< makeKeyValueReference("isHiddenNode", details.isHiddenNode) << makeKeyValueReference("is_hidden_node", details.isHiddenNode)
<< makeKeyValueReference("nodeType", nodeType_string ); << makeKeyValueReference("nodeType" , nodeType_string )
<< makeKeyValueReference("last_contact" , details.lastConnect );
if(details.state & RS_PEER_STATE_CONNECTED) if(details.state & RS_PEER_STATE_CONNECTED)
{ {
@ -123,34 +129,34 @@ void peerDetailsToStream(StreamBase& stream, RsPeerDetails& details)
bool peerInfoToStream(StreamBase& stream, RsPeerDetails& details, RsPeers* peers, std::list<RsGroupInfo>& grpInfo, bool have_avatar) bool peerInfoToStream(StreamBase& stream, RsPeerDetails& details, RsPeers* peers, std::list<RsGroupInfo>& grpInfo, bool have_avatar)
{ {
bool ok = true; bool ok = true;
peerDetailsToStream(stream, details); peerDetailsToStream(stream, details);
stream << makeKeyValue("is_online", peers->isOnline(details.id)) stream << makeKeyValue("is_online", peers->isOnline(details.id))
<< makeKeyValue("chat_id", ChatId(details.id).toStdString()) << makeKeyValue("chat_id", ChatId(details.id).toStdString())
<< makeKeyValue("custom_state_string", rsMsgs->getCustomStateString(details.id)); << makeKeyValue("custom_state_string", rsMsgs->getCustomStateString(details.id));
std::string avatar_address = "/"+details.id.toStdString()+"/avatar_image"; std::string avatar_address = "/"+details.id.toStdString()+"/avatar_image";
if(!have_avatar) if(!have_avatar)
avatar_address = ""; avatar_address = "";
stream << makeKeyValue("avatar_address", avatar_address); stream << makeKeyValue("avatar_address", avatar_address);
StreamBase& grpStream = stream.getStreamToMember("groups"); StreamBase& grpStream = stream.getStreamToMember("groups");
for(std::list<RsGroupInfo>::iterator lit = grpInfo.begin(); lit != grpInfo.end(); lit++) for(std::list<RsGroupInfo>::iterator lit = grpInfo.begin(); lit != grpInfo.end(); lit++)
{ {
RsGroupInfo& grp = *lit; RsGroupInfo& grp = *lit;
if(std::find(grp.peerIds.begin(), grp.peerIds.end(), details.gpg_id) != grp.peerIds.end()) if(std::find(grp.peerIds.begin(), grp.peerIds.end(), details.gpg_id) != grp.peerIds.end())
{ {
grpStream.getStreamToMember() grpStream.getStreamToMember()
<< makeKeyValueReference("group_name", grp.name) << makeKeyValueReference("group_name", grp.name)
<< makeKeyValueReference("group_id", grp.id); << makeKeyValueReference("group_id", grp.id);
} }
} }
return ok; return ok;
} }
std::string peerStateString(int peerState) std::string peerStateString(int peerState)
@ -231,16 +237,14 @@ std::string connectStateString(RsPeerDetails &details)
return stateString; return stateString;
} }
PeersHandler::PeersHandler(StateTokenServer* sts, RsNotify* notify, RsPeers *peers, RsMsgs* msgs): PeersHandler::PeersHandler( StateTokenServer* sts, RsNotify* notify,
mStateTokenServer(sts), RsPeers *peers, RsMsgs* msgs ) :
mNotify(notify), mStateTokenServer(sts), mNotify(notify), mRsPeers(peers), mRsMsgs(msgs),
mRsPeers(peers), mRsMsgs(msgs), status(0), mMtx("PeersHandler Mutex")
status(0),
mMtx("PeersHandler Mutex")
{ {
mNotify->registerNotifyClient(this); mNotify->registerNotifyClient(this);
mStateTokenServer->registerTickClient(this); mStateTokenServer->registerTickClient(this);
addResourceHandler("*", this, &PeersHandler::handleWildcard); addResourceHandler("*", this, &PeersHandler::handleWildcard);
addResourceHandler("attempt_connection", this, &PeersHandler::handleAttemptConnection); addResourceHandler("attempt_connection", this, &PeersHandler::handleAttemptConnection);
addResourceHandler("get_state_string", this, &PeersHandler::handleGetStateString); addResourceHandler("get_state_string", this, &PeersHandler::handleGetStateString);
addResourceHandler("set_state_string", this, &PeersHandler::handleSetStateString); addResourceHandler("set_state_string", this, &PeersHandler::handleSetStateString);
@ -253,23 +257,25 @@ PeersHandler::PeersHandler(StateTokenServer* sts, RsNotify* notify, RsPeers *pee
addResourceHandler("get_node_options", this, &PeersHandler::handleGetNodeOptions); addResourceHandler("get_node_options", this, &PeersHandler::handleGetNodeOptions);
addResourceHandler("set_node_options", this, &PeersHandler::handleSetNodeOptions); addResourceHandler("set_node_options", this, &PeersHandler::handleSetNodeOptions);
addResourceHandler("examine_cert", this, &PeersHandler::handleExamineCert); addResourceHandler("examine_cert", this, &PeersHandler::handleExamineCert);
addResourceHandler("remove_node", this, &PeersHandler::handleRemoveNode);
addResourceHandler("get_inactive_users", this, &PeersHandler::handleGetInactiveUsers);
} }
PeersHandler::~PeersHandler() PeersHandler::~PeersHandler()
{ {
mNotify->unregisterNotifyClient(this); mNotify->unregisterNotifyClient(this);
mStateTokenServer->unregisterTickClient(this); mStateTokenServer->unregisterTickClient(this);
} }
void PeersHandler::notifyListChange(int list, int /* type */) void PeersHandler::notifyListChange(int list, int /* type */)
{ {
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
if(list == NOTIFY_LIST_FRIENDS) if(list == NOTIFY_LIST_FRIENDS)
{ {
mStateTokenServer->discardToken(mStateToken); mStateTokenServer->discardToken(mStateToken);
mStateToken = mStateTokenServer->getNewToken(); mStateToken = mStateTokenServer->getNewToken();
} }
} }
void PeersHandler::notifyPeerStatusChanged(const std::string& /*peer_id*/, uint32_t /*state*/) void PeersHandler::notifyPeerStatusChanged(const std::string& /*peer_id*/, uint32_t /*state*/)
@ -280,22 +286,22 @@ void PeersHandler::notifyPeerStatusChanged(const std::string& /*peer_id*/, uint3
void PeersHandler::notifyPeerHasNewAvatar(std::string /*peer_id*/) void PeersHandler::notifyPeerHasNewAvatar(std::string /*peer_id*/)
{ {
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
mStateTokenServer->replaceToken(mStateToken); mStateTokenServer->replaceToken(mStateToken);
} }
void PeersHandler::tick() void PeersHandler::tick()
{ {
std::list<RsPeerId> online; std::list<RsPeerId> online;
mRsPeers->getOnlineList(online); mRsPeers->getOnlineList(online);
if(online != mOnlinePeers) if(online != mOnlinePeers)
{ {
mOnlinePeers = online; mOnlinePeers = online;
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
mStateTokenServer->discardToken(mStateToken); mStateTokenServer->discardToken(mStateToken);
mStateToken = mStateTokenServer->getNewToken(); mStateToken = mStateTokenServer->getNewToken();
} }
StatusInfo statusInfo; StatusInfo statusInfo;
rsStatus->getOwnStatus(statusInfo); rsStatus->getOwnStatus(statusInfo);
@ -321,21 +327,21 @@ void PeersHandler::tick()
void PeersHandler::notifyUnreadMsgCountChanged(const RsPeerId &peer, uint32_t count) void PeersHandler::notifyUnreadMsgCountChanged(const RsPeerId &peer, uint32_t count)
{ {
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
mUnreadMsgsCounts[peer] = count; mUnreadMsgsCounts[peer] = count;
mStateTokenServer->replaceToken(mStateToken); mStateTokenServer->replaceToken(mStateToken);
} }
static bool have_avatar(RsMsgs* msgs, const RsPeerId& id) static bool have_avatar(RsMsgs* msgs, const RsPeerId& id)
{ {
// check if avatar data is available // check if avatar data is available
// requests missing avatar images as a side effect // requests missing avatar images as a side effect
unsigned char *data = NULL ; unsigned char *data = NULL ;
int size = 0 ; int size = 0 ;
msgs->getAvatarData(id, data,size) ; msgs->getAvatarData(id, data,size) ;
std::vector<uint8_t> avatar(data, data+size); std::vector<uint8_t> avatar(data, data+size);
delete[] data; delete[] data;
return size != 0; return size != 0;
} }
void PeersHandler::handleGetStateString(Request& /*req*/, Response& resp) void PeersHandler::handleGetStateString(Request& /*req*/, Response& resp)
@ -407,118 +413,122 @@ void PeersHandler::handleSetCustomStateString(Request& req, Response& resp)
void PeersHandler::handleWildcard(Request &req, Response &resp) void PeersHandler::handleWildcard(Request &req, Response &resp)
{ {
bool ok = false; bool ok = false;
if(!req.mPath.empty()) if(!req.mPath.empty())
{ {
std::string str = req.mPath.top(); std::string str = req.mPath.top();
req.mPath.pop(); req.mPath.pop();
if(str != "") if(str != "")
{ {
if(str == "self" && !req.mPath.empty() && req.mPath.top() == "certificate") if(str == "self" && !req.mPath.empty() && req.mPath.top() == "certificate")
{ {
resp.mDataStream << makeKeyValue("cert_string", mRsPeers->GetRetroshareInvite(false)); resp.mDataStream << makeKeyValue("cert_string", mRsPeers->GetRetroshareInvite(false));
resp.setOk(); resp.setOk();
return; return;
} }
// assume the path element is a peer id // assume the path element is a peer id
// sometimes it is a peer id for location info // sometimes it is a peer id for location info
// another time it is a pgp id // another time it is a pgp id
// this will confuse the client developer // this will confuse the client developer
if(!req.mPath.empty() && req.mPath.top() == "avatar_image") if(!req.mPath.empty() && req.mPath.top() == "avatar_image")
{ {
// the avatar image // the avatar image
// better have this extra, else have to load all avatar images // better have this extra, else have to load all avatar images
// only to see who is online // only to see who is online
unsigned char *data = NULL ; unsigned char *data = NULL ;
int size = 0 ; int size = 0 ;
mRsMsgs->getAvatarData(RsPeerId(str),data,size) ; mRsMsgs->getAvatarData(RsPeerId(str),data,size) ;
std::vector<uint8_t> avatar(data, data+size); std::vector<uint8_t> avatar(data, data+size);
delete[] data; delete[] data;
resp.mDataStream << avatar; resp.mDataStream << avatar;
} }
else if(!req.mPath.empty() && req.mPath.top() == "delete") else if(!req.mPath.empty() && req.mPath.top() == "delete")
{ {
mRsPeers->removeFriend(RsPgpId(str)); mRsPeers->removeFriend(RsPgpId(str));
} }
else else
{ {
std::list<RsGroupInfo> grpInfo; std::list<RsGroupInfo> grpInfo;
mRsPeers->getGroupInfoList(grpInfo); mRsPeers->getGroupInfoList(grpInfo);
RsPeerDetails details; RsPeerDetails details;
ok &= mRsPeers->getPeerDetails(RsPeerId(str), details); ok &= mRsPeers->getPeerDetails(RsPeerId(str), details);
ok = peerInfoToStream(resp.mDataStream, details, mRsPeers, grpInfo, have_avatar(mRsMsgs, RsPeerId(str))); ok = peerInfoToStream(resp.mDataStream, details, mRsPeers, grpInfo, have_avatar(mRsMsgs, RsPeerId(str)));
} }
} }
} }
else else
{ {
// no more path element // no more path element
if(req.isGet()) if(req.isGet())
{ {
std::map<RsPeerId, uint32_t> unread_msgs; std::map<RsPeerId, uint32_t> unread_msgs;
{ {
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
unread_msgs = mUnreadMsgsCounts; unread_msgs = mUnreadMsgsCounts;
} }
std::list<StatusInfo> statusInfo; std::list<StatusInfo> statusInfo;
rsStatus->getStatusList(statusInfo); rsStatus->getStatusList(statusInfo);
// list all peers // list all peers
ok = true; ok = true;
std::list<RsPgpId> identities; std::list<RsPgpId> identities;
ok &= mRsPeers->getGPGAcceptedList(identities); ok &= mRsPeers->getGPGAcceptedList(identities);
RsPgpId own_pgp = mRsPeers->getGPGOwnId(); RsPgpId own_pgp = mRsPeers->getGPGOwnId();
identities.push_back(own_pgp); identities.push_back(own_pgp);
std::list<RsPeerId> peers; std::list<RsPeerId> peers;
ok &= mRsPeers->getFriendList(peers); ok &= mRsPeers->getFriendList(peers);
std::list<RsGroupInfo> grpInfo; std::list<RsGroupInfo> grpInfo;
mRsPeers->getGroupInfoList(grpInfo); mRsPeers->getGroupInfoList(grpInfo);
std::vector<RsPeerDetails> detailsVec; std::vector<RsPeerDetails> detailsVec;
for(std::list<RsPeerId>::iterator lit = peers.begin(); lit != peers.end(); ++lit) for(std::list<RsPeerId>::iterator lit = peers.begin(); lit != peers.end(); ++lit)
{ {
RsPeerDetails details; RsPeerDetails details;
ok &= mRsPeers->getPeerDetails(*lit, details); ok &= mRsPeers->getPeerDetails(*lit, details);
detailsVec.push_back(details); detailsVec.push_back(details);
} }
// mark response as list, in case it is empty // mark response as list, in case it is empty
resp.mDataStream.getStreamToMember(); resp.mDataStream.getStreamToMember();
for(std::list<RsPgpId>::iterator lit = identities.begin(); lit != identities.end(); ++lit) for(std::list<RsPgpId>::iterator lit = identities.begin(); lit != identities.end(); ++lit)
{ {
// if no own ssl id is known, then hide the own id from the friendslist // if no own ssl id is known, then hide the own id from the friendslist
if(*lit == own_pgp) if(*lit == own_pgp)
{ {
bool found = false; bool found = false;
for(std::vector<RsPeerDetails>::iterator vit = detailsVec.begin(); vit != detailsVec.end(); ++vit) for(std::vector<RsPeerDetails>::iterator vit = detailsVec.begin(); vit != detailsVec.end(); ++vit)
{ {
if(vit->gpg_id == *lit) if(vit->gpg_id == *lit)
found = true; found = true;
} }
if(!found) if(!found)
continue; continue;
} }
StreamBase& itemStream = resp.mDataStream.getStreamToMember(); StreamBase& itemStream = resp.mDataStream.getStreamToMember();
itemStream << makeKeyValueReference("pgp_id", *lit); itemStream << makeKeyValueReference("pgp_id", *lit);
itemStream << makeKeyValue("name", mRsPeers->getGPGName(*lit)); itemStream << makeKeyValue("name", mRsPeers->getGPGName(*lit));
itemStream << makeKeyValue("is_own", *lit == own_pgp); itemStream << makeKeyValue("is_own", *lit == own_pgp);
StreamBase& locationStream = itemStream.getStreamToMember("locations"); StreamBase& locationStream = itemStream.getStreamToMember("locations");
// mark as list (in case list is empty) // mark as list (in case list is empty)
locationStream.getStreamToMember(); locationStream.getStreamToMember();
int bestPeerState = 0; int bestPeerState = 0;
uint32_t lastConnect = 0;
unsigned int bestRSState = 0; unsigned int bestRSState = 0;
std::string bestCustomStateString; std::string bestCustomStateString;
for(std::vector<RsPeerDetails>::iterator vit = detailsVec.begin(); vit != detailsVec.end(); ++vit) for(std::vector<RsPeerDetails>::iterator vit = detailsVec.begin(); vit != detailsVec.end(); ++vit)
{ {
if(vit->gpg_id == *lit) if(vit->gpg_id == *lit)
{ {
StreamBase& stream = locationStream.getStreamToMember(); StreamBase& stream = locationStream.getStreamToMember();
double unread = 0; double unread = 0;
if(unread_msgs.find(vit->id) != unread_msgs.end()) if(unread_msgs.find(vit->id) != unread_msgs.end())
unread = unread_msgs.find(vit->id)->second; unread = unread_msgs.find(vit->id)->second;
stream << makeKeyValueReference("unread_msgs", unread); stream << makeKeyValueReference("unread_msgs", unread);
peerInfoToStream(stream,*vit, mRsPeers, grpInfo, have_avatar(mRsMsgs, vit->id)); peerInfoToStream(stream,*vit, mRsPeers, grpInfo, have_avatar(mRsMsgs, vit->id));
// Get latest contact timestamp
if(vit->lastConnect > lastConnect)
lastConnect = vit->lastConnect;
/* Custom state string */ /* Custom state string */
std::string customStateString; std::string customStateString;
@ -580,7 +590,7 @@ void PeersHandler::handleWildcard(Request &req, Response &resp)
} }
} }
} }
} }
itemStream << makeKeyValue("custom_state_string", bestCustomStateString); itemStream << makeKeyValue("custom_state_string", bestCustomStateString);
std::string state_string; std::string state_string;
@ -597,70 +607,171 @@ void PeersHandler::handleWildcard(Request &req, Response &resp)
state_string = "undefined"; state_string = "undefined";
itemStream << makeKeyValue("state_string", state_string); itemStream << makeKeyValue("state_string", state_string);
} itemStream << makeKeyValue("last_contact", lastConnect);
resp.mStateToken = getCurrentStateToken(); }
} resp.mStateToken = getCurrentStateToken();
else if(req.isPut()) }
{ else if(req.isPut())
std::string cert_string; {
req.mStream << makeKeyValueReference("cert_string", cert_string); std::string cert_string;
req.mStream << makeKeyValueReference("cert_string", cert_string);
ServicePermissionFlags flags; ServicePermissionFlags flags;
StreamBase& flags_stream = req.mStream.getStreamToMember("flags"); StreamBase& flags_stream = req.mStream.getStreamToMember("flags");
if(req.mStream.isOK()) if(req.mStream.isOK())
{
bool direct_dl = RS_NODE_PERM_DEFAULT & RS_NODE_PERM_DIRECT_DL;
flags_stream << makeKeyValueReference("allow_direct_download", direct_dl);
if(direct_dl) flags |= RS_NODE_PERM_DIRECT_DL;
bool allow_push = RS_NODE_PERM_DEFAULT & RS_NODE_PERM_ALLOW_PUSH;
flags_stream << makeKeyValueReference("allow_push", allow_push);
if(allow_push) flags |= RS_NODE_PERM_ALLOW_PUSH;
bool require_whitelist = RS_NODE_PERM_DEFAULT & RS_NODE_PERM_REQUIRE_WL;
flags_stream << makeKeyValueReference("require_whitelist", require_whitelist);
if(require_whitelist) flags |= RS_NODE_PERM_REQUIRE_WL;
}
else
{
flags = RS_NODE_PERM_DEFAULT;
}
RsPeerId peer_id;
RsPgpId pgp_id;
std::string cleanCert;
int error_code;
std::string error_string;
if (mRsPeers->cleanCertificate(cert_string, cleanCert, error_code))
{ {
if(mRsPeers->loadCertificateFromString(cert_string, peer_id, pgp_id, error_string) bool direct_dl = RS_NODE_PERM_DEFAULT & RS_NODE_PERM_DIRECT_DL;
&& mRsPeers->addFriend(peer_id, pgp_id, flags)) flags_stream << makeKeyValueReference("allow_direct_download", direct_dl);
{ if(direct_dl) flags |= RS_NODE_PERM_DIRECT_DL;
ok = true;
resp.mDataStream << makeKeyValueReference("pgp_id", pgp_id); bool allow_push = RS_NODE_PERM_DEFAULT & RS_NODE_PERM_ALLOW_PUSH;
resp.mDataStream << makeKeyValueReference("peer_id", peer_id); flags_stream << makeKeyValueReference("allow_push", allow_push);
} if(allow_push) flags |= RS_NODE_PERM_ALLOW_PUSH;
else
{ bool require_whitelist = RS_NODE_PERM_DEFAULT & RS_NODE_PERM_REQUIRE_WL;
resp.mDebug << "Error: failed to add peer" << std::endl; flags_stream << makeKeyValueReference("require_whitelist", require_whitelist);
resp.mDebug << error_string << std::endl; if(require_whitelist) flags |= RS_NODE_PERM_REQUIRE_WL;
}
} }
else else
{ {
resp.mDebug << "Error: failed to add peer" << std::endl; flags = RS_NODE_PERM_DEFAULT;
resp.mDebug << error_code << std::endl;
} }
} //RsPeerId peer_id;
} //RsPgpId pgp_id;
if(ok) //std::string cleanCert;
{ uint32_t error_code;
resp.setOk(); std::string error_string;
} RsPeerDetails peerDetails;
else //std::string debug_string = " ";
{ RsPgpId own_pgp = mRsPeers->getGPGOwnId();
resp.setFail(); RsPeerId ownpeer_id = mRsPeers->getOwnId();
} do
{
if (!cert_string.empty())
{
RsPgpId pgp_id ;
RsPeerId ssl_id ;
std::string error_string ;
if(!mRsPeers->loadCertificateFromString(cert_string,ssl_id,pgp_id,error_string))
{
std::cerr << "handleWildcard::loadCertificateFromString(): cannot load that certificate. " ;
std::cerr << error_string << std::endl;
resp.mDebug << "cannot load that certificate " << std::endl;
resp.mDebug << error_string << std::endl;
break ;
}
}
std::cerr << "handleWildcard addPeer: loadDetailsFromStringCert" << std::endl;
if(!mRsPeers->loadDetailsFromStringCert(cert_string, peerDetails, error_code))
{
resp.mDebug << "Error: failed to add peer can not get peerDetails" << std::endl;
resp.mDebug << error_code << std::endl;
break;
}
std::cerr << "handleWildcard addPeer: peerDetails.gpg_id" << std::endl;
if(peerDetails.gpg_id.isNull())
{
resp.mDebug << "Error: failed to add peer gpg_id.isNull" << std::endl;
resp.mDebug << error_string << std::endl;
break;
}
if(peerDetails.gpg_id == own_pgp)
{
if(peerDetails.id == ownpeer_id)
{
std::cerr << "handleWildcard addPeer: is own peer_id, ignore" << std::endl;
resp.mDebug << "Error: failed to add peer_id, because its your own peer_id" << std::endl;
resp.mDebug << error_string << std::endl;
break;
}
std::cerr << "handleWildcard addPeer: is own pgp_id, update only" << std::endl;
}
else
{
if(!mRsPeers->addFriend(peerDetails.id, peerDetails.gpg_id, flags))
{
resp.mDebug << "Error: failed to addFriend" << std::endl;
resp.mDebug << error_string << std::endl;
break;
}
std::cerr << "handleWildcard addPeer: addFriend ok " << peerDetails.gpg_id << std::endl;
}
ok = true;
// Retrun node details to response, after succes of adding peers
peerDetailsToStream(resp.mDataStream, peerDetails);
std::cerr << "handleWildcard addPeer: peerDetailsToStream" << std::endl;
if (!peerDetails.location.empty())
{
std::cerr << "handleWildcard addPeer: setting peer node." << std::endl;
mRsPeers->setLocation(peerDetails.id, peerDetails.location);
}
// Update new address even the peer already existed.
if (peerDetails.isHiddenNode)
{
std::cerr << "handleWildcard addPeer: setting hidden node.";
std::cerr << peerDetails.hiddenNodeAddress;
std::cerr << " Port: " << peerDetails.hiddenNodePort << std::endl;
mRsPeers->setHiddenNode(peerDetails.id, peerDetails.hiddenNodeAddress, peerDetails.hiddenNodePort);
}
else
{
//let's check if there is ip adresses in the certificate.
if (!peerDetails.extAddr.empty() && peerDetails.extPort)
{
std::cerr << "handleWildcard addPeer: setting ip ext address." ;
std::cerr << peerDetails.extAddr;
std::cerr << " Port: " << peerDetails.extPort;
std::cerr << std::endl;
mRsPeers->setExtAddress(peerDetails.id, peerDetails.extAddr, peerDetails.extPort);
}
if (!peerDetails.localAddr.empty() && peerDetails.localPort)
{
std::cerr << "handleWildcard addPeer: setting ip local address." ;
std::cerr << peerDetails.localAddr;
std::cerr << " Port: " << peerDetails.localPort << std::endl;
mRsPeers->setLocalAddress(peerDetails.id, peerDetails.localAddr, peerDetails.localPort);
}
if (!peerDetails.dyndns.empty())
{
std::cerr << "handleWildcard addPeer: setting DynDNS." ;
std::cerr << peerDetails.dyndns << std::endl;
mRsPeers->setDynDNS(peerDetails.id, peerDetails.dyndns);
}
}
// std::cerr << debug_string << std::endl;
// resp.mDebug << debug_string << std::endl;
// rslog(RSL_WARNING, peerhandlerzone, debug_string );
}while(0);
}
}
if(ok)
{
resp.setOk();
}
else
{
resp.setFail();
}
} }
void PeersHandler::handleAttemptConnection(Request &req, Response &resp) void PeersHandler::handleAttemptConnection(Request &req, Response &resp)
@ -678,21 +789,133 @@ void PeersHandler::handleAttemptConnection(Request &req, Response &resp)
void PeersHandler::handleExamineCert(Request &req, Response &resp) void PeersHandler::handleExamineCert(Request &req, Response &resp)
{ {
std::string cert_string; std::string cert_string;
req.mStream << makeKeyValueReference("cert_string", cert_string); req.mStream << makeKeyValueReference("cert_string", cert_string);
RsPeerDetails details; RsPeerDetails details;
uint32_t error_code; uint32_t error_code;
if(mRsPeers->loadDetailsFromStringCert(cert_string, details, error_code)) if(mRsPeers->loadDetailsFromStringCert(cert_string, details, error_code))
{ {
peerDetailsToStream(resp.mDataStream, details); peerDetailsToStream(resp.mDataStream, details);
resp.setOk(); resp.setOk();
} }
else else
{ {
resp.setFail("failed to load certificate"); resp.setFail("failed to load certificate");
} }
} }
/**
* \brief Remove specific location or user
*
* \param [in] req request from user either peer_id or gpg_id is needed.
* \param [in] resp response to user
* \return
*
* \details
*/
void PeersHandler::handleRemoveNode(Request &req, Response &resp)
{
std::string ssl_peer_id;
std::string gpg_id;
req.mStream << makeKeyValueReference("peer_id", ssl_peer_id);
req.mStream << makeKeyValueReference("gpg_id", gpg_id);
RsPeerId peerId(ssl_peer_id);
RsPgpId gpgId(gpg_id);
if(!gpgId.isNull())
{
mRsPeers->removeFriend(gpgId);
resp.mDataStream << makeKeyValue("gpg_id", gpg_id);
resp.setOk();
}
else if(!peerId.isNull())
{
mRsPeers->removeFriendLocation(peerId);
resp.mDataStream << makeKeyValue("peer_id", ssl_peer_id);
resp.setOk();
}
else
{
resp.setFail("handleRemoveNode Invalid peer_id or gpg_id");
}
}
/**
* \brief Retrieve inactive user list before specific UNIX time
*
* \param [in] req request from user, datatime in UNIX timestamp.
* \param [in] resp response to request
* \return a pgp_id list.
*
* \details Combine this with handleRemoveNode,
* batch remove inactive users are possible and convenient.
*/
void PeersHandler::handleGetInactiveUsers(Request &req, Response &resp)
{
std::string datetime;
req.mStream << makeKeyValueReference("datetime", datetime);
uint32_t before = strtoul(datetime.c_str(), NULL, 10);
if(datetime.empty())
{
std::cerr << "PeersHandler:datetime is empty" << std::endl;
before = time(NULL);
}
// list all peers
std::list<RsPeerId> peers;
mRsPeers->getFriendList(peers);
// Make pair of gpg_id and last connect time
std::map<RsPgpId, uint32_t> mapRsPgpId;
// get all peers' infomations
for(std::list<RsPeerId>::iterator lt = peers.begin(); lt != peers.end(); ++lt)
{
RsPeerDetails details;
mRsPeers->getPeerDetails(*lt, details);
// Search for exist pgp_id, update the last connect time
if(mapRsPgpId.find(details.gpg_id) != mapRsPgpId.end())
{
if(mapRsPgpId[details.gpg_id] < details.lastConnect)
mapRsPgpId[details.gpg_id] = details.lastConnect;
}
else
{
mapRsPgpId.insert(std::make_pair(details.gpg_id, details.lastConnect));
}
}
// mark response as list, in case it is empty
resp.mDataStream.getStreamToMember();
std::map<RsPgpId, uint32_t>::iterator lit;
for( lit = mapRsPgpId.begin(); lit != mapRsPgpId.end(); ++lit)
{
if (lit->second < before)
{
std::cerr << "YES Adding OLD: " << mRsPeers->getGPGName(lit->first);
std::cerr << "last_contact: " << lit->second <<std::endl;
StreamBase& itemStream = resp.mDataStream.getStreamToMember();
itemStream << makeKeyValue("pgp_id", lit->first.toStdString());
itemStream << makeKeyValue("name", mRsPeers->getGPGName(lit->first));
itemStream << makeKeyValue("last_contact", lit->second);
}
}
resp.setOk();
}
void PeersHandler::handleGetNetworkOptions(Request& /*req*/, Response& resp) void PeersHandler::handleGetNetworkOptions(Request& /*req*/, Response& resp)
{ {
RsPeerDetails detail; RsPeerDetails detail;
@ -865,7 +1088,7 @@ void PeersHandler::handleSetNetworkOptions(Request& req, Response& resp)
bool checkIP; bool checkIP;
req.mStream << makeKeyValueReference("check_ip", checkIP); req.mStream << makeKeyValueReference("check_ip", checkIP);
rsPeers->allowServerIPDetermination(checkIP) ; mRsPeers->allowServerIPDetermination(checkIP) ;
// Tor // Tor
std::string toraddr; std::string toraddr;
@ -1110,7 +1333,7 @@ void PeersHandler::handleSetNodeOptions(Request& req, Response& resp)
else else
{ {
if(detail.hiddenNodeAddress != local_address || detail.hiddenNodePort != local_port) if(detail.hiddenNodeAddress != local_address || detail.hiddenNodePort != local_port)
rsPeers->setHiddenNode(peerId, local_address, local_port); mRsPeers->setHiddenNode(peerId, local_address, local_port);
} }
resp.setOk(); resp.setOk();
@ -1118,10 +1341,10 @@ void PeersHandler::handleSetNodeOptions(Request& req, Response& resp)
StateToken PeersHandler::getCurrentStateToken() StateToken PeersHandler::getCurrentStateToken()
{ {
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
if(mStateToken.isNull()) if(mStateToken.isNull())
mStateToken = mStateTokenServer->getNewToken(); mStateToken = mStateTokenServer->getNewToken();
return mStateToken; return mStateToken;
} }
} // namespace resource_api } // namespace resource_api

View File

@ -34,22 +34,22 @@ namespace resource_api
class PeersHandler: public ResourceRouter, NotifyClient, Tickable, public UnreadMsgNotify class PeersHandler: public ResourceRouter, NotifyClient, Tickable, public UnreadMsgNotify
{ {
public: public:
PeersHandler(StateTokenServer* sts, RsNotify* notify, RsPeers* peers, RsMsgs* msgs); PeersHandler(StateTokenServer* sts, RsNotify* notify, RsPeers* peers, RsMsgs* msgs);
virtual ~PeersHandler(); virtual ~PeersHandler();
// from NotifyClient // from NotifyClient
// note: this may get called from foreign threads // note: this may get called from foreign threads
virtual void notifyListChange(int list, int type); // friends list change virtual void notifyListChange(int list, int type); // friends list change
virtual void notifyPeerStatusChanged(const std::string& /*peer_id*/, uint32_t /*state*/); virtual void notifyPeerStatusChanged(const std::string& /*peer_id*/, uint32_t /*state*/);
virtual void notifyPeerHasNewAvatar(std::string /*peer_id*/); virtual void notifyPeerHasNewAvatar(std::string /*peer_id*/);
// from Tickable // from Tickable
virtual void tick(); virtual void tick();
// from UnreadMsgNotify // from UnreadMsgNotify
// ChatHandler calls this to tell us about unreadmsgs // ChatHandler calls this to tell us about unreadmsgs
// this allows to merge unread msgs info with the peers list // this allows to merge unread msgs info with the peers list
virtual void notifyUnreadMsgCountChanged(const RsPeerId& peer, uint32_t count); virtual void notifyUnreadMsgCountChanged(const RsPeerId& peer, uint32_t count);
private: private:
void handleWildcard(Request& req, Response& resp); void handleWildcard(Request& req, Response& resp);
@ -72,24 +72,26 @@ private:
void handleGetNodeOptions(Request& req, Response& resp); void handleGetNodeOptions(Request& req, Response& resp);
void handleSetNodeOptions(Request& req, Response& resp); void handleSetNodeOptions(Request& req, Response& resp);
void handleRemoveNode(Request &req, Response &resp);
void handleGetInactiveUsers(Request &req, Response &resp);
// a helper which ensures proper mutex locking
StateToken getCurrentStateToken();
// a helper which ensures proper mutex locking StateTokenServer* mStateTokenServer;
StateToken getCurrentStateToken(); RsNotify* mNotify;
RsPeers* mRsPeers;
RsMsgs* mRsMsgs; // required for avatar data
StateTokenServer* mStateTokenServer; std::list<RsPeerId> mOnlinePeers;
RsNotify* mNotify;
RsPeers* mRsPeers;
RsMsgs* mRsMsgs; // required for avatar data
std::list<RsPeerId> mOnlinePeers;
uint32_t status; uint32_t status;
std::string custom_state_string; std::string custom_state_string;
RsMutex mMtx; RsMutex mMtx;
StateToken mStateToken; // mutex protected StateToken mStateToken; // mutex protected
StateToken mStringStateToken; // mutex protected StateToken mStringStateToken; // mutex protected
StateToken mCustomStateToken; // mutex protected StateToken mCustomStateToken; // mutex protected
std::map<RsPeerId, uint32_t> mUnreadMsgsCounts; std::map<RsPeerId, uint32_t> mUnreadMsgsCounts;
}; };
} // namespace resource_api } // namespace resource_api