@@ -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;
+ }
}
}
@@ -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])