[Spice-devel] [PATCH spice-server 06/33] sys-socket: Add socket_newpair utility

Marc-André Lureau marcandre.lureau at gmail.com
Sat Dec 22 10:11:35 UTC 2018


Hi

On Fri, Dec 21, 2018 at 4:03 PM Frediano Ziglio <fziglio at redhat.com> wrote:
>
> Allows to easier port socketpair.
> Windows does not have this function, we need to create a pair
> using 2 internet sockets and connecting one to the other.

Have you considered namedpipes instead?


>
> Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
> ---
>  server/sys-socket.c | 75 +++++++++++++++++++++++++++++++++++++++++++++
>  server/sys-socket.h |  7 +++++
>  2 files changed, 82 insertions(+)
>
> diff --git a/server/sys-socket.c b/server/sys-socket.c
> index 7ce5dab1..af2f0b83 100644
> --- a/server/sys-socket.c
> +++ b/server/sys-socket.c
> @@ -209,4 +209,79 @@ SPICE_CONSTRUCTOR_FUNC(socket_win32_init)
>      WSADATA wsaData;
>      WSAStartup(MAKEWORD(2, 2), &wsaData);
>  }
> +
> +int socket_newpair(int type, int protocol, socket_t sv[2])
> +{
> +    struct sockaddr_in sa, sa2;
> +    socklen_t addrlen;
> +    SOCKET s, pairs[2];
> +
> +    if (!sv) {
> +        return -1;
> +    }
> +
> +    /* create a listener */
> +    s = socket(AF_INET, type, 0);
> +    if (s == INVALID_SOCKET) {
> +        return -1;
> +    }
> +
> +    pairs[1] = INVALID_SOCKET;
> +
> +    pairs[0] = socket(AF_INET, type, 0);
> +    if (pairs[0] == INVALID_SOCKET) {
> +        goto cleanup;
> +    }
> +
> +    /* bind to a random port */
> +    sa.sin_family = AF_INET;
> +    sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
> +    sa.sin_port = 0;
> +    if (bind(s, (struct sockaddr*) &sa, sizeof(sa)) < 0) {
> +        goto cleanup;
> +    }
> +    if (listen(s, 1) < 0) {
> +        goto cleanup;
> +    }
> +
> +    /* connect to kernel choosen port */
> +    addrlen = sizeof(sa);
> +    if (getsockname(s, (struct sockaddr*) &sa, &addrlen) < 0) {
> +        goto cleanup;
> +    }
> +    if (connect(pairs[0], (struct sockaddr*) &sa, sizeof(sa)) < 0) {
> +        goto cleanup;
> +    }
> +    addrlen = sizeof(sa2);
> +    pairs[1] = accept(s, (struct sockaddr*) &sa2, &addrlen);
> +    if (pairs[1] == INVALID_SOCKET) {
> +        goto cleanup;
> +    }
> +
> +    /* check proper connection */
> +    addrlen = sizeof(sa);
> +    if (getsockname(pairs[0], (struct sockaddr*) &sa, &addrlen) < 0) {
> +        goto cleanup;
> +    }
> +    addrlen = sizeof(sa2);
> +    if (getpeername(pairs[1], (struct sockaddr*) &sa2, &addrlen) < 0) {
> +        goto cleanup;
> +    }
> +    if (sa.sin_family != sa2.sin_family || sa.sin_port != sa2.sin_port
> +        || sa.sin_addr.s_addr != sa2.sin_addr.s_addr) {
> +        goto cleanup;
> +    }
> +
> +    closesocket(s);
> +    sv[0] = SOCKET_FROM_INT(pairs[0]);
> +    sv[1] = SOCKET_FROM_INT(pairs[1]);
> +    return 0;
> +
> +cleanup:
> +    socket_win32_set_errno();
> +    closesocket(s);
> +    closesocket(pairs[0]);
> +    closesocket(pairs[1]);
> +    return -1;
> +}
>  #endif
> diff --git a/server/sys-socket.h b/server/sys-socket.h
> index c21e9a69..9dca563b 100644
> --- a/server/sys-socket.h
> +++ b/server/sys-socket.h
> @@ -56,6 +56,11 @@ static inline void socket_win32_set_errno(void)
>  {
>  }
>
> +static inline int socket_newpair(int type, int protocol, socket_t sv[2])
> +{
> +    return socketpair(AF_LOCAL, type, protocol, (int*) sv);
> +}
> +
>  #define socket_read(sock, buf, len) read(socket_get_raw(sock), buf, len)
>  #define socket_write(sock, buf, len) write(socket_get_raw(sock), buf, len)
>  #define socket_writev(sock, iov, n) writev(socket_get_raw(sock), iov, n)
> @@ -170,6 +175,8 @@ socket_listen(socket_t sock, int backlog)
>      }
>      return res;
>  }
> +
> +int socket_newpair(int type, int protocol, socket_t sv[2]);
>  #endif
>
>  // common part
> --
> 2.17.2
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/spice-devel



--
Marc-André Lureau


More information about the Spice-devel mailing list