Split UdpVpn in -Client and -Server flavour
This commit is contained in:
parent
8b75660bbc
commit
b8bb6d2c5f
8 changed files with 267 additions and 105 deletions
6
Makefile
6
Makefile
|
@ -2,7 +2,11 @@ CXX=g++
|
||||||
CXXFLAGS=-O2 -g -Wall -Wextra -std=c++17
|
CXXFLAGS=-O2 -g -Wall -Wextra -std=c++17
|
||||||
CXXLIBS=
|
CXXLIBS=
|
||||||
|
|
||||||
OBJS=UdpVpn.o VpnPeer.o TunDevice.o ip_header.o util.o main.o
|
OBJS= \
|
||||||
|
UdpVpn.o UdpVpnClient.o UdpVpnServer.o \
|
||||||
|
VpnPeer.o \
|
||||||
|
TunDevice.o \
|
||||||
|
ip_header.o util.o main.o
|
||||||
TARGET=congestvpn
|
TARGET=congestvpn
|
||||||
|
|
||||||
all: $(TARGET)
|
all: $(TARGET)
|
||||||
|
|
84
UdpVpn.cpp
84
UdpVpn.cpp
|
@ -9,12 +9,11 @@
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
UdpVpn::UdpVpn()
|
#include "ip_header.hpp"
|
||||||
: _bound(false), _stopped(false), _has_peer(false), _tun_dev("cvpn%d")
|
|
||||||
{
|
|
||||||
memset(&_serv_addr, 0, sizeof(_serv_addr));
|
|
||||||
memset(&_peer_addr, 0, sizeof(_peer_addr));
|
|
||||||
|
|
||||||
|
UdpVpn::UdpVpn()
|
||||||
|
: _stopped(false), _tun_dev("cvpn%d")
|
||||||
|
{
|
||||||
_socket = socket(AF_INET6, SOCK_DGRAM, 0);
|
_socket = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||||
if(_socket < 0)
|
if(_socket < 0)
|
||||||
throw UdpVpn::InitializationError("Cannot create socket", errno, true);
|
throw UdpVpn::InitializationError("Cannot create socket", errno, true);
|
||||||
|
@ -24,36 +23,6 @@ UdpVpn::~UdpVpn() {
|
||||||
close(_socket);
|
close(_socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UdpVpn::bind(in_port_t port) {
|
|
||||||
bind(in6addr_any, port);
|
|
||||||
}
|
|
||||||
void UdpVpn::bind(const struct in6_addr& bind_addr6, in_port_t port) {
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
_serv_addr.sin6_family = AF_INET6;
|
|
||||||
_serv_addr.sin6_port = htons(port);
|
|
||||||
_serv_addr.sin6_addr = bind_addr6;
|
|
||||||
|
|
||||||
rc = ::bind(
|
|
||||||
_socket, (const struct sockaddr*)&_serv_addr, sizeof(_serv_addr));
|
|
||||||
if(rc < 0) {
|
|
||||||
throw UdpVpn::InitializationError("Cannot bind socket", errno, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
debugf("> Listening on port %d\n", port);
|
|
||||||
_bound = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UdpVpn::set_peer(const sockaddr_in6& peer_addr) {
|
|
||||||
memcpy(&_peer_addr, &peer_addr, sizeof(_peer_addr));
|
|
||||||
_has_peer = true;
|
|
||||||
|
|
||||||
char peer_addr_str[INET6_ADDRSTRLEN];
|
|
||||||
inet_ntop(
|
|
||||||
AF_INET6, &(peer_addr.sin6_addr), peer_addr_str, INET6_ADDRSTRLEN);
|
|
||||||
debugf("Set peer to %s:%d\n", peer_addr_str, ntohs(peer_addr.sin6_port));
|
|
||||||
}
|
|
||||||
|
|
||||||
void UdpVpn::run() {
|
void UdpVpn::run() {
|
||||||
int rc;
|
int rc;
|
||||||
int start_at_fd = 0; // read from polled fds in round-robin fashion
|
int start_at_fd = 0; // read from polled fds in round-robin fashion
|
||||||
|
@ -98,63 +67,40 @@ void UdpVpn::run() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UdpVpn::receive_from_tun() {
|
size_t UdpVpn::read_from_tun(char* buffer, size_t len) {
|
||||||
// We know that there is data available -- use `read()`
|
// We know that there is data available -- use `read()`
|
||||||
char buffer[1500];
|
size_t nread = _tun_dev.read(buffer, len);
|
||||||
size_t nread = _tun_dev.read(buffer, 1500);
|
|
||||||
|
|
||||||
if(nread == 0)
|
if(nread == 0)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
kdebugf("Transmitting packet of size %d to peer\n", nread);
|
return nread;
|
||||||
send_over_udp(buffer, nread);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UdpVpn::receive_from_udp() {
|
size_t UdpVpn::read_from_udp(char* buffer, size_t len,
|
||||||
|
sockaddr_in6& peer_addr)
|
||||||
|
{
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
char buffer[1500];
|
|
||||||
struct sockaddr_in6 peer_addr;
|
|
||||||
socklen_t peer_addr_len = sizeof(peer_addr);
|
socklen_t peer_addr_len = sizeof(peer_addr);
|
||||||
|
nread = recvfrom(_socket, buffer, len, MSG_WAITALL,
|
||||||
nread = recvfrom(_socket, buffer, 1500, MSG_WAITALL,
|
|
||||||
(struct sockaddr*) &peer_addr, &peer_addr_len);
|
(struct sockaddr*) &peer_addr, &peer_addr_len);
|
||||||
|
|
||||||
if(nread < 0)
|
if(nread < 0)
|
||||||
throw UdpVpn::NetError("Cannot receive datagram", errno, true);
|
throw UdpVpn::NetError("Cannot receive datagram", errno, true);
|
||||||
if(nread == 0)
|
if(nread == 0)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
if(peer_addr.sin6_family != AF_INET6) {
|
if(peer_addr.sin6_family != AF_INET6) {
|
||||||
debugf("WARNING: Received non-ipv6 family datagram %d. Ignoring.\n",
|
debugf("WARNING: Received non-ipv6 family datagram %d. Ignoring.\n",
|
||||||
peer_addr.sin6_family);
|
peer_addr.sin6_family);
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
if(peer_addr_len != sizeof(peer_addr)) {
|
if(peer_addr_len != sizeof(peer_addr)) {
|
||||||
debugf("WARNING: received unexpected source address length %u."
|
debugf("WARNING: received unexpected source address length %u."
|
||||||
"Ignoring.\n",
|
"Ignoring.\n",
|
||||||
peer_addr_len);
|
peer_addr_len);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_peer(peer_addr);
|
|
||||||
|
|
||||||
// Reinject into tun
|
|
||||||
kdebugf("Receiving packet of size %d from peer\n", nread);
|
|
||||||
_tun_dev.write(buffer, nread);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t UdpVpn::send_over_udp(const char* data, size_t len) {
|
|
||||||
ssize_t nsent;
|
|
||||||
|
|
||||||
if(!_has_peer) {
|
|
||||||
debugf("Dropping packet to be transmitted: no peer.\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsent = sendto(_socket, data, len, MSG_CONFIRM,
|
return nread;
|
||||||
(const struct sockaddr*) &_peer_addr, sizeof(_peer_addr));
|
|
||||||
if(nsent < 0)
|
|
||||||
throw NetError("Could not send UDP packet", errno, true);
|
|
||||||
|
|
||||||
return (size_t) nsent;
|
|
||||||
}
|
}
|
||||||
|
|
22
UdpVpn.hpp
22
UdpVpn.hpp
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
#include "TunDevice.hpp"
|
#include "TunDevice.hpp"
|
||||||
|
#include "VpnPeer.hpp"
|
||||||
|
|
||||||
/** Handles UDP communication */
|
/** Handles UDP communication */
|
||||||
|
|
||||||
|
@ -28,18 +29,10 @@ class UdpVpn {
|
||||||
};
|
};
|
||||||
|
|
||||||
UdpVpn();
|
UdpVpn();
|
||||||
~UdpVpn();
|
virtual ~UdpVpn();
|
||||||
|
|
||||||
void bind(in_port_t port);
|
|
||||||
void bind(const struct in6_addr& bind_addr6, in_port_t port);
|
|
||||||
|
|
||||||
int get_socket_fd() const { return _socket; }
|
int get_socket_fd() const { return _socket; }
|
||||||
const TunDevice& get_tun_dev() const { return _tun_dev; }
|
const TunDevice& get_tun_dev() const { return _tun_dev; }
|
||||||
bool is_bound() const { return _bound; }
|
|
||||||
|
|
||||||
// Sets the peer address
|
|
||||||
void set_peer(const sockaddr_in6& peer_addr);
|
|
||||||
void unset_peer() { _has_peer = false; }
|
|
||||||
|
|
||||||
// Run the server.
|
// Run the server.
|
||||||
void run();
|
void run();
|
||||||
|
@ -48,17 +41,14 @@ class UdpVpn {
|
||||||
void stop() { _stopped = true; }
|
void stop() { _stopped = true; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void receive_from_tun();
|
virtual void receive_from_tun() = 0;
|
||||||
void receive_from_udp();
|
virtual void receive_from_udp() = 0;
|
||||||
|
|
||||||
size_t send_over_udp(const char* data, size_t len);
|
size_t read_from_tun(char* buffer, size_t len);
|
||||||
|
size_t read_from_udp(char* buffer, size_t len, sockaddr_in6& peer_addr);
|
||||||
|
|
||||||
private:
|
|
||||||
int _socket;
|
int _socket;
|
||||||
bool _bound;
|
|
||||||
bool _stopped;
|
bool _stopped;
|
||||||
bool _has_peer;
|
|
||||||
struct sockaddr_in6 _serv_addr, _peer_addr;
|
|
||||||
|
|
||||||
TunDevice _tun_dev;
|
TunDevice _tun_dev;
|
||||||
};
|
};
|
||||||
|
|
67
UdpVpnClient.cpp
Normal file
67
UdpVpnClient.cpp
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "UdpVpnClient.hpp"
|
||||||
|
#include "ip_header.hpp"
|
||||||
|
|
||||||
|
UdpVpnClient::UdpVpnClient(const struct sockaddr_in6& server) : UdpVpn() {
|
||||||
|
memset(&_server_addr, 0, sizeof(_server_addr));
|
||||||
|
set_server(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UdpVpnClient::set_server(const struct sockaddr_in6& server_addr) {
|
||||||
|
if(server_addr.sin6_family != AF_INET6)
|
||||||
|
throw UdpVpn::InitializationError("Server address must be IPv6");
|
||||||
|
|
||||||
|
memcpy(&_server_addr, &server_addr, sizeof(_server_addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
void UdpVpnClient::receive_from_tun() {
|
||||||
|
char buffer[1500];
|
||||||
|
size_t nread = read_from_tun(buffer, 1500);
|
||||||
|
if(nread == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Parse inner packet header -- assume IPv6 for now [FIXME]
|
||||||
|
IPv6Header inner_header;
|
||||||
|
if(!parse_ipv6_header(buffer, nread, inner_header)) {
|
||||||
|
// Not a valid header -- ignore the packet
|
||||||
|
debugf("Ignoring outgoing packet with invalid header\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
kdebugf("Transmitting %s -> %s, size %d\n",
|
||||||
|
format_address(inner_header.source.s6_addr),
|
||||||
|
format_address(inner_header.dest.s6_addr),
|
||||||
|
nread);
|
||||||
|
|
||||||
|
write_to_server(buffer, nread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UdpVpnClient::receive_from_udp() {
|
||||||
|
char buffer[1500];
|
||||||
|
sockaddr_in6 peer_addr;
|
||||||
|
size_t nread = read_from_udp(buffer, 1500, peer_addr);
|
||||||
|
|
||||||
|
// Parse inner packet header -- assume IPv6 for now [FIXME]
|
||||||
|
IPv6Header inner_header;
|
||||||
|
if(!parse_ipv6_header(buffer, nread, inner_header)) {
|
||||||
|
// Not a valid header -- ignore the packet
|
||||||
|
debugf("Ignoring packet with invalid header\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reinject into tun
|
||||||
|
kdebugf("Receiving packet of size %d from peer\n", nread);
|
||||||
|
_tun_dev.write(buffer, nread);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t UdpVpnClient::write_to_server(const char* data, size_t len) {
|
||||||
|
ssize_t nsent;
|
||||||
|
|
||||||
|
nsent = sendto(_socket, data, len, MSG_CONFIRM,
|
||||||
|
(const struct sockaddr*) &_server_addr, sizeof(_server_addr));
|
||||||
|
if(nsent < 0)
|
||||||
|
throw NetError("Could not send UDP packet", errno, true);
|
||||||
|
|
||||||
|
return (size_t) nsent;
|
||||||
|
}
|
18
UdpVpnClient.hpp
Normal file
18
UdpVpnClient.hpp
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "UdpVpn.hpp"
|
||||||
|
|
||||||
|
class UdpVpnClient: public UdpVpn {
|
||||||
|
public:
|
||||||
|
UdpVpnClient(const struct sockaddr_in6& server);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void set_server(const struct sockaddr_in6& server_addr);
|
||||||
|
|
||||||
|
virtual void receive_from_tun();
|
||||||
|
virtual void receive_from_udp();
|
||||||
|
|
||||||
|
size_t write_to_server(const char* data, size_t len);
|
||||||
|
|
||||||
|
struct sockaddr_in6 _server_addr;
|
||||||
|
};
|
104
UdpVpnServer.cpp
Normal file
104
UdpVpnServer.cpp
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "UdpVpnServer.hpp"
|
||||||
|
#include "ip_header.hpp"
|
||||||
|
|
||||||
|
UdpVpnServer::UdpVpnServer(in_port_t port) : UdpVpn() {
|
||||||
|
memset(&_bind_addr, 0, sizeof(_bind_addr));
|
||||||
|
bind(in6addr_any, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
UdpVpnServer::UdpVpnServer(const struct in6_addr& bind_addr6, in_port_t port)
|
||||||
|
: UdpVpn()
|
||||||
|
{
|
||||||
|
memset(&_bind_addr, 0, sizeof(_bind_addr));
|
||||||
|
bind(bind_addr6, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UdpVpnServer::bind(const struct in6_addr& bind_addr6, in_port_t port) {
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
_bind_addr.sin6_family = AF_INET6;
|
||||||
|
_bind_addr.sin6_port = htons(port);
|
||||||
|
_bind_addr.sin6_addr = bind_addr6;
|
||||||
|
|
||||||
|
rc = ::bind(
|
||||||
|
_socket, (const struct sockaddr*)&_bind_addr, sizeof(_bind_addr));
|
||||||
|
if(rc < 0) {
|
||||||
|
throw UdpVpn::InitializationError("Cannot bind socket", errno, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
debugf("> Listening on port %d\n", port);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::shared_ptr<VpnPeer> UdpVpnServer::get_peer_for_ip(
|
||||||
|
const in6_addr& peer_addr)
|
||||||
|
{
|
||||||
|
auto peer_iter = _peers.find(peer_addr);
|
||||||
|
if(peer_iter == _peers.end()) // Unknown peer
|
||||||
|
return nullptr;
|
||||||
|
return peer_iter->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UdpVpnServer::receive_from_tun() {
|
||||||
|
char buffer[1500];
|
||||||
|
size_t nread = read_from_tun(buffer, 1500);
|
||||||
|
if(nread == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Parse inner packet header -- assume IPv6 for now [FIXME]
|
||||||
|
IPv6Header inner_header;
|
||||||
|
if(!parse_ipv6_header(buffer, nread, inner_header)) {
|
||||||
|
// Not a valid header -- ignore the packet
|
||||||
|
debugf("Ignoring outgoing packet with invalid header\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recover VpnPeer -- or drop if new
|
||||||
|
std::shared_ptr<VpnPeer> peer = get_peer_for_ip(inner_header.dest);
|
||||||
|
if(!peer) {
|
||||||
|
debugf("Dropping packet for destination %s -- unknown peer.\n",
|
||||||
|
format_address(inner_header.dest.s6_addr));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
kdebugf("Transmitting %s -> %s, size %d\n",
|
||||||
|
format_address(inner_header.source.s6_addr),
|
||||||
|
format_address(inner_header.dest.s6_addr),
|
||||||
|
nread);
|
||||||
|
peer->write(buffer, nread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UdpVpnServer::receive_from_udp() {
|
||||||
|
char buffer[1500];
|
||||||
|
sockaddr_in6 peer_addr;
|
||||||
|
size_t nread = read_from_udp(buffer, 1500, peer_addr);
|
||||||
|
|
||||||
|
// Parse inner packet header -- assume IPv6 for now [FIXME]
|
||||||
|
IPv6Header inner_header;
|
||||||
|
if(!parse_ipv6_header(buffer, nread, inner_header)) {
|
||||||
|
// Not a valid header -- ignore the packet
|
||||||
|
debugf("Ignoring packet with invalid header\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recover VpnPeer -- or create if new
|
||||||
|
std::shared_ptr<VpnPeer> peer = get_peer_for_ip(inner_header.source);
|
||||||
|
if(!peer) {
|
||||||
|
peer = std::make_shared<VpnPeer>(this, peer_addr, inner_header.source);
|
||||||
|
auto insert_result = _peers.insert({inner_header.source, peer});
|
||||||
|
|
||||||
|
debugf("Got new peer %s:%d -- %s [really inserted=%d]\n",
|
||||||
|
format_address(peer_addr.sin6_addr.s6_addr),
|
||||||
|
htons(peer_addr.sin6_port),
|
||||||
|
format_address(inner_header.source.s6_addr),
|
||||||
|
insert_result.second);
|
||||||
|
}
|
||||||
|
// VpnPeer* peer = (peer_iter->second);
|
||||||
|
// TODO -- pass the packet to `peer` for a cleaner flow
|
||||||
|
|
||||||
|
// Reinject into tun
|
||||||
|
kdebugf("Receiving packet of size %d from peer\n", nread);
|
||||||
|
_tun_dev.write(buffer, nread);
|
||||||
|
}
|
23
UdpVpnServer.hpp
Normal file
23
UdpVpnServer.hpp
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "UdpVpn.hpp"
|
||||||
|
|
||||||
|
class UdpVpnServer: public UdpVpn {
|
||||||
|
public:
|
||||||
|
UdpVpnServer(in_port_t port);
|
||||||
|
UdpVpnServer(const struct in6_addr& bind_addr6, in_port_t port);
|
||||||
|
protected:
|
||||||
|
void bind(const struct in6_addr& bind_addr6, in_port_t port);
|
||||||
|
|
||||||
|
/** Get the peer associated to this (internal) IP. */
|
||||||
|
std::shared_ptr<VpnPeer> get_peer_for_ip(const in6_addr& peer_addr);
|
||||||
|
|
||||||
|
virtual void receive_from_tun();
|
||||||
|
virtual void receive_from_udp();
|
||||||
|
|
||||||
|
struct sockaddr_in6 _bind_addr;
|
||||||
|
std::unordered_map<in6_addr, std::shared_ptr<VpnPeer>> _peers;
|
||||||
|
};
|
42
main.cpp
42
main.cpp
|
@ -5,6 +5,8 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "UdpVpn.hpp"
|
#include "UdpVpn.hpp"
|
||||||
|
#include "UdpVpnServer.hpp"
|
||||||
|
#include "UdpVpnClient.hpp"
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
|
|
||||||
struct ProgOptions {
|
struct ProgOptions {
|
||||||
|
@ -91,32 +93,40 @@ int main(int argc, char** argv) {
|
||||||
signal(SIGINT, stop_sig_handler);
|
signal(SIGINT, stop_sig_handler);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
UdpVpn vpn;
|
if(program_options.listen && program_options.has_peer) {
|
||||||
vpn_instance = &vpn;
|
fprintf(stderr,
|
||||||
|
"ERROR: Cannot be a server and a client at the same time "
|
||||||
if(program_options.listen) {
|
"-- provide either -l or -s.\n");
|
||||||
vpn.bind(program_options.bind_addr, program_options.bind_port);
|
return 1;
|
||||||
}
|
}
|
||||||
|
if(program_options.listen) {
|
||||||
if(program_options.has_peer) {
|
vpn_instance = new UdpVpnServer(
|
||||||
|
program_options.bind_addr, program_options.bind_port);
|
||||||
|
} else if(program_options.has_peer) {
|
||||||
if(program_options.server_port == 0) {
|
if(program_options.server_port == 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Initial peer set without a port -- ignoring.\n");
|
"ERROR: A client instance must be given a server port "
|
||||||
|
"-- please provide -p.\n");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
struct sockaddr_in6 server_addr;
|
struct sockaddr_in6 server_addr;
|
||||||
server_addr.sin6_family = AF_INET6;
|
server_addr.sin6_family = AF_INET6; memcpy(&server_addr.sin6_addr, &program_options.server_addr,
|
||||||
memcpy(&server_addr.sin6_addr,
|
|
||||||
&program_options.server_addr,
|
|
||||||
sizeof(server_addr.sin6_addr));
|
sizeof(server_addr.sin6_addr));
|
||||||
server_addr.sin6_port = htons(program_options.server_port);
|
server_addr.sin6_port = htons(program_options.server_port);
|
||||||
vpn.set_peer(server_addr);
|
|
||||||
}
|
vpn_instance = new UdpVpnClient(server_addr);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,
|
||||||
|
"ERROR: Must be either a server or a client "
|
||||||
|
"-- provide either -l or -s.\n");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Starting to listen...\n");
|
printf("Starting to listen...\n");
|
||||||
vpn.run();
|
vpn_instance->run();
|
||||||
vpn_instance = nullptr;
|
|
||||||
|
delete vpn_instance;
|
||||||
|
|
||||||
printf("Shutting down.\n");
|
printf("Shutting down.\n");
|
||||||
} catch(const TunDevice::InitializationError& exn) {
|
} catch(const TunDevice::InitializationError& exn) {
|
||||||
|
|
Loading…
Reference in a new issue