mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-04-13 12:31:52 +02:00
* Port-Forwards are now being setuped in a separate thread to avoid blocking the GUI.
This commit is contained in:
parent
b95d8a6b93
commit
e828972b95
@ -77,13 +77,15 @@ public:
|
||||
signals:
|
||||
void settingsChanged();
|
||||
|
||||
private slots:
|
||||
void setupSIP();
|
||||
|
||||
private:
|
||||
void initLocalCollection();
|
||||
void loadPlugins();
|
||||
void registerMetaTypes();
|
||||
void startServent();
|
||||
void setupDatabase();
|
||||
void setupSIP();
|
||||
void setupPipeline();
|
||||
void startHTTP();
|
||||
|
||||
|
@ -29,6 +29,7 @@ set( libSources
|
||||
network/filetransferconnection.cpp
|
||||
network/dbsyncconnection.cpp
|
||||
network/remotecollection.cpp
|
||||
network/portfwdthread.cpp
|
||||
|
||||
database/fuzzyindex.cpp
|
||||
database/databaseworker.cpp
|
||||
@ -122,6 +123,7 @@ set( libHeaders
|
||||
network/servent.h
|
||||
network/connection.h
|
||||
network/controlconnection.h
|
||||
network/portfwdthread.h
|
||||
)
|
||||
|
||||
include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ..
|
||||
|
89
src/libtomahawk/network/portfwdthread.cpp
Normal file
89
src/libtomahawk/network/portfwdthread.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
#include "portfwdthread.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QStringList>
|
||||
#include <QTime>
|
||||
#include <QTimer>
|
||||
|
||||
#include "portfwd/portfwd.h"
|
||||
|
||||
|
||||
PortFwdThread::PortFwdThread( unsigned int port )
|
||||
: QThread()
|
||||
, m_externalPort( 0 )
|
||||
, m_port( port )
|
||||
{
|
||||
moveToThread( this );
|
||||
start();
|
||||
}
|
||||
|
||||
|
||||
PortFwdThread::~PortFwdThread()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "waiting for event loop to finish...";
|
||||
quit();
|
||||
wait( 2500 );
|
||||
|
||||
delete m_portfwd;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PortFwdThread::work()
|
||||
{
|
||||
qsrand( QTime( 0, 0, 0 ).secsTo( QTime::currentTime() ) );
|
||||
m_portfwd = new Portfwd();
|
||||
|
||||
// try and pick an available port:
|
||||
if( m_portfwd->init( 2000 ) )
|
||||
{
|
||||
int tryport = m_port;
|
||||
|
||||
// last.fm office firewall policy hack
|
||||
// (corp. firewall allows outgoing connections to this port,
|
||||
// so listen on this if you want lastfmers to connect to you)
|
||||
if( qApp->arguments().contains( "--porthack" ) )
|
||||
{
|
||||
tryport = 3389;
|
||||
m_portfwd->remove( tryport );
|
||||
}
|
||||
|
||||
for( int r = 0; r < 5; ++r )
|
||||
{
|
||||
qDebug() << "Trying to setup portfwd on" << tryport;
|
||||
if( m_portfwd->add( tryport, m_port ) )
|
||||
{
|
||||
QString pubip = QString( m_portfwd->external_ip().c_str() );
|
||||
m_externalAddress = QHostAddress( pubip );
|
||||
m_externalPort = tryport;
|
||||
qDebug() << "External servent address detected as" << pubip << ":" << m_externalPort;
|
||||
qDebug() << "Max upstream " << m_portfwd->max_upstream_bps() << "bps";
|
||||
qDebug() << "Max downstream" << m_portfwd->max_downstream_bps() << "bps";
|
||||
break;
|
||||
}
|
||||
tryport = qAbs( 10000 + 50000 * (float)qrand() / RAND_MAX );
|
||||
}
|
||||
}
|
||||
else
|
||||
qDebug() << "No UPNP Gateway device found?";
|
||||
|
||||
if( !m_externalPort )
|
||||
qDebug() << "Could not setup fwd for port:" << m_port;
|
||||
|
||||
emit externalAddressDetected( m_externalAddress, m_externalPort );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PortFwdThread::run()
|
||||
{
|
||||
QTimer::singleShot( 0, this, SLOT( work() ) );
|
||||
exec();
|
||||
|
||||
if ( m_externalPort )
|
||||
{
|
||||
qDebug() << "Unregistering port fwd";
|
||||
m_portfwd->remove( m_externalPort );
|
||||
}
|
||||
}
|
32
src/libtomahawk/network/portfwdthread.h
Normal file
32
src/libtomahawk/network/portfwdthread.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef PORTFWDTHREAD_H
|
||||
#define PORTFWDTHREAD_H
|
||||
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <QHostAddress>
|
||||
|
||||
class Portfwd;
|
||||
|
||||
class PortFwdThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PortFwdThread( unsigned int port );
|
||||
~PortFwdThread();
|
||||
|
||||
signals:
|
||||
void externalAddressDetected( QHostAddress ha, unsigned int port );
|
||||
|
||||
private slots:
|
||||
void work();
|
||||
|
||||
private:
|
||||
void run();
|
||||
|
||||
Portfwd* m_portfwd;
|
||||
QHostAddress m_externalAddress;
|
||||
unsigned int m_externalPort, m_port;
|
||||
};
|
||||
|
||||
#endif // PORTFWDTHREAD_H
|
@ -4,7 +4,6 @@
|
||||
#include <QMutexLocker>
|
||||
#include <QNetworkInterface>
|
||||
#include <QFile>
|
||||
#include <QTime>
|
||||
#include <QThread>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkReply>
|
||||
@ -18,7 +17,7 @@
|
||||
#include "filetransferconnection.h"
|
||||
#include "sourcelist.h"
|
||||
|
||||
#include "portfwd/portfwd.h"
|
||||
#include "portfwdthread.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
@ -36,12 +35,9 @@ Servent::Servent( QObject* parent )
|
||||
: QTcpServer( parent )
|
||||
, m_port( 0 )
|
||||
, m_externalPort( 0 )
|
||||
, pf( new Portfwd() )
|
||||
{
|
||||
s_instance = this;
|
||||
|
||||
qsrand( QTime( 0, 0, 0 ).secsTo( QTime::currentTime() ) );
|
||||
|
||||
{
|
||||
boost::function<QSharedPointer<QIODevice>(result_ptr)> fac =
|
||||
boost::bind( &Servent::localFileIODeviceFactory, this, _1 );
|
||||
@ -64,11 +60,7 @@ Servent::Servent( QObject* parent )
|
||||
|
||||
Servent::~Servent()
|
||||
{
|
||||
if( m_externalPort )
|
||||
{
|
||||
qDebug() << "Unregistering port fwd";
|
||||
pf->remove( m_externalPort );
|
||||
}
|
||||
delete m_portfwd;
|
||||
}
|
||||
|
||||
|
||||
@ -88,52 +80,6 @@ Servent::startListening( QHostAddress ha, bool upnp, int port )
|
||||
qDebug() << "Servent listening on port" << m_port << " servent thread:" << thread();
|
||||
}
|
||||
|
||||
// TODO check if we have a public/internet IP on this machine directly
|
||||
// FIXME the portfwd stuff is blocking, so we hang here for 2 secs atm
|
||||
if( upnp )
|
||||
{
|
||||
// try and pick an available port:
|
||||
if( pf->init( 2000 ) )
|
||||
{
|
||||
int tryport = m_port;
|
||||
|
||||
// last.fm office firewall policy hack
|
||||
// (corp. firewall allows outgoing connections to this port,
|
||||
// so listen on this if you want lastfmers to connect to you)
|
||||
if( qApp->arguments().contains( "--porthack" ) )
|
||||
{
|
||||
tryport = 3389;
|
||||
pf->remove( tryport );
|
||||
}
|
||||
|
||||
for( int r=0; r<5; ++r )
|
||||
{
|
||||
qDebug() << "Trying to setup portfwd on" << tryport;
|
||||
if( pf->add( tryport, m_port ) )
|
||||
{
|
||||
QString pubip = QString( pf->external_ip().c_str() );
|
||||
m_externalAddress = QHostAddress( pubip );
|
||||
m_externalPort = tryport;
|
||||
qDebug() << "External servent address detected as" << pubip << ":" << m_externalPort;
|
||||
qDebug() << "Max upstream " << pf->max_upstream_bps() << "bps";
|
||||
qDebug() << "Max downstream" << pf->max_downstream_bps() << "bps";
|
||||
break;
|
||||
}
|
||||
tryport = 10000 + 50000 * (float)qrand()/RAND_MAX;
|
||||
}
|
||||
if( !m_externalPort )
|
||||
{
|
||||
qDebug() << "Could not setup fwd for port:" << m_port;
|
||||
}
|
||||
}
|
||||
else qDebug() << "No UPNP Gateway device found?";
|
||||
}
|
||||
|
||||
if( m_externalPort == 0 )
|
||||
{
|
||||
qDebug() << "No external access, LAN and outbound connections only!";
|
||||
}
|
||||
|
||||
// --lanhack means to advertise your LAN IP over jabber as if it were externallyVisible
|
||||
if( qApp->arguments().contains( "--lanhack" ) )
|
||||
{
|
||||
@ -149,6 +95,13 @@ Servent::startListening( QHostAddress ha, bool upnp, int port )
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( upnp )
|
||||
{
|
||||
// TODO check if we have a public/internet IP on this machine directly
|
||||
m_portfwd = new PortFwdThread( m_port );
|
||||
connect( m_portfwd, SIGNAL( externalAddressDetected( QHostAddress, unsigned int ) ),
|
||||
SLOT( setExternalAddress( QHostAddress, unsigned int ) ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -160,7 +113,7 @@ Servent::createConnectionKey( const QString& name )
|
||||
Q_ASSERT( this->thread() == QThread::currentThread() );
|
||||
|
||||
QString key = uuid();
|
||||
ControlConnection * cc = new ControlConnection( this );
|
||||
ControlConnection* cc = new ControlConnection( this );
|
||||
cc->setName( name.isEmpty() ? QString( "KEY(%1)" ).arg( key ) : name );
|
||||
registerOffer( key, cc );
|
||||
return key;
|
||||
@ -168,10 +121,17 @@ Servent::createConnectionKey( const QString& name )
|
||||
|
||||
|
||||
void
|
||||
Servent::setExternalAddress( QHostAddress ha, int port )
|
||||
Servent::setExternalAddress( QHostAddress ha, unsigned int port )
|
||||
{
|
||||
m_externalAddress = ha;
|
||||
m_externalPort = port;
|
||||
|
||||
if( m_externalPort == 0 )
|
||||
{
|
||||
qDebug() << "No external access, LAN and outbound connections only!";
|
||||
}
|
||||
|
||||
emit ready();
|
||||
}
|
||||
|
||||
|
||||
@ -217,8 +177,10 @@ void
|
||||
Servent::incomingConnection( int sd )
|
||||
{
|
||||
Q_ASSERT( this->thread() == QThread::currentThread() );
|
||||
|
||||
QTcpSocketExtra* sock = new QTcpSocketExtra;
|
||||
qDebug() << Q_FUNC_INFO << "Accepting connection, sock" << sock;
|
||||
|
||||
sock->moveToThread( thread() );
|
||||
sock->_disowned = false;
|
||||
sock->_outbound = false;
|
||||
@ -381,7 +343,6 @@ Servent::socketConnected()
|
||||
qDebug() << "Servent::SocketConnected" << thread() << "socket:" << sock;
|
||||
|
||||
Connection* conn = sock->_conn;
|
||||
|
||||
handoverSocket( conn, sock );
|
||||
}
|
||||
|
||||
@ -421,7 +382,7 @@ Servent::socketError( QAbstractSocket::SocketError e )
|
||||
|
||||
Connection* conn = sock->_conn;
|
||||
qDebug() << "Servent::SocketError:" << e << conn->id() << conn->name();
|
||||
if(!sock->_disowned)
|
||||
if( !sock->_disowned )
|
||||
{
|
||||
// connection will delete if we already transferred ownership, otherwise:
|
||||
sock->deleteLater();
|
||||
@ -749,7 +710,7 @@ QSharedPointer<QIODevice>
|
||||
Servent::localFileIODeviceFactory( const Tomahawk::result_ptr& result )
|
||||
{
|
||||
// ignore "file://" at front of url
|
||||
QFile * io = new QFile( result->url().mid( QString( "file://" ).length() ) );
|
||||
QFile* io = new QFile( result->url().mid( QString( "file://" ).length() ) );
|
||||
if ( io )
|
||||
io->open( QIODevice::ReadOnly );
|
||||
|
||||
|
@ -33,7 +33,7 @@ class ControlConnection;
|
||||
class FileTransferConnection;
|
||||
class ProxyConnection;
|
||||
class RemoteCollectionConnection;
|
||||
class Portfwd;
|
||||
class PortFwdThread;
|
||||
|
||||
// this is used to hold a bit of state, so when a connected signal is emitted
|
||||
// from a socket, we can associate it with a Connection object etc.
|
||||
@ -90,7 +90,6 @@ public:
|
||||
void connectToPeer( const QString& ha, int port, const QString &key, Connection* conn );
|
||||
void reverseOfferRequest( ControlConnection* orig_conn, const QString& key, const QString& theirkey );
|
||||
|
||||
void setExternalAddress( QHostAddress ha, int port );
|
||||
bool visibleExternally() const { return m_externalPort > 0 && !m_externalAddress.isNull(); }
|
||||
QHostAddress externalAddress() const { return m_externalAddress; }
|
||||
int externalPort() const { return m_externalPort; }
|
||||
@ -111,11 +110,14 @@ public:
|
||||
signals:
|
||||
void fileTransferStarted( FileTransferConnection* );
|
||||
void fileTransferFinished( FileTransferConnection* );
|
||||
void ready();
|
||||
|
||||
protected:
|
||||
void incomingConnection( int sd );
|
||||
|
||||
public slots:
|
||||
void setExternalAddress( QHostAddress ha, unsigned int port );
|
||||
|
||||
void socketError( QAbstractSocket::SocketError );
|
||||
void createParallelConnection( Connection* orig_conn, Connection* new_conn, const QString& key );
|
||||
|
||||
@ -145,9 +147,9 @@ private:
|
||||
QList< FileTransferConnection* > m_ftsessions;
|
||||
QMutex m_ftsession_mut;
|
||||
|
||||
Portfwd* pf;
|
||||
QMap< QString,boost::function<QSharedPointer<QIODevice>(Tomahawk::result_ptr)> > m_iofactories;
|
||||
|
||||
PortFwdThread* m_portfwd;
|
||||
static Servent* s_instance;
|
||||
};
|
||||
|
||||
|
@ -108,10 +108,6 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
|
||||
{
|
||||
qsrand( QTime( 0, 0, 0 ).secsTo( QTime::currentTime() ) );
|
||||
|
||||
new Pipeline( this );
|
||||
new SourceList( this );
|
||||
m_servent = new Servent( this );
|
||||
|
||||
#ifdef TOMAHAWK_HEADLESS
|
||||
m_headless = true;
|
||||
#else
|
||||
@ -134,6 +130,13 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
|
||||
|
||||
new TomahawkSettings( this );
|
||||
m_audioEngine = new AudioEngine;
|
||||
|
||||
new Pipeline( this );
|
||||
new SourceList( this );
|
||||
|
||||
m_servent = new Servent( this );
|
||||
connect( m_servent, SIGNAL( ready() ), SLOT( setupSIP() ) );
|
||||
|
||||
setupDatabase();
|
||||
|
||||
#ifndef NO_LIBLASTFM
|
||||
@ -160,8 +163,8 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
|
||||
{
|
||||
qDebug() << "Setting proxy to saved values";
|
||||
m_proxy = new QNetworkProxy( static_cast<QNetworkProxy::ProxyType>(TomahawkSettings::instance()->proxyType()), TomahawkSettings::instance()->proxyHost(), TomahawkSettings::instance()->proxyPort(), TomahawkSettings::instance()->proxyUsername(), TomahawkSettings::instance()->proxyPassword() );
|
||||
qDebug() << "Proxy type = " << QString::number( static_cast<int>(m_proxy->type()) );
|
||||
qDebug() << "Proxy host = " << m_proxy->hostName();
|
||||
qDebug() << "Proxy type =" << QString::number( static_cast<int>(m_proxy->type()) );
|
||||
qDebug() << "Proxy host =" << m_proxy->hostName();
|
||||
QNetworkAccessManager* nam = TomahawkApp::instance()->nam();
|
||||
nam->setProxy( *m_proxy );
|
||||
}
|
||||
@ -170,14 +173,9 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
|
||||
|
||||
QNetworkProxy::setApplicationProxy( *m_proxy );
|
||||
|
||||
m_sipHandler = new SipHandler( this );
|
||||
m_infoSystem = new Tomahawk::InfoSystem::InfoSystem( this );
|
||||
|
||||
if( !arguments().contains("--nojabber") )
|
||||
{
|
||||
setupSIP();
|
||||
m_xmppBot = new XMPPBot( this );
|
||||
}
|
||||
|
||||
#ifndef TOMAHAWK_HEADLESS
|
||||
if ( !m_headless )
|
||||
{
|
||||
@ -196,8 +194,6 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
|
||||
if( arguments().contains( "--http" ) || TomahawkSettings::instance()->value( "network/http", true ).toBool() )
|
||||
startHTTP();
|
||||
|
||||
m_sipHandler->connect();
|
||||
|
||||
#ifndef TOMAHAWK_HEADLESS
|
||||
if ( !TomahawkSettings::instance()->hasScannerPath() )
|
||||
{
|
||||
@ -258,6 +254,7 @@ TomahawkApp::registerMetaTypes()
|
||||
qRegisterMetaType< QTcpSocket* >("QTcpSocket*");
|
||||
qRegisterMetaType< QSharedPointer<QIODevice> >("QSharedPointer<QIODevice>");
|
||||
qRegisterMetaType< QFileInfo >("QFileInfo");
|
||||
qRegisterMetaType< QHostAddress >("QHostAddress");
|
||||
qRegisterMetaType< QMap<QString, unsigned int> >("QMap<QString, unsigned int>");
|
||||
qRegisterMetaType< QMap< QString, plentry_ptr > >("QMap< QString, plentry_ptr >");
|
||||
qRegisterMetaType< QHash< QString, QMap<quint32, quint16> > >("QHash< QString, QMap<quint32, quint16> >");
|
||||
@ -399,8 +396,12 @@ TomahawkApp::setupSIP()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
m_sipHandler = new SipHandler( this );
|
||||
if( !arguments().contains( "--nojabber" ) )
|
||||
{
|
||||
m_xmppBot = new XMPPBot( this );
|
||||
|
||||
// m_sipHandler->setProxy( m_proxy );
|
||||
m_sipHandler->connect();
|
||||
// m_sipHandler->setProxy( m_proxy );
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user