PageRenderTime 224ms CodeModel.GetById 111ms app.highlight 13ms RepoModel.GetById 98ms app.codeStats 0ms

/src/libtomahawk/network/PortFwdThread.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 144 lines | 94 code | 29 blank | 21 comment | 10 complexity | 02f34f17dbad4455c7cd29eda29313b2 MD5 | raw file
  1/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2 *
  3 *   Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
  4 *
  5 *   Tomahawk is free software: you can redistribute it and/or modify
  6 *   it under the terms of the GNU General Public License as published by
  7 *   the Free Software Foundation, either version 3 of the License, or
  8 *   (at your option) any later version.
  9 *
 10 *   Tomahawk is distributed in the hope that it will be useful,
 11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 13 *   GNU General Public License for more details.
 14 *
 15 *   You should have received a copy of the GNU General Public License
 16 *   along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
 17 */
 18
 19#include "PortFwdThread.h"
 20
 21#include "portfwd/portfwd.h"
 22#include "utils/Logger.h"
 23#include "Source.h"
 24
 25#include <QCoreApplication>
 26#include <QNetworkInterface>
 27#include <QStringList>
 28#include <QTime>
 29#include <QTimer>
 30
 31
 32PortFwdThread::PortFwdThread( unsigned int port )
 33    : QThread()
 34    , m_port( port )
 35{
 36}
 37
 38
 39PortFwdThread::~PortFwdThread()
 40{
 41}
 42
 43
 44void
 45PortFwdThread::run()
 46{
 47    m_worker = QPointer< PortFwdWorker >( new PortFwdWorker( m_port ) );
 48    Q_ASSERT( m_worker );
 49    connect( m_worker.data(), SIGNAL( externalAddressDetected( QHostAddress, unsigned int ) ), this, SIGNAL( externalAddressDetected( QHostAddress, unsigned int ) ) );
 50    QTimer::singleShot( 0, m_worker.data(), SLOT( work() ) );
 51    exec();
 52
 53    if ( m_worker.data()->externalPort() )
 54    {
 55        qDebug() << "Unregistering port fwd";
 56        m_worker.data()->unregister();
 57    }
 58
 59    if ( m_worker )
 60        delete m_worker.data();
 61}
 62
 63
 64QPointer< PortFwdWorker >
 65PortFwdThread::worker() const
 66{
 67    return m_worker;
 68}
 69
 70
 71PortFwdWorker::PortFwdWorker( unsigned int port )
 72    : QObject()
 73    , m_externalPort( 0 )
 74    , m_port( port )
 75{
 76}
 77
 78
 79PortFwdWorker::~PortFwdWorker()
 80{
 81    delete m_portfwd;
 82}
 83
 84
 85void
 86PortFwdWorker::unregister()
 87{
 88    m_portfwd->remove( m_externalPort );
 89}
 90
 91
 92void
 93PortFwdWorker::work()
 94{
 95    qsrand( QTime( 0, 0, 0 ).secsTo( QTime::currentTime() ) );
 96    m_portfwd = new Portfwd();
 97
 98    foreach ( QHostAddress ha, QNetworkInterface::allAddresses() )
 99    {
100        if( ha.toString() == "127.0.0.1" ) continue;
101        if( ha.toString().contains( ":" ) ) continue; //ipv6
102
103        m_portfwd->addBlockedDevice( ha.toString().toStdString() );
104    }
105
106    // try and pick an available port:
107    if ( m_portfwd->init( 2000 ) )
108    {
109        int tryport = m_port;
110
111        // last.fm office firewall policy hack
112        // (corp. firewall allows outgoing connections to this port,
113        //  so listen on this if you want lastfmers to connect to you)
114        if ( qApp->arguments().contains( "--porthack" ) )
115        {
116            tryport = 3389;
117            m_portfwd->remove( tryport );
118        }
119
120        for ( int r = 0; r < 3; ++r )
121        {
122            qDebug() << "Trying to setup portfwd on" << tryport;
123            if ( m_portfwd->add( tryport, m_port ) )
124            {
125                QString pubip = QString( m_portfwd->external_ip().c_str() ).trimmed();
126                m_externalAddress = QHostAddress( pubip );
127                m_externalPort = tryport;
128                tDebug() << "External servent address detected as" << pubip << ":" << m_externalPort;
129                qDebug() << "Max upstream  " << m_portfwd->max_upstream_bps() << "bps";
130                qDebug() << "Max downstream" << m_portfwd->max_downstream_bps() << "bps";
131                break;
132            }
133            tryport = qAbs( 10000 + 50000 * (float)qrand() / RAND_MAX );
134        }
135    }
136    else
137        tDebug() << "No UPNP Gateway device found?";
138
139    if ( !m_externalPort )
140        tDebug() << "Could not setup fwd for port:" << m_port;
141
142    emit externalAddressDetected( m_externalAddress, m_externalPort );
143}
144