Bug 261449 - Loaded quantities with webseeds do not match
Summary: Loaded quantities with webseeds do not match
Status: RESOLVED FIXED
Alias: None
Product: ktorrent
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: openSUSE Linux
: NOR normal
Target Milestone: ---
Assignee: Joris Guisson
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-12-28 14:04 UTC by Axel Braun
Modified: 2010-12-29 12:19 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments
webseed view (146.03 KB, image/png)
2010-12-28 14:04 UTC, Axel Braun
Details
File status (148.93 KB, image/png)
2010-12-28 14:05 UTC, Axel Braun
Details
1.6 GB loaded on a 1.1 GB file, and still only 9% complete (154.07 KB, image/png)
2010-12-28 16:04 UTC, Axel Braun
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Axel Braun 2010-12-28 14:04:19 UTC
Created attachment 55314 [details]
webseed view

Version:           unspecified (using KDE 4.4.4) 
OS:                Linux

I have currently some downloads running that use webseeds as well as torrents: The webseed claims that it has already loaded some 500 MB, while the main torrent window claims it has only loaded some 100 MB, which is approximately in line with the file status (see screenshots).
where hat the rest of the downloads gone.

Reproducible: Sometimes

Steps to Reproduce:
May this depend on the webseed?



OS: Linux (i686) release 2.6.34.7-0.5-desktop
Compiler: gcc
Comment 1 Axel Braun 2010-12-28 14:05:15 UTC
Created attachment 55315 [details]
File status
Comment 2 Joris Guisson 2010-12-28 14:10:41 UTC
Version ?
Comment 3 Axel Braun 2010-12-28 14:22:56 UTC
(In reply to comment #2)
> Version ?

ktorrent? 3.3.4
Comment 4 Axel Braun 2010-12-28 16:04:15 UTC
Created attachment 55318 [details]
1.6 GB loaded on a 1.1 GB file, and still only 9% complete

...think it does not make sense to continue with webseeds
Comment 5 Joris Guisson 2010-12-28 18:15:41 UTC
Send me the torrent
Comment 6 Joris Guisson 2010-12-29 11:29:50 UTC
Two things:
- There is a bug in the latest development code which results in the hash check always failing in this situation, this bug is not present in the version you are running, so this is not what you are seeing
- The webseed and the torrent do not match, after 99 MB they diverge, none of the data beyond 99 MB matches. The fact that you get stuck at 9 % is thus very logical.

So you need to stop using the webseed for this torrent, and I need to make it clear in the GUI that this is happening, instead of retrying continuously to download a chunk which is never gonna match.
Comment 7 Joris Guisson 2010-12-29 12:19:31 UTC
commit 6f64659c7b05cc0033b4827b37aa87a4e9f4d1da
branch master
Author: Joris <joris.guisson@gmail.com>
Date:   Wed Dec 29 12:17:26 2010 +0100

    Disable webseeds if they send data which does not match
    
    BUG: 261449

diff --git a/ChangeLog b/ChangeLog
index 7192502..78664c3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -26,6 +26,7 @@ Changes in 1.1:
 - Fix crash in PeerConnector cleanup (258878)
 - Queue data checks so that they run one after the other (215711)
 - Revamp UTP code with smart pointers
+- Disable webseeds if they send data which does not match (261449)
 
 Changes in 1.0.5:
 - Update PeerID client identifications
diff --git a/src/download/downloader.cpp b/src/download/downloader.cpp
index 78c89ac..8b55069 100644
--- a/src/download/downloader.cpp
+++ b/src/download/downloader.cpp
@@ -21,6 +21,7 @@
 
 #include <QFile>
 #include <QTextStream>
+#include <KLocale>
 #include <util/file.h>
 #include <util/log.h>
 #include <diskio/chunkmanager.h>
@@ -758,6 +759,7 @@ namespace bt
 	
 	void Downloader::onChunkReady(Chunk* c)
 	{
+		WebSeed* ws = webseeds_chunks.find(c->getIndex());
 		webseeds_chunks.erase(c->getIndex());
 		PieceData::Ptr piece = c->getPiece(0,c->getSize(),true);
 		if (piece && c->checkHash(tor.getHash(c->getIndex())))
@@ -805,6 +807,7 @@ namespace bt
 				cman.resetChunk(c->getIndex());
 			
 			chunk_selector->reinsert(c->getIndex());
+			ws->disable(i18n("Disabled because webseed does not match torrent"));
 		}
 	}
 	
diff --git a/src/download/webseed.cpp b/src/download/webseed.cpp
index 9a18291..b569ff1 100644
--- a/src/download/webseed.cpp
+++ b/src/download/webseed.cpp
@@ -103,6 +103,13 @@ namespace bt
 		reset();
 	}
 
+	void WebSeed::disable(const QString& reason)
+	{
+		setEnabled(false);
+		status = reason;
+		Out(SYS_CON|LOG_IMPORTANT) << "Auto disabled webseed " << url.prettyUrl() << endl;
+	}
+
 
 	bool WebSeed::busy() const
 	{
@@ -218,7 +225,6 @@ namespace bt
 		if (path.endsWith('/') && !isUserCreated())
 			path += tor.getNameSuggestion();
 		
-		//Out(SYS_GEN|LOG_DEBUG) << "WebSeed: continuing current chunk " << cur_chunk << " " << bytes_of_cur_chunk << endl;
 		first_chunk = cur_chunk;
 		if (tor.isMultiFile())
 		{
@@ -292,82 +298,88 @@ namespace bt
 		
 	Uint32 WebSeed::update()
 	{
-		if (!conn || !busy())
-			return 0;
-		
-		if (!conn->ok())
-		{
-			readData();
-			Out(SYS_CON|LOG_DEBUG) << "WebSeed: connection not OK" << endl;
-			// shit happened delete connection
-			status = conn->getStatusString();
-			if (conn->responseCode() == 404)
-			{
-				// if not found then retire this webseed for now
-				retryLater();
-			}
-			delete conn;
-			conn = 0;
-			chunkStopped();
-			first_chunk = last_chunk = cur_chunk = tor.getNumChunks() + 1;
-			num_failures++;
-			if (num_failures == 3)
-				retryLater();
-			return 0;
-		}
-		else if (conn->closed())
+		try
 		{
-			// Make sure we handle all data
-			readData();
+			if (!conn || !busy())
+				return 0;
 			
-			Out(SYS_CON|LOG_DEBUG) << "WebSeed: connection closed" << endl;
-			delete conn;
-			conn = 0;
-			
-			status = i18n("Connection closed");
-			chunkStopped();
-			if (last_chunk < tor.getNumChunks())
+			if (!conn->ok())
 			{
-				// lets try this again if we have not yet got the full range
-				download(cur_chunk,last_chunk);
+				readData();
+				
+				Out(SYS_CON|LOG_DEBUG) << "WebSeed: connection not OK" << endl;
+				// shit happened delete connection
 				status = conn->getStatusString();
-			}
-		}
-		else if (conn->isRedirected())
-		{
-			// Make sure we handle all data
-			readData();
-			redirected(conn->redirectedUrl());
-		}
-		else 
-		{
-			readData();
-			if (range_queue.count() > 0 && conn->ready())
-			{
-				if (conn->closed())
+				if (conn->responseCode() == 404)
 				{
-					// after a redirect it is possible that the connection is closed
-					// so we need to reconnect to the old url
-					conn->deleteLater();
-					conn = new HttpConnection();
-					conn->setGroupIDs(up_gid,down_gid);
-					connectToServer();
+					// if not found then retire this webseed for now
+					retryLater();
 				}
+				delete conn;
+				conn = 0;
+				chunkStopped();
+				first_chunk = last_chunk = cur_chunk = tor.getNumChunks() + 1;
+				num_failures++;
+				if (num_failures == 3)
+					retryLater();
+				return 0;
+			}
+			else if (conn->closed())
+			{
+				// Make sure we handle all data
+				readData();
 				
-				QString path = url.path();
-				if (path.endsWith('/'))
-					path += tor.getNameSuggestion();
+				Out(SYS_CON|LOG_DEBUG) << "WebSeed: connection closed" << endl;
+				delete conn;
+				conn = 0;
 				
-				// ask for the next range
-				Range r = range_queue[0];
-				range_queue.pop_front();
-				const TorrentFile & tf = tor.getFile(r.file);
-				QString host = redirected_url.isValid() ? redirected_url.host() : url.host();
-				conn->get(host,path + '/' + tf.getPath(),r.off,r.len);
+				status = i18n("Connection closed");
+				chunkStopped();
+				if (last_chunk < tor.getNumChunks())
+				{
+					// lets try this again if we have not yet got the full range
+					download(cur_chunk,last_chunk);
+					status = conn->getStatusString();
+				}
+			}
+			else if (conn->isRedirected())
+			{
+				// Make sure we handle all data
+				readData();
+				redirected(conn->redirectedUrl());
+			}
+			else 
+			{
+				readData();
+				if (range_queue.count() > 0 && conn->ready())
+				{
+					if (conn->closed())
+					{
+						// after a redirect it is possible that the connection is closed
+						// so we need to reconnect to the old url
+						conn->deleteLater();
+						conn = new HttpConnection();
+						conn->setGroupIDs(up_gid,down_gid);
+						connectToServer();
+					}
+					
+					QString path = url.path();
+					if (path.endsWith('/'))
+						path += tor.getNameSuggestion();
+					
+					// ask for the next range
+					Range r = range_queue[0];
+					range_queue.pop_front();
+					const TorrentFile & tf = tor.getFile(r.file);
+					QString host = redirected_url.isValid() ? redirected_url.host() : url.host();
+					conn->get(host,path + '/' + tf.getPath(),r.off,r.len);
+				}
+				status = conn->getStatusString();
 			}
-			status = conn->getStatusString();
 		}
-		
+		catch (AutoDisabled &)
+		{
+		}
 		Uint32 ret = downloaded;
 		downloaded = 0;
 		total_downloaded += ret;
@@ -397,7 +409,6 @@ namespace bt
 	
 	void WebSeed::handleData(const QByteArray & tmp)
 	{
-//		Out(SYS_GEN|LOG_DEBUG) << "Handling data: " << tmp.length() << " bytes" << endl;
 		Uint32 off = 0;
 		while (off < (Uint32)tmp.size() && cur_chunk <= last_chunk)
 		{
@@ -427,6 +438,9 @@ namespace bt
 				if (c->getStatus() != Chunk::ON_DISK)
 				{
 					chunkReady(c);
+					// It is possible that the webseed has been disabled due receiving a bad chunk
+					if (!isEnabled())
+						throw AutoDisabled();
 				}
 				
 				chunkStopped();
diff --git a/src/download/webseed.h b/src/download/webseed.h
index e0e9cc9..b4ae35a 100644
--- a/src/download/webseed.h
+++ b/src/download/webseed.h
@@ -119,6 +119,9 @@ namespace bt
 		
 		virtual void setEnabled(bool on);
 		
+		/// Disable the webseed 
+		void disable(const QString & reason);
+		
 		/// Get the number of failed attempts
 		Uint32 failedAttempts() const {return num_failures;}
 		
@@ -165,6 +168,8 @@ namespace bt
 			Uint64 len;
 		};
 		
+		class AutoDisabled {}; // Exception
+		
 		void fillRangeList(Uint32 chunk);
 		void handleData(const QByteArray & data);
 		void chunkStarted(Uint32 chunk);