Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

working

  • Loading branch information...
commit c4cc50a1554cd4d1ecb3503814c78c7336680841 1 parent adc55f0
Pieter Wuille authored December 20, 2011
6  Makefile
... ...
@@ -0,0 +1,6 @@
  1
+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
  2
+	g++ -pthread -lssl -O3 -ggdb3 -march=nocona -Wno-invalid-offsetof -o dnsseed bitcoin.cpp netbase.cpp protocol.cpp db.cpp main.cpp dns.o
  3
+
  4
+dns.o: dns.c
  5
+	gcc -std=c99 -O3 -g0 -march=nocona dns.c -c -o dns.o
  6
+
285  bitcoin.cpp
... ...
@@ -0,0 +1,285 @@
  1
+#include <algorithm>
  2
+
  3
+#include "db.h"
  4
+#include "netbase.h"
  5
+#include "protocol.h"
  6
+#include "serialize.h"
  7
+#include "uint256.h"
  8
+
  9
+#define BITCOIN_SEED_NONCE  0x0539a019ca550825
  10
+#define REQUIRE_HEIGHT 140700
  11
+#define MIN_VERSION 40000
  12
+
  13
+using namespace std;
  14
+
  15
+class CNode {
  16
+  SOCKET sock;
  17
+  CDataStream vSend;
  18
+  CDataStream vRecv;
  19
+  unsigned int nHeaderStart;
  20
+  unsigned int nMessageStart;
  21
+  int nVersion;
  22
+  int nRecvVersion;
  23
+  string strSubVer;
  24
+  int nStartingHeight;
  25
+  vector<CAddress> *vAddr;
  26
+  int ban;
  27
+  int64 doneAfter;
  28
+  CAddress you;
  29
+
  30
+  void BeginMessage(const char *pszCommand) {
  31
+    if (nHeaderStart != -1) AbortMessage();
  32
+    nHeaderStart = vSend.size();
  33
+    vSend << CMessageHeader(pszCommand, 0);
  34
+    nMessageStart = vSend.size();
  35
+    printf("%s: SEND %s\n", you.ToString().c_str(), pszCommand); 
  36
+  }
  37
+  
  38
+  void AbortMessage() {
  39
+    if (nHeaderStart == -1) return;
  40
+    vSend.resize(nHeaderStart);
  41
+    nHeaderStart = -1;
  42
+    nMessageStart = -1;
  43
+  }
  44
+  
  45
+  void EndMessage() {
  46
+    if (nHeaderStart == -1) return;
  47
+    unsigned int nSize = vSend.size() - nMessageStart;
  48
+    memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize));
  49
+    if (vSend.GetVersion() >= 209) {
  50
+      uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end());
  51
+      unsigned int nChecksum = 0;
  52
+      memcpy(&nChecksum, &hash, sizeof(nChecksum));
  53
+      assert(nMessageStart - nHeaderStart >= offsetof(CMessageHeader, nChecksum) + sizeof(nChecksum));
  54
+      memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nChecksum), &nChecksum, sizeof(nChecksum));
  55
+    }
  56
+    nHeaderStart = -1;
  57
+    nMessageStart = -1;
  58
+  }
  59
+  
  60
+  void Send() {
  61
+    if (sock == INVALID_SOCKET) return;
  62
+    if (vSend.empty()) return;
  63
+    int nBytes = send(sock, &vSend[0], vSend.size(), 0);
  64
+    if (nBytes > 0) {
  65
+      vSend.erase(vSend.begin(), vSend.begin() + nBytes);
  66
+    } else {
  67
+      close(sock);
  68
+      sock = INVALID_SOCKET;
  69
+    }
  70
+  }
  71
+  
  72
+  void PushVersion() {
  73
+    int64 nTime = time(NULL);
  74
+    uint64 nLocalNonce = BITCOIN_SEED_NONCE;
  75
+    int64 nLocalServices = 0;
  76
+    CAddress me(CIPPort("0.0.0.0"));
  77
+    BeginMessage("version");
  78
+    int nBestHeight = REQUIRE_HEIGHT;
  79
+    string ver = "/bitcoin-seeder:0.01/";
  80
+    vSend << PROTOCOL_VERSION << nLocalServices << nTime << you << me << nLocalNonce << ver << nBestHeight;
  81
+    EndMessage();
  82
+  }
  83
+ 
  84
+  void GotVersion() {
  85
+    if (nVersion < MIN_VERSION) {
  86
+      printf("%s: BAD (version %i is below %i)\n", you.ToString().c_str(), nVersion, MIN_VERSION);
  87
+      ban = 1000000;
  88
+      return;
  89
+    }
  90
+    printf("%s: version %i\n", you.ToString().c_str(), nVersion);
  91
+    BeginMessage("getaddr");
  92
+    EndMessage();
  93
+    doneAfter = time(NULL) + 10;
  94
+  }
  95
+
  96
+  bool ProcessMessage(string strCommand, CDataStream& vRecv) {
  97
+    printf("%s: RECV %s\n", you.ToString().c_str(), strCommand.c_str());
  98
+    if (strCommand == "version") {
  99
+      int64 nTime;
  100
+      CAddress addrMe;
  101
+      CAddress addrFrom;
  102
+      uint64 nNonce = 1;
  103
+      vRecv >> nVersion >> you.nServices >> nTime >> addrMe;
  104
+      if (nVersion == 10300) nVersion = 300;
  105
+      if (nVersion >= 106 && !vRecv.empty())
  106
+        vRecv >> addrFrom >> nNonce;
  107
+      if (nVersion >= 106 && !vRecv.empty())
  108
+        vRecv >> strSubVer;
  109
+      if (nVersion >= 209 && !vRecv.empty())
  110
+        vRecv >> nStartingHeight;
  111
+      
  112
+      if (!(you.nServices & NODE_NETWORK)) {
  113
+        printf("%s: BAD (no NODE_NETWORK)\n", you.ToString().c_str());
  114
+        ban = 1000000;
  115
+        return true;
  116
+      }
  117
+      
  118
+      if (nVersion >= 209) {
  119
+        BeginMessage("verack");
  120
+        EndMessage();
  121
+      }
  122
+      vSend.SetVersion(min(nVersion, PROTOCOL_VERSION));
  123
+      if (nVersion < 209) {
  124
+        this->vRecv.SetVersion(min(nVersion, PROTOCOL_VERSION));
  125
+        GotVersion();
  126
+      }
  127
+      return false;
  128
+    }
  129
+    
  130
+    if (strCommand == "verack") {
  131
+      this->vRecv.SetVersion(min(nVersion, PROTOCOL_VERSION));
  132
+      GotVersion();
  133
+      return false;
  134
+    }
  135
+    
  136
+    if (strCommand == "addr") {
  137
+      vector<CAddress> vAddrNew;
  138
+      vRecv >> vAddrNew;
  139
+      printf("%s: got %i addresses\n", you.ToString().c_str(), (int)vAddrNew.size());
  140
+      int64 now = time(NULL);
  141
+      vector<CAddress>::iterator it = vAddrNew.begin();
  142
+      if (doneAfter == 0 || doneAfter > now + 1) doneAfter = now + 1;
  143
+      while (it != vAddrNew.end()) {
  144
+        CAddress &addr = *it;
  145
+//        printf("%s: got address %s\n", you.ToString().c_str(), addr.ToString().c_str(), (int)(vAddr->size()));
  146
+        it++;
  147
+        if (!addr.IsIPv4())
  148
+          continue;
  149
+        if (addr.nTime <= 100000000 || addr.nTime > now + 600)
  150
+          addr.nTime = now - 5 * 86400;
  151
+        vAddr->push_back(addr);
  152
+//        printf("%s: added address %s (#%i)\n", you.ToString().c_str(), addr.ToString().c_str(), (int)(vAddr->size()));
  153
+        if (vAddr->size() > 1000) {doneAfter = 1; return true; }
  154
+      }
  155
+      return false;
  156
+    }
  157
+    
  158
+    return false;
  159
+  }
  160
+  
  161
+  bool ProcessMessages() {
  162
+    if (vRecv.empty()) return false;
  163
+    do {
  164
+      CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart), END(pchMessageStart));
  165
+      int nHeaderSize = vRecv.GetSerializeSize(CMessageHeader());
  166
+      if (vRecv.end() - pstart < nHeaderSize) {
  167
+        if (vRecv.size() > nHeaderSize) {
  168
+          vRecv.erase(vRecv.begin(), vRecv.end() - nHeaderSize);
  169
+        }
  170
+        break;
  171
+      }
  172
+      vRecv.erase(vRecv.begin(), pstart);
  173
+      vector<char> vHeaderSave(vRecv.begin(), vRecv.begin() + nHeaderSize);
  174
+      CMessageHeader hdr;
  175
+      vRecv >> hdr;
  176
+      if (!hdr.IsValid()) { 
  177
+        printf("%s: BAD (invalid header)\n", you.ToString().c_str());
  178
+        ban = 100000; return true;
  179
+      }
  180
+      string strCommand = hdr.GetCommand();
  181
+      unsigned int nMessageSize = hdr.nMessageSize;
  182
+      if (nMessageSize > MAX_SIZE) { 
  183
+        printf("%s: BAD (message too large)\n", you.ToString().c_str());
  184
+        ban = 100000;
  185
+        return true; 
  186
+      }
  187
+      if (nMessageSize > vRecv.size()) {
  188
+        vRecv.insert(vRecv.begin(), vHeaderSave.begin(), vHeaderSave.end());
  189
+        break;
  190
+      }
  191
+      if (vRecv.GetVersion() >= 209) {
  192
+        uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
  193
+        unsigned int nChecksum = 0;
  194
+        memcpy(&nChecksum, &hash, sizeof(nChecksum));
  195
+        if (nChecksum != hdr.nChecksum) continue;
  196
+      }
  197
+      CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion);
  198
+      vRecv.ignore(nMessageSize);
  199
+      if (ProcessMessage(strCommand, vMsg))
  200
+        return true;
  201
+      printf("%s: done processing %s\n", you.ToString().c_str(), strCommand.c_str());
  202
+    } while(1);
  203
+    return false;
  204
+  }
  205
+  
  206
+public:
  207
+  CNode(const CIPPort& ip, vector<CAddress>& vAddrIn) : you(ip), nHeaderStart(-1), nMessageStart(-1), vAddr(&vAddrIn) {
  208
+    vSend.SetType(SER_NETWORK);
  209
+    vSend.SetVersion(0);
  210
+    vRecv.SetType(SER_NETWORK);
  211
+    vRecv.SetVersion(0);
  212
+    if (time(NULL) > 1329696000) {
  213
+      vSend.SetVersion(209);
  214
+      vRecv.SetVersion(209);
  215
+    }
  216
+  }
  217
+  bool Run() {
  218
+    bool res = true;
  219
+    if (!you.ConnectSocket(sock)) return false;
  220
+    PushVersion();
  221
+    Send();
  222
+    int64 now;
  223
+    while (now = time(NULL), ban == 0 && (doneAfter == 0 || doneAfter > now) && sock != INVALID_SOCKET) {
  224
+      char pchBuf[0x10000];
  225
+      fd_set set;
  226
+      FD_ZERO(&set);
  227
+      FD_SET(sock,&set);
  228
+      struct timeval wa;
  229
+      if (doneAfter) {
  230
+        wa.tv_sec = doneAfter - now;
  231
+        wa.tv_usec = 0;
  232
+      } else {
  233
+        wa.tv_sec = 10;
  234
+        wa.tv_usec = 0;
  235
+      }
  236
+      int ret = select(sock+1, &set, NULL, &set, &wa);
  237
+      if (ret != 1) {
  238
+        if (!doneAfter) res = false;
  239
+        break;
  240
+      }
  241
+      int nBytes = recv(sock, pchBuf, sizeof(pchBuf), 0);
  242
+      int nPos = vRecv.size();
  243
+      if (nBytes > 0) {
  244
+        vRecv.resize(nPos + nBytes);
  245
+        memcpy(&vRecv[nPos], pchBuf, nBytes);
  246
+      } else if (nBytes == 0) {
  247
+        Sleep(127);
  248
+      } else {
  249
+        break;
  250
+      }
  251
+      ProcessMessages();
  252
+      Send();
  253
+    }
  254
+    close(sock);
  255
+    sock = INVALID_SOCKET;
  256
+    return (ban == 0) && res;
  257
+  }
  258
+  
  259
+  int GetBan() {
  260
+    return ban;
  261
+  }
  262
+};
  263
+
  264
+bool TestNode(const CIPPort &cip, int &ban, vector<CAddress>& vAddr) {
  265
+  CNode node(cip, vAddr);
  266
+  bool ret = node.Run();
  267
+  if (!ret) {
  268
+    ban = node.GetBan();
  269
+  } else {
  270
+    ban = 0;
  271
+  }
  272
+  printf("%s: %s!!!\n", cip.ToString().c_str(), ret ? "GOOD" : "BAD");
  273
+  return ret;
  274
+}
  275
+
  276
+/*
  277
+int main(void) {
  278
+  CIPPort ip("bitcoin.sipa.be", 8333, true);
  279
+  vector<CAddress> vAddr;
  280
+  vAddr.clear();
  281
+  int ban = 0;
  282
+  bool ret = TestNode(ip, ban, vAddr);
  283
+  printf("ret=%s ban=%i vAddr.size()=%i\n", ret ? "good" : "bad", ban, (int)vAddr.size());
  284
+}
  285
+*/
8  bitcoin.h
... ...
@@ -0,0 +1,8 @@
  1
+#ifndef _BITCOIN_H_
  2
+#define _BITCOIN_H_ 1
  3
+
  4
+#include "protocol.h"
  5
+
  6
+bool TestNode(const CIPPort &cip, int &ban, std::vector<CAddress>& vAddr);
  7
+
  8
+#endif
41  db.cpp
@@ -18,17 +18,30 @@ void CAddrInfo::Update(bool good) {
18 18
 }
19 19
 
20 20
 bool CAddrDb::Get_(CIPPort &ip) {
21  
-  int tot = unkId.size() + ourId.size();
22  
-  if (tot == 0) return false;
23  
-  int rnd = rand() % tot;
24  
-  if (tot < unkId.size()) {
25  
-    set<int>::iterator it = unkId.begin();
26  
-    return *it;
27  
-  } else {
28  
-    int ret = ourId.front();
29  
-    ourId.pop_front();
30  
-    return ret;
31  
-  }
  21
+  int cont = 0;
  22
+  do {
  23
+    cont = 0;
  24
+    int tot = unkId.size() + ourId.size();
  25
+    if (tot == 0) return false;
  26
+    int rnd = rand() % tot;
  27
+    if (rnd < unkId.size()) {
  28
+      set<int>::iterator it = unkId.begin();
  29
+      ip = idToInfo[*it].ip;
  30
+      unkId.erase(it);
  31
+      printf("From UNK: %s\n", ip.ToString().c_str());
  32
+    } else {
  33
+      int ret = ourId.front();
  34
+      ourId.pop_front();
  35
+      if (unkId.size() > 0 && time(NULL) - idToInfo[ret].ourLastTry < MIN_RETRY) {
  36
+        ourId.push_back(ret);
  37
+        cont=1;
  38
+        continue;
  39
+      }
  40
+      ip = idToInfo[ret].ip;
  41
+      printf("From OUR: %s (size = %i)\n", ip.ToString().c_str(), (int)ourId.size());
  42
+    }
  43
+  } while(cont);
  44
+  return true;
32 45
 }
33 46
 
34 47
 int CAddrDb::Lookup_(const CIPPort &ip) {
@@ -38,7 +51,9 @@ int CAddrDb::Lookup_(const CIPPort &ip) {
38 51
 }
39 52
 
40 53
 void CAddrDb::Good_(const CIPPort &addr) {
  54
+  printf("%s: good!\n", addr.ToString().c_str());
41 55
   int id = Lookup_(addr);
  56
+  printf("%s: good (id=%i)!\n", addr.ToString().c_str(), id);
42 57
   if (id == -1) return;
43 58
   unkId.erase(id);
44 59
   banned.erase(addr);
@@ -94,7 +109,7 @@ void CAddrDb::Add_(const CAddress &addr) {
94 109
   CIPPort ipp(addr);
95 110
   if (banned.count(ipp)) {
96 111
     time_t bantime = banned[ipp];
97  
-    if (bantime < time(NULL))
  112
+    if (bantime < time(NULL) && addr.nTime > bantime)
98 113
       banned.erase(ipp);
99 114
     else
100 115
       return;
@@ -119,8 +134,8 @@ void CAddrDb::Add_(const CAddress &addr) {
119 134
   int id = nId++;
120 135
   idToInfo[id] = ai;
121 136
   ipToId[ipp] = id;
  137
+  printf("%s: added as id %i\n", ipp.ToString().c_str(), ipToId[ipp]);
122 138
   unkId.insert(id);
123  
-  printf("%s: added\n", addr.ToString().c_str());
124 139
 }
125 140
 
126 141
 void CAddrDb::GetIPs_(set<CIP>& ips, int max, bool fOnlyIPv4) {
7  db.h
@@ -11,6 +11,7 @@
11 11
 #include "util.h"
12 12
 
13 13
 #define TAU 86400.0
  14
+#define MIN_RETRY 1000
14 15
 
15 16
 class CAddrInfo {
16 17
 private:
@@ -26,7 +27,7 @@ class CAddrInfo {
26 27
   int success;
27 28
 public:
28 29
   bool IsGood() {
29  
-    return (weight > 0.5 & reliability/weight > 0.8 && timing/weight < 86400 && count/weight > 1.0) && ip.GetPort() == 8333;
  30
+    return (weight > 0 && reliability/weight > 0.8 && timing/weight < 86400) && ip.GetPort() == 8333;
30 31
   }
31 32
   bool IsTerrible() {
32 33
     return (weight > 0.5 & reliability/weight < 0.2 && timing/weight < 86400 && count/weight > 2.0);
@@ -65,6 +66,10 @@ class CAddrDb {
65 66
   void GetIPs_(std::set<CIP>& ips, int max, bool fOnlyIPv4);
66 67
 
67 68
 public:
  69
+  void Stats() {
  70
+    CRITICAL_BLOCK(cs)
  71
+      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());
  72
+  }
68 73
   void Add(const CAddress &addr) {
69 74
     CRITICAL_BLOCK(cs)
70 75
       Add_(addr);
19  dns.c
@@ -18,6 +18,8 @@ char *host = "seedtest.bitcoin.sipa.be";
18 18
 char *ns = "vps.sipa.be";
19 19
 char *mbox = "sipa.ulyssis.org";
20 20
 
  21
+extern int GetIPList(struct in_addr *addr, int max, int ipv4only);
  22
+
21 23
 typedef enum {
22 24
   CLASS_IN = 1,
23 25
   QCLASS_ANY = 255
@@ -300,16 +302,18 @@ ssize_t static dnshandle(const unsigned char *inbuf, size_t insize, unsigned cha
300 302
   
301 303
   // A records
302 304
   if ((typ == TYPE_A || typ == QTYPE_ANY) && (cls == CLASS_IN || cls == QCLASS_ANY)) {
303  
-    uint32_t ip = 0x01101102;
304  
-    do {
305  
-      int ret = write_record_a(&outpos, outend - auth_size, "", offset, CLASS_IN, datattl, (const struct in_addr*)(&ip));
  305
+    struct in_addr addr[20];
  306
+    int naddr = GetIPList(addr, 20, 1);
  307
+    int n = 0;
  308
+    while (n < naddr) {
  309
+      int ret = write_record_a(&outpos, outend - auth_size, "", offset, CLASS_IN, datattl, &addr[n]);
306 310
 //      printf("wrote A record: %i\n", ret);
307 311
       if (!ret) {
308  
-        ip += 0x01101102;
  312
+        n++;
309 313
         outbuf[7]++;
310 314
       } else
311 315
         break;
312  
-    } while(1);
  316
+    }
313 317
   }
314 318
   
315 319
   // Authority section
@@ -360,8 +364,3 @@ int dnsserver(void) {
360 364
   } while(1);
361 365
   return 0;
362 366
 }
363  
-
364  
-int main(void) {
365  
-  dnsserver();
366  
-  return 0;
367  
-}
69  main.cpp
... ...
@@ -0,0 +1,69 @@
  1
+#include <pthread.h>
  2
+
  3
+#include "bitcoin.h"
  4
+#include "db.h"
  5
+
  6
+using namespace std;
  7
+
  8
+extern "C" {
  9
+// #include "dns.h"
  10
+}
  11
+
  12
+CAddrDb db;
  13
+
  14
+extern "C" void* ThreadCrawler(void* data) {
  15
+  do {
  16
+    db.Stats();
  17
+    CIPPort ip;
  18
+    if (!db.Get(ip)) {
  19
+      Sleep(5000);
  20
+      continue;
  21
+    }
  22
+    int ban = 0;
  23
+    vector<CAddress> addr;
  24
+    bool ret = TestNode(ip,ban,addr);
  25
+    db.Add(addr);
  26
+    if (ret) {
  27
+      db.Good(ip);
  28
+    } else {
  29
+      db.Bad(ip, ban);
  30
+    }
  31
+  } while(1);
  32
+}
  33
+
  34
+extern "C" int GetIPList(struct in_addr *addr, int max, int ipv4only) {
  35
+  set<CIP> ips;
  36
+  db.GetIPs(ips, max, ipv4only);
  37
+  int n = 0;
  38
+  for (set<CIP>::iterator it = ips.begin(); it != ips.end(); it++) {
  39
+    if ((*it).GetInAddr(&addr[n]))
  40
+      n++;
  41
+  }
  42
+  return n;
  43
+}
  44
+
  45
+extern "C" int dnsserver(void);
  46
+
  47
+extern "C" void* ThreadDNS(void*) {
  48
+  dnsserver();
  49
+}
  50
+
  51
+#define NTHREADS 100
  52
+
  53
+int main(void) {
  54
+  vector<CIP> ips;
  55
+  LookupHost("dnsseed.bluematt.me", ips);
  56
+  for (vector<CIP>::iterator it = ips.begin(); it != ips.end(); it++) {
  57
+    db.Add(CIPPort(*it, 8333));
  58
+  }
  59
+  pthread_t thread[NTHREADS];
  60
+  for (int i=0; i<NTHREADS-1; i++) {
  61
+    pthread_create(&thread[i], NULL, ThreadCrawler, NULL);
  62
+  }
  63
+  pthread_create(&thread[NTHREADS-1], NULL, ThreadDNS, NULL);
  64
+  for (int i=0; i<NTHREADS; i++) {
  65
+    void* res;
  66
+    pthread_join(thread[i], &res);
  67
+  }
  68
+  return 0;
  69
+}
14  netbase.cpp
@@ -177,7 +177,11 @@ bool CIPPort::ConnectSocket(SOCKET& hSocketRet, int nTimeout) const
177 177
 
178 178
     SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
179 179
     if (hSocket == INVALID_SOCKET)
  180
+    {
  181
+        printf("Failed to create socket: %s\n", strerror(errno));
180 182
         return false;
  183
+    }
  184
+
181 185
 #ifdef SO_NOSIGPIPE
182 186
     int set = 1;
183 187
     setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
@@ -194,8 +198,8 @@ bool CIPPort::ConnectSocket(SOCKET& hSocketRet, int nTimeout) const
194 198
     if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
195 199
 #endif
196 200
     {
  201
+        printf("Failed to set socket NONBLOCK\n");
197 202
         closesocket(hSocket);
198  
-        return false;
199 203
     }
200 204
 
201 205
 
@@ -265,10 +269,12 @@ bool CIPPort::ConnectSocket(SOCKET& hSocketRet, int nTimeout) const
265 269
     if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
266 270
 #endif
267 271
     {
  272
+        printf("Failed to set socket blocking\n");
268 273
         closesocket(hSocket);
269 274
         return false;
270 275
     }
271 276
 
  277
+    printf("%s: connected\n", ToString().c_str());
272 278
     hSocketRet = hSocket;
273 279
     return true;
274 280
 }
@@ -463,12 +469,12 @@ bool operator==(const CIP& a, const CIP& b)
463 469
 
464 470
 bool operator!=(const CIP& a, const CIP& b)
465 471
 {
466  
-    return (memcmp(a.ip, b.ip, 16) == 0);
  472
+    return (memcmp(a.ip, b.ip, 16) != 0);
467 473
 }
468 474
 
469 475
 bool operator<(const CIP& a, const CIP& b)
470 476
 {
471  
-    return (memcmp(a.ip, b.ip, 16) <= 0);
  477
+    return (memcmp(a.ip, b.ip, 16) < 0);
472 478
 }
473 479
 
474 480
 bool CIP::GetInAddr(struct in_addr* pipv4Addr) const
@@ -652,7 +658,7 @@ bool operator!=(const CIPPort& a, const CIPPort& b)
652 658
 
653 659
 bool operator<(const CIPPort& a, const CIPPort& b)
654 660
 {
655  
-    return (operator<((CIP)a, (CIP)b) || a.port < b.port);
  661
+    return (operator<((CIP)a, (CIP)b) || (operator==((CIP)a, (CIP)b) && (a.port < b.port)));
656 662
 }
657 663
 
658 664
 bool CIPPort::GetSockAddr(struct sockaddr_in* paddr) const
2  protocol.cpp
@@ -86,7 +86,7 @@ CAddress::CAddress() : CIPPort()
86 86
     Init();
87 87
 }
88 88
 
89  
-CAddress::CAddress(CIPPort &ipIn, uint64 nServicesIn) : CIPPort(ipIn)
  89
+CAddress::CAddress(CIPPort ipIn, uint64 nServicesIn) : CIPPort(ipIn)
90 90
 {
91 91
     Init();
92 92
     nServices = nServicesIn;
2  protocol.h
@@ -66,7 +66,7 @@ class CAddress : public CIPPort
66 66
 {
67 67
     public:
68 68
         CAddress();
69  
-        CAddress(CIPPort& ipIn, uint64 nServicesIn=NODE_NETWORK);
  69
+        CAddress(CIPPort ipIn, uint64 nServicesIn=NODE_NETWORK);
70 70
 
71 71
         void Init();
72 72
 
76  serialize.h
@@ -60,9 +60,7 @@ class CDataStream;
60 60
 class CAutoFile;
61 61
 static const unsigned int MAX_SIZE = 0x02000000;
62 62
 
63  
-static const int VERSION = 50100;
64  
-static const char* pszSubVer = "";
65  
-static const bool VERSION_IS_BETA = true;
  63
+static const int PROTOCOL_VERSION = 60000;
66 64
 
67 65
 // Used to bypass the rule against non-const reference to temporary
68 66
 // where it makes sense with wrappers such as CFlatData or CTxDB
@@ -91,7 +89,7 @@ enum
91 89
 };
92 90
 
93 91
 #define IMPLEMENT_SERIALIZE(statements)    \
94  
-    unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const  \
  92
+    unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const  \
95 93
     {                                           \
96 94
         CSerActionGetSerializeSize ser_action;  \
97 95
         const bool fGetSize = true;             \
@@ -105,7 +103,7 @@ enum
105 103
         return nSerSize;                        \
106 104
     }                                           \
107 105
     template<typename Stream>                   \
108  
-    void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const  \
  106
+    void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const  \
109 107
     {                                           \
110 108
         CSerActionSerialize ser_action;         \
111 109
         const bool fGetSize = false;            \
@@ -115,7 +113,7 @@ enum
115 113
         {statements}                            \
116 114
     }                                           \
117 115
     template<typename Stream>                   \
118  
-    void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)  \
  116
+    void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION)  \
119 117
     {                                           \
120 118
         CSerActionUnserialize ser_action;       \
121 119
         const bool fGetSize = false;            \
@@ -362,43 +360,43 @@ template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_st
362 360
 // vector
363 361
 template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
364 362
 template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
365  
-template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion=VERSION);
  363
+template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion=PROTOCOL_VERSION);
366 364
 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&);
367 365
 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&);
368  
-template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion=VERSION);
  366
+template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion=PROTOCOL_VERSION);
369 367
 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&);
370 368
 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&);
371  
-template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion=VERSION);
  369
+template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion=PROTOCOL_VERSION);
372 370
 
373 371
 // others derived from vector
374  
-extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=VERSION);
375  
-template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion=VERSION);
376  
-template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion=VERSION);
  372
+extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=PROTOCOL_VERSION);
  373
+template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion=PROTOCOL_VERSION);
  374
+template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion=PROTOCOL_VERSION);
377 375
 
378 376
 // pair
379  
-template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion=VERSION);
380  
-template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion=VERSION);
381  
-template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion=VERSION);
  377
+template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion=PROTOCOL_VERSION);
  378
+template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion=PROTOCOL_VERSION);
  379
+template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion=PROTOCOL_VERSION);
382 380
 
383 381
 // 3 tuple
384  
-template<typename T0, typename T1, typename T2> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion=VERSION);
385  
-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);
386  
-template<typename Stream, typename T0, typename T1, typename T2> void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion=VERSION);
  382
+template<typename T0, typename T1, typename T2> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion=PROTOCOL_VERSION);
  383
+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);
  384
+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);
387 385
 
388 386
 // 4 tuple
389  
-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);
390  
-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);
391  
-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);
  387
+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);
  388
+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);
  389
+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);
392 390
 
393 391
 // map
394  
-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);
395  
-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);
396  
-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);
  392
+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);
  393
+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);
  394
+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);
397 395
 
398 396
 // set
399  
-template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
400  
-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);
401  
-template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
  397
+template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion=PROTOCOL_VERSION);
  398
+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);
  399
+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);
402 400
 
403 401
 
404 402
 
@@ -411,19 +409,19 @@ template<typename Stream, typename K, typename Pred, typename A> void Unserializ
411 409
 // Thanks to Boost serialization for this idea.
412 410
 //
413 411
 template<typename T>
414  
-inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion=VERSION)
  412
+inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion=PROTOCOL_VERSION)
415 413
 {
416 414
     return a.GetSerializeSize((int)nType, nVersion);
417 415
 }
418 416
 
419 417
 template<typename Stream, typename T>
420  
-inline void Serialize(Stream& os, const T& a, long nType, int nVersion=VERSION)
  418
+inline void Serialize(Stream& os, const T& a, long nType, int nVersion=PROTOCOL_VERSION)
421 419
 {
422 420
     a.Serialize(os, (int)nType, nVersion);
423 421
 }
424 422
 
425 423
 template<typename Stream, typename T>
426  
-inline void Unserialize(Stream& is, T& a, long nType, int nVersion=VERSION)
  424
+inline void Unserialize(Stream& is, T& a, long nType, int nVersion=PROTOCOL_VERSION)
427 425
 {
428 426
     a.Unserialize(is, (int)nType, nVersion);
429 427
 }
@@ -857,39 +855,39 @@ class CDataStream
857 855
     typedef vector_type::const_iterator   const_iterator;
858 856
     typedef vector_type::reverse_iterator reverse_iterator;
859 857
 
860  
-    explicit CDataStream(int nTypeIn=SER_NETWORK, int nVersionIn=VERSION)
  858
+    explicit CDataStream(int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION)
861 859
     {
862 860
         Init(nTypeIn, nVersionIn);
863 861
     }
864 862
 
865  
-    CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(pbegin, pend)
  863
+    CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(pbegin, pend)
866 864
     {
867 865
         Init(nTypeIn, nVersionIn);
868 866
     }
869 867
 
870 868
 #if !defined(_MSC_VER) || _MSC_VER >= 1300
871  
-    CDataStream(const char* pbegin, const char* pend, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(pbegin, pend)
  869
+    CDataStream(const char* pbegin, const char* pend, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(pbegin, pend)
872 870
     {
873 871
         Init(nTypeIn, nVersionIn);
874 872
     }
875 873
 #endif
876 874
 
877  
-    CDataStream(const vector_type& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())
  875
+    CDataStream(const vector_type& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(vchIn.begin(), vchIn.end())
878 876
     {
879 877
         Init(nTypeIn, nVersionIn);
880 878
     }
881 879
 
882  
-    CDataStream(const std::vector<char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())
  880
+    CDataStream(const std::vector<char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(vchIn.begin(), vchIn.end())
883 881
     {
884 882
         Init(nTypeIn, nVersionIn);
885 883
     }
886 884
 
887  
-    CDataStream(const std::vector<unsigned char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0])
  885
+    CDataStream(const std::vector<unsigned char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0])
888 886
     {
889 887
         Init(nTypeIn, nVersionIn);
890 888
     }
891 889
 
892  
-    void Init(int nTypeIn=SER_NETWORK, int nVersionIn=VERSION)
  890
+    void Init(int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION)
893 891
     {
894 892
         nReadPos = 0;
895 893
         nType = nTypeIn;
@@ -1103,7 +1101,7 @@ class CDataStream
1103 1101
     }
1104 1102
 
1105 1103
     template<typename Stream>
1106  
-    void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
  1104
+    void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const
1107 1105
     {
1108 1106
         // Special case: stream << stream concatenates like stream += stream
1109 1107
         if (!vch.empty())
@@ -1212,7 +1210,7 @@ class CAutoFile
1212 1210
 
1213 1211
     typedef FILE element_type;
1214 1212
 
1215  
-    CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=VERSION)
  1213
+    CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=PROTOCOL_VERSION)
1216 1214
     {
1217 1215
         file = filenew;
1218 1216
         nType = nTypeIn;
6  uint256.h
@@ -364,19 +364,19 @@ class base_uint
364 364
     }
365 365
 
366 366
 
367  
-    unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const
  367
+    unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const
368 368
     {
369 369
         return sizeof(pn);
370 370
     }
371 371
 
372 372
     template<typename Stream>
373  
-    void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
  373
+    void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const
374 374
     {
375 375
         s.write((char*)pn, sizeof(pn));
376 376
     }
377 377
 
378 378
     template<typename Stream>
379  
-    void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)
  379
+    void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION)
380 380
     {
381 381
         s.read((char*)pn, sizeof(pn));
382 382
     }
20  util.h
@@ -3,6 +3,9 @@
3 3
 
4 4
 #include <pthread.h>
5 5
 #include <errno.h>
  6
+#include <openssl/sha.h>
  7
+
  8
+#include "uint256.h"
6 9
 
7 10
 #define loop                for (;;)
8 11
 #define BEGIN(a)            ((char*)&(a))
@@ -64,4 +67,21 @@ class CCriticalBlock
64 67
 #define CRITICAL_BLOCK(cs)     \
65 68
     if (CCriticalBlock criticalblock = CCriticalBlock(cs))
66 69
 
  70
+template<typename T1> inline uint256 Hash(const T1 pbegin, const T1 pend)
  71
+{
  72
+    static unsigned char pblank[1];
  73
+    uint256 hash1;
  74
+    SHA256((pbegin == pend ? pblank : (unsigned char*)&pbegin[0]), (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1);
  75
+    uint256 hash2;
  76
+    SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
  77
+    return hash2;
  78
+}
  79
+
  80
+void static inline Sleep(int nMilliSec) {
  81
+  struct timespec wa;
  82
+  wa.tv_sec = nMilliSec/1000;
  83
+  wa.tv_nsec = (nMilliSec % 1000) * 1000000;
  84
+  nanosleep(&wa, NULL);
  85
+}
  86
+
67 87
 #endif

0 notes on commit c4cc50a

Please sign in to comment.
Something went wrong with that request. Please try again.