Merge 1e3aca0837
into e032d14a48
This commit is contained in:
commit
28afc5708b
|
@ -6,17 +6,25 @@ set (CMAKE_AUTORCC ON)
|
||||||
set (CMAKE_AUTOUIC ON)
|
set (CMAKE_AUTOUIC ON)
|
||||||
set (CMAKE_INCLUDE_CURRENT_DIR ON)
|
set (CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
|
||||||
file (GLOB GUI_SOURCE_FILES src/*.cpp src/*.h)
|
|
||||||
file (GLOB GUI_UI_FILES src/*.ui)
|
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
set (GUI_RC_FILES res/win/Barrier.rc)
|
set (resources res/win/Barrier.rc)
|
||||||
|
set (arch "win32")
|
||||||
|
else()
|
||||||
|
set (arch "unix")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
file (GLOB sources src/*.cpp src/${arch}/*.cpp)
|
||||||
|
file (GLOB headers src/*.h src/${arch}/*.h)
|
||||||
|
file (GLOB designs src/*.ui)
|
||||||
|
|
||||||
|
if (BARRIER_ADD_HEADERS)
|
||||||
|
list (APPEND sources ${headers})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_executable (barrier WIN32
|
add_executable (barrier WIN32
|
||||||
${GUI_SOURCE_FILES}
|
${sources}
|
||||||
${GUI_UI_FILES}
|
${designs}
|
||||||
${GUI_RC_FILES}
|
${resources}
|
||||||
res/Barrier.qrc
|
res/Barrier.qrc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -32,7 +40,7 @@ if (WIN32)
|
||||||
HINTS ENV BONJOUR_SDK_HOME
|
HINTS ENV BONJOUR_SDK_HOME
|
||||||
PATH_SUFFIXES "Lib/x64")
|
PATH_SUFFIXES "Lib/x64")
|
||||||
set_target_properties (barrier PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT")
|
set_target_properties (barrier PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT")
|
||||||
target_link_libraries (barrier ${DNSSD_LIB})
|
target_link_libraries (barrier ${DNSSD_LIB} Ws2_32.lib Iphlpapi.lib)
|
||||||
elseif (APPLE)
|
elseif (APPLE)
|
||||||
find_library(APPSERVICES_LIB ApplicationServices)
|
find_library(APPSERVICES_LIB ApplicationServices)
|
||||||
target_link_libraries(barrier ${APPSERVICES_LIB})
|
target_link_libraries(barrier ${APPSERVICES_LIB})
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Debauchee
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string default_interface_ip();
|
||||||
|
|
||||||
|
}
|
|
@ -20,6 +20,7 @@
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "ZeroconfRegister.h"
|
#include "ZeroconfRegister.h"
|
||||||
#include "ZeroconfBrowser.h"
|
#include "ZeroconfBrowser.h"
|
||||||
|
#include "DefaultInterfaceIP.h"
|
||||||
|
|
||||||
#include <QtNetwork>
|
#include <QtNetwork>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
@ -34,12 +35,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const QStringList preferedIPAddress(
|
|
||||||
QStringList() <<
|
|
||||||
"192.168." <<
|
|
||||||
"10." <<
|
|
||||||
"172.");
|
|
||||||
|
|
||||||
const char* ZeroconfService:: m_ServerServiceName = "_barrierServerZeroconf._tcp";
|
const char* ZeroconfService:: m_ServerServiceName = "_barrierServerZeroconf._tcp";
|
||||||
const char* ZeroconfService:: m_ClientServiceName = "_barrierClientZeroconf._tcp";
|
const char* ZeroconfService:: m_ClientServiceName = "_barrierClientZeroconf._tcp";
|
||||||
|
|
||||||
|
@ -124,27 +119,6 @@ void ZeroconfService::errorHandle(DNSServiceErrorType errorCode)
|
||||||
tr("Error code: %1.").arg(errorCode));
|
tr("Error code: %1.").arg(errorCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ZeroconfService::getLocalIPAddresses()
|
|
||||||
{
|
|
||||||
QStringList addresses;
|
|
||||||
foreach (const QHostAddress& address, QNetworkInterface::allAddresses()) {
|
|
||||||
if (address.protocol() == QAbstractSocket::IPv4Protocol &&
|
|
||||||
address != QHostAddress(QHostAddress::LocalHost)) {
|
|
||||||
addresses.append(address.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (const QString& preferedIP, preferedIPAddress) {
|
|
||||||
foreach (const QString& address, addresses) {
|
|
||||||
if (address.startsWith(preferedIP)) {
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ZeroconfService::registerService(bool server)
|
bool ZeroconfService::registerService(bool server)
|
||||||
{
|
{
|
||||||
bool result = true;
|
bool result = true;
|
||||||
|
@ -159,7 +133,7 @@ bool ZeroconfService::registerService(bool server)
|
||||||
else {
|
else {
|
||||||
m_pZeroconfRegister = new ZeroconfRegister(this);
|
m_pZeroconfRegister = new ZeroconfRegister(this);
|
||||||
if (server) {
|
if (server) {
|
||||||
QString localIP = getLocalIPAddresses();
|
QString localIP = QString::fromStdString(Debauchee::default_interface_ip());
|
||||||
if (localIP.isEmpty()) {
|
if (localIP.isEmpty()) {
|
||||||
QMessageBox::warning(m_pMainWindow, tr("Barrier"),
|
QMessageBox::warning(m_pMainWindow, tr("Barrier"),
|
||||||
tr("Failed to get local IP address. "
|
tr("Failed to get local IP address. "
|
||||||
|
|
|
@ -42,7 +42,6 @@ private slots:
|
||||||
void errorHandle(DNSServiceErrorType errorCode);
|
void errorHandle(DNSServiceErrorType errorCode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString getLocalIPAddresses();
|
|
||||||
bool registerService(bool server);
|
bool registerService(bool server);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -67,6 +67,13 @@ int main(int argc, char* argv[])
|
||||||
/* Workaround for QTBUG-40332 - "High ping when QNetworkAccessManager is instantiated" */
|
/* Workaround for QTBUG-40332 - "High ping when QNetworkAccessManager is instantiated" */
|
||||||
::setenv ("QT_BEARER_POLL_TIMEOUT", "-1", 1);
|
::setenv ("QT_BEARER_POLL_TIMEOUT", "-1", 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
// winsock needs to be initialized for DefaultInterfaceIP
|
||||||
|
WSADATA wd;
|
||||||
|
WSAStartup(MAKEWORD(2, 0), &wd);
|
||||||
|
#endif
|
||||||
|
|
||||||
QCoreApplication::setOrganizationName("Debauchee");
|
QCoreApplication::setOrganizationName("Debauchee");
|
||||||
QCoreApplication::setOrganizationDomain("github.com");
|
QCoreApplication::setOrganizationDomain("github.com");
|
||||||
QCoreApplication::setApplicationName("Barrier");
|
QCoreApplication::setApplicationName("Barrier");
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
#include "IfAddrsResource.h"
|
||||||
|
#include "SocketResource.h"
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <linux/wireless.h>
|
||||||
|
#else
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <net/if_media.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace Debauchee
|
||||||
|
{
|
||||||
|
|
||||||
|
static bool is_wireless(const char * ifname, const SocketResource& sock)
|
||||||
|
{
|
||||||
|
#ifdef __linux__
|
||||||
|
struct iwreq req;
|
||||||
|
::memset(&req, 0, sizeof(struct iwreq));
|
||||||
|
::strncpy(req.ifr_name, ifname, IFNAMSIZ - 1);
|
||||||
|
return ioctl(sock, SIOCGIWMODE, &req) >= 0;
|
||||||
|
#else
|
||||||
|
struct ifmediareq req;
|
||||||
|
::memset(&req, 0, sizeof(struct ifmediareq));
|
||||||
|
::strncpy(req.ifm_name, ifname, IFNAMSIZ - 1);
|
||||||
|
if (ioctl(sock, SIOCGIFMEDIA, &req) >= 0 &&
|
||||||
|
(req.ifm_status & IFM_AVALID)
|
||||||
|
) {
|
||||||
|
return IFM_TYPE(req.ifm_active) == IFM_IEEE80211;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_wireless(const char * ifname)
|
||||||
|
{
|
||||||
|
if (ifname) {
|
||||||
|
SocketResource sock(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (sock.is_valid()) {
|
||||||
|
return is_wireless(ifname, sock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string default_interface_ip()
|
||||||
|
{
|
||||||
|
std::string wirelessAddress;
|
||||||
|
IfAddrsResource ifa;
|
||||||
|
if (ifa.is_valid()) {
|
||||||
|
for (struct ifaddrs * next = ifa; next; next = next->ifa_next) {
|
||||||
|
auto sain = (struct sockaddr_in *)next->ifa_addr;
|
||||||
|
if (!sain || sain->sin_family != AF_INET ||
|
||||||
|
!(next->ifa_flags & IFF_RUNNING) ||
|
||||||
|
(next->ifa_flags & IFF_LOOPBACK)
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::string address = inet_ntoa(sain->sin_addr);
|
||||||
|
// take first wired address right away
|
||||||
|
if (!is_wireless(next->ifa_name)) {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
// save first wireless address to be used if we don't find a wired one
|
||||||
|
if (wirelessAddress.empty()) {
|
||||||
|
wirelessAddress = address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return wirelessAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <ifaddrs.h>
|
||||||
|
|
||||||
|
namespace Debauchee
|
||||||
|
{
|
||||||
|
|
||||||
|
class IfAddrsResource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit IfAddrsResource() :
|
||||||
|
_valid(getifaddrs(&_ifa) == 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~IfAddrsResource()
|
||||||
|
{
|
||||||
|
if (_valid) {
|
||||||
|
freeifaddrs(_ifa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_valid() const { return _valid; }
|
||||||
|
|
||||||
|
operator struct ifaddrs * () const { return _ifa; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _valid;
|
||||||
|
struct ifaddrs * _ifa;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
namespace Debauchee
|
||||||
|
{
|
||||||
|
|
||||||
|
class SocketResource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit SocketResource(int domain, int type, int protocol) :
|
||||||
|
_fd(socket(domain, type, protocol))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~SocketResource()
|
||||||
|
{
|
||||||
|
if (is_valid()) {
|
||||||
|
close(_fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_valid() const { return _fd >= 0; }
|
||||||
|
|
||||||
|
operator int() const { return _fd; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int _fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
// REQUIRES: Ws2_32.lib, Iphlpapi.lib
|
||||||
|
// REQUIRES: WSAStartup(..)
|
||||||
|
|
||||||
|
// see comments regarding WSAAddressToStringA in address_string(..)
|
||||||
|
#define _WINSOCK_DEPRECATED_NO_WARNINGS
|
||||||
|
|
||||||
|
#include <WinSock2.h>
|
||||||
|
#include <iphlpapi.h>
|
||||||
|
#include <string>
|
||||||
|
#include "HeapResource.h"
|
||||||
|
|
||||||
|
namespace Debauchee
|
||||||
|
{
|
||||||
|
|
||||||
|
static ULONG get_addresses(IP_ADAPTER_ADDRESSES * addresses, PULONG sz)
|
||||||
|
{
|
||||||
|
return GetAdaptersAddresses(AF_INET,
|
||||||
|
GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME,
|
||||||
|
NULL, addresses, sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string address_string(const SOCKET_ADDRESS& address)
|
||||||
|
{
|
||||||
|
// planning to use this with Qt but QString does not have a c'tor
|
||||||
|
// for wide strings so we need to force the ANSI API here
|
||||||
|
DWORD szStrAddress = 1023;
|
||||||
|
char strAddress[1024];
|
||||||
|
if (WSAAddressToStringA(address.lpSockaddr, address.iSockaddrLength, NULL, strAddress, &szStrAddress)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return strAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string first_unicast_address(IP_ADAPTER_UNICAST_ADDRESS * unicast)
|
||||||
|
{
|
||||||
|
while (unicast) {
|
||||||
|
auto address = address_string(unicast->Address);
|
||||||
|
if (!address.empty()) {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
unicast = unicast->Next;
|
||||||
|
}
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_useable_interface(const IP_ADAPTER_ADDRESSES * ifa)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
// is an ethernet or wireless interface AND
|
||||||
|
(ifa->IfType == IF_TYPE_ETHERNET_CSMACD || ifa->IfType == IF_TYPE_IEEE80211) &&
|
||||||
|
// is up
|
||||||
|
ifa->OperStatus == IfOperStatusUp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string default_ip_address(const IP_ADAPTER_ADDRESSES * next)
|
||||||
|
{
|
||||||
|
std::string wirelessAddress;
|
||||||
|
for ( ; next; next = next->Next) {
|
||||||
|
if (!is_useable_interface(next)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::string address = first_unicast_address(next->FirstUnicastAddress);
|
||||||
|
if (address.empty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// take first wired address right away
|
||||||
|
if (next->IfType == IF_TYPE_ETHERNET_CSMACD) {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
// save first wireless address to be used if we don't find a wired one
|
||||||
|
if (wirelessAddress.empty()) {
|
||||||
|
wirelessAddress = address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return wirelessAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string default_interface_ip()
|
||||||
|
{
|
||||||
|
const ULONG DefaultSzAddresses = 15 * 1024; // 15k recommended by msdn
|
||||||
|
ULONG szAddresses = DefaultSzAddresses;
|
||||||
|
HeapResource<IP_ADAPTER_ADDRESSES> addresses(GetProcessHeap(), 0, DefaultSzAddresses);
|
||||||
|
if (addresses.is_valid()) {
|
||||||
|
ULONG result;
|
||||||
|
while (ERROR_BUFFER_OVERFLOW == (result = get_addresses(addresses, &szAddresses))) {
|
||||||
|
// add more space in case more adapters have shown up
|
||||||
|
szAddresses += DefaultSzAddresses;
|
||||||
|
swap(addresses, HeapResource<IP_ADAPTER_ADDRESSES>(GetProcessHeap(), 0, szAddresses));
|
||||||
|
if (!addresses.is_valid()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (result == ERROR_SUCCESS) {
|
||||||
|
return default_ip_address(addresses);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Debauchee
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class HeapResource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit HeapResource(HANDLE heap, DWORD flags, SIZE_T sz) :
|
||||||
|
_heap(heap),
|
||||||
|
_flags(flags),
|
||||||
|
_mem((T*)HeapAlloc(heap, flags, sz))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HeapResource(HeapResource<T>&& other)
|
||||||
|
: _mem(NULL)
|
||||||
|
{
|
||||||
|
swap(*this, other);
|
||||||
|
}
|
||||||
|
|
||||||
|
~HeapResource()
|
||||||
|
{
|
||||||
|
if (is_valid()) {
|
||||||
|
HeapFree(_heap, _flags, _mem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
friend void swap(HeapResource<T>& first, HeapResource<T>& second)
|
||||||
|
{
|
||||||
|
using std::swap;
|
||||||
|
swap(first._heap, second._heap);
|
||||||
|
swap(first._flags, second._flags);
|
||||||
|
swap(first._mem, second._mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_valid() const { return _mem != NULL; }
|
||||||
|
|
||||||
|
operator T*() const { return _mem; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
HANDLE _heap;
|
||||||
|
DWORD _flags;
|
||||||
|
T * _mem;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue