diff --git a/client.cpp b/client.cpp index 18d6c52..8e3372c 100644 --- a/client.cpp +++ b/client.cpp @@ -24,8 +24,9 @@ License along with FlashMQ. If not, see . #include #include "logger.h" +#include "utils.h" -Client::Client(int fd, std::shared_ptr threadData, SSL *ssl, bool websocket, std::shared_ptr settings, bool fuzzMode) : +Client::Client(int fd, std::shared_ptr threadData, SSL *ssl, bool websocket, struct sockaddr *addr, std::shared_ptr settings, bool fuzzMode) : fd(fd), fuzzMode(fuzzMode), initialBufferSize(settings->clientInitialBufferSize), // The client is constructed in the main thread, so we need to use its settings copy @@ -37,6 +38,13 @@ Client::Client(int fd, std::shared_ptr threadData, SSL *ssl, bool we { int flags = fcntl(fd, F_GETFL); fcntl(fd, F_SETFL, flags | O_NONBLOCK); + + this->address = sockaddrToString(addr); + + if (ssl) + transportStr = websocket ? "TCP/Websocket/MQTT/SSL" : "TCP/MQTT/SSL"; + else + transportStr = websocket ? "TCP/Websocket/MQTT/Non-SSL" : "TCP/MQTT/Non-SSL"; } Client::~Client() @@ -255,10 +263,9 @@ bool Client::writeBufIntoFd() std::string Client::repr() { - std::ostringstream a; - a << "[Client=" << clientid << ", user=" << username << ", fd=" << fd << "]"; - a.flush(); - return a.str(); + std::string s = formatString("[ClientID='%s', username='%s', fd=%d, keepalive=%ds, transport='%s', address='%s']", + clientid.c_str(), username.c_str(), fd, keepalive, this->transportStr.c_str(), this->address.c_str()); + return s; } /** diff --git a/client.h b/client.h index 1bdf858..076efe5 100644 --- a/client.h +++ b/client.h @@ -40,7 +40,6 @@ License along with FlashMQ. If not, see . #define MQTT_HEADER_LENGH 2 -// TODO: give accepted addr, for showing in logs class Client { friend class IoWrapper; @@ -54,6 +53,8 @@ class Client const size_t maxPacketSize = 0; IoWrapper ioWrapper; + std::string transportStr; + std::string address; CirBuf readbuf; CirBuf writebuf; @@ -88,7 +89,7 @@ class Client void setReadyForReading(bool val); public: - Client(int fd, std::shared_ptr threadData, SSL *ssl, bool websocket, std::shared_ptr settings, bool fuzzMode=false); + Client(int fd, std::shared_ptr threadData, SSL *ssl, bool websocket, struct sockaddr *addr, std::shared_ptr settings, bool fuzzMode=false); Client(const Client &other) = delete; Client(Client &&other) = delete; ~Client(); diff --git a/mainapp.cpp b/mainapp.cpp index 4b9be20..e9f296b 100644 --- a/mainapp.cpp +++ b/mainapp.cpp @@ -496,12 +496,12 @@ void MainApp::start() std::shared_ptr threaddata(new ThreadData(0, subscriptionStore, settings)); - std::shared_ptr client(new Client(fd, threaddata, nullptr, fuzzWebsockets, settings, true)); - std::shared_ptr subscriber(new Client(fdnull, threaddata, nullptr, fuzzWebsockets, settings, true)); + std::shared_ptr client(new Client(fd, threaddata, nullptr, fuzzWebsockets, nullptr, settings, true)); + std::shared_ptr subscriber(new Client(fdnull, threaddata, nullptr, fuzzWebsockets, nullptr, settings, true)); subscriber->setClientProperties(ProtocolVersion::Mqtt311, "subscriber", "subuser", true, 60, true); subscriber->setAuthenticated(true); - std::shared_ptr websocketsubscriber(new Client(fdnull2, threaddata, nullptr, true, settings, true)); + std::shared_ptr websocketsubscriber(new Client(fdnull2, threaddata, nullptr, true, nullptr, settings, true)); websocketsubscriber->setClientProperties(ProtocolVersion::Mqtt311, "websocketsubscriber", "websocksubuser", true, 60, true); websocketsubscriber->setAuthenticated(true); websocketsubscriber->setFakeUpgraded(); @@ -573,10 +573,11 @@ void MainApp::start() logger->logf(LOG_INFO, "Accepting connection on thread %d on %s", thread_data->threadnr, listener->getProtocolName().c_str()); - struct sockaddr addr; - memset(&addr, 0, sizeof(struct sockaddr)); - socklen_t len = sizeof(struct sockaddr); - int fd = check(accept(cur_fd, &addr, &len)); + struct sockaddr_in6 addrBiggest; + struct sockaddr *addr = reinterpret_cast(&addrBiggest); + socklen_t len = sizeof(struct sockaddr_in6); + memset(addr, 0, len); + int fd = check(accept(cur_fd, addr, &len)); SSL *clientSSL = nullptr; if (listener->isSsl()) @@ -593,7 +594,7 @@ void MainApp::start() SSL_set_fd(clientSSL, fd); } - std::shared_ptr client(new Client(fd, thread_data, clientSSL, listener->websocket, settings)); + std::shared_ptr client(new Client(fd, thread_data, clientSSL, listener->websocket, addr, settings)); thread_data->giveClient(client); } else diff --git a/utils.cpp b/utils.cpp index 5bcc75f..50a57b0 100644 --- a/utils.cpp +++ b/utils.cpp @@ -600,3 +600,35 @@ ssize_t getFileSize(const std::string &path) return statbuf.st_size; } + +std::string sockaddrToString(sockaddr *addr) +{ + if (!addr) + return "[unknown address]"; + + char buf[INET6_ADDRSTRLEN]; + void *addr_in = nullptr; + + if (addr->sa_family == AF_INET) + { + struct sockaddr_in *ipv4sockAddr = reinterpret_cast(addr); + addr_in = &ipv4sockAddr->sin_addr; + } + else if (addr->sa_family == AF_INET6) + { + struct sockaddr_in6 *ipv6sockAddr = reinterpret_cast(addr); + addr_in = &ipv6sockAddr->sin6_addr; + } + + if (addr_in) + { + const char *rc = inet_ntop(addr->sa_family, addr_in, buf, INET6_ADDRSTRLEN); + if (rc) + { + std::string remote_addr(rc); + return remote_addr; + } + } + + return "[unknown address]"; +} diff --git a/utils.h b/utils.h index 796928c..0906ea7 100644 --- a/utils.h +++ b/utils.h @@ -91,5 +91,7 @@ BindAddr getBindAddr(int family, const std::string &bindAddress, int port); ssize_t getFileSize(const std::string &path); +std::string sockaddrToString(struct sockaddr *addr); + #endif // UTILS_H