Пример #1
0
        private bool ProcessValuesStr(DHTNode remoteNode, BList valuesList, BString token)
        {
            bool result = false;

            if (valuesList != null && valuesList.Count != 0)
            {
                var values = DHTNode.ParseValuesList(valuesList);

                if (values.Count > 0)
                {
#if DEBUG_DHT_INTERNALS
                    fLogger.WriteDebug("Receive {0} values (peers) from {1}", values.Count, remoteNode.EndPoint);
#endif

                    foreach (var peer in values)
                    {
                        fLogger.WriteDebug("Receive peer {0} from {1}", peer, remoteNode.EndPoint);

                        if (peer.Address.Equals(PublicEndPoint.Address))
                        {
                            result = true;
                        }
                    }

                    if (PeersFound != null)
                    {
                        PeersFound(this, new PeersFoundEventArgs(values));
                    }
                }
            }
            return(result);
        }
Пример #2
0
        private void OnRecvAnnouncePeerResponse(DHTNode remoteNode)
        {
            // id only
#if DEBUG_DHT_INTERNALS
            fLogger.WriteDebug("Peer announced successfully to {0}", remoteNode.EndPoint);
#endif
        }
Пример #3
0
 private void OnRecvCustomResponse(DHTNode remoteNode, BDictionary data)
 {
     if (ResponseReceived != null)
     {
         ResponseReceived(this, new MessageEventArgs(remoteNode.EndPoint, remoteNode.Id, data));
     }
 }
Пример #4
0
        internal void SendAnnouncePeerQuery(DHTNode remoteNode, DHTId infoHash, byte implied_port, int port, BString token)
        {
            if (remoteNode == null || token == null || token.Length == 0)
            {
                return;
            }

            long nowTicks = DateTime.UtcNow.Ticks;

            if (nowTicks - remoteNode.LastAnnouncementTime < AnnounceLife.Ticks)
            {
                return;
            }
            remoteNode.LastAnnouncementTime = nowTicks;

#if DEBUG_DHT_INTERNALS
            fLogger.WriteDebug("Send announce peer query {0}, {1}, {2}", remoteNode.EndPoint, implied_port, port);
#endif

            // https://www.bittorrent.org/beps/bep_0005.html
            // If implied_port (0/1) is present and non-zero, the port argument should be ignored
            // and the source port of the UDP packet should be used as the peer's port instead.

            var transactionID = DHTTransactions.GetNextId();
            var msg           = DHTMessage.CreateAnnouncePeerQuery(transactionID, fLocalID, infoHash, implied_port, port, token);
            fTransactions.SetQuery(transactionID, msg);
            Send(remoteNode.EndPoint, msg);
        }
Пример #5
0
        private void OnRecvAnnouncePeerQuery(IPEndPoint ipinfo, BDictionary data)
        {
            var t    = data.Get <BString>("t");
            var args = data.Get <BDictionary>("a");

            var id          = args.Get <BString>("id");
            var infoHash    = new DHTId(args.Get <BString>("info_hash"));
            var impliedPort = args.Get <BNumber>("implied_port");
            int port        = (impliedPort != null && impliedPort.Value == 1) ? ipinfo.Port : (int)args.Get <BNumber>("port").Value;

            var remoteNode = new DHTNode(id.Value, ipinfo);

            UpdateRoutingTable(remoteNode);

#if DEBUG_DHT_INTERNALS
            fLogger.WriteDebug("Receive `announce_peer` query from {0} for {1}", remoteNode.ToString(), infoHash.ToString());
#endif

            // skip response for another infohash query
            if (infoHash == fSearchInfoHash)
            {
                // receive `announce_peer` query for our infohash
                var nodesList = fRoutingTable.GetClosest(infoHash.Data);
                Send(ipinfo, DHTMessage.CreateAnnouncePeerResponse(t, fLocalID, nodesList));

                if (PeersFound != null)
                {
                    PeersFound(this, new PeersFoundEventArgs(new List <IPEndPoint>()
                    {
                        ipinfo
                    }));
                }
            }
        }
Пример #6
0
        public static DHTMessage CreateGetPeersResponse(
            BString transactionID, DHTId nodeId, DHTId infoHash,
            IList <IDHTPeer> peersList, IList <DHTNode> nodesList)
        {
            BList values = DHTNode.CompactPeers(peersList);
            var   nodes  = new BString(DHTNode.CompactNodes(nodesList));

            BDictionary sendData = new BDictionary();

            sendData.Add("t", transactionID);
            sendData.Add("y", "r");

            var r = new BDictionary();

            r.Add("id", nodeId.ToBencodedString());
            r.Add("token", new BString(infoHash.Data.SubArray(0, 2)));
            if (values != null)
            {
                r.Add("values", values);
            }
            r.Add("nodes", nodes);
            sendData.Add("r", r);

            return(new DHTMessage(MessageType.Response, QueryType.None, sendData));
        }
Пример #7
0
        public void Test_GetNeighbor()
        {
            var bytes1 = new byte[] { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 };
            var bytes2 = new byte[] { 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77 };
            var result = DHTNode.GetNeighbor(bytes1, bytes2);

            Assert.AreEqual("1111111111111111111177777777777777777777", result.ToString());
        }
Пример #8
0
        public void Test_ToString()
        {
            var endPoint = new IPEndPoint(IPAddress.Any, 0);
            var randId   = DHTHelper.GetRandomID();
            var node     = new DHTNode(randId, endPoint);

            Assert.IsNotNullOrEmpty(node.ToString());
        }
Пример #9
0
        public void Test_ctor()
        {
            var endPoint = new IPEndPoint(IPAddress.Any, 0);
            var node     = new DHTNode(endPoint);

            Assert.IsNotNull(node);
            Assert.IsNull(node.ID);
            Assert.AreEqual(endPoint, node.EndPoint);
        }
Пример #10
0
        private void UpdateRoutingTable(DHTNode node)
        {
            if (fRoutingTable.UpdateNode(node))
            {
                fLastNodesUpdateTime = DateTime.UtcNow.Ticks;

                fPeersHolder.SaveNode(node);
            }
        }
Пример #11
0
        public void Test_UpdateNode()
        {
            var table = new DHTRoutingTable(10);

            table.UpdateNode(null);

            var node = new DHTNode(DHTHelper.GetRandomID(), new IPEndPoint(IPAddress.Any, 0));

            table.UpdateNode(node);
        }
Пример #12
0
        private void OnRecvGetPeersResponse(DHTNode remoteNode, BString nodesStr, BList valuesList, BString token)
        {
            // according to bep_0005, get_peers response can contain a list of nodes
            ProcessNodesStr(remoteNode, nodesStr);

            if (!ProcessValuesStr(remoteNode, valuesList, token))
            {
                SendAnnouncePeerQuery(remoteNode, fSearchInfoHash, 0, PublicEndPoint.Port, token);
            }
        }
Пример #13
0
        internal void SendFindNodeQuery(IPEndPoint address, DHTId target, bool neighbor = true)
        {
            var   transactionID = DHTTransactions.GetNextId();
            DHTId targetId      = (target == null) ? fLocalID : ((neighbor) ? DHTNode.GetNeighbor(target.Data, fLocalID.Data) : target);

            var msg = DHTMessage.CreateFindNodeQuery(transactionID, fLocalID, targetId);

            fTransactions.SetQuery(transactionID, msg);
            Send(address, msg);
        }
        public void Test_UpdateNode_DDoS_Protection()
        {
            var table = new DHTRoutingTable(10);

            // do not use nodes with ports below 1024
            var node   = new DHTNode(DHTId.CreateRandom(), new IPEndPoint(IPAddress.Any, 111));
            var result = table.UpdateNode(node);

            Assert.IsFalse(result);
        }
Пример #15
0
        private void OnRecvResponseX(IPEndPoint ipinfo, DHTResponseMessage msg)
        {
            if (msg == null)
            {
                return;
            }

            BDictionary data = msg.Data;

            var tid = data.Get <BString>("t");

            var returnValues = data.Get <BDictionary>("r");

            if (returnValues == null)
            {
                // response is invalid
                return;
            }

            BString id         = returnValues.Get <BString>("id");
            BString tokStr     = returnValues.Get <BString>("token");
            BList   valuesList = returnValues.Get <BList>("values");
            BString nodesStr   = returnValues.Get <BString>("nodes");

            var remoteNode = new DHTNode(id.Value, ipinfo);

            UpdateRoutingTable(remoteNode);

            // define type of response by transactionId of query/response
            QueryType queryType = fTransactions.CheckQuery(tid);

            switch (queryType)
            {
            case QueryType.Ping:
                OnRecvPingResponse(remoteNode);
                break;

            case QueryType.FindNode:
                OnRecvFindNodeResponse(remoteNode, nodesStr);
                break;

            case QueryType.GetPeers:
                OnRecvGetPeersResponse(remoteNode, nodesStr, valuesList, tokStr);
                break;

            case QueryType.AnnouncePeer:
                OnRecvAnnouncePeerResponse(remoteNode);
                break;

            case QueryType.None:
                // TransactionId bad or unknown
                OnRecvCustomResponse(remoteNode, data);
                break;
            }
        }
Пример #16
0
        private void OnRecvPingResponse(DHTNode remoteNode)
        {
            // id only
#if DEBUG_DHT_INTERNALS
            fLogger.WriteDebug("Peer pinged: {0}", remoteNode.EndPoint);
#endif

            if (PeerPinged != null)
            {
                PeerPinged(this, new PeerPingedEventArgs(remoteNode.EndPoint, remoteNode.Id));
            }
        }
Пример #17
0
        public void Test_ctor2()
        {
            var endPoint = new IPEndPoint(IPAddress.Any, 0);
            var randId   = DHTHelper.GetRandomID();
            var node     = new DHTNode(randId, endPoint);

            Assert.IsNotNull(node);
            Assert.AreEqual(randId, node.ID);
            Assert.AreEqual(endPoint, node.EndPoint);

            Assert.AreEqual(0, node.LastAnnouncementTime);
            Assert.AreEqual(0, node.LastUpdateTime);
        }
Пример #18
0
        public static byte[] CompactNode(DHTNode node)
        {
            IPAddress address = node.EndPoint.Address;
            ushort    port    = (ushort)node.EndPoint.Port;

            var info = new byte[26];

            Buffer.BlockCopy(node.Id.Data, 0, info, 0, 20);
            Buffer.BlockCopy(address.GetAddressBytes(), 0, info, 20, 4);
            info[24] = (byte)((port >> 8) & 0xFF);
            info[25] = (byte)(port & 0xFF);
            return(info);
        }
Пример #19
0
        public void Test_DHTNode()
        {
            var endPoint = new IPEndPoint(IPAddress.Any, 0);
            var randId   = DHTId.CreateRandom();
            var node     = new DHTNode(randId, endPoint);

            Assert.IsNotNull(node);
            Assert.AreEqual(randId.Data, node.Id.Data);
            Assert.AreEqual(endPoint, node.EndPoint);
            Assert.IsNotNullOrEmpty(node.ToString());

            Assert.AreEqual(0, node.LastAnnouncementTime);
            Assert.AreEqual(0, node.LastUpdateTime);
        }
Пример #20
0
        private void ProcessNodesStr(DHTNode remoteNode, BString nodesStr)
        {
            var nodesList = DHTNode.ParseNodesList(nodesStr);

            if (nodesList != null && nodesList.Count > 0)
            {
#if DEBUG_DHT_INTERNALS
                fLogger.WriteDebug("Receive {0} nodes from {1}", nodesList.Count, remoteNode.EndPoint);
#endif

                foreach (var node in nodesList)
                {
                    UpdateRoutingTable(node);
                }
            }
        }
        public void Test_FindNodes()
        {
            var table = new DHTRoutingTable(10);

            var randId = DHTId.CreateRandom();
            var nodes  = table.GetClosest(randId.Data);

            Assert.IsNotNull(nodes);
            Assert.AreEqual(0, nodes.Count);

            var node = new DHTNode(randId, new IPEndPoint(IPAddress.Any, 6881));

            table.UpdateNode(node);
            nodes = table.GetClosest(randId.Data);
            Assert.IsNotNull(nodes);
            Assert.AreEqual(1, nodes.Count);
        }
Пример #22
0
        public static DHTMessage CreateAnnouncePeerResponse(BString transactionID, DHTId nodeId, IList <DHTNode> nodesList)
        {
            var nodes = new BString(DHTNode.CompactNodes(nodesList));

            BDictionary sendData = new BDictionary();

            sendData.Add("y", "r");
            sendData.Add("t", transactionID);

            var r = new BDictionary();

            r.Add("id", nodeId.ToBencodedString());
            r.Add("nodes", nodes);
            sendData.Add("r", r);

            return(new DHTMessage(MessageType.Response, QueryType.None, sendData));
        }
Пример #23
0
        public void Test_FindNodes()
        {
            var table = new DHTRoutingTable(10);

            var randId = DHTHelper.GetRandomID();
            var nodes  = table.FindNodes(randId);

            Assert.IsNotNull(nodes);
            Assert.AreEqual(0, nodes.Count);

            var node = new DHTNode(randId, new IPEndPoint(IPAddress.Any, 0));

            table.UpdateNode(node);
            nodes = table.FindNodes(randId);
            Assert.IsNotNull(nodes);
            Assert.AreEqual(1, nodes.Count);
        }
Пример #24
0
        public void Test_FindNode()
        {
            var table = new DHTRoutingTable(10);

            var randId       = DHTHelper.GetRandomID();
            var nodeEndPoint = new IPEndPoint(IPAddress.Any, 0);
            var node         = new DHTNode(randId, nodeEndPoint);

            table.UpdateNode(node);

            var node2 = table.FindNode(nodeEndPoint);

            Assert.IsNotNull(node2);

            node2 = table.FindNode(null);
            Assert.IsNull(node2);
        }
Пример #25
0
        private void OnRecvPingQuery(IPEndPoint ipinfo, BDictionary data)
        {
            var t    = data.Get <BString>("t");
            var args = data.Get <BDictionary>("a");

            var id = args.Get <BString>("id");

            var remoteNode = new DHTNode(id.Value, ipinfo);

            UpdateRoutingTable(remoteNode);

#if DEBUG_DHT_INTERNALS
            fLogger.WriteDebug("Receive `ping` query from {0}", remoteNode.ToString());
#endif

            Send(ipinfo, DHTMessage.CreatePingResponse(t, fLocalID));
        }
        public bool UpdateNode(DHTNode node)
        {
            if (node == null || node.Id == null)
            {
                return(false);
            }

            // protection against participation in botnet attacks
            if (node.EndPoint.Port <= 1024)
            {
                return(false);
            }

            if (IsFull)
            {
                ClearExpireNode();
            }

            if (IsFull)
            {
                return(false);
            }

            DHTNode existNode;

            if (fKTable.TryGetValue(node.EndPoint, out existNode))
            {
                if (node.Id == existNode.Id)
                {
                    node = existNode;
                }
                else
                {
                    // replace to new
                    fKTable[node.EndPoint] = node;
                }
            }
            else
            {
                fKTable.Add(node.EndPoint, node);
            }

            node.Update();

            return(true);
        }
Пример #27
0
        public static List <DHTNode> ParseNodesListIP6(byte[] data)
        {
            var result = new List <DHTNode>();

            for (int i = 0; i < data.Length; i += 38)
            {
                var dd = data.Skip(i).Take(38).ToArray();

                var b = dd[36];
                dd[36] = dd[37];
                dd[37] = b;
                var id   = dd.Take(20).ToArray();
                var ip   = new IPAddress(dd.Skip(20).Take(16).ToArray());
                var port = BitConverter.ToUInt16(dd, 36);
                var tt   = new DHTNode(id, new IPEndPoint(PrepareAddress(ip), port));
                result.Add(tt);
            }
            return(result);
        }
Пример #28
0
        private void OnRecvFindNodeQuery(IPEndPoint ipinfo, BDictionary data)
        {
            var t    = data.Get <BString>("t");
            var args = data.Get <BDictionary>("a");

            var id     = args.Get <BString>("id");
            var target = args.Get <BString>("target");

            var remoteNode = new DHTNode(id.Value, ipinfo);

            UpdateRoutingTable(remoteNode);

#if DEBUG_DHT_INTERNALS
            fLogger.WriteDebug("Receive `find_node` query from {0}", remoteNode.ToString());
#endif

            var nodesList = fRoutingTable.GetClosest(target.Value);
            Send(ipinfo, DHTMessage.CreateFindNodeResponse(t, fLocalID, nodesList));
        }
Пример #29
0
        private static List <DHTNode> ParseNodesListIP6(byte[] data)
        {
            var result = new List <DHTNode>();

            for (int i = 0; i < data.Length; i += 38)
            {
                var dd = data.SubArray(i, 38);

                var b = dd[36];
                dd[36] = dd[37];
                dd[37] = b;
                var id   = dd.SubArray(0, 20);
                var ip   = new IPAddress(dd.SubArray(20, 16));
                var port = BitConverter.ToUInt16(dd, 36);
                var tt   = new DHTNode(id, new IPEndPoint(Utilities.PrepareAddress(ip), port));
                result.Add(tt);
            }
            return(result);
        }
Пример #30
0
        public static List <DHTNode> ParseNodesListIP4(byte[] data)
        {
            var result = new List <DHTNode>();

            for (int i = 0; i < data.Length; i += 26)
            {
                var dd = data.Skip(i).Take(26).ToArray();
                //var bc = dd.ToHexString();
                //Console.WriteLine(bc);
                var b = dd[24];
                dd[24] = dd[25];
                dd[25] = b;
                var id   = dd.Take(20).ToArray();
                var ip   = new IPAddress(dd.Skip(20).Take(4).ToArray());
                var port = BitConverter.ToUInt16(dd, 24);
                var tt   = new DHTNode(id, new IPEndPoint(PrepareAddress(ip), port));
                result.Add(tt);
            }
            return(result);
        }