@@ -383,6 +383,7 @@ def initialize(args = {})
383383    @verbose  =  false  # Make this configurable with a switch on the class. 
384384    @auth  =  args [ :auth ]  || DefaultAuth 
385385    @base  =  args [ :base ]  || DefaultTreebase 
386+     @timeout  =  args [ :timeout ]  || 60 
386387    encryption  args [ :encryption ]  # may be nil 
387388
388389    if  pr  =  @auth [ :password ]  and  pr . respond_to? ( :call ) 
@@ -562,7 +563,7 @@ def open
562563      @open_connection  =  Net ::LDAP ::Connection . new ( :host  =>  @host , 
563564                                                   :port  =>  @port , 
564565                                                   :encryption  => 
565-                                                    @encryption ) 
566+                                                    @encryption ,   :timeout   =>   @timeout ) 
566567      @open_connection . bind ( @auth ) 
567568      yield  self 
568569    ensure 
@@ -634,7 +635,7 @@ def search(args = {})
634635    else 
635636      begin 
636637        conn  =  Net ::LDAP ::Connection . new ( :host  =>  @host ,  :port  =>  @port , 
637-                                          :encryption  =>  @encryption ) 
638+                                          :encryption  =>  @encryption ,   :timeout   =>   @timeout ) 
638639        if  ( @result  =  conn . bind ( args [ :auth ]  || @auth ) ) . result_code  == 0 
639640          @result  =  conn . search ( args )  {  |entry |
640641            result_set  << entry  if  result_set 
@@ -716,7 +717,7 @@ def bind(auth = @auth)
716717    else 
717718      begin 
718719        conn  =  Connection . new ( :host  =>  @host ,  :port  =>  @port , 
719-                               :encryption  =>  @encryption ) 
720+                               :encryption  =>  @encryption ,   :timeout   =>   @timeout ) 
720721        @result  =  conn . bind ( auth ) 
721722      ensure 
722723        conn . close  if  conn 
@@ -817,7 +818,7 @@ def add(args)
817818      @result  =  0 
818819      begin 
819820        conn  =  Connection . new ( :host  =>  @host ,  :port  =>  @port , 
820-                               :encryption  =>  @encryption ) 
821+                               :encryption  =>  @encryption ,   :timeout   =>   @timeout ) 
821822        if  ( @result  =  conn . bind ( args [ :auth ]  || @auth ) ) . result_code  == 0 
822823          @result  =  conn . add ( args ) 
823824        end 
@@ -915,7 +916,7 @@ def modify(args)
915916      @result  =  0 
916917      begin 
917918        conn  =  Connection . new ( :host  =>  @host ,  :port  =>  @port , 
918-                               :encryption  =>  @encryption ) 
919+                               :encryption  =>  @encryption ,   :timeout   =>   @timeout ) 
919920        if  ( @result  =  conn . bind ( args [ :auth ]  || @auth ) ) . result_code  == 0 
920921          @result  =  conn . modify ( args ) 
921922        end 
@@ -987,7 +988,7 @@ def rename(args)
987988      @result  =  0 
988989      begin 
989990        conn  =  Connection . new ( :host  =>  @host ,  :port  =>  @port , 
990-                               :encryption  =>  @encryption ) 
991+                               :encryption  =>  @encryption ,   :timeout   =>   @timeout ) 
991992        if  ( @result  =  conn . bind ( args [ :auth ]  || @auth ) ) . result_code  == 0 
992993          @result  =  conn . rename ( args ) 
993994        end 
@@ -1015,7 +1016,7 @@ def delete(args)
10151016      @result  =  0 
10161017      begin 
10171018        conn  =  Connection . new ( :host  =>  @host ,  :port  =>  @port , 
1018-                               :encryption  =>  @encryption ) 
1019+                               :encryption  =>  @encryption ,   :timeout   =>   @timeout ) 
10191020        if  ( @result  =  conn . bind ( args [ :auth ]  || @auth ) ) . result_code  == 0 
10201021          @result  =  conn . delete ( args ) 
10211022        end 
@@ -1119,9 +1120,34 @@ class Net::LDAP::Connection #:nodoc:
11191120  LdapVersion  =  3 
11201121  MaxSaslChallenges  =  10 
11211122
1123+   def  socket_connect_with_timeout ( host ,  port ,  timeout = nil ) 
1124+       addr  =  Socket . getaddrinfo ( host ,  nil ) 
1125+       sock  =  Socket . new ( Socket . const_get ( addr [ 0 ] [ 0 ] ) ,  Socket ::SOCK_STREAM ,  0 ) 
1126+ 
1127+       if  timeout 
1128+         secs  =  Integer ( timeout ) 
1129+         usecs  =  Integer ( ( timeout  - secs )  * 1_000_000 ) 
1130+         optval  =  [ secs ,  usecs ] . pack ( "l_2" ) 
1131+ 
1132+         sock . setsockopt  Socket ::SOL_SOCKET ,  Socket ::SO_RCVTIMEO ,  optval 
1133+         sock . setsockopt  Socket ::SOL_SOCKET ,  Socket ::SO_SNDTIMEO ,  optval 
1134+       end 
1135+ 
1136+       begin 
1137+         sock . connect_nonblock ( Socket . pack_sockaddr_in ( port ,  addr [ 0 ] [ 3 ] ) ) 
1138+       rescue  Errno ::EINPROGRESS  =>  ex 
1139+         rzult  =  select ( [ sock ] ,  [ sock ] ,  [ sock ] ,  timeout ) 
1140+         if  !rzult 
1141+           raise  Errno ::ETIMEDOUT ,  "Timeout #{ timeout  ? "(#{ timeout }   seconds)"  : "(default)" }   exceeded" 
1142+         end 
1143+       end 
1144+       return  sock 
1145+   end 
1146+ 
11221147  def  initialize ( server ) 
11231148    begin 
1124-       @conn  =  TCPSocket . new ( server [ :host ] ,  server [ :port ] ) 
1149+       @conn  =  socket_connect_with_timeout ( server [ :host ] ,  server [ :port ] ,  server [ :timeout ] ) 
1150+       #@conn = TCPSocket.new(server[:host], server[:port]) 
11251151    rescue  SocketError 
11261152      raise  Net ::LDAP ::LdapError ,  "No such address or other socket error." 
11271153    rescue  Errno ::ECONNREFUSED 
0 commit comments