Exemple #1
0
        async Task <P2PSettings> MatchingRequest(string url, StunResult ret, CancellationToken token)
        {
            var json    = $"{{\"endpoint\":\"{ret.EndPoint}\",\"local_endpoint\":\"{ret.LocalEndPoint}\", \"nattype\": \"{ret.NatType}\"}}";
            var content = new StringContent(json);

            using (var client = new HttpClient())
            {
                var response = await client.PostAsync(url, content, token);

                if (response.StatusCode == HttpStatusCode.OK)
                {
                    json = await response.Content.ReadAsStringAsync();

                    var res = Json.From <Response>(json);
                    return(new P2PSettings
                    {
                        SelfId = res.id,
                        Peers = res.peers.Select(x => x.Create()).ToArray()
                    });
                }
                else if (response.StatusCode == HttpStatusCode.RequestTimeout)
                {
                    throw new Exception("Matching Timeout");
                }
            }
            throw new Exception("Matching fail");
        }
Exemple #2
0
        /// <summary>
        /// Processes a received stun message.
        /// </summary>
        /// <returns>Stun result</returns>
        /// <param name="inputData">Input raw stun message</param>
        public static StunResult ProcessStun(byte[] inputData, int inputDataLength)
        {
            StunResult retVal = new StunResult();

            if (inputDataLength < 20)
            {
                return(retVal);
            }
            byte[] messageShortBytes = new byte[2];
            Array.Copy(inputData, 0, messageShortBytes, 0, 2);
            UdpMeshCommon.FlipEndian(ref messageShortBytes);
            int messageTypeCombined = BitConverter.ToInt16(messageShortBytes, 0);

            Array.Copy(inputData, 2, messageShortBytes, 0, 2);
            UdpMeshCommon.FlipEndian(ref messageShortBytes);
            int messageLength = BitConverter.ToInt16(messageShortBytes, 0);

            byte[] messageGuidBytes = new byte[16];
            Array.Copy(inputData, 4, messageGuidBytes, 0, 16);
            retVal.messageGuid = new Guid(messageGuidBytes);
            int bytesToRead = messageLength;

            while (bytesToRead > 0)
            {
                if (bytesToRead < 4)
                {
                    return(retVal);
                }
                Array.Copy(inputData, inputData.Length - bytesToRead, messageShortBytes, 0, 2);
                UdpMeshCommon.FlipEndian(ref messageShortBytes);
                int attrType = BitConverter.ToUInt16(messageShortBytes, 0);
                bytesToRead -= 2;
                Array.Copy(inputData, inputData.Length - bytesToRead, messageShortBytes, 0, 2);
                UdpMeshCommon.FlipEndian(ref messageShortBytes);
                int attrLength = BitConverter.ToUInt16(messageShortBytes, 0);
                bytesToRead -= 2;
                if (attrLength > 0)
                {
                    byte[] attrBytes = new byte[attrLength];
                    Array.Copy(inputData, inputData.Length - bytesToRead, attrBytes, 0, attrLength);
                    bytesToRead -= attrLength;
                    if (attrType == 1 && attrBytes[1] == 1 && attrLength == 8)
                    {
                        Array.Copy(attrBytes, 2, messageShortBytes, 0, 2);
                        UdpMeshCommon.FlipEndian(ref messageShortBytes);
                        retVal.port = BitConverter.ToUInt16(messageShortBytes, 0);
                        byte[] ipBytes = new byte[4];
                        Array.Copy(attrBytes, 4, ipBytes, 0, 4);
                        retVal.remoteAddr = new IPAddress(ipBytes);
                        retVal.success    = true;
                    }
                    if (attrType == 1 && attrBytes[1] == 2 && attrLength == 20)
                    {
                        Array.Copy(attrBytes, 2, messageShortBytes, 0, 2);
                        UdpMeshCommon.FlipEndian(ref messageShortBytes);
                        retVal.port = BitConverter.ToUInt16(messageShortBytes, 0);
                        byte[] ipBytes = new byte[16];
                        Array.Copy(attrBytes, 4, ipBytes, 0, 16);
                        retVal.remoteAddr = new IPAddress(ipBytes);
                        retVal.success    = true;
                    }
                    if (attrType == 32 && attrBytes[1] == 1 && attrLength == 8)
                    {
                        Array.Copy(attrBytes, 2, messageShortBytes, 0, 2);
                        //Xor with magic cookie
                        XorBytes(messageShortBytes, messageGuidBytes);
                        UdpMeshCommon.FlipEndian(ref messageShortBytes);
                        retVal.port = BitConverter.ToUInt16(messageShortBytes, 0);
                        byte[] ipBytes = new byte[4];
                        Array.Copy(attrBytes, 4, ipBytes, 0, 4);
                        //Xor with magic cookie
                        XorBytes(ipBytes, messageGuidBytes);
                        retVal.remoteAddr = new IPAddress(ipBytes);
                        retVal.success    = true;
                    }
                    if (attrType == 32 && attrBytes[1] == 2 && attrLength == 20)
                    {
                        Array.Copy(attrBytes, 2, messageShortBytes, 0, 2);
                        //Xor with magic cookie
                        XorBytes(messageShortBytes, messageGuidBytes);
                        UdpMeshCommon.FlipEndian(ref messageShortBytes);
                        retVal.port = BitConverter.ToUInt16(messageShortBytes, 0);
                        byte[] ipBytes = new byte[16];
                        Array.Copy(attrBytes, 4, ipBytes, 0, 16);
                        //Xor with magic cookie
                        XorBytes(ipBytes, messageGuidBytes);
                        retVal.remoteAddr = new IPAddress(ipBytes);
                        retVal.success    = true;
                    }
                }
            }
            if (callback != null)
            {
                callback(retVal);
            }
            return(retVal);
        }