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;
|
||||
}
|
||||
|
||||
/// 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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace Util {
|
|||
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 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.
|
||||
|
|
|
@ -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!");
|
||||
|
|
Loading…
Add table
Reference in a new issue