#!/bin/bash shopt -s extglob if [ "`uname -s`" = "Darwin" ] ; then export nwif=en0 libsuffix=.0.dylib else export nwif=eth0 libsuffix=.so.0 fi bandwidth="" remotedir="$PWD" provision=false asynclist="sync async" modelist="listener polling waitset" modelistdefault=true rate="" sizelist="0 20 50 100 200 500 1000 2000 5000 10000 20000 50000 100000 200000 500000 1000000" timeout=30 loopback=true resultdir="throughput-result" resultdirdefault=true force=false netstats=false watermarks="" remotes="" security="none" operation=throughput usage () { cat >&2 <&2 ; exit 1 ;; esac for m in $modelist ; do case $m in $allowedmodes) ;; *) echo "unsupported mode \"$m\" for operation \"$operation\"" >&2 ; exit 1 ;; esac done for a in $asynclist ; do case $a in sync|async) ;; *) echo "unsupported sync/async \"$a\" for operation \"$operation\"" >&2 ; exit 1 ;; esac done case "$security" in none) gensec=false gensec_governance=false ;; sign|encrypt|rtps-sign|rtps-encrypt|metadata-sign|metadata-encrypt|payload-encrypt) gensec=true gensec_governance=true ;; *.xml) cp "$security" $secdir/governance.xml || exit 1 gensec=true gensec_governance=false ;; *) echo "unsupport security mode \"$security\"" >&2 ; exit 1 ;; esac secfiles="secperf/sloth_priv_key.pem secperf/sloth_cert.pem secperf/id_ca_cert.pem secperf/perm_ca_cert.pem secperf/governance.p7s secperf/permissions.p7s" if $gensec ; then mkdir -p secperf || { echo "can't create secperf directory" >&2 ; exit 1 ; } if [ "`uname -s`" = "Darwin" -a "`which openssl`" = /usr/bin/openssl ] ; then if which brew >/dev/null 2>&1 ; then openssl="`brew --prefix openssl`/bin/openssl" fi else openssl=openssl fi [ -n "$openssl" ] || { echo "this needs a functioning openssl executable" 2>&1 ; exit 1 ; } if $gensec_governance ; then case $security in rtps-sign|sign) rtps_protection=SIGN metadata_protection=NONE data_protection=NONE ;; rtps-encrypt) rtps_protection=ENCRYPT metadata_protection=NONE data_protection=NONE ;; metadata-sign) rtps_protection=NONE metadata_protection=SIGN data_protection=NONE ;; metadata-encrypt) rtps_protection=NONE metadata_protection=ENCRYPT data_protection=NONE ;; payload-encrypt|encrypt) rtps_protection=NONE metadata_protection=NONE data_protection=ENCRYPT ;; *) exit 1 ;; esac cat >secperf/governance.xml < 0 230 false true NONE NONE $rtps_protection * true true true true $metadata_protection $data_protection EOF cat >secperf/permissions.xml < emailAddress=alice@cycloneddssecurity.adlinktech.com,CN=Alice Example,O=Example Organization,OU=Organizational Unit Name,L=Locality Name,ST=OV,C=NL 2020-01-01T01:00:00 2120-01-01T01:00:00 0 230 * * * * DENY EOF # generate any missing keys/certificates [ -r secperf/id_ca_priv_key.pem ] || $openssl genrsa -out secperf/id_ca_priv_key.pem 2048 [ -r secperf/id_ca_cert.pem ] || $openssl req -x509 -key secperf/id_ca_priv_key.pem -out secperf/id_ca_cert.pem -days 3650 -subj "/C=NL/ST=OV/L=Locality Name/OU=Example OU/O=Example ID CA Organization/CN=Example ID CA/emailAddress=authority@cycloneddssecurity.adlinktech.com" [ -r secperf/perm_ca_priv_key.pem ] || $openssl genrsa -out secperf/perm_ca_priv_key.pem 2048 [ -r secperf/perm_ca_cert.pem ] || $openssl req -x509 -key secperf/perm_ca_priv_key.pem -out secperf/perm_ca_cert.pem -days 3650 -subj "/C=NL/ST=OV/L=Locality Name/OU=Example OU/O=Example CA Organization/CN=Example Permissions CA/emailAddress=authority@cycloneddssecurity.adlinktech.com" [ -r secperf/sloth_priv_key.pem ] || $openssl genrsa -out secperf/sloth_priv_key.pem 2048 [ -r secperf/sloth.csr ] || $openssl req -new -key secperf/sloth_priv_key.pem -out secperf/sloth.csr -subj "/C=NL/ST=OV/L=Locality Name/OU=Organizational Unit Name/O=Example Organization/CN=Alice Example/emailAddress=alice@cycloneddssecurity.adlinktech.com" [ -r secperf/sloth_cert.pem ] || $openssl x509 -req -CA secperf/id_ca_cert.pem -CAkey secperf/id_ca_priv_key.pem -CAcreateserial -days 3650 -in secperf/sloth.csr -out secperf/sloth_cert.pem # always sign permissions, governance $openssl smime -sign -in secperf/permissions.xml -text -out secperf/permissions.p7s -signer secperf/perm_ca_cert.pem -inkey secperf/perm_ca_priv_key.pem $openssl smime -sign -in secperf/governance.xml -text -out secperf/governance.p7s -signer secperf/perm_ca_cert.pem -inkey secperf/perm_ca_priv_key.pem fi fi [ -z "$rnwif" ] && rnwif=$nwif cfg=cdds-simple.xml cat >$cfg < $loopback 65500B EOF if [ "$security" != "none" ] ; then cat >>$cfg < file:\${secdir}/id_ca_cert.pem file:\${secdir}/sloth_cert.pem file:\${secdir}/sloth_priv_key.pem file:\${secdir}/perm_ca_cert.pem file:\${secdir}/governance.p7s file:\${secdir}/permissions.p7s EOF fi cat >>$cfg < 2s \${async:-0} $watermarks fine \${trace} \${logdir}/cdds.log EOF localbindir="" locallibdir="" for x in "" /Release /RelWithDebInfo /Debug ; do if [ -x bin$x/ddsperf -a -f lib$x/libddsc$libsuffix ] ; then localbindir=bin$x locallibdir=lib$x break fi done if [ -z "$localbindir" -o -z "$locallibdir" ] ; then echo "ddsperf or libddsc$libsuffix not found on the local machine" >&2 exit 1 fi if [ ! -d $resultdir ] ; then mkdir $resultdir elif $force ; then rm -rf $resultdir mkdir $resultdir elif [ `ls $resultdir | wc -l` -gt 0 ] ; then echo "output directory $resultdir is non-empty" >&2 exit 1 fi [ -d $resultdir ] || { echo "output directory $resultdir doesn't exist" >&2 ; exit 1 ; } if $provision ; then echo "provisioning ..." for r in $remotes ; do ssh $r mkdir -p $remotedir $remotedir/bin $remotedir/lib scp $locallibdir/libddsc$libsuffix $r:$remotedir/lib scp $localbindir/ddsperf $r:$remotedir/bin done fi if [ "$security" != "none" ] ; then for r in $remotes ; do ssh $r mkdir -p $remotedir $remotedir/secperf scp $secfiles $r:$remotedir/secperf done fi topic=KS [ -z "$sizelist" ] && topic=OU export CYCLONEDDS_URI=file://$PWD/$cfg for r in $remotes ; do scp $cfg $r:$remotedir || { echo "failed to copy $cfg to $remote:$PWD" >&2 ; exit 1 ; } done for async_mode in $asynclist ; do case "$async_mode" in sync) async=0 ;; async) async=1 ;; *) echo "$async_mode: invalid setting for ASYNC" >&2 ; continue ;; esac export async for sub_mode in $modelist ; do echo "======== ASYNC $async MODE $sub_mode =========" subpids="" netstat_pids="" trap dokill_and_exit SIGINT cat > run-remote.tmp <&2 exit 1 fi #/usr/sbin/tcpdump -c 20000 -s 0 -w /tmp/x.pcap -i eth0 -Z erik 'udp[8:4]=0x52545053' & tcpdumppid=\$! #/usr/sbin/tcpdump -c 20000 -s 0 -w /tmp/x.pcap -i eth0 -Z erik 'udp' & tcpdumppid=\$! \$remotebindir/ddsperf -1l -X -d $rnwif$bandwidth -c -T $topic $remote_oper $sub_mode > $remote_oper.log & pid=\$! echo \$pid > $operation-test-$remote_oper-\$pid.pid wait \$pid [ -n "\$tcpdumppid" ] && kill -INT \$tcpdumppid EOF for r in $remotes ; do scp run-remote.tmp $r:$remotedir ssh $r ". $remotedir/run-remote.tmp" & subpids="$subpids $!" done outdir=$resultdir/$async_mode-$sub_mode mkdir $outdir rm -f $outdir/$local_oper.log export logdir=$outdir export secdir=./secperf if $netstats ; then ping `echo $1 | sed -e 's/.*@//'` > $outdir/icmpping.log & netstats_pids=$! if [ "`uname -s`" = "Darwin" ] ; then rm -f $outdir/netstat.log bash -c "while true ; do /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I >> $outdir/netstat.log ; sleep 1; done" & netstats_pids="$netstats_pids $!" fi fi for size in ${sizelist:-0} ; do echo "size $size" #export trace=trace,-content $localbindir/ddsperf -Q minmatch:$# -Q initwait:3 \ -X -c -d $nwif$bandwidth \ -D $timeout -T $topic \ $local_oper size $size $rate | \ tee -a $outdir/$local_oper.log done dokill wait for r in $remotes ; do scp $r:$remotedir/$remote_oper.log $outdir/$remote_oper-$r.log done if [ $operation = "throughput" ] ; then # write a summary, one line per second # col 0: raw network receive bandwidth (Mb/s) # col 1: appl receive bandwidth, 1s trailing average (Mb/s) # col 2: appl receive bandwidth, 10s trailing average (Mb/s) # (this assumes the network interface name is eth, en, or lo, optionally followed by a 0) perl -ne 'if(/size \d+ total.* (\d+\.\d+) Mb\/s.* (\d+\.\d+) Mb\/s/){$r=$1;$r10=$2;}if(/(?:eth|en|lo)0?: xmit.*? recv (\d+\.\d+)/){$rnet=$1;}if(/discarded\s+(\d+)/){printf "%f %f %f %u\n", $rnet, $r, $r10, $1;}' $outdir/sub-$1.log > $resultdir/summary-$async_mode-$sub_mode.txt perl -ne 'if(/(?:eth|en|lo)0?: xmit (\d+\.\d+) Mb\/s/){printf "%f\n", $1}' $outdir/pub.log > $resultdir/net-xmit-bytes.txt perl -ne 'print "$1 $2 $3 $4 $5\n" if /^(\d+)\s+(\d+)(\s+\d+)$/ || /^\[\d+\]\s+(\d+\.\d+)\s+discarded\s+\d+\s+rexmit\s+(\d+)\s+[A-Za-z_ ]+(\d+)[A-Za-z_ ]+(\d+)[A-Za-z_ ]+(\d+)$/' $outdir/pub.log > $resultdir/rexmit-bytes.txt if $netstats ; then perl -ne 'print "$1\n" if /time=([0-9.]+)/' $outdir/icmpping.log > $resultdir/lat.log if [ "`uname -s`" = "Darwin" ] ; then perl -ne 'if(/CtlRSSI:\s*(-?\d+)/){$rssi=$1;}if(/CtlNoise:\s*(-?\d+)/){$noise=$1;}if(/maxRate:\s*(\d+)/){$max=$1;}if(/lastTxRate:\s*(\d+)/){$lasttx=$1;print "$max $lasttx $rssi $noise\n"}' $outdir/netstat.log > $resultdir/net.log fi fi fi done done