vendor/bundle/ruby/2.7.0/gems/dnsruby-1.61.5/lib/dnsruby/packet_sender.rb
#  This method sends the packet using the built-in pure Ruby event loop, with no dependencies.
This method sends the packet using the built-in pure Ruby event loop, with no dependencies.
This method sends the packet using the built - in pure Ruby event loop with no dependencies .
def send_dnsruby(query_bytes, query, client_query_id, client_queue, use_tcp) 
      endtime = Time.now + @packet_timeout
      st = SelectThread.instance
      socket = nil
      runnextportloop = true
      numtries = 0
      src_address = @src_address
      if (@ipv6)
        src_address = @src_address6
      end
      while (runnextportloop) do
        begin
          numtries += 1
          src_port = get_next_src_port
          if (use_tcp)
            begin
              if (@tcp_pipelining)
                socket, new_socket = tcp_pipeline_socket(src_port)
                src_port = @tcp_pipeline_local_port
              else
                socket = Socket.tcp(@server, @port, src_address, src_port, connect_timeout: @packet_timeout)
                new_socket = true
              end
            rescue Errno::EBADF, Errno::ENETUNREACH => e
              err=IOError.new("TCP connection error to #{@server}:#{@port} from #{src_address}:#{src_port}, use_tcp=#{use_tcp}, exception = #{e.class}, #{e}")
              Dnsruby.log.error { "#{err}" }
              st.push_exception_to_select(client_query_id, client_queue, err, nil)
              return
            end
          else
            socket = nil
            if (/java/ =~ RUBY_PLATFORM)
              socket = UDPSocket.new()
            else
              socket = UDPSocket.new(@ipv6 ? Socket::AF_INET6 : Socket::AF_INET)
            end
            new_socket = true
            socket.bind(src_address, src_port)
            socket.connect(@server, @port)
          end
          runnextportloop = false
        rescue Exception => e
          if (socket!=nil)
            begin
              socket.close unless @tcp_pipelining && !new_socket
            rescue Exception
            end
          end
          if ((e.class != Errno::EADDRINUSE) || (numtries > 50) ||
              ((e.class == Errno::EADDRINUSE) && (src_port == @src_port[0])))
            err_msg = "dnsruby can't connect to #{@server}:#{@port} from #{src_address}:#{src_port}, use_tcp=#{use_tcp}, exception = #{e.class}, #{e} #{e.backtrace}"
            err=IOError.new(err_msg)
            Dnsruby.log.error( "#{err}")
            Dnsruby.log.error(e.backtrace)
            if @tcp_pipelining
              st.push_exception_to_select(client_query_id, client_queue, SocketEofResolvError.new(err_msg), nil)
            else
              st.push_exception_to_select(client_query_id, client_queue, err, nil)
            end
            return
          end
        end
      end
      if (socket==nil)
        err=IOError.new("dnsruby can't connect to #{@server}:#{@port} from #{src_address}:#{src_port}, use_tcp=#{use_tcp}")
        Dnsruby.log.error { "#{err}" }
        st.push_exception_to_select(client_query_id, client_queue, err, nil)
        return
      end
      Dnsruby.log.debug { "Sending packet to #{@server}:#{@port} from #{src_address}:#{src_port}, use_tcp=#{use_tcp} : #{query.question()[0].qname}, #{query.question()[0].qtype}" }
      query_settings = SelectThread::QuerySettings.new(query_bytes, query, @ignore_truncation, client_queue, client_query_id, socket, @server, @port, endtime, udp_packet_size, self)
      query_settings.is_persistent_socket = @tcp_pipelining if use_tcp
      query_settings.tcp_pipelining_max_queries = @tcp_pipelining_max_queries if @tcp_pipelining
      begin
        if (use_tcp)
          lenmsg = [query_bytes.length].pack('n')
          socket.send(lenmsg, 0)
        end
        socket.send(query_bytes, 0)
        st.add_to_select(query_settings)
      rescue Exception => e
        err_msg = "Send failed to #{@server}:#{@port} from #{src_address}:#{src_port}, use_tcp=#{use_tcp}, exception : #{e}"
        err=IOError.new(err_msg)
        Dnsruby.log.error { "#{err}" }
        Dnsruby.log.error(e.backtrace)
        if @tcp_pipelining
          st.push_exception_to_select(client_query_id, client_queue, SocketEofResolvError.new(err_msg), nil) if new_socket
        else
          st.push_exception_to_select(client_query_id, client_queue, err, nil)
        end
        begin
          socket.close unless @tcp_pipelining && !new_socket
        rescue Exception
        end
        return
      end
      Dnsruby.log.debug { "Packet sent to #{@server}:#{@port} from #{src_address}:#{src_port}, use_tcp=#{use_tcp} : #{query.question()[0].qname}, #{query.question()[0].qtype}" }
    end
