Merge branch 'master'

This commit is contained in:
zeners 2016-03-26 23:24:29 +01:00
commit 922644f03e
56 changed files with 6676 additions and 4685 deletions

View file

@ -66,6 +66,7 @@ public:
std::cerr << "!!!!!! Received Data status from global router, but the client service is not handling it !!!!!!!!!!" << std::endl ;
std::cerr << " message ID = " << received_id << std::endl;
std::cerr << " data status = " << data_status << std::endl;
std::cerr << " signer ID = " << signer_id << std::endl;
}
// This function is mandatory. It should do two things:

View file

@ -34,6 +34,11 @@
* #define GXS_SECURITY_DEBUG 1
***/
static const uint32_t MULTI_ENCRYPTION_FORMAT_v001_HEADER = 0xFACE;
static const uint32_t MULTI_ENCRYPTION_FORMAT_v001_HEADER_SIZE = 2 ;
static const uint32_t MULTI_ENCRYPTION_FORMAT_v001_NUMBER_OF_KEYS_SIZE = 2 ;
static const uint32_t MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE = 256 ;
static RsGxsId getRsaKeyFingerprint(RSA *pubkey)
{
int lenn = BN_num_bytes(pubkey -> n);
@ -93,7 +98,9 @@ static void setRSAPublicKeyData(RsTlvSecurityKey & key, RSA *rsa_pub)
bool GxsSecurity::checkPrivateKey(const RsTlvSecurityKey& key)
{
#ifdef GXS_SECURITY_DEBUG
std::cerr << "Checking private key " << key.keyId << " ..." << std::endl;
#endif
if( (key.keyFlags & RSTLV_KEY_TYPE_MASK) != RSTLV_KEY_TYPE_FULL)
{
@ -128,7 +135,9 @@ bool GxsSecurity::checkPrivateKey(const RsTlvSecurityKey& key)
}
bool GxsSecurity::checkPublicKey(const RsTlvSecurityKey& key)
{
#ifdef GXS_SECURITY_DEBUG
std::cerr << "Checking public key " << key.keyId << " ..." << std::endl;
#endif
if( (key.keyFlags & RSTLV_KEY_TYPE_MASK) != RSTLV_KEY_TYPE_PUBLIC_ONLY)
{
@ -224,7 +233,7 @@ bool GxsSecurity::extractPublicKey(const RsTlvSecurityKey& private_key,RsTlvSecu
{
std::cerr << std::endl;
std::cerr << "WARNING: GXS ID key pair " << private_key.keyId << " has inconsistent fingerprint. This is an old key " << std::endl;
std::cerr << " that is unsecured (can be faked easily) should not be used anymore. Please delete it." << std::endl;
std::cerr << " that is unsecure (can be faked easily). You should delete it!" << std::endl;
std::cerr << std::endl;
public_key.keyId = private_key.keyId ;
@ -410,10 +419,15 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
#ifdef DISTRIB_DEBUG
std::cerr << "GxsSecurity::encrypt() " << std::endl;
#endif
// Encrypts (in,inlen) into (out,outlen) using the given RSA public key.
// The format of the encrypted data is:
//
// [--- Encrypted session key length ---|--- Encrypted session key ---|--- IV ---|---- Encrypted data ---]
//
RSA *tmpkey = ::extractPublicKey(key) ;
RSA *rsa_publish_pub = RSAPublicKey_dup(tmpkey) ;
RSA_free(tmpkey) ;
RSA *tmpkey = ::extractPublicKey(key) ;
RSA *rsa_publish_pub = RSAPublicKey_dup(tmpkey) ;
RSA_free(tmpkey) ;
EVP_PKEY *public_key = NULL;
@ -430,7 +444,7 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
{
#ifdef DISTRIB_DEBUG
std::cerr << "GxsSecurity(): Could not generate publish key " << grpId
<< std::endl;
<< std::endl;
#endif
return false;
}
@ -477,7 +491,7 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
// now encrypt actual data
if(!EVP_SealUpdate(&ctx, (unsigned char*) out + out_offset, &out_currOffset, (unsigned char*) in, inlen))
{
free(out) ;
free(out) ;
out = NULL ;
return false;
}
@ -488,7 +502,7 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
// add padding
if(!EVP_SealFinal(&ctx, (unsigned char*) out + out_offset, &out_currOffset))
{
free(out) ;
free(out) ;
out = NULL ;
return false;
}
@ -499,7 +513,7 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
// make sure offset has not gone passed valid memory bounds
if(out_offset > max_outlen)
{
free(out) ;
free(out) ;
out = NULL ;
return false;
}
@ -511,14 +525,160 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
return true;
}
bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const std::vector<RsTlvSecurityKey>& keys)
{
#ifdef DISTRIB_DEBUG
std::cerr << "GxsSecurity::encrypt() " << std::endl;
#endif
// Encrypts (in,inlen) into (out,outlen) using the given RSA public key.
// The format of the encrypted data is:
//
// [--- ID ---|--- number of encrypted keys---| n * (--- Encrypted session keys ---) |--- IV ---|---- Encrypted data ---]
// 2 bytes 2 byte = n 256 bytes EVP_MAX_IV_LENGTH Rest of packet
//
out = NULL ;
try
{
std::vector<EVP_PKEY *> public_keys(keys.size(),NULL);
for(uint32_t i=0;i<keys.size();++i)
{
RSA *tmpkey = ::extractPublicKey(keys[i]) ;
RSA *rsa_publish_pub = RSAPublicKey_dup(tmpkey) ;
RSA_free(tmpkey) ;
if(rsa_publish_pub != NULL)
{
public_keys[i] = EVP_PKEY_new();
EVP_PKEY_assign_RSA(public_keys[i], rsa_publish_pub);
}
else
{
std::cerr << "GxsSecurity(): Could not generate public key for key id " << keys[i].keyId << std::endl;
throw std::runtime_error("Cannot extract public key") ;
}
}
EVP_CIPHER_CTX ctx;
unsigned char iv[EVP_MAX_IV_LENGTH];
EVP_CIPHER_CTX_init(&ctx);
std::vector<unsigned char *> ek(keys.size(),NULL) ;
std::vector<int> eklen(keys.size(),0) ;
for(uint32_t i=0;i<keys.size();++i)
{
int max_evp_key_size = EVP_PKEY_size(public_keys[i]);
if(max_evp_key_size != MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE)
throw std::runtime_error("EVP_PKEY_size should be equal to 256. It's not!") ;
ek[i] = (unsigned char*)rs_malloc(max_evp_key_size);
if(ek[i] == NULL)
throw std::runtime_error("malloc error on encrypted keys") ;
}
const EVP_CIPHER *cipher = EVP_aes_128_cbc();
int cipher_block_size = EVP_CIPHER_block_size(cipher);
// intialize context and send store encrypted cipher in ek
if(!EVP_SealInit(&ctx, EVP_aes_128_cbc(), ek.data(), eklen.data(), iv, public_keys.data(), keys.size()))
return false;
int total_ek_size = MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE * keys.size() ;
int max_outlen = MULTI_ENCRYPTION_FORMAT_v001_HEADER_SIZE + MULTI_ENCRYPTION_FORMAT_v001_NUMBER_OF_KEYS_SIZE + total_ek_size + EVP_MAX_IV_LENGTH + (inlen + cipher_block_size) ;
// now assign memory to out accounting for data, and cipher block size, key length, and key length val
out = (uint8_t*)rs_malloc(max_outlen);
if(out == NULL)
return false ;
int out_offset = 0;
// header
out[out_offset++] = MULTI_ENCRYPTION_FORMAT_v001_HEADER & 0xff ;
out[out_offset++] = (MULTI_ENCRYPTION_FORMAT_v001_HEADER >> 8) & 0xff ;
// number of keys
out[out_offset++] = keys.size() & 0xff ;
out[out_offset++] = (keys.size() >> 8) & 0xff ;
// encrypted keys, each preceeded with its length
for(uint32_t i=0;i<keys.size();++i)
{
if(eklen[i] != MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE)
{
std::cerr << "(EE) eklen[i]=" << eklen[i] << " in " << __PRETTY_FUNCTION__ << " for key id " << keys[i].keyId << ". This is unexpected. Cannot encrypt." << std::endl;
throw std::runtime_error("Encryption error") ;
}
memcpy((unsigned char*)out + out_offset, ek[i],eklen[i]) ;
out_offset += eklen[i] ;
}
memcpy((unsigned char*)out + out_offset, iv, EVP_MAX_IV_LENGTH);
out_offset += EVP_MAX_IV_LENGTH;
int out_currOffset = 0;
// now encrypt actual data
if(!EVP_SealUpdate(&ctx, (unsigned char*) out + out_offset, &out_currOffset, (unsigned char*) in, inlen))
throw std::runtime_error("Encryption error in SealUpdate()") ;
// move along to partial block space
out_offset += out_currOffset;
// add padding
if(!EVP_SealFinal(&ctx, (unsigned char*) out + out_offset, &out_currOffset))
throw std::runtime_error("Encryption error in SealFinal()") ;
// move to end
out_offset += out_currOffset;
// make sure offset has not gone passed valid memory bounds
if(out_offset > max_outlen)
throw std::runtime_error("Memory used by encryption exceeds allocated memory block") ;
// free encrypted key data
for(uint32_t i=0;i<keys.size();++i)
if(ek[i]) free(ek[i]);
outlen = out_offset;
return true;
}
catch(std::exception& e)
{
std::cerr << "(EE) Exception caught while encrypting: " << e.what() << std::endl;
if(out) free(out) ;
out = NULL ;
return false ;
}
}
bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in, uint32_t inlen, const RsTlvSecurityKey& key)
{
// Decrypts (in,inlen) into (out,outlen) using the given RSA public key.
// The format of the encrypted data (in) is:
//
// [--- Encrypted session key length ---|--- Encrypted session key ---|--- IV ---|---- Encrypted data ---]
//
// This method can be used to decrypt multi-encrypted data, if passing he correct encrypted key block (corresponding to the given key)
#ifdef DISTRIB_DEBUG
#ifdef GXS_SECURITY_DEBUG
std::cerr << "GxsSecurity::decrypt() " << std::endl;
#endif
RSA *rsa_publish = extractPrivateKey(key) ;
RSA *rsa_publish = extractPrivateKey(key) ;
EVP_PKEY *privateKey = NULL;
//RSA* rsa_publish = EVP_PKEY_get1_RSA(privateKey);
@ -531,7 +691,7 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
}
else
{
#ifdef DISTRIB_DEBUG
#ifdef GXS_SECURITY_DEBUG
std::cerr << "GxsSecurity(): Could not generate publish key " << grpId
<< std::endl;
#endif
@ -572,9 +732,13 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
const EVP_CIPHER* cipher = EVP_aes_128_cbc();
if(!EVP_OpenInit(&ctx, cipher, ek, eklen, iv, privateKey)) return false;
if(!EVP_OpenInit(&ctx, cipher, ek, eklen, iv, privateKey))
{
std::cerr << "(EE) Cannot decrypt data. Most likely reason: private GXS key is missing." << std::endl;
return false;
}
if(inlen < in_offset)
if(inlen < (uint32_t)in_offset)
{
std::cerr << "Severe error in " << __PRETTY_FUNCTION__ << ": cannot encrypt. " << std::endl;
return false ;
@ -606,7 +770,144 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
return true;
}
bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in, uint32_t inlen, const std::vector<RsTlvSecurityKey>& keys)
{
// Decrypts (in,inlen) into (out,outlen) using one of the given RSA public keys, trying them all in a row.
// The format of the encrypted data is:
//
// [--- ID ---|--- number of encrypted keys---| n * (--- Encrypted session keys ---) |--- IV ---|---- Encrypted data ---]
// 2 bytes 2 byte = n 256 bytes EVP_MAX_IV_LENGTH Rest of packet
//
// This method can be used to decrypt multi-encrypted data, if passing he correct encrypted key block (corresponding to the given key)
#ifdef DISTRIB_DEBUG
std::cerr << "GxsSecurity::decrypt() " << std::endl;
#endif
try
{
// check that the input block has a valid format.
uint32_t offset = 0 ;
uint16_t format_id = in[offset] + (in[offset+1] << 8) ;
if(format_id != MULTI_ENCRYPTION_FORMAT_v001_HEADER)
{
std::cerr << "Unrecognised format in encrypted block. Header id = " << std::hex << format_id << std::dec << std::endl;
throw std::runtime_error("Unrecognised format in encrypted block.") ;
}
offset += MULTI_ENCRYPTION_FORMAT_v001_HEADER_SIZE;
// read number of encrypted keys
uint32_t number_of_keys = in[offset] + (in[offset+1] << 8) ;
offset += MULTI_ENCRYPTION_FORMAT_v001_NUMBER_OF_KEYS_SIZE;
// reach the actual data offset
uint32_t encrypted_keys_offset = offset ;
uint32_t encrypted_block_size = 0 ;
uint32_t IV_offset = offset + number_of_keys * MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE ;
uint32_t encrypted_block_offset = IV_offset + EVP_MAX_IV_LENGTH ;
// read IV offset
if(encrypted_block_offset >= inlen)
throw std::runtime_error("Offset error") ;
encrypted_block_size = inlen - encrypted_block_offset ;
#ifdef GXS_SECURITY_DEBUG
std::cerr << " number of keys in envelop: " << number_of_keys << std::endl;
std::cerr << " IV offset : " << IV_offset << std::endl;
std::cerr << " encrypted block offset : " << encrypted_block_offset << std::endl;
std::cerr << " encrypted block size : " << encrypted_block_size << std::endl;
#endif
// decrypt
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
bool succeed = false;
for(uint32_t j=0;j<keys.size() && !succeed;++j)
{
RSA *rsa_private = extractPrivateKey(keys[j]) ;
EVP_PKEY *privateKey = NULL;
#ifdef GXS_SECURITY_DEBUG
std::cerr << " trying key " << keys[j].keyId << std::endl;
#endif
if(rsa_private != NULL)
{
privateKey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(privateKey, rsa_private);
}
else
{
RSA_free(rsa_private) ;
std::cerr << "(EE) Cannot extract private key from key Id " << keys[j].keyId << ". This is a bug. Non owned key?" << std::endl;
continue ;
}
for(uint32_t i=0;i<number_of_keys && !succeed;++i)
{
succeed = EVP_OpenInit(&ctx, EVP_aes_128_cbc(),in + encrypted_keys_offset + i*MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE , MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE, in+IV_offset, privateKey);
#ifdef GXS_SECURITY_DEBUG
std::cerr << " encrypted key at offset " << encrypted_keys_offset + i*MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE << ": " << succeed << std::endl;
#endif
}
EVP_PKEY_free(privateKey) ;
}
if(!succeed)
throw std::runtime_error("No matching key available.") ;
#ifdef GXS_SECURITY_DEBUG
std::cerr << " now decrypting with the matching key." << std::endl;
#endif
out = (uint8_t*)rs_malloc(encrypted_block_size) ;
if(out == NULL)
throw std::runtime_error("Memory allocation error") ;
int out_currOffset = 0 ;
if(!EVP_OpenUpdate(&ctx, (unsigned char*) out, &out_currOffset, (unsigned char*)in + encrypted_block_offset, encrypted_block_size))
throw std::runtime_error("Decryption error in EVP_OpenUpdate") ;
outlen = out_currOffset;
if(!EVP_OpenFinal(&ctx, (unsigned char*)out + out_currOffset, &out_currOffset))
throw std::runtime_error("Decryption error in EVP_OpenFinal") ;
outlen += out_currOffset;
#ifdef GXS_SECURITY_DEBUG
std::cerr << " successfully decrypted block of size " << outlen << std::endl;
#endif
return true;
}
catch(std::exception& e)
{
// cleanup and return false
#ifdef GXS_SECURITY_DEBUG
std::cerr << " (EE) error caught: " << e.what() << std::endl;
#endif
if(out)
{
free(out) ;
out = NULL ;
}
return false;
}
}
bool GxsSecurity::validateNxsGrp(const RsNxsGrp& grp, const RsTlvKeySignature& sign, const RsTlvSecurityKey& key)
{
#ifdef GXS_SECURITY_DEBUG

View file

@ -63,7 +63,8 @@ class GxsSecurity
*@param in
*@param inlen
*/
static bool encrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const RsTlvSecurityKey& key) ;
static bool encrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const RsTlvSecurityKey& key) ;
static bool encrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const std::vector<RsTlvSecurityKey>& keys) ;
/**
* Decrypts data using evelope decryption (taken from open ssl's evp_sealinit )
@ -74,7 +75,8 @@ class GxsSecurity
* @param inlen
* @return false if encryption failed
*/
static bool decrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const RsTlvSecurityKey& key) ;
static bool decrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const RsTlvSecurityKey& key) ;
static bool decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in, uint32_t inlen, const std::vector<RsTlvSecurityKey>& keys);
/*!
* uses grp signature to check if group has been

View file

@ -92,9 +92,9 @@ public:
uint32_t mMaxVisibleCount ;
};
typedef std::map<RsGxsGroupId, std::vector<RsNxsMsg*> > NxsMsgDataResult;
typedef std::map<RsGxsGroupId, std::vector<RsNxsMsg*> > NxsMsgDataResult;
typedef std::map<RsGxsGrpMsgIdPair, std::vector<RsNxsMsg*> > NxsMsgRelatedDataResult;
typedef std::map<RsGxsGroupId, std::vector<RsNxsMsg*> > GxsMsgResult; // <grpId, msgs>
typedef std::map<RsGxsGroupId, std::vector<RsNxsMsg*> > GxsMsgResult; // <grpId, msgs>
/*!
* The main role of GDS is the preparation and handing out of messages requested from

View file

@ -156,6 +156,11 @@ RsGenExchange::~RsGenExchange()
}
bool RsGenExchange::getGroupServerUpdateTS(const RsGxsGroupId& gid, time_t& grp_server_update_TS, time_t& msg_server_update_TS)
{
return mNetService->getGroupServerUpdateTS(gid,grp_server_update_TS,msg_server_update_TS) ;
}
void RsGenExchange::data_tick()
{
@ -170,7 +175,7 @@ void RsGenExchange::tick()
// Meta Changes should happen first.
// This is important, as services want to change Meta, then get results.
// Services shouldn't rely on this ordering - but some do.
processGrpMetaChanges();
processGrpMetaChanges();
processMsgMetaChanges();
mDataAccess->processRequests();
@ -183,9 +188,9 @@ void RsGenExchange::tick()
processGroupDelete();
processRecvdData();
processRecvdData();
processRoutingClues() ;
processRoutingClues() ;
if(!mNotifications.empty())
{
@ -234,6 +239,11 @@ void RsGenExchange::tick()
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED, false);
gc->mGrpIdList = grpIds;
#ifdef GEN_EXCH_DEBUG
std::cerr << " adding the following grp ids to notification: " << std::endl;
for(std::list<RsGxsGroupId>::const_iterator it(grpIds.begin());it!=grpIds.end();++it)
std::cerr << " " << *it << std::endl;
#endif
mNotifications.push_back(gc);
}
@ -1137,8 +1147,13 @@ void RsGenExchange::receiveChanges(std::vector<RsGxsNotify*>& changes)
out.mGrps.splice(out.mGrps.end(), gc->mGrpIdList);
}
}
else
std::cerr << "(EE) Unknown changes type!!" << std::endl;
delete n;
}
changes.clear() ;
RsServer::notify()->notifyGxsChange(out);
}
@ -1153,6 +1168,8 @@ bool RsGenExchange::subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId,
if(mNetService != NULL)
mNetService->subscribeStatusChanged(grpId,subscribe) ;
else
std::cerr << "(EE) No mNetService in RsGenExchange for service 0x" << std::hex << mServType << std::dec << std::endl;
return true;
}
@ -1814,6 +1831,11 @@ void RsGenExchange::processGrpMetaChanges()
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED, true);
gc->mGrpIdList = grpChanged;
mNotifications.push_back(gc);
#ifdef GEN_EXCH_DEBUG
std::cerr << " adding the following grp ids to notification: " << std::endl;
for(std::list<RsGxsGroupId>::const_iterator it(grpChanged.begin());it!=grpChanged.end();++it)
std::cerr << " " << *it << std::endl;
#endif
}
}
@ -2458,6 +2480,11 @@ void RsGenExchange::publishGrps()
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PUBLISH, false);
gc->mGrpIdList = grpChanged;
mNotifications.push_back(gc);
#ifdef GEN_EXCH_DEBUG
std::cerr << " adding the following grp ids to notification: " << std::endl;
for(std::list<RsGxsGroupId>::const_iterator it(grpChanged.begin());it!=grpChanged.end();++it)
std::cerr << " " << *it << std::endl;
#endif
}
}
@ -2755,30 +2782,30 @@ void RsGenExchange::processRecvdMessages()
void RsGenExchange::processRecvdGroups()
{
RS_STACK_MUTEX(mGenMtx) ;
RS_STACK_MUTEX(mGenMtx) ;
if(mReceivedGrps.empty())
return;
if(mReceivedGrps.empty())
return;
NxsGrpPendValidVect::iterator vit = mReceivedGrps.begin();
std::vector<RsGxsGroupId> existingGrpIds;
std::list<RsGxsGroupId> grpIds;
NxsGrpPendValidVect::iterator vit = mReceivedGrps.begin();
std::vector<RsGxsGroupId> existingGrpIds;
std::list<RsGxsGroupId> grpIds;
std::map<RsNxsGrp*, RsGxsGrpMetaData*> grps;
std::map<RsNxsGrp*, RsGxsGrpMetaData*> grps;
mDataStore->retrieveGroupIds(existingGrpIds);
mDataStore->retrieveGroupIds(existingGrpIds);
while( vit != mReceivedGrps.end())
{
GxsPendingItem<RsNxsGrp*, RsGxsGroupId>& gpsi = *vit;
RsNxsGrp* grp = gpsi.mItem;
RsGxsGrpMetaData* meta = new RsGxsGrpMetaData();
bool deserialOk = false;
while( vit != mReceivedGrps.end())
{
GxsPendingItem<RsNxsGrp*, RsGxsGroupId>& gpsi = *vit;
RsNxsGrp* grp = gpsi.mItem;
RsGxsGrpMetaData* meta = new RsGxsGrpMetaData();
bool deserialOk = false;
if(grp->meta.bin_len != 0)
deserialOk = meta->deserialise(grp->meta.bin_data, grp->meta.bin_len);
if(grp->meta.bin_len != 0)
deserialOk = meta->deserialise(grp->meta.bin_data, grp->meta.bin_len);
bool erase = true;
bool erase = true;
if(deserialOk)
{
@ -2788,22 +2815,22 @@ void RsGenExchange::processRecvdGroups()
grp->metaData = meta;
uint8_t ret = validateGrp(grp);
if(ret == VALIDATE_SUCCESS)
{
if(ret == VALIDATE_SUCCESS)
{
meta->mGroupStatus = GXS_SERV::GXS_GRP_STATUS_UNPROCESSED | GXS_SERV::GXS_GRP_STATUS_UNREAD;
meta->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED;
computeHash(grp->grp, meta->mHash);
// group has been validated. Let's notify the global router for the clue
#ifdef GEN_EXCH_DEBUG
std::cerr << " Group routage info: Identity=" << meta->mAuthorId << " from " << grp->PeerId() << std::endl;
#endif
// group has been validated. Let's notify the global router for the clue
if(!meta->mAuthorId.isNull())
mRoutingClues[meta->mAuthorId].insert(grp->PeerId()) ;
{
#ifdef GEN_EXCH_DEBUG
std::cerr << "Group routage info: Identity=" << meta->mAuthorId << " from " << grp->PeerId() << std::endl;
#endif
mRoutingClues[meta->mAuthorId].insert(grp->PeerId()) ;
}
// This has been moved here (as opposed to inside part for new groups below) because it is used to update the server TS when updates
// of grp metadata arrive.
@ -2816,6 +2843,8 @@ void RsGenExchange::processRecvdGroups()
if(meta->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
meta->mOriginator = grp->PeerId();
meta->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED;
grps.insert(std::make_pair(grp, meta));
grpIds.push_back(grp->grpId);
}
@ -2826,17 +2855,17 @@ void RsGenExchange::processRecvdGroups()
mGroupUpdates.push_back(update);
}
erase = true;
}
else if(ret == VALIDATE_FAIL)
{
}
else if(ret == VALIDATE_FAIL)
{
#ifdef GEN_EXCH_DEBUG
std::cerr << " failed to validate incoming meta, grpId: " << grp->grpId << ": wrong signature" << std::endl;
#endif
delete grp;
erase = true;
}
else if(ret == VALIDATE_FAIL_TRY_LATER)
{
}
else if(ret == VALIDATE_FAIL_TRY_LATER)
{
#ifdef GEN_EXCH_DEBUG
std::cerr << " failed to validate incoming grp, trying again. grpId: " << grp->grpId << std::endl;
@ -2862,21 +2891,26 @@ void RsGenExchange::processRecvdGroups()
delete grp;
delete meta;
erase = true;
}
}
if(erase)
vit = mReceivedGrps.erase(vit);
else
++vit;
}
if(erase)
vit = mReceivedGrps.erase(vit);
else
++vit;
}
if(!grpIds.empty())
{
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVE, false);
c->mGrpIdList = grpIds;
mNotifications.push_back(c);
mDataStore->storeGroup(grps);
}
if(!grpIds.empty())
{
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVE, false);
c->mGrpIdList = grpIds;
mNotifications.push_back(c);
mDataStore->storeGroup(grps);
#ifdef GEN_EXCH_DEBUG
std::cerr << " adding the following grp ids to notification: " << std::endl;
for(std::list<RsGxsGroupId>::const_iterator it(grpIds.begin());it!=grpIds.end();++it)
std::cerr << " " << *it << std::endl;
#endif
}
}
void RsGenExchange::performUpdateValidation()
@ -2936,22 +2970,35 @@ void RsGenExchange::performUpdateValidation()
else
{
delete gu.newGrp;
gu.newGrp = NULL ;
}
delete gu.oldGrpMeta;
gu.oldGrpMeta = NULL ;
}
mDataStore->updateGroup(grps);
// notify the client
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVE, true);
for(uint32_t i=0;i<mGroupUpdates.size();++i)
c->mGrpIdList.push_back(mGroupUpdates[i].oldGrpMeta->mGroupId) ;
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;
#endif
}
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;
#endif
// cleanup
mGroupUpdates.clear();

View file

@ -615,6 +615,14 @@ public:
*/
void shareGroupPublishKey(const RsGxsGroupId& grpId,const std::set<RsPeerId>& peers) ;
/*!
* Returns the local TS of the group as known by the network service.
* This is useful to allow various network services to sync their update TS
* when needed. Typical use case is forums and circles.
* @param gid GroupId the TS is which is requested
*/
bool getGroupServerUpdateTS(const RsGxsGroupId& gid,time_t& grp_server_update_TS,time_t& msg_server_update_TS) ;
protected:

