creditsdb.h

Go to the documentation of this file.
00001 /**
00002  *  Copyright (C) 2004-2005 Alo Sarv <madcat_@users.sourceforge.net>
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  */
00018 
00019 /** @file creditsdb.h Interface for CreditsDb and ClientCredits classes */
00020 
00021 #ifndef __CREDITSDB_H__
00022 #define __CREDITSDB_H__
00023 
00024 #include <hn/object.h>
00025 #include <hn/hash.h>
00026 #include <math.h>
00027 #include "ed2ktypes.h"
00028 #include "publickey.h"
00029 
00030 /**
00031  * Credits object represent one single client's credits entry.
00032  */
00033 class Credits {
00034 public:
00035         //! Construct by publickey and hash
00036         Credits(PublicKey key, const Hash<MD4Hash> &h);
00037 
00038         float getScore() const {
00039                 if (m_downloaded < 1024*1024) {
00040                         return 1.0;
00041                 }
00042                 float score1 = m_uploaded?m_downloaded*2/m_uploaded :10;
00043                 float score2 = sqrt(m_downloaded/1024.0*1024.0) + 2;
00044                 return score1 > score2 ? score1 : score2;
00045         }
00046 
00047         uint64_t      getUploaded()   const { return m_uploaded;   }
00048         uint64_t      getDownloaded() const { return m_downloaded; }
00049         uint32_t      getLastSeen()   const { return m_lastSeen;   }
00050         Hash<MD4Hash> getHash()       const { return m_hash;       }
00051         PublicKey     getPubKey()     const { return m_pubKey;     }
00052 
00053         void addUploaded(uint32_t amount)   { m_uploaded += amount;   }
00054         void addDownloaded(uint32_t amount) { m_downloaded += amount; }
00055         void setLastSeen(uint32_t time)     { m_lastSeen = time;      }
00056 private:
00057         friend class CreditsDb;
00058 
00059         /**
00060          * Construct and load from stream. This is used only by
00061          * CreditsDb, and is thus private.
00062          *
00063          * @param i          Input stream to read data from
00064          * @param ver        Version of stream (pubkey or not)
00065          */
00066         Credits(std::istream &i, uint8_t ver);
00067 
00068         Credits();                                    //!< Forbidden
00069         ~Credits();                                   //!< Allowed by CreditsDb
00070         Credits(const Credits&);                      //!< Forbidden
00071         const Credits& operator=(const Credits&);     //! Forbidden
00072 
00073         //! @name Data
00074         //@{
00075         Hash<MD4Hash> m_hash;              //!< Userhash
00076         uint64_t      m_uploaded;          //!< Sent to him/her
00077         uint64_t      m_downloaded;        //!< Received from him/her
00078         uint32_t      m_lastSeen;          //!< Time last seen
00079         PublicKey     m_pubKey;            //!< public key
00080         //@}
00081 
00082         //! Output operator to streams, used for writing clients.met
00083         friend std::ostream& operator<<(std::ostream &o, const Credits &c);
00084 };
00085 
00086 namespace Detail {
00087         struct CreditsList;
00088 }
00089 
00090 /**
00091  * CreditsDb class stores and maintains ClientCredits type objects, which
00092  * represent eDonkey2000 client credits. Actually, what this means is we
00093  * store the clients userhash and public key, and keep track of how much we
00094  * have sent data to the client, and how much we have received back. All of
00095  * this forms the base for eMule extended protocol feature, which rewards
00096  * uploaders based on their credits. More on that in UploadQueue-related
00097  * classes. Note that not all clients connecting to eDonkey2000 network support
00098  * credits, and thus only clients giving back credits should be rewarded here.
00099  * At the point of this writing (15/10/2004), only eMule-derived clients, plus
00100  * ShareAza fully support this system as far as I know.
00101  *
00102  * CreditsDb stores its contents at config/ed2k/clients.met between sessions.
00103  * The file format conforms to eMule's respective file format.
00104  *
00105  * This class is a Singleton, the only instance of this class may be retrieved
00106  * through instance() member function.
00107  */
00108 class CreditsDb {
00109 public:
00110         //! Singleton, lazy instanciating
00111         static CreditsDb& instance() {
00112                 static CreditsDb *cdb = new CreditsDb();
00113                 return *cdb;
00114         }
00115 
00116         /**
00117          * Initializes public/private RSA keypair either by loading it from
00118          * file, or creating new one if needed.
00119          */
00120         void initCrypting();
00121 
00122         /**
00123          * Load the contents from file, adding all entries found there to list
00124          *
00125          * @param file     File to read data from
00126          *
00127          * \throws std::runtime_error if parsing fails
00128          */
00129         void load(const std::string &file);
00130 
00131         /**
00132          * Save the contents to file.
00133          *
00134          * @param file      File to write to
00135          */
00136         void save(const std::string &file) const;
00137 
00138         /**
00139          * @returns Own public key
00140          */
00141         PublicKey getPublicKey() const { return m_pubKey; }
00142 
00143         /**
00144          * Find credits, looking with PublicKey.
00145          *
00146          * @param key  Client's PublicKey to search for
00147          * @return     Pointer to Credits object corresponding to @param key, or
00148          *             0 if not found.
00149          */
00150         Credits* find(const PublicKey &key) const;
00151 
00152         /**
00153          * Find credits, looking with userhash.
00154          *
00155          * @param hash  Client's userhash
00156          * @return      Pointer to Credits object corresponding to @param hash,
00157          *              or 0 if not found.
00158          *
00159          * \note Usage of this function is discouraged, due to hash-stealers.
00160          */
00161         Credits* find(const Hash<MD4Hash> &hash) const;
00162 
00163         /**
00164          * Create credits entry for specified publickey/hash
00165          */
00166         Credits* create(PublicKey key, const Hash<MD4Hash> &hash);
00167 
00168         /**
00169          * Creates a signature to be sent to client owning target credits.
00170          *
00171          * @param key        Remote client's public key
00172          * @param callenge   Challenge value
00173          * @param ipType     Type of IP (if any) to include
00174          * @param ip         The ip to be included (if any)
00175          * @return           Signature to be sent back to client
00176          */
00177         static std::string createSignature(
00178                 PublicKey key, uint32_t challenge, IpType ipType, uint32_t ip
00179         );
00180 
00181         /**
00182          * Attempts to verify signature against public key stored here.
00183          *
00184          * @param key        Remote client's public key
00185          * @param challenge  Challenge value sent to this client previously
00186          * @param sign       The signature the remote client sent back
00187          * @param ipType     Type of IP included in the signature (if any)
00188          * @param ip         IP address included in the signature (if any)
00189          * @return           True if verification succeeds, false otherwise
00190          */
00191         static bool verifySignature(
00192                 PublicKey key, uint32_t challenge,
00193                 const std::string &sign, IpType ipType, uint32_t ip
00194         );
00195 private:
00196         CreditsDb();                                   //!< Singleton
00197         ~CreditsDb();                                  //!< Singleton
00198         CreditsDb(const CreditsDb&);                   //!< No copying allowed
00199         const CreditsDb& operator=(const CreditsDb&);  //!< No copying allowed
00200 
00201         /**
00202          * Loads private RSA key from file, and calculates public RSA key from
00203          * it.
00204          *
00205          * @param where      File to read private key from.
00206          */
00207         void loadCryptKey(const std::string &where);
00208 
00209         /**
00210          * Creates new public/private RSA keypair, and saves it to file.
00211          *
00212          * @param where      File to write private key to.
00213          */
00214         void createCryptKey(const std::string &where);
00215 
00216         //! Public RSA key
00217         PublicKey m_pubKey;
00218 
00219         boost::scoped_ptr<Detail::CreditsList> m_list;
00220 };
00221 
00222 #endif