85 lines
2.8 KiB
C++
85 lines
2.8 KiB
C++
// Copyright 2020-2023 The Mumble Developers. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license
|
|
// that can be found in the LICENSE file at the root of the
|
|
// Mumble source tree or at <https://www.mumble.info/LICENSE>.
|
|
|
|
#ifndef MUMBLE_MUMBLE_ZEROCONF_H_
|
|
#define MUMBLE_MUMBLE_ZEROCONF_H_
|
|
|
|
#include "BonjourServiceBrowser.h"
|
|
#include "BonjourServiceResolver.h"
|
|
|
|
#include <memory>
|
|
|
|
#ifdef Q_OS_WIN
|
|
# include <windns.h>
|
|
#endif
|
|
|
|
class Zeroconf : public QObject {
|
|
private:
|
|
Q_OBJECT
|
|
Q_DISABLE_COPY(Zeroconf)
|
|
protected:
|
|
#ifdef Q_OS_WIN
|
|
struct Resolver {
|
|
Zeroconf *m_zeroconf;
|
|
BonjourRecord m_record;
|
|
DNS_SERVICE_CANCEL m_cancel;
|
|
|
|
bool operator==(const Resolver &other) const { return m_record == other.m_record; }
|
|
|
|
Resolver(Zeroconf *zeroconf, const BonjourRecord &record) : m_zeroconf(zeroconf), m_record(record){};
|
|
};
|
|
#endif
|
|
bool m_ok;
|
|
QList< BonjourRecord > m_records;
|
|
std::unique_ptr< BonjourServiceBrowser > m_helperBrowser;
|
|
std::unique_ptr< BonjourServiceResolver > m_helperResolver;
|
|
#ifdef Q_OS_WIN
|
|
QList< Resolver > m_resolvers;
|
|
std::unique_ptr< DNS_SERVICE_CANCEL > m_cancelBrowser;
|
|
|
|
bool stopResolver(Resolver &resolver);
|
|
|
|
static void WINAPI callbackBrowseComplete(const DWORD status, void *context, DNS_RECORD *records);
|
|
static void WINAPI callbackResolveComplete(const DWORD status, void *context, DNS_SERVICE_INSTANCE *instance);
|
|
#endif
|
|
void resetHelperBrowser();
|
|
void resetHelperResolver();
|
|
|
|
void helperBrowserRecordsChanged(const QList< BonjourRecord > &records);
|
|
void helperResolverRecordResolved(const BonjourRecord record, const QString hostname, const int port);
|
|
void helperBrowserError(const DNSServiceErrorType error) const;
|
|
void helperResolverError(const BonjourRecord record, const DNSServiceErrorType error);
|
|
#ifdef Q_OS_WIN
|
|
DNS_STATUS(WINAPI *DnsServiceBrowse)(PDNS_SERVICE_BROWSE_REQUEST pRequest, PDNS_SERVICE_CANCEL pCancel);
|
|
DNS_STATUS(WINAPI *DnsServiceBrowseCancel)(PDNS_SERVICE_CANCEL pCancelHandle);
|
|
DNS_STATUS(WINAPI *DnsServiceResolve)(PDNS_SERVICE_RESOLVE_REQUEST pRequest, PDNS_SERVICE_CANCEL pCancel);
|
|
DNS_STATUS(WINAPI *DnsServiceResolveCancel)(PDNS_SERVICE_CANCEL pCancelHandle);
|
|
VOID(WINAPI *DnsServiceFreeInstance)(PDNS_SERVICE_INSTANCE pInstance);
|
|
#endif
|
|
public:
|
|
inline bool isOk() const { return m_ok; }
|
|
inline QList< BonjourRecord > currentRecords() const {
|
|
return m_helperBrowser ? m_helperBrowser->currentRecords() : m_records;
|
|
}
|
|
|
|
bool startBrowser(const QString &serviceType);
|
|
bool stopBrowser();
|
|
|
|
bool startResolver(const BonjourRecord &record);
|
|
#ifdef Q_OS_WIN
|
|
bool stopResolver(const BonjourRecord &record);
|
|
#endif
|
|
bool cleanupResolvers();
|
|
|
|
Zeroconf();
|
|
~Zeroconf();
|
|
signals:
|
|
void recordsChanged(const QList< BonjourRecord > &records);
|
|
void recordResolved(const BonjourRecord record, const QString hostname, const uint16_t port);
|
|
void resolveError(const BonjourRecord record);
|
|
};
|
|
|
|
#endif
|