Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A try to solve timeouts on TCP sockets #182

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 42 additions & 17 deletions lib/net/ldap/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,51 @@ class Net::LDAP::Connection #:nodoc:
LdapVersion = 3
MaxSaslChallenges = 10

def initialize(server)
def initialize(server, timeout = 5)
@instrumentation_service = server[:instrumentation_service]

if server[:socket]
@conn = server[:socket]
else
addr = Socket.getaddrinfo(server[:host], nil)
sockaddr = Socket.pack_sockaddr_in(server[:port], addr[0][3])

Socket.new(Socket.const_get(addr[0][0]), Socket::SOCK_STREAM, 0).tap do |socket|
@conn = socket
@conn.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)

begin
@conn.connect_nonblock(sockaddr)
rescue IO::WaitWritable
if IO.select(nil, [socket], nil, timeout)
begin
@conn.connect_nonblock(sockaddr)
rescue Errno::EISCONN
# Good news everybody, the socket is connected!
rescue SocketError
raise Net::LDAP::LdapError, "No such address or other socket error."
rescue Errno::ECONNREFUSED
raise Net::LDAP::LdapError, "Server #{server[:host]} refused connection on port #{server[:port]}."
rescue Errno::EHOSTUNREACH => error
raise Net::LDAP::LdapError, "Host #{server[:host]} was unreachable (#{error.message})"
rescue
# An unexpected exception was raised - the connection is no good.
raise
end
else
# IO.select returns nil when the socket is not ready before timeout
# seconds have elapsed
raise "Connection timeout"
end
end
end

if server[:encryption]
setup_encryption server[:encryption]
end

begin
@conn = server[:socket] || TCPSocket.new(server[:host], server[:port])
rescue SocketError
raise Net::LDAP::LdapError, "No such address or other socket error."
rescue Errno::ECONNREFUSED
raise Net::LDAP::LdapError, "Server #{server[:host]} refused connection on port #{server[:port]}."
rescue Errno::EHOSTUNREACH => error
raise Net::LDAP::LdapError, "Host #{server[:host]} was unreachable (#{error.message})"
rescue Errno::ETIMEDOUT
raise Net::LDAP::LdapError, "Connection to #{server[:host]} timed out."
end

if server[:encryption]
setup_encryption server[:encryption]
yield self if block_given?
end

yield self if block_given?
end

module GetbyteForSSLSocket
Expand Down