136 lines
6.9 KiB
C
136 lines
6.9 KiB
C
#ifndef _WG_OBFUSCATOR_H_
|
|
#define _WG_OBFUSCATOR_H_
|
|
|
|
#include <arpa/inet.h>
|
|
#include <errno.h>
|
|
#include <stdint.h>
|
|
#include <sys/types.h>
|
|
#include "uthash.h"
|
|
|
|
// on Linux, use epoll for better performance
|
|
#ifdef __linux__
|
|
#define USE_EPOLL
|
|
#endif
|
|
|
|
#ifdef USE_EPOLL
|
|
#include <sys/epoll.h>
|
|
#define MAX_EVENTS 1024
|
|
#else
|
|
#include <poll.h>
|
|
#endif
|
|
|
|
#define WG_OBFUSCATOR_VERSION "1.6"
|
|
#define WG_OBFUSCATOR_GIT_REPO "https://github.com/ClusterM/wg-obfuscator"
|
|
|
|
#define LL_DEFAULT LL_INFO // default logging level
|
|
|
|
// Main parameters
|
|
// TODO: make these configurable via command line arguments or config file
|
|
#define BUFFER_SIZE 65535 // size of the buffer for receiving data from the clients and server
|
|
#define PREBUFFER_SIZE 1024 // size of the additional buffer size before the main buffer
|
|
#define POLL_TIMEOUT 5000 // in milliseconds
|
|
#define HANDSHAKE_TIMEOUT 5000 // in milliseconds
|
|
#define ITERATE_INTERVAL 1000 // in milliseconds
|
|
#define MAX_DUMMY_LENGTH_TOTAL 1024 // maximum length of a packet after dummy data extension
|
|
#define MAX_DUMMY_LENGTH_HANDSHAKE 512 // maximum length of dummy data for handshake packets
|
|
|
|
#define MAX_CLIENTS_DEFAULT 1024 // maximum number of clients
|
|
#define IDLE_TIMEOUT_DEFAULT 300000 // in milliseconds
|
|
#define IN_TIMEOUT_DEFAULT 0 // in milliseconds
|
|
#define MAX_DUMMY_LENGTH_DATA_DEFAULT 4 // maximum length of dummy data for data packets
|
|
|
|
// Default instance name
|
|
#define DEFAULT_INSTANCE_NAME "main"
|
|
|
|
// Logging levels
|
|
#define LL_ERROR 0
|
|
#define LL_WARN 1
|
|
#define LL_INFO 2
|
|
#define LL_DEBUG 3
|
|
#define LL_TRACE 4
|
|
|
|
// Maximum length of a single log line, longer hex dumps are split into several lines
|
|
#define LOG_LINE_MAX 16384
|
|
|
|
#define log(level, fmt, ...) do { if (verbose >= (level)) log_printf((level), fmt, ##__VA_ARGS__); } while (0)
|
|
#define serror_level(level, fmt, ...) log(level, fmt " - %s (%d)", ##__VA_ARGS__, strerror(errno), errno)
|
|
#define serror(fmt, ...) serror_level(LL_ERROR, fmt, ##__VA_ARGS__)
|
|
|
|
// Direction of... something
|
|
typedef enum {
|
|
DIR_CLIENT_TO_SERVER = 0,
|
|
DIR_SERVER_TO_CLIENT = 1,
|
|
} direction_t;
|
|
|
|
struct masking_handler; // forward declaration
|
|
typedef struct masking_handler masking_handler_t;
|
|
|
|
// Structure to hold obfuscator configuration
|
|
typedef struct {
|
|
int listen_port; // Listening port for the obfuscator
|
|
char forward_host_port[256]; // Host and port to forward the data to
|
|
char xor_key[256]; // Key for obfuscation
|
|
char client_interface[256]; // Client interface as a string
|
|
char *static_bindings; // Static bindings as a string
|
|
int max_clients; // Maximum number of clients
|
|
long idle_timeout; // Idle timeout in milliseconds
|
|
long in_timeout; // Incoming timeout in milliseconds
|
|
int max_dummy_length_data; // Maximum length of dummy data for data packets
|
|
uint32_t fwmark; // Firewall mark
|
|
masking_handler_t *masking_handler; // Masking handler to use
|
|
uint8_t allow_clean; // 1 if non-obfuscated (clean) clients are allowed, 0 otherwise
|
|
char log_file[512]; // Path of the log file
|
|
int8_t log_timestamps; // 1 to force timestamps on, 0 to force them off, -1 for auto
|
|
long resolve_interval; // Hostname re-resolve interval in milliseconds, 0 to disable periodic refresh
|
|
|
|
uint8_t log_file_set; // 1 if the log file is set, 0 otherwise
|
|
uint8_t listen_port_set; // 1 if the listen port is set, 0 otherwise
|
|
uint8_t forward_host_port_set; // 1 if the forward host and port are set, 0 otherwise
|
|
uint8_t xor_key_set; // 1 if the XOR key is set, 0 otherwise
|
|
uint8_t client_interface_set; // 1 if the client interface is set, 0 otherwise
|
|
uint8_t static_bindings_set; // 1 if the static bindings are set, 0 otherwise
|
|
uint8_t masking_handler_set; // 1 if the masking handler is set, 0 otherwise
|
|
} obfuscator_config_t;
|
|
|
|
// Structure to hold client connection information
|
|
typedef struct {
|
|
struct sockaddr_in client_addr; // client address and port (key for the hash table)
|
|
struct sockaddr_in our_addr; // our address and port on the server connection
|
|
long last_activity_time; // last time we received data from/to this client
|
|
long last_incoming_time; // last time we received data from the remote server
|
|
long last_handshake_request_time; // last time we received a handshake request from/to this client
|
|
long last_handshake_time; // last time we received a handshake response from/to this client
|
|
long last_masking_timer_time; // last time we called the masking timer handler for this client
|
|
int server_sock; // socket for the connection to the server
|
|
uint8_t version; // obfuscation version
|
|
masking_handler_t *masking_handler; // masking handler in use
|
|
uint8_t handshaked : 1; // 1 if the handshake is complete, 0 otherwise
|
|
uint8_t handshake_direction : 1; // 1 if the handshake is from client to server, 0 if from server to client
|
|
uint8_t client_obfuscated : 1; // 1 if the client is obfuscated, 0 otherwise
|
|
uint8_t server_obfuscated : 1; // 1 if the server is obfuscated, 0 otherwise
|
|
uint8_t client_clean : 1; // 1 if the client speaks plain (non-obfuscated) WireGuard, traffic is passed through as is (allow-clean mode)
|
|
uint8_t is_static : 1; // 1 if this is a static binding entry, 0 otherwise
|
|
char bind_host[256]; // Original hostname of a static binding, empty if the address is a literal or the entry is dynamic
|
|
UT_hash_handle hh;
|
|
} client_entry_t;
|
|
|
|
// Verbosity level
|
|
extern int verbose;
|
|
// Section name (for multiple instances)
|
|
extern char section_name[256];
|
|
|
|
const char *version_string(void);
|
|
void print_version(void);
|
|
void register_child_instance(pid_t pid);
|
|
|
|
void log_init(const char *path, int8_t timestamps_mode);
|
|
void log_reopen(void);
|
|
#ifdef __GNUC__
|
|
void log_printf(int level, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
|
|
#else
|
|
void log_printf(int level, const char *fmt, ...);
|
|
#endif
|
|
void log_hexdump(int level, const char *prefix, const uint8_t *data, int length);
|
|
|
|
#endif
|