1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-04-20 07:52:30 +02:00

Wait in ConnectMan for authentication until declaring a Connection as success

This commit is contained in:
Uwe L. Korn 2013-08-30 16:06:31 +02:00
parent 086b051665
commit 80f12c3410
4 changed files with 105 additions and 26 deletions

View File

@ -331,12 +331,14 @@ Connection::checkACL()
{
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Not checking ACL, nodeid is empty";
QTimer::singleShot( 0, this, SLOT( doSetup() ) );
emit authSuccessful();
return;
}
if ( Servent::isIPWhitelisted( d_func()->peerIpAddress ) )
{
QTimer::singleShot( 0, this, SLOT( doSetup() ) );
emit authSuccessful();
return;
}
@ -358,15 +360,19 @@ Connection::aclDecision( Tomahawk::ACLStatus::Type status )
{
Q_D( Connection );
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "ACL decision for" << name() << ":" << status;
if ( status == Tomahawk::ACLStatus::Stream )
{
QTimer::singleShot( 0, this, SLOT( doSetup() ) );
return;
}
// We have a decision, free memory.
d->aclRequest->deleteLater();
if ( status == Tomahawk::ACLStatus::Stream )
{
QTimer::singleShot( 0, this, SLOT( doSetup() ) );
emit authSuccessful();
return;
}
emit authFailed();
shutdown();
}
@ -379,6 +385,8 @@ Connection::authCheckTimeout()
if ( d->ready )
return;
emit authTimeout();
tDebug( LOGVERBOSE ) << "Closing connection, not authed in time.";
shutdown();
}

View File

@ -87,6 +87,24 @@ public:
QString bareName() const;
signals:
/**
* Emitted if the authentication of this connection finally failed.
*/
void authFailed();
/**
* Emitted if this connection was authenticated so that we can start talking to the other peer.
*/
void authSuccessful();
/**
* Emiited if the authentication could not be processed in a given timespan.
*
* Though this does implicate a permanent problem in establishing a connection to the other peer,
* this connection will be shutdown. In most cases this signal is emitted because we are waiting
* for a user decision which has not yet be given.
*/
void authTimeout();
void ready();
void failed();
void finished();

View File

@ -103,6 +103,39 @@ ConnectionManager::setWeakRef( QWeakPointer<ConnectionManager> weakRef )
d_func()->ownRef = weakRef;
}
void
ConnectionManager::authSuccessful()
{
Q_D( ConnectionManager );
// We have successfully connected to the other peer, we're done.
disconnect( d->controlConnection.data(), SIGNAL( authSuccessful() ), this, SLOT( authSuccessful() ) );
disconnect( d->controlConnection.data(), SIGNAL( authFailed() ), this , SLOT( authFailed() ) );
disconnect( d->controlConnection.data(), SIGNAL( authTimeout() ), this, SLOT( authFailed() ) );
d->currentPeerInfo.clear();
deactivate();
}
void
ConnectionManager::authFailed()
{
Q_D( ConnectionManager );
// We could not auth with the peer on the other side, maybe this is the wrong one?
disconnect( d->controlConnection.data(), SIGNAL( authSuccessful() ), this, SLOT( authSuccessful() ) );
disconnect( d->controlConnection.data(), SIGNAL( authFailed() ), this, SLOT( authFailed() ) );
disconnect( d->controlConnection.data(), SIGNAL( authTimeout() ), this, SLOT( authFailed() ) );
// If auth failed, we need to setup a new controlconnection as the old will be destroyed.
newControlConnection( d->currentPeerInfo );
// Try to connect with the next available SipInfo.
tryConnect();
}
void
ConnectionManager::handleSipInfoPrivate( const Tomahawk::peerinfo_ptr &peerInfo )
{
@ -142,6 +175,32 @@ ConnectionManager::handleSipInfoPrivate( const Tomahawk::peerinfo_ptr &peerInfo
deactivate();
}
void
ConnectionManager::newControlConnection( const Tomahawk::peerinfo_ptr& peerInfo )
{
Q_D( ConnectionManager );
QVariantMap m;
m["conntype"] = "accept-offer";
m["key"] = peerInfo->key();
m["nodeid"] = Tomahawk::Database::instance()->impl()->dbid();
d->controlConnection = QPointer<ControlConnection>( new ControlConnection( Servent::instance() ) );
d->controlConnection->setShutdownOnEmptyPeerInfos( false );
d->controlConnection->addPeerInfo( peerInfo );
d->controlConnection->setFirstMessage( m );
if ( peerInfo->id().length() )
d->controlConnection->setName( peerInfo->contactId() );
if ( peerInfo->nodeId().length() )
d->controlConnection->setId( peerInfo->nodeId() );
d->controlConnection->setNodeId( peerInfo->nodeId() );
Servent::instance()->registerControlConnection( d->controlConnection.data() );
}
void
ConnectionManager::connectToPeer( const Tomahawk::peerinfo_ptr &peerInfo, bool lock )
{
@ -234,24 +293,7 @@ ConnectionManager::connectToPeer( const Tomahawk::peerinfo_ptr &peerInfo, bool l
d_func()->sipCandidates.append( privateIPv6 );
}
QVariantMap m;
m["conntype"] = "accept-offer";
m["key"] = peerInfo->key();
m["nodeid"] = Tomahawk::Database::instance()->impl()->dbid();
d_func()->controlConnection = QPointer<ControlConnection>( new ControlConnection( Servent::instance() ) );
d_func()->controlConnection->setShutdownOnEmptyPeerInfos( false );
d_func()->controlConnection->addPeerInfo( peerInfo );
d_func()->controlConnection->setFirstMessage( m );
if ( peerInfo->id().length() )
d_func()->controlConnection->setName( peerInfo->contactId() );
if ( peerInfo->nodeId().length() )
d_func()->controlConnection->setId( peerInfo->nodeId() );
d_func()->controlConnection->setNodeId( peerInfo->nodeId() );
Servent::instance()->registerControlConnection( d_func()->controlConnection.data() );
newControlConnection( peerInfo );
tryConnect();
}
@ -357,15 +399,19 @@ ConnectionManager::deactivate()
void
ConnectionManager::socketConnected()
{
Q_D( ConnectionManager );
QTcpSocketExtra* sock = (QTcpSocketExtra*)sender();
peerInfoDebug( d_func()->currentPeerInfo ) << Q_FUNC_INFO << "Connected to hostaddr: " << sock->peerAddress() << ", hostname:" << sock->peerName();
peerInfoDebug( d->currentPeerInfo ) << Q_FUNC_INFO << "Connected to hostaddr: " << sock->peerAddress() << ", hostname:" << sock->peerName();
Q_ASSERT( !sock->_conn.isNull() );
handoverSocket( sock );
d_func()->currentPeerInfo.clear();
deactivate();
// Connect signal to wait for authentication result.
connect( d->controlConnection.data(), SIGNAL( authSuccessful() ), SLOT( authSuccessful() ) );
connect( d->controlConnection.data(), SIGNAL( authFailed()) , SLOT( authFailed() ) );
connect( d->controlConnection.data(), SIGNAL( authTimeout() ), SLOT( authFailed() ) );
}
void

View File

@ -60,6 +60,8 @@ public:
void setWeakRef( QWeakPointer< ConnectionManager > weakRef );
private slots:
void authSuccessful();
void authFailed();
void socketConnected();
void socketError( QAbstractSocket::SocketError error );
@ -74,6 +76,11 @@ private:
*/
ConnectionManager( const QString& nodeid );
/**
* Create a new ControlConnection for talking to a peer.
*/
void newControlConnection(const Tomahawk::peerinfo_ptr &peerInfo);
/**
* Proxy handleSipInfoPrivate to hand over a strong reference to the connectionManager
* so that the refcount is >0 while transferring the context of operation to another thread.