@ -1942,3 +1942,103 @@ void CNode::Fuzz(int nChance)
// (more changes exponentially less likely):
// (more changes exponentially less likely):
Fuzz ( 2 ) ;
Fuzz ( 2 ) ;
}
}
//
// CAddrDB
//
CAddrDB : : CAddrDB ( )
{
pathAddr = GetDataDir ( ) / " peers.dat " ;
}
bool CAddrDB : : Write ( const CAddrMan & addr )
{
// Generate random temporary filename
unsigned short randv = 0 ;
RAND_bytes ( ( unsigned char * ) & randv , sizeof ( randv ) ) ;
std : : string tmpfn = strprintf ( " peers.dat.%04x " , randv ) ;
// serialize addresses, checksum data up to that point, then append csum
CDataStream ssPeers ( SER_DISK , CLIENT_VERSION ) ;
ssPeers < < FLATDATA ( Params ( ) . MessageStart ( ) ) ;
ssPeers < < addr ;
uint256 hash = Hash ( ssPeers . begin ( ) , ssPeers . end ( ) ) ;
ssPeers < < hash ;
// open temp output file, and associate with CAutoFile
boost : : filesystem : : path pathTmp = GetDataDir ( ) / tmpfn ;
FILE * file = fopen ( pathTmp . string ( ) . c_str ( ) , " wb " ) ;
CAutoFile fileout = CAutoFile ( file , SER_DISK , CLIENT_VERSION ) ;
if ( ! fileout )
return error ( " CAddrman::Write() : open failed " ) ;
// Write and commit header, data
try {
fileout < < ssPeers ;
}
catch ( std : : exception & e ) {
return error ( " CAddrman::Write() : I / O error " ) ;
}
FileCommit ( fileout ) ;
fileout . fclose ( ) ;
// replace existing peers.dat, if any, with new peers.dat.XXXX
if ( ! RenameOver ( pathTmp , pathAddr ) )
return error ( " CAddrman::Write() : Rename - into - place failed " ) ;
return true ;
}
bool CAddrDB : : Read ( CAddrMan & addr )
{
// open input file, and associate with CAutoFile
FILE * file = fopen ( pathAddr . string ( ) . c_str ( ) , " rb " ) ;
CAutoFile filein = CAutoFile ( file , SER_DISK , CLIENT_VERSION ) ;
if ( ! filein )
return error ( " CAddrman::Read() : open failed " ) ;
// use file size to size memory buffer
int fileSize = GetFilesize ( filein ) ;
int dataSize = fileSize - sizeof ( uint256 ) ;
//Don't try to resize to a negative number if file is small
if ( dataSize < 0 ) dataSize = 0 ;
vector < unsigned char > vchData ;
vchData . resize ( dataSize ) ;
uint256 hashIn ;
// read data and checksum from file
try {
filein . read ( ( char * ) & vchData [ 0 ] , dataSize ) ;
filein > > hashIn ;
}
catch ( std : : exception & e ) {
return error ( " CAddrman::Read() 2 : I / O error or stream data corrupted " ) ;
}
filein . fclose ( ) ;
CDataStream ssPeers ( vchData , SER_DISK , CLIENT_VERSION ) ;
// verify stored checksum matches input data
uint256 hashTmp = Hash ( ssPeers . begin ( ) , ssPeers . end ( ) ) ;
if ( hashIn ! = hashTmp )
return error ( " CAddrman::Read() : checksum mismatch ; data corrupted " );
unsigned char pchMsgTmp [ 4 ] ;
try {
// de-serialize file header (network specific magic number) and ..
ssPeers > > FLATDATA ( pchMsgTmp ) ;
// ... verify the network matches ours
if ( memcmp ( pchMsgTmp , Params ( ) . MessageStart ( ) , sizeof ( pchMsgTmp ) ) )
return error ( " CAddrman::Read() : invalid network magic number " ) ;
// de-serialize address data into one CAddrMan object
ssPeers > > addr ;
}
catch ( std : : exception & e ) {
return error ( " CAddrman::Read() : I / O error or stream data corrupted " ) ;
}
return true ;
}