Merging branches/v0.6-initdev into trunk.

These split at 6672 -> 7075, so quite a bit merge.
libretroshare compiles - but untested.
retroshare-gui needs GenCertDialog.ui and IdEditDialog.ui to be properly merged. (compile errors).
some plugins will be broken.
retroshare-nogui is untested.



git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7078 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2014-02-01 14:16:15 +00:00
commit c0738eec7f
407 changed files with 23716 additions and 50779 deletions

View file

@ -26,6 +26,7 @@
#include "retroshare/rsexpr.h"
#include "util/rsdir.h"
#include "util/rsstring.h"
#include "util/rscompress.h"
#include <assert.h>
#include <stdlib.h>
@ -753,9 +754,10 @@ int FileIndex::printFileIndex(std::string &out)
return 1;
}
int FileIndex::loadIndex(const std::string& filename, const std::string& expectedHash, uint64_t /*size*/)
int FileIndex::loadIndex(const std::string& filename, const std::string& expectedHash, uint64_t size)
{
std::ifstream file (filename.c_str(), std::ifstream::binary);
FILE *file = RsDirUtil::rs_fopen(filename.c_str(),"rb") ;
if (!file)
{
#ifdef FI_DEBUG
@ -766,28 +768,36 @@ int FileIndex::loadIndex(const std::string& filename, const std::string& expecte
}
/* load file into memory, close file */
char ibuf[512];
std::string s;
while(!file.eof())
{
file.read(ibuf, 512);
s.append(ibuf, file.gcount());
}
file.close();
uint8_t *compressed_data = new uint8_t[size] ;
/* calculate hash */
unsigned char sha_buf[SHA_DIGEST_LENGTH];
SHA_CTX *sha_ctx = new SHA_CTX;
SHA1_Init(sha_ctx);
SHA1_Update(sha_ctx, s.c_str(), s.length());
SHA1_Final(&sha_buf[0], sha_ctx);
delete sha_ctx;
std::string tmpout;
for(int i = 0; i < SHA_DIGEST_LENGTH; i++)
if(compressed_data == NULL)
{
rs_sprintf_append(tmpout, "%02x", (unsigned int) (sha_buf[i]));
std::cerr << "FileIndex::loadIndex(): can't allocate memory for " << size << " bytes." << std::endl;
return 0 ;
}
int bytesread = 0 ;
if(size != (bytesread = fread(compressed_data,1,size,file)))
{
std::cerr << "FileIndex::loadIndex(): can't read " << size << " bytes from file " << filename << ". Only " << bytesread << " actually read." << std::endl;
return 0 ;
}
fclose(file) ;
std::string tmpout = RsDirUtil::sha1sum((unsigned char *)(compressed_data),size).toStdString() ;
// /* calculate hash */
// unsigned char sha_buf[SHA_DIGEST_LENGTH];
// SHA_CTX *sha_ctx = new SHA_CTX;
// SHA1_Init(sha_ctx);
// SHA1_Update(sha_ctx, s.c_str(), s.length());
// SHA1_Final(&sha_buf[0], sha_ctx);
// delete sha_ctx;
//
// std::string tmpout;
// for(int i = 0; i < SHA_DIGEST_LENGTH; i++)
// {
// rs_sprintf_append(tmpout, "%02x", (unsigned int) (sha_buf[i]));
// }
if (expectedHash != "" && expectedHash != tmpout)
{
@ -798,6 +808,21 @@ int FileIndex::loadIndex(const std::string& filename, const std::string& expecte
#endif
return 0;
}
// now uncompress the string
//
uint8_t *uncompressed_data = NULL ;
unsigned int uncompressed_data_size = 0 ;
if(!RsCompress::uncompress_memory_chunk(compressed_data,size,uncompressed_data,uncompressed_data_size))
{
std::cerr << "FileIndex::loadIndex() Decompression failed! Fileindex can't be read." << std::endl;
return 0 ;
}
std::string s((char *)uncompressed_data,uncompressed_data_size) ;
delete[] compressed_data ;
free(uncompressed_data) ;
#define FIND_NEXT(s,start,end,c) end = s.find(c, start); if (end == std::string::npos) end = s.length();
@ -973,7 +998,6 @@ int FileIndex::saveIndex(const std::string& filename, std::string &fileHash, uin
std::string s;
size = 0 ;
fileHash = "" ;
/* print version and header */
s += "# FileIndex version 0.1\n";
@ -1010,18 +1034,37 @@ int FileIndex::saveIndex(const std::string& filename, std::string &fileHash, uin
/* signal to pop directory from stack in loadIndex() */
s += "-\n";
/* calculate sha1 hash */
SHA_CTX *sha_ctx = new SHA_CTX;
SHA1_Init(sha_ctx);
SHA1_Update(sha_ctx, s.c_str(), s.length());
SHA1_Final(&sha_buf[0], sha_ctx);
delete sha_ctx;
// now compress the data.
std::cerr << "FileIndex::saveIndex(): compressign data." << std::endl;
for(int i = 0; i < SHA_DIGEST_LENGTH; i++)
uint8_t *compressed_data = NULL ;
uint32_t compressed_data_size = 0 ;
if(!RsCompress::compress_memory_chunk((unsigned char *)s.c_str(),s.length(),compressed_data,compressed_data_size))
{
rs_sprintf_append(fileHash, "%02x", (unsigned int) (sha_buf[i]));
std::cerr << "(EE) ERROR in file list compression ! file list can't be saved" << std::endl;
return false ;
}
fileHash = RsDirUtil::sha1sum((unsigned char *)compressed_data,compressed_data_size).toStdString() ;
std::cerr << " old size = " << s.length() << std::endl;
std::cerr << " new size = " << compressed_data_size << std::endl;
std::cerr << " hash = " << fileHash << std::endl;
// /* calculate sha1 hash */
// SHA_CTX *sha_ctx = new SHA_CTX;
// SHA1_Init(sha_ctx);
// SHA1_Update(sha_ctx, s.c_str(), s.length());
// SHA1_Final(&sha_buf[0], sha_ctx);
// delete sha_ctx;
//
// for(int i = 0; i < SHA_DIGEST_LENGTH; i++)
// {
// rs_sprintf_append(fileHash, "%02x", (unsigned int) (sha_buf[i]));
// }
/* finally, save to file */
FILE *file = RsDirUtil::rs_fopen(filenametmp.c_str(), "wb");
@ -1030,9 +1073,16 @@ int FileIndex::saveIndex(const std::string& filename, std::string &fileHash, uin
std::cerr << "FileIndex::saveIndex error opening file for writting: " << filename << ". Giving up." << std::endl;
return 0;
}
fprintf(file,"%s",s.c_str()) ;
int outwritten ;
if(compressed_data_size != (outwritten=fwrite(compressed_data,1,compressed_data_size,file)))
{
std::cerr << "FileIndex::saveIndex error. File not entirely written. Only " << outwritten << " bytes wrote out of " << compressed_data_size << " check for disk full, or disk quotas." << std::endl;
return 0;
}
fclose(file);
free(compressed_data) ;
// Use a temp file name so that the file is never half saved.
//

View file

@ -349,7 +349,7 @@ bool p3BitDht::dropPeer(std::string pid)
/* extract current peer status */
bool p3BitDht::getPeerStatus(std::string id,
struct sockaddr_in &/*laddr*/, struct sockaddr_in &/*raddr*/,
struct sockaddr_storage &/*laddr*/, struct sockaddr_storage &/*raddr*/,
uint32_t &/*type*/, uint32_t &/*mode*/)
{
/* remove unused parameter warnings */
@ -363,7 +363,7 @@ bool p3BitDht::getPeerStatus(std::string id,
return false;
}
bool p3BitDht::getExternalInterface(struct sockaddr_in &/*raddr*/,
bool p3BitDht::getExternalInterface(struct sockaddr_storage &/*raddr*/,
uint32_t &/*mode*/)
{

View file

@ -197,8 +197,8 @@ virtual bool getNetworkStats(uint32_t &netsize, uint32_t &localnetsize);
virtual bool findPeer(std::string id);
virtual bool dropPeer(std::string id);
virtual int addBadPeer(const struct sockaddr_in &addr, uint32_t reason, uint32_t flags, uint32_t age);
virtual int addKnownPeer(const std::string &pid, const struct sockaddr_in &addr, uint32_t flags);
virtual int addBadPeer(const struct sockaddr_storage &addr, uint32_t reason, uint32_t flags, uint32_t age);
virtual int addKnownPeer(const std::string &pid, const struct sockaddr_storage &addr, uint32_t flags);
//virtual int addFriend(const std::string pid);
//virtual int addFriendOfFriend(const std::string pid);
//virtual int addOther(const std::string pid);
@ -208,10 +208,10 @@ virtual void ConnectionFeedback(std::string pid, int state);
/* extract current peer status */
virtual bool getPeerStatus(std::string id,
struct sockaddr_in &laddr, struct sockaddr_in &raddr,
struct sockaddr_storage &laddr, struct sockaddr_storage &raddr,
uint32_t &type, uint32_t &mode);
virtual bool getExternalInterface(struct sockaddr_in &raddr,
virtual bool getExternalInterface(struct sockaddr_storage &raddr,
uint32_t &mode);

View file

@ -72,7 +72,13 @@ int p3BitDht::InfoCallback(const bdId *id, uint32_t /*type*/, uint32_t /*flags*/
if (mPeerSharer)
{
mPeerSharer->updatePeer(rsid, addr, outtype, outreason, outage);
struct sockaddr_storage tmpaddr;
struct sockaddr_in *ap = (struct sockaddr_in *) &tmpaddr;
ap->sin_family = AF_INET;
ap->sin_addr = addr.sin_addr;
ap->sin_port = addr.sin_port;
mPeerSharer->updatePeer(rsid, tmpaddr, outtype, outreason, outage);
}
/* call to the Stunners to drop the address as well */
@ -1768,14 +1774,25 @@ int p3BitDht::checkConnectionAllowed(const bdId *peerId, int mode)
*/
void p3BitDht::ConnectCalloutTCPAttempt(const std::string &peerId, struct sockaddr_in raddr)
void p3BitDht::ConnectCalloutTCPAttempt(const std::string &peerId, struct sockaddr_in raddrv4)
{
struct sockaddr_in proxyaddr;
struct sockaddr_in srcaddr;
sockaddr_clear(&proxyaddr);
sockaddr_clear(&srcaddr);
struct sockaddr_storage raddr;
struct sockaddr_storage proxyaddr;
struct sockaddr_storage srcaddr;
sockaddr_storage_clear(proxyaddr);
sockaddr_storage_clear(proxyaddr);
sockaddr_storage_clear(srcaddr);
struct sockaddr_in *rap = (struct sockaddr_in *) &raddr;
struct sockaddr_in *pap = (struct sockaddr_in *) &proxyaddr;
struct sockaddr_in *sap = (struct sockaddr_in *) &srcaddr;
// only one to translate
rap->sin_family = AF_INET;
rap->sin_addr = raddrv4.sin_addr;
rap->sin_port = raddrv4.sin_port;
uint32_t source = RS_CB_DHT;
uint32_t connectFlags = RS_CB_FLAG_ORDER_UNSPEC | RS_CB_FLAG_MODE_TCP;
uint32_t delay = 0;
@ -1785,14 +1802,25 @@ void p3BitDht::ConnectCalloutTCPAttempt(const std::string &peerId, struct sockad
}
void p3BitDht::ConnectCalloutDirectOrProxy(const std::string &peerId, struct sockaddr_in raddr, uint32_t connectFlags, uint32_t delay)
void p3BitDht::ConnectCalloutDirectOrProxy(const std::string &peerId, struct sockaddr_in raddrv4, uint32_t connectFlags, uint32_t delay)
{
struct sockaddr_in proxyaddr;
struct sockaddr_in srcaddr;
sockaddr_clear(&proxyaddr);
sockaddr_clear(&srcaddr);
struct sockaddr_storage raddr;
struct sockaddr_storage proxyaddr;
struct sockaddr_storage srcaddr;
sockaddr_storage_clear(proxyaddr);
sockaddr_storage_clear(proxyaddr);
sockaddr_storage_clear(srcaddr);
struct sockaddr_in *rap = (struct sockaddr_in *) &raddr;
struct sockaddr_in *pap = (struct sockaddr_in *) &proxyaddr;
struct sockaddr_in *sap = (struct sockaddr_in *) &srcaddr;
// only one to translate
rap->sin_family = AF_INET;
rap->sin_addr = raddrv4.sin_addr;
rap->sin_port = raddrv4.sin_port;
uint32_t source = RS_CB_DHT;
uint32_t bandwidth = 0;
@ -1800,9 +1828,33 @@ void p3BitDht::ConnectCalloutDirectOrProxy(const std::string &peerId, struct soc
}
void p3BitDht::ConnectCalloutRelay(const std::string &peerId,
struct sockaddr_in srcaddr, struct sockaddr_in proxyaddr, struct sockaddr_in destaddr,
struct sockaddr_in srcaddrv4, struct sockaddr_in proxyaddrv4, struct sockaddr_in destaddrv4,
uint32_t connectFlags, uint32_t bandwidth)
{
struct sockaddr_storage destaddr;
struct sockaddr_storage proxyaddr;
struct sockaddr_storage srcaddr;
sockaddr_storage_clear(proxyaddr);
sockaddr_storage_clear(proxyaddr);
sockaddr_storage_clear(srcaddr);
struct sockaddr_in *dap = (struct sockaddr_in *) &destaddr;
struct sockaddr_in *pap = (struct sockaddr_in *) &proxyaddr;
struct sockaddr_in *sap = (struct sockaddr_in *) &srcaddr;
dap->sin_family = AF_INET;
dap->sin_addr = destaddrv4.sin_addr;
dap->sin_port = destaddrv4.sin_port;
pap->sin_family = AF_INET;
pap->sin_addr = proxyaddrv4.sin_addr;
pap->sin_port = proxyaddrv4.sin_port;
sap->sin_family = AF_INET;
sap->sin_addr = srcaddrv4.sin_addr;
sap->sin_port = srcaddrv4.sin_port;
uint32_t source = RS_CB_DHT;
uint32_t delay = 0;

View file

@ -184,26 +184,68 @@ bool p3BitDht::dropPeer(std::string pid)
********************************* Basic Peer Details *************************************
******************************************************************************************/
int p3BitDht::addBadPeer(const struct sockaddr_in &addr, uint32_t /*reason*/, uint32_t /*flags*/, uint32_t /*age*/)
int p3BitDht::addBadPeer(const struct sockaddr_storage &addr, uint32_t /*reason*/, uint32_t /*flags*/, uint32_t /*age*/)
{
//mUdpBitDht->updateKnownPeer(&id, 0, bdflags);
struct sockaddr_in addrv4;
if (addr.ss_family != AF_INET)
{
std::cerr << "p3BitDht::addBadPeer() cannot handle IPV6 Yet, aborting";
std::cerr << std::endl;
abort();
}
struct sockaddr_in *ap = (struct sockaddr_in *) &addr;
// convert.
addrv4.sin_family = ap->sin_family;
addrv4.sin_addr = ap->sin_addr;
addrv4.sin_port = ap->sin_port;
if (mDhtStunner)
{
mDhtStunner->dropStunPeer(addr);
mDhtStunner->dropStunPeer(addrv4);
}
if (mProxyStunner)
{
mProxyStunner->dropStunPeer(addr);
mProxyStunner->dropStunPeer(addrv4);
}
return 1;
}
int p3BitDht::addKnownPeer(const std::string &pid, const struct sockaddr_in &addr, uint32_t flags)
int p3BitDht::addKnownPeer(const std::string &pid, const struct sockaddr_storage &addr, uint32_t flags)
{
struct sockaddr_in addrv4;
if (addr.ss_family != AF_INET)
{
std::cerr << "p3BitDht::addKnownPeer() Warning! Non IPv4 Address - Cannot handle IPV6 Yet.";
std::cerr << std::endl;
sockaddr_clear(&addrv4);
if (flags & NETASSIST_KNOWN_PEER_ONLINE)
{
std::cerr << "p3BitDht::addKnownPeer() Non IPv4 Address & ONLINE. Abort()ing.";
std::cerr << std::endl;
abort();
}
}
else
{
// convert.
struct sockaddr_in *ap = (struct sockaddr_in *) &addr;
addrv4.sin_family = ap->sin_family;
addrv4.sin_addr = ap->sin_addr;
addrv4.sin_port = ap->sin_port;
}
int p3type = 0;
int bdflags = 0;
bdId id;
@ -262,13 +304,13 @@ int p3BitDht::addKnownPeer(const std::string &pid, const struct sockaddr_in &add
id.id = dpd->mDhtId.id;
id.addr = addr;
id.addr = addrv4;
}
else
{
// shouldn't use own id without mutex - but it is static!
id.id = mOwnDhtId;
id.addr = addr;
id.addr = addrv4;
}
mUdpBitDht->updateKnownPeer(&id, 0, bdflags);

View file

@ -39,9 +39,21 @@ class stunAddrAssist: public pqiAddrAssist
mStunner = stunner;
}
virtual bool getExternalAddr(struct sockaddr_in &remote, uint8_t &stable)
virtual bool getExternalAddr(struct sockaddr_storage &remote, uint8_t &stable)
{
return mStunner->externalAddr(remote, stable);
// IPV4 ONLY.
struct sockaddr_in remotev4;
if (mStunner->externalAddr(remotev4, stable))
{
sockaddr_storage_clear(remote);
struct sockaddr_in *addr = (struct sockaddr_in *) &remote;
addr->sin_family = AF_INET;
addr->sin_addr = remotev4.sin_addr;
addr->sin_port = remotev4.sin_port;
return true;
}
return false;
}
virtual int tick()

File diff suppressed because it is too large Load diff

View file

@ -1,756 +0,0 @@
/*
* libretroshare/src/distrib: p3distrib.h
*
*
* Copyright 2004-2011 by Robert Fernie.
* 2010-2011 Christopher Evi-Parker
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* 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".
*
*/
#ifndef P3_GENERIC_DISTRIB_HEADER
#define P3_GENERIC_DISTRIB_HEADER
#include "pqi/pqi.h"
#include "pqi/pqistore.h"
#include "pqi/p3cfgmgr.h"
#include "services/p3service.h"
#include "dbase/cachestrapper.h"
#include "serialiser/rsdistribitems.h"
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include <set>
#include <vector>
/*
* Group Messages....
*
* Forums / Channels / Blogs...
*
*
* Plan.
*
* (1) First create basic structures .... algorithms.
*
* (2) integrate with Cache Source/Store for data transmission.
* (3) integrate with Serialiser for messages
* (4) bring over the final key parts from existing p3channel.
*/
const uint32_t GROUP_MAX_FWD_OFFSET = (60 * 60 * 24 * 2); /* 2 Days */
/*
* A data structure to store dummy (missing) msgs.
* They are added to the GroupInfo if there is a missing parent Msg of thread Msg
* Basic Logic is:
*
*/
class RsDistribDummyMsg
{
public:
RsDistribDummyMsg( std::string tId, std::string pId, std::string mId, uint32_t ts);
RsDistribDummyMsg() { return; }
std::string threadId;
std::string parentId;
std::string msgId;
uint32_t timestamp;
time_t childTS; /* timestamp of most recent child */
};
//! for storing group keys to members of a group
/*!
* This key but be of many types, including private/public publish key, or admin prite key for group
* @see p3GroupDistrib
*/
class GroupKey
{
public:
GroupKey()
:type(0), startTS(0), endTS(0), key(NULL) { return; }
uint32_t type; /// whether key is full or public
std::string keyId;
time_t startTS, endTS;
EVP_PKEY *key; /// actual group key in evp format
};
//! used to store group picture
/*!
* ensures use of png image format
* @see p3GroupDistrib
*/
class GroupIcon{
public:
GroupIcon(): pngImageData(NULL), imageSize(0) {
return;
}
~GroupIcon(){
if((pngImageData != NULL) && (imageSize > 0))
delete[] pngImageData;
return;
}
unsigned char* pngImageData; /// pointer to image data in png format
int imageSize;
};
//! used by p3groupDistrib to store mirror info found in rsDistribGroup (i.e. messages, posts, etc)
/*!
* used by p3Groudistrib to store group info, also used to communicate group information
* to p3groupdistrib inherited classes. contain
* @see rsDistribGroup
*/
class GroupInfo
{
public:
GroupInfo()
:distribGroup(NULL), grpFlags(0), pop(0), lastPost(0), flags(0), grpChanged(false)
{
return;
}
virtual ~GroupInfo() ;
std::string grpId; /// the group id
RsDistribGrp *distribGroup; /// item which contains further information on group
std::list<std::string> sources;
std::map<std::string, RsDistribMsg *> msgs;
std::map<std::string, RsDistribDummyMsg> dummyMsgs; // dummyMsgs.
/***********************************/
/* Copied from DistribGrp */
std::wstring grpName;
std::wstring grpDesc; /// group description
std::wstring grpCategory;
uint32_t grpFlags; /// PRIVACY & AUTHENTICATION
uint32_t pop; /// popularity sources.size()
time_t lastPost; /// modded as msgs added
/***********************************/
uint32_t flags; /// PUBLISH, SUBSCRIBE, ADMIN
std::string publishKeyId; /// current active Publish Key
std::map<std::string, GroupKey> publishKeys;
GroupKey adminKey;
GroupIcon grpIcon;
/* NOT USED YET */
std::map<std::string, RsDistribMsg* > decrypted_msg_cache; /// stores a cache of messages that have been decrypted
bool publisher, allowAnon, allowUnknown;
bool subscribed, listener;
uint32_t type;
/// FLAG for Client - set if changed
bool grpChanged;
};
std::ostream &operator<<(std::ostream &out, const GroupInfo &info);
//! information on what cache stores group info
/*!
* This can refer to idividual cache message, data etc
*/
class GroupCache
{
public:
std::string filename;
time_t start, end;
uint16_t cacheSubId; /// used to resolve complete cache id
};
/* Flags for locked_notifyGroupChanged() ***/
const uint32_t GRP_NEW_UPDATE = 0x0001;
const uint32_t GRP_UPDATE = 0x0002;
const uint32_t GRP_LOAD_KEY = 0x0003;
const uint32_t GRP_NEW_MSG = 0x0004;
const uint32_t GRP_SUBSCRIBED = 0x0005;
const uint32_t GRP_UNSUBSCRIBED = 0x0006;
typedef std::map<std::string, std::list<RsCacheData> > CacheOptData;
//! Cache based service to implement group messaging
/*!
*
* Group Description:
*
* Master Public/Private Key: (Admin Key) used to control
* Group Name/Description/Icon.
* Filter Lists.
* Publish Keys.
*
* Publish Keys.
* TimeStore Length determined by inheriting class
*
* Everyone gets:
* Master Public Key.
* Publish Public Keys.
* blacklist, or whitelist filter. (Only useful for Non-Anonymous groups)
* Name, Desc,
* etc.
*
* Admins get Master Private Key.
* Publishers get Publish Private Key.
* - Channels only some get publish key.
* - Forums everyone gets publish private key.
*
* Group id is the public admin keys id
*
*/
/*
* To Handle Cache Data Loading.... we want to be able to seperate Historical
* from new data (primarily for the gui's benefit).
* to do this we have a mHistoricalCaches flag, which is automatically raised at startup,
* and a function is called to cancel it (HistoricalCachesDone()).
*/
class CacheDataPending
{
public:
CacheDataPending(const RsCacheData &data, bool local, bool historical);
RsCacheData mData;
bool mLocal;
bool mHistorical;
};
class p3GroupDistrib: public CacheSource, public CacheStore, public p3Config, public p3ThreadedService
{
public:
p3GroupDistrib(uint16_t subtype,
CacheStrapper *cs, CacheTransfer *cft,
std::string sourcedir, std::string storedir, std::string keyBackUpDir,
uint32_t configId,
uint32_t storePeriod, uint32_t pubPeriod);
virtual ~p3GroupDistrib() ;
/***************************************************************************************/
/******************************* CACHE SOURCE / STORE Interface ************************/
/***************************************************************************************/
/* TO FINISH */
public:
virtual bool loadLocalCache(const RsCacheData &data); /// overloaded from Cache Source
virtual int loadCache(const RsCacheData &data); /// overloaded from Cache Store
/* From RsThread */
virtual void run(); /* called once the thread is started */
void HistoricalCachesDone(); // called when Stored Caches have been added to Pending List.
private:
// derived from CacheSource
virtual bool isPeerAcceptedAsCacheReceiver(const std::string& ssl_id) ;
// derived from CacheStore
virtual bool isPeerAcceptedAsCacheProvider(const std::string& ssl_id) ;
/* these lists are filled by the overloaded fns... then cleared by the thread */
bool mHistoricalCaches; // initially true.... falsified by HistoricalCachesDone()
std::list<CacheDataPending> mPendingCaches;
/* top level load */
int loadAnyCache(const RsCacheData &data, bool local, bool historical);
/* load cache files */
void loadFileGroups(const std::string &filename, const std::string &src, bool local, bool historical);
void loadFileMsgs(const std::string &filename, const RsCacheData& , bool local, bool historical);
bool backUpKeys(const std::list<RsDistribGrpKey* > &keysToBackUp, std::string grpId);
void locked_sharePubKey();
/*!
* Attempt to load public key from recvd list if it exists for grpId
* @param grpId the id for the group for which private publish key is wanted
*/
bool attemptPublishKeysRecvd();
/*!
* Simply load cache opt messages
* @param data
*/
void loadCacheOptMsgs(const RsCacheData& data, const std::string& grpId);
protected:
/* load cache msgs */
/*!
* processes cache opt request by loading data for group
* @param grpId the group to process request for
* @return false if group does not exist
*/
bool processCacheOptReq(const std::string &grpId);
/*!
* msg is loaded to its group and republished,
* msg decrypted if grp is private
* @param msg msg to loaded
* @param src src of msg (peer id)
* @param local is this a local cache msg (your msg)
*/
bool loadMsg(RsDistribSignedMsg *msg, const std::string &src, bool local, bool historical);
/*!
* msg is loaded to its group and republished,
* msg decrypted if grp is private
* @param msg msg to loaded
* @param src src of msg (peer id)
* @param local is this a local cache msg (your msg)
*/
bool locked_loadMsg(RsDistribSignedMsg *newMsg, const std::string &src, bool local, bool historical);
/*!
* adds newgrp to grp set, GroupInfo type created and stored
* @param newGrp grp to be added
*/
bool loadGroup(RsDistribGrp *newGrp, bool historical);
/*!
* Adds new keys dependent on whether it is an admin or publish key
* on return resource pointed to by newKey should be considered invalid
* @param newKey key to be added
* @return if key is loaded to group or stored return true
*/
bool loadGroupKey(RsDistribGrpKey *newKey, bool historical);
/***************************************************************************************/
/***************************************************************************************/
/***************************************************************************************/
/**************************** Create Content *******************************************/
/***************************************************************************************/
/* TO FINISH */
public:
/*!
* This create a distributed grp which is sent via cache system to connected peers
* @param name name of the group created
* @param desc description of the group
* @param flags privacy flag
* @param pngImageData pointer to image data, data is copied
* @param imageSize size of the image passed
* @return id of the group
*/
std::string createGroup(std::wstring name, std::wstring desc, uint32_t flags, unsigned char *pngImageData, uint32_t imageSize);
/*!
* msg is packed into a signed message (and encrypted msg grp is private) and then sent via cache system to connnected peers
* @param msg
* @param personalSign whether to personal to sign image (this is done using gpg cert)
* @return the msg id
*/
std::string publishMsg(RsDistribMsg *msg, bool personalSign);
/*!
* note: call back to locked_eventDuplicateMSg is made on execution
* @param grpId id of group to subscribe to
* @param subscribe true to subscribe and vice versa
* @return
*/
bool subscribeToGroup(const std::string &grpId, bool subscribe);
/***************************************************************************************/
/***************************************************************************************/
/***************************************************************************************/
/****************************** Access Content ***************************************/
/***************************************************************************************/
public:
/*!
* get Group Lists
*/
bool getAllGroupList(std::list<std::string> &grpids);
bool getSubscribedGroupList(std::list<std::string> &grpids);
bool getPublishGroupList(std::list<std::string> &grpids);
/*!
*
* @param popMin lower limit for a grp's populairty in grpids
* @param popMax upper limit for a grp's popularity in grpids
* @param grpids grpids of grps which adhere to upper and lower limit of popularity
* @return nothing returned
*/
void getPopularGroupList(uint32_t popMin, uint32_t popMax, std::list<std::string> &grpids);
/* get Msg Lists */
bool getAllMsgList(const std::string& grpId, std::list<std::string> &msgIds);
bool getParentMsgList(const std::string& grpId, const std::string& pId, std::list<std::string> &msgIds);
bool getTimePeriodMsgList(const std::string& grpId, uint32_t timeMin,
uint32_t timeMax, std::list<std::string> &msgIds);
GroupInfo *locked_getGroupInfo(const std::string& grpId);
RsDistribMsg *locked_getGroupMsg(const std::string& grpId, const std::string& msgId);
/*!
* for retrieving the grpList for which public keys are available
*/
void getGrpListPubKeyAvailable(std::list<std::string>& grpList);
/* Filter Messages */
/***************************************************************************************/
/***************************** Event Feedback ******************************************/
/***************************************************************************************/
protected:
/*!
* root version (p3Distrib::) of this function must be called
*/
virtual void locked_notifyGroupChanged(GroupInfo &info, uint32_t flags, bool historical);
/*!
* client (inheriting class) should use this to determing behaviour of
* their service when a duplicate msg is found
* @param group should be called when duplicate message loaded
* @param the duplicate message
* @param id
* @param historical: is this msg from an historical cache
* @return successfully executed or not
*/
virtual bool locked_eventDuplicateMsg(GroupInfo *, RsDistribMsg *, const std::string& id, bool historical) = 0;
/*!
* Inheriting class should implement this as a response to a new msg arriving
* @param
* @param
* @param id src of msg (peer id)
* @param historical: is this msg from an historical cache
* @return
*/
virtual bool locked_eventNewMsg(GroupInfo *, RsDistribMsg *, const std::string& id, bool historical) = 0;
/***************************************************************************************/
/********************************* p3Config ********************************************/
/***************************************************************************************/
/* TO FINISH */
protected:
virtual RsSerialiser *setupSerialiser();
virtual bool saveList(bool &cleanup, std::list<RsItem *>& saveList);
virtual void saveDone();
virtual bool loadList(std::list<RsItem *>& load);
/*!
* called by top class, child can use to save configs
*/
virtual std::list<RsItem *> childSaveList() = 0;
/*!
* called by top class, child can use to load configs
*/
virtual bool childLoadList(std::list<RsItem *>& configSaves) = 0;
/***************************************************************************************/
/***************************************************************************************/
public:
virtual int tick(); /* overloaded form pqiService */
/***************************************************************************************/
/**************************** Publish Content ******************************************/
/***************************************************************************************/
/* TO FINISH */
protected:
/* create/mod cache content */
/*!
* adds msg to pending msg map
* @param msg a signed message by peer
*/
void locked_toPublishMsg(RsDistribSignedMsg *msg);
/*!
* adds pending msg
*/
void publishPendingMsgs();
/*!
* sends created groups to cache, to be passed to cache listeners
*/
void publishDistribGroups();
/*!
* removes old caches based on store period (anything that has been in local cache longer
* than the store period is deleted
* @param now the current time when method is called
*/
void clear_local_caches(time_t now);
/*!
* assumes RsDistribMtx is locked when call is made
*/
void locked_publishPendingMsgs();
/*!
* @return cache sub id
*/
uint16_t locked_determineCacheSubId();
/**
* grp keys are backed up when a grp is created this allows user to retrieve lost keys in case config saving fails
* @param grpId the grpId id for which backup keys should be restored
* @return false if failed and vice versa
*/
virtual bool restoreGrpKeys(const std::string& grpId); /// restores a group keys from backup
/**
* Allows user to send keys to a list of peers
* @param grpId the group for which to share public keys
* @param peers The peers to which public keys should be sent
*/
virtual bool sharePubKey(std::string grpId, std::list<std::string>& peers);
/**
* Attempt to receive publication keys
*/
virtual void receivePubKeys();
/**
* Allows group admin(s) to change group icon, description and name
*@param grpId group id
*@param gi the changes to grp name, icon, and description should be reflected here
*/
virtual bool locked_editGroup(std::string grpId, GroupInfo& gi);
/***************************************************************************************/
/***************************************************************************************/
/***************************************************************************************/
/*************************** Overloaded Functions **************************************/
/***************************************************************************************/
/*!
* Overloaded by inherited classes to Pack/UnPack their messages
* @return inherited class's serialiser
*/
virtual RsSerialType *createSerialiser() = 0;
/*! Used to Create/Load Cache Files only
* @param bio binary i/o
* @param src peer id from which write/read content originates
* @param bioflags read write permision for bio
* @return pointer to pqistore instance
*/
virtual pqistore *createStore(BinInterface *bio, const std::string &src, uint32_t bioflags);
virtual bool locked_checkGroupInfo(GroupInfo &info, RsDistribGrp *newGrp);
virtual bool locked_updateGroupInfo(GroupInfo &info, RsDistribGrp *newGrp);
virtual bool locked_checkGroupKeys(GroupInfo &info);
/*!
* @param info group for which admin key will be added to
* @param newKey admin key
* @return true if key successfully added
*/
virtual bool locked_updateGroupAdminKey(GroupInfo &info, RsDistribGrpKey *newKey);
/*!
* @param info group for which publish key will be added to
* @param newKey publish key
* @return true if publish key successfully added
*/
virtual bool locked_updateGroupPublishKey(GroupInfo &info, RsDistribGrpKey *newKey);
/*!
* Use this to retrieve packed message from a signed message
* @param newMsg signed message
* @return pointer to unpacked msg
*/
virtual RsDistribMsg* unpackDistribSignedMsg(RsDistribSignedMsg *newMsg);
/*!
* message is checked to see if it is in a valid time range
* @param info
* @param msg message to be checked
* @return false if msg is outside correct time range
*/
virtual bool locked_checkDistribMsg(GroupInfo &info, RsDistribMsg *msg);
/*!
* chooses the best publish key based on it being full and latest
* @param info group to choose publish key
* @return true if a publish key could be found
*/
virtual bool locked_choosePublishKey(GroupInfo &info);
//virtual RsDistribGrp *locked_createPublicDistribGrp(GroupInfo &info);
//virtual RsDistribGrp *locked_createPrivateDistribGrp(GroupInfo &info);
/***************************************************************************************/
/***************************** Utility Functions ***************************************/
/***************************************************************************************/
/* TO FINISH */
/* utilities */
std::string HashRsItem(const RsItem *item);
bool locked_updateChildTS(GroupInfo &gi, RsDistribMsg *msg);
/***************************************************************************************/
/***************************************************************************************/
/***************************************************************************************/
/***************************** Utility Functions ***************************************/
/***************************************************************************************/
public:
void printGroups(std::ostream &out);
/*!
* returns list of ids for group caches that have changed
*/
bool groupsChanged(std::list<std::string> &groupIds);
/***************************************************************************************/
/***************************************************************************************/
/***************************************************************************************/
/**************************** DummyMsgs Functions **************************************/
/***************************************************************************************/
public:
bool locked_CheckNewMsgDummies(GroupInfo &info, RsDistribMsg *msg, std::string id, bool historical);
bool locked_addDummyMsg(GroupInfo &info, std::string threadId, std::string parentId, std::string msgId, uint32_t ts);
bool locked_clearDummyMsg(GroupInfo &info, std::string msgId);
bool locked_updateDummyChildTS(GroupInfo &gi, std::string parentId, time_t updateTS); // NOTE MUST BE MERGED WITH nromal version.
bool locked_printAllDummyMsgs();
bool locked_printDummyMsgs(GroupInfo &info);
/* access the dummy msgs */
bool getDummyParentMsgList(const std::string& grpId, const std::string& pId, std::list<std::string> &msgIds);
RsDistribDummyMsg *locked_getGroupDummyMsg(const std::string& grpId, const std::string& msgId);
/* key cache functions - we use .... (not overloaded)
*/
/* storage */
protected:
RsMutex distribMtx; /// Protects all class atrributes
std::string mOwnId; /// rs peer id
private:
std::list<GroupCache> mLocalCaches;
std::map<std::string, GroupInfo> mGroups;
uint32_t mStorePeriod, mPubPeriod;
/* Message Publishing */
std::list<RsDistribSignedMsg *> mPendingPublish;
time_t mLastPublishTime;
std::map<uint32_t, uint16_t> mLocalCacheTs;
uint16_t mMaxCacheSubId;
bool mGroupsChanged;
bool mGroupsRepublish;
std::list<RsItem *> saveCleanupList; /* TEMPORARY LIST WHEN SAVING */
std::string mKeyBackUpDir;
const std::string BACKUP_KEY_FILE;
std::map<std::string, RsDistribGrpKey* > mRecvdPubKeys; /// full publishing keys received from users
std::map<std::string, std::list<std::string> > mPendingPubKeyRecipients; /// peers to receive publics key for a given grp
std::set<std::string> mPubKeyAvailableGrpId; // groups id for which public keys are available
time_t mLastKeyPublishTime, mLastRecvdKeyTime;
/**** cache opt ****/
/*
* 1. when rs starts it loads only subscribed groups
* 2. and for unsubscribed groups these are store with their grp to cache mappings
* 3. when user clicks on a group this activates process cache which loads cache for only that group
*
*/
/// stores map of grp to cache mapping
CacheOptData mGrpCacheMap;
/// group subscribed to at start of rs
std::set<std::string> mSubscribedGrp;
/// unsubscribed groups that are already loaded
std::set<std::string> mCacheOptLoaded;
/// current exception group
std::string mCurrGrpException;
};
/***************************************************************************************/
/***************************************************************************************/
#endif // P3_GENERIC_DISTRIB_HEADER

View file

@ -1,478 +0,0 @@
/*
* libretroshare/src/distrib: p3distribverify.cc
*
*
* Copyright 2008-2010 by Robert Fernie
* 2011 Christopher Evi-Parker
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* 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 "p3distribsecurity.h"
#include "pqi/authgpg.h"
#include "retroshare/rsdistrib.h"
#include "retroshare/rspeers.h"
p3DistribSecurity::p3DistribSecurity()
{
}
p3DistribSecurity::~p3DistribSecurity()
{
}
RSA *p3DistribSecurity::extractPublicKey(RsTlvSecurityKey& key)
{
const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data;
long keylen = key.keyData.bin_len;
/* extract admin key */
RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr), keylen);
return rsakey;
}
bool p3DistribSecurity::validateDistribSignedMsg(GroupInfo & info, RsDistribSignedMsg *newMsg)
{
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg()";
std::cerr << std::endl;
std::cerr << "GroupInfo -> distribGrp:";
std::cerr << std::endl;
info.distribGroup->print(std::cerr, 10);
std::cerr << std::endl;
std::cerr << "RsDistribSignedMsg: ";
std::cerr << std::endl;
newMsg->print(std::cerr, 10);
std::cerr << std::endl;
#endif
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() publish KeyId: " << newMsg->publishSignature.keyId << std::endl;
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() personal KeyId: " << newMsg->personalSignature.keyId << std::endl;
#endif
/********************* check signature *******************/
/* find the right key */
RsTlvSecurityKeySet &keyset = info.distribGroup->publishKeys;
std::map<std::string, RsTlvSecurityKey>::iterator kit;
kit = keyset.keys.find(newMsg->publishSignature.keyId);
if (kit == keyset.keys.end())
{
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Missing Publish Key";
std::cerr << std::endl;
#endif
return false;
}
/* check signature timeperiod */
if ((newMsg->timestamp < kit->second.startTS) ||
(newMsg->timestamp > kit->second.endTS))
{
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() TS out of range";
std::cerr << std::endl;
#endif
return false;
}
/* decode key */
const unsigned char *keyptr = (const unsigned char *) kit->second.keyData.bin_data;
long keylen = kit->second.keyData.bin_len;
unsigned int siglen = newMsg->publishSignature.signData.bin_len;
unsigned char *sigbuf = (unsigned char *) newMsg->publishSignature.signData.bin_data;
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Decode Key";
std::cerr << " keylen: " << keylen << " siglen: " << siglen;
std::cerr << std::endl;
#endif
/* extract admin key */
RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr), keylen);
if (!rsakey)
{
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg()";
std::cerr << " Invalid RSA Key";
std::cerr << std::endl;
unsigned long err = ERR_get_error();
std::cerr << "RSA Load Failed .... CODE(" << err << ")" << std::endl;
std::cerr << ERR_error_string(err, NULL) << std::endl;
kit->second.print(std::cerr, 10);
#endif
}
EVP_PKEY *signKey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(signKey, rsakey);
/* calc and check signature */
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_VerifyInit(mdctx, EVP_sha1());
EVP_VerifyUpdate(mdctx, newMsg->packet.bin_data, newMsg->packet.bin_len);
int signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey);
/* clean up */
EVP_PKEY_free(signKey);
EVP_MD_CTX_destroy(mdctx);
/* now verify Personal signature */
if ((signOk == 1) && ((info.grpFlags & RS_DISTRIB_AUTHEN_MASK) & RS_DISTRIB_AUTHEN_REQ))
{
unsigned int personalsiglen =
newMsg->personalSignature.signData.bin_len;
unsigned char *personalsigbuf = (unsigned char *)
newMsg->personalSignature.signData.bin_data;
RsPeerDetails signerDetails;
std::string gpg_fpr;
if (AuthGPG::getAuthGPG()->getGPGDetails(newMsg->personalSignature.keyId, signerDetails))
{
gpg_fpr = signerDetails.fpr;
}
bool gpgSign = AuthGPG::getAuthGPG()->VerifySignBin(
newMsg->packet.bin_data, newMsg->packet.bin_len,
personalsigbuf, personalsiglen, gpg_fpr);
if (gpgSign) {
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Success for gpg signature." << std::endl;
#endif
signOk = 1;
} else {
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Fail for gpg signature." << std::endl;
#endif
signOk = 0;
}
}
if (signOk == 1)
{
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Signature OK";
std::cerr << std::endl;
#endif
return true;
}
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Signature invalid";
std::cerr << std::endl;
#endif
return false;
}
std::string p3DistribSecurity::getBinDataSign(void *data, int len)
{
unsigned char *tmp = (unsigned char *) data;
// copy first CERTSIGNLEN bytes...
if (len > CERTSIGNLEN)
{
len = CERTSIGNLEN;
}
std::string id;
for(uint32_t i = 0; i < CERTSIGNLEN; i++)
{
rs_sprintf_append(id, "%02x", (uint16_t) (((uint8_t *) (tmp))[i]));
}
return id;
}
bool p3DistribSecurity::encrypt(void *& out, int & outlen, const void *in, int inlen, EVP_PKEY *privateKey)
{
#ifdef DISTRIB_DEBUG
std::cerr << "p3DistribSecurity::encrypt() " << std::endl;
#endif
RSA *rsa_publish_pub = NULL;
EVP_PKEY *public_key = NULL;
RSA* rsa_publish = EVP_PKEY_get1_RSA(privateKey);
rsa_publish_pub = RSAPublicKey_dup(rsa_publish);
if(rsa_publish_pub != NULL){
public_key = EVP_PKEY_new();
EVP_PKEY_assign_RSA(public_key, rsa_publish_pub);
}else{
#ifdef DISTRIB_DEBUG
std::cerr << "p3DistribSecurity(): Could not generate publish key " << grpId
<< std::endl;
#endif
return false;
}
EVP_CIPHER_CTX ctx;
int eklen, net_ekl;
unsigned char *ek;
unsigned char iv[EVP_MAX_IV_LENGTH];
EVP_CIPHER_CTX_init(&ctx);
int out_currOffset = 0;
int out_offset = 0;
int max_evp_key_size = EVP_PKEY_size(public_key);
ek = (unsigned char*)malloc(max_evp_key_size);
const EVP_CIPHER *cipher = EVP_aes_128_cbc();
int cipher_block_size = EVP_CIPHER_block_size(cipher);
int size_net_ekl = sizeof(net_ekl);
int max_outlen = inlen + cipher_block_size + EVP_MAX_IV_LENGTH + max_evp_key_size + size_net_ekl;
// intialize context and send store encrypted cipher in ek
if(!EVP_SealInit(&ctx, EVP_aes_128_cbc(), &ek, &eklen, iv, &public_key, 1)) return false;
// now assign memory to out accounting for data, and cipher block size, key length, and key length val
out = new unsigned char[inlen + cipher_block_size + size_net_ekl + eklen + EVP_MAX_IV_LENGTH];
net_ekl = htonl(eklen);
memcpy((unsigned char*)out + out_offset, &net_ekl, size_net_ekl);
out_offset += size_net_ekl;
memcpy((unsigned char*)out + out_offset, ek, eklen);
out_offset += eklen;
memcpy((unsigned char*)out + out_offset, iv, EVP_MAX_IV_LENGTH);
out_offset += EVP_MAX_IV_LENGTH;
// now encrypt actual data
if(!EVP_SealUpdate(&ctx, (unsigned char*) out + out_offset, &out_currOffset, (unsigned char*) in, inlen)) return false;
// move along to partial block space
out_offset += out_currOffset;
// add padding
if(!EVP_SealFinal(&ctx, (unsigned char*) out + out_offset, &out_currOffset)) return false;
// move to end
out_offset += out_currOffset;
// make sure offset has not gone passed valid memory bounds
if(out_offset > max_outlen) return false;
// free encrypted key data
free(ek);
outlen = out_offset;
return true;
delete[] ek;
#ifdef DISTRIB_DEBUG
std::cerr << "p3DistribSecurity::encrypt() finished with outlen : " << outlen << std::endl;
#endif
return true;
}
bool p3DistribSecurity::decrypt(void *& out, int & outlen, const void *in, int inlen, EVP_PKEY *privateKey)
{
#ifdef DISTRIB_DEBUG
std::cerr << "p3DistribSecurity::decrypt() " << std::endl;
#endif
EVP_CIPHER_CTX ctx;
int eklen = 0, net_ekl = 0;
unsigned char *ek = NULL;
unsigned char iv[EVP_MAX_IV_LENGTH];
ek = (unsigned char*)malloc(EVP_PKEY_size(privateKey));
EVP_CIPHER_CTX_init(&ctx);
int in_offset = 0, out_currOffset = 0;
int size_net_ekl = sizeof(net_ekl);
memcpy(&net_ekl, (unsigned char*)in, size_net_ekl);
eklen = ntohl(net_ekl);
in_offset += size_net_ekl;
memcpy(ek, (unsigned char*)in + in_offset, eklen);
in_offset += eklen;
memcpy(iv, (unsigned char*)in + in_offset, EVP_MAX_IV_LENGTH);
in_offset += EVP_MAX_IV_LENGTH;
const EVP_CIPHER* cipher = EVP_aes_128_cbc();
if(!EVP_OpenInit(&ctx, cipher, ek, eklen, iv, privateKey)) return false;
out = new unsigned char[inlen - in_offset];
if(!EVP_OpenUpdate(&ctx, (unsigned char*) out, &out_currOffset, (unsigned char*)in + in_offset, inlen - in_offset)) return false;
in_offset += out_currOffset;
outlen += out_currOffset;
if(!EVP_OpenFinal(&ctx, (unsigned char*)out + out_currOffset, &out_currOffset)) return false;
outlen += out_currOffset;
free(ek);
return true;
}
std::string p3DistribSecurity::getRsaKeySign(RSA *pubkey)
{
int len = BN_num_bytes(pubkey -> n);
unsigned char tmp[len];
BN_bn2bin(pubkey -> n, tmp);
// copy first CERTSIGNLEN bytes...
if (len > CERTSIGNLEN)
{
len = CERTSIGNLEN;
}
std::string id;
for(uint32_t i = 0; i < CERTSIGNLEN; i++)
{
rs_sprintf_append(id, "%02x", (uint16_t) (((uint8_t *) (tmp))[i]));
}
return id;
}
bool p3DistribSecurity::validateDistribGrp(RsDistribGrp *newGrp)
{
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::validateDistribGrp()";
std::cerr << std::endl;
#endif
/* check signature */
RsSerialType *serialType = new RsDistribSerialiser();
/* copy out signature (shallow copy) */
RsTlvKeySignature tmpSign = newGrp->adminSignature;
unsigned char *sigbuf = (unsigned char *) tmpSign.signData.bin_data;
unsigned int siglen = tmpSign.signData.bin_len;
/* clear signature */
newGrp->adminSignature.TlvClear();
uint32_t size = serialType->size(newGrp);
char* data = new char[size];
serialType->serialise(newGrp, data, &size);
const unsigned char *keyptr = (const unsigned char *) newGrp->adminKey.keyData.bin_data;
long keylen = newGrp->adminKey.keyData.bin_len;
/* extract admin key */
RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr), keylen);
EVP_PKEY *key = EVP_PKEY_new();
EVP_PKEY_assign_RSA(key, rsakey);
/* calc and check signature */
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_VerifyInit(mdctx, EVP_sha1());
EVP_VerifyUpdate(mdctx, data, size);
int ans = EVP_VerifyFinal(mdctx, sigbuf, siglen, key);
/* restore signature */
newGrp->adminSignature = tmpSign;
tmpSign.TlvClear();
/* clean up */
EVP_PKEY_free(key);
delete serialType;
EVP_MD_CTX_destroy(mdctx);
delete[] data;
if (ans == 1)
return true;
#ifdef DISTRIB_DEBUG
std::cerr << "p3GroupDistrib::validateDistribGrp() Signature invalid";
std::cerr << std::endl;
#endif
return false;
}
void p3DistribSecurity::setRSAPublicKey(RsTlvSecurityKey & key, RSA *rsa_pub)
{
unsigned char data[10240]; /* more than enough space */
unsigned char *ptr = data;
int reqspace = i2d_RSAPublicKey(rsa_pub, &ptr);
key.keyData.setBinData(data, reqspace);
std::string keyId = getRsaKeySign(rsa_pub);
key.keyId = keyId;
}
void p3DistribSecurity::setRSAPrivateKey(RsTlvSecurityKey & key, RSA *rsa_priv)
{
unsigned char data[10240]; /* more than enough space */
unsigned char *ptr = data;
int reqspace = i2d_RSAPrivateKey(rsa_priv, &ptr);
key.keyData.setBinData(data, reqspace);
std::string keyId = getRsaKeySign(rsa_priv);
key.keyId = keyId;
}
RSA *p3DistribSecurity::extractPrivateKey(RsTlvSecurityKey & key)
{
const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data;
long keylen = key.keyData.bin_len;
/* extract admin key */
RSA *rsakey = d2i_RSAPrivateKey(NULL, &(keyptr), keylen);
return rsakey;
}

View file

@ -1,132 +0,0 @@
/*
* libretroshare/src/distrib: p3distribverify.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2008-2010 by Robert Fernie
* 2011 Christopher Evi-Parker
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* 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".
*
*/
#ifndef P3DISTRIBVERIFY_H_
#define P3DISTRIBVERIFY_H_
#include "serialiser/rstlvkeys.h"
#include "distrib/p3distrib.h"
#include <openssl/ssl.h>
#include <openssl/evp.h>
/*!
* This contains functionality for performing security
* operations needed to validate data received in p3GroupDistrib
* Also has functionality to receive data
*/
class p3DistribSecurity {
public:
p3DistribSecurity();
~p3DistribSecurity();
/*!
* extracts the public key from an RsTlvSecurityKey
* @param key RsTlvSecurityKey to extract public RSA key from
* @return pointer to the public RSA key if successful, null otherwise
*/
static RSA *extractPublicKey(RsTlvSecurityKey &key);
/*!
* extracts the public key from an RsTlvSecurityKey
* @param key RsTlvSecurityKey to extract private RSA key from
* @return pointer to the private RSA key if successful, null otherwise
*/
static RSA *extractPrivateKey(RsTlvSecurityKey &key);
/*!
* stores the rsa public key in a RsTlvSecurityKey
* @param key RsTlvSecurityKey to store the public rsa key in
* @param rsa_pub
*/
static void setRSAPublicKey(RsTlvSecurityKey &key, RSA *rsa_pub);
/*!
* stores the rsa private key in a RsTlvSecurityKey
* @param key stores the rsa private key in a RsTlvSecurityKey
* @param rsa_priv the rsa private key to store
*/
static void setRSAPrivateKey(RsTlvSecurityKey &key, RSA *rsa_priv);
/*!
* extracts signature from RSA key
* @param pubkey
* @return signature of RSA key in hex format
*/
static std::string getRsaKeySign(RSA *pubkey);
/*!
* extracts the signature and stores it in a string
* in hex format
* @param data
* @param len
* @return
*/
static std::string getBinDataSign(void *data, int len);
/*!
* Encrypts data using envelope encryption (taken from open ssl's evp_sealinit )
* only full publish key holders can encrypt data for given group
*@param out
*@param outlen
*@param in
*@param inlen
*/
static bool encrypt(void *&out, int &outlen, const void *in, int inlen, EVP_PKEY *privateKey);
/**
* Decrypts data using evelope decryption (taken from open ssl's evp_sealinit )
* only full publish key holders can decrypt data for a group
* @param out where decrypted data is written to
* @param outlen
* @param in
* @param inlen
* @return false if encryption failed
*/
static bool decrypt(void *&out, int &outlen, const void *in, int inlen, EVP_PKEY *privateKey);
/*!
* uses grp signature to check if group has been
* tampered with
* @param newGrp
* @return true if group valid false otherwise
*/
static bool validateDistribGrp(RsDistribGrp *newGrp);
/*!
* uses groupinfo public key to verify signature of signed message
* @param info groupinfo for which msg is meant for
* @param msg
* @return false if verfication of signature is not passed
*/
static bool validateDistribSignedMsg(GroupInfo &info, RsDistribSignedMsg *msg);
};
#endif /* P3DISTRIBVERIFY_H_ */

View file

@ -64,10 +64,6 @@ class ftDataSend
virtual bool sendChunkMapRequest(const std::string& peer_id,const std::string& hash,bool is_client) = 0;
virtual bool sendChunkMap(const std::string& peer_id,const std::string& hash,const CompressedChunkMap& cmap,bool is_client) = 0;
/// Send a request for a chunk crc map
virtual bool sendCRC32MapRequest(const std::string& peer_id,const std::string& hash) = 0;
/// Send a chunk crc map
virtual bool sendCRC32Map(const std::string& peer_id,const std::string& hash,const CRC32Map& crc_map) = 0;
/// Send a request for a chunk crc map
virtual bool sendSingleChunkCRCRequest(const std::string& peer_id,const std::string& hash,uint32_t chunk_number) = 0;
/// Send a chunk crc map
@ -94,11 +90,6 @@ class ftDataRecv
/// Send a chunk map
virtual bool recvChunkMap(const std::string& peer_id,const std::string& hash,const CompressedChunkMap& cmap,bool is_client) = 0;
/// Send a request for a chunk map
virtual bool recvCRC32MapRequest(const std::string& peer_id,const std::string& hash) = 0;
/// Send a chunk map
virtual bool recvCRC32Map(const std::string& peer_id,const std::string& hash,const CRC32Map& crcmap) = 0;
virtual bool recvSingleChunkCRCRequest(const std::string& peer_id,const std::string& hash,uint32_t chunk_id) = 0;
virtual bool recvSingleChunkCRC(const std::string& peer_id,const std::string& hash,uint32_t chunk_id,const Sha1CheckSum& sum) = 0;

View file

@ -60,7 +60,7 @@ const uint32_t FT_DATA = 0x0001; // data cuhnk to be stored
const uint32_t FT_DATA_REQ = 0x0002; // data request to be treated
const uint32_t FT_CLIENT_CHUNK_MAP_REQ = 0x0003; // chunk map request to be treated by client
const uint32_t FT_SERVER_CHUNK_MAP_REQ = 0x0004; // chunk map request to be treated by server
const uint32_t FT_CRC32MAP_REQ = 0x0005; // crc32 map request to be treated by server
//const uint32_t FT_CRC32MAP_REQ = 0x0005; // crc32 map request to be treated by server
const uint32_t FT_CLIENT_CHUNK_CRC_REQ = 0x0006; // chunk sha1 crc request to be treated
ftRequest::ftRequest(uint32_t type, std::string peerId, std::string hash, uint64_t size, uint64_t offset, uint32_t chunk, void *data)
@ -273,19 +273,6 @@ bool ftDataMultiplex::recvChunkMapRequest(const std::string& peerId, const std::
return true;
}
bool ftDataMultiplex::recvCRC32MapRequest(const std::string& peerId, const std::string& hash)
{
#ifdef MPLEX_DEBUG
std::cerr << "ftDataMultiplex::recvChunkMapRequest() Server Recv";
std::cerr << std::endl;
#endif
/* Store in Queue */
RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/
mRequestQueue.push_back(ftRequest(FT_CRC32MAP_REQ,peerId,hash,0,0,0,NULL));
return true;
}
bool ftDataMultiplex::recvSingleChunkCRCRequest(const std::string& peerId, const std::string& hash,uint32_t chunk_number)
{
#ifdef MPLEX_DEBUG
@ -299,27 +286,6 @@ bool ftDataMultiplex::recvSingleChunkCRCRequest(const std::string& peerId, const
return true;
}
class CRC32Thread: public RsThread
{
public:
CRC32Thread(ftDataMultiplex *dataplex,const std::string& peerId,const std::string& hash)
: _plex(dataplex),_finished(false),_peerId(peerId),_hash(hash) {}
virtual void run()
{
#ifdef MPLEX_DEBUG
std::cerr << "CRC32Thread is running for file " << _hash << std::endl;
#endif
_plex->computeAndSendCRC32Map(_peerId,_hash) ;
_finished = true ;
}
bool finished() { return _finished ; }
private:
ftDataMultiplex *_plex ;
bool _finished ;
std::string _peerId ;
std::string _hash ;
};
/*********** BACKGROUND THREAD OPERATIONS ***********/
bool ftDataMultiplex::workQueued()
@ -341,7 +307,6 @@ bool ftDataMultiplex::workQueued()
bool ftDataMultiplex::doWork()
{
bool doRequests = true;
time_t now = time(NULL) ;
/* Handle All the current Requests */
while(doRequests)
@ -396,14 +361,6 @@ bool ftDataMultiplex::doWork()
handleRecvServerChunkMapRequest(req.mPeerId,req.mHash) ;
break ;
case FT_CRC32MAP_REQ:
#ifdef MPLEX_DEBUG
std::cerr << "ftDataMultiplex::doWork() Handling FT_CLIENT_CRC32_MAP_REQ";
std::cerr << std::endl;
#endif
handleRecvCRC32MapRequest(req.mPeerId,req.mHash) ;
break ;
case FT_CLIENT_CHUNK_CRC_REQ:
#ifdef MPLEX_DEBUG
std::cerr << "ftDataMultiplex::doWork() Handling FT_CLIENT_CHUNK_CRC_REQ";
@ -421,47 +378,6 @@ bool ftDataMultiplex::doWork()
}
}
// Look for potentially finished CRC32Map threads, and destroys them.
{
RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/
for(std::list<CRC32Thread*>::iterator lit(_crc32map_threads.begin());lit!=_crc32map_threads.end();)
if((*lit)->finished())
{
std::cerr << "ftDataMultiplex::doWork: thread " << *lit << " ended. Deleting it." << std::endl;
(*lit)->join() ;
delete (*lit) ;
std::list<CRC32Thread*>::iterator tmp(lit) ;
++lit ;
_crc32map_threads.erase(tmp) ;
}
else
{
std::cerr << "ftDataMultiplex::doWork: thread " << *lit << " still working. Not quitting it." << std::endl;
++lit ;
}
// Take the opportunity to cleanup the list, so that it cannot grow indefinitely
#ifdef MPLEX_DEBUG
std::cerr << "ftDataMultiplex::doWork: Cleaning up list of cached maps." << std::endl ;
#endif
// Keep CRC32 maps in cache for 30 mins max.
//
for(std::map<std::string,std::pair<time_t,CRC32Map> >::iterator it = _cached_crc32maps.begin();it!=_cached_crc32maps.end();)
if(it->second.first + 30*60 < now)
{
std::cerr << "Removing cached map for file " << it->first << " that was kept for too long now." << std::endl;
std::map<std::string,std::pair<time_t,CRC32Map> >::iterator tmp(it) ;
++it ;
_cached_crc32maps.erase(tmp) ;
}
else
++it ;
}
/* Only Handle One Search Per Period....
* Lower Priority
*/
@ -583,27 +499,6 @@ bool ftDataMultiplex::dispatchReceivedChunkCheckSum()
return true ;
}
bool ftDataMultiplex::recvCRC32Map(const std::string& /*peerId*/, const std::string& hash,const CRC32Map& crc_map)
{
RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/
std::map<std::string, ftClient>::iterator it = mClients.find(hash);
if(it == mClients.end())
{
std::cerr << "ftDataMultiplex::recvCRCMap() ERROR: No matching Client for CRC32map. This is an error. " << hash << " !" << std::endl;
/* error */
return false;
}
#ifdef MPLEX_DEBUG
std::cerr << "ftDataMultiplex::recvCRCMap() Passing crc map of file " << hash << ", to FT Module" << std::endl;
#endif
(it->second).mModule->addCRC32Map(crc_map);
return true ;
}
// A chunk map has arrived. It can be two different situations:
// - an uploader has sent his chunk map, so we need to store it in the corresponding ftFileProvider
// - a source for a download has sent his chunk map, so we need to send it to the corresponding ftFileCreator.
@ -654,152 +549,6 @@ bool ftDataMultiplex::recvChunkMap(const std::string& peerId, const std::string&
return false;
}
bool ftDataMultiplex::handleRecvCRC32MapRequest(const std::string& peerId, const std::string& hash)
{
bool found = false ;
CRC32Map cmap ;
// 1 - look into cache
#ifdef MPLEX_DEBUG
std::cerr << "ftDataMultiplex::handleRecvChunkMapReq() : source " << peerId << " asked for CRC32 map for file " << hash << std::endl;
#endif
{
RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/
std::map<std::string,std::pair<time_t,CRC32Map> >::iterator it = _cached_crc32maps.find(hash) ;
if(it != _cached_crc32maps.end())
{
cmap = it->second.second ;
it->second.first = time(NULL) ; // update time stamp
found = true ;
#ifdef MPLEX_DEBUG
std::cerr << "ftDataMultiplex::handleRecvChunkMapReq() : CRC32 map found in cache !!" << std::endl;
#endif
}
}
if(found)
{
#ifdef MPLEX_DEBUG
std::cerr << "File CRC32 map was obtained successfully. Sending it." << std::endl ;
#endif
mDataSend->sendCRC32Map(peerId,hash,cmap);
return true ;
}
else
{
std::cerr << "File CRC32 Not found. Computing it." << std::endl ;
{
RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/
if(_crc32map_threads.size() > 1)
{
std::cerr << "Too many threads already computing CRC32Maps (2 is the current maximum)! Giving up." << std::endl;
return false ;
}
}
CRC32Thread *thread = new CRC32Thread(this,peerId,hash);
{
RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/
_crc32map_threads.push_back(thread) ;
}
thread->start() ;
return true ;
}
}
bool ftDataMultiplex::computeAndSendCRC32Map(const std::string& peerId, const std::string& hash)
{
bool found ;
std::map<std::string, ftFileProvider *>::iterator it ;
std::string filename ;
uint64_t filesize =0;
// 1 - look into the list of servers
{
RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/
it = mServers.find(hash) ;
if(it == mServers.end())
found = false ;
}
// 2 - if not found, create a server.
//
if(!found)
{
#ifdef MPLEX_DEBUG
std::cerr << "ftDataMultiplex::handleRecvChunkMapReq() ERROR: No matching file Provider for hash " << hash ;
std::cerr << std::endl;
#endif
if(!handleSearchRequest(peerId,hash))
return false ;
#ifdef MPLEX_DEBUG
std::cerr << "ftDataMultiplex::handleRecvChunkMapReq() A new file Provider has been made up for hash " << hash ;
std::cerr << std::endl;
#endif
}
{
RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/
it = mServers.find(hash) ;
if(it == mServers.end()) // handleSearchRequest should have filled mServers[hash], but we have been off-mutex since,
{
std::cerr << "Could definitely not find a provider for file " << hash << ". Maybe the file does not exist?" << std::endl;
return false ; // so it's safer to check again.
}
else
{
filesize = it->second->fileSize() ;
filename = it->second->fileName() ;
}
}
#ifdef MPLEX_DEBUG
std::cerr << "Computing CRC32Map for file " << filename << ", hash=" << hash << ", size=" << filesize << std::endl;
#endif
FILE *fd = RsDirUtil::rs_fopen(filename.c_str(),"rb") ;
if(fd == NULL)
{
std::cerr << "Could not open file " << filename << " for read!! CRC32Map computation cancelled." << std::endl ;
return false ;
}
CRC32Map cmap ;
if(!RsDirUtil::crc32File(fd,filesize,ChunkMap::CHUNKMAP_FIXED_CHUNK_SIZE,cmap))
{
std::cerr << "CRC32Map computation failed." << std::endl ;
fclose(fd) ;
return false ;
}
fclose(fd) ;
{
RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/
std::cerr << "File CRC32 was successfully computed. Storing it into cache." << std::endl ;
_cached_crc32maps[hash] = std::pair<time_t,CRC32Map>(time(NULL),cmap) ;
}
#ifdef MPLEX_DEBUG
std::cerr << "File CRC32 was successfully computed. Sending it." << std::endl ;
#endif
mDataSend->sendCRC32Map(peerId,hash,cmap);
return true ;
}
bool ftDataMultiplex::handleRecvClientChunkMapRequest(const std::string& peerId, const std::string& hash)
{
CompressedChunkMap cmap ;
@ -1152,10 +901,6 @@ bool ftDataMultiplex::sendChunkMapRequest(const std::string& peer_id,const std::
{
return mDataSend->sendChunkMapRequest(peer_id,hash,is_client);
}
bool ftDataMultiplex::sendCRC32MapRequest(const std::string& peer_id,const std::string& hash)
{
return mDataSend->sendCRC32MapRequest(peer_id,hash);
}
bool ftDataMultiplex::sendSingleChunkCRCRequests(const std::string& hash, const std::vector<uint32_t>& to_ask)
{
RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/

View file

@ -36,7 +36,6 @@ class ftTransferModule;
class ftFileProvider;
class ftFileCreator;
class ftSearch;
class CRC32Thread;
#include <string>
#include <list>
@ -121,11 +120,6 @@ class ftDataMultiplex: public ftDataRecv, public RsQueueThread
/* Server/client Send */
bool sendChunkMapRequest(const std::string& peerId, const std::string& hash,bool is_client) ;
/* Client Send */
bool sendCRC32MapRequest(const std::string& peerId, const std::string& hash) ;
/* called from a separate thread */
bool computeAndSendCRC32Map(const std::string& peerId, const std::string& hash) ;
/* called from a separate thread */
bool sendSingleChunkCRCRequests(const std::string& hash, const std::vector<uint32_t>& to_ask) ;
@ -143,10 +137,6 @@ class ftDataMultiplex: public ftDataRecv, public RsQueueThread
virtual bool recvChunkMapRequest(const std::string& peer_id,const std::string& hash,bool is_client) ;
/// Receive a chunk map
virtual bool recvChunkMap(const std::string& peer_id,const std::string& hash,const CompressedChunkMap& cmap,bool is_client) ;
/// Receive a CRC map
virtual bool recvCRC32Map(const std::string& peer_id,const std::string& hash,const CRC32Map& crc_map) ;
/// Receive a CRC map request
virtual bool recvCRC32MapRequest(const std::string& peer_id,const std::string& hash) ;
virtual bool recvSingleChunkCRCRequest(const std::string& peer_id,const std::string& hash,uint32_t chunk_id) ;
virtual bool recvSingleChunkCRC(const std::string& peer_id,const std::string& hash,uint32_t chunk_id,const Sha1CheckSum& sum) ;
@ -170,7 +160,6 @@ class ftDataMultiplex: public ftDataRecv, public RsQueueThread
bool handleSearchRequest(const std::string& peerId, const std::string& hash);
bool handleRecvClientChunkMapRequest(const std::string& peerId, const std::string& hash) ;
bool handleRecvServerChunkMapRequest(const std::string& peerId, const std::string& hash) ;
bool handleRecvCRC32MapRequest(const std::string& peerId, const std::string& hash) ;
bool handleRecvChunkCrcRequest(const std::string& peerId, const std::string& hash,uint32_t chunk_id) ;
/* We end up doing the actual server job here */
@ -185,9 +174,6 @@ class ftDataMultiplex: public ftDataRecv, public RsQueueThread
std::list<ftRequest> mSearchQueue;
// std::map<std::string, time_t> mUnknownHashs;
std::list<CRC32Thread *> _crc32map_threads ;
std::map<std::string,std::pair<time_t,CRC32Map> > _cached_crc32maps ;
std::map<std::string,Sha1CacheEntry> _cached_sha1maps ; // one cache entry per file hash. Handled dynamically.
ftDataSend *mDataSend;

View file

@ -52,23 +52,29 @@ const int ftserverzone = 29539;
#include "pqi/pqi.h"
#include "pqi/p3linkmgr.h"
#include "serialiser/rsfiletransferitems.h"
#include "serialiser/rsserviceids.h"
/***
* #define SERVER_DEBUG 1
* #define DEBUG_TICK 1
* #define SERVER_DEBUG 1
* #define SERVER_DEBUG_CACHE 1
***/
static const time_t FILE_TRANSFER_LOW_PRIORITY_TASKS_PERIOD = 5 ; // low priority tasks handling every 5 seconds
/* Setup */
ftServer::ftServer(p3PeerMgr *pm, p3LinkMgr *lm)
: mP3iface(NULL), mPeerMgr(pm),
: p3Service(RS_SERVICE_TYPE_FILE_TRANSFER),
mPeerMgr(pm),
mLinkMgr(lm),
mCacheStrapper(NULL),
mFiStore(NULL), mFiMon(NULL),
mFtController(NULL), mFtExtra(NULL),
mFtDataplex(NULL), mFtSearch(NULL), srvMutex("ftServer")
{
mCacheStrapper = new ftCacheStrapper(lm);
mCacheStrapper = new ftCacheStrapper(lm);
addSerialType(new RsFileTransferSerialiser()) ;
}
void ftServer::setConfigDirectory(std::string path)
@ -88,11 +94,6 @@ void ftServer::setConfigDirectory(std::string path)
RsDirUtil::checkCreateDirectory(remotecachedir) ;
}
void ftServer::setP3Interface(P3Interface *pqi)
{
mP3iface = pqi;
}
/* Control Interface */
/* add Config Items (Extra, Controller) */
@ -182,16 +183,10 @@ void ftServer::StartupThreads()
/* Dataplex */
mFtDataplex->start();
/* start own thread */
start();
}
void ftServer::StopThreads()
{
/* stop own thread */
join();
/* stop Dataplex */
mFtDataplex->join();
@ -228,31 +223,22 @@ CacheTransfer *ftServer::getCacheTransfer()
return mFtController;
}
void ftServer::run()
/***************************************************************/
/********************** RsFiles Interface **********************/
/***************************************************************/
/***************************************************************/
/********************** Controller Access **********************/
/***************************************************************/
bool ftServer::ResumeTransfers()
{
while(isRunning())
{
mFtDataplex->deleteUnusedServers() ;
mFtDataplex->handlePendingCrcRequests() ;
mFtDataplex->dispatchReceivedChunkCheckSum() ;
#ifdef WIN32
Sleep(5000);
#else
sleep(5);
#endif
}
mFtController->activate();
return true;
}
/***************************************************************/
/********************** RsFiles Interface **********************/
/***************************************************************/
/***************************************************************/
/********************** Controller Access **********************/
/***************************************************************/
bool ftServer::checkHash(const std::string& hash,std::string& error_string)
{
static const uint32_t HASH_LENGTH = 40 ;
@ -465,15 +451,11 @@ RsTurtleGenericTunnelItem *ftServer::deserialiseItem(void *data,uint32_t size) c
#ifdef SERVER_DEBUG
std::cerr << "p3turtle: deserialising packet: " << std::endl ;
#endif
#ifdef SERVER_DEBUG
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_TYPE_TURTLE != getRsItemService(rstype)))
{
#ifdef SERVER_DEBUG
std::cerr << " Wrong type !!" << std::endl ;
#endif
return NULL; /* wrong type */
}
#endif
switch(getRsItemSubType(rstype))
{
@ -857,10 +839,15 @@ bool ftServer::shareDownloadDirectory(bool share)
/**************** Config Interface *****************************/
/***************************************************************/
/* Key Functions to be overloaded for Full Configuration */
/* Key Functions to be overloaded for Full Configuration */
RsSerialiser *ftServer::setupSerialiser()
{
return NULL;
RsSerialiser *rss = new RsSerialiser ;
rss->addSerialType(new RsFileTransferSerialiser) ;
//rss->addSerialType(new RsGeneralConfigSerialiser());
return rss ;
}
bool ftServer::saveList(bool &/*cleanup*/, std::list<RsItem *>& /*list*/)
@ -887,6 +874,9 @@ bool ftServer::loadConfigMap(std::map<std::string, std::string> &/*configMap*/)
/* Client Send */
bool ftServer::sendDataRequest(const std::string& peerId, const std::string& hash, uint64_t size, uint64_t offset, uint32_t chunksize)
{
#ifdef SERVER_DEBUG
std::cerr << "ftServer::sendDataRequest() to peer " << peerId << " for hash " << hash << ", offset=" << offset << ", chunk size="<< chunksize << std::endl;
#endif
if(mTurtleRouter->isTurtlePeer(peerId))
{
RsTurtleFileRequestItem *item = new RsTurtleFileRequestItem ;
@ -898,9 +888,10 @@ bool ftServer::sendDataRequest(const std::string& peerId, const std::string& has
}
else
{
std::cerr << "ftServer::sendDataRequest() " <<std::endl;
/* create a packet */
/* push to networking part */
RsFileRequest *rfi = new RsFileRequest();
RsFileTransferDataRequestItem *rfi = new RsFileTransferDataRequestItem();
/* id */
rfi->PeerId(peerId);
@ -913,7 +904,7 @@ bool ftServer::sendDataRequest(const std::string& peerId, const std::string& has
rfi->fileoffset = offset; /* ftr->offset; */
rfi->chunksize = chunksize; /* ftr->chunk; */
mP3iface->SendFileRequest(rfi);
sendItem(rfi);
}
return true;
@ -921,6 +912,9 @@ bool ftServer::sendDataRequest(const std::string& peerId, const std::string& has
bool ftServer::sendChunkMapRequest(const std::string& peerId,const std::string& hash,bool is_client)
{
#ifdef SERVER_DEBUG
std::cerr << "ftServer::sendChunkMapRequest() to peer " << peerId << " for hash " << hash << std::endl;
#endif
if(mTurtleRouter->isTurtlePeer(peerId))
{
RsTurtleFileMapRequestItem *item = new RsTurtleFileMapRequestItem ;
@ -930,7 +924,7 @@ bool ftServer::sendChunkMapRequest(const std::string& peerId,const std::string&
{
/* create a packet */
/* push to networking part */
RsFileChunkMapRequest *rfi = new RsFileChunkMapRequest();
RsFileTransferChunkMapRequestItem *rfi = new RsFileTransferChunkMapRequestItem();
/* id */
rfi->PeerId(peerId);
@ -939,7 +933,7 @@ bool ftServer::sendChunkMapRequest(const std::string& peerId,const std::string&
rfi->hash = hash; /* ftr->hash; */
rfi->is_client = is_client ;
mP3iface->SendFileChunkMapRequest(rfi);
sendItem(rfi);
}
return true ;
@ -947,6 +941,9 @@ bool ftServer::sendChunkMapRequest(const std::string& peerId,const std::string&
bool ftServer::sendChunkMap(const std::string& peerId,const std::string& hash,const CompressedChunkMap& map,bool is_client)
{
#ifdef SERVER_DEBUG
std::cerr << "ftServer::sendChunkMap() to peer " << peerId << " for hash " << hash << std::endl;
#endif
if(mTurtleRouter->isTurtlePeer(peerId))
{
RsTurtleFileMapItem *item = new RsTurtleFileMapItem ;
@ -957,7 +954,7 @@ bool ftServer::sendChunkMap(const std::string& peerId,const std::string& hash,co
{
/* create a packet */
/* push to networking part */
RsFileChunkMap *rfi = new RsFileChunkMap();
RsFileTransferChunkMapItem *rfi = new RsFileTransferChunkMapItem();
/* id */
rfi->PeerId(peerId);
@ -967,38 +964,17 @@ bool ftServer::sendChunkMap(const std::string& peerId,const std::string& hash,co
rfi->is_client = is_client; /* ftr->hash; */
rfi->compressed_map = map; /* ftr->hash; */
mP3iface->SendFileChunkMap(rfi);
sendItem(rfi);
}
return true ;
}
bool ftServer::sendCRC32MapRequest(const std::string& peerId,const std::string& hash)
{
if(mTurtleRouter->isTurtlePeer(peerId))
{
RsTurtleFileCrcRequestItem *item = new RsTurtleFileCrcRequestItem;
mTurtleRouter->sendTurtleData(peerId,item) ;
}
else
{
/* create a packet */
/* push to networking part */
RsFileCRC32MapRequest *rfi = new RsFileCRC32MapRequest();
/* id */
rfi->PeerId(peerId);
/* file info */
rfi->hash = hash; /* ftr->hash; */
mP3iface->SendFileCRC32MapRequest(rfi);
}
return true ;
}
bool ftServer::sendSingleChunkCRCRequest(const std::string& peerId,const std::string& hash,uint32_t chunk_number)
{
#ifdef SERVER_DEBUG
std::cerr << "ftServer::sendSingleCRCRequest() to peer " << peerId << " for hash " << hash << ", chunk number=" << chunk_number << std::endl;
#endif
if(mTurtleRouter->isTurtlePeer(peerId))
{
RsTurtleChunkCrcRequestItem *item = new RsTurtleChunkCrcRequestItem;
@ -1010,7 +986,7 @@ bool ftServer::sendSingleChunkCRCRequest(const std::string& peerId,const std::st
{
/* create a packet */
/* push to networking part */
RsFileSingleChunkCrcRequest *rfi = new RsFileSingleChunkCrcRequest();
RsFileTransferSingleChunkCrcRequestItem *rfi = new RsFileTransferSingleChunkCrcRequestItem();
/* id */
rfi->PeerId(peerId);
@ -1019,41 +995,17 @@ bool ftServer::sendSingleChunkCRCRequest(const std::string& peerId,const std::st
rfi->hash = hash; /* ftr->hash; */
rfi->chunk_number = chunk_number ;
mP3iface->SendFileSingleChunkCrcRequest(rfi);
sendItem(rfi);
}
return true ;
}
bool ftServer::sendCRC32Map(const std::string& peerId,const std::string& hash,const CRC32Map& crcmap)
{
if(mTurtleRouter->isTurtlePeer(peerId))
{
RsTurtleFileCrcItem *item = new RsTurtleFileCrcItem ;
item->crc_map = crcmap ;
mTurtleRouter->sendTurtleData(peerId,item) ;
}
else
{
/* create a packet */
/* push to networking part */
RsFileCRC32Map *rfi = new RsFileCRC32Map();
/* id */
rfi->PeerId(peerId);
/* file info */
rfi->hash = hash; /* ftr->hash; */
rfi->crc_map = crcmap; /* ftr->hash; */
mP3iface->SendFileCRC32Map(rfi);
}
return true ;
}
bool ftServer::sendSingleChunkCRC(const std::string& peerId,const std::string& hash,uint32_t chunk_number,const Sha1CheckSum& crc)
{
#ifdef SERVER_DEBUG
std::cerr << "ftServer::sendSingleCRC() to peer " << peerId << " for hash " << hash << ", chunk number=" << chunk_number << std::endl;
#endif
if(mTurtleRouter->isTurtlePeer(peerId))
{
RsTurtleChunkCrcItem *item = new RsTurtleChunkCrcItem;
@ -1066,7 +1018,7 @@ bool ftServer::sendSingleChunkCRC(const std::string& peerId,const std::string& h
{
/* create a packet */
/* push to networking part */
RsFileSingleChunkCrc *rfi = new RsFileSingleChunkCrc();
RsFileTransferSingleChunkCrcItem *rfi = new RsFileTransferSingleChunkCrcItem();
/* id */
rfi->PeerId(peerId);
@ -1076,16 +1028,12 @@ bool ftServer::sendSingleChunkCRC(const std::string& peerId,const std::string& h
rfi->check_sum = crc;
rfi->chunk_number = chunk_number;
mP3iface->SendFileSingleChunkCrc(rfi);
sendItem(rfi);
}
return true ;
}
//const uint32_t MAX_FT_CHUNK = 32 * 1024; /* 32K */
//const uint32_t MAX_FT_CHUNK = 16 * 1024; /* 16K */
const uint32_t MAX_FT_CHUNK = 8 * 1024; /* 16K */
/* Server Send */
bool ftServer::sendData(const std::string& peerId, const std::string& hash, uint64_t size, uint64_t baseoffset, uint32_t chunksize, void *data)
{
@ -1106,6 +1054,11 @@ bool ftServer::sendData(const std::string& peerId, const std::string& hash, uint
while(tosend > 0)
{
//static const uint32_t MAX_FT_CHUNK = 32 * 1024; /* 32K */
//static const uint32_t MAX_FT_CHUNK = 16 * 1024; /* 16K */
//
static const uint32_t MAX_FT_CHUNK = 8 * 1024; /* 16K */
/* workout size */
chunk = MAX_FT_CHUNK;
if (chunk > tosend)
@ -1135,7 +1088,7 @@ bool ftServer::sendData(const std::string& peerId, const std::string& hash, uint
}
else
{
RsFileData *rfd = new RsFileData();
RsFileTransferDataItem *rfd = new RsFileTransferDataItem();
/* set id */
rfd->PeerId(peerId);
@ -1153,7 +1106,7 @@ bool ftServer::sendData(const std::string& peerId, const std::string& hash, uint
/* file data */
rfd->fd.binData.setBinData( &(((uint8_t *) data)[offset]), chunk);
mP3iface->SendFileData(rfd);
sendItem(rfd);
/* print the data pointer */
#ifdef SERVER_DEBUG
@ -1176,6 +1129,8 @@ bool ftServer::sendData(const std::string& peerId, const std::string& hash, uint
return true;
}
// Dont delete the item. The client (p3turtle) is doing it after calling this.
//
void ftServer::receiveTurtleData(RsTurtleGenericTunnelItem *i,
const std::string& hash,
const std::string& virtual_peer_id,
@ -1186,6 +1141,9 @@ void ftServer::receiveTurtleData(RsTurtleGenericTunnelItem *i,
case RS_TURTLE_SUBTYPE_FILE_REQUEST:
{
RsTurtleFileRequestItem *item = dynamic_cast<RsTurtleFileRequestItem *>(i) ;
#ifdef SERVER_DEBUG
std::cerr << "ftServer::receiveTurtleData(): received file data request for " << hash << " from peer " << virtual_peer_id << std::endl;
#endif
getMultiplexer()->recvDataRequest(virtual_peer_id,hash,0,item->chunk_offset,item->chunk_size) ;
}
break ;
@ -1193,6 +1151,9 @@ void ftServer::receiveTurtleData(RsTurtleGenericTunnelItem *i,
case RS_TURTLE_SUBTYPE_FILE_DATA :
{
RsTurtleFileDataItem *item = dynamic_cast<RsTurtleFileDataItem *>(i) ;
#ifdef SERVER_DEBUG
std::cerr << "ftServer::receiveTurtleData(): received file data for " << hash << " from peer " << virtual_peer_id << std::endl;
#endif
getMultiplexer()->recvData(virtual_peer_id,hash,0,item->chunk_offset,item->chunk_size,item->chunk_data) ;
item->chunk_data = NULL ; // this prevents deletion in the destructor of RsFileDataItem, because data will be deleted
@ -1204,33 +1165,29 @@ void ftServer::receiveTurtleData(RsTurtleGenericTunnelItem *i,
case RS_TURTLE_SUBTYPE_FILE_MAP :
{
RsTurtleFileMapItem *item = dynamic_cast<RsTurtleFileMapItem *>(i) ;
#ifdef SERVER_DEBUG
std::cerr << "ftServer::receiveTurtleData(): received chunk map for hash " << hash << " from peer " << virtual_peer_id << std::endl;
#endif
getMultiplexer()->recvChunkMap(virtual_peer_id,hash,item->compressed_map,direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT) ;
}
break ;
case RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST:
{
RsTurtleFileMapRequestItem *item = dynamic_cast<RsTurtleFileMapRequestItem *>(i) ;
//RsTurtleFileMapRequestItem *item = dynamic_cast<RsTurtleFileMapRequestItem *>(i) ;
#ifdef SERVER_DEBUG
std::cerr << "ftServer::receiveTurtleData(): received chunkmap request for hash " << hash << " from peer " << virtual_peer_id << std::endl;
#endif
getMultiplexer()->recvChunkMapRequest(virtual_peer_id,hash,direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT) ;
}
break ;
case RS_TURTLE_SUBTYPE_FILE_CRC :
{
RsTurtleFileCrcItem *item = dynamic_cast<RsTurtleFileCrcItem *>(i) ;
getMultiplexer()->recvCRC32Map(virtual_peer_id,hash,item->crc_map) ;
}
break ;
case RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST:
{
getMultiplexer()->recvCRC32MapRequest(virtual_peer_id,hash) ;
}
break ;
case RS_TURTLE_SUBTYPE_CHUNK_CRC :
{
RsTurtleChunkCrcItem *item = dynamic_cast<RsTurtleChunkCrcItem *>(i) ;
#ifdef SERVER_DEBUG
std::cerr << "ftServer::receiveTurtleData(): received single chunk CRC for hash " << hash << " from peer " << virtual_peer_id << std::endl;
#endif
getMultiplexer()->recvSingleChunkCRC(virtual_peer_id,hash,item->chunk_number,item->check_sum) ;
}
break ;
@ -1238,6 +1195,9 @@ void ftServer::receiveTurtleData(RsTurtleGenericTunnelItem *i,
case RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST:
{
RsTurtleChunkCrcRequestItem *item = dynamic_cast<RsTurtleChunkCrcRequestItem *>(i) ;
#ifdef SERVER_DEBUG
std::cerr << "ftServer::receiveTurtleData(): received single chunk CRC request for hash " << hash << " from peer " << virtual_peer_id << std::endl;
#endif
getMultiplexer()->recvSingleChunkCRCRequest(virtual_peer_id,hash,item->chunk_number) ;
}
break ;
@ -1246,358 +1206,189 @@ void ftServer::receiveTurtleData(RsTurtleGenericTunnelItem *i,
}
}
/* NB: The rsCore lock must be activated before calling this.
* This Lock should be moved lower into the system...
* most likely destination is in ftServer.
*/
int ftServer::tick()
{
rslog(RSL_DEBUG_BASIC, ftserverzone,
"filedexserver::tick()");
bool moreToTick = false ;
if (mP3iface == NULL)
if(handleIncoming())
moreToTick = true;
if(handleCacheData())
moreToTick = true;
static time_t last_law_priority_tasks_handling_time = 0 ;
time_t now = time(NULL) ;
if(last_law_priority_tasks_handling_time + FILE_TRANSFER_LOW_PRIORITY_TASKS_PERIOD < now)
{
#ifdef SERVER_DEBUG
std::cerr << "ftServer::tick() ERROR: mP3iface == NULL";
#endif
last_law_priority_tasks_handling_time = now ;
rslog(RSL_DEBUG_BASIC, ftserverzone,
"filedexserver::tick() Invalid Interface()");
return 1;
mFtDataplex->deleteUnusedServers() ;
mFtDataplex->handlePendingCrcRequests() ;
mFtDataplex->dispatchReceivedChunkCheckSum() ;
}
int moreToTick = 0;
if (0 < mP3iface -> tick())
{
moreToTick = 1;
#ifdef DEBUG_TICK
std::cerr << "filedexserver::tick() moreToTick from mP3iface" << std::endl;
#endif
}
if (0 < handleInputQueues())
{
moreToTick = 1;
#ifdef DEBUG_TICK
std::cerr << "filedexserver::tick() moreToTick from InputQueues" << std::endl;
#endif
}
return moreToTick;
}
// This function needs to be divided up.
bool ftServer::handleInputQueues()
{
bool moreToTick = false;
if (handleCacheData())
moreToTick = true;
if (handleFileData())
moreToTick = true;
return moreToTick;
}
bool ftServer::handleCacheData()
bool ftServer::handleCacheData()
{
// get all the incoming results.. and print to the screen.
RsCacheRequest *cr;
RsCacheItem *ci;
std::list<std::pair<RsPeerId, RsCacheData> > cacheUpdates;
std::list<std::pair<RsPeerId, RsCacheData> >::iterator it;
int i=0 ;
// Loop through Search Results.
int i = 0;
int i_init = 0;
#ifdef SERVER_DEBUG
//std::cerr << "ftServer::handleCacheData()" << std::endl;
#ifdef SERVER_DEBUG_CACHE
std::cerr << "handleCacheData() " << std::endl;
#endif
while((ci = mP3iface -> GetSearchResult()) != NULL)
mCacheStrapper->getCacheUpdates(cacheUpdates);
for(it = cacheUpdates.begin(); it != cacheUpdates.end(); it++)
{
/* construct reply */
RsFileTransferCacheItem *ci = new RsFileTransferCacheItem();
#ifdef SERVER_DEBUG
std::cerr << "ftServer::handleCacheData() Recvd SearchResult (CacheResponse!)" << std::endl;
std::string out;
if (i++ == i_init)
{
out += "Recieved Search Results:\n";
}
ci -> print_string(out);
rslog(RSL_DEBUG_BASIC, ftserverzone, out);
/* id from incoming */
ci -> PeerId(it->first);
ci -> file.hash = (it->second).hash;
ci -> file.name = (it->second).name;
ci -> file.path = ""; // (it->second).path;
ci -> file.filesize = (it->second).size;
ci -> cacheType = (it->second).cid.type;
ci -> cacheSubId = (it->second).cid.subid;
#ifdef SERVER_DEBUG_CACHE
std::string out2 = "Outgoing CacheStrapper Update -> RsCacheItem:\n";
ci -> print_string(out2);
std::cerr << out2 << std::endl;
#endif
/* these go to the CacheStrapper! */
RsCacheData data;
data.pid = ci->PeerId();
data.cid = CacheId(ci->cacheType, ci->cacheSubId);
data.path = ci->file.path;
data.name = ci->file.name;
data.hash = ci->file.hash;
data.size = ci->file.filesize;
data.recvd = time(NULL) ;
sendItem(ci);
mCacheStrapper->recvCacheResponse(data, time(NULL));
delete ci;
i++;
}
// now requested Searches.
i_init = i;
while((cr = mP3iface -> RequestedSearch()) != NULL)
{
#ifdef SERVER_DEBUG
/* just delete these */
std::string out = "Requested Search:\n";
cr -> print_string(out);
rslog(RSL_DEBUG_BASIC, ftserverzone, out);
#endif
delete cr;
}
// Now handle it replacement (pushed cache results)
{
std::list<std::pair<RsPeerId, RsCacheData> > cacheUpdates;
std::list<std::pair<RsPeerId, RsCacheData> >::iterator it;
mCacheStrapper->getCacheUpdates(cacheUpdates);
for(it = cacheUpdates.begin(); it != cacheUpdates.end(); it++)
{
/* construct reply */
RsCacheItem *ci = new RsCacheItem();
/* id from incoming */
ci -> PeerId(it->first);
ci -> file.hash = (it->second).hash;
ci -> file.name = (it->second).name;
ci -> file.path = ""; // (it->second).path;
ci -> file.filesize = (it->second).size;
ci -> cacheType = (it->second).cid.type;
ci -> cacheSubId = (it->second).cid.subid;
#ifdef SERVER_DEBUG
std::string out2 = "Outgoing CacheStrapper Update -> RsCacheItem:\n";
ci -> print_string(out2);
std::cerr << out2 << std::endl;
#endif
//rslog(RSL_DEBUG_BASIC, ftserverzone, out2.str());
mP3iface -> SendSearchResult(ci);
i++;
}
}
return (i > 0);
return i>0 ;
}
bool ftServer::handleFileData()
int ftServer::handleIncoming()
{
// now File Input.
RsFileRequest *fr;
RsFileData *fd;
RsFileChunkMapRequest *fcmr;
RsFileChunkMap *fcm;
RsFileCRC32MapRequest *fccrcmr;
RsFileCRC32Map *fccrcm;
RsFileSingleChunkCrcRequest *fscrcr;
RsFileSingleChunkCrc *fscrc;
int nhandled = 0 ;
int i_init = 0;
int i = 0;
i_init = i;
while((fr = mP3iface -> GetFileRequest()) != NULL )
{
RsItem *item = NULL ;
#ifdef SERVER_DEBUG
std::cerr << "ftServer::handleFileData() Recvd ftFiler Request" << std::endl;
std::string out;
if (i == i_init)
{
out += "Incoming(Net) File Item:\n";
}
fr -> print_string(out);
rslog(RSL_DEBUG_BASIC, ftserverzone, out);
std::cerr << "ftServer::handleIncoming() " << std::endl;
#endif
i++; /* count */
mFtDataplex->recvDataRequest(fr->PeerId(),
fr->file.hash, fr->file.filesize,
fr->fileoffset, fr->chunksize);
FileInfo(ffr);
delete fr;
}
// now File Data.
i_init = i;
while((fd = mP3iface -> GetFileData()) != NULL )
while(NULL != (item = recvItem()))
{
#ifdef SERVER_DEBUG
std::cerr << "ftServer::handleFileData() Recvd ftFiler Data" << std::endl;
std::cerr << "hash: " << fd->fd.file.hash;
std::cerr << " length: " << fd->fd.binData.bin_len;
std::cerr << " data: " << fd->fd.binData.bin_data;
std::cerr << std::endl;
nhandled++ ;
std::string out;
if (i == i_init)
switch(item->PacketSubType())
{
out += "Incoming(Net) File Data:\n";
}
fd -> print_string(out);
rslog(RSL_DEBUG_BASIC, ftserverzone, out);
#endif
i++; /* count */
/* incoming data */
mFtDataplex->recvData(fd->PeerId(),
fd->fd.file.hash, fd->fd.file.filesize,
fd->fd.file_offset,
fd->fd.binData.bin_len,
fd->fd.binData.bin_data);
/* we've stolen the data part -> so blank before delete
*/
fd->fd.binData.TlvShallowClear();
delete fd;
}
// now file chunkmap requests
i_init = i;
while((fcmr = mP3iface -> GetFileChunkMapRequest()) != NULL )
{
case RS_PKT_SUBTYPE_FT_DATA_REQUEST:
{
RsFileTransferDataRequestItem *f = dynamic_cast<RsFileTransferDataRequestItem*>(item) ;
#ifdef SERVER_DEBUG
std::cerr << "ftServer::handleFileData() Recvd ChunkMap request" << std::endl;
std::string out;
if (i == i_init)
{
out += "Incoming(Net) File Data:\n";
}
fcmr -> print_string(out);
rslog(RSL_DEBUG_BASIC, ftserverzone, out);
std::cerr << "ftServer::handleIncoming: received data request for hash " << f->file.hash << ", offset=" << f->fileoffset << ", chunk size=" << f->chunksize << std::endl;
#endif
i++; /* count */
mFtDataplex->recvDataRequest(f->PeerId(), f->file.hash, f->file.filesize, f->fileoffset, f->chunksize);
}
break ;
/* incoming data */
mFtDataplex->recvChunkMapRequest(fcmr->PeerId(), fcmr->hash,fcmr->is_client) ;
delete fcmr;
}
// now file chunkmaps
i_init = i;
while((fcm = mP3iface -> GetFileChunkMap()) != NULL )
{
case RS_PKT_SUBTYPE_FT_DATA:
{
RsFileTransferDataItem *f = dynamic_cast<RsFileTransferDataItem*>(item) ;
#ifdef SERVER_DEBUG
std::cerr << "ftServer::handleFileData() Recvd ChunkMap request" << std::endl;
std::string out;
if (i == i_init)
{
out += "Incoming(Net) File Data:\n";
}
fcm -> print_string(out);
rslog(RSL_DEBUG_BASIC, ftserverzone, out);
std::cerr << "ftServer::handleIncoming: received data for hash " << f->fd.file.hash << ", offset=" << f->fd.file_offset << ", chunk size=" << f->fd.binData.bin_len << std::endl;
#endif
i++; /* count */
mFtDataplex->recvData(f->PeerId(), f->fd.file.hash, f->fd.file.filesize, f->fd.file_offset, f->fd.binData.bin_len, f->fd.binData.bin_data);
/* incoming data */
mFtDataplex->recvChunkMap(fcm->PeerId(), fcm->hash,fcm->compressed_map,fcm->is_client) ;
/* we've stolen the data part -> so blank before delete
*/
f->fd.binData.TlvShallowClear();
}
break ;
delete fcm;
}
// now file chunkmap requests
i_init = i;
while((fccrcmr = mP3iface -> GetFileCRC32MapRequest()) != NULL )
{
case RS_PKT_SUBTYPE_FT_CHUNK_MAP_REQUEST:
{
RsFileTransferChunkMapRequestItem *f = dynamic_cast<RsFileTransferChunkMapRequestItem*>(item) ;
#ifdef SERVER_DEBUG
std::cerr << "ftServer::handleFileData() Recvd ChunkMap request" << std::endl;
std::string out;
if (i == i_init)
{
out += "Incoming(Net) File Data:\n";
}
fccrcmr -> print_string(out);
rslog(RSL_DEBUG_BASIC, ftserverzone, out);
std::cerr << "ftServer::handleIncoming: received chunkmap request for hash " << f->hash << ", client=" << f->is_client << std::endl;
#endif
i++; /* count */
mFtDataplex->recvChunkMapRequest(f->PeerId(), f->hash,f->is_client) ;
}
break ;
/* incoming data */
mFtDataplex->recvCRC32MapRequest(fccrcmr->PeerId(), fccrcmr->hash) ;
delete fccrcmr;
}
// now file chunkmaps
i_init = i;
while((fccrcm = mP3iface -> GetFileCRC32Map()) != NULL )
{
case RS_PKT_SUBTYPE_FT_CHUNK_MAP:
{
RsFileTransferChunkMapItem *f = dynamic_cast<RsFileTransferChunkMapItem*>(item) ;
#ifdef SERVER_DEBUG
std::cerr << "ftServer::handleFileData() Recvd ChunkMap request" << std::endl;
std::string out;
if (i == i_init)
{
out += "Incoming(Net) File Data:\n";
}
fccrcm -> print_string(out);
rslog(RSL_DEBUG_BASIC, ftserverzone, out);
std::cerr << "ftServer::handleIncoming: received chunkmap for hash " << f->hash << ", client=" << f->is_client << /*", map=" << f->compressed_map <<*/ std::endl;
#endif
i++; /* count */
mFtDataplex->recvChunkMap(f->PeerId(), f->hash,f->compressed_map,f->is_client) ;
}
break ;
/* incoming data */
mFtDataplex->recvCRC32Map(fccrcm->PeerId(), fccrcm->hash,fccrcm->crc_map);
delete fccrcm;
}
// now file chunk crc requests
i_init = i;
while((fscrcr = mP3iface -> GetFileSingleChunkCrcRequest()) != NULL )
{
case RS_PKT_SUBTYPE_FT_CHUNK_CRC_REQUEST:
{
RsFileTransferSingleChunkCrcRequestItem *f = dynamic_cast<RsFileTransferSingleChunkCrcRequestItem*>(item) ;
#ifdef SERVER_DEBUG
std::cerr << "ftServer::handleFileData() Recvd ChunkMap request" << std::endl;
std::string out;
if (i == i_init)
{
out += "Incoming(Net) File CRC Request:\n";
}
fscrcr -> print_string(out);
rslog(RSL_DEBUG_BASIC, ftserverzone, out);
std::cerr << "ftServer::handleIncoming: received single chunk crc req for hash " << f->hash << ", chunk number=" << f->chunk_number << std::endl;
#endif
i++; /* count */
mFtDataplex->recvSingleChunkCRCRequest(f->PeerId(), f->hash,f->chunk_number) ;
}
break ;
/* incoming data */
mFtDataplex->recvSingleChunkCRCRequest(fscrcr->PeerId(), fscrcr->hash,fscrcr->chunk_number) ;
delete fscrcr;
}
// now file chunkmaps
i_init = i;
while((fscrc = mP3iface -> GetFileSingleChunkCrc()) != NULL )
{
case RS_PKT_SUBTYPE_FT_CHUNK_CRC:
{
RsFileTransferSingleChunkCrcItem *f = dynamic_cast<RsFileTransferSingleChunkCrcItem *>(item) ;
#ifdef SERVER_DEBUG
std::cerr << "ftServer::handleFileData() Recvd ChunkMap request" << std::endl;
std::string out;
if (i == i_init)
{
out += "Incoming(Net) File Data:\n";
}
fscrc -> print_string(out);
rslog(RSL_DEBUG_BASIC, ftserverzone, out);
std::cerr << "ftServer::handleIncoming: received single chunk crc req for hash " << f->hash << ", chunk number=" << f->chunk_number << ", checksum = " << f->check_sum << std::endl;
#endif
i++; /* count */
mFtDataplex->recvSingleChunkCRC(f->PeerId(), f->hash,f->chunk_number,f->check_sum);
}
break ;
/* incoming data */
mFtDataplex->recvSingleChunkCRC(fscrc->PeerId(), fscrc->hash,fscrc->chunk_number,fscrc->check_sum);
case RS_PKT_SUBTYPE_FT_CACHE_ITEM:
{
RsFileTransferCacheItem *ci = dynamic_cast<RsFileTransferCacheItem*>(item) ;
#ifdef SERVER_DEBUG_CACHE
std::cerr << "ftServer::handleIncoming: received cache item hash=" << ci->file.hash << ". from peer " << ci->PeerId() << std::endl;
#endif
/* these go to the CacheStrapper! */
RsCacheData data;
data.pid = ci->PeerId();
data.cid = CacheId(ci->cacheType, ci->cacheSubId);
data.path = ci->file.path;
data.name = ci->file.name;
data.hash = ci->file.hash;
data.size = ci->file.filesize;
data.recvd = time(NULL) ;
delete fscrcr;
mCacheStrapper->recvCacheResponse(data, time(NULL));
}
break ;
// case RS_PKT_SUBTYPE_FT_CACHE_REQUEST:
// {
// // do nothing
// RsFileTransferCacheRequestItem *cr = dynamic_cast<RsFileTransferCacheRequestItem*>(item) ;
//#ifdef SERVER_DEBUG_CACHE
// std::cerr << "ftServer::handleIncoming: received cache request from peer " << cr->PeerId() << std::endl;
//#endif
// }
// break ;
}
delete item ;
}
if (i > 0)
{
return 1;
}
return 0;
return nhandled;
}
/**********************************
@ -1617,10 +1408,3 @@ bool ftServer::addConfiguration(p3ConfigMgr *cfgmgr)
return true;
}
bool ftServer::ResumeTransfers()
{
mFtController->activate();
return true;
}

View file

@ -45,6 +45,7 @@
#include "ft/ftdata.h"
#include "turtle/turtleclientservice.h"
#include "services/p3service.h"
#include "retroshare/rsfiles.h"
//#include "dbase/cachestrapper.h"
@ -73,7 +74,7 @@ class ftDwlQueue;
class p3PeerMgr;
class p3LinkMgr;
class ftServer: public RsFiles, public ftDataSend, public RsTurtleClientService, public RsThread
class ftServer: public p3Service, public RsFiles, public ftDataSend, public RsTurtleClientService
{
public:
@ -87,8 +88,6 @@ class ftServer: public RsFiles, public ftDataSend, public RsTurtleClientService,
/* Assign important variables */
void setConfigDirectory(std::string path);
void setP3Interface(P3Interface *pqi);
/* add Config Items (Extra, Controller) */
void addConfigComponents(p3ConfigMgr *mgr);
@ -101,12 +100,6 @@ class ftServer: public RsFiles, public ftDataSend, public RsTurtleClientService,
void SetupFtServer() ;
virtual void connectToTurtleRouter(p3turtle *p) ;
void StartupThreads();
void StopThreads();
/* own thread */
virtual void run();
// Checks that the given hash is well formed. Used to chase
// string bugs.
static bool checkHash(const std::string& hash,std::string& error_string) ;
@ -125,6 +118,9 @@ class ftServer: public RsFiles, public ftDataSend, public RsTurtleClientService,
/************** (Implements RsFiles) ***************************/
/***************************************************************/
void StartupThreads();
void StopThreads();
// member access
ftDataMultiplex *getMultiplexer() const { return mFtDataplex ; }
@ -238,8 +234,6 @@ class ftServer: public RsFiles, public ftDataSend, public RsTurtleClientService,
virtual bool sendDataRequest(const std::string& peerId, const std::string& hash, uint64_t size, uint64_t offset, uint32_t chunksize);
virtual bool sendChunkMapRequest(const std::string& peer_id,const std::string& hash,bool is_client) ;
virtual bool sendChunkMap(const std::string& peer_id,const std::string& hash,const CompressedChunkMap& cmap,bool is_client) ;
virtual bool sendCRC32MapRequest(const std::string&, const std::string&) ;
virtual bool sendCRC32Map(const std::string&, const std::string&, const CRC32Map&) ;
virtual bool sendSingleChunkCRCRequest(const std::string& peer_id,const std::string& hash,uint32_t chunk_number) ;
virtual bool sendSingleChunkCRC(const std::string& peer_id,const std::string& hash,uint32_t chunk_number,const Sha1CheckSum& crc) ;
@ -250,17 +244,12 @@ class ftServer: public RsFiles, public ftDataSend, public RsTurtleClientService,
bool addConfiguration(p3ConfigMgr *cfgmgr);
bool ResumeTransfers();
private:
bool handleInputQueues();
bool handleCacheData();
bool handleFileData();
/******************* p3 Config Overload ************************/
protected:
/* Key Functions to be overloaded for Full Configuration */
virtual RsSerialiser *setupSerialiser();
virtual bool saveList(bool &cleanup, std::list<RsItem *>&);
virtual bool loadList(std::list<RsItem *>& load);
virtual bool loadList(std::list<RsItem *>& load);
private:
bool loadConfigMap(std::map<std::string, std::string> &configMap);
@ -268,6 +257,10 @@ class ftServer: public RsFiles, public ftDataSend, public RsTurtleClientService,
/*************************** p3 Config Overload ********************/
protected:
int handleIncoming() ;
bool handleCacheData() ;
private:
/**** INTERNAL FUNCTIONS ***/
@ -279,9 +272,6 @@ class ftServer: public RsFiles, public ftDataSend, public RsTurtleClientService,
/* no need for Mutex protection -
* as each component is protected independently.
*/
P3Interface *mP3iface; /* XXX THIS NEEDS PROTECTION */
p3PeerMgr *mPeerMgr;
p3LinkMgr *mLinkMgr;
@ -295,7 +285,6 @@ class ftServer: public RsFiles, public ftDataSend, public RsTurtleClientService,
ftDataMultiplex *mFtDataplex;
p3turtle *mTurtleRouter ;
ftFileSearch *mFtSearch;
ftDwlQueue *mFtDwlQueue;
@ -304,7 +293,6 @@ class ftServer: public RsFiles, public ftDataSend, public RsTurtleClientService,
std::string mConfigPath;
std::string mDownloadPath;
std::string mPartialsPath;
};

View file

@ -530,9 +530,6 @@ int ftTransferModule::tick()
case FT_TM_FLAG_CHECKING: // Check if file hash matches the hashed data
checkFile() ;
break ;
case FT_TM_FLAG_CHUNK_CRC: // File is waiting for CRC32 map. Check if received, and re-set matched chunks
checkCRC() ;
break ;
default:
break;
}
@ -648,171 +645,6 @@ void ftTransferModule::forceCheck()
mFileStatus.stat = ftFileStatus::PQIFILE_DOWNLOADING;
}
bool ftTransferModule::checkCRC()
{
// We have a finite state machine here.
//
// The states are, for each chunk, and what should be done:
// DONT_HAVE
// -> ask for the chunk CRC
// ASKED
// -> do nothing
// RECEIVED
// -> check the chunk
// CHECKED
// -> do nothing
//
// CRCs are asked by group of CRC_REQUEST_MAX_SIZE chunks at a time. The response may contain a different
// number of CRCs, depending on the availability.
//
// Server side:
// - Only complete files can compute CRCs, as the CRCs of downloaded chunks in an unchecked file are un-verified.
// - CRCs of files are cached, so that they don't get computed twice.
//
#ifdef FT_DEBUG
std::cerr << "ftTransferModule::checkCRC(): looking for CRC32 map." << std::endl ;
#endif
// Loop over chunks. Collect the ones to ask for, and hash the ones received.
// If we have
//
time_t now = time(NULL) ;
RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/
switch(_crcmap_state)
{
case FT_TM_CRC_MAP_STATE_NOCHECK:
_crcreq_source = "" ;
#ifdef FT_DEBUG
std::cerr << "ftTransferModule::checkCRC(): state is NOCHECK. Doing nothing." << std::endl ;
#endif
break ;
case FT_TM_CRC_MAP_STATE_DONT_HAVE:
{
// Check wether we have a CRC map or not.
//
std::cerr << "FT_TM_CRC_MAP_STATE_ASKED: last time is " << _crcmap_last_asked_time << std::endl ;
std::cerr << "FT_TM_CRC_MAP_STATE_ASKED: now is " << now << std::endl ;
uint64_t threshold = (uint64_t)(FT_TM_CRC_MAP_MAX_WAIT_PER_GIG * (1+mSize/float(1024ull*1024ull*1024ull))) ;
std::cerr << "Threshold is " << threshold << std::endl;
std::cerr << "Limit is " << (uint64_t)_crcmap_last_asked_time + threshold << std::endl ;
std::cerr << "Requested source is \"" << _crcreq_source << "\"" << std::endl;
if( _crcreq_source != "" && (uint64_t)_crcmap_last_tunnel_keepup + 10 <= (uint64_t)now)
{
#ifdef FT_DEBUG
std::cerr << "ftTransferModule::checkCRC(): sending keepup to source " << _crcreq_source << std::endl ;
#endif
locked_requestData(_crcreq_source,0,(uint32_t)std::min((uint64_t)512,mSize));
_crcmap_last_tunnel_keepup = now ;
}
if( (uint64_t)_crcmap_last_asked_time + threshold > (uint64_t)now)
{
#ifdef FT_DEBUG
std::cerr << "ftTransferModule::checkCRC(): state is NOCHECK. Doing nothing." << std::endl ;
#endif
break ;
}
// Ask the ones we should ask for. We use a very coarse strategy now: we
// send the request to a random source. We'll make this more sensible
// later.
#ifdef FT_DEBUG
std::cerr << "ftTransferModule::checkCRC(): state is DONT_HAVE or last request is too old. Selecting a source for asking a CRC map." << std::endl ;
#endif
if(mFileSources.empty())
{
std::cerr << "ftTransferModule::checkCRC(): No sources available for checking file " << mHash << ": waiting 3 additional sec." <<std::endl ;
_crcmap_last_asked_time = now - threshold + 3 ;
break ;
}
bool found = false ;
for(std::map<std::string,peerInfo>::const_iterator mit = mFileSources.begin();mit != mFileSources.end();++mit)
if(mFileCreator->sourceIsComplete(mit->first))
{
//#ifdef FT_DEBUG
std::cerr << "ftTransferModule::checkCRC(): sending CRC map request to source " << mit->first << std::endl ;
//#endif
_crcmap_last_asked_time = now ;
_crcreq_source = mit->first ;
mMultiplexor->sendCRC32MapRequest(mit->first,mHash);
found = true ;
break ;
}
}
break ;
case FT_TM_CRC_MAP_STATE_HAVE:
{
#ifdef FT_DEBUG
std::cerr << "ftTransferModule::checkCRC(): got a CRC32 map. Matching chunks..." << std::endl ;
#endif
// The CRCmap is complete. Let's cross check it with existing chunks in ftFileCreator !
//
uint32_t bad_chunks ;
uint32_t incomplete_chunks ;
if(!mFileCreator->crossCheckChunkMap(_crcmap,bad_chunks,incomplete_chunks))
{
std::cerr << "ftTransferModule::checkCRC(): could not check CRC chunks!" << std::endl ;
return false;
}
// go back to download stage, if not all chunks are correct.
//
if(bad_chunks > 0)
{
mFlag = FT_TM_FLAG_DOWNLOADING ;
mFileStatus.stat = ftFileStatus::PQIFILE_DOWNLOADING;
std::cerr << "ftTransferModule::checkCRC(): Done. File has errors: " << bad_chunks << " bad chunks found. Restarting download for these chunks only." << std::endl ;
}
else if(incomplete_chunks > 0)
{
mFlag = FT_TM_FLAG_DOWNLOADING ;
mFileStatus.stat = ftFileStatus::PQIFILE_DOWNLOADING;
#ifdef FT_DEBUG
std::cerr << "ftTransferModule::checkCRC(): Done. all chunks ok. Continuing download for remaining chunks." << std::endl ;
#endif
}
else
{
// We do as if the file is not complete. This way, it finishes properly.
//
//mFlag = FT_TM_FLAG_COMPLETE ; // Transfer is complete.
mFlag = FT_TM_FLAG_DOWNLOADING ;
mFileStatus.stat = ftFileStatus::PQIFILE_DOWNLOADING;
#ifdef FT_DEBUG
std::cerr << "ftTransferModule::checkCRC(): Done. CRC check is ok, file is complete." << std::endl ;
#endif
}
_crcmap_state = FT_TM_CRC_MAP_STATE_NOCHECK ;
_crcreq_source = "" ;
}
}
return true ;
}
void ftTransferModule::addCRC32Map(const CRC32Map& crc_map)
{
RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/
// Note: for now, we only send complete CRC32 maps, so the crc_map is always complete. When we
// send partial CRC maps, we will have to check them for completness.
//
_crcmap_state = FT_TM_CRC_MAP_STATE_HAVE ;
_crcmap = crc_map ;
}
void ftTransferModule::adjustSpeed()
{
RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/

View file

@ -38,7 +38,7 @@ GxsSecurity::~GxsSecurity()
{
}
RSA *GxsSecurity::extractPublicKey(RsTlvSecurityKey& key)
RSA *GxsSecurity::extractPublicKey(const RsTlvSecurityKey& key)
{
const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data;
long keylen = key.keyData.bin_len;
@ -489,7 +489,7 @@ void GxsSecurity::setRSAPrivateKey(RsTlvSecurityKey & key, RSA *rsa_priv)
key.keyId = keyId;
}
RSA *GxsSecurity::extractPrivateKey(RsTlvSecurityKey & key)
RSA *GxsSecurity::extractPrivateKey(const RsTlvSecurityKey & key)
{
const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data;
long keylen = key.keyData.bin_len;

View file

@ -51,14 +51,14 @@ public:
* @param key RsTlvSecurityKey to extract public RSA key from
* @return pointer to the public RSA key if successful, null otherwise
*/
static RSA *extractPublicKey(RsTlvSecurityKey &key);
static RSA *extractPublicKey(const RsTlvSecurityKey &key);
/*!
* extracts the public key from an RsTlvSecurityKey
* @param key RsTlvSecurityKey to extract private RSA key from
* @return pointer to the private RSA key if successful, null otherwise
*/
static RSA *extractPrivateKey(RsTlvSecurityKey &key);
static RSA *extractPrivateKey(const RsTlvSecurityKey &key);
/*!
* stores the rsa public key in a RsTlvSecurityKey

View file

@ -34,6 +34,8 @@
#define MSG_TABLE_NAME std::string("MESSAGES")
#define GRP_TABLE_NAME std::string("GROUPS")
#define GRP_LAST_POST_UPDATE_TRIGGER std::string("LAST_POST_UPDATE")
// generic
#define KEY_NXS_FILE std::string("nxsFile")
@ -42,12 +44,14 @@
#define KEY_NXS_IDENTITY std::string("identity")
#define KEY_GRP_ID std::string("grpId")
#define KEY_ORIG_GRP_ID std::string("origGrpId")
#define KEY_PARENT_GRP_ID std::string("parentGrpId")
#define KEY_SIGN_SET std::string("signSet")
#define KEY_TIME_STAMP std::string("timeStamp")
#define KEY_NXS_FLAGS std::string("flags")
#define KEY_NXS_META std::string("meta")
#define KEY_NXS_SERV_STRING std::string("serv_str")
#define KEY_NXS_HASH std::string("hash")
#define KEY_RECV_TS std::string("recv_time_stamp")
// grp table columns
@ -111,6 +115,8 @@
#define COL_GRP_INTERN_CIRCLE 18
#define COL_GRP_ORIGINATOR 19
#define COL_GRP_AUTHEN_FLAGS 20
#define COL_PARENT_GRP_ID 21
#define COL_GRP_RECV_TS 22
// msg col numbers
@ -122,6 +128,7 @@
#define COL_THREAD_ID 11
#define COL_MSG_NAME 12
#define COL_MSG_SERV_STRING 13
#define COL_MSG_RECV_TS 14
// generic meta shared col numbers
#define COL_GRP_ID 0
@ -154,7 +161,7 @@ RsDataService::RsDataService(const std::string &serviceDir, const std::string &d
msgMetaColumns.push_back(KEY_SIGN_SET); msgMetaColumns.push_back(KEY_NXS_IDENTITY); msgMetaColumns.push_back(KEY_NXS_HASH);
msgMetaColumns.push_back(KEY_MSG_ID); msgMetaColumns.push_back(KEY_ORIG_MSG_ID); msgMetaColumns.push_back(KEY_MSG_STATUS);
msgMetaColumns.push_back(KEY_CHILD_TS); msgMetaColumns.push_back(KEY_MSG_PARENT_ID); msgMetaColumns.push_back(KEY_MSG_THREAD_ID);
msgMetaColumns.push_back(KEY_MSG_NAME); msgMetaColumns.push_back(KEY_NXS_SERV_STRING);
msgMetaColumns.push_back(KEY_MSG_NAME); msgMetaColumns.push_back(KEY_NXS_SERV_STRING); msgMetaColumns.push_back(KEY_RECV_TS);
// for retrieving actual data
msgColumns.push_back(KEY_GRP_ID); msgColumns.push_back(KEY_NXS_FILE); msgColumns.push_back(KEY_NXS_FILE_OFFSET);
@ -168,7 +175,8 @@ RsDataService::RsDataService(const std::string &serviceDir, const std::string &d
grpMetaColumns.push_back(KEY_GRP_LAST_POST); grpMetaColumns.push_back(KEY_ORIG_GRP_ID); grpMetaColumns.push_back(KEY_NXS_SERV_STRING);
grpMetaColumns.push_back(KEY_GRP_SIGN_FLAGS); grpMetaColumns.push_back(KEY_GRP_CIRCLE_ID); grpMetaColumns.push_back(KEY_GRP_CIRCLE_TYPE);
grpMetaColumns.push_back(KEY_GRP_INTERNAL_CIRCLE); grpMetaColumns.push_back(KEY_GRP_ORIGINATOR);
grpMetaColumns.push_back(KEY_GRP_AUTHEN_FLAGS);
grpMetaColumns.push_back(KEY_GRP_AUTHEN_FLAGS); grpMetaColumns.push_back(KEY_PARENT_GRP_ID); grpMetaColumns.push_back(KEY_RECV_TS);
// for retrieving actual grp data
grpColumns.push_back(KEY_GRP_ID); grpColumns.push_back(KEY_NXS_FILE); grpColumns.push_back(KEY_NXS_FILE_OFFSET);
@ -177,6 +185,8 @@ RsDataService::RsDataService(const std::string &serviceDir, const std::string &d
// for retrieving msg offsets
mMsgOffSetColumns.push_back(KEY_MSG_ID); mMsgOffSetColumns.push_back(KEY_NXS_FILE_OFFSET);
mMsgOffSetColumns.push_back(KEY_NXS_FILE_LEN);
grpIdColumn.push_back(KEY_GRP_ID);
}
RsDataService::~RsDataService(){
@ -210,6 +220,7 @@ void RsDataService::initialise(){
KEY_MSG_NAME + " TEXT," +
KEY_NXS_SERV_STRING + " TEXT," +
KEY_NXS_HASH + " TEXT," +
KEY_RECV_TS + " INT," +
KEY_NXS_FILE_LEN + " INT);");
// create table for grp data
@ -238,8 +249,16 @@ void RsDataService::initialise(){
KEY_GRP_INTERNAL_CIRCLE + " TEXT," +
KEY_GRP_ORIGINATOR + " TEXT," +
KEY_NXS_HASH + " TEXT," +
KEY_RECV_TS + " INT," +
KEY_PARENT_GRP_ID + " TEXT," +
KEY_SIGN_SET + " BLOB);");
mDb->execSQL("CREATE TRIGGER " + GRP_LAST_POST_UPDATE_TRIGGER +
" INSERT ON " + MSG_TABLE_NAME +
std::string(" BEGIN ") +
" UPDATE " + GRP_TABLE_NAME + " SET " + KEY_GRP_LAST_POST + "= new."
+ KEY_RECV_TS + " WHERE " + KEY_GRP_ID + "=new." + KEY_GRP_ID + ";"
+ std::string("END;"));
}
RsGxsGrpMetaData* RsDataService::locked_getGrpMeta(RetroCursor &c)
@ -291,8 +310,11 @@ RsGxsGrpMetaData* RsDataService::locked_getGrpMeta(RetroCursor &c)
c.getString(COL_GRP_INTERN_CIRCLE, grpMeta->mInternalCircle);
c.getString(COL_GRP_ORIGINATOR, grpMeta->mOriginator);
grpMeta->mAuthenFlags = c.getInt32(COL_GRP_AUTHEN_FLAGS);
grpMeta->mRecvTS = c.getInt32(COL_GRP_RECV_TS);
c.getString(COL_PARENT_GRP_ID, grpMeta->mParentGrpId);
if(ok)
return grpMeta;
else
@ -377,6 +399,7 @@ RsGxsMsgMetaData* RsDataService::locked_getMsgMeta(RetroCursor &c)
c.getString(COL_MSG_NAME, msgMeta->mMsgName);
c.getString(COL_MSG_SERV_STRING, msgMeta->mServiceString);
c.getString(COL_HASH, msgMeta->mHash);
msgMeta->recvTS = c.getInt32(COL_MSG_RECV_TS);
offset = 0;
data = (char*)c.getData(COL_SIGN_SET, data_len);
@ -489,6 +512,7 @@ int RsDataService::storeMessage(std::map<RsNxsMsg *, RsGxsMsgMetaData *> &msg)
cv.put(KEY_GRP_ID, msgMetaPtr->mGroupId);
cv.put(KEY_NXS_SERV_STRING, msgMetaPtr->mServiceString);
cv.put(KEY_NXS_HASH, msgMetaPtr->mHash);
cv.put(KEY_RECV_TS, (int32_t)msgMetaPtr->recvTS);
char signSetData[msgMetaPtr->signSet.TlvSize()];
@ -595,7 +619,9 @@ int RsDataService::storeGroup(std::map<RsNxsGrp *, RsGxsGrpMetaData *> &grp)
cv.put(KEY_GRP_INTERNAL_CIRCLE, grpMetaPtr->mInternalCircle);
cv.put(KEY_GRP_ORIGINATOR, grpMetaPtr->mOriginator);
cv.put(KEY_GRP_AUTHEN_FLAGS, (int32_t)grpMetaPtr->mAuthenFlags);
cv.put(KEY_PARENT_GRP_ID, grpMetaPtr->mParentGrpId);
cv.put(KEY_NXS_HASH, grpMetaPtr->mHash);
cv.put(KEY_RECV_TS, (int32_t)grpMetaPtr->mRecvTS);
if(! (grpMetaPtr->mAuthorId.empty()) ){
cv.put(KEY_NXS_IDENTITY, grpMetaPtr->mAuthorId);
@ -641,6 +667,98 @@ int RsDataService::storeGroup(std::map<RsNxsGrp *, RsGxsGrpMetaData *> &grp)
return ret;
}
int RsDataService::updateGroup(std::map<RsNxsGrp *, RsGxsGrpMetaData *> &grp)
{
RsStackMutex stack(mDbMutex);
std::map<RsNxsGrp*, RsGxsGrpMetaData* >::iterator sit = grp.begin();
// begin transaction
mDb->execSQL("BEGIN;");
for(; sit != grp.end(); sit++)
{
RsNxsGrp* grpPtr = sit->first;
RsGxsGrpMetaData* grpMetaPtr = sit->second;
// if data is larger than max item size do not add
if(!validSize(grpPtr)) continue;
std::string grpFile = mServiceDir + "/" + grpPtr->grpId;
std::ofstream ostrm(grpFile.c_str(), std::ios::binary | std::ios::trunc);
uint32_t offset = 0; // get file offset
/*!
* STORE file offset, file length, file name,
* grpId, flags, publish time stamp, identity,
* id signature, admin signatue, key set, last posting ts
* and meta data
**/
ContentValue cv;
cv.put(KEY_NXS_FILE_OFFSET, (int32_t)offset);
cv.put(KEY_NXS_FILE_LEN, (int32_t)grpPtr->grp.TlvSize());
cv.put(KEY_NXS_FILE, grpFile);
cv.put(KEY_GRP_ID, grpPtr->grpId);
cv.put(KEY_GRP_NAME, grpMetaPtr->mGroupName);
cv.put(KEY_ORIG_GRP_ID, grpMetaPtr->mOrigGrpId);
cv.put(KEY_NXS_SERV_STRING, grpMetaPtr->mServiceString);
cv.put(KEY_NXS_FLAGS, (int32_t)grpMetaPtr->mGroupFlags);
cv.put(KEY_TIME_STAMP, (int32_t)grpMetaPtr->mPublishTs);
cv.put(KEY_GRP_SIGN_FLAGS, (int32_t)grpMetaPtr->mSignFlags);
cv.put(KEY_GRP_CIRCLE_ID, grpMetaPtr->mCircleId);
cv.put(KEY_GRP_CIRCLE_TYPE, (int32_t)grpMetaPtr->mCircleType);
cv.put(KEY_GRP_INTERNAL_CIRCLE, grpMetaPtr->mInternalCircle);
cv.put(KEY_GRP_ORIGINATOR, grpMetaPtr->mOriginator);
cv.put(KEY_GRP_AUTHEN_FLAGS, (int32_t)grpMetaPtr->mAuthenFlags);
cv.put(KEY_NXS_HASH, grpMetaPtr->mHash);
if(! (grpMetaPtr->mAuthorId.empty()) ){
cv.put(KEY_NXS_IDENTITY, grpMetaPtr->mAuthorId);
}
offset = 0;
char keySetData[grpMetaPtr->keys.TlvSize()];
grpMetaPtr->keys.SetTlv(keySetData, grpMetaPtr->keys.TlvSize(), &offset);
cv.put(KEY_KEY_SET, grpMetaPtr->keys.TlvSize(), keySetData);
offset = 0;
char metaData[grpPtr->meta.TlvSize()];
grpPtr->meta.SetTlv(metaData, grpPtr->meta.TlvSize(), &offset);
cv.put(KEY_NXS_META, grpPtr->meta.TlvSize(), metaData);
// local meta data
cv.put(KEY_GRP_SUBCR_FLAG, (int32_t)grpMetaPtr->mSubscribeFlags);
cv.put(KEY_GRP_POP, (int32_t)grpMetaPtr->mPop);
cv.put(KEY_MSG_COUNT, (int32_t)grpMetaPtr->mMsgCount);
cv.put(KEY_GRP_STATUS, (int32_t)grpMetaPtr->mGroupStatus);
cv.put(KEY_GRP_LAST_POST, (int32_t)grpMetaPtr->mLastPost);
offset = 0;
char grpData[grpPtr->grp.TlvSize()];
grpPtr->grp.SetTlv(grpData, grpPtr->grp.TlvSize(), &offset);
ostrm.write(grpData, grpPtr->grp.TlvSize());
ostrm.close();
mDb->sqlUpdate(GRP_TABLE_NAME, "grpId='" + grpPtr->grpId + "'", cv);
}
// finish transaction
bool ret = mDb->execSQL("COMMIT;");
for(sit = grp.begin(); sit != grp.end(); sit++)
{
//TODO: API encourages aliasing, remove this abomination
if(sit->second != sit->first->metaData)
delete sit->second;
delete sit->first;
}
return ret;
}
bool RsDataService::validSize(RsNxsGrp* grp) const
{
if((grp->grp.TlvSize() + grp->meta.TlvSize()) <= GXS_MAX_ITEM_SIZE) return true;
@ -964,34 +1082,33 @@ int RsDataService::retrieveGxsGrpMetaData(std::map<RsGxsGroupId, RsGxsGrpMetaDat
}else
{
std::map<RsGxsGroupId, RsGxsGrpMetaData *>::iterator mit = grp.begin();
for(; mit != grp.end(); mit++)
{
const RsGxsGroupId& grpId = mit->first;
RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, grpMetaColumns, "grpId='" + grpId + "'", "");
for(; mit != grp.end(); mit++)
{
const RsGxsGroupId& grpId = mit->first;
RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, grpMetaColumns, "grpId='" + grpId + "'", "");
if(c)
{
bool valid = c->moveToFirst();
if(c)
{
bool valid = c->moveToFirst();
while(valid)
{
RsGxsGrpMetaData* g = locked_getGrpMeta(*c);
while(valid)
{
RsGxsGrpMetaData* g = locked_getGrpMeta(*c);
if(g)
{
grp[g->mGroupId] = g;
}
valid = c->moveToNext();
}
delete c;
}
if(g)
{
grp[g->mGroupId] = g;
}
valid = c->moveToNext();
}
delete c;
}
}
}
}
}
return 1;
@ -1010,21 +1127,22 @@ int RsDataService::resetDataStore()
std::map<std::string, RsNxsGrp*>::iterator mit
= grps.begin();
// remove all grp msgs files from service dir
for(; mit != grps.end(); mit++){
std::string file = mServiceDir + "/" + mit->first;
std::string msgFile = file + "-msgs";
remove(file.c_str()); // remove group file
remove(msgFile.c_str()); // and remove messages file
delete mit->second;
}
{
RsStackMutex stack(mDbMutex);
mDb->closeDb();
}
remove(mDbName.c_str()); // remove db file
// remove all grp msgs files from service dir
for(; mit != grps.end(); mit++){
std::string file = mServiceDir + "/" + mit->first;
std::string msgFile = file + "-msgs";
remove(file.c_str()); // remove group file
remove(msgFile.c_str()); // and remove messages file
delete mit->second;
}
mDb->execSQL("DROP TABLE " + MSG_TABLE_NAME);
mDb->execSQL("DROP TABLE " + GRP_TABLE_NAME);
mDb->execSQL("DROP TRIGGER " + GRP_LAST_POST_UPDATE_TRIGGER);
}
// recreate database
initialise();
@ -1177,6 +1295,31 @@ int RsDataService::removeGroups(const std::vector<std::string> &grpIds)
return 1;
}
int RsDataService::retrieveGroupIds(std::vector<std::string> &grpIds)
{
RsStackMutex stack(mDbMutex);
RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, grpIdColumn, "", "");
if(c)
{
bool valid = c->moveToFirst();
while(valid)
{
std::string grpId;
c->getString(0, grpId);
grpIds.push_back(grpId);
valid = c->moveToNext();
}
delete c;
}else
{
return 0;
}
return 1;
}
bool RsDataService::locked_updateMessageEntries(const MsgUpdates& updates)
{

View file

@ -106,6 +106,13 @@ public:
*/
int removeGroups(const std::vector<RsGxsGroupId>& grpIds);
/*!
* Retrieves all group ids in store
* @param grpIds all grpids in store is inserted into this vector
* @return error code
*/
int retrieveGroupIds(std::vector<std::string> &grpIds);
/*!
* @return the cache size set for this RsGeneralDataService in bytes
*/
@ -130,6 +137,13 @@ public:
*/
int storeGroup(std::map<RsNxsGrp*, RsGxsGrpMetaData*>& grp);
/*!
* Updates group entries in Db
* @param grp map of group and decoded meta data
* @return error code
*/
int updateGroup(std::map<RsNxsGrp*, RsGxsGrpMetaData*>& grsp);
/*!
* @param metaData The meta data item to update
* @return error code
@ -238,6 +252,7 @@ private:
std::list<std::string> grpColumns;
std::list<std::string> grpMetaColumns;
std::list<std::string> grpIdColumn;
std::string mServiceDir, mDbName;
uint16_t mServType;

View file

@ -169,6 +169,13 @@ public:
*/
virtual int removeGroups(const std::vector<RsGxsGroupId>& grpIds) = 0;
/*!
* Retrieves all group ids in store
* @param grpIds all grpids in store is inserted into this vector
* @return error code
*/
virtual int retrieveGroupIds(std::vector<RsGxsGroupId>& grpIds) = 0;
/*!
* @return the cache size set for this RsGeneralDataService in bytes
*/
@ -194,6 +201,13 @@ public:
virtual int storeGroup(std::map<RsNxsGrp*, RsGxsGrpMetaData*>& grsp) = 0;
/*!
* Updates group entries in Db
* @param grp map of group and decoded meta data
* @return error code
*/
virtual int updateGroup(std::map<RsNxsGrp*, RsGxsGrpMetaData*>& grsp) = 0;
/*!
* @param metaData
*/

View file

@ -26,11 +26,6 @@
#include <unistd.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include "pqi/pqihash.h"
#include "rsgenexchange.h"
#include "gxssecurity.h"
@ -118,6 +113,8 @@ void RsGenExchange::tick()
publishMsgs();
processGroupUpdatePublish();
processRecvdData();
if(!mNotifications.empty())
@ -278,6 +275,56 @@ void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& privatekeySet,
}
}
void RsGenExchange::generatePublicFromPrivateKeys(const RsTlvSecurityKeySet &privatekeySet,
RsTlvSecurityKeySet &publickeySet)
{
// actually just copy settings of one key except mark its key flags public
typedef std::map<std::string, RsTlvSecurityKey> keyMap;
const keyMap& allKeys = privatekeySet.keys;
keyMap::const_iterator cit = allKeys.begin();
bool adminFound = false, publishFound = false;
for(; cit != allKeys.end(); cit++)
{
const RsTlvSecurityKey& privKey = cit->second;
if(privKey.keyFlags & RSTLV_KEY_TYPE_FULL)
{
RsTlvSecurityKey pubKey;
pubKey = privKey;
RSA *rsaPrivKey = NULL, *rsaPubKey = NULL;
rsaPrivKey = GxsSecurity::extractPrivateKey(privKey);
if(rsaPrivKey)
rsaPubKey = RSAPublicKey_dup(rsaPrivKey);
if(rsaPrivKey && rsaPubKey)
{
GxsSecurity::setRSAPublicKey(pubKey, rsaPubKey);
if(pubKey.keyFlags & RSTLV_KEY_DISTRIB_ADMIN)
pubKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_PUBLIC_ONLY;
if(pubKey.keyFlags & RSTLV_KEY_DISTRIB_PRIVATE)
pubKey.keyFlags = RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_PUBLIC_ONLY;
pubKey.endTS = pubKey.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */
publickeySet.keys.insert(std::make_pair(pubKey.keyId, pubKey));
}
if(rsaPrivKey)
RSA_free(rsaPrivKey);
if(rsaPubKey)
RSA_free(rsaPubKey);
}
}
}
uint8_t RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& privateKeySet, RsTlvSecurityKeySet& publicKeySet)
{
std::cerr << "RsGenExchange::createGroup()";
@ -768,6 +815,7 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSecu
}else
{
std::list<std::string> peers;
peers.push_back(msg->PeerId());
mGixs->requestKey(metaData.mAuthorId, peers);
return VALIDATE_FAIL_TRY_LATER;
}
@ -841,6 +889,7 @@ int RsGenExchange::validateGrp(RsNxsGrp* grp, RsTlvSecurityKeySet& grpKeySet)
}else
{
std::list<std::string> peers;
peers.push_back(grp->PeerId());
mGixs->requestKey(metaData.mAuthorId, peers);
return VALIDATE_FAIL_TRY_LATER;
}
@ -1369,6 +1418,20 @@ void RsGenExchange::publishGroup(uint32_t& token, RsGxsGrpItem *grpItem)
}
void RsGenExchange::updateGroup(uint32_t& token, RsGxsGroupUpdateMeta& updateMeta, RsGxsGrpItem* grpItem)
{
RsStackMutex stack(mGenMtx);
token = mDataAccess->generatePublicToken();
mGroupUpdatePublish.push_back(GroupUpdatePublish(grpItem, updateMeta, token));
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::updateGroup() token: " << token;
std::cerr << std::endl;
#endif
}
void RsGenExchange::publishMsg(uint32_t& token, RsGxsMsgItem *msgItem)
{
RsStackMutex stack(mGenMtx);
@ -1721,6 +1784,7 @@ void RsGenExchange::publishMsgs()
msg->metaData->mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_UNREAD;
msgId = msg->msgId;
grpId = msg->grpId;
msg->metaData->recvTS = time(NULL);
computeHash(msg->msg, msg->metaData->mHash);
mDataAccess->addMsgData(msg);
msgChangeMap[grpId].push_back(msgId);
@ -1785,6 +1849,115 @@ RsGenExchange::ServiceCreate_Return RsGenExchange::service_CreateGroup(RsGxsGrpI
#define PENDING_SIGN_TIMEOUT 10 // 5 seconds
void RsGenExchange::processGroupUpdatePublish()
{
RsStackMutex stack(mGenMtx);
// get keys for group update publish
// first build meta request map for groups to be updated
std::map<std::string, RsGxsGrpMetaData*> grpMeta;
std::vector<GroupUpdatePublish>::iterator vit = mGroupUpdatePublish.begin();
for(; vit != mGroupUpdatePublish.end(); vit++)
{
GroupUpdatePublish& gup = *vit;
const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId;
grpMeta.insert(std::make_pair(groupId, (RsGxsGrpMetaData*)(NULL)));
}
if(grpMeta.empty())
return;
mDataStore->retrieveGxsGrpMetaData(grpMeta);
// now
vit = mGroupUpdatePublish.begin();
for(; vit != mGroupUpdatePublish.end(); vit++)
{
GroupUpdatePublish& gup = *vit;
const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId;
std::map<std::string, RsGxsGrpMetaData*>::iterator mit = grpMeta.find(groupId);
RsGxsGrpMetaData* meta = NULL;
if(mit == grpMeta.end())
{
std::cerr << "Error! could not find meta of old group to update!" << std::endl;
mDataAccess->updatePublicRequestStatus(gup.mToken, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
delete gup.grpItem;
continue;
}else
{
meta = mit->second;
}
gup.grpItem->meta = *meta;
assignMetaUpdates(gup.grpItem->meta, gup.mUpdateMeta);
GxsGrpPendingSign ggps(gup.grpItem, ggps.mToken);
bool publishAndAdminPrivatePresent = checkKeys(meta->keys);
if(publishAndAdminPrivatePresent)
{
ggps.mPrivateKeys = meta->keys;
generatePublicFromPrivateKeys(ggps.mPrivateKeys, ggps.mPublicKeys);
ggps.mHaveKeys = true;
ggps.mStartTS = time(NULL);
ggps.mLastAttemptTS = 0;
ggps.mIsUpdate = true;
ggps.mToken = gup.mToken;
mGrpsToPublish.push_back(ggps);
}else
{
delete gup.grpItem;
mDataAccess->updatePublicRequestStatus(gup.mToken, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
}
delete meta;
}
mGroupUpdatePublish.clear();
}
void RsGenExchange::assignMetaUpdates(RsGroupMetaData& meta, const RsGxsGroupUpdateMeta metaUpdate) const
{
const RsGxsGroupUpdateMeta::GxsMetaUpdate* updates = metaUpdate.getUpdates();
RsGxsGroupUpdateMeta::GxsMetaUpdate::const_iterator mit = updates->begin();
for(; mit != updates->end(); mit++)
{
if(mit->first == RsGxsGroupUpdateMeta::NAME)
meta.mGroupName = mit->second;
}
}
bool RsGenExchange::checkKeys(const RsTlvSecurityKeySet& keySet)
{
typedef std::map<std::string, RsTlvSecurityKey> keyMap;
const keyMap& allKeys = keySet.keys;
keyMap::const_iterator cit = allKeys.begin();
bool adminFound = false, publishFound = false;
for(; cit != allKeys.end(); cit++)
{
const RsTlvSecurityKey& key = cit->second;
if(key.keyFlags & RSTLV_KEY_TYPE_FULL)
{
if(key.keyFlags & RSTLV_KEY_DISTRIB_ADMIN)
adminFound = true;
if(key.keyFlags & RSTLV_KEY_DISTRIB_PRIVATE)
publishFound = true;
}
}
// user must have both private and public parts of publish and admin keys
return adminFound && publishFound;
}
void RsGenExchange::publishGrps()
{
RsStackMutex stack(mGenMtx);
@ -1855,10 +2028,6 @@ void RsGenExchange::publishGrps()
// get group id from private admin key id
grpItem->meta.mGroupId = grp->grpId = privAdminKey.keyId;
// what!? this will remove the private keys!
privatekeySet.keys.insert(publicKeySet.keys.begin(),
publicKeySet.keys.end());
ServiceCreate_Return ret = service_CreateGroup(grpItem, privatekeySet);
@ -1882,6 +2051,7 @@ void RsGenExchange::publishGrps()
{
grp->metaData = new RsGxsGrpMetaData();
grpItem->meta.mPublishTs = time(NULL);
//grpItem->meta.mParentGrpId = std::string("empty");
*(grp->metaData) = grpItem->meta;
// TODO: change when publish key optimisation added (public groups don't have publish key
@ -1906,7 +2076,12 @@ void RsGenExchange::publishGrps()
{
grpId = grp->grpId;
computeHash(grp->grp, grp->metaData->mHash);
mDataAccess->addGroupData(grp);
grp->metaData->mRecvTS = time(NULL);
if(ggps.mIsUpdate)
mDataAccess->updateGroupData(grp);
else
mDataAccess->addGroupData(grp);
}
else
{
@ -2038,6 +2213,8 @@ void RsGenExchange::processRecvdData()
processRecvdGroups();
processRecvdMessages();
performUpdateValidation();
}
@ -2070,6 +2247,9 @@ void RsGenExchange::processRecvdMessages()
}
}
if(mReceivedMsgs.empty())
return;
std::vector<RsNxsMsg*>::iterator vit = mReceivedMsgs.begin();
GxsMsgReq msgIds;
std::map<RsNxsMsg*, RsGxsMsgMetaData*> msgs;
@ -2122,6 +2302,7 @@ void RsGenExchange::processRecvdMessages()
if(validated_entry != mMsgPendingValidate.end()) mMsgPendingValidate.erase(validated_entry);
computeHash(msg->msg, meta->mHash);
meta->recvTS = time(NULL);
}
}
else
@ -2192,10 +2373,16 @@ void RsGenExchange::processRecvdGroups()
{
RsStackMutex stack(mGenMtx);
if(mReceivedGrps.empty())
return;
NxsGrpPendValidVect::iterator vit = mReceivedGrps.begin();
std::vector<std::string> existingGrpIds;
std::list<std::string> grpIds;
std::map<RsNxsGrp*, RsGxsGrpMetaData*> grps;
std::list<RsGxsGroupId> grpIds;
mDataStore->retrieveGroupIds(existingGrpIds);
while( vit != mReceivedGrps.end())
{
@ -2220,13 +2407,24 @@ void RsGenExchange::processRecvdGroups()
meta->mGroupStatus = GXS_SERV::GXS_GRP_STATUS_UNPROCESSED | GXS_SERV::GXS_GRP_STATUS_UNREAD;
meta->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED;
if(meta->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
meta->mOriginator = grp->PeerId();
computeHash(grp->grp, meta->mHash);
grps.insert(std::make_pair(grp, meta));
grpIds.push_back(grp->grpId);
// now check if group already existss
if(std::find(existingGrpIds.begin(), existingGrpIds.end(), grp->grpId) == existingGrpIds.end())
{
meta->mRecvTS = time(NULL);
if(meta->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
meta->mOriginator = grp->PeerId();
grps.insert(std::make_pair(grp, meta));
grpIds.push_back(grp->grpId);
}
else
{
GroupUpdate update;
update.newGrp = grp;
mGroupUpdates.push_back(update);
}
erase = true;
}
else if(ret == VALIDATE_FAIL)
@ -2278,3 +2476,99 @@ void RsGenExchange::processRecvdGroups()
mDataStore->storeGroup(grps);
}
}
void RsGenExchange::performUpdateValidation()
{
RsStackMutex stack(mGenMtx);
#ifdef GXS_GENX_DEBUG
std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl;
#endif
if(mGroupUpdates.empty())
return;
std::map<std::string, RsGxsGrpMetaData*> grpMetas;
std::vector<GroupUpdate>::iterator vit = mGroupUpdates.begin();
for(; vit != mGroupUpdates.end(); vit++)
grpMetas.insert(std::make_pair(vit->newGrp->grpId, (RsGxsGrpMetaData*)NULL));
if(!grpMetas.empty())
mDataStore->retrieveGxsGrpMetaData(grpMetas);
else
return;
vit = mGroupUpdates.begin();
for(; vit != mGroupUpdates.end(); vit++)
{
GroupUpdate& gu = *vit;
std::map<std::string, RsGxsGrpMetaData*>::iterator mit =
grpMetas.find(gu.newGrp->grpId);
gu.oldGrpMeta = mit->second;
gu.validUpdate = updateValid(*(gu.oldGrpMeta), *(gu.newGrp));
}
#ifdef GXS_GENX_DEBUG
std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl;
#endif
vit = mGroupUpdates.begin();
std::map<RsNxsGrp*, RsGxsGrpMetaData*> grps;
for(; vit != mGroupUpdates.end(); vit++)
{
GroupUpdate& gu = *vit;
if(gu.validUpdate)
{
if(gu.newGrp->metaData->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
gu.newGrp->metaData->mOriginator = gu.newGrp->PeerId();
grps.insert(std::make_pair(gu.newGrp, gu.newGrp->metaData));
}
else
{
delete gu.newGrp;
}
delete gu.oldGrpMeta;
}
mDataStore->updateGroup(grps);
mGroupUpdates.clear();
}
bool RsGenExchange::updateValid(RsGxsGrpMetaData& oldGrpMeta, RsNxsGrp& newGrp) const
{
std::map<SignType, RsTlvKeySignature>& signSet = newGrp.metaData->signSet.keySignSet;
std::map<SignType, RsTlvKeySignature>::iterator mit = signSet.find(GXS_SERV::FLAG_AUTHEN_ADMIN);
if(mit == signSet.end())
{
#ifdef GXS_GENX_DEBUG
std::cerr << "RsGenExchange::updateValid() new admin sign not found! " << std::endl;
std::cerr << "RsGenExchange::updateValid() grpId: " << oldGrp.grpId << std::endl;
#endif
return false;
}
RsTlvKeySignature adminSign = mit->second;
std::map<std::string, RsTlvSecurityKey>& keys = oldGrpMeta.keys.keys;
std::map<std::string, RsTlvSecurityKey>::iterator keyMit = keys.find(oldGrpMeta.mGroupId);
if(keyMit == keys.end())
{
#ifdef GXS_GENX_DEBUG
std::cerr << "RsGenExchange::updateValid() admin key not found! " << std::endl;
#endif
return false;
}
// also check this is the latest published group
bool latest = newGrp.metaData->mPublishTs > oldGrpMeta.mPublishTs;
return GxsSecurity::validateNxsGrp(newGrp, adminSign, keyMit->second) && latest;
}

View file

@ -71,13 +71,14 @@ class GxsGrpPendingSign
public:
GxsGrpPendingSign(RsGxsGrpItem* item, uint32_t token): mLastAttemptTS(0), mStartTS(time(NULL)), mToken(token),
mItem(item), mHaveKeys(false)
mItem(item), mHaveKeys(false), mIsUpdate(false)
{}
time_t mLastAttemptTS, mStartTS;
uint32_t mToken;
RsGxsGrpItem* mItem;
bool mHaveKeys; // mKeys->first == true if key present
bool mIsUpdate;
RsTlvSecurityKeySet mPrivateKeys;
RsTlvSecurityKeySet mPublicKeys;
};
@ -516,7 +517,6 @@ protected:
/*!
* Enables publication of a group item \n
* If the item exists already this is simply versioned \n
* This will induce a related change message \n
* Ownership of item passes to this rsgenexchange \n
* @param token
@ -524,6 +524,16 @@ protected:
*/
void publishGroup(uint32_t& token, RsGxsGrpItem* grpItem);
/*!
* Updates an existing group item \n
* This will induce a related change message \n
* Ownership of item passes to this rsgenexchange \n
* @param token
* @param grpItem
*/
void updateGroup(uint32_t& token, RsGxsGroupUpdateMeta& updateMeta, RsGxsGrpItem* grpItem);
public:
/*!
* Enables publication of a message item \n
@ -629,6 +639,8 @@ private:
void publishGrps();
void processGroupUpdatePublish();
void publishMsgs();
/*!
@ -700,11 +712,20 @@ private:
/*!
* Generate a set of keys that can define a GXS group
* @param privatekeySet contains private generated keys
* @param privatekeySet contains public generated keys (counterpart of private)
* @param publickeySet contains public generated keys (counterpart of private)
* @param genPublicKeys should publish key pair also be generated
*/
void generateGroupKeys(RsTlvSecurityKeySet& privatekeySet, RsTlvSecurityKeySet& publickeySet, bool genPublishKeys);
/*!
* Generate public set of keys from their private counterparts
* No keys will be generated if one fails
* @param privatekeySet contains private generated keys
* @param publickeySet contains public generated keys (counterpart of private)
* @return false if key gen failed for a key set
*/
void generatePublicFromPrivateKeys(const RsTlvSecurityKeySet& privatekeySet, RsTlvSecurityKeySet& publickeySet);
/*!
* Attempts to validate msg signatures
* @param msg message to be validated
@ -736,6 +757,32 @@ private:
static void computeHash(const RsTlvBinaryData& data, std::string& hash);
/*!
* Checks validation of recently received groups to be
* updated
*/
void performUpdateValidation();
/*!
* Checks if the update is valid (i.e. the new admin signature is by the old admin key)
* @param oldGrp the old group to be updated (must have meta data member initialised)
* @param newGrp the new group that updates the old group (must have meta data member initialised)
* @return
*/
bool updateValid(RsGxsGrpMetaData& oldGrp, RsNxsGrp& newGrp) const;
/*!
* convenience function for checking private publish and admin keys are present
* @param keySet The keys set to split into a private and public set
* @return false, if private admin and publish keys cannot be found, true otherwise
*/
bool checkKeys(const RsTlvSecurityKeySet& keySet);
/*!
* Convenience function for assigning the meta update items to the actual group meta
*/
void assignMetaUpdates(RsGroupMetaData& meta, const RsGxsGroupUpdateMeta metaUpdate) const;
private:
RsMutex mGenMtx;
@ -798,6 +845,13 @@ private:
const uint8_t CREATE_FAIL, CREATE_SUCCESS, CREATE_FAIL_TRY_LATER, SIGN_MAX_ATTEMPTS;
const uint8_t SIGN_FAIL, SIGN_SUCCESS, SIGN_FAIL_TRY_LATER;
const uint8_t VALIDATE_FAIL, VALIDATE_SUCCESS, VALIDATE_FAIL_TRY_LATER, VALIDATE_MAX_ATTEMPTS;
private:
std::vector<GroupUpdate> mGroupUpdates, mPeersGroupUpdate;
std::vector<GroupUpdatePublish> mGroupUpdatePublish;
};
#endif // RSGENEXCHANGE_H

View file

@ -176,7 +176,7 @@ class RsGixsReputation
public:
// get Reputation.
virtual bool haveReputation(const RsGxsId &id) = 0;
virtual bool loadReputation(const RsGxsId &id) = 0;
virtual bool loadReputation(const RsGxsId &id, const std::list<std::string>& peers) = 0;
virtual bool getReputation(const RsGxsId &id, GixsReputation &rep) = 0;
};

View file

@ -49,6 +49,7 @@ uint32_t RsGxsGrpMetaData::serial_size()
s += 4; // for mCircleType
s += GetTlvStringSize(mCircleId);
s += 4; // mAuthenFlag
s += GetTlvStringSize(mParentGrpId);
return s;
}
@ -74,6 +75,8 @@ void RsGxsGrpMetaData::clear(){
mOriginator.clear();
mCircleType = 0;
mAuthenFlags = 0;
mParentGrpId.clear();
mRecvTS = 0;
}
@ -103,6 +106,7 @@ bool RsGxsGrpMetaData::serialise(void *data, uint32_t &pktsize)
ok &= SetTlvString(data, tlvsize, &offset, 0, mGroupId);
ok &= SetTlvString(data, tlvsize, &offset, 0, mOrigGrpId);
ok &= SetTlvString(data, tlvsize, &offset, 0, mParentGrpId);
ok &= SetTlvString(data, tlvsize, &offset, 0, mGroupName);
ok &= setRawUInt32(data, tlvsize, &offset, mGroupFlags);
ok &= setRawUInt32(data, tlvsize, &offset, mPublishTs);
@ -133,6 +137,7 @@ bool RsGxsGrpMetaData::deserialise(void *data, uint32_t &pktsize)
ok &= GetTlvString(data, pktsize, &offset, 0, mGroupId);
ok &= GetTlvString(data, pktsize, &offset, 0, mOrigGrpId);
ok &= GetTlvString(data, pktsize, &offset, 0, mParentGrpId);
ok &= GetTlvString(data, pktsize, &offset, 0, mGroupName);
ok &= getRawUInt32(data, pktsize, &offset, &mGroupFlags);
ok &= getRawUInt32(data, pktsize, &offset, &mPublishTs);
@ -196,6 +201,7 @@ void RsGxsMsgMetaData::clear()
mMsgFlags = 0;
mMsgStatus = 0;
mChildTs = 0;
recvTS = 0;
}
bool RsGxsMsgMetaData::serialise(void *data, uint32_t *size)
@ -284,6 +290,8 @@ void RsGxsGrpMetaData::operator =(const RsGroupMetaData& rMeta)
this->mInternalCircle = rMeta.mInternalCircle;
this->mOriginator = rMeta.mOriginator;
this->mAuthenFlags = rMeta.mAuthenFlags;
//std::cout << "rMeta.mParentGrpId= " <<rMeta.mParentGrpId<<"\n";
this->mParentGrpId = rMeta.mParentGrpId;
}
void RsGxsMsgMetaData::operator =(const RsMsgMetaData& rMeta)

View file

@ -63,6 +63,7 @@ public:
std::string mServiceString;
uint32_t mAuthenFlags;
RsGxsGroupId mParentGrpId;
// BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG.
@ -70,17 +71,16 @@ public:
uint32_t mPop; // HOW DO WE DO THIS NOW.
uint32_t mMsgCount; // ???
time_t mLastPost; // ???
uint32_t mLastPost; // ???
uint32_t mGroupStatus;
uint32_t mRecvTS;
std::string mOriginator;
std::string mInternalCircle;
std::string mHash;
};
class RsGxsMsgMetaData
{
public:
@ -114,6 +114,7 @@ public:
uint32_t mMsgStatus;
time_t mChildTs;
uint32_t recvTS;
std::string mHash;
bool validated;

View file

@ -1489,7 +1489,14 @@ bool RsGxsDataAccess::addGroupData(RsNxsGrp* grp) {
return mDataStore->storeGroup(grpM);
}
bool RsGxsDataAccess::updateGroupData(RsNxsGrp* grp) {
RsStackMutex stack(mDataMutex);
std::map<RsNxsGrp*, RsGxsGrpMetaData*> grpM;
grpM.insert(std::make_pair(grp, grp->metaData));
return mDataStore->updateGroup(grpM);
}
bool RsGxsDataAccess::addMsgData(RsNxsMsg* msg) {

View file

@ -126,14 +126,21 @@ public:
public:
/*!
* This adds a groups to the gxs data base, this is a blocking call
* Responsibility for grp still lies with callee \n
* This adds a groups to the gxs data base, this is a blocking call \n
* If function returns successfully DataAccess can be queried for grp
* @param grp the group to add, responsibility grp passed lies with callee
* @return false if group cound not be added
*/
bool addGroupData(RsNxsGrp* grp);
/*!
* This updates a groups in the gxs data base, this is a blocking call \n
* If function returns successfully DataAccess can be queried for grp
* @param grp the group to add, responsibility grp passed lies with callee
* @return false if group cound not be added
*/
bool updateGroupData(RsNxsGrp* grp);
/*!
* This adds a group to the gxs data base, this is a blocking call \n
* Responsibility for msg still lies with callee \n
@ -429,11 +436,13 @@ private:
private:
RsGeneralDataService* mDataStore;
RsMutex mDataMutex; /* protecting below */
uint32_t mNextToken;
std::map<uint32_t, uint32_t> mPublicToken;
std::map<uint32_t, GxsRequest*> mRequests;
RsMutex mDataMutex;
};

View file

@ -36,16 +36,16 @@
#define GIXS_CUT_OFF 0
#define SYNC_PERIOD 12 // in microseconds every 10 seconds (1 second for testing)
#define TRANSAC_TIMEOUT 5 // 5 seconds
#define TRANSAC_TIMEOUT 10 // 10 seconds
const uint32_t RsGxsNetService::FRAGMENT_SIZE = 150000;
RsGxsNetService::RsGxsNetService(uint16_t servType, RsGeneralDataService *gds,
RsNxsNetMgr *netMgr, RsNxsObserver *nxsObs, RsGixsReputation* reputations, RsGcxs* circles)
RsNxsNetMgr *netMgr, RsNxsObserver *nxsObs, RsGixsReputation* reputations, RsGcxs* circles, bool grpAutoSync)
: p3Config(servType), p3ThreadedService(servType),
mTransactionTimeOut(TRANSAC_TIMEOUT), mServType(servType), mDataStore(gds), mTransactionN(0),
mObserver(nxsObs), mNxsMutex("RsGxsNetService"), mNetMgr(netMgr), mSYNC_PERIOD(SYNC_PERIOD),
mSyncTs(0), mReputations(reputations), mCircles(circles)
mSyncTs(0), mReputations(reputations), mCircles(circles), mGrpAutoSync(grpAutoSync), mGrpServerUpdateItem(NULL)
{
addSerialType(new RsNxsSerialiser(mServType));
@ -85,13 +85,27 @@ void RsGxsNetService::syncWithPeers()
std::set<std::string>::iterator sit = peers.begin();
// for now just grps
for(; sit != peers.end(); sit++)
if(mGrpAutoSync)
{
RsNxsSyncGrp *grp = new RsNxsSyncGrp(mServType);
grp->clear();
grp->PeerId(*sit);
sendItem(grp);
// for now just grps
for(; sit != peers.end(); sit++)
{
const std::string peerId = *sit;
ClientGrpMap::const_iterator cit = mClientGrpUpdateMap.find(peerId);
uint32_t updateTS = 0;
if(cit != mClientGrpUpdateMap.end())
{
const RsGxsGrpUpdateItem *gui = cit->second;
updateTS = gui->grpUpdateTS;
}
RsNxsSyncGrp *grp = new RsNxsSyncGrp(mServType);
grp->clear();
grp->PeerId(*sit);
grp->updateTS = updateTS;
sendItem(grp);
}
}
#ifdef GXS_ENABLE_SYNC_MSGS
@ -108,7 +122,9 @@ void RsGxsNetService::syncWithPeers()
RsGxsGrpMetaData* meta = mit->second;
if(meta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED )
{
grpIds.push_back(mit->first);
}
delete meta;
}
@ -122,13 +138,36 @@ void RsGxsNetService::syncWithPeers()
std::vector<RsGxsGroupId>::iterator vit = grpIds.begin();
// now see if you have an updateTS so optimise whether you need
// to get a new list of peer data
RsGxsMsgUpdateItem* mui = NULL;
ClientMsgMap::const_iterator cit = mClientMsgUpdateMap.find(*sit);
if(cit != mClientMsgUpdateMap.end())
{
mui = cit->second;
}
for(; vit != grpIds.end(); vit++)
{
RsNxsSyncMsg* msg = new RsNxsSyncMsg(mServType);
msg->clear();
msg->PeerId(*sit);
msg->grpId = *vit;
sendItem(msg);
uint32_t updateTS = 0;
if(mui)
{
std::map<std::string, uint32_t>::const_iterator cit2 = mui->msgUpdateTS.find(*vit);
if(cit2 != mui->msgUpdateTS.end())
{
updateTS = cit2->second;
}
}
RsNxsSyncMsg* msg = new RsNxsSyncMsg(mServType);
msg->clear();
msg->PeerId(*sit);
msg->grpId = *vit;
msg->updateTS = updateTS;
sendItem(msg);
}
}
#endif
@ -524,20 +563,105 @@ void RsGxsNetService::collateMsgFragments(MsgFragments fragments, std::map<RsGxs
fragments.clear();
}
bool RsGxsNetService::loadList(std::list<RsItem*>& load)
class StoreHere
{
return false;
public:
StoreHere(RsGxsNetService::ClientGrpMap& cgm, RsGxsNetService::ClientMsgMap& cmm,
RsGxsNetService::ServerMsgMap& smm,
RsGxsServerGrpUpdateItem*& sgm) : mClientGrpMap(cgm), mClientMsgMap(cmm),
mServerMsgMap(smm), mServerGrpUpdateItem(sgm)
{}
void operator() (RsItem* item)
{
RsGxsMsgUpdateItem* mui;
RsGxsGrpUpdateItem* gui;
RsGxsServerGrpUpdateItem* gsui;
RsGxsServerMsgUpdateItem* msui;
if((mui = dynamic_cast<RsGxsMsgUpdateItem*>(item)) != NULL)
mClientMsgMap.insert(std::make_pair(mui->peerId, mui));
else if((gui = dynamic_cast<RsGxsGrpUpdateItem*>(item)) != NULL)
mClientGrpMap.insert(std::make_pair(gui->peerId, gui));
else if((msui = dynamic_cast<RsGxsServerMsgUpdateItem*>(item)) != NULL)
mServerMsgMap.insert(std::make_pair(msui->grpId, msui));
else if((gsui = dynamic_cast<RsGxsServerGrpUpdateItem*>(item)) != NULL)
{
if(mServerGrpUpdateItem == NULL)
{
mServerGrpUpdateItem = gsui;
}
else
{
#ifdef NXS_NET_DEBUG
std::cerr << "Error! More than one server group update item exists!" << std::endl;
#endif
delete gsui;
}
}
else
{
std::cerr << "Type not expected!" << std::endl;
}
}
private:
RsGxsNetService::ClientGrpMap& mClientGrpMap;
RsGxsNetService::ClientMsgMap& mClientMsgMap;
RsGxsNetService::ServerMsgMap& mServerMsgMap;
RsGxsServerGrpUpdateItem*& mServerGrpUpdateItem;
};
bool RsGxsNetService::loadList(std::list<RsItem *> &load)
{
std::for_each(load.begin(), load.end(), StoreHere(mClientGrpUpdateMap, mClientMsgUpdateMap,
mServerMsgUpdateMap, mGrpServerUpdateItem));
return true;
}
#include <algorithm>
template <typename UpdateMap>
struct get_second : public std::unary_function<typename UpdateMap::value_type, RsItem*>
{
RsItem* operator()(const typename UpdateMap::value_type& value) const
{
return value.second;
}
};
bool RsGxsNetService::saveList(bool& cleanup, std::list<RsItem*>& save)
{
return false;
RsStackMutex stack(mNxsMutex);
// hardcore templates
std::transform(mClientGrpUpdateMap.begin(), mClientGrpUpdateMap.end(),
std::back_inserter(save), get_second<ClientGrpMap>());
std::transform(mClientMsgUpdateMap.begin(), mClientMsgUpdateMap.end(),
std::back_inserter(save), get_second<ClientMsgMap>());
std::transform(mServerMsgUpdateMap.begin(), mServerMsgUpdateMap.end(),
std::back_inserter(save), get_second<ServerMsgMap>());
save.push_back(mGrpServerUpdateItem);
cleanup = false;
return true;
}
RsSerialiser *RsGxsNetService::setupSerialiser()
{
return NULL;
RsSerialiser *rss = new RsSerialiser;
rss->addSerialType(new RsGxsUpdateSerialiser(mServType));
return rss;
}
void RsGxsNetService::recvNxsItemQueue(){
@ -748,7 +872,8 @@ bool RsGxsNetService::locked_processTransac(RsNxsTransac* item)
void RsGxsNetService::run(){
double timeDelta = 0.2;
double timeDelta = 0.5;
int updateCounter = 0;
while(isRunning()){
@ -758,6 +883,14 @@ void RsGxsNetService::run(){
Sleep((int) (timeDelta * 1000));
#endif
if(updateCounter == 20)
{
updateServerSyncTS();
updateCounter = 0;
}
else
updateCounter++;
// process active transactions
processTransactions();
@ -767,13 +900,71 @@ void RsGxsNetService::run(){
// vetting of id and circle info
runVetting();
processExplicitGroupRequests();
}
}
void RsGxsNetService::updateServerSyncTS()
{
RsStackMutex stack(mNxsMutex);
std::map<RsGxsGroupId, RsGxsGrpMetaData*> gxsMap;
// retrieve all grps and update TS
mDataStore->retrieveGxsGrpMetaData(gxsMap);
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit = gxsMap.begin();
// as a grp list server also note this is the latest item you have
if(mGrpServerUpdateItem == NULL)
{
mGrpServerUpdateItem = new RsGxsServerGrpUpdateItem(mServType);
}
bool change = false;
for(; mit != gxsMap.end(); mit++)
{
const RsGxsGroupId& grpId = mit->first;
RsGxsGrpMetaData* grpMeta = mit->second;
ServerMsgMap::iterator mapIT = mServerMsgUpdateMap.find(grpId);
RsGxsServerMsgUpdateItem* msui = NULL;
if(mapIT == mServerMsgUpdateMap.end())
{
msui = new RsGxsServerMsgUpdateItem(mServType);
msui->grpId = grpMeta->mGroupId;
mServerMsgUpdateMap.insert(std::make_pair(msui->grpId, msui));
}else
{
msui = mapIT->second;
}
if(grpMeta->mLastPost > msui->msgUpdateTS )
{
change = true;
msui->msgUpdateTS = grpMeta->mLastPost;
}
// this might be very inefficient with time
if(grpMeta->mRecvTS > mGrpServerUpdateItem->grpUpdateTS)
{
mGrpServerUpdateItem->grpUpdateTS = grpMeta->mRecvTS;
change = true;
}
}
// actual change in config settings, then save configuration
if(change)
IndicateConfigChanged();
freeAndClearContainerResource<std::map<RsGxsGroupId, RsGxsGrpMetaData*>,
RsGxsGrpMetaData*>(gxsMap);
}
bool RsGxsNetService::locked_checkTransacTimedOut(NxsTransaction* tr)
{
//return tr->mTimeOut < ((uint32_t) time(NULL));
return false;
return tr->mTimeOut < ((uint32_t) time(NULL));
}
void RsGxsNetService::processTransactions(){
@ -1036,25 +1227,52 @@ void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr)
// notify listener of grps
mObserver->notifyNewGroups(grps);
// now note this as the latest you've received from this peer
std::string peerFrom = tr->mTransaction->PeerId();
uint32_t updateTS = tr->mTransaction->updateTS;
ClientGrpMap::iterator it = mClientGrpUpdateMap.find(peerFrom);
RsGxsGrpUpdateItem* item = NULL;
if(it != mClientGrpUpdateMap.end())
{
item = it->second;
}else
{
item = new RsGxsGrpUpdateItem(mServType);
mClientGrpUpdateMap.insert(
std::make_pair(peerFrom, item));
}
item->grpUpdateTS = updateTS;
item->peerId = peerFrom;
IndicateConfigChanged();
}else if(flag & RsNxsTransac::FLAG_TYPE_MSGS)
{
std::vector<RsNxsMsg*> msgs;
std::string grpId;
while(tr->mItems.size() > 0)
{
RsNxsMsg* msg = dynamic_cast<RsNxsMsg*>(tr->mItems.front());
if(msg)
{
tr->mItems.pop_front();
msgs.push_back(msg);
if(grpId.empty())
grpId = msg->grpId;
tr->mItems.pop_front();
msgs.push_back(msg);
}
else
{
#ifdef NXS_NET_DEBUG
std::cerr << "RsGxsNetService::processCompletedTransactions(): item did not caste to msg"
<< std::endl;
std::cerr << "RsGxsNetService::processCompletedTransactions(): item did not caste to msg"
<< std::endl;
#endif
}
}
@ -1078,6 +1296,10 @@ void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr)
// notify listener of msgs
mObserver->notifyNewMessages(msgs);
// now note that this is the latest you've received from this peer
// for the grp id
locked_doMsgUpdateWork(tr->mTransaction, grpId);
}
}else if(tr->mFlag == NxsTransaction::FLAG_STATE_FAILED){
// don't do anything transaction will simply be cleaned
@ -1085,6 +1307,33 @@ void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr)
return;
}
void RsGxsNetService::locked_doMsgUpdateWork(const RsNxsTransac *nxsTrans, const std::string &grpId)
{
// firts check if peer exists
const std::string& peerFrom = nxsTrans->PeerId();
ClientMsgMap::iterator it = mClientMsgUpdateMap.find(peerFrom);
RsGxsMsgUpdateItem* mui = NULL;
// now update the peer's entry for this grp id
if(it != mClientMsgUpdateMap.end())
{
mui = it->second;
}
else
{
mui = new RsGxsMsgUpdateItem(mServType);
mClientMsgUpdateMap.insert(std::make_pair(peerFrom, mui));
}
mui->msgUpdateTS[grpId] = nxsTrans->updateTS;
mui->peerId = peerFrom;
IndicateConfigChanged();
}
void RsGxsNetService::locked_processCompletedOutgoingTrans(NxsTransaction* tr)
{
uint16_t flag = tr->mTransaction->transactFlag;
@ -1125,6 +1374,7 @@ void RsGxsNetService::locked_processCompletedOutgoingTrans(NxsTransaction* tr)
std::cerr << "complete Sending Grp Data, transN: " <<
tr->mTransaction->transactionNumber << std::endl;
#endif
}else if(flag & RsNxsTransac::FLAG_TYPE_MSGS)
{
#ifdef NXS_NET_DEBUG
@ -1166,7 +1416,7 @@ void RsGxsNetService::locked_pushMsgTransactionFromList(
newTrans->mTimeOut = time(NULL) + mTransactionTimeOut;
// create transaction copy with your id to indicate
// its an outgoing transaction
newTrans->mTransaction = new RsNxsTransac(*transac);
newTrans->mTransaction = new RsNxsTransac(*transac);
newTrans->mTransaction->PeerId(mOwnId);
sendItem(transac);
{
@ -1248,7 +1498,7 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
msgIdSet.insert((*vit)->mMsgId);
delete(*vit);
}
msgMetaV.clear();
msgMetaV.clear();
// get unique id for this transaction
uint32_t transN = locked_getTransactionId();
@ -1261,6 +1511,9 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
MsgAuthorV toVet;
std::list<std::string> peers;
peers.push_back(tr->mTransaction->PeerId());
for(; llit != msgItemL.end(); llit++)
{
RsNxsSyncMsgItem*& syncItem = *llit;
@ -1294,7 +1547,7 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
else
{
// preload for speed
mReputations->loadReputation(syncItem->authorId);
mReputations->loadReputation(syncItem->authorId, peers);
MsgAuthEntry entry;
entry.mAuthorId = syncItem->authorId;
entry.mGrpId = syncItem->grpId;
@ -1375,6 +1628,7 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
}
std::map<std::string, RsGxsGrpMetaData*> grpMetaMap;
std::map<std::string, RsGxsGrpMetaData*>::const_iterator metaIter;
mDataStore->retrieveGxsGrpMetaData(grpMetaMap);
// now do compare and add loop
@ -1384,13 +1638,23 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
uint32_t transN = locked_getTransactionId();
GrpAuthorV toVet;
std::list<std::string> peers;
peers.push_back(tr->mTransaction->PeerId());
for(; llit != grpItemL.end(); llit++)
{
RsNxsSyncGrpItem*& grpSyncItem = *llit;
const std::string& grpId = grpSyncItem->grpId;
metaIter = grpMetaMap.find(grpId);
bool haveItem = false;
bool latestVersion = false;
if (metaIter != grpMetaMap.end())
{
haveItem = true;
latestVersion = grpSyncItem->publishTs > metaIter->second->mPublishTs;
}
if(grpMetaMap.find(grpId) == grpMetaMap.end()){
if(!haveItem || (haveItem && latestVersion) ){
// determine if you need to check reputation
bool checkRep = !grpSyncItem->authorId.empty();
@ -1412,7 +1676,7 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
else
{
// preload reputation for later
mReputations->loadReputation(grpSyncItem->authorId);
mReputations->loadReputation(grpSyncItem->authorId, peers);
GrpAuthEntry entry;
entry.mAuthorId = grpSyncItem->authorId;
entry.mGrpId = grpSyncItem->grpId;
@ -1505,11 +1769,15 @@ void RsGxsNetService::locked_genSendGrpsTransaction(NxsTransaction* tr)
return;
}
uint32_t updateTS = 0;
if(mGrpServerUpdateItem)
updateTS = mGrpServerUpdateItem->grpUpdateTS;
RsNxsTransac* ntr = new RsNxsTransac(mServType);
ntr->transactionNumber = transN;
ntr->transactFlag = RsNxsTransac::FLAG_BEGIN_P1 |
RsNxsTransac::FLAG_TYPE_GRPS;
ntr->updateTS = updateTS;
ntr->nItems = grps.size();
ntr->PeerId(tr->mTransaction->PeerId());
@ -1625,12 +1893,17 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
return;
}
std::string grpId = "";
for(;lit != tr->mItems.end(); lit++)
{
RsNxsSyncMsgItem* item = dynamic_cast<RsNxsSyncMsgItem*>(*lit);
if (item)
{
msgIds[item->grpId].push_back(item->msgId);
if(grpId.empty())
grpId = item->grpId;
}
else
{
@ -1687,10 +1960,18 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
return;
}
uint32_t updateTS = 0;
ServerMsgMap::const_iterator cit = mServerMsgUpdateMap.find(grpId);
if(cit != mServerMsgUpdateMap.end())
updateTS = cit->second->msgUpdateTS;
RsNxsTransac* ntr = new RsNxsTransac(mServType);
ntr->transactionNumber = transN;
ntr->transactFlag = RsNxsTransac::FLAG_BEGIN_P1 |
RsNxsTransac::FLAG_TYPE_MSGS;
ntr->updateTS = updateTS;
ntr->nItems = msgSize;
ntr->PeerId(peerId);
@ -1766,13 +2047,32 @@ void RsGxsNetService::locked_pushGrpRespFromList(std::list<RsNxsItem*>& respList
locked_addTransaction(tr);
}
bool RsGxsNetService::locked_CanReceiveUpdate(const RsNxsSyncGrp *item)
{
// don't sync if you have no new updates for this peer
if(mGrpServerUpdateItem)
{
if(item->updateTS >= mGrpServerUpdateItem->grpUpdateTS && item->updateTS != 0)
{
return false;
}
}
return true;
}
void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrp* item)
{
RsStackMutex stack(mNxsMutex);
if(!locked_CanReceiveUpdate(item))
return;
std::string peer = item->PeerId();
std::map<std::string, RsGxsGrpMetaData*> grp;
mDataStore->retrieveGxsGrpMetaData(grp);
@ -1826,6 +2126,8 @@ void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrp* item)
return;
}
bool RsGxsNetService::canSendGrpId(const std::string& sslId, RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& toVet)
{
// first do the simple checks
@ -1881,10 +2183,31 @@ bool RsGxsNetService::canSendGrpId(const std::string& sslId, RsGxsGrpMetaData& g
return true;
}
bool RsGxsNetService::locked_CanReceiveUpdate(const RsNxsSyncMsg *item)
{
ServerMsgMap::const_iterator cit = mServerMsgUpdateMap.find(item->grpId);
if(cit != mServerMsgUpdateMap.end())
{
const RsGxsServerMsgUpdateItem *msui = cit->second;
if(item->updateTS >= msui->msgUpdateTS && item->updateTS != 0)
{
#ifdef NXS_NET_DEBUG
std::cerr << "RsGxsNetService::locked_CanReceiveUpdate(): Msgs up to date" << std::endl;
#endif
return false;
}
}
return true;
}
void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsg* item)
{
RsStackMutex stack(mNxsMutex);
if(!locked_CanReceiveUpdate(item))
return;
const std::string& peer = item->PeerId();
GxsMsgMetaResult metaResult;
@ -2066,3 +2389,40 @@ void RsGxsNetService::setSyncAge(uint32_t age)
}
int RsGxsNetService::requestGrp(const std::list<RsGxsGroupId>& grpId, const std::string& peerId)
{
RsStackMutex stack(mNxsMutex);
mExplicitRequest[peerId].assign(grpId.begin(), grpId.end());
return 1;
}
void RsGxsNetService::processExplicitGroupRequests()
{
RsStackMutex stack(mNxsMutex);
std::map<std::string, std::list<RsGxsGroupId> >::const_iterator cit = mExplicitRequest.begin();
for(; cit != mExplicitRequest.end(); cit++)
{
const std::string& peerId = cit->first;
const std::list<RsGxsGroupId>& groupIdList = cit->second;
std::list<RsNxsItem*> grpSyncItems;
std::list<RsGxsGroupId>::const_iterator git = groupIdList.begin();
uint32_t transN = locked_getTransactionId();
for(; git != groupIdList.end(); git++)
{
RsNxsSyncGrpItem* item = new RsNxsSyncGrpItem(mServType);
item->grpId = *git;
item->PeerId(peerId);
item->flag = RsNxsSyncGrpItem::FLAG_REQUEST;
item->transactionNumber = transN;
grpSyncItems.push_back(item);
}
if(!grpSyncItems.empty())
locked_pushGrpTransactionFromList(grpSyncItems, peerId, transN);
}
mExplicitRequest.clear();
}

View file

@ -34,6 +34,7 @@
#include "rsnxsobserver.h"
#include "pqi/p3linkmgr.h"
#include "serialiser/rsnxsitems.h"
#include "serialiser/rsgxsupdateitems.h"
#include "rsgxsnetutils.h"
#include "pqi/p3cfgmgr.h"
#include "rsgixs.h"
@ -73,7 +74,7 @@ public:
* arrive
*/
RsGxsNetService(uint16_t servType, RsGeneralDataService* gds, RsNxsNetMgr* netMgr,
RsNxsObserver* nxsObs = NULL, RsGixsReputation* repuations = NULL, RsGcxs* circles = NULL);
RsNxsObserver* nxsObs = NULL, RsGixsReputation* repuations = NULL, RsGcxs* circles = NULL, bool grpAutoSync = true);
virtual ~RsGxsNetService();
@ -115,7 +116,7 @@ public:
* @param msgId the messages to retrieve
* @return request token to be redeemed
*/
int requestMsg(const std::string& msgId, uint8_t hops){ return 0;}
int requestMsg(const RsGxsGrpMsgIdPair& msgId){ return 0;}
/*!
* Request for this group is sent through to peers on your network
@ -123,7 +124,7 @@ public:
* @param enabled set to false to disable pause, and true otherwise
* @return request token to be redeemed
*/
int requestGrp(const std::list<std::string>& grpId, uint8_t hops){ return 0;}
int requestGrp(const std::list<RsGxsGroupId>& grpId, const std::string& peerId);
/* p3Config methods */
@ -322,6 +323,15 @@ private:
bool locked_canReceive(const RsGxsGrpMetaData * const grpMeta, const std::string& peerId);
void processExplicitGroupRequests();
void locked_doMsgUpdateWork(const RsNxsTransac* nxsTrans, const std::string& grpId);
void updateServerSyncTS();
bool locked_CanReceiveUpdate(const RsNxsSyncGrp* item);
bool locked_CanReceiveUpdate(const RsNxsSyncMsg* item);
private:
typedef std::vector<RsNxsGrp*> GrpFragments;
@ -418,10 +428,30 @@ private:
RsGcxs* mCircles;
RsGixsReputation* mReputations;
bool mGrpAutoSync;
// need to be verfied
std::vector<AuthorPending*> mPendingResp;
std::vector<GrpCircleVetting*> mPendingCircleVets;
std::map<std::string, std::list<RsGxsGroupId> > mExplicitRequest;
// nxs sync optimisation
// can pull dynamically the latest timestamp for each message
public:
typedef std::map<std::string, RsGxsMsgUpdateItem*> ClientMsgMap;
typedef std::map<std::string, RsGxsServerMsgUpdateItem*> ServerMsgMap;
typedef std::map<std::string, RsGxsGrpUpdateItem*> ClientGrpMap;
private:
ClientMsgMap mClientMsgUpdateMap;
ServerMsgMap mServerMsgUpdateMap;
ClientGrpMap mClientGrpUpdateMap;
RsGxsServerGrpUpdateItem* mGrpServerUpdateItem;
};
#endif // RSGXSNETSERVICE_H

View file

@ -47,14 +47,16 @@ bool AuthorPending::expired() const
}
bool AuthorPending::getAuthorRep(GixsReputation& rep,
const std::string& authorId)
const std::string& authorId, const std::string& peerId)
{
if(mRep->haveReputation(authorId))
{
return mRep->getReputation(authorId, rep);
}
mRep->loadReputation(authorId);
std::list<std::string> peers;
peers.push_back(peerId);
mRep->loadReputation(authorId, peers);
return false;
}
@ -94,7 +96,7 @@ bool MsgRespPending::accepted()
if(!entry.mPassedVetting)
{
GixsReputation rep;
if(getAuthorRep(rep, entry.mAuthorId))
if(getAuthorRep(rep, entry.mAuthorId, mPeerId))
{
if(rep.score > mCutOff)
{
@ -129,7 +131,7 @@ bool GrpRespPending::accepted()
{
GixsReputation rep;
if(getAuthorRep(rep, entry.mAuthorId))
if(getAuthorRep(rep, entry.mAuthorId, mPeerId))
{
if(rep.score > mCutOff)
{

View file

@ -141,7 +141,7 @@ protected:
* @param authorId reputation to get
* @return true if successfully retrieve repution
*/
bool getAuthorRep(GixsReputation& rep, const std::string& authorId);
bool getAuthorRep(GixsReputation& rep, const std::string& authorId, const std::string& peerId);
private:

View file

@ -129,4 +129,24 @@ private:
};
class GroupUpdate
{
public:
GroupUpdate() : oldGrpMeta(NULL), newGrp(NULL), validUpdate(false)
{}
RsGxsGrpMetaData* oldGrpMeta;
RsNxsGrp* newGrp;
bool validUpdate;
};
class GroupUpdatePublish
{
public:
GroupUpdatePublish(RsGxsGrpItem* item, RsGxsGroupUpdateMeta updateMeta, uint32_t token)
: grpItem(item), mUpdateMeta(updateMeta), mToken(token) {}
RsGxsGrpItem* grpItem;
RsGxsGroupUpdateMeta mUpdateMeta;
uint32_t mToken;
};
#endif /* GXSUTIL_H_ */

View file

@ -68,21 +68,6 @@ public:
*/
virtual void setSyncAge(uint32_t age) = 0;
/*!
* Explicitly requests all the groups contained by a peer
* Circumvents polling of peers for message
* @param peerId id of peer
*/
virtual void requestGroupsOfPeer(const std::string& peerId) = 0;
/*!
* get messages of a peer for a given group id, this circumvents the normal
* polling of peers for messages of given group id
* @param peerId Id of peer
* @param grpId id of group to request messages for
*/
virtual void requestMessagesOfPeer(const std::string& peerId, const std::string& grpId) = 0;
/*!
* Initiates a search through the network
* This returns messages which contains the search terms set in RsGxsSearch
@ -116,7 +101,7 @@ public:
* @param msgId the messages to retrieve
* @return request token to be redeemed
*/
virtual int requestMsg(const std::string& msgId, uint8_t hops) = 0;
virtual int requestMsg(const RsGxsGrpMsgIdPair& msgId) = 0;
/*!
* Request for this group is sent through to peers on your network
@ -124,7 +109,7 @@ public:
* @param enabled set to false to disable pause, and true otherwise
* @return request token to be redeemed
*/
virtual int requestGrp(const std::list<std::string>& grpId, uint8_t hops) = 0;
virtual int requestGrp(const std::list<RsGxsGroupId>& grpId, const std::string& peerId) = 0;
};

View file

@ -3,18 +3,13 @@ CONFIG += staticlib bitdht
CONFIG -= qt
TARGET = retroshare
CONFIG += test_voip
#GXS Stuff.
# This should be disabled for releases until further notice.
#CONFIG += gxs debug
CONFIG += gxs debug
#CONFIG += grouter
#CONFIG += dsdv
# Beware: All data of the stripped services are lost
DEFINES *= PQI_DISABLE_TUNNEL
#ENABLE_CACHE_OPT
profiling {
QMAKE_CXXFLAGS -= -fomit-frame-pointer
QMAKE_CXXFLAGS *= -pg -g -fno-omit-frame-pointer
@ -107,13 +102,9 @@ SOURCES += tcponudp/udppeer.cc \
PUBLIC_HEADERS = retroshare/rsblogs.h \
retroshare/rschannels.h \
retroshare/rsdisc.h \
retroshare/rsdistrib.h \
PUBLIC_HEADERS = retroshare/rsdisc.h \
retroshare/rsexpr.h \
retroshare/rsfiles.h \
retroshare/rsforums.h \
retroshare/rshistory.h \
retroshare/rsiface.h \
retroshare/rsinit.h \
@ -127,17 +118,16 @@ PUBLIC_HEADERS = retroshare/rsblogs.h \
retroshare/rsturtle.h \
retroshare/rstypes.h \
retroshare/rsdht.h \
retroshare/rsrtt.h \
retroshare/rsconfig.h
HEADERS += plugins/pluginmanager.h \
plugins/dlfcn_win32.h \
serialiser/rspluginitems.h
HEADERS += $$PUBLIC_HEADERS
# public headers to be...
HEADERS += retroshare/rsgame.h \
retroshare/rsphoto.h
################################# Linux ##########################################
linux-* {
@ -338,8 +328,6 @@ HEADERS += dbase/cachestrapper.h \
dbase/findex.h \
dbase/fistore.h
#HEADERS += dht/p3bitdht.h \
HEADERS += ft/ftchunkmap.h \
ft/ftcontroller.h \
ft/ftdata.h \
@ -364,7 +352,6 @@ HEADERS += pqi/authssl.h \
pqi/p3peermgr.h \
pqi/p3linkmgr.h \
pqi/p3netmgr.h \
pqi/p3dhtmgr.h \
pqi/p3notify.h \
pqi/p3upnpmgr.h \
pqi/pqiqos.h \
@ -389,31 +376,29 @@ HEADERS += pqi/authssl.h \
pqi/pqissl.h \
pqi/pqissllistener.h \
pqi/pqisslpersongrp.h \
pqi/pqissltunnel.h \
pqi/pqissludp.h \
pqi/pqisslproxy.h \
pqi/pqistore.h \
pqi/pqistreamer.h \
pqi/pqithreadstreamer.h \
pqi/pqiqosstreamer.h \
pqi/sslfns.h \
pqi/pqinetstatebox.h
HEADERS += rsserver/p3discovery.h \
rsserver/p3face.h \
# pqi/p3dhtmgr.h \
HEADERS += rsserver/p3face.h \
rsserver/p3history.h \
rsserver/p3msgs.h \
rsserver/p3peers.h \
rsserver/p3status.h \
rsserver/rsaccounts.h \
rsserver/p3serverconfig.h
HEADERS += serialiser/rsbaseitems.h \
serialiser/rsbaseserial.h \
serialiser/rsblogitems.h \
serialiser/rschannelitems.h \
HEADERS += serialiser/rsbaseserial.h \
serialiser/rsfiletransferitems.h \
serialiser/rsserviceserialiser.h \
serialiser/rsconfigitems.h \
serialiser/rsdiscitems.h \
serialiser/rsdistribitems.h \
serialiser/rsforumitems.h \
serialiser/rsgameitems.h \
serialiser/rshistoryitems.h \
serialiser/rsmsgitems.h \
serialiser/rsserial.h \
@ -429,32 +414,29 @@ HEADERS += serialiser/rsbaseitems.h \
serialiser/rstlvbanlist.h \
serialiser/rsbanlistitems.h \
serialiser/rsbwctrlitems.h \
serialiser/rstunnelitems.h
serialiser/rsdiscovery2items.h \
serialiser/rsheartbeatitems.h \
serialiser/rsrttitems.h \
serialiser/rsgxsrecognitems.h \
serialiser/rsgxsupdateitems.h
HEADERS += services/p3channels.h \
services/p3chatservice.h \
services/p3disc.h \
services/p3forums.h \
services/p3gamelauncher.h \
services/p3gameservice.h \
HEADERS += services/p3chatservice.h \
services/p3msgservice.h \
services/p3service.h \
services/p3statusservice.h \
services/p3banlist.h \
services/p3bwctrl.h \
services/p3tunnel.h
HEADERS += distrib/p3distrib.h \
distrib/p3distribsecurity.h
# services/p3blogs.h \
services/p3discovery2.h \
services/p3heartbeat.h \
services/p3rtt.h \
HEADERS += turtle/p3turtle.h \
turtle/rsturtleitem.h \
turtle/turtletypes.h
HEADERS += util/folderiterator.h \
util/rsdebug.h \
util/rscompress.h \
util/smallobject.h \
util/rsdir.h \
util/rsdiscspace.h \
@ -471,6 +453,7 @@ HEADERS += util/folderiterator.h \
util/pugiconfig.h \
util/rsmemcache.h \
util/rstickevent.h \
util/rsrecogn.h \
SOURCES += dbase/cachestrapper.cc \
dbase/fimonitor.cc \
@ -500,7 +483,6 @@ SOURCES += pqi/authgpg.cc \
pqi/p3peermgr.cc \
pqi/p3linkmgr.cc \
pqi/p3netmgr.cc \
pqi/p3dhtmgr.cc \
pqi/p3notify.cc \
pqi/pqiqos.cc \
pqi/pqiarchive.cc \
@ -518,16 +500,18 @@ SOURCES += pqi/authgpg.cc \
pqi/pqissl.cc \
pqi/pqissllistener.cc \
pqi/pqisslpersongrp.cc \
pqi/pqissltunnel.cc \
pqi/pqissludp.cc \
pqi/pqisslproxy.cc \
pqi/pqistore.cc \
pqi/pqistreamer.cc \
pqi/pqithreadstreamer.cc \
pqi/pqiqosstreamer.cc \
pqi/sslfns.cc \
pqi/pqinetstatebox.cc
SOURCES += rsserver/p3discovery.cc \
rsserver/p3face-config.cc \
# pqi/p3dhtmgr.cc \
SOURCES += rsserver/p3face-config.cc \
rsserver/p3face-msgs.cc \
rsserver/p3face-server.cc \
rsserver/p3history.cc \
@ -535,6 +519,7 @@ SOURCES += rsserver/p3discovery.cc \
rsserver/p3peers.cc \
rsserver/p3status.cc \
rsserver/rsinit.cc \
rsserver/rsaccounts.cc \
rsserver/rsloginhandler.cc \
rsserver/rstypes.cc \
rsserver/p3serverconfig.cc
@ -543,15 +528,10 @@ SOURCES += plugins/pluginmanager.cc \
plugins/dlfcn_win32.cc \
serialiser/rspluginitems.cc
SOURCES += serialiser/rsbaseitems.cc \
serialiser/rsbaseserial.cc \
serialiser/rsblogitems.cc \
serialiser/rschannelitems.cc \
SOURCES += serialiser/rsbaseserial.cc \
serialiser/rsfiletransferitems.cc \
serialiser/rsserviceserialiser.cc \
serialiser/rsconfigitems.cc \
serialiser/rsdiscitems.cc \
serialiser/rsdistribitems.cc \
serialiser/rsforumitems.cc \
serialiser/rsgameitems.cc \
serialiser/rshistoryitems.cc \
serialiser/rsmsgitems.cc \
serialiser/rsserial.cc \
@ -567,24 +547,22 @@ SOURCES += serialiser/rsbaseitems.cc \
serialiser/rstlvbanlist.cc \
serialiser/rsbanlistitems.cc \
serialiser/rsbwctrlitems.cc \
serialiser/rstunnelitems.cc
serialiser/rsdiscovery2items.cc \
serialiser/rsheartbeatitems.cc \
serialiser/rsrttitems.cc \
serialiser/rsgxsrecognitems.cc \
serialiser/rsgxsupdateitems.cc
SOURCES += services/p3channels.cc \
services/p3chatservice.cc \
services/p3disc.cc \
services/p3forums.cc \
services/p3gamelauncher.cc \
SOURCES += services/p3chatservice.cc \
services/p3msgservice.cc \
services/p3service.cc \
services/p3statusservice.cc \
services/p3banlist.cc \
services/p3bwctrl.cc \
services/p3discovery2.cc \
services/p3heartbeat.cc \
services/p3rtt.cc \
# removed because getPeer() doesn t exist services/p3tunnel.cc
SOURCES += distrib/p3distrib.cc \
distrib/p3distribsecurity.cc
SOURCES += turtle/p3turtle.cc \
turtle/rsturtleitem.cc
# turtle/turtlerouting.cc \
@ -594,10 +572,12 @@ SOURCES += turtle/p3turtle.cc \
SOURCES += util/folderiterator.cc \
util/rsdebug.cc \
util/rscompress.cc \
util/smallobject.cc \
util/rsdir.cc \
util/rsdiscspace.cc \
util/rsnet.cc \
util/rsnet_ss.cc \
util/extaddrfinder.cc \
util/dnsresolver.cc \
util/rsprint.cc \
@ -608,6 +588,7 @@ SOURCES += util/folderiterator.cc \
util/rsaes.cc \
util/rsrandom.cc \
util/rstickevent.cc \
util/rsrecogn.cc \
upnp_miniupnpc {
@ -752,11 +733,13 @@ gxs {
serialiser/rswireitems.cc \
# Posted Service
HEADERS += services/p3posted.h \
HEADERS += services/p3postbase.h \
services/p3posted.h \
retroshare/rsposted.h \
serialiser/rsposteditems.h
SOURCES += services/p3posted.cc \
SOURCES += services/p3postbase.cc \
services/p3posted.cc \
serialiser/rsposteditems.cc
#Photo Service
@ -809,12 +792,3 @@ test_bitdht {
use_blogs {
HEADERS += services/p3blogs.h
SOURCES += services/p3blogs.cc
DEFINES *= RS_USE_BLOGS
}

View file

@ -1808,8 +1808,8 @@ bool PGPHandler::locked_syncPublicKeyring()
bool PGPHandler::locked_syncTrustDatabase()
{
struct stat64 buf ;
std::wstring wfullname;
#ifdef WINDOWS_SYS
std::wstring wfullname;
librs::util::ConvertUtf8ToUtf16(_trustdb_path, wfullname);
if(-1 == _wstati64(wfullname.c_str(), &buf))
#else

View file

@ -7,10 +7,9 @@
#include <util/radix64.h>
#include <pgp/pgpkeyutil.h>
#include "rscertificate.h"
#include "util/rsstring.h"
//#define DEBUG_RSCERTIFICATE
//#define V_06_USE_CHECKSUM
#define DEBUG_RSCERTIFICATE
static const std::string PGP_CERTIFICATE_START ( "-----BEGIN PGP PUBLIC KEY BLOCK-----" );
static const std::string PGP_CERTIFICATE_END ( "-----END PGP PUBLIC KEY BLOCK-----" );
@ -18,6 +17,7 @@ static const std::string EXTERNAL_IP_BEGIN_SECTION ( "--EXT--" );
static const std::string LOCAL_IP_BEGIN_SECTION ( "--LOCAL--" );
static const std::string SSLID_BEGIN_SECTION ( "--SSLID--" );
static const std::string LOCATION_BEGIN_SECTION ( "--LOCATION--" );
static const std::string HIDDEN_NODE_BEGIN_SECTION ( "--HIDDEN--" );
static const uint8_t CERTIFICATE_PTAG_PGP_SECTION = 0x01 ;
static const uint8_t CERTIFICATE_PTAG_EXTIPANDPORT_SECTION = 0x02 ;
@ -26,6 +26,10 @@ static const uint8_t CERTIFICATE_PTAG_DNS_SECTION = 0x04 ;
static const uint8_t CERTIFICATE_PTAG_SSLID_SECTION = 0x05 ;
static const uint8_t CERTIFICATE_PTAG_NAME_SECTION = 0x06 ;
static const uint8_t CERTIFICATE_PTAG_CHECKSUM_SECTION = 0x07 ;
static const uint8_t CERTIFICATE_PTAG_HIDDENNODE_SECTION = 0x08 ;
static const uint8_t CERTIFICATE_PTAG_VERSION_SECTION = 0x09 ;
static const uint8_t CERTIFICATE_VERSION_06 = 0x06 ;
static bool is_acceptable_radix64Char(char c)
{
@ -73,17 +77,26 @@ std::string RsCertificate::toStdString() const
size_t p = 0 ;
unsigned char *buf = new unsigned char[BS] ;
addPacket( CERTIFICATE_PTAG_PGP_SECTION , binary_pgp_key , binary_pgp_key_size , buf, p, BS ) ;
addPacket( CERTIFICATE_PTAG_VERSION_SECTION, &CERTIFICATE_VERSION_06 , 1 , buf, p, BS ) ;
addPacket( CERTIFICATE_PTAG_PGP_SECTION , binary_pgp_key , binary_pgp_key_size , buf, p, BS ) ;
if(!only_pgp)
{
addPacket( CERTIFICATE_PTAG_EXTIPANDPORT_SECTION, ipv4_external_ip_and_port , 6 , buf, p, BS ) ;
addPacket( CERTIFICATE_PTAG_LOCIPANDPORT_SECTION, ipv4_internal_ip_and_port , 6 , buf, p, BS ) ;
addPacket( CERTIFICATE_PTAG_DNS_SECTION , (unsigned char *)dns_name.c_str() , dns_name.length() , buf, p, BS ) ;
if (hidden_node)
{
addPacket( CERTIFICATE_PTAG_HIDDENNODE_SECTION, (unsigned char *)hidden_node_address.c_str(), hidden_node_address.length() , buf, p, BS ) ;
}
else
{
addPacket( CERTIFICATE_PTAG_EXTIPANDPORT_SECTION, ipv4_external_ip_and_port , 6 , buf, p, BS ) ;
addPacket( CERTIFICATE_PTAG_LOCIPANDPORT_SECTION, ipv4_internal_ip_and_port , 6 , buf, p, BS ) ;
addPacket( CERTIFICATE_PTAG_DNS_SECTION , (unsigned char *)dns_name.c_str() , dns_name.length() , buf, p, BS ) ;
}
addPacket( CERTIFICATE_PTAG_NAME_SECTION , (unsigned char *)location_name.c_str() ,location_name.length() , buf, p, BS ) ;
addPacket( CERTIFICATE_PTAG_SSLID_SECTION , location_id.toByteArray() ,location_id.SIZE_IN_BYTES, buf, p, BS ) ;
}
#ifdef V_06_USE_CHECKSUM
uint32_t computed_crc = PGPKeyManagement::compute24bitsCRC(buf,p) ;
// handle endian issues.
@ -93,7 +106,7 @@ std::string RsCertificate::toStdString() const
mem[2] = (computed_crc >> 16) & 0xff ;
addPacket( CERTIFICATE_PTAG_CHECKSUM_SECTION,mem,3,buf,p,BS) ;
#endif
std::string out_string ;
Radix64::encode((char *)buf, p, out_string) ;
@ -124,7 +137,7 @@ RsCertificate::RsCertificate(const std::string& str)
uint32_t err_code ;
binary_pgp_key = NULL ;
if(!initFromString(str,err_code) && !initFromString_oldFormat(str,err_code))
if(!initFromString(str,err_code))
throw err_code ;
}
@ -144,14 +157,52 @@ RsCertificate::RsCertificate(const RsPeerDetails& Detail, const unsigned char *b
location_id = SSLIdType( Detail.id ) ;
location_name = Detail.location ;
scan_ip(Detail.localAddr,Detail.localPort,ipv4_internal_ip_and_port) ;
scan_ip(Detail.extAddr,Detail.extPort,ipv4_external_ip_and_port) ;
if (Detail.isHiddenNode)
{
hidden_node = true;
hidden_node_address = Detail.hiddenNodeAddress;
rs_sprintf_append(hidden_node_address, ":%u", Detail.hiddenNodePort);
dns_name = Detail.dyndns ;
memset(ipv4_internal_ip_and_port,0,6) ;
memset(ipv4_external_ip_and_port,0,6) ;
dns_name = "" ;
}
else
{
hidden_node = false;
hidden_node_address = "";
try
{
scan_ip(Detail.localAddr,Detail.localPort,ipv4_internal_ip_and_port) ;
}
catch(...)
{
std::cerr << "RsCertificate::Invalid LocalAddress";
std::cerr << std::endl;
memset(ipv4_internal_ip_and_port,0,6) ;
}
try
{
scan_ip(Detail.extAddr,Detail.extPort,ipv4_external_ip_and_port) ;
}
catch(...)
{
std::cerr << "RsCertificate::Invalid ExternalAddress";
std::cerr << std::endl;
memset(ipv4_external_ip_and_port,0,6) ;
}
dns_name = Detail.dyndns ;
}
}
else
{
only_pgp = true ;
hidden_node = false;
hidden_node_address = "";
location_id = SSLIdType() ;
location_name = "" ;
memset(ipv4_internal_ip_and_port,0,6) ;
@ -208,6 +259,7 @@ bool RsCertificate::initFromString(const std::string& instr,uint32_t& err_code)
unsigned char *buf = (unsigned char *)bf ;
size_t total_s = 0 ;
only_pgp = true ;
uint8_t certificate_version = 0x00 ;
while(total_s < size)
{
@ -230,6 +282,11 @@ bool RsCertificate::initFromString(const std::string& instr,uint32_t& err_code)
#endif
switch(ptag)
{
case CERTIFICATE_PTAG_VERSION_SECTION: certificate_version = buf[0] ;
buf = &buf[s] ;
break ;
case CERTIFICATE_PTAG_PGP_SECTION: binary_pgp_key = new unsigned char[s] ;
memcpy(binary_pgp_key,buf,s) ;
binary_pgp_key_size = s ;
@ -256,8 +313,16 @@ bool RsCertificate::initFromString(const std::string& instr,uint32_t& err_code)
buf = &buf[s] ;
break ;
case CERTIFICATE_PTAG_HIDDENNODE_SECTION:
hidden_node_address = std::string((char *)buf,s);
hidden_node = true;
buf = &buf[s];
break ;
case CERTIFICATE_PTAG_LOCIPANDPORT_SECTION:
if(s != 6)
{
err_code = CERTIFICATE_PARSING_ERROR_INVALID_LOCAL_IP;
return false ;
@ -302,12 +367,20 @@ bool RsCertificate::initFromString(const std::string& instr,uint32_t& err_code)
total_s += s ;
}
#ifdef V_06_USE_CHECKSUM
if(!checksum_check_passed)
{
err_code = CERTIFICATE_PARSING_ERROR_MISSING_CHECKSUM ;
return false ;
}
if(certificate_version != CERTIFICATE_VERSION_06)
{
err_code = CERTIFICATE_PARSING_ERROR_WRONG_VERSION ;
return false ;
}
#ifdef DEBUG_RSCERTIFICATE
std::cerr << "Certificate is version " << (int)certificate_version << std::endl;
#endif
if(total_s != size)
@ -326,6 +399,17 @@ bool RsCertificate::initFromString(const std::string& instr,uint32_t& err_code)
}
}
std::string RsCertificate::hidden_node_string() const
{
if ((!only_pgp) && (hidden_node))
{
return hidden_node_address;
}
std::string empty;
return empty;
}
std::string RsCertificate::sslid_string() const
{
if (only_pgp)
@ -364,12 +448,6 @@ unsigned short RsCertificate::loc_port_us() const
bool RsCertificate::cleanCertificate(const std::string& input,std::string& output,Format& format,int& error_code)
{
if(cleanCertificate_oldFormat(input,output,error_code))
{
format = RS_CERTIFICATE_OLD_FORMAT ;
return true ;
}
if(cleanCertificate(input,output,error_code))
{
format = RS_CERTIFICATE_RADIX ;
@ -423,557 +501,7 @@ bool RsCertificate::cleanCertificate(const std::string& instr,std::string& str,i
return true ;
}
// All the code below should be removed when in 0.6. Certificates will only use the new format.
//
bool RsCertificate::cleanCertificate_oldFormat(const std::string& certstr,std::string& cleanCertificate,int& error_code)
{
error_code = RS_PEER_CERT_CLEANING_CODE_UNKOWN_ERROR ; // default
const std::string& badCertificate(certstr) ;
std::string pgpend("-----END PGP PUBLIC KEY BLOCK-----");
size_t pos = certstr.find(pgpend);
std::string peer_info ;
std::string cert ;
if (pos != std::string::npos)
{
pos += pgpend.length();
cert = certstr.substr(0, pos);
if (pos + 1 < certstr.length())
peer_info = certstr.substr(pos + 1);
}
else
{
error_code = RS_PEER_CERT_CLEANING_CODE_NO_END_TAG ;
return false ;
}
if(cert.empty())
return false ;
/*
Buffer for storing the cleaned certificate. In certain cases the
cleanCertificate can be larger than the badCertificate
*/
cleanCertificate = "";
//The entire certificate begin tag
const char * beginCertTag="-----BEGIN";
//The entire certificate end tag
const char * endCertTag="-----END";
//Tag containing dots. The common part of both start and end tags
const char * commonTag="-----";
//Only BEGIN part of the begin tag
const char * beginTag="BEGIN";
//Only END part of the end tag
const char * endTag="END";
//The start index of the ----- part of the certificate begin tag
size_t beginCertStartIdx1=0;
//The start index of the BEGIN part of the certificate begin tag
size_t beginCertStartIdx2=0;
//The start index of the end part(-----) of the certificate begin tag. The begin tag ends with -----. Example -----BEGIN XPGP CERTIFICATE-----
size_t beginCertEndIdx=0;
//The start index of the ----- part of the certificate end tag
size_t endCertStartIdx1=0;
//The start index of the END part of the certificate end tag
size_t endCertStartIdx2=0;
//The start index of the end part(-----) of the certificate end tag. The begin tag ends with -----. Example -----BEGIN XPGP CERTIFICATE-----
size_t endCertEndIdx=0;
//The length of the bad certificate.
size_t lengthOfCert=certstr.length();
//The current index value in the bad certificate
size_t currBadCertIdx=0;
//Temporary index value
size_t tmpIdx=0;
//Boolean flag showing if the begin tag or the end tag has been found
bool found=false;
/*
Calculating the value of the beginCertStartIdx1 and beginCertStartIdx2. Here
we first locate the occurance of ----- and then the location of BEGIN. Next
we check if there are any non space or non new-line characters between their
occureance. If there are any other characters between the two(----- and
BEGIN), other than space and new line then it means that it is the
certificate begin tag. Here we take care of the fact that we may have
introduced some spaces and newlines in the begin tag by mistake. This takes
care of the spaces and newlines between ----- and BEGIN.
*/
while(found==false && (beginCertStartIdx1=certstr.find(commonTag,tmpIdx))!=std::string::npos)
{
beginCertStartIdx2=certstr.find(beginTag,beginCertStartIdx1+strlen(commonTag));
tmpIdx=beginCertStartIdx1+strlen(commonTag);
if(beginCertStartIdx2!=std::string::npos)
{
found=true;
for(size_t i=beginCertStartIdx1+strlen(commonTag);i<beginCertStartIdx2;i++)
{
if(certstr[i]!=' ' && certstr[i]!='\n' )
{
found=false;
break;
}
}
}
else
{
break;
}
}
/*
begin tag not found
*/
if(!found)
{
std::cerr<<"Certificate corrupted beyond repair: No <------BEGIN > tag"<<std::endl;
error_code = RS_PEER_CERT_CLEANING_CODE_NO_BEGIN_TAG ;
return false;
}
beginCertEndIdx=certstr.find(commonTag,beginCertStartIdx2);
if(beginCertEndIdx==std::string::npos)
{
std::cerr<<"Certificate corrupted beyond repair: No <------BEGIN > tag"<<std::endl;
error_code = RS_PEER_CERT_CLEANING_CODE_NO_BEGIN_TAG ;
return false;
}
tmpIdx=beginCertEndIdx+strlen(commonTag);
found=false;
/*
Calculating the value of the endCertStartIdx1 and endCertStartIdx2. Here we first locate the occurance of ----- and then
the location of END. Next we check if there are any non space or non new-line characters between their occureance. If there are any other
characters between the two(----- and END), other than space and new line then it means that it is the certificate end tag.
Here we take care of the fact that we may have introduced some spaces and newlines in the end tag by mistake. This
takes care of the spaces and newlines between ----- and END.
*/
while(found==false && (endCertStartIdx1=certstr.find(commonTag,tmpIdx))!=std::string::npos)
{
endCertStartIdx2=certstr.find(endTag,endCertStartIdx1+strlen(commonTag));
tmpIdx=endCertStartIdx1+strlen(commonTag);
if(endCertStartIdx2!=std::string::npos)
{
found=true;
for(size_t i=endCertStartIdx1+strlen(commonTag);i<endCertStartIdx2;i++)
{
if(certstr[i]!=' '&& certstr[i]!='\n')
{
found=false;
break;
}
}
}
else
{
break;
}
}
/*
end tag not found
*/
if(!found)
{
std::cerr<<"Certificate corrupted beyond repair: No <------END > tag"<<std::endl;
error_code = RS_PEER_CERT_CLEANING_CODE_NO_END_TAG ;
return false;
}
endCertEndIdx=certstr.find(commonTag,endCertStartIdx2);
if(endCertEndIdx==std::string::npos || endCertEndIdx>=lengthOfCert)
{
std::cerr<<"Certificate corrupted beyond repair: No <------END > tag"<<std::endl;
error_code = RS_PEER_CERT_CLEANING_CODE_NO_END_TAG ;
return false;
}
/*
Copying the begin tag(-----BEGIN) to the clean certificate
*/
cleanCertificate += beginCertTag;
currBadCertIdx=beginCertStartIdx2+strlen(beginTag);
/*
Copying the name of the tag e.g XPGP CERTIFICATE. At the same time remove any white spaces and new line
characters.
*/
while(currBadCertIdx<beginCertEndIdx)
{
if(badCertificate[currBadCertIdx]=='\n')
{
currBadCertIdx++;
}
else if(badCertificate[currBadCertIdx]==' ' && (badCertificate[currBadCertIdx-1]==' '|| badCertificate[currBadCertIdx-1]=='\n') )
{
currBadCertIdx++;
}
else
{
cleanCertificate += badCertificate[currBadCertIdx];
currBadCertIdx++;
}
}
/*
If the last character is a space we need to remove it.
*/
if(cleanCertificate.substr(cleanCertificate.length()-1, 1) == " ")
{
cleanCertificate.erase(cleanCertificate.length()-1);
}
/*
Copying the end part of the certificate start tag(-----).
*/
cleanCertificate += commonTag;
cleanCertificate += "\n";
currBadCertIdx=currBadCertIdx+strlen(commonTag);
/*
Remove the white spaces between the end of the certificate begin tag and the actual
start of the certificate.
*/
while(badCertificate[currBadCertIdx]=='\n'|| badCertificate[currBadCertIdx]==' ')
{
currBadCertIdx++;
}
//keep the armor header
std::list<std::string> header;
header.push_back("Version");
header.push_back("Comment");
header.push_back("MessageID");
header.push_back("Hash");
header.push_back("Charset");
for (std::list<std::string>::iterator headerIt = header.begin (); headerIt != header.end(); headerIt++)
{
if (badCertificate.substr(currBadCertIdx, (*headerIt).length()) == *headerIt)
{
cleanCertificate += badCertificate.substr(currBadCertIdx, (*headerIt).length());
currBadCertIdx += (*headerIt).length();
while(currBadCertIdx<endCertStartIdx1 && badCertificate[currBadCertIdx]!='\n')
{
cleanCertificate += badCertificate[currBadCertIdx];
currBadCertIdx++;
}
cleanCertificate += "\n";
}
}
//add empty line after armor header
cleanCertificate += "\n";
//Start of the actual certificate. Remove spaces in the certificate
//and make sure there are 64 characters per line in the
//new cleaned certificate
int cntPerLine=0;
while(currBadCertIdx<endCertStartIdx1)
{
if(cntPerLine==64)
{
cleanCertificate += "\n";
cntPerLine=0;
}
if(badCertificate[currBadCertIdx]=='=') /* checksum */
break;
else if(badCertificate[currBadCertIdx]=='\t')
currBadCertIdx++;
else if(badCertificate[currBadCertIdx]==' ')
currBadCertIdx++;
else if(badCertificate[currBadCertIdx]=='\n')
currBadCertIdx++;
else if(is_acceptable_radix64Char(badCertificate[currBadCertIdx]))
{
cleanCertificate += badCertificate[currBadCertIdx];
cntPerLine++;
currBadCertIdx++;
}
else
{
std::cerr << "Warning: Invalid character in radix certificate encoding: " << badCertificate[currBadCertIdx] << std::endl;
currBadCertIdx++;
}
}
if(currBadCertIdx>=endCertStartIdx1)
{
std::cerr<<"Certificate corrupted beyond repair: No checksum, or no newline after first tag"<<std::endl;
error_code = RS_PEER_CERT_CLEANING_CODE_NO_CHECKSUM ;
return false;
}
while(currBadCertIdx < endCertStartIdx1 && (badCertificate[currBadCertIdx] == '=' || badCertificate[currBadCertIdx] == ' ' || badCertificate[currBadCertIdx] == '\n' ))
currBadCertIdx++ ;
switch(cntPerLine % 4)
{
case 0: break ;
case 1: std::cerr<<"Certificate corrupted beyond repair: wrongnumber of chars on last line (n%4=1)"<<std::endl;
error_code = RS_PEER_CERT_CLEANING_CODE_WRONG_NUMBER;
return false ;
case 2: cleanCertificate += "==" ;
break ;
case 3: cleanCertificate += "=" ;
break ;
}
cleanCertificate += "\n=";
// if (badCertificate[currBadCertIdx] == '=')
// {
/* checksum */
while(currBadCertIdx<endCertStartIdx1)
{
if (badCertificate[currBadCertIdx]==' ')
{
currBadCertIdx++;
continue;
}
else if(badCertificate[currBadCertIdx]=='\n')
{
currBadCertIdx++;
continue;
}
cleanCertificate += badCertificate[currBadCertIdx];
cntPerLine++;
currBadCertIdx++;
}
// }
if(cleanCertificate.substr(cleanCertificate.length()-1,1)!="\n")
{
cleanCertificate += "\n";
// std::cerr<<"zeeeee"<<std::endl;
}
else
{
// std::cerr<<"zooooo"<<std::endl;
}
/*
Copying the begining part of the certificate end tag. Copying
-----END part of the tag.
*/
cleanCertificate += endCertTag;
currBadCertIdx=endCertStartIdx2+strlen(endTag);
/*
Copying the name of the certificate e.g XPGP CERTIFICATE. The end tag also has the
the name of the tag.
*/
while(currBadCertIdx<endCertEndIdx)
{
if(badCertificate[currBadCertIdx]=='\n')
{
currBadCertIdx++;
}
else if( badCertificate[currBadCertIdx]==' ' && (badCertificate[currBadCertIdx-1]==' '|| badCertificate[currBadCertIdx-1]=='\n'))
{
currBadCertIdx++;
}
else
{
cleanCertificate += badCertificate[currBadCertIdx];
currBadCertIdx++;
}
}
/*
If the last character is a space we need to remove it.
*/
if(cleanCertificate.substr(cleanCertificate.length()-1,1)==" ")
{
cleanCertificate.erase(cleanCertificate.length()-1);
}
/*
Copying the end part(-----) of the end tag in the certificate.
*/
cleanCertificate += commonTag;
cleanCertificate += "\n";
error_code = RS_PEER_CERT_CLEANING_CODE_NO_ERROR ;
cleanCertificate += peer_info ;
return true;
}
std::string RsCertificate::toStdString_oldFormat() const
{
std::string res ;
res += PGPKeyManagement::makeArmouredKey(binary_pgp_key,binary_pgp_key_size,pgp_version) ;
if(only_pgp)
return res ;
res += SSLID_BEGIN_SECTION ;
res += location_id.toStdString(false) ;
res += ";" ;
res += LOCATION_BEGIN_SECTION ;
res += location_name ;
res += ";\n" ;
std::ostringstream os ;
os << LOCAL_IP_BEGIN_SECTION ;
os << (int)ipv4_internal_ip_and_port[0] << "." << (int)ipv4_internal_ip_and_port[1] << "." << (int)ipv4_internal_ip_and_port[2] << "." << (int)ipv4_internal_ip_and_port[3] ;
os << ":" ;
os << ipv4_internal_ip_and_port[4]*256+ipv4_internal_ip_and_port[5] ;
os << ";" ;
os << EXTERNAL_IP_BEGIN_SECTION ;
os << (int)ipv4_external_ip_and_port[0] << "." << (int)ipv4_external_ip_and_port[1] << "." << (int)ipv4_external_ip_and_port[2] << "." << (int)ipv4_external_ip_and_port[3] ;
os << ":" ;
os << ipv4_external_ip_and_port[4]*256+ipv4_external_ip_and_port[5] ;
os << ";" ;
res += os.str() ;
res += "\n" ;
return res ;
}
bool RsCertificate::initFromString_oldFormat(const std::string& certstr,uint32_t& /*err_code*/)
{
//parse the text to get ip address
try
{
const std::string CERT_SSL_ID = "--SSLID--";
const std::string CERT_LOCATION = "--LOCATION--";
const std::string CERT_LOCAL_IP = "--LOCAL--";
const std::string CERT_EXT_IP = "--EXT--";
const std::string CERT_DYNDNS = "--DYNDNS--";
std::string cert;
std::string peerInfo;
/* search for -----END CERTIFICATE----- */
std::string pgpend("-----END PGP PUBLIC KEY BLOCK-----");
size_t pos = certstr.find(pgpend);
if (pos != std::string::npos)
{
pos += pgpend.length();
cert = certstr.substr(0, pos);
if (pos + 1 < certstr.length())
peerInfo = certstr.substr(pos + 1);
}
if(cert.empty())
return false ;
// find radix 64 part.
std::string radix_cert = PGPKeyParser::extractRadixPartFromArmouredKey(certstr,pgp_version) ;
char *key_bin ;
Radix64::decode(radix_cert,key_bin,binary_pgp_key_size) ;
binary_pgp_key = (unsigned char *)key_bin ;
only_pgp = true ;
#ifdef P3PEERS_DEBUG
std::cerr << "Parsing cert for sslid, location, ext and local address details. : " << certstr << std::endl;
#endif
//let's parse the ssl id
size_t parsePosition = peerInfo.find(CERT_SSL_ID);
std::cerr << "sslid position : " << parsePosition << std::endl;
if (parsePosition != std::string::npos) {
parsePosition += CERT_SSL_ID.length();
std::string subCert = peerInfo.substr(parsePosition);
parsePosition = subCert.find(";");
if (parsePosition != std::string::npos) {
std::string ssl_id = subCert.substr(0, parsePosition);
std::cerr << "SSL id : " << ssl_id << std::endl;
location_id = SSLIdType(ssl_id) ;
only_pgp = false ;
}
}
//let's parse the location
parsePosition = peerInfo.find(CERT_LOCATION);
std::cerr << "location position : " << parsePosition << std::endl;
if (parsePosition != std::string::npos) {
parsePosition += CERT_LOCATION.length();
std::string subCert = peerInfo.substr(parsePosition);
parsePosition = subCert.find(";");
if (parsePosition != std::string::npos) {
std::string location = subCert.substr(0, parsePosition);
std::cerr << "location : " << location << std::endl;
location_name = location;
}
}
//let's parse ip local address
parsePosition = peerInfo.find(CERT_LOCAL_IP);
std::cerr << "local ip position : " << parsePosition << std::endl;
if (parsePosition != std::string::npos) {
parsePosition += CERT_LOCAL_IP.length();
std::string subCert = peerInfo.substr(parsePosition);
parsePosition = subCert.find(":");
if (parsePosition != std::string::npos) {
std::string local_ip = subCert.substr(0, parsePosition);
std::cerr << "Local Ip : " << local_ip << std::endl;
unsigned short localPort ;
//let's parse local port
subCert = subCert.substr(parsePosition + 1);
parsePosition = subCert.find(";");
if (parsePosition != std::string::npos) {
std::string local_port = subCert.substr(0, parsePosition);
std::cerr << "Local port : " << local_port << std::endl;
sscanf(local_port.c_str(), "%hu", &localPort);
}
scan_ip(local_ip,localPort,ipv4_internal_ip_and_port) ;
}
}
//let's parse ip ext address
parsePosition = peerInfo.find(CERT_EXT_IP);
std::cerr << "Ext ip position : " << parsePosition << std::endl;
if (parsePosition != std::string::npos) {
parsePosition = parsePosition + CERT_EXT_IP.length();
std::string subCert = peerInfo.substr(parsePosition);
parsePosition = subCert.find(":");
if (parsePosition != std::string::npos) {
std::string ext_ip = subCert.substr(0, parsePosition);
std::cerr << "Ext Ip : " << ext_ip << std::endl;
unsigned short extPort ;
//let's parse ext port
subCert = subCert.substr(parsePosition + 1);
parsePosition = subCert.find(";");
if (parsePosition != std::string::npos) {
std::string ext_port = subCert.substr(0, parsePosition);
std::cerr << "Ext port : " << ext_port << std::endl;
sscanf(ext_port.c_str(), "%hu", &extPort);
}
scan_ip(ext_ip,extPort,ipv4_external_ip_and_port) ;
}
}
//let's parse DynDNS
parsePosition = peerInfo.find(CERT_DYNDNS);
std::cerr << "location DynDNS : " << parsePosition << std::endl;
if (parsePosition != std::string::npos) {
parsePosition += CERT_DYNDNS.length();
std::string subCert = peerInfo.substr(parsePosition);
parsePosition = subCert.find(";");
if (parsePosition != std::string::npos) {
std::string DynDNS = subCert.substr(0, parsePosition);
std::cerr << "DynDNS : " << DynDNS << std::endl;
dns_name = DynDNS;
}
}
}
catch (...)
{
std::cerr << "ConnectFriendWizard : Parse ip address error." << std::endl;
return false ;
}
return true;
}

View file

@ -11,7 +11,6 @@ class RsCertificate
typedef enum { RS_CERTIFICATE_OLD_FORMAT, RS_CERTIFICATE_RADIX } Format ;
// Constructs from text.
// - old format: The input string must comply with the GPG format (See RFC4880)
// - new format: The input string should only contain radix chars and spaces/LF/tabs.
//
RsCertificate(const std::string& input_string) ;
@ -25,7 +24,6 @@ class RsCertificate
virtual ~RsCertificate();
// Outut to text
std::string toStdString_oldFormat() const ;
std::string toStdString() const ;
std::string ext_ip_string() const ;
@ -33,6 +31,8 @@ class RsCertificate
std::string location_name_string() const { return location_name; }
std::string dns_string() const { return dns_name ; }
std::string sslid_string() const;
std::string hidden_node_string() const;
std::string armouredPGPKey() const ;
unsigned short ext_port_us() const ;
@ -45,11 +45,9 @@ class RsCertificate
private:
static bool cleanCertificate(const std::string& input,std::string& output,int&) ; // new radix format
static bool cleanCertificate_oldFormat(const std::string& input,std::string& output,int&) ; // old text format
static void scan_ip(const std::string& ip_string, unsigned short port,unsigned char *destination_memory) ;
bool initFromString(const std::string& str,uint32_t& err_code) ;
bool initFromString_oldFormat(const std::string& str,uint32_t& err_code) ;
static void addPacket(uint8_t ptag, const unsigned char *mem, size_t size, unsigned char *& buf, size_t& offset, size_t& buf_size) ;
@ -66,7 +64,9 @@ class RsCertificate
SSLIdType location_id ;
std::string pgp_version ;
std::string dns_name ;
std::string hidden_node_address;
bool only_pgp ; // does the cert contain only pgp info?
bool hidden_node; // IP or hidden Node Address.
};

View file

@ -39,14 +39,7 @@
#ifndef RS_GPG_AUTH_HEADER
#define RS_GPG_AUTH_HEADER
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include "util/rsthreads.h"
//#include "retroshare/rspeers.h"
#include <string>
#include <list>
#include <set>
#include <map>
#include "pqi/p3cfgmgr.h"
#include "pgp/pgphandler.h"

View file

@ -46,9 +46,8 @@
/******************** notify of new Cert **************************/
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/x509.h>
#include <openssl/ssl.h>
#include <iomanip>
@ -1120,7 +1119,7 @@ int AuthSSLimpl::VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx)
#ifdef AUTHSSL_DEBUG
fprintf(stderr, "Doing REAL PGP Certificates\n");
#endif
uint32_t auth_diagnostic ;
uint32_t auth_diagnostic ;
/* do the REAL Authentication */
if (!AuthX509WithGPG(X509_STORE_CTX_get_current_cert(ctx),auth_diagnostic))
@ -1128,7 +1127,7 @@ int AuthSSLimpl::VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx)
#ifdef AUTHSSL_DEBUG
fprintf(stderr, "AuthSSLimpl::VerifyX509Callback() X509 not authenticated.\n");
#endif
std::cerr << "(WW) Certificate was rejected because authentication failed. Diagnostic = " << auth_diagnostic << std::endl;
std::cerr << "(WW) Certificate was rejected because authentication failed. Diagnostic = " << auth_diagnostic << std::endl;
return false;
}
std::string pgpid = getX509CNString(X509_STORE_CTX_get_current_cert(ctx)->cert_info->issuer);
@ -1401,13 +1400,12 @@ void AuthSSLimpl::getCurrentConnectionAttemptInfo(std::string& gpg_id,std::strin
bool AuthSSLimpl::FailedCertificate(X509 *x509, const std::string& gpgid,
const std::string& sslid,
const std::string& sslcn,
const struct sockaddr_in& addr,
const struct sockaddr_storage& addr,
bool incoming)
{
std::string ip_address ;
rs_sprintf_append(ip_address, "%s:%u", rs_inet_ntoa(addr.sin_addr).c_str(), ntohs(addr.sin_port));
uint32_t auth_diagnostic = 0 ;
std::string ip_address = sockaddr_storage_tostring(addr);
uint32_t auth_diagnostic = 0 ;
bool authed ;
if(x509 == NULL)
@ -1649,7 +1647,7 @@ bool AuthSSLimpl::loadList(std::list<RsItem*>& load)
X509 *peer = loadX509FromPEM(kit->value);
/* authenticate it */
uint32_t diagnos ;
uint32_t diagnos ;
if (AuthX509WithGPG(peer,diagnos))
{
LocalStoreCert(peer);

View file

@ -39,8 +39,8 @@
*
*/
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <string>
#include <map>
@ -153,7 +153,7 @@ virtual SSL_CTX *getCTX() = 0;
virtual void setCurrentConnectionAttemptInfo(const std::string& gpg_id,const std::string& ssl_id,const std::string& ssl_cn) = 0 ;
virtual void getCurrentConnectionAttemptInfo( std::string& gpg_id, std::string& ssl_id, std::string& ssl_cn) = 0 ;
virtual bool FailedCertificate(X509 *x509, const std::string& gpgid,const std::string& sslid,const std::string& sslcn,const struct sockaddr_in &addr, bool incoming) = 0; /* store for discovery */
virtual bool FailedCertificate(X509 *x509, const std::string& gpgid,const std::string& sslid,const std::string& sslcn,const struct sockaddr_storage &addr, bool incoming) = 0; /* store for discovery */
virtual bool CheckCertificate(std::string peerId, X509 *x509) = 0; /* check that they are exact match */
static void setAuthSSL_debug(AuthSSL*) ; // used for debug only. The real function is InitSSL()
@ -232,7 +232,7 @@ virtual SSL_CTX *getCTX();
/* Restored these functions: */
virtual void setCurrentConnectionAttemptInfo(const std::string& gpg_id,const std::string& ssl_id,const std::string& ssl_cn) ;
virtual void getCurrentConnectionAttemptInfo( std::string& gpg_id, std::string& ssl_id, std::string& ssl_cn) ;
virtual bool FailedCertificate(X509 *x509, const std::string& gpgid,const std::string& sslid,const std::string& sslcn,const struct sockaddr_in &addr, bool incoming); /* store for discovery */
virtual bool FailedCertificate(X509 *x509, const std::string& gpgid,const std::string& sslid,const std::string& sslcn,const struct sockaddr_storage &addr, bool incoming); /* store for discovery */
virtual bool CheckCertificate(std::string peerId, X509 *x509); /* check that they are exact match */

View file

@ -43,15 +43,10 @@
#define BACKEDUP_SAVE
p3ConfigMgr::p3ConfigMgr(std::string dir, std::string fname, std::string signame)
:basedir(dir), metafname(fname), metasigfname(signame), cfgMtx("p3ConfigMgr"),
p3ConfigMgr::p3ConfigMgr(std::string dir)
:basedir(dir), cfgMtx("p3ConfigMgr"),
mConfigSaveActive(true)
{
oldConfigType = checkForGlobalSigConfig();
// configuration to load correct global types
pqiConfig::globalConfigType = oldConfigType;
}
void p3ConfigMgr::tick()
@ -123,242 +118,13 @@ void p3ConfigMgr::saveConfig()
}
/* save metaconfig */
}
if(ok && oldConfigType)
removeOldConfigType();
return;
}
void p3ConfigMgr::removeOldConfigType()
{
std::string fName = basedir + "/" + metafname;
std::string sigfName = basedir + "/" + metasigfname;
remove(fName.c_str());
remove(sigfName.c_str());
//now set globalconfig type to false so mgr saves
oldConfigType = false;
pqiConfig::globalConfigType = oldConfigType;
}
void p3ConfigMgr::globalSaveConfig()
{
RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::globalSaveConfig()";
std::cerr << std::endl;
#endif
RsConfigKeyValueSet *item = new RsConfigKeyValueSet();
std::map<uint32_t, pqiConfig *>::iterator it;
for(it = configs.begin(); it != configs.end(); it++)
{
if (it->second->HasConfigChanged(1))
{
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::globalSaveConfig() Saving Element: ";
std::cerr << it->first;
std::cerr << std::endl;
#endif
it->second->saveConfiguration();
}
/* save metaconfig */
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::globalSaveConfig() Element: ";
std::cerr << it->first << " Hash: " << it->second->Hash();
std::cerr << std::endl;
#endif
if (it->second->Hash() == "")
{
/* skip if no hash */
continue;
}
RsTlvKeyValue kv;
rs_sprintf(kv.key, "%lu", it->first);
kv.value = it->second->Hash();
item->tlvkvs.pairs.push_back(kv);
}
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::globalSaveConfig() Complete MetaConfigItem: ";
std::cerr << std::endl;
item->print(std::cerr, 20);
#endif
/* construct filename */
std::string fname = basedir;
std::string sign_fname = basedir;
std::string fname_backup, sign_fname_backup; // back up files
if (basedir != "")
{
fname += "/";
sign_fname += "/";
}
fname += metafname;
sign_fname += metasigfname;
fname_backup = fname + ".tmp";
sign_fname_backup = sign_fname + ".tmp";
/* Write the data to a stream */
uint32_t bioflags = BIN_FLAGS_WRITEABLE;
BinMemInterface *configbio = new BinMemInterface(1000, bioflags);
RsSerialiser *rss = new RsSerialiser();
rss->addSerialType(new RsGeneralConfigSerialiser());
pqistore store(rss, "CONFIG", configbio, BIN_FLAGS_WRITEABLE);
store.SendItem(item);
/* sign data */
std::string signature;
AuthSSL::getAuthSSL()->SignData(configbio->memptr(), configbio->memsize(), signature);
/* write signature to configuration */
BinMemInterface *signbio = new BinMemInterface(signature.c_str(),
signature.length(), BIN_FLAGS_READABLE);
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::globalSaveConfig() MetaFile Signature:";
std::cerr << std::endl;
std::cerr << signature;
std::cerr << std::endl;
#endif
// begin two pass save
backedUpFileSave(fname, fname_backup, sign_fname, sign_fname_backup, configbio, signbio);
delete signbio;
}
bool p3ConfigMgr::backedUpFileSave(const std::string& fname, const std::string& fname_backup, const std::string& sign_fname,
const std::string& sign_fname_backup, BinMemInterface* configbio, BinMemInterface* signbio){
FILE *file = NULL, *sign = NULL;
char *config_buff=NULL, *sign_buff=NULL;
int size_file=0, size_sign=0;
// begin two pass saving by writing to back up file instead
if (!configbio->writetofile(fname_backup.c_str()) || !signbio->writetofile(sign_fname_backup.c_str()))
{
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::backedupFileSave() Failed write to Backup MetaFiles " << fname_backup
<< " and " << sign_fname_backup;
std::cerr << std::endl;
#endif
return false;
}
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::backedUpFileSave() Save file and keeps a back up " << std::endl;
#endif
// open file from which to collect buffer
file = RsDirUtil::rs_fopen(fname.c_str(), "rb");
sign = RsDirUtil::rs_fopen(sign_fname.c_str(), "rb");
// if failed then create files
if((file == NULL) || (sign == NULL)){
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::backedUpFileSave() failed to open meta files " << fname << std::endl;
#endif
file = RsDirUtil::rs_fopen(fname.c_str(), "wb");
sign = RsDirUtil::rs_fopen(sign_fname.c_str(), "wb");
if((file == NULL) || (sign == NULL)){
std::cerr << "p3Config::backedUpFileSave() failed to open backup meta files" << fname_backup << std::endl;
return false;
}
}
//determine file size
fseek(file, 0L, SEEK_END);
size_file = ftell(file);
fseek(file, 0L, SEEK_SET);
fseek(sign, 0L, SEEK_END);
size_sign = ftell(sign);
fseek(sign, 0L, SEEK_SET);
if((size_file) > 0 && (size_sign > 0)){
//read this into a buffer
config_buff = new char[size_file];
fread(config_buff, 1, size_file, file);
//read this into a buffer
sign_buff = new char[size_sign];
fread(sign_buff, 1, size_sign, sign);
}
fclose(file);
fclose(sign);
// rename back-up to current file
if(!RsDirUtil::renameFile(fname_backup, fname) || !RsDirUtil::renameFile(sign_fname_backup, sign_fname)){
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::backedUpFileSave() Failed to rename backup meta files: " << std::endl
<< fname_backup << " to " << fname << std::endl
<< sign_fname_backup << " to " << sign_fname << std::endl;
#endif
if (config_buff)
delete[] config_buff;
if (sign_buff)
delete[] sign_buff;
return true;
}
if((size_file) > 0 && (size_sign > 0)){
// now write actual back-up file
file = RsDirUtil::rs_fopen(fname_backup.c_str(), "wb");
sign = RsDirUtil::rs_fopen(sign_fname_backup.c_str(), "wb");
if((file == NULL) || (sign == NULL)){
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::backedUpFileSave() fopen failed for file: " << fname_backup << std::endl;
#endif
delete[] config_buff;
delete[] sign_buff;
return true;
}
if(size_file != (int) fwrite(config_buff,1, size_file, file))
RsServer::notify()->AddSysMessage(0, RS_SYS_WARNING, "Write error", "Error while writing backup configuration file " + fname_backup + "\nIs your disc full or out of quota ?");
if(size_sign != (int) fwrite(sign_buff, 1, size_sign, sign))
RsServer::notify()->AddSysMessage(0, RS_SYS_WARNING, "Write error", "Error while writing main signature file " + sign_fname_backup + "\nIs your disc full or out of quota ?");
fclose(file);
fclose(sign);
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::backedUpFileSave() finished backed up save. " << std::endl;
#endif
delete[] config_buff;
delete[] sign_buff;
}
return true;
}
void p3ConfigMgr::loadConfiguration()
{
if(oldConfigType)
globalLoadConfig();
else
loadConfig();
loadConfig();
return;
}
@ -385,222 +151,6 @@ void p3ConfigMgr::loadConfig()
return;
}
void p3ConfigMgr::globalLoadConfig()
{
RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::loadConfiguration()";
std::cerr << std::endl;
#endif
/* construct filename */
std::string fname = basedir;
std::string sign_fname = basedir;
std::string fname_backup, sign_fname_backup;
if (basedir != "")
{
fname += "/";
sign_fname += "/";
}
fname += metafname;
sign_fname += metasigfname;
// temporary files
fname_backup = fname + ".tmp";
sign_fname_backup = sign_fname + ".tmp";
BinMemInterface* membio = new BinMemInterface(1000, BIN_FLAGS_READABLE);
// Will attempt to get signature first from meta file then if that fails try temporary meta files, these will correspond to temp configs
bool pass = getSignAttempt(fname, sign_fname, membio);
// if first attempt fails then try and temporary files
if(!pass){
#ifdef CONFIG_DEBUG
std::cerr << "\np3ConfigMgr::loadConfiguration(): Trying to load METACONFIG item and METASIGN with temporary files";
std::cerr << std::endl;
#endif
pass = getSignAttempt(fname_backup, sign_fname_backup , membio);
if(!pass){
#ifdef CONFIG_DEBUG
std::cerr << "\np3ConfigMgr::loadConfiguration(): failed to load METACONFIG item and METASIGN";
std::cerr << std::endl;
#endif
return;
}
}
membio->fseek(0); /* go back to start of file */
RsSerialiser *rss = new RsSerialiser();
rss->addSerialType(new RsGeneralConfigSerialiser());
pqistore stream(rss, "CONFIG", membio, BIN_FLAGS_READABLE);
RsItem *rsitem = stream.GetItem();
RsConfigKeyValueSet *item = dynamic_cast<RsConfigKeyValueSet *>(rsitem);
if (!item)
{
delete rsitem;
return;
}
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::loadConfiguration() Loaded MetaConfigItem: ";
std::cerr << std::endl;
item->print(std::cerr, 20);
#endif
/* extract info from KeyValueSet */
std::list<RsTlvKeyValue>::iterator it;
for(it = item->tlvkvs.pairs.begin(); it != item->tlvkvs.pairs.end(); it++)
{
/* find the configuration */
uint32_t confId = atoi(it->key.c_str());
std::string hashin = it->value;
/*********************** HACK TO CHANGE CACHE CONFIG ID *********
* REMOVE IN A MONTH OR TWO
*/
if (confId == CONFIG_TYPE_CACHE_OLDID)
{
confId = CONFIG_TYPE_CACHE;
}
/*********************** HACK TO CHANGE CACHE CONFIG ID *********/
std::map<uint32_t, pqiConfig *>::iterator cit;
cit = configs.find(confId);
if (cit != configs.end())
{
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::loadConfiguration() Element: ";
std::cerr << confId << " Hash: " << hashin;
std::cerr << std::endl;
#endif
(cit->second)->loadConfiguration(hashin);
/* force config to CHANGED to force saving into new non-global sig format */
cit->second->IndicateConfigChanged();
// cit->second->HasConfigChanged(0);
// cit->second->HasConfigChanged(1);
}
}
delete item;
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::loadConfiguration() Done!";
std::cerr << std::endl;
#endif
}
bool p3ConfigMgr::getSignAttempt(std::string& metaConfigFname, std::string& metaSignFname, BinMemInterface* membio){
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::getSignAttempt() metaConfigFname : " << metaConfigFname;
std::cerr << std::endl;
std::cerr << "p3ConfigMgr::getSignAttempt() metaSignFname : " << metaSignFname;
std::cerr << std::endl;
#endif
/* read signature */
BinMemInterface *signbio = new BinMemInterface(1000, BIN_FLAGS_READABLE);
if (!signbio->readfromfile(metaSignFname.c_str()))
{
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::getSignAttempt() Failed to Load MetaSignFile";
std::cerr << std::endl;
#endif
/* HACK to load the old one (with the wrong directory)
* THIS SHOULD BE REMOVED IN A COUPLE OF VERSIONS....
* ONLY HERE TO CORRECT BAD MISTAKE IN EARLIER VERSIONS.
*/
metaSignFname = metasigfname;
metaConfigFname = metafname;
if (!signbio->readfromfile(metaSignFname.c_str()))
{
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::getSignAttempt() HACK: Failed to Load ALT MetaSignFile";
std::cerr << std::endl;
#endif
}
else
{
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::getSignAttempt() HACK: Loaded ALT MetaSignFile";
std::cerr << std::endl;
#endif
}
}
std::string oldsignature((char *) signbio->memptr(), signbio->memsize());
delete signbio;
if (!membio->readfromfile(metaConfigFname.c_str()))
{
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::getSignAttempt() Failed to Load MetaFile";
std::cerr << std::endl;
#endif
// delete membio;
// return ;
}
/* get signature */
std::string signature;
AuthSSL::getAuthSSL()->SignData(membio->memptr(), membio->memsize(), signature);
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::getSignAttempt() New MetaFile Signature:";
std::cerr << std::endl;
std::cerr << signature;
std::cerr << std::endl;
#endif
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::getSignAttempt() Orig MetaFile Signature:";
std::cerr << std::endl;
std::cerr << oldsignature;
std::cerr << std::endl;
#endif
if (signature != oldsignature)
{
/* Failed */
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::getSignAttempt() Signature Check Failed";
std::cerr << std::endl;
#endif
return false;
}
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::getSignAttempt() Signature Check Passed!";
std::cerr << std::endl;
#endif
return true;
}
void p3ConfigMgr::addConfiguration(std::string file, pqiConfig *conf)
{
@ -635,32 +185,7 @@ void p3ConfigMgr::completeConfiguration()
mConfigSaveActive = false;
}
bool p3ConfigMgr::checkForGlobalSigConfig()
{
bool oldTypeExists;
FILE *metaFile = NULL, *metaSig = NULL;
std::string fName = basedir + "/" + metafname;
std::string sigName = basedir + "/" + metasigfname;
metaFile = RsDirUtil::rs_fopen(fName.c_str(), "r");
metaSig = RsDirUtil::rs_fopen(sigName.c_str(), "r");
// check if files exist
if((metaFile != NULL) && (metaSig != NULL))
{
oldTypeExists = true;
fclose(metaFile);
fclose(metaSig);
}
else
oldTypeExists = false;
return oldTypeExists;
}
p3Config::p3Config(uint32_t t)
:pqiConfig(t)
@ -671,10 +196,7 @@ p3Config::p3Config(uint32_t t)
bool p3Config::loadConfiguration(std::string &loadHash)
{
if(globalConfigType)
return loadGlobalConfig(loadHash);
else
return loadConfig();
return loadConfig();
}
bool p3Config::loadConfig()
@ -790,128 +312,6 @@ bool p3Config::loadAttempt(const std::string& cfgFname,const std::string& signFn
return true;
}
bool p3Config::loadGlobalConfig(std::string &loadHash)
{
bool pass = false;
std::string cfg_fname = Filename();
std::string cfg_fname_backup = cfg_fname + ".tmp";
std::string hashstr;
std::list<RsItem *> load;
#ifdef CONFIG_DEBUG
std::string success_fname = cfg_fname;
std::cerr << "p3Config::loadConfiguration(): Attempting to load configuration file" << cfg_fname << std::endl;
#endif
pass = getHashAttempt(loadHash, hashstr, cfg_fname, load);
if(!pass){
load.clear();
pass = getHashAttempt(loadHash, hashstr, cfg_fname_backup, load);
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::loadConfiguration() ERROR: Failed to get Hash from " << success_fname << std::endl;
success_fname = cfg_fname_backup;
#endif
if(!pass){
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::loadConfiguration() ERROR: Failed to get Hash from " << success_fname << std::endl;
#endif
return false;
}
}
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::loadConfiguration(): SUCCESS: configuration file loaded" << success_fname << std::endl;
#endif
setHash(hashstr);
return loadList(load);
}
bool p3Config::getHashAttempt(const std::string& loadHash, std::string& hashstr,const std::string& cfg_fname,
std::list<RsItem *>& load){
std::list<RsItem *>::iterator it;
uint32_t bioflags = BIN_FLAGS_HASH_DATA | BIN_FLAGS_READABLE;
BinInterface *bio = new BinFileInterface(cfg_fname.c_str(), bioflags);
PQInterface *stream = NULL;
std::string tempString, msgConfigFileName;
std::string filename = Filename() ;
std::string::reverse_iterator rit = filename.rbegin();
// get the msgconfig file name
for(int i =0; (i <= 7) && (rit != filename.rend()); i++)
{
tempString.push_back(*rit);
rit++;
}
rit = tempString.rbegin();
for(; rit !=tempString.rend(); rit++)
msgConfigFileName.push_back(*rit);
if(msgConfigFileName == "msgs.cfg")
stream = new pqiarchive(setupSerialiser(), bio, bioflags);
else
stream = new pqistore(setupSerialiser(), "CONFIG", bio, bioflags);
RsItem *item = NULL;
while(NULL != (item = stream->GetItem()))
{
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::loadConfiguration() loaded item:";
std::cerr << std::endl;
item->print(std::cerr, 0);
std::cerr << std::endl;
#endif
load.push_back(item);
}
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::loadConfiguration() loaded " << load.size();
std::cerr << " Elements from File: " << cfg_fname;
std::cerr << std::endl;
#endif
/* check hash */
hashstr = bio->gethash();
// if hash then atmpt load with temporary file
if (hashstr != loadHash)
{
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::loadConfiguration() ERROR: Hash != MATCHloaded";
std::cerr << std::endl;
#endif
/* bad load */
for(it = load.begin(); it != load.end(); it++)
{
delete (*it);
}
setHash("");
delete stream;
return false;
}
delete stream;
return true;
}
bool p3Config::saveConfiguration()
{
return saveConfig();
@ -1003,176 +403,6 @@ bool p3Config::saveConfig()
}
bool p3Config::saveGlobalConfig()
{
bool cleanup = true;
std::list<RsItem *> toSave;
saveList(cleanup, toSave);
std::string cfg_fname = Filename(); // get configuration file name
std::string cfg_fname_backup = Filename()+".tmp"; // backup file for two pass save
#ifdef CONFIG_DEBUG
std::cerr << "Writting p3config file " << cfg_fname << std::endl ;
std::cerr << "p3Config::saveConfiguration() toSave " << toSave.size();
std::cerr << " Elements to File: " << cfg_fname;
std::cerr << std::endl;
#endif
// saves current config and keeps back-up (old configuration)
if(!backedUpFileSave(cfg_fname, cfg_fname_backup, toSave, cleanup)){
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::saveConfiguration(): Failed to save file" << std::endl;
#endif
return false;
}
saveDone(); // callback to inherited class to unlock any Mutexes protecting saveList() data
return true;
}
bool p3Config::backedUpFileSave(const std::string& cfg_fname, const std::string& cfg_fname_backup, std::list<RsItem* >& itemList,
bool cleanup){
uint32_t bioflags = BIN_FLAGS_HASH_DATA | BIN_FLAGS_WRITEABLE;
uint32_t stream_flags = BIN_FLAGS_WRITEABLE;
bool written = true;
FILE* cfg_file = NULL;
char* buff=NULL;
int size_file = 0;
if (!cleanup)
stream_flags |= BIN_FLAGS_NO_DELETE;
BinInterface *bio = new BinFileInterface(cfg_fname_backup.c_str(), bioflags);
pqistore *stream = new pqistore(setupSerialiser(), "CONFIG", bio, stream_flags);
std::list<RsItem *>::iterator it;
for(it = itemList.begin(); it != itemList.end(); it++)
{
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::backedUpFileSave() save item:";
std::cerr << std::endl;
(*it)->print(std::cerr, 0);
std::cerr << std::endl;
#endif
written = written && stream->SendItem(*it);
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::backedUpFileSave() saved ";
#endif
}
/* store the hash */
setHash(bio->gethash());
// bio is taken care of in stream's destructor
delete stream;
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::backedUpFileSave() Save file and keeps a back up " << std::endl;
#endif
// open file from which to collect buffer
cfg_file = RsDirUtil::rs_fopen(cfg_fname.c_str(), "rb");
// if it fails to open, create file,but back-up file will now be empty
if(cfg_file == NULL){
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::backedUpFileSave() fopen failed for file: " << cfg_fname << std::endl;
#endif
cfg_file = RsDirUtil::rs_fopen(cfg_fname.c_str(), "wb");
if(cfg_file == NULL)
{
std::cerr << "p3Config::backedUpFileSave() fopen failed for file:" << cfg_fname << std::endl;
return false ;
}
}
//determine file size
fseek(cfg_file, 0L, SEEK_END);
size_file = ftell(cfg_file);
if(size_file < 0) // ftell returns -1 when fails
{
fclose(cfg_file);
size_file = 0 ;
}
fseek(cfg_file, 0L, SEEK_SET);
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::backedUpFileSave(): Size of file: " << size_file << std::endl;
#endif
// no point continuing, empty files all have same hash
if(size_file > 0){
//read this into a data buffer
buff = new char[size_file];
fread(buff, 1, size_file, cfg_file);
}
fclose(cfg_file);
// rename back-up to current file, if this fails should return false hash's will not match at startup
if(!RsDirUtil::renameFile(cfg_fname_backup, cfg_fname)){
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::backedUpFileSave() Failed to rename file" << cfg_fname_backup << " to "
<< cfg_fname << std::endl;
#endif
written &= false; // at least one file save should be successful
}
if(size_file > 0)
{
// now write actual back-up file
cfg_file = RsDirUtil::rs_fopen(cfg_fname_backup.c_str(), "wb");
if(cfg_file == NULL){
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::backedUpFileSave() fopen failed for file: " << cfg_fname_backup << std::endl;
#endif
}
if(size_file != (int) fwrite(buff, 1, size_file, cfg_file))
{
RsServer::notify()->AddSysMessage(0, RS_SYS_WARNING, "Write error", "Error while writing backup configuration file " + cfg_fname_backup + "\nIs your disc full or out of quota ?");
fclose(cfg_file);
delete[] buff;
return false ;
}
fclose(cfg_file);
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::backedUpFileSave() finished backed up save. " << std::endl;
#endif
delete[] buff;
written |= true; // either backup or current file should have been saved
}
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::backedUpFileSave() finished backed up save. " << std::endl;
#endif
return written;
}
/**************************** CONFIGURATION CLASSES ********************/
p3GeneralConfig::p3GeneralConfig()
@ -1313,8 +543,6 @@ bool p3GeneralConfig::loadList(std::list<RsItem *>& load)
* only the Indication and hash really need it
*/
bool pqiConfig::globalConfigType = false;
pqiConfig::pqiConfig(uint32_t t)
: cfgMtx("pqiConfig"), ConfInd(2), type(t)
{

View file

@ -63,7 +63,6 @@ const uint32_t CONFIG_TYPE_GENERAL = 0x0001;
const uint32_t CONFIG_TYPE_PEERS = 0x0002;
const uint32_t CONFIG_TYPE_FSERVER = 0x0003;
const uint32_t CONFIG_TYPE_MSGS = 0x0004;
const uint32_t CONFIG_TYPE_CACHE_OLDID = 0x0005;
const uint32_t CONFIG_TYPE_AUTHGPG = 0x0006;
/* new FileTransfer */
@ -155,8 +154,6 @@ void setHash(const std::string& h);
RsMutex cfgMtx;
static bool globalConfigType;
private:
/**
@ -200,10 +197,8 @@ class p3ConfigMgr
/**
* @param bdir base directory: where config files will be saved
* @param fname file name for global configuration
* @param signame file name for global signature
*/
p3ConfigMgr(std::string bdir, std::string fname, std::string signame);
p3ConfigMgr(std::string bdir);
/**
* checks and update all added configurations
@ -237,31 +232,6 @@ class p3ConfigMgr
private:
/**
* this checks for the global config file and signature and determines class's mode of operation
* @return global file rs-v0.#.cfg and rs-v0.#.sgn are present
* @deprecated
*/
bool checkForGlobalSigConfig();
/**
* removes theoldconfiguration type
* @deprecated
*/
void removeOldConfigType();
/**
* to save old style global-signature configuration files
* @deprecated
*/
void globalSaveConfig();
/**
* to load up old style global-signature config files
* @deprecated
*/
void globalLoadConfig();
/**
* saves configuration of pqiconfigs in object configs
*/
@ -272,33 +242,10 @@ class p3ConfigMgr
*/
void loadConfig();
/**
* checks if signature and configuration file's signature matches
* @return false if signature file does not match configuration file's signature
*/
bool getSignAttempt(std::string& metaConfigFname, std::string& metaSignFname, BinMemInterface* membio);
/**
* takes current configuration which is stored in back-up file, and moves it to actual config file
* then stores data that was in actual config file into back-up, Corresponding signatures and handled
* simlarly in parallel
*@param fname the name of the first configuration file checked
*@param fname_backup the seconf file, backup, checked if first file does not exist or is corrupted
*@param sign file name in which signature is kept
*@param sign_backup file name in which signature which correspond to backup config is kept
*@param configbio to write config to file
*@param signbio to write signature config to file
*/
bool backedUpFileSave(const std::string& fname, const std::string& fname_backup,const std::string& sign,
const std::string& sign_backup, BinMemInterface* configbio, BinMemInterface* signbio);
const std::string basedir;
const std::string metafname;
const std::string metasigfname;
RsMutex cfgMtx; /* below is protected */
bool oldConfigType;
bool mConfigSaveActive;
std::map<uint32_t, pqiConfig *> configs;
};
@ -351,26 +298,9 @@ virtual void saveDone() { return; }
private:
/**
* takes current configuration which is stored in back-up file, and moves it to actual config file
* then stores data that was in actual config file into back-up, This is an rs specific solution
* @param fname the name of the first configuration file checked
* @param fname_backup the seconf file, backup, checked if first file does not exist or is corrupted
*/
bool backedUpFileSave(const std::string& fname, const std::string& fname_backup, std::list<RsItem* >& toSave,
bool cleanup);
/*
* for retrieving hash files
*/
bool getHashAttempt(const std::string& loadHash, std::string& hashstr, const std::string& fname, std::list<RsItem *>& load);
bool loadConfig();
bool saveConfig();
bool loadGlobalConfig(std::string& hash);
bool saveGlobalConfig();
bool loadAttempt(const std::string&,const std::string&, std::list<RsItem *>& load);
}; /* end of p3Config */

View file

@ -109,7 +109,8 @@ void p3HistoryMgr::addMessage(bool incoming, const std::string &chatPeerId, cons
item->saveToDisc = false;
}
librs::util::ConvertUtf16ToUtf8(chatItem->message, item->message);
item->message = chatItem->message ;
//librs::util::ConvertUtf16ToUtf8(chatItem->message, item->message);
std::map<std::string, std::map<uint32_t, RsHistoryMsgItem*> >::iterator mit = mMessages.find(item->chatPeerId);
if (mit != mMessages.end()) {

View file

@ -58,6 +58,11 @@ const int p3connectzone = 3431;
* #define LINKMGR_DEBUG_LINKTYPE 1
***/
#define LINKMGR_DEBUG 1
#define LINKMGR_DEBUG_CONNFAIL 1
#define LINKMGR_DEBUG_ACTIONS 1
#define LINKMGR_DEBUG_LINKTYPE 1
/****
* #define DISABLE_UDP_CONNECTIONS 1
***/
@ -85,9 +90,9 @@ const uint32_t P3CONNMGR_UDP_DEFAULT_PERIOD = 30; // this represents how long i
void printConnectState(std::ostream &out, peerConnectState &peer);
peerConnectAddress::peerConnectAddress()
:delay(0), period(0), type(0), flags(0), ts(0)
:delay(0), period(0), type(0), flags(0), ts(0), domain_port(0)
{
sockaddr_clear(&addr);
sockaddr_storage_clear(addr);
}
@ -136,7 +141,6 @@ p3LinkMgrIMPL::p3LinkMgrIMPL(p3PeerMgrIMPL *peerMgr, p3NetMgrIMPL *netMgr)
{
RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/
mAllowTunnelConnection = false;
mDNSResolver = new DNSResolver();
mRetryPeriod = MIN_RETRY_PERIOD;
@ -145,10 +149,13 @@ p3LinkMgrIMPL::p3LinkMgrIMPL(p3PeerMgrIMPL *peerMgr, p3NetMgrIMPL *netMgr)
/* setup Banned Ip Address - static for now
*/
struct in_addr bip;
memset(&bip, 0, sizeof(bip));
bip.s_addr = 1;
struct sockaddr_storage bip;
sockaddr_storage_clear(bip);
struct sockaddr_in *addr = (struct sockaddr_in *) &bip;
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = 1;
addr->sin_port = htons(0);
mBannedIpList.push_back(bip);
}
@ -159,19 +166,7 @@ p3LinkMgrIMPL::p3LinkMgrIMPL(p3PeerMgrIMPL *peerMgr, p3NetMgrIMPL *netMgr)
return;
}
void p3LinkMgrIMPL::setTunnelConnection(bool b)
{
RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/
mAllowTunnelConnection = b;
}
bool p3LinkMgrIMPL::getTunnelConnection()
{
RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/
return mAllowTunnelConnection;
}
bool p3LinkMgrIMPL::setLocalAddress(struct sockaddr_in addr)
bool p3LinkMgrIMPL::setLocalAddress(const struct sockaddr_storage &addr)
{
RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/
mLocalAddress = addr;
@ -179,10 +174,11 @@ bool p3LinkMgrIMPL::setLocalAddress(struct sockaddr_in addr)
return true ;
}
struct sockaddr_in p3LinkMgrIMPL::getLocalAddress()
bool p3LinkMgrIMPL::getLocalAddress(struct sockaddr_storage &addr)
{
RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/
return mLocalAddress;
addr = mLocalAddress;
return true;
}
@ -586,10 +582,11 @@ const std::string p3LinkMgrIMPL::getOwnId()
}
bool p3LinkMgrIMPL::connectAttempt(const std::string &id, struct sockaddr_in &raddr,
struct sockaddr_in &proxyaddr,
struct sockaddr_in &srcaddr,
uint32_t &delay, uint32_t &period, uint32_t &type, uint32_t &flags, uint32_t &bandwidth)
bool p3LinkMgrIMPL::connectAttempt(const std::string &id, struct sockaddr_storage &raddr,
struct sockaddr_storage &proxyaddr,
struct sockaddr_storage &srcaddr,
uint32_t &delay, uint32_t &period, uint32_t &type, uint32_t &flags, uint32_t &bandwidth,
std::string &domain_addr, uint16_t &domain_port)
{
RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/
@ -643,6 +640,9 @@ bool p3LinkMgrIMPL::connectAttempt(const std::string &id, struct sockaddr_in &ra
srcaddr = it->second.currentConnAddrAttempt.srcaddr;
bandwidth = it->second.currentConnAddrAttempt.bandwidth;
domain_addr = it->second.currentConnAddrAttempt.domain_addr;
domain_port = it->second.currentConnAddrAttempt.domain_port;
/********* Setup LinkType parameters **********/
#define TRICKLE_LIMIT 2001 // 2kb
@ -692,13 +692,6 @@ bool p3LinkMgrIMPL::connectAttempt(const std::string &id, struct sockaddr_in &ra
it->second.linkType |= RS_NET_CONN_TRANS_UDP_UNKNOWN;
}
}
else if (type & RS_NET_CONN_TUNNEL)
{
#ifdef LINKMGR_DEBUG_LINKTYPE
std::cerr << "p3LinkMgrIMPL::connectAttempt() type & TUNNEL => TUNNEL" << std::endl;
#endif
it->second.linkType |= RS_NET_CONN_TRANS_TUNNEL;
}
else
{
#ifdef LINKMGR_DEBUG_LINKTYPE
@ -748,7 +741,7 @@ bool p3LinkMgrIMPL::connectAttempt(const std::string &id, struct sockaddr_in &ra
std::cerr << "p3LinkMgrIMPL::connectAttempt() found an address: id: " << id << std::endl;
std::cerr << " laddr: " << rs_inet_ntoa(raddr.sin_addr) << " lport: " << ntohs(raddr.sin_port) << " delay: " << delay << " period: " << period;
std::cerr << " laddr: " << sockaddr_storage_tostring(raddr) << " delay: " << delay << " period: " << period;
std::cerr << " type: " << type << std::endl;
std::cerr << "p3LinkMgrIMPL::connectAttempt() set LinkType to: " << it->second.linkType << std::endl;
#endif
@ -758,11 +751,11 @@ bool p3LinkMgrIMPL::connectAttempt(const std::string &id, struct sockaddr_in &ra
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::connectAttempt() found an address: id: " << id << std::endl;
std::cerr << " laddr: " << rs_inet_ntoa(addr.sin_addr) << " lport: " << ntohs(addr.sin_port) << " delay: " << delay << " period: " << period;
std::cerr << " laddr: " << sockaddr_storage_tostring(raddr) << " delay: " << delay << " period: " << period;
std::cerr << " type: " << type << std::endl;
std::cerr << "p3LinkMgrIMPL::connectAttempt() set LinkType to: " << it->second.linkType << std::endl;
#endif
if (raddr.sin_addr.s_addr == 0 || raddr.sin_port == 0) {
if (sockaddr_storage_isnull(raddr)) {
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::connectAttempt() WARNING: address or port is null" << std::endl;
std::cerr << " type: " << type << std::endl;
@ -781,7 +774,7 @@ bool p3LinkMgrIMPL::connectAttempt(const std::string &id, struct sockaddr_in &ra
*
*/
bool p3LinkMgrIMPL::connectResult(const std::string &id, bool success, uint32_t flags, struct sockaddr_in remote_peer_address)
bool p3LinkMgrIMPL::connectResult(const std::string &id, bool success, uint32_t flags, const struct sockaddr_storage &remote_peer_address)
{
bool doDhtAssist = false ;
bool updatePeerAddr = false;
@ -875,10 +868,7 @@ bool p3LinkMgrIMPL::connectResult(const std::string &id, bool success, uint32_t
// This means we only update connections that we've made.. so maybe not too bad?
if ((it->second.inConnAttempt) &&
(it->second.currentConnAddrAttempt.addr.sin_addr.s_addr
== remote_peer_address.sin_addr.s_addr) &&
(it->second.currentConnAddrAttempt.addr.sin_port
== remote_peer_address.sin_port))
(sockaddr_storage_same(it->second.currentConnAddrAttempt.addr, remote_peer_address)))
{
updatePeerAddr = true;
#ifdef LINKMGR_DEBUG
@ -1004,7 +994,7 @@ bool p3LinkMgrIMPL::connectResult(const std::string &id, bool success, uint32_t
mNetMgr->netAssistFriend(id,false);
/* inform NetMgr that we know this peers address: but only if external address */
if (isExternalNet(&(remote_peer_address.sin_addr)))
if (sockaddr_storage_isExternalNet(remote_peer_address))
{
mNetMgr->netAssistKnownPeer(id,remote_peer_address,
NETASSIST_KNOWN_PEER_FRIEND | NETASSIST_KNOWN_PEER_ONLINE);
@ -1040,7 +1030,7 @@ bool p3LinkMgrIMPL::connectResult(const std::string &id, bool success, uint32_t
*/
// from pqissl, when a connection failed due to security
void p3LinkMgrIMPL::notifyDeniedConnection(const std::string& gpgid,const std::string& sslid,const std::string& sslcn,const struct sockaddr_in &addr, bool incoming)
void p3LinkMgrIMPL::notifyDeniedConnection(const std::string& gpgid,const std::string& sslid,const std::string& sslcn,const struct sockaddr_storage &addr, bool incoming)
{
std::cerr << "p3LinkMgrIMPL::notifyDeniedConnection()";
std::cerr << " pgpid: " << gpgid;
@ -1097,7 +1087,8 @@ void p3LinkMgrIMPL::peerStatus(std::string id, const pqiIpAddrSet &addrs,
details.ts = now;
bool updateNetConfig = (source == RS_CB_PERSON);
uint32_t peerVisibility = 0;
uint32_t peer_vs_disc = 0;
uint32_t peer_vs_dht = 0;
uint32_t peerNetMode = 0;
uint32_t ownNetMode = mNetMgr->getNetworkMode();
@ -1231,20 +1222,20 @@ void p3LinkMgrIMPL::peerStatus(std::string id, const pqiIpAddrSet &addrs,
/* always update VIS status */
if (flags & RS_NET_FLAGS_USE_DISC)
{
peerVisibility &= (~RS_VIS_STATE_NODISC);
peer_vs_disc = RS_VS_DISC_FULL;
}
else
{
peerVisibility |= RS_VIS_STATE_NODISC;
peer_vs_disc = RS_VS_DISC_OFF;
}
if (flags & RS_NET_FLAGS_USE_DHT)
{
peerVisibility &= (~RS_VIS_STATE_NODHT);
peer_vs_dht = RS_VS_DHT_FULL;
}
else
{
peerVisibility |= RS_VIS_STATE_NODHT;
peer_vs_dht = RS_VS_DHT_OFF;
}
@ -1315,7 +1306,7 @@ void p3LinkMgrIMPL::peerStatus(std::string id, const pqiIpAddrSet &addrs,
bool newAddrs = mPeerMgr->updateAddressList(id, addrs);
if (updateNetConfig)
{
mPeerMgr -> setVisState(id, peerVisibility);
mPeerMgr -> setVisState(id, peer_vs_disc, peer_vs_dht);
mPeerMgr -> setNetworkMode(id, peerNetMode);
}
@ -1353,14 +1344,14 @@ void p3LinkMgrIMPL::peerStatus(std::string id, const pqiIpAddrSet &addrs,
}
/* This has become very unwieldy - as extra arguments are required for UDP connections */
void p3LinkMgrIMPL::peerConnectRequest(std::string id, struct sockaddr_in raddr, struct sockaddr_in proxyaddr, struct sockaddr_in srcaddr,
void p3LinkMgrIMPL::peerConnectRequest(std::string id, const struct sockaddr_storage &raddr, const struct sockaddr_storage &proxyaddr, const struct sockaddr_storage &srcaddr,
uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth)
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::peerConnectRequest() id: " << id;
std::cerr << " raddr: " << rs_inet_ntoa(raddr.sin_addr) << ":" << ntohs(raddr.sin_port);
std::cerr << " proxyaddr: " << rs_inet_ntoa(proxyaddr.sin_addr) << ":" << ntohs(proxyaddr.sin_port);
std::cerr << " srcaddr: " << rs_inet_ntoa(srcaddr.sin_addr) << ":" << ntohs(srcaddr.sin_port);
std::cerr << " raddr: " << sockaddr_storage_tostring(raddr);
std::cerr << " proxyaddr: " << sockaddr_storage_tostring(proxyaddr);
std::cerr << " srcaddr: " << sockaddr_storage_tostring(srcaddr);
std::cerr << " source: " << source;
std::cerr << " flags: " << flags;
std::cerr << " delay: " << delay;
@ -1370,9 +1361,13 @@ void p3LinkMgrIMPL::peerConnectRequest(std::string id, struct sockaddr_in rad
{
/* Log */
std::string out = "p3LinkMgrIMPL::peerConnectRequest() id: " + id;
rs_sprintf_append(out, " raddr: %s:%u", rs_inet_ntoa(raddr.sin_addr).c_str(), ntohs(raddr.sin_port));
rs_sprintf_append(out, " proxyaddr: %s:%u", rs_inet_ntoa(proxyaddr.sin_addr).c_str(), ntohs(proxyaddr.sin_port));
rs_sprintf_append(out, " srcaddr: %s:%u", rs_inet_ntoa(srcaddr.sin_addr).c_str(), ntohs(srcaddr.sin_port));
out += " raddr: ";
out += sockaddr_storage_tostring(raddr);
out += " proxyaddr: ";
out += sockaddr_storage_tostring(proxyaddr);
out += " srcaddr: ";
out += sockaddr_storage_tostring(srcaddr);
rs_sprintf_append(out, " source: %lu", source);
rs_sprintf_append(out, " flags: %lu", flags);
rs_sprintf_append(out, " delay: %lu", delay);
@ -1420,7 +1415,7 @@ void p3LinkMgrIMPL::peerConnectRequest(std::string id, struct sockaddr_in rad
return;
}
/* setup specific attempt for DHT found address. */
locked_ConnectAttempt_SpecificAddress(&(it->second), &raddr);
locked_ConnectAttempt_SpecificAddress(&(it->second), raddr);
}
retryConnect(id);
@ -1472,8 +1467,8 @@ bool p3LinkMgrIMPL::retryConnect(const std::string &id)
bool p3LinkMgrIMPL::tryConnectUDP(const std::string &id, struct sockaddr_in &rUdpAddr,
struct sockaddr_in &proxyaddr, struct sockaddr_in &srcaddr,
bool p3LinkMgrIMPL::tryConnectUDP(const std::string &id, const struct sockaddr_storage &rUdpAddr,
const struct sockaddr_storage &proxyaddr, const struct sockaddr_storage &srcaddr,
uint32_t flags, uint32_t delay, uint32_t bandwidth)
{
@ -1496,6 +1491,13 @@ bool p3LinkMgrIMPL::tryConnectUDP(const std::string &id, struct sockaddr_in &r
return false;
#endif
if (mPeerMgr->isHidden())
{
std::cerr << "p3LinkMgrIMPL::tryConnectUDP() isHidden(): no connection attempts for : " << id;
std::cerr << std::endl;
return false;
}
RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/
@ -1527,25 +1529,15 @@ bool p3LinkMgrIMPL::tryConnectUDP(const std::string &id, struct sockaddr_in &r
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::retryConnectUDP() Peer Already Connected" << std::endl;
#endif
if (it->second.connecttype & RS_NET_CONN_TUNNEL) {
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::retryConnectUDP() Peer Connected through a tunnel connection, let's try a normal connection." << std::endl;
#endif
} else {
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::retryConnectUDP() Peer Connected no more connection attempts" << std::endl;
#endif
return false;
}
return false;
}
/* Explicit Request to start the UDP connection */
if (isValidNet(&(rUdpAddr.sin_addr)))
if (sockaddr_storage_isValidNet(rUdpAddr))
{
#ifdef LINKMGR_DEBUG
std::cerr << "Adding udp connection attempt: ";
std::cerr << "Addr: " << rs_inet_ntoa(rUdpAddr.sin_addr);
std::cerr << ":" << ntohs(rUdpAddr.sin_port);
std::cerr << "Addr: " << sockaddr_storage_tostring(rUdpAddr);
std::cerr << std::endl;
#endif
peerConnectAddress pca;
@ -1612,19 +1604,7 @@ bool p3LinkMgrIMPL::retryConnectTCP(const std::string &id)
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::retryConnectTCP() Peer Already Connected" << std::endl;
#endif
if (it->second.connecttype & RS_NET_CONN_TUNNEL)
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::retryConnectTCP() Peer Connected through a tunnel connection, let's try a normal connection." << std::endl;
#endif
}
else
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::retryConnectTCP() Peer Connected no more connection attempts" << std::endl;
#endif
return false;
}
return false;
}
} /****** END of LOCKED ******/
@ -1634,8 +1614,37 @@ bool p3LinkMgrIMPL::retryConnectTCP(const std::string &id)
#endif
/* If we reach here, must retry .... extract the required info from p3PeerMgr */
struct sockaddr_in lAddr;
struct sockaddr_in eAddr;
/* first possibility - is it a hidden peer */
if (mPeerMgr->isHiddenPeer(id))
{
struct sockaddr_storage proxy_addr;
std::string domain_addr;
uint16_t domain_port;
/* then we just have one connect attempt via the Proxy */
if (mPeerMgr->getProxyAddress(id, proxy_addr, domain_addr, domain_port))
{
RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/
std::map<std::string, peerConnectState>::iterator it;
if (mFriendList.end() != (it = mFriendList.find(id)))
{
locked_ConnectAttempt_ProxyAddress(&(it->second), proxy_addr, domain_addr, domain_port);
return locked_ConnectAttempt_Complete(&(it->second));
}
}
return false;
}
if (mPeerMgr->isHidden())
{
std::cerr << "p3LinkMgrIMPL::retryConnectTCP() isHidden(): no connection attempts for : " << id;
std::cerr << std::endl;
return false;
}
struct sockaddr_storage lAddr;
struct sockaddr_storage eAddr;
pqiIpAddrSet histAddrs;
std::string dyndns;
@ -1646,11 +1655,11 @@ bool p3LinkMgrIMPL::retryConnectTCP(const std::string &id)
std::map<std::string, peerConnectState>::iterator it;
if (mFriendList.end() != (it = mFriendList.find(id)))
{
locked_ConnectAttempt_CurrentAddresses(&(it->second), &lAddr, &eAddr);
locked_ConnectAttempt_CurrentAddresses(&(it->second), lAddr, eAddr);
uint16_t dynPort = ntohs(eAddr.sin_port);
uint16_t dynPort = sockaddr_storage_port(eAddr);
if (!dynPort)
dynPort = ntohs(lAddr.sin_port);
dynPort = sockaddr_storage_port(lAddr);
if (dynPort)
{
locked_ConnectAttempt_AddDynDNS(&(it->second), dyndns, dynPort);
@ -1658,8 +1667,6 @@ bool p3LinkMgrIMPL::retryConnectTCP(const std::string &id)
locked_ConnectAttempt_HistoricalAddresses(&(it->second), histAddrs);
//locked_ConnectAttempt_AddTunnel(&(it->second));
/* finish it off */
return locked_ConnectAttempt_Complete(&(it->second));
}
@ -1682,12 +1689,11 @@ bool p3LinkMgrIMPL::retryConnectTCP(const std::string &id)
#define MAX_TCP_ADDR_AGE (3600 * 24 * 14) // two weeks in seconds.
bool p3LinkMgrIMPL::locked_CheckPotentialAddr(const struct sockaddr_in *addr, time_t age)
bool p3LinkMgrIMPL::locked_CheckPotentialAddr(const struct sockaddr_storage &addr, time_t age)
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_CheckPotentialAddr(";
std::cerr << rs_inet_ntoa(addr->sin_addr);
std::cerr << ":" << ntohs(addr->sin_port);
std::cerr << sockaddr_storage_tostring(addr);
std::cerr << ", " << age << ")";
std::cerr << std::endl;
#endif
@ -1704,10 +1710,10 @@ bool p3LinkMgrIMPL::locked_CheckPotentialAddr(const struct sockaddr_in *addr, t
return false;
}
bool isValid = isValidNet(&(addr->sin_addr));
// bool isLoopback = isLoopbackNet(&(addr->sin_addr));
// bool isPrivate = isPrivateNet(&(addr->sin_addr));
bool isExternal = isExternalNet(&(addr->sin_addr));
bool isValid = sockaddr_storage_isValidNet(addr);
bool isLoopback = sockaddr_storage_isLoopbackNet(addr);
// bool isPrivate = sockaddr_storage_isPrivateNet(addr);
bool isExternal = sockaddr_storage_isExternalNet(addr);
/* if invalid - quick rejection */
if (!isValid)
@ -1722,10 +1728,10 @@ bool p3LinkMgrIMPL::locked_CheckPotentialAddr(const struct sockaddr_in *addr, t
/* if it is on the ban list - ignore */
/* checks - is it the dreaded 1.0.0.0 */
std::list<struct in_addr>::const_iterator it;
std::list<struct sockaddr_storage>::const_iterator it;
for(it = mBannedIpList.begin(); it != mBannedIpList.end(); it++)
{
if (it->s_addr == addr->sin_addr.s_addr)
if (sockaddr_storage_sameip(*it, addr))
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_CheckPotentialAddr() REJECTING - ON BANNED IPLIST";
@ -1749,6 +1755,18 @@ bool p3LinkMgrIMPL::locked_CheckPotentialAddr(const struct sockaddr_in *addr, t
}
/* if loopback, then okay - probably proxy connection (or local testing).
*/
if (isLoopback)
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_CheckPotentialAddr() ACCEPTING - LOOPBACK";
std::cerr << std::endl;
#endif
return true;
}
/* get here, it is private or loopback
* - can only connect to these addresses if we are on the same subnet.
- check net against our local address.
@ -1756,12 +1774,12 @@ bool p3LinkMgrIMPL::locked_CheckPotentialAddr(const struct sockaddr_in *addr, t
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_CheckPotentialAddr() Checking sameNet against: ";
std::cerr << rs_inet_ntoa(mLocalAddress.sin_addr);
std::cerr << sockaddr_storage_iptostring(mLocalAddress);
std::cerr << ")";
std::cerr << std::endl;
#endif
if (sameNet(&(mLocalAddress.sin_addr), &(addr->sin_addr)))
if (sockaddr_storage_samenet(mLocalAddress, addr))
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_CheckPotentialAddr() ACCEPTING - PRIVATE & sameNET";
@ -1781,29 +1799,28 @@ bool p3LinkMgrIMPL::locked_CheckPotentialAddr(const struct sockaddr_in *addr, t
}
void p3LinkMgrIMPL::locked_ConnectAttempt_SpecificAddress(peerConnectState *peer, struct sockaddr_in *remoteAddr)
void p3LinkMgrIMPL::locked_ConnectAttempt_SpecificAddress(peerConnectState *peer, const struct sockaddr_storage &remoteAddr)
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_SpecificAddresses()";
std::cerr << std::endl;
#endif
if ((remoteAddr) && (locked_CheckPotentialAddr(remoteAddr, 0)))
if (locked_CheckPotentialAddr(remoteAddr, 0))
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_SpecificAddresses() ";
std::cerr << "Adding tcp connection attempt: ";
std::cerr << "Addr: " << rs_inet_ntoa(remoteAddr->sin_addr);
std::cerr << ":" << ntohs(remoteAddr->sin_port);
std::cerr << "Addr: " << sockaddr_storage_tostring(remoteAddr);
std::cerr << std::endl;
#endif
peerConnectAddress pca;
pca.addr = *remoteAddr;
pca.addr = remoteAddr;
pca.type = RS_NET_CONN_TCP_EXTERNAL;
pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY;
pca.ts = time(NULL);
pca.period = P3CONNMGR_TCP_DEFAULT_PERIOD;
sockaddr_clear(&(pca.proxyaddr));
sockaddr_clear(&(pca.srcaddr));
sockaddr_storage_clear(pca.proxyaddr);
sockaddr_storage_clear(pca.srcaddr);
pca.bandwidth = 0;
addAddressIfUnique(peer->connAddrs, pca, false);
@ -1811,7 +1828,7 @@ void p3LinkMgrIMPL::locked_ConnectAttempt_SpecificAddress(peerConnectState *pee
}
void p3LinkMgrIMPL::locked_ConnectAttempt_CurrentAddresses(peerConnectState *peer, struct sockaddr_in *localAddr, struct sockaddr_in *serverAddr)
void p3LinkMgrIMPL::locked_ConnectAttempt_CurrentAddresses(peerConnectState *peer, const struct sockaddr_storage &localAddr, const struct sockaddr_storage &serverAddr)
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_CurrentAddresses()";
@ -1819,45 +1836,43 @@ void p3LinkMgrIMPL::locked_ConnectAttempt_CurrentAddresses(peerConnectState *pe
#endif
// Just push all the addresses onto the stack.
/* try "current addresses" first */
if ((localAddr) && (locked_CheckPotentialAddr(localAddr, 0)))
if (locked_CheckPotentialAddr(localAddr, 0))
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_CurrentAddresses() ";
std::cerr << "Adding tcp connection attempt: ";
std::cerr << "Current Local Addr: " << rs_inet_ntoa(localAddr->sin_addr);
std::cerr << ":" << ntohs(localAddr->sin_port);
std::cerr << "Current Local Addr: " << sockaddr_storage_tostring(localAddr);
std::cerr << std::endl;
#endif
peerConnectAddress pca;
pca.addr = *localAddr;
pca.addr = localAddr;
pca.type = RS_NET_CONN_TCP_LOCAL;
pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY;
pca.ts = time(NULL);
pca.period = P3CONNMGR_TCP_DEFAULT_PERIOD;
sockaddr_clear(&(pca.proxyaddr));
sockaddr_clear(&(pca.srcaddr));
sockaddr_storage_clear(pca.proxyaddr);
sockaddr_storage_clear(pca.srcaddr);
pca.bandwidth = 0;
addAddressIfUnique(peer->connAddrs, pca, false);
}
if ((serverAddr) && (locked_CheckPotentialAddr(serverAddr, 0)))
if (locked_CheckPotentialAddr(serverAddr, 0))
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_CurrentAddresses() ";
std::cerr << "Adding tcp connection attempt: ";
std::cerr << "Current Ext Addr: " << rs_inet_ntoa(serverAddr->sin_addr);
std::cerr << ":" << ntohs(serverAddr->sin_port);
std::cerr << "Current Ext Addr: " << sockaddr_storage_tostring(serverAddr);
std::cerr << std::endl;
#endif
peerConnectAddress pca;
pca.addr = *serverAddr;
pca.addr = serverAddr;
pca.type = RS_NET_CONN_TCP_EXTERNAL;
pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY;
pca.ts = time(NULL);
pca.period = P3CONNMGR_TCP_DEFAULT_PERIOD;
sockaddr_clear(&(pca.proxyaddr));
sockaddr_clear(&(pca.srcaddr));
sockaddr_storage_clear(pca.proxyaddr);
sockaddr_storage_clear(pca.srcaddr);
pca.bandwidth = 0;
addAddressIfUnique(peer->connAddrs, pca, false);
@ -1879,14 +1894,13 @@ void p3LinkMgrIMPL::locked_ConnectAttempt_HistoricalAddresses(peerConnectState
for(ait = ipAddrs.mLocal.mAddrs.begin();
ait != ipAddrs.mLocal.mAddrs.end(); ait++)
{
if (locked_CheckPotentialAddr(&(ait->mAddr), now - ait->mSeenTime))
if (locked_CheckPotentialAddr(ait->mAddr, now - ait->mSeenTime))
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_HistoricalAddresses() ";
std::cerr << "Adding tcp connection attempt: ";
std::cerr << "Local Addr: " << rs_inet_ntoa(ait->mAddr.sin_addr);
std::cerr << ":" << ntohs(ait->mAddr.sin_port);
std::cerr << "Local Addr: " << sockaddr_storage_tostring(ait->mAddr);
std::cerr << std::endl;
#endif
@ -1896,8 +1910,8 @@ void p3LinkMgrIMPL::locked_ConnectAttempt_HistoricalAddresses(peerConnectState
pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY;
pca.ts = time(NULL);
pca.period = P3CONNMGR_TCP_DEFAULT_PERIOD;
sockaddr_clear(&(pca.proxyaddr));
sockaddr_clear(&(pca.srcaddr));
sockaddr_storage_clear(pca.proxyaddr);
sockaddr_storage_clear(pca.srcaddr);
pca.bandwidth = 0;
addAddressIfUnique(peer->connAddrs, pca, false);
@ -1907,14 +1921,13 @@ void p3LinkMgrIMPL::locked_ConnectAttempt_HistoricalAddresses(peerConnectState
for(ait = ipAddrs.mExt.mAddrs.begin();
ait != ipAddrs.mExt.mAddrs.end(); ait++)
{
if (locked_CheckPotentialAddr(&(ait->mAddr), now - ait->mSeenTime))
if (locked_CheckPotentialAddr(ait->mAddr, now - ait->mSeenTime))
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_HistoricalAddresses() ";
std::cerr << "Adding tcp connection attempt: ";
std::cerr << "Ext Addr: " << rs_inet_ntoa(ait->mAddr.sin_addr);
std::cerr << ":" << ntohs(ait->mAddr.sin_port);
std::cerr << "Ext Addr: " << sockaddr_storage_tostring(ait->mAddr);
std::cerr << std::endl;
#endif
peerConnectAddress pca;
@ -1923,8 +1936,8 @@ void p3LinkMgrIMPL::locked_ConnectAttempt_HistoricalAddresses(peerConnectState
pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY;
pca.ts = time(NULL);
pca.period = P3CONNMGR_TCP_DEFAULT_PERIOD;
sockaddr_clear(&(pca.proxyaddr));
sockaddr_clear(&(pca.srcaddr));
sockaddr_storage_clear(pca.proxyaddr);
sockaddr_storage_clear(pca.srcaddr);
pca.bandwidth = 0;
addAddressIfUnique(peer->connAddrs, pca, false);
@ -1936,7 +1949,7 @@ void p3LinkMgrIMPL::locked_ConnectAttempt_HistoricalAddresses(peerConnectState
void p3LinkMgrIMPL::locked_ConnectAttempt_AddDynDNS(peerConnectState *peer, std::string dyndns, uint16_t port)
{
/* try dyndns address too */
struct in_addr addr;
struct sockaddr_storage addr;
if (!dyndns.empty() && port)
{
#ifdef LINKMGR_DEBUG
@ -1947,26 +1960,25 @@ void p3LinkMgrIMPL::locked_ConnectAttempt_AddDynDNS(peerConnectState *peer, std
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_AddDynDNS() ";
std::cerr << "Adding tcp connection attempt: ";
std::cerr << "DynDNS Addr: " << rs_inet_ntoa(addr);
std::cerr << ":" << ntohs(port);
std::cerr << "DynDNS Addr: " << sockaddr_storage_iptostring(addr);
std::cerr << ":" << port;
std::cerr << std::endl;
#endif
peerConnectAddress pca;
pca.addr.sin_family = AF_INET;
pca.addr.sin_addr.s_addr = addr.s_addr;
pca.addr.sin_port = htons(port);
sockaddr_storage_copyip(pca.addr, addr);
sockaddr_storage_setport(pca.addr, port);
pca.type = RS_NET_CONN_TCP_EXTERNAL;
//for the delay, we add a random time and some more time when the friend list is big
pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY;
pca.ts = time(NULL);
pca.period = P3CONNMGR_TCP_DEFAULT_PERIOD;
sockaddr_clear(&(pca.proxyaddr));
sockaddr_clear(&(pca.srcaddr));
sockaddr_storage_clear(pca.proxyaddr);
sockaddr_storage_clear(pca.srcaddr);
pca.bandwidth = 0;
/* check address validity */
if (locked_CheckPotentialAddr(&(pca.addr), 0))
if (locked_CheckPotentialAddr(pca.addr, 0))
{
addAddressIfUnique(peer->connAddrs, pca, true);
}
@ -1989,27 +2001,32 @@ void p3LinkMgrIMPL::locked_ConnectAttempt_AddDynDNS(peerConnectState *peer, std
}
void p3LinkMgrIMPL::locked_ConnectAttempt_AddTunnel(peerConnectState *peer)
void p3LinkMgrIMPL::locked_ConnectAttempt_ProxyAddress(peerConnectState *peer, const struct sockaddr_storage &proxy_addr, const std::string &domain_addr, uint16_t domain_port)
{
if (!(peer->state & RS_PEER_S_CONNECTED) && mAllowTunnelConnection)
{
#ifdef LINKMGR_DEBUG
std::cerr << "Adding TUNNEL Connection Attempt";
std::cerr << std::endl;
std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_ProxyAddress() trying address: " << domain_addr << ":" << domain_port << std::endl;
#endif
peerConnectAddress pca;
pca.type = RS_NET_CONN_TUNNEL;
pca.ts = time(NULL);
pca.period = 0;
peerConnectAddress pca;
pca.addr = proxy_addr;
sockaddr_clear(&pca.addr);
pca.type = RS_NET_CONN_TCP_HIDDEN;
sockaddr_clear(&(pca.proxyaddr));
sockaddr_clear(&(pca.srcaddr));
pca.bandwidth = 0;
addAddressIfUnique(peer->connAddrs, pca, false);
//for the delay, we add a random time and some more time when the friend list is big
pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY;
pca.ts = time(NULL);
pca.period = P3CONNMGR_TCP_DEFAULT_PERIOD;
sockaddr_storage_clear(pca.proxyaddr);
sockaddr_storage_clear(pca.srcaddr);
pca.bandwidth = 0;
pca.domain_addr = domain_addr;
pca.domain_port = domain_port;
/* check address validity */
if (locked_CheckPotentialAddr(pca.addr, 0))
{
addAddressIfUnique(peer->connAddrs, pca, true);
}
}
@ -2020,15 +2037,14 @@ bool p3LinkMgrIMPL::addAddressIfUnique(std::list<peerConnectAddress> &addrList,
* in the list
*/
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::addAddressIfUnique() Checking Address: " << rs_inet_ntoa(pca.addr.sin_addr);
std::cerr << "p3LinkMgrIMPL::addAddressIfUnique() Checking Address: " << sockaddr_storage_iptostring(pca.addr);
std::cerr << std::endl;
#endif
std::list<peerConnectAddress>::iterator it;
for(it = addrList.begin(); it != addrList.end(); it++)
{
if ((pca.addr.sin_addr.s_addr == it->addr.sin_addr.s_addr) &&
(pca.addr.sin_port == it->addr.sin_port) &&
if (sockaddr_storage_same(pca.addr, it->addr) &&
(pca.type == it->type))
{
#ifdef LINKMGR_DEBUG

View file

@ -42,15 +42,18 @@ class DNSResolver ;
/* order of attempts ... */
const uint32_t RS_NET_CONN_TCP_ALL = 0x000f;
const uint32_t RS_NET_CONN_UDP_ALL = 0x00f0;
const uint32_t RS_NET_CONN_TUNNEL = 0x0f00;
const uint32_t RS_NET_CONN_TCP_LOCAL = 0x0001;
const uint32_t RS_NET_CONN_TCP_EXTERNAL = 0x0002;
const uint32_t RS_NET_CONN_TCP_UNKNOW_TOPOLOGY = 0x0004;
const uint32_t RS_NET_CONN_TCP_HIDDEN = 0x0008;
const uint32_t RS_NET_CONN_UDP_DHT_SYNC = 0x0010;
const uint32_t RS_NET_CONN_UDP_PEER_SYNC = 0x0020; /* coming soon */
// These are set in pqipersongroup.
const uint32_t RS_TCP_STD_TIMEOUT_PERIOD = 5; /* 5 seconds! */
const uint32_t RS_TCP_HIDDEN_TIMEOUT_PERIOD = 30; /* 30 seconds! */
const uint32_t RS_UDP_STD_TIMEOUT_PERIOD = 80; /* 80 secs, allows UDP TTL to get to 40! - Plenty of time (30+80) = 110 secs */
class peerAddrInfo
@ -69,7 +72,7 @@ class peerConnectAddress
public:
peerConnectAddress(); /* init */
struct sockaddr_in addr;
struct sockaddr_storage addr;
uint32_t delay; /* to stop simultaneous connects */
uint32_t period; /* UDP only */
uint32_t type;
@ -77,9 +80,13 @@ class peerConnectAddress
time_t ts;
// Extra Parameters for Relay connections.
struct sockaddr_in proxyaddr;
struct sockaddr_in srcaddr;
struct sockaddr_storage proxyaddr;
struct sockaddr_storage srcaddr;
uint32_t bandwidth;
// Extra Parameters for Proxy/Hidden connection.
std::string domain_addr;
uint16_t domain_port;
};
class peerConnectState
@ -108,7 +115,7 @@ class peerConnectState
peerAddrInfo disc;
peerAddrInfo peer;
sockaddr_in connectaddr ; // current connection address. Can be local or external.
struct sockaddr_storage connectaddr; // current connection address. Can be local or external.
/* a list of connect attempts to make (in order) */
bool inConnAttempt;
@ -159,26 +166,25 @@ virtual void addMonitor(pqiMonitor *mon) = 0;
virtual void removeMonitor(pqiMonitor *mon) = 0;
/****************** Connections *******************/
virtual bool connectAttempt(const std::string &id, struct sockaddr_in &raddr,
struct sockaddr_in &proxyaddr, struct sockaddr_in &srcaddr,
uint32_t &delay, uint32_t &period, uint32_t &type, uint32_t &flags, uint32_t &bandwidth) = 0;
virtual bool connectAttempt(const std::string &id, struct sockaddr_storage &raddr,
struct sockaddr_storage &proxyaddr, struct sockaddr_storage &srcaddr,
uint32_t &delay, uint32_t &period, uint32_t &type, uint32_t &flags, uint32_t &bandwidth,
std::string &domain_addr, uint16_t &domain_port) = 0;
virtual bool connectResult(const std::string &id, bool success, uint32_t flags, struct sockaddr_in remote_peer_address) = 0;
virtual bool connectResult(const std::string &id, bool success, uint32_t flags, const struct sockaddr_storage &remote_peer_address) = 0;
virtual bool retryConnect(const std::string &id) = 0;
virtual void notifyDeniedConnection(const std::string& gpgid,const std::string& sslid,const std::string& sslcn,const struct sockaddr_in &addr, bool incoming) = 0;
virtual void notifyDeniedConnection(const std::string& gpgid,const std::string& sslid,const std::string& sslcn,const struct sockaddr_storage &addr, bool incoming) = 0;
/* Network Addresses */
virtual bool setLocalAddress(struct sockaddr_in addr) = 0;
virtual struct sockaddr_in getLocalAddress() = 0;
virtual bool setLocalAddress(const struct sockaddr_storage &addr) = 0;
virtual bool getLocalAddress(struct sockaddr_storage &addr) = 0;
/************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/
virtual void getFriendList(std::list<std::string> &ssl_peers) = 0; // ONLY used by p3peers.cc USE p3PeerMgr instead.
virtual bool getFriendNetStatus(const std::string &id, peerConnectState &state) = 0; // ONLY used by p3peers.cc
virtual void setTunnelConnection(bool b) = 0; // ONLY used by p3peermgr.cc & p3peers.cc MOVE => p3PeerMgr
virtual bool getTunnelConnection() = 0; // ONLY used by p3peermgr.cc & p3peers.cc MOVE => p3PeerMgr
/************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/
virtual int addFriend(const std::string &ssl_id, bool isVisible) = 0;
@ -186,8 +192,8 @@ virtual int addFriend(const std::string &ssl_id, bool isVisible) = 0;
// THESE MUSTn't BE specfied HERE - as overloaded from pqiConnectCb.
//virtual void peerStatus(std::string id, const pqiIpAddrSet &addrs,
// uint32_t type, uint32_t flags, uint32_t source) = 0;
//virtual void peerConnectRequest(std::string id, struct sockaddr_in raddr,
// struct sockaddr_in proxyaddr, struct sockaddr_in srcaddr,
//virtual void peerConnectRequest(std::string id, const struct sockaddr_storage &raddr,
// const struct sockaddr_storage &proxyaddr, const struct sockaddr_storage &srcaddr,
// uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth) = 0;
/****************************************************************************/
@ -218,24 +224,25 @@ virtual void addMonitor(pqiMonitor *mon);
virtual void removeMonitor(pqiMonitor *mon);
/****************** Connections *******************/
virtual bool connectAttempt(const std::string &id, struct sockaddr_in &raddr,
struct sockaddr_in &proxyaddr, struct sockaddr_in &srcaddr,
uint32_t &delay, uint32_t &period, uint32_t &type, uint32_t &flags, uint32_t &bandwidth);
virtual bool connectAttempt(const std::string &id, struct sockaddr_storage &raddr,
struct sockaddr_storage &proxyaddr, struct sockaddr_storage &srcaddr,
uint32_t &delay, uint32_t &period, uint32_t &type, uint32_t &flags, uint32_t &bandwidth,
std::string &domain_addr, uint16_t &domain_port);
virtual bool connectResult(const std::string &id, bool success, uint32_t flags, struct sockaddr_in remote_peer_address);
virtual bool connectResult(const std::string &id, bool success, uint32_t flags, const struct sockaddr_storage &remote_peer_address);
virtual bool retryConnect(const std::string &id);
virtual void notifyDeniedConnection(const std::string& gpgid,const std::string& sslid,const std::string& sslcn,const struct sockaddr_in &addr, bool incoming);
virtual void notifyDeniedConnection(const std::string& gpgid,const std::string& sslid,const std::string& sslcn,const struct sockaddr_storage &addr, bool incoming);
/* Network Addresses */
virtual bool setLocalAddress(struct sockaddr_in addr);
virtual struct sockaddr_in getLocalAddress();
virtual bool setLocalAddress(const struct sockaddr_storage &addr);
virtual bool getLocalAddress(struct sockaddr_storage &addr);
/******* overloaded from pqiConnectCb *************/
virtual void peerStatus(std::string id, const pqiIpAddrSet &addrs,
uint32_t type, uint32_t flags, uint32_t source);
virtual void peerConnectRequest(std::string id, struct sockaddr_in raddr,
struct sockaddr_in proxyaddr, struct sockaddr_in srcaddr,
virtual void peerConnectRequest(std::string id, const struct sockaddr_storage &raddr,
const struct sockaddr_storage &proxyaddr, const struct sockaddr_storage &srcaddr,
uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth);
@ -244,9 +251,6 @@ virtual void peerConnectRequest(std::string id, struct sockaddr_in raddr,
virtual void getFriendList(std::list<std::string> &ssl_peers); // ONLY used by p3peers.cc USE p3PeerMgr instead.
virtual bool getFriendNetStatus(const std::string &id, peerConnectState &state); // ONLY used by p3peers.cc
virtual void setTunnelConnection(bool b); // ONLY used by p3peermgr.cc & p3peers.cc MOVE => p3PeerMgr
virtual bool getTunnelConnection(); // ONLY used by p3peermgr.cc & p3peers.cc MOVE => p3PeerMgr
/************************************************************************************************/
/* Extra IMPL Functions (used by p3PeerMgr, p3NetMgr + Setup) */
/************************************************************************************************/
@ -280,22 +284,23 @@ void statusTick();
void tickMonitors();
/* connect attempts UDP */
bool tryConnectUDP(const std::string &id, struct sockaddr_in &rUdpAddr,
struct sockaddr_in &proxyaddr, struct sockaddr_in &srcaddr,
bool tryConnectUDP(const std::string &id, const struct sockaddr_storage &rUdpAddr,
const struct sockaddr_storage &proxyaddr, const struct sockaddr_storage &srcaddr,
uint32_t flags, uint32_t delay, uint32_t bandwidth);
/* connect attempts TCP */
bool retryConnectTCP(const std::string &id);
void locked_ConnectAttempt_SpecificAddress(peerConnectState *peer, struct sockaddr_in *remoteAddr);
void locked_ConnectAttempt_CurrentAddresses(peerConnectState *peer, struct sockaddr_in *localAddr, struct sockaddr_in *serverAddr);
void locked_ConnectAttempt_SpecificAddress(peerConnectState *peer, const struct sockaddr_storage &remoteAddr);
void locked_ConnectAttempt_CurrentAddresses(peerConnectState *peer, const struct sockaddr_storage &localAddr, const struct sockaddr_storage &serverAddr);
void locked_ConnectAttempt_HistoricalAddresses(peerConnectState *peer, const pqiIpAddrSet &ipAddrs);
void locked_ConnectAttempt_AddDynDNS(peerConnectState *peer, std::string dyndns, uint16_t dynPort);
void locked_ConnectAttempt_AddTunnel(peerConnectState *peer);
void locked_ConnectAttempt_ProxyAddress(peerConnectState *peer, const struct sockaddr_storage &proxy_addr, const std::string &domain_addr, uint16_t domain_port);
bool locked_ConnectAttempt_Complete(peerConnectState *peer);
bool locked_CheckPotentialAddr(const struct sockaddr_in *addr, time_t age);
bool locked_CheckPotentialAddr(const struct sockaddr_storage &addr, time_t age);
bool addAddressIfUnique(std::list<peerConnectAddress> &addrList, peerConnectAddress &pca, bool pushFront);
@ -313,7 +318,7 @@ private:
bool mStatusChanged;
struct sockaddr_in mLocalAddress;
struct sockaddr_storage mLocalAddress;
std::list<pqiMonitor *> clients;
@ -332,7 +337,7 @@ private:
uint32_t lastGroupId;
/* relatively static list of banned ip addresses */
std::list<struct in_addr> mBannedIpList;
std::list<struct sockaddr_storage> mBannedIpList;
};
#endif // MRK_PQI_LINK_MANAGER_HEADER

View file

@ -82,8 +82,8 @@ pqiNetStatus::pqiNetStatus()
mDhtNetworkSize = 0;
mDhtRsNetworkSize = 0;
sockaddr_clear(&mLocalAddr);
sockaddr_clear(&mExtAddr);
sockaddr_storage_clear(mLocalAddr);
sockaddr_storage_clear(mExtAddr);
return;
}
@ -102,8 +102,8 @@ void pqiNetStatus::print(std::ostream &out)
out << std::endl;
out << "mDhtNetworkSize: " << mDhtNetworkSize << " mDhtRsNetworkSize: " << mDhtRsNetworkSize;
out << std::endl;
out << "mLocalAddr: " << rs_inet_ntoa(mLocalAddr.sin_addr) << ":" << ntohs(mLocalAddr.sin_port) << " ";
out << "mExtAddr: " << rs_inet_ntoa(mExtAddr.sin_addr) << ":" << ntohs(mExtAddr.sin_port) << " ";
out << "mLocalAddr: " << sockaddr_storage_tostring(mLocalAddr) << " ";
out << "mExtAddr: " << sockaddr_storage_tostring(mExtAddr) << " ";
out << " NetOk: " << NetOk();
out << std::endl;
}
@ -129,13 +129,17 @@ p3NetMgrIMPL::p3NetMgrIMPL()
mLastSlowTickTime = 0;
mOldNatType = RSNET_NATTYPE_UNKNOWN;
mOldNatHole = RSNET_NATHOLE_UNKNOWN;
mLocalAddr.sin_port = 0;
mLocalAddr.sin_addr.s_addr = 0;
mLocalAddr.sin_family = AF_INET ;
mExtAddr.sin_port = 0;
mExtAddr.sin_addr.s_addr = 0;
mExtAddr.sin_family = AF_INET ;
mVisState = 0 ;
sockaddr_storage_clear(mLocalAddr);
sockaddr_storage_clear(mExtAddr);
// force to IPv4 for the moment.
mLocalAddr.ss_family = AF_INET;
mExtAddr.ss_family = AF_INET;
// default to full.
mVsDisc = RS_VS_DISC_FULL;
mVsDht = RS_VS_DHT_FULL;
}
#ifdef NETMGR_DEBUG
@ -270,7 +274,7 @@ void p3NetMgrIMPL::netReset()
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
struct sockaddr_in iaddr = mLocalAddr;
struct sockaddr_storage iaddr = mLocalAddr;
#ifdef NETMGR_DEBUG_RESET
std::cerr << "p3NetMgrIMPL::netReset() resetting listeners" << std::endl;
@ -381,6 +385,13 @@ void p3NetMgrIMPL::netStartup()
mNetStatus = RS_NET_EXT_SETUP;
break;
case RS_NET_MODE_TRY_LOOPBACK:
std::cerr << "p3NetMgrIMPL::netStartup() TRY_LOOPBACK mode";
std::cerr << std::endl;
mNetMode |= RS_NET_MODE_HIDDEN;
mNetStatus = RS_NET_LOOPBACK;
break;
default: // Fall through.
#ifdef NETMGR_DEBUG_RESET
@ -536,6 +547,7 @@ void p3NetMgrIMPL::netTick()
case RS_NET_LOOPBACK:
//don't do a shutdown because a client in a computer without local network might be usefull for debug.
//shutdown();
std::cerr << "p3NetMgrIMPL::netTick() STATUS: RS_NET_LOOPBACK" << std::endl;
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cerr << "p3NetMgrIMPL::netTick() STATUS: RS_NET_LOOPBACK" << std::endl;
#endif
@ -556,10 +568,10 @@ void p3NetMgrIMPL::netDhtInit()
uint32_t vs = 0;
{
RsStackMutex stack(mNetMtx); /*********** LOCKED MUTEX ************/
vs = mVisState;
vs = mVsDht;
}
enableNetAssistConnect(!(vs & RS_VIS_STATE_NODHT));
enableNetAssistConnect(vs != RS_VS_DHT_OFF);
}
@ -575,8 +587,8 @@ void p3NetMgrIMPL::netUpnpInit()
/* get the ports from the configuration */
mNetStatus = RS_NET_UPNP_SETUP;
iport = ntohs(mLocalAddr.sin_port);
eport = ntohs(mExtAddr.sin_port);
iport = sockaddr_storage_port(mLocalAddr);
eport = sockaddr_storage_port(mExtAddr);
if ((eport < 1000) || (eport > 30000))
{
eport = iport;
@ -601,7 +613,7 @@ void p3NetMgrIMPL::netUpnpCheck()
mNetMtx.unlock(); /* UNLOCK MUTEX */
struct sockaddr_in extAddr;
struct sockaddr_storage extAddr;
int upnpState = netAssistFirewallActive();
if (((upnpState == 0) && (delta > (time_t)MAX_UPNP_INIT)) ||
@ -633,12 +645,11 @@ void p3NetMgrIMPL::netUpnpCheck()
* we now have external upnp address. Golden!
* don't set netOk flag until have seen some traffic.
*/
if (isValidNet(&(extAddr.sin_addr)))
if (sockaddr_storage_isValidNet(extAddr))
{
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cerr << "p3NetMgrIMPL::netUpnpCheck() ";
std::cerr << "UpnpAddr: " << rs_inet_ntoa(extAddr.sin_addr);
std::cerr << ":" << ntohs(extAddr.sin_port);
std::cerr << "UpnpAddr: " << sockaddr_storage_tostring(extAddr);
std::cerr << std::endl;
#endif
mNetFlags.mUpnpOk = true;
@ -673,7 +684,7 @@ void p3NetMgrIMPL::netExtCheck()
{
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
bool isStable = false;
struct sockaddr_in tmpip ;
struct sockaddr_storage tmpip ;
/* check for External Address */
/* in order of importance */
@ -690,7 +701,7 @@ void p3NetMgrIMPL::netExtCheck()
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cerr << "p3NetMgrIMPL::netExtCheck() Ext supplied from netAssistExternalAddress()" << std::endl;
#endif
if (isValidNet(&(tmpip.sin_addr)))
if (sockaddr_storage_isValidNet(tmpip))
{
// must be stable???
isStable = true;
@ -715,8 +726,8 @@ void p3NetMgrIMPL::netExtCheck()
std::cerr << "p3NetMgrIMPL::netExtCheck() Ext Not Ok, Checking DhtStunner" << std::endl;
#endif
uint8_t isstable = 0;
struct sockaddr_in tmpaddr;
sockaddr_clear(&tmpaddr);
struct sockaddr_storage tmpaddr;
sockaddr_storage_clear(tmpaddr);
if (mDhtStunner)
{
@ -731,7 +742,7 @@ void p3NetMgrIMPL::netExtCheck()
#ifdef NETMGR_DEBUG_STATEBOX
std::cerr << "p3NetMgrIMPL::netExtCheck() From DhtStunner: ";
std::cerr << rs_inet_ntoa(tmpaddr.sin_addr) << ":" << htons(tmpaddr.sin_port);
std::cerr << sockaddr_storage_tostring(tmpaddr);
std::cerr << " Stable: " << (uint32_t) isstable;
std::cerr << std::endl;
#endif
@ -748,18 +759,18 @@ void p3NetMgrIMPL::netExtCheck()
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cerr << "p3NetMgrIMPL::netExtCheck() checking ExtAddrFinder" << std::endl;
#endif
bool extFinderOk = mExtAddrFinder->hasValidIP(&(tmpip.sin_addr));
bool extFinderOk = mExtAddrFinder->hasValidIP(tmpip);
if (extFinderOk)
{
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cerr << "p3NetMgrIMPL::netExtCheck() Ext supplied by ExtAddrFinder" << std::endl;
#endif
/* best guess at port */
tmpip.sin_port = mNetFlags.mLocalAddr.sin_port;
sockaddr_storage_setport(tmpip, sockaddr_storage_port(mLocalAddr));
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cerr << "p3NetMgrIMPL::netExtCheck() ";
std::cerr << "ExtAddr: " << rs_inet_ntoa(tmpip.sin_addr);
std::cerr << ":" << ntohs(tmpip.sin_port);
std::cerr << "ExtAddr: " << sockaddr_storage_tostring(tmpip);
std::cerr << std::endl;
#endif
@ -783,8 +794,7 @@ void p3NetMgrIMPL::netExtCheck()
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cerr << "p3NetMgrIMPL::netExtCheck() ";
std::cerr << "ExtAddr: " << rs_inet_ntoa(mNetFlags.mExtAddr.sin_addr);
std::cerr << ":" << ntohs(mNetFlags.mExtAddr.sin_port);
std::cerr << "ExtAddr: " << sockaddr_storage_tostring(mNetFlags.mExtAddr);
std::cerr << std::endl;
#endif
//update ip address list
@ -903,10 +913,21 @@ bool p3NetMgrIMPL::checkNetAddress()
bool addrChanged = false;
bool validAddr = false;
struct in_addr prefAddr;
struct sockaddr_in oldAddr;
struct sockaddr_storage prefAddr;
struct sockaddr_storage oldAddr;
if (mNetMode & RS_NET_MODE_TRY_LOOPBACK)
{
std::cerr << "p3NetMgrIMPL::checkNetAddress() LOOPBACK ... forcing to 127.0.0.1";
std::cerr << std::endl;
sockaddr_storage_ipv4_aton(prefAddr, "127.0.0.1");
validAddr = true;
}
else
{
validAddr = getPreferredInterface(mLocalAddr, prefAddr);
}
validAddr = getPreferredInterface(mLocalAddr.sin_addr, prefAddr);
/* if we don't have a valid address - reset */
if (!validAddr)
@ -927,15 +948,14 @@ bool p3NetMgrIMPL::checkNetAddress()
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
oldAddr = mLocalAddr;
addrChanged = (prefAddr.s_addr != mLocalAddr.sin_addr.s_addr);
addrChanged = !sockaddr_storage_sameip(prefAddr, mLocalAddr);
#ifdef NETMGR_DEBUG_TICK
std::cerr << "p3NetMgrIMPL::checkNetAddress()";
std::cerr << std::endl;
std::cerr << "Current Local: " << rs_inet_ntoa(mLocalAddr.sin_addr);
std::cerr << ":" << ntohs(mLocalAddr.sin_port);
std::cerr << "Current Local: " << sockaddr_storage_tostring(mLocalAddr);
std::cerr << std::endl;
std::cerr << "Current Preferred: " << rs_inet_ntoa(prefAddr);
std::cerr << "Current Preferred: " << sockaddr_storage_iptostring(prefAddr);
std::cerr << std::endl;
#endif
@ -944,19 +964,18 @@ bool p3NetMgrIMPL::checkNetAddress()
{
std::cerr << "p3NetMgrIMPL::checkNetAddress() Address Changed!";
std::cerr << std::endl;
std::cerr << "Current Local: " << rs_inet_ntoa(mLocalAddr.sin_addr);
std::cerr << ":" << ntohs(mLocalAddr.sin_port);
std::cerr << "Current Local: " << sockaddr_storage_tostring(mLocalAddr);
std::cerr << std::endl;
std::cerr << "Current Preferred: " << rs_inet_ntoa(prefAddr);
std::cerr << "Current Preferred: " << sockaddr_storage_iptostring(prefAddr);
std::cerr << std::endl;
}
#endif
// update address.
mLocalAddr.sin_addr = prefAddr;
sockaddr_storage_copyip(mLocalAddr, prefAddr);
mNetFlags.mLocalAddr = mLocalAddr;
if(isLoopbackNet(&(mLocalAddr.sin_addr)))
if(sockaddr_storage_isLoopbackNet(mLocalAddr))
{
#ifdef NETMGR_DEBUG
std::cerr << "p3NetMgrIMPL::checkNetAddress() laddr: Loopback" << std::endl;
@ -964,7 +983,7 @@ bool p3NetMgrIMPL::checkNetAddress()
mNetFlags.mLocalAddrOk = false;
mNetStatus = RS_NET_LOOPBACK;
}
else if (!isValidNet(&mLocalAddr.sin_addr))
else if (!sockaddr_storage_isValidNet(mLocalAddr))
{
#ifdef NETMGR_DEBUG
std::cerr << "p3NetMgrIMPL::checkNetAddress() laddr: invalid" << std::endl;
@ -980,7 +999,7 @@ bool p3NetMgrIMPL::checkNetAddress()
}
int port = ntohs(mLocalAddr.sin_port);
int port = sockaddr_storage_port(mLocalAddr);
if ((port < PQI_MIN_PORT) || (port > PQI_MAX_PORT))
{
#ifdef NETMGR_DEBUG
@ -990,8 +1009,9 @@ bool p3NetMgrIMPL::checkNetAddress()
// same, but appear random from peer to peer.
// Random port avoids clashes, improves anonymity.
//
mLocalAddr.sin_port = htons(PQI_MIN_PORT + (RSRandom::random_u32() % (PQI_MAX_PORT - PQI_MIN_PORT)));
int new_port = htons(PQI_MIN_PORT + (RSRandom::random_u32() % (PQI_MAX_PORT - PQI_MIN_PORT)));
sockaddr_storage_setport(mLocalAddr, new_port);
addrChanged = true;
}
@ -1000,18 +1020,17 @@ bool p3NetMgrIMPL::checkNetAddress()
* are the same (modify server)... this mismatch can
* occur when the local port is changed....
*/
if (mLocalAddr.sin_addr.s_addr == mExtAddr.sin_addr.s_addr)
if (sockaddr_storage_sameip(mLocalAddr, mExtAddr))
{
mExtAddr.sin_port = mLocalAddr.sin_port;
sockaddr_storage_setport(mExtAddr, sockaddr_storage_port(mLocalAddr));
}
// ensure that address family is set, otherwise windows Barfs.
mLocalAddr.sin_family = AF_INET;
mExtAddr.sin_family = AF_INET;
//mLocalAddr.sin_family = AF_INET;
//mExtAddr.sin_family = AF_INET;
#ifdef NETMGR_DEBUG_TICK
std::cerr << "p3NetMgrIMPL::checkNetAddress() Final Local Address: " << rs_inet_ntoa(mLocalAddr.sin_addr);
std::cerr << ":" << ntohs(mLocalAddr.sin_port) << std::endl;
std::cerr << "p3NetMgrIMPL::checkNetAddress() Final Local Address: " << sockaddr_storage_tostring(mLocalAddr);
std::cerr << std::endl;
#endif
@ -1050,13 +1069,12 @@ void p3NetMgrIMPL::addNetListener(pqiNetListener *listener)
bool p3NetMgrIMPL::setLocalAddress(struct sockaddr_in addr)
bool p3NetMgrIMPL::setLocalAddress(const struct sockaddr_storage &addr)
{
bool changed = false;
{
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
if ((mLocalAddr.sin_addr.s_addr != addr.sin_addr.s_addr) ||
(mLocalAddr.sin_port != addr.sin_port))
if (sockaddr_storage_same(mLocalAddr, addr))
{
changed = true;
}
@ -1075,13 +1093,12 @@ bool p3NetMgrIMPL::setLocalAddress(struct sockaddr_in addr)
return true;
}
bool p3NetMgrIMPL::setExtAddress(struct sockaddr_in addr)
bool p3NetMgrIMPL::setExtAddress(const struct sockaddr_storage &addr)
{
bool changed = false;
{
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
if ((mExtAddr.sin_addr.s_addr != addr.sin_addr.s_addr) ||
(mExtAddr.sin_port != addr.sin_port))
if (sockaddr_storage_same(mExtAddr, addr))
{
changed = true;
}
@ -1109,12 +1126,12 @@ bool p3NetMgrIMPL::setNetworkMode(uint32_t netMode)
oldNetMode = mNetMode;
#ifdef NETMGR_DEBUG
//#ifdef NETMGR_DEBUG
std::cerr << "p3NetMgrIMPL::setNetworkMode()";
std::cerr << " Existing netMode: " << mNetMode;
std::cerr << " Input netMode: " << netMode;
std::cerr << std::endl;
#endif
//#endif
mNetMode &= ~(RS_NET_MODE_TRYMODE);
switch(netMode & RS_NET_MODE_ACTUAL)
@ -1125,6 +1142,9 @@ bool p3NetMgrIMPL::setNetworkMode(uint32_t netMode)
case RS_NET_MODE_UPNP:
mNetMode |= RS_NET_MODE_TRY_UPNP;
break;
case RS_NET_MODE_HIDDEN:
mNetMode |= RS_NET_MODE_TRY_LOOPBACK;
break;
default:
case RS_NET_MODE_UDP:
mNetMode |= RS_NET_MODE_TRY_UDP;
@ -1145,15 +1165,16 @@ bool p3NetMgrIMPL::setNetworkMode(uint32_t netMode)
}
bool p3NetMgrIMPL::setVisState(uint32_t visState)
bool p3NetMgrIMPL::setVisState(uint16_t vs_disc, uint16_t vs_dht)
{
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
mVisState = visState;
mVsDisc = vs_disc;
mVsDht = vs_dht;
/* if we've started up - then tweak Dht On/Off */
if (mNetStatus != RS_NET_UNKNOWN)
{
enableNetAssistConnect(!(mVisState & RS_VIS_STATE_NODHT));
enableNetAssistConnect(mVsDht != RS_VS_DHT_OFF);
}
return true;
@ -1229,7 +1250,7 @@ bool p3NetMgrIMPL::netAssistFirewallPorts(uint16_t iport, uint16_t eport)
}
bool p3NetMgrIMPL::netAssistExtAddress(struct sockaddr_in &extAddr)
bool p3NetMgrIMPL::netAssistExtAddress(struct sockaddr_storage &extAddr)
{
std::map<uint32_t, pqiNetAssistFirewall *>::iterator it;
for(it = mFwAgents.begin(); it != mFwAgents.end(); it++)
@ -1377,7 +1398,7 @@ bool p3NetMgrIMPL::netAssistFriend(const std::string &id, bool on)
}
bool p3NetMgrIMPL::netAssistKnownPeer(const std::string &id, const struct sockaddr_in &addr, uint32_t flags)
bool p3NetMgrIMPL::netAssistKnownPeer(const std::string &id, const struct sockaddr_storage &addr, uint32_t flags)
{
std::map<uint32_t, pqiNetAssistConnect *>::iterator it;
@ -1393,12 +1414,12 @@ bool p3NetMgrIMPL::netAssistKnownPeer(const std::string &id, const struct sockad
return true;
}
bool p3NetMgrIMPL::netAssistBadPeer(const struct sockaddr_in &addr, uint32_t reason, uint32_t flags, uint32_t age)
bool p3NetMgrIMPL::netAssistBadPeer(const struct sockaddr_storage &addr, uint32_t reason, uint32_t flags, uint32_t age)
{
std::map<uint32_t, pqiNetAssistConnect *>::iterator it;
#ifdef NETMGR_DEBUG
std::cerr << "p3NetMgrIMPL::netAssistBadPeer(" << rs_inet_ntoa(addr.sin_addr) << ")";
std::cerr << "p3NetMgrIMPL::netAssistBadPeer(" << sockaddr_storage_iptostring(addr) << ")";
std::cerr << std::endl;
#endif
@ -1433,7 +1454,7 @@ bool p3NetMgrIMPL::netAssistStatusUpdate(const std::string &id, int state)
std::map<uint32_t, pqiNetAssistConnect *>::iterator it;
#ifdef NETMGR_DEBUG
std::cerr << "p3NetMgrIMPL::netAssistFriend(" << id << ", " << on << ")";
std::cerr << "p3NetMgrIMPL::netAssistStatusUpdate(" << id << ", " << state << ")";
std::cerr << std::endl;
#endif
@ -1445,8 +1466,8 @@ bool p3NetMgrIMPL::netAssistStatusUpdate(const std::string &id, int state)
}
bool p3NetMgrIMPL::netAssistSetAddress( struct sockaddr_in &/*laddr*/,
struct sockaddr_in &/*eaddr*/,
bool p3NetMgrIMPL::netAssistSetAddress( const struct sockaddr_storage & /*laddr*/,
const struct sockaddr_storage & /*eaddr*/,
uint32_t /*mode*/)
{
#if 0
@ -1600,8 +1621,8 @@ void p3NetMgrIMPL::updateNetStateBox_temporal()
#endif
uint8_t isstable = 0;
struct sockaddr_in tmpaddr;
sockaddr_clear(&tmpaddr);
struct sockaddr_storage tmpaddr;
sockaddr_storage_clear(tmpaddr);
if (mDhtStunner)
{
@ -1610,11 +1631,11 @@ void p3NetMgrIMPL::updateNetStateBox_temporal()
if (mDhtStunner->getExternalAddr(tmpaddr, isstable))
{
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
mNetStateBox.setAddressStunDht(&tmpaddr, isstable);
mNetStateBox.setAddressStunDht(tmpaddr, isstable);
#ifdef NETMGR_DEBUG_STATEBOX
std::cerr << "p3NetMgrIMPL::updateNetStateBox_temporal() DhtStunner: ";
std::cerr << rs_inet_ntoa(tmpaddr.sin_addr) << ":" << htons(tmpaddr.sin_port);
std::cerr << sockaddr_storage_tostring(tmpaddr);
std::cerr << " Stable: " << (uint32_t) isstable;
std::cerr << std::endl;
#endif
@ -1629,11 +1650,11 @@ void p3NetMgrIMPL::updateNetStateBox_temporal()
if (mProxyStunner->getExternalAddr(tmpaddr, isstable))
{
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
mNetStateBox.setAddressStunProxy(&tmpaddr, isstable);
mNetStateBox.setAddressStunProxy(tmpaddr, isstable);
#ifdef NETMGR_DEBUG_STATEBOX
std::cerr << "p3NetMgrIMPL::updateNetStateBox_temporal() ProxyStunner: ";
std::cerr << rs_inet_ntoa(tmpaddr.sin_addr) << ":" << htons(tmpaddr.sin_port);
std::cerr << sockaddr_storage_tostring(tmpaddr);
std::cerr << " Stable: " << (uint32_t) isstable;
std::cerr << std::endl;
#endif
@ -1805,7 +1826,7 @@ void p3NetMgrIMPL::updateNetStateBox_startup()
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
/* fill in the data */
struct sockaddr_in tmpip;
struct sockaddr_storage tmpip;
/* net Assist */
if (netAssistExtAddress(tmpip))
@ -1817,19 +1838,18 @@ void p3NetMgrIMPL::updateNetStateBox_startup()
std::cerr << std::endl;
#endif
if (isValidNet(&(tmpip.sin_addr)))
if (sockaddr_storage_isValidNet(tmpip))
{
#ifdef NETMGR_DEBUG_STATEBOX
std::cerr << "p3NetMgrIMPL::updateNetStateBox_startup() ";
std::cerr << "netAssist Returned: " << rs_inet_ntoa(tmpip.sin_addr);
std::cerr << ":" << ntohs(tmpip.sin_port);
std::cerr << "netAssist Returned: " << sockaddr_storage_tostring(tmpip);
std::cerr << std::endl;
#endif
mNetStateBox.setAddressUPnP(true, &tmpip);
mNetStateBox.setAddressUPnP(true, tmpip);
}
else
{
mNetStateBox.setAddressUPnP(false, &tmpip);
mNetStateBox.setAddressUPnP(false, tmpip);
#ifdef NETMGR_DEBUG_STATEBOX
std::cerr << "p3NetMgrIMPL::updateNetStateBox_startup() ";
std::cerr << "ERROR Bad Address supplied from netAssistExternalAddress()";
@ -1844,30 +1864,30 @@ void p3NetMgrIMPL::updateNetStateBox_startup()
std::cerr << " netAssistExtAddress() is not active";
std::cerr << std::endl;
#endif
mNetStateBox.setAddressUPnP(false, &tmpip);
mNetStateBox.setAddressUPnP(false, tmpip);
}
/* ExtAddrFinder */
if (mUseExtAddrFinder)
{
bool extFinderOk = mExtAddrFinder->hasValidIP(&(tmpip.sin_addr));
bool extFinderOk = mExtAddrFinder->hasValidIP(tmpip);
if (extFinderOk)
{
/* best guess at port */
tmpip.sin_port = mNetFlags.mLocalAddr.sin_port;
sockaddr_storage_setport(tmpip, sockaddr_storage_port(mNetFlags.mLocalAddr));
#ifdef NETMGR_DEBUG_STATEBOX
std::cerr << "p3NetMgrIMPL::updateNetStateBox_startup() ";
std::cerr << "ExtAddrFinder Returned: " << rs_inet_ntoa(tmpip.sin_addr);
std::cerr << "ExtAddrFinder Returned: " << sockaddr_storage_iptostring(tmpip);
std::cerr << std::endl;
#endif
mNetStateBox.setAddressWebIP(true, &tmpip);
mNetStateBox.setAddressWebIP(true, tmpip);
}
else
{
mNetStateBox.setAddressWebIP(false, &tmpip);
mNetStateBox.setAddressWebIP(false, tmpip);
#ifdef NETMGR_DEBUG_STATEBOX
std::cerr << "p3NetMgrIMPL::updateNetStateBox_startup() ";
std::cerr << " ExtAddrFinder hasn't found an address yet";
@ -1882,7 +1902,7 @@ void p3NetMgrIMPL::updateNetStateBox_startup()
std::cerr << " ExtAddrFinder is not active";
std::cerr << std::endl;
#endif
mNetStateBox.setAddressWebIP(false, &tmpip);
mNetStateBox.setAddressWebIP(false, tmpip);
}

View file

@ -68,8 +68,8 @@ class pqiNetStatus
uint32_t mDhtNetworkSize;
uint32_t mDhtRsNetworkSize;
struct sockaddr_in mLocalAddr; // percieved ext addr.
struct sockaddr_in mExtAddr; // percieved ext addr.
struct sockaddr_storage mLocalAddr; // percieved ext addr.
struct sockaddr_storage mExtAddr; // percieved ext addr.
bool mResetReq; // Not Used yet!.
@ -115,12 +115,12 @@ virtual ~p3NetMgr() { return; }
// Setup Network State.
virtual bool setNetworkMode(uint32_t netMode) = 0;
virtual bool setVisState(uint32_t visState) = 0;
virtual bool setVisState(uint16_t vs_disc, uint16_t vs_dht) = 0;
// Switch DHT On/Off.
virtual bool netAssistFriend(const std::string &id, bool on) = 0;
virtual bool netAssistKnownPeer(const std::string &id, const struct sockaddr_in &addr, uint32_t flags) = 0;
virtual bool netAssistBadPeer(const struct sockaddr_in &addr, uint32_t reason, uint32_t flags, uint32_t age) = 0;
virtual bool netAssistKnownPeer(const std::string &id, const struct sockaddr_storage &addr, uint32_t flags) = 0;
virtual bool netAssistBadPeer(const struct sockaddr_storage &addr, uint32_t reason, uint32_t flags, uint32_t age) = 0;
virtual bool netAssistStatusUpdate(const std::string &id, int mode) = 0;
/* Get Network State */
@ -171,12 +171,12 @@ class p3NetMgrIMPL: public p3NetMgr
// Setup Network State.
virtual bool setNetworkMode(uint32_t netMode);
virtual bool setVisState(uint32_t visState);
virtual bool setVisState(uint16_t vs_disc, uint16_t vs_dht);
// Switch DHT On/Off.
virtual bool netAssistFriend(const std::string &id, bool on);
virtual bool netAssistKnownPeer(const std::string &id, const struct sockaddr_in &addr, uint32_t flags);
virtual bool netAssistBadPeer(const struct sockaddr_in &addr, uint32_t reason, uint32_t flags, uint32_t age);
virtual bool netAssistKnownPeer(const std::string &id, const struct sockaddr_storage &addr, uint32_t flags);
virtual bool netAssistBadPeer(const struct sockaddr_storage &addr, uint32_t reason, uint32_t flags, uint32_t age);
virtual bool netAssistStatusUpdate(const std::string &id, int mode);
/* Get Network State */
@ -214,8 +214,8 @@ void setAddrAssist(pqiAddrAssist *dhtStun, pqiAddrAssist *proxyStun);
void tick();
// THESE MIGHT BE ADDED TO INTERFACE.
bool setLocalAddress(struct sockaddr_in addr);
bool setExtAddress(struct sockaddr_in addr);
bool setLocalAddress(const struct sockaddr_storage &addr);
bool setExtAddress(const struct sockaddr_storage &addr);
/*************** Setup ***************************/
void addNetAssistConnect(uint32_t type, pqiNetAssistConnect *);
@ -262,13 +262,13 @@ bool netAssistConnectStats(uint32_t &netsize, uint32_t &localnetsize);
void netAssistTick();
/* Assist Firewall */
bool netAssistExtAddress(struct sockaddr_in &extAddr);
bool netAssistExtAddress(struct sockaddr_storage &extAddr);
bool netAssistFirewallPorts(uint16_t iport, uint16_t eport);
/* Assist Connect */
//virtual bool netAssistFriend(std::string id, bool on); (PUBLIC)
bool netAssistSetAddress( struct sockaddr_in &laddr,
struct sockaddr_in &eaddr,
bool netAssistSetAddress(const struct sockaddr_storage &laddr,
const struct sockaddr_storage &eaddr,
uint32_t mode);
bool netAssistAttach(bool on);
@ -326,11 +326,12 @@ private:
void netStatusReset_locked();
struct sockaddr_in mLocalAddr;
struct sockaddr_in mExtAddr;
struct sockaddr_storage mLocalAddr;
struct sockaddr_storage mExtAddr;
uint32_t mNetMode;
uint32_t mVisState;
uint16_t mVsDisc;
uint16_t mVsDht;
time_t mNetInitTS;
uint32_t mNetStatus;

View file

@ -68,19 +68,28 @@ const uint32_t PEER_IP_CONNECT_STATE_MAX_LIST_SIZE = 4;
/****
* #define PEER_DEBUG 1
***/
#define PEER_DEBUG 1
#define MAX_AVAIL_PERIOD 230 //times a peer stay in available state when not connected
#define MIN_RETRY_PERIOD 140
static const std::string kConfigDefaultProxyServerIpAddr = "127.0.0.1";
static const uint16_t kConfigDefaultProxyServerPort = 9050; // standard port.
static const std::string kConfigKeyExtIpFinder = "USE_EXTR_IP_FINDER";
static const std::string kConfigKeyProxyServerIpAddr = "PROXY_SERVER_IPADDR";
static const std::string kConfigKeyProxyServerPort = "PROXY_SERVER_PORT";
void printConnectState(std::ostream &out, peerState &peer);
peerState::peerState()
:id("unknown"),
gpg_id("unknown"),
netMode(RS_NET_MODE_UNKNOWN), visState(RS_VIS_STATE_STD), lastcontact(0)
netMode(RS_NET_MODE_UNKNOWN), vs_disc(RS_VS_DISC_FULL), vs_dht(RS_VS_DHT_FULL), lastcontact(0),
hiddenNode(false), hiddenPort(0)
{
sockaddr_clear(&localaddr);
sockaddr_clear(&serveraddr);
sockaddr_storage_clear(localaddr);
sockaddr_storage_clear(serveraddr);
return;
}
@ -89,18 +98,22 @@ std::string textPeerConnectState(peerState &state)
{
std::string out = "Id: " + state.id + "\n";
rs_sprintf_append(out, "NetMode: %lu\n", state.netMode);
rs_sprintf_append(out, "VisState: %lu\n", state.visState);
rs_sprintf_append(out, "laddr: %s:%u\n", rs_inet_ntoa(state.localaddr.sin_addr).c_str(), ntohs(state.localaddr.sin_port));
rs_sprintf_append(out, "eaddr: %s:%u\n", rs_inet_ntoa(state.serveraddr.sin_addr).c_str(), ntohs(state.serveraddr.sin_port));
rs_sprintf_append(out, "VisState: Disc: %u Dht: %u\n", state.vs_disc, state.vs_dht);
out += "laddr: ";
out += sockaddr_storage_tostring(state.localaddr);
out += "\neaddr: ";
out += sockaddr_storage_tostring(state.serveraddr);
out += "\n";
return out;
}
p3PeerMgrIMPL::p3PeerMgrIMPL( const std::string& ssl_own_id,
const std::string& gpg_own_id,
const std::string& gpg_own_name,
const std::string& ssl_own_location)
p3PeerMgrIMPL::p3PeerMgrIMPL(const std::string& ssl_own_id,
const std::string& gpg_own_id,
const std::string& gpg_own_name,
const std::string& ssl_own_location)
:p3Config(CONFIG_TYPE_PEERS), mPeerMtx("p3PeerMgr"), mStatusChanged(false)
{
@ -116,11 +129,17 @@ p3PeerMgrIMPL::p3PeerMgrIMPL( const std::string& ssl_own_id,
mOwnState.name = gpg_own_name ;
mOwnState.location = ssl_own_location ;
mOwnState.netMode = RS_NET_MODE_UPNP; // Default to UPNP.
mOwnState.visState = 0;
mOwnState.vs_disc = RS_VS_DISC_FULL;
mOwnState.vs_dht = RS_VS_DHT_FULL;
lastGroupId = 1;
// setup default ProxyServerAddress.
sockaddr_storage_clear(mProxyServerAddress);
sockaddr_storage_ipv4_aton(mProxyServerAddress,
kConfigDefaultProxyServerIpAddr.c_str());
sockaddr_storage_ipv4_setport(mProxyServerAddress,
kConfigDefaultProxyServerPort);
}
#ifdef PEER_DEBUG
@ -137,18 +156,77 @@ void p3PeerMgrIMPL::setManagers(p3LinkMgrIMPL *linkMgr, p3NetMgrIMPL *netMgr)
mNetMgr = netMgr;
}
bool p3PeerMgrIMPL::setupHiddenNode(const std::string &hiddenAddress, const uint16_t hiddenPort)
{
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
std::cerr << "p3PeerMgrIMPL::setupHiddenNode()";
std::cerr << " Address: " << hiddenAddress;
std::cerr << " Port: " << hiddenPort;
std::cerr << std::endl;
mOwnState.hiddenNode = true;
mOwnState.hiddenPort = hiddenPort;
mOwnState.hiddenDomain = hiddenAddress;
}
forceHiddenNode();
return true;
}
bool p3PeerMgrIMPL::forceHiddenNode()
{
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
if (RS_NET_MODE_HIDDEN != mOwnState.netMode)
{
std::cerr << "p3PeerMgrIMPL::forceHiddenNode() Required!";
std::cerr << std::endl;
}
mOwnState.hiddenNode = true;
// force external address - otherwise its invalid.
sockaddr_storage_clear(mOwnState.serveraddr);
sockaddr_storage_ipv4_aton(mOwnState.serveraddr, "0.0.0.0");
sockaddr_storage_ipv4_setport(mOwnState.serveraddr, 0);
}
setOwnNetworkMode(RS_NET_MODE_HIDDEN);
// switch off DHT too.
setOwnVisState(mOwnState.vs_disc, RS_VS_DHT_OFF);
// Force the Port.
struct sockaddr_storage loopback;
sockaddr_storage_clear(loopback);
sockaddr_storage_ipv4_aton(loopback, "127.0.0.1");
uint16_t port = sockaddr_storage_port(mOwnState.localaddr);
sockaddr_storage_ipv4_setport(loopback, port);
setLocalAddress(AuthSSL::getAuthSSL()->OwnId(), loopback);
mNetMgr->setIPServersEnabled(false);
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
return true;
}
bool p3PeerMgrIMPL::setOwnNetworkMode(uint32_t netMode)
{
bool changed = false;
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
#ifdef PEER_DEBUG
//#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::setOwnNetworkMode() :";
std::cerr << " Existing netMode: " << mOwnState.netMode;
std::cerr << " Input netMode: " << netMode;
std::cerr << std::endl;
#endif
//#endif
if (mOwnState.netMode != (netMode & RS_NET_MODE_ACTUAL))
{
@ -163,29 +241,32 @@ bool p3PeerMgrIMPL::setOwnNetworkMode(uint32_t netMode)
return changed;
}
bool p3PeerMgrIMPL::setOwnVisState(uint32_t visState)
bool p3PeerMgrIMPL::setOwnVisState(uint16_t vs_disc, uint16_t vs_dht)
{
bool changed = false;
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
std::string out;
rs_sprintf(out, "p3PeerMgr::setOwnVisState() Existing vis: %lu Input vis: %lu", mOwnState.visState, visState);
rs_sprintf(out, "p3PeerMgr::setOwnVisState() Existing vis: %u/%u Input vis: %u/%u",
mOwnState.vs_disc, mOwnState.vs_dht, vs_disc, vs_dht);
rslog(RSL_WARNING, p3peermgrzone, out);
#ifdef PEER_DEBUG
std::cerr << out.str() << std::endl;
std::cerr << out.c_str() << std::endl;
#endif
if (mOwnState.visState != visState) {
mOwnState.visState = visState;
if (mOwnState.vs_disc != vs_disc || mOwnState.vs_dht != vs_dht)
{
mOwnState.vs_disc = vs_disc;
mOwnState.vs_dht = vs_dht;
changed = true;
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
}
}
// Pass on Flags to NetMgr.
mNetMgr->setVisState(visState);
mNetMgr->setVisState(vs_disc, vs_dht);
return changed;
}
@ -274,6 +355,131 @@ bool p3PeerMgrIMPL::getGpgId(const std::string &ssl_id, std::string &gpgId)
return true;
}
/**** HIDDEN STUFF ****/
bool p3PeerMgrIMPL::isHidden()
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
return mOwnState.hiddenNode;
}
bool p3PeerMgrIMPL::isHiddenPeer(const std::string &ssl_id)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
/* check for existing */
std::map<std::string, peerState>::iterator it;
it = mFriendList.find(ssl_id);
if (it == mFriendList.end())
{
std::cerr << "p3PeerMgrIMPL::isHiddenPeer(" << ssl_id << ") Missing Peer => false";
std::cerr << std::endl;
return false;
}
std::cerr << "p3PeerMgrIMPL::isHiddenPeer(" << ssl_id << ") = " << (it->second).hiddenNode;
std::cerr << std::endl;
return (it->second).hiddenNode;
}
bool p3PeerMgrIMPL::setHiddenDomainPort(const std::string &ssl_id, const std::string &domain_addr, const uint16_t domain_port)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
std::cerr << "p3PeerMgrIMPL::setHiddenDomainPort()";
std::cerr << std::endl;
std::string domain = domain_addr;
// trim whitespace!
size_t pos = domain.find_last_not_of(" \t\n");
if (std::string::npos != pos)
{
domain = domain.substr(0, pos + 1);
}
pos = domain.find_first_not_of(" \t\n");
if (std::string::npos != pos)
{
domain = domain.substr(pos);
}
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
if (ssl_id == AuthSSL::getAuthSSL()->OwnId())
{
mOwnState.hiddenNode = true;
mOwnState.hiddenDomain = domain;
mOwnState.hiddenPort = domain_port;
std::cerr << "p3PeerMgrIMPL::setHiddenDomainPort() Set own State";
std::cerr << std::endl;
return true;
}
/* check for existing */
std::map<std::string, peerState>::iterator it;
it = mFriendList.find(ssl_id);
if (it == mFriendList.end())
{
std::cerr << "p3PeerMgrIMPL::setHiddenDomainPort() Peer Not Found";
std::cerr << std::endl;
return false;
}
it->second.hiddenDomain = domain;
it->second.hiddenPort = domain_port;
it->second.hiddenNode = true;
std::cerr << "p3PeerMgrIMPL::setHiddenDomainPort() Set Peers State";
std::cerr << std::endl;
return true;
}
bool p3PeerMgrIMPL::setProxyServerAddress(const struct sockaddr_storage &proxy_addr)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
if (!sockaddr_storage_same(mProxyServerAddress,proxy_addr))
{
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
mProxyServerAddress = proxy_addr;
}
return true;
}
bool p3PeerMgrIMPL::getProxyServerAddress(struct sockaddr_storage &proxy_addr)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
proxy_addr = mProxyServerAddress;
return true;
}
bool p3PeerMgrIMPL::getProxyAddress(const std::string &ssl_id, struct sockaddr_storage &proxy_addr, std::string &domain_addr, uint16_t &domain_port)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
/* check for existing */
std::map<std::string, peerState>::iterator it;
it = mFriendList.find(ssl_id);
if (it == mFriendList.end())
{
return false;
}
if (!it->second.hiddenNode)
{
return false;
}
domain_addr = it->second.hiddenDomain;
domain_port = it->second.hiddenPort;
proxy_addr = mProxyServerAddress;
return true;
}
// Placeholder until we implement this functionality.
uint32_t p3PeerMgrIMPL::getConnectionType(const std::string &/*sslId*/)
{
@ -394,7 +600,7 @@ void p3PeerMgrIMPL::getOthersList(std::list<std::string> &peers)
int p3PeerMgrIMPL::getConnectAddresses(const std::string &id,
struct sockaddr_in &lAddr, struct sockaddr_in &eAddr,
struct sockaddr_storage &lAddr, struct sockaddr_storage &eAddr,
pqiIpAddrSet &histAddrs, std::string &dyndns)
{
@ -454,7 +660,7 @@ bool p3PeerMgrIMPL::haveOnceConnected()
/*******************************************************************/
/*******************************************************************/
bool p3PeerMgrIMPL::addFriend(const std::string& input_id, const std::string& input_gpg_id, uint32_t netMode, uint32_t visState, time_t lastContact,ServicePermissionFlags service_flags)
bool p3PeerMgrIMPL::addFriend(const std::string& input_id, const std::string& input_gpg_id, uint32_t netMode, uint16_t vs_disc, uint16_t vs_dht, time_t lastContact,ServicePermissionFlags service_flags)
{
bool notifyLinkMgr = false;
std::string id = input_id ;
@ -530,7 +736,9 @@ bool p3PeerMgrIMPL::addFriend(const std::string& input_id, const std::string& in
it = mFriendList.find(id);
/* setup connectivity parameters */
it->second.visState = visState;
it->second.vs_disc = vs_disc;
it->second.vs_dht = vs_dht;
it->second.netMode = netMode;
it->second.lastcontact = lastContact;
@ -553,7 +761,8 @@ bool p3PeerMgrIMPL::addFriend(const std::string& input_id, const std::string& in
pstate.gpg_id = gpg_id;
pstate.name = AuthGPG::getAuthGPG()->getGPGName(gpg_id);
pstate.visState = visState;
pstate.vs_disc = vs_disc;
pstate.vs_dht = vs_dht;
pstate.netMode = netMode;
pstate.lastcontact = lastContact;
@ -571,7 +780,7 @@ bool p3PeerMgrIMPL::addFriend(const std::string& input_id, const std::string& in
if (notifyLinkMgr)
{
mLinkMgr->addFriend(id, !(visState & RS_VIS_STATE_NODHT));
mLinkMgr->addFriend(id, vs_dht != RS_VS_DHT_OFF);
}
service_flags &= servicePermissionFlags(gpg_id) ; // Always reduce the permissions.
@ -774,12 +983,12 @@ bool p3PeerMgrIMPL::addNeighbour(std::string id)
* as it doesn't call back to there.
*/
bool p3PeerMgrIMPL::UpdateOwnAddress(const struct sockaddr_in &localAddr, const struct sockaddr_in &extAddr)
bool p3PeerMgrIMPL::UpdateOwnAddress(const struct sockaddr_storage &localAddr, const struct sockaddr_storage &extAddr)
{
std::cerr << "p3PeerMgrIMPL::UpdateOwnAddress(";
std::cerr << rs_inet_ntoa(localAddr.sin_addr) << ":" << htons(localAddr.sin_port);
std::cerr << sockaddr_storage_tostring(localAddr);
std::cerr << ", ";
std::cerr << rs_inet_ntoa(extAddr.sin_addr) << ":" << htons(extAddr.sin_port);
std::cerr << sockaddr_storage_tostring(extAddr);
std::cerr << ")" << std::endl;
{
@ -820,19 +1029,18 @@ bool p3PeerMgrIMPL::UpdateOwnAddress(const struct sockaddr_in &localAddr, const
std::cerr << " as MANUAL FORWARD Mode (ERROR - SHOULD NOT BE TRIGGERED: TRY_EXT_MODE)";
std::cerr << std::endl;
std::cerr << "Address is Now: ";
std::cerr << rs_inet_ntoa(mOwnState.serveraddr.sin_addr);
std::cerr << ":" << htons(mOwnState.serveraddr.sin_port);
std::cerr << sockaddr_storage_tostring(mOwnState.serveraddr);
std::cerr << std::endl;
}
else if (mOwnState.netMode & RS_NET_MODE_EXT)
{
mOwnState.serveraddr.sin_addr.s_addr = extAddr.sin_addr.s_addr;
sockaddr_storage_copyip(mOwnState.serveraddr,extAddr);
std::cerr << "p3PeerMgrIMPL::UpdateOwnAddress() Disabling Update of Server Port ";
std::cerr << " as MANUAL FORWARD Mode";
std::cerr << std::endl;
std::cerr << "Address is Now: ";
std::cerr << rs_inet_ntoa(mOwnState.serveraddr.sin_addr);
std::cerr << ":" << htons(mOwnState.serveraddr.sin_port);
std::cerr << sockaddr_storage_tostring(mOwnState.serveraddr);
std::cerr << std::endl;
}
else
@ -850,7 +1058,7 @@ bool p3PeerMgrIMPL::UpdateOwnAddress(const struct sockaddr_in &localAddr, const
bool p3PeerMgrIMPL::setLocalAddress(const std::string &id, struct sockaddr_in addr)
bool p3PeerMgrIMPL::setLocalAddress(const std::string &id, const struct sockaddr_storage &addr)
{
bool changed = false;
@ -858,8 +1066,7 @@ bool p3PeerMgrIMPL::setLocalAddress(const std::string &id, struct sockaddr_in
{
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
if (mOwnState.localaddr.sin_addr.s_addr != addr.sin_addr.s_addr ||
mOwnState.localaddr.sin_port != addr.sin_port)
if (!sockaddr_storage_same(mOwnState.localaddr, addr))
{
mOwnState.localaddr = addr;
changed = true;
@ -891,8 +1098,8 @@ bool p3PeerMgrIMPL::setLocalAddress(const std::string &id, struct sockaddr_in
}
/* "it" points to peer */
if ((it->second.localaddr.sin_addr.s_addr != addr.sin_addr.s_addr) ||
(it->second.localaddr.sin_port != addr.sin_port)) {
if (!sockaddr_storage_same(it->second.localaddr, addr))
{
it->second.localaddr = addr;
changed = true;
}
@ -912,7 +1119,7 @@ bool p3PeerMgrIMPL::setLocalAddress(const std::string &id, struct sockaddr_in
return changed;
}
bool p3PeerMgrIMPL::setExtAddress(const std::string &id, struct sockaddr_in addr)
bool p3PeerMgrIMPL::setExtAddress(const std::string &id, const struct sockaddr_storage &addr)
{
bool changed = false;
@ -920,8 +1127,7 @@ bool p3PeerMgrIMPL::setExtAddress(const std::string &id, struct sockaddr_in a
{
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
if (mOwnState.serveraddr.sin_addr.s_addr != addr.sin_addr.s_addr ||
mOwnState.serveraddr.sin_port != addr.sin_port)
if (!sockaddr_storage_same(mOwnState.serveraddr, addr))
{
mOwnState.serveraddr = addr;
changed = true;
@ -948,8 +1154,8 @@ bool p3PeerMgrIMPL::setExtAddress(const std::string &id, struct sockaddr_in a
}
/* "it" points to peer */
if ((it->second.serveraddr.sin_addr.s_addr != addr.sin_addr.s_addr) ||
(it->second.serveraddr.sin_port != addr.sin_port)) {
if (!sockaddr_storage_same(it->second.serveraddr, addr))
{
it->second.serveraddr = addr;
changed = true;
}
@ -1043,7 +1249,9 @@ bool p3PeerMgrIMPL::updateAddressList(const std::string& id, const pqiIpAddrS
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::setLocalAddress() Updated Address for: " << id;
std::cerr << std::endl;
it->second.ipAddrs.printAddrs(std::cerr);
std::string addrstr;
it->second.ipAddrs.printAddrs(addrstr);
std::cerr << addrstr;
std::cerr << std::endl;
#endif
@ -1074,7 +1282,7 @@ bool p3PeerMgrIMPL::updateCurrentAddress(const std::string& id, const pqiIpAd
}
}
if (isPrivateNet(&(addr.mAddr.sin_addr)))
if (sockaddr_storage_isPrivateNet(addr.mAddr))
{
it->second.ipAddrs.updateLocalAddrs(addr);
it->second.localaddr = addr.mAddr;
@ -1088,7 +1296,9 @@ bool p3PeerMgrIMPL::updateCurrentAddress(const std::string& id, const pqiIpAd
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::updatedCurrentAddress() Updated Address for: " << id;
std::cerr << std::endl;
it->second.ipAddrs.printAddrs(std::cerr);
std::string addrstr;
it->second.ipAddrs.printAddrs(addrstr);
std::cerr << addrstr;
std::cerr << std::endl;
#endif
@ -1186,20 +1396,19 @@ bool p3PeerMgrIMPL::setLocation(const std::string &id, const std::string &loc
return changed;
}
bool p3PeerMgrIMPL::setVisState(const std::string &id, uint32_t visState)
bool p3PeerMgrIMPL::setVisState(const std::string &id, uint16_t vs_disc, uint16_t vs_dht)
{
{
std::string out;
rs_sprintf(out, "p3PeerMgr::setVisState(%s, %lu)", id.c_str(), visState);
rs_sprintf(out, "p3PeerMgr::setVisState(%s, %u, %u)", id.c_str(), vs_disc, vs_dht);
rslog(RSL_WARNING, p3peermgrzone, out);
}
if (id == AuthSSL::getAuthSSL()->OwnId())
{
return setOwnVisState(visState);
return setOwnVisState(vs_disc, vs_dht);
}
bool dht_state ;
bool isFriend = false;
bool changed = false;
{
@ -1220,53 +1429,47 @@ bool p3PeerMgrIMPL::setVisState(const std::string &id, uint32_t visState)
}
/* "it" points to peer */
if (it->second.visState != visState) {
it->second.visState = visState;
if ((it->second.vs_disc != vs_disc) || (it->second.vs_dht = vs_dht))
{
it->second.vs_disc = vs_disc;
it->second.vs_dht = vs_dht;
changed = true;
dht_state = it->second.visState & RS_VIS_STATE_NODHT ;
std::cerr << "p3PeerMgrIMPL::setVisState(" << id << ", " << std::hex << visState << std::dec << ") ";
std::cerr << "p3PeerMgrIMPL::setVisState(" << id << ", DISC: " << vs_disc << " DHT: " << vs_dht << ") ";
std::cerr << " NAME: " << it->second.name;
if (it->second.visState & RS_VIS_STATE_NODHT)
switch(it->second.vs_disc)
{
std::cerr << " NO-DHT ";
default:
case RS_VS_DISC_OFF:
std::cerr << " NO-DISC ";
break;
case RS_VS_DISC_MINIMAL:
std::cerr << " MIN-DISC ";
break;
case RS_VS_DISC_FULL:
std::cerr << " FULL-DISC ";
break;
}
else
switch(it->second.vs_dht)
{
std::cerr << " DHT-OK ";
}
if (it->second.visState & RS_VIS_STATE_NODISC)
{
std::cerr << " NO-DISC ";
}
else
{
std::cerr << " DISC-OK ";
default:
case RS_VS_DHT_OFF:
std::cerr << " NO-DHT ";
break;
case RS_VS_DHT_PASSIVE:
std::cerr << " PASSIVE-DHT ";
break;
case RS_VS_DHT_FULL:
std::cerr << " FULL-DHT ";
break;
}
std::cerr << std::endl;
}
}
if(isFriend && changed)
{
/* toggle DHT state */
if(dht_state)
{
std::cerr << "p3PeerMgrIMPL::setVisState() setFriendVisibility => false";
std::cerr << std::endl;
/* hidden from DHT world */
mLinkMgr->setFriendVisibility(id, false);
}
else
{
std::cerr << "p3PeerMgrIMPL::setVisState() setFriendVisibility => true";
std::cerr << std::endl;
mLinkMgr->setFriendVisibility(id, true);
}
mLinkMgr->setFriendVisibility(id, vs_dht != RS_VS_DHT_OFF);
}
if (changed) {
@ -1305,7 +1508,10 @@ bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list<RsItem *>& saveData)
/* create a list of current peers */
cleanup = false;
bool useExtAddrFinder = mNetMgr->getIPServersEnabled();
bool allowTunnelConnection = mLinkMgr->getTunnelConnection();
// Store Proxy Server.
struct sockaddr_storage proxy_addr;
getProxyServerAddress(proxy_addr);
mPeerMtx.lock(); /****** MUTEX LOCKED *******/
@ -1331,14 +1537,21 @@ bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list<RsItem *>& saveData)
#endif
item->netMode = mOwnState.netMode;
item->visState = mOwnState.visState;
item->vs_disc = mOwnState.vs_disc;
item->vs_dht = mOwnState.vs_dht;
item->lastContact = mOwnState.lastcontact;
item->currentlocaladdr = mOwnState.localaddr;
item->currentremoteaddr = mOwnState.serveraddr;
item->dyndns = mOwnState.dyndns;
mOwnState.ipAddrs.mLocal.loadTlv(item->localAddrList);
mOwnState.ipAddrs.mExt.loadTlv(item->extAddrList);
item->localAddrV4.addr = mOwnState.localaddr;
item->extAddrV4.addr = mOwnState.serveraddr;
sockaddr_storage_clear(item->localAddrV6.addr);
sockaddr_storage_clear(item->extAddrV6.addr);
item->dyndns = mOwnState.dyndns;
mOwnState.ipAddrs.mLocal.loadTlv(item->localAddrList);
mOwnState.ipAddrs.mExt.loadTlv(item->extAddrList);
item->domain_addr = mOwnState.hiddenDomain;
item->domain_port = mOwnState.hiddenPort;
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::saveList() Own Config Item:" << std::endl;
@ -1360,14 +1573,24 @@ bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list<RsItem *>& saveData)
item->gpg_id = (it->second).gpg_id;
item->location = (it->second).location;
item->netMode = (it->second).netMode;
item->visState = (it->second).visState;
item->vs_disc = (it->second).vs_disc;
item->vs_dht = (it->second).vs_dht;
item->lastContact = (it->second).lastcontact;
item->currentlocaladdr = (it->second).localaddr;
item->currentremoteaddr = (it->second).serveraddr;
item->localAddrV4.addr = (it->second).localaddr;
item->extAddrV4.addr = (it->second).serveraddr;
sockaddr_storage_clear(item->localAddrV6.addr);
sockaddr_storage_clear(item->extAddrV6.addr);
item->dyndns = (it->second).dyndns;
(it->second).ipAddrs.mLocal.loadTlv(item->localAddrList);
(it->second).ipAddrs.mExt.loadTlv(item->extAddrList);
item->domain_addr = (it->second).hiddenDomain;
item->domain_port = (it->second).hiddenPort;
saveData.push_back(item);
saveCleanupList.push_back(item);
#ifdef PEER_DEBUG
@ -1393,31 +1616,25 @@ bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list<RsItem *>& saveData)
RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ;
RsTlvKeyValue kv;
kv.key = "USE_EXTR_IP_FINDER" ;
kv.key = kConfigKeyExtIpFinder;
kv.value = (useExtAddrFinder)?"TRUE":"FALSE" ;
vitem->tlvkvs.pairs.push_back(kv) ;
#ifdef PEER_DEBUG
std::cout << "Pushing item for use_extr_addr_finder = " << useExtAddrFinder << std::endl ;
#endif
std::cerr << "Saving proxyServerAddress: " << sockaddr_storage_tostring(proxy_addr);
std::cerr << std::endl;
kv.key = kConfigKeyProxyServerIpAddr;
kv.value = sockaddr_storage_iptostring(proxy_addr);
vitem->tlvkvs.pairs.push_back(kv) ;
kv.key = kConfigKeyProxyServerPort;
kv.value = sockaddr_storage_porttostring(proxy_addr);
vitem->tlvkvs.pairs.push_back(kv) ;
saveData.push_back(vitem);
saveCleanupList.push_back(vitem);
// Now save config for network digging strategies
RsConfigKeyValueSet *vitem2 = new RsConfigKeyValueSet ;
RsTlvKeyValue kv2;
kv2.key = "ALLOW_TUNNEL_CONNECTION" ;
kv2.value = (allowTunnelConnection)?"TRUE":"FALSE" ;
vitem2->tlvkvs.pairs.push_back(kv2) ;
#ifdef PEER_DEBUG
std::cout << "Pushing item for allow_tunnel_connection = " << allowTunnelConnection << std::endl ;
#endif
saveData.push_back(vitem2);
saveCleanupList.push_back(vitem2);
/* save groups */
std::list<RsPeerGroupItem *>::iterator groupIt;
@ -1448,8 +1665,9 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
// DEFAULTS.
bool useExtAddrFinder = true;
bool allowTunnelConnection = true;
std::string proxyIpAddress = kConfigDefaultProxyServerIpAddr;
uint16_t proxyPort = kConfigDefaultProxyServerPort;
if (load.size() == 0) {
std::cerr << "p3PeerMgrIMPL::loadList() list is empty, it may be a configuration problem." << std::endl;
return false;
@ -1477,7 +1695,7 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
#endif
/* add ownConfig */
setOwnNetworkMode(pitem->netMode);
setOwnVisState(pitem->visState);
setOwnVisState(pitem->vs_disc, pitem->vs_dht);
mOwnState.gpg_id = AuthGPG::getAuthGPG()->getGPGOwnId();
mOwnState.location = AuthSSL::getAuthSSL()->getOwnLocation();
@ -1490,20 +1708,30 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
std::cerr << std::endl;
#endif
/* ************* */
addFriend(pitem->pid, pitem->gpg_id, pitem->netMode, pitem->visState, pitem->lastContact, RS_SERVICE_PERM_ALL);
addFriend(pitem->pid, pitem->gpg_id, pitem->netMode, pitem->vs_disc, pitem->vs_dht, pitem->lastContact, RS_SERVICE_PERM_ALL);
setLocation(pitem->pid, pitem->location);
}
setLocalAddress(pitem->pid, pitem->currentlocaladdr);
setExtAddress(pitem->pid, pitem->currentremoteaddr);
setDynDNS (pitem->pid, pitem->dyndns);
/* convert addresses */
pqiIpAddrSet addrs;
addrs.mLocal.extractFromTlv(pitem->localAddrList);
addrs.mExt.extractFromTlv(pitem->extAddrList);
if (pitem->netMode == RS_NET_MODE_HIDDEN)
{
/* set only the hidden stuff & localAddress */
setLocalAddress(pitem->pid, pitem->localAddrV4.addr);
setHiddenDomainPort(pitem->pid, pitem->domain_addr, pitem->domain_port);
}
else
{
setLocalAddress(pitem->pid, pitem->localAddrV4.addr);
setExtAddress(pitem->pid, pitem->extAddrV4.addr);
setDynDNS (pitem->pid, pitem->dyndns);
/* convert addresses */
pqiIpAddrSet addrs;
addrs.mLocal.extractFromTlv(pitem->localAddrList);
addrs.mExt.extractFromTlv(pitem->extAddrList);
updateAddressList(pitem->pid, addrs);
updateAddressList(pitem->pid, addrs);
}
delete(*it);
@ -1521,13 +1749,25 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
std::cerr << std::endl;
#endif
std::list<RsTlvKeyValue>::iterator kit;
for(kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); kit++) {
if(kit->key == "USE_EXTR_IP_FINDER") {
for(kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); kit++)
{
if (kit->key == kConfigKeyExtIpFinder)
{
useExtAddrFinder = (kit->value == "TRUE");
std::cerr << "setting use_extr_addr_finder to " << useExtAddrFinder << std::endl ;
} else if (kit->key == "ALLOW_TUNNEL_CONNECTION") {
allowTunnelConnection = (kit->value == "TRUE");
std::cerr << "setting allow_tunnel_connection to " << allowTunnelConnection << std::endl ;
}
else if (kit->key == kConfigKeyProxyServerIpAddr)
{
proxyIpAddress = kit->value;
std::cerr << "Loaded proxyIpAddress: " << proxyIpAddress;
std::cerr << std::endl ;
}
else if (kit->key == kConfigKeyProxyServerPort)
{
proxyPort = atoi(kit->value.c_str());
std::cerr << "Loaded proxyPort: " << proxyPort;
std::cerr << std::endl ;
}
}
@ -1625,9 +1865,25 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
}
}
// If we are hidden - don't want ExtAddrFinder - ever!
if (isHidden())
{
useExtAddrFinder = false;
}
mNetMgr->setIPServersEnabled(useExtAddrFinder);
mLinkMgr->setTunnelConnection(allowTunnelConnection);
// Configure Proxy Server.
struct sockaddr_storage proxy_addr;
sockaddr_storage_clear(proxy_addr);
sockaddr_storage_ipv4_aton(proxy_addr, proxyIpAddress.c_str());
sockaddr_storage_ipv4_setport(proxy_addr, proxyPort);
if (sockaddr_storage_isValidNet(proxy_addr))
{
setProxyServerAddress(proxy_addr);
}
return true;
}

View file

@ -35,40 +35,26 @@
#include "util/rsthreads.h"
/* RS_VIS_STATE_XXXX
* determines how public this peer wants to be...
*
* STD = advertise to Peers / DHT checking etc
* GRAY = share with friends / but not DHT
* DARK = hidden from all
* BROWN? = hidden from friends / but on DHT
*/
const uint32_t RS_VIS_STATE_NODISC = 0x0001;
const uint32_t RS_VIS_STATE_NODHT = 0x0002;
const uint32_t RS_VIS_STATE_STD = 0x0000;
const uint32_t RS_VIS_STATE_GRAY = RS_VIS_STATE_NODHT;
const uint32_t RS_VIS_STATE_DARK = RS_VIS_STATE_NODISC | RS_VIS_STATE_NODHT;
const uint32_t RS_VIS_STATE_BROWN = RS_VIS_STATE_NODISC;
/* RS_VIS_STATE -> specified in rspeers.h
*/
/* Startup Modes (confirmed later) */
const uint32_t RS_NET_MODE_TRYMODE = 0x00f0;
const uint32_t RS_NET_MODE_TRYMODE = 0xff00;
const uint32_t RS_NET_MODE_TRY_EXT = 0x0010;
const uint32_t RS_NET_MODE_TRY_UPNP = 0x0020;
const uint32_t RS_NET_MODE_TRY_UDP = 0x0040;
const uint32_t RS_NET_MODE_TRY_EXT = 0x0100;
const uint32_t RS_NET_MODE_TRY_UPNP = 0x0200;
const uint32_t RS_NET_MODE_TRY_UDP = 0x0400;
const uint32_t RS_NET_MODE_TRY_LOOPBACK = 0x0800;
/* Actual State */
const uint32_t RS_NET_MODE_ACTUAL = 0x000f;
const uint32_t RS_NET_MODE_ACTUAL = 0x00ff;
const uint32_t RS_NET_MODE_UNKNOWN = 0x0000;
const uint32_t RS_NET_MODE_EXT = 0x0001;
const uint32_t RS_NET_MODE_UPNP = 0x0002;
const uint32_t RS_NET_MODE_UDP = 0x0004;
const uint32_t RS_NET_MODE_UNREACHABLE = 0x0008;
const uint32_t RS_NET_MODE_HIDDEN = 0x0008;
const uint32_t RS_NET_MODE_UNREACHABLE = 0x0010;
/* flags of peerStatus */
@ -87,11 +73,13 @@ class peerState
std::string id;
std::string gpg_id;
uint32_t netMode; /* EXT / UPNP / UDP / INVALID */
uint32_t visState; /* STD, GRAY, DARK */
uint32_t netMode; /* EXT / UPNP / UDP / HIDDEN / INVALID */
/* visState */
uint16_t vs_disc;
uint16_t vs_dht;
struct sockaddr_in localaddr;
struct sockaddr_in serveraddr;
struct sockaddr_storage localaddr;
struct sockaddr_storage serveraddr;
std::string dyndns;
time_t lastcontact;
@ -99,6 +87,10 @@ class peerState
/* list of addresses from various sources */
pqiIpAddrSet ipAddrs;
bool hiddenNode; /* all IP addresses / dyndns must be blank */
std::string hiddenDomain;
uint16_t hiddenPort;
std::string location;
std::string name;
@ -123,7 +115,8 @@ class p3PeerMgr
virtual ~p3PeerMgr() { return; }
virtual bool addFriend(const std::string &ssl_id, const std::string &gpg_id, uint32_t netMode = RS_NET_MODE_UDP,
uint32_t visState = RS_VIS_STATE_STD , time_t lastContact = 0,ServicePermissionFlags = ServicePermissionFlags(RS_SERVICE_PERM_ALL)) = 0;
uint16_t vsDisc = RS_VS_DISC_FULL, uint16_t vsDht = RS_VS_DHT_FULL,
time_t lastContact = 0,ServicePermissionFlags = ServicePermissionFlags(RS_SERVICE_PERM_ALL)) = 0;
virtual bool removeFriend(const std::string &ssl_id, bool removePgpId) = 0;
virtual bool isFriend(const std::string &ssl_id) = 0;
@ -154,14 +147,15 @@ virtual bool assignPeersToGroup(const std::string &groupId, const std::list<s
* 3) p3disc - reasonable
*/
virtual bool setLocalAddress(const std::string &id, struct sockaddr_in addr) = 0;
virtual bool setExtAddress(const std::string &id, struct sockaddr_in addr) = 0;
virtual bool setLocalAddress(const std::string &id, const struct sockaddr_storage &addr) = 0;
virtual bool setExtAddress(const std::string &id, const struct sockaddr_storage &addr) = 0;
virtual bool setDynDNS(const std::string &id, const std::string &dyndns) = 0;
virtual bool setNetworkMode(const std::string &id, uint32_t netMode) = 0;
virtual bool setVisState(const std::string &id, uint32_t visState) = 0;
virtual bool setVisState(const std::string &id, uint16_t vs_disc, uint16_t vs_dht) = 0;
virtual bool setLocation(const std::string &pid, const std::string &location) = 0;
virtual bool setHiddenDomainPort(const std::string &id, const std::string &domain_addr, const uint16_t domain_port) = 0;
virtual bool updateCurrentAddress(const std::string& id, const pqiIpAddress &addr) = 0;
virtual bool updateLastContact(const std::string& id) = 0;
@ -169,7 +163,7 @@ virtual bool updateAddressList(const std::string& id, const pqiIpAddrSet &add
// THIS MUST ONLY BE CALLED BY NETMGR!!!!
virtual bool UpdateOwnAddress(const struct sockaddr_in &mLocalAddr, const struct sockaddr_in &mExtAddr) = 0;
virtual bool UpdateOwnAddress(const struct sockaddr_storage &local_addr, const struct sockaddr_storage &ext_addr) = 0;
/**************** Net Status Info ****************/
/*
@ -188,6 +182,13 @@ virtual bool getPeerName(const std::string &ssl_id, std::string &name) = 0;
virtual bool getGpgId(const std::string &sslId, std::string &gpgId) = 0;
virtual uint32_t getConnectionType(const std::string &sslId) = 0;
virtual bool setProxyServerAddress(const struct sockaddr_storage &proxy_addr) = 0;
virtual bool getProxyServerAddress(struct sockaddr_storage &proxy_addr) = 0;
virtual bool isHidden() = 0;
virtual bool isHiddenPeer(const std::string &ssl_id) = 0;
virtual bool getProxyAddress(const std::string &ssl_id, struct sockaddr_storage &proxy_addr, std::string &domain_addr, uint16_t &domain_port) = 0;
virtual int getFriendCount(bool ssl, bool online) = 0;
/************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/
@ -214,7 +215,8 @@ class p3PeerMgrIMPL: public p3PeerMgr, public p3Config
/************************************************************************************************/
virtual bool addFriend(const std::string &ssl_id, const std::string &gpg_id, uint32_t netMode = RS_NET_MODE_UDP,
uint32_t visState = RS_VIS_STATE_STD , time_t lastContact = 0,ServicePermissionFlags = ServicePermissionFlags(RS_SERVICE_PERM_ALL));
uint16_t vsDisc = RS_VS_DISC_FULL, uint16_t vsDht = RS_VS_DHT_FULL,
time_t lastContact = 0,ServicePermissionFlags = ServicePermissionFlags(RS_SERVICE_PERM_ALL));
virtual bool removeFriend(const std::string &ssl_id, bool removePgpId);
virtual bool isFriend(const std::string &ssl_id);
@ -245,22 +247,23 @@ virtual bool assignPeersToGroup(const std::string &groupId, const std::list<s
* 3) p3disc - reasonable
*/
virtual bool setLocalAddress(const std::string &id, struct sockaddr_in addr);
virtual bool setExtAddress(const std::string &id, struct sockaddr_in addr);
virtual bool setLocalAddress(const std::string &id, const struct sockaddr_storage &addr);
virtual bool setExtAddress(const std::string &id, const struct sockaddr_storage &addr);
virtual bool setDynDNS(const std::string &id, const std::string &dyndns);
virtual bool setNetworkMode(const std::string &id, uint32_t netMode);
virtual bool setVisState(const std::string &id, uint32_t visState);
virtual bool setVisState(const std::string &id, uint16_t vs_disc, uint16_t vs_dht);
virtual bool setLocation(const std::string &pid, const std::string &location);
virtual bool setHiddenDomainPort(const std::string &id, const std::string &domain_addr, const uint16_t domain_port);
virtual bool updateCurrentAddress(const std::string& id, const pqiIpAddress &addr);
virtual bool updateLastContact(const std::string& id);
virtual bool updateAddressList(const std::string& id, const pqiIpAddrSet &addrs);
// THIS MUST ONLY BE CALLED BY NETMGR!!!!
virtual bool UpdateOwnAddress(const struct sockaddr_in &mLocalAddr, const struct sockaddr_in &mExtAddr);
virtual bool UpdateOwnAddress(const struct sockaddr_storage &local_addr, const struct sockaddr_storage &ext_addr);
/**************** Net Status Info ****************/
/*
* MUST RATIONALISE THE DATA FROM THESE FUNCTIONS
@ -278,6 +281,12 @@ virtual bool getPeerName(const std::string &ssl_id, std::string &name);
virtual bool getGpgId(const std::string &sslId, std::string &gpgId);
virtual uint32_t getConnectionType(const std::string &sslId);
virtual bool setProxyServerAddress(const struct sockaddr_storage &proxy_addr);
virtual bool getProxyServerAddress(struct sockaddr_storage &proxy_addr);
virtual bool isHidden();
virtual bool isHiddenPeer(const std::string &ssl_id);
virtual bool getProxyAddress(const std::string &ssl_id, struct sockaddr_storage &proxy_addr, std::string &domain_addr, uint16_t &domain_port);
virtual int getFriendCount(bool ssl, bool online);
/************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/
@ -297,14 +306,17 @@ virtual bool haveOnceConnected();
void setManagers(p3LinkMgrIMPL *linkMgr, p3NetMgrIMPL *netMgr);
bool forceHiddenNode();
bool setupHiddenNode(const std::string &hiddenAddress, const uint16_t hiddenPort);
void tick();
const std::string getOwnId();
bool setOwnNetworkMode(uint32_t netMode);
bool setOwnVisState(uint32_t visState);
bool setOwnVisState(uint16_t vs_disc, uint16_t vs_dht);
int getConnectAddresses(const std::string &id,
struct sockaddr_in &lAddr, struct sockaddr_in &eAddr,
struct sockaddr_storage &lAddr, struct sockaddr_storage &eAddr,
pqiIpAddrSet &histAddrs, std::string &dyndns);
@ -349,6 +361,8 @@ private:
std::list<RsItem *> saveCleanupList; /* TEMPORARY LIST WHEN SAVING */
std::map<std::string, ServicePermissionFlags> mFriendsPermissionFlags ; // permission flags for each gpg key
struct sockaddr_storage mProxyServerAddress;
};
#endif // MRK_PQI_PEER_MANAGER_HEADER

View file

@ -50,8 +50,8 @@ virtual void setInternalPort(unsigned short iport_in) = 0;
virtual void setExternalPort(unsigned short eport_in) = 0;
/* as determined by uPnP */
virtual bool getInternalAddress(struct sockaddr_in &addr) = 0;
virtual bool getExternalAddress(struct sockaddr_in &addr) = 0;
virtual bool getInternalAddress(struct sockaddr_storage &addr) = 0;
virtual bool getExternalAddress(struct sockaddr_storage &addr) = 0;
};

View file

@ -34,7 +34,6 @@
#include "pqi/pqi_base.h"
#include "pqi/pqinetwork.h"
#include "serialiser/rsserial.h"
#include "serialiser/rsbaseitems.h"
#include <iostream>
#include <functional>
@ -49,41 +48,7 @@ class SearchInterface
public:
SearchInterface() { return; }
virtual ~SearchInterface() { return; }
// Cache Requests
virtual int SearchSpecific(RsCacheRequest *) = 0;
virtual RsCacheRequest *RequestedSearch() = 0;
// Cache Results
virtual int SendSearchResult(RsCacheItem *item) = 0;
virtual RsCacheItem *GetSearchResult() = 0;
// FileTransfer.
virtual RsFileRequest *GetFileRequest() = 0;
virtual int SendFileRequest(RsFileRequest *) = 0;
virtual RsFileData *GetFileData() = 0;
virtual int SendFileData(RsFileData *) = 0;
virtual RsFileChunkMapRequest *GetFileChunkMapRequest() = 0;
virtual int SendFileChunkMapRequest(RsFileChunkMapRequest *) = 0;
virtual RsFileChunkMap *GetFileChunkMap() = 0;
virtual int SendFileChunkMap(RsFileChunkMap *) = 0;
virtual RsFileCRC32MapRequest *GetFileCRC32MapRequest() = 0;
virtual int SendFileCRC32MapRequest(RsFileCRC32MapRequest *) = 0;
virtual RsFileCRC32Map *GetFileCRC32Map() = 0;
virtual int SendFileCRC32Map(RsFileCRC32Map *) = 0;
virtual RsFileSingleChunkCrcRequest *GetFileSingleChunkCrcRequest()=0;
virtual int SendFileSingleChunkCrcRequest(RsFileSingleChunkCrcRequest *ns)=0;
virtual RsFileSingleChunkCrc *GetFileSingleChunkCrc()=0;
virtual int SendFileSingleChunkCrc(RsFileSingleChunkCrc *ns)=0;
virtual ~SearchInterface() { return; }
};
class P3Interface: public SearchInterface
@ -100,5 +65,20 @@ virtual RsRawItem *GetRsRawItem() = 0;
};
/* interface to allow outgoing messages to be sent directly
* through to the pqiperson, rather than being queued
*/
class pqiPublisher
{
public:
virtual ~pqiPublisher() { return; }
virtual bool sendItem(RsRawItem *item) = 0;
};
#endif // PQI_TOP_HEADER

View file

@ -41,7 +41,7 @@
#include "serialiser/rsserial.h"
#define PQI_MIN_PORT 1024
#define PQI_MIN_PORT 10 // TO ALLOW USERS TO HAVE PORT 80! - was 1024
#define PQI_MAX_PORT 65535
#define PQI_DEFAULT_PORT 7812
@ -214,6 +214,7 @@ class PQInterface: public RateInterface
* Retrieve RsItem from a facility
*/
virtual RsItem *GetItem() = 0;
virtual bool RecvItem(RsItem * /*item*/ ) { return false; } /* alternative for for GetItem(), when we want to push */
/**
* also there are tick + person id functions.
@ -223,10 +224,11 @@ class PQInterface: public RateInterface
virtual std::string PeerId() { return peerId; }
// the callback from NetInterface Connection Events.
virtual int notifyEvent(NetInterface *ni, int event)
virtual int notifyEvent(NetInterface *ni, int event, const struct sockaddr_storage &remote_peer_address)
{
(void) ni; /* remove unused parameter warnings */
(void) event; /* remove unused parameter warnings */
(void) remote_peer_address;
return 0;
}
@ -241,7 +243,7 @@ class PQInterface: public RateInterface
const uint32_t PQI_CONNECT_TCP = 0x0001;
const uint32_t PQI_CONNECT_UDP = 0x0002;
const uint32_t PQI_CONNECT_TUNNEL = 0x0003;
const uint32_t PQI_CONNECT_HIDDEN_TCP = 0x0004;
#define BIN_FLAGS_NO_CLOSE 0x0001
@ -282,11 +284,13 @@ virtual int readdata(void *data, int len) = 0;
/**
* Is more particular the case of the sending data through a socket (internet)
* moretoread and candsend, take a microsec timeout argument.
*
*/
virtual int netstatus() = 0;
virtual int isactive() = 0;
virtual bool moretoread() = 0;
virtual bool cansend() = 0;
virtual bool moretoread(uint32_t usec) = 0;
virtual bool cansend(uint32_t usec) = 0;
/**
* method for streamer to shutdown bininterface
@ -326,6 +330,9 @@ static const uint32_t NET_PARAM_CONNECT_BANDWIDTH = 5;
static const uint32_t NET_PARAM_CONNECT_PROXY = 6;
static const uint32_t NET_PARAM_CONNECT_SOURCE = 7;
static const uint32_t NET_PARAM_CONNECT_DOMAIN_ADDRESS = 8;
static const uint32_t NET_PARAM_CONNECT_REMOTE_PORT = 9;
/*!
* ******************** Network INTERFACE ***************************
@ -352,16 +359,17 @@ public:
virtual ~NetInterface()
{ return; }
virtual int connect(struct sockaddr_in raddr) = 0;
virtual int connect(const struct sockaddr_storage &raddr) = 0;
virtual int listen() = 0;
virtual int stoplistening() = 0;
virtual int disconnect() = 0;
virtual int reset() = 0;
virtual std::string PeerId() { return peerId; }
virtual int getConnectAddress(struct sockaddr_in &raddr) = 0;
virtual int getConnectAddress(struct sockaddr_storage &raddr) = 0;
virtual bool connect_parameter(uint32_t type, uint32_t value) = 0;
virtual bool connect_additional_address(uint32_t /*type*/, struct sockaddr_in */*addr*/) { return false; } // only needed by udp.
virtual bool connect_parameter(uint32_t /* type */ , const std::string & /* value */ ) { return false; } // not generally used.
virtual bool connect_additional_address(uint32_t /*type*/, const struct sockaddr_storage & /*addr*/) { return false; } // only needed by udp.
protected:
PQInterface *parent() { return p; }

View file

@ -239,7 +239,7 @@ int pqiarchive::writePkt(RsItem *pqi)
}
if (!(bio->cansend()))
if (!(bio->cansend(0)))
{
std::string out = "pqiarchive::writePkt() BIO cannot write!\nDiscarding:\n";
pqi -> print_string(out);
@ -321,7 +321,7 @@ int pqiarchive::readPkt(RsItem **item_out, long *ts_out)
{
pqioutput(PQL_DEBUG_ALL, pqiarchivezone, "pqiarchive::readPkt()");
if ((!(bio->isactive())) || (!(bio->moretoread())))
if ((!(bio->isactive())) || (!(bio->moretoread(0))))
{
return 0;
}

View file

@ -74,8 +74,8 @@ class PortForwardParams
uint32_t fwdId;
uint32_t status;
uint32_t typeFlags;
struct sockaddr_in intAddr;
struct sockaddr_in extaddr;
struct sockaddr_storage intAddr;
struct sockaddr_storage extaddr;
};
class pqiNetAssistFirewall: public pqiNetAssist
@ -89,8 +89,8 @@ virtual void setInternalPort(unsigned short iport_in) = 0;
virtual void setExternalPort(unsigned short eport_in) = 0;
/* as determined by uPnP */
virtual bool getInternalAddress(struct sockaddr_in &addr) = 0;
virtual bool getExternalAddress(struct sockaddr_in &addr) = 0;
virtual bool getInternalAddress(struct sockaddr_storage &addr) = 0;
virtual bool getExternalAddress(struct sockaddr_storage &addr) = 0;
/* New Port Forward interface to support as many ports as necessary */
@ -109,7 +109,7 @@ class pqiNetAssistPeerShare
public:
/* share Addresses for various reasons (bad peers, etc) */
virtual void updatePeer(std::string id, struct sockaddr_in addr, int type, int reason, int age) = 0;
virtual void updatePeer(std::string id, const struct sockaddr_storage &addr, int type, int reason, int age) = 0;
};
@ -126,7 +126,7 @@ class pqiAddrAssist
pqiAddrAssist() { return; }
virtual ~pqiAddrAssist() { return; }
virtual bool getExternalAddr(struct sockaddr_in &remote, uint8_t &stable) = 0;
virtual bool getExternalAddr(struct sockaddr_storage &remote, uint8_t &stable) = 0;
virtual void setRefreshPeriod(int32_t period) = 0;
virtual int tick() = 0; /* for internal accounting */
@ -163,14 +163,14 @@ virtual bool findPeer(std::string id) = 0;
virtual bool dropPeer(std::string id) = 0;
/* add non-active peers (can still toggle active/non-active via above) */
virtual int addBadPeer(const struct sockaddr_in &addr, uint32_t reason, uint32_t flags, uint32_t age) = 0;
virtual int addKnownPeer(const std::string &pid, const struct sockaddr_in &addr, uint32_t flags) = 0;
virtual int addBadPeer(const struct sockaddr_storage &addr, uint32_t reason, uint32_t flags, uint32_t age) = 0;
virtual int addKnownPeer(const std::string &pid, const struct sockaddr_storage &addr, uint32_t flags) = 0;
virtual void ConnectionFeedback(std::string pid, int mode) = 0;
/* extract current peer status */
virtual bool getPeerStatus(std::string id,
struct sockaddr_in &laddr, struct sockaddr_in &raddr,
struct sockaddr_storage &laddr, struct sockaddr_storage &raddr,
uint32_t &type, uint32_t &mode) = 0; // DEPRECIATE.
virtual bool setAttachMode(bool on) = 0; // FIXUP.

View file

@ -302,7 +302,7 @@ uint64_t BinEncryptedFileInterface::bytecount()
return cpyCount;
}
bool BinEncryptedFileInterface::moretoread()
bool BinEncryptedFileInterface::moretoread(uint32_t /* usec */)
{
if(haveData)
return (cpyCount < sizeData);
@ -500,6 +500,10 @@ void printNetBinID(std::ostream &out, std::string id, uint32_t t)
{
out << "TCP)";
}
else if (t == PQI_CONNECT_HIDDEN_TCP)
{
out << "HTCP";
}
else
{
out << "UDP)";
@ -524,11 +528,10 @@ NetBinDummy::NetBinDummy(PQInterface *parent, std::string id, uint32_t t)
}
// Net Interface
int NetBinDummy::connect(struct sockaddr_in raddr)
int NetBinDummy::connect(const struct sockaddr_storage &raddr)
{
std::cerr << "NetBinDummy::connect(";
std::cerr << rs_inet_ntoa(raddr.sin_addr) << ":";
std::cerr << htons(raddr.sin_port);
std::cerr << sockaddr_storage_tostring(raddr);
std::cerr << ") ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
@ -542,7 +545,8 @@ int NetBinDummy::connect(struct sockaddr_in raddr)
std::cerr << std::endl;
if (parent())
{
parent()->notifyEvent(this, CONNECT_FAILED);
struct sockaddr_storage addr = raddr;
parent()->notifyEvent(this, CONNECT_FAILED, raddr);
}
}
else if (!dummyConnected)
@ -592,7 +596,10 @@ int NetBinDummy::disconnect()
if (parent())
{
parent()->notifyEvent(this, CONNECT_FAILED);
struct sockaddr_storage addr;
sockaddr_storage_clear(addr);
parent()->notifyEvent(this, CONNECT_FAILED, addr);
}
return 1;
@ -624,7 +631,12 @@ int NetBinDummy::tick()
dummyConnected = true;
toConnect = false;
if (parent())
parent()->notifyEvent(this, CONNECT_SUCCESS);
{
struct sockaddr_storage addr;
sockaddr_storage_clear(addr);
parent()->notifyEvent(this, CONNECT_SUCCESS, addr);
}
}
else
{
@ -678,7 +690,7 @@ int NetBinDummy::isactive()
return dummyConnected;
}
bool NetBinDummy::moretoread()
bool NetBinDummy::moretoread(uint32_t /* usec */)
{
std::cerr << "NetBinDummy::moretoread() ";
printNetBinID(std::cerr, PeerId(), type);
@ -687,7 +699,7 @@ bool NetBinDummy::moretoread()
return false;
}
bool NetBinDummy::cansend()
bool NetBinDummy::cansend(uint32_t /* usec */)
{
std::cerr << "NetBinDummy::cansend() ";
printNetBinID(std::cerr, PeerId(), type);

View file

@ -52,7 +52,7 @@ virtual int senddata(void *data, int len);
virtual int readdata(void *data, int len);
virtual int netstatus() { return 1;}
virtual int isactive() { return (buf != NULL);}
virtual bool moretoread()
virtual bool moretoread(uint32_t /* usec */ )
{
if ((buf) && (bin_flags | BIN_FLAGS_READABLE))
{
@ -65,7 +65,10 @@ virtual bool moretoread()
}
virtual int close();
virtual bool cansend() { return (bin_flags | BIN_FLAGS_WRITEABLE); }
virtual bool cansend(uint32_t /* usec */)
{
return (bin_flags | BIN_FLAGS_WRITEABLE);
}
virtual bool bandwidthLimited() { return false; }
//! if HASHing is switched on
@ -118,7 +121,7 @@ public:
int close();
uint64_t bytecount();
bool moretoread();
bool moretoread(uint32_t usec);
private:
@ -156,7 +159,7 @@ virtual int senddata(void *data, int len);
virtual int readdata(void *data, int len);
virtual int netstatus() { return 1; }
virtual int isactive() { return 1; }
virtual bool moretoread()
virtual bool moretoread(uint32_t /* usec */)
{
if ((buf) && (bin_flags | BIN_FLAGS_READABLE ))
{
@ -169,7 +172,10 @@ virtual bool moretoread()
}
virtual int close();
virtual bool cansend() { return (bin_flags | BIN_FLAGS_WRITEABLE); }
virtual bool cansend(uint32_t /* usec */)
{
return (bin_flags | BIN_FLAGS_WRITEABLE);
}
virtual bool bandwidthLimited() { return false; }
virtual std::string gethash();
@ -193,7 +199,7 @@ public:
virtual ~NetBinDummy() { return; }
// Net Interface
virtual int connect(struct sockaddr_in raddr);
virtual int connect(const struct sockaddr_storage &raddr);
virtual int listen();
virtual int stoplistening();
virtual int disconnect();
@ -204,7 +210,7 @@ virtual bool connect_parameter(uint32_t type, uint32_t value)
(void) value; /* suppress unused parameter warning */
return false;
}
virtual int getConnectAddress(struct sockaddr_in &raddr)
virtual int getConnectAddress(struct sockaddr_storage &raddr)
{
(void) raddr; /* suppress unused parameter warning */
return 0;
@ -217,8 +223,8 @@ virtual int senddata(void *data, int len);
virtual int readdata(void *data, int len);
virtual int netstatus();
virtual int isactive();
virtual bool moretoread();
virtual bool cansend();
virtual bool moretoread(uint32_t usec);
virtual bool cansend(uint32_t usec);
virtual int close();
virtual std::string gethash();

View file

@ -287,50 +287,6 @@ int pqihandler::locked_HandleRsItem(RsItem *item, int allowglobal,uint32_t& comp
return 1;
}
int pqihandler::SearchSpecific(RsCacheRequest *ns)
{
return queueOutRsItem(ns) ;
}
int pqihandler::SendSearchResult(RsCacheItem *ns)
{
return queueOutRsItem(ns) ;
}
int pqihandler::SendFileRequest(RsFileRequest *ns)
{
return queueOutRsItem(ns) ;
}
int pqihandler::SendFileData(RsFileData *ns)
{
return queueOutRsItem(ns) ;
}
int pqihandler::SendFileChunkMapRequest(RsFileChunkMapRequest *ns)
{
return queueOutRsItem(ns) ;
}
int pqihandler::SendFileChunkMap(RsFileChunkMap *ns)
{
return queueOutRsItem(ns) ;
}
int pqihandler::SendFileCRC32MapRequest(RsFileCRC32MapRequest *ns)
{
return queueOutRsItem(ns) ;
}
int pqihandler::SendFileCRC32Map(RsFileCRC32Map *ns)
{
return queueOutRsItem(ns) ;
}
int pqihandler::SendFileSingleChunkCrcRequest(RsFileSingleChunkCrcRequest *ns)
{
return queueOutRsItem(ns) ;
}
int pqihandler::SendFileSingleChunkCrc(RsFileSingleChunkCrc *ns)
{
return queueOutRsItem(ns) ;
}
int pqihandler::SendRsRawItem(RsRawItem *ns)
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, "pqihandler::SendRsRawItem()");
@ -340,8 +296,6 @@ int pqihandler::SendRsRawItem(RsRawItem *ns)
return queueOutRsItem(ns) ;
}
// inputs. This is a very basic
// system that is completely biased and slow...
// someone please fix.
@ -410,9 +364,6 @@ void pqihandler::locked_SortnStoreItem(RsItem *item)
{
/* get class type / subtype out of the item */
uint8_t vers = item -> PacketVersion();
uint8_t cls = item -> PacketClass();
uint8_t type = item -> PacketType();
uint8_t subtype = item -> PacketSubType();
/* whole Version reserved for SERVICES/CACHES */
if (vers == RS_PKT_VERSION_SERVICE)
@ -423,257 +374,25 @@ void pqihandler::locked_SortnStoreItem(RsItem *item)
item = NULL;
return;
}
std::cerr << "pqihandler::locked_SortnStoreItem() : unhandled item! Will be deleted. This is certainly a bug." << std::endl;
if (vers != RS_PKT_VERSION1)
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"SortnStore -> Invalid VERSION! Deleting!");
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, "SortnStore -> Invalid VERSION! Deleting!");
delete item;
item = NULL;
return;
}
switch(cls)
{
case RS_PKT_CLASS_BASE:
switch(type)
{
case RS_PKT_TYPE_CACHE:
switch(subtype)
{
case RS_PKT_SUBTYPE_CACHE_REQUEST:
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"SortnStore -> Cache Request");
in_search.push_back(item);
item = NULL;
break;
case RS_PKT_SUBTYPE_CACHE_ITEM:
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"SortnStore -> Cache Result");
in_result.push_back(item);
item = NULL;
break;
default:
break; /* no match! */
}
break;
case RS_PKT_TYPE_FILE:
switch(subtype)
{
case RS_PKT_SUBTYPE_FI_REQUEST:
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"SortnStore -> File Request");
in_request.push_back(item);
item = NULL;
break;
case RS_PKT_SUBTYPE_FI_DATA:
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, "SortnStore -> File Data");
in_data.push_back(item);
item = NULL;
break;
case RS_PKT_SUBTYPE_FI_CHUNK_MAP_REQUEST:
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, "SortnStore -> File ChunkMap Request");
in_chunkmap_request.push_back(item);
item = NULL;
break;
case RS_PKT_SUBTYPE_FI_CHUNK_MAP:
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, "SortnStore -> File ChunkMap");
in_chunkmap.push_back(item);
item = NULL;
break;
case RS_PKT_SUBTYPE_FI_CRC32_MAP_REQUEST:
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, "SortnStore -> File Crc32Map Request");
in_crc32map_request.push_back(item);
item = NULL;
break;
case RS_PKT_SUBTYPE_FI_CRC32_MAP:
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, "SortnStore -> File CRC32Map");
in_crc32map.push_back(item);
item = NULL;
break;
case RS_PKT_SUBTYPE_FI_CHUNK_CRC_REQUEST:
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, "SortnStore -> File Crc Request");
in_singlechunkcrc_request.push_back(item);
item = NULL;
break;
case RS_PKT_SUBTYPE_FI_CHUNK_CRC:
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, "SortnStore -> File CRC32Map");
in_singlechunkcrc.push_back(item);
item = NULL;
break;
default:
break; /* no match! */
}
break;
default:
break; /* no match! */
}
break;
default:
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"SortnStore -> Unknown");
break;
}
if (item)
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"SortnStore -> Deleting Unsorted Item");
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, "SortnStore -> Deleting Unsorted Item");
delete item;
}
return;
}
// much like the input stuff.
RsCacheItem *pqihandler::GetSearchResult()
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (in_result.size() != 0)
{
RsCacheItem *fi = dynamic_cast<RsCacheItem *>(in_result.front());
if (!fi) { delete in_result.front(); }
in_result.pop_front();
return fi;
}
return NULL;
}
RsCacheRequest *pqihandler::RequestedSearch()
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (in_search.size() != 0)
{
RsCacheRequest *fi = dynamic_cast<RsCacheRequest *>(in_search.front());
if (!fi) { delete in_search.front(); }
in_search.pop_front();
return fi;
}
return NULL;
}
RsFileRequest *pqihandler::GetFileRequest()
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (in_request.size() != 0)
{
RsFileRequest *fi = dynamic_cast<RsFileRequest *>(in_request.front());
if (!fi) { delete in_request.front(); }
in_request.pop_front();
return fi;
}
return NULL;
}
RsFileData *pqihandler::GetFileData()
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (in_data.size() != 0)
{
RsFileData *fi = dynamic_cast<RsFileData *>(in_data.front());
if (!fi) { delete in_data.front(); }
in_data.pop_front();
return fi;
}
return NULL;
}
RsFileChunkMapRequest *pqihandler::GetFileChunkMapRequest()
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (in_chunkmap_request.size() != 0)
{
RsFileChunkMapRequest *fi = dynamic_cast<RsFileChunkMapRequest *>(in_chunkmap_request.front());
if (!fi) { delete in_chunkmap_request.front(); }
in_chunkmap_request.pop_front();
return fi;
}
return NULL;
}
RsFileChunkMap *pqihandler::GetFileChunkMap()
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (in_chunkmap.size() != 0)
{
RsFileChunkMap *fi = dynamic_cast<RsFileChunkMap *>(in_chunkmap.front());
if (!fi) { delete in_chunkmap.front(); }
in_chunkmap.pop_front();
return fi;
}
return NULL;
}
RsFileCRC32MapRequest *pqihandler::GetFileCRC32MapRequest()
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (in_crc32map_request.size() != 0)
{
RsFileCRC32MapRequest *fi = dynamic_cast<RsFileCRC32MapRequest *>(in_crc32map_request.front());
if (!fi) { delete in_crc32map_request.front(); }
in_crc32map_request.pop_front();
return fi;
}
return NULL;
}
RsFileCRC32Map *pqihandler::GetFileCRC32Map()
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (in_crc32map.size() != 0)
{
RsFileCRC32Map *fi = dynamic_cast<RsFileCRC32Map *>(in_crc32map.front());
if (!fi) { delete in_crc32map.front(); }
in_crc32map.pop_front();
return fi;
}
return NULL;
}
RsFileSingleChunkCrcRequest *pqihandler::GetFileSingleChunkCrcRequest()
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (in_singlechunkcrc_request.size() != 0)
{
RsFileSingleChunkCrcRequest *fi = dynamic_cast<RsFileSingleChunkCrcRequest *>(in_singlechunkcrc_request.front());
if (!fi) { delete in_singlechunkcrc_request.front(); }
in_singlechunkcrc_request.pop_front();
return fi;
}
return NULL;
}
RsFileSingleChunkCrc *pqihandler::GetFileSingleChunkCrc()
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (in_singlechunkcrc.size() != 0)
{
RsFileSingleChunkCrc *fi = dynamic_cast<RsFileSingleChunkCrc *>(in_singlechunkcrc.front());
if (!fi) { delete in_singlechunkcrc.front(); }
in_singlechunkcrc.pop_front();
return fi;
}
return NULL;
}
RsRawItem *pqihandler::GetRsRawItem()
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/

View file

@ -46,39 +46,20 @@ class SearchModule
// Presents a P3 Face to the world!
// and funnels data through to a PQInterface.
//
class pqihandler: public P3Interface
class pqihandler: public P3Interface, public pqiPublisher
{
public:
pqihandler(SecurityPolicy *Global);
/**** Overloaded from pqiPublisher ****/
virtual bool sendItem(RsRawItem *item)
{
return SendRsRawItem(item);
}
bool AddSearchModule(SearchModule *mod);
bool RemoveSearchModule(SearchModule *mod);
// P3Interface.
virtual int SearchSpecific(RsCacheRequest *ns);
virtual int SendSearchResult(RsCacheItem *);
// inputs.
virtual RsCacheRequest * RequestedSearch();
virtual RsCacheItem * GetSearchResult();
// file i/o
virtual int SendFileRequest(RsFileRequest *ns);
virtual int SendFileData(RsFileData *ns);
virtual int SendFileChunkMapRequest(RsFileChunkMapRequest *ns);
virtual int SendFileChunkMap(RsFileChunkMap *ns);
virtual int SendFileCRC32MapRequest(RsFileCRC32MapRequest *ns);
virtual int SendFileCRC32Map(RsFileCRC32Map *ns);
virtual int SendFileSingleChunkCrcRequest(RsFileSingleChunkCrcRequest *ns);
virtual int SendFileSingleChunkCrc(RsFileSingleChunkCrc *ns);
virtual RsFileRequest *GetFileRequest();
virtual RsFileData *GetFileData();
virtual RsFileChunkMapRequest *GetFileChunkMapRequest();
virtual RsFileChunkMap *GetFileChunkMap();
virtual RsFileCRC32MapRequest *GetFileCRC32MapRequest();
virtual RsFileCRC32Map *GetFileCRC32Map();
virtual RsFileSingleChunkCrcRequest *GetFileSingleChunkCrcRequest();
virtual RsFileSingleChunkCrc *GetFileSingleChunkCrc();
// Rest of P3Interface
virtual int tick();
virtual int status();
@ -113,8 +94,7 @@ class pqihandler: public P3Interface
std::map<std::string, SearchModule *> mods;
SecurityPolicy *globsec;
// Temporary storage...
std::list<RsItem *> in_result, in_search, in_request, in_data, in_service,in_chunkmap,in_chunkmap_request,in_crc32map_request,in_crc32map,in_singlechunkcrc,in_singlechunkcrc_request;
std::list<RsItem *> in_service;
private:

View file

@ -29,6 +29,7 @@
#include <openssl/sha.h>
#include <string>
#include <iomanip>
#include <string.h>
#include "util/rsstring.h"
#include "retroshare/rstypes.h"
#include <inttypes.h>

View file

@ -29,15 +29,14 @@
bool pqiIpAddress::sameAddress(const pqiIpAddress &a) const
{
return ((mAddr.sin_addr.s_addr == a.mAddr.sin_addr.s_addr) &&
(mAddr.sin_port == a.mAddr.sin_port));
return sockaddr_storage_same(mAddr, a.mAddr);
}
bool pqiIpAddress::validAddress() const
{
/* filter for unlikely addresses */
if(isLoopbackNet(&(mAddr.sin_addr)))
if(sockaddr_storage_isLoopbackNet(mAddr))
{
#ifdef IPADDR_DEBUG
std::cerr << "pqiIpAddress::validAddress() ip parameter is loopback: disgarding." << std::endl ;
@ -45,7 +44,7 @@ bool pqiIpAddress::validAddress() const
return false;
}
if(mAddr.sin_addr.s_addr == 0 || mAddr.sin_addr.s_addr == 1 || mAddr.sin_port == 0)
if(sockaddr_storage_isnull(mAddr))
{
#ifdef IPADDR_DEBUG
std::cerr << "pqiIpAddress::validAddress() ip parameter is 0.0.0.0/1, or port is 0, ignoring." << std::endl;
@ -168,7 +167,7 @@ void pqiIpAddrList::extractFromTlv(const RsTlvIpAddrSet &tlvAddrs)
for(it = tlvAddrs.addrs.begin(); it != tlvAddrs.addrs.end() ; ++it)
{
pqiIpAddress addr;
addr.mAddr = it->addr;
addr.mAddr = it->addr.addr;
addr.mSeenTime = it->seenTime;
addr.mSrc = it->source;
@ -176,14 +175,14 @@ void pqiIpAddrList::extractFromTlv(const RsTlvIpAddrSet &tlvAddrs)
}
}
void pqiIpAddrList::loadTlv(RsTlvIpAddrSet &tlvAddrs)
void pqiIpAddrList::loadTlv(RsTlvIpAddrSet &tlvAddrs) const
{
std::list<pqiIpAddress>::iterator it;
std::list<pqiIpAddress>::const_iterator it;
for(it = mAddrs.begin(); it != mAddrs.end() ; ++it)
{
RsTlvIpAddressInfo addr;
addr.addr = it->mAddr;
addr.addr.addr = it->mAddr;
addr.seenTime = it->mSeenTime;
addr.source = it->mSrc;
@ -199,7 +198,8 @@ void pqiIpAddrList::printIpAddressList(std::string &out) const
time_t now = time(NULL);
for(it = mAddrs.begin(); it != mAddrs.end(); it++)
{
rs_sprintf_append(out, "%s:%u ( %ld old)\n", rs_inet_ntoa(it->mAddr.sin_addr).c_str(), ntohs(it->mAddr.sin_port), now - it->mSeenTime);
out += sockaddr_storage_tostring(it->mAddr);
rs_sprintf_append(out, "( %ld old)\n", now - it->mSeenTime);
}
return;
}

View file

@ -37,7 +37,7 @@ class pqiIpAddress
bool sameAddress(const pqiIpAddress &a) const;
bool validAddress() const;
struct sockaddr_in mAddr;
struct sockaddr_storage mAddr;
time_t mSeenTime;
uint32_t mSrc;
};
@ -51,7 +51,7 @@ class pqiIpAddrList
bool updateIpAddressList(const pqiIpAddress &addr);
void printIpAddressList(std::string &out) const;
void extractFromTlv(const RsTlvIpAddrSet &tlvAddrs);
void loadTlv(RsTlvIpAddrSet &tlvAddrs);
void loadTlv(RsTlvIpAddrSet &tlvAddrs) const;
// sorted list... based on seen time.
std::list<pqiIpAddress> mAddrs;

View file

@ -38,7 +38,7 @@ virtual ~pqilistener() { return; }
virtual int tick() { return 1; }
virtual int status() { return 1; }
virtual int setListenAddr(struct sockaddr_in addr)
virtual int setListenAddr(const struct sockaddr_storage &addr)
{
(void) addr; /* suppress unused parameter warning */
return 1;

View file

@ -62,23 +62,21 @@ void pqiConnectCbDummy::peerStatus(std::string id, const pqiIpAddrSet &addrs,
}
void pqiConnectCbDummy::peerConnectRequest(std::string id,
struct sockaddr_in raddr, uint32_t source)
const struct sockaddr_storage &raddr, uint32_t source)
{
std::cerr << "pqiConnectCbDummy::peerConnectRequest()";
std::cerr << " id: " << id;
std::cerr << " raddr: " << rs_inet_ntoa(raddr.sin_addr);
std::cerr << ":" << ntohs(raddr.sin_port);
std::cerr << " raddr: " << sockaddr_storage_tostring(raddr);
std::cerr << " source: " << source;
std::cerr << std::endl;
}
#if 0
void pqiConnectCbDummy::stunStatus(std::string id, struct sockaddr_in raddr,
void pqiConnectCbDummy::stunStatus(std::string id, const struct sockaddr_storage *raddr,
uint32_t type, uint32_t flags)
{
std::cerr << "pqiConnectCbDummy::stunStatus()";
std::cerr << " idhash: " << RsUtil::BinToHex(id) << " raddr: " << rs_inet_ntoa(raddr.sin_addr);
std::cerr << ":" << ntohs(raddr.sin_port);
std::cerr << " idhash: " << RsUtil::BinToHex(id) << " raddr: " << sockaddr_storage_tostring(raddr);
std::cerr << " type: " << type;
std::cerr << " flags: " << flags;
std::cerr << std::endl;

View file

@ -156,11 +156,11 @@ virtual ~pqiConnectCb() { return; }
virtual void peerStatus(std::string id, const pqiIpAddrSet &addrs,
uint32_t type, uint32_t flags, uint32_t source) = 0;
virtual void peerConnectRequest(std::string id, struct sockaddr_in raddr,
struct sockaddr_in proxyaddr, struct sockaddr_in srcaddr,
virtual void peerConnectRequest(std::string id, const struct sockaddr_storage &raddr,
const struct sockaddr_storage &proxyaddr, const struct sockaddr_storage &srcaddr,
uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth) = 0;
//virtual void stunStatus(std::string id, struct sockaddr_in raddr, uint32_t type, uint32_t flags) = 0;
//virtual void stunStatus(std::string id, const struct sockaddr_storage &raddr, uint32_t type, uint32_t flags) = 0;
};
@ -174,9 +174,9 @@ virtual void peerStatus(std::string id, const pqiIpAddrSet &addrs,
uint32_t type, uint32_t mode, uint32_t source);
virtual void peerConnectRequest(std::string id,
struct sockaddr_in raddr, uint32_t source);
const struct sockaddr_storage &raddr, uint32_t source);
//virtual void stunStatus(std::string id, struct sockaddr_in raddr, uint32_t type, uint32_t flags);
//virtual void stunStatus(std::string id, const struct sockaddr_storage &raddr, uint32_t type, uint32_t flags);
};
@ -184,7 +184,7 @@ virtual void peerConnectRequest(std::string id,
class pqiNetListener
{
public:
virtual bool resetListener(struct sockaddr_in &local) = 0;
virtual bool resetListener(const struct sockaddr_storage &local) = 0;
};

View file

@ -6,15 +6,14 @@
// External Interface.
void pqiNetStateBox::setAddressStunDht(struct sockaddr_in *addr, bool stable)
void pqiNetStateBox::setAddressStunDht(const struct sockaddr_storage &addr, bool stable)
{
if ((!mStunDhtSet) || (mStunDhtStable != stable) ||
(addr->sin_addr.s_addr != mStunDhtAddr.sin_addr.s_addr) ||
(addr->sin_port != mStunDhtAddr.sin_port))
(!sockaddr_storage_same(addr, mStunDhtAddr)))
{
mStunDhtSet = true;
mStunDhtStable = stable;
mStunDhtAddr = *addr;
mStunDhtAddr = addr;
mStatusOkay = false;
}
@ -22,15 +21,13 @@ void pqiNetStateBox::setAddressStunDht(struct sockaddr_in *addr, bool stable)
}
void pqiNetStateBox::setAddressStunProxy(struct sockaddr_in *addr, bool stable)
void pqiNetStateBox::setAddressStunProxy(const struct sockaddr_storage &addr, bool stable)
{
if ((!mStunProxySet) || (mStunProxyStable != stable) ||
(addr->sin_addr.s_addr != mStunProxyAddr.sin_addr.s_addr) ||
(addr->sin_port != mStunProxyAddr.sin_port))
(!sockaddr_storage_same(addr, mStunProxyAddr)))
{
if (addr->sin_addr.s_addr == mStunProxyAddr.sin_addr.s_addr)
if (sockaddr_storage_sameip(addr,mStunProxyAddr))
{
if (mStunProxyStable != stable)
{
@ -44,22 +41,20 @@ void pqiNetStateBox::setAddressStunProxy(struct sockaddr_in *addr, bool stable)
mStunProxySet = true;
mStunProxyStable = stable;
mStunProxyAddr = *addr;
mStunProxyAddr = addr;
mStatusOkay = false;
}
mStunProxyTS = time(NULL);
}
void pqiNetStateBox::setAddressUPnP(bool active, struct sockaddr_in *addr)
void pqiNetStateBox::setAddressUPnP(bool active, const struct sockaddr_storage &addr)
{
if ((!mUPnPSet) || (mUPnPActive != active) ||
(addr->sin_addr.s_addr != mUPnPAddr.sin_addr.s_addr) ||
(addr->sin_port != mUPnPAddr.sin_port))
(!sockaddr_storage_same(addr, mUPnPAddr)))
{
mUPnPSet = true;
mUPnPAddr = *addr;
mUPnPAddr = addr;
mUPnPActive = active;
mStatusOkay = false;
@ -68,15 +63,13 @@ void pqiNetStateBox::setAddressUPnP(bool active, struct sockaddr_in *addr)
}
void pqiNetStateBox::setAddressNatPMP(bool active, struct sockaddr_in *addr)
void pqiNetStateBox::setAddressNatPMP(bool active, const struct sockaddr_storage &addr)
{
if ((!mNatPMPSet) || (mNatPMPActive != active) ||
(addr->sin_addr.s_addr != mNatPMPAddr.sin_addr.s_addr) ||
(addr->sin_port != mNatPMPAddr.sin_port))
(!sockaddr_storage_same(addr, mNatPMPAddr)))
{
mNatPMPSet = true;
mNatPMPAddr = *addr;
mNatPMPAddr = addr;
mNatPMPActive = active;
mStatusOkay = false;
@ -86,15 +79,13 @@ void pqiNetStateBox::setAddressNatPMP(bool active, struct sockaddr_in *addr)
void pqiNetStateBox::setAddressWebIP(bool active, struct sockaddr_in *addr)
void pqiNetStateBox::setAddressWebIP(bool active, const struct sockaddr_storage &addr)
{
if ((!mWebIPSet) || (mWebIPActive != active) ||
(addr->sin_addr.s_addr != mWebIPAddr.sin_addr.s_addr) ||
(addr->sin_port != mWebIPAddr.sin_port))
(!sockaddr_storage_same(addr, mWebIPAddr)))
{
mWebIPSet = true;
mWebIPAddr = *addr;
mWebIPAddr = addr;
mWebIPActive = active;
mStatusOkay = false;
@ -188,35 +179,25 @@ void pqiNetStateBox::reset()
mStunDhtSet = false;
mStunDhtTS = 0;
mStunDhtStable = false;
mStunDhtAddr.sin_addr.s_addr = 0 ;
mStunDhtAddr.sin_port = 0 ;
//struct sockaddr_in mStunDhtAddr;
sockaddr_storage_clear(mStunDhtAddr);
mStunProxySet = false;
mStunProxySemiStable = false;
mStunProxyTS = 0;
mStunProxyStable = false;
mStunProxyAddr.sin_addr.s_addr = 0 ;
mStunProxyAddr.sin_port = 0 ;
//struct sockaddr_in mStunProxyAddr;
sockaddr_storage_clear(mStunProxyAddr);
mUPnPSet = false;
mUPnPActive = false;
mUPnPAddr.sin_addr.s_addr = 0 ;
mUPnPAddr.sin_port = 0 ;
//struct sockaddr_in mUPnPAddr;
sockaddr_storage_clear(mUPnPAddr);
mNatPMPSet = false;
mNatPMPActive = false;
mNatPMPAddr.sin_addr.s_addr = 0 ;
mNatPMPAddr.sin_port = 0 ;
//struct sockaddr_in mNatPMPAddr;
sockaddr_storage_clear(mNatPMPAddr);
mWebIPSet = false;
mWebIPActive = false;
mWebIPAddr.sin_addr.s_addr = 0 ;
mWebIPAddr.sin_port = 0 ;
//struct sockaddr_in mWebIPAddr;
sockaddr_storage_clear(mWebIPAddr);
mPortForwardSet = false;
mPortForwarded = false;

View file

@ -21,12 +21,12 @@ class pqiNetStateBox
void reset();
/* input network bits */
void setAddressStunDht(struct sockaddr_in *, bool stable);
void setAddressStunProxy(struct sockaddr_in *, bool stable);
void setAddressStunDht(const struct sockaddr_storage &addr, bool stable);
void setAddressStunProxy(const struct sockaddr_storage &addr, bool stable);
void setAddressUPnP(bool active, struct sockaddr_in *addr);
void setAddressNatPMP(bool active, struct sockaddr_in *addr);
void setAddressWebIP(bool active, struct sockaddr_in *addr);
void setAddressUPnP(bool active, const struct sockaddr_storage &addr);
void setAddressNatPMP(bool active, const struct sockaddr_storage &addr);
void setAddressWebIP(bool active, const struct sockaddr_storage &addr);
void setPortForwarded(bool active, uint16_t port);
@ -63,13 +63,13 @@ class pqiNetStateBox
bool mStunDhtSet;
time_t mStunDhtTS;
bool mStunDhtStable;
struct sockaddr_in mStunDhtAddr;
struct sockaddr_storage mStunDhtAddr;
bool mStunProxySet;
time_t mStunProxyTS;
bool mStunProxyStable;
bool mStunProxySemiStable;
struct sockaddr_in mStunProxyAddr;
struct sockaddr_storage mStunProxyAddr;
bool mDhtSet;
time_t mDhtTS;
@ -77,17 +77,17 @@ class pqiNetStateBox
bool mDhtActive;
bool mUPnPSet;
struct sockaddr_in mUPnPAddr;
struct sockaddr_storage mUPnPAddr;
bool mUPnPActive;
time_t mUPnPTS;
bool mNatPMPSet;
struct sockaddr_in mNatPMPAddr;
struct sockaddr_storage mNatPMPAddr;
bool mNatPMPActive;
time_t mNatPMPTS;
bool mWebIPSet;
struct sockaddr_in mWebIPAddr;
struct sockaddr_storage mWebIPAddr;
bool mWebIPActive;
time_t mWebIPTS;

View file

@ -147,7 +147,7 @@ std::string socket_errorType(int err)
#include <net/if.h>
#include <sys/ioctl.h>
bool getLocalInterfaces(struct in_addr &/*routeAddr*/, std::list<struct in_addr> &addrs)
bool getLocalInterfaces_ipv4(struct in_addr &/*routeAddr*/, std::list<struct in_addr> &addrs)
{
int sock = 0;
struct ifreq ifreq;
@ -328,7 +328,7 @@ std::string socket_errorType(int err)
// A function to determine the interfaces on your computer....
// No idea of how to do this in windows....
// see if it compiles.
bool getLocalInterfaces(struct in_addr &routeAddr, std::list<struct in_addr> &addrs)
bool getLocalInterfaces_ipv4(struct in_addr &routeAddr, std::list<struct in_addr> &addrs)
{
// Get the best interface for transport to routeAddr
// This interface should be first in list!
@ -560,8 +560,7 @@ int inaddr_cmp(struct sockaddr_in addr1, unsigned long addr2)
return 1;
}
bool getPreferredInterface(in_addr &routeAddr, struct in_addr &prefAddr) // returns best addr.
bool getPreferredInterface_ipv4(in_addr &routeAddr, struct in_addr &prefAddr) // returns best addr.
{
std::list<struct in_addr> addrs;
std::list<struct in_addr>::iterator it;
@ -576,7 +575,7 @@ bool getPreferredInterface(in_addr &routeAddr, struct in_addr &prefAddr) // ret
bool found_priv = false;
bool found_ext = false;
if (!getLocalInterfaces(routeAddr, addrs))
if (!getLocalInterfaces_ipv4(routeAddr, addrs))
{
return false;
}
@ -690,6 +689,78 @@ bool getPreferredInterface(in_addr &routeAddr, struct in_addr &prefAddr) // ret
return false;
}
bool getPreferredInterface(struct sockaddr_storage &existAddr, struct sockaddr_storage &prefAddr)
{
struct in_addr existing_addr;
struct in_addr pref_addr;
{
struct sockaddr_in *eaddr = (sockaddr_in *) &existAddr;
if (eaddr->sin_family != AF_INET)
{
std::cerr << "getPreferredInterface() ERROR only valid for IPv4 for now";
abort();
return false;
}
existing_addr = eaddr->sin_addr;
}
if (getPreferredInterface_ipv4(existing_addr, pref_addr))
{
/* store into prefAddr */
sockaddr_storage_clear(prefAddr);
struct sockaddr_in *addr = (sockaddr_in *) &prefAddr;
addr->sin_family = AF_INET;
addr->sin_addr = pref_addr;
addr->sin_port = htons(0);
return true;
}
return false;
}
bool getLocalInterfaces(struct sockaddr_storage &existAddr, std::list<struct sockaddr_storage> &addrs)
{
struct in_addr existing_addr;
std::list<struct in_addr> local_addrs;
{
struct sockaddr_in *eaddr = (sockaddr_in *) &existAddr;
if (eaddr->sin_family != AF_INET)
{
std::cerr << "getLocalInterfaces() ERROR only valid for IPv4 for now";
abort();
return false;
}
existing_addr = eaddr->sin_addr;
}
if (getLocalInterfaces_ipv4(existing_addr, local_addrs))
{
std::list<struct in_addr>::iterator it;
for(it = local_addrs.begin(); it != local_addrs.end(); it++)
{
/* store into prefAddr */
sockaddr_storage localAddr;
sockaddr_storage_clear(localAddr);
struct sockaddr_in *addr = (sockaddr_in *) &localAddr;
addr->sin_family = AF_INET;
addr->sin_addr = *it;
addr->sin_port = htons(0);
addrs.push_back(localAddr);
}
return true;
}
return false;
}
bool sameNet(const struct in_addr *addr, const struct in_addr *addr2)
{
#ifdef NET_DEBUG
@ -879,9 +950,34 @@ int unix_fcntl_nonblock(int fd)
}
int unix_connect(int fd, const struct sockaddr *serv_addr, socklen_t addrlen)
int unix_connect(int fd, const struct sockaddr *serv_addr, socklen_t socklen)
{
int ret = connect(fd, serv_addr, addrlen);
std::cerr << "unix_connect()";
std::cerr << std::endl;
const struct sockaddr_storage *ss_addr = (struct sockaddr_storage *) serv_addr;
socklen_t len = socklen;
switch (ss_addr->ss_family)
{
case AF_INET:
len = sizeof(struct sockaddr_in);
break;
case AF_INET6:
len = sizeof(struct sockaddr_in6);
break;
}
if (len > socklen)
{
std::cerr << "unix_connect() ERROR len > socklen";
std::cerr << std::endl;
len = socklen;
//return EINVAL;
}
int ret = connect(fd, serv_addr, len);
/******************* WINDOWS SPECIFIC PART ******************/
#ifdef WINDOWS_SYS // WINDOWS

View file

@ -45,13 +45,8 @@
#else
#include "util/rsnet.h" /* more generic networking header */
#include <winsock2.h>
typedef int socklen_t;
//typedef unsigned long in_addr_t;
// Some Network functions that are missing from windows.
in_addr_t inet_netof(struct in_addr addr);
@ -106,8 +101,8 @@ int sockaddr_cmp(struct sockaddr_in &addr1, struct sockaddr_in &addr2 );
int inaddr_cmp(struct sockaddr_in addr1, struct sockaddr_in addr2 );
int inaddr_cmp(struct sockaddr_in addr1, unsigned long);
bool getPreferredInterface(struct in_addr &routeAddr, struct in_addr &prefAddr); // returns best addr.
bool getLocalInterfaces(in_addr &routeAddr, std::list<struct in_addr> &addrs); // returns all possible addrs.
bool getPreferredInterface(struct sockaddr_storage &existAddr, struct sockaddr_storage &prefAddr); // returns best addr.
bool getLocalInterfaces(struct sockaddr_storage &existAddr, std::list<struct sockaddr_storage> &addrs); // returns all possible addrs.
// checks (addr1 & 255.255.255.0) == (addr2 & 255.255.255.0)
bool isSameSubnet(struct in_addr *addr1, struct in_addr *addr2);

View file

@ -27,7 +27,7 @@
#include "pqi/pqiperson.h"
#include "pqi/pqipersongrp.h"
#include "pqi/pqissl.h"
#include "services/p3disc.h"
const int pqipersonzone = 82371;
#include "util/rsdebug.h"
@ -35,11 +35,12 @@ const int pqipersonzone = 82371;
#include "retroshare/rspeers.h"
/****
* #define PERSON_DEBUG
* #define PERSON_DEBUG 1
****/
pqiperson::pqiperson(std::string id, pqipersongrp *pg)
:PQInterface(id), active(false), activepqi(NULL),
:PQInterface(id), mNotifyMtx("pqiperson-notify"), mPersonMtx("pqiperson"),
active(false), activepqi(NULL),
inConnectAttempt(false), waittimes(0),
pqipg(pg)
{
@ -51,6 +52,8 @@ pqiperson::pqiperson(std::string id, pqipersongrp *pg)
pqiperson::~pqiperson()
{
RsStackMutex stack(mPersonMtx); /**** LOCK MUTEX ****/
// clean up the children.
std::map<uint32_t, pqiconnect *>::iterator it;
for(it = kids.begin(); it != kids.end(); it++)
@ -65,6 +68,8 @@ pqiperson::~pqiperson()
// The PQInterface interface.
int pqiperson::SendItem(RsItem *i,uint32_t& serialized_size)
{
RsStackMutex stack(mPersonMtx); /**** LOCK MUTEX ****/
std::string out = "pqiperson::SendItem()";
if (active)
{
@ -87,14 +92,27 @@ int pqiperson::SendItem(RsItem *i,uint32_t& serialized_size)
RsItem *pqiperson::GetItem()
{
RsStackMutex stack(mPersonMtx); /**** LOCK MUTEX ****/
if (active)
return activepqi -> GetItem();
// else not possible.
return NULL;
}
bool pqiperson::RecvItem(RsItem *item)
{
std::cerr << "pqiperson::RecvItem()";
std::cerr << std::endl;
return pqipg->recvItem((RsRawItem *) item);
}
int pqiperson::status()
{
RsStackMutex stack(mPersonMtx); /**** LOCK MUTEX ****/
if (active)
return activepqi -> status();
return -1;
@ -102,6 +120,8 @@ int pqiperson::status()
int pqiperson::receiveHeartbeat()
{
RsStackMutex stack(mPersonMtx); /**** LOCK MUTEX ****/
pqioutput(PQL_WARNING, pqipersonzone, "pqiperson::receiveHeartbeat() from peer : " + PeerId());
lastHeartbeatReceived = time(NULL);
@ -111,61 +131,68 @@ int pqiperson::receiveHeartbeat()
// tick......
int pqiperson::tick()
{
//if lastHeartbeatReceived is 0, it might be not activated so don't do a net reset.
if (active && (lastHeartbeatReceived != 0) &&
(time(NULL) - lastHeartbeatReceived) > HEARTBEAT_REPEAT_TIME * 5)
int activeTick = 0;
{
int ageLastIncoming = time(NULL) - activepqi->getLastIncomingTS();
std::string out = "pqiperson::tick() WARNING No heartbeat from: " + PeerId();
//out << " assume dead. calling pqissl::reset(), LastHeartbeat was: ";
rs_sprintf_append(out, " LastHeartbeat was: %ld secs ago", time(NULL) - lastHeartbeatReceived);
rs_sprintf_append(out, " LastIncoming was: %d secs ago", ageLastIncoming);
pqioutput(PQL_WARNING, pqipersonzone, out);
#define NO_PACKET_TIMEOUT 60
if (ageLastIncoming > NO_PACKET_TIMEOUT)
RsStackMutex stack(mPersonMtx); /**** LOCK MUTEX ****/
//if lastHeartbeatReceived is 0, it might be not activated so don't do a net reset.
if (active && (lastHeartbeatReceived != 0) &&
(time(NULL) - lastHeartbeatReceived) > HEARTBEAT_REPEAT_TIME * 5)
{
out = "pqiperson::tick() " + PeerId();
out += " No Heartbeat & No Packets -> assume dead. calling pqissl::reset()";
int ageLastIncoming = time(NULL) - activepqi->getLastIncomingTS();
std::string out = "pqiperson::tick() WARNING No heartbeat from: " + PeerId();
//out << " assume dead. calling pqissl::reset(), LastHeartbeat was: ";
rs_sprintf_append(out, " LastHeartbeat was: %ld secs ago", time(NULL) - lastHeartbeatReceived);
rs_sprintf_append(out, " LastIncoming was: %d secs ago", ageLastIncoming);
pqioutput(PQL_WARNING, pqipersonzone, out);
this->reset();
#define NO_PACKET_TIMEOUT 60
if (ageLastIncoming > NO_PACKET_TIMEOUT)
{
out = "pqiperson::tick() " + PeerId();
out += " No Heartbeat & No Packets -> assume dead. calling pqissl::reset()";
pqioutput(PQL_WARNING, pqipersonzone, out);
this->reset_locked();
}
}
{
std::string out = "pqiperson::tick() Id: " + PeerId() + " ";
if (active)
out += "***Active***";
else
out += ">>InActive<<";
out += "\n";
rs_sprintf_append(out, "Activepqi: %p inConnectAttempt: ", activepqi);
if (inConnectAttempt)
out += "In Connection Attempt";
else
out += " Not Connecting ";
out += "\n";
// tick the children.
std::map<uint32_t, pqiconnect *>::iterator it;
for(it = kids.begin(); it != kids.end(); it++)
{
if (0 < (it->second) -> tick())
{
activeTick = 1;
}
rs_sprintf_append(out, "\tTicking Child: %d\n", it->first);
}
pqioutput(PQL_DEBUG_ALL, pqipersonzone, out);
} // end of pqioutput.
}
int activeTick = 0;
{
std::string out = "pqiperson::tick() Id: " + PeerId() + " ";
if (active)
out += "***Active***";
else
out += ">>InActive<<";
out += "\n";
rs_sprintf_append(out, "Activepqi: %p inConnectAttempt: ", activepqi);
if (inConnectAttempt)
out += "In Connection Attempt";
else
out += " Not Connecting ";
out += "\n";
// tick the children.
std::map<uint32_t, pqiconnect *>::iterator it;
for(it = kids.begin(); it != kids.end(); it++)
{
if (0 < (it->second) -> tick())
{
activeTick = 1;
}
rs_sprintf_append(out, "\tTicking Child: %d\n", it->first);
}
pqioutput(PQL_DEBUG_ALL, pqipersonzone, out);
} // end of pqioutput.
// handle Notify Events that were generated.
processNotifyEvents();
return activeTick;
}
@ -173,8 +200,60 @@ int pqiperson::tick()
// callback function for the child - notify of a change.
// This is only used for out-of-band info....
// otherwise could get dangerous loops.
int pqiperson::notifyEvent(NetInterface *ni, int newState)
// - Actually, now we have - must store and process later.
int pqiperson::notifyEvent(NetInterface *ni, int newState, const struct sockaddr_storage &remote_peer_address)
{
if (mPersonMtx.trylock())
{
handleNotifyEvent_locked(ni, newState, remote_peer_address);
mPersonMtx.unlock();
return 1;
}
RsStackMutex stack(mNotifyMtx); /**** LOCK MUTEX ****/
mNotifyQueue.push_back(NotifyData(ni, newState, remote_peer_address));
return 1;
}
void pqiperson::processNotifyEvents()
{
NetInterface *ni;
int state;
struct sockaddr_storage addr;
while(1)
{
{
RsStackMutex stack(mNotifyMtx); /**** LOCK MUTEX ****/
if (mNotifyQueue.empty())
{
return;
}
NotifyData &data = mNotifyQueue.front();
ni = data.mNi;
state = data.mState;
addr = data.mAddr;
mNotifyQueue.pop_front();
}
RsStackMutex stack(mPersonMtx); /**** LOCK MUTEX ****/
handleNotifyEvent_locked(ni, state, addr);
}
return;
}
int pqiperson::handleNotifyEvent_locked(NetInterface *ni, int newState, const struct sockaddr_storage &remote_peer_address)
{
{
std::string out = "pqiperson::notifyEvent() Id: " + PeerId() + "\n";
rs_sprintf_append(out, "Message: %d from: %p\n", newState, ni);
@ -219,8 +298,6 @@ int pqiperson::notifyEvent(NetInterface *ni, int newState)
/* notify */
if (pqipg) {
struct sockaddr_in remote_peer_address;
pqi->getConnectAddress(remote_peer_address);
pqipg->notifyConnect(PeerId(), type, true, remote_peer_address);
}
@ -246,6 +323,8 @@ int pqiperson::notifyEvent(NetInterface *ni, int newState)
activepqi = pqi;
inConnectAttempt = false;
activepqi->start(); // STARTUP THREAD.
/* reset all other children? (clear up long UDP attempt) */
for(it = kids.begin(); it != kids.end(); it++)
{
@ -273,6 +352,7 @@ int pqiperson::notifyEvent(NetInterface *ni, int newState)
{
pqioutput(PQL_WARNING, pqipersonzone, "pqiperson::notifyEvent() Id: " + PeerId() + " CONNECT_FAILED->marking so!");
activepqi->stop(); // STOP THREAD.
active = false;
activepqi = NULL;
}
@ -289,9 +369,7 @@ int pqiperson::notifyEvent(NetInterface *ni, int newState)
/* notify up */
if (pqipg)
{
struct sockaddr_in raddr;
sockaddr_clear(&raddr);
pqipg->notifyConnect(PeerId(), type, false, raddr);
pqipg->notifyConnect(PeerId(), type, false, remote_peer_address);
}
return 1;
@ -306,12 +384,20 @@ int pqiperson::notifyEvent(NetInterface *ni, int newState)
/***************** Not PQInterface Fns ***********************/
int pqiperson::reset()
{
RsStackMutex stack(mPersonMtx); /**** LOCK MUTEX ****/
return reset_locked();
}
int pqiperson::reset_locked()
{
pqioutput(PQL_WARNING, pqipersonzone, "pqiperson::reset() resetting all pqiconnect for Id: " + PeerId());
std::map<uint32_t, pqiconnect *>::iterator it;
for(it = kids.begin(); it != kids.end(); it++)
{
(it->second) -> stop(); // STOP THREAD.
(it->second) -> reset();
}
@ -322,8 +408,29 @@ int pqiperson::reset()
return 1;
}
int pqiperson::fullstopthreads()
{
RsStackMutex stack(mPersonMtx); /**** LOCK MUTEX ****/
pqioutput(PQL_WARNING, pqipersonzone, "pqiperson::fullstopthreads() for Id: " + PeerId());
std::map<uint32_t, pqiconnect *>::iterator it;
for(it = kids.begin(); it != kids.end(); it++)
{
(it->second) -> fullstop(); // WAIT FOR THREAD TO STOP.
}
activepqi = NULL;
active = false;
lastHeartbeatReceived = 0;
return 1;
}
int pqiperson::addChildInterface(uint32_t type, pqiconnect *pqi)
{
RsStackMutex stack(mPersonMtx); /**** LOCK MUTEX ****/
{
std::string out;
rs_sprintf(out, "pqiperson::addChildInterface() : Id %s %u", PeerId().c_str(), type);
@ -340,6 +447,8 @@ int pqiperson::addChildInterface(uint32_t type, pqiconnect *pqi)
int pqiperson::listen()
{
RsStackMutex stack(mPersonMtx); /**** LOCK MUTEX ****/
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, "pqiperson::listen() Id: " + PeerId());
if (!active)
@ -357,6 +466,8 @@ int pqiperson::listen()
int pqiperson::stoplistening()
{
RsStackMutex stack(mPersonMtx); /**** LOCK MUTEX ****/
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, "pqiperson::stoplistening() Id: " + PeerId());
std::map<uint32_t, pqiconnect *>::iterator it;
@ -368,18 +479,24 @@ int pqiperson::stoplistening()
return 1;
}
int pqiperson::connect(uint32_t type, struct sockaddr_in raddr,
struct sockaddr_in &proxyaddr, struct sockaddr_in &srcaddr,
uint32_t delay, uint32_t period, uint32_t timeout, uint32_t flags, uint32_t bandwidth)
int pqiperson::connect(uint32_t type, const struct sockaddr_storage &raddr,
const struct sockaddr_storage &proxyaddr, const struct sockaddr_storage &srcaddr,
uint32_t delay, uint32_t period, uint32_t timeout, uint32_t flags, uint32_t bandwidth,
const std::string &domain_addr, uint16_t domain_port)
{
RsStackMutex stack(mPersonMtx); /**** LOCK MUTEX ****/
#ifdef PERSON_DEBUG
#endif
{
std::string out = "pqiperson::connect() Id: " + PeerId();
rs_sprintf_append(out, " type: %u", type);
rs_sprintf_append(out, " addr: %s:%u", rs_inet_ntoa(raddr.sin_addr).c_str(), ntohs(raddr.sin_port));
rs_sprintf_append(out, " proxyaddr: %s:%u", rs_inet_ntoa(proxyaddr.sin_addr).c_str(), ntohs(proxyaddr.sin_port));
rs_sprintf_append(out, " srcaddr: %s:%u", rs_inet_ntoa(srcaddr.sin_addr).c_str(), ntohs(srcaddr.sin_port));
out += " addr: ";
out += sockaddr_storage_tostring(raddr);
out += " proxyaddr: ";
out += sockaddr_storage_tostring(proxyaddr);
out += " srcaddr: ";
out += sockaddr_storage_tostring(srcaddr);
rs_sprintf_append(out, " delay: %u", delay);
rs_sprintf_append(out, " period: %u", period);
rs_sprintf_append(out, " timeout: %u", timeout);
@ -414,19 +531,27 @@ int pqiperson::connect(uint32_t type, struct sockaddr_in raddr,
#ifdef PERSON_DEBUG
std::cerr << "pqiperson::connect() WARNING, clearing rate cap" << std::endl;
#endif
setRateCap(0,0);
setRateCap_locked(0,0);
#ifdef PERSON_DEBUG
std::cerr << "pqiperson::connect() setting connect_parameters" << std::endl;
#endif
// These two are universal.
(it->second)->connect_parameter(NET_PARAM_CONNECT_DELAY, delay);
(it->second)->connect_parameter(NET_PARAM_CONNECT_PERIOD, period);
(it->second)->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);
(it->second)->connect_additional_address(NET_PARAM_CONNECT_PROXY, &proxyaddr);
(it->second)->connect_additional_address(NET_PARAM_CONNECT_SOURCE, &srcaddr);
(it->second)->connect_additional_address(NET_PARAM_CONNECT_PROXY, proxyaddr);
(it->second)->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);
(it->second)->connect(raddr);
@ -437,25 +562,10 @@ int pqiperson::connect(uint32_t type, struct sockaddr_in raddr,
}
pqiconnect *pqiperson::getKid(uint32_t type)
{
std::map<uint32_t, pqiconnect *>::iterator it;
if (kids.empty()) {
return NULL;
}
it = kids.find(type);
if (it == kids.end())
{
return NULL;
} else {
return it->second;
}
}
void pqiperson::getRates(RsBwRates &rates)
{
RsStackMutex stack(mPersonMtx); /**** LOCK MUTEX ****/
// get the rate from the active one.
if ((!active) || (activepqi == NULL))
return;
@ -464,6 +574,8 @@ void pqiperson::getRates(RsBwRates &rates)
int pqiperson::getQueueSize(bool in)
{
RsStackMutex stack(mPersonMtx); /**** LOCK MUTEX ****/
// get the rate from the active one.
if ((!active) || (activepqi == NULL))
return 0;
@ -472,6 +584,8 @@ int pqiperson::getQueueSize(bool in)
bool pqiperson::getCryptoParams(RsPeerCryptoParams& params)
{
RsStackMutex stack(mPersonMtx); /**** LOCK MUTEX ****/
if(active && activepqi != NULL)
return activepqi->getCryptoParams(params) ;
else
@ -508,6 +622,8 @@ bool pqiconnect::getCryptoParams(RsPeerCryptoParams& params)
float pqiperson::getRate(bool in)
{
RsStackMutex stack(mPersonMtx); /**** LOCK MUTEX ****/
// get the rate from the active one.
if ((!active) || (activepqi == NULL))
return 0;
@ -516,6 +632,8 @@ float pqiperson::getRate(bool in)
void pqiperson::setMaxRate(bool in, float val)
{
RsStackMutex stack(mPersonMtx); /**** LOCK MUTEX ****/
// set to all of them. (and us)
PQInterface::setMaxRate(in, val);
// clean up the children.
@ -527,6 +645,12 @@ void pqiperson::setMaxRate(bool in, float val)
}
void pqiperson::setRateCap(float val_in, float val_out)
{
RsStackMutex stack(mPersonMtx); /**** LOCK MUTEX ****/
return setRateCap_locked(val_in, val_out);
}
void pqiperson::setRateCap_locked(float val_in, float val_out)
{
// set to all of them. (and us)
PQInterface::setRateCap(val_in, val_out);

View file

@ -30,6 +30,7 @@
#include "pqi/pqi.h"
#include "util/rsnet.h"
#include <list>
@ -45,12 +46,13 @@ static const int CONNECT_FAILED = 5;
static const int HEARTBEAT_REPEAT_TIME = 5;
#include "pqi/pqiqosstreamer.h"
#include "pqi/pqithreadstreamer.h"
class pqiconnect: public pqiQoSstreamer, public NetInterface
{
public:
pqiconnect(RsSerialiser *rss, NetBinInterface *ni_in)
:pqiQoSstreamer(rss, ni_in->PeerId(), ni_in, 0), // pqistreamer will cleanup NetInterface.
pqiconnect(PQInterface *parent, RsSerialiser *rss, NetBinInterface *ni_in)
:pqiQoSstreamer(parent, rss, ni_in->PeerId(), ni_in, 0), // pqistreamer will cleanup NetInterface.
NetInterface(NULL, ni_in->PeerId()), // No need for callback
ni(ni_in)
{
@ -67,17 +69,17 @@ virtual ~pqiconnect() { return; }
virtual bool getCryptoParams(RsPeerCryptoParams& params) ;
// presents a virtual NetInterface -> passes to ni.
virtual int connect(struct sockaddr_in raddr) { return ni->connect(raddr); }
virtual int connect(const struct sockaddr_storage &raddr) { return ni->connect(raddr); }
virtual int listen() { return ni -> listen(); }
virtual int stoplistening() { return ni -> stoplistening(); }
virtual int reset() { return ni -> reset(); }
virtual int disconnect() { return ni -> reset(); }
virtual bool connect_parameter(uint32_t type, uint32_t value) { return ni -> connect_parameter(type, value);}
virtual bool connect_additional_address(uint32_t type, struct sockaddr_in *addr) { return ni -> connect_additional_address(type, addr);}
virtual bool connect_parameter(uint32_t type, std::string value) { return ni -> connect_parameter(type, value);}
virtual bool connect_additional_address(uint32_t type, const struct sockaddr_storage &addr) { return ni -> connect_additional_address(type, addr);}
virtual int getConnectAddress(struct sockaddr_in &raddr){ return ni->getConnectAddress(raddr); }
virtual int getConnectAddress(struct sockaddr_storage &raddr){ return ni->getConnectAddress(raddr); }
// get the contact from the net side!
virtual std::string PeerId()
@ -102,6 +104,25 @@ protected:
class pqipersongrp;
class NotifyData
{
public:
NotifyData()
:mNi(NULL), mState(0)
{
sockaddr_storage_clear(mAddr);
}
NotifyData(NetInterface *ni, int state, const struct sockaddr_storage &addr)
:mNi(ni), mState(state), mAddr(addr) { return; }
NetInterface *mNi;
int mState;
struct sockaddr_storage mAddr;
};
class pqiperson: public PQInterface
{
public:
@ -113,10 +134,13 @@ int reset();
int listen();
int stoplistening();
int connect(uint32_t type, struct sockaddr_in raddr,
struct sockaddr_in &proxyaddr, struct sockaddr_in &srcaddr,
uint32_t delay, uint32_t period, uint32_t timeout, uint32_t flags, uint32_t bandwidth);
int connect(uint32_t type, const struct sockaddr_storage &raddr,
const struct sockaddr_storage &proxyaddr, const struct sockaddr_storage &srcaddr,
uint32_t delay, uint32_t period, uint32_t timeout, uint32_t flags, uint32_t bandwidth,
const std::string &domain_addr, uint16_t domain_port);
int fullstopthreads();
int receiveHeartbeat();
// add in connection method.
int addChildInterface(uint32_t type, pqiconnect *pqi);
@ -132,12 +156,13 @@ virtual int SendItem(RsItem *item)
return SendItem(item,serialized_size) ;
}
virtual RsItem *GetItem();
virtual bool RecvItem(RsItem *item);
virtual int status();
virtual int tick();
// overloaded callback function for the child - notify of a change.
int notifyEvent(NetInterface *ni, int event);
virtual int notifyEvent(NetInterface *ni, int event, const struct sockaddr_storage &addr);
// PQInterface for rate control overloaded....
virtual int getQueueSize(bool in);
@ -146,10 +171,22 @@ virtual float getRate(bool in);
virtual void setMaxRate(bool in, float val);
virtual void setRateCap(float val_in, float val_out);
pqiconnect *getKid(uint32_t type);
private:
void processNotifyEvents();
int handleNotifyEvent_locked(NetInterface *ni, int event, const struct sockaddr_storage &addr);
RsMutex mNotifyMtx; /**** LOCKS Notify Queue ****/
std::list<NotifyData> mNotifyQueue;
RsMutex mPersonMtx; /**** LOCKS below ****/
int reset_locked();
void setRateCap_locked(float val_in, float val_out);
std::map<uint32_t, pqiconnect *> kids;
bool active;
pqiconnect *activepqi;

View file

@ -26,6 +26,7 @@
#include "pqi/pqipersongrp.h"
#include "pqi/p3linkmgr.h"
#include "util/rsdebug.h"
#include "serialiser/rsserviceserialiser.h"
#include <stdio.h>
@ -43,7 +44,7 @@ static std::list<std::string> waitingIds;
/****
*#define PGRP_DEBUG 1
****/
//#define PGRP_DEBUG 1
#define PGRP_DEBUG 1
#define DEFAULT_DOWNLOAD_KB_RATE (200.0)
#define DEFAULT_UPLOAD_KB_RATE (50.0)
@ -55,13 +56,28 @@ static std::list<std::string> waitingIds;
* pqilistener and when accessing pqihandlers data.
*/
// New speedy recv.
bool pqipersongrp::RecvRsRawItem(RsRawItem *item)
{
std::cerr << "pqipersongrp::RecvRsRawItem()";
std::cerr << std::endl;
p3ServiceServer::recvItem(item);
return true;
}
// handle the tunnel services.
int pqipersongrp::tickServiceRecv()
{
RsRawItem *pqi = NULL;
int i = 0;
pqioutput(PQL_DEBUG_ALL, pqipersongrpzone, "pqipersongrp::tickTunnelServer()");
pqioutput(PQL_DEBUG_ALL, pqipersongrpzone, "pqipersongrp::tickServiceRecv()");
//p3ServiceServer::tick();
@ -69,8 +85,8 @@ int pqipersongrp::tickServiceRecv()
{
++i;
pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone,
"pqipersongrp::tickTunnelServer() Incoming TunnelItem");
incoming(pqi);
"pqipersongrp::tickServiceRecv() Incoming TunnelItem");
recvItem(pqi);
}
if (0 < i)
@ -81,6 +97,11 @@ int pqipersongrp::tickServiceRecv()
}
// handle the tunnel services.
// Improvements:
// This function is no longer necessary, and data is pushed directly to pqihandler.
#if 0
int pqipersongrp::tickServiceSend()
{
RsRawItem *pqi = NULL;
@ -105,10 +126,12 @@ int pqipersongrp::tickServiceSend()
return 0;
}
#endif
// init
pqipersongrp::pqipersongrp(SecurityPolicy *glob, unsigned long flags)
:pqihandler(glob), pqil(NULL), initFlags(flags)
:pqihandler(glob), p3ServiceServer(this), pqil(NULL), initFlags(flags)
{
}
@ -129,6 +152,7 @@ int pqipersongrp::tick()
int i = 0;
#if 0
if (tickServiceSend())
{
i = 1;
@ -136,14 +160,18 @@ int pqipersongrp::tick()
std::cerr << "pqipersongrp::tick() moreToTick from tickServiceSend()" << std::endl;
#endif
}
#endif
if (pqihandler::tick()) /* does actual Send/Recv */
#if 0
if (pqihandler::tick()) /* does Send/Recv */
{
i = 1;
#ifdef PGRP_DEBUG
std::cerr << "pqipersongrp::tick() moreToTick from pqihandler::tick()" << std::endl;
#endif
}
#endif
if (tickServiceRecv())
@ -154,6 +182,19 @@ int pqipersongrp::tick()
#endif
}
p3ServiceServer::tick();
#if 1
if (pqihandler::tick()) /* does Send/Recv */
{
i = 1;
#ifdef PGRP_DEBUG
std::cerr << "pqipersongrp::tick() moreToTick from pqihandler::tick()" << std::endl;
#endif
}
#endif
return i;
}
@ -184,7 +225,8 @@ int pqipersongrp::init_listener()
{
/* extract details from
*/
struct sockaddr_in laddr = mLinkMgr->getLocalAddress();
struct sockaddr_storage laddr;
mLinkMgr->getLocalAddress(laddr);
RsStackMutex stack(coreMtx); /******* LOCKED MUTEX **********/
pqil = locked_createListener(laddr);
@ -192,7 +234,7 @@ int pqipersongrp::init_listener()
return 1;
}
bool pqipersongrp::resetListener(struct sockaddr_in &local)
bool pqipersongrp::resetListener(const struct sockaddr_storage &local)
{
#ifdef PGRP_DEBUG
std::cerr << "pqipersongrp::resetListener()" << std::endl;
@ -413,6 +455,7 @@ int pqipersongrp::removePeer(std::string id)
p -> stoplistening();
pqioutput(PQL_WARNING, pqipersongrpzone, "pqipersongrp::removePeer() => reset() called before deleting person");
p -> reset();
p -> fullstopthreads();
delete p;
mods.erase(it);
}
@ -543,18 +586,20 @@ int pqipersongrp::connectPeer(std::string id
///////////////////////////////////////////////////////////
#endif
struct sockaddr_in addr;
struct sockaddr_storage addr;
uint32_t delay;
uint32_t period;
uint32_t timeout;
uint32_t type;
uint32_t flags = 0 ;
struct sockaddr_in proxyaddr;
struct sockaddr_in srcaddr;
struct sockaddr_storage proxyaddr;
struct sockaddr_storage srcaddr;
uint32_t bandwidth;
std::string domain_addr;
uint16_t domain_port;
if (!mLinkMgr->connectAttempt(id, addr, proxyaddr, srcaddr, delay, period, type, flags, bandwidth))
if (!mLinkMgr->connectAttempt(id, addr, proxyaddr, srcaddr, delay, period, type, flags, bandwidth, domain_addr, domain_port))
{
#ifdef PGRP_DEBUG
std::cerr << " pqipersongrp::connectPeer() No Net Address";
@ -565,11 +610,13 @@ int pqipersongrp::connectPeer(std::string id
#ifdef PGRP_DEBUG
std::cerr << " pqipersongrp::connectPeer() connectAttempt data id: " << id;
std::cerr << " addr: " << rs_inet_ntoa(addr.sin_addr) << ":" << ntohs(addr.sin_port);
std::cerr << " addr: " << sockaddr_storage_tostring(addr);
std::cerr << " delay: " << delay;
std::cerr << " period: " << period;
std::cerr << " type: " << type;
std::cerr << " flags: " << flags;
std::cerr << " domain_addr: " << domain_addr;
std::cerr << " domain_port: " << domain_port;
std::cerr << std::endl;
#endif
@ -577,8 +624,16 @@ int pqipersongrp::connectPeer(std::string id
uint32_t ptype;
if (type & RS_NET_CONN_TCP_ALL)
{
ptype = PQI_CONNECT_TCP;
timeout = RS_TCP_STD_TIMEOUT_PERIOD;
if (type == RS_NET_CONN_TCP_HIDDEN)
{
ptype = PQI_CONNECT_HIDDEN_TCP;
timeout = RS_TCP_HIDDEN_TIMEOUT_PERIOD;
}
else
{
ptype = PQI_CONNECT_TCP;
timeout = RS_TCP_STD_TIMEOUT_PERIOD;
}
#ifdef PGRP_DEBUG
std::cerr << " pqipersongrp::connectPeer() connecting with TCP: Timeout :" << timeout;
std::cerr << std::endl;
@ -591,15 +646,6 @@ int pqipersongrp::connectPeer(std::string id
#ifdef PGRP_DEBUG
std::cerr << " pqipersongrp::connectPeer() connecting with UDP: Timeout :" << timeout;
std::cerr << std::endl;
#endif
}
else if (type & RS_NET_CONN_TUNNEL)
{
ptype = PQI_CONNECT_TUNNEL;
timeout = period * 2;
#ifdef PGRP_DEBUG
std::cerr << " pqipersongrp::connectPeer() connecting with Tunnel: Timeout :" << timeout;
std::cerr << std::endl;
#endif
}
else
@ -611,12 +657,12 @@ int pqipersongrp::connectPeer(std::string id
return 0;
}
p->connect(ptype, addr, proxyaddr, srcaddr, delay, period, timeout, flags, bandwidth);
p->connect(ptype, addr, proxyaddr, srcaddr, delay, period, timeout, flags, bandwidth, domain_addr, domain_port);
return 1;
}
bool pqipersongrp::notifyConnect(std::string id, uint32_t ptype, bool success, struct sockaddr_in raddr)
bool pqipersongrp::notifyConnect(std::string id, uint32_t ptype, bool success, const struct sockaddr_storage &raddr)
{
uint32_t type = 0;
if (ptype == PQI_CONNECT_TCP)
@ -627,11 +673,6 @@ bool pqipersongrp::notifyConnect(std::string id, uint32_t ptype, bool success
{
type = RS_NET_CONN_UDP_ALL;
}
else if (ptype == PQI_CONNECT_TUNNEL)
{
type = RS_NET_CONN_TUNNEL;
}
if (mLinkMgr)
mLinkMgr->connectResult(id, success, type, raddr);
@ -643,7 +684,7 @@ bool pqipersongrp::notifyConnect(std::string id, uint32_t ptype, bool success
#include "pqi/pqibin.h"
pqilistener * pqipersongrpDummy::locked_createListener(struct sockaddr_in /*laddr*/)
pqilistener * pqipersongrpDummy::locked_createListener(const struct sockaddr_storage & /*laddr*/)
{
pqilistener *listener = new pqilistener();
return listener;
@ -660,11 +701,9 @@ pqiperson * pqipersongrpDummy::locked_createPerson(std::string id, pqilistener *
NetBinDummy *d1 = new NetBinDummy(pqip, id, PQI_CONNECT_TCP);
RsSerialiser *rss = new RsSerialiser();
rss->addSerialType(new RsFileItemSerialiser());
rss->addSerialType(new RsCacheItemSerialiser());
rss->addSerialType(new RsServiceSerialiser());
pqiconnect *pqic = new pqiconnect(rss, d1);
pqiconnect *pqic = new pqiconnect(pqip, rss, d1);
pqip -> addChildInterface(PQI_CONNECT_TCP, pqic);
@ -672,11 +711,9 @@ pqiperson * pqipersongrpDummy::locked_createPerson(std::string id, pqilistener *
NetBinDummy *d2 = new NetBinDummy(pqip, id, PQI_CONNECT_UDP);
RsSerialiser *rss2 = new RsSerialiser();
rss2->addSerialType(new RsFileItemSerialiser());
rss2->addSerialType(new RsCacheItemSerialiser());
rss2->addSerialType(new RsServiceSerialiser());
pqiconnect *pqic2 = new pqiconnect(rss2, d2);
pqiconnect *pqic2 = new pqiconnect(pqip, rss2, d2);
pqip -> addChildInterface(PQI_CONNECT_UDP, pqic2);

View file

@ -55,7 +55,7 @@ class pqipersongrp: public pqihandler, public pqiMonitor, public p3ServiceServer
/*************************** Setup *************************/
/* pqilistener */
virtual bool resetListener(struct sockaddr_in &local); // overloaded from pqiNetListener
virtual bool resetListener(const struct sockaddr_storage &local); // overloaded from pqiNetListener
int init_listener();
/*************** pqiMonitor callback ***********************/
@ -80,11 +80,15 @@ int connectPeer(std::string id
#endif
);
// New speedy recv.
virtual bool RecvRsRawItem(RsRawItem *item);
/* Work-around to dodgy pointer stuff */
int tagHeartbeatRecvd(std::string id);
/*** callback from children ****/
bool notifyConnect(std::string id, uint32_t type, bool success, struct sockaddr_in remote_peer_address);
bool notifyConnect(std::string id, uint32_t type, bool success, const struct sockaddr_storage &remote_peer_address);
//bool notifyConnect(std::string id, uint32_t type, bool success);
// tick interfaces.
@ -98,7 +102,7 @@ virtual bool locked_getCryptoParams(const std::string&, RsPeerCryptoParams&) { r
/********* FUNCTIONS to OVERLOAD for specialisation ********/
// THESE NEED TO BE LOCKED UNTIL PQILISTENER IS THREAD-SAFE.
virtual pqilistener *locked_createListener(struct sockaddr_in laddr) = 0;
virtual pqilistener *locked_createListener(const struct sockaddr_storage &laddr) = 0;
virtual pqiperson *locked_createPerson(std::string id, pqilistener *listener) = 0;
/********* FUNCTIONS to OVERLOAD for specialisation ********/
@ -114,9 +118,9 @@ virtual int checkOutgoingRsItem(RsItem *item, int global)
private:
// The tunnelserver operation.
// The serviceserver operation.
int tickServiceRecv();
int tickServiceSend();
//int tickServiceSend();
pqilistener *pqil;
unsigned long initFlags;
@ -131,7 +135,7 @@ class pqipersongrpDummy: public pqipersongrp
protected:
/********* FUNCTIONS to OVERLOAD for specialisation ********/
virtual pqilistener *locked_createListener(struct sockaddr_in laddr);
virtual pqilistener *locked_createListener(const struct sockaddr_storage &laddr);
virtual pqiperson *locked_createPerson(std::string id, pqilistener *listener);
/********* FUNCTIONS to OVERLOAD for specialisation ********/
};

View file

@ -25,8 +25,8 @@
#include "pqiqosstreamer.h"
pqiQoSstreamer::pqiQoSstreamer(RsSerialiser *rss, std::string peerid, BinInterface *bio_in, int bio_flagsin)
: pqistreamer(rss,peerid,bio_in,bio_flagsin), pqiQoS(PQI_QOS_STREAMER_MAX_LEVELS, PQI_QOS_STREAMER_ALPHA)
pqiQoSstreamer::pqiQoSstreamer(PQInterface *parent, RsSerialiser *rss, std::string peerid, BinInterface *bio_in, int bio_flagsin)
: pqithreadstreamer(parent,rss,peerid,bio_in,bio_flagsin), pqiQoS(PQI_QOS_STREAMER_MAX_LEVELS, PQI_QOS_STREAMER_ALPHA)
{
_total_item_size = 0 ;
_total_item_count = 0 ;
@ -37,7 +37,10 @@ int pqiQoSstreamer::getQueueSize(bool in)
if(in)
return pqistreamer::getQueueSize(in) ;
else
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
return qos_queue_size() ;
}
}
void pqiQoSstreamer::locked_storeInOutputQueue(void *ptr,int priority)

View file

@ -26,18 +26,18 @@
#pragma once
#include "pqiqos.h"
#include "pqistreamer.h"
#include "pqithreadstreamer.h"
class pqiQoSstreamer: public pqistreamer, public pqiQoS
class pqiQoSstreamer: public pqithreadstreamer, public pqiQoS
{
public:
pqiQoSstreamer(RsSerialiser *rss, std::string peerid, BinInterface *bio_in, int bio_flagsin);
pqiQoSstreamer(PQInterface *parent, RsSerialiser *rss, std::string peerid, BinInterface *bio_in, int bio_flagsin);
static const uint32_t PQI_QOS_STREAMER_MAX_LEVELS = 10 ;
static const float PQI_QOS_STREAMER_ALPHA = 2.0 ;
virtual void locked_storeInOutputQueue(void *ptr,int priority) ;
virtual int out_queue_size() const { return _total_item_count ; }
virtual int locked_out_queue_size() const { return _total_item_count ; }
virtual void locked_clear_out_queue() ;
virtual int locked_compute_out_pkt_size() const { return _total_item_size ; }
virtual void *locked_pop_out_data() ;

View file

@ -3,11 +3,11 @@
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2008 by Robert Fernie.
* Copyright 2004-2013 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
* License Version 2 as published by the Free Software Foundation.
* License Version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -33,7 +33,18 @@ const int pqiservicezone = 60478;
* #define SERVICE_DEBUG 1
****/
p3ServiceServer::p3ServiceServer() : srvMtx("p3ServiceServer")
void pqiService::setServiceServer(p3ServiceServer *server)
{
mServiceServer = server;
}
bool pqiService::send(RsRawItem *item)
{
return mServiceServer->sendItem(item);
}
p3ServiceServer::p3ServiceServer(pqiPublisher *pub) : mPublisher(pub), srvMtx("p3ServiceServer")
{
RsStackMutex stack(srvMtx); /********* LOCKED *********/
@ -42,7 +53,6 @@ p3ServiceServer::p3ServiceServer() : srvMtx("p3ServiceServer")
"p3ServiceServer::p3ServiceServer()");
#endif
rrit = services.begin();
return;
}
@ -55,20 +65,23 @@ int p3ServiceServer::addService(pqiService *ts)
"p3ServiceServer::addService()");
#endif
std::map<uint32_t, pqiService *>::iterator it;
it = services.find(ts -> getType());
if (it != services.end())
{
std::cerr << "p3ServiceServer::addService(): Service already added with id " << ts->getType() << "!" << std::endl;
// it exists already!
return -1;
}
ts->setServiceServer(this);
services[ts -> getType()] = ts;
rrit = services.begin();
return 1;
}
int p3ServiceServer::incoming(RsRawItem *item)
bool p3ServiceServer::recvItem(RsRawItem *item)
{
RsStackMutex stack(srvMtx); /********* LOCKED *********/
@ -92,12 +105,8 @@ int p3ServiceServer::incoming(RsRawItem *item)
pqioutput(PQL_DEBUG_BASIC, pqiservicezone,
"p3ServiceServer::incoming() Service: No Service - deleting");
#endif
// delete it.
delete item;
// it exists already!
return -1;
return false;
}
{
@ -107,75 +116,28 @@ int p3ServiceServer::incoming(RsRawItem *item)
pqioutput(PQL_DEBUG_BASIC, pqiservicezone, out);
#endif
return (it->second) -> receive(item);
return (it->second) -> recv(item);
}
delete item;
return -1;
return false;
}
RsRawItem *p3ServiceServer::outgoing()
bool p3ServiceServer::sendItem(RsRawItem *item)
{
RsStackMutex stack(srvMtx); /********* LOCKED *********/
#ifdef SERVICE_DEBUG
pqioutput(PQL_DEBUG_ALL, pqiservicezone,
"p3ServiceServer::outgoing()");
std::cerr << "p3ServiceServer::sendItem()";
std::cerr << std::endl;
item -> print_string(out);
std::cerr << std::endl;
#endif
if (rrit != services.end())
{
rrit++;
}
else
{
rrit = services.begin();
}
/* any filtering ??? */
std::map<uint32_t, pqiService *>::iterator sit = rrit;
// run to the end.
RsRawItem *item;
// run through to the end,
for(;rrit != services.end();rrit++)
{
if (NULL != (item = (rrit -> second) -> send()))
{
#ifdef SERVICE_DEBUG
std::string out;
rs_sprintf(out, "p3ServiceServer::outgoing() Got Item From: %p\n", rrit -> second);
item -> print_string(out);
std::cerr << out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqiservicezone, out);
#endif
return item;
}
}
// from the beginning to where we started.
for(rrit = services.begin();rrit != sit; rrit++)
{
if (NULL != (item = (rrit -> second) -> send()))
{
#ifdef SERVICE_DEBUG
std::string out;
rs_sprintf(out, "p3ServiceServer::outgoing() Got Item From: %p\n", rrit -> second);
item -> print_string(out);
pqioutput(PQL_DEBUG_BASIC, pqiservicezone, out);
std::cerr << out << std::endl;
#endif
return item;
}
}
return NULL;
mPublisher->sendItem(item);
return true;
}

View file

@ -27,6 +27,7 @@
#ifndef PQI_SERVICE_HEADER
#define PQI_SERVICE_HEADER
#include "pqi/pqi.h"
#include "pqi/pqi_base.h"
#include "util/rsthreads.h"
@ -51,20 +52,23 @@
// DataType is defined in the serialiser directory.
class RsRawItem;
class p3ServiceServer;
class pqiService
{
protected:
pqiService(uint32_t t) // our type of packets.
:type(t) { return; }
:type(t), mServiceServer(NULL) { return; }
virtual ~pqiService() { return; }
public:
void setServiceServer(p3ServiceServer *server);
//
virtual int receive(RsRawItem *) = 0;
virtual RsRawItem * send() = 0;
virtual bool recv(RsRawItem *) = 0;
virtual bool send(RsRawItem *item);
uint32_t getType() { return type; }
@ -72,28 +76,35 @@ virtual int tick() { return 0; }
private:
uint32_t type;
p3ServiceServer *mServiceServer; // const, no need for mutex.
};
#include <map>
/* We are pushing the packets back through p3ServiceServer2,
* so that we can filter services at this level later...
* if we decide not to do this, pqiService2 can call through
* to the base level pqiPublisher instead.
*/
class p3ServiceServer
{
public:
p3ServiceServer();
p3ServiceServer(pqiPublisher *pub);
int addService(pqiService *);
int incoming(RsRawItem *);
RsRawItem *outgoing();
bool recvItem(RsRawItem *);
bool sendItem(RsRawItem *);
int tick();
private:
pqiPublisher *mPublisher; // constant no need for mutex.
RsMutex srvMtx;
std::map<uint32_t, pqiService *> services;
std::map<uint32_t, pqiService *>::iterator rrit;
};

View file

@ -93,18 +93,20 @@ static const int PQISSL_SSL_CONNECT_TIMEOUT = 30;
pqissl::pqissl(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm)
:NetBinInterface(parent, parent->PeerId()),
waiting(WAITING_NOT), active(false), certvalid(false),
mLinkMgr(lm), pqil(l),
mSslMtx("pqissl"),
active(false), certvalid(false), waiting(WAITING_NOT),
sslmode(PQISSL_ACTIVE), ssl_connection(NULL), sockfd(-1),
pqil(l), // no init for remote_addr.
readpkt(NULL), pktlen(0),
readpkt(NULL), pktlen(0), total_len(0),
attempt_ts(0),
sameLAN(false), n_read_zero(0), mReadZeroTS(0),
mConnectDelay(0), mConnectTS(0),
mConnectTimeout(0), mTimeoutTS(0), mLinkMgr(lm)
mConnectTimeout(0), mTimeoutTS(0)
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
/* set address to zero */
sockaddr_clear(&remote_addr);
sockaddr_storage_clear(remote_addr);
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone, "pqissl for PeerId: " + PeerId());
@ -142,11 +144,12 @@ pqissl::pqissl(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm)
/********** Implementation of NetInterface *************************/
int pqissl::connect(struct sockaddr_in raddr)
int pqissl::connect(const struct sockaddr_storage &raddr)
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
// reset failures
remote_addr = raddr;
remote_addr.sin_family = AF_INET;
return ConnectAttempt();
}
@ -176,9 +179,13 @@ int pqissl::disconnect()
return reset();
}
int pqissl::getConnectAddress(struct sockaddr_in &raddr) {
raddr = remote_addr;
return (remote_addr.sin_addr.s_addr == 0);
int pqissl::getConnectAddress(struct sockaddr_storage &raddr)
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
raddr = remote_addr;
// TODO.
return (!sockaddr_storage_isnull(remote_addr));
}
/* BinInterface version of reset() for pqistreamer */
@ -191,8 +198,17 @@ int pqissl::close()
// put back on the listening queue.
int pqissl::reset()
{
std::string outLog;
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
return reset_locked();
}
int pqissl::reset_locked()
{
std::string outLog;
bool neededReset = false;
/* a reset shouldn't cause us to stop listening
* only reasons for stoplistening() are;
*
@ -211,7 +227,6 @@ int pqissl::reset()
outLog += "\n";
#endif
bool neededReset = false;
if (ssl_connection != NULL)
{
@ -259,14 +274,27 @@ int pqissl::reset()
// clean up the streamer
if (parent())
{
parent() -> notifyEvent(this, NET_CONNECT_FAILED);
struct sockaddr_storage addr;
sockaddr_storage_clear(addr);
parent() -> notifyEvent(this, NET_CONNECT_FAILED, addr);
}
}
return 1;
}
bool pqissl::connect_parameter(uint32_t type, const std::string &value)
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
(void) value;
return false;
}
bool pqissl::connect_parameter(uint32_t type, uint32_t value)
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
#ifdef PQISSL_LOG_DEBUG
{
std::string out = "pqissl::connect_parameter() Peer: " + PeerId();
@ -312,6 +340,8 @@ bool pqissl::connect_parameter(uint32_t type, uint32_t value)
void pqissl::getCryptoParams(RsPeerCryptoParams& params)
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
if(active)
{
params.connexion_state = 1 ;
@ -343,6 +373,7 @@ void pqissl::getCryptoParams(RsPeerCryptoParams& params)
int pqissl::status()
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
#ifdef PQISSL_LOG_DEBUG
std::string out = "pqissl::status()";
@ -381,6 +412,8 @@ int pqissl::status()
// tick......
int pqissl::tick()
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
//pqistreamer::tick();
// continue existing connection attempt.
@ -473,7 +506,7 @@ int pqissl::ConnectAttempt()
rslog(RSL_ALERT, pqisslzone,
"pqissl::ConnectAttempt() STATE = Unknown - calling reset()");
reset();
reset_locked();
break;
}
rslog(RSL_ALERT, pqisslzone, "pqissl::ConnectAttempt() Unknown");
@ -503,8 +536,11 @@ int pqissl::Failed_Connection()
if (parent())
{
parent() -> notifyEvent(this, NET_CONNECT_UNREACHABLE);
struct sockaddr_storage addr;
sockaddr_storage_clear(addr);
parent() -> notifyEvent(this, NET_CONNECT_UNREACHABLE, addr);
}
waiting = WAITING_NOT;
return 1;
@ -578,7 +614,7 @@ int pqissl::Delay_Connection()
int pqissl::Initiate_Connection()
{
int err;
struct sockaddr_in addr = remote_addr;
struct sockaddr_storage addr = remote_addr;
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
@ -638,11 +674,12 @@ int pqissl::Initiate_Connection()
{
std::string out;
rs_sprintf(out, "pqissl::Initiate_Connection() Connecting To: %s via: %s:%u", PeerId().c_str(), rs_inet_ntoa(addr.sin_addr).c_str(), ntohs(addr.sin_port));
rs_sprintf(out, "pqissl::Initiate_Connection() Connecting To: %s via: ", PeerId().c_str());
out += sockaddr_storage_tostring(addr);
rslog(RSL_WARNING, pqisslzone, out);
}
if (addr.sin_addr.s_addr == 0)
if (sockaddr_storage_isnull(addr))
{
rslog(RSL_WARNING, pqisslzone, "pqissl::Initiate_Connection() Invalid (0.0.0.0) Remote Address, Aborting Connect.");
waiting = WAITING_FAIL_INTERFACE;
@ -745,8 +782,9 @@ int pqissl::Initiate_Connection()
waiting = WAITING_FAIL_INTERFACE;
rslog(RSL_WARNING, pqisslzone, out);
// extra output for the moment.
//std::cerr << out.str();
std::cerr << out;
return -1;
}
@ -784,13 +822,8 @@ int pqissl::Initiate_Connection()
*
*/
int pqissl::Basic_Connection_Complete()
bool pqissl::CheckConnectionTimeout()
{
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::Basic_Connection_Complete()...");
#endif
/* new TimeOut code. */
if (time(NULL) > mTimeoutTS)
{
@ -801,11 +834,27 @@ int pqissl::Basic_Connection_Complete()
/* as sockfd is valid, this should close it all up */
rslog(RSL_ALERT, pqisslzone, "pqissl::Basic_Connection_Complete() -> calling reset()");
reset();
reset_locked();
return true;
}
return false;
}
int pqissl::Basic_Connection_Complete()
{
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::Basic_Connection_Complete()...");
#endif
if (CheckConnectionTimeout())
{
// calls reset.
return -1;
}
if (waiting != WAITING_SOCK_CONNECT)
{
rslog(RSL_ALERT, pqisslzone,
@ -818,7 +867,7 @@ int pqissl::Basic_Connection_Complete()
rslog(RSL_ALERT, pqisslzone,
"pqissl::Basic_Connection_Complete() problem with the socket descriptor. Aborting");
rslog(RSL_ALERT, pqisslzone, "pqissl::Basic_Connection_Complete() -> calling reset()");
reset();
reset_locked();
return -1;
}
@ -1119,7 +1168,7 @@ int pqissl::SSL_Connection_Complete()
Extract_Failed_SSL_Certificate();
rslog(RSL_ALERT, pqisslzone, "pqissl::SSL_Connection_Complete() -> calling reset()");
reset();
reset_locked();
waiting = WAITING_FAIL_INTERFACE;
return -1;
@ -1198,7 +1247,7 @@ int pqissl::Authorise_SSL_Connection()
"pqissl::Authorise_SSL_Connection() Connection Timed Out!");
/* as sockfd is valid, this should close it all up */
rslog(RSL_ALERT, pqisslzone, "pqissl::Authorise_Connection_Complete() -> calling reset()");
reset();
reset_locked();
}
int err;
@ -1224,7 +1273,7 @@ int pqissl::Authorise_SSL_Connection()
rslog(RSL_ALERT, pqisslzone, "pqissl::Authorise_Connection_Complete() -> calling reset()");
// Failed completely
reset();
reset_locked();
return -1;
}
@ -1236,7 +1285,7 @@ int pqissl::Authorise_SSL_Connection()
rslog(RSL_ALERT, pqisslzone, "pqissl::Authorise_Connection_Complete() -> calling reset()");
// Failed completely
reset();
reset_locked();
return -1;
}
@ -1260,7 +1309,7 @@ int pqissl::Authorise_SSL_Connection()
// then okay...
rslog(RSL_WARNING, pqisslzone, "pqissl::Authorise_SSL_Connection() Accepting Conn. Peer: " + PeerId());
accept(ssl_connection, sockfd, remote_addr);
accept_locked(ssl_connection, sockfd, remote_addr);
return 1;
}
@ -1269,11 +1318,23 @@ int pqissl::Authorise_SSL_Connection()
// else shutdown ssl connection.
rslog(RSL_ALERT, pqisslzone, "pqissl::Authorise_Connection_Complete() -> calling reset()");
reset();
reset_locked();
return 0;
}
int pqissl::accept(SSL *ssl, int fd, struct sockaddr_in foreign_addr) // initiate incoming connection.
/* This function is public, and callable from pqilistener - so must be mutex protected */
int pqissl::accept(SSL *ssl, int fd, const struct sockaddr_storage &foreign_addr) // initiate incoming connection.
{
std::cerr << "pqissl::accept()";
std::cerr << std::endl;
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
return accept_locked(ssl, fd, foreign_addr);
}
int pqissl::accept_locked(SSL *ssl, int fd, const struct sockaddr_storage &foreign_addr) // initiate incoming connection.
{
if (waiting != WAITING_NOT)
{
@ -1331,7 +1392,7 @@ int pqissl::accept(SSL *ssl, int fd, struct sockaddr_in foreign_addr) // initiat
"pqissl::accept() STATE = Unknown - ignore?");
rslog(RSL_ALERT, pqisslzone, "pqissl::accept() -> calling reset()");
reset();
reset_locked();
break;
}
@ -1367,13 +1428,14 @@ int pqissl::accept(SSL *ssl, int fd, struct sockaddr_in foreign_addr) // initiat
/* check whether it is on the same LAN */
struct sockaddr_in localaddr = mLinkMgr->getLocalAddress();
sameLAN = isSameSubnet(&(remote_addr.sin_addr), &(localaddr.sin_addr));
struct sockaddr_storage localaddr;
mLinkMgr->getLocalAddress(localaddr);
sameLAN = sockaddr_storage_samesubnet(remote_addr, localaddr);
{
std::string out = "pqissl::accept() SUCCESSFUL connection to: " + PeerId();
out += " localaddr: " + rs_inet_ntoa(localaddr.sin_addr);
out += " remoteaddr: " + rs_inet_ntoa(remote_addr.sin_addr);
out += " localaddr: " + sockaddr_storage_iptostring(localaddr);
out += " remoteaddr: " + sockaddr_storage_iptostring(remote_addr);
if (sameLAN)
{
@ -1411,7 +1473,7 @@ int pqissl::accept(SSL *ssl, int fd, struct sockaddr_in foreign_addr) // initiat
waiting = WAITING_FAIL_INTERFACE;
// failed completely.
rslog(RSL_ALERT, pqisslzone, "pqissl::accept() -> calling reset()");
reset();
reset_locked();
return -1;
}
else
@ -1427,21 +1489,28 @@ int pqissl::accept(SSL *ssl, int fd, struct sockaddr_in foreign_addr) // initiat
active = true;
waiting = WAITING_NOT;
std::cerr << "pqissl::accept_locked() connection complete - notifying parent";
std::cerr << std::endl;
// Notify the pqiperson.... (Both Connect/Receive)
if (parent())
{
parent() -> notifyEvent(this, NET_CONNECT_SUCCESS);
struct sockaddr_storage addr = remote_addr;
parent() -> notifyEvent(this, NET_CONNECT_SUCCESS, addr);
}
return 1;
}
/********** Implementation of BinInterface **************************
* All the rest of the BinInterface.
* This functions much be Mutex protected.
*
*/
int pqissl::senddata(void *data, int len)
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
int tmppktlen ;
#ifdef PQISSL_DEBUG
@ -1483,7 +1552,7 @@ int pqissl::senddata(void *data, int len)
}
rslog(RSL_ALERT, pqisslzone, "pqissl::senddata() -> calling reset()");
reset();
reset_locked();
return -1;
}
else if (err == SSL_ERROR_WANT_WRITE)
@ -1508,7 +1577,7 @@ int pqissl::senddata(void *data, int len)
rslog(RSL_ALERT, pqisslzone, out);
rslog(RSL_ALERT, pqisslzone, "pqissl::senddata() -> calling reset()");
reset();
reset_locked();
return -1;
}
}
@ -1517,6 +1586,8 @@ int pqissl::senddata(void *data, int len)
int pqissl::readdata(void *data, int len)
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
#ifdef PQISSL_DEBUG
std::cout << "Reading data thread=" << pthread_self() << ", ssl=" << (void*)this << std::endl ;
#endif
@ -1588,7 +1659,7 @@ int pqissl::readdata(void *data, int len)
rs_sprintf_append(out, " ReadZero Age: %ld", time(NULL) - mReadZeroTS);
rslog(RSL_ALERT, pqisslzone, "pqissl::readdata() -> calling reset()");
reset();
reset_locked();
}
rslog(RSL_ALERT, pqisslzone, out);
@ -1625,7 +1696,7 @@ int pqissl::readdata(void *data, int len)
}
rslog(RSL_ALERT, pqisslzone, "pqissl::readdata() -> calling reset()");
reset();
reset_locked();
std::cerr << out << std::endl ;
return -1;
}
@ -1656,7 +1727,7 @@ int pqissl::readdata(void *data, int len)
std::cerr << out << std::endl ;
rslog(RSL_ALERT, pqisslzone, "pqissl::readdata() -> calling reset()");
reset();
reset_locked();
return -1;
}
@ -1692,11 +1763,15 @@ int pqissl::netstatus()
int pqissl::isactive()
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
return active;
}
bool pqissl::moretoread()
bool pqissl::moretoread(uint32_t usec)
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
#ifdef PQISSL_DEBUG
{
std::string out;
@ -1711,12 +1786,12 @@ bool pqissl::moretoread()
FD_ZERO(&ExceptFDs);
FD_SET(sockfd, &ReadFDs);
FD_SET(sockfd, &WriteFDs);
// Dont set WriteFDs.
FD_SET(sockfd, &ExceptFDs);
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
timeout.tv_usec = usec;
if (select(sockfd + 1, &ReadFDs, &WriteFDs, &ExceptFDs, &timeout) < 0)
{
@ -1734,26 +1809,10 @@ bool pqissl::moretoread()
// this is a definite bad socket!.
// reset.
rslog(RSL_ALERT, pqisslzone, "pqissl::moretoread() -> calling reset()");
reset();
reset_locked();
return 0;
}
if (FD_ISSET(sockfd, &WriteFDs))
{
#ifdef PQISSL_DEBUG
// write can work.
rslog(RSL_DEBUG_ALL, pqisslzone,
"pqissl::moretoread() Can Write!");
#endif
}
else
{
#ifdef PQISSL_DEBUG
// write can work.
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::moretoread() Can *NOT* Write!");
#endif
}
if (FD_ISSET(sockfd, &ReadFDs))
{
@ -1774,8 +1833,10 @@ bool pqissl::moretoread()
}
bool pqissl::cansend()
bool pqissl::cansend(uint32_t usec)
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
#ifdef PQISSL_DEBUG
rslog(RSL_DEBUG_ALL, pqisslzone,
"pqissl::cansend() polling socket!");
@ -1788,13 +1849,14 @@ bool pqissl::cansend()
FD_ZERO(&WriteFDs);
FD_ZERO(&ExceptFDs);
FD_SET(sockfd, &ReadFDs);
// Dont Set ReadFDs.
FD_SET(sockfd, &WriteFDs);
FD_SET(sockfd, &ExceptFDs);
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
timeout.tv_usec = usec;
if (select(sockfd + 1, &ReadFDs, &WriteFDs, &ExceptFDs, &timeout) < 0)
{
@ -1814,7 +1876,7 @@ bool pqissl::cansend()
// this is a definite bad socket!.
// reset.
rslog(RSL_ALERT, pqisslzone, "pqissl::cansend() -> calling reset()");
reset();
reset_locked();
return 0;
}
@ -1849,3 +1911,17 @@ std::string pqissl::gethash()
/********** End of Implementation of BinInterface ******************/
int pqissl::net_internal_close(int fd)
{
return unix_close(fd);
}
int pqissl::net_internal_SSL_set_fd(SSL *ssl, int fd)
{
return SSL_set_fd(ssl, fd);
}
int pqissl::net_internal_fcntl_nonblock(int fd)
{
return unix_fcntl_nonblock(fd);
}

View file

@ -28,8 +28,6 @@
#ifndef MRK_PQI_SSL_HEADER
#define MRK_PQI_SSL_HEADER
#include <openssl/ssl.h>
// operating system specific network header.
#include "pqi/pqinetwork.h"
@ -93,13 +91,14 @@ public:
virtual ~pqissl();
// NetInterface
virtual int connect(struct sockaddr_in raddr);
virtual int connect(const struct sockaddr_storage &raddr);
virtual int listen();
virtual int stoplistening();
virtual int reset();
virtual int disconnect();
virtual int getConnectAddress(struct sockaddr_in &raddr);
virtual int getConnectAddress(struct sockaddr_storage &raddr);
virtual bool connect_parameter(uint32_t type, const std::string &value);
virtual bool connect_parameter(uint32_t type, uint32_t value);
// BinInterface
@ -110,14 +109,37 @@ virtual int senddata(void*, int);
virtual int readdata(void*, int);
virtual int netstatus();
virtual int isactive();
virtual bool moretoread();
virtual bool cansend();
virtual bool moretoread(uint32_t usec);
virtual bool cansend(uint32_t usec);
virtual int close(); /* BinInterface version of reset() */
virtual std::string gethash(); /* not used here */
virtual bool bandwidthLimited() { return true ; } // replace by !sameLAN to avoid bandwidth limiting on LAN
public:
/* Completion of the SSL connection,
* this is public, so it can be called by
* the listener (should make friends??)
*/
int accept(SSL *ssl, int fd, const struct sockaddr_storage &foreign_addr);
void getCryptoParams(RsPeerCryptoParams& params) ;
protected:
/* no mutex protection for these ones */
p3LinkMgr *mLinkMgr;
pqissllistener *pqil;
RsMutex mSslMtx; /**** MUTEX protects data and fn below ****/
virtual int reset_locked();
int accept_locked(SSL *ssl, int fd, const struct sockaddr_storage &foreign_addr);
// A little bit of information to describe
// the SSL state, this is needed
// to allow full Non-Blocking Connect behaviour.
@ -125,7 +147,6 @@ protected:
// to complete an SSL.
int ConnectAttempt();
int waiting;
virtual int Failed_Connection();
@ -144,37 +165,29 @@ int Authorise_SSL_Connection();
int Extract_Failed_SSL_Certificate(); // try to get cert anyway.
public:
// check connection timeout.
bool CheckConnectionTimeout();
/* Completion of the SSL connection,
* this is public, so it can be called by
* the listener (should make friends??)
*/
int accept(SSL *ssl, int fd, struct sockaddr_in foreign_addr);
void getCryptoParams(RsPeerCryptoParams& params) ;
protected:
//protected internal fns that are overloaded for udp case.
virtual int net_internal_close(int fd) { return unix_close(fd); }
virtual int net_internal_SSL_set_fd(SSL *ssl, int fd) { return SSL_set_fd(ssl, fd); }
virtual int net_internal_fcntl_nonblock(int fd) { return unix_fcntl_nonblock(fd);}
virtual int net_internal_close(int fd);
virtual int net_internal_SSL_set_fd(SSL *ssl, int fd);
virtual int net_internal_fcntl_nonblock(int fd);
/* data */
bool active;
bool certvalid;
int waiting;
// addition for udp (tcp version == ACTIVE).
int sslmode;
SSL *ssl_connection;
int sockfd;
pqissllistener *pqil;
struct sockaddr_in remote_addr;
struct sockaddr_storage remote_addr;
void *readpkt;
int pktlen;
@ -194,11 +207,10 @@ virtual int net_internal_fcntl_nonblock(int fd) { return unix_fcntl_nonblock(fd)
uint32_t mConnectTimeout;
time_t mTimeoutTS;
p3LinkMgr *mLinkMgr;
private:
// ssl only fns.
int connectInterface(sockaddr_in&);
int connectInterface(const struct sockaddr_storage &addr);
};

View file

@ -55,7 +55,7 @@ const int pqissllistenzone = 49787;
*/
pqissllistenbase::pqissllistenbase(struct sockaddr_in addr, p3PeerMgr *pm)
pqissllistenbase::pqissllistenbase(const struct sockaddr_storage &addr, p3PeerMgr *pm)
:laddr(addr), active(false), mPeerMgr(pm)
{
@ -87,7 +87,7 @@ int pqissllistenbase::tick()
int pqissllistenbase::status()
{
std::string out;
rs_sprintf(out, "pqissllistenbase::status(): Listening on port: %u", ntohs(laddr.sin_port));
rs_sprintf(out, "pqissllistenbase::status(): Listening on port: %u", sockaddr_storage_port(laddr));
pqioutput(PQL_DEBUG_ALL, pqissllistenzone, out);
return 1;
}
@ -146,16 +146,11 @@ int pqissllistenbase::setuplisten()
// setup listening address.
// fill in fconstant bits.
laddr.sin_family = AF_INET;
{
std::string out = "pqissllistenbase::setuplisten()\n";
rs_sprintf_append(out, "\tAddress Family: %d\n", (int) laddr.sin_family);
rs_sprintf_append(out, "\tSetup Address: %s\n", rs_inet_ntoa(laddr.sin_addr).c_str());
rs_sprintf_append(out, "\tSetup Port: %u", ntohs(laddr.sin_port));
out += "\t FAMILY: " + sockaddr_storage_familytostring(laddr);
out += "\t ADDRESS: " + sockaddr_storage_tostring(laddr);
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out);
//std::cerr << out.str() << std::endl;
}
@ -185,17 +180,21 @@ int pqissllistenbase::setuplisten()
}
#ifdef OPEN_UNIVERSAL_PORT
struct sockaddr_in tmpaddr = laddr;
tmpaddr.sin_addr.s_addr = 0;
if (0 != (err = bind(lsock, (struct sockaddr *) &tmpaddr, sizeof(tmpaddr))))
struct sockaddr_storage tmpaddr = laddr;
sockaddr_storage_zeroip(tmpaddr);
if (0 != (err = universal_bind(lsock, (struct sockaddr *) &tmpaddr, sizeof(tmpaddr))))
#else
if (0 != (err = bind(lsock, (struct sockaddr *) &laddr, sizeof(laddr))))
if (0 != (err = universal_bind(lsock, (struct sockaddr *) &laddr, sizeof(laddr))))
#endif
{
std::string out = "pqissllistenbase::setuplisten() Cannot Bind to Local Address!\n";
showSocketError(out);
pqioutput(PQL_ALERT, pqissllistenzone, out);
std::cerr << out << std::endl;
std::cerr << "laddr: " << sockaddr_storage_tostring(laddr) << std::endl;
#ifdef OPEN_UNIVERSAL_PORT
std::cerr << "Zeroed tmpaddr: " << sockaddr_storage_tostring(tmpaddr) << std::endl;
#endif
exit(1);
return -1;
@ -268,7 +267,7 @@ int pqissllistenbase::setuplisten()
return 1;
}
int pqissllistenbase::setListenAddr(struct sockaddr_in addr)
int pqissllistenbase::setListenAddr(const struct sockaddr_storage &addr)
{
laddr = addr;
return 1;
@ -305,7 +304,7 @@ int pqissllistenbase::acceptconnection()
// These are local but temp variables...
// can't be arsed making them all the time.
struct sockaddr_in remote_addr;
struct sockaddr_storage remote_addr;
socklen_t addrlen = sizeof(remote_addr);
int fd = accept(lsock, (struct sockaddr *) &remote_addr, &addrlen);
int err = 0;
@ -356,7 +355,8 @@ int pqissllistenbase::acceptconnection()
{
std::string out;
rs_sprintf(out, "Accepted Connection from %s:%u", rs_inet_ntoa(remote_addr.sin_addr).c_str(), ntohs(remote_addr.sin_port));
out += "Accepted Connection from ";
out += sockaddr_storage_tostring(remote_addr);
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out);
}
@ -507,12 +507,14 @@ int pqissllistenbase::Extract_Failed_SSL_Certificate(const IncomingSSLInfo& inf
std::cerr << " GPG id = " << info.gpgid << std::endl;
std::cerr << " SSL id = " << info.sslid << std::endl;
std::cerr << " SSL cn = " << info.sslcn << std::endl;
std::cerr << " addr+p = " << rs_inet_ntoa(info.addr.sin_addr) << ":" << ntohs(info.addr.sin_port) << std::endl;
std::cerr << " addr+p = " << sockaddr_storage_tostring(info.addr) << std::endl;
if (peercert == NULL)
{
std::string out;
rs_sprintf(out, "pqissllistenbase::Extract_Failed_SSL_Certificate() from: %s:%u ERROR Peer didn't give Cert!", rs_inet_ntoa(info.addr.sin_addr).c_str(), ntohs(info.addr.sin_port));
out += "pqissllistenbase::Extract_Failed_SSL_Certificate() from: ";
out += sockaddr_storage_tostring(info.addr);
out += " ERROR Peer didn't give Cert!";
std::cerr << out << std::endl;
AuthSSL::getAuthSSL()->FailedCertificate(peercert, info.gpgid,info.sslid,info.sslcn,info.addr, true);
@ -525,7 +527,9 @@ int pqissllistenbase::Extract_Failed_SSL_Certificate(const IncomingSSLInfo& inf
{
std::string out;
rs_sprintf(out, "pqissllistenbase::Extract_Failed_SSL_Certificate() from: %s:%u Passing Cert to AuthSSL() for analysis", rs_inet_ntoa(info.addr.sin_addr).c_str(), ntohs(info.addr.sin_port));
out += "pqissllistenbase::Extract_Failed_SSL_Certificate() from: ";
out += sockaddr_storage_tostring(info.addr);
out += " Passing Cert to AuthSSL() for analysis";
std::cerr << out << std::endl;
pqioutput(PQL_WARNING, pqissllistenzone, out);
@ -675,7 +679,7 @@ int pqissllistenbase::isSSLActive(int /*fd*/, SSL *ssl)
*
*/
pqissllistener::pqissllistener(struct sockaddr_in addr, p3PeerMgr *lm)
pqissllistener::pqissllistener(const struct sockaddr_storage &addr, p3PeerMgr *lm)
:pqissllistenbase(addr, lm)
{
return;
@ -743,8 +747,9 @@ int pqissllistener::status()
// print certificates we are listening for.
std::map<std::string, pqissl *>::iterator it;
std::string out = "pqissllistener::status(): ";
rs_sprintf(out, " Listening (%u) for Certs:", ntohs(laddr.sin_port));
std::string out = "pqissllistener::status(): Listening (";
out += sockaddr_storage_tostring(laddr);
out += ") for Certs:";
for(it = listenaddr.begin(); it != listenaddr.end(); it++)
{
out += "\n" + it -> first ;
@ -820,7 +825,9 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info)
if (found == false)
{
std::string out = "No Matching Certificate for Connection:" + rs_inet_ntoa(info.addr.sin_addr) +"\npqissllistenbase: Will shut it down!";
std::string out = "No Matching Certificate for Connection:";
out += sockaddr_storage_tostring(info.addr);
out += "\npqissllistenbase: Will shut it down!";
pqioutput(PQL_WARNING, pqissllistenzone, out);
// but as it passed the authentication step,
@ -850,13 +857,15 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info)
accepted_ssl.push_back(as);
std::string out = "pqissllistener::completeConnection() Successful Connection with: " + newPeerId;
out += " for Connection:" + rs_inet_ntoa(info.addr.sin_addr) + " Adding to WAIT-ACCEPT Queue";
out += " for Connection:";
out += sockaddr_storage_tostring(info.addr);
out += " Adding to WAIT-ACCEPT Queue";
pqioutput(PQL_WARNING, pqissllistenzone, out);
return 1;
}
int pqissllistener::finaliseConnection(int fd, SSL *ssl, std::string peerId, struct sockaddr_in &remote_addr)
int pqissllistener::finaliseConnection(int fd, SSL *ssl, std::string peerId, const struct sockaddr_storage &remote_addr)
{
std::map<std::string, pqissl *>::iterator it;
@ -867,13 +876,15 @@ int pqissllistener::finaliseConnection(int fd, SSL *ssl, std::string peerId, str
it = listenaddr.find(peerId);
if (it == listenaddr.end())
{
out += "No Matching Peer for Connection:" + rs_inet_ntoa(remote_addr.sin_addr);
out += "No Matching Peer for Connection:";
out += sockaddr_storage_tostring(remote_addr);
out += "\npqissllistener => Shutting Down!";
pqioutput(PQL_WARNING, pqissllistenzone, out);
return -1;
}
out += "Found Matching Peer for Connection:" + rs_inet_ntoa(remote_addr.sin_addr);
out += "Found Matching Peer for Connection:";
out += sockaddr_storage_tostring(remote_addr);
out += "\npqissllistener => Passing to pqissl module!";
pqioutput(PQL_WARNING, pqissllistenzone, out);

View file

@ -55,7 +55,7 @@ class AcceptedSSL
SSL *mSSL;
std::string mPeerId;
struct sockaddr_in mAddr;
struct sockaddr_storage mAddr;
time_t mAcceptTS;
};
@ -67,7 +67,7 @@ class pqissllistenbase: public pqilistener
public:
pqissllistenbase(struct sockaddr_in addr, p3PeerMgr *pm);
pqissllistenbase(const struct sockaddr_storage &addr, p3PeerMgr *pm);
virtual ~pqissllistenbase();
/*************************************/
@ -75,7 +75,7 @@ virtual ~pqissllistenbase();
virtual int tick();
virtual int status();
virtual int setListenAddr(struct sockaddr_in addr);
virtual int setListenAddr(const struct sockaddr_storage &addr);
virtual int setuplisten();
virtual int resetlisten();
@ -88,7 +88,7 @@ int finaliseAccepts();
struct IncomingSSLInfo
{
SSL *ssl ;
sockaddr_in addr ;
sockaddr_storage addr ;
std::string gpgid ;
std::string sslid ;
std::string sslcn ;
@ -100,10 +100,10 @@ int closeConnection(int fd, SSL *ssl);
int isSSLActive(int fd, SSL *ssl);
virtual int completeConnection(int sockfd, IncomingSSLInfo&) = 0;
virtual int finaliseConnection(int fd, SSL *ssl, std::string peerId, struct sockaddr_in &raddr) = 0;
virtual int finaliseConnection(int fd, SSL *ssl, std::string peerId, const struct sockaddr_storage &raddr) = 0;
protected:
struct sockaddr_in laddr;
struct sockaddr_storage laddr;
std::list<AcceptedSSL> accepted_ssl;
private:
@ -126,7 +126,7 @@ class pqissllistener: public pqissllistenbase
{
public:
pqissllistener(struct sockaddr_in addr, p3PeerMgr *pm);
pqissllistener(const struct sockaddr_storage &addr, p3PeerMgr *pm);
virtual ~pqissllistener();
int addlistenaddr(std::string id, pqissl *acc);
@ -136,7 +136,7 @@ int removeListenPort(std::string id);
virtual int status();
virtual int completeConnection(int sockfd, IncomingSSLInfo&);
virtual int finaliseConnection(int fd, SSL *ssl, std::string peerId, struct sockaddr_in &raddr);
virtual int finaliseConnection(int fd, SSL *ssl, std::string peerId, const struct sockaddr_storage &raddr);
private:

View file

@ -23,6 +23,7 @@
*
*/
#include "serialiser/rsserviceserialiser.h"
#include "util/rsdebug.h"
#include "pqi/pqisslpersongrp.h"
@ -39,17 +40,16 @@ const int pqipersongrpzone = 354;
#include "pqi/pqissl.h"
#include "pqi/pqissllistener.h"
#include "pqi/p3peermgr.h"
#ifndef PQI_DISABLE_TUNNEL
#include "pqi/pqissltunnel.h"
#endif
#ifndef PQI_DISABLE_UDP
#include "pqi/pqissludp.h"
#endif
#include "pqi/pqisslproxy.h"
pqilistener * pqisslpersongrp::locked_createListener(struct sockaddr_in laddr)
pqilistener * pqisslpersongrp::locked_createListener(const struct sockaddr_storage &laddr)
{
pqilistener *listener = new pqissllistener(laddr, mPeerMgr);
return listener;
@ -57,52 +57,73 @@ pqilistener * pqisslpersongrp::locked_createListener(struct sockaddr_in laddr)
pqiperson * pqisslpersongrp::locked_createPerson(std::string id, pqilistener *listener)
{
std::cerr << "pqisslpersongrp::locked_createPerson() PeerId: " << id;
std::cerr << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone, "pqipersongrp::createPerson() PeerId: " + id);
pqiperson *pqip = new pqiperson(id, this);
pqissl *pqis = new pqissl((pqissllistener *) listener, pqip, mLinkMgr);
/* construct the serialiser ....
* Needs:
* * FileItem
* * FileData
* * ServiceGeneric
*/
// If using proxy, then only create a proxy item, otherwise can use any.
// If we are a hidden node - then all connections should be via proxy.
if (mPeerMgr->isHiddenPeer(id) || mPeerMgr->isHidden())
{
std::cerr << "pqisslpersongrp::locked_createPerson() Is Hidden Peer!";
std::cerr << std::endl;
RsSerialiser *rss = new RsSerialiser();
rss->addSerialType(new RsFileItemSerialiser());
rss->addSerialType(new RsCacheItemSerialiser());
rss->addSerialType(new RsServiceSerialiser());
pqiconnect *pqisc = new pqiconnect(rss, pqis);
pqip -> addChildInterface(PQI_CONNECT_TCP, pqisc);
#ifndef PQI_DISABLE_TUNNEL
pqissltunnel *pqitun = new pqissltunnel(pqip, mLinkMgr);
RsSerialiser *rss3 = new RsSerialiser();
rss3->addSerialType(new RsFileItemSerialiser());
rss3->addSerialType(new RsCacheItemSerialiser());
rss3->addSerialType(new RsServiceSerialiser());
pqiconnect *pqicontun = new pqiconnect(rss3, pqitun);
pqip -> addChildInterface(PQI_CONNECT_TUNNEL, pqicontun);
#endif
#ifndef PQI_DISABLE_UDP
pqissludp *pqius = new pqissludp(pqip, mLinkMgr);
RsSerialiser *rss2 = new RsSerialiser();
rss2->addSerialType(new RsFileItemSerialiser());
rss2->addSerialType(new RsCacheItemSerialiser());
rss2->addSerialType(new RsServiceSerialiser());
pqisslproxy *pqis = new pqisslproxy((pqissllistener *) listener, pqip, mLinkMgr);
pqiconnect *pqiusc = new pqiconnect(rss2, pqius);
/* construct the serialiser ....
* Needs:
* * FileItem
* * FileData
* * ServiceGeneric
*/
// add a ssl + proxy interface.
// Add Proxy First.
pqip -> addChildInterface(PQI_CONNECT_UDP, pqiusc);
RsSerialiser *rss = new RsSerialiser();
rss->addSerialType(new RsServiceSerialiser());
pqiconnect *pqisc = new pqiconnect(pqip, rss, pqis);
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_TCP, pqisc);
}
else
{
std::cerr << "pqisslpersongrp::locked_createPerson() Is Normal Peer!";
std::cerr << std::endl;
pqissl *pqis = new pqissl((pqissllistener *) listener, pqip, mLinkMgr);
/* construct the serialiser ....
* Needs:
* * FileItem
* * FileData
* * ServiceGeneric
*/
ssl_tunnels[id] = pqis ; // keeps for getting crypt info per peer.
RsSerialiser *rss = new RsSerialiser();
rss->addSerialType(new RsServiceSerialiser());
pqiconnect *pqisc = new pqiconnect(pqip, rss, pqis);
pqip -> addChildInterface(PQI_CONNECT_TCP, pqisc);
#ifndef PQI_DISABLE_UDP
pqissludp *pqius = new pqissludp(pqip, mLinkMgr);
RsSerialiser *rss2 = new RsSerialiser();
rss2->addSerialType(new RsServiceSerialiser());
pqiconnect *pqiusc = new pqiconnect(pqip, rss2, pqius);
// add a ssl + proxy interface.
// Add Proxy First.
pqip -> addChildInterface(PQI_CONNECT_UDP, pqiusc);
#endif
}
return pqip;
}

View file

@ -43,7 +43,7 @@ class pqisslpersongrp: public pqipersongrp
protected:
/********* FUNCTIONS to OVERLOAD for specialisation ********/
virtual pqilistener *locked_createListener(struct sockaddr_in laddr);
virtual pqilistener *locked_createListener(const struct sockaddr_storage &laddr);
virtual pqiperson *locked_createPerson(std::string id, pqilistener *listener);
/********* FUNCTIONS to OVERLOAD for specialisation ********/

View file

@ -0,0 +1,508 @@
/*
* pqisslproxy.cc
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2013 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
* License Version 2.1 as published by the Free Software Foundation.
*
* 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 "pqi/pqisslproxy.h"
#include "pqi/pqinetwork.h"
#include <errno.h>
#include <openssl/err.h>
#include <sstream>
#include "util/rsdebug.h"
#include "util/rsnet.h"
#include "pqi/p3linkmgr.h"
const int pqisslproxyzone = 3517;
#define PROXY_DEBUG 1
#define PROXY_STATE_FAILED 0
#define PROXY_STATE_INIT 1
#define PROXY_STATE_WAITING_METHOD_RESPONSE 2
#define PROXY_STATE_WAITING_SOCKS_RESPONSE 3
#define PROXY_STATE_CONNECTION_COMPLETE 4
pqisslproxy::pqisslproxy(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm)
:pqissl(l, parent, lm)
{
sockaddr_storage_clear(remote_addr);
return;
}
pqisslproxy::~pqisslproxy()
{
rslog(RSL_ALERT, pqisslproxyzone,
"pqisslproxy::~pqisslproxy -> destroying pqisslproxy");
stoplistening();
reset();
return;
}
int pqisslproxy::Initiate_Connection()
{
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Initiate_Connection()";
std::cerr << std::endl;
#endif
rslog(RSL_DEBUG_BASIC, pqisslproxyzone,
"pqisslproxy::Initiate_Connection() Connection to Proxy");
/* init proxy state */
mProxyState = PROXY_STATE_INIT;
/* call standard Init_Conn() */
return pqissl::Initiate_Connection();
}
/********* VERY DIFFERENT **********/
int pqisslproxy::Basic_Connection_Complete()
{
rslog(RSL_DEBUG_BASIC, pqisslproxyzone,
"pqisslproxy::Basic_Connection_Complete()...");
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Basic_Connection_Complete() STATE: " << mProxyState;
std::cerr << std::endl;
#endif
if (CheckConnectionTimeout())
{
// calls reset.
return -1;
}
int ret = 0;
switch(mProxyState)
{
case PROXY_STATE_INIT:
ret = Proxy_Send_Method(); // checks basic conn, sends Method when able.
break;
case PROXY_STATE_WAITING_METHOD_RESPONSE:
ret = Proxy_Send_Address(); // waits for Method Response, send Address when able.
break;
case PROXY_STATE_WAITING_SOCKS_RESPONSE:
ret = Proxy_Connection_Complete(); // wait for ACK.
break;
case PROXY_STATE_CONNECTION_COMPLETE:
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Basic_Connection_Complete() COMPLETED";
std::cerr << std::endl;
#endif
return 1;
case PROXY_STATE_FAILED:
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Basic_Connection_Complete() FAILED";
std::cerr << std::endl;
#endif
reset_locked();
return -1;
}
if (ret < 0)
{
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Basic_Connection_Complete() FAILED(2)";
std::cerr << std::endl;
#endif
reset_locked();
return -1; // FAILURE.
}
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Basic_Connection_Complete() IN PROGRESS";
std::cerr << std::endl;
#endif
// In Progress.
return 0;
}
int pqisslproxy::Proxy_Send_Method()
{
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Send_Method() Checking pqissl::Basic_Connection_Complete()";
std::cerr << std::endl;
#endif
int ret = pqissl::Basic_Connection_Complete();
if (ret != 1)
{
return ret; // basic connection not complete.
}
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Send_Method() Basic complete, sending Method";
std::cerr << std::endl;
#endif
/* send hello to proxy server */
char method_hello_data[3] = { 0x05, 0x01, 0x00 }; // [ Ver | nMethods (1) | No Auth Method ]
int sent = send(sockfd, method_hello_data, 3, 0);
if (sent != 3)
{
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Send_Method() Send Failure";
std::cerr << std::endl;
#endif
return -1;
}
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Send_Method() Send Method Okay";
std::cerr << std::endl;
#endif
mProxyState = PROXY_STATE_WAITING_METHOD_RESPONSE;
return 1;
}
int pqisslproxy::Proxy_Method_Response()
{
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Method_Response()";
std::cerr << std::endl;
#endif
/* get response from proxy server */
char method_response[2];
// read from the socket.
int recvd = recv(sockfd, method_response, 2, MSG_WAITALL);
if (recvd != 2)
{
if ((recvd == -1) && (errno == EAGAIN))
{
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Method_Response() EAGAIN";
std::cerr << std::endl;
#endif
return 0;
}
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Method_Response() Error recving response";
std::cerr << std::endl;
#endif
return -1;
}
// does it make sense?
if (method_response[0] != 0x05)
{
// Error.
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Method_Response() Error response[0] != 0x05. Is: ";
std::cerr << (uint32_t) method_response[0];
std::cerr << std::endl;
#endif
return -1;
}
if (method_response[1] != 0x00)
{
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Method_Response() Error response[0] != 0x00. Is: ";
std::cerr << (uint32_t) method_response[1];
std::cerr << std::endl;
#endif
// Error.
return -1;
}
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Method_Response() Response Okay";
std::cerr << std::endl;
#endif
return 1;
}
#define MAX_SOCKS_REQUEST_LEN 262 // 4 + 1 + 255 + 2.
int pqisslproxy::Proxy_Send_Address()
{
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Send_Address() Checking Method Response";
std::cerr << std::endl;
#endif
// Check Method Response.
int ret = Proxy_Method_Response();
if (ret != 1)
{
return ret; // Method Response not complete.
}
char socks_request[MAX_SOCKS_REQUEST_LEN] =
{ 0x05, // SOCKS VERSION.
0x01, // CONNECT (Tor doesn't support BIND or UDP).
0x00, // RESERVED.
0x03, // ADDRESS TYPE (Domain Name)
0x00, // Length of Domain name... the rest is variable so can't hard code it!
};
/* get the length of the domain name, pack so we can't overflow uint8_t */
uint8_t len = mDomainAddress.length();
socks_request[4] = len;
for(int i = 0; i < len; i++)
{
socks_request[5 + i] = mDomainAddress[i];
}
/* now add the port, being careful with packing */
uint16_t net_port = htons(mRemotePort);
socks_request[5 + len] = ((uint8_t *) &net_port)[0];
socks_request[5 + len + 1] = ((uint8_t *) &net_port)[1];
int pkt_len = 5 + len + 2;
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Send_Address() Sending String: ";
for(int i = 0; i < pkt_len; i++)
std::cerr << (uint32_t) socks_request[i];
std::cerr << std::endl;
#endif
int sent = send(sockfd, socks_request, pkt_len, 0);
if (sent != pkt_len)
{
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Send_Address() Send Error";
std::cerr << std::endl;
#endif
return -1;
}
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Send_Address() Sent Okay";
std::cerr << std::endl;
#endif
mProxyState = PROXY_STATE_WAITING_SOCKS_RESPONSE;
return 1;
}
int pqisslproxy::Proxy_Connection_Complete()
{
/* get response from proxy server */
/* response is similar format to request - with variable length data */
char socks_response[MAX_SOCKS_REQUEST_LEN];
int recvd = recv(sockfd, socks_response, 5, MSG_WAITALL);
if (recvd != 5)
{
if ((recvd == -1) && (errno == EAGAIN))
{
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Connection_Complete() EAGAIN";
std::cerr << std::endl;
#endif
return 0;
}
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Connection_Complete() recv error";
std::cerr << std::endl;
#endif
return -1;
}
// error checking.
if (socks_response[0] != 0x05)
{
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Connection_Complete() ERROR socks_response[0] != 0x05. is: ";
std::cerr << (uint32_t) socks_response[0];
std::cerr << std::endl;
#endif
// error.
return -1;
}
if (socks_response[1] != 0x00)
{
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Connection_Complete() ERROR socks_response[1] != 0x00. is: ";
std::cerr << (uint32_t) socks_response[1];
std::cerr << std::endl;
#endif
// connection failed.
return -1;
}
int address_bytes = 0;
switch(socks_response[3]) // Address Type.
{
case 0x01:
// IPv4 4 address bytes.
address_bytes = 4;
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Connection_Complete() IPv4 Address Type";
std::cerr << std::endl;
#endif
break;
case 0x04:
// IPv6 16 address bytes.
address_bytes = 16;
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Connection_Complete() IPv6 Address Type";
std::cerr << std::endl;
#endif
break;
case 0x03:
// Variable address bytes - specified in next byte.
address_bytes = 1 + socks_response[4];
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Connection_Complete() Domain Address Type. len: " << address_bytes;
std::cerr << std::endl;
#endif
break;
default:
// unknown error.
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Connection_Complete() ERROR Unknown Address Type";
std::cerr << std::endl;
#endif
return -1;
break;
}
// read the remaining bytes.
recvd = recv(sockfd, &(socks_response[5]), address_bytes + 1, MSG_WAITALL); // address_bytes - 1 + 2...
if (recvd != address_bytes + 1)
{
if ((recvd == -1) && (errno == EAGAIN))
{
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Connection_Complete() ERROR EAGAIN at end.";
std::cerr << std::endl;
#endif
// Waiting - shouldn't happen.
return 0;
}
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Connection_Complete() ERROR recving(2)";
std::cerr << std::endl;
#endif
return -1;
}
#ifdef PROXY_DEBUG
std::cerr << "pqisslproxy::Proxy_Connection_Complete() Received String: ";
for(int i = 0; i < 4 + address_bytes + 2; i++)
std::cerr << (uint32_t) socks_response[i];
std::cerr << std::endl;
#endif
// should print address.
// if we get here - connection is good!.
mProxyState = PROXY_STATE_CONNECTION_COMPLETE;
return 1;
}
bool pqisslproxy::connect_parameter(uint32_t type, const std::string &value)
{
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
if (type == NET_PARAM_CONNECT_DOMAIN_ADDRESS)
{
std::string out;
rs_sprintf(out, "pqisslproxy::connect_parameter() Peer: %s DOMAIN_ADDRESS: %s", PeerId().c_str(), value.c_str());
rslog(RSL_WARNING, pqisslproxyzone, out);
mDomainAddress = value;
std::cerr << out << std::endl;
return true;
}
}
return pqissl::connect_parameter(type, value);
}
bool pqisslproxy::connect_parameter(uint32_t type, uint32_t value)
{
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
if (type == NET_PARAM_CONNECT_REMOTE_PORT)
{
std::string out;
rs_sprintf(out, "pqisslproxy::connect_parameter() Peer: %s REMOTE_PORT: %lu", PeerId().c_str(), value);
rslog(RSL_WARNING, pqisslproxyzone, out);
mRemotePort = value;
std::cerr << out << std::endl;
return true;
}
}
return pqissl::connect_parameter(type, value);
}

View file

@ -0,0 +1,87 @@
/*
* pqisslproxy.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2013 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
* License Version 2.1 as published by the Free Software Foundation.
*
* 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".
*
*/
#ifndef MRK_PQI_SSL_PROXY_HEADER
#define MRK_PQI_SSL_PROXY_HEADER
// operating system specific network header.
#include "pqi/pqinetwork.h"
#include <string>
#include <map>
#include "pqi/pqissl.h"
/* pqisslproxy uses SOCKS5 proxy to hidden your own address and connect to peers.
* It uses the Domain Name interface of SOCKS5, as opposed to an IP address.
*/
class pqisslproxy;
class cert;
/* This provides a NetBinInterface, which is
* primarily inherited from pqissl.
* fns declared here are different -> all others are identical.
*/
class pqisslproxy: public pqissl
{
public:
pqisslproxy(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm);
virtual ~pqisslproxy();
// NetInterface. Is the same.
// BinInterface. Is the same.
virtual bool connect_parameter(uint32_t type, const std::string &value);
virtual bool connect_parameter(uint32_t type, uint32_t value);
protected:
//Initiate is the same - except it uses the Proxy Address rather than the Peer Address.
// minor tweaks to setup data state.
virtual int Initiate_Connection();
// The real overloading is done in Basic Connection Complete.
// Instead of just checking for an open socket, we need to communicate with the SOCKS5 proxy.
virtual int Basic_Connection_Complete();
// These are the internal steps in setting up the Proxy Connection.
virtual int Proxy_Send_Method();
virtual int Proxy_Method_Response();
virtual int Proxy_Send_Address();
virtual int Proxy_Connection_Complete();
private:
uint32_t mProxyState;
std::string mDomainAddress;
uint16_t mRemotePort;
};
#endif // MRK_PQI_SSL_PROXY_HEADER

View file

@ -1,554 +0,0 @@
/*
* "$Id: pqissl.cc,v 1.28 2007-03-17 19:32:59 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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
* License Version 2 as published by the Free Software Foundation.
*
* 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 "pqi/pqissltunnel.h"
#include "pqi/pqinetwork.h"
#include "pqi/p3linkmgr.h"
//#include "services/p3tunnel.h"
#include "util/rsnet.h"
#include "util/rsdebug.h"
#include "util/rsstring.h"
#include <unistd.h>
#include <errno.h>
#include <openssl/err.h>
const int pqisslzone = 37714;
#define TUNNEL_WAITING_NOT 0
#define TUNNEL_WAITING_DELAY 1
#define TUNNEL_WAITING_SPAM_HANDSHAKE 2
#define TUNNEL_WAITING_RETURN_HANDSHAKE 3
#define TUNNEL_PASSIVE 0x00
#define TUNNEL_ACTIVE 0x01
#define TUNNEL_START_CONNECTION_DELAY 1
#define TUNNEL_PING_TIMEOUT 6
#define TUNNEL_REPEAT_PING_TIME 2
#define TUNNEL_TIMEOUT_AFTER_RESET 30
#define TUNNEL_TRY_OTHER_CONNECTION_INTERVAL 190 //let's try a normal tcp or udp connection every 190 sec
//const int TUNNEL_LOCAL_FLAG = 0x01;
//const int TUNNEL_REMOTE_FLAG = 0x02;
//const int TUNNEL_UDP_FLAG = 0x02;
//
//static const int PQISSL_MAX_READ_ZERO_COUNT = 20;
//static const int PQISSL_SSL_CONNECT_TIMEOUT = 30;
/********** PQI SSL STUFF ******************************************
*
* A little note on the notifyEvent(FAILED)....
*
* this is called from
* (1) reset if needed!
* (2) Determine_Remote_Address (when all options have failed).
*
* reset() is only called when a TCP/SSL connection has been
* established, and there is an error. If there is a failed TCP
* connection, then an alternative address can be attempted.
*
* reset() is called from
* (1) destruction.
* (2) disconnect()
* (3) bad waiting state.
*
* // TCP/or SSL connection already established....
* (5) pqissltunnel::SSL_Connection_Complete() <- okay -> cos we made a TCP connection already.
* (6) pqissltunnel::accept() <- okay cos something went wrong.
* (7) moretoread()/cansend() <- okay cos
*
*/
pqissltunnel::pqissltunnel(PQInterface *parent, p3LinkMgr *cm, p3tunnel *p3t)
:NetBinInterface(parent, parent->PeerId()), mLinkMgr(cm)
{
active = false;
waiting = TUNNEL_WAITING_NOT;
rslog(RSL_ALERT, pqisslzone, "pqissltunnel for PeerId: " + PeerId());
// if (!(AuthSSL::getAuthSSL()->isAuthenticated(PeerId()))) {
// rslog(RSL_ALERT, pqisslzone,
// "pqissltunnel::Warning Certificate Not Approved!");
// rslog(RSL_ALERT, pqisslzone,
// "\t pqissltunnel will not initialise....");
// }
mP3tunnel = p3t;
current_data_offset = 0;
curent_data_packet.length = 0;
return;
}
pqissltunnel::~pqissltunnel() {
rslog(RSL_ALERT, pqisslzone,
"pqissltunnel::~pqissltunnel -> destroying pqissl");
//stoplistening();
reset();
return;
}
/********** Implementation of NetInterface *************************/
int pqissltunnel::connect(struct sockaddr_in /*raddr*/) {
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::connect() called : " << PeerId() << std::endl;
#endif
last_normal_connection_attempt_time = time(NULL);
mConnectTS = time(NULL);
resetTime = time(NULL) - TUNNEL_TIMEOUT_AFTER_RESET;
waiting = TUNNEL_WAITING_DELAY;
return 0;
}
// tells pqilistener to listen for us.
int pqissltunnel::listen()
{
//no use
return 0;
}
int pqissltunnel::stoplistening()
{
//no use
return 1;
}
int pqissltunnel::disconnect()
{
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::disconnect() called : " << PeerId() << std::endl;
#endif
return reset();
}
/* BinInterface version of reset() for pqistreamer */
int pqissltunnel::close()
{
return reset();
}
// put back on the listening queue.
int pqissltunnel::reset()
{
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::reset() called : " << PeerId() << std::endl;
#endif
if (active)
{
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::reset() Reset Required because tunnel was activated !" << std::endl;
std::cerr << "pqissltunnel::reset() Will Attempt notifyEvent(FAILED)" << std::endl;
#endif
waiting = TUNNEL_WAITING_NOT;
active = false;
resetTime = time(NULL);
// clean up the streamer
if (parent()) {
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::reset() notifyEvent(FAILED)" << std::endl;
#endif
parent() -> notifyEvent(this, NET_CONNECT_FAILED);
}
} else {
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::reset() Reset not required because tunnel was not activated !" << std::endl;
#endif
}
return 1;
}
int pqissltunnel::getConnectAddress(struct sockaddr_in &raddr) {
sockaddr_clear(&raddr);
return 0;
}
bool pqissltunnel::connect_parameter(uint32_t type, uint32_t value)
{
{
std::string out = "pqissltunnel::connect_parameter() (not used) Peer: " + PeerId();
rs_sprintf_append(out, " type: %lu value: %lu", type, value);
rslog(RSL_DEBUG_ALL, pqisslzone, out);
}
if (type == NET_PARAM_CONNECT_DELAY)
{
std::string out = "pqissltunnel::connect_parameter() (not used) Peer: " + PeerId();
rs_sprintf_append(out, " DELAY: %lu", value);
rslog(RSL_WARNING, pqisslzone, out);
return true;
}
else if (type == NET_PARAM_CONNECT_TIMEOUT)
{
std::string out = "pqissltunnel::connect_parameter() (not used) Peer: " + PeerId();
rs_sprintf_append(out, " TIMEOUT: %lu", value);
rslog(RSL_WARNING, pqisslzone, out);
return true;
}
return false;
}
/********** End of Implementation of NetInterface ******************/
/********** Implementation of BinInterface **************************
* Only status() + tick() are here ... as they are really related
* to the NetInterface, and not the BinInterface,
*
*/
/* returns ...
* -1 if inactive.
* 0 if connecting.
* 1 if connected.
*/
int pqissltunnel::status()
{
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::status() called." << std::endl;
#endif
if (active) {
std::cerr << " active: " << std::endl;
// print out connection.
std::cerr << "dest : " << PeerId();
std::cerr << "relay : " << relayPeerId;
std::cerr << std::endl;
}
else {
std::cerr << " Waiting for connection!" << std::endl;
}
if (active) {
return 1;
} else if (waiting > 0) {
return 0;
}
return -1;
}
int pqissltunnel::tick()
{
if (active && ((time(NULL) - last_normal_connection_attempt_time) > TUNNEL_TRY_OTHER_CONNECTION_INTERVAL)) {
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::tick() attempt to connect through a normal tcp or udp connection." << std::endl;
#endif
last_normal_connection_attempt_time = time(NULL);
mLinkMgr->retryConnect(parent()->PeerId());
}
if (active && ((time(NULL) - last_ping_send_time) > TUNNEL_REPEAT_PING_TIME)) {
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::tick() sending a ping." << std::endl;
#endif
last_ping_send_time = time(NULL);;
mP3tunnel->pingTunnelConnection(relayPeerId, parent()->PeerId());
}
if (active && ((time(NULL) - last_packet_time) > TUNNEL_PING_TIMEOUT)) {
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::tick() no packet received since PING_RECEIVE_TIME_OUT. Connection is broken." << std::endl;
#endif
reset();
}
// continue existing connection attempt.
if (!active)
{
// if we are waiting.. continue the connection (only)
if (waiting > 0)
{
#ifdef DEBUG_PQISSL_TUNNEL
//std::cerr << "pqissltunnel::tick() Continuing Connection Attempt!" << std::endl;
#endif
ConnectAttempt();
return 1;
}
}
return 1;
}
/********** End of Implementation of BinInterface ******************/
/********** Internals of Tunnel Connection ****************************/
int pqissltunnel::ConnectAttempt()
{
#ifdef DEBUG_PQISSL_TUNNEL
//std::cerr << "pqissltunnel::ConnectAttempt() called." << std::endl;
#endif
switch(waiting)
{
case TUNNEL_WAITING_NOT:
active = true; /* we're starting this one */
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::ConnectAttempt() STATE = Not Waiting." << std::endl;
#endif
case TUNNEL_WAITING_DELAY:
if ((time(NULL) - mConnectTS) > TUNNEL_START_CONNECTION_DELAY) {
waiting = TUNNEL_WAITING_SPAM_HANDSHAKE;
}
break;
case TUNNEL_WAITING_SPAM_HANDSHAKE:
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::ConnectAttempt() STATE = Waiting for spamming handshake." << std::endl;
#endif
spam_handshake();
waiting = TUNNEL_WAITING_RETURN_HANDSHAKE;
break;
case TUNNEL_WAITING_RETURN_HANDSHAKE:
if ((time(NULL) - mConnectTS) < TUNNEL_PING_TIMEOUT) {
#ifdef DEBUG_PQISSL_TUNNEL
//std::cerr << "pqissltunnel::ConnectAttempt() STATE = Waiting for handshake reply." << std::endl;
#endif
} else {
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::ConnectAttempt() no handshake reply during imparing time. Connection failed." << std::endl;
#endif
waiting = TUNNEL_WAITING_NOT;
active = false;
// clean up the streamer
if (parent()) {
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::reset() Reset not required because tunnel was not activated !" << std::endl;
#endif
parent() -> notifyEvent(this, NET_CONNECT_FAILED);
}
}
break;
default:
std::cerr << "pqissltunnel::ConnectAttempt() STATE = Unknown - Reset" << std::endl;
reset();
break;
}
return -1;
}
void pqissltunnel::spam_handshake()
{
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::spam_handshake() starting to spam handshake tunnel packet." << std::endl;
#endif
std::list<std::string> peers;
mLinkMgr->getOnlineList(peers);
std::list<std::string>::iterator it = peers.begin();
while (it != peers.end()) {
//send a handshake to the destination through the relay
if (*it != parent()->PeerId()) {
mP3tunnel->initiateHandshake(*it, parent()->PeerId());
}
++it;
}
}
void pqissltunnel::addIncomingPacket(void* encoded_data, int encoded_data_length) {
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::addIncomingPacket() called." << std::endl;
#endif
last_packet_time = time(NULL);
data_with_length data_w_l;
data_w_l.data = (void*)malloc(encoded_data_length) ;
memcpy(data_w_l.data, encoded_data, encoded_data_length);
data_w_l.length = encoded_data_length;
data_packet_queue.push_front(data_w_l);
}
void pqissltunnel::IncommingPingPacket() {
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::IncommingPingPacket() called" << std::endl;
#endif
last_packet_time = time(NULL);
}
void pqissltunnel::IncommingHanshakePacket(std::string incRelayPeerId) {
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::IncommingHanshakePacket() called with incRelayPeerId : " << incRelayPeerId << std::endl;
#endif
if ((time(NULL) - resetTime) <= TUNNEL_TIMEOUT_AFTER_RESET) {
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::IncommingHanshakePacket() a reset occured, don't activate the connection." << std::endl;
#endif
return;
}
last_packet_time = time(NULL);
std::string message = "pqissltunnel::IncommingHanshakePacket() mConnMgr->isOnline(parent()->PeerId() : ";
if (mLinkMgr->isOnline(parent()->PeerId())) {
message += "true";
} else {
message += "false";
}
rslog(RSL_DEBUG_BASIC, pqisslzone, message);
if (active || mLinkMgr->isOnline(parent()->PeerId())) {
//connection is already active, or peer is already online don't do nothing
return;
}
//TODO : check if cert is in order before accepting
//activate connection
waiting = TUNNEL_WAITING_NOT;
active = true;
relayPeerId = incRelayPeerId;
if (parent())
{
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::IncommingHanshakePacket() Notify the pqiperson.... (Both Connect/Receive)" << parent()->PeerId() <<std::endl;
#endif
rslog(RSL_DEBUG_BASIC, pqisslzone, "pqissltunnel::IncommingHanshakePacket() Notify the pqiperson.... (Both Connect/Receive)");
parent() -> notifyEvent(this, NET_CONNECT_SUCCESS);
}
}
/********** Implementation of BinInterface **************************
* All the rest of the BinInterface.
*
*/
int pqissltunnel::senddata(void *data, int len)
{
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::senddata() called" << std::endl ;
#endif
if (!active) {
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::senddata() connection is not active" << std::endl ;
#endif
return -1;
}
int outlen = 0;
void * out;
if (!AuthSSL::getAuthSSL()->encrypt(out, outlen, data, len, parent()->PeerId())) {
std::cerr << "pqissltunnel::senddata() problem while crypting packet, ignoring it." << std::endl;
return -1;
}
#ifdef DEBUG_PQISSL_TUNNEL
std::cerr << "pqissltunnel::senddata() sending item via p3tunnel" << std::endl ;
#endif
mP3tunnel->sendTunnelData(parent()->PeerId(), relayPeerId, out, outlen);
return len;
}
int pqissltunnel::readdata(void *data, int len)
{
#ifdef DEBUG_PQISSL_TUNNEL
std::cout << "pqissltunnel::readdata() called" << std::endl ;
#endif
//let's see if we got a new packet to read
if (current_data_offset >= curent_data_packet.length) {
//current packet has finished reading, let's pop out a new packet if available
if (data_packet_queue.size() ==0) {
//no more to read
return -1;
} else {
//let's read a new packet
current_data_offset = 0;
//decrypt one packet from the queue and put it into the current data packet.
if (!AuthSSL::getAuthSSL()->decrypt(curent_data_packet.data, curent_data_packet.length, data_packet_queue.back().data, data_packet_queue.back().length)) {
std::cerr << "pqissltunnel::readdata() problem while decrypting packet, ignoring it." << std::endl;
curent_data_packet.length = 0;
return -1;
}
data_packet_queue.pop_back();
}
}
if (current_data_offset < curent_data_packet.length) {
#ifdef DEBUG_PQISSL_TUNNEL
std::cout << "pqissltunnel::readdata() reading..." << std::endl ;
std::cout << "pqissltunnel::readdata() len : " << len << std::endl ;
std::cout << "pqissltunnel::readdata() current_data_offset : " << current_data_offset << std::endl ;
std::cout << "pqissltunnel::readdata() curent_data_packet.length : " << curent_data_packet.length << std::endl ;
std::cerr << "pqissltunnel::readdata() getRsItemSize(curent_data_packet.data) : " << getRsItemSize(curent_data_packet.data) << std::endl;
#endif
//read from packet
memcpy(data, (void*)((unsigned long int)curent_data_packet.data+(unsigned long int)current_data_offset), len);
current_data_offset += len;
return len;
}
return -1;
}
// dummy function currently.
int pqissltunnel::netstatus()
{
return 1;
}
int pqissltunnel::isactive()
{
return active;
}
bool pqissltunnel::moretoread()
{
//let's see if we got an old packet or a new packet to read
if (current_data_offset >= curent_data_packet.length && data_packet_queue.size() ==0) {
return false;
} else {
return true;
}
}
bool pqissltunnel::cansend()
{
if (!mLinkMgr->isOnline(relayPeerId)) {
reset();
return false;
}
return true;
}
std::string pqissltunnel::gethash()
{
std::string dummyhash;
return dummyhash;
}
/********** End of Implementation of BinInterface ******************/

View file

@ -1,146 +0,0 @@
/*
* "$Id: pqissl.h,v 1.18 2007-03-11 14:54:22 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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
* License Version 2 as published by the Free Software Foundation.
*
* 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".
*
*/
#ifndef MRK_PQI_SSL_TUNNEL_HEADER
#define MRK_PQI_SSL_TUNNEL_HEADER
#include "util/rswin.h"
#include <openssl/ssl.h>
// operating system specific network header.
//#include "pqi/pqinetwork.h"
#include "pqi/pqi_base.h"
#include "services/p3tunnel.h"
#include "pqi/authssl.h"
/***************************** pqi Net SSL Interface *********************************
* This provides the base SSL interface class,
* and handles most of the required functionality.
*
* there are a series of small fn's that can be overloaded
* to provide alternative behaviour....
*
* Classes expected to inherit from this are:
*
* pqissllistener -> pqissllistener (tcp only)
* -> pqixpgplistener (tcp only)
*
* pqissl -> pqissltcp
* -> pqissludp
* -> pqixpgptcp
* -> pqixpgpudp
*
*/
class pqissl;
class cert;
class pqissltunnellistener;
class p3LinkMgr;
struct data_with_length {
int length;
void *data;
};
class pqissltunnel: public NetBinInterface
{
public:
pqissltunnel(PQInterface *parent, p3LinkMgr *cm, p3tunnel *p3t);
virtual ~pqissltunnel();
// NetInterface
//the addr is not used for the tunnel
virtual int connect(struct sockaddr_in raddr);
virtual int listen();
virtual int stoplistening();
virtual int reset();
virtual int disconnect();
virtual int getConnectAddress(struct sockaddr_in &raddr);
virtual bool connect_parameter(uint32_t type, uint32_t value);
// BinInterface
virtual int tick();
virtual int status();
virtual int senddata(void*, int);
virtual int readdata(void*, int);
virtual int netstatus();
virtual int isactive();
virtual bool moretoread();
virtual bool cansend();
virtual int close(); /* BinInterface version of reset() */
virtual std::string gethash(); /* not used here */
virtual bool bandwidthLimited() { return true ; } // replace by !sameLAN to avoid bandwidth limiting on lAN
//called by the p3tunnel service to add incoming packets that will be read by the read data function.
void addIncomingPacket(void* encoded_data, int data_length);
void IncommingPingPacket();
void IncommingHanshakePacket(std::string incRelayPeerId);
private:
//if no packet (last_time_packet_time) is received since PING_RECEIVE_TIME_OUT, let's assume the connection is broken
int last_normal_connection_attempt_time;
//if no packet (last_time_packet_time) is received since PING_RECEIVE_TIME_OUT, let's assume the connection is broken
int last_packet_time;
//send a ping on a regular basis
int last_ping_send_time;
int ConnectAttempt();
void spam_handshake();
int waiting;
bool active;
time_t resetTime;
pqissltunnellistener *pqil;
/* Need Certificate specific functions here! */
time_t mConnectTS;
p3LinkMgr *mLinkMgr;
p3tunnel *mP3tunnel;
std::list<data_with_length> data_packet_queue;
data_with_length curent_data_packet;
int current_data_offset;
//tunneling details
std::string relayPeerId;
};
#endif // MRK_PQI_SSL_HEADER

View file

@ -30,7 +30,7 @@
#include "tcponudp/bio_tou.h"
#include <errno.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include "util/rsdebug.h"
@ -38,6 +38,7 @@
#include "util/rsstring.h"
#include "pqi/p3linkmgr.h"
#include <unistd.h>
const int pqissludpzone = 3144;
@ -54,7 +55,9 @@ pqissludp::pqissludp(PQInterface *parent, p3LinkMgr *lm)
:pqissl(NULL, parent, lm), tou_bio(NULL),
listen_checktime(0), mConnectPeriod(PQI_SSLUDP_DEF_CONN_PERIOD)
{
sockaddr_clear(&remote_addr);
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
sockaddr_storage_clear(remote_addr);
return;
}
@ -74,6 +77,8 @@ pqissludp::~pqissludp()
stoplistening(); /* remove from p3proxy listenqueue */
reset();
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
if (tou_bio) // this should be in the reset?
{
BIO_free(tou_bio);
@ -81,12 +86,13 @@ pqissludp::~pqissludp()
return;
}
int pqissludp::reset()
int pqissludp::reset_locked()
{
/* reset for next time.*/
mConnectFlags = 0;
mConnectPeriod = PQI_SSLUDP_DEF_CONN_PERIOD;
return pqissl::reset();
return pqissl::reset_locked();
}
@ -150,7 +156,7 @@ int pqissludp::Initiate_Connection()
int err;
attach(); /* open socket */
remote_addr.sin_family = AF_INET;
//remote_addr.sin_family = AF_INET;
rslog(RSL_DEBUG_BASIC, pqissludpzone,
"pqissludp::Initiate_Connection() Attempting Outgoing Connection....");
@ -196,7 +202,10 @@ int pqissludp::Initiate_Connection()
{
std::string out = "pqissludp::Initiate_Connection() Connecting To: " + PeerId();
rs_sprintf(out, " via: %s:%u", rs_inet_ntoa(remote_addr.sin_addr).c_str(), ntohs(remote_addr.sin_port));
out += " via: ";
out += sockaddr_storage_tostring(remote_addr);
out += " ";
if (sslmode)
{
out += "ACTIVE Connect (SSL_Connect)";
@ -208,12 +217,12 @@ int pqissludp::Initiate_Connection()
rslog(RSL_WARNING, pqissludpzone, out);
}
if (remote_addr.sin_addr.s_addr == 0)
if (sockaddr_storage_isnull(remote_addr))
{
rslog(RSL_WARNING, pqissludpzone, "pqissludp::Initiate_Connection() Invalid (0.0.0.0) Remote Address, Aborting Connect.");
waiting = WAITING_FAIL_INTERFACE;
reset();
reset_locked();
return -1;
}
@ -234,11 +243,48 @@ int pqissludp::Initiate_Connection()
else if (mConnectFlags & RS_CB_FLAG_MODE_UDP_RELAY)
{
std::cerr << "Calling tou_connect_via_relay(";
std::cerr << mConnectSrcAddr << ",";
std::cerr << mConnectProxyAddr << ",";
std::cerr << remote_addr << ")" << std::endl;
std::cerr << sockaddr_storage_tostring(mConnectSrcAddr) << ",";
std::cerr << sockaddr_storage_tostring(mConnectProxyAddr) << ",";
std::cerr << sockaddr_storage_tostring(remote_addr) << ")" << std::endl;
tou_connect_via_relay(sockfd, &(mConnectSrcAddr), &(mConnectProxyAddr), &(remote_addr));
{
std::cerr << "CONVERTING ALL ADDRESSES TO IPV4: TODO make IPV6";
std::cerr << std::endl;
struct sockaddr_in srcaddr;
struct sockaddr_in proxyaddr;
struct sockaddr_in remoteaddr;
if ((mConnectSrcAddr.ss_family != AF_INET) ||
(mConnectProxyAddr.ss_family != AF_INET) ||
(remote_addr.ss_family != AF_INET))
{
std::cerr << "Error One Address is not IPv4. aborting";
std::cerr << std::endl;
abort();
}
struct sockaddr_in *rap = (struct sockaddr_in *) &remote_addr;
struct sockaddr_in *pap = (struct sockaddr_in *) &mConnectProxyAddr;
struct sockaddr_in *sap = (struct sockaddr_in *) &mConnectSrcAddr;
srcaddr.sin_family = AF_INET;
proxyaddr.sin_family = AF_INET;
remoteaddr.sin_family = AF_INET;
srcaddr.sin_addr = sap->sin_addr;
proxyaddr.sin_addr = pap->sin_addr;
remoteaddr.sin_addr = rap->sin_addr;
srcaddr.sin_port = sap->sin_port;
proxyaddr.sin_port = pap->sin_port;
remoteaddr.sin_port = rap->sin_port;
tou_connect_via_relay(sockfd, &srcaddr, &proxyaddr, &remoteaddr);
}
/*** It seems that the UDP Layer sees x 1.2 the traffic of the SSL layer.
* We need to compensate somewhere... we drop the maximum traffic to 75% of limit
@ -282,7 +328,7 @@ int pqissludp::Initiate_Connection()
rslog(RSL_WARNING, pqissludpzone, out);
reset();
reset_locked();
return -1;
}
@ -306,21 +352,11 @@ int pqissludp::Basic_Connection_Complete()
rslog(RSL_DEBUG_BASIC, pqissludpzone,
"pqissludp::Basic_Connection_Complete()...");
if (time(NULL) > mTimeoutTS)
if (CheckConnectionTimeout())
{
std::string out = "pqissludp::Basic_Connection_Complete() Connection Timed Out. Peer: " + PeerId();
rs_sprintf_append(out, " Period: %lu", mConnectTimeout);
rslog(RSL_WARNING, pqissludpzone, out);
/* as sockfd is valid, this should close it all up */
reset();
return -1;
}
if (waiting != WAITING_SOCK_CONNECT)
{
rslog(RSL_DEBUG_BASIC, pqissludpzone,
@ -347,7 +383,7 @@ int pqissludp::Basic_Connection_Complete()
rs_sprintf_append(out, "Error: Connection Failed: %d - %s", err, socket_errorType(err).c_str());
rslog(RSL_DEBUG_BASIC, pqissludpzone, out);
reset();
reset_locked();
// Then send unreachable message.
waiting = WAITING_FAIL_INTERFACE;
@ -438,77 +474,102 @@ int pqissludp::stoplistening()
bool pqissludp::connect_parameter(uint32_t type, uint32_t value)
{
//std::cerr << "pqissludp::connect_parameter() type: " << type << "value: " << value << std::endl;
if (type == NET_PARAM_CONNECT_PERIOD)
{
std::string out;
rs_sprintf(out, "pqissludp::connect_parameter() Peer: %s PERIOD: %lu", PeerId().c_str(), value);
rslog(RSL_WARNING, pqissludpzone, out);
mConnectPeriod = value;
std::cerr << out << std::endl;
return true;
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
//std::cerr << "pqissludp::connect_parameter() type: " << type << "value: " << value << std::endl;
if (type == NET_PARAM_CONNECT_PERIOD)
{
std::string out;
rs_sprintf(out, "pqissludp::connect_parameter() Peer: %s PERIOD: %lu", PeerId().c_str(), value);
rslog(RSL_WARNING, pqissludpzone, out);
mConnectPeriod = value;
std::cerr << out << std::endl;
return true;
}
else if (type == NET_PARAM_CONNECT_FLAGS)
{
std::string out;
rs_sprintf(out, "pqissludp::connect_parameter() Peer: %s FLAGS: %lu", PeerId().c_str(), value);
rslog(RSL_WARNING, pqissludpzone, out);
mConnectFlags = value;
std::cerr << out<< std::endl;
return true;
}
else if (type == NET_PARAM_CONNECT_BANDWIDTH)
{
std::string out;
rs_sprintf(out, "pqissludp::connect_parameter() Peer: %s BANDWIDTH: %lu", PeerId().c_str(), value);
rslog(RSL_WARNING, pqissludpzone, out);
mConnectBandwidth = value;
std::cerr << out << std::endl;
return true;
}
}
else if (type == NET_PARAM_CONNECT_FLAGS)
{
std::string out;
rs_sprintf(out, "pqissludp::connect_parameter() Peer: %s FLAGS: %lu", PeerId().c_str(), value);
rslog(RSL_WARNING, pqissludpzone, out);
mConnectFlags = value;
std::cerr << out<< std::endl;
return true;
}
else if (type == NET_PARAM_CONNECT_BANDWIDTH)
{
std::string out;
rs_sprintf(out, "pqissludp::connect_parameter() Peer: %s BANDWIDTH: %lu", PeerId().c_str(), value);
rslog(RSL_WARNING, pqissludpzone, out);
mConnectBandwidth = value;
std::cerr << out << std::endl;
return true;
}
return pqissl::connect_parameter(type, value);
}
bool pqissludp::connect_additional_address(uint32_t type, struct sockaddr_in *addr)
bool pqissludp::connect_additional_address(uint32_t type, const struct sockaddr_storage &addr)
{
if (type == NET_PARAM_CONNECT_PROXY)
{
std::string out;
rs_sprintf(out, "pqissludp::connect_additional_address() Peer: %s PROXYADDR: %s:%u", PeerId().c_str(), rs_inet_ntoa(addr->sin_addr).c_str(), ntohs(addr->sin_port));
rslog(RSL_WARNING, pqissludpzone, out);
mConnectProxyAddr = *addr;
std::cerr << out << std::endl;
return true;
}
else if (type == NET_PARAM_CONNECT_SOURCE)
{
std::string out;
rs_sprintf(out, "pqissludp::connect_additional_address() Peer: %s SRCADDR: %s:%u", PeerId().c_str(), rs_inet_ntoa(addr->sin_addr).c_str(), ntohs(addr->sin_port));
rslog(RSL_WARNING, pqissludpzone, out);
mConnectSrcAddr = *addr;
std::cerr << out << std::endl;
return true;
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
if (type == NET_PARAM_CONNECT_PROXY)
{
std::string out;
rs_sprintf(out, "pqissludp::connect_additional_address() Peer: %s PROXYADDR: ", PeerId().c_str());
out += sockaddr_storage_tostring(addr);
rslog(RSL_WARNING, pqissludpzone, out);
mConnectProxyAddr = addr;
std::cerr << out << std::endl;
return true;
}
else if (type == NET_PARAM_CONNECT_SOURCE)
{
std::string out;
rs_sprintf(out, "pqissludp::connect_additional_address() Peer: %s SRCADDR: ", PeerId().c_str());
out += sockaddr_storage_tostring(addr);
rslog(RSL_WARNING, pqissludpzone, out);
mConnectSrcAddr = addr;
std::cerr << out << std::endl;
return true;
}
}
return pqissl::connect_additional_address(type, addr);
}
/********** PQI STREAMER OVERLOADING *********************************/
bool pqissludp::moretoread()
bool pqissludp::moretoread(uint32_t usec)
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
{
std::string out = "pqissludp::moretoread()";
rs_sprintf_append(out, " polling socket (%d)", sockfd);
rslog(RSL_DEBUG_ALL, pqissludpzone, out);
}
if (usec)
{
std::cerr << "pqissludp::moretoread() usec parameter: " << usec;
std::cerr << std::endl;
if (0 < tou_maxread(sockfd))
{
return true;
}
usleep(usec);
}
/* check for more to read first ... if nothing... check error
*/
/* <===================== UDP Difference *******************/
@ -548,7 +609,7 @@ bool pqissludp::moretoread()
rslog(RSL_WARNING, pqissludpzone, out);
}
reset();
reset_locked();
return 0;
}
@ -561,8 +622,23 @@ bool pqissludp::moretoread()
}
bool pqissludp::cansend()
bool pqissludp::cansend(uint32_t usec)
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
if (usec)
{
std::cerr << "pqissludp::cansend() usec parameter: " << usec;
std::cerr << std::endl;
if (0 < tou_maxwrite(sockfd))
{
return true;
}
usleep(usec);
}
rslog(RSL_DEBUG_ALL, pqissludpzone,
"pqissludp::cansend() polling socket!");

View file

@ -28,8 +28,6 @@
#ifndef MRK_PQI_SSL_UDP_HEADER
#define MRK_PQI_SSL_UDP_HEADER
#include <openssl/ssl.h>
// operating system specific network header.
#include "pqi/pqinetwork.h"
@ -64,23 +62,24 @@ virtual ~pqissludp();
virtual int listen();
virtual int stoplistening();
virtual int tick();
virtual int reset();
virtual bool connect_parameter(uint32_t type, uint32_t value);
virtual bool connect_additional_address(uint32_t type, struct sockaddr_in *addr);
virtual bool connect_additional_address(uint32_t type, const struct sockaddr_storage &addr);
// BinInterface.
// These are reimplemented.
virtual bool moretoread();
virtual bool cansend();
virtual bool moretoread(uint32_t usec);
virtual bool cansend(uint32_t usec);
/* UDP always through firewalls -> always bandwidth Limited */
virtual bool bandwidthLimited() { return true; }
protected:
// pqissludp specific.
// called to initiate a connection;
int attach();
protected:
virtual int reset_locked();
virtual int Initiate_Connection();
virtual int Basic_Connection_Complete();
@ -103,8 +102,8 @@ private:
uint32_t mConnectFlags;
uint32_t mConnectBandwidth;
struct sockaddr_in mConnectProxyAddr;
struct sockaddr_in mConnectSrcAddr;
struct sockaddr_storage mConnectProxyAddr;
struct sockaddr_storage mConnectSrcAddr;
};
#endif // MRK_PQI_SSL_UDP_HEADER

View file

@ -155,8 +155,7 @@ RsItem *pqistore::GetItem()
#ifdef PQISTORE_DEBUG
if (outPkt != NULL)
{
std::string out;
rs_sprintf(out, "pqistore::GetItem() Returning:\n");
std::string out = "pqistore::GetItem() Returning:\n";
outPkt -> print(out);
pqioutput(PQL_DEBUG_BASIC, pqistorezone, out);
}
@ -226,7 +225,7 @@ int pqistore::writePkt(RsItem *pqi)
}
if (!(bio->cansend()))
if (!(bio->cansend(0)))
{
std::string out;
rs_sprintf(out, "pqistore::writePkt() BIO cannot write!\niscarding:\n");
@ -281,9 +280,9 @@ int pqistore::readPkt(RsItem **item_out)
#endif
bStopReading = false ;
if ((!(bio->isactive())) || (!(bio->moretoread())))
if ((!(bio->isactive())) || (!(bio->moretoread(0))))
{
bStopReading = true ;
bStopReading = true ;
return 0;
}
@ -431,7 +430,7 @@ bool pqiSSLstore::getEncryptedItems(std::list<RsItem* >& rsItemList)
if (NULL != (item = GetItem()))
rsItemList.push_back(item);
} while (enc_bio->isactive() && enc_bio->moretoread() && !bStopReading);
} while (enc_bio->isactive() && enc_bio->moretoread(0) && !bStopReading);
return true;
}
@ -488,7 +487,7 @@ int pqiSSLstore::readPkt(RsItem **item_out)
#endif
bStopReading=false ;
if ((!(enc_bio->isactive())) || (!(enc_bio->moretoread())))
if ((!(enc_bio->isactive())) || (!(enc_bio->moretoread(0))))
{
bStopReading=true ;
return 0;

View file

@ -34,7 +34,6 @@
#include "rsserver/p3face.h"
#include "serialiser/rsserial.h"
#include "serialiser/rsbaseitems.h" /***** For RsFileData *****/
const int pqistreamerzone = 8221;
@ -47,29 +46,30 @@ const int PQISTREAM_ABS_MAX = 100000000; /* 100 MB/sec (actually per loop) */
#define DEBUG_PQISTREAMER 1
***/
#ifdef DEBUG_TRANSFERS
#include "util/rsprint.h"
#endif
pqistreamer::pqistreamer(RsSerialiser *rss, std::string id, BinInterface *bio_in, int bio_flags_in)
:PQInterface(id), rsSerialiser(rss), bio(bio_in), bio_flags(bio_flags_in),
pkt_wpending(NULL),
totalRead(0), totalSent(0),
currRead(0), currSent(0),
avgReadCount(0), avgSentCount(0), streamerMtx("pqistreamer")
:PQInterface(id), mStreamerMtx("pqistreamer"),
mBio(bio_in), mBio_flags(bio_flags_in), mRsSerialiser(rss),
mPkt_wpending(NULL),
mTotalRead(0), mTotalSent(0),
mCurrRead(0), mCurrSent(0),
mAvgReadCount(0), mAvgSentCount(0)
{
avgLastUpdate = currReadTS = currSentTS = time(NULL);
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
mAvgLastUpdate = mCurrReadTS = mCurrSentTS = time(NULL);
/* allocated once */
pkt_rpend_size = getRsPktMaxSize();
pkt_rpending = malloc(pkt_rpend_size);
reading_state = reading_state_initial ;
mPkt_rpend_size = getRsPktMaxSize();
mPkt_rpending = malloc(mPkt_rpend_size);
mReading_state = reading_state_initial ;
// thread_id = pthread_self() ;
// avoid uninitialized (and random) memory read.
memset(pkt_rpending,0,pkt_rpend_size) ;
memset(mPkt_rpending,0,mPkt_rpend_size) ;
// 100 B/s (minimal)
setMaxRate(true, 0.1);
@ -85,48 +85,48 @@ pqistreamer::pqistreamer(RsSerialiser *rss, std::string id, BinInterface *bio_in
exit(1);
}
failed_read_attempts = 0 ; // reset failed read, as no packet is still read.
mFailed_read_attempts = 0; // reset failed read, as no packet is still read.
return;
}
pqistreamer::~pqistreamer()
{
RsStackMutex stack(streamerMtx) ; // lock out_pkt and out_data
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::~pqistreamer() Destruction!");
if (bio_flags & BIN_FLAGS_NO_CLOSE)
if (mBio_flags & BIN_FLAGS_NO_CLOSE)
{
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::~pqistreamer() Not Closing BinInterface!");
}
else if (bio)
else if (mBio)
{
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::~pqistreamer() Deleting BinInterface!");
delete bio;
delete mBio;
}
/* clean up serialiser */
if (rsSerialiser)
delete rsSerialiser;
if (mRsSerialiser)
delete mRsSerialiser;
// clean up outgoing. (cntrl packets)
locked_clear_out_queue() ;
if (pkt_wpending)
if (mPkt_wpending)
{
free(pkt_wpending);
pkt_wpending = NULL;
free(mPkt_wpending);
mPkt_wpending = NULL;
}
free(pkt_rpending);
free(mPkt_rpending);
// clean up incoming.
while(incoming.size() > 0)
while(mIncoming.size() > 0)
{
RsItem *i = incoming.front();
incoming.pop_front();
RsItem *i = mIncoming.front();
mIncoming.pop_front();
delete i;
}
return;
@ -145,7 +145,9 @@ int pqistreamer::SendItem(RsItem *si,uint32_t& out_size)
}
#endif
return queue_outpqi(si,out_size);
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
return queue_outpqi_locked(si,out_size);
}
RsItem *pqistreamer::GetItem()
@ -154,12 +156,13 @@ RsItem *pqistreamer::GetItem()
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::GetItem()");
#endif
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
if(incoming.empty())
if(mIncoming.empty())
return NULL;
RsItem *osr = incoming.front() ;
incoming.pop_front() ;
RsItem *osr = mIncoming.front() ;
mIncoming.pop_front() ;
return osr;
}
@ -167,31 +170,26 @@ RsItem *pqistreamer::GetItem()
// // PQInterface
int pqistreamer::tick()
{
#ifdef DEBUG_PQISTREAMER
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
std::string out = "pqistreamer::tick()\n" + PeerId();
rs_sprintf_append(out, ": currRead/Sent: %d/%d", currRead, currSent);
rs_sprintf_append(out, ": currRead/Sent: %d/%d", mCurrRead, mCurrSent);
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out);
}
#endif
bio->tick();
/* short circuit everything is bio isn't active */
if (!(bio->isactive()))
if (!tick_bio())
{
return 0;
}
tick_recv(0);
tick_send(0);
/* must do both, as outgoing will catch some bad sockets,
* that incoming will not
*/
handleincoming();
handleoutgoing();
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
#ifdef DEBUG_PQISTREAMER
/* give details of the packets */
{
@ -199,7 +197,7 @@ int pqistreamer::tick()
std::string out = "pqistreamer::tick() Queued Data: for " + PeerId();
if (bio->isactive())
if (mBio->isactive())
{
out += " (active)";
}
@ -210,11 +208,10 @@ int pqistreamer::tick()
out += "\n";
{
RsStackMutex stack(streamerMtx) ; // lock out_pkt and out_data
int total = compute_out_pkt_size() ;
int total = locked_compute_out_pkt_size() ;
rs_sprintf_append(out, "\t Out Packets [%d] => %d bytes\n", out_queue_size(), total);
rs_sprintf_append(out, "\t Incoming [%d]\n", incoming.size());
rs_sprintf_append(out, "\t Out Packets [%d] => %d bytes\n", locked_out_queue_size(), total);
rs_sprintf_append(out, "\t Incoming [%d]\n", mIncoming.size());
}
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out);
@ -222,22 +219,68 @@ int pqistreamer::tick()
#endif
/* if there is more stuff in the queues */
if ((incoming.size() > 0) || (out_queue_size() > 0))
if ((mIncoming.size() > 0) || (locked_out_queue_size() > 0))
{
return 1;
}
return 0;
}
int pqistreamer::tick_bio()
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
mBio->tick();
/* short circuit everything is bio isn't active */
if (!(mBio->isactive()))
{
return 0;
}
return 1;
}
int pqistreamer::tick_recv(uint32_t timeout)
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
if (mBio->moretoread(timeout))
{
handleincoming_locked();
}
return 1;
}
int pqistreamer::tick_send(uint32_t timeout)
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
/* short circuit everything is bio isn't active */
if (!(mBio->isactive()))
{
return 0;
}
if (mBio->cansend(timeout))
{
handleoutgoing_locked();
}
return 1;
}
int pqistreamer::status()
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
#ifdef DEBUG_PQISTREAMER
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::status()");
if (bio->isactive())
if (mBio->isactive())
{
std::string out;
rs_sprintf(out, "Data in:%d out:%d", totalRead, totalSent);
rs_sprintf(out, "Data in:%d out:%d", mTotalRead, mTotalSent);
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out);
}
#endif
@ -247,44 +290,32 @@ int pqistreamer::status()
void pqistreamer::locked_storeInOutputQueue(void *ptr,int)
{
out_pkt.push_back(ptr);
mOutPkts.push_back(ptr);
}
//
/**************** HANDLE OUTGOING TRANSLATION + TRANSMISSION ******/
int pqistreamer::queue_outpqi(RsItem *pqi,uint32_t& pktsize)
int pqistreamer::queue_outpqi_locked(RsItem *pqi,uint32_t& pktsize)
{
pktsize = 0 ;
#ifdef DEBUG_PQISTREAMER
std::cerr << "pqistreamer::queue_outpqi() called." << std::endl;
#endif
RsStackMutex stack(streamerMtx) ; // lock out_pkt and out_data
// This is called by different threads, and by threads that are not the handleoutgoing thread,
// so it should be protected by a mutex !!
#ifdef DEBUG_PQISTREAMER
if(dynamic_cast<RsFileData*>(pqi)!=NULL && (bio_flags & BIN_FLAGS_NO_DELETE))
{
std::cerr << "Having file data with flags = " << bio_flags << std::endl ;
}
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::queue_outpqi()");
#endif
/* decide which type of packet it is */
pktsize = rsSerialiser->size(pqi);
pktsize = mRsSerialiser->size(pqi);
void *ptr = malloc(pktsize);
#ifdef DEBUG_PQISTREAMER
std::cerr << "pqistreamer::queue_outpqi() serializing packet with packet size : " << pktsize << std::endl;
#endif
if (rsSerialiser->serialise(pqi, ptr, &pktsize))
if (mRsSerialiser->serialise(pqi, ptr, &pktsize))
{
locked_storeInOutputQueue(ptr,pqi->priority_level()) ;
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
if (!(mBio_flags & BIN_FLAGS_NO_DELETE))
{
delete pqi;
}
@ -300,41 +331,42 @@ int pqistreamer::queue_outpqi(RsItem *pqi,uint32_t& pktsize)
pqi -> print_string(out);
pqioutput(PQL_ALERT, pqistreamerzone, out);
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
if (!(mBio_flags & BIN_FLAGS_NO_DELETE))
{
delete pqi;
}
return 1; // keep error internal.
}
int pqistreamer::handleincomingitem(RsItem *pqi)
int pqistreamer::handleincomingitem_locked(RsItem *pqi)
{
#ifdef DEBUG_PQISTREAMER
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::handleincomingitem()");
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::handleincomingitem_locked()");
#endif
// timestamp last received packet.
mLastIncomingTs = time(NULL);
// Use overloaded Contact function
pqi -> PeerId(PeerId());
incoming.push_back(pqi);
mIncoming.push_back(pqi);
return 1;
}
time_t pqistreamer::getLastIncomingTS()
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
return mLastIncomingTs;
}
int pqistreamer::handleoutgoing()
int pqistreamer::handleoutgoing_locked()
{
RsStackMutex stack(streamerMtx) ; // lock out_pkt and out_data
#ifdef DEBUG_PQISTREAMER
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::handleoutgoing()");
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::handleoutgoing_locked()");
#endif
int maxbytes = outAllowedBytes();
int maxbytes = outAllowedBytes_locked();
int sentbytes = 0;
int len;
int ss;
@ -343,19 +375,19 @@ int pqistreamer::handleoutgoing()
std::list<void *>::iterator it;
// if not connection, or cannot send anything... pause.
if (!(bio->isactive()))
if (!(mBio->isactive()))
{
/* if we are not active - clear anything in the queues. */
locked_clear_out_queue() ;
/* also remove the pending packets */
if (pkt_wpending)
if (mPkt_wpending)
{
free(pkt_wpending);
pkt_wpending = NULL;
free(mPkt_wpending);
mPkt_wpending = NULL;
}
outSentBytes(sentbytes);
outSentBytes_locked(sentbytes);
return 0;
}
@ -366,41 +398,41 @@ int pqistreamer::handleoutgoing()
{
sent = false;
if ((!(bio->cansend())) || (maxbytes < sentbytes))
if ((!(mBio->cansend(0))) || (maxbytes < sentbytes))
{
#ifdef DEBUG_TRANSFERS
if (maxbytes < sentbytes)
{
std::cerr << "pqistreamer::handleoutgoing() Stopped sending sentbytes > maxbytes. Sent " << sentbytes << " bytes ";
std::cerr << "pqistreamer::handleoutgoing_locked() Stopped sending sentbytes > maxbytes. Sent " << sentbytes << " bytes ";
std::cerr << std::endl;
}
else
{
std::cerr << "pqistreamer::handleoutgoing() Stopped sending at cansend() is false";
std::cerr << "pqistreamer::handleoutgoing_locked() Stopped sending at cansend() is false";
std::cerr << std::endl;
}
#endif
outSentBytes(sentbytes);
outSentBytes_locked(sentbytes);
return 0;
}
// send a out_pkt., else send out_data. unless
// there is a pending packet.
if (!pkt_wpending)
pkt_wpending = locked_pop_out_data() ;
if (!mPkt_wpending)
mPkt_wpending = locked_pop_out_data() ;
if (pkt_wpending)
if (mPkt_wpending)
{
// write packet.
len = getRsItemSize(pkt_wpending);
len = getRsItemSize(mPkt_wpending);
#ifdef DEBUG_PQISTREAMER
std::cout << "Sending Out Pkt of size " << len << " !" << std::endl;
#endif
if (len != (ss = bio->senddata(pkt_wpending, len)))
if (len != (ss = mBio->senddata(mPkt_wpending, len)))
{
#ifdef DEBUG_PQISTREAMER
std::string out;
@ -409,60 +441,60 @@ int pqistreamer::handleoutgoing()
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out);
#endif
outSentBytes(sentbytes);
outSentBytes_locked(sentbytes);
// pkt_wpending will kept til next time.
// ensuring exactly the same data is written (openSSL requirement).
return -1;
}
#ifdef DEBUG_TRANSFERS
std::cerr << "pqistreamer::handleoutgoing() Sent Packet len: " << len << " @ " << RsUtil::AccurateTimeString();
std::cerr << "pqistreamer::handleoutgoing_locked() Sent Packet len: " << len << " @ " << RsUtil::AccurateTimeString();
std::cerr << std::endl;
#endif
free(pkt_wpending);
pkt_wpending = NULL;
free(mPkt_wpending);
mPkt_wpending = NULL;
sentbytes += len;
sent = true;
}
}
outSentBytes(sentbytes);
outSentBytes_locked(sentbytes);
return 1;
}
/* Handles reading from input stream.
*/
int pqistreamer::handleincoming()
int pqistreamer::handleincoming_locked()
{
int readbytes = 0;
static const int max_failed_read_attempts = 2000 ;
#ifdef DEBUG_PQISTREAMER
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::handleincoming()");
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::handleincoming_locked()");
#endif
if(!(bio->isactive()))
if(!(mBio->isactive()))
{
reading_state = reading_state_initial ;
inReadBytes(readbytes);
mReading_state = reading_state_initial ;
inReadBytes_locked(readbytes);
return 0;
}
// enough space to read any packet.
int maxlen = pkt_rpend_size;
void *block = pkt_rpending;
int maxlen = mPkt_rpend_size;
void *block = mPkt_rpending;
// initial read size: basic packet.
int blen = getRsPktBaseSize();
int maxin = inAllowedBytes();
int maxin = inAllowedBytes_locked();
#ifdef DEBUG_PQISTREAMER
std::cerr << "[" << (void*)pthread_self() << "] " << "reading state = " << reading_state << std::endl ;
std::cerr << "[" << (void*)pthread_self() << "] " << "reading state = " << mReading_state << std::endl ;
#endif
switch(reading_state)
switch(mReading_state)
{
case reading_state_initial: /*std::cerr << "jumping to start" << std::endl; */ goto start_packet_read ;
case reading_state_packet_started: /*std::cerr << "jumping to middle" << std::endl;*/ goto continue_packet ;
@ -477,11 +509,11 @@ start_packet_read:
#endif
memset(block,0,blen) ; // reset the block, to avoid uninitialized memory reads.
if (blen != (tmplen = bio->readdata(block, blen)))
if (blen != (tmplen = mBio->readdata(block, blen)))
{
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, "pqistreamer::handleincoming() Didn't read BasePkt!");
inReadBytes(readbytes);
inReadBytes_locked(readbytes);
// error.... (either blocked or failure)
if (tmplen == 0)
@ -500,7 +532,7 @@ start_packet_read:
//
//pqioutput(PQL_WARNING, pqistreamerzone, "pqistreamer::handleincoming() Error in bio read");
#ifdef DEBUG_PQISTREAMER
std::cerr << "[" << (void*)pthread_self() << "] " << "given up 2, state = " << reading_state << std::endl ;
std::cerr << "[" << (void*)pthread_self() << "] " << "given up 2, state = " << mReading_state << std::endl ;
#endif
return 0;
}
@ -527,8 +559,8 @@ start_packet_read:
#endif
readbytes += blen;
reading_state = reading_state_packet_started ;
failed_read_attempts = 0 ; // reset failed read, as the packet has been totally read.
mReading_state = reading_state_packet_started ;
mFailed_read_attempts = 0 ; // reset failed read, as the packet has been totally read.
}
continue_packet:
{
@ -539,7 +571,7 @@ continue_packet:
std::cerr << "[" << (void*)pthread_self() << "] " << "continuing packet getRsItemSize(block) = " << getRsItemSize(block) << std::endl ;
std::cerr << "[" << (void*)pthread_self() << "] " << "continuing packet extralen = " << extralen << std::endl ;
std::cerr << "[" << (void*)pthread_self() << "] " << "continuing packet state=" << reading_state << std::endl ;
std::cerr << "[" << (void*)pthread_self() << "] " << "continuing packet state=" << mReading_state << std::endl ;
std::cerr << "[" << (void*)pthread_self() << "] " << "block 1 : " << (int)(((unsigned char*)block)[0]) << " " << (int)(((unsigned char*)block)[1]) << " " << (int)(((unsigned char*)block)[2]) << " " << (int)(((unsigned char*)block)[3]) << " "
<< (int)(((unsigned char*)block)[4]) << " "
<< (int)(((unsigned char*)block)[5]) << " "
@ -590,9 +622,9 @@ continue_packet:
std::cerr << std::endl;
}
bio->close();
reading_state = reading_state_initial ; // restart at state 1.
failed_read_attempts = 0 ;
mBio->close();
mReading_state = reading_state_initial ; // restart at state 1.
mFailed_read_attempts = 0 ;
return -1;
// Used to exit now! exit(1);
@ -611,14 +643,14 @@ continue_packet:
// so, don't do that:
// memset( extradata,0,extralen ) ;
if (extralen != (tmplen = bio->readdata(extradata, extralen)))
if (extralen != (tmplen = mBio->readdata(extradata, extralen)))
{
#ifdef DEBUG_PQISTREAMER
if(tmplen > 0)
std::cerr << "[" << (void*)pthread_self() << "] " << "Incomplete packet read ! This is a real problem ;-)" << std::endl ;
#endif
if(++failed_read_attempts > max_failed_read_attempts)
if(++mFailed_read_attempts > max_failed_read_attempts)
{
std::string out;
rs_sprintf(out, "Error Completing Read (read %d/%d)", tmplen, extralen);
@ -655,22 +687,22 @@ continue_packet:
std::cerr << msgout << std::endl;
}
bio->close();
reading_state = reading_state_initial ; // restart at state 1.
failed_read_attempts = 0 ;
mBio->close();
mReading_state = reading_state_initial ; // restart at state 1.
mFailed_read_attempts = 0 ;
return -1;
}
else
{
#ifdef DEBUG_PQISTREAMER
std::cerr << "[" << (void*)pthread_self() << "] " << "given up 5, state = " << reading_state << std::endl ;
std::cerr << "[" << (void*)pthread_self() << "] " << "given up 5, state = " << mReading_state << std::endl ;
#endif
return 0 ; // this is just a SSL_WANT_READ error. Don't panic, we'll re-try the read soon.
// we assume readdata() returned either -1 or the complete read size.
}
}
#ifdef DEBUG_PQISTREAMER
std::cerr << "[" << (void*)pthread_self() << "] " << "continuing packet state=" << reading_state << std::endl ;
std::cerr << "[" << (void*)pthread_self() << "] " << "continuing packet state=" << mReading_state << std::endl ;
std::cerr << "[" << (void*)pthread_self() << "] " << "block 2 : " << (int)(((unsigned char*)extradata)[0]) << " " << (int)(((unsigned char*)extradata)[1]) << " " << (int)(((unsigned char*)extradata)[2]) << " " << (int)(((unsigned char*)extradata)[3]) << " "
<< (int)(((unsigned char*)extradata)[4]) << " "
<< (int)(((unsigned char*)extradata)[5]) << " "
@ -678,7 +710,7 @@ continue_packet:
<< (int)(((unsigned char*)extradata)[7]) << " " << std::endl ;
#endif
failed_read_attempts = 0 ;
mFailed_read_attempts = 0 ;
readbytes += extralen;
}
@ -706,9 +738,9 @@ continue_packet:
// fclose(f) ;
// exit(-1) ;
// }
RsItem *pkt = rsSerialiser->deserialise(block, &pktlen);
RsItem *pkt = mRsSerialiser->deserialise(block, &pktlen);
if ((pkt != NULL) && (0 < handleincomingitem(pkt)))
if ((pkt != NULL) && (0 < handleincomingitem_locked(pkt)))
{
#ifdef DEBUG_PQISTREAMER
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, "Successfully Read a Packet!");
@ -721,11 +753,11 @@ continue_packet:
#endif
}
reading_state = reading_state_initial ; // restart at state 1.
failed_read_attempts = 0 ; // reset failed read, as the packet has been totally read.
mReading_state = reading_state_initial ; // restart at state 1.
mFailed_read_attempts = 0 ; // reset failed read, as the packet has been totally read.
}
if(maxin > readbytes && bio->moretoread())
if(maxin > readbytes && mBio->moretoread(0))
goto start_packet_read ;
#ifdef DEBUG_TRANSFERS
@ -736,14 +768,14 @@ continue_packet:
}
#endif
inReadBytes(readbytes);
inReadBytes_locked(readbytes);
return 0;
}
/* BandWidth Management Assistance */
float pqistreamer::outTimeSlice()
float pqistreamer::outTimeSlice_locked()
{
#ifdef DEBUG_PQISTREAMER
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::outTimeSlice()");
@ -754,87 +786,87 @@ float pqistreamer::outTimeSlice()
}
// very simple.....
int pqistreamer::outAllowedBytes()
int pqistreamer::outAllowedBytes_locked()
{
int t = time(NULL); // get current timestep.
/* allow a lot if not bandwidthLimited */
if (!bio->bandwidthLimited())
if (!mBio->bandwidthLimited())
{
currSent = 0;
currSentTS = t;
mCurrSent = 0;
mCurrSentTS = t;
return PQISTREAM_ABS_MAX;
}
int dt = t - currSentTS;
int dt = t - mCurrSentTS;
// limiter -> for when currSentTs -> 0.
if (dt > 5)
dt = 5;
int maxout = (int) (getMaxRate(false) * 1000.0);
currSent -= dt * maxout;
if (currSent < 0)
mCurrSent -= dt * maxout;
if (mCurrSent < 0)
{
currSent = 0;
mCurrSent = 0;
}
currSentTS = t;
mCurrSentTS = t;
#ifdef DEBUG_PQISTREAMER
{
std::string out;
rs_sprintf(out, "pqistreamer::outAllowedBytes() is %d/%d", maxout - currSent, maxout);
rs_sprintf(out, "pqistreamer::outAllowedBytes() is %d/%d", maxout - mCurrSent, maxout);
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out);
}
#endif
return maxout - currSent;
return maxout - mCurrSent;
}
int pqistreamer::inAllowedBytes()
int pqistreamer::inAllowedBytes_locked()
{
int t = time(NULL); // get current timestep.
/* allow a lot if not bandwidthLimited */
if (!bio->bandwidthLimited())
if (!mBio->bandwidthLimited())
{
currReadTS = t;
currRead = 0;
mCurrReadTS = t;
mCurrRead = 0;
return PQISTREAM_ABS_MAX;
}
int dt = t - currReadTS;
int dt = t - mCurrReadTS;
// limiter -> for when currReadTs -> 0.
if (dt > 5)
dt = 5;
int maxin = (int) (getMaxRate(true) * 1000.0);
currRead -= dt * maxin;
if (currRead < 0)
mCurrRead -= dt * maxin;
if (mCurrRead < 0)
{
currRead = 0;
mCurrRead = 0;
}
currReadTS = t;
mCurrReadTS = t;
#ifdef DEBUG_PQISTREAMER
{
std::string out;
rs_sprintf(out, "pqistreamer::inAllowedBytes() is %d/%d", maxin - currRead, maxin);
rs_sprintf(out, "pqistreamer::inAllowedBytes() is %d/%d", maxin - mCurrRead, maxin);
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out);
}
#endif
return maxin - currRead;
return maxin - mCurrRead;
}
static const float AVG_PERIOD = 5; // sec
static const float AVG_FRAC = 0.8; // for low pass filter.
void pqistreamer::outSentBytes(int outb)
void pqistreamer::outSentBytes_locked(int outb)
{
#ifdef DEBUG_PQISTREAMER
{
@ -863,29 +895,29 @@ void pqistreamer::outSentBytes(int outb)
totalSent += outb;
currSent += outb;
avgSentCount += outb;
mTotalSent += outb;
mCurrSent += outb;
mAvgSentCount += outb;
int t = time(NULL); // get current timestep.
if (t - avgLastUpdate > AVG_PERIOD)
if (t - mAvgLastUpdate > AVG_PERIOD)
{
float avgReadpSec = getRate(true);
float avgSentpSec = getRate(false);
avgReadpSec *= AVG_FRAC;
avgReadpSec += (1.0 - AVG_FRAC) * avgReadCount /
(1000.0 * (t - avgLastUpdate));
avgReadpSec += (1.0 - AVG_FRAC) * mAvgReadCount /
(1000.0 * (t - mAvgLastUpdate));
avgSentpSec *= AVG_FRAC;
avgSentpSec += (1.0 - AVG_FRAC) * avgSentCount /
(1000.0 * (t - avgLastUpdate));
avgSentpSec += (1.0 - AVG_FRAC) * mAvgSentCount /
(1000.0 * (t - mAvgLastUpdate));
/* pretend our rate is zero if we are
* not bandwidthLimited().
*/
if (bio->bandwidthLimited())
if (mBio->bandwidthLimited())
{
setRate(true, avgReadpSec);
setRate(false, avgSentpSec);
@ -897,14 +929,14 @@ void pqistreamer::outSentBytes(int outb)
}
avgLastUpdate = t;
avgReadCount = 0;
avgSentCount = 0;
mAvgLastUpdate = t;
mAvgReadCount = 0;
mAvgSentCount = 0;
}
return;
}
void pqistreamer::inReadBytes(int inb)
void pqistreamer::inReadBytes_locked(int inb)
{
#ifdef DEBUG_PQISTREAMER
{
@ -914,45 +946,50 @@ void pqistreamer::inReadBytes(int inb)
}
#endif
totalRead += inb;
currRead += inb;
avgReadCount += inb;
mTotalRead += inb;
mCurrRead += inb;
mAvgReadCount += inb;
return;
}
int pqistreamer::getQueueSize(bool in)
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
if (in)
return incoming.size();
return out_queue_size();
return mIncoming.size();
return locked_out_queue_size();
}
void pqistreamer::getRates(RsBwRates &rates)
{
RateInterface::getRates(rates);
rates.mQueueIn = incoming.size();
rates.mQueueOut = out_queue_size();
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
rates.mQueueIn = mIncoming.size();
rates.mQueueOut = locked_out_queue_size();
}
int pqistreamer::out_queue_size() const
int pqistreamer::locked_out_queue_size() const
{
// Warning: because out_pkt is a list, calling size
// is O(n) ! Makign algorithms pretty inefficient. We should record how many
// items get stored and discarded to have a proper size value at any time
//
return out_pkt.size() ;
return mOutPkts.size() ;
}
void pqistreamer::locked_clear_out_queue()
{
for(std::list<void*>::iterator it = out_pkt.begin(); it != out_pkt.end(); )
for(std::list<void*>::iterator it = mOutPkts.begin(); it != mOutPkts.end(); )
{
free(*it);
it = out_pkt.erase(it);
it = mOutPkts.erase(it);
#ifdef DEBUG_PQISTREAMER
std::string out = "pqistreamer::handleoutgoing() Not active -> Clearing Pkt!";
// std::cerr << out ;
std::string out = "pqistreamer::locked_clear_out_queue() Not active -> Clearing Pkt!";
std::cerr << out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out);
#endif
}
@ -962,7 +999,7 @@ int pqistreamer::locked_compute_out_pkt_size() const
{
int total = 0 ;
for(std::list<void*>::const_iterator it = out_pkt.begin(); it != out_pkt.end(); ++it)
for(std::list<void*>::const_iterator it = mOutPkts.begin(); it != mOutPkts.end(); ++it)
total += getRsItemSize(*it);
return total ;
@ -972,12 +1009,12 @@ void *pqistreamer::locked_pop_out_data()
{
void *res = NULL ;
if (!out_pkt.empty())
if (!mOutPkts.empty())
{
res = *(out_pkt.begin());
out_pkt.pop_front();
res = *(mOutPkts.begin());
mOutPkts.pop_front();
#ifdef DEBUG_TRANSFERS
std::cerr << "pqistreamer::handleoutgoing() getting next pkt from out_pkt queue";
std::cerr << "pqistreamer::locked_pop_out_data() getting next pkt from mOutPkts queue";
std::cerr << std::endl;
#endif
}

View file

@ -62,74 +62,82 @@ class pqistreamer: public PQInterface
virtual void getRates(RsBwRates &rates);
virtual int getQueueSize(bool in); // extracting data.
protected:
int tick_bio();
int tick_send(uint32_t timeout);
int tick_recv(uint32_t timeout);
/* Implementation */
// These methods are redefined in pqiQoSstreamer
//
virtual void locked_storeInOutputQueue(void *ptr,int priority) ;
virtual int out_queue_size() const ;
virtual int locked_out_queue_size() const ;
virtual void locked_clear_out_queue() ;
virtual int locked_compute_out_pkt_size() const ;
virtual void *locked_pop_out_data() ;
protected:
RsMutex mStreamerMtx ; // Protects data, fns below, protected so pqiqos can use it too.
// Binary Interface for IO, initialisated at startup.
BinInterface *mBio;
unsigned int mBio_flags; // BIN_FLAGS_NO_CLOSE | BIN_FLAGS_NO_DELETE
private:
// to filter functions - detect filecancel/data and act!
int queue_outpqi(RsItem *i,uint32_t& serialized_size);
int handleincomingitem(RsItem *i);
int queue_outpqi_locked(RsItem *i,uint32_t& serialized_size);
int handleincomingitem_locked(RsItem *i);
// ticked regularly (manages out queues and sending
// via above interfaces.
virtual int handleoutgoing();
virtual int handleincoming();
virtual int handleoutgoing_locked();
virtual int handleincoming_locked();
// Bandwidth/Streaming Management.
float outTimeSlice();
float outTimeSlice_locked();
int outAllowedBytes_locked();
void outSentBytes_locked(int );
int inAllowedBytes_locked();
void inReadBytes_locked(int );
int outAllowedBytes();
void outSentBytes(int );
int inAllowedBytes();
void inReadBytes(int );
// RsSerialiser - determines which packets can be serialised.
RsSerialiser *rsSerialiser;
// Binary Interface for IO, initialisated at startup.
BinInterface *bio;
unsigned int bio_flags; // BIN_FLAGS_NO_CLOSE | BIN_FLAGS_NO_DELETE
RsSerialiser *mRsSerialiser;
void *pkt_wpending; // storage for pending packet to write.
int pkt_rpend_size; // size of pkt_rpending.
void *pkt_rpending; // storage for read in pending packets.
void *mPkt_wpending; // storage for pending packet to write.
int mPkt_rpend_size; // size of pkt_rpending.
void *mPkt_rpending; // storage for read in pending packets.
enum {reading_state_packet_started=1,
reading_state_initial=0 } ;
int reading_state ;
int failed_read_attempts ;
int mReading_state ;
int mFailed_read_attempts ;
// Temp Storage for transient data.....
std::list<void *> out_pkt; // Cntrl / Search / Results queue
std::list<RsItem *> incoming;
std::list<void *> mOutPkts; // Cntrl / Search / Results queue
std::list<RsItem *> mIncoming;
// data for network stats.
int totalRead;
int totalSent;
int mTotalRead;
int mTotalSent;
// these are representative (but not exact)
int currRead;
int currSent;
int currReadTS; // TS from which these are measured.
int currSentTS;
int mCurrRead;
int mCurrSent;
int mCurrReadTS; // TS from which these are measured.
int mCurrSentTS;
int avgLastUpdate; // TS from which these are measured.
float avgReadCount;
float avgSentCount;
int mAvgLastUpdate; // TS from which these are measured.
float mAvgReadCount;
float mAvgSentCount;
time_t mLastIncomingTs;
RsMutex streamerMtx ; // WHAT IS THIS PROTECTING. XXX
// pthread_t thread_id;A
};

View file

@ -0,0 +1,175 @@
/*
* pqithreadstreamer.cc
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2013 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
* License Version 2.1 as published by the Free Software Foundation.
*
* 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 "pqi/pqithreadstreamer.h"
#include <unistd.h>
#define DEFAULT_STREAMER_TIMEOUT 10000 // 10 ms.
#define DEFAULT_STREAMER_SLEEP 1000 // 1 ms.
#define DEFAULT_STREAMER_IDLE_SLEEP 1000000 // 1 sec
pqithreadstreamer::pqithreadstreamer(PQInterface *parent, RsSerialiser *rss, std::string id, BinInterface *bio_in, int bio_flags_in)
:pqistreamer(rss, id, bio_in, bio_flags_in), mParent(parent), mThreadMutex("pqithreadstreamer"), mTimeout(0)
{
mTimeout = DEFAULT_STREAMER_TIMEOUT;
mSleepPeriod = DEFAULT_STREAMER_SLEEP;
return;
}
bool pqithreadstreamer::RecvItem(RsItem *item)
{
return mParent->RecvItem(item);
}
int pqithreadstreamer::tick()
{
tick_bio();
return 0;
}
void pqithreadstreamer::start()
{
{
RsStackMutex stack(mThreadMutex);
mToRun = true;
}
RsThread::start();
}
void pqithreadstreamer::run()
{
std::cerr << "pqithreadstream::run()";
std::cerr << std::endl;
{
RsStackMutex stack(mThreadMutex);
mRunning = true;
}
while(1)
{
{
RsStackMutex stack(mThreadMutex);
if (!mToRun)
{
std::cerr << "pqithreadstream::run() stopping";
std::cerr << std::endl;
mRunning = false;
return;
}
}
data_tick();
}
}
void pqithreadstreamer::stop()
{
RsStackMutex stack(mThreadMutex);
std::cerr << "pqithreadstream::stop()";
std::cerr << std::endl;
mToRun = false;
}
void pqithreadstreamer::fullstop()
{
stop();
while(1)
{
RsStackMutex stack(mThreadMutex);
if (!mRunning)
{
std::cerr << "pqithreadstream::fullstop() complete";
std::cerr << std::endl;
return;
}
usleep(1000);
}
}
bool pqithreadstreamer::threadrunning()
{
RsStackMutex stack(mThreadMutex);
return mRunning;
}
int pqithreadstreamer::data_tick()
{
//std::cerr << "pqithreadstream::data_tick()";
//std::cerr << std::endl;
uint32_t recv_timeout = 0;
uint32_t sleep_period = 0;
bool isactive = false;
{
RsStackMutex stack(mStreamerMtx);
recv_timeout = mTimeout;
sleep_period = mSleepPeriod;
isactive = mBio->isactive();
}
if (!isactive)
{
usleep(DEFAULT_STREAMER_IDLE_SLEEP);
return 0;
}
//std::cerr << "pqithreadstream::data_tick() tick_recv";
//std::cerr << std::endl;
tick_recv(recv_timeout);
// Push Items, Outside of Mutex.
RsItem *incoming = NULL;
while((incoming = GetItem()))
{
RecvItem(incoming);
}
//std::cerr << "pqithreadstream::data_tick() tick_send";
//std::cerr << std::endl;
tick_send(0);
if (sleep_period)
{
//std::cerr << "pqithreadstream::data_tick() usleep";
//std::cerr << std::endl;
usleep(sleep_period);
}
return 1;
}

View file

@ -0,0 +1,62 @@
/*
* libretroshare/src/pqi pqithreadstreamer.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2013 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
* License Version 2.1 as published by the Free Software Foundation.
*
* 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".
*
*/
#ifndef MRK_PQI_THREAD_STREAMER_HEADER
#define MRK_PQI_THREAD_STREAMER_HEADER
#include "pqi/pqistreamer.h"
#include "util/rsthreads.h"
class pqithreadstreamer: public pqistreamer, public RsThread
{
public:
pqithreadstreamer(PQInterface *parent, RsSerialiser *rss, std::string peerid, BinInterface *bio_in, int bio_flagsin);
virtual void run();
virtual void start();
virtual void stop();
virtual void fullstop();
virtual bool threadrunning();
virtual bool RecvItem(RsItem *item);
virtual int tick();
protected:
int data_tick();
PQInterface *mParent;
uint32_t mTimeout;
uint32_t mSleepPeriod;
private:
/* thread variables */
RsMutex mThreadMutex;
bool mRunning;
bool mToRun;
};
#endif //MRK_PQI_THREAD_STREAMER_HEADER

View file

@ -35,7 +35,6 @@
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/ssl.h>
#include <inttypes.h>
#include <string>

View file

@ -1,154 +0,0 @@
#ifndef RS_BLOG_GUI_INTERFACE_H
#define RS_BLOG_GUI_INTERFACE_H
/*
* libretroshare/src/rsiface: rsblogs.h
*
* RetroShare C++ Interface.
*
* Copyright 2008 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
* License Version 2 as published by the Free Software Foundation.
*
* 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 <list>
#include <iostream>
#include <string>
#include "rstypes.h"
#include "rsdistrib.h" /* For FLAGS */
class BlogInfo
{
public:
BlogInfo() {}
std::string blogId;
std::wstring blogName;
std::wstring blogDesc;
uint32_t blogFlags;
uint32_t pop;
unsigned char* pngChanImage;
uint32_t pngImageLen;
time_t lastPost;
};
class BlogMsgInfo
{
public:
BlogMsgInfo() {}
std::string blogId;
std::string msgId;
/// this has a value if replying to another msg
std::string msgIdReply;
unsigned int msgflags;
std::wstring subject;
std::wstring msg;
time_t ts;
std::list<FileInfo> files;
uint32_t count;
uint64_t size;
};
class BlogMsgSummary
{
public:
BlogMsgSummary() {}
std::string blogId;
std::string msgId;
uint32_t msgflags;
std::wstring subject;
std::wstring msg;
std::string msgIdReply;
uint32_t count; /* file count */
time_t ts;
};
std::ostream &operator<<(std::ostream &out, const BlogInfo &info);
std::ostream &operator<<(std::ostream &out, const BlogMsgSummary &info);
std::ostream &operator<<(std::ostream &out, const BlogMsgInfo &info);
class RsBlogs;
extern RsBlogs *rsBlogs;
class RsBlogs
{
public:
RsBlogs() { return; }
virtual ~RsBlogs() { return; }
/****************************************/
/*!
* Checks if the group a blod id belongs to has changed
*/
virtual bool blogsChanged(std::list<std::string> &blogIds) = 0;
virtual std::string createBlog(std::wstring blogName, std::wstring blogDesc, uint32_t blogFlags,
unsigned char* pngImageData, uint32_t imageSize) = 0;
virtual bool getBlogInfo(std::string cId, BlogInfo &ci) = 0;
virtual bool getBlogList(std::list<BlogInfo> &chanList) = 0;
virtual bool getBlogMsgList(std::string cId, std::list<BlogMsgSummary> &msgs) = 0;
/*!
* Retrieves a specific blog Msg based on group Id and message Id
*/
virtual bool getBlogMessage(std::string cId, std::string mId, BlogMsgInfo &msg) = 0;
/*!
* Can send blog message to user
* @param info the message
*/
virtual bool BlogMessageSend(BlogMsgInfo &info) = 0;
/*!
* Allows user to subscribe to a blog via group ID
* @param cId group id
* @param subscribe determine subscription based on value
*/
virtual bool blogSubscribe(std::string cId, bool subscribe) = 0;
/*!
* Commenting on other user's blogs, ensure field info has a valid info.msgIdReply has valid msg id, this
* points to which message the blog reply is replying to
*/
virtual bool BlogMessageReply(BlogMsgInfo &info) = 0;
/*!
*
*/
virtual bool isReply(BlogMsgInfo &info) = 0;
/****************************************/
};
#endif

View file

@ -1,283 +0,0 @@
#ifndef RS_CHANNEL_GUI_INTERFACE_H
#define RS_CHANNEL_GUI_INTERFACE_H
/*
* libretroshare/src/rsiface: rschannels.h
*
* RetroShare C++ Interface.
*
* Copyright 2008 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
* License Version 2 as published by the Free Software Foundation.
*
* 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 <list>
#include <iostream>
#include <string>
#include "rstypes.h"
#include "rsdistrib.h" /* For FLAGS */
#define CHANNEL_MSG_STATUS_MASK 0x000f
#define CHANNEL_MSG_STATUS_READ 0x0001
#define CHANNEL_MSG_STATUS_UNREAD_BY_USER 0x0002
#define CHANNEL_MSG_STATUS_DOWLOADED 0x0004
//! Stores information for a give channel id
/*!
* Stores all information for a given channel id
*/
class ChannelInfo
{
public:
ChannelInfo() : autoDownload(false), pngChanImage(NULL), pngImageLen(0)
{}
std::string channelId;
std::wstring channelName;
std::wstring channelDesc;
uint32_t channelFlags;
uint32_t pop; /// popularity
bool autoDownload;
unsigned char* pngChanImage;
uint32_t pngImageLen;
time_t lastPost;
std::string destination_directory ;
};
//! for storing a channel msgs thumbnail picture
class ChannelMsgThumbnail
{
public:
ChannelMsgThumbnail() : image_thumbnail(NULL), im_thumbnail_size(0) {}
unsigned char* image_thumbnail;
int im_thumbnail_size;
};
//! Stores information on a message within a channel
class ChannelMsgInfo
{
public:
ChannelMsgInfo () : count(0), size(0) {}
std::string channelId;
std::string msgId;
unsigned int msgflags;
std::wstring subject;
std::wstring msg;
time_t ts; /// time stamp
std::list<FileInfo> files;
uint32_t count; /// file count
uint64_t size; /// size of all files
ChannelMsgThumbnail thumbnail;
};
//! gives a more brief account of a channel message than channelMsgInfo
class ChannelMsgSummary
{
public:
ChannelMsgSummary() : count(0) {}
std::string channelId;
std::string msgId;
uint32_t msgflags;
std::wstring subject;
std::wstring msg;
uint32_t count; /// file count
time_t ts; /// time stamp
};
std::ostream &operator<<(std::ostream &out, const ChannelInfo &info);
std::ostream &operator<<(std::ostream &out, const ChannelMsgSummary &info);
std::ostream &operator<<(std::ostream &out, const ChannelMsgInfo &info);
class RsChannels;
extern RsChannels *rsChannels;
/*!
* retroshare interface to the channels distributed group service
* Channels user to create feeds similar to RSS feed where you can share files
* with other users, when you subscribe to a channel you immediately begin downloading
* the file shared on that channel. Channel feeds are shared anonymously
*/
class RsChannels
{
public:
RsChannels() { return; }
virtual ~RsChannels() { return; }
/****************************************/
/*!
* returns a list of channel id that have changed (i.e. received new message, chan descr update)
* @param chanIds this is populated with channel ids that have changed
*/
virtual bool channelsChanged(std::list<std::string> &chanIds) = 0;
/*!
* @param chanName name of the channel
* @param chanDesc a short description for the created channel
* @param chanFlags admin details on created channel group see rsdistrib.h for flags types
* @param pngImageData point at image data in PNG format
* @param imageSize size of the image data
*/
virtual std::string createChannel(std::wstring chanName, std::wstring chanDesc, uint32_t chanFlags,
unsigned char* pngImageData, uint32_t imageSize) = 0;
/*!
* retrieve channel information
* @param cId channel id
* @param ci channel info is store here
*/
virtual bool getChannelInfo(const std::string &cId, ChannelInfo &ci) = 0;
/*!
* @param chanList populated channelinfo for all channels
*/
virtual bool getChannelList(std::list<ChannelInfo> &chanList) = 0;
/*!
* get a message summary list for a given channel id
* @param cId channel id user wants messages for
* @param msgs summary of messages for the given cId
*/
virtual bool getChannelMsgList(const std::string &cId, std::list<ChannelMsgSummary> &msgs) = 0;
/*!
* retrieve more comprehensive message info given channel id and message id
*/
virtual bool getChannelMessage(const std::string &cId, const std::string &mId, ChannelMsgInfo &msg) = 0;
/*!
* set message status
* @param cId channel id
* @param mId message id
* @param status status to set
* @param statusMask bitmask to modify
*/
virtual bool setMessageStatus(const std::string& cId,const std::string& mId, const uint32_t status, const uint32_t statusMask) = 0;
/*!
* set message status
* @param cId channel id
* @param mId message id
* @param status status
*/
virtual bool getMessageStatus(const std::string& cId, const std::string& mId, uint32_t& status) = 0;
/*!
* count the new and unread messages
* @param cId channel id
* @param newCount count of new messages
* @param unreadCount count of unread messages
*/
virtual bool getMessageCount(const std::string &cId, unsigned int &newCount, unsigned int &unreadCount) = 0;
/*!
* send message contain in message info to the id indicated within it (make sure you set the channel id of the message info)
* @param info message to be sent
*/
virtual bool ChannelMessageSend(ChannelMsgInfo &info) = 0;
/*!
* @param cId the channel id
* @param subscribe set to true if you want to subscribe and to false to unsubscribe
* @param set true to allow autodownload of new content and false otherwise, ignored when second param is false
*/
virtual bool channelSubscribe(const std::string &cId, bool subscribe, bool autoDl) = 0;
/*!
* This hashes a file which is not already shared by client or his peers,
* The file is copied into the channels directory if its not too large (> 100mb)
* @param path This is full path to file
* @param channel Id
*/
virtual bool channelExtraFileHash(const std::string &path, const std::string &chId, FileInfo& fInfo) = 0;
/*!
* This removes hashed extra files, and also removes channels directory copy if it exists
* @param chId channel id
*/
virtual bool channelExtraFileRemove(const std::string &hash, const std::string &chId) = 0;
/*!
* Restores channel private keys for channel in the event keys stored in configuration files are lost
* @param chId channel id to restore keys for
*/
virtual bool channelRestoreKeys(const std::string &chId) = 0;
/*!
* shares keys with peers
*@param chId the channel for which private publish keys will be shared
*@param peers peers in this list will be sent keys
*
*/
virtual bool channelShareKeys(const std::string &chId, std::list<std::string>& peers) = 0;
/****************************************/
/*!
* allows peers to change information for the channel:
* can only change channel image, descriptions and name
*
*/
virtual bool channelEditInfo(const std::string &chId, ChannelInfo &ci) = 0;
/*!
* get list of channels for which private publish key is available
* @param grpIds list of channels for which private publish key is available
*/
virtual void getPubKeysAvailableGrpIds(std::list<std::string>& chanIds) = 0;
/*!
* set the channel so that it does not auto download any more
* @param chId the channel id to set for
* @param set to true to enable auto dl and false to disable
*/
virtual bool channelSetAutoDl(const std::string& chId, bool autoDl) = 0;
// sets the defautl destination directory for files downloaded in this channel.
// Default is "" which means Downloads/
virtual bool channelSetDestinationDirectory(const std::string& cid,const std::string& dir) = 0 ;
/*!
* get what autoDl is set to for the given channel id
* @param chId id of channel to get autoDl status for
* @param autoDl
* @return false if channel cannot be found
*/
virtual bool channelGetAutoDl(const std::string& chId, bool& autoDl) = 0;
};
#endif

View file

@ -42,9 +42,9 @@ class RsDisc
RsDisc() { return; }
virtual ~RsDisc() { return; }
virtual bool getDiscFriends(std::string id, std::list<std::string>& friends) = 0;
virtual bool getDiscGPGFriends(std::string id, std::list<std::string>& gpg_friends) = 0;
virtual bool getDiscVersions(std::map<std::string, std::string> &versions) = 0;
virtual bool getDiscFriends(const std::string &id, std::list<std::string>& friends) = 0;
virtual bool getDiscPgpFriends(const std::string &pgpid, std::list<std::string>& gpg_friends) = 0;
virtual bool getPeerVersion(const std::string &id, std::string &versions) = 0;
virtual bool getWaitingDiscCount(unsigned int *sendCount, unsigned int *recvCount) = 0;
};

View file

@ -1,56 +0,0 @@
#ifndef RS_DISTRIB_GUI_INTERFACE_H
#define RS_DISTRIB_GUI_INTERFACE_H
/*
* libretroshare/src/rsiface: rsdistrib.h
*
* RetroShare C++ Interface.
*
* Copyright 2007-2008 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
* License Version 2 as published by the Free Software Foundation.
*
* 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".
*
*/
#define RS_DISTRIB_PRIVACY_MASK 0x0000000f /* who can publish & view */
#define RS_DISTRIB_AUTHEN_MASK 0x000000f0 /* how to publish */
#define RS_DISTRIB_LISTEN_MASK 0x00000f00 /* distribution flags */
#define RS_DISTRIB_UPDATE_MASK 0x0000f000 /* if sending a group info update */
#define RS_DISTRIB_MISC_MASK 0x00ff0000 /* if sending a group info update */
#define RS_DISTRIB_PUBLIC 0x00000001 /* anyone can publish */
#define RS_DISTRIB_PRIVATE 0x00000002 /* anyone with key can publish */
#define RS_DISTRIB_ENCRYPTED 0x00000004 /* need publish key to view */
#define RS_DISTRIB_AUTHEN_REQ 0x00000010 /* you must sign messages */
#define RS_DISTRIB_AUTHEN_ANON 0x00000020 /* you can send anonymous messages */
#define RS_DISTRIB_ADMIN 0x00000100
#define RS_DISTRIB_PUBLISH 0x00000200
#define RS_DISTRIB_SUBSCRIBED 0x00000400
#define RS_DISTRIB_UPDATE 0x00001000
/* don't know if this should go with the above flags, as it message specific, and not a group settings.
* As it is currently not stored any configuration, it can be changed.
*/
#define RS_DISTRIB_MISSING_MSG 0x00010000
#endif

View file

@ -1,167 +0,0 @@
#ifndef RS_FORUM_GUI_INTERFACE_H
#define RS_FORUM_GUI_INTERFACE_H
/*
* libretroshare/src/rsiface: rsforums.h
*
* RetroShare C++ Interface.
*
* Copyright 2007-2008 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
* License Version 2 as published by the Free Software Foundation.
*
* 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 <list>
#include <iostream>
#include <string>
#include "rstypes.h"
#include "rsdistrib.h" /* For FLAGS */
#define FORUM_MSG_STATUS_MASK 0x000f
#define FORUM_MSG_STATUS_READ 0x0001
#define FORUM_MSG_STATUS_UNREAD_BY_USER 0x0002
#define FORUM_MSG_STATUS_LOAD_EMBEDDED_IMAGES 0x0004
class ForumInfo
{
public:
ForumInfo()
{
forumFlags = 0 ;
subscribeFlags = 0 ;
pop = 0 ;
lastPost = 0 ;
}
std::string forumId;
std::wstring forumName;
std::wstring forumDesc;
uint32_t forumFlags;
uint32_t subscribeFlags;
uint32_t pop;
time_t lastPost;
};
class ForumMsgInfo
{
public:
ForumMsgInfo()
{
msgflags = 0 ;
ts = childTS = status = 0 ;
}
std::string forumId;
std::string threadId;
std::string parentId;
std::string msgId;
std::string srcId; /* if Authenticated -> signed here */
unsigned int msgflags;
std::wstring title;
std::wstring msg;
time_t ts;
time_t childTS;
uint32_t status;
};
class ThreadInfoSummary
{
public:
ThreadInfoSummary()
{
msgflags = 0 ;
count = 0 ;
ts = childTS = 0 ;
}
std::string forumId;
std::string threadId;
std::string parentId;
std::string msgId;
uint32_t msgflags;
std::wstring title;
std::wstring msg;
int count; /* file count */
time_t ts;
time_t childTS;
};
std::ostream &operator<<(std::ostream &out, const ForumInfo &info);
std::ostream &operator<<(std::ostream &out, const ThreadInfoSummary &info);
std::ostream &operator<<(std::ostream &out, const ForumMsgInfo &info);
class RsForums;
extern RsForums *rsForums;
class RsForums
{
public:
RsForums() { return; }
virtual ~RsForums() { return; }
/****************************************/
virtual bool forumsChanged(std::list<std::string> &forumIds) = 0;
virtual std::string createForum(const std::wstring &forumName, const std::wstring &forumDesc, uint32_t forumFlags) = 0;
virtual bool getForumInfo(const std::string &fId, ForumInfo &fi) = 0;
/*!
* allows peers to change information for the forum:
* can only change name and descriptions
*
*/
virtual bool setForumInfo(const std::string &fId, ForumInfo &fi) = 0;
virtual bool getForumList(std::list<ForumInfo> &forumList) = 0;
virtual bool getForumThreadList(const std::string &fId, std::list<ThreadInfoSummary> &msgs) = 0;
virtual bool getForumThreadMsgList(const std::string &fId, const std::string &pId, std::list<ThreadInfoSummary> &msgs) = 0;
virtual bool getForumMessage(const std::string &fId, const std::string &mId, ForumMsgInfo &msg) = 0;
virtual bool setMessageStatus(const std::string& fId,const std::string& mId, const uint32_t status, const uint32_t statusMask) = 0;
virtual bool getMessageStatus(const std::string& fId, const std::string& mId, uint32_t& status) = 0;
virtual bool ForumMessageSend(ForumMsgInfo &info) = 0;
virtual bool forumRestoreKeys(const std::string& fId) = 0;
virtual bool forumSubscribe(const std::string &fId, bool subscribe) = 0;
/*!
* shares keys with peers
*@param fId the forum for which private publish keys will be shared
*@param peers list of peers to be sent keys
*
*/
virtual bool forumShareKeys(std::string fId, std::list<std::string>& peers) = 0;
virtual bool getMessageCount(const std::string &fId, unsigned int &newCount, unsigned int &unreadCount) = 0;
/****************************************/
};
#endif

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