aboutsummaryrefslogtreecommitdiff
path: root/src/testing
diff options
context:
space:
mode:
Diffstat (limited to 'src/testing')
-rw-r--r--src/testing/Makefile.am1
-rw-r--r--src/testing/gnunet-cmds-helper.c10
-rw-r--r--src/testing/test_testing_topology.c44
-rw-r--r--src/testing/testing.c260
-rw-r--r--src/testing/testing_api_cmd_local_test_prepared.c168
-rw-r--r--src/testing/testing_cmds.h17
-rwxr-xr-xsrc/testing/topo.sh8
7 files changed, 504 insertions, 4 deletions
diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am
index 39e85c4ac..3daa29e1e 100644
--- a/src/testing/Makefile.am
+++ b/src/testing/Makefile.am
@@ -47,6 +47,7 @@ libgnunettesting_la_SOURCES = \
47 testing_api_cmd_end.c \ 47 testing_api_cmd_end.c \
48 testing_api_cmd_finish.c \ 48 testing_api_cmd_finish.c \
49 testing_api_cmd_local_test_finished.c \ 49 testing_api_cmd_local_test_finished.c \
50 testing_api_cmd_local_test_prepared.c \
50 testing_api_cmd_send_peer_ready.c \ 51 testing_api_cmd_send_peer_ready.c \
51 testing_api_cmd_block_until_all_peers_started.c \ 52 testing_api_cmd_block_until_all_peers_started.c \
52 testing_api_cmd_block_until_external_trigger.c \ 53 testing_api_cmd_block_until_external_trigger.c \
diff --git a/src/testing/gnunet-cmds-helper.c b/src/testing/gnunet-cmds-helper.c
index e50db0cf6..4aeccb115 100644
--- a/src/testing/gnunet-cmds-helper.c
+++ b/src/testing/gnunet-cmds-helper.c
@@ -418,9 +418,19 @@ tokenizer_cb (void *cls, const struct GNUNET_MessageHeader *message)
418 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED == ntohs ( 418 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED == ntohs (
419 message->type)) 419 message->type))
420 { 420 {
421 LOG (GNUNET_ERROR_TYPE_DEBUG,
422 "all peers started\n");
421 plugin->api->all_peers_started (); 423 plugin->api->all_peers_started ();
422 return GNUNET_OK; 424 return GNUNET_OK;
423 } 425 }
426 else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_LOCAL_TESTS_PREPARED == ntohs (
427 message->type))
428 {
429 LOG (GNUNET_ERROR_TYPE_DEBUG,
430 "all local tests prepared\n");
431 plugin->api->all_local_tests_prepared ();
432 return GNUNET_OK;
433 }
424 else 434 else
425 { 435 {
426 LOG (GNUNET_ERROR_TYPE_WARNING, "Received unexpected message -- exiting\n"); 436 LOG (GNUNET_ERROR_TYPE_WARNING, "Received unexpected message -- exiting\n");
diff --git a/src/testing/test_testing_topology.c b/src/testing/test_testing_topology.c
new file mode 100644
index 000000000..cfc91e609
--- /dev/null
+++ b/src/testing/test_testing_topology.c
@@ -0,0 +1,44 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2021 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testbed/plugin_testcmd.c
23 * @brief a plugin to provide the API for running test cases.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testing_ng_lib.h"
29
30#define LOG(kind, ...) GNUNET_log_from (kind, "testing-api", __VA_ARGS__)
31
32int
33main (int argc,
34 char *const *argv)
35{
36 GNUNET_log_setup ("test-topology",
37 "DEBUG",
38 NULL);
39 LOG (GNUNET_ERROR_TYPE_DEBUG,
40 "Test\n");
41 GNUNET_TESTING_get_topo_from_file ("topo.conf");
42 LOG (GNUNET_ERROR_TYPE_DEBUG,
43 "Test2\n");
44}
diff --git a/src/testing/testing.c b/src/testing/testing.c
index 766c7b084..4d9b7c0cb 100644
--- a/src/testing/testing.c
+++ b/src/testing/testing.c
@@ -38,6 +38,15 @@
38 38
39#define LOG(kind, ...) GNUNET_log_from (kind, "testing-api", __VA_ARGS__) 39#define LOG(kind, ...) GNUNET_log_from (kind, "testing-api", __VA_ARGS__)
40 40
41#define CONNECT_ADDRESS_TEMPLATE "%s-192.168.15.%u:60002"
42
43#define ROUTER_CONNECT_ADDRESS_TEMPLATE "%s-92.68.150.%u:60002"
44
45#define KNOWN_CONNECT_ADDRESS_TEMPLATE "%s-92.68.151.%u:60002"
46
47#define PREFIX_TCP "tcp"
48
49#define PREFIX_UDP "udp"
41 50
42/** 51/**
43 * Lowest port used for GNUnet testing. Should be high enough to not 52 * Lowest port used for GNUnet testing. Should be high enough to not
@@ -1901,7 +1910,7 @@ get_connect_value (char *line, struct GNUNET_TESTING_NetjailNode *node)
1901 unsigned int namespace_n; 1910 unsigned int namespace_n;
1902 char *rest = NULL; 1911 char *rest = NULL;
1903 char *rest2 = NULL; 1912 char *rest2 = NULL;
1904 struct GNUNET_TESTING_ADDRESS_PREFIX *prefix; 1913 struct GNUNET_TESTING_AddressPrefix *prefix;
1905 1914
1906 node_connection = GNUNET_new (struct GNUNET_TESTING_NodeConnection); 1915 node_connection = GNUNET_new (struct GNUNET_TESTING_NodeConnection);
1907 node_connection->node = node; 1916 node_connection->node = node;
@@ -1937,7 +1946,7 @@ get_connect_value (char *line, struct GNUNET_TESTING_NetjailNode *node)
1937 } 1946 }
1938 while (NULL != (token = strtok_r (NULL, ":", &rest))) 1947 while (NULL != (token = strtok_r (NULL, ":", &rest)))
1939 { 1948 {
1940 prefix = GNUNET_new (struct GNUNET_TESTING_ADDRESS_PREFIX); 1949 prefix = GNUNET_new (struct GNUNET_TESTING_AddressPrefix);
1941 token2 = strtok_r (token, "}", &rest2); 1950 token2 = strtok_r (token, "}", &rest2);
1942 if (NULL != token2) 1951 if (NULL != token2)
1943 { 1952 {
@@ -1959,6 +1968,9 @@ get_connect_value (char *line, struct GNUNET_TESTING_NetjailNode *node)
1959 GNUNET_CONTAINER_DLL_insert (node_connection->address_prefixes_head, 1968 GNUNET_CONTAINER_DLL_insert (node_connection->address_prefixes_head,
1960 node_connection->address_prefixes_tail, 1969 node_connection->address_prefixes_tail,
1961 prefix); 1970 prefix);
1971 LOG (GNUNET_ERROR_TYPE_ERROR,
1972 "address_prefix %s\n",
1973 prefix->address_prefix);
1962 } 1974 }
1963 1975
1964 GNUNET_free (copy); 1976 GNUNET_free (copy);
@@ -2003,6 +2015,250 @@ node_connections (char *line, struct GNUNET_TESTING_NetjailNode *node)
2003} 2015}
2004 2016
2005 2017
2018static int
2019log_nodes (void *cls, const struct GNUNET_ShortHashCode *id, void *value)
2020{
2021 struct GNUNET_TESTING_NetjailNode *node = value;
2022 struct GNUNET_TESTING_NodeConnection *pos_connection;
2023 struct GNUNET_TESTING_AddressPrefix *pos_prefix;
2024
2025 LOG (GNUNET_ERROR_TYPE_ERROR,
2026 "plugin: %s space: %u node: %u global: %u\n",
2027 node->plugin,
2028 node->namespace_n,
2029 node->node_n,
2030 node->is_global);
2031
2032 for (pos_connection = node->node_connections_head; NULL != pos_connection;
2033 pos_connection = pos_connection->next)
2034 {
2035
2036 LOG (GNUNET_ERROR_TYPE_ERROR,
2037 "namespace_n: %u node_n: %u node_type: %u\n",
2038 pos_connection->namespace_n,
2039 pos_connection->node_n,
2040 pos_connection->node_type);
2041
2042 for (pos_prefix = pos_connection->address_prefixes_head; NULL != pos_prefix;
2043 pos_prefix =
2044 pos_prefix->next)
2045 {
2046 LOG (GNUNET_ERROR_TYPE_ERROR,
2047 "prefix: %s\n",
2048 pos_prefix->address_prefix);
2049 }
2050 }
2051 return GNUNET_YES;
2052}
2053
2054
2055static int
2056log_namespaces (void *cls, const struct GNUNET_ShortHashCode *id, void *value)
2057{
2058 struct GNUNET_TESTING_NetjailNamespace *namespace = value;
2059 struct GNUNET_TESTING_NetjailRouter *router = namespace->router;
2060
2061 LOG (GNUNET_ERROR_TYPE_ERROR,
2062 "router_tcp: %u router_udp: %u spaces: %u\n",
2063 router->tcp_port,
2064 router->udp_port,
2065 namespace->namespace_n);
2066 GNUNET_CONTAINER_multishortmap_iterate (namespace->nodes, &log_nodes, NULL);
2067 return GNUNET_YES;
2068}
2069
2070
2071static int
2072log_topo (struct GNUNET_TESTING_NetjailTopology *topology)
2073{
2074 LOG (GNUNET_ERROR_TYPE_ERROR,
2075 "plugin: %s spaces: %u nodes: %u known: %u\n",
2076 topology->plugin,
2077 topology->namespaces_n,
2078 topology->nodes_m,
2079 topology->nodes_x);
2080
2081 GNUNET_CONTAINER_multishortmap_iterate (topology->map_namespaces,
2082 log_namespaces, NULL);
2083 GNUNET_CONTAINER_multishortmap_iterate (topology->map_globals, &log_nodes,
2084 NULL);
2085 return GNUNET_YES;
2086}
2087
2088
2089/**
2090 * Get the connections to other nodes for a specific node.
2091 *
2092 * @param num The specific node we want the connections for.
2093 * @param topology The topology we get the connections from.
2094 * @return The connections of the node.
2095 */
2096struct GNUNET_TESTING_NodeConnection *
2097GNUNET_TESTING_get_connections (unsigned int num, struct
2098 GNUNET_TESTING_NetjailTopology *topology)
2099{
2100 struct GNUNET_TESTING_NetjailNode *node;
2101 struct GNUNET_ShortHashCode *hkey;
2102 struct GNUNET_HashCode hc;
2103 struct GNUNET_TESTING_NetjailNamespace *namespace;
2104 unsigned int namespace_n, node_m;
2105
2106 log_topo (topology);
2107
2108 hkey = GNUNET_new (struct GNUNET_ShortHashCode);
2109 if (topology->nodes_x >= num)
2110 {
2111
2112 GNUNET_CRYPTO_hash (&num, sizeof(num), &hc);
2113 memcpy (hkey,
2114 &hc,
2115 sizeof (*hkey));
2116 node = GNUNET_CONTAINER_multishortmap_get (topology->map_globals,
2117 hkey);
2118 }
2119 else
2120 {
2121 namespace_n = (unsigned int) floor ((num - topology->nodes_x)
2122 / topology->nodes_m);
2123 LOG (GNUNET_ERROR_TYPE_ERROR,
2124 "num: %u nodes_x: %u nodes_m: %u namespace_n: %u\n",
2125 num,
2126 topology->nodes_x,
2127 topology->nodes_m,
2128 namespace_n);
2129 hkey = GNUNET_new (struct GNUNET_ShortHashCode);
2130 GNUNET_CRYPTO_hash (&namespace_n, sizeof(namespace_n), &hc);
2131 memcpy (hkey,
2132 &hc,
2133 sizeof (*hkey));
2134 namespace = GNUNET_CONTAINER_multishortmap_get (topology->map_namespaces,
2135 hkey);
2136 node_m = num - topology->nodes_x - topology->nodes_m * (namespace_n - 1);
2137 hkey = GNUNET_new (struct GNUNET_ShortHashCode);
2138 GNUNET_CRYPTO_hash (&node_m, sizeof(node_m), &hc);
2139 memcpy (hkey,
2140 &hc,
2141 sizeof (*hkey));
2142 node = GNUNET_CONTAINER_multishortmap_get (namespace->nodes,
2143 hkey);
2144 }
2145
2146
2147 return node->node_connections_head;
2148}
2149
2150
2151/**
2152 * Retrieve the public key from the test system with the unique node id.
2153 *
2154 * @param num The unique node id.
2155 * @param tl_system The test system.
2156 * @return The peer identity wrapping the public key.
2157 */
2158struct GNUNET_PeerIdentity *
2159GNUNET_TESTING_get_pub_key (unsigned int num, struct
2160 GNUNET_TESTING_System *tl_system)
2161{
2162 struct GNUNET_PeerIdentity *peer = GNUNET_new (struct GNUNET_PeerIdentity);
2163 struct GNUNET_CRYPTO_EddsaPublicKey *pub_key = GNUNET_new (struct
2164 GNUNET_CRYPTO_EddsaPublicKey);
2165 struct GNUNET_CRYPTO_EddsaPrivateKey *priv_key = GNUNET_new (struct
2166 GNUNET_CRYPTO_EddsaPrivateKey);
2167
2168 priv_key = GNUNET_TESTING_hostkey_get (tl_system,
2169 num,
2170 peer);
2171
2172 GNUNET_CRYPTO_eddsa_key_get_public (priv_key,
2173 pub_key);
2174 peer->public_key = *pub_key;
2175 return peer;
2176}
2177
2178
2179/**
2180 * Calculate the unique id identifying a node from a given connction.
2181 *
2182 * @param node_connection The connection we calculate the id from.
2183 * @param topology The topology we get all needed information from.
2184 * @return The unique id of the node from the connection.
2185 */
2186unsigned int
2187GNUNET_TESTING_calculate_num (struct
2188 GNUNET_TESTING_NodeConnection *node_connection,
2189 struct GNUNET_TESTING_NetjailTopology *topology)
2190{
2191 unsigned int n, m, num;
2192
2193 n = node_connection->namespace_n;
2194 m = node_connection->node_n;
2195
2196 if (0 == n)
2197 num = m;
2198 else
2199 num = (n - 1) * topology->nodes_m + m + topology->nodes_x;
2200
2201 return num;
2202}
2203
2204
2205/**
2206 * Get the address for a specific communicator from a connection.
2207 *
2208 * @param connection The connection we like to have the address from.
2209 * @param prefix The communicator protocol prefix.
2210 * @return The address of the communicator.
2211 */
2212char *
2213GNUNET_TESTING_get_address (struct GNUNET_TESTING_NodeConnection *connection,
2214 char *prefix)
2215{
2216 struct GNUNET_TESTING_NetjailNode *node;
2217 char *addr;
2218 char *template;
2219
2220 LOG (GNUNET_ERROR_TYPE_ERROR,
2221 "node_n: %u\n",
2222 connection->node_n);
2223
2224 node = connection->node;
2225 if (connection->namespace_n == node->namespace_n)
2226 {
2227 template = CONNECT_ADDRESS_TEMPLATE;
2228 }
2229 else if (0 == connection->namespace_n)
2230 {
2231 template = KNOWN_CONNECT_ADDRESS_TEMPLATE;
2232 }
2233 else
2234 {
2235 template = ROUTER_CONNECT_ADDRESS_TEMPLATE;
2236 }
2237
2238 if (0 == strcmp (PREFIX_TCP, prefix))
2239 {
2240
2241 GNUNET_asprintf (&addr,
2242 template,
2243 prefix,
2244 connection->node_n);
2245 }
2246 else if (0 == strcmp (PREFIX_UDP, prefix))
2247 {
2248 GNUNET_asprintf (&addr,
2249 template,
2250 prefix,
2251 connection->node_n);
2252 }
2253 else
2254 {
2255 GNUNET_break (0);
2256 }
2257
2258 return addr;
2259}
2260
2261
2006/** 2262/**
2007 * Create a GNUNET_CMDS_LOCAL_FINISHED message. 2263 * Create a GNUNET_CMDS_LOCAL_FINISHED message.
2008 * 2264 *
diff --git a/src/testing/testing_api_cmd_local_test_prepared.c b/src/testing/testing_api_cmd_local_test_prepared.c
new file mode 100644
index 000000000..4e915c7c0
--- /dev/null
+++ b/src/testing/testing_api_cmd_local_test_prepared.c
@@ -0,0 +1,168 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2021 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file testing_api_cmd_local_test_prepared.c
23 * @brief cmd to block the interpreter loop until all peers started.
24 * @author t3sserakt
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testing_ng_lib.h"
29#include "testing_cmds.h"
30
31/**
32 * Generic logging shortcut
33 */
34#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
35
36
37/**
38 * Struct to hold information for callbacks.
39 *
40 */
41struct LocalPreparedState
42{
43 /**
44 * Callback to write messages to the master loop.
45 *
46 */
47 TESTING_CMD_HELPER_write_cb write_message;
48
49 /**
50 * The message send back to the master loop.
51 *
52 */
53 struct GNUNET_CMDS_LOCAL_TEST_PREPARED *reply;
54
55 /**
56 * Flag indicating if all local tests finished.
57 */
58 unsigned int *all_local_tests_prepared;
59};
60
61
62/**
63 * Trait function of this cmd does nothing.
64 *
65 */
66static int
67local_test_prepared_traits (void *cls,
68 const void **ret,
69 const char *trait,
70 unsigned int index)
71{
72 return GNUNET_OK;
73}
74
75
76/**
77 * The cleanup function of this cmd frees resources the cmd allocated.
78 *
79 */
80static void
81local_test_prepared_cleanup (void *cls,
82 const struct GNUNET_TESTING_Command *cmd)
83{
84 struct LocalPreparedState *lfs = cls;
85
86 GNUNET_free (lfs->reply);
87 GNUNET_free (lfs);
88}
89
90
91/**
92 * This function sends a GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TESTS_PREPARED message to the master loop.
93 *
94 */
95static void
96local_test_prepared_run (void *cls,
97 const struct GNUNET_TESTING_Command *cmd,
98 struct GNUNET_TESTING_Interpreter *is)
99{
100 struct LocalPreparedState *lfs = cls;
101
102 struct GNUNET_CMDS_LOCAL_TEST_PREPARED *reply;
103 size_t msg_length;
104
105 msg_length = sizeof(struct GNUNET_CMDS_LOCAL_TEST_PREPARED);
106 reply = GNUNET_new (struct GNUNET_CMDS_LOCAL_TEST_PREPARED);
107 reply->header.type = htons (
108 GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TEST_PREPARED);
109 reply->header.size = htons ((uint16_t) msg_length);
110 lfs->reply = reply;
111 lfs->write_message ((struct GNUNET_MessageHeader *) reply, msg_length);
112}
113
114
115/**
116 * This finish function will stop the local loop without shutting down the scheduler, because we do not call the continuation, which is the interpreter_next method.
117 *
118 */
119static int
120local_test_prepared_finish (void *cls,
121 GNUNET_SCHEDULER_TaskCallback cont,
122 void *cont_cls)
123{
124 struct LocalPreparedState *lfs = cls;
125 unsigned int *ret = lfs->all_local_tests_prepared;
126
127 if (GNUNET_YES == *ret)
128 {
129 cont (cont_cls);
130 }
131
132 return *ret;
133
134}
135
136
137/**
138 * Create command.
139 *
140 * @param label name for command.
141 * @param write_message Callback to write messages to the master loop.
142 * @param all_local_tests_prepared Flag which will be set from outside.
143 * @return command.
144 */
145struct GNUNET_TESTING_Command
146GNUNET_TESTING_cmd_local_test_prepared (const char *label,
147 TESTING_CMD_HELPER_write_cb
148 write_message,
149 unsigned int *
150 all_local_tests_prepared)
151{
152 struct LocalPreparedState *lfs;
153
154 lfs = GNUNET_new (struct LocalPreparedState);
155 lfs->write_message = write_message;
156 lfs->all_local_tests_prepared = all_local_tests_prepared;
157
158 struct GNUNET_TESTING_Command cmd = {
159 .cls = lfs,
160 .label = label,
161 .run = &local_test_prepared_run,
162 .finish = &local_test_prepared_finish,
163 .cleanup = &local_test_prepared_cleanup,
164 .traits = &local_test_prepared_traits
165 };
166
167 return cmd;
168}
diff --git a/src/testing/testing_cmds.h b/src/testing/testing_cmds.h
index 09e4f2dcb..12db87d19 100644
--- a/src/testing/testing_cmds.h
+++ b/src/testing/testing_cmds.h
@@ -87,6 +87,23 @@ struct GNUNET_CMDS_LOCAL_FINISHED
87 enum GNUNET_GenericReturnValue result; 87 enum GNUNET_GenericReturnValue result;
88}; 88};
89 89
90struct GNUNET_CMDS_LOCAL_TEST_PREPARED
91{
92 /**
93 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TEST_PREPARED
94 */
95 struct GNUNET_MessageHeader header;
96};
97
98struct GNUNET_CMDS_ALL_LOCAL_TESTS_PREPARED
99{
100 /**
101 * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_LOCAL_TESTS_PREPARED
102 */
103 struct GNUNET_MessageHeader header;
104};
105
90GNUNET_NETWORK_STRUCT_END 106GNUNET_NETWORK_STRUCT_END
107
91#endif 108#endif
92/* end of testing_cmds.h */ 109/* end of testing_cmds.h */
diff --git a/src/testing/topo.sh b/src/testing/topo.sh
index 090c3053f..0046622b6 100755
--- a/src/testing/topo.sh
+++ b/src/testing/topo.sh
@@ -20,8 +20,7 @@ extract_attributes()
20 number=$(echo $line|cut -d \| -f 1| cut -c 2-|cut -d : -f 2 ) 20 number=$(echo $line|cut -d \| -f 1| cut -c 2-|cut -d : -f 2 )
21 echo $number 21 echo $number
22 fi 22 fi
23 23
24
25 nf=$(echo $line|awk -F: '{print NF}') 24 nf=$(echo $line|awk -F: '{print NF}')
26 for ((i=2;i<=$nf;i++)) 25 for ((i=2;i<=$nf;i++))
27 do 26 do
@@ -67,6 +66,11 @@ while read line; do
67 then 66 then
68 GLOBAL_N=$(cut -d : -f 2 <<< $line) 67 GLOBAL_N=$(cut -d : -f 2 <<< $line)
69 echo $GLOBAL_N 68 echo $GLOBAL_N
69 for ((i=1;i<=$GLOBAL_N;i++))
70 do
71 R_TCP[$i]=0
72 R_UDP[$i]=0
73 done
70 elif [ "$key" = "X" ] 74 elif [ "$key" = "X" ]
71 then 75 then
72 KNOWN=$(cut -d : -f 2 <<< $line) 76 KNOWN=$(cut -d : -f 2 <<< $line)