From ada8af0b828a18aa24bb7a82021f20318a12f4ca Mon Sep 17 00:00:00 2001 From: dongresource Date: Tue, 8 Dec 2020 21:02:37 +0100 Subject: [PATCH] Print informative error messages for socket operations Windows implementation pending. --- src/CNProtocol.cpp | 23 +++++++++++++++++++++-- src/CNProtocol.hpp | 1 + src/Monitor.cpp | 13 +++++++++++-- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/CNProtocol.cpp b/src/CNProtocol.cpp index baa559e..5f0bddc 100644 --- a/src/CNProtocol.cpp +++ b/src/CNProtocol.cpp @@ -78,7 +78,7 @@ bool CNSocket::sendData(uint8_t* data, int size) { maxTries--; continue; // try again } - std::cout << "[FATAL] SOCKET ERROR: " << OF_ERRNO << std::endl; + printSocketError("send"); return false; // error occured while sending bytes } sentBytes += sent; @@ -180,6 +180,7 @@ void CNSocket::step() { activelyReading = true; } else if (OF_ERRNO != OF_EWOULD) { // serious socket issue, disconnect connection + printSocketError("recv"); kill(); return; } @@ -192,6 +193,7 @@ void CNSocket::step() { readBufferIndex += recved; else if (OF_ERRNO != OF_EWOULD) { // serious socket issue, disconnect connection + printSocketError("recv"); kill(); return; } @@ -214,6 +216,14 @@ void CNSocket::step() { } } +void printSocketError(const char *call) { +#ifdef _WIN32 + // TODO: ycc plz implement +#else + perror(call); +#endif +} + bool setSockNonblocking(SOCKET listener, SOCKET newSock) { #ifdef _WIN32 unsigned long mode = 1; @@ -221,6 +231,7 @@ bool setSockNonblocking(SOCKET listener, SOCKET newSock) { #else if (fcntl(newSock, F_SETFL, (fcntl(newSock, F_GETFL, 0) | O_NONBLOCK)) != 0) { #endif + printSocketError("fcntl"); std::cerr << "[WARN] OpenFusion: fcntl failed on new connection" << std::endl; #ifdef _WIN32 shutdown(newSock, SD_BOTH); @@ -241,6 +252,7 @@ void CNServer::init() { // create socket file descriptor sock = socket(AF_INET, SOCK_STREAM, 0); if (SOCKETINVALID(sock)) { + printSocketError("socket"); std::cerr << "[FATAL] OpenFusion: socket failed" << std::endl; exit(EXIT_FAILURE); } @@ -253,6 +265,7 @@ void CNServer::init() { if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) != 0) { #endif std::cerr << "[FATAL] OpenFusion: setsockopt failed" << std::endl; + printSocketError("setsockopt"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; @@ -264,11 +277,13 @@ void CNServer::init() { // Bind to the port if (SOCKETERROR(bind(sock, (struct sockaddr *)&address, addressSize))) { std::cerr << "[FATAL] OpenFusion: bind failed" << std::endl; + printSocketError("bind"); exit(EXIT_FAILURE); } if (SOCKETERROR(listen(sock, SOMAXCONN))) { std::cerr << "[FATAL] OpenFusion: listen failed" << std::endl; + printSocketError("listen"); exit(EXIT_FAILURE); } @@ -279,6 +294,7 @@ void CNServer::init() { #else if (fcntl(sock, F_SETFL, (fcntl(sock, F_GETFL, 0) | O_NONBLOCK)) != 0) { #endif + printSocketError("fcntl"); std::cerr << "[FATAL] OpenFusion: fcntl failed" << std::endl; exit(EXIT_FAILURE); } @@ -317,6 +333,7 @@ void CNServer::start() { continue; #endif std::cout << "[FATAL] poll() returned error" << std::endl; + printSocketError("poll"); terminate(0); } @@ -337,8 +354,10 @@ void CNServer::start() { } SOCKET newConnectionSocket = accept(sock, (struct sockaddr *)&address, (socklen_t*)&addressSize); - if (SOCKETINVALID(newConnectionSocket)) + if (SOCKETINVALID(newConnectionSocket)) { + printSocketError("accept"); continue; + } if (!setSockNonblocking(sock, newConnectionSocket)) continue; diff --git a/src/CNProtocol.hpp b/src/CNProtocol.hpp index 49be477..a91454e 100644 --- a/src/CNProtocol.hpp +++ b/src/CNProtocol.hpp @@ -118,6 +118,7 @@ inline bool validInVarPacket(size_t base, int32_t npayloads, size_t plsize, size return true; } +void printSocketError(const char *func); bool setSockNonblocking(SOCKET listener, SOCKET newSock); namespace CNSocketEncryption { diff --git a/src/Monitor.cpp b/src/Monitor.cpp index 0be3fe4..bc0b333 100644 --- a/src/Monitor.cpp +++ b/src/Monitor.cpp @@ -15,6 +15,7 @@ SOCKET Monitor::init() { listener = socket(AF_INET, SOCK_STREAM, 0); if (SOCKETERROR(listener)) { std::cout << "Failed to create monitor socket" << std::endl; + printSocketError("socket"); exit(1); } @@ -25,6 +26,7 @@ SOCKET Monitor::init() { #endif if (SOCKETERROR(setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)))) { std::cout << "Failed to set SO_REUSEADDR on monitor socket" << std::endl; + printSocketError("setsockopt"); exit(1); } @@ -34,11 +36,13 @@ SOCKET Monitor::init() { if (SOCKETERROR(bind(listener, (struct sockaddr*)&address, sizeof(address)))) { std::cout << "Failed to bind to monitor port" << std::endl; + printSocketError("bind"); exit(1); } if (SOCKETERROR(listen(listener, SOMAXCONN))) { std::cout << "Failed to listen on monitor port" << std::endl; + printSocketError("listen"); exit(1); } @@ -49,6 +53,7 @@ SOCKET Monitor::init() { if (fcntl(listener, F_SETFL, (fcntl(listener, F_GETFL, 0) | O_NONBLOCK)) != 0) { #endif std::cerr << "[FATAL] OpenFusion: fcntl failed" << std::endl; + printSocketError("fcntl"); exit(EXIT_FAILURE); } @@ -66,6 +71,8 @@ static bool transmit(std::list::iterator& it, char *buff, int len) { while (n < len) { n += send(sock, buff+n, len-n, 0); if (SOCKETERROR(n)) { + printSocketError("send"); + #ifdef _WIN32 shutdown(sock, SD_BOTH); closesocket(sock); @@ -90,7 +97,7 @@ void Monitor::tick(CNServer *serv, time_t delta) { int n; auto it = sockets.begin(); - outer: +outer: while (it != sockets.end()) { if (!transmit(it, (char*)"begin\n", 6)) continue; @@ -129,8 +136,10 @@ bool Monitor::acceptConnection(SOCKET fd, uint16_t revents) { } int sock = accept(listener, (struct sockaddr*)&address, &len); - if (SOCKETERROR(sock)) + if (SOCKETERROR(sock)) { + printSocketError("accept"); return true; + } setSockNonblocking(listener, sock);