Esempio n. 1
0
        //internal class SockInterfacePair
        //{
        //    internal UdpSocket sock;
        //    internal IPAddress extInterface;
        //    public bool Initialized;

        //    internal SockInterfacePair(UdpSocket sock, IPAddress extIntf)
        //    {
        //        this.sock = sock;
        //        this.extInterface = extIntf;
        //        Initialized = false;
        //    }
        //}


        // Apparently binding to the same ports on UDPSender and UDPListener causes problems in unicast.
        // Sharing the socket though, allows us to tunnel through firewalls as data is sent and received
        // on the same  endpoint.
        // This region of code enables sharing sockets between the two classes.

        //internal static SockInterfacePair GetSharedSocket(IPEndPoint endPoint)
        //{
        //    lock (socks)
        //    {
        //        object sockObj = socks[endPoint];
        //        if (sockObj != null)
        //        {
        //            SockInterfacePair sip = (SockInterfacePair)sockObj;
        //            ++sip.sock.refCount;

        //            return sip;
        //        }
        //        else
        //        {
        //            // Create the socket
        //            UdpSocket sock = new UdpSocket(endPoint.AddressFamily);

        //            // Get the External Interface, save it for future use
        //            IPAddress externalInterface = Utility.GetLocalRoutingInterface(endPoint.Address);

        //            if (externalInterface == null)
        //            {
        //                // Pri3: Do something more helpful here
        //                throw new Exception(Strings.UnableToFindLocalRoutingInterface);
        //            }

        //            if (Utility.IsMulticast(endPoint.Address))
        //            {
        //                // Allow multiple binds to this socket, as it will still function properly
        //                //  (this is only the case if it is a multicast socket.  Unicast sockets fail to
        //                //   receive all data on all sockets)
        //                sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, -1);

        //                // We don't join the multicast group here, because we may not want to listen
        //                // to our own data (halfing our throughput).  jasonv - 10/28/2004
        //            }

        //            // Add the socket to the hashtable
        //            SockInterfacePair sip = new SockInterfacePair(sock, externalInterface);
        //            socks.Add(endPoint, sip);

        //            // Increase the socket's reference count
        //            ++sock.refCount;

        //            return sip;
        //        }
        //    }
        //}

        //internal static void ReleaseSharedSocket(IPEndPoint endPoint, UdpSocket sock)
        //{
        //    object sockObj = socks[endPoint];
        //    if (sockObj == null)
        //        throw new InvalidOperationException(Strings.SockDoesNotExistAsASharedSocket);

        //    lock (socks)
        //    {
        //        if (--sock.refCount <= 0)
        //        {
        //            // Leave the multicast group
        //            if (Utility.IsMulticast(endPoint.Address))
        //            {
        //                try
        //                {
        //                    if (endPoint.AddressFamily == AddressFamily.InterNetworkV6)
        //                    {
        //                        IPv6MulticastOption mo = new IPv6MulticastOption(endPoint.Address);
        //                        sock.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.DropMembership, mo);
        //                    }
        //                    else
        //                    {
        //                        MulticastOption mo = new MulticastOption(endPoint.Address);
        //                        sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.DropMembership, mo);
        //                    }
        //                }
        //                catch { } // The user of the socket *may* not have joined the multicast group (?)
        //            }

        //            // Remove ourselves from the shared pool
        //            socks.Remove(endPoint);

        //            // Close the socket
        //            try
        //            {
        //                sock.Close();
        //            }
        //            catch (ObjectDisposedException) { }
        //        }
        //    }
        //}

        internal static void ReleaseSocket(IPEndPoint endPoint, UdpSocket sock)
        {
            // Leave the multicast group
            if (Utility.IsMulticast(endPoint.Address))
            {
                try
                {
                    if (endPoint.AddressFamily == AddressFamily.InterNetworkV6)
                    {
                        IPv6MulticastOption mo = new IPv6MulticastOption(endPoint.Address);
                        sock.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.DropMembership, mo);
                    }
                    else
                    {
                        MulticastOption mo = new MulticastOption(endPoint.Address);
                        sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.DropMembership, mo);
                    }
                }
                catch { } // The user of the socket *may* not have joined the multicast group (?)
            }

            // Close the socket
            try
            {
                sock.Close();
            }
            catch (ObjectDisposedException) { }
        }
Esempio n. 2
0
        //returns the port number used...
        public static int CreateListenSocketsOnUniquePort(IPAddress ipv4Address, IPAddress ipv6Address, int receiveBufferSize, int timeToLive, out UdpSocket ipv4Socket, out UdpSocket ipv6Socket)
        {
            // We need both IPv4 and IPv6 on the same port. We can't atomicly bind for IPv4 and IPv6, 
            // so we try 10 times, which even with a 50% failure rate will statistically succeed 99.9% of the time.
            //
            // We look in the range of 49152-65534 for Vista default behavior parity.
            // http://www.iana.org/assignments/port-numbers
            // 
            // We also grab the 10 random numbers in a row to reduce collisions between multiple people somehow
            // colliding on the same seed.
            const int retries = 10;
            const int lowWatermark = 49152;
            const int highWatermark = 65535;

            ipv4Socket = null;
            ipv6Socket = null;

            int[] portNumbers = new int[retries];

            Random randomNumberGenerator = new Random(AppDomain.CurrentDomain.GetHashCode() | Environment.TickCount);

            for (int i = 0; i < retries; i++)
            {
                portNumbers[i] = randomNumberGenerator.Next(lowWatermark, highWatermark);
            }


            int port = -1;
            for (int i = 0; i < retries; i++)
            {
                port = portNumbers[i];
                try
                {
                    ipv4Socket = UdpUtility.CreateUnicastListenSocket(ipv4Address, ref port, receiveBufferSize, timeToLive);
                    ipv6Socket = UdpUtility.CreateUnicastListenSocket(ipv6Address, ref port, receiveBufferSize, timeToLive);
                    break;
                }
                catch (AddressAlreadyInUseException)
                {
                    if (ipv4Socket != null)
                    {
                        ipv4Socket.Close();
                        ipv4Socket = null;
                    }
                    ipv6Socket = null;
                }
                catch (AddressAccessDeniedException)
                {
                    if (ipv4Socket != null)
                    {
                        ipv4Socket.Close();
                        ipv4Socket = null;
                    }
                    ipv6Socket = null;
                }
            }

            if (ipv4Socket == null)
            {
                throw FxTrace.Exception.AsError(new AddressAlreadyInUseException(SR.UniquePortNotAvailable));
            }

            Fx.Assert(ipv4Socket != null, "An exception should have been thrown if the ipv4Socket socket is null");
            Fx.Assert(ipv6Socket != null, "An exception should have been thrown if the ipv6Socket socket is null");
            Fx.Assert(port > 0, "The port number should have been greater than 0. Actual value was " + port);

            return port;
        }