Exemple #1
0
        public static IPEndPoint GetMappedAddress(this StunAttribute attribute)
        {
            var variable = attribute.Variable;

            if (variable[0] != 0)
            {
                Debug.LogWarning($"MAPPED-ADDRESS first byte must be 0x00, got 0x{variable[0].ToString("X2")}");
            }

            var family      = (AddressFamily)variable[1];
            var port        = (ushort)((variable[2] << 8) | variable[3]);
            var addressSize = variable.Length - sizeof(ushort) * 2;

            if (family == AddressFamily.IPv4 && addressSize != 4)
            {
                Debug.LogWarning($"MAPPED-ADDRESS with family {family} needs to have 32 bits, got {addressSize * 8} bits");
            }
            else if (family == AddressFamily.IPv6 && addressSize != 16)
            {
                Debug.LogWarning($"MAPPED-ADDRESS with family {family} needs to have 128 bits, got {addressSize * 8} bits");
            }

            var addressBytes = new byte[addressSize];

            Array.Copy(variable, 4, addressBytes, 0, addressBytes.Length);
            var ipAddress = new IPAddress(addressBytes);

            return(new IPEndPoint(ipAddress, port));
        }
Exemple #2
0
        private async void Start()
        {
            var hosts = new string[] {
                "stun://localhost:3478",
                "stun://127.0.0.1:3478",

                // Google
                "stun://stun.l.google.com:19302",
                "stun://stun1.l.google.com:19302",
                "stun://stun2.l.google.com:19302",
                "stun://stun3.l.google.com:19302",
                "stun://stun4.l.google.com:19302",

                // Other
                "stun://stun.voip.blackberry.com:3478",
                "stun://stun.voipgate.com:3478",
                "stun://stun.voys.nl:3478",
                "stun://stun1.faktortel.com.au:3478",

                // TCP
                "stun://stun.sipnet.net:3478",
                "stun://stun.sipnet.ru:3478",
                "stun://stun.stunprotocol.org:3478",
            };

            var req = new StunMessage();

            var software = new StunAttribute(StunAttributeType.SOFTWARE, req);

            software.SetSoftware("Ice Cold Mirror");

            req.attributes.Add(software);

            var clientUdp = new StunClientUdp();
            var clientTcp = new StunClientTcp();

            await Task.WhenAll(hosts.Select(async(host) => {
                try {
                    var res = await clientUdp.SendRequest(req, host).AwaitWithTimeout(1500);
                    Debug.Log("UDP: " + res);
                    var indication = res.attributes.First(a => a.Type == StunAttributeType.XOR_MAPPED_ADDRESS).GetXorMappedAddress();
                    Debug.LogWarning($"UDP: {host} STUN indication is {indication}");
                } catch (Exception e) {
                    Debug.LogException(new Exception($"UDP: STUN host \"{host}\" failed", e));
                }
            }).ToArray());

            await Task.WhenAll(hosts.Select(async(host) => {
                try {
                    var res = await clientTcp.SendRequest(req, host).AwaitWithTimeout(1500);
                    Debug.Log("TCP: " + res);
                    var indication = res.attributes.First(a => a.Type == StunAttributeType.XOR_MAPPED_ADDRESS).GetXorMappedAddress();
                    Debug.LogWarning($"TCP: {host} STUN indication is {indication}");
                } catch (Exception e) {
                    Debug.LogException(new Exception($"TCP: STUN host \"{host}\" failed", e));
                }
            }).ToArray());
        }
Exemple #3
0
        public static IPEndPoint GetXorMappedAddress(this StunAttribute attribute)
        {
            var variable = attribute.Variable;

            if (variable[0] != 0)
            {
                Debug.LogWarning($"XOR-MAPPED-ADDRESS first byte must be 0x00, got 0x{variable[0].ToString("X2")}");
            }

            var family = (AddressFamily)variable[1];
            var xPort  = (ushort)((variable[2] << 8) | variable[3]);
            // xor port with 16 most significant bit of magic cookie
            var port = (ushort)(xPort ^ ((magicCookieBytes[0] << 8) | magicCookieBytes[1]));

            var addressSize = variable.Length - sizeof(ushort) * 2;

            if (family == AddressFamily.IPv4 && addressSize != 4)
            {
                Debug.LogWarning($"XOR-MAPPED-ADDRESS with family {family} needs to have 32 bits, got {addressSize * 8} bits");
            }
            else if (family == AddressFamily.IPv6 && addressSize != 16)
            {
                Debug.LogWarning($"XOR-MAPPED-ADDRESS with family {family} needs to have 128 bits, got {addressSize * 8} bits");
            }

            var addressBytes = new byte[addressSize];

            Array.Copy(variable, 4, addressBytes, 0, addressBytes.Length);

            // xor each address byte with the magic cookie byte
            for (int i = 0; i < 4; i++)
            {
                addressBytes[i] ^= magicCookieBytes[i];
            }

            if (family == AddressFamily.IPv6)
            {
                var header = attribute.Owner.header;
                // getting the transaction id generates GC, only call when ipv6
                var transactionID = header.TransactionId;

                // xor each byte with the concatenation of magic cookie and transaction id
                for (int i = 0; i < transactionID.Length; i++)
                {
                    addressBytes[i + 4] ^= transactionID[i];
                }
            }

            var ipAddress = new IPAddress(addressBytes);

            return(new IPEndPoint(ipAddress, port));
        }
Exemple #4
0
        public StunMessage(Stream stream)
        {
            this.header = new StunMessageHeader(stream);

            var pos = 0;

            while (pos < header.Length)
            {
                var attr = new StunAttribute(stream, this);
                pos += attr.AttrbiuteLength;
                this.attributes.Add(attr);
            }
        }
Exemple #5
0
        public static void SetSoftware(this StunAttribute attribute, string info)
        {
            if (info.Length >= 128)
            {
                throw new ArgumentException("String must be less than 128 characteres", nameof(info));
            }

            var bytes = Encoding.UTF8.GetBytes(info);

            if (bytes.Length >= 763)
            {
                throw new ArgumentException("String must be less than 763 bytes", nameof(info));
            }

            attribute.Variable = bytes;
        }
Exemple #6
0
 public static void SetMappedAddress(this StunAttribute attribute, IPEndPoint endPoint)
 {
     throw new NotImplementedException();
 }
Exemple #7
0
 public static string GetSoftware(this StunAttribute attribute)
 {
     return(Encoding.UTF8.GetString(attribute.Variable));
 }