From 70ac65398521dd23d4cd8e7c62af71e0493e42fa Mon Sep 17 00:00:00 2001
From: "Uwe L. Korn" <uwelk@xhochy.com>
Date: Sat, 6 Apr 2013 00:09:06 +0200
Subject: [PATCH] Fix multiple ip connection mechanism

---
 src/libtomahawk/network/QTcpSocketExtra.cpp |  2 +-
 src/libtomahawk/network/Servent.cpp         | 73 ++++++++++++---------
 src/libtomahawk/network/Servent.h           |  3 +-
 3 files changed, 44 insertions(+), 34 deletions(-)

diff --git a/src/libtomahawk/network/QTcpSocketExtra.cpp b/src/libtomahawk/network/QTcpSocketExtra.cpp
index 25aa087ee..c77e12517 100644
--- a/src/libtomahawk/network/QTcpSocketExtra.cpp
+++ b/src/libtomahawk/network/QTcpSocketExtra.cpp
@@ -57,7 +57,7 @@ QTcpSocketExtra::connectTimeout()
     if ( state() != ConnectedState )
     {
         // We did not manage to connect in the given timespan, so abort the attempt...
-        close();
+        abort();
         // .. and notify error handlers.
         emit error( SocketTimeoutError );
     }
diff --git a/src/libtomahawk/network/Servent.cpp b/src/libtomahawk/network/Servent.cpp
index 3a07329ff..ae8ad6987 100644
--- a/src/libtomahawk/network/Servent.cpp
+++ b/src/libtomahawk/network/Servent.cpp
@@ -54,6 +54,9 @@
 
 typedef QPair< QList< SipInfo >, Connection* > sipConnectionPair;
 Q_DECLARE_METATYPE( sipConnectionPair )
+Q_DECLARE_METATYPE( QList< SipInfo > )
+Q_DECLARE_METATYPE( Connection* )
+Q_DECLARE_METATYPE( QTcpSocketExtra* )
 
 using namespace Tomahawk;
 
@@ -735,6 +738,34 @@ void Servent::handoverSocket( Connection* conn, QTcpSocketExtra* sock )
     conn->start( sock );
 }
 
+void
+Servent::cleanupSocket( QTcpSocketExtra *sock )
+{
+    if ( !sock )
+    {
+        tLog() << "SocketError, sock is null";
+        return;
+    }
+
+    if ( !sock->_conn.isNull() )
+    {
+        Connection* conn = sock->_conn.data();
+
+        if ( !sock->_disowned )
+        {
+            // connection will delete if we already transferred ownership, otherwise:
+            sock->deleteLater();
+        }
+
+        conn->markAsFailed(); // will emit failed, then finished
+    }
+    else
+    {
+        tLog() << "SocketError, connection is null";
+        sock->deleteLater();
+    }
+}
+
 void
 Servent::connectToPeer( const peerinfo_ptr& peerInfo )
 {
@@ -871,8 +902,8 @@ Servent::connectToPeer(const QList<SipInfo>& sipInfoList, Connection* conn )
 
     connect( sock, SIGNAL( connected() ), SLOT( socketConnected() ) );
     NewClosure( sock, SIGNAL( error( QAbstractSocket::SocketError ) ),
-                this, SLOT( connectToPeerFailed( QAbstractSocket::SocketError, QPair<QList<SipInfo>, Connection*> ) ),
-                QPair<QList<SipInfo>, Connection*>(sipInfo, conn) );
+                this, SLOT( connectToPeerFailed( QList<SipInfo>, Connection*, QTcpSocketExtra* ) ),
+                sipInfo, conn, sock );
 
     if ( !conn->peerIpAddress().isNull() )
         sock->connectToHost( conn->peerIpAddress(), info.port(), QTcpSocket::ReadWrite );
@@ -882,55 +913,33 @@ Servent::connectToPeer(const QList<SipInfo>& sipInfoList, Connection* conn )
 }
 
 void
-Servent::connectToPeerFailed( QAbstractSocket::SocketError e, QPair<QList<SipInfo>, Connection*> pair )
+Servent::connectToPeerFailed( QList<SipInfo> sipInfo, Connection* conn, QTcpSocketExtra* socket )
 {
-    QList<SipInfo> sipInfo = pair.first;
-    Connection* conn = pair.second;
 
-    // Call default handler
-    socketError( e );
+    cleanupSocket( socket );
 
-    if ( e != QAbstractSocket::SocketResourceError )
+    if ( !socket )
     {
         // If we do not have run out of resource, try next SipInfo
         connectToPeer( sipInfo, conn );
     }
+    // Try next SipInfo
+    connectToPeer( sipInfo, conn );
 }
 
 void
 Servent::socketError( QAbstractSocket::SocketError e )
 {
     QTcpSocketExtra* sock = (QTcpSocketExtra*)sender();
-    if ( !sock )
-    {
-        tLog() << "SocketError, sock is null";
-        return;
-    }
-
     if ( !sock->_conn.isNull() )
     {
         Connection* conn = sock->_conn.data();
-        tLog() << "Servent::SocketError:" << e << conn->id() << conn->name();
-
-        if ( !sock->_disowned )
-        {
-            // connection will delete if we already transferred ownership, otherwise:
-            sock->deleteLater();
-        }
-
-        conn->markAsFailed(); // will emit failed, then finished
-    }
-    else
-    {
-        tLog() << "SocketError, connection is null";
-        sock->deleteLater();
+        tLog() << Q_FUNC_INFO << e << conn->id() << conn->name();
     }
+
+    cleanupSocket( sock );
 }
 
-
-
-
-
 void
 Servent::reverseOfferRequest( ControlConnection* orig_conn, const QString& theirdbid, const QString& key, const QString& theirkey )
 {
diff --git a/src/libtomahawk/network/Servent.h b/src/libtomahawk/network/Servent.h
index 44ac55cce..89ecc7f22 100644
--- a/src/libtomahawk/network/Servent.h
+++ b/src/libtomahawk/network/Servent.h
@@ -130,7 +130,7 @@ protected:
 public slots:
     void setExternalAddress( QHostAddress ha, unsigned int port );
 
-    void connectToPeerFailed( QAbstractSocket::SocketError e, QPair<QList<SipInfo>, Connection*> pair );
+    void connectToPeerFailed(QList<SipInfo> sipInfo, Connection* conn , QTcpSocketExtra *socket);
     void socketError( QAbstractSocket::SocketError e );
     void createParallelConnection( Connection* orig_conn, Connection* new_conn, const QString& key );
 
@@ -147,6 +147,7 @@ private slots:
 
 private:
     void handoverSocket( Connection* conn, QTcpSocketExtra* sock );
+    void cleanupSocket( QTcpSocketExtra* sock );
     void printCurrentTransfers();
 
     QJson::Parser parser;