From d64ac269856744b9bab170964e1d6f36896ecc55 Mon Sep 17 00:00:00 2001 From: t3sserakt Date: Thu, 14 Oct 2021 16:39:24 +0200 Subject: removed versioned artefacts with v2 and v3. changes to reflect the changes in testing_api_loop.c --- src/testing/Makefile.am | 4 - src/testing/netjail_core.sh | 190 +++++- src/testing/netjail_core_v2.sh | 260 -------- src/testing/netjail_exec.sh | 6 +- src/testing/netjail_exec_v2.sh | 14 - src/testing/netjail_start.sh | 70 +- src/testing/netjail_start_v2.sh | 74 --- src/testing/netjail_stop.sh | 49 +- src/testing/netjail_stop_v2.sh | 59 -- src/testing/testing.c | 30 +- ...testing_api_cmd_block_until_all_peers_started.c | 6 + .../testing_api_cmd_block_until_external_trigger.c | 63 +- src/testing/testing_api_cmd_netjail_start.c | 71 +- .../testing_api_cmd_netjail_start_testsystem.c | 327 ++++++---- .../testing_api_cmd_netjail_start_testsystem_v2.c | 723 --------------------- src/testing/testing_api_cmd_netjail_start_v2.c | 209 ------ src/testing/testing_api_cmd_netjail_stop.c | 54 +- .../testing_api_cmd_netjail_stop_testsystem.c | 79 ++- .../testing_api_cmd_netjail_stop_testsystem_v2.c | 141 ---- src/testing/testing_api_cmd_netjail_stop_v2.c | 185 ------ src/testing/testing_api_loop.c | 8 +- src/testing/testing_cmds.h | 2 + 22 files changed, 665 insertions(+), 1959 deletions(-) delete mode 100755 src/testing/netjail_core_v2.sh delete mode 100755 src/testing/netjail_exec_v2.sh delete mode 100755 src/testing/netjail_start_v2.sh delete mode 100755 src/testing/netjail_stop_v2.sh delete mode 100644 src/testing/testing_api_cmd_netjail_start_testsystem_v2.c delete mode 100644 src/testing/testing_api_cmd_netjail_start_v2.c delete mode 100644 src/testing/testing_api_cmd_netjail_stop_testsystem_v2.c delete mode 100644 src/testing/testing_api_cmd_netjail_stop_v2.c (limited to 'src/testing') diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am index e9389a876..39e85c4ac 100644 --- a/src/testing/Makefile.am +++ b/src/testing/Makefile.am @@ -51,13 +51,9 @@ libgnunettesting_la_SOURCES = \ testing_api_cmd_block_until_all_peers_started.c \ testing_api_cmd_block_until_external_trigger.c \ testing_api_cmd_netjail_start.c \ - testing_api_cmd_netjail_start_v2.c \ testing_api_cmd_netjail_start_testsystem.c \ - testing_api_cmd_netjail_start_testsystem_v2.c \ testing_api_cmd_netjail_stop_testsystem.c \ - testing_api_cmd_netjail_stop_testsystem_v2.c \ testing_api_cmd_netjail_stop.c \ - testing_api_cmd_netjail_stop_v2.c \ testing.c testing.h \ testing_api_cmd_system_create.c \ testing_api_cmd_system_destroy.c \ diff --git a/src/testing/netjail_core.sh b/src/testing/netjail_core.sh index cf350d3fa..ef0a54a5e 100755 --- a/src/testing/netjail_core.sh +++ b/src/testing/netjail_core.sh @@ -2,6 +2,7 @@ # +PREFIX=${PPID:?must run from a parent process} # running with `sudo` is required to be # able running the actual commands as the @@ -9,10 +10,61 @@ export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" -netjail_check() { - NODE_COUNT=$1 +export RESULT= +export NAMESPACE_NUM=0 +export INTERFACE_NUM=0 + +netjail_next_namespace() { + local NUM=$NAMESPACE_NUM + NAMESPACE_NUM=$(($NAMESPACE_NUM + 1)) + RESULT=$NUM +} + +netjail_next_interface() { + local NUM=$INTERFACE_NUM + INTERFACE_NUM=$(($INTERFACE_NUM + 1)) + RESULT=$NUM +} + +netjail_opt() { + local OPT=$1 + shift 1 + + INDEX=1 + + while [ $# -gt 0 ]; do + if [ "$1" = "$OPT" ]; then + RESULT=$INDEX + return + fi + + INDEX=$(($INDEX + 1)) + shift 1 + done + + RESULT=0 +} + +netjail_opts() { + local OPT=$1 + local DEF=$2 + shift 2 + + while [ $# -gt 0 ]; do + if [ "$1" = "$OPT" ]; then + printf "$2" + return + fi + + shift 1 + done + + RESULT="$DEF" +} - FD_COUNT=$(($(ls /proc/self/fd | wc -w) - 4)) +netjail_check() { + local NODE_COUNT=$1 + local FD_COUNT=$(($(ls /proc/self/fd | wc -w) - 4)) # quit if `$FD_COUNT < ($LOCAL_M * $GLOBAL_N * 2)`: # the script also requires `sudo -C ($FD_COUNT + 4)` @@ -25,43 +77,81 @@ netjail_check() { fi } -netjail_print_name() { - printf "%s%02x%02x" $1 $2 ${3:-0} +netjail_check_bin() { + local PROGRAM=$1 + local MATCH=$(ls $(echo $PATH | tr ":" "\n") | grep "^$PROGRAM\$" | tr "\n" " " | awk '{ print $1 }') + + # quit if the required binary $PROGRAM can not be + # found in the used $PATH. + + if [ "$MATCH" != "$PROGRAM" ]; then + echo "Required binary not found: $PROGRAM" >&2 + exit 1 + fi } netjail_bridge() { - BRIDGE=$1 + netjail_next_interface + local NUM=$RESULT + local BRIDGE=$(printf "%06x-%08x" $PREFIX $NUM) ip link add $BRIDGE type bridge ip link set dev $BRIDGE up + + RESULT=$BRIDGE +} + +netjail_bridge_name() { + netjail_next_interface + local NUM=$RESULT + local BRIDGE=$(printf "%06x-%08x" $PREFIX $NUM) + + RESULT=$BRIDGE } netjail_bridge_clear() { - BRIDGE=$1 + local BRIDGE=$1 ip link delete $BRIDGE } netjail_node() { - NODE=$1 + netjail_next_namespace + local NUM=$RESULT + local NODE=$(printf "%06x-%08x" $PREFIX $NUM) ip netns add $NODE + + RESULT=$NODE +} + +netjail_node_name() { + netjail_next_namespace + local NUM=$RESULT + local NODE=$(printf "%06x-%08x" $PREFIX $NUM) + + RESULT=$NODE } netjail_node_clear() { - NODE=$1 + local NODE=$1 ip netns delete $NODE } netjail_node_link_bridge() { - NODE=$1 - BRIDGE=$2 - ADDRESS=$3 - MASK=$4 + local NODE=$1 + local BRIDGE=$2 + local ADDRESS=$3 + local MASK=$4 - LINK_IF="$NODE-$BRIDGE-0" - LINK_BR="$NODE-$BRIDGE-1" + netjail_next_interface + local NUM_IF=$RESULT + netjail_next_interface + local NUM_BR=$RESULT + + local LINK_IF=$(printf "%06x-%08x" $PREFIX $NUM_IF) + local LINK_BR=$(printf "%06x-%08x" $PREFIX $NUM_BR) ip link add $LINK_IF type veth peer name $LINK_BR ip link set $LINK_IF netns $NODE @@ -72,28 +162,47 @@ netjail_node_link_bridge() { ip -n $NODE link set up dev lo ip link set $LINK_BR up + + RESULT=$LINK_BR +} + +netjail_node_link_bridge_name() { + + netjail_next_interface + netjail_next_interface + local NUM_BR=$RESULT + + local LINK_BR=$(printf "%06x-%08x" $PREFIX $NUM_BR) + + RESULT=$LINK_BR +} + +netjail_node_unlink_bridge() { + local LINK_BR=$1 + + ip link delete $LINK_BR } netjail_node_add_nat() { - NODE=$1 - ADDRESS=$2 - MASK=$3 + local NODE=$1 + local ADDRESS=$2 + local MASK=$3 ip netns exec $NODE iptables -t nat -A POSTROUTING -s "$ADDRESS/$MASK" -j MASQUERADE } netjail_node_add_default() { - NODE=$1 - ADDRESS=$2 + local NODE=$1 + local ADDRESS=$2 ip -n $NODE route add default via $ADDRESS } netjail_node_exec() { JAILOR=${SUDO_USER:?must run in sudo} - NODE=$1 - FD_IN=$2 - FD_OUT=$3 + local NODE=$1 + local FD_IN=$2 + local FD_OUT=$3 shift 3 ip netns exec $NODE sudo -u $JAILOR -- $@ 1>& $FD_OUT 0<& $FD_IN @@ -114,3 +223,38 @@ netjail_node_exec_without_fds_and_sudo() { ip netns exec $NODE $@ } +netjail_kill() { + local PID=$1 + local MATCH=$(ps --pid $PID | awk "{ if ( \$1 == $PID ) { print \$1 } }" | wc -l) + + if [ $MATCH -gt 0 ]; then + kill -n 19 $PID + + for CHILD in $(ps -o pid,ppid -ax | awk "{ if ( \$2 == $PID ) { print \$1 } }"); do + netjail_kill $CHILD + done + + kill $PID + fi +} + +netjail_killall() { + if [ $# -gt 0 ]; then + local PIDS=$1 + + for PID in $PIDS; do + netjail_kill $PID + done + fi +} + +netjail_waitall() { + if [ $# -gt 0 ]; then + local PIDS=$1 + + for PID in $PIDS; do + wait $PID + done + fi +} + diff --git a/src/testing/netjail_core_v2.sh b/src/testing/netjail_core_v2.sh deleted file mode 100755 index ef0a54a5e..000000000 --- a/src/testing/netjail_core_v2.sh +++ /dev/null @@ -1,260 +0,0 @@ -#!/bin/sh -# - - -PREFIX=${PPID:?must run from a parent process} - -# running with `sudo` is required to be -# able running the actual commands as the -# original user. - -export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - -export RESULT= -export NAMESPACE_NUM=0 -export INTERFACE_NUM=0 - -netjail_next_namespace() { - local NUM=$NAMESPACE_NUM - NAMESPACE_NUM=$(($NAMESPACE_NUM + 1)) - RESULT=$NUM -} - -netjail_next_interface() { - local NUM=$INTERFACE_NUM - INTERFACE_NUM=$(($INTERFACE_NUM + 1)) - RESULT=$NUM -} - -netjail_opt() { - local OPT=$1 - shift 1 - - INDEX=1 - - while [ $# -gt 0 ]; do - if [ "$1" = "$OPT" ]; then - RESULT=$INDEX - return - fi - - INDEX=$(($INDEX + 1)) - shift 1 - done - - RESULT=0 -} - -netjail_opts() { - local OPT=$1 - local DEF=$2 - shift 2 - - while [ $# -gt 0 ]; do - if [ "$1" = "$OPT" ]; then - printf "$2" - return - fi - - shift 1 - done - - RESULT="$DEF" -} - -netjail_check() { - local NODE_COUNT=$1 - local FD_COUNT=$(($(ls /proc/self/fd | wc -w) - 4)) - - # quit if `$FD_COUNT < ($LOCAL_M * $GLOBAL_N * 2)`: - # the script also requires `sudo -C ($FD_COUNT + 4)` - # so you need 'Defaults closefrom_override' in the - # sudoers file. - - if [ $FD_COUNT -lt $(($NODE_COUNT * 2)) ]; then - echo "File descriptors do not match requirements!" >&2 - exit 1 - fi -} - -netjail_check_bin() { - local PROGRAM=$1 - local MATCH=$(ls $(echo $PATH | tr ":" "\n") | grep "^$PROGRAM\$" | tr "\n" " " | awk '{ print $1 }') - - # quit if the required binary $PROGRAM can not be - # found in the used $PATH. - - if [ "$MATCH" != "$PROGRAM" ]; then - echo "Required binary not found: $PROGRAM" >&2 - exit 1 - fi -} - -netjail_bridge() { - netjail_next_interface - local NUM=$RESULT - local BRIDGE=$(printf "%06x-%08x" $PREFIX $NUM) - - ip link add $BRIDGE type bridge - ip link set dev $BRIDGE up - - RESULT=$BRIDGE -} - -netjail_bridge_name() { - netjail_next_interface - local NUM=$RESULT - local BRIDGE=$(printf "%06x-%08x" $PREFIX $NUM) - - RESULT=$BRIDGE -} - -netjail_bridge_clear() { - local BRIDGE=$1 - - ip link delete $BRIDGE -} - -netjail_node() { - netjail_next_namespace - local NUM=$RESULT - local NODE=$(printf "%06x-%08x" $PREFIX $NUM) - - ip netns add $NODE - - RESULT=$NODE -} - -netjail_node_name() { - netjail_next_namespace - local NUM=$RESULT - local NODE=$(printf "%06x-%08x" $PREFIX $NUM) - - RESULT=$NODE -} - -netjail_node_clear() { - local NODE=$1 - - ip netns delete $NODE -} - -netjail_node_link_bridge() { - local NODE=$1 - local BRIDGE=$2 - local ADDRESS=$3 - local MASK=$4 - - netjail_next_interface - local NUM_IF=$RESULT - netjail_next_interface - local NUM_BR=$RESULT - - local LINK_IF=$(printf "%06x-%08x" $PREFIX $NUM_IF) - local LINK_BR=$(printf "%06x-%08x" $PREFIX $NUM_BR) - - ip link add $LINK_IF type veth peer name $LINK_BR - ip link set $LINK_IF netns $NODE - ip link set $LINK_BR master $BRIDGE - - ip -n $NODE addr add "$ADDRESS/$MASK" dev $LINK_IF - ip -n $NODE link set $LINK_IF up - ip -n $NODE link set up dev lo - - ip link set $LINK_BR up - - RESULT=$LINK_BR -} - -netjail_node_link_bridge_name() { - - netjail_next_interface - netjail_next_interface - local NUM_BR=$RESULT - - local LINK_BR=$(printf "%06x-%08x" $PREFIX $NUM_BR) - - RESULT=$LINK_BR -} - -netjail_node_unlink_bridge() { - local LINK_BR=$1 - - ip link delete $LINK_BR -} - -netjail_node_add_nat() { - local NODE=$1 - local ADDRESS=$2 - local MASK=$3 - - ip netns exec $NODE iptables -t nat -A POSTROUTING -s "$ADDRESS/$MASK" -j MASQUERADE -} - -netjail_node_add_default() { - local NODE=$1 - local ADDRESS=$2 - - ip -n $NODE route add default via $ADDRESS -} - -netjail_node_exec() { - JAILOR=${SUDO_USER:?must run in sudo} - local NODE=$1 - local FD_IN=$2 - local FD_OUT=$3 - shift 3 - - ip netns exec $NODE sudo -u $JAILOR -- $@ 1>& $FD_OUT 0<& $FD_IN -} - -netjail_node_exec_without_fds() { - JAILOR=${SUDO_USER:?must run in sudo} - NODE=$1 - shift 1 - - ip netns exec $NODE sudo -u $JAILOR -- $@ -} - -netjail_node_exec_without_fds_and_sudo() { - NODE=$1 - shift 1 - - ip netns exec $NODE $@ -} - -netjail_kill() { - local PID=$1 - local MATCH=$(ps --pid $PID | awk "{ if ( \$1 == $PID ) { print \$1 } }" | wc -l) - - if [ $MATCH -gt 0 ]; then - kill -n 19 $PID - - for CHILD in $(ps -o pid,ppid -ax | awk "{ if ( \$2 == $PID ) { print \$1 } }"); do - netjail_kill $CHILD - done - - kill $PID - fi -} - -netjail_killall() { - if [ $# -gt 0 ]; then - local PIDS=$1 - - for PID in $PIDS; do - netjail_kill $PID - done - fi -} - -netjail_waitall() { - if [ $# -gt 0 ]; then - local PIDS=$1 - - for PID in $PIDS; do - wait $PID - done - fi -} - diff --git a/src/testing/netjail_exec.sh b/src/testing/netjail_exec.sh index 17a7caaac..cd993a39b 100755 --- a/src/testing/netjail_exec.sh +++ b/src/testing/netjail_exec.sh @@ -9,8 +9,6 @@ export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" M=$1 N=$2 -NODE=$(netjail_print_name "N" $N $M) +NODE=$6 - - -netjail_node_exec_without_fds_and_sudo $NODE $3 $4 $5 $1 $2 +netjail_node_exec_without_fds_and_sudo $NODE $3 $4 $5 $1 $2 diff --git a/src/testing/netjail_exec_v2.sh b/src/testing/netjail_exec_v2.sh deleted file mode 100755 index 597baad20..000000000 --- a/src/testing/netjail_exec_v2.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -. "./../testing/netjail_core_v2.sh" - -set -eu -set -x - -export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - -M=$1 -N=$2 - -NODE=$6 - -netjail_node_exec_without_fds_and_sudo $NODE $3 $4 $5 $1 $2 diff --git a/src/testing/netjail_start.sh b/src/testing/netjail_start.sh index 0984a3c42..1dfe1dfdf 100755 --- a/src/testing/netjail_start.sh +++ b/src/testing/netjail_start.sh @@ -1,52 +1,74 @@ -#!/bin/sh +#!/bin/bash . "./../testing/netjail_core.sh" +. "./../testing/topo.sh" set -eu set -x export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" -LOCAL_M=$1 -GLOBAL_N=$2 +filename=$1 +PREFIX=$2 -# TODO: stunserver? ..and globally known peer? +read_topology $filename shift 2 LOCAL_GROUP="192.168.15" GLOBAL_GROUP="92.68.150" +KNOWN_GROUP="92.68.151" -NETWORK_NET=$(netjail_print_name "n" $GLOBAL_N $LOCAL_M) -netjail_bridge $NETWORK_NET +echo "Start [local: $LOCAL_GROUP.0/24, global: $GLOBAL_GROUP.0/16]" -for N in $(seq $GLOBAL_N); do - ROUTER=$(netjail_print_name "R" $N) +netjail_bridge +NETWORK_NET=$RESULT - netjail_node $ROUTER - netjail_node_link_bridge $ROUTER $NETWORK_NET "$GLOBAL_GROUP.$N" 24 +for X in $(seq $KNOWN); do + netjail_node + KNOWN_NODES[$X]=$RESULT + netjail_node_link_bridge ${KNOWN_NODES[$X]} $NETWORK_NET "$KNOWN_GROUP.$X" 16 + KNOWN_LINKS[$X]=$RESULT +done - ROUTER_NET=$(netjail_print_name "r" $N) +declare -A NODES +declare -A NODE_LINKS - netjail_bridge $ROUTER_NET +for N in $(seq $GLOBAL_N); do + netjail_node + ROUTERS[$N]=$RESULT + netjail_node_link_bridge ${ROUTERS[$N]} $NETWORK_NET "$GLOBAL_GROUP.$N" 16 + NETWORK_LINKS[$N]=$RESULT + netjail_bridge + ROUTER_NETS[$N]=$RESULT for M in $(seq $LOCAL_M); do - NODE=$(netjail_print_name "N" $N $M) - - netjail_node $NODE - netjail_node_link_bridge $NODE $ROUTER_NET "$LOCAL_GROUP.$M" 24 + netjail_node + NODES[$N,$M]=$RESULT + netjail_node_link_bridge ${NODES[$N,$M]} ${ROUTER_NETS[$N]} "$LOCAL_GROUP.$M" 24 + NODE_LINKS[$N,$M]=$RESULT done ROUTER_ADDR="$LOCAL_GROUP.$(($LOCAL_M+1))" - - netjail_node_link_bridge $ROUTER $ROUTER_NET $ROUTER_ADDR 24 - netjail_node_add_nat $ROUTER $ROUTER_ADDR 24 + netjail_node_link_bridge ${ROUTERS[$N]} ${ROUTER_NETS[$N]} $ROUTER_ADDR 24 + ROUTER_LINKS[$N]=$RESULT + + netjail_node_add_nat ${ROUTERS[$N]} $ROUTER_ADDR 24 for M in $(seq $LOCAL_M); do - NODE=$(netjail_print_name "N" $N $M) - - netjail_node_add_default $NODE $ROUTER_ADDR + netjail_node_add_default ${NODES[$N,$M]} $ROUTER_ADDR done -done - + # TODO Topology configuration must be enhanced to configure forwarding to more than one subnet node via different ports. + + if [ "1" == "${R_TCP[$N]}" ] + then + ip netns exec ${ROUTERS[$N]} iptables -t nat -A PREROUTING -p tcp -d $GLOBAL_GROUP.$N --dport 60002 -j DNAT --to $LOCAL_GROUP.1 + ip netns exec ${ROUTERS[$N]} iptables -A FORWARD -d $LOCAL_GROUP.1 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT + fi + if [ "1" == "${R_UDP[$N]}" ] + then + ip netns exec ${ROUTERS[$N]} iptables -t nat -A PREROUTING -p udp -d $GLOBAL_GROUP.$N --dport 60002 -j DNAT --to $LOCAL_GROUP.1 + ip netns exec ${ROUTERS[$N]} iptables -A FORWARD -d $LOCAL_GROUP.1 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT + fi +done diff --git a/src/testing/netjail_start_v2.sh b/src/testing/netjail_start_v2.sh deleted file mode 100755 index dd1f2ad93..000000000 --- a/src/testing/netjail_start_v2.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/bash -. "./../testing/netjail_core_v2.sh" -. "./../testing/topo.sh" - -set -eu -set -x - -export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - -filename=$1 -PREFIX=$2 - -read_topology $filename - -shift 2 - -LOCAL_GROUP="192.168.15" -GLOBAL_GROUP="92.68.150" -KNOWN_GROUP="92.68.151" - - -echo "Start [local: $LOCAL_GROUP.0/24, global: $GLOBAL_GROUP.0/16]" - -netjail_bridge -NETWORK_NET=$RESULT - -for X in $(seq $KNOWN); do - netjail_node - KNOWN_NODES[$X]=$RESULT - netjail_node_link_bridge ${KNOWN_NODES[$X]} $NETWORK_NET "$KNOWN_GROUP.$X" 16 - KNOWN_LINKS[$X]=$RESULT -done - -declare -A NODES -declare -A NODE_LINKS - -for N in $(seq $GLOBAL_N); do - netjail_node - ROUTERS[$N]=$RESULT - netjail_node_link_bridge ${ROUTERS[$N]} $NETWORK_NET "$GLOBAL_GROUP.$N" 16 - NETWORK_LINKS[$N]=$RESULT - netjail_bridge - ROUTER_NETS[$N]=$RESULT - - for M in $(seq $LOCAL_M); do - netjail_node - NODES[$N,$M]=$RESULT - netjail_node_link_bridge ${NODES[$N,$M]} ${ROUTER_NETS[$N]} "$LOCAL_GROUP.$M" 24 - NODE_LINKS[$N,$M]=$RESULT - done - - ROUTER_ADDR="$LOCAL_GROUP.$(($LOCAL_M+1))" - netjail_node_link_bridge ${ROUTERS[$N]} ${ROUTER_NETS[$N]} $ROUTER_ADDR 24 - ROUTER_LINKS[$N]=$RESULT - - netjail_node_add_nat ${ROUTERS[$N]} $ROUTER_ADDR 24 - - for M in $(seq $LOCAL_M); do - netjail_node_add_default ${NODES[$N,$M]} $ROUTER_ADDR - done - - # TODO Topology configuration must be enhanced to configure forwarding to more than one subnet node via different ports. - - if [ "1" == "${R_TCP[$N]}" ] - then - ip netns exec ${ROUTERS[$N]} iptables -t nat -A PREROUTING -p tcp -d $GLOBAL_GROUP.$N --dport 60002 -j DNAT --to $LOCAL_GROUP.1 - ip netns exec ${ROUTERS[$N]} iptables -A FORWARD -d $LOCAL_GROUP.1 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT - fi - if [ "1" == "${R_UDP[$N]}" ] - then - ip netns exec ${ROUTERS[$N]} iptables -t nat -A PREROUTING -p udp -d $GLOBAL_GROUP.$N --dport 60002 -j DNAT --to $LOCAL_GROUP.1 - ip netns exec ${ROUTERS[$N]} iptables -A FORWARD -d $LOCAL_GROUP.1 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT - fi -done diff --git a/src/testing/netjail_stop.sh b/src/testing/netjail_stop.sh index 08f68cf7f..abfaf3acf 100755 --- a/src/testing/netjail_stop.sh +++ b/src/testing/netjail_stop.sh @@ -1,24 +1,57 @@ -#!/bin/sh +#!/bin/bash . "./../testing/netjail_core.sh" +. "./../testing/topo.sh" set -eu set -x export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" -LOCAL_M=$1 -GLOBAL_N=$2 -NETWORK_NET=$(netjail_print_name "n" $GLOBAL_N $LOCAL_M) +filename=$1 +PREFIX=$2 -shift 2 +read_topology $filename + +declare -A NODES +declare -A NODE_LINKS + +netjail_bridge_name +NETWORK_NET=$RESULT + +for X in $(seq $KNOWN); do + netjail_node_name + KNOWN_NODES[$X]=$RESULT + netjail_node_link_bridge_name + KNOWN_LINKS[$X]=$RESULT + netjail_node_unlink_bridge ${KNOWN_LINKS[$X]} + netjail_node_clear ${KNOWN_NODES[$X]} +done for N in $(seq $GLOBAL_N); do + netjail_node_name + ROUTERS[$N]=$RESULT + netjail_node_link_bridge_name + NETWORK_LINKS[$N]=$RESULT + netjail_bridge_name + ROUTER_NETS[$N]=$RESULT + netjail_node_link_bridge_name + ROUTER_LINKS[$N]=$RESULT + + netjail_node_unlink_bridge ${ROUTER_LINKS[$N]} + for M in $(seq $LOCAL_M); do - netjail_node_clear $(netjail_print_name "N" $N $M) + netjail_node_name + NODES[$N,$M]=$RESULT + netjail_node_link_bridge_name + NODE_LINKS[$N,$M]=$RESULT + netjail_node_unlink_bridge ${NODE_LINKS[$N,$M]} + netjail_node_clear ${NODES[$N,$M]} done + - netjail_bridge_clear $(netjail_print_name "r" $N) - netjail_node_clear $(netjail_print_name "R" $N) + netjail_bridge_clear ${ROUTER_NETS[$N]} + netjail_node_unlink_bridge ${NETWORK_LINKS[$N]} + netjail_node_clear ${ROUTERS[$N]} done netjail_bridge_clear $NETWORK_NET diff --git a/src/testing/netjail_stop_v2.sh b/src/testing/netjail_stop_v2.sh deleted file mode 100755 index 6e9fd1ccc..000000000 --- a/src/testing/netjail_stop_v2.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash -. "./../testing/netjail_core_v2.sh" -. "./../testing/topo.sh" - -set -eu -set -x - -export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - -filename=$1 -PREFIX=$2 - -read_topology $filename - -declare -A NODES -declare -A NODE_LINKS - -netjail_bridge_name -NETWORK_NET=$RESULT - -for X in $(seq $KNOWN); do - netjail_node_name - KNOWN_NODES[$X]=$RESULT - netjail_node_link_bridge_name - KNOWN_LINKS[$X]=$RESULT - netjail_node_unlink_bridge ${KNOWN_LINKS[$X]} - netjail_node_clear ${KNOWN_NODES[$X]} -done - -for N in $(seq $GLOBAL_N); do - netjail_node_name - ROUTERS[$N]=$RESULT - netjail_node_link_bridge_name - NETWORK_LINKS[$N]=$RESULT - netjail_bridge_name - ROUTER_NETS[$N]=$RESULT - netjail_node_link_bridge_name - ROUTER_LINKS[$N]=$RESULT - - netjail_node_unlink_bridge ${ROUTER_LINKS[$N]} - - for M in $(seq $LOCAL_M); do - netjail_node_name - NODES[$N,$M]=$RESULT - netjail_node_link_bridge_name - NODE_LINKS[$N,$M]=$RESULT - netjail_node_unlink_bridge ${NODE_LINKS[$N,$M]} - netjail_node_clear ${NODES[$N,$M]} - done - - - netjail_bridge_clear ${ROUTER_NETS[$N]} - netjail_node_unlink_bridge ${NETWORK_LINKS[$N]} - netjail_node_clear ${ROUTERS[$N]} -done - -netjail_bridge_clear $NETWORK_NET - -echo "Done" diff --git a/src/testing/testing.c b/src/testing/testing.c index a11d404a5..766c7b084 100644 --- a/src/testing/testing.c +++ b/src/testing/testing.c @@ -34,6 +34,7 @@ #include "gnunet_arm_service.h" #include "gnunet_testing_lib.h" #include "gnunet_testing_ng_lib.h" +#include "testing_cmds.h" #define LOG(kind, ...) GNUNET_log_from (kind, "testing-api", __VA_ARGS__) @@ -1961,10 +1962,6 @@ get_connect_value (char *line, struct GNUNET_TESTING_NetjailNode *node) } GNUNET_free (copy); - LOG (GNUNET_ERROR_TYPE_ERROR, - "address_prefix %s\n", - prefix->address_prefix); - return node_connection; } @@ -2006,6 +2003,31 @@ node_connections (char *line, struct GNUNET_TESTING_NetjailNode *node) } +/** + * Create a GNUNET_CMDS_LOCAL_FINISHED message. + * + * @param rv The result of the local test as GNUNET_GenericReturnValue. + * @return The GNUNET_CMDS_LOCAL_FINISHED message. +*/ +struct GNUNET_MessageHeader * +GNUNET_TESTING_send_local_test_finished_msg (enum GNUNET_GenericReturnValue rv) +{ + struct GNUNET_CMDS_LOCAL_FINISHED *reply; + size_t msg_length; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Local test exits with status %d\n", + rv); + msg_length = sizeof(struct GNUNET_CMDS_LOCAL_FINISHED); + reply = GNUNET_new (struct GNUNET_CMDS_LOCAL_FINISHED); + reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED); + reply->header.size = htons ((uint16_t) msg_length); + reply->result = htons (rv); + + return (struct GNUNET_MessageHeader *) reply; +} + + /** * Getting the topology from file. * diff --git a/src/testing/testing_api_cmd_block_until_all_peers_started.c b/src/testing/testing_api_cmd_block_until_all_peers_started.c index 8a47a7ce0..763713e15 100644 --- a/src/testing/testing_api_cmd_block_until_all_peers_started.c +++ b/src/testing/testing_api_cmd_block_until_all_peers_started.c @@ -38,6 +38,11 @@ */ struct BlockState { + /** + * Context for our asynchronous completion. + */ + struct GNUNET_TESTING_AsyncContext ac; + /** * Flag to indicate if all peers have started. * @@ -93,6 +98,7 @@ GNUNET_TESTING_cmd_block_until_all_peers_started (const char *label, .cls = bs, .label = label, .run = &block_until_all_peers_started_run, + .ac = &bs->ac, .cleanup = &block_until_all_peers_started_cleanup }; diff --git a/src/testing/testing_api_cmd_block_until_external_trigger.c b/src/testing/testing_api_cmd_block_until_external_trigger.c index b416fa595..aeb9ffda3 100644 --- a/src/testing/testing_api_cmd_block_until_external_trigger.c +++ b/src/testing/testing_api_cmd_block_until_external_trigger.c @@ -39,9 +39,14 @@ struct BlockState { /** - * Flag to indicate if all peers have started. + * Context for our asynchronous completion. */ - unsigned int *stop_blocking; + struct GNUNET_TESTING_AsyncContext ac; + + /** + * The label of this command. + */ + const char *label; }; @@ -57,6 +62,47 @@ block_until_all_peers_started_cleanup (void *cls) GNUNET_free (bs); } +static int +block_until_external_trigger_traits (void *cls, + const void **ret, + const char *trait, + unsigned int index) +{ + struct BlockState *bs = cls; + struct GNUNET_TESTING_AsyncContext *ac = &bs->ac; + struct GNUNET_TESTING_Trait traits[] = { + { + .index = 0, + .trait_name = "async_context", + .ptr = (const void *) ac, + }, + GNUNET_TESTING_trait_end () + }; + + return GNUNET_TESTING_get_trait (traits, + ret, + trait, + index); +} + + +/** + * Function to get the trait with the async context. + * + * @param[out] ac GNUNET_TESTING_AsyncContext. + * @return #GNUNET_OK if no error occurred, #GNUNET_SYSERR otherwise. + */ +int +GNUNET_TESTING_get_trait_async_context ( + const struct GNUNET_TESTING_Command *cmd, + struct GNUNET_TESTING_AsyncContext **ac) +{ + return cmd->traits (cmd->cls, + (const void **) ac, + "async_context", + (unsigned int) 0); +} + /** * This function does nothing but to start the cmd. @@ -66,8 +112,11 @@ static void block_until_all_peers_started_run (void *cls, struct GNUNET_TESTING_Interpreter *is) { + struct BlockState *bs = cls; + LOG (GNUNET_ERROR_TYPE_DEBUG, - "block_until_all_peers_started_run!\n"); + "block %s running!\n", + bs->label); } @@ -79,20 +128,20 @@ block_until_all_peers_started_run (void *cls, * @return command. */ struct GNUNET_TESTING_Command -GNUNET_TESTING_cmd_block_until_external_trigger (const char *label, - unsigned int * - stop_blocking) +GNUNET_TESTING_cmd_block_until_external_trigger (const char *label) { struct BlockState *bs; bs = GNUNET_new (struct BlockState); - bs->stop_blocking = stop_blocking; + bs->label = label; { struct GNUNET_TESTING_Command cmd = { .cls = bs, .label = label, .run = &block_until_all_peers_started_run, + .ac = &bs->ac, .cleanup = &block_until_all_peers_started_cleanup, + .traits = block_until_external_trigger_traits }; return cmd; diff --git a/src/testing/testing_api_cmd_netjail_start.c b/src/testing/testing_api_cmd_netjail_start.c index 9cd84cb4f..35fb90f3c 100644 --- a/src/testing/testing_api_cmd_netjail_start.c +++ b/src/testing/testing_api_cmd_netjail_start.c @@ -19,7 +19,7 @@ */ /** - * @file testing/testing_api_cmd_hello_world.c + * @file testing/testing_api_cmd_netjail_start.c * @brief Command to start the netjail script. * @author t3sserakt */ @@ -43,16 +43,16 @@ struct NetJailState // Child Wait handle struct GNUNET_ChildWaitHandle *cwh; - // Number of local nodes in each namespace. - char *local_m; - - // The number of namespaces. - char *global_n; - /** * The process id of the start script. */ struct GNUNET_OS_Process *start_proc; + + /** + * Configuration file for the test topology. + */ + char *topology_config; + }; @@ -67,6 +67,7 @@ netjail_start_cleanup (void *cls) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "netjail_start_cleanup!\n"); + if (NULL != ns->cwh) { GNUNET_wait_child_cancel (ns->cwh); @@ -105,9 +106,9 @@ child_completed_callback (void *cls, } else { - // FIXME: log status code GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Child completed with an error!\n"); + "Child failed with error %lu!\n", + exit_code); GNUNET_TESTING_async_fail (&ns->ac); } } @@ -124,13 +125,13 @@ netjail_start_run (void *cls, struct GNUNET_TESTING_Interpreter *is) { struct NetJailState *ns = cls; - char *const script_argv[] = { - NETJAIL_START_SCRIPT, - ns->local_m, - ns->global_n, - NULL - }; - unsigned int helper_check = GNUNET_OS_check_helper_binary ( + char pid[15]; + enum GNUNET_GenericReturnValue helper_check; + + // FIXME: NETJAIL_START_SCRIPT like this is bad, + // use location from share/gnunet/ of installed + // binary in case libgnunettesting is used as a lib! + helper_check = GNUNET_OS_check_helper_binary ( NETJAIL_START_SCRIPT, GNUNET_YES, NULL); @@ -141,22 +142,37 @@ netjail_start_run (void *cls, "No SUID for %s!\n", NETJAIL_START_SCRIPT); GNUNET_TESTING_interpreter_fail (is); + return; } - else if (GNUNET_NO == helper_check) + if (GNUNET_SYSERR == helper_check) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s not found!\n", NETJAIL_START_SCRIPT); GNUNET_TESTING_interpreter_fail (is); + return; } - ns->start_proc = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR, - NULL, - NULL, - NULL, - NETJAIL_START_SCRIPT, - script_argv); + GNUNET_snprintf (pid, + sizeof (pid), + "%u", + getpid ()); + { + char *const script_argv[] = { + NETJAIL_START_SCRIPT, + ns->topology_config, + pid, + NULL + }; + ns->start_proc + = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR, + NULL, + NULL, + NULL, + NETJAIL_START_SCRIPT, + script_argv); + } ns->cwh = GNUNET_wait_child (ns->start_proc, &child_completed_callback, ns); @@ -168,20 +184,17 @@ netjail_start_run (void *cls, * Create command. * * @param label name for command. - * @param local_m Number of local nodes in each namespace. - * @param global_n The number of namespaces. + * @param topology_config Configuration file for the test topology. * @return command. */ struct GNUNET_TESTING_Command GNUNET_TESTING_cmd_netjail_start (const char *label, - char *local_m, - char *global_n) + char *topology_config) { struct NetJailState *ns; ns = GNUNET_new (struct NetJailState); - ns->local_m = local_m; - ns->global_n = global_n; + ns->topology_config = topology_config; { struct GNUNET_TESTING_Command cmd = { .cls = ns, diff --git a/src/testing/testing_api_cmd_netjail_start_testsystem.c b/src/testing/testing_api_cmd_netjail_start_testsystem.c index 4224a5736..a1d71c436 100644 --- a/src/testing/testing_api_cmd_netjail_start_testsystem.c +++ b/src/testing/testing_api_cmd_netjail_start_testsystem.c @@ -66,6 +66,11 @@ struct NetJailState */ struct GNUNET_TESTING_AsyncContext ac; + /** + * The complete topology information. + */ + struct GNUNET_TESTING_NetjailTopology *topology; + /** * Pointer to the return value of the test. * @@ -96,16 +101,22 @@ struct NetJailState unsigned int n_helper; /** - * Number of nodes in a network namespace. //TODO make this a unsigned int + * Number of nodes in a natted subnet. + * + */ + unsigned int local_m; + + /** + * Number of natted subnets. * */ - char *local_m; + unsigned int global_n; /** - * Number of network namespaces. //TODO make this a unsigned int + * Number of global known nodes. * */ - char *global_n; + unsigned int known; /** * The send handle for the helper @@ -271,7 +282,8 @@ netjail_exec_traits (void *cls, int GNUNET_TESTING_get_trait_helper_handles (const struct GNUNET_TESTING_Command *cmd, - struct GNUNET_HELPER_Handle ***helper) + struct GNUNET_HELPER_Handle *** + helper) { return cmd->traits (cmd->cls, (const void **) helper, @@ -301,6 +313,43 @@ clear_msg (void *cls, int result) } +static void +send_all_peers_started (unsigned int i, unsigned int j, struct NetJailState *ns) +{ + unsigned int total_number = ns->local_m * ns->global_n + ns->known; + struct GNUNET_CMDS_ALL_PEERS_STARTED *reply; + size_t msg_length; + struct GNUNET_HELPER_Handle *helper; + struct TestingSystemCount *tbc; + + tbc = GNUNET_new (struct TestingSystemCount); + tbc->ns = ns; + // TODO This needs to be more generic. As we send more messages back and forth, we can not grow the arrays again and again, because this is to error prone. + if (0 == i) + tbc->count = j + total_number; + else + tbc->count = (i - 1) * ns->local_m + j + total_number + ns->known; + + helper = ns->helper[tbc->count - 1 - total_number]; + msg_length = sizeof(struct GNUNET_CMDS_ALL_PEERS_STARTED); + reply = GNUNET_new (struct GNUNET_CMDS_ALL_PEERS_STARTED); + reply->header.type = htons ( + GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED); + reply->header.size = htons ((uint16_t) msg_length); + + GNUNET_array_append (ns->msg, ns->n_msg, &reply->header); + + struct GNUNET_HELPER_SendHandle *sh = GNUNET_HELPER_send ( + helper, + &reply->header, + GNUNET_NO, + &clear_msg, + tbc); + + GNUNET_array_append (ns->shandle, ns->n_shandle, sh); +} + + /** * Functions with this signature are called whenever a * complete message is received by the tokenizer. @@ -319,6 +368,7 @@ helper_mst (void *cls, const struct GNUNET_MessageHeader *message) struct TestingSystemCount *tbc = cls; struct NetJailState *ns = tbc->ns; struct HelperMessage *hp_msg; + unsigned int total_number = ns->local_m * ns->global_n + ns->known; if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY == ntohs (message->type)) { @@ -328,11 +378,31 @@ helper_mst (void *cls, const struct GNUNET_MessageHeader *message) message->type)) { ns->number_of_peers_started++; + if (ns->number_of_peers_started == total_number) + { + for (int i = 1; i <= ns->known; i++) + { + send_all_peers_started (0,i, ns); + } + + for (int i = 1; i <= ns->global_n; i++) + { + for (int j = 1; j <= ns->local_m; j++) + { + send_all_peers_started (i,j, ns); + } + } + ns->number_of_peers_started = 0; + } } else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED == ntohs ( message->type)) { ns->number_of_local_test_finished++; + if (ns->number_of_local_test_finished == total_number) + { + GNUNET_TESTING_async_finish (&ns->ac); + } } else { @@ -343,6 +413,12 @@ helper_mst (void *cls, const struct GNUNET_MessageHeader *message) hp_msg); } + + + + + + return GNUNET_OK; } @@ -354,24 +430,21 @@ helper_mst (void *cls, const struct GNUNET_MessageHeader *message) static void exp_cb (void *cls) { - struct NetJailState *ns = cls; + struct TestingSystemCount *tbc = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called exp_cb.\n"); - *ns->rv = 1; + GNUNET_TESTING_interpreter_fail (tbc->ns->ac.is); } /** * Function to initialize a init message for the helper. * - * @param m_char The actual node in a namespace. //TODO Change this to unsigned int - * @param n_char The actual namespace. //TODO Change this to unsigned int * @param plugin_name Name of the test case plugin the helper will load. * */ static struct GNUNET_CMDS_HelperInit * -create_helper_init_msg_ (char *m_char, - char *n_char, - const char *plugin_name) +create_helper_init_msg_ (const char *plugin_name) { struct GNUNET_CMDS_HelperInit *msg; uint16_t plugin_name_len; @@ -398,24 +471,49 @@ create_helper_init_msg_ (char *m_char, static void start_helper (struct NetJailState *ns, struct GNUNET_CONFIGURATION_Handle *config, - char *m_char, - char *n_char) + unsigned int m, + unsigned int n) { struct GNUNET_HELPER_Handle *helper; struct GNUNET_CMDS_HelperInit *msg; struct TestingSystemCount *tbc; - char *const script_argv[] = { - NETJAIL_EXEC_SCRIPT, - m_char, - n_char, - GNUNET_OS_get_libexec_binary_path ( - HELPER_CMDS_BINARY), - ns->global_n, - ns->local_m, - NULL - }; - unsigned int m = atoi (m_char); - unsigned int n = atoi (n_char); + char *m_char, *n_char, *global_n_char, *local_m_char, *known_char, *node_id, + *plugin; + pid_t pid; + unsigned int script_num; + struct GNUNET_ShortHashCode *hkey; + struct GNUNET_HashCode hc; + struct GNUNET_TESTING_NetjailTopology *topology = ns->topology; + struct GNUNET_TESTING_NetjailNode *node; + struct GNUNET_TESTING_NetjailNamespace *namespace; + + + if (0 == n) + script_num = m - 1; + else + script_num = n - 1 + (n - 1) * ns->local_m + m + ns->known; + pid = getpid (); + + GNUNET_asprintf (&m_char, "%u", m); + GNUNET_asprintf (&n_char, "%u", n); + GNUNET_asprintf (&local_m_char, "%u", ns->local_m); + GNUNET_asprintf (&global_n_char, "%u",ns->global_n); + GNUNET_asprintf (&known_char, "%u",ns->known); + GNUNET_asprintf (&node_id, "%06x-%08x\n", + pid, + script_num); + + + char *const script_argv[] = {NETJAIL_EXEC_SCRIPT, + m_char, + n_char, + GNUNET_OS_get_libexec_binary_path ( + HELPER_CMDS_BINARY), + global_n_char, + local_m_char, + node_id, + NULL}; + unsigned int helper_check = GNUNET_OS_check_helper_binary ( NETJAIL_EXEC_SCRIPT, GNUNET_YES, @@ -423,7 +521,10 @@ start_helper (struct NetJailState *ns, struct tbc = GNUNET_new (struct TestingSystemCount); tbc->ns = ns; - tbc->count = (n - 1) * atoi (ns->local_m) + m; + if (0 == n) + tbc->count = m; + else + tbc->count = (n - 1) * ns->local_m + m + ns->known; GNUNET_CONTAINER_DLL_insert (ns->tbcs_head, ns->tbcs_tail, tbc); @@ -434,18 +535,17 @@ start_helper (struct NetJailState *ns, struct GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No SUID for %s!\n", NETJAIL_EXEC_SCRIPT); - *ns->rv = 1; + GNUNET_TESTING_interpreter_fail (ns->ac.is); } else if (GNUNET_NO == helper_check) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s not found!\n", NETJAIL_EXEC_SCRIPT); - *ns->rv = 1; + GNUNET_TESTING_interpreter_fail (ns->ac.is); } - GNUNET_array_append (ns->helper, - ns->n_helper, - GNUNET_HELPER_start ( + + GNUNET_array_append (ns->helper, ns->n_helper, GNUNET_HELPER_start ( GNUNET_YES, NETJAIL_EXEC_SCRIPT, script_argv, @@ -455,9 +555,57 @@ start_helper (struct NetJailState *ns, struct helper = ns->helper[tbc->count - 1]; - msg = create_helper_init_msg_ (m_char, - n_char, - ns->plugin_name); + hkey = GNUNET_new (struct GNUNET_ShortHashCode); + + plugin = topology->plugin; + + if (0 == m) + { + + GNUNET_CRYPTO_hash (&n, sizeof(n), &hc); + memcpy (hkey, + &hc, + sizeof (*hkey)); + if (1 == GNUNET_CONTAINER_multishortmap_contains (topology->map_globals, + hkey)) + { + node = GNUNET_CONTAINER_multishortmap_get (topology->map_globals, + hkey); + if (NULL != node->plugin) + plugin = node->plugin; + } + + } + else + { + GNUNET_CRYPTO_hash (&m, sizeof(m), &hc); + memcpy (hkey, + &hc, + sizeof (*hkey)); + if (1 == GNUNET_CONTAINER_multishortmap_contains (topology->map_namespaces, + hkey)) + { + namespace = GNUNET_CONTAINER_multishortmap_get (topology->map_namespaces, + hkey); + GNUNET_CRYPTO_hash (&n, sizeof(n), &hc); + memcpy (hkey, + &hc, + sizeof (*hkey)); + if (1 == GNUNET_CONTAINER_multishortmap_contains (namespace->nodes, + hkey)) + { + node = GNUNET_CONTAINER_multishortmap_get (namespace->nodes, + hkey); + if (NULL != node->plugin) + plugin = node->plugin; + } + } + + + } + + msg = create_helper_init_msg_ (plugin); + GNUNET_array_append (ns->msg, ns->n_msg, &msg->header); GNUNET_array_append (ns->shandle, ns->n_shandle, GNUNET_HELPER_send ( @@ -472,7 +620,7 @@ start_helper (struct NetJailState *ns, struct GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Send handle is NULL!\n"); GNUNET_free (msg); - *ns->rv = 1; + GNUNET_TESTING_interpreter_fail (ns->ac.is); } } @@ -488,93 +636,26 @@ static void netjail_exec_run (void *cls, struct GNUNET_TESTING_Interpreter *is) { - char str_m[12]; - char str_n[12]; struct NetJailState *ns = cls; struct GNUNET_CONFIGURATION_Handle *config = GNUNET_CONFIGURATION_create (); - for (int i = 1; i <= atoi (ns->global_n); i++) + for (int i = 1; i <= ns->known; i++) { - for (int j = 1; j <= atoi (ns->local_m); j++) - { - sprintf (str_n, "%d", i); - sprintf (str_m, "%d", j); - start_helper (ns, config, - str_m, - str_n); - } + start_helper (ns, config, + i, + 0); } -} - -/** - * This function checks on three different information. - * - * 1. Did all helpers start. This is only logged. - * 2. Did all peer start. - * In this case a GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED is send to all peers. - * 3. Did all peers finished the test case. In this case interpreter_next will be called. - * - * => FIXME: must change _completely_. - */ -static int -netjail_start_finish (void *cls, - GNUNET_SCHEDULER_TaskCallback cont, - void *cont_cls) -{ - unsigned int ret = GNUNET_NO; - struct NetJailState *ns = cls; - unsigned int total_number = atoi (ns->local_m) * atoi (ns->global_n); - struct GNUNET_CMDS_ALL_PEERS_STARTED *reply; - size_t msg_length; - struct GNUNET_HELPER_Handle *helper; - struct TestingSystemCount *tbc; - - if (ns->number_of_local_test_finished == total_number) + for (int i = 1; i <= ns->global_n; i++) { - ret = GNUNET_YES; - cont (cont_cls); - } - - if (ns->number_of_testsystems_started == total_number) - { - ns->number_of_testsystems_started = 0; - } - - if (ns->number_of_peers_started == total_number) - { - for (int i = 1; i <= atoi (ns->global_n); i++) + for (int j = 1; j <= ns->local_m; j++) { - for (int j = 1; j <= atoi (ns->local_m); j++) - { - tbc = GNUNET_new (struct TestingSystemCount); - tbc->ns = ns; - // TODO This needs to be more generic. As we send more messages back and forth, we can not grow the arrays again and again, because this is to error prone. - tbc->count = (i - 1) * atoi (ns->local_m) + j + total_number; - - helper = ns->helper[tbc->count - 1 - total_number]; - msg_length = sizeof(struct GNUNET_CMDS_ALL_PEERS_STARTED); - reply = GNUNET_new (struct GNUNET_CMDS_ALL_PEERS_STARTED); - reply->header.type = htons ( - GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED); - reply->header.size = htons ((uint16_t) msg_length); - - GNUNET_array_append (ns->msg, ns->n_msg, &reply->header); - - struct GNUNET_HELPER_SendHandle *sh = GNUNET_HELPER_send ( - helper, - &reply->header, - GNUNET_NO, - &clear_msg, - tbc); - - GNUNET_array_append (ns->shandle, ns->n_shandle, sh); - } + start_helper (ns, config, + j, + i); } - ns->number_of_peers_started = 0; } - return ret; } @@ -582,26 +663,24 @@ netjail_start_finish (void *cls, * Create command. * * @param label Name for the command. - * @param local_m Number of nodes in a network namespace. //TODO make this a unsigned int - * @param global_n Number of network namespaces. //TODO make this a unsigned int - * @param plugin_name Name of the test case plugin the helper will load. - * @param rv Pointer to the return value of the test. + * @param topology_config Configuration file for the test topology. * @return command. */ struct GNUNET_TESTING_Command GNUNET_TESTING_cmd_netjail_start_testing_system (const char *label, - char *local_m, - char *global_n, - char *plugin_name, - unsigned int *rv) + const char *topology_config) { struct NetJailState *ns; + struct GNUNET_TESTING_NetjailTopology *topology = + GNUNET_TESTING_get_topo_from_file (topology_config); + ns = GNUNET_new (struct NetJailState); - ns->local_m = local_m; - ns->global_n = global_n; - ns->plugin_name = plugin_name; - ns->rv = rv; + ns->local_m = topology->nodes_m; + ns->global_n = topology->namespaces_n; + ns->known = topology->nodes_x; + ns->plugin_name = topology->plugin; + ns->topology = topology; struct GNUNET_TESTING_Command cmd = { .cls = ns, diff --git a/src/testing/testing_api_cmd_netjail_start_testsystem_v2.c b/src/testing/testing_api_cmd_netjail_start_testsystem_v2.c deleted file mode 100644 index d319b73b4..000000000 --- a/src/testing/testing_api_cmd_netjail_start_testsystem_v2.c +++ /dev/null @@ -1,723 +0,0 @@ -/* - This file is part of GNUnet - Copyright (C) 2021 GNUnet e.V. - - GNUnet is free software: you can redistribute it and/or modify it - under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - SPDX-License-Identifier: AGPL3.0-or-later - */ - -/** - * @file testing/testing_api_cmd_hello_world.c - * @brief Command to start the netjail peers. - * @author t3sserakt - */ -#include "platform.h" -#include "gnunet_testing_ng_lib.h" -#include "testing_cmds.h" - -#define NETJAIL_EXEC_SCRIPT "./../testing/netjail_exec_v2.sh" - -/** - * Struct to store messages send/received by the helper into a DLL - * - */ -struct HelperMessage -{ - - /** - * Kept in a DLL. - */ - struct HelperMessage *next; - - /** - * Kept in a DLL. - */ - struct HelperMessage *prev; - - /** - * Size of the original message. - */ - uint16_t bytes_msg; - - /* Followed by @e bytes_msg of msg.*/ -}; - - -/** - * Struct to store information handed over to callbacks. - * - */ -struct NetJailState -{ - /** - * Context for our asynchronous completion. - */ - struct GNUNET_TESTING_AsyncContext ac; - - /** - * The complete topology information. - */ - struct GNUNET_TESTING_NetjailTopology *topology; - - /** - * Pointer to the return value of the test. - * - */ - unsigned int *rv; - - /** - * Head of the DLL which stores messages received by the helper. - * - */ - struct HelperMessage *hp_messages_head; - - /** - * Tail of the DLL which stores messages received by the helper. - * - */ - struct HelperMessage *hp_messages_tail; - - /** - * Array with handles of helper processes. - */ - struct GNUNET_HELPER_Handle **helper; - - /** - * Size of the array NetJailState#helper. - * - */ - unsigned int n_helper; - - /** - * Number of nodes in a natted subnet. - * - */ - unsigned int local_m; - - /** - * Number of natted subnets. - * - */ - unsigned int global_n; - - /** - * Number of global known nodes. - * - */ - unsigned int known; - - /** - * The send handle for the helper - */ - struct GNUNET_HELPER_SendHandle **shandle; - - /** - * Size of the array NetJailState#shandle. - * - */ - unsigned int n_shandle; - - /** - * The messages send to the helper. - */ - struct GNUNET_MessageHeader **msg; - - /** - * Size of the array NetJailState#msg. - * - */ - unsigned int n_msg; - - /** - * Number of test environments started. - * - */ - unsigned int number_of_testsystems_started; - - /** - * Number of peers started. - * - */ - unsigned int number_of_peers_started; - - /** - * Number of local tests finished. - * - */ - unsigned int number_of_local_test_finished; - - /** - * Name of the test case plugin the helper will load. - * - */ - char *plugin_name; - - /** - * HEAD of the DLL containing TestingSystemCount. - * - */ - struct TestingSystemCount *tbcs_head; - - /** - * TAIL of the DLL containing TestingSystemCount. - * - */ - struct TestingSystemCount *tbcs_tail; -}; - -/** - * Struct containing the number of the test environment and the NetJailState which - * will be handed to callbacks specific to a test environment. - */ -struct TestingSystemCount -{ - /** - * Kept in a DLL. - */ - struct TestingSystemCount *next; - - /** - * Kept in a DLL. - */ - struct TestingSystemCount *prev; - - /** - * The number of the test environment. - * - */ - unsigned int count; - - /** - * Struct to store information handed over to callbacks. - * - */ - struct NetJailState *ns; -}; - -/** -* Code to clean up resource this cmd used. -* -* @param cls closure -*/ -static void -netjail_exec_cleanup (void *cls) -{ - struct NetJailState *ns = cls; - struct HelperMessage *message_pos; - struct TestingSystemCount *tbc_pos; - - while (NULL != (message_pos = ns->hp_messages_head)) - { - GNUNET_CONTAINER_DLL_remove (ns->hp_messages_head, - ns->hp_messages_tail, - message_pos); - GNUNET_free (message_pos); - } - while (NULL != (tbc_pos = ns->tbcs_head)) - { - GNUNET_CONTAINER_DLL_remove (ns->tbcs_head, - ns->tbcs_tail, - tbc_pos); - GNUNET_free (tbc_pos); - } - GNUNET_free (ns); -} - - -/** - * This function prepares an array with traits. - * - */ -static int -netjail_exec_traits (void *cls, - const void **ret, - const char *trait, - unsigned int index) -{ - struct NetJailState *ns = cls; - struct GNUNET_HELPER_Handle **helper = ns->helper; - struct HelperMessage *hp_messages_head = ns->hp_messages_head; - - - struct GNUNET_TESTING_Trait traits[] = { - { - .index = 0, - .trait_name = "helper_handles", - .ptr = (const void *) helper, - }, - { - .index = 1, - .trait_name = "hp_msgs_head", - .ptr = (const void *) hp_messages_head, - }, - GNUNET_TESTING_trait_end () - }; - - return GNUNET_TESTING_get_trait (traits, - ret, - trait, - index); -} - - -/** - * Offer handles to testing cmd helper from trait - * - * @param cmd command to extract the message from. - * @param pt pointer to message. - * @return #GNUNET_OK on success. - */ -int -GNUNET_TESTING_get_trait_helper_handles_v2 (const struct - GNUNET_TESTING_Command *cmd, - struct GNUNET_HELPER_Handle *** - helper) -{ - return cmd->traits (cmd->cls, - (const void **) helper, - "helper_handles", - (unsigned int) 0); -} - - -/** - * Continuation function from GNUNET_HELPER_send() - * - * @param cls closure - * @param result GNUNET_OK on success, - * GNUNET_NO if helper process died - * GNUNET_SYSERR during GNUNET_HELPER_stop - */ -static void -clear_msg (void *cls, int result) -{ - struct TestingSystemCount *tbc = cls; - struct NetJailState *ns = tbc->ns; - - GNUNET_assert (NULL != ns->shandle[tbc->count - 1]); - ns->shandle[tbc->count - 1] = NULL; - GNUNET_free (ns->msg[tbc->count - 1]); - ns->msg[tbc->count - 1] = NULL; -} - - -/** - * Functions with this signature are called whenever a - * complete message is received by the tokenizer. - * - * Do not call GNUNET_SERVER_mst_destroy in callback - * - * @param cls closure - * @param client identification of the client - * @param message the actual message - * - * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing - */ -static int -helper_mst (void *cls, const struct GNUNET_MessageHeader *message) -{ - struct TestingSystemCount *tbc = cls; - struct NetJailState *ns = tbc->ns; - struct HelperMessage *hp_msg; - - if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY == ntohs (message->type)) - { - ns->number_of_testsystems_started++; - } - else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED == ntohs ( - message->type)) - { - ns->number_of_peers_started++; - } - else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED == ntohs ( - message->type)) - { - ns->number_of_local_test_finished++; - } - else - { - hp_msg = GNUNET_new (struct HelperMessage); - hp_msg->bytes_msg = message->size; - memcpy (&hp_msg[1], message, message->size); - GNUNET_CONTAINER_DLL_insert (ns->hp_messages_head, ns->hp_messages_tail, - hp_msg); - } - - return GNUNET_OK; -} - - -/** - * Callback called if there was an exception during execution of the helper. - * - */ -static void -exp_cb (void *cls) -{ - struct NetJailState *ns = cls; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called exp_cb.\n"); - *ns->rv = 1; -} - - -/** - * Function to initialize a init message for the helper. - * - * @param m_char The actual node in a namespace. //TODO Change this to unsigned int - * @param n_char The actual namespace. //TODO Change this to unsigned int - * @param plugin_name Name of the test case plugin the helper will load. - * - */ -static struct GNUNET_CMDS_HelperInit * -create_helper_init_msg_ (const char *plugin_name) -{ - struct GNUNET_CMDS_HelperInit *msg; - uint16_t plugin_name_len; - uint16_t msg_size; - - GNUNET_assert (NULL != plugin_name); - plugin_name_len = strlen (plugin_name); - msg_size = sizeof(struct GNUNET_CMDS_HelperInit) + plugin_name_len; - msg = GNUNET_malloc (msg_size); - msg->header.size = htons (msg_size); - msg->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT); - msg->plugin_name_size = htons (plugin_name_len); - GNUNET_memcpy ((char *) &msg[1], - plugin_name, - plugin_name_len); - return msg; -} - - -/** - * Function which start a single helper process. - * - */ -static void -start_helper (struct NetJailState *ns, struct - GNUNET_CONFIGURATION_Handle *config, - unsigned int m, - unsigned int n) -{ - struct GNUNET_HELPER_Handle *helper; - struct GNUNET_CMDS_HelperInit *msg; - struct TestingSystemCount *tbc; - char *m_char, *n_char, *global_n_char, *local_m_char, *known_char, *node_id, - *plugin; - pid_t pid; - unsigned int script_num; - struct GNUNET_ShortHashCode *hkey; - struct GNUNET_HashCode hc; - struct GNUNET_TESTING_NetjailTopology *topology = ns->topology; - struct GNUNET_TESTING_NetjailNode *node; - struct GNUNET_TESTING_NetjailNamespace *namespace; - - - if (0 == n) - script_num = m - 1; - else - script_num = n - 1 + (n - 1) * ns->local_m + m + ns->known; - pid = getpid (); - - GNUNET_asprintf (&m_char, "%u", m); - GNUNET_asprintf (&n_char, "%u", n); - GNUNET_asprintf (&local_m_char, "%u", ns->local_m); - GNUNET_asprintf (&global_n_char, "%u",ns->global_n); - GNUNET_asprintf (&known_char, "%u",ns->known); - GNUNET_asprintf (&node_id, "%06x-%08x\n", - pid, - script_num); - - - char *const script_argv[] = {NETJAIL_EXEC_SCRIPT, - m_char, - n_char, - GNUNET_OS_get_libexec_binary_path ( - HELPER_CMDS_BINARY), - global_n_char, - local_m_char, - node_id, - NULL}; - - unsigned int helper_check = GNUNET_OS_check_helper_binary ( - NETJAIL_EXEC_SCRIPT, - GNUNET_YES, - NULL); - - tbc = GNUNET_new (struct TestingSystemCount); - tbc->ns = ns; - if (0 == n) - tbc->count = m; - else - tbc->count = (n - 1) * ns->local_m + m + ns->known; - - GNUNET_CONTAINER_DLL_insert (ns->tbcs_head, ns->tbcs_tail, - tbc); - - - if (GNUNET_NO == helper_check) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "No SUID for %s!\n", - NETJAIL_EXEC_SCRIPT); - *ns->rv = 1; - } - else if (GNUNET_NO == helper_check) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%s not found!\n", - NETJAIL_EXEC_SCRIPT); - *ns->rv = 1; - } - - GNUNET_array_append (ns->helper, ns->n_helper, GNUNET_HELPER_start ( - GNUNET_YES, - NETJAIL_EXEC_SCRIPT, - script_argv, - &helper_mst, - &exp_cb, - tbc)); - - helper = ns->helper[tbc->count - 1]; - - hkey = GNUNET_new (struct GNUNET_ShortHashCode); - - plugin = topology->plugin; - - if (0 == m) - { - - GNUNET_CRYPTO_hash (&n, sizeof(n), &hc); - memcpy (hkey, - &hc, - sizeof (*hkey)); - if (1 == GNUNET_CONTAINER_multishortmap_contains (topology->map_globals, - hkey)) - { - node = GNUNET_CONTAINER_multishortmap_get (topology->map_globals, - hkey); - if (NULL != node->plugin) - plugin = node->plugin; - } - - } - else - { - GNUNET_CRYPTO_hash (&m, sizeof(m), &hc); - memcpy (hkey, - &hc, - sizeof (*hkey)); - if (1 == GNUNET_CONTAINER_multishortmap_contains (topology->map_namespaces, - hkey)) - { - namespace = GNUNET_CONTAINER_multishortmap_get (topology->map_namespaces, - hkey); - GNUNET_CRYPTO_hash (&n, sizeof(n), &hc); - memcpy (hkey, - &hc, - sizeof (*hkey)); - if (1 == GNUNET_CONTAINER_multishortmap_contains (namespace->nodes, - hkey)) - { - node = GNUNET_CONTAINER_multishortmap_get (namespace->nodes, - hkey); - if (NULL != node->plugin) - plugin = node->plugin; - } - } - - - } - - msg = create_helper_init_msg_ (plugin); - - GNUNET_array_append (ns->msg, ns->n_msg, &msg->header); - - GNUNET_array_append (ns->shandle, ns->n_shandle, GNUNET_HELPER_send ( - helper, - &msg->header, - GNUNET_NO, - &clear_msg, - tbc)); - - if (NULL == ns->shandle[tbc->count - 1]) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Send handle is NULL!\n"); - GNUNET_free (msg); - *ns->rv = 1; - } -} - - -/** -* This function starts a helper process for each node. -* -* @param cls closure. -* @param cmd CMD being run. -* @param is interpreter state. -*/ -static void -netjail_exec_run (void *cls, - struct GNUNET_TESTING_Interpreter *is) -{ - struct NetJailState *ns = cls; - struct GNUNET_CONFIGURATION_Handle *config = - GNUNET_CONFIGURATION_create (); - - for (int i = 1; i <= ns->known; i++) - { - start_helper (ns, config, - i, - 0); - } - - for (int i = 1; i <= ns->global_n; i++) - { - for (int j = 1; j <= ns->local_m; j++) - { - start_helper (ns, config, - j, - i); - } - } -} - - -static void -send_all_peers_started (unsigned int i, unsigned int j, struct NetJailState *ns) -{ - unsigned int total_number = ns->local_m * ns->global_n + ns->known; - struct GNUNET_CMDS_ALL_PEERS_STARTED *reply; - size_t msg_length; - struct GNUNET_HELPER_Handle *helper; - struct TestingSystemCount *tbc; - - tbc = GNUNET_new (struct TestingSystemCount); - tbc->ns = ns; - // TODO This needs to be more generic. As we send more messages back and forth, we can not grow the arrays again and again, because this is to error prone. - if (0 == i) - tbc->count = j + total_number; - else - tbc->count = (i - 1) * ns->local_m + j + total_number + ns->known; - - helper = ns->helper[tbc->count - 1 - total_number]; - msg_length = sizeof(struct GNUNET_CMDS_ALL_PEERS_STARTED); - reply = GNUNET_new (struct GNUNET_CMDS_ALL_PEERS_STARTED); - reply->header.type = htons ( - GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED); - reply->header.size = htons ((uint16_t) msg_length); - - GNUNET_array_append (ns->msg, ns->n_msg, &reply->header); - - struct GNUNET_HELPER_SendHandle *sh = GNUNET_HELPER_send ( - helper, - &reply->header, - GNUNET_NO, - &clear_msg, - tbc); - - GNUNET_array_append (ns->shandle, ns->n_shandle, sh); -} - - -/** - * This function checks on three different information. - * - * 1. Did all helpers start. This is only logged. - * 2. Did all peer start. - * In this case a GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED is send to all peers. - * 3. Did all peers finished the test case. In this case interpreter_next will be called. - * - */ -// FIXME: must change completely! -static int -netjail_start_finish (void *cls, - GNUNET_SCHEDULER_TaskCallback cont, - void *cont_cls) -{ - unsigned int ret = GNUNET_NO; - struct NetJailState *ns = cls; - unsigned int total_number = ns->local_m * ns->global_n + ns->known; - - - if (ns->number_of_local_test_finished == total_number) - { - ret = GNUNET_YES; - cont (cont_cls); - } - - if (ns->number_of_testsystems_started == total_number) - { - ns->number_of_testsystems_started = 0; - } - - if (ns->number_of_peers_started == total_number) - { - for (int i = 1; i <= ns->known; i++) - { - send_all_peers_started (0,i, ns); - } - - for (int i = 1; i <= ns->global_n; i++) - { - for (int j = 1; j <= ns->local_m; j++) - { - send_all_peers_started (i,j, ns); - } - } - ns->number_of_peers_started = 0; - } - return ret; -} - - -/** - * Create command. - * - * @param label Name for the command. - * @param topology_config Configuration file for the test topology. - * @param rv Pointer to the return value of the test. - * @return command. - */ -struct GNUNET_TESTING_Command -GNUNET_TESTING_cmd_netjail_start_testing_system_v2 (const char *label, - const char *topology_config, - unsigned int *rv) -{ - struct NetJailState *ns; - - struct GNUNET_TESTING_NetjailTopology *topology = - GNUNET_TESTING_get_topo_from_file (topology_config); - - ns = GNUNET_new (struct NetJailState); - ns->rv = rv; - ns->local_m = topology->nodes_m; - ns->global_n = topology->namespaces_n; - ns->known = topology->nodes_x; - ns->plugin_name = topology->plugin; - ns->topology = topology; - - struct GNUNET_TESTING_Command cmd = { - .cls = ns, - .label = label, - .run = &netjail_exec_run, - .ac = &ns->ac, - .cleanup = &netjail_exec_cleanup, - .traits = &netjail_exec_traits - }; - - return cmd; -} diff --git a/src/testing/testing_api_cmd_netjail_start_v2.c b/src/testing/testing_api_cmd_netjail_start_v2.c deleted file mode 100644 index 7567c2981..000000000 --- a/src/testing/testing_api_cmd_netjail_start_v2.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - This file is part of GNUnet - Copyright (C) 2021 GNUnet e.V. - - GNUnet is free software: you can redistribute it and/or modify it - under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - SPDX-License-Identifier: AGPL3.0-or-later - */ - -/** - * @file testing/testing_api_cmd_netjail_start_v2.c - * @brief Command to start the netjail script. - * @author t3sserakt - */ -#include "platform.h" -#include "gnunet_util_lib.h" -#include "gnunet_testing_ng_lib.h" - -#define NETJAIL_START_SCRIPT "./../testing/netjail_start_v2.sh" - -/** - * Struct to hold information for callbacks. - * - */ -struct NetJailState -{ - /** - * Context for our asynchronous completion. - */ - struct GNUNET_TESTING_AsyncContext ac; - - // Child Wait handle - struct GNUNET_ChildWaitHandle *cwh; - - /** - * Configuration file for the test topology. - */ - char *topology_config; - - /** - * The process id of the start script. - */ - struct GNUNET_OS_Process *start_proc; - -}; - - -/** - * The cleanup function of this cmd frees resources the cmd allocated. - * - */ -static void -netjail_start_cleanup (void *cls) -{ - struct NetJailState *ns = cls; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "netjail_start_cleanup!\n"); - - if (NULL != ns->cwh) - { - GNUNET_wait_child_cancel (ns->cwh); - ns->cwh = NULL; - } - if (NULL != ns->start_proc) - { - GNUNET_assert (0 == - GNUNET_OS_process_kill (ns->start_proc, - SIGKILL)); - GNUNET_assert (GNUNET_OK == - GNUNET_OS_process_wait (ns->start_proc)); - GNUNET_OS_process_destroy (ns->start_proc); - ns->start_proc = NULL; - } - GNUNET_free (ns); -} - - -/** - * Callback which will be called if the setup script finished. - * - */ -static void -child_completed_callback (void *cls, - enum GNUNET_OS_ProcessStatusType type, - long unsigned int exit_code) -{ - struct NetJailState *ns = cls; - - GNUNET_OS_process_destroy (ns->start_proc); - ns->start_proc = NULL; - if (0 == exit_code) - { - GNUNET_TESTING_async_finish (&ns->ac); - } - else - { - // FIXME: log status code - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Child completed with an error!\n"); - GNUNET_TESTING_async_fail (&ns->ac); - } -} - - -/** -* The run method starts the script which setup the network namespaces. -* -* @param cls closure. -* @param is interpreter state. -*/ -static void -netjail_start_run (void *cls, - struct GNUNET_TESTING_Interpreter *is) -{ - struct NetJailState *ns = cls; - char pid[15]; - enum GNUNET_GenericReturnValue helper_check; - - // FIXME: NETJAIL_START_SCRIPT like this is bad, - // use location from share/gnunet/ of installed - // binary in case libgnunettesting is used as a lib! - helper_check = GNUNET_OS_check_helper_binary ( - NETJAIL_START_SCRIPT, - GNUNET_YES, - NULL); - - if (GNUNET_NO == helper_check) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "No SUID for %s!\n", - NETJAIL_START_SCRIPT); - GNUNET_TESTING_interpreter_fail (is); - return; - } - if (GNUNET_SYSERR == helper_check) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%s not found!\n", - NETJAIL_START_SCRIPT); - GNUNET_TESTING_interpreter_fail (is); - return; - } - - GNUNET_snprintf (pid, - sizeof (pid), - "%u", - getpid ()); - { - char *const script_argv[] = { - NETJAIL_START_SCRIPT, - ns->topology_config, - pid, - NULL - }; - - ns->start_proc - = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR, - NULL, - NULL, - NULL, - NETJAIL_START_SCRIPT, - script_argv); - } - ns->cwh = GNUNET_wait_child (ns->start_proc, - &child_completed_callback, - ns); - GNUNET_break (NULL != ns->cwh); -} - - -/** - * Create command. - * - * @param label name for command. - * @param topology_config Configuration file for the test topology. - * @return command. - */ -struct GNUNET_TESTING_Command -GNUNET_TESTING_cmd_netjail_start_v2 (const char *label, - char *topology_config) -{ - struct NetJailState *ns; - - ns = GNUNET_new (struct NetJailState); - ns->topology_config = topology_config; - { - struct GNUNET_TESTING_Command cmd = { - .cls = ns, - .label = label, - .run = &netjail_start_run, - .ac = &ns->ac, - .cleanup = &netjail_start_cleanup - }; - - return cmd; - } -} diff --git a/src/testing/testing_api_cmd_netjail_stop.c b/src/testing/testing_api_cmd_netjail_stop.c index 8c78b5e93..5033272a3 100644 --- a/src/testing/testing_api_cmd_netjail_stop.c +++ b/src/testing/testing_api_cmd_netjail_stop.c @@ -31,7 +31,7 @@ #define NETJAIL_STOP_SCRIPT "./../testing/netjail_stop.sh" // Child Wait handle -struct GNUNET_ChildWaitHandle *cwh; +static struct GNUNET_ChildWaitHandle *cwh; /** * Struct to hold information for callbacks. @@ -44,11 +44,10 @@ struct NetJailState */ struct GNUNET_TESTING_AsyncContext ac; - // Number of local nodes in each namespace. - char *local_m; - - // The number of namespaces. - char *global_n; + /** + * Configuration file for the test topology. + */ + char *topology_config; /** * The process id of the start script. @@ -85,20 +84,6 @@ netjail_stop_cleanup (void *cls) } -/** - * Trait function of this cmd does nothing. - * - */ -static enum GNUNET_GenericReturnValue -netjail_stop_traits (void *cls, - const void **ret, - const char *trait, - unsigned int index) -{ - return GNUNET_NO; -} - - /** * Callback which will be called if the setup script finished. * @@ -110,7 +95,7 @@ child_completed_callback (void *cls, { struct NetJailState *ns = cls; - cwh = NULL; + cwh = NULL; // WTF? globals!?!?! GNUNET_OS_process_destroy (ns->stop_proc); ns->stop_proc = NULL; if (0 == exit_code) @@ -119,7 +104,6 @@ child_completed_callback (void *cls, } else { - // FIXME: log exit code! GNUNET_TESTING_async_fail (&ns->ac); } } @@ -129,7 +113,6 @@ child_completed_callback (void *cls, * The run method starts the script which deletes the network namespaces. * * @param cls closure. -* @param cmd CMD being run. * @param is interpreter state. */ static void @@ -137,12 +120,15 @@ netjail_stop_run (void *cls, struct GNUNET_TESTING_Interpreter *is) { struct NetJailState *ns = cls; - char *const script_argv[] = { - NETJAIL_STOP_SCRIPT, - ns->local_m, - ns->global_n, - NULL - }; + char *pid; + + GNUNET_asprintf (&pid, + "%u", + getpid ()); + char *const script_argv[] = {NETJAIL_STOP_SCRIPT, + ns->topology_config, + pid, + NULL}; unsigned int helper_check = GNUNET_OS_check_helper_binary ( NETJAIL_STOP_SCRIPT, GNUNET_YES, @@ -174,28 +160,24 @@ netjail_stop_run (void *cls, &child_completed_callback, ns); GNUNET_break (NULL != cwh); - } struct GNUNET_TESTING_Command GNUNET_TESTING_cmd_netjail_stop (const char *label, - char *local_m, - char *global_n) + char *topology_config) { struct NetJailState *ns; ns = GNUNET_new (struct NetJailState); - ns->local_m = local_m; - ns->global_n = global_n; + ns->topology_config = topology_config; { struct GNUNET_TESTING_Command cmd = { .cls = ns, .label = label, .run = &netjail_stop_run, .ac = &ns->ac, - .cleanup = &netjail_stop_cleanup, - .traits = &netjail_stop_traits + .cleanup = &netjail_stop_cleanup }; return cmd; diff --git a/src/testing/testing_api_cmd_netjail_stop_testsystem.c b/src/testing/testing_api_cmd_netjail_stop_testsystem.c index 04b0e4e94..d3754153d 100644 --- a/src/testing/testing_api_cmd_netjail_stop_testsystem.c +++ b/src/testing/testing_api_cmd_netjail_stop_testsystem.c @@ -42,9 +42,15 @@ struct StopHelperState */ struct GNUNET_HELPER_Handle **helper; - char *local_m; + unsigned int local_m; - char *global_n; + unsigned int global_n; + + /** + * Number of global known nodes. + * + */ + unsigned int known; }; @@ -57,6 +63,7 @@ struct StopHelperState static void stop_testing_system_cleanup (void *cls) { + } @@ -64,13 +71,13 @@ stop_testing_system_cleanup (void *cls) * Trait function of this cmd does nothing. * */ -static enum GNUNET_GenericReturnValue +static int stop_testing_system_traits (void *cls, const void **ret, const char *trait, unsigned int index) { - return GNUNET_NO; + return GNUNET_OK; } @@ -88,17 +95,30 @@ stop_testing_system_run (void *cls, struct GNUNET_HELPER_Handle **helper; const struct GNUNET_TESTING_Command *start_helper_cmd; - start_helper_cmd = GNUNET_TESTING_interpreter_lookup_command ( - is, - shs->helper_start_label); + start_helper_cmd = GNUNET_TESTING_interpreter_lookup_command (NULL, + shs-> + helper_start_label); GNUNET_TESTING_get_trait_helper_handles (start_helper_cmd, &helper); - for (int i = 1; i <= atoi (shs->global_n); i++) + for (int i = 1; i <= shs->known; i++) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "i: %u\n", + i); + GNUNET_HELPER_stop (helper[i - 1], + GNUNET_YES); + } + + for (int i = 1; i <= shs->global_n; i++) { - for (int j = 1; j <= atoi (shs->local_m); j++) + for (int j = 1; j <= shs->local_m; j++) { - GNUNET_HELPER_stop (helper[(i - 1) * atoi (shs->local_m) + j - 1], + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "i: %u j: %u\n", + i, + j); + GNUNET_HELPER_stop (helper[(i - 1) * shs->local_m + j + shs->known - 1], GNUNET_YES); } } @@ -107,34 +127,35 @@ stop_testing_system_run (void *cls, /** * Create command. - * @param helper_start_label label of the cmd to start the test system. + * * @param label name for command. - * @param . - * @param local_m Number of nodes in a network namespace. //TODO make this a unsigned int - * @param global_n Number of network namespaces. //TODO make this a unsigned int + * @param helper_start_label label of the cmd to start the test system. + * @param topology_config Configuration file for the test topology. * @return command. */ struct GNUNET_TESTING_Command GNUNET_TESTING_cmd_stop_testing_system (const char *label, const char *helper_start_label, - char *local_m, - char *global_n) + const char *topology_config) { struct StopHelperState *shs; + struct GNUNET_TESTING_NetjailTopology *topology = + GNUNET_TESTING_get_topo_from_file (topology_config); + shs = GNUNET_new (struct StopHelperState); shs->helper_start_label = helper_start_label; - shs->local_m = local_m; - shs->global_n = global_n; - { - struct GNUNET_TESTING_Command cmd = { - .cls = shs, - .label = label, - .run = &stop_testing_system_run, - .cleanup = &stop_testing_system_cleanup, - .traits = &stop_testing_system_traits - }; - - return cmd; - } + shs->local_m = topology->nodes_m; + shs->global_n = topology->namespaces_n; + shs->known = topology->nodes_x; + + struct GNUNET_TESTING_Command cmd = { + .cls = shs, + .label = label, + .run = &stop_testing_system_run, + .cleanup = &stop_testing_system_cleanup, + .traits = &stop_testing_system_traits + }; + + return cmd; } diff --git a/src/testing/testing_api_cmd_netjail_stop_testsystem_v2.c b/src/testing/testing_api_cmd_netjail_stop_testsystem_v2.c deleted file mode 100644 index 65eb85d9a..000000000 --- a/src/testing/testing_api_cmd_netjail_stop_testsystem_v2.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - This file is part of GNUnet - Copyright (C) 2021 GNUnet e.V. - - GNUnet is free software: you can redistribute it and/or modify it - under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - SPDX-License-Identifier: AGPL3.0-or-later - */ - -/** - * @file testing/testing_api_cmd_hello_world.c - * @brief Command to start the netjail peers. - * @author t3sserakt - */ -#include "platform.h" -#include "gnunet_testing_ng_lib.h" -#include "testing_cmds.h" - - -/** - * Struct to store information handed over to callbacks. - * - */ -struct StopHelperState -{ - - const char *helper_start_label; - - /** - * The process handle - */ - struct GNUNET_HELPER_Handle **helper; - - unsigned int local_m; - - unsigned int global_n; -}; - - -/** -* Code to clean up resource this cmd used. -* -* @param cls closure -*/ -static void -stop_testing_system_cleanup (void *cls) -{ - -} - - -/** - * Trait function of this cmd does nothing. - * - */ -static enum GNUNET_GenericReturnValue -stop_testing_system_traits (void *cls, - const void **ret, - const char *trait, - unsigned int index) -{ - return GNUNET_NO; -} - - -/** -* This function stops the helper process for each node. -* -* @param cls closure. -* @param is interpreter state. -*/ -static void -stop_testing_system_run (void *cls, - struct GNUNET_TESTING_Interpreter *is) -{ - struct StopHelperState *shs = cls; - struct GNUNET_HELPER_Handle **helper; - const struct GNUNET_TESTING_Command *start_helper_cmd; - - start_helper_cmd = GNUNET_TESTING_interpreter_lookup_command ( - is, - shs->helper_start_label); - GNUNET_TESTING_get_trait_helper_handles (start_helper_cmd, - &helper); - - for (int i = 1; i <= shs->global_n; i++) - { - for (int j = 1; j <= shs->local_m; j++) - { - GNUNET_HELPER_stop (helper[(i - 1) * shs->local_m + j - 1], - GNUNET_YES); - } - } -} - - -/** - * Create command. - * - * @param label name for command. - * @param helper_start_label label of the cmd to start the test system. - * @param topology_config Configuration file for the test topology. - * @return command. - */ -struct GNUNET_TESTING_Command -GNUNET_TESTING_cmd_stop_testing_system_v2 (const char *label, - const char *helper_start_label, - const char *topology_config) -{ - struct StopHelperState *shs; - - struct GNUNET_TESTING_NetjailTopology *topology = - GNUNET_TESTING_get_topo_from_file (topology_config); - - shs = GNUNET_new (struct StopHelperState); - shs->helper_start_label = helper_start_label; - shs->local_m = topology->nodes_m; - shs->global_n = topology->namespaces_n; - { - struct GNUNET_TESTING_Command cmd = { - .cls = shs, - .label = label, - .run = &stop_testing_system_run, - .cleanup = &stop_testing_system_cleanup, - .traits = &stop_testing_system_traits - }; - - return cmd; - } -} diff --git a/src/testing/testing_api_cmd_netjail_stop_v2.c b/src/testing/testing_api_cmd_netjail_stop_v2.c deleted file mode 100644 index a0e2657cb..000000000 --- a/src/testing/testing_api_cmd_netjail_stop_v2.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - This file is part of GNUnet - Copyright (C) 2021 GNUnet e.V. - - GNUnet is free software: you can redistribute it and/or modify it - under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - SPDX-License-Identifier: AGPL3.0-or-later - */ - -/** - * @file testing/testing_api_cmd_netjail_stop_v2.c - * @brief Command to stop the netjail script. - * @author t3sserakt - */ -#include "platform.h" -#include "gnunet_util_lib.h" -#include "gnunet_testing_ng_lib.h" - - -#define NETJAIL_STOP_SCRIPT "./../testing/netjail_stop_v2.sh" - -// Child Wait handle -static struct GNUNET_ChildWaitHandle *cwh; - -/** - * Struct to hold information for callbacks. - * - */ -struct NetJailState -{ - /** - * Context for our asynchronous completion. - */ - struct GNUNET_TESTING_AsyncContext ac; - - /** - * Configuration file for the test topology. - */ - char *topology_config; - - /** - * The process id of the start script. - */ - struct GNUNET_OS_Process *stop_proc; - -}; - - -/** - * The cleanup function of this cmd frees resources the cmd allocated. - * - */ -static void -netjail_stop_cleanup (void *cls) -{ - struct NetJailState *ns = cls; - - if (NULL != cwh) - { - GNUNET_wait_child_cancel (cwh); - cwh = NULL; - } - if (NULL != ns->stop_proc) - { - GNUNET_assert (0 == - GNUNET_OS_process_kill (ns->stop_proc, - SIGKILL)); - GNUNET_assert (GNUNET_OK == - GNUNET_OS_process_wait (ns->stop_proc)); - GNUNET_OS_process_destroy (ns->stop_proc); - ns->stop_proc = NULL; - } -} - - -/** - * Callback which will be called if the setup script finished. - * - */ -static void -child_completed_callback (void *cls, - enum GNUNET_OS_ProcessStatusType type, - long unsigned int exit_code) -{ - struct NetJailState *ns = cls; - - cwh = NULL; // WTF? globals!?!?! - GNUNET_OS_process_destroy (ns->stop_proc); - ns->stop_proc = NULL; - if (0 == exit_code) - { - GNUNET_TESTING_async_finish (&ns->ac); - } - else - { - GNUNET_TESTING_async_fail (&ns->ac); - } -} - - -/** -* The run method starts the script which deletes the network namespaces. -* -* @param cls closure. -* @param is interpreter state. -*/ -static void -netjail_stop_run (void *cls, - struct GNUNET_TESTING_Interpreter *is) -{ - struct NetJailState *ns = cls; - char *pid; - - GNUNET_asprintf (&pid, - "%u", - getpid ()); - char *const script_argv[] = {NETJAIL_STOP_SCRIPT, - ns->topology_config, - pid, - NULL}; - unsigned int helper_check = GNUNET_OS_check_helper_binary ( - NETJAIL_STOP_SCRIPT, - GNUNET_YES, - NULL); - - if (GNUNET_NO == helper_check) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "No SUID for %s!\n", - NETJAIL_STOP_SCRIPT); - GNUNET_TESTING_interpreter_fail (is); - } - else if (GNUNET_NO == helper_check) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%s not found!\n", - NETJAIL_STOP_SCRIPT); - GNUNET_TESTING_interpreter_fail (is); - } - - ns->stop_proc = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR, - NULL, - NULL, - NULL, - NETJAIL_STOP_SCRIPT, - script_argv); - - cwh = GNUNET_wait_child (ns->stop_proc, - &child_completed_callback, - ns); - GNUNET_break (NULL != cwh); -} - - -struct GNUNET_TESTING_Command -GNUNET_TESTING_cmd_netjail_stop_v2 (const char *label, - char *topology_config) -{ - struct NetJailState *ns; - - ns = GNUNET_new (struct NetJailState); - ns->topology_config = topology_config; - { - struct GNUNET_TESTING_Command cmd = { - .cls = ns, - .label = label, - .run = &netjail_stop_run, - .ac = &ns->ac, - .cleanup = &netjail_stop_cleanup - }; - - return cmd; - } -} diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c index e0cb3fcda..3727d2543 100644 --- a/src/testing/testing_api_loop.c +++ b/src/testing/testing_api_loop.c @@ -313,8 +313,12 @@ interpreter_run (void *cls) } cmd->run (cmd->cls, is); - if ( (cmd->asynchronous_finish) && - (NULL != cmd->ac->cont) ) + if (NULL == cmd->ac) + { + interpreter_next (is); + } + else if ( (cmd->asynchronous_finish) && + (NULL != cmd->ac->cont) ) { cmd->ac->cont = NULL; interpreter_next (is); diff --git a/src/testing/testing_cmds.h b/src/testing/testing_cmds.h index 7a5860aea..09e4f2dcb 100644 --- a/src/testing/testing_cmds.h +++ b/src/testing/testing_cmds.h @@ -83,6 +83,8 @@ struct GNUNET_CMDS_LOCAL_FINISHED * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED */ struct GNUNET_MessageHeader header; + + enum GNUNET_GenericReturnValue result; }; GNUNET_NETWORK_STRUCT_END -- cgit v1.2.3