aboutsummaryrefslogtreecommitdiff
path: root/src/nat/gnunet-service-nat_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nat/gnunet-service-nat_helper.c')
-rw-r--r--src/nat/gnunet-service-nat_helper.c359
1 files changed, 180 insertions, 179 deletions
diff --git a/src/nat/gnunet-service-nat_helper.c b/src/nat/gnunet-service-nat_helper.c
index 42612751d..58d7b4c61 100644
--- a/src/nat/gnunet-service-nat_helper.c
+++ b/src/nat/gnunet-service-nat_helper.c
@@ -32,7 +32,8 @@
32/** 32/**
33 * Information we keep per NAT helper process. 33 * Information we keep per NAT helper process.
34 */ 34 */
35struct HelperContext { 35struct HelperContext
36{
36 /** 37 /**
37 * IP address we pass to the NAT helper. 38 * IP address we pass to the NAT helper.
38 */ 39 */
@@ -87,7 +88,7 @@ struct HelperContext {
87 * @param cls a `struct HelperContext` 88 * @param cls a `struct HelperContext`
88 */ 89 */
89static void 90static void
90restart_nat_server(void *cls); 91restart_nat_server (void *cls);
91 92
92 93
93/** 94/**
@@ -96,13 +97,13 @@ restart_nat_server(void *cls);
96 * @param h context of the helper 97 * @param h context of the helper
97 */ 98 */
98static void 99static void
99try_again(struct HelperContext *h) 100try_again (struct HelperContext *h)
100{ 101{
101 GNUNET_assert(NULL == h->server_read_task); 102 GNUNET_assert (NULL == h->server_read_task);
102 h->server_retry_delay = GNUNET_TIME_STD_BACKOFF(h->server_retry_delay); 103 h->server_retry_delay = GNUNET_TIME_STD_BACKOFF (h->server_retry_delay);
103 h->server_read_task = GNUNET_SCHEDULER_add_delayed(h->server_retry_delay, 104 h->server_read_task = GNUNET_SCHEDULER_add_delayed (h->server_retry_delay,
104 &restart_nat_server, 105 &restart_nat_server,
105 h); 106 h);
106} 107}
107 108
108 109
@@ -114,7 +115,7 @@ try_again(struct HelperContext *h)
114 * @param cls the `struct HelperContext` 115 * @param cls the `struct HelperContext`
115 */ 116 */
116static void 117static void
117nat_server_read(void *cls) 118nat_server_read (void *cls)
118{ 119{
119 struct HelperContext *h = cls; 120 struct HelperContext *h = cls;
120 char mybuf[40]; 121 char mybuf[40];
@@ -124,73 +125,73 @@ nat_server_read(void *cls)
124 struct sockaddr_in sin_addr; 125 struct sockaddr_in sin_addr;
125 126
126 h->server_read_task = NULL; 127 h->server_read_task = NULL;
127 memset(mybuf, 0, sizeof(mybuf)); 128 memset (mybuf, 0, sizeof(mybuf));
128 bytes = 129 bytes =
129 GNUNET_DISK_file_read(h->server_stdout_handle, mybuf, sizeof(mybuf)); 130 GNUNET_DISK_file_read (h->server_stdout_handle, mybuf, sizeof(mybuf));
130 if (bytes < 1) 131 if (bytes < 1)
131 { 132 {
132 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 133 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
133 "Finished reading from server stdout with code: %d\n", 134 "Finished reading from server stdout with code: %d\n",
134 (int)bytes); 135 (int) bytes);
135 if (0 != GNUNET_OS_process_kill(h->server_proc, GNUNET_TERM_SIG)) 136 if (0 != GNUNET_OS_process_kill (h->server_proc, GNUNET_TERM_SIG))
136 GNUNET_log_from_strerror(GNUNET_ERROR_TYPE_WARNING, "nat", "kill"); 137 GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, "nat", "kill");
137 GNUNET_OS_process_wait(h->server_proc); 138 GNUNET_OS_process_wait (h->server_proc);
138 GNUNET_OS_process_destroy(h->server_proc); 139 GNUNET_OS_process_destroy (h->server_proc);
139 h->server_proc = NULL; 140 h->server_proc = NULL;
140 GNUNET_DISK_pipe_close(h->server_stdout); 141 GNUNET_DISK_pipe_close (h->server_stdout);
141 h->server_stdout = NULL; 142 h->server_stdout = NULL;
142 h->server_stdout_handle = NULL; 143 h->server_stdout_handle = NULL;
143 try_again(h); 144 try_again (h);
144 return; 145 return;
145 } 146 }
146 147
147 port_start = NULL; 148 port_start = NULL;
148 for (size_t i = 0; i < sizeof(mybuf); i++) 149 for (size_t i = 0; i < sizeof(mybuf); i++)
150 {
151 if (mybuf[i] == '\n')
149 { 152 {
150 if (mybuf[i] == '\n') 153 mybuf[i] = '\0';
151 { 154 break;
152 mybuf[i] = '\0';
153 break;
154 }
155 if ((mybuf[i] == ':') && (i + 1 < sizeof(mybuf)))
156 {
157 mybuf[i] = '\0';
158 port_start = &mybuf[i + 1];
159 }
160 } 155 }
156 if ((mybuf[i] == ':') && (i + 1 < sizeof(mybuf)))
157 {
158 mybuf[i] = '\0';
159 port_start = &mybuf[i + 1];
160 }
161 }
161 162
162 /* construct socket address of sender */ 163 /* construct socket address of sender */
163 memset(&sin_addr, 0, sizeof(sin_addr)); 164 memset (&sin_addr, 0, sizeof(sin_addr));
164 sin_addr.sin_family = AF_INET; 165 sin_addr.sin_family = AF_INET;
165#if HAVE_SOCKADDR_IN_SIN_LEN 166#if HAVE_SOCKADDR_IN_SIN_LEN
166 sin_addr.sin_len = sizeof(sin_addr); 167 sin_addr.sin_len = sizeof(sin_addr);
167#endif 168#endif
168 if ((NULL == port_start) || (1 != sscanf(port_start, "%d", &port)) || 169 if ((NULL == port_start) || (1 != sscanf (port_start, "%d", &port)) ||
169 (-1 == inet_pton(AF_INET, mybuf, &sin_addr.sin_addr))) 170 (-1 == inet_pton (AF_INET, mybuf, &sin_addr.sin_addr)))
170 { 171 {
171 /* should we restart gnunet-helper-nat-server? */ 172 /* should we restart gnunet-helper-nat-server? */
172 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 173 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
173 _( 174 _ (
174 "gnunet-helper-nat-server generated malformed address `%s'\n"), 175 "gnunet-helper-nat-server generated malformed address `%s'\n"),
175 mybuf); 176 mybuf);
176 h->server_read_task = 177 h->server_read_task =
177 GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_UNIT_FOREVER_REL, 178 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
178 h->server_stdout_handle, 179 h->server_stdout_handle,
179 &nat_server_read, 180 &nat_server_read,
180 h); 181 h);
181 return; 182 return;
182 } 183 }
183 sin_addr.sin_port = htons((uint16_t)port); 184 sin_addr.sin_port = htons ((uint16_t) port);
184 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 185 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
185 "gnunet-helper-nat-server read: %s:%d\n", 186 "gnunet-helper-nat-server read: %s:%d\n",
186 mybuf, 187 mybuf,
187 port); 188 port);
188 h->cb(h->cb_cls, &sin_addr); 189 h->cb (h->cb_cls, &sin_addr);
189 h->server_read_task = 190 h->server_read_task =
190 GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_UNIT_FOREVER_REL, 191 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
191 h->server_stdout_handle, 192 h->server_stdout_handle,
192 &nat_server_read, 193 &nat_server_read,
193 h); 194 h);
194} 195}
195 196
196 197
@@ -201,67 +202,67 @@ nat_server_read(void *cls)
201 * @param cls a `struct HelperContext` 202 * @param cls a `struct HelperContext`
202 */ 203 */
203static void 204static void
204restart_nat_server(void *cls) 205restart_nat_server (void *cls)
205{ 206{
206 struct HelperContext *h = cls; 207 struct HelperContext *h = cls;
207 char *binary; 208 char *binary;
208 char ia[INET_ADDRSTRLEN]; 209 char ia[INET_ADDRSTRLEN];
209 210
210 h->server_read_task = NULL; 211 h->server_read_task = NULL;
211 GNUNET_assert(NULL != 212 GNUNET_assert (NULL !=
212 inet_ntop(AF_INET, &h->internal_address, ia, sizeof(ia))); 213 inet_ntop (AF_INET, &h->internal_address, ia, sizeof(ia)));
213 /* Start the server process */ 214 /* Start the server process */
214 binary = GNUNET_OS_get_suid_binary_path(h->cfg, "gnunet-helper-nat-server"); 215 binary = GNUNET_OS_get_suid_binary_path (h->cfg, "gnunet-helper-nat-server");
215 if (GNUNET_YES != GNUNET_OS_check_helper_binary(binary, GNUNET_YES, ia)) 216 if (GNUNET_YES != GNUNET_OS_check_helper_binary (binary, GNUNET_YES, ia))
216 { 217 {
217 /* move instantly to max delay, as this is unlikely to be fixed */ 218 /* move instantly to max delay, as this is unlikely to be fixed */
218 h->server_retry_delay = GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD; 219 h->server_retry_delay = GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD;
219 GNUNET_free(binary); 220 GNUNET_free (binary);
220 try_again(h); 221 try_again (h);
221 return; 222 return;
222 } 223 }
223 h->server_stdout = 224 h->server_stdout =
224 GNUNET_DISK_pipe(GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES); 225 GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES);
225 if (NULL == h->server_stdout) 226 if (NULL == h->server_stdout)
226 { 227 {
227 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "pipe"); 228 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "pipe");
228 GNUNET_free(binary); 229 GNUNET_free (binary);
229 try_again(h); 230 try_again (h);
230 return; 231 return;
231 } 232 }
232 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 233 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
233 "Starting `%s' at `%s'\n", 234 "Starting `%s' at `%s'\n",
234 "gnunet-helper-nat-server", 235 "gnunet-helper-nat-server",
235 ia); 236 ia);
236 h->server_proc = GNUNET_OS_start_process(GNUNET_NO, 237 h->server_proc = GNUNET_OS_start_process (GNUNET_NO,
237 0, 238 0,
238 NULL, 239 NULL,
239 h->server_stdout, 240 h->server_stdout,
240 NULL, 241 NULL,
241 binary, 242 binary,
242 "gnunet-helper-nat-server", 243 "gnunet-helper-nat-server",
243 ia, 244 ia,
244 NULL); 245 NULL);
245 GNUNET_free(binary); 246 GNUNET_free (binary);
246 if (NULL == h->server_proc) 247 if (NULL == h->server_proc)
247 { 248 {
248 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 249 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
249 _("Failed to start %s\n"), 250 _ ("Failed to start %s\n"),
250 "gnunet-helper-nat-server"); 251 "gnunet-helper-nat-server");
251 GNUNET_DISK_pipe_close(h->server_stdout); 252 GNUNET_DISK_pipe_close (h->server_stdout);
252 h->server_stdout = NULL; 253 h->server_stdout = NULL;
253 try_again(h); 254 try_again (h);
254 return; 255 return;
255 } 256 }
256 /* Close the write end of the read pipe */ 257 /* Close the write end of the read pipe */
257 GNUNET_DISK_pipe_close_end(h->server_stdout, GNUNET_DISK_PIPE_END_WRITE); 258 GNUNET_DISK_pipe_close_end (h->server_stdout, GNUNET_DISK_PIPE_END_WRITE);
258 h->server_stdout_handle = 259 h->server_stdout_handle =
259 GNUNET_DISK_pipe_handle(h->server_stdout, GNUNET_DISK_PIPE_END_READ); 260 GNUNET_DISK_pipe_handle (h->server_stdout, GNUNET_DISK_PIPE_END_READ);
260 h->server_read_task = 261 h->server_read_task =
261 GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_UNIT_FOREVER_REL, 262 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
262 h->server_stdout_handle, 263 h->server_stdout_handle,
263 &nat_server_read, 264 &nat_server_read,
264 h); 265 h);
265} 266}
266 267
267 268
@@ -276,24 +277,24 @@ restart_nat_server(void *cls)
276 * @return NULL on error 277 * @return NULL on error
277 */ 278 */
278struct HelperContext * 279struct HelperContext *
279GN_start_gnunet_nat_server_(const struct in_addr *internal_address, 280GN_start_gnunet_nat_server_ (const struct in_addr *internal_address,
280 GN_ReversalCallback cb, 281 GN_ReversalCallback cb,
281 void *cb_cls, 282 void *cb_cls,
282 const struct GNUNET_CONFIGURATION_Handle *cfg) 283 const struct GNUNET_CONFIGURATION_Handle *cfg)
283{ 284{
284 struct HelperContext *h; 285 struct HelperContext *h;
285 286
286 h = GNUNET_new(struct HelperContext); 287 h = GNUNET_new (struct HelperContext);
287 h->cb = cb; 288 h->cb = cb;
288 h->cb_cls = cb_cls; 289 h->cb_cls = cb_cls;
289 h->internal_address = *internal_address; 290 h->internal_address = *internal_address;
290 h->cfg = cfg; 291 h->cfg = cfg;
291 restart_nat_server(h); 292 restart_nat_server (h);
292 if (NULL == h->server_stdout) 293 if (NULL == h->server_stdout)
293 { 294 {
294 GN_stop_gnunet_nat_server_(h); 295 GN_stop_gnunet_nat_server_ (h);
295 return NULL; 296 return NULL;
296 } 297 }
297 return h; 298 return h;
298} 299}
299 300
@@ -305,31 +306,31 @@ GN_start_gnunet_nat_server_(const struct in_addr *internal_address,
305 * @param h helper context to stop 306 * @param h helper context to stop
306 */ 307 */
307void 308void
308GN_stop_gnunet_nat_server_(struct HelperContext *h) 309GN_stop_gnunet_nat_server_ (struct HelperContext *h)
309{ 310{
310 if (NULL != h->server_read_task) 311 if (NULL != h->server_read_task)
311 { 312 {
312 GNUNET_SCHEDULER_cancel(h->server_read_task); 313 GNUNET_SCHEDULER_cancel (h->server_read_task);
313 h->server_read_task = NULL; 314 h->server_read_task = NULL;
314 } 315 }
315 if (NULL != h->server_proc) 316 if (NULL != h->server_proc)
316 { 317 {
317 if (0 != GNUNET_OS_process_kill(h->server_proc, GNUNET_TERM_SIG)) 318 if (0 != GNUNET_OS_process_kill (h->server_proc, GNUNET_TERM_SIG))
318 GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "kill"); 319 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
319 GNUNET_OS_process_wait(h->server_proc); 320 GNUNET_OS_process_wait (h->server_proc);
320 GNUNET_OS_process_destroy(h->server_proc); 321 GNUNET_OS_process_destroy (h->server_proc);
321 h->server_proc = NULL; 322 h->server_proc = NULL;
322 GNUNET_DISK_pipe_close(h->server_stdout); 323 GNUNET_DISK_pipe_close (h->server_stdout);
323 h->server_stdout = NULL; 324 h->server_stdout = NULL;
324 h->server_stdout_handle = NULL; 325 h->server_stdout_handle = NULL;
325 } 326 }
326 if (NULL != h->server_stdout) 327 if (NULL != h->server_stdout)
327 { 328 {
328 GNUNET_DISK_pipe_close(h->server_stdout); 329 GNUNET_DISK_pipe_close (h->server_stdout);
329 h->server_stdout = NULL; 330 h->server_stdout = NULL;
330 h->server_stdout_handle = NULL; 331 h->server_stdout_handle = NULL;
331 } 332 }
332 GNUNET_free(h); 333 GNUNET_free (h);
333} 334}
334 335
335 336
@@ -346,10 +347,10 @@ GN_stop_gnunet_nat_server_(struct HelperContext *h)
346 * #GNUNET_OK otherwise 347 * #GNUNET_OK otherwise
347 */ 348 */
348int 349int
349GN_request_connection_reversal(const struct in_addr *internal_address, 350GN_request_connection_reversal (const struct in_addr *internal_address,
350 uint16_t internal_port, 351 uint16_t internal_port,
351 const struct in_addr *remote_v4, 352 const struct in_addr *remote_v4,
352 const struct GNUNET_CONFIGURATION_Handle *cfg) 353 const struct GNUNET_CONFIGURATION_Handle *cfg)
353{ 354{
354 char intv4[INET_ADDRSTRLEN]; 355 char intv4[INET_ADDRSTRLEN];
355 char remv4[INET_ADDRSTRLEN]; 356 char remv4[INET_ADDRSTRLEN];
@@ -357,44 +358,44 @@ GN_request_connection_reversal(const struct in_addr *internal_address,
357 struct GNUNET_OS_Process *proc; 358 struct GNUNET_OS_Process *proc;
358 char *binary; 359 char *binary;
359 360
360 if (NULL == inet_ntop(AF_INET, internal_address, intv4, INET_ADDRSTRLEN)) 361 if (NULL == inet_ntop (AF_INET, internal_address, intv4, INET_ADDRSTRLEN))
361 { 362 {
362 GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "inet_ntop"); 363 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop");
363 return GNUNET_SYSERR; 364 return GNUNET_SYSERR;
364 } 365 }
365 if (NULL == inet_ntop(AF_INET, remote_v4, remv4, INET_ADDRSTRLEN)) 366 if (NULL == inet_ntop (AF_INET, remote_v4, remv4, INET_ADDRSTRLEN))
366 { 367 {
367 GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "inet_ntop"); 368 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop");
368 return GNUNET_SYSERR; 369 return GNUNET_SYSERR;
369 } 370 }
370 GNUNET_snprintf(port_as_string, 371 GNUNET_snprintf (port_as_string,
371 sizeof(port_as_string), 372 sizeof(port_as_string),
372 "%d", 373 "%d",
373 internal_port); 374 internal_port);
374 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 375 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
375 "Running gnunet-helper-nat-client %s %s %u\n", 376 "Running gnunet-helper-nat-client %s %s %u\n",
376 intv4, 377 intv4,
377 remv4, 378 remv4,
378 internal_port); 379 internal_port);
379 binary = GNUNET_OS_get_suid_binary_path(cfg, "gnunet-helper-nat-client"); 380 binary = GNUNET_OS_get_suid_binary_path (cfg, "gnunet-helper-nat-client");
380 proc = GNUNET_OS_start_process(GNUNET_NO, 381 proc = GNUNET_OS_start_process (GNUNET_NO,
381 0, 382 0,
382 NULL, 383 NULL,
383 NULL, 384 NULL,
384 NULL, 385 NULL,
385 binary, 386 binary,
386 "gnunet-helper-nat-client", 387 "gnunet-helper-nat-client",
387 intv4, 388 intv4,
388 remv4, 389 remv4,
389 port_as_string, 390 port_as_string,
390 NULL); 391 NULL);
391 GNUNET_free(binary); 392 GNUNET_free (binary);
392 if (NULL == proc) 393 if (NULL == proc)
393 return GNUNET_SYSERR; 394 return GNUNET_SYSERR;
394 /* we know that the gnunet-helper-nat-client will terminate virtually 395 /* we know that the gnunet-helper-nat-client will terminate virtually
395 * instantly */ 396 * instantly */
396 GNUNET_OS_process_wait(proc); 397 GNUNET_OS_process_wait (proc);
397 GNUNET_OS_process_destroy(proc); 398 GNUNET_OS_process_destroy (proc);
398 return GNUNET_OK; 399 return GNUNET_OK;
399} 400}
400 401