Merge branch 'development' into LTS_development
This commit is contained in:
commit
dd5d8815be
6 changed files with 72 additions and 17 deletions
18
lib/json.cpp
18
lib/json.cpp
|
@ -612,6 +612,24 @@ JSON::Value &JSON::Value::assignFrom(const Value &rhs, const std::set<std::strin
|
||||||
return *this;
|
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.
|
/// Sets this JSON::Value to be equal to the given JSON::Value.
|
||||||
JSON::Value &JSON::Value::operator=(const JSON::Value &rhs){
|
JSON::Value &JSON::Value::operator=(const JSON::Value &rhs){
|
||||||
null();
|
null();
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
static const std::set<std::string> emptyset;
|
||||||
|
|
||||||
/// JSON-related classes and functions
|
/// JSON-related classes and functions
|
||||||
namespace JSON{
|
namespace JSON{
|
||||||
|
|
||||||
|
@ -50,10 +52,11 @@ namespace JSON{
|
||||||
// comparison operators
|
// comparison operators
|
||||||
bool operator==(const Value &rhs) const;
|
bool operator==(const Value &rhs) const;
|
||||||
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 compareExcept(const Value &rhs, const std::set<std::string> &skip = emptyset) const;
|
||||||
bool compareOnly(const Value &rhs, const std::set<std::string> &check) const;
|
bool compareOnly(const Value &rhs, const std::set<std::string> &check = emptyset) const;
|
||||||
// assignment operators
|
// 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 Value &rhs);
|
||||||
Value &operator=(const std::string &rhs);
|
Value &operator=(const std::string &rhs);
|
||||||
Value &operator=(const char *rhs);
|
Value &operator=(const char *rhs);
|
||||||
|
|
|
@ -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){
|
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";
|
char tmpBuffer[17] = "\000\000\000\000\000\000\000\000\000\000\377\377\000\000\000\000";
|
||||||
switch (remoteaddr.sin6_family){
|
switch (remoteaddr.sin6_family){
|
||||||
|
@ -238,7 +247,7 @@ std::string Socket::resolveHostToBestExternalAddrGuess(const std::string &host,
|
||||||
hints.ai_flags = AI_ADDRCONFIG;
|
hints.ai_flags = AI_ADDRCONFIG;
|
||||||
int s = getaddrinfo(host.c_str(), 0, &hints, &result);
|
int s = getaddrinfo(host.c_str(), 0, &hints, &result);
|
||||||
if (s != 0){
|
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 "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,13 +445,21 @@ void Socket::Buffer::clear(){
|
||||||
}
|
}
|
||||||
|
|
||||||
void Socket::Connection::setBoundAddr(){
|
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){
|
if (!isTrueSocket){
|
||||||
boundaddr = "";
|
boundaddr = "";
|
||||||
return;
|
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;
|
struct sockaddr_in6 tmpaddr;
|
||||||
socklen_t len = sizeof(tmpaddr);
|
socklen_t len = sizeof(tmpaddr);
|
||||||
if (!getsockname(sSend, (sockaddr *)&tmpaddr, &len)){
|
if (!getsockname(getSocket(), (sockaddr *)&tmpaddr, &len)){
|
||||||
static char addrconv[INET6_ADDRSTRLEN];
|
static char addrconv[INET6_ADDRSTRLEN];
|
||||||
if (tmpaddr.sin6_family == AF_INET6){
|
if (tmpaddr.sin6_family == AF_INET6){
|
||||||
boundaddr = inet_ntop(AF_INET6, &(tmpaddr.sin6_addr), addrconv, INET6_ADDRSTRLEN);
|
boundaddr = inet_ntop(AF_INET6, &(tmpaddr.sin6_addr), addrconv, INET6_ADDRSTRLEN);
|
||||||
|
@ -649,12 +666,18 @@ void Socket::Connection::drop(){
|
||||||
|
|
||||||
/// Returns internal socket number.
|
/// Returns internal socket number.
|
||||||
int Socket::Connection::getSocket(){
|
int Socket::Connection::getSocket(){
|
||||||
|
#ifdef SSL
|
||||||
|
if (sslConnected){return server_fd->fd;}
|
||||||
|
#endif
|
||||||
if (sSend != -1){return sSend;}
|
if (sSend != -1){return sSend;}
|
||||||
return sRecv;
|
return sRecv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns non-piped internal socket number.
|
/// Returns non-piped internal socket number.
|
||||||
int Socket::Connection::getPureSocket(){
|
int Socket::Connection::getPureSocket(){
|
||||||
|
#ifdef SSL
|
||||||
|
if (sslConnected){return server_fd->fd;}
|
||||||
|
#endif
|
||||||
if (!isTrueSocket){return -1;}
|
if (!isTrueSocket){return -1;}
|
||||||
return sSend;
|
return sSend;
|
||||||
}
|
}
|
||||||
|
@ -790,6 +813,8 @@ void Socket::Connection::open(std::string host, int port, bool nonblock, bool wi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sslConnected = true;
|
sslConnected = true;
|
||||||
|
isTrueSocket = true;
|
||||||
|
setBoundAddr();
|
||||||
Blocking = true;
|
Blocking = true;
|
||||||
if (nonblock){setBlocking(false);}
|
if (nonblock){setBlocking(false);}
|
||||||
DONTEVEN_MSG("SSL connect success");
|
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;
|
hints.ai_flags = AI_ADDRCONFIG;
|
||||||
int s = getaddrinfo(host.c_str(), ss.str().c_str(), &hints, &result);
|
int s = getaddrinfo(host.c_str(), ss.str().c_str(), &hints, &result);
|
||||||
if (s != 0){
|
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());
|
FAIL_MSG("Could not connect to %s:%i! Error: %s", host.c_str(), port, lastErr.c_str());
|
||||||
close();
|
close();
|
||||||
return;
|
return;
|
||||||
|
@ -1605,7 +1630,7 @@ void Socket::UDPConnection::SetDestination(std::string destIp, uint32_t port){
|
||||||
hints.ai_next = NULL;
|
hints.ai_next = NULL;
|
||||||
int s = getaddrinfo(destIp.c_str(), ss.str().c_str(), &hints, &result);
|
int s = getaddrinfo(destIp.c_str(), ss.str().c_str(), &hints, &result);
|
||||||
if (s != 0){
|
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;
|
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 (iface == "0.0.0.0" || iface.length() == 0){
|
||||||
if ((addr_ret = getaddrinfo(0, ss.str().c_str(), &hints, &addr_result)) != 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;
|
return 0;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if ((addr_ret = getaddrinfo(iface.c_str(), ss.str().c_str(), &hints, &addr_result)) != 0){
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1844,7 +1869,7 @@ uint16_t Socket::UDPConnection::bind(int port, std::string iface, const std::str
|
||||||
memset(&mreq6, 0, sizeof(mreq6));
|
memset(&mreq6, 0, sizeof(mreq6));
|
||||||
struct addrinfo *reslocal, *resmulti;
|
struct addrinfo *reslocal, *resmulti;
|
||||||
if ((addr_ret = getaddrinfo(iface.c_str(), 0, &hints, &resmulti)) != 0){
|
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();
|
close();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1883,7 +1908,7 @@ uint16_t Socket::UDPConnection::bind(int port, std::string iface, const std::str
|
||||||
if (family == AF_INET6){
|
if (family == AF_INET6){
|
||||||
INFO_MSG("Registering for IPv6 multicast on interface %s", curIface.c_str());
|
INFO_MSG("Registering for IPv6 multicast on interface %s", curIface.c_str());
|
||||||
if ((addr_ret = getaddrinfo(curIface.c_str(), 0, &hints, &reslocal)) != 0){
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
memcpy(&mreq6.ipv6mr_multiaddr, &((sockaddr_in6 *)resmulti->ai_addr)->sin6_addr,
|
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{
|
}else{
|
||||||
INFO_MSG("Registering for IPv4 multicast on interface %s", curIface.c_str());
|
INFO_MSG("Registering for IPv4 multicast on interface %s", curIface.c_str());
|
||||||
if ((addr_ret = getaddrinfo(curIface.c_str(), 0, &hints, &reslocal)) != 0){
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
mreq4.imr_multiaddr = ((sockaddr_in *)resmulti->ai_addr)->sin_addr;
|
mreq4.imr_multiaddr = ((sockaddr_in *)resmulti->ai_addr)->sin_addr;
|
||||||
|
|
|
@ -87,6 +87,12 @@ uint64_t Util::bootMS() {
|
||||||
return ((uint64_t)t.tv_sec) * 1000 + t.tv_nsec / 1000000;
|
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.
|
/// Gets the current time in microseconds.
|
||||||
uint64_t Util::getMicros() {
|
uint64_t Util::getMicros() {
|
||||||
struct timespec t;
|
struct timespec t;
|
||||||
|
|
|
@ -11,9 +11,10 @@ namespace Util {
|
||||||
void sleep(int64_t ms); ///< Sleeps for roughly the indicated amount of milliseconds.
|
void sleep(int64_t ms); ///< Sleeps for roughly the indicated amount of milliseconds.
|
||||||
uint64_t getMS(); ///< Gets the current time in milliseconds.
|
uint64_t getMS(); ///< Gets the current time in milliseconds.
|
||||||
uint64_t bootSecs(); ///< Gets the current system uptime in seconds.
|
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 bootMS(); ///< Gets the current system uptime in milliseconds.
|
||||||
uint64_t getMicros();///<Gets the current time in microseconds
|
uint64_t getMicros(); ///< Gets the current time in microseconds
|
||||||
uint64_t getMicros(uint64_t previous);///<Gets the time difference in microseconds.
|
uint64_t getMicros(uint64_t previous); ///< Gets the time difference in microseconds.
|
||||||
uint64_t getNTP();
|
uint64_t getNTP();
|
||||||
uint64_t epoch(); ///< Gets the amount of seconds since 01/01/1970.
|
uint64_t epoch(); ///< Gets the amount of seconds since 01/01/1970.
|
||||||
std::string getUTCString(uint64_t epoch = 0);
|
std::string getUTCString(uint64_t epoch = 0);
|
||||||
|
|
|
@ -121,7 +121,9 @@ namespace Mist{
|
||||||
}
|
}
|
||||||
args.push_back("");
|
args.push_back("");
|
||||||
Util::Procs::socketList.insert(fd[0]);
|
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);
|
pid_t http_proc = Util::Procs::StartPiped(args, &(fd[1]), &(fd[1]), &fderr);
|
||||||
|
unsetenv("MIST_BOUND_ADDR");
|
||||||
close(fd[1]);
|
close(fd[1]);
|
||||||
if (http_proc < 2){
|
if (http_proc < 2){
|
||||||
FAIL_MSG("Could not spawn MistOutHTTP process for SSL connection!");
|
FAIL_MSG("Could not spawn MistOutHTTP process for SSL connection!");
|
||||||
|
|
Loading…
Add table
Reference in a new issue