1 /* Copyright 2020-2021 IGEL Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 #include "dlmclient.h"
18 #include "dlm-protocol.h"
20 #include "socket-path.h"
28 #include <sys/socket.h>
32 void dlm_enable_debug_log(bool enable)
34 dlm_log_enable_debug(enable);
42 static bool lease_connect(struct dlm_lease *lease, const char *name)
44 struct sockaddr_un sa = {
45 .sun_family = AF_UNIX,
48 if (!sockaddr_set_lease_server_path(&sa, name))
51 int dlm_server_sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
52 if (dlm_server_sock < 0) {
53 DEBUG_LOG("Socket creation failed: %s\n", strerror(errno));
57 while (connect(dlm_server_sock, (struct sockaddr *)&sa,
58 sizeof(struct sockaddr_un)) == -1) {
61 DEBUG_LOG("Cannot connect to %s: %s\n", sa.sun_path,
63 close(dlm_server_sock);
66 lease->dlm_server_sock = dlm_server_sock;
70 static bool lease_send_request(struct dlm_lease *lease, enum dlm_opcode opcode)
72 struct dlm_client_request request = {
76 if (!send_dlm_client_request(lease->dlm_server_sock, &request)) {
77 DEBUG_LOG("Socket data send error: %s\n", strerror(errno));
83 static bool lease_recv_fd(struct dlm_lease *lease)
85 char ctrl_buf[CMSG_SPACE(sizeof(int))] = {0};
89 iov[0].iov_base = data;
90 iov[0].iov_len = sizeof(data);
93 .msg_control = ctrl_buf,
94 .msg_controllen = CMSG_SPACE(sizeof(int)),
100 while ((ret = recvmsg(lease->dlm_server_sock, &msg, 0)) <= 0) {
103 DEBUG_LOG("Request rejected by DRM lease manager\n");
104 // TODO: Report why the request was rejected.
107 if (errno != EINTR) {
108 DEBUG_LOG("Socket data receive error: %s\n",
114 lease->lease_fd = -1;
115 struct cmsghdr *cmsg;
116 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
117 cmsg = CMSG_NXTHDR(&msg, cmsg)) {
118 if (cmsg->cmsg_level == SOL_SOCKET &&
119 cmsg->cmsg_type == SCM_RIGHTS) {
120 int nfds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
121 int *fds = (int *)CMSG_DATA(cmsg);
124 lease->lease_fd = fds[0];
129 "Expected 1 fd from lease manager. Received %d\n",
131 /* Close any unexpected fds so we don't leak them. */
132 for (int i = 0; i < nfds; i++)
138 if (lease->lease_fd < 0) {
139 DEBUG_LOG("Expected data not received from lease manager\n");
147 struct dlm_lease *dlm_get_lease(const char *name)
150 struct dlm_lease *lease = calloc(1, sizeof(struct dlm_lease));
152 DEBUG_LOG("can't allocate memory : %s\n", strerror(errno));
156 if (!lease_connect(lease, name)) {
161 if (!lease_send_request(lease, DLM_GET_LEASE))
164 if (!lease_recv_fd(lease))
171 dlm_release_lease(lease);
176 void dlm_release_lease(struct dlm_lease *lease)
181 lease_send_request(lease, DLM_RELEASE_LEASE);
182 close(lease->lease_fd);
183 close(lease->dlm_server_sock);
187 int dlm_lease_fd(struct dlm_lease *lease)
192 return lease->lease_fd;