RetroShare/libretroshare/src/ft/ftfilecreator.h
csoler 8bfc74485a First implementation of per-chunk CRC32 check. This is triggered
- by the right-click+Force Check on files.
- when a global hash on a downloaded file does not match the announced hash.

When a CRC map check is ordered, the CRC map is requested to one of the sources for the current file download.
When received, all downloaded chunks are checked w.r.t the reference CRC and marked as not done if the CRCs do not match.
The exchange of CRC32 map and requests has been tested, as well as CRC map checking during download (force check).

To be implemented soon:
    - caching of CRC32 maps (although these are fast to compute)
    - CRC32 map packets for normal downloads. For now these work only for turtle tunnels.
    - handling of errors if the CRC never comes. For now, the download will stay stuck in "Checking..." mode.

So, don't play too much with the force check feature for now...





git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3310 b45a01b8-16f6-495d-af2f-9b41ad6348cc
2010-07-21 23:14:10 +00:00

141 lines
4.8 KiB
C++

/*
* libretroshare/src/ft/ ftfilecreator.h
*
* File Transfer for RetroShare.
*
* Copyright 2008 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef FT_FILE_CREATOR_HEADER
#define FT_FILE_CREATOR_HEADER
/*
* ftFileCreator
*
* TODO: Serialiser Load / Save.
*
*/
#include "ftfileprovider.h"
#include "ftchunkmap.h"
#include <map>
class ftFileCreator: public ftFileProvider
{
public:
ftFileCreator(std::string savepath, uint64_t size, std::string hash);
~ftFileCreator();
/* overloaded from FileProvider */
virtual bool getFileData(uint64_t offset, uint32_t &chunk_size, void *data);
bool finished() ;
uint64_t getRecvd();
/// (temporarily) close the file, to save file descriptors.
void closeFile() ;
void getChunkMap(FileChunksInfo& info) ;
void setChunkStrategy(FileChunksInfo::ChunkStrategy s) ;
FileChunksInfo::ChunkStrategy getChunkStrategy() ;
// Computes a sha1sum of the partial file, to check that the data is overall consistent.
// This function is not mutexed. This is a bit dangerous, but otherwise we might stuck the GUI for a
// long time. Therefore, we must pay attention not to call this function
// at a time file_name nor hash can be modified, which is quite easy.
bool hashReceivedData(std::string& hash) ;
// Checks the CRC32 of all chunks against the given CRC32 map. Re-flag the bad chunks as being void.
// bad_chunks: count of achieved chunks that don't match the CRC
// incomplete_chunks: count of any bad or not yet downloaded chunk
//
bool crossCheckChunkMap(const CRC32Map& ref,uint32_t& bad_chunks,uint32_t& incomplete_chunks) ;
/*
* creation functions for FileCreator
*/
// Gets a new variable-sized chunk of size "size_hint" from the given peer id. The returned size, "size" is
// at most equal to size_hint. chunk_map_needed is set if
// - no chunkmap info is available. In such a case, the chunk info is irrelevant and false is returned.
// - the chunk info is too old. In tis case, true is returned, and the chunks info can be used.
//
bool getMissingChunk(const std::string& peer_id,uint32_t size_hint,uint64_t& offset, uint32_t& size,bool& is_chunk_map_too_old);
// Takes care of purging any inactive chunks. This should be called regularly, because some peers may disconnect
// and let inactive chunks not finished.
//
void removeInactiveChunks() ;
// removes the designated file source from the chunkmap.
void removeFileSource(const std::string& peer_id) ;
// Returns resets the time stamp of the last data receive.
time_t lastRecvTimeStamp() ;
void resetRecvTimeStamp() ;
// actually store data in the file, and update chunks info
//
bool addFileData(uint64_t offset, uint32_t chunk_size, void *data);
// Load/save the availability map for the file being downloaded, in a compact/compressed form.
// This is used for
// - loading and saving info about the current transfers
// - getting info about current chunks for the GUI
// - sending availability info to the peers for which we also are a source
//
virtual void getAvailabilityMap(CompressedChunkMap& cmap) ;
void setAvailabilityMap(const CompressedChunkMap& cmap) ;
// Provides a complete per-chunk CRC32 map to client who want to check their data.
// This is overloads ftFileProvider, but returns false, because we can't ensure that unchecked chunks
// will provide a CRC32 that is faithful to the original hash.
//
virtual bool getCRC32Map(CRC32Map& crc_map) { return false ; }
// This is called when receiving the availability map from a source peer, for the file being handled.
//
void setSourceMap(const std::string& peer_id,const CompressedChunkMap& map) ;
protected:
virtual int locked_initializeFileAttrs();
private:
bool locked_printChunkMap();
int locked_notifyReceived(uint64_t offset, uint32_t chunk_size);
/*
* structure to track missing chunks
*/
uint64_t mStart;
uint64_t mEnd;
std::map<uint64_t, ftChunk> mChunks;
ChunkMap chunkMap ;
time_t _last_recv_time_t ; /// last time stamp when data was received.
};
#endif // FT_FILE_CREATOR_HEADER