faildns 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. data/bin/failnamed +203 -0
  2. data/bin/failresolve +37 -0
  3. data/lib/faildns.rb +20 -0
  4. data/lib/faildns/class.rb +96 -0
  5. data/lib/faildns/client.rb +114 -0
  6. data/lib/faildns/common.rb +52 -0
  7. data/lib/faildns/domainname.rb +223 -0
  8. data/lib/faildns/header.rb +254 -0
  9. data/lib/faildns/header/opcode.rb +95 -0
  10. data/lib/faildns/header/status.rb +123 -0
  11. data/lib/faildns/header/type.rb +72 -0
  12. data/lib/faildns/ip.rb +57 -0
  13. data/lib/faildns/message.rb +100 -0
  14. data/lib/faildns/qclass.rb +51 -0
  15. data/lib/faildns/qtype.rb +60 -0
  16. data/lib/faildns/question.rb +101 -0
  17. data/lib/faildns/resourcerecord.rb +140 -0
  18. data/lib/faildns/resourcerecord/IN.rb +29 -0
  19. data/lib/faildns/resourcerecord/IN/A.rb +75 -0
  20. data/lib/faildns/resourcerecord/IN/AAAA.rb +77 -0
  21. data/lib/faildns/resourcerecord/IN/CNAME.rb +70 -0
  22. data/lib/faildns/resourcerecord/IN/HINFO.rb +79 -0
  23. data/lib/faildns/resourcerecord/IN/MX.rb +75 -0
  24. data/lib/faildns/resourcerecord/IN/NS.rb +77 -0
  25. data/lib/faildns/resourcerecord/IN/NULL.rb +66 -0
  26. data/lib/faildns/resourcerecord/IN/PTR.rb +69 -0
  27. data/lib/faildns/resourcerecord/IN/SOA.rb +128 -0
  28. data/lib/faildns/resourcerecord/IN/TXT.rb +63 -0
  29. data/lib/faildns/resourcerecord/data.rb +41 -0
  30. data/lib/faildns/server.rb +71 -0
  31. data/lib/faildns/server/dispatcher.rb +181 -0
  32. data/lib/faildns/server/dispatcher/connectiondispatcher.rb +93 -0
  33. data/lib/faildns/server/dispatcher/event.rb +47 -0
  34. data/lib/faildns/server/dispatcher/eventdispatcher.rb +73 -0
  35. data/lib/faildns/server/dispatcher/socket.rb +93 -0
  36. data/lib/faildns/type.rb +186 -0
  37. metadata +100 -0
