/******************************************************************************* * libretroshare/src/pqi: pqi_base.h * * * * libretroshare: retroshare core library * * * * Copyright 2004-2006 by Robert Fernie * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * * published by the Free Software Foundation, either version 3 of the * * License, or (at your option) any later version. * * * * This program 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 Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public License * * along with this program. If not, see . * * * *******************************************************************************/ #ifndef PQI_BASE_ITEM_HEADER #define PQI_BASE_ITEM_HEADER #include #include #include #include #include #include #include "pqi/pqinetwork.h" struct RSTrafficClue; /*** Base DataTypes: ****/ #include "serialiser/rsserial.h" #include "retroshare/rstypes.h" int getPQIsearchId(); int fixme(char *str, int n); struct RsPeerCryptoParams; //! controlling data rates /*! * For controlling data rates. * #define DEBUG_RATECAP 1 */ class RsBwRates { public: RsBwRates() :mRateIn(0), mRateOut(0), mMaxRateIn(0), mMaxRateOut(0), mQueueIn(0), mQueueOut(0) {return;} float mRateIn; float mRateOut; float mMaxRateIn; float mMaxRateOut; int mQueueIn; int mQueueOut; }; class RateInterface { public: RateInterface() :bw_in(0), bw_out(0), bwMax_in(0), bwMax_out(0), bwCapEnabled(false), bwCap_in(0), bwCap_out(0) { return; } virtual ~RateInterface() { return; } virtual void getRates(RsBwRates &rates) { rates.mRateIn = bw_in; rates.mRateOut = bw_out; rates.mMaxRateIn = bwMax_in; rates.mMaxRateOut = bwMax_out; return; } virtual int gatherStatistics(std::list& /* outqueue_lst */,std::list& /* inqueue_lst */) { return 0;} virtual int getQueueSize(bool /* in */) { return 0;} 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; if (bwCapEnabled) { if (bwMax_in > bwCap_in) { bwMax_in = bwCap_in; } } } else { bwMax_out = val; if (bwCapEnabled) { if (bwMax_out > bwCap_out) { bwMax_out = bwCap_out; } } } return; } virtual void setRateCap(float val_in, float val_out) { if ((val_in == 0) && (val_out == 0)) { #ifdef DEBUG_RATECAP std::cerr << "RateInterface::setRateCap() Now disabled" << std::endl; #endif bwCapEnabled = false; } else { #ifdef DEBUG_RATECAP std::cerr << "RateInterface::setRateCap() Enabled "; std::cerr << "in: " << bwCap_in << " out: " << bwCap_out << std::endl; #endif bwCapEnabled = true; bwCap_in = val_in; bwCap_out = val_out; } return; } protected: virtual 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; bool bwCapEnabled; float bwCap_in, bwCap_out; }; class NetInterface; //! The basic exchange interface. /*! * * This inherits the RateInterface, as Bandwidth control * is critical to a networked application. **/ class PQInterface: public RateInterface { public: explicit PQInterface(const RsPeerId &id) : traf_in(0), traf_out(0), peerId(id) {} virtual ~PQInterface() {} /*! * allows user to send RsItems to a particular facility (file, network) */ virtual int SendItem(RsItem *) = 0; // this function is overloaded in classes that need the serilized size to be returned. virtual int SendItem(RsItem *item,uint32_t& size) { size = 0 ; static bool already=false ; if(!already) { std::cerr << "Warning: PQInterface::SendItem(RsItem*,uint32_t&) calledbut not overloaded! Serialized size will not be returned." << std::endl; already=true ; } return SendItem(item) ; } virtual bool getCryptoParams(RsPeerCryptoParams&) { return false ;} /*! * Retrieve RsItem from a facility */ virtual RsItem *GetItem() = 0; virtual bool RecvItem(RsItem * /*item*/ ) { return false; } /* alternative for for GetItem(), when we want to push */ /** * also there are tick + person id functions. */ virtual int tick() { return 0; } virtual int status() { return 0; } virtual const RsPeerId& PeerId() { return peerId; } // the callback from NetInterface Connection Events. virtual int notifyEvent(NetInterface * /*ni*/, int /*event*/, const sockaddr_storage & /*remote_peer_address*/) { return 0; } virtual uint64_t getTraffic(bool in) { uint64_t ret = 0; if (in) { ret = traf_in; traf_in = 0; return ret; } ret = traf_out; traf_out = 0; return ret; } uint64_t traf_in; uint64_t traf_out; private: RsPeerId peerId; }; /**** Consts for pqiperson -> placed here for NetBinDummy usage() */ const uint32_t PQI_CONNECT_TCP = 0x0001; const uint32_t PQI_CONNECT_UDP = 0x0002; const uint32_t PQI_CONNECT_HIDDEN_TOR_TCP = 0x0004; const uint32_t PQI_CONNECT_HIDDEN_I2P_TCP = 0x0008; #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 /*! * This defines the binary interface used by Network/loopback/file * interfaces * e.g. sending binary data to file or to memory or even through a socket */ class BinInterface { public: BinInterface() {} virtual ~BinInterface() {} /** * To be called loop, for updating state */ virtual int tick() = 0; /** * Sends data to a prescribed location (implementation dependent) *@param data what will be sent *@param len the size of data pointed to in memory *@returns total number of bytes actually sent */ virtual int senddata(void *data, int len) = 0; /** * reads data from a prescribed location (implementation dependent) * -- WARNING -- if used to feed a pqistreamer, the streamer will assume one of the two situations: * 1 - len bytes are read, or * 2 - less than len bytes are read, but in this case the interface should keep the data * This rule corresponds to openssl behavior. If not followed, incoming packets will be lost. * *@param data what will be sent *@param len the size of data pointed to in memory */ virtual int readdata(void *data, int len) = 0; /** * Is more particular the case of the sending data through a socket (internet) * moretoread and candsend, take a microsec timeout argument. * */ virtual int netstatus() = 0; virtual int isactive() = 0; virtual bool moretoread(uint32_t usec) = 0; virtual bool cansend(uint32_t usec) = 0; /** * method for streamer to shutdown bininterface **/ virtual int close() = 0; /** * If hashing data **/ virtual RsFileHash gethash() = 0; /** * Number of bytes read/sent */ virtual uint64_t bytecount() { return 0; } /** * used by pqistreamer to limit transfers **/ virtual bool bandwidthLimited() { return true; } }; 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; static const uint32_t NET_PARAM_CONNECT_FLAGS = 4; static const uint32_t NET_PARAM_CONNECT_BANDWIDTH = 5; static const uint32_t NET_PARAM_CONNECT_PROXY = 6; static const uint32_t NET_PARAM_CONNECT_SOURCE = 7; static const uint32_t NET_PARAM_CONNECT_DOMAIN_ADDRESS = 8; static const uint32_t NET_PARAM_CONNECT_REMOTE_PORT = 9; /*! * ******************** Network INTERFACE *************************** * 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. **/ class NetInterface { public: /** * @param p_in used to notify system of connect/disconnect events */ NetInterface(PQInterface *p_in, const RsPeerId& id) : p(p_in), peerId(id) {} virtual ~NetInterface() {} /* TODO * The data entrypoint is connect(const struct sockaddr_storage &raddr) * To generalize NetInterface we should have a more general type for raddr * As an example a string containing an url or encoded like a domain name */ virtual int connect(const struct sockaddr_storage &raddr) = 0; virtual int listen() = 0; virtual int stoplistening() = 0; virtual int disconnect() = 0; virtual int reset() = 0; virtual const RsPeerId& PeerId() { return peerId; } virtual int getConnectAddress(struct sockaddr_storage &raddr) = 0; virtual bool connect_parameter(uint32_t type, uint32_t value) = 0; virtual bool connect_parameter(uint32_t /* type */ , const std::string & /* value */ ) { return false; } // not generally used. virtual bool connect_additional_address(uint32_t /*type*/, const struct sockaddr_storage & /*addr*/) { return false; } // only needed by udp. protected: PQInterface *parent() { return p; } private: PQInterface *p; RsPeerId peerId; }; //! network binary interface (abstract) /** * Should be used for networking and connecting to addresses * * @see pqissl * @see NetInterface * @see BinInterface **/ class NetBinInterface: public NetInterface, public BinInterface { public: NetBinInterface(PQInterface *parent, const RsPeerId& id) : NetInterface(parent, id) {} virtual ~NetBinInterface() {} }; #define CHAN_SIGN_SIZE 16 #define CERTSIGNLEN 16 /* actual byte length of signature */ #define PQI_PEERID_LENGTH 32 /* When expanded into a string */ #endif // PQI_BASE_ITEM_HEADER