mirror of
https://github.com/uroni/urbackup_backend.git
synced 2025-10-26 11:36:50 +00:00
493 lines
14 KiB
C++
493 lines
14 KiB
C++
#pragma once
|
|
|
|
#include "../Interface/Thread.h"
|
|
#include "../Interface/Database.h"
|
|
#include "../Interface/Query.h"
|
|
#include "../Interface/SettingsReader.h"
|
|
#include "../Interface/Mutex.h"
|
|
#include "../Interface/ThreadPool.h"
|
|
#include "../urlplugin/IUrlFactory.h"
|
|
#include "../urbackupcommon/fileclient/FileClient.h"
|
|
#include "../urbackupcommon/fileclient/FileClientChunked.h"
|
|
#include "../urbackupcommon/os_functions.h"
|
|
#include "server_hash.h"
|
|
#include "server_prepare_hash.h"
|
|
#include "server_status.h"
|
|
#include "../urbackupcommon/sha2/sha2.h"
|
|
#include "../urbackupcommon/fileclient/tcpstack.h"
|
|
#include "server_settings.h"
|
|
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include "server_log.h"
|
|
|
|
class ServerVHDWriter;
|
|
class IFile;
|
|
class IPipe;
|
|
class ServerPingThread;
|
|
class FileClient;
|
|
class IPipeThrottler;
|
|
class BackupServerContinuous;
|
|
class ContinuousBackup;
|
|
class Backup;
|
|
class ServerBackupDao;
|
|
class ImageBackup;
|
|
class ServerChannelThread;
|
|
class IECDHKeyExchange;
|
|
class IECIESDecryption;
|
|
|
|
const int c_group_default = 0;
|
|
const int c_group_continuous = 1;
|
|
const int c_group_max = 99;
|
|
const int c_group_size = 100;
|
|
|
|
struct SProtocolVersions
|
|
{
|
|
SProtocolVersions() :
|
|
filesrv_protocol_version(0), file_protocol_version(0),
|
|
file_protocol_version_v2(0), set_settings_version(0),
|
|
image_protocol_version(0), eta_version(0), cdp_version(0),
|
|
efi_version(0), file_meta(0), select_sha_version(0),
|
|
client_bitmap_version(0), cmd_version(0),
|
|
symbit_version(0), phash_version(0),
|
|
wtokens_version(0), update_vols(0),
|
|
update_capa_interval(0), require_previous_cbitmap(0),
|
|
async_index_version(0), restore_version(0),
|
|
filesrvtunnel(0)
|
|
{
|
|
|
|
}
|
|
|
|
int filesrv_protocol_version;
|
|
int file_protocol_version;
|
|
int file_protocol_version_v2;
|
|
int set_settings_version;
|
|
int image_protocol_version;
|
|
int eta_version;
|
|
int cdp_version;
|
|
int efi_version;
|
|
int file_meta;
|
|
int select_sha_version;
|
|
int client_bitmap_version;
|
|
int cmd_version;
|
|
int require_previous_cbitmap;
|
|
int async_index_version;
|
|
int symbit_version;
|
|
int phash_version;
|
|
int wtokens_version;
|
|
int update_vols;
|
|
int update_capa_interval;
|
|
std::string os_simple;
|
|
int restore_version;
|
|
int filesrvtunnel;
|
|
};
|
|
|
|
struct SRunningBackup
|
|
{
|
|
SRunningBackup()
|
|
: backup(NULL), ticket(ILLEGAL_THREADPOOL_TICKET),
|
|
group(c_group_default), running(false)
|
|
{
|
|
|
|
}
|
|
|
|
|
|
Backup* backup;
|
|
bool running;
|
|
THREADPOOL_TICKET ticket;
|
|
int group;
|
|
std::string letter;
|
|
};
|
|
|
|
struct SRunningRestore
|
|
{
|
|
SRunningRestore(std::string restore_identity, logid_t log_id, int64 status_id, int64 restore_id)
|
|
: restore_identity(restore_identity), log_id(log_id), status_id(status_id), restore_id(restore_id),
|
|
last_active(Server->getTimeMS())
|
|
{}
|
|
|
|
std::string restore_identity;
|
|
logid_t log_id;
|
|
int64 status_id;
|
|
int64 restore_id;
|
|
int64 last_active;
|
|
};
|
|
|
|
struct SRunningLocalBackup
|
|
{
|
|
SRunningLocalBackup(logid_t log_id, int64 status_id, int backupid)
|
|
: log_id(log_id), status_id(status_id), backupid(backupid),
|
|
last_active(Server->getTimeMS())
|
|
{}
|
|
|
|
logid_t log_id;
|
|
int64 status_id;
|
|
int backupid;
|
|
int64 last_active;
|
|
};
|
|
|
|
struct SShareCleanup
|
|
{
|
|
SShareCleanup(std::string name, std::string identity, bool cleanup_file, bool remove_callback)
|
|
: name(name), identity(identity), cleanup_file(cleanup_file), remove_callback(remove_callback)
|
|
{
|
|
|
|
}
|
|
|
|
std::string name;
|
|
std::string identity;
|
|
bool cleanup_file;
|
|
bool remove_callback;
|
|
};
|
|
|
|
namespace
|
|
{
|
|
const int CAPA_NO_IMAGE_BACKUPS = 1;
|
|
}
|
|
|
|
class ClientMain : public IThread, public FileClientChunked::ReconnectionCallback,
|
|
public FileClient::ReconnectionCallback, public INotEnoughSpaceCallback,
|
|
public FileClient::NoFreeSpaceCallback, public FileClientChunked::NoFreeSpaceCallback,
|
|
public FileClient::ProgressLogCallback
|
|
{
|
|
public:
|
|
ClientMain(IPipe *pPipe, FileClient::SAddrHint pAddr, const std::string &pName, const std::string& pSubName, const std::string& pMainName, int filebackup_group_offset,
|
|
bool internet_connection, bool use_file_snapshots, bool use_image_snapshots, bool use_reflink);
|
|
~ClientMain(void);
|
|
|
|
void operator()(void);
|
|
|
|
bool authenticateIfNeeded(bool retry_exit, bool force);
|
|
|
|
struct SConnection
|
|
{
|
|
SConnection()
|
|
: conn(),
|
|
internet_connection(false)
|
|
{}
|
|
|
|
std::unique_ptr<IPipe> conn;
|
|
bool internet_connection;
|
|
};
|
|
|
|
bool sendClientMessage(const std::string &msg, const std::string &retok, const std::string &errmsg, unsigned int timeout, bool logerr=true, int max_loglevel=LL_ERROR, bool *retok_err=NULL, std::string* retok_str=NULL, SConnection* conn=NULL, bool do_encrypt = true);
|
|
bool sendClientMessageRetry(const std::string &msg, const std::string &retok, const std::string &errmsg, unsigned int timeout, size_t retry=0, bool logerr=true, int max_loglevel=LL_ERROR, bool *retok_err=NULL, std::string* retok_str=NULL, bool do_encrypt = true);
|
|
std::string sendClientMessage(const std::string &msg, const std::string &errmsg, unsigned int timeout, bool logerr=true, int max_loglevel=LL_ERROR, SConnection* conn=NULL, bool do_encrypt = true);
|
|
std::string sendClientMessageRetry(const std::string &msg, const std::string &errmsg, unsigned int timeout, size_t retry=0, bool logerr=true, int max_loglevel=LL_ERROR, unsigned int timeout_after_first=0, bool do_encrypt=true);
|
|
void sendToPipe(const std::string &msg);
|
|
|
|
bool createDirectoryForClient();
|
|
|
|
FileClient::SAddrHint getClientaddr(void);
|
|
|
|
static void init_mutex(void);
|
|
static void destroy_mutex(void);
|
|
|
|
static MailServer getMailServerSettings(void);
|
|
static bool sendMailToAdmins(const std::string& subj, const std::string& message);
|
|
|
|
static int getNumberOfRunningBackups(void);
|
|
static int getNumberOfRunningFileBackups(void);
|
|
static bool tooManyClients(IDatabase *db, const std::string &clientname, ServerSettings *server_settings);
|
|
static int getClientID(IDatabase *db, const std::string &clientname, ServerSettings *server_settings,
|
|
bool *new_client, std::string* authkey=NULL, int* client_group=NULL, std::string* perm_uid=NULL);
|
|
|
|
IPipe *getClientCommandConnection(ServerSettings* server_settings, int timeoutms=10000, std::string* clientaddr=NULL, bool do_encrypt=true);
|
|
|
|
virtual IPipe * new_fileclient_connection(void);
|
|
|
|
virtual bool handle_not_enough_space(const std::string &path);
|
|
|
|
virtual bool handle_not_enough_space(const std::string &path, logid_t logid);
|
|
|
|
static IFsFile *getTemporaryFileRetry(bool use_tmpfiles, const std::string& tmpfile_path, logid_t logid);
|
|
|
|
static void destroyTemporaryFile(IFile *tmp);
|
|
|
|
|
|
|
|
virtual void log_progress( const std::string& fn, int64 total, int64 downloaded, int64 speed_bps );
|
|
|
|
_u32 getClientFilesrvConnection(FileClient *fc, ServerSettings* server_settings, int timeoutms=10000);
|
|
|
|
bool getClientChunkedFilesrvConnection(std::unique_ptr<FileClientChunked>& fc_chunked,
|
|
ServerSettings* server_settings, FileClientChunked::NoFreeSpaceCallback* no_free_space_callback, int timeoutms=10000);
|
|
|
|
bool isOnInternetConnection()
|
|
{
|
|
return internet_connection;
|
|
}
|
|
|
|
SProtocolVersions getProtocolVersions()
|
|
{
|
|
return protocol_versions;
|
|
}
|
|
|
|
void refreshSessionIdentity()
|
|
{
|
|
IScopedLock lock(clientaddr_mutex);
|
|
session_identity_refreshtime = Server->getTimeMS();
|
|
}
|
|
|
|
std::string getIdentity();
|
|
|
|
std::string getSecretSessionKey();
|
|
|
|
std::string getSessionCompression(int& level);
|
|
|
|
int getCurrImageVersion()
|
|
{
|
|
return curr_image_version;
|
|
}
|
|
|
|
static bool run_script(std::string name, const std::string& params, logid_t logid);
|
|
|
|
void stopBackupRunning(bool file);
|
|
|
|
void updateClientAddress(const std::string& address_data);
|
|
|
|
IPipe* getInternalCommandPipe()
|
|
{
|
|
return pipe;
|
|
}
|
|
|
|
void setContinuousBackup(BackupServerContinuous* cb);
|
|
|
|
void addContinuousChanges( const std::string& changes );
|
|
|
|
static void addShareToCleanup(int clientid, const SShareCleanup& cleanupData);
|
|
|
|
static void cleanupRestoreShare(int clientid, std::string restore_identity);
|
|
|
|
void updateLocalBackup(int64 status_id, bool success, bool should_backoff);
|
|
|
|
bool removeRestore(int64 restore_id);
|
|
|
|
bool removeLocalBackup(int64 status_id);
|
|
|
|
bool updateRestoreRunning(int64 restore_id);
|
|
|
|
bool updateLocalBackupRunning(int backupid);
|
|
|
|
static bool startBackupBarrier(int64 timeout_seconds);
|
|
|
|
static void stopBackupBarrier();
|
|
|
|
void updateCapa();
|
|
|
|
std::vector<SLogEntry> parseLogData(int64 max_duration, const std::string& data);
|
|
|
|
bool isDataplanOkay(ServerSettings* local_settings, bool file);
|
|
|
|
static std::string getClientIpStr(const std::string& clientname);
|
|
|
|
void setConnectionMetered(bool b);
|
|
|
|
void setWindowsLocked(bool b);
|
|
|
|
void forceReauthenticate();
|
|
|
|
static std::string normalizeVolumeUpper(std::string volume);
|
|
|
|
std::vector<std::string> getAllowRestoreClients()
|
|
{
|
|
IScopedLock lock(clientaddr_mutex);
|
|
return allow_restore_clients;
|
|
}
|
|
|
|
static void wakeupClientUidReset();
|
|
|
|
private:
|
|
void unloadSQL(void);
|
|
void prepareSQL(void);
|
|
void updateLastseen(int64 lastseen);
|
|
bool isUpdateFull(int tgroup);
|
|
bool isUpdateIncr(int tgroup);
|
|
bool isUpdateFullImage(void);
|
|
bool isUpdateIncrImage(void);
|
|
bool isUpdateFullImage(const std::string &letter);
|
|
bool isUpdateIncrImage(const std::string &letter);
|
|
void sendClientBackupIncrIntervall(void);
|
|
void sendSettings(void);
|
|
bool getClientSettings(bool& doesnt_exist);
|
|
bool updateClientSetting(const std::string &key, const std::string &value, int use, int64 use_last_modified);
|
|
void sendClientLogdata(void);
|
|
bool isRunningImageBackup(const std::string& letter);
|
|
bool isImageGroupQueued(const std::string& letter, bool full);
|
|
bool isRunningFileBackup(int group, bool queue_only=true);
|
|
void checkClientVersion(void);
|
|
bool sendFile(IPipe *cc, IFile *f, int timeout);
|
|
bool isBackupsRunningOkay(bool file, bool incr=false);
|
|
bool updateCapabilities(bool* needs_restart);
|
|
IPipeThrottler *getThrottler(int speed_bps);
|
|
bool inBackupWindow(Backup* backup);
|
|
void updateClientAccessKey();
|
|
bool isDataplanOkay(bool file);
|
|
bool isOnline(ServerChannelThread& channel_thread);
|
|
|
|
unsigned int exponentialBackoffTime(size_t count, unsigned int sleeptime, unsigned div);
|
|
bool exponentialBackoff(size_t count, int64 lasttime, unsigned int sleeptime, unsigned div);
|
|
unsigned int exponentialBackoffTimeImage();
|
|
unsigned int exponentialBackoffTimeFile();
|
|
bool exponentialBackoffImage();
|
|
bool exponentialBackoffFile();
|
|
bool exponentialBackoffCdp();
|
|
bool pauseRetryBackup();
|
|
|
|
bool sendServerIdentity(bool retry_exit);
|
|
bool authenticatePubKeyInt(IECDHKeyExchange* ecdh_key_exchange);
|
|
bool authenticatePubKey();
|
|
|
|
void timeoutRestores();
|
|
|
|
void timeoutLocalBackups();
|
|
|
|
void cleanupShares();
|
|
static void cleanupShare(SShareCleanup& tocleanup);
|
|
|
|
void finishFailedRestore(std::string restore_identity, logid_t log_id, int64 status_id, int64 restore_id);
|
|
|
|
void finishLocalBackup(bool success, logid_t log_id, int64 status_id, int backupid);
|
|
|
|
bool isLocalBackupRunning(int64 status_id);
|
|
|
|
bool isBackupFinished(const SRunningBackup& rb);
|
|
|
|
bool renameClient(const std::string& clientuid);
|
|
void updateVirtualClients();
|
|
|
|
bool checkClientName(bool& continue_start_backups);
|
|
|
|
|
|
struct SPathComponents
|
|
{
|
|
std::string backupfolder;
|
|
std::string clientname;
|
|
std::string path;
|
|
};
|
|
|
|
SPathComponents extractBackupComponents(const std::string& path, const std::string& backupfolder, const std::vector<std::string>& old_backupfolders);
|
|
std::string curr_image_format;
|
|
|
|
IPipe *pipe;
|
|
IDatabase *db;
|
|
|
|
FileClient::SAddrHint clientaddr;
|
|
IMutex *clientaddr_mutex;
|
|
std::string clientname;
|
|
std::string clientsubname;
|
|
std::string clientmainname;
|
|
int filebackup_group_offset;
|
|
|
|
std::string tmpfile_path;
|
|
static size_t tmpfile_num;
|
|
static IMutex *tmpfile_mutex;
|
|
|
|
int clientid;
|
|
std::string perm_uid;
|
|
|
|
std::unique_ptr<ServerSettings> server_settings;
|
|
|
|
IQuery *q_update_lastseen;
|
|
IQuery *q_update_setting;
|
|
IQuery *q_get_setting;
|
|
IQuery *q_insert_setting;
|
|
IQuery *q_get_unsent_logdata;
|
|
IQuery *q_set_logdata_sent;
|
|
|
|
bool can_backup_images;
|
|
|
|
bool do_full_backup_now;
|
|
bool do_incr_backup_now;
|
|
bool do_update_settings;
|
|
bool do_full_image_now;
|
|
bool do_incr_image_now;
|
|
bool do_update_access_key;
|
|
bool cdp_needs_sync;
|
|
|
|
static int running_backups;
|
|
static int running_file_backups;
|
|
static IMutex *running_backup_mutex;
|
|
|
|
SProtocolVersions protocol_versions;
|
|
volatile bool internet_connection;
|
|
volatile bool connection_metered;
|
|
std::atomic<bool> windows_locked;
|
|
int update_version;
|
|
std::string all_volumes;
|
|
std::string all_nonusb_volumes;
|
|
|
|
bool use_file_snapshots;
|
|
bool use_image_snapshots;
|
|
bool use_reflink;
|
|
bool use_tmpfiles;
|
|
bool use_tmpfiles_images;
|
|
|
|
CTCPStack tcpstack;
|
|
CTCPStack tcpstack_checksum;
|
|
|
|
IMutex* throttle_mutex;
|
|
IPipeThrottler *client_throttler;
|
|
|
|
int64 last_backup_try;
|
|
|
|
int64 last_image_backup_try;
|
|
size_t count_image_backup_try;
|
|
|
|
int64 last_file_backup_try;
|
|
size_t count_file_backup_try;
|
|
|
|
int64 last_cdp_backup_try;
|
|
size_t count_cdp_backup_try;
|
|
|
|
std::string session_identity;
|
|
int64 session_identity_refreshtime;
|
|
std::string secret_session_key;
|
|
std::string session_compressed;
|
|
int session_compression_level;
|
|
|
|
ServerBackupDao* backup_dao;
|
|
|
|
int64 client_updated_time;
|
|
|
|
BackupServerContinuous* continuous_backup;
|
|
IMutex* continuous_mutex;
|
|
|
|
unsigned int curr_image_version;
|
|
|
|
std::vector<SRunningBackup> backup_queue;
|
|
|
|
static IMutex* cleanup_mutex;
|
|
static std::map<int, std::vector<SShareCleanup> > cleanup_shares;
|
|
|
|
logid_t logid;
|
|
static int restore_client_id;
|
|
static bool running_backups_allowed;
|
|
|
|
int last_incr_freq;
|
|
int last_startup_backup_delay;
|
|
|
|
std::string curr_server_token;
|
|
bool needs_authentification;
|
|
|
|
std::unique_ptr<IMutex> restore_mutex;
|
|
std::vector<SRunningRestore> running_restores;
|
|
|
|
std::mutex local_backup_mutex;
|
|
std::vector<SRunningLocalBackup> running_local_backups;
|
|
|
|
std::vector< std::map<ImageBackup*, bool> > running_image_groups;
|
|
|
|
volatile bool update_capa;
|
|
|
|
volatile bool do_reauthenticate;
|
|
|
|
std::vector<std::string> allow_restore_clients;
|
|
|
|
static IMutex* ecdh_key_exchange_mutex;
|
|
static std::vector<std::pair<IECDHKeyExchange*, int64> > ecdh_key_exchange_buffer;
|
|
|
|
static IMutex* client_uid_reset_mutex;
|
|
static ICondition* client_uid_reset_cond;
|
|
};
|