From: RYAN D. MOATS <rmo...@us.ibm.com> Allow TCP connection strings to also use DNS names in addition to IPv4 and IPv6 addresses. Updated test case "ovsdb-client get-schema-version - tcp socket" to verify.
Signed-off-by: RYAN D. MOATS <rmo...@us.ibm.com> --- lib/stream-tcp.c | 66 +++++++++++++++++++++++++++++++++++++++++++++--- tests/ovsdb-server.at | 2 + 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/lib/stream-tcp.c b/lib/stream-tcp.c index fc5a606..483ff77 100644 --- a/lib/stream-tcp.c +++ b/lib/stream-tcp.c @@ -15,6 +15,7 @@ */ #include <config.h> +#include <ctype.h> #include "stream.h" #include <errno.h> #include <inttypes.h> @@ -48,17 +49,72 @@ new_tcp_stream(const char *name, int fd, int connect_status, return new_fd_stream(name, fd, connect_status, AF_INET, streamp); } +static bool +is_name_dns(char *suffix) +{ + char *c = suffix; + if (*c == '[') { + return false; + } + while (*c && *c != ':') { + if (isalpha(*c) || *c == '-') { + return true; + } + c++; + } + return false; +} + static int tcp_open(const char *name, char *suffix, struct stream **streamp, uint8_t dscp) { int fd, error; - error = inet_open_active(SOCK_STREAM, suffix, 0, NULL, &fd, dscp); - if (fd >= 0) { - return new_tcp_stream(name, fd, error, streamp); - } else { - VLOG_ERR("%s: connect: %s", name, ovs_strerror(error)); + /* if suffix begins with a domain name, rather than either an IPv4 + * or IPv6 address, then make a call to getaddrinfo to get the IP + * addresses for this call. we'll loop through trying to connect + * to each one and fail if we get through all of them without a + * successful connection. */ + if (is_name_dns(suffix)) { + char *c = strchr(suffix, ':'); + *c = 0; + struct addrinfo hints; + struct addrinfo *servinfo, *p; + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_INET; //TODO: make this work with IPv6 + hints.ai_socktype = SOCK_STREAM; + int status = getaddrinfo(suffix, c+1, &hints, &servinfo); + *c = ':'; + if (status != 0) { + VLOG_ERR("%s: getaddrinfo: %s", name, ovs_strerror(status)); + return status; + } + for (p = servinfo; p != NULL; p = p->ai_next) { + char ipv4str[15]; + struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr; + void *addr = &(ipv4->sin_addr); + inet_ntop(p->ai_family, addr, ipv4str, sizeof ipv4str); + char *new_suffix = xasprintf("%s:%s", ipv4str, c+1); + error = inet_open_active(SOCK_STREAM, new_suffix, 0, NULL, &fd, + dscp); + free(new_suffix); + if (fd >= 0) { + freeaddrinfo(servinfo); + return new_tcp_stream(name, fd, error, streamp); + } + } + freeaddrinfo(servinfo); + VLOG_ERR("%s: can not connect, last error: %s", name, + ovs_strerror(error)); return error; + } else { + error = inet_open_active(SOCK_STREAM, suffix, 0, NULL, &fd, dscp); + if (fd >= 0) { + return new_tcp_stream(name, fd, error, streamp); + } else { + VLOG_ERR("%s: connect: %s", name, ovs_strerror(error)); + return error; + } } } diff --git a/tests/ovsdb-server.at b/tests/ovsdb-server.at index c869d6f..44c93b8 100644 --- a/tests/ovsdb-server.at +++ b/tests/ovsdb-server.at @@ -854,6 +854,8 @@ AT_CHECK([ovsdb-server --log-file --detach --no-chdir --pidfile="`pwd`"/pid --un PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT]) AT_CHECK([ovsdb-client get-schema-version tcp:127.0.0.1:$TCP_PORT ordinals], [0], [5.1.3 ]) +AT_CHECK([ovsdb-client get-schema-version tcp:localhost:$TCP_PORT ordinals], [0], [5.1.3 +]) OVSDB_SERVER_SHUTDOWN AT_CLEANUP]) -- 1.7.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev