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; } }
public static DHTMessage ParseBuffer(byte[] buffer) { if (buffer == null || buffer.Length == 0 || buffer[0] != 'd') { return(null); } var data = fParser.Parse <BDictionary>(buffer); var bsY = data.Get <BString>("y"); if (bsY == null) { return(null); } string strMsgType = bsY.ToString(); MessageType msgType = DHTMessage.GetMessageType(strMsgType); DHTMessage result; switch (msgType) { case MessageType.Response: result = new DHTResponseMessage(msgType, QueryType.None, data); break; case MessageType.Query: result = new DHTQueryMessage(msgType, QueryType.None, data); break; case MessageType.Error: result = new DHTErrorMessage(msgType, QueryType.None, data); break; default: result = new DHTMessage(msgType, QueryType.None, data); break; } result.Parse(); return(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"); BString id = null; BString tokStr = null; BList valuesList = null; BString nodesStr = null; if (returnValues != null) { id = returnValues.Get <BString>("id"); tokStr = returnValues.Get <BString>("token"); valuesList = returnValues.Get <BList>("values"); nodesStr = returnValues.Get <BString>("nodes"); } if (id == null || id.Length == 0) { // response is invalid return; } fRoutingTable.UpdateNode(new DHTNode(id.Value, ipinfo)); // according to bep_????, most types of response contain a list of nodes ProcessNodesStr(ipinfo, nodesStr); // define type of response by transactionId of query/response QueryType queryType = CheckTransaction(tid); bool canAnnounce = false; switch (queryType) { case QueryType.Ping: RaisePeerPinged(ipinfo, id.Value); break; case QueryType.FindNode: break; case QueryType.GetPeers: if (tokStr != null && tokStr.Length != 0) { if (!ProcessValuesStr(ipinfo, valuesList)) { canAnnounce = true; } } break; case QueryType.AnnouncePeer: break; case QueryType.None: // TransactionId bad or unknown RaiseResponseReceived(ipinfo, id.Value, data); break; } if (canAnnounce) { SendAnnouncePeerQuery(ipinfo, fSearchInfoHash, 1, fPublicEndPoint.Port, tokStr); } }