merged to upstream/master

This commit is contained in:
mr-alice 2016-06-18 16:59:01 -04:00
commit 8e2ff56f9a
395 changed files with 15613 additions and 45420 deletions

View file

@ -1,11 +0,0 @@
This is the list of known BUGS:
-------------------------------
* None!

View file

@ -124,10 +124,13 @@ void DistantChatService::handleRecvChatStatusItem(RsChatStatusItem *cs)
std::cerr << "DistantChatService::handleRecvChatStatusItem(): received keep alive packet for inactive chat! peerId=" << cs->PeerId() << std::endl;
}
bool DistantChatService::acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTunnelId& tunnel_id)
bool DistantChatService::acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTunnelId& tunnel_id,bool is_client_side)
{
bool res = true ;
if(is_client_side) // always accept distant chat when we're the client side.
return true ;
if(mDistantChatPermissions & RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NON_CONTACTS)
res = (rsIdentity!=NULL) && rsIdentity->isARegularContact(gxs_id) ;
@ -261,9 +264,12 @@ bool DistantChatService::initiateDistantChatConnexion(const RsGxsId& to_gxs_id,
RsChatMsgItem *item = new RsChatMsgItem;
item->message = "[Starting distant chat. Please wait for secure tunnel to be established]" ;
item->chatFlags = RS_CHAT_FLAG_PRIVATE ;
item->sendTime = time(NULL) ;
item->PeerId(RsPeerId(tunnel_id)) ;
handleRecvChatMsgItem(item) ;
delete item ; // item is replaced by NULL if partial, but this is not the case here.
return true ;
}

View file

@ -63,7 +63,7 @@ public:
// derived in p3ChatService, so as to pass down some info
virtual void handleIncomingItem(RsItem *) = 0;
virtual bool handleRecvChatMsgItem(RsChatMsgItem *ci)=0 ;
virtual bool handleRecvChatMsgItem(RsChatMsgItem *& ci)=0 ;
bool handleOutgoingItem(RsChatItem *) ;
bool handleRecvItem(RsChatItem *) ;
@ -89,7 +89,7 @@ public:
virtual void connectToGxsTunnelService(RsGxsTunnelService *tunnel_service) ;
private:
virtual bool acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTunnelService::RsGxsTunnelId& tunnel_id) ;
virtual bool acceptDataFromPeer(const RsGxsId& gxs_id, const RsGxsTunnelService::RsGxsTunnelId& tunnel_id, bool is_client_side) ;
virtual void notifyTunnelStatus(const RsGxsTunnelService::RsGxsTunnelId& tunnel_id,uint32_t tunnel_status) ;
virtual void receiveData(const RsGxsTunnelService::RsGxsTunnelId& id,unsigned char *data,uint32_t data_size) ;

View file

@ -152,6 +152,10 @@ bool DistributedChatService::handleRecvChatLobbyMsgItem(RsChatMsgItem *ci)
return false;
}
// add a routing clue for this peer/GXSid combination. This is quite reliable since the lobby transport is almost instantaneous
rsGRouter->addRoutingClue(GRouterKeyId(cli->signature.keyId),cli->PeerId()) ;
ChatLobbyFlags fl ;
// delete items that are not for us, as early as possible.
@ -420,11 +424,6 @@ void DistributedChatService::checkSizeAndSendLobbyMessage(RsChatItem *msg)
sendChatItem(msg) ;
}
bool DistributedChatService::locked_checkAndRebuildPartialLobbyMessage(RsChatLobbyMsgItem *ci)
{
return true ;
}
bool DistributedChatService::handleRecvItem(RsChatItem *item)
{
switch(item->PacketSubType())
@ -699,6 +698,9 @@ void DistributedChatService::handleRecvChatLobbyEventItem(RsChatLobbyEventItem *
std::cerr << std::endl;
return ;
}
// add a routing clue for this peer/GXSid combination. This is quite reliable since the lobby transport is almost instantaneous
rsGRouter->addRoutingClue(GRouterKeyId(item->signature.keyId),item->PeerId()) ;
if(! bounceLobbyObject(item,item->PeerId()))
return ;

View file

@ -90,7 +90,6 @@ class DistributedChatService
void addToSaveList(std::list<RsItem*>& list) const ;
bool processLoadListItem(const RsItem *item) ;
bool locked_checkAndRebuildPartialLobbyMessage(RsChatLobbyMsgItem *) ;
void checkSizeAndSendLobbyMessage(RsChatItem *) ;
bool sendLobbyChat(const ChatLobbyId &lobby_id, const std::string&) ;

View file

@ -95,49 +95,51 @@ int p3ChatService::tick()
void p3ChatService::sendPublicChat(const std::string &msg)
{
/* go through all the peers */
/* go through all the peers */
std::set<RsPeerId> ids;
std::set<RsPeerId>::iterator it;
mServiceCtrl->getPeersConnected(getServiceInfo().mServiceType, ids);
std::set<RsPeerId> ids;
std::set<RsPeerId>::iterator it;
mServiceCtrl->getPeersConnected(getServiceInfo().mServiceType, ids);
/* add in own id -> so get reflection */
RsPeerId ownId = mServiceCtrl->getOwnId();
ids.insert(ownId);
/* add in own id -> so get reflection */
RsPeerId ownId = mServiceCtrl->getOwnId();
ids.insert(ownId);
#ifdef CHAT_DEBUG
std::cerr << "p3ChatService::sendChat()";
std::cerr << std::endl;
std::cerr << "p3ChatService::sendChat()";
std::cerr << std::endl;
#endif
for(it = ids.begin(); it != ids.end(); ++it)
{
RsChatMsgItem *ci = new RsChatMsgItem();
for(it = ids.begin(); it != ids.end(); ++it)
{
RsChatMsgItem *ci = new RsChatMsgItem();
ci->PeerId(*it);
ci->chatFlags = RS_CHAT_FLAG_PUBLIC;
ci->sendTime = time(NULL);
ci->recvTime = ci->sendTime;
ci->message = msg;
ci->PeerId(*it);
ci->chatFlags = RS_CHAT_FLAG_PUBLIC;
ci->sendTime = time(NULL);
ci->recvTime = ci->sendTime;
ci->message = msg;
#ifdef CHAT_DEBUG
std::cerr << "p3ChatService::sendChat() Item:";
std::cerr << std::endl;
ci->print(std::cerr);
std::cerr << std::endl;
std::cerr << "p3ChatService::sendChat() Item:";
std::cerr << std::endl;
ci->print(std::cerr);
std::cerr << std::endl;
#endif
if (*it == ownId) {
//mHistoryMgr->addMessage(false, RsPeerId(), ownId, ci);
ChatMessage message;
initChatMessage(ci, message);
message.incoming = false;
message.online = true;
RsServer::notify()->notifyChatMessage(message);
mHistoryMgr->addMessage(message);
}
sendItem(ci);
}
if (*it == ownId)
{
//mHistoryMgr->addMessage(false, RsPeerId(), ownId, ci);
ChatMessage message;
initChatMessage(ci, message);
message.incoming = false;
message.online = true;
RsServer::notify()->notifyChatMessage(message);
mHistoryMgr->addMessage(message);
}
else
checkSizeAndSendMessage(ci);
}
}
@ -244,6 +246,11 @@ void p3ChatService::sendStatusString(const ChatId& id , const std::string& statu
}
}
void p3ChatService::clearChatLobby(const ChatId& id)
{
RsServer::notify()->notifyChatCleared(id);
}
void p3ChatService::sendChatItem(RsChatItem *item)
{
if(DistantChatService::handleOutgoingItem(item))
@ -423,7 +430,14 @@ bool p3ChatService::sendChat(ChatId destination, std::string msg)
return true;
}
bool p3ChatService::locked_checkAndRebuildPartialMessage(RsChatMsgItem *ci)
// This method might take control over the memory, or modify it, possibly adding missing parts.
// This function looks weird because it cannot duplicate the message since it does not know
// what type of object it is and the duplicate method of lobby messages is reserved for
// ChatLobby bouncing objects.
//
// Returns false if the item shouldn't be used (and replaced to NULL)
bool p3ChatService::locked_checkAndRebuildPartialMessage(RsChatMsgItem *& ci)
{
// Check is the item is ending an incomplete item.
//
@ -440,13 +454,16 @@ bool p3ChatService::locked_checkAndRebuildPartialMessage(RsChatMsgItem *ci)
ci->message = it->second->message + ci->message ;
ci->chatFlags |= it->second->chatFlags ;
// always remove existing partial. The compound message is in ci now.
delete it->second ;
if(!ci_is_incomplete)
_pendingPartialMessages.erase(it) ;
_pendingPartialMessages.erase(it) ;
}
// now decide what to do: if ci is incomplete, store it and replace the pointer with NULL
// if complete, return it.
if(ci_is_incomplete)
{
#ifdef CHAT_DEBUG
@ -454,7 +471,8 @@ bool p3ChatService::locked_checkAndRebuildPartialMessage(RsChatMsgItem *ci)
#endif
// The item is a partial message. Push it, and wait for the rest.
//
_pendingPartialMessages[ci->PeerId()] = ci ;
_pendingPartialMessages[ci->PeerId()] = ci ; // cannot use duplicate() here
ci = NULL ; // takes memory ownership over ci
return false ;
}
else
@ -498,8 +516,10 @@ void p3ChatService::handleIncomingItem(RsItem *item)
//
RsChatMsgItem *ci = dynamic_cast<RsChatMsgItem*>(item) ;
if(ci != NULL)
{
if(! handleRecvChatMsgItem(ci))
{
handleRecvChatMsgItem(ci);
if(ci)
delete ci ;
return ; // don't delete! It's handled by handleRecvChatMsgItem in some specific cases only.
@ -549,10 +569,10 @@ uint32_t p3ChatService::getMaxMessageSecuritySize(int type)
{
switch (type)
{
case RS_CHAT_TYPE_PUBLIC:
case RS_CHAT_TYPE_LOBBY:
return MAX_MESSAGE_SECURITY_SIZE;
case RS_CHAT_TYPE_PUBLIC:
case RS_CHAT_TYPE_PRIVATE:
case RS_CHAT_TYPE_DISTANT:
return 0; // unlimited
@ -660,7 +680,7 @@ bool p3ChatService::checkForMessageSecurity(RsChatMsgItem *ci)
return true ;
}
bool p3ChatService::handleRecvChatMsgItem(RsChatMsgItem *ci)
bool p3ChatService::handleRecvChatMsgItem(RsChatMsgItem *& ci)
{
time_t now = time(NULL);
std::string name;
@ -669,15 +689,8 @@ bool p3ChatService::handleRecvChatMsgItem(RsChatMsgItem *ci)
{
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
// This crap is because chat lobby messages use a different method for chunking messages using an additional
// subpacket ID, and a list of lobbies. We cannot just collapse the two because it would make the normal chat
// (and chat lobbies) not backward compatible.
if(!DistributedChatService::locked_checkAndRebuildPartialLobbyMessage(dynamic_cast<RsChatLobbyMsgItem*>(ci)))
return true ;
if(!locked_checkAndRebuildPartialMessage(ci))
return true ;
if(!locked_checkAndRebuildPartialMessage(ci)) // we make sure this call does not take control over the memory
return true ; // message is a subpart of an existing message. So everything ok, but we need to return.
}
// Check for security. This avoids bombing messages, and so on.

View file

@ -95,7 +95,13 @@ public:
* can be used to send 'immediate' status msgs, these status updates are meant for immediate use by peer (not saved by rs)
* e.g currently used to update user when a peer 'is typing' during a chat
*/
void sendStatusString(const ChatId& peer_id,const std::string& status_str) ;
void sendStatusString(const ChatId& id,const std::string& status_str) ;
/**
* @brief clearChatLobby: Signal chat was cleared by GUI.
* @param id: Chat id cleared.
*/
virtual void clearChatLobby(const ChatId& id);
/*!
* send to all peers online
@ -199,7 +205,8 @@ private:
void receiveStateString(const RsPeerId& id,const std::string& s) ;
/// methods for handling various Chat items.
bool handleRecvChatMsgItem(RsChatMsgItem *item) ; // returns false if the item should be deleted.
virtual bool handleRecvChatMsgItem(RsChatMsgItem *&item) ; // NULL-ifies the item if memory ownership is taken
void handleRecvChatStatusItem(RsChatStatusItem *item) ;
void handleRecvChatAvatarItem(RsChatAvatarItem *item) ;
@ -214,7 +221,8 @@ private:
void checkSizeAndSendMessage(RsChatMsgItem *item) ; // keep for compatibility for a few weeks.
/// Called when a RsChatMsgItem is received. The item may be collapsed with any waiting partial chat item from the same peer.
bool locked_checkAndRebuildPartialMessage(RsChatMsgItem *) ;
/// if so, the chat item will be turned to NULL
bool locked_checkAndRebuildPartialMessage(RsChatMsgItem *&) ;
RsChatAvatarItem *makeOwnAvatarItem() ;
RsChatStatusItem *makeOwnCustomStateStringItem() ;

View file

@ -406,7 +406,7 @@ class RsChatDHPublicKeyItem: public RsChatItem
BIGNUM *public_key ;
RsTlvKeySignature signature ; // signs the public key in a row.
RsTlvSecurityKey gxs_key ; // public key of the signer
RsTlvPublicRSAKey gxs_key ; // public key of the signer
private:
RsChatDHPublicKeyItem(const RsChatDHPublicKeyItem&) : RsChatItem(RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY) {} // make the object non copy-able

View file

@ -1159,8 +1159,7 @@ bool CacheTransfer::RequestCache(RsCacheData &data, CacheStore *cbStore)
*/
if ((data.hash == dit->second.hash) &&
(data.path == dit->second.path) &&
(data.size == dit->second.size) &&
(cbStore == cbStore))
(data.size == dit->second.size))
{
std::cerr << "Re-request duplicate cache... let it continue";
std::cerr << std::endl;

View file

@ -33,7 +33,7 @@
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#ifdef __MAC_10_10
#ifdef __MACH__
#include <unordered_set>
#else
#include <tr1/unordered_set>
@ -58,7 +58,7 @@ static const char FILE_CACHE_SEPARATOR_CHAR = '|' ;
****/
static RsMutex FIndexPtrMtx("FIndexPtrMtx") ;
#ifdef __MAC_10_10
#ifdef __MACH__
std::unordered_set<void*> FileIndex::_pointers ;
#else
std::tr1::unordered_set<void*> FileIndex::_pointers ;
@ -961,8 +961,10 @@ int FileIndex::loadIndex(const std::string& filename, const RsFileHash& expected
nfile->pop = atoi(tokens[4].c_str());
nfile->updtime = atoi(tokens[5].c_str());
nfile->parent = ndir;
nfile->row = ndir->subdirs.size() + ndir->files.size();
ndir->files[nfile->name] = nfile;
if (ndir) {
nfile->row = ndir->subdirs.size() + ndir->files.size();
ndir->files[nfile->name] = nfile;
}
}
/* create new dir and add to stack */

View file

@ -27,7 +27,7 @@
#include <string>
#include <map>
#include <set>
#if __MAC_10_10
#if __MACH__
#include <unordered_set>
#else
#include <tr1/unordered_set>
@ -250,7 +250,7 @@ class FileIndex
PersonEntry *root;
#ifdef __MAC_10_10
#ifdef __MACH__
static std::unordered_set<void*> _pointers ;
#else
static std::tr1::unordered_set<void*> _pointers ;

View file

@ -188,19 +188,18 @@ void ftServer::StartupThreads()
/* self contained threads */
/* startup ExtraList Thread */
mFtExtra->start();
mFtExtra->start("ft extra lst");
/* startup Monitor Thread */
/* startup the FileMonitor (after cache load) */
/* start it up */
mFiMon->start();
mFiMon->start("ft monitor");
/* Controller thread */
mFtController->start();
mFtController->start("ft ctrl");
/* Dataplex */
mFtDataplex->start();
mFtDataplex->start("ft dataplex");
}
void ftServer::StopThreads()
@ -257,7 +256,7 @@ bool ftServer::ResumeTransfers()
return true;
}
bool ftServer::checkHash(const RsFileHash& hash,std::string& error_string)
bool ftServer::checkHash(const RsFileHash& /*hash*/, std::string& /*error_string*/)
{
return true ;
}

View file

@ -592,7 +592,7 @@ bool ftTransferModule::checkFile()
// Note: using new is really important to avoid copy and write errors in the thread.
//
_hash_thread = new HashThread(mFileCreator) ;
_hash_thread->start() ;
_hash_thread->start("ft hash") ;
#ifdef FT_DEBUG
std::cerr << "ftTransferModule::checkFile(): launched hashing thread for file " << mHash << std::endl ;
#endif

View file

@ -532,12 +532,18 @@ bool RsGRouterTransactionAcknItem::serialise(void *data,uint32_t& size) const
return ok;
}
bool RsGRouterGenericDataItem::serialise_signed_data(void *data,uint32_t& size) const
bool RsGRouterGenericDataItem::serialise_signed_data(void *data,uint32_t size) const
{
bool ok = true;
uint32_t offset = 0;
uint32_t tlvsize = signed_data_size() ;
if(tlvsize > size)
{
ok = false;
std::cerr << "RsGRouterReceiptItem::serialisedata() size error! Not enough size in supplied container." << std::endl;
}
/* add mandatory parts first */
ok &= setRawUInt64(data, tlvsize, &offset, routing_id);
@ -580,12 +586,18 @@ bool RsGRouterSignedReceiptItem::serialise(void *data,uint32_t& size) const
return ok;
}
bool RsGRouterSignedReceiptItem::serialise_signed_data(void *data,uint32_t& size) const
bool RsGRouterSignedReceiptItem::serialise_signed_data(void *data,uint32_t size) const
{
bool ok = true;
uint32_t offset=0;
uint32_t tlvsize = signed_data_size() ;
if(tlvsize > size)
{
ok = false;
std::cerr << "RsGRouterReceiptItem::serialisedata() size error! Not enough size in supplied container." << std::endl;
}
/* add mandatory parts first */
ok &= setRawUInt64(data, tlvsize, &offset, routing_id);

View file

@ -101,7 +101,7 @@ public:
virtual ~RsGRouterAbstractMsgItem() {}
virtual uint32_t signed_data_size() const = 0 ;
virtual bool serialise_signed_data(void *data,uint32_t& size) const = 0 ;
virtual bool serialise_signed_data(void *data,uint32_t size) const = 0 ;
GRouterMsgPropagationId routing_id ;
GRouterKeyId destination_key ;
@ -137,7 +137,7 @@ class RsGRouterGenericDataItem: public RsGRouterAbstractMsgItem, public RsGRoute
// utility methods for signing data
virtual uint32_t signed_data_size() const ;
virtual bool serialise_signed_data(void *data,uint32_t& size) const ;
virtual bool serialise_signed_data(void *data, uint32_t size) const ;
};
class RsGRouterSignedReceiptItem: public RsGRouterAbstractMsgItem
@ -160,7 +160,7 @@ class RsGRouterSignedReceiptItem: public RsGRouterAbstractMsgItem
// utility methods for signing data
virtual uint32_t signed_data_size() const ;
virtual bool serialise_signed_data(void *data,uint32_t& size) const ;
virtual bool serialise_signed_data(void *data, uint32_t size) const ;
};
// Low-level data items

View file

@ -103,7 +103,9 @@ bool GRouterMatrix::addRoutingClue(const GRouterKeyId& key_id,const RsPeerId& so
for(std::list<RoutingMatrixHitEntry>::const_iterator mit(lst.begin());mit!=lst.end();++mit)
if((*mit).friend_id == fid && (*mit).time_stamp + RS_GROUTER_MATRIX_MIN_TIME_BETWEEN_HITS > now)
{
#ifdef ROUTING_MATRIX_DEBUG
std::cerr << "GRouterMatrix::addRoutingClue(): too many clues for key " << key_id.toStdString() << " from friend " << source_friend << " in a small interval of " << now - lst.front().time_stamp << " seconds. Flooding?" << std::endl;
#endif
return false ;
}

View file

@ -483,7 +483,7 @@ void p3GRouter::handleLowLevelTransactionAckItem(RsGRouterTransactionAcknItem *t
#endif
}
void p3GRouter::receiveTurtleData(RsTurtleGenericTunnelItem *gitem,const RsFileHash& hash,const RsPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction)
void p3GRouter::receiveTurtleData(RsTurtleGenericTunnelItem *gitem, const RsFileHash &/*hash*/, const RsPeerId &virtual_peer_id, RsTurtleGenericTunnelItem::Direction /*direction*/)
{
#ifdef GROUTER_DEBUG
std::cerr << "p3GRouter::receiveTurtleData() " << std::endl;
@ -613,7 +613,6 @@ RsGRouterAbstractMsgItem *GRouterDataInfo::addDataChunk(RsGRouterTransactionChun
{
RsItem *data_item = RsGRouterSerialiser().deserialise(incoming_data_buffer->chunk_data,&incoming_data_buffer->chunk_size) ;
incoming_data_buffer->chunk_data = NULL;
delete incoming_data_buffer;
incoming_data_buffer = NULL ;
@ -1141,24 +1140,30 @@ void p3GRouter::locked_collectAvailableFriends(const GRouterKeyId& gxs_id,const
for(uint32_t i=0;i<tmp_peers.size();++i)
if(incoming_routes.find(tmp_peers[i]) != incoming_routes.end())
{
{
#ifdef GROUTER_DEBUG
std::cerr << " removing " << tmp_peers[i] << " which is an incoming route" << std::endl;
#endif
}
}
else if(online_ids.find(tmp_peers[i]) == online_ids.end())
{
#ifdef GROUTER_DEBUG
std::cerr << " removing " << tmp_peers[i] << " because it is offline now!" << std::endl;
#endif
}
else if(probas[i] < RS_GROUTER_PROBABILITY_THRESHOLD_BEST_PEERS_SELECT*max_probability)
{
{
#ifdef GROUTER_DEBUG
std::cerr << " removing " << tmp_peers[i] << " because probability is below best peers threshold" << std::endl;
#endif
}
}
else
{
{
tmp_peers[count] = tmp_peers[i] ;
probas[count] = (max_probability==0.0)? (0.5+0.001*RSRandom::random_f32()) : probas[i] ;
++count ;
}
++count ;
}
tmp_peers.resize(count) ;
probas.resize(count) ;
@ -1953,8 +1958,6 @@ bool p3GRouter::signDataItem(RsGRouterAbstractMsgItem *item,const RsGxsId& signi
{
try
{
RsTlvSecurityKey signature_key ;
#ifdef GROUTER_DEBUG
std::cerr << "p3GRouter::signDataItem()" << std::endl;
std::cerr << " Key ID = " << signing_id << std::endl;

View file

@ -225,20 +225,13 @@ private:
void handleLowLevelTransactionAckItem(RsGRouterTransactionAcknItem*) ;
static Sha1CheckSum computeDataItemHash(RsGRouterGenericDataItem *data_item);
#ifdef __APPLE__
public:
#endif
class nullstream: public std::ostream {};
std::ostream& grouter_debug() const
{
static nullstream null ;
static std::ostream null(0);
return _debug_enabled?(std::cerr):null;
}
#ifdef __APPLE__
private:
#endif
void routePendingObjects() ;
void handleTunnels() ;
void autoWash() ;
@ -364,5 +357,3 @@ private:
uint64_t _random_salt ;
};
template<typename T> p3GRouter::nullstream& operator<<(p3GRouter::nullstream& ns,const T&) { return ns ; }

View file

@ -39,18 +39,31 @@ 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_old_insecure_method(RSA *pubkey)
{
int lenn = BN_num_bytes(pubkey -> n);
RsTemporaryMemory tmp(lenn) ;
BN_bn2bin(pubkey -> n, tmp);
// Copy first CERTSIGNLEN bytes from the hash of the public modulus and exponent
// We should not be using strings here, but a real ID. To be done later.
assert(lenn >= CERTSIGNLEN) ;
return RsGxsId((unsigned char*)tmp) ;
}
static RsGxsId getRsaKeyFingerprint(RSA *pubkey)
{
int lenn = BN_num_bytes(pubkey -> n);
int lene = BN_num_bytes(pubkey -> e);
unsigned char *tmp = new unsigned char[lenn+lene];
RsTemporaryMemory tmp(lenn+lene) ;
BN_bn2bin(pubkey -> n, tmp);
BN_bn2bin(pubkey -> e, &tmp[lenn]);
Sha1CheckSum s = RsDirUtil::sha1sum(tmp,lenn+lene) ;
delete[] tmp ;
Sha1CheckSum s = RsDirUtil::sha1sum(tmp,lenn+lene) ;
// Copy first CERTSIGNLEN bytes from the hash of the public modulus and exponent
// We should not be using strings here, but a real ID. To be done later.
@ -60,7 +73,7 @@ static RsGxsId getRsaKeyFingerprint(RSA *pubkey)
return RsGxsId(s.toStdString().substr(0,2*CERTSIGNLEN));
}
static RSA *extractPrivateKey(const RsTlvSecurityKey & key)
static RSA *extractPrivateKey(const RsTlvPrivateRSAKey& key)
{
assert(key.keyFlags & RSTLV_KEY_TYPE_FULL) ;
@ -73,7 +86,7 @@ static RSA *extractPrivateKey(const RsTlvSecurityKey & key)
return rsakey;
}
static RSA *extractPublicKey(const RsTlvSecurityKey& key)
static RSA *extractPublicKey(const RsTlvPublicRSAKey& key)
{
assert(!(key.keyFlags & RSTLV_KEY_TYPE_FULL)) ;
@ -85,18 +98,39 @@ static RSA *extractPublicKey(const RsTlvSecurityKey& key)
return rsakey;
}
static void setRSAPublicKeyData(RsTlvSecurityKey & key, RSA *rsa_pub)
static void setRSAPublicKeyData(RsTlvPublicRSAKey& key, RSA *rsa_pub)
{
assert(!(key.keyFlags & RSTLV_KEY_TYPE_FULL)) ;
unsigned char *data = NULL ; // this works for OpenSSL > 0.9.7
int reqspace = i2d_RSAPublicKey(rsa_pub, &data);
key.keyData.setBinData(data, reqspace);
key.keyId = getRsaKeyFingerprint(rsa_pub);
free(data) ;
free(data) ;
}
bool GxsSecurity::checkPrivateKey(const RsTlvSecurityKey& key)
static void setRSAPrivateKeyData(RsTlvPrivateRSAKey& key, RSA *rsa_priv)
{
assert(key.keyFlags & RSTLV_KEY_TYPE_FULL) ;
unsigned char *data = NULL ; // this works for OpenSSL > 0.9.7
int reqspace = i2d_RSAPrivateKey(rsa_priv, &data);
key.keyData.setBinData(data, reqspace);
key.keyId = getRsaKeyFingerprint(rsa_priv);
free(data) ;
}
bool GxsSecurity::checkFingerprint(const RsTlvPublicRSAKey& key)
{
RSA *rsa_pub = ::extractPublicKey(key) ;
bool res = (key.keyId == getRsaKeyFingerprint(rsa_pub)) ;
RSA_free(rsa_pub) ;
return res ;
}
bool GxsSecurity::checkPrivateKey(const RsTlvPrivateRSAKey& key)
{
#ifdef GXS_SECURITY_DEBUG
std::cerr << "Checking private key " << key.keyId << " ..." << std::endl;
@ -123,17 +157,33 @@ bool GxsSecurity::checkPrivateKey(const RsTlvSecurityKey& key)
return false ;
}
RsGxsId recomputed_key_id = getRsaKeyFingerprint(rsa_pub) ;
RSA_free(rsa_pub) ;
if(recomputed_key_id != key.keyId)
{
std::cerr << "(WW) GxsSecurity::checkPrivateKey(): key " << key.keyId << " has wrong fingerprint " << recomputed_key_id << "! This is unexpected." << std::endl;
return false ;
if(key.keyId == getRsaKeyFingerprint_old_insecure_method(rsa_pub))
{
#ifdef GXS_SECURITY_DEBUG
std::cerr << "(WW) fingerprint of key " << key.keyId << " was derived using old---insecure---format. It can be faked easily. You should get rid of this key!" << std::endl;
#endif
RSA_free(rsa_pub) ;
// The policy is to *accept* these private keys, but the public key that corresponds will be rejected anyway, as it can easily be faked.
return true ;
}
else
{
std::cerr << "(WW) GxsSecurity::checkPrivateKey(): key " << key.keyId << " has wrong fingerprint " << recomputed_key_id << std::endl;
RSA_free(rsa_pub) ;
return false ;
}
}
RSA_free(rsa_pub) ;
return true ;
}
bool GxsSecurity::checkPublicKey(const RsTlvSecurityKey& key)
bool GxsSecurity::checkPublicKey(const RsTlvPublicRSAKey &key)
{
#ifdef GXS_SECURITY_DEBUG
std::cerr << "Checking public key " << key.keyId << " ..." << std::endl;
@ -144,6 +194,19 @@ bool GxsSecurity::checkPublicKey(const RsTlvSecurityKey& key)
std::cerr << "(WW) GxsSecurity::checkPublicKey(): public key has wrong flags " << std::hex << (key.keyFlags & RSTLV_KEY_TYPE_MASK) << std::dec << ". This is unexpected." << std::endl;
return false ;
}
// try to extract private key
const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data;
long keylen = key.keyData.bin_len;
RSA *rsa_prv = d2i_RSAPrivateKey(NULL, &(keyptr), keylen);
if(rsa_prv != NULL)
{
std::cerr << "(SS) GxsSecurity::checkPublicKey(): public key with ID " << key.keyId << " actually is a Private key!!!" << std::endl;
RSA_free(rsa_prv) ;
return false ;
}
RSA *rsa_pub = ::extractPublicKey(key) ;
if(rsa_pub == NULL)
@ -152,53 +215,63 @@ bool GxsSecurity::checkPublicKey(const RsTlvSecurityKey& key)
return false ;
}
RsGxsId recomputed_key_id = getRsaKeyFingerprint(rsa_pub) ;
RSA_free(rsa_pub) ;
if(recomputed_key_id != key.keyId)
{
std::cerr << "(WW) GxsSecurity::checkPublicKey(): key " << key.keyId << " has wrong fingerprint " << recomputed_key_id << "! This is unexpected." << std::endl;
if(key.keyId == getRsaKeyFingerprint_old_insecure_method(rsa_pub))
{
#ifdef GXS_SECURITY_DEBUG
std::cerr << "(WW) fingerprint was derived using old---insecure---format. It can be faked easily." << std::endl;
#endif
RSA_free(rsa_pub) ;
// The policy is to accept these public keys, but warn the owner, since they might be fake keys. They will be soon rejected here, by replacing
// the return value by false.
return true ;
}
else
std::cerr << "(WW) GxsSecurity::checkPublicKey(): key " << key.keyId << " has wrong fingerprint " << recomputed_key_id << "! Key will be discarded." << std::endl;
RSA_free(rsa_pub) ;
return false ;
}
RSA_free(rsa_pub) ;
return true ;
}
static void setRSAPrivateKeyData(RsTlvSecurityKey & key, RSA *rsa_priv)
{
unsigned char *data = NULL ;
int reqspace = i2d_RSAPrivateKey(rsa_priv, &data);
key.keyData.setBinData(data, reqspace);
key.keyId = getRsaKeyFingerprint(rsa_priv);
free(data) ;
}
bool GxsSecurity::generateKeyPair(RsTlvSecurityKey& public_key,RsTlvSecurityKey& private_key)
bool GxsSecurity::generateKeyPair(RsTlvPublicRSAKey& public_key,RsTlvPrivateRSAKey& private_key)
{
// admin keys
RSA *rsa = RSA_generate_key(2048, 65537, NULL, NULL);
RSA *rsa_pub = RSAPublicKey_dup(rsa);
public_key.keyFlags = RSTLV_KEY_TYPE_PUBLIC_ONLY ;
private_key.keyFlags = RSTLV_KEY_TYPE_FULL ;
setRSAPublicKeyData(public_key, rsa_pub);
setRSAPrivateKeyData(private_key, rsa);
public_key.startTS = time(NULL);
public_key.endTS = public_key.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */
public_key.keyFlags = RSTLV_KEY_TYPE_PUBLIC_ONLY ;
private_key.startTS = public_key.startTS;
private_key.endTS = 0; /* no end */
private_key.keyFlags = RSTLV_KEY_TYPE_FULL ;
// clean up
RSA_free(rsa);
RSA_free(rsa_pub);
return true ;
if(!(private_key.checkKey() && public_key.checkKey()))
{
std::cerr << "(EE) ERROR while generating keys. Something inconsistent in flags. This is probably a bad sign!" << std::endl;
return false ;
}
return true ;
}
bool GxsSecurity::extractPublicKey(const RsTlvSecurityKey& private_key,RsTlvSecurityKey& public_key)
bool GxsSecurity::extractPublicKey(const RsTlvPrivateRSAKey &private_key, RsTlvPublicRSAKey &public_key)
{
public_key.TlvClear() ;
@ -242,30 +315,30 @@ bool GxsSecurity::extractPublicKey(const RsTlvSecurityKey& private_key,RsTlvSecu
return true ;
}
bool GxsSecurity::getSignature(const char *data, uint32_t data_len, const RsTlvSecurityKey& privKey, RsTlvKeySignature& sign)
bool GxsSecurity::getSignature(const char *data, uint32_t data_len, const RsTlvPrivateRSAKey &privKey, RsTlvKeySignature& sign)
{
RSA* rsa_pub = extractPrivateKey(privKey);
RSA* rsa_priv = extractPrivateKey(privKey);
if(!rsa_pub)
if(!rsa_priv)
{
std::cerr << "GxsSecurity::getSignature(): Cannot create signature. Keydata is incomplete." << std::endl;
return false ;
}
EVP_PKEY *key_pub = EVP_PKEY_new();
EVP_PKEY_assign_RSA(key_pub, rsa_pub);
EVP_PKEY *key_priv = EVP_PKEY_new();
EVP_PKEY_assign_RSA(key_priv, rsa_priv);
/* calc and check signature */
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
bool ok = EVP_SignInit(mdctx, EVP_sha1()) == 1;
ok &= EVP_SignUpdate(mdctx, data, data_len) == 1;
unsigned int siglen = EVP_PKEY_size(key_pub);
unsigned int siglen = EVP_PKEY_size(key_priv);
unsigned char sigbuf[siglen];
ok &= EVP_SignFinal(mdctx, sigbuf, &siglen, key_pub) == 1;
ok &= EVP_SignFinal(mdctx, sigbuf, &siglen, key_priv) == 1;
// clean up
EVP_MD_CTX_destroy(mdctx);
EVP_PKEY_free(key_pub);
EVP_PKEY_free(key_priv);
sign.signData.setBinData(sigbuf, siglen);
sign.keyId = RsGxsId(privKey.keyId);
@ -273,12 +346,11 @@ bool GxsSecurity::getSignature(const char *data, uint32_t data_len, const RsTlvS
return ok;
}
bool GxsSecurity::validateSignature(const char *data, uint32_t data_len, const RsTlvSecurityKey& key, const RsTlvKeySignature& signature)
bool GxsSecurity::validateSignature(const char *data, uint32_t data_len, const RsTlvPublicRSAKey &key, const RsTlvKeySignature& signature)
{
RSA *tmpkey = (key.keyFlags & RSTLV_KEY_TYPE_FULL)?(::extractPrivateKey(key)):(::extractPublicKey(key)) ;
RSA *rsakey = RSAPublicKey_dup(tmpkey) ; // always extract public key
RSA_free(tmpkey) ;
assert(!(key.keyFlags & RSTLV_KEY_TYPE_FULL)) ;
RSA *rsakey = ::extractPublicKey(key) ;
if(!rsakey)
{
@ -304,7 +376,7 @@ bool GxsSecurity::validateSignature(const char *data, uint32_t data_len, const R
return signOk;
}
bool GxsSecurity::validateNxsMsg(const RsNxsMsg& msg, const RsTlvKeySignature& sign, const RsTlvSecurityKey& key)
bool GxsSecurity::validateNxsMsg(const RsNxsMsg& msg, const RsTlvKeySignature& sign, const RsTlvPublicRSAKey& key)
{
#ifdef GXS_SECURITY_DEBUG
std::cerr << "GxsSecurity::validateNxsMsg()";
@ -363,35 +435,39 @@ bool GxsSecurity::validateNxsMsg(const RsNxsMsg& msg, const RsTlvKeySignature& s
RsGxsMessageId msgId = msgMeta.mMsgId, origMsgId = msgMeta.mOrigMsgId;
msgMeta.mOrigMsgId.clear();
msgMeta.mMsgId.clear();
int signOk = 0 ;
uint32_t metaDataLen = msgMeta.serial_size();
uint32_t allMsgDataLen = metaDataLen + msg.msg.bin_len;
char* metaData = new char[metaDataLen];
char* allMsgData = new char[allMsgDataLen]; // msgData + metaData
{
EVP_PKEY *signKey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(signKey, rsakey);
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
msgMeta.serialise(metaData, &metaDataLen);
uint32_t metaDataLen = msgMeta.serial_size();
uint32_t allMsgDataLen = metaDataLen + msg.msg.bin_len;
// copy msg data and meta in allmsgData buffer
memcpy(allMsgData, msg.msg.bin_data, msg.msg.bin_len);
memcpy(allMsgData+(msg.msg.bin_len), metaData, metaDataLen);
RsTemporaryMemory metaData(metaDataLen) ;
RsTemporaryMemory allMsgData(allMsgDataLen) ;
delete[] metaData ;
if(!metaData || !allMsgData)
return false ;
msgMeta.serialise(metaData, &metaDataLen);
EVP_PKEY *signKey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(signKey, rsakey);
// copy msg data and meta in allmsgData buffer
memcpy(allMsgData, msg.msg.bin_data, msg.msg.bin_len);
memcpy(allMsgData+(msg.msg.bin_len), metaData, metaDataLen);
/* calc and check signature */
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
/* calc and check signature */
EVP_VerifyInit(mdctx, EVP_sha1());
EVP_VerifyUpdate(mdctx, allMsgData, allMsgDataLen);
int signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey);
EVP_VerifyInit(mdctx, EVP_sha1());
EVP_VerifyUpdate(mdctx, allMsgData, allMsgDataLen);
delete[] allMsgData ;
signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey);
/* clean up */
EVP_PKEY_free(signKey);
EVP_MD_CTX_destroy(mdctx);
/* clean up */
EVP_PKEY_free(signKey);
EVP_MD_CTX_destroy(mdctx);
}
msgMeta.mOrigMsgId = origMsgId;
msgMeta.mMsgId = msgId;
@ -414,7 +490,7 @@ bool GxsSecurity::validateNxsMsg(const RsNxsMsg& msg, const RsTlvKeySignature& s
return false;
}
bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const RsTlvSecurityKey& key)
bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const RsTlvPublicRSAKey& key)
{
#ifdef DISTRIB_DEBUG
std::cerr << "GxsSecurity::encrypt() " << std::endl;
@ -425,6 +501,8 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
// [--- Encrypted session key length ---|--- Encrypted session key ---|--- IV ---|---- Encrypted data ---]
//
out = NULL ;
RSA *tmpkey = ::extractPublicKey(key) ;
RSA *rsa_publish_pub = RSAPublicKey_dup(tmpkey) ;
RSA_free(tmpkey) ;
@ -509,7 +587,7 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
// move to end
out_offset += out_currOffset;
// make sure offset has not gone passed valid memory bounds
if(out_offset > max_outlen)
{
@ -521,11 +599,13 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
// free encrypted key data
free(ek);
EVP_CIPHER_CTX_cleanup(&ctx);
outlen = out_offset;
return true;
}
bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const std::vector<RsTlvSecurityKey>& keys)
bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const std::vector<RsTlvPublicRSAKey> &keys)
{
#ifdef DISTRIB_DEBUG
std::cerr << "GxsSecurity::encrypt() " << std::endl;
@ -538,11 +618,12 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
//
out = NULL ;
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
std::vector<EVP_PKEY *> public_keys(keys.size(),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]) ;
@ -561,9 +642,7 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
}
}
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) ;
@ -587,6 +666,11 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
if(!EVP_SealInit(&ctx, EVP_aes_128_cbc(), ek.data(), eklen.data(), iv, public_keys.data(), keys.size()))
return false;
// now we can release the encryption keys
for(uint32_t i=0;i<public_keys.size();++i)
EVP_PKEY_free(public_keys[i]) ;
public_keys.clear() ;
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) ;
@ -653,20 +737,28 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
if(ek[i]) free(ek[i]);
outlen = out_offset;
EVP_CIPHER_CTX_cleanup(&ctx);
return true;
}
catch(std::exception& e)
{
std::cerr << "(EE) Exception caught while encrypting: " << e.what() << std::endl;
EVP_CIPHER_CTX_cleanup(&ctx);
if(out) free(out) ;
out = NULL ;
for(uint32_t i=0;i<public_keys.size();++i)
EVP_PKEY_free(public_keys[i]) ;
public_keys.clear() ;
return false ;
}
}
bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in, uint32_t inlen, const RsTlvSecurityKey& key)
bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in, uint32_t inlen, const RsTlvPrivateRSAKey &key)
{
// Decrypts (in,inlen) into (out,outlen) using the given RSA public key.
// The format of the encrypted data (in) is:
@ -675,6 +767,7 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
//
// This method can be used to decrypt multi-encrypted data, if passing he correct encrypted key block (corresponding to the given key)
out = NULL ;
#ifdef GXS_SECURITY_DEBUG
std::cerr << "GxsSecurity::decrypt() " << std::endl;
#endif
@ -767,10 +860,11 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
outlen += out_currOffset;
free(ek);
EVP_CIPHER_CTX_cleanup(&ctx);
return true;
}
bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in, uint32_t inlen, const std::vector<RsTlvSecurityKey>& keys)
bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in, uint32_t inlen, const std::vector<RsTlvPrivateRSAKey> &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:
@ -783,9 +877,13 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
#ifdef DISTRIB_DEBUG
std::cerr << "GxsSecurity::decrypt() " << std::endl;
#endif
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
try
{
out = NULL ;
// check that the input block has a valid format.
uint32_t offset = 0 ;
@ -826,8 +924,6 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
// decrypt
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
bool succeed = false;
for(uint32_t j=0;j<keys.size() && !succeed;++j)
@ -855,6 +951,9 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
{
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);
if(!succeed)
EVP_CIPHER_CTX_cleanup(&ctx);
#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
@ -890,6 +989,7 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
#ifdef GXS_SECURITY_DEBUG
std::cerr << " successfully decrypted block of size " << outlen << std::endl;
#endif
EVP_CIPHER_CTX_cleanup(&ctx);
return true;
}
catch(std::exception& e)
@ -905,10 +1005,11 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
out = NULL ;
}
EVP_CIPHER_CTX_cleanup(&ctx);
return false;
}
}
bool GxsSecurity::validateNxsGrp(const RsNxsGrp& grp, const RsTlvKeySignature& sign, const RsTlvSecurityKey& key)
bool GxsSecurity::validateNxsGrp(const RsNxsGrp& grp, const RsTlvKeySignature& sign, const RsTlvPublicRSAKey &key)
{
#ifdef GXS_SECURITY_DEBUG
std::cerr << "GxsSecurity::validateNxsGrp()";
@ -946,7 +1047,7 @@ bool GxsSecurity::validateNxsGrp(const RsNxsGrp& grp, const RsTlvKeySignature& s
#endif
/* extract admin key */
RSA *rsakey = (key.keyFlags & RSTLV_KEY_TYPE_FULL)? d2i_RSAPrivateKey(NULL, &(keyptr), keylen): d2i_RSAPublicKey(NULL, &(keyptr), keylen);
RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr), keylen);
if (!rsakey)
{
@ -1021,4 +1122,21 @@ bool GxsSecurity::validateNxsGrp(const RsNxsGrp& grp, const RsTlvKeySignature& s
return false;
}
void GxsSecurity::createPublicKeysFromPrivateKeys(RsTlvSecurityKeySet& keyset)
{
for( std::map<RsGxsId, RsTlvPrivateRSAKey>::const_iterator it = keyset.private_keys.begin(); it != keyset.private_keys.end() ; ++it)
if(keyset.public_keys.find(it->second.keyId) == keyset.public_keys.end())
{
RsTlvPublicRSAKey pub_key ;
if(!extractPublicKey(it->second,pub_key))
{
std::cerr << "(EE) ERROR when trying to generate public key from private key for ID " << it->second.keyId << ". This is probably a bug with security implications." << std::endl;
continue ;
}
keyset.public_keys[it->second.keyId] = pub_key ;
std::cerr << "(II) Generated missing public key for ID " << it->second.keyId << " from private key." << std::endl;
}
}

View file

@ -45,7 +45,7 @@ class GxsSecurity
/*!
* Extracts a public key from a private key.
*/
static bool extractPublicKey(const RsTlvSecurityKey& private_key,RsTlvSecurityKey& public_key) ;
static bool extractPublicKey(const RsTlvPrivateRSAKey& private_key,RsTlvPublicRSAKey& public_key) ;
/*!
* Generates a public/private RSA keypair. To be used for all GXS purposes.
@ -53,7 +53,7 @@ class GxsSecurity
* @param RsTlvSecurityKey private RSA key
* @return true if the generate was successful, false otherwise.
*/
static bool generateKeyPair(RsTlvSecurityKey& public_key,RsTlvSecurityKey& private_key) ;
static bool generateKeyPair(RsTlvPublicRSAKey &public_key, RsTlvPrivateRSAKey &private_key) ;
/*!
* Encrypts data using envelope encryption (taken from open ssl's evp_sealinit )
@ -63,8 +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 std::vector<RsTlvSecurityKey>& keys) ;
static bool encrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const RsTlvPublicRSAKey& key) ;
static bool encrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const std::vector<RsTlvPublicRSAKey>& keys) ;
/**
* Decrypts data using evelope decryption (taken from open ssl's evp_sealinit )
@ -75,8 +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 std::vector<RsTlvSecurityKey>& keys);
static bool decrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const RsTlvPrivateRSAKey& key) ;
static bool decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in, uint32_t inlen, const std::vector<RsTlvPrivateRSAKey>& keys);
/*!
* uses grp signature to check if group has been
@ -86,7 +86,7 @@ class GxsSecurity
* @param key the public key to use to check signature
* @return true if group valid false otherwise
*/
static bool validateNxsGrp(const RsNxsGrp& grp, const RsTlvKeySignature& sign, const RsTlvSecurityKey& key);
static bool validateNxsGrp(const RsNxsGrp& grp, const RsTlvKeySignature& sign, const RsTlvPublicRSAKey& key);
/*!
* Validate a msg's signature using the given public key
@ -95,7 +95,7 @@ class GxsSecurity
* @param key the public key to use to check signature
* @return false if verfication of signature is not passed
*/
static bool validateNxsMsg(const RsNxsMsg& msg, const RsTlvKeySignature& sign, const RsTlvSecurityKey& key);
static bool validateNxsMsg(const RsNxsMsg& msg, const RsTlvKeySignature& sign, const RsTlvPublicRSAKey &key);
/*!
@ -105,7 +105,7 @@ class GxsSecurity
* @param sign the signature is stored here
* @return false if signature creation failed, true is signature created
*/
static bool getSignature(const char *data, uint32_t data_len, const RsTlvSecurityKey& privKey, RsTlvKeySignature& sign);
static bool getSignature(const char *data, uint32_t data_len, const RsTlvPrivateRSAKey& privKey, RsTlvKeySignature& sign);
/*!
* @param data data that has been signed
@ -114,7 +114,7 @@ class GxsSecurity
* @param sign Signature for the data
* @return true if signature checks
*/
static bool validateSignature(const char *data, uint32_t data_len, const RsTlvSecurityKey& pubKey, const RsTlvKeySignature& sign);
static bool validateSignature(const char *data, uint32_t data_len, const RsTlvPublicRSAKey& pubKey, const RsTlvKeySignature& sign);
/*!
* Checks that the public key has correct fingerprint and correct flags.
@ -123,8 +123,18 @@ class GxsSecurity
* @return false if the key is invalid.
*/
static bool checkPublicKey(const RsTlvSecurityKey &key);
static bool checkPrivateKey(const RsTlvSecurityKey &key);
static bool checkPublicKey(const RsTlvPublicRSAKey &key);
static bool checkPrivateKey(const RsTlvPrivateRSAKey &key);
static bool checkFingerprint(const RsTlvPublicRSAKey& key); // helper function to only check the fingerprint
/*!
* Adds possibly missing public keys when private keys are present.
*
* \brief createPublicKeysForPrivateKeys
* \param set set of keys to consider
* \return
*/
static void createPublicKeysFromPrivateKeys(RsTlvSecurityKeySet& set) ;
};
#endif // GXSSECURITY_H

View file

@ -63,8 +63,8 @@ static const uint32_t INDEX_AUTHEN_ADMIN = 0x00000040; // admin key
//#define GEN_EXCH_DEBUG 1
#define MSG_CLEANUP_PERIOD 60*5 // 5 minutes
#define INTEGRITY_CHECK_PERIOD 60*30 // 30 minutes
#define MSG_CLEANUP_PERIOD 60*59 // 59 minutes
#define INTEGRITY_CHECK_PERIOD 60*31 // 31 minutes
RsGenExchange::RsGenExchange(RsGeneralDataService *gds, RsNetworkExchangeService *ns,
RsSerialType *serviceSerialiser, uint16_t servType, RsGixs* gixs,
@ -108,41 +108,6 @@ void RsGenExchange::setNetworkExchangeService(RsNetworkExchangeService *ns)
mNetService = ns ;
}
#ifdef TO_BE_DELETED_IF_NOT_USEFUL
// This class has been tested so as to see where the database gets modified.
class RsDataBaseTester
{
public:
RsDataBaseTester(RsGeneralDataService *store,const RsGxsGroupId& grpId,const std::string& info)
:_grpId(grpId),_store(store),_info(info)
{
//std::cerr << "RsDataBaseTester: (" << _info << ") retrieving messages for group " << grpId << std::endl;
_store->retrieveMsgIds(_grpId, _msgIds1) ;
}
~RsDataBaseTester()
{
//std::cerr << "RsDataBaseTester: (" << _info << ") testing messages for group " << _grpId << std::endl;
_store->retrieveMsgIds(_grpId, _msgIds2) ;
bool all_idendical = true ;
std::cerr << std::dec ;
if(_msgIds1.size() != _msgIds2.size())
std::cerr << " " << _info << " (EE) The two arrays are different (size1=" << _msgIds1.size() << ", size2=" << _msgIds2.size() << ") !!" << std::endl;
else
for(uint32_t i=0;i<_msgIds1.size();++i)
if(_msgIds1[i] != _msgIds2[i])
std::cerr << " " << _info << " (EE) The two arrays are different for i=" << i << " !!" << std::endl;
}
RsGxsGroupId _grpId ;
RsGeneralDataService *_store ;
std::vector<RsGxsMessageId> _msgIds1 ;
std::vector<RsGxsMessageId> _msgIds2 ;
std::string _info ;
};
#endif
RsGenExchange::~RsGenExchange()
{
// need to destruct in a certain order (bad thing, TODO: put down instance ownership rules!)
@ -187,6 +152,7 @@ void RsGenExchange::tick()
processGroupUpdatePublish();
processGroupDelete();
processMessageDelete();
processRecvdData();
@ -264,7 +230,7 @@ void RsGenExchange::tick()
else
{
mIntegrityCheck = new RsGxsIntegrityCheck(mDataStore,mGixs);
mIntegrityCheck->start();
mIntegrityCheck->start("gxs integrity");
mChecking = true;
}
}
@ -340,47 +306,39 @@ bool RsGenExchange::acknowledgeTokenGrp(const uint32_t& token, RsGxsGroupId& grp
return true;
}
void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& privatekeySet, RsTlvSecurityKeySet& publickeySet, bool genPublishKeys)
void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet, bool genPublishKeys)
{
/* create Keys */
RsTlvSecurityKey adminKey, privAdminKey;
GxsSecurity::generateKeyPair(adminKey,privAdminKey) ;
/* create Keys */
RsTlvPublicRSAKey pubAdminKey ;
RsTlvPrivateRSAKey privAdminKey;
// for now all public
adminKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_PUBLIC_ONLY;
privAdminKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL;
GxsSecurity::generateKeyPair(pubAdminKey,privAdminKey) ;
publickeySet.keys[adminKey.keyId] = adminKey;
privatekeySet.keys[privAdminKey.keyId] = privAdminKey;
// for now all public
pubAdminKey.keyFlags |= RSTLV_KEY_DISTRIB_ADMIN ;
privAdminKey.keyFlags |= RSTLV_KEY_DISTRIB_ADMIN ;
if(genPublishKeys)
{
/* set publish keys */
RsTlvSecurityKey publishKey, privPublishKey;
GxsSecurity::generateKeyPair(publishKey,privPublishKey) ;
keySet.public_keys[pubAdminKey.keyId] = pubAdminKey;
keySet.private_keys[privAdminKey.keyId] = privAdminKey;
// for now all public
publishKey.keyFlags = RSTLV_KEY_DISTRIB_PUBLISH | RSTLV_KEY_TYPE_PUBLIC_ONLY;
privPublishKey.keyFlags = RSTLV_KEY_DISTRIB_PUBLISH | RSTLV_KEY_TYPE_FULL;
if(genPublishKeys)
{
/* set publish keys */
RsTlvPublicRSAKey pubPublishKey ;
RsTlvPrivateRSAKey privPublishKey;
publickeySet.keys[publishKey.keyId] = publishKey;
privatekeySet.keys[privPublishKey.keyId] = privPublishKey;
}
GxsSecurity::generateKeyPair(pubPublishKey,privPublishKey) ;
// for now all public
pubPublishKey.keyFlags |= RSTLV_KEY_DISTRIB_PUBLISH ;
privPublishKey.keyFlags |= RSTLV_KEY_DISTRIB_PUBLISH ;
keySet.public_keys[pubPublishKey.keyId] = pubPublishKey;
keySet.private_keys[privPublishKey.keyId] = privPublishKey;
}
}
void RsGenExchange::generatePublicFromPrivateKeys(const RsTlvSecurityKeySet &privatekeySet, RsTlvSecurityKeySet &publickeySet)
{
// actually just copy settings of one key except mark its key flags public
publickeySet = RsTlvSecurityKeySet() ;
RsTlvSecurityKey pubkey ;
for(std::map<RsGxsId, RsTlvSecurityKey>::const_iterator cit=privatekeySet.keys.begin(); cit != privatekeySet.keys.end(); ++cit)
if(GxsSecurity::extractPublicKey(cit->second,pubkey))
publickeySet.keys.insert(std::make_pair(pubkey.keyId, pubkey));
}
uint8_t RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& privateKeySet, RsTlvSecurityKeySet& publicKeySet)
uint8_t RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet)
{
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::createGroup()";
@ -392,19 +350,18 @@ uint8_t RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& privateKe
/* add public admin and publish keys to grp */
// find private admin key
RsTlvSecurityKey privAdminKey;
std::map<RsGxsId, RsTlvSecurityKey>::iterator mit = privateKeySet.keys.begin();
RsTlvPrivateRSAKey privAdminKey;
bool privKeyFound = false; // private admin key
for(; mit != privateKeySet.keys.end(); ++mit)
for( std::map<RsGxsId, RsTlvPrivateRSAKey>::iterator mit = keySet.private_keys.begin(); mit != keySet.private_keys.end(); ++mit)
{
RsTlvSecurityKey& key = mit->second;
RsTlvPrivateRSAKey& key = mit->second;
if((key.keyFlags & RSTLV_KEY_DISTRIB_ADMIN) && (key.keyFlags & RSTLV_KEY_TYPE_FULL))
{
privAdminKey = key;
privKeyFound = true;
break ;
break ;
}
}
@ -416,13 +373,17 @@ uint8_t RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& privateKe
return false;
}
meta->keys = publicKeySet; // only public keys are included to be transported
// only public keys are included to be transported. The 2nd line below is very important.
meta->keys = keySet;
meta->keys.private_keys.clear() ;
// group is self signing
// for the creation of group signature
// only public admin and publish keys are present in meta
uint32_t metaDataLen = meta->serial_size(RS_GXS_GRP_META_DATA_CURRENT_API_VERSION);
uint32_t allGrpDataLen = metaDataLen + grp->grp.bin_len;
char* metaData = new char[metaDataLen];
char* allGrpData = new char[allGrpDataLen]; // msgData + metaData
@ -502,12 +463,11 @@ int RsGenExchange::createGroupSignatures(RsTlvKeySignatureSet& signSet, RsTlvBin
if(haveKey)
{
RsTlvSecurityKey authorKey;
RsTlvPrivateRSAKey authorKey;
mGixs->getPrivateKey(grpMeta.mAuthorId, authorKey);
RsTlvKeySignature sign;
if(GxsSecurity::getSignature((char*)grpData.bin_data, grpData.bin_len,
authorKey, sign))
if(GxsSecurity::getSignature((char*)grpData.bin_data, grpData.bin_len, authorKey, sign))
{
id_ret = SIGN_SUCCESS;
mGixs->timeStampKey(grpMeta.mAuthorId) ;
@ -622,12 +582,12 @@ int RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinar
if(needPublishSign)
{
// public and shared is publish key
RsTlvSecurityKeySet& keys = grpMeta.keys;
RsTlvSecurityKey* publishKey;
const RsTlvSecurityKeySet& keys = grpMeta.keys;
const RsTlvPrivateRSAKey *publishKey;
std::map<RsGxsId, RsTlvSecurityKey>::iterator mit =
keys.keys.begin(), mit_end = keys.keys.end();
std::map<RsGxsId, RsTlvPrivateRSAKey>::const_iterator mit = keys.private_keys.begin(), mit_end = keys.private_keys.end();
bool publish_key_found = false;
for(; mit != mit_end; ++mit)
{
@ -671,7 +631,7 @@ int RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinar
if(haveKey)
{
RsTlvSecurityKey authorKey;
RsTlvPrivateRSAKey authorKey;
mGixs->getPrivateKey(msgMeta.mAuthorId, authorKey);
RsTlvKeySignature sign;
@ -840,13 +800,13 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uin
{
RsTlvKeySignature sign = metaData.signSet.keySignSet[INDEX_AUTHEN_PUBLISH];
std::map<RsGxsId, RsTlvSecurityKey>& keys = grpKeySet.keys;
std::map<RsGxsId, RsTlvSecurityKey>::iterator mit = keys.begin();
std::map<RsGxsId, RsTlvPublicRSAKey>& keys = grpKeySet.public_keys;
std::map<RsGxsId, RsTlvPublicRSAKey>::iterator mit = keys.begin();
RsGxsId keyId;
for(; mit != keys.end() ; ++mit)
{
RsTlvSecurityKey& key = mit->second;
RsTlvPublicRSAKey& key = mit->second;
if(key.keyFlags & RSTLV_KEY_DISTRIB_PUBLIC_deprecated)
{
@ -864,7 +824,7 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uin
if(!keyId.isNull())
{
RsTlvSecurityKey& key = keys[keyId];
RsTlvPublicRSAKey& key = keys[keyId];
publishValidate &= GxsSecurity::validateNxsMsg(*msg, sign, key);
}
else
@ -888,7 +848,7 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uin
if(haveKey)
{
RsTlvSecurityKey authorKey;
RsTlvPublicRSAKey authorKey;
bool auth_key_fetched = mGixs->getKey(metaData.mAuthorId, authorKey) ;
if (auth_key_fetched)
@ -1007,7 +967,7 @@ int RsGenExchange::validateGrp(RsNxsGrp* grp)
std::cerr << " have ID key in cache: yes" << std::endl;
#endif
RsTlvSecurityKey authorKey;
RsTlvPublicRSAKey authorKey;
bool auth_key_fetched = mGixs->getKey(metaData.mAuthorId, authorKey) ;
if (auth_key_fetched)
@ -1168,8 +1128,10 @@ bool RsGenExchange::subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId,
if(mNetService != NULL)
mNetService->subscribeStatusChanged(grpId,subscribe) ;
#ifdef GEN_EXCH_DEBUG
else
std::cerr << "(EE) No mNetService in RsGenExchange for service 0x" << std::hex << mServType << std::dec << std::endl;
#endif
return true;
}
@ -1620,6 +1582,11 @@ void RsGenExchange::deleteGroup(uint32_t& token, RsGxsGrpItem* grpItem)
std::cerr << std::endl;
#endif
}
void RsGenExchange::deleteMsgs(uint32_t& token, const GxsMsgReq& msgs)
{
token = mDataAccess->generatePublicToken();
mMsgDeletePublish.push_back(MsgDeletePublish(msgs, token));
}
void RsGenExchange::publishMsg(uint32_t& token, RsGxsMsgItem *msgItem)
{
@ -2149,20 +2116,23 @@ void RsGenExchange::processGroupUpdatePublish()
//gup.grpItem->meta = *meta;
GxsGrpPendingSign ggps(gup.grpItem, gup.mToken);
bool publishAndAdminPrivatePresent = checkKeys(meta->keys);
if(publishAndAdminPrivatePresent)
if(checkKeys(meta->keys))
{
ggps.mPrivateKeys = meta->keys;
generatePublicFromPrivateKeys(ggps.mPrivateKeys, ggps.mPublicKeys);
ggps.mKeys = meta->keys;
GxsSecurity::createPublicKeysFromPrivateKeys(ggps.mKeys) ;
ggps.mHaveKeys = true;
ggps.mStartTS = time(NULL);
ggps.mLastAttemptTS = 0;
ggps.mIsUpdate = true;
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);
}
@ -2188,6 +2158,7 @@ void RsGenExchange::processRoutingClues()
mTrackingClues.clear() ;
}
void RsGenExchange::processGroupDelete()
{
RS_STACK_MUTEX(mGenMtx) ;
@ -2234,18 +2205,65 @@ void RsGenExchange::processGroupDelete()
mGroupDeletePublish.clear();
}
void RsGenExchange::processMessageDelete()
{
RS_STACK_MUTEX(mGenMtx) ;
#ifdef TODO
typedef std::pair<bool, RsGxsGroupId> GrpNote;
std::map<uint32_t, GrpNote> toNotify;
#endif
for( std::vector<MsgDeletePublish>::iterator vit = mMsgDeletePublish.begin(); vit != mMsgDeletePublish.end(); ++vit)
{
#ifdef TODO
uint32_t token = (*vit).mToken;
const RsGxsGroupId& groupId = gdp.grpItem->meta.mGroupId;
toNotify.insert(std::make_pair( token, GrpNote(true, groupId)));
#endif
mDataStore->removeMsgs( (*vit).mMsgs );
}
#warning TODO: notify for deleted messages
#ifdef SUSPENDED
std::list<RsGxsGroupId> grpDeleted;
std::map<uint32_t, GrpNote>::iterator mit = toNotify.begin();
for(; mit != toNotify.end(); ++mit)
{
GrpNote& note = mit->second;
uint8_t status = note.first ? RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE
: RsTokenService::GXS_REQUEST_V2_STATUS_FAILED;
mGrpNotify.insert(std::make_pair(mit->first, note.second));
mDataAccess->updatePublicRequestStatus(mit->first, status);
if(note.first)
grpDeleted.push_back(note.second);
}
if(!grpDeleted.empty())
{
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PUBLISH, false);
gc->mGrpIdList = grpDeleted;
mNotifications.push_back(gc);
}
#endif
mMsgDeletePublish.clear();
}
bool RsGenExchange::checkKeys(const RsTlvSecurityKeySet& keySet)
{
typedef std::map<RsGxsId, RsTlvSecurityKey> keyMap;
const keyMap& allKeys = keySet.keys;
typedef std::map<RsGxsId, RsTlvPrivateRSAKey> keyMap;
const keyMap& allKeys = keySet.private_keys;
keyMap::const_iterator cit = allKeys.begin();
bool adminFound = false, publishFound = false;
for(; cit != allKeys.end(); ++cit)
{
const RsTlvSecurityKey& key = cit->second;
if(key.keyFlags & RSTLV_KEY_TYPE_FULL)
const RsTlvPrivateRSAKey& key = cit->second;
if(key.keyFlags & RSTLV_KEY_TYPE_FULL) // this one is not useful. Just a security.
{
if(key.keyFlags & RSTLV_KEY_DISTRIB_ADMIN)
adminFound = true;
@ -2254,6 +2272,11 @@ bool RsGenExchange::checkKeys(const RsTlvSecurityKeySet& keySet)
publishFound = true;
}
else if(key.keyFlags & RSTLV_KEY_TYPE_PUBLIC_ONLY) // this one is not useful. Just a security.
{
std::cerr << "(EE) found a public only key in the private key list" << std::endl;
return false ;
}
}
// user must have both private and public parts of publish and admin keys
@ -2292,29 +2315,23 @@ void RsGenExchange::publishGrps()
RsNxsGrp* grp = new RsNxsGrp(mServType);
RsGxsGrpItem* grpItem = ggps.mItem;
RsTlvSecurityKeySet privatekeySet, publicKeySet;
RsTlvSecurityKeySet fullKeySet;
if(!(ggps.mHaveKeys))
{
generateGroupKeys(privatekeySet, publicKeySet, true);
generateGroupKeys(fullKeySet, true);
ggps.mHaveKeys = true;
ggps.mPrivateKeys = privatekeySet;
ggps.mPublicKeys = publicKeySet;
ggps.mKeys = fullKeySet;
}
else
{
privatekeySet = ggps.mPrivateKeys;
publicKeySet = ggps.mPublicKeys;
}
// find private admin key
RsTlvSecurityKey privAdminKey;
std::map<RsGxsId, RsTlvSecurityKey>::iterator mit_keys = privatekeySet.keys.begin();
fullKeySet = ggps.mKeys;
// find private admin key
RsTlvPrivateRSAKey privAdminKey;
bool privKeyFound = false;
for(; mit_keys != privatekeySet.keys.end(); ++mit_keys)
for(std::map<RsGxsId, RsTlvPrivateRSAKey>::iterator mit_keys = fullKeySet.private_keys.begin(); mit_keys != fullKeySet.private_keys.end(); ++mit_keys)
{
RsTlvSecurityKey& key = mit_keys->second;
RsTlvPrivateRSAKey& key = mit_keys->second;
if(key.keyFlags == (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL))
{
@ -2330,8 +2347,7 @@ void RsGenExchange::publishGrps()
// get group id from private admin key id
grpItem->meta.mGroupId = grp->grpId = RsGxsGroupId(privAdminKey.keyId);
ServiceCreate_Return ret = service_CreateGroup(grpItem, privatekeySet);
ServiceCreate_Return ret = service_CreateGroup(grpItem, fullKeySet);
bool serialOk = false, servCreateOk;
@ -2359,7 +2375,7 @@ void RsGenExchange::publishGrps()
grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN | GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED
| GXS_SERV::GROUP_SUBSCRIBE_PUBLISH;
create = createGroup(grp, privatekeySet, publicKeySet);
create = createGroup(grp, fullKeySet);
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::publishGrps() ";
@ -2371,15 +2387,22 @@ void RsGenExchange::publishGrps()
if(create == CREATE_SUCCESS)
{
// Here we need to make sure that no private keys are included. This is very important since private keys
// can be used to modify the group. Normally the private key set is whiped out by createGroup, but
grp->metaData->keys.private_keys.clear() ;
uint32_t mdSize = grp->metaData->serial_size(RS_GXS_GRP_META_DATA_CURRENT_API_VERSION);
char* metaData = new char[mdSize];
serialOk = grp->metaData->serialise(metaData, mdSize,RS_GXS_GRP_META_DATA_CURRENT_API_VERSION);
grp->meta.setBinData(metaData, mdSize);
delete[] metaData;
{
RsTemporaryMemory metaData(mdSize);
serialOk = grp->metaData->serialise(metaData, mdSize,RS_GXS_GRP_META_DATA_CURRENT_API_VERSION);
#warning TODO: grp->meta should be renamed grp->public_meta !
grp->meta.setBinData(metaData, mdSize);
}
// place back private keys for publisher
grp->metaData->keys = privatekeySet;
// Place back private keys for publisher and database storage
grp->metaData->keys.private_keys = fullKeySet.private_keys;
if(mDataStore->validSize(grp) && serialOk)
{
@ -2390,10 +2413,10 @@ void RsGenExchange::publishGrps()
if(ggps.mIsUpdate)
mDataAccess->updateGroupData(grp);
else
mDataAccess->addGroupData(grp);
if(mNetService!=NULL)
mNetService->subscribeStatusChanged(grpId,true) ;
mDataAccess->addGroupData(grp);
#warning this is bad: addGroupData/updateGroupData actially deletes grp. But it may be used below? grp should be a class object and not deleted manually!
if(mNetService!=NULL)
mNetService->subscribeStatusChanged(grpId,true) ;
}
else
{
@ -2513,29 +2536,30 @@ RsGeneralDataService* RsGenExchange::getDataStore()
bool RsGenExchange::getGroupKeys(const RsGxsGroupId &grpId, RsTlvSecurityKeySet &keySet)
{
if(grpId.isNull())
return false;
if(grpId.isNull())
return false;
RS_STACK_MUTEX(mGenMtx) ;
RS_STACK_MUTEX(mGenMtx) ;
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMeta;
grpMeta[grpId] = NULL;
mDataStore->retrieveGxsGrpMetaData(grpMeta);
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMeta;
grpMeta[grpId] = NULL;
mDataStore->retrieveGxsGrpMetaData(grpMeta);
if(grpMeta.empty())
return false;
if(grpMeta.empty())
return false;
RsGxsGrpMetaData* meta = grpMeta[grpId];
RsGxsGrpMetaData* meta = grpMeta[grpId];
if(meta == NULL)
return false;
if(meta == NULL)
return false;
keySet = meta->keys;
keySet = meta->keys;
GxsSecurity::createPublicKeysFromPrivateKeys(keySet) ;
for(std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator it=grpMeta.begin();it!=grpMeta.end();++it)
delete it->second ;
for(std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator it=grpMeta.begin();it!=grpMeta.end();++it)
delete it->second ;
return true;
return true;
}
void RsGenExchange::shareGroupPublishKey(const RsGxsGroupId& grpId,const std::set<RsPeerId>& peers)
@ -2840,8 +2864,8 @@ void RsGenExchange::processRecvdGroups()
// now check if group already existss
if(std::find(existingGrpIds.begin(), existingGrpIds.end(), grp->grpId) == existingGrpIds.end())
{
if(meta->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
meta->mOriginator = grp->PeerId();
//if(meta->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
meta->mOriginator = grp->PeerId();
meta->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED;
@ -2957,7 +2981,7 @@ void RsGenExchange::performUpdateValidation()
if(gu.validUpdate)
{
if(gu.newGrp->metaData->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
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
@ -3021,8 +3045,8 @@ bool RsGenExchange::updateValid(RsGxsGrpMetaData& oldGrpMeta, RsNxsGrp& newGrp)
RsTlvKeySignature adminSign = mit->second;
std::map<RsGxsId, RsTlvSecurityKey>& keys = oldGrpMeta.keys.keys;
std::map<RsGxsId, RsTlvSecurityKey>::iterator keyMit = keys.find(RsGxsId(oldGrpMeta.mGroupId));
std::map<RsGxsId, RsTlvPublicRSAKey>& keys = oldGrpMeta.keys.public_keys;
std::map<RsGxsId, RsTlvPublicRSAKey>::iterator keyMit = keys.find(RsGxsId(oldGrpMeta.mGroupId));
if(keyMit == keys.end())
{

View file

@ -79,8 +79,7 @@ public:
RsGxsGrpItem* mItem;
bool mHaveKeys; // mKeys->first == true if key present
bool mIsUpdate;
RsTlvSecurityKeySet mPrivateKeys;
RsTlvSecurityKeySet mPublicKeys;
RsTlvSecurityKeySet mKeys;
};
typedef std::map<RsGxsGroupId, std::vector<RsGxsMsgItem*> > GxsMsgDataMap;
@ -535,6 +534,14 @@ public:
*/
void publishMsg(uint32_t& token, RsGxsMsgItem* msgItem);
/*!
* Deletes the messages \n
* This will induce a related change message \n
* @param token
* @param msgs
*/
void deleteMsgs(uint32_t& token, const GxsMsgReq& msgs);
protected:
/*!
* This represents the group before its signature is calculated
@ -657,6 +664,7 @@ private:
void processGroupUpdatePublish();
void processGroupDelete();
void processMessageDelete();
void processRoutingClues();
void publishMsgs();
@ -685,7 +693,7 @@ private:
* @return CREATE_SUCCESS for success, CREATE_FAIL for fail,
* CREATE_FAIL_TRY_LATER for Id sign key not avail (but requested)
*/
uint8_t createGroup(RsNxsGrp* grp, RsTlvSecurityKeySet& privateKeySet, RsTlvSecurityKeySet& publicKeySet);
uint8_t createGroup(RsNxsGrp* grp, RsTlvSecurityKeySet& keySet);
/*!
* This completes the creation of an instance on RsNxsMsg
@ -733,16 +741,7 @@ private:
* @param publickeySet contains public generated keys (counterpart of private)
* @param genPublicKeys should publish key pair also be generated
*/
void generateGroupKeys(RsTlvSecurityKeySet& privatekeySet, RsTlvSecurityKeySet& publickeySet, bool genPublishKeys);
/*!
* Generate public set of keys from their private counterparts
* No keys will be generated if one fails
* @param privatekeySet contains private generated keys
* @param publickeySet contains public generated keys (counterpart of private)
* @return false if key gen failed for a key set
*/
void generatePublicFromPrivateKeys(const RsTlvSecurityKeySet& privatekeySet, RsTlvSecurityKeySet& publickeySet);
void generateGroupKeys(RsTlvSecurityKeySet& keySet, bool genPublishKeys);
/*!
* Attempts to validate msg signatures
@ -869,6 +868,7 @@ private:
std::vector<GroupUpdatePublish> mGroupUpdatePublish;
std::vector<GroupDeletePublish> mGroupDeletePublish;
std::vector<MsgDeletePublish> mMsgDeletePublish;
std::map<RsGxsId,std::set<RsPeerId> > mRoutingClues ;
std::list<std::pair<RsGxsMessageId,RsPeerId> > mTrackingClues ;

View file

@ -160,8 +160,8 @@ public:
* @return a pointer to a valid profile if successful, otherwise NULL
*
*/
virtual bool getKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0;
virtual bool getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0; // For signing outgoing messages.
virtual bool getKey(const RsGxsId &id, RsTlvPublicRSAKey& key) = 0;
virtual bool getPrivateKey(const RsGxsId &id, RsTlvPrivateRSAKey& 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
};
@ -213,9 +213,11 @@ class RsGcxs
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 recipients(const RsGxsCircleId &circleId, const RsGxsGroupId& destination_group, std::list<RsGxsId>& idlist) = 0;
virtual bool isRecipient(const RsGxsCircleId &circleId, const RsGxsGroupId& destination_group, const RsGxsId& id) = 0;
virtual bool getLocalCircleServerUpdateTS(const RsGxsCircleId& gid,time_t& grp_server_update_TS,time_t& msg_server_update_TS) =0;
};

View file

@ -1468,7 +1468,7 @@ bool RsGxsDataAccess::getMsgRelatedInfo(MsgRelatedInfoReq *req)
/* first guess is potentially better than Orig (can't be worse!) */
time_t latestTs = 0;
RsGxsMessageId latestMsgId;
RsGxsMsgMetaData* latestMeta;
RsGxsMsgMetaData* latestMeta=NULL;
for(vit_meta = metaV.begin(); vit_meta != metaV.end(); ++vit_meta)
{

File diff suppressed because it is too large Load diff

View file

@ -332,7 +332,7 @@ private:
* Handles an nxs item for msgs synchronisation
* @param item contaims msg sync info
*/
void handleRecvSyncMessage(RsNxsSyncMsgReqItem* item);
void handleRecvSyncMessage(RsNxsSyncMsgReqItem* item,bool item_was_encrypted);
/*!
* Handles an nxs item for group publish key
@ -354,7 +354,7 @@ private:
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);
bool checkCanRecvMsgFromPeer(const RsPeerId& sslId, const RsGxsGrpMetaData& meta, RsGxsCircleId& should_encrypt_id);
void locked_createTransactionFromPending(MsgRespPending* grpPend);
void locked_createTransactionFromPending(GrpRespPending* msgPend);
@ -384,8 +384,10 @@ private:
#endif
bool locked_CanReceiveUpdate(const RsNxsSyncGrpReqItem *item);
bool locked_CanReceiveUpdate(const RsNxsSyncMsgReqItem* item);
bool locked_CanReceiveUpdate(RsNxsSyncMsgReqItem *item, bool &grp_is_known);
static RsGxsGroupId hashGrpId(const RsGxsGroupId& gid,const RsPeerId& pid) ;
private:
typedef std::vector<RsNxsGrp*> GrpFragments;
@ -454,7 +456,8 @@ private:
/*!
* encrypts/decrypts the transaction for the destination circle id.
*/
bool encryptSingleNxsItem(RsNxsItem *item, const RsGxsCircleId& destination_circle, RsNxsItem *& encrypted_item, uint32_t &status) ;
bool encryptSingleNxsItem(RsNxsItem *item, const RsGxsCircleId& destination_circle, const RsGxsGroupId &destination_group, RsNxsItem *& encrypted_item, uint32_t &status) ;
bool decryptSingleNxsItem(const RsNxsEncryptedDataItem *encrypted_item, RsNxsItem *&nxsitem, std::vector<RsTlvPrivateRSAKey> *private_keys=NULL);
bool processTransactionForDecryption(NxsTransaction *tr); // return false when the keys are not loaded => need retry later
void cleanRejectedMessages();

View file

@ -291,7 +291,7 @@ bool MsgCircleIdsRequestVetting::cleared()
}
for(uint32_t i=0;i<mMsgs.size();)
if(!mCircles->isRecipient(mCircleId,mMsgs[i].mAuthorId))
if(!mCircles->isRecipient(mCircleId,mGrpId,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;

View file

@ -54,7 +54,7 @@ RsGxsMessageCleanUp::RsGxsMessageCleanUp(RsGeneralDataService* const dataService
bool RsGxsMessageCleanUp::clean()
{
int i = 1;
uint32_t i = 1;
time_t now = time(NULL);
@ -89,11 +89,14 @@ bool RsGxsMessageCleanUp::clean()
remove &= !(meta->mMsgStatus & GXS_SERV::GXS_MSG_STATUS_KEEP);
// if not subscribed remove messages (can optimise this really)
remove = remove || (grpMeta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED);
remove = remove || (grpMeta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED);
remove = remove || !(grpMeta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED);
if( remove )
{
req[grpId].push_back(meta->mMsgId);
std::cerr << "Scheduling msg id " << meta->mMsgId << " in grp " << grpId << " for removal." << std::endl;
}
delete meta;
@ -281,7 +284,7 @@ bool RsGxsIntegrityCheck::check()
std::cerr << " " << *it << std::endl;
#endif
}
int nb_requested_not_in_cache = 0;
uint32_t nb_requested_not_in_cache = 0;
#ifdef GXSUTIL_DEBUG
std::cerr << " issuing random get on friends for non existing IDs" << std::endl;
@ -289,7 +292,7 @@ bool RsGxsIntegrityCheck::check()
// now request a cache update for them, which triggers downloading from friends, if missing.
for(;nb_requested_not_in_cache<MAX_GXS_IDS_REQUESTS_NET && gxs_ids.size()>0;)
for(;nb_requested_not_in_cache<MAX_GXS_IDS_REQUESTS_NET && !gxs_ids.empty();)
{
uint32_t n = RSRandom::random_u32() % gxs_ids.size() ;
#ifdef GXSUTIL_DEBUG

View file

@ -162,4 +162,15 @@ public:
uint32_t mToken;
};
class MsgDeletePublish
{
public:
MsgDeletePublish(const GxsMsgReq& msgs, uint32_t token)
: mMsgs(msgs), mToken(token) {}
GxsMsgReq mMsgs ;
uint32_t mToken;
};
#endif /* GXSUTIL_H_ */

View file

@ -301,7 +301,7 @@ void p3GxsTunnelService::handleIncomingItem(const RsGxsTunnelId& tunnel_id,RsGxs
delete item ;
}
void p3GxsTunnelService::handleRecvTunnelDataAckItem(const RsGxsTunnelId& id,RsGxsTunnelDataAckItem *item)
void p3GxsTunnelService::handleRecvTunnelDataAckItem(const RsGxsTunnelId &/*id*/,RsGxsTunnelDataAckItem *item)
{
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
@ -349,6 +349,7 @@ void p3GxsTunnelService::handleRecvTunnelDataItem(const RsGxsTunnelId& tunnel_id
RsGxsTunnelClientService *service = NULL ;
RsGxsId peer_from ;
bool is_client_side = false ;
{
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
@ -367,6 +368,7 @@ void p3GxsTunnelService::handleRecvTunnelDataItem(const RsGxsTunnelId& tunnel_id
{
it2->second.client_services.insert(item->service_id) ;
peer_from = it2->second.to_gxs_id ;
is_client_side = (it2->second.direction == RsTurtleGenericDataItem::DIRECTION_CLIENT);
}
// Check if the item has already been received. This is necessary because we actually re-send items until an ACK is received. If the ACK gets lost (connection interrupted) the
@ -380,7 +382,7 @@ void p3GxsTunnelService::handleRecvTunnelDataItem(const RsGxsTunnelId& tunnel_id
it2->second.received_data_prints[item->unique_item_counter] = time(NULL) ;
}
if(service->acceptDataFromPeer(peer_from,tunnel_id))
if(service->acceptDataFromPeer(peer_from,tunnel_id,is_client_side))
service->receiveData(tunnel_id,item->data,item->data_size) ;
item->data = NULL ; // avoids deletion, since the client has the memory now
@ -888,7 +890,7 @@ void p3GxsTunnelService::handleRecvDHPublicKey(RsGxsTunnelDHPublicKeyItem *item)
RsTemporaryMemory data(pubkey_size) ;
BN_bn2bin(item->public_key, data) ;
RsTlvSecurityKey signature_key ;
RsTlvPublicRSAKey signature_key ;
// We need to get the key of the sender, but if the key is not cached, we
// need to get it first. So we let the system work for 2-3 seconds before
@ -1057,9 +1059,9 @@ bool p3GxsTunnelService::locked_sendDHPublicKey(const DH *dh,const RsGxsId& own_
// we should also sign the data and check the signature on the other end.
//
RsTlvKeySignature signature ;
RsTlvSecurityKey signature_key ;
RsTlvSecurityKey signature_key_public ;
RsTlvKeySignature signature ;
RsTlvPrivateRSAKey signature_key ;
RsTlvPublicRSAKey signature_key_public ;
uint32_t error_status ;
@ -1224,7 +1226,9 @@ bool p3GxsTunnelService::locked_sendEncryptedTunnelData(RsGxsTunnelItem *item)
if(it == _gxs_tunnel_contacts.end())
{
std::cerr << "(EE) Cannot find contact key info for tunnel id " << tunnel_id << ". Cannot send message!" << std::endl;
#ifdef DEBUG_GXS_TUNNEL
std::cerr << " Cannot find contact key info for tunnel id " << tunnel_id << ". Cannot send message!" << std::endl;
#endif
return false;
}
if(it->second.status != RS_GXS_TUNNEL_STATUS_CAN_TALK)
@ -1472,6 +1476,7 @@ bool p3GxsTunnelService::getTunnelInfo(const RsGxsTunnelId& tunnel_id,GxsTunnelI
info.tunnel_status = it->second.status;
info.total_size_sent = it->second.total_sent;
info.total_size_received= it->second.total_received;
info.is_client_side = (it->second.direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT);
// Data packets

View file

@ -378,6 +378,12 @@ RsGxsTunnelDataItem *RsGxsTunnelSerialiser::deserialise_RsGxsTunnelDataItem(void
uint32_t offset = 8; // skip the header
uint32_t rssize = getRsItemSize(dat);
bool ok = true ;
if(rssize > size)
{
std::cerr << "RsGxsTunnelDataItem::() Size error while deserializing." << std::endl ;
return NULL ;
}
RsGxsTunnelDataItem *item = new RsGxsTunnelDataItem();
@ -388,9 +394,9 @@ RsGxsTunnelDataItem *RsGxsTunnelSerialiser::deserialise_RsGxsTunnelDataItem(void
ok &= getRawUInt32(dat, rssize, &offset, &item->service_id);
ok &= getRawUInt32(dat, rssize, &offset, &item->data_size);
if(item->data_size > rssize || rssize - item->data_size < offset)
if(item->data_size > rssize || rssize < offset + item->data_size)
{
std::cerr << "RsGxsTunnelDHPublicKeyItem::() Size error while deserializing." << std::endl ;
std::cerr << "RsGxsTunnelDataItem::() Size error while deserializing." << std::endl ;
delete item ;
return NULL ;
}
@ -450,12 +456,18 @@ RsGxsTunnelDataAckItem *RsGxsTunnelSerialiser::deserialise_RsGxsTunnelDataAckIte
return item ;
}
RsGxsTunnelStatusItem *RsGxsTunnelSerialiser::deserialise_RsGxsTunnelStatusItem(void *dat,uint32_t size)
RsGxsTunnelStatusItem *RsGxsTunnelSerialiser::deserialise_RsGxsTunnelStatusItem(void *dat, uint32_t size)
{
uint32_t offset = 8; // skip the header
uint32_t rssize = getRsItemSize(dat);
bool ok = true ;
if(rssize > size)
{
std::cerr << "RsGxsTunnelStatusItem::() Size error while deserializing." << std::endl ;
return NULL ;
}
RsGxsTunnelStatusItem *item = new RsGxsTunnelStatusItem();
/* get mandatory parts first */
@ -464,13 +476,13 @@ RsGxsTunnelStatusItem *RsGxsTunnelSerialiser::deserialise_RsGxsTunnelStatusItem(
if (offset != rssize)
{
std::cerr << "RsGxsTunnelDHPublicKeyItem::() Size error while deserializing." << std::endl ;
std::cerr << "RsGxsTunnelStatusItem::() Size error while deserializing." << std::endl ;
delete item ;
return NULL ;
}
if (!ok)
{
std::cerr << "RsGxsTunnelDHPublicKeyItem::() Unknown error while deserializing." << std::endl ;
std::cerr << "RsGxsTunnelStatusItem::() Unknown error while deserializing." << std::endl ;
delete item ;
return NULL ;
}

View file

@ -146,7 +146,7 @@ class RsGxsTunnelDHPublicKeyItem: public RsGxsTunnelItem
BIGNUM *public_key ;
RsTlvKeySignature signature ; // signs the public key in a row.
RsTlvSecurityKey gxs_key ; // public key of the signer
RsTlvPublicRSAKey gxs_key ; // public key of the signer
private:
// make the object non copy-able

View file

@ -122,7 +122,7 @@ linux-* {
CONFIG += link_pkgconfig
QMAKE_CXXFLAGS *= -Wall -D_FILE_OFFSET_BITS=64
QMAKE_CC = g++
QMAKE_CC = $${QMAKE_CXX}
contains(CONFIG, NO_SQLCIPHER) {
DEFINES *= NO_SQLCIPHER
@ -160,7 +160,7 @@ linux-* {
DEFINES *= PATCHED_LIBUPNP
}
DEFINES *= UBUNTU
DEFINES *= HAS_GNOME_KEYRING
PKGCONFIG *= gnome-keyring-1
PKGCONFIG *= libssl libupnp
PKGCONFIG *= libcrypto zlib
@ -225,7 +225,7 @@ win32-x-g++ {
################################# Windows ##########################################
win32 {
QMAKE_CC = g++
QMAKE_CC = $${QMAKE_CXX}
OBJECTS_DIR = temp/obj
MOC_DIR = temp/moc
DEFINES *= WINDOWS_SYS WIN32 STATICLIB MINGW WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T
@ -259,7 +259,7 @@ win32 {
################################# MacOSX ##########################################
mac {
QMAKE_CC = g++
QMAKE_CC = $${QMAKE_CXX}
OBJECTS_DIR = temp/obj
MOC_DIR = temp/moc
#DEFINES = WINDOWS_SYS WIN32 STATICLIB MINGW

View file

@ -66,6 +66,11 @@ bool PgpAuxUtilsImpl::getGPGAllList(std::list<RsPgpId> &ids)
return AuthGPG::getAuthGPG()->getGPGAllList(ids);
}
bool PgpAuxUtilsImpl::parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const
{
return AuthGPG::getAuthGPG()->parseSignature(sign,signlen,issuer);
}
bool PgpAuxUtilsImpl::askForDeferredSelfSignature(const void *data,
const uint32_t len,
unsigned char *sign,

View file

@ -41,10 +41,9 @@ class PgpAuxUtils
virtual bool getGPGAllList(std::list<RsPgpId> &ids) = 0;
virtual bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const = 0;
virtual bool parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const =0;
virtual bool VerifySignBin(const void *data, uint32_t len, unsigned char *sign, unsigned int signlen, const PGPFingerprintType& withfingerprint) = 0;
virtual bool askForDeferredSelfSignature(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,int& signature_result ) = 0;
};
class PgpAuxUtilsImpl: public PgpAuxUtils
@ -55,6 +54,7 @@ public:
virtual const RsPgpId &getPGPOwnId();
virtual RsPgpId getPGPId(const RsPeerId& sslid);
virtual bool parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const ;
virtual bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const;
virtual bool VerifySignBin(const void *data, uint32_t len, unsigned char *sign, unsigned int signlen, const PGPFingerprintType& withfingerprint);
virtual bool getGPGAllList(std::list<RsPgpId> &ids);

View file

@ -1692,6 +1692,24 @@ bool PGPHandler::mergeKeySignatures(ops_keydata_t *dst,const ops_keydata_t *src)
return to_add.size() > 0 ;
}
bool PGPHandler::parseSignature(unsigned char *sign, unsigned int signlen,RsPgpId& issuer_id)
{
uint64_t issuer ;
if(!PGPKeyManagement::parseSignature(sign,signlen,issuer))
return false ;
unsigned char bytes[8] ;
for(int i=0;i<8;++i)
{
bytes[7-i] = issuer & 0xff ;
issuer >>= 8 ;
}
issuer_id = RsPgpId(bytes) ;
return true ;
}
bool PGPHandler::privateTrustCertificate(const RsPgpId& id,int trustlvl)
{
if(trustlvl < 0 || trustlvl >= 6 || trustlvl == 1)
@ -1960,12 +1978,20 @@ bool PGPHandler::removeKeysFromPGPKeyring(const std::set<RsPgpId>& keys_to_remov
char template_name[_pubring_path.length()+8] ;
sprintf(template_name,"%s.XXXXXX",_pubring_path.c_str()) ;
#if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8
int fd_keyring_backup(mkstemp(template_name));
if (fd_keyring_backup == -1)
#else
if(mktemp(template_name) == NULL)
#endif
{
std::cerr << "PGPHandler::removeKeysFromPGPKeyring(): cannot create keyring backup file. Giving up." << std::endl;
error_code = PGP_KEYRING_REMOVAL_ERROR_CANNOT_CREATE_BACKUP ;
return false ;
}
#if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8
close(fd_keyring_backup); // TODO: keep the file open and use the fd
#endif
if(!ops_write_keyring_to_file(_pubring,ops_false,template_name,ops_true))
{

View file

@ -74,7 +74,7 @@ class PGPHandler
bool haveSecretKey(const RsPgpId& id) const ;
bool importGPGKeyPair(const std::string& filename,RsPgpId& imported_id,std::string& import_error) ;
bool importGPGKeyPairFromString(const std::string& data,RsPgpId& imported_id,std::string& import_error) ;
bool importGPGKeyPairFromString(const std::string& data,RsPgpId& imported_id,std::string& import_error) ;
bool exportGPGKeyPair(const std::string& filename,const RsPgpId& exported_id) const ;
bool availableGPGCertificatesWithPrivateKeys(std::list<RsPgpId>& ids);
@ -85,6 +85,7 @@ class PGPHandler
std::string SaveCertificateToString(const RsPgpId& id,bool include_signatures) const ;
bool exportPublicKey(const RsPgpId& id,unsigned char *& mem,size_t& mem_size,bool armoured,bool include_signatures) const ;
bool parseSignature(unsigned char *sign, unsigned int signlen,RsPgpId& issuer_id) ;
bool SignDataBin(const RsPgpId& id,const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,bool make_raw_signature=false) ;
bool VerifySignBin(const void *data, uint32_t data_len, unsigned char *sign, unsigned int sign_len, const PGPFingerprintType& withfingerprint) ;
bool privateSignCertificate(const RsPgpId& own_id,const RsPgpId& id_of_key_to_sign) ;
@ -110,7 +111,7 @@ class PGPHandler
// Removes the given keys from the keyring. Also backup the keyring to a file which name is automatically generated
// and given pack for proper display.
//
bool removeKeysFromPGPKeyring(const std::set<RsPgpId>& key_ids,std::string& backup_file,uint32_t& error_code) ;
bool removeKeysFromPGPKeyring(const std::set<RsPgpId>& key_ids,std::string& backup_file,uint32_t& error_code) ;
//bool isKeySupported(const RsPgpId& id) const ;

View file

@ -121,13 +121,13 @@ std::string PGPKeyParser::extractRadixPartFromArmouredKey(const std::string& pgp
std::string PGPKeyManagement::makeArmouredKey(const unsigned char *keydata,size_t key_size,const std::string& version_string)
{
std::string outstring ;
Radix64::encode((const char *)keydata,key_size,outstring) ;
Radix64::encode(keydata,key_size,outstring) ;
uint32_t crc = compute24bitsCRC((unsigned char *)keydata,key_size) ;
unsigned char tmp[3] = { uint8_t((crc >> 16) & 0xff), uint8_t((crc >> 8) & 0xff), uint8_t(crc & 0xff) } ;
std::string crc_string ;
Radix64::encode((const char *)tmp,3,crc_string) ;
Radix64::encode(tmp,3,crc_string) ;
#ifdef DEBUG_PGPUTIL
std::cerr << "After signature pruning: " << std::endl;
@ -157,7 +157,77 @@ uint32_t PGPKeyManagement::compute24bitsCRC(unsigned char *octets, size_t len)
crc ^= PGP_CRC24_POLY;
}
}
return crc & 0xFFFFFFL;
return crc & 0xFFFFFFL;
}
bool PGPKeyManagement::parseSignature(const unsigned char *signature, size_t sign_len, uint64_t& issuer)
{
unsigned char *data = (unsigned char *)signature ;
#ifdef DEBUG_PGPUTIL
std::cerr << "Total size: " << len << std::endl;
#endif
uint8_t packet_tag;
uint32_t packet_length ;
PGPKeyParser::read_packetHeader(data,packet_tag,packet_length) ;
#ifdef DEBUG_PGPUTIL
std::cerr << "Packet tag : " << (int)packet_tag << ", length=" << packet_length << std::endl;
#endif
// 2 - parse key data, only keep public key data, user id and self-signature.
bool issuer_found=false ;
if(sign_len < 12) // conservative check to allow the explicit reads below, until header of first sub-packet
return false ;
unsigned char signature_type = data[0] ;
if(signature_type != 4)
return false ;
data += 1 ; // skip version number
data += 1 ; // skip signature type
data += 1 ; // skip public key algorithm
data += 1 ; // skip hash algorithm
uint32_t hashed_size = 256u*data[0] + data[1] ;
data += 2 ;
// now read hashed sub-packets
uint8_t *start_hashed_data = data ;
while(true)
{
int subpacket_size = PGPKeyParser::read_125Size(data) ; // following RFC4880
uint8_t subpacket_type = data[0] ; data+=1 ;
#ifdef DEBUG_PGPUTIL
std::cerr << " SubPacket tag: " << (int)subpacket_type << std::endl;
std::cerr << " SubPacket length: " << subpacket_size << std::endl;
#endif
if(subpacket_type == PGPKeyParser::PGP_PACKET_TAG_ISSUER && subpacket_size == 9)
{
issuer_found = true ;
issuer = PGPKeyParser::read_KeyID(data) ;
}
else
data += subpacket_size-1 ; // we remove the size of subpacket type
if(issuer_found)
break ;
if( (uint64_t)data - (uint64_t)start_hashed_data >= hashed_size )
break ;
}
// non hashed sub-packets are ignored for now.
return issuer_found ;
}
uint64_t PGPKeyParser::read_KeyID(unsigned char *& data)

View file

@ -65,6 +65,8 @@ class PGPKeyManagement
// Computes the 24 bits CRC checksum necessary to all PGP data.
//
static uint32_t compute24bitsCRC(unsigned char *data,size_t len) ;
static bool parseSignature(const unsigned char *signature, size_t sign_len, uint64_t &issuer) ;
};
// This class handles the parsing of PGP packet headers under various (old and new) formats.
@ -75,6 +77,7 @@ class PGPKeyParser
static const uint8_t PGP_PACKET_TAG_PUBLIC_KEY = 6 ;
static const uint8_t PGP_PACKET_TAG_USER_ID = 13 ;
static const uint8_t PGP_PACKET_TAG_SIGNATURE = 2 ;
static const uint8_t PGP_PACKET_TAG_ISSUER = 16 ;
// These functions read and move the data pointer to the next byte after the read section.
//

View file

@ -109,7 +109,7 @@ std::string RsCertificate::toStdString() const
std::string out_string ;
Radix64::encode((char *)buf, p, out_string) ;
Radix64::encode(buf, p, out_string) ;
// Now slice up to 64 chars.
//

View file

@ -554,7 +554,7 @@ bool RsPluginManager::saveList(bool& cleanup, std::list<RsItem*>& list)
// {
// }
RsPQIService::RsPQIService(uint16_t service_type,uint32_t /*tick_delay_in_seconds*/, RsPluginHandler* /*pgHandler*/)
RsPQIService::RsPQIService(uint16_t /*service_type*/, uint32_t /*tick_delay_in_seconds*/, RsPluginHandler* /*pgHandler*/)
: p3Service(),p3Config()
{
}

View file

@ -130,7 +130,7 @@ AuthGPG::AuthGPG(const std::string& path_to_public_keyring,const std::string& pa
{
_force_sync_database = false ;
mCount = 0;
start();
start("AuthGPG");
}
/* This function is called when retroshare is first started
@ -308,6 +308,11 @@ bool AuthGPG::VerifySignature(const void *data, int datalen, const void *sig, un
return PGPHandler::VerifySignBin((unsigned char*)data,datalen,(unsigned char*)sig,siglen,withfingerprint) ;
}
bool AuthGPG::parseSignature(const void *sig, unsigned int siglen, RsPgpId& issuer_id)
{
return PGPHandler::parseSignature((unsigned char*)sig,siglen,issuer_id) ;
}
bool AuthGPG::exportProfile(const std::string& fname,const RsPgpId& exported_id)
{
return PGPHandler::exportGPGKeyPair(fname,exported_id) ;

View file

@ -210,6 +210,7 @@ class AuthGPG: public p3Config, public RsTickingThread, public PGPHandler
****/
virtual bool SignDataBin(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen);
virtual bool VerifySignBin(const void*, uint32_t, unsigned char*, unsigned int, const PGPFingerprintType& withfingerprint);
virtual bool parseSignature(const void *sig, unsigned int siglen, RsPgpId& issuer_id);
virtual bool encryptDataBin(const RsPgpId& pgp_id,const void *data, const uint32_t len, unsigned char *encr, unsigned int *encrlen);
virtual bool decryptDataBin(const void *data, const uint32_t len, unsigned char *decr, unsigned int *decrlen);

View file

@ -991,6 +991,11 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,uint32_t& diagnostic)
#endif
/* copy data into signature */
if(sigoutl < signature->length)
{
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR ;
goto err;
}
sigoutl = signature->length;
memmove(buf_sigout, signature->data, sigoutl);

View file

@ -105,7 +105,6 @@ void p3HistoryMgr::addMessage(const ChatMessage& cm)
if(cm.chat_id.isDistantChatId())
{
uint32_t status;
DistantChatPeerInfo dcpinfo;
if (rsMsgs->getDistantChatStatus(cm.chat_id.toDistantChatId(), dcpinfo))
peerName = cm.chat_id.toPeerId().toStdString();

View file

@ -41,8 +41,6 @@
#include "util/rsprint.h"
#include "util/rsdebug.h"
#include "util/rsstring.h"
const int p3connectzone = 3431;
#include "serialiser/rsconfigitems.h"
#include "retroshare/rsiface.h"
@ -52,6 +50,8 @@ const int p3connectzone = 3431;
/* Network setup States */
static struct RsLog::logInfo p3connectzoneInfo = {RsLog::Default, "p3connect"};
#define p3connectzone &p3connectzoneInfo
/****
* #define LINKMGR_DEBUG 1
@ -110,10 +110,6 @@ peerConnectState::peerConnectState()
inConnAttempt(0),
wasDeniedConnection(false), deniedTS(false), deniedInConnAttempt(false)
{
//sockaddr_clear(&currentlocaladdr);
//sockaddr_clear(&currentserveraddr);
return;
}
std::string textPeerConnectState(peerConnectState &state)
@ -1036,7 +1032,7 @@ bool p3LinkMgrIMPL::connectResult(const RsPeerId &id, bool success, bool isIncom
*/
// from pqissl, when a connection failed due to security
void p3LinkMgrIMPL::notifyDeniedConnection(const RsPgpId& gpgid,const RsPeerId& sslid,const std::string& sslcn,const struct sockaddr_storage &addr, bool incoming)
void p3LinkMgrIMPL::notifyDeniedConnection(const RsPgpId& gpgid,const RsPeerId& sslid,const std::string& sslcn,const struct sockaddr_storage &/*addr*/, bool incoming)
{
std::cerr << "p3LinkMgrIMPL::notifyDeniedConnection()";
std::cerr << " pgpid: " << gpgid;

View file

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

View file

@ -39,7 +39,8 @@
//#include "util/rsprint.h"
//#include "util/rsdebug.h"
const int p3netmgrzone = 7563;
struct RsLog::logInfo p3netmgrzoneInfo = {RsLog::Default, "p3netmgr"};
#define p3netmgrzone &p3netmgrzoneInfo
#include "serialiser/rsconfigitems.h"
#include "retroshare/rsiface.h"
@ -1640,7 +1641,7 @@ void p3NetMgrIMPL::getNetStatus(pqiNetStatus &status)
/* must extract data... then update mNetFlags */
bool dhtOk = netAssistConnectActive();
uint32_t netsize, rsnetsize;
uint32_t netsize = 0, rsnetsize = 0;
netAssistConnectStats(netsize, rsnetsize);
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/

View file

@ -223,8 +223,9 @@ void p3Notify::notifyListPreChange(int list, int type) { FOR_ALL_NOTIFY_CLIENTS
void p3Notify::notifyListChange (int list, int type) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyListChange (list,type) ; }
void p3Notify::notifyErrorMsg (int list, int sev, std::string msg) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyErrorMsg(list,sev,msg) ; }
void p3Notify::notifyChatMessage (const ChatMessage &msg) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatMessage(msg) ; }
void p3Notify::notifyChatStatus (const ChatId& chat_id, const std::string& status_string) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatStatus(chat_id,status_string) ; }
void p3Notify::notifyChatMessage (const ChatMessage &msg) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatMessage(msg) ; }
void p3Notify::notifyChatStatus (const ChatId& chat_id, const std::string& status_string) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatStatus(chat_id,status_string) ; }
void p3Notify::notifyChatCleared (const ChatId& chat_id) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatCleared(chat_id) ; }
void p3Notify::notifyChatLobbyTimeShift (int time_shift) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatLobbyTimeShift(time_shift) ; }
void p3Notify::notifyCustomState (const std::string& peer_id , const std::string& status_string ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyCustomState (peer_id,status_string) ; }

View file

@ -98,9 +98,10 @@ class p3Notify: public RsNotify
void notifyListPreChange (int /* list */, int /* type */) ;
void notifyListChange (int /* list */, int /* type */) ;
void notifyErrorMsg (int /* list */, int /* sev */, std::string /* msg */) ;
void notifyChatMessage (const ChatMessage& /* msg */) ;
void notifyChatStatus (const ChatId& /* chat_id */, const std::string& /* status_string */) ;
void notifyChatLobbyEvent (uint64_t /* lobby id */, uint32_t /* event type */ , const RsGxsId & /* nickname */, const std::string& /* any string */) ;
void notifyChatMessage (const ChatMessage& /* msg */) ;
void notifyChatStatus (const ChatId& /* chat_id */, const std::string& /* status_string */) ;
void notifyChatCleared (const ChatId& /* chat_id */) ;
void notifyChatLobbyEvent (uint64_t /* lobby id */, uint32_t /* event type */ , const RsGxsId & /* nickname */, const std::string& /* any string */) ;
void notifyChatLobbyTimeShift (int /* time_shift*/) ;
void notifyCustomState (const std::string& /* peer_id */, const std::string& /* status_string */) ;
void notifyHashingInfo (uint32_t /* type */, const std::string& /* fileinfo */) ;

View file

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

View file

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

View file

@ -125,7 +125,7 @@ public:
return ok;
}
static RsServicePermissionItem *deserialise(uint8_t *data,uint32_t size)
static RsServicePermissionItem *deserialise(uint8_t *data, uint32_t size)
{
RsServicePermissionItem *item = new RsServicePermissionItem ;
@ -133,6 +133,12 @@ public:
uint32_t rssize = getRsItemSize(data);
bool ok = true ;
if(rssize > size)
{
std::cerr << __PRETTY_FUNCTION__ << ": error while deserialising! Item will be dropped." << std::endl;
return NULL ;
}
/* add mandatory parts first */
ok &= getRawUInt32(data, rssize, &offset, &item->mServiceId);
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, item->mServiceName);
@ -1247,6 +1253,8 @@ void p3ServiceControl::updatePeerConnect(const RsPeerId &peerId)
#ifdef SERVICECONTROL_DEBUG
std::cerr << "p3ServiceControl::updatePeerConnect(): " << peerId.toStdString();
std::cerr << std::endl;
#else
(void)peerId;
#endif
return;
}

View file

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

View file

@ -170,7 +170,7 @@ uint64_t BinFileInterface::bytecount()
return 0;
}
int BinFileInterface::getFileSize()
uint64_t BinFileInterface::getFileSize()
{
return size;
}
@ -229,7 +229,14 @@ int BinEncryptedFileInterface::readdata(void* data, int len)
if(!haveData) // read whole data for first call, or first call after close()
{
encrypDataLen = BinFileInterface::getFileSize();
uint64_t encrypDataLen64 = BinFileInterface::getFileSize();
if(encrypDataLen64 > uint64_t(~(int)0))
{
std::cerr << __PRETTY_FUNCTION__ << ": cannot decrypt files of size > " << ~(int)0 << std::endl;
return -1 ;
}
encrypDataLen = (int)encrypDataLen64 ;
encryptedData = new char[encrypDataLen];
// make sure assign was successful
@ -245,18 +252,21 @@ int BinEncryptedFileInterface::readdata(void* data, int len)
if((encrypDataLen > 0) && (encryptedData != NULL))
{
if(!AuthSSL::getAuthSSL()->decrypt((void*&)(this->data), sizeData, encryptedData, encrypDataLen))
int sizeDataInt = 0 ;
if(!AuthSSL::getAuthSSL()->decrypt((void*&)(this->data), sizeDataInt, encryptedData, encrypDataLen))
{
delete[] encryptedData;
return -1;
}
sizeData = sizeDataInt ;
haveData = true;
delete[] encryptedData;
}
if(len <= sizeData)
if((uint64_t)len <= sizeData)
{
memcpy(data, this->data, len);
cpyCount += len;
@ -270,7 +280,7 @@ int BinEncryptedFileInterface::readdata(void* data, int len)
else
{
if((cpyCount + len) <= sizeData)
if((cpyCount + len) <= (uint64_t)sizeData)
{
memcpy(data, (void *) ((this->data) + cpyCount), len);
cpyCount += len;
@ -306,9 +316,9 @@ uint64_t BinEncryptedFileInterface::bytecount()
bool BinEncryptedFileInterface::moretoread(uint32_t /* usec */)
{
if(haveData)
return (cpyCount < sizeData);
return (cpyCount < (uint64_t)sizeData);
else
return cpyCount < getFileSize();
return cpyCount < (uint64_t)getFileSize();
}
BinMemInterface::BinMemInterface(int defsize, int flags)

View file

@ -76,12 +76,12 @@ virtual RsFileHash gethash();
virtual uint64_t bytecount();
protected:
virtual int getFileSize();
virtual uint64_t getFileSize();
private:
int bin_flags;
FILE *buf;
int size;
uint64_t size;
pqihash *hash;
uint64_t bcount;
};
@ -127,7 +127,7 @@ private:
char* data;
bool haveData;
int sizeData;
uint64_t sizeData;
uint64_t cpyCount;
};

View file

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

View file

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

View file

@ -71,7 +71,7 @@ void pqiConnectCbDummy::peerConnectRequest(const RsPeerId& id,
std::cerr << std::endl;
}
void pqiMonitor::disconnectPeer(const RsPeerId &peer)
void pqiMonitor::disconnectPeer(const RsPeerId &/*peer*/)
{
std::cerr << "(EE) pqiMonitor::disconnectPeer() shouldn't be called!!!"<< std::endl;
}

View file

@ -41,7 +41,8 @@
#include "util/rsstring.h"
#include "util/rsnet.h"
static const int pqinetzone = 96184;
static struct RsLog::logInfo pqinetzoneInfo = {RsLog::Default, "pqinet"};
#define pqinetzone &pqinetzoneInfo
/*****
* #define NET_DEBUG 1

View file

@ -27,13 +27,13 @@
#include "pqi/pqiperson.h"
#include "pqi/pqipersongrp.h"
#include "pqi/pqissl.h"
const int pqipersonzone = 82371;
#include "util/rsdebug.h"
#include "util/rsstring.h"
#include "retroshare/rspeers.h"
static struct RsLog::logInfo pqipersonzoneInfo = {RsLog::Default, "pqiperson"};
#define pqipersonzone &pqipersonzoneInfo
/****
* #define PERSON_DEBUG 1
****/
@ -67,7 +67,7 @@ int pqiperson::SendItem(RsItem *i,uint32_t& serialized_size)
// check if debug output is wanted, to avoid unecessary work
// getZoneLevel() locks a global mutex and does a lookup in a map or returns a default value
// (not sure if this is a performance problem)
if (PQL_DEBUG_BASIC <= getZoneLevel(pqipersonzone))
if (PQL_DEBUG_BASIC <= pqipersonzoneInfo.lvl)
{
std::string out = "pqiperson::SendItem() Active: Sending On\n";
i->print_string(out, 5); // this can be very expensive
@ -80,7 +80,7 @@ int pqiperson::SendItem(RsItem *i,uint32_t& serialized_size)
}
else
{
if (PQL_DEBUG_BASIC <= getZoneLevel(pqipersonzone))
if (PQL_DEBUG_BASIC <= pqipersonzoneInfo.lvl)
{
std::string out = "pqiperson::SendItem()";
out += " Not Active: Used to put in ToGo Store\n";
@ -141,9 +141,19 @@ int pqiperson::tick()
{
RS_STACK_MUTEX(mPersonMtx);
#ifdef PERSON_DEBUG
if(active)
{
std::cerr << "pqiperson: peer=" << (activepqi? (activepqi->PeerId()): (RsPeerId())) <<", active=" << active << ", last HB=" << time(NULL) - lastHeartbeatReceived << " secs ago." ;
if(lastHeartbeatReceived==0)
std::cerr << "!!!!!!!" << std::endl;
else
std::cerr << std::endl;
}
#endif
//if lastHeartbeatReceived is 0, it might be not activated so don't do a net reset.
if ( active && (lastHeartbeatReceived != 0)
&& (time(NULL) - lastHeartbeatReceived) > HEARTBEAT_REPEAT_TIME * 5)
if ( active && time(NULL) > lastHeartbeatReceived + HEARTBEAT_REPEAT_TIME * 20)
{
int ageLastIncoming = time(NULL) - activepqi->getLastIncomingTS();
@ -157,12 +167,7 @@ int pqiperson::tick()
if (ageLastIncoming > 60) // Check timeout
{
#ifdef PERSON_DEBUG
std::cerr << "pqiperson::tick() " << PeerId().toStdString()
<< " No Heartbeat & No Packets -> assume dead."
<< "calling pqissl::reset()" << std::endl;
#endif
std::cerr << "pqiperson::tick() " << PeerId().toStdString() << " No Heartbeat & No Packets for 60 secs -> assume dead." << std::endl;
this->reset_locked();
}
@ -338,11 +343,12 @@ int pqiperson::handleNotifyEvent_locked(NetInterface *ni, int newState,
// mark as active.
active = true;
lastHeartbeatReceived = 0;
lastHeartbeatReceived = time(NULL) ;
activepqi = pqi;
inConnectAttempt = false;
activepqi->start(); // STARTUP THREAD.
// STARTUP THREAD
activepqi->start("pqi " + PeerId().toStdString().substr(0, 11));
// reset all other children (clear up long UDP attempt)
for(it = kids.begin(); it != kids.end(); ++it)

View file

@ -43,7 +43,7 @@ static const int CONNECT_UNREACHABLE = 3;
static const int CONNECT_FIREWALLED = 4;
static const int CONNECT_FAILED = 5;
static const int HEARTBEAT_REPEAT_TIME = 5;
static const time_t HEARTBEAT_REPEAT_TIME = 5;
#include "pqi/pqiqosstreamer.h"
#include "pqi/pqithreadstreamer.h"

View file

@ -31,7 +31,8 @@
#include <stdio.h>
const int pqipersongrpzone = 354;
static struct RsLog::logInfo pqipersongrpzoneInfo = {RsLog::Default, "pqipersongrp"};
#define pqipersongrpzone &pqipersongrpzoneInfo
#ifdef WINDOWS_SYS
///////////////////////////////////////////////////////////
@ -140,7 +141,7 @@ int pqipersongrp::tickServiceSend()
// init
pqipersongrp::pqipersongrp(p3ServiceControl *ctrl, unsigned long flags)
:pqihandler(), p3ServiceServer(this, ctrl), pqil(NULL), initFlags(flags)
:pqihandler(), p3ServiceServer(this, ctrl), pqil(NULL), pqilMtx("pqipersongrp"), initFlags(flags)
{
}
@ -152,7 +153,7 @@ int pqipersongrp::tick()
*/
{
RsStackMutex stack(coreMtx); /******* LOCKED MUTEX **********/
RsStackMutex stack(pqilMtx); /******* LOCKED MUTEX **********/
if (pqil)
{
pqil -> tick();
@ -196,7 +197,7 @@ int pqipersongrp::tick()
int pqipersongrp::status()
{
{
RsStackMutex stack(coreMtx); /******* LOCKED MUTEX **********/
RsStackMutex stack(pqilMtx); /******* LOCKED MUTEX **********/
if (pqil)
{
pqil -> status();
@ -213,7 +214,7 @@ int pqipersongrp::init_listener()
/* extract our information from the p3ConnectMgr */
if (initFlags & PQIPERSON_NO_LISTENER)
{
RsStackMutex stack(coreMtx); /******* LOCKED MUTEX **********/
RsStackMutex stack(pqilMtx); /******* LOCKED MUTEX **********/
pqil = NULL;
}
else
@ -223,7 +224,7 @@ int pqipersongrp::init_listener()
struct sockaddr_storage laddr;
mLinkMgr->getLocalAddress(laddr);
RsStackMutex stack(coreMtx); /******* LOCKED MUTEX **********/
RsStackMutex stack(pqilMtx); /******* LOCKED MUTEX **********/
pqil = locked_createListener(laddr);
}
return 1;
@ -239,7 +240,7 @@ bool pqipersongrp::resetListener(const struct sockaddr_storage &local)
// change the address.
// restart.
RsStackMutex stack(coreMtx); /******* LOCKED MUTEX **********/
RsStackMutex stack(pqilMtx); /******* LOCKED MUTEX **********/
if (pqil != NULL)
{
@ -410,7 +411,7 @@ int pqipersongrp::addPeer(const RsPeerId& id)
{
// The Mutex is required here as pqiListener is not thread-safe.
RsStackMutex stack(coreMtx); /******* LOCKED MUTEX **********/
RsStackMutex stack(pqilMtx); /******* LOCKED MUTEX **********/
pqiperson *pqip = locked_createPerson(id, pqil);
// attach to pqihandler

View file

@ -123,6 +123,7 @@ virtual int checkOutgoingRsItem(RsItem *item, int global)
//int tickServiceSend();
pqilistener *pqil;
RsMutex pqilMtx; /* MUTEX */
unsigned long initFlags;
};

View file

@ -6,6 +6,8 @@
#include "pqiqos.h"
const uint32_t pqiQoS::MAX_PACKET_COUNTER_VALUE = (1 << 24) ;
pqiQoS::pqiQoS(uint32_t nb_levels,float alpha)
: _item_queues(nb_levels),_alpha(alpha)
{
@ -14,6 +16,7 @@ pqiQoS::pqiQoS(uint32_t nb_levels,float alpha)
float c = 1.0f ;
float inc = alpha ;
_nb_items = 0 ;
_id_counter = 0 ;
for(int i=((int)nb_levels)-1;i>=0;--i,c *= alpha)
{
@ -44,7 +47,7 @@ void pqiQoS::print() const
std::cerr << std::endl;
}
void pqiQoS::in_rsItem(void *ptr,int priority)
void pqiQoS::in_rsItem(void *ptr,int size,int priority)
{
if(uint32_t(priority) >= _item_queues.size())
{
@ -52,8 +55,11 @@ void pqiQoS::in_rsItem(void *ptr,int priority)
priority = _item_queues.size()-1 ;
}
_item_queues[priority].push(ptr) ;
_item_queues[priority].push(ptr,size,_id_counter++) ;
++_nb_items ;
if(_id_counter >= MAX_PACKET_COUNTER_VALUE)
_id_counter = 0 ;
}
// int pqiQoS::gatherStatistics(std::vector<uint32_t>& per_service_count,std::vector<uint32_t>& per_priority_count) const
@ -80,7 +86,7 @@ void pqiQoS::in_rsItem(void *ptr,int priority)
// }
void *pqiQoS::out_rsItem()
void *pqiQoS::out_rsItem(uint32_t max_slice_size, uint32_t& size, bool& starts, bool& ends, uint32_t& packet_id)
{
// Go through the queues. Increment counters.
@ -105,11 +111,21 @@ void *pqiQoS::out_rsItem()
if(last >= 0)
{
assert(_nb_items > 0) ;
--_nb_items ;
return _item_queues[last].pop();
// now chop a slice of this item
void *res = _item_queues[last].slice(max_slice_size,size,starts,ends,packet_id) ;
if(ends)
--_nb_items ;
return res ;
}
else
return NULL ;
}

View file

@ -36,75 +36,148 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <vector>
#include <list>
#include <util/rsmemory.h>
class pqiQoS
{
public:
pqiQoS(uint32_t max_levels,float alpha) ;
struct ItemRecord
{
void *data ;
uint32_t current_offset ;
uint32_t size ;
uint32_t id ;
};
class ItemQueue
{
public:
pqiQoS(uint32_t max_levels,float alpha) ;
class ItemQueue
ItemQueue()
{
public:
ItemQueue()
{
_item_count =0 ;
}
void *pop()
{
if(_items.empty())
return NULL ;
_item_count =0 ;
}
void *pop()
{
if(_items.empty())
return NULL ;
void *item = _items.front() ;
_items.pop_front() ;
--_item_count ;
void *item = _items.front().data ;
_items.pop_front() ;
--_item_count ;
return item ;
}
return item ;
}
void push(void *item)
{
_items.push_back(item) ;
++_item_count ;
}
void *slice(uint32_t max_size,uint32_t& size,bool& starts,bool& ends,uint32_t& packet_id)
{
if(_items.empty())
return NULL ;
uint32_t size() const { return _item_count ; }
ItemRecord& rec(_items.front()) ;
packet_id = rec.id ;
float _threshold ;
float _counter ;
float _inc ;
uint32_t _item_count ;
std::list<void*> _items ;
};
// readily get rid of the item if it can be sent as a whole
// This function pops items from the queue, y order of priority
//
void *out_rsItem() ;
if(rec.current_offset == 0 && rec.size < max_size)
{
starts = true ;
ends = true ;
size = rec.size ;
// This function is used to queue items.
//
void in_rsItem(void *item,int priority) ;
return pop() ;
}
starts = (rec.current_offset == 0) ;
ends = (rec.current_offset + max_size >= rec.size) ;
void print() const ;
uint64_t qos_queue_size() const { return _nb_items ; }
if(rec.size <= rec.current_offset)
{
std::cerr << "(EE) severe error in slicing in QoS." << std::endl;
pop() ;
return NULL ;
}
// kills all waiting items.
void clear() ;
size = std::min(max_size, uint32_t((int)rec.size - (int)rec.current_offset)) ;
void *mem = rs_malloc(size) ;
// get some stats about what's going on. service_packets will contain the number of
// packets per service, and queue_sizes will contain the size of the different priority queues.
if(!mem)
{
std::cerr << "(EE) memory allocation error in QoS." << std::endl;
pop() ;
return NULL ;
}
//int gatherStatistics(std::vector<uint32_t>& per_service_count,std::vector<uint32_t>& per_priority_count) const ;
memcpy(mem,&((unsigned char*)rec.data)[rec.current_offset],size) ;
void computeTotalItemSize() const ;
int debug_computeTotalItemSize() const ;
private:
// This vector stores the lists of items with equal priorities.
//
std::vector<ItemQueue> _item_queues ;
float _alpha ;
uint64_t _nb_items ;
if(ends) // we're taking the whole stuff. So we can delete the entry.
{
free(rec.data) ;
_items.pop_front() ;
}
else
rec.current_offset += size ; // by construction, !ends implies rec.current_offset < rec.size
return mem ;
}
void push(void *item,uint32_t size,uint32_t id)
{
ItemRecord rec ;
rec.data = item ;
rec.current_offset = 0 ;
rec.size = size ;
rec.id = id ;
_items.push_back(rec) ;
}
uint32_t size() const { return _item_count ; }
float _threshold ;
float _counter ;
float _inc ;
uint32_t _item_count ;
std::list<ItemRecord> _items ;
};
// This function pops items from the queue, y order of priority
//
void *out_rsItem(uint32_t max_slice_size,uint32_t& size,bool& starts,bool& ends,uint32_t& packet_id) ;
// This function is used to queue items.
//
void in_rsItem(void *item, int size, int priority) ;
void print() const ;
uint64_t qos_queue_size() const { return _nb_items ; }
// kills all waiting items.
void clear() ;
// get some stats about what's going on. service_packets will contain the number of
// packets per service, and queue_sizes will contain the size of the different priority queues.
//int gatherStatistics(std::vector<uint32_t>& per_service_count,std::vector<uint32_t>& per_priority_count) const ;
void computeTotalItemSize() const ;
int debug_computeTotalItemSize() const ;
private:
// This vector stores the lists of items with equal priorities.
//
std::vector<ItemQueue> _item_queues ;
float _alpha ;
uint64_t _nb_items ;
uint32_t _id_counter ;
static const uint32_t MAX_PACKET_COUNTER_VALUE ;
};

View file

@ -25,6 +25,8 @@
#include "pqiqosstreamer.h"
const float pqiQoSstreamer::PQI_QOS_STREAMER_ALPHA = 2.0f ;
pqiQoSstreamer::pqiQoSstreamer(PQInterface *parent, RsSerialiser *rss, const RsPeerId& peerid, BinInterface *bio_in, int bio_flagsin)
: pqithreadstreamer(parent,rss,peerid,bio_in,bio_flagsin), pqiQoS(PQI_QOS_STREAMER_MAX_LEVELS, PQI_QOS_STREAMER_ALPHA)
{
@ -48,12 +50,12 @@ int pqiQoSstreamer::getQueueSize(bool in)
// return pqiQoS::gatherStatistics(per_service_count,per_priority_count) ;
//}
void pqiQoSstreamer::locked_storeInOutputQueue(void *ptr,int priority)
void pqiQoSstreamer::locked_storeInOutputQueue(void *ptr,int size,int priority)
{
_total_item_size += getRsItemSize(ptr) ;
_total_item_size += size ;
++_total_item_count ;
pqiQoS::in_rsItem(ptr,priority) ;
pqiQoS::in_rsItem(ptr,size,priority) ;
}
void pqiQoSstreamer::locked_clear_out_queue()
@ -63,14 +65,16 @@ void pqiQoSstreamer::locked_clear_out_queue()
_total_item_count = 0 ;
}
void *pqiQoSstreamer::locked_pop_out_data()
void *pqiQoSstreamer::locked_pop_out_data(uint32_t max_slice_size, uint32_t& size, bool& starts, bool& ends, uint32_t& packet_id)
{
void *out = pqiQoS::out_rsItem() ;
void *out = pqiQoS::out_rsItem(max_slice_size,size,starts,ends,packet_id) ;
if(out != NULL)
{
_total_item_size -= getRsItemSize(out) ;
--_total_item_count ;
if(ends)
--_total_item_count ;
}
return out ;

View file

@ -34,13 +34,13 @@ class pqiQoSstreamer: public pqithreadstreamer, public pqiQoS
pqiQoSstreamer(PQInterface *parent, RsSerialiser *rss, const RsPeerId& peerid, BinInterface *bio_in, int bio_flagsin);
static const uint32_t PQI_QOS_STREAMER_MAX_LEVELS = 10 ;
static const float PQI_QOS_STREAMER_ALPHA = 2.0 ;
static const float PQI_QOS_STREAMER_ALPHA ;
virtual void locked_storeInOutputQueue(void *ptr,int priority) ;
virtual void locked_storeInOutputQueue(void *ptr, int size, int priority) ;
virtual int locked_out_queue_size() const { return _total_item_count ; }
virtual void locked_clear_out_queue() ;
virtual int locked_compute_out_pkt_size() const { return _total_item_size ; }
virtual void *locked_pop_out_data() ;
virtual void *locked_pop_out_data(uint32_t max_slice_size,uint32_t& size,bool& starts,bool& ends,uint32_t& packet_id);
//virtual int locked_gatherStatistics(std::vector<uint32_t>& per_service_count,std::vector<uint32_t>& per_priority_count) const; // extracting data.

View file

@ -44,7 +44,8 @@
#include "rsserver/p3face.h"
const int pqisslzone = 37714;
static struct RsLog::logInfo pqisslzoneInfo = {RsLog::Default, "pqisslzone"};
#define pqisslzone &pqisslzoneInfo
/*********
#define WAITING_NOT 0
@ -1074,6 +1075,12 @@ int pqissl::Initiate_SSL_Connection()
"pqissl::Initiate_SSL_Connection() SSL Connection Okay");
#endif
if(ssl_connection != NULL)
{
SSL_shutdown(ssl_connection);
SSL_free(ssl_connection) ;
}
ssl_connection = ssl;
net_internal_SSL_set_fd(ssl, sockfd);
@ -1297,7 +1304,7 @@ int pqissl::Authorise_SSL_Connection()
// which could be
// (pqissl's case) sslcert->serveraddr or sslcert->localaddr.
bool res = AuthSSL::getAuthSSL()->CheckCertificate(PeerId(), peercert);
AuthSSL::getAuthSSL()->CheckCertificate(PeerId(), peercert);
bool certCorrect = true; /* WE know it okay already! */
uint32_t check_result ;
@ -1616,6 +1623,10 @@ int pqissl::readdata(void *data, int len)
#ifdef PQISSL_DEBUG
std::cout << "Reading data thread=" << pthread_self() << ", ssl=" << (void*)this << std::endl ;
#endif
// safety check. Apparently this avoids some SIGSEGV.
//
if(ssl_connection == NULL)
return -1;
// There is a do, because packets can be splitted into multiple ssl buffers
// when they are larger than 16384 bytes. Such packets have to be read in
@ -1851,7 +1862,11 @@ bool pqissl::moretoread(uint32_t usec)
#endif
return 1;
}
else
else if(SSL_pending(ssl_connection) > 0)
{
return 1 ;
}
else
{
#ifdef PQISSL_DEBUG
rslog(RSL_DEBUG_ALL, pqisslzone,

View file

@ -35,9 +35,11 @@
#include "util/rsdebug.h"
#include "util/rsstring.h"
#include "retroshare/rsbanlist.h"
#include <unistd.h>
const int pqissllistenzone = 49787;
static struct RsLog::logInfo pqissllistenzoneInfo = {RsLog::Default, "p3peermgr"};
#define pqissllistenzone &pqissllistenzoneInfo
/* NB: This #define makes the listener open 0.0.0.0:X port instead
* of a specific port - this might help retroshare work on PCs with
@ -57,7 +59,7 @@ const int pqissllistenzone = 49787;
pqissllistenbase::pqissllistenbase(const sockaddr_storage &addr, p3PeerMgr *pm)
: laddr(addr), active(false), mPeerMgr(pm)
: laddr(addr), mPeerMgr(pm), active(false)
{
if (!(AuthSSL::getAuthSSL()-> active()))
{
@ -322,11 +324,12 @@ int pqissllistenbase::acceptconnection()
// can't be arsed making them all the time.
struct sockaddr_storage remote_addr;
socklen_t addrlen = sizeof(remote_addr);
int fd = accept(lsock, (struct sockaddr *) &remote_addr, &addrlen);
int err = 0;
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS // ie UNIX
int fd = accept(lsock, (struct sockaddr *) &remote_addr, &addrlen);
int err = 0;
if (fd < 0)
{
pqioutput(PQL_DEBUG_ALL, pqissllistenzone,
@ -347,7 +350,10 @@ int pqissllistenbase::acceptconnection()
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#else //WINDOWS_SYS
if ((unsigned) fd == INVALID_SOCKET)
SOCKET fd = accept(lsock, (struct sockaddr *) &remote_addr, &addrlen);
int err = 0;
if (fd == INVALID_SOCKET)
{
pqioutput(PQL_DEBUG_ALL, pqissllistenzone,
"pqissllistenbase::acceptconnnection() Nothing to Accept!");
@ -369,12 +375,21 @@ int pqissllistenbase::acceptconnection()
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
{
std::string out;
out += "Accepted Connection from ";
out += sockaddr_storage_tostring(remote_addr);
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out);
}
std::cerr << "(II) Checking incoming connection address: " << sockaddr_storage_iptostring(remote_addr) ;
if(rsBanList != NULL && !rsBanList->isAddressAccepted(remote_addr, RSBANLIST_CHECKING_FLAGS_BLACKLIST))
{
std::cerr << " => early rejected at this point, because of blacklist." << std::endl;
return false ;
}
else
std::cerr << " => Accepted (i.e. whitelisted, or not blacklisted)." << std::endl;
{
std::string out;
out += "Accepted Connection from ";
out += sockaddr_storage_tostring(remote_addr);
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out);
}
// Negotiate certificates. SSL stylee.
// Allow negotiations for secure transaction.

View file

@ -29,8 +29,8 @@
#include "pqi/pqisslpersongrp.h"
#include "pqi/authssl.h"
const int pqipersongrpzone = 354;
static struct RsLog::logInfo pqipersongrpzoneInfo = {RsLog::Default, "pqipersongrp"};
#define pqipersongrpzone &pqipersongrpzoneInfo
/****
* #define PQI_DISABLE_UDP 1

View file

@ -38,7 +38,8 @@
#include "pqi/p3linkmgr.h"
const int pqisslproxyzone = 3517;
static struct RsLog::logInfo pqisslproxyzoneInfo = {RsLog::Default, "pqisslproxy"};
#define pqisslproxyzone &pqisslproxyzoneInfo
// #define PROXY_DEBUG 1

View file

@ -40,7 +40,8 @@
#include "pqi/p3linkmgr.h"
#include <unistd.h>
const int pqissludpzone = 3144;
static struct RsLog::logInfo pqissludpzoneInfo = {RsLog::Default, "pqissludp"};
#define pqissludpzone &pqissludpzoneInfo
/* a final timeout, to ensure this never blocks completely
* 300 secs to complete udp/tcp/ssl connection.
@ -615,6 +616,9 @@ bool pqissludp::moretoread(uint32_t usec)
reset_locked();
return 0;
}
if(SSL_pending(ssl_connection) > 0)
return 1 ;
/* otherwise - not error - strange! */
rslog(RSL_DEBUG_BASIC, pqissludpzone,

View file

@ -53,7 +53,8 @@
// #define PQISTORE_DEBUG
//
const int pqistorezone = 9511;
static struct RsLog::logInfo pqistorezoneInfo = {RsLog::Default, "pqistore"};
#define pqistorezone &pqistorezoneInfo
pqistore::pqistore(RsSerialiser *rss, const RsPeerId& srcId, BinInterface *bio_in, int bio_flags_in)
:PQInterface(RsPeerId()), rsSerialiser(rss), bio_flags(bio_flags_in),
@ -406,7 +407,11 @@ bool pqiSSLstore::encryptedSendItems(const std::list<RsItem*>& rsItemList)
if(rsSerialiser->serialise(*it, &data[offset],&sizeItem))
offset += sizeItem;
else
std::cerr << "(EE) pqiSSLstore::encryptedSendItems(): One item did not serialize. The item is probably unknown from the serializer. Dropping the item. " << std::endl;
{
std::cerr << "(EE) pqiSSLstore::encryptedSendItems(): One item did not serialize. The item is probably unknown from the serializer. Dropping the item. " << std::endl;
std::cerr << "Item content: " << std::endl;
(*it)->print(std::cerr) ;
}
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
delete *it;

File diff suppressed because it is too large Load diff

View file

@ -40,6 +40,12 @@
// The interface does not handle connection, just communication.
// possible bioflags: BIN_FLAGS_NO_CLOSE | BIN_FLAGS_NO_DELETE
struct PartialPacketRecord
{
void *mem ;
uint32_t size ;
};
class pqistreamer: public PQInterface
{
public:
@ -55,14 +61,18 @@ class pqistreamer: public PQInterface
}
virtual int SendItem(RsItem *,uint32_t& serialized_size);
virtual RsItem *GetItem();
virtual int tick();
virtual int status();
time_t getLastIncomingTS(); // Time of last data packet, for checking a connection is alive.
virtual void getRates(RsBwRates &rates);
virtual int getQueueSize(bool in); // extracting data.
virtual int gatherStatistics(std::list<RSTrafficClue>& outqueue_stats,std::list<RSTrafficClue>& inqueue_stats); // extracting data.
// mutex protected versions of RateInterface calls.
virtual void setRate(bool b,float f) ;
virtual void setMaxRate(bool b,float f) ;
virtual float getRate(bool b) ;
protected:
int tick_bio();
@ -73,15 +83,15 @@ class pqistreamer: public PQInterface
// These methods are redefined in pqiQoSstreamer
//
virtual void locked_storeInOutputQueue(void *ptr,int priority) ;
virtual void locked_storeInOutputQueue(void *ptr, int size, int priority) ;
virtual int locked_out_queue_size() const ;
virtual void locked_clear_out_queue() ;
virtual int locked_compute_out_pkt_size() const ;
virtual void *locked_pop_out_data() ;
//virtual int locked_gatherStatistics(std::vector<uint32_t>& per_service_count,std::vector<uint32_t>& per_priority_count) const; // extracting data.
virtual int locked_gatherStatistics(std::list<RSTrafficClue>& outqueue_stats,std::list<RSTrafficClue>& inqueue_stats); // extracting data.
virtual void *locked_pop_out_data(uint32_t max_slice_size,uint32_t& size,bool& starts,bool& ends,uint32_t& packet_id);
virtual int locked_gatherStatistics(std::list<RSTrafficClue>& outqueue_stats,std::list<RSTrafficClue>& inqueue_stats); // extracting data.
void updateRates() ;
protected:
RsMutex mStreamerMtx ; // Protects data, fns below, protected so pqiqos can use it too.
@ -139,12 +149,13 @@ class pqistreamer: public PQInterface
// these are representative (but not exact)
int mCurrRead;
int mCurrSent;
int mCurrReadTS; // TS from which these are measured.
int mCurrSentTS;
time_t mCurrReadTS; // TS from which these are measured.
time_t mCurrSentTS;
int mAvgLastUpdate; // TS from which these are measured.
float mAvgReadCount;
float mAvgSentCount;
time_t mAvgLastUpdate; // TS from which these are measured.
uint32_t mAvgReadCount;
uint32_t mAvgSentCount;
time_t mLastIncomingTs;
@ -156,7 +167,12 @@ class pqistreamer: public PQInterface
std::list<RSTrafficClue> mCurrentStatsChunk_Out ;
time_t mStatisticsTimeStamp ;
void locked_addTrafficClue(const RsItem *pqi, uint32_t pktsize, std::list<RSTrafficClue> &lst);
bool mAcceptsPacketSlicing ;
time_t mLastSentPacketSlicingProbe ;
void locked_addTrafficClue(const RsItem *pqi, uint32_t pktsize, std::list<RSTrafficClue> &lst);
RsItem *addPartialPacket(const void *block, uint32_t len, uint32_t slice_packet_id,bool packet_starting,bool packet_ending,uint32_t& total_len);
std::map<uint32_t,PartialPacketRecord> mPartialPackets ;
};
#endif //MRK_PQI_STREAMER_HEADER

View file

@ -34,7 +34,7 @@
//#define PQISTREAMER_DEBUG
pqithreadstreamer::pqithreadstreamer(PQInterface *parent, RsSerialiser *rss, const RsPeerId& id, BinInterface *bio_in, int bio_flags_in)
:pqistreamer(rss, id, bio_in, bio_flags_in), mParent(parent), mThreadMutex("pqithreadstreamer"), mTimeout(0)
:pqistreamer(rss, id, bio_in, bio_flags_in), mParent(parent), mTimeout(0), mThreadMutex("pqithreadstreamer")
{
mTimeout = DEFAULT_STREAMER_TIMEOUT;
mSleepPeriod = DEFAULT_STREAMER_SLEEP;
@ -64,6 +64,8 @@ void pqithreadstreamer::data_tick()
sleep_period = mSleepPeriod;
isactive = mBio->isactive();
}
updateRates() ;
if (!isactive)
{

View file

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

View file

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

View file

@ -83,9 +83,10 @@ virtual ~RsGxsChannels() { return; }
/* Specific Service Data */
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsChannelGroup> &groups) = 0;
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts, std::vector<RsGxsComment> &cmts) = 0;
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts) = 0;
virtual bool getRelatedPosts(const uint32_t &token, std::vector<RsGxsChannelPost> &posts) = 0;
//Not currently used
//virtual bool getRelatedPosts(const uint32_t &token, std::vector<RsGxsChannelPost> &posts) = 0;
/* From RsGxsCommentService */
//virtual bool getCommentData(const uint32_t &token, std::vector<RsGxsComment> &comments) = 0;

View file

@ -48,18 +48,25 @@ class RsGxsCircles;
extern RsGxsCircles *rsGxsCircles;
typedef RsPgpId RsPgpId;
//typedef RsGxsCircleId RsCircleInternalId;
#define GXS_CIRCLE_TYPE_PUBLIC 0x0001
#define GXS_CIRCLE_TYPE_EXTERNAL 0x0002
#define GXS_CIRCLE_TYPE_YOUREYESONLY 0x0003
#define GXS_CIRCLE_TYPE_LOCAL 0x0004
// The meaning of the different circle types is:
//
//
static const uint32_t GXS_CIRCLE_TYPE_PUBLIC = 0x0001 ; // not restricted to a circle
static const uint32_t GXS_CIRCLE_TYPE_EXTERNAL = 0x0002 ; // restricted to an external circle, made of RsGxsId
static const uint32_t GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY = 0x0003 ; // restricted to a subset of friend nodes of a given RS node given by a RsPgpId list
static const uint32_t GXS_CIRCLE_TYPE_LOCAL = 0x0004 ; // not distributed at all
static const uint32_t GXS_CIRCLE_TYPE_EXT_SELF = 0x0005 ; // self-restricted. Not used, except at creation time when the circle ID isn't known yet. Set to EXTERNAL afterwards.
static const uint32_t GXS_CIRCLE_TYPE_YOUR_EYES_ONLY = 0x0006 ; // distributed to nodes signed by your own PGP key only.
// A special one - used only by Circles themselves - meaning Circle ID == Group ID.
#define GXS_CIRCLE_TYPE_EXT_SELF 0x0005
static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST = 0x0001 ;// user is validated by circle admin
static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED = 0x0002 ;// user has subscribed the group
static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_KEY_AVAILABLE = 0x0004 ;// key is available, so we can encrypt for this circle
static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_ALLOWED = 0x0007 ;// user is allowed. Combines all flags above.
/* Permissions is part of GroupMetaData
*/
static const uint32_t GXS_CIRCLE_FLAGS_IS_EXTERNAL = 0x0008 ;// user is allowed
/* Permissions is part of GroupMetaData */
class GxsPermissions
{
@ -72,7 +79,6 @@ public:
RsGxsCircleId mInternalCircle; // if Originator == ownId, otherwise blank.
};
class RsGxsCircleGroup
{
public:
@ -100,59 +106,47 @@ class RsGxsCircleMsg
class RsGxsCircleDetails
{
public:
RsGxsCircleDetails() : mCircleType(GXS_CIRCLE_TYPE_EXTERNAL), mAmIAllowed(false) {}
RsGxsCircleId mCircleId;
std::string mCircleName;
uint32_t mCircleType;
bool mIsExternal;
RsGxsCircleId mRestrictedCircleId;
bool mAmIAllowed ; // true when one of load GXS ids belong to the circle allowed list (admin list & subscribed list).
bool operator ==(const RsGxsCircleDetails& rGxsDetails) {
return ( mCircleId == rGxsDetails.mCircleId
&& mCircleName == rGxsDetails.mCircleName
&& mCircleType == rGxsDetails.mCircleType
&& mIsExternal == rGxsDetails.mIsExternal
&& mAllowedAnonPeers == rGxsDetails.mAllowedAnonPeers
&& mAllowedSignedPeers == rGxsDetails.mAllowedSignedPeers
);
}
bool operator !=(const RsGxsCircleDetails& rGxsDetails) {
return ( mCircleId != rGxsDetails.mCircleId
|| mCircleName != rGxsDetails.mCircleName
|| mCircleType != rGxsDetails.mCircleType
|| mIsExternal != rGxsDetails.mIsExternal
|| mAllowedAnonPeers != rGxsDetails.mAllowedAnonPeers
|| mAllowedSignedPeers != rGxsDetails.mAllowedSignedPeers
);
}
std::set<RsGxsId> mAllowedAnonPeers;
std::map<RsPgpId, std::set<RsGxsId> > mAllowedSignedPeers;
std::set<RsGxsId> mAllowedGxsIds; // This crosses admin list and subscribed list
std::set<RsPgpId> mAllowedNodes;
std::map<RsGxsId,uint32_t> mSubscriptionFlags ; // subscription flags for all ids
};
class RsGxsCircles: public RsGxsIfaceHelper
{
public:
RsGxsCircles(RsGxsIface *gxs)
:RsGxsIfaceHelper(gxs) { return; }
virtual ~RsGxsCircles() { return; }
public:
RsGxsCircles(RsGxsIface *gxs) :RsGxsIfaceHelper(gxs) { return; }
virtual ~RsGxsCircles() { return; }
/* External Interface (Cached stuff) */
virtual bool getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details) = 0;
virtual bool getCircleExternalIdList(std::list<RsGxsCircleId> &circleIds) = 0;
virtual bool getCirclePersonalIdList(std::list<RsGxsCircleId> &circleIds) = 0;
virtual bool getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details) = 0;
virtual bool getCircleExternalIdList(std::list<RsGxsCircleId> &circleIds) = 0;
virtual bool getCirclePersonalIdList(std::list<RsGxsCircleId> &circleIds) = 0;
/* membership management for external circles */
virtual bool requestCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id)=0 ;
virtual bool cancelCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id)=0 ;
/* standard load */
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups) = 0;
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups) = 0;
/* make new group */
virtual void createGroup(uint32_t& token, RsGxsCircleGroup &group) = 0;
/* update an existing group */
virtual void updateGroup(uint32_t &token, RsGxsCircleGroup &group) = 0;
/* make new group */
virtual void createGroup(uint32_t& token, RsGxsCircleGroup &group) = 0;
/* update an existing group */
virtual void updateGroup(uint32_t &token, RsGxsCircleGroup &group) = 0;
};

View file

@ -108,6 +108,19 @@ class RsGxsComment
// This is filled in if detailed Comment Data is called.
std::list<RsGxsVote> mVotes;
const std::ostream &print(std::ostream &out, std::string indent = "", std::string varName = "") const {
out << indent << varName << " of RsGxsComment Values ###################" << std::endl;
mMeta.print(out, indent + " ", "mMeta");
out << indent << " mComment: " << mComment << std::endl;
out << indent << " mUpVotes: " << mUpVotes << std::endl;
out << indent << " mDownVotes: " << mDownVotes << std::endl;
out << indent << " mScore: " << mScore << std::endl;
out << indent << " mOwnVote: " << mOwnVote << std::endl;
out << indent << " mVotes.size(): " << mVotes.size() << std::endl;
out << indent << "######################################################" << std::endl;
return out;
}
};

View file

@ -102,6 +102,7 @@ namespace GXS_SERV {
// GENERIC GXS MACROS
#define IS_MSG_NEW(status) (status & GXS_SERV::GXS_MSG_STATUS_GUI_NEW)
#define IS_MSG_UNREAD(status) (status & GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD)
#define IS_MSG_UNPROCESSED(status) (status & GXS_SERV::GXS_MSG_STATUS_UNPROCESSED)
#define IS_GROUP_PGP_AUTHED(signFlags) (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG)
#define IS_GROUP_MESSAGE_TRACKING(signFlags) (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES)
@ -111,7 +112,4 @@ namespace GXS_SERV {
#define IS_GROUP_SUBSCRIBED(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)
#define IS_GROUP_NOT_SUBSCRIBED(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED)
#define IS_MSG_UNPROCESSED(status) (status & GXS_SERV::GXS_MSG_STATUS_UNPROCESSED)
#endif // RSGXSFLAGS_H

View file

@ -70,7 +70,8 @@ virtual ~RsGxsForums() { return; }
/* Specific Service Data */
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsForumGroup> &groups) = 0;
virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs) = 0;
virtual bool getRelatedMessages(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs) = 0;
//Not currently used
//virtual bool getRelatedMessages(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs) = 0;
//////////////////////////////////////////////////////////////////////////////
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) = 0;

View file

@ -131,6 +131,24 @@ public:
time_t mChildTs;
std::string mServiceString; // Service Specific Free-Form extra storage.
const std::ostream &print(std::ostream &out, std::string indent = "", std::string varName = "") const {
out
<< indent << varName << " of RsMsgMetaData Values ###################" << std::endl
<< indent << " mGroupId: " << mGroupId.toStdString() << std::endl
<< indent << " mMsgId: " << mMsgId.toStdString() << std::endl
<< indent << " mThreadId: " << mThreadId.toStdString() << std::endl
<< indent << " mParentId: " << mParentId.toStdString() << std::endl
<< indent << " mOrigMsgId: " << mOrigMsgId.toStdString() << std::endl
<< indent << " mAuthorId: " << mAuthorId.toStdString() << std::endl
<< indent << " mMsgName: " << mMsgName << std::endl
<< indent << " mPublishTs: " << mPublishTs << std::endl
<< indent << " mMsgFlags: " << std::hex << mMsgFlags << std::dec << std::endl
<< indent << " mMsgStatus: " << std::hex << mMsgStatus << std::dec << std::endl
<< indent << " mChildTs: " << mChildTs << std::endl
<< indent << " mServiceString: " << mServiceString << std::endl
<< indent << "######################################################" << std::endl;
return out;
}
};
class GxsGroupStatistic

View file

@ -66,7 +66,7 @@ public:
// Gives feedback about type of data that is allowed in. For security reasons, this always needs to be re-derived (Clients can return true on default)
virtual bool acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTunnelId& tunnel_id) = 0 ;
virtual bool acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTunnelId& tunnel_id,bool is_client_side) = 0 ;
};
class GxsTunnelInfo
@ -80,6 +80,7 @@ public:
uint32_t tunnel_status ; // active, requested, DH pending, etc.
uint32_t total_size_sent ; // total bytes sent through that tunnel since openned (including management).
uint32_t total_size_received ; // total bytes received through that tunnel since openned (including management).
bool is_client_side ; // specifiec wether we are client(managing the tunnel) or server.
// Data packets

View file

@ -69,6 +69,7 @@ static const uint32_t RS_IDENTITY_FLAGS_IS_A_CONTACT = 0x0001;
static const uint32_t RS_IDENTITY_FLAGS_PGP_LINKED = 0x0002;
static const uint32_t RS_IDENTITY_FLAGS_PGP_KNOWN = 0x0004;
static const uint32_t RS_IDENTITY_FLAGS_IS_OWN_ID = 0x0008;
static const uint32_t RS_IDENTITY_FLAGS_IS_DEPRECATED= 0x0010; // used to denote keys with deprecated fingerprint format.
class GxsReputation
{
@ -235,6 +236,7 @@ virtual bool getIdDetails(const RsGxsId &id, RsIdentityDetails &details) = 0;
// Fills up list of all own ids. Returns false if ids are not yet loaded.
virtual bool getOwnIds(std::list<RsGxsId> &ownIds) = 0;
virtual bool isOwnId(const RsGxsId& id) = 0;
//
virtual bool submitOpinion(uint32_t& token, const RsGxsId &id,

View file

@ -98,8 +98,7 @@ class RsInit
* Post Login Options
*/
static bool getStartMinimised() ;
static std::string getRetroShareLink();
static bool getStartMinimised();
static int getSslPwdLen();
static bool getAutoLogin();

View file

@ -307,7 +307,6 @@ public:
bool isBroadcast() const;
RsPeerId toPeerId() const;
RsGxsId toGxsId() const;
ChatLobbyId toLobbyId() const;
DistantChatPeerId toDistantChatId() const;
@ -444,12 +443,13 @@ virtual bool resetMessageStandardTagTypes(Rs::Msgs::MsgTagType& tags) = 0;
// sendChat for broadcast, private, lobby and private distant chat
// note: for lobby chat, you first have to subscribe to a lobby
// for private distant chat, it is reqired to have an active distant chat session
virtual bool sendChat(ChatId id, std::string msg) = 0;
virtual bool sendChat(ChatId id, std::string msg) = 0;
virtual uint32_t getMaxMessageSecuritySize(int type) = 0;
virtual void sendStatusString(const ChatId& id,const std::string& status_string) = 0 ;
virtual void sendStatusString(const ChatId& id,const std::string& status_string) = 0;
virtual void clearChatLobby(const ChatId& id) = 0;
virtual void setCustomStateString(const std::string& status_string) = 0 ;
virtual void setCustomStateString(const std::string& status_string) = 0 ;
virtual std::string getCustomStateString() = 0 ;
virtual std::string getCustomStateString(const RsPeerId& peer_id) = 0 ;
@ -479,8 +479,8 @@ virtual bool setIdentityForChatLobby(const ChatLobbyId& lobby_id,const RsGxsId&
virtual bool getIdentityForChatLobby(const ChatLobbyId& lobby_id,RsGxsId& nick) = 0 ;
virtual bool setDefaultIdentityForChatLobby(const RsGxsId& nick) = 0;
virtual void getDefaultIdentityForChatLobby(RsGxsId& id) = 0 ;
virtual void setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe) = 0 ;
virtual bool getLobbyAutoSubscribe(const ChatLobbyId& lobby_id) = 0 ;
virtual void setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe) = 0 ;
virtual bool getLobbyAutoSubscribe(const ChatLobbyId& lobby_id) = 0 ;
virtual ChatLobbyId createChatLobby(const std::string& lobby_name,const RsGxsId& lobby_identity,const std::string& lobby_topic,const std::set<RsPeerId>& invited_friends,ChatLobbyFlags lobby_privacy_type) = 0 ;
/****************************************/

View file

@ -210,9 +210,10 @@ class NotifyClient
virtual void notifyListPreChange (int /* list */, int /* type */) {}
virtual void notifyListChange (int /* list */, int /* type */) {}
virtual void notifyErrorMsg (int /* list */, int /* sev */, std::string /* msg */) {}
virtual void notifyChatMessage (const ChatMessage& /* msg */) {}
virtual void notifyChatStatus (const ChatId& /* chat_id */, const std::string& /* status_string */) {}
virtual void notifyChatLobbyEvent (uint64_t /* lobby id */, uint32_t /* event type */ ,const RsGxsId& /* nickname */,const std::string& /* any string */) {}
virtual void notifyChatMessage (const ChatMessage& /* msg */) {}
virtual void notifyChatStatus (const ChatId& /* chat_id */, const std::string& /* status_string */) {}
virtual void notifyChatCleared (const ChatId& /* chat_id */) {}
virtual void notifyChatLobbyEvent (uint64_t /* lobby id */, uint32_t /* event type */ ,const RsGxsId& /* nickname */,const std::string& /* any string */) {}
virtual void notifyChatLobbyTimeShift (int /* time_shift*/) {}
virtual void notifyCustomState (const std::string& /* peer_id */, const std::string& /* status_string */) {}
virtual void notifyHashingInfo (uint32_t /* type */, const std::string& /* fileinfo */) {}

View file

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

View file

@ -84,7 +84,8 @@ virtual ~RsPosted() { return; }
/* Specific Service Data */
virtual bool getGroupData(const uint32_t &token, std::vector<RsPostedGroup> &groups) = 0;
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts) = 0;
virtual bool getRelatedPosts(const uint32_t &token, std::vector<RsPostedPost> &posts) = 0;
//Not currently used
//virtual bool getRelatedPosts(const uint32_t &token, std::vector<RsPostedPost> &posts) = 0;
/* From RsGxsCommentService */
//virtual bool getCommentData(const uint32_t &token, std::vector<RsGxsComment> &comments) = 0;

View file

@ -31,8 +31,8 @@
class RsReputations
{
public:
static const float REPUTATION_THRESHOLD_ANTI_SPAM = 1.4f ;
static const float REPUTATION_THRESHOLD_DEFAULT = 1.0f ;
static const float REPUTATION_THRESHOLD_ANTI_SPAM;
static const float REPUTATION_THRESHOLD_DEFAULT;
// This is the interface file for the reputation system
//
@ -51,6 +51,8 @@ public:
virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) =0;
virtual bool getReputationInfo(const RsGxsId& id,ReputationInfo& info) =0 ;
virtual void setNodeAutoBanThreshold(uint32_t n) =0;
virtual uint32_t nodeAutoBanThreshold() =0;
// This one is a proxy designed to allow fast checking of a GXS id.
// it basically returns true if assessment is not ASSESSMENT_OK

View file

@ -118,6 +118,15 @@ class Condition
std::string name;
};
class PeerBandwidthLimits
{
public:
PeerBandwidthLimits() : max_up_rate_kbs(0), max_dl_rate_kbs(0) {}
uint32_t max_up_rate_kbs ;
uint32_t max_dl_rate_kbs ;
};
//class SearchRequest // unused stuff.
//{
// public:
@ -324,9 +333,9 @@ class CompressedChunkMap
uint32_t residue = total_size%chunk_size ;
if(residue && operator[](nbchks-1))
return (filledChunks(nbchks)-1)*chunk_size + (total_size%chunk_size) ;
return (filledChunks(nbchks)-1)*(uint64_t)chunk_size + (total_size%chunk_size) ;
else
return filledChunks(nbchks)*chunk_size ;
return filledChunks(nbchks)*(uint64_t)chunk_size ;
}
inline bool operator[](uint32_t i) const { return (_map[i >> 5] & (1 << (i & 31))) > 0 ; }

View file

@ -71,9 +71,9 @@ void RsServer::ConfigFinalSave()
mConfigMgr->completeConfiguration();
}
void RsServer::startServiceThread(RsTickingThread *t)
void RsServer::startServiceThread(RsTickingThread *t, const std::string &threadName)
{
t->start() ;
t->start(threadName) ;
mRegisteredServiceThreads.push_back(t) ;
}

View file

@ -35,10 +35,69 @@
#include <sqlcipher/sqlite3.h>
#endif
#ifndef RS_ENABLE_ZCNATASSIST
#ifdef RS_USE_LIBUPNP
#include "upnp/upnpconfig.h"
#else
#include "miniupnpc/miniupnpc.h"
#endif // RS_USE_LIBUPNP
#endif // RS_ENABLE_ZCNATASSIST
std::string RsServer::getSQLCipherVersion()
{
sqlite3* mDb;
std::string versionstring("");
const char* version;
int rc = sqlite3_open_v2("", &mDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE , NULL); //create DB in a temp file
if(rc){
std::cerr << "Can't open database, Error code: " << sqlite3_errmsg(mDb)
<< std::endl;
sqlite3_close(mDb);
mDb = NULL;
return "";
}
std::string sqlQuery = "PRAGMA cipher_version;";
sqlite3_stmt* stmt = NULL;
rc = sqlite3_prepare_v2(mDb, sqlQuery.c_str(), sqlQuery.length(), &stmt, NULL);
if (rc == SQLITE_OK) {
rc = sqlite3_step(stmt);
switch (rc) {
case SQLITE_ROW:
version = (const char *)sqlite3_column_text(stmt, 0); //not needed to free
versionstring.append(version);
break;
case SQLITE_DONE:
break;
default:
std::cerr << "RetroDb::tableExists(): Error executing statement (code: " << rc << ")"
<< std::endl;
break;
}
}
if (stmt) {
sqlite3_finalize(stmt);
}
sqlite3_close(mDb); // no-op if mDb is NULL (https://www.sqlite.org/c3ref/close.html)
return versionstring;
}
void RsServer::getLibraries(std::list<RsLibraryInfo> &libraries)
{
libraries.push_back(RsLibraryInfo("bzip2", BZ2_bzlibVersion()));
libraries.push_back(RsLibraryInfo("OpenSSL", SSLeay_version(SSLEAY_VERSION)));
libraries.push_back(RsLibraryInfo("SQLCipher", SQLITE_VERSION));
libraries.push_back(RsLibraryInfo("SQLite", SQLITE_VERSION));
#ifndef NO_SQLCIPHER
libraries.push_back(RsLibraryInfo("SQLCipher", getSQLCipherVersion()));
#endif
#ifndef RS_ENABLE_ZCNATASSIST
#ifdef RS_USE_LIBUPNP
libraries.push_back(RsLibraryInfo("UPnP (libupnp)", UPNP_VERSION_STRING));
#else
libraries.push_back(RsLibraryInfo("UPnP (MiniUPnP)", MINIUPNPC_VERSION));
#endif // RS_USE_LIBUPNP
#endif // RS_ENABLE_ZCNATASSIST
libraries.push_back(RsLibraryInfo("Zlib", ZLIB_VERSION));
}

View file

@ -69,6 +69,14 @@ static double getCurrentTS()
return cts;
}
// These values should be tunable from the GUI, to offer a compromise between speed and CPU use.
// In some cases (VOIP) it's likely that we will need to set them temporarily to a very low
// value, in order to favor a fast feedback
const double RsServer::minTimeDelta = 0.05; // 25;
const double RsServer::maxTimeDelta = 0.2;
const double RsServer::kickLimit = 0.15;
RsServer::RsServer()
: coreMutex("RsServer")
@ -134,7 +142,7 @@ void RsServer::data_tick()
double ts = getCurrentTS();
double delta = ts - mLastts;
/* for the fast ticked stuff */
if (delta > mTimeDelta)
{

View file

@ -120,8 +120,8 @@ class RsServer: public RsControl, public RsTickingThread
public:
/* Config */
virtual void ConfigFinalSave( );
virtual void startServiceThread(RsTickingThread *t) ;
virtual void ConfigFinalSave( );
virtual void startServiceThread(RsTickingThread *t, const std::string &threadName) ;
/************* Rs shut down function: in upnp 'port lease time' bug *****************/
@ -139,6 +139,8 @@ class RsServer: public RsControl, public RsTickingThread
private:
std::string getSQLCipherVersion();
// The real Server Parts.
//filedexserver *server;
@ -194,9 +196,9 @@ class RsServer: public RsControl, public RsTickingThread
double mAvgTickRate ;
double mTimeDelta ;
static const double minTimeDelta = 0.1; // 25;
static const double maxTimeDelta = 0.5;
static const double kickLimit = 0.15;
static const double minTimeDelta; // 25;
static const double maxTimeDelta;
static const double kickLimit;
};
/* Helper function to convert windows paths

View file

@ -409,9 +409,14 @@ uint32_t p3Msgs::getMaxMessageSecuritySize(int type)
return mChatSrv->getMaxMessageSecuritySize(type);
}
void p3Msgs::sendStatusString(const ChatId& peer_id, const std::string& status_string)
void p3Msgs::sendStatusString(const ChatId& id, const std::string& status_string)
{
mChatSrv->sendStatusString(peer_id, status_string);
mChatSrv->sendStatusString(id, status_string);
}
void p3Msgs::clearChatLobby(const ChatId &id)
{
mChatSrv->clearChatLobby(id);
}
void p3Msgs::getOwnAvatarData(unsigned char *& data,int& size)

View file

@ -127,12 +127,18 @@ class p3Msgs: public RsMsgs
*/
virtual uint32_t getMaxMessageSecuritySize(int type);
/*!
* sends immediate status string to a specific peer, e.g. in a private chat
* @param chat_id chat id to send status string to
* @param status_string immediate status to send
*/
virtual void sendStatusString(const ChatId& chat_id, const std::string& status_string) ;
/*!
* sends immediate status string to a specific peer, e.g. in a private chat
* @param chat_id chat id to send status string to
* @param status_string immediate status to send
*/
virtual void sendStatusString(const ChatId& id, const std::string& status_string) ;
/**
* @brief clearChatLobby: Signal chat was cleared by GUI.
* @param id: Chat id cleared.
*/
virtual void clearChatLobby(const ChatId &id);
/****************************************/

Some files were not shown because too many files have changed in this diff Show more