genesis                 1 
genesis                 2 
genesis                 3 
genesis                 4 
genesis                 5 
genesis                 6 #include "protocol.h"
genesis                 7 #include "util.h"
genesis                 8 
genesis                 9 #ifndef WIN32
genesis                10 # include <arpa/inet.h>
genesis                11 #endif
genesis                12 
genesis                13 
genesis                14 bool Lookup(const char *pszName, std::vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
genesis                15 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
genesis                16 
genesis                17 static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
genesis                18 static const char* ppszTypeName[] =
genesis                19 {
genesis                20     "ERROR",
genesis                21     "tx",
genesis                22     "block",
genesis                23 };
genesis                24 
genesis                25 CMessageHeader::CMessageHeader()
genesis                26 {
genesis                27     memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));
genesis                28     memset(pchCommand, 0, sizeof(pchCommand));
genesis                29     pchCommand[1] = 1;
genesis                30     nMessageSize = -1;
genesis                31     nChecksum = 0;
genesis                32 }
genesis                33 
genesis                34 CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn)
genesis                35 {
genesis                36     memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));
genesis                37     strncpy(pchCommand, pszCommand, COMMAND_SIZE);
genesis                38     nMessageSize = nMessageSizeIn;
genesis                39     nChecksum = 0;
genesis                40 }
genesis                41 
genesis                42 std::string CMessageHeader::GetCommand() const
genesis                43 {
genesis                44     if (pchCommand[COMMAND_SIZE-1] == 0)
genesis                45         return std::string(pchCommand, pchCommand + strlen(pchCommand));
genesis                46     else
genesis                47         return std::string(pchCommand, pchCommand + COMMAND_SIZE);
genesis                48 }
genesis                49 
genesis                50 bool CMessageHeader::IsValid() const
genesis                51 {
genesis                52     
genesis                53     if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0)
genesis                54         return false;
genesis                55 
genesis                56     
genesis                57     for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++)
genesis                58     {
genesis                59         if (*p1 == 0)
genesis                60         {
genesis                61             
genesis                62             for (; p1 < pchCommand + COMMAND_SIZE; p1++)
genesis                63                 if (*p1 != 0)
genesis                64                     return false;
genesis                65         }
genesis                66         else if (*p1 < ' ' || *p1 > 0x7E)
genesis                67             return false;
genesis                68     }
genesis                69 
genesis                70     
genesis                71     if (nMessageSize > MAX_SIZE)
genesis                72     {
genesis                73         printf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand().c_str(), nMessageSize);
genesis                74         return false;
genesis                75     }
genesis                76 
genesis                77     return true;
genesis                78 }
genesis                79 
genesis                80 CAddress::CAddress()
genesis                81 {
genesis                82     Init();
genesis                83 }
genesis                84 
genesis                85 CAddress::CAddress(unsigned int ipIn, unsigned short portIn, uint64 nServicesIn)
genesis                86 {
genesis                87     Init();
genesis                88     ip = ipIn;
genesis                89     port = htons(portIn == 0 ? GetDefaultPort() : portIn);
genesis                90     nServices = nServicesIn;
genesis                91 }
genesis                92 
genesis                93 CAddress::CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn)
genesis                94 {
genesis                95     Init();
genesis                96     ip = sockaddr.sin_addr.s_addr;
genesis                97     port = sockaddr.sin_port;
genesis                98     nServices = nServicesIn;
genesis                99 }
genesis               100 
genesis               101 CAddress::CAddress(const char* pszIn, int portIn, bool fNameLookup, uint64 nServicesIn)
genesis               102 {
genesis               103     Init();
genesis               104     Lookup(pszIn, *this, nServicesIn, fNameLookup, portIn);
genesis               105 }
genesis               106 
genesis               107 CAddress::CAddress(const char* pszIn, bool fNameLookup, uint64 nServicesIn)
genesis               108 {
genesis               109     Init();
genesis               110     Lookup(pszIn, *this, nServicesIn, fNameLookup, 0, true);
genesis               111 }
genesis               112 
genesis               113 CAddress::CAddress(std::string strIn, int portIn, bool fNameLookup, uint64 nServicesIn)
genesis               114 {
genesis               115     Init();
genesis               116     Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, portIn);
genesis               117 }
genesis               118 
genesis               119 CAddress::CAddress(std::string strIn, bool fNameLookup, uint64 nServicesIn)
genesis               120 {
genesis               121     Init();
genesis               122     Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, 0, true);
genesis               123 }
genesis               124 
genesis               125 void CAddress::Init()
genesis               126 {
genesis               127     nServices = NODE_NETWORK;
genesis               128     memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
genesis               129     ip = INADDR_NONE;
genesis               130     port = htons(GetDefaultPort());
genesis               131     nTime = 100000000;
genesis               132     nLastTry = 0;
genesis               133 }
genesis               134 
genesis               135 bool operator==(const CAddress& a, const CAddress& b)
genesis               136 {
genesis               137     return (memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)) == 0 &&
genesis               138             a.ip   == b.ip &&
genesis               139             a.port == b.port);
genesis               140 }
genesis               141 
genesis               142 bool operator!=(const CAddress& a, const CAddress& b)
genesis               143 {
genesis               144     return (!(a == b));
genesis               145 }
genesis               146 
genesis               147 bool operator<(const CAddress& a, const CAddress& b)
genesis               148 {
genesis               149     int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved));
genesis               150     if (ret < 0)
genesis               151         return true;
genesis               152     else if (ret == 0)
genesis               153     {
genesis               154         if (ntohl(a.ip) < ntohl(b.ip))
genesis               155             return true;
genesis               156         else if (a.ip == b.ip)
genesis               157             return ntohs(a.port) < ntohs(b.port);
genesis               158     }
genesis               159     return false;
genesis               160 }
genesis               161 
genesis               162 std::vector<unsigned char> CAddress::GetKey() const
genesis               163 {
genesis               164     CDataStream ss;
genesis               165     ss.reserve(18);
genesis               166     ss << FLATDATA(pchReserved) << ip << port;
genesis               167 
genesis               168     #if defined(_MSC_VER) && _MSC_VER < 1300
genesis               169     return std::vector<unsigned char>((unsigned char*)&ss.begin()[0], (unsigned char*)&ss.end()[0]);
genesis               170     #else
genesis               171     return std::vector<unsigned char>(ss.begin(), ss.end());
genesis               172     #endif
genesis               173 }
genesis               174 
genesis               175 struct sockaddr_in CAddress::GetSockAddr() const
genesis               176 {
genesis               177     struct sockaddr_in sockaddr;
genesis               178     memset(&sockaddr, 0, sizeof(sockaddr));
genesis               179     sockaddr.sin_family = AF_INET;
genesis               180     sockaddr.sin_addr.s_addr = ip;
genesis               181     sockaddr.sin_port = port;
genesis               182     return sockaddr;
genesis               183 }
genesis               184 
genesis               185 bool CAddress::IsIPv4() const
genesis               186 {
genesis               187     return (memcmp(pchReserved, pchIPv4, sizeof(pchIPv4)) == 0);
genesis               188 }
genesis               189 
genesis               190 bool CAddress::IsRFC1918() const
genesis               191 {
genesis               192   return IsIPv4() && (GetByte(3) == 10 ||
genesis               193     (GetByte(3) == 192 && GetByte(2) == 168) ||
genesis               194     (GetByte(3) == 172 &&
genesis               195       (GetByte(2) >= 16 && GetByte(2) <= 31)));
genesis               196 }
genesis               197 
genesis               198 bool CAddress::IsRFC3927() const
genesis               199 {
genesis               200   return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254);
genesis               201 }
genesis               202 
genesis               203 bool CAddress::IsLocal() const
genesis               204 {
genesis               205   return IsIPv4() && (GetByte(3) == 127 ||
genesis               206       GetByte(3) == 0);
genesis               207 }
genesis               208 
genesis               209 bool CAddress::IsRoutable() const
genesis               210 {
genesis               211     return IsValid() &&
genesis               212         !(IsRFC1918() || IsRFC3927() || IsLocal());
genesis               213 }
genesis               214 
genesis               215 bool CAddress::IsValid() const
genesis               216 {
genesis               217     
genesis               218     
genesis               219     
genesis               220     
genesis               221     
genesis               222     
genesis               223     if (memcmp(pchReserved, pchIPv4+3, sizeof(pchIPv4)-3) == 0)
genesis               224         return false;
genesis               225 
genesis               226     return (ip != 0 && ip != INADDR_NONE && port != htons(USHRT_MAX));
genesis               227 }
genesis               228 
genesis               229 unsigned char CAddress::GetByte(int n) const
genesis               230 {
genesis               231     return ((unsigned char*)&ip)[3-n];
genesis               232 }
genesis               233 
genesis               234 std::string CAddress::ToStringIPPort() const
genesis               235 {
genesis               236     return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
genesis               237 }
genesis               238 
genesis               239 std::string CAddress::ToStringIP() const
genesis               240 {
genesis               241     return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
genesis               242 }
genesis               243 
genesis               244 std::string CAddress::ToStringPort() const
genesis               245 {
genesis               246     return strprintf("%u", ntohs(port));
genesis               247 }
genesis               248 
genesis               249 std::string CAddress::ToString() const
genesis               250 {
genesis               251     return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
genesis               252 }
genesis               253 
genesis               254 void CAddress::print() const
genesis               255 {
genesis               256     printf("CAddress(%s)\n", ToString().c_str());
genesis               257 }
genesis               258 
genesis               259 CInv::CInv()
genesis               260 {
genesis               261     type = 0;
genesis               262     hash = 0;
genesis               263 }
genesis               264 
genesis               265 CInv::CInv(int typeIn, const uint256& hashIn)
genesis               266 {
genesis               267     type = typeIn;
genesis               268     hash = hashIn;
genesis               269 }
genesis               270 
genesis               271 CInv::CInv(const std::string& strType, const uint256& hashIn)
genesis               272 {
genesis               273     int i;
genesis               274     for (i = 1; i < ARRAYLEN(ppszTypeName); i++)
genesis               275     {
genesis               276         if (strType == ppszTypeName[i])
genesis               277         {
genesis               278             type = i;
genesis               279             break;
genesis               280         }
genesis               281     }
genesis               282     if (i == ARRAYLEN(ppszTypeName))
genesis               283         throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str()));
genesis               284     hash = hashIn;
genesis               285 }
genesis               286 
genesis               287 bool operator<(const CInv& a, const CInv& b)
genesis               288 {
genesis               289     return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
genesis               290 }
genesis               291 
genesis               292 bool CInv::IsKnownType() const
genesis               293 {
genesis               294     return (type >= 1 && type < ARRAYLEN(ppszTypeName));
genesis               295 }
genesis               296 
genesis               297 const char* CInv::GetCommand() const
genesis               298 {
genesis               299     if (!IsKnownType())
genesis               300         throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type));
genesis               301     return ppszTypeName[type];
genesis               302 }
genesis               303 
genesis               304 std::string CInv::ToString() const
genesis               305 {
genesis               306     return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,20).c_str());
genesis               307 }
genesis               308 
genesis               309 void CInv::print() const
genesis               310 {
genesis               311     printf("CInv(%s)\n", ToString().c_str());
genesis               312 }