mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-11 04:12:36 -03:00
Separate listening sockets, -bind=<addr>
This commit is contained in:
parent
7fa4443f77
commit
8f10a28890
5 changed files with 140 additions and 92 deletions
36
src/init.cpp
36
src/init.cpp
|
@ -119,6 +119,18 @@ bool AppInit(int argc, char* argv[])
|
||||||
return fRet;
|
return fRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool static Bind(const CService &addr) {
|
||||||
|
if (IsLimited(addr))
|
||||||
|
return false;
|
||||||
|
std::string strError;
|
||||||
|
if (!BindListenPort(addr, strError))
|
||||||
|
{
|
||||||
|
ThreadSafeMessageBox(strError, _("Bitcoin"), wxOK | wxMODAL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool AppInit2(int argc, char* argv[])
|
bool AppInit2(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -193,6 +205,7 @@ bool AppInit2(int argc, char* argv[])
|
||||||
" -discover \t " + _("Try to discover public IP address (default: 1)") + "\n" +
|
" -discover \t " + _("Try to discover public IP address (default: 1)") + "\n" +
|
||||||
" -irc \t " + _("Find peers using internet relay chat (default: 0)") + "\n" +
|
" -irc \t " + _("Find peers using internet relay chat (default: 0)") + "\n" +
|
||||||
" -listen \t " + _("Accept connections from outside (default: 1)") + "\n" +
|
" -listen \t " + _("Accept connections from outside (default: 1)") + "\n" +
|
||||||
|
" -bind=<addr> \t " + _("Bind to given address. Use [host]:port notation for IPv6") + "\n" +
|
||||||
#ifdef QT_GUI
|
#ifdef QT_GUI
|
||||||
" -lang=<lang> \t\t " + _("Set language, for example \"de_DE\" (default: system locale)") + "\n" +
|
" -lang=<lang> \t\t " + _("Set language, for example \"de_DE\" (default: system locale)") + "\n" +
|
||||||
#endif
|
#endif
|
||||||
|
@ -548,7 +561,11 @@ bool AppInit2(int argc, char* argv[])
|
||||||
|
|
||||||
if (mapArgs.count("-connect"))
|
if (mapArgs.count("-connect"))
|
||||||
SoftSetBoolArg("-dnsseed", false);
|
SoftSetBoolArg("-dnsseed", false);
|
||||||
|
|
||||||
|
// even in Tor mode, if -bind is specified, you really want -listen
|
||||||
|
if (mapArgs.count("-bind"))
|
||||||
|
SoftSetBoolArg("-listen", true);
|
||||||
|
|
||||||
bool fTor = (fUseProxy && addrProxy.GetPort() == 9050);
|
bool fTor = (fUseProxy && addrProxy.GetPort() == 9050);
|
||||||
if (fTor)
|
if (fTor)
|
||||||
{
|
{
|
||||||
|
@ -588,14 +605,23 @@ bool AppInit2(int argc, char* argv[])
|
||||||
const char* pszP2SH = "/P2SH/";
|
const char* pszP2SH = "/P2SH/";
|
||||||
COINBASE_FLAGS << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH));
|
COINBASE_FLAGS << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH));
|
||||||
|
|
||||||
|
bool fBound = false;
|
||||||
if (!fNoListen)
|
if (!fNoListen)
|
||||||
{
|
{
|
||||||
std::string strError;
|
std::string strError;
|
||||||
if (!BindListenPort(strError))
|
if (mapArgs.count("-bind")) {
|
||||||
{
|
BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) {
|
||||||
ThreadSafeMessageBox(strError, _("Bitcoin"), wxOK | wxMODAL);
|
fBound |= Bind(CService(strBind, GetDefaultPort(), false));
|
||||||
return false;
|
}
|
||||||
|
} else {
|
||||||
|
struct in_addr inaddr_any = {s_addr: INADDR_ANY};
|
||||||
|
fBound |= Bind(CService(inaddr_any, GetDefaultPort()));
|
||||||
|
#ifdef USE_IPV6
|
||||||
|
fBound |= Bind(CService(in6addr_any, GetDefaultPort()));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
if (!fBound)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mapArgs.count("-externalip"))
|
if (mapArgs.count("-externalip"))
|
||||||
|
|
86
src/net.cpp
86
src/net.cpp
|
@ -52,7 +52,7 @@ static bool vfLimited[NET_MAX] = {};
|
||||||
static CNode* pnodeLocalHost = NULL;
|
static CNode* pnodeLocalHost = NULL;
|
||||||
uint64 nLocalHostNonce = 0;
|
uint64 nLocalHostNonce = 0;
|
||||||
array<int, THREAD_MAX> vnThreadsRunning;
|
array<int, THREAD_MAX> vnThreadsRunning;
|
||||||
static SOCKET hListenSocket = INVALID_SOCKET;
|
static std::vector<SOCKET> vhListenSocket;
|
||||||
CAddrMan addrman;
|
CAddrMan addrman;
|
||||||
|
|
||||||
vector<CNode*> vNodes;
|
vector<CNode*> vNodes;
|
||||||
|
@ -719,9 +719,10 @@ void ThreadSocketHandler2(void* parg)
|
||||||
FD_ZERO(&fdsetError);
|
FD_ZERO(&fdsetError);
|
||||||
SOCKET hSocketMax = 0;
|
SOCKET hSocketMax = 0;
|
||||||
|
|
||||||
if(hListenSocket != INVALID_SOCKET)
|
BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) {
|
||||||
FD_SET(hListenSocket, &fdsetRecv);
|
FD_SET(hListenSocket, &fdsetRecv);
|
||||||
hSocketMax = max(hSocketMax, hListenSocket);
|
hSocketMax = max(hSocketMax, hListenSocket);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
LOCK(cs_vNodes);
|
LOCK(cs_vNodes);
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
|
@ -762,12 +763,13 @@ void ThreadSocketHandler2(void* parg)
|
||||||
//
|
//
|
||||||
// Accept new connections
|
// Accept new connections
|
||||||
//
|
//
|
||||||
|
BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
|
||||||
if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
|
if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
|
||||||
{
|
{
|
||||||
#ifdef USE_IPV6
|
#ifdef USE_IPV6
|
||||||
struct sockaddr_in6 sockaddr;
|
struct sockaddr_storage sockaddr;
|
||||||
#else
|
#else
|
||||||
struct sockaddr_in sockaddr;
|
struct sockaddr sockaddr;
|
||||||
#endif
|
#endif
|
||||||
socklen_t len = sizeof(sockaddr);
|
socklen_t len = sizeof(sockaddr);
|
||||||
SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
|
SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
|
||||||
|
@ -775,7 +777,8 @@ void ThreadSocketHandler2(void* parg)
|
||||||
int nInbound = 0;
|
int nInbound = 0;
|
||||||
|
|
||||||
if (hSocket != INVALID_SOCKET)
|
if (hSocket != INVALID_SOCKET)
|
||||||
addr = CAddress(sockaddr);
|
if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
|
||||||
|
printf("warning: unknown socket family\n");
|
||||||
|
|
||||||
{
|
{
|
||||||
LOCK(cs_vNodes);
|
LOCK(cs_vNodes);
|
||||||
|
@ -1656,9 +1659,8 @@ void ThreadMessageHandler2(void* parg)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool BindListenPort(string& strError)
|
bool BindListenPort(const CService &addrBind, string& strError)
|
||||||
{
|
{
|
||||||
unsigned short nPort = GetListenPort();
|
|
||||||
strError = "";
|
strError = "";
|
||||||
int nOne = 1;
|
int nOne = 1;
|
||||||
|
|
||||||
|
@ -1676,11 +1678,19 @@ bool BindListenPort(string& strError)
|
||||||
|
|
||||||
// Create socket for listening for incoming connections
|
// Create socket for listening for incoming connections
|
||||||
#ifdef USE_IPV6
|
#ifdef USE_IPV6
|
||||||
int nFamily = AF_INET6;
|
struct sockaddr_storage sockaddr;
|
||||||
#else
|
#else
|
||||||
int nFamily = AF_INET;
|
struct sockaddr sockaddr;
|
||||||
#endif
|
#endif
|
||||||
hListenSocket = socket(nFamily, SOCK_STREAM, IPPROTO_TCP);
|
socklen_t len = sizeof(sockaddr);
|
||||||
|
if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
|
||||||
|
{
|
||||||
|
strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str());
|
||||||
|
printf("%s\n", strError.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
|
||||||
if (hListenSocket == INVALID_SOCKET)
|
if (hListenSocket == INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
|
strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
|
||||||
|
@ -1699,6 +1709,7 @@ bool BindListenPort(string& strError)
|
||||||
setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
|
setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
// Set to nonblocking, incoming connections will also inherit this
|
// Set to nonblocking, incoming connections will also inherit this
|
||||||
if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
|
if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
|
||||||
|
@ -1711,38 +1722,33 @@ bool BindListenPort(string& strError)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The sockaddr_in structure specifies the address family,
|
|
||||||
// IP address, and port for the socket that is being bound
|
|
||||||
#ifdef USE_IPV6
|
#ifdef USE_IPV6
|
||||||
struct sockaddr_in6 sockaddr = sockaddr_in6();
|
// some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
|
||||||
memset(&sockaddr, 0, sizeof(sockaddr));
|
// and enable it by default or not. Try to enable it, if possible.
|
||||||
sockaddr.sin6_family = AF_INET6;
|
if (addrBind.IsIPv6()) {
|
||||||
sockaddr.sin6_addr = in6addr_any; // bind to all IPs on this computer
|
#ifdef IPV6_V6ONLY
|
||||||
sockaddr.sin6_port = htons(nPort);
|
setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
|
||||||
# ifdef WIN32
|
|
||||||
int nProtLevel = 10 /* PROTECTION_LEVEL_UNRESTRICTED */;
|
|
||||||
int nParameterId = 23 /* IPV6_PROTECTION_LEVEl */;
|
|
||||||
// this call is allowed to fail
|
|
||||||
setsockopt(hListenSocket, IPPROTO_IPV6, nParameterId, (const char*)&nProtLevel, sizeof(int));
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
struct sockaddr_in sockaddr = sockaddr_in();
|
|
||||||
memset(&sockaddr, 0, sizeof(sockaddr));
|
|
||||||
sockaddr.sin_family = AF_INET;
|
|
||||||
sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
|
|
||||||
sockaddr.sin_port = htons(nPort);
|
|
||||||
#endif
|
#endif
|
||||||
if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
|
#ifdef WIN32
|
||||||
|
int nProtLevel = 10 /* PROTECTION_LEVEL_UNRESTRICTED */;
|
||||||
|
int nParameterId = 23 /* IPV6_PROTECTION_LEVEl */;
|
||||||
|
// this call is allowed to fail
|
||||||
|
setsockopt(hListenSocket, IPPROTO_IPV6, nParameterId, (const char*)&nProtLevel, sizeof(int));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
|
||||||
{
|
{
|
||||||
int nErr = WSAGetLastError();
|
int nErr = WSAGetLastError();
|
||||||
if (nErr == WSAEADDRINUSE)
|
if (nErr == WSAEADDRINUSE)
|
||||||
strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), nPort);
|
strError = strprintf(_("Unable to bind to %s on this computer. Bitcoin is probably already running."), addrBind.ToString().c_str());
|
||||||
else
|
else
|
||||||
strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d, %s)", nPort, nErr, strerror(nErr));
|
strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr));
|
||||||
printf("%s\n", strError.c_str());
|
printf("%s\n", strError.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
printf("Bound to port %d\n", (int)nPort);
|
printf("Bound to %s\n", addrBind.ToString().c_str());
|
||||||
|
|
||||||
// Listen for incoming connections
|
// Listen for incoming connections
|
||||||
if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
|
if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
|
||||||
|
@ -1752,6 +1758,11 @@ bool BindListenPort(string& strError)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vhListenSocket.push_back(hListenSocket);
|
||||||
|
|
||||||
|
if (addrBind.IsRoutable() && GetBoolArg("-discover", true))
|
||||||
|
AddLocal(addrBind, LOCAL_BIND);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1915,9 +1926,10 @@ public:
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
if (pnode->hSocket != INVALID_SOCKET)
|
if (pnode->hSocket != INVALID_SOCKET)
|
||||||
closesocket(pnode->hSocket);
|
closesocket(pnode->hSocket);
|
||||||
if (hListenSocket != INVALID_SOCKET)
|
BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
|
||||||
if (closesocket(hListenSocket) == SOCKET_ERROR)
|
if (hListenSocket != INVALID_SOCKET)
|
||||||
printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
|
if (closesocket(hListenSocket) == SOCKET_ERROR)
|
||||||
|
printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
// Shutdown Windows Sockets
|
// Shutdown Windows Sockets
|
||||||
|
|
|
@ -38,7 +38,7 @@ CNode* FindNode(const CNetAddr& ip);
|
||||||
CNode* FindNode(const CService& ip);
|
CNode* FindNode(const CService& ip);
|
||||||
CNode* ConnectNode(CAddress addrConnect, const char *strDest = NULL, int64 nTimeout=0);
|
CNode* ConnectNode(CAddress addrConnect, const char *strDest = NULL, int64 nTimeout=0);
|
||||||
void MapPort(bool fMapPort);
|
void MapPort(bool fMapPort);
|
||||||
bool BindListenPort(std::string& strError=REF(std::string()));
|
bool BindListenPort(const CService &bindAddr, std::string& strError=REF(std::string()));
|
||||||
void StartNode(void* parg);
|
void StartNode(void* parg);
|
||||||
bool StopNode();
|
bool StopNode();
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@ enum
|
||||||
{
|
{
|
||||||
LOCAL_NONE, // unknown
|
LOCAL_NONE, // unknown
|
||||||
LOCAL_IF, // address a local interface listens on
|
LOCAL_IF, // address a local interface listens on
|
||||||
|
LOCAL_BIND, // address explicit bound to
|
||||||
LOCAL_UPNP, // address reported by UPnP
|
LOCAL_UPNP, // address reported by UPnP
|
||||||
LOCAL_IRC, // address reported by IRC (deprecated)
|
LOCAL_IRC, // address reported by IRC (deprecated)
|
||||||
LOCAL_HTTP, // address reported by whatismyip.com and similars
|
LOCAL_HTTP, // address reported by whatismyip.com and similars
|
||||||
|
|
103
src/netbase.cpp
103
src/netbase.cpp
|
@ -183,7 +183,12 @@ bool static Socks4(const CService &addrDest, SOCKET& hSocket)
|
||||||
}
|
}
|
||||||
char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
|
char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
addrDest.GetSockAddr(&addr);
|
socklen_t len = sizeof(addr);
|
||||||
|
if (!addrDest.GetSockAddr((struct sockaddr*)&addr, &len) || addr.sin_family != AF_INET)
|
||||||
|
{
|
||||||
|
closesocket(hSocket);
|
||||||
|
return error("Cannot get proxy destination address");
|
||||||
|
}
|
||||||
memcpy(pszSocks4IP + 2, &addr.sin_port, 2);
|
memcpy(pszSocks4IP + 2, &addr.sin_port, 2);
|
||||||
memcpy(pszSocks4IP + 4, &addr.sin_addr, 4);
|
memcpy(pszSocks4IP + 4, &addr.sin_addr, 4);
|
||||||
char* pszSocks4 = pszSocks4IP;
|
char* pszSocks4 = pszSocks4IP;
|
||||||
|
@ -319,37 +324,18 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
|
||||||
{
|
{
|
||||||
hSocketRet = INVALID_SOCKET;
|
hSocketRet = INVALID_SOCKET;
|
||||||
|
|
||||||
struct sockaddr_storage sockaddr;
|
|
||||||
int nFamily = 0;
|
|
||||||
size_t nSockAddrLen = 0;
|
|
||||||
|
|
||||||
if (addrConnect.IsIPv4())
|
|
||||||
{
|
|
||||||
// Use IPv4 stack to connect to IPv4 addresses
|
|
||||||
struct sockaddr_in sockaddr4;
|
|
||||||
if (!addrConnect.GetSockAddr(&sockaddr4))
|
|
||||||
return false;
|
|
||||||
memcpy(&sockaddr, &sockaddr4, sizeof(sockaddr4));
|
|
||||||
nSockAddrLen = sizeof(sockaddr4);
|
|
||||||
nFamily = AF_INET;
|
|
||||||
}
|
|
||||||
#ifdef USE_IPV6
|
#ifdef USE_IPV6
|
||||||
else if (addrConnect.IsIPv6())
|
struct sockaddr_storage sockaddr;
|
||||||
{
|
#else
|
||||||
struct sockaddr_in6 sockaddr6;
|
struct sockaddr sockaddr;
|
||||||
if (!addrConnect.GetSockAddr6(&sockaddr6))
|
|
||||||
return false;
|
|
||||||
memcpy(&sockaddr, &sockaddr6, sizeof(sockaddr6));
|
|
||||||
nSockAddrLen = sizeof(sockaddr6);
|
|
||||||
nFamily = AF_INET6;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
else {
|
socklen_t len = sizeof(sockaddr);
|
||||||
|
if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) {
|
||||||
printf("Cannot connect to %s: unsupported network\n", addrConnect.ToString().c_str());
|
printf("Cannot connect to %s: unsupported network\n", addrConnect.ToString().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOCKET hSocket = socket(nFamily, SOCK_STREAM, IPPROTO_TCP);
|
SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
|
||||||
if (hSocket == INVALID_SOCKET)
|
if (hSocket == INVALID_SOCKET)
|
||||||
return false;
|
return false;
|
||||||
#ifdef SO_NOSIGPIPE
|
#ifdef SO_NOSIGPIPE
|
||||||
|
@ -369,7 +355,7 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connect(hSocket, (struct sockaddr*)&sockaddr, nSockAddrLen) == SOCKET_ERROR)
|
if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
|
||||||
{
|
{
|
||||||
// WSAEINVAL is here because some legacy version of winsock uses it
|
// WSAEINVAL is here because some legacy version of winsock uses it
|
||||||
if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
|
if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
|
||||||
|
@ -902,6 +888,22 @@ CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr),
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool CService::SetSockAddr(const struct sockaddr *paddr)
|
||||||
|
{
|
||||||
|
switch (paddr->sa_family) {
|
||||||
|
case AF_INET:
|
||||||
|
*this = CService(*(const struct sockaddr_in*)paddr);
|
||||||
|
return true;
|
||||||
|
#ifdef USE_IPV6
|
||||||
|
case AF_INET6:
|
||||||
|
*this = CService(*(const struct sockaddr_in6*)paddr);
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CService::CService(const char *pszIpPort, bool fAllowLookup)
|
CService::CService(const char *pszIpPort, bool fAllowLookup)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
|
@ -954,29 +956,36 @@ bool operator<(const CService& a, const CService& b)
|
||||||
return (CNetAddr)a < (CNetAddr)b || ((CNetAddr)a == (CNetAddr)b && a.port < b.port);
|
return (CNetAddr)a < (CNetAddr)b || ((CNetAddr)a == (CNetAddr)b && a.port < b.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CService::GetSockAddr(struct sockaddr_in* paddr) const
|
bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const
|
||||||
{
|
{
|
||||||
if (!IsIPv4())
|
if (IsIPv4()) {
|
||||||
return false;
|
if (*addrlen < sizeof(struct sockaddr_in))
|
||||||
memset(paddr, 0, sizeof(struct sockaddr_in));
|
return false;
|
||||||
if (!GetInAddr(&paddr->sin_addr))
|
*addrlen = sizeof(struct sockaddr_in);
|
||||||
return false;
|
struct sockaddr_in *paddrin = (struct sockaddr_in*)paddr;
|
||||||
paddr->sin_family = AF_INET;
|
memset(paddrin, 0, *addrlen);
|
||||||
paddr->sin_port = htons(port);
|
if (!GetInAddr(&paddrin->sin_addr))
|
||||||
return true;
|
return false;
|
||||||
}
|
paddrin->sin_family = AF_INET;
|
||||||
|
paddrin->sin_port = htons(port);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
#ifdef USE_IPV6
|
#ifdef USE_IPV6
|
||||||
bool CService::GetSockAddr6(struct sockaddr_in6* paddr) const
|
if (IsIPv6()) {
|
||||||
{
|
if (*addrlen < sizeof(struct sockaddr_in6))
|
||||||
memset(paddr, 0, sizeof(struct sockaddr_in6));
|
return false;
|
||||||
if (!GetIn6Addr(&paddr->sin6_addr))
|
*addrlen = sizeof(struct sockaddr_in6);
|
||||||
return false;
|
struct sockaddr_in6 *paddrin6 = (struct sockaddr_in6*)paddr;
|
||||||
paddr->sin6_family = AF_INET6;
|
memset(paddrin6, 0, *addrlen);
|
||||||
paddr->sin6_port = htons(port);
|
if (!GetIn6Addr(&paddrin6->sin6_addr))
|
||||||
return true;
|
return false;
|
||||||
}
|
paddrin6->sin6_family = AF_INET6;
|
||||||
|
paddrin6->sin6_port = htons(port);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<unsigned char> CService::GetKey() const
|
std::vector<unsigned char> CService::GetKey() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -105,7 +105,8 @@ class CService : public CNetAddr
|
||||||
void Init();
|
void Init();
|
||||||
void SetPort(unsigned short portIn);
|
void SetPort(unsigned short portIn);
|
||||||
unsigned short GetPort() const;
|
unsigned short GetPort() const;
|
||||||
bool GetSockAddr(struct sockaddr_in* paddr) const;
|
bool GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const;
|
||||||
|
bool SetSockAddr(const struct sockaddr* paddr);
|
||||||
friend bool operator==(const CService& a, const CService& b);
|
friend bool operator==(const CService& a, const CService& b);
|
||||||
friend bool operator!=(const CService& a, const CService& b);
|
friend bool operator!=(const CService& a, const CService& b);
|
||||||
friend bool operator<(const CService& a, const CService& b);
|
friend bool operator<(const CService& a, const CService& b);
|
||||||
|
@ -117,7 +118,6 @@ class CService : public CNetAddr
|
||||||
|
|
||||||
#ifdef USE_IPV6
|
#ifdef USE_IPV6
|
||||||
CService(const struct in6_addr& ipv6Addr, unsigned short port);
|
CService(const struct in6_addr& ipv6Addr, unsigned short port);
|
||||||
bool GetSockAddr6(struct sockaddr_in6* paddr) const;
|
|
||||||
CService(const struct sockaddr_in6& addr);
|
CService(const struct sockaddr_in6& addr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue