Skip to content
Snippets Groups Projects
Commit 37d66377 authored by Vladislav Shpilevoy's avatar Vladislav Shpilevoy
Browse files

sio: implement getsockname wrapper

SWIM wants to allow to bind to zero ports so as the kernel could
choose any free port automatically. It is needed mainly for
tests.

Zero port means that a real port is known only after bind() has
called, and getsockname() should be used to get it. SWIM uses sio
library for such lowlevel API. This is why that function is added
to sio.

Needed for #3234
parent 3fb69c15
No related merge requests found
......@@ -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)
{
......
......@@ -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
......
......@@ -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();
......
*** 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 ***
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment