From b9776b2a5e8fa45749148e34c3f2df6ec4249ead Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Thu, 24 May 2018 17:01:44 -0400 Subject: [PATCH] Factor out hostname parsing for reuse --- common/tr_aaa_server.c | 103 ++----------------------------------------------- common/tr_util.c | 98 +++++++++++++++++++++++++++++++++++++++++++++- include/tr_util.h | 4 ++ 3 files changed, 104 insertions(+), 101 deletions(-) diff --git a/common/tr_aaa_server.c b/common/tr_aaa_server.c index 7345783..193f018 100644 --- a/common/tr_aaa_server.c +++ b/common/tr_aaa_server.c @@ -38,6 +38,7 @@ #include #include #include +#include static int tr_aaa_server_destructor(void *obj) { @@ -117,84 +118,6 @@ void tr_aaa_server_set_port(TR_AAA_SERVER *aaa, int port) } /** - * Parse the port from a hostname:port string - * - * @param s string to parse - * @return the specified port, 0 if none specified, -1 if invalid - */ -static int tr_aaa_server_parse_port(const char *s) -{ - const char *s_port; - char *end_of_conversion; - long int port; /* long instead of int because we use strtol */ - - /* Find the first colon */ - s_port = strchr(s, ':'); /* port starts at s_port + 1 */ - if (s_port == NULL) - return 0; /* no port */ - - /* Check that the last colon is the same as the first */ - if (strrchr(s, ':') != s_port) - return -1; /* multiple colons are invalid*/ - - s_port += 1; /* port now starts at s_port */ - - /* Parse the port number */ - port = strtol(s, &end_of_conversion, /* base */ 10); - - /* validate */ - if ((end_of_conversion == s_port) /* there was no port, just a colon */ - || (*end_of_conversion != '\0') /* did not reach the end of the string */ - || (port <= 0) || (port > 65535)) { - return -1; - } - - return (int) port; -} - -/** - * Parse a hostname out of a hostname:port string - * - * The ":port" section is optional. Ignores the string after the first colon. - * Does not validate the port section of the name. - * - * An empty hostname is allowed (but s must not be null) - * - * @param s - * @return TR_NAME or null on error (i.e., out-of-memory) - */ -static TR_NAME *tr_aaa_server_parse_hostname(const char *s) -{ - const char *colon; - char *hostname; - size_t hostname_len; - TR_NAME *retval; - - if (s == NULL) - return NULL; - - /* find the colon */ - colon = strchr(s, ':'); - if (colon == NULL) - return tr_new_name(s); /* there was no colon, take the whole string */ - - /* make a copy of the hostname portion of the string */ - hostname_len = colon - s; - hostname = malloc(hostname_len + 1); /* +1 for the null termination */ - if (hostname == NULL) - return NULL; - - /* copy up to the colon, add a null termination, and make a TR_NAME */ - strncpy(hostname, s, hostname_len); - hostname[hostname_len] = '\0'; - retval = tr_new_name(hostname); - - /* clean up and return */ - free(hostname); - return retval; -} - -/** * Allocate a AAA server record and fill it in by parsing a hostname:port string * * Does not validate hostname or port values. The port will be -1 if the port @@ -210,11 +133,11 @@ TR_AAA_SERVER *tr_aaa_server_from_string(TALLOC_CTX *mem_ctx, const char *s) if (aaa == NULL) goto failed; - tr_aaa_server_set_hostname(aaa, tr_aaa_server_parse_hostname(s)); + tr_aaa_server_set_hostname(aaa, tr_parse_hostname(s)); if (tr_aaa_server_get_hostname(aaa) == NULL) goto failed; - tr_aaa_server_set_port(aaa, tr_aaa_server_parse_port(s)); + tr_aaa_server_set_port(aaa, tr_parse_port(s)); talloc_steal(mem_ctx, aaa); /*put this in the caller's context */ goto succeeded; @@ -226,26 +149,6 @@ succeeded: return aaa; } - -/** - * Allocate a AAA server record and fill it in by parsing a hostname:port TR_NAME - * - * Does not validate hostname or port values. The port will be -1 if the port - * could not be parsed properly. - * - * @return newly allocated TR_AAA_SERVER in the mem_ctx context, or NULL on error - */ -TR_AAA_SERVER *tr_aaa_server_from_name(TALLOC_CTX *mem_ctx, TR_NAME *n) -{ - TR_AAA_SERVER *aaa = NULL; - char *s = tr_name_strdup(n); - if (s != NULL) { - aaa = tr_aaa_server_from_string(mem_ctx, s); - free(s); - } - return aaa; -} - TR_AAA_SERVER_ITER *tr_aaa_server_iter_new(TALLOC_CTX *mem_ctx) { return talloc(mem_ctx, TR_AAA_SERVER_ITER); diff --git a/common/tr_util.c b/common/tr_util.c index 2e59606..527a743 100644 --- a/common/tr_util.c +++ b/common/tr_util.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -209,4 +210,99 @@ struct timespec *tr_clock_convert(clockid_t from, const struct timespec *when, return NULL; } return dst; -} \ No newline at end of file +} + +TR_NAME *tr_parse_hostname(const char *s) +{ + const char *colon; + char *hostname; + size_t hostname_len; + TR_NAME *retval; + + if (s == NULL) + return NULL; + + /* find the colon */ + colon = strchr(s, ':'); + if (colon == NULL) + return tr_new_name(s); /* there was no colon, take the whole string */ + + /* make a copy of the hostname portion of the string */ + hostname_len = colon - s; + hostname = malloc(hostname_len + 1); /* +1 for the null termination */ + if (hostname == NULL) + return NULL; + + /* copy up to the colon, add a null termination, and make a TR_NAME */ + strncpy(hostname, s, hostname_len); + hostname[hostname_len] = '\0'; + retval = tr_new_name(hostname); + + /* clean up and return */ + free(hostname); + return retval; +} + +/** + * Parse the port from a hostname:port string + * + * @param s string to parse + * @return the specified port, 0 if none specified, -1 if invalid + */ +int tr_parse_port(const char *s) +{ + const char *s_port; + char *end_of_conversion; + long int port; /* long instead of int because we use strtol */ + + /* Find the first colon */ + s_port = strchr(s, ':'); /* port starts at s_port + 1 */ + if (s_port == NULL) + return 0; /* no port */ + + /* Check that the last colon is the same as the first */ + if (strrchr(s, ':') != s_port) + return -1; /* multiple colons are invalid*/ + + s_port += 1; /* port now starts at s_port */ + + /* Parse the port number */ + port = strtol(s, &end_of_conversion, /* base */ 10); + + /* validate */ + if ((end_of_conversion == s_port) /* there was no port, just a colon */ + || (*end_of_conversion != '\0') /* did not reach the end of the string */ + || (port <= 0) || (port > 65535)) { + return -1; + } + + return (int) port; +} + +/** + * Parse hostname and port + * + * @param s + * @param hn_dest + * @param p_dest + * @return 0 on success, -1 on error + */ +int tr_parse_hostname_and_port(const char *s, TR_NAME **hn_dest, int *p_dest) +{ + if ((hn_dest == NULL) || (p_dest == NULL)) + return -1; + + *hn_dest = tr_parse_hostname(s); + if (*hn_dest == NULL) + return -1; + + *p_dest = tr_parse_port(s); + if ((*p_dest < 0) || (*p_dest > 65535)) { + tr_free_name(*hn_dest); + *hn_dest = NULL; + return -1; + } + + return 0; +} + diff --git a/include/tr_util.h b/include/tr_util.h index 9bf7d8e..d1e2d03 100644 --- a/include/tr_util.h +++ b/include/tr_util.h @@ -35,6 +35,7 @@ #ifndef TR_UTIL_H #define TR_UTIL_H +#include #include /* NB, tr_bin_to_hex() is also prototyped in trust_router/tr_dh.h */ @@ -46,5 +47,8 @@ int tr_sub_timespec(const struct timespec *ts1_copy, const struct timespec *ts2_ char *timespec_to_str(const struct timespec *ts); struct timespec *tr_clock_convert(clockid_t from, const struct timespec *when, clockid_t to, struct timespec *dst); +TR_NAME *tr_parse_hostname(const char *s); +int tr_parse_port(const char *s); +int tr_parse_hostname_and_port(const char *s, TR_NAME **hn_dest, int *p_dest); #endif /* TR_UTIL_H */ -- 2.1.4