merged with upstream/master

This commit is contained in:
csoler 2016-06-16 20:19:03 -04:00
commit dbd78d2401
77 changed files with 2311 additions and 1333 deletions

View file

@ -1163,8 +1163,10 @@ bool RsGenExchange::subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId,
if(mNetService != NULL)
mNetService->subscribeStatusChanged(grpId,subscribe) ;
#ifdef GEN_EXCH_DEBUG
else
std::cerr << "(EE) No mNetService in RsGenExchange for service 0x" << std::hex << mServType << std::dec << std::endl;
#endif
return true;
}

View file

@ -208,6 +208,7 @@
#include "retroshare/rsgxsflags.h"
#include "retroshare/rsgxscircles.h"
#include "pgp/pgpauxutils.h"
#include "util/rsdir.h"
#include "util/rsmemory.h"
#include "util/stacktrace.h"
@ -604,6 +605,21 @@ public:
std::vector<T*>::clear() ;
}
};
RsGxsGroupId RsGxsNetService::hashGrpId(const RsGxsGroupId& gid,const RsPeerId& pid)
{
static const uint32_t SIZE = RsGxsGroupId::SIZE_IN_BYTES + RsPeerId::SIZE_IN_BYTES ;
unsigned char tmpmem[SIZE];
uint32_t offset = 0 ;
pid.serialise(tmpmem,SIZE,offset) ;
gid.serialise(tmpmem,SIZE,offset) ;
assert(RsGxsGroupId::SIZE_IN_BYTES <= Sha1CheckSum::SIZE_IN_BYTES) ;
return RsGxsGroupId( RsDirUtil::sha1sum(tmpmem,SIZE).toByteArray() );
}
void RsGxsNetService::syncWithPeers()
{
#ifdef NXS_NET_DEBUG_0
@ -742,43 +758,24 @@ void RsGxsNetService::syncWithPeers()
RsNxsSyncMsgReqItem* msg = new RsNxsSyncMsgReqItem(mServType);
msg->clear();
msg->PeerId(peerId);
msg->grpId = grpId;
msg->updateTS = updateTS;
if(encrypt_to_this_circle_id.isNull())
{
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_PG(*sit,grpId) << " Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself - in clear " << std::endl;
#endif
sendItem(msg);
}
msg->grpId = grpId;
else
{
msg->grpId = hashGrpId(grpId,mNetMgr->getOwnId()) ;
msg->flag |= RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID ;
}
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_PG(*sit,grpId) << " Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself - encrypted for circle " << encrypt_to_this_circle_id << std::endl;
GXSNETDEBUG_PG(*sit,grpId) << " Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself - in clear " << std::endl;
#endif
RsNxsItem *encrypted_item = NULL ;
uint32_t status ;
if(encryptSingleNxsItem(msg, encrypt_to_this_circle_id, grpId, encrypted_item, status))
sendItem(encrypted_item) ;
else
std::cerr << "(WW) could not encrypt for circle ID " << encrypt_to_this_circle_id << ". Not yet in cache?" << std::endl;
delete msg ;
}
sendItem(msg);
#ifdef NXS_NET_DEBUG_5
GXSNETDEBUG_PG(*sit,grpId) << "Service "<< std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending global message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself" << std::endl;
#endif
//}
//else
//{
// delete msg ;
//#ifdef NXS_NET_DEBUG_0
// GXSNETDEBUG_PG(*sit,grpId) << " cancel RsNxsSyncMsg req (last local update TS for group+peer) for grpId=" << grpId << " to peer " << *sit << ": not enough bandwidth." << std::endl;
//#endif
//}
}
}
@ -3686,7 +3683,9 @@ bool RsGxsNetService::encryptSingleNxsItem(RsNxsItem *item, const RsGxsCircleId&
if(recipients.empty())
{
std::cerr << " (EE) No recipients found for circle " << destination_circle << ". Circle not in cache, or empty circle?" << std::endl;
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_P_(item->PeerId()) << " (EE) No recipients found for circle " << destination_circle << ". Circle not in cache, or empty circle?" << std::endl;
#endif
return false ;
}
@ -4342,28 +4341,53 @@ bool RsGxsNetService::checkCanRecvMsgFromPeer(const RsPeerId& sslId, const RsGxs
return true;
}
bool RsGxsNetService::locked_CanReceiveUpdate(const RsNxsSyncMsgReqItem *item)
bool RsGxsNetService::locked_CanReceiveUpdate(RsNxsSyncMsgReqItem *item,bool& grp_is_known)
{
// Do we have new updates for this peer?
// Here we compare times in the same clock: the friend's clock, so it should be fine.
ServerMsgMap::const_iterator cit = mServerMsgUpdateMap.find(item->grpId);
grp_is_known = false ;
if(item->flag & RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID)
{
// Item contains the hashed group ID in order to protect is from friends who don't know it. So we de-hash it using bruteforce over known group IDs for this peer.
// We could save the de-hash result. But the cost is quite light, since the number of encrypted groups per service is usually low.
for(ServerMsgMap::const_iterator it(mServerMsgUpdateMap.begin());it!=mServerMsgUpdateMap.end();++it)
if(item->grpId == hashGrpId(it->first,item->PeerId()))
{
item->grpId = it->first ;
item->flag &= ~RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID;
#ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << "(II) de-hashed group ID " << it->first << " from hash " << item->grpId << " and peer id " << item->PeerId() << std::endl;
#endif
grp_is_known = true ;
return item->updateTS < it->second->msgUpdateTS ;
}
return false ;
}
ServerMsgMap::const_iterator cit = mServerMsgUpdateMap.find(item->grpId);
if(cit != mServerMsgUpdateMap.end())
{
const RsGxsServerMsgUpdateItem *msui = cit->second;
const RsGxsServerMsgUpdateItem *msui = cit->second;
#ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " local time stamp: " << std::dec<< time(NULL) - msui->msgUpdateTS << " secs ago. Update sent: " << (item->updateTS < msui->msgUpdateTS) << std::endl;
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " local time stamp: " << std::dec<< time(NULL) - msui->msgUpdateTS << " secs ago. Update sent: " << (item->updateTS < msui->msgUpdateTS) << std::endl;
#endif
return item->updateTS < msui->msgUpdateTS ;
grp_is_known = true ;
return item->updateTS < msui->msgUpdateTS ;
}
#ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " no local time stamp for this grp. "<< std::endl;
#endif
return false;
}
void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_was_encrypted)
{
if (!item)
@ -4372,19 +4396,28 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_
RS_STACK_MUTEX(mNxsMutex) ;
const RsPeerId& peer = item->PeerId();
bool grp_is_known = false;
bool was_circle_protected = item_was_encrypted || bool(item->flag & RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID);
bool peer_can_receive_update = locked_CanReceiveUpdate(item, grp_is_known);
if(item_was_encrypted)
std::cerr << "(WW) got an encrypted msg sync req. from " << item->PeerId() << ". This will not send messages updates for group " << item->grpId << std::endl;
// Insert the PeerId in suppliers list for this grpId
#ifdef NXS_NET_DEBUG_6
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << "RsGxsNetService::handleRecvSyncMessage(): Inserting PeerId " << item->PeerId() << " in suppliers list for group " << item->grpId << std::endl;
#endif
RsGroupNetworkStatsRecord& rec(mGroupNetworkStats[item->grpId]) ; // this creates it if needed
rec.suppliers.insert(peer) ;
#ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << "handleRecvSyncMsg(): Received last update TS of group " << item->grpId << ", for peer " << peer << ", TS = " << time(NULL) - item->updateTS << " secs ago." ;
#endif
if(!locked_CanReceiveUpdate(item))
if(grp_is_known)
{
RsGroupNetworkStatsRecord& rec(mGroupNetworkStats[item->grpId]) ; // this creates it if needed. When the grp is unknown (and hashed) this will would create a unused entry
rec.suppliers.insert(peer) ;
}
if(!peer_can_receive_update)
{
#ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " no update will be sent." << std::endl;
@ -4413,10 +4446,10 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_
return ;
}
if( (grpMeta->mCircleType == GXS_CIRCLE_TYPE_EXTERNAL) != item_was_encrypted )
if( (grpMeta->mCircleType == GXS_CIRCLE_TYPE_EXTERNAL) != was_circle_protected )
{
std::cerr << "(EE) received a sync Msg request for group " << item->grpId << " from peer " << item->PeerId() ;
if(!item_was_encrypted)
if(!was_circle_protected)
std::cerr << ". The group is tied to an external circle (ID=" << grpMeta->mCircleId << ") but the request wasn't encrypted." << std::endl;
else
std::cerr << ". The group is not tied to an external circle (ID=" << grpMeta->mCircleId << ") but the request was encrypted." << std::endl;

View file

@ -384,8 +384,10 @@ private:
#endif
bool locked_CanReceiveUpdate(const RsNxsSyncGrpReqItem *item);
bool locked_CanReceiveUpdate(const RsNxsSyncMsgReqItem* item);
bool locked_CanReceiveUpdate(RsNxsSyncMsgReqItem *item, bool &grp_is_known);
static RsGxsGroupId hashGrpId(const RsGxsGroupId& gid,const RsPeerId& pid) ;
private:
typedef std::vector<RsNxsGrp*> GrpFragments;

View file

@ -110,10 +110,6 @@ peerConnectState::peerConnectState()
inConnAttempt(0),
wasDeniedConnection(false), deniedTS(false), deniedInConnAttempt(false)
{
//sockaddr_clear(&currentlocaladdr);
//sockaddr_clear(&currentserveraddr);
return;
}
std::string textPeerConnectState(peerConnectState &state)

View file

@ -129,7 +129,6 @@ class peerConnectState
time_t deniedTS;
bool deniedInConnAttempt; /* is below valid */
peerConnectAddress deniedConnectionAttempt;
};
class p3tunnel;
@ -312,7 +311,7 @@ bool addAddressIfUnique(std::list<peerConnectAddress> &addrList, peerConnectAdd
private:
// These should have there own Mutex Protection,
// These should have their own Mutex Protection,
//p3tunnel *mP3tunnel;
DNSResolver *mDNSResolver ;

View file

@ -1999,7 +1999,7 @@ bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list<RsItem *>& saveData)
item->domain_addr = (it->second).hiddenDomain;
item->domain_port = (it->second).hiddenPort;
saveData.push_back(item);
saveCleanupList.push_back(item);
#ifdef PEER_DEBUG
@ -2009,6 +2009,10 @@ bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list<RsItem *>& saveData)
#endif
}
RsPeerBandwidthLimitsItem *pblitem = new RsPeerBandwidthLimitsItem ;
pblitem->peers = mPeerBandwidthLimits ;
saveData.push_back(pblitem) ;
RsPeerServicePermissionItem *sitem = new RsPeerServicePermissionItem ;
for(std::map<RsPgpId,ServicePermissionFlags>::const_iterator it(mFriendsPermissionFlags.begin());it!=mFriendsPermissionFlags.end();++it)
@ -2016,7 +2020,7 @@ bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list<RsItem *>& saveData)
sitem->pgp_ids.push_back(it->first) ;
sitem->service_flags.push_back(it->second) ;
}
saveData.push_back(sitem) ;
saveCleanupList.push_back(sitem);
@ -2072,6 +2076,61 @@ bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list<RsItem *>& saveData)
return true;
}
bool p3PeerMgrIMPL::getMaxRates(const RsPeerId& pid,uint32_t& maxUp,uint32_t& maxDn)
{
RsPgpId pgp_id ;
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
std::map<RsPeerId, peerState>::const_iterator it = mFriendList.find(pid) ;
if(it == mFriendList.end())
return false ;
pgp_id = it->second.gpg_id ;
}
return getMaxRates(pgp_id,maxUp,maxDn) ;
}
bool p3PeerMgrIMPL::getMaxRates(const RsPgpId& pid,uint32_t& maxUp,uint32_t& maxDn)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
std::map<RsPgpId,PeerBandwidthLimits>::const_iterator it2 = mPeerBandwidthLimits.find(pid) ;
if(it2 != mPeerBandwidthLimits.end())
{
maxUp = it2->second.max_up_rate_kbs ;
maxDn = it2->second.max_dl_rate_kbs ;
return true ;
}
else
{
maxUp = 0;
maxDn = 0;
return false ;
}
}
bool p3PeerMgrIMPL::setMaxRates(const RsPgpId& pid,uint32_t maxUp,uint32_t maxDn)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
PeerBandwidthLimits& p(mPeerBandwidthLimits[pid]) ;
if(maxUp == p.max_up_rate_kbs && maxDn == p.max_dl_rate_kbs)
return true ;
std::cerr << "Updating max rates for peer " << pid << " to " << maxUp << " kB/s (up), " << maxDn << " kB/s (dn)" << std::endl;
p.max_up_rate_kbs = maxUp ;
p.max_dl_rate_kbs = maxDn ;
IndicateConfigChanged();
return true ;
}
void p3PeerMgrIMPL::saveDone()
{
/* clean up the save List */
@ -2090,276 +2149,288 @@ void p3PeerMgrIMPL::saveDone()
bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
{
// DEFAULTS.
bool useExtAddrFinder = true;
std::string proxyIpAddressTor = kConfigDefaultProxyServerIpAddr;
uint16_t proxyPortTor = kConfigDefaultProxyServerPortTor;
std::string proxyIpAddressI2P = kConfigDefaultProxyServerIpAddr;
uint16_t proxyPortI2P = kConfigDefaultProxyServerPortI2P;
// DEFAULTS.
bool useExtAddrFinder = true;
std::string proxyIpAddressTor = kConfigDefaultProxyServerIpAddr;
uint16_t proxyPortTor = kConfigDefaultProxyServerPortTor;
std::string proxyIpAddressI2P = kConfigDefaultProxyServerIpAddr;
uint16_t proxyPortI2P = kConfigDefaultProxyServerPortI2P;
if (load.empty()) {
std::cerr << "p3PeerMgrIMPL::loadList() list is empty, it may be a configuration problem." << std::endl;
return false;
}
if (load.empty()) {
std::cerr << "p3PeerMgrIMPL::loadList() list is empty, it may be a configuration problem." << std::endl;
return false;
}
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::loadList() Item Count: " << load.size() << std::endl;
std::cerr << "p3PeerMgrIMPL::loadList() Item Count: " << load.size() << std::endl;
#endif
RsPeerId ownId = getOwnId();
RsPeerId ownId = getOwnId();
/* load the list of peers */
std::list<RsItem *>::iterator it;
for(it = load.begin(); it != load.end(); ++it)
{
RsPeerNetItem *pitem = dynamic_cast<RsPeerNetItem *>(*it);
if (pitem)
{
RsPeerId peer_id = pitem->peerId ;
RsPgpId peer_pgp_id = pitem->pgpId ;
/* load the list of peers */
std::list<RsItem *>::iterator it;
for(it = load.begin(); it != load.end(); ++it)
{
RsPeerNetItem *pitem = dynamic_cast<RsPeerNetItem *>(*it);
if (pitem)
{
RsPeerId peer_id = pitem->peerId ;
RsPgpId peer_pgp_id = pitem->pgpId ;
if (peer_id == ownId)
{
if (peer_id == ownId)
{
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::loadList() Own Config Item:" << std::endl;
pitem->print(std::cerr, 10);
std::cerr << std::endl;
std::cerr << "p3PeerMgrIMPL::loadList() Own Config Item:" << std::endl;
pitem->print(std::cerr, 10);
std::cerr << std::endl;
#endif
/* add ownConfig */
setOwnNetworkMode(pitem->netMode);
setOwnVisState(pitem->vs_disc, pitem->vs_dht);
/* add ownConfig */
setOwnNetworkMode(pitem->netMode);
setOwnVisState(pitem->vs_disc, pitem->vs_dht);
mOwnState.gpg_id = AuthGPG::getAuthGPG()->getGPGOwnId();
mOwnState.location = AuthSSL::getAuthSSL()->getOwnLocation();
}
else
{
mOwnState.gpg_id = AuthGPG::getAuthGPG()->getGPGOwnId();
mOwnState.location = AuthSSL::getAuthSSL()->getOwnLocation();
}
else
{
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::loadList() Peer Config Item:" << std::endl;
pitem->print(std::cerr, 10);
std::cerr << std::endl;
std::cerr << "p3PeerMgrIMPL::loadList() Peer Config Item:" << std::endl;
pitem->print(std::cerr, 10);
std::cerr << std::endl;
#endif
/* ************* */
// permission flags is used as a mask for the existing perms, so we set it to 0xffff
addFriend(peer_id, peer_pgp_id, pitem->netMode, pitem->vs_disc, pitem->vs_dht, pitem->lastContact, RS_NODE_PERM_ALL);
setLocation(pitem->peerId, pitem->location);
}
/* ************* */
// permission flags is used as a mask for the existing perms, so we set it to 0xffff
addFriend(peer_id, peer_pgp_id, pitem->netMode, pitem->vs_disc, pitem->vs_dht, pitem->lastContact, RS_NODE_PERM_ALL);
setLocation(pitem->peerId, pitem->location);
}
if (pitem->netMode == RS_NET_MODE_HIDDEN)
{
/* set only the hidden stuff & localAddress */
setLocalAddress(peer_id, pitem->localAddrV4.addr);
setHiddenDomainPort(peer_id, pitem->domain_addr, pitem->domain_port);
if (pitem->netMode == RS_NET_MODE_HIDDEN)
{
/* set only the hidden stuff & localAddress */
setLocalAddress(peer_id, pitem->localAddrV4.addr);
setHiddenDomainPort(peer_id, pitem->domain_addr, pitem->domain_port);
}
else
{
setLocalAddress(peer_id, pitem->localAddrV4.addr);
setExtAddress(peer_id, pitem->extAddrV4.addr);
setDynDNS (peer_id, pitem->dyndns);
}
else
{
setLocalAddress(peer_id, pitem->localAddrV4.addr);
setExtAddress(peer_id, pitem->extAddrV4.addr);
setDynDNS (peer_id, pitem->dyndns);
/* convert addresses */
pqiIpAddrSet addrs;
addrs.mLocal.extractFromTlv(pitem->localAddrList);
addrs.mExt.extractFromTlv(pitem->extAddrList);
updateAddressList(peer_id, addrs);
}
/* convert addresses */
pqiIpAddrSet addrs;
addrs.mLocal.extractFromTlv(pitem->localAddrList);
addrs.mExt.extractFromTlv(pitem->extAddrList);
delete(*it);
updateAddressList(peer_id, addrs);
}
continue;
}
delete(*it);
RsConfigKeyValueSet *vitem = dynamic_cast<RsConfigKeyValueSet *>(*it) ;
if (vitem)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
continue;
}
RsConfigKeyValueSet *vitem = dynamic_cast<RsConfigKeyValueSet *>(*it) ;
if (vitem)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::loadList() General Variable Config Item:" << std::endl;
vitem->print(std::cerr, 10);
std::cerr << std::endl;
std::cerr << "p3PeerMgrIMPL::loadList() General Variable Config Item:" << std::endl;
vitem->print(std::cerr, 10);
std::cerr << std::endl;
#endif
std::list<RsTlvKeyValue>::iterator kit;
for(kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit)
{
if (kit->key == kConfigKeyExtIpFinder)
{
useExtAddrFinder = (kit->value == "TRUE");
std::list<RsTlvKeyValue>::iterator kit;
for(kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit)
{
if (kit->key == kConfigKeyExtIpFinder)
{
useExtAddrFinder = (kit->value == "TRUE");
#ifdef PEER_DEBUG
std::cerr << "setting use_extr_addr_finder to " << useExtAddrFinder << std::endl ;
std::cerr << "setting use_extr_addr_finder to " << useExtAddrFinder << std::endl ;
#endif
}
// Tor
else if (kit->key == kConfigKeyProxyServerIpAddrTor)
{
proxyIpAddressTor = kit->value;
}
// Tor
else if (kit->key == kConfigKeyProxyServerIpAddrTor)
{
proxyIpAddressTor = kit->value;
#ifdef PEER_DEBUG
std::cerr << "Loaded proxyIpAddress for Tor: " << proxyIpAddressTor;
std::cerr << std::endl ;
std::cerr << "Loaded proxyIpAddress for Tor: " << proxyIpAddressTor;
std::cerr << std::endl ;
#endif
}
else if (kit->key == kConfigKeyProxyServerPortTor)
{
proxyPortTor = atoi(kit->value.c_str());
#ifdef PEER_DEBUG
std::cerr << "Loaded proxyPort for Tor: " << proxyPortTor;
std::cerr << std::endl ;
#endif
}
// I2p
else if (kit->key == kConfigKeyProxyServerIpAddrI2P)
{
proxyIpAddressI2P = kit->value;
#ifdef PEER_DEBUG
std::cerr << "Loaded proxyIpAddress for I2P: " << proxyIpAddressI2P;
std::cerr << std::endl ;
#endif
}
else if (kit->key == kConfigKeyProxyServerPortI2P)
{
proxyPortI2P = atoi(kit->value.c_str());
#ifdef PEER_DEBUG
std::cerr << "Loaded proxyPort for I2P: " << proxyPortI2P;
std::cerr << std::endl ;
#endif
}
}
delete(*it);
}
else if (kit->key == kConfigKeyProxyServerPortTor)
{
proxyPortTor = atoi(kit->value.c_str());
#ifdef PEER_DEBUG
std::cerr << "Loaded proxyPort for Tor: " << proxyPortTor;
std::cerr << std::endl ;
#endif
}
// I2p
else if (kit->key == kConfigKeyProxyServerIpAddrI2P)
{
proxyIpAddressI2P = kit->value;
#ifdef PEER_DEBUG
std::cerr << "Loaded proxyIpAddress for I2P: " << proxyIpAddressI2P;
std::cerr << std::endl ;
#endif
}
else if (kit->key == kConfigKeyProxyServerPortI2P)
{
proxyPortI2P = atoi(kit->value.c_str());
#ifdef PEER_DEBUG
std::cerr << "Loaded proxyPort for I2P: " << proxyPortI2P;
std::cerr << std::endl ;
#endif
}
}
continue;
}
delete(*it);
RsPeerGroupItem *gitem = dynamic_cast<RsPeerGroupItem *>(*it) ;
if (gitem)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
continue;
}
RsPeerGroupItem *gitem = dynamic_cast<RsPeerGroupItem *>(*it) ;
if (gitem)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::loadList() Peer group item:" << std::endl;
gitem->print(std::cerr, 10);
std::cerr << std::endl;
std::cerr << "p3PeerMgrIMPL::loadList() Peer group item:" << std::endl;
gitem->print(std::cerr, 10);
std::cerr << std::endl;
#endif
groupList.push_back(gitem); // don't delete
groupList.push_back(gitem); // don't delete
if ((gitem->flag & RS_GROUP_FLAG_STANDARD) == 0) {
/* calculate group id */
uint32_t groupId = atoi(gitem->id.c_str());
if (groupId > lastGroupId) {
lastGroupId = groupId;
}
}
if ((gitem->flag & RS_GROUP_FLAG_STANDARD) == 0) {
/* calculate group id */
uint32_t groupId = atoi(gitem->id.c_str());
if (groupId > lastGroupId) {
lastGroupId = groupId;
}
}
continue;
}
RsPeerServicePermissionItem *sitem = dynamic_cast<RsPeerServicePermissionItem*>(*it) ;
continue;
}
RsPeerBandwidthLimitsItem *pblitem = dynamic_cast<RsPeerBandwidthLimitsItem*>(*it) ;
if(sitem)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
if(pblitem)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
#ifdef PEER_DEBUG
std::cerr << "Loaded service permission item: " << std::endl;
std::cerr << "Loaded service permission item: " << std::endl;
#endif
mPeerBandwidthLimits = pblitem->peers ;
}
RsPeerServicePermissionItem *sitem = dynamic_cast<RsPeerServicePermissionItem*>(*it) ;
if(sitem)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
for(uint32_t i=0;i<sitem->pgp_ids.size();++i)
if(AuthGPG::getAuthGPG()->isGPGAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthGPG::getAuthGPG()->getGPGOwnId())
{
mFriendsPermissionFlags[sitem->pgp_ids[i]] = sitem->service_flags[i] ;
#ifdef PEER_DEBUG
std::cerr << " " << sitem->pgp_ids[i] << " - " << sitem->service_flags[i] << std::endl;
std::cerr << "Loaded service permission item: " << std::endl;
#endif
}
for(uint32_t i=0;i<sitem->pgp_ids.size();++i)
if(AuthGPG::getAuthGPG()->isGPGAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthGPG::getAuthGPG()->getGPGOwnId())
{
mFriendsPermissionFlags[sitem->pgp_ids[i]] = sitem->service_flags[i] ;
#ifdef PEER_DEBUG
else
std::cerr << " " << sitem->pgp_ids[i] << " - Not a friend!" << std::endl;
std::cerr << " " << sitem->pgp_ids[i] << " - " << sitem->service_flags[i] << std::endl;
#endif
}
}
#ifdef PEER_DEBUG
else
std::cerr << " " << sitem->pgp_ids[i] << " - Not a friend!" << std::endl;
#endif
}
delete (*it);
}
delete (*it);
}
{
/* set missing groupIds */
{
/* set missing groupIds */
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
/* Standard groups */
const int standardGroupCount = 5;
const char *standardGroup[standardGroupCount] = { RS_GROUP_ID_FRIENDS, RS_GROUP_ID_FAMILY, RS_GROUP_ID_COWORKERS, RS_GROUP_ID_OTHERS, RS_GROUP_ID_FAVORITES };
bool foundStandardGroup[standardGroupCount] = { false, false, false, false, false };
/* Standard groups */
const int standardGroupCount = 5;
const char *standardGroup[standardGroupCount] = { RS_GROUP_ID_FRIENDS, RS_GROUP_ID_FAMILY, RS_GROUP_ID_COWORKERS, RS_GROUP_ID_OTHERS, RS_GROUP_ID_FAVORITES };
bool foundStandardGroup[standardGroupCount] = { false, false, false, false, false };
std::list<RsPeerGroupItem *>::iterator groupIt;
for (groupIt = groupList.begin(); groupIt != groupList.end(); ++groupIt) {
if ((*groupIt)->flag & RS_GROUP_FLAG_STANDARD) {
int i;
for (i = 0; i < standardGroupCount; ++i) {
if ((*groupIt)->id == standardGroup[i]) {
foundStandardGroup[i] = true;
break;
}
}
if (i >= standardGroupCount) {
/* No more a standard group, remove the flag standard */
(*groupIt)->flag &= ~RS_GROUP_FLAG_STANDARD;
}
} else {
uint32_t groupId = atoi((*groupIt)->id.c_str());
if (groupId == 0) {
rs_sprintf((*groupIt)->id, "%lu", lastGroupId++);
}
}
}
/* Initialize standard groups */
for (int i = 0; i < standardGroupCount; ++i) {
if (foundStandardGroup[i] == false) {
RsPeerGroupItem *gitem = new RsPeerGroupItem;
gitem->id = standardGroup[i];
gitem->name = standardGroup[i];
gitem->flag |= RS_GROUP_FLAG_STANDARD;
groupList.push_back(gitem);
}
}
}
std::list<RsPeerGroupItem *>::iterator groupIt;
for (groupIt = groupList.begin(); groupIt != groupList.end(); ++groupIt) {
if ((*groupIt)->flag & RS_GROUP_FLAG_STANDARD) {
int i;
for (i = 0; i < standardGroupCount; ++i) {
if ((*groupIt)->id == standardGroup[i]) {
foundStandardGroup[i] = true;
break;
}
}
// If we are hidden - don't want ExtAddrFinder - ever!
if (isHidden())
{
useExtAddrFinder = false;
}
if (i >= standardGroupCount) {
/* No more a standard group, remove the flag standard */
(*groupIt)->flag &= ~RS_GROUP_FLAG_STANDARD;
}
} else {
uint32_t groupId = atoi((*groupIt)->id.c_str());
if (groupId == 0) {
rs_sprintf((*groupIt)->id, "%lu", lastGroupId++);
}
}
}
mNetMgr->setIPServersEnabled(useExtAddrFinder);
/* Initialize standard groups */
for (int i = 0; i < standardGroupCount; ++i) {
if (foundStandardGroup[i] == false) {
RsPeerGroupItem *gitem = new RsPeerGroupItem;
gitem->id = standardGroup[i];
gitem->name = standardGroup[i];
gitem->flag |= RS_GROUP_FLAG_STANDARD;
groupList.push_back(gitem);
}
}
}
// Configure Proxy Server.
struct sockaddr_storage proxy_addr;
// Tor
sockaddr_storage_clear(proxy_addr);
sockaddr_storage_ipv4_aton(proxy_addr, proxyIpAddressTor.c_str());
sockaddr_storage_ipv4_setport(proxy_addr, proxyPortTor);
// If we are hidden - don't want ExtAddrFinder - ever!
if (isHidden())
{
useExtAddrFinder = false;
}
if (sockaddr_storage_isValidNet(proxy_addr))
{
setProxyServerAddress(RS_HIDDEN_TYPE_TOR, proxy_addr);
}
mNetMgr->setIPServersEnabled(useExtAddrFinder);
// I2P
sockaddr_storage_clear(proxy_addr);
sockaddr_storage_ipv4_aton(proxy_addr, proxyIpAddressI2P.c_str());
sockaddr_storage_ipv4_setport(proxy_addr, proxyPortI2P);
// Configure Proxy Server.
struct sockaddr_storage proxy_addr;
// Tor
sockaddr_storage_clear(proxy_addr);
sockaddr_storage_ipv4_aton(proxy_addr, proxyIpAddressTor.c_str());
sockaddr_storage_ipv4_setport(proxy_addr, proxyPortTor);
if (sockaddr_storage_isValidNet(proxy_addr))
{
setProxyServerAddress(RS_HIDDEN_TYPE_I2P, proxy_addr);
}
if (sockaddr_storage_isValidNet(proxy_addr))
{
setProxyServerAddress(RS_HIDDEN_TYPE_TOR, proxy_addr);
}
load.clear() ;
return true;
// I2P
sockaddr_storage_clear(proxy_addr);
sockaddr_storage_ipv4_aton(proxy_addr, proxyIpAddressI2P.c_str());
sockaddr_storage_ipv4_setport(proxy_addr, proxyPortI2P);
if (sockaddr_storage_isValidNet(proxy_addr))
{
setProxyServerAddress(RS_HIDDEN_TYPE_I2P, proxy_addr);
}
load.clear() ;
return true;
}

View file

@ -102,6 +102,8 @@ class peerState
std::string location;
std::string name;
uint32_t maxUpRate ;
uint32_t maxDnRate ;
};
class RsPeerGroupItem;
@ -207,6 +209,9 @@ virtual uint32_t getHiddenType(const RsPeerId &ssl_id) = 0;
virtual int getFriendCount(bool ssl, bool online) = 0;
virtual bool setMaxRates(const RsPgpId& pid,uint32_t maxUp,uint32_t maxDn)=0;
virtual bool getMaxRates(const RsPgpId& pid,uint32_t& maxUp,uint32_t& maxDn)=0;
virtual bool getMaxRates(const RsPeerId& pid,uint32_t& maxUp,uint32_t& maxDn)=0;
/************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/
@ -321,6 +326,9 @@ virtual int getFriendCount(bool ssl, bool online);
// Single Use Function... shouldn't be here. used by p3serverconfig.cc
virtual bool haveOnceConnected();
virtual bool setMaxRates(const RsPgpId& pid,uint32_t maxUp,uint32_t maxDn);
virtual bool getMaxRates(const RsPgpId& pid,uint32_t& maxUp,uint32_t& maxDn);
virtual bool getMaxRates(const RsPeerId& pid,uint32_t& maxUp,uint32_t& maxDn);
/************************************************************************************************/
/* Extra IMPL Functions (used by p3LinkMgr, p3NetMgr + Setup) */
@ -392,6 +400,7 @@ private:
std::list<RsItem *> saveCleanupList; /* TEMPORARY LIST WHEN SAVING */
std::map<RsPgpId, ServicePermissionFlags> mFriendsPermissionFlags ; // permission flags for each gpg key
std::map<RsPgpId, PeerBandwidthLimits> mPeerBandwidthLimits ; // bandwidth limits for each gpg key
struct sockaddr_storage mProxyServerAddressTor;
struct sockaddr_storage mProxyServerAddressI2P;

View file

@ -80,103 +80,103 @@ class RateInterface
public:
RateInterface()
:bw_in(0), bw_out(0), bwMax_in(0), bwMax_out(0),
bwCapEnabled(false), bwCap_in(0), bwCap_out(0) { return; }
:bw_in(0), bw_out(0), bwMax_in(0), bwMax_out(0),
bwCapEnabled(false), bwCap_in(0), bwCap_out(0) { return; }
virtual ~RateInterface() { return; }
virtual ~RateInterface() { return; }
virtual void getRates(RsBwRates &rates)
{
rates.mRateIn = bw_in;
rates.mRateOut = bw_out;
rates.mMaxRateIn = bwMax_in;
rates.mMaxRateOut = bwMax_out;
return;
}
virtual int gatherStatistics(std::list<RSTrafficClue>& /* outqueue_lst */,std::list<RSTrafficClue>& /* inqueue_lst */) { return 0;}
virtual int getQueueSize(bool /* in */) { return 0;}
virtual float getRate(bool in)
virtual void getRates(RsBwRates &rates)
{
if (in)
return bw_in;
return bw_out;
rates.mRateIn = bw_in;
rates.mRateOut = bw_out;
rates.mMaxRateIn = bwMax_in;
rates.mMaxRateOut = bwMax_out;
return;
}
virtual float getMaxRate(bool in)
virtual int gatherStatistics(std::list<RSTrafficClue>& /* outqueue_lst */,std::list<RSTrafficClue>& /* inqueue_lst */) { return 0;}
virtual int getQueueSize(bool /* in */) { return 0;}
virtual float getRate(bool in)
{
if (in)
return bwMax_in;
return bwMax_out;
if (in)
return bw_in;
return bw_out;
}
virtual void setMaxRate(bool in, float val)
virtual float getMaxRate(bool in)
{
if (in)
if (in)
return bwMax_in;
return bwMax_out;
}
virtual void setMaxRate(bool in, float val)
{
bwMax_in = val;
if (bwCapEnabled)
if (in)
{
if (bwMax_in > bwCap_in)
bwMax_in = val;
if (bwCapEnabled)
{
bwMax_in = bwCap_in;
if (bwMax_in > bwCap_in)
{
bwMax_in = bwCap_in;
}
}
}
}
else
{
bwMax_out = val;
if (bwCapEnabled)
else
{
if (bwMax_out > bwCap_out)
bwMax_out = val;
if (bwCapEnabled)
{
bwMax_out = bwCap_out;
if (bwMax_out > bwCap_out)
{
bwMax_out = bwCap_out;
}
}
}
}
return;
return;
}
virtual void setRateCap(float val_in, float val_out)
{
if ((val_in == 0) && (val_out == 0))
virtual void setRateCap(float val_in, float val_out)
{
if ((val_in == 0) && (val_out == 0))
{
#ifdef DEBUG_RATECAP
std::cerr << "RateInterface::setRateCap() Now disabled" << std::endl;
std::cerr << "RateInterface::setRateCap() Now disabled" << std::endl;
#endif
bwCapEnabled = false;
}
else
{
bwCapEnabled = false;
}
else
{
#ifdef DEBUG_RATECAP
std::cerr << "RateInterface::setRateCap() Enabled ";
std::cerr << "in: " << bwCap_in << " out: " << bwCap_out << std::endl;
std::cerr << "RateInterface::setRateCap() Enabled ";
std::cerr << "in: " << bwCap_in << " out: " << bwCap_out << std::endl;
#endif
bwCapEnabled = true;
bwCap_in = val_in;
bwCap_out = val_out;
bwCapEnabled = true;
bwCap_in = val_in;
bwCap_out = val_out;
}
return;
}
return;
}
protected:
void setRate(bool in, float val)
virtual void setRate(bool in, float val)
{
if (in)
bw_in = val;
else
bw_out = val;
return;
if (in)
bw_in = val;
else
bw_out = val;
return;
}
private:
float bw_in, bw_out, bwMax_in, bwMax_out;
bool bwCapEnabled;
float bwCap_in, bwCap_out;
private:
float bw_in, bw_out, bwMax_in, bwMax_out;
bool bwCapEnabled;
float bwCap_in, bwCap_out;
};

View file

@ -27,6 +27,7 @@
#include "util/rsdebug.h"
#include "util/rsstring.h"
#include "retroshare/rspeers.h"
#include <stdlib.h>
#include <time.h>
@ -69,18 +70,19 @@ static const float PQI_HANDLER_NB_PRIORITY_RATIO = 2 ;
pqihandler::pqihandler() : coreMtx("pqihandler")
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
// setup minimal total+individual rates.
rateIndiv_out = 0.01;
rateIndiv_in = 0.01;
rateMax_out = 0.01;
// setup minimal total+individual rates.
rateIndiv_out = 0.01;
rateIndiv_in = 0.01;
rateMax_out = 0.01;
rateMax_in = 0.01;
rateTotal_in = 0.0 ;
rateTotal_out = 0.0 ;
last_m = time(NULL) ;
nb_ticks = 0 ;
ticks_per_sec = 5 ; // initial guess
nb_ticks = 0 ;
mLastRateCapUpdate = 0 ;
ticks_per_sec = 5 ; // initial guess
return;
}
@ -113,27 +115,27 @@ int pqihandler::tick()
moreToTick = 1;
}
#endif
}
}
// static time_t last_print_time = 0 ;
// time_t now = time(NULL) ;
// if(now > last_print_time + 3)
// {
// std::map<uint16_t,uint32_t> per_service_count ;
// std::vector<uint32_t> per_priority_count ;
//
// ExtractOutQueueStatistics(per_service_count,per_priority_count) ;
//
// std::cerr << "PQIHandler outqueues: " << std::endl;
//
// for(std::map<uint16_t,uint32_t>::const_iterator it=per_service_count.begin();it!=per_service_count.end();++it)
// std::cerr << " " << std::hex << it->first << std::dec << " " << it->second << std::endl;
//
// for(int i=0;i<per_priority_count.size();++i)
// std::cerr << " " << i << " : " << per_priority_count[i] << std::endl;
//
// last_print_time = now ;
// }
time_t now = time(NULL) ;
if(now > mLastRateCapUpdate + 5)
{
// every 5 secs, update the max rates for all modules
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
for(std::map<RsPeerId, SearchModule *>::iterator it = mods.begin(); it != mods.end(); ++it)
{
// This is rather inelegant, but pqihandler has searchModules that are dynamically allocated, so the max rates
// need to be updated from inside.
uint32_t maxUp,maxDn ;
rsPeers->getPeerMaximumRates(it->first,maxUp,maxDn);
it->second->pqi->setRateCap(maxDn,maxUp);// mind the order! Dn first, than Up.
}
mLastRateCapUpdate = now ;
}
UpdateRates();
return moreToTick;
@ -277,144 +279,6 @@ int pqihandler::SendRsRawItem(RsRawItem *ns)
return queueOutRsItem(ns) ;
}
#ifdef TO_BE_REMOVED
// inputs. This is a very basic
// system that is completely biased and slow...
// someone please fix.
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// THIS CODE SHOULD BE ABLE TO BE REMOVED!
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
int pqihandler::locked_GetItems()
{
std::map<RsPeerId, SearchModule *>::iterator it;
RsItem *item;
int count = 0;
// loop through modules....
for(it = mods.begin(); it != mods.end(); ++it)
{
SearchModule *mod = (it -> second);
// check security... is output allowed.
if(0 < secpolicy_check((it -> second) -> sp,
0, PQI_INCOMING)) // PQI_ITEM_TYPE_ITEM, PQI_INCOMING))
{
// if yes... attempt to read.
while((item = (mod -> pqi) -> GetItem()) != NULL)
{
static int ntimes =0 ;
// if(++ntimes < 20)
{
std::cerr << "pqihandler::locked_GetItems() pqi->GetItem()";
std::cerr << " should never happen anymore!";
std::cerr << std::endl;
}
#ifdef RSITEM_DEBUG
std::string out;
rs_sprintf(out, "pqihandler::GetItems() Incoming Item from: %p\n", mod -> pqi);
item -> print_string(out);
pqioutput(PQL_DEBUG_BASIC,
pqihandlerzone, out);
#endif
if (item->PeerId() != (mod->pqi)->PeerId())
{
/* ERROR */
pqioutput(PQL_ALERT,
pqihandlerzone, "ERROR PeerIds dont match!");
item->PeerId(mod->pqi->PeerId());
}
locked_SortnStoreItem(item);
count++;
}
}
else
{
// not allowed to recieve from here....
while((item = (mod -> pqi) -> GetItem()) != NULL)
{
std::string out;
rs_sprintf(out, "pqihandler::GetItems() Incoming Item from: %p\n", mod -> pqi);
item -> print_string(out);
out += "\nItem Not Allowed (Sec Pol). deleting!";
pqioutput(PQL_DEBUG_BASIC,
pqihandlerzone, out);
delete item;
}
}
}
return count;
}
void pqihandler::locked_SortnStoreItem(RsItem *item)
{
/* get class type / subtype out of the item */
uint8_t vers = item -> PacketVersion();
/* whole Version reserved for SERVICES/CACHES */
if (vers == RS_PKT_VERSION_SERVICE)
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"SortnStore -> Service");
in_service.push_back(item);
item = NULL;
return;
}
std::cerr << "pqihandler::locked_SortnStoreItem() : unhandled item! Will be deleted. This is certainly a bug." << std::endl;
if (vers != RS_PKT_VERSION1)
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, "SortnStore -> Invalid VERSION! Deleting!");
delete item;
item = NULL;
return;
}
if (item)
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, "SortnStore -> Deleting Unsorted Item");
delete item;
}
return;
}
RsRawItem *pqihandler::GetRsRawItem()
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (in_service.size() != 0)
{
RsRawItem *fi = dynamic_cast<RsRawItem *>(in_service.front());
if (!fi) { delete in_service.front(); }
in_service.pop_front();
return fi;
}
return NULL;
}
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// ABOVE CODE SHOULD BE ABLE TO BE REMOVED!
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
#endif
static const float MIN_RATE = 0.01; // 10 B/s
int pqihandler::ExtractTrafficInfo(std::list<RSTrafficClue>& out_lst,std::list<RSTrafficClue>& in_lst)
{
in_lst.clear() ;
@ -640,6 +504,7 @@ int pqihandler::UpdateRates()
for(it = mods.begin(); it != mods.end(); ++it)
{
SearchModule *mod = (it -> second);
mod -> pqi -> setMaxRate(true, in_max_bw);
mod -> pqi -> setMaxRate(false, out_max_bw);
}
@ -649,18 +514,10 @@ int pqihandler::UpdateRates()
for(it = mods.begin(); it != mods.end(); ++it)
{
SearchModule *mod = (it -> second);
if (mod -> pqi -> getMaxRate(false) < max_out_effective) {
mod -> pqi -> setMaxRate(false, max_out_effective);
}
if (mod -> pqi -> getMaxRate(false) > avail_out) {
mod -> pqi -> setMaxRate(false, avail_out);
}
if (mod -> pqi -> getMaxRate(true) < max_in_effective) {
mod -> pqi -> setMaxRate(true, max_in_effective);
}
if (mod -> pqi -> getMaxRate(true) > avail_in) {
mod -> pqi -> setMaxRate(true, avail_in);
}
if (mod -> pqi -> getMaxRate(false) < max_out_effective) mod -> pqi -> setMaxRate(false, max_out_effective);
if (mod -> pqi -> getMaxRate(false) > avail_out) mod -> pqi -> setMaxRate(false, avail_out);
if (mod -> pqi -> getMaxRate(true) < max_in_effective) mod -> pqi -> setMaxRate(true, max_in_effective);
if (mod -> pqi -> getMaxRate(true) > avail_in) mod -> pqi -> setMaxRate(true, avail_in);
}
return 1;

View file

@ -39,8 +39,10 @@
class SearchModule
{
public:
RsPeerId peerid;
PQInterface *pqi;
SearchModule() : pqi(NULL) {}
RsPeerId peerid ;
PQInterface *pqi;
};
// Presents a P3 Face to the world!
@ -71,14 +73,18 @@ class pqihandler: public P3Interface, public pqiPublisher
#endif
// rate control.
//void setMaxRate(const RsPeerId& pid,bool in, uint32_t val_kBs);
void setMaxRate(bool in, float val);
float getMaxRate(bool in);
void setMaxRates(const RsPeerId& pid,bool in,float val) ;
float getMaxRates(const RsPeerId& pid,bool in) ;
void getCurrentRates(float &in, float &out);
// TESTING INTERFACE.
int ExtractRates(std::map<RsPeerId, RsBwRates> &ratemap, RsBwRates &totals);
int ExtractTrafficInfo(std::list<RSTrafficClue> &out_lst, std::list<RSTrafficClue> &in_lst);
int ExtractTrafficInfo(std::list<RSTrafficClue> &out_lst, std::list<RSTrafficClue> &in_lst);
protected:
/* check to be overloaded by those that can
@ -115,6 +121,7 @@ protected:
uint32_t nb_ticks ;
time_t last_m ;
time_t mLastRateCapUpdate ;
float ticks_per_sec ;
};

View file

@ -374,11 +374,15 @@ int pqissllistenbase::acceptconnection()
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
std::cerr << "(II) Checking incoming connection address: " << sockaddr_storage_iptostring(remote_addr) ;
if(rsBanList != NULL && !rsBanList->isAddressAccepted(remote_addr, RSBANLIST_CHECKING_FLAGS_BLACKLIST))
{
std::cerr << "(II) pqissllistenner::acceptConnection(): early denying connection attempt from blacklisted IP " << sockaddr_storage_iptostring(remote_addr) << std::endl;
std::cerr << " => early rejected at this point, because of blacklist." << std::endl;
return false ;
}
else
std::cerr << " => Accepted (i.e. whitelisted, or not blacklisted)." << std::endl;
{
std::string out;
out += "Accepted Connection from ";

View file

@ -615,6 +615,9 @@ bool pqissludp::moretoread(uint32_t usec)
reset_locked();
return 0;
}
if(SSL_pending(ssl_connection) > 0)
return 1 ;
/* otherwise - not error - strange! */
rslog(RSL_DEBUG_BASIC, pqissludpzone,

View file

@ -406,7 +406,11 @@ bool pqiSSLstore::encryptedSendItems(const std::list<RsItem*>& rsItemList)
if(rsSerialiser->serialise(*it, &data[offset],&sizeItem))
offset += sizeItem;
else
std::cerr << "(EE) pqiSSLstore::encryptedSendItems(): One item did not serialize. The item is probably unknown from the serializer. Dropping the item. " << std::endl;
{
std::cerr << "(EE) pqiSSLstore::encryptedSendItems(): One item did not serialize. The item is probably unknown from the serializer. Dropping the item. " << std::endl;
std::cerr << "Item content: " << std::endl;
(*it)->print(std::cerr) ;
}
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
delete *it;

View file

@ -77,37 +77,38 @@ pqistreamer::pqistreamer(RsSerialiser *rss, const RsPeerId& id, BinInterface *bi
mCurrRead(0), mCurrSent(0),
mAvgReadCount(0), mAvgSentCount(0)
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
// 100 B/s (minimal)
setMaxRate(true, 0.1);
setMaxRate(false, 0.1);
setRate(true, 0); // needs to be off-mutex
setRate(false, 0);
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
mAcceptsPacketSlicing = false ; // by default. Will be turned into true when everyone's ready.
mLastSentPacketSlicingProbe = 0 ;
mAvgLastUpdate = mCurrReadTS = mCurrSentTS = time(NULL);
mIncomingSize = 0 ;
mStatisticsTimeStamp = 0 ;
/* allocated once */
/* allocated once */
mPkt_rpend_size = 0;
mPkt_rpending = 0;
mReading_state = reading_state_initial ;
mReading_state = reading_state_initial ;
// 100 B/s (minimal)
setMaxRate(true, 0.1);
setMaxRate(false, 0.1);
setRate(true, 0);
setRate(false, 0);
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::pqistreamer() Initialisation!");
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::pqistreamer() Initialisation!");
if (!bio_in)
{
pqioutput(PQL_ALERT, pqistreamerzone, "pqistreamer::pqistreamer() NULL bio, FATAL ERROR!");
exit(1);
}
if (!bio_in)
{
pqioutput(PQL_ALERT, pqistreamerzone, "pqistreamer::pqistreamer() NULL bio, FATAL ERROR!");
exit(1);
}
mFailed_read_attempts = 0; // reset failed read, as no packet is still read.
mFailed_read_attempts = 0; // reset failed read, as no packet is still read.
return;
return;
}
pqistreamer::~pqistreamer()
@ -195,18 +196,39 @@ RsItem *pqistreamer::GetItem()
return osr;
}
float pqistreamer::getRate(bool b)
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
return RateInterface::getRate(b) ;
}
void pqistreamer::setMaxRate(bool b,float f)
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
RateInterface::setMaxRate(b,f) ;
}
void pqistreamer::setRate(bool b,float f)
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
RateInterface::setRate(b,f) ;
}
void pqistreamer::updateRates()
{
// now update rates both ways.
time_t t = time(NULL); // get current timestep.
int64_t diff ;
if (t > mAvgLastUpdate + PQISTREAM_AVG_PERIOD)
{
int64_t diff = int64_t(t) - int64_t(mAvgLastUpdate) ;
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
float avgReadpSec = getRate(true ) * PQISTREAM_AVG_FRAC + (1.0 - PQISTREAM_AVG_FRAC) * mAvgReadCount/(1000.0 * float(diff));
float avgSentpSec = getRate(false) * PQISTREAM_AVG_FRAC + (1.0 - PQISTREAM_AVG_FRAC) * mAvgSentCount/(1000.0 * float(diff));
diff = int64_t(t) - int64_t(mAvgLastUpdate) ;
}
if (diff > PQISTREAM_AVG_PERIOD)
{
float avgReadpSec = getRate(true ) * PQISTREAM_AVG_FRAC + (1.0 - PQISTREAM_AVG_FRAC) * mAvgReadCount/(1024.0 * float(diff));
float avgSentpSec = getRate(false) * PQISTREAM_AVG_FRAC + (1.0 - PQISTREAM_AVG_FRAC) * mAvgSentCount/(1024.0 * float(diff));
#ifdef DEBUG_PQISTREAMER
std::cerr << "Peer " << PeerId() << ": Current speed estimates: " << avgReadpSec << " / " << avgSentpSec << std::endl;
@ -226,9 +248,12 @@ void pqistreamer::updateRates()
setRate(false, 0);
}
mAvgLastUpdate = t;
mAvgReadCount = 0;
mAvgSentCount = 0;
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
mAvgLastUpdate = t;
mAvgReadCount = 0;
mAvgSentCount = 0;
}
}
}

View file

@ -67,6 +67,12 @@ class pqistreamer: public PQInterface
virtual void getRates(RsBwRates &rates);
virtual int getQueueSize(bool in); // extracting data.
virtual int gatherStatistics(std::list<RSTrafficClue>& outqueue_stats,std::list<RSTrafficClue>& inqueue_stats); // extracting data.
// mutex protected versions of RateInterface calls.
virtual void setRate(bool b,float f) ;
virtual void setMaxRate(bool b,float f) ;
virtual float getRate(bool b) ;
protected:
int tick_bio();
@ -85,7 +91,7 @@ class pqistreamer: public PQInterface
virtual int locked_gatherStatistics(std::list<RSTrafficClue>& outqueue_stats,std::list<RSTrafficClue>& inqueue_stats); // extracting data.
void updateRates() ;
protected:
RsMutex mStreamerMtx ; // Protects data, fns below, protected so pqiqos can use it too.
@ -148,8 +154,8 @@ class pqistreamer: public PQInterface
time_t mCurrSentTS;
time_t mAvgLastUpdate; // TS from which these are measured.
float mAvgReadCount;
float mAvgSentCount;
uint32_t mAvgReadCount;
uint32_t mAvgSentCount;
time_t mLastIncomingTs;

View file

@ -293,8 +293,8 @@ public:
/* Data Rate Control - to be moved here */
virtual int SetMaxDataRates( int downKb, int upKb ) = 0;
virtual int GetMaxDataRates( int &inKb, int &outKb ) = 0;
virtual int GetCurrentDataRates( float &inKb, float &outKb ) = 0;
};
#endif

View file

@ -61,7 +61,7 @@ template<int n> class t_RsFlags32
#define FLAGS_TAG_TRANSFER_REQS 0x4228af
#define FLAGS_TAG_FILE_STORAGE 0x184738
#define FLAGS_TAG_FILE_SEARCH 0xf29ba5
#define FLAGS_TAG_FILE_SEARCH 0xf29ba5
#define FLAGS_TAG_SERVICE_PERM 0x380912
#define FLAGS_TAG_SERVICE_CHAT 0x839042

View file

@ -112,6 +112,7 @@ class RsGxsCircleDetails
std::string mCircleName;
uint32_t mCircleType;
RsGxsCircleId mRestrictedCircleId;
bool mAmIAllowed ; // true when one of load GXS ids belong to the circle allowed list (admin list & subscribed list).
@ -123,32 +124,29 @@ class RsGxsCircleDetails
class RsGxsCircles: public RsGxsIfaceHelper
{
public:
RsGxsCircles(RsGxsIface *gxs)
:RsGxsIfaceHelper(gxs) { return; }
virtual ~RsGxsCircles() { return; }
public:
RsGxsCircles(RsGxsIface *gxs) :RsGxsIfaceHelper(gxs) { return; }
virtual ~RsGxsCircles() { return; }
/* External Interface (Cached stuff) */
virtual bool getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details) = 0;
virtual bool getCircleExternalIdList(std::list<RsGxsCircleId> &circleIds) = 0;
virtual bool getCirclePersonalIdList(std::list<RsGxsCircleId> &circleIds) = 0;
virtual bool getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details) = 0;
virtual bool getCircleExternalIdList(std::list<RsGxsCircleId> &circleIds) = 0;
virtual bool getCirclePersonalIdList(std::list<RsGxsCircleId> &circleIds) = 0;
/* membership management for external circles */
virtual bool requestCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id)=0 ;
virtual bool cancelCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id)=0 ;
/* membership management for external circles */
virtual bool requestCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id)=0 ;
virtual bool cancelCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id)=0 ;
/* standard load */
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups) = 0;
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups) = 0;
/* make new group */
virtual void createGroup(uint32_t& token, RsGxsCircleGroup &group) = 0;
/* update an existing group */
virtual void updateGroup(uint32_t &token, RsGxsCircleGroup &group) = 0;
/* make new group */
virtual void createGroup(uint32_t& token, RsGxsCircleGroup &group) = 0;
/* update an existing group */
virtual void updateGroup(uint32_t &token, RsGxsCircleGroup &group) = 0;
};

View file

@ -428,6 +428,10 @@ public:
virtual ServicePermissionFlags servicePermissionFlags(const RsPgpId& gpg_id) = 0;
virtual ServicePermissionFlags servicePermissionFlags(const RsPeerId& ssl_id) = 0;
virtual void setServicePermissionFlags(const RsPgpId& gpg_id,const ServicePermissionFlags& flags) = 0;
virtual bool setPeerMaximumRates(const RsPgpId& pid,uint32_t maxUploadRate,uint32_t maxDownloadRate) =0;
virtual bool getPeerMaximumRates(const RsPeerId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate) =0;
virtual bool getPeerMaximumRates(const RsPgpId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate) =0;
};
#endif

View file

@ -118,6 +118,15 @@ class Condition
std::string name;
};
class PeerBandwidthLimits
{
public:
PeerBandwidthLimits() : max_up_rate_kbs(0), max_dl_rate_kbs(0) {}
uint32_t max_up_rate_kbs ;
uint32_t max_dl_rate_kbs ;
};
//class SearchRequest // unused stuff.
//{
// public:

View file

@ -35,6 +35,14 @@
#include <sqlcipher/sqlite3.h>
#endif
#ifndef RS_ENABLE_ZCNATASSIST
#ifdef RS_USE_LIBUPNP
#include "upnp/upnpconfig.h"
#else
#include "miniupnpc/miniupnpc.h"
#endif // RS_USE_LIBUPNP
#endif // RS_ENABLE_ZCNATASSIST
std::string RsServer::getSQLCipherVersion()
{
sqlite3* mDb;
@ -84,5 +92,12 @@ void RsServer::getLibraries(std::list<RsLibraryInfo> &libraries)
#ifndef NO_SQLCIPHER
libraries.push_back(RsLibraryInfo("SQLCipher", getSQLCipherVersion()));
#endif
#ifndef RS_ENABLE_ZCNATASSIST
#ifdef RS_USE_LIBUPNP
libraries.push_back(RsLibraryInfo("UPnP (libupnp)", UPNP_VERSION_STRING));
#else
libraries.push_back(RsLibraryInfo("UPnP (MiniUPnP)", MINIUPNPC_VERSION));
#endif // RS_USE_LIBUPNP
#endif // RS_ENABLE_ZCNATASSIST
libraries.push_back(RsLibraryInfo("Zlib", ZLIB_VERSION));
}

View file

@ -241,6 +241,20 @@ bool p3Peers::isFriend(const RsPeerId &ssl_id)
return mPeerMgr->isFriend(ssl_id);
}
bool p3Peers::getPeerMaximumRates(const RsPeerId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate)
{
return mPeerMgr->getMaxRates(pid,maxUploadRate,maxDownloadRate) ;
}
bool p3Peers::getPeerMaximumRates(const RsPgpId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate)
{
return mPeerMgr->getMaxRates(pid,maxUploadRate,maxDownloadRate) ;
}
bool p3Peers::setPeerMaximumRates(const RsPgpId& pid,uint32_t maxUploadRate,uint32_t maxDownloadRate)
{
return mPeerMgr->setMaxRates(pid,maxUploadRate,maxDownloadRate) ;
}
bool p3Peers::haveSecretKey(const RsPgpId& id)
{
return AuthGPG::getAuthGPG()->haveSecretKey(id);
@ -296,17 +310,17 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
d.hiddenNodeAddress = ps.hiddenDomain;
d.hiddenNodePort = ps.hiddenPort;
d.hiddenType = ps.hiddenType;
if(sockaddr_storage_isnull(ps.localaddr)) // that happens if the address is not initialised.
{
{
d.localAddr = "INVALID_IP";
d.localPort = 0 ;
}
else
{
}
else
{
d.localAddr = sockaddr_storage_iptostring(ps.localaddr);
d.localPort = sockaddr_storage_port(ps.localaddr);
}
}
d.extAddr = "hidden";
d.extPort = 0;
d.dyndns = "";
@ -341,10 +355,10 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
}
d.dyndns = ps.dyndns;
std::list<pqiIpAddress>::iterator it;
for(it = ps.ipAddrs.mLocal.mAddrs.begin();
it != ps.ipAddrs.mLocal.mAddrs.end(); ++it)
it != ps.ipAddrs.mLocal.mAddrs.end(); ++it)
{
std::string toto;
toto += "L:";
@ -352,8 +366,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
rs_sprintf_append(toto, " %ld sec", time(NULL) - it->mSeenTime);
d.ipAddressList.push_back(toto);
}
for(it = ps.ipAddrs.mExt.mAddrs.begin();
it != ps.ipAddrs.mExt.mAddrs.end(); ++it)
for(it = ps.ipAddrs.mExt.mAddrs.begin(); it != ps.ipAddrs.mExt.mAddrs.end(); ++it)
{
std::string toto;
toto += "E:";
@ -362,33 +375,32 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
d.ipAddressList.push_back(toto);
}
}
switch(ps.netMode & RS_NET_MODE_ACTUAL)
{
case RS_NET_MODE_EXT:
d.netMode = RS_NETMODE_EXT;
break;
case RS_NET_MODE_UPNP:
d.netMode = RS_NETMODE_UPNP;
break;
case RS_NET_MODE_UDP:
d.netMode = RS_NETMODE_UDP;
break;
case RS_NET_MODE_HIDDEN:
d.netMode = RS_NETMODE_HIDDEN;
break;
case RS_NET_MODE_UNREACHABLE:
case RS_NET_MODE_UNKNOWN:
default:
d.netMode = RS_NETMODE_UNREACHABLE;
break;
case RS_NET_MODE_EXT:
d.netMode = RS_NETMODE_EXT;
break;
case RS_NET_MODE_UPNP:
d.netMode = RS_NETMODE_UPNP;
break;
case RS_NET_MODE_UDP:
d.netMode = RS_NETMODE_UDP;
break;
case RS_NET_MODE_HIDDEN:
d.netMode = RS_NETMODE_HIDDEN;
break;
case RS_NET_MODE_UNREACHABLE:
case RS_NET_MODE_UNKNOWN:
default:
d.netMode = RS_NETMODE_UNREACHABLE;
break;
}
d.vs_disc = ps.vs_disc;
d.vs_dht = ps.vs_dht;
/* Translate */
peerConnectState pcs;
if (!mLinkMgr->getFriendNetStatus(id, pcs))
@ -414,14 +426,10 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
}
d.state = 0;
if (pcs.state & RS_PEER_S_FRIEND)
d.state |= RS_PEER_STATE_FRIEND;
if (pcs.state & RS_PEER_S_ONLINE)
d.state |= RS_PEER_STATE_ONLINE;
if (pcs.state & RS_PEER_S_CONNECTED)
d.state |= RS_PEER_STATE_CONNECTED;
if (pcs.state & RS_PEER_S_UNREACHABLE)
d.state |= RS_PEER_STATE_UNREACHABLE;
if (pcs.state & RS_PEER_S_FRIEND) d.state |= RS_PEER_STATE_FRIEND;
if (pcs.state & RS_PEER_S_ONLINE) d.state |= RS_PEER_STATE_ONLINE;
if (pcs.state & RS_PEER_S_CONNECTED) d.state |= RS_PEER_STATE_CONNECTED;
if (pcs.state & RS_PEER_S_UNREACHABLE) d.state |= RS_PEER_STATE_UNREACHABLE;
d.actAsServer = pcs.actAsServer;
@ -433,7 +441,6 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
d.connectState = RS_PEER_CONNECTSTATE_OFFLINE;
d.connectStateString.clear();
if (pcs.inConnAttempt)
{
if (pcs.currentConnAddrAttempt.type & RS_NET_CONN_TCP_ALL) {
@ -445,7 +452,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
}
}
else if (pcs.state & RS_PEER_S_CONNECTED)
{
{
/* peer is connected - determine how and set proper connectState */
if(mPeerMgr->isHidden())
{
@ -519,8 +526,8 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
d.connectState = RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN;
}
}
}
}
d.wasDeniedConnection = pcs.wasDeniedConnection;
d.deniedTS = pcs.deniedTS;

View file

@ -139,6 +139,9 @@ public:
virtual ServicePermissionFlags servicePermissionFlags(const RsPeerId & ssl_id);
virtual void setServicePermissionFlags(const RsPgpId& gpg_id,const ServicePermissionFlags& flags);
virtual bool setPeerMaximumRates(const RsPgpId& pid,uint32_t maxUploadRate,uint32_t maxDownloadRate);
virtual bool getPeerMaximumRates(const RsPgpId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate);
virtual bool getPeerMaximumRates(const RsPeerId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate);
private:
p3LinkMgr *mLinkMgr;

View file

@ -503,7 +503,6 @@ bool p3ServerConfig::switchToOperatingMode(uint32_t opMode)
return true;
}
/* handle data rates.
* Mutex must be handled at the lower levels: TODO */

View file

@ -684,6 +684,7 @@ uint32_t RsPeerConfigSerialiser::size(RsItem *i)
RsPeerNetItem *pni;
RsPeerGroupItem *pgi;
RsPeerServicePermissionItem *pri;
RsPeerBandwidthLimitsItem *pblitem;
if (NULL != (pni = dynamic_cast<RsPeerNetItem *>(i)))
{
@ -701,6 +702,10 @@ uint32_t RsPeerConfigSerialiser::size(RsItem *i)
{
return sizePermissions(pri);
}
else if (NULL != (pblitem = dynamic_cast<RsPeerBandwidthLimitsItem *>(i)))
{
return sizePeerBandwidthLimits(pblitem);
}
return 0;
}
@ -712,6 +717,7 @@ bool RsPeerConfigSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsi
RsPeerStunItem *psi;
RsPeerGroupItem *pgi;
RsPeerServicePermissionItem *pri;
RsPeerBandwidthLimitsItem *pblitem;
if (NULL != (pni = dynamic_cast<RsPeerNetItem *>(i)))
{
@ -729,6 +735,10 @@ bool RsPeerConfigSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsi
{
return serialisePermissions(pri, data, pktsize);
}
else if (NULL != (pblitem = dynamic_cast<RsPeerBandwidthLimitsItem *>(i)))
{
return serialisePeerBandwidthLimits(pblitem, data, pktsize);
}
return false;
}
@ -758,6 +768,8 @@ RsItem *RsPeerConfigSerialiser::deserialise(void *data, uint32_t *pktsize)
return deserialiseGroup(data, pktsize);
case RS_PKT_SUBTYPE_PEER_PERMISSIONS:
return deserialisePermissions(data, pktsize);
case RS_PKT_SUBTYPE_PEER_BANDLIMITS:
return deserialisePeerBandwidthLimits(data, pktsize);
default:
return NULL;
}
@ -880,7 +892,6 @@ uint32_t RsPeerConfigSerialiser::sizeNet(RsPeerNetItem *i)
s += 2; /* domain_port */
return s;
}
bool RsPeerConfigSerialiser::serialiseNet(RsPeerNetItem *item, void *data, uint32_t *size)
@ -1028,6 +1039,160 @@ RsPeerNetItem *RsPeerConfigSerialiser::deserialiseNet(void *data, uint32_t *size
return item;
}
/****************************************************************************/
uint32_t RsPeerConfigSerialiser::sizePeerBandwidthLimits(RsPeerBandwidthLimitsItem *i)
{
uint32_t s = 8; /* header */
s += 4; // number of elements
s += i->peers.size() * (4 + 4 + RsPgpId::SIZE_IN_BYTES) ;
return s;
}
bool RsPeerConfigSerialiser::serialisePeerBandwidthLimits(RsPeerBandwidthLimitsItem *item, void *data, uint32_t *size)
{
uint32_t tlvsize = RsPeerConfigSerialiser::sizePeerBandwidthLimits(item);
uint32_t offset = 0;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsPeerConfigSerialiser::serialiseNet() tlvsize: " << tlvsize << std::endl;
#endif
if(*size < tlvsize)
{
#ifdef RSSERIAL_ERROR_DEBUG
std::cerr << "RsPeerConfigSerialiser::serialiseNet() ERROR not enough space" << std::endl;
#endif
return false; /* not enough space */
}
*size = tlvsize;
bool ok = true;
// serialise header
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
#ifdef RSSERIAL_DEBUG
std::cerr << "RsPeerConfigSerialiser::serialiseNet() Header: " << ok << std::endl;
std::cerr << "RsPeerConfigSerialiser::serialiseNet() Header test: " << tlvsize << std::endl;
#endif
/* skip the header */
offset += 8;
ok &= setRawUInt32(data, tlvsize, &offset, item->peers.size()); /* Mandatory */
for(std::map<RsPgpId,PeerBandwidthLimits>::const_iterator it(item->peers.begin());it!=item->peers.end();++it)
{
ok &= it->first.serialise(data,tlvsize,offset);
ok &= setRawUInt32(data, tlvsize, &offset, it->second.max_up_rate_kbs); /* Mandatory */
ok &= setRawUInt32(data, tlvsize, &offset, it->second.max_dl_rate_kbs); /* Mandatory */
}
if(offset != tlvsize)
{
#ifdef RSSERIAL_ERROR_DEBUG
std::cerr << "RsPeerConfigSerialiser::serialiseNet() Size Error! " << std::endl;
#endif
ok = false;
}
return ok;
}
RsPeerBandwidthLimitsItem *RsPeerConfigSerialiser::deserialisePeerBandwidthLimits(void *data, uint32_t *size)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
uint32_t offset = 0;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsPeerConfigSerialiser::deserialiseNet() rssize: " << rssize << std::endl;
#endif
if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) ||
(RS_PKT_CLASS_CONFIG != getRsItemClass(rstype)) ||
(RS_PKT_TYPE_PEER_CONFIG != getRsItemType(rstype)) ||
(RS_PKT_SUBTYPE_PEER_BANDLIMITS != getRsItemSubType(rstype)))
{
#ifdef RSSERIAL_ERROR_DEBUG
std::cerr << "RsPeerConfigSerialiser::deserialiseNet() ERROR Type" << std::endl;
#endif
return NULL; /* wrong type */
}
if (*size < rssize) /* check size */
{
#ifdef RSSERIAL_ERROR_DEBUG
std::cerr << "RsPeerConfigSerialiser::deserialiseNet() ERROR not enough data" << std::endl;
#endif
return NULL; /* not enough data */
}
/* set the packet length */
*size = rssize;
bool ok = true;
RsPeerBandwidthLimitsItem *item = new RsPeerBandwidthLimitsItem();
/* skip the header */
offset += 8;
/* get mandatory parts first */
uint32_t n ;
ok &= getRawUInt32(data, rssize, &offset, &n) ;
for(uint32_t i=0;i<n;++i)
{
RsPgpId pgpid ;
ok &= pgpid.deserialise(data,rssize,offset) ;
PeerBandwidthLimits p ;
ok &= getRawUInt32(data, rssize, &offset, &(p.max_up_rate_kbs)); /* Mandatory */
ok &= getRawUInt32(data, rssize, &offset, &(p.max_dl_rate_kbs)); /* Mandatory */
item->peers[pgpid] = p ;
}
if (offset != rssize)
{
#ifdef RSSERIAL_ERROR_DEBUG
std::cerr << "RsPeerConfigSerialiser::deserialiseNet() ERROR size mismatch" << std::endl;
#endif
/* error */
delete item;
return NULL;
}
return item;
}
std::ostream &RsPeerBandwidthLimitsItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsPeerBandwidthLimitsItem", indent);
uint16_t int_Indent = indent + 2;
for(std::map<RsPgpId,PeerBandwidthLimits>::const_iterator it(peers.begin());it!=peers.end();++it)
{
printIndent(out, int_Indent);
out << it->first << " : " << it->second.max_up_rate_kbs << " (up) " << it->second.max_dl_rate_kbs << " (dn)" << std::endl;
}
printRsItemEnd(out, "RsPeerStunItem", indent);
return out;
}
/****************************************************************************/
RsPeerStunItem::~RsPeerStunItem()

View file

@ -54,6 +54,7 @@ const uint8_t RS_PKT_SUBTYPE_PEER_STUN = 0x02;
const uint8_t RS_PKT_SUBTYPE_PEER_NET = 0x03;
const uint8_t RS_PKT_SUBTYPE_PEER_GROUP = 0x04;
const uint8_t RS_PKT_SUBTYPE_PEER_PERMISSIONS = 0x05;
const uint8_t RS_PKT_SUBTYPE_PEER_BANDLIMITS = 0x06;
/* FILE CONFIG SUBTYPES */
const uint8_t RS_PKT_SUBTYPE_FILE_TRANSFER = 0x01;
@ -61,6 +62,8 @@ const uint8_t RS_PKT_SUBTYPE_FILE_ITEM = 0x02;
/**************************************************************************/
// We should make these items use a clean serialise code, and all derive from the same item type.
class RsPeerNetItem: public RsItem
{
public:
@ -97,6 +100,7 @@ std::ostream &print(std::ostream &out, uint16_t indent = 0);
uint16_t domain_port;
};
// This item should be merged with the next item, but that is not backward compatible.
class RsPeerServicePermissionItem : public RsItem
{
public:
@ -114,7 +118,21 @@ class RsPeerServicePermissionItem : public RsItem
std::vector<RsPgpId> pgp_ids ;
std::vector<ServicePermissionFlags> service_flags ;
};
class RsPeerBandwidthLimitsItem : public RsItem
{
public:
RsPeerBandwidthLimitsItem() : RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_PEER_CONFIG, RS_PKT_SUBTYPE_PEER_BANDLIMITS) {}
virtual ~RsPeerBandwidthLimitsItem() {}
virtual void clear()
{
peers.clear() ;
}
std::ostream &print(std::ostream &out, uint16_t indent = 0);
/* Mandatory */
std::map<RsPgpId,PeerBandwidthLimits> peers ;
};
class RsPeerGroupItem : public RsItem
{
@ -183,6 +201,10 @@ virtual uint32_t sizeGroup(RsPeerGroupItem *);
virtual bool serialiseGroup (RsPeerGroupItem *item, void *data, uint32_t *size);
virtual RsPeerGroupItem * deserialiseGroup(void *data, uint32_t *size);
virtual uint32_t sizePeerBandwidthLimits(RsPeerBandwidthLimitsItem *);
virtual bool serialisePeerBandwidthLimits (RsPeerBandwidthLimitsItem *item, void *data, uint32_t *size);
virtual RsPeerBandwidthLimitsItem *deserialisePeerBandwidthLimits(void *data, uint32_t *size);
virtual uint32_t sizePermissions(RsPeerServicePermissionItem *);
virtual bool serialisePermissions (RsPeerServicePermissionItem *item, void *data, uint32_t *size);
virtual RsPeerServicePermissionItem * deserialisePermissions(void *data, uint32_t *size);

View file

@ -13,8 +13,10 @@ const uint8_t RsNxsSyncGrpItem::FLAG_RESPONSE = 0x002;
const uint8_t RsNxsSyncMsgItem::FLAG_REQUEST = 0x001;
const uint8_t RsNxsSyncMsgItem::FLAG_RESPONSE = 0x002;
const uint8_t RsNxsSyncGrpItem::FLAG_USE_SYNC_HASH = 0x001;
const uint8_t RsNxsSyncMsgItem::FLAG_USE_SYNC_HASH = 0x001;
const uint8_t RsNxsSyncGrpItem::FLAG_USE_SYNC_HASH = 0x0001;
const uint8_t RsNxsSyncMsgItem::FLAG_USE_SYNC_HASH = 0x0001;
const uint8_t RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID = 0x02;
/** transaction state **/
const uint16_t RsNxsTransacItem::FLAG_BEGIN_P1 = 0x0001;

View file

@ -351,12 +351,12 @@ public:
#ifdef UNUSED_CODE
static const uint8_t FLAG_USE_SYNC_HASH;
#endif
static const uint8_t FLAG_USE_HASHED_GROUP_ID;
RsNxsSyncMsgReqItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_MSG_REQ_ITEM) { clear(); return; }
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const;
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const;
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent);

View file

@ -283,6 +283,7 @@ bool p3GxsCircles:: getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails
details.mCircleName = data.mCircleName;
details.mCircleType = data.mCircleType;
details.mRestrictedCircleId = data.mRestrictedCircleId;
details.mAllowedNodes = data.mAllowedNodes;
details.mSubscriptionFlags.clear();
@ -588,6 +589,7 @@ bool RsGxsCircleCache::loadBaseCircle(const RsGxsCircleGroup &circle)
mOriginator = circle.mMeta.mOriginator ;
mAllowedNodes = circle.mLocalFriends ;
mRestrictedCircleId = circle.mMeta.mCircleId ;
mMembershipStatus.clear() ;

View file

@ -152,6 +152,7 @@ class RsGxsCircleCache
uint32_t mCircleType;
bool mIsExternal;
RsGxsCircleId mRestrictedCircleId ; // circle ID that circle is restricted to.
uint32_t mGroupStatus;
uint32_t mGroupSubscribeFlags;

View file

@ -58,9 +58,14 @@
#define GXSID_MAX_CACHE_SIZE 5000
static const uint32_t MAX_KEEP_UNUSED_KEYS = 30*86400 ; // remove unused keys after 30 days
static const uint32_t MAX_KEEP_BANNED_KEYS = 30*86400 ; // remove banned keys after 5 days
static const uint32_t MAX_DELAY_BEFORE_CLEANING = 601 ; // clean old keys every 10 mins
// unused keys are deleted according to some heuristic that should favor known keys, signed keys etc.
static const time_t MAX_KEEP_KEYS_BANNED = 2 * 86400 ; // get rid of banned ids after 2 days. That gives a chance to un-ban someone before he gets kicked out
static const time_t MAX_KEEP_KEYS_DEFAULT = 5 * 86400 ; // default for unsigned identities: 5 days
static const time_t MAX_KEEP_KEYS_SIGNED = 8 * 86400 ; // signed identities by unknown key
static const time_t MAX_KEEP_KEYS_SIGNED_KNOWN = 30 * 86400 ; // signed identities by known node keys
static const uint32_t MAX_DELAY_BEFORE_CLEANING= 1800 ; // clean old keys every 30 mins
RsIdentity *rsIdentity = NULL;
@ -153,7 +158,7 @@ p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *ne
{
mBgSchedule_Mode = 0;
mBgSchedule_Active = false;
mLastKeyCleaningTime = 0 ;
mLastKeyCleaningTime = time(NULL) - int(MAX_DELAY_BEFORE_CLEANING * 0.9) ;
mLastConfigUpdate = 0 ;
mOwnIdsLoaded = false ;
@ -262,11 +267,16 @@ time_t p3IdService::locked_getLastUsageTS(const RsGxsId& gxs_id)
}
void p3IdService::timeStampKey(const RsGxsId& gxs_id)
{
RS_STACK_MUTEX(mIdMtx) ;
if(rsReputations->isIdentityBanned(gxs_id))
{
std::cerr << "(II) p3IdService:timeStampKey(): refusing to time stamp key " << gxs_id << " because it is banned." << std::endl;
return;
}
RS_STACK_MUTEX(mIdMtx) ;
mKeysTS[gxs_id] = time(NULL) ;
slowIndicateConfigChanged() ;
slowIndicateConfigChanged() ;
}
bool p3IdService::loadList(std::list<RsItem*>& items)
@ -306,49 +316,114 @@ bool p3IdService::saveList(bool& cleanup,std::list<RsItem*>& items)
items.push_back(item) ;
return true ;
}
class IdCacheEntryCleaner
{
public:
IdCacheEntryCleaner(const std::map<RsGxsId,time_t>& last_usage_TSs) : mLastUsageTS(last_usage_TSs) {}
bool processEntry(RsGxsIdCache& entry)
{
time_t now = time(NULL);
const RsGxsId& gxs_id = entry.details.mId ;
bool is_id_banned = rsReputations->isIdentityBanned(gxs_id) ;
bool is_own_id = (bool)(entry.details.mFlags & RS_IDENTITY_FLAGS_IS_OWN_ID) ;
bool is_known_id = (bool)(entry.details.mFlags & RS_IDENTITY_FLAGS_PGP_KNOWN) ;
bool is_signed_id = (bool)(entry.details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED) ;
bool is_a_contact = (bool)(entry.details.mFlags & RS_IDENTITY_FLAGS_IS_A_CONTACT) ;
std::cerr << "Identity: " << gxs_id << ": banned: " << is_id_banned << ", own: " << is_own_id << ", contact: " << is_a_contact << ", signed: " << is_signed_id << ", known: " << is_known_id;
if(is_own_id || is_a_contact)
{
std::cerr << " => kept" << std::endl;
return true ;
}
std::map<RsGxsId,time_t>::const_iterator it = mLastUsageTS.find(gxs_id) ;
if(it == mLastUsageTS.end())
{
std::cerr << "No Ts for this ID" << std::endl;
return true ;
}
time_t last_usage_ts = it->second;
time_t max_keep_time ;
if(is_id_banned)
max_keep_time = MAX_KEEP_KEYS_BANNED ;
else if(is_known_id)
max_keep_time = MAX_KEEP_KEYS_SIGNED_KNOWN ;
else if(is_signed_id)
max_keep_time = MAX_KEEP_KEYS_SIGNED ;
else
max_keep_time = MAX_KEEP_KEYS_DEFAULT ;
std::cerr << ". Max keep = " << max_keep_time/86400 << " days. Unused for " << (now - last_usage_ts + 86399)/86400 << " days " ;
if(now > last_usage_ts + max_keep_time)
{
std::cerr << " => delete " << std::endl;
ids_to_delete.push_back(gxs_id) ;
}
else
std::cerr << " => keep " << std::endl;
return true;
}
std::list<RsGxsId> ids_to_delete ;
const std::map<RsGxsId,time_t>& mLastUsageTS;
};
void p3IdService::cleanUnusedKeys()
{
std::list<RsGxsId> ids_to_delete ;
std::list<RsGxsId> ids_to_delete ;
// we need to stash all ids to delete into an off-mutex structure since deleteIdentity() will trigger the lock
{
RS_STACK_MUTEX(mIdMtx) ;
std::cerr << "Cleaning unused keys:" << std::endl;
// we need to stash all ids to delete into an off-mutex structure since deleteIdentity() will trigger the lock
{
RS_STACK_MUTEX(mIdMtx) ;
if(!mOwnIdsLoaded)
{
std::cerr << "(EE) Own ids not loaded. Cannot clean unused keys." << std::endl;
return ;
}
if(!mOwnIdsLoaded)
{
std::cerr << "(EE) Own ids not loaded. Cannot clean unused keys." << std::endl;
return ;
}
// grab at most 10 identities to delete. No need to send too many requests to the token queue at once.
time_t now = time(NULL) ;
int n=0 ;
// grab at most 10 identities to delete. No need to send too many requests to the token queue at once.
time_t now = time(NULL) ;
int n=0 ;
IdCacheEntryCleaner idcec(mKeysTS) ;
for(std::map<RsGxsId,time_t>::iterator it(mKeysTS.begin());it!=mKeysTS.end() && n < 10;++it)
{
if(it->second + MAX_KEEP_UNUSED_KEYS < now && std::find(mOwnIds.begin(),mOwnIds.end(),it->first) == mOwnIds.end())
ids_to_delete.push_back(it->first),++n ;
else if(it->second + MAX_KEEP_BANNED_KEYS < now && rsReputations->isIdentityBanned(it->first))
ids_to_delete.push_back(it->first),++n ;
}
}
mKeyCache.applyToAllCachedEntries(idcec,&IdCacheEntryCleaner::processEntry);
ids_to_delete = idcec.ids_to_delete ;
}
std::cerr << "Collected " << ids_to_delete.size() << " keys to delete among " << mKeyCache.size() << std::endl;
for(std::list<RsGxsId>::const_iterator it(ids_to_delete.begin());it!=ids_to_delete.end();++it)
{
std::cerr << "Deleting identity " << *it << " which is too old." << std::endl;
uint32_t token ;
RsGxsIdGroup group;
group.mMeta.mGroupId=RsGxsGroupId(*it);
rsIdentity->deleteIdentity(token, group);
for(std::list<RsGxsId>::const_iterator it(ids_to_delete.begin());it!=ids_to_delete.end();++it)
{
std::cerr << "Deleting identity " << *it << " which is too old." << std::endl;
uint32_t token ;
RsGxsIdGroup group;
group.mMeta.mGroupId=RsGxsGroupId(*it);
rsIdentity->deleteIdentity(token, group);
{
RS_STACK_MUTEX(mIdMtx) ;
std::map<RsGxsId,time_t>::iterator tmp = mKeysTS.find(*it) ;
{
RS_STACK_MUTEX(mIdMtx) ;
std::map<RsGxsId,time_t>::iterator tmp = mKeysTS.find(*it) ;
if(mKeysTS.end() != tmp)
mKeysTS.erase(tmp) ;
}
}
if(mKeysTS.end() != tmp)
mKeysTS.erase(tmp) ;
// mPublicKeyCache.erase(*it) ; no need to do it now. It's done in p3IdService::deleteGroup()
}
}
}
void p3IdService::service_tick()
@ -454,9 +529,6 @@ bool p3IdService:: getIdDetails(const RsGxsId &id, RsIdentityDetails &details)
details = data.details;
details.mLastUsageTS = locked_getLastUsageTS(id) ;
if(mContacts.find(id) != mContacts.end())
details.mFlags |= RS_IDENTITY_FLAGS_IS_A_CONTACT ;
// one utf8 symbol can be at most 4 bytes long - would be better to measure real unicode length !!!
if(details.mNickname.length() > RSID_MAXIMUM_NICKNAME_SIZE*4)
details.mNickname = "[too long a name]" ;
@ -1914,6 +1986,9 @@ bool p3IdService::cache_store(const RsGxsIdGroupItem *item)
// Create Cache Data.
RsGxsIdCache keycache(item, pubkey, fullkey,tagList);
if(mContacts.find(id) != mContacts.end())
keycache.details.mFlags |= RS_IDENTITY_FLAGS_IS_A_CONTACT;
mKeyCache.store(id, keycache);
mKeyCache.resize();

View file

@ -381,14 +381,14 @@ bool upnphandler::start_upnp()
if (!SetRedirectAndTest(&(config -> urls), &(config->data),
in_addr, in_port1, eport1, eprot1,
NULL /*leaseDuration*/, NULL /*description*/,
NULL /*leaseDuration*/, "RetroShare_TCP" /*description*/,
0))
{
upnpState = RS_UPNP_S_TCP_FAILED;
}
else if (!SetRedirectAndTest(&(config -> urls), &(config->data),
in_addr, in_port2, eport2, eprot2,
NULL /*leaseDuration*/, NULL /*description*/,
NULL /*leaseDuration*/, "RetroShare_UDP" /*description*/,
0))
{
upnpState = RS_UPNP_S_UDP_FAILED;

View file

@ -298,7 +298,7 @@ int SetRedirectAndTest(struct UPNPUrls * urls,
// const char * remoteHost,
// const char * leaseDuration);
r = UPNP_AddPortMapping(urls->controlURL, servicetype,
eport, iport, iaddr, NULL, proto, NULL, NULL);
eport, iport, iaddr, description, proto, NULL, NULL);
#else
#if MINIUPNPC_API_VERSION >= -3 //1.0 2009/04/17
/* $Id: upnpcommands.h,v 1.18 2010/06/09 10:59:09 nanard Exp $ */
@ -311,7 +311,7 @@ int SetRedirectAndTest(struct UPNPUrls * urls,
// const char * proto,
// const char * remoteHost);
r = UPNP_AddPortMapping(urls->controlURL, servicetype,
eport, iport, iaddr, NULL, proto, NULL);
eport, iport, iaddr, description, proto, NULL);
#else
#if MINIUPNPC_API_VERSION >= -7//Before 1.0
/* $Id: upnpcommands.h,v 1.14 2008/09/25 18:02:50 nanard Exp $ */
@ -323,7 +323,7 @@ int SetRedirectAndTest(struct UPNPUrls * urls,
// const char * desc,
// const char * proto);
r = UPNP_AddPortMapping(urls->controlURL, servicetype,
eport, iport, iaddr, NULL, proto);
eport, iport, iaddr, description, proto);
#else
#error MINIUPNPC_API_VERSION is not defined. You may define one follow miniupnpc library version
#endif//>=-7

View file

@ -73,6 +73,7 @@ public:
template<class ClientClass> bool applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(Value&));
uint32_t size() const { return mDataMap.size() ; }
private:
bool update_lrumap(const Key &key, time_t old_ts, time_t new_ts);

View file

@ -279,11 +279,22 @@ void *SmallObject::operator new(size_t size)
#endif
RsStackMutex m(_mtx) ;
void *p = _allocator.allocate(size) ;
// This should normally not happen. But that prevents a crash when quitting, since we cannot prevent the constructor
// of an object to call operator new(), nor to handle the case where it returns NULL.
// The memory will therefore not be deleted if that happens. We thus print a warning.
if(_allocator._active)
return _allocator.allocate(size) ;
else
{
std::cerr << "(EE) allocating " << size << " bytes of memory that cannot be deleted. This is a bug, except if it happens when closing Retroshare" << std::endl;
return malloc(size) ;
}
#ifdef DEBUG_MEMORY
std::cerr << "new RsItem: " << p << ", size=" << size << std::endl;
#endif
return p ;
}
void SmallObject::operator delete(void *p,size_t size)

View file

@ -3,6 +3,12 @@
#don't exit even if a command fails
set +e
SCRIPT_PATH=$(dirname "`readlink -f "${0}"`")
OLDLANG=${LANG}
export LANG=C
if ( git log -n 1 &> /dev/null); then
#retrieve git information
version="$(git log --pretty=format:"%H" | head -1 | cut -c1-8)"
@ -22,7 +28,9 @@ fi
if [[ ${version} != '' ]]; then
echo "Writing version to retroshare/rsversion.h : ${version}"
sed -e "s%RS_REVISION_NUMBER.*%RS_REVISION_NUMBER 0x${version}%" retroshare/rsversion.in >retroshare/rsversion.h
sed -e "s%RS_REVISION_NUMBER.*%RS_REVISION_NUMBER 0x${version}%" ${SCRIPT_PATH}/retroshare/rsversion.in >${SCRIPT_PATH}/retroshare/rsversion.h
fi
export LANG=${OLDLANG}
echo "script version_detail.sh finished normally"
exit 0