View file

@ -123,16 +123,12 @@ public:
virtual bool encryptData(const uint8_t *clear_data,uint32_t clear_data_size,uint8_t *& encrypted_data,uint32_t& encrypted_data_size,const RsGxsId& encryption_key_id,bool force_load,uint32_t& encryption_error) = 0 ;
virtual bool decryptData(const uint8_t *encrypted_data,uint32_t encrypted_data_size,uint8_t *& clear_data,uint32_t& clear_data_size,const RsGxsId& encryption_key_id,uint32_t& encryption_error) = 0 ;
// virtual bool getPublicKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0;
virtual bool getOwnIds(std::list<RsGxsId>& ids) = 0;
virtual bool isOwnId(const RsGxsId& key_id) = 0 ;
virtual void timeStampKey(const RsGxsId& key_id) = 0 ;
// virtual void networkRequestPublicKey(const RsGxsId& key_id,const std::list<RsPeerId>& peer_ids) = 0 ;
// Key related interface - used for validating msgs and groups.
// Key related interface - used for validating msgs and groups.
/*!
* Use to query a whether given key is available by its key reference
* @param keyref the keyref of key that is being checked for
@ -147,8 +143,8 @@ public:
*/
virtual bool havePrivateKey(const RsGxsId &id) = 0;
// The fetchKey has an optional peerList.. this is people that had the msg with the signature.
// These same people should have the identity - so we ask them first.
// The fetchKey has an optional peerList.. this is people that had the msg with the signature.
// These same people should have the identity - so we ask them first.
/*!
* Use to request a given key reference
* @param keyref the KeyRef of the key being requested
@ -167,9 +163,6 @@ public:
virtual bool getKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0;
virtual bool getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0; // For signing outgoing messages.
virtual bool getIdDetails(const RsGxsId& id, RsIdentityDetails& details) = 0 ; // Proxy function so that we get p3Identity info from Gxs
#ifdef SUSPENDED
#endif
};
class GixsReputation
@ -218,9 +211,13 @@ class RsGcxs
virtual bool isLoaded(const RsGxsCircleId &circleId) = 0;
virtual bool loadCircle(const RsGxsCircleId &circleId) = 0;
virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id) = 0;
virtual int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id) = 0;
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist) = 0;
virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id,bool& should_encrypt) = 0;
virtual int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id) = 0;
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId>& friendlist) = 0;
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsGxsId>& idlist) = 0;
virtual bool isRecipient(const RsGxsCircleId &circleId, const RsGxsId& id) = 0;
virtual bool getLocalCircleServerUpdateTS(const RsGxsCircleId& gid,time_t& grp_server_update_TS,time_t& msg_server_update_TS) =0;
};
@ -231,8 +228,12 @@ public:
RsGxsCircleExchange(RsGeneralDataService* gds, RsNetworkExchangeService* ns, RsSerialType* serviceSerialiser,
uint16_t mServType, RsGixs* gixs, uint32_t authenPolicy)
:RsGenExchange(gds,ns,serviceSerialiser,mServType, gixs, authenPolicy) { return; }
virtual ~RsGxsCircleExchange() { return; }
virtual ~RsGxsCircleExchange() { return; }
virtual bool getLocalCircleServerUpdateTS(const RsGxsCircleId& gid,time_t& grp_server_update_TS,time_t& msg_server_update_TS)
{
return RsGenExchange::getGroupServerUpdateTS(RsGxsGroupId(gid),grp_server_update_TS,msg_server_update_TS) ;
}
};

File diff suppressed because it is too large Load diff

View file

@ -91,7 +91,7 @@ public:
RsNxsNetMgr *netMgr,
RsNxsObserver *nxsObs, // used to be = NULL.
const RsServiceInfo serviceInfo,
RsGixsReputation* reputations = NULL, RsGcxs* circles = NULL,
RsGixsReputation* reputations = NULL, RsGcxs* circles = NULL, RsGixs *gixs=NULL,
PgpAuxUtils *pgpUtils = NULL,
bool grpAutoSync = true, bool msgAutoSync = true);
@ -154,6 +154,8 @@ public:
virtual void rejectMessage(const RsGxsMessageId& msg_id) ;
virtual bool getGroupServerUpdateTS(const RsGxsGroupId& gid,time_t& grp_server_update_TS,time_t& msg_server_update_TS) ;
/* p3Config methods */
public:
@ -215,7 +217,7 @@ private:
* @param item the transaction item to process
* @return false ownership of item left with callee
*/
bool locked_processTransac(RsNxsTransac* item);
bool locked_processTransac(RsNxsTransacItem* item);
/*!
* This adds a transaction
@ -318,19 +320,19 @@ private:
* of groups held by user
* @param item contains grp sync info
*/
void handleRecvSyncGroup(RsNxsSyncGrp* item);
void handleRecvSyncGroup(RsNxsSyncGrpReqItem* item);
/*!
* Handles an nxs item for group statistics
* @param item contaims update time stamp and number of messages
*/
void handleRecvSyncGrpStatistics(RsNxsSyncGrpStats *grs);
void handleRecvSyncGrpStatistics(RsNxsSyncGrpStatsItem *grs);
/*!
* Handles an nxs item for msgs synchronisation
* @param item contaims msg sync info
*/
void handleRecvSyncMessage(RsNxsSyncMsg* item);
void handleRecvSyncMessage(RsNxsSyncMsgReqItem* item);
/*!
* Handles an nxs item for group publish key
@ -349,22 +351,21 @@ 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 canSendMsgIds(const std::vector<RsGxsMsgMetaData*>& msgMetas, const RsGxsGrpMetaData&, const RsPeerId& sslId);
bool canSendGrpId(const RsPeerId& sslId, RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& toVet, bool &should_encrypt);
bool canSendMsgIds(std::vector<RsGxsMsgMetaData*>& msgMetas, const RsGxsGrpMetaData&, const RsPeerId& sslId, RsGxsCircleId &should_encrypt_id);
bool checkCanRecvMsgFromPeer(const RsPeerId& sslId, const RsGxsGrpMetaData& meta);
void locked_createTransactionFromPending(MsgRespPending* grpPend);
void locked_createTransactionFromPending(GrpRespPending* msgPend);
void locked_createTransactionFromPending(GrpCircleIdRequestVetting* grpPend);
void locked_createTransactionFromPending(MsgCircleIdsRequestVetting* grpPend);
bool locked_createTransactionFromPending(GrpCircleIdRequestVetting* grpPend) ;
bool locked_createTransactionFromPending(MsgCircleIdsRequestVetting* grpPend) ;
void locked_pushMsgTransactionFromList(std::list<RsNxsItem*>& reqList, const RsPeerId& peerId, const uint32_t& transN);
void locked_pushGrpTransactionFromList(std::list<RsNxsItem*>& reqList, const RsPeerId& peerId, const uint32_t& transN);
void locked_pushGrpTransactionFromList(std::list<RsNxsItem*>& reqList, const RsPeerId& peerId, const uint32_t& transN); // forms a grp list request
void locked_pushMsgTransactionFromList(std::list<RsNxsItem*>& reqList, const RsPeerId& peerId, const uint32_t& transN); // forms a msg list request
void locked_pushGrpRespFromList(std::list<RsNxsItem*>& respList, const RsPeerId& peer, const uint32_t& transN);
void locked_pushMsgRespFromList(std::list<RsNxsItem*>& itemL, const RsPeerId& sslId, const RsGxsGroupId &grp_id, const uint32_t& transN);
void syncWithPeers();
void syncGrpStatistics();
void addGroupItemToList(NxsTransaction*& tr,
@ -375,15 +376,15 @@ private:
void processExplicitGroupRequests();
void locked_doMsgUpdateWork(const RsNxsTransac* nxsTrans, const RsGxsGroupId& grpId);
void locked_doMsgUpdateWork(const RsNxsTransacItem* nxsTrans, const RsGxsGroupId& grpId);
void updateServerSyncTS();
#ifdef TO_REMOVE
void updateClientSyncTS();
#endif
bool locked_CanReceiveUpdate(const RsNxsSyncGrp* item);
bool locked_CanReceiveUpdate(const RsNxsSyncMsg* item);
bool locked_CanReceiveUpdate(const RsNxsSyncGrpReqItem *item);
bool locked_CanReceiveUpdate(const RsNxsSyncMsgReqItem* item);
private:
@ -450,8 +451,15 @@ private:
void locked_stampPeerGroupUpdateTime(const RsPeerId& pid,const RsGxsGroupId& grpId,time_t tm,uint32_t n_messages) ;
/*!
* encrypts/decrypts the transaction for the destination circle id.
*/
bool encryptSingleNxsItem(RsNxsItem *item, const RsGxsCircleId& destination_circle, RsNxsItem *& encrypted_item, uint32_t &status) ;
bool processTransactionForDecryption(NxsTransaction *tr); // return false when the keys are not loaded => need retry later
void cleanRejectedMessages();
void processObserverNotifications();
private:
@ -469,8 +477,8 @@ private:
/*** transactions ***/
/*** synchronisation ***/
std::list<RsNxsSyncGrp*> mSyncGrp;
std::list<RsNxsSyncMsg*> mSyncMsg;
std::list<RsNxsSyncGrpItem*> mSyncGrp;
std::list<RsNxsSyncMsgItem*> mSyncMsg;
/*** synchronisation ***/
RsNxsObserver* mObserver;
@ -496,6 +504,7 @@ private:
int mUpdateCounter ;
RsGcxs* mCircles;
RsGixs *mGixs;
RsGixsReputation* mReputations;
PgpAuxUtils *mPgpUtils;
bool mGrpAutoSync;
@ -516,7 +525,6 @@ public:
typedef std::map<RsPeerId, RsGxsMsgUpdateItem*> ClientMsgMap;
typedef std::map<RsGxsGroupId, RsGxsServerMsgUpdateItem*> ServerMsgMap;
typedef std::map<RsPeerId, RsGxsGrpUpdateItem*> ClientGrpMap;
private:
ClientMsgMap mClientMsgUpdateMap;

View file

@ -222,12 +222,12 @@ bool GrpCircleVetting::expired()
{
return time(NULL) > (mTimeStamp + EXPIRY_PERIOD_OFFSET);
}
bool GrpCircleVetting::canSend(const SSLIdType& peerId, const RsGxsCircleId& circleId)
bool GrpCircleVetting::canSend(const SSLIdType& peerId, const RsGxsCircleId& circleId,bool& should_encrypt)
{
if(mCircles->isLoaded(circleId))
{
const RsPgpId& pgpId = mPgpUtils->getPGPId(peerId);
return mCircles->canSend(circleId, pgpId);
return mCircles->canSend(circleId, pgpId,should_encrypt);
}
mCircles->loadCircle(circleId);
@ -250,7 +250,7 @@ bool GrpCircleIdRequestVetting::cleared()
if(!gic.mCleared)
{
if(canSend(mPeerId, gic.mCircleId))
if(canSend(mPeerId, gic.mCircleId,gic.mShouldEncrypt))
{
gic.mCleared = true;
count++;
@ -284,9 +284,30 @@ MsgCircleIdsRequestVetting::MsgCircleIdsRequestVetting(RsGcxs* const circles,
bool MsgCircleIdsRequestVetting::cleared()
{
return canSend(mPeerId, mCircleId);
if(!mCircles->isLoaded(mCircleId))
{
mCircles->loadCircle(mCircleId);
return false ;
}
for(uint32_t i=0;i<mMsgs.size();)
if(!mCircles->isRecipient(mCircleId,mMsgs[i].mAuthorId))
{
std::cerr << "(WW) MsgCircleIdsRequestVetting::cleared() filtering out message " << mMsgs[i].mMsgId << " because it's signed by author " << mMsgs[i].mAuthorId << " which is not in circle " << mCircleId << std::endl;
mMsgs[i] = mMsgs[mMsgs.size()-1] ;
mMsgs.pop_back();
}
else
++i ;
RsPgpId pgpId = mPgpUtils->getPGPId(mPeerId);
bool can_send_res = mCircles->canSend(mCircleId, pgpId,mShouldEncrypt);
if(mShouldEncrypt) // that means the circle is external
return true ;
else
return can_send_res ;
}
int MsgCircleIdsRequestVetting::getType() const

View file

@ -66,7 +66,7 @@ public:
* c timeout set for this transaction
* c and itemCount
*/
RsNxsTransac* mTransaction;
RsNxsTransacItem* mTransaction;
std::list<RsNxsItem*> mItems; // items received or sent
};
@ -214,7 +214,9 @@ public:
RsGxsGroupId mGroupId;
RsGxsCircleId mCircleId;
RsGxsId mAuthorId;
bool mCleared;
bool mShouldEncrypt;
};
class MsgIdCircleVet
@ -252,9 +254,7 @@ public:
virtual bool cleared() = 0;
protected:
bool canSend(const RsPeerId& peerId, const RsGxsCircleId& circleId);
private:
bool canSend(const RsPeerId& peerId, const RsGxsCircleId& circleId, bool& should_encrypt);
RsGcxs* const mCircles;
PgpAuxUtils *mPgpUtils;
@ -286,6 +286,7 @@ public:
RsGxsGroupId mGrpId;
RsPeerId mPeerId;
RsGxsCircleId mCircleId;
bool mShouldEncrypt;
};

View file

@ -134,6 +134,16 @@ public:
* \param msgId
*/
virtual void rejectMessage(const RsGxsMessageId& msgId) =0;
/*!
* \brief getGroupServerUpdateTS
* Returns the server update time stamp for that group. This is used for synchronisation of TS between
* various network exchange services, suhc as channels/circles or forums/circles
* \param gid group for that request
* \param tm time stamp computed
* \return false if the group is not found, true otherwise
*/
virtual bool getGroupServerUpdateTS(const RsGxsGroupId& gid,time_t& grp_server_update_TS,time_t& msg_server_update_TS) =0;
};
#endif // RSGNP_H

View file

@ -111,8 +111,8 @@ class RsGxsCircleDetails
&& mCircleName == rGxsDetails.mCircleName
&& mCircleType == rGxsDetails.mCircleType
&& mIsExternal == rGxsDetails.mIsExternal
&& mUnknownPeers == rGxsDetails.mUnknownPeers
&& mAllowedPeers == rGxsDetails.mAllowedPeers
&& mAllowedAnonPeers == rGxsDetails.mAllowedAnonPeers
&& mAllowedSignedPeers == rGxsDetails.mAllowedSignedPeers
);
}
@ -121,13 +121,13 @@ class RsGxsCircleDetails
|| mCircleName != rGxsDetails.mCircleName
|| mCircleType != rGxsDetails.mCircleType
|| mIsExternal != rGxsDetails.mIsExternal
|| mUnknownPeers != rGxsDetails.mUnknownPeers
|| mAllowedPeers != rGxsDetails.mAllowedPeers
|| mAllowedAnonPeers != rGxsDetails.mAllowedAnonPeers
|| mAllowedSignedPeers != rGxsDetails.mAllowedSignedPeers
);
}
std::set<RsGxsId> mUnknownPeers;
std::map<RsPgpId, std::list<RsGxsId> > mAllowedPeers;
std::set<RsGxsId> mAllowedAnonPeers;
std::map<RsPgpId, std::set<RsGxsId> > mAllowedSignedPeers;
};
class RsGxsCircles: public RsGxsIfaceHelper

