コード例 #1
0
        /// <summary>
        /// Gets a listener on a port within the assigned port range.
        /// </summary>
        /// <param name="connection">Connection for which to create the listener.</param>
        /// <param name="pasvOptions">The options for the <see cref="IPasvListener"/>.</param>
        /// <returns>Configured PasvListener.</returns>
        /// <exception cref="SocketException">When no free port could be found, or other bad things happen. See <see cref="SocketError"/>.</exception>
        private IPasvListener CreateListenerInRange(IFtpConnection connection, PasvListenerOptions pasvOptions)
        {
            lock (_listenerLock)
            {
                // randomize ports so we don't always get the ports in the same order
                foreach (var port in GetPorts(pasvOptions))
                {
                    try
                    {
                        return(new PasvListener(connection.LocalEndPoint.Address, port, pasvOptions.PublicAddress));
                    }
                    catch (SocketException se)
                    {
                        // retry if the socket is already in use, else throw the underlying exception
                        if (se.SocketErrorCode != SocketError.AddressAlreadyInUse)
                        {
                            _log?.LogError(se, "Could not create listener");
                            throw;
                        }
                    }
                }

                // if we reach this point, we have not been able to create a listener within range
                _log?.LogWarning("No free ports available for data connection");
                throw new SocketException((int)SocketError.AddressAlreadyInUse);
            }
        }
コード例 #2
0
        private IEnumerable <int> GetPorts(PasvListenerOptions options)
        {
            var portRangeCount = (options.PasvMaxPort - options.PasvMinPort + 1) * 2;

            while (portRangeCount-- != 0)
            {
                yield return(_prng.Next(options.PasvMinPort, options.PasvMaxPort + 1));
            }
        }