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); }
private void OnRecvAnnouncePeerResponse(DHTNode remoteNode) { // id only #if DEBUG_DHT_INTERNALS fLogger.WriteDebug("Peer announced successfully to {0}", remoteNode.EndPoint); #endif }
private void OnRecvCustomResponse(DHTNode remoteNode, BDictionary data) { if (ResponseReceived != null) { ResponseReceived(this, new MessageEventArgs(remoteNode.EndPoint, remoteNode.Id, data)); } }
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); }
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 })); } } }
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)); }
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()); }
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()); }
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); }
private void UpdateRoutingTable(DHTNode node) { if (fRoutingTable.UpdateNode(node)) { fLastNodesUpdateTime = DateTime.UtcNow.Ticks; fPeersHolder.SaveNode(node); } }
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); }
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); } }
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); }
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; } }
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)); } }
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); }
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); }
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); }
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); }
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)); }
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); }
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); }
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); }
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); }
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)); }
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); }
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); }