Mercurial > hg > bitcoin
annotate src/netbase.cpp @ 2476:a9b012461972 draft
IPv6 node support
This will make bitcoin relay valid routable IPv6 addresses, and when
USE_IPV6 is enabled, listen on IPv6 interfaces and attempt connections
to IPv6 addresses.
author | Pieter Wuille <pieter.wuille@gmail.com> |
---|---|
date | Sat, 31 Mar 2012 17:58:25 +0200 |
parents | 1f0e9f9f3e51 |
children | f8e75c9db98a |
rev | line source |
---|---|
1731 | 1 // Copyright (c) 2009-2010 Satoshi Nakamoto |
1818
20667468f95b
Update all copyrights to 2012
Gavin Andresen <gavinandresen@gmail.com>
parents:
1762
diff
changeset
|
2 // Copyright (c) 2009-2012 The Bitcoin developers |
1731 | 3 // Distributed under the MIT/X11 software license, see the accompanying |
4 // file license.txt or http://www.opensource.org/licenses/mit-license.php. | |
5 | |
6 #include "netbase.h" | |
7 #include "util.h" | |
8 | |
9 #ifndef WIN32 | |
10 #include <sys/fcntl.h> | |
11 #endif | |
12 | |
13 #include "strlcpy.h" | |
14 | |
15 using namespace std; | |
16 | |
17 // Settings | |
2363
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
18 int nSocksVersion = 5; |
1731 | 19 int fUseProxy = false; |
2363
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
20 bool fProxyNameLookup = false; |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
21 bool fNameLookup = false; |
1731 | 22 CService addrProxy("127.0.0.1",9050); |
23 int nConnectTimeout = 5000; | |
24 | |
25 | |
26 static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; | |
27 | |
2257
d2314c70384e
Fix sign-compare warnings: netbase's Lookup* max-solutions may be unsigned
Jeff Garzik <jeff@garzik.org>
parents:
2256
diff
changeset
|
28 bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup) |
1731 | 29 { |
30 vIP.clear(); | |
1749
a16663dadac9
Compile with extra warnings turned on. And more makefile/code tidying up.
Gavin Andresen <gavinandresen@gmail.com>
parents:
1731
diff
changeset
|
31 struct addrinfo aiHint; |
a16663dadac9
Compile with extra warnings turned on. And more makefile/code tidying up.
Gavin Andresen <gavinandresen@gmail.com>
parents:
1731
diff
changeset
|
32 memset(&aiHint, 0, sizeof(struct addrinfo)); |
a16663dadac9
Compile with extra warnings turned on. And more makefile/code tidying up.
Gavin Andresen <gavinandresen@gmail.com>
parents:
1731
diff
changeset
|
33 |
1731 | 34 aiHint.ai_socktype = SOCK_STREAM; |
35 aiHint.ai_protocol = IPPROTO_TCP; | |
36 #ifdef WIN32 | |
37 # ifdef USE_IPV6 | |
38 aiHint.ai_family = AF_UNSPEC; | |
39 aiHint.ai_flags = fAllowLookup ? 0 : AI_NUMERICHOST; | |
40 # else | |
41 aiHint.ai_family = AF_INET; | |
42 aiHint.ai_flags = fAllowLookup ? 0 : AI_NUMERICHOST; | |
43 # endif | |
44 #else | |
45 # ifdef USE_IPV6 | |
46 aiHint.ai_family = AF_UNSPEC; | |
47 aiHint.ai_flags = AI_ADDRCONFIG | (fAllowLookup ? 0 : AI_NUMERICHOST); | |
48 # else | |
49 aiHint.ai_family = AF_INET; | |
50 aiHint.ai_flags = AI_ADDRCONFIG | (fAllowLookup ? 0 : AI_NUMERICHOST); | |
51 # endif | |
52 #endif | |
53 struct addrinfo *aiRes = NULL; | |
54 int nErr = getaddrinfo(pszName, NULL, &aiHint, &aiRes); | |
55 if (nErr) | |
56 return false; | |
57 | |
58 struct addrinfo *aiTrav = aiRes; | |
59 while (aiTrav != NULL && (nMaxSolutions == 0 || vIP.size() < nMaxSolutions)) | |
60 { | |
61 if (aiTrav->ai_family == AF_INET) | |
62 { | |
63 assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in)); | |
64 vIP.push_back(CNetAddr(((struct sockaddr_in*)(aiTrav->ai_addr))->sin_addr)); | |
65 } | |
66 | |
67 #ifdef USE_IPV6 | |
68 if (aiTrav->ai_family == AF_INET6) | |
69 { | |
70 assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in6)); | |
71 vIP.push_back(CNetAddr(((struct sockaddr_in6*)(aiTrav->ai_addr))->sin6_addr)); | |
72 } | |
73 #endif | |
74 | |
75 aiTrav = aiTrav->ai_next; | |
76 } | |
77 | |
78 freeaddrinfo(aiRes); | |
79 | |
80 return (vIP.size() > 0); | |
81 } | |
82 | |
2257
d2314c70384e
Fix sign-compare warnings: netbase's Lookup* max-solutions may be unsigned
Jeff Garzik <jeff@garzik.org>
parents:
2256
diff
changeset
|
83 bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup) |
1731 | 84 { |
85 if (pszName[0] == 0) | |
86 return false; | |
87 char psz[256]; | |
88 char *pszHost = psz; | |
89 strlcpy(psz, pszName, sizeof(psz)); | |
90 if (psz[0] == '[' && psz[strlen(psz)-1] == ']') | |
91 { | |
92 pszHost = psz+1; | |
93 psz[strlen(psz)-1] = 0; | |
94 } | |
95 | |
96 return LookupIntern(pszHost, vIP, nMaxSolutions, fAllowLookup); | |
97 } | |
98 | |
2257
d2314c70384e
Fix sign-compare warnings: netbase's Lookup* max-solutions may be unsigned
Jeff Garzik <jeff@garzik.org>
parents:
2256
diff
changeset
|
99 bool LookupHostNumeric(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions) |
1731 | 100 { |
101 return LookupHost(pszName, vIP, nMaxSolutions, false); | |
102 } | |
103 | |
2257
d2314c70384e
Fix sign-compare warnings: netbase's Lookup* max-solutions may be unsigned
Jeff Garzik <jeff@garzik.org>
parents:
2256
diff
changeset
|
104 bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions) |
1731 | 105 { |
106 if (pszName[0] == 0) | |
107 return false; | |
108 int port = portDefault; | |
109 char psz[256]; | |
110 char *pszHost = psz; | |
111 strlcpy(psz, pszName, sizeof(psz)); | |
112 char* pszColon = strrchr(psz+1,':'); | |
113 char *pszPortEnd = NULL; | |
114 int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0; | |
115 if (pszColon && pszPortEnd && pszPortEnd[0] == 0) | |
116 { | |
117 if (psz[0] == '[' && pszColon[-1] == ']') | |
118 { | |
119 pszHost = psz+1; | |
120 pszColon[-1] = 0; | |
121 } | |
122 else | |
123 pszColon[0] = 0; | |
124 if (port >= 0 && port <= USHRT_MAX) | |
125 port = portParsed; | |
126 } | |
127 else | |
128 { | |
129 if (psz[0] == '[' && psz[strlen(psz)-1] == ']') | |
130 { | |
131 pszHost = psz+1; | |
132 psz[strlen(psz)-1] = 0; | |
133 } | |
134 | |
135 } | |
136 | |
137 std::vector<CNetAddr> vIP; | |
1747
77ce235c56b7
Add -keepnode which attempts to -addnode and keep a connection open
Matt Corallo <matt@bluematt.me>
parents:
1731
diff
changeset
|
138 bool fRet = LookupIntern(pszHost, vIP, nMaxSolutions, fAllowLookup); |
1731 | 139 if (!fRet) |
140 return false; | |
1747
77ce235c56b7
Add -keepnode which attempts to -addnode and keep a connection open
Matt Corallo <matt@bluematt.me>
parents:
1731
diff
changeset
|
141 vAddr.resize(vIP.size()); |
2256
341e07b996f2
Fix loop index var types, fixing many minor sign comparison warnings
Jeff Garzik <jeff@garzik.org>
parents:
1911
diff
changeset
|
142 for (unsigned int i = 0; i < vIP.size(); i++) |
1747
77ce235c56b7
Add -keepnode which attempts to -addnode and keep a connection open
Matt Corallo <matt@bluematt.me>
parents:
1731
diff
changeset
|
143 vAddr[i] = CService(vIP[i], port); |
77ce235c56b7
Add -keepnode which attempts to -addnode and keep a connection open
Matt Corallo <matt@bluematt.me>
parents:
1731
diff
changeset
|
144 return true; |
77ce235c56b7
Add -keepnode which attempts to -addnode and keep a connection open
Matt Corallo <matt@bluematt.me>
parents:
1731
diff
changeset
|
145 } |
77ce235c56b7
Add -keepnode which attempts to -addnode and keep a connection open
Matt Corallo <matt@bluematt.me>
parents:
1731
diff
changeset
|
146 |
77ce235c56b7
Add -keepnode which attempts to -addnode and keep a connection open
Matt Corallo <matt@bluematt.me>
parents:
1731
diff
changeset
|
147 bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLookup) |
77ce235c56b7
Add -keepnode which attempts to -addnode and keep a connection open
Matt Corallo <matt@bluematt.me>
parents:
1731
diff
changeset
|
148 { |
77ce235c56b7
Add -keepnode which attempts to -addnode and keep a connection open
Matt Corallo <matt@bluematt.me>
parents:
1731
diff
changeset
|
149 std::vector<CService> vService; |
77ce235c56b7
Add -keepnode which attempts to -addnode and keep a connection open
Matt Corallo <matt@bluematt.me>
parents:
1731
diff
changeset
|
150 bool fRet = Lookup(pszName, vService, portDefault, fAllowLookup, 1); |
77ce235c56b7
Add -keepnode which attempts to -addnode and keep a connection open
Matt Corallo <matt@bluematt.me>
parents:
1731
diff
changeset
|
151 if (!fRet) |
77ce235c56b7
Add -keepnode which attempts to -addnode and keep a connection open
Matt Corallo <matt@bluematt.me>
parents:
1731
diff
changeset
|
152 return false; |
77ce235c56b7
Add -keepnode which attempts to -addnode and keep a connection open
Matt Corallo <matt@bluematt.me>
parents:
1731
diff
changeset
|
153 addr = vService[0]; |
1731 | 154 return true; |
155 } | |
156 | |
157 bool LookupNumeric(const char *pszName, CService& addr, int portDefault) | |
158 { | |
159 return Lookup(pszName, addr, portDefault, false); | |
160 } | |
161 | |
2360
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
162 bool static Socks4(const CService &addrDest, SOCKET& hSocket) |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
163 { |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
164 printf("SOCKS4 connecting %s\n", addrDest.ToString().c_str()); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
165 if (!addrDest.IsIPv4()) |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
166 { |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
167 closesocket(hSocket); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
168 return error("Proxy destination is not IPv4"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
169 } |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
170 char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user"; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
171 struct sockaddr_in addr; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
172 addrDest.GetSockAddr(&addr); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
173 memcpy(pszSocks4IP + 2, &addr.sin_port, 2); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
174 memcpy(pszSocks4IP + 4, &addr.sin_addr, 4); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
175 char* pszSocks4 = pszSocks4IP; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
176 int nSize = sizeof(pszSocks4IP); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
177 |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
178 int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
179 if (ret != nSize) |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
180 { |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
181 closesocket(hSocket); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
182 return error("Error sending to proxy"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
183 } |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
184 char pchRet[8]; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
185 if (recv(hSocket, pchRet, 8, 0) != 8) |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
186 { |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
187 closesocket(hSocket); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
188 return error("Error reading proxy response"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
189 } |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
190 if (pchRet[1] != 0x5a) |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
191 { |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
192 closesocket(hSocket); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
193 if (pchRet[1] != 0x5b) |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
194 printf("ERROR: Proxy returned error %d\n", pchRet[1]); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
195 return false; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
196 } |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
197 printf("SOCKS4 connected %s\n", addrDest.ToString().c_str()); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
198 return true; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
199 } |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
200 |
2362
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
201 bool static Socks5(string strDest, int port, SOCKET& hSocket) |
2360
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
202 { |
2362
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
203 printf("SOCKS5 connecting %s\n", strDest.c_str()); |
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
204 if (strDest.size() > 255) |
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
205 { |
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
206 closesocket(hSocket); |
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
207 return error("Hostname too long"); |
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
208 } |
2360
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
209 char pszSocks5Init[] = "\5\1\0"; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
210 char *pszSocks5 = pszSocks5Init; |
2422 | 211 ssize_t nSize = sizeof(pszSocks5Init); |
2360
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
212 |
2422 | 213 ssize_t ret = send(hSocket, pszSocks5, nSize, MSG_NOSIGNAL); |
2360
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
214 if (ret != nSize) |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
215 { |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
216 closesocket(hSocket); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
217 return error("Error sending to proxy"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
218 } |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
219 char pchRet1[2]; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
220 if (recv(hSocket, pchRet1, 2, 0) != 2) |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
221 { |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
222 closesocket(hSocket); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
223 return error("Error reading proxy response"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
224 } |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
225 if (pchRet1[0] != 0x05 || pchRet1[1] != 0x00) |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
226 { |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
227 closesocket(hSocket); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
228 return error("Proxy failed to initialize"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
229 } |
2361
812ed27a255f
SOCKS5 connect via hostname
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2360
diff
changeset
|
230 string strSocks5("\5\1"); |
812ed27a255f
SOCKS5 connect via hostname
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2360
diff
changeset
|
231 strSocks5 += '\000'; strSocks5 += '\003'; |
812ed27a255f
SOCKS5 connect via hostname
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2360
diff
changeset
|
232 strSocks5 += static_cast<char>(std::min((int)strDest.size(), 255)); |
2362
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
233 strSocks5 += strDest; |
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
234 strSocks5 += static_cast<char>((port >> 8) & 0xFF); |
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
235 strSocks5 += static_cast<char>((port >> 0) & 0xFF); |
2361
812ed27a255f
SOCKS5 connect via hostname
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2360
diff
changeset
|
236 ret = send(hSocket, strSocks5.c_str(), strSocks5.size(), MSG_NOSIGNAL); |
2422 | 237 if (ret != (ssize_t)strSocks5.size()) |
2360
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
238 { |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
239 closesocket(hSocket); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
240 return error("Error sending to proxy"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
241 } |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
242 char pchRet2[4]; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
243 if (recv(hSocket, pchRet2, 4, 0) != 4) |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
244 { |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
245 closesocket(hSocket); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
246 return error("Error reading proxy response"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
247 } |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
248 if (pchRet2[0] != 0x05) |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
249 { |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
250 closesocket(hSocket); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
251 return error("Proxy failed to accept request"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
252 } |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
253 if (pchRet2[1] != 0x00) |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
254 { |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
255 closesocket(hSocket); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
256 switch (pchRet2[1]) |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
257 { |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
258 case 0x01: return error("Proxy error: general failure"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
259 case 0x02: return error("Proxy error: connection not allowed"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
260 case 0x03: return error("Proxy error: network unreachable"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
261 case 0x04: return error("Proxy error: host unreachable"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
262 case 0x05: return error("Proxy error: connection refused"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
263 case 0x06: return error("Proxy error: TTL expired"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
264 case 0x07: return error("Proxy error: protocol error"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
265 case 0x08: return error("Proxy error: address type not supported"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
266 default: return error("Proxy error: unknown"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
267 } |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
268 } |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
269 if (pchRet2[2] != 0x00) |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
270 { |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
271 closesocket(hSocket); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
272 return error("Error: malformed proxy response"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
273 } |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
274 char pchRet3[256]; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
275 switch (pchRet2[3]) |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
276 { |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
277 case 0x01: ret = recv(hSocket, pchRet3, 4, 0) != 4; break; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
278 case 0x04: ret = recv(hSocket, pchRet3, 16, 0) != 16; break; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
279 case 0x03: |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
280 { |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
281 ret = recv(hSocket, pchRet3, 1, 0) != 1; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
282 if (ret) |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
283 return error("Error reading from proxy"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
284 int nRecv = pchRet3[0]; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
285 ret = recv(hSocket, pchRet3, nRecv, 0) != nRecv; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
286 break; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
287 } |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
288 default: closesocket(hSocket); return error("Error: malformed proxy response"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
289 } |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
290 if (ret) |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
291 { |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
292 closesocket(hSocket); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
293 return error("Error reading from proxy"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
294 } |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
295 if (recv(hSocket, pchRet3, 2, 0) != 2) |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
296 { |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
297 closesocket(hSocket); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
298 return error("Error reading from proxy"); |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
299 } |
2362
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
300 printf("SOCKS5 connected %s\n", strDest.c_str()); |
2360
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
301 return true; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
302 } |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
303 |
2362
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
304 bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout) |
1731 | 305 { |
306 hSocketRet = INVALID_SOCKET; | |
307 | |
2476 | 308 struct sockaddr_storage sockaddr; |
309 int nFamily = 0; | |
310 size_t nSockAddrLen = 0; | |
311 | |
312 if (addrConnect.IsIPv4()) | |
313 { | |
314 // Use IPv4 stack to connect to IPv4 addresses | |
315 struct sockaddr_in sockaddr4; | |
316 if (!addrConnect.GetSockAddr(&sockaddr4)) | |
317 return false; | |
318 memcpy(&sockaddr, &sockaddr4, sizeof(sockaddr4)); | |
319 nSockAddrLen = sizeof(sockaddr4); | |
320 nFamily = AF_INET; | |
321 } | |
322 #ifdef USE_IPV6 | |
323 else if (addrConnect.IsIPv6()) | |
324 { | |
325 struct sockaddr_in6 sockaddr6; | |
326 if (!addrConnect.GetSockAddr6(&sockaddr6)) | |
327 return false; | |
328 memcpy(&sockaddr, &sockaddr6, sizeof(sockaddr6)); | |
329 nSockAddrLen = sizeof(sockaddr6); | |
330 nFamily = AF_INET6; | |
331 } | |
332 #endif | |
333 else { | |
334 printf("Cannot connect to %s: unsupported network\n", addrConnect.ToString().c_str()); | |
335 return false; | |
336 } | |
337 | |
338 SOCKET hSocket = socket(nFamily, SOCK_STREAM, IPPROTO_TCP); | |
1731 | 339 if (hSocket == INVALID_SOCKET) |
340 return false; | |
341 #ifdef SO_NOSIGPIPE | |
342 int set = 1; | |
343 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); | |
344 #endif | |
345 | |
346 #ifdef WIN32 | |
347 u_long fNonblock = 1; | |
348 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) | |
349 #else | |
350 int fFlags = fcntl(hSocket, F_GETFL, 0); | |
351 if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1) | |
352 #endif | |
353 { | |
354 closesocket(hSocket); | |
355 return false; | |
356 } | |
357 | |
2476 | 358 if (connect(hSocket, (struct sockaddr*)&sockaddr, nSockAddrLen) == SOCKET_ERROR) |
1731 | 359 { |
360 // WSAEINVAL is here because some legacy version of winsock uses it | |
361 if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL) | |
362 { | |
363 struct timeval timeout; | |
364 timeout.tv_sec = nTimeout / 1000; | |
365 timeout.tv_usec = (nTimeout % 1000) * 1000; | |
366 | |
367 fd_set fdset; | |
368 FD_ZERO(&fdset); | |
369 FD_SET(hSocket, &fdset); | |
370 int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout); | |
371 if (nRet == 0) | |
372 { | |
373 printf("connection timeout\n"); | |
374 closesocket(hSocket); | |
375 return false; | |
376 } | |
377 if (nRet == SOCKET_ERROR) | |
378 { | |
379 printf("select() for connection failed: %i\n",WSAGetLastError()); | |
380 closesocket(hSocket); | |
381 return false; | |
382 } | |
383 socklen_t nRetSize = sizeof(nRet); | |
384 #ifdef WIN32 | |
385 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR) | |
386 #else | |
387 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR) | |
388 #endif | |
389 { | |
390 printf("getsockopt() for connection failed: %i\n",WSAGetLastError()); | |
391 closesocket(hSocket); | |
392 return false; | |
393 } | |
394 if (nRet != 0) | |
395 { | |
396 printf("connect() failed after select(): %s\n",strerror(nRet)); | |
397 closesocket(hSocket); | |
398 return false; | |
399 } | |
400 } | |
401 #ifdef WIN32 | |
402 else if (WSAGetLastError() != WSAEISCONN) | |
403 #else | |
404 else | |
405 #endif | |
406 { | |
407 printf("connect() failed: %i\n",WSAGetLastError()); | |
408 closesocket(hSocket); | |
409 return false; | |
410 } | |
411 } | |
412 | |
413 // this isn't even strictly necessary | |
414 // CNode::ConnectNode immediately turns the socket back to non-blocking | |
415 // but we'll turn it back to blocking just in case | |
416 #ifdef WIN32 | |
417 fNonblock = 0; | |
418 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) | |
419 #else | |
420 fFlags = fcntl(hSocket, F_GETFL, 0); | |
421 if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR) | |
422 #endif | |
423 { | |
424 closesocket(hSocket); | |
425 return false; | |
426 } | |
427 | |
2362
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
428 hSocketRet = hSocket; |
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
429 return true; |
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
430 } |
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
431 |
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
432 bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout) |
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
433 { |
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
434 SOCKET hSocket = INVALID_SOCKET; |
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
435 bool fProxy = (fUseProxy && addrDest.IsRoutable()); |
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
436 |
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
437 if (!ConnectSocketDirectly(fProxy ? addrProxy : addrDest, hSocket, nTimeout)) |
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
438 return false; |
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
439 |
1731 | 440 if (fProxy) |
441 { | |
2363
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
442 switch(nSocksVersion) |
1731 | 443 { |
2360
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
444 case 4: |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
445 if (!Socks4(addrDest, hSocket)) |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
446 return false; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
447 break; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
448 |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
449 case 5: |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
450 default: |
2362
f130873df296
refactor ConnectSocket
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2361
diff
changeset
|
451 if (!Socks5(addrDest.ToStringIP(), addrDest.GetPort(), hSocket)) |
2360
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
452 return false; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
453 break; |
5c7c8fa1d568
SOCKS5 support by default
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2257
diff
changeset
|
454 } |
1731 | 455 } |
456 | |
457 hSocketRet = hSocket; | |
458 return true; | |
459 } | |
460 | |
2363
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
461 bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout) |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
462 { |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
463 string strDest(pszDest); |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
464 int port = portDefault; |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
465 |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
466 size_t colon = strDest.find_last_of(':'); |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
467 char *endp = NULL; |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
468 int n = strtol(pszDest + colon + 1, &endp, 10); |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
469 if (endp && *endp == 0 && n >= 0) { |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
470 strDest = strDest.substr(0, colon); |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
471 if (n > 0 && n < 0x10000) |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
472 port = n; |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
473 } |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
474 if (strDest[0] == '[' && strDest[strDest.size()-1] == ']') |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
475 strDest = strDest.substr(1, strDest.size()-2); |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
476 |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
477 SOCKET hSocket = INVALID_SOCKET; |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
478 CService addrResolved(CNetAddr(strDest, fNameLookup && !fProxyNameLookup), port); |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
479 if (addrResolved.IsValid()) { |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
480 addr = addrResolved; |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
481 return ConnectSocket(addr, hSocketRet, nTimeout); |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
482 } |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
483 addr = CService("0.0.0.0:0"); |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
484 if (!fNameLookup) |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
485 return false; |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
486 if (!ConnectSocketDirectly(addrProxy, hSocket, nTimeout)) |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
487 return false; |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
488 |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
489 switch(nSocksVersion) |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
490 { |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
491 case 4: return false; |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
492 case 5: |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
493 default: |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
494 if (!Socks5(strDest, port, hSocket)) |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
495 return false; |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
496 break; |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
497 } |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
498 |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
499 hSocketRet = hSocket; |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
500 return true; |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
501 } |
978eaea61f78
Support connecting by hostnames passed to proxy (-proxydns)
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2362
diff
changeset
|
502 |
1731 | 503 void CNetAddr::Init() |
504 { | |
505 memset(ip, 0, 16); | |
506 } | |
507 | |
508 void CNetAddr::SetIP(const CNetAddr& ipIn) | |
509 { | |
510 memcpy(ip, ipIn.ip, sizeof(ip)); | |
511 } | |
512 | |
513 CNetAddr::CNetAddr() | |
514 { | |
515 Init(); | |
516 } | |
517 | |
518 CNetAddr::CNetAddr(const struct in_addr& ipv4Addr) | |
519 { | |
520 memcpy(ip, pchIPv4, 12); | |
521 memcpy(ip+12, &ipv4Addr, 4); | |
522 } | |
523 | |
524 #ifdef USE_IPV6 | |
525 CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr) | |
526 { | |
527 memcpy(ip, &ipv6Addr, 16); | |
528 } | |
529 #endif | |
530 | |
531 CNetAddr::CNetAddr(const char *pszIp, bool fAllowLookup) | |
532 { | |
533 Init(); | |
534 std::vector<CNetAddr> vIP; | |
535 if (LookupHost(pszIp, vIP, 1, fAllowLookup)) | |
536 *this = vIP[0]; | |
537 } | |
538 | |
539 CNetAddr::CNetAddr(const std::string &strIp, bool fAllowLookup) | |
540 { | |
541 Init(); | |
542 std::vector<CNetAddr> vIP; | |
543 if (LookupHost(strIp.c_str(), vIP, 1, fAllowLookup)) | |
544 *this = vIP[0]; | |
545 } | |
546 | |
547 int CNetAddr::GetByte(int n) const | |
548 { | |
549 return ip[15-n]; | |
550 } | |
551 | |
552 bool CNetAddr::IsIPv4() const | |
553 { | |
554 return (memcmp(ip, pchIPv4, sizeof(pchIPv4)) == 0); | |
555 } | |
556 | |
2476 | 557 bool CNetAddr::IsIPv6() const |
558 { | |
559 return (!IsIPv4()); | |
560 } | |
561 | |
1731 | 562 bool CNetAddr::IsRFC1918() const |
563 { | |
564 return IsIPv4() && ( | |
565 GetByte(3) == 10 || | |
566 (GetByte(3) == 192 && GetByte(2) == 168) || | |
567 (GetByte(3) == 172 && (GetByte(2) >= 16 && GetByte(2) <= 31))); | |
568 } | |
569 | |
570 bool CNetAddr::IsRFC3927() const | |
571 { | |
572 return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254); | |
573 } | |
574 | |
575 bool CNetAddr::IsRFC3849() const | |
576 { | |
577 return GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x0D && GetByte(12) == 0xB8; | |
578 } | |
579 | |
580 bool CNetAddr::IsRFC3964() const | |
581 { | |
582 return (GetByte(15) == 0x20 && GetByte(14) == 0x02); | |
583 } | |
584 | |
585 bool CNetAddr::IsRFC6052() const | |
586 { | |
587 static const unsigned char pchRFC6052[] = {0,0x64,0xFF,0x9B,0,0,0,0,0,0,0,0}; | |
588 return (memcmp(ip, pchRFC6052, sizeof(pchRFC6052)) == 0); | |
589 } | |
590 | |
591 bool CNetAddr::IsRFC4380() const | |
592 { | |
593 return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0 && GetByte(12) == 0); | |
594 } | |
595 | |
596 bool CNetAddr::IsRFC4862() const | |
597 { | |
598 static const unsigned char pchRFC4862[] = {0xFE,0x80,0,0,0,0,0,0}; | |
599 return (memcmp(ip, pchRFC4862, sizeof(pchRFC4862)) == 0); | |
600 } | |
601 | |
602 bool CNetAddr::IsRFC4193() const | |
603 { | |
604 return ((GetByte(15) & 0xFE) == 0xFC); | |
605 } | |
606 | |
607 bool CNetAddr::IsRFC6145() const | |
608 { | |
609 static const unsigned char pchRFC6145[] = {0,0,0,0,0,0,0,0,0xFF,0xFF,0,0}; | |
610 return (memcmp(ip, pchRFC6145, sizeof(pchRFC6145)) == 0); | |
611 } | |
612 | |
613 bool CNetAddr::IsRFC4843() const | |
614 { | |
1856
54a8b11aba45
fix typo in CNetAddr::IsRFC4843() (fixes #850)
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
1818
diff
changeset
|
615 return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x00 && (GetByte(12) & 0xF0) == 0x10); |
1731 | 616 } |
617 | |
618 bool CNetAddr::IsLocal() const | |
619 { | |
620 // IPv4 loopback | |
621 if (IsIPv4() && (GetByte(3) == 127 || GetByte(3) == 0)) | |
622 return true; | |
623 | |
624 // IPv6 loopback (::1/128) | |
625 static const unsigned char pchLocal[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; | |
626 if (memcmp(ip, pchLocal, 16) == 0) | |
627 return true; | |
628 | |
629 return false; | |
630 } | |
631 | |
632 bool CNetAddr::IsMulticast() const | |
633 { | |
634 return (IsIPv4() && (GetByte(3) & 0xF0) == 0xE0) | |
635 || (GetByte(15) == 0xFF); | |
636 } | |
637 | |
638 bool CNetAddr::IsValid() const | |
639 { | |
640 // Clean up 3-byte shifted addresses caused by garbage in size field | |
641 // of addr messages from versions before 0.2.9 checksum. | |
642 // Two consecutive addr messages look like this: | |
643 // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26... | |
644 // so if the first length field is garbled, it reads the second batch | |
645 // of addr misaligned by 3 bytes. | |
646 if (memcmp(ip, pchIPv4+3, sizeof(pchIPv4)-3) == 0) | |
647 return false; | |
648 | |
649 // unspecified IPv6 address (::/128) | |
650 unsigned char ipNone[16] = {}; | |
651 if (memcmp(ip, ipNone, 16) == 0) | |
652 return false; | |
653 | |
654 // documentation IPv6 address | |
655 if (IsRFC3849()) | |
656 return false; | |
657 | |
658 if (IsIPv4()) | |
659 { | |
660 // INADDR_NONE | |
661 uint32_t ipNone = INADDR_NONE; | |
662 if (memcmp(ip+12, &ipNone, 4) == 0) | |
663 return false; | |
664 | |
665 // 0 | |
666 ipNone = 0; | |
667 if (memcmp(ip+12, &ipNone, 4) == 0) | |
668 return false; | |
669 } | |
670 | |
671 return true; | |
672 } | |
673 | |
674 bool CNetAddr::IsRoutable() const | |
675 { | |
676 return IsValid() && !(IsRFC1918() || IsRFC3927() || IsRFC4862() || IsRFC4193() || IsRFC4843() || IsLocal()); | |
677 } | |
678 | |
679 std::string CNetAddr::ToStringIP() const | |
680 { | |
681 if (IsIPv4()) | |
682 return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); | |
683 else | |
684 return strprintf("%x:%x:%x:%x:%x:%x:%x:%x", | |
685 GetByte(15) << 8 | GetByte(14), GetByte(13) << 8 | GetByte(12), | |
686 GetByte(11) << 8 | GetByte(10), GetByte(9) << 8 | GetByte(8), | |
687 GetByte(7) << 8 | GetByte(6), GetByte(5) << 8 | GetByte(4), | |
688 GetByte(3) << 8 | GetByte(2), GetByte(1) << 8 | GetByte(0)); | |
689 } | |
690 | |
691 std::string CNetAddr::ToString() const | |
692 { | |
693 return ToStringIP(); | |
694 } | |
695 | |
696 bool operator==(const CNetAddr& a, const CNetAddr& b) | |
697 { | |
698 return (memcmp(a.ip, b.ip, 16) == 0); | |
699 } | |
700 | |
701 bool operator!=(const CNetAddr& a, const CNetAddr& b) | |
702 { | |
703 return (memcmp(a.ip, b.ip, 16) != 0); | |
704 } | |
705 | |
706 bool operator<(const CNetAddr& a, const CNetAddr& b) | |
707 { | |
708 return (memcmp(a.ip, b.ip, 16) < 0); | |
709 } | |
710 | |
711 bool CNetAddr::GetInAddr(struct in_addr* pipv4Addr) const | |
712 { | |
713 if (!IsIPv4()) | |
714 return false; | |
715 memcpy(pipv4Addr, ip+12, 4); | |
716 return true; | |
717 } | |
718 | |
719 #ifdef USE_IPV6 | |
720 bool CNetAddr::GetIn6Addr(struct in6_addr* pipv6Addr) const | |
721 { | |
722 memcpy(pipv6Addr, ip, 16); | |
723 return true; | |
724 } | |
725 #endif | |
726 | |
727 // get canonical identifier of an address' group | |
728 // no two connections will be attempted to addresses with the same group | |
729 std::vector<unsigned char> CNetAddr::GetGroup() const | |
730 { | |
731 std::vector<unsigned char> vchRet; | |
1911
a9190d020909
CAddrMan: stochastic address manager
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1856
diff
changeset
|
732 int nClass = 0; // 0=IPv6, 1=IPv4, 254=local, 255=unroutable |
1731 | 733 int nStartByte = 0; |
734 int nBits = 16; | |
735 | |
1911
a9190d020909
CAddrMan: stochastic address manager
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1856
diff
changeset
|
736 // all local addresses belong to the same group |
a9190d020909
CAddrMan: stochastic address manager
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1856
diff
changeset
|
737 if (IsLocal()) |
a9190d020909
CAddrMan: stochastic address manager
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1856
diff
changeset
|
738 { |
a9190d020909
CAddrMan: stochastic address manager
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1856
diff
changeset
|
739 nClass = 254; |
a9190d020909
CAddrMan: stochastic address manager
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1856
diff
changeset
|
740 nBits = 0; |
a9190d020909
CAddrMan: stochastic address manager
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1856
diff
changeset
|
741 } |
a9190d020909
CAddrMan: stochastic address manager
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1856
diff
changeset
|
742 |
a9190d020909
CAddrMan: stochastic address manager
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1856
diff
changeset
|
743 // all unroutable addresses belong to the same group |
1731 | 744 if (!IsRoutable()) |
745 { | |
746 nClass = 255; | |
1911
a9190d020909
CAddrMan: stochastic address manager
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1856
diff
changeset
|
747 nBits = 0; |
1731 | 748 } |
749 // for IPv4 addresses, '1' + the 16 higher-order bits of the IP | |
750 // includes mapped IPv4, SIIT translated IPv4, and the well-known prefix | |
751 else if (IsIPv4() || IsRFC6145() || IsRFC6052()) | |
752 { | |
753 nClass = 1; | |
754 nStartByte = 12; | |
755 } | |
756 // for 6to4 tunneled addresses, use the encapsulated IPv4 address | |
757 else if (IsRFC3964()) | |
758 { | |
759 nClass = 1; | |
760 nStartByte = 2; | |
761 } | |
762 // for Teredo-tunneled IPv6 addresses, use the encapsulated IPv4 address | |
763 else if (IsRFC4380()) | |
764 { | |
765 vchRet.push_back(1); | |
766 vchRet.push_back(GetByte(3) ^ 0xFF); | |
767 vchRet.push_back(GetByte(2) ^ 0xFF); | |
768 return vchRet; | |
769 } | |
770 // for he.net, use /36 groups | |
771 else if (GetByte(15) == 0x20 && GetByte(14) == 0x11 && GetByte(13) == 0x04 && GetByte(12) == 0x70) | |
772 nBits = 36; | |
773 // for the rest of the IPv6 network, use /32 groups | |
774 else | |
775 nBits = 32; | |
776 | |
777 vchRet.push_back(nClass); | |
778 while (nBits >= 8) | |
779 { | |
780 vchRet.push_back(GetByte(15 - nStartByte)); | |
781 nStartByte++; | |
782 nBits -= 8; | |
783 } | |
784 if (nBits > 0) | |
785 vchRet.push_back(GetByte(15 - nStartByte) | ((1 << nBits) - 1)); | |
786 | |
787 return vchRet; | |
788 } | |
789 | |
790 int64 CNetAddr::GetHash() const | |
791 { | |
792 uint256 hash = Hash(&ip[0], &ip[16]); | |
793 int64 nRet; | |
794 memcpy(&nRet, &hash, sizeof(nRet)); | |
795 return nRet; | |
796 } | |
797 | |
798 void CNetAddr::print() const | |
799 { | |
800 printf("CNetAddr(%s)\n", ToString().c_str()); | |
801 } | |
802 | |
2417
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
803 // for IPv6 partners: for unknown/Teredo partners: for IPv4 partners: |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
804 // 0 - unroutable // 0 - unroutable // 0 - unroutable |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
805 // 1 - teredo // 1 - teredo // 1 - ipv4 |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
806 // 2 - tunneled ipv6 // 2 - tunneled ipv6 |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
807 // 3 - ipv4 // 3 - ipv6 |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
808 // 4 - ipv6 // 4 - ipv4 |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
809 int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
810 { |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
811 if (!IsValid() || !IsRoutable()) |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
812 return 0; |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
813 if (paddrPartner && paddrPartner->IsIPv4()) |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
814 return IsIPv4() ? 1 : 0; |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
815 if (IsRFC4380()) |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
816 return 1; |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
817 if (IsRFC3964() || IsRFC6052()) |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
818 return 2; |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
819 bool fRealIPv6 = paddrPartner && !paddrPartner->IsRFC4380() && paddrPartner->IsValid() && paddrPartner->IsRoutable(); |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
820 if (fRealIPv6) |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
821 return IsIPv4() ? 3 : 4; |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
822 else |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
823 return IsIPv4() ? 4 : 3; |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
824 } |
fa61c1977722
Support for multiple local addresses
Pieter Wuille <pieter.wuille@gmail.com>
parents:
2363
diff
changeset
|
825 |
1731 | 826 void CService::Init() |
827 { | |
828 port = 0; | |
829 } | |
830 | |
831 CService::CService() | |
832 { | |
833 Init(); | |
834 } | |
835 | |
836 CService::CService(const CNetAddr& cip, unsigned short portIn) : CNetAddr(cip), port(portIn) | |
837 { | |
838 } | |
839 | |
840 CService::CService(const struct in_addr& ipv4Addr, unsigned short portIn) : CNetAddr(ipv4Addr), port(portIn) | |
841 { | |
842 } | |
843 | |
844 #ifdef USE_IPV6 | |
845 CService::CService(const struct in6_addr& ipv6Addr, unsigned short portIn) : CNetAddr(ipv6Addr), port(portIn) | |
846 { | |
847 } | |
848 #endif | |
849 | |
850 CService::CService(const struct sockaddr_in& addr) : CNetAddr(addr.sin_addr), port(ntohs(addr.sin_port)) | |
851 { | |
852 assert(addr.sin_family == AF_INET); | |
853 } | |
854 | |
855 #ifdef USE_IPV6 | |
856 CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr), port(ntohs(addr.sin6_port)) | |
857 { | |
858 assert(addr.sin6_family == AF_INET6); | |
859 } | |
860 #endif | |
861 | |
862 CService::CService(const char *pszIpPort, bool fAllowLookup) | |
863 { | |
864 Init(); | |
865 CService ip; | |
866 if (Lookup(pszIpPort, ip, 0, fAllowLookup)) | |
867 *this = ip; | |
868 } | |
869 | |
1762
3ae3a30451cb
Fix handling of default ports
Pieter Wuille <sipa@ulyssis.org>
parents:
1761
diff
changeset
|
870 CService::CService(const char *pszIpPort, int portDefault, bool fAllowLookup) |
1731 | 871 { |
1762
3ae3a30451cb
Fix handling of default ports
Pieter Wuille <sipa@ulyssis.org>
parents:
1761
diff
changeset
|
872 Init(); |
3ae3a30451cb
Fix handling of default ports
Pieter Wuille <sipa@ulyssis.org>
parents:
1761
diff
changeset
|
873 CService ip; |
3ae3a30451cb
Fix handling of default ports
Pieter Wuille <sipa@ulyssis.org>
parents:
1761
diff
changeset
|
874 if (Lookup(pszIpPort, ip, portDefault, fAllowLookup)) |
3ae3a30451cb
Fix handling of default ports
Pieter Wuille <sipa@ulyssis.org>
parents:
1761
diff
changeset
|
875 *this = ip; |
1731 | 876 } |
877 | |
878 CService::CService(const std::string &strIpPort, bool fAllowLookup) | |
879 { | |
880 Init(); | |
881 CService ip; | |
882 if (Lookup(strIpPort.c_str(), ip, 0, fAllowLookup)) | |
883 *this = ip; | |
884 } | |
885 | |
1762
3ae3a30451cb
Fix handling of default ports
Pieter Wuille <sipa@ulyssis.org>
parents:
1761
diff
changeset
|
886 CService::CService(const std::string &strIpPort, int portDefault, bool fAllowLookup) |
1731 | 887 { |
1762
3ae3a30451cb
Fix handling of default ports
Pieter Wuille <sipa@ulyssis.org>
parents:
1761
diff
changeset
|
888 Init(); |
3ae3a30451cb
Fix handling of default ports
Pieter Wuille <sipa@ulyssis.org>
parents:
1761
diff
changeset
|
889 CService ip; |
3ae3a30451cb
Fix handling of default ports
Pieter Wuille <sipa@ulyssis.org>
parents:
1761
diff
changeset
|
890 if (Lookup(strIpPort.c_str(), ip, portDefault, fAllowLookup)) |
3ae3a30451cb
Fix handling of default ports
Pieter Wuille <sipa@ulyssis.org>
parents:
1761
diff
changeset
|
891 *this = ip; |
1731 | 892 } |
893 | |
894 unsigned short CService::GetPort() const | |
895 { | |
896 return port; | |
897 } | |
898 | |
899 bool operator==(const CService& a, const CService& b) | |
900 { | |
901 return (CNetAddr)a == (CNetAddr)b && a.port == b.port; | |
902 } | |
903 | |
904 bool operator!=(const CService& a, const CService& b) | |
905 { | |
906 return (CNetAddr)a != (CNetAddr)b || a.port != b.port; | |
907 } | |
908 | |
909 bool operator<(const CService& a, const CService& b) | |
910 { | |
911 return (CNetAddr)a < (CNetAddr)b || ((CNetAddr)a == (CNetAddr)b && a.port < b.port); | |
912 } | |
913 | |
914 bool CService::GetSockAddr(struct sockaddr_in* paddr) const | |
915 { | |
916 if (!IsIPv4()) | |
917 return false; | |
918 memset(paddr, 0, sizeof(struct sockaddr_in)); | |
919 if (!GetInAddr(&paddr->sin_addr)) | |
920 return false; | |
921 paddr->sin_family = AF_INET; | |
922 paddr->sin_port = htons(port); | |
923 return true; | |
924 } | |
925 | |
926 #ifdef USE_IPV6 | |
927 bool CService::GetSockAddr6(struct sockaddr_in6* paddr) const | |
928 { | |
929 memset(paddr, 0, sizeof(struct sockaddr_in6)); | |
930 if (!GetIn6Addr(&paddr->sin6_addr)) | |
931 return false; | |
932 paddr->sin6_family = AF_INET6; | |
933 paddr->sin6_port = htons(port); | |
934 return true; | |
935 } | |
936 #endif | |
937 | |
938 std::vector<unsigned char> CService::GetKey() const | |
939 { | |
940 std::vector<unsigned char> vKey; | |
941 vKey.resize(18); | |
942 memcpy(&vKey[0], ip, 16); | |
943 vKey[16] = port / 0x100; | |
944 vKey[17] = port & 0x0FF; | |
945 return vKey; | |
946 } | |
947 | |
948 std::string CService::ToStringPort() const | |
949 { | |
2476 | 950 return strprintf("%i", port); |
1731 | 951 } |
952 | |
953 std::string CService::ToStringIPPort() const | |
954 { | |
2476 | 955 if (IsIPv4()) { |
956 return ToStringIP() + ":" + ToStringPort(); | |
957 } else { | |
958 return "[" + ToStringIP() + "]:" + ToStringPort(); | |
959 } | |
1731 | 960 } |
961 | |
962 std::string CService::ToString() const | |
963 { | |
964 return ToStringIPPort(); | |
965 } | |
966 | |
967 void CService::print() const | |
968 { | |
969 printf("CService(%s)\n", ToString().c_str()); | |
970 } | |
971 | |
972 void CService::SetPort(unsigned short portIn) | |
973 { | |
974 port = portIn; | |
975 } |