-
+ E76EC1350E05C0FEF1798A50903586ACE4737FAA6DB134094A88A23A96E2A54D8E135A840B822EF136D336B035B3B03B7DED83A99267C892663B15D11AD00720bitcoin/src/protocol.cpp(0 . 0)(1 . 312)
17168 // Copyright (c) 2009-2010 Satoshi Nakamoto
17169 // Copyright (c) 2011 The Bitcoin developers
17170 // Distributed under the MIT/X11 software license, see the accompanying
17171 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
17172 
17173 #include "protocol.h"
17174 #include "util.h"
17175 
17176 #ifndef WIN32
17177 # include <arpa/inet.h>
17178 #endif
17179 
17180 // Prototypes from net.h, but that header (currently) stinks, can't #include it without breaking things
17181 bool Lookup(const char *pszName, std::vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
17182 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
17183 
17184 static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
17185 static const char* ppszTypeName[] =
17186 {
17187     "ERROR",
17188     "tx",
17189     "block",
17190 };
17191 
17192 CMessageHeader::CMessageHeader()
17193 {
17194     memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));
17195     memset(pchCommand, 0, sizeof(pchCommand));
17196     pchCommand[1] = 1;
17197     nMessageSize = -1;
17198     nChecksum = 0;
17199 }
17200 
17201 CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn)
17202 {
17203     memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));
17204     strncpy(pchCommand, pszCommand, COMMAND_SIZE);
17205     nMessageSize = nMessageSizeIn;
17206     nChecksum = 0;
17207 }
17208 
17209 std::string CMessageHeader::GetCommand() const
17210 {
17211     if (pchCommand[COMMAND_SIZE-1] == 0)
17212         return std::string(pchCommand, pchCommand + strlen(pchCommand));
17213     else
17214         return std::string(pchCommand, pchCommand + COMMAND_SIZE);
17215 }
17216 
17217 bool CMessageHeader::IsValid() const
17218 {
17219     // Check start string
17220     if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0)
17221         return false;
17222 
17223     // Check the command string for errors
17224     for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++)
17225     {
17226         if (*p1 == 0)
17227         {
17228             // Must be all zeros after the first zero
17229             for (; p1 < pchCommand + COMMAND_SIZE; p1++)
17230                 if (*p1 != 0)
17231                     return false;
17232         }
17233         else if (*p1 < ' ' || *p1 > 0x7E)
17234             return false;
17235     }
17236 
17237     // Message size
17238     if (nMessageSize > MAX_SIZE)
17239     {
17240         printf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand().c_str(), nMessageSize);
17241         return false;
17242     }
17243 
17244     return true;
17245 }
17246 
17247 CAddress::CAddress()
17248 {
17249     Init();
17250 }
17251 
17252 CAddress::CAddress(unsigned int ipIn, unsigned short portIn, uint64 nServicesIn)
17253 {
17254     Init();
17255     ip = ipIn;
17256     port = htons(portIn == 0 ? GetDefaultPort() : portIn);
17257     nServices = nServicesIn;
17258 }
17259 
17260 CAddress::CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn)
17261 {
17262     Init();
17263     ip = sockaddr.sin_addr.s_addr;
17264     port = sockaddr.sin_port;
17265     nServices = nServicesIn;
17266 }
17267 
17268 CAddress::CAddress(const char* pszIn, int portIn, bool fNameLookup, uint64 nServicesIn)
17269 {
17270     Init();
17271     Lookup(pszIn, *this, nServicesIn, fNameLookup, portIn);
17272 }
17273 
17274 CAddress::CAddress(const char* pszIn, bool fNameLookup, uint64 nServicesIn)
17275 {
17276     Init();
17277     Lookup(pszIn, *this, nServicesIn, fNameLookup, 0, true);
17278 }
17279 
17280 CAddress::CAddress(std::string strIn, int portIn, bool fNameLookup, uint64 nServicesIn)
17281 {
17282     Init();
17283     Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, portIn);
17284 }
17285 
17286 CAddress::CAddress(std::string strIn, bool fNameLookup, uint64 nServicesIn)
17287 {
17288     Init();
17289     Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, 0, true);
17290 }
17291 
17292 void CAddress::Init()
17293 {
17294     nServices = NODE_NETWORK;
17295     memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
17296     ip = INADDR_NONE;
17297     port = htons(GetDefaultPort());
17298     nTime = 100000000;
17299     nLastTry = 0;
17300 }
17301 
17302 bool operator==(const CAddress& a, const CAddress& b)
17303 {
17304     return (memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)) == 0 &&
17305             a.ip   == b.ip &&
17306             a.port == b.port);
17307 }
17308 
17309 bool operator!=(const CAddress& a, const CAddress& b)
17310 {
17311     return (!(a == b));
17312 }
17313 
17314 bool operator<(const CAddress& a, const CAddress& b)
17315 {
17316     int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved));
17317     if (ret < 0)
17318         return true;
17319     else if (ret == 0)
17320     {
17321         if (ntohl(a.ip) < ntohl(b.ip))
17322             return true;
17323         else if (a.ip == b.ip)
17324             return ntohs(a.port) < ntohs(b.port);
17325     }
17326     return false;
17327 }
17328 
17329 std::vector<unsigned char> CAddress::GetKey() const
17330 {
17331     CDataStream ss;
17332     ss.reserve(18);
17333     ss << FLATDATA(pchReserved) << ip << port;
17334 
17335     #if defined(_MSC_VER) && _MSC_VER < 1300
17336     return std::vector<unsigned char>((unsigned char*)&ss.begin()[0], (unsigned char*)&ss.end()[0]);
17337     #else
17338     return std::vector<unsigned char>(ss.begin(), ss.end());
17339     #endif
17340 }
17341 
17342 struct sockaddr_in CAddress::GetSockAddr() const
17343 {
17344     struct sockaddr_in sockaddr;
17345     memset(&sockaddr, 0, sizeof(sockaddr));
17346     sockaddr.sin_family = AF_INET;
17347     sockaddr.sin_addr.s_addr = ip;
17348     sockaddr.sin_port = port;
17349     return sockaddr;
17350 }
17351 
17352 bool CAddress::IsIPv4() const
17353 {
17354     return (memcmp(pchReserved, pchIPv4, sizeof(pchIPv4)) == 0);
17355 }
17356 
17357 bool CAddress::IsRFC1918() const
17358 {
17359   return IsIPv4() && (GetByte(3) == 10 ||
17360     (GetByte(3) == 192 && GetByte(2) == 168) ||
17361     (GetByte(3) == 172 &&
17362       (GetByte(2) >= 16 && GetByte(2) <= 31)));
17363 }
17364 
17365 bool CAddress::IsRFC3927() const
17366 {
17367   return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254);
17368 }
17369 
17370 bool CAddress::IsLocal() const
17371 {
17372   return IsIPv4() && (GetByte(3) == 127 ||
17373       GetByte(3) == 0);
17374 }
17375 
17376 bool CAddress::IsRoutable() const
17377 {
17378     return IsValid() &&
17379         !(IsRFC1918() || IsRFC3927() || IsLocal());
17380 }
17381 
17382 bool CAddress::IsValid() const
17383 {
17384     // Clean up 3-byte shifted addresses caused by garbage in size field
17385     // of addr messages from versions before 0.2.9 checksum.
17386     // Two consecutive addr messages look like this:
17387     // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26...
17388     // so if the first length field is garbled, it reads the second batch
17389     // of addr misaligned by 3 bytes.
17390     if (memcmp(pchReserved, pchIPv4+3, sizeof(pchIPv4)-3) == 0)
17391         return false;
17392 
17393     return (ip != 0 && ip != INADDR_NONE && port != htons(USHRT_MAX));
17394 }
17395 
17396 unsigned char CAddress::GetByte(int n) const
17397 {
17398     return ((unsigned char*)&ip)[3-n];
17399 }
17400 
17401 std::string CAddress::ToStringIPPort() const
17402 {
17403     return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
17404 }
17405 
17406 std::string CAddress::ToStringIP() const
17407 {
17408     return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
17409 }
17410 
17411 std::string CAddress::ToStringPort() const
17412 {
17413     return strprintf("%u", ntohs(port));
17414 }
17415 
17416 std::string CAddress::ToString() const
17417 {
17418     return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
17419 }
17420 
17421 void CAddress::print() const
17422 {
17423     printf("CAddress(%s)\n", ToString().c_str());
17424 }
17425 
17426 CInv::CInv()
17427 {
17428     type = 0;
17429     hash = 0;
17430 }
17431 
17432 CInv::CInv(int typeIn, const uint256& hashIn)
17433 {
17434     type = typeIn;
17435     hash = hashIn;
17436 }
17437 
17438 CInv::CInv(const std::string& strType, const uint256& hashIn)
17439 {
17440     int i;
17441     for (i = 1; i < ARRAYLEN(ppszTypeName); i++)
17442     {
17443         if (strType == ppszTypeName[i])
17444         {
17445             type = i;
17446             break;
17447         }
17448     }
17449     if (i == ARRAYLEN(ppszTypeName))
17450         throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str()));
17451     hash = hashIn;
17452 }
17453 
17454 bool operator<(const CInv& a, const CInv& b)
17455 {
17456     return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
17457 }
17458 
17459 bool CInv::IsKnownType() const
17460 {
17461     return (type >= 1 && type < ARRAYLEN(ppszTypeName));
17462 }
17463 
17464 const char* CInv::GetCommand() const
17465 {
17466     if (!IsKnownType())
17467         throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type));
17468     return ppszTypeName[type];
17469 }
17470 
17471 std::string CInv::ToString() const
17472 {
17473     return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,20).c_str());
17474 }
17475 
17476 void CInv::print() const
17477 {
17478     printf("CInv(%s)\n", ToString().c_str());
17479 }