Skip to content
Snippets Groups Projects
Commit 2ae2dc01 authored by Jan Hák's avatar Jan Hák Committed by Daniel Salzman
Browse files

tcpgen: integration of tool for testing TCP (DNS-over-TCP)

parent 86f91e36
No related merge requests found
#!/usr/bin/env bash
#set -x
PKT_OVERHEAD=42
IPTABLES="iptables"
# Discover network setup
function net_discover()
{
UNIQ="guniq"
if [ `uname` = "Linux" ]; then
UNIQ="uniq"
fi
ip4=""; ip6=""; mac=""
addr=""; link=""
if [ "`ssh $1 uname`" = "Linux" ]; then
addr="$(ssh $1 ip -d -o addr|grep ": ${2}"|grep -o -E "(inet|inet6) ([^ ]+)"|grep -v Link|$UNIQ -w 5)"
link="$(ssh $1 ip -d -o link|grep ": ${2}"|grep -o -E "(ether) ([^ ]+)"|$UNIQ -w 5)"
else
addr="$(ssh $1 ifconfig ${2}|grep -o -E "inet(6)? ([^ ]+)"|$UNIQ|grep -v -E "(fe80)|%")"
link="$(ssh $1 ifconfig ${2}|grep -o -E "ether ([^ ]+)"|$UNIQ -w 5)"
fi
while read -r l; do
l=( $(echo $l) )
case ${l[0]} in
inet) ip4=( ${net_v4[@]} $(echo ${l[1]}|cut -d\/ -f1) ) ;;
inet6) ip6=( ${net_v6[@]} $(echo ${l[1]}|cut -d\/ -f1) ) ;;
esac
done <<< "$addr"
while read -r l; do
l=( $(echo $l) )
case ${l[0]} in
ether) mac=( ${net_mac[@]} ${l[1]} ) ;;
esac
done <<< "$link"
# Decide used address
output=()
if [[ ${IP_VERSION} -eq 4 ]]; then
output=("${mac}" "${ip4}")
else
output=("${mac}" "${ip6}")
fi
echo ${output[@]}
}
# Rewrite pcap file according to current network settings
function trace_rewrite()
{
player=( $(echo ${players[$2]}|tr ':' ' ') )
net_dst=( $(net_discover ${target} ${iface}) )
net_src=( $(net_discover ${player[0]} ${player[1]}) )
tcprewrite --dlt=enet -i ${1} -o ${1}.live.${2} &>>${LOG}
tcpprep --auto=client --cachefile=tmp.cache --pcap=${1}.live.${2} &>>${LOG}
if [ -z "${net_dst[1]}" ]; then
echo "FATAL ERROR: net_dst[1] is empty. Is the dst interface UP?"
return
fi
if [ -z "${net_src[1]}" ]; then
echo "FATAL ERROR: net_src[1] is empty. Is the src interface UP?"
return
fi
#Store TCPGen configuration at player
cat <<- CONFIGURATION | ssh -T ${player[0]} "cat > /tmp/tcpgen.conf"
source-mac ${net_src[0]}
destination-mac ${net_dst[0]}
ipv${IP_VERSION}-source-network 10.10.0.0
ipv${IP_VERSION}-source-netmask 255.255.0.0
ipv${IP_VERSION}-destination-ip ${net_dst[1]}
tcp-destination-port ${PORT}
#ip-ipv6-probability 0.5
CONFIGURATION
# Copy rewrited file
scp ${BASEDIR}/${1}.live.${2} ${player[0]}:/tmp/ &>> ${LOG}
#TODO Test on BSD systems
if [ `uname` = "Linux" ]; then
sudo ip -${IP_VERSION} neigh replace "${net_src[1]}" lladdr "${net_src[0]}" dev "${iface}"
fi
RP="arp"
if [ $IP_VERSION -eq "6" ]; then
RP="ndp"
fi
sudo $RP -s ${net_src[1]} ${net_src[0]}
}
function stats() {
RX_bytes=`grep -E "RX bytes" tcpgen.out | awk '{print $3}' | paste -sd+ - | bc`
RX_responses=`grep -E "RX responses" tcpgen.out | awk '{print $3}' | paste -sd+ - | bc`
TX_bytes=`grep -E "TX bytes" tcpgen.out | awk '{print $3}' | paste -sd+ - | bc`
TX_queries=`grep -E "TX queries" tcpgen.out | awk '{print $3}' | paste -sd+ - | bc`
echo ${TX_bytes} ${TX_queries} ${RX_bytes} ${RX_responses}
}
function load_dpdk_driver()
{
[ $# -lt 2 ] && echo "Not enough arguments!"
info=`ssh $1 "dpdk-devbind --status-dev net | grep if=$2"`
original_driver=`echo $info | sed -e "s/^.*drv=//" -e "s/ .*$//"`
bus=`echo $info | awk '{print $1}' | cut -c 6-`
ssh $1 "sudo ip link set $2 down"
ssh $1 "sudo dpdk-devbind -b igb_uio $bus"
echo $bus $original_driver
}
function unload_dpdk_driver()
{
ssh $1 "sudo dpdk-devbind -b $3 $2"
}
# Replay pcap file to nameserver and evaluate number of answered responses
function trace_replay()
{
# Prepare tcpreplay flags
speed="-g 0"
[ "${1}" -gt 0 ] && speed="-g $(( 1000000 * ${#players[@]} / ${1} ))"
duration="-r $(( ${replay_duration:-30} * 1000000 ))"
rflags="-p 1 ${speed} ${duration}"
# Replay the trace files
jobs=()
i=0; while [ ${i} -lt ${#players[@]} ]; do
player=( $(echo ${players[$i]}|tr ':' ' ') )
ret=( $(load_dpdk_driver ${player[0]} ${player[1]}) )
cmd="sudo ~/dpdk-tcp-generator/build/tcpgen -c 1 -- ${rflags} -c /tmp/tcpgen.conf --pcap /tmp/${2}.live.${i}"
(ssh "${player[0]}" "${cmd}" 2>&1 | grep -ve 'EAL' >> tcpgen.out) &
jobs=( ${jobs[@]} $! )
bus=( ${bus[@]} ${ret[0]} )
drivers=( ${drivers[@]} ${ret[1]} )
(( i += 1 ))
done
i=0; while [ ${i} -lt ${#players[@]} ]; do
wait ${jobs[$i]}
player=( $(echo ${players[$i]}|tr ':' ' ') )
unload_dpdk_driver $player ${bus[$i]} ${drivers[$i]}
(( i += 1 ))
done
# Wait for delayed packets
sleep ${replay_duration:-30}
statistics=( $(stats) )
query_size="${statistics[0]}"
query_pkts="${statistics[1]}"
reply_size="${statistics[2]}"
reply_pkts="${statistics[3]}"
# Calculate results
answered=$(bc <<< "scale=2; ${reply_pkts}*100.0/${query_pkts}")
query_rate=$(bc <<< "scale=0; ${query_pkts}/${replay_duration:-30}")
reply_rate=$(bc <<< "scale=0; ${reply_pkts}/${replay_duration:-30}")
query_avglen=$(bc <<< "scale=0; ${query_size}/${query_pkts}")
reply_avglen=$(bc <<< "scale=0; ${reply_size}/${reply_pkts}")
echo ${answered} ${query_rate} ${query_avglen} ${reply_rate} ${reply_avglen}
}
function module_init()
{
line=`tar --gzip --list --verbose --file=${DATADIR}/${2}.tgz | grep .pcap`
if [[ `uname` == "Linux" ]]; then
TRACE=`echo $line | awk '{print $6}'`
else
TRACE=`echo $line | awk '{print $9}'`
fi
#Get number of IPv from pcap file
ip=${TRACE:11:1}
IP_VERSION=$ip
# Check for IPv6 measurement
if [ ${ip} ] && [ ${ip} = "6" ]; then
PKT_OVERHEAD=62
IPTABLES="ip6tables"
fi
if [ ! -f ${TRACE} ]; then
echo "'${TRACE}' not found, skipping"
return 1
fi
# Populate address list
addr=( $(net_discover ${target} ${iface}) )
ADDRLIST=( 127.0.0.1 ${addr[1]} )
}
function module_exec()
{
output="${BASEDIR}/results/${1}.data"
# Drop filesystem and page caches
sudo sync
echo 3|sudo tee /proc/sys/vm/drop_caches &>/dev/null
# Start nameserver
ns_prep ${NAMECONF}
ns_start ${NAMECONF}
if [ $? -gt 0 ]; then
echo "error: failed to start '${1}'"
return 1
fi
if [[ `uname` != "Linux" ]]; then
SEQ="gseq"
else
SEQ="seq"
fi
# Perform measurement of answered queries
do_rates=(0)
if [ "${replay_rates}" ]; then
if [ "${replay_step}" ] && [ ${#replay_rates[@]} -ge 2 ]; then
do_rates=( $(${SEQ} ${replay_rates[0]} ${replay_step} ${replay_rates[1]}) )
else
do_rates=${replay_rates[@]}
fi
fi
# Prepare pcap files for replaying
i=0; while [ ${i} -lt ${#players[@]} ]; do
trace_rewrite ${TRACE} ${i}
if [ $? -ne 0 ]; then
echo "error: failed to prepare tracefile for ${players[$i]}"
return 1
fi
(( i += 1 ))
done
# Replay the pcap files
for pps in ${do_rates[@]}; do
result=( $(trace_replay ${pps} ${TRACE}) )
[ ${pps} -eq 0 ] && pps="maximum"
echo "${1} ${result[0]} % answered for ${result[1]} q/s, ${result[2]} B avg (${result[3]} a/s, ${result[4]} B avg)"
echo -e "${result[1]}\t${result[0]}\t${result[2]}" >> ${output}.tmp
done
# Stop nameserver
ns_stop ${NAMECONF}
# Save results
echo -e "# $(ns_info)" > ${output}
cat ${output}.tmp|sort -n >> ${output}
rm ${output}.tmp
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment