mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-04-19 14:55:54 -04:00
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:
parent
ed517d7ebf
commit
e76eef9c7e
1125
libretroshare/src/_dbase/cachestrapper.cc
Normal file
1125
libretroshare/src/_dbase/cachestrapper.cc
Normal file
File diff suppressed because it is too large
Load Diff
329
libretroshare/src/_dbase/cachestrapper.h
Normal file
329
libretroshare/src/_dbase/cachestrapper.h
Normal 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
|
8
libretroshare/src/_dbase/dbase.pri
Normal file
8
libretroshare/src/_dbase/dbase.pri
Normal file
@ -0,0 +1,8 @@
|
||||
INCLUDEPATH += $$PWD \
|
||||
../$$PWP
|
||||
DEPENDPATH += $$PWD
|
||||
|
||||
SOURCES = cachestrapper.cc
|
||||
|
||||
HEADERS = cachestrapper.h
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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
|
||||
|
2690
libretroshare/src/_pqi/authssl.cc
Normal file
2690
libretroshare/src/_pqi/authssl.cc
Normal file
File diff suppressed because it is too large
Load Diff
241
libretroshare/src/_pqi/authssl.h
Normal file
241
libretroshare/src/_pqi/authssl.h
Normal 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
|
2361
libretroshare/src/_pqi/authxpgp.cc
Normal file
2361
libretroshare/src/_pqi/authxpgp.cc
Normal file
File diff suppressed because it is too large
Load Diff
211
libretroshare/src/_pqi/authxpgp.h
Normal file
211
libretroshare/src/_pqi/authxpgp.h
Normal 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
|
371
libretroshare/src/_pqi/cleanupxpgp.cc
Normal file
371
libretroshare/src/_pqi/cleanupxpgp.cc
Normal 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;
|
||||
|
||||
}
|
||||
|
||||
|
55
libretroshare/src/_pqi/cleanupxpgp.h
Normal file
55
libretroshare/src/_pqi/cleanupxpgp.h
Normal 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
|
302
libretroshare/src/_pqi/p3authmgr.cc
Normal file
302
libretroshare/src/_pqi/p3authmgr.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
222
libretroshare/src/_pqi/p3authmgr.h
Normal file
222
libretroshare/src/_pqi/p3authmgr.h
Normal 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
|
||||
|
||||
|
||||
|
||||
|
714
libretroshare/src/_pqi/p3cfgmgr.cc
Normal file
714
libretroshare/src/_pqi/p3cfgmgr.cc
Normal 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;
|
||||
}
|
||||
|
228
libretroshare/src/_pqi/p3cfgmgr.h
Normal file
228
libretroshare/src/_pqi/p3cfgmgr.h
Normal 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
|
3387
libretroshare/src/_pqi/p3connmgr.cc
Normal file
3387
libretroshare/src/_pqi/p3connmgr.cc
Normal file
File diff suppressed because it is too large
Load Diff
404
libretroshare/src/_pqi/p3connmgr.h
Normal file
404
libretroshare/src/_pqi/p3connmgr.h
Normal 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
|
||||
|
||||
|
||||
|
||||
|
1788
libretroshare/src/_pqi/p3dhtmgr.cc
Normal file
1788
libretroshare/src/_pqi/p3dhtmgr.cc
Normal file
File diff suppressed because it is too large
Load Diff
263
libretroshare/src/_pqi/p3dhtmgr.h
Normal file
263
libretroshare/src/_pqi/p3dhtmgr.h
Normal 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
|
||||
|
||||
|
197
libretroshare/src/_pqi/p3notify.cc
Normal file
197
libretroshare/src/_pqi/p3notify.cc
Normal 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;
|
||||
}
|
||||
|
104
libretroshare/src/_pqi/p3notify.h
Normal file
104
libretroshare/src/_pqi/p3notify.h
Normal 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
|
59
libretroshare/src/_pqi/p3upnpmgr.h
Normal file
59
libretroshare/src/_pqi/p3upnpmgr.h
Normal 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 */
|
||||
|
86
libretroshare/src/_pqi/pqi.h
Normal file
86
libretroshare/src/_pqi/pqi.h
Normal 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
|
||||
|
@ -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
|
||||
|
410
libretroshare/src/_pqi/pqi_base.cc
Normal file
410
libretroshare/src/_pqi/pqi_base.cc
Normal 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
|
461
libretroshare/src/_pqi/pqi_base.h
Normal file
461
libretroshare/src/_pqi/pqi_base.h
Normal 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
|
||||
|
474
libretroshare/src/_pqi/pqiarchive.cc
Normal file
474
libretroshare/src/_pqi/pqiarchive.cc
Normal 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();
|
||||
}
|
||||
|
||||
|
||||
|
95
libretroshare/src/_pqi/pqiarchive.h
Normal file
95
libretroshare/src/_pqi/pqiarchive.h
Normal 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
|
126
libretroshare/src/_pqi/pqiassist.h
Normal file
126
libretroshare/src/_pqi/pqiassist.h
Normal 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 */
|
||||
|
565
libretroshare/src/_pqi/pqibin.cc
Normal file
565
libretroshare/src/_pqi/pqibin.cc
Normal 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("");
|
||||
}
|
||||
|
165
libretroshare/src/_pqi/pqibin.h
Normal file
165
libretroshare/src/_pqi/pqibin.h
Normal 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
|
||||
|
705
libretroshare/src/_pqi/pqihandler.cc
Normal file
705
libretroshare/src/_pqi/pqihandler.cc
Normal 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;
|
||||
}
|
||||
|
126
libretroshare/src/_pqi/pqihandler.h
Normal file
126
libretroshare/src/_pqi/pqihandler.h
Normal 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
|
48
libretroshare/src/_pqi/pqihash.cc
Normal file
48
libretroshare/src/_pqi/pqihash.cc
Normal 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;
|
||||
}
|
||||
|
51
libretroshare/src/_pqi/pqihash.h
Normal file
51
libretroshare/src/_pqi/pqihash.h
Normal 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
|
26
libretroshare/src/_pqi/pqiindic.cc
Normal file
26
libretroshare/src/_pqi/pqiindic.cc
Normal 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;
|
||||
}
|
||||
|
51
libretroshare/src/_pqi/pqiindic.h
Normal file
51
libretroshare/src/_pqi/pqiindic.h
Normal 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
|
48
libretroshare/src/_pqi/pqilistener.h
Normal file
48
libretroshare/src/_pqi/pqilistener.h
Normal 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
|
90
libretroshare/src/_pqi/pqiloopback.cc
Normal file
90
libretroshare/src/_pqi/pqiloopback.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
55
libretroshare/src/_pqi/pqiloopback.h
Normal file
55
libretroshare/src/_pqi/pqiloopback.h
Normal 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
|
85
libretroshare/src/_pqi/pqimonitor.cc
Normal file
85
libretroshare/src/_pqi/pqimonitor.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
138
libretroshare/src/_pqi/pqimonitor.h
Normal file
138
libretroshare/src/_pqi/pqimonitor.h
Normal 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
|
||||
|
866
libretroshare/src/_pqi/pqinetwork.cc
Normal file
866
libretroshare/src/_pqi/pqinetwork.cc
Normal 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 ******************/
|
||||
|
138
libretroshare/src/_pqi/pqinetwork.h
Normal file
138
libretroshare/src/_pqi/pqinetwork.h
Normal 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
|
||||
|
51
libretroshare/src/_pqi/pqinotify.h
Normal file
51
libretroshare/src/_pqi/pqinotify.h
Normal 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
|
479
libretroshare/src/_pqi/pqiperson.cc
Normal file
479
libretroshare/src/_pqi/pqiperson.cc
Normal 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);
|
||||
}
|
||||
}
|
||||
|
122
libretroshare/src/_pqi/pqiperson.h
Normal file
122
libretroshare/src/_pqi/pqiperson.h
Normal 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
|
||||
|
508
libretroshare/src/_pqi/pqipersongrp.cc
Normal file
508
libretroshare/src/_pqi/pqipersongrp.cc
Normal 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 ***************************/
|
||||
|
117
libretroshare/src/_pqi/pqipersongrp.h
Normal file
117
libretroshare/src/_pqi/pqipersongrp.h
Normal 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
|
74
libretroshare/src/_pqi/pqisecurity.cc
Normal file
74
libretroshare/src/_pqi/pqisecurity.cc
Normal 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
|
59
libretroshare/src/_pqi/pqisecurity.h
Normal file
59
libretroshare/src/_pqi/pqisecurity.h
Normal 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
|
||||
|
223
libretroshare/src/_pqi/pqiservice.cc
Normal file
223
libretroshare/src/_pqi/pqiservice.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
|
101
libretroshare/src/_pqi/pqiservice.h
Normal file
101
libretroshare/src/_pqi/pqiservice.h
Normal 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
|
1671
libretroshare/src/_pqi/pqissl.cc
Normal file
1671
libretroshare/src/_pqi/pqissl.cc
Normal file
File diff suppressed because it is too large
Load Diff
230
libretroshare/src/_pqi/pqissl.h
Normal file
230
libretroshare/src/_pqi/pqissl.h
Normal 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
|
733
libretroshare/src/_pqi/pqissllistener.cc
Normal file
733
libretroshare/src/_pqi/pqissllistener.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
131
libretroshare/src/_pqi/pqissllistener.h
Normal file
131
libretroshare/src/_pqi/pqissllistener.h
Normal 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
|
105
libretroshare/src/_pqi/pqisslpersongrp.cc
Normal file
105
libretroshare/src/_pqi/pqisslpersongrp.cc
Normal 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 ***************************/
|
||||
|
||||
|
48
libretroshare/src/_pqi/pqisslpersongrp.h
Normal file
48
libretroshare/src/_pqi/pqisslpersongrp.h
Normal 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
|
513
libretroshare/src/_pqi/pqissludp.cc
Normal file
513
libretroshare/src/_pqi/pqissludp.cc
Normal 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 *******************/
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
104
libretroshare/src/_pqi/pqissludp.h
Normal file
104
libretroshare/src/_pqi/pqissludp.h
Normal 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
|
378
libretroshare/src/_pqi/pqistore.cc
Normal file
378
libretroshare/src/_pqi/pqistore.cc
Normal 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();
|
||||
}
|
||||
|
||||
|
||||
|
72
libretroshare/src/_pqi/pqistore.h
Normal file
72
libretroshare/src/_pqi/pqistore.h
Normal 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
|
910
libretroshare/src/_pqi/pqistreamer.cc
Normal file
910
libretroshare/src/_pqi/pqistreamer.cc
Normal 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;
|
||||
}
|
||||
|
116
libretroshare/src/_pqi/pqistreamer.h
Normal file
116
libretroshare/src/_pqi/pqistreamer.h
Normal 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
|
2031
libretroshare/src/_pqi/sslcert.cc
Normal file
2031
libretroshare/src/_pqi/sslcert.cc
Normal file
File diff suppressed because it is too large
Load Diff
192
libretroshare/src/_pqi/sslcert.h
Normal file
192
libretroshare/src/_pqi/sslcert.h
Normal 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
|
2569
libretroshare/src/_pqi/xpgpcert.cc
Normal file
2569
libretroshare/src/_pqi/xpgpcert.cc
Normal file
File diff suppressed because it is too large
Load Diff
221
libretroshare/src/_pqi/xpgpcert.h
Normal file
221
libretroshare/src/_pqi/xpgpcert.h
Normal 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
|
876
libretroshare/src/_server/filedexserver.cc
Normal file
876
libretroshare/src/_server/filedexserver.cc
Normal 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;
|
||||
}
|
||||
|
177
libretroshare/src/_server/filedexserver.h
Normal file
177
libretroshare/src/_server/filedexserver.h
Normal 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
|
162
libretroshare/src/_server/ft.cc
Normal file
162
libretroshare/src/_server/ft.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
140
libretroshare/src/_server/ft.h
Normal file
140
libretroshare/src/_server/ft.h
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
1767
libretroshare/src/_server/ftfiler.cc
Normal file
1767
libretroshare/src/_server/ftfiler.cc
Normal file
File diff suppressed because it is too large
Load Diff
232
libretroshare/src/_server/ftfiler.h
Normal file
232
libretroshare/src/_server/ftfiler.h
Normal 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
|
51
libretroshare/src/_server/hashsearch.cc
Normal file
51
libretroshare/src/_server/hashsearch.cc
Normal 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();
|
||||
}
|
||||
|
||||
|
61
libretroshare/src/_server/hashsearch.h
Normal file
61
libretroshare/src/_server/hashsearch.h
Normal 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
|
1220
libretroshare/src/_server/pqifiler.cc
Normal file
1220
libretroshare/src/_server/pqifiler.cc
Normal file
File diff suppressed because it is too large
Load Diff
183
libretroshare/src/_server/pqifiler.h
Normal file
183
libretroshare/src/_server/pqifiler.h
Normal 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
|
14
libretroshare/src/_server/server.pri
Normal file
14
libretroshare/src/_server/server.pri
Normal 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
|
362
libretroshare/src/_tests/conn_test.cc
Normal file
362
libretroshare/src/_tests/conn_test.cc
Normal 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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
346
libretroshare/src/_tests/ftcachetest.cc
Normal file
346
libretroshare/src/_tests/ftcachetest.cc
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
44
libretroshare/src/_tests/xpgp_id.cc
Normal file
44
libretroshare/src/_tests/xpgp_id.cc
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -51,7 +51,7 @@ class AuthXPGP;
|
||||
|
||||
class xpgpcert
|
||||
{
|
||||
public:
|
||||
public:
|
||||
xpgpcert(XPGP *xpgp, std::string id);
|
||||
|
||||
/* certificate parameters */
|
||||
|
@ -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"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user