Merge branch 'development' into LTS_development

This commit is contained in:
Thulinma 2020-03-12 16:26:48 +01:00
commit dd5d8815be
6 changed files with 72 additions and 17 deletions

View file

@ -612,6 +612,24 @@ JSON::Value &JSON::Value::assignFrom(const Value &rhs, const std::set<std::strin
return *this;
}
/// Extends this JSON::Value object with the given JSON::Value object, skipping given member(s) recursively.
JSON::Value &JSON::Value::extend(const Value &rhs, const std::set<std::string> &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();

View file

@ -10,6 +10,8 @@
#include <string>
#include <vector>
static const std::set<std::string> 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<std::string> &skip) const;
bool compareOnly(const Value &rhs, const std::set<std::string> &check) const;
bool compareExcept(const Value &rhs, const std::set<std::string> &skip = emptyset) const;
bool compareOnly(const Value &rhs, const std::set<std::string> &check = emptyset) const;
// assignment operators
Value &assignFrom(const Value &rhs, const std::set<std::string> &skip);
Value &extend(const Value &rhs, const std::set<std::string> &skip = emptyset);
Value &assignFrom(const Value &rhs, const std::set<std::string> &skip = emptyset);
Value &operator=(const Value &rhs);
Value &operator=(const std::string &rhs);
Value &operator=(const char *rhs);

View file

@ -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 "";
}
@ -436,13 +445,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 +666,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 +813,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");
@ -809,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;
@ -1605,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;
}
@ -1762,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;
}
}
@ -1844,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;
}
@ -1883,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,
@ -1898,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;

View file

@ -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;

View file

@ -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();///<Gets the current time in microseconds
uint64_t getMicros(uint64_t previous);///<Gets the time difference in microseconds.
uint64_t getMS(); ///< Gets the current time in milliseconds.
uint64_t bootSecs(); ///< Gets the current system uptime in seconds.
uint64_t unixMS(); ///< Gets the current Unix time in milliseconds.
uint64_t bootMS(); ///< Gets the current system uptime in milliseconds.
uint64_t getMicros(); ///< Gets the current time in microseconds
uint64_t getMicros(uint64_t previous); ///< Gets the time difference in microseconds.
uint64_t getNTP();
uint64_t epoch(); ///< Gets the amount of seconds since 01/01/1970.
std::string getUTCString(uint64_t epoch = 0);

View file

@ -121,7 +121,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!");