def connection
      @connection_errors = []
      addrinfo.each do |_,port,_,addr,_,_,_|
        retried = false
        begin
          @conn = TCPSocket.new(addr, port)
        rescue Errno::EINVAL => e
          if retried
            message = e.message.split(" - ")[1]
            @connection_errors << Errno::EINVAL.new(
              "#{message}: TCPSocket.new(#{addr.inspect}, #{port.inspect})")
            next
          end

          retried = true
          retry
        end

        args = [@conn]
        args << options[:ssl_context] if options[:ssl_context]
        @sock = OpenSSL::SSL::SSLSocket.new(*args)
        @sock.sync_close = true

        begin
          @sock.connect
          @greeting = recv_frame  # Perform initial recv

          return yield
        rescue Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::EHOSTUNREACH => e
          @connection_errors << e
          next # try the next address in the list
        rescue OpenSSL::SSL::SSLError => e
          # Connection error, most likely the IP isn't in the allow list
          if e.message =~ /returned=5 errno=0/
            @connection_errors << ConnectionError.new("SSL Connection error, IP may not be permitted to connect to #{@host}",
               @conn.addr, @conn.peeraddr, e)
            next
          else
            raise e
          end
        ensure
          @sock.close # closes @conn
          @conn = @sock = nil
        end
      end

      # Should only get here if we didn't return from the block above

      addrinfo(true) # Update our addrinfo in case the DNS has changed
      raise @connection_errors.last unless @connection_errors.empty?
      raise Errno::EHOSTUNREACH, "Failed to connect to host #{@host}"
    end
def connection
      @connection_errors = []
      addrinfo.each do |_,port,_,addr,_,_,_|
        retried = false
        begin
          @conn = TCPSocket.new(addr, port)
        rescue Errno::EINVAL => e
          if retried
            message = e.message.split(" - ")[1]
            @connection_errors << Errno::EINVAL.new(
              "#{message}: TCPSocket.new(#{addr.inspect}, #{port.inspect})")
            next
          end

          retried = true
          retry
        end

        args = [@conn]
        args << options[:ssl_context] if options[:ssl_context]
        @sock = OpenSSL::SSL::SSLSocket.new(*args)
        @sock.sync_close = true

        begin
          @sock.connect
          @greeting = recv_frame  # Perform initial recv

          return yield
        rescue Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::EHOSTUNREACH => e
          @connection_errors << e
          next # try the next address in the list
        rescue OpenSSL::SSL::SSLError => e
          # Connection error, most likely the IP isn't in the allow list
          if e.message =~ /returned=5 errno=0/
            @connection_errors << ConnectionError.new("SSL Connection error, IP may not be permitted to connect to #{@host}",
               @conn.addr, @conn.peeraddr, e)
            next
          else
            raise e
          end
        ensure
          @sock.close # closes @conn
          @conn = @sock = nil
        end
      end

      # Should only get here if we didn't return from the block above

      addrinfo(true) # Update our addrinfo in case the DNS has changed
      raise @connection_errors.last unless @connection_errors.empty?
      raise Errno::EHOSTUNREACH, "Failed to connect to host #{@host}"
    end
EPP Server Connection

 @yield connected session
 @example typical usage
   connection do
     # .. do stuff with logged in session ..
   end
 @example usage with with_login
   connection do
     with_login do
       # .. do stuff with logged in session ..
     end
   end