return Write(make_pair(string("addr"), addr.GetKey()), addr);
}
+bool CAddrDB::EraseAddress(const CAddress& addr)
+{
+ return Erase(make_pair(string("addr"), addr.GetKey()));
+}
+
bool CAddrDB::LoadAddresses()
{
CRITICAL_BLOCK(cs_mapAddresses)
pcursor->close();
printf("Loaded %d addresses\n", mapAddresses.size());
-
- // Fix for possible bug that manifests in mapAddresses.count in irc.cpp,
- // just need to call count here and it doesn't happen there. The bug was the
- // pack pragma in irc.cpp and has been fixed, but I'm not in a hurry to delete this.
- mapAddresses.count(vector<unsigned char>(18));
}
return true;
void operator=(const CAddrDB&);
public:
bool WriteAddress(const CAddress& addr);
+ bool EraseAddress(const CAddress& addr);
bool LoadAddresses();
};
}
else if (nBytes <= 0)
{
+ if (fShutdown)
+ return false;
+ if (nBytes < 0)
+ {
+ int nErr = WSAGetLastError();
+ if (nErr == WSAEMSGSIZE)
+ continue;
+ if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
+ {
+ Sleep(10);
+ continue;
+ }
+ }
if (!strLine.empty())
return true;
- // socket closed
- printf("IRC socket closed\n");
- return false;
- }
- else
- {
- // socket error
- int nErr = WSAGetLastError();
- if (nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
+ if (nBytes == 0)
+ {
+ // socket closed
+ printf("IRC socket closed\n");
+ return false;
+ }
+ else
{
+ // socket error
+ int nErr = WSAGetLastError();
printf("IRC recv failed: %d\n", nErr);
return false;
}
CAddress addr;
if (DecodeAddress(pszName, addr))
{
- addr.nTime = GetAdjustedTime() - 51 * 60;
- if (AddAddress(addr))
+ addr.nTime = GetAdjustedTime();
+ if (AddAddress(addr, 51 * 60))
printf("IRC got new address\n");
nGotIRCAddresses++;
}
bool IsInitialBlockDownload()
{
- if (pindexBest == NULL)
+ if (pindexBest == NULL || nBestHeight < 74000)
return true;
static int64 nLastUpdate;
static CBlockIndex* pindexLastBest;
if (pfrom->nVersion < 209)
pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION));
+ if (!pfrom->fInbound)
+ {
+ // Advertise our address
+ if (addrLocalHost.IsRoutable() && !fUseProxy)
+ {
+ CAddress addr(addrLocalHost);
+ addr.nTime = GetAdjustedTime();
+ pfrom->PushAddress(addr);
+ }
+
+ // Get recent addresses
+ if (pfrom->nVersion >= 31402 || mapAddresses.size() < 1000)
+ {
+ pfrom->PushMessage("getaddr");
+ pfrom->fGetAddr = true;
+ }
+ }
+
// Ask the first connected node for block updates
static int nAskedForBlocks;
if (!pfrom->fClient && (nAskedForBlocks < 1 || vNodes.size() <= 1))
{
vector<CAddress> vAddr;
vRecv >> vAddr;
- if (pfrom->nVersion < 200) // don't want addresses from 0.1.5
+
+ // Don't want addr from older versions unless seeding
+ if (pfrom->nVersion < 209)
return true;
- if (pfrom->nVersion < 209 && mapAddresses.size() > 1000) // don't want addr from 0.2.0 unless seeding
+ if (pfrom->nVersion < 31402 && mapAddresses.size() > 1000)
return true;
if (vAddr.size() > 1000)
return error("message addr size() = %d", vAddr.size());
// Store the new addresses
+ int64 nNow = GetAdjustedTime();
+ int64 nSince = nNow - 10 * 60;
foreach(CAddress& addr, vAddr)
{
if (fShutdown)
// ignore IPv6 for now, since it isn't implemented anyway
if (!addr.IsIPv4())
continue;
- addr.nTime = GetAdjustedTime() - 2 * 60 * 60;
- if (pfrom->fGetAddr || vAddr.size() > 10)
- addr.nTime -= 5 * 24 * 60 * 60;
- AddAddress(addr);
+ if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
+ addr.nTime = nNow - 5 * 24 * 60 * 60;
+ AddAddress(addr, 2 * 60 * 60);
pfrom->AddAddressKnown(addr);
- if (!pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
+ if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
{
// Relay to a limited number of other nodes
CRITICAL_BLOCK(cs_vNodes)
multimap<uint256, CNode*> mapMix;
foreach(CNode* pnode, vNodes)
{
+ if (pnode->nVersion < 31402)
+ continue;
unsigned int nPointer;
memcpy(&nPointer, &pnode, sizeof(nPointer));
uint256 hashKey = hashRand ^ nPointer;
if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSend.empty())
pto->PushMessage("ping");
+ // Resend wallet transactions that haven't gotten in a block yet
+ ResendWalletTransactions();
+
// Address refresh broadcast
static int64 nLastRebroadcast;
- if (GetTime() - nLastRebroadcast > 24 * 60 * 60) // every 24 hours
+ if (GetTime() - nLastRebroadcast > 24 * 60 * 60)
{
nLastRebroadcast = GetTime();
CRITICAL_BLOCK(cs_vNodes)
// Rebroadcast our address
if (addrLocalHost.IsRoutable() && !fUseProxy)
- pnode->PushAddress(addrLocalHost);
+ {
+ CAddress addr(addrLocalHost);
+ addr.nTime = GetAdjustedTime();
+ pnode->PushAddress(addr);
+ }
}
}
}
- // Resend wallet transactions that haven't gotten in a block yet
- ResendWalletTransactions();
+ // Clear out old addresses periodically so it's not too much work at once
+ static int64 nLastClear;
+ if (nLastClear == 0)
+ nLastClear = GetTime();
+ if (GetTime() - nLastClear > 10 * 60 && vNodes.size() >= 3)
+ {
+ nLastClear = GetTime();
+ CRITICAL_BLOCK(cs_mapAddresses)
+ {
+ CAddrDB addrdb;
+ int64 nSince = GetAdjustedTime() - 14 * 24 * 60 * 60;
+ for (map<vector<unsigned char>, CAddress>::iterator mi = mapAddresses.begin();
+ mi != mapAddresses.end();)
+ {
+ const CAddress& addr = (*mi).second;
+ if (addr.nTime < nSince)
+ {
+ if (mapAddresses.size() < 1000 || GetTime() > nLastClear + 20)
+ break;
+ addrdb.EraseAddress(addr);
+ mapAddresses.erase(mi++);
+ }
+ else
+ mi++;
+ }
+ }
+ }
//
}
}
closesocket(hSocket);
- if (strLine.find("<"))
+ if (strLine.find("<") != -1)
strLine = strLine.substr(0, strLine.find("<"));
strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
-bool AddAddress(CAddress addr)
+bool AddAddress(CAddress addr, int64 nTimePenalty)
{
if (!addr.IsRoutable())
return false;
if (addr.ip == addrLocalHost.ip)
return false;
+ addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
CRITICAL_BLOCK(cs_mapAddresses)
{
map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
return false;
pnode->fNetworkNode = true;
- if (addrLocalHost.IsRoutable() && !fUseProxy)
- {
- // Advertise our address
- vector<CAddress> vAddr;
- vAddr.push_back(addrLocalHost);
- pnode->PushMessage("addr", vAddr);
- }
-
- // Get as many addresses as we can
- pnode->PushMessage("getaddr");
- pnode->fGetAddr = true; // don't relay the results of the getaddr
-
- ////// should the one on the receiving end do this too?
- // Subscribe our local subscription list
- const unsigned int nHops = 0;
- for (unsigned int nChannel = 0; nChannel < pnodeLocalHost->vfSubscribe.size(); nChannel++)
- if (pnodeLocalHost->vfSubscribe[nChannel])
- pnode->PushMessage("subscribe", nChannel, nHops);
-
return true;
}
bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet);
bool GetMyExternalIP(unsigned int& ipRet);
-bool AddAddress(CAddress addr);
+bool AddAddress(CAddress addr, int64 nTimePenalty=0);
void AddressCurrentlyConnected(const CAddress& addr);
CNode* FindNode(unsigned int ip);
CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
unsigned int ip;
unsigned short port;
- // disk only
+ // disk and network only
unsigned int nTime;
// memory only
memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
ip = INADDR_NONE;
port = GetDefaultPort();
- nTime = GetAdjustedTime();
+ nTime = 100000000;
nLastTry = 0;
}
IMPLEMENT_SERIALIZE
(
+ if (fRead)
+ const_cast<CAddress*>(this)->Init();
if (nType & SER_DISK)
- {
READWRITE(nVersion);
+ if ((nType & SER_DISK) || (nVersion >= 31402 && !(nType & SER_GETHASH)))
READWRITE(nTime);
- }
READWRITE(nServices);
READWRITE(FLATDATA(pchReserved)); // for IPv6
READWRITE(ip);
const char* GetCommand() const
{
if (!IsKnownType())
- throw std::out_of_range(strprintf("CInv::GetCommand() : type=% unknown type", type));
+ throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type));
return ppszTypeName[type];
}
AbortMessage();
}
- const char* GetMessageCommand() const
- {
- if (nHeaderStart == -1)
- return "";
- return &vSend[nHeaderStart] + offsetof(CMessageHeader, pchCommand);
- }
-
return Value::null;
}
+
Value validateaddress(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 1)
class CAutoFile;
static const unsigned int MAX_SIZE = 0x02000000;
-static const int VERSION = 31401;
+static const int VERSION = 31402;
static const char* pszSubVer = "";