diff --git a/src/box/replica.cc b/src/box/replica.cc
index 70757da09c48ffe6c70950988035a1f3e7703798..42f2a7ce9b513c78fab8f58a1754053d29accae0 100644
--- a/src/box/replica.cc
+++ b/src/box/replica.cc
@@ -108,7 +108,7 @@ remote_connect(struct recovery_state *r, struct ev_io *coio,
 	char service[URI_MAXSERVICE];
 	snprintf(service, sizeof(service), "%.*s", (int) uri->service_len,
 		 uri->service);
-	coio_connect(coio, host, service, &remote->addr, &remote->addr_len);
+	coio_connect(coio, host, service, &remote->addr, &remote->addr_len, 0);
 	assert(coio->fd >= 0);
 	coio_readn(coio, greeting, sizeof(greeting));
 
diff --git a/src/coio.cc b/src/coio.cc
index 612bdd90da0a905cd21f77d0b0a8d5bfae18212b..48fca73e42246acf6205c6a595c8113fb4476de5 100644
--- a/src/coio.cc
+++ b/src/coio.cc
@@ -32,6 +32,7 @@
 #include <sys/un.h>
 #include <netinet/tcp.h>
 #include <stdio.h>
+#include <arpa/inet.h>
 
 #include "iobuf.h"
 #include "sio.h"
@@ -146,7 +147,7 @@ coio_connect_addr(struct ev_io *coio, struct sockaddr *addr,
 int
 coio_connect_timeout(struct ev_io *coio, const char *host, const char *service,
 		     struct sockaddr *addr, socklen_t *addr_len,
-		     ev_tstamp timeout)
+		     ev_tstamp timeout, int host_hint)
 {
 	/* try to resolve a hostname */
 	struct ev_loop *loop = loop();
@@ -170,11 +171,33 @@ coio_connect_timeout(struct ev_io *coio, const char *host, const char *service,
 		return 0;
 	}
 
-	struct addrinfo *ai = coeio_resolve(SOCK_STREAM, host, service, delay);
+	struct addrinfo *ai = NULL;
+	struct addrinfo ai_local;
+	if (host_hint) {
+		ai_local.ai_next = NULL;
+		if (host_hint == 1) { // IPv4
+			ai_local.ai_addrlen = sizeof(sockaddr_in);
+			ai_local.ai_addr = (sockaddr*)malloc(ai_local.ai_addrlen);
+			memset(ai_local.ai_addr, 0, ai_local.ai_addrlen);
+			((sockaddr_in*)ai_local.ai_addr)->sin_family = AF_INET;
+			((sockaddr_in*)ai_local.ai_addr)->sin_port = htons((uint16_t)atoi(service));
+			inet_pton(AF_INET, host, &((sockaddr_in*)ai_local.ai_addr)->sin_addr);
+		} else { // IPv6
+			ai_local.ai_addrlen = sizeof(sockaddr_in6);
+			ai_local.ai_addr = (sockaddr*)malloc(ai_local.ai_addrlen);
+			memset(ai_local.ai_addr, 0, ai_local.ai_addrlen);
+			((sockaddr_in6*)ai_local.ai_addr)->sin6_family = AF_INET6;
+			((sockaddr_in6*)ai_local.ai_addr)->sin6_port = htons((uint16_t)atoi(service));
+			inet_pton(AF_INET6, host, &((sockaddr_in6*)ai_local.ai_addr)->sin6_addr);
+		}
+		ai = &ai_local;
+	} else {
+		ai = coeio_resolve(SOCK_STREAM, host, service, delay);
+	}
 	if (ai == NULL)
 		return -1; /* timeout */
 
-	auto addrinfo_guard = make_scoped_guard([=]{ freeaddrinfo(ai); });
+	auto addrinfo_guard = make_scoped_guard([=]{ if (!host_hint) freeaddrinfo(ai); else free(ai_local.ai_addr); });
 	evio_timeout_update(loop(), start, &delay);
 
 	coio_timeout_init(&start, &delay, timeout);
@@ -595,7 +618,7 @@ coio_service_on_accept(struct evio_service *evio_service,
 	 * Start the created fiber. It becomes the coio object owner
 	 * and will have to close it and free before termination.
 	 */
-	fiber_call(f, coio, addr, iobuf, service->handler_param);
+	fiber_call(f, coio, addr, addrlen, iobuf, service->handler_param);
 }
 
 void
diff --git a/src/coio.h b/src/coio.h
index 25bf23ede9a8a72877c80187a45f989a5d99d879..702602ca126b29990d91a829a9b269dce20c0bac 100644
--- a/src/coio.h
+++ b/src/coio.h
@@ -47,14 +47,14 @@ struct coio_service
 int
 coio_connect_timeout(struct ev_io *coio, const char *host, const char *service,
 		     struct sockaddr *addr, socklen_t *addr_len,
-		     ev_tstamp timeout);
+		     ev_tstamp timeout, int host_hint);
 
 static inline int
 coio_connect(struct ev_io *coio, const char *host, const char *service,
-	     struct sockaddr *addr, socklen_t *addr_len)
+	     struct sockaddr *addr, socklen_t *addr_len, int host_hint)
 {
 	return coio_connect_timeout(coio, host, service, addr, addr_len,
-				    TIMEOUT_INFINITY);
+				    TIMEOUT_INFINITY, host_hint);
 }
 
 void