107
108
sock = SOCKET (PF_INET, SOCK_DGRAM, 17);
110
GE_DIE_STRERROR (ectx, GE_FATAL | GE_ADMIN | GE_IMMEDIATE, "socket");
111
GNUNET_GE_DIE_STRERROR (ectx,
112
GNUNET_GE_FATAL | GNUNET_GE_ADMIN |
113
GNUNET_GE_IMMEDIATE, "socket");
113
116
if (SETSOCKOPT (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
115
GE_DIE_STRERROR (ectx,
116
GE_FATAL | GE_ADMIN | GE_IMMEDIATE, "setsockopt");
118
GNUNET_GE_DIE_STRERROR (ectx,
119
GNUNET_GE_FATAL | GNUNET_GE_ADMIN |
120
GNUNET_GE_IMMEDIATE, "setsockopt");
119
GE_ASSERT (NULL, port != 0);
123
GNUNET_GE_ASSERT (NULL, port != 0);
120
124
memset (&sin, 0, sizeof (sin));
121
125
sin.sin_family = AF_INET;
122
126
sin.sin_addr.s_addr = INADDR_ANY;
123
127
sin.sin_port = htons (port);
124
128
if (BIND (sock, (struct sockaddr *) &sin, sizeof (sin)) < 0)
126
GE_LOG_STRERROR (ectx, GE_FATAL | GE_ADMIN | GE_IMMEDIATE, "bind");
128
GE_FATAL | GE_ADMIN | GE_IMMEDIATE,
129
_("Failed to bind to UDP port %d.\n"), port);
130
GE_DIE_STRERROR (ectx, GE_FATAL | GE_USER | GE_IMMEDIATE, "bind");
130
GNUNET_GE_LOG_STRERROR (ectx,
131
GNUNET_GE_FATAL | GNUNET_GE_ADMIN |
132
GNUNET_GE_IMMEDIATE, "bind");
134
GNUNET_GE_FATAL | GNUNET_GE_ADMIN | GNUNET_GE_IMMEDIATE,
135
_("Failed to bind to UDP port %d.\n"), port);
136
GNUNET_GE_DIE_STRERROR (ectx,
137
GNUNET_GE_FATAL | GNUNET_GE_USER |
138
GNUNET_GE_IMMEDIATE, "bind");
133
141
/* do not bind if port == 0, then we use
142
150
isBlacklisted (const void *addr, unsigned int addr_len)
152
GNUNET_IPv4Address ip;
147
155
if (addr_len == sizeof (struct sockaddr_in))
149
memcpy (&ip, &((struct sockaddr_in *) addr)->sin_addr, sizeof (IPaddr));
157
memcpy (&ip, &((struct sockaddr_in *) addr)->sin_addr,
158
sizeof (GNUNET_IPv4Address));
151
else if (addr_len == sizeof (IPaddr))
160
else if (addr_len == sizeof (GNUNET_IPv4Address))
153
162
memcpy (&ip, addr, addr_len);
166
return GNUNET_SYSERR;
159
MUTEX_LOCK (configLock);
160
ret = check_ipv4_listed (filteredNetworks_, ip);
161
MUTEX_UNLOCK (configLock);
168
GNUNET_mutex_lock (configLock);
169
ret = GNUNET_check_ipv4_listed (filteredNetworks_, ip);
170
GNUNET_mutex_unlock (configLock);
169
178
isWhitelisted (const void *addr, unsigned int addr_len)
180
GNUNET_IPv4Address ip;
174
183
if (addr_len == sizeof (struct sockaddr_in))
176
memcpy (&ip, &((struct sockaddr_in *) addr)->sin_addr, sizeof (IPaddr));
185
memcpy (&ip, &((struct sockaddr_in *) addr)->sin_addr,
186
sizeof (GNUNET_IPv4Address));
178
else if (addr_len == sizeof (IPaddr))
188
else if (addr_len == sizeof (GNUNET_IPv4Address))
180
190
memcpy (&ip, addr, addr_len);
194
return GNUNET_SYSERR;
187
MUTEX_LOCK (configLock);
197
GNUNET_mutex_lock (configLock);
188
198
if (allowedNetworks_ != NULL)
189
ret = check_ipv4_listed (allowedNetworks_, ip);
190
MUTEX_UNLOCK (configLock);
199
ret = GNUNET_check_ipv4_listed (allowedNetworks_, ip);
200
GNUNET_mutex_unlock (configLock);
195
205
isRejected (const void *addr, unsigned int addr_len)
197
if ((YES == isBlacklisted (addr,
199
(YES != isWhitelisted (addr, addr_len)))
207
if ((GNUNET_YES == isBlacklisted (addr,
209
(GNUNET_YES != isWhitelisted (addr, addr_len)))
203
GE_DEBUG | GE_USER | GE_BULK,
204
"Rejecting traffic from %u.%u.%u.%u.\n",
205
PRIP (ntohl (*(int *) addr)));
213
GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_BULK,
214
"Rejecting traffic from %u.%u.%u.%u.\n",
215
GNUNET_PRIP (ntohl (*(int *) addr)));
218
228
* @param helo the hello message to verify
219
229
* (the signature/crc have been verified before)
220
* @return OK on success, SYSERR on failure
230
* @return GNUNET_OK on success, GNUNET_SYSERR on failure
223
verifyHello (const P2P_hello_MESSAGE * hello)
233
verifyHello (const GNUNET_MessageHello * hello)
225
235
const HostAddress *haddr;
227
237
haddr = (const HostAddress *) &hello[1];
228
238
if ((ntohs (hello->senderAddressSize) != sizeof (HostAddress)) ||
229
(ntohs (hello->header.size) != P2P_hello_MESSAGE_size (hello)) ||
230
(ntohs (hello->header.type) != p2p_PROTO_hello))
235
if ((YES == isBlacklisted (&haddr->ip,
237
(YES != isWhitelisted (&haddr->ip, sizeof (IPaddr))))
241
GE_DEBUG | GE_USER | GE_BULK,
242
"Rejecting UDP HELLO from %u.%u.%u.%u:%u due to configuration.\n",
243
PRIP (ntohl (*(int *) &haddr->ip.addr)), ntohs (haddr->port));
245
return SYSERR; /* obviously invalid */
249
GE_DEBUG | GE_USER | GE_BULK,
250
"Verified UDP HELLO from %u.%u.%u.%u:%u.\n",
251
PRIP (ntohl (*(int *) &haddr->ip.addr)), ntohs (haddr->port));
239
(ntohs (hello->header.size) != GNUNET_sizeof_hello (hello)) ||
240
(ntohs (hello->header.type) != GNUNET_P2P_PROTO_HELLO))
242
GNUNET_GE_BREAK (NULL, 0);
243
return GNUNET_SYSERR;
245
if ((GNUNET_YES == isBlacklisted (&haddr->ip,
246
sizeof (GNUNET_IPv4Address))) ||
247
(GNUNET_YES != isWhitelisted (&haddr->ip, sizeof (GNUNET_IPv4Address))))
251
GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_BULK,
252
"Rejecting UDP HELLO from %u.%u.%u.%u:%u due to configuration.\n",
253
GNUNET_PRIP (ntohl (*(int *) &haddr->ip.addr)),
254
ntohs (haddr->port));
256
return GNUNET_SYSERR; /* obviously invalid */
260
GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_BULK,
261
"Verified UDP HELLO from %u.%u.%u.%u:%u.\n",
262
GNUNET_PRIP (ntohl (*(int *) &haddr->ip.addr)),
263
ntohs (haddr->port));
257
269
* Create a hello-Message for the current node. The hello is created
258
270
* without signature and without a timestamp. The GNUnet core will
259
* sign the message and add an expiration time.
271
* GNUNET_RSA_sign the message and add an expiration time.
261
273
* @return hello on success, NULL on error
263
static P2P_hello_MESSAGE *
275
static GNUNET_MessageHello *
266
278
static HostAddress last_addr;
267
P2P_hello_MESSAGE *msg;
279
GNUNET_MessageHello *msg;
268
280
HostAddress *haddr;
269
281
unsigned short port;
273
285
return NULL; /* UDP transport configured send-only */
275
msg = MALLOC (sizeof (P2P_hello_MESSAGE) + sizeof (HostAddress));
287
msg = GNUNET_malloc (sizeof (GNUNET_MessageHello) + sizeof (HostAddress));
276
288
haddr = (HostAddress *) & msg[1];
279
291
if (!(((upnp != NULL) &&
280
(OK == upnp->get_ip (port,
283
(SYSERR != getPublicIPAddress (cfg, ectx, &haddr->ip))))
292
(GNUNET_OK == upnp->get_ip (port,
296
GNUNET_IP_get_public_ipv4_address (cfg, ectx, &haddr->ip))))
287
GE_WARNING | GE_ADMIN | GE_USER | GE_BULK,
288
_("UDP: Could not determine my public IP address.\n"));
300
GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_USER |
302
_("UDP: Could not determine my public IP address.\n"));
291
305
haddr->port = htons (port);
292
306
haddr->reserved = htons (0);
293
307
if (0 != memcmp (haddr, &last_addr, sizeof (HostAddress)))
296
GE_DEBUG | GE_USER | GE_BULK,
297
"UDP uses IP address %u.%u.%u.%u.\n",
298
PRIP (ntohl (*(int *) &haddr->ip)));
310
GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_BULK,
311
"UDP uses IP address %u.%u.%u.%u.\n",
312
GNUNET_PRIP (ntohl (*(int *) &haddr->ip)));
299
313
last_addr = *haddr;
301
315
msg->senderAddressSize = htons (sizeof (HostAddress));
302
msg->protocol = htons (UDP_PROTOCOL_NUMBER);
316
msg->protocol = htons (GNUNET_TRANSPORT_PROTOCOL_NUMBER_UDP);
303
317
msg->MTU = htonl (udpAPI.mtu);
308
322
* Send a message to the specified remote node.
310
* @param tsession the P2P_hello_MESSAGE identifying the remote node
324
* @param tsession the GNUNET_MessageHello identifying the remote node
311
325
* @param message what to send
312
326
* @param size the size of the message
313
* @return SYSERR on error, OK on success
327
* @return GNUNET_SYSERR on error, GNUNET_OK on success
316
udpSend (TSession * tsession,
330
udpSend (GNUNET_TSession * tsession,
317
331
const void *message, const unsigned int size, int important)
320
P2P_hello_MESSAGE *hello;
334
GNUNET_MessageHello *hello;
321
335
HostAddress *haddr;
322
336
struct sockaddr_in sin; /* an Internet endpoint address */
327
GE_ASSERT (NULL, tsession != NULL);
341
GNUNET_GE_ASSERT (NULL, tsession != NULL);
328
342
if (udp_sock == NULL)
343
return GNUNET_SYSERR;
346
GNUNET_GE_BREAK (ectx, 0);
347
return GNUNET_SYSERR;
335
349
if (size > udpAPI.mtu)
351
GNUNET_GE_BREAK (ectx, 0);
352
return GNUNET_SYSERR;
340
hello = (P2P_hello_MESSAGE *) tsession->internal;
354
hello = (GNUNET_MessageHello *) tsession->internal;
341
355
if (hello == NULL)
356
return GNUNET_SYSERR;
344
358
haddr = (HostAddress *) & hello[1];
345
359
ssize = size + sizeof (UDPMessage);
360
mp = GNUNET_malloc (ssize);
347
361
mp->header.size = htons (ssize);
348
362
mp->header.type = 0;
349
363
mp->sender = *(coreAPI->myIdentity);
350
364
memcpy (&mp[1], message, size);
352
366
memset (&sin, 0, sizeof (sin));
353
367
sin.sin_family = AF_INET;
354
368
sin.sin_port = haddr->port;
356
GE_ASSERT (ectx, sizeof (struct in_addr) == sizeof (IPaddr));
357
memcpy (&sin.sin_addr, &haddr->ip, sizeof (IPaddr));
370
GNUNET_GE_ASSERT (ectx,
371
sizeof (struct in_addr) == sizeof (GNUNET_IPv4Address));
372
memcpy (&sin.sin_addr, &haddr->ip, sizeof (GNUNET_IPv4Address));
360
GE_DEBUG | GE_USER | GE_BULK,
361
"Sending message of %d bytes via UDP to %u.%u.%u.%u:%u.\n",
362
ssize, PRIP (ntohl (*(int *) &sin.sin_addr)), ntohs (sin.sin_port));
375
GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_BULK,
376
"Sending message of %d bytes via UDP to %u.%u.%u.%u:%u.\n",
377
ssize, GNUNET_PRIP (ntohl (*(int *) &sin.sin_addr)),
378
ntohs (sin.sin_port));
365
if (YES == socket_send_to (udp_sock,
368
ssize, &sent, (const char *) &sin, sizeof (sin)))
381
if (GNUNET_YES == GNUNET_socket_send_to (udp_sock,
382
GNUNET_NC_NONBLOCKING,
384
ssize, &sent, (const char *) &sin,
371
388
win_ols_sendto (udp_sock, mp, ssize, (const char *) &sin, sizeof (sin));
372
389
if (sent != SOCKET_ERROR)
376
393
if (stats != NULL)
377
394
stats->change (stat_bytesSent, sent);
382
GE_WARNING | GE_ADMIN | GE_BULK,
384
("Failed to send message of size %d via UDP to %u.%u.%u.%u:%u: %s\n"),
385
ssize, PRIP (ntohl (*(int *) &sin.sin_addr)),
386
ntohs (sin.sin_port), STRERROR (errno));
399
GNUNET_GE_WARNING | GNUNET_GE_ADMIN | GNUNET_GE_BULK,
401
("Failed to send message of size %d via UDP to %u.%u.%u.%u:%u: %s\n"),
402
ssize, GNUNET_PRIP (ntohl (*(int *) &sin.sin_addr)),
403
ntohs (sin.sin_port), STRERROR (errno));
387
404
if (stats != NULL)
388
405
stats->change (stat_bytesDropped, ssize);
395
412
* Start the server process to receive inbound traffic.
397
* @return OK on success, SYSERR if the operation failed
414
* @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed
400
417
startTransportServer ()
403
420
unsigned short port;
405
GE_ASSERT (ectx, selector == NULL);
422
GNUNET_GE_ASSERT (ectx, selector == NULL);
406
423
/* initialize UDP network */
407
424
port = getGNUnetUDPPort ();
410
427
sock = listensock (port);
413
selector = select_create ("udp", YES, ectx, load_monitor, sock, sizeof (struct sockaddr_in), 0, /* timeout */
414
&select_message_handler,
416
&select_accept_handler,
418
&select_close_handler,
419
NULL, 64 * 1024, 16 /* max sockets */ );
429
return GNUNET_SYSERR;
430
selector = GNUNET_select_create ("udp", GNUNET_YES, ectx, load_monitor, sock, sizeof (struct sockaddr_in), 0, /* timeout */
431
&select_message_handler,
433
&select_accept_handler,
435
&select_close_handler,
437
16 /* max sockets */ );
420
438
if (selector == NULL)
439
return GNUNET_SYSERR;
424
442
sock = SOCKET (PF_INET, SOCK_DGRAM, 17);
430
GE_LOG_STRERROR (ectx, GE_ERROR | GE_ADMIN | GE_BULK, "socket");
431
select_destroy (selector);
448
GNUNET_GE_LOG_STRERROR (ectx,
449
GNUNET_GE_ERROR | GNUNET_GE_ADMIN |
450
GNUNET_GE_BULK, "socket");
451
GNUNET_select_destroy (selector);
453
return GNUNET_SYSERR;
435
udp_sock = socket_create (ectx, load_monitor, sock);
436
GE_ASSERT (ectx, udp_sock != NULL);
455
udp_sock = GNUNET_socket_create (ectx, load_monitor, sock);
456
GNUNET_GE_ASSERT (ectx, udp_sock != NULL);
448
MUTEX_LOCK (configLock);
449
FREENONNULL (filteredNetworks_);
450
FREENONNULL (allowedNetworks_);
452
GC_get_configuration_value_string (cfg, "UDP", "BLACKLIST", "", &ch);
453
filteredNetworks_ = parse_ipv4_network_specification (ectx, ch);
456
GC_get_configuration_value_string (cfg, "UDP", "WHITELIST", "", &ch);
468
GNUNET_mutex_lock (configLock);
469
GNUNET_free_non_null (filteredNetworks_);
470
GNUNET_free_non_null (allowedNetworks_);
472
GNUNET_GC_get_configuration_value_string (cfg, "UDP", "BLACKLIST", "", &ch);
473
filteredNetworks_ = GNUNET_parse_ipv4_network_specification (ectx, ch);
476
GNUNET_GC_get_configuration_value_string (cfg, "UDP", "WHITELIST", "", &ch);
457
477
if (strlen (ch) > 0)
458
allowedNetworks_ = parse_ipv4_network_specification (ectx, ch);
478
allowedNetworks_ = GNUNET_parse_ipv4_network_specification (ectx, ch);
460
480
allowedNetworks_ = NULL;
462
MUTEX_UNLOCK (configLock);
482
GNUNET_mutex_unlock (configLock);
467
487
* Convert UDP hello to IP address
470
helloToAddress (const P2P_hello_MESSAGE * hello,
490
helloToAddress (const GNUNET_MessageHello * hello,
471
491
void **sa, unsigned int *sa_len)
473
493
const HostAddress *haddr = (const HostAddress *) &hello[1];
474
494
struct sockaddr_in *serverAddr;
476
496
*sa_len = sizeof (struct sockaddr_in);
477
serverAddr = MALLOC (sizeof (struct sockaddr_in));
497
serverAddr = GNUNET_malloc (sizeof (struct sockaddr_in));
478
498
*sa = serverAddr;
479
499
memset (serverAddr, 0, sizeof (struct sockaddr_in));
480
500
serverAddr->sin_family = AF_INET;
481
memcpy (&serverAddr->sin_addr, haddr, sizeof (IPaddr));
501
memcpy (&serverAddr->sin_addr, haddr, sizeof (GNUNET_IPv4Address));
482
502
serverAddr->sin_port = haddr->port;
493
513
* The exported method. Makes the core api available via a global and
494
514
* returns the udp transport API.
497
inittransport_udp (CoreAPIForTransport * core)
516
GNUNET_TransportAPI *
517
inittransport_udp (GNUNET_CoreAPIForTransport * core)
499
519
unsigned long long mtu;
501
521
ectx = core->ectx;
503
523
load_monitor = core->load_monitor;
504
GE_ASSERT (ectx, sizeof (HostAddress) == 8);
505
GE_ASSERT (ectx, sizeof (UDPMessage) == 68);
524
GNUNET_GE_ASSERT (ectx, sizeof (HostAddress) == 8);
525
GNUNET_GE_ASSERT (ectx, sizeof (UDPMessage) == 68);
507
if (-1 == GC_get_configuration_value_number (cfg,
511
+ P2P_MESSAGE_OVERHEAD
512
+ sizeof (MESSAGE_HEADER) + 32,
513
65500, MESSAGE_SIZE, &mtu))
527
if (-1 == GNUNET_GC_get_configuration_value_number (cfg,
532
GNUNET_P2P_MESSAGE_OVERHEAD
535
(GNUNET_MessageHeader) +
519
GE_ERROR | GE_USER | GE_IMMEDIATE,
520
_("MTU %llu for `%s' is probably too low!\n"), mtu, "UDP");
521
if (GC_get_configuration_value_yesno (cfg, "UDP", "UPNP", YES) == YES)
543
GNUNET_GE_ERROR | GNUNET_GE_USER | GNUNET_GE_IMMEDIATE,
544
_("MTU %llu for `%s' is probably too low!\n"), mtu, "UDP");
545
if (GNUNET_GC_get_configuration_value_yesno (cfg, "UDP", "UPNP", GNUNET_YES)
523
upnp = coreAPI->requestService ("upnp");
548
upnp = coreAPI->request_service ("upnp");
525
550
if (upnp == NULL)
527
GE_ERROR | GE_USER | GE_IMMEDIATE,
528
"The UPnP service could not be loaded. To disable UPnP, set the "
529
"configuration option \"UPNP\" in section \"UDP\" to \"NO\"\n");
552
GNUNET_GE_ERROR | GNUNET_GE_USER | GNUNET_GE_IMMEDIATE,
553
"The UPnP service could not be loaded. To disable UPnP, set the "
554
"configuration option \"UPNP\" in section \"UDP\" to \"NO\"\n");
531
stats = coreAPI->requestService ("stats");
556
stats = coreAPI->request_service ("stats");
532
557
if (stats != NULL)
534
559
stat_bytesReceived