diff --git a/Simple-Web-Server b/Simple-Web-Server index d1bf544d..e70509e0 160000 --- a/Simple-Web-Server +++ b/Simple-Web-Server @@ -1 +1 @@ -Subproject commit d1bf544d9266bdf5b86517e4a70de63216529e5b +Subproject commit e70509e078ade2eb9679862ab6a48b4ee2fefb66 diff --git a/nvhttp.cpp b/nvhttp.cpp index 79276e24..a35d14f6 100644 --- a/nvhttp.cpp +++ b/nvhttp.cpp @@ -19,6 +19,7 @@ #include "utility.h" #include "stream.h" #include "nvhttp.h" +#include "platform/common.h" namespace nvhttp { @@ -34,6 +35,7 @@ namespace pt = boost::property_tree; std::string read_file(const char *path); +std::string local_ip; using https_server_t = SimpleWeb::Server; using http_server_t = SimpleWeb::Server; @@ -396,10 +398,10 @@ void serverinfo(std::shared_ptr::Response> res tree.put("root.GfeVersion", GFE_VERSION); tree.put("root.uniqueid", config::nvhttp.unique_id); tree.put("root.mac", "42:45:F0:65:D6:F4"); - tree.put("root.LocalIP", "192.168.0.195"); //FIXME: Should be determined at runtime + tree.put("root.LocalIP", local_ip); if(config::nvhttp.external_ip.empty()) { - tree.put("root.ExternalIP", "192.168.0.195"); + tree.put("root.ExternalIP", local_ip); } else { tree.put("root.ExternalIP", config::nvhttp.external_ip); @@ -497,6 +499,13 @@ void appasset(std::shared_ptr::Response> respo } void start() { + local_ip = platf::get_local_ip(); + if(local_ip.empty()) { + std::cout << "Error: Could not determine the local ip-address"sv << std::endl; + + exit(8); + } + load_devices(); conf_intern.pkey = read_file(config::nvhttp.pkey.c_str()); diff --git a/platform/common.h b/platform/common.h index c7002c6f..ec4ac958 100644 --- a/platform/common.h +++ b/platform/common.h @@ -5,6 +5,7 @@ #ifndef SUNSHINE_COMMON_H #define SUNSHINE_COMMON_H +#include #include namespace platf { @@ -19,6 +20,7 @@ using img_t = util::safe_ptr; using mic_t = util::safe_ptr; using audio_t = util::safe_ptr; +std::string get_local_ip(); display_t display(); img_t snapshot(display_t &display); mic_t microphone(); @@ -34,7 +36,6 @@ void move_mouse(display_t::element_type *display, int deltaX, int deltaY); void button_mouse(display_t::element_type *display, int button, bool release); void scroll(display_t::element_type *display, int distance); void keyboard(display_t::element_type *display, uint16_t modcode, bool release); - } #endif //SUNSHINE_COMMON_H diff --git a/platform/linux.cpp b/platform/linux.cpp index 0680d52f..b0b2657b 100644 --- a/platform/linux.cpp +++ b/platform/linux.cpp @@ -4,6 +4,10 @@ #include "common.h" +#include +#include +#include + #include #include #include @@ -15,9 +19,72 @@ #include #include +#include namespace platf { using namespace std::literals; + +using ifaddr_t = util::safe_ptr; + +ifaddr_t get_ifaddrs() { + ifaddrs *p { nullptr }; + + getifaddrs(&p); + + return ifaddr_t { p }; +} + +std::string from_sockaddr(const sockaddr *const ip_addr) { + char data[INET6_ADDRSTRLEN]; + + auto family = ip_addr->sa_family; + if(family == AF_INET6) { + inet_ntop(AF_INET6, &((sockaddr_in6*)ip_addr)->sin6_addr, data, INET6_ADDRSTRLEN); + } + + if(family == AF_INET) { + inet_ntop(AF_INET, &((sockaddr_in*)ip_addr)->sin_addr, data, INET_ADDRSTRLEN); + } + + return std::string { data }; +} + +std::string get_local_ip(int family) { + std::bitset<2> family_f {}; + + if(family == 0) { + family_f[0] = true; + family_f[1] = true; + } + + if(family == AF_INET) { + family_f[0] = true; + } + + if(family == AF_INET6) { + family_f[1] = true; + } + + + std::string ip_addr; + auto ifaddr = get_ifaddrs(); + for(auto pos = ifaddr.get(); pos != nullptr; pos = pos->ifa_next) { + if(pos->ifa_addr && pos->ifa_flags & IFF_UP && !(pos->ifa_flags & IFF_LOOPBACK)) { + if( + (family_f[0] && pos->ifa_addr->sa_family == AF_INET) || + (family_f[1] && pos->ifa_addr->sa_family == AF_INET6) + ){ + ip_addr = from_sockaddr(pos->ifa_addr); + break; + } + } + } + + return ip_addr; +} + +std::string get_local_ip() { return get_local_ip(AF_INET); } + struct display_attr_t { display_attr_t() : display { XOpenDisplay(nullptr) }, window { DefaultRootWindow(display) }, attr {} { XGetWindowAttributes(display, window, &attr);