Esempio n. 1
0
        private async Task ProcessResponseAsync(DhtMessage msg, DhtNode responseNode)
        {
            _kTable.AddOrUpdateNode(responseNode);
            object         nodeInfo;
            ISet <DhtNode> nodes = null;

            switch (msg.CommandType)
            {
            case CommandType.Find_Node:
                if (_kTable.IsFull || !msg.Data.TryGetValue("nodes", out nodeInfo))
                {
                    return;
                }
                nodes = DhtNode.ParseNode((byte[])nodeInfo);
                break;

            case CommandType.Get_Peers:
                var hashByte = msg.Get <byte[]>("info_hash");
                var infoHash = new InfoHash(hashByte);
                if (msg.Data.TryGetValue("values", out nodeInfo))
                {
                    IList <object> peerInfo;
                    if (nodeInfo is byte[] bytes)
                    {
                        peerInfo = new object[] { bytes };
                    }
                    else
                    {
                        peerInfo = (IList <object>)nodeInfo;
                    }
                    var peers = new HashSet <IPEndPoint>(peerInfo.Count);
                    foreach (var t in peerInfo)
                    {
                        var peer  = (byte[])t;
                        var point = DhtNode.ParsePeer(peer, 0);
                        if (point.Address.IsPublic())
                        {
                            peers.Add(point);
                        }
                    }
                    if (peers.Count > 0)
                    {
                        infoHash.Peers = peers;
                        if (OnFindPeer != null)
                        {
                            await OnFindPeer(infoHash);
                        }
                        return;
                    }
                }
                if (msg.Data.TryGetValue("nodes", out nodeInfo))
                {
                    if (!(nodeInfo is byte[]))
                    {
                        return;
                    }
                    nodes = DhtNode.ParseNode((byte[])nodeInfo);
                    foreach (var node in nodes)
                    {
                        _kTable.AddNode(node);
                        GetPeers(node, infoHash.Bytes);
                    }
                }
                break;
            }
            if (nodes != null)
            {
                foreach (var node in nodes)
                {
                    _nodeQueue.TryAdd(node);
                    _kTable.AddNode(node);
                }
            }
        }
Esempio n. 2
0
        private async Task ProcessRequestAsync(DhtMessage msg, IPEndPoint remotePoint)
        {
            var response = new DhtMessage
            {
                MessageId  = msg.MessageId,
                MesageType = MessageType.Response
            };
            var requestNode = new DhtNode()
            {
                NodeId = (byte[])msg.Data["id"], Host = remotePoint.Address, Port = (ushort)remotePoint.Port
            };

            _kTable.AddOrUpdateNode(requestNode);
            response.Data.Add("id", GetNeighborNodeId(requestNode.NodeId));
            switch (msg.CommandType)
            {
            case CommandType.Find_Node:
                var targetNodeId = (byte[])msg.Data["target"];
                response.Data.Add("nodes", _kTable.FindNodes(targetNodeId).SelectMany(n => n.CompactNode()).ToArray());
                break;

            case CommandType.Get_Peers:
            case CommandType.Announce_Peer:
                var infoHash = new InfoHash((byte[])msg.Data["info_hash"]);
                if (OnReceiveInfoHash != null)
                {
                    await OnReceiveInfoHash(infoHash);
                }
                if (msg.CommandType == CommandType.Get_Peers)
                {
                    var nodes = _kTable.FindNodes(infoHash.Bytes);
                    response.Data.Add("nodes", nodes.SelectMany(n => n.CompactNode()).ToArray());
                    response.Data.Add("token", infoHash.Value.Substring(0, 2));
                    if (!infoHash.IsDown)
                    {
                        foreach (var node in nodes)
                        {
                            GetPeers(node, infoHash.Bytes);
                        }
                    }
                }
                else if (!infoHash.IsDown)
                {
                    if (!msg.Data.Keys.Contains("implied_port") || 0.Equals(msg.Data["implied_port"]))    //implied_port !=0 则端口使用port
                    {
                        remotePoint.Port = Convert.ToInt32(msg.Data["port"]);
                    }
                    infoHash.Peers = new HashSet <IPEndPoint>(1)
                    {
                        remotePoint
                    };
                    if (OnAnnouncePeer != null)
                    {
                        await OnAnnouncePeer(infoHash);
                    }
                }
                break;

            case CommandType.Ping:
                break;

            default:
                return;
            }
            _replyMessageQueue.TryAdd(new Tuple <DhtMessage, DhtNode>(response, new DhtNode(remotePoint)));
        }