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
|
dnsseed: dns.o bitcoin.o netbase.o protocol.o db.o main.o util.o
|
||||||
g++ -pthread -lcrypto -o dnsseed dns.o bitcoin.o netbase.o protocol.o db.o main.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
|
%.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
|
dns.o: dns.c
|
||||||
gcc -pthread -std=c99 -O2 -ggdb3 -march=nocona dns.c -c -o dns.o
|
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);
|
int64 nTime = time(NULL);
|
||||||
uint64 nLocalNonce = BITCOIN_SEED_NONCE;
|
uint64 nLocalNonce = BITCOIN_SEED_NONCE;
|
||||||
int64 nLocalServices = 0;
|
int64 nLocalServices = 0;
|
||||||
CAddress me(CIPPort("0.0.0.0"));
|
CAddress me(CService("0.0.0.0"));
|
||||||
BeginMessage("version");
|
BeginMessage("version");
|
||||||
int nBestHeight = REQUIRE_HEIGHT;
|
int nBestHeight = REQUIRE_HEIGHT;
|
||||||
string ver = "/bitcoin-seeder:0.01/";
|
string ver = "/bitcoin-seeder:0.01/";
|
||||||
|
@ -132,8 +132,6 @@ class CNode {
|
||||||
CAddress &addr = *it;
|
CAddress &addr = *it;
|
||||||
// printf("%s: got address %s\n", ToString(you).c_str(), addr.ToString().c_str(), (int)(vAddr->size()));
|
// printf("%s: got address %s\n", ToString(you).c_str(), addr.ToString().c_str(), (int)(vAddr->size()));
|
||||||
it++;
|
it++;
|
||||||
if (!addr.IsIPv4())
|
|
||||||
continue;
|
|
||||||
if (addr.nTime <= 100000000 || addr.nTime > now + 600)
|
if (addr.nTime <= 100000000 || addr.nTime > now + 600)
|
||||||
addr.nTime = now - 5 * 86400;
|
addr.nTime = now - 5 * 86400;
|
||||||
vAddr->push_back(addr);
|
vAddr->push_back(addr);
|
||||||
|
@ -192,7 +190,7 @@ class CNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
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.SetType(SER_NETWORK);
|
||||||
vSend.SetVersion(0);
|
vSend.SetVersion(0);
|
||||||
vRecv.SetType(SER_NETWORK);
|
vRecv.SetType(SER_NETWORK);
|
||||||
|
@ -204,7 +202,7 @@ public:
|
||||||
}
|
}
|
||||||
bool Run() {
|
bool Run() {
|
||||||
bool res = true;
|
bool res = true;
|
||||||
if (!you.ConnectSocket(sock)) return false;
|
if (!ConnectSocket(you, sock)) return false;
|
||||||
PushVersion();
|
PushVersion();
|
||||||
Send();
|
Send();
|
||||||
int64 now;
|
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 {
|
try {
|
||||||
CNode node(cip, vAddr);
|
CNode node(cip, vAddr);
|
||||||
bool ret = node.Run();
|
bool ret = node.Run();
|
||||||
|
@ -283,7 +281,7 @@ bool TestNode(const CIPPort &cip, int &ban, int &clientV, std::string &clientSV,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
int main(void) {
|
int main(void) {
|
||||||
CIPPort ip("bitcoin.sipa.be", 8333, true);
|
CService ip("bitcoin.sipa.be", 8333, true);
|
||||||
vector<CAddress> vAddr;
|
vector<CAddress> vAddr;
|
||||||
vAddr.clear();
|
vAddr.clear();
|
||||||
int ban = 0;
|
int ban = 0;
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
|
|
||||||
#include "protocol.h"
|
#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
|
#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);
|
// 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);
|
int64 now = time(NULL);
|
||||||
int cont = 0;
|
int cont = 0;
|
||||||
int tot = unkId.size();
|
int tot = unkId.size();
|
||||||
|
@ -78,13 +78,13 @@ bool CAddrDb::Get_(CIPPort &ip, int &wait) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CAddrDb::Lookup_(const CIPPort &ip) {
|
int CAddrDb::Lookup_(const CService &ip) {
|
||||||
if (ipToId.count(ip))
|
if (ipToId.count(ip))
|
||||||
return ipToId[ip];
|
return ipToId[ip];
|
||||||
return -1;
|
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);
|
int id = Lookup_(addr);
|
||||||
if (id == -1) return;
|
if (id == -1) return;
|
||||||
unkId.erase(id);
|
unkId.erase(id);
|
||||||
|
@ -101,7 +101,7 @@ void CAddrDb::Good_(const CIPPort &addr, int clientV, std::string clientSV) {
|
||||||
ourId.push_back(id);
|
ourId.push_back(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAddrDb::Bad_(const CIPPort &addr, int ban)
|
void CAddrDb::Bad_(const CService &addr, int ban)
|
||||||
{
|
{
|
||||||
int id = Lookup_(addr);
|
int id = Lookup_(addr);
|
||||||
if (id == -1) return;
|
if (id == -1) return;
|
||||||
|
@ -130,7 +130,7 @@ void CAddrDb::Bad_(const CIPPort &addr, int ban)
|
||||||
nDirty++;
|
nDirty++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAddrDb::Skipped_(const CIPPort &addr)
|
void CAddrDb::Skipped_(const CService &addr)
|
||||||
{
|
{
|
||||||
int id = Lookup_(addr);
|
int id = Lookup_(addr);
|
||||||
if (id == -1) return;
|
if (id == -1) return;
|
||||||
|
@ -144,7 +144,7 @@ void CAddrDb::Skipped_(const CIPPort &addr)
|
||||||
void CAddrDb::Add_(const CAddress &addr, bool force) {
|
void CAddrDb::Add_(const CAddress &addr, bool force) {
|
||||||
if (!force && !addr.IsRoutable())
|
if (!force && !addr.IsRoutable())
|
||||||
return;
|
return;
|
||||||
CIPPort ipp(addr);
|
CService ipp(addr);
|
||||||
if (banned.count(ipp)) {
|
if (banned.count(ipp)) {
|
||||||
time_t bantime = banned[ipp];
|
time_t bantime = banned[ipp];
|
||||||
if (force || (bantime < time(NULL) && addr.nTime > bantime))
|
if (force || (bantime < time(NULL) && addr.nTime > bantime))
|
||||||
|
@ -180,7 +180,7 @@ void CAddrDb::Add_(const CAddress &addr, bool force) {
|
||||||
nDirty++;
|
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) {
|
if (goodId.size() == 0) {
|
||||||
int id = -1;
|
int id = -1;
|
||||||
if (ourId.size() == 0) {
|
if (ourId.size() == 0) {
|
||||||
|
@ -208,8 +208,8 @@ void CAddrDb::GetIPs_(set<CIP>& ips, int max, bool fOnlyIPv4) {
|
||||||
ids.insert(id);
|
ids.insert(id);
|
||||||
}
|
}
|
||||||
for (set<int>::const_iterator it = ids.begin(); it != ids.end(); it++) {
|
for (set<int>::const_iterator it = ids.begin(); it != ids.end(); it++) {
|
||||||
CIPPort &ip = idToInfo[*it].ip;
|
CService &ip = idToInfo[*it].ip;
|
||||||
if (ip.IsValid() && (!fOnlyIPv4 || ip.IsIPv4()))
|
if (nets[ip.GetNetwork()])
|
||||||
ips.insert(ip);
|
ips.insert(ip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
35
db.h
35
db.h
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
#define MIN_RETRY 1000
|
#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();
|
std::string str = ip.ToString();
|
||||||
while (str.size() < 22) str += ' ';
|
while (str.size() < 22) str += ' ';
|
||||||
return str;
|
return str;
|
||||||
|
@ -44,7 +44,7 @@ public:
|
||||||
|
|
||||||
class CAddrReport {
|
class CAddrReport {
|
||||||
public:
|
public:
|
||||||
CIPPort ip;
|
CService ip;
|
||||||
int clientVersion;
|
int clientVersion;
|
||||||
double uptime[5];
|
double uptime[5];
|
||||||
std::string clientSubVersion;
|
std::string clientSubVersion;
|
||||||
|
@ -53,7 +53,7 @@ public:
|
||||||
|
|
||||||
class CAddrInfo {
|
class CAddrInfo {
|
||||||
private:
|
private:
|
||||||
CIPPort ip;
|
CService ip;
|
||||||
uint64_t services;
|
uint64_t services;
|
||||||
int64 lastTry;
|
int64 lastTry;
|
||||||
int64 ourLastTry;
|
int64 ourLastTry;
|
||||||
|
@ -87,7 +87,6 @@ public:
|
||||||
if (ip.GetPort() != 8333) return false;
|
if (ip.GetPort() != 8333) return false;
|
||||||
if (!(services & NODE_NETWORK)) return false;
|
if (!(services & NODE_NETWORK)) return false;
|
||||||
if (!ip.IsRoutable()) return false;
|
if (!ip.IsRoutable()) return false;
|
||||||
if (!ip.IsIPv4()) return false;
|
|
||||||
if (clientVersion && clientVersion < 32400) return false;
|
if (clientVersion && clientVersion < 32400) return false;
|
||||||
|
|
||||||
if (total <= 3 && success * 2 >= total) return true;
|
if (total <= 3 && success * 2 >= total) return true;
|
||||||
|
@ -170,7 +169,7 @@ private:
|
||||||
mutable CCriticalSection cs;
|
mutable CCriticalSection cs;
|
||||||
int nId; // number of address id's
|
int nId; // number of address id's
|
||||||
std::map<int, CAddrInfo> idToInfo; // map address id to address info (b,c,d,e)
|
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::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> unkId; // set of nodes not yet tried (b)
|
||||||
std::set<int> goodId; // set of good nodes (d, good e)
|
std::set<int> goodId; // set of good nodes (d, good e)
|
||||||
|
@ -179,15 +178,15 @@ private:
|
||||||
protected:
|
protected:
|
||||||
// internal routines that assume proper locks are acquired
|
// internal routines that assume proper locks are acquired
|
||||||
void Add_(const CAddress &addr, bool force); // add an address
|
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)
|
bool Get_(CService &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 Good_(const CService &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 Bad_(const CService &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_)
|
void Skipped_(const CService &ip); // mark an IP as skipped (must have been returned by Get_)
|
||||||
int Lookup_(const CIPPort &ip); // look up id of an IP
|
int Lookup_(const CService &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)
|
void GetIPs_(std::set<CNetAddr>& ips, int max, const bool* nets); // get a random set of IPs (shared lock only)
|
||||||
|
|
||||||
public:
|
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) {
|
void GetStats(CAddrDbStats &stats) {
|
||||||
SHARED_CRITICAL_BLOCK(cs) {
|
SHARED_CRITICAL_BLOCK(cs) {
|
||||||
|
@ -272,24 +271,24 @@ public:
|
||||||
for (int i=0; i<vAddr.size(); i++)
|
for (int i=0; i<vAddr.size(); i++)
|
||||||
Add_(vAddr[i], fForce);
|
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)
|
CRITICAL_BLOCK(cs)
|
||||||
Good_(addr, clientVersion, clientSubVersion);
|
Good_(addr, clientVersion, clientSubVersion);
|
||||||
}
|
}
|
||||||
void Skipped(const CIPPort &addr) {
|
void Skipped(const CService &addr) {
|
||||||
CRITICAL_BLOCK(cs)
|
CRITICAL_BLOCK(cs)
|
||||||
Skipped_(addr);
|
Skipped_(addr);
|
||||||
}
|
}
|
||||||
void Bad(const CIPPort &addr, int ban = 0) {
|
void Bad(const CService &addr, int ban = 0) {
|
||||||
CRITICAL_BLOCK(cs)
|
CRITICAL_BLOCK(cs)
|
||||||
Bad_(addr, ban);
|
Bad_(addr, ban);
|
||||||
}
|
}
|
||||||
bool Get(CIPPort &ip, int& wait) {
|
bool Get(CService &ip, int& wait) {
|
||||||
CRITICAL_BLOCK(cs)
|
CRITICAL_BLOCK(cs)
|
||||||
return Get_(ip, wait);
|
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)
|
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;
|
unsigned char *oldpos = *outpos;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int ret = write_record(outpos, outend, name, offset, TYPE_A, cls, ttl);
|
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
|
// rdlength
|
||||||
*((*outpos)++) = 0; *((*outpos)++) = 4;
|
*((*outpos)++) = 0; *((*outpos)++) = 4;
|
||||||
// rdata
|
// rdata
|
||||||
const unsigned char *pd = (const unsigned char*)ip;
|
|
||||||
for (int i=0; i<4; i++)
|
for (int i=0; i<4; i++)
|
||||||
*((*outpos)++) = pd[i];
|
*((*outpos)++) = ip->data.v4[i];
|
||||||
return 0;
|
return 0;
|
||||||
error:
|
error:
|
||||||
*outpos = oldpos;
|
*outpos = oldpos;
|
||||||
return error;
|
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;
|
unsigned char *oldpos = *outpos;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int ret = write_record(outpos, outend, name, offset, TYPE_AAAA, cls, ttl);
|
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
|
// rdlength
|
||||||
*((*outpos)++) = 0; *((*outpos)++) = 16;
|
*((*outpos)++) = 0; *((*outpos)++) = 16;
|
||||||
// rdata
|
// rdata
|
||||||
const unsigned char *pd = (const unsigned char*)ip;
|
|
||||||
for (int i=0; i<16; i++)
|
for (int i=0; i<16; i++)
|
||||||
*((*outpos)++) = pd[i];
|
*((*outpos)++) = ip->data.v6[i];
|
||||||
return 0;
|
return 0;
|
||||||
error:
|
error:
|
||||||
*outpos = oldpos;
|
*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]++; }
|
if (!ret2) { outbuf[7]++; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// A records
|
// A/AAAA records
|
||||||
if ((typ == TYPE_A || typ == QTYPE_ANY) && (cls == CLASS_IN || cls == QCLASS_ANY)) {
|
if ((typ == TYPE_A || typ == TYPE_AAAA || typ == QTYPE_ANY) && (cls == CLASS_IN || cls == QCLASS_ANY)) {
|
||||||
struct in_addr addr[32];
|
addr_t addr[32];
|
||||||
int naddr = opt->cb((void*)opt, addr, 32, 1);
|
int naddr = opt->cb((void*)opt, addr, 32, typ == TYPE_A || typ == QTYPE_ANY, typ == TYPE_AAAA || typ == QTYPE_ANY);
|
||||||
int n = 0;
|
int n = 0;
|
||||||
while (n < naddr) {
|
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);
|
// printf("wrote A record: %i\n", ret);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
n++;
|
n++;
|
||||||
|
|
10
dns.h
10
dns.h
|
@ -3,6 +3,14 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int v;
|
||||||
|
union {
|
||||||
|
unsigned char v4[4];
|
||||||
|
unsigned char v6[16];
|
||||||
|
} data;
|
||||||
|
} addr_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int port;
|
int port;
|
||||||
int datattl;
|
int datattl;
|
||||||
|
@ -10,7 +18,7 @@ typedef struct {
|
||||||
const char *host;
|
const char *host;
|
||||||
const char *ns;
|
const char *ns;
|
||||||
const char *mbox;
|
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
|
// stats
|
||||||
uint64_t nRequests;
|
uint64_t nRequests;
|
||||||
} dns_opt_t;
|
} dns_opt_t;
|
||||||
|
|
62
main.cpp
62
main.cpp
|
@ -105,7 +105,7 @@ CAddrDb db;
|
||||||
|
|
||||||
extern "C" void* ThreadCrawler(void* data) {
|
extern "C" void* ThreadCrawler(void* data) {
|
||||||
do {
|
do {
|
||||||
CIPPort ip;
|
CService ip;
|
||||||
int wait = 5;
|
int wait = 5;
|
||||||
if (!db.Get(ip, wait)) {
|
if (!db.Get(ip, wait)) {
|
||||||
wait *= 1000;
|
wait *= 1000;
|
||||||
|
@ -127,29 +127,50 @@ extern "C" void* ThreadCrawler(void* data) {
|
||||||
} while(1);
|
} 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 {
|
class CDnsThread {
|
||||||
public:
|
public:
|
||||||
dns_opt_t dns_opt;
|
dns_opt_t dns_opt;
|
||||||
vector<struct in_addr> cache;
|
vector<addr_t> cache;
|
||||||
|
int nIPv4, nIPv6;
|
||||||
time_t cacheTime;
|
time_t cacheTime;
|
||||||
unsigned int cacheHits;
|
unsigned int cacheHits;
|
||||||
uint64_t dbQueries;
|
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);
|
time_t now = time(NULL);
|
||||||
cacheHits++;
|
cacheHits++;
|
||||||
if (force || cacheHits > (cache.size()*cache.size()/400) || (cacheHits*cacheHits > cache.size() / 20 && (now - cacheTime > 5))) {
|
if (force || cacheHits > (cache.size()*cache.size()/400) || (cacheHits*cacheHits > cache.size() / 20 && (now - cacheTime > 5))) {
|
||||||
set<CIP> ips;
|
set<CNetAddr> ips;
|
||||||
db.GetIPs(ips, 1000, ipv4only);
|
db.GetIPs(ips, 1000, nets);
|
||||||
dbQueries++;
|
dbQueries++;
|
||||||
cache.clear();
|
cache.clear();
|
||||||
|
nIPv4 = 0;
|
||||||
|
nIPv6 = 0;
|
||||||
cache.reserve(ips.size());
|
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 in_addr addr;
|
||||||
|
struct in6_addr addr6;
|
||||||
if ((*it).GetInAddr(&addr)) {
|
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;
|
cacheHits = 0;
|
||||||
|
@ -171,7 +192,9 @@ public:
|
||||||
cacheTime = 0;
|
cacheTime = 0;
|
||||||
cacheHits = 0;
|
cacheHits = 0;
|
||||||
dbQueries = 0;
|
dbQueries = 0;
|
||||||
cacheHit(true, true);
|
nIPv4 = 0;
|
||||||
|
nIPv6 = 0;
|
||||||
|
cacheHit(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void run() {
|
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;
|
CDnsThread *thread = (CDnsThread*)data;
|
||||||
thread->cacheHit(ipv4only);
|
thread->cacheHit();
|
||||||
unsigned int size = thread->cache.size();
|
unsigned int size = (ipv4 ? thread->nIPv4 : 0) + (ipv6 ? thread->nIPv6 : 0);
|
||||||
if (max > size)
|
if (max > size)
|
||||||
max = size;
|
max = size;
|
||||||
for (int i=0; i<max; i++) {
|
int i=0;
|
||||||
|
while (i<max) {
|
||||||
int j = i + (rand() % (size - i));
|
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];
|
addr[i] = thread->cache[j];
|
||||||
thread->cache[j] = thread->cache[i];
|
thread->cache[j] = thread->cache[i];
|
||||||
thread->cache[i] = addr[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*) {
|
extern "C" void* ThreadSeeder(void*) {
|
||||||
do {
|
do {
|
||||||
for (int i=0; i<sizeof(seeds)/sizeof(seeds[0]); i++) {
|
for (int i=0; i<sizeof(seeds)/sizeof(seeds[0]); i++) {
|
||||||
vector<CIP> ips;
|
vector<CNetAddr> ips;
|
||||||
LookupHost(seeds[i].c_str(), ips);
|
LookupHost(seeds[i].c_str(), ips);
|
||||||
for (vector<CIP>::iterator it = ips.begin(); it != ips.end(); it++) {
|
for (vector<CNetAddr>::iterator it = ips.begin(); it != ips.end(); it++) {
|
||||||
db.Add(CIPPort(*it, 8333), true);
|
db.Add(CService(*it, 8333), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Sleep(1800000);
|
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
|
// 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
|
#ifndef BITCOIN_NETBASE_H
|
||||||
#define BITCOIN_NETBASE_H
|
#define BITCOIN_NETBASE_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#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"
|
#include "serialize.h"
|
||||||
|
#include "compat.h"
|
||||||
typedef int SOCKET;
|
|
||||||
|
|
||||||
extern int nConnectTimeout;
|
extern int nConnectTimeout;
|
||||||
|
|
||||||
// IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
|
#ifdef WIN32
|
||||||
class CIP
|
// 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:
|
protected:
|
||||||
unsigned char ip[16]; // in network byte order
|
unsigned char ip[16]; // in network byte order
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CIP();
|
CNetAddr();
|
||||||
CIP(const struct in_addr& ipv4Addr);
|
CNetAddr(const struct in_addr& ipv4Addr);
|
||||||
CIP(const char *pszIp, bool fAllowLookup = false);
|
explicit CNetAddr(const char *pszIp, bool fAllowLookup = false);
|
||||||
CIP(const std::string &strIp, bool fAllowLookup = false);
|
explicit CNetAddr(const std::string &strIp, bool fAllowLookup = false);
|
||||||
void Init();
|
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 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 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 IsRFC3849() const; // IPv6 documentation address (2001:0DB8::/32)
|
||||||
bool IsRFC3927() const; // IPv4 autoconfig (169.254.0.0/16)
|
bool IsRFC3927() const; // IPv4 autoconfig (169.254.0.0/16)
|
||||||
|
@ -54,25 +57,30 @@ class CIP
|
||||||
bool IsRFC4862() const; // IPv6 autoconfig (FE80::/64)
|
bool IsRFC4862() const; // IPv6 autoconfig (FE80::/64)
|
||||||
bool IsRFC6052() const; // IPv6 well-known prefix (64:FF9B::/96)
|
bool IsRFC6052() const; // IPv6 well-known prefix (64:FF9B::/96)
|
||||||
bool IsRFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96)
|
bool IsRFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96)
|
||||||
|
bool IsTor() const;
|
||||||
|
bool IsI2P() const;
|
||||||
bool IsLocal() const;
|
bool IsLocal() const;
|
||||||
bool IsRoutable() const;
|
bool IsRoutable() const;
|
||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
bool IsMulticast() const;
|
bool IsMulticast() const;
|
||||||
|
enum Network GetNetwork() const;
|
||||||
std::string ToString() const;
|
std::string ToString() const;
|
||||||
|
std::string ToStringIP() const;
|
||||||
int GetByte(int n) const;
|
int GetByte(int n) const;
|
||||||
int64 GetHash() const;
|
int64 GetHash() const;
|
||||||
bool GetInAddr(struct in_addr* pipv4Addr) const;
|
bool GetInAddr(struct in_addr* pipv4Addr) const;
|
||||||
std::vector<unsigned char> GetGroup() const;
|
std::vector<unsigned char> GetGroup() const;
|
||||||
|
int GetReachabilityFrom(const CNetAddr *paddrPartner = NULL) const;
|
||||||
void print() const;
|
void print() const;
|
||||||
|
|
||||||
#ifdef USE_IPV6
|
#ifdef USE_IPV6
|
||||||
CIP(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
|
#endif
|
||||||
|
|
||||||
friend bool operator==(const CIP& a, const CIP& b);
|
friend bool operator==(const CNetAddr& a, const CNetAddr& b);
|
||||||
friend bool operator!=(const CIP& a, const CIP& b);
|
friend bool operator!=(const CNetAddr& a, const CNetAddr& b);
|
||||||
friend bool operator<(const CIP& a, const CIP& b);
|
friend bool operator<(const CNetAddr& a, const CNetAddr& b);
|
||||||
|
|
||||||
IMPLEMENT_SERIALIZE
|
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:
|
protected:
|
||||||
unsigned short port; // host order
|
unsigned short port; // host order
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CIPPort();
|
CService();
|
||||||
CIPPort(const CIP& ip, unsigned short port);
|
CService(const CNetAddr& ip, unsigned short port);
|
||||||
CIPPort(const struct in_addr& ipv4Addr, unsigned short port);
|
CService(const struct in_addr& ipv4Addr, unsigned short port);
|
||||||
CIPPort(const struct sockaddr_in& addr);
|
CService(const struct sockaddr_in& addr);
|
||||||
CIPPort(const char *pszIp, int port, bool fAllowLookup = false);
|
explicit CService(const char *pszIpPort, int portDefault, bool fAllowLookup = false);
|
||||||
CIPPort(const char *pszIpPort, bool fAllowLookup = false);
|
explicit CService(const char *pszIpPort, bool fAllowLookup = false);
|
||||||
CIPPort(const std::string& strIp, int port, bool fAllowLookup = false);
|
explicit CService(const std::string& strIpPort, int portDefault, bool fAllowLookup = false);
|
||||||
CIPPort(const std::string& strIpPort, bool fAllowLookup = false);
|
explicit CService(const std::string& strIpPort, bool fAllowLookup = false);
|
||||||
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 ConnectSocket(SOCKET& hSocketRet, int nTimeout = nConnectTimeout) const;
|
bool SetSockAddr(const struct sockaddr* paddr);
|
||||||
friend bool operator==(const CIPPort& a, const CIPPort& b);
|
friend bool operator==(const CService& a, const CService& b);
|
||||||
friend bool operator!=(const CIPPort& a, const CIPPort& b);
|
friend bool operator!=(const CService& a, const CService& b);
|
||||||
friend bool operator<(const CIPPort& a, const CIPPort& b);
|
friend bool operator<(const CService& a, const CService& b);
|
||||||
std::vector<unsigned char> GetKey() const;
|
std::vector<unsigned char> GetKey() const;
|
||||||
std::string ToString() const;
|
std::string ToString() const;
|
||||||
|
std::string ToStringPort() const;
|
||||||
|
std::string ToStringIPPort() const;
|
||||||
void print() const;
|
void print() const;
|
||||||
|
|
||||||
#ifdef USE_IPV6
|
#ifdef USE_IPV6
|
||||||
CIPPort(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);
|
||||||
CIPPort(const struct sockaddr_in6& addr);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
IMPLEMENT_SERIALIZE
|
IMPLEMENT_SERIALIZE
|
||||||
(
|
(
|
||||||
CIPPort* pthis = const_cast<CIPPort*>(this);
|
CService* pthis = const_cast<CService*>(this);
|
||||||
READWRITE(FLATDATA(ip));
|
READWRITE(FLATDATA(ip));
|
||||||
unsigned short portN = htons(port);
|
unsigned short portN = htons(port);
|
||||||
READWRITE(portN);
|
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);
|
enum Network ParseNetwork(std::string net);
|
||||||
bool LookupHostNumeric(const char *pszName, std::vector<CIP>& vIP, int nMaxSolutions = 0);
|
bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion = 5);
|
||||||
bool Lookup(const char *pszName, CIPPort& addr, int portDefault = 0, bool fAllowLookup = true);
|
bool GetProxy(enum Network net, CService &addrProxy);
|
||||||
bool LookupNumeric(const char *pszName, CIPPort& addr, int portDefault = 0);
|
bool IsProxy(const CNetAddr &addr);
|
||||||
|
bool SetNameProxy(CService addrProxy, int nSocksVersion = 5);
|
||||||
// Settings
|
bool GetNameProxy();
|
||||||
extern int fUseProxy;
|
bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions = 0, bool fAllowLookup = true);
|
||||||
extern CIPPort addrProxy;
|
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
|
#endif
|
||||||
|
|
|
@ -81,12 +81,12 @@ bool CMessageHeader::IsValid() const
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CAddress::CAddress() : CIPPort()
|
CAddress::CAddress() : CService()
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
CAddress::CAddress(CIPPort ipIn, uint64 nServicesIn) : CIPPort(ipIn)
|
CAddress::CAddress(CService ipIn, uint64 nServicesIn) : CService(ipIn)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
nServices = nServicesIn;
|
nServices = nServicesIn;
|
||||||
|
|
|
@ -62,18 +62,18 @@ enum
|
||||||
NODE_NETWORK = (1 << 0),
|
NODE_NETWORK = (1 << 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
class CAddress : public CIPPort
|
class CAddress : public CService
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CAddress();
|
CAddress();
|
||||||
CAddress(CIPPort ipIn, uint64 nServicesIn=NODE_NETWORK);
|
CAddress(CService ipIn, uint64 nServicesIn=NODE_NETWORK);
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
IMPLEMENT_SERIALIZE
|
IMPLEMENT_SERIALIZE
|
||||||
(
|
(
|
||||||
CAddress* pthis = const_cast<CAddress*>(this);
|
CAddress* pthis = const_cast<CAddress*>(this);
|
||||||
CIPPort* pip = (CIPPort*)pthis;
|
CService* pip = (CService*)pthis;
|
||||||
if (fRead)
|
if (fRead)
|
||||||
pthis->Init();
|
pthis->Init();
|
||||||
if (nType & SER_DISK)
|
if (nType & SER_DISK)
|
||||||
|
|
6
test.pl
6
test.pl
|
@ -17,8 +17,8 @@ sub go {
|
||||||
|
|
||||||
my $sock = IO::Socket::INET->new(
|
my $sock = IO::Socket::INET->new(
|
||||||
Proto => 'udp',
|
Proto => 'udp',
|
||||||
PeerPort => 5353,
|
PeerPort => 53,
|
||||||
PeerAddr => "127.0.0.1",
|
PeerAddr => "vps.sipa.be",
|
||||||
) or die "Could not create socket: $!\n";
|
) or die "Could not create socket: $!\n";
|
||||||
|
|
||||||
while($run) {
|
while($run) {
|
||||||
|
@ -52,7 +52,7 @@ sub go {
|
||||||
|
|
||||||
my @threads;
|
my @threads;
|
||||||
|
|
||||||
for my $i (0..3) {
|
for my $i (0..500) {
|
||||||
$threads[$i] = threads->create(\&go, $i);
|
$threads[$i] = threads->create(\&go, $i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
44
util.h
44
util.h
|
@ -4,6 +4,7 @@
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
|
|
||||||
|
@ -26,21 +27,6 @@
|
||||||
#define INVALID_SOCKET (SOCKET)(~0)
|
#define INVALID_SOCKET (SOCKET)(~0)
|
||||||
#define SOCKET_ERROR -1
|
#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
|
// Wrapper to automatically initialize mutex
|
||||||
class CCriticalSection
|
class CCriticalSection
|
||||||
{
|
{
|
||||||
|
@ -87,10 +73,30 @@ template<typename T1> inline uint256 Hash(const T1 pbegin, const T1 pend)
|
||||||
}
|
}
|
||||||
|
|
||||||
void static inline Sleep(int nMilliSec) {
|
void static inline Sleep(int nMilliSec) {
|
||||||
struct timespec wa;
|
struct timespec wa;
|
||||||
wa.tv_sec = nMilliSec/1000;
|
wa.tv_sec = nMilliSec/1000;
|
||||||
wa.tv_nsec = (nMilliSec % 1000) * 1000000;
|
wa.tv_nsec = (nMilliSec % 1000) * 1000000;
|
||||||
nanosleep(&wa, NULL);
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue