2012-02-13 13:22:35 -05:00
|
|
|
/*
|
|
|
|
* libretroshare/src/services p3idservice.cc
|
|
|
|
*
|
|
|
|
* Id interface for RetroShare.
|
|
|
|
*
|
|
|
|
* Copyright 2012-2012 by Robert Fernie.
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
2012-06-13 20:27:28 -04:00
|
|
|
* License Version 2.1 as published by the Free Software Foundation.
|
2012-02-13 13:22:35 -05:00
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
|
|
|
* USA.
|
|
|
|
*
|
|
|
|
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "services/p3idservice.h"
|
2012-10-21 11:48:18 -04:00
|
|
|
#include "serialiser/rsgxsiditems.h"
|
2012-02-13 13:22:35 -05:00
|
|
|
|
|
|
|
#include "util/rsrandom.h"
|
2012-11-05 17:28:08 -05:00
|
|
|
#include "util/rsstring.h"
|
|
|
|
|
|
|
|
#include "pqi/authgpg.h"
|
|
|
|
|
2012-02-13 13:22:35 -05:00
|
|
|
#include <retroshare/rspeers.h>
|
2012-10-21 11:48:18 -04:00
|
|
|
|
2012-02-13 13:22:35 -05:00
|
|
|
#include <sstream>
|
2012-07-30 07:35:26 -04:00
|
|
|
#include <stdio.h>
|
2012-02-13 13:22:35 -05:00
|
|
|
|
|
|
|
/****
|
|
|
|
* #define ID_DEBUG 1
|
|
|
|
****/
|
|
|
|
|
2012-06-07 13:10:47 -04:00
|
|
|
#define ID_REQUEST_LIST 0x0001
|
|
|
|
#define ID_REQUEST_IDENTITY 0x0002
|
|
|
|
#define ID_REQUEST_REPUTATION 0x0003
|
|
|
|
#define ID_REQUEST_OPINION 0x0004
|
|
|
|
|
2012-02-13 13:22:35 -05:00
|
|
|
RsIdentity *rsIdentity = NULL;
|
|
|
|
|
2012-10-22 16:36:28 -04:00
|
|
|
|
2012-11-05 17:28:08 -05:00
|
|
|
/******
|
|
|
|
* Some notes:
|
|
|
|
* Identity tasks:
|
|
|
|
* - Provide keys for signing / validating author signatures.
|
|
|
|
* - Reputations
|
|
|
|
* - Identify Known Friend's IDs.
|
|
|
|
* - Provide details to other services (nicknames, reputations, gpg ids, etc)
|
|
|
|
*
|
|
|
|
* Background services:
|
|
|
|
* - Lookup and cache keys / details of identities.
|
|
|
|
* - Check GPGHashes.
|
|
|
|
* - Calculate Reputations.
|
|
|
|
*
|
|
|
|
* We have a lot of information to store in Service Strings.
|
|
|
|
* - GPGId or last check ts.
|
|
|
|
* - Reputation stuff.
|
|
|
|
*/
|
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
#define RSGXSID_MAX_SERVICE_STRING 1024
|
2012-02-13 13:22:35 -05:00
|
|
|
|
2012-11-06 14:18:11 -05:00
|
|
|
#define BG_PGPHASH 1
|
|
|
|
#define BG_REPUTATION 2
|
|
|
|
|
2012-06-13 20:27:28 -04:00
|
|
|
/********************************************************************************/
|
|
|
|
/******************* Startup / Tick ******************************************/
|
|
|
|
/********************************************************************************/
|
|
|
|
|
2012-10-17 20:28:54 -04:00
|
|
|
p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *nes)
|
2012-11-01 20:45:50 -04:00
|
|
|
: RsGxsIdExchange(gds, nes, new RsGxsIdSerialiser(), RS_SERVICE_GXSV1_TYPE_GXSID), RsIdentity(this),
|
2012-10-17 20:28:54 -04:00
|
|
|
mIdMtx("p3IdService")
|
|
|
|
{
|
2012-11-03 07:57:27 -04:00
|
|
|
mCacheTest_LastTs = 0;
|
|
|
|
mCacheTest_Active = false;
|
2012-10-17 20:28:54 -04:00
|
|
|
|
2012-11-03 09:15:21 -04:00
|
|
|
mCacheLoad_LastCycle = 0;
|
|
|
|
mCacheLoad_Status = 0;
|
2012-11-06 14:18:11 -05:00
|
|
|
|
|
|
|
mHashPgp_SearchActive = false;
|
2012-11-07 16:38:43 -05:00
|
|
|
mHashPgp_LastTs = 0;
|
2012-11-06 14:18:11 -05:00
|
|
|
|
|
|
|
mBgSchedule_Mode = 0;
|
|
|
|
mBgSchedule_Active = false;
|
2012-10-17 20:28:54 -04:00
|
|
|
}
|
|
|
|
|
2012-10-28 19:13:15 -04:00
|
|
|
void p3IdService::service_tick()
|
2012-02-13 13:22:35 -05:00
|
|
|
{
|
2012-10-31 19:27:13 -04:00
|
|
|
//std::cerr << "p3IdService::service_tick()";
|
|
|
|
//std::cerr << std::endl;
|
2012-06-07 13:10:47 -04:00
|
|
|
|
2012-07-29 09:09:36 -04:00
|
|
|
// Disable for now.
|
|
|
|
// background_tick();
|
|
|
|
|
2012-11-01 20:45:50 -04:00
|
|
|
cache_tick();
|
|
|
|
|
|
|
|
// internal testing - request keys. (NOT FINISHED YET)
|
2012-11-03 07:57:27 -04:00
|
|
|
cachetest_tick();
|
2012-10-21 15:15:46 -04:00
|
|
|
|
2012-11-06 14:18:11 -05:00
|
|
|
// background stuff.
|
2012-11-07 16:38:43 -05:00
|
|
|
scheduling_tick();
|
2012-11-06 14:18:11 -05:00
|
|
|
|
2012-10-28 19:13:15 -04:00
|
|
|
return;
|
2012-02-13 13:22:35 -05:00
|
|
|
}
|
|
|
|
|
2012-10-28 19:13:15 -04:00
|
|
|
void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|
|
|
{
|
2012-11-01 20:45:50 -04:00
|
|
|
std::cerr << "p3IdService::notifyChanges()";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-10-28 19:13:15 -04:00
|
|
|
receiveChanges(changes);
|
|
|
|
}
|
2012-06-07 13:10:47 -04:00
|
|
|
|
2012-10-17 20:28:54 -04:00
|
|
|
/********************************************************************************/
|
|
|
|
/******************* RsIdentity Interface ***************************************/
|
|
|
|
/********************************************************************************/
|
2012-06-07 13:10:47 -04:00
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
bool p3IdService:: getNickname(const RsGxsId &id, std::string &nickname)
|
2012-06-07 13:10:47 -04:00
|
|
|
{
|
2012-10-17 20:28:54 -04:00
|
|
|
return false;
|
2012-06-07 13:10:47 -04:00
|
|
|
}
|
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
bool p3IdService:: getIdDetails(const RsGxsId &id, RsIdentityDetails &details)
|
2012-06-07 13:10:47 -04:00
|
|
|
{
|
2012-10-17 20:28:54 -04:00
|
|
|
return false;
|
2012-06-07 13:10:47 -04:00
|
|
|
}
|
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
bool p3IdService:: getOwnIds(std::list<RsGxsId> &ownIds)
|
2012-06-07 13:10:47 -04:00
|
|
|
{
|
2012-10-17 20:28:54 -04:00
|
|
|
return false;
|
2012-06-07 13:10:47 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-10-17 20:28:54 -04:00
|
|
|
//
|
|
|
|
bool p3IdService::submitOpinion(uint32_t& token, RsIdOpinion &opinion)
|
2012-06-07 13:10:47 -04:00
|
|
|
{
|
2012-10-17 20:28:54 -04:00
|
|
|
return false;
|
2012-06-13 20:27:28 -04:00
|
|
|
}
|
2012-06-07 13:10:47 -04:00
|
|
|
|
2012-10-17 20:28:54 -04:00
|
|
|
bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms)
|
2012-06-13 20:27:28 -04:00
|
|
|
{
|
2012-11-07 16:38:43 -05:00
|
|
|
|
|
|
|
RsGxsIdGroup id;
|
|
|
|
|
|
|
|
id.mMeta.mGroupName = params.nickname;
|
|
|
|
if (params.isPgpLinked)
|
|
|
|
{
|
|
|
|
id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
id.mMeta.mGroupFlags = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
createGroup(token, id);
|
|
|
|
return true;
|
2012-06-07 13:10:47 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-10-17 20:28:54 -04:00
|
|
|
/********************************************************************************/
|
|
|
|
/******************* RsGixs Interface ***************************************/
|
|
|
|
/********************************************************************************/
|
2012-06-07 13:10:47 -04:00
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
bool p3IdService::haveKey(const RsGxsId &id)
|
2012-06-13 20:27:28 -04:00
|
|
|
{
|
2012-11-03 10:07:26 -04:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
return mPublicKeyCache.is_cached(id);
|
2012-06-13 20:27:28 -04:00
|
|
|
}
|
2012-06-07 13:10:47 -04:00
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
bool p3IdService::havePrivateKey(const RsGxsId &id)
|
2012-06-13 20:27:28 -04:00
|
|
|
{
|
2012-11-03 10:07:26 -04:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
return mPrivateKeyCache.is_cached(id);
|
2012-06-07 13:10:47 -04:00
|
|
|
}
|
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
bool p3IdService::requestKey(const RsGxsId &id, const std::list<PeerId> &peers)
|
2012-07-06 19:14:18 -04:00
|
|
|
{
|
2012-11-03 10:07:26 -04:00
|
|
|
if (haveKey(id))
|
2012-10-22 16:36:28 -04:00
|
|
|
return true;
|
|
|
|
return cache_request_load(id);
|
2012-07-06 19:14:18 -04:00
|
|
|
}
|
2012-06-07 13:10:47 -04:00
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
int p3IdService::getKey(const RsGxsId &id, RsTlvSecurityKey &key)
|
2012-06-13 20:27:28 -04:00
|
|
|
{
|
2012-11-03 10:07:26 -04:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
2012-10-22 16:36:28 -04:00
|
|
|
RsGxsIdCache data;
|
2012-11-03 10:07:26 -04:00
|
|
|
if (mPublicKeyCache.fetch(id, data))
|
2012-10-22 16:36:28 -04:00
|
|
|
{
|
|
|
|
key = data.pubkey;
|
|
|
|
return 1;
|
|
|
|
}
|
2012-10-17 20:28:54 -04:00
|
|
|
return -1;
|
2012-07-06 19:14:18 -04:00
|
|
|
}
|
|
|
|
|
2012-11-03 07:57:27 -04:00
|
|
|
bool p3IdService::requestPrivateKey(const RsGxsId &id)
|
|
|
|
{
|
2012-11-03 10:07:26 -04:00
|
|
|
if (havePrivateKey(id))
|
|
|
|
return true;
|
|
|
|
return cache_request_load(id);
|
2012-11-03 07:57:27 -04:00
|
|
|
}
|
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
int p3IdService::getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key)
|
2012-07-06 19:14:18 -04:00
|
|
|
{
|
2012-11-03 10:07:26 -04:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
RsGxsIdCache data;
|
|
|
|
if (mPrivateKeyCache.fetch(id, data))
|
|
|
|
{
|
|
|
|
key = data.pubkey;
|
|
|
|
return 1;
|
|
|
|
}
|
2012-10-17 20:28:54 -04:00
|
|
|
return -1;
|
2012-06-13 20:27:28 -04:00
|
|
|
}
|
2012-06-07 13:10:47 -04:00
|
|
|
|
|
|
|
|
2012-10-17 20:28:54 -04:00
|
|
|
/********************************************************************************/
|
|
|
|
/******************* RsGixsReputation ***************************************/
|
|
|
|
/********************************************************************************/
|
2012-02-13 13:22:35 -05:00
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
bool p3IdService::getReputation(const RsGxsId &id, const GixsReputation &rep)
|
2012-06-13 20:27:28 -04:00
|
|
|
{
|
|
|
|
return false;
|
2012-02-13 13:22:35 -05:00
|
|
|
}
|
|
|
|
|
2012-06-07 13:10:47 -04:00
|
|
|
|
2012-10-17 20:28:54 -04:00
|
|
|
/********************************************************************************/
|
|
|
|
/******************* Get/Set Data ******************************************/
|
|
|
|
/********************************************************************************/
|
2012-02-13 13:22:35 -05:00
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
bool p3IdService::getGroupData(const uint32_t &token, std::vector<RsGxsIdGroup> &groups)
|
2012-06-13 20:27:28 -04:00
|
|
|
{
|
|
|
|
|
2012-10-17 20:28:54 -04:00
|
|
|
std::vector<RsGxsGrpItem*> grpData;
|
|
|
|
bool ok = RsGenExchange::getGroupData(token, grpData);
|
2012-06-13 20:27:28 -04:00
|
|
|
|
2012-10-17 20:28:54 -04:00
|
|
|
if(ok)
|
|
|
|
{
|
|
|
|
std::vector<RsGxsGrpItem*>::iterator vit = grpData.begin();
|
2012-07-06 19:14:18 -04:00
|
|
|
|
2012-10-17 20:28:54 -04:00
|
|
|
for(; vit != grpData.end(); vit++)
|
|
|
|
{
|
|
|
|
RsGxsIdGroupItem* item = dynamic_cast<RsGxsIdGroupItem*>(*vit);
|
2012-10-21 11:48:18 -04:00
|
|
|
RsGxsIdGroup group = item->group;
|
|
|
|
group.mMeta = item->meta;
|
2012-11-06 14:18:11 -05:00
|
|
|
|
|
|
|
// Decode information from serviceString.
|
|
|
|
SSGxsIdGroup ssdata;
|
|
|
|
if (ssdata.load(group.mMeta.mServiceString))
|
|
|
|
{
|
|
|
|
group.mPgpKnown = ssdata.pgp.idKnown;
|
|
|
|
group.mPgpId = ssdata.pgp.pgpId;
|
2012-11-07 16:38:43 -05:00
|
|
|
|
|
|
|
std::cerr << "p3IdService::getGroupData() Success decoding ServiceString";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
std::cerr << "\t mGpgKnown: " << group.mPgpKnown;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
std::cerr << "\t mGpgId: " << group.mPgpId;
|
|
|
|
std::cerr << std::endl;
|
2012-11-06 14:18:11 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
group.mPgpKnown = false;
|
|
|
|
group.mPgpId = "";
|
2012-11-07 16:38:43 -05:00
|
|
|
|
|
|
|
std::cerr << "p3IdService::getGroupData() Failed to decode ServiceString";
|
|
|
|
std::cerr << std::endl;
|
2012-11-06 14:18:11 -05:00
|
|
|
}
|
|
|
|
|
2012-10-17 20:28:54 -04:00
|
|
|
groups.push_back(group);
|
|
|
|
}
|
|
|
|
}
|
2012-06-13 20:27:28 -04:00
|
|
|
|
2012-10-17 20:28:54 -04:00
|
|
|
return ok;
|
2012-02-13 13:22:35 -05:00
|
|
|
}
|
|
|
|
|
2012-06-13 20:27:28 -04:00
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
bool p3IdService::getMsgData(const uint32_t &token, std::vector<RsGxsIdOpinion> &opinions)
|
2012-02-13 13:22:35 -05:00
|
|
|
{
|
2012-10-17 20:28:54 -04:00
|
|
|
GxsMsgDataMap msgData;
|
|
|
|
bool ok = RsGenExchange::getMsgData(token, msgData);
|
2012-02-13 13:22:35 -05:00
|
|
|
|
2012-10-17 20:28:54 -04:00
|
|
|
if(ok)
|
2012-02-13 13:22:35 -05:00
|
|
|
{
|
2012-10-17 20:28:54 -04:00
|
|
|
GxsMsgDataMap::iterator mit = msgData.begin();
|
|
|
|
|
|
|
|
for(; mit != msgData.end(); mit++)
|
|
|
|
{
|
|
|
|
RsGxsGroupId grpId = mit->first;
|
|
|
|
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
|
|
|
|
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
|
|
|
|
|
|
|
|
for(; vit != msgItems.end(); vit++)
|
|
|
|
{
|
2012-10-21 11:48:18 -04:00
|
|
|
RsGxsIdOpinionItem* item = dynamic_cast<RsGxsIdOpinionItem*>(*vit);
|
2012-10-17 20:28:54 -04:00
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
if (item)
|
2012-10-17 20:28:54 -04:00
|
|
|
{
|
2012-10-21 11:48:18 -04:00
|
|
|
RsGxsIdOpinion opinion = item->opinion;
|
|
|
|
opinion.mMeta = item->meta;
|
|
|
|
opinions.push_back(opinion);
|
2012-10-17 20:28:54 -04:00
|
|
|
delete item;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-10-21 11:48:18 -04:00
|
|
|
std::cerr << "Not a IdOpinion Item, deleting!" << std::endl;
|
2012-10-17 20:28:54 -04:00
|
|
|
delete *vit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-06-13 20:27:28 -04:00
|
|
|
}
|
2012-10-17 20:28:54 -04:00
|
|
|
return ok;
|
2012-06-13 20:27:28 -04:00
|
|
|
}
|
|
|
|
|
2012-10-17 20:28:54 -04:00
|
|
|
/********************************************************************************/
|
|
|
|
/********************************************************************************/
|
|
|
|
/********************************************************************************/
|
2012-06-13 20:27:28 -04:00
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
bool p3IdService::createGroup(uint32_t& token, RsGxsIdGroup &group)
|
2012-06-13 20:27:28 -04:00
|
|
|
{
|
2012-10-17 20:28:54 -04:00
|
|
|
RsGxsIdGroupItem* item = new RsGxsIdGroupItem();
|
|
|
|
item->group = group;
|
|
|
|
item->meta = group.mMeta;
|
|
|
|
RsGenExchange::publishGroup(token, item);
|
|
|
|
return true;
|
2012-06-13 20:27:28 -04:00
|
|
|
}
|
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
bool p3IdService::createMsg(uint32_t& token, RsGxsIdOpinion &opinion)
|
2012-06-13 20:27:28 -04:00
|
|
|
{
|
2012-10-21 11:48:18 -04:00
|
|
|
RsGxsIdOpinionItem* item = new RsGxsIdOpinionItem();
|
|
|
|
item->opinion = opinion;
|
|
|
|
item->meta = opinion.mMeta;
|
2012-10-17 20:28:54 -04:00
|
|
|
RsGenExchange::publishMsg(token, item);
|
|
|
|
return true;
|
2012-06-13 20:27:28 -04:00
|
|
|
}
|
|
|
|
|
2012-10-21 15:15:46 -04:00
|
|
|
/************************************************************************************/
|
|
|
|
/************************************************************************************/
|
|
|
|
/************************************************************************************/
|
|
|
|
|
2012-11-05 17:28:08 -05:00
|
|
|
/* Encoding / Decoding Group Service String stuff
|
|
|
|
*
|
|
|
|
* Pgp stuff.
|
|
|
|
*
|
|
|
|
* If flagged as pgp id....
|
|
|
|
* then we need to know if its been matched, or when we last tried to match.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool SSGxsIdPgp::load(const std::string &input)
|
|
|
|
{
|
|
|
|
char pgpline[RSGXSID_MAX_SERVICE_STRING];
|
|
|
|
int timestamp = 0;
|
|
|
|
if (1 == sscanf(input.c_str(), "K:1 I:%[^)]", pgpline))
|
|
|
|
{
|
|
|
|
idKnown = true;
|
|
|
|
pgpId = pgpline;
|
|
|
|
}
|
|
|
|
else if (1 == sscanf(input.c_str(), "K:0 T:%d", ×tamp))
|
|
|
|
{
|
|
|
|
lastCheckTs = timestamp;
|
|
|
|
idKnown = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string SSGxsIdPgp::save() const
|
|
|
|
{
|
|
|
|
std::string output;
|
|
|
|
if (idKnown)
|
|
|
|
{
|
|
|
|
output += "K:1 I:";
|
|
|
|
output += pgpId;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rs_sprintf(output, "K:0 T:%d", lastCheckTs);
|
|
|
|
}
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SSGxsIdScore::load(const std::string &input)
|
|
|
|
{
|
|
|
|
return (1 == sscanf(input.c_str(), "%d", &score));
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string SSGxsIdScore::save() const
|
|
|
|
{
|
|
|
|
std::string output;
|
|
|
|
rs_sprintf(output, "%d", score);
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SSGxsIdCumulator::load(const std::string &input)
|
|
|
|
{
|
|
|
|
return (4 == sscanf(input.c_str(), "%d %d %lf %lf", &count, &nullcount, &sum, &sumsq));
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string SSGxsIdCumulator::save() const
|
|
|
|
{
|
|
|
|
std::string output;
|
|
|
|
rs_sprintf(output, "%d %d %lf %lf", count, nullcount, sum, sumsq);
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SSGxsIdGroup::load(const std::string &input)
|
|
|
|
{
|
|
|
|
char pgpstr[RSGXSID_MAX_SERVICE_STRING];
|
|
|
|
char scorestr[RSGXSID_MAX_SERVICE_STRING];
|
|
|
|
char opinionstr[RSGXSID_MAX_SERVICE_STRING];
|
|
|
|
char repstr[RSGXSID_MAX_SERVICE_STRING];
|
|
|
|
|
|
|
|
// split into two parts.
|
2012-11-07 16:38:43 -05:00
|
|
|
if (4 != sscanf(input.c_str(), "v1 {P:%[^}]} {Y:%[^}]} {O:%[^}]} {R:%[^}]}", pgpstr, scorestr, opinionstr, repstr))
|
2012-11-05 17:28:08 -05:00
|
|
|
{
|
|
|
|
std::cerr << "SSGxsIdGroup::load() Failed to extract 4 Parts";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ok = true;
|
2012-11-07 16:38:43 -05:00
|
|
|
if (pgp.load(pgpstr))
|
2012-11-05 17:28:08 -05:00
|
|
|
{
|
|
|
|
std::cerr << "SSGxsIdGroup::load() pgpstr: " << pgpstr;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::cerr << "SSGxsIdGroup::load() Invalid pgpstr: " << pgpstr;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
ok = false;
|
|
|
|
}
|
|
|
|
|
2012-11-07 16:38:43 -05:00
|
|
|
if (score.load(scorestr))
|
2012-11-05 17:28:08 -05:00
|
|
|
{
|
|
|
|
std::cerr << "SSGxsIdGroup::load() scorestr: " << scorestr;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::cerr << "SSGxsIdGroup::load() Invalid scorestr: " << scorestr;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
ok = false;
|
|
|
|
}
|
|
|
|
|
2012-11-07 16:38:43 -05:00
|
|
|
if (opinion.load(opinionstr))
|
2012-11-05 17:28:08 -05:00
|
|
|
{
|
|
|
|
std::cerr << "SSGxsIdGroup::load() opinionstr: " << opinionstr;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::cerr << "SSGxsIdGroup::load() Invalid opinionstr: " << opinionstr;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
ok = false;
|
|
|
|
}
|
|
|
|
|
2012-11-07 16:38:43 -05:00
|
|
|
if (reputation.load(repstr))
|
2012-11-05 17:28:08 -05:00
|
|
|
{
|
|
|
|
std::cerr << "SSGxsIdGroup::load() repstr: " << repstr;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::cerr << "SSGxsIdGroup::load() Invalid repstr: " << repstr;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
ok = false;
|
|
|
|
}
|
|
|
|
|
2012-11-07 16:38:43 -05:00
|
|
|
std::cerr << "SSGxsIdGroup::load() regurgitated: " << save();
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
std::cerr << "SSGxsIdGroup::load() isOkay?: " << ok;
|
|
|
|
std::cerr << std::endl;
|
2012-11-05 17:28:08 -05:00
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string SSGxsIdGroup::save() const
|
|
|
|
{
|
|
|
|
std::string output = "v1 ";
|
|
|
|
|
|
|
|
output += "{P:";
|
|
|
|
output += pgp.save();
|
|
|
|
output += "}";
|
|
|
|
|
|
|
|
output += "{Y:";
|
|
|
|
output += score.save();
|
|
|
|
output += "}";
|
|
|
|
|
|
|
|
output += "{O:";
|
|
|
|
output += opinion.save();
|
|
|
|
output += "}";
|
|
|
|
|
|
|
|
output += "{R:";
|
|
|
|
output += reputation.save();
|
|
|
|
output += "}";
|
|
|
|
|
2012-11-07 16:38:43 -05:00
|
|
|
//std::cerr << "SSGxsIdGroup::save() output: " << output;
|
|
|
|
//std::cerr << std::endl;
|
2012-11-05 17:28:08 -05:00
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************************/
|
|
|
|
/************************************************************************************/
|
|
|
|
/************************************************************************************/
|
|
|
|
|
2012-10-21 15:15:46 -04:00
|
|
|
/* Cache of recently used keys
|
|
|
|
*
|
|
|
|
* It is expensive to fetch the keys, so we want to keep them around if possible.
|
|
|
|
* It only stores the immutable stuff.
|
|
|
|
*
|
|
|
|
* This is probably crude and crap to start with.
|
|
|
|
* Want Least Recently Used (LRU) discard policy, without having to search whole cache.
|
|
|
|
* Use two maps:
|
|
|
|
* - CacheMap[key] => data.
|
|
|
|
* - LRUMultiMap[AccessTS] => key
|
|
|
|
*
|
|
|
|
* NOTE: This could be moved to a seperate class and templated to make generic
|
|
|
|
* as it might be generally useful.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2012-10-22 16:36:28 -04:00
|
|
|
RsGxsIdCache::RsGxsIdCache()
|
|
|
|
:reputation(0), lastUsedTs(0)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-11-03 07:57:27 -04:00
|
|
|
RsGxsIdCache::RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvSecurityKey &in_pkey)
|
2012-10-22 16:36:28 -04:00
|
|
|
{
|
|
|
|
id = item->meta.mGroupId;
|
|
|
|
name = item->meta.mGroupName;
|
2012-11-03 07:57:27 -04:00
|
|
|
pubkey = in_pkey;
|
2012-10-22 16:36:28 -04:00
|
|
|
|
2012-11-01 20:45:50 -04:00
|
|
|
std::cerr << "RsGxsIdCache::RsGxsIdCache() for: " << id;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-10-22 16:36:28 -04:00
|
|
|
reputation = 0; /* TODO: extract from string - This will need to be refreshed!!! */
|
|
|
|
lastUsedTs = 0;
|
|
|
|
|
2012-11-03 07:57:27 -04:00
|
|
|
}
|
2012-10-22 16:36:28 -04:00
|
|
|
|
|
|
|
bool p3IdService::cache_store(const RsGxsIdGroupItem *item)
|
2012-10-21 15:15:46 -04:00
|
|
|
{
|
2012-11-01 20:45:50 -04:00
|
|
|
std::cerr << "p3IdService::cache_store() Item: ";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
//item->print(std::cerr, 0); NEEDS CONST!!!! TODO
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-11-03 07:57:27 -04:00
|
|
|
/* extract key from keys */
|
|
|
|
RsTlvSecurityKeySet keySet;
|
|
|
|
RsTlvSecurityKey pubkey;
|
2012-11-03 10:07:26 -04:00
|
|
|
RsTlvSecurityKey fullkey;
|
|
|
|
bool pub_key_ok = false;
|
|
|
|
bool full_key_ok = false;
|
2012-11-03 07:57:27 -04:00
|
|
|
|
2012-11-03 10:07:26 -04:00
|
|
|
RsGxsId id = item->meta.mGroupId;
|
|
|
|
if (!getGroupKeys(id, keySet))
|
2012-11-03 07:57:27 -04:00
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::cache_store() ERROR getting GroupKeys for: ";
|
|
|
|
std::cerr << item->meta.mGroupId;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::map<std::string, RsTlvSecurityKey>::iterator kit;
|
|
|
|
|
|
|
|
//std::cerr << "p3IdService::cache_store() KeySet is:";
|
|
|
|
//keySet.print(std::cerr, 10);
|
|
|
|
|
|
|
|
for (kit = keySet.keys.begin(); kit != keySet.keys.end(); kit++)
|
|
|
|
{
|
2012-11-03 10:07:26 -04:00
|
|
|
if (kit->second.keyFlags | RSTLV_KEY_DISTRIB_ADMIN)
|
2012-11-03 07:57:27 -04:00
|
|
|
{
|
2012-11-03 10:07:26 -04:00
|
|
|
std::cerr << "p3IdService::cache_store() Found Admin Key";
|
2012-11-03 07:57:27 -04:00
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-11-03 10:07:26 -04:00
|
|
|
/* save full key - if we have it */
|
|
|
|
if (kit->second.keyFlags | RSTLV_KEY_TYPE_FULL)
|
|
|
|
{
|
|
|
|
fullkey = kit->second;
|
|
|
|
full_key_ok = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* cache public key always */
|
2012-11-03 07:57:27 -04:00
|
|
|
pubkey = kit->second;
|
2012-11-03 10:07:26 -04:00
|
|
|
pub_key_ok = true;
|
2012-11-03 07:57:27 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-03 10:07:26 -04:00
|
|
|
if (!pub_key_ok)
|
2012-11-03 07:57:27 -04:00
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::cache_store() ERROR No Public Key Found";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-10-21 15:15:46 -04:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
|
|
|
|
// Create Cache Data.
|
2012-11-03 10:07:26 -04:00
|
|
|
RsGxsIdCache pubcache(item, pubkey);
|
|
|
|
mPublicKeyCache.store(id, pubcache);
|
2012-10-21 15:15:46 -04:00
|
|
|
|
2012-11-03 10:07:26 -04:00
|
|
|
if (full_key_ok)
|
2012-10-21 15:15:46 -04:00
|
|
|
{
|
2012-11-03 10:07:26 -04:00
|
|
|
RsGxsIdCache fullcache(item, fullkey);
|
|
|
|
mPrivateKeyCache.store(id, fullcache);
|
2012-10-21 15:15:46 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/***** BELOW LOADS THE CACHE FROM GXS DATASTORE *****/
|
|
|
|
|
|
|
|
#define MIN_CYCLE_GAP 2
|
|
|
|
|
|
|
|
int p3IdService::cache_tick()
|
|
|
|
{
|
2012-11-01 20:45:50 -04:00
|
|
|
//std::cerr << "p3IdService::cache_tick()";
|
|
|
|
//std::cerr << std::endl;
|
2012-10-21 15:15:46 -04:00
|
|
|
|
|
|
|
/* every minute - run a background check */
|
|
|
|
time_t now = time(NULL);
|
|
|
|
bool doCycle = false;
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
if (now - mCacheLoad_LastCycle > MIN_CYCLE_GAP)
|
|
|
|
{
|
|
|
|
doCycle = true;
|
|
|
|
mCacheLoad_LastCycle = now;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (doCycle)
|
|
|
|
{
|
|
|
|
cache_start_load();
|
|
|
|
}
|
|
|
|
|
|
|
|
cache_check_loading();
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool p3IdService::cache_request_load(const RsGxsId &id)
|
|
|
|
{
|
2012-11-01 20:45:50 -04:00
|
|
|
std::cerr << "p3IdService::cache_request_load(" << id << ")";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-10-21 15:15:46 -04:00
|
|
|
bool start = false;
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
|
|
|
|
mCacheLoad_ToCache.push_back(id);
|
|
|
|
|
|
|
|
if (time(NULL) - mCacheLoad_LastCycle > MIN_CYCLE_GAP)
|
|
|
|
{
|
|
|
|
start = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (start)
|
|
|
|
cache_start_load();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool p3IdService::cache_start_load()
|
|
|
|
{
|
|
|
|
/* trigger request to load missing ids into cache */
|
|
|
|
std::list<RsGxsGroupId> groupIds;
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
|
|
|
|
/* now we process the modGroupList -> a map so we can use it easily later, and create id list too */
|
|
|
|
std::list<RsGxsId>::iterator it;
|
|
|
|
for(it = mCacheLoad_ToCache.begin(); it != mCacheLoad_ToCache.end(); it++)
|
|
|
|
{
|
|
|
|
groupIds.push_back(*it); // might need conversion?
|
|
|
|
}
|
|
|
|
|
|
|
|
mCacheLoad_ToCache.clear();
|
|
|
|
}
|
|
|
|
|
2012-11-01 20:45:50 -04:00
|
|
|
if (groupIds.size() > 0)
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::cache_start_load() #Groups: " << groupIds.size();
|
|
|
|
std::cerr << std::endl;
|
2012-10-21 15:15:46 -04:00
|
|
|
|
2012-11-01 20:45:50 -04:00
|
|
|
mCacheLoad_LastCycle = time(NULL);
|
|
|
|
mCacheLoad_Status = 1;
|
2012-10-21 15:15:46 -04:00
|
|
|
|
2012-11-01 20:45:50 -04:00
|
|
|
uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA;
|
|
|
|
RsTokReqOptions opts;
|
|
|
|
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
|
|
|
|
uint32_t token = 0;
|
|
|
|
|
|
|
|
RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts, groupIds);
|
|
|
|
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
mCacheLoad_Tokens.push_back(token);
|
|
|
|
}
|
2012-10-21 15:15:46 -04:00
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool p3IdService::cache_check_loading()
|
|
|
|
{
|
|
|
|
/* check the status of all active tokens */
|
|
|
|
std::list<uint32_t> toload;
|
|
|
|
std::list<uint32_t>::iterator it;
|
2012-11-03 10:07:26 -04:00
|
|
|
|
|
|
|
bool stuffToLoad = false;
|
2012-10-21 15:15:46 -04:00
|
|
|
{
|
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
for(it = mCacheLoad_Tokens.begin(); it != mCacheLoad_Tokens.end();)
|
|
|
|
{
|
2012-11-01 20:45:50 -04:00
|
|
|
std::cerr << "p3IdService::cache_check_loading() token: " << *it;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-10-21 15:15:46 -04:00
|
|
|
uint32_t token = *it;
|
|
|
|
uint32_t status = RsGenExchange::getTokenService()->requestStatus(token);
|
|
|
|
//checkRequestStatus(token, status, reqtype, anstype, ts);
|
|
|
|
|
|
|
|
if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
|
|
|
{
|
|
|
|
it = mCacheLoad_Tokens.erase(it);
|
|
|
|
toload.push_back(token);
|
2012-11-03 10:07:26 -04:00
|
|
|
stuffToLoad = true;
|
2012-10-21 15:15:46 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
it++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-03 10:07:26 -04:00
|
|
|
if (stuffToLoad)
|
2012-10-21 15:15:46 -04:00
|
|
|
{
|
2012-11-03 10:07:26 -04:00
|
|
|
for(it = toload.begin(); it != toload.end(); it++)
|
|
|
|
{
|
|
|
|
cache_load_for_token(*it);
|
|
|
|
}
|
|
|
|
|
|
|
|
// cleanup.
|
|
|
|
mPrivateKeyCache.resize();
|
|
|
|
mPublicKeyCache.resize();
|
2012-10-21 15:15:46 -04:00
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
bool p3IdService::cache_load_for_token(uint32_t token)
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::cache_load_for_token() : " << token;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-10-22 16:36:28 -04:00
|
|
|
std::vector<RsGxsGrpItem*> grpData;
|
|
|
|
bool ok = RsGenExchange::getGroupData(token, grpData);
|
|
|
|
|
|
|
|
if(ok)
|
|
|
|
{
|
|
|
|
std::vector<RsGxsGrpItem*>::iterator vit = grpData.begin();
|
2012-10-21 15:15:46 -04:00
|
|
|
|
2012-10-22 16:36:28 -04:00
|
|
|
for(; vit != grpData.end(); vit++)
|
|
|
|
{
|
|
|
|
RsGxsIdGroupItem* item = dynamic_cast<RsGxsIdGroupItem*>(*vit);
|
|
|
|
|
|
|
|
std::cerr << "p3IdService::cache_load_for_token() Loaded Id with Meta: ";
|
|
|
|
std::cerr << item->meta;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
/* cache the data */
|
|
|
|
cache_store(item);
|
|
|
|
delete item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2012-10-21 15:15:46 -04:00
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::cache_load_for_token() ERROR no data";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-01 20:45:50 -04:00
|
|
|
/************************************************************************************/
|
|
|
|
/************************************************************************************/
|
|
|
|
|
2012-11-03 07:57:27 -04:00
|
|
|
#define TEST_PERIOD 60
|
|
|
|
|
2012-11-01 20:45:50 -04:00
|
|
|
bool p3IdService::cachetest_tick()
|
|
|
|
{
|
|
|
|
/* every minute - run a background check */
|
|
|
|
time_t now = time(NULL);
|
2012-11-03 07:57:27 -04:00
|
|
|
bool doTest = false;
|
2012-11-01 20:45:50 -04:00
|
|
|
{
|
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
if (now - mCacheTest_LastTs > TEST_PERIOD)
|
|
|
|
{
|
|
|
|
doTest = true;
|
|
|
|
mCacheTest_LastTs = now;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-03 07:57:27 -04:00
|
|
|
if (doTest)
|
2012-11-01 20:45:50 -04:00
|
|
|
{
|
2012-11-03 07:57:27 -04:00
|
|
|
std::cerr << "p3IdService::cachetest_tick() starting";
|
|
|
|
std::cerr << std::endl;
|
2012-11-01 20:45:50 -04:00
|
|
|
cachetest_getlist();
|
|
|
|
}
|
|
|
|
|
|
|
|
cachetest_request();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool p3IdService::cachetest_getlist()
|
|
|
|
{
|
2012-11-03 07:57:27 -04:00
|
|
|
|
2012-11-01 20:45:50 -04:00
|
|
|
{
|
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
if (mCacheTest_Active)
|
|
|
|
{
|
2012-11-03 07:57:27 -04:00
|
|
|
std::cerr << "p3IdService::cachetest_getlist() Already active";
|
|
|
|
std::cerr << std::endl;
|
2012-11-01 20:45:50 -04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-03 07:57:27 -04:00
|
|
|
std::cerr << "p3IdService::cachetest_getlist() making request";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-11-01 20:45:50 -04:00
|
|
|
uint32_t ansType = RS_TOKREQ_ANSTYPE_LIST;
|
|
|
|
RsTokReqOptions opts;
|
2012-11-03 07:57:27 -04:00
|
|
|
opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS;
|
2012-11-01 20:45:50 -04:00
|
|
|
uint32_t token = 0;
|
|
|
|
|
|
|
|
RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts);
|
|
|
|
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
mCacheTest_Token = token;
|
|
|
|
mCacheTest_Active = true;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool p3IdService::cachetest_request()
|
|
|
|
{
|
|
|
|
uint32_t token = 0;
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
if (!mCacheTest_Active)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
token = mCacheTest_Token;
|
|
|
|
}
|
|
|
|
|
2012-11-03 07:57:27 -04:00
|
|
|
std::cerr << "p3IdService::cachetest_request() checking request";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-11-01 20:45:50 -04:00
|
|
|
uint32_t status = RsGenExchange::getTokenService()->requestStatus(token);
|
|
|
|
|
|
|
|
if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
|
|
|
{
|
2012-11-03 07:57:27 -04:00
|
|
|
std::cerr << "p3IdService::cachetest_request() token ready: " << token;
|
2012-11-01 20:45:50 -04:00
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-11-03 07:57:27 -04:00
|
|
|
std::list<RsGxsId> grpIds;
|
2012-11-01 20:45:50 -04:00
|
|
|
bool ok = RsGenExchange::getGroupList(token, grpIds);
|
|
|
|
|
2012-11-03 07:57:27 -04:00
|
|
|
{
|
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
mCacheTest_Active = false;
|
|
|
|
}
|
|
|
|
|
2012-11-01 20:45:50 -04:00
|
|
|
if(ok)
|
|
|
|
{
|
2012-11-03 07:57:27 -04:00
|
|
|
std::list<RsGxsId>::iterator vit = grpIds.begin();
|
2012-11-01 20:45:50 -04:00
|
|
|
for(; vit != grpIds.end(); vit++)
|
|
|
|
{
|
|
|
|
/* 5% chance of checking it! */
|
2012-11-03 10:07:26 -04:00
|
|
|
if (RSRandom::random_f32() < 0.25)
|
2012-11-01 20:45:50 -04:00
|
|
|
{
|
2012-11-03 07:57:27 -04:00
|
|
|
std::cerr << "p3IdService::cachetest_request() Testing Id: " << *vit;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-11-01 20:45:50 -04:00
|
|
|
/* try the cache! */
|
|
|
|
if (!haveKey(*vit))
|
|
|
|
{
|
|
|
|
std::list<PeerId> nullpeers;
|
|
|
|
requestKey(*vit, nullpeers);
|
2012-11-03 07:57:27 -04:00
|
|
|
|
|
|
|
std::cerr << "p3IdService::cachetest_request() Requested Key Id: " << *vit;
|
|
|
|
std::cerr << std::endl;
|
2012-11-01 20:45:50 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
RsTlvSecurityKey seckey;
|
|
|
|
if (getKey(*vit, seckey))
|
|
|
|
{
|
2012-11-03 07:57:27 -04:00
|
|
|
std::cerr << "p3IdService::cachetest_request() Got Key OK Id: " << *vit;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-11-01 20:45:50 -04:00
|
|
|
// success!
|
2012-11-03 07:57:27 -04:00
|
|
|
seckey.print(std::cerr, 10);
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-11-01 20:45:50 -04:00
|
|
|
|
|
|
|
}
|
2012-11-03 07:57:27 -04:00
|
|
|
else
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::cachetest_request() ERROR no Key for Id: " << *vit;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
}
|
2012-11-01 20:45:50 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* try private key too! */
|
|
|
|
if (!havePrivateKey(*vit))
|
|
|
|
{
|
|
|
|
requestPrivateKey(*vit);
|
2012-11-03 07:57:27 -04:00
|
|
|
std::cerr << "p3IdService::cachetest_request() Requested PrivateKey Id: " << *vit;
|
|
|
|
std::cerr << std::endl;
|
2012-11-01 20:45:50 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
RsTlvSecurityKey seckey;
|
|
|
|
if (getPrivateKey(*vit, seckey))
|
|
|
|
{
|
|
|
|
// success!
|
2012-11-03 07:57:27 -04:00
|
|
|
std::cerr << "p3IdService::cachetest_request() Got PrivateKey OK Id: " << *vit;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::cachetest_request() ERROR no PrivateKey for Id: " << *vit;
|
|
|
|
std::cerr << std::endl;
|
2012-11-01 20:45:50 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::cache_load_for_token() ERROR no data";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-11-06 14:18:11 -05:00
|
|
|
/************************************************************************************/
|
|
|
|
/************************************************************************************/
|
|
|
|
/************************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We have two background tasks that use the ServiceString: PGPHash & Reputation.
|
|
|
|
*
|
|
|
|
* Only one task can be run at a time - otherwise potential overwrite issues.
|
|
|
|
* So this part coordinates that part of the code.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define ID_BACKGROUND_PERIOD 60
|
|
|
|
|
|
|
|
int p3IdService::scheduling_tick()
|
|
|
|
{
|
2012-11-07 16:38:43 -05:00
|
|
|
//std::cerr << "p3IdService::scheduling_tick()";
|
|
|
|
//std::cerr << std::endl;
|
2012-11-06 14:18:11 -05:00
|
|
|
|
|
|
|
/*** MUTEX TODO ***/
|
2012-11-07 16:38:43 -05:00
|
|
|
bool active;
|
|
|
|
uint32_t mode;
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
active = mBgSchedule_Active;
|
|
|
|
mode = mBgSchedule_Mode;
|
|
|
|
}
|
2012-11-06 14:18:11 -05:00
|
|
|
|
2012-11-07 16:38:43 -05:00
|
|
|
if (active)
|
2012-11-06 14:18:11 -05:00
|
|
|
{
|
|
|
|
bool done = false;
|
2012-11-07 16:38:43 -05:00
|
|
|
if (mode == BG_PGPHASH)
|
2012-11-06 14:18:11 -05:00
|
|
|
{
|
|
|
|
done = pgphash_continue();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
done = reputation_continue();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (done)
|
|
|
|
{
|
2012-11-07 16:38:43 -05:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
2012-11-06 14:18:11 -05:00
|
|
|
mBgSchedule_Active = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (pgphash_start())
|
|
|
|
{
|
2012-11-07 16:38:43 -05:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
2012-11-06 14:18:11 -05:00
|
|
|
mBgSchedule_Mode = BG_PGPHASH;
|
|
|
|
mBgSchedule_Active = true;
|
|
|
|
}
|
|
|
|
else if (reputation_start())
|
|
|
|
{
|
2012-11-07 16:38:43 -05:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
2012-11-06 14:18:11 -05:00
|
|
|
mBgSchedule_Mode = BG_REPUTATION;
|
|
|
|
mBgSchedule_Active = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-05 17:28:08 -05:00
|
|
|
/************************************************************************************/
|
|
|
|
/************************************************************************************/
|
|
|
|
/************************************************************************************/
|
|
|
|
|
|
|
|
/* Task to determine GPGHash matches
|
|
|
|
*
|
|
|
|
* Info to be stored in GroupServiceString + Cache.
|
|
|
|
*
|
|
|
|
* Actually - it must be a Signature here - otherwise, you could
|
|
|
|
* put in a hash from someone else!
|
|
|
|
*
|
|
|
|
* Don't think that we need to match very often - maybe once a day?
|
|
|
|
* Actually - we should scale the matching based on number of keys we have.
|
|
|
|
*
|
|
|
|
* imagine - 10^6 rsa keys + 10^3 gpg keys => 10^9 combinations.
|
|
|
|
* -- far too many to check all quickly.
|
|
|
|
*
|
|
|
|
* Need to grab and cache data we need... then check over slowly.
|
|
|
|
*
|
|
|
|
* maybe grab a list of all gpgids - that we know of: store id list.
|
|
|
|
* then big GroupRequest, and iterate through these.
|
|
|
|
**/
|
|
|
|
|
|
|
|
//const int SHA_DIGEST_LENGTH = 20;
|
|
|
|
|
|
|
|
typedef t_RsGenericIdType<SHA_DIGEST_LENGTH> GxsIdPgpHash;
|
|
|
|
|
|
|
|
static void calcPGPHash(const RsGxsId &id, const PGPFingerprintType &pgp, GxsIdPgpHash &hash);
|
|
|
|
|
|
|
|
|
|
|
|
void p3IdService::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet)
|
|
|
|
{
|
|
|
|
RsGxsIdGroupItem *item = dynamic_cast<RsGxsIdGroupItem *>(grpItem);
|
|
|
|
if (!item)
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::service_CreateGroup() ERROR invalid cast";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
return;
|
|
|
|
}
|
2012-11-07 16:38:43 -05:00
|
|
|
|
|
|
|
|
|
|
|
/********************* TEMP HACK UNTIL GXS FILLS IN GROUP_ID *****************/
|
|
|
|
// find private admin key
|
|
|
|
std::map<std::string, RsTlvSecurityKey>::iterator mit = keySet.keys.begin();
|
|
|
|
for(; mit != keySet.keys.end(); mit++)
|
|
|
|
{
|
|
|
|
RsTlvSecurityKey& pk = mit->second;
|
|
|
|
|
|
|
|
if(pk.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL))
|
|
|
|
{
|
|
|
|
item->group.mMeta.mGroupId = pk.keyId;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(mit == keySet.keys.end())
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::service_CreateGroup() ERROR no admin key";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/********************* TEMP HACK UNTIL GXS FILLS IN GROUP_ID *****************/
|
2012-11-05 17:28:08 -05:00
|
|
|
|
|
|
|
std::cerr << "p3IdService::service_CreateGroup() for : " << item->group.mMeta.mGroupId;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
if (item->group.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)
|
|
|
|
{
|
|
|
|
/* create the hash */
|
|
|
|
GxsIdPgpHash hash;
|
|
|
|
|
|
|
|
/* */
|
|
|
|
PGPFingerprintType ownFinger;
|
|
|
|
PGPIdType ownId(AuthGPG::getAuthGPG()->getGPGOwnId());
|
|
|
|
|
|
|
|
if (!AuthGPG::getAuthGPG()->getKeyFingerprint(ownId,ownFinger))
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::service_CreateGroup() ERROR Own Finger is stuck";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
return; // abandon attempt!
|
|
|
|
}
|
|
|
|
|
|
|
|
calcPGPHash(item->group.mMeta.mGroupId, ownFinger, hash);
|
|
|
|
item->group.mPgpIdHash = hash.toStdString();
|
|
|
|
|
|
|
|
/* do signature */
|
|
|
|
|
2012-11-06 14:18:11 -05:00
|
|
|
#if ENABLE_PGP_SIGNATURES
|
2012-11-05 17:28:08 -05:00
|
|
|
#define MAX_SIGN_SIZE 2048
|
|
|
|
uint8_t signarray[MAX_SIGN_SIZE];
|
|
|
|
unsigned int sign_size = MAX_SIGN_SIZE;
|
|
|
|
if (!AuthGPG::getAuthGPG()->SignDataBin((void *) hash.toByteArray(), hash.SIZE_IN_BYTES, signarray, &sign_size))
|
|
|
|
{
|
|
|
|
/* error */
|
|
|
|
std::cerr << "p3IdService::service_CreateGroup() ERROR Signing stuff";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* push binary into string -> really bad! */
|
|
|
|
item->group.mPgpIdSign = "";
|
|
|
|
for(unsigned int i = 0; i < sign_size; i++)
|
|
|
|
{
|
|
|
|
item->group.mPgpIdSign += signarray[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* done! */
|
2012-11-06 14:18:11 -05:00
|
|
|
#else
|
|
|
|
item->group.mPgpIdSign = "";
|
|
|
|
#endif
|
|
|
|
|
2012-11-05 17:28:08 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-06 14:18:11 -05:00
|
|
|
#define HASHPGP_PERIOD 180
|
2012-11-05 17:28:08 -05:00
|
|
|
|
|
|
|
|
2012-11-06 14:18:11 -05:00
|
|
|
bool p3IdService::pgphash_start()
|
2012-11-05 17:28:08 -05:00
|
|
|
{
|
|
|
|
/* every minute - run a background check */
|
|
|
|
time_t now = time(NULL);
|
|
|
|
bool doHash = false;
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
2012-11-06 14:18:11 -05:00
|
|
|
if (now - mHashPgp_LastTs > HASHPGP_PERIOD)
|
2012-11-05 17:28:08 -05:00
|
|
|
{
|
|
|
|
doHash = true;
|
|
|
|
mHashPgp_LastTs = now;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (doHash)
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::pgphash_tick() starting";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
pgphash_getlist();
|
2012-11-06 14:18:11 -05:00
|
|
|
return true;
|
2012-11-05 17:28:08 -05:00
|
|
|
}
|
2012-11-06 14:18:11 -05:00
|
|
|
return false;
|
|
|
|
}
|
2012-11-05 17:28:08 -05:00
|
|
|
|
|
|
|
|
2012-11-06 14:18:11 -05:00
|
|
|
bool p3IdService::pgphash_continue()
|
|
|
|
{
|
2012-11-07 16:38:43 -05:00
|
|
|
std::cerr << "p3IdService::pgphash_continue()";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
bool active;
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
active = mHashPgp_SearchActive;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (active)
|
2012-11-06 14:18:11 -05:00
|
|
|
{
|
|
|
|
pgphash_request();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return pgphash_process();
|
|
|
|
}
|
|
|
|
return false;
|
2012-11-05 17:28:08 -05:00
|
|
|
}
|
|
|
|
|
2012-11-06 14:18:11 -05:00
|
|
|
|
|
|
|
|
2012-11-05 17:28:08 -05:00
|
|
|
bool p3IdService::pgphash_getlist()
|
|
|
|
{
|
|
|
|
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
2012-11-06 14:18:11 -05:00
|
|
|
if (mHashPgp_SearchActive)
|
2012-11-05 17:28:08 -05:00
|
|
|
{
|
2012-11-07 16:38:43 -05:00
|
|
|
std::cerr << "p3IdService::pgphash_getlist() Already active";
|
2012-11-05 17:28:08 -05:00
|
|
|
std::cerr << std::endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-07 16:38:43 -05:00
|
|
|
std::cerr << "p3IdService::pgphash_getlist() making request";
|
2012-11-05 17:28:08 -05:00
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-11-07 16:38:43 -05:00
|
|
|
getPgpIdList();
|
|
|
|
|
|
|
|
// ACTUALLY only need summary - but have written code for data.
|
|
|
|
// Also need to use opts.groupFlags to filter stuff properly to REALID's only.
|
|
|
|
// TODO
|
|
|
|
|
|
|
|
//uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY;
|
|
|
|
uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA;
|
2012-11-05 17:28:08 -05:00
|
|
|
RsTokReqOptions opts;
|
2012-11-07 16:38:43 -05:00
|
|
|
//opts.mReqType = GXS_REQUEST_TYPE_GROUP_META;
|
|
|
|
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
|
2012-11-05 17:28:08 -05:00
|
|
|
uint32_t token = 0;
|
|
|
|
|
|
|
|
RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts);
|
|
|
|
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
mHashPgp_Token = token;
|
2012-11-06 14:18:11 -05:00
|
|
|
mHashPgp_SearchActive = true;
|
2012-11-05 17:28:08 -05:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool p3IdService::pgphash_request()
|
|
|
|
{
|
|
|
|
uint32_t token = 0;
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
2012-11-06 14:18:11 -05:00
|
|
|
if (!mHashPgp_SearchActive)
|
2012-11-05 17:28:08 -05:00
|
|
|
{
|
2012-11-07 16:38:43 -05:00
|
|
|
std::cerr << "p3IdService::pgphash_request() Search Not Active returning false";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-11-05 17:28:08 -05:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
token = mHashPgp_Token;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::cerr << "p3IdService::pgphash_request() checking request";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
uint32_t status = RsGenExchange::getTokenService()->requestStatus(token);
|
|
|
|
|
|
|
|
if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::pgphash_request() token ready: " << token;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
// We need full data - for access to Hash & Signature.
|
|
|
|
// Perhaps we will change this to an initial pass through Meta,
|
|
|
|
// and use this to discard lots of things.
|
|
|
|
|
|
|
|
// Even better - we can set flags in the Meta Data, (IdType),
|
|
|
|
// And use GXS to filter out all the AnonIds, and only have to process
|
|
|
|
// Proper Ids.
|
|
|
|
|
|
|
|
// We Will do this later!
|
|
|
|
|
|
|
|
std::vector<RsGxsIdGroup> groups;
|
|
|
|
std::vector<RsGxsIdGroup> groupsToProcess;
|
|
|
|
bool ok = getGroupData(token, groups);
|
|
|
|
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
2012-11-06 14:18:11 -05:00
|
|
|
mHashPgp_SearchActive = false;
|
2012-11-05 17:28:08 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if(ok)
|
|
|
|
{
|
2012-11-07 16:38:43 -05:00
|
|
|
std::cerr << "p3IdService::pgphash_request() Have " << groups.size() << " Groups";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-11-05 17:28:08 -05:00
|
|
|
std::vector<RsGxsIdGroup>::iterator vit;
|
|
|
|
for(vit = groups.begin(); vit != groups.end(); vit++)
|
|
|
|
{
|
2012-11-07 16:38:43 -05:00
|
|
|
std::cerr << "p3IdService::pgphash_request() Group Id: " << vit->mMeta.mGroupId;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-11-05 17:28:08 -05:00
|
|
|
/* Filter based on IdType */
|
|
|
|
if (!(vit->mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID))
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::pgphash_request() discarding AnonID";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* now we need to decode the Service String - see what is saved there */
|
|
|
|
SSGxsIdGroup ssdata;
|
|
|
|
if (ssdata.load(vit->mMeta.mServiceString))
|
|
|
|
{
|
|
|
|
if (ssdata.pgp.idKnown)
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::pgphash_request() discarding Already Known";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Have a linear attempt policy -
|
|
|
|
* if zero checks - try now.
|
|
|
|
* if 1 check, at least a day.
|
|
|
|
* if 2 checks: 2days, etc.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define SECS_PER_DAY (3600 * 24)
|
|
|
|
time_t age = time(NULL) - ssdata.pgp.lastCheckTs;
|
|
|
|
time_t wait_period = ssdata.pgp.checkAttempts * SECS_PER_DAY;
|
|
|
|
if (wait_period > 30 * SECS_PER_DAY)
|
|
|
|
{
|
|
|
|
wait_period = 30 * SECS_PER_DAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (age < wait_period)
|
|
|
|
{
|
2012-11-07 16:38:43 -05:00
|
|
|
std::cerr << "p3IdService::pgphash_request() discarding Recent Check";
|
2012-11-05 17:28:08 -05:00
|
|
|
std::cerr << std::endl;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if we get here -> then its to be processed */
|
2012-11-07 16:38:43 -05:00
|
|
|
std::cerr << "p3IdService::pgphash_request() ToProcess Group: " << vit->mMeta.mGroupId;
|
2012-11-05 17:28:08 -05:00
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-11-07 16:38:43 -05:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
2012-11-05 17:28:08 -05:00
|
|
|
mGroupsToProcess.push_back(*vit);
|
|
|
|
}
|
|
|
|
}
|
2012-11-07 16:38:43 -05:00
|
|
|
else
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::pgphash_request() getGroupData ERROR";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
}
|
|
|
|
|
2012-11-05 17:28:08 -05:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool p3IdService::pgphash_process()
|
|
|
|
{
|
|
|
|
/* each time this is called - process one Id from mGroupsToProcess */
|
2012-11-07 16:38:43 -05:00
|
|
|
RsGxsIdGroup pg;
|
2012-11-05 17:28:08 -05:00
|
|
|
{
|
2012-11-07 16:38:43 -05:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
if (mGroupsToProcess.empty())
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::pgphash_process() List Empty... Done";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
pg = mGroupsToProcess.front();
|
|
|
|
mGroupsToProcess.pop_front();
|
2012-11-05 17:28:08 -05:00
|
|
|
|
2012-11-07 16:38:43 -05:00
|
|
|
std::cerr << "p3IdService::pgphash_process() Popped Group: " << pg.mMeta.mGroupId;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
}
|
2012-11-05 17:28:08 -05:00
|
|
|
|
|
|
|
SSGxsIdGroup ssdata;
|
|
|
|
ssdata.load(pg.mMeta.mServiceString); // attempt load - okay if fails.
|
|
|
|
|
|
|
|
PGPIdType pgpId;
|
|
|
|
|
|
|
|
if (checkId(pg, pgpId))
|
|
|
|
{
|
|
|
|
/* found a match - update everything */
|
|
|
|
/* Consistency issues here - what if Reputation was recently updated? */
|
|
|
|
|
2012-11-07 16:38:43 -05:00
|
|
|
std::cerr << "p3IdService::pgphash_process() CheckId Success for Group: " << pg.mMeta.mGroupId;
|
|
|
|
std::cerr << " PgpId: " << pgpId.toStdString();
|
|
|
|
std::cerr << std::endl;
|
2012-11-05 17:28:08 -05:00
|
|
|
|
|
|
|
/* update */
|
|
|
|
ssdata.pgp.idKnown = true;
|
|
|
|
ssdata.pgp.pgpId = pgpId.toStdString();
|
|
|
|
|
|
|
|
// SHOULD BE PUSHED TO CACHE!
|
|
|
|
#if 0
|
|
|
|
id.mGpgIdKnown = true;
|
|
|
|
|
|
|
|
id.mGpgId = *it;
|
|
|
|
id.mGpgName = details.name;
|
|
|
|
id.mGpgEmail = details.email;
|
|
|
|
|
|
|
|
if (*it == ownId)
|
|
|
|
{
|
|
|
|
id.mIdType |= RSID_RELATION_YOURSELF;
|
|
|
|
}
|
|
|
|
else if (rsPeers->isGPGAccepted(*it))
|
|
|
|
{
|
|
|
|
id.mIdType |= RSID_RELATION_FRIEND;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
id.mIdType |= RSID_RELATION_OTHER;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-11-07 16:38:43 -05:00
|
|
|
std::cerr << "p3IdService::pgphash_process() No Match for Group: " << pg.mMeta.mGroupId;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-11-05 17:28:08 -05:00
|
|
|
ssdata.pgp.lastCheckTs = time(NULL);
|
|
|
|
ssdata.pgp.checkAttempts++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set new Group ServiceString */
|
|
|
|
uint32_t dummyToken = 0;
|
|
|
|
std::string serviceString = ssdata.save();
|
|
|
|
setGroupServiceString(dummyToken, pg.mMeta.mGroupId, serviceString);
|
|
|
|
|
2012-11-07 16:38:43 -05:00
|
|
|
return false; // as there are more items on the queue to process.
|
2012-11-05 17:28:08 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool p3IdService::checkId(const RsGxsIdGroup &grp, PGPIdType &pgpId)
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::checkId() Starting Match Check for RsGxsId: ";
|
|
|
|
std::cerr << grp.mMeta.mGroupId;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
/* iterate through and check hash */
|
|
|
|
GxsIdPgpHash ans(grp.mPgpIdHash);
|
|
|
|
|
2012-11-07 16:38:43 -05:00
|
|
|
std::cerr << "\tExpected Answer: " << ans.toStdString();
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
|
2012-11-05 17:28:08 -05:00
|
|
|
std::map<PGPIdType, PGPFingerprintType>::iterator mit;
|
|
|
|
for(mit = mPgpFingerprintMap.begin(); mit != mPgpFingerprintMap.end(); mit++)
|
|
|
|
{
|
|
|
|
GxsIdPgpHash hash;
|
|
|
|
calcPGPHash(grp.mMeta.mGroupId, mit->second, hash);
|
|
|
|
if (ans == hash)
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::checkId() HASH MATCH!";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-11-06 14:18:11 -05:00
|
|
|
#if ENABLE_PGP_SIGNATURES
|
2012-11-05 17:28:08 -05:00
|
|
|
/* miracle match! */
|
|
|
|
/* check signature too */
|
|
|
|
if (AuthGPG::getAuthGPG()->VerifySignBin((void *) hash.toByteArray(), hash.SIZE_IN_BYTES,
|
|
|
|
(unsigned char *) grp.mPgpIdSign.c_str(), grp.mPgpIdSign.length(),
|
|
|
|
mit->second.toStdString()))
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::checkId() Signature Okay too!";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
pgpId = mit->first;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* error */
|
|
|
|
std::cerr << "p3IdService::checkId() ERROR Signature Failed";
|
|
|
|
std::cerr << std::endl;
|
2012-11-06 14:18:11 -05:00
|
|
|
#else
|
2012-11-07 16:38:43 -05:00
|
|
|
pgpId = mit->first;
|
2012-11-06 14:18:11 -05:00
|
|
|
std::cerr << "p3IdService::checkId() Skipping Signature check for now... Hash Okay";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
return true;
|
|
|
|
#endif
|
|
|
|
|
2012-11-05 17:28:08 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::cerr << "p3IdService::checkId() Checked " << mPgpFingerprintMap.size() << " Hashes without Match";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* worker functions */
|
|
|
|
void p3IdService::getPgpIdList()
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::getPgpIdList() Starting....";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
std::list<std::string> list;
|
|
|
|
AuthGPG::getAuthGPG()->getGPGFilteredList(list);
|
|
|
|
|
2012-11-07 16:38:43 -05:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
|
|
|
|
mPgpFingerprintMap.clear();
|
|
|
|
|
2012-11-05 17:28:08 -05:00
|
|
|
std::list<std::string>::iterator it;
|
|
|
|
for(it = list.begin(); it != list.end(); it++)
|
|
|
|
{
|
|
|
|
PGPIdType pgpId(*it);
|
|
|
|
PGPFingerprintType fp;
|
|
|
|
AuthGPG::getAuthGPG()->getKeyFingerprint(pgpId, fp);
|
|
|
|
|
2012-11-07 16:38:43 -05:00
|
|
|
std::cerr << "p3IdService::getPgpIdList() Id: " << pgpId.toStdString() << " => " << fp.toStdString();
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-11-05 17:28:08 -05:00
|
|
|
mPgpFingerprintMap[pgpId] = fp;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::cerr << "p3IdService::getPgpIdList() Items: " << mPgpFingerprintMap.size();
|
|
|
|
std::cerr << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void calcPGPHash(const RsGxsId &id, const PGPFingerprintType &pgp, GxsIdPgpHash &hash)
|
|
|
|
{
|
|
|
|
unsigned char signature[SHA_DIGEST_LENGTH];
|
|
|
|
/* hash id + pubkey => pgphash */
|
|
|
|
SHA_CTX *sha_ctx = new SHA_CTX;
|
|
|
|
SHA1_Init(sha_ctx);
|
|
|
|
|
|
|
|
SHA1_Update(sha_ctx, id.c_str(), id.length()); // TO FIX ONE DAY.
|
|
|
|
SHA1_Update(sha_ctx, pgp.toByteArray(), pgp.SIZE_IN_BYTES);
|
|
|
|
SHA1_Final(signature, sha_ctx);
|
|
|
|
hash = GxsIdPgpHash(signature);
|
|
|
|
|
2012-11-07 16:38:43 -05:00
|
|
|
std::cerr << "calcPGPHash():";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
std::cerr << "\tRsGxsId: " << id;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
std::cerr << "\tFingerprint: " << pgp.toStdString();
|
|
|
|
std::cerr << std::endl;
|
|
|
|
std::cerr << "\tFinal Hash: " << hash.toStdString();
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-11-05 17:28:08 -05:00
|
|
|
delete sha_ctx;
|
|
|
|
}
|
|
|
|
|
2012-10-21 15:15:46 -04:00
|
|
|
|
2012-06-13 20:27:28 -04:00
|
|
|
/************************************************************************************/
|
|
|
|
/************************************************************************************/
|
|
|
|
/************************************************************************************/
|
|
|
|
/************************************************************************************/
|
|
|
|
/************************************************************************************/
|
|
|
|
|
2012-10-17 20:28:54 -04:00
|
|
|
std::string p3IdService::genRandomId()
|
2012-02-13 13:22:35 -05:00
|
|
|
{
|
2012-10-17 20:28:54 -04:00
|
|
|
std::string randomId;
|
|
|
|
for(int i = 0; i < 20; i++)
|
2012-02-13 13:22:35 -05:00
|
|
|
{
|
2012-10-17 20:28:54 -04:00
|
|
|
randomId += (char) ('a' + (RSRandom::random_u32() % 26));
|
2012-02-13 13:22:35 -05:00
|
|
|
}
|
|
|
|
|
2012-10-17 20:28:54 -04:00
|
|
|
return randomId;
|
2012-02-13 13:22:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void p3IdService::generateDummyData()
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
|
|
|
|
/* grab all the gpg ids... and make some ids */
|
|
|
|
|
|
|
|
std::list<std::string> gpgids;
|
|
|
|
std::list<std::string>::iterator it;
|
|
|
|
|
|
|
|
rsPeers->getGPGAllList(gpgids);
|
|
|
|
|
|
|
|
std::string ownId = rsPeers->getGPGOwnId();
|
|
|
|
gpgids.push_back(ownId);
|
|
|
|
|
2012-11-03 07:57:27 -04:00
|
|
|
int genCount = 0;
|
2012-02-13 13:22:35 -05:00
|
|
|
int i;
|
|
|
|
for(it = gpgids.begin(); it != gpgids.end(); it++)
|
|
|
|
{
|
|
|
|
/* create one or two for each one */
|
|
|
|
int nIds = 1 + (RSRandom::random_u32() % 2);
|
|
|
|
for(i = 0; i < nIds; i++)
|
|
|
|
{
|
2012-10-21 11:48:18 -04:00
|
|
|
RsGxsIdGroup id;
|
2012-02-13 13:22:35 -05:00
|
|
|
|
|
|
|
RsPeerDetails details;
|
|
|
|
|
2012-06-13 20:27:28 -04:00
|
|
|
//id.mKeyId = genRandomId();
|
|
|
|
id.mMeta.mGroupId = genRandomId();
|
2012-11-05 17:28:08 -05:00
|
|
|
id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID;
|
|
|
|
id.mPgpIdHash = genRandomId();
|
|
|
|
id.mPgpIdSign = genRandomId();
|
2012-02-13 13:22:35 -05:00
|
|
|
|
|
|
|
if (rsPeers->getPeerDetails(*it, details))
|
|
|
|
{
|
|
|
|
std::ostringstream out;
|
|
|
|
out << details.name << "_" << i + 1;
|
|
|
|
|
2012-06-13 20:27:28 -04:00
|
|
|
//id.mNickname = out.str();
|
|
|
|
id.mMeta.mGroupName = out.str();
|
2012-02-13 13:22:35 -05:00
|
|
|
|
2012-11-05 17:28:08 -05:00
|
|
|
|
2012-02-13 13:22:35 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::generateDummyData() missing" << std::endl;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-06-13 20:27:28 -04:00
|
|
|
//id.mNickname = genRandomId();
|
|
|
|
id.mMeta.mGroupName = genRandomId();
|
2012-02-13 13:22:35 -05:00
|
|
|
}
|
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
uint32_t dummyToken = 0;
|
|
|
|
createGroup(dummyToken, id);
|
2012-11-03 07:57:27 -04:00
|
|
|
|
|
|
|
// LIMIT - AS GENERATION IS BROKEN.
|
2012-11-07 16:38:43 -05:00
|
|
|
#define MAX_TEST_GEN 5
|
2012-11-03 07:57:27 -04:00
|
|
|
if (++genCount > MAX_TEST_GEN)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2012-02-13 13:22:35 -05:00
|
|
|
}
|
|
|
|
}
|
2012-11-03 10:07:26 -04:00
|
|
|
return;
|
2012-02-13 13:22:35 -05:00
|
|
|
|
2012-07-07 21:26:55 -04:00
|
|
|
#define MAX_RANDOM_GPGIDS 10 //1000
|
|
|
|
#define MAX_RANDOM_PSEUDOIDS 50 //5000
|
2012-02-13 13:22:35 -05:00
|
|
|
|
|
|
|
int nFakeGPGs = (RSRandom::random_u32() % MAX_RANDOM_GPGIDS);
|
|
|
|
int nFakePseudoIds = (RSRandom::random_u32() % MAX_RANDOM_PSEUDOIDS);
|
|
|
|
|
|
|
|
/* make some fake gpg ids */
|
|
|
|
for(i = 0; i < nFakeGPGs; i++)
|
|
|
|
{
|
2012-10-21 11:48:18 -04:00
|
|
|
RsGxsIdGroup id;
|
2012-02-13 13:22:35 -05:00
|
|
|
|
|
|
|
RsPeerDetails details;
|
|
|
|
|
2012-11-05 17:28:08 -05:00
|
|
|
id.mMeta.mGroupName = genRandomId();
|
|
|
|
|
2012-06-13 20:27:28 -04:00
|
|
|
id.mMeta.mGroupId = genRandomId();
|
2012-11-05 17:28:08 -05:00
|
|
|
id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID;
|
|
|
|
id.mPgpIdHash = genRandomId();
|
|
|
|
id.mPgpIdSign = genRandomId();
|
2012-02-13 13:22:35 -05:00
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
uint32_t dummyToken = 0;
|
|
|
|
createGroup(dummyToken, id);
|
2012-02-13 13:22:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/* make lots of pseudo ids */
|
|
|
|
for(i = 0; i < nFakePseudoIds; i++)
|
|
|
|
{
|
2012-10-21 11:48:18 -04:00
|
|
|
RsGxsIdGroup id;
|
2012-02-13 13:22:35 -05:00
|
|
|
|
|
|
|
RsPeerDetails details;
|
|
|
|
|
2012-11-05 17:28:08 -05:00
|
|
|
id.mMeta.mGroupName = genRandomId();
|
|
|
|
|
2012-06-13 20:27:28 -04:00
|
|
|
id.mMeta.mGroupId = genRandomId();
|
2012-11-05 17:28:08 -05:00
|
|
|
id.mMeta.mGroupFlags = 0;
|
|
|
|
id.mPgpIdHash = "";
|
|
|
|
id.mPgpIdSign = "";
|
|
|
|
|
2012-02-13 13:22:35 -05:00
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
uint32_t dummyToken = 0;
|
|
|
|
createGroup(dummyToken, id);
|
2012-02-13 13:22:35 -05:00
|
|
|
}
|
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
//mUpdated = true;
|
2012-02-13 13:22:35 -05:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string rsIdTypeToString(uint32_t idtype)
|
|
|
|
{
|
|
|
|
std::string str;
|
|
|
|
if (idtype & RSID_TYPE_REALID)
|
|
|
|
{
|
|
|
|
str += "GPGID ";
|
|
|
|
}
|
|
|
|
if (idtype & RSID_TYPE_PSEUDONYM)
|
|
|
|
{
|
|
|
|
str += "PSEUDO ";
|
|
|
|
}
|
|
|
|
if (idtype & RSID_RELATION_YOURSELF)
|
|
|
|
{
|
|
|
|
str += "YOURSELF ";
|
|
|
|
}
|
|
|
|
if (idtype & RSID_RELATION_FRIEND)
|
|
|
|
{
|
|
|
|
str += "FRIEND ";
|
|
|
|
}
|
|
|
|
if (idtype & RSID_RELATION_FOF)
|
|
|
|
{
|
|
|
|
str += "FOF ";
|
|
|
|
}
|
|
|
|
if (idtype & RSID_RELATION_OTHER)
|
|
|
|
{
|
|
|
|
str += "OTHER ";
|
|
|
|
}
|
|
|
|
if (idtype & RSID_RELATION_UNKNOWN)
|
|
|
|
{
|
|
|
|
str += "UNKNOWN ";
|
|
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-06-13 20:27:28 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-07-27 08:45:52 -04:00
|
|
|
/************************************************************************************/
|
|
|
|
/************************************************************************************/
|
|
|
|
/************************************************************************************/
|
|
|
|
/************************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
/* here we are running a background process that calculates the reputation scores
|
|
|
|
* for each of the IDs....
|
|
|
|
*
|
|
|
|
* As this class will be extensively used by many other threads... it is best
|
|
|
|
* that we don't block at all. This should be in a background thread.
|
|
|
|
* Perhaps a generic method to handle this will be advisable.... but we do that later.
|
|
|
|
*
|
|
|
|
* To start with we will work from the Posted service.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* So Reputation....
|
|
|
|
* Three components:
|
|
|
|
* 1) Your Opinion: Should override everything else.
|
|
|
|
* 2) Implicit Factors: Know the associated GPG Key.
|
|
|
|
* 3) Your Friends Opinions:
|
|
|
|
* 4) Your Friends Calculated Reputation Scores.
|
|
|
|
*
|
|
|
|
* Must make sure that there is no Feedback loop in the Reputation calculation.
|
|
|
|
*
|
|
|
|
* So: Our Score + Friends Scores => Local Reputation.
|
|
|
|
* Local Reputation + Friends Reputations => Final Reputation?
|
|
|
|
*
|
|
|
|
* Do we need to 'ignore' Non-scores?
|
|
|
|
* ---> This becomes like the "Best Comment" algorithm from Reddit...
|
|
|
|
* Use a statistical mechanism to work out a lower bound on Reputation.
|
|
|
|
*
|
|
|
|
* But what if your opinion is wrong?.... well likely your friends will
|
|
|
|
* get their messages and reply... you'll see the missing message - request it - check reputation etc.
|
|
|
|
*
|
|
|
|
* So we are going to have three different scores (Own, Peers, (the neighbour) Hood)...
|
|
|
|
*
|
|
|
|
* So next question, when do we need to incrementally calculate the score?
|
|
|
|
* .... how often do we need to recalculate everything -> this could lead to a flux of messages.
|
2012-07-29 09:09:36 -04:00
|
|
|
*
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* MORE NOTES:
|
|
|
|
*
|
|
|
|
* The Opinion Messages will have to be signed by PGP or SSL Keys, to guarantee that we don't
|
|
|
|
* multiple votes per person... As the message system doesn't handle uniqueness in this respect,
|
|
|
|
* we might have to do FULL_CALC for everything - This bit TODO.
|
|
|
|
*
|
|
|
|
* This will make IdService quite different to the other GXS services.
|
2012-07-27 08:45:52 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
/************************************************************************************/
|
|
|
|
/*
|
|
|
|
* Processing Algorithm:
|
|
|
|
* - Grab all Groups which have received messages.
|
|
|
|
* (opt 1)-> grab latest msgs for each of these and process => score.
|
|
|
|
* (opt 2)-> try incremental system (people probably won't change opinions often -> just set them once)
|
|
|
|
* --> if not possible, fallback to full calculation.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2012-11-06 14:18:11 -05:00
|
|
|
bool p3IdService::reputation_start()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool p3IdService::reputation_continue()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-07-27 08:45:52 -04:00
|
|
|
|
|
|
|
#define ID_BACKGROUND_PERIOD 60
|
|
|
|
|
|
|
|
int p3IdService::background_tick()
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::background_tick()";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
// Run Background Stuff.
|
|
|
|
background_checkTokenRequest();
|
|
|
|
|
|
|
|
/* every minute - run a background check */
|
|
|
|
time_t now = time(NULL);
|
|
|
|
bool doCheck = false;
|
|
|
|
{
|
2012-07-29 09:09:36 -04:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
2012-07-27 08:45:52 -04:00
|
|
|
if (now - mLastBgCheck > ID_BACKGROUND_PERIOD)
|
|
|
|
{
|
|
|
|
doCheck = true;
|
|
|
|
mLastBgCheck = now;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (doCheck)
|
|
|
|
{
|
2012-07-29 09:09:36 -04:00
|
|
|
//addExtraDummyData();
|
2012-07-27 08:45:52 -04:00
|
|
|
background_requestGroups();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Add in new votes + comments.
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/***** Background Processing ****
|
|
|
|
*
|
|
|
|
* Process Each Message - as it arrives.
|
|
|
|
*
|
|
|
|
* Update
|
|
|
|
*
|
|
|
|
*/
|
2012-07-29 09:09:36 -04:00
|
|
|
#define ID_BG_IDLE 0
|
|
|
|
#define ID_BG_REQUEST_GROUPS 1
|
2012-07-27 08:45:52 -04:00
|
|
|
#define ID_BG_REQUEST_UNPROCESSED 2
|
2012-07-29 09:09:36 -04:00
|
|
|
#define ID_BG_REQUEST_FULLCALC 3
|
2012-07-27 08:45:52 -04:00
|
|
|
|
|
|
|
bool p3IdService::background_checkTokenRequest()
|
|
|
|
{
|
|
|
|
uint32_t token = 0;
|
|
|
|
uint32_t phase = 0;
|
|
|
|
{
|
2012-07-29 09:09:36 -04:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
2012-07-27 08:45:52 -04:00
|
|
|
if (!mBgProcessing)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
token = mBgToken;
|
|
|
|
phase = mBgPhase;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t status;
|
|
|
|
uint32_t reqtype;
|
|
|
|
uint32_t anstype;
|
|
|
|
time_t ts;
|
2012-10-21 11:48:18 -04:00
|
|
|
|
|
|
|
|
|
|
|
status = RsGenExchange::getTokenService()->requestStatus(token);
|
|
|
|
//checkRequestStatus(token, status, reqtype, anstype, ts);
|
2012-07-27 08:45:52 -04:00
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
2012-07-27 08:45:52 -04:00
|
|
|
{
|
|
|
|
switch(phase)
|
|
|
|
{
|
|
|
|
case ID_BG_REQUEST_GROUPS:
|
|
|
|
background_requestNewMessages();
|
|
|
|
break;
|
|
|
|
case ID_BG_REQUEST_UNPROCESSED:
|
|
|
|
background_processNewMessages();
|
|
|
|
break;
|
2012-07-29 09:09:36 -04:00
|
|
|
case ID_BG_REQUEST_FULLCALC:
|
|
|
|
background_processFullCalc();
|
2012-07-27 08:45:52 -04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool p3IdService::background_requestGroups()
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::background_requestGroups()";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
// grab all the subscribed groups.
|
|
|
|
uint32_t token = 0;
|
|
|
|
|
|
|
|
{
|
2012-07-29 09:09:36 -04:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
2012-07-27 08:45:52 -04:00
|
|
|
|
|
|
|
if (mBgProcessing)
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::background_requestGroups() ERROR Already processing, Skip this cycle";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
mBgProcessing = true;
|
|
|
|
mBgPhase = ID_BG_REQUEST_GROUPS;
|
|
|
|
mBgToken = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY;
|
2012-10-21 15:45:35 -04:00
|
|
|
RsTokReqOptions opts;
|
2012-07-27 08:45:52 -04:00
|
|
|
std::list<std::string> groupIds;
|
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
/**
|
|
|
|
TODO
|
2012-07-27 08:45:52 -04:00
|
|
|
opts.mStatusFilter = RSGXS_GROUP_STATUS_NEWMSG;
|
|
|
|
opts.mStatusMask = RSGXS_GROUP_STATUS_NEWMSG;
|
2012-10-21 11:48:18 -04:00
|
|
|
**/
|
2012-07-27 08:45:52 -04:00
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts, groupIds);
|
2012-07-27 08:45:52 -04:00
|
|
|
{
|
2012-07-29 09:09:36 -04:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
2012-07-27 08:45:52 -04:00
|
|
|
mBgToken = token;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool p3IdService::background_requestNewMessages()
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::background_requestNewMessages()";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-07-29 09:09:36 -04:00
|
|
|
std::list<RsGroupMetaData> modGroupList;
|
|
|
|
std::list<RsGroupMetaData>::iterator it;
|
|
|
|
|
2012-07-27 08:45:52 -04:00
|
|
|
std::list<std::string> groupIds;
|
|
|
|
uint32_t token = 0;
|
|
|
|
|
|
|
|
{
|
2012-07-29 09:09:36 -04:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
2012-07-27 08:45:52 -04:00
|
|
|
token = mBgToken;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!getGroupSummary(token, modGroupList))
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::background_requestNewMessages() ERROR No Group List";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
background_cleanup();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
2012-07-29 09:09:36 -04:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
2012-07-27 08:45:52 -04:00
|
|
|
mBgPhase = ID_BG_REQUEST_UNPROCESSED;
|
|
|
|
mBgToken = 0;
|
|
|
|
|
|
|
|
/* now we process the modGroupList -> a map so we can use it easily later, and create id list too */
|
|
|
|
for(it = modGroupList.begin(); it != modGroupList.end(); it++)
|
|
|
|
{
|
2012-10-21 11:48:18 -04:00
|
|
|
/*** TODO
|
|
|
|
uint32_t dummyToken = 0;
|
|
|
|
setGroupStatusFlags(dummyToken, it->mGroupId, 0, RSGXS_GROUP_STATUS_NEWMSG);
|
|
|
|
***/
|
2012-07-27 08:45:52 -04:00
|
|
|
|
|
|
|
mBgGroupMap[it->mGroupId] = *it;
|
2012-07-29 09:09:36 -04:00
|
|
|
groupIds.push_back(it->mGroupId);
|
2012-07-27 08:45:52 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY;
|
2012-10-21 15:45:35 -04:00
|
|
|
RsTokReqOptions opts;
|
2012-07-27 08:45:52 -04:00
|
|
|
token = 0;
|
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
/* TODO
|
2012-07-27 08:45:52 -04:00
|
|
|
opts.mStatusFilter = RSGXS_MSG_STATUS_UNPROCESSED;
|
|
|
|
opts.mStatusMask = RSGXS_MSG_STATUS_UNPROCESSED;
|
2012-10-21 11:48:18 -04:00
|
|
|
*/
|
2012-07-27 08:45:52 -04:00
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
RsGenExchange::getTokenService()->requestMsgInfo(token, ansType, opts, groupIds);
|
2012-07-27 08:45:52 -04:00
|
|
|
|
|
|
|
{
|
2012-07-29 09:09:36 -04:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
2012-07-27 08:45:52 -04:00
|
|
|
mBgToken = token;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool p3IdService::background_processNewMessages()
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::background_processNewMessages()";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
GxsMsgMetaMap newMsgMap;
|
|
|
|
GxsMsgMetaMap::iterator it;
|
2012-07-27 08:45:52 -04:00
|
|
|
uint32_t token = 0;
|
|
|
|
|
|
|
|
{
|
2012-07-29 09:09:36 -04:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
2012-07-27 08:45:52 -04:00
|
|
|
token = mBgToken;
|
|
|
|
}
|
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
if (!getMsgSummary(token, newMsgMap))
|
2012-07-27 08:45:52 -04:00
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::background_processNewMessages() ERROR No New Msgs";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
background_cleanup();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* iterate through the msgs.. update the mBgGroupMap with new data,
|
|
|
|
* and flag these items as modified - so we rewrite them to the db later.
|
|
|
|
*
|
|
|
|
* If a message is not an original -> store groupId for requiring full analysis later.
|
|
|
|
*/
|
|
|
|
|
2012-07-29 09:09:36 -04:00
|
|
|
std::map<std::string, RsGroupMetaData>::iterator mit;
|
2012-07-27 08:45:52 -04:00
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
for (it = newMsgMap.begin(); it != newMsgMap.end(); it++)
|
|
|
|
{
|
|
|
|
std::vector<RsMsgMetaData>::iterator vit;
|
|
|
|
for(vit = it->second.begin(); vit != it->second.end(); vit++)
|
2012-07-27 08:45:52 -04:00
|
|
|
{
|
2012-10-21 11:48:18 -04:00
|
|
|
std::cerr << "p3IdService::background_processNewMessages() new MsgId: " << vit->mMsgId;
|
2012-07-29 09:09:36 -04:00
|
|
|
std::cerr << std::endl;
|
2012-10-21 11:48:18 -04:00
|
|
|
|
|
|
|
/* flag each new vote as processed */
|
|
|
|
/**
|
|
|
|
TODO
|
|
|
|
uint32_t dummyToken = 0;
|
|
|
|
setMsgStatusFlags(dummyToken, it->mMsgId, 0, RSGXS_MSG_STATUS_UNPROCESSED);
|
|
|
|
**/
|
|
|
|
|
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
|
|
|
|
mit = mBgGroupMap.find(it->first);
|
|
|
|
if (mit == mBgGroupMap.end())
|
2012-07-27 08:45:52 -04:00
|
|
|
{
|
2012-10-21 11:48:18 -04:00
|
|
|
std::cerr << "p3IdService::background_processNewMessages() ERROR missing GroupId: ";
|
|
|
|
std::cerr << vit->mGroupId;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-07-27 08:45:52 -04:00
|
|
|
/* error */
|
2012-10-21 11:48:18 -04:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mit->second.mGroupStatus & ID_LOCAL_STATUS_FULL_CALC_FLAG)
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::background_processNewMessages() Group Already marked FULL_CALC";
|
2012-07-29 09:09:36 -04:00
|
|
|
std::cerr << std::endl;
|
2012-10-21 11:48:18 -04:00
|
|
|
|
|
|
|
/* already marked */
|
|
|
|
continue;
|
2012-07-27 08:45:52 -04:00
|
|
|
}
|
2012-10-21 11:48:18 -04:00
|
|
|
|
|
|
|
if (vit->mMsgId != vit->mOrigMsgId)
|
2012-07-27 08:45:52 -04:00
|
|
|
{
|
2012-10-21 11:48:18 -04:00
|
|
|
/*
|
|
|
|
* not original -> hard, redo calc (alt: could substract previous score)
|
|
|
|
*/
|
|
|
|
|
|
|
|
std::cerr << "p3IdService::background_processNewMessages() Update, mark for FULL_CALC";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
mit->second.mGroupStatus |= ID_LOCAL_STATUS_FULL_CALC_FLAG;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Try incremental calculation.
|
|
|
|
* - extract parameters from group.
|
|
|
|
* - increment, & save back.
|
|
|
|
* - flag group as modified.
|
|
|
|
*/
|
|
|
|
|
|
|
|
std::cerr << "p3IdService::background_processNewMessages() NewOpt, Try Inc Calc";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
mit->second.mGroupStatus |= ID_LOCAL_STATUS_INC_CALC_FLAG;
|
|
|
|
|
2012-11-05 17:28:08 -05:00
|
|
|
SSGxsIdGroup ssdata;
|
|
|
|
if (!ssdata.load(mit->second.mServiceString))
|
2012-10-21 11:48:18 -04:00
|
|
|
{
|
|
|
|
/* error */
|
|
|
|
std::cerr << "p3IdService::background_processNewMessages() ERROR Extracting";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* do calcs */
|
|
|
|
std::cerr << "p3IdService::background_processNewMessages() Extracted: ";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
/* store it back in */
|
|
|
|
std::cerr << "p3IdService::background_processNewMessages() Stored: ";
|
2012-07-29 09:09:36 -04:00
|
|
|
std::cerr << std::endl;
|
2012-11-05 17:28:08 -05:00
|
|
|
|
|
|
|
std::string serviceString = ssdata.save();
|
|
|
|
if (0)
|
2012-10-21 11:48:18 -04:00
|
|
|
{
|
|
|
|
/* error */
|
|
|
|
std::cerr << "p3IdService::background_processNewMessages() ERROR Storing";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
}
|
2012-07-27 08:45:52 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* now iterate through groups again
|
|
|
|
* -> update status as we go
|
|
|
|
* -> record one requiring a full analyssis
|
|
|
|
*/
|
|
|
|
|
|
|
|
{
|
2012-07-29 09:09:36 -04:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
|
|
|
|
std::cerr << "p3IdService::background_processNewMessages() Checking Groups for Calc Type";
|
|
|
|
std::cerr << std::endl;
|
2012-07-27 08:45:52 -04:00
|
|
|
|
|
|
|
for(mit = mBgGroupMap.begin(); mit != mBgGroupMap.end(); mit++)
|
|
|
|
{
|
2012-07-29 09:09:36 -04:00
|
|
|
if (mit->second.mGroupStatus & ID_LOCAL_STATUS_FULL_CALC_FLAG)
|
2012-07-27 08:45:52 -04:00
|
|
|
{
|
2012-07-29 09:09:36 -04:00
|
|
|
std::cerr << "p3IdService::background_processNewMessages() FullCalc for: ";
|
|
|
|
std::cerr << mit->second.mGroupId;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
mBgFullCalcGroups.push_back(mit->second.mGroupId);
|
2012-07-27 08:45:52 -04:00
|
|
|
}
|
2012-07-29 09:09:36 -04:00
|
|
|
else if (mit->second.mGroupStatus & ID_LOCAL_STATUS_INC_CALC_FLAG)
|
2012-07-27 08:45:52 -04:00
|
|
|
{
|
2012-07-29 09:09:36 -04:00
|
|
|
std::cerr << "p3IdService::background_processNewMessages() IncCalc done for: ";
|
|
|
|
std::cerr << mit->second.mGroupId;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-07-27 08:45:52 -04:00
|
|
|
/* set Cache */
|
2012-10-21 11:48:18 -04:00
|
|
|
uint32_t dummyToken = 0;
|
|
|
|
setGroupServiceString(dummyToken, mit->second.mGroupId, mit->second.mServiceString);
|
2012-07-27 08:45:52 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* why is it here? error. */
|
2012-07-29 09:09:36 -04:00
|
|
|
std::cerr << "p3IdService::background_processNewMessages() ERROR for: ";
|
|
|
|
std::cerr << mit->second.mGroupId;
|
|
|
|
std::cerr << std::endl;
|
2012-07-27 08:45:52 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-29 09:09:36 -04:00
|
|
|
return background_FullCalcRequest();
|
2012-07-27 08:45:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool p3IdService::background_FullCalcRequest()
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* grab an GroupId from List.
|
|
|
|
* - If empty, we are finished.
|
|
|
|
* - request all latest mesgs
|
|
|
|
*/
|
2012-07-29 09:09:36 -04:00
|
|
|
|
2012-07-27 08:45:52 -04:00
|
|
|
std::list<std::string> groupIds;
|
|
|
|
{
|
2012-07-29 09:09:36 -04:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
mBgPhase = ID_BG_REQUEST_FULLCALC;
|
2012-07-27 08:45:52 -04:00
|
|
|
mBgToken = 0;
|
|
|
|
mBgGroupMap.clear();
|
|
|
|
|
|
|
|
if (mBgFullCalcGroups.empty())
|
|
|
|
{
|
|
|
|
/* finished! */
|
2012-07-29 09:09:36 -04:00
|
|
|
background_cleanup();
|
|
|
|
return true;
|
2012-07-27 08:45:52 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
groupIds.push_back(mBgFullCalcGroups.front());
|
|
|
|
mBgFullCalcGroups.pop_front();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* request the summary info from the parents */
|
|
|
|
uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA;
|
2012-07-29 09:09:36 -04:00
|
|
|
uint32_t token = 0;
|
2012-10-21 15:45:35 -04:00
|
|
|
RsTokReqOptions opts;
|
2012-07-29 09:09:36 -04:00
|
|
|
opts.mOptions = RS_TOKREQOPT_MSG_LATEST;
|
2012-07-27 08:45:52 -04:00
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
RsGenExchange::getTokenService()->requestMsgInfo(token, ansType, opts, groupIds);
|
2012-07-27 08:45:52 -04:00
|
|
|
|
|
|
|
{
|
2012-07-29 09:09:36 -04:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
2012-07-27 08:45:52 -04:00
|
|
|
mBgToken = token;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool p3IdService::background_processFullCalc()
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::background_processFullCalc()";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
std::list<RsMsgMetaData> msgList;
|
|
|
|
std::list<RsMsgMetaData>::iterator it;
|
|
|
|
|
|
|
|
|
|
|
|
bool validmsgs = false;
|
|
|
|
|
|
|
|
/* calc variables */
|
|
|
|
uint32_t opinion_count = 0;
|
|
|
|
uint32_t opinion_nullcount = 0;
|
|
|
|
double opinion_sum = 0;
|
|
|
|
double opinion_sumsq = 0;
|
|
|
|
|
|
|
|
uint32_t rep_count = 0;
|
|
|
|
uint32_t rep_nullcount = 0;
|
|
|
|
double rep_sum = 0;
|
|
|
|
double rep_sumsq = 0;
|
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
std::vector<RsGxsIdOpinion> opinions;
|
|
|
|
std::vector<RsGxsIdOpinion>::iterator vit;
|
|
|
|
|
|
|
|
if (!getMsgData(mBgToken, opinions))
|
2012-07-27 08:45:52 -04:00
|
|
|
{
|
2012-10-21 11:48:18 -04:00
|
|
|
std::cerr << "p3IdService::background_processFullCalc() ERROR Failed to get Opinions";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string groupId;
|
|
|
|
for(vit = opinions.begin(); vit != opinions.end(); vit++)
|
|
|
|
{
|
|
|
|
RsGxsIdOpinion &opinion = *vit;
|
|
|
|
|
|
|
|
/* These should all be same group - should check for sanity! */
|
|
|
|
if (groupId == "")
|
|
|
|
{
|
|
|
|
groupId = opinion.mMeta.mGroupId;
|
|
|
|
}
|
|
|
|
|
2012-07-27 08:45:52 -04:00
|
|
|
std::cerr << "p3IdService::background_processFullCalc() Msg:";
|
2012-10-21 11:48:18 -04:00
|
|
|
std::cerr << opinion;
|
2012-07-27 08:45:52 -04:00
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
validmsgs = true;
|
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
/* for each opinion.... extract score, and reputation */
|
|
|
|
if (opinion.mOpinion != 0)
|
2012-07-27 08:45:52 -04:00
|
|
|
{
|
|
|
|
opinion_count++;
|
2012-10-21 11:48:18 -04:00
|
|
|
opinion_sum += opinion.mOpinion;
|
|
|
|
opinion_sum += (opinion.mOpinion * opinion.mOpinion);
|
2012-07-27 08:45:52 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
opinion_nullcount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
/* for each opinion.... extract score, and reputation */
|
|
|
|
if (opinion.mReputation != 0)
|
2012-07-27 08:45:52 -04:00
|
|
|
{
|
|
|
|
rep_nullcount++;
|
2012-10-21 11:48:18 -04:00
|
|
|
rep_sum += opinion.mReputation;
|
|
|
|
rep_sum += (opinion.mReputation * opinion.mReputation);
|
2012-07-27 08:45:52 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rep_nullcount++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
double opinion_avg = 0;
|
|
|
|
double opinion_var = 0;
|
|
|
|
double opinion_frac = 0;
|
|
|
|
|
|
|
|
double rep_avg = 0;
|
|
|
|
double rep_var = 0;
|
|
|
|
double rep_frac = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (opinion_count)
|
|
|
|
{
|
|
|
|
opinion_avg = opinion_sum / opinion_count;
|
|
|
|
opinion_var = (opinion_sumsq - opinion_count * opinion_avg * opinion_avg) / opinion_count;
|
|
|
|
opinion_frac = opinion_count / ((float) (opinion_count + opinion_nullcount));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rep_count)
|
|
|
|
{
|
|
|
|
rep_avg = rep_sum / rep_count;
|
|
|
|
rep_var = (rep_sumsq - rep_count * rep_avg * rep_avg) / rep_count;
|
|
|
|
rep_frac = rep_count / ((float) (rep_count + rep_nullcount));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (validmsgs)
|
|
|
|
{
|
2012-11-05 17:28:08 -05:00
|
|
|
SSGxsIdGroup ssdata;
|
|
|
|
std::string serviceString = ssdata.save();
|
|
|
|
|
|
|
|
std::cerr << "p3IdService::background_updateVoteCounts() Encoded String: " << serviceString;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
/* store new result */
|
|
|
|
uint32_t dummyToken = 0;
|
|
|
|
setGroupServiceString(dummyToken, groupId, serviceString);
|
2012-07-27 08:45:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
{
|
2012-07-29 09:09:36 -04:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
|
|
|
mBgPhase = ID_BG_IDLE;
|
2012-07-27 08:45:52 -04:00
|
|
|
mBgToken = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return background_FullCalcRequest();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool p3IdService::background_cleanup()
|
|
|
|
{
|
|
|
|
std::cerr << "p3IdService::background_cleanup()";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-07-29 09:09:36 -04:00
|
|
|
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
|
2012-07-27 08:45:52 -04:00
|
|
|
|
|
|
|
// Cleanup.
|
|
|
|
mBgProcessing = false;
|
2012-07-29 09:09:36 -04:00
|
|
|
mBgPhase = ID_BG_IDLE;
|
2012-07-27 08:45:52 -04:00
|
|
|
mBgToken = 0;
|
2012-07-29 09:09:36 -04:00
|
|
|
mBgGroupMap.clear();
|
|
|
|
mBgFullCalcGroups.clear();
|
|
|
|
|
2012-07-27 08:45:52 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
std::ostream &operator<<(std::ostream &out, const RsGxsIdGroup &grp)
|
2012-07-29 09:09:36 -04:00
|
|
|
{
|
2012-10-21 11:48:18 -04:00
|
|
|
out << "RsGxsIdGroup: Meta: " << grp.mMeta;
|
2012-11-05 17:28:08 -05:00
|
|
|
out << " PgpIdHash: " << grp.mPgpIdHash;
|
|
|
|
out << " PgpIdSign: [binary]"; // << grp.mPgpIdSign;
|
2012-07-29 09:09:36 -04:00
|
|
|
out << std::endl;
|
|
|
|
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
std::ostream &operator<<(std::ostream &out, const RsGxsIdOpinion &opinion)
|
2012-07-29 09:09:36 -04:00
|
|
|
{
|
2012-10-21 11:48:18 -04:00
|
|
|
out << "RsGxsIdOpinion: Meta: " << opinion.mMeta;
|
2012-07-29 09:09:36 -04:00
|
|
|
out << std::endl;
|
|
|
|
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|