aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authort3sserakt <t3ss@posteo.de>2020-06-12 12:51:46 +0200
committert3sserakt <t3ss@posteo.de>2020-06-12 12:51:46 +0200
commit726ac3ef2819e41aa5f045d76d9966b078934e32 (patch)
treebb94685c92fd06acfd1e9e2866b2afdffe1ec477 /src
parent11dbdc79aeb05e82913ac70cf2ac8d4f45b02c28 (diff)
downloadgnunet-726ac3ef2819e41aa5f045d76d9966b078934e32.tar.gz
gnunet-726ac3ef2819e41aa5f045d76d9966b078934e32.zip
Fixed 5528: TCP *communicator* bindto option should support DNS names, and 6013: TCP communicator should bind to IPv6 and IPv4 if only port given
Diffstat (limited to 'src')
-rw-r--r--src/transport/Makefile.am14
-rw-r--r--src/transport/gnunet-communicator-tcp.c898
-rw-r--r--src/transport/test_communicator_tcp_basic_peer1.conf7
-rw-r--r--src/transport/test_communicator_tcp_basic_peer2.conf6
-rw-r--r--src/transport/transport-testing2.c51
-rw-r--r--src/util/resolver_api.c2
6 files changed, 751 insertions, 227 deletions
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index 02e87da0f..eadb601ef 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -669,13 +669,13 @@ TESTS += \
669 test_transport_api_timeout_udp \ 669 test_transport_api_timeout_udp \
670 test_transport_api_udp_nat \ 670 test_transport_api_udp_nat \
671 test_transport_api_reliability_udp \ 671 test_transport_api_reliability_udp \
672test_quota_compliance_udp \ 672 test_quota_compliance_udp \
673test_communicator_basic-unix \ 673 test_communicator_basic-unix \
674test_communicator_basic-tcp \ 674 test_communicator_basic-tcp \
675test_communicator_basic-udp \ 675 test_communicator_basic-udp \
676test_communicator_rekey-tcp \ 676 test_communicator_rekey-tcp \
677test_communicator_rekey-udp \ 677 test_communicator_rekey-udp \
678test_communicator_backchannel-udp 678 test_communicator_backchannel-udp
679endif 679endif
680endif 680endif
681 681
diff --git a/src/transport/gnunet-communicator-tcp.c b/src/transport/gnunet-communicator-tcp.c
index 7f70c55df..e25cdf139 100644
--- a/src/transport/gnunet-communicator-tcp.c
+++ b/src/transport/gnunet-communicator-tcp.c
@@ -40,8 +40,10 @@
40#include "gnunet_nt_lib.h" 40#include "gnunet_nt_lib.h"
41#include "gnunet_nat_service.h" 41#include "gnunet_nat_service.h"
42#include "gnunet_statistics_service.h" 42#include "gnunet_statistics_service.h"
43#include "gnunet_ats_transport_service.h"
44#include "transport.h"
43#include "gnunet_transport_communication_service.h" 45#include "gnunet_transport_communication_service.h"
44 46#include "gnunet_resolver_service.h"
45/** 47/**
46 * How long do we believe our addresses to remain up (before 48 * How long do we believe our addresses to remain up (before
47 * the other peer should revalidate). 49 * the other peer should revalidate).
@@ -253,6 +255,21 @@ struct TCPFinish
253 255
254GNUNET_NETWORK_STRUCT_END 256GNUNET_NETWORK_STRUCT_END
255 257
258/**
259 * Struct to use as closure.
260 */
261struct ListenTask
262{
263 /**
264 * ID of listen task
265 */
266 struct GNUNET_SCHEDULER_Task *listen_task;
267
268 /**
269 * Listen socket.
270 */
271 struct GNUNET_NETWORK_Handle *listen_sock;
272};
256 273
257/** 274/**
258 * Handle for a queue. 275 * Handle for a queue.
@@ -265,6 +282,16 @@ struct Queue
265 struct GNUNET_PeerIdentity target; 282 struct GNUNET_PeerIdentity target;
266 283
267 /** 284 /**
285 * ID of listen task
286 */
287 struct GNUNET_SCHEDULER_Task *listen_task;
288
289 /**
290 * Listen socket.
291 */
292 struct GNUNET_NETWORK_Handle *listen_sock;
293
294 /**
268 * socket that we transmit all data with on this queue 295 * socket that we transmit all data with on this queue
269 */ 296 */
270 struct GNUNET_NETWORK_Handle *sock; 297 struct GNUNET_NETWORK_Handle *sock;
@@ -449,6 +476,16 @@ struct ProtoQueue
449 struct ProtoQueue *prev; 476 struct ProtoQueue *prev;
450 477
451 /** 478 /**
479 * ID of listen task
480 */
481 struct GNUNET_SCHEDULER_Task *listen_task;
482
483 /**
484 * Listen socket.
485 */
486 struct GNUNET_NETWORK_Handle *listen_sock;
487
488 /**
452 * socket that we transmit all data with on this queue 489 * socket that we transmit all data with on this queue
453 */ 490 */
454 struct GNUNET_NETWORK_Handle *sock; 491 struct GNUNET_NETWORK_Handle *sock;
@@ -485,11 +522,61 @@ struct ProtoQueue
485 size_t ibuf_off; 522 size_t ibuf_off;
486}; 523};
487 524
525/**
526 * In case of port only configuration we like to bind to ipv4 and ipv6 addresses.
527 */
528struct PortOnlyIpv4Ipv6
529{
530 /**
531 * Ipv4 address we like to bind to.
532 */
533 struct sockaddr *addr_ipv4;
534
535 /**
536 * Length of ipv4 address.
537 */
538 socklen_t *addr_len_ipv4;
539
540 /**
541 * Ipv6 address we like to bind to.
542 */
543 struct sockaddr *addr_ipv6;
544
545 /**
546 * Length of ipv6 address.
547 */
548 socklen_t *addr_len_ipv6;
549
550};
488 551
489/** 552/**
490 * ID of listen task 553 * DLL to store the addresses we like to register at NAT service.
491 */ 554 */
492static struct GNUNET_SCHEDULER_Task *listen_task; 555struct Addresses
556{
557 /**
558 * Kept in a DLL.
559 */
560 struct Addresses *next;
561
562 /**
563 * Kept in a DLL.
564 */
565 struct Addresses *prev;
566
567 /**
568 * Address we like to register at NAT service.
569 */
570 struct sockaddr *addr;
571
572 /**
573 * Length of address we like to register at NAT service.
574 */
575 socklen_t addr_len;
576
577};
578
579
493 580
494/** 581/**
495 * Maximum queue length before we stop reading towards the transport service. 582 * Maximum queue length before we stop reading towards the transport service.
@@ -512,11 +599,6 @@ static struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
512static struct GNUNET_CONTAINER_MultiPeerMap *queue_map; 599static struct GNUNET_CONTAINER_MultiPeerMap *queue_map;
513 600
514/** 601/**
515 * Listen socket.
516 */
517static struct GNUNET_NETWORK_Handle *listen_sock;
518
519/**
520 * Our public key. 602 * Our public key.
521 */ 603 */
522static struct GNUNET_PeerIdentity my_identity; 604static struct GNUNET_PeerIdentity my_identity;
@@ -556,6 +638,25 @@ static struct ProtoQueue *proto_head;
556 */ 638 */
557static struct ProtoQueue *proto_tail; 639static struct ProtoQueue *proto_tail;
558 640
641/**
642 * Handle for DNS lookup of bindto address
643 */
644struct GNUNET_RESOLVER_RequestHandle *resolve_request_handle;
645
646/**
647 * Head of DLL with addresses we like to register at NAT servcie.
648 */
649struct Addresses *addrs_head;
650
651/**
652 * Head of DLL with addresses we like to register at NAT servcie.
653 */
654struct Addresses *addrs_tail;
655
656/**
657 * Number of addresses in the DLL for register at NAT service.
658 */
659int addrs_lens;
559 660
560/** 661/**
561 * We have been notified that our listen socket has something to 662 * We have been notified that our listen socket has something to
@@ -579,6 +680,10 @@ static void
579queue_destroy (struct Queue *queue) 680queue_destroy (struct Queue *queue)
580{ 681{
581 struct GNUNET_MQ_Handle *mq; 682 struct GNUNET_MQ_Handle *mq;
683 struct ListenTask *lt;
684 lt = GNUNET_new (struct ListenTask);
685 lt->listen_sock = queue->listen_sock;
686 lt->listen_task = queue->listen_task;
582 687
583 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 688 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
584 "Disconnecting queue for peer `%s'\n", 689 "Disconnecting queue for peer `%s'\n",
@@ -618,11 +723,13 @@ queue_destroy (struct Queue *queue)
618 queue->destroyed = GNUNET_YES; 723 queue->destroyed = GNUNET_YES;
619 else 724 else
620 GNUNET_free (queue); 725 GNUNET_free (queue);
621 if (NULL == listen_task) 726
622 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 727 if (NULL == lt->listen_task)
623 listen_sock, 728 lt->listen_task = GNUNET_SCHEDULER_add_read_net (
624 &listen_cb, 729 GNUNET_TIME_UNIT_FOREVER_REL,
625 NULL); 730 lt->listen_sock,
731 &listen_cb,
732 lt);
626} 733}
627 734
628 735
@@ -1063,7 +1170,8 @@ queue_read (void *cls)
1063 However, we have to take into account that the plaintext buffer may have 1170 However, we have to take into account that the plaintext buffer may have
1064 already contained data and not jumpt too far ahead in the ciphertext. 1171 already contained data and not jumpt too far ahead in the ciphertext.
1065 If there is no rekey and the last message is incomplete (max > total), 1172 If there is no rekey and the last message is incomplete (max > total),
1066 it is safe to keep the decryption so we shift by 'max' */if (GNUNET_YES == queue->rekeyed) 1173 it is safe to keep the decryption so we shift by 'max' */
1174 if (GNUNET_YES == queue->rekeyed)
1067 { 1175 {
1068 max = total - old_pread_off; 1176 max = total - old_pread_off;
1069 queue->rekeyed = GNUNET_NO; 1177 queue->rekeyed = GNUNET_NO;
@@ -1095,143 +1203,276 @@ queue_read (void *cls)
1095 queue_finish (queue); 1203 queue_finish (queue);
1096} 1204}
1097 1205
1206/**
1207 * Convert a `struct sockaddr_in6 to a `struct sockaddr *`
1208 *
1209 * @param[out] sock_len set to the length of the address.
1210 * @param v6 The sockaddr_in6 to be converted.
1211 * @return The struct sockaddr *.
1212 */
1213static struct sockaddr *
1214tcp_address_to_sockaddr_numeric_v6 (socklen_t *sock_len, struct sockaddr_in6 v6,
1215 unsigned int port)
1216{
1217 struct sockaddr *in;
1218
1219 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1220 "1 address %s\n",
1221 GNUNET_a2s (in, *sock_len));
1222
1223 v6.sin6_family = AF_INET6;
1224 v6.sin6_port = htons ((uint16_t) port);
1225#if HAVE_SOCKADDR_IN_SIN_LEN
1226 v6.sin6_len = sizeof(sizeof(struct sockaddr_in6));
1227#endif
1228 in = GNUNET_memdup (&v6, sizeof(v6));
1229 *sock_len = sizeof(struct sockaddr_in6);
1230 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1231 "address %s\n",
1232 GNUNET_a2s (in, *sock_len));
1233
1234 return in;
1235}
1098 1236
1099/** 1237/**
1100 * Convert TCP bind specification to a `struct sockaddr *` 1238 * Convert a `struct sockaddr_in4 to a `struct sockaddr *`
1101 * 1239 *
1102 * @param bindto bind specification to convert 1240 * @param[out] sock_len set to the length of the address.
1103 * @param[out] sock_len set to the length of the address 1241 * @param v4 The sockaddr_in4 to be converted.
1104 * @return converted bindto specification 1242 * @return The struct sockaddr *.
1105 */ 1243 */
1106static struct sockaddr * 1244static struct sockaddr *
1107tcp_address_to_sockaddr (const char *bindto, socklen_t *sock_len) 1245tcp_address_to_sockaddr_numeric_v4 (socklen_t *sock_len, struct sockaddr_in v4,
1246 unsigned int port)
1108{ 1247{
1109 struct sockaddr *in; 1248 struct sockaddr *in;
1110 unsigned int port; 1249
1111 char dummy[2]; 1250 v4.sin_family = AF_INET;
1112 char *colon; 1251 v4.sin_port = htons ((uint16_t) port);
1252#if HAVE_SOCKADDR_IN_SIN_LEN
1253 v4.sin_len = sizeof(struct sockaddr_in);
1254#endif
1255 in = GNUNET_memdup (&v4, sizeof(v4));
1256 *sock_len = sizeof(struct sockaddr_in);
1257 return in;
1258}
1259
1260/**
1261 * Convert TCP bind specification to a `struct PortOnlyIpv4Ipv6 *`
1262 *
1263 * @param bindto bind specification to convert.
1264 * @return The converted bindto specification.
1265 */
1266static struct PortOnlyIpv4Ipv6 *
1267tcp_address_to_sockaddr_port_only (const char *bindto, unsigned int *port)
1268{
1269 struct PortOnlyIpv4Ipv6 *po;
1270 struct sockaddr_in *i4;
1271 struct sockaddr_in6 *i6;
1272 socklen_t sock_len_ipv4;
1273 socklen_t sock_len_ipv6;
1274
1275 /* interpreting value as just a PORT number */
1276 if (*port > UINT16_MAX)
1277 {
1278 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1279 "BINDTO specification `%s' invalid: value too large for port\n",
1280 bindto);
1281 return NULL;
1282 }
1283
1284 po = GNUNET_new (struct PortOnlyIpv4Ipv6);
1285
1286 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
1287 (GNUNET_YES ==
1288 GNUNET_CONFIGURATION_get_value_yesno (cfg,
1289 COMMUNICATOR_CONFIG_SECTION,
1290 "DISABLE_V6")))
1291 {
1292 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
1293 po->addr_ipv4 = tcp_address_to_sockaddr_numeric_v4 (&sock_len_ipv4, *i4,
1294 *port);
1295 po->addr_len_ipv4 = &sock_len_ipv4;
1296 }
1297 else
1298 {
1299
1300 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
1301 po->addr_ipv4 = tcp_address_to_sockaddr_numeric_v4 (&sock_len_ipv4, *i4,
1302 *port);
1303 po->addr_len_ipv4 = &sock_len_ipv4;
1304
1305 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1306 "3.5 address %s\n",
1307 GNUNET_a2s (po->addr_ipv4, sock_len_ipv4));
1308
1309 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
1310 po->addr_ipv6 = tcp_address_to_sockaddr_numeric_v6 (&sock_len_ipv6, *i6,
1311 *port);
1312 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1313 "3 address %s\n",
1314 GNUNET_a2s (po->addr_ipv6, sock_len_ipv6));
1315
1316 po->addr_len_ipv6 = &sock_len_ipv6;
1317 }
1318 return po;
1319}
1320
1321/**
1322 * This Method extracts the address part of the BINDTO string.
1323 *
1324 * @param bindto String we extract the address part from.
1325 * @return The extracted address string.
1326 */
1327static char *
1328extract_address (const char *bindto)
1329{
1330
1331 char *start;
1332 char *token;
1113 char *cp; 1333 char *cp;
1334 char *rest = NULL;
1114 1335
1115 if (1 == sscanf (bindto, "%u%1s", &port, dummy)) 1336 if (NULL == bindto)
1337 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1338 "bindto is NULL\n");
1339
1340 cp = GNUNET_strdup (bindto);
1341 start = cp;
1342 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
1116 { 1343 {
1117 /* interpreting value as just a PORT number */ 1344 start++; /* skip over '['*/
1118 if (port > UINT16_MAX) 1345 cp[strlen (cp) - 1] = '\0'; /* eat ']'*/
1346 }
1347 else {
1348 token = strtok_r (cp, "]", &rest);
1349 if (strlen (bindto) == strlen (token))
1119 { 1350 {
1120 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1351 token = strtok_r (cp, ":", &rest);
1121 "BINDTO specification `%s' invalid: value too large for port\n",
1122 bindto);
1123 return NULL;
1124 } 1352 }
1125 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) || 1353 else
1126 (GNUNET_YES ==
1127 GNUNET_CONFIGURATION_get_value_yesno (cfg,
1128 COMMUNICATOR_CONFIG_SECTION,
1129 "DISABLE_V6")))
1130 { 1354 {
1131 struct sockaddr_in *i4; 1355 token++;
1356 return token;
1357 }
1358 }
1132 1359
1133 i4 = GNUNET_malloc (sizeof(struct sockaddr_in)); 1360 // GNUNET_free(cp);
1134 i4->sin_family = AF_INET; 1361
1135 i4->sin_port = htons ((uint16_t) port); 1362 return start;
1136#if HAVE_SOCKADDR_IN_SIN_LEN 1363}
1137 i4->sin_len = sizeof(sizeof(struct sockaddr_in)); 1364
1138#endif 1365/**
1139 *sock_len = sizeof(struct sockaddr_in); 1366 * This Method extracts the port part of the BINDTO string.
1140 in = (struct sockaddr *) i4; 1367 *
1368 * @param addr_and_port String we extract the port from.
1369 * @return The extracted port as unsigned int.
1370 */
1371static unsigned int
1372extract_port (const char *addr_and_port)
1373{
1374 unsigned int port;
1375 char dummy[2];
1376 char *token;
1377 char *addr;
1378 char *colon;
1379 char *cp;
1380 char *rest = NULL;
1381
1382 if (NULL != addr_and_port)
1383 {
1384 cp = GNUNET_strdup (addr_and_port);
1385 token = strtok_r (cp, "]", &rest);
1386 if (strlen (addr_and_port) == strlen (token))
1387 {
1388 colon = strrchr (cp, ':');
1389 if (NULL == colon)
1390 {
1391 return 0;
1392 }
1393 addr = colon;
1394 addr++;
1141 } 1395 }
1142 else 1396 else
1143 { 1397 {
1144 struct sockaddr_in6 *i6; 1398 token = strtok_r (NULL, "]", &rest);
1145 1399 if (NULL == token)
1146 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6)); 1400 {
1147 i6->sin6_family = AF_INET6; 1401 return 0;
1148 i6->sin6_port = htons ((uint16_t) port); 1402 }
1149#if HAVE_SOCKADDR_IN_SIN_LEN 1403 else
1150 i6->sin6_len = sizeof(sizeof(struct sockaddr_in6)); 1404 {
1151#endif 1405 addr = token;
1152 *sock_len = sizeof(struct sockaddr_in6); 1406 addr++;
1153 in = (struct sockaddr *) i6; 1407 }
1154 } 1408 }
1155 return in; 1409
1156 } 1410
1157 cp = GNUNET_strdup (bindto); 1411 if (1 == sscanf (addr, "%u%1s", &port, dummy))
1158 colon = strrchr (cp, ':');
1159 if (NULL != colon)
1160 {
1161 /* interpet value after colon as port */
1162 *colon = '\0';
1163 colon++;
1164 if (1 == sscanf (colon, "%u%1s", &port, dummy))
1165 { 1412 {
1166 /* interpreting value as just a PORT number */ 1413 /* interpreting value as just a PORT number */
1167 if (port > UINT16_MAX) 1414 if (port > UINT16_MAX)
1168 { 1415 {
1169 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1416 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1170 "BINDTO specification `%s' invalid: value too large for port\n", 1417 "Port `%u' invalid: value too large for port\n",
1171 bindto); 1418 port);
1172 GNUNET_free (cp); 1419 // GNUNET_free (cp);
1173 return NULL; 1420 return 0;
1174 } 1421 }
1175 } 1422 }
1176 else 1423 else
1177 { 1424 {
1178 GNUNET_log ( 1425 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1179 GNUNET_ERROR_TYPE_ERROR, 1426 "BINDTO specification invalid: last ':' not followed by number\n");
1180 "BINDTO specification `%s' invalid: last ':' not followed by number\n", 1427 // GNUNET_free (cp);
1181 bindto); 1428 return 0;
1182 GNUNET_free (cp);
1183 return NULL;
1184 } 1429 }
1185 } 1430 }
1186 else 1431 else
1187 { 1432 {
1433 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1434 "return 0\n");
1188 /* interpret missing port as 0, aka pick any free one */ 1435 /* interpret missing port as 0, aka pick any free one */
1189 port = 0; 1436 port = 0;
1190 } 1437 }
1191 {
1192 /* try IPv4 */
1193 struct sockaddr_in v4;
1194 1438
1195 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr)) 1439
1196 { 1440 return port;
1197 v4.sin_family = AF_INET; 1441}
1198 v4.sin_port = htons ((uint16_t) port); 1442
1199#if HAVE_SOCKADDR_IN_SIN_LEN 1443/**
1200 v4.sin_len = sizeof(struct sockaddr_in); 1444 * Convert TCP bind specification to a `struct sockaddr *`
1201#endif 1445 *
1202 in = GNUNET_memdup (&v4, sizeof(v4)); 1446 * @param bindto bind specification to convert
1203 *sock_len = sizeof(v4); 1447 * @param[out] sock_len set to the length of the address
1204 GNUNET_free (cp); 1448 * @return converted bindto specification
1205 return in; 1449 */
1206 } 1450static struct sockaddr *
1451tcp_address_to_sockaddr (const char *bindto, socklen_t *sock_len)
1452{
1453 struct sockaddr *in;
1454 unsigned int port;
1455 struct sockaddr_in v4;
1456 struct sockaddr_in6 v6;
1457 const char *start;
1458
1459 // cp = GNUNET_strdup (bindto);
1460 start = extract_address (bindto);
1461
1462 if (1 == inet_pton (AF_INET, start, &v4.sin_addr))
1463 {
1464 // colon = strrchr (cp, ':');
1465 port = extract_port (bindto);
1466 in = tcp_address_to_sockaddr_numeric_v4 (sock_len, v4, port);
1207 } 1467 }
1468 else if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
1208 { 1469 {
1209 /* try IPv6 */ 1470 // colon = strrchr (cp, ':');
1210 struct sockaddr_in6 v6; 1471 port = extract_port (bindto);
1211 const char *start; 1472 in = tcp_address_to_sockaddr_numeric_v6 (sock_len, v6, port);
1212
1213 start = cp;
1214 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
1215 {
1216 start++; /* skip over '[' */
1217 cp[strlen (cp) - 1] = '\0'; /* eat ']' */
1218 }
1219 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
1220 {
1221 v6.sin6_family = AF_INET6;
1222 v6.sin6_port = htons ((uint16_t) port);
1223#if HAVE_SOCKADDR_IN_SIN_LEN
1224 v6.sin6_len = sizeof(sizeof(struct sockaddr_in6));
1225#endif
1226 in = GNUNET_memdup (&v6, sizeof(v6));
1227 *sock_len = sizeof(v6);
1228 GNUNET_free (cp);
1229 return in;
1230 }
1231 } 1473 }
1232 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */ 1474
1233 GNUNET_free (cp); 1475 return in;
1234 return NULL;
1235} 1476}
1236 1477
1237 1478
@@ -1667,6 +1908,16 @@ decrypt_and_check_tc (struct Queue *queue,
1667static void 1908static void
1668free_proto_queue (struct ProtoQueue *pq) 1909free_proto_queue (struct ProtoQueue *pq)
1669{ 1910{
1911 if (NULL != pq->listen_task)
1912 {
1913 GNUNET_SCHEDULER_cancel (pq->listen_task);
1914 pq->listen_task = NULL;
1915 }
1916 if (NULL != pq->listen_sock)
1917 {
1918 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pq->listen_sock));
1919 pq->listen_sock = NULL;
1920 }
1670 GNUNET_NETWORK_socket_close (pq->sock); 1921 GNUNET_NETWORK_socket_close (pq->sock);
1671 GNUNET_free (pq->address); 1922 GNUNET_free (pq->address);
1672 GNUNET_CONTAINER_DLL_remove (proto_head, proto_tail, pq); 1923 GNUNET_CONTAINER_DLL_remove (proto_head, proto_tail, pq);
@@ -1739,6 +1990,8 @@ proto_read_kx (void *cls)
1739 queue->address = pq->address; /* steals reference */ 1990 queue->address = pq->address; /* steals reference */
1740 queue->address_len = pq->address_len; 1991 queue->address_len = pq->address_len;
1741 queue->target = tc.sender; 1992 queue->target = tc.sender;
1993 queue->listen_task = pq->listen_task;
1994 queue->listen_sock = pq->listen_sock;
1742 queue->sock = pq->sock; 1995 queue->sock = pq->sock;
1743 start_initial_kx_out (queue); 1996 start_initial_kx_out (queue);
1744 boot_queue (queue, GNUNET_TRANSPORT_CS_INBOUND); 1997 boot_queue (queue, GNUNET_TRANSPORT_CS_INBOUND);
@@ -1762,7 +2015,7 @@ proto_read_kx (void *cls)
1762 * read. Do the read and reschedule this function to be called again 2015 * read. Do the read and reschedule this function to be called again
1763 * once more is available. 2016 * once more is available.
1764 * 2017 *
1765 * @param cls NULL 2018 * @param cls ListenTask with listening socket and task
1766 */ 2019 */
1767static void 2020static void
1768listen_cb (void *cls) 2021listen_cb (void *cls)
@@ -1771,20 +2024,23 @@ listen_cb (void *cls)
1771 socklen_t addrlen; 2024 socklen_t addrlen;
1772 struct GNUNET_NETWORK_Handle *sock; 2025 struct GNUNET_NETWORK_Handle *sock;
1773 struct ProtoQueue *pq; 2026 struct ProtoQueue *pq;
2027 struct ListenTask *lt;
1774 2028
1775 listen_task = NULL; 2029 lt = cls;
1776 GNUNET_assert (NULL != listen_sock); 2030
2031 lt->listen_task = NULL;
2032 GNUNET_assert (NULL != lt->listen_sock);
1777 addrlen = sizeof(in); 2033 addrlen = sizeof(in);
1778 memset (&in, 0, sizeof(in)); 2034 memset (&in, 0, sizeof(in));
1779 sock = GNUNET_NETWORK_socket_accept (listen_sock, 2035 sock = GNUNET_NETWORK_socket_accept (lt->listen_sock,
1780 (struct sockaddr*) &in, 2036 (struct sockaddr*) &in,
1781 &addrlen); 2037 &addrlen);
1782 if ((NULL == sock) && ((EMFILE == errno) || (ENFILE == errno))) 2038 if ((NULL == sock) && ((EMFILE == errno) || (ENFILE == errno)))
1783 return; /* system limit reached, wait until connection goes down */ 2039 return; /* system limit reached, wait until connection goes down */
1784 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 2040 lt->listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1785 listen_sock, 2041 lt->listen_sock,
1786 &listen_cb, 2042 &listen_cb,
1787 NULL); 2043 lt);
1788 if ((NULL == sock) && ((EAGAIN == errno) || (ENOBUFS == errno))) 2044 if ((NULL == sock) && ((EAGAIN == errno) || (ENOBUFS == errno)))
1789 return; 2045 return;
1790 if (NULL == sock) 2046 if (NULL == sock)
@@ -1884,7 +2140,6 @@ queue_read_kx (void *cls)
1884 queue->read_task = GNUNET_SCHEDULER_add_now (&queue_read, queue); 2140 queue->read_task = GNUNET_SCHEDULER_add_now (&queue_read, queue);
1885} 2141}
1886 2142
1887
1888/** 2143/**
1889 * Function called by the transport service to initialize a 2144 * Function called by the transport service to initialize a
1890 * message queue given address information about another peer. 2145 * message queue given address information about another peer.
@@ -1924,6 +2179,13 @@ mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
1924 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")]; 2179 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
1925 in = tcp_address_to_sockaddr (path, &in_len); 2180 in = tcp_address_to_sockaddr (path, &in_len);
1926 2181
2182 if (NULL == in)
2183 {
2184 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2185 "Failed to setup TCP socket address\n");
2186 return GNUNET_SYSERR;
2187 }
2188
1927 sock = GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM, IPPROTO_TCP); 2189 sock = GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM, IPPROTO_TCP);
1928 if (NULL == sock) 2190 if (NULL == sock)
1929 { 2191 {
@@ -1967,7 +2229,6 @@ mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
1967 return GNUNET_OK; 2229 return GNUNET_OK;
1968} 2230}
1969 2231
1970
1971/** 2232/**
1972 * Iterator over all message queues to clean up. 2233 * Iterator over all message queues to clean up.
1973 * 2234 *
@@ -2005,16 +2266,6 @@ do_shutdown (void *cls)
2005 GNUNET_NAT_unregister (nat); 2266 GNUNET_NAT_unregister (nat);
2006 nat = NULL; 2267 nat = NULL;
2007 } 2268 }
2008 if (NULL != listen_task)
2009 {
2010 GNUNET_SCHEDULER_cancel (listen_task);
2011 listen_task = NULL;
2012 }
2013 if (NULL != listen_sock)
2014 {
2015 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (listen_sock));
2016 listen_sock = NULL;
2017 }
2018 GNUNET_CONTAINER_multipeermap_iterate (queue_map, &get_queue_delete_it, NULL); 2269 GNUNET_CONTAINER_multipeermap_iterate (queue_map, &get_queue_delete_it, NULL);
2019 GNUNET_CONTAINER_multipeermap_destroy (queue_map); 2270 GNUNET_CONTAINER_multipeermap_destroy (queue_map);
2020 if (NULL != ch) 2271 if (NULL != ch)
@@ -2087,6 +2338,10 @@ nat_address_cb (void *cls,
2087 char *my_addr; 2338 char *my_addr;
2088 struct GNUNET_TRANSPORT_AddressIdentifier *ai; 2339 struct GNUNET_TRANSPORT_AddressIdentifier *ai;
2089 2340
2341 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2342 "1 nat_address %s\n",
2343 GNUNET_a2s (addr, addrlen));
2344
2090 if (GNUNET_YES == add_remove) 2345 if (GNUNET_YES == add_remove)
2091 { 2346 {
2092 enum GNUNET_NetworkType nt; 2347 enum GNUNET_NetworkType nt;
@@ -2112,80 +2367,53 @@ nat_address_cb (void *cls,
2112 } 2367 }
2113} 2368}
2114 2369
2115
2116/** 2370/**
2117 * Setup communicator and launch network interactions. 2371 * This method launch network interactions for each address we like to bind to.
2118 * 2372 *
2119 * @param cls NULL (always) 2373 * @param addr The address we will listen to.
2120 * @param args remaining command-line arguments 2374 * @param in_len The length of the address we will listen to.
2121 * @param cfgfile name of the configuration file used (for saving, can be NULL!) 2375 * @return GNUNET_SYSERR in case of error. GNUNET_OK in case we are successfully listen to the address.
2122 * @param c configuration
2123 */ 2376 */
2124static void 2377static int
2125run (void *cls, 2378init_socket (const struct sockaddr *addr,
2126 char *const *args, 2379 socklen_t in_len)
2127 const char *cfgfile,
2128 const struct GNUNET_CONFIGURATION_Handle *c)
2129{ 2380{
2130 char *bindto;
2131 struct sockaddr *in;
2132 socklen_t in_len;
2133 struct sockaddr_storage in_sto; 2381 struct sockaddr_storage in_sto;
2134 socklen_t sto_len; 2382 socklen_t sto_len;
2383 struct GNUNET_NETWORK_Handle *listen_sock;
2384 struct ListenTask *lt;
2135 2385
2136 (void) cls; 2386 if (NULL == addr)
2137 cfg = c;
2138 if (GNUNET_OK !=
2139 GNUNET_CONFIGURATION_get_value_string (cfg,
2140 COMMUNICATOR_CONFIG_SECTION,
2141 "BINDTO",
2142 &bindto))
2143 {
2144 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
2145 COMMUNICATOR_CONFIG_SECTION,
2146 "BINDTO");
2147 return;
2148 }
2149 if (GNUNET_OK !=
2150 GNUNET_CONFIGURATION_get_value_number (cfg,
2151 COMMUNICATOR_CONFIG_SECTION,
2152 "MAX_QUEUE_LENGTH",
2153 &max_queue_length))
2154 max_queue_length = DEFAULT_MAX_QUEUE_LENGTH;
2155 if (GNUNET_OK !=
2156 GNUNET_CONFIGURATION_get_value_time (cfg,
2157 COMMUNICATOR_CONFIG_SECTION,
2158 "REKEY_INTERVAL",
2159 &rekey_interval))
2160 rekey_interval = DEFAULT_REKEY_INTERVAL;
2161
2162 in = tcp_address_to_sockaddr (bindto, &in_len);
2163 if (NULL == in)
2164 { 2387 {
2165 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2388 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2166 "Failed to setup TCP socket address with path `%s'\n", 2389 "Address is NULL.\n");
2167 bindto); 2390 return GNUNET_SYSERR;
2168 GNUNET_free (bindto);
2169 return;
2170 } 2391 }
2392
2393 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2394 "4 address %s\n",
2395 GNUNET_a2s (addr, in_len));
2396
2397 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2398 "address %s\n",
2399 GNUNET_a2s (addr, in_len));
2400
2171 listen_sock = 2401 listen_sock =
2172 GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM, IPPROTO_TCP); 2402 GNUNET_NETWORK_socket_create (addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
2173 if (NULL == listen_sock) 2403 if (NULL == listen_sock)
2174 { 2404 {
2175 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket"); 2405 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
2176 GNUNET_free (in); 2406 return GNUNET_SYSERR;
2177 GNUNET_free (bindto);
2178 return;
2179 } 2407 }
2180 if (GNUNET_OK != GNUNET_NETWORK_socket_bind (listen_sock, in, in_len)) 2408
2409 if (GNUNET_OK != GNUNET_NETWORK_socket_bind (listen_sock, addr, in_len))
2181 { 2410 {
2182 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "bind", bindto); 2411 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
2183 GNUNET_NETWORK_socket_close (listen_sock); 2412 GNUNET_NETWORK_socket_close (listen_sock);
2184 listen_sock = NULL; 2413 listen_sock = NULL;
2185 GNUNET_free (in); 2414 return GNUNET_SYSERR;
2186 GNUNET_free (bindto);
2187 return;
2188 } 2415 }
2416
2189 if (GNUNET_OK != 2417 if (GNUNET_OK !=
2190 GNUNET_NETWORK_socket_listen (listen_sock, 2418 GNUNET_NETWORK_socket_listen (listen_sock,
2191 5)) 2419 5))
@@ -2194,69 +2422,311 @@ run (void *cls,
2194 "listen"); 2422 "listen");
2195 GNUNET_NETWORK_socket_close (listen_sock); 2423 GNUNET_NETWORK_socket_close (listen_sock);
2196 listen_sock = NULL; 2424 listen_sock = NULL;
2197 GNUNET_free (in); 2425 return GNUNET_SYSERR;
2198 GNUNET_free (bindto);
2199 } 2426 }
2427
2200 /* We might have bound to port 0, allowing the OS to figure it out; 2428 /* We might have bound to port 0, allowing the OS to figure it out;
2201 thus, get the real IN-address from the socket */ 2429 thus, get the real IN-address from the socket */
2202 sto_len = sizeof(in_sto); 2430 sto_len = sizeof(in_sto);
2431
2203 if (0 != getsockname (GNUNET_NETWORK_get_fd (listen_sock), 2432 if (0 != getsockname (GNUNET_NETWORK_get_fd (listen_sock),
2204 (struct sockaddr *) &in_sto, 2433 (struct sockaddr *) &in_sto,
2205 &sto_len)) 2434 &sto_len))
2206 { 2435 {
2207 memcpy (&in_sto, in, in_len); 2436 memcpy (&in_sto, addr, in_len);
2208 sto_len = in_len; 2437 sto_len = in_len;
2209 } 2438 }
2210 GNUNET_free (in); 2439
2211 GNUNET_free (bindto); 2440 addr = (struct sockaddr *) &in_sto;
2212 in = (struct sockaddr *) &in_sto;
2213 in_len = sto_len; 2441 in_len = sto_len;
2214 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2442 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2215 "Bound to `%s'\n", 2443 "Bound to `%s'\n",
2216 GNUNET_a2s ((const struct sockaddr *) &in_sto, sto_len)); 2444 GNUNET_a2s ((const struct sockaddr *) &in_sto, sto_len));
2217 stats = GNUNET_STATISTICS_create ("C-TCP", cfg); 2445 stats = GNUNET_STATISTICS_create ("C-TCP", cfg);
2218 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); 2446 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
2219 is = GNUNET_NT_scanner_init (); 2447
2220 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg); 2448 if (NULL == is)
2449 is = GNUNET_NT_scanner_init ();
2450
2451 if (NULL == my_private_key)
2452 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
2221 if (NULL == my_private_key) 2453 if (NULL == my_private_key)
2222 { 2454 {
2223 GNUNET_log ( 2455 GNUNET_log (
2224 GNUNET_ERROR_TYPE_ERROR, 2456 GNUNET_ERROR_TYPE_ERROR,
2225 _ ( 2457 _ (
2226 "Transport service is lacking key configuration settings. Exiting.\n")); 2458 "Transport service is lacking key configuration settings. Exiting.\n"));
2459 GNUNET_RESOLVER_request_cancel (resolve_request_handle);
2227 GNUNET_SCHEDULER_shutdown (); 2460 GNUNET_SCHEDULER_shutdown ();
2228 return; 2461 return GNUNET_SYSERR;
2229 } 2462 }
2230 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key, &my_identity.public_key); 2463 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key, &my_identity.public_key);
2231 /* start listening */ 2464 /* start listening */
2232 listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 2465
2233 listen_sock, 2466 lt = GNUNET_new (struct ListenTask);
2234 &listen_cb, 2467 lt->listen_sock = listen_sock;
2235 NULL); 2468
2236 queue_map = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); 2469 lt->listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2237 ch = GNUNET_TRANSPORT_communicator_connect (cfg, 2470 listen_sock,
2238 COMMUNICATOR_CONFIG_SECTION, 2471 &listen_cb,
2239 COMMUNICATOR_ADDRESS_PREFIX, 2472 lt);
2240 GNUNET_TRANSPORT_CC_RELIABLE, 2473
2241 &mq_init, 2474 if (NULL == queue_map)
2242 NULL, 2475 queue_map = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO);
2243 &enc_notify_cb, 2476
2244 NULL); 2477 if (NULL == ch )
2478 ch = GNUNET_TRANSPORT_communicator_connect (cfg,
2479 COMMUNICATOR_CONFIG_SECTION,
2480 COMMUNICATOR_ADDRESS_PREFIX,
2481 GNUNET_TRANSPORT_CC_RELIABLE,
2482 &mq_init,
2483 NULL,
2484 &enc_notify_cb,
2485 NULL);
2486
2245 if (NULL == ch) 2487 if (NULL == ch)
2246 { 2488 {
2247 GNUNET_break (0); 2489 GNUNET_break (0);
2490 GNUNET_RESOLVER_request_cancel (resolve_request_handle);
2248 GNUNET_SCHEDULER_shutdown (); 2491 GNUNET_SCHEDULER_shutdown ();
2249 return; 2492 return GNUNET_SYSERR;
2493 }
2494
2495 return GNUNET_OK;
2496
2497}
2498
2499/**
2500 * This method reads from the DLL addrs_head to register them at the NAT service.
2501 */
2502static void
2503nat_register ()
2504{
2505
2506 struct sockaddr **saddrs;
2507 socklen_t *saddr_lens;
2508 int i;
2509 struct Addresses *pos;
2510
2511 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2512 "nat here\n");
2513
2514 i = 0;
2515 saddrs = GNUNET_malloc ((addrs_lens + 1) * sizeof(struct sockaddr *));
2516
2517 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2518 "2 nat here\n");
2519
2520 saddr_lens = GNUNET_malloc ((addrs_lens + 1) * sizeof(socklen_t));
2521
2522 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2523 "3 nat here\n");
2524
2525 for (pos = addrs_head; NULL != pos; pos = pos->next)
2526 {
2527
2528 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2529 "5 nat here\n");
2530
2531 saddr_lens[i] = addrs_head->addr_len;
2532 saddrs[i] = GNUNET_malloc (saddr_lens[i]);
2533 saddrs[i] = addrs_head->addr;
2534
2535 i++;
2536
2537 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2538 "6 nat here\n");
2539
2250 } 2540 }
2541
2251 nat = GNUNET_NAT_register (cfg, 2542 nat = GNUNET_NAT_register (cfg,
2252 COMMUNICATOR_CONFIG_SECTION, 2543 COMMUNICATOR_CONFIG_SECTION,
2253 IPPROTO_TCP, 2544 IPPROTO_TCP,
2254 1 /* one address */, 2545 addrs_lens,
2255 (const struct sockaddr **) &in, 2546 (const struct sockaddr **) saddrs,
2256 &in_len, 2547 saddr_lens,
2257 &nat_address_cb, 2548 &nat_address_cb,
2258 NULL /* FIXME: support reversal: #5529 */, 2549 NULL /* FIXME: support reversal: #5529 */,
2259 NULL /* closure */); 2550 NULL /* closure */);
2551
2552 if (NULL == nat)
2553 {
2554 GNUNET_break (0);
2555 GNUNET_RESOLVER_request_cancel (resolve_request_handle);
2556 GNUNET_SCHEDULER_shutdown ();
2557 }
2558}
2559
2560/**
2561 * This method adds addresses to the DLL, that are later register at the NAT service.
2562 */
2563static void
2564add_addr (struct sockaddr *in, socklen_t in_len)
2565{
2566
2567 struct Addresses *saddrs;
2568
2569 saddrs = GNUNET_new (struct Addresses);
2570 saddrs->addr = in;
2571 saddrs->addr_len = in_len;
2572 GNUNET_CONTAINER_DLL_insert (addrs_head, addrs_tail, saddrs);
2573 addrs_lens++;
2574}
2575
2576/**
2577 * This method is the callback called by the resolver API, and wraps method init_socket.
2578 *
2579 * @param cls The port we will bind to.
2580 * @param addr The address we will bind to.
2581 * @param in_len The length of the address we will bind to.
2582 */
2583static void
2584init_socket_resolv (void *cls,
2585 const struct sockaddr *addr,
2586 socklen_t in_len)
2587{
2588 struct sockaddr_in *v4;
2589 struct sockaddr_in6 *v6;
2590 struct sockaddr *in;
2591 unsigned int *port;
2592
2593 port = cls;
2594 if (NULL != addr)
2595 {
2596 if (AF_INET == addr->sa_family)
2597 {
2598 v4 = (struct sockaddr_in *) addr;
2599 in = tcp_address_to_sockaddr_numeric_v4 (&in_len, *v4, *port);// _global);
2600 add_addr (in, in_len);
2601 }
2602 else if (AF_INET6 == addr->sa_family)
2603 {
2604 v6 = (struct sockaddr_in6 *) addr;
2605 in = tcp_address_to_sockaddr_numeric_v6 (&in_len, *v6, *port);// _global);
2606 add_addr (in, in_len);
2607 }
2608 else
2609 {
2610 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2611 "Address family %u not suitable (not AF_INET %u nor AF_INET6 %u \n",
2612 addr->sa_family,
2613 AF_INET,
2614 AF_INET6);
2615 return;
2616 }
2617 init_socket (in,
2618 in_len);
2619 }
2620 else
2621 {
2622 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2623 "Address is NULL. This might be an error or the resolver finished resolving.\n");
2624 nat_register ();
2625 }
2626}
2627
2628/**
2629 * Setup communicator and launch network interactions.
2630 *
2631 * @param cls NULL (always)
2632 * @param args remaining command-line arguments
2633 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
2634 * @param c configuration
2635 */
2636static void
2637run (void *cls,
2638 char *const *args,
2639 const char *cfgfile,
2640 const struct GNUNET_CONFIGURATION_Handle *c)
2641{
2642 char *bindto;
2643 struct sockaddr *in;
2644 socklen_t in_len;
2645 struct sockaddr_in v4;
2646 struct sockaddr_in6 v6;
2647 char *start;
2648 unsigned int port;
2649 char dummy[2];
2650 char *rest = NULL;
2651 struct PortOnlyIpv4Ipv6 *po;
2652
2653 (void) cls;
2654 cfg = c;
2655 if (GNUNET_OK !=
2656 GNUNET_CONFIGURATION_get_value_string (cfg,
2657 COMMUNICATOR_CONFIG_SECTION,
2658 "BINDTO",
2659 &bindto))
2660 {
2661 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
2662 COMMUNICATOR_CONFIG_SECTION,
2663 "BINDTO");
2664 return;
2665 }
2666 if (GNUNET_OK !=
2667 GNUNET_CONFIGURATION_get_value_number (cfg,
2668 COMMUNICATOR_CONFIG_SECTION,
2669 "MAX_QUEUE_LENGTH",
2670 &max_queue_length))
2671 max_queue_length = DEFAULT_MAX_QUEUE_LENGTH;
2672 if (GNUNET_OK !=
2673 GNUNET_CONFIGURATION_get_value_time (cfg,
2674 COMMUNICATOR_CONFIG_SECTION,
2675 "REKEY_INTERVAL",
2676 &rekey_interval))
2677 rekey_interval = DEFAULT_REKEY_INTERVAL;
2678
2679
2680 // cp = GNUNET_strdup (bindto);
2681 start = extract_address (bindto);
2682
2683 if (1 == sscanf (bindto, "%u%1s", &port, dummy))
2684 {
2685 po = tcp_address_to_sockaddr_port_only (bindto, &port);
2686
2687 if (NULL != &po->addr_ipv4)
2688 {
2689 init_socket (po->addr_ipv4, *po->addr_len_ipv4);
2690 add_addr (po->addr_ipv4, *po->addr_len_ipv4);
2691 }
2692
2693 if (NULL != &po->addr_ipv6)
2694 {
2695 init_socket (po->addr_ipv6, *po->addr_len_ipv6);
2696 add_addr (po->addr_ipv6, *po->addr_len_ipv6);
2697 }
2698
2699 nat_register ();
2700 }
2701 else if (1 == inet_pton (AF_INET, start, &v4.sin_addr))
2702 {
2703 port = extract_port (bindto);
2704
2705 in = tcp_address_to_sockaddr_numeric_v4 (&in_len, v4, port);
2706 init_socket (in, in_len);
2707 add_addr (in, in_len);
2708 nat_register ();
2709 }
2710 else if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2711 {
2712 port = extract_port (bindto);
2713 in = tcp_address_to_sockaddr_numeric_v6 (&in_len, v6, port);
2714 init_socket (in, in_len);
2715 add_addr (in, in_len);
2716 nat_register ();
2717 }
2718 else
2719 {
2720 port = extract_port (bindto);
2721
2722 resolve_request_handle = GNUNET_RESOLVER_ip_get (strtok_r (bindto, ":",
2723 &rest),
2724 AF_UNSPEC,
2725 GNUNET_TIME_UNIT_MINUTES,
2726 &init_socket_resolv,
2727 &port);
2728 }
2729 GNUNET_free (bindto);
2260} 2730}
2261 2731
2262 2732
diff --git a/src/transport/test_communicator_tcp_basic_peer1.conf b/src/transport/test_communicator_tcp_basic_peer1.conf
index fc08af1ee..d0293ff51 100644
--- a/src/transport/test_communicator_tcp_basic_peer1.conf
+++ b/src/transport/test_communicator_tcp_basic_peer1.conf
@@ -18,14 +18,17 @@ UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport_test_1.sock
18 18
19[nat] 19[nat]
20UNIXPATH = $GNUNET_TMP/test-communicator-unix-1/nat.sock 20UNIXPATH = $GNUNET_TMP/test-communicator-unix-1/nat.sock
21ENABLE_IPSCAN = YES
22 21
23[communicator-unix] 22[communicator-unix]
24UNIXPATH = $GNUNET_RUNTIME_DIR/test_gnunet-communicator-unix_1.sock 23UNIXPATH = $GNUNET_RUNTIME_DIR/test_gnunet-communicator-unix_1.sock
25 24
26[communicator-tcp] 25[communicator-tcp]
27BINDTO = 60002 26BINDTO = 60002
28DISABLE_V6 = YES 27DISABLE_V6 = NO
29 28
30[communicator-udp] 29[communicator-udp]
31BINDTO = 60002 30BINDTO = 60002
31
32[resolver]
33PORT = 62089
34UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver_test_1.sock
diff --git a/src/transport/test_communicator_tcp_basic_peer2.conf b/src/transport/test_communicator_tcp_basic_peer2.conf
index 4197df00d..5b9050547 100644
--- a/src/transport/test_communicator_tcp_basic_peer2.conf
+++ b/src/transport/test_communicator_tcp_basic_peer2.conf
@@ -25,7 +25,11 @@ UNIXPATH = $GNUNET_RUNTIME_DIR/test_gnunet-communicator-unix_2.sock
25 25
26[communicator-tcp] 26[communicator-tcp]
27BINDTO = 60003 27BINDTO = 60003
28DISABLE_V6 = YES 28DISABLE_V6 = NO
29 29
30[communicator-udp] 30[communicator-udp]
31BINDTO = 60003 31BINDTO = 60003
32
33[resolver]
34PORT = 62090
35UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver_test_2.sock
diff --git a/src/transport/transport-testing2.c b/src/transport/transport-testing2.c
index e85e46b11..0dc1bb331 100644
--- a/src/transport/transport-testing2.c
+++ b/src/transport/transport-testing2.c
@@ -109,6 +109,11 @@ struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle
109 struct GNUNET_OS_Process *nat_proc; 109 struct GNUNET_OS_Process *nat_proc;
110 110
111 /** 111 /**
112 * resolver service process
113 */
114 struct GNUNET_OS_Process *resolver_proc;
115
116 /**
112 * @brief Task that will be run on shutdown to stop and clean communicator 117 * @brief Task that will be run on shutdown to stop and clean communicator
113 */ 118 */
114 struct GNUNET_SCHEDULER_Task *c_shutdown_task; 119 struct GNUNET_SCHEDULER_Task *c_shutdown_task;
@@ -877,11 +882,11 @@ shutdown_process (struct GNUNET_OS_Process *proc)
877 if (0 != GNUNET_OS_process_kill (proc, SIGTERM)) 882 if (0 != GNUNET_OS_process_kill (proc, SIGTERM))
878 { 883 {
879 LOG (GNUNET_ERROR_TYPE_WARNING, 884 LOG (GNUNET_ERROR_TYPE_WARNING,
880 "Error shutting down communicator with SIGERM, trying SIGKILL\n"); 885 "Error shutting down process with SIGERM, trying SIGKILL\n");
881 if (0 != GNUNET_OS_process_kill (proc, SIGKILL)) 886 if (0 != GNUNET_OS_process_kill (proc, SIGKILL))
882 { 887 {
883 LOG (GNUNET_ERROR_TYPE_ERROR, 888 LOG (GNUNET_ERROR_TYPE_ERROR,
884 "Error shutting down communicator with SIGERM and SIGKILL\n"); 889 "Error shutting down process with SIGERM and SIGKILL\n");
885 } 890 }
886 } 891 }
887 GNUNET_OS_process_destroy (proc); 892 GNUNET_OS_process_destroy (proc);
@@ -942,6 +947,45 @@ shutdown_nat (void *cls)
942 shutdown_process (proc); 947 shutdown_process (proc);
943} 948}
944 949
950/**
951 * @brief Task run at shutdown to kill the resolver process
952 *
953 * @param cls Closure - Process of communicator
954 */
955static void
956shutdown_resolver (void *cls)
957{
958 struct GNUNET_OS_Process *proc = cls;
959 shutdown_process (proc);
960}
961
962static void
963resolver_start (struct
964 GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *tc_h)
965{
966 char *binary;
967
968 LOG (GNUNET_ERROR_TYPE_DEBUG, "resolver_start\n");
969 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-resolver");
970 tc_h->resolver_proc = GNUNET_OS_start_process (GNUNET_YES,
971 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
972 NULL,
973 NULL,
974 NULL,
975 binary,
976 "gnunet-service-resolver",
977 "-c",
978 tc_h->cfg_filename,
979 NULL);
980 if (NULL == tc_h->resolver_proc)
981 {
982 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to start resolver service!");
983 return;
984 }
985 LOG (GNUNET_ERROR_TYPE_INFO, "started resolver service\n");
986 GNUNET_free (binary);
987
988}
945 989
946/** 990/**
947 * @brief Start NAT 991 * @brief Start NAT
@@ -1037,6 +1081,8 @@ GNUNET_TRANSPORT_TESTING_transport_communicator_service_start (
1037 transport_communicator_start (tc_h); 1081 transport_communicator_start (tc_h);
1038 /* Start NAT */ 1082 /* Start NAT */
1039 nat_start (tc_h); 1083 nat_start (tc_h);
1084 /* Start resolver service */
1085 resolver_start (tc_h);
1040 /* Schedule start communicator */ 1086 /* Schedule start communicator */
1041 communicator_start (tc_h, 1087 communicator_start (tc_h,
1042 binary_name); 1088 binary_name);
@@ -1051,6 +1097,7 @@ GNUNET_TRANSPORT_TESTING_transport_communicator_service_stop (
1051 shutdown_communicator (tc_h->c_proc); 1097 shutdown_communicator (tc_h->c_proc);
1052 shutdown_service (tc_h->sh); 1098 shutdown_service (tc_h->sh);
1053 shutdown_nat (tc_h->nat_proc); 1099 shutdown_nat (tc_h->nat_proc);
1100 shutdown_resolver (tc_h->resolver_proc);
1054 GNUNET_CONFIGURATION_destroy (tc_h->cfg); 1101 GNUNET_CONFIGURATION_destroy (tc_h->cfg);
1055 GNUNET_free (tc_h); 1102 GNUNET_free (tc_h);
1056} 1103}
diff --git a/src/util/resolver_api.c b/src/util/resolver_api.c
index a1e30bbd4..d38c700e4 100644
--- a/src/util/resolver_api.c
+++ b/src/util/resolver_api.c
@@ -152,7 +152,7 @@ struct GNUNET_RESOLVER_RequestHandle
152 /** 152 /**
153 * Has this request been transmitted to the service? 153 * Has this request been transmitted to the service?
154 * #GNUNET_YES if transmitted 154 * #GNUNET_YES if transmitted
155 * #GNUNET_YES if not transmitted 155 * #GNUNET_NO if not transmitted
156 * #GNUNET_SYSERR when request was canceled 156 * #GNUNET_SYSERR when request was canceled
157 */ 157 */
158 int was_transmitted; 158 int was_transmitted;