[or-cvs] r11794: Commit this stuff somewhere before I delete it accidentally (in tor/trunk/contrib: . auto-naming)

weasel at seul.org weasel at seul.org
Mon Oct 8 23:40:52 UTC 2007


Author: weasel
Date: 2007-10-08 19:40:52 -0400 (Mon, 08 Oct 2007)
New Revision: 11794

Added:
   tor/trunk/contrib/auto-naming/
   tor/trunk/contrib/auto-naming/build-approved-routers
   tor/trunk/contrib/auto-naming/create-db.sql
   tor/trunk/contrib/auto-naming/db-config.rb
   tor/trunk/contrib/auto-naming/db.rb
   tor/trunk/contrib/auto-naming/process-consensus
   tor/trunk/contrib/auto-naming/update-named-status.rb
Log:
Commit this stuff somewhere before I delete it accidentally

Added: tor/trunk/contrib/auto-naming/build-approved-routers
===================================================================
--- tor/trunk/contrib/auto-naming/build-approved-routers	                        (rev 0)
+++ tor/trunk/contrib/auto-naming/build-approved-routers	2007-10-08 23:40:52 UTC (rev 11794)
@@ -0,0 +1,22 @@
+#!/usr/bin/ruby
+
+require "yaml"
+
+require 'db'
+require 'db-config'
+
+verbose = ARGV.first == "-v"
+
+db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+
+db.transaction_begin
+named = db.query2("
+		SELECT fingerprint, router_id, nickname_id, nick, first_seen, last_seen
+		FROM router NATURAL JOIN router_claims_nickname NATURAL JOIN nickname
+		WHERE named")
+while (n=named.next) do
+	puts "# (r##{n['router_id']},n##{n['nickname_id']}); first_seen: #{n['first_seen']}, last_seen: #{n['last_seen']}"
+	fpr = n['fingerprint'].split(/(....)/).delete_if{|x| x=="" }.join(' ')
+	puts "#{n['nick']} #{fpr}}"
+end
+db.transaction_commit


Property changes on: tor/trunk/contrib/auto-naming/build-approved-routers
___________________________________________________________________
Name: svn:executable
   + *

Added: tor/trunk/contrib/auto-naming/create-db.sql
===================================================================
--- tor/trunk/contrib/auto-naming/create-db.sql	                        (rev 0)
+++ tor/trunk/contrib/auto-naming/create-db.sql	2007-10-08 23:40:52 UTC (rev 11794)
@@ -0,0 +1,29 @@
+
+CREATE TABLE router (
+	router_id	SERIAL PRIMARY KEY,
+	fingerprint	CHAR(40)		NOT NULL,
+	UNIQUE(fingerprint)
+);
+-- already created implicitly due to unique contraint
+-- CREATE INDEX router_fingerprint ON router(fingerprint);
+
+CREATE TABLE nickname (
+	nickname_id	SERIAL PRIMARY KEY,
+	nick		VARCHAR(30)		NOT NULL,
+	UNIQUE(nick)
+);
+-- already created implicitly due to unique contraint
+-- CREATE INDEX nickname_nick ON nickname(nick);
+
+CREATE TABLE router_claims_nickname (
+	router_id	INTEGER		NOT NULL	REFERENCES router(router_id) ON DELETE CASCADE,
+	nickname_id	INTEGER		NOT NULL	REFERENCES nickname(nickname_id) ON DELETE CASCADE,
+	first_seen	TIMESTAMP WITH TIME ZONE	NOT NULL	DEFAULT CURRENT_TIMESTAMP,
+	last_seen	TIMESTAMP WITH TIME ZONE	NOT NULL	DEFAULT CURRENT_TIMESTAMP,
+	named		BOOLEAN				NOT NULL	DEFAULT 'false',
+	UNIQUE(router_id, nickname_id)
+);
+CREATE INDEX router_claims_nickname_router_id ON router_claims_nickname(router_id);
+CREATE INDEX router_claims_nickname_nickname_id ON router_claims_nickname(nickname_id);
+CREATE INDEX router_claims_nickname_first_seen ON router_claims_nickname(first_seen);
+CREATE INDEX router_claims_nickname_last_seen ON router_claims_nickname(last_seen);

Added: tor/trunk/contrib/auto-naming/db-config.rb
===================================================================
--- tor/trunk/contrib/auto-naming/db-config.rb	                        (rev 0)
+++ tor/trunk/contrib/auto-naming/db-config.rb	2007-10-08 23:40:52 UTC (rev 11794)
@@ -0,0 +1,6 @@
+$CONFIG             = {} unless $CONFIG
+$CONFIG['database'] = {} unless $CONFIG['database']
+
+$CONFIG['database']['dbname'] = 'tornaming';
+$CONFIG['database']['user'] = 'tornaming';
+$CONFIG['database']['password'] = 'x';

Added: tor/trunk/contrib/auto-naming/db.rb
===================================================================
--- tor/trunk/contrib/auto-naming/db.rb	                        (rev 0)
+++ tor/trunk/contrib/auto-naming/db.rb	2007-10-08 23:40:52 UTC (rev 11794)
@@ -0,0 +1,145 @@
+#!/usr/bin/ruby
+
+require "dbi"
+
+class WeaselDbQueryHandle
+	def initialize(sth)
+		@sth = sth
+	end
+
+	def next()
+		row = @sth.fetch_hash
+		if row
+			return row
+		else
+			@sth.finish
+			return nil
+		end
+	end
+end
+
+class Db
+	def initialize(database, user, password)
+		@dbh = DBI.connect("dbi:Pg:#{database}:localhost", user, password);
+		@dbh['AutoCommit'] = false
+		@transaction = false
+		@pre_initial_transaction=true
+	end
+
+	def do(query,*args)
+		@dbh.do(query,*args)
+	end
+	def transaction_begin()
+		@dbh.do("BEGIN") unless @pre_initial_transaction
+		@transaction = true
+		@pre_initial_transaction=false
+	end
+	def transaction_commit()
+		@dbh.do("COMMIT")
+		@transaction = false
+	end
+	def transaction_rollback()
+		@dbh.do("ROLLBACK")
+	end
+	def get_primarykey_name(table);
+		#return 'ref';
+		return table+'_id';
+	end
+
+	def update(table, values, keys)
+		cols = []
+		vals = []
+		values.each_pair{ |k,v|
+			cols << "#{k}=?"
+			vals << v
+		}
+
+		wheres = []
+		keys.each_pair{ |k,v|
+			wheres << "#{k}=?"
+			vals << v
+		}
+
+		throw "update value set empty" unless cols.size > 0
+		throw "where clause empty" unless wheres.size > 0
+
+		query = "UPDATE #{table} SET #{cols.join(',')} WHERE #{wheres.join(' AND ')}"
+		transaction_begin unless transaction_before=@transaction
+		r = @dbh.do(query, *vals)
+		transaction_commit unless transaction_before
+		return r
+	end
+
+	def update_row(table, values)
+		pk_name = get_primarykey_name(table);
+		throw "Ref not defined" unless values[pk_name]
+		return update(table, values.clone.delete_if{|k,v| k == pk_name}, { pk_name => values[pk_name] });
+	end
+	def insert(table, values)
+		cols = values.keys
+		vals = values.values
+		qmarks = values.values.collect{ '?' }
+
+		query = "INSERT INTO #{table} (#{cols.join(',')}) VALUES (#{qmarks.join(',')})"
+		transaction_begin unless transaction_before=@transaction
+		@dbh.do(query, *vals)
+		transaction_commit unless transaction_before
+	end
+
+	def insert_row(table, values)
+		pk_name = get_primarykey_name(table);
+		if values[pk_name]
+			insert(table, values)
+		else
+			transaction_begin unless transaction_before=@transaction
+			row = query_row("SELECT nextval(pg_get_serial_sequence('#{table}', '#{pk_name}')) AS newref");
+			throw "No newref?" unless row['newref']
+			values[pk_name] = row['newref']
+			insert(table, values);
+			transaction_commit unless transaction_before
+		end
+	end
+	def delete_row(table, ref)
+		pk_name = get_primarykey_name(table);
+		query = "DELETE FROM #{table} WHERE #{pk_name}=?"
+		transaction_begin unless transaction_before=@transaction
+		@dbh.do(query, ref)
+		transaction_commit unless transaction_before
+	end
+	def query(query, *params)
+		sth = @dbh.execute(query, *params)
+		while row = sth.fetch_hash
+			yield row
+		end
+		sth.finish
+	end
+	# nil if no results
+	# hash if one match
+	# throw otherwise
+	def query_row(query, *params)
+		sth = @dbh.execute(query, *params)
+
+		row = sth.fetch_hash
+		if row == nil
+			sth.finish
+			return nil
+		elsif sth.fetch_hash != nil
+			sth.finish
+			throw "More than one result when querying for #{query}"
+		else
+			sth.finish
+			return row
+		end
+	end
+	def query_all(query, *params)
+		sth = @dbh.execute(query, *params)
+
+		rows = sth.fetch_all
+		return nil if rows.size == 0
+		return rows
+	end
+	def query2(query, *params)
+		sth = @dbh.execute(query, *params)
+		return WeaselDbQueryHandle.new(sth)
+	end
+end

Added: tor/trunk/contrib/auto-naming/process-consensus
===================================================================
--- tor/trunk/contrib/auto-naming/process-consensus	                        (rev 0)
+++ tor/trunk/contrib/auto-naming/process-consensus	2007-10-08 23:40:52 UTC (rev 11794)
@@ -0,0 +1,94 @@
+#!/usr/bin/ruby
+
+require "yaml"
+
+require 'db'
+require 'db-config'
+require 'update-named-status'
+
+$db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+
+$router_cache = {}
+$nickname_cache = {}
+
+def parse_consensus consensus
+	ts = nil
+	routers = []
+	consensus.each do |line|
+		(key, value) = line.split(' ',2)
+		case key
+			when "valid-after", "published": ts = DateTime.parse(value)
+			when "r":
+				(nick, fpr, _) = value.split(' ', 3)
+				nick.downcase!
+				next if nick == 'unnamed'
+				routers << {
+					'nick' => nick,
+					'fingerprint' => (fpr+'=').unpack('m').first.unpack('H*').first
+					}
+		end
+	end
+	throw "Did not find a timestamp" unless ts
+	throw "Did not find any routers" unless routers.size > 0
+	return ts, routers
+end
+
+def insert_routers_into_db(router, table, field, value)
+	pk = table+'_id'
+	row = $db.query_row("SELECT #{pk} FROM #{table} WHERE #{field}=?", value)
+	if row
+		return row[pk]
+	else
+		r = { field => value }
+		$db.insert_row( table, r )
+		return r[pk]
+	end
+end
+
+def handle_one_consensus(c)
+	puts "parsing..." if $verbose
+	timestamp, routers = parse_consensus c
+	puts "storing..." if $verbose
+
+	routers.each do |router|
+		fpr = router['fingerprint']
+		nick = router['nick']
+		$router_cache[fpr] = router_id = ($router_cache[fpr] or insert_routers_into_db(router, 'router', 'fingerprint', router['fingerprint']))
+		$nickname_cache[nick] = nickname_id = ($nickname_cache[nick] or insert_routers_into_db(router, 'nickname', 'nick', router['nick']))
+
+		row = $db.update(
+			'router_claims_nickname',
+			{ 'last_seen' => timestamp.to_s },
+			{ 'router_id' => router_id, 'nickname_id' => nickname_id} )
+		case row
+			when 0:
+				$db.insert('router_claims_nickname',
+					{
+						'first_seen' => timestamp.to_s,
+						'last_seen' => timestamp.to_s,
+						'router_id' => router_id, 'nickname_id' => nickname_id} )
+			when 1:
+			else
+				throw "Update of router_claims_nickname returned unexpected number of affected rows(#{row})"
+		end
+	end
+end
+
+$db.transaction_begin
+if ARGV.first == '-v'
+	$verbose = true
+	ARGV.shift
+end
+
+if ARGV.size == 0
+	handle_one_consensus STDIN.readlines
+	do_update true
+else
+	ARGV.each do |filename|
+		puts filename if $verbose
+		handle_one_consensus File.new(filename).readlines
+		puts "updating..." if $verbose
+		do_update $verbose
+	end
+end
+$db.transaction_commit


Property changes on: tor/trunk/contrib/auto-naming/process-consensus
___________________________________________________________________
Name: svn:executable
   + *

Added: tor/trunk/contrib/auto-naming/update-named-status.rb
===================================================================
--- tor/trunk/contrib/auto-naming/update-named-status.rb	                        (rev 0)
+++ tor/trunk/contrib/auto-naming/update-named-status.rb	2007-10-08 23:40:52 UTC (rev 11794)
@@ -0,0 +1,43 @@
+#!/usr/bin/ruby
+
+require "yaml"
+
+require 'db'
+require 'db-config'
+
+def do_update verbose
+	now = "TIMESTAMP '" + $db.query_row("SELECT max(last_seen) AS max FROM router_claims_nickname")['max'].to_s + "'"
+
+	denamed = $db.do("
+			UPDATE router_claims_nickname
+			SET named=false
+			WHERE named
+			  AND last_seen < #{now} - INTERVAL '6 months'")
+	puts "de-named: #{denamed}" if verbose
+
+	named = $db.do("
+			UPDATE router_claims_nickname
+			SET named=true
+			WHERE NOT named
+			  AND first_seen < #{now} - INTERVAL '2 weeks'
+			  AND last_seen  > #{now} - INTERVAL '2 days'
+			  AND NOT EXISTS (SELECT *
+			       FROM router_claims_nickname AS innertable
+			       WHERE named
+			         AND router_claims_nickname.nickname_id=innertable.nickname_id) "+ # if that nickname is already named, we lose.
+			" AND NOT EXISTS (SELECT *
+			       FROM router_claims_nickname AS innertable
+			       WHERE router_claims_nickname.nickname_id=innertable.nickname_id
+			         AND router_claims_nickname.router_id <> innertable.router_id
+			         AND last_seen > #{now} - INTERVAL '1 month') ") # if nobody else wanted that nickname in the last month we are set
+	puts "named: #{named}" if verbose
+end
+
+if __FILE__ == $0
+	$db = Db.new($CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password'])
+	verbose = ARGV.first == "-v"
+
+	$db.transaction_begin
+	do_update verbose
+	$db.transaction_commit
+end


Property changes on: tor/trunk/contrib/auto-naming/update-named-status.rb
___________________________________________________________________
Name: svn:executable
   + *



More information about the tor-commits mailing list