@@ -0,0 +1,69 @@
1
+ #--
2
+ # Copyleft meh. [http://meh.doesntexist.org | meh@paranoici.org]
3
+ #
4
+ # This file is part of faildns.
5
+ #
6
+ # faildns is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # faildns is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with faildns. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+ require 'faildns/resourcerecord/data'
21
+
22
+ module DNS
23
+
24
+ class ResourceRecord
25
+
26
+ module IN
27
+
28
+ #--
29
+ # +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
30
+ # / PTRDNAME /
31
+ # +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
32
+ #
33
+ # where:
34
+ #
35
+ # PTRDNAME A <domain-name> which points to some location in the
36
+ # domain name space.
37
+ #
38
+ # PTR records cause no additional section processing. These RRs are used
39
+ # in special domains to point to some other location in the domain space.
40
+ # These records are simple data, and don't imply any special processing
41
+ # similar to that performed by CNAME, which identifies aliases. See the
42
+ # description of the IN-ADDR.ARPA domain for an example.
43
+ #++
44
+
45
+ class PTR < Data
46
+ def self._parse (string, original)
47
+ PTR.new(DomainName.parse(string.clone, original))
48
+ end
49
+
50
+ attr_reader :domain
51
+
52
+ def initialize (domain)
53
+ @domain = domain
54
+ end
55
+
56
+ def pack
57
+ @domain.pack
58
+ end
59
+
60
+ def to_s
61
+ @domain.to_s
62
+ end
63
+ end
64
+
65
+ end
66
+
67
+ end
68
+
69
+ end
@@ -0,0 +1,128 @@
1
+ #--
2
+ # Copyleft meh. [http://meh.doesntexist.org | meh@paranoici.org]
3
+ #
4
+ # This file is part of faildns.
5
+ #
6
+ # faildns is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # faildns is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with faildns. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+ require 'faildns/resourcerecord/data'
21
+
22
+ module DNS
23
+
24
+ class ResourceRecord
25
+
26
+ module IN
27
+
28
+ #--
29
+ # +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
30
+ # / MNAME /
31
+ # / /
32
+ # +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
33
+ # / RNAME /
34
+ # +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
35
+ # | SERIAL |
36
+ # | |
37
+ # +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
38
+ # | REFRESH |
39
+ # | |
40
+ # +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
41
+ # | RETRY |
42
+ # | |
43
+ # +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
44
+ # | EXPIRE |
45
+ # | |
46
+ # +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
47
+ # | MINIMUM |
48
+ # | |
49
+ # +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
50
+ #
51
+ # where:
52
+ #
53
+ # MNAME The <domain-name> of the name server that was the
54
+ # original or primary source of data for this zone.
55
+ #
56
+ # RNAME A <domain-name> which specifies the mailbox of the
57
+ # person responsible for this zone.
58
+ #
59
+ # SERIAL The unsigned 32 bit version number of the original copy
60
+ # of the zone. Zone transfers preserve this value. This
61
+ # value wraps and should be compared using sequence space
62
+ # arithmetic.
63
+ #
64
+ # REFRESH A 32 bit time interval before the zone should be
65
+ # refreshed.
66
+ #
67
+ # RETRY A 32 bit time interval that should elapse before a
68
+ # failed refresh should be retried.
69
+ #
70
+ # EXPIRE A 32 bit time value that specifies the upper limit on
71
+ # the time interval that can elapse before the zone is no
72
+ # longer authoritative.
73
+ #
74
+ # MINIMUM The unsigned 32 bit minimum TTL field that should be
75
+ # exported with any RR from this zone.
76
+ #
77
+ # SOA records cause no additional section processing.
78
+ #
79
+ # All times are in units of seconds.
80
+ #
81
+ # Most of these fields are pertinent only for name server maintenance
82
+ # operations. However, MINIMUM is used in all query operations that
83
+ # retrieve RRs from a zone. Whenever a RR is sent in a response to a
84
+ # query, the TTL field is set to the maximum of the TTL field from the RR
85
+ # and the MINIMUM field in the appropriate SOA. Thus MINIMUM is a lower
86
+ # bound on the TTL field for all RRs in a zone. Note that this use of
87
+ # MINIMUM should occur when the RRs are copied into the response and not
88
+ # when the zone is loaded from a master file or via a zone transfer. The
89
+ # reason for this provison is to allow future dynamic update facilities to
90
+ # change the SOA RR with known semantics.
91
+ #++
92
+
93
+ class SOA < Data
94
+ def self._parse (string, original)
95
+ result = {}
96
+
97
+ result[:MNAME] = DomainName.parse(string, original)
98
+ result[:RNAME] = DomainName.parse(string, original)
99
+
100
+ result[:SERIAL] = string.unpack('N'); string[0, 4] = ''
101
+ result[:REFRESH] = string.unpack('N'); string[0, 4] = ''
102
+ result[:RETRY] = string.unpack('N'); string[0, 4] = ''
103
+ result[:EXPIRE] = string.unpack('N'); string[0, 4] = ''
104
+ result[:MINIMUM] = string.unpack('N'); string[0, 4] = ''
105
+
106
+ SOA.new(result)
107
+ end
108
+
109
+ def initialize (data)
110
+ @data = data
111
+ end
112
+
113
+ def [] (name)
114
+ @data[name]
115
+ end
116
+
117
+ def pack
118
+ result[:MNAME].pack + result[:RNAME].pack + [result[:SERIAL]].pack('N') +
119
+ [result[:REFRESH]].pack('N') + [result[:RETRY]].pack('N') + [result[:EXPIRE]].pack('N') +
120
+ [result[:MINIMUM]].pack('N')
121
+ end
122
+ end
123
+
124
+ end
125
+
126
+ end
127
+
128
+ end
@@ -0,0 +1,63 @@
1
+ #--
2
+ # Copyleft meh. [http://meh.doesntexist.org | meh@paranoici.org]
3
+ #
4
+ # This file is part of faildns.
5
+ #
6
+ # faildns is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # faildns is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with faildns. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+ require 'faildns/resourcerecord/data'
21
+
22
+ module DNS
23
+
24
+ class ResourceRecord
25
+
26
+ module IN
27
+
28
+ #--
29
+ # +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
30
+ # / TXT-DATA /
31
+ # +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
32
+ #
33
+ # where:
34
+ #
35
+ # TXT-DATA One or more <character-string>s.
36
+ #
37
+ # TXT RRs are used to hold descriptive text. The semantics of the text
38
+ # depends on the domain where it is found.
39
+ #++
40
+
41
+ class TXT < Data
42
+ def self._parse (string, original)
43
+ data = []
44
+
45
+ while !string.empty?
46
+ data.push(string[1, (tmp = string.unpack('C'))]); string[0, tmp + 1] = ''
47
+ end
48
+
49
+ TXT.new(data)
50
+ end
51
+
52
+ attr_reader :data
53
+
54
+ def initialize (data)
55
+ @data = data
56
+ end
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+
63
+ end
@@ -0,0 +1,41 @@
1
+ #--
2
+ # Copyleft meh. [http://meh.doesntexist.org | meh@paranoici.org]
3
+ #
4
+ # This file is part of faildns.
5
+ #
6
+ # faildns is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # faildns is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with faildns. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+ module DNS
21
+
22
+ class ResourceRecord
23
+
24
+ class Data
25
+ def self.parse (string, length, original)
26
+ string.force_encoding 'BINARY'
27
+
28
+ data = string[0, length]; string[0, length] = ''
29
+
30
+ self._parse(data, original)
31
+ end
32
+
33
+ private
34
+
35
+ def initialize
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,71 @@
1
+ #--
2
+ # Copyleft meh. [http://meh.doesntexist.org | meh@paranoici.org]
3
+ #
4
+ # This file is part of faildns.
5
+ #
6
+ # faildns is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # faildns is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with faildns. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+ require 'faildns/common'
21
+ require 'faildns/server/dispatcher'
22
+
23
+ module DNS
24
+
25
+ class Server
26
+ attr_reader :options, :dispatcher
27
+
28
+ def initialize (options={})
29
+ if !options.is_a? Hash
30
+ raise ArgumentError.new('You have to pass a Hash')
31
+ end
32
+
33
+ @options = options
34
+
35
+ @dispatcher = Dispatcher.new(self)
36
+
37
+ if block_given?
38
+ yield self
39
+ end
40
+ end
41
+
42
+ def start
43
+ if @started
44
+ return
45
+ end
46
+
47
+ @started = true
48
+
49
+ @dispatcher.start
50
+ end
51
+
52
+ def stopping
53
+ @stopping = true
54
+
55
+ @dispatcher.stop
56
+ end
57
+
58
+ def register (*args)
59
+ @dispatcher.event.register(*args)
60
+ end
61
+
62
+ def observe (*args)
63
+ @dispatcher.event.observe(*args)
64
+ end
65
+
66
+ def fire (*args)
67
+ @dispatcher.event.fire(*args)
68
+ end
69
+ end
70
+
71
+ end
@@ -0,0 +1,181 @@
1
+ #--
2
+ # Copyleft meh. [http://meh.doesntexist.org | meh@paranoici.org]
3
+ #
4
+ # This file is part of faildns.
5
+ #
6
+ # faildns is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # faildns is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with faildns. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+ require 'faildns/server/dispatcher/connectiondispatcher'
21
+ require 'faildns/server/dispatcher/eventdispatcher'
22
+
23
+ module DNS
24
+
25
+ class Server
26
+
27
+ class Dispatcher
28
+ attr_reader :server, :connection, :event
29
+
30
+ def initialize (server)
31
+ @server = server
32
+
33
+ @connection = ConnectionDispatcher.new(self)
34
+ @event = EventDispatcher.new(self)
35
+
36
+ @intervals = {}
37
+ @timeouts = {}
38
+ end
39
+
40
+ def start
41
+ @connection.start
42
+
43
+ @started = true
44
+
45
+ @defaults = [Fiber.new {
46
+ while true
47
+ @connection.read
48
+
49
+ Fiber.yield
50
+ end
51
+ }]
52
+
53
+ self.loop
54
+ end
55
+
56
+ def stop
57
+ if !@started
58
+ return
59
+ end
60
+
61
+ @started = false
62
+ @stopping = true
63
+
64
+ @event.finalize
65
+ @connection.finalize
66
+
67
+ @stopping = false
68
+ end
69
+
70
+ def loop
71
+ while true
72
+ @defaults.each {|fiber|
73
+ begin
74
+ fiber.resume
75
+ rescue FiberError
76
+ DNS.debug 'Something went deeply wrong in the dispatcher, aborting.'
77
+ Process::exit 23
78
+ rescue Exception => e
79
+ DNS.debug e
80
+ end
81
+ }
82
+
83
+ @intervals.each {|fiber, meta|
84
+ begin
85
+ if !@intervals[fiber]
86
+ raise FiberError
87
+ end
88
+
89
+ if meta[:at] <= Time.now
90
+ fiber.resume
91
+
92
+ meta[:at] += meta[:offset]
93
+ end
94
+ rescue FiberError
95
+ clearInterval meta
96
+ rescue Exception => e
97
+ DNS.debug e
98
+ end
99
+ }
100
+
101
+ @timeouts.each {|fiber, meta|
102
+ begin
103
+ if !@timeouts[fiber]
104
+ raise FiberError
105
+ end
106
+
107
+ if meta[:at] <= Time.now
108
+ fiber.resume
109
+
110
+ clearTimeout meta
111
+ end
112
+ rescue FiberError
113
+ clearTimeout meta
114
+ rescue Exception => e
115
+ DNS.debug e
116
+ end
117
+ }
118
+ end
119
+ end
120
+
121
+ def setTimeout (fiber, time)
122
+ @timeouts[fiber] = {
123
+ :fiber => fiber,
124
+ :at => Time.now + time,
125
+ :on => Time.now,
126
+ }
127
+ end
128
+
129
+ def clearTimeout (timeout)
130
+ @timeouts.delete(timeout[:fiber])
131
+ end
132
+
133
+ def setInterval (fiber, time)
134
+ @intervals[fiber] = {
135
+ :fiber => fiber,
136
+ :offset => time,
137
+ :at => Time.now + time,
138
+ :on => Time.now,
139
+ }
140
+ end
141
+
142
+ def clearInterval (interval)
143
+ @intervals.delete(interval[:fiber])
144
+ end
145
+
146
+ def connections
147
+ @connection.connections
148
+ end
149
+
150
+ def input
151
+ @connection.input
152
+ end
153
+
154
+ def output
155
+ @connection.output
156
+ end
157
+
158
+ def disconnecting
159
+ @connection.disconnecting
160
+ end
161
+
162
+ def alias (*args)
163
+ @event.alias(*args)
164
+ end
165
+
166
+ def register (*args)
167
+ @event.register(*args)
168
+ end
169
+
170
+ def dispatch (*args)
171
+ @event.dispatch(*args)
172
+ end
173
+
174
+ def execute (*args)
175
+ @event.execute(*args)
176
+ end
177
+ end
178
+
179
+ end
180
+
181
+ end