[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Debian JP master SVN www commits (rev.554)
=======================================================
Repository: /org/svn.debian.or.jp/repos
Revision: 554
Commiter: yasu
Date: 2008-02-05 19:30:57 +0900 (火, 05 2月 2008)
=======================================================
Log:
add -F and --logfile options.
=======================================================
Changed:
U cdn/trunk/DNS-Balance/ChangeLog
U cdn/trunk/DNS-Balance/dns_balance.rb
U cdn/trunk/DNS-Balance/multilog.rb
Modified: cdn/trunk/DNS-Balance/ChangeLog
===================================================================
--- cdn/trunk/DNS-Balance/ChangeLog 2008-02-04 02:46:20 UTC (rev 553)
+++ cdn/trunk/DNS-Balance/ChangeLog 2008-02-05 10:30:57 UTC (rev 554)
@@ -1,3 +1,11 @@
+2008-02-05 ARAKI Yasuhiro <ar@debian.org>
+
+ * dns_balance.rb:
+ - Change to run default daemon mode. If you want to run foreground, run with '-F'.
+ - Add '--logfile' option (default /var/log/dns_balance.log)
+
+ * multilog.rb (MultiLog::log): Add timestamp.
+
2008-02-04 ARAKI Yasuhiro <ar@debian.org>
* dns_balance.rb (select_namespace): コマンドラインオプションに
Modified: cdn/trunk/DNS-Balance/dns_balance.rb
===================================================================
--- cdn/trunk/DNS-Balance/dns_balance.rb 2008-02-04 02:46:20 UTC (rev 553)
+++ cdn/trunk/DNS-Balance/dns_balance.rb 2008-02-05 10:30:57 UTC (rev 554)
@@ -16,6 +16,9 @@
$LOAD_PATH.unshift(PREFIX)
end
+$process_file = '/var/run/dns_balance.pid'
+$logfile = '/var/log/dns_balance.log'
+
require 'socket'
require 'thread'
require 'optparse'
@@ -237,6 +240,158 @@
end
end
+def run
+ #
+ # アドレスデータベースの動的更新
+ #
+ Thread::start {
+ loop {
+ if test(?r, PREFIX + "/addr") || test(?r, "./addr")
+ begin
+ load("addr")
+
+ ML.log("reload")
+ rescue NameError,SyntaxError,Exception
+ ML.log("reload failed")
+ end
+ end
+
+ #if test(?r, PREFIX + "/addr-once") || test(?r, "./addr-once")
+ # Thread.exit
+ #end
+
+ #p $addr_db
+ sleep(2*60) # 5 分毎に更新
+ }
+ }
+
+ gs = UDPSocket::new()
+ sockaddr = (if OPT["i"] == nil then Socket::INADDR_ANY else OPT["i"] end)
+ if OPT["port"]
+ gs.bind(sockaddr, OPT["port"])
+ else
+ gs.bind(sockaddr, Service::Domain)
+ end
+
+ #
+ # メインループ
+ #
+ loop {
+ (packet, client) = gs.recvfrom(1024)
+ Thread.start {
+ $SAFE = 2
+ begin
+ client_data = get_client_data(client)
+ (q, q_type, q_class) = parse_packet(packet)
+ check_packet(q, q_type, q_class) # -> NoQuery, NotImpl
+
+ name = dnsstr_to_str(q).downcase
+ namespace = select_namespace(client_data["addr"], name)
+
+ check_type(q, q_type, q_class, namespace)
+
+ if $addr_db[namespace][name].size > 1 # -> NoMethodError -> NoQuery
+ size = 8
+ else
+ size = 1
+ end
+ a_array = select_rand_array(namespace, name, size) #.uniq
+
+ if a_array.size == 0
+ raise DnsNoMoreResourceError
+ end
+
+ # 返答生成
+ r = packet[0,12] + q + q_type + q_class
+ r[2] |= 0x84 # answer & authenticated
+ r[3] = 0 # no error
+
+ ans_addrs = []
+ a_array.each {
+ |i|
+ addr = $addr_db[namespace][name][i][0]
+ ans_addrs.push(addr) # ログ出力用
+
+ # TTL 選択。近い所がある事が分かっているなら TTL を長くする
+ if (a_array.size == 1)
+ ttl = "\0\0\x0e\x10" # 1時間
+ else
+ ttl = "\0\0\0\x3c" # 60秒
+ end
+
+ # 返答生成。 オフセットは 0x000c
+ r += "\xc0\x0c" + DnsType::A + DnsClass::INET + ttl + "\0\4" + addr.pack("CCCC")
+ }
+
+ # 返答の数をセット
+ r[6,2] = [a_array.size].pack("n")
+ r[8,4] = "\0\0\0\0"
+
+ # 長過ぎたら削る
+ if r.length > 512
+ raise DnsTruncatedError
+ end
+
+ status = "ok"
+
+ rescue DnsNotImplementedError
+ r = packet[0,12] + q + q_type + q_class
+ r[2] |= 0x80 # answer
+ r[2] &= ~0x04 # not authenticated
+ r[3] = 0
+ r[3] |= 0x04 # not implemented error
+ r[6,6] = "\0\0\0\0\0\0"
+ status = "NotImpl"
+
+ rescue DnsTruncatedError
+ # 長過ぎる時は削ってフラグを立てる
+ r = r[0,512]
+ r[2] |= 0x02
+ status = "Truncated"
+
+ rescue DnsNoErrorError
+ r = packet[0,12] + q + q_type + q_class
+ r[2] |= 0x84 # answer & authenticated
+ r[3] = 0 # no error
+
+ r[6,6] = "\0\0\0\0\0\0"
+
+ status = "NoError"
+
+ rescue DnsNoQueryError,DnsNoMoreResourceError,NoMethodError,StandardError
+ r = packet[0,12] + q + q_type + q_class
+ r[2] |= 0x84 # answer & authenticated
+ r[3] = 0
+ r[3] |= 0x03 # name error
+ r[6,6] = "\0\0\0\0\0\0"
+ status = "NoQuery"
+
+ rescue
+ # ここには来ないはず
+ r = packet[0,12] + q + q_type + q_class
+ r[2] |= 0x80 # answer
+ r[2] &= ~0x04 # not authenticated
+ r[3] = 0
+ r[3] |= 0x05 # query refused error
+ r[6,6] = "\0\0\0\0\0\0"
+ status = "other"
+ end
+
+ #print packet.dump, "\n"
+ #print r.dump, "\n"
+ #p q
+
+ gs.send(r, 0, client_data["addr"], client_data["port"])
+
+ logger(ML, client_data["addr"], status, name, namespace, ans_addrs)
+
+ }
+ }
+
+end
+
+
+
######################################################################
# main
@@ -253,6 +408,11 @@
|o|
OPT["port"] = o;
}
+ opt.on("--logfile filename", String, "Set logfile (default: #{$logfile})") {
+ |o|
+ OPT["logfile"] = true
+ $logfile = o;
+ }
opt.on("--geoip", "Enable GeoIP ") {
OPT["country"] = true
OPT["continent"] = true
@@ -266,6 +426,9 @@
opt.on("--as", "Enable AS namespace") {
OPT["as"] = true
}
+ opt.on("-F", "Unfork (test purpose)") {
+ OPT["unfork"] = true
+ }
opt.on_tail("-h", "--help", "Show this help message and exit") {
STDERR.printf("%s", opt.to_s)
exit(111)
@@ -275,157 +438,42 @@
OPT.freeze
ML = MultiLog::new
-ML.open
-ML.log("dir: " + PREFIX)
-ML.log("start")
+if OPT["unfork"]
-
-#
-# アドレスデータベースの動的更新
-#
-Thread::start {
- loop {
- if test(?r, PREFIX + "/addr") || test(?r, "./addr")
- begin
- load("addr")
-
- ML.log("reload")
- rescue NameError,SyntaxError,Exception
- ML.log("reload failed")
- end
+ if OPT["logfile"]
+ fd = open($logfile, "w")
+ ML.open(fd)
+ else
+ ML.open
+ end
+ ML.log("dir: " + PREFIX)
+ ML.log("start")
+ print "Start #{$0} running in Foreground mode.\n"
+ run
+else
+ fd = open($logfile, "w")
+ ML.open(fd)
+ ML.log("dir: " + PREFIX)
+ ML.log("start")
+ Process.fork do
+ if File.exist?($process_file)
+ print "Other daemon running. pidfile is #{$process_file}\n"
+ old_pid = File.open($process_file).read.chomp.to_i
+ exit 1
+ fail
end
-
- #if test(?r, PREFIX + "/addr-once") || test(?r, "./addr-once")
- # Thread.exit
- #end
-
- #p $addr_db
- sleep(2*60) # 5 分毎に更新
- }
-}
-
-gs = UDPSocket::new()
-sockaddr = (if OPT["i"] == nil then Socket::INADDR_ANY else OPT["i"] end)
-if OPT["port"]
- gs.bind(sockaddr, OPT["port"])
-else
- gs.bind(sockaddr, Service::Domain)
+ pid = Process.setsid
+ print "Start #{$0} running pid is #{pid}\n"
+ pidfile = open($process_file, "w+")
+ pidfile.write(pid)
+ pidfile.flush
+ trap("SIGINT"){ exit! 0 }
+ trap("SIGTERM"){ exit! 0 }
+ trap("SIGHUP"){ exit! 0 }
+ [ STDIN, STDOUT, STDERR ].each do |io|
+ io.reopen("/dev/null", "r+")
+ end
+ run
+ end
end
-
-#
-# メインループ
-#
-loop {
- (packet, client) = gs.recvfrom(1024)
- Thread.start {
- $SAFE = 2
- begin
- client_data = get_client_data(client)
- (q, q_type, q_class) = parse_packet(packet)
- check_packet(q, q_type, q_class) # -> NoQuery, NotImpl
-
- name = dnsstr_to_str(q).downcase
- namespace = select_namespace(client_data["addr"], name)
-
- check_type(q, q_type, q_class, namespace)
-
- if $addr_db[namespace][name].size > 1 # -> NoMethodError -> NoQuery
- size = 8
- else
- size = 1
- end
- a_array = select_rand_array(namespace, name, size) #.uniq
-
- if a_array.size == 0
- raise DnsNoMoreResourceError
- end
-
- # 返答生成
- r = packet[0,12] + q + q_type + q_class
- r[2] |= 0x84 # answer & authenticated
- r[3] = 0 # no error
-
- ans_addrs = []
- a_array.each {
- |i|
- addr = $addr_db[namespace][name][i][0]
- ans_addrs.push(addr) # ログ出力用
-
- # TTL 選択。近い所がある事が分かっているなら TTL を長くする
- if (a_array.size == 1)
- ttl = "\0\0\x0e\x10" # 1時間
- else
- ttl = "\0\0\0\x3c" # 60秒
- end
-
- # 返答生成。 オフセットは 0x000c
- r += "\xc0\x0c" + DnsType::A + DnsClass::INET + ttl + "\0\4" + addr.pack("CCCC")
- }
-
- # 返答の数をセット
- r[6,2] = [a_array.size].pack("n")
- r[8,4] = "\0\0\0\0"
-
- # 長過ぎたら削る
- if r.length > 512
- raise DnsTruncatedError
- end
-
- status = "ok"
-
- rescue DnsNotImplementedError
- r = packet[0,12] + q + q_type + q_class
- r[2] |= 0x80 # answer
- r[2] &= ~0x04 # not authenticated
- r[3] = 0
- r[3] |= 0x04 # not implemented error
- r[6,6] = "\0\0\0\0\0\0"
- status = "NotImpl"
-
- rescue DnsTruncatedError
- # 長過ぎる時は削ってフラグを立てる
- r = r[0,512]
- r[2] |= 0x02
- status = "Truncated"
-
- rescue DnsNoErrorError
- r = packet[0,12] + q + q_type + q_class
- r[2] |= 0x84 # answer & authenticated
- r[3] = 0 # no error
-
- r[6,6] = "\0\0\0\0\0\0"
-
- status = "NoError"
-
- rescue DnsNoQueryError,DnsNoMoreResourceError,NoMethodError,StandardError
- r = packet[0,12] + q + q_type + q_class
- r[2] |= 0x84 # answer & authenticated
- r[3] = 0
- r[3] |= 0x03 # name error
- r[6,6] = "\0\0\0\0\0\0"
- status = "NoQuery"
-
- rescue
- # ここには来ないはず
- r = packet[0,12] + q + q_type + q_class
- r[2] |= 0x80 # answer
- r[2] &= ~0x04 # not authenticated
- r[3] = 0
- r[3] |= 0x05 # query refused error
- r[6,6] = "\0\0\0\0\0\0"
- status = "other"
- end
-
- #print packet.dump, "\n"
- #print r.dump, "\n"
- #p q
-
- gs.send(r, 0, client_data["addr"], client_data["port"])
-
- logger(ML, client_data["addr"], status, name, namespace, ans_addrs)
-
- }
-}
-
-# end
Modified: cdn/trunk/DNS-Balance/multilog.rb
===================================================================
--- cdn/trunk/DNS-Balance/multilog.rb 2008-02-04 02:46:20 UTC (rev 553)
+++ cdn/trunk/DNS-Balance/multilog.rb 2008-02-05 10:30:57 UTC (rev 554)
@@ -38,7 +38,7 @@
raise RuntimeError if !opened?()
@loglock.synchronize do
- @outport.print(str + "\n")
+ @outport.print(Time.now.to_s + ' ' + str + "\n")
@outport.flush
end
end