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