Esempio n. 1
0
        public MemoryWriter(PieceWriter writer, int capacity)
        {
            Check.Writer(writer);

            if (capacity < 0)
                throw new ArgumentOutOfRangeException("capacity");

            cachedBlocks = new List<CachedBlock>();
            this.Capacity = capacity;
            this.writer = writer;
        }
Esempio n. 2
0
        public MemoryWriter(PieceWriter writer, int capacity)
        {
            if (writer == null)
                throw new ArgumentNullException("writer");

            if (capacity < 0)
                throw new ArgumentOutOfRangeException("capacity");

            memoryBuffer = new List<BufferedIO>();
            this.capacity = capacity;
            this.writer = writer;
        }
 public EngineTestRig(string savePath, int piecelength, PieceWriter writer)
 {
     if (writer == null)
         writer = new MemoryWriter(new NullWriter());
     Listener = new CustomListener();
     Engine = new ClientEngine(new EngineSettings(), Listener, writer);
     TorrentDict = CreateTorrent(piecelength);
     Torrent = Torrent.Load(TorrentDict);
     Manager = new TorrentManager(Torrent, savePath, new TorrentSettings());
     Engine.Register(Manager);
     //manager.Start();
 }
Esempio n. 4
0
        internal DiskManager(ClientEngine engine, PieceWriter writer)
        {
            this.bufferedReads = new Queue<BufferedIO>();
            this.bufferedWrites = new Queue<BufferedIO>();
            this.cache = new Cache<BufferedIO>(true).Synchronize ();
            this.engine = engine;
            this.readLimiter = new RateLimiter();
            this.readMonitor = new SpeedMonitor();
            this.writeMonitor = new SpeedMonitor();
            this.writeLimiter = new RateLimiter();
            this.writer = writer;

            LoopTask = delegate {
                if (disposed)
                    return;

                while (this.bufferedWrites.Count > 0 && writeLimiter.TryProcess(bufferedWrites.Peek ().buffer.Length / 2048))
                {
                    BufferedIO write;
                    lock (bufferLock)
                        write = this.bufferedWrites.Dequeue();
                    try
                    {
                        PerformWrite(write);
                        cache.Enqueue (write);
                    }
                    catch (Exception ex)
                    {
                        if (write.Manager != null)
                            SetError(write.Manager, Reason.WriteFailure, ex);
                    }
                }

                while (this.bufferedReads.Count > 0 && readLimiter.TryProcess(bufferedReads.Peek().Count / 2048))
                {
                    BufferedIO read;
                    lock(bufferLock)
                        read = this.bufferedReads.Dequeue();

                    try
                    {
                        PerformRead(read);
                        cache.Enqueue (read);
                    }
                    catch (Exception ex)
                    {
                        if(read.Manager != null)
                            SetError(read.Manager, Reason.ReadFailure, ex);
                    }
                }
            };

            IOLoop.QueueTimeout(TimeSpan.FromSeconds(1), delegate {
                if (disposed)
                    return false;

                readMonitor.Tick();
                writeMonitor.Tick();
                LoopTask();
                return true;
            });
        }
		///<summary>
		///used for creating multi file mode torrents.
		///</summary>
		///<returns>the dictionary representing which is stored in the torrent file</returns>
		protected void CreateMultiFileTorrent(BEncodedDictionary dictionary, TorrentFile[] files, PieceWriter writer, string name)
		{
			AddCommonStuff(dictionary);
			var info = (BEncodedDictionary)dictionary["info"];

			var torrentFiles = new BEncodedList(); //the dict which hold the file infos

			for (var i = 0; i < files.Length; i++) torrentFiles.Add(GetFileInfoDict(files[i]));

			info.Add("files", torrentFiles);

			Logger.Log(null, "Topmost directory: {0}", name);
			info.Add("name", new BEncodedString(name));

			info.Add("pieces", new BEncodedString(CalcPiecesHash(Path, files, writer)));
		}
		internal BEncodedDictionary Create(TorrentFile[] files, PieceWriter writer, string name)
		{
			// Clone the base dictionary and fill the remaining data into the clone
			var torrentDict = BEncodedDictionary.Decode<BEncodedDictionary>(dict.Encode());
			Array.Sort<TorrentFile>(files, delegate(TorrentFile a, TorrentFile b) { return String.CompareOrdinal(a.Path, b.Path); });

			if (Directory.Exists(Path))
			{
				Logger.Log(null, "Creating multifile torrent from: {0}", Path);
				CreateMultiFileTorrent(torrentDict, files, writer, name);
			}
			else
			{
				Logger.Log(null, "Creating singlefile torrent from: {0}", Path);
				CreateSingleFileTorrent(torrentDict, files, writer, name);
			}

			return torrentDict;
		}
 private void CreateSingleFileTorrent(BEncodedDictionary dictionary, List<TorrentFile> mappings,
     PieceWriter writer,
     string name)
 {
     var infoDict = (BEncodedDictionary) dictionary["info"];
     infoDict.Add("length", new BEncodedNumber(mappings[0].Length));
     if (mappings[0].MD5 != null)
         infoDict["md5sum"] = (BEncodedString) mappings[0].MD5;
 }
        private byte[] CalcPiecesHash(List<TorrentFile> files, PieceWriter writer)
        {
            byte[] buffer = null;
            var bufferRead = 0;
            long fileRead = 0;
            long overallRead = 0;
            long overallTotal = 0;
            MD5 md5Hasher = null;
            SHA1 shaHasher = null;
            List<byte> torrentHashes = null;

            shaHasher = HashAlgoFactory.Create<SHA1>();
            torrentHashes = new List<byte>();
            overallTotal = Toolbox.Accumulate(files, delegate(TorrentFile m) { return m.Length; });

            var pieceLength = PieceLength;
            buffer = new byte[pieceLength];

            if (StoreMD5)
                md5Hasher = HashAlgoFactory.Create<MD5>();

            try
            {
                foreach (var file in files)
                {
                    fileRead = 0;
                    if (md5Hasher != null)
                        md5Hasher.Initialize();

                    while (fileRead < file.Length)
                    {
                        var toRead = (int) Math.Min(buffer.Length - bufferRead, file.Length - fileRead);
                        var read = writer.Read(file, fileRead, buffer, bufferRead, toRead);

                        if (md5Hasher != null)
                            md5Hasher.TransformBlock(buffer, bufferRead, read, buffer, bufferRead);
                        shaHasher.TransformBlock(buffer, bufferRead, read, buffer, bufferRead);

                        bufferRead += read;
                        fileRead += read;
                        overallRead += read;

                        if (bufferRead == buffer.Length)
                        {
                            bufferRead = 0;
                            shaHasher.TransformFinalBlock(buffer, 0, 0);
                            torrentHashes.AddRange(shaHasher.Hash);
                            shaHasher.Initialize();
                        }
                        RaiseHashed(new TorrentCreatorEventArgs(file.Path, fileRead, file.Length, overallRead,
                            overallTotal));
                    }
                    if (md5Hasher != null)
                    {
                        md5Hasher.TransformFinalBlock(buffer, 0, 0);
                        md5Hasher.Initialize();
                        file.MD5 = md5Hasher.Hash;
                    }
                }
                if (bufferRead > 0)
                {
                    shaHasher.TransformFinalBlock(buffer, 0, 0);
                    torrentHashes.AddRange(shaHasher.Hash);
                }
            }
            finally
            {
                if (shaHasher != null)
                    shaHasher.Clear();
                if (md5Hasher != null)
                    md5Hasher.Clear();
            }
            return torrentHashes.ToArray();
        }
Esempio n. 9
0
 public TestRig(string savePath, PieceWriter writer, string[][] tier)
     : this(savePath, 256 * 1024, writer, false, tier)
 {
 }
Esempio n. 10
0
 public TestRig(string savePath, PieceWriter writer)
     : this(savePath, 256 * 1024, writer, false, null)
 {
 }
Esempio n. 11
0
 public MemoryWriter(PieceWriter writer)
     : this(writer, 2 * 1024 * 1024)
 {
 }
Esempio n. 12
0
        public EngineTestRig(string savePath, PieceWriter writer)
            : this(savePath, 256 * 1024, writer)
        {

        }
Esempio n. 13
0
 void CreateMultiFileTorrent (BEncodedDictionary dictionary, List<TorrentFile> mappings, PieceWriter writer, string name)
 {
     BEncodedDictionary info = (BEncodedDictionary) dictionary ["info"];
     List<BEncodedValue> files = mappings.Select(ToFileInfoDict).ToList();
     info.Add ("files", new BEncodedList (files));
 }
Esempio n. 14
0
        public ClientEngine(EngineSettings settings, PieceWriter writer)
            : this(settings, new SocketListener(new IPEndPoint(IPAddress.Any, 0)), writer)

        {

        }
Esempio n. 15
0
 public TestRig(string savePath, PieceWriter writer, bool singleFile, string[][] tier)
     : this(savePath, 256 * 1024, writer, singleFile, tier)
 {
 }
Esempio n. 16
0
        public ClientEngine(EngineSettings settings, PeerListener listener, PieceWriter writer)
        {
            Check.Settings(settings);
            Check.Listener(listener);
            Check.Writer(writer);

            this.listener = listener;
            this.settings = settings;

            this.connectionManager = new ConnectionManager(this);
            RegisterDht (new NullDhtEngine());
            this.diskManager = new DiskManager(this, writer);
            this.listenManager = new ListenManager(this);
            MainLoop.QueueTimeout(TimeSpan.FromMilliseconds(TickLength), delegate {
                if (IsRunning && !disposed)
                    LogicTick();
                return !disposed;
            });
            this.torrents = new MonoTorrentCollection<TorrentManager>();
            CreateRateLimiters();
            this.peerId = GeneratePeerId();

            localPeerListener = new LocalPeerListener(this);
            localPeerManager = new LocalPeerManager();
            LocalPeerSearchEnabled = SupportsLocalPeerDiscovery;
            listenManager.Register(listener);
            // This means we created the listener in the constructor
            if (listener.Endpoint.Port == 0)
                listener.ChangeEndpoint(new IPEndPoint(IPAddress.Any, settings.ListenPort));
        }
Esempio n. 17
0
 public TestRig(string savePath, int piecelength, PieceWriter writer)
     : this(savePath, piecelength, writer, false, null)
 {
 }
 private void CreateMultiFileTorrent(BEncodedDictionary dictionary, List<TorrentFile> mappings,
     PieceWriter writer,
     string name)
 {
     var info = (BEncodedDictionary) dictionary["info"];
     var files = mappings.ConvertAll(ToFileInfoDict);
     info.Add("files", new BEncodedList(files));
 }
Esempio n. 19
0
 public TestRig(string savePath, int piecelength, PieceWriter writer, string[][] tier)
     : this(savePath, piecelength, writer, false, tier)
 {
 }
		internal BEncodedDictionary Create(PieceWriter writer)
		{
			if (!Directory.Exists(Path) && !File.Exists(Path)) throw new ArgumentException("no such file or directory", Path);

			var files = new List<TorrentFile>();
			LoadFiles(Path, files);

			if (files.Count == 0) throw new TorrentException("There were no files in the specified directory");

			var parts = path.Split(new char[] { System.IO.Path.DirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries);
			var name = File.Exists(Path) ? System.IO.Path.GetFileName(path) : parts[parts.Length - 1];
			return Create(files.ToArray(), writer, name);
		}
Esempio n. 21
0
        public TestRig(string savePath, int piecelength, PieceWriter writer, bool singleFile, string[][] tier)
        {
            this.savePath = savePath;
            this.piecelength = piecelength;
            this.singleFile = singleFile;
            this.tier = tier;

            if (writer == null)
                writer = new TestWriter();
            listener = new CustomListener();
            engine = new ClientEngine(new EngineSettings(), listener, writer);
            RecreateManager();
        }
		///<summary>
		///calculates all hashes over the files which should be included in the torrent
		///</summmary>
		byte[] CalcPiecesHash(string path, TorrentFile[] files, PieceWriter writer)
		{
			var piecesBuffer = new byte[GetPieceCount(files)*20]; //holds all the pieces hashes
			var piecesBufferOffset = 0;

			var totalLength = Toolbox.Accumulate<TorrentFile>(files, delegate(TorrentFile f) { return f.Length; });
			var buffer = new ArraySegment<byte>(new byte[PieceLength]);

			while (totalLength > 0)
			{
				var bytesToRead = (int)Math.Min(totalLength, PieceLength);
				var io = new BufferedIO(null, buffer, (piecesBufferOffset/20)*PieceLength, bytesToRead, bytesToRead, files, path);
				totalLength -= writer.ReadChunk(io);

				// If we are using the synchronous version, result is null
				if (result != null && result.Aborted) return piecesBuffer;

				var currentHash = hasher.ComputeHash(buffer.Array, 0, io.ActualCount);
				RaiseHashed(new TorrentCreatorEventArgs(0,
				                                        0,
				                                        //reader.CurrentFile.Position, reader.CurrentFile.Length,
				                                        piecesBufferOffset*PieceLength,
				                                        (piecesBuffer.Length - 20)*PieceLength));
				Buffer.BlockCopy(currentHash, 0, piecesBuffer, piecesBufferOffset, currentHash.Length);
				piecesBufferOffset += currentHash.Length;
			}
			return piecesBuffer;
		}
Esempio n. 23
0
 public MemoryWriter(PieceWriter writer)
     : this(writer, 2 * 1024 * 1024)
 {
 }
		///<summary>
		///used for creating a single file torrent file
		///<summary>
		///<returns>the dictionary representing which is stored in the torrent file</returns>
		protected void CreateSingleFileTorrent(BEncodedDictionary dictionary, TorrentFile[] files, PieceWriter writer, string name)
		{
			AddCommonStuff(dictionary);

			var infoDict = (BEncodedDictionary)dictionary["info"];
			infoDict.Add("length", new BEncodedNumber(files[0].Length));
			infoDict.Add("name", (BEncodedString)name);

			if (StoreMD5) AddMD5(infoDict, Path);

			Logger.Log(null, "name == {0}", name);
			var path = System.IO.Path.GetDirectoryName(Path);
			infoDict.Add("pieces", new BEncodedString(CalcPiecesHash(path, files, writer)));
		}
Esempio n. 25
0
        public ClientEngine(EngineSettings settings, PeerListener listener, PieceWriter writer)
        {
            Check.Settings(settings);
            Check.Listener(listener);
            Check.Writer(writer);

            this.listener = listener;
            this.settings = settings;

            this.connectionManager = new ConnectionManager(this);
            this.dhtListener = new UdpListener(new IPEndPoint(IPAddress.Any, settings.ListenPort));
            this.dhtEngine = new DhtEngine(dhtListener);
            this.diskManager = new DiskManager(this, writer);
            this.listenManager = new ListenManager(this);
            MainLoop.QueueTimeout(TimeSpan.FromMilliseconds(TickLength), delegate {
                if (IsRunning && !disposed)
                    LogicTick();
                return !disposed;
            });
            this.torrents = new MonoTorrentCollection<TorrentManager>();
            this.downloadLimiter = new RateLimiter();
            this.uploadLimiter = new RateLimiter();
            this.peerId = GeneratePeerId();

            listenManager.Register(listener);

            dhtEngine.StateChanged += delegate {
                if (dhtEngine.State != State.Ready)
                    return;
                MainLoop.Queue(delegate {
                    foreach (TorrentManager manager in torrents)
                    {
                        if (!manager.CanUseDht)
                            continue;

                        dhtEngine.Announce(manager.Torrent.infoHash, Listener.Endpoint.Port);
                        dhtEngine.GetPeers(manager.Torrent.infoHash);
                    }
                });
            };
            // This means we created the listener in the constructor
            if (listener.Endpoint.Port == 0)
                listener.ChangeEndpoint(new IPEndPoint(IPAddress.Any, settings.ListenPort));

            listener.Start();
        }