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 | SQL 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
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

Modified src/resolver.cr from [d8a14eee35] to [7201657da1].

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