merged upstream/master

This commit is contained in:
csoler 2018-03-15 09:19:56 +01:00
commit 04dc764339
No known key found for this signature in database
GPG key ID: 7BCA522266C0804C
329 changed files with 129212 additions and 86062 deletions

View file

@ -1403,13 +1403,34 @@ bool DistributedChatService::acceptLobbyInvite(const ChatLobbyId& lobby_id,const
return false;
}
//std::map<ChatLobbyId,VisibleChatLobbyRecord>::const_iterator vid = _visible_lobbies.find(lobby_id) ;
//When invited to new Lobby, it is not visible.
//if(_visible_lobbies.end() == vid)
//{
// std::cerr << " (EE) Cannot subscribe a non visible chat lobby!!" << std::endl;
// return false ;
//}
RsIdentityDetails det ;
if( (!rsIdentity->getIdDetails(identity,det)) || !(det.mFlags & RS_IDENTITY_FLAGS_IS_OWN_ID))
{
std::cerr << " (EE) Cannot subscribe with identity " << identity << " because it is not ours! Something's wrong here." << std::endl;
return false ;
}
if( (it->second.lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED ) && !(det.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED))
{
std::cerr << " (EE) Cannot subscribe with identity " << identity << " because it is unsigned and the lobby requires signed ids only." << std::endl;
return false ;
}
if(_chat_lobbys.find(lobby_id) != _chat_lobbys.end())
{
std::cerr << " (II) Lobby already exists. Weird." << std::endl;
return true ;
}
#ifdef DEBUG_CHAT_LOBBIES
std::cerr << " Creating new Lobby entry." << std::endl;
#endif
@ -1417,8 +1438,8 @@ bool DistributedChatService::acceptLobbyInvite(const ChatLobbyId& lobby_id,const
ChatLobbyEntry entry ;
entry.participating_friends.insert(it->second.peer_id) ;
entry.lobby_flags = it->second.lobby_flags ;
entry.gxs_id = identity ;
entry.lobby_flags = it->second.lobby_flags ;
entry.gxs_id = identity ;
entry.lobby_id = lobby_id ;
entry.lobby_name = it->second.lobby_name ;
entry.lobby_topic = it->second.lobby_topic ;
@ -1491,11 +1512,12 @@ void DistributedChatService::denyLobbyInvite(const ChatLobbyId& lobby_id)
bool DistributedChatService::joinVisibleChatLobby(const ChatLobbyId& lobby_id,const RsGxsId& gxs_id)
{
if(!mGixs->isOwnId(gxs_id))
{
std::cerr << "(EE) Cannot lobby using gxs id " << gxs_id << std::endl;
return false ;
}
RsIdentityDetails det ;
if( (!rsIdentity->getIdDetails(gxs_id,det)) || !(det.mFlags & RS_IDENTITY_FLAGS_IS_OWN_ID))
{
std::cerr << " (EE) Cannot subscribe with identity " << gxs_id << " because it is not ours! Something's wrong here." << std::endl;
return false ;
}
#ifdef DEBUG_CHAT_LOBBIES
std::cerr << "Joining public chat lobby " << std::hex << lobby_id << std::dec << std::endl;
@ -1527,6 +1549,12 @@ bool DistributedChatService::joinVisibleChatLobby(const ChatLobbyId& lobby_id,co
return true ;
}
if( (it->second.lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED ) && !(det.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED))
{
std::cerr << " (EE) Cannot subscribe with identity " << gxs_id << " because it is unsigned and the lobby requires signed ids only." << std::endl;
return false ;
}
#ifdef DEBUG_CHAT_LOBBIES
std::cerr << " Creating new lobby entry." << std::endl;
#endif

View file

@ -38,7 +38,7 @@
#include "crypto/chacha20.h"
#include "util/rsprint.h"
#include "util/rsrandom.h"
#include "util/rsscopetimer.h"
#include "util/rstime.h"
#define rotl(x,n) { x = (x << n) | (x >> (-n & 31)) ;}
@ -1385,27 +1385,27 @@ bool perform_tests()
uint8_t received_tag[16] ;
{
RsScopeTimer s("AEAD1") ;
rstime::RsScopeTimer s("AEAD1") ;
chacha20_encrypt_rs(key, 1, nonce, ten_megabyte_data,SIZE) ;
std::cerr << " Chacha20 encryption speed : " << SIZE / (1024.0*1024.0) / s.duration() << " MB/s" << std::endl;
}
{
RsScopeTimer s("AEAD2") ;
rstime::RsScopeTimer s("AEAD2") ;
AEAD_chacha20_poly1305_rs(key,nonce,ten_megabyte_data,SIZE,aad,12,received_tag,true) ;
std::cerr << " AEAD/poly1305 own encryption speed : " << SIZE / (1024.0*1024.0) / s.duration() << " MB/s" << std::endl;
}
#if OPENSSL_VERSION_NUMBER >= 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER)
{
RsScopeTimer s("AEAD3") ;
rstime::RsScopeTimer s("AEAD3") ;
AEAD_chacha20_poly1305_openssl(key,nonce,ten_megabyte_data,SIZE,aad,12,received_tag,true) ;
std::cerr << " AEAD/poly1305 openssl encryption speed: " << SIZE / (1024.0*1024.0) / s.duration() << " MB/s" << std::endl;
}
#endif
{
RsScopeTimer s("AEAD4") ;
rstime::RsScopeTimer s("AEAD4") ;
AEAD_chacha20_sha256(key,nonce,ten_megabyte_data,SIZE,aad,12,received_tag,true) ;
std::cerr << " AEAD/sha256 encryption speed : " << SIZE / (1024.0*1024.0) / s.duration() << " MB/s" << std::endl;

View file

@ -23,6 +23,7 @@
*
*/
#include "util/folderiterator.h"
#include "util/rstime.h"
#include "rsserver/p3face.h"
#include "directory_storage.h"
@ -92,7 +93,7 @@ void LocalDirectoryUpdater::data_tick()
for(uint32_t i=0;i<10;++i)
{
usleep(1*1000*1000);
rstime::rs_usleep(1*1000*1000);
{
if(mForceUpdate)

View file

@ -24,7 +24,7 @@
*/
#include "util/rsdir.h"
#include "util/rsprint.h"
#include "util/rsscopetimer.h"
#include "util/rstime.h"
#include "rsserver/p3face.h"
#include "pqi/authssl.h"
#include "hash_cache.h"
@ -125,7 +125,7 @@ void HashStorage::data_tick()
std::cerr << "nothing to hash. Sleeping for " << st << " us" << std::endl;
#endif
usleep(st); // when no files to hash, just wait for 2 secs. This avoids a dramatic loop.
rstime::rs_usleep(st); // when no files to hash, just wait for 2 secs. This avoids a dramatic loop.
if(st > MAX_INACTIVITY_SLEEP_TIME)
{
@ -163,7 +163,7 @@ void HashStorage::data_tick()
if(paused) // we need to wait off mutex!!
{
usleep(MAX_INACTIVITY_SLEEP_TIME) ;
rstime::rs_usleep(MAX_INACTIVITY_SLEEP_TIME) ;
std::cerr << "Hashing process currently paused." << std::endl;
return;
}
@ -190,7 +190,7 @@ void HashStorage::data_tick()
RsServer::notify()->notifyHashingInfo(NOTIFY_HASHTYPE_HASH_FILE, tmpout) ;
double seconds_origin = RsScopeTimer::currentTime() ;
double seconds_origin = rstime::RsScopeTimer::currentTime() ;
if(RsDirUtil::getFileHash(job.full_path, hash,size, this))
{
@ -215,7 +215,7 @@ void HashStorage::data_tick()
else
std::cerr << "ERROR: cannot hash file " << job.full_path << std::endl;
mHashingTime += RsScopeTimer::currentTime() - seconds_origin ;
mHashingTime += rstime::RsScopeTimer::currentTime() - seconds_origin ;
mHashedBytes += size ;
if(mHashingTime > 3)

View file

@ -1155,6 +1155,8 @@ int p3FileDatabase::SearchKeywords(const std::list<std::string>& keywords, std::
if(flags & RS_FILE_HINTS_LOCAL)
{
std::list<EntryIndex> firesults;
std::list<void *> pointers;
{
RS_STACK_MUTEX(mFLSMtx) ;
@ -1164,16 +1166,16 @@ int p3FileDatabase::SearchKeywords(const std::list<std::string>& keywords, std::
{
void *p=NULL;
convertEntryIndexToPointer<sizeof(void*)>(*it,0,p);
*it = (intptr_t)p ;
pointers.push_back(p) ;
}
}
filterResults(firesults,results,flags,client_peer_id) ;
filterResults(pointers,results,flags,client_peer_id) ;
}
if(flags & RS_FILE_HINTS_REMOTE)
{
std::list<EntryIndex> firesults;
std::list<void*> pointers ;
{
RS_STACK_MUTEX(mFLSMtx) ;
@ -1188,21 +1190,21 @@ int p3FileDatabase::SearchKeywords(const std::list<std::string>& keywords, std::
{
void *p=NULL;
convertEntryIndexToPointer<sizeof(void*)>(*it,i+1,p);
firesults.push_back((intptr_t)p) ;
}
pointers.push_back(p) ;
}
}
}
for(std::list<EntryIndex>::const_iterator rit ( firesults.begin()); rit != firesults.end(); ++rit)
{
DirDetails dd;
for(auto it(pointers.begin());it!=pointers.end();++it)
{
DirDetails dd;
if(!RequestDirDetails ((void*)(intptr_t)*rit,dd,RS_FILE_HINTS_REMOTE))
continue ;
results.push_back(dd);
}
if(!RequestDirDetails (*it,dd,RS_FILE_HINTS_REMOTE))
continue ;
results.push_back(dd);
}
}
return !results.empty() ;
@ -1213,6 +1215,7 @@ int p3FileDatabase::SearchBoolExp(RsRegularExpression::Expression *exp, std::lis
if(flags & RS_FILE_HINTS_LOCAL)
{
std::list<EntryIndex> firesults;
std::list<void*> pointers;
{
RS_STACK_MUTEX(mFLSMtx) ;
@ -1222,17 +1225,16 @@ int p3FileDatabase::SearchBoolExp(RsRegularExpression::Expression *exp, std::lis
{
void *p=NULL;
convertEntryIndexToPointer<sizeof(void*)>(*it,0,p);
*it = (intptr_t)p ;
pointers.push_back(p);
}
}
filterResults(firesults,results,flags,client_peer_id) ;
filterResults(pointers,results,flags,client_peer_id) ;
}
if(flags & RS_FILE_HINTS_REMOTE)
{
std::list<EntryIndex> firesults;
std::list<void*> pointers ;
{
RS_STACK_MUTEX(mFLSMtx) ;
@ -1246,21 +1248,20 @@ int p3FileDatabase::SearchBoolExp(RsRegularExpression::Expression *exp, std::lis
{
void *p=NULL;
convertEntryIndexToPointer<sizeof(void*)>(*it,i+1,p);
firesults.push_back((intptr_t)p) ;
}
pointers.push_back(p) ;
}
}
}
for(std::list<EntryIndex>::const_iterator rit ( firesults.begin()); rit != firesults.end(); ++rit)
{
DirDetails dd;
for(auto it(pointers.begin());it!=pointers.end();++it)
{
DirDetails dd;
if(!RequestDirDetails ((void*)(intptr_t)*rit,dd,RS_FILE_HINTS_REMOTE))
continue ;
if(!RequestDirDetails (*it,dd,RS_FILE_HINTS_REMOTE))
continue ;
results.push_back(dd);
}
results.push_back(dd);
}
}
return !results.empty() ;
@ -1312,7 +1313,7 @@ bool p3FileDatabase::search(const RsFileHash &hash, FileSearchFlags hintflags, F
return false;
}
int p3FileDatabase::filterResults(const std::list<EntryIndex>& firesults,std::list<DirDetails>& results,FileSearchFlags flags,const RsPeerId& peer_id) const
int p3FileDatabase::filterResults(const std::list<void*>& firesults,std::list<DirDetails>& results,FileSearchFlags flags,const RsPeerId& peer_id) const
{
results.clear();
@ -1320,17 +1321,17 @@ int p3FileDatabase::filterResults(const std::list<EntryIndex>& firesults,std::li
/* translate/filter results */
for(std::list<EntryIndex>::const_iterator rit(firesults.begin()); rit != firesults.end(); ++rit)
for(std::list<void*>::const_iterator rit(firesults.begin()); rit != firesults.end(); ++rit)
{
DirDetails cdetails ;
if(!RequestDirDetails ((void*)(intptr_t)*rit,cdetails,RS_FILE_HINTS_LOCAL))
if(!RequestDirDetails (*rit,cdetails,RS_FILE_HINTS_LOCAL))
{
P3FILELISTS_ERROR() << "(EE) Cannot get dir details for entry " << (void*)(intptr_t)*rit << std::endl;
P3FILELISTS_ERROR() << "(EE) Cannot get dir details for entry " << *rit << std::endl;
continue ;
}
#ifdef DEBUG_P3FILELISTS
P3FILELISTS_DEBUG() << "Filtering candidate " << (void*)(intptr_t)(*rit) << ", flags=" << cdetails.flags << ", peer=" << peer_id ;
P3FILELISTS_DEBUG() << "Filtering candidate " << *rit << ", flags=" << cdetails.flags << ", peer=" << peer_id ;
#endif
if(!peer_id.isNull())

View file

@ -159,7 +159,7 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub
protected:
int filterResults(const std::list<EntryIndex>& firesults,std::list<DirDetails>& results,FileSearchFlags flags,const RsPeerId& peer_id) const;
int filterResults(const std::list<void*>& firesults,std::list<DirDetails>& results,FileSearchFlags flags,const RsPeerId& peer_id) const;
std::string makeRemoteFileName(const RsPeerId& pid) const;
// Derived from p3Config

View file

@ -40,6 +40,7 @@
#endif
#include "util/rsdiscspace.h"
#include "util/rsmemory.h"
#include "util/rstime.h"
#include "ft/ftcontroller.h"
@ -219,7 +220,7 @@ void ftController::data_tick()
/* check the queues */
//Waiting 1 sec before start
usleep(1*1000*1000); // 1 sec
rstime::rs_usleep(1*1000*1000); // 1 sec
#ifdef CONTROL_DEBUG
//std::cerr << "ftController::run()";
@ -301,7 +302,7 @@ void ftController::searchForDirectSources()
FileInfo info ; // Info needs to be re-allocated each time, to start with a clear list of peers (it's not cleared down there)
if( mSearch->search(it->first, RS_FILE_HINTS_REMOTE | RS_FILE_HINTS_SPEC_ONLY, info) )
for( std::list<TransferInfo>::const_iterator pit = info.peers.begin(); pit != info.peers.end(); ++pit )
for( std::vector<TransferInfo>::const_iterator pit = info.peers.begin(); pit != info.peers.end(); ++pit )
{
bool bAllowDirectDL = false;
switch (mFilePermDirectDLPolicy) {
@ -734,13 +735,39 @@ bool ftController::completeFile(const RsFileHash& hash)
fc->mState = ftFileControl::COMPLETED;
std::string dst_dir,src_dir,src_file,dst_file ;
RsDirUtil::splitDirFromFile(fc->mCurrentPath,src_dir,src_file) ;
RsDirUtil::splitDirFromFile(fc->mDestination,dst_dir,dst_file) ;
// We use this intermediate file in case the destination directory is not available, so as to not keep the partial file name.
std::string intermediate_file_name = src_dir+'/'+dst_file ;
// I don't know how the size can be zero, but believe me, this happens,
// and it causes an error on linux because then the file may not even exist.
//
if( fc->mSize > 0 && RsDirUtil::moveFile(fc->mCurrentPath,fc->mDestination) )
fc->mCurrentPath = fc->mDestination;
else
if( fc->mSize == 0)
fc->mState = ftFileControl::ERROR_COMPLETION;
else
{
std::cerr << "CompleteFile(): renaming " << fc->mCurrentPath << " into " << fc->mDestination << std::endl;
std::cerr << "CompleteFile(): 1 - renaming " << fc->mCurrentPath << " info " << intermediate_file_name << std::endl;
if(RsDirUtil::moveFile(fc->mCurrentPath,intermediate_file_name) )
{
fc->mCurrentPath = intermediate_file_name ;
std::cerr << "CompleteFile(): 2 - renaming/copying " << intermediate_file_name << " into " << fc->mDestination << std::endl;
if(RsDirUtil::moveFile(intermediate_file_name,fc->mDestination) )
fc->mCurrentPath = fc->mDestination;
else
fc->mState = ftFileControl::ERROR_COMPLETION;
}
else
fc->mState = ftFileControl::ERROR_COMPLETION;
}
/* for extralist additions */
path = fc->mDestination;
@ -1003,7 +1030,7 @@ bool ftController::FileRequest(const std::string& fname, const RsFileHash& hash
}
std::list<RsPeerId>::const_iterator it;
std::list<TransferInfo>::const_iterator pit;
std::vector<TransferInfo>::const_iterator pit;
#ifdef CONTROL_DEBUG
std::cerr << "ftController::FileRequest(" << fname << ",";
@ -1596,6 +1623,8 @@ bool ftController::FileDetails(const RsFileHash &hash, FileInfo &info)
bool isDownloading = false;
bool isSuspended = false;
info.peers.clear();
for(pit = peerIds.begin(); pit != peerIds.end(); ++pit)
{
if (it->second->mTransfer->getPeerState(*pit, state, tfRate))

View file

@ -32,6 +32,7 @@
#include "ft/ftextralist.h"
#include "rsitems/rsconfigitems.h"
#include "util/rsdir.h"
#include "util/rstime.h"
#include <stdio.h>
#include <unistd.h> /* for (u)sleep() */
#include <time.h>
@ -64,12 +65,8 @@ void ftExtraList::data_tick()
/* Hash a file */
hashAFile();
#ifdef WIN32
Sleep(1);
#else
/* microsleep */
usleep(10);
#endif
rstime::rs_usleep(10);
}
else
{
@ -513,16 +510,7 @@ bool ftExtraList::loadList(std::list<RsItem *>& load)
delete (*it);
/* short sleep */
#ifndef WINDOWS_SYS
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
usleep(1000); /* 1000 per second */
#else
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
Sleep(1);
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
rstime::rs_usleep(1000) ;
}
load.clear() ;
return true;

View file

@ -35,10 +35,11 @@
#include <algorithm>
#ifdef RS_DATA_SERVICE_DEBUG_TIME
#include <util/rsscopetimer.h>
#include <util/rstime.h>
#endif
#include "rsdataservice.h"
#include "retroshare/rsgxsflags.h"
#include "util/rsstring.h"
#define MSG_TABLE_NAME std::string("MESSAGES")
@ -113,6 +114,8 @@ const std::string RsGeneralDataService::MSG_META_STATUS = KEY_MSG_STATUS;
const uint32_t RsGeneralDataService::GXS_MAX_ITEM_SIZE = 1572864; // 1.5 Mbytes
static const uint32_t CACHE_ENTRY_GRACE_PERIOD = 600 ; // 10 minutes
static int addColumn(std::list<std::string> &list, const std::string &attribute)
{
list.push_back(attribute);
@ -486,15 +489,13 @@ bool RsDataService::finishReleaseUpdate(int release, bool result)
return result;
}
RsGxsGrpMetaData* RsDataService::locked_getGrpMeta(RetroCursor &c, int colOffset)
RsGxsGrpMetaData* RsDataService::locked_getGrpMeta(RetroCursor &c, int colOffset,bool use_cache)
{
#ifdef RS_DATA_SERVICE_DEBUG
std::cerr << "RsDataService::locked_getGrpMeta()";
std::cerr << std::endl;
#endif
RsGxsGrpMetaData* grpMeta = new RsGxsGrpMetaData();
bool ok = true;
// for extracting raw data
@ -505,6 +506,25 @@ RsGxsGrpMetaData* RsDataService::locked_getGrpMeta(RetroCursor &c, int colOffset
// grpId
std::string tempId;
c.getString(mColGrpMeta_GrpId + colOffset, tempId);
RsGxsGrpMetaData* grpMeta ;
RsGxsGroupId grpId(tempId) ;
if(use_cache)
{
auto it = mGrpMetaDataCache.find(grpId) ;
if(it != mGrpMetaDataCache.end())
grpMeta = it->second ;
else
{
grpMeta = new RsGxsGrpMetaData();
mGrpMetaDataCache[grpId] = grpMeta ;
}
}
else
grpMeta = new RsGxsGrpMetaData();
grpMeta->mGroupId = RsGxsGroupId(tempId);
c.getString(mColGrpMeta_NxsIdentity + colOffset, tempId);
grpMeta->mAuthorId = RsGxsId(tempId);
@ -553,12 +573,46 @@ RsGxsGrpMetaData* RsDataService::locked_getGrpMeta(RetroCursor &c, int colOffset
c.getString(mColGrpMeta_ParentGrpId, tempId);
grpMeta->mParentGrpId = RsGxsGroupId(tempId);
// make sure that flags and keys are actually consistent
bool have_private_admin_key = false ;
bool have_private_publish_key = false ;
for(auto mit = grpMeta->keys.private_keys.begin(); mit != grpMeta->keys.private_keys.end();++mit)
{
if(mit->second.keyFlags == (RSTLV_KEY_DISTRIB_PUBLISH | RSTLV_KEY_TYPE_FULL)) have_private_publish_key = true ;
if(mit->second.keyFlags == (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL)) have_private_admin_key = true ;
}
if(have_private_admin_key && !(grpMeta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN))
{
std::cerr << "(WW) inconsistency in group " << grpMeta->mGroupId << ": group does not have flag ADMIN but an admin key was found. Updating the flags." << std::endl;
grpMeta->mSubscribeFlags |= GXS_SERV::GROUP_SUBSCRIBE_ADMIN;
}
if(!have_private_admin_key && (grpMeta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN))
{
std::cerr << "(WW) inconsistency in group " << grpMeta->mGroupId << ": group has flag ADMIN but no admin key found. Updating the flags." << std::endl;
grpMeta->mSubscribeFlags &= ~GXS_SERV::GROUP_SUBSCRIBE_ADMIN;
}
if(have_private_publish_key && !(grpMeta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_PUBLISH))
{
std::cerr << "(WW) inconsistency in group " << grpMeta->mGroupId << ": group does not have flag PUBLISH but an admin key was found. Updating the flags." << std::endl;
grpMeta->mSubscribeFlags |= GXS_SERV::GROUP_SUBSCRIBE_PUBLISH;
}
if(!have_private_publish_key && (grpMeta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_PUBLISH))
{
std::cerr << "(WW) inconsistency in group " << grpMeta->mGroupId << ": group has flag PUBLISH but no admin key found. Updating the flags." << std::endl;
grpMeta->mSubscribeFlags &= ~GXS_SERV::GROUP_SUBSCRIBE_PUBLISH;
}
if(ok)
return grpMeta;
else
delete grpMeta;
return NULL;
{
if(!use_cache)
delete grpMeta;
return NULL;
}
}
RsNxsGrp* RsDataService::locked_getGroup(RetroCursor &c)
@ -876,7 +930,7 @@ int RsDataService::storeGroup(const std::list<RsNxsGrp*>& grp)
cv.put(KEY_GRP_STATUS, (int32_t)grpMetaPtr->mGroupStatus);
cv.put(KEY_GRP_LAST_POST, (int32_t)grpMetaPtr->mLastPost);
locked_clearGrpMetaCache(grpMetaPtr->mGroupId);
locked_updateGrpMetaCache(*grpMetaPtr);
if (!mDb->sqlInsert(GRP_TABLE_NAME, "", cv))
{
@ -892,10 +946,50 @@ int RsDataService::storeGroup(const std::list<RsNxsGrp*>& grp)
return ret;
}
void RsDataService::locked_updateGrpMetaCache(const RsGxsGrpMetaData& meta)
{
auto it = mGrpMetaDataCache.find(meta.mGroupId) ;
if(it != mGrpMetaDataCache.end())
*(it->second) = meta ;
}
void RsDataService::locked_clearGrpMetaCache(const RsGxsGroupId& gid)
{
mGrpMetaDataCache.erase(gid) ; // cleans existing cache entry
mGrpMetaDataCache_ContainsAllDatabase = false;
time_t now = time(NULL) ;
auto it = mGrpMetaDataCache.find(gid) ;
// We dont actually delete the item, because it might be used by a calling client.
// In this case, the memory will not be used for long, so we keep it into a list for a safe amount
// of time and delete it later. Using smart pointers here would be more elegant, but that would need
// to be implemented thread safe, which is difficult in this case.
if(it != mGrpMetaDataCache.end())
{
#ifdef RS_DATA_SERVICE_DEBUG
std::cerr << "(II) moving database cache entry " << (void*)(*it).second << " to dead list." << std::endl;
#endif
mOldCachedItems.push_back(std::make_pair(now,it->second)) ;
mGrpMetaDataCache.erase(it) ;
mGrpMetaDataCache_ContainsAllDatabase = false;
}
// We also take that opportunity to delete old entries.
auto it2(mOldCachedItems.begin());
while(it2!=mOldCachedItems.end() && (*it2).first + CACHE_ENTRY_GRACE_PERIOD < now)
{
#ifdef RS_DATA_SERVICE_DEBUG
std::cerr << "(II) deleting old GXS database cache entry " << (void*)(*it2).second << ", " << now - (*it2).first << " seconds old." << std::endl;
#endif
delete (*it2).second ;
it2 = mOldCachedItems.erase(it2) ;
}
}
int RsDataService::updateGroup(const std::list<RsNxsGrp *> &grp)
@ -966,7 +1060,7 @@ int RsDataService::updateGroup(const std::list<RsNxsGrp *> &grp)
mDb->sqlUpdate(GRP_TABLE_NAME, "grpId='" + grpPtr->grpId.toStdString() + "'", cv);
locked_clearGrpMetaCache(grpMetaPtr->mGroupId);
locked_updateGrpMetaCache(*grpMetaPtr);
}
// finish transaction
bool ret = mDb->commitTransaction();
@ -1009,7 +1103,7 @@ bool RsDataService::validSize(RsNxsGrp* grp) const
int RsDataService::retrieveNxsGrps(std::map<RsGxsGroupId, RsNxsGrp *> &grp, bool withMeta, bool /* cache */)
{
#ifdef RS_DATA_SERVICE_DEBUG_TIME
RsScopeTimer timer("");
rstime::RsScopeTimer timer("");
int resultCount = 0;
int requestedGroups = grp.size();
#endif
@ -1097,7 +1191,7 @@ void RsDataService::locked_retrieveGroups(RetroCursor* c, std::vector<RsNxsGrp*>
if(g)
{
if (metaOffset) {
g->metaData = locked_getGrpMeta(*c, metaOffset);
g->metaData = locked_getGrpMeta(*c, metaOffset,false);
}
grps.push_back(g);
}
@ -1109,7 +1203,7 @@ void RsDataService::locked_retrieveGroups(RetroCursor* c, std::vector<RsNxsGrp*>
int RsDataService::retrieveNxsMsgs(const GxsMsgReq &reqIds, GxsMsgResult &msg, bool /* cache */, bool withMeta)
{
#ifdef RS_DATA_SERVICE_DEBUG_TIME
RsScopeTimer timer("");
rstime::RsScopeTimer timer("");
int resultCount = 0;
#endif
@ -1197,7 +1291,7 @@ int RsDataService::retrieveGxsMsgMetaData(const GxsMsgReq& reqIds, GxsMsgMetaRes
RsStackMutex stack(mDbMutex);
#ifdef RS_DATA_SERVICE_DEBUG_TIME
RsScopeTimer timer("");
rstime::RsScopeTimer timer("");
int resultCount = 0;
#endif
@ -1274,7 +1368,7 @@ void RsDataService::locked_retrieveMsgMeta(RetroCursor *c, std::vector<RsGxsMsgM
}
}
int RsDataService::retrieveGxsGrpMetaData(std::map<RsGxsGroupId, RsGxsGrpMetaData *>& grp)
int RsDataService::retrieveGxsGrpMetaData(RsGxsGrpMetaTemporaryMap& grp)
{
#ifdef RS_DATA_SERVICE_DEBUG
std::cerr << "RsDataService::retrieveGxsGrpMetaData()";
@ -1284,7 +1378,7 @@ int RsDataService::retrieveGxsGrpMetaData(std::map<RsGxsGroupId, RsGxsGrpMetaDat
RsStackMutex stack(mDbMutex);
#ifdef RS_DATA_SERVICE_DEBUG_TIME
RsScopeTimer timer("");
rstime::RsScopeTimer timer("");
int resultCount = 0;
int requestedGroups = grp.size();
#endif
@ -1297,100 +1391,101 @@ int RsDataService::retrieveGxsGrpMetaData(std::map<RsGxsGroupId, RsGxsGrpMetaDat
std::cerr << (void*)this << ": RsDataService::retrieveGxsGrpMetaData() retrieving all from cache!" << std::endl;
#endif
for(std::map<RsGxsGroupId,RsGxsGrpMetaData>::const_iterator it(mGrpMetaDataCache.begin());it!=mGrpMetaDataCache.end();++it)
grp[it->first] = new RsGxsGrpMetaData(it->second);
grp = mGrpMetaDataCache ;
}
else
{
{
#ifdef RS_DATA_SERVICE_DEBUG
std::cerr << "RsDataService::retrieveGxsGrpMetaData() retrieving all" << std::endl;
std::cerr << "RsDataService::retrieveGxsGrpMetaData() retrieving all" << std::endl;
#endif
// clear the cache
RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, mGrpMetaColumns, "", "");
RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, mGrpMetaColumns, "", "");
if(c)
{
bool valid = c->moveToFirst();
if(c)
{
bool valid = c->moveToFirst();
while(valid)
{
RsGxsGrpMetaData* g = locked_getGrpMeta(*c, 0);
if(g)
{
grp[g->mGroupId] = g;
mGrpMetaDataCache[g->mGroupId] = *g ;
while(valid)
{
RsGxsGrpMetaData* g = locked_getGrpMeta(*c, 0,true);
if(g)
{
grp[g->mGroupId] = g;
#ifdef RS_DATA_SERVICE_DEBUG_CACHE
std::cerr << (void *)this << ": Retrieving (all) Grp metadata grpId=" << g->mGroupId << std::endl;
std::cerr << (void *)this << ": Retrieving (all) Grp metadata grpId=" << g->mGroupId << std::endl;
#endif
}
valid = c->moveToNext();
}
valid = c->moveToNext();
#ifdef RS_DATA_SERVICE_DEBUG_TIME
++resultCount;
++resultCount;
#endif
}
delete c;
}
}
delete c;
}
mGrpMetaDataCache_ContainsAllDatabase = true ;
}
mGrpMetaDataCache_ContainsAllDatabase = true ;
}
}else
else
{
std::map<RsGxsGroupId, RsGxsGrpMetaData *>::iterator mit = grp.begin();
std::map<RsGxsGroupId, RsGxsGrpMetaData *>::iterator mit = grp.begin();
for(; mit != grp.end(); ++mit)
{
std::map<RsGxsGroupId, RsGxsGrpMetaData>::const_iterator itt = mGrpMetaDataCache.find(mit->first) ;
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::const_iterator itt = mGrpMetaDataCache.find(mit->first) ;
if(itt != mGrpMetaDataCache.end())
{
#ifdef RS_DATA_SERVICE_DEBUG_CACHE
std::cerr << "Retrieving Grp metadata grpId=" << mit->first << " from cache!" << std::endl;
#endif
grp[mit->first] = new RsGxsGrpMetaData(itt->second) ;
grp[mit->first] = itt->second ;
}
else
{
{
#ifdef RS_DATA_SERVICE_DEBUG_CACHE
std::cerr << "Retrieving Grp metadata grpId=" << mit->first ;
std::cerr << "Retrieving Grp metadata grpId=" << mit->first ;
#endif
const RsGxsGroupId& grpId = mit->first;
RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, mGrpMetaColumns, "grpId='" + grpId.toStdString() + "'", "");
const RsGxsGroupId& grpId = mit->first;
RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, mGrpMetaColumns, "grpId='" + grpId.toStdString() + "'", "");
if(c)
{
bool valid = c->moveToFirst();
if(c)
{
bool valid = c->moveToFirst();
#ifdef RS_DATA_SERVICE_DEBUG_CACHE
if(!valid)
std::cerr << " Empty query! GrpId " << grpId << " is not in database" << std::endl;
if(!valid)
std::cerr << " Empty query! GrpId " << grpId << " is not in database" << std::endl;
#endif
while(valid)
{
RsGxsGrpMetaData* g = locked_getGrpMeta(*c, 0);
while(valid)
{
RsGxsGrpMetaData* g = locked_getGrpMeta(*c, 0,true);
if(g)
{
grp[g->mGroupId] = g;
mGrpMetaDataCache[g->mGroupId] = *g ;
if(g)
{
grp[g->mGroupId] = g;
#ifdef RS_DATA_SERVICE_DEBUG_CACHE
std::cerr << ". Got it. Updating cache." << std::endl;
std::cerr << ". Got it. Updating cache." << std::endl;
#endif
}
valid = c->moveToNext();
}
valid = c->moveToNext();
#ifdef RS_DATA_SERVICE_DEBUG_TIME
++resultCount;
++resultCount;
#endif
}
delete c;
}
}
delete c;
}
#ifdef RS_DATA_SERVICE_DEBUG_CACHE
else
std::cerr << ". not found!" << std::endl;
else
std::cerr << ". not found!" << std::endl;
#endif
}
}
}
}
@ -1491,7 +1586,7 @@ int RsDataService::retrieveGroupIds(std::vector<RsGxsGroupId> &grpIds)
RsStackMutex stack(mDbMutex);
#ifdef RS_DATA_SERVICE_DEBUG_TIME
RsScopeTimer timer("");
rstime::RsScopeTimer timer("");
int resultCount = 0;
#endif
@ -1528,7 +1623,7 @@ int RsDataService::retrieveGroupIds(std::vector<RsGxsGroupId> &grpIds)
int RsDataService::retrieveMsgIds(const RsGxsGroupId& grpId, RsGxsMessageId::std_vector& msgIds)
{
#ifdef RS_DATA_SERVICE_DEBUG_TIME
RsScopeTimer timer("");
rstime::RsScopeTimer timer("");
int resultCount = 0;
#endif
@ -1607,7 +1702,7 @@ bool RsDataService::locked_removeGroupEntries(const std::vector<RsGxsGroupId>& g
mDb->sqlDelete(GRP_TABLE_NAME, KEY_GRP_ID+ "='" + grpId.toStdString() + "'", "");
// also remove the group meta from cache.
mGrpMetaDataCache.erase(*vit) ;
locked_clearGrpMetaCache(*vit) ;
}
ret &= mDb->commitTransaction();

View file

@ -71,7 +71,7 @@ public:
* @param cache whether to store retrieval in mem for faster later retrieval
* @return error code
*/
int retrieveGxsGrpMetaData(std::map<RsGxsGroupId, RsGxsGrpMetaData*>& grp);
int retrieveGxsGrpMetaData(RsGxsGrpMetaTemporaryMap& grp);
/*!
* Retrieves meta data of all groups stored (most current versions only)
@ -208,7 +208,7 @@ private:
* extracts a grp meta item from a cursor at its
* current position
*/
RsGxsGrpMetaData* locked_getGrpMeta(RetroCursor& c, int colOffset);
RsGxsGrpMetaData* locked_getGrpMeta(RetroCursor& c, int colOffset, bool use_cache);
/*!
* extracts a msg item from a cursor at its
@ -346,8 +346,11 @@ private:
// the entre list of grp metadata is requested (which happens quite often)
void locked_clearGrpMetaCache(const RsGxsGroupId& gid);
void locked_updateGrpMetaCache(const RsGxsGrpMetaData& meta);
std::map<RsGxsGroupId,RsGxsGrpMetaData*> mGrpMetaDataCache ;
std::list<std::pair<time_t,RsGxsGrpMetaData*> > mOldCachedItems ;
std::map<RsGxsGroupId,RsGxsGrpMetaData> mGrpMetaDataCache ;
bool mGrpMetaDataCache_ContainsAllDatabase ;
};

View file

@ -36,9 +36,9 @@
#include "rsitems/rsnxsitems.h"
#include "gxs/rsgxsdata.h"
#include "rsgxs.h"
#include "rsgxsutil.h"
#include "util/contentvalue.h"
class RsGxsSearchModule {
public:
@ -61,6 +61,8 @@ public:
ContentValue val;
};
typedef std::map<RsGxsGroupId,RsGxsGrpMetaData*> RsGxsGrpMetaTemporaryMap;
/*!
* This allows modification of local
* meta data items of a group
@ -168,7 +170,7 @@ public:
* , if grpId is failed to be retrieved it will be erased from map
* @return error code
*/
virtual int retrieveGxsGrpMetaData(std::map<RsGxsGroupId, RsGxsGrpMetaData*>& grp) = 0;
virtual int retrieveGxsGrpMetaData(RsGxsGrpMetaTemporaryMap& grp) = 0;
/*!
* Retrieves meta data of all groups stored (most current versions only)

View file

@ -31,6 +31,7 @@
#include "gxssecurity.h"
#include "util/contentvalue.h"
#include "util/rsprint.h"
#include "util/rstime.h"
#include "retroshare/rsgxsflags.h"
#include "retroshare/rsgxscircles.h"
#include "retroshare/rsgrouter.h"
@ -138,7 +139,7 @@ void RsGenExchange::data_tick()
static const double timeDelta = 0.1; // slow tick in sec
tick();
usleep((int) (timeDelta * 1000 *1000)); // timeDelta sec
rstime::rs_usleep((int) (timeDelta * 1000 *1000)); // timeDelta sec
}
void RsGenExchange::tick()
@ -533,7 +534,7 @@ int RsGenExchange::createGroupSignatures(RsTlvKeySignatureSet& signSet, RsTlvBin
}
int RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinaryData& msgData,
const RsGxsMsgMetaData& msgMeta, RsGxsGrpMetaData& grpMeta)
const RsGxsMsgMetaData& msgMeta, const RsGxsGrpMetaData& grpMeta)
{
bool needPublishSign = false, needIdentitySign = false;
uint32_t grpFlag = grpMeta.mGroupFlags;
@ -714,8 +715,7 @@ int RsGenExchange::createMessage(RsNxsMsg* msg)
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::createMessage() " << std::endl;
#endif
std::map<RsGxsGroupId, RsGxsGrpMetaData*> metaMap;
RsGxsGrpMetaTemporaryMap metaMap ;
metaMap.insert(std::make_pair(id, (RsGxsGrpMetaData*)(NULL)));
mDataStore->retrieveGxsGrpMetaData(metaMap);
@ -730,7 +730,7 @@ int RsGenExchange::createMessage(RsNxsMsg* msg)
else
{
// get publish key
RsGxsGrpMetaData* grpMeta = metaMap[id];
const RsGxsGrpMetaData* grpMeta = metaMap[id];
uint32_t metaDataLen = meta.serial_size();
uint32_t allMsgDataLen = metaDataLen + msg->msg.bin_len;
@ -763,8 +763,6 @@ int RsGenExchange::createMessage(RsNxsMsg* msg)
delete[] metaData;
delete[] allMsgData;
delete grpMeta;
}
if(ret_val == SIGN_FAIL)
@ -1196,14 +1194,14 @@ bool RsGenExchange::getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult
bool RsGenExchange::getGroupMeta(const uint32_t &token, std::list<RsGroupMetaData> &groupInfo)
{
std::list<RsGxsGrpMetaData*> metaL;
std::list<const RsGxsGrpMetaData*> metaL;
bool ok = mDataAccess->getGroupSummary(token, metaL);
RsGroupMetaData m;
for( std::list<RsGxsGrpMetaData*>::iterator lit = metaL.begin(); lit != metaL.end(); ++lit)
for( auto lit = metaL.begin(); lit != metaL.end(); ++lit)
{
RsGxsGrpMetaData& gMeta = *(*lit);
const RsGxsGrpMetaData& gMeta = *(*lit);
m = gMeta;
RsGroupNetworkStats sts ;
@ -1223,7 +1221,6 @@ bool RsGenExchange::getGroupMeta(const uint32_t &token, std::list<RsGroupMetaDat
}
groupInfo.push_back(m);
delete (*lit);
}
return ok;
@ -1646,7 +1643,7 @@ void RsGenExchange::notifyReceivePublishKey(const RsGxsGroupId &grpId)
{
RS_STACK_MUTEX(mGenMtx);
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PUBLISHKEY, false);
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PUBLISHKEY, true);
gc->mGrpIdList.push_back(grpId);
mNotifications.push_back(gc);
}
@ -2080,10 +2077,10 @@ bool RsGenExchange::processGrpMask(const RsGxsGroupId& grpId, ContentValue &grpC
// first find out which mask is involved
int32_t value, mask, currValue;
std::string key;
RsGxsGrpMetaData* grpMeta = NULL;
const RsGxsGrpMetaData* grpMeta = NULL;
bool ok = false;
std::map<RsGxsGroupId, RsGxsGrpMetaData* > grpMetaMap;
RsGxsGrpMetaTemporaryMap grpMetaMap;
std::map<RsGxsGroupId, RsGxsGrpMetaData* >::iterator mit;
grpMetaMap.insert(std::make_pair(grpId, (RsGxsGrpMetaData*)(NULL)));
@ -2092,6 +2089,7 @@ bool RsGenExchange::processGrpMask(const RsGxsGroupId& grpId, ContentValue &grpC
if((mit = grpMetaMap.find(grpId)) != grpMetaMap.end())
{
grpMeta = mit->second;
if (!grpMeta)
{
#ifdef GEN_EXCH_DEBUG
@ -2112,12 +2110,9 @@ bool RsGenExchange::processGrpMask(const RsGxsGroupId& grpId, ContentValue &grpC
{
key = RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG;
currValue = grpMeta->mSubscribeFlags;
}else
{
if(grpMeta)
delete grpMeta;
return !(grpCv.empty());
}
else
return !(grpCv.empty());
ok &= grpCv.getAsInt32(key+GXS_MASK, mask);
@ -2129,9 +2124,6 @@ bool RsGenExchange::processGrpMask(const RsGxsGroupId& grpId, ContentValue &grpC
grpCv.put(key, value);
if(grpMeta)
delete grpMeta;
return ok;
}
@ -2350,7 +2342,7 @@ void RsGenExchange::processGroupUpdatePublish()
// get keys for group update publish
// first build meta request map for groups to be updated
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMeta;
RsGxsGrpMetaTemporaryMap grpMeta;
std::vector<GroupUpdatePublish>::iterator vit = mGroupUpdatePublish.begin();
for(; vit != mGroupUpdatePublish.end(); ++vit)
@ -2360,8 +2352,8 @@ void RsGenExchange::processGroupUpdatePublish()
grpMeta.insert(std::make_pair(groupId, (RsGxsGrpMetaData*)(NULL)));
}
if(grpMeta.empty())
return;
if(grpMeta.empty())
return;
mDataStore->retrieveGxsGrpMetaData(grpMeta);
@ -2373,18 +2365,16 @@ void RsGenExchange::processGroupUpdatePublish()
const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId;
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit = grpMeta.find(groupId);
RsGxsGrpMetaData* meta = NULL;
const RsGxsGrpMetaData* meta = NULL;
if(mit == grpMeta.end() || mit->second == NULL)
{
std::cerr << "Error! could not find meta of old group to update!" << std::endl;
mDataAccess->updatePublicRequestStatus(gup.mToken, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
delete gup.grpItem;
continue;
}else
{
meta = mit->second;
}
else
meta = mit->second;
//gup.grpItem->meta = *meta;
GxsGrpPendingSign ggps(gup.grpItem, gup.mToken);
@ -2402,14 +2392,13 @@ void RsGenExchange::processGroupUpdatePublish()
ggps.mToken = gup.mToken;
mGrpsToPublish.push_back(ggps);
}
else
else
{
std::cerr << "(EE) publish group fails because RS cannot find the private publish and author keys" << std::endl;
delete gup.grpItem;
mDataAccess->updatePublicRequestStatus(gup.mToken, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
}
delete meta;
}
mGroupUpdatePublish.clear();
@ -2591,7 +2580,11 @@ void RsGenExchange::publishGrps()
ggps.mKeys = fullKeySet;
}
else
{
// We should just merge the keys instead of overwriting them, because the update may not contain private parts.
fullKeySet = ggps.mKeys;
}
// find private admin key
RsTlvPrivateRSAKey privAdminKey;
@ -2767,7 +2760,7 @@ void RsGenExchange::publishGrps()
if(!grpChanged.empty())
{
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PUBLISH, false);
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVE, true);
gc->mGrpIdList = grpChanged;
mNotifications.push_back(gc);
#ifdef GEN_EXCH_DEBUG
@ -2781,8 +2774,8 @@ void RsGenExchange::publishGrps()
// This is done off-mutex to avoid possible cross deadlocks with the net service.
if(mNetService!=NULL)
for(std::list<RsGxsGroupId>::const_iterator it(groups_to_subscribe.begin());it!=groups_to_subscribe.end();++it)
mNetService->subscribeStatusChanged((*it),true) ;
for(std::list<RsGxsGroupId>::const_iterator it(groups_to_subscribe.begin());it!=groups_to_subscribe.end();++it)
mNetService->subscribeStatusChanged((*it),true) ;
}
@ -2814,23 +2807,20 @@ bool RsGenExchange::getGroupKeys(const RsGxsGroupId &grpId, RsTlvSecurityKeySet
RS_STACK_MUTEX(mGenMtx) ;
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMeta;
RsGxsGrpMetaTemporaryMap grpMeta;
grpMeta[grpId] = NULL;
mDataStore->retrieveGxsGrpMetaData(grpMeta);
if(grpMeta.empty())
return false;
RsGxsGrpMetaData* meta = grpMeta[grpId];
const RsGxsGrpMetaData* meta = grpMeta[grpId];
if(meta == NULL)
return false;
keySet = meta->keys;
GxsSecurity::createPublicKeysFromPrivateKeys(keySet) ;
for(std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator it=grpMeta.begin();it!=grpMeta.end();++it)
delete it->second ;
GxsSecurity::createPublicKeysFromPrivateKeys(keySet) ;
return true;
}
@ -2900,7 +2890,9 @@ void RsGenExchange::processRecvdMessages()
if(!accept_new_msg || gpsi.mFirstTryTS + VALIDATE_MAX_WAITING_TIME < now)
{
#ifdef GEN_EXCH_DEBUG
std::cerr << "Pending validation grp=" << gpsi.mId.first << ", msg=" << gpsi.mId.second << ", has exceeded validation time limit. The author's key can probably not be obtained. This is unexpected." << std::endl;
#endif
delete gpsi.mItem;
pend_it = mMsgPendingValidate.erase(pend_it);
@ -2958,11 +2950,12 @@ void RsGenExchange::processRecvdMessages()
continue ;
}
RsGxsGrpMetaData *grpMeta = mit->second;
const RsGxsGrpMetaData *grpMeta = mit->second;
RsTlvSecurityKeySet keys = grpMeta->keys ;
GxsSecurity::createPublicKeysFromPrivateKeys(grpMeta->keys); // make sure we have the public keys that correspond to the private ones, as it happens. Most of the time this call does nothing.
GxsSecurity::createPublicKeysFromPrivateKeys(keys); // make sure we have the public keys that correspond to the private ones, as it happens. Most of the time this call does nothing.
int validateReturn = validateMsg(msg, grpMeta->mGroupFlags, grpMeta->mSignFlags, grpMeta->keys);
int validateReturn = validateMsg(msg, grpMeta->mGroupFlags, grpMeta->mSignFlags, keys);
#ifdef GEN_EXCH_DEBUG
std::cerr << " grpMeta.mSignFlags: " << std::hex << grpMeta->mSignFlags << std::dec << std::endl;
@ -3176,7 +3169,7 @@ void RsGenExchange::processRecvdGroups()
void RsGenExchange::performUpdateValidation()
{
RS_STACK_MUTEX(mGenMtx) ;
RS_STACK_MUTEX(mGenMtx) ;
if(mGroupUpdates.empty())
return;
@ -3185,7 +3178,7 @@ void RsGenExchange::performUpdateValidation()
std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl;
#endif
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMetas;
RsGxsGrpMetaTemporaryMap grpMetas;
std::vector<GroupUpdate>::iterator vit = mGroupUpdates.begin();
for(; vit != mGroupUpdates.end(); ++vit)
@ -3200,8 +3193,7 @@ void RsGenExchange::performUpdateValidation()
for(; vit != mGroupUpdates.end(); ++vit)
{
GroupUpdate& gu = *vit;
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit =
grpMetas.find(gu.newGrp->grpId);
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit = grpMetas.find(gu.newGrp->grpId);
gu.oldGrpMeta = mit->second;
gu.validUpdate = updateValid(*(gu.oldGrpMeta), *(gu.newGrp));
}
@ -3223,51 +3215,57 @@ void RsGenExchange::performUpdateValidation()
if(gu.newGrp->metaData->mCircleType == GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY)
gu.newGrp->metaData->mOriginator = gu.newGrp->PeerId();
// Keep subscriptionflag to what it was. This avoids clearing off the flag when updates to group meta information
// is received.
gu.newGrp->metaData->mSubscribeFlags = gu.oldGrpMeta->mSubscribeFlags ;
// Keep subscriptionflag to what it was. This avoids clearing off the flag when updates to group meta information
// is received.
gu.newGrp->metaData->mSubscribeFlags = gu.oldGrpMeta->mSubscribeFlags ;
// Also keep private keys if present
if(!gu.newGrp->metaData->keys.private_keys.empty())
std::cerr << "(EE) performUpdateValidation() group " <<gu.newGrp->metaData->mGroupId << " has been received with private keys. This is very unexpected!" << std::endl;
else
gu.newGrp->metaData->keys.private_keys = gu.oldGrpMeta->keys.private_keys ;
grps.push_back(gu.newGrp);
}
else
{
delete gu.newGrp;
gu.newGrp = NULL ;
gu.newGrp = NULL ;
}
delete gu.oldGrpMeta;
gu.oldGrpMeta = NULL ;
gu.oldGrpMeta = NULL ;
}
// notify the client
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVE, true);
for(uint32_t i=0;i<mGroupUpdates.size();++i)
if(mGroupUpdates[i].newGrp != NULL)
{
c->mGrpIdList.push_back(mGroupUpdates[i].newGrp->grpId) ;
// notify the client
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVE, true);
for(uint32_t i=0;i<mGroupUpdates.size();++i)
if(mGroupUpdates[i].newGrp != NULL)
{
c->mGrpIdList.push_back(mGroupUpdates[i].newGrp->grpId) ;
#ifdef GEN_EXCH_DEBUG
std::cerr << " " << mGroupUpdates[i].newGrp->grpId << std::endl;
std::cerr << " " << mGroupUpdates[i].newGrp->grpId << std::endl;
#endif
}
mNotifications.push_back(c);
// Warning: updateGroup will destroy the objects in grps. Dont use it afterwards!
}
mNotifications.push_back(c);
// Warning: updateGroup will destroy the objects in grps. Dont use it afterwards!
mDataStore->updateGroup(grps);
#ifdef GEN_EXCH_DEBUG
std::cerr << " adding the following grp ids to notification: " << std::endl;
std::cerr << " adding the following grp ids to notification: " << std::endl;
#endif
// cleanup
// cleanup
mGroupUpdates.clear();
}
bool RsGenExchange::updateValid(RsGxsGrpMetaData& oldGrpMeta, RsNxsGrp& newGrp) const
bool RsGenExchange::updateValid(const RsGxsGrpMetaData& oldGrpMeta, const RsNxsGrp& newGrp) const
{
std::map<SignType, RsTlvKeySignature>& signSet = newGrp.metaData->signSet.keySignSet;
std::map<SignType, RsTlvKeySignature>::iterator mit = signSet.find(INDEX_AUTHEN_ADMIN);
@ -3283,10 +3281,11 @@ bool RsGenExchange::updateValid(RsGxsGrpMetaData& oldGrpMeta, RsNxsGrp& newGrp)
}
RsTlvKeySignature adminSign = mit->second;
RsTlvSecurityKeySet old_keys = oldGrpMeta.keys ;
GxsSecurity::createPublicKeysFromPrivateKeys(oldGrpMeta.keys); // make sure we have the public keys that correspond to the private ones, as it happens. Most of the time this call does nothing.
GxsSecurity::createPublicKeysFromPrivateKeys(old_keys); // make sure we have the public keys that correspond to the private ones, as it happens. Most of the time this call does nothing.
std::map<RsGxsId, RsTlvPublicRSAKey>& keys = oldGrpMeta.keys.public_keys;
std::map<RsGxsId, RsTlvPublicRSAKey>& keys = old_keys.public_keys;
std::map<RsGxsId, RsTlvPublicRSAKey>::iterator keyMit = keys.find(RsGxsId(oldGrpMeta.mGroupId));
if(keyMit == keys.end())

View file

@ -223,7 +223,7 @@ public:
* @param groupInfo
* @return false if could not redeem token
*/
bool getGroupMeta(const uint32_t &token, std::list<RsGroupMetaData> &groupInfo);
bool getGroupMeta(const uint32_t &token, std::list<RsGroupMetaData>& groupInfo);
/*!
* retrieves message meta data associated to a request token
@ -765,7 +765,7 @@ private:
* SIGN_FAIL_TRY_LATER for Id sign key not avail (but requested), try later
*/
int createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinaryData& msgData,
const RsGxsMsgMetaData& msgMeta, RsGxsGrpMetaData& grpMeta);
const RsGxsMsgMetaData& msgMeta, const RsGxsGrpMetaData& grpMeta);
/*!
* convenience function to create sign for groups
@ -835,7 +835,7 @@ private:
* @param newGrp the new group that updates the old group (must have meta data member initialised)
* @return
*/
bool updateValid(RsGxsGrpMetaData& oldGrp, RsNxsGrp& newGrp) const;
bool updateValid(const RsGxsGrpMetaData& oldGrp, const RsNxsGrp& newGrp) const;
/*!
* convenience function for checking private publish and admin keys are present
@ -915,7 +915,6 @@ private:
std::vector<MsgDeletePublish> mMsgDeletePublish;
std::map<RsGxsId,std::set<RsPeerId> > mRoutingClues ;
std::list<std::pair<RsGxsMessageId,RsPeerId> > mTrackingClues ;
};
#endif // RSGENEXCHANGE_H

View file

@ -186,7 +186,8 @@ class RsGixsReputation
{
public:
// get Reputation.
virtual RsReputations::ReputationLevel overallReputationLevel(const RsGxsId& id,uint32_t *identity_flags=NULL) = 0;
virtual RsReputations::ReputationLevel overallReputationLevel(const RsGxsId& id,uint32_t *identity_flags=NULL) = 0;
virtual ~RsGixsReputation(){}
};
/*** This Class pulls all the GXS Interfaces together ****/
@ -210,6 +211,7 @@ virtual ~RsGxsIdExchange() { return; }
class RsGcxs
{
public:
virtual ~RsGcxs(){}
/* GXS Interface - for working out who can receive */
virtual bool isLoaded(const RsGxsCircleId &circleId) = 0;

View file

@ -33,7 +33,7 @@ RsGxsGrpMetaData::RsGxsGrpMetaData()
clear();
}
uint32_t RsGxsGrpMetaData::serial_size(uint32_t api_version)
uint32_t RsGxsGrpMetaData::serial_size(uint32_t api_version) const
{
uint32_t s = 8; // header size

View file

@ -51,7 +51,7 @@ public:
RsGxsGrpMetaData();
bool deserialise(void *data, uint32_t &pktsize);
bool serialise(void* data, uint32_t &pktsize, uint32_t api_version);
uint32_t serial_size(uint32_t api_version);
uint32_t serial_size(uint32_t api_version) const;
void clear();
void operator =(const RsGroupMetaData& rMeta);

View file

@ -25,6 +25,7 @@
#include <time.h>
#include "rsgxsutil.h"
#include "rsgxsdataaccess.h"
#include "retroshare/rsgxsflags.h"
@ -377,7 +378,7 @@ bool RsGxsDataAccess::clearRequest(const uint32_t& token)
return true;
}
bool RsGxsDataAccess::getGroupSummary(const uint32_t& token, std::list<RsGxsGrpMetaData*>& groupInfo)
bool RsGxsDataAccess::getGroupSummary(const uint32_t& token, std::list<const RsGxsGrpMetaData*>& groupInfo)
{
RS_STACK_MUTEX(mDataMutex);
@ -1000,18 +1001,17 @@ bool RsGxsDataAccess::getGroupData(GroupDataReq* req)
bool RsGxsDataAccess::getGroupSummary(GroupMetaReq* req)
{
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMeta;
RsGxsGrpMetaTemporaryMap grpMeta;
std::list<RsGxsGroupId> grpIdsOut;
std::list<RsGxsGroupId> grpIdsOut;
getGroupList(req->mGroupIds, req->Options, grpIdsOut);
getGroupList(req->mGroupIds, req->Options, grpIdsOut);
if(grpIdsOut.empty())
return true;
if(grpIdsOut.empty())
return true;
std::list<RsGxsGroupId>::const_iterator lit = grpIdsOut.begin();
std::list<RsGxsGroupId>::const_iterator lit = grpIdsOut.begin();
for(; lit != grpIdsOut.end(); ++lit)
for(; lit != grpIdsOut.end(); ++lit)
grpMeta[*lit] = NULL;
mDataStore->retrieveGxsGrpMetaData(grpMeta);
@ -1033,29 +1033,18 @@ bool RsGxsDataAccess::getGroupList(GroupIdReq* req)
bool RsGxsDataAccess::getGroupList(const std::list<RsGxsGroupId>& grpIdsIn, const RsTokReqOptions& opts, std::list<RsGxsGroupId>& grpIdsOut)
{
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMeta;
RsGxsGrpMetaTemporaryMap grpMeta;
std::list<RsGxsGroupId>::const_iterator lit = grpIdsIn.begin();
for(; lit != grpIdsIn.end(); ++lit)
grpMeta[*lit] = NULL;
for(auto lit = grpIdsIn.begin(); lit != grpIdsIn.end(); ++lit)
grpMeta[*lit] = NULL;
mDataStore->retrieveGxsGrpMetaData(grpMeta);
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit = grpMeta.begin();
for(; mit != grpMeta.end(); ++mit)
{
grpIdsOut.push_back(mit->first);
}
for(auto mit = grpMeta.begin() ; mit != grpMeta.end(); ++mit)
grpIdsOut.push_back(mit->first);
filterGrpList(grpIdsOut, opts, grpMeta);
for(mit = grpMeta.begin(); mit != grpMeta.end(); ++mit)
{
delete mit->second; // so wasteful!!
}
return true;
}
@ -1622,12 +1611,10 @@ bool RsGxsDataAccess::getGroupStatistic(GroupStatisticRequest *req)
// potentially very expensive!
bool RsGxsDataAccess::getServiceStatistic(ServiceStatisticRequest *req)
{
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMeta;
RsGxsGrpMetaTemporaryMap grpMeta ;
mDataStore->retrieveGxsGrpMetaData(grpMeta);
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit = grpMeta.begin();
req->mServiceStatistic.mNumGrps = grpMeta.size();
req->mServiceStatistic.mNumMsgs = 0;
req->mServiceStatistic.mSizeOfGrps = 0;
@ -1638,9 +1625,9 @@ bool RsGxsDataAccess::getServiceStatistic(ServiceStatisticRequest *req)
req->mServiceStatistic.mNumChildMsgsNew = 0;
req->mServiceStatistic.mNumChildMsgsUnread = 0;
for(; mit != grpMeta.end(); ++mit)
for(auto mit = grpMeta.begin(); mit != grpMeta.end(); ++mit)
{
RsGxsGrpMetaData* m = mit->second;
const RsGxsGrpMetaData* m = mit->second;
req->mServiceStatistic.mSizeOfGrps += m->mGrpSize + m->serial_size(RS_GXS_GRP_META_DATA_CURRENT_API_VERSION);
if (IS_GROUP_SUBSCRIBED(m->mSubscribeFlags))
@ -1658,8 +1645,6 @@ bool RsGxsDataAccess::getServiceStatistic(ServiceStatisticRequest *req)
req->mServiceStatistic.mNumChildMsgsNew += gr.mGroupStatistic.mNumChildMsgsNew;
req->mServiceStatistic.mNumChildMsgsUnread += gr.mGroupStatistic.mNumChildMsgsUnread;
}
delete m;
}
req->mServiceStatistic.mSizeStore = req->mServiceStatistic.mSizeOfGrps + req->mServiceStatistic.mSizeOfMsgs;

View file

@ -209,7 +209,7 @@ public:
* @param token request token to be redeemed
* @param groupInfo
*/
bool getGroupSummary(const uint32_t &token, std::list<RsGxsGrpMetaData*> &groupInfo);
bool getGroupSummary(const uint32_t &token, std::list<const RsGxsGrpMetaData*>& groupInfo);
/*!
*

View file

@ -255,6 +255,7 @@
#include "retroshare/rspeers.h"
#include "pgp/pgpauxutils.h"
#include "util/rsdir.h"
#include "util/rstime.h"
#include "util/rsmemory.h"
#include "util/stacktrace.h"
@ -433,6 +434,8 @@ int RsGxsNetService::tick()
should_notify = should_notify || !mNewGroupsToNotify.empty() ;
should_notify = should_notify || !mNewMessagesToNotify.empty() ;
should_notify = should_notify || !mNewPublishKeysToNotify.empty() ;
should_notify = should_notify || !mNewStatsToNotify.empty() ;
}
if(should_notify)
@ -495,8 +498,11 @@ void RsGxsNetService::processObserverNotifications()
if(!grps_copy.empty()) mObserver->notifyNewGroups (grps_copy);
if(!msgs_copy.empty()) mObserver->notifyNewMessages(msgs_copy);
for(std::set<RsGxsGroupId>::const_iterator it(keys_copy.begin());it!=keys_copy.end();++it) mObserver->notifyReceivePublishKey(*it);
for(std::set<RsGxsGroupId>::const_iterator it(stat_copy.begin());it!=stat_copy.end();++it) mObserver->notifyChangedGroupStats(*it);
for(std::set<RsGxsGroupId>::const_iterator it(keys_copy.begin());it!=keys_copy.end();++it)
mObserver->notifyReceivePublishKey(*it);
for(std::set<RsGxsGroupId>::const_iterator it(stat_copy.begin());it!=stat_copy.end();++it)
mObserver->notifyChangedGroupStats(*it);
}
void RsGxsNetService::rejectMessage(const RsGxsMessageId& msg_id)
@ -734,7 +740,7 @@ void RsGxsNetService::syncGrpStatistics()
time_t now = time(NULL) ;
for(std::map<RsGxsGroupId,RsGxsGrpMetaData*>::const_iterator it(grpMeta.begin());it!=grpMeta.end();++it)
for(auto it(grpMeta.begin());it!=grpMeta.end();++it)
{
const RsGxsGrpConfig& rec = locked_getGrpConfig(it->first) ;
@ -800,7 +806,7 @@ void RsGxsNetService::handleRecvSyncGrpStatistics(RsNxsSyncGrpStatsItem *grs)
mDataStore->retrieveGxsGrpMetaData(grpMetas);
RsGxsGrpMetaData* grpMeta = grpMetas[grs->grpId];
const RsGxsGrpMetaData* grpMeta = grpMetas[grs->grpId];
if(grpMeta == NULL)
{
@ -1832,7 +1838,7 @@ void RsGxsNetService::data_tick()
static const double timeDelta = 0.5;
//Start waiting as nothing to do in runup
usleep((int) (timeDelta * 1000 * 1000)); // timeDelta sec
rstime::rs_usleep((int) (timeDelta * 1000 * 1000)); // timeDelta sec
if(mUpdateCounter >= 120) // 60 seconds
{
@ -1996,7 +2002,7 @@ void RsGxsNetService::updateServerSyncTS()
// finally, update timestamps.
bool change = false;
for(std::map<RsGxsGroupId, RsGxsGrpMetaData*>::const_iterator mit = gxsMap.begin();mit != gxsMap.end(); ++mit)
for(auto mit = gxsMap.begin();mit != gxsMap.end(); ++mit)
{
// Check if the group is subscribed and restricted to a circle. If the circle has changed, update the
// global TS to reflect that change to clients who may be able to see/subscribe to that particular group.
@ -2767,7 +2773,7 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
grpMetaMap[grpId] = NULL;
mDataStore->retrieveGxsGrpMetaData(grpMetaMap);
RsGxsGrpMetaData* grpMeta = grpMetaMap[grpId];
const RsGxsGrpMetaData* grpMeta = grpMetaMap[grpId];
if(grpMeta == NULL) // this should not happen, but just in case...
{
@ -3870,9 +3876,9 @@ void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrpReqItem *item)
GXSNETDEBUG_P_(peer) << " Group list beings being sent: " << std::endl;
#endif
for(std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit = grp.begin(); mit != grp.end(); ++mit)
for(auto mit = grp.begin(); mit != grp.end(); ++mit)
{
RsGxsGrpMetaData* grpMeta = mit->second;
const RsGxsGrpMetaData* grpMeta = mit->second;
// Only send info about subscribed groups.
@ -3944,7 +3950,7 @@ void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrpReqItem *item)
bool RsGxsNetService::canSendGrpId(const RsPeerId& sslId, RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& /* toVet */, bool& should_encrypt)
bool RsGxsNetService::canSendGrpId(const RsPeerId& sslId, const RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& /* toVet */, bool& should_encrypt)
{
#ifdef NXS_NET_DEBUG_4
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << "RsGxsNetService::canSendGrpId()"<< std::endl;
@ -4137,7 +4143,7 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_
grpMetas[item->grpId] = NULL;
mDataStore->retrieveGxsGrpMetaData(grpMetas);
RsGxsGrpMetaData* grpMeta = grpMetas[item->grpId];
const RsGxsGrpMetaData* grpMeta = grpMetas[item->grpId];
if(grpMeta == NULL)
{
@ -4678,7 +4684,7 @@ void RsGxsNetService::sharePublishKeysPending()
// Find the publish keys in the retrieved info
RsGxsGrpMetaData *grpMeta = grpMetaMap[mit->first] ;
const RsGxsGrpMetaData *grpMeta = grpMetaMap[mit->first] ;
if(grpMeta == NULL)
{
@ -4763,7 +4769,7 @@ void RsGxsNetService::handleRecvPublishKeys(RsNxsGroupPublishKeyItem *item)
// update the publish keys in this group meta info
RsGxsGrpMetaData *grpMeta = grpMetaMap[item->grpId] ;
const RsGxsGrpMetaData *grpMeta = grpMetaMap[item->grpId] ;
if (!grpMeta) {
std::cerr << "(EE) RsGxsNetService::handleRecvPublishKeys() grpMeta not found." << std::endl;
return ;
@ -4800,14 +4806,16 @@ void RsGxsNetService::handleRecvPublishKeys(RsNxsGroupPublishKeyItem *item)
#ifdef NXS_NET_DEBUG_3
GXSNETDEBUG_PG(item->PeerId(),item->grpId)<< " (EE) Publish key already present in database. Discarding message." << std::endl;
#endif
mNewPublishKeysToNotify.insert(item->grpId) ;
return ;
}
// Store/update the info.
grpMeta->keys.private_keys[item->private_key.keyId] = item->private_key ;
RsTlvSecurityKeySet keys = grpMeta->keys ;
keys.private_keys[item->private_key.keyId] = item->private_key ;
bool ret = mDataStore->updateGroupKeys(item->grpId,grpMeta->keys, grpMeta->mSubscribeFlags | GXS_SERV::GROUP_SUBSCRIBE_PUBLISH) ;
bool ret = mDataStore->updateGroupKeys(item->grpId,keys, grpMeta->mSubscribeFlags | GXS_SERV::GROUP_SUBSCRIBE_PUBLISH) ;
if(ret)
{

View file

@ -370,7 +370,7 @@ private:
* @param toVet groupid/peer to vet are stored here if their circle id is not cached
* @return false, if you cannot send to this peer, true otherwise
*/
bool canSendGrpId(const RsPeerId& sslId, RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& toVet, bool &should_encrypt);
bool canSendGrpId(const RsPeerId& sslId, const RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& toVet, bool &should_encrypt);
bool canSendMsgIds(std::vector<RsGxsMsgMetaData*>& msgMetas, const RsGxsGrpMetaData&, const RsPeerId& sslId, RsGxsCircleId &should_encrypt_id);
/*!

View file

@ -28,7 +28,8 @@
GroupMetaReq::~GroupMetaReq()
{
rsstd::delete_all(mGroupMetaData.begin(), mGroupMetaData.end());
//rsstd::delete_all(mGroupMetaData.begin(), mGroupMetaData.end()); // now memory ownership is kept by the cache.
mGroupMetaData.clear();
}
GroupDataReq::~GroupDataReq()

View file

@ -52,7 +52,7 @@ public:
public:
std::list<RsGxsGroupId> mGroupIds;
std::list<RsGxsGrpMetaData*> mGroupMetaData;
std::list<const RsGxsGrpMetaData*> mGroupMetaData;
};
class GroupIdReq : public GxsRequest

View file

@ -42,13 +42,10 @@ static const uint32_t MAX_GXS_IDS_REQUESTS_NET = 10 ; // max number of reques
RsGxsMessageCleanUp::RsGxsMessageCleanUp(RsGeneralDataService* const dataService, RsGenExchange *genex, uint32_t chunkSize)
: mDs(dataService), mGenExchangeClient(genex), CHUNK_SIZE(chunkSize)
{
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMeta;
RsGxsGrpMetaTemporaryMap grpMeta;
mDs->retrieveGxsGrpMetaData(grpMeta);
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator cit = grpMeta.begin();
for(;cit != grpMeta.end(); ++cit)
for(auto cit=grpMeta.begin();cit != grpMeta.end(); ++cit)
mGrpMeta.push_back(cit->second);
}
@ -64,7 +61,7 @@ bool RsGxsMessageCleanUp::clean()
#endif
while(!mGrpMeta.empty())
{
RsGxsGrpMetaData* grpMeta = mGrpMeta.back();
const RsGxsGrpMetaData* grpMeta = mGrpMeta.back();
const RsGxsGroupId& grpId = grpMeta->mGroupId;
mGrpMeta.pop_back();
GxsMsgReq req;
@ -137,8 +134,6 @@ bool RsGxsMessageCleanUp::clean()
mDs->removeMsgs(req);
delete grpMeta;
i++;
if(i > CHUNK_SIZE) break;
}

View file

@ -32,6 +32,7 @@
class RsGixs ;
class RsGenExchange ;
class RsGeneralDataService ;
// temporary holds a map of pointers to class T, and destroys all pointers on delete.
@ -104,7 +105,7 @@ public:
}
};
typedef t_RsGxsGenericDataTemporaryMap<RsGxsGroupId,RsGxsGrpMetaData> RsGxsGrpMetaTemporaryMap;
typedef std::map<RsGxsGroupId,RsGxsGrpMetaData*> RsGxsGrpMetaTemporaryMap;
typedef t_RsGxsGenericDataTemporaryMap<RsGxsGroupId,RsNxsGrp> RsNxsGrpDataTemporaryMap;
typedef t_RsGxsGenericDataTemporaryMapVector<RsGxsMsgMetaData> RsGxsMsgMetaTemporaryMap ;
@ -178,7 +179,7 @@ private:
RsGeneralDataService* const mDs;
RsGenExchange *mGenExchangeClient;
uint32_t CHUNK_SIZE;
std::vector<RsGxsGrpMetaData*> mGrpMeta;
std::vector<const RsGxsGrpMetaData*> mGrpMeta;
};
/*!
@ -226,7 +227,7 @@ class GroupUpdate
public:
GroupUpdate() : oldGrpMeta(NULL), newGrp(NULL), validUpdate(false)
{}
RsGxsGrpMetaData* oldGrpMeta;
const RsGxsGrpMetaData* oldGrpMeta;
RsNxsGrp* newGrp;
bool validUpdate;
};

View file

@ -143,7 +143,10 @@ void p3GxsTunnelService::flush()
for(std::list<RsGxsTunnelDHPublicKeyItem*>::iterator it=pendingDHItems.begin();it!=pendingDHItems.end();)
if(locked_sendClearTunnelData(*it) )
{
delete *it ;
it = pendingDHItems.erase(it) ;
}
else
++it ;
}
@ -155,7 +158,10 @@ void p3GxsTunnelService::flush()
for(std::list<RsGxsTunnelItem*>::iterator it=pendingGxsTunnelItems.begin();it!=pendingGxsTunnelItems.end();)
if(locked_sendEncryptedTunnelData(*it) )
{
delete *it ;
it = pendingGxsTunnelItems.erase(it) ;
}
else
{
++it ;
@ -744,6 +750,8 @@ void p3GxsTunnelService::receiveTurtleData(RsTurtleGenericTunnelItem *gitem,cons
}
else
std::cerr << "(EE) Deserialiased item has unexpected type." << std::endl;
delete citem ;
}
}

View file

@ -1,7 +1,7 @@
!include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri")
TEMPLATE = lib
CONFIG += staticlib bitdht
CONFIG += staticlib
CONFIG += create_prl
CONFIG -= qt
TARGET = retroshare
@ -10,7 +10,14 @@ DESTDIR = lib
#CONFIG += dsdv
# the dht stunner is used to obtain RS' external ip addr. when it is natted
retrotor {
DEFINES *= RETROTOR
CONFIG -= bitdht
} else {
CONFIG += bitdht
}
# the dht stunner is used to obtain RS external ip addr. when it is natted
# this system is unreliable and rs supports a newer and better one (asking connected peers)
# CONFIG += useDhtStunner
@ -90,6 +97,7 @@ HEADERS += tcponudp/udppeer.h \
tcponudp/tcpstream.h \
tcponudp/tou.h \
tcponudp/udprelay.h \
pqi/pqissludp.h \
SOURCES += tcponudp/udppeer.cc \
tcponudp/tcppacket.cc \
@ -97,6 +105,7 @@ SOURCES += tcponudp/udppeer.cc \
tcponudp/tou.cc \
tcponudp/bss_tou.c \
tcponudp/udprelay.cc \
pqi/pqissludp.cc \
useDhtStunner {
HEADERS += dht/stunaddrassist.h \
@ -434,7 +443,6 @@ HEADERS += pqi/authssl.h \
pqi/pqissllistener.h \
pqi/pqisslpersongrp.h \
pqi/pqissli2pbob.h \
pqi/pqissludp.h \
pqi/pqisslproxy.h \
pqi/pqistore.h \
pqi/pqistreamer.h \
@ -539,7 +547,7 @@ HEADERS += util/folderiterator.h \
util/rsmemcache.h \
util/rstickevent.h \
util/rsrecogn.h \
util/rsscopetimer.h \
util/rstime.h \
util/stacktrace.h \
util/rsdeprecate.h \
util/cxx11retrocompat.h
@ -590,7 +598,6 @@ SOURCES += pqi/authgpg.cc \
pqi/pqissllistener.cc \
pqi/pqisslpersongrp.cc \
pqi/pqissli2pbob.cpp \
pqi/pqissludp.cc \
pqi/pqisslproxy.cc \
pqi/pqistore.cc \
pqi/pqistreamer.cc \
@ -688,7 +695,7 @@ SOURCES += util/folderiterator.cc \
util/rsrandom.cc \
util/rstickevent.cc \
util/rsrecogn.cc \
util/rsscopetimer.cc
util/rstime.cc
upnp_miniupnpc {
@ -919,24 +926,28 @@ test_bitdht {
################################# Android #####################################
android-g++ {
android-* {
## ifaddrs is missing on Android to add them don't use the one from
## https://github.com/morristech/android-ifaddrs
## because they crash, use QNetworkInterface from Qt instead
## because it crash, use QNetworkInterface from Qt instead
CONFIG *= qt
QT *= network
## Add this here and not in retroshare.pri because static library are very
## sensible to order in command line, has to be in the end of file for the
## same reason
DEFINES *= "fopen64=fopen"
DEFINES *= "fseeko64=fseeko"
DEFINES *= "ftello64=ftello"
LIBS *= -lbz2 -lupnp -lixml -lthreadutil -lsqlite3
## Static library are verysensible to order in command line, has to be in the
## end of file for this reason
LIBS += -L$$NATIVE_LIBS_TOOLCHAIN_PATH/sysroot/usr/lib/ -lsqlcipher
PRE_TARGETDEPS += $$NATIVE_LIBS_TOOLCHAIN_PATH/sysroot/usr/lib/libsqlcipher.a
LIBS += -L$$NATIVE_LIBS_TOOLCHAIN_PATH/sysroot/usr/lib/ -lssl
INCLUDEPATH += $$NATIVE_LIBS_TOOLCHAIN_PATH/sysroot/usr/include
DEPENDPATH += $$NATIVE_LIBS_TOOLCHAIN_PATH/sysroot/usr/include
PRE_TARGETDEPS += $$NATIVE_LIBS_TOOLCHAIN_PATH/sysroot/usr/lib/libssl.a
LIBS += -L$$NATIVE_LIBS_TOOLCHAIN_PATH/sysroot/usr/lib/ -lcrypto
INCLUDEPATH += $$NATIVE_LIBS_TOOLCHAIN_PATH/sysroot/usr/include
DEPENDPATH += $$NATIVE_LIBS_TOOLCHAIN_PATH/sysroot/usr/include
PRE_TARGETDEPS += $$NATIVE_LIBS_TOOLCHAIN_PATH/sysroot/usr/lib/libcrypto.a
HEADERS += util/androiddebug.h

View file

@ -35,6 +35,7 @@
class PgpAuxUtils
{
public:
virtual ~PgpAuxUtils(){}
virtual const RsPgpId &getPGPOwnId() = 0;
virtual RsPgpId getPGPId(const RsPeerId& sslid) = 0;

View file

@ -360,8 +360,9 @@ bool RsCertificate::initFromString(const std::string& instr,uint32_t& err_code)
}
break ;
default:
err_code = CERTIFICATE_PARSING_ERROR_UNKNOWN_SECTION_PTAG ;
return false ;
std::cerr << "(WW) unknwown PTAG 0x" << std::hex << ptag << std::dec << " in certificate! Ignoring it." << std::endl;
buf = &buf[s] ;
break ;
}
total_s += s ;

View file

@ -35,6 +35,7 @@
#include "pgp/pgphandler.h"
#include <util/rsdir.h>
#include <util/rstime.h>
#include <pgp/pgpkeyutil.h>
#include <unistd.h> /* for (u)sleep() */
#include <iostream>
@ -187,7 +188,7 @@ int AuthGPG::GPGInit(const RsPgpId &ownId)
void AuthGPG::data_tick()
{
usleep(100 * 1000); //100 msec
rstime::rs_usleep(100 * 1000); //100 msec
/// every 100 milliseconds
processServices();

View file

@ -3,7 +3,8 @@
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2007-2011 by Robert Fernie.
* Copyright (C) 2007-2011 Robert Fernie
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -24,6 +25,7 @@
*/
#include <time.h>
#include <vector>
#include "pqi/p3netmgr.h"
@ -37,8 +39,7 @@
#include "util/extaddrfinder.h"
#include "util/dnsresolver.h"
//#include "util/rsprint.h"
//#include "util/rsdebug.h"
struct RsLog::logInfo p3netmgrzoneInfo = {RsLog::Default, "p3netmgr"};
#define p3netmgrzone &p3netmgrzoneInfo
@ -165,11 +166,6 @@ void p3NetMgrIMPL::setManagers(p3PeerMgr *peerMgr, p3LinkMgr *linkMgr)
mLinkMgr = linkMgr;
}
//void p3NetMgrIMPL::setDhtMgr(p3DhtMgr *dhtMgr)
//{
// mDhtMgr = dhtMgr;
//}
#ifdef RS_USE_DHT_STUNNER
void p3NetMgrIMPL::setAddrAssist(pqiAddrAssist *dhtStun, pqiAddrAssist *proxyStun)
{
@ -718,7 +714,7 @@ void p3NetMgrIMPL::netExtCheck()
#endif
if(sockaddr_storage_isValidNet(tmpip))
{
if(rsBanList->isAddressAccepted(tmpip,RSBANLIST_CHECKING_FLAGS_BLACKLIST))
if( (rsBanList==NULL) || rsBanList->isAddressAccepted(tmpip,RSBANLIST_CHECKING_FLAGS_BLACKLIST))
{
// must be stable???
isStable = true;
@ -761,7 +757,7 @@ void p3NetMgrIMPL::netExtCheck()
/* input network bits */
if (mDhtStunner->getExternalAddr(tmpaddr, isstable))
{
if(rsBanList->isAddressAccepted(tmpaddr,RSBANLIST_CHECKING_FLAGS_BLACKLIST))
if((rsBanList == NULL) || rsBanList->isAddressAccepted(tmpaddr,RSBANLIST_CHECKING_FLAGS_BLACKLIST))
{
// must be stable???
isStable = (isstable == 1);
@ -1020,19 +1016,41 @@ bool p3NetMgrIMPL::checkNetAddress()
}
else
{
// TODO: Sat Oct 24 15:51:24 CEST 2015 The fact of having just one local address is a flawed assumption, this should be redesigned soon.
std::list<sockaddr_storage> addrs;
std::list<sockaddr_storage>::iterator it;
/* TODO: Sat Oct 24 15:51:24 CEST 2015 The fact of having just one local
* address is a flawed assumption, this should be redesigned as soon as
* possible. It will require complete reenginering of the network layer
* code. */
std::vector<sockaddr_storage> addrs;
if (getLocalAddresses(addrs))
for(it = addrs.begin(); (it != addrs.end() && !validAddr); ++it)
if(sockaddr_storage_isValidNet(*it) && !sockaddr_storage_isLoopbackNet(*it))
{
for (auto it = addrs.begin(); it!=addrs.end(); ++it)
{
sockaddr_storage& addr(*it);
if( sockaddr_storage_isValidNet(addr) &&
!sockaddr_storage_isLoopbackNet(addr) &&
!sockaddr_storage_isLinkLocalNet(addr))
{
prefAddr = *it;
prefAddr = addr;
validAddr = true;
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cout << "p3NetMgrIMPL::checkNetAddress() prefAddr: " << sockaddr_storage_iptostring(prefAddr) << std::endl;
#endif
break;
}
}
/* If no satisfactory local address has been found yet relax and
* accept also link local addresses */
if(!validAddr) for (auto it = addrs.begin(); it!=addrs.end(); ++it)
{
sockaddr_storage& addr(*it);
if( sockaddr_storage_isValidNet(addr) &&
!sockaddr_storage_isLoopbackNet(addr) )
{
prefAddr = addr;
validAddr = true;
break;
}
}
}
}

View file

@ -519,6 +519,25 @@ uint32_t p3PeerMgrIMPL::getHiddenType(const RsPeerId &ssl_id)
return (it->second).hiddenType;
}
bool p3PeerMgrIMPL::isHiddenNode(const RsPeerId& id)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
if (id == AuthSSL::getAuthSSL()->OwnId())
return mOwnState.hiddenNode ;
else
{
std::map<RsPeerId,peerState>::const_iterator it = mFriendList.find(id);
if (it == mFriendList.end())
{
std::cerr << "p3PeerMgrIMPL::isHiddenNode() Peer Not Found" << std::endl;
return false;
}
return it->second.hiddenNode ;
}
}
/**
* @brief sets hidden domain and port for a given ssl ID
* @param ssl_id peer to set domain and port for
@ -1218,7 +1237,7 @@ bool p3PeerMgrIMPL::UpdateOwnAddress(const struct sockaddr_storage &localAddr,
std::cerr << ")" << std::endl;
#endif
if(!rsBanList->isAddressAccepted(localAddr, RSBANLIST_CHECKING_FLAGS_BLACKLIST))
if((rsBanList != NULL) && !rsBanList->isAddressAccepted(localAddr, RSBANLIST_CHECKING_FLAGS_BLACKLIST))
{
std::cerr << "(SS) Trying to set own IP to a banned IP " << sockaddr_storage_iptostring(localAddr) << ". This probably means that a friend in under traffic re-routing attack." << std::endl;
return false ;
@ -1357,7 +1376,7 @@ bool p3PeerMgrIMPL::setExtAddress(const RsPeerId &id, const struct sockaddr_s
bool changed = false;
uint32_t check_res = 0 ;
if(!rsBanList->isAddressAccepted(addr,RSBANLIST_CHECKING_FLAGS_BLACKLIST,&check_res))
if(rsBanList!=NULL && !rsBanList->isAddressAccepted(addr,RSBANLIST_CHECKING_FLAGS_BLACKLIST,&check_res))
{
std::cerr << "(SS) trying to set external contact address for peer " << id << " to a banned address " << sockaddr_storage_iptostring(addr )<< std::endl;
return false ;
@ -1531,7 +1550,7 @@ bool p3PeerMgrIMPL::addCandidateForOwnExternalAddress(const RsPeerId &from, cons
// Notify for every friend that has reported a wrong external address, except if that address is in the IP whitelist.
if((!rsBanList->isAddressAccepted(addr_filtered,RSBANLIST_CHECKING_FLAGS_WHITELIST)) && (!sockaddr_storage_sameip(own_addr,addr_filtered)))
if((rsBanList!=NULL && !rsBanList->isAddressAccepted(addr_filtered,RSBANLIST_CHECKING_FLAGS_WHITELIST)) && (!sockaddr_storage_sameip(own_addr,addr_filtered)))
{
std::cerr << " Peer " << from << " reports a connection address (" << sockaddr_storage_iptostring(addr_filtered) <<") that is not your current external address (" << sockaddr_storage_iptostring(own_addr) << "). This is weird." << std::endl;
@ -1632,6 +1651,8 @@ bool p3PeerMgrIMPL::updateAddressList(const RsPeerId& id, const pqiIpAddrSet
cleanIpList(clean_set.mExt.mAddrs,id,mLinkMgr) ;
cleanIpList(clean_set.mLocal.mAddrs,id,mLinkMgr) ;
bool am_I_a_hidden_node = isHiddenNode(getOwnId()) ;
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
/* check if it is our own ip */
@ -1655,7 +1676,12 @@ bool p3PeerMgrIMPL::updateAddressList(const RsPeerId& id, const pqiIpAddrSet
}
/* "it" points to peer */
it->second.ipAddrs.updateAddrs(clean_set);
if(!am_I_a_hidden_node)
it->second.ipAddrs.updateAddrs(clean_set);
else
it->second.ipAddrs.clear();
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::setLocalAddress() Updated Address for: " << id;
std::cerr << std::endl;
@ -2173,6 +2199,7 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
#endif
RsPeerId ownId = getOwnId();
bool am_I_a_hidden_node = isHiddenNode(ownId) ;
/* load the list of peers */
std::list<RsItem *>::iterator it;
@ -2220,16 +2247,20 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
}
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);
if(!am_I_a_hidden_node) // clear IPs if w're a hidden node. Friend's clear node IPs where previously sent.
{
setLocalAddress(peer_id, pitem->localAddrV4.addr);
setExtAddress(peer_id, pitem->extAddrV4.addr);
setDynDNS (peer_id, pitem->dyndns);
/* convert addresses */
addrs.mLocal.extractFromTlv(pitem->localAddrList);
addrs.mExt.extractFromTlv(pitem->extAddrList);
}
updateAddressList(peer_id, addrs);
}
delete(*it);
@ -2774,7 +2805,7 @@ bool p3PeerMgrIMPL::removeBannedIps()
if(cleanIpList(it->second.ipAddrs.mExt.mAddrs,it->first,mLinkMgr)) changed = true ;
if(cleanIpList(it->second.ipAddrs.mLocal.mAddrs,it->first,mLinkMgr)) changed = true ;
if(!rsBanList->isAddressAccepted(it->second.serveraddr,RSBANLIST_CHECKING_FLAGS_BLACKLIST))
if(rsBanList!=NULL && !rsBanList->isAddressAccepted(it->second.serveraddr,RSBANLIST_CHECKING_FLAGS_BLACKLIST))
{
sockaddr_storage_clear(it->second.serveraddr) ;
std::cerr << "(SS) Peer " << it->first << " has a banned server address. Wiping it out." << std::endl;

View file

@ -171,6 +171,7 @@ virtual bool setVisState(const RsPeerId &id, uint16_t vs_disc, uint16_t vs_dht)
virtual bool setLocation(const RsPeerId &pid, const std::string &location) = 0;
virtual bool setHiddenDomainPort(const RsPeerId &id, const std::string &domain_addr, const uint16_t domain_port) = 0;
virtual bool isHiddenNode(const RsPeerId& id) = 0 ;
virtual bool updateCurrentAddress(const RsPeerId& id, const pqiIpAddress &addr) = 0;
virtual bool updateLastContact(const RsPeerId& id) = 0;
@ -284,6 +285,7 @@ public:
virtual bool setLocation(const RsPeerId &pid, const std::string &location);
virtual bool setHiddenDomainPort(const RsPeerId &id, const std::string &domain_addr, const uint16_t domain_port);
virtual bool isHiddenNode(const RsPeerId& id);
virtual bool updateCurrentAddress(const RsPeerId& id, const pqiIpAddress &addr);
virtual bool updateLastContact(const RsPeerId& id);

View file

@ -29,7 +29,7 @@
#include "util/rsnet.h"
#include "serialiser/rstlvaddrs.h"
#define MAX_ADDRESS_LIST_SIZE 4
#define MAX_ADDRESS_LIST_SIZE 10
class pqiIpAddress
{
@ -68,6 +68,12 @@ class pqiIpAddrSet
void printAddrs(std::string &out) const;
pqiIpAddrList mLocal;
pqiIpAddrList mExt;
void clear()
{
mLocal.mAddrs.clear();
mExt.mAddrs.clear();
}
};

View file

@ -4,7 +4,9 @@
#include "pqi/pqinetstatebox.h"
#include "time.h"
#ifdef RS_USE_BITDHT
#include "bitdht/bdiface.h"
#endif
// External Interface.

View file

@ -3,7 +3,8 @@
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 by Robert Fernie.
* Copyright (C) 2004-2006 Robert Fernie.
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -284,7 +285,7 @@ int inet_aton(const char *name, struct in_addr *addr)
# include <net/if.h>
#endif // WINDOWS_SYS
bool getLocalAddresses(std::list<sockaddr_storage> & addrs)
bool getLocalAddresses(std::vector<sockaddr_storage>& addrs)
{
addrs.clear();

View file

@ -3,7 +3,8 @@
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 by Robert Fernie.
* Copyright (C) 2004-2006 Robert Fernie.
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -24,10 +25,10 @@
*/
#ifndef MRK_PQI_NETWORKING_HEADER
#define MRK_PQI_NETWORKING_HEADER
#include <vector>
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
@ -95,7 +96,7 @@ void showSocketError(std::string &out);
std::string socket_errorType(int err);
bool getLocalAddresses(std::list<struct sockaddr_storage> & addrs);
bool getLocalAddresses(std::vector<sockaddr_storage> & addrs);
/* universal socket interface */

View file

@ -1321,14 +1321,14 @@ int pqissl::Authorise_SSL_Connection()
if (rsPeers->servicePermissionFlags(PeerId()) & RS_NODE_PERM_REQUIRE_WL)
checking_flags |= RSBANLIST_CHECKING_FLAGS_WHITELIST;
if(!rsBanList->isAddressAccepted(remote_addr,checking_flags,&check_result))
if(rsBanList!=NULL && !rsBanList->isAddressAccepted(remote_addr,checking_flags,&check_result))
{
std::cerr << "(SS) refusing connection attempt from IP address " << sockaddr_storage_iptostring(remote_addr) << ". Reason: " <<
std::cerr << "(SS) refusing connection attempt from IP address " << sockaddr_storage_iptostring(remote_addr) << ". Reason: " <<
((check_result == RSBANLIST_CHECK_RESULT_NOT_WHITELISTED)?"not whitelisted (peer requires whitelist)":"blacklisted") << std::endl;
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_IP_BLACKLISTED, PeerId().toStdString(), sockaddr_storage_iptostring(remote_addr), "", "", check_result);
reset_locked();
return 0 ;
reset_locked();
return 0 ;
}
// check it's the right one.
if (certCorrect)
@ -1371,12 +1371,12 @@ int pqissl::accept_locked(SSL *ssl, int fd, const struct sockaddr_storage &forei
if (rsPeers->servicePermissionFlags(PeerId()) & RS_NODE_PERM_REQUIRE_WL)
checking_flags |= RSBANLIST_CHECKING_FLAGS_WHITELIST;
if(!rsBanList->isAddressAccepted(foreign_addr,checking_flags,&check_result))
if(rsBanList!=NULL && !rsBanList->isAddressAccepted(foreign_addr,checking_flags,&check_result))
{
std::cerr << "(SS) refusing incoming SSL connection from blacklisted foreign address " << sockaddr_storage_iptostring(foreign_addr)
<< ". Reason: " << check_result << "." << std::endl;
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_IP_BLACKLISTED, PeerId().toStdString(), sockaddr_storage_iptostring(foreign_addr), "", "", check_result);
reset_locked();
reset_locked();
return -1;
}
if (waiting != WAITING_NOT)

View file

@ -36,6 +36,9 @@ static struct RsLog::logInfo pqipersongrpzoneInfo = {RsLog::Default, "pqipersong
/****
* #define PQI_DISABLE_UDP 1
***/
#ifdef RETROTOR
#define PQI_DISABLE_UDP 1
#endif
/********************************** SSL Specific features ***************************/

View file

@ -35,6 +35,7 @@
#include "util/rsdebug.h"
#include "util/rsnet.h"
#include "util/rstime.h"
#include "util/rsstring.h"
#include "pqi/p3linkmgr.h"
@ -571,7 +572,7 @@ bool pqissludp::moretoread(uint32_t usec)
{
return true;
}
usleep(usec);
rstime::rs_usleep(usec);
}
/* check for more to read first ... if nothing... check error
@ -655,7 +656,7 @@ bool pqissludp::cansend(uint32_t usec)
return true;
}
usleep(usec);
rstime::rs_usleep(usec);
}
rslog(RSL_DEBUG_ALL, pqissludpzone,

View file

@ -24,6 +24,7 @@
*/
#include "util/rstime.h"
#include "pqi/pqithreadstreamer.h"
#include <unistd.h>
@ -69,7 +70,7 @@ void pqithreadstreamer::data_tick()
if (!isactive)
{
usleep(DEFAULT_STREAMER_IDLE_SLEEP);
rstime::rs_usleep(DEFAULT_STREAMER_IDLE_SLEEP);
return ;
}
@ -92,7 +93,7 @@ void pqithreadstreamer::data_tick()
if (sleep_period)
{
usleep(sleep_period);
rstime::rs_usleep(sleep_period);
}
}

View file

@ -368,6 +368,7 @@ public:
virtual bool setHiddenNode(const RsPeerId &id, const std::string &hidden_node_address) = 0;
virtual bool setHiddenNode(const RsPeerId &id, const std::string &address, uint16_t port) = 0;
virtual bool isHiddenNode(const RsPeerId &id) = 0;
virtual bool setLocalAddress(const RsPeerId &ssl_id, const std::string &addr, uint16_t port) = 0;
virtual bool setExtAddress( const RsPeerId &ssl_id, const std::string &addr, uint16_t port) = 0;

View file

@ -52,13 +52,20 @@ struct TurtleFileInfo
std::string name ;
uint64_t size ;
};
struct TurtleRequestDisplayInfo
struct TurtleTunnelRequestDisplayInfo
{
uint32_t request_id ; // Id of the request
RsPeerId source_peer_id ; // Peer that relayed the request
uint32_t age ; // Age in seconds
uint32_t depth ; // Depth of the request. Might be altered.
uint32_t request_id ; // Id of the request
RsPeerId source_peer_id ; // Peer that relayed the request
uint32_t age ; // Age in seconds
uint32_t depth ; // Depth of the request. Might be altered.
};
struct TurtleSearchRequestDisplayInfo
{
uint32_t request_id ; // Id of the request
RsPeerId source_peer_id ; // Peer that relayed the request
uint32_t age ; // Age in seconds
uint32_t depth ; // Depth of the request. Might be altered.
uint32_t hits ;
std::string keywords;
};
@ -135,7 +142,7 @@ class RsTurtle
// Get info from the turtle router. I use std strings to hide the internal structs.
//
virtual void getInfo(std::vector<std::vector<std::string> >&,std::vector<std::vector<std::string> >&,
std::vector<TurtleRequestDisplayInfo>&,std::vector<TurtleRequestDisplayInfo>&) const = 0;
std::vector<TurtleSearchRequestDisplayInfo>&,std::vector<TurtleTunnelRequestDisplayInfo>&) const = 0;
// Get info about turtle traffic. See TurtleTrafficStatisticsInfo members for details.
//

View file

@ -208,7 +208,7 @@ class FileInfo
uint64_t transfered;
double tfRate; /* in kbytes */
uint32_t downloadStatus; // FT_STATE_DOWNLOADING & co. See rstypes.h
std::list<TransferInfo> peers;
std::vector<TransferInfo> peers;
DwlSpeed priority ;
time_t lastTS;

View file

@ -1,6 +1,6 @@
#define RS_MAJOR_VERSION 0
#define RS_MINOR_VERSION 6
#define RS_BUILD_NUMBER 3
#define RS_BUILD_NUMBER 4
#define RS_BUILD_NUMBER_ADD "" // <-- do we need this?
// The revision number should be the 4 first bytes of the git revision hash, which is obtained using:
// git log --pretty="%H" | head -1 | cut -c1-8

View file

@ -1,6 +1,6 @@
#define RS_MAJOR_VERSION 0
#define RS_MINOR_VERSION 6
#define RS_BUILD_NUMBER 3
#define RS_BUILD_NUMBER 4
#define RS_BUILD_NUMBER_ADD ""
// The revision number should be the 4 first bytes of the git revision hash, which is obtained using:

View file

@ -84,6 +84,9 @@ const uint16_t RS_SERVICE_GXS_TYPE_REPUTATION = 0x0219;
const uint16_t RS_SERVICE_TYPE_GXS_RECOGN = 0x0220;
const uint16_t RS_SERVICE_TYPE_GXS_TRANS = 0x0230;
const uint16_t RS_SERVICE_GXS_TYPE_FORUMS_CONFIG = 0x0315;
const uint16_t RS_SERVICE_GXS_TYPE_CHANNELS_CONFIG = 0x0317;
// Experimental Services.
/* DSDV Testing at the moment - Service Only */
const uint16_t RS_SERVICE_TYPE_DSDV = 0x1010;

View file

@ -25,6 +25,7 @@
*/
#include "util/rstime.h"
#include "rsserver/p3face.h"
#include "retroshare/rsplugin.h"
@ -134,11 +135,7 @@ RsServer::~RsServer()
/* Thread Fn: Run the Core */
void RsServer::data_tick()
{
#ifndef WINDOWS_SYS
usleep((int) (mTimeDelta * 1000000));
#else
Sleep((int) (mTimeDelta * 1000));
#endif
rstime::rs_usleep(mTimeDelta * 1000000);
double ts = getCurrentTS();
double delta = ts - mLastts;

View file

@ -882,6 +882,11 @@ bool p3Peers::setHiddenNode(const RsPeerId &id, const std::string &hidden_node_
}
bool p3Peers::isHiddenNode(const RsPeerId &id)
{
return mPeerMgr->isHiddenNode(id) ;
}
bool p3Peers::setHiddenNode(const RsPeerId &id, const std::string &address, uint16_t port)
{
#ifdef P3PEERS_DEBUG

View file

@ -94,6 +94,7 @@ public:
virtual bool setLocation(const RsPeerId &ssl_id, const std::string &location);//location is shown in the gui to differentiate ssl certs
virtual bool setHiddenNode(const RsPeerId &id, const std::string &hidden_node_address);
virtual bool setHiddenNode(const RsPeerId &id, const std::string &address, uint16_t port);
virtual bool isHiddenNode(const RsPeerId &id);
virtual bool setLocalAddress(const RsPeerId &id, const std::string &addr, uint16_t port);
virtual bool setExtAddress(const RsPeerId &id, const std::string &addr, uint16_t port);

View file

@ -71,8 +71,11 @@ RsAccountsDetail::RsAccountsDetail() : mAccountsLocked(false), mPreferredId("")
bool RsAccountsDetail::loadAccounts()
{
int failing_accounts ;
getAvailableAccounts(mAccounts,failing_accounts,mUnsupportedKeys);
#ifdef RETROTOR
getAvailableAccounts(mAccounts,failing_accounts,mUnsupportedKeys,true);
#else
getAvailableAccounts(mAccounts,failing_accounts,mUnsupportedKeys,false);
#endif
loadPreferredAccount();
checkPreferredId();
@ -512,7 +515,7 @@ bool RsAccountsDetail::getAccountOptions(bool &ishidden, bool &isFirstTimeRun)
/* directories with valid certificates in the expected location */
bool RsAccountsDetail::getAvailableAccounts(std::map<RsPeerId, AccountDetails> &accounts,int& failing_accounts,std::map<std::string,std::vector<std::string> >& unsupported_keys)
bool RsAccountsDetail::getAvailableAccounts(std::map<RsPeerId, AccountDetails> &accounts,int& failing_accounts,std::map<std::string,std::vector<std::string> >& unsupported_keys,bool hidden_only)
{
failing_accounts = 0 ;
/* get the directories */
@ -615,6 +618,9 @@ bool RsAccountsDetail::getAvailableAccounts(std::map<RsPeerId, AccountDetails> &
continue;
}
if(hidden_only && !hidden_location)
continue ;
if(valid_prefix && isHexaString(lochex) && (lochex).length() == 32)
{
std::string accountdir = mBaseDirectory + "/" + *it;

View file

@ -142,9 +142,9 @@ class RsAccountsDetail
static bool defaultBaseDirectory();
bool getAvailableAccounts(std::map<RsPeerId, AccountDetails> &accounts,
bool getAvailableAccounts(std::map<RsPeerId, AccountDetails> &accounts,
int& failing_accounts,
std::map<std::string,std::vector<std::string> >& unsupported_keys);
std::map<std::string,std::vector<std::string> >& unsupported_keys, bool hidden_only=false);
bool setupAccount(const std::string& accountdir);

View file

@ -35,6 +35,11 @@
#include "util/rswin.h"
#endif
#ifdef __ANDROID__
# include <QFile> // To install bdboot.txt
# include <QString> // for String::fromStdString(...)
#endif
#include "util/argstream.h"
#include "util/rsdebug.h"
#include "util/rsdir.h"
@ -65,6 +70,11 @@
#include <sys/param.h>
#endif
// This needs to be defined here, because when USE_BITDHT is unset, the variable, that is defined in libbitdht (not compiled!) will be missing.
#ifndef RS_USE_BITDHT
RsDht *rsDht = NULL ;
#endif
// for blocking signals
#include <signal.h>
@ -825,9 +835,10 @@ RsGRouter *rsGRouter = NULL ;
#include "pqi/p3linkmgr.h"
#include "pqi/p3netmgr.h"
#ifndef RETROTOR
#include "tcponudp/tou.h"
#include "tcponudp/rsudpstack.h"
#endif
#ifdef RS_USE_BITDHT
@ -1042,7 +1053,32 @@ int RsServer::StartupRetroShare()
uint64_t tmp_size ;
if (!RsDirUtil::checkFile(bootstrapfile,tmp_size,true))
{
std::cerr << "DHT bootstrap file not in ConfigDir: " << bootstrapfile << std::endl;
std::cerr << "DHT bootstrap file not in ConfigDir: " << bootstrapfile
<< std::endl;
#ifdef __ANDROID__
QFile bdbootRF("assets:/values/bdboot.txt");
if(!bdbootRF.open(QIODevice::ReadOnly | QIODevice::Text))
std::cerr << __PRETTY_FUNCTION__
<< " bdbootRF(assets:/values/bdboot.txt).open(...) fail: "
<< bdbootRF.errorString().toStdString() << std::endl;
else
{
QFile bdbootCF(QString::fromStdString(bootstrapfile));
if(!bdbootCF.open(QIODevice::WriteOnly | QIODevice::Text))
std::cerr << __PRETTY_FUNCTION__ << " bdbootCF("
<< bootstrapfile << ").open(...) fail: "
<< bdbootRF.errorString().toStdString() << std::endl;
else
{
bdbootCF.write(bdbootRF.readAll());
bdbootCF.close();
std::cerr << "Installed DHT bootstrap file not in ConfigDir: "
<< bootstrapfile << std::endl;
}
bdbootRF.close();
}
#else
std::string installfile = rsAccounts->PathDataDirectory();
installfile += "/";
installfile += BITDHT_BOOTSTRAP_FILENAME;
@ -1064,6 +1100,7 @@ int RsServer::StartupRetroShare()
{
std::cerr << "No Installation DHT bootstrap file to copy" << std::endl;
}
#endif // def __ANDROID__
}
/* construct the rest of the stack, important to build them in the correct order! */
@ -1155,9 +1192,9 @@ int RsServer::StartupRetroShare()
#ifdef RS_USE_DHT_STUNNER
mNetMgr->setAddrAssist(new stunAddrAssist(mDhtStunner), new stunAddrAssist(mProxyStunner));
#endif // RS_USE_DHT_STUNNER
#else //RS_USE_BITDHT
/* install NULL Pointer for rsDht Interface */
rsDht = NULL;
// #else //RS_USE_BITDHT
// /* install NULL Pointer for rsDht Interface */
// rsDht = NULL;
#endif //RS_USE_BITDHT
@ -1474,7 +1511,11 @@ int RsServer::StartupRetroShare()
interfaces.mMsgs = rsMsgs;
interfaces.mTurtle = rsTurtle;
interfaces.mDisc = rsDisc;
#ifdef RS_USE_BITDHT
interfaces.mDht = rsDht;
#else
interfaces.mDht = NULL;
#endif
interfaces.mNotify = mNotify;
interfaces.mServiceControl = serviceCtrl;
interfaces.mPluginHandler = mPluginsManager;
@ -1508,10 +1549,17 @@ int RsServer::StartupRetroShare()
#endif
// new services to test.
#ifndef RETROTOR
p3BanList *mBanList = new p3BanList(serviceCtrl, mNetMgr);
rsBanList = mBanList ;
pqih -> addService(mBanList, true);
#else
rsBanList = NULL ;
#endif
#ifdef RS_USE_BITDHT
mBitDht->setupPeerSharer(mBanList);
#endif
p3BandwidthControl *mBwCtrl = new p3BandwidthControl(pqih);
pqih -> addService(mBwCtrl, true);
@ -1577,7 +1625,9 @@ int RsServer::StartupRetroShare()
mConfigMgr->addConfiguration("p3History.cfg", mHistoryMgr);
mConfigMgr->addConfiguration("p3Status.cfg", mStatusSrv);
mConfigMgr->addConfiguration("turtle.cfg", tr);
#ifndef RETROTOR
mConfigMgr->addConfiguration("banlist.cfg", mBanList);
#endif
mConfigMgr->addConfiguration("servicecontrol.cfg", serviceCtrl);
mConfigMgr->addConfiguration("reputations.cfg", mReputations);
#ifdef ENABLE_GROUTER
@ -1599,7 +1649,9 @@ int RsServer::StartupRetroShare()
mConfigMgr->addConfiguration("identity.cfg", gxsid_ns);
mConfigMgr->addConfiguration("gxsforums.cfg", gxsforums_ns);
mConfigMgr->addConfiguration("gxsforums_srv.cfg", mGxsForums);
mConfigMgr->addConfiguration("gxschannels.cfg", gxschannels_ns);
mConfigMgr->addConfiguration("gxschannels_srv.cfg", mGxsChannels);
mConfigMgr->addConfiguration("gxscircles.cfg", gxscircles_ns);
mConfigMgr->addConfiguration("posted.cfg", posted_ns);
#ifdef RS_USE_WIKI

View file

@ -8,6 +8,7 @@
#include "util/radix32.h"
#include "util/radix64.h"
#include "util/rsdebug.h"
#include "util/rstime.h"
#include "util/rsprint.h"
#include "util/rsrandom.h"
@ -39,7 +40,7 @@ static struct RsLog::logInfo i2pBobLogInfo = {RsLog::Default, "p3I2pBob"};
static const time_t selfCheckPeroid = 30;
void doSleep(useconds_t timeToSleepMS) {
usleep((useconds_t) (timeToSleepMS * 1000));
rstime::rs_usleep((useconds_t) (timeToSleepMS * 1000));
}
p3I2pBob::p3I2pBob(p3PeerMgr *peerMgr)

View file

@ -1,6 +1,7 @@
#include "rsautoproxymonitor.h"
#include <unistd.h> /* for usleep() */
#include "util/rstime.h"
rsAutoProxyMonitor *rsAutoProxyMonitor::mInstance = NULL;
@ -93,7 +94,7 @@ void rsAutoProxyMonitor::stopAllRSShutdown()
// wait for shutdown of all services
uint32_t t = 0, timeout = 15;
do {
usleep(1000 * 1000);
rstime::rs_usleep(1000 * 1000);
RS_STACK_MUTEX(mLock);
std::cout << "(II) waiting for auto proxy service(s) to shut down " << t << "/" << timeout << " (remaining: " << mProxies.size() << ")" << std::endl;
if (mProxies.empty())

View file

@ -3,7 +3,8 @@
*
* Services for RetroShare.
*
* Copyright 2004-2013 by Robert Fernie.
* Copyright (C) 2004-2013 Robert Fernie.
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -25,11 +26,15 @@
#include "services/p3discovery2.h"
#include "pqi/p3peermgr.h"
#include "pqi/pqinetwork.h" // for getLocalAddresses
#include "util/rsversioninfo.h"
#include "retroshare/rsiface.h"
#include "rsserver/p3face.h"
#include <vector> // for std::vector
#include <algorithm> // for std::random_shuffle
// Interface pointer.
RsDisc *rsDisc = NULL;
@ -38,7 +43,9 @@ RsDisc *rsDisc = NULL;
* #define P3DISC_DEBUG 1
****/
bool populateContactInfo(const peerState &detail, RsDiscContactItem *pkt)
static bool populateContactInfo( const peerState &detail,
RsDiscContactItem *pkt,
bool include_ip_information )
{
pkt->clear();
@ -62,14 +69,24 @@ bool populateContactInfo(const peerState &detail, RsDiscContactItem *pkt)
{
pkt->isHidden = false;
pkt->localAddrV4.addr = detail.localaddr;
pkt->extAddrV4.addr = detail.serveraddr;
sockaddr_storage_clear(pkt->localAddrV6.addr);
sockaddr_storage_clear(pkt->extAddrV6.addr);
if(include_ip_information)
{
pkt->localAddrV4.addr = detail.localaddr;
pkt->extAddrV4.addr = detail.serveraddr;
sockaddr_storage_clear(pkt->localAddrV6.addr);
sockaddr_storage_clear(pkt->extAddrV6.addr);
pkt->dyndns = detail.dyndns;
detail.ipAddrs.mLocal.loadTlv(pkt->localAddrList);
detail.ipAddrs.mExt.loadTlv(pkt->extAddrList);
pkt->dyndns = detail.dyndns;
detail.ipAddrs.mLocal.loadTlv(pkt->localAddrList);
detail.ipAddrs.mExt.loadTlv(pkt->extAddrList);
}
else
{
sockaddr_storage_clear(pkt->localAddrV6.addr);
sockaddr_storage_clear(pkt->extAddrV6.addr);
sockaddr_storage_clear(pkt->localAddrV4.addr);
sockaddr_storage_clear(pkt->extAddrV4.addr);
}
}
return true;
@ -331,12 +348,57 @@ void p3discovery2::sendOwnContactInfo(const SSLID &sslid)
std::cerr << std::endl;
#endif
peerState detail;
if (mPeerMgr->getOwnNetStatus(detail))
if (mPeerMgr->getOwnNetStatus(detail))
{
RsDiscContactItem *pkt = new RsDiscContactItem();
populateContactInfo(detail, pkt);
pkt->version = RsUtil::retroshareVersion();
/* Workaround to spread multiple local ip addresses when presents. This
* is needed because RS wrongly assumes that there is just one active
* local ip address at time. */
std::vector<sockaddr_storage> addrs;
if(!detail.hiddenNode && getLocalAddresses(addrs))
{
/* To work around MAX_ADDRESS_LIST_SIZE addresses limitation,
* let's shuffle the list of
* local addresses in the hope that with enough time every local
* address is advertised to trusted nodes so they may try to
* connect to all of them including the most convenient if a local
* connection exists.*/
std::random_shuffle(addrs.begin(), addrs.end());
for (auto it = addrs.begin(); it!=addrs.end(); ++it)
{
sockaddr_storage& addr(*it);
if( sockaddr_storage_isValidNet(addr) &&
!sockaddr_storage_isLoopbackNet(addr) &&
!sockaddr_storage_sameip(addr, detail.localaddr) )
{
pqiIpAddress pqiIp;
sockaddr_storage_clear(pqiIp.mAddr);
pqiIp.mAddr.ss_family = addr.ss_family;
sockaddr_storage_copyip(pqiIp.mAddr, addr);
sockaddr_storage_setport(
pqiIp.mAddr,
sockaddr_storage_port(detail.localaddr) );
pqiIp.mSeenTime = time(nullptr);
pqiIp.mSrc = 0;
detail.ipAddrs.updateLocalAddrs(pqiIp);
}
}
}
RsDiscContactItem *pkt = new RsDiscContactItem();
/* Cyril: we dont send our own IP to an hidden node. It will not use it
* anyway. */
populateContactInfo(detail, pkt, !rsPeers->isHiddenNode(sslid));
/* G10h4ck: sending IP information also to hidden nodes has proven very
* helpful in the usecase of non hidden nodes, that share a common
* hidden trusted node, to discover each other IP.
* Advanced/corner case non hidden node users that want to hide their
* IP to a specific hidden ~trusted~ node can do it through the
* permission matrix. Disabling this instead will make life more
* difficult for average user, that moreover whould have no way to
* revert an hardcoded policy. */
//populateContactInfo(detail, pkt, true);
pkt->version = RsUtil::retroshareVersion();
pkt->PeerId(sslid);
#ifdef P3DISC_DEBUG
@ -372,6 +434,7 @@ void p3discovery2::recvOwnContactInfo(const SSLID &fromId, const RsDiscContactIt
mPeerMgr->setVisState(fromId, item->vs_disc, item->vs_dht);
setPeerVersion(fromId, item->version);
updatePeerAddresses(item);
// This information will be sent out to online peers, at the receipt of their PGPList.
@ -423,13 +486,11 @@ void p3discovery2::recvOwnContactInfo(const SSLID &fromId, const RsDiscContactIt
void p3discovery2::updatePeerAddresses(const RsDiscContactItem *item)
{
if (item->isHidden)
{
mPeerMgr->setHiddenDomainPort(item->sslId, item->hiddenAddr, item->hiddenPort);
}
mPeerMgr->setHiddenDomainPort(item->sslId, item->hiddenAddr,
item->hiddenPort);
else
{
mPeerMgr->setDynDNS(item->sslId, item->dyndns);
mPeerMgr->setDynDNS(item->sslId, item->dyndns);
updatePeerAddressList(item);
}
}
@ -440,8 +501,19 @@ void p3discovery2::updatePeerAddressList(const RsDiscContactItem *item)
if (item->isHidden)
{
}
else
else if(!mPeerMgr->isHiddenNode(rsPeers->getOwnId()))
{
/* Cyril: we don't store IP addresses if we're a hidden node.
* Normally they should not be sent to us, except for old peers. */
/* G10h4ck: sending IP information also to hidden nodes has proven very
* helpful in the usecase of non hidden nodes, that share a common
* hidden trusted node, to discover each other IP.
* Advanced/corner case non hidden node users that want to hide their
* IP to a specific hidden ~trusted~ node can do it through the
* permission matrix. Disabling this instead will make life more
* difficult for average user, that moreover whould have no way to
* revert an hardcoded policy. */
pqiIpAddrSet addrsFromPeer;
addrsFromPeer.mLocal.extractFromTlv(item->localAddrList);
addrsFromPeer.mExt.extractFromTlv(item->extAddrList);
@ -464,13 +536,12 @@ void p3discovery2::updatePeerAddressList(const RsDiscContactItem *item)
void p3discovery2::sendPGPList(const SSLID &toId)
{
updatePgpFriendList();
RsStackMutex stack(mDiscMtx); /********** STACK LOCKED MTX ******/
RS_STACK_MUTEX(mDiscMtx);
#ifdef P3DISC_DEBUG
std::cerr << "p3discovery2::sendPGPList() to " << toId;
std::cerr << std::endl;
std::cerr << "p3discovery2::sendPGPList() to " << toId << std::endl;
#endif
RsDiscPgpListItem *pkt = new RsDiscPgpListItem();
@ -501,7 +572,7 @@ void p3discovery2::updatePgpFriendList()
std::cerr << std::endl;
#endif
RsStackMutex stack(mDiscMtx); /********** STACK LOCKED MTX ******/
RS_STACK_MUTEX(mDiscMtx);
#define PGP_MAX_UPDATE_PERIOD 300
@ -817,7 +888,7 @@ void p3discovery2::sendContactInfo_locked(const PGPID &aboutId, const SSLID &toI
if (mPeerMgr->getFriendNetStatus(sit->first, detail))
{
RsDiscContactItem *pkt = new RsDiscContactItem();
populateContactInfo(detail, pkt);
populateContactInfo(detail, pkt,!mPeerMgr->isHiddenNode(toId));// never send IPs to an hidden node. The node will not use them anyway.
pkt->PeerId(toId);
// send to each peer its own connection address.
@ -856,26 +927,20 @@ void p3discovery2::sendContactInfo_locked(const PGPID &aboutId, const SSLID &toI
void p3discovery2::processContactInfo(const SSLID &fromId, const RsDiscContactItem *item)
{
RsStackMutex stack(mDiscMtx); /********** STACK LOCKED MTX ******/
(void) fromId; // remove unused parameter warnings, debug only
RS_STACK_MUTEX(mDiscMtx);
if (item->sslId == rsPeers->getOwnId())
{
if(sockaddr_storage_isExternalNet(item->currentConnectAddress.addr))
mPeerMgr->addCandidateForOwnExternalAddress(item->PeerId(), item->currentConnectAddress.addr) ;
#ifdef P3DISC_DEBUG
std::cerr << "p3discovery2::processContactInfo(" << fromId << ") PGPID: ";
std::cerr << item->pgpId << " Ignoring Info on self";
std::cerr << std::endl;
#else
/* remove unused parameter warnings */
(void) fromId;
#endif
delete item;
{
if(sockaddr_storage_isExternalNet(item->currentConnectAddress.addr))
mPeerMgr->addCandidateForOwnExternalAddress(
item->PeerId(), item->currentConnectAddress.addr);
delete item;
return;
}
/* */
std::map<PGPID, DiscPgpInfo>::iterator it;
it = mFriendList.find(item->pgpId);
if (it == mFriendList.end())
@ -888,7 +953,8 @@ void p3discovery2::processContactInfo(const SSLID &fromId, const RsDiscContactIt
std::cerr << std::endl;
#endif
/* THESE ARE OUR FRIEND OF FRIENDS ... pass this information along to NetMgr & DHT...
/* THESE ARE OUR FRIEND OF FRIENDS ... pass this information along to
* NetMgr & DHT...
* as we can track FOF and use them as potential Proxies / Relays
*/
@ -934,7 +1000,10 @@ void p3discovery2::processContactInfo(const SSLID &fromId, const RsDiscContactIt
// set last seen to RS_PEER_OFFLINE_NO_DISC minus 1 so that it won't be shared with other friends
// until a first connection is established
mPeerMgr->addFriend(item->sslId, item->pgpId, item->netMode, RS_VS_DISC_OFF, RS_VS_DHT_FULL, time(NULL) - RS_PEER_OFFLINE_NO_DISC - 1, RS_NODE_PERM_ALL);
mPeerMgr->addFriend( item->sslId, item->pgpId, item->netMode,
RS_VS_DISC_OFF, RS_VS_DHT_FULL,
time(NULL) - RS_PEER_OFFLINE_NO_DISC - 1,
RS_NODE_PERM_ALL );
updatePeerAddresses(item);
}
}

View file

@ -120,6 +120,92 @@ uint32_t p3GxsChannels::channelsAuthenPolicy()
return policy;
}
static const uint32_t GXS_CHANNELS_CONFIG_MAX_TIME_NOTIFY_STORAGE = 86400*30*2 ; // ignore notifications for 2 months
static const uint8_t GXS_CHANNELS_CONFIG_SUBTYPE_NOTIFY_RECORD = 0x01 ;
struct RsGxsForumNotifyRecordsItem: public RsItem
{
RsGxsForumNotifyRecordsItem()
: RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_GXS_TYPE_CHANNELS_CONFIG,GXS_CHANNELS_CONFIG_SUBTYPE_NOTIFY_RECORD)
{}
virtual ~RsGxsForumNotifyRecordsItem() {}
void serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx )
{
RS_REGISTER_SERIAL_MEMBER(records);
}
void clear() {}
std::map<RsGxsGroupId,time_t> records;
};
class GxsChannelsConfigSerializer : public RsServiceSerializer
{
public:
GxsChannelsConfigSerializer() : RsServiceSerializer(RS_SERVICE_GXS_TYPE_CHANNELS_CONFIG) {}
virtual ~GxsChannelsConfigSerializer() {}
RsItem* create_item(uint16_t service_id, uint8_t item_sub_id) const
{
if(service_id != RS_SERVICE_GXS_TYPE_CHANNELS_CONFIG)
return NULL;
switch(item_sub_id)
{
case GXS_CHANNELS_CONFIG_SUBTYPE_NOTIFY_RECORD: return new RsGxsForumNotifyRecordsItem();
default:
return NULL;
}
}
};
bool p3GxsChannels::saveList(bool &cleanup, std::list<RsItem *>&saveList)
{
cleanup = true ;
RsGxsForumNotifyRecordsItem *item = new RsGxsForumNotifyRecordsItem ;
item->records = mKnownChannels ;
saveList.push_back(item) ;
return true;
}
bool p3GxsChannels::loadList(std::list<RsItem *>& loadList)
{
while(!loadList.empty())
{
RsItem *item = loadList.front();
loadList.pop_front();
time_t now = time(NULL);
RsGxsForumNotifyRecordsItem *fnr = dynamic_cast<RsGxsForumNotifyRecordsItem*>(item) ;
if(fnr != NULL)
{
mKnownChannels.clear();
for(auto it(fnr->records.begin());it!=fnr->records.end();++it)
if( it->second + GXS_CHANNELS_CONFIG_MAX_TIME_NOTIFY_STORAGE < now)
mKnownChannels.insert(*it) ;
}
delete item ;
}
return true;
}
RsSerialiser* p3GxsChannels::setupSerialiser()
{
RsSerialiser* rss = new RsSerialiser;
rss->addSerialType(new GxsChannelsConfigSerializer());
return rss;
}
/** Overloaded to cache new groups **/
RsGenExchange::ServiceCreate_Return p3GxsChannels::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& /* keySet */)
@ -223,7 +309,7 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
if(mKnownChannels.find(*git) == mKnownChannels.end())
{
notify->AddFeedItem(RS_FEED_ITEM_CHANNEL_NEW, git->toStdString());
mKnownChannels.insert(*git) ;
mKnownChannels.insert(std::make_pair(*git,time(NULL))) ;
}
else
std::cerr << "(II) Not notifying already known channel " << *git << std::endl;

View file

@ -55,7 +55,7 @@ class SSGxsChannelGroup
class p3GxsChannels: public RsGenExchange, public RsGxsChannels,
public GxsTokenQueue,
public GxsTokenQueue, public p3Config,
public RsTickEvent /* only needed for testing - remove after */
{
public:
@ -68,6 +68,10 @@ virtual void service_tick();
protected:
virtual RsSerialiser* setupSerialiser(); // @see p3Config::setupSerialiser()
virtual bool saveList(bool &cleanup, std::list<RsItem *>&saveList); // @see p3Config::saveList(bool &cleanup, std::list<RsItem *>&)
virtual bool loadList(std::list<RsItem *>& loadList); // @see p3Config::loadList(std::list<RsItem *>&)
// Overloaded to cache new groups.
virtual RsGenExchange::ServiceCreate_Return service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet);
@ -218,7 +222,7 @@ bool generateGroup(uint32_t &token, std::string groupName);
RsGxsMessageId mGenThreadId;
p3GxsCommentService *mCommentService;
std::set<RsGxsGroupId> mKnownChannels;
std::map<RsGxsGroupId,time_t> mKnownChannels;
};
#endif

View file

@ -95,6 +95,91 @@ uint32_t p3GxsForums::forumsAuthenPolicy()
return policy;
}
static const uint32_t GXS_FORUMS_CONFIG_MAX_TIME_NOTIFY_STORAGE = 86400*30*2 ; // ignore notifications for 2 months
static const uint8_t GXS_FORUMS_CONFIG_SUBTYPE_NOTIFY_RECORD = 0x01 ;
struct RsGxsForumNotifyRecordsItem: public RsItem
{
RsGxsForumNotifyRecordsItem()
: RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_GXS_TYPE_FORUMS_CONFIG,GXS_FORUMS_CONFIG_SUBTYPE_NOTIFY_RECORD)
{}
virtual ~RsGxsForumNotifyRecordsItem() {}
void serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx )
{
RS_REGISTER_SERIAL_MEMBER(records);
}
void clear() {}
std::map<RsGxsGroupId,time_t> records;
};
class GxsForumsConfigSerializer : public RsServiceSerializer
{
public:
GxsForumsConfigSerializer() : RsServiceSerializer(RS_SERVICE_GXS_TYPE_FORUMS_CONFIG) {}
virtual ~GxsForumsConfigSerializer() {}
RsItem* create_item(uint16_t service_id, uint8_t item_sub_id) const
{
if(service_id != RS_SERVICE_GXS_TYPE_FORUMS_CONFIG)
return NULL;
switch(item_sub_id)
{
case GXS_FORUMS_CONFIG_SUBTYPE_NOTIFY_RECORD: return new RsGxsForumNotifyRecordsItem();
default:
return NULL;
}
}
};
bool p3GxsForums::saveList(bool &cleanup, std::list<RsItem *>&saveList)
{
cleanup = true ;
RsGxsForumNotifyRecordsItem *item = new RsGxsForumNotifyRecordsItem ;
item->records = mKnownForums ;
saveList.push_back(item) ;
return true;
}
bool p3GxsForums::loadList(std::list<RsItem *>& loadList)
{
while(!loadList.empty())
{
RsItem *item = loadList.front();
loadList.pop_front();
time_t now = time(NULL);
RsGxsForumNotifyRecordsItem *fnr = dynamic_cast<RsGxsForumNotifyRecordsItem*>(item) ;
if(fnr != NULL)
{
mKnownForums.clear();
for(auto it(fnr->records.begin());it!=fnr->records.end();++it)
if( it->second + GXS_FORUMS_CONFIG_MAX_TIME_NOTIFY_STORAGE < now)
mKnownForums.insert(*it) ;
}
delete item ;
}
return true;
}
RsSerialiser* p3GxsForums::setupSerialiser()
{
RsSerialiser* rss = new RsSerialiser;
rss->addSerialType(new GxsForumsConfigSerializer());
return rss;
}
void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
{
@ -145,7 +230,9 @@ void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
if(mKnownForums.find(*git) == mKnownForums.end())
{
notify->AddFeedItem(RS_FEED_ITEM_FORUM_NEW, git->toStdString());
mKnownForums.insert(*git) ;
mKnownForums.insert(std::make_pair(*git,time(NULL))) ;
IndicateConfigChanged();
}
else
std::cerr << "(II) Not notifying already known forum " << *git << std::endl;
@ -584,4 +671,3 @@ void p3GxsForums::handle_event(uint32_t event_type, const std::string &/*elabel*
break;
}
}

View file

@ -39,7 +39,7 @@
*
*/
class p3GxsForums: public RsGenExchange, public RsGxsForums,
class p3GxsForums: public RsGenExchange, public RsGxsForums, public p3Config,
public RsTickEvent /* only needed for testing - remove after */
{
public:
@ -58,6 +58,10 @@ virtual void notifyChanges(std::vector<RsGxsNotify*>& changes);
// Overloaded from RsTickEvent.
virtual void handle_event(uint32_t event_type, const std::string &elabel);
virtual RsSerialiser* setupSerialiser(); // @see p3Config::setupSerialiser()
virtual bool saveList(bool &cleanup, std::list<RsItem *>&saveList); // @see p3Config::saveList(bool &cleanup, std::list<RsItem *>&)
virtual bool loadList(std::list<RsItem *>& loadList); // @see p3Config::loadList(std::list<RsItem *>&)
public:
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsForumGroup> &groups);
@ -117,7 +121,7 @@ bool generateGroup(uint32_t &token, std::string groupName);
int mGenCount;
std::vector<ForumDummyRef> mGenRefs;
RsGxsMessageId mGenThreadId;
std::set<RsGxsGroupId> mKnownForums ;
std::map<RsGxsGroupId,time_t> mKnownForums ;
};

View file

@ -34,6 +34,7 @@
#include "util/rsstring.h"
#include "util/radix64.h"
#include "util/rsdir.h"
#include "util/rstime.h"
#include "crypto/hashstream.h"
#include "gxs/gxssecurity.h"
#include "retroshare/rspeers.h"
@ -1071,7 +1072,7 @@ bool p3IdService::signData(const uint8_t *data,uint32_t data_size,const RsGxsId&
#ifdef DEBUG_IDS
std::cerr << " Cannot get key. Waiting for caching. try " << i << "/6" << std::endl;
#endif
usleep(500 * 1000) ; // sleep for 500 msec.
rstime::rs_usleep(500 * 1000) ; // sleep for 500 msec.
}
else
break ;
@ -1110,7 +1111,7 @@ bool p3IdService::validateData(const uint8_t *data,uint32_t data_size,const RsTl
#ifdef DEBUG_IDS
std::cerr << " Cannot get key. Waiting for caching. try " << i << "/6" << std::endl;
#endif
if(force_load) usleep(500 * 1000) ; // sleep for 500 msec.
if(force_load) rstime::rs_usleep(500 * 1000) ; // sleep for 500 msec.
}
else
break ;
@ -1151,7 +1152,7 @@ bool p3IdService::encryptData( const uint8_t *decrypted_data,
if(getKey(encryption_key_id,encryption_key))
break ;
else
usleep(500*1000) ; // sleep half a sec.
rstime::rs_usleep(500*1000) ; // sleep half a sec.
if(encryption_key.keyId.isNull())
{
@ -1222,7 +1223,7 @@ bool p3IdService::encryptData( const uint8_t* decrypted_data,
}
if(keyNotYetFoundIds.empty()) break;
else usleep(500*1000);
else rstime::rs_usleep(500*1000);
}
if(!keyNotYetFoundIds.empty())
@ -1279,7 +1280,7 @@ bool p3IdService::decryptData( const uint8_t *encrypted_data,
int maxRounds = force_load ? 6 : 1;
for(int i=0; i<maxRounds ;++i)
if(getPrivateKey(key_id,encryption_key)) break;
else usleep(500*1000) ; // sleep half a sec.
else rstime::rs_usleep(500*1000) ; // sleep half a sec.
if(encryption_key.keyId.isNull())
{
@ -1356,7 +1357,7 @@ bool p3IdService::decryptData( const uint8_t* encrypted_data,
}
if(keyNotYetFoundIds.empty()) break;
else usleep(500*1000);
else rstime::rs_usleep(500*1000);
}
if(!keyNotYetFoundIds.empty())
@ -1658,9 +1659,8 @@ bool p3IdService::getGroupData(const uint32_t &token, std::vector<RsGxsIdGroup>
group.mPgpKnown = false;
group.mPgpId.clear();
std::cerr << "p3IdService::getGroupData() Failed to decode ServiceString \""
<< group.mMeta.mServiceString << "\"" ;
std::cerr << std::endl;
if(!group.mMeta.mServiceString.empty())
std::cerr << "p3IdService::getGroupData() " << group.mMeta.mGroupId << " (" << group.mMeta.mGroupName << ") : Failed to decode, or no ServiceString \"" << group.mMeta.mServiceString << "\"" << std::endl;
}
group.mIsAContact = (mContacts.find(RsGxsId(group.mMeta.mGroupId)) != mContacts.end());
@ -2252,7 +2252,7 @@ void RsGxsIdCache::updateServiceString(std::string serviceString)
#ifdef DEBUG_RECOGN
std::cerr << "RsGxsIdCache::updateServiceString() updating recogntags";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
#endif
if (ssdata.recogntags.publishTs == mPublishTs)
{
std::list<RsRecognTag>::iterator it;
@ -2264,7 +2264,7 @@ void RsGxsIdCache::updateServiceString(std::string serviceString)
#ifdef DEBUG_RECOGN
std::cerr << "RsGxsIdCache::updateServiceString() Valid Tag: " << it->tag_class << ":" << it->tag_type;
std::cerr << std::endl;
#endif // DEBUG_RECOGN
#endif
details.mRecognTags.push_back(*it);
}
else
@ -2272,7 +2272,7 @@ void RsGxsIdCache::updateServiceString(std::string serviceString)
#ifdef DEBUG_RECOGN
std::cerr << "RsGxsIdCache::updateServiceString() Invalid Tag: " << it->tag_class << ":" << it->tag_type;
std::cerr << std::endl;
#endif // DEBUG_RECOGN
#endif
}
}
}
@ -2281,7 +2281,7 @@ void RsGxsIdCache::updateServiceString(std::string serviceString)
#ifdef DEBUG_RECOGN
std::cerr << "RsGxsIdCache::updateServiceString() recogntags old publishTs";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
#endif
}
}
@ -2290,7 +2290,7 @@ void RsGxsIdCache::updateServiceString(std::string serviceString)
#ifdef DEBUG_RECOGN
std::cerr << "RsGxsIdCache::updateServiceString() recogntags unprocessed";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
#endif
}
// copy over Reputation scores.

View file

@ -23,7 +23,7 @@
*
*/
//#define P3TURTLE_DEBUG
//#define P3TURTLE_DEBUG
#include <unistd.h>
#include <stdexcept>
@ -89,6 +89,7 @@ static const time_t TUNNEL_CLEANING_LAPS_TIME = 10 ; /// clean tunn
static const time_t TIME_BETWEEN_TUNNEL_MANAGEMENT_CALLS = 2 ; /// Tunnel management calls every 2 secs.
static const uint32_t MAX_TUNNEL_REQS_PER_SECOND = 1 ; /// maximum number of tunnel requests issued per second. Was 0.5 before
static const uint32_t MAX_ALLOWED_SR_IN_CACHE = 120 ; /// maximum number of search requests allowed in cache. That makes 2 per sec.
static const uint32_t TURTLE_SEARCH_RESULT_MAX_HITS =5000 ; /// maximum number of search results forwarded back to the source.
static const float depth_peer_probability[7] = { 1.0f,0.99f,0.9f,0.7f,0.6f,0.5,0.4f } ;
@ -98,6 +99,8 @@ static const int MAX_TR_FORWARD_PER_SEC_UPPER_LIMIT = 30 ;
static const int MAX_TR_FORWARD_PER_SEC_LOWER_LIMIT = 10 ;
static const int DISTANCE_SQUEEZING_POWER = 8 ;
#define HEX_PRINT(a) std::hex << a << std::dec
p3turtle::p3turtle(p3ServiceControl *sc,p3LinkMgr *lm)
:p3Service(), p3Config(), mServiceControl(sc), mLinkMgr(lm), mTurtleMtx("p3turtle")
{
@ -468,7 +471,7 @@ void p3turtle::autoWash()
for(std::vector<TurtleTunnelId>::const_iterator it2(it->second.tunnels.begin());it2!=it->second.tunnels.end();++it2)
{
#ifdef P3TURTLE_DEBUG
std::cerr << (void*)*it2 << "," ;
std::cerr << HEX_PRINT(*it2) << "," ;
#endif
tunnels_to_remove.push_back(*it2) ;
}
@ -493,13 +496,13 @@ void p3turtle::autoWash()
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
for(std::map<TurtleSearchRequestId,TurtleRequestInfo>::iterator it(_search_requests_origins.begin());it!=_search_requests_origins.end();)
for(std::map<TurtleSearchRequestId,TurtleSearchRequestInfo>::iterator it(_search_requests_origins.begin());it!=_search_requests_origins.end();)
if(now > (time_t)(it->second.time_stamp + SEARCH_REQUESTS_LIFE_TIME))
{
#ifdef P3TURTLE_DEBUG
std::cerr << " removed search request " << (void *)it->first << ", timeout." << std::endl ;
std::cerr << " removed search request " << HEX_PRINT(it->first) << ", timeout." << std::endl ;
#endif
std::map<TurtleSearchRequestId,TurtleRequestInfo>::iterator tmp(it) ;
std::map<TurtleSearchRequestId,TurtleSearchRequestInfo>::iterator tmp(it) ;
++tmp ;
_search_requests_origins.erase(it) ;
it = tmp ;
@ -513,13 +516,13 @@ void p3turtle::autoWash()
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
for(std::map<TurtleTunnelRequestId,TurtleRequestInfo>::iterator it(_tunnel_requests_origins.begin());it!=_tunnel_requests_origins.end();)
for(std::map<TurtleTunnelRequestId,TurtleTunnelRequestInfo>::iterator it(_tunnel_requests_origins.begin());it!=_tunnel_requests_origins.end();)
if(now > (time_t)(it->second.time_stamp + TUNNEL_REQUESTS_LIFE_TIME))
{
#ifdef P3TURTLE_DEBUG
std::cerr << " removed tunnel request " << (void *)it->first << ", timeout." << std::endl ;
std::cerr << " removed tunnel request " << HEX_PRINT(it->first) << ", timeout." << std::endl ;
#endif
std::map<TurtleTunnelRequestId,TurtleRequestInfo>::iterator tmp(it) ;
std::map<TurtleTunnelRequestId,TurtleTunnelRequestInfo>::iterator tmp(it) ;
++tmp ;
_tunnel_requests_origins.erase(it) ;
it = tmp ;
@ -538,7 +541,7 @@ void p3turtle::autoWash()
if(now > (time_t)(it->second.time_stamp + MAXIMUM_TUNNEL_IDLE_TIME))
{
#ifdef P3TURTLE_DEBUG
std::cerr << " removing tunnel " << (void *)it->first << ": timeout." << std::endl ;
std::cerr << " removing tunnel " << HEX_PRINT(it->first) << ": timeout." << std::endl ;
#endif
tunnels_to_close.push_back(it->first) ;
}
@ -589,7 +592,7 @@ void p3turtle::locked_closeTunnel(TurtleTunnelId tid,std::vector<std::pair<RsTur
return ;
}
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: Closing tunnel " << (void*)tid << std::endl ;
std::cerr << "p3turtle: Closing tunnel " << HEX_PRINT(tid) << std::endl ;
#endif
if(it->second.local_src == _own_id) // this is a starting tunnel. We thus remove
@ -903,10 +906,11 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item)
// This is a new request. Let's add it to the request map, and forward it to
// open peers.
TurtleRequestInfo& req( _search_requests_origins[item->request_id] ) ;
TurtleSearchRequestInfo& req( _search_requests_origins[item->request_id] ) ;
req.origin = item->PeerId() ;
req.time_stamp = time(NULL) ;
req.depth = item->depth ;
req.result_count = 0;
req.keywords = item->GetKeywords() ;
// If it's not for us, perform a local search. If something found, forward the search result back.
@ -928,7 +932,7 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item)
if(!result.empty())
std::cerr << " " << result.size() << " matches found. Sending back to origin (" << item->PeerId() << ")." << std::endl ;
#endif
while(!result.empty())
while(!result.empty() && req.result_count < TURTLE_SEARCH_RESULT_MAX_HITS)
{
// Let's chop search results items into several chunks of finite size to avoid exceeding streamer's capacity.
//
@ -945,10 +949,12 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item)
}
res_item->result.push_back(result.front()) ;
++req.result_count ; // increase hit number for this particular search request.
item_size += 8 /* size */ + result.front().hash.serial_size() + result.front().name.size() ;
result.pop_front() ;
if(item_size > RSTURTLE_MAX_SEARCH_RESPONSE_SIZE || result.empty())
if(item_size > RSTURTLE_MAX_SEARCH_RESPONSE_SIZE || result.empty() || req.result_count >= TURTLE_SEARCH_RESULT_MAX_HITS)
{
#ifdef P3TURTLE_DEBUG
std::cerr << " Sending back chunk of size " << item_size << ", for " << res_item->result.size() << " elements." << std::endl ;
@ -959,6 +965,14 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item)
}
}
// if enough has been sent back already, do not sarch further
#ifdef P3TURTLE_DEBUG
std::cerr << " result count = " << req.result_count << std::endl;
#endif
if(req.result_count >= TURTLE_SEARCH_RESULT_MAX_HITS)
return ;
// If search depth not too large, also forward this search request to all other peers.
//
// We use a random factor on the depth test that is biased by a mix between the session id and the partial tunnel id
@ -1019,7 +1033,7 @@ void p3turtle::handleSearchResult(RsTurtleSearchResultItem *item)
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
// Find who actually sent the corresponding request.
//
std::map<TurtleRequestId,TurtleRequestInfo>::const_iterator it = _search_requests_origins.find(item->request_id) ;
std::map<TurtleRequestId,TurtleSearchRequestInfo>::iterator it = _search_requests_origins.find(item->request_id) ;
#ifdef P3TURTLE_DEBUG
std::cerr << "Received search result:" << std::endl ;
item->print(std::cerr,0) ;
@ -1036,12 +1050,35 @@ void p3turtle::handleSearchResult(RsTurtleSearchResultItem *item)
// Is this result's target actually ours ?
if(it->second.origin == _own_id)
{
it->second.result_count += item->result.size() ;
returnSearchResult(item) ; // Yes, so send upward.
}
else
{ // Nope, so forward it back.
{ // Nope, so forward it back.
#ifdef P3TURTLE_DEBUG
std::cerr << " Forwarding result back to " << it->second.origin << std::endl;
#endif
// We update the total count forwarded back, and chop it to TURTLE_SEARCH_RESULT_MAX_HITS.
uint32_t n = item->result.size(); // not so good!
if(it->second.result_count >= TURTLE_SEARCH_RESULT_MAX_HITS)
{
std::cerr << "(WW) exceeded turtle search result to forward. Req=" << std::hex << item->request_id << std::dec << ": dropping item with " << n << " elements." << std::endl;
return ;
}
if(it->second.result_count + n > TURTLE_SEARCH_RESULT_MAX_HITS)
{
for(uint32_t i=it->second.result_count + n; i>TURTLE_SEARCH_RESULT_MAX_HITS;--i)
item->result.pop_back() ;
it->second.result_count = TURTLE_SEARCH_RESULT_MAX_HITS ;
}
else
it->second.result_count += n ;
RsTurtleSearchResultItem *fwd_item = new RsTurtleSearchResultItem(*item) ; // copy the item
// Normally here, we should setup the forward adress, so that the owner's
@ -1082,7 +1119,7 @@ void p3turtle::routeGenericTunnelItem(RsTurtleGenericTunnelItem *item)
if(it == _local_tunnels.end())
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: got file map with unknown tunnel id " << (void*)item->tunnelId() << std::endl ;
std::cerr << "p3turtle: got file map with unknown tunnel id " << HEX_PRINT(item->tunnelId()) << std::endl ;
#endif
delete item;
return ;
@ -1183,7 +1220,7 @@ bool p3turtle::getTunnelServiceInfo(TurtleTunnelId tunnel_id,RsPeerId& vpid,RsFi
if(it2 == _local_tunnels.end())
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: unknown tunnel id " << (void*)tunnel_id << std::endl ;
std::cerr << "p3turtle: unknown tunnel id " << std::hex << tunnel_id << std::dec << std::endl ;
#endif
return false;
}
@ -1191,7 +1228,7 @@ bool p3turtle::getTunnelServiceInfo(TurtleTunnelId tunnel_id,RsPeerId& vpid,RsFi
TurtleTunnel& tunnel(it2->second) ;
#ifdef P3TURTLE_DEBUG
assert(!tunnel.hash.empty()) ;
assert(!tunnel.hash.isNull()) ;
std::cerr << " This is an endpoint for this file map." << std::endl ;
std::cerr << " Forwarding data to the multiplexer." << std::endl ;
@ -1293,7 +1330,7 @@ void p3turtle::sendTurtleData(const RsPeerId& virtual_peer_id,RsTurtleGenericTun
}
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: sending service packet to virtual peer id " << virtual_peer_id << ", hash=0x" << tunnel.hash << ", tunnel = " << (void*)item->tunnel_id << ", next peer=" << tunnel.local_dst << std::endl ;
std::cerr << "p3turtle: sending service packet to virtual peer id " << virtual_peer_id << ", hash=0x" << tunnel.hash << ", tunnel = " << HEX_PRINT(item->tunnel_id) << ", next peer=" << tunnel.local_dst << std::endl ;
#endif
sendItem(item) ;
}
@ -1313,7 +1350,7 @@ RsPeerId p3turtle::getTurtlePeerId(TurtleTunnelId tid) const
#ifdef P3TURTLE_DEBUG
assert(it!=_local_tunnels.end()) ;
assert(it->second.vpid != "") ;
assert(!it->second.vpid.isNull()) ;
#endif
return it->second.vpid ;
@ -1418,7 +1455,7 @@ void p3turtle::handleTunnelRequest(RsTurtleOpenTunnelItem *item)
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
std::map<TurtleTunnelRequestId,TurtleRequestInfo>::iterator it = _tunnel_requests_origins.find(item->request_id) ;
std::map<TurtleTunnelRequestId,TurtleTunnelRequestInfo>::iterator it = _tunnel_requests_origins.find(item->request_id) ;
if(it != _tunnel_requests_origins.end())
{
@ -1431,7 +1468,7 @@ void p3turtle::handleTunnelRequest(RsTurtleOpenTunnelItem *item)
// it to open peers, while the mutex is locked, so no-one can trigger the
// lock before the data is consistent.
TurtleRequestInfo& req( _tunnel_requests_origins[item->request_id] ) ;
TurtleTunnelRequestInfo& req( _tunnel_requests_origins[item->request_id] ) ;
req.origin = item->PeerId() ;
req.time_stamp = time(NULL) ;
req.depth = item->depth ;
@ -1617,7 +1654,7 @@ void p3turtle::handleTunnelResult(RsTurtleTunnelOkItem *item)
// Find who actually sent the corresponding turtle tunnel request.
//
std::map<TurtleTunnelRequestId,TurtleRequestInfo>::iterator it = _tunnel_requests_origins.find(item->request_id) ;
std::map<TurtleTunnelRequestId,TurtleTunnelRequestInfo>::iterator it = _tunnel_requests_origins.find(item->request_id) ;
#ifdef P3TURTLE_DEBUG
std::cerr << "Received tunnel result:" << std::endl ;
item->print(std::cerr,0) ;
@ -1649,7 +1686,7 @@ void p3turtle::handleTunnelResult(RsTurtleTunnelOkItem *item)
if(found)
{
#ifdef P3TURTLE_DEBUG
std::cerr << "Tunnel id " << (void*)item->tunnel_id << " is already there. Not storing." << std::endl ;
std::cerr << "Tunnel id " << HEX_PRINT(item->tunnel_id) << " is already there. Not storing." << std::endl ;
#endif
}
else
@ -1671,7 +1708,7 @@ void p3turtle::handleTunnelResult(RsTurtleTunnelOkItem *item)
if(it->second.origin == _own_id)
{
#ifdef P3TURTLE_DEBUG
std::cerr << " Tunnel starting point. Storing id=" << (void*)item->tunnel_id << " for hash (unknown) and tunnel request id " << it->second.origin << std::endl;
std::cerr << " Tunnel starting point. Storing id=" << HEX_PRINT(item->tunnel_id) << " for hash (unknown) and tunnel request id " << it->second.origin << std::endl;
#endif
// Tunnel is ending here. Add it to the list of tunnels for the given hash.
@ -1915,7 +1952,7 @@ void p3turtle::returnSearchResult(RsTurtleSearchResultItem *item)
// just cout for now, but it should be notified to the gui
#ifdef P3TURTLE_DEBUG
std::cerr << " Returning result for search request " << (void*)item->request_id << " upwards." << std::endl ;
std::cerr << " Returning result for search request " << HEX_PRINT(item->request_id) << " upwards." << std::endl ;
#endif
RsServer::notify()->notifyTurtleSearchResult(item->request_id,item->result) ;
@ -2045,8 +2082,8 @@ std::string p3turtle::getPeerNameForVirtualPeerId(const RsPeerId& virtual_peer_i
void p3turtle::getInfo( std::vector<std::vector<std::string> >& hashes_info,
std::vector<std::vector<std::string> >& tunnels_info,
std::vector<TurtleRequestDisplayInfo >& search_reqs_info,
std::vector<TurtleRequestDisplayInfo >& tunnel_reqs_info) const
std::vector<TurtleSearchRequestDisplayInfo >& search_reqs_info,
std::vector<TurtleTunnelRequestDisplayInfo >& tunnel_reqs_info) const
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
@ -2094,24 +2131,25 @@ void p3turtle::getInfo( std::vector<std::vector<std::string> >& hashes_info,
search_reqs_info.clear();
for(std::map<TurtleSearchRequestId,TurtleRequestInfo>::const_iterator it(_search_requests_origins.begin());it!=_search_requests_origins.end();++it)
for(std::map<TurtleSearchRequestId,TurtleSearchRequestInfo>::const_iterator it(_search_requests_origins.begin());it!=_search_requests_origins.end();++it)
{
TurtleRequestDisplayInfo info ;
TurtleSearchRequestDisplayInfo info ;
info.request_id = it->first ;
info.source_peer_id = it->second.origin ;
info.age = now - it->second.time_stamp ;
info.depth = it->second.depth ;
info.keywords = it->second.keywords ;
info.keywords = it->second.keywords ;
info.hits = it->second.result_count ;
search_reqs_info.push_back(info) ;
}
tunnel_reqs_info.clear();
for(std::map<TurtleSearchRequestId,TurtleRequestInfo>::const_iterator it(_tunnel_requests_origins.begin());it!=_tunnel_requests_origins.end();++it)
for(std::map<TurtleSearchRequestId,TurtleTunnelRequestInfo>::const_iterator it(_tunnel_requests_origins.begin());it!=_tunnel_requests_origins.end();++it)
{
TurtleRequestDisplayInfo info ;
TurtleTunnelRequestDisplayInfo info ;
info.request_id = it->first ;
info.source_peer_id = it->second.origin ;
@ -2136,16 +2174,16 @@ void p3turtle::dumpState()
{
std::cerr << " hash=0x" << it->first << ", tunnel ids =" ;
for(std::vector<TurtleTunnelId>::const_iterator it2(it->second.tunnels.begin());it2!=it->second.tunnels.end();++it2)
std::cerr << " " << (void*)*it2 ;
std::cerr << " " << HEX_PRINT(*it2) ;
//std::cerr << ", last_req=" << (void*)it->second.last_request << ", time_stamp = " << it->second.time_stamp << "(" << now-it->second.time_stamp << " secs ago)" << std::endl ;
}
std::cerr << " Active outgoing file hashes: " << _outgoing_file_hashes.size() << std::endl ;
for(std::map<TurtleTunnelId,RsTurtleClientService*>::const_iterator it(_outgoing_file_hashes.begin());it!=_outgoing_file_hashes.end();++it)
std::cerr << " Active outgoing file hashes: " << _outgoing_tunnel_client_services.size() << std::endl ;
for(std::map<TurtleTunnelId,RsTurtleClientService*>::const_iterator it(_outgoing_tunnel_client_services.begin());it!=_outgoing_tunnel_client_services.end();++it)
std::cerr << " TID=0x" << it->first << std::endl ;
std::cerr << " Local tunnels:" << std::endl ;
for(std::map<TurtleTunnelId,TurtleTunnel>::const_iterator it(_local_tunnels.begin());it!=_local_tunnels.end();++it)
std::cerr << " " << (void*)it->first << ": from="
std::cerr << " " << HEX_PRINT(it->first) << ": from="
<< it->second.local_src << ", to=" << it->second.local_dst
<< ", hash=0x" << it->second.hash << ", ts=" << it->second.time_stamp << " (" << now-it->second.time_stamp << " secs ago)"
<< ", peer id =" << it->second.vpid << std::endl ;
@ -2153,20 +2191,21 @@ void p3turtle::dumpState()
std::cerr << " buffered request origins: " << std::endl ;
std::cerr << " Search requests: " << _search_requests_origins.size() << std::endl ;
for(std::map<TurtleSearchRequestId,TurtleRequestInfo>::const_iterator it(_search_requests_origins.begin());it!=_search_requests_origins.end();++it)
std::cerr << " " << (void*)it->first << ": from=" << it->second.origin
for(std::map<TurtleSearchRequestId,TurtleSearchRequestInfo>::const_iterator it(_search_requests_origins.begin());it!=_search_requests_origins.end();++it)
std::cerr << " " << HEX_PRINT(it->first) << ": from=" << it->second.origin
<< ", ts=" << it->second.time_stamp << " (" << now-it->second.time_stamp
<< " secs ago)" << std::endl ;
<< " secs ago)"
<< it->second.result_count << " hits" << std::endl ;
std::cerr << " Tunnel requests: " << _tunnel_requests_origins.size() << std::endl ;
for(std::map<TurtleTunnelRequestId,TurtleRequestInfo>::const_iterator it(_tunnel_requests_origins.begin());it!=_tunnel_requests_origins.end();++it)
std::cerr << " " << (void*)it->first << ": from=" << it->second.origin
for(std::map<TurtleTunnelRequestId,TurtleTunnelRequestInfo>::const_iterator it(_tunnel_requests_origins.begin());it!=_tunnel_requests_origins.end();++it)
std::cerr << " " << HEX_PRINT(it->first) << ": from=" << it->second.origin
<< ", ts=" << it->second.time_stamp << " (" << now-it->second.time_stamp
<< " secs ago)" << std::endl ;
std::cerr << " Virtual peers:" << std::endl ;
for(std::map<TurtleVirtualPeerId,TurtleTunnelId>::const_iterator it(_virtual_peers.begin());it!=_virtual_peers.end();++it)
std::cerr << " id=" << it->first << ", tunnel=" << (void*)(it->second) << std::endl ;
std::cerr << " id=" << it->first << ", tunnel=" << HEX_PRINT(it->second) << std::endl ;
std::cerr << " Online peers: " << std::endl ;
// for(std::list<pqipeer>::const_iterator it(_online_peers.begin());it!=_online_peers.end();++it)
// std::cerr << " id=" << it->id << ", name=" << it->name << ", state=" << it->state << ", actions=" << it->actions << std::endl ;

View file

@ -163,17 +163,25 @@ class RsSerialiser;
static const int TURTLE_MAX_SEARCH_DEPTH = 6 ;
static const int TURTLE_MAX_SEARCH_REQ_ACCEPTED_SERIAL_SIZE = 200 ;
// This class is used to keep trace of requests (searches and tunnels).
// This classes are used to keep trace of requests (searches and tunnels).
//
class TurtleRequestInfo
class TurtleSearchRequestInfo
{
public:
TurtlePeerId origin ; // where the request came from.
uint32_t time_stamp ; // last time the tunnel was actually used. Used for cleaning old tunnels.
int depth ; // depth of the request. Used to optimize tunnel length.
std::set<uint32_t> responses; // responses to this request. Useful to avoid spamming tunnel responses.
TurtlePeerId origin ; // where the request came from.
uint32_t time_stamp ; // last time the tunnel was actually used. Used for cleaning old tunnels.
int depth ; // depth of the request. Used to optimize tunnel length.
uint32_t result_count; // responses to this request. Useful to avoid spamming tunnel responses.
std::string keywords;
};
class TurtleTunnelRequestInfo
{
public:
TurtlePeerId origin ; // where the request came from.
uint32_t time_stamp ; // last time the tunnel was actually used. Used for cleaning old tunnels.
int depth ; // depth of the request. Used to optimize tunnel length.
std::set<uint32_t> responses; // responses to this request. Useful to avoid spamming tunnel responses.
};
class TurtleTunnel
{
@ -281,8 +289,8 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config
/// get info about tunnels
virtual void getInfo(std::vector<std::vector<std::string> >&,
std::vector<std::vector<std::string> >&,
std::vector<TurtleRequestDisplayInfo >&,
std::vector<TurtleRequestDisplayInfo >&) const ;
std::vector<TurtleSearchRequestDisplayInfo >&,
std::vector<TurtleTunnelRequestDisplayInfo >&) const ;
virtual void getTrafficStatistics(TurtleTrafficStatisticsInfo& info) const ;
@ -396,10 +404,10 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config
mutable RsMutex mTurtleMtx;
/// keeps trace of who emmitted a given search request
std::map<TurtleSearchRequestId,TurtleRequestInfo> _search_requests_origins ;
std::map<TurtleSearchRequestId,TurtleSearchRequestInfo> _search_requests_origins ;
/// keeps trace of who emmitted a tunnel request
std::map<TurtleTunnelRequestId,TurtleRequestInfo> _tunnel_requests_origins ;
std::map<TurtleTunnelRequestId,TurtleTunnelRequestInfo> _tunnel_requests_origins ;
/// stores adequate tunnels for each file hash locally managed
std::map<TurtleFileHash,TurtleHashInfo> _incoming_file_hashes ;

View file

@ -33,6 +33,7 @@
#include "util/rsdir.h"
#include "util/rsstring.h"
#include "util/rsrandom.h"
#include "util/rstime.h"
#include "util/rsmemory.h"
#include "util/folderiterator.h"
#include "retroshare/rstypes.h"
@ -104,6 +105,23 @@ const char *RsDirUtil::scanf_string_for_uint(int bytes)
return strgs[0] ;
}
bool RsDirUtil::splitDirFromFile(const std::string& full_path,std::string& dir, std::string& file)
{
int i = full_path.rfind('/', full_path.size()-1);
if(i == full_path.size()-1) // '/' not found!
{
file = full_path ;
dir = "." ;
return true ;
}
dir.assign(full_path,0,i+1) ;
file.assign(full_path,i+1,full_path.size()) ;
return true ;
}
void RsDirUtil::removeTopDir(const std::string& dir, std::string& path)
{
path.clear();
@ -245,6 +263,19 @@ bool RsDirUtil::fileExists(const std::string& filename)
bool RsDirUtil::moveFile(const std::string& source,const std::string& dest)
{
// Check that the destination directory exists. If not, create it.
std::string dest_dir ;
std::string dest_file ;
splitDirFromFile(dest,dest_dir,dest_file) ;
std::cerr << "Moving file " << source << " to " << dest << std::endl;
std::cerr << "Checking that directory " << dest_dir << " actually exists." << std::endl;
if(!checkCreateDirectory(dest_dir))
return false ;
// First try a rename
//
@ -458,7 +489,7 @@ bool RsDirUtil::checkCreateDirectory(const std::string& dir)
std::cerr << "check_create_directory() Fatal Error et oui--";
std::cerr <<std::endl<< "\tcannot create:" <<dir<<std::endl;
#endif
return 0;
return false;
}
#ifdef RSDIR_DEBUG
@ -466,7 +497,7 @@ bool RsDirUtil::checkCreateDirectory(const std::string& dir)
std::cerr <<std::endl<< "\tcreated:" <<dir<<std::endl;
#endif
return 1;
return true;
}
#ifdef RSDIR_DEBUG
@ -480,7 +511,7 @@ bool RsDirUtil::checkCreateDirectory(const std::string& dir)
closedir(direc) ;
#endif
return 1;
return true;
}
@ -681,7 +712,7 @@ bool RsDirUtil::renameFile(const std::string& from, const std::string& to)
#endif
/* set errno? */
return false ;
usleep(100 * 1000); // 100 msec
rstime::rs_usleep(100 * 1000); // 100 msec
if (loops >= 30)
return false ;
@ -887,7 +918,7 @@ RsStackFileLock::RsStackFileLock(const std::string& file_path)
while(RsDirUtil::createLockFile(file_path,_file_handle))
{
std::cerr << "Cannot acquire file lock " << file_path << ", waiting 1 sec." << std::endl;
usleep(1 * 1000 * 1000) ; // 1 sec
rstime::rs_usleep(1 * 1000 * 1000) ; // 1 sec
}
#ifdef RSDIR_DEBUG
std::cerr << "Acquired file handle " << _file_handle << ", lock file:" << file_path << std::endl;
@ -1291,7 +1322,7 @@ bool RsDirUtil::renameWideFile(const std::wstring& from, const std::wstring& to)
#endif
/* set errno? */
return false ;
usleep(100 * 1000); //100 msec
rstime::rs_usleep(100 * 1000); //100 msec
if (loops >= 30)
return false ;

View file

@ -83,6 +83,11 @@ const char *scanf_string_for_uint(int bytes) ;
int breakupDirList(const std::string& path, std::list<std::string> &subdirs);
// Splits the path into parent directory and file. File can be empty if full_path is a dir ending with '/'
// if full_path does not contain a directory, then dir will be "." and file will be full_path.
bool splitDirFromFile(const std::string& full_path,std::string& dir, std::string& file);
bool copyFile(const std::string& source,const std::string& dest);
bool moveFile(const std::string& source,const std::string& dest);
bool removeFile(const std::string& file);

View file

@ -135,7 +135,7 @@ std::string StringExpression::toStdString(const std::string& varstr) const
strlist += *iter + " ";
if(!strlist.empty())
strlist.pop_back(); // pops the last ","
strlist.resize(strlist.size()-1); //strlist.pop_back(); // pops the last ",". c++11 is needed for pop_back()
switch(Op)
{

View file

@ -4,6 +4,7 @@
* Universal Networking Header for RetroShare.
*
* Copyright 2007-2008 by Robert Fernie.
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -147,25 +148,25 @@ bool isLoopbackNet(const struct in_addr *addr)
return (taddr == (127 << 24 | 1));
}
bool isPrivateNet(const struct in_addr *addr)
bool isPrivateNet(const struct in_addr *addr)
{
in_addr_t taddr = ntohl(addr->s_addr);
// 10.0.0.0/8
// 172.16.0.0/12
// 192.168.0.0/16
// 169.254.0.0/16
if ((taddr>>24 == 10) ||
(taddr>>20 == (172<<4 | 16>>4)) ||
(taddr>>16 == (192<<8 | 168)) ||
(taddr>>16 == (169<<8 | 254)))
{
if ( (taddr>>24 == 10) || // 10.0.0.0/8
(taddr>>20 == (172<<4 | 16>>4)) || // 172.16.0.0/12
(taddr>>16 == (192<<8 | 168)) || // 192.168.0.0/16
(taddr>>16 == (169<<8 | 254)) ) // 169.254.0.0/16
return true;
}
else
{
return false;
}
return false;
}
bool isLinkLocalNet(const struct in_addr *addr)
{
in_addr_t taddr = ntohl(addr->s_addr);
if ( taddr>>16 == (169<<8 | 254) ) return true; // 169.254.0.0/16
return false;
}
bool isExternalNet(const struct in_addr *addr)

View file

@ -4,6 +4,7 @@
* Universal Networking Header for RetroShare.
*
* Copyright 2004-2006 by Robert Fernie.
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -72,6 +73,7 @@ void sockaddr_clear(struct sockaddr_in *addr);
bool isValidNet(const struct in_addr *addr);
bool isLoopbackNet(const struct in_addr *addr);
bool isPrivateNet(const struct in_addr *addr);
bool isLinkLocalNet(const struct in_addr *addr);
bool isExternalNet(const struct in_addr *addr);
// uses a re-entrant version of gethostbyname
@ -128,6 +130,7 @@ bool sockaddr_storage_isnull(const struct sockaddr_storage &addr);
bool sockaddr_storage_isValidNet(const struct sockaddr_storage &addr);
bool sockaddr_storage_isLoopbackNet(const struct sockaddr_storage &addr);
bool sockaddr_storage_isPrivateNet(const struct sockaddr_storage &addr);
bool sockaddr_storage_isLinkLocalNet(const struct sockaddr_storage &addr);
bool sockaddr_storage_isExternalNet(const struct sockaddr_storage &addr);
bool rs_inet_ntop(const sockaddr_storage &addr, std::string &dst);

View file

@ -4,6 +4,7 @@
* sockaddr_storage functions for RetroShare.
*
* Copyright 2013-2013 by Robert Fernie.
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -389,7 +390,8 @@ void sockaddr_storage_dump(const sockaddr_storage & addr, std::string * outputSt
std::stringstream output;
output << "sockaddr_storage_dump(addr) ";
switch (addr.ss_family){
switch (addr.ss_family)
{
case AF_INET:
{
const sockaddr_in * in = (const sockaddr_in *) & addr;
@ -421,7 +423,8 @@ void sockaddr_storage_dump(const sockaddr_storage & addr, std::string * outputSt
for( uint32_t i = 0; i < sizeof(addr); ++i )
output << std::setw(2) << std::setfill('0') << std::hex << +buf[i];
// The unary +buf[i] operation forces a no-op type conversion to an int with the correct sign
}}
}
}
if(outputString)
{
@ -578,6 +581,31 @@ bool sockaddr_storage_isPrivateNet(const struct sockaddr_storage &addr)
return false;
}
bool sockaddr_storage_isLinkLocalNet(const struct sockaddr_storage &addr)
{
#ifdef SS_DEBUG
std::cerr << __PRETTY_FUNCTION__ << std::endl;
#endif
switch(addr.ss_family)
{
case AF_INET:
return isLinkLocalNet(&(to_const_ipv4_ptr(addr)->sin_addr));
case AF_INET6:
std::cerr << __PRETTY_FUNCTION__ << " for AF_INET6 not implemented"
<< std::endl;
break;
default:
#ifdef SS_DEBUG
std::cerr << __PRETTY_FUNCTION__ <<" INVALID Family:" << std::endl;
sockaddr_storage_dump(addr);
#endif
break;
}
return false;
}
bool sockaddr_storage_isExternalNet(const struct sockaddr_storage &addr)
{

View file

@ -30,6 +30,8 @@
#include <iostream>
#include <time.h>
#include "util/rstime.h"
#ifdef __APPLE__
int __attribute__((weak)) pthread_setname_np(const char *__buf) ;
int RS_pthread_setname_np(pthread_t /*__target_thread*/, const char *__buf) {
@ -289,7 +291,7 @@ void RsQueueThread::data_tick()
THREAD_DEBUG << "RsQueueThread::data_tick() no work: sleeping for: " << mLastSleep << " ms" << std::endl;
#endif
}
usleep(mLastSleep * 1000); // mLastSleep msec
rstime::rs_usleep(mLastSleep * 1000); // mLastSleep msec
}
void RsMutex::unlock()

View file

@ -24,8 +24,29 @@
*/
#include <iostream>
#include <thread>
#include <sys/time.h>
#include "rsscopetimer.h"
#include <unistd.h>
#include "rstime.h"
namespace rstime {
int rs_usleep(uint32_t micro_seconds)
{
while(micro_seconds >= 1000000)
{
// usleep cannot be called with 1000000 or more.
usleep(500000) ;
usleep(500000) ;
micro_seconds -= 1000000 ;
}
usleep(micro_seconds) ;
return 0 ;
}
RsScopeTimer::RsScopeTimer(const std::string& name)
{
@ -57,3 +78,5 @@ double RsScopeTimer::duration()
{
return currentTime() - _seconds;
}
}

View file

@ -23,29 +23,40 @@
*
*/
// Use this class to measure and display time duration of a given environment:
//
// {
// RsScopeTimer timer("callToMeasure()") ;
//
// callToMeasure() ;
// }
//
#include <string>
class RsScopeTimer
{
public:
RsScopeTimer(const std::string& name);
~RsScopeTimer();
namespace rstime {
void start();
double duration();
/*!
* \brief This is a cross-system definition of usleep, which accepts any 32 bits number of micro-seconds.
*/
static double currentTime();
int rs_usleep(uint32_t micro_seconds);
private:
std::string _name ;
double _seconds ;
};
/* Use this class to measure and display time duration of a given environment:
{
RsScopeTimer timer("callToMeasure()") ;
callToMeasure() ;
}
*/
class RsScopeTimer
{
public:
RsScopeTimer(const std::string& name);
~RsScopeTimer();
void start();
double duration();
static double currentTime();
private:
std::string _name ;
double _seconds ;
};
}