summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authort3serakt <t3ss@posteo.de>2024-02-15 13:53:40 +0100
committert3serakt <t3ss@posteo.de>2024-02-15 14:04:16 +0100
commit4b2303a35baa05a966543f036b43bb0cfaf22ab5 (patch)
tree2a8c8bb8547db7106a5598b2374db9c46623e46e
parent04c59fc58fbfd279306aaa22451754caa9b5a150 (diff)
Transport: Added test case to simulate router NAT mapping behavior.dev/t3ss/probnat
-rw-r--r--scripts/Makefile.am4
-rwxr-xr-xscripts/netjail/getmsg.sh15
-rwxr-xr-xscripts/netjail/nat_node_test.sh25
-rwxr-xr-xscripts/netjail/netjail_start.sh10
-rwxr-xr-xscripts/netjail/netjail_stop.sh2
-rw-r--r--src/service/testing/testing_api_cmd_exec_bash_script.c50
-rw-r--r--src/service/transport/Makefile.am17
-rwxr-xr-xsrc/service/transport/nat_router.sh63
-rwxr-xr-xsrc/service/transport/test_transport_nat_mapping.sh12
-rw-r--r--src/service/transport/test_transport_nat_mapping_topo.conf8
-rw-r--r--src/service/transport/test_transport_plugin_cmd_nat_mapping.c419
-rwxr-xr-xsrc/service/transport/timeout.sh59
12 files changed, 653 insertions, 31 deletions
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 994d90952..f714cdc84 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -2,6 +2,8 @@
AM_CPPFLAGS = -I$(top_srcdir)/src/include -I$(top_builddir)/src/include
dist_pkgdata_DATA = \
+ netjail/nat_node_test.sh \
+ netjail/getmsg.sh \
netjail/netjail_core.sh \
netjail/netjail_exec.sh \
netjail/netjail_start.sh \
@@ -20,6 +22,8 @@ EXTRA_DIST = \
sphinx_update.sh
install-data-hook:
+ chmod o+x '$(DESTDIR)$(pkgdatadir)/nat_node_test.sh'
+ chmod o+x '$(DESTDIR)$(pkgdatadir)/getmsg.sh'
chmod o+x '$(DESTDIR)$(pkgdatadir)/netjail_core.sh'
chmod o+x '$(DESTDIR)$(pkgdatadir)/netjail_start.sh'
chmod o+x '$(DESTDIR)$(pkgdatadir)/netjail_stop.sh'
diff --git a/scripts/netjail/getmsg.sh b/scripts/netjail/getmsg.sh
new file mode 100755
index 000000000..84d500c88
--- /dev/null
+++ b/scripts/netjail/getmsg.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+dirname=$(dirname "$0")
+if [ $3 -gt 3 ]
+then
+ exit 1
+fi
+it=$(($3+1))
+read MESSAGE
+echo START "$MESSAGE" END
+if [ "START second END" != "$MESSAGE" ] || [ "START END" != "$MESSAGE" ]
+then
+ (nc -N -l $1 | $dirname/getmsg.sh $1 $2 $it >> getmsg_$2.out) &
+else
+ echo failure
+fi
diff --git a/scripts/netjail/nat_node_test.sh b/scripts/netjail/nat_node_test.sh
new file mode 100755
index 000000000..f10e581ee
--- /dev/null
+++ b/scripts/netjail/nat_node_test.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+dirname=$(dirname "$0")
+PORT=$1
+PREFIX=$2
+DST=$3
+echo nat_node_test args $PORT $PREFIX $DST > gaga_$PREFIX.out
+(nc -N -l $PORT | $dirname/getmsg.sh $PORT $PREFIX 1 > getmsg_$PREFIX.out) &
+printf "first" |nc -N $DST $PORT
+sleep 5
+printf "second" |nc -N $DST $PORT
+sleep 10
+printf "third" |nc -N $DST $PORT
+sleep 5
+if [ "" != "$(grep failure getmsg_$PREFIX.out)" ]
+then
+ echo FAILURE: We received third message. >> gaga_$PREFIX.out
+ exit 1
+elif [ "" != "$(grep second getmsg_$PREFIX.out)" ]
+then
+ echo SUCCESS >> gaga_$PREFIX.out
+ exit 0
+else
+ echo FAILURE: Something unexpected happened. >> gaga_$PREFIX.out
+ exit 1
+fi
diff --git a/scripts/netjail/netjail_start.sh b/scripts/netjail/netjail_start.sh
index 5e1dd2b1f..11a3f3a58 100755
--- a/scripts/netjail/netjail_start.sh
+++ b/scripts/netjail/netjail_start.sh
@@ -99,18 +99,18 @@ for N in $(seq $GLOBAL_N); do
ip netns exec ${ROUTERS[$N]} ip route add "$KNOWN_GROUP.$X" dev ${ROUTER_EXT_IF[$N]}
ip netns exec ${ROUTERS[$N]} ip route add default via "$KNOWN_GROUP.$X"
-
+
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]} nft add rule ip nat prerouting ip daddr $GLOBAL_GROUP.$N tcp dport 60002 counter dnat to $LOCAL_GROUP.1
@@ -159,7 +159,7 @@ for N in $(seq $GLOBAL_N); do
fi
if [ "" != "${R_SCRIPT[$N]}" ]
then
- ip netns exec ${ROUTERS[$N]} ./${R_SCRIPT[$N]} ${ROUTER_NETS[$N]} 1
+ ip netns exec ${ROUTERS[$N]} ./${R_SCRIPT[$N]} ${ROUTER_NETS[$N]} 1 $N &
fi
done
diff --git a/scripts/netjail/netjail_stop.sh b/scripts/netjail/netjail_stop.sh
index 8f6c07f50..420a14b62 100755
--- a/scripts/netjail/netjail_stop.sh
+++ b/scripts/netjail/netjail_stop.sh
@@ -47,7 +47,7 @@ for N in $(seq $GLOBAL_N); do
then
if [ "" != "${R_SCRIPT[$N]}" ]
then
- ip netns exec ${ROUTERS[$N]} ./${R_SCRIPT[$N]} ${ROUTERS[$N]} 0 $PREFIX
+ ip netns exec ${ROUTERS[$N]} ./${R_SCRIPT[$N]} ${ROUTERS[$N]} 0 $N
fi
rm -rf /tmp/netjail_scripts
fi
diff --git a/src/service/testing/testing_api_cmd_exec_bash_script.c b/src/service/testing/testing_api_cmd_exec_bash_script.c
index 171a2baac..54850ccb9 100644
--- a/src/service/testing/testing_api_cmd_exec_bash_script.c
+++ b/src/service/testing/testing_api_cmd_exec_bash_script.c
@@ -59,7 +59,7 @@ struct BashScriptState
/**
* Arguments for the script
*/
- char *const*script_argv;
+ char **script_argv;
/**
* Size of script_argv.
@@ -139,28 +139,21 @@ exec_bash_script_run (void *cls,
{
struct BashScriptState *bss = cls;
enum GNUNET_GenericReturnValue helper_check;
- char *argv[bss->argc + 2];
-
- char *data_dir;
- char *script_name;
-
- data_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR);
- GNUNET_asprintf (&script_name, "%s%s", data_dir, bss->script);
helper_check = GNUNET_OS_check_helper_binary (
- script_name,
+ bss->script_argv[0],
GNUNET_YES,
NULL);
LOG (GNUNET_ERROR_TYPE_DEBUG,
"script_name %s\n",
- script_name);
+ bss->script_argv[0]);
if (GNUNET_NO == helper_check)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"No SUID for %s!\n",
- script_name);
+ bss->script_argv[0]);
GNUNET_TESTING_interpreter_fail (is);
return;
}
@@ -168,24 +161,17 @@ exec_bash_script_run (void *cls,
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"%s not found!\n",
- script_name);
+ bss->script_argv[0]);
GNUNET_TESTING_interpreter_fail (is);
return;
}
- argv[0] = script_name;
- if (NULL != bss->script_argv)
- {
- for (int i = 0; i < bss->argc;i++)
- argv[i + 1] = bss->script_argv[i];
- }
- argv[bss->argc] = NULL;
bss->start_proc = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR,
NULL,
NULL,
NULL,
- script_name,
- argv);
+ bss->script_argv[0],
+ bss->script_argv);
bss->cwh = GNUNET_wait_child (bss->start_proc,
&child_completed_callback,
bss);
@@ -200,13 +186,27 @@ GNUNET_TESTING_cmd_exec_bash_script (const char *label,
GNUNET_ChildCompletedCallback cb)
{
struct BashScriptState *bss;
+ char *data_dir;
+ char *script_name;
+ unsigned int c;
+
+ data_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR);
+ GNUNET_asprintf (&script_name, "%s%s", data_dir, script);
bss = GNUNET_new (struct BashScriptState);
- bss->script = script;
- bss->script_argv = script_argv; // FIXME this is not just a cast to fix
- bss->argc = argc;
bss->cb = cb;
+ bss->script_argv = GNUNET_malloc (sizeof(char *) * (argc + 2));
+ bss->script_argv[0] = GNUNET_strdup (script_name);
+ for (c = 0; c < argc; c++)
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "script_argv %u: %s\n",
+ c,
+ script_argv[c]);
+ bss->script_argv[c + 1] = GNUNET_strdup (script_argv[c]);
+ }
+ bss->script_argv[c + 1] = NULL;
return GNUNET_TESTING_command_new (bss,
label,
&exec_bash_script_run,
diff --git a/src/service/transport/Makefile.am b/src/service/transport/Makefile.am
index e15a9b029..03c5448f4 100644
--- a/src/service/transport/Makefile.am
+++ b/src/service/transport/Makefile.am
@@ -189,6 +189,7 @@ gnunet_service_transport_LDADD = \
$(GN_LIBINTL)
plugin_LTLIBRARIES = \
+ libgnunet_test_transport_plugin_cmd_nat_mapping.la \
libgnunet_test_transport_plugin_cmd_simple_send_performance.la \
libgnunet_test_transport_plugin_cmd_nat_upnp.la \
libgnunet_test_transport_plugin_cmd_simple_send.la \
@@ -196,6 +197,22 @@ plugin_LTLIBRARIES = \
libgnunet_test_transport_plugin_cmd_simple_send_dv.la \
libgnunet_test_transport_plugin_cmd_udp_backchannel.la
+libgnunet_test_transport_plugin_cmd_nat_mapping_la_SOURCES = \
+ test_transport_plugin_cmd_nat_mapping.c
+libgnunet_test_transport_plugin_cmd_nat_mapping_la_LIBADD = \
+ libgnunettransporttesting2.la \
+ libgnunettransportapplication.la \
+ libgnunettransportcore.la \
+ $(top_builddir)/src/service/testing/libgnunettesting.la \
+ $(top_builddir)/src/service/peerstore/libgnunetpeerstore.la \
+ $(top_builddir)/src/service/statistics/libgnunetstatistics.la \
+ $(top_builddir)/src/lib/hello/libgnunethello.la \
+ $(top_builddir)/src/service/arm/libgnunetarm.la \
+ $(top_builddir)/src/lib/util/libgnunetutil.la \
+ $(LTLIBINTL)
+libgnunet_test_transport_plugin_cmd_nat_mapping_la_LDFLAGS = \
+ $(GN_PLUGIN_LDFLAGS)
+
libgnunet_test_transport_plugin_cmd_nat_upnp_la_SOURCES = \
test_transport_plugin_cmd_nat_upnp.c
libgnunet_test_transport_plugin_cmd_nat_upnp_la_LIBADD = \
diff --git a/src/service/transport/nat_router.sh b/src/service/transport/nat_router.sh
new file mode 100755
index 000000000..37fa5db3c
--- /dev/null
+++ b/src/service/transport/nat_router.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+dirname=$(dirname "$0")
+PREFIX=$3
+echo start $2 >> timeout_$PREFIX.log
+if [ $2 -eq 1 ]
+then
+ if [ ! -d /tmp/netjail_scripts ]
+ then
+ mkdir /tmp/netjail_scripts
+ fi
+ if [ -f timeout_$PREFIX.out ]
+ then
+ rm timeout_$PREFIX.out
+ fi
+ touch timeout_$PREFIX.out
+ if [ -f timeout_$PREFIX.log ]
+ then
+ rm timeout_$PREFIX.log
+ fi
+ touch timeout_$PREFIX.log
+ timeout=6000000000
+ $dirname/timeout.sh $timeout $PREFIX &
+ echo gaga >> timeout_$PREFIX.log
+ timeout_pid=$!
+ conntrack -E -e NEW -s 192.168.15.1 -d 92.68.150.1/24 | while read line
+ do
+ protocol=$(echo $line|awk '{printf $2"\n"}'|awk '{printf $1"\n"}')
+ dst=$(echo $line|awk -Fdst= '{printf $2"\n"}'|awk '{printf $1"\n"}')
+ src=$(echo $line|awk -Fdst= '{printf $1"\n"}'|awk -Fsrc= '{printf $2"\n"}')
+ port=$(echo $line|awk -Fdport= '{printf $2"\n"}'|awk '{printf $1"\n"}')
+ echo dnat >> timeout_$PREFIX.log
+ now=$(date +%s%N)
+ kill -TSTP $timeout_pid
+ if [ $(wc -l < timeout_$PREFIX.out) -eq 0 ]
+ then
+ iptables-nft -t nat -A PREROUTING -p $protocol -s $dst -d 92.68.150.$PREFIX -j DNAT --to $src
+ # echo iptables-nft -t nat -A PREROUTING -p $protocol -s $dst -d 92.68.150.1 -j DNAT --to $src >> timeout_$PREFIX.out
+ echo forwarding >> timeout_$PREFIX.log
+ fi
+ # echo $line >> timeout_$PREFIX.out
+ echo $now $protocol $dst $src $port >> timeout_$PREFIX.out
+ kill -CONT $timeout_pid
+ done
+ echo gigi >> timeout_$PREFIX.log
+ rm timeout_$PREFIX.out
+else
+ #echo "find -L /proc/[1-9]*/task/*/ns/net -samefile /run/netns/$1|while read x" >> timeout_$PREFIX.log
+ #find -L /proc/[1-9]*/task/*/ns/net -samefile /run/netns/$1|while read x
+ #do
+ #if [ "" != "$(ps aux|grep $x|grep conntrack)" ]
+ #then
+ echo kill conntrack >> timeout_$PREFIX.log
+ killall conntrack #$x
+ #fi
+ #if [ "" != "$(ps aux|grep $x|grep timeout)" ]
+ #then
+ echo kill timeout >> timeout_$PREFIX.log
+ killall timeout.sh #$x
+ echo kill getmsg >> timeout_$PREFIX.log
+ killall getmsg.sh
+ #fi
+ #done
+fi
diff --git a/src/service/transport/test_transport_nat_mapping.sh b/src/service/transport/test_transport_nat_mapping.sh
new file mode 100755
index 000000000..4e7d6d738
--- /dev/null
+++ b/src/service/transport/test_transport_nat_mapping.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+if ! [ -d "/run/netns" ]; then
+ echo You have to create the directory /run/netns.
+fi
+if [ -f /proc/sys/kernel/unprivileged_userns_clone ]; then
+ if [ "$(cat /proc/sys/kernel/unprivileged_userns_clone)" != 1 ]; then
+ echo -e "Error during test setup: The kernel parameter kernel.unprivileged_userns_clone has to be set to 1! One has to execute\n\n sysctl kernel.unprivileged_userns_clone=1\n"
+ exit 78
+ fi
+fi
+# exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; valgrind --leak-check=full --track-origins=yes --trace-children=yes --trace-children-skip=/usr/bin/awk,/usr/bin/cut,/usr/bin/seq,/sbin/ip/sed/bash ./test_transport_start_with_config test_transport_distance_vector_inverse_topo.conf"
+exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; ./test_transport_start_with_config test_transport_nat_mapping_topo.conf"
diff --git a/src/service/transport/test_transport_nat_mapping_topo.conf b/src/service/transport/test_transport_nat_mapping_topo.conf
new file mode 100644
index 000000000..4993d77f4
--- /dev/null
+++ b/src/service/transport/test_transport_nat_mapping_topo.conf
@@ -0,0 +1,8 @@
+M:1
+N:2
+X:0
+T:libgnunet_test_transport_plugin_cmd_nat_mapping
+R:1|{tcp_port:0}|{udp_port:0}|{script:nat_router.sh}
+R:2|{tcp_port:0}|{udp_port:0}|{script:nat_router.sh}
+P:1:1|{connect:{P:2:1:tcp}}
+P:2:1|{connect:{P:1:1:tcp}} \ No newline at end of file
diff --git a/src/service/transport/test_transport_plugin_cmd_nat_mapping.c b/src/service/transport/test_transport_plugin_cmd_nat_mapping.c
new file mode 100644
index 000000000..cb16da284
--- /dev/null
+++ b/src/service/transport/test_transport_plugin_cmd_nat_mapping.c
@@ -0,0 +1,419 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+/**
+ * @file testbed/plugin_cmd_nat_mapping.c
+ * @brief a plugin to provide the API for running test cases.
+ * @author t3sserakt
+ */
+#include "platform.h"
+#include "gnunet_testing_barrier.h"
+#include "gnunet_testing_netjail_lib.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_transport_application_service.h"
+#include "transport-testing2.h"
+#include "transport-testing-cmds.h"
+#include "gnunet_testing_barrier.h"
+
+/**
+ * Generic logging shortcut
+ */
+#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
+
+#define BASE_DIR "testdir"
+
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 600)
+
+#define ROUTER_BASE_IP "92.68.150."
+
+static struct GNUNET_TESTING_Command block_send;
+
+static struct GNUNET_TESTING_Command block_receive;
+
+static struct GNUNET_TESTING_Command connect_peers;
+
+static struct GNUNET_TESTING_Command local_prepared;
+
+static struct GNUNET_TESTING_Interpreter *is;
+
+/**
+ * Function called to check a message of type GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE being
+ * received.
+ *
+ */
+static int
+check_test (void *cls,
+ const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
+{
+ return GNUNET_OK;
+}
+
+
+/**
+ * Function called to handle a message of type GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE
+ * being received.
+ *
+ */
+static void
+handle_test (void *cls,
+ const struct GNUNET_TRANSPORT_TESTING_TestMessage *message)
+{
+ struct GNUNET_TESTING_AsyncContext *ac;
+
+ GNUNET_TESTING_get_trait_async_context (&block_receive,
+ &ac);
+ GNUNET_assert (NULL != ac);
+ if (NULL == ac->cont)
+ GNUNET_TESTING_async_fail ((struct GNUNET_TESTING_AsyncContext *) ac);
+ else
+ GNUNET_TESTING_async_finish ((struct GNUNET_TESTING_AsyncContext *) ac);
+}
+
+
+struct GNUNET_TESTING_BarrierList *
+get_waiting_for_barriers ()
+{
+ //No Barrier
+ return GNUNET_new (struct GNUNET_TESTING_BarrierList);
+}
+
+
+/**
+ * Callback to set the flag indicating all peers started. Will be called via the plugin api.
+ *
+ */
+static void
+all_peers_started ()
+{
+ struct GNUNET_TESTING_AsyncContext *ac;
+
+ GNUNET_TESTING_get_trait_async_context (&block_send,
+ &ac);
+ GNUNET_assert (NULL != ac);
+ if (NULL == ac->cont)
+ GNUNET_TESTING_async_fail ((struct GNUNET_TESTING_AsyncContext *) ac);
+ else
+ GNUNET_TESTING_async_finish ((struct GNUNET_TESTING_AsyncContext *) ac);
+}
+
+
+/**
+ * Function called with the final result of the test.
+ *
+ * @param cls the `struct MainParams`
+ * @param rv #GNUNET_OK if the test passed
+ */
+static void
+handle_result (void *cls,
+ enum GNUNET_GenericReturnValue rv)
+{
+ struct TestState *ts = cls;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Local test exits with status %d\n",
+ rv);
+
+ ts->finished_cb (rv);
+ GNUNET_free (ts->testdir);
+ GNUNET_free (ts->cfgname);
+ GNUNET_TESTING_free_topology (ts->topology);
+ GNUNET_free (ts);
+}
+
+
+/**
+ * Callback from start peer cmd for signaling a peer got connected.
+ *
+ */
+static void *
+notify_connect (struct GNUNET_TESTING_Interpreter *is,
+ const struct GNUNET_PeerIdentity *peer)
+{
+ const struct ConnectPeersState *cps;
+ const struct GNUNET_TESTING_Command *cmd;
+
+ cmd = GNUNET_TESTING_interpreter_lookup_command (is,
+ "connect-peers");
+ GNUNET_TRANSPORT_TESTING_get_trait_connect_peer_state (cmd,
+ &cps);
+ void *ret = NULL;
+
+ cps->notify_connect (is,
+ peer);
+ return ret;
+}
+
+
+/**
+ * Callback to set the flag indicating all peers are prepared to finish. Will be called via the plugin api.
+ */
+static void
+all_local_tests_prepared ()
+{
+ const struct GNUNET_TESTING_LocalPreparedState *lfs;
+
+ GNUNET_TESTING_get_trait_local_prepared_state (&local_prepared,
+ &lfs);
+ GNUNET_assert (NULL != &lfs->ac);
+ if (NULL == lfs->ac.cont)
+ GNUNET_TESTING_async_fail ((struct GNUNET_TESTING_AsyncContext *) &lfs->ac);
+ else
+ GNUNET_TESTING_async_finish ((struct
+ GNUNET_TESTING_AsyncContext *) &lfs->ac);
+}
+
+
+static void
+child_completed_callback (void *cls,
+ enum GNUNET_OS_ProcessStatusType type,
+ long unsigned int exit_code)
+{
+
+}
+
+
+/**
+ * Function to start a local test case.
+ *
+ * @param write_message Callback to send a message to the master loop.
+ * @param router_ip Global address of the network namespace.
+ * @param node_ip The IP address of the node.
+ * @param m The number of the node in a network namespace.
+ * @param n The number of the network namespace.
+ * @param local_m The number of nodes in a network namespace.
+ */
+static struct GNUNET_TESTING_Interpreter *
+start_testcase (GNUNET_TESTING_cmd_helper_write_cb write_message,
+ const char *router_ip,
+ const char *node_ip,
+ const char *m,
+ const char *n,
+ const char *local_m,
+ const char *topology_data,
+ unsigned int *read_file,
+ GNUNET_TESTING_cmd_helper_finish_cb finished_cb)
+{
+
+ unsigned int n_int;
+ unsigned int m_int;
+ unsigned int local_m_int;
+ unsigned int num;
+ struct TestState *ts = GNUNET_new (struct TestState);
+ struct GNUNET_TESTING_NetjailTopology *topology;
+ unsigned int sscanf_ret = 0;
+ char **argv = NULL;
+ unsigned int argc = 0;
+ char *dst_ip;
+ char *num_string;
+
+
+
+ ts->finished_cb = finished_cb;
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "n %s m %s\n",
+ n,
+ m);
+
+ if (GNUNET_YES == *read_file)
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "read from file\n");
+ topology = GNUNET_TESTING_get_topo_from_file (topology_data);
+ }
+ else
+ topology = GNUNET_TESTING_get_topo_from_string (topology_data);
+
+ ts->topology = topology;
+
+ errno = 0;
+ sscanf_ret = sscanf (m, "%u", &m_int);
+ if (errno != 0)
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sscanf");
+ }
+ GNUNET_assert (0 < sscanf_ret);
+ errno = 0;
+ sscanf_ret = sscanf (n, "%u", &n_int);
+ if (errno != 0)
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sscanf");
+ }
+ GNUNET_assert (0 < sscanf_ret);
+ errno = 0;
+ sscanf_ret = sscanf (local_m, "%u", &local_m_int);
+ if (errno != 0)
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sscanf");
+ }
+ GNUNET_assert (0 < sscanf_ret);
+
+ if (0 == n_int)
+ num = m_int;
+ else
+ num = (n_int - 1) * local_m_int + m_int + topology->nodes_x;
+
+ block_send = GNUNET_TESTING_cmd_block_until_external_trigger (
+ "block");
+ block_receive = GNUNET_TESTING_cmd_block_until_external_trigger (
+ "block-receive");
+ connect_peers = GNUNET_TRANSPORT_cmd_connect_peers ("connect-peers",
+ "start-peer",
+ "system-create",
+ num,
+ topology,
+ 0,
+ GNUNET_YES);
+ local_prepared = GNUNET_TESTING_cmd_local_test_prepared (
+ "local-test-prepared",
+ write_message);
+
+
+ GNUNET_asprintf (&ts->cfgname,
+ "test_transport_api2_tcp_node1.conf");
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "plugin cfgname: %s\n",
+ ts->cfgname);
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "node ip: %s\n",
+ node_ip);
+
+ GNUNET_asprintf (&ts->testdir,
+ "%s%s%s",
+ BASE_DIR,
+ m,
+ n);
+
+ struct GNUNET_MQ_MessageHandler handlers[] = {
+ GNUNET_MQ_hd_var_size (test,
+ GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE,
+ struct GNUNET_TRANSPORT_TESTING_TestMessage,
+ ts),
+ GNUNET_MQ_handler_end ()
+ };
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "num: %u\n",
+ num);
+ GNUNET_asprintf (&num_string,
+ "%u",
+ num);
+ GNUNET_array_append (argv, argc, "7777");
+ GNUNET_array_append (argv, argc, num_string);
+ if (1 == num )
+ {
+ GNUNET_asprintf (&dst_ip,
+ ROUTER_BASE_IP "%u",
+ num + 1);
+ GNUNET_array_append (argv, argc, dst_ip);
+ }
+ else
+ {
+ GNUNET_asprintf (&dst_ip,
+ ROUTER_BASE_IP "%u",
+ num - 1);
+ GNUNET_array_append (argv, argc, dst_ip);
+ }
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "dst_ip %s\n",
+ dst_ip);
+ struct GNUNET_TESTING_Command commands[] = {
+ GNUNET_TESTING_cmd_system_create ("system-create",
+ ts->testdir),
+ GNUNET_TRANSPORT_cmd_start_peer ("start-peer",
+ "system-create",
+ num,
+ node_ip,
+ handlers,
+ ts->cfgname,
+ notify_connect,
+ GNUNET_NO),
+ GNUNET_TESTING_cmd_exec_bash_script ("nat_node_test",
+ "nat_node_test.sh",
+ argv,
+ argc,
+ &child_completed_callback),
+ GNUNET_TESTING_cmd_send_peer_ready ("send-peer-ready",
+ write_message),
+ block_send,
+ connect_peers,
+ local_prepared,
+ GNUNET_TRANSPORT_cmd_stop_peer ("stop-peer",
+ "start-peer"),
+ GNUNET_TESTING_cmd_system_destroy ("system-destroy",
+ "system-create"),
+ GNUNET_TESTING_cmd_end ()
+ };
+
+ ts->write_message = write_message;
+
+ is = GNUNET_TESTING_run (commands,
+ TIMEOUT,
+ &handle_result,
+ ts);
+ GNUNET_free (num_string);
+ GNUNET_free (dst_ip);
+ return is;
+}
+
+
+/**
+ * Entry point for the plugin.
+ *
+ * @param cls NULL
+ * @return the exported block API
+ */
+void *
+libgnunet_test_transport_plugin_cmd_nat_mapping_init (void *cls)
+{
+ struct GNUNET_TESTING_PluginFunctions *api;
+
+ GNUNET_log_setup ("simple-send",
+ "DEBUG",
+ NULL);
+
+ api = GNUNET_new (struct GNUNET_TESTING_PluginFunctions);
+ api->start_testcase = &start_testcase;
+ api->all_peers_started = &all_peers_started;
+ api->all_local_tests_prepared = all_local_tests_prepared;
+ api->get_waiting_for_barriers = get_waiting_for_barriers;
+ return api;
+}
+
+
+/**
+ * Exit point from the plugin.
+ *
+ * @param cls the return value from #libgnunet_test_transport_plugin_cmd_nat_mapping_done
+ * @return NULL
+ */
+void *
+libgnunet_test_transport_plugin_cmd_nat_mapping_done (void *cls)
+{
+ struct GNUNET_TESTING_PluginFunctions *api = cls;
+
+ GNUNET_free (api);
+ return NULL;
+}
+
+
+/* end of plugin_cmd_nat_mapping.c */
diff --git a/src/service/transport/timeout.sh b/src/service/transport/timeout.sh
new file mode 100755
index 000000000..b5692eb7c
--- /dev/null
+++ b/src/service/transport/timeout.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+timeout=$1
+PREFIX=$2
+line=$(head -n 1 timeout_$PREFIX.out)
+date=$(echo $line|awk '{printf $1"\n"}')
+now=$(date +%s%N)
+sleeptime=$(bc -l <<< "0.000000001*$1")
+if [ "" != "$line" ] && [ $timeout -le $(($now - $date)) ]
+then
+ sleeptime=0
+elif [ "" != "$line" ]
+then
+ sleeptime=$(bc -l <<< "(${now}-${date})/1000000000")
+fi
+echo $sleeptime >> timeout_$PREFIX.log
+while sleep $sleeptime
+do
+ line_num=$(wc -l < timeout_$PREFIX.out)
+ if [ 0 -lt $line_num ];then
+ for i in $(seq 1 $line_num)
+ do
+ line=$(head -n 1 timeout_$PREFIX.out)
+ date=$(echo $line|awk '{printf $1"\n"}')
+ port=$(echo $line|awk '{printf $5"\n"}')
+ dst=$(echo $line|awk '{printf $3"\n"}')
+ src=$(echo $line|awk '{printf $4"\n"}')
+ protocol=$(echo $line|awk '{printf $2"\n"}')
+ ports[$i]=-1
+ now=$(date +%s%N)
+ echo $timeout $now $date >> timeout_$PREFIX.log
+ if [ $timeout -le $(($now - $date)) ]
+ then
+ ports[$i]=$port
+ echo delete dnat $port ${ports[$i]} >> timeout_$PREFIX.log
+ sed -i -n -e '2,$p' timeout_$PREFIX.out
+ sleeptime=$(bc -l <<< "0.000000001*$1")
+ else
+ for j in $(seq 1 $i)
+ do
+ if [ ${ports[$j]} -eq $port ]
+ then
+ ports[$j]=-1
+ fi
+ done
+ sleeptime=$(bc -l <<< "(${now}-${date})/1000000000")
+ echo $sleeptime >> timeout_$PREFIX.log
+ fi
+ done
+ for i in $(seq 1 $line_num)
+ do
+ echo $i ${ports[$i]} >> timeout_$PREFIX.log
+ if [ ${ports[$i]} -ne -1 ]
+ then
+ echo iptables-nft -t nat -D PREROUTING -p $protocol -s $dst -d 92.68.150.$PREFIX -j DNAT --to $src >> timeout_$PREFIX.log
+ iptables-nft -t nat -D PREROUTING -p $protocol -s $dst -d 92.68.150.$PREFIX -j DNAT --to $src
+ fi
+ done
+ fi
+done