2018-08-11 20:27:14 -05:00
|
|
|
// SPDX-License-Identifier: AGPL-1.0-only
|
|
|
|
// Copyright (C) 2018 Ludvig Strigeus <info@tunsafe.com>. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "service_win32_api.h"
|
2018-09-15 11:22:05 -05:00
|
|
|
#include "service_pipe_win32.h"
|
2018-08-11 20:27:14 -05:00
|
|
|
#include "network_win32_api.h"
|
|
|
|
#include "tunsafe_threading.h"
|
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
// Takes care of multiple TunsafeServiceBackend
|
|
|
|
class TunsafeServiceManager : public PipeManager::Delegate {
|
|
|
|
friend class TunsafeServiceBackend;
|
|
|
|
friend class TunsafeServiceServer;
|
2018-08-11 20:27:14 -05:00
|
|
|
public:
|
2018-09-15 11:22:05 -05:00
|
|
|
TunsafeServiceManager();
|
|
|
|
virtual ~TunsafeServiceManager();
|
|
|
|
|
|
|
|
// -- from PipeManager::Delegate
|
|
|
|
virtual void HandleNotify() override;
|
|
|
|
virtual PipeConnection::Delegate *HandleNewConnection(PipeConnection *connection) override;
|
2018-08-11 20:27:14 -05:00
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
// Called by the service control code to bring the service up or down
|
|
|
|
unsigned OnStart(int argc, wchar_t **argv);
|
|
|
|
void OnStop();
|
|
|
|
void OnShutdown();
|
2018-08-11 20:27:14 -05:00
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
TunsafeServiceBackend *main_backend() { return main_backend_; }
|
2018-08-11 20:27:14 -05:00
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
TunsafeServiceBackend *CreateBackend(const char *guid);
|
|
|
|
void DestroyBackend(TunsafeServiceBackend *backend);
|
2018-08-11 20:27:14 -05:00
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
bool SwitchInterface(TunsafeServiceServer *server, const char *interfac, bool want_create);
|
2018-08-11 20:27:14 -05:00
|
|
|
|
|
|
|
private:
|
2018-09-15 11:22:05 -05:00
|
|
|
// Points at the Tunsafe hklm reg key
|
|
|
|
HKEY hkey_;
|
|
|
|
uint32 server_unique_id_;
|
|
|
|
|
|
|
|
PipeManager pipe_manager_;
|
|
|
|
|
|
|
|
TunsafeServiceBackend *main_backend_;
|
|
|
|
std::vector<TunsafeServiceBackend *> backends_;
|
2018-08-11 20:27:14 -05:00
|
|
|
};
|
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
// One of these exist for each TunsafeBackend
|
|
|
|
class TunsafeServiceBackend : public TunsafeBackend::Delegate {
|
|
|
|
friend class TunsafeServiceServer;
|
2018-08-11 20:27:14 -05:00
|
|
|
public:
|
2018-09-15 11:22:05 -05:00
|
|
|
explicit TunsafeServiceBackend(TunsafeServiceManager *manager);
|
|
|
|
virtual ~TunsafeServiceBackend();
|
2018-08-11 20:27:14 -05:00
|
|
|
|
|
|
|
// -- from TunsafeBackend::Delegate
|
2018-09-15 11:22:05 -05:00
|
|
|
virtual void OnGetStats(const WgProcessorStats &stats) override;
|
|
|
|
virtual void OnClearLog() override;
|
|
|
|
virtual void OnLogLine(const char **s) override;
|
|
|
|
virtual void OnStateChanged() override;
|
|
|
|
virtual void OnStatusCode(TunsafeBackend::StatusCode status) override;
|
|
|
|
virtual void OnGraphAvailable() override;
|
|
|
|
virtual void OnConfigurationProtocolReply(uint32 ident, const std::string &&reply) override;
|
|
|
|
|
|
|
|
TunsafeBackend *backend() { return backend_; }
|
2018-08-11 20:27:14 -05:00
|
|
|
TunsafeBackend::Delegate *delegate() { return thread_delegate_; }
|
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
void Start(const char *filename);
|
|
|
|
void RememberLastUsedConfigFile(const char *filename);
|
|
|
|
|
|
|
|
void Stop();
|
|
|
|
|
|
|
|
// Trigger backend stats updates whenever a connected pipe client needs it
|
|
|
|
void UpdateRequestStats();
|
|
|
|
|
|
|
|
// Called by TunsafeServiceManager::HandleNotify to process events
|
|
|
|
// on each backend.
|
|
|
|
void HandleNotify();
|
|
|
|
|
|
|
|
// Send a state update to all connected pipes unless filter is set, then it
|
|
|
|
// sends only to that.
|
|
|
|
void SendStateUpdate(TunsafeServiceServer *filter);
|
|
|
|
|
|
|
|
// Called whenever a pipe server disconnects
|
|
|
|
void RemovePipeServer(TunsafeServiceServer *pipe_server);
|
|
|
|
|
|
|
|
// Called to register a pipe server with this backend
|
|
|
|
void AddPipeServer(TunsafeServiceServer *pipe_server);
|
2018-08-11 20:27:14 -05:00
|
|
|
private:
|
2018-09-15 11:22:05 -05:00
|
|
|
// Points at the service manager
|
|
|
|
TunsafeServiceManager *manager_;
|
|
|
|
|
|
|
|
// Points at the actual TunsafeBackend
|
|
|
|
TunsafeBackend *backend_;
|
|
|
|
|
|
|
|
// Points at all |TunsafeServiceServer| currently associated with this
|
|
|
|
// backend.
|
|
|
|
std::vector<TunsafeServiceServer*> pipe_servers_;
|
|
|
|
|
|
|
|
// Points at the thing that transmits TunsafeBackend events to
|
|
|
|
// the main thread
|
|
|
|
TunsafeBackend::Delegate *thread_delegate_;
|
|
|
|
|
|
|
|
// The config filename that is loaded
|
|
|
|
std::string current_filename_;
|
|
|
|
|
|
|
|
// Positions into |historical_log_lines_|
|
|
|
|
uint32 historical_log_lines_pos_;
|
|
|
|
uint32 historical_log_lines_count_;
|
|
|
|
|
|
|
|
enum { LOGLINE_COUNT = 256 };
|
|
|
|
char *historical_log_lines_[LOGLINE_COUNT];
|
|
|
|
};
|
|
|
|
|
|
|
|
// The server side of the client<->server pipe connection
|
|
|
|
class TunsafeServiceServer : public PipeConnection::Delegate {
|
|
|
|
|
|
|
|
public:
|
|
|
|
TunsafeServiceServer(PipeConnection *pipe, TunsafeServiceBackend *backend, uint32 unique_id);
|
|
|
|
virtual ~TunsafeServiceServer();
|
|
|
|
|
|
|
|
void WritePacket(int type, const uint8 *data, size_t data_size);
|
|
|
|
|
|
|
|
// -- from PipeConnection::Delegate
|
|
|
|
virtual bool HandleMessage(int type, uint8 *data, size_t size) override;
|
|
|
|
virtual void HandleDisconnect() override;
|
|
|
|
|
|
|
|
// Called by TunsafeServiceBackend to push a graph to the client
|
|
|
|
void OnGraphAvailable();
|
|
|
|
|
|
|
|
// Called by TunsafeServiceBackend to push more log lines to the client
|
2018-08-11 20:27:14 -05:00
|
|
|
void SendQueuedLogLines();
|
2018-09-15 11:22:05 -05:00
|
|
|
|
|
|
|
bool want_stats() const { return want_stats_; }
|
|
|
|
bool want_state_updates() const { return want_state_updates_; }
|
|
|
|
uint32 unique_id() const { return unique_id_; }
|
|
|
|
TunsafeServiceBackend *service_backend() { return service_backend_; }
|
|
|
|
void set_service_backend(TunsafeServiceBackend *sb) { service_backend_ = sb; }
|
|
|
|
private:
|
2018-08-11 20:27:14 -05:00
|
|
|
bool AuthenticateUser();
|
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
// Whether the client wants state updates
|
|
|
|
bool want_state_updates_;
|
2018-08-11 20:27:14 -05:00
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
// Whether the client has authenticated
|
2018-08-11 20:27:14 -05:00
|
|
|
bool did_authenticate_user_;
|
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
// Whether we want stats
|
|
|
|
bool want_stats_;
|
2018-08-11 20:27:14 -05:00
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
// Whether the currently connected user wants a graph
|
|
|
|
uint32 want_graph_type_;
|
2018-08-11 20:27:14 -05:00
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
// The last log line sent to the currently connected user
|
2018-08-11 20:27:14 -05:00
|
|
|
uint32 last_line_sent_;
|
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
uint32 unique_id_;
|
|
|
|
|
|
|
|
// The pipe used to communicate
|
|
|
|
PipeConnection *connection_;
|
|
|
|
|
|
|
|
// The backend we're currently associated with
|
|
|
|
TunsafeServiceBackend *service_backend_;
|
2018-08-11 20:27:14 -05:00
|
|
|
};
|
|
|
|
|
2018-09-15 11:22:05 -05:00
|
|
|
|
|
|
|
struct ServiceState {
|
|
|
|
uint8 is_started : 1;
|
2018-10-21 14:53:02 -05:00
|
|
|
uint8 reserved1;
|
|
|
|
uint16 internet_block_state;
|
|
|
|
uint8 reserved[24 + 64];
|
2018-09-15 11:22:05 -05:00
|
|
|
uint32 ipv4_ip;
|
|
|
|
uint8 public_key[32];
|
|
|
|
};
|
|
|
|
|
|
|
|
STATIC_ASSERT(sizeof(ServiceState) == 128, ServiceState_wrong_size);
|
|
|
|
|
|
|
|
class TunsafeServiceClient : public TunsafeBackend, public PipeConnection::Delegate, public PipeManager::Delegate {
|
2018-08-11 20:27:14 -05:00
|
|
|
public:
|
|
|
|
TunsafeServiceClient(TunsafeBackend::Delegate *delegate);
|
|
|
|
virtual ~TunsafeServiceClient();
|
2018-09-15 11:22:05 -05:00
|
|
|
|
|
|
|
// -- from TunsafeBackend
|
|
|
|
virtual bool Configure();
|
2018-08-11 20:27:14 -05:00
|
|
|
virtual void Teardown();
|
2018-09-15 11:22:05 -05:00
|
|
|
virtual bool SetTunAdapterName(const char *name);
|
2018-08-11 20:27:14 -05:00
|
|
|
virtual void Start(const char *config_file);
|
|
|
|
virtual void Stop();
|
|
|
|
virtual void RequestStats(bool enable);
|
|
|
|
virtual void ResetStats();
|
2018-10-21 14:53:02 -05:00
|
|
|
virtual InternetBlockState GetInternetBlockState();
|
2018-08-11 20:27:14 -05:00
|
|
|
virtual void SetInternetBlockState(InternetBlockState s);
|
|
|
|
virtual std::string GetConfigFileName();
|
|
|
|
virtual void SetServiceStartupFlags(uint32 flags);
|
|
|
|
virtual LinearizedGraph *GetGraph(int type);
|
2018-09-15 11:22:05 -05:00
|
|
|
virtual void SendConfigurationProtocolPacket(uint32 identifier, const std::string &&message) override;
|
|
|
|
|
|
|
|
// -- from PipeConnection::Delegate
|
|
|
|
virtual bool HandleMessage(int type, uint8 *data, size_t size) override;
|
|
|
|
virtual void HandleDisconnect() override;
|
|
|
|
|
|
|
|
// -- from PipeManager::Delegate
|
|
|
|
virtual void HandleNotify() override;
|
|
|
|
virtual PipeConnection::Delegate *HandleNewConnection(PipeConnection *connection) override;
|
2018-08-11 20:27:14 -05:00
|
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
TunsafeBackend::Delegate *delegate_;
|
|
|
|
uint8 want_stats_;
|
|
|
|
bool got_state_from_control_;
|
|
|
|
ServiceState service_state_;
|
|
|
|
std::string config_file_;
|
2018-09-15 11:22:05 -05:00
|
|
|
PipeManager pipe_manager_;
|
|
|
|
PipeConnection *connection_;
|
2018-08-11 20:27:14 -05:00
|
|
|
LinearizedGraph *cached_graph_;
|
|
|
|
uint32 last_graph_type_;
|
|
|
|
Mutex mutex_;
|
|
|
|
};
|
2018-09-15 11:22:05 -05:00
|
|
|
|