mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-19 12:21:52 +02:00
Integrate qjdns/jdnsshared, make a shared library, and do some implementation
This commit is contained in:
@@ -258,6 +258,7 @@ set( libHeaders
|
||||
playlist/dynamic/widgets/MiscControlWidgets.h
|
||||
playlist/dynamic/widgets/CollapsibleControls.h
|
||||
|
||||
utils/tomahawkutils.h
|
||||
utils/querylabel.h
|
||||
utils/elidedlabel.h
|
||||
utils/animatedcounterlabel.h
|
||||
@@ -296,6 +297,9 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ..
|
||||
../../qxt/qxtweb-standalone/qxtweb
|
||||
../../rtaudio
|
||||
../../alsa-playback
|
||||
../../thirdparty/jdns
|
||||
../../thirdparty/jdns/jdns
|
||||
../../thirdparty/jdns/jdnsshared
|
||||
playlist
|
||||
)
|
||||
|
||||
@@ -359,7 +363,7 @@ target_link_libraries( tomahawklib
|
||||
vorbisfile
|
||||
ogg
|
||||
FLAC++
|
||||
jdns
|
||||
tomahawk_jdns
|
||||
clucene
|
||||
)
|
||||
|
||||
|
@@ -16,8 +16,11 @@
|
||||
#ifdef Q_WS_MAC
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <thirdparty/jdns/qjdns.h>
|
||||
#endif
|
||||
|
||||
#include <qjdns.h>
|
||||
#include <jdnsshared.h>
|
||||
|
||||
namespace TomahawkUtils
|
||||
{
|
||||
@@ -305,4 +308,62 @@ setProxy( QNetworkProxy* proxy )
|
||||
s_proxy = proxy;
|
||||
}
|
||||
|
||||
|
||||
///////////////// DNSResolver /////////////////
|
||||
|
||||
static DNSResolver* s_dnsResolver = 0;
|
||||
|
||||
DNSResolver*
|
||||
dnsResolver()
|
||||
{
|
||||
if( !s_dnsResolver )
|
||||
s_dnsResolver = new DNSResolver();
|
||||
|
||||
return s_dnsResolver;
|
||||
}
|
||||
|
||||
DNSResolver::DNSResolver()
|
||||
{
|
||||
m_dnsShared = new JDnsShared(JDnsShared::UnicastInternet);
|
||||
m_dnsShared->addInterface(QHostAddress::Any);
|
||||
m_dnsShared->addInterface(QHostAddress::AnyIPv6);
|
||||
m_dnsSharedRequest = new JDnsSharedRequest(m_dnsShared);
|
||||
}
|
||||
|
||||
void
|
||||
DNSResolver::resolve( QString &host, QString &type )
|
||||
{
|
||||
connect(m_dnsSharedRequest, SIGNAL(resultsReady()), SLOT(resultsReady()));
|
||||
if( type == "SRV" )
|
||||
{
|
||||
// For the moment, assume we are looking for XMPP...
|
||||
m_dnsSharedRequest->query( "_xmpp-client._tcp." + host.toUtf8(), QJDns::Srv );
|
||||
}
|
||||
else
|
||||
{
|
||||
QString badResult( "NONE" );
|
||||
emit result( badResult );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DNSResolver::resultsReady()
|
||||
{
|
||||
if( m_dnsSharedRequest->success() )
|
||||
{
|
||||
QList<QJDns::Record> results = m_dnsSharedRequest->results();
|
||||
foreach( QJDns::Record r, results )
|
||||
{
|
||||
if( r.type == QJDns::Srv )
|
||||
{
|
||||
QString foundResult( r.name );
|
||||
emit result( foundResult );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
QString badResult( "NONE" );
|
||||
emit result( badResult );
|
||||
}
|
||||
|
||||
} // ns
|
||||
|
@@ -2,6 +2,7 @@
|
||||
#define TOMAHAWKUTILS_H
|
||||
|
||||
#include "dllmacro.h"
|
||||
#include <QObject>
|
||||
|
||||
#define RESPATH ":/data/"
|
||||
|
||||
@@ -12,8 +13,31 @@ class QPixmap;
|
||||
class QNetworkAccessManager;
|
||||
class QNetworkProxy;
|
||||
|
||||
class JDnsShared;
|
||||
class JDnsSharedRequest;
|
||||
|
||||
namespace TomahawkUtils
|
||||
{
|
||||
class DLLEXPORT DNSResolver : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DNSResolver();
|
||||
~DNSResolver() {}
|
||||
|
||||
void resolve( QString &host, QString &type );
|
||||
|
||||
signals:
|
||||
void result( QString &result );
|
||||
|
||||
public slots:
|
||||
void resultsReady();
|
||||
|
||||
private:
|
||||
JDnsShared* m_dnsShared;
|
||||
JDnsSharedRequest* m_dnsSharedRequest;
|
||||
};
|
||||
|
||||
DLLEXPORT QDir appConfigDir();
|
||||
DLLEXPORT QDir appDataDir();
|
||||
|
||||
@@ -28,6 +52,8 @@ namespace TomahawkUtils
|
||||
|
||||
DLLEXPORT void setNam( QNetworkAccessManager* nam );
|
||||
DLLEXPORT void setProxy( QNetworkProxy* proxy );
|
||||
|
||||
DLLEXPORT DNSResolver* dnsResolver();
|
||||
}
|
||||
|
||||
#endif // TOMAHAWKUTILS_H
|
||||
|
45
thirdparty/jdns/CMakeLists.txt
vendored
45
thirdparty/jdns/CMakeLists.txt
vendored
@@ -6,39 +6,46 @@ SET(CMAKE_VERBOSE_MAKEFILE ON)
|
||||
SET( QT_USE_QTNETWORK TRUE )
|
||||
INCLUDE( ${QT_USE_FILE} )
|
||||
|
||||
add_definitions( ${QT_DEFINITIONS} )
|
||||
add_definitions( -DQT_SHARED )
|
||||
|
||||
if(WIN32)
|
||||
SET(PLATFORM_SPECIFIC_LIBS "ws2_32.dll" "advapi32.dll" )
|
||||
set(PLATFORM_SPECIFIC_LIBS "ws2_32.dll" "advapi32.dll" )
|
||||
endif(WIN32)
|
||||
|
||||
set(JDNS_SOURCES
|
||||
jdns_util.c
|
||||
jdns_packet.c
|
||||
jdns_mdnsd.c
|
||||
jdns_sys.c
|
||||
jdns.c
|
||||
qjdns_sock.cpp
|
||||
qjdns.cpp
|
||||
set(TOMAHAWK_JDNS_SOURCES
|
||||
jdns/jdns_util.c
|
||||
jdns/jdns_packet.c
|
||||
jdns/jdns_mdnsd.c
|
||||
jdns/jdns_sys.c
|
||||
jdns/jdns.c
|
||||
jdns/qjdns_sock.cpp
|
||||
jdns/qjdns.cpp
|
||||
jdnsshared/jdnsshared.cpp
|
||||
)
|
||||
|
||||
set(JDNS_HEADERS
|
||||
qjdns.h
|
||||
set(TOMAHAWK_JDNS_HEADERS
|
||||
jdns/qjdns.h
|
||||
jdns/qjdns_helpers.h
|
||||
jdnsshared/jdnsshared.h
|
||||
jdnsshared/jdnsshared_helpers.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
.
|
||||
${QT_INCLUDE_DIR}
|
||||
${QT_INCLUDES}
|
||||
jdns
|
||||
)
|
||||
|
||||
qt4_wrap_cpp( JDNS_MOC ${JDNS_HEADERS} )
|
||||
qt4_wrap_cpp( TOMAHAWK_JDNS_MOC ${TOMAHAWK_JDNS_HEADERS} )
|
||||
|
||||
if(WIN32)
|
||||
ADD_LIBRARY(jdns SHARED ${JDNS_SOURCES} ${JDNS_MOC})
|
||||
else()
|
||||
ADD_LIBRARY(jdns STATIC ${JDNS_SOURCES} ${JDNS_MOC})
|
||||
endif()
|
||||
ADD_LIBRARY(tomahawk_jdns SHARED ${TOMAHAWK_JDNS_SOURCES} ${TOMAHAWK_JDNS_MOC})
|
||||
|
||||
target_link_libraries(jdns
|
||||
target_link_libraries(tomahawk_jdns
|
||||
${QT_LIBRARIES}
|
||||
)
|
||||
|
||||
INSTALL(TARGETS jdns ARCHIVE DESTINATION lib)
|
||||
SET_TARGET_PROPERTIES( tomahawk_jdns PROPERTIES DEFINE_SYMBOL MAKE_JDNS_LIB )
|
||||
|
||||
INSTALL(TARGETS tomahawk_jdns DESTINATION lib)
|
||||
|
638
thirdparty/jdns/jdns/qjdns.cpp
vendored
Normal file
638
thirdparty/jdns/jdns/qjdns.cpp
vendored
Normal file
@@ -0,0 +1,638 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Justin Karneges
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "qjdns.h"
|
||||
|
||||
#include <time.h>
|
||||
#include "qjdns_sock.h"
|
||||
#include "qjdns_helpers.h"
|
||||
#include "jdns.h"
|
||||
|
||||
// for fprintf
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// QJDns::NameServer
|
||||
//----------------------------------------------------------------------------
|
||||
QJDns::NameServer::NameServer()
|
||||
{
|
||||
port = JDNS_UNICAST_PORT;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// QJDns::Record
|
||||
//----------------------------------------------------------------------------
|
||||
QJDns::Record::Record()
|
||||
{
|
||||
ttl = 0;
|
||||
type = -1;
|
||||
haveKnown = false;
|
||||
}
|
||||
|
||||
bool QJDns::Record::verify() const
|
||||
{
|
||||
jdns_rr_t *rr = export_record(*this);
|
||||
int ok = jdns_rr_verify(rr);
|
||||
jdns_rr_delete(rr);
|
||||
return (ok ? true : false);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// QJDns
|
||||
//----------------------------------------------------------------------------
|
||||
QJDns::Private::Private(QJDns *_q) :
|
||||
QObject(_q),
|
||||
q(_q),
|
||||
stepTrigger(this),
|
||||
debugTrigger(this),
|
||||
stepTimeout(this),
|
||||
pErrors(0),
|
||||
pPublished(0),
|
||||
pResponses(0)
|
||||
{
|
||||
sess = 0;
|
||||
shutting_down = false;
|
||||
new_debug_strings = false;
|
||||
pending = 0;
|
||||
|
||||
connect(&stepTrigger, SIGNAL(timeout()), SLOT(doNextStepSlot()));
|
||||
stepTrigger.setSingleShot(true);
|
||||
|
||||
connect(&debugTrigger, SIGNAL(timeout()), SLOT(doDebug()));
|
||||
debugTrigger.setSingleShot(true);
|
||||
|
||||
connect(&stepTimeout, SIGNAL(timeout()), SLOT(st_timeout()));
|
||||
stepTimeout.setSingleShot(true);
|
||||
|
||||
my_srand();
|
||||
|
||||
clock.start();
|
||||
}
|
||||
|
||||
QJDns::Private::~Private()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void QJDns::Private::cleanup()
|
||||
{
|
||||
if(sess)
|
||||
{
|
||||
jdns_session_delete(sess);
|
||||
sess = 0;
|
||||
}
|
||||
|
||||
shutting_down = false;
|
||||
pending = 0;
|
||||
|
||||
// it is safe to delete the QUdpSocket objects here without
|
||||
// deleteLater, since this code path never occurs when
|
||||
// a signal from those objects is on the stack
|
||||
qDeleteAll(socketForHandle);
|
||||
socketForHandle.clear();
|
||||
handleForSocket.clear();
|
||||
|
||||
stepTrigger.stop();
|
||||
stepTimeout.stop();
|
||||
need_handle = 0;
|
||||
}
|
||||
|
||||
bool QJDns::Private::init(QJDns::Mode _mode, const QHostAddress &address)
|
||||
{
|
||||
mode = _mode;
|
||||
|
||||
jdns_callbacks_t callbacks;
|
||||
callbacks.app = this;
|
||||
callbacks.time_now = cb_time_now;
|
||||
callbacks.rand_int = cb_rand_int;
|
||||
callbacks.debug_line = cb_debug_line;
|
||||
callbacks.udp_bind = cb_udp_bind;
|
||||
callbacks.udp_unbind = cb_udp_unbind;
|
||||
callbacks.udp_read = cb_udp_read;
|
||||
callbacks.udp_write = cb_udp_write;
|
||||
sess = jdns_session_new(&callbacks);
|
||||
jdns_set_hold_ids_enabled(sess, 1);
|
||||
next_handle = 1;
|
||||
need_handle = false;
|
||||
|
||||
int ret;
|
||||
|
||||
jdns_address_t *baddr = qt2addr(address);
|
||||
if(mode == Unicast)
|
||||
{
|
||||
ret = jdns_init_unicast(sess, baddr, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
jdns_address_t *maddr;
|
||||
if(address.protocol() == QAbstractSocket::IPv6Protocol)
|
||||
maddr = jdns_address_multicast6_new();
|
||||
else
|
||||
maddr = jdns_address_multicast4_new();
|
||||
ret = jdns_init_multicast(sess, baddr, JDNS_MULTICAST_PORT, maddr);
|
||||
jdns_address_delete(maddr);
|
||||
}
|
||||
jdns_address_delete(baddr);
|
||||
|
||||
if(!ret)
|
||||
{
|
||||
jdns_session_delete(sess);
|
||||
sess = 0;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void QJDns::Private::setNameServers(const QList<NameServer> &nslist)
|
||||
{
|
||||
jdns_nameserverlist_t *addrs = jdns_nameserverlist_new();
|
||||
for(int n = 0; n < nslist.count(); ++n)
|
||||
{
|
||||
jdns_address_t *addr = qt2addr(nslist[n].address);
|
||||
jdns_nameserverlist_append(addrs, addr, nslist[n].port);
|
||||
jdns_address_delete(addr);
|
||||
}
|
||||
jdns_set_nameservers(sess, addrs);
|
||||
jdns_nameserverlist_delete(addrs);
|
||||
}
|
||||
|
||||
void QJDns::Private::process()
|
||||
{
|
||||
if(!stepTrigger.isActive())
|
||||
{
|
||||
stepTimeout.stop();
|
||||
stepTrigger.start();
|
||||
}
|
||||
}
|
||||
|
||||
void QJDns::Private::processDebug()
|
||||
{
|
||||
new_debug_strings = true;
|
||||
if(!debugTrigger.isActive())
|
||||
debugTrigger.start();
|
||||
}
|
||||
|
||||
void QJDns::Private::doNextStep()
|
||||
{
|
||||
if(shutting_down && complete_shutdown)
|
||||
{
|
||||
cleanup();
|
||||
emit q->shutdownFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
QPointer<QObject> self = this;
|
||||
|
||||
int ret = jdns_step(sess);
|
||||
|
||||
QList<LateError> errors;
|
||||
QList<int> published;
|
||||
QList<LateResponse> responses;
|
||||
bool finish_shutdown = false;
|
||||
|
||||
pErrors = &errors;
|
||||
pPublished = &published;
|
||||
pResponses = &responses;
|
||||
|
||||
while(1)
|
||||
{
|
||||
jdns_event_t *e = jdns_next_event(sess);
|
||||
if(!e)
|
||||
break;
|
||||
|
||||
if(e->type == JDNS_EVENT_SHUTDOWN)
|
||||
{
|
||||
finish_shutdown = true;
|
||||
}
|
||||
else if(e->type == JDNS_EVENT_PUBLISH)
|
||||
{
|
||||
if(e->status != JDNS_STATUS_SUCCESS)
|
||||
{
|
||||
QJDns::Error error;
|
||||
if(e->status == JDNS_STATUS_CONFLICT)
|
||||
error = QJDns::ErrorConflict;
|
||||
else
|
||||
error = QJDns::ErrorGeneric;
|
||||
LateError le;
|
||||
le.source_type = 1;
|
||||
le.id = e->id;
|
||||
le.error = error;
|
||||
errors += le;
|
||||
}
|
||||
else
|
||||
{
|
||||
published += e->id;
|
||||
}
|
||||
}
|
||||
else if(e->type == JDNS_EVENT_RESPONSE)
|
||||
{
|
||||
if(e->status != JDNS_STATUS_SUCCESS)
|
||||
{
|
||||
QJDns::Error error;
|
||||
if(e->status == JDNS_STATUS_NXDOMAIN)
|
||||
error = QJDns::ErrorNXDomain;
|
||||
else if(e->status == JDNS_STATUS_TIMEOUT)
|
||||
error = QJDns::ErrorTimeout;
|
||||
else
|
||||
error = QJDns::ErrorGeneric;
|
||||
LateError le;
|
||||
le.source_type = 0;
|
||||
le.id = e->id;
|
||||
le.error = error;
|
||||
errors += le;
|
||||
}
|
||||
else
|
||||
{
|
||||
QJDns::Response out_response;
|
||||
for(int n = 0; n < e->response->answerCount; ++n)
|
||||
out_response.answerRecords += import_record(e->response->answerRecords[n]);
|
||||
LateResponse lr;
|
||||
lr.id = e->id;
|
||||
lr.response = out_response;
|
||||
if(mode == Unicast)
|
||||
lr.do_cancel = true;
|
||||
else
|
||||
lr.do_cancel = false;
|
||||
responses += lr;
|
||||
}
|
||||
}
|
||||
|
||||
jdns_event_delete(e);
|
||||
}
|
||||
|
||||
if(ret & JDNS_STEP_TIMER)
|
||||
stepTimeout.start(jdns_next_timer(sess));
|
||||
else
|
||||
stepTimeout.stop();
|
||||
|
||||
need_handle = (ret & JDNS_STEP_HANDLE);
|
||||
|
||||
// read the lists safely enough so that items can be deleted
|
||||
// behind our back
|
||||
|
||||
while(!errors.isEmpty())
|
||||
{
|
||||
LateError i = errors.takeFirst();
|
||||
if(i.source_type == 0)
|
||||
jdns_cancel_query(sess, i.id);
|
||||
else
|
||||
jdns_cancel_publish(sess, i.id);
|
||||
emit q->error(i.id, i.error);
|
||||
if(!self)
|
||||
return;
|
||||
}
|
||||
|
||||
while(!published.isEmpty())
|
||||
{
|
||||
int i = published.takeFirst();
|
||||
emit q->published(i);
|
||||
if(!self)
|
||||
return;
|
||||
}
|
||||
|
||||
while(!responses.isEmpty())
|
||||
{
|
||||
LateResponse i = responses.takeFirst();
|
||||
if(i.do_cancel)
|
||||
jdns_cancel_query(sess, i.id);
|
||||
emit q->resultsReady(i.id, i.response);
|
||||
if(!self)
|
||||
return;
|
||||
}
|
||||
|
||||
if(finish_shutdown)
|
||||
{
|
||||
// if we have pending udp packets to write, stick around
|
||||
if(pending > 0)
|
||||
{
|
||||
pending_wait = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
complete_shutdown = true;
|
||||
process();
|
||||
}
|
||||
}
|
||||
|
||||
pErrors = 0;
|
||||
pPublished = 0;
|
||||
pResponses = 0;
|
||||
}
|
||||
|
||||
void QJDns::Private::removeCancelled(int id)
|
||||
{
|
||||
if(pErrors)
|
||||
{
|
||||
for(int n = 0; n < pErrors->count(); ++n)
|
||||
{
|
||||
if(pErrors->at(n).id == id)
|
||||
{
|
||||
pErrors->removeAt(n);
|
||||
--n; // adjust position
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(pPublished)
|
||||
{
|
||||
for(int n = 0; n < pPublished->count(); ++n)
|
||||
{
|
||||
if(pPublished->at(n) == id)
|
||||
{
|
||||
pPublished->removeAt(n);
|
||||
--n; // adjust position
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(pResponses)
|
||||
{
|
||||
for(int n = 0; n < pResponses->count(); ++n)
|
||||
{
|
||||
if(pResponses->at(n).id == id)
|
||||
{
|
||||
pResponses->removeAt(n);
|
||||
--n; // adjust position
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QJDns::Private::udp_readyRead()
|
||||
{
|
||||
QUdpSocket *sock = (QUdpSocket *)sender();
|
||||
int handle = handleForSocket.value(sock);
|
||||
|
||||
if(need_handle)
|
||||
{
|
||||
jdns_set_handle_readable(sess, handle);
|
||||
process();
|
||||
}
|
||||
else
|
||||
{
|
||||
// eat packet
|
||||
QByteArray buf(4096, 0);
|
||||
QHostAddress from_addr;
|
||||
quint16 from_port;
|
||||
sock->readDatagram(buf.data(), buf.size(), &from_addr, &from_port);
|
||||
}
|
||||
}
|
||||
|
||||
void QJDns::Private::udp_bytesWritten(qint64)
|
||||
{
|
||||
if(pending > 0)
|
||||
{
|
||||
--pending;
|
||||
if(shutting_down && pending_wait && pending == 0)
|
||||
{
|
||||
pending_wait = false;
|
||||
complete_shutdown = true;
|
||||
process();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QJDns::Private::st_timeout()
|
||||
{
|
||||
doNextStep();
|
||||
}
|
||||
|
||||
void QJDns::Private::doNextStepSlot()
|
||||
{
|
||||
doNextStep();
|
||||
}
|
||||
|
||||
void QJDns::Private::doDebug()
|
||||
{
|
||||
if(new_debug_strings)
|
||||
{
|
||||
new_debug_strings = false;
|
||||
if(!debug_strings.isEmpty())
|
||||
emit q->debugLinesReady();
|
||||
}
|
||||
}
|
||||
|
||||
QJDns::QJDns(QObject *parent)
|
||||
:QObject(parent)
|
||||
{
|
||||
d = new Private(this);
|
||||
}
|
||||
|
||||
QJDns::~QJDns()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool QJDns::init(Mode mode, const QHostAddress &address)
|
||||
{
|
||||
return d->init(mode, address);
|
||||
}
|
||||
|
||||
void QJDns::shutdown()
|
||||
{
|
||||
d->shutting_down = true;
|
||||
d->pending_wait = false;
|
||||
d->complete_shutdown = false;
|
||||
jdns_shutdown(d->sess);
|
||||
d->process();
|
||||
}
|
||||
|
||||
QStringList QJDns::debugLines()
|
||||
{
|
||||
QStringList tmp = d->debug_strings;
|
||||
d->debug_strings.clear();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
QJDns::SystemInfo QJDns::systemInfo()
|
||||
{
|
||||
SystemInfo out;
|
||||
jdns_dnsparams_t *params = jdns_system_dnsparams();
|
||||
for(int n = 0; n < params->nameservers->count; ++n)
|
||||
{
|
||||
NameServer ns;
|
||||
ns.address = addr2qt(params->nameservers->item[n]->address);
|
||||
out.nameServers += ns;
|
||||
}
|
||||
for(int n = 0; n < params->domains->count; ++n)
|
||||
out.domains += str2qt(params->domains->item[n]);
|
||||
for(int n = 0; n < params->hosts->count; ++n)
|
||||
{
|
||||
DnsHost h;
|
||||
h.name = str2qt(params->hosts->item[n]->name);
|
||||
h.address = addr2qt(params->hosts->item[n]->address);
|
||||
out.hosts += h;
|
||||
}
|
||||
jdns_dnsparams_delete(params);
|
||||
return out;
|
||||
}
|
||||
|
||||
#define PROBE_BASE 20000
|
||||
#define PROBE_RANGE 100
|
||||
|
||||
QHostAddress QJDns::detectPrimaryMulticast(const QHostAddress &address)
|
||||
{
|
||||
my_srand();
|
||||
|
||||
QUdpSocket *sock = new QUdpSocket;
|
||||
QUdpSocket::BindMode mode;
|
||||
mode |= QUdpSocket::ShareAddress;
|
||||
mode |= QUdpSocket::ReuseAddressHint;
|
||||
int port = -1;
|
||||
for(int n = 0; n < PROBE_RANGE; ++n)
|
||||
{
|
||||
if(sock->bind(address, PROBE_BASE + n, mode))
|
||||
{
|
||||
port = PROBE_BASE + n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(port == -1)
|
||||
{
|
||||
delete sock;
|
||||
return QHostAddress();
|
||||
}
|
||||
|
||||
jdns_address_t *a;
|
||||
if(address.protocol() == QAbstractSocket::IPv6Protocol)
|
||||
a = jdns_address_multicast6_new();
|
||||
else
|
||||
a = jdns_address_multicast4_new();
|
||||
QHostAddress maddr = addr2qt(a);
|
||||
jdns_address_delete(a);
|
||||
|
||||
if(address.protocol() == QAbstractSocket::IPv6Protocol)
|
||||
{
|
||||
int x;
|
||||
if(!qjdns_sock_setMulticast6(sock->socketDescriptor(), maddr.toIPv6Address().c, &x))
|
||||
{
|
||||
delete sock;
|
||||
return QHostAddress();
|
||||
}
|
||||
qjdns_sock_setTTL6(sock->socketDescriptor(), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int x;
|
||||
if(!qjdns_sock_setMulticast4(sock->socketDescriptor(), maddr.toIPv4Address(), &x))
|
||||
{
|
||||
delete sock;
|
||||
return QHostAddress();
|
||||
}
|
||||
qjdns_sock_setTTL4(sock->socketDescriptor(), 0);
|
||||
}
|
||||
|
||||
QHostAddress result;
|
||||
QByteArray out(128, 0);
|
||||
for(int n = 0; n < out.size(); ++n)
|
||||
out[n] = rand();
|
||||
if(sock->writeDatagram(out.data(), out.size(), maddr, port) == -1)
|
||||
{
|
||||
delete sock;
|
||||
return QHostAddress();
|
||||
}
|
||||
while(1)
|
||||
{
|
||||
if(!sock->waitForReadyRead(1000))
|
||||
{
|
||||
fprintf(stderr, "QJDns::detectPrimaryMulticast: timeout while checking %s\n", qPrintable(address.toString()));
|
||||
delete sock;
|
||||
return QHostAddress();
|
||||
}
|
||||
QByteArray in(128, 0);
|
||||
QHostAddress from_addr;
|
||||
quint16 from_port;
|
||||
int ret = sock->readDatagram(in.data(), in.size(), &from_addr, &from_port);
|
||||
if(ret == -1)
|
||||
{
|
||||
delete sock;
|
||||
return QHostAddress();
|
||||
}
|
||||
|
||||
if(from_port != port)
|
||||
continue;
|
||||
in.resize(ret);
|
||||
if(in != out)
|
||||
continue;
|
||||
|
||||
result = from_addr;
|
||||
break;
|
||||
}
|
||||
delete sock;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void QJDns::setNameServers(const QList<NameServer> &list)
|
||||
{
|
||||
d->setNameServers(list);
|
||||
}
|
||||
|
||||
int QJDns::queryStart(const QByteArray &name, int type)
|
||||
{
|
||||
int id = jdns_query(d->sess, (const unsigned char *)name.data(), type);
|
||||
d->process();
|
||||
return id;
|
||||
}
|
||||
|
||||
void QJDns::queryCancel(int id)
|
||||
{
|
||||
jdns_cancel_query(d->sess, id);
|
||||
d->removeCancelled(id);
|
||||
d->process();
|
||||
}
|
||||
|
||||
int QJDns::publishStart(PublishMode m, const Record &record)
|
||||
{
|
||||
jdns_rr_t *rr = export_record(record);
|
||||
|
||||
int pubmode;
|
||||
if(m == QJDns::Unique)
|
||||
pubmode = JDNS_PUBLISH_UNIQUE;
|
||||
else
|
||||
pubmode = JDNS_PUBLISH_SHARED;
|
||||
|
||||
int id = jdns_publish(d->sess, pubmode, rr);
|
||||
jdns_rr_delete(rr);
|
||||
d->process();
|
||||
return id;
|
||||
}
|
||||
|
||||
void QJDns::publishUpdate(int id, const Record &record)
|
||||
{
|
||||
jdns_rr_t *rr = export_record(record);
|
||||
|
||||
jdns_update_publish(d->sess, id, rr);
|
||||
jdns_rr_delete(rr);
|
||||
d->process();
|
||||
}
|
||||
|
||||
void QJDns::publishCancel(int id)
|
||||
{
|
||||
jdns_cancel_publish(d->sess, id);
|
||||
d->removeCancelled(id);
|
||||
d->process();
|
||||
}
|
||||
|
||||
//#include "qjdns.moc"
|
17
thirdparty/jdns/jdns_export.h
vendored
Normal file
17
thirdparty/jdns/jdns_export.h
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef JDNS_EXPORT_H
|
||||
#define JDNS_EXPORT_H
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
#ifdef Q_WS_WIN
|
||||
# if defined(MAKE_JDNS_LIB)
|
||||
# define JDNS_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define JDNS_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
#else
|
||||
# define JDNS_EXPORT Q_DECL_EXPORT
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@@ -34,71 +34,18 @@
|
||||
// on each interface. We don't do anything about this.
|
||||
|
||||
#include "jdnsshared.h"
|
||||
|
||||
namespace {
|
||||
#include "jdns_export.h"
|
||||
#include "jdnsshared_helpers.h"
|
||||
|
||||
// safeobj stuff, from qca
|
||||
|
||||
void releaseAndDeleteLater(QObject *owner, QObject *obj)
|
||||
{
|
||||
obj->disconnect(owner);
|
||||
obj->setParent(0);
|
||||
obj->deleteLater();
|
||||
}
|
||||
|
||||
class SafeTimer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SafeTimer(QObject *parent = 0) :
|
||||
QObject(parent)
|
||||
{
|
||||
t = new QTimer(this);
|
||||
connect(t, SIGNAL(timeout()), SIGNAL(timeout()));
|
||||
}
|
||||
|
||||
~SafeTimer()
|
||||
{
|
||||
releaseAndDeleteLater(this, t);
|
||||
}
|
||||
|
||||
int interval() const { return t->interval(); }
|
||||
bool isActive() const { return t->isActive(); }
|
||||
bool isSingleShot() const { return t->isSingleShot(); }
|
||||
void setInterval(int msec) { t->setInterval(msec); }
|
||||
void setSingleShot(bool singleShot) { t->setSingleShot(singleShot); }
|
||||
int timerId() const { return t->timerId(); }
|
||||
|
||||
public slots:
|
||||
void start(int msec) { t->start(msec); }
|
||||
void start() { t->start(); }
|
||||
void stop() { t->stop(); }
|
||||
|
||||
signals:
|
||||
void timeout();
|
||||
|
||||
private:
|
||||
QTimer *t;
|
||||
};
|
||||
|
||||
// for caching system info
|
||||
|
||||
class SystemInfoCache
|
||||
{
|
||||
public:
|
||||
QJDns::SystemInfo info;
|
||||
QTime time;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Q_GLOBAL_STATIC(QMutex, jdnsshared_mutex)
|
||||
Q_GLOBAL_STATIC(SystemInfoCache, jdnsshared_infocache)
|
||||
|
||||
static QJDns::SystemInfo get_sys_info()
|
||||
{
|
||||
QMutexLocker locker(jdnsshared_mutex());
|
||||
SystemInfoCache *c = jdnsshared_infocache();
|
||||
SystemInfoCache *c = jdnsshared_infocache();
|
||||
|
||||
// cache info for 1/2 second, enough to prevent re-reading of sys
|
||||
// info 20 times because of all the different resolves
|
||||
@@ -193,42 +140,6 @@ static QByteArray makeReverseName(const QHostAddress &addr)
|
||||
return out;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Handle
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
namespace {
|
||||
|
||||
// QJDns uses integer handle ids, but they are only unique within
|
||||
// the relevant QJDns instance. Since we want our handles to be
|
||||
// unique across all instances, we'll make an instance/id pair.
|
||||
class Handle
|
||||
{
|
||||
public:
|
||||
QJDns *jdns;
|
||||
int id;
|
||||
|
||||
Handle() : jdns(0), id(-1)
|
||||
{
|
||||
}
|
||||
|
||||
Handle(QJDns *_jdns, int _id) : jdns(_jdns), id(_id)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==(const Handle &a) const
|
||||
{
|
||||
if(a.jdns == jdns && a.id == id)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator!=(const Handle &a) const
|
||||
{
|
||||
return !(operator==(a));
|
||||
}
|
||||
};
|
||||
|
||||
// adapted from qHash<QPair>
|
||||
static inline uint qHash(const Handle &key)
|
||||
{
|
||||
@@ -237,166 +148,122 @@ static inline uint qHash(const Handle &key)
|
||||
return ((h1 << 16) | (h1 >> 16)) ^ h2;
|
||||
}
|
||||
|
||||
JDnsShutdownAgent::JDnsShutdownAgent()
|
||||
: QObject()
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// JDnsShutdown
|
||||
//----------------------------------------------------------------------------
|
||||
namespace {
|
||||
|
||||
class JDnsShutdownAgent : public QObject
|
||||
void JDnsShutdownAgent::start()
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
void start()
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "started", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
signals:
|
||||
void started();
|
||||
};
|
||||
|
||||
class JDnsShutdownWorker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QList<JDnsShared*> list;
|
||||
|
||||
JDnsShutdownWorker(const QList<JDnsShared*> &_list) : QObject(0), list(_list)
|
||||
{
|
||||
foreach(JDnsShared *i, list)
|
||||
{
|
||||
connect(i, SIGNAL(shutdownFinished()), SLOT(jdns_shutdownFinished()));
|
||||
i->shutdown(); // MUST support DOR-DS, and it does
|
||||
}
|
||||
}
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
|
||||
private slots:
|
||||
void jdns_shutdownFinished()
|
||||
{
|
||||
JDnsShared *i = (JDnsShared *)sender();
|
||||
list.removeAll(i);
|
||||
delete i;
|
||||
if(list.isEmpty())
|
||||
emit finished();
|
||||
}
|
||||
};
|
||||
|
||||
class JDnsShutdown : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QMutex m;
|
||||
QWaitCondition w;
|
||||
QList<JDnsShared*> list;
|
||||
JDnsShutdownAgent *agent;
|
||||
JDnsShutdownWorker *worker;
|
||||
int phase;
|
||||
|
||||
void waitForShutdown(const QList<JDnsShared*> &_list)
|
||||
{
|
||||
list = _list;
|
||||
phase = 0;
|
||||
|
||||
m.lock();
|
||||
start();
|
||||
w.wait(&m);
|
||||
|
||||
foreach(JDnsShared *i, list)
|
||||
{
|
||||
i->setParent(0);
|
||||
i->moveToThread(this);
|
||||
}
|
||||
|
||||
phase = 1;
|
||||
agent->start();
|
||||
wait();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void run()
|
||||
{
|
||||
m.lock();
|
||||
agent = new JDnsShutdownAgent;
|
||||
connect(agent, SIGNAL(started()), SLOT(agent_started()), Qt::DirectConnection);
|
||||
agent->start();
|
||||
exec();
|
||||
delete agent;
|
||||
}
|
||||
|
||||
private slots:
|
||||
void agent_started()
|
||||
{
|
||||
if(phase == 0)
|
||||
{
|
||||
w.wakeOne();
|
||||
m.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
worker = new JDnsShutdownWorker(list);
|
||||
connect(worker, SIGNAL(finished()), SLOT(worker_finished()), Qt::DirectConnection);
|
||||
}
|
||||
}
|
||||
|
||||
void worker_finished()
|
||||
{
|
||||
delete worker;
|
||||
worker = 0;
|
||||
|
||||
quit();
|
||||
}
|
||||
};
|
||||
|
||||
QMetaObject::invokeMethod(this, "started", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// JDnsSharedDebug
|
||||
//----------------------------------------------------------------------------
|
||||
class JDnsSharedDebugPrivate : public QObject
|
||||
|
||||
JDnsShutdownWorker::JDnsShutdownWorker(const QList<JDnsShared*> &_list) : QObject(0), list(_list)
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
JDnsSharedDebug *q;
|
||||
QMutex m;
|
||||
QStringList lines;
|
||||
bool dirty;
|
||||
|
||||
JDnsSharedDebugPrivate(JDnsSharedDebug *_q) : QObject(_q), q(_q)
|
||||
foreach(JDnsShared *i, list)
|
||||
{
|
||||
dirty = false;
|
||||
connect(i, SIGNAL(shutdownFinished()), SLOT(jdns_shutdownFinished()));
|
||||
i->shutdown(); // MUST support DOR-DS, and it does
|
||||
}
|
||||
}
|
||||
|
||||
void JDnsShutdownWorker::jdns_shutdownFinished()
|
||||
{
|
||||
JDnsShared *i = (JDnsShared *)sender();
|
||||
list.removeAll(i);
|
||||
delete i;
|
||||
if(list.isEmpty())
|
||||
emit finished();
|
||||
}
|
||||
|
||||
JDnsShutdown::JDnsShutdown()
|
||||
: QThread()
|
||||
{
|
||||
}
|
||||
|
||||
void JDnsShutdown::waitForShutdown(const QList<JDnsShared*> &_list)
|
||||
{
|
||||
list = _list;
|
||||
phase = 0;
|
||||
|
||||
m.lock();
|
||||
start();
|
||||
w.wait(&m);
|
||||
|
||||
foreach(JDnsShared *i, list)
|
||||
{
|
||||
i->setParent(0);
|
||||
i->moveToThread(this);
|
||||
}
|
||||
|
||||
void addDebug(const QString &name, const QStringList &_lines)
|
||||
phase = 1;
|
||||
agent->start();
|
||||
wait();
|
||||
}
|
||||
|
||||
void JDnsShutdown::run()
|
||||
{
|
||||
m.lock();
|
||||
agent = new JDnsShutdownAgent;
|
||||
connect(agent, SIGNAL(started()), SLOT(agent_started()), Qt::DirectConnection);
|
||||
agent->start();
|
||||
exec();
|
||||
delete agent;
|
||||
}
|
||||
|
||||
void JDnsShutdown::agent_started()
|
||||
{
|
||||
if(phase == 0)
|
||||
{
|
||||
if(!_lines.isEmpty())
|
||||
w.wakeOne();
|
||||
m.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
worker = new JDnsShutdownWorker(list);
|
||||
connect(worker, SIGNAL(finished()), SLOT(worker_finished()), Qt::DirectConnection);
|
||||
}
|
||||
}
|
||||
|
||||
void JDnsShutdown::worker_finished()
|
||||
{
|
||||
delete worker;
|
||||
worker = 0;
|
||||
|
||||
quit();
|
||||
}
|
||||
|
||||
JDnsSharedDebugPrivate::JDnsSharedDebugPrivate(JDnsSharedDebug *_q)
|
||||
: QObject(_q), q(_q)
|
||||
{
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
void JDnsSharedDebugPrivate::addDebug(const QString &name, const QStringList &_lines)
|
||||
{
|
||||
if(!_lines.isEmpty())
|
||||
{
|
||||
QMutexLocker locker(&m);
|
||||
for(int n = 0; n < _lines.count(); ++n)
|
||||
lines += name + ": " + _lines[n];
|
||||
if(!dirty)
|
||||
{
|
||||
QMutexLocker locker(&m);
|
||||
for(int n = 0; n < _lines.count(); ++n)
|
||||
lines += name + ": " + _lines[n];
|
||||
if(!dirty)
|
||||
{
|
||||
dirty = true;
|
||||
QMetaObject::invokeMethod(this, "doUpdate", Qt::QueuedConnection);
|
||||
}
|
||||
dirty = true;
|
||||
QMetaObject::invokeMethod(this, "doUpdate", Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private slots:
|
||||
void doUpdate()
|
||||
void JDnsSharedDebugPrivate::doUpdate()
|
||||
{
|
||||
{
|
||||
{
|
||||
QMutexLocker locker(&m);
|
||||
if(!dirty)
|
||||
return;
|
||||
}
|
||||
emit q->readyRead();
|
||||
QMutexLocker locker(&m);
|
||||
if(!dirty)
|
||||
return;
|
||||
}
|
||||
};
|
||||
emit q->readyRead();
|
||||
}
|
||||
|
||||
JDnsSharedDebug::JDnsSharedDebug(QObject *parent)
|
||||
:QObject(parent)
|
||||
@@ -418,281 +285,195 @@ QStringList JDnsSharedDebug::readDebugLines()
|
||||
return tmplines;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// JDnsSharedRequest
|
||||
//----------------------------------------------------------------------------
|
||||
class JDnsSharedPrivate : public QObject
|
||||
JDnsSharedPrivate::JDnsSharedPrivate(JDnsShared *_q)
|
||||
: QObject(_q), q(_q)
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
class Instance
|
||||
{
|
||||
public:
|
||||
QJDns *jdns;
|
||||
QHostAddress addr;
|
||||
int index;
|
||||
}
|
||||
|
||||
Instance() : jdns(0)
|
||||
JDnsSharedRequest *JDnsSharedPrivate::findRequest(QJDns *jdns, int id) const
|
||||
{
|
||||
Handle h(jdns, id);
|
||||
return requestForHandle.value(h);
|
||||
}
|
||||
|
||||
void JDnsSharedPrivate::jdns_link(QJDns *jdns)
|
||||
{
|
||||
connect(jdns, SIGNAL(resultsReady(int, const QJDns::Response &)), SLOT(jdns_resultsReady(int, const QJDns::Response &)));
|
||||
connect(jdns, SIGNAL(published(int)), SLOT(jdns_published(int)));
|
||||
connect(jdns, SIGNAL(error(int, QJDns::Error)), SLOT(jdns_error(int, QJDns::Error)));
|
||||
connect(jdns, SIGNAL(shutdownFinished()), SLOT(jdns_shutdownFinished()));
|
||||
connect(jdns, SIGNAL(debugLinesReady()), SLOT(jdns_debugLinesReady()));
|
||||
}
|
||||
|
||||
int JDnsSharedPrivate::getNewIndex() const
|
||||
{
|
||||
// find lowest unused value
|
||||
for(int n = 0;; ++n)
|
||||
{
|
||||
bool found = false;
|
||||
foreach(Instance *i, instances)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
enum PreprocessMode
|
||||
{
|
||||
None, // don't muck with anything
|
||||
FillInAddress, // for A/AAAA
|
||||
FillInPtrOwner6, // for PTR, IPv6
|
||||
FillInPtrOwner4, // for PTR, IPv4
|
||||
};
|
||||
|
||||
JDnsShared *q;
|
||||
JDnsShared::Mode mode;
|
||||
bool shutting_down;
|
||||
JDnsSharedDebug *db;
|
||||
QString dbname;
|
||||
|
||||
QList<Instance*> instances;
|
||||
QHash<QJDns*,Instance*> instanceForQJDns;
|
||||
|
||||
QSet<JDnsSharedRequest*> requests;
|
||||
QHash<Handle,JDnsSharedRequest*> requestForHandle;
|
||||
|
||||
JDnsSharedPrivate(JDnsShared *_q) : QObject(_q), q(_q)
|
||||
{
|
||||
}
|
||||
|
||||
JDnsSharedRequest *findRequest(QJDns *jdns, int id) const
|
||||
{
|
||||
Handle h(jdns, id);
|
||||
return requestForHandle.value(h);
|
||||
}
|
||||
|
||||
void jdns_link(QJDns *jdns)
|
||||
{
|
||||
connect(jdns, SIGNAL(resultsReady(int, const QJDns::Response &)), SLOT(jdns_resultsReady(int, const QJDns::Response &)));
|
||||
connect(jdns, SIGNAL(published(int)), SLOT(jdns_published(int)));
|
||||
connect(jdns, SIGNAL(error(int, QJDns::Error)), SLOT(jdns_error(int, QJDns::Error)));
|
||||
connect(jdns, SIGNAL(shutdownFinished()), SLOT(jdns_shutdownFinished()));
|
||||
connect(jdns, SIGNAL(debugLinesReady()), SLOT(jdns_debugLinesReady()));
|
||||
}
|
||||
|
||||
int getNewIndex() const
|
||||
{
|
||||
// find lowest unused value
|
||||
for(int n = 0;; ++n)
|
||||
{
|
||||
bool found = false;
|
||||
foreach(Instance *i, instances)
|
||||
if(i->index == n)
|
||||
{
|
||||
if(i->index == n)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if(!found)
|
||||
return n;
|
||||
}
|
||||
if(!found)
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
void JDnsSharedPrivate::addDebug(int index, const QString &line)
|
||||
{
|
||||
if(db)
|
||||
db->d->addDebug(dbname + QString::number(index), QStringList() << line);
|
||||
}
|
||||
|
||||
void JDnsSharedPrivate::doDebug(QJDns *jdns, int index)
|
||||
{
|
||||
QStringList lines = jdns->debugLines();
|
||||
if(db)
|
||||
db->d->addDebug(dbname + QString::number(index), lines);
|
||||
}
|
||||
|
||||
JDnsSharedPrivate::PreprocessMode JDnsSharedPrivate::determinePpMode(const QJDns::Record &in)
|
||||
{
|
||||
// Note: since our implementation only allows 1 ipv4 and 1 ipv6
|
||||
// interface to exist, it is safe to publish both kinds of
|
||||
// records on both interfaces, with the same values. For
|
||||
// example, an A record can be published on both interfaces,
|
||||
// with the value set to the ipv4 interface. If we supported
|
||||
// multiple ipv4 interfaces, then this wouldn't work, because
|
||||
// we wouldn't know which value to use for the A record when
|
||||
// publishing on the ipv6 interface.
|
||||
|
||||
// publishing our own IP address? null address means the user
|
||||
// wants us to fill in the blank with our address.
|
||||
if((in.type == QJDns::Aaaa || in.type == QJDns::A) && in.address.isNull())
|
||||
{
|
||||
return FillInAddress;
|
||||
}
|
||||
// publishing our own reverse lookup? partial owner means
|
||||
// user wants us to fill in the rest.
|
||||
else if(in.type == QJDns::Ptr && in.owner == ".ip6.arpa.")
|
||||
{
|
||||
return FillInPtrOwner6;
|
||||
}
|
||||
else if(in.type == QJDns::Ptr && in.owner == ".in-addr.arpa.")
|
||||
{
|
||||
return FillInPtrOwner4;
|
||||
}
|
||||
|
||||
void addDebug(int index, const QString &line)
|
||||
return None;
|
||||
}
|
||||
|
||||
QJDns::Record JDnsSharedPrivate::manipulateRecord(const QJDns::Record &in, PreprocessMode ppmode, bool *modified)
|
||||
{
|
||||
if(ppmode == FillInAddress)
|
||||
{
|
||||
if(db)
|
||||
db->d->addDebug(dbname + QString::number(index), QStringList() << line);
|
||||
}
|
||||
QJDns::Record out = in;
|
||||
|
||||
void doDebug(QJDns *jdns, int index)
|
||||
{
|
||||
QStringList lines = jdns->debugLines();
|
||||
if(db)
|
||||
db->d->addDebug(dbname + QString::number(index), lines);
|
||||
}
|
||||
|
||||
PreprocessMode determinePpMode(const QJDns::Record &in)
|
||||
{
|
||||
// Note: since our implementation only allows 1 ipv4 and 1 ipv6
|
||||
// interface to exist, it is safe to publish both kinds of
|
||||
// records on both interfaces, with the same values. For
|
||||
// example, an A record can be published on both interfaces,
|
||||
// with the value set to the ipv4 interface. If we supported
|
||||
// multiple ipv4 interfaces, then this wouldn't work, because
|
||||
// we wouldn't know which value to use for the A record when
|
||||
// publishing on the ipv6 interface.
|
||||
|
||||
// publishing our own IP address? null address means the user
|
||||
// wants us to fill in the blank with our address.
|
||||
if((in.type == QJDns::Aaaa || in.type == QJDns::A) && in.address.isNull())
|
||||
if(in.type == QJDns::Aaaa)
|
||||
{
|
||||
return FillInAddress;
|
||||
}
|
||||
// publishing our own reverse lookup? partial owner means
|
||||
// user wants us to fill in the rest.
|
||||
else if(in.type == QJDns::Ptr && in.owner == ".ip6.arpa.")
|
||||
{
|
||||
return FillInPtrOwner6;
|
||||
}
|
||||
else if(in.type == QJDns::Ptr && in.owner == ".in-addr.arpa.")
|
||||
{
|
||||
return FillInPtrOwner4;
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
|
||||
QJDns::Record manipulateRecord(const QJDns::Record &in, PreprocessMode ppmode, bool *modified = 0)
|
||||
{
|
||||
if(ppmode == FillInAddress)
|
||||
{
|
||||
QJDns::Record out = in;
|
||||
|
||||
if(in.type == QJDns::Aaaa)
|
||||
{
|
||||
// are we operating on ipv6?
|
||||
foreach(Instance *i, instances)
|
||||
{
|
||||
if(i->addr.protocol() == QAbstractSocket::IPv6Protocol)
|
||||
{
|
||||
if(modified && !(out.address == i->addr))
|
||||
*modified = true;
|
||||
out.address = i->addr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // A
|
||||
{
|
||||
// are we operating on ipv4?
|
||||
foreach(Instance *i, instances)
|
||||
{
|
||||
if(i->addr.protocol() == QAbstractSocket::IPv4Protocol)
|
||||
{
|
||||
if(modified && !(out.address == i->addr))
|
||||
*modified = true;
|
||||
out.address = i->addr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
else if(ppmode == FillInPtrOwner6)
|
||||
{
|
||||
QJDns::Record out = in;
|
||||
|
||||
// are we operating on ipv6?
|
||||
foreach(Instance *i, instances)
|
||||
{
|
||||
if(i->addr.protocol() == QAbstractSocket::IPv6Protocol)
|
||||
{
|
||||
QByteArray newOwner = makeReverseName(i->addr);
|
||||
if(modified && !(out.owner == newOwner))
|
||||
if(modified && !(out.address == i->addr))
|
||||
*modified = true;
|
||||
out.owner = newOwner;
|
||||
out.address = i->addr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
else if(ppmode == FillInPtrOwner4)
|
||||
else // A
|
||||
{
|
||||
QJDns::Record out = in;
|
||||
|
||||
// are we operating on ipv4?
|
||||
foreach(Instance *i, instances)
|
||||
{
|
||||
if(i->addr.protocol() == QAbstractSocket::IPv4Protocol)
|
||||
{
|
||||
QByteArray newOwner = makeReverseName(i->addr);
|
||||
if(modified && !(out.owner == newOwner))
|
||||
if(modified && !(out.address == i->addr))
|
||||
*modified = true;
|
||||
out.owner = newOwner;
|
||||
out.address = i->addr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
if(modified)
|
||||
*modified = false;
|
||||
return in;
|
||||
return out;
|
||||
}
|
||||
|
||||
bool addInterface(const QHostAddress &addr);
|
||||
void removeInterface(const QHostAddress &addr);
|
||||
|
||||
void queryStart(JDnsSharedRequest *obj, const QByteArray &name, int qType);
|
||||
void queryCancel(JDnsSharedRequest *obj);
|
||||
void publishStart(JDnsSharedRequest *obj, QJDns::PublishMode m, const QJDns::Record &record);
|
||||
void publishUpdate(JDnsSharedRequest *obj, const QJDns::Record &record);
|
||||
void publishCancel(JDnsSharedRequest *obj);
|
||||
|
||||
public slots:
|
||||
void late_shutdown()
|
||||
else if(ppmode == FillInPtrOwner6)
|
||||
{
|
||||
shutting_down = false;
|
||||
emit q->shutdownFinished();
|
||||
QJDns::Record out = in;
|
||||
|
||||
// are we operating on ipv6?
|
||||
foreach(Instance *i, instances)
|
||||
{
|
||||
if(i->addr.protocol() == QAbstractSocket::IPv6Protocol)
|
||||
{
|
||||
QByteArray newOwner = makeReverseName(i->addr);
|
||||
if(modified && !(out.owner == newOwner))
|
||||
*modified = true;
|
||||
out.owner = newOwner;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
else if(ppmode == FillInPtrOwner4)
|
||||
{
|
||||
QJDns::Record out = in;
|
||||
|
||||
// are we operating on ipv4?
|
||||
foreach(Instance *i, instances)
|
||||
{
|
||||
if(i->addr.protocol() == QAbstractSocket::IPv4Protocol)
|
||||
{
|
||||
QByteArray newOwner = makeReverseName(i->addr);
|
||||
if(modified && !(out.owner == newOwner))
|
||||
*modified = true;
|
||||
out.owner = newOwner;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
private slots:
|
||||
void jdns_resultsReady(int id, const QJDns::Response &results);
|
||||
void jdns_published(int id);
|
||||
void jdns_error(int id, QJDns::Error e);
|
||||
void jdns_shutdownFinished();
|
||||
void jdns_debugLinesReady();
|
||||
};
|
||||
if(modified)
|
||||
*modified = false;
|
||||
return in;
|
||||
}
|
||||
|
||||
class JDnsSharedRequestPrivate : public QObject
|
||||
void JDnsSharedPrivate::late_shutdown()
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
JDnsSharedRequest *q;
|
||||
JDnsSharedPrivate *jsp;
|
||||
shutting_down = false;
|
||||
emit q->shutdownFinished();
|
||||
}
|
||||
|
||||
// current action
|
||||
JDnsSharedRequest::Type type;
|
||||
QByteArray name;
|
||||
int qType;
|
||||
QJDns::PublishMode pubmode;
|
||||
JDnsSharedPrivate::PreprocessMode ppmode;
|
||||
QJDns::Record pubrecord;
|
||||
JDnsSharedRequestPrivate::JDnsSharedRequestPrivate(JDnsSharedRequest *_q)
|
||||
: QObject(_q), q(_q), lateTimer(this)
|
||||
{
|
||||
connect(&lateTimer, SIGNAL(timeout()), SLOT(lateTimer_timeout()));
|
||||
}
|
||||
|
||||
// a single request might have to perform multiple QJDns operations
|
||||
QList<Handle> handles;
|
||||
void JDnsSharedRequestPrivate::resetSession()
|
||||
{
|
||||
name = QByteArray();
|
||||
pubrecord = QJDns::Record();
|
||||
handles.clear();
|
||||
published.clear();
|
||||
queryCache.clear();
|
||||
}
|
||||
|
||||
// keep a list of handles that successfully publish
|
||||
QList<Handle> published;
|
||||
|
||||
// use to weed out dups for multicast
|
||||
QList<QJDns::Record> queryCache;
|
||||
|
||||
bool success;
|
||||
JDnsSharedRequest::Error error;
|
||||
QList<QJDns::Record> results;
|
||||
SafeTimer lateTimer;
|
||||
|
||||
JDnsSharedRequestPrivate(JDnsSharedRequest *_q) : QObject(_q), q(_q), lateTimer(this)
|
||||
{
|
||||
connect(&lateTimer, SIGNAL(timeout()), SLOT(lateTimer_timeout()));
|
||||
}
|
||||
|
||||
void resetSession()
|
||||
{
|
||||
name = QByteArray();
|
||||
pubrecord = QJDns::Record();
|
||||
handles.clear();
|
||||
published.clear();
|
||||
queryCache.clear();
|
||||
}
|
||||
|
||||
private slots:
|
||||
void lateTimer_timeout()
|
||||
{
|
||||
emit q->resultsReady();
|
||||
}
|
||||
};
|
||||
void JDnsSharedRequestPrivate::lateTimer_timeout()
|
||||
{
|
||||
emit q->resultsReady();
|
||||
}
|
||||
|
||||
JDnsSharedRequest::JDnsSharedRequest(JDnsShared *jdnsShared, QObject *parent)
|
||||
:QObject(parent)
|
||||
@@ -816,7 +597,7 @@ QList<QByteArray> JDnsShared::domains()
|
||||
|
||||
void JDnsShared::waitForShutdown(const QList<JDnsShared*> &instances)
|
||||
{
|
||||
JDnsShutdown s;
|
||||
JDnsShutdown s;
|
||||
s.waitForShutdown(instances);
|
||||
}
|
||||
|
||||
@@ -920,7 +701,7 @@ bool JDnsSharedPrivate::addInterface(const QHostAddress &addr)
|
||||
{
|
||||
if(obj->d->type == JDnsSharedRequest::Query)
|
||||
{
|
||||
Handle h(i->jdns, i->jdns->queryStart(obj->d->name, obj->d->qType));
|
||||
Handle h(i->jdns, i->jdns->queryStart(obj->d->name, obj->d->qType));
|
||||
obj->d->handles += h;
|
||||
requestForHandle.insert(h, obj);
|
||||
}
|
||||
@@ -936,7 +717,7 @@ bool JDnsSharedPrivate::addInterface(const QHostAddress &addr)
|
||||
}
|
||||
|
||||
// publish the record on the new interface
|
||||
Handle h(i->jdns, i->jdns->publishStart(obj->d->pubmode, obj->d->pubrecord));
|
||||
Handle h(i->jdns, i->jdns->publishStart(obj->d->pubmode, obj->d->pubrecord));
|
||||
obj->d->handles += h;
|
||||
requestForHandle.insert(h, obj);
|
||||
}
|
||||
@@ -970,7 +751,7 @@ void JDnsSharedPrivate::removeInterface(const QHostAddress &addr)
|
||||
{
|
||||
for(int n = 0; n < obj->d->handles.count(); ++n)
|
||||
{
|
||||
Handle h = obj->d->handles[n];
|
||||
Handle h = obj->d->handles[n];
|
||||
if(h.jdns == i->jdns)
|
||||
{
|
||||
// see above, no need to cancel the operation
|
||||
@@ -985,7 +766,7 @@ void JDnsSharedPrivate::removeInterface(const QHostAddress &addr)
|
||||
{
|
||||
for(int n = 0; n < obj->d->published.count(); ++n)
|
||||
{
|
||||
Handle h = obj->d->published[n];
|
||||
Handle h = obj->d->published[n];
|
||||
if(h.jdns == i->jdns)
|
||||
{
|
||||
obj->d->published.removeAt(n);
|
||||
@@ -1135,7 +916,7 @@ void JDnsSharedPrivate::queryStart(JDnsSharedRequest *obj, const QByteArray &nam
|
||||
// query on all jdns instances
|
||||
foreach(Instance *i, instances)
|
||||
{
|
||||
Handle h(i->jdns, i->jdns->queryStart(name, qType));
|
||||
Handle h(i->jdns, i->jdns->queryStart(name, qType));
|
||||
obj->d->handles += h;
|
||||
|
||||
// keep track of this handle for this request
|
||||
@@ -1181,7 +962,7 @@ void JDnsSharedPrivate::publishStart(JDnsSharedRequest *obj, QJDns::PublishMode
|
||||
// attempt to publish on all jdns instances
|
||||
foreach(JDnsSharedPrivate::Instance *i, instances)
|
||||
{
|
||||
Handle h(i->jdns, i->jdns->publishStart(m, obj->d->pubrecord));
|
||||
Handle h(i->jdns, i->jdns->publishStart(m, obj->d->pubrecord));
|
||||
obj->d->handles += h;
|
||||
|
||||
// keep track of this handle for this request
|
||||
@@ -1232,7 +1013,7 @@ void JDnsSharedPrivate::jdns_resultsReady(int id, const QJDns::Response &results
|
||||
// only one response, so "cancel" it
|
||||
for(int n = 0; n < obj->d->handles.count(); ++n)
|
||||
{
|
||||
Handle h = obj->d->handles[n];
|
||||
Handle h = obj->d->handles[n];
|
||||
if(h.jdns == jdns && h.id == id)
|
||||
{
|
||||
obj->d->handles.removeAt(n);
|
||||
@@ -1306,10 +1087,10 @@ void JDnsSharedPrivate::jdns_published(int id)
|
||||
Q_ASSERT(obj);
|
||||
|
||||
// find handle
|
||||
Handle handle;
|
||||
Handle handle;
|
||||
for(int n = 0; n < obj->d->handles.count(); ++n)
|
||||
{
|
||||
Handle h = obj->d->handles[n];
|
||||
Handle h = obj->d->handles[n];
|
||||
if(h.jdns == jdns && h.id == id)
|
||||
{
|
||||
handle = h;
|
||||
@@ -1342,7 +1123,7 @@ void JDnsSharedPrivate::jdns_error(int id, QJDns::Error e)
|
||||
// "cancel" it
|
||||
for(int n = 0; n < obj->d->handles.count(); ++n)
|
||||
{
|
||||
Handle h = obj->d->handles[n];
|
||||
Handle h = obj->d->handles[n];
|
||||
if(h.jdns == jdns && h.id == id)
|
||||
{
|
||||
obj->d->handles.removeAt(n);
|
||||
@@ -1416,5 +1197,3 @@ void JDnsSharedPrivate::jdns_debugLinesReady()
|
||||
|
||||
doDebug(jdns, instanceForQJDns.value(jdns)->index);
|
||||
}
|
||||
|
||||
#include "jdnsshared.moc"
|
@@ -73,7 +73,7 @@ public:
|
||||
/**
|
||||
\brief Destroys the object
|
||||
*/
|
||||
~JDnsSharedDebug();
|
||||
virtual ~JDnsSharedDebug();
|
||||
|
||||
/**
|
||||
\brief Read the available debug information
|
322
thirdparty/jdns/jdnsshared/jdnsshared_helpers.h
vendored
Normal file
322
thirdparty/jdns/jdnsshared/jdnsshared_helpers.h
vendored
Normal file
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
* Copyright (C) 2006-2008 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
// Note: JDnsShared supports multiple interfaces for multicast, but only one
|
||||
// for IPv4 and one for IPv6. Sharing multiple interfaces of the same IP
|
||||
// version for multicast is unfortunately not possible without reworking
|
||||
// the jdns subsystem.
|
||||
//
|
||||
// The reason for this limitation is that in order to do multi-interface
|
||||
// multicast, you have to do a single bind to Any, and then use special
|
||||
// functions to determine which interface a packet came from and to
|
||||
// specify which interface a packet should go out on. Again this is just
|
||||
// not possible with the current system and the assumptions made by jdns.
|
||||
|
||||
// Note: When quering against multiple interfaces with multicast, it is
|
||||
// possible that different answers for a unique record may be reported
|
||||
// on each interface. We don't do anything about this.
|
||||
|
||||
#include "jdnsshared.h"
|
||||
#include "jdns_export.h"
|
||||
|
||||
// safeobj stuff, from qca
|
||||
|
||||
class JDNS_EXPORT JDnsSharedSafeTimer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
void JDnsSharedReleaseAndDeleteLater(QObject *owner, QObject *obj)
|
||||
{
|
||||
obj->disconnect(owner);
|
||||
obj->setParent(0);
|
||||
obj->deleteLater();
|
||||
}
|
||||
|
||||
JDnsSharedSafeTimer(QObject *parent = 0) :
|
||||
QObject(parent)
|
||||
{
|
||||
t = new QTimer(this);
|
||||
connect(t, SIGNAL(timeout()), SIGNAL(timeout()));
|
||||
}
|
||||
|
||||
~JDnsSharedSafeTimer()
|
||||
{
|
||||
JDnsSharedReleaseAndDeleteLater(this, t);
|
||||
}
|
||||
|
||||
int interval() const { return t->interval(); }
|
||||
bool isActive() const { return t->isActive(); }
|
||||
bool isSingleShot() const { return t->isSingleShot(); }
|
||||
void setInterval(int msec) { t->setInterval(msec); }
|
||||
void setSingleShot(bool singleShot) { t->setSingleShot(singleShot); }
|
||||
int timerId() const { return t->timerId(); }
|
||||
|
||||
public slots:
|
||||
void start(int msec) { t->start(msec); }
|
||||
void start() { t->start(); }
|
||||
void stop() { t->stop(); }
|
||||
|
||||
signals:
|
||||
void timeout();
|
||||
|
||||
private:
|
||||
QTimer *t;
|
||||
};
|
||||
|
||||
// for caching system info
|
||||
|
||||
class SystemInfoCache
|
||||
{
|
||||
public:
|
||||
QJDns::SystemInfo info;
|
||||
QTime time;
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Handle
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// QJDns uses integer handle ids, but they are only unique within
|
||||
// the relevant QJDns instance. Since we want our handles to be
|
||||
// unique across all instances, we'll make an instance/id pair.
|
||||
class Handle
|
||||
{
|
||||
public:
|
||||
QJDns *jdns;
|
||||
int id;
|
||||
|
||||
Handle() : jdns(0), id(-1)
|
||||
{
|
||||
}
|
||||
|
||||
Handle(QJDns *_jdns, int _id) : jdns(_jdns), id(_id)
|
||||
{
|
||||
}
|
||||
|
||||
~Handle() {}
|
||||
|
||||
bool operator==(const Handle &a) const
|
||||
{
|
||||
if(a.jdns == jdns && a.id == id)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator!=(const Handle &a) const
|
||||
{
|
||||
return !(operator==(a));
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// JDnsShutdown
|
||||
//----------------------------------------------------------------------------
|
||||
class JDnsShutdownAgent : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
JDnsShutdownAgent();
|
||||
~JDnsShutdownAgent() {}
|
||||
void start();
|
||||
|
||||
signals:
|
||||
void started();
|
||||
};
|
||||
|
||||
|
||||
class JDnsShutdownWorker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QList<JDnsShared*> list;
|
||||
|
||||
JDnsShutdownWorker(const QList<JDnsShared*> &_list);
|
||||
virtual ~JDnsShutdownWorker() {}
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
|
||||
private slots:
|
||||
void jdns_shutdownFinished();
|
||||
};
|
||||
|
||||
class JDnsShutdown : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
QMutex m;
|
||||
QWaitCondition w;
|
||||
QList<JDnsShared*> list;
|
||||
JDnsShutdownAgent *agent;
|
||||
JDnsShutdownWorker *worker;
|
||||
int phase;
|
||||
|
||||
JDnsShutdown();
|
||||
~JDnsShutdown() {}
|
||||
void waitForShutdown(const QList<JDnsShared*> &_list);
|
||||
|
||||
protected:
|
||||
virtual void run();
|
||||
|
||||
private slots:
|
||||
void agent_started();
|
||||
|
||||
void worker_finished();
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// JDnsSharedDebug
|
||||
//----------------------------------------------------------------------------
|
||||
class JDnsSharedDebugPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
JDnsSharedDebug *q;
|
||||
QMutex m;
|
||||
QStringList lines;
|
||||
bool dirty;
|
||||
|
||||
JDnsSharedDebugPrivate(JDnsSharedDebug *_q);
|
||||
~JDnsSharedDebugPrivate() {}
|
||||
|
||||
void addDebug(const QString &name, const QStringList &_lines);
|
||||
|
||||
private slots:
|
||||
void doUpdate();
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// JDnsSharedRequest
|
||||
//----------------------------------------------------------------------------
|
||||
class JDnsSharedPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
class Instance
|
||||
{
|
||||
public:
|
||||
QJDns *jdns;
|
||||
QHostAddress addr;
|
||||
int index;
|
||||
|
||||
Instance() : jdns(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
enum PreprocessMode
|
||||
{
|
||||
None, // don't muck with anything
|
||||
FillInAddress, // for A/AAAA
|
||||
FillInPtrOwner6, // for PTR, IPv6
|
||||
FillInPtrOwner4, // for PTR, IPv4
|
||||
};
|
||||
|
||||
JDnsShared *q;
|
||||
JDnsShared::Mode mode;
|
||||
bool shutting_down;
|
||||
JDnsSharedDebug *db;
|
||||
QString dbname;
|
||||
|
||||
QList<Instance*> instances;
|
||||
QHash<QJDns*,Instance*> instanceForQJDns;
|
||||
|
||||
QSet<JDnsSharedRequest*> requests;
|
||||
QHash<Handle,JDnsSharedRequest*> requestForHandle;
|
||||
|
||||
JDnsSharedPrivate(JDnsShared *_q);
|
||||
|
||||
~JDnsSharedPrivate() {}
|
||||
|
||||
JDnsSharedRequest *findRequest(QJDns *jdns, int id) const;
|
||||
|
||||
void jdns_link(QJDns *jdns);
|
||||
|
||||
int getNewIndex() const;
|
||||
|
||||
void addDebug(int index, const QString &line);
|
||||
|
||||
void doDebug(QJDns *jdns, int index);
|
||||
|
||||
PreprocessMode determinePpMode(const QJDns::Record &in);
|
||||
|
||||
QJDns::Record manipulateRecord(const QJDns::Record &in, PreprocessMode ppmode, bool *modified = 0);
|
||||
|
||||
bool addInterface(const QHostAddress &addr);
|
||||
void removeInterface(const QHostAddress &addr);
|
||||
|
||||
void queryStart(JDnsSharedRequest *obj, const QByteArray &name, int qType);
|
||||
void queryCancel(JDnsSharedRequest *obj);
|
||||
void publishStart(JDnsSharedRequest *obj, QJDns::PublishMode m, const QJDns::Record &record);
|
||||
void publishUpdate(JDnsSharedRequest *obj, const QJDns::Record &record);
|
||||
void publishCancel(JDnsSharedRequest *obj);
|
||||
|
||||
public slots:
|
||||
void late_shutdown();
|
||||
|
||||
private slots:
|
||||
void jdns_resultsReady(int id, const QJDns::Response &results);
|
||||
void jdns_published(int id);
|
||||
void jdns_error(int id, QJDns::Error e);
|
||||
void jdns_shutdownFinished();
|
||||
void jdns_debugLinesReady();
|
||||
};
|
||||
|
||||
class JDnsSharedRequestPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
JDnsSharedRequest *q;
|
||||
JDnsSharedPrivate *jsp;
|
||||
|
||||
// current action
|
||||
JDnsSharedRequest::Type type;
|
||||
QByteArray name;
|
||||
int qType;
|
||||
QJDns::PublishMode pubmode;
|
||||
JDnsSharedPrivate::PreprocessMode ppmode;
|
||||
QJDns::Record pubrecord;
|
||||
|
||||
// a single request might have to perform multiple QJDns operations
|
||||
QList<Handle> handles;
|
||||
|
||||
// keep a list of handles that successfully publish
|
||||
QList<Handle> published;
|
||||
|
||||
// use to weed out dups for multicast
|
||||
QList<QJDns::Record> queryCache;
|
||||
|
||||
bool success;
|
||||
JDnsSharedRequest::Error error;
|
||||
QList<QJDns::Record> results;
|
||||
JDnsSharedSafeTimer lateTimer;
|
||||
|
||||
JDnsSharedRequestPrivate(JDnsSharedRequest *_q);
|
||||
~JDnsSharedRequestPrivate() {};
|
||||
|
||||
void resetSession();
|
||||
|
||||
private slots:
|
||||
void lateTimer_timeout();
|
||||
};
|
||||
|
1047
thirdparty/jdns/qjdns.cpp
vendored
1047
thirdparty/jdns/qjdns.cpp
vendored
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user