From e651f612faaab8db756269e65a439e1d63601793 Mon Sep 17 00:00:00 2001 From: Katze Miau Date: Sat, 3 Dec 2011 12:18:42 +0000 Subject: p2ptbl: add gossip protocol - add `p2ptbl gossip` to distribute tables via udp bcast - add interface option to `p2ptbl update` for immediate communication of updates - add p2ptbl-recv as HBBP-handler to receive table updates p2ptbl-recv has to be symlinked from /p2ptbl/. It reads the table name from $0 and assumes that all tables are stored in /tmp/p2ptbl/. diff --git a/files/common/sbin/p2ptbl b/files/common/sbin/p2ptbl index 8365915..a728a9c 100755 --- a/files/common/sbin/p2ptbl +++ b/files/common/sbin/p2ptbl @@ -1,25 +1,34 @@ #!/bin/sh -function init { +set -e + +init () { [ -n "$1" ] || printArgs - [ -f "$1" ] || cat >$1 "$1" "$tmpfile" merge "$1" "$tmpfile" + if [ -n "$4" ]; then + # broadcast update + gzip <"$tmpfile" >"$tmpfile.gz" + broadcaster $4 p2ptbl/$(basename "$1") - <"$tmpfile.gz" + rm "$tmpfile.gz" + fi rm "$tmpfile" } -function merge { +merge () { sort "$1" "$2" \ | { oldkey="" @@ -43,16 +52,41 @@ function merge { mv "$1~" "$1" } -function printArgs { +gossip() { + tgts="$2" + if="$3" + [ "$tgts" -gt 0 -a -n "$if" ] 2>/dev/null || printArgs + + # binary search over number of sent lines until size is maximized + # and below target size + lc=$(wc -l <"$1") + [ $lc == 0 ] && return + shuf -v seed=$RANDOM <"$1" >"$1.gossip" + while [ $lc -ge 1 ]; do + head -n$lc "$1.gossip" | gzip >"$1.gossip.gz" + if [ $tgts -ge $(wc -c <"$1.gossip.gz") ]; then + broadcaster $if p2ptbl/$(basename "$1") - <"$1.gossip.gz" + rm "$1.gossip" "$1.gossip.gz" + return; + fi + lc=$(($lc / 2)) + done + rm "$1.gossip" "$1.gossip.gz" + echo "$1 has rows bigger then requested packet size" + exit 1 +} + +printArgs () { echo -e "Usage: $0 init table $0 get table key -$0 update table key value -$0 merge table foreign-table" - exit -1 +$0 update table key value [interface] +$0 merge table foreign-table +$0 gossip table target-size interface" + exit 1 } -function checkTable { +checkTable () { [ -n "$1" ] || printArgs; [ -f "$1" ] || { echo "$1 is no P2P table"; @@ -60,24 +94,33 @@ function checkTable { } } +lockTable () { + checkTable "$2" + exec 666<"$2" + flock "$1" 666 +} + case "$1" in init) - checkTable "$2" init "$2" ;; get) - checkTable "$2" + lockTable -s "$2" get "$2" "$3" ;; update) - checkTable "$2" - update "$2" "$3" "$4" + lockTable -s "$2" + update "$2" "$3" "$4" "$5" ;; merge) - checkTable "$2" - checkTable "$3" + lockTable -x "$2" + checkTable "$3" merge "$2" "$3" ;; + gossip) + lockTable -s "$2" + gossip "$2" "$3" "$4" + ;; *) printArgs ;; diff --git a/files/common/sbin/p2ptbl-recv b/files/common/sbin/p2ptbl-recv new file mode 100755 index 0000000..f10fa39 --- /dev/null +++ b/files/common/sbin/p2ptbl-recv @@ -0,0 +1,12 @@ +#!/bin/sh + +set -e + +tbldir=/tmp/p2ptbl +tbl=$tbldir/$(basename $0) + +[ -f $tbl ] || p2ptbl init $tbl + +gunzip > $tbl.recv +p2ptbl merge $tbl $tbl.recv +rm $tbl.recv \ No newline at end of file -- cgit v0.10.1