virSocketSendMsgWithFDs method send fds along with payload using SCM_RIGHTS. virSocketRecvHttpResponse method polls, receives http response on the input socket and returns the http response code. These methods are required to add network suppport in ch driver. Signed-off-by: Praveen K Paladugu <prapal@xxxxxxxxxxxxxxxxxxx> --- po/POTFILES | 1 + src/libvirt_private.syms | 2 + src/util/virsocket.c | 109 +++++++++++++++++++++++++++++++++++++++ src/util/virsocket.h | 3 ++ 4 files changed, 115 insertions(+) diff --git a/po/POTFILES b/po/POTFILES index 023c041f61..b594a8dd39 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -326,6 +326,7 @@ src/util/virscsi.c src/util/virscsihost.c src/util/virscsivhost.c src/util/virsecret.c +src/util/virsocket.c src/util/virsocketaddr.c src/util/virstoragefile.c src/util/virstring.c diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 680a90034a..e643cea774 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3371,7 +3371,9 @@ virSecureEraseString; # util/virsocket.h virSocketRecvFD; +virSocketRecvHttpResponse; virSocketSendFD; +virSocketSendMsgWithFDs; # util/virsocketaddr.h diff --git a/src/util/virsocket.c b/src/util/virsocket.c index cd6f7ecd1b..b11e53a215 100644 --- a/src/util/virsocket.c +++ b/src/util/virsocket.c @@ -22,8 +22,14 @@ #include "virsocket.h" #include "virutil.h" #include "virfile.h" +#include "virlog.h" #include <fcntl.h> +#include <poll.h> + +#define PKT_TIMEOUT_MS 500 /* ms */ + +VIR_LOG_INIT("util.virsocket"); #ifdef WIN32 @@ -482,6 +488,109 @@ virSocketRecvFD(int sock, int fdflags) return fd; } + +/** + * virSocketSendMsgWithFDs: + * @sock: socket to send payload and fds to + * @payload: payload to send + * @fds: array of fds to send + * @fds_len: len of fds array + + * Send @fds along with @payload to @sock using SCM_RIGHTS. + * Return number of bytes sent on success, or -1 on error. + */ +int +virSocketSendMsgWithFDs(int sock, const char *payload, int *fds, size_t fds_len) +{ + struct msghdr msg; + struct iovec iov[1]; /* Send a single payload, so set vector len to 1 */ + int ret; + char control[CMSG_SPACE(sizeof(int)*fds_len)]; + struct cmsghdr *cmsg; + + memset(&msg, 0, sizeof(msg)); + memset(control, 0, sizeof(control)); + + iov[0].iov_base = (void *) payload; + iov[0].iov_len = strlen(payload); + + msg.msg_iov = iov; + msg.msg_iovlen = 1; + + msg.msg_control = control; + msg.msg_controllen = sizeof(control); + + cmsg = CMSG_FIRSTHDR(&msg); + if (!cmsg) { + VIR_ERROR(_("Couldn't fit control msg header in msg")); + return -1; + } + cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fds_len); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + memcpy(CMSG_DATA(cmsg), fds, sizeof(int) * fds_len); + + do { + ret = sendmsg(sock, &msg, 0); + } while (ret < 0 && errno == EINTR); + + if (ret < 0) + return -1; + + return ret; +} + +/** + * virSocketRecvHttpResponse: + * @sock: socket to receive http response on + * + * This function polls @sock for HTTP response + * Returns HTTP response code from received message, or -1 on error. + */ +int virSocketRecvHttpResponse(int sock) +{ + struct pollfd pfds[1]; + /* This is only used for responses from ch guests, which fit within + * 1024 buffer + */ + char buf[1024]; + int response_code, ret; + + pfds[0].fd = sock; + pfds[0].events = POLLIN; + + do { + ret = poll(pfds, G_N_ELEMENTS(pfds), PKT_TIMEOUT_MS); + } while (ret < 0 && errno == EINTR); + + if (ret <= 0) { + if (ret < 0) { + VIR_ERROR(_("Poll on sock %1$d failed"), sock); + } else if (ret == 0) { + VIR_ERROR(_("Poll on sock %1$d timed out"), sock); + } + return -1; + } + + do { + ret = recv(sock, buf, sizeof(buf), 0); + } while (ret < 0 && errno == EINTR); + + if (ret < 0) { + VIR_ERROR(_("recv on sock %1$d failed"), sock); + return -1; + } + + /* Parse the HTTP response code */ + ret = sscanf(buf, "HTTP/1.%*d %d", &response_code); + if (ret != 1) { + VIR_ERROR(_("Failed to parse HTTP response code")); + return -1; + } + + return response_code; +} + #else /* WIN32 */ int virSocketSendFD(int sock G_GNUC_UNUSED, int fd G_GNUC_UNUSED) diff --git a/src/util/virsocket.h b/src/util/virsocket.h index 419da8b3ae..9190a6a569 100644 --- a/src/util/virsocket.h +++ b/src/util/virsocket.h @@ -22,6 +22,9 @@ int virSocketSendFD(int sock, int fd); int virSocketRecvFD(int sock, int fdflags); +int virSocketSendMsgWithFDs(int sock, const char *payload, int *fds, + size_t fd_len); +int virSocketRecvHttpResponse(int sock); #ifdef WIN32 -- 2.41.0 _______________________________________________ Devel mailing list -- devel@xxxxxxxxxxxxxxxxx To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxx