mumble-voip_mumble/src/mumble/Zeroconf.h

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