mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-02 22:25:04 -04:00
Merge branch 'master' into qmlapp_pex_alpha
This commit is contained in:
commit
59b77da6a2
113 changed files with 6880 additions and 1675 deletions
|
@ -349,7 +349,7 @@ bool p3ChatService::sendChat(ChatId destination, std::string msg)
|
|||
uint32_t sz = _serializer->size(ci);
|
||||
std::vector<uint8_t> data; data.resize(sz);
|
||||
_serializer->serialise(ci, &data[0], &sz);
|
||||
mGxsTransport.sendMail(tId, GxsTransSubServices::P3_CHAT_SERVICE,
|
||||
mGxsTransport.sendData(tId, GxsTransSubServices::P3_CHAT_SERVICE,
|
||||
de.from, de.to, &data[0], sz);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
//#define DEBUG_CHACHA20
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x010100000L
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
#define AEAD_chacha20_poly1305_openssl AEAD_chacha20_poly1305
|
||||
#else
|
||||
#define AEAD_chacha20_poly1305_rs AEAD_chacha20_poly1305
|
||||
|
@ -386,7 +386,7 @@ void chacha20_encrypt_rs(uint8_t key[32], uint32_t block_counter, uint8_t nonce[
|
|||
}
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x010100000L
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
void chacha20_encrypt_openssl(uint8_t key[32], uint32_t block_counter, uint8_t nonce[12], uint8_t *data, uint32_t size)
|
||||
{
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
|
@ -577,7 +577,7 @@ bool AEAD_chacha20_poly1305_rs(uint8_t key[32], uint8_t nonce[12],uint8_t *data,
|
|||
}
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x010100000L
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
#define errorOut {ret = false; goto out;}
|
||||
|
||||
bool AEAD_chacha20_poly1305_openssl(uint8_t key[32], uint8_t nonce[12], uint8_t *data, uint32_t data_size, uint8_t *aad, uint32_t aad_size, uint8_t tag[16], bool encrypt_or_decrypt)
|
||||
|
@ -667,7 +667,7 @@ bool AEAD_chacha20_sha256(uint8_t key[32], uint8_t nonce[12],uint8_t *data,uint3
|
|||
|
||||
if(encrypt)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
chacha20_encrypt_rs(key,1,nonce,data,data_size);
|
||||
#else
|
||||
chacha20_encrypt_openssl(key, 1, nonce, data, data_size);
|
||||
|
@ -676,7 +676,7 @@ bool AEAD_chacha20_sha256(uint8_t key[32], uint8_t nonce[12],uint8_t *data,uint3
|
|||
uint8_t computed_tag[EVP_MAX_MD_SIZE];
|
||||
unsigned int md_size ;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
HMAC_CTX hmac_ctx ;
|
||||
HMAC_CTX_init(&hmac_ctx) ;
|
||||
|
||||
|
@ -709,7 +709,7 @@ bool AEAD_chacha20_sha256(uint8_t key[32], uint8_t nonce[12],uint8_t *data,uint3
|
|||
uint8_t computed_tag[EVP_MAX_MD_SIZE];
|
||||
unsigned int md_size ;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
HMAC_CTX hmac_ctx ;
|
||||
HMAC_CTX_init(&hmac_ctx) ;
|
||||
|
||||
|
@ -733,7 +733,7 @@ bool AEAD_chacha20_sha256(uint8_t key[32], uint8_t nonce[12],uint8_t *data,uint3
|
|||
|
||||
// decrypt
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
chacha20_encrypt_rs(key,1,nonce,data,data_size);
|
||||
#else
|
||||
chacha20_encrypt_openssl(key, 1, nonce, data, data_size);
|
||||
|
@ -1396,7 +1396,7 @@ bool perform_tests()
|
|||
|
||||
std::cerr << " AEAD/poly1305 own encryption speed : " << SIZE / (1024.0*1024.0) / s.duration() << " MB/s" << std::endl;
|
||||
}
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x010100000L
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
{
|
||||
RsScopeTimer s("AEAD3") ;
|
||||
AEAD_chacha20_poly1305_openssl(key,nonce,ten_megabyte_data,SIZE,aad,12,received_tag,true) ;
|
||||
|
|
|
@ -1624,11 +1624,18 @@ Sha1CheckSum p3GRouter::computeDataItemHash(RsGRouterGenericDataItem *data_item)
|
|||
RsTemporaryMemory mem(total_size) ;
|
||||
|
||||
uint32_t offset = 0 ;
|
||||
signature_serializer.serialise(data_item,mem,&total_size) ;
|
||||
offset += signed_data_size ;
|
||||
uint32_t tmp_size = total_size ;
|
||||
signature_serializer.serialise(data_item,mem,&tmp_size) ;
|
||||
if(tmp_size != signed_data_size)
|
||||
std::cerr << "(EE) Some error occured in p3GRouter::computeDataItemHash(). Mismatched offset/data size" << std::endl;
|
||||
|
||||
offset += tmp_size ;
|
||||
|
||||
data_item->signature.SetTlv(mem, total_size,&offset) ;
|
||||
|
||||
if(offset != total_size)
|
||||
std::cerr << "(EE) Some error occured in p3GRouter::computeDataItemHash(). Mismatched offset/data size" << std::endl;
|
||||
|
||||
return RsDirUtil::sha1sum(mem,total_size) ;
|
||||
}
|
||||
|
||||
|
@ -1983,7 +1990,7 @@ bool p3GRouter::signDataItem(RsGRouterAbstractMsgItem *item,const RsGxsId& signi
|
|||
std::cerr << "Created signature for data hash: " << RsDirUtil::sha1sum(data,data_size) << " and key id=" << signing_id << std::endl;
|
||||
//#endif
|
||||
// Check signature
|
||||
RsIdentityUsage::UsageCode info;
|
||||
RsIdentityUsage::UsageCode info = RsIdentityUsage::GLOBAL_ROUTER_SIGNATURE_CREATION;
|
||||
uint32_t error;
|
||||
|
||||
if(verifySignedDataItem(item,info,error))
|
||||
|
|
|
@ -41,7 +41,7 @@ static const uint32_t MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE = 256 ;
|
|||
|
||||
static RsGxsId getRsaKeyFingerprint_old_insecure_method(RSA *pubkey)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
int lenn = BN_num_bytes(pubkey -> n);
|
||||
|
||||
RsTemporaryMemory tmp(lenn) ;
|
||||
|
@ -65,7 +65,7 @@ static RsGxsId getRsaKeyFingerprint_old_insecure_method(RSA *pubkey)
|
|||
}
|
||||
static RsGxsId getRsaKeyFingerprint(RSA *pubkey)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
int lenn = BN_num_bytes(pubkey -> n);
|
||||
int lene = BN_num_bytes(pubkey -> e);
|
||||
|
||||
|
@ -359,7 +359,7 @@ bool GxsSecurity::getSignature(const char *data, uint32_t data_len, const RsTlvP
|
|||
ok &= EVP_SignUpdate(mdctx, data, data_len) == 1;
|
||||
|
||||
unsigned int siglen = EVP_PKEY_size(key_priv);
|
||||
unsigned char sigbuf[siglen];
|
||||
unsigned char sigbuf[siglen] = { 0 };
|
||||
ok &= EVP_SignFinal(mdctx, sigbuf, &siglen, key_priv) == 1;
|
||||
|
||||
// clean up
|
||||
|
|
|
@ -1576,11 +1576,20 @@ bool RsGxsDataAccess::getGroupStatistic(GroupStatisticRequest *req)
|
|||
req->mGroupStatistic.mNumChildMsgsNew = 0;
|
||||
req->mGroupStatistic.mNumChildMsgsUnread = 0;
|
||||
|
||||
std::set<RsGxsMessageId> obsolete_msgs ; // stored message ids that are referred to as older versions of an existing message
|
||||
|
||||
for(uint32_t i = 0; i < msgMetaV.size(); ++i)
|
||||
if(!msgMetaV[i]->mOrigMsgId.isNull() && msgMetaV[i]->mOrigMsgId!=msgMetaV[i]->mMsgId)
|
||||
obsolete_msgs.insert(msgMetaV[i]->mOrigMsgId);
|
||||
|
||||
for(uint32_t i = 0; i < msgMetaV.size(); ++i)
|
||||
{
|
||||
RsGxsMsgMetaData* m = msgMetaV[i];
|
||||
req->mGroupStatistic.mTotalSizeOfMsgs += m->mMsgSize + m->serial_size();
|
||||
|
||||
if(obsolete_msgs.find(m->mMsgId) != obsolete_msgs.end()) // skip obsolete messages.
|
||||
continue;
|
||||
|
||||
if (IS_MSG_NEW(m->mMsgStatus))
|
||||
{
|
||||
if (m->mParentId.isNull())
|
||||
|
|
|
@ -16,11 +16,14 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "util/rsdir.h"
|
||||
#include "gxstrans/p3gxstrans.h"
|
||||
#include "util/stacktrace.h"
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
RsGxsTrans *rsGxsTrans = NULL ;
|
||||
|
||||
p3GxsTrans::~p3GxsTrans()
|
||||
{
|
||||
p3Config::saveConfiguration();
|
||||
|
@ -31,7 +34,36 @@ p3GxsTrans::~p3GxsTrans()
|
|||
}
|
||||
}
|
||||
|
||||
bool p3GxsTrans::sendMail( RsGxsTransId& mailId,
|
||||
bool p3GxsTrans::getStatistics(GxsTransStatistics& stats)
|
||||
{
|
||||
stats.prefered_group_id = mPreferredGroupId;
|
||||
stats.outgoing_records.clear();
|
||||
|
||||
{
|
||||
RS_STACK_MUTEX(mOutgoingMutex);
|
||||
|
||||
for ( auto it = mOutgoingQueue.begin(); it != mOutgoingQueue.end(); ++it)
|
||||
{
|
||||
const OutgoingRecord& pr(it->second);
|
||||
|
||||
RsGxsTransOutgoingRecord rec ;
|
||||
rec.status = pr.status ;
|
||||
rec.send_TS = pr.mailItem.meta.mPublishTs ;
|
||||
rec.group_id = pr.mailItem.meta.mGroupId ;
|
||||
rec.trans_id = pr.mailItem.mailId ;
|
||||
rec.recipient = pr.recipient ;
|
||||
rec.data_size = pr.mailData.size();
|
||||
rec.data_hash = RsDirUtil::sha1sum(pr.mailData.data(),pr.mailData.size());
|
||||
rec.client_service = pr.clientService ;
|
||||
|
||||
stats.outgoing_records.push_back(rec) ;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsTrans::sendData( RsGxsTransId& mailId,
|
||||
GxsTransSubServices service,
|
||||
const RsGxsId& own_gxsid, const RsGxsId& recipient,
|
||||
const uint8_t* data, uint32_t size,
|
||||
|
@ -55,7 +87,10 @@ bool p3GxsTrans::sendMail( RsGxsTransId& mailId,
|
|||
}
|
||||
|
||||
OutgoingRecord pr( recipient, service, data, size );
|
||||
|
||||
pr.mailItem.clear();
|
||||
pr.mailItem.meta.mAuthorId = own_gxsid;
|
||||
pr.mailItem.meta.mMsgId.clear();
|
||||
pr.mailItem.cryptoType = cm;
|
||||
pr.mailItem.mailId = RSRandom::random_u64();
|
||||
|
||||
|
@ -120,9 +155,9 @@ void p3GxsTrans::handleResponse(uint32_t token, uint32_t req_type)
|
|||
&& meta.mGroupId != mPreferredGroupId;
|
||||
|
||||
if(shoudlSubscribe)
|
||||
subscribeToGroup(token, meta.mGroupId, true);
|
||||
RsGenExchange::subscribeToGroup(token, meta.mGroupId, true);
|
||||
else if(shoudlUnSubscribe)
|
||||
subscribeToGroup(token, meta.mGroupId, false);
|
||||
RsGenExchange::subscribeToGroup(token, meta.mGroupId, false);
|
||||
|
||||
#ifdef GXS_MAIL_GRP_DEBUG
|
||||
char buff[30];
|
||||
|
@ -220,10 +255,113 @@ void p3GxsTrans::handleResponse(uint32_t token, uint32_t req_type)
|
|||
}
|
||||
}
|
||||
|
||||
void p3GxsTrans::GxsTransIntegrityCleanupThread::run()
|
||||
{
|
||||
// first take out all the groups
|
||||
std::map<RsGxsGroupId, RsNxsGrp*> grp;
|
||||
mDs->retrieveNxsGrps(grp, true, true);
|
||||
|
||||
std::cerr << "GxsTransIntegrityCleanupThread::run()" << std::endl;
|
||||
|
||||
// compute hash and compare to stored value, if it fails then simply add it
|
||||
// to list
|
||||
|
||||
GxsMsgReq grps;
|
||||
for(std::map<RsGxsGroupId, RsNxsGrp*>::iterator git = grp.begin(); git != grp.end(); ++git)
|
||||
{
|
||||
RsNxsGrp* grp = git->second;
|
||||
|
||||
// store the group for retrieveNxsMsgs
|
||||
grps[grp->grpId];
|
||||
|
||||
delete grp;
|
||||
}
|
||||
|
||||
// now messages
|
||||
|
||||
std::map<RsGxsTransId,std::pair<RsGxsGroupId,RsGxsMessageId> > stored_msgs ;
|
||||
std::list<RsGxsTransId> received_msgs ;
|
||||
|
||||
GxsMsgResult msgs;
|
||||
mDs->retrieveNxsMsgs(grps, msgs, false, true);
|
||||
|
||||
for(GxsMsgResult::iterator mit = msgs.begin();mit != msgs.end(); ++mit)
|
||||
{
|
||||
std::vector<RsNxsMsg*>& msgV = mit->second;
|
||||
std::vector<RsNxsMsg*>::iterator vit = msgV.begin();
|
||||
|
||||
for(; vit != msgV.end(); ++vit)
|
||||
{
|
||||
RsNxsMsg* msg = *vit;
|
||||
|
||||
RsGxsTransSerializer s ;
|
||||
uint32_t size = msg->msg.bin_len;
|
||||
RsItem *item = s.deserialise(msg->msg.bin_data,&size);
|
||||
RsGxsTransMailItem *mitem ;
|
||||
RsGxsTransPresignedReceipt *pitem ;
|
||||
|
||||
if(item == NULL)
|
||||
std::cerr << " Unrecocognised item type!" << std::endl;
|
||||
else if(NULL != (mitem = dynamic_cast<RsGxsTransMailItem*>(item)))
|
||||
{
|
||||
std::cerr << " " << msg->metaData->mMsgId << ": Mail data with ID " << std::hex << mitem->mailId << std::dec << " from " << msg->metaData->mAuthorId << " size: " << msg->msg.bin_len << std::endl;
|
||||
|
||||
stored_msgs[mitem->mailId] = std::make_pair(msg->metaData->mGroupId,msg->metaData->mMsgId) ;
|
||||
}
|
||||
else if(NULL != (pitem = dynamic_cast<RsGxsTransPresignedReceipt*>(item)))
|
||||
{
|
||||
std::cerr << " " << msg->metaData->mMsgId << ": Signed rcpt of ID " << std::hex << pitem->mailId << std::dec << " from " << msg->metaData->mAuthorId << " size: " << msg->msg.bin_len << std::endl;
|
||||
|
||||
received_msgs.push_back(pitem->mailId) ;
|
||||
}
|
||||
else
|
||||
std::cerr << " Unknown item type!" << std::endl;
|
||||
|
||||
delete msg;
|
||||
}
|
||||
}
|
||||
|
||||
GxsMsgReq msgsToDel ;
|
||||
|
||||
std::cerr << "Msg removal report:" << std::endl;
|
||||
|
||||
for(std::list<RsGxsTransId>::const_iterator it(received_msgs.begin());it!=received_msgs.end();++it)
|
||||
{
|
||||
std::map<RsGxsTransId,std::pair<RsGxsGroupId,RsGxsMessageId> >::const_iterator it2 = stored_msgs.find(*it) ;
|
||||
|
||||
if(stored_msgs.end() != it2)
|
||||
{
|
||||
msgsToDel[it2->second.first].push_back(it2->second.second);
|
||||
|
||||
std::cerr << " scheduling msg " << std::hex << it2->second.first << "," << it2->second.second << " for deletion." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
mDs->removeMsgs(msgsToDel);
|
||||
}
|
||||
|
||||
void p3GxsTrans::service_tick()
|
||||
{
|
||||
GxsTokenQueue::checkRequests();
|
||||
|
||||
time_t now = time(NULL);
|
||||
|
||||
if(mLastMsgCleanup + MAX_DELAY_BETWEEN_CLEANUPS < now)
|
||||
{
|
||||
if(!mCleanupThread)
|
||||
mCleanupThread = new GxsTransIntegrityCleanupThread(getDataStore());
|
||||
|
||||
if(mCleanupThread->isRunning())
|
||||
std::cerr << "Cleanup thread is already running. Not running it again!" << std::endl;
|
||||
else
|
||||
{
|
||||
std::cerr << "Starting GxsIntegrity cleanup thread." << std::endl;
|
||||
|
||||
mCleanupThread->start() ;
|
||||
mLastMsgCleanup = now ;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
RS_STACK_MUTEX(mOutgoingMutex);
|
||||
for ( auto it = mOutgoingQueue.begin(); it != mOutgoingQueue.end(); )
|
||||
|
@ -337,7 +475,7 @@ void p3GxsTrans::notifyChanges(std::vector<RsGxsNotify*>& changes)
|
|||
std::cout << "p3GxsTrans::notifyChanges(...) msgChange" << std::endl;
|
||||
uint32_t token;
|
||||
RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||
getTokenService()->requestMsgInfo( token, 0xcaca,
|
||||
RsGenExchange::getTokenService()->requestMsgInfo( token, 0xcaca,
|
||||
opts, msgChange->msgChangeMap );
|
||||
GxsTokenQueue::queueRequest(token, MAILS_UPDATE);
|
||||
|
||||
|
@ -393,8 +531,8 @@ bool p3GxsTrans::requestGroupsData(const std::list<RsGxsGroupId>* groupIds)
|
|||
// std::cout << "p3GxsTrans::requestGroupsList()" << std::endl;
|
||||
uint32_t token;
|
||||
RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
|
||||
if(!groupIds) getTokenService()->requestGroupInfo(token, 0xcaca, opts);
|
||||
else getTokenService()->requestGroupInfo(token, 0xcaca, opts, *groupIds);
|
||||
if(!groupIds) RsGenExchange::getTokenService()->requestGroupInfo(token, 0xcaca, opts);
|
||||
else RsGenExchange::getTokenService()->requestGroupInfo(token, 0xcaca, opts, *groupIds);
|
||||
GxsTokenQueue::queueRequest(token, GROUPS_LIST);
|
||||
return true;
|
||||
}
|
||||
|
@ -526,6 +664,7 @@ void p3GxsTrans::processOutgoingRecord(OutgoingRecord& pr)
|
|||
{
|
||||
pr.mailItem.saltRecipientHint(pr.recipient);
|
||||
pr.mailItem.saltRecipientHint(RsGxsId::random());
|
||||
pr.mailItem.meta.mPublishTs = time(NULL);
|
||||
}
|
||||
case GxsTransSendStatus::PENDING_PREFERRED_GROUP:
|
||||
{
|
||||
|
@ -608,8 +747,7 @@ void p3GxsTrans::processOutgoingRecord(OutgoingRecord& pr)
|
|||
pr.recipient, encryptError, true ) )
|
||||
{
|
||||
pr.mailItem.payload.resize(encryptedSize);
|
||||
memcpy( &pr.mailItem.payload[0], encryptedData,
|
||||
encryptedSize );
|
||||
memcpy( &pr.mailItem.payload[0], encryptedData, encryptedSize );
|
||||
free(encryptedData);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "gxstrans/p3gxstransitems.h"
|
||||
#include "services/p3idservice.h" // For p3IdService
|
||||
#include "util/rsthreads.h"
|
||||
#include "retroshare/rsgxstrans.h"
|
||||
|
||||
struct p3GxsTrans;
|
||||
|
||||
|
@ -76,18 +77,36 @@ struct GxsTransClient
|
|||
* @see GxsTransClient::receiveGxsTransMail(...),
|
||||
* @see GxsTransClient::notifyGxsTransSendStatus(...).
|
||||
*/
|
||||
struct p3GxsTrans : RsGenExchange, GxsTokenQueue, p3Config
|
||||
class p3GxsTrans : public RsGenExchange, public GxsTokenQueue, public p3Config, public RsGxsTrans
|
||||
{
|
||||
public:
|
||||
p3GxsTrans( RsGeneralDataService* gds, RsNetworkExchangeService* nes,
|
||||
p3IdService& identities ) :
|
||||
RsGenExchange( gds, nes, new RsGxsTransSerializer(),
|
||||
RS_SERVICE_TYPE_GXS_TRANS, &identities,
|
||||
AuthenPolicy(), GXS_STORAGE_PERIOD ),
|
||||
GxsTokenQueue(this), mIdService(identities),
|
||||
GxsTokenQueue(this),
|
||||
RsGxsTrans(this),
|
||||
mIdService(identities),
|
||||
mServClientsMutex("p3GxsTrans client services map mutex"),
|
||||
mOutgoingMutex("p3GxsTrans outgoing queue map mutex"),
|
||||
mIngoingMutex("p3GxsTrans ingoing queue map mutex") {}
|
||||
~p3GxsTrans();
|
||||
mIngoingMutex("p3GxsTrans ingoing queue map mutex")
|
||||
{
|
||||
mLastMsgCleanup = time(NULL) - 60; // to be changed into 0
|
||||
mCleanupThread = NULL ;
|
||||
}
|
||||
|
||||
virtual ~p3GxsTrans();
|
||||
|
||||
/*!
|
||||
* \brief getStatistics
|
||||
* Gathers all sorts of statistics about the internals of p3GxsTrans, in order to display info about the running status,
|
||||
* message transport, etc.
|
||||
* \param stats This structure contains all statistics information.
|
||||
* \return true is the call succeeds.
|
||||
*/
|
||||
|
||||
virtual bool getStatistics(GxsTransStatistics& stats);
|
||||
|
||||
/**
|
||||
* Send an email to recipient, in the process author of the email is
|
||||
|
@ -97,7 +116,7 @@ struct p3GxsTrans : RsGenExchange, GxsTokenQueue, p3Config
|
|||
* This method is part of the public interface of this service.
|
||||
* @return true if the mail will be sent, false if not
|
||||
*/
|
||||
bool sendMail( RsGxsTransId& mailId,
|
||||
bool sendData( RsGxsTransId& mailId,
|
||||
GxsTransSubServices service,
|
||||
const RsGxsId& own_gxsid, const RsGxsId& recipient,
|
||||
const uint8_t* data, uint32_t size,
|
||||
|
@ -139,7 +158,10 @@ private:
|
|||
* signed acknowledged is received for each of them.
|
||||
* Two weeks seems fair ATM.
|
||||
*/
|
||||
const static uint32_t GXS_STORAGE_PERIOD = 0x127500;
|
||||
static const uint32_t GXS_STORAGE_PERIOD = 0x127500;
|
||||
static const uint32_t MAX_DELAY_BETWEEN_CLEANUPS = 1203; // every 20 mins. Could be less.
|
||||
|
||||
time_t mLastMsgCleanup ;
|
||||
|
||||
/// Define how the backend should handle authentication based on signatures
|
||||
static uint32_t AuthenPolicy();
|
||||
|
@ -251,5 +273,27 @@ private:
|
|||
uint32_t decrypted_data_size );
|
||||
|
||||
void notifyClientService(const OutgoingRecord& pr);
|
||||
|
||||
/*!
|
||||
* Checks the integrity message and groups
|
||||
*/
|
||||
class GxsTransIntegrityCleanupThread : public RsSingleJobThread
|
||||
{
|
||||
enum CheckState { CheckStart, CheckChecking };
|
||||
|
||||
public:
|
||||
GxsTransIntegrityCleanupThread(RsGeneralDataService *const dataService): mDs(dataService) {}
|
||||
|
||||
bool isDone();
|
||||
void run();
|
||||
|
||||
void getDeletedIds(std::list<RsGxsGroupId>& grpIds, std::map<RsGxsGroupId, std::vector<RsGxsMessageId> >& msgIds);
|
||||
|
||||
private:
|
||||
|
||||
RsGeneralDataService* const mDs;
|
||||
};
|
||||
|
||||
GxsTransIntegrityCleanupThread *mCleanupThread ;
|
||||
};
|
||||
|
||||
|
|
|
@ -23,41 +23,28 @@
|
|||
#include "serialiser/rsbaseserial.h"
|
||||
#include "serialiser/rstlvidset.h"
|
||||
#include "retroshare/rsgxsflags.h"
|
||||
#include "retroshare/rsgxstrans.h"
|
||||
#include "retroshare/rsgxscircles.h" // For: GXS_CIRCLE_TYPE_PUBLIC
|
||||
#include "services/p3idservice.h"
|
||||
#include "serialiser/rstypeserializer.h"
|
||||
|
||||
/// Subservices identifiers (like port for TCP)
|
||||
enum class GxsTransSubServices : uint16_t
|
||||
{
|
||||
UNKNOWN = 0,
|
||||
TEST_SERVICE = 1,
|
||||
P3_MSG_SERVICE = 2,
|
||||
P3_CHAT_SERVICE = 3
|
||||
};
|
||||
|
||||
/// Values must fit into uint8_t
|
||||
enum class GxsTransItemsSubtypes : uint8_t
|
||||
{
|
||||
GXS_TRANS_SUBTYPE_MAIL = 1,
|
||||
GXS_TRANS_SUBTYPE_RECEIPT = 2,
|
||||
GXS_TRANS_SUBTYPE_GROUP = 3,
|
||||
OUTGOING_RECORD_ITEM = 4
|
||||
};
|
||||
|
||||
typedef uint64_t RsGxsTransId;
|
||||
|
||||
struct RsNxsTransPresignedReceipt : RsNxsMsg
|
||||
class RsNxsTransPresignedReceipt : public RsNxsMsg
|
||||
{
|
||||
public:
|
||||
RsNxsTransPresignedReceipt() : RsNxsMsg(RS_SERVICE_TYPE_GXS_TRANS) {}
|
||||
|
||||
virtual ~RsNxsTransPresignedReceipt() {}
|
||||
};
|
||||
|
||||
struct RsGxsTransBaseItem : RsGxsMsgItem
|
||||
class RsGxsTransBaseItem : public RsGxsMsgItem
|
||||
{
|
||||
public:
|
||||
RsGxsTransBaseItem(GxsTransItemsSubtypes subtype) :
|
||||
RsGxsMsgItem( RS_SERVICE_TYPE_GXS_TRANS,
|
||||
static_cast<uint8_t>(subtype) ), mailId(0) {}
|
||||
|
||||
virtual ~RsGxsTransBaseItem() {}
|
||||
|
||||
RsGxsTransId mailId;
|
||||
|
||||
void inline clear()
|
||||
|
@ -71,10 +58,11 @@ struct RsGxsTransBaseItem : RsGxsMsgItem
|
|||
{ RS_REGISTER_SERIAL_MEMBER_TYPED(mailId, uint64_t); }
|
||||
};
|
||||
|
||||
struct RsGxsTransPresignedReceipt : RsGxsTransBaseItem
|
||||
class RsGxsTransPresignedReceipt : public RsGxsTransBaseItem
|
||||
{
|
||||
RsGxsTransPresignedReceipt() :
|
||||
RsGxsTransBaseItem(GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_RECEIPT) {}
|
||||
public:
|
||||
RsGxsTransPresignedReceipt() : RsGxsTransBaseItem(GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_RECEIPT) {}
|
||||
virtual ~RsGxsTransPresignedReceipt() {}
|
||||
};
|
||||
|
||||
enum class RsGxsTransEncryptionMode : uint8_t
|
||||
|
@ -84,12 +72,15 @@ enum class RsGxsTransEncryptionMode : uint8_t
|
|||
UNDEFINED_ENCRYPTION = 250
|
||||
};
|
||||
|
||||
struct RsGxsTransMailItem : RsGxsTransBaseItem
|
||||
class RsGxsTransMailItem : public RsGxsTransBaseItem
|
||||
{
|
||||
public:
|
||||
RsGxsTransMailItem() :
|
||||
RsGxsTransBaseItem(GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_MAIL),
|
||||
cryptoType(RsGxsTransEncryptionMode::UNDEFINED_ENCRYPTION) {}
|
||||
|
||||
virtual ~RsGxsTransMailItem() {}
|
||||
|
||||
RsGxsTransEncryptionMode cryptoType;
|
||||
|
||||
/**
|
||||
|
@ -166,8 +157,9 @@ struct RsGxsTransMailItem : RsGxsTransBaseItem
|
|||
const static uint32_t MAX_SIZE = 10*8*1024*1024;
|
||||
};
|
||||
|
||||
struct RsGxsTransGroupItem : RsGxsGrpItem
|
||||
class RsGxsTransGroupItem : public RsGxsGrpItem
|
||||
{
|
||||
public:
|
||||
RsGxsTransGroupItem() :
|
||||
RsGxsGrpItem( RS_SERVICE_TYPE_GXS_TRANS,
|
||||
static_cast<uint8_t>(
|
||||
|
@ -177,6 +169,7 @@ struct RsGxsTransGroupItem : RsGxsGrpItem
|
|||
meta.mGroupName = "Mail";
|
||||
meta.mCircleType = GXS_CIRCLE_TYPE_PUBLIC;
|
||||
}
|
||||
virtual ~RsGxsTransGroupItem() {}
|
||||
|
||||
// TODO: Talk with Cyril why there is no RsGxsGrpItem::serial_process
|
||||
virtual void serial_process(RsGenericSerializer::SerializeJob /*j*/,
|
||||
|
@ -188,33 +181,16 @@ struct RsGxsTransGroupItem : RsGxsGrpItem
|
|||
{ return out; }
|
||||
};
|
||||
|
||||
enum class GxsTransSendStatus : uint8_t
|
||||
{
|
||||
UNKNOWN = 0,
|
||||
PENDING_PROCESSING,
|
||||
PENDING_PREFERRED_GROUP,
|
||||
PENDING_RECEIPT_CREATE,
|
||||
PENDING_RECEIPT_SIGNATURE,
|
||||
PENDING_SERIALIZATION,
|
||||
PENDING_PAYLOAD_CREATE,
|
||||
PENDING_PAYLOAD_ENCRYPT,
|
||||
PENDING_PUBLISH,
|
||||
/** This will be useful so the user can know if the mail reached at least
|
||||
* some friend node, in case of internet connection interruption */
|
||||
//PENDING_TRANSFER,
|
||||
PENDING_RECEIPT_RECEIVE,
|
||||
/// Records with status >= RECEIPT_RECEIVED get deleted
|
||||
RECEIPT_RECEIVED,
|
||||
FAILED_RECEIPT_SIGNATURE = 240,
|
||||
FAILED_ENCRYPTION
|
||||
};
|
||||
|
||||
class RsGxsTransSerializer;
|
||||
struct OutgoingRecord : RsItem
|
||||
|
||||
class OutgoingRecord : public RsItem
|
||||
{
|
||||
public:
|
||||
OutgoingRecord( RsGxsId rec, GxsTransSubServices cs,
|
||||
const uint8_t* data, uint32_t size );
|
||||
|
||||
virtual ~OutgoingRecord() {}
|
||||
|
||||
GxsTransSendStatus status;
|
||||
RsGxsId recipient;
|
||||
/// Don't use a pointer would be invalid after publish
|
||||
|
@ -234,10 +210,11 @@ private:
|
|||
};
|
||||
|
||||
|
||||
struct RsGxsTransSerializer : public RsServiceSerializer
|
||||
class RsGxsTransSerializer : public RsServiceSerializer
|
||||
{
|
||||
public:
|
||||
RsGxsTransSerializer() : RsServiceSerializer(RS_SERVICE_TYPE_GXS_TRANS) {}
|
||||
~RsGxsTransSerializer() {}
|
||||
virtual ~RsGxsTransSerializer() {}
|
||||
|
||||
RsItem* create_item(uint16_t service_id, uint8_t item_sub_id) const
|
||||
{
|
||||
|
|
|
@ -1056,7 +1056,7 @@ bool p3GxsTunnelService::locked_sendDHPublicKey(const DH *dh,const RsGxsId& own_
|
|||
}
|
||||
|
||||
RsGxsTunnelDHPublicKeyItem *dhitem = new RsGxsTunnelDHPublicKeyItem ;
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
dhitem->public_key = BN_dup(dh->pub_key) ;
|
||||
#else
|
||||
const BIGNUM *pub_key=NULL ;
|
||||
|
@ -1140,7 +1140,7 @@ bool p3GxsTunnelService::locked_initDHSessionKey(DH *& dh)
|
|||
return false ;
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
BN_hex2bn(&dh->p,dh_prime_2048_hex.c_str()) ;
|
||||
BN_hex2bn(&dh->g,"5") ;
|
||||
#else
|
||||
|
|
|
@ -140,7 +140,6 @@ PUBLIC_HEADERS = retroshare/rsdisc.h \
|
|||
retroshare/rsversion.h \
|
||||
retroshare/rsservicecontrol.h \
|
||||
|
||||
|
||||
HEADERS += plugins/pluginmanager.h \
|
||||
plugins/dlfcn_win32.h \
|
||||
rsitems/rspluginitems.h \
|
||||
|
@ -429,6 +428,7 @@ HEADERS += pqi/authssl.h \
|
|||
pqi/pqissl.h \
|
||||
pqi/pqissllistener.h \
|
||||
pqi/pqisslpersongrp.h \
|
||||
pqi/pqissli2pbob.h \
|
||||
pqi/pqissludp.h \
|
||||
pqi/pqisslproxy.h \
|
||||
pqi/pqistore.h \
|
||||
|
@ -493,7 +493,9 @@ HEADERS += rsitems/rsitem.h \
|
|||
rsitems/rsgxsupdateitems.h \
|
||||
rsitems/rsserviceinfoitems.h \
|
||||
|
||||
HEADERS += services/p3msgservice.h \
|
||||
HEADERS += services/autoproxy/p3i2pbob.h \
|
||||
services/autoproxy/rsautoproxymonitor.h \
|
||||
services/p3msgservice.h \
|
||||
services/p3service.h \
|
||||
services/p3statusservice.h \
|
||||
services/p3banlist.h \
|
||||
|
@ -518,6 +520,9 @@ HEADERS += util/folderiterator.h \
|
|||
util/rsnet.h \
|
||||
util/extaddrfinder.h \
|
||||
util/dnsresolver.h \
|
||||
util/radix32.h \
|
||||
util/radix64.h \
|
||||
util/rsinitedptr.h \
|
||||
util/rsprint.h \
|
||||
util/rsstring.h \
|
||||
util/rsstd.h \
|
||||
|
@ -525,7 +530,6 @@ HEADERS += util/folderiterator.h \
|
|||
util/rsversioninfo.h \
|
||||
util/rswin.h \
|
||||
util/rsrandom.h \
|
||||
util/radix64.h \
|
||||
util/pugiconfig.h \
|
||||
util/rsmemcache.h \
|
||||
util/rstickevent.h \
|
||||
|
@ -580,6 +584,7 @@ SOURCES += pqi/authgpg.cc \
|
|||
pqi/pqissl.cc \
|
||||
pqi/pqissllistener.cc \
|
||||
pqi/pqisslpersongrp.cc \
|
||||
pqi/pqissli2pbob.cpp \
|
||||
pqi/pqissludp.cc \
|
||||
pqi/pqisslproxy.cc \
|
||||
pqi/pqistore.cc \
|
||||
|
@ -638,7 +643,9 @@ SOURCES += serialiser/rsbaseserial.cc \
|
|||
rsitems/rsgxsupdateitems.cc \
|
||||
rsitems/rsserviceinfoitems.cc \
|
||||
|
||||
SOURCES += services/p3msgservice.cc \
|
||||
SOURCES += services/autoproxy/rsautoproxymonitor.cc \
|
||||
services/autoproxy/p3i2pbob.cc \
|
||||
services/p3msgservice.cc \
|
||||
services/p3service.cc \
|
||||
services/p3statusservice.cc \
|
||||
services/p3banlist.cc \
|
||||
|
|
|
@ -245,7 +245,7 @@ sslcert::sslcert(X509 *x509, const RsPeerId& pid)
|
|||
{
|
||||
certificate = x509;
|
||||
id = pid;
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
name = getX509CNString(x509->cert_info->subject);
|
||||
org = getX509OrgString(x509->cert_info->subject);
|
||||
location = getX509LocString(x509->cert_info->subject);
|
||||
|
@ -377,7 +377,7 @@ static int initLib = 0;
|
|||
|
||||
if (dh)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
BN_hex2bn(&dh->p,dh_prime_4096_hex.c_str()) ;
|
||||
BN_hex2bn(&dh->g,"5") ;
|
||||
#else
|
||||
|
@ -599,7 +599,7 @@ bool AuthSSLimpl::SignData(const void *data, const uint32_t len, std::string &si
|
|||
|
||||
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
|
||||
unsigned int signlen = EVP_PKEY_size(mOwnPrivateKey);
|
||||
unsigned char signature[signlen];
|
||||
unsigned char signature[signlen] = { 0 };
|
||||
|
||||
if (0 == EVP_SignInit(mdctx, EVP_sha1()))
|
||||
{
|
||||
|
@ -795,7 +795,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
|
|||
// The code has been copied in order to use the PGP signing instead of supplying the
|
||||
// private EVP_KEY to ASN1_sign(), which would be another alternative.
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
int (*i2d)(X509_CINF*, unsigned char**) = i2d_X509_CINF;
|
||||
X509_ALGOR *algor1 = x509->cert_info->signature;
|
||||
X509_ALGOR *algor2 = x509->sig_alg;
|
||||
|
@ -824,7 +824,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
|
|||
/* FIX ALGORITHMS */
|
||||
|
||||
a = const_cast<X509_ALGOR*>(algor1);
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
ASN1_TYPE_free(a->parameter);
|
||||
a->parameter=ASN1_TYPE_new();
|
||||
a->parameter->type=V_ASN1_NULL;
|
||||
|
@ -836,7 +836,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
|
|||
#endif
|
||||
|
||||
a = const_cast<X509_ALGOR*>(algor2);
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
ASN1_TYPE_free(a->parameter);
|
||||
a->parameter=ASN1_TYPE_new();
|
||||
a->parameter->type=V_ASN1_NULL;
|
||||
|
@ -851,7 +851,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
|
|||
std::cerr << "Algorithms Fixed" << std::endl;
|
||||
|
||||
/* input buffer */
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
inl=i2d(data,NULL);
|
||||
buf_in=(unsigned char *)OPENSSL_malloc((unsigned int)inl);
|
||||
unsigned char *p=NULL;
|
||||
|
@ -874,7 +874,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
|
|||
}
|
||||
std::cerr << "Buffers Allocated" << std::endl;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
p=buf_in;
|
||||
i2d(data,&p);
|
||||
#endif
|
||||
|
@ -960,7 +960,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,uint32_t& diagnostic)
|
|||
}
|
||||
|
||||
/* extract CN for peer Id */
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
RsPgpId issuer(std::string(getX509CNString(x509->cert_info->issuer)));
|
||||
#else
|
||||
RsPgpId issuer(std::string(getX509CNString(X509_get_issuer_name(x509))));
|
||||
|
@ -979,7 +979,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,uint32_t& diagnostic)
|
|||
|
||||
/*** NOW The Manual signing bit (HACKED FROM asn1/a_sign.c) ***/
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
int (*i2d)(X509_CINF*, unsigned char**) = i2d_X509_CINF;
|
||||
ASN1_BIT_STRING *signature = x509->signature;
|
||||
X509_CINF *data = x509->cert_info;
|
||||
|
@ -1000,7 +1000,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,uint32_t& diagnostic)
|
|||
int sigoutl=0;
|
||||
|
||||
/* input buffer */
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
inl=i2d(data,NULL);
|
||||
buf_in=(unsigned char *)OPENSSL_malloc((unsigned int)inl);
|
||||
unsigned char *p=NULL;
|
||||
|
@ -1033,7 +1033,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,uint32_t& diagnostic)
|
|||
std::cerr << "Buffers Allocated" << std::endl;
|
||||
#endif
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
p=buf_in;
|
||||
i2d(data,&p);
|
||||
#endif
|
||||
|
@ -1157,7 +1157,7 @@ static int verify_x509_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
|||
|
||||
if(x509 != NULL)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
RsPgpId gpgid (std::string(getX509CNString(x509->cert_info->issuer)));
|
||||
#else
|
||||
RsPgpId gpgid (std::string(getX509CNString(X509_get_issuer_name(x509))));
|
||||
|
@ -1165,7 +1165,7 @@ static int verify_x509_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
|||
|
||||
if(gpgid.isNull())
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
std::cerr << "verify_x509_callback(): wrong PGP id \"" << std::string(getX509CNString(x509->cert_info->issuer)) << "\"" << std::endl;
|
||||
#else
|
||||
std::cerr << "verify_x509_callback(): wrong PGP id \"" << std::string(getX509CNString(X509_get_issuer_name(x509))) << "\"" << std::endl;
|
||||
|
@ -1173,7 +1173,7 @@ static int verify_x509_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
|||
return false ;
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
std::string sslcn = getX509CNString(x509->cert_info->subject);
|
||||
#else
|
||||
std::string sslcn = getX509CNString(X509_get_subject_name(x509));
|
||||
|
@ -1262,7 +1262,7 @@ int AuthSSLimpl::VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx)
|
|||
std::cerr << "(WW) Certificate was rejected because authentication failed. Diagnostic = " << auth_diagnostic << std::endl;
|
||||
return false;
|
||||
}
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
RsPgpId pgpid(std::string(getX509CNString(X509_STORE_CTX_get_current_cert(ctx)->cert_info->issuer)));
|
||||
#else
|
||||
RsPgpId pgpid(std::string(getX509CNString(X509_get_issuer_name(X509_STORE_CTX_get_current_cert(ctx)))));
|
||||
|
@ -1339,7 +1339,7 @@ bool AuthSSLimpl::encrypt(void *&out, int &outlen, const void *in, int inlen,
|
|||
#endif
|
||||
return false;
|
||||
} else {
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
public_key = mCerts[peerId]->certificate->cert_info->key->pkey;
|
||||
#else
|
||||
public_key = X509_get0_pubkey(mCerts[peerId]->certificate) ;
|
||||
|
@ -1586,20 +1586,26 @@ bool AuthSSLimpl::FailedCertificate(X509 *x509, const RsPgpId& gpgid,
|
|||
|
||||
switch(auth_diagnostic)
|
||||
{
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_MISSING: RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_MISSING_CERTIFICATE, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
break ;
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_NOT_VALID: RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_BAD_CERTIFICATE, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
break ;
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN: RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_UNKNOWN_IN , gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
break ;
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR: RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_INTERNAL_ERROR , gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
break ;
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE: RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_WRONG_SIGNATURE, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
break ;
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_OK:
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_UNKNOWN:
|
||||
default:
|
||||
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_CONNECT_ATTEMPT, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_MISSING:
|
||||
RsServer::notify()->notifyConnectionWithoutCert();
|
||||
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_MISSING_CERTIFICATE, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
break ;
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_NOT_VALID:
|
||||
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_BAD_CERTIFICATE, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
break ;
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN:
|
||||
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_UNKNOWN_IN , gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
break ;
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR:
|
||||
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_INTERNAL_ERROR , gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
break ;
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE:
|
||||
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_WRONG_SIGNATURE, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
break ;
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_OK:
|
||||
case RS_SSL_HANDSHAKE_DIAGNOSTIC_UNKNOWN:
|
||||
default:
|
||||
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_CONNECT_ATTEMPT, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
|
||||
}
|
||||
|
||||
#ifdef AUTHSSL_DEBUG
|
||||
|
|
|
@ -237,6 +237,7 @@ void p3Notify::notifyOwnStatusMessageChanged()
|
|||
void p3Notify::notifyDiskFull (uint32_t location , uint32_t size_limit_in_MB ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDiskFull (location,size_limit_in_MB) ; }
|
||||
void p3Notify::notifyPeerStatusChanged (const std::string& peer_id , uint32_t status ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerStatusChanged (peer_id,status) ; }
|
||||
void p3Notify::notifyGxsChange (const RsGxsChanges& changes) {FOR_ALL_NOTIFY_CLIENTS (*it)->notifyGxsChange(changes) ;}
|
||||
void p3Notify::notifyConnectionWithoutCert () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyConnectionWithoutCert(); }
|
||||
|
||||
void p3Notify::notifyPeerStatusChangedSummary () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerStatusChangedSummary() ; }
|
||||
void p3Notify::notifyDiscInfoChanged () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDiscInfoChanged () ; }
|
||||
|
|
|
@ -112,6 +112,7 @@ class p3Notify: public RsNotify
|
|||
void notifyDiskFull (uint32_t /* location */, uint32_t /* size limit in MB */) ;
|
||||
void notifyPeerStatusChanged (const std::string& /* peer_id */, uint32_t /* status */) ;
|
||||
void notifyGxsChange (const RsGxsChanges& /* changes */);
|
||||
void notifyConnectionWithoutCert ();
|
||||
|
||||
void notifyPeerStatusChangedSummary () ;
|
||||
void notifyDiscInfoChanged () ;
|
||||
|
|
|
@ -521,12 +521,14 @@ int pqiperson::connect(uint32_t type, const sockaddr_storage &raddr,
|
|||
return 0;
|
||||
}
|
||||
|
||||
pqiconnect *pqi = it->second;
|
||||
|
||||
#ifdef PERSON_DEBUG
|
||||
std::cerr << "pqiperson::connect() resetting for new connection attempt" << std::endl;
|
||||
#endif
|
||||
|
||||
/* set the parameters */
|
||||
(it->second)->reset();
|
||||
pqi->reset();
|
||||
|
||||
#ifdef PERSON_DEBUG
|
||||
std::cerr << "pqiperson::connect() clearing rate cap" << std::endl;
|
||||
|
@ -538,22 +540,22 @@ int pqiperson::connect(uint32_t type, const sockaddr_storage &raddr,
|
|||
#endif
|
||||
|
||||
// These two are universal.
|
||||
(it->second)->connect_parameter(NET_PARAM_CONNECT_DELAY, delay);
|
||||
(it->second)->connect_parameter(NET_PARAM_CONNECT_TIMEOUT, timeout);
|
||||
pqi->connect_parameter(NET_PARAM_CONNECT_DELAY, delay);
|
||||
pqi->connect_parameter(NET_PARAM_CONNECT_TIMEOUT, timeout);
|
||||
|
||||
// these 5 are only used by UDP connections.
|
||||
(it->second)->connect_parameter(NET_PARAM_CONNECT_PERIOD, period);
|
||||
(it->second)->connect_parameter(NET_PARAM_CONNECT_FLAGS, flags);
|
||||
(it->second)->connect_parameter(NET_PARAM_CONNECT_BANDWIDTH, bandwidth);
|
||||
pqi->connect_parameter(NET_PARAM_CONNECT_PERIOD, period);
|
||||
pqi->connect_parameter(NET_PARAM_CONNECT_FLAGS, flags);
|
||||
pqi->connect_parameter(NET_PARAM_CONNECT_BANDWIDTH, bandwidth);
|
||||
|
||||
(it->second)->connect_additional_address(NET_PARAM_CONNECT_PROXY, proxyaddr);
|
||||
(it->second)->connect_additional_address(NET_PARAM_CONNECT_SOURCE, srcaddr);
|
||||
pqi->connect_additional_address(NET_PARAM_CONNECT_PROXY, proxyaddr);
|
||||
pqi->connect_additional_address(NET_PARAM_CONNECT_SOURCE, srcaddr);
|
||||
|
||||
// These are used by Proxy/Hidden
|
||||
(it->second)->connect_parameter(NET_PARAM_CONNECT_DOMAIN_ADDRESS, domain_addr);
|
||||
(it->second)->connect_parameter(NET_PARAM_CONNECT_REMOTE_PORT, domain_port);
|
||||
pqi->connect_parameter(NET_PARAM_CONNECT_DOMAIN_ADDRESS, domain_addr);
|
||||
pqi->connect_parameter(NET_PARAM_CONNECT_REMOTE_PORT, domain_port);
|
||||
|
||||
(it->second)->connect(raddr);
|
||||
pqi->connect(raddr);
|
||||
|
||||
// flag if we started a new connectionAttempt.
|
||||
inConnectAttempt = true;
|
||||
|
|
|
@ -361,7 +361,7 @@ void pqissl::getCryptoParams(RsPeerCryptoParams& params)
|
|||
|
||||
bool pqissl::actAsServer()
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
return (bool)ssl_connection->server;
|
||||
#else
|
||||
return (bool)SSL_is_server(ssl_connection);
|
||||
|
@ -1230,7 +1230,7 @@ int pqissl::Extract_Failed_SSL_Certificate()
|
|||
RsPeerId sslid ;
|
||||
getX509id(peercert, sslid) ;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
RsPgpId gpgid(getX509CNString(peercert->cert_info->issuer));
|
||||
std::string sslcn = getX509CNString(peercert->cert_info->subject);
|
||||
#else
|
||||
|
|
31
libretroshare/src/pqi/pqissli2pbob.cpp
Normal file
31
libretroshare/src/pqi/pqissli2pbob.cpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
#include "pqissli2pbob.h"
|
||||
|
||||
bool pqissli2pbob::connect_parameter(uint32_t type, const std::string &value)
|
||||
{
|
||||
if (type == NET_PARAM_CONNECT_DOMAIN_ADDRESS)
|
||||
{
|
||||
RS_STACK_MUTEX(mSslMtx);
|
||||
// a new line must be appended!
|
||||
mI2pAddr = value + '\n';
|
||||
return true;
|
||||
}
|
||||
|
||||
return pqissl::connect_parameter(type, value);
|
||||
}
|
||||
|
||||
int pqissli2pbob::Basic_Connection_Complete()
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((ret = pqissl::Basic_Connection_Complete()) != 1)
|
||||
{
|
||||
// basic connection not complete.
|
||||
return ret;
|
||||
}
|
||||
|
||||
// send addr. (new line is already appended)
|
||||
ret = send(sockfd, mI2pAddr.c_str(), mI2pAddr.length(), 0);
|
||||
if (ret != (int)mI2pAddr.length())
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
31
libretroshare/src/pqi/pqissli2pbob.h
Normal file
31
libretroshare/src/pqi/pqissli2pbob.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef PQISSLI2PBOB_H
|
||||
#define PQISSLI2PBOB_H
|
||||
|
||||
#include "pqi/pqissl.h"
|
||||
|
||||
/*
|
||||
* This class is a minimal varied version of pqissl to work with I2P BOB tunnels.
|
||||
* The only difference is that the [.b32].i2p addresses must be sent first.
|
||||
*
|
||||
* Everything else is untouched.
|
||||
*/
|
||||
|
||||
class pqissli2pbob : public pqissl
|
||||
{
|
||||
public:
|
||||
pqissli2pbob(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm)
|
||||
: pqissl(l, parent, lm) {}
|
||||
|
||||
// NetInterface interface
|
||||
public:
|
||||
bool connect_parameter(uint32_t type, const std::string &value);
|
||||
|
||||
// pqissl interface
|
||||
protected:
|
||||
int Basic_Connection_Complete();
|
||||
|
||||
private:
|
||||
std::string mI2pAddr;
|
||||
};
|
||||
|
||||
#endif // PQISSLI2PBOB_H
|
|
@ -493,7 +493,7 @@ int pqissllistenbase::continueSSL(IncomingSSLInfo& incoming_connexion_info, bool
|
|||
#endif
|
||||
if(x509 != NULL)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
incoming_connexion_info.gpgid = RsPgpId(std::string(getX509CNString(x509->cert_info->issuer)));
|
||||
incoming_connexion_info.sslcn = getX509CNString(x509->cert_info->subject);
|
||||
#else
|
||||
|
@ -892,7 +892,7 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info)
|
|||
AuthSSL::getAuthSSL()->CheckCertificate(newPeerId, peercert);
|
||||
|
||||
/* now need to get GPG id too */
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
RsPgpId pgpid(std::string(getX509CNString(peercert->cert_info->issuer)));
|
||||
#else
|
||||
RsPgpId pgpid(std::string(getX509CNString(X509_get_issuer_name(peercert))));
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
*/
|
||||
|
||||
#include "serialiser/rsserializer.h"
|
||||
#include "services/autoproxy/rsautoproxymonitor.h"
|
||||
#include "util/rsdebug.h"
|
||||
|
||||
#include "pqi/pqisslpersongrp.h"
|
||||
|
@ -49,6 +50,7 @@ static struct RsLog::logInfo pqipersongrpzoneInfo = {RsLog::Default, "pqipersong
|
|||
#endif
|
||||
|
||||
#include "pqi/pqisslproxy.h"
|
||||
#include "pqi/pqissli2pbob.h"
|
||||
|
||||
pqilistener * pqisslpersongrp::locked_createListener(const struct sockaddr_storage &laddr)
|
||||
{
|
||||
|
@ -76,29 +78,34 @@ pqiperson * pqisslpersongrp::locked_createPerson(const RsPeerId& id, pqilistener
|
|||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
pqisslproxy *pqis = new pqisslproxy((pqissllistener *) listener, pqip, mLinkMgr);
|
||||
|
||||
/* construct the serialiser ....
|
||||
* Needs:
|
||||
* * FileItem
|
||||
* * FileData
|
||||
* * ServiceGeneric
|
||||
*/
|
||||
// Use pqicI2PBOB for I2P
|
||||
pqiconnect *pqicSOCKSProxy, *pqicI2PBOB;
|
||||
{
|
||||
pqisslproxy *pqis = new pqisslproxy((pqissllistener *) listener, pqip, mLinkMgr);
|
||||
RsSerialiser *rss = new RsSerialiser();
|
||||
rss->addSerialType(new RsRawSerialiser());
|
||||
pqicSOCKSProxy = new pqiconnect(pqip, rss, pqis);
|
||||
}
|
||||
if (rsAutoProxyMonitor::instance()->isEnabled(autoProxyType::I2PBOB))
|
||||
{
|
||||
pqissli2pbob *pqis = new pqissli2pbob((pqissllistener *) listener, pqip, mLinkMgr);
|
||||
RsSerialiser *rss = new RsSerialiser();
|
||||
rss->addSerialType(new RsRawSerialiser());
|
||||
|
||||
pqicI2PBOB = new pqiconnect(pqip, rss, pqis);
|
||||
} else {
|
||||
pqicI2PBOB = pqicSOCKSProxy;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RsSerialiser *rss = new RsSerialiser();
|
||||
rss->addSerialType(new RsRawSerialiser());
|
||||
|
||||
pqiconnect *pqisc = new pqiconnect(pqip, rss, pqis);
|
||||
|
||||
/* first select type based on peer */
|
||||
uint32_t typePeer = mPeerMgr->getHiddenType(id);
|
||||
switch (typePeer) {
|
||||
case RS_HIDDEN_TYPE_TOR:
|
||||
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_TOR_TCP, pqisc);
|
||||
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_TOR_TCP, pqicSOCKSProxy);
|
||||
break;
|
||||
case RS_HIDDEN_TYPE_I2P:
|
||||
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_I2P_TCP, pqisc);
|
||||
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_I2P_TCP, pqicI2PBOB);
|
||||
break;
|
||||
default:
|
||||
/* peer is not a hidden one but we are */
|
||||
|
@ -106,7 +113,7 @@ pqiperson * pqisslpersongrp::locked_createPerson(const RsPeerId& id, pqilistener
|
|||
uint32_t typeOwn = mPeerMgr->getHiddenType(AuthSSL::getAuthSSL()->OwnId());
|
||||
switch (typeOwn) {
|
||||
case RS_HIDDEN_TYPE_I2P:
|
||||
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_I2P_TCP, pqisc);
|
||||
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_I2P_TCP, pqicI2PBOB);
|
||||
break;
|
||||
default:
|
||||
/* this case shouldn't happen! */
|
||||
|
@ -117,7 +124,7 @@ pqiperson * pqisslpersongrp::locked_createPerson(const RsPeerId& id, pqilistener
|
|||
std::cerr << " - hidden types: peer=" << typePeer << " own=" << typeOwn << std::endl;
|
||||
std::cerr << " --> falling back to Tor" << std::endl;
|
||||
case RS_HIDDEN_TYPE_TOR:
|
||||
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_TOR_TCP, pqisc);
|
||||
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_TOR_TCP, pqicSOCKSProxy);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ private:
|
|||
uint32_t mProxyState;
|
||||
|
||||
std::string mDomainAddress;
|
||||
uint16_t mRemotePort;
|
||||
uint16_t mRemotePort;
|
||||
};
|
||||
|
||||
#endif // MRK_PQI_SSL_PROXY_HEADER
|
||||
|
|
|
@ -602,7 +602,7 @@ bool getX509id(X509 *x509, RsPeerId& xid)
|
|||
}
|
||||
|
||||
// get the signature from the cert, and copy to the array.
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
ASN1_BIT_STRING *signature = x509->signature;
|
||||
#else
|
||||
const ASN1_BIT_STRING *signature = NULL ;
|
||||
|
@ -700,7 +700,7 @@ int LoadCheckX509(const char *cert_file, RsPgpId& issuerName, std::string &locat
|
|||
if (valid)
|
||||
{
|
||||
// extract the name.
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
issuerName = RsPgpId(std::string(getX509CNString(x509->cert_info->issuer)));
|
||||
location = getX509LocString(x509->cert_info->subject);
|
||||
#else
|
||||
|
|
|
@ -60,6 +60,8 @@ public:
|
|||
|
||||
public:
|
||||
RsMsgMetaData mMeta;
|
||||
|
||||
std::set<RsGxsMessageId> mOlderVersions ;
|
||||
std::string mMsg; // UTF8 encoded.
|
||||
|
||||
std::list<RsGxsFile> mFiles;
|
||||
|
|
103
libretroshare/src/retroshare/rsgxstrans.h
Normal file
103
libretroshare/src/retroshare/rsgxstrans.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
#pragma once
|
||||
|
||||
#include "retroshare/rstokenservice.h"
|
||||
#include "retroshare/rsgxsifacehelper.h"
|
||||
#include "retroshare/rsgxscommon.h"
|
||||
|
||||
/// Subservices identifiers (like port for TCP)
|
||||
enum class GxsTransSubServices : uint16_t
|
||||
{
|
||||
UNKNOWN = 0x00,
|
||||
TEST_SERVICE = 0x01,
|
||||
P3_MSG_SERVICE = 0x02,
|
||||
P3_CHAT_SERVICE = 0x03
|
||||
};
|
||||
|
||||
/// Values must fit into uint8_t
|
||||
enum class GxsTransItemsSubtypes : uint8_t
|
||||
{
|
||||
GXS_TRANS_SUBTYPE_MAIL = 0x01,
|
||||
GXS_TRANS_SUBTYPE_RECEIPT = 0x02,
|
||||
GXS_TRANS_SUBTYPE_GROUP = 0x03,
|
||||
OUTGOING_RECORD_ITEM = 0x04
|
||||
};
|
||||
|
||||
enum class GxsTransSendStatus : uint8_t
|
||||
{
|
||||
UNKNOWN = 0x00,
|
||||
PENDING_PROCESSING = 0x01,
|
||||
PENDING_PREFERRED_GROUP = 0x02,
|
||||
PENDING_RECEIPT_CREATE = 0x03,
|
||||
PENDING_RECEIPT_SIGNATURE = 0x04,
|
||||
PENDING_SERIALIZATION = 0x05,
|
||||
PENDING_PAYLOAD_CREATE = 0x06,
|
||||
PENDING_PAYLOAD_ENCRYPT = 0x07,
|
||||
PENDING_PUBLISH = 0x08,
|
||||
/** This will be useful so the user can know if the mail reached at least
|
||||
* some friend node, in case of internet connection interruption */
|
||||
//PENDING_TRANSFER,
|
||||
PENDING_RECEIPT_RECEIVE = 0x09,
|
||||
/// Records with status >= RECEIPT_RECEIVED get deleted
|
||||
RECEIPT_RECEIVED = 0x0a,
|
||||
FAILED_RECEIPT_SIGNATURE = 0xf0,
|
||||
FAILED_ENCRYPTION = 0xf1
|
||||
};
|
||||
|
||||
typedef uint64_t RsGxsTransId;
|
||||
|
||||
class RsGxsTransGroup
|
||||
{
|
||||
public:
|
||||
RsGroupMetaData mMeta;
|
||||
};
|
||||
|
||||
class RsGxsTransMsg
|
||||
{
|
||||
public:
|
||||
RsGxsTransMsg() : size(0),data(NULL) {}
|
||||
virtual ~RsGxsTransMsg() { free(data) ; }
|
||||
|
||||
public:
|
||||
RsMsgMetaData mMeta;
|
||||
|
||||
uint32_t size ;
|
||||
uint8_t *data ;
|
||||
};
|
||||
|
||||
struct RsGxsTransOutgoingRecord
|
||||
{
|
||||
GxsTransSendStatus status;
|
||||
RsGxsId recipient;
|
||||
RsGxsTransId trans_id;
|
||||
|
||||
GxsTransSubServices client_service;
|
||||
|
||||
uint32_t data_size ;
|
||||
Sha1CheckSum data_hash ;
|
||||
uint32_t send_TS ;
|
||||
RsGxsGroupId group_id ;
|
||||
};
|
||||
|
||||
class RsGxsTrans: public RsGxsIfaceHelper
|
||||
{
|
||||
public:
|
||||
class GxsTransStatistics
|
||||
{
|
||||
public:
|
||||
GxsTransStatistics() {}
|
||||
|
||||
RsGxsGroupId prefered_group_id ;
|
||||
std::vector<RsGxsTransOutgoingRecord> outgoing_records;
|
||||
};
|
||||
|
||||
RsGxsTrans(RsGxsIface *gxs) : RsGxsIfaceHelper(gxs) {}
|
||||
|
||||
virtual ~RsGxsTrans() {}
|
||||
|
||||
virtual bool getStatistics(GxsTransStatistics& stats)=0;
|
||||
|
||||
// virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsTransGroup> &groups) = 0;
|
||||
// virtual bool getPostData(const uint32_t &token, std::vector<RsGxsTransMsg> &posts) = 0;
|
||||
};
|
||||
|
||||
extern RsGxsTrans *rsGxsTrans ;
|
|
@ -78,7 +78,7 @@ class RsInit
|
|||
/*!
|
||||
* Setup Hidden Location;
|
||||
*/
|
||||
static bool SetHiddenLocation(const std::string& hiddenaddress, uint16_t port);
|
||||
static void SetHiddenLocation(const std::string& hiddenaddress, uint16_t port, bool useBob);
|
||||
|
||||
static bool LoadPassword(const std::string& passwd) ;
|
||||
|
||||
|
|
|
@ -228,6 +228,7 @@ class NotifyClient
|
|||
virtual void notifyDiskFull (uint32_t /* location */, uint32_t /* size limit in MB */) {}
|
||||
virtual void notifyPeerStatusChanged (const std::string& /* peer_id */, uint32_t /* status */) {}
|
||||
virtual void notifyGxsChange (const RsGxsChanges& /* changes */) {}
|
||||
virtual void notifyConnectionWithoutCert () {}
|
||||
|
||||
/* one or more peers has changed the states */
|
||||
virtual void notifyPeerStatusChangedSummary () {}
|
||||
|
|
|
@ -45,6 +45,8 @@ const int p3facemsgzone = 11453;
|
|||
// TO SHUTDOWN THREADS.
|
||||
#ifdef RS_ENABLE_GXS
|
||||
|
||||
#include "services/autoproxy/rsautoproxymonitor.h"
|
||||
|
||||
#include "services/p3idservice.h"
|
||||
#include "services/p3gxscircles.h"
|
||||
#include "services/p3wiki.h"
|
||||
|
@ -89,6 +91,8 @@ void RsServer::rsGlobalShutDown()
|
|||
|
||||
mNetMgr->shutdown(); /* Handles UPnP */
|
||||
|
||||
rsAutoProxyMonitor::instance()->stopAllRSShutdown();
|
||||
|
||||
fullstop() ;
|
||||
|
||||
// kill all registered service threads
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
|
||||
class p3heartbeat;
|
||||
class p3discovery2;
|
||||
class p3I2pBob;
|
||||
|
||||
/* GXS Classes - just declare the classes.
|
||||
so we don't have to totally recompile to switch */
|
||||
|
@ -129,7 +130,7 @@ class RsServer: public RsControl, public RsTickingThread
|
|||
* This function is responsible for ensuring Retroshare exits in a legal state:
|
||||
* i.e. releases all held resources and saves current configuration
|
||||
*/
|
||||
virtual void rsGlobalShutDown( );
|
||||
virtual void rsGlobalShutDown( );
|
||||
|
||||
/****************************************/
|
||||
|
||||
|
@ -164,6 +165,7 @@ class RsServer: public RsControl, public RsTickingThread
|
|||
p3ChatService *chatSrv;
|
||||
p3StatusService *mStatusSrv;
|
||||
p3GxsTunnelService *mGxsTunnels;
|
||||
p3I2pBob *mI2pBob;
|
||||
|
||||
// This list contains all threaded services. It will be used to shut them down properly.
|
||||
|
||||
|
|
|
@ -125,6 +125,8 @@ class RsInitConfig
|
|||
std::string hiddenNodeAddress;
|
||||
uint16_t hiddenNodePort;
|
||||
|
||||
bool hiddenNodeI2PBOB;
|
||||
|
||||
/* Logging */
|
||||
bool haveLogFile;
|
||||
bool outStderr;
|
||||
|
@ -794,13 +796,13 @@ void RsInit::setAutoLogin(bool autoLogin){
|
|||
}
|
||||
|
||||
/* Setup Hidden Location; */
|
||||
bool RsInit::SetHiddenLocation(const std::string& hiddenaddress, uint16_t port)
|
||||
void RsInit::SetHiddenLocation(const std::string& hiddenaddress, uint16_t port, bool useBob)
|
||||
{
|
||||
/* parse the bugger (todo) */
|
||||
rsInitConfig->hiddenNodeSet = true;
|
||||
rsInitConfig->hiddenNodeAddress = hiddenaddress;
|
||||
rsInitConfig->hiddenNodePort = port;
|
||||
return true;
|
||||
rsInitConfig->hiddenNodeI2PBOB = useBob;
|
||||
}
|
||||
|
||||
|
||||
|
@ -854,7 +856,10 @@ RsGRouter *rsGRouter = NULL ;
|
|||
#include "upnp/upnphandler_miniupnp.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#include "services/autoproxy/p3i2pbob.h"
|
||||
#include "services/autoproxy/rsautoproxymonitor.h"
|
||||
|
||||
#include "services/p3gxsreputation.h"
|
||||
#include "services/p3serviceinfo.h"
|
||||
#include "services/p3heartbeat.h"
|
||||
|
@ -1046,8 +1051,11 @@ int RsServer::StartupRetroShare()
|
|||
|
||||
mPeerMgr->setManagers(mLinkMgr, mNetMgr);
|
||||
mNetMgr->setManagers(mPeerMgr, mLinkMgr);
|
||||
|
||||
|
||||
|
||||
rsAutoProxyMonitor *autoProxy = rsAutoProxyMonitor::instance();
|
||||
mI2pBob = new p3I2pBob(mPeerMgr);
|
||||
autoProxy->addProxy(autoProxyType::I2PBOB, mI2pBob);
|
||||
|
||||
//load all the SSL certs as friends
|
||||
// std::list<std::string> sslIds;
|
||||
// AuthSSL::getAuthSSL()->getAuthenticatedList(sslIds);
|
||||
|
@ -1261,12 +1269,6 @@ int RsServer::StartupRetroShare()
|
|||
|
||||
rsFiles = ftserver;
|
||||
|
||||
|
||||
/* create Cache Services */
|
||||
std::string config_dir = rsAccounts->PathAccountDirectory();
|
||||
std::string localcachedir = config_dir + "/cache/local";
|
||||
std::string remotecachedir = config_dir + "/cache/remote";
|
||||
|
||||
std::vector<std::string> plugins_directories ;
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
@ -1694,6 +1696,7 @@ int RsServer::StartupRetroShare()
|
|||
//mConfigMgr->addConfiguration("photo.cfg", photo_ns);
|
||||
//mConfigMgr->addConfiguration("wire.cfg", wire_ns);
|
||||
#endif
|
||||
mConfigMgr->addConfiguration("I2PBOB.cfg", mI2pBob);
|
||||
|
||||
mPluginsManager->addConfigurations(mConfigMgr) ;
|
||||
|
||||
|
@ -1739,12 +1742,46 @@ int RsServer::StartupRetroShare()
|
|||
{
|
||||
mPeerMgr->setOwnNetworkMode(RS_NET_MODE_EXT);
|
||||
mPeerMgr->setOwnVisState(RS_VS_DISC_FULL, RS_VS_DHT_FULL);
|
||||
|
||||
}
|
||||
|
||||
if (rsInitConfig->hiddenNodeSet)
|
||||
{
|
||||
mPeerMgr->setupHiddenNode(rsInitConfig->hiddenNodeAddress, rsInitConfig->hiddenNodePort);
|
||||
std::cout << "RsServer::StartupRetroShare setting up hidden locations" << std::endl;
|
||||
|
||||
if (rsInitConfig->hiddenNodeI2PBOB) {
|
||||
std::cout << "RsServer::StartupRetroShare setting up BOB" << std::endl;
|
||||
|
||||
// we need a local port!
|
||||
mNetMgr->checkNetAddress();
|
||||
|
||||
// add i2p proxy
|
||||
// bob will use this address
|
||||
sockaddr_storage i2pInstance;
|
||||
sockaddr_storage_ipv4_aton(i2pInstance, rsInitConfig->hiddenNodeAddress.c_str());
|
||||
mPeerMgr->setProxyServerAddress(RS_HIDDEN_TYPE_I2P, i2pInstance);
|
||||
|
||||
std::string addr; // will be set by auto proxy service
|
||||
uint16_t port = rsInitConfig->hiddenNodePort; // unused by bob
|
||||
|
||||
bool r = autoProxy->initialSetup(autoProxyType::I2PBOB, addr, port);
|
||||
|
||||
if (r && !addr.empty()) {
|
||||
mPeerMgr->setupHiddenNode(addr, port);
|
||||
|
||||
// now enable bob
|
||||
bobSettings bs;
|
||||
autoProxy->taskSync(autoProxyType::I2PBOB, autoProxyTask::getSettings, &bs);
|
||||
bs.enableBob = true;
|
||||
autoProxy->taskSync(autoProxyType::I2PBOB, autoProxyTask::setSettings, &bs);
|
||||
} else {
|
||||
std::cerr << "RsServer::StartupRetroShare failed to receive keys" << std::endl;
|
||||
/// TODO add notify for failed bob setup
|
||||
}
|
||||
} else {
|
||||
mPeerMgr->setupHiddenNode(rsInitConfig->hiddenNodeAddress, rsInitConfig->hiddenNodePort);
|
||||
}
|
||||
|
||||
std::cout << "RsServer::StartupRetroShare hidden location set up" << std::endl;
|
||||
}
|
||||
else if (isHiddenNode)
|
||||
{
|
||||
|
@ -1753,15 +1790,27 @@ int RsServer::StartupRetroShare()
|
|||
|
||||
mNetMgr -> checkNetAddress();
|
||||
|
||||
if (rsInitConfig->hiddenNodeSet) {
|
||||
// newly created location
|
||||
// mNetMgr->checkNetAddress() will setup ports for us
|
||||
// trigger updates for auto proxy services
|
||||
std::vector<autoProxyType::autoProxyType_enum> types;
|
||||
|
||||
// i2p bob need to rebuild its command map
|
||||
types.push_back(autoProxyType::I2PBOB);
|
||||
|
||||
rsAutoProxyMonitor::taskSync(types, autoProxyTask::reloadConfig);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/* startup (stuff dependent on Ids/peers is after this point) */
|
||||
/**************************************************************************/
|
||||
|
||||
autoProxy->startAll();
|
||||
|
||||
pqih->init_listener();
|
||||
mNetMgr->addNetListener(pqih); /* add listener so we can reset all sockets later */
|
||||
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* load caches and secondary data */
|
||||
/**************************************************************************/
|
||||
|
@ -1788,8 +1837,10 @@ int RsServer::StartupRetroShare()
|
|||
/* Start up Threads */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifdef RS_ENABLE_GXS
|
||||
// auto proxy threads
|
||||
startServiceThread(mI2pBob, "I2P-BOB");
|
||||
|
||||
#ifdef RS_ENABLE_GXS
|
||||
// Must Set the GXS pointers before starting threads.
|
||||
rsIdentity = mGxsIdService;
|
||||
rsGxsCircles = mGxsCircles;
|
||||
|
@ -1799,6 +1850,8 @@ int RsServer::StartupRetroShare()
|
|||
rsPosted = mPosted;
|
||||
rsGxsForums = mGxsForums;
|
||||
rsGxsChannels = mGxsChannels;
|
||||
rsGxsTrans = mGxsTrans;
|
||||
|
||||
//rsPhoto = mPhoto;
|
||||
//rsWire = mWire;
|
||||
|
||||
|
|
1115
libretroshare/src/services/autoproxy/p3i2pbob.cc
Normal file
1115
libretroshare/src/services/autoproxy/p3i2pbob.cc
Normal file
File diff suppressed because it is too large
Load diff
250
libretroshare/src/services/autoproxy/p3i2pbob.h
Normal file
250
libretroshare/src/services/autoproxy/p3i2pbob.h
Normal file
|
@ -0,0 +1,250 @@
|
|||
#ifndef P3I2PBOB_H
|
||||
#define P3I2PBOB_H
|
||||
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#ifndef WINDOWS_SYS
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#include "services/autoproxy/rsautoproxymonitor.h"
|
||||
#include "util/rsthreads.h"
|
||||
#include "pqi/p3cfgmgr.h"
|
||||
|
||||
/*
|
||||
* This class implements I2P BOB (BASIC OPEN BRIDGE) communication to allow RS
|
||||
* to automatically remote control I2P to setup the needed tunnel.
|
||||
* BOB is a simple text-based interface: https://geti2p.net/en/docs/api/bob
|
||||
*
|
||||
* Note 1:
|
||||
* One tunnel is enough even for hidden locations since it can be used
|
||||
* bidirectional. (In contrast to what RS I2P users had to set up manually.)
|
||||
*
|
||||
* Note 2:
|
||||
* BOB tunnels are no SOCKS tunnel. Therefore pqissli2pbob implements a simplified
|
||||
* proxy specially for BOB tunnels.
|
||||
*
|
||||
* Note 3:
|
||||
* BOB needs a unique name as an ID for each tunnel.
|
||||
* We use 'RetroShare-' + 8 base32 characters.
|
||||
*
|
||||
* Design:
|
||||
* The service uses three state machines to manage its task:
|
||||
* int stateMachineBOB();
|
||||
* mBOBState
|
||||
* int stateMachineController();
|
||||
* mState
|
||||
* mTask
|
||||
*
|
||||
* stateMachineBOB:
|
||||
* This state machine manages the low level communication with BOB. It basically has a linked
|
||||
* list (currently a implemented as a std::map) that contains a command and the next
|
||||
* state.
|
||||
* Each high level operation (start up / shut down / get keys) is represented by a
|
||||
* chain of states. E.g. the chain to retrieve new keys:
|
||||
* mCommands[bobState::setnickN] = {setnick, bobState::newkeysN};
|
||||
* mCommands[bobState::newkeysN] = {newkeys, bobState::getkeys};
|
||||
* mCommands[bobState::getkeys] = {getkeys, bobState::clear};
|
||||
* mCommands[bobState::clear] = {clear, bobState::quit};
|
||||
* mCommands[bobState::quit] = {quit, bobState::cleared};
|
||||
*
|
||||
* stateMachineController:
|
||||
* This state machone manages the high level tasks.
|
||||
* It is controlled by mState and mTask.
|
||||
*
|
||||
* mTast:
|
||||
* Tracks the high level operation (like start up).
|
||||
* It will keep its value even when a task is done to track
|
||||
* the requested BOB state.
|
||||
* When other operations are performed like a conection check
|
||||
* the last task gets backed up and is later restored again
|
||||
*
|
||||
* mState:
|
||||
* This state lives only for one operation an manages the communication
|
||||
* with the BOB instance. This is basically connecting, starting BOB
|
||||
* protocol and disconnecting
|
||||
*
|
||||
* How a task looks like:
|
||||
* 1) RS sets task using the ticket system
|
||||
* 2) stateMachineController connects to BOBs control port, sets mBobState to a lists head
|
||||
* 3) stateMachineBOB processes command chain
|
||||
* 4) stateMachineBOB is done and sets mBobState to cleared signaling that the connection
|
||||
* is cleared and can be closed
|
||||
* 5) stateMachineController disconnects from BOBs control port and updates mState
|
||||
*/
|
||||
|
||||
///
|
||||
/// \brief The controllerState enum
|
||||
/// States for the controller to keep track of what he is currently doing
|
||||
enum controllerState {
|
||||
csIdel,
|
||||
csDoConnect,
|
||||
csConnected,
|
||||
csWaitForBob,
|
||||
csDoDisconnect,
|
||||
csDisconnected,
|
||||
csError
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief The controllerTask enum
|
||||
/// This state tracks the controllers tast (e.g. setup a BOB tunnel or shut down
|
||||
/// an existing one).
|
||||
enum controllerTask {
|
||||
ctIdle,
|
||||
ctRunSetUp,
|
||||
ctRunShutDown,
|
||||
ctRunGetKeys,
|
||||
ctRunCheck
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief The bobState enum
|
||||
/// One state for each message
|
||||
///
|
||||
enum bobState {
|
||||
bsCleared,
|
||||
bsSetnickC, // chain head for only client tunnel
|
||||
bsSetnickN, // chain head for getting new (server) keys
|
||||
bsSetnickS, // chain head for client and server tunnel
|
||||
bsGetnick,
|
||||
bsNewkeysC, // part of chain for only client tunnel
|
||||
bsNewkeysN, // part of chain for getting new (server) keys
|
||||
bsGetkeys,
|
||||
bsSetkeys,
|
||||
bsInhost,
|
||||
bsOuthost,
|
||||
bsInport,
|
||||
bsOutport,
|
||||
bsInlength,
|
||||
bsOutlength,
|
||||
bsInvariance,
|
||||
bsOutvariance,
|
||||
bsInquantity,
|
||||
bsOutquantity,
|
||||
bsQuiet,
|
||||
bsStart,
|
||||
bsStop,
|
||||
bsClear,
|
||||
bsList, // chain head for 'list' command
|
||||
bsQuit
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief The bobStateInfo struct
|
||||
/// State machine with commands
|
||||
/// \todo This could be replaced by a linked list instead of a map
|
||||
struct bobStateInfo {
|
||||
std::string command;
|
||||
bobState nextState;
|
||||
};
|
||||
|
||||
struct bobSettings {
|
||||
bool enableBob; ///< This field is used by the pqi subsystem to determinine whether SOCKS proxy or BOB is used for I2P connections
|
||||
std::string keys; ///< (optional) server keys
|
||||
std::string addr; ///< (optional) hidden service addr. in base32 form
|
||||
|
||||
int8_t inLength;
|
||||
int8_t inQuantity;
|
||||
int8_t inVariance;
|
||||
|
||||
int8_t outLength;
|
||||
int8_t outQuantity;
|
||||
int8_t outVariance;
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief The bobStates struct
|
||||
/// This container struct is used to pass all states.
|
||||
/// Additionally, the tunnel name is included to to show it in the GUI.
|
||||
/// The advantage of a struct is that it can be forward declared.
|
||||
struct bobStates {
|
||||
bobState bs;
|
||||
controllerState cs;
|
||||
controllerTask ct;
|
||||
|
||||
std::string tunnelName;
|
||||
};
|
||||
|
||||
class p3PeerMgr;
|
||||
|
||||
class p3I2pBob : public RsTickingThread, public p3Config, public autoProxyService
|
||||
{
|
||||
public:
|
||||
p3I2pBob(p3PeerMgr *peerMgr);
|
||||
|
||||
// autoProxyService interface
|
||||
public:
|
||||
bool isEnabled();
|
||||
bool initialSetup(std::string &addr, uint16_t &);
|
||||
void processTaskAsync(taskTicket *ticket);
|
||||
void processTaskSync(taskTicket *ticket);
|
||||
|
||||
static std::string keyToBase32Addr(const std::string &key);
|
||||
|
||||
// RsTickingThread interface
|
||||
public:
|
||||
void data_tick();
|
||||
|
||||
private:
|
||||
int stateMachineBOB();
|
||||
int stateMachineBOB_locked_failure(const std::string &answer, const bobStateInfo ¤tState);
|
||||
|
||||
int stateMachineController();
|
||||
int stateMachineController_locked_idle();
|
||||
int stateMachineController_locked_connected();
|
||||
int stateMachineController_locked_disconnected();
|
||||
int stateMachineController_locked_error();
|
||||
|
||||
// p3Config interface
|
||||
protected:
|
||||
RsSerialiser *setupSerialiser();
|
||||
bool saveList(bool &cleanup, std::list<RsItem *> &lst);
|
||||
bool loadList(std::list<RsItem *> &load);
|
||||
|
||||
private:
|
||||
// helpers
|
||||
void getBOBSettings(bobSettings *settings);
|
||||
void setBOBSettings(const bobSettings *settings);
|
||||
void getStates(bobStates *bs);
|
||||
|
||||
std::string executeCommand(const std::string &command);
|
||||
bool connectI2P();
|
||||
bool disconnectI2P();
|
||||
|
||||
void finalizeSettings_locked();
|
||||
void updateSettings_locked();
|
||||
|
||||
std::string recv();
|
||||
|
||||
// states for state machines
|
||||
controllerState mState;
|
||||
controllerTask mTask;
|
||||
// used to store old state when in error state
|
||||
// mStateOld is also used as a flag when an error occured in BOB protocol
|
||||
controllerState mStateOld;
|
||||
// mTaskOld is used to keep the previous task (start up / shut down) when requesting keys or checking the connection
|
||||
controllerTask mTaskOld;
|
||||
bobSettings mSetting;
|
||||
bobState mBOBState;
|
||||
|
||||
// used variables
|
||||
p3PeerMgr *mPeerMgr;
|
||||
bool mConfigLoaded;
|
||||
int mSocket;
|
||||
time_t mLastProxyCheck;
|
||||
sockaddr_storage mI2PProxyAddr;
|
||||
std::map<bobState, bobStateInfo> mCommands;
|
||||
std::string mErrorMsg;
|
||||
std::string mTunnelName;
|
||||
|
||||
std::queue<taskTicket *> mPending;
|
||||
taskTicket *mProcessing;
|
||||
|
||||
// mutex
|
||||
RsMutex mLock;
|
||||
};
|
||||
|
||||
#endif // P3I2PBOB_H
|
303
libretroshare/src/services/autoproxy/rsautoproxymonitor.cc
Normal file
303
libretroshare/src/services/autoproxy/rsautoproxymonitor.cc
Normal file
|
@ -0,0 +1,303 @@
|
|||
#include "rsautoproxymonitor.h"
|
||||
|
||||
#include <unistd.h> /* for usleep() */
|
||||
|
||||
rsAutoProxyMonitor *rsAutoProxyMonitor::mInstance = NULL;
|
||||
|
||||
rsAutoProxyMonitor::rsAutoProxyMonitor()
|
||||
: mRSShutDown(false), mLock("rs auto proxy monitor")
|
||||
{
|
||||
mProxies.clear();
|
||||
}
|
||||
|
||||
rsAutoProxyMonitor *rsAutoProxyMonitor::instance()
|
||||
{
|
||||
if (mInstance == NULL)
|
||||
mInstance = new rsAutoProxyMonitor();
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::addProxy(autoProxyType::autoProxyType_enum type, autoProxyService *service)
|
||||
{
|
||||
RS_STACK_MUTEX(mLock);
|
||||
if (mProxies.find(type) != mProxies.end())
|
||||
std::cerr << "sAutoProxyMonitor::addProxy type " << type << " already added - OVERWRITING" << std::endl;
|
||||
|
||||
mProxies[type] = service;
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::startAll()
|
||||
{
|
||||
// create ticket
|
||||
taskTicket *tt = getTicket();
|
||||
tt->cb = this;
|
||||
tt->task = autoProxyTask::start;
|
||||
|
||||
{
|
||||
std::map<autoProxyType::autoProxyType_enum, autoProxyService*>::const_iterator it;
|
||||
|
||||
// fill types
|
||||
RS_STACK_MUTEX(mLock);
|
||||
for (it = mProxies.begin(); it != mProxies.end(); ++it)
|
||||
if (it->second->isEnabled())
|
||||
tt->types.push_back(it->first);
|
||||
}
|
||||
|
||||
task(tt);
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::stopAll()
|
||||
{
|
||||
// create ticket
|
||||
taskTicket *tt = getTicket();
|
||||
tt->cb = this;
|
||||
tt->task = autoProxyTask::stop;
|
||||
|
||||
{
|
||||
std::map<autoProxyType::autoProxyType_enum, autoProxyService*>::const_iterator it;
|
||||
|
||||
// fill types
|
||||
RS_STACK_MUTEX(mLock);
|
||||
for (it = mProxies.begin(); it != mProxies.end(); ++it)
|
||||
if (it->second->isEnabled())
|
||||
tt->types.push_back(it->first);
|
||||
}
|
||||
|
||||
task(tt);
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::stopAllRSShutdown()
|
||||
{
|
||||
{
|
||||
RS_STACK_MUTEX(mLock);
|
||||
mRSShutDown = true;
|
||||
|
||||
// remove disabled services
|
||||
std::vector<autoProxyType::autoProxyType_enum> toRemove;
|
||||
std::map<autoProxyType::autoProxyType_enum, autoProxyService*>::const_iterator it;
|
||||
for (it = mProxies.begin(); it != mProxies.end(); ++it) {
|
||||
if (!it->second->isEnabled()) {
|
||||
toRemove.push_back(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<autoProxyType::autoProxyType_enum>::const_iterator it2;
|
||||
for (it2 = toRemove.begin(); it2 != toRemove.end(); ++it2) {
|
||||
mProxies.erase(*it2);
|
||||
}
|
||||
}
|
||||
|
||||
// stop all remaining
|
||||
stopAll();
|
||||
|
||||
// wait for shutdown of all services
|
||||
uint32_t t = 0, timeout = 15;
|
||||
do {
|
||||
usleep(1000 * 1000);
|
||||
RS_STACK_MUTEX(mLock);
|
||||
std::cout << "(II) waiting for auto proxy service(s) to shut down " << t << "/" << timeout << " (remaining: " << mProxies.size() << ")" << std::endl;
|
||||
if (mProxies.empty())
|
||||
break;
|
||||
t++;
|
||||
} while (t < timeout );
|
||||
}
|
||||
|
||||
bool rsAutoProxyMonitor::isEnabled(autoProxyType::autoProxyType_enum t)
|
||||
{
|
||||
autoProxyService *s = lookUpService(t);
|
||||
if (s == NULL)
|
||||
return false;
|
||||
|
||||
return s->isEnabled();
|
||||
}
|
||||
|
||||
bool rsAutoProxyMonitor::initialSetup(autoProxyType::autoProxyType_enum t, std::string &addr, uint16_t &port)
|
||||
{
|
||||
autoProxyService *s = lookUpService(t);
|
||||
if (s == NULL)
|
||||
return false;
|
||||
|
||||
return s->initialSetup(addr, port);
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::task(taskTicket *ticket)
|
||||
{
|
||||
// sanity checks
|
||||
if (!ticket->async && ticket->types.size() > 1) {
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::task synchronous call to multiple services. This can cause problems!" << std::endl;
|
||||
}
|
||||
if (ticket->async && !ticket->cb && ticket->data) {
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::task asynchronous call with data but no callback. This will likely causes memory leak!" << std::endl;
|
||||
}
|
||||
if (ticket->types.size() > 1 && ticket->data) {
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::task call with data to multiple services. This will likely causes memory leak!" << std::endl;
|
||||
}
|
||||
|
||||
std::vector<autoProxyType::autoProxyType_enum>::const_iterator it;
|
||||
|
||||
for (it = ticket->types.begin(); it != ticket->types.end(); ++it) {
|
||||
autoProxyService* s = lookUpService(*it);
|
||||
if (s == NULL)
|
||||
continue;
|
||||
|
||||
if (ticket->async) {
|
||||
// copy ticket
|
||||
taskTicket *tt = new taskTicket();
|
||||
*tt = *ticket;
|
||||
tt->types.clear();
|
||||
tt->types.push_back(*it);
|
||||
s->processTaskAsync(tt);
|
||||
} else {
|
||||
s->processTaskSync(ticket);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::taskAsync(autoProxyType::autoProxyType_enum type, autoProxyTask::autoProxyTask_enum task, autoProxyCallback *cb, void *data)
|
||||
{
|
||||
std::vector<autoProxyType::autoProxyType_enum> types;
|
||||
types.push_back(type);
|
||||
taskAsync(types, task, cb, data);
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::taskAsync(std::vector<autoProxyType::autoProxyType_enum> types, autoProxyTask::autoProxyTask_enum task, autoProxyCallback *cb, void *data)
|
||||
{
|
||||
if (!isAsyncTask(task)) {
|
||||
// Usually the services will reject this ticket.
|
||||
// Just print a warning - maybe there is some special case where this is a good idea.
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::taskAsync called with a synchronous task!" << std::endl;
|
||||
}
|
||||
|
||||
taskTicket *tt = getTicket();
|
||||
tt->task = task;
|
||||
tt->types = types;
|
||||
if (cb)
|
||||
tt->cb = cb;
|
||||
if (data)
|
||||
tt->data = data;
|
||||
|
||||
instance()->task(tt);
|
||||
// tickets were copied, clean up
|
||||
delete tt;
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::taskSync(autoProxyType::autoProxyType_enum type, autoProxyTask::autoProxyTask_enum task, void *data)
|
||||
{
|
||||
std::vector<autoProxyType::autoProxyType_enum> types;
|
||||
types.push_back(type);
|
||||
taskSync(types, task, data);
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::taskSync(std::vector<autoProxyType::autoProxyType_enum> types, autoProxyTask::autoProxyTask_enum task, void *data)
|
||||
{
|
||||
if (isAsyncTask(task)) {
|
||||
// Usually the services will reject this ticket.
|
||||
// Just print a warning - maybe there is some special case where this is a good idea.
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::taskSync called with an asynchronous task!" << std::endl;
|
||||
}
|
||||
|
||||
taskTicket *tt = getTicket();
|
||||
tt->async = false;
|
||||
tt->task = task;
|
||||
tt->types = types;
|
||||
if (data)
|
||||
tt->data = data;
|
||||
|
||||
instance()->task(tt);
|
||||
// call done, clean up
|
||||
delete tt;
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::taskError(taskTicket *t)
|
||||
{
|
||||
taskDone(t, autoProxyStatus::error);
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::taskDone(taskTicket *t, autoProxyStatus::autoProxyStatus_enum status)
|
||||
{
|
||||
bool cleanUp = false;
|
||||
|
||||
t->result = status;
|
||||
if (t->cb) {
|
||||
t->cb->taskFinished(t);
|
||||
if (t != NULL) {
|
||||
// callack did not clean up properly
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::taskFinish callback did not clean up!" << std::endl;
|
||||
cleanUp = true;
|
||||
}
|
||||
} else if (t->async){
|
||||
// async and no callback
|
||||
// we must take care of deleting
|
||||
cleanUp = true;
|
||||
if(t->data)
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::taskFinish async call with data attached but no callback set!" << std::endl;
|
||||
}
|
||||
|
||||
if (cleanUp) {
|
||||
if (t->data) {
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::taskFinish will try to delete void pointer!" << std::endl;
|
||||
#pragma GCC diagnostic ignored "-Wdelete-incomplete"
|
||||
delete t->data;
|
||||
#pragma GCC diagnostic pop
|
||||
t->data = NULL;
|
||||
}
|
||||
delete t;
|
||||
t = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
taskTicket *rsAutoProxyMonitor::getTicket()
|
||||
{
|
||||
taskTicket *tt = new taskTicket();
|
||||
tt->cb = NULL;
|
||||
tt->data = NULL;
|
||||
tt->async = true;
|
||||
tt->result = autoProxyStatus::undefined;
|
||||
return tt;
|
||||
}
|
||||
|
||||
void rsAutoProxyMonitor::taskFinished(taskTicket *&ticket)
|
||||
{
|
||||
{
|
||||
RS_STACK_MUTEX(mLock);
|
||||
if (mRSShutDown && ticket->task == autoProxyTask::stop) {
|
||||
mProxies.erase(ticket->types.front());
|
||||
}
|
||||
}
|
||||
|
||||
// clean up
|
||||
if (ticket->data) {
|
||||
std::cerr << "rsAutoProxyMonitor::taskFinished data set. Will try to delete void pointer" << std::endl;
|
||||
#pragma GCC diagnostic ignored "-Wdelete-incomplete"
|
||||
delete ticket->data;
|
||||
#pragma GCC diagnostic pop
|
||||
ticket->data = NULL;
|
||||
}
|
||||
delete ticket;
|
||||
ticket = NULL;
|
||||
}
|
||||
|
||||
autoProxyService *rsAutoProxyMonitor::lookUpService(autoProxyType::autoProxyType_enum t)
|
||||
{
|
||||
RS_STACK_MUTEX(mLock);
|
||||
std::map<autoProxyType::autoProxyType_enum, autoProxyService*>::const_iterator itService;
|
||||
if ((itService = mProxies.find(t)) != mProxies.end()) {
|
||||
return itService->second;
|
||||
}
|
||||
std::cerr << "sAutoProxyMonitor::lookUpService no service for type " << t << " found!" << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool rsAutoProxyMonitor::isAsyncTask(autoProxyTask::autoProxyTask_enum t)
|
||||
{
|
||||
switch (t) {
|
||||
case autoProxyTask::start:
|
||||
case autoProxyTask::stop:
|
||||
case autoProxyTask::receiveKey:
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
216
libretroshare/src/services/autoproxy/rsautoproxymonitor.h
Normal file
216
libretroshare/src/services/autoproxy/rsautoproxymonitor.h
Normal file
|
@ -0,0 +1,216 @@
|
|||
#ifndef RSAUTOPROXYMONITOR_H
|
||||
#define RSAUTOPROXYMONITOR_H
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <util/rsthreads.h>
|
||||
|
||||
class autoProxyCallback;
|
||||
|
||||
namespace autoProxyType {
|
||||
enum autoProxyType_enum {
|
||||
I2PBOB
|
||||
};
|
||||
}
|
||||
|
||||
namespace autoProxyTask {
|
||||
enum autoProxyTask_enum {
|
||||
/* async tasks */
|
||||
start, ///< start up proxy
|
||||
stop, ///< shut down proxy
|
||||
receiveKey, ///< renew proxy key (if any)
|
||||
proxyStatusCheck, ///< use to check if the proxy is still running
|
||||
/* sync tasks */
|
||||
status, ///< get status from auto proxy
|
||||
getSettings, ///< get setting from auto proxy
|
||||
setSettings, ///< set setting of auto proxy
|
||||
reloadConfig, ///< signal config reload/rebuild
|
||||
getErrorInfo ///< get error information from auto proxy
|
||||
};
|
||||
}
|
||||
|
||||
namespace autoProxyStatus {
|
||||
enum autoProxyStatus_enum {
|
||||
undefined, ///< undefined - usually not yet set
|
||||
disabled, ///< used when a task cannot be done (e.g. a disabled service cannot be startet or stopped)
|
||||
offline, ///< proxy is not set up
|
||||
online, ///< proxy is set up
|
||||
ok, ///< generic ok
|
||||
error ///< generic error
|
||||
};
|
||||
}
|
||||
|
||||
struct taskTicket {
|
||||
///
|
||||
/// \brief types auto proxy service types that should get the ticket
|
||||
///
|
||||
std::vector<autoProxyType::autoProxyType_enum> types;
|
||||
|
||||
///
|
||||
/// \brief task the task to satisfy
|
||||
///
|
||||
autoProxyTask::autoProxyTask_enum task;
|
||||
|
||||
///
|
||||
/// \brief cb (optional) callback that gets called once the task is done
|
||||
///
|
||||
autoProxyCallback *cb;
|
||||
|
||||
///
|
||||
/// \brief result (optional) result
|
||||
///
|
||||
autoProxyStatus::autoProxyStatus_enum result;
|
||||
|
||||
///
|
||||
/// \brief data (optional) service dependent data
|
||||
///
|
||||
/// Needs to be allocated and freed by caller!
|
||||
///
|
||||
void *data;
|
||||
|
||||
///
|
||||
/// \brief async is the call Asynchronous
|
||||
///
|
||||
/// Will create a copy of the ticket for each
|
||||
/// service and delete the original ticket.
|
||||
///
|
||||
bool async;
|
||||
};
|
||||
|
||||
class autoProxyCallback {
|
||||
public:
|
||||
///
|
||||
/// \brief taskFinished called when a task is finished
|
||||
/// \param ticket
|
||||
///
|
||||
/// Remove everything: ticket and attached data if any!
|
||||
///
|
||||
virtual void taskFinished(taskTicket *&ticket) = 0;
|
||||
};
|
||||
|
||||
class autoProxyService {
|
||||
public:
|
||||
///
|
||||
/// \brief isEnabled must be provided to directly get a result without going through the ticket system
|
||||
/// \return whether the auto proxy service is enabled or not
|
||||
///
|
||||
virtual bool isEnabled() = 0;
|
||||
|
||||
///
|
||||
/// \brief initialSetup used when creating a node
|
||||
/// \param addr new address for the hidden service
|
||||
/// \param port new port for the hidden service
|
||||
/// \return true on success
|
||||
///
|
||||
/// This function is used to do an initial setup when creating a new hidden node.
|
||||
/// Nothing has been set up at this point to the auto proxy service must take care
|
||||
/// of everything (e.g. starting (and stoping) of needed threads)
|
||||
///
|
||||
virtual bool initialSetup(std::string &addr, uint16_t &port) = 0;
|
||||
|
||||
///
|
||||
/// \brief processTaskAsync adds a ticket to the auto proxies task list
|
||||
/// \param ticket
|
||||
///
|
||||
/// Don't call the callback in this function as this can cause dead locks!
|
||||
///
|
||||
virtual void processTaskAsync(taskTicket *ticket) = 0;
|
||||
|
||||
///
|
||||
/// \brief processTaskSync taskTicket must be satisfied immediately
|
||||
/// \param ticket
|
||||
///
|
||||
virtual void processTaskSync(taskTicket *ticket) = 0;
|
||||
};
|
||||
|
||||
class rsAutoProxyMonitor : autoProxyCallback
|
||||
{
|
||||
public:
|
||||
static rsAutoProxyMonitor *instance();
|
||||
|
||||
///
|
||||
/// \brief addProxy adds a new auto proxy service to the monitor
|
||||
/// \param type type of the new auto proxy service
|
||||
/// \param service pointer to the service
|
||||
///
|
||||
void addProxy(autoProxyType::autoProxyType_enum type, autoProxyService *service);
|
||||
|
||||
// global functions
|
||||
void startAll();
|
||||
void stopAll();
|
||||
void stopAllRSShutdown();
|
||||
bool isEnabled(autoProxyType::autoProxyType_enum t);
|
||||
// use this when creating a new node
|
||||
bool initialSetup(autoProxyType::autoProxyType_enum t, std::string &addr, uint16_t &port);
|
||||
|
||||
///
|
||||
/// \brief task Sends a task to all requested services
|
||||
/// \param ticket Ticket containing required information
|
||||
///
|
||||
/// There are two kind of tasks: asyn and sync.
|
||||
/// All tasks that involve communication with the target program (e.g. I2P or Tor) are asynchronous.
|
||||
/// All other task are synchronous (e.g. getting settings)
|
||||
///
|
||||
///
|
||||
/// Synchronous:
|
||||
/// When you want to get the settings from a service you can call task() with a ticket only listing
|
||||
/// one service and data pointing to the service's settings class/struct. Set async to false so
|
||||
/// that the service gets your original ticket. Ther service will process the request (get settings)
|
||||
/// immediately and when the call to task() is done you can access the settings from your ticket.
|
||||
///
|
||||
/// When additionally a call back is set the service will also call it. This can cause deadlocks!
|
||||
///
|
||||
///
|
||||
/// Asynchronous:
|
||||
/// When you want to start up all services or request new keys for all services you can call task() with a list
|
||||
/// of services and set async to true. When each service has fullfilled the resquest he will
|
||||
/// use the callback. The original caller ticket will be copied and each call to the callback
|
||||
/// will use its copy of the original ticket. The attached data is not copied so each service gets
|
||||
/// the same pointer!
|
||||
///
|
||||
///
|
||||
/// Note:
|
||||
/// Services should not delet or allocate anything unless no call back is provided and it is an
|
||||
/// async call. In that case the service should delete the ticket and the attacked data.
|
||||
/// Otherwise the caller must take care of cleaning up.
|
||||
/// This class provides two wrappers to take care of this that should be used: taskError and taskDone
|
||||
///
|
||||
/// Note2:
|
||||
/// This function is private so that each user must use the wrappers taskAsync and taskSync that include
|
||||
/// more sanity checks
|
||||
///
|
||||
private:
|
||||
void task(taskTicket *ticket);
|
||||
|
||||
public:
|
||||
static void taskAsync(autoProxyType::autoProxyType_enum type, autoProxyTask::autoProxyTask_enum task, autoProxyCallback *cb = NULL, void *data = NULL);
|
||||
static void taskAsync(std::vector<autoProxyType::autoProxyType_enum> types, autoProxyTask::autoProxyTask_enum task, autoProxyCallback *cb = NULL, void *data = NULL);
|
||||
static void taskSync (autoProxyType::autoProxyType_enum type, autoProxyTask::autoProxyTask_enum task, void *data = NULL);
|
||||
static void taskSync (std::vector<autoProxyType::autoProxyType_enum> types, autoProxyTask::autoProxyTask_enum task, void *data = NULL);
|
||||
|
||||
// usefull helpers
|
||||
static void taskError(taskTicket *t);
|
||||
static void taskDone(taskTicket *t, autoProxyStatus::autoProxyStatus_enum status);
|
||||
static taskTicket *getTicket();
|
||||
|
||||
// autoProxyCallback interface
|
||||
public:
|
||||
void taskFinished(taskTicket *&ticket);
|
||||
|
||||
private:
|
||||
rsAutoProxyMonitor();
|
||||
|
||||
autoProxyService *lookUpService(autoProxyType::autoProxyType_enum t);
|
||||
static bool isAsyncTask(autoProxyTask::autoProxyTask_enum t);
|
||||
|
||||
std::map<autoProxyType::autoProxyType_enum, autoProxyService*> mProxies;
|
||||
bool mRSShutDown;
|
||||
RsMutex mLock;
|
||||
|
||||
static rsAutoProxyMonitor *mInstance;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // RSAUTOPROXYMONITOR_H
|
|
@ -2259,7 +2259,7 @@ void p3MsgService::sendDistantMsgItem(RsMsgItem *msgitem)
|
|||
msg_serialized_data, msg_serialized_rssize,
|
||||
signing_key_id, grouter_message_id );
|
||||
RsGxsTransId gxsMailId;
|
||||
mGxsTransServ.sendMail( gxsMailId, GxsTransSubServices::P3_MSG_SERVICE,
|
||||
mGxsTransServ.sendData( gxsMailId, GxsTransSubServices::P3_MSG_SERVICE,
|
||||
signing_key_id, destination_key_id,
|
||||
msg_serialized_data, msg_serialized_rssize );
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ static int clear_tou_socket_error(int s);
|
|||
|
||||
#include "tou.h"
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
//static void BIO_set_shutdown(BIO *a,int s) { a->shutdown=s; }
|
||||
|
||||
static int BIO_get_shutdown(BIO *a) { return a->shutdown; }
|
||||
|
|
50
libretroshare/src/util/radix32.h
Normal file
50
libretroshare/src/util/radix32.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
#ifndef RADIX32_H
|
||||
#define RADIX32_H
|
||||
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
|
||||
class Radix32
|
||||
{
|
||||
public:
|
||||
static std::string encode(const std::vector<uint8_t> &in) {
|
||||
return encode(in.data(), in.size());
|
||||
}
|
||||
|
||||
static std::string encode(const uint8_t *data, size_t len) {
|
||||
std::string out = "";
|
||||
|
||||
size_t pos = 1;
|
||||
uint8_t bits = 8, index;
|
||||
uint16_t tmp = data[0]; // need min. 16 bits here
|
||||
while (bits > 0 || pos < len) {
|
||||
if (bits < 5) {
|
||||
if (pos < len) {
|
||||
tmp <<= 8;
|
||||
tmp |= data[pos++] & 0xFF;
|
||||
bits += 8;
|
||||
} else { // last byte
|
||||
tmp <<= (5 - bits);
|
||||
bits = 5;
|
||||
}
|
||||
}
|
||||
|
||||
bits -= 5;
|
||||
index = (tmp >> bits) & 0x1F;
|
||||
out.push_back(bintoasc()[index]);
|
||||
}
|
||||
|
||||
// append padding
|
||||
while(out.length() % 4 != 0)
|
||||
out.push_back('=');
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
private:
|
||||
static const inline char *bintoasc() { static const char bta[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; return bta ; }
|
||||
};
|
||||
|
||||
#endif // RADIX32_H
|
|
@ -57,6 +57,10 @@
|
|||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#ifndef __GLIBC__
|
||||
#define canonicalize_file_name(p) realpath(p, NULL)
|
||||
#endif
|
||||
|
||||
/****
|
||||
* #define RSDIR_DEBUG 1
|
||||
****/
|
||||
|
|
|
@ -126,3 +126,24 @@ std::string RsUtil::HashId(const std::string &id, bool reverse)
|
|||
// out << std::setprecision(15) << getCurrentTS();
|
||||
// return out.str();
|
||||
//}
|
||||
|
||||
std::vector<uint8_t> RsUtil::BinToSha256(const std::vector<uint8_t> &in)
|
||||
{
|
||||
std::vector<uint8_t> out;
|
||||
|
||||
SHA256_CTX *sha_ctx = new SHA256_CTX;
|
||||
uint8_t sha_hash[SHA256_DIGEST_LENGTH] = {0};
|
||||
|
||||
SHA256_Init(sha_ctx);
|
||||
SHA256_Update(sha_ctx, in.data(), in.size());
|
||||
SHA256_Final(sha_hash, sha_ctx);
|
||||
|
||||
for(uint16_t i = 0; i < SHA256_DIGEST_LENGTH; i++)
|
||||
{
|
||||
out.push_back(sha_hash[i]);
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
delete sha_ctx;
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include <inttypes.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace RsUtil {
|
||||
|
||||
|
@ -38,6 +39,7 @@ std::string BinToHex(const char *arr, const uint32_t len);
|
|||
std::string BinToHex(const unsigned char *arr, const uint32_t len);
|
||||
std::string NumberToString(uint64_t n, bool hex=false);
|
||||
std::string HashId(const std::string &id, bool reverse = false);
|
||||
std::vector<uint8_t> BinToSha256(const std::vector<uint8_t> &in);
|
||||
|
||||
//std::string AccurateTimeString();
|
||||
|
||||
|
|
|
@ -508,7 +508,7 @@ bool RsRecogn::itemToRadix64(RsItem *item, std::string &radstr)
|
|||
|
||||
std::string RsRecogn::getRsaKeyId(RSA *pubkey)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
int len = BN_num_bytes(pubkey -> n);
|
||||
unsigned char tmp[len];
|
||||
BN_bn2bin(pubkey -> n, tmp);
|
||||
|
|
|
@ -61,6 +61,16 @@ int RS_pthread_setname_np(pthread_t __target_thread, const char *__buf) {
|
|||
#include <iostream>
|
||||
#endif
|
||||
|
||||
void RsThread::go()
|
||||
{
|
||||
mShouldStopSemaphore.set(0) ;
|
||||
mHasStoppedSemaphore.set(0) ;
|
||||
|
||||
runloop();
|
||||
|
||||
mHasStoppedSemaphore.set(1);
|
||||
mShouldStopSemaphore.set(0);
|
||||
}
|
||||
void *RsThread::rsthread_init(void* p)
|
||||
{
|
||||
RsThread *thread = (RsThread *) p;
|
||||
|
@ -76,7 +86,7 @@ void *RsThread::rsthread_init(void* p)
|
|||
std::cerr << "[Thread ID:" << std::hex << pthread_self() << std::dec << "] thread is started. Calling runloop()..." << std::endl;
|
||||
#endif
|
||||
|
||||
thread -> runloop();
|
||||
thread->go();
|
||||
return NULL;
|
||||
}
|
||||
RsThread::RsThread()
|
||||
|
@ -216,14 +226,11 @@ RsTickingThread::RsTickingThread()
|
|||
|
||||
void RsSingleJobThread::runloop()
|
||||
{
|
||||
mHasStoppedSemaphore.set(0) ;
|
||||
run() ;
|
||||
}
|
||||
|
||||
void RsTickingThread::runloop()
|
||||
{
|
||||
mHasStoppedSemaphore.set(0) ; // first time we are 100% the thread is actually running.
|
||||
|
||||
#ifdef DEBUG_THREADS
|
||||
THREAD_DEBUG << "RsTickingThread::runloop(). Setting stopped=0" << std::endl;
|
||||
#endif
|
||||
|
@ -235,7 +242,6 @@ void RsTickingThread::runloop()
|
|||
#ifdef DEBUG_THREADS
|
||||
THREAD_DEBUG << "pqithreadstreamer::runloop(): asked to stop. setting hasStopped=1, and returning. Thread ends." << std::endl;
|
||||
#endif
|
||||
mHasStoppedSemaphore.set(1);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
|
|
@ -263,6 +263,7 @@ class RsThread
|
|||
|
||||
protected:
|
||||
virtual void runloop() =0; /* called once the thread is started. Should be overloaded by subclasses. */
|
||||
void go() ; // this one calls runloop and also sets the flags correctly when the thread is finished running.
|
||||
|
||||
RsSemaphore mHasStoppedSemaphore;
|
||||
RsSemaphore mShouldStopSemaphore;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#if !defined(WINDOWS_SYS) && !defined(__ANDROID__)
|
||||
#if defined(__linux__) && defined(__GLIBC__)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <execinfo.h>
|
||||
|
@ -110,13 +110,13 @@ static inline void print_stacktrace(FILE *out = stderr, unsigned int max_frames
|
|||
free(symbollist);
|
||||
}
|
||||
|
||||
#else // !defined(WINDOWS_SYS) && !defined(__ANDROID__)
|
||||
#else // defined(__linux__) && defined(__GLIBC__)
|
||||
static inline void print_stacktrace(FILE *out = stderr, unsigned int max_frames = 63)
|
||||
{
|
||||
(void) max_frames;
|
||||
|
||||
fprintf(out, "TODO: 2016/01/01 print_stacktrace not implemented yet for WINDOWS_SYS and ANDROID\n");
|
||||
}
|
||||
#endif // !defined(WINDOWS_SYS) && !defined(__ANDROID__)
|
||||
#endif // defined(__linux__) && defined(__GLIBC__)
|
||||
|
||||
#endif // _STACKTRACE_H_
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue