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); } } }
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))); }