aboutsummaryrefslogtreecommitdiff
path: root/kms/client/kms_client.c
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2024-05-13 21:22:29 +0200
committerdec05eba <dec05eba@protonmail.com>2024-05-13 21:22:29 +0200
commitc01eb535136a0f4b2545a8a8df0d9b3c527cd02f (patch)
tree8da3ac4152efbbae5b56045cd600a5ab8e22d609 /kms/client/kms_client.c
parent133c3a22b9cf3a55ebda19ce2af6db2e236462f1 (diff)
fix possible freeze on exit if exiting quickly after startHEADmaster
Diffstat (limited to 'kms/client/kms_client.c')
-rw-r--r--kms/client/kms_client.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/kms/client/kms_client.c b/kms/client/kms_client.c
index 1c8f634..869bf81 100644
--- a/kms/client/kms_client.c
+++ b/kms/client/kms_client.c
@@ -79,7 +79,7 @@ static int send_msg_to_server(int server_fd, gsr_kms_request *request) {
return sendmsg(server_fd, &response_message, 0);
}
-static int recv_msg_from_server(int server_fd, gsr_kms_response *response) {
+static int recv_msg_from_server(int server_pid, int server_fd, gsr_kms_response *response) {
struct iovec iov;
iov.iov_base = response;
iov.iov_len = sizeof(*response);
@@ -93,11 +93,26 @@ static int recv_msg_from_server(int server_fd, gsr_kms_response *response) {
response_message.msg_control = cmsgbuf;
response_message.msg_controllen = sizeof(cmsgbuf);
- int res = recvmsg(server_fd, &response_message, MSG_WAITALL);
- if(res <= 0)
- return res;
+ int res = 0;
+ for(;;) {
+ res = recvmsg(server_fd, &response_message, MSG_DONTWAIT);
+ if(res <= 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
+ // If we are replacing the connection and closing the application at the same time
+ // then recvmsg can get stuck (because the server died), so we prevent that by doing
+ // non-blocking recvmsg and checking if the server died
+ int status = 0;
+ int wait_result = waitpid(server_pid, &status, WNOHANG);
+ if(wait_result != 0) {
+ res = -1;
+ break;
+ }
+ usleep(1000);
+ } else {
+ break;
+ }
+ }
- if(response->num_fds > 0) {
+ if(res > 0 && response->num_fds > 0) {
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&response_message);
if(cmsg) {
int *fds = (int*)CMSG_DATA(cmsg);
@@ -371,7 +386,7 @@ int gsr_kms_client_replace_connection(gsr_kms_client *self) {
return -1;
}
- const int recv_res = recv_msg_from_server(self->socket_pair[GSR_SOCKET_PAIR_LOCAL], &response);
+ const int recv_res = recv_msg_from_server(self->kms_server_pid, self->socket_pair[GSR_SOCKET_PAIR_LOCAL], &response);
if(recv_res == 0) {
fprintf(stderr, "gsr warning: gsr_kms_client_replace_connection: kms server shut down\n");
return -1;
@@ -404,7 +419,7 @@ int gsr_kms_client_get_kms(gsr_kms_client *self, gsr_kms_response *response) {
return -1;
}
- const int recv_res = recv_msg_from_server(self->socket_pair[GSR_SOCKET_PAIR_LOCAL], response);
+ const int recv_res = recv_msg_from_server(self->kms_server_pid, self->socket_pair[GSR_SOCKET_PAIR_LOCAL], response);
if(recv_res == 0) {
fprintf(stderr, "gsr warning: gsr_kms_client_get_kms: kms server shut down\n");
strcpy(response->err_msg, "failed to receive");