merged with upstreamm/master

This commit is contained in:
csoler 2020-05-09 22:33:27 +02:00
commit 6f6e0de5f1
No known key found for this signature in database
GPG key ID: 7BCA522266C0804C
59 changed files with 1438 additions and 1164 deletions

View file

@ -289,7 +289,7 @@ bool GxsSecurity::generateKeyPair(RsTlvPublicRSAKey& public_key,RsTlvPrivateRSAK
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 false ;
}
return true ;
@ -418,11 +418,11 @@ bool GxsSecurity::validateNxsMsg(const RsNxsMsg& msg, const RsTlvKeySignature& s
/* check signature timeperiod */
if ((msgMeta.mPublishTs < key.startTS) || (key.endTS != 0 && msgMeta.mPublishTs > key.endTS))
{
RsWarn() << __PRETTY_FUNCTION__ << " GxsSecurity::validateNxsMsg() TS out of range for key " << msgMeta.mAuthorId
<< " usage is limited to TS=[" << key.startTS << "," << key.endTS << "] and msg publish time is " << msgMeta.mPublishTs << std::endl;
return false;
}
{
RsWarn() << __PRETTY_FUNCTION__ << " GxsSecurity::validateNxsMsg() TS out of range for key " << msgMeta.mAuthorId
<< " usage is limited to TS=[" << key.startTS << "," << key.endTS << "] and msg publish time is " << msgMeta.mPublishTs << std::endl;
return false;
}
/* decode key */
const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data;

View file

@ -274,12 +274,12 @@
NXS_NET_DEBUG_8 gxs distant sync
***/
#define NXS_NET_DEBUG_0 1
#define NXS_NET_DEBUG_1 1
//#define NXS_NET_DEBUG_0 1
//#define NXS_NET_DEBUG_1 1
//#define NXS_NET_DEBUG_2 1
//#define NXS_NET_DEBUG_3 1
#define NXS_NET_DEBUG_4 1
#define NXS_NET_DEBUG_5 1
//#define NXS_NET_DEBUG_4 1
//#define NXS_NET_DEBUG_5 1
//#define NXS_NET_DEBUG_6 1
//#define NXS_NET_DEBUG_7 1
//#define NXS_NET_DEBUG_8 1
@ -321,7 +321,7 @@ static const uint32_t RS_NXS_ITEM_ENCRYPTION_STATUS_GXS_KEY_MISSING = 0x05 ;
|| defined(NXS_NET_DEBUG_8)
static const RsPeerId peer_to_print = RsPeerId();//std::string("a97fef0e2dc82ddb19200fb30f9ac575")) ;
static const RsGxsGroupId group_id_to_print = RsGxsGroupId(std::string("66052380f5d1d0c5992e2b55dc402ce6")) ; // use this to allow to this group id only, or "" for all IDs
static const RsGxsGroupId group_id_to_print = RsGxsGroupId() ; // use this to allow to this group id only, or "" for all IDs
static const uint32_t service_to_print = RS_SERVICE_GXS_TYPE_GXSCIRCLE; // use this to allow to this service id only, or 0 for all services
// warning. Numbers should be SERVICE IDS (see serialiser/rsserviceids.h. E.g. 0x0215 for forums)

View file

@ -806,22 +806,22 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
X509_NAME_free(issuer_name);
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
// (does not leak the key creation date to the outside anymore. for more privacy)
ASN1_TIME_set(X509_get_notBefore(x509), 0);
ASN1_TIME_set(X509_get_notAfter(x509), 0);
// (does not leak the key creation date to the outside anymore. for more privacy)
ASN1_TIME_set(X509_get_notBefore(x509), 0);
ASN1_TIME_set(X509_get_notAfter(x509), 0);
#else
// NEW code, set validity time between 2010 and 2110 (remember to change it when, if OpenSSL check it by default. ;) )
// (does not leak the key creation date to the outside anymore. for more privacy)
if (!ASN1_TIME_set_string(X509_getm_notBefore(x509), "20100101000000Z"))
{
RsErr() << __PRETTY_FUNCTION__ << " Set notBefore FAIL" << std::endl;
return NULL;
}
if (!ASN1_TIME_set_string(X509_getm_notAfter(x509), "21100101000000Z"))
{
RsErr() << __PRETTY_FUNCTION__ << " Set notAfter FAIL" << std::endl;
return NULL;
}
// NEW code, set validity time between 2010 and 2110 (remember to change it when, if OpenSSL check it by default. ;) )
// (does not leak the key creation date to the outside anymore. for more privacy)
if (!ASN1_TIME_set_string(X509_getm_notBefore(x509), "20100101000000Z"))
{
RsErr() << __PRETTY_FUNCTION__ << " Set notBefore FAIL" << std::endl;
return NULL;
}
if (!ASN1_TIME_set_string(X509_getm_notAfter(x509), "21100101000000Z"))
{
RsErr() << __PRETTY_FUNCTION__ << " Set notAfter FAIL" << std::endl;
return NULL;
}
#endif
if (!X509_set_subject_name(x509, X509_REQ_get_subject_name(req)))

View file

@ -56,6 +56,69 @@ const int PQISSL_UDP_FLAG = 0x02;
/* TCP buffer size for Windows systems */
const int WINDOWS_TCP_BUFFER_SIZE = 512 * 1024; // 512 KB
// This is a (very) simple overview of the different state machnines. The tree includes high level funtions only.
//
// connect_parameter() is used to pass down settings, like address or timeout values
//
// tick() or connect()
// |
// +----- ConnectAttempt()
// |
// +--WAITING_NOT or WAITING_DELAY
// | |
// | +----- Delay_Connection()
// | |
// | +--WAITING_NOT
// | | - set 'waiting' to WAITING_DELAY and set delay for next connection attempt
// | |
// | +--WAITING_DELAY
// | |
// | +----- Initiate_Connection()
// | |
// | +----- setup socket
// | +----- connect
// | - on success: set "waiting" to WAITING_SOCK_CONNECT and "sockfd" to newly created socket
// | - on failure: set "waiting" to WAITING_FAIL_INTERFACE
// |
// +--WAITING_SOCK_CONNECT
// | |
// | +----- Initiate_SSL_Connection()
// | |
// | +----- Basic_Connection_Complete()
// | | |
// | | +----- CheckConnectionTimeout()
// | | |
// | | +----- ready up socket.
// | | - SOCKS, udp tou, i2p BOB intercept here
// | | - on failure: set "waiting" to WAITING_FAIL_INTERFACE and "sockfd" to -1
// | |
// | +----- create SSL context and attach file descriptors
// | - on success:_set "waiting" to WAITING_SSL_CONNECTION
// |
// +--WAITING_SSL_CONNECTION or WAITING_SSL_AUTHORISE
// | |
// | +----- Authorise_SSL_Connection()
// | |
// | +----- SSL_Connection_Complete()
// | | |
// | | +----- performes TSL handshake
// | | - on success: set "waiting" to WAITING_SSL_AUTHORISE
// | | - on failure: set "waiting" to WAITING_FAIL_INTERFACE
// | |
// | +----- set "waiting" to WAITING_NOT
// | |
// | +----- accept_locked()
// | - add peer to the rest of RS and start pqi thread
// |
// |
// +--WAITING_FAIL_INTERFACE
// |
// +----- Failed_Connection()
// - set "waiting" to WAITING_NOT
//
/***************************** pqi Net SSL Interface *********************************
* This provides the base SSL interface class,
* and handles most of the required functionality.
@ -203,9 +266,9 @@ bool CheckConnectionTimeout();
uint32_t mConnectTimeout;
rstime_t mTimeoutTS;
RS_SET_CONTEXT_DEBUG_LEVEL(1)
private:
// ssl only fns.
int connectInterface(const struct sockaddr_storage &addr);
RS_SET_CONTEXT_DEBUG_LEVEL(1)
};

View file

@ -34,6 +34,73 @@
#define RS_PQISSL_AUTH_DOUBLE_CHECK 1
// This is a simple overview of how the listener is setup, ticked (calling accept) and peers added to it.
// On the highest level (RsServer) the listener lives inside the pqisslpersongrp class (variable: "pqih").
// Inside pqisslpersongrp the listener is stored in "pqil".
//
// The listener has an internal list with incoming connections that are handled in a similar fashion to pqissl.
// (Mainly setting up the socket (non-blocking) and establisching the ssl handshake.)
// When everything went fine the connection is passed to pqissl in finaliseConnection()
//
// This is how the listener is initialized during start up:
//
// RsServer::StartupRetroShare()
// |
// +----- pqih = new pqisslpersongrp(serviceCtrl, flags, mPeerMgr);
// +----- pqih->init_listener();
// |
// +----- pqil = locked_createListener(laddr);
// |
// +----- return new pqissllistener(laddr, mPeerMgr);
//
//
// This is how the listener is ticked to call accept:
//
// RsServer::StartupRetroShare()
// |
// +----- pqih->tick();
// |
// +----- pqil->tick();
// |
// +----- acceptconnection();
// | |
// | +----- accecpt()
// |
// +----- continueaccepts();
// +----- finaliseAccepts();
// |
// +----- finaliseConnection()
// |
// +----- pqis->accept()
//
//
// This is how peers (their id) are registered to the listener:
// (This is only used to tell if a connection peer is known or a new one (which is then added))
//
// pqipersongrp::addPeer()
// |
// +----- pqiperson *pqip = locked_createPerson(id, pqil);
// | |
// | +----- pqiperson *pqip = new pqiperson(id, this);
// | +----- pqissl *pqis = new pqissl((pqissllistener *) listener, pqip, mLinkMgr);
// | +----- pqiconnect *pqisc = new pqiconnect(pqip, rss, pqis);
// | +----- pqip->addChildInterface(PQI_CONNECT_TCP, pqisc);
// | |
// | +-- sets kids[type] = pqisc;
// |
// +----- pqip->reset();
// +----- pqip->listen();
// |
// +-- for all kids[]
// |
// +----- listen() ( of class pqiconnect )
// |
// +----- listen() ( of class pqissl )
// |
// +----- pqil->addlistenaddr(PeerId(), this);
/***************************** pqi Net SSL Interface *********************************
*/

View file

@ -333,6 +333,19 @@ public:
std::vector<RsGxsChannelPost>& posts,
std::vector<RsGxsComment>& comments ) = 0;
/**
* @brief Get channel comments corresponding to the given IDs.
* If the set is empty, nothing is returned.
* @jsonapi{development}
* @param[in] channelId id of the channel of which the content is requested
* @param[in] contentIds ids of requested contents
* @param[out] comments storage for the comments
* @return false if something failed, true otherwhise
*/
virtual bool getChannelComments(const RsGxsGroupId &channelId,
const std::set<RsGxsMessageId> &contentIds,
std::vector<RsGxsComment> &comments) = 0;
/**
* @brief Get channel content summaries
* @jsonapi{development}

View file

@ -41,11 +41,12 @@
#include "services/rseventsservice.h"
/****
#define DEBUG_TICK 1
****/
/*******************
#define TICK_DEBUG 1
*******************/
#define WARN_BIG_CYCLE_TIME (0.2)
#ifdef WINDOWS_SYS
#include "util/rstime.h"
#include <sys/timeb.h>
@ -73,14 +74,13 @@ static double getCurrentTS()
// 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;
const double RsServer::minTickInterval = 0.05;
const double RsServer::maxTickInterval = 0.2;
RsServer::RsServer() :
coreMutex("RsServer"), mShutdownCallback([](int){}),
coreReady(false)
coreMutex("RsServer"), mShutdownCallback([](int){}),
coreReady(false)
{
{
RsEventsService* tmpRsEvtPtr = new RsEventsService();
@ -108,21 +108,20 @@ RsServer::RsServer() :
msgSrv = NULL;
chatSrv = NULL;
mStatusSrv = NULL;
mGxsTunnels = NULL;
mGxsTunnels = NULL;
mMin = 0;
mLoop = 0;
mLastts = getCurrentTS();
mTickInterval = maxTickInterval ;
mAvgRunDuration = 0;
mLastRunDuration = 0;
mCycle1 = 0;
mCycle2 = 0;
mCycle3 = 0;
mCycle4 = 0;
/* caches (that need ticking) */
mLastts = getCurrentTS();
mLastSec = 0; /* for the slower ticked stuff */
mTimeDelta = 0.25 ;
mAvgTickRate = mTimeDelta;
/* caches (that need ticking) */
/* Config */
/* config */
mConfigMgr = NULL;
mGeneralConfig = NULL;
}
@ -132,143 +131,132 @@ RsServer::~RsServer()
delete mGxsTrans;
}
/* General Internal Helper Functions
----> MUST BE LOCKED!
*/
// General Internal Helper Functions ----> MUST BE LOCKED!
/* Thread Fn: Run the Core */
void RsServer::threadTick()
{
rstime::rs_usleep(mTimeDelta * 1000000);
double ts = getCurrentTS();
double delta = ts - mLastts;
/* for the fast ticked stuff */
if (delta > mTimeDelta)
{
#ifdef DEBUG_TICK
std::cerr << "Delta: " << delta << std::endl;
std::cerr << "Time Delta: " << mTimeDelta << std::endl;
std::cerr << "Avg Tick Rate: " << mAvgTickRate << std::endl;
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG ticking interval "<< mTickInterval << std::endl;
#endif
mLastts = ts;
// we try to tick at a regular interval which depends on the load
// if there is time left, we sleep
double timeToSleep = mTickInterval - mAvgRunDuration;
/******************************** RUN SERVER *****************/
lockRsCore();
if (timeToSleep > 0)
{
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG will sleep " << timeToSleep << " ms" << std::endl;
#endif
rstime::rs_usleep(timeToSleep * 1000000);
}
int moreToTick = pqih->tick();
double ts = getCurrentTS();
mLastts = ts;
#ifdef DEBUG_TICK
std::cerr << "RsServer::run() ftserver->tick(): moreToTick: " << moreToTick << std::endl;
// stuff we do always
// tick the core
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG ticking server" << std::endl;
#endif
lockRsCore();
int moreToTick = pqih->tick();
unlockRsCore();
// tick the managers
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG ticking mPeerMgr" << std::endl;
#endif
mPeerMgr->tick();
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG ticking mLinkMgr" << std::endl;
#endif
mLinkMgr->tick();
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG ticking mNetMgr" << std::endl;
#endif
mNetMgr->tick();
// stuff we do every second
if (ts - mCycle1 > 1)
{
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG every second" << std::endl;
#endif
// slow services
if (rsPlugins)
rsPlugins->slowTickPlugins((rstime_t)ts);
// UDP keepalive
// tou_tick_stunkeepalive();
// other stuff to tick
// update();
mCycle1 = ts;
}
// stuff we do every five seconds
if (ts - mCycle2 > 5)
{
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG every 5 seconds" << std::endl;
#endif
// save stuff
mConfigMgr->tick();
mCycle2 = ts;
}
// stuff we do every minute
if (ts - mCycle3 > 60)
{
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG every 60 seconds" << std::endl;
#endif
// force saving FileTransferStatus TODO
// ftserver->saveFileTransferStatus();
// see if we need to resave certs
// AuthSSL::getAuthSSL()->CheckSaveCertificates();
mCycle3 = ts;
}
// stuff we do every hour
if (ts - mCycle4 > 3600)
{
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG every hour" << std::endl;
#endif
mCycle4 = ts;
}
// ticking is done, now compute new values of mLastRunDuration, mAvgRunDuration and mTickInterval
ts = getCurrentTS();
mLastRunDuration = ts - mLastts;
mAvgRunDuration = 0.1 * mLastRunDuration + 0.9 * mAvgRunDuration;
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG new mLastRunDuration " << mLastRunDuration << " mAvgRunDuration " << mAvgRunDuration << std::endl;
if (mLastRunDuration > WARN_BIG_CYCLE_TIME)
RsDbg() << "TICK_DEBUG excessively long lycle time " << mLastRunDuration << std::endl;
#endif
// if the core has returned that there is more to tick we decrease the ticking interval, else we increse it
// this should be studied closer as I dont think that the core ever returns 1
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG moreToTick " << moreToTick << std::endl;
#endif
if (moreToTick == 1)
mTickInterval = 0.9 * mTickInterval;
else
mTickInterval = 1.1 * mTickInterval;
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG new tick interval " << mTickInterval << std::endl;
#endif
unlockRsCore();
/* tick the Managers */
mPeerMgr->tick();
mLinkMgr->tick();
mNetMgr->tick();
/******************************** RUN SERVER *****************/
/* adjust tick rate depending on whether there is more.
*/
mAvgTickRate = 0.2 * mTimeDelta + 0.8 * mAvgTickRate;
if (1 == moreToTick)
{
mTimeDelta = 0.9 * mAvgTickRate;
if (mTimeDelta > kickLimit)
{
/* force next tick in one sec
* if we are reading data.
*/
mTimeDelta = kickLimit;
mAvgTickRate = kickLimit;
}
}
else
{
mTimeDelta = 1.1 * mAvgTickRate;
}
/* limiter */
if (mTimeDelta < minTimeDelta)
{
mTimeDelta = minTimeDelta;
}
else if (mTimeDelta > maxTimeDelta)
{
mTimeDelta = maxTimeDelta;
}
/* Fast Updates */
/* now we have the slow ticking stuff */
/* stuff ticked once a second (but can be slowed down) */
if ((int) ts > mLastSec)
{
mLastSec = (int) ts;
// Every second! (UDP keepalive).
//tou_tick_stunkeepalive();
// every five loops (> 5 secs)
if (mLoop % 5 == 0)
{
// update_quick_stats();
// Update All Every 5 Seconds.
// These Update Functions do the locking themselves.
#ifdef DEBUG_TICK
std::cerr << "RsServer::run() Updates()" << std::endl;
#endif
mConfigMgr->tick(); /* saves stuff */
}
// every 60 loops (> 1 min)
if (++mLoop >= 60)
{
mLoop = 0;
/* force saving FileTransferStatus TODO */
//ftserver->saveFileTransferStatus();
/* see if we need to resave certs */
//AuthSSL::getAuthSSL()->CheckSaveCertificates();
/* hour loop */
if (++mMin >= 60)
{
mMin = 0;
}
}
/* Tick slow services */
if(rsPlugins)
rsPlugins->slowTickPlugins((rstime_t)ts);
// slow update tick as well.
// update();
} // end of slow tick.
} // end of only once a second.
#ifdef DEBUG_TICK
double endCycleTs = getCurrentTS();
double cycleTime = endCycleTs - ts;
if (cycleTime > WARN_BIG_CYCLE_TIME)
{
std::string out;
rs_sprintf(out, "RsServer::run() WARNING Excessively Long Cycle Time: %g secs => Please DEBUG", cycleTime);
std::cerr << out << std::endl;
}
// keep the tick interval within allowed limits
if (mTickInterval < minTickInterval)
mTickInterval = minTickInterval;
else if (mTickInterval > maxTickInterval)
mTickInterval = maxTickInterval;
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG new tick interval after limiter " << mTickInterval << std::endl;
#endif
}

View file

@ -172,8 +172,8 @@ public:
// p3Posted *mPosted;
// p3PhotoService *mPhoto;
// p3GxsCircles *mGxsCircles;
// p3GxsNetService *mGxsNetService;
// p3IdService *mGxsIdService;
// p3GxsNetService *mGxsNetService;
// p3IdService *mGxsIdService;
// p3GxsForums *mGxsForums;
// p3GxsChannels *mGxsChannels;
// p3Wire *mWire;
@ -188,16 +188,14 @@ public:
// Worker Data.....
int mMin ;
int mLoop ;
int mLastts ;
long mLastSec ;
double mAvgTickRate ;
double mTimeDelta ;
double mLastts;
double mTickInterval;
double mLastRunDuration;
double mAvgRunDuration;
double mCycle1, mCycle2, mCycle3, mCycle4;
static const double minTimeDelta; // 25;
static const double maxTimeDelta;
static const double kickLimit;
static const double minTickInterval;
static const double maxTickInterval;
/// @see RsControl::setShutdownCallback
std::function<void(int)> mShutdownCallback;

View file

@ -1193,7 +1193,7 @@ int RsServer::StartupRetroShare()
std::cerr << "(EE) Cannot create extensions directory " << extensions_dir
<< ". This is not mandatory, but you probably have a permission problem." << std::endl;
#ifndef DEBUG_PLUGIN_SYSTEM
#ifdef DEBUG_PLUGIN_SYSTEM
plugins_directories.push_back(".") ; // this list should be saved/set to some correct value.
// possible entries include: /usr/lib/retroshare, ~/.retroshare/extensions/, etc.
#endif

View file

@ -542,22 +542,33 @@ void RsTypeSerializer::RawMemoryWrapper::serial_process(
ctx.mOffset += second;
break;
case RsGenericSerializer::DESERIALIZE:
{
uint32_t serialSize = 0;
RS_SERIAL_PROCESS(serialSize);
if(first || second)
{
/* Items are created anew before deserialization so buffer pointer
* must be null and size 0 at this point */
RsWarn() << __PRETTY_FUNCTION__ << " DESERIALIZE got uninitialized "
<< " or pre-allocated buffer! Buffer pointer: " << first
<< " must be null and size: " << second << " must be 0 at "
<< "this point. Does your item costructor initialize them "
<< "properly?" << std::endl;
print_stacktrace();
}
RS_SERIAL_PROCESS(second);
if(!ctx.mOk) break;
ctx.mOk = serialSize <= MAX_SERIALIZED_CHUNK_SIZE;
ctx.mOk = (second <= MAX_SERIALIZED_CHUNK_SIZE);
if(!ctx.mOk)
{
RsErr() << __PRETTY_FUNCTION__
<< std::errc::message_size << " "
<< serialSize << " > " << MAX_SERIALIZED_CHUNK_SIZE
<< second << " > " << MAX_SERIALIZED_CHUNK_SIZE
<< std::endl;
clear();
break;
}
if(!serialSize)
if(!second)
{
Dbg3() << __PRETTY_FUNCTION__ << " Deserialized empty memory chunk"
<< std::endl;
@ -565,7 +576,7 @@ void RsTypeSerializer::RawMemoryWrapper::serial_process(
break;
}
ctx.mOk = ctx.mSize >= ctx.mOffset + serialSize;
ctx.mOk = ctx.mSize >= ctx.mOffset + second;
if(!ctx.mOk)
{
RsErr() << __PRETTY_FUNCTION__ << std::errc::no_buffer_space
@ -576,16 +587,10 @@ void RsTypeSerializer::RawMemoryWrapper::serial_process(
break;
}
if(serialSize != second)
{
first = reinterpret_cast<uint8_t*>(realloc(first, serialSize));
second = serialSize;
}
first = reinterpret_cast<uint8_t*>(malloc(second));
memcpy(first, ctx.mData + ctx.mOffset, second);
ctx.mOffset += second;
break;
}
case RsGenericSerializer::PRINT: break;
case RsGenericSerializer::TO_JSON:
{

View file

@ -1116,11 +1116,30 @@ bool p3GxsChannels::getChannelContent( const RsGxsGroupId& channelId,
msgIds[channelId] = contentIds;
if( !requestMsgInfo(token, opts, msgIds) || waitToken(token) != RsTokenService::COMPLETE )
return false;
return false;
return getPostData(token, posts, comments);
}
bool p3GxsChannels::getChannelComments(const RsGxsGroupId &channelId,
const std::set<RsGxsMessageId> &contentIds,
std::vector<RsGxsComment> &comments)
{
std::vector<RsGxsGrpMsgIdPair> msgIds;
for (auto& msg:contentIds)
msgIds.push_back(RsGxsGrpMsgIdPair(channelId,msg));
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA;
opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST;
uint32_t token;
if( !requestMsgRelatedInfo(token, opts, msgIds) || waitToken(token) != RsTokenService::COMPLETE )
return false;
return getRelatedComments(token,comments);
}
bool p3GxsChannels::createChannelV2(
const std::string& name, const std::string& description,
const RsGxsImage& thumbnail, const RsGxsId& authorId,

View file

@ -196,6 +196,11 @@ virtual bool ExtraFileRemove(const RsFileHash &hash);
std::vector<RsGxsChannelPost>& posts,
std::vector<RsGxsComment>& comments ) override;
/// Implementation of @see RsGxsChannels::getChannelComments
virtual bool getChannelComments(const RsGxsGroupId &channelId,
const std::set<RsGxsMessageId> &contentIds,
std::vector<RsGxsComment> &comments) override;
/// Implementation of @see RsGxsChannels::getContentSummaries
bool getContentSummaries(
const RsGxsGroupId& channelId,

View file

@ -40,7 +40,6 @@
/****
* #define DEBUG_CIRCLES 1
****/
#define DEBUG_CIRCLES 1
/*extern*/ RsGxsCircles* rsGxsCircles = nullptr;

View file

@ -166,7 +166,13 @@ class RsTurtleRegExpSearchRequestItem: public RsTurtleFileSearchRequestItem
class RsTurtleGenericSearchRequestItem: public RsTurtleSearchRequestItem
{
public:
RsTurtleGenericSearchRequestItem() : RsTurtleSearchRequestItem(RS_TURTLE_SUBTYPE_GENERIC_SEARCH_REQUEST) {}
RsTurtleGenericSearchRequestItem()
: RsTurtleSearchRequestItem(RS_TURTLE_SUBTYPE_GENERIC_SEARCH_REQUEST),
service_id(0),
search_data_len(0),
request_type(0),
search_data(nullptr)
{}
virtual ~RsTurtleGenericSearchRequestItem() { clear(); }
uint16_t service_id ; // service to search
@ -221,7 +227,11 @@ class RsTurtleFTSearchResultItem: public RsTurtleSearchResultItem
class RsTurtleGenericSearchResultItem: public RsTurtleSearchResultItem
{
public:
RsTurtleGenericSearchResultItem() : RsTurtleSearchResultItem(RS_TURTLE_SUBTYPE_GENERIC_SEARCH_RESULT){}
RsTurtleGenericSearchResultItem()
: RsTurtleSearchResultItem(RS_TURTLE_SUBTYPE_GENERIC_SEARCH_RESULT),
result_data(nullptr),
result_data_len(0)
{}
virtual ~RsTurtleGenericSearchResultItem() {}
uint32_t count() const { return result_data_len/50 ; } // This is a blind size estimate. We should probably use the actual size to limit search results.