Module: RubyDNS

Defined in:
lib/rubydns/version.rb,
lib/rubydns.rb,
lib/rubydns/server.rb,
lib/rubydns/handler.rb,
lib/rubydns/transaction.rb

Overview

Copyright © 2009 Samuel Williams. Released under the GNU GPLv3.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see <www.gnu.org/licenses/>.

Defined Under Namespace

Modules: TCPHandler, UDPHandler, VERSION Classes: LengthError, Server, Transaction

Constant Summary collapse

UDP_TRUNCATION_SIZE =
512

Class Method Summary collapse

Class Method Details

.constantize(names) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/rubydns/transaction.rb', line 37

def self.constantize(names)
	top = Object

	names.each do |name|
		if top.const_defined?(name)
			top = top.const_get(name)
		else
			return nil
		end
	end

	top
end

.find_constant(top, klass) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/rubydns/transaction.rb', line 51

def self.find_constant(top, klass)
	names = top.name.split("::")

	while names.size
		object = self.constantize(names + klass)
	
		return object if object
	
		names.pop
	end

	return nil
end

.lookup_resource_class(klass, top = nil) ⇒ Object

Turn a symbol or string name into a resource class. For example, convert :A into Resolv::DNS::Resource::IN::A Provide a second argument (top) to specify a namespace where klass should be resolved, e.g. Resolv::DNS::Resource::IN.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/rubydns/transaction.rb', line 22

def self.lookup_resource_class(klass, top = nil)
	return nil if klass == nil
	
	if Symbol === klass
		klass = klass.to_s
	end
	
	if String === klass
		top ||= Resolv::DNS::Resource::IN
		klass = self.find_constant(top, klass.split("::"))
	end
	
	return klass
end

.run_server(options = {}, &block) ⇒ Object

Run a server with the given rules. A number of options can be supplied:

:interfaces

A set of sockets or addresses as defined below.

One important feature of DNS is the port it runs on. The options[:listen] allows you to specify a set of network interfaces and ports to run the server on. This must be a list of [protocol, interface address, port].

INTERFACES = [[:udp, "0.0.0.0", 5300]]
RubyDNS::run_server(:listen => INTERFACES) do
  ...
end

You can specify already connected sockets if need be:

socket = UDPSocket.new; socket.bind("0.0.0.0", 53)
Process::Sys.setuid(server_uid)
INTERFACES = [socket]

The default interface is [[:udp, "0.0.0.0", 53]]. The server typically needs to run as root for this to work, since port 53 is privileged.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/rubydns.rb', line 54

def self.run_server (options = {}, &block)
	server = RubyDNS::Server.new(&block)
	server.logger.info "Starting server..."
	
	options[:listen] ||= [[:udp, "0.0.0.0", 53], [:tcp, "0.0.0.0", 53]]
	
	EventMachine.run do
		server.fire(:setup)
		
		# Setup server sockets
		options[:listen].each do |spec|
			server.logger.info "Listening on #{spec.join(':')}"
			if spec[0] == :udp
				EventMachine.open_datagram_socket(spec[1], spec[2], UDPHandler, server)
			elsif spec[0] == :tcp
				EventMachine.start_server(spec[1], spec[2], TCPHandler, server)
			end
		end
		
		server.fire(:start)
	end
	
	server.fire(:stop)
end