diff options
-rw-r--r-- | common/dlm-protocol.c | 83 | ||||
-rw-r--r-- | common/dlm-protocol.h | 2 | ||||
-rw-r--r-- | drm-lease-manager/lease-server.c | 32 | ||||
-rw-r--r-- | drm-lease-manager/test/test-socket-client.c | 36 | ||||
-rw-r--r-- | libdlmclient/dlmclient.c | 73 |
5 files changed, 110 insertions, 116 deletions
diff --git a/common/dlm-protocol.c b/common/dlm-protocol.c index 4fc87b2..79aa86f 100644 --- a/common/dlm-protocol.c +++ b/common/dlm-protocol.c @@ -64,3 +64,86 @@ bool send_dlm_client_request(int socket, struct dlm_client_request *request) } return true; } + +int receive_lease_fd(int socket) +{ + int lease_fd = -1; + char ctrl_buf[CMSG_SPACE(sizeof(lease_fd))]; + + char data; + struct iovec iov = {.iov_base = &data, .iov_len = sizeof(data)}; + struct msghdr msg = { + .msg_iov = &iov, + .msg_iovlen = 1, + .msg_control = ctrl_buf, + .msg_controllen = sizeof(ctrl_buf), + }; + + ssize_t len; + while ((len = recvmsg(socket, &msg, 0)) <= 0) { + if (len == 0) { + errno = EACCES; + goto err; + } + + if (errno != EINTR) + goto err; + } + + struct cmsghdr *cmsg; + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_RIGHTS) { + int nfds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int); + int *fds = (int *)CMSG_DATA(cmsg); + + if (nfds == 1) { + lease_fd = fds[0]; + break; + } + + /* Close any unexpected fds so we don't leak them. */ + for (int i = 0; i < nfds; i++) + close(fds[i]); + break; + } + } + + if (lease_fd < 0) { + errno = EPROTO; + goto err; + } + +err: + return lease_fd; +} + +bool send_lease_fd(int socket, int lease) +{ + char data; + struct iovec iov = { + .iov_base = &data, + .iov_len = sizeof(data), + }; + + char ctrl_buf[CMSG_SPACE(sizeof(lease))] = {0}; + + struct msghdr msg = { + .msg_iov = &iov, + .msg_iovlen = 1, + .msg_controllen = sizeof(ctrl_buf), + .msg_control = ctrl_buf, + }; + + struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(sizeof(lease)); + *((int *)CMSG_DATA(cmsg)) = lease; + + if (sendmsg(socket, &msg, 0) < 0) + return false; + + return true; +} diff --git a/common/dlm-protocol.h b/common/dlm-protocol.h index 44785e5..c7e1327 100644 --- a/common/dlm-protocol.h +++ b/common/dlm-protocol.h @@ -29,4 +29,6 @@ struct dlm_client_request { bool receive_dlm_client_request(int socket, struct dlm_client_request *request); bool send_dlm_client_request(int socket, struct dlm_client_request *request); +int receive_lease_fd(int socket); +bool send_lease_fd(int socket, int lease); #endif diff --git a/drm-lease-manager/lease-server.c b/drm-lease-manager/lease-server.c index ac4dd01..c81d363 100644 --- a/drm-lease-manager/lease-server.c +++ b/drm-lease-manager/lease-server.c @@ -346,39 +346,21 @@ bool ls_send_fd(struct ls *ls, struct ls_client *client, int fd) assert(ls); assert(client); + struct ls_server *serv = client->serv; + if (fd < 0) return false; - char data[1]; - struct iovec iov = { - .iov_base = data, - .iov_len = sizeof(data), - }; - - char ctrl_buf[CMSG_SPACE(sizeof(int))] = {0}; - - struct msghdr msg = { - .msg_iov = &iov, - .msg_iovlen = 1, - .msg_controllen = sizeof(ctrl_buf), - .msg_control = ctrl_buf, - }; - - struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(sizeof(int)); - *((int *)CMSG_DATA(cmsg)) = fd; - - struct ls_server *serv = client->serv; - - if (sendmsg(client->socket.fd, &msg, 0) < 0) { + if (!send_lease_fd(client->socket.fd, fd)) { DEBUG_LOG("sendmsg failed on %s: %s\n", serv->address.sun_path, strerror(errno)); return false; } - INFO_LOG("Lease request granted on %s\n", serv->address.sun_path); + if (fd > 0) + INFO_LOG("Lease request granted on %s\n", + serv->address.sun_path); + return true; } diff --git a/drm-lease-manager/test/test-socket-client.c b/drm-lease-manager/test/test-socket-client.c index 9d191ff..fa26500 100644 --- a/drm-lease-manager/test/test-socket-client.c +++ b/drm-lease-manager/test/test-socket-client.c @@ -66,40 +66,6 @@ static void client_gst_socket_status(int socket_fd, struct test_config *config) return; } -static int receive_fd_from_socket(int sockfd) -{ - union { - struct cmsghdr align; - char buf[CMSG_SPACE(sizeof(int))]; - } u; - - char data; - struct iovec iov = {.iov_base = &data, .iov_len = sizeof(data)}; - struct msghdr msg = { - .msg_iov = &iov, - .msg_iovlen = 1, - .msg_control = u.buf, - .msg_controllen = sizeof(u.buf), - }; - - if (recvmsg(sockfd, &msg, 0) < 0) - return -1; - - int recv_fd = -1; - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - ck_assert_int_eq(cmsg->cmsg_level, SOL_SOCKET); - - if (cmsg->cmsg_type != SCM_RIGHTS) - continue; - - int nfds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int); - ck_assert_int_eq(nfds, 1); - recv_fd = *(int *)CMSG_DATA(cmsg); - } - return recv_fd; -} - static void *test_client_thread(void *arg) { struct client_state *cstate = arg; @@ -132,7 +98,7 @@ static void *test_client_thread(void *arg) client_gst_socket_status(client, config); if (config->has_data) { - config->received_fd = receive_fd_from_socket(client); + config->received_fd = receive_lease_fd(client); } cstate->socket_fd = client; diff --git a/libdlmclient/dlmclient.c b/libdlmclient/dlmclient.c index 03c08a8..dbe2609 100644 --- a/libdlmclient/dlmclient.c +++ b/libdlmclient/dlmclient.c @@ -82,66 +82,27 @@ static bool lease_send_request(struct dlm_lease *lease, enum dlm_opcode opcode) static bool lease_recv_fd(struct dlm_lease *lease) { - char ctrl_buf[CMSG_SPACE(sizeof(int))] = {0}; - char data[1] = {0}; - - struct iovec iov[1]; - iov[0].iov_base = data; - iov[0].iov_len = sizeof(data); - - struct msghdr msg = { - .msg_control = ctrl_buf, - .msg_controllen = CMSG_SPACE(sizeof(int)), - .msg_iov = iov, - .msg_iovlen = 1, - }; + lease->lease_fd = receive_lease_fd(lease->dlm_server_sock); - int ret; - while ((ret = recvmsg(lease->dlm_server_sock, &msg, 0)) <= 0) { - if (ret == 0) { - errno = EACCES; - DEBUG_LOG("Request rejected by DRM lease manager\n"); - // TODO: Report why the request was rejected. - return false; - } - if (errno != EINTR) { - DEBUG_LOG("Socket data receive error: %s\n", - strerror(errno)); - return false; - } - } + if (lease->lease_fd < 0) + goto err; - lease->lease_fd = -1; - struct cmsghdr *cmsg; - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level == SOL_SOCKET && - cmsg->cmsg_type == SCM_RIGHTS) { - int nfds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int); - int *fds = (int *)CMSG_DATA(cmsg); - - if (nfds == 1) { - lease->lease_fd = fds[0]; - break; - } - - DEBUG_LOG( - "Expected 1 fd from lease manager. Received %d\n", - nfds); - /* Close any unexpected fds so we don't leak them. */ - for (int i = 0; i < nfds; i++) - close(fds[i]); - break; - } - } + return true; - if (lease->lease_fd < 0) { - DEBUG_LOG("Expected data not received from lease manager\n"); - errno = EPROTO; - return false; +err: + switch (errno) { + case EACCES: + DEBUG_LOG("Lease request rejected by DRM lease manager\n"); + break; + case EPROTO: + DEBUG_LOG("Unexpected data received from lease manager\n"); + break; + default: + DEBUG_LOG("Lease manager receive data error: %s\n", + strerror(errno)); + break; } - - return true; + return false; } struct dlm_lease *dlm_get_lease(const char *name) |