diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-10-07 11:31:37 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-10-07 11:31:37 +0000 |
commit | 0ecd945a968543984a5757b938f5ff872c1c2da3 (patch) | |
tree | 07691c15ab4fb20d138350cc66f57055ee49992e /src/nat | |
parent | 6c83690184e6f258e61d8187ad5999f4f87f2e49 (diff) | |
download | gnunet-0ecd945a968543984a5757b938f5ff872c1c2da3.tar.gz gnunet-0ecd945a968543984a5757b938f5ff872c1c2da3.zip |
-fix testcase to handle SUCCESS status reply, only recv UDP after STUN Request is out, etc.
Diffstat (limited to 'src/nat')
-rw-r--r-- | src/nat/test_stun.c | 239 |
1 files changed, 124 insertions, 115 deletions
diff --git a/src/nat/test_stun.c b/src/nat/test_stun.c index 5045b1cac..5855addd7 100644 --- a/src/nat/test_stun.c +++ b/src/nat/test_stun.c | |||
@@ -24,8 +24,7 @@ | |||
24 | * @file nat/test_stun.c | 24 | * @file nat/test_stun.c |
25 | * @brief Testcase for STUN library | 25 | * @brief Testcase for STUN library |
26 | * @author Bruno Souza Cabral | 26 | * @author Bruno Souza Cabral |
27 | 27 | * @author Christian Grothoff | |
28 | * | ||
29 | */ | 28 | */ |
30 | 29 | ||
31 | 30 | ||
@@ -49,9 +48,11 @@ | |||
49 | * The port the test service is running on (default 7895) | 48 | * The port the test service is running on (default 7895) |
50 | */ | 49 | */ |
51 | static unsigned long port = 7895; | 50 | static unsigned long port = 7895; |
51 | |||
52 | static int ret = 1; | 52 | static int ret = 1; |
53 | 53 | ||
54 | static char *stun_server = "stun.ekiga.net"; | 54 | static const char *stun_server = "stun.gnunet.org"; |
55 | |||
55 | static int stun_port = 3478; | 56 | static int stun_port = 3478; |
56 | 57 | ||
57 | /** | 58 | /** |
@@ -59,45 +60,50 @@ static int stun_port = 3478; | |||
59 | */ | 60 | */ |
60 | static struct GNUNET_NETWORK_Handle *lsock4; | 61 | static struct GNUNET_NETWORK_Handle *lsock4; |
61 | 62 | ||
62 | |||
63 | /** | 63 | /** |
64 | * The listen task ID for IPv4 | 64 | * The listen task ID for IPv4 |
65 | */ | 65 | */ |
66 | static struct GNUNET_SCHEDULER_Task * ltask4; | 66 | static struct GNUNET_SCHEDULER_Task *ltask4; |
67 | |||
68 | 67 | ||
68 | /** | ||
69 | * Handle for the STUN request. | ||
70 | */ | ||
71 | static struct GNUNET_NAT_STUN_Handle *rh; | ||
69 | 72 | ||
70 | 73 | ||
71 | static void | 74 | static void |
72 | print_answer(struct sockaddr_in* answer) | 75 | print_answer(struct sockaddr_in* answer) |
73 | { | 76 | { |
74 | GNUNET_log (GNUNET_ERROR_TYPE_INFO,"External IP is: %s , with port %d\n", inet_ntoa(answer->sin_addr), ntohs(answer->sin_port)); | 77 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
78 | "External IP is: %s , with port %d\n", | ||
79 | inet_ntoa (answer->sin_addr), | ||
80 | ntohs (answer->sin_port)); | ||
75 | } | 81 | } |
76 | 82 | ||
77 | 83 | ||
78 | |||
79 | /** | 84 | /** |
80 | * Function that terminates the test. | 85 | * Function that terminates the test. |
81 | */ | 86 | */ |
82 | static void | 87 | static void |
83 | stop () | 88 | stop () |
84 | { | 89 | { |
85 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping NAT and quitting...\n"); | 90 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
86 | 91 | "Stopping NAT and quitting...\n"); | |
87 | //Clean task | 92 | if (NULL != ltask4) |
88 | if(NULL != ltask4) | ||
89 | { | 93 | { |
90 | GNUNET_SCHEDULER_cancel (ltask4); | 94 | GNUNET_SCHEDULER_cancel (ltask4); |
91 | ltask4 = NULL; | 95 | ltask4 = NULL; |
92 | } | 96 | } |
93 | |||
94 | //Clean socket | ||
95 | if(NULL != lsock4) | 97 | if(NULL != lsock4) |
96 | { | 98 | { |
97 | GNUNET_NETWORK_socket_close(lsock4); | 99 | GNUNET_NETWORK_socket_close(lsock4); |
98 | lsock4 = NULL; | 100 | lsock4 = NULL; |
99 | } | 101 | } |
100 | 102 | if (NULL != rh) | |
103 | { | ||
104 | GNUNET_NAT_stun_make_request_cancel (rh); | ||
105 | rh = NULL; | ||
106 | } | ||
101 | } | 107 | } |
102 | 108 | ||
103 | 109 | ||
@@ -112,48 +118,41 @@ static void | |||
112 | do_udp_read (void *cls, | 118 | do_udp_read (void *cls, |
113 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 119 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
114 | { | 120 | { |
115 | //struct GNUNET_NAT_Test *tst = cls; | 121 | //struct GNUNET_NAT_Test *tst = cls; |
116 | unsigned char reply_buf[1024]; | 122 | unsigned char reply_buf[1024]; |
117 | ssize_t rlen; | 123 | ssize_t rlen; |
118 | struct sockaddr_in answer; | 124 | struct sockaddr_in answer; |
119 | 125 | ||
120 | if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) && | 126 | ltask4 = NULL; |
121 | (GNUNET_NETWORK_fdset_isset (tc->read_ready, | 127 | if ( (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) || |
122 | lsock4))) | 128 | (! GNUNET_NETWORK_fdset_isset (tc->read_ready, |
123 | { | 129 | lsock4)) ) |
124 | rlen = GNUNET_NETWORK_socket_recv (lsock4, reply_buf, sizeof (reply_buf)); | ||
125 | |||
126 | |||
127 | //Lets handle the packet | ||
128 | memset(&answer, 0, sizeof(struct sockaddr_in)); | ||
129 | |||
130 | if(GNUNET_OK == GNUNET_NAT_stun_handle_packet(reply_buf, rlen, &answer)) | ||
131 | { | ||
132 | //Print the answer | ||
133 | ret = 0; | ||
134 | print_answer(&answer); | ||
135 | |||
136 | //Destroy the connection | ||
137 | GNUNET_NETWORK_socket_close(lsock4); | ||
138 | lsock4 = NULL; | ||
139 | |||
140 | } | ||
141 | else | ||
142 | { | ||
143 | //Lets try again, its a invalid message | ||
144 | ltask4 = GNUNET_SCHEDULER_add_read_net (TIMEOUT, | ||
145 | lsock4, &do_udp_read, NULL); | ||
146 | } | ||
147 | |||
148 | } | ||
149 | else | ||
150 | { | 130 | { |
151 | //We got a timeout | 131 | fprintf (stderr, |
152 | ltask4 = NULL; | 132 | "Timeout waiting for STUN response\n"); |
153 | stop(); | 133 | stop(); |
154 | } | 134 | } |
155 | 135 | rlen = GNUNET_NETWORK_socket_recv (lsock4, | |
156 | ltask4 = NULL; | 136 | reply_buf, |
137 | sizeof (reply_buf)); | ||
138 | memset (&answer, | ||
139 | 0, | ||
140 | sizeof(struct sockaddr_in)); | ||
141 | if (GNUNET_OK != | ||
142 | GNUNET_NAT_stun_handle_packet (reply_buf, | ||
143 | rlen, | ||
144 | &answer)) | ||
145 | { | ||
146 | fprintf (stderr, | ||
147 | "Unexpected UDP packet, trying to read more\n"); | ||
148 | ltask4 = GNUNET_SCHEDULER_add_read_net (TIMEOUT, | ||
149 | lsock4, | ||
150 | &do_udp_read, NULL); | ||
151 | return; | ||
152 | } | ||
153 | ret = 0; | ||
154 | print_answer (&answer); | ||
155 | stop (); | ||
157 | } | 156 | } |
158 | 157 | ||
159 | 158 | ||
@@ -165,87 +164,96 @@ do_udp_read (void *cls, | |||
165 | static struct GNUNET_NETWORK_Handle * | 164 | static struct GNUNET_NETWORK_Handle * |
166 | bind_v4 () | 165 | bind_v4 () |
167 | { | 166 | { |
168 | struct GNUNET_NETWORK_Handle *ls; | 167 | struct GNUNET_NETWORK_Handle *ls; |
169 | struct sockaddr_in sa4; | 168 | struct sockaddr_in sa4; |
170 | int eno; | 169 | int eno; |
171 | 170 | ||
172 | memset (&sa4, 0, sizeof (sa4)); | 171 | memset (&sa4, 0, sizeof (sa4)); |
173 | sa4.sin_family = AF_INET; | 172 | sa4.sin_family = AF_INET; |
174 | sa4.sin_port = htons (port); | 173 | sa4.sin_port = htons (port); |
175 | #if HAVE_SOCKADDR_IN_SIN_LEN | 174 | #if HAVE_SOCKADDR_IN_SIN_LEN |
176 | sa4.sin_len = sizeof (sa4); | 175 | sa4.sin_len = sizeof (sa4); |
177 | #endif | 176 | #endif |
178 | ls = GNUNET_NETWORK_socket_create (AF_INET, | 177 | ls = GNUNET_NETWORK_socket_create (AF_INET, |
179 | SOCK_DGRAM, | 178 | SOCK_DGRAM, |
180 | 0); | 179 | 0); |
181 | if (NULL == ls) | 180 | if (NULL == ls) |
182 | return NULL; | 181 | return NULL; |
183 | if (GNUNET_OK != | 182 | if (GNUNET_OK != |
184 | GNUNET_NETWORK_socket_bind (ls, (const struct sockaddr *) &sa4, | 183 | GNUNET_NETWORK_socket_bind (ls, |
185 | sizeof (sa4))) | 184 | (const struct sockaddr *) &sa4, |
186 | { | 185 | sizeof (sa4))) |
187 | eno = errno; | 186 | { |
188 | GNUNET_NETWORK_socket_close (ls); | 187 | eno = errno; |
189 | errno = eno; | 188 | GNUNET_NETWORK_socket_close (ls); |
190 | return NULL; | 189 | errno = eno; |
191 | } | 190 | return NULL; |
192 | return ls; | 191 | } |
192 | return ls; | ||
193 | } | 193 | } |
194 | 194 | ||
195 | 195 | ||
196 | 196 | /** | |
197 | static void request_callback(void *cls, | 197 | * Function called with the result of the STUN request transmission attempt. |
198 | enum GNUNET_NAT_StatusCode error) | 198 | * |
199 | * @param cls unused | ||
200 | * @param error status code from STUN | ||
201 | */ | ||
202 | static void | ||
203 | request_callback (void *cls, | ||
204 | enum GNUNET_NAT_StatusCode error) | ||
199 | { | 205 | { |
200 | if(error == GNUNET_NAT_ERROR_NOT_ONLINE) | 206 | rh = NULL; |
207 | if (GNUNET_NAT_ERROR_SUCCESS == error) | ||
201 | { | 208 | { |
202 | //If we are not online, mark the test as success | 209 | /* all good, start to receive */ |
203 | ret = 0; | 210 | ltask4 = GNUNET_SCHEDULER_add_read_net (TIMEOUT, |
204 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 211 | lsock4, |
205 | "test-stun detected as offline, cant make STUN request.\n" | 212 | &do_udp_read, |
206 | ); | 213 | NULL); |
214 | return; | ||
215 | } | ||
216 | if (error == GNUNET_NAT_ERROR_NOT_ONLINE) | ||
217 | { | ||
218 | ret = 77; /* report 'skip' */ | ||
219 | fprintf (stderr, | ||
220 | "System is offline, cannot test STUN request.\n"); | ||
207 | } | 221 | } |
208 | else | 222 | else |
209 | { | 223 | { |
210 | ret = error; | 224 | ret = error; |
211 | } | 225 | } |
212 | stop(); | 226 | stop(); |
213 | }; | 227 | } |
214 | 228 | ||
215 | 229 | ||
216 | /** | 230 | /** |
217 | * Main function run with scheduler. | 231 | * Main function run with scheduler. |
218 | */ | 232 | */ |
219 | static void | 233 | static void |
220 | run (void *cls, char *const *args, const char *cfgfile, | 234 | run (void *cls, |
235 | char *const *args, | ||
236 | const char *cfgfile, | ||
221 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 237 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
222 | { | 238 | { |
223 | |||
224 | //Lets create the socket | 239 | //Lets create the socket |
225 | lsock4 = bind_v4 (); | 240 | lsock4 = bind_v4 (); |
226 | ltask4 = NULL; | ||
227 | if (NULL == lsock4) | 241 | if (NULL == lsock4) |
228 | { | 242 | { |
229 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind"); | 243 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, |
230 | GNUNET_SCHEDULER_shutdown (); | 244 | "bind"); |
231 | return; | 245 | GNUNET_SCHEDULER_shutdown (); |
232 | } | 246 | return; |
233 | else | ||
234 | { | ||
235 | //Lets call our function now when it accepts | ||
236 | ltask4 = GNUNET_SCHEDULER_add_read_net (TIMEOUT, | ||
237 | lsock4, &do_udp_read, NULL ); | ||
238 | |||
239 | } | 247 | } |
240 | |||
241 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 248 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
242 | "Service listens on port %u\n", | 249 | "Service listens on port %u\n", |
243 | port); | 250 | port); |
244 | GNUNET_NAT_stun_make_request (stun_server, stun_port, lsock4, | 251 | rh = GNUNET_NAT_stun_make_request (stun_server, |
245 | &request_callback, NULL); | 252 | stun_port, |
246 | 253 | lsock4, | |
247 | GNUNET_SCHEDULER_add_delayed (TIMEOUT, &stop, NULL); | 254 | &request_callback, NULL); |
248 | 255 | GNUNET_SCHEDULER_add_delayed (TIMEOUT, | |
256 | &stop, NULL); | ||
249 | } | 257 | } |
250 | 258 | ||
251 | 259 | ||
@@ -255,21 +263,20 @@ main (int argc, char *const argv[]) | |||
255 | struct GNUNET_GETOPT_CommandLineOption options[] = { | 263 | struct GNUNET_GETOPT_CommandLineOption options[] = { |
256 | GNUNET_GETOPT_OPTION_END | 264 | GNUNET_GETOPT_OPTION_END |
257 | }; | 265 | }; |
258 | |||
259 | char *const argv_prog[] = { | 266 | char *const argv_prog[] = { |
260 | "test-stun", | 267 | "test-stun", |
261 | "-c", | 268 | "-c", |
262 | "test_stun.conf", | 269 | "test_stun.conf", |
263 | NULL | 270 | NULL |
264 | }; | 271 | }; |
272 | char *fn; | ||
273 | struct GNUNET_OS_Process *proc; | ||
274 | |||
265 | GNUNET_log_setup ("test-stun", | 275 | GNUNET_log_setup ("test-stun", |
266 | "WARNING", | 276 | "WARNING", |
267 | NULL); | 277 | NULL); |
268 | 278 | ||
269 | /* Lets start resolver */ | 279 | /* Lets start resolver */ |
270 | char *fn; | ||
271 | struct GNUNET_OS_Process *proc; | ||
272 | |||
273 | fn = GNUNET_OS_get_libexec_binary_path ("gnunet-service-resolver"); | 280 | fn = GNUNET_OS_get_libexec_binary_path ("gnunet-service-resolver"); |
274 | proc = GNUNET_OS_start_process (GNUNET_YES, | 281 | proc = GNUNET_OS_start_process (GNUNET_YES, |
275 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, | 282 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, |
@@ -280,25 +287,27 @@ main (int argc, char *const argv[]) | |||
280 | 287 | ||
281 | if (NULL == proc) | 288 | if (NULL == proc) |
282 | { | 289 | { |
283 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "This test was unable to start gnunet-service-resolver, and it is required to run ...\n"); | 290 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
291 | "This test was unable to start gnunet-service-resolver, and it is required to run ...\n"); | ||
284 | exit(1); | 292 | exit(1); |
285 | } | 293 | } |
286 | 294 | ||
287 | GNUNET_PROGRAM_run (3, argv_prog, "test-stun", "nohelp", options, &run, NULL); | 295 | GNUNET_PROGRAM_run (3, argv_prog, |
288 | 296 | "test-stun", "nohelp", | |
297 | options, | ||
298 | &run, NULL); | ||
289 | 299 | ||
290 | /* Now kill the resolver */ | 300 | /* Now kill the resolver */ |
291 | if (0 != GNUNET_OS_process_kill (proc, GNUNET_TERM_SIG)) | 301 | if (0 != GNUNET_OS_process_kill (proc, GNUNET_TERM_SIG)) |
292 | { | 302 | { |
293 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); | 303 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); |
294 | } | 304 | } |
295 | GNUNET_OS_process_wait (proc); | 305 | GNUNET_OS_process_wait (proc); |
296 | GNUNET_OS_process_destroy (proc); | 306 | GNUNET_OS_process_destroy (proc); |
297 | proc = NULL; | 307 | proc = NULL; |
298 | GNUNET_free (fn); | 308 | GNUNET_free (fn); |
299 | 309 | ||
300 | 310 | return ret; | |
301 | return ret; | ||
302 | } | 311 | } |
303 | 312 | ||
304 | /* end of test_stun.c */ | 313 | /* end of test_stun.c */ |