Bugfix: IPC: Correctly handle the case when multiple messages get received at once via the socket
When the sending application was so fast (*cough*) that the messages could get queued by the kernel, it may happen that we receive multiple messages at once.
This commit is contained in:
parent
acb07b95c0
commit
3779f9292f
42
src/ipc.c
42
src/ipc.c
|
@ -77,10 +77,16 @@ static void ipc_handle_message(uint8_t *message, int size,
|
||||||
LOG("payload as a string = %s\n", message);
|
LOG("payload as a string = %s\n", message);
|
||||||
|
|
||||||
switch (message_type) {
|
switch (message_type) {
|
||||||
case I3_IPC_MESSAGE_TYPE_COMMAND:
|
case I3_IPC_MESSAGE_TYPE_COMMAND: {
|
||||||
parse_command(global_conn, (const char*)message);
|
/* To get a properly terminated buffer, we copy
|
||||||
|
* message_size bytes out of the buffer */
|
||||||
|
char *command = scalloc(message_size);
|
||||||
|
strncpy(command, (const char*)message, message_size);
|
||||||
|
parse_command(global_conn, (const char*)command);
|
||||||
|
free(command);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
LOG("unhandled ipc message\n");
|
LOG("unhandled ipc message\n");
|
||||||
break;
|
break;
|
||||||
|
@ -148,20 +154,30 @@ static void ipc_receive_message(EV_P_ struct ev_io *w, int revents) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *message = (uint8_t*)buf;
|
uint8_t *message = (uint8_t*)buf;
|
||||||
message += strlen(I3_IPC_MAGIC);
|
while (n > 0) {
|
||||||
n -= strlen(I3_IPC_MAGIC);
|
LOG("IPC: n = %d\n", n);
|
||||||
|
message += strlen(I3_IPC_MAGIC);
|
||||||
|
n -= strlen(I3_IPC_MAGIC);
|
||||||
|
|
||||||
/* The next 32 bit after the magic are the message size */
|
/* The next 32 bit after the magic are the message size */
|
||||||
uint32_t message_size = *((uint32_t*)message);
|
uint32_t message_size = *((uint32_t*)message);
|
||||||
message += sizeof(uint32_t);
|
message += sizeof(uint32_t);
|
||||||
n -= sizeof(uint32_t);
|
n -= sizeof(uint32_t);
|
||||||
|
|
||||||
/* The last 32 bits of the header are the message type */
|
if (message_size > n) {
|
||||||
uint32_t message_type = *((uint32_t*)message);
|
LOG("IPC: Either the message size was wrong or the message was not read completely, dropping\n");
|
||||||
message += sizeof(uint32_t);
|
return;
|
||||||
n -= sizeof(uint32_t);
|
}
|
||||||
|
|
||||||
ipc_handle_message(message, n, message_size, message_type);
|
/* The last 32 bits of the header are the message type */
|
||||||
|
uint32_t message_type = *((uint32_t*)message);
|
||||||
|
message += sizeof(uint32_t);
|
||||||
|
n -= sizeof(uint32_t);
|
||||||
|
|
||||||
|
ipc_handle_message(message, n, message_size, message_type);
|
||||||
|
n -= message_size;
|
||||||
|
message += message_size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue