Esempio n. 1
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;
            }
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
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");

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