aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/dlm-protocol.c83
-rw-r--r--common/dlm-protocol.h2
-rw-r--r--drm-lease-manager/lease-server.c32
-rw-r--r--drm-lease-manager/test/test-socket-client.c36
-rw-r--r--libdlmclient/dlmclient.c73
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)