wamupd 1.1.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.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ pkg
data/CHANGELOG.md ADDED
File without changes
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Jonathan Walker
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,97 @@
1
+ Wamupd
2
+ ======
3
+
4
+ Introduction
5
+ ------------
6
+
7
+ Wamupd was originally created by roguelazer - for the original application,
8
+ see http://www.roguelazer.com/code/wamupd/. This version is primarily forked
9
+ to support the stable versions of Ruby (1.9), mDNSResponder (258.18),
10
+ Avahi (0.6.29), D-Bus (1.4.6), and FreeBSD (8.2) at the time of writing. It
11
+ also fixes some threading issues, adds logging, rc.d support, and FreeBSD
12
+ packaging.
13
+
14
+ Requirements
15
+ ------------
16
+
17
+ * ruby19
18
+ * ruby-dbus *(see my fork on [GitHub](https://github.com/johnnywalker/ruby-dbus))*
19
+ * algorithms
20
+ * rubygems
21
+ * dnsruby
22
+ * logger
23
+
24
+ ruby-dbus v0.6.0 does _not_ work properly on FreeBSD due to a problem with the
25
+ initial null byte sent to D-Bus for unix socket authentication. FreeBSD
26
+ supports the SCM\_CREDS socket option, so a simple patch is required.
27
+
28
+ Installing
29
+ ----------
30
+
31
+ After cloning this repository, use gmake to create the wamupd package and then
32
+ install the resulting file:
33
+
34
+ git clone https://github.com/johnnywalker/wamupd
35
+ cd wamupd
36
+ gmake
37
+ sudo pkg_add wamupd.tbz
38
+
39
+ Once installed, create the configuration file using the distribution template
40
+ and enable the wamupd service in your /etc/rc.conf:
41
+
42
+ cd /usr/local/etc/
43
+ sudo cp wamupd.yaml.dist wamupd.yaml
44
+ sudo vim wamupd.yaml (edit appropriately)
45
+ sudo echo wamupd_enable="YES" >>/etc/rc.conf
46
+ sudo service wamupd start
47
+
48
+ Specify custom arguments to wamupd as needed using the wamupd\_flags entry in
49
+ /etc/rc.conf. In order to get more information on the arguments available, try this:
50
+
51
+ sudo service wamupd stop
52
+ sudo /usr/local/sbin/wamupd run -- -h
53
+
54
+ The default flags used are:
55
+
56
+ wamupd_flags="-c /usr/local/etc/wamupd.yaml -A /usr/local/etc/avahi/services -a -i"
57
+
58
+ A log is created at /var/log/wamupd.log, but this only contains small amounts
59
+ of information. In order to debug your configuration, make sure the service
60
+ isn't running and then execute the /usr/local/sbin/wamupd program in the
61
+ foreground (note: the typical arguments used are "-A -a -i" - the "--" separates
62
+ the daemon command from the script arguments):
63
+
64
+ sudo service wamupd stop
65
+ sudo /usr/local/sbin/wamupd run -- -A -a -i
66
+
67
+ To uninstall, simply use pkg_delete:
68
+
69
+ sudo pkg_delete wamupd
70
+
71
+ Usage
72
+ -----
73
+
74
+ Usage: wamupd run -- [options] service-file
75
+ -c, --config FILE Get configuration data from FILE
76
+ If FILE is not provided, defaults to /usr/local/etc/wamupd.yaml
77
+ -A, --avahi-services [DIRECTORY] Load Avahi service definitions from DIRECTORY
78
+ If DIRECTORY is not provided, defaults to /usr/local/etc/avahi/services
79
+ If the -A flag is omitted altogether, static records will not be added.
80
+ -i, --[no-]ip-addresses Enable/Disable Publishing A and AAAA records
81
+ -a, --avahi Load Avahi services over D-BUS
82
+ -h, --help Show this message
83
+
84
+ Configuration
85
+ -------------
86
+
87
+ Make a wamupd.yaml file in /usr/local/etc/ in normal YAML style. Available
88
+ parameters include:
89
+ - hostname: the hostname of this machine
90
+ - zone: the zone to write to
91
+ - dns\_server: the dns server that controls the above zone
92
+ - dns\_port: the port to talk to
93
+ - dnssec\_key\_name: the key name for DNSSEC. Do not specify if you're
94
+ not using DNSSEC
95
+ - dnssec\_key\_hmac: the key value for DNSSEC.
96
+ - ttl: the standard TTL to use.
97
+ - transport: either "tcp" or "udp"
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ gemspec = eval(File.read(Dir["*.gemspec"].first))
2
+
3
+
4
+ desc "Validate the gemspec"
5
+ task :gemspec do
6
+ gemspec.validate
7
+ end
8
+
9
+ desc "Build gem locally"
10
+ task :build => :gemspec do
11
+ system "gem build #{gemspec.name}.gemspec"
12
+ FileUtils.mkdir_p "pkg"
13
+ FileUtils.mv "#{gemspec.name}-#{gemspec.version}.gem", "pkg"
14
+ end
15
+
16
+ desc "Install gem locally"
17
+ task :install => :build do
18
+ system "gem install pkg/#{gemspec.name}-#{gemspec.version}"
19
+ end
20
+
21
+ desc "Clean automatically generated files"
22
+ task :clean do
23
+ FileUtils.rm_rf "pkg"
24
+ end
data/bin/wamupd ADDED
@@ -0,0 +1,314 @@
1
+ #!/usr/local/bin/ruby
2
+ # Copyright (C) 2009-2010 James Brown <roguelazer@roguelazer.com>.
3
+ #
4
+ # This file is part of wamupd.
5
+ #
6
+ # wamupd is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # wamupd 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 General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with wamupd. If not, see <http://www.gnu.org/licenses/>.
18
+ #
19
+ # == Synopsis
20
+ #
21
+ # wamupd: Read avahi service descriptions and current IP information, then
22
+ # use that information to generate Wide-Area mDNS Updates
23
+ #
24
+ # == Usage
25
+ #
26
+ # wamupd service-file
27
+ #
28
+ # -a, --avahi
29
+ # Load Avahi services over D-BUS
30
+ # -A DIRECTORY, --avahi-services DIRECTORY
31
+ # Load Avahi service definitions from DIRECTORY
32
+ # If DIRECTORY is not provided, defaults to /etc/avahi/services
33
+ # If the -A flag is omitted altogether, static records will not be added.
34
+ # -c FILE, --config FILE:
35
+ # Get configuration data from FILE
36
+ # -i, --ip-addreses (or --no-ip-addresses)
37
+ # Enable/Disable Publishing A and AAAA records
38
+ # -h, --help:
39
+ # Show this help
40
+
41
+ require 'rubygems'
42
+ require 'daemons'
43
+
44
+ options = {
45
+ :dir_mode => :system,
46
+ :multiple => false,
47
+ }
48
+
49
+ Daemons.run_proc('wamupd', options) do
50
+
51
+ require "wamupd"
52
+ require "getoptlong"
53
+ require "optparse"
54
+ require "singleton"
55
+ require "timeout"
56
+ require "logger"
57
+
58
+ # Wamupd is a module that is used to namespace all of the wamupd code.
59
+ module Wamupd
60
+ DEFAULT_CONFIG_FILE = "/usr/local/etc/wamupd.yaml"
61
+ DEFAULT_AVAHI_SERVICES_DIR = "/usr/local/etc/avahi/services"
62
+
63
+ app = Daemons.controller.group.applications.first
64
+
65
+ Options = Struct.new(:config, :ip_addresses, :avahi, :avahi_services_dir, :avahi_services)
66
+ $options = Options.new
67
+ $options.config = DEFAULT_CONFIG_FILE
68
+ $options.ip_addresses = false
69
+ $options.avahi = false
70
+ $options.avahi_services = false
71
+ $options.avahi_services_dir = DEFAULT_AVAHI_SERVICES_DIR
72
+
73
+ OptionParser.new do |opts|
74
+ opts.banner = "Usage: wamupd run -- [options] service-file"
75
+
76
+ opts.on("-c", "--config FILE",
77
+ "Get configuration data from FILE",
78
+ "If FILE is not provided, defaults to " + DEFAULT_CONFIG_FILE) do |cfg|
79
+ $options.config = cfg
80
+ end
81
+
82
+ opts.on("-A", "--avahi-services [DIRECTORY]",
83
+ "Load Avahi service definitions from DIRECTORY",
84
+ " If DIRECTORY is not provided, defaults to " + DEFAULT_AVAHI_SERVICES_DIR,
85
+ " If the -A flag is omitted altogether, static records will not be added.") do |services|
86
+ if services then
87
+ $options.avahi_services_dir = services
88
+ end
89
+ $options.avahi_services = true
90
+ end
91
+
92
+ opts.on("-i", "--[no-]ip-addresses", "Enable/Disable Publishing A and AAAA records") do |ips|
93
+ $options.ip_addresses = ips
94
+ end
95
+
96
+ opts.on("-a", "--avahi", "Load Avahi services over D-BUS") do |avahi|
97
+ $options.avahi = true
98
+ end
99
+
100
+ opts.on("-h", "--help", "Show this message") do
101
+ puts opts
102
+ exit
103
+ end
104
+ end.parse!(app.app_argv)
105
+
106
+ unless Daemons.controller.options[:ontop]
107
+ $logger = Logger.new(app.logfile, 'monthly')
108
+ $logger.level = Logger::INFO
109
+ else
110
+ $logger = Logger.new(STDOUT)
111
+ $logger.level = Logger::DEBUG
112
+ end
113
+
114
+ CurrentProcess.change_privilege('nobody', 'nogroup')
115
+
116
+
117
+ # Main wamupd object
118
+ class Main
119
+ include Singleton
120
+
121
+ # Process command-line objects
122
+ def process_args
123
+ @config_file = $options.config
124
+ @avahi_dir = $options.avahi_services_dir
125
+ @bools[:ip] = $options.ip_addresses
126
+ @bools[:avahi] = $options.avahi
127
+ @bools[:avahi_services] = $options.avahi_services
128
+ end
129
+
130
+ # Construct the object and process all command-line options
131
+ def initialize
132
+ @exiting = false
133
+
134
+ @bools = {
135
+ :publish=>false,
136
+ :unpublish=>false,
137
+ :avahi=>false,
138
+ :avahi_services=>false,
139
+ :ip=>false
140
+ }
141
+
142
+ $settings = MainSettings.instance()
143
+
144
+ process_args()
145
+
146
+ # Load settings
147
+ if (not File.exists?(@config_file))
148
+ $stderr.puts "Could not find configuration file #{@config_file}"
149
+ $stderr.puts "Try running with --help?"
150
+ exit
151
+ end
152
+ $settings.load_from_yaml(@config_file)
153
+
154
+ if (@bools[:ip])
155
+ @d = DNSIpController.new()
156
+ end
157
+
158
+ if (@bools[:avahi] or @bools[:avahi_services])
159
+ @a = Wamupd::DNSAvahiController.new()
160
+ end
161
+
162
+ if (@bools[:avahi_services])
163
+ @avahi_services = AvahiServiceFile.load_from_directory(@avahi_dir)
164
+ end
165
+ :w
166
+
167
+ if (@bools[:avahi])
168
+ @am = Wamupd::AvahiModel.new
169
+ end
170
+ end
171
+
172
+ # Actually run the program.
173
+ #
174
+ # This call doesn't return until SIGTERM is caught.
175
+ def run
176
+ $logger.debug "Starting main function"
177
+
178
+ update_queue = Queue.new
179
+ DNSUpdate.queue = update_queue
180
+
181
+ threads = []
182
+ if (@bools[:avahi] or @bools[:avahi_services])
183
+ # Handle the DNS controller
184
+ threads << Thread.new {
185
+ @a.on(:added) { |item,id|
186
+ $logger.debug('dns_controller') { "Added #{item.type_in_zone_with_name} (id=\"#{id}\")" }
187
+ }
188
+ @a.on(:deleted) { |item|
189
+ $logger.debug('dns_controller') { "Deleted #{item.type_in_zone_with_name}" }
190
+ }
191
+ @a.on(:renewed) { |item|
192
+ $logger.debug('dns_controller') { "Renewed #{item.type_in_zone_with_name}" }
193
+ }
194
+ @a.run
195
+ }
196
+
197
+ # Lease maintenance
198
+ threads << Thread.new {
199
+ @a.update_leases
200
+ }
201
+ end
202
+
203
+ publish_static
204
+
205
+ if (@bools[:avahi])
206
+ @am.on(:added) { |avahi_service|
207
+ @a.queue << Wamupd::Action.new(Wamupd::ActionType::ADD, avahi_service)
208
+ $logger.debug('avahi_listener') { "Found service: #{avahi_service}" }
209
+ }
210
+ # Handle listening to D-BUS
211
+ threads << Thread.new {
212
+ $logger.debug('dbus_listener') { "Starting" }
213
+ @am.run
214
+ }
215
+ end
216
+
217
+ if (@bools[:ip])
218
+ threads << Thread.new{
219
+ $logger.debug('ip_controller') { "Starting" }
220
+ @d.update_leases
221
+ }
222
+ end
223
+
224
+ threads << Thread.new {
225
+ while (1)
226
+ response_id, response, exception = update_queue.pop
227
+ $logger.debug('reporter') { "Got back response #{response_id}" }
228
+ if (not exception.nil?)
229
+ if (exception.kind_of?(Dnsruby::TsigNotSignedResponseError))
230
+ # Do nothing
231
+ else
232
+ $logger.warn('reporter') { "Error: #{exception}" }
233
+ $logger.warn('reporter') { response }
234
+ end
235
+ end
236
+ if (response.rcode != Dnsruby::RCode::NOERROR)
237
+ $logger.warn('reporter') { "Got an unexpected rcode (#{response.rcode})" }
238
+ $logger.warn('reporter') { response }
239
+ end
240
+ if DNSUpdate.outstanding.delete(response_id).nil?
241
+ $logger.warn('reporter') { "Got back an unexpected response ID" }
242
+ $logger.warn('reporter') { response }
243
+ end
244
+ end
245
+ }
246
+
247
+ stop_proc = proc { stop_threads(threads) }
248
+ trap(1, stop_proc)
249
+ trap(2, stop_proc)
250
+ trap(15, stop_proc)
251
+
252
+ $logger.info "Wamupd started"
253
+ while (!@exiting)
254
+ sleep(10)
255
+ end
256
+
257
+ threads.each { |t|
258
+ t.join
259
+ }
260
+
261
+ exit
262
+ end
263
+
264
+ def stop_threads(threads)
265
+ if (not @exiting) then
266
+ @exiting = true
267
+
268
+ $logger.info "Unregistering services..."
269
+ if (@bools[:avahi] or @bools[:avahi_services])
270
+ @a.exit
271
+ end
272
+ if (@bools[:avahi])
273
+ @am.exit
274
+ end
275
+ if (@bools[:ip])
276
+ @d.unpublish
277
+ end
278
+ sleep($settings.max_dns_response_time)
279
+ threads.each { |t|
280
+ t.exit
281
+ }
282
+ $logger.info "Wamupd stopped"
283
+ end
284
+ end
285
+
286
+ def publish_static
287
+ if (@d)
288
+ @d.on(:added) { |type,address|
289
+ $logger.debug('static_publisher') { "Added #{type} record for #{address}" }
290
+ }
291
+ @d.on(:removed) { |type,address|
292
+ $logger.debug('static_publisher') { "Removed #{type} record for #{address}" }
293
+ }
294
+ @d.publish
295
+ end
296
+
297
+ if (@avahi_services)
298
+ @avahi_services.each { |avahi_service_file|
299
+ avahi_service_file.each { |avahi_service|
300
+ @a.queue << Wamupd::Action.new(Wamupd::ActionType::ADD, avahi_service)
301
+ $logger.debug('static_publisher') { "Found static Avahi service: #{avahi_service}" }
302
+ }
303
+ }
304
+ end
305
+ end
306
+
307
+ private :process_args, :publish_static, :exit
308
+ end
309
+ end
310
+
311
+
312
+ w = Wamupd::Main.instance
313
+ w.run
314
+ end
@@ -0,0 +1,40 @@
1
+ # Copyright (C) 2010 James Brown <roguelazer@roguelazer.com>.
2
+ #
3
+ # This file is part of wamupd.
4
+ #
5
+ # wamupd is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # wamupd is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with wamupd. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ module Wamupd
19
+ # Possible actions in the system. Essentially, an enum
20
+ class ActionType
21
+ ADD=1
22
+ DELETE=2
23
+ QUIT=4
24
+ end
25
+
26
+ # A command wrapper
27
+ class Action
28
+ # The action to be performed. A Wamupd::ActionType
29
+ attr_reader :action
30
+
31
+ # The associated record (might be an AvahiService, or whatever else
32
+ # is appropriate). Might be nil
33
+ attr_reader :record
34
+
35
+ def initialize(action, record=nil)
36
+ @action=action
37
+ @record=record
38
+ end
39
+ end
40
+ end