View file

@ -1334,7 +1334,7 @@ int RsServer::StartupRetroShare()
RsGxsNetService* gxsid_ns = new RsGxsNetService(
RS_SERVICE_GXS_TYPE_GXSID, gxsid_ds, nxsMgr,
mGxsIdService, mGxsIdService->getServiceInfo(),
mGxsIdService, mGxsCircles,
mGxsIdService, mGxsCircles,mGxsIdService,
pgpAuxUtils,
false,false); // don't synchronise group automatic (need explicit group request)
// don't sync messages at all.
@ -1353,9 +1353,13 @@ int RsServer::StartupRetroShare()
RsGxsNetService* gxscircles_ns = new RsGxsNetService(
RS_SERVICE_GXS_TYPE_GXSCIRCLE, gxscircles_ds, nxsMgr,
mGxsCircles, mGxsCircles->getServiceInfo(),
mGxsIdService, mGxsCircles,
pgpAuxUtils);
mGxsIdService, mGxsCircles,mGxsIdService,
pgpAuxUtils,
true,false); // synchronise group automatic
// don't sync messages at all.
mGxsCircles->setNetworkExchangeService(gxscircles_ns) ;
/**** Posted GXS service ****/
@ -1370,7 +1374,7 @@ int RsServer::StartupRetroShare()
RsGxsNetService* posted_ns = new RsGxsNetService(
RS_SERVICE_GXS_TYPE_POSTED, posted_ds, nxsMgr,
mPosted, mPosted->getServiceInfo(),
mGxsIdService, mGxsCircles,
mGxsIdService, mGxsCircles,mGxsIdService,
pgpAuxUtils);
mPosted->setNetworkExchangeService(posted_ns) ;
@ -1410,7 +1414,7 @@ int RsServer::StartupRetroShare()
RsGxsNetService* gxsforums_ns = new RsGxsNetService(
RS_SERVICE_GXS_TYPE_FORUMS, gxsforums_ds, nxsMgr,
mGxsForums, mGxsForums->getServiceInfo(),
mGxsIdService, mGxsCircles,
mGxsIdService, mGxsCircles,mGxsIdService,
pgpAuxUtils);
mGxsForums->setNetworkExchangeService(gxsforums_ns) ;
@ -1426,7 +1430,7 @@ int RsServer::StartupRetroShare()
RsGxsNetService* gxschannels_ns = new RsGxsNetService(
RS_SERVICE_GXS_TYPE_CHANNELS, gxschannels_ds, nxsMgr,
mGxsChannels, mGxsChannels->getServiceInfo(),
mGxsIdService, mGxsCircles,
mGxsIdService, mGxsCircles,mGxsIdService,
pgpAuxUtils);
mGxsChannels->setNetworkExchangeService(gxschannels_ns) ;
@ -1443,7 +1447,7 @@ int RsServer::StartupRetroShare()
RsGxsNetService* photo_ns = new RsGxsNetService(
RS_SERVICE_GXS_TYPE_PHOTO, photo_ds, nxsMgr,
mPhoto, mPhoto->getServiceInfo(),
mGxsIdService, mGxsCircles,
mGxsIdService, mGxsCircles,mGxsIdService,
pgpAuxUtils);
#endif
@ -1459,7 +1463,7 @@ int RsServer::StartupRetroShare()
RsGxsNetService* wire_ns = new RsGxsNetService(
RS_SERVICE_GXS_TYPE_WIRE, wire_ds, nxsMgr,
mWire, mWire->getServiceInfo(),
mGxsIdService, mGxsCircles,
mGxsIdService, mGxsCircles,mGxsIdService,
pgpAuxUtils);
#endif
// now add to p3service

View file

@ -29,8 +29,7 @@
#include "serialiser/rstlvbase.h"
#include "serialiser/rsbaseserial.h"
#define CIRCLE_DEBUG 1
//#define CIRCLE_DEBUG 1
uint32_t RsGxsCircleSerialiser::size(RsItem *item)
{

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -176,18 +176,16 @@ const uint16_t TLV_TYPE_CERT_X509 = 0x0101;
const uint16_t TLV_TYPE_CERT_OPENPGP = 0x0102;
const uint16_t TLV_TYPE_KEY_EVP_PKEY = 0x0110; /* Used (Generic - Distrib) */
const uint16_t TLV_TYPE_KEY_PRIV_RSA = 0x0111; /* not used yet */
const uint16_t TLV_TYPE_KEY_PUB_RSA = 0x0112; /* not used yet */
const uint16_t TLV_TYPE_KEY_PRIV_RSA = 0x0111; /* not used yet */
const uint16_t TLV_TYPE_KEY_PUB_RSA = 0x0112; /* not used yet */
const uint16_t TLV_TYPE_SIGN_RSA_SHA1 = 0x0120; /* Used (Distrib/Forums) */
const uint16_t TLV_TYPE_BIN_IMAGE = 0x0130; /* Used (Generic - Forums) */
const uint16_t TLV_TYPE_BIN_FILEDATA = 0x0140; /* Used - ACTIVE! */
const uint16_t TLV_TYPE_SIGN_RSA_SHA1 = 0x0120; /* Used (Distrib/Forums) */
const uint16_t TLV_TYPE_BIN_IMAGE = 0x0130; /* Used (Generic - Forums) */
const uint16_t TLV_TYPE_BIN_FILEDATA = 0x0140; /* Used - ACTIVE! */
const uint16_t TLV_TYPE_BIN_SERIALISE = 0x0150; /* Used (Generic - Distrib) */
const uint16_t TLV_TYPE_BIN_GENERIC = 0x0160; /* Used (DSDV Data) */
const uint16_t TLV_TYPE_BIN_GENERIC = 0x0160; /* Used (DSDV Data) */
const uint16_t TLV_TYPE_BIN_ENCRYPTED = 0x0170; /* Encrypted data */
/**** Compound Types ****/

View file

@ -37,10 +37,14 @@
/*!********************************** RsTlvFileBinaryData **********************************/
RsTlvBinaryData::RsTlvBinaryData()
:tlvtype(0), bin_len(0), bin_data(NULL)
{
}
RsTlvBinaryData::RsTlvBinaryData(uint16_t t)
:tlvtype(t), bin_len(0), bin_data(NULL)
{
return;
}
RsTlvBinaryData::RsTlvBinaryData(const RsTlvBinaryData &b)

View file

@ -35,25 +35,29 @@
class RsTlvBinaryData: public RsTlvItem
{
public:
RsTlvBinaryData(uint16_t t);
RsTlvBinaryData(const RsTlvBinaryData& b); // as per rule of three
void operator=(const RsTlvBinaryData& b); // as per rule of three
virtual ~RsTlvBinaryData(); // as per rule of three
virtual uint32_t TlvSize() const;
virtual void TlvClear(); /*! Initialize fields to empty legal values ( "0", "", etc) */
virtual void TlvShallowClear(); /*! Don't delete the binary data */
public:
RsTlvBinaryData();
RsTlvBinaryData(uint16_t t);
RsTlvBinaryData(const RsTlvBinaryData& b); // as per rule of three
void operator=(const RsTlvBinaryData& b); // as per rule of three
virtual ~RsTlvBinaryData(); // as per rule of three
virtual uint32_t TlvSize() const;
virtual void TlvClear(); /*! Initialize fields to empty legal values ( "0", "", etc) */
virtual void TlvShallowClear(); /*! Don't delete the binary data */
/// Serialise.
/*! Serialise Tlv to buffer(*data) of 'size' bytes starting at *offset */
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const;
/// Serialise.
/*! Serialise Tlv to buffer(*data) of 'size' bytes starting at *offset */
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const;
/// Deserialise.
/*! Deserialise Tlv buffer(*data) of 'size' bytes starting at *offset */
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset);
virtual std::ostream &print(std::ostream &out, uint16_t indent) const; /*! Error/Debug util function */
/// Deserialise.
/*! Deserialise Tlv buffer(*data) of 'size' bytes starting at *offset */
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset);
virtual std::ostream &print(std::ostream &out, uint16_t indent) const; /*! Error/Debug util function */
bool setBinData(const void *data, uint32_t size);
// mallocs the necessary size, and copies data into the allocated buffer in bin_data
bool setBinData(const void *data, uint32_t size);
uint16_t tlvtype; /// set/checked against TLV input
uint32_t bin_len; /// size of malloc'ed data (not serialised)

View file

