mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-06-04 12:49:28 -04:00
Merge branch 'master' into Fix_ClangWarnings
This commit is contained in:
commit
9102a698e4
66 changed files with 2471 additions and 559 deletions
|
@ -133,12 +133,7 @@ void HashStorage::data_tick()
|
|||
|
||||
if(!mChanged) // otherwise it might prevent from saving the hash cache
|
||||
{
|
||||
std::cerr << "Stopping hashing thread." << std::endl;
|
||||
shutdown();
|
||||
mRunning = false ;
|
||||
mTotalSizeToHash = 0;
|
||||
mTotalFilesToHash = 0;
|
||||
std::cerr << "done." << std::endl;
|
||||
stopHashThread();
|
||||
}
|
||||
|
||||
RsServer::notify()->notifyHashingInfo(NOTIFY_HASHTYPE_FINISH, "") ;
|
||||
|
@ -262,10 +257,12 @@ bool HashStorage::requestHash(const std::string& full_path,uint64_t size,rstime_
|
|||
it->second.time_stamp = now ;
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
if(it->second.time_stamp != (uint64_t)mod_time)
|
||||
if(it->second.modf_stamp != (uint64_t)mod_time)
|
||||
{
|
||||
std::cerr << "(WW) detected a 1 hour shift in file modification time. This normally happens to many files at once, when daylight saving time shifts (file=\"" << full_path << "\")." << std::endl;
|
||||
it->second.time_stamp = (uint64_t)mod_time;
|
||||
it->second.modf_stamp = (uint64_t)mod_time;
|
||||
mChanged = true;
|
||||
startHashThread();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -301,6 +298,13 @@ bool HashStorage::requestHash(const std::string& full_path,uint64_t size,rstime_
|
|||
mTotalSizeToHash += size ;
|
||||
++mTotalFilesToHash;
|
||||
|
||||
startHashThread();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void HashStorage::startHashThread()
|
||||
{
|
||||
if(!mRunning)
|
||||
{
|
||||
mRunning = true ;
|
||||
|
@ -308,10 +312,21 @@ bool HashStorage::requestHash(const std::string& full_path,uint64_t size,rstime_
|
|||
mHashCounter = 0;
|
||||
mTotalHashedSize = 0;
|
||||
|
||||
start("fs hash cache") ;
|
||||
start("fs hash cache") ;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
void HashStorage::stopHashThread()
|
||||
{
|
||||
if (mRunning)
|
||||
{
|
||||
std::cerr << "Stopping hashing thread." << std::endl;
|
||||
shutdown();
|
||||
mRunning = false ;
|
||||
mTotalSizeToHash = 0;
|
||||
mTotalFilesToHash = 0;
|
||||
std::cerr << "done." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void HashStorage::clean()
|
||||
|
|
|
@ -97,6 +97,9 @@ private:
|
|||
*/
|
||||
void clean() ;
|
||||
|
||||
void startHashThread();
|
||||
void stopHashThread();
|
||||
|
||||
// loading/saving the entire hash database to a file
|
||||
|
||||
void locked_save() ;
|
||||
|
|
|
@ -692,22 +692,40 @@ void p3GxsTunnelService::receiveTurtleData(const RsTurtleGenericTunnelItem *gite
|
|||
(void) direction;
|
||||
#endif
|
||||
|
||||
const RsTurtleGenericDataItem *item = dynamic_cast<const RsTurtleGenericDataItem*>(gitem) ;
|
||||
void *data_bytes;
|
||||
uint32_t data_size ;
|
||||
bool accept_fast_items = false;
|
||||
|
||||
if(item == NULL)
|
||||
const RsTurtleGenericFastDataItem *fitem = dynamic_cast<const RsTurtleGenericFastDataItem*>(gitem) ;
|
||||
|
||||
if(fitem != NULL)
|
||||
{
|
||||
std::cerr << "(EE) item is not a data item. That is an error." << std::endl;
|
||||
return ;
|
||||
data_bytes = fitem->data_bytes ;
|
||||
data_size = fitem->data_size ;
|
||||
accept_fast_items = true;
|
||||
}
|
||||
// Call the AES crypto module
|
||||
else
|
||||
{
|
||||
const RsTurtleGenericDataItem *item = dynamic_cast<const RsTurtleGenericDataItem*>(gitem) ;
|
||||
|
||||
if(item == NULL)
|
||||
{
|
||||
std::cerr << "(EE) item is not a data item. That is an error." << std::endl;
|
||||
return ;
|
||||
}
|
||||
data_bytes = item->data_bytes ;
|
||||
data_size = item->data_size ;
|
||||
}
|
||||
|
||||
// Call the AES crypto module
|
||||
// - the IV is the first 8 bytes of item->data_bytes
|
||||
|
||||
if(item->data_size < 8)
|
||||
if(data_size < 8)
|
||||
{
|
||||
std::cerr << "(EE) item encrypted data stream is too small: size = " << item->data_size << std::endl;
|
||||
std::cerr << "(EE) item encrypted data stream is too small: size = " << data_size << std::endl;
|
||||
return ;
|
||||
}
|
||||
if(*((uint64_t*)item->data_bytes) != 0) // WTF?? we should use flags
|
||||
if(*((uint64_t*)data_bytes) != 0) // WTF?? we should use flags
|
||||
{
|
||||
#ifdef DEBUG_GXS_TUNNEL
|
||||
std::cerr << " Item is encrypted." << std::endl;
|
||||
|
@ -715,7 +733,7 @@ void p3GxsTunnelService::receiveTurtleData(const RsTurtleGenericTunnelItem *gite
|
|||
|
||||
// if cannot decrypt, it means the key is wrong. We need to re-negociate a new key.
|
||||
|
||||
handleEncryptedData((uint8_t*)item->data_bytes,item->data_size,hash,virtual_peer_id) ;
|
||||
handleEncryptedData((uint8_t*)data_bytes,data_size,hash,virtual_peer_id,accept_fast_items) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -725,8 +743,8 @@ void p3GxsTunnelService::receiveTurtleData(const RsTurtleGenericTunnelItem *gite
|
|||
|
||||
// Now try deserialise the decrypted data to make an RsItem out of it.
|
||||
//
|
||||
uint32_t pktsize = item->data_size-8;
|
||||
RsItem *citem = RsGxsTunnelSerialiser().deserialise(&((uint8_t*)item->data_bytes)[8],&pktsize) ;
|
||||
uint32_t pktsize = data_size-8;
|
||||
RsItem *citem = RsGxsTunnelSerialiser().deserialise(&((uint8_t*)data_bytes)[8],&pktsize) ;
|
||||
|
||||
if(citem == NULL)
|
||||
{
|
||||
|
@ -752,7 +770,11 @@ void p3GxsTunnelService::receiveTurtleData(const RsTurtleGenericTunnelItem *gite
|
|||
|
||||
// This function encrypts the given data and adds a MAC and an IV into a serialised memory chunk that is then sent through the tunnel.
|
||||
|
||||
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_004
|
||||
bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t data_size,const TurtleFileHash& hash,const RsPeerId& virtual_peer_id,bool accepts_fast_items)
|
||||
#else
|
||||
bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t data_size,const TurtleFileHash& hash,const RsPeerId& virtual_peer_id)
|
||||
#endif
|
||||
{
|
||||
#ifdef DEBUG_GXS_TUNNEL
|
||||
std::cerr << "p3GxsTunnelService::handleEncryptedDataItem()" << std::endl;
|
||||
|
@ -795,6 +817,16 @@ bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t
|
|||
std::cerr << "(EE) no tunnel data for tunnel ID=" << tunnel_id << ". This is a bug." << std::endl;
|
||||
return false ;
|
||||
}
|
||||
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_004
|
||||
if(accepts_fast_items)
|
||||
{
|
||||
if(!it2->second.accepts_fast_turtle_items)
|
||||
std::cerr << "(II) received probe for Fast track turtle items for tunnel VPID " << it2->second.virtual_peer_id << ": switching to Fast items mode." << std::endl;
|
||||
|
||||
it2->second.accepts_fast_turtle_items = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
memcpy(aes_key,it2->second.aes_key,GXS_TUNNEL_AES_KEY_SIZE) ;
|
||||
|
||||
#ifdef DEBUG_GXS_TUNNEL
|
||||
|
@ -1291,36 +1323,79 @@ bool p3GxsTunnelService::locked_sendEncryptedTunnelData(RsGxsTunnelItem *item)
|
|||
|
||||
// make a TurtleGenericData item out of it:
|
||||
//
|
||||
RsTurtleGenericDataItem *gitem = new RsTurtleGenericDataItem ;
|
||||
|
||||
gitem->data_size = encrypted_size + GXS_TUNNEL_ENCRYPTION_IV_SIZE + GXS_TUNNEL_ENCRYPTION_HMAC_SIZE ;
|
||||
gitem->data_bytes = rs_malloc(gitem->data_size) ;
|
||||
uint32_t data_size = encrypted_size + GXS_TUNNEL_ENCRYPTION_IV_SIZE + GXS_TUNNEL_ENCRYPTION_HMAC_SIZE ;
|
||||
void *data_bytes = rs_malloc(data_size) ;
|
||||
|
||||
if(gitem->data_bytes == NULL)
|
||||
if(data_bytes == NULL)
|
||||
return false ;
|
||||
|
||||
memcpy(& ((uint8_t*)gitem->data_bytes)[0] ,&IV,8) ;
|
||||
memcpy(& ((uint8_t*)data_bytes)[0] ,&IV,8) ;
|
||||
|
||||
unsigned int md_len = GXS_TUNNEL_ENCRYPTION_HMAC_SIZE ;
|
||||
HMAC(EVP_sha1(),aes_key,GXS_TUNNEL_AES_KEY_SIZE,encrypted_data,encrypted_size,&(((uint8_t*)gitem->data_bytes)[GXS_TUNNEL_ENCRYPTION_IV_SIZE]),&md_len) ;
|
||||
HMAC(EVP_sha1(),aes_key,GXS_TUNNEL_AES_KEY_SIZE,encrypted_data,encrypted_size,&(((uint8_t*)data_bytes)[GXS_TUNNEL_ENCRYPTION_IV_SIZE]),&md_len) ;
|
||||
|
||||
memcpy(& (((uint8_t*)gitem->data_bytes)[GXS_TUNNEL_ENCRYPTION_HMAC_SIZE+GXS_TUNNEL_ENCRYPTION_IV_SIZE]),encrypted_data,encrypted_size) ;
|
||||
memcpy(& (((uint8_t*)data_bytes)[GXS_TUNNEL_ENCRYPTION_HMAC_SIZE+GXS_TUNNEL_ENCRYPTION_IV_SIZE]),encrypted_data,encrypted_size) ;
|
||||
|
||||
#ifdef DEBUG_GXS_TUNNEL
|
||||
std::cerr << " Using IV: " << std::hex << IV << std::dec << std::endl;
|
||||
std::cerr << " Using Key: " << RsUtil::BinToHex((char*)aes_key,GXS_TUNNEL_AES_KEY_SIZE) ; std::cerr << std::endl;
|
||||
std::cerr << " hmac: " << RsUtil::BinToHex((char*)gitem->data_bytes,GXS_TUNNEL_ENCRYPTION_HMAC_SIZE) << std::endl;
|
||||
std::cerr << " hmac: " << RsUtil::BinToHex((char*)data_bytes,GXS_TUNNEL_ENCRYPTION_HMAC_SIZE) << std::endl;
|
||||
#endif
|
||||
#ifdef DEBUG_GXS_TUNNEL
|
||||
std::cerr << "GxsTunnelService::sendEncryptedTunnelData(): Sending encrypted data to virtual peer: " << virtual_peer_id << std::endl;
|
||||
std::cerr << " gitem->data_size = " << gitem->data_size << std::endl;
|
||||
std::cerr << " serialised data = " << RsUtil::BinToHex((unsigned char*)gitem->data_bytes,gitem->data_size,100) ;
|
||||
std::cerr << " data_size = " << data_size << std::endl;
|
||||
std::cerr << " serialised data = " << RsUtil::BinToHex((unsigned char*)data_bytes,data_size,100) ;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
mTurtle->sendTurtleData(virtual_peer_id,gitem) ;
|
||||
|
||||
return true ;
|
||||
// We send the item through the turtle tunnel. We do that using the new 'fast' item type if the tunnel accepts it, and using the old slow one otherwise.
|
||||
// Still if the tunnel hasn't been probed, we duplicate the packet using the new fast item format. The packet being received twice on the other side will
|
||||
// be discarded with a warning.
|
||||
// Note that because the data is deleted by sendTurtleData(), we need to send all packets at the end, and properly duplicate the data when needed.
|
||||
|
||||
#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_004
|
||||
RsTurtleGenericFastDataItem *gitem = new RsTurtleGenericFastDataItem;
|
||||
gitem->data_bytes = data_bytes;
|
||||
gitem->data_size = data_size ;
|
||||
#else
|
||||
RsTurtleGenericDataItem *gitem = NULL;
|
||||
RsTurtleGenericFastDataItem *gitem2 = NULL;
|
||||
|
||||
if(!it->second.accepts_fast_turtle_items)
|
||||
{
|
||||
std::cerr << "Sending old format (slow) item for packet IV=" << std::hex << IV << std::dec << " in tunnel VPID=" << it->second.virtual_peer_id << std::endl;
|
||||
gitem = new RsTurtleGenericDataItem ;
|
||||
|
||||
gitem->data_bytes = data_bytes;
|
||||
gitem->data_size = data_size ;
|
||||
}
|
||||
|
||||
if(it->second.accepts_fast_turtle_items || !it->second.already_probed_for_fast_items)
|
||||
{
|
||||
std::cerr << "Sending new format (fast) item for packet IV=" << std::hex << IV << std::dec << " in tunnel VPID=" << it->second.virtual_peer_id << std::endl;
|
||||
gitem2 = new RsTurtleGenericFastDataItem ;
|
||||
|
||||
if(gitem != NULL) // duplicate the data because it was already sent in gitem.
|
||||
{
|
||||
gitem2->data_bytes = rs_malloc(data_size);
|
||||
gitem2->data_size = data_size ;
|
||||
memcpy(gitem2->data_bytes,data_bytes,data_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
gitem2->data_bytes = data_bytes;
|
||||
gitem2->data_size = data_size ;
|
||||
}
|
||||
|
||||
it->second.already_probed_for_fast_items = true;
|
||||
|
||||
}
|
||||
if(gitem2) mTurtle->sendTurtleData(virtual_peer_id,gitem2) ;
|
||||
#endif
|
||||
if(gitem) mTurtle->sendTurtleData(virtual_peer_id,gitem) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
bool p3GxsTunnelService::requestSecuredTunnel(const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, RsGxsTunnelId &tunnel_id, uint32_t service_id, uint32_t& error_code)
|
||||
|
|
|
@ -128,14 +128,12 @@ public:
|
|||
// Creates the invite if the public key of the distant peer is available.
|
||||
// Om success, stores the invite in the map above, so that we can respond to tunnel requests.
|
||||
//
|
||||
virtual bool requestSecuredTunnel(const RsGxsId& to_id,const RsGxsId& from_id,RsGxsTunnelId& tunnel_id,uint32_t service_id,uint32_t& error_code) ;
|
||||
|
||||
virtual bool closeExistingTunnel(const RsGxsTunnelId &tunnel_id,uint32_t service_id) ;
|
||||
virtual bool getTunnelsInfo(std::vector<GxsTunnelInfo>& infos);
|
||||
virtual bool getTunnelInfo(const RsGxsTunnelId& tunnel_id,GxsTunnelInfo& info);
|
||||
virtual bool sendData(const RsGxsTunnelId& tunnel_id,uint32_t service_id,const uint8_t *data,uint32_t size) ;
|
||||
|
||||
virtual bool registerClientService(uint32_t service_id,RsGxsTunnelClientService *service) ;
|
||||
virtual bool requestSecuredTunnel(const RsGxsId& to_id,const RsGxsId& from_id,RsGxsTunnelId& tunnel_id,uint32_t service_id,uint32_t& error_code) override ;
|
||||
virtual bool closeExistingTunnel(const RsGxsTunnelId &tunnel_id,uint32_t service_id) override ;
|
||||
virtual bool getTunnelsInfo(std::vector<GxsTunnelInfo>& infos) override ;
|
||||
virtual bool getTunnelInfo(const RsGxsTunnelId& tunnel_id,GxsTunnelInfo& info) override ;
|
||||
virtual bool sendData(const RsGxsTunnelId& tunnel_id,uint32_t service_id,const uint8_t *data,uint32_t size) override ;
|
||||
virtual bool registerClientService(uint32_t service_id,RsGxsTunnelClientService *service) override ;
|
||||
|
||||
// derived from p3service
|
||||
|
||||
|
@ -150,6 +148,9 @@ private:
|
|||
{
|
||||
public:
|
||||
GxsTunnelPeerInfo() : last_contact(0), last_keep_alive_sent(0), status(0), direction(0)
|
||||
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_004
|
||||
,accepts_fast_turtle_items(false)
|
||||
#endif
|
||||
{
|
||||
memset(aes_key, 0, GXS_TUNNEL_AES_KEY_SIZE);
|
||||
|
||||
|
@ -158,20 +159,24 @@ private:
|
|||
}
|
||||
|
||||
rstime_t last_contact ; // used to keep track of working connexion
|
||||
rstime_t last_keep_alive_sent ; // last time we sent a keep alive packet.
|
||||
rstime_t last_keep_alive_sent ; // last time we sent a keep alive packet.
|
||||
|
||||
unsigned char aes_key[GXS_TUNNEL_AES_KEY_SIZE] ;
|
||||
|
||||
uint32_t status ; // info: do we have a tunnel ?
|
||||
RsPeerId virtual_peer_id; // given by the turtle router. Identifies the tunnel.
|
||||
RsGxsId to_gxs_id; // gxs id we're talking to
|
||||
RsGxsId own_gxs_id ; // gxs id we're using to talk.
|
||||
RsTurtleGenericTunnelItem::Direction direction ; // specifiec wether we are client(managing the tunnel) or server.
|
||||
TurtleFileHash hash ; // hash that is last used. This is necessary for handling tunnel establishment
|
||||
std::set<uint32_t> client_services ;// services that used this tunnel
|
||||
std::map<uint64_t,rstime_t> received_data_prints ; // list of recently received messages, to avoid duplicates. Kept for 20 mins at most.
|
||||
uint32_t total_sent ;
|
||||
uint32_t total_received ;
|
||||
uint32_t status ; // info: do we have a tunnel ?
|
||||
RsPeerId virtual_peer_id; // given by the turtle router. Identifies the tunnel.
|
||||
RsGxsId to_gxs_id; // gxs id we're talking to
|
||||
RsGxsId own_gxs_id ; // gxs id we're using to talk.
|
||||
RsTurtleGenericTunnelItem::Direction direction ; // specifiec wether we are client(managing the tunnel) or server.
|
||||
TurtleFileHash hash ; // hash that is last used. This is necessary for handling tunnel establishment
|
||||
std::set<uint32_t> client_services ; // services that used this tunnel
|
||||
std::map<uint64_t,rstime_t> received_data_prints ; // list of recently received messages, to avoid duplicates. Kept for 20 mins at most.
|
||||
uint32_t total_sent ; // total data sent to this peer
|
||||
uint32_t total_received ; // total data received by this peer
|
||||
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_004
|
||||
bool accepts_fast_turtle_items; // does the tunnel accept RsTurtleGenericFastDataItem type?
|
||||
bool already_probed_for_fast_items; // has the tunnel been probed already? If not, a fast item will be sent
|
||||
#endif
|
||||
};
|
||||
|
||||
class GxsTunnelDHInfo
|
||||
|
@ -243,7 +248,11 @@ private:
|
|||
bool locked_sendEncryptedTunnelData(RsGxsTunnelItem *item) ;
|
||||
bool locked_sendClearTunnelData(RsGxsTunnelDHPublicKeyItem *item); // this limits the usage to DH items. Others should be encrypted!
|
||||
|
||||
bool handleEncryptedData(const uint8_t *data_bytes,uint32_t data_size,const TurtleFileHash& hash,const RsPeerId& virtual_peer_id) ;
|
||||
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_004
|
||||
bool handleEncryptedData(const uint8_t *data_bytes, uint32_t data_size, const TurtleFileHash& hash, const RsPeerId& virtual_peer_id, bool accepts_fast_items) ;
|
||||
#else
|
||||
bool handleEncryptedData(const uint8_t *data_bytes, uint32_t data_size, const TurtleFileHash& hash, const RsPeerId& virtual_peer_id) ;
|
||||
#endif
|
||||
|
||||
// local data
|
||||
|
||||
|
|
|
@ -185,9 +185,10 @@ class NetInterface;
|
|||
**/
|
||||
class PQInterface: public RateInterface
|
||||
{
|
||||
public:
|
||||
explicit PQInterface(const RsPeerId &id) :peerId(id) { return; }
|
||||
virtual ~PQInterface() { return; }
|
||||
public:
|
||||
explicit PQInterface(const RsPeerId &id) :
|
||||
traf_in(0), traf_out(0), peerId(id) {}
|
||||
virtual ~PQInterface() {}
|
||||
|
||||
/*!
|
||||
* allows user to send RsItems to a particular facility (file, network)
|
||||
|
@ -228,6 +229,22 @@ class PQInterface: public RateInterface
|
|||
const sockaddr_storage & /*remote_peer_address*/)
|
||||
{ return 0; }
|
||||
|
||||
virtual uint64_t getTraffic(bool in)
|
||||
{
|
||||
uint64_t ret = 0;
|
||||
if (in)
|
||||
{
|
||||
ret = traf_in;
|
||||
traf_in = 0;
|
||||
return ret;
|
||||
}
|
||||
ret = traf_out;
|
||||
traf_out = 0;
|
||||
return ret;
|
||||
}
|
||||
uint64_t traf_in;
|
||||
uint64_t traf_out;
|
||||
|
||||
private:
|
||||
|
||||
RsPeerId peerId;
|
||||
|
|
|
@ -83,6 +83,8 @@ pqihandler::pqihandler() : coreMtx("pqihandler")
|
|||
rateMax_in = 0.01;
|
||||
rateTotal_in = 0.0 ;
|
||||
rateTotal_out = 0.0 ;
|
||||
traffInSum = 0;
|
||||
traffOutSum = 0;
|
||||
last_m = time(NULL) ;
|
||||
nb_ticks = 0 ;
|
||||
mLastRateCapUpdate = 0 ;
|
||||
|
@ -371,6 +373,9 @@ int pqihandler::UpdateRates()
|
|||
{
|
||||
SearchModule *mod = (it -> second);
|
||||
float crate_in = mod -> pqi -> getRate(true);
|
||||
|
||||
traffInSum += mod -> pqi -> getTraffic(true);
|
||||
traffOutSum += mod -> pqi -> getTraffic(false);
|
||||
|
||||
#ifdef PQI_HDL_DEBUG_UR
|
||||
if(crate_in > 0.0)
|
||||
|
@ -540,4 +545,8 @@ void pqihandler::locked_StoreCurrentRates(float in, float out)
|
|||
rateTotal_out = out;
|
||||
}
|
||||
|
||||
|
||||
void pqihandler::GetTraffic(uint64_t &in, uint64_t &out)
|
||||
{
|
||||
in = traffInSum;
|
||||
out = traffOutSum;
|
||||
}
|
||||
|
|
|
@ -87,6 +87,10 @@ class pqihandler: public P3Interface, public pqiPublisher
|
|||
int ExtractRates(std::map<RsPeerId, RsBwRates> &ratemap, RsBwRates &totals);
|
||||
int ExtractTrafficInfo(std::list<RSTrafficClue> &out_lst, std::list<RSTrafficClue> &in_lst);
|
||||
|
||||
uint64_t traffInSum;
|
||||
uint64_t traffOutSum;
|
||||
void GetTraffic(uint64_t &in, uint64_t &out);
|
||||
|
||||
protected:
|
||||
/* check to be overloaded by those that can
|
||||
* generates warnings otherwise
|
||||
|
|
|
@ -637,6 +637,13 @@ float pqiperson::getRate(bool in)
|
|||
return activepqi -> getRate(in);
|
||||
}
|
||||
|
||||
uint64_t pqiperson::getTraffic(bool in)
|
||||
{
|
||||
if ((!active) || (activepqi == NULL))
|
||||
return 0;
|
||||
return activepqi -> getTraffic(in);
|
||||
}
|
||||
|
||||
void pqiperson::setMaxRate(bool in, float val)
|
||||
{
|
||||
RS_STACK_MUTEX(mPersonMtx);
|
||||
|
|
|
@ -143,6 +143,7 @@ public:
|
|||
virtual int getQueueSize(bool in);
|
||||
virtual void getRates(RsBwRates &rates);
|
||||
virtual float getRate(bool in);
|
||||
virtual uint64_t getTraffic(bool in);
|
||||
virtual void setMaxRate(bool in, float val);
|
||||
virtual void setRateCap(float val_in, float val_out);
|
||||
virtual int gatherStatistics(std::list<RSTrafficClue>& outqueue_lst,
|
||||
|
|
|
@ -216,6 +216,7 @@ float pqistreamer::getRate(bool b)
|
|||
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
|
||||
return RateInterface::getRate(b) ;
|
||||
}
|
||||
|
||||
void pqistreamer::setMaxRate(bool b,float f)
|
||||
{
|
||||
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
|
||||
|
@ -1226,7 +1227,7 @@ void pqistreamer::outSentBytes_locked(uint32_t outb)
|
|||
mTotalSent += outb;
|
||||
mCurrSent += outb;
|
||||
mAvgSentCount += outb;
|
||||
|
||||
PQInterface::traf_out += outb;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1243,7 +1244,7 @@ void pqistreamer::inReadBytes_locked(uint32_t inb)
|
|||
mTotalRead += inb;
|
||||
mCurrRead += inb;
|
||||
mAvgReadCount += inb;
|
||||
|
||||
PQInterface::traf_in += inb;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -409,6 +409,7 @@ public:
|
|||
* @return returns 1 on succes and 0 otherwise
|
||||
*/
|
||||
virtual int GetCurrentDataRates( float &inKb, float &outKb ) = 0;
|
||||
virtual int GetTrafficSum( uint64_t &inb, uint64_t &outb ) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* libretroshare: retroshare core library *
|
||||
* *
|
||||
* Copyright (C) 2012 Robert Fernie <retroshare@lunamutt.com> *
|
||||
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License as *
|
||||
|
@ -33,6 +33,8 @@
|
|||
#include "serialiser/rsserializable.h"
|
||||
#include "retroshare/rsturtle.h"
|
||||
#include "util/rsdeprecate.h"
|
||||
#include "retroshare/rsgxscircles.h"
|
||||
#include "util/rsmemory.h"
|
||||
|
||||
class RsGxsChannels;
|
||||
|
||||
|
@ -102,34 +104,114 @@ public:
|
|||
/**
|
||||
* @brief Create channel. Blocking API.
|
||||
* @jsonapi{development}
|
||||
* @param[inout] channel Channel data (name, description...)
|
||||
* @return false on error, true otherwise
|
||||
* @param[in] name Name of the channel
|
||||
* @param[in] description Description of the channel
|
||||
* @param[in] thumbnail Optional image to show as channel thumbnail.
|
||||
* @param[in] authorId Optional id of the author. Leave empty for an
|
||||
* anonymous channel.
|
||||
* @param[in] circleType Optional visibility rule, default public.
|
||||
* @param[in] circleId If the channel is not public specify the id of
|
||||
* the circle who can see the channel. Depending on
|
||||
* the value you pass for
|
||||
* circleType this should be be an external circle
|
||||
* if EXTERNAL is passed, a local friend group id
|
||||
* if NODES_GROUP is passed, empty otherwise.
|
||||
* @param[out] channelId Optional storage for the id of the created
|
||||
* channel, meaningful only if creations succeeds.
|
||||
* @param[out] errorMessage Optional storage for error messsage, meaningful
|
||||
* only if creation fail.
|
||||
* @return False on error, true otherwise.
|
||||
*/
|
||||
virtual bool createChannel(RsGxsChannelGroup& channel) = 0;
|
||||
virtual bool createChannelV2(
|
||||
const std::string& name,
|
||||
const std::string& description,
|
||||
const RsGxsImage& thumbnail = RsGxsImage(),
|
||||
const RsGxsId& authorId = RsGxsId(),
|
||||
RsGxsCircleType circleType = RsGxsCircleType::PUBLIC,
|
||||
const RsGxsCircleId& circleId = RsGxsCircleId(),
|
||||
RsGxsGroupId& channelId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId),
|
||||
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* @brief Add a comment on a post or on another comment
|
||||
* @brief Add a comment on a post or on another comment. Blocking API.
|
||||
* @jsonapi{development}
|
||||
* @param[inout] comment
|
||||
* @param[in] channelId Id of the channel in which the comment is to be
|
||||
* posted
|
||||
* @param[in] threadId Id of the post (that is a thread) in the channel
|
||||
* where the comment is placed
|
||||
* @param[in] parentId Id of the parent of the comment that is either a
|
||||
* channel post Id or the Id of another comment.
|
||||
* @param[in] authorId Id of the author of the comment
|
||||
* @param[in] comment UTF-8 string containing the comment itself
|
||||
* @param[out] commentMessageId Optional storage for the id of the comment
|
||||
* that was created, meaningful only on success.
|
||||
* @param[out] errorMessage Optional storage for error message, meaningful
|
||||
* only on failure.
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool createComment(RsGxsComment& comment) = 0;
|
||||
virtual bool createCommentV2(
|
||||
const RsGxsGroupId& channelId,
|
||||
const RsGxsMessageId& threadId,
|
||||
const RsGxsMessageId& parentId,
|
||||
const RsGxsId& authorId,
|
||||
const std::string& comment,
|
||||
RsGxsMessageId& commentMessageId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId),
|
||||
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* @brief Create channel post. Blocking API.
|
||||
* @jsonapi{development}
|
||||
* @param[inout] post
|
||||
* @param[in] channelId Id of the channel where to put the post. Beware
|
||||
* you need publish rights on that channel to post.
|
||||
* @param[in] title Title of the post
|
||||
* @param[in] mBody Text content of the post
|
||||
* @param[in] files Optional list of attached files. These are
|
||||
* supposed to be already shared,
|
||||
* @see ExtraFileHash() below otherwise.
|
||||
* @param[in] thumbnail Optional thumbnail image for the post.
|
||||
* @param[in] origPostId If this is supposed to replace an already
|
||||
* existent post, the id of the old post. If left
|
||||
* blank a new post will be created.
|
||||
* @param[out] postId Optional storage for the id of the created post,
|
||||
* meaningful only on success.
|
||||
* @param[out] errorMessage Optional storage for the error message,
|
||||
* meaningful only on failure.
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool createPost(RsGxsChannelPost& post) = 0;
|
||||
virtual bool createPostV2(
|
||||
const RsGxsGroupId& channelId, const std::string& title,
|
||||
const std::string& mBody,
|
||||
const std::list<RsGxsFile>& files = std::list<RsGxsFile>(),
|
||||
const RsGxsImage& thumbnail = RsGxsImage(),
|
||||
const RsGxsMessageId& origPostId = RsGxsMessageId(),
|
||||
RsGxsMessageId& postId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId),
|
||||
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0;
|
||||
|
||||
/**
|
||||
* @brief createVote
|
||||
* @brief Create a vote
|
||||
* @jsonapi{development}
|
||||
* @param[inout] vote
|
||||
* @param[in] channelId Id of the channel where to vote
|
||||
* @param[in] postId Id of the channel post of which a comment is
|
||||
* voted.
|
||||
* @param[in] commentId Id of the comment that is voted
|
||||
* @param[in] authorId Id of the author. Needs to be of an owned
|
||||
* identity.
|
||||
* @param[in] vote Vote value, either RsGxsVoteType::DOWN or
|
||||
* RsGxsVoteType::UP
|
||||
* @param[out] voteId Optional storage for the id of the created vote,
|
||||
* meaningful only on success.
|
||||
* @param[out] errorMessage Optional storage for error message, meaningful
|
||||
* only on failure.
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
virtual bool createVote(RsGxsVote& vote) = 0;
|
||||
virtual bool createVoteV2(
|
||||
const RsGxsGroupId& channelId, const RsGxsMessageId& postId,
|
||||
const RsGxsMessageId& commentId, const RsGxsId& authorId,
|
||||
RsGxsVoteType vote,
|
||||
RsGxsMessageId& voteId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId),
|
||||
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Edit channel details.
|
||||
|
@ -315,6 +397,16 @@ public:
|
|||
/* Following functions are deprecated as they expose internal functioning
|
||||
* semantic, instead of a safe to use API */
|
||||
|
||||
/**
|
||||
* @brief Create channel. Blocking API.
|
||||
* @jsonapi{development}
|
||||
* @deprecated { substituted by createChannelV2 }
|
||||
* @param[inout] channel Channel data (name, description...)
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
RS_DEPRECATED_FOR(createChannelV2)
|
||||
virtual bool createChannel(RsGxsChannelGroup& channel) = 0;
|
||||
|
||||
RS_DEPRECATED_FOR(getChannelsInfo)
|
||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsChannelGroup> &groups) = 0;
|
||||
|
||||
|
@ -372,9 +464,29 @@ public:
|
|||
* @param[in] group Channel data (name, description...)
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
RS_DEPRECATED_FOR(createChannel)
|
||||
RS_DEPRECATED_FOR(createChannelV2)
|
||||
virtual bool createGroup(uint32_t& token, RsGxsChannelGroup& group) = 0;
|
||||
|
||||
/**
|
||||
* @brief Add a comment on a post or on another comment
|
||||
* @jsonapi{development}
|
||||
* @deprecated
|
||||
* @param[inout] comment
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
RS_DEPRECATED_FOR(createCommentV2)
|
||||
virtual bool createComment(RsGxsComment& comment) = 0;
|
||||
|
||||
/**
|
||||
* @brief Create channel post. Blocking API.
|
||||
* @jsonapi{development}
|
||||
* @deprecated
|
||||
* @param[inout] post
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
RS_DEPRECATED_FOR(createPostV2)
|
||||
virtual bool createPost(RsGxsChannelPost& post) = 0;
|
||||
|
||||
/**
|
||||
* @brief Request post creation.
|
||||
* The action is performed asyncronously, so it could fail in a subsequent
|
||||
|
@ -385,9 +497,19 @@ public:
|
|||
* @param[in] post
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
RS_DEPRECATED
|
||||
RS_DEPRECATED_FOR(createPostV2)
|
||||
virtual bool createPost(uint32_t& token, RsGxsChannelPost& post) = 0;
|
||||
|
||||
/**
|
||||
* @brief createVote
|
||||
* @jsonapi{development}
|
||||
* @deprecated
|
||||
* @param[inout] vote
|
||||
* @return false on error, true otherwise
|
||||
*/
|
||||
RS_DEPRECATED_FOR(createVoteV2)
|
||||
virtual bool createVote(RsGxsVote& vote) = 0;
|
||||
|
||||
/**
|
||||
* @brief Request channel change.
|
||||
* The action is performed asyncronously, so it could fail in a subsequent
|
||||
|
|
|
@ -42,24 +42,35 @@ class RsGxsCircles;
|
|||
*/
|
||||
extern RsGxsCircles* rsGxsCircles;
|
||||
|
||||
enum class RsGxsCircleType : uint32_t // 32 bit overkill, just for retrocompat
|
||||
{
|
||||
UNKNOWN = 0, /// Used to detect uninizialized values.
|
||||
PUBLIC = 1, /// Public distribution
|
||||
EXTERNAL = 2, /// Restricted to an external circle
|
||||
|
||||
// TODO: convert to enum
|
||||
/// The meaning of the different circle types is:
|
||||
static const uint32_t GXS_CIRCLE_TYPE_UNKNOWN = 0x0000 ; /// Used to detect uninizialized values.
|
||||
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.
|
||||
/** Restricted to a group of friend nodes, the administrator of the circle
|
||||
* behave as a hub for them */
|
||||
NODES_GROUP = 3,
|
||||
|
||||
LOCAL = 4, /// not distributed at all
|
||||
|
||||
/** Self-restricted. Used only at creation time of self-restricted circles
|
||||
* when the circle id isn't known yet. Once the circle id is known the type
|
||||
* is set to EXTERNAL, and the external circle id is set to the id of the
|
||||
* circle itself.
|
||||
*/
|
||||
EXT_SELF = 5,
|
||||
|
||||
/// distributed to nodes signed by your own PGP key only.
|
||||
YOUR_EYES_ONLY = 6
|
||||
};
|
||||
|
||||
// TODO: convert to enum class
|
||||
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.
|
||||
|
||||
static const uint32_t GXS_CIRCLE_FLAGS_IS_EXTERNAL = 0x0008 ;// user is allowed
|
||||
|
||||
|
||||
struct RsGxsCircleGroup : RsSerializable
|
||||
{
|
||||
|
@ -110,8 +121,9 @@ struct RsGxsCircleMsg : RsSerializable
|
|||
struct RsGxsCircleDetails : RsSerializable
|
||||
{
|
||||
RsGxsCircleDetails() :
|
||||
mCircleType(GXS_CIRCLE_TYPE_EXTERNAL), mAmIAllowed(false) {}
|
||||
~RsGxsCircleDetails() {}
|
||||
mCircleType(static_cast<uint32_t>(RsGxsCircleType::EXTERNAL)),
|
||||
mAmIAllowed(false) {}
|
||||
~RsGxsCircleDetails() override {}
|
||||
|
||||
RsGxsCircleId mCircleId;
|
||||
std::string mCircleName;
|
||||
|
@ -264,3 +276,34 @@ public:
|
|||
RS_DEPRECATED_FOR("editCircle, inviteIdsToCircle")
|
||||
virtual void updateGroup(uint32_t &token, RsGxsCircleGroup &group) = 0;
|
||||
};
|
||||
|
||||
|
||||
/// @deprecated Used to detect uninizialized values.
|
||||
RS_DEPRECATED_FOR("RsGxsCircleType::UNKNOWN")
|
||||
static const uint32_t GXS_CIRCLE_TYPE_UNKNOWN = 0x0000;
|
||||
|
||||
/// @deprecated not restricted to a circle
|
||||
RS_DEPRECATED_FOR("RsGxsCircleType::PUBLIC")
|
||||
static const uint32_t GXS_CIRCLE_TYPE_PUBLIC = 0x0001;
|
||||
|
||||
/// @deprecated restricted to an external circle, made of RsGxsId
|
||||
RS_DEPRECATED_FOR("RsGxsCircleType::EXTERNAL")
|
||||
static const uint32_t GXS_CIRCLE_TYPE_EXTERNAL = 0x0002;
|
||||
|
||||
/// @deprecated restricted to a subset of friend nodes of a given RS node given
|
||||
/// by a RsPgpId list
|
||||
RS_DEPRECATED_FOR("RsGxsCircleType::NODES_GROUP")
|
||||
static const uint32_t GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY = 0x0003;
|
||||
|
||||
/// @deprecated not distributed at all
|
||||
RS_DEPRECATED_FOR("RsGxsCircleType::LOCAL")
|
||||
static const uint32_t GXS_CIRCLE_TYPE_LOCAL = 0x0004;
|
||||
|
||||
/// @deprecated self-restricted. Not used, except at creation time when the
|
||||
/// circle ID isn't known yet. Set to EXTERNAL afterwards.
|
||||
RS_DEPRECATED_FOR("RsGxsCircleType::EXT_SELF")
|
||||
static const uint32_t GXS_CIRCLE_TYPE_EXT_SELF = 0x0005;
|
||||
|
||||
/// @deprecated distributed to nodes signed by your own PGP key only.
|
||||
RS_DEPRECATED_FOR("RsGxsCircleType::YOUR_EYES_ONLY")
|
||||
static const uint32_t GXS_CIRCLE_TYPE_YOUR_EYES_ONLY = 0x0006;
|
||||
|
|
|
@ -19,11 +19,9 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#ifndef RETROSHARE_GXS_COMMON_OBJS_INTERFACE_H
|
||||
#define RETROSHARE_GXS_COMMON_OBJS_INTERFACE_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
|
@ -79,10 +77,12 @@ struct RsGxsImage : RsSerializable
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
#define GXS_VOTE_NONE 0x0000
|
||||
#define GXS_VOTE_DOWN 0x0001
|
||||
#define GXS_VOTE_UP 0x0002
|
||||
enum class RsGxsVoteType : uint32_t
|
||||
{
|
||||
NONE = 0, /// Used to detect unset vote?
|
||||
DOWN = 1, /// Negative vote
|
||||
UP = 2 /// Positive vote
|
||||
};
|
||||
|
||||
|
||||
// Status Flags to indicate Voting....
|
||||
|
@ -181,7 +181,11 @@ struct RsGxsCommentService
|
|||
std::pair<RsGxsGroupId, RsGxsMessageId>& msgId ) = 0;
|
||||
};
|
||||
|
||||
/// @deprecated use RsGxsVoteType::NONE instead @see RsGxsVoteType
|
||||
#define GXS_VOTE_NONE 0x0000
|
||||
|
||||
/// @deprecated use RsGxsVoteType::DOWN instead @see RsGxsVoteType
|
||||
#define GXS_VOTE_DOWN 0x0001
|
||||
|
||||
#endif
|
||||
|
||||
/// @deprecated use RsGxsVoteType::UP instead @see RsGxsVoteType
|
||||
#define GXS_VOTE_UP 0x0002
|
||||
|
|
|
@ -52,14 +52,15 @@ namespace GXS_SERV {
|
|||
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_MASK = 0x0000ff00;
|
||||
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_NONE = 0x00000000;
|
||||
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_GPG = 0x00000100; // Anti-spam feature. Allows to ask higher reputation to anonymous IDs
|
||||
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_REQUIRED = 0x00000200;
|
||||
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN = 0x00000400;
|
||||
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_REQUIRED = 0x00000200; // unused
|
||||
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN = 0x00000400; // ???
|
||||
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES = 0x00000800; // not used anymore
|
||||
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN = 0x00001000; // Anti-spam feature. Allows to ask higher reputation to unknown IDs and anonymous IDs
|
||||
|
||||
// These are *not used*
|
||||
static const uint32_t FLAG_GROUP_SIGN_PUBLISH_MASK = 0x000000ff;
|
||||
static const uint32_t FLAG_GROUP_SIGN_PUBLISH_ENCRYPTED = 0x00000001;
|
||||
static const uint32_t FLAG_GROUP_SIGN_PUBLISH_ALLSIGNED = 0x00000002;
|
||||
static const uint32_t FLAG_GROUP_SIGN_PUBLISH_ALLSIGNED = 0x00000002; // unused
|
||||
static const uint32_t FLAG_GROUP_SIGN_PUBLISH_THREADHEAD = 0x00000004;
|
||||
static const uint32_t FLAG_GROUP_SIGN_PUBLISH_NONEREQ = 0x00000008;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* libretroshare: retroshare core library *
|
||||
* *
|
||||
* Copyright 2011 by Christopher Evi-Parker *
|
||||
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License as *
|
||||
|
@ -20,9 +20,7 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef RSGXSIFACEIMPL_H
|
||||
#define RSGXSIFACEIMPL_H
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
@ -292,19 +290,51 @@ protected:
|
|||
* Useful for blocking API implementation.
|
||||
* @param[in] token token associated to the request caller is waiting for
|
||||
* @param[in] maxWait maximum waiting time in milliseconds
|
||||
* @param[in] checkEvery time in millisecond between status checks
|
||||
*/
|
||||
RsTokenService::GxsRequestStatus waitToken(
|
||||
uint32_t token,
|
||||
std::chrono::milliseconds maxWait = std::chrono::milliseconds(500) )
|
||||
std::chrono::milliseconds maxWait = std::chrono::milliseconds(500),
|
||||
std::chrono::milliseconds checkEvery = std::chrono::milliseconds(2))
|
||||
{
|
||||
#if defined(__ANDROID__) && (__ANDROID_API__ < 24)
|
||||
auto wkStartime = std::chrono::steady_clock::now();
|
||||
int maxWorkAroundCnt = 10;
|
||||
LLwaitTokenBeginLabel:
|
||||
#endif
|
||||
auto timeout = std::chrono::steady_clock::now() + maxWait;
|
||||
auto st = requestStatus(token);
|
||||
while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE)
|
||||
&& std::chrono::steady_clock::now() < timeout )
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
||||
std::this_thread::sleep_for(checkEvery);
|
||||
st = requestStatus(token);
|
||||
}
|
||||
|
||||
#if defined(__ANDROID__) && (__ANDROID_API__ < 24)
|
||||
/* Work around for very slow/old android devices, we don't expect this
|
||||
* to be necessary on newer devices. If it take unreasonably long
|
||||
* something worser is already happening elsewere and we return anyway.
|
||||
*/
|
||||
if( st > RsTokenService::FAILED && st < RsTokenService::COMPLETE
|
||||
&& maxWorkAroundCnt-- > 0 )
|
||||
{
|
||||
maxWait *= 10;
|
||||
checkEvery *= 3;
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Slow Android device "
|
||||
<< " workaround st: " << st
|
||||
<< " maxWorkAroundCnt: " << maxWorkAroundCnt
|
||||
<< " maxWait: " << maxWait.count()
|
||||
<< " checkEvery: " << checkEvery.count() << std::endl;
|
||||
goto LLwaitTokenBeginLabel;
|
||||
}
|
||||
std::cerr << __PRETTY_FUNCTION__ << " lasted: "
|
||||
<< std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::steady_clock::now() - wkStartime ).count()
|
||||
<< "ms" << std::endl;
|
||||
|
||||
#endif
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
|
@ -312,5 +342,3 @@ private:
|
|||
RsGxsIface& mGxs;
|
||||
RsTokenService& mTokenService;
|
||||
};
|
||||
|
||||
#endif // RSGXSIFACEIMPL_H
|
||||
|
|
|
@ -563,8 +563,8 @@ public:
|
|||
/**
|
||||
* @brief MessageToTrash
|
||||
* @jsonapi{development}
|
||||
* @param[in] msgId
|
||||
* @param[in] bTrash
|
||||
* @param[in] msgId Id of the message to mode to trash box
|
||||
* @param[in] bTrash Move to trash if true, otherwise remove from trash
|
||||
* @return true on success
|
||||
*/
|
||||
virtual bool MessageToTrash(const std::string &msgId, bool bTrash) = 0;
|
||||
|
|
|
@ -44,6 +44,7 @@ class RsPostedGroup
|
|||
|
||||
RsGroupMetaData mMeta;
|
||||
std::string mDescription;
|
||||
RsGxsImage mGroupImage;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -121,15 +121,14 @@ public:
|
|||
|
||||
enum GxsRequestStatus : uint8_t
|
||||
{
|
||||
FAILED,
|
||||
PENDING,
|
||||
PARTIAL,
|
||||
COMPLETE,
|
||||
DONE, /// Once all data has been retrived
|
||||
CANCELLED
|
||||
FAILED = 0,
|
||||
PENDING = 1,
|
||||
PARTIAL = 2,
|
||||
COMPLETE = 3,
|
||||
DONE = 4, /// Once all data has been retrived
|
||||
CANCELLED = 5
|
||||
};
|
||||
|
||||
|
||||
RsTokenService() {}
|
||||
virtual ~RsTokenService() {}
|
||||
|
||||
|
|
|
@ -31,21 +31,22 @@ const uint8_t QOS_PRIORITY_TOP = 9 ;
|
|||
|
||||
// Turtle traffic
|
||||
//
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_OPEN_TUNNEL = 6 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_TUNNEL_OK = 6 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_OPEN_TUNNEL = 6 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_TUNNEL_OK = 6 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_SEARCH_REQUEST = 6 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_REQUEST = 5 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_CRC_REQUEST = 5 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_CHUNK_CRC_REQUEST= 5 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_REQUEST = 5 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_CRC_REQUEST = 5 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_CHUNK_CRC_REQUEST= 5 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_MAP_REQUEST = 5 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_SEARCH_RESULT = 3 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_DATA = 3 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_SEARCH_RESULT = 3 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_DATA = 3 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_CRC = 3 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_CHUNK_CRC = 5 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_MAP = 3 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_GENERIC_ITEM = 3 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_FORWARD_FILE_DATA= 3 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_GENERIC_DATA = 5 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_GENERIC_FAST_DATA= 7 ;
|
||||
|
||||
// File transfer
|
||||
//
|
||||
|
|
|
@ -44,7 +44,15 @@ void RsGxsPostedPostItem::serial_process(RsGenericSerializer::SerializeJob j,RsG
|
|||
|
||||
void RsGxsPostedGroupItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
||||
{
|
||||
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR ,mGroup.mDescription,"mGroup.mDescription") ;
|
||||
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR ,mDescription,"mDescription") ;
|
||||
|
||||
if(j == RsGenericSerializer::DESERIALIZE && ctx.mOffset == ctx.mSize)
|
||||
return ;
|
||||
|
||||
if((j == RsGenericSerializer::SIZE_ESTIMATE || j == RsGenericSerializer::SERIALIZE) && mGroupImage.empty())
|
||||
return ;
|
||||
|
||||
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,mGroupImage,"mGroupImage") ;
|
||||
}
|
||||
|
||||
RsItem *RsGxsPostedSerialiser::create_item(uint16_t service_id,uint8_t item_subtype) const
|
||||
|
@ -109,6 +117,42 @@ void RsGxsPostedPostItem::clear()
|
|||
}
|
||||
void RsGxsPostedGroupItem::clear()
|
||||
{
|
||||
mGroup.mDescription.clear();
|
||||
mDescription.clear();
|
||||
mGroupImage.TlvClear();
|
||||
}
|
||||
|
||||
bool RsGxsPostedGroupItem::fromPostedGroup(RsPostedGroup &group, bool moveImage)
|
||||
{
|
||||
clear();
|
||||
meta = group.mMeta;
|
||||
mDescription = group.mDescription;
|
||||
|
||||
if (moveImage)
|
||||
{
|
||||
mGroupImage.binData.bin_data = group.mGroupImage.mData;
|
||||
mGroupImage.binData.bin_len = group.mGroupImage.mSize;
|
||||
group.mGroupImage.shallowClear();
|
||||
}
|
||||
else
|
||||
{
|
||||
mGroupImage.binData.setBinData(group.mGroupImage.mData, group.mGroupImage.mSize);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RsGxsPostedGroupItem::toPostedGroup(RsPostedGroup &group, bool moveImage)
|
||||
{
|
||||
group.mMeta = meta;
|
||||
group.mDescription = mDescription;
|
||||
if (moveImage)
|
||||
{
|
||||
group.mGroupImage.take((uint8_t *) mGroupImage.binData.bin_data, mGroupImage.binData.bin_len);
|
||||
// mGroupImage doesn't have a ShallowClear at the moment!
|
||||
mGroupImage.binData.TlvShallowClear();
|
||||
}
|
||||
else
|
||||
{
|
||||
group.mGroupImage.copy((uint8_t *) mGroupImage.binData.bin_data, mGroupImage.binData.bin_len);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -42,8 +42,12 @@ public:
|
|||
|
||||
virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
||||
|
||||
RsPostedGroup mGroup;
|
||||
// use conversion functions to transform:
|
||||
bool fromPostedGroup(RsPostedGroup &group, bool moveImage);
|
||||
bool toPostedGroup(RsPostedGroup &group, bool moveImage);
|
||||
|
||||
std::string mDescription;
|
||||
RsTlvImage mGroupImage;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -560,4 +560,8 @@ int p3ServerConfig::GetCurrentDataRates( float &inKb, float &outKb )
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int p3ServerConfig::GetTrafficSum(uint64_t &inb, uint64_t &outb )
|
||||
{
|
||||
mPqiHandler->GetTraffic(inb, outb);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -91,6 +91,7 @@ virtual bool setOperatingMode(const std::string &opModeStr);
|
|||
virtual int SetMaxDataRates( int downKb, int upKb );
|
||||
virtual int GetMaxDataRates( int &downKb, int &upKb );
|
||||
virtual int GetCurrentDataRates( float &inKb, float &outKb );
|
||||
virtual int GetTrafficSum( uint64_t &inb, uint64_t &outb );
|
||||
|
||||
/********************* ABOVE is RsConfig Interface *******/
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* libretroshare: retroshare core library *
|
||||
* *
|
||||
* Copyright (C) 2012 Robert Fernie <retroshare@lunamutt.com> *
|
||||
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License as *
|
||||
|
@ -31,12 +31,14 @@
|
|||
|
||||
#include "retroshare/rsgxsflags.h"
|
||||
#include "retroshare/rsfiles.h"
|
||||
#include "retroshare/rspeers.h"
|
||||
|
||||
#include "rsserver/p3face.h"
|
||||
#include "retroshare/rsnotify.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
||||
// For Dummy Msgs.
|
||||
#include "util/rsrandom.h"
|
||||
|
@ -1055,26 +1057,145 @@ bool p3GxsChannels::getChannelContent( const RsGxsGroupId& channelId,
|
|||
return getPostData(token, posts, comments);
|
||||
}
|
||||
|
||||
bool p3GxsChannels::createChannel(RsGxsChannelGroup& channel)
|
||||
bool p3GxsChannels::createChannelV2(
|
||||
const std::string& name, const std::string& description,
|
||||
const RsGxsImage& thumbnail, const RsGxsId& authorId,
|
||||
RsGxsCircleType circleType, const RsGxsCircleId& circleId,
|
||||
RsGxsGroupId& channelId, std::string& errorMessage )
|
||||
{
|
||||
// do some checks
|
||||
|
||||
if( circleType != RsGxsCircleType::PUBLIC
|
||||
&& circleType != RsGxsCircleType::EXTERNAL
|
||||
&& circleType != RsGxsCircleType::NODES_GROUP
|
||||
&& circleType != RsGxsCircleType::LOCAL
|
||||
&& circleType != RsGxsCircleType::YOUR_EYES_ONLY)
|
||||
{
|
||||
errorMessage = "circleType has invalid value";
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(circleType)
|
||||
{
|
||||
case RsGxsCircleType::EXTERNAL:
|
||||
if(circleId.isNull())
|
||||
{
|
||||
errorMessage = "circleType is EXTERNAL but circleId is null";
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case RsGxsCircleType::NODES_GROUP:
|
||||
{
|
||||
RsGroupInfo ginfo;
|
||||
|
||||
if(!rsPeers->getGroupInfo(RsNodeGroupId(circleId), ginfo))
|
||||
{
|
||||
errorMessage = "circleType is NODES_GROUP but circleId does not "
|
||||
"correspond to an actual group of friends";
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if(!circleId.isNull())
|
||||
{
|
||||
errorMessage = "circleType requires a null circleId, but a non "
|
||||
"null circleId (";
|
||||
errorMessage += circleId.toStdString();
|
||||
errorMessage += ") was supplied";
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Create a consistent channel group meta from the information supplied
|
||||
RsGxsChannelGroup channel;
|
||||
|
||||
channel.mMeta.mGroupName = name;
|
||||
channel.mMeta.mAuthorId = authorId;
|
||||
channel.mMeta.mCircleType = static_cast<uint32_t>(circleType);
|
||||
|
||||
channel.mMeta.mSignFlags = GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_NONEREQ
|
||||
| GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_REQUIRED;
|
||||
|
||||
channel.mMeta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_PUBLIC;
|
||||
|
||||
channel.mMeta.mCircleId.clear();
|
||||
channel.mMeta.mInternalCircle.clear();
|
||||
|
||||
switch(circleType)
|
||||
{
|
||||
case RsGxsCircleType::NODES_GROUP:
|
||||
channel.mMeta.mInternalCircle = circleId; break;
|
||||
case RsGxsCircleType::EXTERNAL:
|
||||
channel.mMeta.mCircleId = circleId; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Create the channel
|
||||
channel.mDescription = description;
|
||||
channel.mImage = thumbnail;
|
||||
|
||||
uint32_t token;
|
||||
if(!createGroup(token, channel))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Error! Failed creating group."
|
||||
errorMessage = "Failed creating GXS group.";
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error! " << errorMessage
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(waitToken(token) != RsTokenService::COMPLETE)
|
||||
// wait for the group creation to complete.
|
||||
RsTokenService::GxsRequestStatus wSt =
|
||||
waitToken( token, std::chrono::milliseconds(5000),
|
||||
std::chrono::milliseconds(20) );
|
||||
if(wSt != RsTokenService::COMPLETE)
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed."
|
||||
errorMessage = "GXS operation waitToken failed with: "
|
||||
+ std::to_string(wSt);
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error! " << errorMessage
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!RsGenExchange::getPublishedGroupMeta(token, channel.mMeta))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting updated "
|
||||
errorMessage = "Failure getting updated group data.";
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error! " << errorMessage
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
channelId = channel.mMeta.mGroupId;
|
||||
|
||||
#ifdef RS_DEEP_SEARCH
|
||||
DeepSearch::indexChannelGroup(channel);
|
||||
#endif // RS_DEEP_SEARCH
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsChannels::createChannel(RsGxsChannelGroup& channel)
|
||||
{
|
||||
uint32_t token;
|
||||
if(!createGroup(token, channel))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error! Failed creating group."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(waitToken(token) != RsTokenService::COMPLETE)
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error! GXS operation failed."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!RsGenExchange::getPublishedGroupMeta(token, channel.mMeta))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error! Failure getting updated "
|
||||
<< " group data." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
@ -1086,53 +1207,121 @@ bool p3GxsChannels::createChannel(RsGxsChannelGroup& channel)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsChannels::createComment(RsGxsComment& comment)
|
||||
bool p3GxsChannels::createVoteV2(
|
||||
const RsGxsGroupId& channelId, const RsGxsMessageId& postId,
|
||||
const RsGxsMessageId& commentId, const RsGxsId& authorId,
|
||||
RsGxsVoteType tVote, RsGxsMessageId& voteId, std::string& errorMessage )
|
||||
{
|
||||
uint32_t token;
|
||||
if(!createNewComment(token, comment))
|
||||
std::vector<RsGxsChannelGroup> channelsInfo;
|
||||
if(!getChannelsInfo(std::list<RsGxsGroupId>({channelId}),channelsInfo))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Error! Failed creating comment."
|
||||
<< std::endl;
|
||||
errorMessage = "Channel with Id " + channelId.toStdString()
|
||||
+ " does not exist.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(commentId.isNull())
|
||||
{
|
||||
errorMessage = "You cannot vote on null comment "
|
||||
+ commentId.toStdString();
|
||||
return false;
|
||||
}
|
||||
|
||||
std::set<RsGxsMessageId> s({commentId});
|
||||
std::vector<RsGxsChannelPost> posts;
|
||||
std::vector<RsGxsComment> comments;
|
||||
|
||||
if(!getChannelContent(channelId, s, posts, comments))
|
||||
{
|
||||
errorMessage = "You cannot vote on comment "
|
||||
+ commentId.toStdString() + " of channel with Id "
|
||||
+ channelId.toStdString()
|
||||
+ ": this comment does not exists locally!";
|
||||
return false;
|
||||
}
|
||||
|
||||
// is the ID a comment ID or a post ID?
|
||||
// It should be comment => should have a parent ID
|
||||
if(posts.front().mMeta.mParentId.isNull())
|
||||
{
|
||||
errorMessage = "You cannot vote on channel message "
|
||||
+ commentId.toStdString() + " of channel with Id "
|
||||
+ channelId.toStdString()
|
||||
+ ": given id refers to a post, not a comment!";
|
||||
return false;
|
||||
}
|
||||
|
||||
if( tVote != RsGxsVoteType::NONE
|
||||
&& tVote != RsGxsVoteType::UP
|
||||
&& tVote != RsGxsVoteType::DOWN )
|
||||
{
|
||||
errorMessage = "Your vote to channel with Id "
|
||||
+ channelId.toStdString() + " has wrong vote type. "
|
||||
+ " Only RsGxsVoteType::NONE, RsGxsVoteType::UP, "
|
||||
+ "RsGxsVoteType::DOWN are accepted.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!rsIdentity->isOwnId(authorId))
|
||||
{
|
||||
errorMessage = "You cannot vote to channel with Id "
|
||||
+ channelId.toStdString() + " with identity "
|
||||
+ authorId.toStdString() + " because it is not yours.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the vote
|
||||
RsGxsVote vote;
|
||||
vote.mMeta.mGroupId = channelId;
|
||||
vote.mMeta.mThreadId = postId;
|
||||
vote.mMeta.mParentId = commentId;
|
||||
vote.mMeta.mAuthorId = authorId;
|
||||
vote.mVoteType = static_cast<uint32_t>(tVote);
|
||||
|
||||
uint32_t token;
|
||||
if(!createNewVote(token, vote))
|
||||
{
|
||||
errorMessage = "Error! Failed creating vote.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(waitToken(token) != RsTokenService::COMPLETE)
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed."
|
||||
<< std::endl;
|
||||
errorMessage = "GXS operation failed.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!RsGenExchange::getPublishedMsgMeta(token, comment.mMeta))
|
||||
if(!RsGenExchange::getPublishedMsgMeta(token, vote.mMeta))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting generated "
|
||||
<< " comment data." << std::endl;
|
||||
errorMessage = "Failure getting generated vote data.";
|
||||
return false;
|
||||
}
|
||||
|
||||
voteId = vote.mMeta.mMsgId;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @deprecated use createVoteV2 instead
|
||||
bool p3GxsChannels::createVote(RsGxsVote& vote)
|
||||
{
|
||||
uint32_t token;
|
||||
if(!createNewVote(token, vote))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Error! Failed creating vote."
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error! Failed creating vote."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(waitToken(token) != RsTokenService::COMPLETE)
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed."
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error! GXS operation failed."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!RsGenExchange::getPublishedMsgMeta(token, vote.mMeta))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting generated "
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error! Failure getting generated "
|
||||
<< " vote data." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
@ -1145,21 +1334,21 @@ bool p3GxsChannels::editChannel(RsGxsChannelGroup& channel)
|
|||
uint32_t token;
|
||||
if(!updateGroup(token, channel))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Error! Failed updating group."
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error! Failed updating group."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(waitToken(token) != RsTokenService::COMPLETE)
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed."
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error! GXS operation failed."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!RsGenExchange::getPublishedGroupMeta(token, channel.mMeta))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting updated "
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error! Failure getting updated "
|
||||
<< " group data." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
@ -1171,11 +1360,64 @@ bool p3GxsChannels::editChannel(RsGxsChannelGroup& channel)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsChannels::createPost(RsGxsChannelPost& post)
|
||||
bool p3GxsChannels::createPostV2(
|
||||
const RsGxsGroupId& channelId, const std::string& title,
|
||||
const std::string& body, const std::list<RsGxsFile>& files,
|
||||
const RsGxsImage& thumbnail, const RsGxsMessageId& origPostId,
|
||||
RsGxsMessageId& postId, std::string& errorMessage )
|
||||
{
|
||||
// Do some checks
|
||||
|
||||
std::vector<RsGxsChannelGroup> channelsInfo;
|
||||
|
||||
if(!getChannelsInfo(std::list<RsGxsGroupId>({channelId}),channelsInfo))
|
||||
{
|
||||
errorMessage = "Channel with Id " + channelId.toStdString() +
|
||||
" does not exist.";
|
||||
return false;
|
||||
}
|
||||
|
||||
const RsGxsChannelGroup& cg(*channelsInfo.begin());
|
||||
|
||||
if(!(cg.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_PUBLISH))
|
||||
{
|
||||
errorMessage = "You cannot post to channel with Id " +
|
||||
channelId.toStdString() + ": missing publish rights!";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!origPostId.isNull())
|
||||
{
|
||||
std::set<RsGxsMessageId> s({origPostId});
|
||||
std::vector<RsGxsChannelPost> posts;
|
||||
std::vector<RsGxsComment> comments;
|
||||
|
||||
if(!getChannelContent(channelId,s,posts,comments))
|
||||
{
|
||||
errorMessage = "You cannot edit post " + origPostId.toStdString()
|
||||
+ " of channel with Id " + channelId.toStdString()
|
||||
+ ": this post does not exist locally!";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the post
|
||||
RsGxsChannelPost post;
|
||||
|
||||
post.mMeta.mGroupId = channelId;
|
||||
post.mMeta.mOrigMsgId = origPostId;
|
||||
post.mMeta.mMsgName = title;
|
||||
|
||||
post.mMsg = body;
|
||||
post.mFiles = files;
|
||||
post.mThumbnail = thumbnail;
|
||||
|
||||
uint32_t token;
|
||||
if( !createPost(token, post)
|
||||
|| waitToken(token) != RsTokenService::COMPLETE ) return false;
|
||||
if(!createPost(token, post) || waitToken(token) != RsTokenService::COMPLETE)
|
||||
{
|
||||
errorMessage = "GXS operation failed";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(RsGenExchange::getPublishedMsgMeta(token,post.mMeta))
|
||||
{
|
||||
|
@ -1183,12 +1425,150 @@ bool p3GxsChannels::createPost(RsGxsChannelPost& post)
|
|||
DeepSearch::indexChannelPost(post);
|
||||
#endif // RS_DEEP_SEARCH
|
||||
|
||||
postId = post.mMeta.mMsgId;
|
||||
return true;
|
||||
}
|
||||
|
||||
errorMessage = "Failed to retrive created post metadata";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool p3GxsChannels::createCommentV2(const RsGxsGroupId& channelId,
|
||||
const RsGxsMessageId& threadId,
|
||||
const RsGxsMessageId& parentId,
|
||||
const RsGxsId& authorId,
|
||||
const std::string& comment,
|
||||
RsGxsMessageId& commentMessageId,
|
||||
std::string& errorMessage)
|
||||
{
|
||||
std::vector<RsGxsChannelGroup> channelsInfo;
|
||||
if(!getChannelsInfo(std::list<RsGxsGroupId>({channelId}),channelsInfo))
|
||||
{
|
||||
errorMessage = "Channel with Id " + channelId.toStdString()
|
||||
+ " does not exist.";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<RsGxsChannelPost> posts;
|
||||
std::vector<RsGxsComment> comments;
|
||||
|
||||
if(!getChannelContent( // does the post thread exist?
|
||||
channelId,std::set<RsGxsMessageId>({threadId}), posts, comments ))
|
||||
{
|
||||
errorMessage = "You cannot comment post " + threadId.toStdString() +
|
||||
" of channel with Id " + channelId.toStdString() +
|
||||
": this post does not exists locally!";
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error: " << errorMessage
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// check that the post thread Id is actually that of a post thread
|
||||
if(posts.size() != 1 || !posts[0].mMeta.mParentId.isNull())
|
||||
{
|
||||
errorMessage = "You cannot comment post " + threadId.toStdString() +
|
||||
" of channel with Id " + channelId.toStdString() +
|
||||
": supplied threadId is not a thread, or parentMsgId is not a" +
|
||||
" comment!";
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error: " << errorMessage
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!parentId.isNull())
|
||||
if(!getChannelContent( // does the post thread exist?
|
||||
channelId,std::set<RsGxsMessageId>({parentId}),posts,comments ))
|
||||
{
|
||||
errorMessage = "You cannot comment post " + parentId.toStdString() +
|
||||
": supplied parent comment Id is not a comment!";
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error: " << errorMessage
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
else if(comments.size() != 1 || comments[0].mMeta.mParentId.isNull())
|
||||
{ // is the comment parent actually a comment?
|
||||
errorMessage = "You cannot comment post " + parentId.toStdString()
|
||||
+ " of channel with Id " + channelId.toStdString() +
|
||||
": supplied mParentMsgId is not a comment Id!";
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error: " << errorMessage
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!rsIdentity->isOwnId(authorId)) // is the voter ID actually ours?
|
||||
{
|
||||
errorMessage = "You cannot comment to channel with Id " +
|
||||
channelId.toStdString() + " with identity " +
|
||||
authorId.toStdString() + " because it is not yours.";
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error: " << errorMessage
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now create the comment
|
||||
RsGxsComment cmt;
|
||||
cmt.mMeta.mGroupId = channelId;
|
||||
cmt.mMeta.mThreadId = threadId;
|
||||
cmt.mMeta.mParentId = parentId;
|
||||
cmt.mMeta.mAuthorId = authorId;
|
||||
cmt.mComment = comment;
|
||||
|
||||
uint32_t token;
|
||||
if(!createNewComment(token, cmt))
|
||||
{
|
||||
errorMessage = "Failed creating comment.";
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error: " << errorMessage
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(waitToken(token) != RsTokenService::COMPLETE)
|
||||
{
|
||||
errorMessage = "GXS operation failed.";
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error: " << errorMessage
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!RsGenExchange::getPublishedMsgMeta(token, cmt.mMeta))
|
||||
{
|
||||
errorMessage = "Failure getting created comment data.";
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error: " << errorMessage
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
commentMessageId = cmt.mMeta.mMsgId;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsChannels::createComment(RsGxsComment& comment) // deprecated
|
||||
{
|
||||
uint32_t token;
|
||||
if(!createNewComment(token, comment))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error! Failed creating comment."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(waitToken(token) != RsTokenService::COMPLETE)
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error! GXS operation failed."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!RsGenExchange::getPublishedMsgMeta(token, comment.mMeta))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error! Failure getting generated "
|
||||
<< " comment data." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsChannels::subscribeToChannel(
|
||||
const RsGxsGroupId& groupId, bool subscribe )
|
||||
{
|
||||
|
@ -1428,13 +1808,31 @@ bool p3GxsChannels::updateGroup(uint32_t &token, RsGxsChannelGroup &group)
|
|||
return true;
|
||||
}
|
||||
|
||||
/// @deprecated use createPostV2 instead
|
||||
bool p3GxsChannels::createPost(RsGxsChannelPost& post)
|
||||
{
|
||||
uint32_t token;
|
||||
if( !createPost(token, post)
|
||||
|| waitToken(token) != RsTokenService::COMPLETE ) return false;
|
||||
|
||||
if(RsGenExchange::getPublishedMsgMeta(token,post.mMeta))
|
||||
{
|
||||
#ifdef RS_DEEP_SEARCH
|
||||
DeepSearch::indexChannelPost(post);
|
||||
#endif // RS_DEEP_SEARCH
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool p3GxsChannels::createPost(uint32_t &token, RsGxsChannelPost &msg)
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::createChannelPost() GroupId: " << msg.mMeta.mGroupId;
|
||||
std::cerr << std::endl;
|
||||
std::cerr << __PRETTY_FUNCTION__ << " GroupId: " << msg.mMeta.mGroupId
|
||||
<< std::endl;
|
||||
#endif
|
||||
|
||||
RsGxsChannelPostItem* msgItem = new RsGxsChannelPostItem();
|
||||
|
@ -1976,7 +2374,7 @@ bool p3GxsChannels::turtleChannelRequest(
|
|||
{
|
||||
if(channelId.isNull())
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << "Error! channelId can't be null!"
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error! channelId can't be null!"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* libretroshare: retroshare core library *
|
||||
* *
|
||||
* Copyright (C) 2012 Robert Fernie <retroshare@lunamutt.com> *
|
||||
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License as *
|
||||
|
@ -20,14 +20,14 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
#ifndef P3_GXSCHANNELS_SERVICE_HEADER
|
||||
#define P3_GXSCHANNELS_SERVICE_HEADER
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "retroshare/rsgxschannels.h"
|
||||
#include "services/p3gxscommon.h"
|
||||
#include "gxs/rsgenexchange.h"
|
||||
#include "gxs/gxstokenqueue.h"
|
||||
#include "util/rsmemory.h"
|
||||
|
||||
#include "util/rstickevent.h"
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
|||
#include <string>
|
||||
|
||||
|
||||
|
||||
class SSGxsChannelGroup
|
||||
{
|
||||
public:
|
||||
|
@ -191,23 +192,64 @@ virtual bool ExtraFileRemove(const RsFileHash &hash);
|
|||
std::vector<RsGxsComment>& comments );
|
||||
|
||||
/// Implementation of @see RsGxsChannels::getContentSummaries
|
||||
virtual bool getContentSummaries( const RsGxsGroupId& channelId,
|
||||
std::vector<RsMsgMetaData>& summaries );
|
||||
virtual bool getContentSummaries(
|
||||
const RsGxsGroupId& channelId,
|
||||
std::vector<RsMsgMetaData>& summaries ) override;
|
||||
|
||||
/// Implementation of @see RsGxsChannels::createChannel
|
||||
virtual bool createChannel(RsGxsChannelGroup& channel);
|
||||
/// Implementation of @see RsGxsChannels::createChannelV2
|
||||
virtual bool createChannelV2(
|
||||
const std::string& name, const std::string& description,
|
||||
const RsGxsImage& thumbnail = RsGxsImage(),
|
||||
const RsGxsId& authorId = RsGxsId(),
|
||||
RsGxsCircleType circleType = RsGxsCircleType::PUBLIC,
|
||||
const RsGxsCircleId& circleId = RsGxsCircleId(),
|
||||
RsGxsGroupId& channelId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId),
|
||||
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
|
||||
) override;
|
||||
|
||||
/// @deprecated Implementation of @see RsGxsChannels::createComment
|
||||
RS_DEPRECATED_FOR(createCommentV2)
|
||||
virtual bool createComment(RsGxsComment& comment) override;
|
||||
|
||||
/// Implementation of @see RsGxsChannels::createComment
|
||||
virtual bool createComment(RsGxsComment& comment);
|
||||
virtual bool createCommentV2(
|
||||
const RsGxsGroupId& channelId, const RsGxsMessageId& threadId,
|
||||
const RsGxsMessageId& parentId, const RsGxsId& authorId,
|
||||
const std::string& comment,
|
||||
RsGxsMessageId& commentMessageId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId),
|
||||
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
|
||||
) override;
|
||||
|
||||
/// Implementation of @see RsGxsChannels::editChannel
|
||||
virtual bool editChannel(RsGxsChannelGroup& channel);
|
||||
virtual bool editChannel(RsGxsChannelGroup& channel) override;
|
||||
|
||||
/// Implementation of @see RsGxsChannels::createPost
|
||||
virtual bool createPost(RsGxsChannelPost& post);
|
||||
/// @deprecated Implementation of @see RsGxsChannels::createPost
|
||||
RS_DEPRECATED_FOR(createPostV2)
|
||||
virtual bool createPost(RsGxsChannelPost& post) override;
|
||||
|
||||
/// Implementation of @see RsGxsChannels::createVote
|
||||
virtual bool createVote(RsGxsVote& vote);
|
||||
/// Implementation of @see RsGxsChannels::createPostV2
|
||||
bool createPostV2(
|
||||
const RsGxsGroupId& channelId, const std::string& title,
|
||||
const std::string& body,
|
||||
const std::list<RsGxsFile>& files = std::list<RsGxsFile>(),
|
||||
const RsGxsImage& thumbnail = RsGxsImage(),
|
||||
const RsGxsMessageId& origPostId = RsGxsMessageId(),
|
||||
RsGxsMessageId& postId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId),
|
||||
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
|
||||
) override;
|
||||
|
||||
/// @deprecated Implementation of @see RsGxsChannels::createVote
|
||||
RS_DEPRECATED_FOR(createVoteV2)
|
||||
virtual bool createVote(RsGxsVote& vote) override;
|
||||
|
||||
/// Implementation of @see RsGxsChannels::createVoteV2
|
||||
virtual bool createVoteV2(
|
||||
const RsGxsGroupId& channelId, const RsGxsMessageId& postId,
|
||||
const RsGxsMessageId& commentId, const RsGxsId& authorId,
|
||||
RsGxsVoteType vote,
|
||||
RsGxsMessageId& voteId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId),
|
||||
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
|
||||
) override;
|
||||
|
||||
/// Implementation of @see RsGxsChannels::subscribeToChannel
|
||||
virtual bool subscribeToChannel( const RsGxsGroupId &groupId,
|
||||
|
@ -219,6 +261,10 @@ virtual bool ExtraFileRemove(const RsFileHash &hash);
|
|||
virtual bool shareChannelKeys(
|
||||
const RsGxsGroupId& channelId, const std::set<RsPeerId>& peers );
|
||||
|
||||
/// Implementation of @see RsGxsChannels::createChannel
|
||||
RS_DEPRECATED_FOR(createChannelV2)
|
||||
virtual bool createChannel(RsGxsChannelGroup& channel) override;
|
||||
|
||||
protected:
|
||||
// Overloaded from GxsTokenQueue for Request callbacks.
|
||||
virtual void handleResponse(uint32_t token, uint32_t req_type);
|
||||
|
@ -263,9 +309,11 @@ bool generateGroup(uint32_t &token, std::string groupName);
|
|||
class ChannelDummyRef
|
||||
{
|
||||
public:
|
||||
ChannelDummyRef() { return; }
|
||||
ChannelDummyRef(const RsGxsGroupId &grpId, const RsGxsMessageId &threadId, const RsGxsMessageId &msgId)
|
||||
:mGroupId(grpId), mThreadId(threadId), mMsgId(msgId) { return; }
|
||||
ChannelDummyRef() {}
|
||||
ChannelDummyRef(
|
||||
const RsGxsGroupId &grpId, const RsGxsMessageId &threadId,
|
||||
const RsGxsMessageId &msgId ) :
|
||||
mGroupId(grpId), mThreadId(threadId), mMsgId(msgId) {}
|
||||
|
||||
RsGxsGroupId mGroupId;
|
||||
RsGxsMessageId mThreadId;
|
||||
|
@ -309,5 +357,3 @@ bool generateGroup(uint32_t &token, std::string groupName);
|
|||
/// Cleanup mSearchCallbacksMap and mDistantChannelsCallbacksMap
|
||||
void cleanTimedOutCallbacks();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -79,9 +79,8 @@ bool p3Posted::getGroupData(const uint32_t &token, std::vector<RsPostedGroup> &g
|
|||
RsGxsPostedGroupItem* item = dynamic_cast<RsGxsPostedGroupItem*>(*vit);
|
||||
if (item)
|
||||
{
|
||||
RsPostedGroup grp = item->mGroup;
|
||||
item->mGroup.mMeta = item->meta;
|
||||
grp.mMeta = item->mGroup.mMeta;
|
||||
RsPostedGroup grp;
|
||||
item->toPostedGroup(grp, true);
|
||||
delete item;
|
||||
groups.push_back(grp);
|
||||
}
|
||||
|
@ -265,8 +264,8 @@ bool p3Posted::createGroup(uint32_t &token, RsPostedGroup &group)
|
|||
std::cerr << "p3Posted::createGroup()" << std::endl;
|
||||
|
||||
RsGxsPostedGroupItem* grpItem = new RsGxsPostedGroupItem();
|
||||
grpItem->mGroup = group;
|
||||
grpItem->meta = group.mMeta;
|
||||
grpItem->fromPostedGroup(group, true);
|
||||
|
||||
|
||||
RsGenExchange::publishGroup(token, grpItem);
|
||||
return true;
|
||||
|
@ -278,8 +277,8 @@ bool p3Posted::updateGroup(uint32_t &token, RsPostedGroup &group)
|
|||
std::cerr << "p3Posted::updateGroup()" << std::endl;
|
||||
|
||||
RsGxsPostedGroupItem* grpItem = new RsGxsPostedGroupItem();
|
||||
grpItem->mGroup = group;
|
||||
grpItem->meta = group.mMeta;
|
||||
grpItem->fromPostedGroup(group, true);
|
||||
|
||||
|
||||
RsGenExchange::updateGroup(token, grpItem);
|
||||
return true;
|
||||
|
|
|
@ -77,18 +77,18 @@ void TS_dumpState() ;
|
|||
// - The total number of TR per second emmited from self will be MAX_TUNNEL_REQS_PER_SECOND / TIME_BETWEEN_TUNNEL_MANAGEMENT_CALLS = 0.5
|
||||
// - I updated forward probabilities to higher values, and min them to 1/nb_connected_friends to prevent blocking tunnels.
|
||||
//
|
||||
static const rstime_t TUNNEL_REQUESTS_LIFE_TIME = 240 ; /// life time for tunnel requests in the cache.
|
||||
static const rstime_t SEARCH_REQUESTS_LIFE_TIME = 240 ; /// life time for search requests in the cache
|
||||
static const rstime_t REGULAR_TUNNEL_DIGGING_TIME = 300 ; /// maximum interval between two tunnel digging campaigns.
|
||||
static const rstime_t MAXIMUM_TUNNEL_IDLE_TIME = 60 ; /// maximum life time of an unused tunnel.
|
||||
static const rstime_t EMPTY_TUNNELS_DIGGING_TIME = 50 ; /// look into tunnels regularly every 50 sec.
|
||||
static const rstime_t TUNNEL_SPEED_ESTIMATE_LAPSE = 5 ; /// estimate tunnel speed every 5 seconds
|
||||
static const rstime_t TUNNEL_CLEANING_LAPS_TIME = 10 ; /// clean tunnels every 10 secs
|
||||
static const rstime_t TIME_BETWEEN_TUNNEL_MANAGEMENT_CALLS = 2 ; /// Tunnel management calls every 2 secs.
|
||||
static const uint32_t MAX_TUNNEL_REQS_PER_SECOND = 1 ; /// maximum number of tunnel requests issued per second. Was 0.5 before
|
||||
static const uint32_t MAX_ALLOWED_SR_IN_CACHE = 120 ; /// maximum number of search requests allowed in cache. That makes 2 per sec.
|
||||
static const uint32_t TURTLE_SEARCH_RESULT_MAX_HITS_FILES =5000 ; /// maximum number of search results forwarded back to the source.
|
||||
static const uint32_t TURTLE_SEARCH_RESULT_MAX_HITS_DEFAULT= 100 ; /// default maximum number of search results forwarded back source.
|
||||
static const rstime_t TUNNEL_REQUESTS_LIFE_TIME = 240 ; /// life time for tunnel requests in the cache.
|
||||
static const rstime_t SEARCH_REQUESTS_LIFE_TIME = 240 ; /// life time for search requests in the cache
|
||||
static const rstime_t REGULAR_TUNNEL_DIGGING_TIME = 300 ; /// maximum interval between two tunnel digging campaigns.
|
||||
static const rstime_t MAXIMUM_TUNNEL_IDLE_TIME = 60 ; /// maximum life time of an unused tunnel.
|
||||
static const rstime_t EMPTY_TUNNELS_DIGGING_TIME = 50 ; /// look into tunnels regularly every 50 sec.
|
||||
static const rstime_t TUNNEL_SPEED_ESTIMATE_LAPSE = 5 ; /// estimate tunnel speed every 5 seconds
|
||||
static const rstime_t TUNNEL_CLEANING_LAPS_TIME = 10 ; /// clean tunnels every 10 secs
|
||||
static const rstime_t TIME_BETWEEN_TUNNEL_MANAGEMENT_CALLS = 2 ; /// Tunnel management calls every 2 secs.
|
||||
static const uint32_t MAX_TUNNEL_REQS_PER_SECOND = 1 ; /// maximum number of tunnel requests issued per second. Was 0.5 before
|
||||
static const uint32_t MAX_ALLOWED_SR_IN_CACHE = 120 ; /// maximum number of search requests allowed in cache. That makes 2 per sec.
|
||||
static const uint32_t TURTLE_SEARCH_RESULT_MAX_HITS_FILES =5000 ; /// maximum number of search results forwarded back to the source.
|
||||
static const uint32_t TURTLE_SEARCH_RESULT_MAX_HITS_DEFAULT = 100 ; /// default maximum number of search results forwarded back source.
|
||||
|
||||
static const float depth_peer_probability[7] = { 1.0f,0.99f,0.9f,0.7f,0.6f,0.5,0.4f } ;
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ RsItem *RsTurtleSerialiser::create_item(uint16_t service,uint8_t item_subtype) c
|
|||
case RS_TURTLE_SUBTYPE_OPEN_TUNNEL : return new RsTurtleOpenTunnelItem();
|
||||
case RS_TURTLE_SUBTYPE_TUNNEL_OK : return new RsTurtleTunnelOkItem();
|
||||
case RS_TURTLE_SUBTYPE_GENERIC_DATA : return new RsTurtleGenericDataItem();
|
||||
case RS_TURTLE_SUBTYPE_GENERIC_FAST_DATA : return new RsTurtleGenericFastDataItem();
|
||||
case RS_TURTLE_SUBTYPE_GENERIC_SEARCH_REQUEST : return new RsTurtleGenericSearchRequestItem();
|
||||
case RS_TURTLE_SUBTYPE_GENERIC_SEARCH_RESULT : return new RsTurtleGenericSearchResultItem();
|
||||
|
||||
|
@ -244,8 +245,12 @@ void RsTurtleTunnelOkItem::serial_process(RsGenericSerializer::SerializeJob j,Rs
|
|||
void RsTurtleGenericDataItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
||||
{
|
||||
RsTypeSerializer::serial_process<uint32_t>(j,ctx,tunnel_id ,"tunnel_id") ;
|
||||
|
||||
RsTypeSerializer::TlvMemBlock_proxy prox(data_bytes,data_size) ;
|
||||
|
||||
RsTypeSerializer::serial_process(j,ctx,prox,"data bytes") ;
|
||||
}
|
||||
void RsTurtleGenericFastDataItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
||||
{
|
||||
RsTypeSerializer::serial_process<uint32_t>(j,ctx,tunnel_id ,"tunnel_id") ;
|
||||
RsTypeSerializer::TlvMemBlock_proxy prox(data_bytes,data_size) ;
|
||||
RsTypeSerializer::serial_process(j,ctx,prox,"data bytes") ;
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ const uint8_t RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST = 0x11 ;
|
|||
// const uint8_t RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST = 0x13 ;
|
||||
const uint8_t RS_TURTLE_SUBTYPE_CHUNK_CRC = 0x14 ;
|
||||
const uint8_t RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST = 0x15 ;
|
||||
const uint8_t RS_TURTLE_SUBTYPE_GENERIC_FAST_DATA = 0x16 ;
|
||||
|
||||
|
||||
class TurtleSearchRequestInfo ;
|
||||
|
@ -331,6 +332,28 @@ class RsTurtleGenericDataItem: public RsTurtleGenericTunnelItem
|
|||
void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
||||
};
|
||||
|
||||
// Same, but with a fact priority. Can rather be used for e.g. distant chat.
|
||||
//
|
||||
class RsTurtleGenericFastDataItem: public RsTurtleGenericTunnelItem
|
||||
{
|
||||
public:
|
||||
RsTurtleGenericFastDataItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_GENERIC_FAST_DATA), data_size(0), data_bytes(0) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_GENERIC_FAST_DATA);}
|
||||
virtual ~RsTurtleGenericFastDataItem() { if(data_bytes != NULL) free(data_bytes) ; }
|
||||
|
||||
virtual bool shouldStampTunnel() const { return true ; }
|
||||
|
||||
uint32_t data_size ;
|
||||
void *data_bytes ;
|
||||
|
||||
void clear()
|
||||
{
|
||||
free(data_bytes) ;
|
||||
data_bytes = NULL ;
|
||||
data_size = 0;
|
||||
}
|
||||
protected:
|
||||
void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
||||
};
|
||||
/***********************************************************************************/
|
||||
/* Turtle Serialiser class */
|
||||
/***********************************************************************************/
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
* *
|
||||
* libretroshare: retroshare core library *
|
||||
* *
|
||||
* Copyright 2012-2012 by Cyril Soler <csoler@users.sourceforge.net> *
|
||||
* Copyright 2012 Cyril Soler <csoler@users.sourceforge.net> *
|
||||
* Copyright 2019 Gioacchino Mazzurco <gio@altermundi.net> *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License as *
|
||||
|
@ -21,9 +22,45 @@
|
|||
*******************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <util/stacktrace.h>
|
||||
#include <memory>
|
||||
|
||||
#include "util/stacktrace.h"
|
||||
|
||||
/**
|
||||
* @brief Shorthand macro to declare optional functions output parameters
|
||||
* To define an optional output paramether use the following syntax
|
||||
*
|
||||
\code{.cpp}
|
||||
bool myFunnyFunction(
|
||||
int mandatoryParamether,
|
||||
BigType& myOptionalOutput = RS_DEFAULT_STORAGE_PARAM(BigType) )
|
||||
\endcode
|
||||
*
|
||||
* The function caller then can call myFunnyFunction either passing
|
||||
* myOptionalOutput parameter or not.
|
||||
* @see RsGxsChannels methods for real usage examples.
|
||||
*
|
||||
* @details
|
||||
* When const references are used to pass function parameters it is easy do make
|
||||
* those params optional by defining a default value in the function
|
||||
* declaration, because a temp is accepted as default parameter in those cases.
|
||||
* It is not as simple when one want to make optional a non-const reference
|
||||
* parameter that is usually used as output, in that case as a temp is in theory
|
||||
* not acceptable.
|
||||
* Yet it is possible to overcome that limitation with the following trick:
|
||||
* If not passed as parameter the storage for the output parameter can be
|
||||
* dinamically allocated directly by the function call, to avoid leaking memory
|
||||
* on each function call the pointer to that storage is made unique so once the
|
||||
* function returns it goes out of scope and is automatically deleted.
|
||||
* About performance overhead: std::unique_ptr have very good performance and
|
||||
* modern compilers may be even able to avoid the dynamic allocation in this
|
||||
* case, any way the allocation would only happen if the parameter is not
|
||||
* passed, so any effect on performace would happen only in case where the
|
||||
* function is called without the parameter.
|
||||
*/
|
||||
#define RS_DEFAULT_STORAGE_PARAM(Type) *std::unique_ptr<Type>(new Type)
|
||||
|
||||
void *rs_malloc(size_t size) ;
|
||||
|
||||
|
|
|
@ -201,7 +201,7 @@ void RsThread::start(const std::string &threadName)
|
|||
if(threadName.length() > 15)
|
||||
{
|
||||
#ifdef DEBUG_THREADS
|
||||
THREAD_DEBUG << "RsThread::start called with to long name '" << name << "' truncating..." << std::endl;
|
||||
THREAD_DEBUG << "RsThread::start called with to long name '" << threadName << "' truncating..." << std::endl;
|
||||
#endif
|
||||
RS_pthread_setname_np(mTid, threadName.substr(0, 15).c_str());
|
||||
} else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue