24 #include <sys/types.h> 29 #include <boost/algorithm/string.hpp> 30 #include <boost/algorithm/string/split.hpp> 44 static_assert(BOOST_VERSION == 106300,
"Wrong boost headers version");
46 std::set<bi::address> Network::getInterfaceAddresses()
48 std::set<bi::address> addresses;
52 if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
53 BOOST_THROW_EXCEPTION(NoNetworking());
60 BOOST_THROW_EXCEPTION(NoNetworking());
63 struct hostent* phe = gethostbyname(ac);
68 BOOST_THROW_EXCEPTION(NoNetworking());
71 for (
int i = 0; phe->h_addr_list[i] != 0; ++i)
74 memcpy(&addr, phe->h_addr_list[i],
sizeof(
struct in_addr));
75 char *addrStr = inet_ntoa(addr);
78 addresses.insert(address.to_v4());
84 if (getifaddrs(&ifaddr) == -1)
85 BOOST_THROW_EXCEPTION(NoNetworking());
87 for (
auto ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
89 if (!ifa->ifa_addr ||
string(ifa->ifa_name) ==
"lo0" || !(ifa->ifa_flags & IFF_UP))
92 if (ifa->ifa_addr->sa_family == AF_INET)
94 in_addr addr = ((
struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
95 boost::asio::ip::address_v4
address(boost::asio::detail::socket_ops::network_to_host_long(addr.s_addr));
97 addresses.insert(address);
99 else if (ifa->ifa_addr->sa_family == AF_INET6)
101 sockaddr_in6* sockaddr = ((
struct sockaddr_in6 *)ifa->ifa_addr);
102 in6_addr addr = sockaddr->sin6_addr;
103 boost::asio::ip::address_v6::bytes_type
bytes;
104 memcpy(&bytes[0], addr.s6_addr, 16);
105 boost::asio::ip::address_v6
address(bytes, sockaddr->sin6_scope_id);
107 addresses.insert(address);
136 cwarn <<
"Couldn't start accepting connections on host. Failed to accept socket on " << listenIP <<
":" << _netPrefs.
listenPort <<
".\n" << boost::current_exception_diagnostic_information();
139 bool requirePort = (bool)_netPrefs.
listenPort;
141 for (
unsigned i = 0; i < 2; ++i)
143 bi::tcp::endpoint endpoint(listenIP, requirePort ? _netPrefs.
listenPort : (i ? 0 : c_defaultListenPort));
151 _acceptor.open(endpoint.protocol());
152 _acceptor.set_option(ba::socket_base::reuse_address(reuse));
153 _acceptor.bind(endpoint);
155 return _acceptor.local_endpoint().port();
160 if (i || requirePort)
163 cwarn <<
"Couldn't start accepting connections on host. Failed to accept socket on " << listenIP <<
":" << _netPrefs.
listenPort <<
".\n" << boost::current_exception_diagnostic_information();
176 bi::tcp::endpoint Network::traverseNAT(std::set<bi::address>
const& _ifAddresses,
unsigned short _listenPort,
bi::address& o_upnpInterfaceAddr)
180 unique_ptr<UPnP> upnp;
183 upnp.reset(
new UPnP);
188 bi::tcp::endpoint upnpEP;
189 if (upnp && upnp->isValid())
193 for (
auto const& addr: _ifAddresses)
194 if (addr.is_v4() &&
isPrivateAddress(addr) && (extPort = upnp->addRedirect(addr.to_string().c_str(), _listenPort)))
200 auto eIP = upnp->externalIP();
201 bi::address eIPAddr(bi::address::from_string(eIP));
204 clog(
NetNote) <<
"Punched through NAT and mapped local port" << _listenPort <<
"onto external port" << extPort <<
".";
206 o_upnpInterfaceAddr = pAddr;
207 upnpEP = bi::tcp::endpoint(eIPAddr, (
unsigned short)extPort);
210 clog(
NetWarn) <<
"Couldn't punch through NAT (or no NAT in place).";
216 bi::tcp::endpoint Network::resolveHost(
string const& _addr)
218 static boost::asio::io_service s_resolverIoService;
220 vector<string> split;
221 boost::split(split, _addr, boost::is_any_of(
":"));
226 if (split.size() > 1)
227 port = static_cast<unsigned>(stoi(split.at(1)));
231 boost::system::error_code ec;
238 boost::system::error_code ec;
240 bi::tcp::resolver r(s_resolverIoService);
241 auto it = r.resolve({bi::tcp::v4(), split[0],
toString(port)}, ec);
244 clog(
NetWarn) <<
"Error resolving host address..." << LogTag::Url << _addr <<
":" << LogTag::Error << ec.message();
245 return bi::tcp::endpoint();
std::string listenIPAddress
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
bool isPrivateAddress(bi::address const &_addressToCheck)
bool isLocalHostAddress(bi::address const &_addressToCheck)
for(size_t i=trim;i< len;i++) hash[i-trim]
std::hash for asio::adress
std::string toString(string32 const &_s)
Make normal string from fixed-length string.
#define WSAGetLastError()
unsigned short listenPort
std::vector< byte > bytes
const unsigned c_defaultIPPort
void * memcpy(void *a, const void *b, size_t c)
struct evm_uint160be address(struct evm_env *env)