[or-cvs] r16503: {} Add a prototype for building exit summaries from a descripto (projects/dir-stats/trunk)
weasel at seul.org
weasel at seul.org
Mon Aug 11 22:30:03 UTC 2008
Author: weasel
Date: 2008-08-11 18:30:03 -0400 (Mon, 11 Aug 2008)
New Revision: 16503
Added:
projects/dir-stats/trunk/exit-summary
Log:
Add a prototype for building exit summaries from a descriptor
Added: projects/dir-stats/trunk/exit-summary
===================================================================
--- projects/dir-stats/trunk/exit-summary (rev 0)
+++ projects/dir-stats/trunk/exit-summary 2008-08-11 22:30:03 UTC (rev 16503)
@@ -0,0 +1,176 @@
+#!/usr/bin/ruby
+
+# This script builds an exit summary from one server descriptor as proposed in #141.
+# the algorithm doesn't exactly match the proposal - maybe the proposal should be fixed.
+#
+# go over the exit policy lines:
+# - ignore rejects for netblocks 0.0.0.0/8 169.254.0.0/16 127.0.0.0/8 192.168.0.0/16 10.0.0.0/8 172.16.0.0/12 (exact match, no subnet match (yet))
+# - ignore accepts unless they are for ip "*"
+# - for a reject count the number of ips in the netblock against the affected ports
+# - for an accept to ip "*" add the affected ports to the accepted list if the number of IPs rejected for a port is less than CUTOFF_COUNT
+
+MAX_TCP = 65535
+CUTOFF_COUNT = 2**25
+class Policyitem
+ attr_accessor :from, :to, :rejectcount, :previously_accepted
+ def initialize(from, to, rejectcount = 0, previously_accepted = false)
+ @from = from
+ @to = to
+ @rejectcount = rejectcount
+ @previously_accepted = previously_accepted
+ end
+end
+
+class Policy
+ def initialize
+ @list = []
+ @list << Policyitem.new(1,MAX_TCP)
+
+ @accepted = []
+ end
+ def print_debug
+ puts "START"
+ @list.each do |i|
+ puts " " + (i.from ? i.from.to_s : "nil") + " - " + (i.to ? i.to.to_s : "nil")
+ end
+
+ last_to = 0
+ @list.each do |i|
+ throw "i.from > i.to: #{i.from} > #{i.to}" if i.from > i.to
+ throw "i.from vs. last_to: #{i.from} > #{last_to}" if i.from != last_to + 1
+ last_to = i.to
+ end
+ end
+ def compress_list(l)
+ index = 0
+ while (l[index+1])
+ if l[index].to+1 == l[index+1].from
+ l[index].to = l[index+1].to
+ l.delete_at(index+1)
+ else
+ index = index+1
+ end
+ end
+ l
+ end
+ def get_accept
+ compress_list(@accepted).collect { |i| (i.from != i.to) ? "#{i.from}-#{i.to}" : i.to.to_s }.join(",")
+ end
+ def get_reject
+ @rejected = []
+ last_accepted = 0
+ @accepted.each do |item|
+ if last_accepted + 1 < item.from
+ @rejected << Policyitem.new(last_accepted + 1, item.from-1)
+ end
+ last_accepted = item.to
+ end
+ if last_accepted < MAX_TCP
+ @rejected << Policyitem.new(last_accepted + 1, MAX_TCP)
+ end
+ compress_list(@rejected).collect { |i| (i.from != i.to) ? "#{i.from}-#{i.to}" : i.to.to_s }.join(",")
+ end
+ def print
+ puts "accept " +get_accept
+ puts "reject " +get_reject
+ end
+ def split(port)
+ port="1-#{MAX_TCP}" if port == "*"
+
+ (from,to) = port.split("-")
+ from = from.to_i
+ to = from unless to
+ to = to.to_i
+
+ index = 0
+ index = index+1 while (@list[index].to < from)
+ if @list[index].from != from
+ @list[index..index] = [ Policyitem.new(@list[index].from, from-1, @list[index].rejectcount, @list[index].previously_accepted),
+ Policyitem.new(from, @list[index].to, @list[index].rejectcount, @list[index].previously_accepted)];
+ index = index + 1;
+ end
+ startindex = index
+
+ index = index+1 while (@list[index].to < to)
+ if @list[index].to != to
+ @list[index..index] = [ Policyitem.new(@list[index].from, to, @list[index].rejectcount, @list[index].previously_accepted),
+ Policyitem.new(to+1, @list[index].to, @list[index].rejectcount, @list[index].previously_accepted)];
+ end
+ endindex = index
+
+ @list[startindex .. endindex]
+ end
+
+ def add(item)
+ (kind,target) = item.split()
+ (ip,port) = target.split(":")
+ case kind
+ when "reject"
+ return if %w(0.0.0.0/8 169.254.0.0/16 127.0.0.0/8 192.168.0.0/16 10.0.0.0/8 172.16.0.0/12).include? ip
+ reject_some(ip, port)
+ when "accept"
+ if ip == "*" then
+ port_accept(port)
+ end
+ else
+ throw "aaaaaaaaaaaarg"
+ end
+ end
+ def port_accept(port)
+ # we got an accept * to the port(list) in port.
+ matching = split(port)
+ matching.each do |item|
+ next if item.previously_accepted
+ #puts "#{item.from}-#{item.to}: #{item.rejectcount}"
+ next if item.rejectcount >= CUTOFF_COUNT
+ @accepted << item
+ item.previously_accepted = true
+ end
+ end
+ def reject_some(ip, port)
+ # we got a reject ip:port to the port(list) in port.
+ matching = split(port)
+ if ip=="*"
+ count = 2**32
+ else
+ (net,prefixlen) = ip.split("/")
+ prefixlen=32 unless prefixlen
+ count = 2**(32-prefixlen.to_i)
+ end
+
+ matching.each do |item|
+ #puts "Adding #{count} to #{item.from}-#{item.to} from reject #{ip}:#{port}"
+ item.rejectcount = item.rejectcount + count
+ end
+ end
+end
+
+p = Policy.new
+while (line=STDIN.gets) do
+ next unless line =~ /^(reject|accept) /
+ p.add line
+end
+p.print
+
+
+
+# Copyright (c) 2008 Peter Palfrader <peter at palfrader.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Property changes on: projects/dir-stats/trunk/exit-summary
___________________________________________________________________
Name: svn:executable
+ *
More information about the tor-commits
mailing list