#ifndef CFILECLIENT_H #define CFILECLIENT_H #include #include "packet_ids.h" #include "../../urbackupcommon/fileclient/tcpstack.h" #include "socket_header.h" #include "../../Interface/Pipe.h" #include "../../Interface/File.h" #include "../../Interface/Mutex.h" #define TCP_PORT 35621 #define UDP_PORT 35622 #define UDP_SOURCE_PORT 35623 #define BUFFERSIZE 32768 #define NBUFFERS 32 #define NUM_FILECLIENTS 5 #define VERSION 36 #define WINDOW_SIZE 512*1024 #define BUFFERSIZE_UDP 4096 //#define DISABLE_WINDOW_SIZE typedef unsigned int _u32; typedef int _i32; typedef unsigned short _u16; typedef __int64 _u64; #define SERVER_TIMEOUT_BACKUPPED 120000 #define SERVER_TIMEOUT 120000 #define LOG class CRData; class FileClient { public: class ReconnectionCallback { public: virtual IPipe * new_fileclient_connection(void)=0; }; class NoFreeSpaceCallback { public: virtual bool handle_not_enough_space(const std::string &path)=0; }; enum MetadataQueue { MetadataQueue_Data, MetadataQueue_Metadata, MetadataQueue_MetadataAndHash }; class QueueCallback { public: virtual std::string getQueuedFileFull(MetadataQueue& metadata, size_t& folder_items, bool& finish_script, int64& file_id) = 0; virtual void unqueueFileFull(const std::string& fn, bool finish_script) = 0; virtual void resetQueueFull() = 0; }; class ProgressLogCallback { public: virtual void log_progress(const std::string& fn, int64 total, int64 downloaded, int64 speed_bps) = 0; }; FileClient(bool enable_find_servers, std::string identity, int protocol_version=0, bool internet_connection=false, FileClient::ReconnectionCallback *reconnection_callback=NULL, FileClient::NoFreeSpaceCallback *nofreespace_callback=NULL); ~FileClient(void); _u32 GetServers(bool start, const std::vector &addr_hints); std::vector getServers(void); std::vector getWrongVersionServers(void); std::vector getServerNames(void); _u32 getLocalIP(void); void setServerName(std::string pName); std::string getServerName(void); int getMaxVersion(void); bool isConnected(void); bool ListDownloaded(void); _u32 Connect(sockaddr_in *addr=NULL); _u32 Connect(IPipe *cp); void Shutdown(); //---needs Connection _u32 GetFile(std::string remotefn, IFsFile *file, bool hashed, bool metadata_only, size_t folder_items, bool is_script, size_t file_id); _u32 GetFileHashAndMetadata(std::string remotefn, std::string& hash, std::string& permissions, int64& filesize, int64& created, int64& modified); _u32 InformMetadataStreamEnd(const std::string& server_token, int tries); _u32 FinishScript(std::string remotefn); void addThrottler(IPipeThrottler *throttler); _i64 getTransferredBytes(void); _i64 getRealTransferredBytes(); _i64 getReceivedDataBytes(bool with_sparse); void resetReceivedDataBytes(bool with_sparse); static std::string getErrorString(_u32 ec); void setReconnectionTimeout(unsigned int t); void setQueueCallback(FileClient::QueueCallback* cb); void setProgressLogCallback(FileClient::ProgressLogCallback* cb); FileClient::ProgressLogCallback* getProgressLogCallback(); void setNoFreeSpaceCallback(FileClient::NoFreeSpaceCallback* cb); _u32 Flush(); bool Reconnect(void); bool isDownloading(); IFile* releaseSparseExtendsFile(); void resetSparseExtentsFile(); static IFile* temporaryFileRetry(); static bool writeFileRetry(IFile* f, const char* buf, _u32 bsize); void setReconnectTries(int tries); private: int getReconnectTriesDecr(); void bindToNewInterfaces(); void fillQueue(); void logProgress(const std::string& remotefn, _u64 filesize, _u64 received); std::vector udpsocks; std::vector broadcast_addrs; std::vector<_u32> broadcast_iface_addrs; IPipe *tcpsock; int64 starttime; int64 connect_starttime; bool socket_open; bool connected; char buffer[BUFFERSIZE_UDP]; sockaddr_in serveraddr; std::vector servers; std::vector wvservers; std::vector servernames; std::vector games; CTCPStack stack; _u32 local_ip; std::string mServerName; int max_version; sockaddr_in server_addr; int connection_id; int protocol_version; bool internet_connection; _i64 real_transferred_bytes; _i64 transferred_bytes; std::vector throttlers; FileClient::ReconnectionCallback *reconnection_callback; FileClient::NoFreeSpaceCallback *nofreespace_callback; FileClient::QueueCallback* queue_callback; unsigned int reconnection_timeout; bool retryBindToNewInterfaces; std::string identity; _i64 received_data_bytes; IMutex* mutex; struct SQueueItem { SQueueItem(std::string fn, bool finish_script) : fn(fn), finish_script(finish_script) { } std::string fn; bool finish_script; }; std::deque queued; char dl_buf[BUFFERSIZE]; size_t dl_off; int64 last_transferred_bytes; int64 last_progress_log; FileClient::ProgressLogCallback* progress_log_callback; bool needs_flush; bool is_downloading; IFile* sparse_extends_f; _i64 sparse_bytes; int reconnect_tries; }; const _u32 ERR_CONTINUE=0; const _u32 ERR_SUCCESS=1; const _u32 ERR_TIMEOUT=2; const _u32 ERR_CANNOT_OPEN_FILE=3; const _u32 ERR_SOCKET_ERROR=4; const _u32 ERR_CONNECTED=5; const _u32 ERR_ERROR=6; const _u32 ERR_BASE_DIR_LOST=7; const _u32 ERR_HASH=8; const _u32 ERR_INT_ERROR=9; const _u32 ERR_CONN_LOST=10; const _u32 ERR_ERRORCODES=11; const _u32 ERR_READ_ERROR = 12; const _u32 sleeptime=50; #endif