net-dns 0.8.0 → 0.20.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +6 -14
- data/.rspec +1 -0
- data/.travis.yml +9 -16
- data/CHANGELOG.md +37 -13
- data/LICENSE.txt +56 -0
- data/README.md +94 -77
- data/demo/check_soa.rb +27 -38
- data/demo/threads.rb +3 -7
- data/lib/net/dns/header.rb +86 -110
- data/lib/net/dns/names.rb +31 -31
- data/lib/net/dns/packet.rb +148 -158
- data/lib/net/dns/question.rb +41 -42
- data/lib/net/dns/resolver/socks.rb +47 -55
- data/lib/net/dns/resolver/timeouts.rb +19 -30
- data/lib/net/dns/resolver.rb +151 -176
- data/lib/net/dns/rr/a.rb +45 -55
- data/lib/net/dns/rr/aaaa.rb +39 -50
- data/lib/net/dns/rr/classes.rb +32 -37
- data/lib/net/dns/rr/cname.rb +31 -41
- data/lib/net/dns/rr/hinfo.rb +40 -56
- data/lib/net/dns/rr/mr.rb +31 -42
- data/lib/net/dns/rr/mx.rb +35 -47
- data/lib/net/dns/rr/ns.rb +31 -41
- data/lib/net/dns/rr/null.rb +10 -15
- data/lib/net/dns/rr/ptr.rb +16 -24
- data/lib/net/dns/rr/soa.rb +36 -35
- data/lib/net/dns/rr/srv.rb +18 -19
- data/lib/net/dns/rr/txt.rb +11 -16
- data/lib/net/dns/rr/types.rb +118 -109
- data/lib/net/dns/rr.rb +107 -117
- data/lib/net/dns/version.rb +5 -13
- data/lib/net/dns.rb +6 -11
- metadata +18 -83
- data/.gitignore +0 -8
- data/Gemfile +0 -4
- data/Rakefile +0 -71
- data/fixtures/resolv.conf +0 -4
- data/lib/net/dns/core_ext.rb +0 -52
- data/net-dns.gemspec +0 -35
- data/test/header_test.rb +0 -167
- data/test/names_test.rb +0 -21
- data/test/packet_test.rb +0 -49
- data/test/question_test.rb +0 -83
- data/test/resolver/timeouts_test.rb +0 -109
- data/test/resolver_test.rb +0 -117
- data/test/rr/a_test.rb +0 -113
- data/test/rr/aaaa_test.rb +0 -109
- data/test/rr/classes_test.rb +0 -85
- data/test/rr/cname_test.rb +0 -97
- data/test/rr/hinfo_test.rb +0 -117
- data/test/rr/mr_test.rb +0 -105
- data/test/rr/mx_test.rb +0 -112
- data/test/rr/ns_test.rb +0 -86
- data/test/rr/types_test.rb +0 -69
- data/test/rr_test.rb +0 -131
- data/test/test_helper.rb +0 -4
data/lib/net/dns/header.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module Net
|
2
2
|
module DNS
|
3
|
-
|
4
3
|
# DNS packet header class
|
5
4
|
#
|
6
5
|
# The Net::DNS::Header class represents the header portion of a
|
@@ -37,7 +36,6 @@ module Net
|
|
37
36
|
# more or less the same.
|
38
37
|
#
|
39
38
|
class Header
|
40
|
-
|
41
39
|
# A wrong +count+ parameter has been passed.
|
42
40
|
class WrongCountError < ArgumentError
|
43
41
|
end
|
@@ -54,7 +52,6 @@ module Net
|
|
54
52
|
class Error < StandardError
|
55
53
|
end
|
56
54
|
|
57
|
-
|
58
55
|
# DNS Header RCode handling class
|
59
56
|
#
|
60
57
|
# It should be used internally by Net::DNS::Header class. However, it's still
|
@@ -103,7 +100,6 @@ module Net
|
|
103
100
|
# More RCodes has to come for TSIGs and other operations.
|
104
101
|
#
|
105
102
|
class RCode
|
106
|
-
|
107
103
|
# Constant for +rcode+ Response Code No Error
|
108
104
|
NOERROR = 0
|
109
105
|
# Constant for +rcode+ Response Code Format Error
|
@@ -117,33 +113,31 @@ module Net
|
|
117
113
|
# Constant for +rcode+ Response Code Refused Error
|
118
114
|
REFUSED = 5
|
119
115
|
|
120
|
-
|
121
|
-
|
122
116
|
RCodeType = %w[NoError FormErr ServFail NXDomain NotImp
|
123
|
-
|
117
|
+
Refused YXDomain YXRRSet NXRRSet NotAuth NotZone].freeze
|
124
118
|
|
125
119
|
RCodeErrorString = ["No errors",
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
attr_reader :code
|
120
|
+
"The name server was unable to interpret the query",
|
121
|
+
"The name server was unable to process this query due to problem with the name server",
|
122
|
+
"Domain name referenced in the query does not exists",
|
123
|
+
"The name server does not support the requested kind of query",
|
124
|
+
"The name server refuses to perform the specified operation for policy reasons",
|
125
|
+
"",
|
126
|
+
"",
|
127
|
+
"",
|
128
|
+
"",
|
129
|
+
"",].freeze
|
130
|
+
|
131
|
+
attr_reader :code
|
132
|
+
attr_reader :type
|
133
|
+
attr_reader :explanation
|
138
134
|
|
139
135
|
def initialize(code)
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
raise ArgumentError, "RCode `#{code}' out of range"
|
146
|
-
end
|
136
|
+
raise ArgumentError, "RCode `#{code}' out of range" unless (0..10).cover? code
|
137
|
+
|
138
|
+
@code = code
|
139
|
+
@type = RCodeType[code]
|
140
|
+
@explanation = RCodeErrorString[code]
|
147
141
|
end
|
148
142
|
|
149
143
|
def to_s
|
@@ -151,7 +145,6 @@ module Net
|
|
151
145
|
end
|
152
146
|
end
|
153
147
|
|
154
|
-
|
155
148
|
# Constant for +opCode+ query
|
156
149
|
QUERY = 0
|
157
150
|
# Constant for +opCode+ iquery
|
@@ -159,7 +152,7 @@ module Net
|
|
159
152
|
# Constant for +opCode+ status
|
160
153
|
STATUS = 2
|
161
154
|
# Array with given strings
|
162
|
-
OPARR = %w[QUERY IQUERY STATUS]
|
155
|
+
OPARR = %w[QUERY IQUERY STATUS].freeze
|
163
156
|
|
164
157
|
# Reader for +id+ attribute
|
165
158
|
attr_reader :id
|
@@ -212,11 +205,9 @@ module Net
|
|
212
205
|
# See also each option for a detailed explanation of usage.
|
213
206
|
#
|
214
207
|
def initialize(arg = {})
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
raise ArgumentError, "Wrong argument class `#{arg.class}'"
|
219
|
-
end
|
208
|
+
raise ArgumentError, "Wrong argument class `#{arg.class}'" unless arg.is_a? Hash
|
209
|
+
|
210
|
+
new_from_hash(arg)
|
220
211
|
end
|
221
212
|
|
222
213
|
# Creates a new Net::DNS::Header object from binary data, which is
|
@@ -232,13 +223,11 @@ module Net
|
|
232
223
|
# #=> "true" if it comes from authoritative name server
|
233
224
|
#
|
234
225
|
def self.parse(arg)
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
raise ArgumentError, "Wrong argument class `#{arg.class}'"
|
241
|
-
end
|
226
|
+
raise ArgumentError, "Wrong argument class `#{arg.class}'" unless arg.is_a? String
|
227
|
+
|
228
|
+
o = allocate
|
229
|
+
o.send(:new_from_binary, arg)
|
230
|
+
o
|
242
231
|
end
|
243
232
|
|
244
233
|
# Inspect method, prints out all the options and relative values.
|
@@ -253,24 +242,24 @@ module Net
|
|
253
242
|
# way of display output.
|
254
243
|
#
|
255
244
|
def inspect
|
256
|
-
";; id =
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
245
|
+
";; id = #{@id}\n" +
|
246
|
+
if false # @opCode == "UPDATE"
|
247
|
+
# do stuff
|
248
|
+
else
|
249
|
+
";; qr = #{@qr}\t" \
|
250
|
+
"opCode: #{opCode_str}\t" \
|
251
|
+
"aa = #{@aa}\t" \
|
252
|
+
"tc = #{@tc}\t" \
|
253
|
+
"rd = #{@rd}\n" \
|
254
|
+
";; ra = #{@ra}\t" \
|
255
|
+
"ad = #{@ad}\t" \
|
256
|
+
"cd = #{@cd}\t" \
|
257
|
+
"rcode = #{@rCode.type}\n" \
|
258
|
+
";; qdCount = #{@qdCount}\t" \
|
259
|
+
"anCount = #{@anCount}\t" \
|
260
|
+
"nsCount = #{@nsCount}\t" \
|
261
|
+
"arCount = #{@arCount}\n"
|
262
|
+
end
|
274
263
|
end
|
275
264
|
|
276
265
|
# The Net::DNS::Header#format method prints out the header
|
@@ -297,7 +286,7 @@ module Net
|
|
297
286
|
def format
|
298
287
|
del = ("+-" * 16) + "+\n"
|
299
288
|
len = del.length
|
300
|
-
str = del + "|" + @id.to_s.center(len-3) + "|\n"
|
289
|
+
str = del + "|" + @id.to_s.center(len - 3) + "|\n"
|
301
290
|
str += del + "|" + @qr.to_s
|
302
291
|
str += "|" + @opCode.to_s.center(7)
|
303
292
|
str += "|" + @aa.to_s
|
@@ -307,10 +296,10 @@ module Net
|
|
307
296
|
str += "|" + @ad.to_s
|
308
297
|
str += "|" + @cd.to_s.center(3)
|
309
298
|
str += "|" + @rCode.to_s.center(7) + "|\n"
|
310
|
-
str += del + "|" + @qdCount.to_s.center(len-3) + "|\n"
|
311
|
-
str += del + "|" + @anCount.to_s.center(len-3) + "|\n"
|
312
|
-
str += del + "|" + @nsCount.to_s.center(len-3) + "|\n"
|
313
|
-
str += del + "|" + @arCount.to_s.center(len-3) + "|\n" + del
|
299
|
+
str += del + "|" + @qdCount.to_s.center(len - 3) + "|\n"
|
300
|
+
str += del + "|" + @anCount.to_s.center(len - 3) + "|\n"
|
301
|
+
str += del + "|" + @nsCount.to_s.center(len - 3) + "|\n"
|
302
|
+
str += del + "|" + @arCount.to_s.center(len - 3) + "|\n" + del
|
314
303
|
str
|
315
304
|
end
|
316
305
|
|
@@ -323,8 +312,8 @@ module Net
|
|
323
312
|
def data
|
324
313
|
arr = []
|
325
314
|
arr.push(@id)
|
326
|
-
arr.push((@qr<<7)|(@opCode<<3)|(@aa<<2)|(@tc<<1)
|
327
|
-
arr.push((@ra<<7)|(@ad<<5)|(@cd<<4)
|
315
|
+
arr.push((@qr << 7) | (@opCode << 3) | (@aa << 2) | (@tc << 1) | @rd)
|
316
|
+
arr.push((@ra << 7) | (@ad << 5) | (@cd << 4) | @rCode.code)
|
328
317
|
arr.push(@qdCount)
|
329
318
|
arr.push(@anCount)
|
330
319
|
arr.push(@nsCount)
|
@@ -336,11 +325,9 @@ module Net
|
|
336
325
|
# performing security tests.
|
337
326
|
#
|
338
327
|
def id=(val)
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
raise ArgumentError, "ID `#{val}' out of range"
|
343
|
-
end
|
328
|
+
raise ArgumentError, "ID `#{val}' out of range" unless (0..65_535).cover? val
|
329
|
+
|
330
|
+
@id = val
|
344
331
|
end
|
345
332
|
|
346
333
|
# Checks whether the header is a query (+qr+ bit set to 0)
|
@@ -361,7 +348,7 @@ module Net
|
|
361
348
|
@qr = 1
|
362
349
|
when false
|
363
350
|
@qr = 0
|
364
|
-
when 0,1
|
351
|
+
when 0, 1
|
365
352
|
@qr = val
|
366
353
|
else
|
367
354
|
raise ArgumentError, ":qr must be true(or 1) or false(or 0)"
|
@@ -399,11 +386,9 @@ module Net
|
|
399
386
|
# header.opCode = Header::STATUS
|
400
387
|
#
|
401
388
|
def opCode=(val)
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
raise WrongOpcodeError, "Wrong opCode value (#{val}), must be QUERY, IQUERY or STATUS"
|
406
|
-
end
|
389
|
+
raise WrongOpcodeError, "Wrong opCode value (#{val}), must be QUERY, IQUERY or STATUS" unless (0..2).cover? val
|
390
|
+
|
391
|
+
@opCode = val
|
407
392
|
end
|
408
393
|
|
409
394
|
# Checks whether the response is authoritative
|
@@ -433,7 +418,7 @@ module Net
|
|
433
418
|
@aa = 1
|
434
419
|
when false
|
435
420
|
@aa = 0
|
436
|
-
when 0,1
|
421
|
+
when 0, 1
|
437
422
|
@aa = val
|
438
423
|
else
|
439
424
|
raise ArgumentError, ":aa must be true(or 1) or false(or 0)"
|
@@ -471,7 +456,7 @@ module Net
|
|
471
456
|
@tc = 1
|
472
457
|
when false
|
473
458
|
@tc = 0
|
474
|
-
when 0,1
|
459
|
+
when 0, 1
|
475
460
|
@tc = val
|
476
461
|
else
|
477
462
|
raise ArgumentError, ":tc must be true(or 1) or false(or 0)"
|
@@ -536,7 +521,7 @@ module Net
|
|
536
521
|
@ra = 1
|
537
522
|
when false
|
538
523
|
@ra = 0
|
539
|
-
when 0,1
|
524
|
+
when 0, 1
|
540
525
|
@ra = val
|
541
526
|
else
|
542
527
|
raise ArgumentError, ":ra must be true(or 1) or false(or 0)"
|
@@ -560,7 +545,7 @@ module Net
|
|
560
545
|
@cd = 1
|
561
546
|
when false
|
562
547
|
@cd = 0
|
563
|
-
when 0,1
|
548
|
+
when 0, 1
|
564
549
|
@cd = val
|
565
550
|
else
|
566
551
|
raise ArgumentError, ":cd must be true(or 1) or false(or 0)"
|
@@ -588,7 +573,7 @@ module Net
|
|
588
573
|
@ad = 1
|
589
574
|
when false
|
590
575
|
@ad = 0
|
591
|
-
when 0,1
|
576
|
+
when 0, 1
|
592
577
|
@ad = val
|
593
578
|
else
|
594
579
|
raise ArgumentError, ":ad must be true(or 1) or false(or 0)"
|
@@ -604,7 +589,7 @@ module Net
|
|
604
589
|
# #=> was unable to interpret the query
|
605
590
|
#
|
606
591
|
def rCode_str
|
607
|
-
|
592
|
+
[rCode.type, rCode.explanation]
|
608
593
|
end
|
609
594
|
|
610
595
|
# Checks for errors in the DNS packet
|
@@ -627,44 +612,36 @@ module Net
|
|
627
612
|
# Sets the number of entries in a question section
|
628
613
|
#
|
629
614
|
def qdCount=(val)
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
raise WrongCountError, "Wrong number of count (#{val}), must be 0-65535"
|
634
|
-
end
|
615
|
+
raise WrongCountError, "Wrong number of count (#{val}), must be 0-65535" unless (0..65_535).cover? val
|
616
|
+
|
617
|
+
@qdCount = val
|
635
618
|
end
|
636
619
|
|
637
620
|
# Sets the number of RRs in an answer section
|
638
621
|
#
|
639
622
|
def anCount=(val)
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
raise WrongCountError, "Wrong number of count (#{val}), must be 0-65535"
|
644
|
-
end
|
623
|
+
raise WrongCountError, "Wrong number of count (#{val}), must be 0-65535" unless (0..65_535).cover? val
|
624
|
+
|
625
|
+
@anCount = val
|
645
626
|
end
|
646
627
|
|
647
628
|
# Sets the number of RRs in an authority section
|
648
629
|
#
|
649
630
|
def nsCount=(val)
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
raise WrongCountError, "Wrong number of count (#{val}), must be 0-65535"
|
654
|
-
end
|
631
|
+
raise WrongCountError, "Wrong number of count (#{val}), must be 0-65535" unless (0..65_535).cover? val
|
632
|
+
|
633
|
+
@nsCount = val
|
655
634
|
end
|
656
635
|
|
657
636
|
# Sets the number of RRs in an addictional section
|
658
637
|
#
|
659
638
|
def arCount=(val)
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
raise WrongCountError, "Wrong number of count: `#{val}' must be 0-65535"
|
664
|
-
end
|
639
|
+
raise WrongCountError, "Wrong number of count: `#{val}' must be 0-65535" unless (0..65_535).cover? val
|
640
|
+
|
641
|
+
@arCount = val
|
665
642
|
end
|
666
643
|
|
667
|
-
|
644
|
+
private
|
668
645
|
|
669
646
|
def new_from_scratch
|
670
647
|
@id = genID # generate ad unique id
|
@@ -679,13 +656,14 @@ module Net
|
|
679
656
|
unless str.size == Net::DNS::HFIXEDSZ
|
680
657
|
raise ArgumentError, "Header binary data has wrong size: `#{str.size}' bytes"
|
681
658
|
end
|
659
|
+
|
682
660
|
arr = str.unpack("n C2 n4")
|
683
|
-
@id
|
661
|
+
@id = arr[0]
|
684
662
|
@qr = (arr[1] >> 7) & 0x01
|
685
663
|
@opCode = (arr[1] >> 3) & 0x0F
|
686
664
|
@aa = (arr[1] >> 2) & 0x01
|
687
665
|
@tc = (arr[1] >> 1) & 0x01
|
688
|
-
@rd
|
666
|
+
@rd = arr[1] & 0x1
|
689
667
|
@ra = (arr[2] >> 7) & 0x01
|
690
668
|
@ad = (arr[2] >> 5) & 0x01
|
691
669
|
@cd = (arr[2] >> 4) & 0x01
|
@@ -698,16 +676,14 @@ module Net
|
|
698
676
|
|
699
677
|
def new_from_hash(hash)
|
700
678
|
new_from_scratch
|
701
|
-
hash.each do |key,val|
|
702
|
-
eval "self.#{key
|
679
|
+
hash.each do |key, val|
|
680
|
+
eval "self.#{key} = val"
|
703
681
|
end
|
704
682
|
end
|
705
683
|
|
706
684
|
def genID
|
707
|
-
rand(
|
685
|
+
rand(65_535)
|
708
686
|
end
|
709
|
-
|
710
687
|
end
|
711
|
-
|
712
688
|
end
|
713
689
|
end
|
data/lib/net/dns/names.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
module Net # :nodoc:
|
2
2
|
module DNS
|
3
|
-
|
4
3
|
module Names
|
5
|
-
|
6
4
|
# Base error class.
|
7
5
|
class Error < StandardError
|
8
6
|
end
|
@@ -11,11 +9,10 @@ module Net # :nodoc:
|
|
11
9
|
class ExpandError < Error
|
12
10
|
end
|
13
11
|
|
14
|
-
|
15
12
|
INT16SZ = 2
|
16
13
|
|
17
14
|
# Expand a compressed name in a DNS Packet object. Please
|
18
|
-
# see
|
15
|
+
# see RFC1035 for an explanation of how the compression
|
19
16
|
# in DNS packets works, how may it be useful and how should
|
20
17
|
# be handled.
|
21
18
|
#
|
@@ -23,29 +20,33 @@ module Net # :nodoc:
|
|
23
20
|
# offset, which indicates the point in the packet in which the
|
24
21
|
# parsing has arrived.
|
25
22
|
#
|
26
|
-
def dn_expand(packet,offset)
|
23
|
+
def dn_expand(packet, offset)
|
27
24
|
name = ""
|
28
25
|
packetlen = packet.size
|
29
|
-
|
30
|
-
raise ExpandError, "Offset is greater than packet
|
31
|
-
|
26
|
+
loop do
|
27
|
+
raise ExpandError, "Offset is greater than packet length!" if packetlen < (offset + 1)
|
28
|
+
|
29
|
+
len = packet.unpack1("@#{offset} C")
|
32
30
|
|
33
31
|
if len == 0
|
34
32
|
offset += 1
|
35
33
|
break
|
36
34
|
elsif (len & 0xC0) == 0xC0
|
37
|
-
raise ExpandError, "Packet ended before offset expand" if packetlen < (offset+INT16SZ)
|
38
|
-
|
35
|
+
raise ExpandError, "Packet ended before offset expand" if packetlen < (offset + INT16SZ)
|
36
|
+
|
37
|
+
ptr = packet.unpack1("@#{offset} n")
|
39
38
|
ptr &= 0x3FFF
|
40
|
-
name2 = dn_expand(packet,ptr)[0]
|
41
|
-
raise ExpandError, "Packet is malformed!" if name2
|
39
|
+
name2 = dn_expand(packet, ptr)[0]
|
40
|
+
raise ExpandError, "Packet is malformed!" if name2.nil?
|
41
|
+
|
42
42
|
name += name2
|
43
43
|
offset += INT16SZ
|
44
44
|
break
|
45
45
|
else
|
46
46
|
offset += 1
|
47
|
-
raise ExpandError, "No expansion found" if packetlen < (offset+len)
|
48
|
-
|
47
|
+
raise ExpandError, "No expansion found" if packetlen < (offset + len)
|
48
|
+
|
49
|
+
elem = packet[offset..offset + len - 1]
|
49
50
|
name += "#{elem}."
|
50
51
|
offset += len
|
51
52
|
end
|
@@ -54,16 +55,18 @@ module Net # :nodoc:
|
|
54
55
|
end
|
55
56
|
|
56
57
|
def pack_name(name)
|
57
|
-
if name.size > 255
|
58
|
+
if name.size > 255
|
58
59
|
raise ArgumentError, "Name may not exceed 255 chars"
|
59
60
|
end
|
61
|
+
|
60
62
|
arr = name.split(".")
|
61
63
|
str = ""
|
62
64
|
arr.each do |elem|
|
63
65
|
if elem.size > 63
|
64
66
|
raise ArgumentError, "Label may not exceed 63 chars"
|
65
67
|
end
|
66
|
-
|
68
|
+
|
69
|
+
str += [elem.size, elem].pack("Ca*")
|
67
70
|
end
|
68
71
|
str += [0].pack("C")
|
69
72
|
str
|
@@ -74,45 +77,42 @@ module Net # :nodoc:
|
|
74
77
|
ar = []
|
75
78
|
string = ""
|
76
79
|
arr.size.times do |i|
|
77
|
-
x = i+1
|
80
|
+
x = i + 1
|
78
81
|
elem = arr[-x]
|
79
82
|
len = elem.size
|
80
|
-
string = (
|
83
|
+
string = (string.reverse + [len, elem].pack("Ca*").reverse).reverse
|
81
84
|
ar.unshift(string)
|
82
85
|
end
|
83
|
-
|
86
|
+
ar
|
84
87
|
end
|
85
88
|
|
86
|
-
def dn_comp(name,offset,compnames)
|
89
|
+
def dn_comp(name, offset, compnames)
|
87
90
|
names = {}
|
88
91
|
ptr = 0
|
89
92
|
str = ""
|
90
93
|
arr = names_array(name)
|
91
94
|
arr.each do |entry|
|
92
|
-
if compnames.
|
95
|
+
if compnames.key?(entry)
|
93
96
|
ptr = 0xC000 | compnames[entry]
|
94
97
|
str += [ptr].pack("n")
|
95
98
|
offset += INT16SZ
|
96
99
|
break
|
97
100
|
else
|
98
|
-
len = entry.
|
101
|
+
len = entry.unpack1("C")
|
99
102
|
elem = entry[1..len]
|
100
|
-
str += [len,elem].pack("Ca*")
|
101
|
-
names.update(
|
103
|
+
str += [len, elem].pack("Ca*")
|
104
|
+
names.update(entry.to_s => offset)
|
102
105
|
offset += len
|
103
106
|
end
|
104
107
|
end
|
105
|
-
|
108
|
+
[str, offset, names]
|
106
109
|
end
|
107
110
|
|
108
111
|
def valid?(name)
|
109
|
-
|
110
|
-
return name
|
111
|
-
else
|
112
|
-
raise ArgumentError, "Invalid FQDN: #{name}"
|
113
|
-
end
|
114
|
-
end
|
112
|
+
raise ArgumentError, "Invalid FQDN: #{name}" unless name =~ /^([a-z0-9]([-a-z0-9]*[a-z0-9])?\.)+((a[cdefgilmnoqrstuwxz]|aero|arpa)|(b[abdefghijmnorstvwyz]|biz)|(c[acdfghiklmnorsuvxyz]|cat|com|coop)|d[ejkmoz]|(e[ceghrstu]|edu)|f[ijkmor]|(g[abdefghilmnpqrstuwy]|gov)|h[kmnrtu]|(i[delmnoqrst]|info|int)|(j[emop]|jobs)|k[eghimnprwyz]|l[abcikrstuvy]|(m[acdghklmnopqrstuvwxyz]|mil|mobi|museum)|(n[acefgilopruz]|name|net)|(om|org)|(p[aefghklmnrstwy]|pro)|qa|r[eouw]|s[abcdeghijklmnortvyz]|(t[cdfghjklmnoprtvwz]|travel)|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw])$/i
|
115
113
|
|
114
|
+
name
|
115
|
+
end
|
116
116
|
end
|
117
117
|
end
|
118
118
|
end
|