Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions include/vtesse/version.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef VTESSE_VERSION_H
#define VTESSE_VERSION_H

/* MAJOR.MM. Bumping it in a push to main publishes release vMAJOR.MM (CI). */
#define VTESSE_VERSION "1.00"

#endif
55 changes: 55 additions & 0 deletions include/vtesse/vtun_client.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* VTun client (TCP transport, type tun / ether, no compression/encryption).
*
* Non-blocking, single-threaded, no global state. Exposes tunnel_ops_t.
* Name resolution uses getaddrinfo() and may block briefly at connect time.
*/
#ifndef VTESSE_VTUN_CLIENT_H
#define VTESSE_VTUN_CLIENT_H

#include <stdint.h>

#include "netcore/tunnel.h"
#include "vtesse/vtun_proto.h"

enum vt_auth {
VT_AUTH_XOR = 0 /* servers built without OpenSSL */
};

typedef struct vt_cfg {
const char *host;
uint16_t port;
const char *session;
const char *password;
int auth; /* enum vt_auth */

/* Optional tuning; 0 selects the default. */
int handshake_timeout_ms; /* per step, default 15000 (CHAL step >= 10000) */
int ka_interval_ms; /* own ECHO_REQ period, default 10000 */
int ka_count; /* dead after ka_count * interval silence, default 5 */
int data_delay_ms; /* OK FLAGS -> TUNNEL_EV_UP delay, default 500 */
int reconnect_min_ms; /* default 1000 */
int reconnect_max_ms; /* default 30000 */
int out_buffer_size; /* default 65536 */
int no_reconnect; /* 1: report FAILED instead of retrying */
} vt_cfg_t;

typedef struct vt vt_t;

/* Copies the configuration. Returns NULL and sets *err on invalid config / OOM. */
vt_t *vt_create(const vt_cfg_t *cfg, int *err);
void vt_destroy(vt_t *vt);

/* Start connecting (first attempt happens immediately). */
int vt_start(vt_t *vt);

/* Tunnel interface. */
const tunnel_ops_t *vt_tunnel_ops(void);
tunnel_t vt_tunnel(vt_t *vt);

/* Diagnostics. */
const char *vt_greeting(const vt_t *vt); /* last server greeting, "" if none */
const vt_flags_t *vt_session_flags(const vt_t *vt); /* flags of the last session */
int vt_is_up(const vt_t *vt);

#endif
73 changes: 73 additions & 0 deletions include/vtesse/vtun_proto.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* VTun wire format helpers (verified against VTun 3.0.2).
* Pure functions, no I/O, explicit byte order.
*/
#ifndef VTESSE_VTUN_PROTO_H
#define VTESSE_VTUN_PROTO_H

#include <stddef.h>
#include <stdint.h>

#define VT_MESG_SIZE 50 /* every control message, NUL padded */
#define VT_CHAL_SIZE 16
#define VT_CHAL_TEXT_SIZE (VT_CHAL_SIZE * 2 + 3) /* "<" + 32 + ">" + NUL */
#define VT_FRAME_SIZE 2048 /* max payload we send */
#define VT_FRAME_OVERHEAD 100 /* receivers accept up to SIZE + OVERHEAD */
#define VT_FRAME_MAX_RX (VT_FRAME_SIZE + VT_FRAME_OVERHEAD)
#define VT_FSIZE_MASK 0x0fff
#define VT_FLAGS_MASK 0xf000
#define VT_CONN_CLOSE 0x1000
#define VT_ECHO_REQ 0x2000
#define VT_ECHO_REP 0x4000
#define VT_BAD_FRAME 0x8000 /* never on the wire in 3.0.2 */
#define VT_SESSION_MAX 42 /* "HOST: " + name + "\n" must fit 49 bytes */

/* Session names: 1..42 printable characters, no space, ':', control chars. */
int vt_session_name_valid(const char *name);

/* Build "<prefix><arg>\n" padded with NUL to 50 bytes. -1 if longer than 49. */
int vt_mesg_build(uint8_t out[VT_MESG_SIZE], const char *prefix, const char *arg);

/* Challenge text "<" + 32 chars 'a'..'p' + ">" <-> 16 bytes. */
void vt_chal_encode(const uint8_t chal[VT_CHAL_SIZE], char out[VT_CHAL_TEXT_SIZE]);
/* Finds '<' in msg; requires exactly 32 chars 'a'..'p' followed by '>'. 0 on success. */
int vt_chal_decode(const char *msg, uint8_t chal[VT_CHAL_SIZE]);

/* XOR challenge response (servers built without OpenSSL). pwd must be non-empty. */
void vt_chal_xor(uint8_t chal[VT_CHAL_SIZE], const char *pwd);

typedef struct vt_flags {
char transport; /* 'T' or 'U', 0 if absent */
char type; /* 'u' tun, 'e' ether, 't' tty, 'p' pipe, 0 if absent */
int keepalive;
int shaper; /* S<n>, 0 if absent */
int zlib; /* C<n> present */
int lzo; /* L<n> present */
int zlevel;
int encrypt; /* E or E<n> present */
int cipher; /* 0 = legacy */
} vt_flags_t;

/* Parse "OK FLAGS: <...>". Same grammar as VTun cf2bf: unknown characters,
* a missing number after C/L/S or a missing '>' are errors. 0 on success. */
int vt_flags_parse(const char *msg, vt_flags_t *f);

/* Policy check: TCP, type tun or ether, no compression, no encryption.
* Returns TUNNEL_OK or a TUNNEL_ERR_* code. */
int vt_flags_check(const vt_flags_t *f);

/* Format flags back as "<...>" in VTun server order (for logs/tests). */
void vt_flags_format(const vt_flags_t *f, char *out, size_t size);

static inline void vt_hdr_put(uint8_t b[2], uint16_t v)
{
b[0] = (uint8_t)(v >> 8);
b[1] = (uint8_t)v;
}

static inline uint16_t vt_hdr_get(const uint8_t b[2])
{
return (uint16_t)((b[0] << 8) | b[1]);
}

#endif
Loading