@ -176,66 +176,72 @@ void p3GxsCircles::service_tick()
void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::notifyChanges()";
std::cerr << std::endl;
std::cerr << "p3GxsCircles::notifyChanges()";
std::cerr << std::endl;
#endif
std::vector<RsGxsNotify *>::iterator it;
for(it = changes.begin(); it != changes.end(); ++it)
{
RsGxsGroupChange *groupChange = dynamic_cast<RsGxsGroupChange *>(*it);
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
if (msgChange && !msgChange->metaChange())
{
std::vector<RsGxsNotify *>::iterator it;
for(it = changes.begin(); it != changes.end(); ++it)
{
RsGxsGroupChange *groupChange = dynamic_cast<RsGxsGroupChange *>(*it);
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
if (msgChange && !msgChange->metaChange())
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::notifyChanges() Found Message Change Notification";
std::cerr << std::endl;
std::cerr << " Found Message Change Notification";
std::cerr << std::endl;
#endif
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > &msgChangeMap = msgChange->msgChangeMap;
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> >::iterator mit;
for(mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit)
{
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > &msgChangeMap = msgChange->msgChangeMap;
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> >::iterator mit;
for(mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit)
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::notifyChanges() Msgs for Group: " << mit->first;
std::cerr << std::endl;
std::cerr << " Msgs for Group: " << mit->first;
std::cerr << std::endl;
#endif
}
}
}
}
/* add groups to ExternalIdList (Might get Personal Circles here until NetChecks in place) */
if (groupChange && !groupChange->metaChange())
{
/* add groups to ExternalIdList (Might get Personal Circles here until NetChecks in place) */
if (groupChange && !groupChange->metaChange())
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::notifyChanges() Found Group Change Notification";
std::cerr << std::endl;
std::cerr << " Found Group Change Notification";
std::cerr << std::endl;
#endif
std::list<RsGxsGroupId> &groupList = groupChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for(git = groupList.begin(); git != groupList.end(); ++git)
{
std::list<RsGxsGroupId> &groupList = groupChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for(git = groupList.begin(); git != groupList.end(); ++git)
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::notifyChanges() Incoming Group: " << *git;
std::cerr << std::endl;
std::cerr << " Incoming Group: " << *git << ". Forcing cache load." << std::endl;
#endif
// for new circles we need to add them to the list.
// we don't know the type of this circle here
// original behavior was to add all ids to the external ids list
addCircleIdToList(RsGxsCircleId(*git), 0);
// reset the cached circle data for this id
{
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
mCircleCache.erase(RsGxsCircleId(*git));
}
}
}
}
RsGxsIfaceHelper::receiveChanges(changes);
// for new circles we need to add them to the list.
// we don't know the type of this circle here
// original behavior was to add all ids to the external ids list
addCircleIdToList(RsGxsCircleId(*git), 0);
// reset the cached circle data for this id
{
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
mCircleCache.erase(RsGxsCircleId(*git));
}
}
}
if(groupChange)
for(std::list<RsGxsGroupId>::const_iterator git(groupChange->mGrpIdList.begin());git!=groupChange->mGrpIdList.end();++git)
{
#ifdef DEBUG_CIRCLES
std::cerr << " forcing cache loading for circle " << *git << " in order to trigger subscribe update." << std::endl;
#endif
force_cache_reload(RsGxsCircleId(*git)) ;
}
}
RsGxsIfaceHelper::receiveChanges(changes); // this clear up the vector and delete its elements
}
/********************************************************************************/
@ -263,8 +269,8 @@ bool p3GxsCircles:: getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails
details.mCircleType = data.mCircleType;
details.mIsExternal = data.mIsExternal;
details.mUnknownPeers = data.mUnknownPeers;
details.mAllowedPeers = data.mAllowedPeers;
details.mAllowedAnonPeers = data.mAllowedAnonPeers;
details.mAllowedSignedPeers = data.mAllowedSignedPeers;
return true;
}
}
@ -341,16 +347,17 @@ bool p3GxsCircles::loadCircle(const RsGxsCircleId &circleId)
return cache_request_load(circleId);
}
int p3GxsCircles::canSend(const RsGxsCircleId &circleId, const RsPgpId &id)
int p3GxsCircles::canSend(const RsGxsCircleId &circleId, const RsPgpId &id, bool& should_encrypt)
{
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
if (mCircleCache.is_cached(circleId))
{
RsGxsCircleCache &data = mCircleCache.ref(circleId);
should_encrypt = (data.mCircleType == GXS_CIRCLE_TYPE_EXTERNAL);
if (data.isAllowedPeer(id))
{
return 1;
}
return 0;
}
return -1;
@ -371,7 +378,7 @@ int p3GxsCircles::canReceive(const RsGxsCircleId &circleId, const RsPgpId &id)
return -1;
}
bool p3GxsCircles::recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist)
bool p3GxsCircles::recipients(const RsGxsCircleId &circleId, std::list<RsPgpId>& friendlist)
{
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
if (mCircleCache.is_cached(circleId))
@ -383,6 +390,34 @@ bool p3GxsCircles::recipients(const RsGxsCircleId &circleId, std::list<RsPgpId>
return false;
}
bool p3GxsCircles::isRecipient(const RsGxsCircleId &circleId, const RsGxsId& id)
{
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
if (mCircleCache.is_cached(circleId))
{
const RsGxsCircleCache &data = mCircleCache.ref(circleId);
return data.isAllowedPeer(id);
}
return false;
}
bool p3GxsCircles::recipients(const RsGxsCircleId& circleId, std::list<RsGxsId>& gxs_ids)
{
RsGxsCircleDetails details ;
if(!getCircleDetails(circleId, details))
return false;
for(std::set<RsGxsId>::const_iterator it(details.mAllowedAnonPeers.begin());it!=details.mAllowedAnonPeers.end();++it)
gxs_ids.push_back(*it) ;
for(std::map<RsPgpId,std::set<RsGxsId> >::const_iterator it(details.mAllowedSignedPeers.begin());it!=details.mAllowedSignedPeers.end();++it)
for(std::set<RsGxsId>::const_iterator it2(it->second.begin());it2!=it->second.end();++it2)
gxs_ids.push_back(*it2) ;
return true;
}
/********************************************************************************/
/******************* Get/Set Data ******************************************/
/********************************************************************************/
@ -495,6 +530,7 @@ RsGxsCircleCache::RsGxsCircleCache()
mIsExternal = true;
mUpdateTime = 0;
mGroupStatus = 0;
mGroupSubscribeFlags = 0;
return;
}
@ -506,11 +542,12 @@ bool RsGxsCircleCache::loadBaseCircle(const RsGxsCircleGroup &circle)
mCircleId = RsGxsCircleId(circle.mMeta.mGroupId);
mCircleName = circle.mMeta.mGroupName;
mUpdateTime = time(NULL);
mProcessedCircles.insert(mCircleId);
// mProcessedCircles.insert(mCircleId);
mCircleType = circle.mMeta.mCircleType;
mIsExternal = (mCircleType != GXS_CIRCLE_TYPE_LOCAL);
mGroupStatus = circle.mMeta.mGroupStatus;
mGroupSubscribeFlags = circle.mMeta.mSubscribeFlags;
#ifdef DEBUG_CIRCLES
std::cerr << "RsGxsCircleCache::loadBaseCircle(" << mCircleId << ")";
@ -534,20 +571,35 @@ bool RsGxsCircleCache::loadSubCircle(const RsGxsCircleCache &subcircle)
return true;
}
bool RsGxsCircleCache::getAllowedPeersList(std::list<RsPgpId> &friendlist)
bool RsGxsCircleCache::getAllowedPeersList(std::list<RsPgpId> &friendlist) const
{
std::map<RsPgpId, std::list<RsGxsId> >::iterator it;
for(it = mAllowedPeers.begin(); it != mAllowedPeers.end(); ++it)
std::map<RsPgpId, std::set<RsGxsId> >::const_iterator it;
for(it = mAllowedSignedPeers.begin(); it != mAllowedSignedPeers.end(); ++it)
{
friendlist.push_back(it->first);
}
return true;
}
bool RsGxsCircleCache::isAllowedPeer(const RsPgpId &id)
bool RsGxsCircleCache::isAllowedPeer(const RsGxsId &id) const
{
std::map<RsPgpId, std::list<RsGxsId> >::iterator it = mAllowedPeers.find(id);
if (it != mAllowedPeers.end())
if(mUnprocessedPeers.find(id) != mUnprocessedPeers.end())
return true ;
if(mAllowedAnonPeers.find(id) != mAllowedAnonPeers.end())
return true ;
for(std::map<RsPgpId,std::set<RsGxsId> >::const_iterator it = mAllowedSignedPeers.begin();it!=mAllowedSignedPeers.end();++it)
if(it->second.find(id) != it->second.end())
return true ;
return false ;
}
bool RsGxsCircleCache::isAllowedPeer(const RsPgpId &id) const
{
std::map<RsPgpId, std::set<RsGxsId> >::const_iterator it = mAllowedSignedPeers.find(id);
if (it != mAllowedSignedPeers.end())
{
return true;
}
@ -557,8 +609,7 @@ bool RsGxsCircleCache::isAllowedPeer(const RsPgpId &id)
bool RsGxsCircleCache::addAllowedPeer(const RsPgpId &pgpId, const RsGxsId &gxsId)
{
/* created if doesn't exist */
std::list<RsGxsId> &gxsList = mAllowedPeers[pgpId];
gxsList.push_back(gxsId);
mAllowedSignedPeers[pgpId].insert(gxsId);
return true;
}
@ -566,7 +617,7 @@ bool RsGxsCircleCache::addAllowedPeer(const RsPgpId &pgpId, const RsGxsId &gxsId
bool RsGxsCircleCache::addLocalFriend(const RsPgpId &pgpId)
{
/* empty list as no GxsID associated */
std::list<RsGxsId> &gxsList = mAllowedPeers[pgpId];
mAllowedSignedPeers.insert(std::make_pair(pgpId,std::set<RsGxsId>()));
return true;
}
@ -753,6 +804,33 @@ bool p3GxsCircles::cachetest_handlerequest(uint32_t token)
/************************************************************************************/
// Complicated deal of loading Circles.
bool p3GxsCircles::force_cache_reload(const RsGxsCircleId& id)
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::force_cache_reload(): Forcing cache reload of Circle ID " << id << std::endl;
#endif
{
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
#ifdef DEBUG_CIRCLES
std::cerr << " clearing from existing cache entries..." << std::endl;
#endif
std::map<RsGxsCircleId, RsGxsCircleCache>::iterator it = mLoadingCache.find(id);
if (it != mLoadingCache.end())
{
mLoadingCache.erase(it) ;
#ifdef DEBUG_CIRCLES
std::cerr << " removed item from currently loading cache entries..." << std::endl;
#endif
}
mCircleCache.erase(id) ;
}
cache_request_load(id) ;
return true ;
}
bool p3GxsCircles::cache_request_load(const RsGxsCircleId &id)
{
@ -946,7 +1024,7 @@ bool p3GxsCircles::cache_load_for_token(uint32_t token)
std::cerr << "p3GxsCircles::cache_load_for_token() Is Unknown -> UnknownPeer: " << *pit;
std::cerr << std::endl;
#endif
cache.mUnknownPeers.insert(*pit);
cache.mAllowedAnonPeers.insert(*pit);
}
}
else
@ -1104,9 +1182,7 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
RsGxsCircleCache &cache = it->second;
/* try reload Ids */
std::set<RsGxsId>::const_iterator pit;
for(pit = cache.mUnprocessedPeers.begin();
pit != cache.mUnprocessedPeers.end(); ++pit)
for(std::set<RsGxsId>::const_iterator pit = cache.mUnprocessedPeers.begin(); pit != cache.mUnprocessedPeers.end(); ++pit)
{
/* check cache */
if (mIdentities->haveKey(*pit))
@ -1127,7 +1203,7 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
}
else
{
cache.mUnknownPeers.insert(*pit);
cache.mAllowedAnonPeers.insert(*pit);
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::cache_reloadids() UnknownPeer: ";
@ -1157,8 +1233,10 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
cache.mUnprocessedPeers.clear();
// If sub-circles are complete too.
#ifdef SUBSCIRCLES
if (cache.mUnprocessedCircles.empty())
{
#endif
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::cache_reloadids() Adding to cache Id: ";
std::cerr << circleId;
@ -1173,6 +1251,7 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
/* remove from loading queue */
mLoadingCache.erase(it);
#ifdef SUBSCIRCLES
}
else
{
@ -1180,6 +1259,7 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
std::cerr << circleId;
std::cerr << std::endl;
}
#endif
return true;
}
@ -1189,17 +1269,14 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
bool p3GxsCircles::checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cache)
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() : ";
std::cerr << cache.mCircleId;
std::cerr << std::endl;
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() : "<< cache.mCircleId << std::endl;
#endif
/* if processed already - ignore */
if (!(cache.mGroupStatus & GXS_SERV::GXS_GRP_STATUS_UNPROCESSED))
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() : Already Processed";
std::cerr << std::endl;
std::cerr << " Already Processed" << std::endl;
#endif
return false;
@ -1209,50 +1286,90 @@ bool p3GxsCircles::checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cache)
if (!cache.mIsExternal)
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() : Personal Circle";
std::cerr << std::endl;
std::cerr << " Personal Circle. Nothing to do." << std::endl;
#endif
return false;
}
/* if we appear in the group - then autosubscribe, and mark as processed */
const RsPgpId& ownId = mPgpUtils->getPGPOwnId();
std::map<RsPgpId, std::list<RsGxsId> >::iterator it = cache.mAllowedPeers.find(ownId);
if (it != cache.mAllowedPeers.end())
std::map<RsPgpId, std::set<RsGxsId> >::iterator it = cache.mAllowedSignedPeers.find(ownId);
bool am_I_allowed = it != cache.mAllowedSignedPeers.end() ;
if(!am_I_allowed)
{
#ifdef DEBUG_CIRCLES
/* we are part of this group - subscribe, clear unprocessed flag */
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() Found OwnId -> AutoSubscribe!";
std::cerr << std::endl;
#endif
// also check if there's an unknown anonymous identity in the list that would belong to us
std::list<RsGxsId> own_gxs_ids ;
rsIdentity->getOwnIds(own_gxs_ids) ;
for(std::list<RsGxsId>::const_iterator it(own_gxs_ids.begin());it!=own_gxs_ids.end();++it)
if(cache.mAllowedAnonPeers.end() != cache.mAllowedAnonPeers.find(*it))
{
am_I_allowed = true ;
#ifdef DEBUG_CIRCLES
std::cerr << " found own GxsId " << *it << " as being in the circle" << std::endl;
#endif
break ;
}
}
#ifdef DEBUG_CIRCLES
else
std::cerr << " found own PGP id as signed to one of the circle's GxsIds" << std::endl;
#endif
if(am_I_allowed)
{
uint32_t token, token2;
RsGenExchange::subscribeToGroup(token, RsGxsGroupId(cache.mCircleId.toStdString()), true);
RsGenExchange::setGroupStatusFlags(token2, RsGxsGroupId(cache.mCircleId.toStdString()), 0, GXS_SERV::GXS_GRP_STATUS_UNPROCESSED);
if(! (cache.mGroupSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED))
{
#ifdef DEBUG_CIRCLES
/* we are part of this group - subscribe, clear unprocessed flag */
std::cerr << " I'm allowed in this circle => AutoSubscribing!" << std::endl;
#endif
RsGenExchange::subscribeToGroup(token, RsGxsGroupId(cache.mCircleId), true);
}
#ifdef DEBUG_CIRCLES
else
std::cerr << " I'm allowed in this circle, and already subscribed." << std::endl;
#endif
RsGenExchange::setGroupStatusFlags(token2, RsGxsGroupId(cache.mCircleId), 0, GXS_SERV::GXS_GRP_STATUS_UNPROCESSED);
cache.mGroupStatus ^= GXS_SERV::GXS_GRP_STATUS_UNPROCESSED;
return true;
}
else if (cache.mUnknownPeers.empty())
else if (cache.mUnprocessedPeers.empty())
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() Know All Peers -> Processed";
std::cerr << std::endl;
#endif
/* we know all the peers - we are not part - we can flag as PROCESSED. */
uint32_t token;
uint32_t token,token2;
RsGenExchange::setGroupStatusFlags(token, RsGxsGroupId(cache.mCircleId.toStdString()), 0, GXS_SERV::GXS_GRP_STATUS_UNPROCESSED);
if(cache.mGroupSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)
{
RsGenExchange::subscribeToGroup(token2, RsGxsGroupId(cache.mCircleId), false);
#ifdef DEBUG_CIRCLES
std::cerr << " Not part of the group! Let's unsubscribe this circle of unfriendly Napoleons!" << std::endl;
#endif
}
#ifdef DEBUG_CIRCLES
else
std::cerr << " Not part of the group, and not subscribed either." << std::endl;
#endif
cache.mGroupStatus ^= GXS_SERV::GXS_GRP_STATUS_UNPROCESSED;
return true ;
}
else
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() Leaving Unprocessed";
std::cerr << std::endl;
std::cerr << " Leaving Unprocessed" << std::endl;
#endif
// Don't clear UNPROCESSED - as we might not know all the peers.
// TODO - work out when we flag as PROCESSED.
}

