From 41f9ed5ef4e08a0751fff1fff591ed29395f9b36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Friedrich=20Scho=CC=88ller?= Date: Fri, 12 May 2017 00:13:50 +0200 Subject: [PATCH] More towards C++ --- src/auth.cpp | 9 +++--- src/auth.h | 2 +- src/client.cpp | 15 +++++---- src/client.h | 7 +++-- src/echo.cpp | 27 +++++++++++------ src/echo.h | 8 +++-- src/exception.cpp | 13 +++----- src/exception.h | 7 ++--- src/main.cpp | 42 +++++++++++++++----------- src/server.cpp | 23 ++++++++------ src/server.h | 12 ++++---- src/tun.cpp | 53 ++++++++++++++++---------------- src/tun.h | 4 +-- src/utility.cpp | 14 +++++---- src/worker.cpp | 77 +++++++++++++++++++---------------------------- src/worker.h | 37 ++++++++++++----------- 16 files changed, 178 insertions(+), 172 deletions(-) diff --git a/src/auth.cpp b/src/auth.cpp index 126fbef..095a7fc 100644 --- a/src/auth.cpp +++ b/src/auth.cpp @@ -23,10 +23,9 @@ #include -Auth::Auth(const char *passphrase) -{ - this->passphrase = passphrase; -} +Auth::Auth(const std::string &passphrase) + : passphrase(passphrase) +{ } Auth::Response Auth::getResponse(const Challenge &challenge) const { @@ -34,7 +33,7 @@ Auth::Response Auth::getResponse(const Challenge &challenge) const Response response; - hasher << passphrase.c_str(); + hasher << passphrase.data(); hasher.Input(&challenge[0], challenge.size()); hasher.Result((unsigned int *)response.data); diff --git a/src/auth.h b/src/auth.h index 7188733..a2432fd 100644 --- a/src/auth.h +++ b/src/auth.h @@ -36,7 +36,7 @@ public: bool operator==(const Response &other) const { return memcmp(this, &other, sizeof(Response)) == 0; } }; - Auth(const char *passphrase); + Auth(const std::string &passphrase); Challenge generateChallenge(int length) const; Response getResponse(const Challenge &challenge) const; diff --git a/src/client.cpp b/src/client.cpp index 4c7955a..675da7e 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -28,14 +28,15 @@ #include #include -using namespace std; +using std::vector; +using std::string; const Worker::TunnelHeader::Magic Client::magic("hanc"); -Client::Client(int tunnelMtu, const char *deviceName, uint32_t serverIp, - int maxPolls, const char *passphrase, uid_t uid, gid_t gid, +Client::Client(int tunnelMtu, const string *deviceName, uint32_t serverIp, + int maxPolls, const string &passphrase, uid_t uid, gid_t gid, bool changeEchoId, bool changeEchoSeq, uint32_t desiredIp) -: Worker(tunnelMtu, deviceName, false, uid, gid), auth(passphrase) + : Worker(tunnelMtu, deviceName, false, uid, gid), auth(passphrase) { this->serverIp = serverIp; this->clientIp = INADDR_NONE; @@ -137,7 +138,7 @@ bool Client::handleEchoData(const TunnelHeader &header, int dataLength, uint32_t clientIp = ip; desiredIp = ip; - tun->setIp(ip, (ip & 0xffffff00) + 1); + tun.setIp(ip, (ip & 0xffffff00) + 1); } state = STATE_ESTABLISHED; @@ -160,6 +161,8 @@ bool Client::handleEchoData(const TunnelHeader &header, int dataLength, uint32_t return true; } break; + default: + break; } syslog(LOG_DEBUG, "invalid packet type: %d, state: %d", header.type, state); @@ -167,7 +170,7 @@ bool Client::handleEchoData(const TunnelHeader &header, int dataLength, uint32_t return true; } -void Client::sendEchoToServer(int type, int dataLength) +void Client::sendEchoToServer(Worker::TunnelHeader::Type type, int dataLength) { if (maxPolls == 0 && state == STATE_ESTABLISHED) setTimeout(KEEP_ALIVE_INTERVAL); diff --git a/src/client.h b/src/client.h index ffd32ee..11d7388 100644 --- a/src/client.h +++ b/src/client.h @@ -27,9 +27,10 @@ class Client : public Worker { + public: - Client(int tunnelMtu, const char *deviceName, uint32_t serverIp, - int maxPolls, const char *passphrase, uid_t uid, gid_t gid, + Client(int tunnelMtu, const std::string *deviceName, uint32_t serverIp, + int maxPolls, const std::string &passphrase, uid_t uid, gid_t gid, bool changeEchoId, bool changeEchoSeq, uint32_t desiredIp); virtual ~Client(); @@ -53,7 +54,7 @@ protected: void startPolling(); - void sendEchoToServer(int type, int dataLength); + void sendEchoToServer(Worker::TunnelHeader::Type type, int dataLength); void sendChallengeResponse(int dataLength); void sendConnectionRequest(); diff --git a/src/echo.cpp b/src/echo.cpp index 65bc098..c931d04 100644 --- a/src/echo.cpp +++ b/src/echo.cpp @@ -42,16 +42,13 @@ Echo::Echo(int maxPayloadSize) throw Exception("creating icmp socket", true); bufferSize = maxPayloadSize + headerSize(); - sendBuffer = new char[bufferSize]; - receiveBuffer = new char[bufferSize]; + sendBuffer.resize(bufferSize); + receiveBuffer.resize(bufferSize); } Echo::~Echo() { close(fd); - - delete[] sendBuffer; - delete[] receiveBuffer; } int Echo::headerSize() @@ -68,15 +65,15 @@ void Echo::send(int payloadLength, uint32_t realIp, bool reply, uint16_t id, uin if (payloadLength + sizeof(IpHeader) + sizeof(EchoHeader) > bufferSize) throw Exception("packet too big"); - EchoHeader *header = (EchoHeader *)(sendBuffer + sizeof(IpHeader)); + EchoHeader *header = (EchoHeader *)(sendBuffer.data() + sizeof(IpHeader)); header->type = reply ? 0: 8; header->code = 0; header->id = htons(id); header->seq = htons(seq); header->chksum = 0; - header->chksum = icmpChecksum(sendBuffer + sizeof(IpHeader), payloadLength + sizeof(EchoHeader)); + header->chksum = icmpChecksum(sendBuffer.data() + sizeof(IpHeader), payloadLength + sizeof(EchoHeader)); - int result = sendto(fd, sendBuffer + sizeof(IpHeader), payloadLength + sizeof(EchoHeader), 0, (struct sockaddr *)&target, sizeof(struct sockaddr_in)); + int result = sendto(fd, sendBuffer.data() + sizeof(IpHeader), payloadLength + sizeof(EchoHeader), 0, (struct sockaddr *)&target, sizeof(struct sockaddr_in)); if (result == -1) syslog(LOG_ERR, "error sending icmp packet: %s", strerror(errno)); } @@ -86,7 +83,7 @@ int Echo::receive(uint32_t &realIp, bool &reply, uint16_t &id, uint16_t &seq) struct sockaddr_in source; int source_addr_len = sizeof(struct sockaddr_in); - int dataLength = recvfrom(fd, receiveBuffer, bufferSize, 0, (struct sockaddr *)&source, (socklen_t *)&source_addr_len); + int dataLength = recvfrom(fd, receiveBuffer.data(), bufferSize, 0, (struct sockaddr *)&source, (socklen_t *)&source_addr_len); if (dataLength == -1) { syslog(LOG_ERR, "error receiving icmp packet: %s", strerror(errno)); @@ -96,7 +93,7 @@ int Echo::receive(uint32_t &realIp, bool &reply, uint16_t &id, uint16_t &seq) if (dataLength < sizeof(IpHeader) + sizeof(EchoHeader)) return -1; - EchoHeader *header = (EchoHeader *)(receiveBuffer + sizeof(IpHeader)); + EchoHeader *header = (EchoHeader *)(receiveBuffer.data() + sizeof(IpHeader)); if ((header->type != 0 && header->type != 8) || header->code != 0) return -1; @@ -122,3 +119,13 @@ uint16_t Echo::icmpChecksum(const char *data, int length) sum += (sum >> 16); return ~sum; } + +char *Echo::sendPayloadBuffer() +{ + return sendBuffer.data() + headerSize(); +} + +char *Echo::receivePayloadBuffer() +{ + return receiveBuffer.data() + headerSize(); +} diff --git a/src/echo.h b/src/echo.h index ebb1780..944a299 100644 --- a/src/echo.h +++ b/src/echo.h @@ -21,6 +21,7 @@ #define ECHO_H #include +#include #include class Echo @@ -34,8 +35,8 @@ public: void send(int payloadLength, uint32_t realIp, bool reply, uint16_t id, uint16_t seq); int receive(uint32_t &realIp, bool &reply, uint16_t &id, uint16_t &seq); - char *sendPayloadBuffer() { return sendBuffer + headerSize(); } - char *receivePayloadBuffer() { return receiveBuffer + headerSize(); } + char *sendPayloadBuffer(); + char *receivePayloadBuffer(); static int headerSize(); protected: @@ -52,7 +53,8 @@ protected: int fd; int bufferSize; - char *sendBuffer, *receiveBuffer; + std::vector sendBuffer; + std::vector receiveBuffer; }; #endif diff --git a/src/exception.cpp b/src/exception.cpp index 480bfca..253ab23 100644 --- a/src/exception.cpp +++ b/src/exception.cpp @@ -23,22 +23,17 @@ #include #include -using namespace std; +using std::string; -Exception::Exception(const char *msg) +Exception::Exception(const string &msg) { this->msg = msg; } -Exception::Exception(const string msg) -{ - this->msg = msg; -} - -Exception::Exception(const char *msg, bool appendSystemError) +Exception::Exception(const string &msg, bool appendSystemError) { if (appendSystemError) - this->msg = string(msg) + ": " + strerror(errno); + this->msg = msg + ": " + strerror(errno); else this->msg = msg; } diff --git a/src/exception.h b/src/exception.h index df2ad63..259a90c 100644 --- a/src/exception.h +++ b/src/exception.h @@ -22,11 +22,10 @@ class Exception { public: - Exception(const char *msg); - Exception(const std::string msg); - Exception(const char *msg, bool appendSystemError); + Exception(const std::string &msg); + Exception(const std::string &msg, bool appendSystemError); - const char *errorMessage() const { return msg.c_str(); } + const std::string &errorMessage() const { return msg; } protected: std::string msg; }; diff --git a/src/main.cpp b/src/main.cpp index 2e53f3f..99b1226 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,7 +21,7 @@ #include "server.h" #include "exception.h" -#include +#include #include #include #include @@ -35,11 +35,14 @@ #include #include #include +#include #ifndef AI_V4MAPPED // Not supported on OpenBSD 6.0 #define AI_V4MAPPED 0 #endif +using std::string; + static Worker *worker = NULL; static void sig_term_handler(int) @@ -58,7 +61,7 @@ static void sig_int_handler(int) static void usage() { - printf( + std::cerr << "Hans - IP over ICMP version 1.0\n\n" "RUN AS CLIENT\n" " hans -c server [-fv] [-p passphrase] [-u user] [-d tun_device]\n" @@ -86,16 +89,15 @@ static void usage() " -q Change echo sequence number on every echo request. May help with\n" " buggy routers. May impact performance with others.\n" " -f Run in foreground.\n" - " -v Print debug information.\n" - ); + " -v Print debug information.\n"; } int main(int argc, char *argv[]) { - const char *serverName; - const char *userName = NULL; - const char *password = ""; - const char *device = NULL; + string serverName; + string userName; + string passphrase; + string device; bool isServer = false; bool isClient = false; bool foreground = false; @@ -126,7 +128,7 @@ int main(int argc, char *argv[]) device = optarg; break; case 'p': - password = strdup(optarg); + passphrase = optarg; memset(optarg, 0, strlen(optarg)); break; case 'c': @@ -137,7 +139,7 @@ int main(int argc, char *argv[]) isServer = true; network = ntohl(inet_addr(optarg)); if (network == INADDR_NONE) - printf("invalid network\n"); + std::cerr << "invalid network\n"; break; case 'm': mtu = atoi(optarg); @@ -170,8 +172,9 @@ int main(int argc, char *argv[]) if (mtu < 68) { - // RFC 791: Every internet module must be able to forward a datagram of 68 octets without further fragmentation. - printf("mtu too small\n"); + // RFC 791: Every internet module must be able to forward a datagram of + // 68 octets without further fragmentation. + std::cerr << "mtu too small\n"; return 1; } @@ -184,13 +187,13 @@ int main(int argc, char *argv[]) return 1; } - if (userName != NULL) + if (!userName.empty()) { #ifdef WIN32 syslog(LOG_ERR, "dropping privileges is not supported on Windows"); return 1; #endif - passwd *pw = getpwnam(userName); + passwd *pw = getpwnam(userName.data()); if (pw != NULL) { @@ -214,7 +217,8 @@ int main(int argc, char *argv[]) { if (isServer) { - worker = new Server(mtu, device, password, network, answerPing, uid, gid, 5000); + worker = new Server(mtu, device.empty() ? NULL : &device, passphrase, + network, answerPing, uid, gid, 5000); } else { @@ -224,7 +228,7 @@ int main(int argc, char *argv[]) hints.ai_family = AF_INET; hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG; - int err = getaddrinfo(serverName, NULL, &hints, &res); + int err = getaddrinfo(serverName.data(), NULL, &hints, &res); if (err) { syslog(LOG_ERR, "getaddrinfo: %s", gai_strerror(err)); @@ -234,7 +238,9 @@ int main(int argc, char *argv[]) sockaddr_in *sockaddr = reinterpret_cast(res->ai_addr); uint32_t serverIp = sockaddr->sin_addr.s_addr; - worker = new Client(mtu, device, ntohl(serverIp), maxPolls, password, uid, gid, changeEchoId, changeEchoSeq, clientIp); + worker = new Client(mtu, device.empty() ? NULL : &device, + ntohl(serverIp), maxPolls, passphrase, uid, gid, + changeEchoId, changeEchoSeq, clientIp); freeaddrinfo(res); } @@ -249,7 +255,7 @@ int main(int argc, char *argv[]) } catch (Exception e) { - syslog(LOG_ERR, "%s", e.errorMessage()); + syslog(LOG_ERR, "%s", e.errorMessage().data()); delete worker; return 1; } diff --git a/src/server.cpp b/src/server.cpp index 89bd59d..374861b 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -25,22 +25,25 @@ #include #include #include -#include +#include -using namespace std; +using std::string; +using std::cout; +using std::endl; #define FIRST_ASSIGNED_IP_OFFSET 100 const Worker::TunnelHeader::Magic Server::magic("hans"); -Server::Server(int tunnelMtu, const char *deviceName, const char *passphrase, uint32_t network, bool answerEcho, uid_t uid, gid_t gid, int pollTimeout) +Server::Server(int tunnelMtu, const string *deviceName, const string &passphrase, + uint32_t network, bool answerEcho, uid_t uid, gid_t gid, int pollTimeout) : Worker(tunnelMtu, deviceName, answerEcho, uid, gid), auth(passphrase) { this->network = network & 0xffffff00; this->pollTimeout = pollTimeout; this->latestAssignedIpOffset = FIRST_ASSIGNED_IP_OFFSET - 1; - tun->setIp(this->network + 1, this->network + 2); + tun.setIp(this->network + 1, this->network + 2); dropPrivileges(); } @@ -200,6 +203,8 @@ bool Server::handleEchoData(const TunnelHeader &header, int dataLength, uint32_t break; case TunnelHeader::TYPE_POLL: return true; + default: + break; } syslog(LOG_DEBUG, "invalid packet from: %s, type: %d, state: %d", Utility::formatIp(realIp).c_str(), header.type, client->state); @@ -248,7 +253,7 @@ void Server::pollReceived(ClientData *client, uint16_t echoId, uint16_t echoSeq) client->pollIds.push(ClientData::EchoId(echoId, echoSeq)); if (client->pollIds.size() > maxSavedPolls) client->pollIds.pop(); - DEBUG_ONLY(printf("poll -> %d\n", (int)client->pollIds.size())); + DEBUG_ONLY(cout << "poll -> " << client->pollIds.size() << endl); if (client->pendingPackets.size() > 0) { @@ -256,14 +261,14 @@ void Server::pollReceived(ClientData *client, uint16_t echoId, uint16_t echoSeq) memcpy(echoSendPayloadBuffer(), &packet.data[0], packet.data.size()); client->pendingPackets.pop(); - DEBUG_ONLY(printf("pending packet: %d bytes\n", (int)packet.data.size())); + DEBUG_ONLY(cout << "pending packet: " << packet.data.size() << " bytes\n"); sendEchoToClient(client, packet.type, packet.data.size()); } client->lastActivity = now; } -void Server::sendEchoToClient(ClientData *client, int type, int dataLength) +void Server::sendEchoToClient(ClientData *client, TunnelHeader::Type type, int dataLength) { if (client->maxPolls == 0) { @@ -276,7 +281,7 @@ void Server::sendEchoToClient(ClientData *client, int type, int dataLength) ClientData::EchoId echoId = client->pollIds.front(); client->pollIds.pop(); - DEBUG_ONLY(printf("sending -> %d\n", (int)client->pollIds.size())); + DEBUG_ONLY(cout << "sending -> " << client->pollIds.size() << endl); sendEcho(magic, type, dataLength, client->realIp, true, echoId.id, echoId.seq); return; } @@ -287,7 +292,7 @@ void Server::sendEchoToClient(ClientData *client, int type, int dataLength) syslog(LOG_WARNING, "packet dropped to %s", Utility::formatIp(client->tunnelIp).c_str()); } - DEBUG_ONLY(printf("packet queued: %d bytes\n", dataLength)); + DEBUG_ONLY(cout << "packet queued: " << dataLength << " bytes\n"); client->pendingPackets.push(Packet()); Packet &packet = client->pendingPackets.back(); diff --git a/src/server.h b/src/server.h index 130104f..7e2b6c7 100644 --- a/src/server.h +++ b/src/server.h @@ -28,27 +28,27 @@ #include #include #include +#include class Server : public Worker { public: - Server(int tunnelMtu, const char *deviceName, const char *passphrase, uint32_t network, bool answerEcho, uid_t uid, gid_t gid, int pollTimeout); + Server(int tunnelMtu, const std::string *deviceName, const std::string &passphrase, + uint32_t network, bool answerEcho, uid_t uid, gid_t gid, int pollTimeout); virtual ~Server(); - // change some time: - // struct __attribute__ ((__packed__)) ClientConnectData struct ClientConnectData { uint8_t maxPolls; uint32_t desiredIp; }; - static const Worker::TunnelHeader::Magic magic; + static const TunnelHeader::Magic magic; protected: struct Packet { - int type; + TunnelHeader::Type type; std::vector data; }; @@ -101,7 +101,7 @@ protected: void checkChallenge(ClientData *client, int dataLength); void sendReset(ClientData *client); - void sendEchoToClient(ClientData *client, int type, int dataLength); + void sendEchoToClient(ClientData *client, TunnelHeader::Type type, int dataLength); void pollReceived(ClientData *client, uint16_t echoId, uint16_t echoSeq); diff --git a/src/tun.cpp b/src/tun.cpp index 03f3315..8bfeb58 100644 --- a/src/tun.cpp +++ b/src/tun.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #ifdef WIN32 #include @@ -37,7 +38,7 @@ typedef ip IpHeader; -using namespace std; +using std::string; #ifdef WIN32 static void winsystem(char *cmd) @@ -53,61 +54,61 @@ static void winsystem(char *cmd) } #endif -Tun::Tun(const char *device, int mtu) +Tun::Tun(const string *device, int mtu) { - char cmdline[512]; - this->mtu = mtu; - if (device != NULL) - { - strncpy(this->device, device, VTUN_DEV_LEN); - this->device[VTUN_DEV_LEN-1] = 0; - } - else - this->device[0] = 0; + if (device) + this->device = *device; + + this->device.resize(VTUN_DEV_LEN); + fd = tun_open(&this->device[0]); + this->device.resize(strlen(this->device.data())); - fd = tun_open(this->device); if (fd == -1) throw Exception(string("could not create tunnel device: ") + tun_last_error()); - syslog(LOG_INFO, "opened tunnel device: %s", this->device); + syslog(LOG_INFO, "opened tunnel device: %s", this->device.data()); + + std::stringstream cmdline; #ifdef WIN32 - snprintf(cmdline, sizeof(cmdline), "netsh interface ipv4 set subinterface \"%s\" mtu=%d", this->device, mtu); - winsystem(cmdline); + cmdline << "netsh interface ipv4 set subinterface \"" << this->device + << "\" mtu=" << mtu; + winsystem(cmdline.str().data()); #else - snprintf(cmdline, sizeof(cmdline), "/sbin/ifconfig %s mtu %u", this->device, mtu); - if (system(cmdline) != 0) + cmdline << "/sbin/ifconfig " << this->device << " mtu " << mtu; + if (system(cmdline.str().data()) != 0) syslog(LOG_ERR, "could not set tun device mtu"); #endif } Tun::~Tun() { - tun_close(fd, device); + tun_close(fd, &device[0]); } void Tun::setIp(uint32_t ip, uint32_t destIp) { - char cmdline[512]; + std::stringstream cmdline; string ips = Utility::formatIp(ip); string destIps = Utility::formatIp(destIp); #ifdef WIN32 - snprintf(cmdline, sizeof(cmdline), "netsh interface ip set address name=\"%s\" " - "static %s 255.255.255.0", device, ips.c_str()); - winsystem(cmdline); + cmdline << "netsh interface ip set address name=\"" << device << "\" " + << "static " << ips << " 255.255.255.0"; + winsystem(cmdline.str().data()); if (!tun_set_ip(fd, ip, ip & 0xffffff00, 0xffffff00)) syslog(LOG_ERR, "could not set tun device driver ip address: %s", tun_last_error()); #elif LINUX - snprintf(cmdline, sizeof(cmdline), "/sbin/ifconfig %s %s netmask 255.255.255.0", device, ips.c_str()); - if (system(cmdline) != 0) + cmdline << "/sbin/ifconfig " << device << " " << ips << " netmask 255.255.255.0"; + if (system(cmdline.str().data()) != 0) syslog(LOG_ERR, "could not set tun device ip address"); #else - snprintf(cmdline, sizeof(cmdline), "/sbin/ifconfig %s %s %s netmask 255.255.255.255", device, ips.c_str(), destIps.c_str()); - if (system(cmdline) != 0) + cmdline << "/sbin/ifconfig " << device << " " << ips << " " << destIps + << " netmask 255.255.255.255"; + if (system(cmdline.str().data()) != 0) syslog(LOG_ERR, "could not set tun device ip address"); #endif } diff --git a/src/tun.h b/src/tun.h index d7e7a73..3e57d00 100644 --- a/src/tun.h +++ b/src/tun.h @@ -28,7 +28,7 @@ class Tun { public: - Tun(const char *device, int mtu); + Tun(const std::string *device, int mtu); ~Tun(); int getFd() { return fd; } @@ -40,7 +40,7 @@ public: void setIp(uint32_t ip, uint32_t destIp); protected: - char device[VTUN_DEV_LEN]; + std::string device; int mtu; int fd; diff --git a/src/utility.cpp b/src/utility.cpp index 5c1c235..87521a7 100644 --- a/src/utility.cpp +++ b/src/utility.cpp @@ -22,14 +22,16 @@ #include #include #include +#include -using namespace std; - -string Utility::formatIp(uint32_t ip) +std::string Utility::formatIp(uint32_t ip) { - char buffer[16]; - sprintf(buffer, "%d.%d.%d.%d", (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff); - return buffer; + std::stringstream s; + s << ((ip >> 24) & 0xff) << '.' + << ((ip >> 16) & 0xff) << '.' + << ((ip >> 8) & 0xff) << '.' + << ((ip >> 0) & 0xff); + return s.str(); } int Utility::rand() diff --git a/src/worker.cpp b/src/worker.cpp index 3cdce79..c6f8dc5 100644 --- a/src/worker.cpp +++ b/src/worker.cpp @@ -28,9 +28,10 @@ #include #include #include -#include +#include -using namespace std; +using std::cout; +using std::endl; Worker::TunnelHeader::Magic::Magic(const char *magic) { @@ -48,54 +49,37 @@ bool Worker::TunnelHeader::Magic::operator!=(const Magic &other) const return memcmp(data, other.data, sizeof(data)) != 0; } -Worker::Worker(int tunnelMtu, const char *deviceName, bool answerEcho, uid_t uid, gid_t gid) +Worker::Worker(int tunnelMtu, const std::string *deviceName, bool answerEcho, + uid_t uid, gid_t gid) + : echo(tunnelMtu + sizeof(TunnelHeader)), tun(deviceName, tunnelMtu) { this->tunnelMtu = tunnelMtu; this->answerEcho = answerEcho; this->uid = uid; this->gid = gid; this->privilegesDropped = false; - - echo = NULL; - tun = NULL; - - try - { - echo = new Echo(tunnelMtu + sizeof(TunnelHeader)); - tun = new Tun(deviceName, tunnelMtu); - } - catch (...) - { - delete echo; - delete tun; - - throw; - } } -Worker::~Worker() -{ - delete echo; - delete tun; -} - -void Worker::sendEcho(const TunnelHeader::Magic &magic, int type, int length, uint32_t realIp, bool reply, uint16_t id, uint16_t seq) +void Worker::sendEcho(const TunnelHeader::Magic &magic, TunnelHeader::Type type, + int length, uint32_t realIp, bool reply, uint16_t id, uint16_t seq) { if (length > payloadBufferSize()) throw Exception("packet too big"); - TunnelHeader *header = (TunnelHeader *)echo->sendPayloadBuffer(); + TunnelHeader *header = (TunnelHeader *)echo.sendPayloadBuffer(); header->magic = magic; header->type = type; - DEBUG_ONLY(printf("sending: type %d, length %d, id %d, seq %d\n", type, length, id, seq)); + DEBUG_ONLY( + cout << "sending: type " << type << ", length " << length + << ", id " << id << ", seq " << seq << endl); - echo->send(length + sizeof(TunnelHeader), realIp, reply, id, seq); + echo.send(length + sizeof(TunnelHeader), realIp, reply, id, seq); } void Worker::sendToTun(int length) { - tun->write(echoReceivePayloadBuffer(), length); + tun.write(echoReceivePayloadBuffer(), length); } void Worker::setTimeout(Time delta) @@ -108,7 +92,7 @@ void Worker::run() now = Time::now(); alive = true; - int maxFd = echo->getFd() > tun->getFd() ? echo->getFd() : tun->getFd(); + int maxFd = echo.getFd() > tun.getFd() ? echo.getFd() : tun.getFd(); while (alive) { @@ -116,8 +100,8 @@ void Worker::run() Time timeout; FD_ZERO(&fs); - FD_SET(tun->getFd(), &fs); - FD_SET(echo->getFd(), &fs); + FD_SET(tun.getFd(), &fs); + FD_SET(echo.getFd(), &fs); if (nextTimeout != Time::ZERO) { @@ -127,7 +111,8 @@ void Worker::run() } // wait for data or timeout - int result = select(maxFd + 1 , &fs, NULL, NULL, nextTimeout != Time::ZERO ? &timeout.getTimeval() : NULL); + timeval *timeval = nextTimeout != Time::ZERO ? &timeout.getTimeval() : NULL; + int result = select(maxFd + 1 , &fs, NULL, NULL, timeval); if (result == -1) { if (alive) @@ -146,43 +131,43 @@ void Worker::run() } // icmp data - if (FD_ISSET(echo->getFd(), &fs)) + if (FD_ISSET(echo.getFd(), &fs)) { bool reply; uint16_t id, seq; uint32_t ip; - int dataLength = echo->receive(ip, reply, id, seq); + int dataLength = echo.receive(ip, reply, id, seq); if (dataLength != -1) { bool valid = dataLength >= sizeof(TunnelHeader); if (valid) { - TunnelHeader *header = (TunnelHeader *)echo->receivePayloadBuffer(); + TunnelHeader *header = (TunnelHeader *)echo.receivePayloadBuffer(); DEBUG_ONLY( - printf("received: type %d, length %d, id %d, seq %d\n", - header->type, (int)(dataLength - sizeof(TunnelHeader)), - id, seq)); + cout << "received: type " << header->type + << ", length " << dataLength - sizeof(TunnelHeader) + << ", id " << id << ", seq " << seq << endl); valid = handleEchoData(*header, dataLength - sizeof(TunnelHeader), ip, reply, id, seq); } if (!valid && !reply && answerEcho) { - memcpy(echo->sendPayloadBuffer(), echo->receivePayloadBuffer(), dataLength); - echo->send(dataLength, ip, true, id, seq); + memcpy(echo.sendPayloadBuffer(), echo.receivePayloadBuffer(), dataLength); + echo.send(dataLength, ip, true, id, seq); } } } // data from tun - if (FD_ISSET(tun->getFd(), &fs)) + if (FD_ISSET(tun.getFd(), &fs)) { uint32_t sourceIp, destIp; - int dataLength = tun->read(echoSendPayloadBuffer(), sourceIp, destIp); + int dataLength = tun.read(echoSendPayloadBuffer(), sourceIp, destIp); if (dataLength == 0) throw Exception("tunnel closed"); @@ -232,10 +217,10 @@ void Worker::handleTimeout() { } char *Worker::echoSendPayloadBuffer() { - return echo->sendPayloadBuffer() + sizeof(TunnelHeader); + return echo.sendPayloadBuffer() + sizeof(TunnelHeader); } char *Worker::echoReceivePayloadBuffer() { - return echo->receivePayloadBuffer() + sizeof(TunnelHeader); + return echo.receivePayloadBuffer() + sizeof(TunnelHeader); } diff --git a/src/worker.h b/src/worker.h index a1f11e7..3ac0367 100644 --- a/src/worker.h +++ b/src/worker.h @@ -30,8 +30,9 @@ class Worker { public: - Worker(int tunnelMtu, const char *deviceName, bool answerEcho, uid_t uid, gid_t gid); - virtual ~Worker(); + Worker(int tunnelMtu, const std::string *deviceName, bool answerEcho, + uid_t uid, gid_t gid); + virtual ~Worker() { } virtual void run(); virtual void stop(); @@ -52,21 +53,21 @@ protected: char data[4]; }; - Magic magic; - uint8_t type; - enum Type { - TYPE_RESET_CONNECTION = 1, - TYPE_CONNECTION_REQUEST = 2, - TYPE_CHALLENGE = 3, - TYPE_CHALLENGE_RESPONSE = 4, - TYPE_CONNECTION_ACCEPT = 5, - TYPE_CHALLENGE_ERROR = 6, - TYPE_DATA = 7, - TYPE_POLL = 8, - TYPE_SERVER_FULL = 9 + TYPE_RESET_CONNECTION = 1, + TYPE_CONNECTION_REQUEST = 2, + TYPE_CHALLENGE = 3, + TYPE_CHALLENGE_RESPONSE = 4, + TYPE_CONNECTION_ACCEPT = 5, + TYPE_CHALLENGE_ERROR = 6, + TYPE_DATA = 7, + TYPE_POLL = 8, + TYPE_SERVER_FULL = 9 }; + + Magic magic; + uint8_t type; }; // size = 5 virtual bool handleEchoData(const TunnelHeader &header, int dataLength, @@ -75,8 +76,8 @@ protected: uint32_t destIp); // to echoSendPayloadBuffer virtual void handleTimeout(); - void sendEcho(const TunnelHeader::Magic &magic, int type, int length, - uint32_t realIp, bool reply, uint16_t id, uint16_t seq); + void sendEcho(const TunnelHeader::Magic &magic, TunnelHeader::Type type, + int length, uint32_t realIp, bool reply, uint16_t id, uint16_t seq); void sendToTun(int length); // from echoReceivePayloadBuffer void setTimeout(Time delta); @@ -88,8 +89,8 @@ protected: void dropPrivileges(); - Echo *echo; - Tun *tun; + Echo echo; + Tun tun; bool alive; bool answerEcho; int tunnelMtu;