1
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
3
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
4
* Copyright 2010-2012, Jeff Mitchell <jeff@tomahawk-player.org>
6
* Tomahawk is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
11
* Tomahawk is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
23
// time before new connection terminates if no auth received
24
#define AUTH_TIMEOUT 180000
26
#include <QtCore/QObject>
27
#include <QtCore/QMap>
28
#include <QtCore/QMutex>
29
#include <QtCore/QSharedPointer>
30
#include <QtCore/QTimer>
31
#include <QtCore/QPointer>
32
#include <QtNetwork/QTcpServer>
33
#include <QtNetwork/QTcpSocket>
34
#include <QtNetwork/QHostInfo>
36
#include <qjson/parser.h>
37
#include <qjson/serializer.h>
38
#include <qjson/qobjecthelper.h>
43
#include <boost/function.hpp>
49
class ControlConnection;
50
class StreamConnection;
51
class ProxyConnection;
52
class RemoteCollectionConnection;
55
// this is used to hold a bit of state, so when a connected signal is emitted
56
// from a socket, we can associate it with a Connection object etc.
57
class DLLEXPORT QTcpSocketExtra : public QTcpSocket
62
QTcpSocketExtra() : QTcpSocket()
64
QTimer::singleShot( AUTH_TIMEOUT, this, SLOT( authTimeout() ) ) ;
67
QWeakPointer<Connection> _conn;
78
qDebug() << "Connection timed out before providing a valid offer-key";
79
this->disconnectFromHost();
83
class DLLEXPORT Servent : public QTcpServer
88
static Servent* instance();
90
explicit Servent( QObject* parent = 0 );
93
bool startListening( QHostAddress ha, bool upnp, int port );
95
int port() const { return m_port; }
97
// creates new token that allows a controlconnection to be set up
98
QString createConnectionKey( const QString& name = "", const QString &nodeid = "", const QString &key = "", bool onceOnly = true );
100
void registerOffer( const QString& key, Connection* conn );
102
void registerControlConnection( ControlConnection* conn );
103
void unregisterControlConnection( ControlConnection* conn );
104
ControlConnection* lookupControlConnection( const QString& name );
106
void connectToPeer( const QString& ha, int port, const QString &key, const QString& name = "", const QString& id = "" );
107
void connectToPeer( const QString& ha, int port, const QString &key, Connection* conn );
108
void reverseOfferRequest( ControlConnection* orig_conn, const QString &theirdbid, const QString& key, const QString& theirkey );
110
bool visibleExternally() const { return !m_externalHostname.isNull() || (m_externalPort > 0 && !m_externalAddress.isNull()); }
111
QString externalAddress() const { return !m_externalHostname.isNull() ? m_externalHostname : m_externalAddress.toString(); }
112
int externalPort() const { return m_externalPort; }
114
QSharedPointer< QIODevice > remoteIODeviceFactory( const Tomahawk::result_ptr& );
115
static bool isIPWhitelisted( QHostAddress ip );
117
bool connectedToSession( const QString& session );
118
unsigned int numConnectedPeers() const { return m_controlconnections.length(); }
120
QList< StreamConnection* > streams() const { return m_scsessions; }
122
QSharedPointer< QIODevice > getIODeviceForUrl( const Tomahawk::result_ptr& result );
123
void registerIODeviceFactory( const QString &proto, boost::function< QSharedPointer< QIODevice >(Tomahawk::result_ptr) > fac );
124
QSharedPointer< QIODevice > localFileIODeviceFactory( const Tomahawk::result_ptr& result );
125
QSharedPointer< QIODevice > httpIODeviceFactory( const Tomahawk::result_ptr& result );
127
bool isReady() const { return m_ready; };
130
void streamStarted( StreamConnection* );
131
void streamFinished( StreamConnection* );
135
void incomingConnection( int sd );
138
void setInternalAddress();
139
void setExternalAddress( QHostAddress ha, unsigned int port );
141
void socketError( QAbstractSocket::SocketError );
142
void createParallelConnection( Connection* orig_conn, Connection* new_conn, const QString& key );
144
void registerStreamConnection( StreamConnection* );
145
void onStreamFinished( StreamConnection* sc );
147
void socketConnected();
148
void triggerDBSync();
153
Connection* claimOffer( ControlConnection* cc, const QString &nodeid, const QString &key, const QHostAddress peer = QHostAddress::Any );
156
bool isValidExternalIP( const QHostAddress& addr ) const;
157
void handoverSocket( Connection* conn, QTcpSocketExtra* sock );
158
void printCurrentTransfers();
160
QJson::Parser parser;
161
QList< ControlConnection* > m_controlconnections; // canonical list of authed peers
162
QMap< QString, QWeakPointer< Connection > > m_offers;
163
QStringList m_connectedNodes;
165
int m_port, m_externalPort;
166
QHostAddress m_externalAddress;
167
QString m_externalHostname;
171
// currently active file transfers:
172
QList< StreamConnection* > m_scsessions;
173
QMutex m_ftsession_mut;
175
QMap< QString,boost::function< QSharedPointer< QIODevice >(Tomahawk::result_ptr) > > m_iofactories;
177
QWeakPointer< PortFwdThread > m_portfwd;
178
static Servent* s_instance;