aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/gnunet_strings_lib.h4
-rw-r--r--src/peerinfo-tool/gnunet-peerinfo.c84
-rw-r--r--src/util/strings.c101
3 files changed, 97 insertions, 92 deletions
diff --git a/src/include/gnunet_strings_lib.h b/src/include/gnunet_strings_lib.h
index 2eebfecff..54d2e3034 100644
--- a/src/include/gnunet_strings_lib.h
+++ b/src/include/gnunet_strings_lib.h
@@ -342,6 +342,7 @@ GNUNET_STRINGS_check_filename (const char *filename,
342 342
343/** 343/**
344 * Tries to convert 'zt_addr' string to an IPv6 address. 344 * Tries to convert 'zt_addr' string to an IPv6 address.
345 * The string is expected to have the format "[ABCD::01]:80".
345 * 346 *
346 * @param zt_addr 0-terminated string. May be mangled by the function. 347 * @param zt_addr 0-terminated string. May be mangled by the function.
347 * @param addrlen length of zt_addr (not counting 0-terminator). 348 * @param addrlen length of zt_addr (not counting 0-terminator).
@@ -358,6 +359,7 @@ GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr,
358 359
359/** 360/**
360 * Tries to convert 'zt_addr' string to an IPv4 address. 361 * Tries to convert 'zt_addr' string to an IPv4 address.
362 * The string is expected to have the format "1.2.3.4:80".
361 * 363 *
362 * @param zt_addr 0-terminated string. May be mangled by the function. 364 * @param zt_addr 0-terminated string. May be mangled by the function.
363 * @param addrlen length of zt_addr (not counting 0-terminator). 365 * @param addrlen length of zt_addr (not counting 0-terminator).
@@ -373,8 +375,6 @@ GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr,
373 375
374/** 376/**
375 * Tries to convert 'addr' string to an IP (v4 or v6) address. 377 * Tries to convert 'addr' string to an IP (v4 or v6) address.
376 * IPv6 address must have its address part enclosed in '()' parens
377 * instead of '[]'.
378 * Will automatically decide whether to treat 'addr' as v4 or v6 address. 378 * Will automatically decide whether to treat 'addr' as v4 or v6 address.
379 * 379 *
380 * @param addr a string, may not be 0-terminated. 380 * @param addr a string, may not be 0-terminated.
diff --git a/src/peerinfo-tool/gnunet-peerinfo.c b/src/peerinfo-tool/gnunet-peerinfo.c
index 2c26c4599..8bb7392d9 100644
--- a/src/peerinfo-tool/gnunet-peerinfo.c
+++ b/src/peerinfo-tool/gnunet-peerinfo.c
@@ -228,6 +228,42 @@ state_machine (void *cls,
228 const struct GNUNET_SCHEDULER_TaskContext *tc); 228 const struct GNUNET_SCHEDULER_TaskContext *tc);
229 229
230 230
231
232/**
233 * Replace all characters in the input 'in' according
234 * to the mapping. The mapping says to map each character
235 * in 'oldchars' to the corresponding character (by offset)
236 * in 'newchars'.
237 *
238 * @param in input string to remap
239 * @param oldchars characters to replace
240 * @param newchars replacement characters, must have same length as 'oldchars'
241 * @return copy of string with replacement applied.
242 */
243static char *
244map_characters (const char *in,
245 const char *oldchars,
246 const char *newchars)
247{
248 char *ret;
249 const char *off;
250 size_t i;
251
252 GNUNET_assert (strlen (oldchars) == strlen (newchars));
253 ret = GNUNET_strdup (in);
254 i = 0;
255 while (ret[i] != '\0')
256 {
257 off = strchr (oldchars, ret[i]);
258 if (NULL != off)
259 ret[i] = newchars[off - oldchars];
260 i++;
261 }
262 return ret;
263}
264
265
266
231/* ********************* 'get_info' ******************* */ 267/* ********************* 'get_info' ******************* */
232 268
233/** 269/**
@@ -412,6 +448,7 @@ compose_uri (void *cls, const struct GNUNET_HELLO_Address *address,
412 struct GetUriContext *guc = cls; 448 struct GetUriContext *guc = cls;
413 struct GNUNET_TRANSPORT_PluginFunctions *papi; 449 struct GNUNET_TRANSPORT_PluginFunctions *papi;
414 const char *addr; 450 const char *addr;
451 char *uri_addr;
415 char *ret; 452 char *ret;
416 char tbuf[16]; 453 char tbuf[16];
417 struct tm *t; 454 struct tm *t;
@@ -433,6 +470,9 @@ compose_uri (void *cls, const struct GNUNET_HELLO_Address *address,
433 addr = papi->address_to_string (papi->cls, address->address, address->address_length); 470 addr = papi->address_to_string (papi->cls, address->address, address->address_length);
434 if ( (addr == NULL) || (strlen(addr) == 0) ) 471 if ( (addr == NULL) || (strlen(addr) == 0) )
435 return GNUNET_OK; 472 return GNUNET_OK;
473 /* For URIs we use '(' and ')' instead of '[' and ']' as brackets are reserved
474 characters in URIs */
475 uri_addr = map_characters (addr, "[]", "()");
436 seconds = expiration.abs_value / 1000; 476 seconds = expiration.abs_value / 1000;
437 t = gmtime (&seconds); 477 t = gmtime (&seconds);
438 GNUNET_assert (0 != strftime (tbuf, sizeof (tbuf), 478 GNUNET_assert (0 != strftime (tbuf, sizeof (tbuf),
@@ -443,7 +483,8 @@ compose_uri (void *cls, const struct GNUNET_HELLO_Address *address,
443 guc->uri, 483 guc->uri,
444 tbuf, 484 tbuf,
445 address->transport_name, 485 address->transport_name,
446 addr); 486 uri_addr);
487 GNUNET_free (uri_addr);
447 GNUNET_free (guc->uri); 488 GNUNET_free (guc->uri);
448 guc->uri = ret; 489 guc->uri = ret;
449 return GNUNET_OK; 490 return GNUNET_OK;
@@ -501,7 +542,8 @@ add_address_to_hello (void *cls, size_t max, void *buffer)
501 struct GNUNET_PEERINFO_HelloAddressParsingContext *ctx = cls; 542 struct GNUNET_PEERINFO_HelloAddressParsingContext *ctx = cls;
502 const char *tname; 543 const char *tname;
503 const char *address; 544 const char *address;
504 char * address_terminated; 545 char *uri_address;
546 char *plugin_address;
505 const char *end; 547 const char *end;
506 char *plugin_name; 548 char *plugin_name;
507 struct tm expiration_time; 549 struct tm expiration_time;
@@ -512,6 +554,7 @@ add_address_to_hello (void *cls, size_t max, void *buffer)
512 size_t addr_len; 554 size_t addr_len;
513 struct GNUNET_HELLO_Address haddr; 555 struct GNUNET_HELLO_Address haddr;
514 size_t ret; 556 size_t ret;
557
515 if (NULL == ctx->pos) 558 if (NULL == ctx->pos)
516 return 0; 559 return 0;
517 if ('!' != ctx->pos[0]) 560 if ('!' != ctx->pos[0])
@@ -564,23 +607,7 @@ add_address_to_hello (void *cls, size_t max, void *buffer)
564 } 607 }
565 address++; 608 address++;
566 end = strchr (address, (int) '!'); 609 end = strchr (address, (int) '!');
567 if (NULL == end) 610 ctx->pos = end;
568 {
569 /* Last address */
570 end = address + strlen (address);
571 address_terminated = strdup (address);
572 ctx->pos = NULL;
573 }
574 else
575 {
576 /* More addresses follow */
577 size_t len = (end - address);
578 address_terminated = GNUNET_malloc (len + 1);
579 memcpy (address_terminated, address, len);
580 address_terminated[len] = '\0';
581 ctx->pos = end;
582
583 }
584 plugin_name = GNUNET_strndup (tname, address - (tname+1)); 611 plugin_name = GNUNET_strndup (tname, address - (tname+1));
585 papi = GPI_plugins_find (plugin_name); 612 papi = GPI_plugins_find (plugin_name);
586 if (NULL == papi) 613 if (NULL == papi)
@@ -593,9 +620,7 @@ add_address_to_hello (void *cls, size_t max, void *buffer)
593 _("Plugin `%s' not found\n"), 620 _("Plugin `%s' not found\n"),
594 plugin_name); 621 plugin_name);
595 GNUNET_free (plugin_name); 622 GNUNET_free (plugin_name);
596
597 GNUNET_break (0); 623 GNUNET_break (0);
598 GNUNET_free (address_terminated);
599 return 0; 624 return 0;
600 } 625 }
601 if (NULL == papi->string_to_address) 626 if (NULL == papi->string_to_address)
@@ -604,25 +629,29 @@ add_address_to_hello (void *cls, size_t max, void *buffer)
604 _("Plugin `%s' does not support URIs yet\n"), 629 _("Plugin `%s' does not support URIs yet\n"),
605 plugin_name); 630 plugin_name);
606 GNUNET_free (plugin_name); 631 GNUNET_free (plugin_name);
607 GNUNET_free (address_terminated);
608 GNUNET_break (0); 632 GNUNET_break (0);
609 return 0; 633 return 0;
610 } 634 }
611 635 uri_address = GNUNET_strndup (address, end - address);
636 /* For URIs we use '(' and ')' instead of '[' and ']' as brackets are reserved
637 characters in URIs; need to convert back to '[]' for the plugin */
638 plugin_address = map_characters (uri_address, "()", "[]");
639 GNUNET_free (uri_address);
612 if (GNUNET_OK != 640 if (GNUNET_OK !=
613 papi->string_to_address (papi->cls, 641 papi->string_to_address (papi->cls,
614 address_terminated, 642 plugin_address,
615 strlen (address_terminated) + 1, 643 strlen (plugin_address),
616 &addr, 644 &addr,
617 &addr_len)) 645 &addr_len))
618 { 646 {
619 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 647 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
620 _("Failed to parse `%s'\n"), 648 _("Failed to parse `%s'\n"),
621 address_terminated); 649 plugin_address);
622 GNUNET_free (plugin_name); 650 GNUNET_free (plugin_name);
623 GNUNET_free (address_terminated); 651 GNUNET_free (plugin_address);
624 return 0; 652 return 0;
625 } 653 }
654 GNUNET_free (plugin_address);
626 /* address.peer is unset - not used by add_address() */ 655 /* address.peer is unset - not used by add_address() */
627 haddr.address_length = addr_len; 656 haddr.address_length = addr_len;
628 haddr.address = addr; 657 haddr.address = addr;
@@ -630,7 +659,6 @@ add_address_to_hello (void *cls, size_t max, void *buffer)
630 ret = GNUNET_HELLO_add_address (&haddr, expire, buffer, max); 659 ret = GNUNET_HELLO_add_address (&haddr, expire, buffer, max);
631 GNUNET_free (addr); 660 GNUNET_free (addr);
632 GNUNET_free (plugin_name); 661 GNUNET_free (plugin_name);
633 GNUNET_free (address_terminated);
634 return ret; 662 return ret;
635} 663}
636 664
diff --git a/src/util/strings.c b/src/util/strings.c
index f9e2d8da6..dcc1a8250 100644
--- a/src/util/strings.c
+++ b/src/util/strings.c
@@ -940,6 +940,7 @@ GNUNET_STRINGS_path_is_absolute (const char *filename, int can_be_uri,
940#define S_ISLNK(m) (((m)&_IFMT) == _IFLNK) 940#define S_ISLNK(m) (((m)&_IFMT) == _IFLNK)
941#endif 941#endif
942 942
943
943/** 944/**
944 * Perform 'checks' on 'filename' 945 * Perform 'checks' on 'filename'
945 * 946 *
@@ -953,39 +954,37 @@ GNUNET_STRINGS_check_filename (const char *filename,
953 enum GNUNET_STRINGS_FilenameCheck checks) 954 enum GNUNET_STRINGS_FilenameCheck checks)
954{ 955{
955 struct stat st; 956 struct stat st;
956 if (filename == NULL || filename[0] == '\0') 957 if ( (NULL == filename) || (filename[0] == '\0') )
957 return GNUNET_SYSERR; 958 return GNUNET_SYSERR;
958 if (checks & GNUNET_STRINGS_CHECK_IS_ABSOLUTE) 959 if (0 != (checks & GNUNET_STRINGS_CHECK_IS_ABSOLUTE))
959 if (!GNUNET_STRINGS_path_is_absolute (filename, GNUNET_NO, NULL, NULL)) 960 if (!GNUNET_STRINGS_path_is_absolute (filename, GNUNET_NO, NULL, NULL))
960 return GNUNET_NO; 961 return GNUNET_NO;
961 if (checks & (GNUNET_STRINGS_CHECK_EXISTS 962 if (0 != (checks & (GNUNET_STRINGS_CHECK_EXISTS
962 | GNUNET_STRINGS_CHECK_IS_DIRECTORY 963 | GNUNET_STRINGS_CHECK_IS_DIRECTORY
963 | GNUNET_STRINGS_CHECK_IS_LINK)) 964 | GNUNET_STRINGS_CHECK_IS_LINK)))
964 { 965 {
965 if (STAT (filename, &st)) 966 if (0 != STAT (filename, &st))
966 { 967 {
967 if (checks & GNUNET_STRINGS_CHECK_EXISTS) 968 if (0 != (checks & GNUNET_STRINGS_CHECK_EXISTS))
968 return GNUNET_NO; 969 return GNUNET_NO;
969 else 970 else
970 return GNUNET_SYSERR; 971 return GNUNET_SYSERR;
971 } 972 }
972 } 973 }
973 if (checks & GNUNET_STRINGS_CHECK_IS_DIRECTORY) 974 if (0 != (checks & GNUNET_STRINGS_CHECK_IS_DIRECTORY))
974 if (!S_ISDIR (st.st_mode)) 975 if (!S_ISDIR (st.st_mode))
975 return GNUNET_NO; 976 return GNUNET_NO;
976 if (checks & GNUNET_STRINGS_CHECK_IS_LINK) 977 if (0 != (checks & GNUNET_STRINGS_CHECK_IS_LINK))
977 if (!S_ISLNK (st.st_mode)) 978 if (!S_ISLNK (st.st_mode))
978 return GNUNET_NO; 979 return GNUNET_NO;
979 return GNUNET_YES; 980 return GNUNET_YES;
980} 981}
981 982
982#define MAX_IPV6_ADDRLEN 47
983#define MAX_IPV4_ADDRLEN 21
984#define MAX_IP_ADDRLEN MAX_IPV6_ADDRLEN
985 983
986 984
987/** 985/**
988 * Tries to convert 'zt_addr' string to an IPv6 address. 986 * Tries to convert 'zt_addr' string to an IPv6 address.
987 * The string is expected to have the format "[ABCD::01]:80".
989 * 988 *
990 * @param zt_addr 0-terminated string. May be mangled by the function. 989 * @param zt_addr 0-terminated string. May be mangled by the function.
991 * @param addrlen length of zt_addr (not counting 0-terminator). 990 * @param addrlen length of zt_addr (not counting 0-terminator).
@@ -999,32 +998,42 @@ GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr,
999 uint16_t addrlen, 998 uint16_t addrlen,
1000 struct sockaddr_in6 *r_buf) 999 struct sockaddr_in6 *r_buf)
1001{ 1000{
1001 char zbuf[addrlen + 1];
1002 int ret; 1002 int ret;
1003 char *port_colon; 1003 char *port_colon;
1004 unsigned int port; 1004 unsigned int port;
1005 1005
1006 if (addrlen < 6) 1006 if (addrlen < 6)
1007 return GNUNET_SYSERR;
1008 memcpy (zbuf, zt_addr, addrlen);
1009 if ('[' != zbuf[0])
1007 return GNUNET_SYSERR; 1010 return GNUNET_SYSERR;
1008 1011 zbuf[addrlen] = '\0';
1009 port_colon = strrchr (zt_addr, ':'); 1012 port_colon = strrchr (zbuf, ':');
1010 if (port_colon == NULL) 1013 if (NULL == port_colon)
1014 return GNUNET_SYSERR;
1015 if (']' != *(port_colon - 1))
1011 return GNUNET_SYSERR; 1016 return GNUNET_SYSERR;
1012 ret = SSCANF (port_colon, ":%u", &port); 1017 ret = SSCANF (port_colon, ":%u", &port);
1013 if (ret != 1 || port > 65535) 1018 if ( (-1 != ret) || (port > 65535) )
1014 return GNUNET_SYSERR; 1019 return GNUNET_SYSERR;
1015 port_colon[0] = '\0'; 1020 *(port_colon-1) = '\0';
1016 memset (r_buf, 0, sizeof (struct sockaddr_in6)); 1021 memset (r_buf, 0, sizeof (struct sockaddr_in6));
1017 ret = inet_pton (AF_INET6, zt_addr, &r_buf->sin6_addr); 1022 ret = inet_pton (AF_INET6, &zbuf[1], &r_buf->sin6_addr);
1018 if (ret <= 0) 1023 if (ret <= 0)
1019 return GNUNET_SYSERR; 1024 return GNUNET_SYSERR;
1020 r_buf->sin6_port = htons (port); 1025 r_buf->sin6_port = htons (port);
1021 r_buf->sin6_family = AF_INET6; 1026 r_buf->sin6_family = AF_INET6;
1027#if HAVE_SOCKADDR_IN_SIN_LEN
1028 r_buf->sin6_len = (u_char) sizeof (struct sockaddr_in6);
1029#endif
1022 return GNUNET_OK; 1030 return GNUNET_OK;
1023} 1031}
1024 1032
1025 1033
1026/** 1034/**
1027 * Tries to convert 'zt_addr' string to an IPv4 address. 1035 * Tries to convert 'zt_addr' string to an IPv4 address.
1036 * The string is expected to have the format "1.2.3.4:80".
1028 * 1037 *
1029 * @param zt_addr 0-terminated string. May be mangled by the function. 1038 * @param zt_addr 0-terminated string. May be mangled by the function.
1030 * @param addrlen length of zt_addr (not counting 0-terminator). 1039 * @param addrlen length of zt_addr (not counting 0-terminator).
@@ -1036,36 +1045,33 @@ int
1036GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr, uint16_t addrlen, 1045GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr, uint16_t addrlen,
1037 struct sockaddr_in *r_buf) 1046 struct sockaddr_in *r_buf)
1038{ 1047{
1039 unsigned int temps[5]; 1048 unsigned int temps[4];
1040 unsigned int port; 1049 unsigned int port;
1041 int cnt; 1050 unsigned int cnt;
1042 1051
1043 if (addrlen < 9) 1052 if (addrlen < 9)
1044 return GNUNET_SYSERR; 1053 return GNUNET_SYSERR;
1045
1046 cnt = SSCANF (zt_addr, "%u.%u.%u.%u:%u", &temps[0], &temps[1], &temps[2], &temps[3], &port); 1054 cnt = SSCANF (zt_addr, "%u.%u.%u.%u:%u", &temps[0], &temps[1], &temps[2], &temps[3], &port);
1047 if (cnt != 5) 1055 if (5 != cnt)
1048 return GNUNET_SYSERR; 1056 return GNUNET_SYSERR;
1049
1050 for (cnt = 0; cnt < 4; cnt++) 1057 for (cnt = 0; cnt < 4; cnt++)
1051 if (temps[cnt] > 0xFF) 1058 if (temps[cnt] > 0xFF)
1052 return GNUNET_SYSERR; 1059 return GNUNET_SYSERR;
1053 if (port > 65535) 1060 if (port > 65535)
1054 return GNUNET_SYSERR; 1061 return GNUNET_SYSERR;
1055
1056
1057
1058 r_buf->sin_family = AF_INET; 1062 r_buf->sin_family = AF_INET;
1059 r_buf->sin_port = htons (port); 1063 r_buf->sin_port = htons (port);
1060 r_buf->sin_addr.s_addr = htonl ((temps[0] << 24) + (temps[1] << 16) + 1064 r_buf->sin_addr.s_addr = htonl ((temps[0] << 24) + (temps[1] << 16) +
1061 (temps[2] << 8) + temps[3]); 1065 (temps[2] << 8) + temps[3]);
1066#if HAVE_SOCKADDR_IN_SIN_LEN
1067 r_buf->sin_len = (u_char) sizeof (struct sockaddr_in);
1068#endif
1062 return GNUNET_OK; 1069 return GNUNET_OK;
1063} 1070}
1064 1071
1072
1065/** 1073/**
1066 * Tries to convert 'addr' string to an IP (v4 or v6) address. 1074 * Tries to convert 'addr' string to an IP (v4 or v6) address.
1067 * IPv6 address must have its address part enclosed in '()' parens
1068 * instead of '[]'.
1069 * Will automatically decide whether to treat 'addr' as v4 or v6 address. 1075 * Will automatically decide whether to treat 'addr' as v4 or v6 address.
1070 * 1076 *
1071 * @param addr a string, may not be 0-terminated. 1077 * @param addr a string, may not be 0-terminated.
@@ -1080,39 +1086,10 @@ GNUNET_STRINGS_to_address_ip (const char *addr,
1080 uint16_t addrlen, 1086 uint16_t addrlen,
1081 struct sockaddr_storage *r_buf) 1087 struct sockaddr_storage *r_buf)
1082{ 1088{
1083 uint16_t i; 1089 if (GNUNET_OK ==
1084 char zt_addr[MAX_IP_ADDRLEN + 1]; 1090 GNUNET_STRINGS_to_address_ipv6 (addr, addrlen, (struct sockaddr_in6 *) r_buf))
1085 uint16_t zt_len = addrlen <= MAX_IP_ADDRLEN ? addrlen : MAX_IP_ADDRLEN; 1091 return GNUNET_OK;
1086 1092 return GNUNET_STRINGS_to_address_ipv4 (addr, addrlen, (struct sockaddr_in *) r_buf);
1087 if (addrlen < 1)
1088 return GNUNET_SYSERR;
1089
1090 memset (zt_addr, 0, MAX_IP_ADDRLEN + 1);
1091 strncpy (zt_addr, addr, zt_len);
1092
1093 /* For URIs we use '(' and ')' instead of '[' and ']'. Do the substitution
1094 * now, as GNUNET_STRINGS_to_address_ipv6() takes a proper []-enclosed IPv6
1095 * address.
1096 */
1097 if (zt_addr[0] == '(')
1098 {
1099 for (i = 0; i < zt_len; i++)
1100 {
1101 switch (zt_addr[i])
1102 {
1103 case '(':
1104 zt_addr[i] = '[';
1105 break;
1106 case ')':
1107 zt_addr[i] = ']';
1108 break;
1109 default:
1110 break;
1111 }
1112 }
1113 return GNUNET_STRINGS_to_address_ipv6 (zt_addr, zt_len, (struct sockaddr_in6 *) r_buf);
1114 }
1115 return GNUNET_STRINGS_to_address_ipv4 (zt_addr, zt_len, (struct sockaddr_in *) r_buf);
1116} 1093}
1117 1094
1118/* end of strings.c */ 1095/* end of strings.c */