예제 #1
0
        public void FillFromMetadata()
        {
            try
            {
                if (metadata.file == null)
                {
                    bitSwarm.StopWithError("No metadata found");
                }

                string curFilePath = Path.Combine(metadata.file.Options.Folder, metadata.file.Filename);
                string curPath     = (new FileInfo(curFilePath)).DirectoryName;

                metadata.file.Dispose();
                BDictionary bInfo = (BDictionary)bParser.Parse(curFilePath);

                if (file.infoHash != Utils.ArrayToStringHex(sha1.ComputeHash(bInfo.EncodeAsBytes())))
                {
                    bitSwarm.StopWithError("[CRITICAL] Metadata SHA1 validation failed");
                }

                file.name = ((BString)bInfo["name"]).ToString();

                string torrentName = Utils.GetValidFileName(file.name) + ".torrent";

                if (!File.Exists(Path.Combine(curPath, torrentName)))
                {
                    File.Move(curFilePath, Path.Combine(bitSwarm.OptionsClone.FolderTorrents, torrentName));
                }

                FillFromInfo(bInfo);
            } catch (Exception e) { bitSwarm.StopWithError($"FillFromMetadata(): {e.Message} - {e.StackTrace}"); }
        }
예제 #2
0
        private void PrepareRequest()
        {
            /* BEndode get_peers Request
             *
             * "t" -> <transId>,
             * "y" -> "q",
             * "q" -> "get_peers",
             * "a" -> { "id" -> <nodeId> , "info_hash" -> <infoHashBytes> }
             *
             */
            byte[] transId = new byte[2]; rnd.NextBytes(transId);
            byte[] nodeId  = new byte[20]; rnd.NextBytes(nodeId);

            BDictionary bRequest = new BDictionary();

            bRequest.Add("t", new BString(transId));
            bRequest.Add("y", "q");
            bRequest.Add("q", "get_peers");

            BDictionary bDicA = new BDictionary();

            bDicA.Add("id", new BString(nodeId));
            bDicA.Add("info_hash", new BString(infoHashBytes));
            bRequest.Add("a", bDicA);

            getPeersBytes = bRequest.EncodeAsBytes();
        }
예제 #3
0
        private void BtnSaveResumeData_Click(object sender, EventArgs e)
        {
            if (utBDictionary == null)
            {
                MessageBox.Show("请先加载 resume.data 文件!");
                return;
            }

            SaveFileDialog dlg = new SaveFileDialog();

            dlg.InitialDirectory = DefaultDirectory;
            dlg.RestoreDirectory = true;
            dlg.Filter           = "dat文件|*.dat";

            if (dlg.ShowDialog() == DialogResult.OK)
            {
                using (FileStream fs = new FileStream(
                           dlg.FileName, FileMode.Create))
                {
                    byte[] bytes = utBDictionary.EncodeAsBytes();
                    fs.Write(bytes, 0, bytes.Length);
                    fs.Flush();

                    MessageBox.Show(string.Format("已保存为 {0}", dlg.FileName));
                }
            }
        }
        public static DHTId CreateSignInfoKey()
        {
            BDictionary subnetKey = new BDictionary();

            subnetKey.Add("info", ProtocolHelper.NETWORK_SIGN);

            lock (sha1) {
                return(new DHTId(sha1.ComputeHash(subnetKey.EncodeAsBytes())));
            }
        }
예제 #5
0
        public void Send(IPEndPoint address, BDictionary data, bool async = true)
        {
            try {
                // according to bep_0005
                data.Add("v", fClientVer);

                byte[] dataArray = data.EncodeAsBytes();
                Send(address, dataArray, async);
            } catch (Exception ex) {
                fLogger.WriteError("Send()", ex);
            }
        }
예제 #6
0
        public async Task GetPeersInfo(GetPeersInfoInput input)
        {
            // 如果 BT 客户端没有传递 IP,则通过 Context 获得。
            if (string.IsNullOrEmpty(input.Ip))
            {
                input.Ip = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString();
            }

            // 本机测试用。
            input.Ip = "127.0.0.1";

            AnnounceInputParameters inputPara = input;
            var resultDict = new BDictionary();

            // 如果产生了错误,则不执行其他操作,直接返回结果。
            if (inputPara.Error.Count == 0)
            {
                _bitTorrentManager.UpdatePeer(input.Info_Hash, inputPara);
                _bitTorrentManager.ClearZombiePeers(input.Info_Hash, TimeSpan.FromMinutes(10));
                var peers = _bitTorrentManager.GetPeers(input.Info_Hash);

                HandlePeersData(resultDict, peers, inputPara);

                // 构建剩余字段信息
                // 客户端等待时间
                resultDict.Add(TrackerServerConsts.IntervalKey, new BNumber((int)TimeSpan.FromSeconds(30).TotalSeconds));
                // 最小等待间隔
                resultDict.Add(TrackerServerConsts.MinIntervalKey, new BNumber((int)TimeSpan.FromSeconds(30).TotalSeconds));
                // Tracker 服务器的 Id
                resultDict.Add(TrackerServerConsts.TrackerIdKey, new BString("Tracker-DEMO"));
                // 已完成的 Peer 数量
                resultDict.Add(TrackerServerConsts.CompleteKey, new BNumber(_bitTorrentManager.GetComplete(input.Info_Hash)));
                // 非做种状态的 Peer 数量
                resultDict.Add(TrackerServerConsts.IncompleteKey, new BNumber(_bitTorrentManager.GetInComplete(input.Info_Hash)));
            }
            else
            {
                resultDict = inputPara.Error;
            }

            // 写入响应结果。
            var resultDictBytes = resultDict.EncodeAsBytes();
            var response        = _httpContextAccessor.HttpContext.Response;

            response.ContentType   = "text/plain";
            response.StatusCode    = 200;
            response.ContentLength = resultDictBytes.Length;
            await response.Body.WriteAsync(resultDictBytes);
        }
예제 #7
0
        private void SendExtShakeHand()
        {
            BDictionary supose = new BDictionary();

            supose.Add("ut_metadata", new BNumber(1));
            BDictionary dic = new BDictionary();

            dic.Add("m", supose);
            var datalist = new List <byte>();

            datalist.Add(0x14);
            datalist.Add(0x00);
            datalist.AddRange(dic.EncodeAsBytes());
            datalist.InsertRange(0, BitConverter.GetBytes((UInt32)datalist.Count).Reverse());
            this.sock.Send(datalist.ToArray());
        }
예제 #8
0
        public void Send(IPEndPoint address, BDictionary data)
        {
            try {
                // according to bep_0005
                data.Add("v", fClientVer);

                byte[] dataArray = data.EncodeAsBytes();
                fSocket.BeginSendTo(dataArray, 0, dataArray.Length, SocketFlags.None, address, (ar) => {
                    try {
                        fSocket.EndReceive(ar);
                    } catch (Exception ex) {
                        fLogger.WriteError("Send.1(" + address.ToString() + "): ", ex);
                    }
                }, null);
            } catch (Exception ex) {
                fLogger.WriteError("Send(): ", ex);
            }
        }
예제 #9
0
 private bool check()
 {
     if (this.state == 0)
     {
         if (this.DataBuffer[0] != 0x13)
         {
             throw new Exception();
         }
         var str1 = Encoding.ASCII.GetString(this.DataBuffer.ToArray(), 1, 19);
         if (str1 != "BitTorrent protocol")
         {
             throw new Exception();
         }
         var reserved = this.DataBuffer.Skip(20).Take(8).ToArray();
         var infoHash = this.DataBuffer.Skip(28).Take(20).ToArray();
         if (infoHash != this.InfoHash)
         {
             throw new Exception();
         }
         var peer_id = this.DataBuffer.ToArray().Skip(48).Take(20);
         this.state = 1;
         SendExtShakeHand();
         this.DataBuffer.RemoveRange(0, 68);
         return(true);
     }
     else if (this.state == 1)
     {
         var lengthArray = this.DataBuffer.Take(4);
         var len         = BitConverter.ToUInt32(lengthArray.Reverse().ToArray(), 0);
         if (this.DataBuffer.Count >= (4 + len))
         {
             var dataBuf = this.DataBuffer.Skip(4).Take((int)len).ToArray();
             var msgid   = dataBuf[0];
             if (msgid != 0x08)
             {
                 throw new Exception();
             }
             var extendMsgID = dataBuf[1];
             if (extendMsgID != 0x00)
             {
                 throw new Exception();
             }
             BencodeParser parse  = new BencodeParser();
             var           supose = parse.Parse <BDictionary>(dataBuf.Skip(2).ToArray());
             if (!supose.ContainsKey("m"))
             {
                 throw new Exception();
             }
             var suplist = supose.Get <BDictionary>("m");
             if (!suplist.ContainsKey("ut_metadata"))
             {
                 throw new Exception();
             }
             var numid = suplist.Get <BNumber>("ut_metadata");
             var size  = supose.Get <BNumber>("metadata_size");
             var count = size / (16 * 1024) + (size % (16 * 1024) > 0 ? 1 : 0);
             for (int i = 0; i < count; i++)
             {
                 BDictionary data = new BDictionary();
                 data.Add("msg_type", 0);
                 data.Add("prece", i);
                 var data2 = new List <byte>();
                 data2.Add(0x14);
                 data2.Add((byte)numid.Value);
                 data2.AddRange(data.EncodeAsBytes());
                 data2.AddRange(BitConverter.GetBytes((UInt32)data2.Count).Reverse());
                 this.sock.Send(data2.ToArray());
             }
             this.state = 2;
             return(true);
         }
         else if (this.state == 2)
         {
         }
     }
     return(false);
 }
예제 #10
0
        private void Send(BDictionary data, IPEndPoint address)
        {
            var dataarrar = data.EncodeAsBytes();

            this.sock.BeginSendTo(dataarrar, 0, dataarrar.Length, SocketFlags.None, address, (x) => { this.sock.EndReceive(x); }, null);
        }
예제 #11
0
 private void OnRecvMessage(byte[] data, IPEndPoint ipinfo)
 {
     try
     {
         var dic = parser.Parse <BDictionary>(data);
         if (dic.Get <BString>("y") == "r")
         {
             var respNode = dic.Get <BDictionary>("r");
             var nodeList = respNode.Get <BString>("nodes");
             if (nodeList == null || nodeList.Length == 0)
             {
                 //Console.WriteLine("ping response " + ipinfo.ToString());
                 return;
             }
             if (nodeList.Value.Count % 26 != 0)
             {
                 throw new Exception("sd");
             }
             var tt   = nodeList.Value.ToArray();
             var ssss = ParseList(tt);
             foreach (var t in ssss)
             {
                 lock (this.nodes)
                 {
                     this.nodes.Enqueue(t);
                     //Console.WriteLine("find a node " + t.Item2);
                 }
             }
             return;
         }
         if (dic.Get <BString>("y") == "q" && dic.Get <BString>("q") == "ping")
         {
             //Console.WriteLine("ping");
             BDictionary resultDic = new BDictionary();
             resultDic.Add("t", dic.Get <BString>("t"));
             resultDic.Add("y", "r");
             var r = new BDictionary();
             r.Add("id", new BString(this.localID));
             resultDic.Add("r", r);
             var dataresult = resultDic.EncodeAsBytes();
             this.sock.BeginSendTo(dataresult, 0, dataresult.Length, SocketFlags.None, ipinfo, (ar) => { this.sock.EndSendTo(ar); }, null);
             return;
         }
         //if(dic.Get<BString>("y") == "q" && dic.Get<BString>("q") == "find_node")
         //{
         //
         //}
         if (dic.Get <BString>("y") == "q" && dic.Get <BString>("q") == "get_peers")
         {
             var t         = dic.Get <BString>("t");
             var a         = dic.Get <BDictionary>("a");
             var rid       = a.Get <BString>("id");
             var info_hash = a.Get <BString>("info_hash");
             var result    = new BDictionary();
             result.Add("t", t);
             result.Add("y", "r");
             var r        = new BDictionary();
             var neighbor = new List <byte>();
             neighbor.AddRange(info_hash.Value.Take(10));
             neighbor.AddRange(this.localID.Skip(10).Take(10));
             r.Add("id", new BString(neighbor));
             r.Add("token", new BString(info_hash.Value.Take(2)));
             r.Add("nodes", "");
             result.Add("r", r);
             var dataresult = result.EncodeAsBytes();
             this.sock.BeginSendTo(dataresult, 0, dataresult.Length, SocketFlags.None, ipinfo, (ar) => { this.sock.EndSendTo(ar); }, null);
             WriteInfo("get_peers", info_hash.Value.ToArray(), rid.Value.ToArray(), null);
             Console.WriteLine(info_hash.Value.ToArray().ToHexString() + "|" + ipinfo.ToString());
             return;
             //this.InfoHashList.Add(info_hash.Value.ToArray());
         }
         if (dic.Get <BString>("y") == "q" && dic.Get <BString>("q") == "announce_peer")
         {
             var id        = dic.Get <BString>("id");
             var a         = dic.Get <BDictionary>("a");
             var info_hash = a.Get <BString>("info_hash");
             int port      = 0;
             if (a.ContainsKey("implied_port") && a.Get <BNumber>("implied_port") == 1)
             {
                 port = ipinfo.Port;
             }
             else
             {
                 port = a.Get <BNumber>("port");
             }
             //CanDownload.Add(new Tuple<byte[], IPEndPoint>(info_hash.Value.ToArray(), new IPEndPoint(ipinfo.Address, port)));
             Console.WriteLine("find a hash_info_candownload!!-------------------------------------");
             WriteInfo("announce_peer", info_hash.Value.ToArray(), id.Value.ToArray(), new IPEndPoint(ipinfo.Address, port));
             return;
         }
         //Console.WriteLine("unknow pack");
         //Console.WriteLine(dic.Keys.ToString());
     }
     catch (Exception ex)
     {
         Console.WriteLine(ex);
     }
 }
예제 #12
0
        public static void SendMessage(BDictionary message, TcpClient client)
        {
            var bytes = message.EncodeAsBytes();

            client.GetStream().Write(bytes, 0, bytes.Length);
        }
예제 #13
0
        private void SendData(IPEndPoint endPoint, BDictionary data)
        {
            fDHTClient.Send(endPoint, data);

            fTCPClient.Send(endPoint, data.EncodeAsBytes());
        }