IPv6/AAAA record support
This commit is contained in:
parent
af48979870
commit
309d8ee0ae
14 changed files with 866 additions and 331 deletions
6
Makefile
6
Makefile
|
@ -1,8 +1,8 @@
|
|||
dnsseed: dns.o bitcoin.o netbase.o protocol.o db.o main.o
|
||||
g++ -pthread -lcrypto -o dnsseed dns.o bitcoin.o netbase.o protocol.o db.o main.o
|
||||
dnsseed: dns.o bitcoin.o netbase.o protocol.o db.o main.o util.o
|
||||
g++ -pthread -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
|
||||
g++ -pthread -O2 -ggdb3 -march=nocona -Wno-invalid-offsetof -c -o $@ $<
|
||||
g++ -DUSE_IPV6 -pthread -O2 -ggdb3 -march=nocona -Wno-invalid-offsetof -c -o $@ $<
|
||||
|
||||
dns.o: dns.c
|
||||
gcc -pthread -std=c99 -O2 -ggdb3 -march=nocona dns.c -c -o dns.o
|
||||
|
|
12
bitcoin.cpp
12
bitcoin.cpp
|
@ -72,7 +72,7 @@ class CNode {
|
|||
int64 nTime = time(NULL);
|
||||
uint64 nLocalNonce = BITCOIN_SEED_NONCE;
|
||||
int64 nLocalServices = 0;
|
||||
CAddress me(CIPPort("0.0.0.0"));
|
||||
CAddress me(CService("0.0.0.0"));
|
||||
BeginMessage("version");
|
||||
int nBestHeight = REQUIRE_HEIGHT;
|
||||
string ver = "/bitcoin-seeder:0.01/";
|
||||
|
@ -132,8 +132,6 @@ class CNode {
|
|||
CAddress &addr = *it;
|
||||
// printf("%s: got address %s\n", ToString(you).c_str(), addr.ToString().c_str(), (int)(vAddr->size()));
|
||||
it++;
|
||||
if (!addr.IsIPv4())
|
||||
continue;
|
||||
if (addr.nTime <= 100000000 || addr.nTime > now + 600)
|
||||
addr.nTime = now - 5 * 86400;
|
||||
vAddr->push_back(addr);
|
||||
|
@ -192,7 +190,7 @@ class CNode {
|
|||
}
|
||||
|
||||
public:
|
||||
CNode(const CIPPort& ip, vector<CAddress>& vAddrIn) : you(ip), nHeaderStart(-1), nMessageStart(-1), vAddr(&vAddrIn), ban(0), doneAfter(0), nVersion(0) {
|
||||
CNode(const CService& ip, vector<CAddress>& vAddrIn) : you(ip), nHeaderStart(-1), nMessageStart(-1), vAddr(&vAddrIn), ban(0), doneAfter(0), nVersion(0) {
|
||||
vSend.SetType(SER_NETWORK);
|
||||
vSend.SetVersion(0);
|
||||
vRecv.SetType(SER_NETWORK);
|
||||
|
@ -204,7 +202,7 @@ public:
|
|||
}
|
||||
bool Run() {
|
||||
bool res = true;
|
||||
if (!you.ConnectSocket(sock)) return false;
|
||||
if (!ConnectSocket(you, sock)) return false;
|
||||
PushVersion();
|
||||
Send();
|
||||
int64 now;
|
||||
|
@ -262,7 +260,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
bool TestNode(const CIPPort &cip, int &ban, int &clientV, std::string &clientSV, vector<CAddress>& vAddr) {
|
||||
bool TestNode(const CService &cip, int &ban, int &clientV, std::string &clientSV, vector<CAddress>& vAddr) {
|
||||
try {
|
||||
CNode node(cip, vAddr);
|
||||
bool ret = node.Run();
|
||||
|
@ -283,7 +281,7 @@ bool TestNode(const CIPPort &cip, int &ban, int &clientV, std::string &clientSV,
|
|||
|
||||
/*
|
||||
int main(void) {
|
||||
CIPPort ip("bitcoin.sipa.be", 8333, true);
|
||||
CService ip("bitcoin.sipa.be", 8333, true);
|
||||
vector<CAddress> vAddr;
|
||||
vAddr.clear();
|
||||
int ban = 0;
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
|
||||
#include "protocol.h"
|
||||
|
||||
bool TestNode(const CIPPort &cip, int &ban, int &client, std::string &clientSV, std::vector<CAddress>& vAddr);
|
||||
bool TestNode(const CService &cip, int &ban, int &client, std::string &clientSV, std::vector<CAddress>& vAddr);
|
||||
|
||||
#endif
|
||||
|
|
18
db.cpp
18
db.cpp
|
@ -26,7 +26,7 @@ void CAddrInfo::Update(bool good) {
|
|||
// 100.0 * stat1W.reliability, 100.0 * (stat1W.reliability + 1.0 - stat1W.weight), stat1W.count);
|
||||
}
|
||||
|
||||
bool CAddrDb::Get_(CIPPort &ip, int &wait) {
|
||||
bool CAddrDb::Get_(CService &ip, int &wait) {
|
||||
int64 now = time(NULL);
|
||||
int cont = 0;
|
||||
int tot = unkId.size();
|
||||
|
@ -78,13 +78,13 @@ bool CAddrDb::Get_(CIPPort &ip, int &wait) {
|
|||
return true;
|
||||
}
|
||||
|
||||
int CAddrDb::Lookup_(const CIPPort &ip) {
|
||||
int CAddrDb::Lookup_(const CService &ip) {
|
||||
if (ipToId.count(ip))
|
||||
return ipToId[ip];
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CAddrDb::Good_(const CIPPort &addr, int clientV, std::string clientSV) {
|
||||
void CAddrDb::Good_(const CService &addr, int clientV, std::string clientSV) {
|
||||
int id = Lookup_(addr);
|
||||
if (id == -1) return;
|
||||
unkId.erase(id);
|
||||
|
@ -101,7 +101,7 @@ void CAddrDb::Good_(const CIPPort &addr, int clientV, std::string clientSV) {
|
|||
ourId.push_back(id);
|
||||
}
|
||||
|
||||
void CAddrDb::Bad_(const CIPPort &addr, int ban)
|
||||
void CAddrDb::Bad_(const CService &addr, int ban)
|
||||
{
|
||||
int id = Lookup_(addr);
|
||||
if (id == -1) return;
|
||||
|
@ -130,7 +130,7 @@ void CAddrDb::Bad_(const CIPPort &addr, int ban)
|
|||
nDirty++;
|
||||
}
|
||||
|
||||
void CAddrDb::Skipped_(const CIPPort &addr)
|
||||
void CAddrDb::Skipped_(const CService &addr)
|
||||
{
|
||||
int id = Lookup_(addr);
|
||||
if (id == -1) return;
|
||||
|
@ -144,7 +144,7 @@ void CAddrDb::Skipped_(const CIPPort &addr)
|
|||
void CAddrDb::Add_(const CAddress &addr, bool force) {
|
||||
if (!force && !addr.IsRoutable())
|
||||
return;
|
||||
CIPPort ipp(addr);
|
||||
CService ipp(addr);
|
||||
if (banned.count(ipp)) {
|
||||
time_t bantime = banned[ipp];
|
||||
if (force || (bantime < time(NULL) && addr.nTime > bantime))
|
||||
|
@ -180,7 +180,7 @@ void CAddrDb::Add_(const CAddress &addr, bool force) {
|
|||
nDirty++;
|
||||
}
|
||||
|
||||
void CAddrDb::GetIPs_(set<CIP>& ips, int max, bool fOnlyIPv4) {
|
||||
void CAddrDb::GetIPs_(set<CNetAddr>& ips, int max, const bool* nets) {
|
||||
if (goodId.size() == 0) {
|
||||
int id = -1;
|
||||
if (ourId.size() == 0) {
|
||||
|
@ -208,8 +208,8 @@ void CAddrDb::GetIPs_(set<CIP>& ips, int max, bool fOnlyIPv4) {
|
|||
ids.insert(id);
|
||||
}
|
||||
for (set<int>::const_iterator it = ids.begin(); it != ids.end(); it++) {
|
||||
CIPPort &ip = idToInfo[*it].ip;
|
||||
if (ip.IsValid() && (!fOnlyIPv4 || ip.IsIPv4()))
|
||||
CService &ip = idToInfo[*it].ip;
|
||||
if (nets[ip.GetNetwork()])
|
||||
ips.insert(ip);
|
||||
}
|
||||
}
|
||||
|
|
35
db.h
35
db.h
|
@ -12,7 +12,7 @@
|
|||
|
||||
#define MIN_RETRY 1000
|
||||
|
||||
std::string static inline ToString(const CIPPort &ip) {
|
||||
std::string static inline ToString(const CService &ip) {
|
||||
std::string str = ip.ToString();
|
||||
while (str.size() < 22) str += ' ';
|
||||
return str;
|
||||
|
@ -44,7 +44,7 @@ public:
|
|||
|
||||
class CAddrReport {
|
||||
public:
|
||||
CIPPort ip;
|
||||
CService ip;
|
||||
int clientVersion;
|
||||
double uptime[5];
|
||||
std::string clientSubVersion;
|
||||
|
@ -53,7 +53,7 @@ public:
|
|||
|
||||
class CAddrInfo {
|
||||
private:
|
||||
CIPPort ip;
|
||||
CService ip;
|
||||
uint64_t services;
|
||||
int64 lastTry;
|
||||
int64 ourLastTry;
|
||||
|
@ -87,7 +87,6 @@ public:
|
|||
if (ip.GetPort() != 8333) return false;
|
||||
if (!(services & NODE_NETWORK)) return false;
|
||||
if (!ip.IsRoutable()) return false;
|
||||
if (!ip.IsIPv4()) return false;
|
||||
if (clientVersion && clientVersion < 32400) return false;
|
||||
|
||||
if (total <= 3 && success * 2 >= total) return true;
|
||||
|
@ -170,7 +169,7 @@ private:
|
|||
mutable CCriticalSection cs;
|
||||
int nId; // number of address id's
|
||||
std::map<int, CAddrInfo> idToInfo; // map address id to address info (b,c,d,e)
|
||||
std::map<CIPPort, int> ipToId; // map ip to id (b,c,d,e)
|
||||
std::map<CService, int> ipToId; // map ip to id (b,c,d,e)
|
||||
std::deque<int> ourId; // sequence of tried nodes, in order we have tried connecting to them (c,d)
|
||||
std::set<int> unkId; // set of nodes not yet tried (b)
|
||||
std::set<int> goodId; // set of good nodes (d, good e)
|
||||
|
@ -179,15 +178,15 @@ private:
|
|||
protected:
|
||||
// internal routines that assume proper locks are acquired
|
||||
void Add_(const CAddress &addr, bool force); // add an address
|
||||
bool Get_(CIPPort &ip, int& wait); // get an IP to test (must call Good_, Bad_, or Skipped_ on result afterwards)
|
||||
void Good_(const CIPPort &ip, int clientV, std::string clientSV); // mark an IP as good (must have been returned by Get_)
|
||||
void Bad_(const CIPPort &ip, int ban); // mark an IP as bad (and optionally ban it) (must have been returned by Get_)
|
||||
void Skipped_(const CIPPort &ip); // mark an IP as skipped (must have been returned by Get_)
|
||||
int Lookup_(const CIPPort &ip); // look up id of an IP
|
||||
void GetIPs_(std::set<CIP>& ips, int max, bool fOnlyIPv4); // get a random set of IPs (shared lock only)
|
||||
bool Get_(CService &ip, int& wait); // get an IP to test (must call Good_, Bad_, or Skipped_ on result afterwards)
|
||||
void Good_(const CService &ip, int clientV, std::string clientSV); // mark an IP as good (must have been returned by Get_)
|
||||
void Bad_(const CService &ip, int ban); // mark an IP as bad (and optionally ban it) (must have been returned by Get_)
|
||||
void Skipped_(const CService &ip); // mark an IP as skipped (must have been returned by Get_)
|
||||
int Lookup_(const CService &ip); // look up id of an IP
|
||||
void GetIPs_(std::set<CNetAddr>& ips, int max, const bool* nets); // get a random set of IPs (shared lock only)
|
||||
|
||||
public:
|
||||
std::map<CIPPort, time_t> banned; // nodes that are banned, with their unban time (a)
|
||||
std::map<CService, time_t> banned; // nodes that are banned, with their unban time (a)
|
||||
|
||||
void GetStats(CAddrDbStats &stats) {
|
||||
SHARED_CRITICAL_BLOCK(cs) {
|
||||
|
@ -272,24 +271,24 @@ public:
|
|||
for (int i=0; i<vAddr.size(); i++)
|
||||
Add_(vAddr[i], fForce);
|
||||
}
|
||||
void Good(const CIPPort &addr, int clientVersion, std::string clientSubVersion) {
|
||||
void Good(const CService &addr, int clientVersion, std::string clientSubVersion) {
|
||||
CRITICAL_BLOCK(cs)
|
||||
Good_(addr, clientVersion, clientSubVersion);
|
||||
}
|
||||
void Skipped(const CIPPort &addr) {
|
||||
void Skipped(const CService &addr) {
|
||||
CRITICAL_BLOCK(cs)
|
||||
Skipped_(addr);
|
||||
}
|
||||
void Bad(const CIPPort &addr, int ban = 0) {
|
||||
void Bad(const CService &addr, int ban = 0) {
|
||||
CRITICAL_BLOCK(cs)
|
||||
Bad_(addr, ban);
|
||||
}
|
||||
bool Get(CIPPort &ip, int& wait) {
|
||||
bool Get(CService &ip, int& wait) {
|
||||
CRITICAL_BLOCK(cs)
|
||||
return Get_(ip, wait);
|
||||
}
|
||||
void GetIPs(std::set<CIP>& ips, int max, bool fOnlyIPv4 = true) {
|
||||
void GetIPs(std::set<CNetAddr>& ips, int max, const bool *nets) {
|
||||
SHARED_CRITICAL_BLOCK(cs)
|
||||
GetIPs_(ips, max, fOnlyIPv4);
|
||||
GetIPs_(ips, max, nets);
|
||||
}
|
||||
};
|
||||
|
|
28
dns.c
28
dns.c
|
@ -127,7 +127,9 @@ error:
|
|||
}
|
||||
|
||||
|
||||
int static write_record_a(unsigned char** outpos, const unsigned char *outend, const char *name, int offset, dns_class cls, int ttl, const struct in_addr *ip) {
|
||||
int static write_record_a(unsigned char** outpos, const unsigned char *outend, const char *name, int offset, dns_class cls, int ttl, const addr_t *ip) {
|
||||
if (ip->v != 4)
|
||||
return -6;
|
||||
unsigned char *oldpos = *outpos;
|
||||
int error = 0;
|
||||
int ret = write_record(outpos, outend, name, offset, TYPE_A, cls, ttl);
|
||||
|
@ -136,16 +138,17 @@ int static write_record_a(unsigned char** outpos, const unsigned char *outend, c
|
|||
// rdlength
|
||||
*((*outpos)++) = 0; *((*outpos)++) = 4;
|
||||
// rdata
|
||||
const unsigned char *pd = (const unsigned char*)ip;
|
||||
for (int i=0; i<4; i++)
|
||||
*((*outpos)++) = pd[i];
|
||||
*((*outpos)++) = ip->data.v4[i];
|
||||
return 0;
|
||||
error:
|
||||
*outpos = oldpos;
|
||||
return error;
|
||||
}
|
||||
|
||||
int static write_record_aaaa(unsigned char** outpos, const unsigned char *outend, const char *name, int offset, dns_class cls, int ttl, const struct in6_addr *ip) {
|
||||
int static write_record_aaaa(unsigned char** outpos, const unsigned char *outend, const char *name, int offset, dns_class cls, int ttl, const addr_t *ip) {
|
||||
if (ip->v != 6)
|
||||
return -6;
|
||||
unsigned char *oldpos = *outpos;
|
||||
int error = 0;
|
||||
int ret = write_record(outpos, outend, name, offset, TYPE_AAAA, cls, ttl);
|
||||
|
@ -154,9 +157,8 @@ int static write_record_aaaa(unsigned char** outpos, const unsigned char *outend
|
|||
// rdlength
|
||||
*((*outpos)++) = 0; *((*outpos)++) = 16;
|
||||
// rdata
|
||||
const unsigned char *pd = (const unsigned char*)ip;
|
||||
for (int i=0; i<16; i++)
|
||||
*((*outpos)++) = pd[i];
|
||||
*((*outpos)++) = ip->data.v6[i];
|
||||
return 0;
|
||||
error:
|
||||
*outpos = oldpos;
|
||||
|
@ -293,13 +295,17 @@ ssize_t static dnshandle(dns_opt_t *opt, const unsigned char *inbuf, size_t insi
|
|||
if (!ret2) { outbuf[7]++; }
|
||||
}
|
||||
|
||||
// A records
|
||||
if ((typ == TYPE_A || typ == QTYPE_ANY) && (cls == CLASS_IN || cls == QCLASS_ANY)) {
|
||||
struct in_addr addr[32];
|
||||
int naddr = opt->cb((void*)opt, addr, 32, 1);
|
||||
// A/AAAA records
|
||||
if ((typ == TYPE_A || typ == TYPE_AAAA || typ == QTYPE_ANY) && (cls == CLASS_IN || cls == QCLASS_ANY)) {
|
||||
addr_t addr[32];
|
||||
int naddr = opt->cb((void*)opt, addr, 32, typ == TYPE_A || typ == QTYPE_ANY, typ == TYPE_AAAA || typ == QTYPE_ANY);
|
||||
int n = 0;
|
||||
while (n < naddr) {
|
||||
int ret = write_record_a(&outpos, outend - auth_size, "", offset, CLASS_IN, opt->datattl, &addr[n]);
|
||||
int ret = 1;
|
||||
if (addr->v == 4)
|
||||
ret = write_record_a(&outpos, outend - auth_size, "", offset, CLASS_IN, opt->datattl, &addr[n]);
|
||||
else if (addr->v == 6)
|
||||
ret = write_record_aaaa(&outpos, outend - auth_size, "", offset, CLASS_IN, opt->datattl, &addr[n]);
|
||||
// printf("wrote A record: %i\n", ret);
|
||||
if (!ret) {
|
||||
n++;
|
||||
|
|
10
dns.h
10
dns.h
|
@ -3,6 +3,14 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
int v;
|
||||
union {
|
||||
unsigned char v4[4];
|
||||
unsigned char v6[16];
|
||||
} data;
|
||||
} addr_t;
|
||||
|
||||
typedef struct {
|
||||
int port;
|
||||
int datattl;
|
||||
|
@ -10,7 +18,7 @@ typedef struct {
|
|||
const char *host;
|
||||
const char *ns;
|
||||
const char *mbox;
|
||||
int (*cb)(void *opt, struct in_addr *addr, int max, int ipv4only);
|
||||
int (*cb)(void *opt, addr_t *addr, int max, int ipv4, int ipv6);
|
||||
// stats
|
||||
uint64_t nRequests;
|
||||
} dns_opt_t;
|
||||
|
|
62
main.cpp
62
main.cpp
|
@ -105,7 +105,7 @@ CAddrDb db;
|
|||
|
||||
extern "C" void* ThreadCrawler(void* data) {
|
||||
do {
|
||||
CIPPort ip;
|
||||
CService ip;
|
||||
int wait = 5;
|
||||
if (!db.Get(ip, wait)) {
|
||||
wait *= 1000;
|
||||
|
@ -127,29 +127,50 @@ extern "C" void* ThreadCrawler(void* data) {
|
|||
} while(1);
|
||||
}
|
||||
|
||||
extern "C" int GetIPList(void *thread, struct in_addr *addr, int max, int ipv4only);
|
||||
extern "C" int GetIPList(void *thread, addr_t *addr, int max, int ipv4, int ipv6);
|
||||
|
||||
class CDnsThread {
|
||||
public:
|
||||
dns_opt_t dns_opt;
|
||||
vector<struct in_addr> cache;
|
||||
vector<addr_t> cache;
|
||||
int nIPv4, nIPv6;
|
||||
time_t cacheTime;
|
||||
unsigned int cacheHits;
|
||||
uint64_t dbQueries;
|
||||
|
||||
void cacheHit(int ipv4only, bool force = false) {
|
||||
void cacheHit(bool force = false) {
|
||||
static bool nets[NET_MAX] = {};
|
||||
if (!nets[NET_IPV4]) {
|
||||
nets[NET_IPV4] = true;
|
||||
nets[NET_IPV6] = true;
|
||||
}
|
||||
time_t now = time(NULL);
|
||||
cacheHits++;
|
||||
if (force || cacheHits > (cache.size()*cache.size()/400) || (cacheHits*cacheHits > cache.size() / 20 && (now - cacheTime > 5))) {
|
||||
set<CIP> ips;
|
||||
db.GetIPs(ips, 1000, ipv4only);
|
||||
set<CNetAddr> ips;
|
||||
db.GetIPs(ips, 1000, nets);
|
||||
dbQueries++;
|
||||
cache.clear();
|
||||
nIPv4 = 0;
|
||||
nIPv6 = 0;
|
||||
cache.reserve(ips.size());
|
||||
for (set<CIP>::iterator it = ips.begin(); it != ips.end(); it++) {
|
||||
for (set<CNetAddr>::iterator it = ips.begin(); it != ips.end(); it++) {
|
||||
struct in_addr addr;
|
||||
struct in6_addr addr6;
|
||||
if ((*it).GetInAddr(&addr)) {
|
||||
cache.push_back(addr);
|
||||
addr_t a;
|
||||
a.v = 4;
|
||||
memcpy(&a.data.v4, &addr, 4);
|
||||
cache.push_back(a);
|
||||
nIPv4++;
|
||||
#ifdef USE_IPV6
|
||||
} else if ((*it).GetIn6Addr(&addr6)) {
|
||||
addr_t a;
|
||||
a.v = 6;
|
||||
memcpy(&a.data.v6, &addr6, 16);
|
||||
cache.push_back(a);
|
||||
nIPv6++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
cacheHits = 0;
|
||||
|
@ -171,7 +192,9 @@ public:
|
|||
cacheTime = 0;
|
||||
cacheHits = 0;
|
||||
dbQueries = 0;
|
||||
cacheHit(true, true);
|
||||
nIPv4 = 0;
|
||||
nIPv6 = 0;
|
||||
cacheHit(true);
|
||||
}
|
||||
|
||||
void run() {
|
||||
|
@ -179,14 +202,21 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
extern "C" int GetIPList(void *data, struct in_addr *addr, int max, int ipv4only) {
|
||||
extern "C" int GetIPList(void *data, addr_t* addr, int max, int ipv4, int ipv6) {
|
||||
CDnsThread *thread = (CDnsThread*)data;
|
||||
thread->cacheHit(ipv4only);
|
||||
unsigned int size = thread->cache.size();
|
||||
thread->cacheHit();
|
||||
unsigned int size = (ipv4 ? thread->nIPv4 : 0) + (ipv6 ? thread->nIPv6 : 0);
|
||||
if (max > size)
|
||||
max = size;
|
||||
for (int i=0; i<max; i++) {
|
||||
int i=0;
|
||||
while (i<max) {
|
||||
int j = i + (rand() % (size - i));
|
||||
do {
|
||||
bool ok = (ipv4 && thread->cache[j].v == 4) ||
|
||||
(ipv6 && thread->cache[j].v == 6);
|
||||
if (ok) break;
|
||||
j = i + ((j - i + 1) % (size - i));
|
||||
} while(1);
|
||||
addr[i] = thread->cache[j];
|
||||
thread->cache[j] = thread->cache[i];
|
||||
thread->cache[i] = addr[i];
|
||||
|
@ -269,10 +299,10 @@ static const string seeds[] = {"dnsseed.bluematt.me", "bitseed.xf2.org", "dnssee
|
|||
extern "C" void* ThreadSeeder(void*) {
|
||||
do {
|
||||
for (int i=0; i<sizeof(seeds)/sizeof(seeds[0]); i++) {
|
||||
vector<CIP> ips;
|
||||
vector<CNetAddr> ips;
|
||||
LookupHost(seeds[i].c_str(), ips);
|
||||
for (vector<CIP>::iterator it = ips.begin(); it != ips.end(); it++) {
|
||||
db.Add(CIPPort(*it, 8333), true);
|
||||
for (vector<CNetAddr>::iterator it = ips.begin(); it != ips.end(); it++) {
|
||||
db.Add(CService(*it, 8333), true);
|
||||
}
|
||||
}
|
||||
Sleep(1800000);
|
||||
|
|
833
netbase.cpp
833
netbase.cpp
File diff suppressed because it is too large
Load diff
131
netbase.h
131
netbase.h
|
@ -1,49 +1,52 @@
|
|||
// Copyright (c) 2011 The Bitcoin developers
|
||||
// Copyright (c) 2009-2012 The Bitcoin developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_NETBASE_H
|
||||
#define BITCOIN_NETBASE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#include <mswsock.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <net/if.h>
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
#ifdef BSD
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include "serialize.h"
|
||||
|
||||
typedef int SOCKET;
|
||||
#include "compat.h"
|
||||
|
||||
extern int nConnectTimeout;
|
||||
|
||||
// IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
|
||||
class CIP
|
||||
#ifdef WIN32
|
||||
// In MSVC, this is defined as a macro, undefine it to prevent a compile and link error
|
||||
#undef SetPort
|
||||
#endif
|
||||
|
||||
enum Network
|
||||
{
|
||||
NET_UNROUTABLE,
|
||||
NET_IPV4,
|
||||
NET_IPV6,
|
||||
NET_TOR,
|
||||
NET_I2P,
|
||||
|
||||
NET_MAX,
|
||||
};
|
||||
|
||||
extern int nConnectTimeout;
|
||||
extern bool fNameLookup;
|
||||
|
||||
/** IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96)) */
|
||||
class CNetAddr
|
||||
{
|
||||
protected:
|
||||
unsigned char ip[16]; // in network byte order
|
||||
|
||||
public:
|
||||
CIP();
|
||||
CIP(const struct in_addr& ipv4Addr);
|
||||
CIP(const char *pszIp, bool fAllowLookup = false);
|
||||
CIP(const std::string &strIp, bool fAllowLookup = false);
|
||||
CNetAddr();
|
||||
CNetAddr(const struct in_addr& ipv4Addr);
|
||||
explicit CNetAddr(const char *pszIp, bool fAllowLookup = false);
|
||||
explicit CNetAddr(const std::string &strIp, bool fAllowLookup = false);
|
||||
void Init();
|
||||
void SetIP(const CIP& ip);
|
||||
void SetIP(const CNetAddr& ip);
|
||||
bool SetSpecial(const std::string &strName); // for Tor and I2P addresses
|
||||
bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
|
||||
bool IsIPv6() const; // IPv6 address (not mapped IPv4, not Tor/I2P)
|
||||
bool IsRFC1918() const; // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12)
|
||||
bool IsRFC3849() const; // IPv6 documentation address (2001:0DB8::/32)
|
||||
bool IsRFC3927() const; // IPv4 autoconfig (169.254.0.0/16)
|
||||
|
@ -54,25 +57,30 @@ class CIP
|
|||
bool IsRFC4862() const; // IPv6 autoconfig (FE80::/64)
|
||||
bool IsRFC6052() const; // IPv6 well-known prefix (64:FF9B::/96)
|
||||
bool IsRFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96)
|
||||
bool IsTor() const;
|
||||
bool IsI2P() const;
|
||||
bool IsLocal() const;
|
||||
bool IsRoutable() const;
|
||||
bool IsValid() const;
|
||||
bool IsMulticast() const;
|
||||
enum Network GetNetwork() const;
|
||||
std::string ToString() const;
|
||||
std::string ToStringIP() const;
|
||||
int GetByte(int n) const;
|
||||
int64 GetHash() const;
|
||||
bool GetInAddr(struct in_addr* pipv4Addr) const;
|
||||
std::vector<unsigned char> GetGroup() const;
|
||||
int GetReachabilityFrom(const CNetAddr *paddrPartner = NULL) const;
|
||||
void print() const;
|
||||
|
||||
#ifdef USE_IPV6
|
||||
CIP(const struct in6_addr& pipv6Addr);
|
||||
CNetAddr(const struct in6_addr& pipv6Addr);
|
||||
bool GetIn6Addr(struct in6_addr* pipv6Addr) const;
|
||||
#endif
|
||||
|
||||
friend bool operator==(const CIP& a, const CIP& b);
|
||||
friend bool operator!=(const CIP& a, const CIP& b);
|
||||
friend bool operator<(const CIP& a, const CIP& 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);
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
(
|
||||
|
@ -80,41 +88,43 @@ class CIP
|
|||
)
|
||||
};
|
||||
|
||||
class CIPPort : public CIP
|
||||
/** A combination of a network address (CNetAddr) and a (TCP) port */
|
||||
class CService : public CNetAddr
|
||||
{
|
||||
protected:
|
||||
unsigned short port; // host order
|
||||
|
||||
public:
|
||||
CIPPort();
|
||||
CIPPort(const CIP& ip, unsigned short port);
|
||||
CIPPort(const struct in_addr& ipv4Addr, unsigned short port);
|
||||
CIPPort(const struct sockaddr_in& addr);
|
||||
CIPPort(const char *pszIp, int port, bool fAllowLookup = false);
|
||||
CIPPort(const char *pszIpPort, bool fAllowLookup = false);
|
||||
CIPPort(const std::string& strIp, int port, bool fAllowLookup = false);
|
||||
CIPPort(const std::string& strIpPort, bool fAllowLookup = false);
|
||||
CService();
|
||||
CService(const CNetAddr& ip, unsigned short port);
|
||||
CService(const struct in_addr& ipv4Addr, unsigned short port);
|
||||
CService(const struct sockaddr_in& addr);
|
||||
explicit CService(const char *pszIpPort, int portDefault, bool fAllowLookup = false);
|
||||
explicit CService(const char *pszIpPort, bool fAllowLookup = false);
|
||||
explicit CService(const std::string& strIpPort, int portDefault, bool fAllowLookup = false);
|
||||
explicit CService(const std::string& strIpPort, bool fAllowLookup = false);
|
||||
void Init();
|
||||
void SetPort(unsigned short portIn);
|
||||
unsigned short GetPort() const;
|
||||
bool GetSockAddr(struct sockaddr_in* paddr) const;
|
||||
bool ConnectSocket(SOCKET& hSocketRet, int nTimeout = nConnectTimeout) const;
|
||||
friend bool operator==(const CIPPort& a, const CIPPort& b);
|
||||
friend bool operator!=(const CIPPort& a, const CIPPort& b);
|
||||
friend bool operator<(const CIPPort& a, const CIPPort& b);
|
||||
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);
|
||||
std::vector<unsigned char> GetKey() const;
|
||||
std::string ToString() const;
|
||||
std::string ToStringPort() const;
|
||||
std::string ToStringIPPort() const;
|
||||
void print() const;
|
||||
|
||||
#ifdef USE_IPV6
|
||||
CIPPort(const struct in6_addr& ipv6Addr, unsigned short port);
|
||||
bool GetSockAddr6(struct sockaddr_in6* paddr) const;
|
||||
CIPPort(const struct sockaddr_in6& addr);
|
||||
CService(const struct in6_addr& ipv6Addr, unsigned short port);
|
||||
CService(const struct sockaddr_in6& addr);
|
||||
#endif
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
(
|
||||
CIPPort* pthis = const_cast<CIPPort*>(this);
|
||||
CService* pthis = const_cast<CService*>(this);
|
||||
READWRITE(FLATDATA(ip));
|
||||
unsigned short portN = htons(port);
|
||||
READWRITE(portN);
|
||||
|
@ -123,13 +133,18 @@ class CIPPort : public CIP
|
|||
)
|
||||
};
|
||||
|
||||
bool LookupHost(const char *pszName, std::vector<CIP>& vIP, int nMaxSolutions = 0, bool fAllowLookup = true);
|
||||
bool LookupHostNumeric(const char *pszName, std::vector<CIP>& vIP, int nMaxSolutions = 0);
|
||||
bool Lookup(const char *pszName, CIPPort& addr, int portDefault = 0, bool fAllowLookup = true);
|
||||
bool LookupNumeric(const char *pszName, CIPPort& addr, int portDefault = 0);
|
||||
|
||||
// Settings
|
||||
extern int fUseProxy;
|
||||
extern CIPPort addrProxy;
|
||||
enum Network ParseNetwork(std::string net);
|
||||
bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion = 5);
|
||||
bool GetProxy(enum Network net, CService &addrProxy);
|
||||
bool IsProxy(const CNetAddr &addr);
|
||||
bool SetNameProxy(CService addrProxy, int nSocksVersion = 5);
|
||||
bool GetNameProxy();
|
||||
bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions = 0, bool fAllowLookup = true);
|
||||
bool LookupHostNumeric(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions = 0);
|
||||
bool Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllowLookup = true);
|
||||
bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault = 0, bool fAllowLookup = true, unsigned int nMaxSolutions = 0);
|
||||
bool LookupNumeric(const char *pszName, CService& addr, int portDefault = 0);
|
||||
bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout = nConnectTimeout);
|
||||
bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault = 0, int nTimeout = nConnectTimeout);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -81,12 +81,12 @@ bool CMessageHeader::IsValid() const
|
|||
|
||||
|
||||
|
||||
CAddress::CAddress() : CIPPort()
|
||||
CAddress::CAddress() : CService()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
CAddress::CAddress(CIPPort ipIn, uint64 nServicesIn) : CIPPort(ipIn)
|
||||
CAddress::CAddress(CService ipIn, uint64 nServicesIn) : CService(ipIn)
|
||||
{
|
||||
Init();
|
||||
nServices = nServicesIn;
|
||||
|
|
|
@ -62,18 +62,18 @@ enum
|
|||
NODE_NETWORK = (1 << 0),
|
||||
};
|
||||
|
||||
class CAddress : public CIPPort
|
||||
class CAddress : public CService
|
||||
{
|
||||
public:
|
||||
CAddress();
|
||||
CAddress(CIPPort ipIn, uint64 nServicesIn=NODE_NETWORK);
|
||||
CAddress(CService ipIn, uint64 nServicesIn=NODE_NETWORK);
|
||||
|
||||
void Init();
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
(
|
||||
CAddress* pthis = const_cast<CAddress*>(this);
|
||||
CIPPort* pip = (CIPPort*)pthis;
|
||||
CService* pip = (CService*)pthis;
|
||||
if (fRead)
|
||||
pthis->Init();
|
||||
if (nType & SER_DISK)
|
||||
|
|
6
test.pl
6
test.pl
|
@ -17,8 +17,8 @@ sub go {
|
|||
|
||||
my $sock = IO::Socket::INET->new(
|
||||
Proto => 'udp',
|
||||
PeerPort => 5353,
|
||||
PeerAddr => "127.0.0.1",
|
||||
PeerPort => 53,
|
||||
PeerAddr => "vps.sipa.be",
|
||||
) or die "Could not create socket: $!\n";
|
||||
|
||||
while($run) {
|
||||
|
@ -52,7 +52,7 @@ sub go {
|
|||
|
||||
my @threads;
|
||||
|
||||
for my $i (0..3) {
|
||||
for my $i (0..500) {
|
||||
$threads[$i] = threads->create(\&go, $i);
|
||||
}
|
||||
|
||||
|
|
44
util.h
44
util.h
|
@ -4,6 +4,7 @@
|
|||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "uint256.h"
|
||||
|
||||
|
@ -26,21 +27,6 @@
|
|||
#define INVALID_SOCKET (SOCKET)(~0)
|
||||
#define SOCKET_ERROR -1
|
||||
|
||||
inline int myclosesocket(SOCKET& hSocket)
|
||||
{
|
||||
if (hSocket == INVALID_SOCKET)
|
||||
return WSAENOTSOCK;
|
||||
#ifdef WIN32
|
||||
int ret = closesocket(hSocket);
|
||||
#else
|
||||
int ret = close(hSocket);
|
||||
#endif
|
||||
hSocket = INVALID_SOCKET;
|
||||
return ret;
|
||||
}
|
||||
#define closesocket(s) myclosesocket(s)
|
||||
|
||||
|
||||
// Wrapper to automatically initialize mutex
|
||||
class CCriticalSection
|
||||
{
|
||||
|
@ -87,10 +73,30 @@ template<typename T1> inline uint256 Hash(const T1 pbegin, const T1 pend)
|
|||
}
|
||||
|
||||
void static inline Sleep(int nMilliSec) {
|
||||
struct timespec wa;
|
||||
wa.tv_sec = nMilliSec/1000;
|
||||
wa.tv_nsec = (nMilliSec % 1000) * 1000000;
|
||||
nanosleep(&wa, NULL);
|
||||
struct timespec wa;
|
||||
wa.tv_sec = nMilliSec/1000;
|
||||
wa.tv_nsec = (nMilliSec % 1000) * 1000000;
|
||||
nanosleep(&wa, NULL);
|
||||
}
|
||||
|
||||
|
||||
std::string vstrprintf(const std::string &format, va_list ap);
|
||||
|
||||
std::string static inline strprintf(const std::string &format, ...) {
|
||||
va_list arg_ptr;
|
||||
va_start(arg_ptr, format);
|
||||
std::string ret = vstrprintf(format, arg_ptr);
|
||||
va_end(arg_ptr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool static inline error(std::string err) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid = NULL);
|
||||
std::string DecodeBase32(const std::string& str);
|
||||
std::string EncodeBase32(const unsigned char* pch, size_t len);
|
||||
std::string EncodeBase32(const std::string& str);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue