More cleanning

git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/ammorais_branch@1354 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
ammorais 2009-07-11 11:49:18 +00:00
parent ed517d7ebf
commit e76eef9c7e
86 changed files with 37356 additions and 30 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,329 @@
/*
* RetroShare FileCache Module: cachestrapper.h
*
* Copyright 2004-2007 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 CACHESTRAPPER_H
#define CACHESTRAPPER_H
#include "_pqi/p3cfgmgr.h"
#include "_pqi/pqimonitor.h"
#include "_util/rsthreads.h"
#include <list>
#include <map>
#include <string>
#include <iostream>
/******************* CacheStrapper and Related Classes *******************
* A generic Cache Update system.
*
* CacheStrapper: maintains a set of CacheSources, and CacheStores,
* queries and updates as new information arrives.
*
* CacheTransfer: Interface for FileTransfer Class to support.
*
* CacheSource: Base Class for cache data provider. eg. FileIndexMonitor.
* CacheStore: Base Class for data cache. eg. FileCache/Store.
*
* Still TODO:
* (1) Design and Implement the Upload side of CacheTransfer/CacheStrapper.
* (2) CacheStrapper:: Save / Load Cache lists....
* (3) Clean up lists, maps on shutdown etc.
* (4) Consider Mutexes for multithreaded operations.
* (5) Test the MultiSource/Store capabilities.
*
******************* CacheStrapper and Related Classes *******************/
class CacheTransfer; /* Interface for File Transfer */
class CacheSource; /* Interface for local File Index/Monitor */
class CacheStore; /* Interface for the actual Cache */
class CacheStrapper; /* Controlling Class */
/****
typedef uint32_t RsPeerId;
*****/
typedef std::string RsPeerId;
/******************************** CacheId ********************************/
class CacheId
{
public:
CacheId() :type(0), subid(0) { return; }
CacheId(uint16_t a, uint16_t b) :type(a), subid(b) { return; }
uint16_t type;
uint16_t subid;
};
bool operator<(const CacheId &a, const CacheId &b);
class CacheData
{
public:
RsPeerId pid;
std::string pname; /* peer name (can be used by cachestore) */
CacheId cid;
std::string path;
std::string name;
std::string hash;
uint64_t size;
time_t recvd;
};
std::ostream &operator<<(std::ostream &out, const CacheData &d);
/***************************** CacheTransfer *****************************/
class CacheTransfer
{
public:
CacheTransfer(CacheStrapper *cs) :strapper(cs) { return; }
virtual ~CacheTransfer() {}
/* upload side of things .... searches through CacheStrapper. */
bool FindCacheFile(std::string hash, std::string &path, uint64_t &size);
/* At the download side RequestCache() => overloaded RequestCacheFile()
* the class should then call CompletedCache() or FailedCache()
*/
bool RequestCache(CacheData &data, CacheStore *cbStore); /* request from CacheStore */
protected:
/* to be overloaded */
virtual bool RequestCacheFile(RsPeerId id, std::string path, std::string hash, uint64_t size);
virtual bool CancelCacheFile(RsPeerId id, std::string path, std::string hash, uint64_t size);
bool CompletedCache(std::string hash); /* internal completion -> does cb */
bool FailedCache(std::string hash); /* internal completion -> does cb */
private:
CacheStrapper *strapper;
std::map<std::string, CacheData> cbData;
std::map<std::string, CacheStore *> cbStores;
};
/************************ CacheSource/CacheStore *************************/
typedef std::map<uint16_t, CacheData> CacheSet;
class CacheSource
{
public:
CacheSource(uint16_t t, bool m, CacheStrapper *cs, std::string cachedir);
virtual ~CacheSource() {}
/* called to determine available cache for peer -
* default acceptable (returns all)
*/
virtual bool cachesAvailable(RsPeerId pid, std::map<CacheId, CacheData> &ids);
/* function called at startup to load from
* configuration file....
* to be overloaded by inherited class
*/
virtual bool loadLocalCache(const CacheData &data);
/* control Caches available */
bool refreshCache(const CacheData &data);
bool clearCache(CacheId id);
/* get private data */
std::string getCacheDir() { return cacheDir; }
bool isMultiCache() { return multiCache; }
uint16_t getCacheType() { return cacheType; }
/* display */
void listCaches(std::ostream &out);
/* search */
bool findCache(std::string hash, CacheData &data) const;
protected:
uint16_t cacheType; /* for checking */
bool multiCache; /* do we care about subid's */
CacheStrapper *mStrapper;
/*** MUTEX LOCKING */
void lockData() const;
void unlockData() const;
CacheSet caches;
private:
std::string cacheDir;
mutable RsMutex cMutex;
};
class CacheStore
{
public:
CacheStore(uint16_t t, bool m, CacheStrapper *cs, CacheTransfer *cft, std::string cachedir);
virtual ~CacheStore() {}
/* current stored data */
bool getStoredCache(CacheData &data); /* use pid/cid in data */
bool getAllStoredCaches(std::list<CacheData> &data); /* use pid/cid in data */
/* input from CacheStrapper -> store can then download new data */
void availableCache(const CacheData &data);
/* called when the download is completed ... updates internal data */
void downloadedCache(const CacheData &data);
/* called if the download fails */
void failedCache(const CacheData &data);
/* virtual functions overloaded by cache implementor */
virtual bool fetchCache(const CacheData &data); /* a question? */
virtual int nameCache(CacheData &data); /* fill in the name/path */
virtual int loadCache(const CacheData &data); /* actual load, once data available */
/* get private data */
std::string getCacheDir() { return cacheDir; }
bool isMultiCache() { return multiCache; }
uint16_t getCacheType() { return cacheType; }
/* display */
void listCaches(std::ostream &out);
protected:
/*** MUTEX LOCKING */
void lockData() const;
void unlockData() const;
/* This function is called to store Cache Entry in the CacheStore Table.
* it must be called from within a Mutex Lock....
*
* It doesn't lock itself -> to avoid race conditions
*/
void locked_storeCacheEntry(const CacheData &data);
bool locked_getStoredCache(CacheData &data);
private:
uint16_t cacheType; /* for checking */
bool multiCache; /* do we care about subid's */
CacheStrapper *mStrapper;
CacheTransfer *cacheTransfer;
std::string cacheDir;
mutable RsMutex cMutex;
std::map<RsPeerId, CacheSet> caches;
};
/***************************** CacheStrapper *****************************/
/* Make Sure you get the Ids right! */
class CachePair
{
public:
CachePair()
:source(NULL), store(NULL), id(0, 0) { return; }
CachePair(CacheSource *a, CacheStore *b, CacheId c)
:source(a), store(b), id(c) { return; }
CacheSource *source;
CacheStore *store;
CacheId id;
};
bool operator<(const CachePair &a, const CachePair &b);
class p3AuthMgr;
class CacheStrapper: public pqiMonitor, public p3Config
{
public:
CacheStrapper(p3AuthMgr *am, p3ConnectMgr *cm);
virtual ~CacheStrapper() { return; }
/************* from pqiMonitor *******************/
virtual void statusChange(const std::list<pqipeer> &plist);
/************* from pqiMonitor *******************/
/* Feedback from CacheSources */
void refreshCache(const CacheData &data);
void refreshCacheStore(const CacheData &data);
/* list of Caches to send out */
bool getCacheUpdates(std::list<std::pair<RsPeerId, CacheData> > &updates);
void addCachePair(CachePair pair);
/*** I/O (2) ***/
void recvCacheResponse(CacheData &data, time_t ts);
void handleCacheQuery(RsPeerId id, std::map<CacheId, CacheData> &data);
/* search through CacheSources. */
bool findCache(std::string hash, CacheData &data) const;
/* display */
void listCaches(std::ostream &out);
void listPeerStatus(std::ostream &out);
/* Config */
protected:
/* Key Functions to be overloaded for Full Configuration */
virtual RsSerialiser *setupSerialiser();
virtual std::list<RsItem *> saveList(bool &cleanup);
virtual bool loadList(std::list<RsItem *> load);
private:
/* these are static - so shouldn't need mutex */
p3AuthMgr *mAuthMgr;
p3ConnectMgr *mConnMgr;
std::map<uint16_t, CachePair> caches;
RsMutex csMtx; /* protect below */
std::list<std::pair<RsPeerId, CacheData> > mCacheUpdates;
};
#endif // CACHESTRAPPER_H

View File

@ -0,0 +1,8 @@
INCLUDEPATH += $$PWD \
../$$PWP
DEPENDPATH += $$PWD
SOURCES = cachestrapper.cc
HEADERS = cachestrapper.h

View File

@ -54,23 +54,8 @@
*/
#include "authgpg.h"
#include <iostream>
#include <sstream>
/* Turn a set of parameters into a string */
static std::string setKeyPairParams(bool useRsa, unsigned int blen,
std::string name, std::string comment, std::string email,
std::string passphrase);
static gpgme_key_t getKey(gpgme_ctx_t, std::string, std::string, std::string);
static gpg_error_t keySignCallback(void *, gpgme_status_code_t, \
const char *, int);
static gpg_error_t trustCallback(void *, gpgme_status_code_t, \
const char *, int);
static void ProcessPGPmeError(gpgme_error_t ERR);
/* Function to sign X509_REQ via GPGme.
*/

View File

@ -27,12 +27,32 @@
*
*/
#ifndef RS_GPG_AUTH_HEADER
#define RS_GPG_AUTH_HEADER
#ifndef AUTHGPG_H
#define AUTHGPG_H
//#include "p3authmgr.h"
#include "authssl.h"
#include <gpgme.h>
#include <iostream>
#include <sstream>
/* Turn a set of parameters into a string */
static std::string setKeyPairParams(bool useRsa, unsigned int blen,
std::string name, std::string comment, std::string email,
std::string passphrase);
static gpgme_key_t getKey(gpgme_ctx_t, std::string, std::string, std::string);
static gpg_error_t keySignCallback(void *, gpgme_status_code_t,
const char *, int);
static gpg_error_t trustCallback(void *, gpgme_status_code_t,
const char *, int);
static void ProcessPGPmeError(gpgme_error_t ERR);
/* gpgcert is the identifier for a person.
* It is a wrapper class for a GPGme OpenPGP certificate.
@ -382,4 +402,4 @@ public:
}
};
#endif
#endif // AUTHGPG_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,241 @@
/*
* libretroshare/src/pqi: authssl.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-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".
*
*/
#ifndef AUTHSSL_H
#define AUTHSSL_H
/*
* This is an implementation of SSL certificate authentication, which can be
* overloaded with pgp style signatures, and web-of-trust authentication.
*
* There are several virtual functions with can be overloaded to acheive this.
* SignCertificate()
* AuthCertificate()
*
* To use as an SSL authentication system, you must use a common CA certificate.
* and compilation should be done with PQI_USE_XPGP off, and PQI_USE_SSLONLY on
* * The pqissl stuff doesn't need to differentiate between SSL, SSL + PGP,
* as its X509 certs.
* * The rsserver stuff has to distinguish between all three types ;(
*
*/
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include <string>
#include <map>
#include "util/rsthreads.h"
#include "pqi/pqi_base.h"
#include "pqi/pqinetwork.h"
#include "pqi/p3authmgr.h"
class AuthSSL;
class sslcert
{
public:
sslcert(X509 *x509, std::string id);
/* certificate parameters */
std::string id;
std::string name;
std::string location;
std::string org;
std::string email;
std::string issuer;
std::string fpr;
std::list<std::string> signers;
/* Auth settings */
bool authed;
/* INTERNAL Parameters */
X509 *certificate;
};
class AuthSSL: public p3AuthMgr
{
public:
/* Initialisation Functions (Unique) */
AuthSSL();
bool validateOwnCertificate(X509 *x509, EVP_PKEY *pkey);
virtual bool active();
virtual int InitAuth(const char *srvr_cert, const char *priv_key,
const char *passwd);
virtual bool CloseAuth();
virtual int setConfigDirectories(std::string confFile, std::string neighDir);
/*********** Overloaded Functions from p3AuthMgr **********/
/* get Certificate Ids */
virtual std::string OwnId();
virtual bool getAllList(std::list<std::string> &ids);
virtual bool getAuthenticatedList(std::list<std::string> &ids);
virtual bool getUnknownList(std::list<std::string> &ids);
/* get Details from the Certificates */
virtual bool isValid(std::string id);
virtual bool isAuthenticated(std::string id);
virtual std::string getName(std::string id);
virtual std::string getIssuerName(std::string id);
virtual bool getDetails(std::string id, pqiAuthDetails &details);
/* first party trust info (dummy) */
virtual bool isTrustingMe(std::string id) ;
virtual void addTrustingPeer(std::string id) ;
/* High Level Load/Save Configuration */
virtual bool FinalSaveCertificates();
virtual bool CheckSaveCertificates();
virtual bool saveCertificates();
virtual bool loadCertificates();
/* Load/Save certificates */
virtual bool LoadCertificateFromString(std::string pem, std::string &id);
virtual std::string SaveCertificateToString(std::string id);
virtual bool LoadCertificateFromFile(std::string filename, std::string &id);
virtual bool SaveCertificateToFile(std::string id, std::string filename);
virtual bool LoadCertificateFromBinary(const uint8_t *ptr, uint32_t len, std::string &id);
virtual bool SaveCertificateToBinary(std::string id, uint8_t **ptr, uint32_t *len);
/* Signatures */
virtual bool AuthCertificate(std::string uid);
/* These are dummy functions */
virtual bool SignCertificate(std::string id);
virtual bool RevokeCertificate(std::string id);
virtual bool TrustCertificate(std::string id, bool trust);
/* Sign / Encrypt / Verify Data (TODO) */
virtual bool SignData(std::string input, std::string &sign);
virtual bool SignData(const void *data, const uint32_t len, std::string &sign);
virtual bool SignDataBin(std::string, unsigned char*, unsigned int*);
virtual bool SignDataBin(const void*, uint32_t, unsigned char*, unsigned int*);
virtual bool VerifySignBin(std::string, const void*, uint32_t, unsigned char*, unsigned int);
/*********** Overloaded Functions from p3AuthMgr **********/
/************* Virtual Functions from AuthSSL *************/
virtual int VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx);
virtual bool ValidateCertificate(X509 *x509, std::string &peerId); /* validate + get id */
/************* Virtual Functions from AuthSSL *************/
public: /* SSL specific functions used in pqissl/pqissllistener */
SSL_CTX *getCTX();
bool FailedCertificate(X509 *x509, bool incoming); /* store for discovery */
bool CheckCertificate(std::string peerId, X509 *x509); /* check that they are exact match */
/* Special Config Loading (backwards compatibility) */
bool loadCertificates(bool &oldFormat, std::map<std::string, std::string> &keyValueMap);
private:
/* Helper Functions */
bool ProcessX509(X509 *x509, std::string &id);
X509 * loadX509FromPEM(std::string pem);
X509 * loadX509FromFile(std::string fname, std::string hash);
bool saveX509ToFile(X509 *x509, std::string fname, std::string &hash);
X509 * loadX509FromDER(const uint8_t *ptr, uint32_t len);
bool saveX509ToDER(X509 *x509, uint8_t **ptr, uint32_t *len);
/*********** LOCKED Functions ******/
bool locked_FindCert(std::string id, sslcert **cert);
/* Data */
RsMutex sslMtx; /**** LOCKING */
int init;
std::string mCertConfigFile;
std::string mNeighDir;
SSL_CTX *sslctx;
std::string mOwnId;
sslcert *mOwnCert;
EVP_PKEY *pkey;
bool mToSaveCerts;
bool mConfigSaveActive;
std::map<std::string, sslcert *> mCerts;
};
X509_REQ *GenerateX509Req(
std::string pkey_file, std::string passwd,
std::string name, std::string email, std::string org,
std::string loc, std::string state, std::string country,
int nbits_in, std::string &errString);
X509 *SignX509Certificate(X509_NAME *issuer, EVP_PKEY *privkey, X509_REQ *req, long days);
/* Helper Functions */
int printSSLError(SSL *ssl, int retval, int err, unsigned long err2, std::ostream &out);
std::string getX509NameString(X509_NAME *name);
std::string getX509CNString(X509_NAME *name);
std::string getX509OrgString(X509_NAME *name);
std::string getX509LocString(X509_NAME *name);
std::string getX509CountryString(X509_NAME *name);
#if 0
std::list<std::string> getXPGPsigners(XPGP *cert);
std::string getXPGPAuthCode(XPGP *xpgp);
#endif
std::string getX509Info(X509 *cert);
bool getX509id(X509 *x509, std::string &xid);
int LoadCheckX509andGetName(const char *cert_file,
std::string &userName, std::string &userId);
#endif // AUTHSSL_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,211 @@
/*
* libretroshare/src/pqi: authxpgp.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-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".
*
*/
#ifndef MRK_AUTH_SSL_XPGP_HEADER
#define MRK_AUTH_SSL_XPGP_HEADER
/* This is the trial XPGP version
*
* It has to be compiled against XPGP ssl version.
* this is only a hacked up version, merging
* (so both can operate in parallel will happen later)
*
*/
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include <string>
#include <map>
#include "util/rsthreads.h"
#include "pqi/pqi_base.h"
#include "pqi/pqinetwork.h"
#include "pqi/p3authmgr.h"
class AuthXPGP;
class xpgpcert
{
public:
xpgpcert(XPGP *xpgp, std::string id);
/* certificate parameters */
std::string id;
std::string name;
std::string location;
std::string org;
std::string email;
std::string fpr;
std::list<std::string> signers;
/* Auth settings */
uint32_t trustLvl;
bool ownsign;
bool trusted;
/* INTERNAL Parameters */
XPGP *certificate;
};
class AuthXPGP: public p3AuthMgr
{
public:
/* Initialisation Functions (Unique) */
AuthXPGP();
virtual bool active();
virtual int InitAuth(const char *srvr_cert, const char *priv_key,
const char *passwd);
virtual bool CloseAuth();
virtual int setConfigDirectories(std::string confFile, std::string neighDir);
/*********** Overloaded Functions from p3AuthMgr **********/
/* get Certificate Ids */
virtual std::string OwnId();
virtual bool getAllList(std::list<std::string> &ids);
virtual bool getAuthenticatedList(std::list<std::string> &ids);
virtual bool getUnknownList(std::list<std::string> &ids);
/* get Details from the Certificates */
virtual bool isValid(std::string id);
virtual bool isAuthenticated(std::string id);
virtual std::string getName(std::string id);
virtual bool getDetails(std::string id, pqiAuthDetails &details);
/* first party trust info */
virtual bool isTrustingMe(std::string id) ;
virtual void addTrustingPeer(std::string id) ;
/* High Level Load/Save Configuration */
virtual bool FinalSaveCertificates();
virtual bool CheckSaveCertificates();
virtual bool saveCertificates();
virtual bool loadCertificates();
/* Load/Save certificates */
virtual bool LoadCertificateFromString(std::string pem, std::string &id);
virtual std::string SaveCertificateToString(std::string id);
virtual bool LoadCertificateFromFile(std::string filename, std::string &id);
virtual bool SaveCertificateToFile(std::string id, std::string filename);
virtual bool LoadCertificateFromBinary(const uint8_t *ptr, uint32_t len, std::string &id);
virtual bool SaveCertificateToBinary(std::string id, uint8_t **ptr, uint32_t *len);
/* Signatures */
virtual bool AuthCertificate(std::string uid);
virtual bool SignCertificate(std::string id);
virtual bool RevokeCertificate(std::string id);
virtual bool TrustCertificate(std::string id, bool trust);
/* Sign / Encrypt / Verify Data (TODO) */
virtual bool SignData(std::string input, std::string &sign);
virtual bool SignData(const void *data, const uint32_t len, std::string &sign);
/* for proper signatures! */
virtual bool SignDataBin(std::string input, unsigned char *sign, unsigned int *signlen);
virtual bool SignDataBin(const void *data, const uint32_t len,
unsigned char *sign, unsigned int *signlen);
virtual bool VerifySignBin(std::string pid,
const void *data, const uint32_t len,
unsigned char *sign, unsigned int signlen);
/*********** Overloaded Functions from p3AuthMgr **********/
public: /* XPGP specific functions used in pqissl/pqissllistener */
SSL_CTX *getCTX();
bool ValidateCertificateXPGP(XPGP *xpgp, std::string &peerId); /* validate + get id */
bool FailedCertificateXPGP(XPGP *xpgp, bool incoming); /* store for discovery */
bool CheckCertificateXPGP(std::string peerId, XPGP *xpgp); /* check that they are exact match */
/* Special Config Loading (backwards compatibility) */
bool loadCertificates(bool &oldFormat, std::map<std::string, std::string> &keyValueMap);
private:
/* Helper Functions */
bool ProcessXPGP(XPGP *xpgp, std::string &id);
XPGP * loadXPGPFromPEM(std::string pem);
XPGP * loadXPGPFromFile(std::string fname, std::string hash);
bool saveXPGPToFile(XPGP *xpgp, std::string fname, std::string &hash);
XPGP * loadXPGPFromDER(const uint8_t *ptr, uint32_t len);
bool saveXPGPToDER(XPGP *xpgp, uint8_t **ptr, uint32_t *len);
/*********** LOCKED Functions ******/
bool locked_FindCert(std::string id, xpgpcert **cert);
/* Data */
RsMutex xpgpMtx; /**** LOCKING */
int init;
std::string mCertConfigFile;
std::string mNeighDir;
SSL_CTX *sslctx;
XPGP_KEYRING *pgp_keyring;
std::string mOwnId;
xpgpcert *mOwnCert;
EVP_PKEY *pkey;
bool mToSaveCerts;
bool mConfigSaveActive;
std::map<std::string, xpgpcert *> mCerts;
std::list<std::string> _trusting_peers ;
};
/* Helper Functions */
int printSSLError(SSL *ssl, int retval, int err, unsigned long err2, std::ostream &out);
std::string getX509NameString(X509_NAME *name);
std::string getX509CNString(X509_NAME *name);
std::string getX509OrgString(X509_NAME *name);
std::string getX509LocString(X509_NAME *name);
std::string getX509CountryString(X509_NAME *name);
std::list<std::string> getXPGPsigners(XPGP *cert);
std::string getXPGPInfo(XPGP *cert);
std::string getXPGPAuthCode(XPGP *xpgp);
int LoadCheckXPGPandGetName(const char *cert_file,
std::string &userName, std::string &userId);
bool getXPGPid(XPGP *xpgp, std::string &xpgpid);
#endif // MRK_SSL_XPGP_CERT_HEADER

View File

@ -0,0 +1,371 @@
/*
* libretroshare/src/pqi: cleanupxpgp.cc
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2008 by Sourashis Roy
*
* 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 "cleanupxpgp.h"
/*
Method for cleaning up the certificate. This method removes any unnecessay white spaces and unnecessary
new line characters in the certificate. Also it makes sure that there are 64 characters per line in
the certificate. This function removes white spaces and new line characters in the entire segment
-----BEGIN XPGP CERTIFICATE-----
<CERTIFICATE>
-----END XPGP CERTIFICATE-----
We also take care of correcting cases like ----- BEGIN. Here extra empty spaces
have been introduced between ----- and BEGIN. Similarly for the
end tag we take care of cases like ----- END XPGP . Here extra empty spaces have been
introduced and the actual tag should have been -----END XPGP
*/
std::string cleanUpCertificate(std::string badCertificate)
{
/*
Buffer for storing the cleaned certificate. In certain cases the
cleanCertificate can be larger than the badCertificate
*/
char * cleanCertificate=new char[badCertificate.length()+100];
//The entire certificate begin tag
char * beginCertTag="-----BEGIN";
//The entire certificate end tag
char * endCertTag="-----END";
//Tag containing dots. The common part of both start and end tags
char * commonTag="-----";
//Only BEGIN part of the begin tag
char * beginTag="BEGIN";
//Only END part of the end tag
char * endTag="END";
//The start index of the ----- part of the certificate begin tag
int beginCertStartIdx1=0;
//The start index of the BEGIN part of the certificate begin tag
int beginCertStartIdx2=0;
//The start index of the end part(-----) of the certificate begin tag. The begin tag ends with -----. Example -----BEGIN XPGP CERTIFICATE-----
int beginCertEndIdx=0;
//The start index of the ----- part of the certificate end tag
int endCertStartIdx1=0;
//The start index of the END part of the certificate end tag
int endCertStartIdx2=0;
//The start index of the end part(-----) of the certificate end tag. The begin tag ends with -----. Example -----BEGIN XPGP CERTIFICATE-----
int endCertEndIdx=0;
//The length of the bad certificate.
int lengthOfCert=badCertificate.length();
//The current index value in the cleaned certificate.
int currCleanCertIdx=0;
//The current index value in the bad certificate
int currBadCertIdx=0;
//Temporary index value
int 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=badCertificate.find(commonTag,tmpIdx))!=std::string::npos)
{
beginCertStartIdx2=badCertificate.find(beginTag,beginCertStartIdx1+strlen(commonTag));
tmpIdx=beginCertStartIdx1+strlen(commonTag);
if(beginCertStartIdx2!=std::string::npos)
{
found=true;
for(int i=beginCertStartIdx1+strlen(commonTag);i<beginCertStartIdx2;i++)
{
if(badCertificate[i]!=' ' && badCertificate[i]!='\n' )
{
found=false;
break;
}
}
}
else
{
break;
}
}
/*
begin tag not found
*/
if(!found)
{
std::cerr<<"Certificate corrupted beyond repair: No <------BEGIN > tag"<<std::endl;
return badCertificate;
}
beginCertEndIdx=badCertificate.find(commonTag,beginCertStartIdx2);
if(beginCertEndIdx==std::string::npos)
{
std::cerr<<"Certificate corrupted beyond repair: No <------BEGIN > tag"<<std::endl;
return badCertificate;
}
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=badCertificate.find(commonTag,tmpIdx))!=std::string::npos)
{
endCertStartIdx2=badCertificate.find(endTag,endCertStartIdx1+strlen(commonTag));
tmpIdx=endCertStartIdx1+strlen(commonTag);
if(endCertStartIdx2!=std::string::npos)
{
found=true;
for(int i=endCertStartIdx1+strlen(commonTag);i<endCertStartIdx2;i++)
{
if(badCertificate[i]!=' '&& badCertificate[i]!='\n')
{
found=false;
break;
}
}
}
else
{
break;
}
}
/*
end tag not found
*/
if(!found)
{
std::cerr<<"Certificate corrupted beyond repair: No <------END > tag"<<std::endl;
return badCertificate;
}
endCertEndIdx=badCertificate.find(commonTag,endCertStartIdx2);
if(endCertEndIdx==std::string::npos || endCertEndIdx>=lengthOfCert)
{
std::cerr<<"Certificate corrupted beyond repair: No <------END > tag"<<std::endl;
return badCertificate;
}
/*
Copying the begin tag(-----BEGIN) to the clean certificate
*/
for(int i=0;i<strlen(beginCertTag);i++)
{
cleanCertificate[currCleanCertIdx+i]=beginCertTag[i];
}
currCleanCertIdx=currCleanCertIdx+strlen(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[currCleanCertIdx]=badCertificate[currBadCertIdx];
currCleanCertIdx++;
currBadCertIdx++;
}
}
/*
If the last character is a space we need to remove it.
*/
if(cleanCertificate[currCleanCertIdx-1]==' ')
{
currCleanCertIdx--;
}
/*
Copying the end part of the certificate start tag(-----).
*/
for(int i=0;i<strlen(commonTag);i++)
{
cleanCertificate[currCleanCertIdx]='-';
currCleanCertIdx++;
}
cleanCertificate[currCleanCertIdx]='\n';
currCleanCertIdx++;
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++;
}
//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[currCleanCertIdx]='\n';
currCleanCertIdx++;
cntPerLine=0;
continue;
}
else if(badCertificate[currBadCertIdx]==' ')
{
currBadCertIdx++;
continue;
}
else if(badCertificate[currBadCertIdx]=='\n')
{
currBadCertIdx++;
continue;
}
cleanCertificate[currCleanCertIdx]=badCertificate[currBadCertIdx];
cntPerLine++;
currCleanCertIdx++;
currBadCertIdx++;
}
if(cleanCertificate[currCleanCertIdx-1]!='\n')
{
cleanCertificate[currCleanCertIdx]='\n';
currCleanCertIdx++;
// 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.
*/
for(int i=0;i<strlen(endCertTag);i++)
{
cleanCertificate[currCleanCertIdx+i]=endCertTag[i];
}
currCleanCertIdx=currCleanCertIdx+strlen(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[currCleanCertIdx]=badCertificate[currBadCertIdx];
currCleanCertIdx++;
currBadCertIdx++;
}
}
/*
If the last character is a space we need to remove it.
*/
if(cleanCertificate[currCleanCertIdx-1]==' ')
{
currCleanCertIdx--;
}
/*
Copying the end part(-----) of the end tag in the certificate.
*/
for(int i=0;i<strlen(commonTag);i++)
{
cleanCertificate[currCleanCertIdx]='-';
currCleanCertIdx++;
}
cleanCertificate[currCleanCertIdx]='\n';
currCleanCertIdx++;
/*
Copying over the cleaned certificate to a new buffer.
*/
char * cleanCert=new char[currCleanCertIdx+1];
for(int i=0;i<currCleanCertIdx;i++ )
{
cleanCert[i]=cleanCertificate[i];
}
cleanCert[currCleanCertIdx]='\0';
std::string cleanCertificateStr=cleanCert;
delete cleanCertificate;
//delete cleanCert;
return cleanCertificateStr;
}
int findEndIdxOfCertStartTag(std::string badCertificate)
{
int idxTag1=0;
int tmpIdx=0;
int idxTag2=0;
char * tag1="---";
char * tag2="---";
bool found=false;
while(found==false && (idxTag1=badCertificate.find(tag1,tmpIdx))!=std::string::npos)
{
idxTag2=badCertificate.find(tag2,idxTag1+strlen(tag1));
if(idxTag2!=std::string::npos)
{
found=true;
for(int i=idxTag1+strlen(tag1);i<idxTag2;i++)
{
if(badCertificate[i]!=' ')
{
found=false;
break;
}
}
}
else
{
break;
}
}
return 1;
}

View File

@ -0,0 +1,55 @@
/*
* libretroshare/src/pqi: cleanupxpgp.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2008 by Sourashis Roy
*
* 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 CLEANUPPXPGP_H
#define CLEANUPPXPGP_H
#include <string>
#include <iostream>
#include <string.h> //strlen
//! Converts invitation to clean XPGP certificate
//! This function was used for extracting XPGP certificates from invitation
//!letters. Typical input was something like
//! You have been invited to join the retroshare community by: beardog-unstable-02
//!
//! Retroshare is a Friend-2-Friend network that enables you to communicate securely and privately ....
//! ... text stuff .....
//!
//!-----BEGIN XPGP CERTIFICATE-----
//!MIICxQIBADCCAUkCAQAwHhcNMDkwMjI4MTgzODIyWhcNMTQwMjI3MTgzODIyWjCC
//! ...more ines here...
//!mEuhG8UmDIzC1jeTu8rTMnO+DO3FH/cek1vlfFl4t9g/xktG9U4SPLg=
//!-----END XPGP CERTIFICATE-----
//!
//! In the newer gui version, users send each other almost clean certificates,
//! so this functon is used only to avoid possible bugs with line endings
std::string cleanUpCertificate(std::string badCertificate);
int findEndIdxOfCertStartTag(std::string badCertificate);
#endif // CLEANUPPXPGP_H

View File

@ -0,0 +1,302 @@
/*
* libretroshare/src/pqi: p3authmgr.cc
*
* 3P/PQI network interface for RetroShare.
*
* 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 <stdint.h>
#include <iostream>
#include "_pqi/p3authmgr.h"
pqiAuthDetails::pqiAuthDetails()
:trustLvl(0), validLvl(0), ownsign(false), trusted(false)
{
return;
}
p3DummyAuthMgr::p3DummyAuthMgr()
{
/* for the truely dummy option */
mOwnId = "OWNID";
pqiAuthDetails ownDetails;
ownDetails.id = mOwnId;
ownDetails.name = "Youself";
ownDetails.email = "me@me.com";
ownDetails.location = "here";
ownDetails.org = "me.com";
ownDetails.trustLvl = 6;
ownDetails.ownsign = true;
ownDetails.trusted = true;
/* ignoring fpr and signers */
mPeerList[mOwnId] = ownDetails;
}
bool p3DummyAuthMgr::isTrustingMe(std::string id)
{
std::cerr << "isTrustingMe is not implemented in p3DummyAuthMgr. Look into authxpgp.cc." << std::endl ;
return false ;
}
void p3DummyAuthMgr::addTrustingPeer(std::string id)
{
std::cerr << "addTrustingPeer is not implemented in p3DummyAuthMgr. Look into authxpgp.cc." << std::endl ;
}
p3DummyAuthMgr::p3DummyAuthMgr(std::string ownId, std::list<pqiAuthDetails> peers)
{
mOwnId = ownId;
bool addedOwn = false;
std::list<pqiAuthDetails>::iterator it;
for(it = peers.begin(); it != peers.end(); it++)
{
mPeerList[it->id] = (*it);
if (it->id == ownId)
{
addedOwn = true;
}
}
if (!addedOwn)
{
pqiAuthDetails ownDetails;
ownDetails.id = mOwnId;
ownDetails.name = "Youself";
ownDetails.email = "me@me.com";
ownDetails.location = "here";
ownDetails.org = "me.com";
ownDetails.trustLvl = 6;
ownDetails.ownsign = true;
ownDetails.trusted = true;
/* ignoring fpr and signers */
mPeerList[mOwnId] = ownDetails;
}
}
bool p3DummyAuthMgr:: active()
{
return true;
}
int p3DummyAuthMgr::InitAuth(const char *srvr_cert, const char *priv_key,
const char *passwd)
{
return 1;
}
bool p3DummyAuthMgr::CloseAuth()
{
return true;
}
int p3DummyAuthMgr::setConfigDirectories(std::string confFile, std::string neighDir)
{
return 1;
}
std::string p3DummyAuthMgr::OwnId()
{
return mOwnId;
}
bool p3DummyAuthMgr::getAllList(std::list<std::string> &ids)
{
std::map<std::string, pqiAuthDetails>::iterator it;
for(it = mPeerList.begin(); it != mPeerList.end(); it++)
{
ids.push_back(it->first);
}
return true;
}
bool p3DummyAuthMgr::getAuthenticatedList(std::list<std::string> &ids)
{
std::map<std::string, pqiAuthDetails>::iterator it;
for(it = mPeerList.begin(); it != mPeerList.end(); it++)
{
if (it->second.trustLvl > 3)
{
ids.push_back(it->first);
}
}
return true;
}
bool p3DummyAuthMgr::getUnknownList(std::list<std::string> &ids)
{
std::map<std::string, pqiAuthDetails>::iterator it;
for(it = mPeerList.begin(); it != mPeerList.end(); it++)
{
if (it->second.trustLvl <= 3)
{
ids.push_back(it->first);
}
}
return true;
}
bool p3DummyAuthMgr::isValid(std::string id)
{
std::map<std::string, pqiAuthDetails>::iterator it;
return (mPeerList.end() != mPeerList.find(id));
}
bool p3DummyAuthMgr::isAuthenticated(std::string id)
{
std::map<std::string, pqiAuthDetails>::iterator it;
if (mPeerList.end() != (it = mPeerList.find(id)))
{
return (it->second.trustLvl > 3);
}
return false;
}
std::string p3DummyAuthMgr::getName(std::string id)
{
std::map<std::string, pqiAuthDetails>::iterator it;
if (mPeerList.end() != (it = mPeerList.find(id)))
{
return it->second.name;
}
std::string empty("");
return empty;
}
bool p3DummyAuthMgr::getDetails(std::string id, pqiAuthDetails &details)
{
std::map<std::string, pqiAuthDetails>::iterator it;
if (mPeerList.end() != (it = mPeerList.find(id)))
{
details = it->second;
return true;
}
return false;
}
bool p3DummyAuthMgr::FinalSaveCertificates()
{
return false;
}
bool p3DummyAuthMgr::CheckSaveCertificates()
{
return false;
}
bool p3DummyAuthMgr::saveCertificates()
{
return false;
}
bool p3DummyAuthMgr::loadCertificates()
{
return false;
}
bool p3DummyAuthMgr::LoadCertificateFromString(std::string pem, std::string &id)
{
return false;
}
std::string p3DummyAuthMgr::SaveCertificateToString(std::string id)
{
std::string dummy("CERT STRING");
return dummy;
}
bool p3DummyAuthMgr::LoadCertificateFromFile(std::string filename, std::string &id)
{
return false;
}
bool p3DummyAuthMgr::SaveCertificateToFile(std::string id, std::string filename)
{
return false;
}
bool p3DummyAuthMgr::LoadCertificateFromBinary(const uint8_t *ptr, uint32_t len, std::string &id)
{
return false;
}
bool p3DummyAuthMgr::SaveCertificateToBinary(std::string id, uint8_t **ptr, uint32_t *len)
{
return false;
}
/* Signatures */
bool p3DummyAuthMgr::AuthCertificate(std::string id)
{
return false;
}
bool p3DummyAuthMgr::SignCertificate(std::string id)
{
return false;
}
bool p3DummyAuthMgr::RevokeCertificate(std::string id)
{
return false;
}
bool p3DummyAuthMgr::TrustCertificate(std::string id, bool trust)
{
return false;
}
bool p3DummyAuthMgr::SignData(std::string input, std::string &sign)
{
return false;
}
bool p3DummyAuthMgr::SignData(const void *data, const uint32_t len, std::string &sign)
{
return false;
}
bool p3DummyAuthMgr::SignDataBin(std::string input,
unsigned char *sign, unsigned int *signlen)
{
return false;
}
bool p3DummyAuthMgr::SignDataBin(const void *data, const uint32_t len,
unsigned char *sign, unsigned int *signlen)
{
return false;
}
bool p3DummyAuthMgr::VerifySignBin(std::string pid,
const void *data, const uint32_t len,
unsigned char *sign, unsigned int signlen)
{
return false;
}

View File

@ -0,0 +1,222 @@
/*
* libretroshare/src/pqi: p3authmgr.h
*
* 3P/PQI network interface for RetroShare.
*
* 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".
*
*/
#ifndef RS_GENERIC_AUTH_HEADER
#define RS_GENERIC_AUTH_HEADER
#include <list>
#include <map>
#include <string>
/************** GENERIC AUTHENTICATION MANAGER ***********
* Provides a common interface for certificates.
*
* Initialisation must be done in derived classes
*
* Key features:
* everything indexed by std::string id;
* has auth perspective: authed / not authed - different to friends.
* load/save certificates as strings or files.
*
*/
class p3AuthMgr;
extern p3AuthMgr *authMgr;
p3AuthMgr *getAuthMgr();
class pqiAuthDetails
{
public:
pqiAuthDetails();
std::string id;
std::string name;
std::string email;
std::string location;
std::string org;
std::string issuer;
std::string fpr; /* fingerprint */
std::list<std::string> signers;
uint32_t trustLvl;
uint32_t validLvl;
bool ownsign;
bool trusted; // means valid in pgp world.
};
class p3AuthMgr
{
public:
virtual ~p3AuthMgr() { return; }
/* initialisation -> done by derived classes */
virtual bool active() = 0;
virtual int InitAuth(const char *srvr_cert, const char *priv_key,
const char *passwd) = 0;
virtual bool CloseAuth() = 0;
virtual int setConfigDirectories(std::string confFile, std::string neighDir) = 0;
/* get Certificate Ids */
virtual std::string OwnId() = 0;
virtual bool getAllList(std::list<std::string> &ids) = 0;
virtual bool getAuthenticatedList(std::list<std::string> &ids) = 0;
virtual bool getUnknownList(std::list<std::string> &ids) = 0;
/* get Details from the Certificates */
virtual bool isValid(std::string id) = 0;
virtual bool isAuthenticated(std::string id) = 0;
virtual std::string getName(std::string id) = 0;
virtual std::string getIssuerName(std::string id) { return getName(id); } // Default to same id.
virtual bool getDetails(std::string id, pqiAuthDetails &details) = 0;
/* High Level Load/Save Configuration */
virtual bool FinalSaveCertificates() = 0;
virtual bool CheckSaveCertificates() = 0;
virtual bool saveCertificates() = 0;
virtual bool loadCertificates() = 0;
/* first party trust info */
virtual bool isTrustingMe(std::string id) = 0;
virtual void addTrustingPeer(std::string id) = 0;
/* Extra Fns for PGP, call std versions if not overloaded */
virtual std::string PGPOwnId() { return OwnId(); }
virtual bool getPGPAllList(std::list<std::string> &ids) { return getAllList(ids); };
/* Load/Save certificates */
virtual bool LoadCertificateFromString(std::string pem, std::string &id) = 0;
virtual std::string SaveCertificateToString(std::string id) = 0;
virtual bool LoadCertificateFromFile(std::string filename, std::string &id) = 0;
virtual bool SaveCertificateToFile(std::string id, std::string filename) = 0;
/* specific OpenSSL ones -> careful with pointers....
* save will allocate space,
*/
virtual bool LoadCertificateFromBinary(const uint8_t *ptr, uint32_t len, std::string &id) = 0;
virtual bool SaveCertificateToBinary(std::string id, uint8_t **ptr, uint32_t *len) = 0;
/* Signatures */
virtual bool AuthCertificate(std::string uid) = 0;
virtual bool SignCertificate(std::string id) = 0;
virtual bool RevokeCertificate(std::string id) = 0;
virtual bool TrustCertificate(std::string id, bool trust) = 0;
/* Sign / Encrypt / Verify Data (TODO) */
virtual bool SignData(std::string input, std::string &sign) = 0;
virtual bool SignData(const void *data, const uint32_t len, std::string &sign) = 0;
virtual bool SignDataBin(std::string input, unsigned char *sign, unsigned int *signlen) = 0;
virtual bool SignDataBin(const void *data, const uint32_t len,
unsigned char *sign, unsigned int *signlen) = 0;
virtual bool VerifySignBin(std::string pid,
const void *data, const uint32_t len,
unsigned char *sign, unsigned int signlen) = 0;
//virtual bool encryptData(std::string recipientId, std::string plaindata, std::string &result);
};
class p3DummyAuthMgr: public p3AuthMgr
{
public:
p3DummyAuthMgr();
p3DummyAuthMgr(std::string ownId, std::list<pqiAuthDetails> peers);
/* initialisation -> done by derived classes */
virtual bool active();
virtual int InitAuth(const char *srvr_cert, const char *priv_key,
const char *passwd);
virtual bool CloseAuth();
virtual int setConfigDirectories(std::string confFile, std::string neighDir);
/* get Certificate Ids */
virtual std::string OwnId();
virtual bool getAllList(std::list<std::string> &ids);
virtual bool getAuthenticatedList(std::list<std::string> &ids);
virtual bool getUnknownList(std::list<std::string> &ids);
/* get Details from the Certificates */
virtual bool isValid(std::string id);
virtual bool isAuthenticated(std::string id);
virtual std::string getName(std::string id);
virtual bool getDetails(std::string id, pqiAuthDetails &details);
/* High Level Load/Save Configuration */
virtual bool FinalSaveCertificates();
virtual bool CheckSaveCertificates();
virtual bool saveCertificates();
virtual bool loadCertificates();
/* first party trust info */
virtual bool isTrustingMe(std::string id) ;
virtual void addTrustingPeer(std::string id) ;
/* Load/Save certificates */
virtual bool LoadCertificateFromString(std::string pem, std::string &id);
virtual std::string SaveCertificateToString(std::string id);
virtual bool LoadCertificateFromFile(std::string filename, std::string &id);
virtual bool SaveCertificateToFile(std::string id, std::string filename);
virtual bool LoadCertificateFromBinary(const uint8_t *ptr, uint32_t len, std::string &id);
virtual bool SaveCertificateToBinary(std::string id, uint8_t **ptr, uint32_t *len);
/* Signatures */
virtual bool AuthCertificate(std::string uid);
virtual bool SignCertificate(std::string id);
virtual bool RevokeCertificate(std::string id);
virtual bool TrustCertificate(std::string id, bool trust);
virtual bool SignData(std::string input, std::string &sign);
virtual bool SignData(const void *data, const uint32_t len, std::string &sign);
virtual bool SignDataBin(std::string input, unsigned char *sign, unsigned int *signlen);
virtual bool SignDataBin(const void *data, const uint32_t len,
unsigned char *sign, unsigned int *signlen);
virtual bool VerifySignBin(std::string pid,
const void *data, const uint32_t len,
unsigned char *sign, unsigned int signlen);
std::string mOwnId;
std::map<std::string, pqiAuthDetails> mPeerList;
};
#endif

View File

@ -0,0 +1,714 @@
/*
* libretroshare/src/pqi: p3cfgmgr.cc
*
* 3P/PQI network interface for RetroShare.
*
* 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 "util/rsdir.h"
#include "rsiface/rspeers.h"
#include "pqi/p3cfgmgr.h"
#include "pqi/p3authmgr.h"
#include "pqi/pqibin.h"
#include "pqi/pqistore.h"
#include "pqi/pqinotify.h"
#include <errno.h>
#include "serialiser/rsconfigitems.h"
/****
* #define CONFIG_DEBUG 1
***/
p3ConfigMgr::p3ConfigMgr(p3AuthMgr *am, std::string dir, std::string fname, std::string signame)
:mAuthMgr(am), basedir(dir), metafname(fname), metasigfname(signame),
mConfigSaveActive(true)
{
}
void p3ConfigMgr::tick()
{
bool toSave = false;
{
RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/
/* iterate through and check if any have changed */
std::map<uint32_t, pqiConfig *>::iterator it;
for(it = configs.begin(); it != configs.end(); it++)
{
if (it->second->HasConfigChanged(0))
{
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::tick() Config Changed - Element: ";
std::cerr << it->first;
std::cerr << std::endl;
#endif
toSave = true;
}
}
/* disable saving before exit */
if (!mConfigSaveActive)
{
toSave = false;
}
}
if (toSave)
{
saveConfiguration();
}
}
void p3ConfigMgr::saveConfiguration()
{
RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::saveConfiguration()";
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::saveConfiguration() Saving Element: ";
std::cerr << it->first;
std::cerr << std::endl;
#endif
it->second->saveConfiguration();
}
/* save metaconfig */
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::saveConfiguration() 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;
{
std::ostringstream out;
out << it->first;
kv.key = out.str();
}
kv.value = it->second->Hash();
item->tlvkvs.pairs.push_back(kv);
}
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::saveConfiguration() Complete MetaConfigItem: ";
std::cerr << std::endl;
item->print(std::cerr, 20);
#endif
/* construct filename */
std::string filename1 = basedir;
std::string filename2 = basedir;
if (basedir != "")
{
filename1 += "/";
filename2 += "/";
}
filename1 += metasigfname;
filename2 += metafname;
/* Write the data to a stream */
uint32_t bioflags = BIN_FLAGS_WRITEABLE;
BinMemInterface *membio = new BinMemInterface(1000, bioflags);
RsSerialiser *rss = new RsSerialiser();
rss->addSerialType(new RsGeneralConfigSerialiser());
pqistore store(rss, "CONFIG", membio, BIN_FLAGS_WRITEABLE);
store.SendItem(item);
/* sign data */
std::string signature;
mAuthMgr->SignData(membio->memptr(), membio->memsize(), signature);
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::saveConfiguration() MetaFile Signature:";
std::cerr << std::endl;
std::cerr << signature;
std::cerr << std::endl;
#endif
if (!membio->writetofile(filename2.c_str()))
{
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::saveConfiguration() Failed to Write MetaFile " << filename2 ;
std::cerr << std::endl;
#endif
}
/* write signature to configuration */
BinMemInterface *signbio = new BinMemInterface(signature.c_str(),
signature.length(), BIN_FLAGS_READABLE);
if (!signbio->writetofile(filename1.c_str()))
{
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::saveConfiguration() Failed to Write MetaSignFile" << filename1 ;
std::cerr << std::endl;
#endif
}
delete signbio;
}
void p3ConfigMgr::loadConfiguration()
{
RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::loadConfiguration()";
std::cerr << std::endl;
#endif
/* construct filename */
std::string filename1 = basedir;
std::string filename2 = basedir;
if (basedir != "")
{
filename1 += "/";
filename2 += "/";
}
filename1 += metasigfname;
filename2 += metafname;
/* write signature to configuration */
BinMemInterface *signbio = new BinMemInterface(1000, BIN_FLAGS_READABLE);
if (!signbio->readfromfile(filename1.c_str()))
{
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::loadConfiguration() 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.
*/
filename1 = metasigfname;
filename2 = metafname;
if (!signbio->readfromfile(filename1.c_str()))
{
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::loadConfiguration() HACK: Failed to Load ALT MetaSignFile";
std::cerr << std::endl;
#endif
}
else
{
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::loadConfiguration() HACK: Loaded ALT MetaSignFile";
std::cerr << std::endl;
#endif
}
}
std::string oldsignature((char *) signbio->memptr(), signbio->memsize());
delete signbio;
BinMemInterface *membio = new BinMemInterface(1000, BIN_FLAGS_READABLE);
if (!membio->readfromfile(filename2.c_str()))
{
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::loadConfiguration() Failed to Load MetaFile";
std::cerr << std::endl;
#endif
// delete membio;
// return ;
}
/* get signature */
std::string signature;
mAuthMgr->SignData(membio->memptr(), membio->memsize(), signature);
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::loadConfiguration() New MetaFile Signature:";
std::cerr << std::endl;
std::cerr << signature;
std::cerr << std::endl;
#endif
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::loadConfiguration() 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::loadConfiguration() Signature Check Failed";
std::cerr << std::endl;
#endif
return;
}
membio->fseek(0); /* go to start */
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 NOT CHANGED */
cit->second->HasConfigChanged(0);
cit->second->HasConfigChanged(1);
}
}
delete item;
#ifdef CONFIG_DEBUG
std::cerr << "p3ConfigMgr::loadConfiguration() Done!";
std::cerr << std::endl;
#endif
}
void p3ConfigMgr::addConfiguration(std::string file, pqiConfig *conf)
{
RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/
/* construct filename */
std::string filename = basedir;
if (basedir != "")
{
filename += "/";
}
filename += file;
conf->setFilename(filename);
configs[conf->Type()] = conf;
}
void p3ConfigMgr::completeConfiguration()
{
saveConfiguration();
RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/
mConfigSaveActive = false;
}
p3Config::p3Config(uint32_t t)
:pqiConfig(t)
{
return;
}
bool p3Config::loadConfiguration(std::string &loadHash)
{
std::list<RsItem *> load;
std::list<RsItem *>::iterator it;
std::string fname = Filename();
uint32_t bioflags = BIN_FLAGS_HASH_DATA | BIN_FLAGS_READABLE;
uint32_t stream_flags = BIN_FLAGS_READABLE;
BinInterface *bio = new BinFileInterface(fname.c_str(), bioflags);
pqistore stream(setupSerialiser(), "CONFIG", bio, stream_flags);
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: " << fname;
std::cerr << std::endl;
#endif
/* check hash */
std::string hashstr = bio->gethash();
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("");
return false;
}
setHash(hashstr);
/* else okay */
return loadList(load);
}
bool p3Config::saveConfiguration()
{
bool cleanup = true;
std::list<RsItem *> toSave = saveList(cleanup);
std::string fname = Filename();
std::string fnametmp = Filename()+".tmp";
std::cerr << "Writting p3config file " << fname.c_str() << std::endl ;
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::saveConfiguration() toSave " << toSave.size();
std::cerr << " Elements to File: " << fname;
std::cerr << std::endl;
#endif
uint32_t bioflags = BIN_FLAGS_HASH_DATA | BIN_FLAGS_WRITEABLE;
uint32_t stream_flags = BIN_FLAGS_WRITEABLE;
if (!cleanup)
stream_flags |= BIN_FLAGS_NO_DELETE;
BinInterface *bio = new BinFileInterface(fnametmp.c_str(), bioflags);
pqistore *stream = new pqistore(setupSerialiser(), "CONFIG", bio, stream_flags);
std::list<RsItem *>::iterator it;
bool written = true ;
for(it = toSave.begin(); it != toSave.end(); it++)
{
#ifdef CONFIG_DEBUG
std::cerr << "p3Config::saveConfiguration() save item:";
std::cerr << std::endl;
(*it)->print(std::cerr, 0);
std::cerr << std::endl;
#endif
written = written && stream->SendItem(*it);
// std::cerr << "written = " << written << std::endl ;
}
/* store the hash */
setHash(bio->gethash());
saveDone(); /* callback to inherited class to unlock any Mutexes
* protecting saveList() data
*/
delete stream ;
if(!written)
return false ;
std::cerr << "renaming " << fnametmp.c_str() << " to " << fname.c_str() << std::endl ;
if(!RsDirUtil::renameFile(fnametmp,fname))
{
std::ostringstream errlog;
#ifdef WIN32
errlog << "Error " << GetLastError() ;
#else
errlog << "Error " << errno ;
#endif
getPqiNotify()->AddSysMessage(0, RS_SYS_WARNING, "File rename error", "Error while renaming file " + fname + ": got error "+errlog.str());
return false ;
}
std::cerr << "Successfully wrote p3config file " << fname.c_str() << std::endl ;
/* else okay */
return true;
}
/**************************** CONFIGURATION CLASSES ********************/
p3GeneralConfig::p3GeneralConfig()
:p3Config(CONFIG_TYPE_GENERAL)
{
return;
}
// General Configuration System
std::string p3GeneralConfig::getSetting(std::string opt)
{
#ifdef CONFIG_DEBUG
std::cerr << "p3GeneralConfig::getSetting(" << opt << ")";
std::cerr << std::endl;
#endif
RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/
/* extract from config */
std::map<std::string, std::string>::iterator it;
if (settings.end() == (it = settings.find(opt)))
{
std::string nullstring;
return nullstring;
}
return it->second;
}
void p3GeneralConfig::setSetting(std::string opt, std::string val)
{
#ifdef CONFIG_DEBUG
std::cerr << "p3GeneralConfig::setSetting(" << opt << " = " << val << ")";
std::cerr << std::endl;
#endif
{
RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/
/* extract from config */
std::map<std::string, std::string>::iterator it;
if (settings.end() != (it = settings.find(opt)))
{
if (it->second == val)
{
/* no change */
return;
}
}
settings[opt] = val;
}
/* outside mutex */
IndicateConfigChanged();
return;
}
RsSerialiser *p3GeneralConfig::setupSerialiser()
{
RsSerialiser *rss = new RsSerialiser();
rss->addSerialType(new RsGeneralConfigSerialiser());
return rss;
}
std::list<RsItem *> p3GeneralConfig::saveList(bool &cleanup)
{
RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/
#ifdef CONFIG_DEBUG
std::cerr << "p3GeneralConfig::saveList() KV sets: " << settings.size();
std::cerr << std::endl;
#endif
cleanup = true;
std::list<RsItem *> savelist;
RsConfigKeyValueSet *item = new RsConfigKeyValueSet();
std::map<std::string, std::string>::iterator it;
for(it = settings.begin(); it != settings.end(); it++)
{
RsTlvKeyValue kv;
kv.key = it->first;
kv.value = it->second;
item->tlvkvs.pairs.push_back(kv);
/* make sure we don't overload it */
if (item->tlvkvs.TlvSize() > 4000)
{
savelist.push_back(item);
item = new RsConfigKeyValueSet();
}
}
if (item->tlvkvs.pairs.size() > 0)
{
savelist.push_back(item);
}
return savelist;
}
bool p3GeneralConfig::loadList(std::list<RsItem *> load)
{
#ifdef CONFIG_DEBUG
std::cerr << "p3GeneralConfig::loadList() count: " << load.size();
std::cerr << std::endl;
#endif
RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/
/* add into settings */
RsConfigKeyValueSet *item = NULL;
std::list<RsItem *>::iterator it;
std::list<RsTlvKeyValue>::iterator kit;
for(it = load.begin(); it != load.end();)
{
item = dynamic_cast<RsConfigKeyValueSet *>(*it);
if (item)
{
for(kit = item->tlvkvs.pairs.begin();
kit != item->tlvkvs.pairs.end(); kit++)
{
settings[kit->key] = kit->value;
}
}
/* cleanup */
delete (*it);
it = load.erase(it);
}
return true;
}
/**** MUTEX NOTE:
* have protected all, but think that
* only the Indication and hash really need it
*/
pqiConfig::pqiConfig(uint32_t t)
:ConfInd(2), type(t)
{
return;
}
pqiConfig::~pqiConfig()
{
return;
}
uint32_t pqiConfig::Type()
{
RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/
return type;
}
std::string pqiConfig::Filename()
{
RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/
return filename;
}
std::string pqiConfig::Hash()
{
RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/
return hash;
}
void pqiConfig::IndicateConfigChanged()
{
RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/
ConfInd.IndicateChanged();
}
bool pqiConfig::HasConfigChanged(uint16_t idx)
{
RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/
return ConfInd.Changed(idx);
}
void pqiConfig::setFilename(std::string name)
{
RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/
filename = name;
}
void pqiConfig::setHash(std::string h)
{
RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/
hash = h;
}

View File

@ -0,0 +1,228 @@
/*
* libretroshare/src/pqi: p3cfgmgr.h
*
* 3P/PQI network interface for RetroShare.
*
* 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".
*
*/
#ifndef P3CFGMGR_H
#define P3CFGMGR_H
#include <string>
#include <map>
#include "_pqi/pqi_base.h"
#include "_pqi/pqiindic.h"
#include "_pqi/pqinetwork.h"
#include "_util/rsthreads.h"
#include "_pqi/pqibin.h"
#include "_pqi/pqistore.h"
#include "_pqi/pqinotify.h"
#include "_pqi/p3authmgr.h"
#include "_util/rsdir.h"
#include "_rsiface/rspeers.h"
#include <errno.h>
/***** Configuration Management *****
*
* we need to store:
* (1) Certificates.
* (2) List of Friends / Net Configuration
* (3) Stun List. / DHT peers.
* (4) general config.
*
*
* At top level we need:
*
* - type / filename / size / hash -
* and the file signed...
*
*
*/
/**** THESE are STORED in CONFIGURATION FILES....
* Cannot be changed
*
*********************/
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;
/* new FileTransfer */
const uint32_t CONFIG_TYPE_FT_SHARED = 0x0007;
const uint32_t CONFIG_TYPE_FT_EXTRA_LIST= 0x0008;
const uint32_t CONFIG_TYPE_FT_CONTROL = 0x0009;
/* turtle router */
const uint32_t CONFIG_TYPE_TURTLE = 0x0020;
/* wish these ids where higher...
* may move when switch to v0.5
*/
const uint32_t CONFIG_TYPE_RANK_LINK = 0x0011;
const uint32_t CONFIG_TYPE_CHAT = 0x0012;
/* standard services */
const uint32_t CONFIG_TYPE_QBLOG = 0x0101;
const uint32_t CONFIG_TYPE_FORUMS = 0x0102;
const uint32_t CONFIG_TYPE_CHANNELS = 0x0103;
/* CACHE ID Must be at the END so that other configurations
* are loaded First (Cache Config --> Cache Loading)
*/
const uint32_t CONFIG_TYPE_CACHE = 0xff01;
class p3ConfigMgr;
class p3AuthMgr;
class pqiConfig
{
public:
pqiConfig(uint32_t t);
virtual ~pqiConfig();
virtual bool loadConfiguration(std::string &loadHash) = 0;
virtual bool saveConfiguration() = 0;
uint32_t Type();
std::string Filename();
std::string Hash();
protected:
void IndicateConfigChanged();
void setHash(std::string h);
RsMutex cfgMtx;
private:
void setFilename(std::string name);
bool HasConfigChanged(uint16_t idx);
Indicator ConfInd;
uint32_t type;
std::string filename;
std::string hash;
friend class p3ConfigMgr;
/* so it can access:
* setFilename() and HasConfigChanged()
*/
};
/**** MUTEX NOTE
* None - because no-one calls any functions
* besides tick() when the system is running.
*/
class p3ConfigMgr
{
public:
p3ConfigMgr(p3AuthMgr *am, std::string bdir, std::string fname, std::string signame);
void tick();
void saveConfiguration();
void loadConfiguration();
void addConfiguration(std::string file, pqiConfig *conf);
/* saves config, and disables further saving
* used for exiting the system
*/
void completeConfiguration();
private:
/* these are constants - so shouldn't need mutex */
p3AuthMgr *mAuthMgr;
const std::string basedir;
const std::string metafname;
const std::string metasigfname;
RsMutex cfgMtx; /* below is protected */
bool mConfigSaveActive;
std::map<uint32_t, pqiConfig *> configs;
};
class p3Config: public pqiConfig
{
public:
p3Config(uint32_t t);
virtual bool loadConfiguration(std::string &loadHash);
virtual bool saveConfiguration();
protected:
/* Key Functions to be overloaded for Full Configuration */
virtual RsSerialiser *setupSerialiser() = 0;
virtual std::list<RsItem *> saveList(bool &cleanup) = 0;
virtual bool loadList(std::list<RsItem *> load) = 0;
/**
* callback for mutex unlocking
* in derived classes (should only be needed if cleanup = false)
*/
virtual void saveDone() { return; }
}; /* end of p3Config */
class p3GeneralConfig: public p3Config
{
public:
p3GeneralConfig();
// General Configuration System
std::string getSetting(std::string opt);
void setSetting(std::string opt, std::string val);
protected:
/* Key Functions to be overloaded for Full Configuration */
virtual RsSerialiser *setupSerialiser();
virtual std::list<RsItem *> saveList(bool &cleanup);
virtual bool loadList(std::list<RsItem *> load);
private:
/* protected by pqiConfig mutex as well! */
std::map<std::string, std::string> settings;
};
#endif // P3CFGMGR_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,404 @@
/*
* libretroshare/src/pqi: p3connmgr.h
*
* 3P/PQI network interface for RetroShare.
*
* 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".
*
*/
#ifndef P3CONNMNGR_H
#define P3CONNMNGR_H
#include "_pqi/p3dhtmgr.h" // Only need it for constants.
#include "_tcponudp/tou.h"
#include "_tcponudp/extaddrfinder.h"
#include "_util/rsprint.h"
#include "_util/rsdebug.h"
#include "_serialiser/rsconfigitems.h"
#include "_pqi/pqinotify.h"
#include "_pqi/pqimonitor.h"
#include "_pqi/p3authmgr.h"
//#include "_pqi/p3dhtmgr.h"
//#include "_pqi/p3upnpmgr.h"
#include "_pqi/pqiassist.h"
#include "_pqi/p3cfgmgr.h"
#include "_util/rsthreads.h"
#include <sstream>
class ExtAddrFinder ;
/* 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;
/* Startup Modes (confirmed later) */
const uint32_t RS_NET_MODE_TRYMODE = 0x00f0;
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;
/* Actual State */
const uint32_t RS_NET_MODE_ACTUAL = 0x000f;
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;
/* 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_TCP_LOCAL = 0x0001;
const uint32_t RS_NET_CONN_TCP_EXTERNAL = 0x0002;
const uint32_t RS_NET_CONN_UDP_DHT_SYNC = 0x0010;
const uint32_t RS_NET_CONN_UDP_PEER_SYNC = 0x0020; /* coming soon */
/* extra flags */
// not sure if needed yet.
//const uint32_t RS_NET_CONN_PEERAGE = 0x0f00;
//const uint32_t RS_NET_CONN_SERVER = 0x0100; /* TCP only */
//const uint32_t RS_NET_CONN_PEER = 0x0200; /* all UDP */
/* flags of peerStatus */
const uint32_t RS_NET_FLAGS_USE_DISC = 0x0001;
const uint32_t RS_NET_FLAGS_USE_DHT = 0x0002;
const uint32_t RS_NET_FLAGS_ONLINE = 0x0004;
const uint32_t RS_NET_FLAGS_EXTERNAL_ADDR = 0x0008;
const uint32_t RS_NET_FLAGS_STABLE_UDP = 0x0010;
const uint32_t RS_NET_FLAGS_TRUSTS_ME = 0x0020;
const uint32_t RS_TCP_STD_TIMEOUT_PERIOD = 5; /* 5 seconds! */
class peerAddrInfo
{
public:
peerAddrInfo(); /* init */
bool found;
uint32_t type;
struct sockaddr_in laddr, raddr;
time_t ts;
};
class peerConnectAddress
{
public:
peerConnectAddress(); /* init */
struct sockaddr_in addr;
uint32_t delay; /* to stop simultaneous connects */
uint32_t period; /* UDP only */
uint32_t type;
time_t ts;
};
class peerConnectState
{
public:
peerConnectState(); /* init */
std::string id;
uint32_t netMode; /* EXT / UPNP / UDP / INVALID */
uint32_t visState; /* STD, GRAY, DARK */
struct sockaddr_in localaddr, serveraddr;
time_t lastcontact;
/***** Below here not stored permanently *****/
uint32_t connecttype; // RS_NET_CONN_TCP_ALL / RS_NET_CONN_UDP_ALL
time_t lastavailable;
time_t lastattempt;
std::string name;
uint32_t state;
uint32_t actions;
uint32_t source; /* most current source */
peerAddrInfo dht;
peerAddrInfo disc;
peerAddrInfo peer;
/* a list of connect attempts to make (in order) */
bool inConnAttempt;
peerConnectAddress currentConnAddr;
std::list<peerConnectAddress> connAddrs;
};
class p3ConnectMgr: public pqiConnectCb, public p3Config
{
public:
p3ConnectMgr(p3AuthMgr *authMgr);
void tick();
/*************** Setup ***************************/
void addNetAssistConnect(uint32_t type, pqiNetAssistConnect *);
void addNetAssistFirewall(uint32_t type, pqiNetAssistFirewall *);
bool checkNetAddress(); /* check our address is sensible */
/*************** External Control ****************/
bool shutdown(); /* blocking shutdown call */
bool retryConnect(std::string id);
bool getUPnPState();
bool getUPnPEnabled();
bool getDHTEnabled();
bool getIPServersEnabled() { return use_extr_addr_finder ;}
void setIPServersEnabled(bool b) ;
void getIPServersList(std::list<std::string>& ip_servers) ;
bool getNetStatusOk();
bool getNetStatusUpnpOk();
bool getNetStatusDhtOk();
bool getNetStatusExtOk();
bool getNetStatusUdpOk();
bool getNetStatusTcpOk();
bool getNetResetReq();
void setOwnNetConfig(uint32_t netMode, uint32_t visState);
bool setLocalAddress(std::string id, struct sockaddr_in addr);
bool setExtAddress(std::string id, struct sockaddr_in addr);
bool setNetworkMode(std::string id, uint32_t netMode);
bool setVisState(std::string id, uint32_t visState);
/* add/remove friends */
bool addFriend(std::string id, uint32_t netMode = RS_NET_MODE_UDP,
uint32_t visState = RS_VIS_STATE_STD , time_t lastContact = 0);
bool removeFriend(std::string);
bool addNeighbour(std::string);
/*************** External Control ****************/
/* access to network details (called through Monitor) */
const std::string getOwnId();
bool getOwnNetStatus(peerConnectState &state);
bool isFriend(std::string id);
bool isOnline(std::string id);
bool getFriendNetStatus(std::string id, peerConnectState &state);
bool getOthersNetStatus(std::string id, peerConnectState &state);
void getOnlineList(std::list<std::string> &peers);
void getFriendList(std::list<std::string> &peers);
void getOthersList(std::list<std::string> &peers);
/**************** handle monitors *****************/
void addMonitor(pqiMonitor *mon);
void removeMonitor(pqiMonitor *mon);
/******* overloaded from pqiConnectCb *************/
virtual void peerStatus(std::string id,
struct sockaddr_in laddr, struct sockaddr_in raddr,
uint32_t type, uint32_t flags, uint32_t source);
virtual void peerConnectRequest(std::string id,
struct sockaddr_in raddr, uint32_t source);
virtual void stunStatus(std::string id, struct sockaddr_in raddr, uint32_t type, uint32_t flags);
/****************** Connections *******************/
bool connectAttempt(std::string id, struct sockaddr_in &addr,
uint32_t &delay, uint32_t &period, uint32_t &type);
bool connectResult(std::string id, bool success, uint32_t flags);
protected:
/****************** Internal Interface *******************/
virtual bool enableNetAssistFirewall(bool on);
virtual bool netAssistFirewallEnabled();
virtual bool netAssistFirewallActive();
virtual bool netAssistFirewallShutdown();
virtual bool enableNetAssistConnect(bool on);
virtual bool netAssistConnectEnabled();
virtual bool netAssistConnectActive();
virtual bool netAssistConnectShutdown();
/* Assist Firewall */
bool netAssistExtAddress(struct sockaddr_in &extAddr);
bool netAssistFirewallPorts(uint16_t iport, uint16_t eport);
/* Assist Connect */
virtual bool netAssistFriend(std::string id, bool on);
virtual bool netAssistAddStun(std::string id);
virtual bool netAssistStun(bool on);
virtual bool netAssistNotify(std::string id);
virtual bool netAssistSetAddress( struct sockaddr_in &laddr,
struct sockaddr_in &eaddr,
uint32_t mode);
/* Internal Functions */
void statusTick();
void netTick();
void netStartup();
/* startup the bits */
void netDhtInit();
void netUdpInit();
void netStunInit();
void netStatusReset();
void netInit();
void netExtInit();
void netExtCheck();
void netUpnpInit();
void netUpnpCheck();
void netUdpCheck();
void netUnreachableCheck();
/* Udp / Stun functions */
bool udpInternalAddress(struct sockaddr_in iaddr);
bool udpExtAddressCheck();
void udpStunPeer(std::string id, struct sockaddr_in &addr);
void stunInit();
bool stunCheck();
void stunCollect(std::string id, struct sockaddr_in addr, uint32_t flags);
bool addBootstrapStunPeers();
/* monitor control */
void tickMonitors();
/* connect attempts */
bool retryConnectTCP(std::string id);
bool retryConnectNotify(std::string id);
/* temporary for testing */
//virtual void loadConfiguration() { return; }
protected:
/*****************************************************************/
/*********************** p3config ******************************/
/* Key Functions to be overloaded for Full Configuration */
virtual RsSerialiser *setupSerialiser();
virtual std::list<RsItem *> saveList(bool &cleanup);
virtual bool loadList(std::list<RsItem *> load);
/*****************************************************************/
#if 0
void setupOwnNetConfig(RsPeerConfigItem *item);
void addPeer(RsPeerConfigItem *item);
#endif
private:
p3AuthMgr *mAuthMgr;
std::map<uint32_t, pqiNetAssistFirewall *> mFwAgents;
std::map<uint32_t, pqiNetAssistConnect *> mDhts;
RsMutex connMtx; /* protects below */
time_t mNetInitTS;
uint32_t mNetStatus;
uint32_t mStunStatus;
uint32_t mStunFound;
bool mStunMoreRequired;
bool mStatusChanged;
std::list<pqiMonitor *> clients;
ExtAddrFinder *mExtAddrFinder ;
bool use_extr_addr_finder ;
/* external Address determination */
bool mUpnpAddrValid, mStunAddrValid;
bool mStunAddrStable;
struct sockaddr_in mUpnpExtAddr;
struct sockaddr_in mStunExtAddr;
/* network status flags (read by rsiface) */
bool netFlagOk;
bool netFlagUpnpOk;
bool netFlagDhtOk;
bool netFlagExtOk;
bool netFlagUdpOk;
bool netFlagTcpOk;
bool netFlagResetReq;
/* these are protected for testing */
protected:
void addPeer(std::string id, std::string name); /* tmp fn */
peerConnectState ownState;
std::list<std::string> mStunList;
std::map<std::string, peerConnectState> mFriendList;
std::map<std::string, peerConnectState> mOthersList;
};
#endif // P3CONNMNGR_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,263 @@
/*
* libretroshare/src/pqi: p3dhtmgr.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-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".
*
*/
#ifndef P3DHDHTMGR_H
#define P3DHDHTMGR_H
/* Interface class for DHT data */
#include <string>
#include <map>
#include <sstream>
#include <iomanip>
#include <stdio.h>
#include <openssl/sha.h>
#include "_pqi/pqinetwork.h"
#include "_util/rsthreads.h"
#include "_pqi/pqimonitor.h"
#include "_pqi/pqiassist.h"
#include "_pqi/p3connmgr.h"
#include "_util/rsprint.h"
#include "_util/rsdebug.h"
/* All other #defs are in .cc */
#define DHT_ADDR_INVALID 0xff
#define DHT_ADDR_TCP 0x01
#define DHT_ADDR_UDP 0x02
/* for DHT peer STATE */
#define DHT_PEER_OFF 0
#define DHT_PEER_INIT 1
#define DHT_PEER_SEARCH 2
#define DHT_PEER_FOUND 3
/* for DHT peer STATE (ownEntry) */
#define DHT_PEER_ADDR_KNOWN 4
#define DHT_PEER_PUBLISHED 5
/* Interface with Real DHT Implementation */
#define DHT_MODE_SEARCH 1
#define DHT_MODE_PUBLISH 1
#define DHT_MODE_NOTIFY 2
#define DHT_MODE_BOOTSTRAP 3
/* TIMEOUTS: Reference Values are set here... */
#define DHT_SEARCH_PERIOD 1800 /* PeerKeys: if we haven't found them: 30 min */
#define DHT_CHECK_PERIOD 1800 /* PeerKeys: re-lookup peer: 30 min */
#define DHT_PUBLISH_PERIOD 1800 /* OwnKey: 30 min */
#define DHT_NOTIFY_PERIOD 300 /* 5 min - Notify Check period */
/* TTLs for DHTs posts */
#define DHT_TTL_PUBLISH (DHT_PUBLISH_PERIOD + 120) // for a little overlap.
#define DHT_TTL_NOTIFY (DHT_NOTIFY_PERIOD + 60) // for time to find it...
#define DHT_TTL_BOOTSTRAP (DHT_PUBLISH_PERIOD) // To start with.
class dhtPeerEntry
{
public:
dhtPeerEntry();
std::string id;
uint32_t state;
time_t lastTS;
uint32_t notifyPending;
time_t notifyTS;
struct sockaddr_in laddr, raddr;
uint32_t type; /* ADDR_TYPE as defined above */
std::string hash1; /* SHA1 Hash of id */
std::string hash2; /* SHA1 Hash of reverse Id */
};
class p3DhtMgr: public pqiNetAssistConnect, public RsThread
{
/*
*/
public:
p3DhtMgr(std::string id, pqiConnectCb *cb);
/********** External DHT Interface ************************
* These Functions are the external interface
* for the DHT, and must be non-blocking and return quickly
*/
/* OVERLOADED From pqiNetAssistConnect. */
virtual void enable(bool on);
virtual void shutdown();
virtual void restart();
virtual bool getEnabled(); /* on */
virtual bool getActive(); /* actually working */
virtual void setBootstrapAllowed(bool on);
virtual bool getBootstrapAllowed();
/* set key data */
virtual bool setExternalInterface(struct sockaddr_in laddr,
struct sockaddr_in raddr, uint32_t type);
/* add / remove peers */
virtual bool findPeer(std::string id);
virtual bool dropPeer(std::string id);
/* post DHT key saying we should connect (callback when done) */
virtual bool notifyPeer(std::string id);
/* extract current peer status */
virtual bool getPeerStatus(std::string id,
struct sockaddr_in &laddr, struct sockaddr_in &raddr,
uint32_t &type, uint32_t &mode);
/* stun */
virtual bool enableStun(bool on);
virtual bool addStun(std::string id);
//doneStun();
/********** Higher Level DHT Work Functions ************************
* These functions translate from the strings/addresss to
* key/value pairs.
*/
public:
/* results from DHT proper */
virtual bool dhtResultNotify(std::string id);
virtual bool dhtResultSearch(std::string id,
struct sockaddr_in &laddr, struct sockaddr_in &raddr,
uint32_t type, std::string sign);
virtual bool dhtResultBootstrap(std::string idhash);
protected:
/* can block briefly (called only from thread) */
virtual bool dhtPublish(std::string id,
struct sockaddr_in &laddr,
struct sockaddr_in &raddr,
uint32_t type, std::string sign);
virtual bool dhtNotify(std::string peerid, std::string ownId,
std::string sign);
virtual bool dhtSearch(std::string id, uint32_t mode);
virtual bool dhtBootstrap(std::string storehash, std::string ownIdHash,
std::string sign); /* to publish bootstrap */
/********** Actual DHT Work Functions ************************
* These involve a very simple LOW-LEVEL interface ...
*
* publish
* search
* result
*
*/
public:
/* Feedback callback (handled here) */
virtual bool resultDHT(std::string key, std::string value);
protected:
virtual bool dhtInit();
virtual bool dhtShutdown();
virtual bool dhtActive();
virtual int status(std::ostream &out);
virtual bool publishDHT(std::string key, std::string value, uint32_t ttl);
virtual bool searchDHT(std::string key);
/********** Internal DHT Threading ************************
*
*/
public:
virtual void run();
private:
/* search scheduling */
void checkDHTStatus();
int checkStunState();
int checkStunState_Active(); /* when in active state */
int doStun();
int checkPeerDHTKeys();
int checkOwnDHTKeys();
int checkNotifyDHT();
void clearDhtData();
/* IP Bootstrap */
bool getDhtBootstrapList();
std::string BootstrapId(uint32_t bin);
std::string randomBootstrapId();
/* other feedback through callback */
// use pqiNetAssistConnect.. version pqiConnectCb *connCb;
/* protected by Mutex */
RsMutex dhtMtx;
bool mDhtOn; /* User desired state */
bool mDhtModifications; /* any user requests? */
dhtPeerEntry ownEntry;
time_t ownNotifyTS;
std::map<std::string, dhtPeerEntry> peers;
std::list<std::string> stunIds;
bool mStunRequired;
uint32_t mDhtState;
time_t mDhtActiveTS;
bool mBootstrapAllowed;
time_t mLastBootstrapListTS;
};
#endif // P3DHDHTMGR_H

View File

@ -0,0 +1,197 @@
/*
* libretroshare/src/rsserver: p3notify.cc
*
* 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 "pqi/p3notify.h"
/* external reference point */
RsNotify *rsNotify = NULL;
pqiNotify *getPqiNotify()
{
return ((p3Notify *) rsNotify);
}
/* Output for retroshare-gui */
bool p3Notify::NotifySysMessage(uint32_t &sysid, uint32_t &type,
std::string &title, std::string &msg)
{
RsStackMutex stack(noteMtx); /************* LOCK MUTEX ************/
if (pendingSysMsgs.size() > 0)
{
p3NotifySysMsg smsg = pendingSysMsgs.front();
pendingSysMsgs.pop_front();
sysid = smsg.sysid;
type = smsg.type;
title = smsg.title;
msg = smsg.msg;
return true;
}
return false;
}
/* Output for retroshare-gui */
bool p3Notify::NotifyLogMessage(uint32_t &sysid, uint32_t &type,
std::string &title, std::string &msg)
{
RsStackMutex stack(noteMtx); /************* LOCK MUTEX ************/
if (pendingLogMsgs.size() > 0)
{
p3NotifyLogMsg smsg = pendingLogMsgs.front();
pendingLogMsgs.pop_front();
sysid = smsg.sysid;
type = smsg.type;
title = smsg.title;
msg = smsg.msg;
return true;
}
return false;
}
bool p3Notify::NotifyPopupMessage(uint32_t &ptype, std::string &name, std::string &msg)
{
RsStackMutex stack(noteMtx); /************* LOCK MUTEX ************/
if (pendingPopupMsgs.size() > 0)
{
p3NotifyPopupMsg pmsg = pendingPopupMsgs.front();
pendingPopupMsgs.pop_front();
ptype = pmsg.type;
name = pmsg.name;
msg = pmsg.msg;
return true;
}
return false;
}
/* Control over Messages */
bool p3Notify::GetSysMessageList(std::map<uint32_t, std::string> &list)
{
return false;
}
bool p3Notify::GetPopupMessageList(std::map<uint32_t, std::string> &list)
{
return false;
}
bool p3Notify::SetSysMessageMode(uint32_t sysid, uint32_t mode)
{
return false;
}
bool p3Notify::SetPopupMessageMode(uint32_t ptype, uint32_t mode)
{
return false;
}
/* Input from libretroshare */
bool p3Notify::AddPopupMessage(uint32_t ptype, std::string name, std::string msg)
{
RsStackMutex stack(noteMtx); /************* LOCK MUTEX ************/
p3NotifyPopupMsg pmsg;
pmsg.type = ptype;
pmsg.name = name;
pmsg.msg = msg;
pendingPopupMsgs.push_back(pmsg);
return true;
}
bool p3Notify::AddSysMessage(uint32_t sysid, uint32_t type,
std::string title, std::string msg)
{
RsStackMutex stack(noteMtx); /************* LOCK MUTEX ************/
p3NotifySysMsg smsg;
smsg.sysid = sysid;
smsg.type = type;
smsg.title = title;
smsg.msg = msg;
pendingSysMsgs.push_back(smsg);
return true;
}
bool p3Notify::AddLogMessage(uint32_t sysid, uint32_t type,
std::string title, std::string msg)
{
RsStackMutex stack(noteMtx); /************* LOCK MUTEX ************/
p3NotifyLogMsg smsg;
smsg.sysid = sysid;
smsg.type = type;
smsg.title = title;
smsg.msg = msg;
pendingLogMsgs.push_back(smsg);
return true;
}
bool p3Notify::GetFeedItem(RsFeedItem &item)
{
RsStackMutex stack(noteMtx); /************* LOCK MUTEX ************/
if (pendingNewsFeed.size() > 0)
{
item = pendingNewsFeed.front();
pendingNewsFeed.pop_front();
return true;
}
return false;
}
bool p3Notify::AddFeedItem(uint32_t type, std::string id1, std::string id2, std::string id3)
{
RsStackMutex stack(noteMtx); /************* LOCK MUTEX ************/
pendingNewsFeed.push_back(RsFeedItem(type, id1, id2, id3));
return true;
}

View File

@ -0,0 +1,104 @@
#ifndef P3NOTIFY_H
#define P3NOTIFY_H
/*
* libretroshare/src/rsserver: p3notify.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 <stdint.h>
#include "rsiface/rsnotify.h"
#include "pqi/pqinotify.h"
#include "util/rsthreads.h"
class p3NotifySysMsg
{
public:
uint32_t sysid;
uint32_t type;
std::string title;
std::string msg;
};
class p3NotifyLogMsg
{
public:
uint32_t sysid;
uint32_t type;
std::string title;
std::string msg;
};
class p3NotifyPopupMsg
{
public:
uint32_t type;
std::string name;
std::string msg;
};
class p3Notify: public RsNotify, public pqiNotify
{
public:
p3Notify() { return; }
virtual ~p3Notify() { return; }
/* Output for retroshare-gui */
virtual bool NotifySysMessage(uint32_t &sysid, uint32_t &type,
std::string &title, std::string &msg);
virtual bool NotifyPopupMessage(uint32_t &ptype, std::string &name, std::string &msg);
virtual bool NotifyLogMessage(uint32_t &sysid, uint32_t &type, std::string &title, std::string &msg);
/* Control over Messages */
virtual bool GetSysMessageList(std::map<uint32_t, std::string> &list);
virtual bool GetPopupMessageList(std::map<uint32_t, std::string> &list);
virtual bool SetSysMessageMode(uint32_t sysid, uint32_t mode);
virtual bool SetPopupMessageMode(uint32_t ptype, uint32_t mode);
virtual bool GetFeedItem(RsFeedItem &item);
/* Overloaded from pqiNotify */
virtual bool AddPopupMessage(uint32_t ptype, std::string name, std::string msg);
virtual bool AddSysMessage(uint32_t sysid, uint32_t type, std::string title, std::string msg);
virtual bool AddLogMessage(uint32_t sysid, uint32_t type, std::string title, std::string msg);
virtual bool AddFeedItem(uint32_t type, std::string id1, std::string id2, std::string id3);
private:
RsMutex noteMtx;
std::list<p3NotifySysMsg> pendingSysMsgs;
std::list<p3NotifyLogMsg> pendingLogMsgs;
std::list<p3NotifyPopupMsg> pendingPopupMsgs;
std::list<RsFeedItem> pendingNewsFeed;
};
#endif // P3NOTIFY_H

View File

@ -0,0 +1,59 @@
/*
* libretroshare/src/pqi: p3upnpmgr.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2007 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 P3UPNPMGR_H
#define P3UPNPMGR_H
/* platform independent networking... */
#include "util/rsthreads.h"
#include "pqi/pqinetwork.h"
class p3UpnpMgr: public pqiNetAssistFirewall
{
public:
virtual ~p3UpnpMgr() { return; }
/* External Interface */
virtual void enable(bool on) = 0; /* launches thread to start it up */
virtual void shutdown() = 0; /* blocking shutdown call */
virtual void restart() = 0; /* must be called if ports change */
virtual bool getEnabled() = 0;
virtual bool getActive() = 0;
/* the address that the listening port is on */
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;
};
#endif /* P3UPNPMGR_H */

View File

@ -0,0 +1,86 @@
/*
* libretroshare/src/pqi pqi.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-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".
*
*/
#ifndef PQI_H
#define PQI_H
/* This just includes the standard headers required.
*/
#include "pqi/pqi_base.h"
#include "pqi/pqinetwork.h"
#include "serialiser/rsserial.h"
#include "serialiser/rsbaseitems.h"
#include <iostream>
#include <functional>
#include <algorithm>
/********************** SEARCH INTERFACE ***************************/
// this is an interface.... so should be
// classified as virtual = 0;
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;
};
class P3Interface: public SearchInterface
{
public:
P3Interface() {return; }
virtual ~P3Interface() {return; }
virtual int tick() { return 1; }
virtual int status() { return 1; }
virtual int SendRsRawItem(RsRawItem *) = 0;
virtual RsRawItem *GetRsRawItem() = 0;
};
#endif // PQI_H

View File

@ -1,7 +1,69 @@
INCLUDEPATH += $$PWD \
../$$PWP
DEPENDPATH += $$PWD
SOURCES = authgpg.cc \
authssl.cc \
authxpgp.cc \
cleanupxpgp.cc \
p3authmgr.cc \
pqi/p3cfgmgr.cc \
p3connmgr.cc \
p3dhtmgr.cc \
p3notify.cc \
pqi_base.cc \
pqiarchive.cc \
pqibin.cc \
pqihandler.cc \
pqihash.cc \
pqiindic.cc \
pqiloopback.cc \
pqimonitor.cc \
pqinetwork.cc \
pqiperson.cc \
pqipersongrp.cc \
pqisecurity.cc \
pqiservice.cc \
pqissl.cc \
pqissllistener.cc \
pqisslpersongrp.cc \
pqissludp.cc \
pqistore.cc \
pqistreamer.cc \
sslcert.cc \
xpgpcert.cc
SOURCES = authgpg.cc
HEADERS = authgpg.h
HEADERS = authgpg.h \
authssl.h \
authxpgp.h \
cleanupxpgp.h \
p3authmgr.h \
p3cfgmgr.h \
p3connmgr.h \
p3dhtmgr.h \
p3notify.h \
p3upnpmgr.h \
pqi.h \
pqi_base.h \
pqiarchive.h \
pqiassist.h \
pqibin.h \
pqihandler.h \
pqihash.h \
pqiindic.h \
pqilistener.h \
pqiloopback.h \
pqimonitor.h \
pqinetwork.h \
pqinotify.h \
pqiperson.h \
pqipersongrp.h \
pqisecurity.h \
pqiservice.h \
pqissl.h \
pqissllistener.h \
pqisslpersongrp.h \
pqissludp.h \
pqistore.h \
pqistreamer.h \
sslcert.h \
xpgpcert.h

View File

@ -0,0 +1,410 @@
/*
* "$Id: pqi_base.cc,v 1.17 2007-03-31 09:41:32 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".
*
*/
// CHANGED : REMOVED : REASON -> Not used in any file
#if 0
#include "pqi/pqi_base.h"
static int next_search_id = 1;
int getPQIsearchId()
{
return next_search_id++;
}
// CHANID Operations.
int pqicid_clear(ChanId *cid)
{
for(int i = 0; i < 10; i++)
{
cid -> route[i] = 0;
}
return 1;
}
int pqicid_copy(const ChanId *cid, ChanId *newcid)
{
for(int i = 0; i < 10; i++)
{
(newcid -> route)[i] = (cid -> route)[i];
}
return 1;
}
int pqicid_cmp(const ChanId *cid1, ChanId *cid2)
{
int ret = 0;
for(int i = 0; i < 10; i++)
{
ret = cid1->route[i] - cid2->route[i];
if (ret != 0)
{
return ret;
}
}
return 0;
}
int pqiroute_getshift(ChanId *id)
{
int *array = id -> route;
int next = array[0];
// shift.
for(int i = 0; i < 10 - 1; i++)
{
array[i] = array[i+1];
}
array[10 - 1] = 0;
return next;
}
int pqiroute_setshift(ChanId *id, int chan)
{
int *array = id -> route;
// shift.
for(int i = 10 - 1; i > 0; i--)
{
array[i] = array[i-1];
}
array[0] = chan;
return 1;
}
#endif
// CHANGED : REMOVED : REASON -> Not declared
#if 0 /* removing old stuff */
/****************** PERSON DETAILS ***********************/
Person::Person()
:dhtFound(false), dhtFlags(0),
lc_timestamp(0), lr_timestamp(0),
nc_timestamp(0), nc_timeintvl(5),
name("Unknown"), status(PERSON_STATUS_MANUAL)
{
for(int i = 0; i < (signed) sizeof(lastaddr); i++)
{
((unsigned char *) (&lastaddr))[i] = 0;
((unsigned char *) (&localaddr))[i] = 0;
((unsigned char *) (&serveraddr))[i] = 0;
((unsigned char *) (&dhtaddr))[i] = 0;
}
pqicid_clear(&cid);
return;
}
Person::~Person()
{
}
int Person::cidpop()
{
return pqiroute_getshift(&cid);
}
void Person::cidpush(int id)
{
pqiroute_setshift(&cid, id);
return;
}
bool Person::Group(std::string in)
{
std::list<std::string>::iterator it;
for(it = groups.begin(); it != groups.end(); it++)
{
if (in == (*it))
{
return true;
}
}
return false;
}
int Person::addGroup(std::string in)
{
groups.push_back(in);
return 1;
}
int Person::removeGroup(std::string in)
{
std::list<std::string>::iterator it;
for(it = groups.begin(); it != groups.end(); it++)
{
if (in == (*it))
{
groups.erase(it);
return 1;
}
}
return 0;
}
bool Person::Valid()
{
return (status & PERSON_STATUS_VALID);
}
void Person::Valid(bool b)
{
if (b)
status |= PERSON_STATUS_VALID;
else
status &= ~PERSON_STATUS_VALID;
}
bool Person::Accepted()
{
return (status & PERSON_STATUS_ACCEPTED);
}
void Person::Accepted(bool b)
{
if (b)
status |= PERSON_STATUS_ACCEPTED;
else
status &= ~PERSON_STATUS_ACCEPTED;
}
bool Person::InUse()
{
return (status & PERSON_STATUS_INUSE);
}
void Person::InUse(bool b)
{
if (b)
status |= PERSON_STATUS_INUSE;
else
status &= ~(PERSON_STATUS_INUSE);
}
bool Person::Listening()
{
return (status & PERSON_STATUS_LISTENING);
}
void Person::Listening(bool b)
{
if (b)
status |= PERSON_STATUS_LISTENING;
else
status &= ~PERSON_STATUS_LISTENING;
}
bool Person::Connected()
{
return (status & PERSON_STATUS_CONNECTED);
}
void Person::Connected(bool b)
{
if (b)
status |= PERSON_STATUS_CONNECTED;
else
status &= ~PERSON_STATUS_CONNECTED;
}
bool Person::WillListen()
{
return (status & PERSON_STATUS_WILL_LISTEN);
}
void Person::WillListen(bool b)
{
if (b)
status |= PERSON_STATUS_WILL_LISTEN;
else
status &= ~PERSON_STATUS_WILL_LISTEN;
}
bool Person::WillConnect()
{
return (status & PERSON_STATUS_WILL_CONNECT);
}
void Person::WillConnect(bool b)
{
if (b)
status |= PERSON_STATUS_WILL_CONNECT;
else
status &= ~PERSON_STATUS_WILL_CONNECT;
}
bool Person::Manual()
{
return (status & PERSON_STATUS_MANUAL);
}
void Person::Manual(bool b)
{
if (b)
status |= PERSON_STATUS_MANUAL;
else
status &= ~PERSON_STATUS_MANUAL;
}
bool Person::Firewalled()
{
return (status & PERSON_STATUS_FIREWALLED);
}
void Person::Firewalled(bool b)
{
if (b)
status |= PERSON_STATUS_FIREWALLED;
else
status &= ~PERSON_STATUS_FIREWALLED;
}
bool Person::Forwarded()
{
return (status & PERSON_STATUS_FORWARDED);
}
void Person::Forwarded(bool b)
{
if (b)
status |= PERSON_STATUS_FORWARDED;
else
status &= ~PERSON_STATUS_FORWARDED;
}
bool Person::Local()
{
return (status & PERSON_STATUS_LOCAL);
}
void Person::Local(bool b)
{
if (b)
status |= PERSON_STATUS_LOCAL;
else
status &= ~PERSON_STATUS_LOCAL;
}
bool Person::Trusted()
{
return (status & PERSON_STATUS_TRUSTED);
}
void Person::Trusted(bool b)
{
if (b)
status |= PERSON_STATUS_TRUSTED;
else
status &= ~PERSON_STATUS_TRUSTED;
}
unsigned int Person::Status()
{
return status;
}
void Person::Status(unsigned int s)
{
status = s;
}
std::string Person::Name()
{
return name;
}
void Person::Name(std::string n)
{
name = n;
}
/* Dynamic Address Foundation */
bool Person::hasDHT()
{
return dhtFound;
}
void Person::setDHT(struct sockaddr_in addr, unsigned int flags)
{
dhtFound = true;
dhtFlags = flags;
dhtaddr = addr;
}
/* GUI Flags */
bool Person::InChat()
{
return (status & PERSON_STATUS_INCHAT);
}
void Person::InChat(bool b)
{
if (b)
status |= PERSON_STATUS_INCHAT;
else
status &= ~PERSON_STATUS_INCHAT;
}
bool Person::InMessage()
{
return (status & PERSON_STATUS_INMSG);
}
void Person::InMessage(bool b)
{
if (b)
status |= PERSON_STATUS_INMSG;
else
status &= ~PERSON_STATUS_INMSG;
}
#endif

View File

@ -0,0 +1,461 @@
/*
* "$Id: pqi_base.h,v 1.18 2007-05-05 16:10:05 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".
*
*/
// CHANGED : REMOVED : REASON -> Not used in any file
#if 0
#ifndef PQI_BASE_H
#define PQI_BASE_H
#include <list>
#include <string>
#include <iostream>
#include <functional>
#include <algorithm>
#include <inttypes.h>
#include <ctype.h>
#include "_pqi/pqinetwork.h"
/*** Base DataTypes: ****/
#include "_serialiser/rsserial.h"
#define PQI_MIN_PORT 1024
#define PQI_MAX_PORT 50000
#define PQI_DEFAULT_PORT 7812
int getPQIsearchId();
// CHANGED: REMODED : Reason -> Not implemented
//int fixme(char *str, int n);
// local functions.
int pqiroute_setshift(ChanId *item, int chan);
int pqiroute_getshift(ChanId *item);
// these ones are also exported!
int pqicid_clear(ChanId *cid);
int pqicid_copy(const ChanId *cid, ChanId *newcid);
int pqicid_cmp(const ChanId *cid1, ChanId *cid2);
// Helper functions for the PQInterface.
#endif
#if 0 /* removing old stuff */
struct chan_id
{
int route[10];
};
typedef unsigned long SearchId; /* unsigned 32 bits */
typedef struct chan_id ChanId;
/* basic worker fns on cids */
int pqicid_clear(ChanId *cid);
int pqicid_copy(const ChanId *cid, ChanId *newcid);
int pqicid_cmp(const ChanId *cid1, ChanId *cid2);
// So the basic pqi interface defines
//
// 1) Person -> reference object
// 2) RsItem
// 3) PQInterface
// which defines:
// - send/recieve objs
// - send/recieve files
//
// This is then extended to
// 4) SInterface
// which seperates the data into providing a basic search interface.
// chat/messages/files/search objs.
//
// TODO IN THIS CLASS.
// 1) Add serialisation.... (later)
// 2) reduce base interface to the minimum.
// 3) Convert cid -> std::stack.
// Base for all Security/Id/Certificate schemes.
// The list of these must be maintained seperately
// from the RsItems....
// Person - includes
// 1) name + signature (unique id)
// 2) address + timestamps of connections.
// 3) status
// 4) groups.
//
// only requires certificate. to complete...
#define PERSON_STATUS_VALID 0x0001
#define PERSON_STATUS_ACCEPTED 0x0002
#define PERSON_STATUS_INUSE 0x0004
#define PERSON_STATUS_LISTENING 0x0008
#define PERSON_STATUS_CONNECTED 0x0010
#define PERSON_STATUS_WILL_LISTEN 0x0020
#define PERSON_STATUS_WILL_CONNECT 0x0040
#define PERSON_STATUS_MANUAL 0x0080
#define PERSON_STATUS_FIREWALLED 0x0100
#define PERSON_STATUS_FORWARDED 0x0200
#define PERSON_STATUS_LOCAL 0x0400
#define PERSON_STATUS_TRUSTED 0x0800
/* some extra flags for advising the gui....
* have no affect on the pqi networking.
*/
#define PERSON_STATUS_INCHAT 0x1000
#define PERSON_STATUS_INMSG 0x2000
class Person
{
public:
Person();
virtual ~Person();
std::string Name();
void Name(std::string);
// Signature needs to be defined.
virtual std::string Signature() { return Name(); };
// These operate on the status.
bool Valid();
void Valid(bool);
bool Accepted();
void Accepted(bool);
bool InUse();
void InUse(bool);
bool Listening();
void Listening(bool);
bool Connected();
void Connected(bool);
bool WillListen();
void WillListen(bool);
bool WillConnect();
void WillConnect(bool);
bool Manual();
void Manual(bool);
bool Firewalled();
void Firewalled(bool);
bool Forwarded();
void Forwarded(bool);
bool Local();
void Local(bool);
bool Trusted();
void Trusted(bool);
/* GUI Flags */
bool InChat();
void InChat(bool);
bool InMessage();
void InMessage(bool);
unsigned int Status();
void Status(unsigned int s);
int addGroup(std::string);
int removeGroup(std::string);
bool Group(std::string);
int cidpop();
void cidpush(int id);
/* Dynamic Address Foundation */
bool hasDHT();
std::string getDHTId();
void setDHT(struct sockaddr_in addr, unsigned int flags);
// public for the moment.
struct sockaddr_in lastaddr, localaddr, serveraddr;
std::string dynDNSaddr;
bool dhtFound;
unsigned int dhtFlags;
struct sockaddr_in dhtaddr;
time_t lc_timestamp; // last connect timestamp
time_t lr_timestamp; // last receive timestamp
time_t nc_timestamp; // next connect timestamp.
time_t nc_timeintvl; // next connect time interval.
ChanId cid; // to get to the correct pqissl.
int trustLvl; /* new field */
private:
std::string name;
unsigned int status;
std::list<std::string> groups;
};
#endif /* removing old stuff */
class RateInterface
{
// controlling data rates.
public:
RateInterface()
:bw_in(0), bw_out(0), bwMax_in(0), bwMax_out(0) { return; }
virtual ~RateInterface() { return; }
virtual float getRate(bool in)
{
if (in)
return bw_in;
return bw_out;
}
virtual float getMaxRate(bool in)
{
if (in)
return bwMax_in;
return bwMax_out;
}
virtual void setMaxRate(bool in, float val)
{
if (in)
bwMax_in = val;
else
bwMax_out = val;
return;
}
protected:
void setRate(bool in, float val)
{
if (in)
bw_in = val;
else
bw_out = val;
return;
}
private:
float bw_in, bw_out, bwMax_in, bwMax_out;
};
/*********************** PQI INTERFACE ******************************\
* The basic exchange interface.
* This inherits the RateInterface, as Bandwidth control
* is a critical to a networked application.
*
*/
class NetInterface;
class PQInterface: public RateInterface
{
public:
PQInterface(std::string id) :peerId(id) { return; }
virtual ~PQInterface() { return; }
virtual int SendItem(RsItem *) = 0;
virtual RsItem *GetItem() = 0;
// also there are tick + person id functions.
virtual int tick() { return 0; }
virtual int status() { return 0; }
virtual std::string PeerId() { return peerId; }
// the callback from NetInterface Connection Events.
virtual int notifyEvent(NetInterface *ni, int event) { return 0; }
private:
std::string peerId;
};
/**** Consts for pqiperson -> placed here for NetBinDummy usage() */
const uint32_t PQI_CONNECT_TCP = 0x0001;
const uint32_t PQI_CONNECT_UDP = 0x0002;
/********************** Binary INTERFACE ****************************
* This defines the binary interface used by Network/loopback/file
* interfaces
*/
#define BIN_FLAGS_NO_CLOSE 0x0001
#define BIN_FLAGS_READABLE 0x0002
#define BIN_FLAGS_WRITEABLE 0x0004
#define BIN_FLAGS_NO_DELETE 0x0008
#define BIN_FLAGS_HASH_DATA 0x0010
class BinInterface
{
public:
BinInterface() { return; }
virtual ~BinInterface() { return; }
virtual int tick() = 0;
virtual int senddata(void *data, int len) = 0;
virtual int readdata(void *data, int len) = 0;
virtual int netstatus() = 0;
virtual int isactive() = 0;
virtual bool moretoread() = 0;
virtual bool cansend() = 0;
/* method for streamer to shutdown bininterface */
virtual int close() = 0;
/* if hashing data */
virtual std::string gethash() = 0;
virtual uint64_t bytecount() { return 0; }
/* used by pqistreamer to limit transfers */
virtual bool bandwidthLimited() { return true; }
};
/********************** Network INTERFACE ***************************
* This defines the Network interface used by sockets/SSL/XPGP
* interfaces
*
* NetInterface: very pure interface, so no tick....
*
* It is passed a pointer to a PQInterface *parent,
* this is used to notify the system of Connect/Disconnect Events.
*
* Below are the Events for callback.
*/
static const int NET_CONNECT_RECEIVED = 1;
static const int NET_CONNECT_SUCCESS = 2;
static const int NET_CONNECT_UNREACHABLE = 3;
static const int NET_CONNECT_FIREWALLED = 4;
static const int NET_CONNECT_FAILED = 5;
static const uint32_t NET_PARAM_CONNECT_DELAY = 1;
static const uint32_t NET_PARAM_CONNECT_PERIOD = 2;
static const uint32_t NET_PARAM_CONNECT_TIMEOUT = 3;
class NetInterface
{
public:
NetInterface(PQInterface *p_in, std::string id)
:p(p_in), peerId(id) { return; }
virtual ~NetInterface()
{ return; }
// virtual int tick() = 0; // Already defined for BinInterface.
virtual int connect(struct sockaddr_in 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 bool connect_parameter(uint32_t type, uint32_t value) = 0;
protected:
PQInterface *parent() { return p; }
private:
PQInterface *p;
std::string peerId;
};
class NetBinInterface: public NetInterface, public BinInterface
{
public:
NetBinInterface(PQInterface *parent, std::string id)
:NetInterface(parent, id)
{ return; }
virtual ~NetBinInterface() { return; }
};
#define CHAN_SIGN_SIZE 16
#define CERTSIGNLEN 16 /* actual byte length of signature */
#define PQI_PEERID_LENGTH 32 /* When expanded into a string */
#if 0
class certsign
{
public:
bool operator<(const certsign &ref) const;
bool operator==(const certsign &ref) const;
char data[CERTSIGNLEN];
};
// IDS aren't inportant in the base class.
// EXCEPT FOR MAYBE THE FLAGS.
// These are OR'ed together.
const int PQI_ITEM_FLAG_NEW = 0x001;
const int PQI_ITEM_FLAG_LOCAL = 0x002;
const int PQI_ITEM_FLAG_PRIVATE = 0x004;
const int PQI_ITEM_TYPE_ITEM = 0x000;
const int PQI_ITEM_TYPE_FILEITEM = 0x001;
const int PQI_ITEM_TYPE_SEARCHITEM = 2;
const int PQI_ITEM_TYPE_CHATITEM = 3;
const int PQI_ITEM_TYPE_INFOITEM = 5;
const int PQI_ITEM_TYPE_COMMANDITEM = 6;
const int PQI_ITEM_TYPE_AUTODISCITEM = 7;
const int PQI_ITEM_TYPE_TUNNELITEM = 777;
const int PQI_ITEM_TYPE_TUNNELINITITEM = 778;
// Sub Type.
const int PQI_FI_SUBTYPE_GENERAL = 1;
const int PQI_FI_SUBTYPE_DATA = 2;
const int PQI_FI_SUBTYPE_CANCELRECV = 3;
const int PQI_FI_SUBTYPE_CANCELSEND = 4;
const int PQI_FI_SUBTYPE_REQUEST = 5;
const int PQI_FI_SUBTYPE_TRANSFER = 6;
const int PQI_FI_SUBTYPE_RATE = 7;
const int PQI_FI_SUBTYPE_ERROR = 8;
const int PQI_FD_FLAG_ENDSTREAM = 1;
#endif /* removing old stuff */
#endif // PQI_BASE_H

View File

@ -0,0 +1,474 @@
/*
* "$Id: pqiarchive.cc,v 1.5 2007-03-21 18:45:41 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".
*
*/
/* This is dependent on the sslroot at the moment.
* -> as we need to create/restore references to the Person.
* -> and store the signatures to do this.
*/
/*******************************************************************
* pqiarchive provides an archive stream.
* This stores RsItem + Person Reference + Timestamp,
*
* and allows Objects to be replayed or restored,
* independently of the rest of the pqi system.
*
*/
#include "_pqi/pqiarchive.h"
const int pqiarchivezone = 9326;
const int PQIARCHIVE_TYPE_PQITEM = 0x0001;
/* PeerId of PQInterface is not important ... as we are archiving
* packets from other people...
*/
pqiarchive::pqiarchive(RsSerialiser *rss, BinInterface *bio_in, int bio_flags_in)
:PQInterface(""), rsSerialiser(rss), bio(bio_in), bio_flags(bio_flags_in),
nextPkt(NULL), nextPktTS(0), firstPktTS(0), initTS(0),realTime(false)
{
{
std::ostringstream out;
out << "pqiarchive::pqiarchive()";
out << " Initialisation!" << std::endl;
pqioutput(PQL_DEBUG_ALL, pqiarchivezone, out.str());
}
if (!bio_in)
{
std::ostringstream out;
out << "pqiarchive::pqiarchive()";
out << " NULL bio, FATAL ERROR!" << std::endl;
pqioutput(PQL_ALERT, pqiarchivezone, out.str());
exit(1);
}
return;
}
pqiarchive::~pqiarchive()
{
{
std::ostringstream out;
out << "pqiarchive::~pqiarchive()";
out << " Destruction!" << std::endl;
pqioutput(PQL_DEBUG_ALL, pqiarchivezone, out.str());
}
if (bio_flags & BIN_FLAGS_NO_CLOSE)
{
std::ostringstream out;
out << "pqiarchive::~pqiarchive()";
out << " Not Closing BinInterface!" << std::endl;
pqioutput(PQL_DEBUG_ALL, pqiarchivezone, out.str());
}
else if (bio)
{
std::ostringstream out;
out << "pqiarchive::~pqiarchive()";
out << " Deleting BinInterface!" << std::endl;
pqioutput(PQL_DEBUG_ALL, pqiarchivezone, out.str());
delete bio;
}
if (rsSerialiser)
delete rsSerialiser;
if (nextPkt)
{
delete nextPkt;
}
return;
}
// Get/Send Items.
int pqiarchive::SendItem(RsItem *si)
{
{
std::ostringstream out;
out << "pqiarchive::SendItem()" << std::endl;
si -> print(out);
pqioutput(PQL_DEBUG_BASIC, pqiarchivezone, out.str());
}
// check if this is a writing bio.
if (!(bio_flags & BIN_FLAGS_WRITEABLE))
{
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
delete si;
return -1;
}
// std::cerr << "SendItem: si->PeerId()=" << si->PeerId() << std::endl ;
int ret = writePkt(si);
return ret; /* 0 - failure, 1 - success*/
}
RsItem *pqiarchive::GetItem()
{
{
std::ostringstream out;
out << "pqiarchive::GetItem()";
pqioutput(PQL_DEBUG_ALL, pqiarchivezone, out.str());
}
// check if this is a reading bio.
if (!(bio_flags & BIN_FLAGS_READABLE))
{
std::ostringstream out;
out << "pqiarchive::GetItem()";
out << "Error Not Readable" << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqiarchivezone, out.str());
return NULL;
}
// load if we dont have a packet.
if (!nextPkt)
{
if (!readPkt(&nextPkt, &nextPktTS))
{
std::ostringstream out;
out << "pqiarchive::GetItem()";
out << "Failed to ReadPkt" << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqiarchivezone, out.str());
return NULL;
}
}
if (!nextPkt) return NULL;
/* if realtime - check delta */
bool rtnPkt = true;
if ((realTime) && (initTS))
{
int delta = time(NULL) - initTS;
int delta2 = nextPktTS - firstPktTS;
if (delta >= delta2)
{
rtnPkt = true;
}
else
{
rtnPkt = false;
}
}
if (rtnPkt)
{
if (!initTS)
{
/* first read! */
initTS = time(NULL);
firstPktTS = nextPktTS;
}
RsItem *outPkt = nextPkt;
nextPkt = NULL;
if (outPkt != NULL)
{
std::ostringstream out;
out << "pqiarchive::GetItem() Returning:" << std::endl;
outPkt -> print(out);
pqioutput(PQL_DEBUG_BASIC, pqiarchivezone, out.str());
}
return outPkt;
}
return NULL;
}
// // PQInterface
int pqiarchive::tick()
{
{
std::ostringstream out;
out << "pqiarchive::tick()";
out << std::endl;
}
return 0;
}
int pqiarchive::status()
{
{
std::ostringstream out;
out << "pqiarchive::status()";
pqioutput(PQL_DEBUG_ALL, pqiarchivezone, out.str());
}
return 0;
}
//
/**************** HANDLE OUTGOING TRANSLATION + TRANSMISSION ******/
int pqiarchive::writePkt(RsItem *pqi)
{
// std::cerr << "writePkt, pqi->peerId()=" << pqi->PeerId() << std::endl ;
{
std::ostringstream out;
out << "pqiarchive::writePkt()";
pqioutput(PQL_DEBUG_ALL, pqiarchivezone, out.str());
}
uint32_t pktsize = rsSerialiser->size(pqi);
void *ptr = malloc(pktsize);
if (!(rsSerialiser->serialise(pqi, ptr, &pktsize)))
{
std::ostringstream out;
out << "pqiarchive::writePkt() Null Pkt generated!";
out << std::endl;
out << "Caused By: " << std::endl;
pqi -> print(out);
pqioutput(PQL_ALERT, pqiarchivezone, out.str());
free(ptr);
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
delete pqi;
return 0;
}
/* extract the extra details */
uint32_t len = getRsItemSize(ptr);
if (len != pktsize)
{
std::ostringstream out;
out << "pqiarchive::writePkt() Length MisMatch: len: " << len;
out << " != pktsize: " << pktsize;
out << std::endl;
out << "Caused By: " << std::endl;
pqi -> print(out);
pqioutput(PQL_ALERT, pqiarchivezone, out.str());
free(ptr);
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
delete pqi;
return 0;
}
if (!(bio->cansend()))
{
std::ostringstream out;
out << "pqiarchive::writePkt() BIO cannot write!";
out << std::endl;
out << "Discarding: " << std::endl;
pqi -> print(out);
pqioutput(PQL_ALERT, pqiarchivezone, out.str());
free(ptr);
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
delete pqi;
return 0;
}
// using the peerid from the item.
if (pqi->PeerId().length() != PQI_PEERID_LENGTH)
{
std::ostringstream out;
out << "pqiarchive::writePkt() Invalid peerId Length!";
out << std::endl;
out << "Found " << pqi->PeerId().length() << " instead of " << PQI_PEERID_LENGTH << std::endl ;
out << "pqi->PeerId() = " << pqi->PeerId() << std::endl ;
out << "Caused By: " << std::endl;
pqi -> print(out);
pqioutput(PQL_ALERT, pqiarchivezone, out.str());
free(ptr);
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
delete pqi;
return 0;
}
std::ostringstream out;
out << "Writing Pkt Header" << std::endl;
struct pqiarchive_header hdr;
hdr.type = PQIARCHIVE_TYPE_PQITEM;
hdr.length = len;
hdr.ts = time(NULL);
memcpy(hdr.personSig, pqi->PeerId().c_str(), PQI_PEERID_LENGTH);
// write packet header.
if (sizeof(hdr) != bio->senddata(&hdr, sizeof(hdr)))
{
out << "Trouble writing header!";
out << std::endl;
pqioutput(PQL_ALERT, pqiarchivezone, out.str());
free(ptr);
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
delete pqi;
return 0;
}
out << "Writing Pkt Body" << std::endl;
// write packet.
if (len != bio->senddata(ptr, len))
{
out << "Problems with Send Data!";
out << std::endl;
pqioutput(PQL_ALERT, pqiarchivezone, out.str());
free(ptr);
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
delete pqi;
return 0;
}
out << " Success!" << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqiarchivezone, out.str());
free(ptr);
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
delete pqi;
return 1;
}
/* Reads a single packet from the input stream
* gets the timestamp as well.
*
*/
int pqiarchive::readPkt(RsItem **item_out, long *ts_out)
{
{
std::ostringstream out;
out << "pqiarchive::readPkt()";
pqioutput(PQL_DEBUG_ALL, pqiarchivezone, out.str());
}
if ((!(bio->isactive())) || (!(bio->moretoread())))
{
return 0;
}
// header
struct pqiarchive_header hdr;
// enough space to read any packet.
int maxlen = getRsPktMaxSize();
void *block = malloc(maxlen);
// initial read size: basic packet.
int blen = getRsPktBaseSize();
int tmplen;
/* read in the header */
if (sizeof(hdr) != bio->readdata(&hdr, sizeof(hdr)))
{
/* error */
pqioutput(PQL_WARNING, pqiarchivezone,
"pqiarchive::readPkt() bad read(1)");
free(block);
return 0;
}
/* we have the header */
// read the basic block (minimum packet size)
if (blen != (tmplen = bio->readdata(block, blen)))
{
pqioutput(PQL_WARNING, pqiarchivezone,
"pqiarchive::readPkt() bad read(2)");
free(block);
return 0;
}
// workout how much more to read.
int extralen = getRsItemSize(block) - blen;
if (extralen > 0)
{
void *extradata = (void *) (((char *) block) + blen);
if (extralen != (tmplen = bio->readdata(extradata, extralen)))
{
std::ostringstream out;
out << "pqiarchive::readPkt() ";
out << "Error Completing Read (read ";
out << tmplen << "/" << extralen << ")" << std::endl;
pqioutput(PQL_ALERT, pqiarchivezone, out.str());
free(block);
return 0;
}
}
// create packet, based on header.
std::cerr << "Read Data Block -> Incoming Pkt(";
std::cerr << blen + extralen << ")" << std::endl;
uint32_t readbytes = extralen + blen;
RsItem *item = rsSerialiser->deserialise(block, &readbytes);
free(block);
if (item == NULL)
{
pqioutput(PQL_ALERT, pqiarchivezone,
"pqiarchive::readPkt() Failed to create Item from archive!");
return 0;
}
/* Cannot detect bad ids here anymore....
* but removed dependancy on the sslroot!
*/
std::string peerId = "";
for(int i = 0; i < PQI_PEERID_LENGTH; i++)
{
peerId += hdr.personSig[i];
}
item->PeerId(peerId);
*item_out = item;
*ts_out = hdr.ts;
return 1;
}
/**** Hashing Functions ****/
std::string pqiarchive::gethash()
{
return bio->gethash();
}

View File

@ -0,0 +1,95 @@
/*
* "$Id: pqiarchive.h,v 1.3 2007-02-18 21:46:49 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 PQIARCHIVE_H
#define PQIARCHIVE_H
#include "_pqi/pqi.h"
#include "_serialiser/rsserial.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include "_util/rsdebug.h"
#include <list>
/*******************************************************************
* pqiarchive provides an archive stream.
* This stores RsItem + Person Reference + Timestamp,
*
* and allows Objects to be replayed or restored,
* independently of the rest of the pqi system.
*
*/
struct pqiarchive_header
{
uint32_t type;
uint32_t length;
uint32_t ts;
uint8_t personSig[PQI_PEERID_LENGTH];
};
class pqiarchive: PQInterface
{
public:
pqiarchive(RsSerialiser *rss, BinInterface *bio_in, int bio_flagsin);
virtual ~pqiarchive();
// PQInterface
virtual int SendItem(RsItem *);
virtual RsItem *GetItem();
virtual int tick();
virtual int status();
virtual void setRealTime(bool r) { realTime = r; }
std::string gethash();
private:
int writePkt(RsItem *item);
int readPkt(RsItem **item_out, long *ts);
// Serialiser
RsSerialiser *rsSerialiser;
// Binary Interface for IO, initialisated at startup.
BinInterface *bio;
unsigned int bio_flags; // only BIN_NO_CLOSE at the moment.
// Temp Storage for transient data.....
RsItem *nextPkt;
long nextPktTS; /* timestamp associated with nextPkt */
long firstPktTS; /* timestamp associated with first read Pkt */
long initTS; /* clock timestamp at first read */
bool realTime;
};
#endif // PQIARCHIVE_H

View File

@ -0,0 +1,126 @@
/*
* libretroshare/src/pqi: pqiassist.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2007 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 PQIASSIST_H
#define PQIASSIST_H
#include <string>
#include <map>
#include "_pqi/pqinetwork.h"
#include "_pqi/pqimonitor.h"
/**********
* This header file provides two interfaces for assisting
* the connections to friends.
*
* pqiNetAssistFirewall - which will provides interfaces
* to functionality like upnp and apple's equivalent.
*
* pqiNetAssistConnect - which will provides interfaces
* to other networks (DHT) etc that can provide information.
* These classes would be expected to use the pqiMonitor
* callback system to notify the connectionMgr.
*
***/
class pqiNetAssist
{
public:
virtual ~pqiNetAssist() { return; }
/* External Interface */
virtual void enable(bool on) = 0;
virtual void shutdown() = 0; /* blocking call */
virtual void restart() = 0;
virtual bool getEnabled() = 0;
virtual bool getActive() = 0;
};
class pqiNetAssistFirewall: public pqiNetAssist
{
public:
virtual ~pqiNetAssistFirewall() { return; }
/* the address that the listening port is on */
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;
};
class pqiNetAssistConnect: public pqiNetAssist
{
/*
*/
public:
pqiNetAssistConnect(std::string id, pqiConnectCb *cb)
:mPeerId(id), mConnCb(cb) { return; }
/********** External DHT Interface ************************
* These Functions are the external interface
* for the DHT, and must be non-blocking and return quickly
*/
virtual void setBootstrapAllowed(bool on) = 0;
virtual bool getBootstrapAllowed() = 0;
/* set key data */
virtual bool setExternalInterface(struct sockaddr_in laddr,
struct sockaddr_in raddr, uint32_t type) = 0;
/* add / remove peers */
virtual bool findPeer(std::string id) = 0;
virtual bool dropPeer(std::string id) = 0;
/* post DHT key saying we should connect (callback when done) */
virtual bool notifyPeer(std::string id) = 0;
/* extract current peer status */
virtual bool getPeerStatus(std::string id,
struct sockaddr_in &laddr, struct sockaddr_in &raddr,
uint32_t &type, uint32_t &mode) = 0;
/* stun */
virtual bool enableStun(bool on) = 0;
virtual bool addStun(std::string id) = 0;
protected:
std::string mPeerId;
pqiConnectCb *mConnCb;
};
#endif /*PQIASSIST_H */

View File

@ -0,0 +1,565 @@
/*
* "$Id: pqibin.cc,v 1.4 2007-02-18 21:46:49 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/pqibin.h"
BinFileInterface::BinFileInterface(const char *fname, int flags)
:bin_flags(flags), buf(NULL), hash(NULL), bcount(0)
{
/* if read + write - open r+ */
if ((bin_flags & BIN_FLAGS_READABLE) &&
(bin_flags & BIN_FLAGS_WRITEABLE))
{
buf = fopen(fname, "rb+");
/* if the file don't exist */
if (!buf)
{
buf = fopen(fname, "wb+");
}
}
else if (bin_flags & BIN_FLAGS_READABLE)
{
buf = fopen(fname, "rb");
}
else if (bin_flags & BIN_FLAGS_WRITEABLE)
{
// This is enough to remove old file in Linux...
// but not in windows.... (what to do)
buf = fopen(fname, "wb");
fflush(buf); /* this might help windows! */
}
else
{
/* not read or write! */
}
if (buf)
{
/* no problem */
/* go to the end */
fseek(buf, 0L, SEEK_END);
/* get size */
size = ftell(buf);
/* back to the start */
fseek(buf, 0L, SEEK_SET);
}
else
{
size = 0;
}
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
hash = new pqihash();
}
}
BinFileInterface::~BinFileInterface()
{
if (buf)
{
fclose(buf);
}
if (hash)
{
delete hash;
}
}
int BinFileInterface::close()
{
if (buf)
{
fclose(buf);
buf = NULL;
}
return 1;
}
int BinFileInterface::senddata(void *data, int len)
{
if (!buf)
return -1;
if (1 != fwrite(data, len, 1, buf))
{
return -1;
}
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
hash->addData(data, len);
bcount += len;
}
return len;
}
int BinFileInterface::readdata(void *data, int len)
{
if (!buf)
return -1;
if (1 != fread(data, len, 1, buf))
{
return -1;
}
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
hash->addData(data, len);
bcount += len;
}
return len;
}
std::string BinFileInterface::gethash()
{
std::string hashstr;
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
hash->Complete(hashstr);
}
return hashstr;
}
uint64_t BinFileInterface::bytecount()
{
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
return bcount;
}
return 0;
}
BinMemInterface::BinMemInterface(int defsize, int flags)
:bin_flags(flags), buf(NULL), size(defsize),
recvsize(0), readloc(0), hash(NULL), bcount(0)
{
buf = malloc(defsize);
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
hash = new pqihash();
}
}
BinMemInterface::BinMemInterface(const void *data, const int defsize, int flags)
:bin_flags(flags), buf(NULL), size(defsize),
recvsize(0), readloc(0), hash(NULL), bcount(0)
{
buf = malloc(defsize);
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
hash = new pqihash();
}
/* just remove the const
* *BAD* but senddata don't change it anyway
*/
senddata((void *) data, defsize);
}
BinMemInterface::~BinMemInterface()
{
if (buf)
free(buf);
if (hash)
delete hash;
return;
}
int BinMemInterface::close()
{
if (buf)
{
free(buf);
buf = NULL;
}
size = 0;
recvsize = 0;
readloc = 0;
return 1;
}
/* some fns to mess with the memory */
int BinMemInterface::fseek(int loc)
{
if (loc <= recvsize)
{
readloc = loc;
return 1;
}
return 0;
}
int BinMemInterface::senddata(void *data, const int len)
{
if(recvsize + len > size)
{
/* resize? */
return -1;
}
memcpy((char *) buf + recvsize, data, len);
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
hash->addData(data, len);
bcount += len;
}
recvsize += len;
return len;
}
int BinMemInterface::readdata(void *data, int len)
{
if(readloc + len > recvsize)
{
/* no more stuff? */
return -1;
}
memcpy(data, (char *) buf + readloc, len);
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
hash->addData(data, len);
bcount += len;
}
readloc += len;
return len;
}
std::string BinMemInterface::gethash()
{
std::string hashstr;
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
hash->Complete(hashstr);
}
return hashstr;
}
uint64_t BinMemInterface::bytecount()
{
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
return bcount;
}
return 0;
}
bool BinMemInterface::writetofile(const char *fname)
{
FILE *fd = fopen(fname, "wb");
if (!fd)
{
return false;
}
if (1 != fwrite(buf, recvsize, 1, fd))
{
fclose(fd);
return false;
}
fclose(fd);
return true;
}
bool BinMemInterface::readfromfile(const char *fname)
{
FILE *fd = fopen(fname, "rb");
if (!fd)
{
return false;
}
/* get size */
::fseek(fd, 0L, SEEK_END);
int fsize = ftell(fd);
if (fsize > size)
{
/* not enough room */
std::cerr << "BinMemInterface::readfromfile() not enough room";
std::cerr << std::endl;
fclose(fd);
return false;
}
::fseek(fd, 0L, SEEK_SET);
if (1 != fread(buf, fsize, 1, fd))
{
/* not enough room */
std::cerr << "BinMemInterface::readfromfile() failed fread";
std::cerr << std::endl;
fclose(fd);
return false;
}
recvsize = fsize;
readloc = 0;
fclose(fd);
return true;
}
/**************************************************************************/
void printNetBinID(std::ostream &out, std::string id, uint32_t t)
{
out << "NetBinId(" << id << ",";
if (t == PQI_CONNECT_TCP)
{
out << "TCP)";
}
else
{
out << "UDP)";
}
}
/************************** NetBinDummy ******************************
* A test framework,
*
*/
#include "pqi/pqiperson.h"
const uint32_t DEFAULT_DUMMY_DELTA = 5;
NetBinDummy::NetBinDummy(PQInterface *parent, std::string id, uint32_t t)
:NetBinInterface(parent, id), type(t), dummyConnected(false),
toConnect(false), connectDelta(DEFAULT_DUMMY_DELTA)
{
return;
}
// Net Interface
int NetBinDummy::connect(struct sockaddr_in raddr)
{
std::cerr << "NetBinDummy::connect(";
std::cerr << inet_ntoa(raddr.sin_addr) << ":";
std::cerr << htons(raddr.sin_port);
std::cerr << ") ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
std::cerr << "NetBinDummy::dummyConnect = true!";
std::cerr << std::endl;
if (type == PQI_CONNECT_TCP)
{
std::cerr << "NetBinDummy:: Not connecting TCP";
std::cerr << std::endl;
if (parent())
{
parent()->notifyEvent(this, CONNECT_FAILED);
}
}
else if (!dummyConnected)
{
toConnect = true;
connectTS = time(NULL) + connectDelta;
std::cerr << "NetBinDummy::toConnect = true, connect in: ";
std::cerr << connectDelta << " secs";
std::cerr << std::endl;
}
else
{
std::cerr << "NetBinDummy:: Already Connected!";
std::cerr << std::endl;
}
return 1;
}
int NetBinDummy::listen()
{
std::cerr << "NetBinDummy::connect() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
return 1;
}
int NetBinDummy::stoplistening()
{
std::cerr << "NetBinDummy::stoplistening() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
return 1;
}
int NetBinDummy::disconnect()
{
std::cerr << "NetBinDummy::disconnect() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
std::cerr << "NetBinDummy::dummyConnect = false!";
std::cerr << std::endl;
dummyConnected = false;
if (parent())
{
parent()->notifyEvent(this, CONNECT_FAILED);
}
return 1;
}
int NetBinDummy::reset()
{
std::cerr << "NetBinDummy::reset() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
disconnect();
return 1;
}
// Bin Interface.
int NetBinDummy::tick()
{
if (toConnect)
{
if (connectTS < time(NULL))
{
std::cerr << "NetBinDummy::tick() dummyConnected = true ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
dummyConnected = true;
toConnect = false;
if (parent())
parent()->notifyEvent(this, CONNECT_SUCCESS);
}
else
{
std::cerr << "NetBinDummy::tick() toConnect ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
}
}
return 0;
}
int NetBinDummy::senddata(void *data, int len)
{
std::cerr << "NetBinDummy::senddata() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
if (dummyConnected)
return len;
return 0;
}
int NetBinDummy::readdata(void *data, int len)
{
std::cerr << "NetBinDummy::readdata() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
return 0;
}
int NetBinDummy::netstatus()
{
std::cerr << "NetBinDummy::netstatus() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
return 1;
}
int NetBinDummy::isactive()
{
std::cerr << "NetBinDummy::isactive() ";
printNetBinID(std::cerr, PeerId(), type);
if (dummyConnected)
std::cerr << " true ";
else
std::cerr << " false ";
std::cerr << std::endl;
return dummyConnected;
}
bool NetBinDummy::moretoread()
{
std::cerr << "NetBinDummy::moretoread() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
return false;
}
bool NetBinDummy::cansend()
{
std::cerr << "NetBinDummy::cansend() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
return dummyConnected;
}
int NetBinDummy::close()
{
std::cerr << "NetBinDummy::close() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
return 1;
}
std::string NetBinDummy::gethash()
{
std::cerr << "NetBinDummy::gethash() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
return std::string("");
}

View File

@ -0,0 +1,165 @@
/*
* "$Id: pqibin.h,v 1.2 2007-02-18 21:46:49 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 PQIBIN_H
#define PQIBIN_H
#include "pqi/pqi_base.h"
#include "pqi/pqihash.h"
#include <stdio.h>
class BinFileInterface: public BinInterface
{
public:
BinFileInterface(const char *fname, int flags);
virtual ~BinFileInterface();
virtual int tick() { return 1; }
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()
{
if ((buf) && (bin_flags | BIN_FLAGS_READABLE))
{
if ((size - ftell(buf)) > 0)
{
return true;
}
}
return false;
}
virtual int close();
virtual bool cansend() { return (bin_flags | BIN_FLAGS_WRITEABLE); }
virtual bool bandwidthLimited() { return false; }
/* if HASHing is switched on */
virtual std::string gethash();
virtual uint64_t bytecount();
private:
int bin_flags;
FILE *buf;
int size;
pqihash *hash;
uint64_t bcount;
};
class BinMemInterface: public BinInterface
{
public:
BinMemInterface(int defsize, int flags);
BinMemInterface(const void *data, const int size, int flags);
virtual ~BinMemInterface();
/* Extra Interfaces */
int fseek(int loc);
int memsize() { return recvsize; }
void *memptr() { return buf; }
/* file interface */
bool writetofile(const char *fname);
bool readfromfile(const char *fname);
virtual int tick() { return 1; }
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()
{
if ((buf) && (bin_flags | BIN_FLAGS_READABLE ))
{
if (readloc < recvsize)
{
return true;
}
}
return false;
}
virtual int close();
virtual bool cansend() { return (bin_flags | BIN_FLAGS_WRITEABLE); }
virtual bool bandwidthLimited() { return false; }
virtual std::string gethash();
virtual uint64_t bytecount();
private:
int bin_flags;
void *buf;
int size;
int recvsize;
int readloc;
pqihash *hash;
uint64_t bcount;
};
class NetBinDummy: public NetBinInterface
{
public:
NetBinDummy(PQInterface *parent, std::string id, uint32_t t);
virtual ~NetBinDummy() { return; }
// Net Interface
virtual int connect(struct sockaddr_in raddr);
virtual int listen();
virtual int stoplistening();
virtual int disconnect();
virtual int reset();
virtual bool connect_parameter(uint32_t type, uint32_t value) { return false; }
// Bin Interface.
virtual int tick();
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 int close();
virtual std::string gethash();
private:
uint32_t type;
bool dummyConnected;
bool toConnect;
uint32_t connectDelta;
time_t connectTS;
};
#endif // PQIBIN_H

View File

@ -0,0 +1,705 @@
/*
* "$Id: pqihandler.cc,v 1.12 2007-03-31 09:41:32 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/pqihandler.h"
const int pqihandlerzone = 34283;
/****
#define DEBUG_TICK 1
#define RSITEM_DEBUG 1
****/
pqihandler::pqihandler(SecurityPolicy *Global)
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
// The global security....
// if something is disabled here...
// cannot be enabled by module.
globsec = Global;
{
std::ostringstream out;
out << "New pqihandler()" << std::endl;
out << "Security Policy: " << secpolicy_print(globsec);
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
}
// setup minimal total+individual rates.
rateIndiv_out = 0.01;
rateIndiv_in = 0.01;
rateMax_out = 0.01;
rateMax_in = 0.01;
return;
}
int pqihandler::tick()
{
int moreToTick = 0;
{ RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
// tick all interfaces...
std::map<std::string, SearchModule *>::iterator it;
for(it = mods.begin(); it != mods.end(); it++)
{
if (0 < ((it -> second) -> pqi) -> tick())
{
#ifdef DEBUG_TICK
std::cerr << "pqihandler::tick() moreToTick from mod()" << std::endl;
#endif
moreToTick = 1;
}
}
// get the items, and queue them correctly
if (0 < locked_GetItems())
{
#ifdef DEBUG_TICK
std::cerr << "pqihandler::tick() moreToTick from GetItems()" << std::endl;
#endif
moreToTick = 1;
}
} /****** UNLOCK ******/
UpdateRates();
return moreToTick;
}
int pqihandler::status()
{
std::map<std::string, SearchModule *>::iterator it;
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
{ // for output
std::ostringstream out;
out << "pqihandler::status() Active Modules:" << std::endl;
// display all interfaces...
for(it = mods.begin(); it != mods.end(); it++)
{
out << "\tModule [" << it -> first << "] Pointer <";
out << (void *) ((it -> second) -> pqi) << ">" << std::endl;
}
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
} // end of output.
// status all interfaces...
for(it = mods.begin(); it != mods.end(); it++)
{
((it -> second) -> pqi) -> status();
}
return 1;
}
bool pqihandler::AddSearchModule(SearchModule *mod)
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
// if peerid used -> error.
std::map<std::string, SearchModule *>::iterator it;
if (mod->peerid != mod->pqi->PeerId())
{
// ERROR!
std::ostringstream out;
out << "ERROR peerid != PeerId!" << std::endl;
pqioutput(PQL_ALERT, pqihandlerzone, out.str());
return false;
}
if (mod->peerid == "")
{
// ERROR!
std::ostringstream out;
out << "ERROR peerid == NULL" << std::endl;
pqioutput(PQL_ALERT, pqihandlerzone, out.str());
return false;
}
if (mods.find(mod->peerid) != mods.end())
{
// ERROR!
std::ostringstream out;
out << "ERROR PeerId Module already exists!" << std::endl;
pqioutput(PQL_ALERT, pqihandlerzone, out.str());
return false;
}
// check security.
if (mod -> sp == NULL)
{
// create policy.
mod -> sp = secpolicy_create();
}
// limit to what global security allows.
secpolicy_limit(globsec, mod -> sp);
// store.
mods[mod->peerid] = mod;
return true;
}
bool pqihandler::RemoveSearchModule(SearchModule *mod)
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
std::map<std::string, SearchModule *>::iterator it;
for(it = mods.begin(); it != mods.end(); it++)
{
if (mod == it -> second)
{
mods.erase(it);
return true;
}
}
return false;
}
// dummy output check
int pqihandler::locked_checkOutgoingRsItem(RsItem *item, int global)
{
pqioutput(PQL_WARNING, pqihandlerzone,
"pqihandler::checkOutgoingPQItem() NULL fn");
return 1;
}
// generalised output
int pqihandler::HandleRsItem(RsItem *item, int allowglobal)
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
std::map<std::string, SearchModule *>::iterator it;
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"pqihandler::HandleRsItem()");
/* simplified to no global! */
if (allowglobal)
{
/* error */
std::ostringstream out;
out << "pqihandler::HandleSearchItem()";
out << " Cannot send out Global RsItem";
pqioutput(PQL_ALERT, pqihandlerzone, out.str());
delete item;
return -1;
}
if (!locked_checkOutgoingRsItem(item, allowglobal))
{
std::ostringstream out;
out << "pqihandler::HandleRsItem() checkOutgoingPQItem";
out << " Failed on item: " << std::endl;
item -> print(out);
pqioutput(PQL_ALERT, pqihandlerzone, out.str());
delete item;
return -1;
}
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"pqihandler::HandleRsItem() Sending to One Channel");
// find module.
if ((it = mods.find(item->PeerId())) == mods.end())
{
std::ostringstream out;
out << "pqihandler::HandleRsItem() Invalid chan!";
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
delete item;
return -1;
}
// check security... is output allowed.
if(0 < secpolicy_check((it -> second) -> sp, 0, PQI_OUTGOING))
{
std::ostringstream out;
out << "pqihandler::HandleRsItem() sending to chan:";
out << it -> first << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
// if yes send on item.
((it -> second) -> pqi) -> SendItem(item);
return 1;
}
else
{
std::ostringstream out;
out << "pqihandler::HandleRsItem()";
out << " Sec not approved";
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
delete item;
return -1;
}
// if successfully sent to at least one.
return 1;
}
int pqihandler::SearchSpecific(RsCacheRequest *ns)
{
return HandleRsItem(ns, 0);
}
int pqihandler::SendSearchResult(RsCacheItem *ns)
{
return HandleRsItem(ns, 0);
}
int pqihandler::SendFileRequest(RsFileRequest *ns)
{
return HandleRsItem(ns, 0);
}
int pqihandler::SendFileData(RsFileData *ns)
{
return HandleRsItem(ns, 0);
}
int pqihandler::SendRsRawItem(RsRawItem *ns)
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"pqihandler::SendRsRawItem()");
return HandleRsItem(ns, 0);
}
// inputs. This is a very basic
// system that is completely biased and slow...
// someone please fix.
int pqihandler::locked_GetItems()
{
std::map<std::string, SearchModule *>::iterator it;
RsItem *item;
int count = 0;
// loop through modules....
for(it = mods.begin(); it != mods.end(); it++)
{
SearchModule *mod = (it -> second);
// check security... is output allowed.
if(0 < secpolicy_check((it -> second) -> sp,
0, PQI_INCOMING)) // PQI_ITEM_TYPE_ITEM, PQI_INCOMING))
{
// if yes... attempt to read.
while((item = (mod -> pqi) -> GetItem()) != NULL)
{
#ifdef RSITEM_DEBUG
std::ostringstream out;
out << "pqihandler::GetItems() Incoming Item ";
out << " from: " << mod -> pqi << std::endl;
item -> print(out);
pqioutput(PQL_DEBUG_BASIC,
pqihandlerzone, out.str());
#endif
if (item->PeerId() != (mod->pqi)->PeerId())
{
/* ERROR */
pqioutput(PQL_ALERT,
pqihandlerzone, "ERROR PeerIds dont match!");
item->PeerId(mod->pqi->PeerId());
}
locked_SortnStoreItem(item);
count++;
}
}
else
{
// not allowed to recieve from here....
while((item = (mod -> pqi) -> GetItem()) != NULL)
{
std::ostringstream out;
out << "pqihandler::GetItems() Incoming Item ";
out << " from: " << mod -> pqi << std::endl;
item -> print(out);
out << std::endl;
out << "Item Not Allowed (Sec Pol). deleting!";
out << std::endl;
pqioutput(PQL_DEBUG_BASIC,
pqihandlerzone, out.str());
delete item;
}
}
}
return count;
}
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)
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"SortnStore -> Service");
in_service.push_back(item);
item = NULL;
return;
}
if (vers != RS_PKT_VERSION1)
{
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;
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");
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;
}
RsRawItem *pqihandler::GetRsRawItem()
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (in_service.size() != 0)
{
RsRawItem *fi = dynamic_cast<RsRawItem *>(in_service.front());
if (!fi) { delete in_service.front(); }
in_service.pop_front();
return fi;
}
return NULL;
}
static const float MIN_RATE = 0.01; // 10 B/s
// internal fn to send updates
int pqihandler::UpdateRates()
{
std::map<std::string, SearchModule *>::iterator it;
int num_sm = mods.size();
float avail_in = getMaxRate(true);
float avail_out = getMaxRate(false);
float used_bw_in = 0;
float used_bw_out = 0;
/* Lock once rates have been retrieved */
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
int effectiveUploadsSm = 0;
int effectiveDownloadsSm = 0;
// loop through modules to get the used bandwith and the number of modules that are affectively transfering
//std::cerr << " Looping through modules" << std::endl;
for(it = mods.begin(); it != mods.end(); it++)
{
SearchModule *mod = (it -> second);
float crate_in = mod -> pqi -> getRate(true);
if (crate_in > 0.01 * avail_in || crate_in > 0.1)
{
effectiveDownloadsSm ++;
}
float crate_out = mod -> pqi -> getRate(false);
if (crate_out > 0.01 * avail_out || crate_out > 0.1)
{
effectiveUploadsSm ++;
}
used_bw_in += crate_in;
used_bw_out += crate_out;
}
// std::cerr << "Totals (In) Used B/W " << used_bw_in;
// std::cerr << " Available B/W " << avail_in;
// std::cerr << " Effective transfers " << effectiveDownloadsSm << std::endl;
// std::cerr << "Totals (Out) Used B/W " << used_bw_out;
// std::cerr << " Available B/W " << avail_out;
// std::cerr << " Effective transfers " << effectiveUploadsSm << std::endl;
locked_StoreCurrentRates(used_bw_in, used_bw_out);
//computing average rates for effective transfers
float max_in_effective = avail_in / num_sm;
if (effectiveDownloadsSm != 0) {
max_in_effective = avail_in / effectiveDownloadsSm;
}
float max_out_effective = avail_out / num_sm;
if (effectiveUploadsSm != 0) {
max_out_effective = avail_out / effectiveUploadsSm;
}
//modify the outgoing rates if bandwith is not used well
float rate_out_modifier = 0;
if (used_bw_out / avail_out < 0.95) {
rate_out_modifier = 0.001 * avail_out;
} else if (used_bw_out / avail_out > 1.05) {
rate_out_modifier = - 0.001 * avail_out;
}
if (rate_out_modifier != 0) {
for(it = mods.begin(); it != mods.end(); it++)
{
SearchModule *mod = (it -> second);
mod -> pqi -> setMaxRate(false, mod -> pqi -> getMaxRate(false) + rate_out_modifier);
}
}
//modify the incoming rates if bandwith is not used well
float rate_in_modifier = 0;
if (used_bw_in / avail_in < 0.95) {
rate_in_modifier = 0.001 * avail_in;
} else if (used_bw_in / avail_in > 1.05) {
rate_in_modifier = - 0.001 * avail_in;
}
if (rate_in_modifier != 0) {
for(it = mods.begin(); it != mods.end(); it++)
{
SearchModule *mod = (it -> second);
mod -> pqi -> setMaxRate(true, mod -> pqi -> getMaxRate(true) + rate_in_modifier);
}
}
//cap the rates
for(it = mods.begin(); it != mods.end(); it++)
{
SearchModule *mod = (it -> second);
if (mod -> pqi -> getMaxRate(false) < max_out_effective) {
mod -> pqi -> setMaxRate(false, max_out_effective);
}
if (mod -> pqi -> getMaxRate(false) > avail_out) {
mod -> pqi -> setMaxRate(false, avail_out);
}
if (mod -> pqi -> getMaxRate(true) < max_in_effective) {
mod -> pqi -> setMaxRate(true, max_in_effective);
}
if (mod -> pqi -> getMaxRate(true) > avail_in) {
mod -> pqi -> setMaxRate(true, avail_in);
}
}
return 1;
}
void pqihandler::getCurrentRates(float &in, float &out)
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
in = rateTotal_in;
out = rateTotal_out;
}
void pqihandler::locked_StoreCurrentRates(float in, float out)
{
rateTotal_in = in;
rateTotal_out = out;
}
//inline void pqihandler::setMaxIndivRate(bool in, float val)
//{
// RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
// if (in)
// rateIndiv_in = val;
// else
// rateIndiv_out = val;
// return;
//}
//
//inline float pqihandler::getMaxIndivRate(bool in)
//{
// RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
// if (in)
// return rateIndiv_in;
// else
// return rateIndiv_out;
//}
void pqihandler::setMaxRate(bool in, float val)
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (in)
rateMax_in = val;
else
rateMax_out = val;
return;
}
float pqihandler::getMaxRate(bool in)
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (in)
return rateMax_in;
else
return rateMax_out;
}

View File

@ -0,0 +1,126 @@
/*
* "$Id: pqihandler.h,v 1.10 2007-03-31 09:41:32 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 PQIHANDLER_H
#define PQIHANDLER_H
#include "_pqi/pqi.h"
#include "_pqi/pqisecurity.h"
#include "_util/rsthreads.h"
#include <sstream>
#include "_util/rsdebug.h"
#include <stdlib.h>
#include <map>
#include <list>
class SearchModule
{
public:
std::string peerid;
PQInterface *pqi;
SecurityPolicy *sp;
};
// Presents a P3 Face to the world!
// and funnels data through to a PQInterface.
//
class pqihandler: public P3Interface
{
public:
pqihandler(SecurityPolicy *Global);
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 RsFileRequest * GetFileRequest();
virtual RsFileData * GetFileData();
// Rest of P3Interface
virtual int tick();
virtual int status();
// Service Data Interface
virtual int SendRsRawItem(RsRawItem *);
virtual RsRawItem *GetRsRawItem();
// rate control.
//indiv rate is deprecated
//void setMaxIndivRate(bool in, float val);
//float getMaxIndivRate(bool in);
inline void setMaxRate(bool in, float val);
inline float getMaxRate(bool in);
void getCurrentRates(float &in, float &out);
protected:
/* check to be overloaded by those that can
* generates warnings otherwise
*/
int HandleRsItem(RsItem *ns, int allowglobal);
virtual int locked_checkOutgoingRsItem(RsItem *item, int global);
int locked_GetItems();
void locked_SortnStoreItem(RsItem *item);
RsMutex coreMtx; /* MUTEX */
std::map<std::string, SearchModule *> mods;
SecurityPolicy *globsec;
// Temporary storage...
std::list<RsItem *> in_result, in_search,
in_request, in_data, in_service;
private:
// rate control.
int UpdateRates();
void locked_StoreCurrentRates(float in, float out);
float rateIndiv_in;
float rateIndiv_out;
float rateMax_in;
float rateMax_out;
float rateTotal_in;
float rateTotal_out;
};
#endif // PQIHANDLER_H

View File

@ -0,0 +1,48 @@
#include "pqihash.h"
pqihash::pqihash()
{
sha_hash = new uint8_t[SHA_DIGEST_LENGTH];
sha_ctx = new SHA_CTX;
SHA1_Init(sha_ctx);
doHash = true;
}
pqihash::~pqihash()
{
delete[] sha_hash;
delete sha_ctx;
}
void pqihash::addData(void *data, uint32_t len)
{
if (doHash)
{
SHA1_Update(sha_ctx, data, len);
}
}
void pqihash::Complete(std::string &hash)
{
if (!doHash)
{
hash = endHash;
return;
}
SHA1_Final(sha_hash, sha_ctx);
std::ostringstream out;
for(int i = 0; i < SHA_DIGEST_LENGTH; i++)
{
out << std::setw(2) << std::setfill('0') << std::hex;
out << (unsigned int) (sha_hash[i]);
}
endHash = out.str();
hash = endHash;
doHash = false;
}

View File

@ -0,0 +1,51 @@
/*
* libretroshare/src/pqi: pqihash.h
*
* 3P/PQI network interface for RetroShare.
*
* 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".
*
*/
#ifndef PQIHASH_H
#define PQIHASH_H
#include <openssl/sha.h>
#include <string>
#include <sstream>
#include <iomanip>
class pqihash
{
public:
pqihash();
~pqihash();
inline void addData(void *data, uint32_t len);
inline void Complete(std::string &hash);
private:
bool doHash;
std::string endHash;
uint8_t *sha_hash;
SHA_CTX *sha_ctx;
};
#endif // PQIHASH_H

View File

@ -0,0 +1,26 @@
#include "pqiindic.h"
Indicator::Indicator(uint16_t n = 1) :
num(n),
changeFlags(n)
{
IndicateChanged();
}
void Indicator::IndicateChanged()
{
for(uint16_t i = 0; i < num; i++)
changeFlags[i]=true;
}
bool Indicator::Changed(uint16_t idx = 0)
{
/* catch overflow */
if (idx > num - 1)
return false;
bool ans = changeFlags[idx];
changeFlags[idx] = false;
return ans;
}

View File

@ -0,0 +1,51 @@
/*
* "$Id: pqiindic.h,v 1.3 2007-02-18 21:46:49 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 PQIINDIC_H
#define PQIINDIC_H
#include <vector>
// This will indicate to num different sources
// when the event has occured.
class Indicator
{
public:
Indicator(uint16_t n = 1);
void IndicateChanged();
bool Changed(uint16_t idx = 0);
private:
uint16_t num;
std::vector<bool> changeFlags;
};
#endif // PQIINDIC_H

View File

@ -0,0 +1,48 @@
/*
* libretroshare/src/pqi: pqilistener.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-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".
*
*/
#ifndef PQILISTENER_H
#define PQILISTENER_H
// operating system specific network header.
#include "pqi/pqinetwork.h"
class pqilistener
{
public:
pqilistener() { return; }
virtual ~pqilistener() { return; }
virtual int tick() { return 1; }
virtual int status() { return 1; }
virtual int setListenAddr(struct sockaddr_in addr) { return 1; }
virtual int setuplisten() { return 1; }
virtual int resetlisten() { return 1; }
};
#endif // PQILISTENER_H

View File

@ -0,0 +1,90 @@
/*
* libretroshare/src/pqi: pqiloopback.cc
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-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 "pqi/pqi.h"
#include "pqi/pqiloopback.h"
/***
#define LOOPBACK_DEBUG 1
***/
pqiloopback::pqiloopback(std::string id)
:PQInterface(id)
{
setMaxRate(true, 0);
setMaxRate(false, 0);
setRate(true, 0);
setRate(false, 0);
return;
}
pqiloopback::~pqiloopback()
{
return;
}
int pqiloopback::SendItem(RsItem *i)
{
#ifdef LOOPBACK_DEBUG
std::cerr << "pqiloopback::SendItem()";
std::cerr << std::endl;
i->print(std::cerr);
std::cerr << std::endl;
#endif
objs.push_back(i);
return 1;
}
RsItem * pqiloopback::GetItem()
{
if (objs.size() > 0)
{
RsItem *pqi = objs.front();
objs.pop_front();
#ifdef LOOPBACK_DEBUG
std::cerr << "pqiloopback::GetItem()";
std::cerr << std::endl;
pqi->print(std::cerr);
std::cerr << std::endl;
#endif
return pqi;
}
return NULL;
}
// PQI interface.
int pqiloopback::tick()
{
return 0;
}
int pqiloopback::status()
{
return 0;
}

View File

@ -0,0 +1,55 @@
/*
* libretroshare/src/pqi: pqiloopback.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-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".
*
*/
#ifndef PQILOOPBACK_H
#define PQILOOPBACK_H
// The standard data types and the search interface.
#include "_pqi/pqi.h"
#include <map>
#include <list>
#include <iostream>
class pqiloopback: public PQInterface
{
public:
pqiloopback(std::string id);
virtual ~pqiloopback();
// search Interface.
virtual int SendItem(RsItem *item);
virtual RsItem *GetItem();
// PQI interface.
virtual int tick();
virtual int status();
virtual int notifyEvent(NetInterface *ni, int event) { return 0; } /* Not used */
private:
std::list<RsItem *> objs;
};
#endif //MRK_PQI_LOOPBACK_HEADER

View File

@ -0,0 +1,85 @@
/*
* libretroshare/src/pqi: pqimonitor.cc
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2007-2008 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/pqimonitor.h"
/***** DUMMY Connect CB for testing *****/
#include <iostream>
pqiConnectCbDummy::pqiConnectCbDummy()
{
std::cerr << "pqiConnectCbDummy()" << std::endl;
return;
}
pqiConnectCbDummy::~pqiConnectCbDummy()
{
return;
}
void pqiConnectCbDummy::peerStatus(std::string id,
struct sockaddr_in laddr, struct sockaddr_in raddr,
uint32_t type, uint32_t mode, uint32_t source)
{
std::cerr << "pqiConnectCbDummy::peerStatus()";
std::cerr << " id: " << id;
std::cerr << " laddr: " << inet_ntoa(laddr.sin_addr);
std::cerr << " lport: " << ntohs(laddr.sin_port);
std::cerr << " raddr: " << inet_ntoa(raddr.sin_addr);
std::cerr << " rport: " << ntohs(raddr.sin_port);
std::cerr << " type: " << type;
std::cerr << " mode: " << mode;
std::cerr << " source: " << source;
std::cerr << std::endl;
}
void pqiConnectCbDummy::peerConnectRequest(std::string id,
struct sockaddr_in raddr, uint32_t source)
{
std::cerr << "pqiConnectCbDummy::peerConnectRequest()";
std::cerr << " id: " << id;
std::cerr << " raddr: " << inet_ntoa(raddr.sin_addr);
std::cerr << ":" << ntohs(raddr.sin_port);
std::cerr << " source: " << source;
std::cerr << std::endl;
}
void pqiConnectCbDummy::stunStatus(std::string id, struct sockaddr_in raddr,
uint32_t type, uint32_t flags)
{
std::cerr << "pqiConnectCbDummy::stunStatus()";
std::cerr << " idhash: " << RsUtil::BinToHex(id) << " raddr: " << inet_ntoa(raddr.sin_addr);
std::cerr << ":" << ntohs(raddr.sin_port);
std::cerr << " type: " << type;
std::cerr << " flags: " << flags;
std::cerr << std::endl;
}

View File

@ -0,0 +1,138 @@
/*
* libretroshare/src/pqi: pqimonitor.h
*
* 3P/PQI network interface for RetroShare.
*
* 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".
*
*/
#ifndef PQIMONITOR_H
#define PQIMONITOR_H
/**** Rough sketch of a Monitor class
* expect it to change significantly
*
*/
#include "_pqi/pqinetwork.h"
#include "_util/rsprint.h"
#include <inttypes.h>
#include <string>
#include <list>
/************** Define Type/Mode/Source ***************/
/* STATE MASK */
const uint32_t RS_PEER_STATE_MASK = 0x00ff;
const uint32_t RS_PEER_ACTION_MASK = 0xff00;
/* STATE */
const uint32_t RS_PEER_S_FRIEND = 0x0001;
const uint32_t RS_PEER_S_ONLINE = 0x0002; /* heard from recently..*/
const uint32_t RS_PEER_S_CONNECTED = 0x0004;
const uint32_t RS_PEER_S_UNREACHABLE = 0x0008;
/* ACTIONS */
const uint32_t RS_PEER_NEW = 0x0001; /* new Peer */
const uint32_t RS_PEER_ONLINE = 0x0002;
const uint32_t RS_PEER_CONNECTED = 0x0004;
const uint32_t RS_PEER_MOVED = 0x0008; /* moved from F->O or O->F */
const uint32_t RS_PEER_DISCONNECTED = 0x0010;
const uint32_t RS_PEER_CONNECT_REQ = 0x0020;
/* Stun Status Flags */
//const uint32_t RS_STUN_SRC_DHT = 0x0001;
//const uint32_t RS_STUN_SRC_PEER = 0x0002;
const uint32_t RS_STUN_ONLINE = 0x0010;
const uint32_t RS_STUN_FRIEND = 0x0020;
const uint32_t RS_STUN_FRIEND_OF_FRIEND = 0x0040;
#define RS_CONNECT_PASSIVE 1
#define RS_CONNECT_ACTIVE 2
#define RS_CB_DHT 1 /* from dht */
#define RS_CB_DISC 2 /* from peers */
#define RS_CB_PERSON 3 /* from connection */
#define RS_CB_PROXY 4 /* via proxy */
class pqipeer
{
public:
std::string id;
std::string name;
uint32_t state;
uint32_t actions;
};
class p3ConnectMgr;
class pqiMonitor
{
public:
pqiMonitor() :mConnMgr(NULL) { return; }
virtual ~pqiMonitor() { return; }
void setConnectionMgr(p3ConnectMgr *cm) { mConnMgr = cm; }
virtual void statusChange(const std::list<pqipeer> &plist) = 0;
//virtual void peerStatus(std::string id, uint32_t mode) = 0;
protected:
p3ConnectMgr *mConnMgr;
};
class pqiConnectCb
{
public:
virtual ~pqiConnectCb() { return; }
virtual void peerStatus(std::string id,struct sockaddr_in laddr, struct sockaddr_in raddr,
uint32_t type, uint32_t flags, uint32_t source) = 0;
virtual void peerConnectRequest(std::string id,struct sockaddr_in raddr, uint32_t source) = 0;
virtual void stunStatus(std::string id, struct sockaddr_in raddr,
uint32_t type, uint32_t flags) = 0;
};
/**** DUMMY CB FOR TESTING (just prints) ****/
class pqiConnectCbDummy: public pqiConnectCb
{
public:
pqiConnectCbDummy();
virtual ~pqiConnectCbDummy();
virtual void peerStatus(std::string id,
struct sockaddr_in laddr, struct sockaddr_in raddr,
uint32_t type, uint32_t mode, uint32_t source);
virtual void peerConnectRequest(std::string id,
struct sockaddr_in raddr, uint32_t source);
virtual void stunStatus(std::string id, struct sockaddr_in raddr, uint32_t type, uint32_t flags);
};
#endif // PQIMONITOR_H

View File

@ -0,0 +1,866 @@
/*
* "$Id: pqinetwork.cc,v 1.18 2007-04-15 18:45:18 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/pqinetwork.h"
#include "util/rsnet.h"
#include <errno.h>
#include <iostream>
#include <stdio.h>
#include "util/rsdebug.h"
#include <sstream>
#include <iomanip>
static const int pqinetzone = 96184;
/*****
* #define NET_DEBUG 1
****/
#ifdef WINDOWS_SYS /* Windows - define errno */
int errno;
#else /* Windows - define errno */
#include <netdb.h>
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
std::ostream &showSocketError(std::ostream &out)
{
int err = errno;
out << "\tSocket Error(" << err << ") : ";
out << socket_errorType(err) << std::endl;
return out;
}
std::string socket_errorType(int err)
{
if (err == EBADF)
{
return std::string("EBADF");
}
else if (err == EINVAL)
{
return std::string("EINVAL");
}
else if (err == EFAULT)
{
return std::string("EFAULT");
}
else if (err == ENOTSOCK)
{
return std::string("ENOTSOCK");
}
else if (err == EISCONN)
{
return std::string("EISCONN");
}
else if (err == ECONNREFUSED)
{
return std::string("ECONNREFUSED");
}
else if (err == ETIMEDOUT)
{
return std::string("ETIMEDOUT");
}
else if (err == ENETUNREACH)
{
return std::string("ENETUNREACH");
}
else if (err == EADDRINUSE)
{
return std::string("EADDRINUSE");
}
else if (err == EINPROGRESS)
{
return std::string("EINPROGRESS");
}
else if (err == EALREADY)
{
return std::string("EALREADY");
}
else if (err == EAGAIN)
{
return std::string("EAGAIN");
}
else if (err == EISCONN)
{
return std::string("EISCONN");
}
else if (err == ENOTCONN)
{
return std::string("ENOTCONN");
}
return std::string("UNKNOWN ERROR CODE");
}
#include <net/if.h>
#include <sys/ioctl.h>
std::list<std::string> getLocalInterfaces()
{
std::list<std::string> addrs;
int sock = 0;
struct ifreq ifreq;
struct if_nameindex *iflist = if_nameindex();
struct if_nameindex *ifptr = iflist;
//need a socket for ioctl()
if( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
pqioutput(PQL_ALERT, pqinetzone,
"Cannot Determine Local Addresses!");
exit(1);
}
if (!ifptr)
{
pqioutput(PQL_ALERT, pqinetzone,
"getLocalInterfaces(): ERROR if_nameindex == NULL");
}
// loop through the interfaces.
//for(; *(char *)ifptr != 0; ifptr++)
for(; ifptr->if_index != 0; ifptr++)
{
//copy in the interface name to look up address of
strncpy(ifreq.ifr_name, ifptr->if_name, IF_NAMESIZE);
if(ioctl(sock, SIOCGIFADDR, &ifreq) != 0)
{
std::ostringstream out;
out << "Cannot Determine Address for Iface: ";
out << ifptr -> if_name << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out.str());
}
else
{
struct sockaddr_in *aptr =
(struct sockaddr_in *) &ifreq.ifr_addr;
const char *astr=inet_ntoa(aptr -> sin_addr);
std::ostringstream out;
out << "Iface: ";
out << ifptr -> if_name << std::endl;
out << " Address: " << astr;
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out.str());
addrs.push_back(astr);
}
}
// free socket -> or else run out of fds.
close(sock);
if_freenameindex(iflist);
return addrs;
}
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#else
std::ostream &showSocketError(std::ostream &out)
{
int err = WSAGetLastError();
out << "\tSocket Error(" << err << ") : ";
out << socket_errorType(err) << std::endl;
return out;
}
std::string socket_errorType(int err)
{
if (err == WSAEBADF)
{
return std::string("WSABADF");
}
else if (err == WSAEINTR)
{
return std::string("WSAEINTR");
}
else if (err == WSAEACCES)
{
return std::string("WSAEACCES");
}
else if (err == WSAEFAULT)
{
return std::string("WSAEFAULT");
}
else if (err == WSAEINVAL)
{
return std::string("WSAEINVAL");
}
else if (err == WSAEMFILE)
{
return std::string("WSAEMFILE");
}
else if (err == WSAEWOULDBLOCK)
{
return std::string("WSAEWOULDBLOCK");
}
else if (err == WSAEINPROGRESS)
{
return std::string("WSAEINPROGRESS");
}
else if (err == WSAEALREADY)
{
return std::string("WSAEALREADY");
}
else if (err == WSAENOTSOCK)
{
return std::string("WSAENOTSOCK");
}
else if (err == WSAEDESTADDRREQ)
{
return std::string("WSAEDESTADDRREQ");
}
else if (err == WSAEMSGSIZE)
{
return std::string("WSAEMSGSIZE");
}
else if (err == WSAEPROTOTYPE)
{
return std::string("WSAEPROTOTYPE");
}
else if (err == WSAENOPROTOOPT)
{
return std::string("WSAENOPROTOOPT");
}
else if (err == WSAENOTSOCK)
{
return std::string("WSAENOTSOCK");
}
else if (err == WSAEISCONN)
{
return std::string("WSAISCONN");
}
else if (err == WSAECONNREFUSED)
{
return std::string("WSACONNREFUSED");
}
else if (err == WSAECONNRESET)
{
return std::string("WSACONNRESET");
}
else if (err == WSAETIMEDOUT)
{
return std::string("WSATIMEDOUT");
}
else if (err == WSAENETUNREACH)
{
return std::string("WSANETUNREACH");
}
else if (err == WSAEADDRINUSE)
{
return std::string("WSAADDRINUSE");
}
else if (err == WSAEAFNOSUPPORT)
{
return std::string("WSAEAFNOSUPPORT (normally UDP related!)");
}
return std::string("----WINDOWS OPERATING SYSTEM FAILURE----");
}
#include <iphlpapi.h>
//#include <iprtrmib.h>
// A function to determine the interfaces on your computer....
// No idea of how to do this in windows....
// see if it compiles.
std::list<std::string> getLocalInterfaces()
{
std::list<std::string> addrs;
/* USE MIB IPADDR Interface */
PMIB_IPADDRTABLE iptable = NULL;
DWORD dwSize = 0;
if (GetIpAddrTable(iptable, &dwSize, 0) !=
ERROR_INSUFFICIENT_BUFFER)
{
pqioutput(PQL_ALERT, pqinetzone,
"Cannot Find Windoze Interfaces!");
exit(0);
}
iptable = (MIB_IPADDRTABLE *) malloc(dwSize);
GetIpAddrTable(iptable, &dwSize, 0);
struct in_addr addr;
for(unsigned int i = 0; i < iptable -> dwNumEntries; i++)
{
std::ostringstream out;
out << "Iface(" << iptable->table[i].dwIndex << ") ";
addr.s_addr = iptable->table[i].dwAddr;
out << " => " << inet_ntoa(addr);
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out.str());
addrs.push_back(inet_ntoa(addr));
}
return addrs;
}
// implement the improved unix inet address fn.
// using old one.
int inet_aton(const char *name, struct in_addr *addr)
{
return (((*addr).s_addr = inet_addr(name)) != INADDR_NONE);
}
// This returns in Net Byte Order.
// NB: Linux man page claims it is in Host Byte order, but
// this is blatantly wrong!..... (for Debian anyway)
// Making this consistent with the Actual behavior (rather than documented).
in_addr_t inet_netof(struct in_addr addr)
{
return pqi_inet_netof(addr);
}
// This returns in Host Byte Order. (as the man page says)
// Again, to be consistent with Linux.
in_addr_t inet_network(const char *inet_name)
{
struct in_addr addr;
if (inet_aton(inet_name, &addr))
{
#ifdef NET_DEBUG
// std::cerr << "inet_network(" << inet_name << ") : ";
// std::cerr << inet_ntoa(addr) << std::endl;
#endif
return ntohl(inet_netof(addr));
}
return 0xffffffff;
//return -1;
}
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#include <iostream>
// This returns in Net Byte Order.
// NB: Linux man page claims it is in Host Byte order, but
// this is blatantly wrong!..... (for Debian anyway)
// Making this consistent with the Actual behavior (rather than documented).
in_addr_t pqi_inet_netof(struct in_addr addr)
{
// decide if A class address.
unsigned long haddr = ntohl(addr.s_addr);
unsigned long abit = haddr & 0xff000000UL;
unsigned long bbit = haddr & 0xffff0000UL;
unsigned long cbit = haddr & 0xffffff00UL;
#ifdef NET_DEBUG
std::cerr << "inet_netof(" << inet_ntoa(addr) << ") ";
#endif
if (!((haddr >> 31) | 0x0UL)) // MSB = 0
{
#ifdef NET_DEBUG
std::cerr << " Type A " << std::endl;
std::cerr << "\tShifted(31): " << (haddr >> 31);
std::cerr << " Xord(0x0UL): " <<
!((haddr >> 31) | 0x0UL) << std::endl;
#endif
return htonl(abit);
}
else if (!((haddr >> 30) ^ 0x2UL)) // 2MSBs = 10
{
#ifdef NET_DEBUG
std::cerr << " Type B " << std::endl;
std::cerr << "\tShifted(30): " << (haddr >> 30);
std::cerr << " Xord(0x2UL): " <<
!((haddr >> 30) | 0x2UL) << std::endl;
#endif
return htonl(bbit);
}
else if (!((haddr >> 29) ^ 0x6UL)) // 3MSBs = 110
{
#ifdef NET_DEBUG
std::cerr << " Type C " << std::endl;
std::cerr << "\tShifted(29): " << (haddr >> 29);
std::cerr << " Xord(0x6UL): " <<
!((haddr >> 29) | 0x6UL) << std::endl;
#endif
return htonl(cbit);
}
else if (!((haddr >> 28) ^ 0xeUL)) // 4MSBs = 1110
{
#ifdef NET_DEBUG
std::cerr << " Type Multicast " << std::endl;
std::cerr << "\tShifted(28): " << (haddr >> 28);
std::cerr << " Xord(0xeUL): " <<
!((haddr >> 29) | 0xeUL) << std::endl;
#endif
return addr.s_addr; // return full address.
}
else if (!((haddr >> 27) ^ 0x1eUL)) // 5MSBs = 11110
{
#ifdef NET_DEBUG
std::cerr << " Type Reserved " << std::endl;
std::cerr << "\tShifted(27): " << (haddr >> 27);
std::cerr << " Xord(0x1eUL): " <<
!((haddr >> 27) | 0x1eUL) << std::endl;
#endif
return addr.s_addr; // return full address.
}
return htonl(abit);
}
int sockaddr_cmp(struct sockaddr_in &addr1, struct sockaddr_in &addr2 )
{
if (addr1.sin_family != addr2.sin_family)
return addr1.sin_family - addr2.sin_family;
if (addr1.sin_addr.s_addr != addr2.sin_addr.s_addr)
return (addr1.sin_addr.s_addr - addr2.sin_addr.s_addr);
if (addr1.sin_port != addr2.sin_port)
return (addr1.sin_port - addr2.sin_port);
return 0;
}
int inaddr_cmp(struct sockaddr_in addr1, struct sockaddr_in addr2 )
{
#ifdef NET_DEBUG
std::ostringstream out;
out << "inaddr_cmp(" << inet_ntoa(addr1.sin_addr);
out << "-" << addr1.sin_addr.s_addr;
out << "," << inet_ntoa(addr2.sin_addr);
out << "-" << addr2.sin_addr.s_addr << ")" << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out.str());
#endif
if (addr1.sin_addr.s_addr == addr2.sin_addr.s_addr)
{
return 0;
}
if (addr1.sin_addr.s_addr < addr2.sin_addr.s_addr)
return -1;
return 1;
}
int inaddr_cmp(struct sockaddr_in addr1, unsigned long addr2)
{
#ifdef NET_DEBUG
struct in_addr inaddr_tmp;
inaddr_tmp.s_addr = addr2;
std::ostringstream out;
out << "inaddr_cmp2(" << inet_ntoa(addr1.sin_addr);
out << " vs " << inet_ntoa(inaddr_tmp);
out << " /or/ ";
out << std::hex << std::setw(10) << addr1.sin_addr.s_addr;
out << " vs " << std::setw(10) << addr2 << ")" << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out.str());
#endif
if (addr1.sin_addr.s_addr == addr2)
{
return 0;
}
if (addr1.sin_addr.s_addr < addr2)
return -1;
return 1;
}
struct in_addr getPreferredInterface() // returns best addr.
{
std::list<std::string> addrs = getLocalInterfaces();
std::list<std::string>::iterator it;
struct in_addr addr_zero = {0}, addr_loop = {0}, addr_priv = {0}, addr_ext = {0}, addr = {0};
bool found_zero = false;
bool found_loopback = false;
bool found_priv = false;
bool found_ext = false;
// find the first of each of these.
// if ext - take first.
// if no ext -> first priv
// if no priv -> first loopback.
for(it = addrs.begin(); it != addrs.end(); it++)
{
inet_aton((*it).c_str(), &addr);
// for windows silliness (returning 0.0.0.0 as valid addr!).
if (addr.s_addr == 0)
{
if (!found_zero)
{
found_zero = true;
addr_zero = addr;
}
}
else if (isLoopbackNet(&addr))
{
if (!found_loopback)
{
found_loopback = true;
addr_loop = addr;
}
}
else if (isPrivateNet(&addr))
{
if (!found_priv)
{
found_priv = true;
addr_priv = addr;
}
}
else
{
if (!found_ext)
{
found_ext = true;
addr_ext = addr;
return addr_ext;
}
}
}
if (found_priv)
return addr_priv;
// next bit can happen under windows,
// a general address is still
// preferable to a loopback device.
if (found_zero)
return addr_zero;
if (found_loopback)
return addr_loop;
// shound be 255.255.255.255 (error).
addr.s_addr = 0xffffffff;
return addr;
}
bool sameNet(struct in_addr *addr, struct in_addr *addr2)
{
#ifdef NET_DEBUG
std::cerr << "sameNet: " << inet_ntoa(*addr);
std::cerr << " VS " << inet_ntoa(*addr2);
std::cerr << std::endl;
#endif
struct in_addr addrnet, addrnet2;
addrnet.s_addr = inet_netof(*addr);
addrnet2.s_addr = inet_netof(*addr2);
#ifdef NET_DEBUG
std::cerr << " (" << inet_ntoa(addrnet);
std::cerr << " =?= " << inet_ntoa(addrnet2);
std::cerr << ")" << std::endl;
#endif
in_addr_t address1 = htonl(addr->s_addr);
in_addr_t address2 = htonl(addr2->s_addr);
// handle case for private net: 172.16.0.0/12
if (address1>>20 == (172<<4 | 16>>4))
{
return (address1>>20 == address2>>20);
}
return (inet_netof(*addr) == inet_netof(*addr2));
}
bool isSameSubnet(struct in_addr *addr1, struct in_addr *addr2)
{
/*
* check that the (addr1 & 255.255.255.0) == (addr2 & 255.255.255.0)
*/
unsigned long a1 = ntohl(addr1->s_addr);
unsigned long a2 = ntohl(addr2->s_addr);
return ((a1 & 0xffffff00) == (a2 & 0xffffff00));
}
/* This just might be portable!!! will see!!!
* Unfortunately this is usable on winXP+, determined by: (_WIN32_WINNT >= 0x0501)
* but not older platforms.... which must use gethostbyname.
*
* include it for now.....
*/
bool LookupDNSAddr(std::string name, struct sockaddr_in &addr)
{
#if 1
char service[100];
struct addrinfo hints_st;
struct addrinfo *hints = &hints_st;
struct addrinfo *res;
hints -> ai_flags = 0; // (cygwin don;t like these) AI_ADDRCONFIG | AI_NUMERICSERV;
hints -> ai_family = AF_INET;
hints -> ai_socktype = 0;
hints -> ai_protocol = 0;
hints -> ai_addrlen = 0;
hints -> ai_addr = NULL;
hints -> ai_canonname = NULL;
hints -> ai_next = NULL;
/* get the port number */
sprintf(service, "%d", ntohs(addr.sin_port));
/* set it to IPV4 */
#ifdef NET_DEBUG
std::cerr << "LookupDNSAddr() name: " << name << " service: " << service << std::endl;
#endif
int err = 0;
if (0 != (err = getaddrinfo(name.c_str(), service, hints, &res)))
{
#ifdef NET_DEBUG
std::cerr << "LookupDNSAddr() getaddrinfo failed!" << std::endl;
std::cerr << "Error: " << gai_strerror(err) << std::endl;
#endif
return false;
}
if ((res) && (res->ai_family == AF_INET))
{
addr = *((struct sockaddr_in *) res->ai_addr);
freeaddrinfo(res);
#ifdef NET_DEBUG
std::cerr << "LookupDNSAddr() getaddrinfo found address" << std::endl;
std::cerr << "addr: " << inet_ntoa(addr.sin_addr) << std::endl;
std::cerr << "port: " << ntohs(addr.sin_port) << std::endl;
#endif
return true;
}
#ifdef NET_DEBUG
std::cerr << "getaddrinfo failed - no address" << std::endl;
#endif
#endif
#ifdef NET_DEBUG
//std::cerr << "getaddrinfo disabled" << std::endl;
#endif
return false;
}
/*************************************************************
* Socket Library Wrapper Functions
* to get over the crapness of the windows.
*
*/
int unix_close(int fd)
{
int ret;
/******************* WINDOWS SPECIFIC PART ******************/
#ifndef WINDOWS_SYS // ie UNIX
ret = close(fd);
#else
#ifdef NET_DEBUG
std::cerr << "unix_close()" << std::endl;
#endif
ret = closesocket(fd);
/* translate error */
#endif
/******************* WINDOWS SPECIFIC PART ******************/
return ret;
}
int unix_socket(int domain, int type, int protocol)
{
int osock = socket(PF_INET, SOCK_STREAM, 0);
/******************* WINDOWS SPECIFIC PART ******************/
#ifdef WINDOWS_SYS // WINDOWS
#ifdef NET_DEBUG
std::cerr << "unix_socket()" << std::endl;
#endif
if ((unsigned) osock == INVALID_SOCKET)
{
// Invalidate socket Unix style.
osock = -1;
errno = WinToUnixError(WSAGetLastError());
}
#endif
/******************* WINDOWS SPECIFIC PART ******************/
return osock;
}
int unix_fcntl_nonblock(int fd)
{
int ret;
/******************* WINDOWS SPECIFIC PART ******************/
#ifndef WINDOWS_SYS // ie UNIX
ret = fcntl(fd, F_SETFL, O_NONBLOCK);
#ifdef NET_DEBUG
std::cerr << "unix_fcntl_nonblock():" << ret << " errno:" << errno << std::endl;
#endif
#else
unsigned long int on = 1;
ret = ioctlsocket(fd, FIONBIO, &on);
#ifdef NET_DEBUG
std::cerr << "unix_fcntl_nonblock()" << std::endl;
#endif
if (ret != 0)
{
/* store unix-style error
*/
ret = -1;
errno = WinToUnixError(WSAGetLastError());
}
#endif
/******************* WINDOWS SPECIFIC PART ******************/
return ret;
}
int unix_connect(int fd, const struct sockaddr *serv_addr, socklen_t addrlen)
{
int ret = connect(fd, serv_addr, addrlen);
/******************* WINDOWS SPECIFIC PART ******************/
#ifdef WINDOWS_SYS // WINDOWS
#ifdef NET_DEBUG
std::cerr << "unix_connect()" << std::endl;
#endif
if (ret != 0)
{
errno = WinToUnixError(WSAGetLastError());
ret = -1;
}
#endif
/******************* WINDOWS SPECIFIC PART ******************/
return ret;
}
int unix_getsockopt_error(int sockfd, int *err)
{
int ret;
*err = 1;
/******************* WINDOWS SPECIFIC PART ******************/
#ifndef WINDOWS_SYS // ie UNIX
socklen_t optlen = 4;
ret=getsockopt(sockfd, SOL_SOCKET, SO_ERROR, err, &optlen);
#else // WINDOWS_SYS
int optlen = 4;
ret=getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char *) err, &optlen);
/* translate */
#ifdef NET_DEBUG
std::cerr << "unix_getsockopt_error() returned: " << (int) err << std::endl;
#endif
if (*err != 0)
{
*err = WinToUnixError(*err);
}
#endif
/******************* WINDOWS SPECIFIC PART ******************/
return ret;
}
/******************* WINDOWS SPECIFIC PART ******************/
#ifdef WINDOWS_SYS // ie WINDOWS.
int WinToUnixError(int error)
{
#ifdef NET_DEBUG
std::cerr << "WinToUnixError(" << error << ")" << std::endl;
#endif
switch(error)
{
case WSAEINPROGRESS:
return EINPROGRESS;
break;
case WSAEWOULDBLOCK:
return EINPROGRESS;
break;
case WSAENETUNREACH:
return ENETUNREACH;
break;
case WSAETIMEDOUT:
return ETIMEDOUT;
break;
case WSAEHOSTDOWN:
return EHOSTDOWN;
break;
case WSAECONNREFUSED:
return ECONNREFUSED;
break;
case WSAECONNRESET:
return ECONNRESET;
break;
default:
#ifdef NET_DEBUG
std::cerr << "WinToUnixError(" << error << ") Code Unknown!";
std::cerr << std::endl;
#endif
break;
}
return ECONNREFUSED; /* sensible default? */
}
#endif
/******************* WINDOWS SPECIFIC PART ******************/

View File

@ -0,0 +1,138 @@
/*
* "$Id: pqinetwork.h,v 1.15 2007-04-15 18:45:18 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 PQINETWORK_H
#define PQINETWORK_H
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/poll.h>
//socket blocking/options.
#include <fcntl.h>
#include <inttypes.h>
#else
/* This defines the platform to be WinXP or later...
* and is needed for getaddrinfo.... (not used anymore)
*
*/
#define _WIN32_WINNT 0x0501
#include "util/rsnet.h" /* more generic networking header */
#include <winsock2.h>
#include <ws2tcpip.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);
in_addr_t inet_network(const char *inet_name);
int inet_aton(const char *name, struct in_addr *addr);
extern int errno; /* Define extern errno, to duplicate unix behaviour */
/* define the Unix Error Codes that we use...
* NB. we should make the same, but not necessary
*/
#define EAGAIN 11
#define EWOULDBLOCK EAGAIN
#define EUSERS 87
#define ENOTSOCK 88
#define EOPNOTSUPP 95
#define EADDRINUSE 98
#define EADDRNOTAVAIL 99
#define ENETDOWN 100
#define ENETUNREACH 101
#define ECONNRESET 104
#define ETIMEDOUT 110
#define ECONNREFUSED 111
#define EHOSTDOWN 112
#define EHOSTUNREACH 113
#define EALREADY 114
#define EINPROGRESS 115
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#include <iostream>
#include <string>
#include <list>
// Same def - different functions...
std::ostream &showSocketError(std::ostream &out);
std::string socket_errorType(int err);
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);
struct in_addr getPreferredInterface(); // returns best addr.
std::list<std::string> getLocalInterfaces(); // 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);
bool sameNet(struct in_addr *addr, struct in_addr *addr2);
in_addr_t pqi_inet_netof(struct in_addr addr); // our implementation.
bool LookupDNSAddr(std::string name, struct sockaddr_in &addr);
/* universal socket interface */
int unix_close(int sockfd);
int unix_socket(int domain, int type, int protocol);
int unix_fcntl_nonblock(int sockfd);
int unix_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
int unix_getsockopt_error(int sockfd, int *err);
#ifdef WINDOWS_SYS // WINDOWS
/******************* WINDOWS SPECIFIC PART ******************/
int WinToUnixError(int error);
#endif
#endif // PQINETWORK_H

View File

@ -0,0 +1,51 @@
#ifndef PQI_NOTIFY_INTERFACE_H
#define PQI_NOTIFY_INTERFACE_H
/*
* libretroshare/src/rsserver: pqinotify.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 "_rsiface/rsnotify.h" /* for ids */
/* Interface for System Notification: Implemented in rsserver */
/* Global Access -> so we don't need everyone to have a pointer to this! */
class pqiNotify
{
public:
pqiNotify() { return; }
virtual ~pqiNotify() { return; }
/* Input from libretroshare */
virtual bool AddPopupMessage(uint32_t ptype, std::string name, std::string msg) = 0;
virtual bool AddSysMessage(uint32_t sysid, uint32_t type, std::string title, std::string msg) = 0;
virtual bool AddLogMessage(uint32_t sysid, uint32_t type, std::string title, std::string msg) = 0;
virtual bool AddFeedItem(uint32_t type, std::string id1, std::string id2, std::string id3) = 0;
};
extern pqiNotify *getPqiNotify();
#endif

View File

@ -0,0 +1,479 @@
/*
* libretroshare/src/pqi pqiperson.cc
*
* 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/pqiperson.h"
const int pqipersonzone = 82371;
/****
* #define PERSON_DEBUG
****/
pqiconnect::pqiconnect(RsSerialiser *rss, NetBinInterface *ni_in) :
pqistreamer(rss, ni_in->PeerId(), ni_in, 0), // pqistreamer will cleanup NetInterface.
NetInterface(NULL, ni_in->PeerId()), // No need for callback.
ni(ni_in)
{
if (!ni_in)
{
std::cerr << "pqiconnect::pqiconnect() NetInterface == NULL, FATAL!";
std::cerr << std::endl;
exit(1);
}
}
int pqiconnect::connect(struct sockaddr_in raddr)
{
return ni->connect(raddr);
}
int pqiconnect::listen()
{
return ni -> listen();
}
int pqiconnect::stoplistening()
{
return ni -> stoplistening();
}
int pqiconnect::reset()
{
return ni -> reset();
}
int pqiconnect::disconnect()
{
return ni -> reset();
}
bool pqiconnect::connect_parameter(uint32_t type, uint32_t value)
{
return ni -> connect_parameter(type, value);
}
std::string pqiconnect::PeerId()
{
if (ni)
{
return ni->PeerId();
}
else
{
return PQInterface::PeerId();
}
}
bool pqiconnect::thisNetInterface(NetInterface *ni_in)
{
return (ni_in == ni);
}
pqiperson::pqiperson(std::string id, pqipersongrp *pg)
:PQInterface(id), active(false), activepqi(NULL),
inConnectAttempt(false), waittimes(0),
pqipg(pg)
{
/* must check id! */
return;
}
pqiperson::~pqiperson()
{
// clean up the children.
std::map<uint32_t, pqiconnect *>::iterator it;
for(it = kids.begin(); it != kids.end(); it++)
{
pqiconnect *pc = (it->second);
delete pc;
}
kids.clear();
}
// The PQInterface interface.
int pqiperson::SendItem(RsItem *i)
{
std::ostringstream out;
out << "pqiperson::SendItem()";
if (active)
{
out << " Active: Sending On";
return activepqi -> SendItem(i);
}
else
{
out << " Not Active: Used to put in ToGo Store";
out << std::endl;
out << " Now deleting...";
delete i;
}
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
return 0; // queued.
}
RsItem *pqiperson::GetItem()
{
if (active)
return activepqi -> GetItem();
// else not possible.
return NULL;
}
int pqiperson::status()
{
if (active)
return activepqi -> status();
return -1;
}
// tick......
int pqiperson::tick()
{
int activeTick = 0;
{
std::ostringstream out;
out << "pqiperson::tick() Id: " << PeerId() << " ";
if (active)
out << "***Active***";
else
out << ">>InActive<<";
out << std::endl;
out << "Activepqi: " << activepqi << " inConnectAttempt: ";
if (inConnectAttempt)
out << "In Connection Attempt";
else
out << " Not Connecting ";
out << std::endl;
// 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;
}
out << "\tTicking Child: " << (it->first) << std::endl;
}
pqioutput(PQL_DEBUG_ALL, pqipersonzone, out.str());
} // end of pqioutput.
return activeTick;
}
// 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)
{
{
std::ostringstream out;
out << "pqiperson::notifyEvent() Id: " << PeerId();
out << std::endl;
out << "Message: " << newState << " from: " << ni << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
}
/* find the pqi, */
pqiconnect *pqi = NULL;
uint32_t type = 0;
std::map<uint32_t, pqiconnect *>::iterator it;
/* start again */
int i = 0;
for(it = kids.begin(); it != kids.end(); it++)
{
std::ostringstream out;
out << "pqiperson::connectattempt() Kid# ";
out << i << " of " << kids.size();
out << std::endl;
out << " type: " << (it->first);
out << " ni: " << (it->second)->ni;
out << " in_ni: " << ni;
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
i++;
if ((it->second)->thisNetInterface(ni))
{
pqi = (it->second);
type = (it->first);
}
}
if (!pqi)
{
pqioutput(PQL_WARNING, pqipersonzone, "Unknown notfyEvent Source!");
return -1;
}
switch(newState)
{
case CONNECT_RECEIVED:
case CONNECT_SUCCESS:
/* notify */
if (pqipg)
pqipg->notifyConnect(PeerId(), type, true);
if ((active) && (activepqi != pqi)) // already connected - trouble
{
pqioutput(PQL_WARNING, pqipersonzone,
"CONNECT_SUCCESS+active->trouble: shutdown EXISTING->switch to new one!");
// This is the RESET that's killing the connections.....
activepqi -> reset();
// this causes a recursive call back into this fn.
// which cleans up state.
// we only do this if its not going to mess with new conn.
}
/* now install a new one. */
{
pqioutput(PQL_WARNING, pqipersonzone,
"CONNECT_SUCCESS->marking so! (resetting others)");
// mark as active.
active = true;
activepqi = pqi;
inConnectAttempt = false;
/* reset all other children? (clear up long UDP attempt) */
for(it = kids.begin(); it != kids.end(); it++)
{
if (it->second != activepqi)
{
it->second->reset();
}
}
return 1;
}
break;
case CONNECT_UNREACHABLE:
case CONNECT_FIREWALLED:
case CONNECT_FAILED:
if (active)
{
if (activepqi == pqi)
{
pqioutput(PQL_WARNING, pqipersonzone,
"CONNECT_FAILED->marking so!");
active = false;
activepqi = NULL;
}
else
{
pqioutput(PQL_WARNING, pqipersonzone,
"CONNECT_FAIL+not activepqi->strange!");
// probably UDP connect has failed,
// TCP connection has been made since attempt started.
return -1;
}
}
else
{
pqioutput(PQL_WARNING, pqipersonzone,
"CONNECT_FAILED+NOT active -> try connect again");
}
/* notify up (But not if we are actually active: rtn -1 case above) */
if (pqipg)
pqipg->notifyConnect(PeerId(), type, false);
return 1;
break;
default:
break;
}
return -1;
}
/***************** Not PQInterface Fns ***********************/
int pqiperson::reset()
{
{
std::ostringstream out;
out << "pqiperson::reset() Id: " << PeerId();
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
}
std::map<uint32_t, pqiconnect *>::iterator it;
for(it = kids.begin(); it != kids.end(); it++)
{
(it->second) -> reset();
}
activepqi = NULL;
active = false;
return 1;
}
int pqiperson::addChildInterface(uint32_t type, pqiconnect *pqi)
{
{
std::ostringstream out;
out << "pqiperson::addChildInterface() : Id " << PeerId() << " " << type;
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
}
kids[type] = pqi;
return 1;
}
/***************** PRIVATE FUNCTIONS ***********************/
// functions to iterate over the connects and change state.
int pqiperson::listen()
{
{
std::ostringstream out;
out << "pqiperson::listen() Id: " << PeerId();
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
}
if (!active)
{
std::map<uint32_t, pqiconnect *>::iterator it;
for(it = kids.begin(); it != kids.end(); it++)
{
// set them all listening.
(it->second) -> listen();
}
}
return 1;
}
int pqiperson::stoplistening()
{
{
std::ostringstream out;
out << "pqiperson::stoplistening() Id: " << PeerId();
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
}
std::map<uint32_t, pqiconnect *>::iterator it;
for(it = kids.begin(); it != kids.end(); it++)
{
// set them all listening.
(it->second) -> stoplistening();
}
return 1;
}
int pqiperson::connect(uint32_t type, struct sockaddr_in raddr, uint32_t delay, uint32_t period, uint32_t timeout)
{
#ifdef PERSON_DEBUG
{
std::ostringstream out;
out << "pqiperson::connect() Id: " << PeerId();
out << " type: " << type;
out << " addr: " << inet_ntoa(raddr.sin_addr);
out << ":" << ntohs(raddr.sin_port);
out << " delay: " << delay;
out << " period: " << period;
out << " timeout: " << timeout;
out << std::endl;
std::cerr << out.str();
//pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
}
#endif
std::map<uint32_t, pqiconnect *>::iterator it;
it = kids.find(type);
if (it == kids.end())
{
#ifdef PERSON_DEBUG
std::ostringstream out;
out << "pqiperson::connect()";
out << " missing pqiconnect";
out << std::endl;
std::cerr << out.str();
//pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
#endif
return 0;
}
/* set the parameters */
(it->second)->reset();
#ifdef PERSON_DEBUG
std::cerr << "pqiperson::connect() setting connect_parameters" << std::endl;
#endif
(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);
(it->second)->connect(raddr);
// flag if we started a new connectionAttempt.
inConnectAttempt = true;
return 1;
}
float pqiperson::getRate(bool in)
{
// get the rate from the active one.
if ((!active) || (activepqi == NULL))
return 0;
return activepqi -> getRate(in);
}
void pqiperson::setMaxRate(bool in, float val)
{
// set to all of them. (and us)
PQInterface::setMaxRate(in, val);
// clean up the children.
std::map<uint32_t, pqiconnect *>::iterator it;
for(it = kids.begin(); it != kids.end(); it++)
{
(it->second) -> setMaxRate(in, val);
}
}

View File

@ -0,0 +1,122 @@
/*
* libretroshare/src/pqi pqiperson.h
*
* 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 PQIPERSON_H
#define PQIPERSON_H
#include "_pqi/pqipersongrp.h"
#include "_pqi/pqi.h"
#include "_util/rsdebug.h"
#include <sstream>
#include <list>
class pqiperson;
static const int CONNECT_RECEIVED = 1;
static const int CONNECT_SUCCESS = 2;
static const int CONNECT_UNREACHABLE = 3;
static const int CONNECT_FIREWALLED = 4;
static const int CONNECT_FAILED = 5;
#include "pqi/pqistreamer.h"
class pqiconnect: public pqistreamer, public NetInterface
{
public:
pqiconnect(RsSerialiser *rss, NetBinInterface *ni_in);
virtual ~pqiconnect() { return; }
// presents a virtual NetInterface -> passes to ni.
virtual int connect(struct sockaddr_in raddr);
virtual int listen();
virtual int stoplistening();
virtual int reset();
virtual int disconnect();
virtual bool connect_parameter(uint32_t type, uint32_t value);
// get the contact from the net side!
virtual std::string PeerId();
// to check if our interface.
virtual bool thisNetInterface(NetInterface *ni_in);
//protected:
NetBinInterface *ni;
protected:
};
class pqipersongrp;
class pqiperson: public PQInterface
{
public:
pqiperson(std::string id, pqipersongrp *ppg);
virtual ~pqiperson(); // must clean up children.
// control of the connection.
int reset();
int listen();
int stoplistening();
int connect(uint32_t type, struct sockaddr_in raddr, uint32_t delay, uint32_t period, uint32_t timeout);
// add in connection method.
int addChildInterface(uint32_t type, pqiconnect *pqi);
// The PQInterface interface.
virtual int SendItem(RsItem *);
virtual RsItem *GetItem();
virtual int status();
virtual int tick();
// overloaded callback function for the child - notify of a change.
int notifyEvent(NetInterface *ni, int event);
// PQInterface for rate control overloaded....
virtual float getRate(bool in);
virtual void setMaxRate(bool in, float val);
private:
std::map<uint32_t, pqiconnect *> kids;
bool active;
pqiconnect *activepqi;
bool inConnectAttempt;
int waittimes;
private: /* Helper functions */
pqipersongrp *pqipg; /* parent for callback */
};
#endif // PQIPERSON_H

View File

@ -0,0 +1,508 @@
/*
* libretroshare/src/pqi: pqipersongrp.cc
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-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 "_pqi/pqipersongrp.h"
#include <sstream>
#include <stdio.h>
const int pqipersongrpzone = 354;
/****
*#define PGRP_DEBUG 1
****/
/* MUTEX NOTES:
* Functions like GetRsRawItem() lock itself (pqihandler) and
* likewise ServiceServer and ConfigMgr mutex themselves.
* This means the only things we need to worry about are:
* pqilistener and when accessing pqihandlers data.
*/
// handle the tunnel services.
int pqipersongrp::tickServiceRecv()
{
RsRawItem *pqi = NULL;
int i = 0;
{
std::ostringstream out;
out << "pqipersongrp::tickTunnelServer()";
pqioutput(PQL_DEBUG_ALL, pqipersongrpzone, out.str());
}
//p3ServiceServer::tick();
while(NULL != (pqi = GetRsRawItem()))
{
++i;
pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone,
"pqipersongrp::tickTunnelServer() Incoming TunnelItem");
incoming(pqi);
}
if (0 < i)
{
return 1;
}
return 0;
}
// handle the tunnel services.
int pqipersongrp::tickServiceSend()
{
RsRawItem *pqi = NULL;
int i = 0;
{
std::ostringstream out;
out << "pqipersongrp::tickServiceSend()";
pqioutput(PQL_DEBUG_ALL, pqipersongrpzone, out.str());
}
p3ServiceServer::tick();
while(NULL != (pqi = outgoing())) /* outgoing has own locking */
{
++i;
pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone,
"pqipersongrp::tickTunnelServer() OutGoing RsItem");
SendRsRawItem(pqi); /* Locked by pqihandler */
}
if (0 < i)
{
return 1;
}
return 0;
}
// init
pqipersongrp::pqipersongrp(SecurityPolicy *glob, unsigned long flags)
:pqihandler(glob), pqil(NULL), config(NULL), initFlags(flags)
{
}
int pqipersongrp::tick()
{
/* could limit the ticking of listener / tunnels to 1/sec...
* but not to important.
*/
{ RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (pqil)
{
pqil -> tick();
}
} /* UNLOCKED */
int i = 0;
if (tickServiceSend())
{
i = 1;
#ifdef PGRP_DEBUG
std::cerr << "pqipersongrp::tick() moreToTick from tickServiceSend()" << std::endl;
#endif
}
if (pqihandler::tick()) /* does actual Send/Recv */
{
i = 1;
#ifdef PGRP_DEBUG
std::cerr << "pqipersongrp::tick() moreToTick from pqihandler::tick()" << std::endl;
#endif
}
if (tickServiceRecv())
{
i = 1;
#ifdef PGRP_DEBUG
std::cerr << "pqipersongrp::tick() moreToTick from tickServiceRecv()" << std::endl;
#endif
}
return i;
}
int pqipersongrp::status()
{
{ RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (pqil)
{
pqil -> status();
}
} /* UNLOCKED */
return pqihandler::status();
}
/* Initialise pqilistener */
int pqipersongrp::init_listener()
{
/* extract our information from the p3ConnectMgr */
if (initFlags & PQIPERSON_NO_LISTENER)
{
pqil = NULL;
}
else
{
/* extract details from
*/
peerConnectState state;
mConnMgr->getOwnNetStatus(state);
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
pqil = createListener(state.localaddr);
}
return 1;
}
int pqipersongrp::restart_listener()
{
// stop it,
// change the address.
// restart.
bool haveListener = false;
{ RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
haveListener = (pqil != NULL);
} /* UNLOCKED */
if (haveListener)
{
peerConnectState state;
mConnMgr->getOwnNetStatus(state);
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
pqil -> resetlisten();
pqil -> setListenAddr(state.localaddr);
pqil -> setuplisten();
}
return 1;
}
/* NOT bothering to protect Config with a mutex.... it is not going to change
* and has its own internal mutexs.
*/
int pqipersongrp::setConfig(p3GeneralConfig *cfg)
{
config = cfg;
return 1;
}
static const std::string pqih_ftr("PQIH_FTR");
int pqipersongrp::save_config()
{
char line[512];
sprintf(line, "%f %f", getMaxRate(true), getMaxRate(false));
if (config)
{
config -> setSetting(pqih_ftr, std::string(line));
}
return 1;
}
int pqipersongrp::load_config()
{
std::string line;
if (config)
{
line = config -> getSetting(pqih_ftr);
}
float mri, mro;
if (2 == sscanf(line.c_str(), "%f %f", &mri, &mro))
{
setMaxRate(true, mri);
setMaxRate(false, mro);
}
else
{
pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone,
"pqipersongrp::load_config() Loading Default Rates!");
setMaxRate(true, 500.0);
setMaxRate(false, 500.0);
}
return 1;
}
void pqipersongrp::statusChange(const std::list<pqipeer> &plist)
{
/* iterate through, only worry about the friends */
std::list<pqipeer>::const_iterator it;
for(it = plist.begin(); it != plist.end(); it++)
{
if (it->state & RS_PEER_S_FRIEND)
{
/* now handle add/remove */
if ((it->actions & RS_PEER_NEW)
|| (it->actions & RS_PEER_MOVED))
{
addPeer(it->id);
}
if (it->actions & RS_PEER_CONNECT_REQ)
{
connectPeer(it->id);
}
}
else /* Not Friend */
{
if (it->actions & RS_PEER_MOVED)
{
removePeer(it->id);
}
}
}
}
int pqipersongrp::addPeer(std::string id)
{
{
std::ostringstream out;
out << "pqipersongrp::addPeer() PeerId: " << id;
pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone, out.str());
}
#ifdef PGRP_DEBUG
std::cerr << " pqipersongrp::addPeer() id: " << id;
std::cerr << std::endl;
#endif
SearchModule *sm = NULL;
{ RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
std::map<std::string, SearchModule *>::iterator it;
it = mods.find(id);
if (it != mods.end())
{
pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone,
"pqipersongrp::addPeer() Peer already in Use!");
return -1;
}
pqiperson *pqip = createPerson(id, pqil);
// attach to pqihandler
sm = new SearchModule();
sm -> peerid = id;
sm -> pqi = pqip;
sm -> sp = secpolicy_create();
// reset it to start it working.
pqip -> reset();
pqip -> listen();
} /* UNLOCKED */
return AddSearchModule(sm);
}
int pqipersongrp::removePeer(std::string id)
{
std::map<std::string, SearchModule *>::iterator it;
#ifdef PGRP_DEBUG
std::cerr << " pqipersongrp::removePeer() id: " << id;
std::cerr << std::endl;
#endif
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
it = mods.find(id);
if (it != mods.end())
{
SearchModule *mod = it->second;
// Don't duplicate remove!!!
//RemoveSearchModule(mod);
secpolicy_delete(mod -> sp);
pqiperson *p = (pqiperson *) mod -> pqi;
p -> reset();
delete p;
mods.erase(it);
}
return 1;
}
int pqipersongrp::connectPeer(std::string id)
{
/* get status from p3connectMgr */
#ifdef PGRP_DEBUG
std::cerr << " pqipersongrp::connectPeer() id: " << id << " does nothing yet! ";
std::cerr << std::endl;
#endif
{ RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
std::map<std::string, SearchModule *>::iterator it;
it = mods.find(id);
if (it == mods.end())
{
return 0;
}
/* get the connect attempt details from the p3connmgr... */
SearchModule *mod = it->second;
pqiperson *p = (pqiperson *) mod -> pqi;
/* get address from p3connmgr */
if (!mConnMgr)
return 0;
struct sockaddr_in addr;
uint32_t delay;
uint32_t period;
uint32_t timeout;
uint32_t type;
if (!mConnMgr->connectAttempt(id, addr, delay, period, type))
{
#ifdef PGRP_DEBUG
std::cerr << " pqipersongrp::connectPeer() No Net Address";
std::cerr << std::endl;
#endif
return 0;
}
#ifdef PGRP_DEBUG
std::cerr << " pqipersongrp::connectPeer() connectAttempt data id: " << id;
std::cerr << " addr: " << inet_ntoa(addr.sin_addr) << ":" << ntohs(addr.sin_port);
std::cerr << " delay: " << delay;
std::cerr << " period: " << period;
std::cerr << " type: " << type;
std::cerr << std::endl;
#endif
uint32_t ptype;
if (type & RS_NET_CONN_TCP_ALL)
{
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;
#endif
}
else if (type & RS_NET_CONN_UDP_ALL)
{
ptype = PQI_CONNECT_UDP;
timeout = period * 2;
#ifdef PGRP_DEBUG
std::cerr << " pqipersongrp::connectPeer() connecting with UDP: Timeout :" << timeout;
std::cerr << std::endl;
#endif
}
else
return 0;
p->connect(ptype, addr, delay, period, timeout);
} /* UNLOCKED */
/* */
return 1;
}
bool pqipersongrp::notifyConnect(std::string id, uint32_t ptype, bool success)
{
uint32_t type = 0;
if (ptype == PQI_CONNECT_TCP)
{
type = RS_NET_CONN_TCP_ALL;
}
else
{
type = RS_NET_CONN_UDP_ALL;
}
if (mConnMgr)
mConnMgr->connectResult(id, success, type);
return (NULL != mConnMgr);
}
/******************************** DUMMY Specific features ***************************/
#include "pqi/pqibin.h"
pqilistener * pqipersongrpDummy::createListener(struct sockaddr_in laddr)
{
pqilistener *listener = new pqilistener();
return listener;
}
pqiperson * pqipersongrpDummy::createPerson(std::string id, pqilistener *listener)
{
{
std::ostringstream out;
out << "pqipersongrpDummy::createPerson() PeerId: " << id;
pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone, out.str());
}
pqiperson *pqip = new pqiperson(id, this);
// TCP
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);
pqip -> addChildInterface(PQI_CONNECT_TCP, pqic);
// UDP.
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);
pqip -> addChildInterface(PQI_CONNECT_UDP, pqic2);
return pqip;
}
/******************************** DUMMY Specific features ***************************/

View File

@ -0,0 +1,117 @@
/*
* libretroshare/src/pqi: pqipersongrp.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-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".
*
*/
#ifndef PQIPERSONGRP_H
#define PQIPERSONGRP_H
#include "pqi/pqihandler.h"
#include "pqi/pqiperson.h"
#include "pqi/pqilistener.h"
#include "pqi/pqiservice.h"
#include "pqi/pqimonitor.h"
#include "pqi/p3cfgmgr.h"
// So this is a specific implementation
//
// it is designed to have one pqilistensocket + a series of pqisockets
//
// as an added bonus, we are going to
// make this a pqitunnelserver, to which services can be attached.
const unsigned long PQIPERSON_NO_LISTENER = 0x0001;
const unsigned long PQIPERSON_ALL_BW_LIMITED = 0x0010;
class pqipersongrp: public pqihandler, public pqiMonitor, public p3ServiceServer
{
public:
pqipersongrp(SecurityPolicy *, unsigned long flags);
/*************************** Setup *************************/
/* pqilistener */
int init_listener();
int restart_listener();
int setConfig(p3GeneralConfig *cfg);
int save_config();
int load_config();
/*************** pqiMonitor callback ***********************/
virtual void statusChange(const std::list<pqipeer> &plist);
/******************* Peer Control **************************/
virtual int addPeer(std::string id); /* can be overloaded for testing */
int removePeer(std::string id);
int connectPeer(std::string id);
/*** callback from children ****/
bool notifyConnect(std::string id, uint32_t type, bool success);
// tick interfaces.
virtual int tick();
virtual int status();
protected:
/********* FUNCTIONS to OVERLOAD for specialisation ********/
virtual pqilistener *createListener(struct sockaddr_in laddr) = 0;
virtual pqiperson *createPerson(std::string id, pqilistener *listener) = 0;
/********* FUNCTIONS to OVERLOAD for specialisation ********/
/* Overloaded RsItem Check
* checks item->cid vs Person
*/
virtual int checkOutgoingRsItem(RsItem *item, int global) { (void)item; (void)global; return 1; }
private:
// The tunnelserver operation.
int tickServiceRecv();
int tickServiceSend();
pqilistener *pqil;
p3GeneralConfig *config;
unsigned long initFlags;
};
class pqipersongrpDummy: public pqipersongrp
{
public:
pqipersongrpDummy(SecurityPolicy *pol, unsigned long flags)
:pqipersongrp(pol, flags) { return; }
protected:
/********* FUNCTIONS to OVERLOAD for specialisation ********/
virtual pqilistener *createListener(struct sockaddr_in laddr);
virtual pqiperson *createPerson(std::string id, pqilistener *listener);
/********* FUNCTIONS to OVERLOAD for specialisation ********/
};
#endif // PQIPERSONGRP_H

View File

@ -0,0 +1,74 @@
/*
* "$Id: pqisecurity.cc,v 1.3 2007-02-18 21:46:49 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".
*
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "_pqi/pqisecurity.h"
#include <stdlib.h> // malloc
// Can keep the structure hidden....
// but won't at the moment.
// functions for checking what is allowed...
// currently these are all dummies.
std::string secpolicy_print(SecurityPolicy *)
{
return std::string("secpolicy_print() Implement Me Please!");
}
SecurityPolicy *secpolicy_create()
{
return (SecurityPolicy *) malloc(sizeof(SecurityPolicy));
}
int secpolicy_delete(SecurityPolicy *p)
{
free(p);
return 1;
}
int secpolicy_limit(SecurityPolicy *limiter,
SecurityPolicy *alter)
{
return 1;
}
int secpolicy_check(SecurityPolicy *, int type_transaction,
int direction)
{
return 1;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,59 @@
/*
* "$Id: pqisecurity.h,v 1.3 2007-02-18 21:46:49 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 PQISECURITY_H
#define PQISECURITY_H
#define PQI_INCOMING 2
#define PQI_OUTGOING 5
#ifdef __cplusplus
extern "C" {
#endif
//structure.
typedef struct sec_policy
{
int searchable; // flags indicate how searchable we are..
} SecurityPolicy;
// functions for checking what is allowed...
//
std::string secpolicy_print(SecurityPolicy *);
SecurityPolicy *secpolicy_create();
int secpolicy_delete(SecurityPolicy *);
int secpolicy_limit(SecurityPolicy *limiter, SecurityPolicy *alter);
int secpolicy_check(SecurityPolicy *, int type_transaction,
int direction);
#ifdef __cplusplus
}
#endif
#endif // PQISECURITY_H

View File

@ -0,0 +1,223 @@
/*
* libretroshare/src/pqi pqiservice.cc
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-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 "pqi/pqiservice.h"
#include <sstream>
const int pqiservicezone = 60478;
/****
* #define SERVICE_DEBUG 1
****/
p3ServiceServer::p3ServiceServer()
{
RsStackMutex stack(srvMtx); /********* LOCKED *********/
#ifdef SERVICE_DEBUG
pqioutput(PQL_DEBUG_BASIC, pqiservicezone,
"p3ServiceServer::p3ServiceServer()");
#endif
rrit = services.begin();
return;
}
int p3ServiceServer::addService(pqiService *ts)
{
RsStackMutex stack(srvMtx); /********* LOCKED *********/
#ifdef SERVICE_DEBUG
pqioutput(PQL_DEBUG_BASIC, pqiservicezone,
"p3ServiceServer::addService()");
#endif
std::map<uint32_t, pqiService *>::iterator it;
it = services.find(ts -> getType());
if (it != services.end())
{
// it exists already!
return -1;
}
services[ts -> getType()] = ts;
rrit = services.begin();
return 1;
}
int p3ServiceServer::incoming(RsRawItem *item)
{
RsStackMutex stack(srvMtx); /********* LOCKED *********/
#ifdef SERVICE_DEBUG
pqioutput(PQL_DEBUG_BASIC, pqiservicezone,
"p3ServiceServer::incoming()");
{
std::ostringstream out;
out << "p3ServiceServer::incoming() PacketId: ";
out << std::hex << item -> PacketId() << std::endl;
out << "Looking for Service: ";
out << (item -> PacketId() & 0xffffff00) << std::dec << std::endl;
out << "Item:" << std::endl;
item -> print(out);
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqiservicezone, out.str());
}
#endif
std::map<uint32_t, pqiService *>::iterator it;
it = services.find(item -> PacketId() & 0xffffff00);
if (it == services.end())
{
#ifdef SERVICE_DEBUG
pqioutput(PQL_DEBUG_BASIC, pqiservicezone,
"p3ServiceServer::incoming() Service: No Service - deleting");
#endif
// delete it.
delete item;
// it exists already!
return -1;
}
{
#ifdef SERVICE_DEBUG
std::ostringstream out;
out << "p3ServiceServer::incoming() Sending to";
out << it -> second << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqiservicezone, out.str());
#endif
return (it->second) -> receive(item);
}
delete item;
return -1;
}
RsRawItem *p3ServiceServer::outgoing()
{
RsStackMutex stack(srvMtx); /********* LOCKED *********/
#ifdef SERVICE_DEBUG
pqioutput(PQL_DEBUG_ALL, pqiservicezone,
"p3ServiceServer::outgoing()");
#endif
if (rrit != services.end())
{
rrit++;
}
else
{
rrit = services.begin();
}
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::ostringstream out;
out << "p3ServiceServer::outgoing() Got Item From:";
out << rrit -> second << std::endl;
item -> print(out);
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqiservicezone, out.str());
#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::ostringstream out;
out << "p3ServiceServer::outgoing() Got Item From:";
out << rrit -> second << std::endl;
item -> print(out);
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqiservicezone, out.str());
#endif
return item;
}
}
return NULL;
}
int p3ServiceServer::tick()
{
RsStackMutex stack(srvMtx); /********* LOCKED *********/
#ifdef SERVICE_DEBUG
pqioutput(PQL_DEBUG_ALL, pqiservicezone,
"p3ServiceServer::tick()");
#endif
std::map<uint32_t, pqiService *>::iterator it;
// from the beginning to where we started.
for(it = services.begin();it != services.end(); it++)
{
#ifdef SERVICE_DEBUG
std::ostringstream out;
out << "p3ServiceServer::service id:" << it -> first;
out << " -> Service: " << it -> second;
out << std::endl;
pqioutput(PQL_DEBUG_ALL, pqiservicezone, out.str());
#endif
// now we should actually tick the service.
(it -> second) -> tick();
}
return 1;
}

View File

@ -0,0 +1,101 @@
/*
* libretroshare/src/pqi pqiservice.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-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".
*
*/
#ifndef PQISERVICE_H
#define PQISERVICE_H
#include "_pqi/pqi_base.h"
#include "_util/rsthreads.h"
#include "_util/rsdebug.h"
// PQI Service, is a generic lower layer on which services can run on.
//
// these packets get passed through the
// server, to a service that is registered.
//
// example services:
// proxytunnel. -> p3proxy.
// sockettunnel
// -> either broadcast (attach to
// open socket instead
// of broadcast address)
// -> or requested/signon.
//
// games,
// voice
// video
//
//
// DataType is defined in the serialiser directory.
class RsRawItem;
class pqiService
{
protected:
pqiService(uint32_t t) // our type of packets.
:type(t) { return; }
virtual ~pqiService() { return; }
public:
//
virtual int receive(RsRawItem *) = 0;
virtual RsRawItem * send() = 0;
uint32_t getType() { return type; }
virtual int tick() { return 0; }
private:
uint32_t type;
};
#include <map>
class p3ServiceServer
{
public:
p3ServiceServer();
int addService(pqiService *);
int incoming(RsRawItem *);
RsRawItem *outgoing();
int tick();
private:
RsMutex srvMtx;
std::map<uint32_t, pqiService *> services;
std::map<uint32_t, pqiService *>::iterator rrit;
};
#endif // PQISERVICE_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,230 @@
/*
* "$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 PQISSL_H
#define PQISSL_H
#include <openssl/ssl.h>
// operating system specific network header.
#include "pqi/pqinetwork.h"
#include <string>
#include <map>
#include "_pqi/pqi_base.h"
#include "_pqi/p3connmgr.h"
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
#include "pqi/authxpgp.h"
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#include "pqi/authssl.h"
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#define WAITING_NOT 0
#define WAITING_DELAY 1
#define WAITING_SOCK_CONNECT 2
#define WAITING_SSL_CONNECTION 3
#define WAITING_SSL_AUTHORISE 4
#define WAITING_FAIL_INTERFACE 5
#define PQISSL_PASSIVE 0x00
#define PQISSL_ACTIVE 0x01
const int PQISSL_LOCAL_FLAG = 0x01;
const int PQISSL_REMOTE_FLAG = 0x02;
const int PQISSL_DNS_FLAG = 0x04;
/* not sure about the value? */
const int PQISSL_UDP_FLAG = 0x02;
/***************************** 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 pqissllistener;
class pqissl: public NetBinInterface
{
public:
pqissl(pqissllistener *l, PQInterface *parent,
p3AuthMgr *am, p3ConnectMgr *cm);
virtual ~pqissl();
// NetInterface
virtual int connect(struct sockaddr_in raddr);
virtual int listen();
virtual int stoplistening();
virtual int reset();
virtual int disconnect();
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();
protected:
// A little bit of information to describe
// the SSL state, this is needed
// to allow full Non-Blocking Connect behaviour.
// This fn loops through the following fns.
// to complete an SSL.
int ConnectAttempt();
int waiting;
virtual int Failed_Connection();
// Start up connection with delay...
virtual int Delay_Connection();
// These two fns are overloaded for udp/etc connections.
virtual int Initiate_Connection();
virtual int Basic_Connection_Complete();
// These should be identical for all cases,
// differences are achieved via the net_internal_* fns.
int Initiate_SSL_Connection();
int SSL_Connection_Complete();
int Authorise_SSL_Connection();
int Extract_Failed_SSL_Certificate(); // try to get cert anyway.
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, struct sockaddr_in foreign_addr);
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);}
/* data */
bool active;
bool certvalid;
// addition for udp (tcp version == ACTIVE).
int sslmode;
SSL *ssl_connection;
int sockfd;
pqissllistener *pqil;
struct sockaddr_in remote_addr;
void *readpkt;
int pktlen;
int attempt_ts;
// Some flags to indicate
// the status of the various interfaces
// (local), (server)
unsigned int net_attempt;
unsigned int net_failure;
unsigned int net_unreachable;
bool sameLAN; /* flag use to allow high-speed transfers */
int n_read_zero; /* a counter to determine if the connection is really dead */
int ssl_connect_timeout; /* timeout to ensure that we don't get stuck (can happen on udp!) */
uint32_t mConnectDelay;
time_t mConnectTS;
uint32_t mConnectTimeout;
time_t mTimeoutTS;
/* Need Certificate specific functions here! */
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
AuthXPGP *mAuthMgr;
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
AuthSSL *mAuthMgr;
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
p3ConnectMgr *mConnMgr;
private:
// ssl only fns.
int connectInterface(sockaddr_in&);
};
#endif // PQISSL_H

View File

@ -0,0 +1,733 @@
/*
* "$Id: pqissllistener.cc,v 1.3 2007-02-18 21:46:49 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/pqissl.h"
#include "_pqi/pqissllistener.h"
#include "_pqi/pqinetwork.h"
#include <errno.h>
#include <openssl/err.h>
#include "_util/rsdebug.h"
#include <sstream>
const int pqissllistenzone = 49787;
/************************ PQI SSL LISTEN BASE ****************************
*
* This provides all of the basic connection stuff,
* and calls completeConnection afterwards...
*
*/
pqissllistenbase::pqissllistenbase(struct sockaddr_in addr, p3AuthMgr *am, p3ConnectMgr *cm)
:laddr(addr), active(false),
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
mAuthMgr((AuthXPGP *) am), mConnMgr(cm)
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
mAuthMgr((AuthSSL *) am), mConnMgr(cm)
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
{
if (!(mAuthMgr -> active()))
{
pqioutput(PQL_ALERT, pqissllistenzone,
"SSL-CTX-CERT-ROOT not initialised!");
exit(1);
}
setuplisten();
return;
}
pqissllistenbase::~pqissllistenbase()
{
return;
}
int pqissllistenbase::tick()
{
status();
// check listen port.
acceptconnection();
return continueaccepts();
}
int pqissllistenbase::status()
{
std::ostringstream out;
out << "pqissllistenbase::status(): ";
out << " Listening on port: " << ntohs(laddr.sin_port) << std::endl;
pqioutput(PQL_DEBUG_ALL, pqissllistenzone, out.str());
return 1;
}
int pqissllistenbase::setuplisten()
{
int err;
if (active)
return -1;
lsock = socket(PF_INET, SOCK_STREAM, 0);
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS // ie UNIX
if (lsock < 0)
{
pqioutput(PQL_ALERT, pqissllistenzone,
"pqissllistenbase::setuplisten() Cannot Open Socket!");
return -1;
}
err = fcntl(lsock, F_SETFL, O_NONBLOCK);
if (err < 0)
{
std::ostringstream out;
out << "Error: Cannot make socket NON-Blocking: ";
out << err << std::endl;
pqioutput(PQL_ERROR, pqissllistenzone, out.str());
return -1;
}
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#else //WINDOWS_SYS
if ((unsigned) lsock == INVALID_SOCKET)
{
std::ostringstream out;
out << "pqissllistenbase::setuplisten()";
out << " Cannot Open Socket!" << std::endl;
out << "Socket Error:";
out << socket_errorType(WSAGetLastError()) << std::endl;
pqioutput(PQL_ALERT, pqissllistenzone, out.str());
return -1;
}
// Make nonblocking.
unsigned long int on = 1;
if (0 != (err = ioctlsocket(lsock, FIONBIO, &on)))
{
std::ostringstream out;
out << "pqissllistenbase::setuplisten()";
out << "Error: Cannot make socket NON-Blocking: ";
out << err << std::endl;
out << "Socket Error:";
out << socket_errorType(WSAGetLastError()) << std::endl;
pqioutput(PQL_ALERT, pqissllistenzone, out.str());
return -1;
}
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
// setup listening address.
// fill in fconstant bits.
laddr.sin_family = AF_INET;
{
std::ostringstream out;
out << "pqissllistenbase::setuplisten()";
out << "\tAddress Family: " << (int) laddr.sin_family;
out << std::endl;
out << "\tSetup Address: " << inet_ntoa(laddr.sin_addr);
out << std::endl;
out << "\tSetup Port: " << ntohs(laddr.sin_port);
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out.str());
}
if (0 != (err = bind(lsock, (struct sockaddr *) &laddr, sizeof(laddr))))
{
std::ostringstream out;
out << "pqissllistenbase::setuplisten()";
out << " Cannot Bind to Local Address!" << std::endl;
showSocketError(out);
pqioutput(PQL_ALERT, pqissllistenzone, out.str());
exit(1);
return -1;
}
else
{
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone,
"pqissllistenbase::setuplisten() Bound to Address.");
}
if (0 != (err = listen(lsock, 100)))
{
std::ostringstream out;
out << "pqissllistenbase::setuplisten()";
out << "Error: Cannot Listen to Socket: ";
out << err << std::endl;
showSocketError(out);
pqioutput(PQL_ALERT, pqissllistenzone, out.str());
exit(1);
return -1;
}
else
{
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone,
"pqissllistenbase::setuplisten() Listening to Socket");
}
active = true;
return 1;
}
int pqissllistenbase::setListenAddr(struct sockaddr_in addr)
{
laddr = addr;
return 1;
}
int pqissllistenbase::resetlisten()
{
if (active)
{
// close ports etc.
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS // ie UNIX
shutdown(lsock, SHUT_RDWR);
close(lsock);
#else //WINDOWS_SYS
closesocket(lsock);
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
active = false;
return 1;
}
return 0;
}
int pqissllistenbase::acceptconnection()
{
if (!active)
return 0;
// check port for any socets...
pqioutput(PQL_DEBUG_ALL, pqissllistenzone, "pqissllistenbase::accepting()");
// These are local but temp variables...
// can't be arsed making them all the time.
struct sockaddr_in remote_addr;
socklen_t addrlen = sizeof(remote_addr);
int fd = accept(lsock, (struct sockaddr *) &remote_addr, &addrlen);
int err = 0;
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS // ie UNIX
if (fd < 0)
{
pqioutput(PQL_DEBUG_ALL, pqissllistenzone,
"pqissllistenbase::acceptconnnection() Nothing to Accept!");
return 0;
}
err = fcntl(fd, F_SETFL, O_NONBLOCK);
if (err < 0)
{
std::ostringstream out;
out << "pqissllistenbase::acceptconnection()";
out << "Error: Cannot make socket NON-Blocking: ";
out << err << std::endl;
pqioutput(PQL_ERROR, pqissllistenzone, out.str());
close(fd);
return -1;
}
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#else //WINDOWS_SYS
if ((unsigned) fd == INVALID_SOCKET)
{
pqioutput(PQL_DEBUG_ALL, pqissllistenzone,
"pqissllistenbase::acceptconnnection() Nothing to Accept!");
return 0;
}
// Make nonblocking.
unsigned long int on = 1;
if (0 != (err = ioctlsocket(fd, FIONBIO, &on)))
{
std::ostringstream out;
out << "pqissllistenbase::acceptconnection()";
out << "Error: Cannot make socket NON-Blocking: ";
out << err << std::endl;
out << "Socket Error:";
out << socket_errorType(WSAGetLastError()) << std::endl;
pqioutput(PQL_ALERT, pqissllistenzone, out.str());
closesocket(fd);
return 0;
}
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
{
std::ostringstream out;
out << "Accepted Connection from ";
out << inet_ntoa(remote_addr.sin_addr) << ":" << ntohs(remote_addr.sin_port);
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out.str());
}
// Negotiate certificates. SSL stylee.
// Allow negotiations for secure transaction.
SSL *ssl = SSL_new(mAuthMgr -> getCTX());
SSL_set_fd(ssl, fd);
return continueSSL(ssl, remote_addr, true); // continue and save if incomplete.
}
int pqissllistenbase::continueSSL(SSL *ssl, struct sockaddr_in remote_addr, bool addin)
{
// attempt the accept again.
int fd = SSL_get_fd(ssl);
int err = SSL_accept(ssl);
if (err <= 0)
{
int ssl_err = SSL_get_error(ssl, err);
int err_err = ERR_get_error();
{
std::ostringstream out;
out << "pqissllistenbase::continueSSL() ";
out << "Issues with SSL Accept(" << err << ")!" << std::endl;
printSSLError(ssl, err, ssl_err, err_err, out);
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out.str());
}
if ((ssl_err == SSL_ERROR_WANT_READ) ||
(ssl_err == SSL_ERROR_WANT_WRITE))
{
std::ostringstream out;
out << "pqissllistenbase::continueSSL() ";
out << " Connection Not Complete!";
out << std::endl;
if (addin)
{
out << "pqissllistenbase::continueSSL() ";
out << "Adding SSL to incoming!";
// add to incomingqueue.
incoming_ssl[ssl] = remote_addr;
}
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out.str());
// zero means still continuing....
return 0;
}
/* we have failed -> get certificate if possible */
Extract_Failed_SSL_Certificate(ssl, &remote_addr);
// other wise delete ssl connection.
// kill connection....
// so it will be removed from cache.
SSL_shutdown(ssl);
// close socket???
/************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS // ie UNIX
shutdown(fd, SHUT_RDWR);
close(fd);
#else //WINDOWS_SYS
closesocket(fd);
#endif
/************************** WINDOWS/UNIX SPECIFIC PART ******************/
// free connection.
SSL_free(ssl);
std::ostringstream out;
out << "Read Error on the SSL Socket";
out << std::endl;
out << "Shutting it down!" << std::endl;
pqioutput(PQL_WARNING, pqissllistenzone, out.str());
// failure -1, pending 0, sucess 1.
return -1;
}
// if it succeeds
if (0 < completeConnection(fd, ssl, remote_addr))
{
return 1;
}
/* else we shut it down! */
pqioutput(PQL_WARNING, pqissllistenzone,
"pqissllistenbase::completeConnection() Failed!");
// delete ssl connection.
SSL_shutdown(ssl);
// close socket???
/************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS // ie UNIX
shutdown(fd, SHUT_RDWR);
close(fd);
#else //WINDOWS_SYS
closesocket(fd);
#endif
/************************** WINDOWS/UNIX SPECIFIC PART ******************/
// free connection.
SSL_free(ssl);
std::ostringstream out;
out << "Shutting it down!" << std::endl;
pqioutput(PQL_WARNING, pqissllistenzone, out.str());
// failure -1, pending 0, sucess 1.
return -1;
}
int pqissllistenbase::Extract_Failed_SSL_Certificate(SSL *ssl, struct sockaddr_in *inaddr)
{
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone,
"pqissllistenbase::Extract_Failed_SSL_Certificate()");
// Get the Peer Certificate....
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
XPGP *peercert = SSL_get_peer_pgp_certificate(ssl);
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
X509 *peercert = SSL_get_peer_certificate(ssl);
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
if (peercert == NULL)
{
pqioutput(PQL_WARNING, pqissllistenzone,
"pqissllistenbase::Extract_Failed_SSL_Certificate() Peer Didnt Give Cert");
return -1;
}
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone,
"pqissllistenbase::Extract_Failed_SSL_Certificate() Have Peer Cert - Registering");
// save certificate... (and ip locations)
// false for outgoing....
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
mAuthMgr->FailedCertificateXPGP(peercert, true);
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
mAuthMgr->FailedCertificate(peercert, true);
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
return 1;
}
int pqissllistenbase::continueaccepts()
{
// for each of the incoming sockets.... call continue.
std::map<SSL *, struct sockaddr_in>::iterator it, itd;
for(it = incoming_ssl.begin(); it != incoming_ssl.end();)
{
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone,
"pqissllistenbase::continueaccepts() Continuing SSL");
if (0 != continueSSL(it->first, it->second, false))
{
pqioutput(PQL_DEBUG_ALERT, pqissllistenzone,
"pqissllistenbase::continueaccepts() SSL Complete/Dead!");
/* save and increment -> so we can delete */
itd = it++;
incoming_ssl.erase(itd);
}
else
{
it++;
}
}
return 1;
}
/************************ PQI SSL LISTENER ****************************
*
* This is the standard pqissl listener interface....
*
* this class only allows connections from
* specific certificates, which are pre specified.
*
*/
pqissllistener::pqissllistener(struct sockaddr_in addr, p3AuthMgr *am, p3ConnectMgr *cm)
:pqissllistenbase(addr, am, cm)
{
return;
}
pqissllistener::~pqissllistener()
{
return;
}
int pqissllistener::addlistenaddr(std::string id, pqissl *acc)
{
std::map<std::string, pqissl *>::iterator it;
std::ostringstream out;
out << "Adding to Cert Listening Addresses Id: " << id << std::endl;
out << "Current Certs:" << std::endl;
for(it = listenaddr.begin(); it != listenaddr.end(); it++)
{
out << id << std::endl;
if (it -> first == id)
{
out << "pqissllistener::addlistenaddr()";
out << "Already listening for Certificate!";
out << std::endl;
pqioutput(PQL_DEBUG_ALERT, pqissllistenzone, out.str());
return -1;
}
}
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out.str());
// not there can accept it!
listenaddr[id] = acc;
return 1;
}
int pqissllistener::removeListenPort(std::string id)
{
// check where the connection is coming from.
// if in list of acceptable addresses,
//
// check if in list.
std::map<std::string, pqissl *>::iterator it;
for(it = listenaddr.begin();it!=listenaddr.end();it++)
{
if (it->first == id)
{
listenaddr.erase(it);
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone,
"pqissllisten::removeListenPort() Success!");
return 1;
}
}
pqioutput(PQL_WARNING, pqissllistenzone,
"pqissllistener::removeListenPort() Failed to Find a Match");
return -1;
}
int pqissllistener::status()
{
pqissllistenbase::status();
// print certificates we are listening for.
std::map<std::string, pqissl *>::iterator it;
std::ostringstream out;
out << "pqissllistener::status(): ";
out << " Listening (" << ntohs(laddr.sin_port) << ") for Certs:" << std::endl;
for(it = listenaddr.begin(); it != listenaddr.end(); it++)
{
out << it -> first << std::endl;
}
pqioutput(PQL_DEBUG_ALL, pqissllistenzone, out.str());
return 1;
}
int pqissllistener::completeConnection(int fd, SSL *ssl, struct sockaddr_in &remote_addr)
{
// Get the Peer Certificate....
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
XPGP *peercert = SSL_get_peer_pgp_certificate(ssl);
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
X509 *peercert = SSL_get_peer_certificate(ssl);
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
if (peercert == NULL)
{
pqioutput(PQL_WARNING, pqissllistenzone,
"pqissllistener::completeConnection() Peer Did Not Provide Cert!");
// failure -1, pending 0, sucess 1.
// pqissllistenbase will shutdown!
return -1;
}
// Check cert.
std::string newPeerId;
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
bool certOk = mAuthMgr->ValidateCertificateXPGP(peercert, newPeerId);
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
/****
* As the validation is actually done before this...
* we should only need to call CheckCertificate here!
****/
bool certOk = mAuthMgr->ValidateCertificate(peercert, newPeerId);
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
bool found = false;
std::map<std::string, pqissl *>::iterator it;
// Let connected one through as well! if ((npc == NULL) || (npc -> Connected()))
if (!certOk)
{
pqioutput(PQL_WARNING, pqissllistenzone,
"pqissllistener::completeConnection() registerCertificate Failed!");
// bad - shutdown.
// pqissllistenbase will shutdown!
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
XPGP_free(peercert);
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
X509_free(peercert);
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
return -1;
}
else
{
std::ostringstream out;
out << "pqissllistener::continueSSL()" << std::endl;
out << "checking: " << newPeerId << std::endl;
// check if cert is in our list.....
for(it = listenaddr.begin();(found!=true) && (it!=listenaddr.end());)
{
out << "\tagainst: " << it->first << std::endl;
if (it -> first == newPeerId)
{
out << "\t\tMatch!";
found = true;
}
else
{
it++;
}
}
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out.str());
}
if (found == false)
{
std::ostringstream out;
out << "No Matching Certificate/Already Connected";
out << " for Connection:" << inet_ntoa(remote_addr.sin_addr);
out << std::endl;
out << "pqissllistenbase: Will shut it down!" << std::endl;
pqioutput(PQL_WARNING, pqissllistenzone, out.str());
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
XPGP_free(peercert);
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
X509_free(peercert);
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
return -1;
}
/* Certificate consumed! */
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
bool certKnown = mAuthMgr->CheckCertificateXPGP(it->first, peercert);
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
bool certKnown = mAuthMgr->CheckCertificate(it->first, peercert);
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
if (certKnown == false)
{
std::ostringstream out;
out << "Failed Final Check";
out << " for Connection:" << inet_ntoa(remote_addr.sin_addr);
out << std::endl;
out << "pqissllistenbase: Will shut it down!" << std::endl;
pqioutput(PQL_WARNING, pqissllistenzone, out.str());
return -1;
}
pqissl *pqis = it -> second;
// dont remove from the list of certificates.
// want to allow a new connection to replace a faulty one!
// listenaddr.erase(it);
// timestamp
// done in sslroot... npc -> lr_timestamp = time(NULL);
// hand off ssl conection.
pqis -> accept(ssl, fd, remote_addr);
return 1;
}

View File

@ -0,0 +1,131 @@
/*
* "$Id: pqissllistener.h,v 1.2 2007-02-18 21:46:49 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 PQISSLLISTENER_H
#define PQISSLLISTENER_H
#include <openssl/ssl.h>
// operating system specific network header.
#include "_pqi/pqinetwork.h"
#include <string>
#include <map>
#include "_pqi/pqi_base.h"
#include "_pqi/pqilistener.h"
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
#include "_pqi/authxpgp.h"
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#include "_pqi/authssl.h"
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
/***************************** pqi Net SSL Interface *********************************
*/
class pqissl;
class pqissllistenbase: public pqilistener
{
public:
pqissllistenbase(struct sockaddr_in addr, p3AuthMgr *am, p3ConnectMgr *cm);
virtual ~pqissllistenbase();
/*************************************/
/* LISTENER INTERFACE **/
virtual int tick();
virtual int status();
virtual int setListenAddr(struct sockaddr_in addr);
virtual int setuplisten();
virtual int resetlisten();
/*************************************/
int acceptconnection();
int continueaccepts();
int continueSSL(SSL *ssl, struct sockaddr_in remote_addr, bool);
virtual int completeConnection(int sockfd, SSL *in_connection, struct sockaddr_in &raddr) = 0;
protected:
struct sockaddr_in laddr;
private:
// fn to get cert, anyway
int Extract_Failed_SSL_Certificate(SSL *ssl, struct sockaddr_in *inaddr);
bool active;
int lsock;
std::map<SSL *, struct sockaddr_in> incoming_ssl;
protected:
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
AuthXPGP *mAuthMgr;
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
AuthSSL *mAuthMgr;
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
p3ConnectMgr *mConnMgr;
};
class pqissllistener: public pqissllistenbase
{
public:
pqissllistener(struct sockaddr_in addr, p3AuthMgr *am, p3ConnectMgr *cm);
virtual ~pqissllistener();
int addlistenaddr(std::string id, pqissl *acc);
int removeListenPort(std::string id);
//virtual int tick();
virtual int status();
virtual int completeConnection(int sockfd, SSL *in_connection, struct sockaddr_in &raddr);
private:
std::map<std::string, pqissl *> listenaddr;
};
#endif // PQISSLLISTENER_H

View File

@ -0,0 +1,105 @@
/*
* libretroshare/src/pqi: pqisslpersongrp.cc
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-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 <sstream>
#include "util/rsdebug.h"
#include "_pqi/pqisslpersongrp.h"
#include "_pqi/p3authmgr.h"
const int pqipersongrpzone = 354;
/****
* #define PQI_DISABLE_UDP 1
***/
/********************************** SSL Specific features ***************************/
#include "_pqi/pqissl.h"
#include "_pqi/pqissllistener.h"
#ifndef PQI_DISABLE_UDP
#include "_pqi/pqissludp.h"
#endif
pqilistener * pqisslpersongrp::createListener(struct sockaddr_in laddr)
{
p3AuthMgr *authMgr = getAuthMgr();
pqilistener *listener = new pqissllistener(laddr, authMgr, mConnMgr);
return listener;
}
pqiperson * pqisslpersongrp::createPerson(std::string id, pqilistener *listener)
{
{
std::ostringstream out;
out << "pqipersongrp::createPerson() PeerId: " << id;
pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone, out.str());
}
p3AuthMgr *authMgr = getAuthMgr();
pqiperson *pqip = new pqiperson(id, this);
pqissl *pqis = new pqissl((pqissllistener *) listener, pqip, authMgr, mConnMgr);
/* construct the serialiser ....
* Needs:
* * FileItem
* * FileData
* * ServiceGeneric
*/
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_UDP
pqissludp *pqius = new pqissludp(pqip, authMgr, mConnMgr);
RsSerialiser *rss2 = new RsSerialiser();
rss2->addSerialType(new RsFileItemSerialiser());
rss2->addSerialType(new RsCacheItemSerialiser());
rss2->addSerialType(new RsServiceSerialiser());
pqiconnect *pqiusc = new pqiconnect(rss2, pqius);
// add a ssl + proxy interface.
// Add Proxy First.
pqip -> addChildInterface(PQI_CONNECT_UDP, pqiusc);
#endif
return pqip;
}
/********************************** SSL Specific features ***************************/

View File

@ -0,0 +1,48 @@
/*
* libretroshare/src/pqi: pqisslpersongrp.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-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".
*
*/
#ifndef PQISSLPERSONGRP_H
#define PQISSLPERSONGRP_H
#include "pqi/pqipersongrp.h"
class pqisslpersongrp: public pqipersongrp
{
public:
pqisslpersongrp(SecurityPolicy *pol, unsigned long flags)
:pqipersongrp(pol, flags) { }
protected:
/********* FUNCTIONS to OVERLOAD for specialisation ********/
virtual pqilistener *createListener(struct sockaddr_in laddr);
virtual pqiperson *createPerson(std::string id, pqilistener *listener);
/********* FUNCTIONS to OVERLOAD for specialisation ********/
};
#endif // PQISSLPERSONGRP_H

View File

@ -0,0 +1,513 @@
/*
* "$Id: pqissludp.cc,v 1.16 2007-02-18 21:46:49 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/pqissludp.h"
#include "_pqi/pqinetwork.h"
#include "_tcponudp/tou.h"
#include "_tcponudp/bio_tou.h"
#include <errno.h>
#include <openssl/err.h>
#include <sstream>
#include "_util/rsdebug.h"
#include "_util/rsnet.h"
const int pqissludpzone = 3144;
/* a final timeout, to ensure this never blocks completely
* 300 secs to complete udp/tcp/ssl connection.
* This is long as the udp connect can take some time.
*/
static const uint32_t PQI_SSLUDP_DEF_CONN_PERIOD = 300; /* 5 minutes? */
/********** PQI SSL UDP STUFF **************************************/
pqissludp::pqissludp(PQInterface *parent, p3AuthMgr *am, p3ConnectMgr *cm)
:pqissl(NULL, parent, am, cm), tou_bio(NULL),
listen_checktime(0), mConnectPeriod(PQI_SSLUDP_DEF_CONN_PERIOD)
{
sockaddr_clear(&remote_addr);
return;
}
pqissludp::~pqissludp()
{
rslog(RSL_ALERT, pqissludpzone,
"pqissludp::~pqissludp -> destroying pqissludp");
/* must call reset from here, so that the
* virtual functions will still work.
* -> as they stop working in base class destructor.
*
* This means that reset() will be called twice, but this should
* be harmless.
*/
stoplistening(); /* remove from p3proxy listenqueue */
reset();
if (tou_bio) // this should be in the reset?
{
BIO_free(tou_bio);
}
return;
}
int pqissludp::reset()
{
/* reset for next time.*/
return pqissl::reset();
}
/* <===================== UDP Difference *******************/
// The Proxy Version takes a few more step
//
// connectInterface is sent via message from the proxy.
// and is set here.
/* <===================== UDP Difference *******************/
int pqissludp::attach()
{
sockfd = tou_socket(0,0,0);
if (0 > sockfd)
{
rslog(RSL_WARNING, pqissludpzone,
"pqissludp::attach() failed to create a socket");
return -1;
}
// setup remote address
rslog(RSL_WARNING, pqissludpzone,
"pqissludp::attach() Opened Local Udp Socket");
return 1;
}
// The Address determination is done centrally
int pqissludp::Initiate_Connection()
{
int err;
attach(); /* open socket */
remote_addr.sin_family = AF_INET;
rslog(RSL_DEBUG_BASIC, pqissludpzone,
"pqissludp::Initiate_Connection() Attempting Outgoing Connection....");
/* decide if we're active or passive */
if (PeerId() < mConnMgr->getOwnId())
{
sslmode = PQISSL_ACTIVE;
}
else
{
sslmode = PQISSL_PASSIVE;
}
if (waiting != WAITING_DELAY)
{
rslog(RSL_WARNING, pqissludpzone,
"pqissludp::Initiate_Connection() Already Attempt in Progress!");
return -1;
}
if (sockfd < 0)
{
rslog(RSL_ALERT, pqissludpzone,
"pqissludp::Initiate_Connection() Socket Creation Failed!");
waiting = WAITING_FAIL_INTERFACE;
return -1;
}
rslog(RSL_DEBUG_BASIC, pqissludpzone,
"pqissludp::Initiate_Connection() Opening Socket");
{
std::ostringstream out;
out << "pqissludp::Initiate_Connection() ";
out << "Connecting To: " << PeerId();
out << " via: " << inet_ntoa(remote_addr.sin_addr) << ":";
out << ntohs(remote_addr.sin_port) << " ";
if (sslmode)
{
out << "ACTIVE Connect (SSL_Connect)";
}
else
{
out << "PASSIVE Connect (SSL_Accept)";
}
rslog(RSL_WARNING, pqissludpzone, out.str());
}
if (remote_addr.sin_addr.s_addr == 0)
{
std::ostringstream out;
out << "pqissludp::Initiate_Connection() ";
out << "Invalid (0.0.0.0) Remote Address,";
out << " Aborting Connect.";
out << std::endl;
rslog(RSL_WARNING, pqissludpzone, out.str());
waiting = WAITING_FAIL_INTERFACE;
reset();
return -1;
}
mTimeoutTS = time(NULL) + mConnectTimeout;
//std::cerr << "Setting Connect Timeout " << mConnectTimeout << " Seconds into Future " << std::endl;
//std::cerr << " Connect Period is:" << mConnectPeriod << std::endl;
/* <===================== UDP Difference *******************/
if (0 != (err = tou_connect(sockfd, (struct sockaddr *) &remote_addr,
sizeof(remote_addr), mConnectPeriod)))
/* <===================== UDP Difference *******************/
{
int tou_err = tou_errno(sockfd);
std::ostringstream out;
out << "pqissludp::Initiate_Connection()";
if ((tou_err == EINPROGRESS) || (tou_err == EAGAIN))
{
// set state to waiting.....
waiting = WAITING_SOCK_CONNECT;
out << " EINPROGRESS Waiting for Socket Connection";
rslog(RSL_WARNING, pqissludpzone, out.str());
return 0;
}
else if ((tou_err == ENETUNREACH) || (tou_err == ETIMEDOUT))
{
out << "ENETUNREACHABLE: cert: " << PeerId();
out << std::endl;
// Then send unreachable message.
waiting = WAITING_FAIL_INTERFACE;
net_unreachable |= net_attempt;
}
out << "Error: Connection Failed: " << tou_err;
out << " - " << socket_errorType(tou_err) << std::endl;
rslog(RSL_WARNING, pqissludpzone, out.str());
reset();
return -1;
}
else
{
rslog(RSL_DEBUG_BASIC, pqissludpzone,
"pqissludp::Init_Connection() connect returned 0");
}
waiting = WAITING_SOCK_CONNECT;
rslog(RSL_DEBUG_BASIC, pqissludpzone,
"pqissludp::Initiate_Connection() Waiting for Socket Connect");
return 1;
}
/********* VERY DIFFERENT **********/
int pqissludp::Basic_Connection_Complete()
{
rslog(RSL_DEBUG_BASIC, pqissludpzone,
"pqissludp::Basic_Connection_Complete()...");
if (time(NULL) > mTimeoutTS)
{
std::ostringstream out;
out << "pqissludp::Basic_Connection_Complete() Connection Timed Out. ";
out << "Peer: " << PeerId() << " Period: ";
out << mConnectTimeout;
rslog(RSL_WARNING, pqissludpzone, out.str());
/* as sockfd is valid, this should close it all up */
reset();
return -1;
}
if (waiting != WAITING_SOCK_CONNECT)
{
rslog(RSL_DEBUG_BASIC, pqissludpzone,
"pqissludp::Basic_Connection_Complete() Wrong Mode");
return -1;
}
/* new approach is to check for an error */
/* check for an error */
int err;
if (0 != (err = tou_errno(sockfd)))
{
if (err == EINPROGRESS)
{
std::ostringstream out;
out << "pqissludp::Basic_Connection_Complete() ";
out << "EINPROGRESS: cert: " << PeerId();
rslog(RSL_DEBUG_BASIC, pqissludpzone, out.str());
}
else if ((err == ENETUNREACH) || (err == ETIMEDOUT))
{
std::ostringstream out;
out << "pqissludp::Basic_Connection_Complete() ";
out << "ENETUNREACH/ETIMEDOUT: cert: ";
out << PeerId();
rslog(RSL_WARNING, pqissludpzone, out.str());
/* is the second one needed? */
std::ostringstream out2;
out2 << "pqissludp::Basic_Connection_Complete() ";
out2 << "Error: Connection Failed: " << err;
out2 << " - " << socket_errorType(err);
rslog(RSL_DEBUG_BASIC, pqissludpzone, out2.str());
net_unreachable |= net_attempt;
reset();
// Then send unreachable message.
waiting = WAITING_FAIL_INTERFACE;
return -1;
}
}
/* <===================== UDP Difference *******************/
if (tou_connected(sockfd))
/* <===================== UDP Difference *******************/
{
std::ostringstream out;
out << "pqissludp::Basic_Connection_Complete() ";
out << "Connection Complete: cert: ";
out << PeerId();
rslog(RSL_WARNING, pqissludpzone, out.str());
return 1;
}
else
{
// not ready return -1;
rslog(RSL_DEBUG_BASIC, pqissludpzone,
"pqissludp::Basic_Connection_Complete() Not Yet Ready!");
return 0;
}
return -1;
}
/* New Internal Functions required to generalise tcp/udp version
* of the programs
*/
// used everywhere
int pqissludp::net_internal_close(int fd)
{
rslog(RSL_ALERT, pqissludpzone,
"pqissludp::net_internal_close() -> tou_close()");
return tou_close(fd);
}
// install udp BIO.
int pqissludp::net_internal_SSL_set_fd(SSL *ssl, int fd)
{
rslog(RSL_DEBUG_BASIC, pqissludpzone,
"pqissludp::net_internal_SSL_set_fd()");
/* create the bio's */
tou_bio =BIO_new(BIO_s_tou_socket());
/* attach the fd's to the BIO's */
BIO_set_fd(tou_bio, fd, BIO_NOCLOSE);
SSL_set_bio(ssl, tou_bio, tou_bio);
return 1;
}
int pqissludp::net_internal_fcntl_nonblock(int fd)
{
rslog(RSL_DEBUG_BASIC, pqissludpzone,
"pqissludp::net_internal_fcntl_nonblock()");
return 0;
}
/* These are identical to pqinetssl version */
//int pqissludp::status()
int pqissludp::tick()
{
pqissl::tick();
return 1;
}
// listen fns call the udpproxy.
int pqissludp::listen()
{
{
std::ostringstream out;
out << "pqissludp::listen() (NULLOP)";
rslog(RSL_DEBUG_BASIC, pqissludpzone, out.str());
}
return 1; //udpproxy->listen();
}
int pqissludp::stoplistening()
{
{
std::ostringstream out;
out << "pqissludp::stoplistening() (NULLOP)";
rslog(RSL_DEBUG_BASIC, pqissludpzone, out.str());
}
return 1; //udpproxy->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::ostringstream out;
out << "pqissludp::connect_parameter() Peer: " << PeerId() << " PERIOD: " << value;
rslog(RSL_WARNING, pqissludpzone, out.str());
mConnectPeriod = value;
return true;
}
return pqissl::connect_parameter(type, value);
}
/********** PQI STREAMER OVERLOADING *********************************/
bool pqissludp::moretoread()
{
{
std::ostringstream out;
out << "pqissludp::moretoread()";
out << " polling socket (" << sockfd << ")";
rslog(RSL_DEBUG_ALL, pqissludpzone, out.str());
}
/* check for more to read first ... if nothing... check error
*/
/* <===================== UDP Difference *******************/
if (tou_maxread(sockfd))
/* <===================== UDP Difference *******************/
{
rslog(RSL_DEBUG_BASIC, pqissludpzone,
"pqissludp::moretoread() Data to Read!");
return 1;
}
/* else check the error */
rslog(RSL_DEBUG_ALL, pqissludpzone,
"pqissludp::moretoread() No Data to Read!");
int err;
if (0 != (err = tou_errno(sockfd)))
{
if ((err == EAGAIN) || (err == EINPROGRESS))
{
std::ostringstream out;
out << "pqissludp::moretoread() ";
out << "EAGAIN/EINPROGRESS: cert " << PeerId();
rslog(RSL_DEBUG_BASIC, pqissludpzone, out.str());
return 0;
}
else if ((err == ENETUNREACH) || (err == ETIMEDOUT))
{
std::ostringstream out;
out << "pqissludp::moretoread() ";
out << "ENETUNREACH/ETIMEDOUT: cert ";
out << PeerId();
rslog(RSL_WARNING, pqissludpzone, out.str());
}
else if (err == EBADF)
{
std::ostringstream out;
out << "pqissludp::moretoread() ";
out << "EBADF: cert ";
out << PeerId();
rslog(RSL_WARNING, pqissludpzone, out.str());
}
else
{
std::ostringstream out;
out << "pqissludp::moretoread() ";
out << " Unknown ERROR: " << err << ": cert ";
out << PeerId();
rslog(RSL_WARNING, pqissludpzone, out.str());
}
reset();
return 0;
}
/* otherwise - not error - strange! */
rslog(RSL_DEBUG_BASIC, pqissludpzone,
"pqissludp::moretoread() No Data + No Error (really nothing)");
return 0;
}
bool pqissludp::cansend()
{
rslog(RSL_DEBUG_ALL, pqissludpzone,
"pqissludp::cansend() polling socket!");
/* <===================== UDP Difference *******************/
return (0 < tou_maxwrite(sockfd));
/* <===================== UDP Difference *******************/
}

View File

@ -0,0 +1,104 @@
/*
* "$Id: pqissludp.h,v 1.8 2007-02-18 21:46:49 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 PQISSLUDP_H
#define PQISSLUDP_H
#include <openssl/ssl.h>
// operating system specific network header.
#include "pqi/pqinetwork.h"
#include <string>
#include <map>
#include "_pqi/pqissl.h"
/* So pqissludp is the special firewall breaking protocol.
* This class will implement the basics of streaming
* ssl over udp using a tcponudp library....
* and a small extension to ssl.
*/
class pqissludp;
class cert;
/* This provides a NetBinInterface, which is
* primarily inherited from pqissl.
* fns declared here are different -> all others are identical.
*/
class pqissludp: public pqissl
{
public:
pqissludp(PQInterface *parent, p3AuthMgr *am, p3ConnectMgr *cm);
virtual ~pqissludp();
// NetInterface.
// listen fns call the udpproxy.
virtual int listen();
virtual int stoplistening();
virtual int tick();
virtual int reset();
virtual bool connect_parameter(uint32_t type, uint32_t value);
// BinInterface.
// These are reimplemented.
virtual bool moretoread();
virtual bool cansend();
/* UDP always through firewalls -> always bandwidth Limited */
virtual bool bandwidthLimited() { return true; }
// pqissludp specific.
// called to initiate a connection;
int attach();
protected:
virtual int Initiate_Connection();
virtual int Basic_Connection_Complete();
//protected internal fns that are overloaded for udp case.
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);
private:
BIO *tou_bio; // specific to ssludp.
//int remote_timeout;
//int proxy_timeout;
long listen_checktime;
uint32_t mConnectPeriod;
};
#endif // PQISSLUDP_H

View File

@ -0,0 +1,378 @@
/*
* "$Id: pqistore.cc,v 1.5 2007-03-21 18:45:41 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".
*
*/
/* This is dependent on the sslroot at the moment.
* -> as we need to create/restore references to the Person.
* -> and store the signatures to do this.
*/
/*******************************************************************
* pqistore provides an store stream.
* This stores RsItem + Person Reference + Timestamp,
*
* and allows Objects to be replayed or restored,
* independently of the rest of the pqi system.
*
*/
#include "_pqi/pqistore.h"
#include "_serialiser/rsserial.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include "_util/rsdebug.h"
const int pqistorezone = 9511;
pqistore::pqistore(RsSerialiser *rss, std::string srcId, BinInterface *bio_in, int bio_flags_in)
:PQInterface(""), rsSerialiser(rss), bio(bio_in), bio_flags(bio_flags_in),
nextPkt(NULL), mSrcId(srcId)
{
{
std::ostringstream out;
out << "pqistore::pqistore()";
out << " Initialisation!" << std::endl;
pqioutput(PQL_DEBUG_ALL, pqistorezone, out.str());
}
if (!bio_in)
{
std::ostringstream out;
out << "pqistore::pqistore()";
out << " NULL bio, FATAL ERROR!" << std::endl;
pqioutput(PQL_ALERT, pqistorezone, out.str());
exit(1);
}
return;
}
pqistore::~pqistore()
{
{
std::ostringstream out;
out << "pqistore::~pqistore()";
out << " Destruction!" << std::endl;
pqioutput(PQL_DEBUG_ALL, pqistorezone, out.str());
}
if (bio_flags & BIN_FLAGS_NO_CLOSE)
{
std::ostringstream out;
out << "pqistore::~pqistore()";
out << " Not Closing BinInterface!" << std::endl;
pqioutput(PQL_DEBUG_ALL, pqistorezone, out.str());
}
else if (bio)
{
std::ostringstream out;
out << "pqistore::~pqistore()";
out << " Deleting BinInterface!" << std::endl;
pqioutput(PQL_DEBUG_ALL, pqistorezone, out.str());
delete bio;
}
if (rsSerialiser)
delete rsSerialiser;
if (nextPkt)
{
delete nextPkt;
}
return;
}
// Get/Send Items.
int pqistore::SendItem(RsItem *si)
{
{
std::ostringstream out;
out << "pqistore::SendItem()" << std::endl;
si -> print(out);
pqioutput(PQL_DEBUG_BASIC, pqistorezone, out.str());
}
// check if this is a writing bio.
if (!(bio_flags & BIN_FLAGS_WRITEABLE))
{
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
delete si;
return -1;
}
// std::cerr << "SendItem: si->PeerId()=" << si->PeerId() << std::endl ;
int ret = writePkt(si);
return ret; /* 0 - failure, 1 - success*/
}
RsItem *pqistore::GetItem()
{
{
std::ostringstream out;
out << "pqistore::GetItem()";
pqioutput(PQL_DEBUG_ALL, pqistorezone, out.str());
}
// check if this is a reading bio.
if (!(bio_flags & BIN_FLAGS_READABLE))
{
std::ostringstream out;
out << "pqistore::GetItem()";
out << "Error Not Readable" << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqistorezone, out.str());
return NULL;
}
// load if we dont have a packet.
if (!nextPkt)
{
if (!readPkt(&nextPkt))
{
std::ostringstream out;
out << "pqistore::GetItem()";
out << "Failed to ReadPkt" << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqistorezone, out.str());
return NULL;
}
}
if (!nextPkt) return NULL;
RsItem *outPkt = nextPkt;
nextPkt = NULL;
if (outPkt != NULL)
{
std::ostringstream out;
out << "pqistore::GetItem() Returning:" << std::endl;
outPkt -> print(out);
pqioutput(PQL_DEBUG_BASIC, pqistorezone, out.str());
}
return outPkt;
}
// // PQInterface
int pqistore::tick()
{
{
std::ostringstream out;
out << "pqistore::tick()";
out << std::endl;
}
return 0;
}
int pqistore::status()
{
{
std::ostringstream out;
out << "pqistore::status()";
pqioutput(PQL_DEBUG_ALL, pqistorezone, out.str());
}
return 0;
}
//
/**************** HANDLE OUTGOING TRANSLATION + TRANSMISSION ******/
int pqistore::writePkt(RsItem *pqi)
{
// std::cerr << "writePkt, pqi->peerId()=" << pqi->PeerId() << std::endl ;
{
std::ostringstream out;
out << "pqistore::writePkt()";
pqioutput(PQL_DEBUG_ALL, pqistorezone, out.str());
}
uint32_t pktsize = rsSerialiser->size(pqi);
void *ptr = malloc(pktsize);
if (!(rsSerialiser->serialise(pqi, ptr, &pktsize)))
{
std::ostringstream out;
out << "pqistore::writePkt() Null Pkt generated!";
out << std::endl;
out << "Caused By: " << std::endl;
pqi -> print(out);
pqioutput(PQL_ALERT, pqistorezone, out.str());
free(ptr);
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
delete pqi;
return 0;
}
/* extract the extra details */
uint32_t len = getRsItemSize(ptr);
if (len != pktsize)
{
std::ostringstream out;
out << "pqistore::writePkt() Length MisMatch: len: " << len;
out << " != pktsize: " << pktsize;
out << std::endl;
out << "Caused By: " << std::endl;
pqi -> print(out);
pqioutput(PQL_ALERT, pqistorezone, out.str());
free(ptr);
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
delete pqi;
return 0;
}
if (!(bio->cansend()))
{
std::ostringstream out;
out << "pqistore::writePkt() BIO cannot write!";
out << std::endl;
out << "Discarding: " << std::endl;
pqi -> print(out);
pqioutput(PQL_ALERT, pqistorezone, out.str());
free(ptr);
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
delete pqi;
return 0;
}
std::ostringstream out;
out << "Writing Pkt Body" << std::endl;
// write packet.
if (len != bio->senddata(ptr, len))
{
out << "Problems with Send Data!";
out << std::endl;
pqioutput(PQL_ALERT, pqistorezone, out.str());
free(ptr);
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
delete pqi;
return 0;
}
out << " Success!" << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqistorezone, out.str());
free(ptr);
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
delete pqi;
return 1;
}
/* Reads a single packet from the input stream
* gets the timestamp as well.
*/
int pqistore::readPkt(RsItem **item_out)
{
{
std::ostringstream out;
out << "pqistore::readPkt()";
pqioutput(PQL_DEBUG_ALL, pqistorezone, out.str());
}
if ((!(bio->isactive())) || (!(bio->moretoread())))
{
return 0;
}
// enough space to read any packet.
int maxlen = getRsPktMaxSize();
void *block = malloc(maxlen);
// initial read size: basic packet.
int blen = getRsPktBaseSize();
int tmplen;
/* we have the header */
// read the basic block (minimum packet size)
if (blen != (tmplen = bio->readdata(block, blen)))
{
pqioutput(PQL_WARNING, pqistorezone,
"pqistore::readPkt() bad read(2)");
free(block);
return 0;
}
// workout how much more to read.
int extralen = getRsItemSize(block) - blen;
if (extralen > 0)
{
void *extradata = (void *) (((char *) block) + blen);
if (extralen != (tmplen = bio->readdata(extradata, extralen)))
{
std::ostringstream out;
out << "pqistore::readPkt() ";
out << "Error Completing Read (read ";
out << tmplen << "/" << extralen << ")" << std::endl;
pqioutput(PQL_ALERT, pqistorezone, out.str());
free(block);
return 0;
}
}
// create packet, based on header.
std::cerr << "Read Data Block -> Incoming Pkt(";
std::cerr << blen + extralen << ")" << std::endl;
uint32_t readbytes = extralen + blen;
RsItem *item = rsSerialiser->deserialise(block, &readbytes);
free(block);
if (item == NULL)
{
pqioutput(PQL_ALERT, pqistorezone,
"pqistore::readPkt() Failed to create Item from store!");
return 0;
}
item->PeerId(mSrcId);
*item_out = item;
return 1;
}
/**** Hashing Functions ****/
std::string pqistore::gethash()
{
return bio->gethash();
}

View File

@ -0,0 +1,72 @@
/*
* pqistore.h
*
* 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 PQISTORE_H
#define PQISTORE_H
#include "_pqi/pqi.h"
#include <list>
/*******************************************************************
* pqistore provides a stream to file.
* objects only - like pqistreamer as opposed to pqiarchive.
*
*/
class pqistore: public PQInterface
{
public:
pqistore(RsSerialiser *rss, std::string srcId, BinInterface *bio_in, int bio_flagsin);
virtual ~pqistore();
// PQInterface
virtual int SendItem(RsItem *);
virtual RsItem *GetItem();
virtual int tick();
virtual int status();
std::string gethash();
private:
int writePkt(RsItem *item);
int readPkt(RsItem **item_out);
// Serialiser
RsSerialiser *rsSerialiser;
// Binary Interface for IO, initialisated at startup.
BinInterface *bio;
unsigned int bio_flags; // only BIN_NO_CLOSE at the moment.
// Temp Storage for transient data.....
RsItem *nextPkt;
std::string mSrcId;
};
#endif //PQISTORE_H

View File

@ -0,0 +1,910 @@
/*
* "$Id: pqistreamer.cc,v 1.19 2007-02-18 21:46:50 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 <iostream>
#include <fstream>
#include <sstream>
#include "_util/rsdebug.h"
#include "_pqi/pqistreamer.h"
#include "_pqi/pqinotify.h"
#include "_serialiser/rsserial.h"
#include "_serialiser/rsbaseitems.h" /***** For RsFileData *****/
const int pqistreamerzone = 8221;
const int PQISTREAM_ABS_MAX = 100000000; /* 100 MB/sec (actually per loop) */
/* This removes the print statements (which hammer pqidebug) */
/***
#define RSITEM_DEBUG 1
***/
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)
{
avgLastUpdate = currReadTS = currSentTS = time(NULL);
/* allocated once */
pkt_rpend_size = getRsPktMaxSize();
pkt_rpending = malloc(pkt_rpend_size);
reading_state = reading_state_initial ;
// thread_id = pthread_self() ;
// avoid uninitialized (and random) memory read.
memset(pkt_rpending,0,pkt_rpend_size) ;
// 100 B/s (minimal)
setMaxRate(true, 0.1);
setMaxRate(false, 0.1);
setRate(true, 0);
setRate(false, 0);
{
std::ostringstream out;
out << "pqistreamer::pqistreamer()";
out << " Initialisation!" << std::endl;
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
}
if (!bio_in)
{
std::ostringstream out;
out << "pqistreamer::pqistreamer()";
out << " NULL bio, FATAL ERROR!" << std::endl;
pqioutput(PQL_ALERT, pqistreamerzone, out.str());
exit(1);
}
failed_read_attempts = 0 ; // reset failed read, as no packet is still read.
return;
}
pqistreamer::~pqistreamer()
{
RsStackMutex stack(streamerMtx) ; // lock out_pkt and out_data
{
std::ostringstream out;
out << "pqistreamer::~pqistreamer()";
out << " Destruction!" << std::endl;
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
}
if (bio_flags & BIN_FLAGS_NO_CLOSE)
{
std::ostringstream out;
out << "pqistreamer::~pqistreamer()";
out << " Not Closing BinInterface!" << std::endl;
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
}
else if (bio)
{
std::ostringstream out;
out << "pqistreamer::~pqistreamer()";
out << " Deleting BinInterface!" << std::endl;
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
delete bio;
}
/* clean up serialiser */
if (rsSerialiser)
delete rsSerialiser;
// clean up outgoing. (cntrl packets)
while(out_pkt.size() > 0)
{
void *pkt = out_pkt.front();
out_pkt.pop_front();
free(pkt);
}
// clean up outgoing (data packets)
while(out_data.size() > 0)
{
void *pkt = out_data.front();
out_data.pop_front();
free(pkt);
}
if (pkt_wpending)
{
free(pkt_wpending);
pkt_wpending = NULL;
}
free(pkt_rpending);
// clean up outgoing.
while(incoming.size() > 0)
{
RsItem *i = incoming.front();
incoming.pop_front();
delete i;
}
return;
}
// Get/Send Items.
int pqistreamer::SendItem(RsItem *si)
{
#ifdef RSITEM_DEBUG
{
std::ostringstream out;
out << "pqistreamer::SendItem():" << std::endl;
si -> print(out);
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
}
#endif
return queue_outpqi(si);
}
RsItem *pqistreamer::GetItem()
{
{
std::ostringstream out;
out << "pqistreamer::GetItem()";
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
}
std::list<RsItem *>::iterator it;
it = incoming.begin();
if (it == incoming.end()) { return NULL; }
RsItem *osr = (*it);
incoming.erase(it);
return osr;
}
// // PQInterface
int pqistreamer::tick()
{
// std::cerr << "enterign tick, state = " << reading_state << std::endl ;
{
std::ostringstream out;
out << "pqistreamer::tick()";
out << std::endl;
out << PeerId() << ": currRead/Sent: " << currRead << "/" << currSent;
out << std::endl;
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
}
// std::cerr << "calling bio-> tick, state = " << reading_state << std::endl ;
bio->tick();
// std::cerr << "after bio-> tick, state = " << reading_state << std::endl ;
/* short circuit everything is bio isn't active */
if (!(bio->isactive()))
{
return 0;
}
/* must do both, as outgoing will catch some bad sockets,
* that incoming will not
*/
// std::cerr << "calling handle incoming, state = " << reading_state << std::endl ;
handleincoming();
// std::cerr << "returned from handle incoming, state = " << reading_state << std::endl ;
handleoutgoing();
// std::cerr << "returned from handle outgoing, state = " << reading_state << std::endl ;
/* give details of the packets */
{
std::list<void *>::iterator it;
std::ostringstream out;
out << "pqistreamer::tick() Queued Data:";
out << " for " << PeerId();
if (bio->isactive())
{
out << " (active)";
}
else
{
out << " (waiting)";
}
out << std::endl;
{
RsStackMutex stack(streamerMtx) ; // lock out_pkt and out_data
int total = 0;
for(it = out_pkt.begin(); it != out_pkt.end(); it++)
{
total += getRsItemSize(*it);
}
out << "\t Out Packets [" << out_pkt.size() << "] => " << total;
out << " bytes" << std::endl;
total = 0;
for(it = out_data.begin(); it != out_data.end(); it++)
{
total += getRsItemSize(*it);
}
out << "\t Out Data [" << out_data.size() << "] => " << total;
out << " bytes" << std::endl;
out << "\t Incoming [" << incoming.size() << "]";
out << std::endl;
}
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out.str());
}
/* if there is more stuff in the queues */
if ((incoming.size() > 0) || (out_pkt.size() > 0) || (out_data.size() > 0))
{
return 1;
}
return 0;
}
int pqistreamer::status()
{
{
std::ostringstream out;
out << "pqistreamer::status()";
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
}
if (bio->isactive())
{
std::ostringstream out;
out << "Data in:" << totalRead << " out:" << totalSent;
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out.str());
}
return 0;
}
//
/**************** HANDLE OUTGOING TRANSLATION + TRANSMISSION ******/
int pqistreamer::queue_outpqi(RsItem *pqi)
{
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 !!
{
std::ostringstream out;
out << "pqistreamer::queue_outpqi()";
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
}
/* decide which type of packet it is */
RsFileData *dta = dynamic_cast<RsFileData *>(pqi);
bool isCntrl = (dta == NULL);
// std::cerr << "Thread (queue_outpqi): thread = " << pthread_self() << "isCntrl=" << isCntrl << std::endl ;
uint32_t pktsize = rsSerialiser->size(pqi);
void *ptr = malloc(pktsize);
// std::cerr << "serializing packet of size " << pktsize << std::endl ;
if (rsSerialiser->serialise(pqi, ptr, &pktsize))
{
if (isCntrl)
{
out_pkt.push_back(ptr);
}
else
{
out_data.push_back(ptr);
}
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
{
delete pqi;
}
return 1;
}
else
{
/* cleanup serialiser */
free(ptr);
}
std::ostringstream out;
out << "pqistreamer::queue_outpqi() Null Pkt generated!";
out << std::endl;
out << "Caused By: " << std::endl;
pqi -> print(out);
pqioutput(PQL_ALERT, pqistreamerzone, out.str());
if (!(bio_flags & BIN_FLAGS_NO_DELETE))
{
delete pqi;
}
return 1; // keep error internal.
}
int pqistreamer::handleincomingitem(RsItem *pqi)
{
{
std::ostringstream out;
out << "pqistreamer::handleincomingitem()";
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
}
// Use overloaded Contact function
pqi -> PeerId(PeerId());
incoming.push_back(pqi);
return 1;
}
int pqistreamer::handleoutgoing()
{
RsStackMutex stack(streamerMtx) ; // lock out_pkt and out_data
{
std::ostringstream out;
out << "pqistreamer::handleoutgoing()";
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
}
int maxbytes = outAllowedBytes();
int sentbytes = 0;
int len;
int ss;
// std::cerr << "pqistreamer: maxbytes=" << maxbytes<< std::endl ;
std::list<void *>::iterator it;
// if not connection, or cannot send anything... pause.
if (!(bio->isactive()))
{
/* if we are not active - clear anything in the queues. */
for(it = out_pkt.begin(); it != out_pkt.end(); )
{
free(*it);
it = out_pkt.erase(it);
std::ostringstream out;
out << "pqistreamer::handleoutgoing() Not active -> Clearing Pkt!";
// std::cerr << out.str() ;
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out.str());
}
for(it = out_data.begin(); it != out_data.end(); )
{
free(*it);
it = out_data.erase(it);
std::ostringstream out;
out << "pqistreamer::handleoutgoing() Not active -> Clearing DPkt!";
// std::cerr << out.str() ;
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out.str());
}
/* also remove the pending packets */
if (pkt_wpending)
{
free(pkt_wpending);
pkt_wpending = NULL;
}
outSentBytes(sentbytes);
return 0;
}
// a very simple round robin
bool sent = true;
while(sent) // catch if all items sent.
{
sent = false;
if ((!(bio->cansend())) || (maxbytes < sentbytes))
{
outSentBytes(sentbytes);
return 0;
}
// send a out_pkt., else send out_data. unless
// there is a pending packet.
if (!pkt_wpending)
{
if (out_pkt.size() > 0)
{
pkt_wpending = *(out_pkt.begin());
out_pkt.pop_front();
}
else if (out_data.size() > 0)
{
pkt_wpending = *(out_data.begin());
out_data.pop_front();
}
}
if (pkt_wpending)
{
std::ostringstream out;
// write packet.
len = getRsItemSize(pkt_wpending);
// std::cout << "Sending Out Pkt of size " << len << " !" << std::endl ;
if (len != (ss = bio->senddata(pkt_wpending, len)))
{
out << "Problems with Send Data! (only " << ss << " bytes sent" << ", total pkt size=" << len ;
out << std::endl;
// std::cerr << out.str() ;
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out.str());
outSentBytes(sentbytes);
// pkt_wpending will kept til next time.
// ensuring exactly the same data is written (openSSL requirement).
return -1;
}
// out << " Success!" << ", sent " << len << " bytes" << std::endl;
// std::cerr << out.str() ;
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out.str());
free(pkt_wpending);
pkt_wpending = NULL;
sentbytes += len;
sent = true;
}
}
outSentBytes(sentbytes);
return 1;
}
/* Handles reading from input stream.
*/
int pqistreamer::handleincoming()
{
int readbytes = 0;
static const int max_failed_read_attempts = 2000 ;
{
std::ostringstream out;
out << "pqistreamer::handleincoming()";
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
}
if(!(bio->isactive()))
{
reading_state = reading_state_initial ;
inReadBytes(readbytes);
return 0;
}
// enough space to read any packet.
int maxlen = pkt_rpend_size;
void *block = pkt_rpending;
// initial read size: basic packet.
int blen = getRsPktBaseSize();
int maxin = inAllowedBytes();
// std::cerr << "reading state = " << reading_state << std::endl ;
switch(reading_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 ;
}
start_packet_read:
{ // scope to ensure variable visibility
// read the basic block (minimum packet size)
int tmplen;
// std::cerr << "starting packet" << std::endl ;
memset(block,0,blen) ; // reset the block, to avoid uninitialized memory reads.
if (blen != (tmplen = bio->readdata(block, blen)))
{
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, "pqistreamer::handleincoming() Didn't read BasePkt!");
inReadBytes(readbytes);
// error.... (either blocked or failure)
if (tmplen == 0)
{
// most likely blocked!
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, "pqistreamer::handleincoming() read blocked");
// std::cerr << "given up 1" << std::endl ;
return 0;
}
else if (tmplen < 0)
{
// Most likely it is that the packet is pending but could not be read by pqissl because of stream flow.
// So we return without an error, and leave the machine state in 'start_read'.
//
//pqioutput(PQL_WARNING, pqistreamerzone, "pqistreamer::handleincoming() Error in bio read");
// std::cerr << "given up 2, state = " << reading_state << std::endl ;
return 0;
}
else // tmplen > 0
{
// strange case....This should never happen as partial reads are handled by pqissl below.
std::ostringstream out;
out << "pqistreamer::handleincoming() Incomplete ";
out << "(Strange) read of " << tmplen << " bytes";
pqioutput(PQL_ALERT, pqistreamerzone, out.str());
// std::cerr << "given up 3" << std::endl ;
return -1;
}
}
// std::cerr << "block 0 : " << (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]) << " "
// << (int)(((unsigned char*)block)[6]) << " "
// << (int)(((unsigned char*)block)[7]) << " " << std::endl ;
readbytes += blen;
reading_state = reading_state_packet_started ;
failed_read_attempts = 0 ; // reset failed read, as the packet has been totally read.
}
continue_packet:
{
// workout how much more to read.
int extralen = getRsItemSize(block) - blen;
// std::cerr << "continuing packet state=" << reading_state << std::endl ;
// std::cerr << "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]) << " "
// << (int)(((unsigned char*)block)[6]) << " "
// << (int)(((unsigned char*)block)[7]) << " " << std::endl ;
if (extralen > maxlen - blen)
{
pqioutput(PQL_ALERT, pqistreamerzone, "ERROR: Read Packet too Big!");
pqiNotify *notify = getPqiNotify();
if (notify)
{
std::string title =
"Warning: Bad Packet Read";
std::ostringstream msgout;
msgout << " **** WARNING **** \n";
msgout << "Retroshare has caught a BAD Packet Read";
msgout << "\n";
msgout << "This is normally caused by connecting to an";
msgout << " OLD version of Retroshare";
msgout << "\n";
msgout << "(M:" << maxlen << " B:" << blen << " E:" << extralen << ")\n";
msgout << "\n";
msgout << "block = "
<< (int)(((unsigned char*)block)[0]) << " "
<< (int)(((unsigned char*)block)[1]) << " "
<< (int)(((unsigned char*)block)[2]) << " "
<< (int)(((unsigned char*)block)[3]) << "\n" ;
msgout << "\n";
msgout << "Please get your friends to upgrade to the latest version";
msgout << "\n";
msgout << "\n";
msgout << "If you are sure the error was not caused by an old version";
msgout << "\n";
msgout << "Please report the problem to Retroshare's developers";
msgout << "\n";
std::string msg = msgout.str();
notify->AddLogMessage(0, RS_SYS_WARNING, title, msg);
}
bio->close();
reading_state = reading_state_initial ; // restart at state 1.
failed_read_attempts = 0 ;
return -1;
// Used to exit now! exit(1);
}
if (extralen > 0)
{
void *extradata = (void *) (((char *) block) + blen);
int tmplen ;
memset((void*)( &(((unsigned char *)block)[blen])),0,extralen) ; // reset the block, to avoid uninitialized memory reads.
memset( extradata,0,extralen ) ; // for checking later
if (extralen != (tmplen = bio->readdata(extradata, extralen)))
{
if(tmplen > 0)
std::cerr << "Incomplete packet read ! This is a real problem ;-)" << std::endl ;
if(++failed_read_attempts > max_failed_read_attempts)
{
std::ostringstream out;
out << "Error Completing Read (read ";
out << tmplen << "/" << extralen << ")" << std::endl;
std::cerr << out.str() ;
pqioutput(PQL_ALERT, pqistreamerzone, out.str());
pqiNotify *notify = getPqiNotify();
if (notify)
{
std::string title = "Warning: Error Completing Read";
std::ostringstream msgout;
msgout << " **** WARNING **** \n";
msgout << "Retroshare has experienced an unexpected Read ERROR";
msgout << "\n";
msgout << "(M:" << maxlen << " B:" << blen;
msgout << " E:" << extralen << " R:" << tmplen << ")\n";
msgout << "\n";
msgout << "Please contact the developers.";
msgout << "\n";
std::string msg = msgout.str();
std::cerr << msg << std::endl ;
std::cerr << "block = "
<< (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]) << " "
<< (int)(((unsigned char*)block)[6]) << " "
<< (int)(((unsigned char*)block)[7]) << " "
<< std::endl ;
// notify->AddSysMessage(0, RS_SYS_WARNING, title, msg);
}
bio->close();
reading_state = reading_state_initial ; // restart at state 1.
failed_read_attempts = 0 ;
return -1;
}
else
{
// std::cerr << "given up 5, state = " << reading_state << std::endl ;
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.
}
}
failed_read_attempts = 0 ;
readbytes += extralen;
}
// create packet, based on header.
{
std::ostringstream out;
out << "Read Data Block -> Incoming Pkt(";
out << blen + extralen << ")" << std::endl;
// std::cerr << out.str() ;
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out.str());
}
// std::cerr << "Deserializing packet of size " << pktlen <<std::endl ;
uint32_t pktlen = blen+extralen ;
// std::cerr << "deserializing. Size=" << pktlen << std::endl ;
if(pktlen == 17306)
{
FILE *f = fopen("dbug.packet.bin","w");
fwrite(block,pktlen,1,f) ;
fclose(f) ;
exit(-1) ;
}
RsItem *pkt = rsSerialiser->deserialise(block, &pktlen);
if ((pkt != NULL) && (0 < handleincomingitem(pkt)))
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, "Successfully Read a Packet!");
else
pqioutput(PQL_ALERT, pqistreamerzone, "Failed to handle Packet!");
reading_state = reading_state_initial ; // restart at state 1.
failed_read_attempts = 0 ; // reset failed read, as the packet has been totally read.
}
if(maxin > readbytes && bio->moretoread())
goto start_packet_read ;
inReadBytes(readbytes);
return 0;
}
/* BandWidth Management Assistance */
float pqistreamer::outTimeSlice()
{
{
std::ostringstream out;
out << "pqistreamer::outTimeSlice()";
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
}
//fixme("pqistreamer::outTimeSlice()", 1);
return 1;
}
// very simple.....
int pqistreamer::outAllowedBytes()
{
int t = time(NULL); // get current timestep.
/* allow a lot if not bandwidthLimited */
if (!bio->bandwidthLimited())
{
currSent = 0;
currSentTS = t;
return PQISTREAM_ABS_MAX;
}
int dt = t - currSentTS;
// limiter -> for when currSentTs -> 0.
if (dt > 5)
dt = 5;
int maxout = (int) (getMaxRate(false) * 1000.0);
currSent -= dt * maxout;
if (currSent < 0)
{
currSent = 0;
}
currSentTS = t;
{
std::ostringstream out;
out << "pqistreamer::outAllowedBytes() is ";
out << maxout - currSent << "/";
out << maxout;
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
}
return maxout - currSent;
}
int pqistreamer::inAllowedBytes()
{
int t = time(NULL); // get current timestep.
/* allow a lot if not bandwidthLimited */
if (!bio->bandwidthLimited())
{
currReadTS = t;
currRead = 0;
return PQISTREAM_ABS_MAX;
}
int dt = t - currReadTS;
// limiter -> for when currReadTs -> 0.
if (dt > 5)
dt = 5;
int maxin = (int) (getMaxRate(true) * 1000.0);
currRead -= dt * maxin;
if (currRead < 0)
{
currRead = 0;
}
currReadTS = t;
{
std::ostringstream out;
out << "pqistreamer::inAllowedBytes() is ";
out << maxin - currRead << "/";
out << maxin;
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
}
return maxin - currRead;
}
static const float AVG_PERIOD = 5; // sec
static const float AVG_FRAC = 0.8; // for low pass filter.
void pqistreamer::outSentBytes(int outb)
{
{
std::ostringstream out;
out << "pqistreamer::outSentBytes(): ";
out << outb << "@" << getRate(false) << "kB/s" << std::endl;
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
}
totalSent += outb;
currSent += outb;
avgSentCount += outb;
int t = time(NULL); // get current timestep.
if (t - avgLastUpdate > AVG_PERIOD)
{
float avgReadpSec = getRate(true);
float avgSentpSec = getRate(false);
avgReadpSec *= AVG_FRAC;
avgReadpSec += (1.0 - AVG_FRAC) * avgReadCount /
(1000.0 * (t - avgLastUpdate));
avgSentpSec *= AVG_FRAC;
avgSentpSec += (1.0 - AVG_FRAC) * avgSentCount /
(1000.0 * (t - avgLastUpdate));
/* pretend our rate is zero if we are
* not bandwidthLimited().
*/
if (bio->bandwidthLimited())
{
setRate(true, avgReadpSec);
setRate(false, avgSentpSec);
}
else
{
setRate(true, 0);
setRate(false, 0);
}
avgLastUpdate = t;
avgReadCount = 0;
avgSentCount = 0;
}
return;
}
void pqistreamer::inReadBytes(int inb)
{
{
std::ostringstream out;
out << "pqistreamer::inReadBytes(): ";
out << inb << "@" << getRate(true) << "kB/s" << std::endl;
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
}
totalRead += inb;
currRead += inb;
avgReadCount += inb;
return;
}

View File

@ -0,0 +1,116 @@
/*
* libretroshare/src/pqi pqistreamer.h
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-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".
*
*/
#ifndef PQISTREAMER_H
#define PQISTREAMER_H
// Only dependent on the base stuff.
#include "_pqi/pqi_base.h"
#include "_util/rsthreads.h"
#include <list>
// Fully implements the PQInterface.
// and communicates with peer etc via the BinInterface.
//
// The interface does not handle connection, just communication.
// possible bioflags: BIN_FLAGS_NO_CLOSE | BIN_FLAGS_NO_DELETE
class pqistreamer: public PQInterface
{
public:
pqistreamer(RsSerialiser *rss, std::string peerid, BinInterface *bio_in, int bio_flagsin);
virtual ~pqistreamer();
// PQInterface
virtual int SendItem(RsItem *);
virtual RsItem *GetItem();
virtual int tick();
virtual int status();
private:
/* Implementation */
// to filter functions - detect filecancel/data and act!
int queue_outpqi( RsItem *i);
int handleincomingitem(RsItem *i);
// ticked regularly (manages out queues and sending
// via above interfaces.
int handleoutgoing();
int handleincoming();
// Bandwidth/Streaming Management.
float outTimeSlice();
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
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.
enum { reading_state_packet_started=1,
reading_state_initial=0 } ;
int reading_state ;
int failed_read_attempts ;
// Temp Storage for transient data.....
std::list<void *> out_pkt; // Cntrl / Search / Results queue
std::list<void *> out_data; // FileData - secondary queue.
std::list<RsItem *> incoming;
// data for network stats.
int totalRead;
int totalSent;
// these are representative (but not exact)
int currRead;
int currSent;
int currReadTS; // TS from which these are measured.
int currSentTS;
int avgLastUpdate; // TS from which these are measured.
float avgReadCount;
float avgSentCount;
RsMutex streamerMtx ;
// pthread_t thread_id;
};
#endif // PQISTREAMER_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,192 @@
#ifndef SSLCERT_H
#define SSLCERT_H
/*
* Core PQI networking: sslcert.h
*
* 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 <openssl/ssl.h>
#include <openssl/evp.h>
#include <string>
#include <map>
#include "_pqi_base.h"
#include "_pqinetwork.h"
#include "_pqiindic.h"
// helper fns.
int printSSLError(SSL *ssl, int retval, int err, unsigned long err2, std::ostream &out);
std::string getX509NameString(X509_NAME *name);
std::string getX509CNString(X509_NAME *name);
std::string getX509OrgString(X509_NAME *name);
std::string getX509LocString(X509_NAME *name);
std::string getX509CountryString(X509_NAME *name);
/* definitions -> functions to be defined */
std::string convert_to_str(certsign &sign);
bool convert_to_certsign(std::string id, certsign &sign);
class sslroot;
class cert: public Person
{
public:
cert();
virtual ~cert();
virtual std::string Signature();
std::string Hash();
void Hash(std::string);
X509 *certificate;
std::string hash;
};
// returns pointer to static variable.
// which must be inited..
sslroot *getSSLRoot();
class sslroot
{
public:
sslroot();
int active();
int setcertdir(char *path);
int initssl(const char *srvr_cert, const char *priv_key,
const char *CA_file, const char *passwd);
int closessl();
/* Context handling */
SSL_CTX *getCTX();
/* Certificate handling */
int compareCerts(cert *a, cert *b);
// network interface.
// program interface.
int addCertificate(cert *c);
int addUntrustedCertificate(cert *c);
int removeCertificate(cert *);
// Creation of Certificates.... (From X509)
// Core functions....
cert *checkDuplicateX509(X509 *x);
cert *checkPeerX509(X509 *x);
cert *makeCertificate(X509 *c);
cert *registerCertificate(X509 *nc, struct sockaddr_in, bool in);
int validateCertificate(cert *c);
// depreciated...
cert *findpeercert(const char *name);
//int loadpeercert(const char *fname);
//int savepeercert(const char *fname);
// Configuration Handling...
int setConfigDirs(const char *cdir, const char *ndir);
// these save both the certificates + the settings.
int saveCertificates(const char *fname);
int saveCertificates();
int loadCertificates(const char *fname);
// with a hash check/recalc in there for good measure.
cert * loadcertificate(const char* fname, std::string hash);
int savecertificate(cert *c, const char* fname);
// digest hashing /signing or encrypting interface.
int hashFile(std::string fname, unsigned char *hash, unsigned int hlen);
int hashDigest(char *data, unsigned int dlen, unsigned char *hash, unsigned int hlen);
int signDigest(EVP_PKEY *key, char *data, unsigned int dlen, unsigned char *hash, unsigned int hlen);
int verifyDigest(EVP_PKEY *key, char *data, unsigned int dlen, unsigned char *enc, unsigned int elen);
int generateKeyPair(EVP_PKEY *keypair, unsigned int keylen);
int printCertificate(cert *, std::ostream &out);
/****** REMOVED!
*
*
std::list<std::string> listCertificates();
*
*
****/
std::list<cert *> &getCertList();
cert * getOwnCert();
int checkNetAddress();
// extra list for certs that aren't in main list.
cert * getCollectedCert();
bool collectedCerts();
bool CertsChanged();
bool CertsMajorChanged();
void IndicateCertsChanged();
std::string getSetting(std::string opt);
void setSetting(std::string opt, std::string val);
/* Fns for relating cert signatures to structures */
cert *findcertsign(certsign &sign);
int getcertsign(cert *c, certsign &sign);
int addtosignmap(cert *);
private: /* data */
std::list<cert *> peercerts;
std::list<cert *> allcerts;
std::list<cert *> collectedcerts;
// whenever a cert is added, it should also be put in the map.
std::map<certsign, cert *> signmap;
// General Configuration System
// easy it put it here - so it can be signed easily.
std::map<std::string, std::string> settings;
std::string certdir;
std::string neighbourdir;
std::string certfile;
SSL_CTX *sslctx;
int init;
Indicator certsChanged;
Indicator certsMajorChanged;
EVP_PKEY *pkey;
cert *own_cert;
};
#endif // SSLCERT_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,221 @@
/*
* "$Id: xpgpcert.h,v 1.9 2007-04-15 18:45:18 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 XPGPCERT_H
#define XPGPCERT_H
/* This is the trial XPGP version
*
* It has to be compiled against XPGP ssl version.
* this is only a hacked up version, merging
* (so both can operate in parallel will happen later)
*
*/
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include <string>
#include <map>
#include "pqi_base.h"
#include "pqinetwork.h"
#include "pqiindic.h"
// helper fns.
int printSSLError(SSL *ssl, int retval, int err, unsigned long err2, std::ostream &out);
std::string getX509NameString(X509_NAME *name);
std::string getX509CNString(X509_NAME *name);
std::string getX509OrgString(X509_NAME *name);
std::string getX509LocString(X509_NAME *name);
std::string getX509CountryString(X509_NAME *name);
int LoadCheckXPGPandGetName(const char *cert_file, std::string &userName);
std::string convert_to_str(certsign &sign);
bool convert_to_certsign(std::string id, certsign &sign);
class sslroot;
class cert: public Person
{
public:
cert();
virtual ~cert();
virtual std::string Signature();
std::string Hash();
void Hash(std::string);
std::string PeerId() { return Signature(); }
XPGP *certificate;
std::string hash;
std::string peerid;
};
// returns pointer to static variable.
// which must be inited..
sslroot *getSSLRoot();
class sslroot
{
public:
sslroot();
int active();
int setcertdir(char *path);
int initssl(const char *srvr_cert, const char *priv_key,
const char *passwd);
int closessl();
/* Context handling */
SSL_CTX *getCTX();
/* Certificate handling */
int compareCerts(cert *a, cert *b);
// network interface.
// program interface.
int addCertificate(cert *c);
int addUntrustedCertificate(cert *c);
int addCollectedCertificate(cert *c);
int removeCertificate(cert *);
// Creation of Certificates.... (From X509)
// Core functions....
cert *checkDuplicateXPGP(XPGP *x);
cert *checkPeerXPGP(XPGP *x);
cert *makeCertificateXPGP(XPGP *c);
cert *registerCertificateXPGP(XPGP *nc, struct sockaddr_in, bool in);
int validateCertificateXPGP(cert *c);
/* Fns specific to XPGP */
int checkAuthCertificate(cert *xpgp);
int signCertificate(cert *);
int trustCertificate(cert *, bool totrust);
int superNodeMode();
int loadInitialTrustedPeer(std::string tp_file);
// depreciated...
cert *findpeercert(const char *name);
//int loadpeercert(const char *fname);
//int savepeercert(const char *fname);
// Configuration Handling...
int setConfigDirs(const char *cdir, const char *ndir);
// these save both the certificates + the settings.
int saveCertificates(const char *fname);
int saveCertificates();
int loadCertificates(const char *fname);
// with a hash check/recalc in there for good measure.
cert * loadcertificate(const char* fname, std::string hash);
int savecertificate(cert *c, const char* fname);
// for sending stuff as text
cert * loadCertFromString(std::string pem);
std::string saveCertAsString(cert *c);
// digest hashing /signing or encrypting interface.
int hashFile(std::string fname, unsigned char *hash, unsigned int hlen);
int hashDigest(char *data, unsigned int dlen, unsigned char *hash, unsigned int hlen);
int signDigest(EVP_PKEY *key, char *data, unsigned int dlen, unsigned char *hash, unsigned int hlen);
int verifyDigest(EVP_PKEY *key, char *data, unsigned int dlen, unsigned char *enc, unsigned int elen);
int generateKeyPair(EVP_PKEY *keypair, unsigned int keylen);
int printCertificate(cert *, std::ostream &out);
/* removing the list of certificate names - ambiguity!
*
std::list<std::string> listCertificates();
*
*/
std::list<cert *> &getCertList();
cert * getOwnCert();
int checkNetAddress();
// extra list for certs that aren't in main list.
cert * getCollectedCert();
bool collectedCerts();
bool CertsChanged();
bool CertsMajorChanged();
void IndicateCertsChanged();
std::string getSetting(std::string opt);
void setSetting(std::string opt, std::string val);
/* Fns for relating cert signatures to structures */
cert *findPeerId(std::string id);
cert *findcertsign(certsign &sign);
int getcertsign(cert *c, certsign &sign);
int addtosignmap(cert *);
private: /* data */
std::list<cert *> peercerts;
std::list<cert *> allcerts;
std::list<cert *> collectedcerts;
// whenever a cert is added, it should also be put in the map.
std::map<certsign, cert *> signmap;
// General Configuration System
// easy it put it here - so it can be signed easily.
std::map<std::string, std::string> settings;
std::string certdir;
std::string neighbourdir;
std::string certfile;
SSL_CTX *sslctx;
int init;
Indicator certsChanged;
Indicator certsMajorChanged;
EVP_PKEY *pkey;
cert *own_cert;
XPGP_KEYRING *pgp_keyring;
};
#endif // XPGPCERT_H

View File

@ -0,0 +1,876 @@
/*
* "$Id: filedexserver.cc,v 1.24 2007-05-05 16:10:06 rmf24 Exp $"
*
* Other Bits 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 "_server/filedexserver.h"
#include <fstream>
#include <time.h>
#include "_pqi/pqibin.h"
#include "_pqi/pqiarchive.h"
#include "_util/rsdebug.h"
#include "_util/rsdir.h"
#include <sstream>
#include <iomanip>
/* New FileCache Stuff */
#include "_server/ftfiler.h"
#include "_dbase/cachestrapper.h"
#include "_dbase/fimonitor.h"
#include "_dbase/fistore.h"
#include "_pqi/p3connmgr.h"
#include "_pqi/p3authmgr.h"
#include "_serialiser/rsserviceids.h"
#include "_serialiser/rsconfigitems.h"
#include <sstream>
const int fldxsrvrzone = 47659;
/****
#define SERVER_DEBUG 1
#define DEBUG_TICK 1
****/
filedexserver::filedexserver()
:p3Config(CONFIG_TYPE_FSERVER),
pqisi(NULL), mAuthMgr(NULL), mConnMgr(NULL),
save_dir("."),
mCacheStrapper(NULL), ftFiler(NULL), fiStore(NULL), fimon(NULL)
{
initialiseFileStore();
}
int filedexserver::setSearchInterface(P3Interface *si, p3AuthMgr *am, p3ConnectMgr *cm)
{
pqisi = si;
mAuthMgr = am;
mConnMgr = cm;
return 1;
}
std::list<RsFileTransfer *> filedexserver::getTransfers()
{
return ftFiler->getStatus();
}
int filedexserver::tick()
{
pqioutput(PQL_DEBUG_BASIC, fldxsrvrzone,
"filedexserver::tick()");
/* the new Cache Hack() */
FileStoreTick();
if (pqisi == NULL)
{
std::ostringstream out;
pqioutput(PQL_DEBUG_BASIC, fldxsrvrzone,
"filedexserver::tick() Invalid Interface()");
return 1;
}
int moreToTick = 0;
if (0 < pqisi -> tick())
{
moreToTick = 1;
#ifdef DEBUG_TICK
std::cerr << "filedexserver::tick() moreToTick from pqisi" << std::endl;
#endif
}
if (0 < handleInputQueues())
{
moreToTick = 1;
#ifdef DEBUG_TICK
std::cerr << "filedexserver::tick() moreToTick from InputQueues" << std::endl;
#endif
}
if (0 < handleOutputQueues())
{
moreToTick = 1;
#ifdef DEBUG_TICK
std::cerr << "filedexserver::tick() moreToTick from OutputQueues" << std::endl;
#endif
}
return moreToTick;
}
int filedexserver::status()
{
pqioutput(PQL_DEBUG_BASIC, fldxsrvrzone,
"filedexserver::status()");
if (pqisi == NULL)
{
pqioutput(PQL_DEBUG_BASIC, fldxsrvrzone,
"filedexserver::status() Invalid Interface()");
return 1;
}
pqisi -> status();
return 1;
}
std::string filedexserver::getSaveDir()
{
return save_dir;
}
void filedexserver::setSaveDir(std::string d)
{
save_dir = d;
if (ftFiler)
ftFiler -> setSaveBasePath(save_dir);
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
}
void filedexserver::setEmergencySaveDir(std::string s)
{
if (ftFiler)
{
ftFiler -> setEmergencyBasePath(s);
}
}
bool filedexserver::getSaveIncSearch()
{
return save_inc;
}
void filedexserver::setSaveIncSearch(bool v)
{
save_inc = v;
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
}
int filedexserver::addSearchDirectory(std::string dir)
{
dbase_dirs.push_back(dir);
reScanDirs();
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
return 1;
}
int filedexserver::removeSearchDirectory(std::string dir)
{
std::list<std::string>::iterator it;
for(it = dbase_dirs.begin(); (it != dbase_dirs.end())
&& (dir != *it); it++);
if (it != dbase_dirs.end())
{
dbase_dirs.erase(it);
}
reScanDirs();
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
return 1;
}
std::list<std::string> &filedexserver::getSearchDirectories()
{
return dbase_dirs;
}
int filedexserver::reScanDirs()
{
if (fimon)
fimon->setSharedDirectories(dbase_dirs);
return 1;
}
bool filedexserver::ConvertSharedFilePath(std::string path, std::string &fullpath)
{
if (fimon)
return fimon->convertSharedFilePath(path, fullpath);
return false;
}
void filedexserver::ForceDirectoryCheck()
{
if (fimon)
fimon->forceDirectoryCheck();
return;
}
bool filedexserver::InDirectoryCheck()
{
if (fimon)
return fimon->inDirectoryCheck();
return false;
}
/*************************************** NEW File Cache Stuff ****************************/
void filedexserver::initialiseFileStore()
{
}
const std::string LOCAL_CACHE_FILE_KEY = "LCF_NAME";
const std::string LOCAL_CACHE_HASH_KEY = "LCF_HASH";
const std::string LOCAL_CACHE_SIZE_KEY = "LCF_SIZE";
void filedexserver::setFileCallback(std::string ownId, CacheStrapper *strapper, ftfiler *ft, NotifyBase *cb)
{
mCacheStrapper = strapper;
ftFiler = ft;
/* setup FiStore/Monitor */
std::string localcachedir = config_dir + "/cache/local";
std::string remotecachedir = config_dir + "/cache/remote";
fiStore = new FileIndexStore(strapper, ftFiler, cb, ownId, remotecachedir);
/* now setup the FiMon */
fimon = new FileIndexMonitor(strapper, localcachedir, ownId);
/* setup ftFiler
* to find peer info / savedir
*/
FileHashSearch *fhs = new FileHashSearch(fiStore, fimon);
ftFiler -> setFileHashSearch(fhs);
ftFiler -> setSaveBasePath(save_dir);
/* now add the set to the cachestrapper */
CachePair cp(fimon, fiStore, CacheId(RS_SERVICE_TYPE_FILE_INDEX, 0));
mCacheStrapper -> addCachePair(cp);
return;
}
void filedexserver::StartupMonitor()
{
/* startup the FileMonitor (after cache load) */
fimon->setPeriod(600); /* 10 minutes */
/* start it up */
fimon->setSharedDirectories(dbase_dirs);
fimon->start();
std::list<RsFileTransfer *>::iterator tit;
for(tit = mResumeTransferList.begin();
tit != mResumeTransferList.end(); tit++)
{
RsFileTransfer *rsft = (*tit);
/* only add in ones which have a hash (filters old versions) */
if (rsft->file.hash != "")
{
ftFiler -> getFile(
rsft->file.name,
rsft->file.hash,
rsft->file.filesize, "");
}
delete rsft;
}
mResumeTransferList.clear();
}
int filedexserver::FileCacheSave()
{
/************ TMP HACK SAVE until new serialiser is finished */
RsPeerId pid;
std::map<CacheId, CacheData> ids;
std::map<CacheId, CacheData>::iterator it;
#ifdef SERVER_DEBUG
std::cerr << "filedexserver::FileCacheSave() listCaches:" << std::endl;
fimon->listCaches(std::cerr);
fimon->cachesAvailable(pid, ids);
#endif
std::string localCacheFile;
std::string localCacheHash;
std::string localCacheSize;
if (ids.size() == 1)
{
it = ids.begin();
localCacheFile = (it->second).name;
localCacheHash = (it->second).hash;
std::ostringstream out;
out << (it->second).size;
localCacheSize = out.str();
}
/* extract the details of the local cache */
//getSSLRoot()->setSetting(LOCAL_CACHE_FILE_KEY, localCacheFile);
//getSSLRoot()->setSetting(LOCAL_CACHE_HASH_KEY, localCacheHash);
//getSSLRoot()->setSetting(LOCAL_CACHE_SIZE_KEY, localCacheSize);
/************ TMP HACK SAVE until new serialiser is finished */
return 1;
}
// Transfer control.
void filedexserver::saveFileTransferStatus()
{
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
}
// Transfer control.
int filedexserver::getFile(std::string fname, std::string hash,
uint32_t size, std::string dest)
{
int ret = ftFiler -> getFile(fname, hash, size, dest);
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
return ret;
}
void filedexserver::clear_old_transfers()
{
ftFiler -> clearFailedTransfers();
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
}
void filedexserver::cancelTransfer(std::string fname, std::string hash, uint32_t size)
{
ftFiler -> cancelFile(hash);
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
}
int filedexserver::RequestDirDetails(std::string uid, std::string path,
DirDetails &details)
{
return fiStore->RequestDirDetails(uid, path, details);
}
int filedexserver::RequestDirDetails(void *ref, DirDetails &details, uint32_t flags)
{
return fiStore->RequestDirDetails(ref, details, flags);
}
int filedexserver::SearchKeywords(std::list<std::string> keywords,std::list<FileDetail> &results,uint32_t flags)
{
return fiStore->SearchKeywords(keywords, results,flags);
}
int filedexserver::SearchBoolExp(Expression * exp, std::list<FileDetail> &results)
{
return fiStore->searchBoolExp(exp, results);
}
int filedexserver::FileStoreTick()
{
ftFiler -> tick();
return 1;
}
// This function needs to be divided up.
int filedexserver::handleInputQueues()
{
// get all the incoming results.. and print to the screen.
RsCacheRequest *cr;
RsCacheItem *ci;
RsFileRequest *fr;
RsFileData *fd;
// Loop through Search Results.
int i = 0;
int i_init = 0;
//std::cerr << "filedexserver::handleInputQueues()" << std::endl;
while((ci = pqisi -> GetSearchResult()) != NULL)
{
//std::cerr << "filedexserver::handleInputQueues() Recvd SearchResult (CacheResponse!)" << std::endl;
std::ostringstream out;
if (i++ == i_init)
{
out << "Recieved Search Results:" << std::endl;
}
ci -> print(out);
pqioutput(PQL_DEBUG_BASIC, fldxsrvrzone, out.str());
/* these go to the CacheStrapper! */
CacheData data;
data.cid = CacheId(ci->cacheType, ci->cacheSubId);
data.hash = ci->file.hash;
data.size = ci->file.filesize;
data.name = ci->file.name;
data.path = ci->file.path;
data.pid = ci->PeerId();
data.pname = mAuthMgr->getName(ci->PeerId());
mCacheStrapper->recvCacheResponse(data, time(NULL));
delete ci;
}
// now requested Searches.
i_init = i;
while((cr = pqisi -> RequestedSearch()) != NULL)
{
/* just delete these */
std::ostringstream out;
out << "Requested Search:" << std::endl;
cr -> print(out);
pqioutput(PQL_DEBUG_BASIC, fldxsrvrzone, out.str());
delete cr;
}
// Now handle it replacement (pushed cache results)
{
std::list<std::pair<RsPeerId, CacheData> > cacheUpdates;
std::list<std::pair<RsPeerId, CacheData> >::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::ostringstream out2;
out2 << "Outgoing CacheStrapper Update -> RsCacheItem:" << std::endl;
ci -> print(out2);
std::cerr << out2.str() << std::endl;
#endif
//pqioutput(PQL_DEBUG_BASIC, fldxsrvrzone, out2.str());
pqisi -> SendSearchResult(ci);
}
}
// now File Input.
i_init = i;
while((fr = pqisi -> GetFileRequest()) != NULL )
{
#ifdef SERVER_DEBUG
std::cerr << "filedexserver::handleInputQueues() Recvd ftFiler Request" << std::endl;
std::ostringstream out;
if (i == i_init)
{
out << "Incoming(Net) File Item:" << std::endl;
}
fr -> print(out);
pqioutput(PQL_DEBUG_BASIC, fldxsrvrzone, out.str());
#endif
i++; /* count */
/* This bit is for debugging only! (not really needed) */
/* request */
ftFileRequest *ffr = new ftFileRequest(fr->PeerId(),
fr->file.hash, fr->file.filesize,
fr->fileoffset, fr->chunksize);
ftFiler->recvFileInfo(ffr);
delete fr;
}
// now File Data.
i_init = i;
while((fd = pqisi -> GetFileData()) != NULL )
{
#ifdef SERVER_DEBUG
//std::cerr << "filedexserver::handleInputQueues() Recvd ftFiler Data" << std::endl;
std::ostringstream out;
if (i == i_init)
{
out << "Incoming(Net) File Data:" << std::endl;
}
fd -> print(out);
pqioutput(PQL_DEBUG_BASIC, fldxsrvrzone, out.str());
#endif
i++; /* count */
/* incoming data */
ftFileData *ffd = new ftFileData(fd->PeerId(),
fd->fd.file.hash, fd->fd.file.filesize,
fd->fd.file_offset,
fd->fd.binData.bin_len,
fd->fd.binData.bin_data, FT_FILEDATA_FLAG_NOFREE);
ftFiler->recvFileInfo(ffd);
delete fd;
}
if (i > 0)
{
return 1;
}
return 0;
}
// This function needs to be divided up.
int filedexserver::handleOutputQueues()
{
// get all the incoming results.. and print to the screen.
//std::cerr << "filedexserver::handleOutputQueues()" << std::endl;
int i = 0;
/* now see if the filer has any data */
ftFileRequest *ftr;
while((ftr = ftFiler -> sendFileInfo()) != NULL)
{
//std::cerr << "filedexserver::handleOutputQueues() ftFiler Data for: " << ftr->id << std::endl;
/* decide if its data or request */
ftFileData *ftd = dynamic_cast<ftFileData *>(ftr);
if (ftd)
{
SendFileData(ftd, ftr->id);
}
else
{
SendFileRequest(ftr, ftr->id);
}
std::ostringstream out;
if (i++ == 0)
{
out << "Outgoing filer -> PQFileItem:" << std::endl;
}
pqioutput(PQL_DEBUG_BASIC, fldxsrvrzone, out.str());
/* clean up */
delete ftr;
}
if (i > 0)
{
return 1;
}
return 0;
}
void filedexserver::SendFileRequest(ftFileRequest *ftr, std::string pid)
{
RsFileRequest *rfi = new RsFileRequest();
/* id */
rfi->PeerId(pid);
/* file info */
rfi->file.filesize = ftr->size;
rfi->file.hash = ftr->hash;
/* offsets */
rfi->fileoffset = ftr->offset;
rfi->chunksize = ftr->chunk;
pqisi -> SendFileRequest(rfi);
}
#define MAX_FT_CHUNK 4096
void filedexserver::SendFileData(ftFileData *ftd, std::string pid)
{
uint32_t tosend = ftd->chunk;
uint32_t baseoffset = ftd->offset;
uint32_t offset = 0;
uint32_t chunk;
while(tosend > 0)
{
/* workout size */
chunk = MAX_FT_CHUNK;
if (chunk > tosend)
{
chunk = tosend;
}
/******** New Serialiser Type *******/
RsFileData *rfd = new RsFileData();
/* set id */
rfd->PeerId(pid);
/* file info */
rfd->fd.file.filesize = ftd->size;
rfd->fd.file.hash = ftd->hash;
rfd->fd.file.name = ""; /* blank other data */
rfd->fd.file.path = "";
rfd->fd.file.pop = 0;
rfd->fd.file.age = 0;
rfd->fd.file_offset = baseoffset + offset;
/* file data */
rfd->fd.binData.setBinData(
&(((uint8_t *) ftd->data)[offset]), chunk);
pqisi -> SendFileData(rfd);
offset += chunk;
tosend -= chunk;
}
}
/***************************************************************************/
/****************************** CONFIGURATION HANDLING *********************/
/***************************************************************************/
/**** OVERLOADED FROM p3Config ****/
static const std::string fdex_dir("FDEX_DIR");
static const std::string save_dir_ss("SAVE_DIR");
static const std::string save_inc_ss("SAVE_INC");
RsSerialiser *filedexserver::setupSerialiser()
{
RsSerialiser *rss = new RsSerialiser();
/* add in the types we need! */
rss->addSerialType(new RsFileConfigSerialiser());
rss->addSerialType(new RsGeneralConfigSerialiser());
return rss;
}
std::list<RsItem *> filedexserver::saveList(bool &cleanup)
{
std::list<RsItem *> saveData;
/* it can delete them! */
cleanup = true;
/* create a key/value set for most of the parameters */
std::map<std::string, std::string> configMap;
std::map<std::string, std::string>::iterator mit;
std::list<std::string>::iterator it;
pqioutput(PQL_DEBUG_BASIC, fldxsrvrzone,
"fildexserver::save_config()");
/* basic control parameters */
configMap[save_dir_ss] = getSaveDir();
if (getSaveIncSearch())
{
configMap[save_inc_ss] = "true";
}
else
{
configMap[save_inc_ss] = "false";
}
int i;
for(it = dbase_dirs.begin(), i = 0; (it != dbase_dirs.end())
&& (i < 1000); it++, i++)
{
std::string name = fdex_dir;
int d1, d2, d3;
d1 = i / 100;
d2 = (i - d1 * 100) / 10;
d3 = i - d1 * 100 - d2 * 10;
name += '0'+d1;
name += '0'+d2;
name += '0'+d3;
configMap[name] = (*it);
}
RsConfigKeyValueSet *rskv = new RsConfigKeyValueSet();
/* Convert to TLV */
for(mit = configMap.begin(); mit != configMap.end(); mit++)
{
RsTlvKeyValue kv;
kv.key = mit->first;
kv.value = mit->second;
rskv->tlvkvs.pairs.push_back(kv);
}
/* Add KeyValue to saveList */
saveData.push_back(rskv);
std::list<RsFileTransfer *>::iterator fit;
std::list<RsFileTransfer *> ftlist = ftFiler -> getStatus();
for(fit = ftlist.begin(); fit != ftlist.end(); fit++)
{
/* only write out the okay/uncompleted (with hash) files */
if (((*fit)->state == FT_STATE_FAILED) ||
((*fit)->state == FT_STATE_COMPLETE) ||
((*fit)->in == false) ||
((*fit)->file.hash == ""))
{
/* ignore */
/* cleanup */
delete(*fit);
}
else
{
saveData.push_back(*fit);
}
}
/* list completed! */
return saveData;
}
bool filedexserver::loadList(std::list<RsItem *> load)
{
std::list<RsItem *>::iterator it;
std::list<RsTlvKeyValue>::iterator kit;
RsConfigKeyValueSet *rskv;
RsFileTransfer *rsft;
#ifdef SERVER_DEBUG
std::cerr << "filedexserver::loadList() Item Count: " << load.size();
std::cerr << std::endl;
#endif
for(it = load.begin(); it != load.end(); it++)
{
/* switch on type */
if (NULL != (rskv = dynamic_cast<RsConfigKeyValueSet *>(*it)))
{
/* make into map */
std::map<std::string, std::string> configMap;
for(kit = rskv->tlvkvs.pairs.begin();
kit != rskv->tlvkvs.pairs.end(); kit++)
{
configMap[kit->key] = kit->value;
}
loadConfigMap(configMap);
/* cleanup */
delete (*it);
}
else if (NULL != (rsft = dynamic_cast<RsFileTransfer *>(*it)))
{
/* save to the preLoad list */
mResumeTransferList.push_back(rsft);
}
else
{
/* cleanup */
delete (*it);
}
}
return true;
}
bool filedexserver::loadConfigMap(std::map<std::string, std::string> &configMap)
{
std::map<std::string, std::string>::iterator mit;
int i;
std::string str_true("true");
std::string empty("");
std::string dir = "notempty";
if (configMap.end() != (mit = configMap.find(save_dir_ss)))
{
setSaveDir(mit->second);
}
if (configMap.end() != (mit = configMap.find(save_inc_ss)))
{
setSaveIncSearch(mit->second == str_true);
}
dbase_dirs.clear();
for(i = 0; (i < 1000) && (dir != empty); i++)
{
std::string name = fdex_dir;
int d1, d2, d3;
d1 = i / 100;
d2 = (i - d1 * 100) / 10;
d3 = i - d1 * 100 - d2 * 10;
name += '0'+d1;
name += '0'+d2;
name += '0'+d3;
if (configMap.end() != (mit = configMap.find(name)))
{
dir = mit->second;
dbase_dirs.push_back(mit->second);
}
}
if (dbase_dirs.size() > 0)
{
std::ostringstream out;
out << "Loading " << dbase_dirs.size();
out << " Directories" << std::endl;
pqioutput(PQL_DEBUG_BASIC, fldxsrvrzone, out.str());
reScanDirs();
}
return true;
}

View File

@ -0,0 +1,177 @@
/*
* "$Id: filedexserver.h,v 1.18 2007-05-05 16:10:06 rmf24 Exp $"
*
* Other Bits 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 FILEDEXSERVER_H
#define FILEDEXSERVER_H
/*
* Slightly more complete server....
* has a filedex pointer, which manages the local indexing/searching.
*
*/
#include "_pqi/pqi.h"
#include "_pqi/pqiindic.h"
#include "_serialiser/rsconfigitems.h"
#include <map>
#include <deque>
#include <list>
#include <map>
#include <iostream>
#include "_rsiface/rsiface.h"
#include "_pqi/p3cfgmgr.h"
class p3ConnectMgr;
class p3AuthMgr;
class CacheStrapper;
class ftfiler;
class FileIndexStore;
class FileIndexMonitor;
class ftFileRequest;
class ftFileData;
class Expression;
#define MAX_RESULTS 100 // nice balance between results and traffic.
class filedexserver: public p3Config
{
public:
filedexserver();
void loadWelcomeMsg(); /* startup message */
int setSearchInterface(P3Interface *si, p3AuthMgr *am, p3ConnectMgr *cm);
std::list<RsFileTransfer *> getTransfers();
void saveFileTransferStatus();
int getFile(std::string fname, std::string hash,
uint32_t size, std::string dest);
void clear_old_transfers();
void cancelTransfer(std::string fname, std::string hash, uint32_t size);
// access to search info is also required.
bool ConvertSharedFilePath(std::string path, std::string &fullpath);
void ForceDirectoryCheck();
bool InDirectoryCheck();
std::list<std::string> &getSearchDirectories();
int addSearchDirectory(std::string dir);
int removeSearchDirectory(std::string dir);
int reScanDirs();
int check_dBUpdate();
std::string getSaveDir();
void setSaveDir(std::string d);
void setEmergencySaveDir(std::string s);
void setConfigDir(std::string d) { config_dir = d; }
bool getSaveIncSearch();
void setSaveIncSearch(bool v);
int tick();
int status();
private:
int handleInputQueues();
int handleOutputQueues();
std::list<std::string> dbase_dirs;
P3Interface *pqisi;MRK_PQI_FILEDEX_SERVER_HEADER
p3AuthMgr *mAuthMgr;
p3ConnectMgr *mConnMgr;
std::string config_dir;
std::string save_dir;
bool save_inc; // is savedir include in share list.
public:
/* some more switches (here for uniform saving) */
int getDHTEnabled() const { return DHTState; }
int getUPnPEnabled() const { return UPnPState; }
void setDHTEnabled(int i) { DHTState = i; }
void setUPnPEnabled(int i) { UPnPState = i; }
private:
int DHTState;
int UPnPState;
/*************************** p3 Config Overload ********************/
protected:
/* Key Functions to be overloaded for Full Configuration */
virtual RsSerialiser *setupSerialiser();
virtual std::list<RsItem *> saveList(bool &cleanup);
virtual bool loadList(std::list<RsItem *> load);
private:
bool loadConfigMap(std::map<std::string, std::string> &configMap);
/*************************** p3 Config Overload ********************/
/* new FileCache stuff */
public:
int FileStoreTick();
int FileCacheSave();
/* Setup */
void initialiseFileStore();
void setFileCallback(std::string ownId, CacheStrapper *strapper,
ftfiler *ft, NotifyBase *cb);
void StartupMonitor();
/* Controls */
int RequestDirDetails(std::string uid, std::string path, DirDetails &details);
int RequestDirDetails(void *ref, DirDetails &details, uint32_t flags);
int SearchKeywords(std::list<std::string> keywords, std::list<FileDetail> &results);
int SearchBoolExp(Expression * exp, std::list<FileDetail> &results);
private:
void SendFileRequest(ftFileRequest *ftr, std::string pid);
void SendFileData(ftFileData *ftd, std::string pid);
CacheStrapper *mCacheStrapper;
ftfiler *ftFiler;
FileIndexStore *fiStore;
FileIndexMonitor *fimon;
/* Temp Transfer List (for loading config) */
std::list<RsFileTransfer *> mResumeTransferList;
};
#endif // FILEDEXSERVER_H

View File

@ -0,0 +1,162 @@
/*
* "$Id: pqifiler.cc,v 1.13 2007-02-19 20:08:30 rmf24 Exp $"
*
* Other Bits 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 "_server/ft.h"
/****
* #define FT_DEBUG 1
***/
ftFileRequest::ftFileRequest(std::string id_in, std::string hash_in,
uint64_t size_in, uint64_t offset_in,
uint32_t chunk_in) :
id(id_in),
hash(hash_in),
size(size_in),
offset(offset_in),
chunk(chunk_in)
{
}
ftFileData::ftFileData(std::string id_in, std::string hash_in, uint64_t size_in,
uint64_t offset_in, uint32_t chunk_in, void *data_in,
uint32_t flags):
ftFileRequest(id_in, hash_in,
size_in, offset_in,
chunk_in),
data(data_in),
ftFlags(flags)
{
}
ftFileData::~ftFileData()
{
// CHANGED : CODE_SIMPLIFIED
if( !(ftFlags & FT_FILEDATA_FLAG_NOFREE) && data)
free(data);
data = NULL;
// if (ftFlags & FT_FILEDATA_FLAG_NOFREE)
// {
// /* don't free */
// }
// else
// {
// if (data)
// {
// free(data);
// }
// }
// data = NULL;
}
bool ftManager::lookupLocalHash(std::string hash, std::string &path, uint64_t &size)
{
std::list<FileDetail> details;
#ifdef FT_DEBUG
std::cerr << "ftManager::lookupLocalHash() hash: " << hash << std::endl;
#endif
if (FindCacheFile(hash, path, size))
{
/* got it from the CacheTransfer() */
#ifdef FT_DEBUG
std::cerr << "ftManager::lookupLocalHash() Found in CacheStrapper:";
std::cerr << path << " size: " << size << std::endl;
#endif
return true;
}
bool ok = false;
if (fhs)
{
ok = (0 != fhs -> searchLocalHash(hash, path, size));
}
else
{
#ifdef FT_DEBUG
std::cerr << "Warning FileHashSearch is Invalid" << std::endl;
#endif
}
if (ok)
{
#ifdef FT_DEBUG
std::cerr << "ftManager::lookupLocalHash() Found in FileHashSearch:";
std::cerr << path << " size: " << size << std::endl;
#endif
return true;
}
return ok;
}
bool ftManager::lookupRemoteHash(std::string hash, std::list<std::string> &ids)
{
std::list<FileDetail> details;
std::list<FileDetail>::iterator it;
#ifdef FT_DEBUG
std::cerr << "ftManager::lookupRemoteHash() hash: " << hash << std::endl;
#endif
if (fhs)
{
fhs -> searchRemoteHash(hash, details);
}
else
{
#ifdef FT_DEBUG
std::cerr << "Warning FileHashSearch is Invalid" << std::endl;
#endif
}
if (details.size() == 0)
{
#ifdef FT_DEBUG
std::cerr << "ftManager::lookupRemoteHash() Not Found!" << std::endl;
#endif
return false;
}
for(it = details.begin(); it != details.end(); it++)
{
#ifdef FT_DEBUG
std::cerr << "ftManager::lookupRemoteHash() Found in FileHashSearch:";
std::cerr << " id: " << it->id << std::endl;
#endif
ids.push_back(it->id);
}
return true;
}

View File

@ -0,0 +1,140 @@
/*
* "$Id: ftManager.h,v 1.13 2007-02-19 20:08:30 rmf24 Exp $"
*
* Other Bits 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 FT_H
#define FT_H
/*
* ftManager - virtual base class for FileTransfer
*/
#include <list>
#include <iostream>
#include <string>
#include "_pqi/pqi.h"
#include "_serialiser/rsconfigitems.h"
#include "_dbase/cachestrapper.h"
#include "_server/hashsearch.h"
class ftFileManager; /* stores files */
class ftFileRequest
{
public:
ftFileRequest(std::string id_in, std::string hash_in,
uint64_t size_in, uint64_t offset_in,
uint32_t chunk_in);
virtual ~ftFileRequest() { }
std::string id;
std::string hash;
uint64_t size;
uint64_t offset;
uint32_t chunk;
};
const uint32_t FT_FILEDATA_FLAG_NOFREE = 0x01;
class ftFileData: public ftFileRequest
{
public:
ftFileData(std::string id_in, std::string hash_in,
uint64_t size_in, uint64_t offset_in,
uint32_t chunk_in, void *data_in, uint32_t flags);
virtual ~ftFileData();
void *data;
uint32_t ftFlags;
};
class ftManager: public CacheTransfer
{
public:
ftManager(CacheStrapper *cs)
:CacheTransfer(cs), fhs(NULL) { return; }
virtual ~ftManager() { return; }
void setFileHashSearch(FileHashSearch *hs) { fhs = hs; }
/****************** PART to be IMPLEMENTE******************/
/* Functions to implement */
/*********** overloaded from CacheTransfer ***************/
/* Must callback after this fn - using utility functions */
//virtual bool RequestCacheFile(RsPeerId id, std::string path,
// std::string hash, uint64_t size);
/******************* GUI Interface ************************/
virtual int getFile(std::string name, std::string hash,
uint64_t size, std::string destpath) = 0;
virtual int cancelFile(std::string hash) = 0;
virtual int clearFailedTransfers() = 0;
virtual int tick() = 0;
virtual std::list<RsFileTransfer *> getStatus() = 0;
/************* Network Interface****************************/
public:
virtual void setSaveBasePath(std::string s) = 0;
virtual void setEmergencyBasePath(std::string s) = 0;
virtual int recvFileInfo(ftFileRequest *in) = 0;
virtual ftFileRequest * sendFileInfo() = 0;
protected:
/****************** UTILITY FUNCTIONS ********************/
/* combines two lookup functions */
bool lookupLocalHash(std::string hash, std::string &path, uint64_t &size);
bool lookupRemoteHash(std::string hash, std::list<std::string> &ids);
/*********** callback from CacheTransfer ***************/
//bool CompletedCache(std::string hash); /* internal completion -> does cb */
//bool FailedCache(std::string hash); /* internal completion -> does cb */
/*********** available from CacheTransfer ***************/
/* upload side of things .... searches through CacheStrapper(Sources) for a cache. */
//bool FindCacheFile(std::string id, std::string hash, std::string &path);
/*********** available from CacheTransfer ***************/
private:
FileHashSearch *fhs;
};
#endif // FT_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,232 @@
/*
* "$Id: ftfiler.h,v 1.5 2007-02-19 20:08:30 rmf24 Exp $"
*
* Other Bits 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 FTFILER_H
#define FTFILER_H
/*
* PQI Filer
*
* This managers the file transfers.
*
*/
#include "_server/ft.h"
#include "_pqi/pqi.h"
#include <list>
#include <iostream>
#include <string>
const int PQIFILE_INIT = 0x0000;
const int PQIFILE_NOT_ONLINE = 0x0001;
const int PQIFILE_DOWNLOADING = 0x0002;
const int PQIFILE_COMPLETE = 0x0004;
const int PQIFILE_FAIL = 0x0010;
/* reasons for DOWNLOAD FAILURE (2nd byte) */
const int PQIFILE_FAIL_CANCEL = 0x0100;
const int PQIFILE_FAIL_NOT_AVAIL = 0x0200;
const int PQIFILE_FAIL_NOT_OPEN = 0x0400;
const int PQIFILE_FAIL_NOT_SEEK = 0x0800;
const int PQIFILE_FAIL_NOT_WRITE = 0x1000;
const int PQIFILE_FAIL_NOT_READ = 0x2000;
const int PQIFILE_FAIL_BAD_PATH = 0x4000;
const int TRANSFER_MODE_TRICKLE = 1;
const int TRANSFER_MODE_NORMAL = 2;
const int TRANSFER_MODE_FAST = 3;
const uint32_t FT_MODE_STD = 1;
const uint32_t FT_MODE_CACHE = 2;
const uint32_t FT_MODE_UPLOAD = 4;
class ftFileStatus
{
public:
/****
ftFileStatus(PQFileItem *in)
:fileItem(in), status(PQIFILE_INIT), fd(NULL),
total_size(0), recv_size(0),
req_loc(0), req_size(0), lastTS(0)
{
return;
}
****/
ftFileStatus(const std::string& name_in, const std::string& hash_in, uint64_t size_in,
const std::string& destpath_in, uint32_t mode_in)
:name(name_in), hash(hash_in), destpath(destpath_in), size(size_in), ftMode(mode_in),
status(PQIFILE_INIT), mode(0), rate(0), fd(NULL), total_size(0), recv_size(0),
req_loc(0), req_size(0), lastTS(0), lastDelta(0),file_name(""),id("")
{
/* not set ...
* id,
* filename,
* sources
*/
return;
}
ftFileStatus(const std::string& id_in, const std::string& name_in, const std::string& hash_in, uint64_t size_in,
const std::string& destpath_in, uint32_t mode_in)
:id(id_in), name(name_in), hash(hash_in), destpath(destpath_in), size(size_in), ftMode(mode_in),
status(PQIFILE_INIT), mode(0), rate(0), fd(NULL), total_size(0), recv_size(0),
req_loc(0), req_size(0), lastTS(0), lastDelta(0),file_name("")
{
/* not set ...
* id,
* filename,
* sources
*/
return;
}
~ftFileStatus()
{
if (fd)
fclose(fd);
}
/* data */
std::string id; /* current source / most recent destination */
std::string name;
std::string hash;
std::string destpath;
uint64_t size;
/* new stuff */
uint32_t ftMode;
std::list<std::string> sources;
uint32_t resetCount;
/* transfer inprogress or not */
int status;
int mode;
float rate;
std::string file_name;
FILE *fd;
uint64_t total_size;
/* this is the simplistic case where only inorder data
* otherwise - need much more status info */
uint64_t recv_size;
/* current file data request / most recent request answered (upload) */
uint64_t req_loc;
uint32_t req_size;
/* timestamp */
time_t lastTS; /* last request / request answered (upload) */
uint32_t lastDelta; /* send til all recved */
};
class ftfiler: public ftManager
{
public:
ftfiler(CacheStrapper *cs)
:ftManager(cs) { return; }
virtual ~ftfiler() { return; }
virtual bool RequestCacheFile(std::string id, std::string path,
std::string hash, uint64_t size);
virtual bool CancelCacheFile(RsPeerId id, std::string path,
std::string hash, uint64_t size);
virtual int getFile(std::string name, std::string hash,
uint64_t size, std::string destpath);
virtual int cancelFile(std::string hash);
virtual int clearFailedTransfers();
int tick();
std::list<RsFileTransfer *> getStatus();
virtual void setSaveBasePath(std::string s);
virtual void setEmergencyBasePath(std::string s);
/************* Network Interface****************************/
virtual int recvFileInfo(ftFileRequest *in);
virtual ftFileRequest *sendFileInfo();
private:
virtual int handleFileError(std::string hash, uint32_t err);
virtual int handleFileNotOnline(std::string hash);
virtual int handleFileNotAvailable(std::string hash);
virtual int handleFileData(std::string hash, uint64_t offset,
void *data, uint32_t size);
virtual int handleFileRequest( std::string id, std::string hash,
uint64_t offset, uint32_t chunk);
virtual int handleFileCacheRequest(std::string id, std::string hash,
uint64_t offset, uint32_t chunk);
ftFileStatus *findRecvFileItem(std::string hash);
void queryInactive();
/**************** End of Interface *************************/
int requestData(ftFileStatus *item);
/************* PQIFILEITEM Generator ***************************
*/
ftFileStatus *createFileCache(std::string hash);
ftFileRequest *generateFileRequest(ftFileStatus *);
int generateFileData(ftFileStatus *s, std::string id, uint64_t offset, uint32_t size);
//int sendFileNotAvail(PQFileItem *req);
/************* FILE DATA HANDLING ******************************
*/
std::string determineTmpFilePath(ftFileStatus *s);
std::string determineDestFilePath(ftFileStatus *s);
int initiateFileTransfer(ftFileStatus *s);
int resetFileTransfer(ftFileStatus *s);
int addFileData(ftFileStatus *s, uint64_t idx, void *data, uint32_t size);
int completeFileTransfer(ftFileStatus *s);
// Data.
private:
std::list<ftFileStatus *> recvFiles;
std::list<ftFileStatus *> fileCache;
std::list<ftFileRequest *> out_queue;
std::string saveBasePath;
std::string mEmergencyIncomingDir;
};
#endif // FTFILER_H

View File

@ -0,0 +1,51 @@
/*
* "$Id: hashsearch.cc,v 1.5 2007-02-19 20:08:30 rmf24 Exp $"
*
* Other Bits 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".
*
*/
/**********
* SearchInterface for the FileTransfer
*/
#include "_server/hashsearch.h"
#include "_dbase/fistore.h"
#include "_dbase/fimonitor.h"
/* Search Interface - For FileTransfer Lookup */
int FileHashSearch::searchLocalHash(std::string hash, std::string &path, uint64_t &size)
{
if (monitor)
{
return monitor->findLocalFile(hash, path, size);
}
return 0;
}
int FileHashSearch::searchRemoteHash(std::string hash, std::list<FileDetail> &results)
{
if (store)
store->SearchHash(hash, results);
return results.size();
}

View File

@ -0,0 +1,61 @@
/*
* "$Id: hashsearch.h,v 1.5 2007-02-19 20:08:30 rmf24 Exp $"
*
* Other Bits 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 HASHSEARCH_H
#define HASHSEARCH_H
/**********
* SearchInterface for the FileTransfer
*/
#include "rsiface/rstypes.h"
class FileIndexStore;
class FileIndexMonitor;
#include "dbase/fistore.h"
#include "dbase/fimonitor.h"
class FileHashSearch
{
public:
FileHashSearch(FileIndexStore *s, FileIndexMonitor *m)
:store(s), monitor(m) { return; }
~FileHashSearch() { return; }
/* Search Interface - For FileTransfer Lookup */
int searchLocalHash(std::string hash, std::string &path, uint64_t &size);
int searchRemoteHash(std::string hash, std::list<FileDetail> &results);
private:
FileIndexStore *store;
FileIndexMonitor *monitor;
};
#endif // HASHSEARCH_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,183 @@
/*
* "$Id: pqifiler.h,v 1.5 2007-02-19 20:08:30 rmf24 Exp $"
*
* Other Bits 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 PQIFILER_H
#define PQIFILER_H
/*
* PQI Filer
*
* This managers the file transfers.
*
*/
#include "_pqi/pqi.h"
#include "_dbase/filelook.h"
#include "_dbase/filedex.h"
#include <list>
#include <iostream>
#include <string>
const int PQIFILE_INIT = 0x0000;
const int PQIFILE_NOT_ONLINE = 0x0001;
const int PQIFILE_DOWNLOADING = 0x0002;
const int PQIFILE_COMPLETE = 0x0004;
const int PQIFILE_FAIL = 0x0010;
/* reasons for DOWNLOAD FAILURE (2nd byte) */
const int PQIFILE_FAIL_CANCEL = 0x0100;
const int PQIFILE_FAIL_NOT_AVAIL = 0x0200;
const int PQIFILE_FAIL_NOT_OPEN = 0x0400;
const int PQIFILE_FAIL_NOT_SEEK = 0x0800;
const int PQIFILE_FAIL_NOT_WRITE = 0x1000;
const int PQIFILE_FAIL_NOT_READ = 0x2000;
const int PQIFILE_FAIL_BAD_PATH = 0x4000;
const int TRANSFER_MODE_TRICKLE = 1;
const int TRANSFER_MODE_NORMAL = 2;
const int TRANSFER_MODE_FAST = 3;
class PQFileStatus
{
public:
PQFileStatus(PQFileItem *in):
fileItem(in), status(PQIFILE_INIT), fd(NULL),
total_size(0), recv_size(0),
req_loc(0), req_size(0), lastTS(0) {}
~PQFileStatus()
{
if (fileItem)
delete fileItem;
if (fd)
fclose(fd);
}
/* data */
PQFileItem *fileItem;
/* transfer inprogress or not */
int status;
int mode;
float rate;
std::string file_name;
FILE *fd;
long total_size;
/* this is the simplistic case where only inorder data
* otherwise - need much more status info */
long recv_size;
/* current file data request */
long req_loc;
int req_size;
/* timestamp */
long lastTS;
int lastDelta; /* send til all recved */
};
class pqifiler
{
public:
#ifdef USE_FILELOOK
pqifiler(fileLook*);
#else
pqifiler(filedex*);
#endif
virtual ~pqifiler() { return; }
/******************* GUI Interface *************************
*/
int getFile(PQFileItem *in);
int cancelFile(PQFileItem *i);
int clearFailedTransfers();
int tick();
std::list<FileTransferItem *> getStatus();
/************* Network Interface****************************
*/
PQItem * sendPQFileItem();
int recvPQFileItem(PQItem *in);
void setSavePath(std::string s) { savePath = s;}
private:
PQFileStatus *findRecvFileItem(PQFileItem *in);
void queryInactive();
int handleFileError(PQFileItem *in);
int handleFileNotOnline(PQFileItem *in);
int handleFileNotAvailable(PQFileItem *in);
int handleFileData(PQFileItem *in);
int handleFileRequest(PQFileItem *in);
int handleFileCacheRequest(PQFileItem *req);
int requestData(PQFileStatus *item);
/************* PQIFILEITEM Generator ***************************
*/
PQFileStatus * createFileCache(PQFileItem *in);
PQFileItem * generatePQFileRequest(PQFileStatus *);
int generateFileData(PQFileStatus *s, PQFileItem *req);
int sendFileNotAvail(PQFileItem *req);
/************* FILE DATA HANDLING ******************************
*/
std::string determineFilePath(PQFileItem *item);
int initiateFileTransfer(PQFileStatus *s);
int resetFileTransfer(PQFileStatus *s);
int addFileData(PQFileStatus *s, long idx, void *data, int size);
// Data.
private:
std::list<PQFileStatus *> recvFiles;
std::list<PQFileStatus *> fileCache;
std::list<PQItem *> out_queue;
#ifdef USE_FILELOOK
fileLook *fileIndex;
#else
filedex *fileIndex;
#endif
std::string savePath;
};
#endif // PQIFILER_H

View File

@ -0,0 +1,14 @@
INCLUDEPATH += $$PWD \
../$$PWP
DEPENDPATH += $$PWD
HEADERS = filedexserver.h \
ft.h \
ftfiler.h \
hashsearch.h \
pqifiler.h
SOURCES = filedexserver.cc \
ft.cc \
ftfiler.cc \
hashsearch.cc \
pqifiler.cc

View File

@ -0,0 +1,362 @@
#include "pqi/p3connmgr.h"
/***** Test for the new DHT system *****/
#include "util/rsnet.h"
#include "util/rsthreads.h"
#include "util/rsprint.h"
#include "pqi/p3dhtmgr.h"
#include "pqi/p3connmgr.h"
#include "pqi/pqisecurity.h"
#include "pqi/pqipersongrp.h"
#include <iostream>
#include <sstream>
#include "tcponudp/udpsorter.h"
/***** Test Framework *****/
const int NumOfPeers = 10;
std::string peerIds[NumOfPeers] =
{"PEER01",
"PEER02", /* Always online, no notify */
"PEER03", /* notify/online at 20sec */
"PEER04", /* Always online, notify at 30 sec */
"PEER05",
"PEER06", /* notify/online at 50sec */
"PEER07",
"PEER08",
"PEER09", /* notify/online at 80sec */
"PEER10"};
#define STUN_PORT 7777
std::string ownId = "OWNID-AAAA";
time_t ownPublishTs;
RsMutex frmMtx;
std::list<std::string> searchIds;
std::list<uint32_t> searchModes;
std::map<std::string, bool> onlineMap;
std::map<uint32_t, std::string> notifyMap;
void initTestData()
{
ownPublishTs = 0;
/* setup Peers that are online always */
bool online;
uint32_t ts;
for(int i = 0; i < NumOfPeers; i++)
{
online = false;
if ((i == 1) || (i == 3))
{
online = true;
}
onlineMap[peerIds[i]] = online;
if ((i == 2) || (i == 3) ||
(i == 5) || (i == 8))
{
ts = i * 10;
notifyMap[ts] = peerIds[i];
}
}
}
void respondPublish()
{
frmMtx.lock(); /* LOCK TEST FRAMEWORK MUTEX */
if (!ownPublishTs)
{
std::cerr << "Own ID first published!" << std::endl;
ownPublishTs = time(NULL);
}
frmMtx.unlock(); /* UNLOCK TEST FRAMEWORK MUTEX */
}
void respondSearch(p3DhtMgr *mgr, std::string id, uint32_t mode)
{
std::cerr << "Checking for Search Results" << std::endl;
time_t now = time(NULL);
bool doNotify = false;
bool doOnline = false;
std::string notifyId;
frmMtx.lock(); /* LOCK TEST FRAMEWORK MUTEX */
if ((mode == DHT_MODE_NOTIFY) && (ownPublishTs))
{
/* */
std::map<uint32_t, std::string>::iterator it;
uint32_t delta_t = now - ownPublishTs;
it = notifyMap.begin();
if (it != notifyMap.end())
{
if (it->first <= delta_t)
{
notifyId = it->second;
onlineMap[notifyId] = true;
notifyMap.erase(it);
doNotify = true;
}
}
}
else if (mode == DHT_MODE_SEARCH)
{
/* translate */
std::map<std::string, bool>::iterator mit;
for(mit = onlineMap.begin(); (mit != onlineMap.end()) &&
(RsUtil::HashId(mit->first, false) != id); mit++);
if (mit != onlineMap.end())
{
doOnline = mit->second;
}
}
frmMtx.unlock(); /* UNLOCK TEST FRAMEWORK MUTEX */
uint32_t type = 0;
struct sockaddr_in laddr;
inet_aton("10.0.0.129", &(laddr.sin_addr));
laddr.sin_port = htons(7812);
laddr.sin_family = AF_INET;
struct sockaddr_in raddr;
inet_aton("127.0.0.1", &(raddr.sin_addr));
raddr.sin_port = htons(STUN_PORT);
raddr.sin_family = AF_INET;
if (doNotify)
{
std::cerr << "Responding to Notify: id:" << notifyId << std::endl;
mgr->dhtResultNotify(RsUtil::HashId(notifyId, true));
}
if (doOnline)
{
std::cerr << "Responding to Search" << std::endl;
mgr->dhtResultSearch(id, laddr, raddr, type, "");
}
}
/***** Test Framework *****/
class DhtMgrTester: public p3DhtMgr
{
/* Implementation */
public:
DhtMgrTester(std::string id, pqiConnectCb *cb)
:p3DhtMgr(id, cb)
{
return;
}
/* Blocking calls (only from thread) */
virtual bool dhtPublish(std::string id,
struct sockaddr_in &laddr, struct sockaddr_in &raddr,
uint32_t type, std::string sign)
{
std::cerr << "DhtMgrTester::dhtPublish() id: " << RsUtil::BinToHex(id);
std::cerr << " laddr: " << inet_ntoa(laddr.sin_addr) << " lport: " << ntohs(laddr.sin_port);
std::cerr << " raddr: " << inet_ntoa(raddr.sin_addr) << " rport: " << ntohs(raddr.sin_port);
std::cerr << " type: " << type << " sign: " << sign;
std::cerr << std::endl;
respondPublish();
return true;
}
virtual bool dhtNotify(std::string peerid, std::string ownid, std::string sign)
{
std::cerr << "DhtMgrTester::dhtNotify() id: " << RsUtil::BinToHex(peerid) << ", ownId: " << RsUtil::BinToHex(ownId);
std::cerr << " sign: " << sign;
std::cerr << std::endl;
return true;
}
virtual bool dhtSearch(std::string id, uint32_t mode)
{
std::cerr << "DhtMgrTester::dhtSearch(id: " << RsUtil::BinToHex(id) << ", mode: " << mode << ")" << std::endl;
frmMtx.lock(); /* LOCK TEST FRAMEWORK MUTEX */
searchIds.push_back(id);
searchModes.push_back(mode);
frmMtx.unlock(); /* LOCK TEST FRAMEWORK MUTEX */
return true;
}
};
/* OVERLOAD THE ConnMgr - to insert peers */
class p3TestConnMgr: public p3ConnectMgr
{
public:
p3TestConnMgr(int mode)
:p3ConnectMgr(new p3DummyAuthMgr()), mTestMode(mode) { return; }
protected:
/* must be virtual for testing */
virtual void loadConfiguration()
{
/* setup own address */
ownState.id = ownId;
ownState.name = "SELF NAME";
ownState.localaddr.sin_family = AF_INET;
inet_aton("127.0.0.1", &(ownState.localaddr.sin_addr));
ownState.localaddr.sin_port = htons(7812);
ownState.netMode = RS_NET_MODE_UDP;
ownState.visState = RS_VIS_STATE_STD;
/* others not important */
//ownState.state = 0;
//ownState.actions = 0;
if (mTestMode == 1) /* Add to Stun List */
{
for(int i = 0; i < NumOfPeers; i++)
{
mStunList.push_back(peerIds[i]);
}
}
else if (mTestMode == 2) /* add to peers */
{
/* add in as peers */
//addPeer();
for(int i = 0; i < NumOfPeers; i++)
{
if (i < 5)
{
mStunList.push_back(RsUtil::HashId(peerIds[i]));
}
else
{
addFriend(peerIds[i]);
}
}
}
}
protected:
uint32_t mTestMode;
};
int main()
{
time_t startTime = time(NULL);
/* setup system */
initTestData();
/* setup a Stunner to respond to ConnMgr */
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
inet_aton("127.0.0.1", &(saddr.sin_addr));
saddr.sin_port = htons(STUN_PORT);
UdpSorter stunner(saddr); /* starts a receiving thread */
p3TestConnMgr connMgr(2);
DhtMgrTester dhtTester(ownId, &connMgr);
/* now add in some peers */
connMgr.setDhtMgr(&dhtTester);
connMgr.setUpnpMgr(NULL);
/************ ADD pqipersongrp as pqimonitor *****************/
SecurityPolicy *pol = secpolicy_create();
unsigned long flags = 0;
pqipersongrp *pqipg = new pqipersongrpDummy(pol, flags);
connMgr.addMonitor(pqipg);
/************ ADD pqipersongrp as pqimonitor *****************/
/* startup dht */
std::cerr << "Starting up DhtTester()" << std::endl;
dhtTester.start();
/* wait for a little before switching on */
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
sleep(1);
#else
Sleep(1000);
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
std::cerr << "Switching on DhtTester()" << std::endl;
dhtTester.setDhtOn(true);
/* wait loop */
while(1)
{
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
sleep(1);
#else
Sleep(1000);
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
connMgr.tick();
pqipg->tick();
/* handle async search */
frmMtx.lock(); /* LOCK TEST FRAMEWORK MUTEX */
std::string id;
uint32_t mode;
bool doRespond = false;
if (searchIds.size() > 0)
{
id = searchIds.front();
mode = searchModes.front();
doRespond = true;
searchIds.pop_front();
searchModes.pop_front();
}
frmMtx.unlock(); /* UNLOCK TEST FRAMEWORK MUTEX */
if (doRespond)
{
respondSearch(&dhtTester, id, mode);
}
}
};

View File

@ -0,0 +1,346 @@
/*
* RetroShare FileCache Module: ficachetest.cc
*
* Copyright 2004-2007 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 "dbase/cachestrapper.h"
#include "dbase/cachetest.h"
#include "server/ftfiler.h"
#include "util/rsdir.h"
#include "pqi/pqidebug.h"
#include <iostream>
#include <fstream>
void handleQuery(CacheStrapper *csp, RsPeerId pid,
std::map<RsPeerId, CacheStrapper *> &strappers);
/* A simple test of the CacheStrapper Code.
*
* create 3 different CacheStrappers, each with a Source/Store Pair and Transfer Class.
* pass queries and responses between the CacheStrappers,
* and ensure that the hashes in the Caches are updated.
*
*/
int main(int argc, char **argv)
{
/* setup test */
std::string tmppath1 = "/tmp/ct1";
std::string tmppath2 = "/tmp/ct2";
std::string tmppath3 = "/tmp/ct3";
std::string tmppathpart1 = tmppath1 + "/partials";
std::string tmppathpart2 = tmppath2 + "/partials";
std::string tmppathpart3 = tmppath3 + "/partials";
std::string tmppathcompleted1 = tmppath1 + "/completed";
std::string tmppathcompleted2 = tmppath2 + "/completed";
std::string tmppathcompleted3 = tmppath3 + "/completed";
std::string tmppathcache2 = tmppath2 + "/cache";
std::string cachefile = "cachefile.txt";
std::string tmppathcachefile2 = tmppathcache2 + "/" + cachefile;
RsDirUtil::checkCreateDirectory(tmppath1.c_str());
RsDirUtil::checkCreateDirectory(tmppath2.c_str());
RsDirUtil::checkCreateDirectory(tmppath3.c_str());
RsDirUtil::checkCreateDirectory(tmppathpart1.c_str());
RsDirUtil::checkCreateDirectory(tmppathpart2.c_str());
RsDirUtil::checkCreateDirectory(tmppathpart3.c_str());
RsDirUtil::checkCreateDirectory(tmppathcompleted1.c_str());
RsDirUtil::checkCreateDirectory(tmppathcompleted2.c_str());
RsDirUtil::checkCreateDirectory(tmppathcompleted3.c_str());
RsDirUtil::checkCreateDirectory(tmppathcache2.c_str());
/* now create a file */
std::ofstream out(tmppathcachefile2.c_str());
out << "Hello this is a cache file!" << std::endl;
out.close();
setOutputLevel(10);
time_t period = 11;
RsPeerId pid1("0x0101");
RsPeerId pid2("0x0102");
RsPeerId pid3("0x0103");
CacheStrapper sc1(pid1, period);
CacheStrapper sc2(pid2, period);
CacheStrapper sc3(pid3, period);
//CacheTransfer ctt1(&sc1);
//CacheTransfer ctt2(&sc2);
//CacheTransfer ctt3(&sc3);
/* setup of the FileTransfer should wait until
* the CacheSource + CacheStrapper are created
*/
FileHashSearch *fhs1 = NULL;
FileHashSearch *fhs2 = NULL;
FileHashSearch *fhs3 = NULL;
ftfiler ff1(&sc1);
ftfiler ff2(&sc2);
ftfiler ff3(&sc3);
ff1.setSaveBasePath(tmppath1);
ff2.setSaveBasePath(tmppath2);
ff3.setSaveBasePath(tmppath3);
ff1.setFileHashSearch(fhs1);
ff2.setFileHashSearch(fhs2);
ff3.setFileHashSearch(fhs3);
std::map<RsPeerId, CacheStrapper *> strappers;
strappers[pid1] = &sc1;
strappers[pid2] = &sc2;
strappers[pid3] = &sc3;
std::string nulldir = "";
CacheSource *csrc1 = new CacheTestSource(nulldir);
//CacheStore *cstore1 = new CacheTestStore(&ctt1, nulldir);
CacheStore *cstore1 = new CacheTestStore(&ff1, nulldir);
CacheId cid1(TESTID, 0);
CacheSource *csrc2 = new CacheTestSource(nulldir);
//CacheStore *cstore2 = new CacheTestStore(&ctt2, nulldir);
CacheStore *cstore2 = new CacheTestStore(&ff2, nulldir);
CacheId cid2(TESTID, 0);
CacheSource *csrc3 = new CacheTestSource(nulldir);
//CacheStore *cstore3 = new CacheTestStore(&ctt3, nulldir);
CacheStore *cstore3 = new CacheTestStore(&ff3, nulldir);
CacheId cid3(TESTID, 0);
CachePair cp1(csrc1, cstore1, cid1);
CachePair cp2(csrc2, cstore2, cid2);
CachePair cp3(csrc3, cstore3, cid3);
sc1.addCachePair(cp1);
sc2.addCachePair(cp2);
sc3.addCachePair(cp3);
sc1.addPeerId(pid2);
sc2.addPeerId(pid1);
sc2.addPeerId(pid3);
sc3.addPeerId(pid2);
/* add in a cache to sc2 */
CacheData cdata;
cdata.pid = pid1;
cdata.cid = cid1;
cdata.name = cachefile; //"Perm Cache";
cdata.path = tmppathcache2; //"./";
cdata.hash = "GHJKI";
cdata.size = 28;
csrc1->refreshCache(cdata);
/* The file we created */
cdata.pid = pid2;
cdata.cid = cid2;
cdata.name = "Funny Cache";
cdata.path = "./";
cdata.size = 1023;
cdata.hash = "ABCDEF";
csrc2->refreshCache(cdata);
/* now exercise it */
for(int i = 0; 1 ; i++)
{
RsPeerId src("");
CacheStrapper *csp = NULL;
if (i % 5 == 1)
{
src = pid1;
csp = &sc1;
}
else if (i % 5 == 2)
{
src = pid2;
csp = &sc2;
}
else if (i % 5 == 3)
{
src = pid3;
csp = &sc3;
}
std::cerr << std::endl;
std::cerr << "Cache Iteraton: " << time(NULL) << std::endl;
std::cerr << std::endl;
if (src != "")
{
handleQuery(csp, src, strappers);
}
if (i % 21 == 0)
{
/* print out the resources */
sc1.listCaches(std::cerr);
sc2.listCaches(std::cerr);
sc3.listCaches(std::cerr);
}
/* every once in a while change the cache on 2 */
if (i % 31 == 25)
{
cdata.hash += "X";
csrc2->refreshCache(cdata);
}
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
sleep(1);
#else
Sleep(1000);
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
/* tick the systems */
ff1.tick();
ff2.tick();
ff3.tick();
/* exchange packets! */
ftFileRequest *ftPkt = NULL;
while(NULL != (ftPkt = ff1.sendFileInfo()))
{
std::cerr << "Outgoing ftPkt from ff1";
std::cerr << std::endl;
if (ftPkt->id == pid2)
{
std::cerr << "ftPkt for ff2" << std::endl;
ftPkt->id = pid1; /* set source correctly */
ff2.recvFileInfo(ftPkt);
}
else if (ftPkt->id == pid3)
{
std::cerr << "ftPkt for ff3" << std::endl;
ftPkt->id = pid1; /* set source correctly */
ff3.recvFileInfo(ftPkt);
}
else
{
std::cerr << "ERROR unknown ftPkt destination!: " << ftPkt->id;
std::cerr << std::endl;
delete ftPkt;
}
}
while(NULL != (ftPkt = ff2.sendFileInfo()))
{
std::cerr << "Outgoing ftPkt from ff2";
std::cerr << std::endl;
if (ftPkt->id == pid1)
{
std::cerr << "ftPkt for ff1" << std::endl;
ftPkt->id = pid2; /* set source correctly */
ff1.recvFileInfo(ftPkt);
}
else if (ftPkt->id == pid3)
{
std::cerr << "ftPkt for ff3" << std::endl;
ftPkt->id = pid2; /* set source correctly */
ff3.recvFileInfo(ftPkt);
}
else
{
std::cerr << "ERROR unknown ftPkt destination!: " << ftPkt->id;
std::cerr << std::endl;
delete ftPkt;
}
}
while(NULL != (ftPkt = ff3.sendFileInfo()))
{
std::cerr << "Outgoing ftPkt from ff3";
std::cerr << std::endl;
if (ftPkt->id == pid1)
{
std::cerr << "ftPkt for ff1" << std::endl;
ftPkt->id = pid3; /* set source correctly */
ff1.recvFileInfo(ftPkt);
}
else if (ftPkt->id == pid2)
{
std::cerr << "ftPkt for ff2" << std::endl;
ftPkt->id = pid3; /* set source correctly */
ff2.recvFileInfo(ftPkt);
}
else
{
std::cerr << "ERROR unknown ftPkt destination!: " << ftPkt->id;
std::cerr << std::endl;
delete ftPkt;
}
}
}
/* Cleanup - TODO */
return 1;
}
void handleQuery(CacheStrapper *csp, RsPeerId pid,
std::map<RsPeerId, CacheStrapper *> &strappers)
{
/* query */
std::list<RsPeerId> ids;
std::list<RsPeerId>::iterator pit;
std::cerr << "Cache Query from: " << pid << std::endl;
csp -> sendCacheQuery(ids, time(NULL));
for(pit = ids.begin(); pit != ids.end(); pit++)
{
std::cerr << "Cache Query for: " << (*pit) << std::endl;
std::map<RsPeerId, CacheStrapper *>::iterator sit;
if (strappers.end() != (sit = strappers.find(*pit)))
{
std::map<CacheId, CacheData> hashs;
std::map<CacheId, CacheData>::iterator hit;
(sit -> second) -> handleCacheQuery(pid, hashs);
for(hit = hashs.begin(); hit != hashs.end(); hit++)
{
csp -> recvCacheResponse(hit->second, time(NULL));
}
}
else
{
std::cerr << "Unknown Query Destination!" << std::endl;
}
}
}

View File

@ -0,0 +1,44 @@
/***** Extract XPGP Id *****/
#include "pqi/authxpgp.h"
#include <iostream>
#include <sstream>
int main(int argc, char **argv)
{
if (argc < 2)
{
std::cerr << "Usage: " << argv[0] << " <certfile>";
std::cerr << std::endl;
exit(1);
}
std::string userName, userId;
if (LoadCheckXPGPandGetName(argv[1], userName, userId))
{
std::cerr << "Cert Ok: name: " << userName;
std::cerr << std::endl;
std::cerr << "id = \"" << userId << "\"";
std::cerr << std::endl;
}
else
{
std::cerr << "Cert Check Failed";
std::cerr << std::endl;
}
}

View File

@ -3,6 +3,8 @@ include(_rsserver/rsserver.pri)
include(_commonfuncs/commonfuncs.pri)
include(_dht/dht.pri)
include(_pqi/pqi.pri)
include(_server/server.pri)
include(_dbase/dbase.pri)
TEMPLATE = lib
CONFIG += static

View File

@ -51,7 +51,7 @@ class AuthXPGP;
class xpgpcert
{
public:
public:
xpgpcert(XPGP *xpgp, std::string id);
/* certificate parameters */

View File

@ -23,14 +23,10 @@
*
*/
#include "util/rsdir.h"
#include "rsiface/rspeers.h"
#include "pqi/p3cfgmgr.h"
#include "pqi/p3authmgr.h"
#include "pqi/pqibin.h"
#include "pqi/pqistore.h"
#include "pqi/pqinotify.h"
#include <errno.h>
#include "_pqi/p3cfgmgr.h"
#include "serialiser/rsconfigitems.h"