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. Signed-off-by: Frediano Ziglio <fziglio@xxxxxxxxxx> --- 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 c4487b79..eea0b443 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) @@ -147,6 +152,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.20.1 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel