genesis 1
genesis 2
genesis 3
genesis 4
genesis 5 #ifndef BITCOIN_NET_H
genesis 6 #define BITCOIN_NET_H
genesis 7
genesis 8 #include <deque>
genesis 9 #include <boost/array.hpp>
genesis 10 #include <boost/foreach.hpp>
genesis 11 #include <openssl/rand.h>
genesis 12
genesis 13 #ifndef WIN32
genesis 14 #include <arpa/inet.h>
genesis 15 #endif
genesis 16
genesis 17 #include "protocol.h"
genesis 18
genesis 19 class CAddrDB;
genesis 20 class CRequestTracker;
genesis 21 class CNode;
genesis 22 class CBlockIndex;
genesis 23 extern int nBestHeight;
genesis 24 extern int nConnectTimeout;
genesis 25
genesis 26
genesis 27
genesis 28 inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 10*1000); }
genesis 29 inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 10*1000); }
genesis 30 static const unsigned int PUBLISH_HOPS = 5;
genesis 31
genesis 32 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout=nConnectTimeout);
genesis 33 bool Lookup(const char *pszName, std::vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
genesis 34 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
genesis 35 bool GetMyExternalIP(unsigned int& ipRet);
genesis 36 bool AddAddress(CAddress addr, int64 nTimePenalty=0, CAddrDB *pAddrDB=NULL);
genesis 37 void AddressCurrentlyConnected(const CAddress& addr);
genesis 38 CNode* FindNode(unsigned int ip);
genesis 39 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
genesis 40 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1);
genesis 41 bool AnySubscribed(unsigned int nChannel);
genesis 42 void MapPort(bool fMapPort);
genesis 43 bool BindListenPort(std::string& strError=REF(std::string()));
genesis 44 void StartNode(void* parg);
genesis 45 bool StopNode();
genesis 46
genesis 47 enum
genesis 48 {
genesis 49 MSG_TX = 1,
genesis 50 MSG_BLOCK,
genesis 51 };
genesis 52
genesis 53 class CRequestTracker
genesis 54 {
genesis 55 public:
genesis 56 void (*fn)(void*, CDataStream&);
genesis 57 void* param1;
genesis 58
genesis 59 explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL)
genesis 60 {
genesis 61 fn = fnIn;
genesis 62 param1 = param1In;
genesis 63 }
genesis 64
genesis 65 bool IsNull()
genesis 66 {
genesis 67 return fn == NULL;
genesis 68 }
genesis 69 };
genesis 70
genesis 71
genesis 72
genesis 73
genesis 74
genesis 75 extern bool fClient;
genesis 76 extern bool fAllowDNS;
genesis 77 extern uint64 nLocalServices;
genesis 78 extern CAddress addrLocalHost;
genesis 79 extern uint64 nLocalHostNonce;
genesis 80 extern boost::array<int, 10> vnThreadsRunning;
genesis 81
genesis 82 extern std::vector<CNode*> vNodes;
genesis 83 extern CCriticalSection cs_vNodes;
genesis 84 extern std::map<std::vector<unsigned char>, CAddress> mapAddresses;
genesis 85 extern CCriticalSection cs_mapAddresses;
genesis 86 extern std::map<CInv, CDataStream> mapRelay;
genesis 87 extern std::deque<std::pair<int64, CInv> > vRelayExpiration;
genesis 88 extern CCriticalSection cs_mapRelay;
genesis 89 extern std::map<CInv, int64> mapAlreadyAskedFor;
genesis 90
genesis 91
genesis 92 extern int fUseProxy;
genesis 93 extern CAddress addrProxy;
genesis 94
genesis 95
genesis 96
genesis 97
genesis 98
genesis 99
genesis 100 class CNode
genesis 101 {
genesis 102 public:
genesis 103
genesis 104 uint64 nServices;
genesis 105 SOCKET hSocket;
genesis 106 CDataStream vSend;
genesis 107 CDataStream vRecv;
genesis 108 CCriticalSection cs_vSend;
genesis 109 CCriticalSection cs_vRecv;
genesis 110 int64 nLastSend;
genesis 111 int64 nLastRecv;
genesis 112 int64 nLastSendEmpty;
genesis 113 int64 nTimeConnected;
genesis 114 unsigned int nHeaderStart;
genesis 115 unsigned int nMessageStart;
genesis 116 CAddress addr;
genesis 117 int nVersion;
genesis 118 std::string strSubVer;
genesis 119 bool fClient;
genesis 120 bool fInbound;
genesis 121 bool fNetworkNode;
genesis 122 bool fSuccessfullyConnected;
genesis 123 bool fDisconnect;
genesis 124 protected:
genesis 125 int nRefCount;
genesis 126
genesis 127
genesis 128
genesis 129 static std::map<unsigned int, int64> setBanned;
genesis 130 static CCriticalSection cs_setBanned;
genesis 131 int nMisbehavior;
genesis 132
genesis 133 public:
genesis 134 int64 nReleaseTime;
genesis 135 std::map<uint256, CRequestTracker> mapRequests;
genesis 136 CCriticalSection cs_mapRequests;
genesis 137 uint256 hashContinue;
genesis 138 CBlockIndex* pindexLastGetBlocksBegin;
genesis 139 uint256 hashLastGetBlocksEnd;
genesis 140 int nStartingHeight;
genesis 141
genesis 142
genesis 143 std::vector<CAddress> vAddrToSend;
genesis 144 std::set<CAddress> setAddrKnown;
genesis 145 bool fGetAddr;
genesis 146 std::set<uint256> setKnown;
genesis 147
genesis 148
genesis 149 std::set<CInv> setInventoryKnown;
genesis 150 std::vector<CInv> vInventoryToSend;
genesis 151 CCriticalSection cs_inventory;
genesis 152 std::multimap<int64, CInv> mapAskFor;
genesis 153
genesis 154
genesis 155 std::vector<char> vfSubscribe;
genesis 156
genesis 157 CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false)
genesis 158 {
genesis 159 nServices = 0;
genesis 160 hSocket = hSocketIn;
genesis 161 vSend.SetType(SER_NETWORK);
genesis 162 vSend.SetVersion(0);
genesis 163 vRecv.SetType(SER_NETWORK);
genesis 164 vRecv.SetVersion(0);
genesis 165
genesis 166 if (GetTime() > 1329696000)
genesis 167 {
genesis 168 vSend.SetVersion(209);
genesis 169 vRecv.SetVersion(209);
genesis 170 }
genesis 171 nLastSend = 0;
genesis 172 nLastRecv = 0;
genesis 173 nLastSendEmpty = GetTime();
genesis 174 nTimeConnected = GetTime();
genesis 175 nHeaderStart = -1;
genesis 176 nMessageStart = -1;
genesis 177 addr = addrIn;
genesis 178 nVersion = 0;
genesis 179 strSubVer = "";
genesis 180 fClient = false;
genesis 181 fInbound = fInboundIn;
genesis 182 fNetworkNode = false;
genesis 183 fSuccessfullyConnected = false;
genesis 184 fDisconnect = false;
genesis 185 nRefCount = 0;
genesis 186 nReleaseTime = 0;
genesis 187 hashContinue = 0;
genesis 188 pindexLastGetBlocksBegin = 0;
genesis 189 hashLastGetBlocksEnd = 0;
genesis 190 nStartingHeight = -1;
genesis 191 fGetAddr = false;
genesis 192 vfSubscribe.assign(256, false);
genesis 193 nMisbehavior = 0;
genesis 194
genesis 195
genesis 196 if (!fInbound)
genesis 197 PushVersion();
genesis 198 }
genesis 199
genesis 200 ~CNode()
genesis 201 {
genesis 202 if (hSocket != INVALID_SOCKET)
genesis 203 {
genesis 204 closesocket(hSocket);
genesis 205 hSocket = INVALID_SOCKET;
genesis 206 }
genesis 207 }
genesis 208
genesis 209 private:
genesis 210 CNode(const CNode&);
genesis 211 void operator=(const CNode&);
genesis 212 public:
genesis 213
genesis 214
genesis 215 int GetRefCount()
genesis 216 {
genesis 217 return std::max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);
genesis 218 }
genesis 219
genesis 220 CNode* AddRef(int64 nTimeout=0)
genesis 221 {
genesis 222 if (nTimeout != 0)
genesis 223 nReleaseTime = std::max(nReleaseTime, GetTime() + nTimeout);
genesis 224 else
genesis 225 nRefCount++;
genesis 226 return this;
genesis 227 }
genesis 228
genesis 229 void Release()
genesis 230 {
genesis 231 nRefCount--;
genesis 232 }
genesis 233
genesis 234
genesis 235
genesis 236 void AddAddressKnown(const CAddress& addr)
genesis 237 {
genesis 238 setAddrKnown.insert(addr);
genesis 239 }
genesis 240
genesis 241 void PushAddress(const CAddress& addr)
genesis 242 {
genesis 243
genesis 244
genesis 245
genesis 246 if (addr.IsValid() && !setAddrKnown.count(addr))
genesis 247 vAddrToSend.push_back(addr);
genesis 248 }
genesis 249
genesis 250
genesis 251 void AddInventoryKnown(const CInv& inv)
genesis 252 {
genesis 253 CRITICAL_BLOCK(cs_inventory)
genesis 254 setInventoryKnown.insert(inv);
genesis 255 }
genesis 256
genesis 257 void PushInventory(const CInv& inv)
genesis 258 {
genesis 259 CRITICAL_BLOCK(cs_inventory)
genesis 260 if (!setInventoryKnown.count(inv))
genesis 261 vInventoryToSend.push_back(inv);
genesis 262 }
genesis 263
genesis 264 void AskFor(const CInv& inv)
genesis 265 {
genesis 266
genesis 267
genesis 268 int64& nRequestTime = mapAlreadyAskedFor[inv];
genesis 269 printf("askfor %s %"PRI64d"\n", inv.ToString().c_str(), nRequestTime);
genesis 270
genesis 271
genesis 272 int64 nNow = (GetTime() - 1) * 1000000;
genesis 273 static int64 nLastTime;
genesis 274 ++nLastTime;
genesis 275 nNow = std::max(nNow, nLastTime);
genesis 276 nLastTime = nNow;
genesis 277
genesis 278
genesis 279 nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
genesis 280 mapAskFor.insert(std::make_pair(nRequestTime, inv));
genesis 281 }
genesis 282
genesis 283
genesis 284
genesis 285 void BeginMessage(const char* pszCommand)
genesis 286 {
genesis 287 ENTER_CRITICAL_SECTION(cs_vSend);
genesis 288 if (nHeaderStart != -1)
genesis 289 AbortMessage();
genesis 290 nHeaderStart = vSend.size();
genesis 291 vSend << CMessageHeader(pszCommand, 0);
genesis 292 nMessageStart = vSend.size();
genesis 293 if (fDebug) {
genesis 294 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
genesis 295 printf("sending: %s ", pszCommand);
genesis 296 }
genesis 297 }
genesis 298
genesis 299 void AbortMessage()
genesis 300 {
genesis 301 if (nHeaderStart == -1)
genesis 302 return;
genesis 303 vSend.resize(nHeaderStart);
genesis 304 nHeaderStart = -1;
genesis 305 nMessageStart = -1;
genesis 306 LEAVE_CRITICAL_SECTION(cs_vSend);
genesis 307
genesis 308 if (fDebug)
genesis 309 printf("(aborted)\n");
genesis 310 }
genesis 311
genesis 312 void EndMessage()
genesis 313 {
genesis 314 if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
genesis 315 {
genesis 316 printf("dropmessages DROPPING SEND MESSAGE\n");
genesis 317 AbortMessage();
genesis 318 return;
genesis 319 }
genesis 320
genesis 321 if (nHeaderStart == -1)
genesis 322 return;
genesis 323
genesis 324
genesis 325 unsigned int nSize = vSend.size() - nMessageStart;
genesis 326 memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize));
genesis 327
genesis 328
genesis 329 if (vSend.GetVersion() >= 209)
genesis 330 {
genesis 331 uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end());
genesis 332 unsigned int nChecksum = 0;
genesis 333 memcpy(&nChecksum, &hash, sizeof(nChecksum));
genesis 334 assert(nMessageStart - nHeaderStart >= offsetof(CMessageHeader, nChecksum) + sizeof(nChecksum));
genesis 335 memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nChecksum), &nChecksum, sizeof(nChecksum));
genesis 336 }
genesis 337
genesis 338 if (fDebug) {
genesis 339 printf("(%d bytes)\n", nSize);
genesis 340 }
genesis 341
genesis 342 nHeaderStart = -1;
genesis 343 nMessageStart = -1;
genesis 344 LEAVE_CRITICAL_SECTION(cs_vSend);
genesis 345 }
genesis 346
genesis 347 void EndMessageAbortIfEmpty()
genesis 348 {
genesis 349 if (nHeaderStart == -1)
genesis 350 return;
genesis 351 int nSize = vSend.size() - nMessageStart;
genesis 352 if (nSize > 0)
genesis 353 EndMessage();
genesis 354 else
genesis 355 AbortMessage();
genesis 356 }
genesis 357
genesis 358
genesis 359
genesis 360 void PushVersion()
genesis 361 {
genesis 362
genesis 363 int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
genesis 364 CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
genesis 365 CAddress addrMe = (fUseProxy || !addrLocalHost.IsRoutable() ? CAddress("0.0.0.0") : addrLocalHost);
genesis 366 RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
genesis 367 PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe,
genesis 368 nLocalHostNonce, std::string(pszSubVer), nBestHeight);
genesis 369 }
genesis 370
genesis 371
genesis 372
genesis 373
genesis 374 void PushMessage(const char* pszCommand)
genesis 375 {
genesis 376 try
genesis 377 {
genesis 378 BeginMessage(pszCommand);
genesis 379 EndMessage();
genesis 380 }
genesis 381 catch (...)
genesis 382 {
genesis 383 AbortMessage();
genesis 384 throw;
genesis 385 }
genesis 386 }
genesis 387
genesis 388 template<typename T1>
genesis 389 void PushMessage(const char* pszCommand, const T1& a1)
genesis 390 {
genesis 391 try
genesis 392 {
genesis 393 BeginMessage(pszCommand);
genesis 394 vSend << a1;
genesis 395 EndMessage();
genesis 396 }
genesis 397 catch (...)
genesis 398 {
genesis 399 AbortMessage();
genesis 400 throw;
genesis 401 }
genesis 402 }
genesis 403
genesis 404 template<typename T1, typename T2>
genesis 405 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
genesis 406 {
genesis 407 try
genesis 408 {
genesis 409 BeginMessage(pszCommand);
genesis 410 vSend << a1 << a2;
genesis 411 EndMessage();
genesis 412 }
genesis 413 catch (...)
genesis 414 {
genesis 415 AbortMessage();
genesis 416 throw;
genesis 417 }
genesis 418 }
genesis 419
genesis 420 template<typename T1, typename T2, typename T3>
genesis 421 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
genesis 422 {
genesis 423 try
genesis 424 {
genesis 425 BeginMessage(pszCommand);
genesis 426 vSend << a1 << a2 << a3;
genesis 427 EndMessage();
genesis 428 }
genesis 429 catch (...)
genesis 430 {
genesis 431 AbortMessage();
genesis 432 throw;
genesis 433 }
genesis 434 }
genesis 435
genesis 436 template<typename T1, typename T2, typename T3, typename T4>
genesis 437 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
genesis 438 {
genesis 439 try
genesis 440 {
genesis 441 BeginMessage(pszCommand);
genesis 442 vSend << a1 << a2 << a3 << a4;
genesis 443 EndMessage();
genesis 444 }
genesis 445 catch (...)
genesis 446 {
genesis 447 AbortMessage();
genesis 448 throw;
genesis 449 }
genesis 450 }
genesis 451
genesis 452 template<typename T1, typename T2, typename T3, typename T4, typename T5>
genesis 453 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
genesis 454 {
genesis 455 try
genesis 456 {
genesis 457 BeginMessage(pszCommand);
genesis 458 vSend << a1 << a2 << a3 << a4 << a5;
genesis 459 EndMessage();
genesis 460 }
genesis 461 catch (...)
genesis 462 {
genesis 463 AbortMessage();
genesis 464 throw;
genesis 465 }
genesis 466 }
genesis 467
genesis 468 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
genesis 469 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
genesis 470 {
genesis 471 try
genesis 472 {
genesis 473 BeginMessage(pszCommand);
genesis 474 vSend << a1 << a2 << a3 << a4 << a5 << a6;
genesis 475 EndMessage();
genesis 476 }
genesis 477 catch (...)
genesis 478 {
genesis 479 AbortMessage();
genesis 480 throw;
genesis 481 }
genesis 482 }
genesis 483
genesis 484 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
genesis 485 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7)
genesis 486 {
genesis 487 try
genesis 488 {
genesis 489 BeginMessage(pszCommand);
genesis 490 vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
genesis 491 EndMessage();
genesis 492 }
genesis 493 catch (...)
genesis 494 {
genesis 495 AbortMessage();
genesis 496 throw;
genesis 497 }
genesis 498 }
genesis 499
genesis 500 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
genesis 501 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8)
genesis 502 {
genesis 503 try
genesis 504 {
genesis 505 BeginMessage(pszCommand);
genesis 506 vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
genesis 507 EndMessage();
genesis 508 }
genesis 509 catch (...)
genesis 510 {
genesis 511 AbortMessage();
genesis 512 throw;
genesis 513 }
genesis 514 }
genesis 515
genesis 516 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
genesis 517 void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8, const T9& a9)
genesis 518 {
genesis 519 try
genesis 520 {
genesis 521 BeginMessage(pszCommand);
genesis 522 vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
genesis 523 EndMessage();
genesis 524 }
genesis 525 catch (...)
genesis 526 {
genesis 527 AbortMessage();
genesis 528 throw;
genesis 529 }
genesis 530 }
genesis 531
genesis 532
genesis 533 void PushRequest(const char* pszCommand,
genesis 534 void (*fn)(void*, CDataStream&), void* param1)
genesis 535 {
genesis 536 uint256 hashReply;
genesis 537 RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
genesis 538
genesis 539 CRITICAL_BLOCK(cs_mapRequests)
genesis 540 mapRequests[hashReply] = CRequestTracker(fn, param1);
genesis 541
genesis 542 PushMessage(pszCommand, hashReply);
genesis 543 }
genesis 544
genesis 545 template<typename T1>
genesis 546 void PushRequest(const char* pszCommand, const T1& a1,
genesis 547 void (*fn)(void*, CDataStream&), void* param1)
genesis 548 {
genesis 549 uint256 hashReply;
genesis 550 RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
genesis 551
genesis 552 CRITICAL_BLOCK(cs_mapRequests)
genesis 553 mapRequests[hashReply] = CRequestTracker(fn, param1);
genesis 554
genesis 555 PushMessage(pszCommand, hashReply, a1);
genesis 556 }
genesis 557
genesis 558 template<typename T1, typename T2>
genesis 559 void PushRequest(const char* pszCommand, const T1& a1, const T2& a2,
genesis 560 void (*fn)(void*, CDataStream&), void* param1)
genesis 561 {
genesis 562 uint256 hashReply;
genesis 563 RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
genesis 564
genesis 565 CRITICAL_BLOCK(cs_mapRequests)
genesis 566 mapRequests[hashReply] = CRequestTracker(fn, param1);
genesis 567
genesis 568 PushMessage(pszCommand, hashReply, a1, a2);
genesis 569 }
genesis 570
genesis 571
genesis 572
genesis 573 void PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd);
genesis 574 bool IsSubscribed(unsigned int nChannel);
genesis 575 void Subscribe(unsigned int nChannel, unsigned int nHops=0);
genesis 576 void CancelSubscribe(unsigned int nChannel);
genesis 577 void CloseSocketDisconnect();
genesis 578 void Cleanup();
genesis 579
genesis 580
genesis 581
genesis 582
genesis 583
genesis 584
genesis 585
genesis 586
genesis 587
genesis 588
genesis 589
genesis 590
genesis 591
genesis 592
genesis 593
genesis 594
genesis 595 static void ClearBanned();
genesis 596 static bool IsBanned(unsigned int ip);
genesis 597 bool Misbehaving(int howmuch);
genesis 598 };
genesis 599
genesis 600
genesis 601
genesis 602
genesis 603
genesis 604
genesis 605
genesis 606
genesis 607
genesis 608
genesis 609 inline void RelayInventory(const CInv& inv)
genesis 610 {
genesis 611
genesis 612 CRITICAL_BLOCK(cs_vNodes)
genesis 613 BOOST_FOREACH(CNode* pnode, vNodes)
genesis 614 pnode->PushInventory(inv);
genesis 615 }
genesis 616
genesis 617 template<typename T>
genesis 618 void RelayMessage(const CInv& inv, const T& a)
genesis 619 {
genesis 620 CDataStream ss(SER_NETWORK);
genesis 621 ss.reserve(10000);
genesis 622 ss << a;
genesis 623 RelayMessage(inv, ss);
genesis 624 }
genesis 625
genesis 626 template<>
genesis 627 inline void RelayMessage<>(const CInv& inv, const CDataStream& ss)
genesis 628 {
genesis 629 CRITICAL_BLOCK(cs_mapRelay)
genesis 630 {
genesis 631
genesis 632 while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
genesis 633 {
genesis 634 mapRelay.erase(vRelayExpiration.front().second);
genesis 635 vRelayExpiration.pop_front();
genesis 636 }
genesis 637
genesis 638
genesis 639 mapRelay[inv] = ss;
genesis 640 vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
genesis 641 }
genesis 642
genesis 643 RelayInventory(inv);
genesis 644 }
genesis 645
genesis 646
genesis 647
genesis 648
genesis 649
genesis 650
genesis 651
genesis 652
genesis 653
genesis 654
genesis 655
genesis 656
genesis 657
genesis 658
genesis 659
genesis 660
genesis 661 template<typename T>
genesis 662 void AdvertStartPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
genesis 663 {
genesis 664
genesis 665 obj.setSources.insert(pfrom->addr.ip);
genesis 666
genesis 667 if (!AdvertInsert(obj))
genesis 668 return;
genesis 669
genesis 670
genesis 671 CRITICAL_BLOCK(cs_vNodes)
genesis 672 BOOST_FOREACH(CNode* pnode, vNodes)
genesis 673 if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
genesis 674 pnode->PushMessage("publish", nChannel, nHops, obj);
genesis 675 }
genesis 676
genesis 677 template<typename T>
genesis 678 void AdvertStopPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
genesis 679 {
genesis 680 uint256 hash = obj.GetHash();
genesis 681
genesis 682 CRITICAL_BLOCK(cs_vNodes)
genesis 683 BOOST_FOREACH(CNode* pnode, vNodes)
genesis 684 if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
genesis 685 pnode->PushMessage("pub-cancel", nChannel, nHops, hash);
genesis 686
genesis 687 AdvertErase(obj);
genesis 688 }
genesis 689
genesis 690 template<typename T>
genesis 691 void AdvertRemoveSource(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
genesis 692 {
genesis 693
genesis 694 obj.setSources.erase(pfrom->addr.ip);
genesis 695
genesis 696
genesis 697 if (obj.setSources.empty())
genesis 698 AdvertStopPublish(pfrom, nChannel, nHops, obj);
genesis 699 }
genesis 700
genesis 701 #endif