working
This commit is contained in:
parent
adc55f0b36
commit
c4cc50a155
13 changed files with 483 additions and 72 deletions
6
Makefile
Normal file
6
Makefile
Normal file
|
@ -0,0 +1,6 @@
|
|||
dnsseed: dns.o bitcoin.cpp netbase.cpp protocol.cpp db.cpp main.cpp bitcoin.h netbase.h protocol.h db.h serialize.h uint256.h util.h
|
||||
g++ -pthread -lssl -O3 -ggdb3 -march=nocona -Wno-invalid-offsetof -o dnsseed bitcoin.cpp netbase.cpp protocol.cpp db.cpp main.cpp dns.o
|
||||
|
||||
dns.o: dns.c
|
||||
gcc -std=c99 -O3 -g0 -march=nocona dns.c -c -o dns.o
|
||||
|
285
bitcoin.cpp
Normal file
285
bitcoin.cpp
Normal file
|
@ -0,0 +1,285 @@
|
|||
#include <algorithm>
|
||||
|
||||
#include "db.h"
|
||||
#include "netbase.h"
|
||||
#include "protocol.h"
|
||||
#include "serialize.h"
|
||||
#include "uint256.h"
|
||||
|
||||
#define BITCOIN_SEED_NONCE 0x0539a019ca550825
|
||||
#define REQUIRE_HEIGHT 140700
|
||||
#define MIN_VERSION 40000
|
||||
|
||||
using namespace std;
|
||||
|
||||
class CNode {
|
||||
SOCKET sock;
|
||||
CDataStream vSend;
|
||||
CDataStream vRecv;
|
||||
unsigned int nHeaderStart;
|
||||
unsigned int nMessageStart;
|
||||
int nVersion;
|
||||
int nRecvVersion;
|
||||
string strSubVer;
|
||||
int nStartingHeight;
|
||||
vector<CAddress> *vAddr;
|
||||
int ban;
|
||||
int64 doneAfter;
|
||||
CAddress you;
|
||||
|
||||
void BeginMessage(const char *pszCommand) {
|
||||
if (nHeaderStart != -1) AbortMessage();
|
||||
nHeaderStart = vSend.size();
|
||||
vSend << CMessageHeader(pszCommand, 0);
|
||||
nMessageStart = vSend.size();
|
||||
printf("%s: SEND %s\n", you.ToString().c_str(), pszCommand);
|
||||
}
|
||||
|
||||
void AbortMessage() {
|
||||
if (nHeaderStart == -1) return;
|
||||
vSend.resize(nHeaderStart);
|
||||
nHeaderStart = -1;
|
||||
nMessageStart = -1;
|
||||
}
|
||||
|
||||
void EndMessage() {
|
||||
if (nHeaderStart == -1) return;
|
||||
unsigned int nSize = vSend.size() - nMessageStart;
|
||||
memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize));
|
||||
if (vSend.GetVersion() >= 209) {
|
||||
uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end());
|
||||
unsigned int nChecksum = 0;
|
||||
memcpy(&nChecksum, &hash, sizeof(nChecksum));
|
||||
assert(nMessageStart - nHeaderStart >= offsetof(CMessageHeader, nChecksum) + sizeof(nChecksum));
|
||||
memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nChecksum), &nChecksum, sizeof(nChecksum));
|
||||
}
|
||||
nHeaderStart = -1;
|
||||
nMessageStart = -1;
|
||||
}
|
||||
|
||||
void Send() {
|
||||
if (sock == INVALID_SOCKET) return;
|
||||
if (vSend.empty()) return;
|
||||
int nBytes = send(sock, &vSend[0], vSend.size(), 0);
|
||||
if (nBytes > 0) {
|
||||
vSend.erase(vSend.begin(), vSend.begin() + nBytes);
|
||||
} else {
|
||||
close(sock);
|
||||
sock = INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
void PushVersion() {
|
||||
int64 nTime = time(NULL);
|
||||
uint64 nLocalNonce = BITCOIN_SEED_NONCE;
|
||||
int64 nLocalServices = 0;
|
||||
CAddress me(CIPPort("0.0.0.0"));
|
||||
BeginMessage("version");
|
||||
int nBestHeight = REQUIRE_HEIGHT;
|
||||
string ver = "/bitcoin-seeder:0.01/";
|
||||
vSend << PROTOCOL_VERSION << nLocalServices << nTime << you << me << nLocalNonce << ver << nBestHeight;
|
||||
EndMessage();
|
||||
}
|
||||
|
||||
void GotVersion() {
|
||||
if (nVersion < MIN_VERSION) {
|
||||
printf("%s: BAD (version %i is below %i)\n", you.ToString().c_str(), nVersion, MIN_VERSION);
|
||||
ban = 1000000;
|
||||
return;
|
||||
}
|
||||
printf("%s: version %i\n", you.ToString().c_str(), nVersion);
|
||||
BeginMessage("getaddr");
|
||||
EndMessage();
|
||||
doneAfter = time(NULL) + 10;
|
||||
}
|
||||
|
||||
bool ProcessMessage(string strCommand, CDataStream& vRecv) {
|
||||
printf("%s: RECV %s\n", you.ToString().c_str(), strCommand.c_str());
|
||||
if (strCommand == "version") {
|
||||
int64 nTime;
|
||||
CAddress addrMe;
|
||||
CAddress addrFrom;
|
||||
uint64 nNonce = 1;
|
||||
vRecv >> nVersion >> you.nServices >> nTime >> addrMe;
|
||||
if (nVersion == 10300) nVersion = 300;
|
||||
if (nVersion >= 106 && !vRecv.empty())
|
||||
vRecv >> addrFrom >> nNonce;
|
||||
if (nVersion >= 106 && !vRecv.empty())
|
||||
vRecv >> strSubVer;
|
||||
if (nVersion >= 209 && !vRecv.empty())
|
||||
vRecv >> nStartingHeight;
|
||||
|
||||
if (!(you.nServices & NODE_NETWORK)) {
|
||||
printf("%s: BAD (no NODE_NETWORK)\n", you.ToString().c_str());
|
||||
ban = 1000000;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (nVersion >= 209) {
|
||||
BeginMessage("verack");
|
||||
EndMessage();
|
||||
}
|
||||
vSend.SetVersion(min(nVersion, PROTOCOL_VERSION));
|
||||
if (nVersion < 209) {
|
||||
this->vRecv.SetVersion(min(nVersion, PROTOCOL_VERSION));
|
||||
GotVersion();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strCommand == "verack") {
|
||||
this->vRecv.SetVersion(min(nVersion, PROTOCOL_VERSION));
|
||||
GotVersion();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strCommand == "addr") {
|
||||
vector<CAddress> vAddrNew;
|
||||
vRecv >> vAddrNew;
|
||||
printf("%s: got %i addresses\n", you.ToString().c_str(), (int)vAddrNew.size());
|
||||
int64 now = time(NULL);
|
||||
vector<CAddress>::iterator it = vAddrNew.begin();
|
||||
if (doneAfter == 0 || doneAfter > now + 1) doneAfter = now + 1;
|
||||
while (it != vAddrNew.end()) {
|
||||
CAddress &addr = *it;
|
||||
// printf("%s: got address %s\n", you.ToString().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);
|
||||
// printf("%s: added address %s (#%i)\n", you.ToString().c_str(), addr.ToString().c_str(), (int)(vAddr->size()));
|
||||
if (vAddr->size() > 1000) {doneAfter = 1; return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProcessMessages() {
|
||||
if (vRecv.empty()) return false;
|
||||
do {
|
||||
CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart), END(pchMessageStart));
|
||||
int nHeaderSize = vRecv.GetSerializeSize(CMessageHeader());
|
||||
if (vRecv.end() - pstart < nHeaderSize) {
|
||||
if (vRecv.size() > nHeaderSize) {
|
||||
vRecv.erase(vRecv.begin(), vRecv.end() - nHeaderSize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
vRecv.erase(vRecv.begin(), pstart);
|
||||
vector<char> vHeaderSave(vRecv.begin(), vRecv.begin() + nHeaderSize);
|
||||
CMessageHeader hdr;
|
||||
vRecv >> hdr;
|
||||
if (!hdr.IsValid()) {
|
||||
printf("%s: BAD (invalid header)\n", you.ToString().c_str());
|
||||
ban = 100000; return true;
|
||||
}
|
||||
string strCommand = hdr.GetCommand();
|
||||
unsigned int nMessageSize = hdr.nMessageSize;
|
||||
if (nMessageSize > MAX_SIZE) {
|
||||
printf("%s: BAD (message too large)\n", you.ToString().c_str());
|
||||
ban = 100000;
|
||||
return true;
|
||||
}
|
||||
if (nMessageSize > vRecv.size()) {
|
||||
vRecv.insert(vRecv.begin(), vHeaderSave.begin(), vHeaderSave.end());
|
||||
break;
|
||||
}
|
||||
if (vRecv.GetVersion() >= 209) {
|
||||
uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
|
||||
unsigned int nChecksum = 0;
|
||||
memcpy(&nChecksum, &hash, sizeof(nChecksum));
|
||||
if (nChecksum != hdr.nChecksum) continue;
|
||||
}
|
||||
CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion);
|
||||
vRecv.ignore(nMessageSize);
|
||||
if (ProcessMessage(strCommand, vMsg))
|
||||
return true;
|
||||
printf("%s: done processing %s\n", you.ToString().c_str(), strCommand.c_str());
|
||||
} while(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
CNode(const CIPPort& ip, vector<CAddress>& vAddrIn) : you(ip), nHeaderStart(-1), nMessageStart(-1), vAddr(&vAddrIn) {
|
||||
vSend.SetType(SER_NETWORK);
|
||||
vSend.SetVersion(0);
|
||||
vRecv.SetType(SER_NETWORK);
|
||||
vRecv.SetVersion(0);
|
||||
if (time(NULL) > 1329696000) {
|
||||
vSend.SetVersion(209);
|
||||
vRecv.SetVersion(209);
|
||||
}
|
||||
}
|
||||
bool Run() {
|
||||
bool res = true;
|
||||
if (!you.ConnectSocket(sock)) return false;
|
||||
PushVersion();
|
||||
Send();
|
||||
int64 now;
|
||||
while (now = time(NULL), ban == 0 && (doneAfter == 0 || doneAfter > now) && sock != INVALID_SOCKET) {
|
||||
char pchBuf[0x10000];
|
||||
fd_set set;
|
||||
FD_ZERO(&set);
|
||||
FD_SET(sock,&set);
|
||||
struct timeval wa;
|
||||
if (doneAfter) {
|
||||
wa.tv_sec = doneAfter - now;
|
||||
wa.tv_usec = 0;
|
||||
} else {
|
||||
wa.tv_sec = 10;
|
||||
wa.tv_usec = 0;
|
||||
}
|
||||
int ret = select(sock+1, &set, NULL, &set, &wa);
|
||||
if (ret != 1) {
|
||||
if (!doneAfter) res = false;
|
||||
break;
|
||||
}
|
||||
int nBytes = recv(sock, pchBuf, sizeof(pchBuf), 0);
|
||||
int nPos = vRecv.size();
|
||||
if (nBytes > 0) {
|
||||
vRecv.resize(nPos + nBytes);
|
||||
memcpy(&vRecv[nPos], pchBuf, nBytes);
|
||||
} else if (nBytes == 0) {
|
||||
Sleep(127);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
ProcessMessages();
|
||||
Send();
|
||||
}
|
||||
close(sock);
|
||||
sock = INVALID_SOCKET;
|
||||
return (ban == 0) && res;
|
||||
}
|
||||
|
||||
int GetBan() {
|
||||
return ban;
|
||||
}
|
||||
};
|
||||
|
||||
bool TestNode(const CIPPort &cip, int &ban, vector<CAddress>& vAddr) {
|
||||
CNode node(cip, vAddr);
|
||||
bool ret = node.Run();
|
||||
if (!ret) {
|
||||
ban = node.GetBan();
|
||||
} else {
|
||||
ban = 0;
|
||||
}
|
||||
printf("%s: %s!!!\n", cip.ToString().c_str(), ret ? "GOOD" : "BAD");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
int main(void) {
|
||||
CIPPort ip("bitcoin.sipa.be", 8333, true);
|
||||
vector<CAddress> vAddr;
|
||||
vAddr.clear();
|
||||
int ban = 0;
|
||||
bool ret = TestNode(ip, ban, vAddr);
|
||||
printf("ret=%s ban=%i vAddr.size()=%i\n", ret ? "good" : "bad", ban, (int)vAddr.size());
|
||||
}
|
||||
*/
|
8
bitcoin.h
Normal file
8
bitcoin.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef _BITCOIN_H_
|
||||
#define _BITCOIN_H_ 1
|
||||
|
||||
#include "protocol.h"
|
||||
|
||||
bool TestNode(const CIPPort &cip, int &ban, std::vector<CAddress>& vAddr);
|
||||
|
||||
#endif
|
41
db.cpp
41
db.cpp
|
@ -18,17 +18,30 @@ void CAddrInfo::Update(bool good) {
|
|||
}
|
||||
|
||||
bool CAddrDb::Get_(CIPPort &ip) {
|
||||
int tot = unkId.size() + ourId.size();
|
||||
if (tot == 0) return false;
|
||||
int rnd = rand() % tot;
|
||||
if (tot < unkId.size()) {
|
||||
set<int>::iterator it = unkId.begin();
|
||||
return *it;
|
||||
} else {
|
||||
int ret = ourId.front();
|
||||
ourId.pop_front();
|
||||
return ret;
|
||||
}
|
||||
int cont = 0;
|
||||
do {
|
||||
cont = 0;
|
||||
int tot = unkId.size() + ourId.size();
|
||||
if (tot == 0) return false;
|
||||
int rnd = rand() % tot;
|
||||
if (rnd < unkId.size()) {
|
||||
set<int>::iterator it = unkId.begin();
|
||||
ip = idToInfo[*it].ip;
|
||||
unkId.erase(it);
|
||||
printf("From UNK: %s\n", ip.ToString().c_str());
|
||||
} else {
|
||||
int ret = ourId.front();
|
||||
ourId.pop_front();
|
||||
if (unkId.size() > 0 && time(NULL) - idToInfo[ret].ourLastTry < MIN_RETRY) {
|
||||
ourId.push_back(ret);
|
||||
cont=1;
|
||||
continue;
|
||||
}
|
||||
ip = idToInfo[ret].ip;
|
||||
printf("From OUR: %s (size = %i)\n", ip.ToString().c_str(), (int)ourId.size());
|
||||
}
|
||||
} while(cont);
|
||||
return true;
|
||||
}
|
||||
|
||||
int CAddrDb::Lookup_(const CIPPort &ip) {
|
||||
|
@ -38,7 +51,9 @@ int CAddrDb::Lookup_(const CIPPort &ip) {
|
|||
}
|
||||
|
||||
void CAddrDb::Good_(const CIPPort &addr) {
|
||||
printf("%s: good!\n", addr.ToString().c_str());
|
||||
int id = Lookup_(addr);
|
||||
printf("%s: good (id=%i)!\n", addr.ToString().c_str(), id);
|
||||
if (id == -1) return;
|
||||
unkId.erase(id);
|
||||
banned.erase(addr);
|
||||
|
@ -94,7 +109,7 @@ void CAddrDb::Add_(const CAddress &addr) {
|
|||
CIPPort ipp(addr);
|
||||
if (banned.count(ipp)) {
|
||||
time_t bantime = banned[ipp];
|
||||
if (bantime < time(NULL))
|
||||
if (bantime < time(NULL) && addr.nTime > bantime)
|
||||
banned.erase(ipp);
|
||||
else
|
||||
return;
|
||||
|
@ -119,8 +134,8 @@ void CAddrDb::Add_(const CAddress &addr) {
|
|||
int id = nId++;
|
||||
idToInfo[id] = ai;
|
||||
ipToId[ipp] = id;
|
||||
printf("%s: added as id %i\n", ipp.ToString().c_str(), ipToId[ipp]);
|
||||
unkId.insert(id);
|
||||
printf("%s: added\n", addr.ToString().c_str());
|
||||
}
|
||||
|
||||
void CAddrDb::GetIPs_(set<CIP>& ips, int max, bool fOnlyIPv4) {
|
||||
|
|
7
db.h
7
db.h
|
@ -11,6 +11,7 @@
|
|||
#include "util.h"
|
||||
|
||||
#define TAU 86400.0
|
||||
#define MIN_RETRY 1000
|
||||
|
||||
class CAddrInfo {
|
||||
private:
|
||||
|
@ -26,7 +27,7 @@ private:
|
|||
int success;
|
||||
public:
|
||||
bool IsGood() {
|
||||
return (weight > 0.5 & reliability/weight > 0.8 && timing/weight < 86400 && count/weight > 1.0) && ip.GetPort() == 8333;
|
||||
return (weight > 0 && reliability/weight > 0.8 && timing/weight < 86400) && ip.GetPort() == 8333;
|
||||
}
|
||||
bool IsTerrible() {
|
||||
return (weight > 0.5 & reliability/weight < 0.2 && timing/weight < 86400 && count/weight > 2.0);
|
||||
|
@ -65,6 +66,10 @@ protected:
|
|||
void GetIPs_(std::set<CIP>& ips, int max, bool fOnlyIPv4);
|
||||
|
||||
public:
|
||||
void Stats() {
|
||||
CRITICAL_BLOCK(cs)
|
||||
printf("**** %i good, %lu our, %i unk, %i banned; %i known ips\n", (int)goodId.size(), (unsigned long)ourId.size(), (int)unkId.size(), (int)banned.size(), (int)ipToId.size());
|
||||
}
|
||||
void Add(const CAddress &addr) {
|
||||
CRITICAL_BLOCK(cs)
|
||||
Add_(addr);
|
||||
|
|
19
dns.c
19
dns.c
|
@ -18,6 +18,8 @@ char *host = "seedtest.bitcoin.sipa.be";
|
|||
char *ns = "vps.sipa.be";
|
||||
char *mbox = "sipa.ulyssis.org";
|
||||
|
||||
extern int GetIPList(struct in_addr *addr, int max, int ipv4only);
|
||||
|
||||
typedef enum {
|
||||
CLASS_IN = 1,
|
||||
QCLASS_ANY = 255
|
||||
|
@ -300,16 +302,18 @@ ssize_t static dnshandle(const unsigned char *inbuf, size_t insize, unsigned cha
|
|||
|
||||
// A records
|
||||
if ((typ == TYPE_A || typ == QTYPE_ANY) && (cls == CLASS_IN || cls == QCLASS_ANY)) {
|
||||
uint32_t ip = 0x01101102;
|
||||
do {
|
||||
int ret = write_record_a(&outpos, outend - auth_size, "", offset, CLASS_IN, datattl, (const struct in_addr*)(&ip));
|
||||
struct in_addr addr[20];
|
||||
int naddr = GetIPList(addr, 20, 1);
|
||||
int n = 0;
|
||||
while (n < naddr) {
|
||||
int ret = write_record_a(&outpos, outend - auth_size, "", offset, CLASS_IN, datattl, &addr[n]);
|
||||
// printf("wrote A record: %i\n", ret);
|
||||
if (!ret) {
|
||||
ip += 0x01101102;
|
||||
n++;
|
||||
outbuf[7]++;
|
||||
} else
|
||||
break;
|
||||
} while(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Authority section
|
||||
|
@ -360,8 +364,3 @@ int dnsserver(void) {
|
|||
} while(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
dnsserver();
|
||||
return 0;
|
||||
}
|
||||
|
|
69
main.cpp
Normal file
69
main.cpp
Normal file
|
@ -0,0 +1,69 @@
|
|||
#include <pthread.h>
|
||||
|
||||
#include "bitcoin.h"
|
||||
#include "db.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern "C" {
|
||||
// #include "dns.h"
|
||||
}
|
||||
|
||||
CAddrDb db;
|
||||
|
||||
extern "C" void* ThreadCrawler(void* data) {
|
||||
do {
|
||||
db.Stats();
|
||||
CIPPort ip;
|
||||
if (!db.Get(ip)) {
|
||||
Sleep(5000);
|
||||
continue;
|
||||
}
|
||||
int ban = 0;
|
||||
vector<CAddress> addr;
|
||||
bool ret = TestNode(ip,ban,addr);
|
||||
db.Add(addr);
|
||||
if (ret) {
|
||||
db.Good(ip);
|
||||
} else {
|
||||
db.Bad(ip, ban);
|
||||
}
|
||||
} while(1);
|
||||
}
|
||||
|
||||
extern "C" int GetIPList(struct in_addr *addr, int max, int ipv4only) {
|
||||
set<CIP> ips;
|
||||
db.GetIPs(ips, max, ipv4only);
|
||||
int n = 0;
|
||||
for (set<CIP>::iterator it = ips.begin(); it != ips.end(); it++) {
|
||||
if ((*it).GetInAddr(&addr[n]))
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
extern "C" int dnsserver(void);
|
||||
|
||||
extern "C" void* ThreadDNS(void*) {
|
||||
dnsserver();
|
||||
}
|
||||
|
||||
#define NTHREADS 100
|
||||
|
||||
int main(void) {
|
||||
vector<CIP> ips;
|
||||
LookupHost("dnsseed.bluematt.me", ips);
|
||||
for (vector<CIP>::iterator it = ips.begin(); it != ips.end(); it++) {
|
||||
db.Add(CIPPort(*it, 8333));
|
||||
}
|
||||
pthread_t thread[NTHREADS];
|
||||
for (int i=0; i<NTHREADS-1; i++) {
|
||||
pthread_create(&thread[i], NULL, ThreadCrawler, NULL);
|
||||
}
|
||||
pthread_create(&thread[NTHREADS-1], NULL, ThreadDNS, NULL);
|
||||
for (int i=0; i<NTHREADS; i++) {
|
||||
void* res;
|
||||
pthread_join(thread[i], &res);
|
||||
}
|
||||
return 0;
|
||||
}
|
14
netbase.cpp
14
netbase.cpp
|
@ -177,7 +177,11 @@ bool CIPPort::ConnectSocket(SOCKET& hSocketRet, int nTimeout) const
|
|||
|
||||
SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (hSocket == INVALID_SOCKET)
|
||||
{
|
||||
printf("Failed to create socket: %s\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef SO_NOSIGPIPE
|
||||
int set = 1;
|
||||
setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
|
||||
|
@ -194,8 +198,8 @@ bool CIPPort::ConnectSocket(SOCKET& hSocketRet, int nTimeout) const
|
|||
if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
|
||||
#endif
|
||||
{
|
||||
printf("Failed to set socket NONBLOCK\n");
|
||||
closesocket(hSocket);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -265,10 +269,12 @@ bool CIPPort::ConnectSocket(SOCKET& hSocketRet, int nTimeout) const
|
|||
if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
|
||||
#endif
|
||||
{
|
||||
printf("Failed to set socket blocking\n");
|
||||
closesocket(hSocket);
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("%s: connected\n", ToString().c_str());
|
||||
hSocketRet = hSocket;
|
||||
return true;
|
||||
}
|
||||
|
@ -463,12 +469,12 @@ bool operator==(const CIP& a, const CIP& b)
|
|||
|
||||
bool operator!=(const CIP& a, const CIP& b)
|
||||
{
|
||||
return (memcmp(a.ip, b.ip, 16) == 0);
|
||||
return (memcmp(a.ip, b.ip, 16) != 0);
|
||||
}
|
||||
|
||||
bool operator<(const CIP& a, const CIP& b)
|
||||
{
|
||||
return (memcmp(a.ip, b.ip, 16) <= 0);
|
||||
return (memcmp(a.ip, b.ip, 16) < 0);
|
||||
}
|
||||
|
||||
bool CIP::GetInAddr(struct in_addr* pipv4Addr) const
|
||||
|
@ -652,7 +658,7 @@ bool operator!=(const CIPPort& a, const CIPPort& b)
|
|||
|
||||
bool operator<(const CIPPort& a, const CIPPort& b)
|
||||
{
|
||||
return (operator<((CIP)a, (CIP)b) || a.port < b.port);
|
||||
return (operator<((CIP)a, (CIP)b) || (operator==((CIP)a, (CIP)b) && (a.port < b.port)));
|
||||
}
|
||||
|
||||
bool CIPPort::GetSockAddr(struct sockaddr_in* paddr) const
|
||||
|
|
|
@ -86,7 +86,7 @@ CAddress::CAddress() : CIPPort()
|
|||
Init();
|
||||
}
|
||||
|
||||
CAddress::CAddress(CIPPort &ipIn, uint64 nServicesIn) : CIPPort(ipIn)
|
||||
CAddress::CAddress(CIPPort ipIn, uint64 nServicesIn) : CIPPort(ipIn)
|
||||
{
|
||||
Init();
|
||||
nServices = nServicesIn;
|
||||
|
|
|
@ -66,7 +66,7 @@ class CAddress : public CIPPort
|
|||
{
|
||||
public:
|
||||
CAddress();
|
||||
CAddress(CIPPort& ipIn, uint64 nServicesIn=NODE_NETWORK);
|
||||
CAddress(CIPPort ipIn, uint64 nServicesIn=NODE_NETWORK);
|
||||
|
||||
void Init();
|
||||
|
||||
|
|
76
serialize.h
76
serialize.h
|
@ -60,9 +60,7 @@ class CDataStream;
|
|||
class CAutoFile;
|
||||
static const unsigned int MAX_SIZE = 0x02000000;
|
||||
|
||||
static const int VERSION = 50100;
|
||||
static const char* pszSubVer = "";
|
||||
static const bool VERSION_IS_BETA = true;
|
||||
static const int PROTOCOL_VERSION = 60000;
|
||||
|
||||
// Used to bypass the rule against non-const reference to temporary
|
||||
// where it makes sense with wrappers such as CFlatData or CTxDB
|
||||
|
@ -91,7 +89,7 @@ enum
|
|||
};
|
||||
|
||||
#define IMPLEMENT_SERIALIZE(statements) \
|
||||
unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const \
|
||||
unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const \
|
||||
{ \
|
||||
CSerActionGetSerializeSize ser_action; \
|
||||
const bool fGetSize = true; \
|
||||
|
@ -105,7 +103,7 @@ enum
|
|||
return nSerSize; \
|
||||
} \
|
||||
template<typename Stream> \
|
||||
void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const \
|
||||
void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const \
|
||||
{ \
|
||||
CSerActionSerialize ser_action; \
|
||||
const bool fGetSize = false; \
|
||||
|
@ -115,7 +113,7 @@ enum
|
|||
{statements} \
|
||||
} \
|
||||
template<typename Stream> \
|
||||
void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) \
|
||||
void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) \
|
||||
{ \
|
||||
CSerActionUnserialize ser_action; \
|
||||
const bool fGetSize = false; \
|
||||
|
@ -362,43 +360,43 @@ template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_st
|
|||
// vector
|
||||
template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
|
||||
template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
|
||||
template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion=VERSION);
|
||||
template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
|
||||
template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
|
||||
template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion=VERSION);
|
||||
template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
|
||||
template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
|
||||
template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion=VERSION);
|
||||
template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
|
||||
// others derived from vector
|
||||
extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=VERSION);
|
||||
template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion=VERSION);
|
||||
template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion=VERSION);
|
||||
extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
|
||||
// pair
|
||||
template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion=VERSION);
|
||||
template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion=VERSION);
|
||||
template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion=VERSION);
|
||||
template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
|
||||
// 3 tuple
|
||||
template<typename T0, typename T1, typename T2> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion=VERSION);
|
||||
template<typename Stream, typename T0, typename T1, typename T2> void Serialize(Stream& os, const boost::tuple<T0, T1, T2>& item, int nType, int nVersion=VERSION);
|
||||
template<typename Stream, typename T0, typename T1, typename T2> void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion=VERSION);
|
||||
template<typename T0, typename T1, typename T2> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
template<typename Stream, typename T0, typename T1, typename T2> void Serialize(Stream& os, const boost::tuple<T0, T1, T2>& item, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
template<typename Stream, typename T0, typename T1, typename T2> void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
|
||||
// 4 tuple
|
||||
template<typename T0, typename T1, typename T2, typename T3> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=VERSION);
|
||||
template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Serialize(Stream& os, const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=VERSION);
|
||||
template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Unserialize(Stream& is, boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=VERSION);
|
||||
template<typename T0, typename T1, typename T2, typename T3> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Serialize(Stream& os, const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Unserialize(Stream& is, boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
|
||||
// map
|
||||
template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION);
|
||||
template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION);
|
||||
template<typename Stream, typename K, typename T, typename Pred, typename A> void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION);
|
||||
template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
template<typename Stream, typename K, typename T, typename Pred, typename A> void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
|
||||
// set
|
||||
template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
|
||||
template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
|
||||
template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
|
||||
template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion=PROTOCOL_VERSION);
|
||||
|
||||
|
||||
|
||||
|
@ -411,19 +409,19 @@ template<typename Stream, typename K, typename Pred, typename A> void Unserializ
|
|||
// Thanks to Boost serialization for this idea.
|
||||
//
|
||||
template<typename T>
|
||||
inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion=VERSION)
|
||||
inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion=PROTOCOL_VERSION)
|
||||
{
|
||||
return a.GetSerializeSize((int)nType, nVersion);
|
||||
}
|
||||
|
||||
template<typename Stream, typename T>
|
||||
inline void Serialize(Stream& os, const T& a, long nType, int nVersion=VERSION)
|
||||
inline void Serialize(Stream& os, const T& a, long nType, int nVersion=PROTOCOL_VERSION)
|
||||
{
|
||||
a.Serialize(os, (int)nType, nVersion);
|
||||
}
|
||||
|
||||
template<typename Stream, typename T>
|
||||
inline void Unserialize(Stream& is, T& a, long nType, int nVersion=VERSION)
|
||||
inline void Unserialize(Stream& is, T& a, long nType, int nVersion=PROTOCOL_VERSION)
|
||||
{
|
||||
a.Unserialize(is, (int)nType, nVersion);
|
||||
}
|
||||
|
@ -857,39 +855,39 @@ public:
|
|||
typedef vector_type::const_iterator const_iterator;
|
||||
typedef vector_type::reverse_iterator reverse_iterator;
|
||||
|
||||
explicit CDataStream(int nTypeIn=SER_NETWORK, int nVersionIn=VERSION)
|
||||
explicit CDataStream(int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION)
|
||||
{
|
||||
Init(nTypeIn, nVersionIn);
|
||||
}
|
||||
|
||||
CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(pbegin, pend)
|
||||
CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(pbegin, pend)
|
||||
{
|
||||
Init(nTypeIn, nVersionIn);
|
||||
}
|
||||
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1300
|
||||
CDataStream(const char* pbegin, const char* pend, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(pbegin, pend)
|
||||
CDataStream(const char* pbegin, const char* pend, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(pbegin, pend)
|
||||
{
|
||||
Init(nTypeIn, nVersionIn);
|
||||
}
|
||||
#endif
|
||||
|
||||
CDataStream(const vector_type& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())
|
||||
CDataStream(const vector_type& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(vchIn.begin(), vchIn.end())
|
||||
{
|
||||
Init(nTypeIn, nVersionIn);
|
||||
}
|
||||
|
||||
CDataStream(const std::vector<char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())
|
||||
CDataStream(const std::vector<char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(vchIn.begin(), vchIn.end())
|
||||
{
|
||||
Init(nTypeIn, nVersionIn);
|
||||
}
|
||||
|
||||
CDataStream(const std::vector<unsigned char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0])
|
||||
CDataStream(const std::vector<unsigned char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0])
|
||||
{
|
||||
Init(nTypeIn, nVersionIn);
|
||||
}
|
||||
|
||||
void Init(int nTypeIn=SER_NETWORK, int nVersionIn=VERSION)
|
||||
void Init(int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION)
|
||||
{
|
||||
nReadPos = 0;
|
||||
nType = nTypeIn;
|
||||
|
@ -1103,7 +1101,7 @@ public:
|
|||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
|
||||
void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const
|
||||
{
|
||||
// Special case: stream << stream concatenates like stream += stream
|
||||
if (!vch.empty())
|
||||
|
@ -1212,7 +1210,7 @@ public:
|
|||
|
||||
typedef FILE element_type;
|
||||
|
||||
CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=VERSION)
|
||||
CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=PROTOCOL_VERSION)
|
||||
{
|
||||
file = filenew;
|
||||
nType = nTypeIn;
|
||||
|
|
|
@ -364,19 +364,19 @@ public:
|
|||
}
|
||||
|
||||
|
||||
unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const
|
||||
unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const
|
||||
{
|
||||
return sizeof(pn);
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
|
||||
void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const
|
||||
{
|
||||
s.write((char*)pn, sizeof(pn));
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)
|
||||
void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION)
|
||||
{
|
||||
s.read((char*)pn, sizeof(pn));
|
||||
}
|
||||
|
|
20
util.h
20
util.h
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "uint256.h"
|
||||
|
||||
#define loop for (;;)
|
||||
#define BEGIN(a) ((char*)&(a))
|
||||
|
@ -64,4 +67,21 @@ public:
|
|||
#define CRITICAL_BLOCK(cs) \
|
||||
if (CCriticalBlock criticalblock = CCriticalBlock(cs))
|
||||
|
||||
template<typename T1> inline uint256 Hash(const T1 pbegin, const T1 pend)
|
||||
{
|
||||
static unsigned char pblank[1];
|
||||
uint256 hash1;
|
||||
SHA256((pbegin == pend ? pblank : (unsigned char*)&pbegin[0]), (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1);
|
||||
uint256 hash2;
|
||||
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
|
||||
return hash2;
|
||||
}
|
||||
|
||||
void static inline Sleep(int nMilliSec) {
|
||||
struct timespec wa;
|
||||
wa.tv_sec = nMilliSec/1000;
|
||||
wa.tv_nsec = (nMilliSec % 1000) * 1000000;
|
||||
nanosleep(&wa, NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue