#pragma once #include #include #include #include "util.hpp" #include "TunDevice.hpp" #include "VpnPeer.hpp" #include "VpnPacket.hpp" /** Handles UDP communication */ class UdpVpn { public: class InitializationError : public MsgException { public: InitializationError( const std::string& msg, int code=0, bool is_perror=false) : MsgException(msg, code, is_perror) {} }; class NetError : public MsgException { public: NetError( const std::string& msg, int code=0, bool is_perror=false) : MsgException(msg, code, is_perror) {} }; UdpVpn(); virtual ~UdpVpn(); int get_socket_fd() const { return _socket; } const TunDevice& get_tun_dev() const { return _tun_dev; } // Run the server. void run(); // Stop the server. Can be called from an interrupt. void stop() { _stopped = true; } // A state dump has been requested void dump_requested() { _dump_requested = true; } size_t get_mtu() const { return _vpn_mtu; } size_t transmit_to_peer(VpnPacket& packet); protected: virtual void acquire_peer( VpnDataPacket& packet, const sockaddr_in6& peer_ext_addr) = 0; size_t read_from_tun(char* buffer, size_t len); size_t read_from_tun(VpnDataPacket& packet); size_t read_from_udp(char* buffer, size_t len, sockaddr_in6& peer_addr); size_t read_from_udp(VpnPacket& packet, sockaddr_in6& peer_addr); void receive_from_tun(); void receive_from_udp(); void receive_tunnelled_tlv(VpnDataPacket& packet); void dump_state() const; int _socket; bool _stopped, _dump_requested; size_t _vpn_mtu; TunDevice _tun_dev; std::unique_ptr _peer; struct timespec _last_control_sent, /**< A control is offered to be sent approx. every 100ms */ _last_tick /**< A tick occurs approx. each 50ms */; };