File indexing completed on 2020-06-26 13:33:05
0001
0002
0003
0004
0005
0006 #include "protocol.h"
0007 #include "util.h"
0008 #include <arpa/inet.h>
0009
0010
0011
0012 bool Lookup(const char *pszName, std::vector<CAddress>& vaddr, int nServices, int nMaxSolutions, int portDefault = 0, bool fAllowPort = false);
0013 bool Lookup(const char *pszName, CAddress& addr, int nServices, int portDefault = 0, bool fAllowPort = false);
0014
0015 static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
0016 static const char* ppszTypeName[] =
0017 {
0018 "ERROR",
0019 "tx",
0020 "block",
0021 };
0022
0023 CMessageHeader::CMessageHeader()
0024 {
0025 memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));
0026 memset(pchCommand, 0, sizeof(pchCommand));
0027 pchCommand[1] = 1;
0028 nMessageSize = -1;
0029 nChecksum = 0;
0030 }
0031
0032 CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn)
0033 {
0034 memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart));
0035 strncpy(pchCommand, pszCommand, COMMAND_SIZE);
0036 nMessageSize = nMessageSizeIn;
0037 nChecksum = 0;
0038 }
0039
0040 std::string CMessageHeader::GetCommand() const
0041 {
0042 if (pchCommand[COMMAND_SIZE-1] == 0)
0043 return std::string(pchCommand, pchCommand + strlen(pchCommand));
0044 else
0045 return std::string(pchCommand, pchCommand + COMMAND_SIZE);
0046 }
0047
0048 bool CMessageHeader::IsValid() const
0049 {
0050
0051 if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0)
0052 return false;
0053
0054
0055 for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++)
0056 {
0057 if (*p1 == 0)
0058 {
0059
0060 for (; p1 < pchCommand + COMMAND_SIZE; p1++)
0061 if (*p1 != 0)
0062 return false;
0063 }
0064 else if (*p1 < ' ' || *p1 > 0x7E)
0065 return false;
0066 }
0067
0068
0069 if (nMessageSize > MAX_SIZE)
0070 {
0071 printf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand().c_str(), nMessageSize);
0072 return false;
0073 }
0074
0075 return true;
0076 }
0077
0078 CAddress::CAddress()
0079 {
0080 Init();
0081 }
0082
0083 CAddress::CAddress(unsigned int ipIn, unsigned short portIn, uint64 nServicesIn)
0084 {
0085 Init();
0086 ip = ipIn;
0087 port = htons(portIn == 0 ? GetDefaultPort() : portIn);
0088 nServices = nServicesIn;
0089 }
0090
0091 CAddress::CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn)
0092 {
0093 Init();
0094 ip = sockaddr.sin_addr.s_addr;
0095 port = sockaddr.sin_port;
0096 nServices = nServicesIn;
0097 }
0098
0099 CAddress::CAddress(const char* pszIn, int portIn, uint64 nServicesIn)
0100 {
0101 Init();
0102 Lookup(pszIn, *this, nServicesIn, portIn);
0103 }
0104
0105 CAddress::CAddress(const char* pszIn, uint64 nServicesIn)
0106 {
0107 Init();
0108 Lookup(pszIn, *this, nServicesIn, 0, true);
0109 }
0110
0111 CAddress::CAddress(std::string strIn, int portIn, uint64 nServicesIn)
0112 {
0113 Init();
0114 Lookup(strIn.c_str(), *this, nServicesIn, portIn);
0115 }
0116
0117 CAddress::CAddress(std::string strIn, uint64 nServicesIn)
0118 {
0119 Init();
0120 Lookup(strIn.c_str(), *this, nServicesIn, 0, true);
0121 }
0122
0123 void CAddress::Init()
0124 {
0125 nServices = NODE_NETWORK;
0126 memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
0127 ip = INADDR_NONE;
0128 port = htons(GetDefaultPort());
0129 nTime = 100000000;
0130 nLastTry = 0;
0131 }
0132
0133 bool operator==(const CAddress& a, const CAddress& b)
0134 {
0135 return (memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)) == 0 &&
0136 a.ip == b.ip &&
0137 a.port == b.port);
0138 }
0139
0140 bool operator!=(const CAddress& a, const CAddress& b)
0141 {
0142 return (!(a == b));
0143 }
0144
0145 bool operator<(const CAddress& a, const CAddress& b)
0146 {
0147 int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved));
0148 if (ret < 0)
0149 return true;
0150 else if (ret == 0)
0151 {
0152 if (ntohl(a.ip) < ntohl(b.ip))
0153 return true;
0154 else if (a.ip == b.ip)
0155 return ntohs(a.port) < ntohs(b.port);
0156 }
0157 return false;
0158 }
0159
0160 std::vector<unsigned char> CAddress::GetKey() const
0161 {
0162 CDataStream ss;
0163 ss.reserve(18);
0164 ss << FLATDATA(pchReserved) << ip << port;
0165
0166 return std::vector<unsigned char>(ss.begin(), ss.end());
0167 }
0168
0169 struct sockaddr_in CAddress::GetSockAddr() const
0170 {
0171 struct sockaddr_in sockaddr;
0172 memset(&sockaddr, 0, sizeof(sockaddr));
0173 sockaddr.sin_family = AF_INET;
0174 sockaddr.sin_addr.s_addr = ip;
0175 sockaddr.sin_port = port;
0176 return sockaddr;
0177 }
0178
0179 bool CAddress::IsIPv4() const
0180 {
0181 return (memcmp(pchReserved, pchIPv4, sizeof(pchIPv4)) == 0);
0182 }
0183
0184 bool CAddress::IsRFC1918() const
0185 {
0186 return IsIPv4() && (GetByte(3) == 10 ||
0187 (GetByte(3) == 192 && GetByte(2) == 168) ||
0188 (GetByte(3) == 172 &&
0189 (GetByte(2) >= 16 && GetByte(2) <= 31)));
0190 }
0191
0192 bool CAddress::IsRFC3927() const
0193 {
0194 return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254);
0195 }
0196
0197 bool CAddress::IsLocal() const
0198 {
0199 return IsIPv4() && (GetByte(3) == 127 ||
0200 GetByte(3) == 0);
0201 }
0202
0203 bool CAddress::IsRoutable() const
0204 {
0205 return IsValid() &&
0206 !(IsRFC1918() || IsRFC3927() || IsLocal());
0207 }
0208
0209 bool CAddress::IsValid() const
0210 {
0211
0212
0213
0214
0215
0216
0217 if (memcmp(pchReserved, pchIPv4+3, sizeof(pchIPv4)-3) == 0)
0218 return false;
0219
0220 return (ip != 0 && ip != INADDR_NONE && port != htons(USHRT_MAX));
0221 }
0222
0223 unsigned char CAddress::GetByte(int n) const
0224 {
0225 return ((unsigned char*)&ip)[3-n];
0226 }
0227
0228 std::string CAddress::ToStringIPPort() const
0229 {
0230 return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
0231 }
0232
0233 std::string CAddress::ToStringIP() const
0234 {
0235 return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
0236 }
0237
0238 std::string CAddress::ToStringPort() const
0239 {
0240 return strprintf("%u", ntohs(port));
0241 }
0242
0243 std::string CAddress::ToString() const
0244 {
0245 return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port));
0246 }
0247
0248 void CAddress::print() const
0249 {
0250 printf("CAddress(%s)\n", ToString().c_str());
0251 }
0252
0253 CInv::CInv()
0254 {
0255 type = 0;
0256 hash = 0;
0257 }
0258
0259 CInv::CInv(int typeIn, const uint256& hashIn)
0260 {
0261 type = typeIn;
0262 hash = hashIn;
0263 }
0264
0265 CInv::CInv(const std::string& strType, const uint256& hashIn)
0266 {
0267 int i;
0268 for (i = 1; i < ARRAYLEN(ppszTypeName); i++)
0269 {
0270 if (strType == ppszTypeName[i])
0271 {
0272 type = i;
0273 break;
0274 }
0275 }
0276 if (i == ARRAYLEN(ppszTypeName))
0277 throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str()));
0278 hash = hashIn;
0279 }
0280
0281 bool operator<(const CInv& a, const CInv& b)
0282 {
0283 return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
0284 }
0285
0286 bool CInv::IsKnownType() const
0287 {
0288 return (type >= 1 && type < ARRAYLEN(ppszTypeName));
0289 }
0290
0291 const char* CInv::GetCommand() const
0292 {
0293 if (!IsKnownType())
0294 throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type));
0295 return ppszTypeName[type];
0296 }
0297
0298 std::string CInv::ToString() const
0299 {
0300 return strprintf("%s %s", GetCommand(), hash.ToString().c_str());
0301 }
0302
0303 void CInv::print() const
0304 {
0305 printf("CInv(%s)\n", ToString().c_str());
0306 }