Пример #1
0
        // NAT METHODS
        private static IceCandidate GatherNAActiveCandidate(IPAddress localIPAddress, IceCandidate baseCandidate)
        {
            // exactly the same procedure like GatherSRActiveCandidate()
            // derived from passive NAT assisted candidate

            IPEndPoint localEndpoint = new IPEndPoint(localIPAddress, 0);

            Socket activeConnectingSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            // here is no bind, because active candidates don't have to be physically allocated here (allocation in connectivity checks)

            /*  RFC 6544 (ICE TCP), Section 3:
            In the case of active candidates, both IP
            address and port are present, but the port is meaningless (it is
            there only for making encoding of active candidates consistent with
            the other candidate types and is ignored by the peer).  As a
            consequence, active candidates do not need to be physically allocated
            at the time of address gathering.  Rather, the physical allocations,
            which occur as a consequence of a connection attempt, occur at the
            time of the connectivity checks.
             */

            // create candidate object
            IpAddressPort activeIpAddressPort = new IpAddressPort(AddressType.IPv4_Address, baseCandidate.addr_port.ipaddr, 0);         // port is meaningless
            IceCandidate activeCandidate = new IceCandidate(activeIpAddressPort, Overlay_Link.TLS_TCP_with_FH);
            activeCandidate.cand_type = CandType.tcp_nat;
            activeCandidate.rel_addr_port = new IpAddressPort(AddressType.IPv4_Address, localEndpoint.Address, 0);                      // port is meaningless
            activeCandidate.activeConnectingSocket = activeConnectingSocket;

            // TCP Type
            activeCandidate.tcpType = TcpType.Active;

            // TCP ICE extension
            IceExtension iceExtension = new IceExtension();
            iceExtension.name = Encoding.UTF8.GetBytes("tcptype");
            iceExtension.value = Encoding.UTF8.GetBytes("active");
            activeCandidate.extension_list.Add(iceExtension);

            return activeCandidate;
        }
Пример #2
0
        private static IceCandidate GatherNAPassiveCandidate(IPAddress localIPAddress)
        {
            // local endpoint
            IPEndPoint localEndpoint = new IPEndPoint(localIPAddress, 0);

            // only one listening socket, because there is no need to use a STUN server. We get the IP and Port from the NAT using UPnP
            Socket passiveListeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            passiveListeningSocket.Bind(localEndpoint);

            // update localEndpoint with binded Port 
            localEndpoint = (IPEndPoint)passiveListeningSocket.LocalEndPoint;


            // check if UPnP is available
            UPnP upnp = new UPnP();
            bool foundUPnPDevice = false;

            try
            {
                foundUPnPDevice = upnp.Discover(localIPAddress);
            }
            catch (Exception e)
            {
                //Console.WriteLine(e.Message);
                return null;
            }


            // IPEndPoint for public mapping
            IPEndPoint publicMapping = null;

            // found UPnP internet gateway device?
            if (foundUPnPDevice)
            {
                // try to get public IP and to add a port mapping
                try
                {
                    string publicIP = upnp.GetExternalIP().ToString();

                    // we can use the local Port for the public NAT port mapping too
                    bool addedPortMapping = upnp.AddPortMapping((ushort)localEndpoint.Port, (ushort)localEndpoint.Port, ProtocolType.Tcp, "RELOAD ICE TCP Port mapping");

                    if (addedPortMapping && !string.IsNullOrEmpty(publicIP))
                    {
                        publicMapping = new IPEndPoint(IPAddress.Parse(publicIP), localEndpoint.Port);
                    }
                    else
                        return null;
                }

                catch (Exception e)
                {
                    //Console.WriteLine(e.Message);
                    return null;
                }
            }
            // no UPnP IGD found
            else
                return null;


            // got public mapping?
            if (publicMapping == null)
                return null;

            // save data in candidate object
            IpAddressPort passiveIpAddressPort = new IpAddressPort(AddressType.IPv4_Address, publicMapping.Address, (ushort)publicMapping.Port);
            IceCandidate passiveCandidate = new IceCandidate(passiveIpAddressPort, Overlay_Link.TLS_TCP_with_FH);
            passiveCandidate.cand_type = CandType.tcp_nat;
            passiveCandidate.rel_addr_port = new IpAddressPort(AddressType.IPv4_Address, localEndpoint.Address, (ushort)localEndpoint.Port);
            passiveCandidate.passiveListeningSocket = passiveListeningSocket;

            // TCP Type
            passiveCandidate.tcpType = TcpType.Passive;

            // TCP ICE extension
            IceExtension iceExtension = new IceExtension();
            iceExtension.name = Encoding.UTF8.GetBytes("tcptype");
            iceExtension.value = Encoding.UTF8.GetBytes("passive");
            passiveCandidate.extension_list.Add(iceExtension);


            return passiveCandidate;
        }
Пример #3
0
        private static IceCandidate GatherSRPassiveCandidate(IPAddress localIPAddress)
        {
            // local endpoint
            IPEndPoint localEndpoint = new IPEndPoint(localIPAddress, 0);

            // listening socket
            Socket passiveListeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            passiveListeningSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            passiveListeningSocket.Bind(localEndpoint);

            // update localEndpoint with binded Port
            localEndpoint = (IPEndPoint)passiveListeningSocket.LocalEndPoint;

            // STUN socket
            Socket passiveSTUNSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            passiveSTUNSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            passiveSTUNSocket.Bind(localEndpoint);

            // get defined STUN servers
            List<IPEndPoint> definedSTUNServers = GetDefinedSTUNServers();

            // servers defined?
            if (definedSTUNServers.Count > 0)
            {
                // use first server
                IPEndPoint STUNEndPoint = definedSTUNServers[0];

                // try to connect
                try
                {
                    passiveSTUNSocket.Connect(STUNEndPoint);
                }

                catch (Exception e1)
                {
                    //Console.WriteLine(e1.Message);

                    // use second STUN server, if defined
                    if (definedSTUNServers.Count == 2)
                    {
                        STUNEndPoint = definedSTUNServers[1];

                        // try to connect
                        try
                        {
                            passiveSTUNSocket.Connect(STUNEndPoint);
                        }

                        catch (Exception e2)
                        {
                            //Console.WriteLine(e2.Message);

                            // could not establish a connection to a STUN server
                            return null;
                        }
                    }
                }

            }

            // no STUN servers defined
            else
                return null;


            // get public mapping
            IPEndPoint publicMapping = GetPublicMapping(passiveSTUNSocket);


            // save data in candidate object
            IpAddressPort passiveIpAddressPort = new IpAddressPort(AddressType.IPv4_Address, publicMapping.Address, (ushort)publicMapping.Port);
            IceCandidate passiveCandidate = new IceCandidate(passiveIpAddressPort, Overlay_Link.TLS_TCP_with_FH);
            passiveCandidate.cand_type = CandType.tcp_srflx;
            passiveCandidate.rel_addr_port = new IpAddressPort(AddressType.IPv4_Address, localEndpoint.Address, (ushort)localEndpoint.Port);
            passiveCandidate.passiveListeningSocket = passiveListeningSocket;
            passiveCandidate.passiveSTUNSocket = passiveSTUNSocket;

            // TCP Type
            passiveCandidate.tcpType = TcpType.Passive;

            // TCP ICE extension
            IceExtension iceExtension = new IceExtension();
            iceExtension.name = Encoding.UTF8.GetBytes("tcptype");
            iceExtension.value = Encoding.UTF8.GetBytes("passive");
            passiveCandidate.extension_list.Add(iceExtension);

            return passiveCandidate;
        }
Пример #4
0
        private static IceCandidate GatherSRSOCandidate(IPAddress localIPAddress)
        {
            // local endpoint
            IPEndPoint localEndpoint = new IPEndPoint(localIPAddress, 0);

            // listening socket
            Socket soListeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            soListeningSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            soListeningSocket.Bind(localEndpoint);

            // update localEndpoint with binded Port
            localEndpoint = (IPEndPoint)soListeningSocket.LocalEndPoint;

            // connecting socket
            Socket soConnectingSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            soConnectingSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            soConnectingSocket.Bind(localEndpoint);

            // STUN1 socket
            Socket soSTUN1Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            soSTUN1Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            soSTUN1Socket.Bind(localEndpoint);

            // STUN2 socket
            Socket soSTUN2Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            soSTUN2Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            soSTUN2Socket.Bind(localEndpoint);


            // public mapping
            IPEndPoint publicMapping = null;


            // get defined STUN servers
            List<IPEndPoint> definedSTUNServers = GetDefinedSTUNServers();

            // no defined STUN servers
            if (definedSTUNServers.Count == 0)
                return null;


            // only one STUN Server defined
            // so we can't predict the port mapping for two successive outgoing connections
            // what we can do here is to assume that the outgoing connections get the same port mapping
            else if (definedSTUNServers.Count == 1)
            {
                // try to connect
                try
                {
                    soSTUN1Socket.Connect(definedSTUNServers[0]);
                }

                catch (Exception e)
                {
                    //Console.WriteLine(e.Message);

                    // could not connect to STUN server
                    return null;
                }

                publicMapping = GetPublicMapping(soSTUN1Socket);

            }

            // two STUN servers defined
            // here we can predict the port mapping for two successive outgoing connections
            else if (definedSTUNServers.Count == 2)
            {
                // try to connect to first STUN server
                try
                {
                    // get first public mapping
                    soSTUN1Socket.Connect(definedSTUNServers[0]);
                    IPEndPoint mapping1 = GetPublicMapping(soSTUN1Socket);

                    // now try to connect to second STUN Server
                    try
                    {
                        soSTUN2Socket.Connect(definedSTUNServers[1]);
                        IPEndPoint mapping2 = GetPublicMapping(soSTUN2Socket);

                        // calculate difference between port mappings
                        int portDifference = mapping2.Port - mapping1.Port;

                        // IP will be the same, port will be adapted
                        publicMapping = new IPEndPoint(mapping2.Address, mapping2.Port + portDifference);
                    }

                    catch (Exception e)
                    {
                        //Console.WriteLine(e.Message);

                        // use first mapping and assume port mapping will be equal
                        publicMapping = mapping1;
                    }

                }
                catch (Exception e1)
                {
                    //Console.WriteLine(e1.Message);

                    // could not connect to first STUN server
                    // try second, but then we can't predict port mapping, only assume the port mapping will be equal for next outgoing connection
                    try
                    {
                        soSTUN2Socket.Connect(definedSTUNServers[1]);

                        publicMapping = GetPublicMapping(soSTUN2Socket);
                    }

                    catch (Exception e2)
                    {
                        //Console.WriteLine(e2.Message);

                        // could not connect to first and second STUN Server
                        return null;
                    }
                }

            }


            // got no public mapping
            if (publicMapping == null)
                return null;


            // save data in candidate object
            IpAddressPort soIpAddressPort = new IpAddressPort(AddressType.IPv4_Address, publicMapping.Address, (ushort)publicMapping.Port);
            IceCandidate soCandidate = new IceCandidate(soIpAddressPort, Overlay_Link.TLS_TCP_with_FH);
            soCandidate.cand_type = CandType.tcp_srflx;
            soCandidate.rel_addr_port = new IpAddressPort(AddressType.IPv4_Address, localEndpoint.Address, (ushort)localEndpoint.Port);
            soCandidate.soListeningSocket = soListeningSocket;
            soCandidate.soConnectingSocket = soConnectingSocket;
            soCandidate.soSTUN1Socket = soSTUN1Socket;
            soCandidate.soSTUN2Socket = soSTUN2Socket;

            // TCP Type
            soCandidate.tcpType = TcpType.SO;

            // TCP ICE extension
            IceExtension iceExtension = new IceExtension();
            iceExtension.name = Encoding.UTF8.GetBytes("tcptype");
            iceExtension.value = Encoding.UTF8.GetBytes("so");
            soCandidate.extension_list.Add(iceExtension);


            return soCandidate;
        }
Пример #5
0
        private static IceCandidate GatherHostSOCandidate(IPAddress localIPAddress)
        {
            // local endpoint
            IPEndPoint localEndpoint = new IPEndPoint(localIPAddress, 0);

            // listening socket
            Socket soListeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            soListeningSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            soListeningSocket.Bind(localEndpoint);

            // update localEndpoint with binded Port
            localEndpoint = (IPEndPoint)soListeningSocket.LocalEndPoint;

            // connecting socket
            Socket soConnectingSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            soConnectingSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            soConnectingSocket.Bind(localEndpoint);

            // save data in candidate object
            IpAddressPort soIpAddressPort = new IpAddressPort(AddressType.IPv4_Address, localEndpoint.Address, (ushort)localEndpoint.Port);
            IceCandidate soCandidate = new IceCandidate(soIpAddressPort, Overlay_Link.TLS_TCP_with_FH);
            soCandidate.cand_type = CandType.tcp_host;
            soCandidate.soListeningSocket = soListeningSocket;
            soCandidate.soConnectingSocket = soConnectingSocket;

            // TCP Type
            soCandidate.tcpType = TcpType.SO;

            // TCP ICE extension
            IceExtension iceExtension = new IceExtension();
            iceExtension.name = Encoding.UTF8.GetBytes("tcptype");
            iceExtension.value = Encoding.UTF8.GetBytes("so");
            soCandidate.extension_list.Add(iceExtension);

            return soCandidate;
        }
Пример #6
0
        private static IceCandidate GatherHostPassiveCandidate(IPAddress localIPAddress)
        {
            // local endpoint
            IPEndPoint localEndpoint = new IPEndPoint(localIPAddress, 0);


            Socket passiveListeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            passiveListeningSocket.Bind(localEndpoint);

            // update localEndpoint with binded Port
            localEndpoint = (IPEndPoint)passiveListeningSocket.LocalEndPoint;

            // save data in candidate object
            IpAddressPort passiveIpAddressPort = new IpAddressPort(AddressType.IPv4_Address, localEndpoint.Address, (ushort)localEndpoint.Port);
            IceCandidate passiveCandidate = new IceCandidate(passiveIpAddressPort, Overlay_Link.TLS_TCP_with_FH);
            passiveCandidate.cand_type = CandType.tcp_host;
            passiveCandidate.passiveListeningSocket = passiveListeningSocket;

            // TCP Type
            passiveCandidate.tcpType = TcpType.Passive;

            // TCP ICE extension
            IceExtension iceExtension = new IceExtension();
            iceExtension.name = Encoding.UTF8.GetBytes("tcptype");
            iceExtension.value = Encoding.UTF8.GetBytes("passive");
            passiveCandidate.extension_list.Add(iceExtension);

            return passiveCandidate;
        }
Пример #7
0
        // HOST METHODS
        private static IceCandidate GatherHostActiveCandidate(IPAddress localIPAddress)
        {
            IPEndPoint localEndpoint = new IPEndPoint(localIPAddress, 0);

            //Socket activeConnectingSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //// here is no bind, because active candidates don't have to be physically allocated here (allocation in connectivity checks)
            //activeConnectingSocket.Bind(localEndpoint); // TEST

            /*  RFC 6544 (ICE TCP), Section 3:
            In the case of active candidates, both IP
            address and port are present, but the port is meaningless (it is
            there only for making encoding of active candidates consistent with
            the other candidate types and is ignored by the peer).  As a
            consequence, active candidates do not need to be physically allocated
            at the time of address gathering.  Rather, the physical allocations,
            which occur as a consequence of a connection attempt, occur at the
            time of the connectivity checks.
             */

            // save data in candidate object
            IpAddressPort activeIpAddressPort = new IpAddressPort(AddressType.IPv4_Address, localEndpoint.Address, (ushort)localEndpoint.Port);
            IceCandidate activeCandidate = new IceCandidate(activeIpAddressPort, Overlay_Link.TLS_TCP_with_FH);
            activeCandidate.cand_type = CandType.tcp_host;
            //activeCandidate.activeConnectingSocket = activeConnectingSocket; // TEST: in PerformCheck

            // TCP Type
            activeCandidate.tcpType = TcpType.Active;

            // TCP ICE extension
            IceExtension iceExtension = new IceExtension();
            iceExtension.name = Encoding.UTF8.GetBytes("tcptype");
            iceExtension.value = Encoding.UTF8.GetBytes("active");
            activeCandidate.extension_list.Add(iceExtension);

            return activeCandidate;
        }
Пример #8
0
        public static IceCandidate CreateBootstrapCandidate(IPAddress localIPAddress, int port)
        {
            // save data in candidate object
            IpAddressPort bootstrapIpAddressPort = new IpAddressPort(AddressType.IPv4_Address, localIPAddress, (ushort)port);
            IceCandidate bootstrapCandidate = new IceCandidate(bootstrapIpAddressPort, Overlay_Link.TLS_TCP_with_FH);
            bootstrapCandidate.cand_type = CandType.tcp_bootstrap;

            // TCP Type
            bootstrapCandidate.tcpType = TcpType.Passive;

            // TCP ICE extension
            IceExtension iceExtension = new IceExtension();
            iceExtension.name = Encoding.UTF8.GetBytes("tcptype");
            iceExtension.value = Encoding.UTF8.GetBytes("passive");
            bootstrapCandidate.extension_list.Add(iceExtension);


            // set other preference and foundation
            bootstrapCandidate.otherPreference = 8191;
            bootstrapCandidate.foundation = ComputeFoundation(bootstrapCandidate);

            return bootstrapCandidate;
        }
Пример #9
0
        public IceCandidate(IpAddressPort addr_port, Overlay_Link ol)
        {
            this.addr_port = addr_port;
            this.priority = IceCandidate.NoICE_PRIORITY;
            this.cand_type = CandType.tcp_host;
            this.overlay_link = ol;

            this.extension_list = new List<IceExtension>();

        }