diff --git a/src/lib/core/sio.c b/src/lib/core/sio.c
index bb8e508d94549d661d39f29879231555f5fb6d19..8f25b8159a45f6ad7463d5d09af7f4a3650c4dd7 100644
--- a/src/lib/core/sio.c
+++ b/src/lib/core/sio.c
@@ -293,6 +293,16 @@ sio_getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen)
 	return 0;
 }
 
+int
+sio_getsockname(int fd, struct sockaddr *addr, socklen_t *addrlen)
+{
+	if (getsockname(fd, addr, addrlen) < 0) {
+		diag_set(SocketError, sio_socketname(fd), "getsockname");
+		return -1;
+	}
+	return 0;
+}
+
 const char *
 sio_strfaddr(const struct sockaddr *addr, socklen_t addrlen)
 {
diff --git a/src/lib/core/sio.h b/src/lib/core/sio.h
index f0998e2f357290a47fe13e05c5bc41d443f610ed..093b5f5baa6c4245814ed5b5ac5fdf7a3dc3eee4 100644
--- a/src/lib/core/sio.h
+++ b/src/lib/core/sio.h
@@ -86,6 +86,21 @@ sio_strfaddr(const struct sockaddr *addr, socklen_t addrlen);
 int
 sio_getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen);
 
+/**
+ * Fill @a addr with a real address currently bound to @a fd
+ * socket.
+ *
+ * @param fd Socket.
+ * @param[out] addr An address structure to fill.
+ * @param[in][out] addlen On input it is a size of @a addr as a
+ *                 buffer. On output it becomes a size of a new
+ *                 content of @a addr.
+ * @retval 0 Success.
+ * @retval -1 Error.
+ */
+int
+sio_getsockname(int fd, struct sockaddr *addr, socklen_t *addrlen);
+
 /**
  * Advance write position in the iovec array
  * based on its current value and the number of
diff --git a/test/unit/sio.c b/test/unit/sio.c
index 84a86aac3f037fe05e6132ef5ee6394650525e66..dffdd5592d100c8addf71c3373b4fe9a6ed9e81d 100644
--- a/test/unit/sio.c
+++ b/test/unit/sio.c
@@ -78,6 +78,26 @@ check_uri_to_addr(void)
 	footer();
 }
 
+static void
+check_auto_bind(void)
+{
+	header();
+	plan(3);
+
+	struct sockaddr_in addr;
+	socklen_t addrlen = sizeof(addr);
+	sio_uri_to_addr("127.0.0.1:0", (struct sockaddr *) &addr);
+	int fd = sio_socket(AF_INET, SOCK_STREAM, 0);
+	is(sio_bind(fd, (struct sockaddr *) &addr, sizeof(addr)), 0,
+	   "bind to 0 works");
+	is(sio_getsockname(fd, (struct sockaddr *) &addr, &addrlen), 0,
+	   "getsockname works on 0 bind");
+	isnt(addr.sin_port, 0, "a real port is returned");
+
+	check_plan();
+	footer();
+}
+
 int
 main(void)
 {
@@ -85,8 +105,9 @@ main(void)
 	fiber_init(fiber_c_invoke);
 
 	header();
-	plan(1);
+	plan(2);
 	check_uri_to_addr();
+	check_auto_bind();
 	int rc = check_plan();
 	footer();
 
diff --git a/test/unit/sio.result b/test/unit/sio.result
index 32a5babae6ceb36bea5cd38818fe0d1769506713..e5712ad3ccf03b24e7f5bb80e39b4051dd5d8f4d 100644
--- a/test/unit/sio.result
+++ b/test/unit/sio.result
@@ -1,5 +1,5 @@
 	*** main ***
-1..1
+1..2
 	*** check_uri_to_addr ***
     1..18
     ok 1 - invalid uri is detected
@@ -22,4 +22,11 @@
     ok 18 - invalid IP
 ok 1 - subtests
 	*** check_uri_to_addr: done ***
+	*** check_auto_bind ***
+    1..3
+    ok 1 - bind to 0 works
+    ok 2 - getsockname works on 0 bind
+    ok 3 - a real port is returned
+ok 2 - subtests
+	*** check_auto_bind: done ***
 	*** main: done ***