tools/hexnet: Implement ipv6 support.
parent
ebcf436a18
commit
e0648720bb
|
@ -19,6 +19,7 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <sockpp/tcp_acceptor.h>
|
#include <sockpp/tcp_acceptor.h>
|
||||||
|
#include <sockpp/tcp6_acceptor.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
|
@ -40,8 +41,11 @@ int64_t mtu = 1500;
|
||||||
std::string host;
|
std::string host;
|
||||||
in_port_t port;
|
in_port_t port;
|
||||||
sockpp::tcp_socket* tcpSocket;
|
sockpp::tcp_socket* tcpSocket;
|
||||||
|
sockpp::tcp6_socket* tcp6Socket;
|
||||||
sockpp::tcp_acceptor tcpAcceptor;
|
sockpp::tcp_acceptor tcpAcceptor;
|
||||||
|
sockpp::tcp6_acceptor tcp6Acceptor;
|
||||||
std::mutex tcpSocketMutex;
|
std::mutex tcpSocketMutex;
|
||||||
|
std::mutex tcp6SocketMutex;
|
||||||
std::mutex consoleMutex;
|
std::mutex consoleMutex;
|
||||||
// used for coordinated graceful exit across threads
|
// used for coordinated graceful exit across threads
|
||||||
bool exitProgram = false;
|
bool exitProgram = false;
|
||||||
|
@ -50,12 +54,20 @@ void signalHandler(int signal) {
|
||||||
exitProgram = true;
|
exitProgram = true;
|
||||||
// if still waiting for incoming connection, stop waiting
|
// if still waiting for incoming connection, stop waiting
|
||||||
tcpAcceptor.shutdown();
|
tcpAcceptor.shutdown();
|
||||||
|
tcp6Acceptor.shutdown();
|
||||||
// tell sockpp to close TCP socket if open because it blocks when trying
|
// tell sockpp to close TCP socket if open because it blocks when trying
|
||||||
// to read and there is no data
|
// to read and there is no data
|
||||||
if (*tcpSocket) {
|
|
||||||
|
if (tcpSocket != nullptr && *tcpSocket) {
|
||||||
// Intentionally not using the mutex here
|
// Intentionally not using the mutex here
|
||||||
|
std::cout << "test\n";
|
||||||
tcpSocket->shutdown(SHUT_RD);
|
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
|
//TODO: figure out if - and how - this applies to UDP
|
||||||
|
|
||||||
// Priority is to finish up all unfinished business that can be finished up.
|
// Priority is to finish up all unfinished business that can be finished up.
|
||||||
|
@ -64,32 +76,71 @@ void signalHandler(int signal) {
|
||||||
consoleMutex.lock();
|
consoleMutex.lock();
|
||||||
std::cerr << "Received signal " << signal << ", shutting down." << std::endl;
|
std::cerr << "Received signal " << signal << ", shutting down." << std::endl;
|
||||||
consoleMutex.unlock();
|
consoleMutex.unlock();
|
||||||
|
std::exit(signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void readFromTCPSocket(sockpp::tcp_socket* socket, int64_t mtu) {
|
void readFromTCPSocket(sockpp::tcp_socket* socket, int64_t mtu) {
|
||||||
ssize_t numBytes;
|
ssize_t numBytes;
|
||||||
uint8_t buffer[mtu];
|
uint8_t buffer[mtu];
|
||||||
tcpSocketMutex.lock();
|
tcpSocketMutex.lock();
|
||||||
while (!exitProgram && (numBytes = socket->read(buffer, sizeof(buffer))) > 0) {
|
while (!exitProgram && (numBytes = socket->read(buffer, sizeof(buffer))) > 0) {
|
||||||
tcpSocketMutex.unlock();
|
|
||||||
consoleMutex.lock();
|
|
||||||
for (ssize_t i=0; i<numBytes; i++) {
|
|
||||||
std::cout << std::hex << std::setfill('0') << std::setw(2) << (short) buffer[i];
|
|
||||||
}
|
|
||||||
std::cout.flush();
|
|
||||||
consoleMutex.unlock();
|
|
||||||
tcpSocketMutex.lock();
|
|
||||||
}
|
|
||||||
tcpSocketMutex.unlock();
|
tcpSocketMutex.unlock();
|
||||||
consoleMutex.lock();
|
consoleMutex.lock();
|
||||||
std::cerr << std::endl << "Connection closed." << std::endl;
|
for (ssize_t i=0; i<numBytes; i++) {
|
||||||
|
std::cout << std::hex << std::setfill('0') << std::setw(2) << (short) buffer[i];
|
||||||
|
}
|
||||||
|
std::cout.flush();
|
||||||
consoleMutex.unlock();
|
consoleMutex.unlock();
|
||||||
|
tcpSocketMutex.lock();
|
||||||
|
}
|
||||||
|
tcpSocketMutex.unlock();
|
||||||
|
consoleMutex.lock();
|
||||||
|
std::cerr << std::endl << "Connection closed." << std::endl;
|
||||||
|
consoleMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void readFromTCP6Socket(sockpp::tcp6_socket* socket, int64_t mtu){
|
||||||
|
ssize_t numBytes;
|
||||||
|
uint8_t buffer[mtu];
|
||||||
|
tcp6SocketMutex.lock();
|
||||||
|
while (!exitProgram && (numBytes = socket->read(buffer, sizeof(buffer))) > 0) {
|
||||||
|
tcp6SocketMutex.unlock();
|
||||||
|
consoleMutex.lock();
|
||||||
|
for (ssize_t i=0; i<numBytes; i++) {
|
||||||
|
std::cout << std::hex << std::setfill('0') << std::setw(2) << (short) buffer[i];
|
||||||
|
}
|
||||||
|
std::cout.flush();
|
||||||
|
consoleMutex.unlock();
|
||||||
|
tcp6SocketMutex.lock();
|
||||||
|
}
|
||||||
|
tcp6SocketMutex.unlock();
|
||||||
|
consoleMutex.lock();
|
||||||
|
std::cerr << std::endl << "Connection closed." << std::endl;
|
||||||
|
consoleMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeToTCPSocket(sockpp::tcp_socket* socket){
|
||||||
|
while (!exitProgram) {
|
||||||
|
//TODO: Implement locking/unlocking/threading shenanigans
|
||||||
|
}
|
||||||
|
consoleMutex.lock();
|
||||||
|
std::cerr << std::endl << "Connection closed." << std::endl;
|
||||||
|
consoleMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeToTCP6Socket(sockpp::tcp6_socket* socket){
|
||||||
|
while (!exitProgram) {
|
||||||
|
//TODO: Implement locking/unlocking/threading shenanigans
|
||||||
|
}
|
||||||
|
consoleMutex.lock();
|
||||||
|
std::cerr << std::endl << "Connection closed." << std::endl;
|
||||||
|
consoleMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]){
|
int main(int argc, char* argv[]){
|
||||||
|
|
||||||
signal(SIGINT, signalHandler);
|
std::signal(SIGINT, signalHandler);
|
||||||
signal(SIGTERM, signalHandler);
|
std::signal(SIGTERM, signalHandler);
|
||||||
|
|
||||||
std::vector<CLI::Flag> flags;
|
std::vector<CLI::Flag> flags;
|
||||||
flags.push_back(CLI::Flag('4', "ipv4", "use IPv4, defaults to both when -4 and -6 are omitted, otherwise uses what is specified"));
|
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);
|
port = (in_port_t) std::stoi(cliParser.getArgument(0).value);
|
||||||
|
|
||||||
if (listenMode) {
|
if (listenMode) {
|
||||||
if (ipv6) {
|
|
||||||
std::cerr << "IPv6 support is not implented yet." << std::endl;
|
|
||||||
return EXIT_UNIMPLEMENTED;
|
|
||||||
}
|
|
||||||
if (udp) {
|
if (udp) {
|
||||||
std::cerr << "UDP support is not implemented yet." << std::endl;
|
std::cerr << "UDP support is not implemented yet." << std::endl;
|
||||||
return EXIT_UNIMPLEMENTED;
|
return EXIT_UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
std::cerr << "Listening on port " << port << "." << std::endl;
|
|
||||||
|
|
||||||
sockpp::socket_initializer socketInitializer;
|
if (ipv6) {
|
||||||
tcpAcceptor = sockpp::tcp_acceptor(port);
|
//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) {
|
if(!tcp6Acceptor){
|
||||||
std::cerr << "Error while creating TCP acceptor: " << tcpAcceptor.last_error_str() << std::endl;
|
std::cerr << "Error while creating TCP6 acceptor: " << tcp6Acceptor.last_error_str() << std::endl;
|
||||||
return EXIT_RUNTIME;
|
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;
|
if(ipv4){
|
||||||
tcpSocket = new sockpp::tcp_socket();
|
std::cerr << "Listening on port " << port << "." << std::endl;
|
||||||
*tcpSocket = tcpAcceptor.accept(&peer);
|
|
||||||
|
|
||||||
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;
|
delete tcpSocket;
|
||||||
return EXIT_RUNTIME;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::thread threadReadTCP = std::thread(readFromTCPSocket, tcpSocket, mtu);
|
|
||||||
threadReadTCP.join();
|
|
||||||
|
|
||||||
delete tcpSocket;
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Client mode is not implemented yet." << std::endl;
|
std::cerr << "Client mode is not implemented yet." << std::endl;
|
||||||
return EXIT_UNIMPLEMENTED;
|
return EXIT_UNIMPLEMENTED;
|
||||||
|
|
Loading…
Reference in New Issue