Merge pull request #19
bb53306
dns: listen on ipv6 (Pavel Vasin)34fd288
remove option to build without ipv6 support (Pavel Vasin)
This commit is contained in:
commit
a59329d936
5 changed files with 21 additions and 57 deletions
2
Makefile
2
Makefile
|
@ -5,7 +5,7 @@ dnsseed: dns.o bitcoin.o netbase.o protocol.o db.o main.o util.o
|
||||||
g++ -pthread $(LDFLAGS) -o dnsseed dns.o bitcoin.o netbase.o protocol.o db.o main.o util.o -lcrypto
|
g++ -pthread $(LDFLAGS) -o dnsseed dns.o bitcoin.o netbase.o protocol.o db.o main.o util.o -lcrypto
|
||||||
|
|
||||||
%.o: %.cpp bitcoin.h netbase.h protocol.h db.h serialize.h uint256.h util.h
|
%.o: %.cpp bitcoin.h netbase.h protocol.h db.h serialize.h uint256.h util.h
|
||||||
g++ -DUSE_IPV6 -pthread $(CXXFLAGS) -Wno-invalid-offsetof -c -o $@ $<
|
g++ -pthread $(CXXFLAGS) -Wno-invalid-offsetof -c -o $@ $<
|
||||||
|
|
||||||
dns.o: dns.c
|
dns.o: dns.c
|
||||||
gcc -pthread -std=c99 $(CXXFLAGS) dns.c -c -o dns.o
|
gcc -pthread -std=c99 $(CXXFLAGS) dns.c -c -o dns.o
|
||||||
|
|
40
dns.c
40
dns.c
|
@ -18,18 +18,18 @@
|
||||||
|
|
||||||
#if defined IP_RECVDSTADDR
|
#if defined IP_RECVDSTADDR
|
||||||
# define DSTADDR_SOCKOPT IP_RECVDSTADDR
|
# define DSTADDR_SOCKOPT IP_RECVDSTADDR
|
||||||
# define DSTADDR_DATASIZE (CMSG_SPACE(sizeof(struct in_addr)))
|
# define DSTADDR_DATASIZE (CMSG_SPACE(sizeof(struct in6_addr)))
|
||||||
# define dstaddr(x) (CMSG_DATA(x))
|
# define dstaddr(x) (CMSG_DATA(x))
|
||||||
#elif defined IP_PKTINFO
|
#elif defined IPV6_PKTINFO
|
||||||
struct in_pktinfo {
|
struct in6_pktinfo
|
||||||
unsigned int ipi_ifindex; /* Interface index */
|
{
|
||||||
struct in_addr ipi_spec_dst; /* Local address */
|
struct in6_addr ipi6_addr; /* src/dst IPv6 address */
|
||||||
struct in_addr ipi_addr; /* Header Destination address */
|
unsigned int ipi6_ifindex; /* send/recv interface index */
|
||||||
};
|
};
|
||||||
|
|
||||||
# define DSTADDR_SOCKOPT IP_PKTINFO
|
# define DSTADDR_SOCKOPT IPV6_PKTINFO
|
||||||
# define DSTADDR_DATASIZE (CMSG_SPACE(sizeof(struct in_pktinfo)))
|
# define DSTADDR_DATASIZE (CMSG_SPACE(sizeof(struct in6_pktinfo)))
|
||||||
# define dstaddr(x) (&(((struct in_pktinfo *)(CMSG_DATA(x)))->ipi_addr))
|
# define dstaddr(x) (&(((struct in6_pktinfo *)(CMSG_DATA(x)))->ipi6_addr))
|
||||||
#else
|
#else
|
||||||
# error "can't determine socket option"
|
# error "can't determine socket option"
|
||||||
#endif
|
#endif
|
||||||
|
@ -380,31 +380,31 @@ error:
|
||||||
static int listenSocket = -1;
|
static int listenSocket = -1;
|
||||||
|
|
||||||
int dnsserver(dns_opt_t *opt) {
|
int dnsserver(dns_opt_t *opt) {
|
||||||
struct sockaddr_in si_other;
|
struct sockaddr_in6 si_other;
|
||||||
int senderSocket = -1;
|
int senderSocket = -1;
|
||||||
senderSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
senderSocket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
if (senderSocket == -1)
|
if (senderSocket == -1)
|
||||||
return -3;
|
return -3;
|
||||||
|
|
||||||
int replySocket;
|
int replySocket;
|
||||||
if (listenSocket == -1) {
|
if (listenSocket == -1) {
|
||||||
struct sockaddr_in si_me;
|
struct sockaddr_in6 si_me;
|
||||||
if ((listenSocket=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) {
|
if ((listenSocket=socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP))==-1) {
|
||||||
listenSocket = -1;
|
listenSocket = -1;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
replySocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
replySocket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
if (replySocket == -1)
|
if (replySocket == -1)
|
||||||
{
|
{
|
||||||
close(listenSocket);
|
close(listenSocket);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int sockopt = 1;
|
int sockopt = 1;
|
||||||
setsockopt(listenSocket, IPPROTO_IP, DSTADDR_SOCKOPT, &sockopt, sizeof sockopt);
|
setsockopt(listenSocket, IPPROTO_IPV6, DSTADDR_SOCKOPT, &sockopt, sizeof sockopt);
|
||||||
memset((char *) &si_me, 0, sizeof(si_me));
|
memset((char *) &si_me, 0, sizeof(si_me));
|
||||||
si_me.sin_family = AF_INET;
|
si_me.sin6_family = AF_INET6;
|
||||||
si_me.sin_port = htons(opt->port);
|
si_me.sin6_port = htons(opt->port);
|
||||||
si_me.sin_addr.s_addr = INADDR_ANY;
|
si_me.sin6_addr = in6addr_any;
|
||||||
if (bind(listenSocket, (struct sockaddr*)&si_me, sizeof(si_me))==-1)
|
if (bind(listenSocket, (struct sockaddr*)&si_me, sizeof(si_me))==-1)
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
@ -428,7 +428,7 @@ int dnsserver(dns_opt_t *opt) {
|
||||||
for (; 1; ++(opt->nRequests))
|
for (; 1; ++(opt->nRequests))
|
||||||
{
|
{
|
||||||
ssize_t insize = recvmsg(listenSocket, &msg, 0);
|
ssize_t insize = recvmsg(listenSocket, &msg, 0);
|
||||||
unsigned char *addr = (unsigned char*)&si_other.sin_addr.s_addr;
|
// unsigned char *addr = (unsigned char*)&si_other.sin_addr.s_addr;
|
||||||
// printf("DNS: Request %llu from %i.%i.%i.%i:%i of %i bytes\n", (unsigned long long)(opt->nRequests), addr[0], addr[1], addr[2], addr[3], ntohs(si_other.sin_port), (int)insize);
|
// printf("DNS: Request %llu from %i.%i.%i.%i:%i of %i bytes\n", (unsigned long long)(opt->nRequests), addr[0], addr[1], addr[2], addr[3], ntohs(si_other.sin_port), (int)insize);
|
||||||
if (insize <= 0)
|
if (insize <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
2
main.cpp
2
main.cpp
|
@ -204,14 +204,12 @@ public:
|
||||||
memcpy(&a.data.v4, &addr, 4);
|
memcpy(&a.data.v4, &addr, 4);
|
||||||
cache.push_back(a);
|
cache.push_back(a);
|
||||||
nIPv4++;
|
nIPv4++;
|
||||||
#ifdef USE_IPV6
|
|
||||||
} else if ((*it).GetIn6Addr(&addr6)) {
|
} else if ((*it).GetIn6Addr(&addr6)) {
|
||||||
addr_t a;
|
addr_t a;
|
||||||
a.v = 6;
|
a.v = 6;
|
||||||
memcpy(&a.data.v6, &addr6, 16);
|
memcpy(&a.data.v6, &addr6, 16);
|
||||||
cache.push_back(a);
|
cache.push_back(a);
|
||||||
nIPv6++;
|
nIPv6++;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cacheHits = 0;
|
cacheHits = 0;
|
||||||
|
|
30
netbase.cpp
30
netbase.cpp
|
@ -74,18 +74,10 @@ bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsign
|
||||||
aiHint.ai_socktype = SOCK_STREAM;
|
aiHint.ai_socktype = SOCK_STREAM;
|
||||||
aiHint.ai_protocol = IPPROTO_TCP;
|
aiHint.ai_protocol = IPPROTO_TCP;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
# ifdef USE_IPV6
|
|
||||||
aiHint.ai_family = AF_UNSPEC;
|
aiHint.ai_family = AF_UNSPEC;
|
||||||
# else
|
|
||||||
aiHint.ai_family = AF_INET;
|
|
||||||
# endif
|
|
||||||
aiHint.ai_flags = fAllowLookup ? 0 : AI_NUMERICHOST;
|
aiHint.ai_flags = fAllowLookup ? 0 : AI_NUMERICHOST;
|
||||||
#else
|
#else
|
||||||
# ifdef USE_IPV6
|
|
||||||
aiHint.ai_family = AF_UNSPEC;
|
aiHint.ai_family = AF_UNSPEC;
|
||||||
# else
|
|
||||||
aiHint.ai_family = AF_INET;
|
|
||||||
# endif
|
|
||||||
aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST;
|
aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST;
|
||||||
#endif
|
#endif
|
||||||
struct addrinfo *aiRes = NULL;
|
struct addrinfo *aiRes = NULL;
|
||||||
|
@ -102,13 +94,11 @@ bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsign
|
||||||
vIP.push_back(CNetAddr(((struct sockaddr_in*)(aiTrav->ai_addr))->sin_addr));
|
vIP.push_back(CNetAddr(((struct sockaddr_in*)(aiTrav->ai_addr))->sin_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_IPV6
|
|
||||||
if (aiTrav->ai_family == AF_INET6)
|
if (aiTrav->ai_family == AF_INET6)
|
||||||
{
|
{
|
||||||
assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in6));
|
assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in6));
|
||||||
vIP.push_back(CNetAddr(((struct sockaddr_in6*)(aiTrav->ai_addr))->sin6_addr));
|
vIP.push_back(CNetAddr(((struct sockaddr_in6*)(aiTrav->ai_addr))->sin6_addr));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
aiTrav = aiTrav->ai_next;
|
aiTrav = aiTrav->ai_next;
|
||||||
}
|
}
|
||||||
|
@ -323,11 +313,7 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
|
||||||
{
|
{
|
||||||
hSocketRet = INVALID_SOCKET;
|
hSocketRet = INVALID_SOCKET;
|
||||||
|
|
||||||
#ifdef USE_IPV6
|
|
||||||
struct sockaddr_storage sockaddr;
|
struct sockaddr_storage sockaddr;
|
||||||
#else
|
|
||||||
struct sockaddr sockaddr;
|
|
||||||
#endif
|
|
||||||
socklen_t len = sizeof(sockaddr);
|
socklen_t len = sizeof(sockaddr);
|
||||||
if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) {
|
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());
|
||||||
|
@ -578,12 +564,10 @@ CNetAddr::CNetAddr(const struct in_addr& ipv4Addr)
|
||||||
memcpy(ip+12, &ipv4Addr, 4);
|
memcpy(ip+12, &ipv4Addr, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_IPV6
|
|
||||||
CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr)
|
CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr)
|
||||||
{
|
{
|
||||||
memcpy(ip, &ipv6Addr, 16);
|
memcpy(ip, &ipv6Addr, 16);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
CNetAddr::CNetAddr(const char *pszIp, bool fAllowLookup)
|
CNetAddr::CNetAddr(const char *pszIp, bool fAllowLookup)
|
||||||
{
|
{
|
||||||
|
@ -772,11 +756,7 @@ std::string CNetAddr::ToStringIP() const
|
||||||
if (IsI2P())
|
if (IsI2P())
|
||||||
return EncodeBase32(&ip[6], 10) + ".oc.b32.i2p";
|
return EncodeBase32(&ip[6], 10) + ".oc.b32.i2p";
|
||||||
CService serv(*this, 0);
|
CService serv(*this, 0);
|
||||||
#ifdef USE_IPV6
|
|
||||||
struct sockaddr_storage sockaddr;
|
struct sockaddr_storage sockaddr;
|
||||||
#else
|
|
||||||
struct sockaddr sockaddr;
|
|
||||||
#endif
|
|
||||||
socklen_t socklen = sizeof(sockaddr);
|
socklen_t socklen = sizeof(sockaddr);
|
||||||
if (serv.GetSockAddr((struct sockaddr*)&sockaddr, &socklen)) {
|
if (serv.GetSockAddr((struct sockaddr*)&sockaddr, &socklen)) {
|
||||||
char name[1025] = "";
|
char name[1025] = "";
|
||||||
|
@ -821,13 +801,11 @@ bool CNetAddr::GetInAddr(struct in_addr* pipv4Addr) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_IPV6
|
|
||||||
bool CNetAddr::GetIn6Addr(struct in6_addr* pipv6Addr) const
|
bool CNetAddr::GetIn6Addr(struct in6_addr* pipv6Addr) const
|
||||||
{
|
{
|
||||||
memcpy(pipv6Addr, ip, 16);
|
memcpy(pipv6Addr, ip, 16);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// get canonical identifier of an address' group
|
// get canonical identifier of an address' group
|
||||||
// no two connections will be attempted to addresses with the same group
|
// no two connections will be attempted to addresses with the same group
|
||||||
|
@ -1013,23 +991,19 @@ CService::CService(const struct in_addr& ipv4Addr, unsigned short portIn) : CNet
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_IPV6
|
|
||||||
CService::CService(const struct in6_addr& ipv6Addr, unsigned short portIn) : CNetAddr(ipv6Addr), port(portIn)
|
CService::CService(const struct in6_addr& ipv6Addr, unsigned short portIn) : CNetAddr(ipv6Addr), port(portIn)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
CService::CService(const struct sockaddr_in& addr) : CNetAddr(addr.sin_addr), port(ntohs(addr.sin_port))
|
CService::CService(const struct sockaddr_in& addr) : CNetAddr(addr.sin_addr), port(ntohs(addr.sin_port))
|
||||||
{
|
{
|
||||||
assert(addr.sin_family == AF_INET);
|
assert(addr.sin_family == AF_INET);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_IPV6
|
|
||||||
CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr), port(ntohs(addr.sin6_port))
|
CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr), port(ntohs(addr.sin6_port))
|
||||||
{
|
{
|
||||||
assert(addr.sin6_family == AF_INET6);
|
assert(addr.sin6_family == AF_INET6);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
bool CService::SetSockAddr(const struct sockaddr *paddr)
|
bool CService::SetSockAddr(const struct sockaddr *paddr)
|
||||||
{
|
{
|
||||||
|
@ -1037,11 +1011,9 @@ bool CService::SetSockAddr(const struct sockaddr *paddr)
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
*this = CService(*(const struct sockaddr_in*)paddr);
|
*this = CService(*(const struct sockaddr_in*)paddr);
|
||||||
return true;
|
return true;
|
||||||
#ifdef USE_IPV6
|
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
*this = CService(*(const struct sockaddr_in6*)paddr);
|
*this = CService(*(const struct sockaddr_in6*)paddr);
|
||||||
return true;
|
return true;
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1113,7 +1085,6 @@ bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const
|
||||||
paddrin->sin_port = htons(port);
|
paddrin->sin_port = htons(port);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#ifdef USE_IPV6
|
|
||||||
if (IsIPv6()) {
|
if (IsIPv6()) {
|
||||||
if (*addrlen < (socklen_t)sizeof(struct sockaddr_in6))
|
if (*addrlen < (socklen_t)sizeof(struct sockaddr_in6))
|
||||||
return false;
|
return false;
|
||||||
|
@ -1126,7 +1097,6 @@ bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const
|
||||||
paddrin6->sin6_port = htons(port);
|
paddrin6->sin6_port = htons(port);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,10 +74,8 @@ class CNetAddr
|
||||||
int GetReachabilityFrom(const CNetAddr *paddrPartner = NULL) const;
|
int GetReachabilityFrom(const CNetAddr *paddrPartner = NULL) const;
|
||||||
void print() const;
|
void print() const;
|
||||||
|
|
||||||
#ifdef USE_IPV6
|
|
||||||
CNetAddr(const struct in6_addr& pipv6Addr);
|
CNetAddr(const struct in6_addr& pipv6Addr);
|
||||||
bool GetIn6Addr(struct in6_addr* pipv6Addr) const;
|
bool GetIn6Addr(struct in6_addr* pipv6Addr) const;
|
||||||
#endif
|
|
||||||
|
|
||||||
friend bool operator==(const CNetAddr& a, const CNetAddr& b);
|
friend bool operator==(const CNetAddr& a, const CNetAddr& b);
|
||||||
friend bool operator!=(const CNetAddr& a, const CNetAddr& b);
|
friend bool operator!=(const CNetAddr& a, const CNetAddr& b);
|
||||||
|
@ -118,10 +116,8 @@ class CService : public CNetAddr
|
||||||
std::string ToStringIPPort() const;
|
std::string ToStringIPPort() const;
|
||||||
void print() const;
|
void print() const;
|
||||||
|
|
||||||
#ifdef USE_IPV6
|
|
||||||
CService(const struct in6_addr& ipv6Addr, unsigned short port);
|
CService(const struct in6_addr& ipv6Addr, unsigned short port);
|
||||||
CService(const struct sockaddr_in6& addr);
|
CService(const struct sockaddr_in6& addr);
|
||||||
#endif
|
|
||||||
|
|
||||||
IMPLEMENT_SERIALIZE
|
IMPLEMENT_SERIALIZE
|
||||||
(
|
(
|
||||||
|
|
Loading…
Reference in a new issue