AsyncDNS-cr  Check-in [af207d1100]

Overview
Comment:Use IO::Memory to build the raw data

This is much nicer than using Bytes and fixes always sending 512 bytes.

Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: af207d1100f56e713d55b8a3e2c1aede86fe7170e42f8176d7bd95535742bffa
User & Date: js on 2021-03-05 01:34:03.787
Other Links: manifest | tags
Context
2021-03-06
21:34
Add receive loop check-in: 8c89490d20 user: js tags: trunk
2021-03-05
01:34
Use IO::Memory to build the raw data check-in: af207d1100 user: js tags: trunk
00:59
Initial support for sending the query check-in: b6cfd2fe24 user: js tags: trunk
Changes
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

44
45
46

47
48

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
      getter raw_data : Bytes

      def initialize(@query : Query, @id : UInt16, @settings : Settings,
                     @block : Response | Error ->)
        @ns_index = 0
        @attempt = 0
        @used_ns = nil
        @raw_data = Bytes.new(512)

        # Header

        i = 0
        @raw_data[i] = (@id >> 8).to_u8; i += 1
        @raw_data[i] = (@id & 0xFF).to_u8; i += 1
        # RD
        @raw_data[i] = 1; i += 1
        i += 1

        # QDCOUNT
        i += 1
        @raw_data[i] = 1; i += 1

        # ANCOUNT, NSCOUNT and ARCOUNT
        i += 6


        # Question

        # QNAME
        @query.domain.split('.').each do |component|
          if component.bytesize > 63 || i + component.bytesize > 512
            raise ArgumentError.new("Domain component too long")
          end

          raw_component = component.to_slice
          @raw_data[i] = raw_component.bytesize.to_u8; i += 1
          @raw_data[i, raw_component.bytesize].copy_from(raw_component)
          i += raw_component.bytesize
        end

        # QTYPE
        qtype = @query.rr_type.to_i
        @raw_data[i] = (qtype >> 8).to_u8; i += 1
        @raw_data[i] = (qtype & 0xFF).to_u8; i+= 1

        # QCLASS
        qclass = @query.dns_class.to_i
        @raw_data[i] = (qclass >> 8).to_u8; i += 1
        @raw_data[i] = (qclass & 0xFF).to_u8; i += 1
      end
    end

    def initialize
      @settings = Settings.new
      @queries = Hash(UInt16, Context).new
      @tcp_queries = Hash(Socket, Context).new







<



|
|
<

<
<
>

<
<
>

<
>





|



<
<
<
|



|
<
<
<

|
|
|







27
28
29
30
31
32
33

34
35
36
37
38

39


40
41


42
43

44
45
46
47
48
49
50
51
52
53



54
55
56
57
58



59
60
61
62
63
64
65
66
67
68
69
      getter raw_data : Bytes

      def initialize(@query : Query, @id : UInt16, @settings : Settings,
                     @block : Response | Error ->)
        @ns_index = 0
        @attempt = 0
        @used_ns = nil


        # Header

        io = IO::Memory.new(512)
        io.write_bytes(@id, IO::ByteFormat::BigEndian)

        # RD


        io.write_bytes(0x100_u16, IO::ByteFormat::BigEndian)
        # QDCOUNT


        io.write_bytes(1_u16, IO::ByteFormat::BigEndian)
        # ANCOUNT, NSCOUNT and ARCOUNT

        3.times { io.write_bytes(0_u16) }

        # Question

        # QNAME
        @query.domain.split('.').each do |component|
          if component.bytesize > 63 || io.size + component.bytesize > 512
            raise ArgumentError.new("Domain component too long")
          end




          io << component
        end

        # QTYPE
        io.write_bytes(@query.rr_type.to_u16, IO::ByteFormat::BigEndian)



        # QCLASS
        io.write_bytes(@query.dns_class.to_u16, IO::ByteFormat::BigEndian)

        @raw_data = io.to_slice
      end
    end

    def initialize
      @settings = Settings.new
      @queries = Hash(UInt16, Context).new
      @tcp_queries = Hash(Socket, Context).new