diff options
| author | Katze Miau <miaukatzemiau@priveasy.de> | 2011-12-03 12:18:42 (GMT) | 
|---|---|---|
| committer | Katze Miau <miaukatzemiau@priveasy.de> | 2011-12-03 12:18:42 (GMT) | 
| commit | e651f612faaab8db756269e65a439e1d63601793 (patch) | |
| tree | 4325682b0abadccd8f19bbd363143bef60dd0998 /files/common/sbin/p2ptbl | |
| parent | 522bfb1a8e9bbe1238dc2fe7991ff42de38b1697 (diff) | |
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 <HBBP-root>/p2ptbl/<table-name>.
It reads the table name from $0 and assumes that all tables are stored
in /tmp/p2ptbl/.
Diffstat (limited to 'files/common/sbin/p2ptbl')
| -rwxr-xr-x | files/common/sbin/p2ptbl | 79 | 
1 files changed, 61 insertions, 18 deletions
| 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 </dev/null +    mkdir -p "$(dirname $1)" +    [ -f "$1" ] || cat >"$1" </dev/null  } -function get { +get () {      [ -n "$2" ] || printArgs -    grep -P "^$2\t" "$1" | cut -f3- +    grep "^$2"$'\t' "$1" | cut -f3-  } -function update { +update () {      [ -n "$2" -a -n "$3" ] || printArgs -    oldversion=$(grep -P "^$2\t" "$1" | cut -f2) +    oldversion=$(grep "^$2"$'\t' "$1" | cut -f2)      tmpfile="$1.update"      echo -e "$2\t$(($oldversion + 1 + $RANDOM))\t$3" > "$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  	;; | 
