From ecc996f3f0be65ae6693ef265c677ba60d78c9d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Bastian?= Date: Wed, 22 Jul 2020 19:09:27 +0200 Subject: [PATCH] C rewrite: phase out exceptions --- TunDevice.cpp | 34 +++++++++++++----------- TunDevice.hpp | 17 ------------ UdpVpn.cpp | 16 ++++++----- UdpVpn.hpp | 17 ------------ UdpVpnServer.cpp | 3 ++- VpnPacket.cpp | 6 +++-- VpnPacket.hpp | 2 -- VpnPeer.cpp | 6 +++-- VpnPeer.hpp | 9 ------- main.cpp | 69 ++++++++++++++++++++---------------------------- util.cpp | 17 ------------ util.hpp | 20 -------------- 12 files changed, 67 insertions(+), 149 deletions(-) diff --git a/TunDevice.cpp b/TunDevice.cpp index 7cd6ea4..0ac330c 100644 --- a/TunDevice.cpp +++ b/TunDevice.cpp @@ -18,8 +18,8 @@ TunDevice::TunDevice(const std::string& dev) int fd; if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) { - throw TunDevice::InitializationError( - "Cannot open /dev/net/tun", errno, true); + perror("Tun device: cannot open /dev/net/tun: "); + exit(1); } memset(&ifr, 0, sizeof(ifr)); @@ -31,15 +31,17 @@ TunDevice::TunDevice(const std::string& dev) */ ifr.ifr_flags = IFF_TUN | IFF_NO_PI; if(!dev.empty()) { - if(dev.size() >= IFNAMSIZ - 2) - throw TunDevice::InitializationError("Device name is too long."); + if(dev.size() >= IFNAMSIZ - 2) { + fprintf(stderr, "Tun device: device name is too long.\n"); + exit(1); + } strncpy(ifr.ifr_name, dev.c_str(), IFNAMSIZ-1); } if(ioctl(fd, TUNSETIFF, (void *) &ifr) < 0){ close(fd); - throw TunDevice::InitializationError( - "Tunnel interface failed [TUNSETIFF]", errno, true); + perror("Tun device: tunnel interface failed [TUNSETIFF]: "); + exit(1); } _dev_name = ifr.ifr_name; _fd = fd; @@ -50,16 +52,16 @@ TunDevice::TunDevice(const std::string& dev) if(ioctl(sockfd, SIOCGIFFLAGS, (void*) &ifr) < 0) { close(fd); close(sockfd); - throw TunDevice::InitializationError( - "Could not get tunnel interface flags", errno, true); + perror("Tun device: could not get tunnel interface flags: "); + exit(1); } ifr.ifr_flags |= IFF_UP | IFF_RUNNING; if(ioctl(sockfd, SIOCSIFFLAGS, (void*) &ifr) < 0) { close(fd); close(sockfd); - throw TunDevice::InitializationError( - "Could not bring tunnel interface up", errno, true); + perror("Tun device: could not bring tunnel interface up: "); + exit(1); } close(sockfd); @@ -102,8 +104,8 @@ size_t TunDevice::poll_packet(char* read_buffer, size_t buf_size, int timeout) { if(poll_rc < 0) { if(errno == EINTR) // Interrupt. return 0; - throw TunDevice::NetError( - "Error polling from interface", errno, true); + perror("Tun device: error polling from interface: "); + exit(1); } else if(poll_rc == 0 || (_poll_fd.revents & POLLIN) == 0) { // Nothing to read @@ -116,8 +118,8 @@ size_t TunDevice::poll_packet(char* read_buffer, size_t buf_size, int timeout) { size_t TunDevice::read(char* read_buffer, size_t buf_size) { int nread = ::read(_fd, read_buffer, buf_size); if(nread < 0) { - throw TunDevice::NetError( - "Error reading from interface", errno, true); + perror("Tun device: error reading from interface: "); + exit(1); } _last_read_size = nread; return _last_read_size; @@ -126,8 +128,8 @@ size_t TunDevice::read(char* read_buffer, size_t buf_size) { size_t TunDevice::write(const char* data, size_t len) { int nwritten = ::write(_fd, data, len); if(nwritten < 0) { - throw TunDevice::NetError( - "Error writing to interface: ", errno, true); + perror("Tun device: error writing to interface: "); + exit(1); } return nwritten; } diff --git a/TunDevice.hpp b/TunDevice.hpp index 0df8b71..7a54491 100644 --- a/TunDevice.hpp +++ b/TunDevice.hpp @@ -6,23 +6,6 @@ class TunDevice { 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) {} - }; - TunDevice(const std::string& dev); ~TunDevice(); diff --git a/UdpVpn.cpp b/UdpVpn.cpp index 4b6f265..b7cb9eb 100644 --- a/UdpVpn.cpp +++ b/UdpVpn.cpp @@ -24,8 +24,10 @@ UdpVpn::UdpVpn() _tun_dev.set_mtu(VpnPacket::get_tunnelled_mtu(_vpn_mtu)); _socket = socket(AF_INET6, SOCK_DGRAM, 0); - if(_socket < 0) - throw UdpVpn::InitializationError("Cannot create socket", errno, true); + if(_socket < 0) { + perror("UdpVpn: cannot create socket: "); + exit(1); + } } UdpVpn::~UdpVpn() { @@ -58,8 +60,8 @@ void UdpVpn::run() { if(rc < 0) { if(errno == EINTR) // Interrupt. continue; - throw UdpVpn::NetError( - "Error polling from interface", errno, true); + perror("UdpVpn: error polling from interface: "); + exit(1); } // ## Check periodic actions @@ -124,8 +126,10 @@ size_t UdpVpn::read_from_udp(char* buffer, size_t len, nread = recvfrom(_socket, buffer, len, 0, (struct sockaddr*) &peer_addr, &peer_addr_len); - if(nread < 0) - throw UdpVpn::NetError("Cannot receive datagram", errno, true); + if(nread < 0) { + perror("UdpVpn: cannot receive datagram: "); + exit(1); + } if(nread == 0) return 0; diff --git a/UdpVpn.hpp b/UdpVpn.hpp index 0ef8a37..3584b28 100644 --- a/UdpVpn.hpp +++ b/UdpVpn.hpp @@ -13,23 +13,6 @@ 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(); diff --git a/UdpVpnServer.cpp b/UdpVpnServer.cpp index 1c99633..40cba72 100644 --- a/UdpVpnServer.cpp +++ b/UdpVpnServer.cpp @@ -51,7 +51,8 @@ void UdpVpnServer::bind(const struct in6_addr& bind_addr6, in_port_t port) { rc = ::bind( _socket, (const struct sockaddr*)&_bind_addr, sizeof(_bind_addr)); if(rc < 0) { - throw UdpVpn::InitializationError("Cannot bind socket", errno, true); + perror("UdpVpn: cannot bind socket: "); + exit(1); } debugf("> Listening on port %d\n", port); diff --git a/VpnPacket.cpp b/VpnPacket.cpp index 0b8df69..ebec760 100644 --- a/VpnPacket.cpp +++ b/VpnPacket.cpp @@ -79,8 +79,10 @@ void VpnPacket::upon_reception() { } uint32_t VpnPacket::next_seqno() { - if(!_peer) - throw PeerNotSet(); + if(!_peer) { + fprintf(stderr, "ERROR: trying to get seqno without peer.\n"); + return 0; + } return _peer->next_seqno(); } diff --git a/VpnPacket.hpp b/VpnPacket.hpp index 4f390a5..9f79523 100644 --- a/VpnPacket.hpp +++ b/VpnPacket.hpp @@ -3,7 +3,6 @@ /** A packet to be transmitted or received over the VPN socket */ #include -#include #include "ip_header.hpp" @@ -50,7 +49,6 @@ class VpnPacketTLV; class VpnPacket { public: static const size_t VPN_HEADER_BYTES; - class PeerNotSet: public std::exception {}; VpnPacket(size_t mtu, bool inbound); ~VpnPacket(); diff --git a/VpnPeer.cpp b/VpnPeer.cpp index cbb8172..a424853 100644 --- a/VpnPeer.cpp +++ b/VpnPeer.cpp @@ -69,8 +69,10 @@ size_t VpnPeer::write(const char* data, size_t len) { nsent = sendto(_vpn->get_socket_fd(), data, len, MSG_CONFIRM, (const struct sockaddr*) &_ext_addr, sizeof(_ext_addr)); - if(nsent < 0) - throw NetError("Could not send UDP packet", errno, true); + if(nsent < 0) { + perror("Could not send UDP packet: "); + exit(1); + } _tot_bytes_sent += nsent; diff --git a/VpnPeer.hpp b/VpnPeer.hpp index a0218a4..7e888db 100644 --- a/VpnPeer.hpp +++ b/VpnPeer.hpp @@ -68,15 +68,6 @@ class RTTLogger { class VpnPeer { public: - class NetError : public MsgException { - public: - NetError( - const std::string& msg, - int code=0, - bool is_perror=false) - : MsgException(msg, code, is_perror) {} - }; - /// Logs the loss reports sent by the remote peer struct LossReports { uint32_t prev_seqno, last_seqno; diff --git a/main.cpp b/main.cpp index 02c91c0..659393a 100644 --- a/main.cpp +++ b/main.cpp @@ -100,52 +100,41 @@ int main(int argc, char** argv) { signal(SIGINT, stop_sig_handler); signal(SIGUSR1, dump_sig_handler); - try { - if(program_options.listen && program_options.has_peer) { + if(program_options.listen && program_options.has_peer) { + fprintf(stderr, + "ERROR: Cannot be a server and a client at the same time " + "-- provide either -l or -s.\n"); + return 1; + } + if(program_options.listen) { + vpn_instance = new UdpVpnServer( + program_options.bind_addr, program_options.bind_port); + } else if(program_options.has_peer) { + if(program_options.server_port == 0) { fprintf(stderr, - "ERROR: Cannot be a server and a client at the same time " - "-- provide either -l or -s.\n"); - return 1; - } - if(program_options.listen) { - vpn_instance = new UdpVpnServer( - program_options.bind_addr, program_options.bind_port); - } else if(program_options.has_peer) { - if(program_options.server_port == 0) { - fprintf(stderr, - "ERROR: A client instance must be given a server port " - "-- please provide -p.\n"); - return 1; - } - - struct sockaddr_in6 server_addr; - server_addr.sin6_family = AF_INET6; memcpy(&server_addr.sin6_addr, &program_options.server_addr, - sizeof(server_addr.sin6_addr)); - server_addr.sin6_port = htons(program_options.server_port); - - vpn_instance = new UdpVpnClient(server_addr); - } else { - fprintf(stderr, - "ERROR: Must be either a server or a client " - "-- provide either -l or -s.\n"); + "ERROR: A client instance must be given a server port " + "-- please provide -p.\n"); return 1; } - printf("Starting to listen...\n"); - vpn_instance->run(); + struct sockaddr_in6 server_addr; + server_addr.sin6_family = AF_INET6; memcpy(&server_addr.sin6_addr, &program_options.server_addr, + sizeof(server_addr.sin6_addr)); + server_addr.sin6_port = htons(program_options.server_port); - delete vpn_instance; - - printf("Shutting down.\n"); - } catch(const TunDevice::InitializationError& exn) { - fprintf(stderr, "TUN INIT ERROR: %s\n", exn.what()); - } catch(const TunDevice::NetError& exn) { - fprintf(stderr, "TUN NET ERROR: %s\n", exn.what()); - } catch(const UdpVpn::InitializationError& exn) { - fprintf(stderr, "VPN INIT ERROR: %s\n", exn.what()); - } catch(const UdpVpn::NetError& exn) { - fprintf(stderr, "VPN NET ERROR: %s\n", exn.what()); + 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"); + vpn_instance->run(); + + delete vpn_instance; + + printf("Shutting down.\n"); return 0; } diff --git a/util.cpp b/util.cpp index 1ed667a..b6c782b 100644 --- a/util.cpp +++ b/util.cpp @@ -109,20 +109,3 @@ bool equal_to::operator()( return memcmp(lhs.s6_addr, rhs.s6_addr, sizeof(lhs.s6_addr)) == 0; } } - -MsgException::MsgException(const std::string& msg, int code, bool is_perror) - : _msg(msg), _code(code) -{ - _what = _msg; - - if(_code != 0) { - if(is_perror) { - _what += ": "; - _what += strerror(errno); - } - - char remainder[20]; - sprintf(remainder, " (code %d)", _code); - _what += remainder; - } -} diff --git a/util.hpp b/util.hpp index 17e926d..85b5c65 100644 --- a/util.hpp +++ b/util.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include @@ -96,22 +95,3 @@ namespace std { bool operator()(const in6_addr& lhs, const in6_addr& rhs) const; }; } - - - -/** MsgException -- an exception bearing a passed explanation message - * - * If `is_perror` is true, then the `strerror` corresponding message is appened - * to the message in `what()`. - */ -class MsgException : public std::exception { - public: - MsgException(const std::string& msg, int code=0, bool is_perror=false); - int errcode() const noexcept { return _code; } - const char* what() const noexcept { return _what.c_str(); }; - - private: - std::string _msg; - int _code; - std::string _what; -};