| Class | Resolv::DNS |
| In: |
lib/resolv.rb
|
| Parent: | Object |
| Port | = | 53 | STD0013 (RFC 1035, etc.) ftp.isi.edu/in-notes/iana/assignments/dns-parameters | |
| UDPSize | = | 512 | ||
| DNSThreadGroup | = | ThreadGroup.new |
# File lib/resolv.rb, line 381
381: def initialize(config_info=nil)
382: @mutex = Mutex.new
383: @config = Config.new(config_info)
384: @initialized = nil
385: end
# File lib/resolv.rb, line 371
371: def self.open(*args)
372: dns = new(*args)
373: return dns unless block_given?
374: begin
375: yield dns
376: ensure
377: dns.close
378: end
379: end
# File lib/resolv.rb, line 404
404: def close
405: @mutex.synchronize {
406: if @initialized
407: @requester.close if @requester
408: @requester = nil
409: @initialized = false
410: end
411: }
412: end
# File lib/resolv.rb, line 425
425: def each_address(name)
426: each_resource(name, Resource::IN::A) {|resource| yield resource.address}
427: end
# File lib/resolv.rb, line 440
440: def each_name(address)
441: case address
442: when Name
443: ptr = address
444: when IPv4::Regex
445: ptr = IPv4.create(address).to_name
446: when IPv6::Regex
447: ptr = IPv6.create(address).to_name
448: else
449: raise ResolvError.new("cannot interpret as address: #{address}")
450: end
451: each_resource(ptr, Resource::IN::PTR) {|resource| yield resource.name}
452: end
# File lib/resolv.rb, line 465
465: def each_resource(name, typeclass, &proc)
466: lazy_initialize
467: q = Queue.new
468: senders = {}
469: begin
470: @config.resolv(name) {|candidate, tout, nameserver|
471: msg = Message.new
472: msg.rd = 1
473: msg.add_question(candidate, typeclass)
474: unless sender = senders[[candidate, nameserver]]
475: sender = senders[[candidate, nameserver]] =
476: @requester.sender(msg, candidate, q, nameserver)
477: end
478: sender.send
479: reply = reply_name = nil
480: timeout(tout, ResolvTimeout) { reply, reply_name = q.pop }
481: case reply.rcode
482: when RCode::NoError
483: extract_resources(reply, reply_name, typeclass, &proc)
484: return
485: when RCode::NXDomain
486: raise Config::NXDomain.new(reply_name.to_s)
487: else
488: raise Config::OtherResolvError.new(reply_name.to_s)
489: end
490: }
491: ensure
492: @requester.delete(q)
493: end
494: end
# File lib/resolv.rb, line 496
496: def extract_resources(msg, name, typeclass)
497: if typeclass < Resource::ANY
498: n0 = Name.create(name)
499: msg.each_answer {|n, ttl, data|
500: yield data if n0 == n
501: }
502: end
503: yielded = false
504: n0 = Name.create(name)
505: msg.each_answer {|n, ttl, data|
506: if n0 == n
507: case data
508: when typeclass
509: yield data
510: yielded = true
511: when Resource::CNAME
512: n0 = data.name
513: end
514: end
515: }
516: return if yielded
517: msg.each_answer {|n, ttl, data|
518: if n0 == n
519: case data
520: when typeclass
521: yield data
522: end
523: end
524: }
525: end
# File lib/resolv.rb, line 414
414: def getaddress(name)
415: each_address(name) {|address| return address}
416: raise ResolvError.new("DNS result has no information for #{name}")
417: end
# File lib/resolv.rb, line 419
419: def getaddresses(name)
420: ret = []
421: each_address(name) {|address| ret << address}
422: return ret
423: end
# File lib/resolv.rb, line 429
429: def getname(address)
430: each_name(address) {|name| return name}
431: raise ResolvError.new("DNS result has no information for #{address}")
432: end
# File lib/resolv.rb, line 434
434: def getnames(address)
435: ret = []
436: each_name(address) {|name| ret << name}
437: return ret
438: end
# File lib/resolv.rb, line 454
454: def getresource(name, typeclass)
455: each_resource(name, typeclass) {|resource| return resource}
456: raise ResolvError.new("DNS result has no information for #{name}")
457: end
# File lib/resolv.rb, line 459
459: def getresources(name, typeclass)
460: ret = []
461: each_resource(name, typeclass) {|resource| ret << resource}
462: return ret
463: end
# File lib/resolv.rb, line 387
387: def lazy_initialize
388: @mutex.synchronize {
389: unless @initialized
390: @config.lazy_initialize
391:
392: if nameserver = @config.single?
393: @requester = Requester::ConnectedUDP.new(nameserver)
394: else
395: @requester = Requester::UnconnectedUDP.new
396: end
397:
398: @initialized = true
399: end
400: }
401: self
402: end