def send_dnsruby ( query_bytes , query , client_query_id , client_queue , use_tcp ) endtime = Time . now + @packet_timeout st = SelectThread . instance socket = nil runnextportloop = true numtries = 0 src_address = @src_address if ( @ipv6 ) src_address = @src_address6 end while ( runnextportloop ) do begin numtries += 1 src_port = get_next_src_port if ( use_tcp ) begin if ( @tcp_pipelining ) socket , new_socket = tcp_pipeline_socket ( src_port ) src_port = @tcp_pipeline_local_port else socket = Socket . tcp ( @server , @port , src_address , src_port , connect_timeout : @packet_timeout ) new_socket = true end rescue Errno :: EBADF , Errno :: ENETUNREACH => e err = IOError . new ( "TCP connection error to #{@server}:#{@port} from #{src_address}:#{src_port}, use_tcp=#{use_tcp}, exception = #{e.class}, #{e}" ) Dnsruby . log . error { "#{err}" } st . push_exception_to_select ( client_query_id , client_queue , err , nil ) return end else socket = nil if ( / java / =~ RUBY_PLATFORM ) socket = UDPSocket . new ( ) else socket = UDPSocket . new ( @ipv6 ? Socket :: AF_INET6 : Socket :: AF_INET ) end new_socket = true socket . bind ( src_address , src_port ) socket . connect ( @server , @port ) end runnextportloop = false rescue Exception => e if ( socket != nil ) begin socket . close unless @tcp_pipelining && ! new_socket rescue Exception end end if ( ( e . class != Errno :: EADDRINUSE ) || ( numtries > 50 ) || ( ( e . class == Errno :: EADDRINUSE ) && ( src_port == @src_port [ 0 ] ) ) ) err_msg = "dnsruby can't connect to #{@server}:#{@port} from #{src_address}:#{src_port}, use_tcp=#{use_tcp}, exception = #{e.class}, #{e} #{e.backtrace}" err = IOError . new ( err_msg ) Dnsruby . log . error ( "#{err}" ) Dnsruby . log . error ( e . backtrace ) if @tcp_pipelining st . push_exception_to_select ( client_query_id , client_queue , SocketEofResolvError . new ( err_msg ) , nil ) else st . push_exception_to_select ( client_query_id , client_queue , err , nil ) end return end end end if ( socket == nil ) err = IOError . new ( "dnsruby can't connect to #{@server}:#{@port} from #{src_address}:#{src_port}, use_tcp=#{use_tcp}" ) Dnsruby . log . error { "#{err}" } st . push_exception_to_select ( client_query_id , client_queue , err , nil ) return end Dnsruby . log . debug { "Sending packet to #{@server}:#{@port} from #{src_address}:#{src_port}, use_tcp=#{use_tcp} : #{query.question()[0].qname}, #{query.question()[0].qtype}" } query_settings = SelectThread :: QuerySettings . new ( query_bytes , query , @ignore_truncation , client_queue , client_query_id , socket , @server , @port , endtime , udp_packet_size , self ) query_settings . is_persistent_socket = @tcp_pipelining if use_tcp query_settings . tcp_pipelining_max_queries = @tcp_pipelining_max_queries if @tcp_pipelining begin if ( use_tcp ) lenmsg = [ query_bytes . length ] . pack ( 'n' ) socket . send ( lenmsg , 0 ) end socket . send ( query_bytes , 0 ) st . add_to_select ( query_settings ) rescue Exception => e err_msg = "Send failed to #{@server}:#{@port} from #{src_address}:#{src_port}, use_tcp=#{use_tcp}, exception : #{e}" err = IOError . new ( err_msg ) Dnsruby . log . error { "#{err}" } Dnsruby . log . error ( e . backtrace ) if @tcp_pipelining st . push_exception_to_select ( client_query_id , client_queue , SocketEofResolvError . new ( err_msg ) , nil ) if new_socket else st . push_exception_to_select ( client_query_id , client_queue , err , nil ) end begin socket . close unless @tcp_pipelining && ! new_socket rescue Exception end return end Dnsruby . log . debug { "Packet sent to #{@server}:#{@port} from #{src_address}:#{src_port}, use_tcp=#{use_tcp} : #{query.question()[0].qname}, #{query.question()[0].qtype}" } end
This method sends the packet using the built-in pure Ruby event loop, with no dependencies.
This method sends the packet using the built - in pure Ruby event loop with no dependencies .
#:nodoc: all #  First send the query (synchronously) #  Can't create a connection #  JRuby UDPSocket only takes 0 parameters - no IPv6 support in JRuby... #               ipv6 = @src_address =~ /:/ #let the select thread close the socket if tcp_pipeli #  Try again if the error was EADDRINUSE and a random source port is used #  Maybe try a max number of times? #             print "#{Time.now} : Sending packet to #{@server} : #{query.question()[0].qname}, #{query.question()[0].qtype}\n" #  Listen for the response before we send the packet (to avoid any race conditions) #  The select thread will now wait for the response and send that or a #  timeout back to the client_queue. #we let the select_thread close the socket when doing tcp #pipelining #       print "Packet sent to #{@server}:#{@port} from #{@src_address}:#{src_port}, use_tcp=#{use_tcp} : #{query.question()[0].qname}, #{query.question()[0].qtype}\n"
query_bytes
<not_specific>
query
<not_specific>
client_query_id
<not_specific>
client_queue
<not_specific>
use_tcp
<not_specific>