-
+ 09C7F4CC1247B2EC45FFDAE139FE2574DAE0EB4CD40D0E48CFD5DE49033AB1F4242E564020E4AF5418B12E7A78430C87D58B1D4829C837B9DAE47D1C1CD32382
bitcoin/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 }