From 4a621ea5c03e6c01c543a5fa33cd9317f1c96c50 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Tue, 19 Nov 2019 12:01:59 +0100 Subject: [PATCH 1/4] Fixed IP detection over HTTPS output --- lib/socket.cpp | 18 +++++++++++++++++- src/output/output_https.cpp | 2 ++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/socket.cpp b/lib/socket.cpp index bd8a5275..2abbf2fd 100644 --- a/lib/socket.cpp +++ b/lib/socket.cpp @@ -436,13 +436,21 @@ void Socket::Buffer::clear(){ } void Socket::Connection::setBoundAddr(){ + //If a bound address was set through environment (e.g. HTTPS output), restore it from there. + char * envbound = getenv("MIST_BOUND_ADDR"); + if (envbound){ + boundaddr = envbound; + return; + } + //If we can't read the address, don't try if (!isTrueSocket){ boundaddr = ""; return; } + //Otherwise, read from socket pointer. Works for both SSL and non-SSL sockets, and real sockets passed as fd's, but not for non-sockets (duh) struct sockaddr_in6 tmpaddr; socklen_t len = sizeof(tmpaddr); - if (!getsockname(sSend, (sockaddr *)&tmpaddr, &len)){ + if (!getsockname(getSocket(), (sockaddr *)&tmpaddr, &len)){ static char addrconv[INET6_ADDRSTRLEN]; if (tmpaddr.sin6_family == AF_INET6){ boundaddr = inet_ntop(AF_INET6, &(tmpaddr.sin6_addr), addrconv, INET6_ADDRSTRLEN); @@ -649,12 +657,18 @@ void Socket::Connection::drop(){ /// Returns internal socket number. int Socket::Connection::getSocket(){ +#ifdef SSL + if (sslConnected){return server_fd->fd;} +#endif if (sSend != -1){return sSend;} return sRecv; } /// Returns non-piped internal socket number. int Socket::Connection::getPureSocket(){ +#ifdef SSL + if (sslConnected){return server_fd->fd;} +#endif if (!isTrueSocket){return -1;} return sSend; } @@ -790,6 +804,8 @@ void Socket::Connection::open(std::string host, int port, bool nonblock, bool wi } } sslConnected = true; + isTrueSocket = true; + setBoundAddr(); Blocking = true; if (nonblock){setBlocking(false);} DONTEVEN_MSG("SSL connect success"); diff --git a/src/output/output_https.cpp b/src/output/output_https.cpp index 3b2fd15c..b1e41df6 100644 --- a/src/output/output_https.cpp +++ b/src/output/output_https.cpp @@ -111,7 +111,9 @@ namespace Mist{ } args.push_back(""); Util::Procs::socketList.insert(fd[0]); + setenv("MIST_BOUND_ADDR", myConn.getBoundAddress().c_str(), 1); pid_t http_proc = Util::Procs::StartPiped(args, &(fd[1]), &(fd[1]), &fderr); + unsetenv("MIST_BOUND_ADDR"); close(fd[1]); if (http_proc < 2){ FAIL_MSG("Could not spawn MistOutHTTP process for SSL connection!"); From b27a74c884e4d7404b44ea9c4a2ffa0c8d86777f Mon Sep 17 00:00:00 2001 From: Thulinma Date: Thu, 12 Dec 2019 00:19:14 +0100 Subject: [PATCH 2/4] Added JSON::Value::extend() --- lib/json.cpp | 18 ++++++++++++++++++ lib/json.h | 9 ++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/json.cpp b/lib/json.cpp index f67e5ef5..2316faf6 100644 --- a/lib/json.cpp +++ b/lib/json.cpp @@ -612,6 +612,24 @@ JSON::Value &JSON::Value::assignFrom(const Value &rhs, const std::set &skip){ + //Null values turn into objects automatically for sanity reasons + if (myType == EMPTY){myType = OBJECT;} + //Abort if either value is not an object + if (myType != rhs.myType || myType != OBJECT){return *this;} + jsonForEachConst(rhs, i){ + if (!skip.count(i.key())){ + if (!objVal.count(i.key()) || !i->isObject()){ + (*this)[i.key()] = *i; + }else{ + (*this)[i.key()].extend(*i, skip); + } + } + } + return *this; +} + /// Sets this JSON::Value to be equal to the given JSON::Value. JSON::Value &JSON::Value::operator=(const JSON::Value &rhs){ null(); diff --git a/lib/json.h b/lib/json.h index 9238457e..aae8717a 100644 --- a/lib/json.h +++ b/lib/json.h @@ -10,6 +10,8 @@ #include #include +static const std::set emptyset; + /// JSON-related classes and functions namespace JSON{ @@ -50,10 +52,11 @@ namespace JSON{ // comparison operators bool operator==(const Value &rhs) const; bool operator!=(const Value &rhs) const; - bool compareExcept(const Value &rhs, const std::set &skip) const; - bool compareOnly(const Value &rhs, const std::set &check) const; + bool compareExcept(const Value &rhs, const std::set &skip = emptyset) const; + bool compareOnly(const Value &rhs, const std::set &check = emptyset) const; // assignment operators - Value &assignFrom(const Value &rhs, const std::set &skip); + Value &extend(const Value &rhs, const std::set &skip = emptyset); + Value &assignFrom(const Value &rhs, const std::set &skip = emptyset); Value &operator=(const Value &rhs); Value &operator=(const std::string &rhs); Value &operator=(const char *rhs); From 5c6341a92afdd7ee074731e6e55728ae965792b8 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Tue, 17 Dec 2019 10:31:51 +0100 Subject: [PATCH 3/4] Made all instances of gai_strerror recursively call strerror as needed --- lib/socket.cpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/lib/socket.cpp b/lib/socket.cpp index 2abbf2fd..6e34365b 100644 --- a/lib/socket.cpp +++ b/lib/socket.cpp @@ -33,6 +33,15 @@ static const char *addrFam(int f){ } } +/// Calls gai_strerror with the given argument, calling regular strerror on the global errno as needed +static const char * gai_strmagic(int errcode){ + if (errcode == EAI_SYSTEM){ + return strerror(errno); + }else{ + return gai_strerror(errcode); + } +} + static std::string getIPv6BinAddr(const struct sockaddr_in6 &remoteaddr){ char tmpBuffer[17] = "\000\000\000\000\000\000\000\000\000\000\377\377\000\000\000\000"; switch (remoteaddr.sin6_family){ @@ -238,7 +247,7 @@ std::string Socket::resolveHostToBestExternalAddrGuess(const std::string &host, hints.ai_flags = AI_ADDRCONFIG; int s = getaddrinfo(host.c_str(), 0, &hints, &result); if (s != 0){ - FAIL_MSG("Could not resolve %s! Error: %s", host.c_str(), gai_strerror(s)); + FAIL_MSG("Could not resolve %s! Error: %s", host.c_str(), gai_strmagic(s)); return ""; } @@ -825,7 +834,7 @@ void Socket::Connection::open(std::string host, int port, bool nonblock, bool wi hints.ai_flags = AI_ADDRCONFIG; int s = getaddrinfo(host.c_str(), ss.str().c_str(), &hints, &result); if (s != 0){ - lastErr = gai_strerror(s); + lastErr = gai_strmagic(s); FAIL_MSG("Could not connect to %s:%i! Error: %s", host.c_str(), port, lastErr.c_str()); close(); return; @@ -1621,7 +1630,7 @@ void Socket::UDPConnection::SetDestination(std::string destIp, uint32_t port){ hints.ai_next = NULL; int s = getaddrinfo(destIp.c_str(), ss.str().c_str(), &hints, &result); if (s != 0){ - FAIL_MSG("Could not connect UDP socket to %s:%i! Error: %s", destIp.c_str(), port, gai_strerror(s)); + FAIL_MSG("Could not connect UDP socket to %s:%i! Error: %s", destIp.c_str(), port, gai_strmagic(s)); return; } @@ -1778,12 +1787,12 @@ uint16_t Socket::UDPConnection::bind(int port, std::string iface, const std::str if (iface == "0.0.0.0" || iface.length() == 0){ if ((addr_ret = getaddrinfo(0, ss.str().c_str(), &hints, &addr_result)) != 0){ - FAIL_MSG("Could not resolve %s for UDP: %s", iface.c_str(), gai_strerror(addr_ret)); + FAIL_MSG("Could not resolve %s for UDP: %s", iface.c_str(), gai_strmagic(addr_ret)); return 0; } }else{ if ((addr_ret = getaddrinfo(iface.c_str(), ss.str().c_str(), &hints, &addr_result)) != 0){ - FAIL_MSG("Could not resolve %s for UDP: %s", iface.c_str(), gai_strerror(addr_ret)); + FAIL_MSG("Could not resolve %s for UDP: %s", iface.c_str(), gai_strmagic(addr_ret)); return 0; } } @@ -1860,7 +1869,7 @@ uint16_t Socket::UDPConnection::bind(int port, std::string iface, const std::str memset(&mreq6, 0, sizeof(mreq6)); struct addrinfo *reslocal, *resmulti; if ((addr_ret = getaddrinfo(iface.c_str(), 0, &hints, &resmulti)) != 0){ - WARN_MSG("Unable to parse multicast address: %s", gai_strerror(addr_ret)); + WARN_MSG("Unable to parse multicast address: %s", gai_strmagic(addr_ret)); close(); return 0; } @@ -1899,7 +1908,7 @@ uint16_t Socket::UDPConnection::bind(int port, std::string iface, const std::str if (family == AF_INET6){ INFO_MSG("Registering for IPv6 multicast on interface %s", curIface.c_str()); if ((addr_ret = getaddrinfo(curIface.c_str(), 0, &hints, &reslocal)) != 0){ - WARN_MSG("Unable to resolve IPv6 interface address %s: %s", curIface.c_str(), gai_strerror(addr_ret)); + WARN_MSG("Unable to resolve IPv6 interface address %s: %s", curIface.c_str(), gai_strmagic(addr_ret)); continue; } memcpy(&mreq6.ipv6mr_multiaddr, &((sockaddr_in6 *)resmulti->ai_addr)->sin6_addr, @@ -1914,7 +1923,7 @@ uint16_t Socket::UDPConnection::bind(int port, std::string iface, const std::str }else{ INFO_MSG("Registering for IPv4 multicast on interface %s", curIface.c_str()); if ((addr_ret = getaddrinfo(curIface.c_str(), 0, &hints, &reslocal)) != 0){ - WARN_MSG("Unable to resolve IPv4 interface address %s: %s", curIface.c_str(), gai_strerror(addr_ret)); + WARN_MSG("Unable to resolve IPv4 interface address %s: %s", curIface.c_str(), gai_strmagic(addr_ret)); continue; } mreq4.imr_multiaddr = ((sockaddr_in *)resmulti->ai_addr)->sin_addr; From 091926a963155610506a12ea8c21b64edba14053 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Thu, 12 Mar 2020 16:23:16 +0100 Subject: [PATCH 4/4] Added Util::unixMS --- lib/timing.cpp | 6 ++++++ lib/timing.h | 11 ++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/timing.cpp b/lib/timing.cpp index c2ebd4a3..a6f7ec7c 100644 --- a/lib/timing.cpp +++ b/lib/timing.cpp @@ -87,6 +87,12 @@ uint64_t Util::bootMS() { return ((uint64_t)t.tv_sec) * 1000 + t.tv_nsec / 1000000; } +uint64_t Util::unixMS(){ + struct timeval t; + gettimeofday(&t, 0); + return ((uint64_t)t.tv_sec) * 1000 + t.tv_usec / 1000; +} + /// Gets the current time in microseconds. uint64_t Util::getMicros() { struct timespec t; diff --git a/lib/timing.h b/lib/timing.h index 6fac1a13..3d8a88e5 100644 --- a/lib/timing.h +++ b/lib/timing.h @@ -9,11 +9,12 @@ namespace Util { void wait(int64_t ms); ///< Sleeps for the indicated amount of milliseconds or longer. void sleep(int64_t ms); ///< Sleeps for roughly the indicated amount of milliseconds. - uint64_t getMS(); ///< Gets the current time in milliseconds. - uint64_t bootSecs(); ///< Gets the current system uptime in seconds. - uint64_t bootMS(); ///< Gets the current system uptime in milliseconds. - uint64_t getMicros();///