View file

@ -132,8 +132,9 @@ class RsGxsCircleCache
bool loadBaseCircle(const RsGxsCircleGroup &circle);
bool loadSubCircle(const RsGxsCircleCache &subcircle);
bool getAllowedPeersList(std::list<RsPgpId> &friendlist);
bool isAllowedPeer(const RsPgpId &id);
bool getAllowedPeersList(std::list<RsPgpId> &friendlist) const;
bool isAllowedPeer(const RsPgpId &id) const;
bool isAllowedPeer(const RsGxsId &id) const;
bool addAllowedPeer(const RsPgpId &pgpid, const RsGxsId &gxsId);
bool addLocalFriend(const RsPgpId &pgpid);
@ -144,14 +145,17 @@ class RsGxsCircleCache
bool mIsExternal;
uint32_t mGroupStatus;
uint32_t mGroupSubscribeFlags;
time_t mUpdateTime;
#ifdef SUBSCIRCLES
std::set<RsGxsCircleId> mUnprocessedCircles;
std::set<RsGxsId> mUnprocessedPeers;
std::set<RsGxsCircleId> mProcessedCircles;
std::set<RsGxsId> mUnknownPeers;
std::map<RsPgpId, std::list<RsGxsId> > mAllowedPeers;
#endif
std::set<RsGxsId> mUnprocessedPeers;
std::set<RsGxsId> mAllowedAnonPeers;
std::map<RsPgpId, std::set<RsGxsId> > mAllowedSignedPeers;
};
@ -175,9 +179,11 @@ virtual RsServiceInfo getServiceInfo();
virtual bool isLoaded(const RsGxsCircleId &circleId);
virtual bool loadCircle(const RsGxsCircleId &circleId);
virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id);
virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id, bool &should_encrypt);
virtual int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id);
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist);
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist) ;
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsGxsId> &gxs_ids) ;
virtual bool isRecipient(const RsGxsCircleId &circleId, const RsGxsId& id) ;
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups);
@ -219,6 +225,7 @@ virtual RsServiceInfo getServiceInfo();
bool cache_request_load(const RsGxsCircleId &id);
bool cache_start_load();
bool force_cache_reload(const RsGxsCircleId& id);
bool cache_load_for_token(uint32_t token);
bool cache_reloadids(const RsGxsCircleId &circleId);