diff --git a/src/tools/hexnet.cpp b/src/tools/hexnet.cpp index 83fa01b..856f813 100644 --- a/src/tools/hexnet.cpp +++ b/src/tools/hexnet.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -40,8 +41,11 @@ int64_t mtu = 1500; std::string host; in_port_t port; sockpp::tcp_socket* tcpSocket; +sockpp::tcp6_socket* tcp6Socket; sockpp::tcp_acceptor tcpAcceptor; +sockpp::tcp6_acceptor tcp6Acceptor; std::mutex tcpSocketMutex; +std::mutex tcp6SocketMutex; std::mutex consoleMutex; // used for coordinated graceful exit across threads bool exitProgram = false; @@ -50,12 +54,20 @@ void signalHandler(int signal) { exitProgram = true; // if still waiting for incoming connection, stop waiting tcpAcceptor.shutdown(); + tcp6Acceptor.shutdown(); // tell sockpp to close TCP socket if open because it blocks when trying // to read and there is no data - if (*tcpSocket) { + + if (tcpSocket != nullptr && *tcpSocket) { // Intentionally not using the mutex here + std::cout << "test\n"; tcpSocket->shutdown(SHUT_RD); } + + if (tcp6Socket != nullptr && *tcp6Socket) { + // Intentionally not using the mutex here + tcp6Socket->shutdown(SHUT_RD); + } //TODO: figure out if - and how - this applies to UDP // Priority is to finish up all unfinished business that can be finished up. @@ -64,32 +76,71 @@ void signalHandler(int signal) { consoleMutex.lock(); std::cerr << "Received signal " << signal << ", shutting down." << std::endl; consoleMutex.unlock(); + std::exit(signal); } void readFromTCPSocket(sockpp::tcp_socket* socket, int64_t mtu) { - ssize_t numBytes; - uint8_t buffer[mtu]; - tcpSocketMutex.lock(); - while (!exitProgram && (numBytes = socket->read(buffer, sizeof(buffer))) > 0) { - tcpSocketMutex.unlock(); - consoleMutex.lock(); - for (ssize_t i=0; iread(buffer, sizeof(buffer))) > 0) { tcpSocketMutex.unlock(); consoleMutex.lock(); - std::cerr << std::endl << "Connection closed." << std::endl; + for (ssize_t i=0; iread(buffer, sizeof(buffer))) > 0) { + tcp6SocketMutex.unlock(); + consoleMutex.lock(); + for (ssize_t i=0; i flags; flags.push_back(CLI::Flag('4', "ipv4", "use IPv4, defaults to both when -4 and -6 are omitted, otherwise uses what is specified")); @@ -140,42 +191,72 @@ int main(int argc, char* argv[]){ port = (in_port_t) std::stoi(cliParser.getArgument(0).value); if (listenMode) { - if (ipv6) { - std::cerr << "IPv6 support is not implented yet." << std::endl; - return EXIT_UNIMPLEMENTED; - } if (udp) { std::cerr << "UDP support is not implemented yet." << std::endl; return EXIT_UNIMPLEMENTED; } - std::cerr << "Listening on port " << port << "." << std::endl; - sockpp::socket_initializer socketInitializer; - tcpAcceptor = sockpp::tcp_acceptor(port); + if (ipv6) { + //std::cerr << "IPv6 support is not implented yet." << std::endl; + //return EXIT_UNIMPLEMENTED; + std::cerr << "Listening on port " << port << "." << std::endl; + sockpp::socket_initializer socketInitializer; + tcp6Acceptor = sockpp::tcp6_acceptor(port); - if (!tcpAcceptor) { - std::cerr << "Error while creating TCP acceptor: " << tcpAcceptor.last_error_str() << std::endl; - return EXIT_RUNTIME; + if(!tcp6Acceptor){ + std::cerr << "Error while creating TCP6 acceptor: " << tcp6Acceptor.last_error_str() << std::endl; + return EXIT_RUNTIME; + } + + sockpp::inet6_address peer; + tcp6Socket = new sockpp::tcp6_socket(); + *tcp6Socket = tcp6Acceptor.accept(&peer); + + std::cerr << "Incoming connection from " << peer << std::endl; + + if (!(*tcp6Socket)) { + std::cerr << "Error on incoming connection: " << tcp6Acceptor.last_error_str() << std::endl; + delete tcp6Socket; + return EXIT_RUNTIME; + } + + std::thread threadReadFromTCP6 = std::thread(readFromTCP6Socket, tcp6Socket, mtu); + threadReadFromTCP6.join(); + + delete tcp6Socket; + return EXIT_SUCCESS; } - sockpp::inet_address peer; - tcpSocket = new sockpp::tcp_socket(); - *tcpSocket = tcpAcceptor.accept(&peer); + if(ipv4){ + std::cerr << "Listening on port " << port << "." << std::endl; - std::cerr << "Incoming connection from " << peer << std::endl; + sockpp::socket_initializer socketInitializer; + tcpAcceptor = sockpp::tcp_acceptor(port); + + if (!tcpAcceptor) { + std::cerr << "Error while creating TCP acceptor: " << tcpAcceptor.last_error_str() << std::endl; + return EXIT_RUNTIME; + } + + sockpp::inet_address peer; + tcpSocket = new sockpp::tcp_socket(); + *tcpSocket = tcpAcceptor.accept(&peer); + + std::cerr << "Incoming connection from " << peer << std::endl; + + if (!(*tcpSocket)) { + std::cerr << "Error on incoming connection: " << tcpAcceptor.last_error_str() << std::endl; + delete tcpSocket; + return EXIT_RUNTIME; + } + + std::thread threadReadFromTCP = std::thread(readFromTCPSocket, tcpSocket, mtu); + threadReadFromTCP.join(); - if (!(*tcpSocket)) { - std::cerr << "Error on incoming connection: " << tcpAcceptor.last_error_str() << std::endl; delete tcpSocket; - return EXIT_RUNTIME; + return EXIT_SUCCESS; } - - std::thread threadReadTCP = std::thread(readFromTCPSocket, tcpSocket, mtu); - threadReadTCP.join(); - - delete tcpSocket; - return EXIT_SUCCESS; - + } else { std::cerr << "Client mode is not implemented yet." << std::endl; return EXIT_UNIMPLEMENTED;