2019-06-03 21:25:59 +02:00
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
|
2019-06-12 15:02:43 +02:00
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
|
2018-10-09 13:20:26 +02:00
|
|
|
|
#include "message.h"
|
2016-12-21 01:26:47 +01:00
|
|
|
|
#include "usocket.h"
|
|
|
|
|
|
2019-07-27 15:46:04 +02:00
|
|
|
|
// #define IPC_WITH_ERRORS 3
|
2016-12-21 01:26:47 +01:00
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
uint32_t ipc_message_raw_serialize (char *buffer, char type, char user_type, char *message, uint32_t message_size)
|
2019-06-03 21:25:59 +02:00
|
|
|
|
{
|
2019-07-27 15:46:04 +02:00
|
|
|
|
uint32_t msize = 6 + message_size;
|
|
|
|
|
buffer[0] = type;
|
2019-06-03 21:25:59 +02:00
|
|
|
|
|
2019-07-27 15:46:04 +02:00
|
|
|
|
uint32_t msize_n = htonl (message_size);
|
|
|
|
|
uint32_t index = 1;
|
2019-06-03 21:25:59 +02:00
|
|
|
|
|
2019-07-27 15:46:04 +02:00
|
|
|
|
memcpy (buffer + index, &msize_n, sizeof (uint32_t));
|
|
|
|
|
index += sizeof (uint32_t);
|
|
|
|
|
buffer[index] = user_type;
|
|
|
|
|
index += 1;
|
|
|
|
|
memcpy (buffer + index, message, message_size);
|
2019-06-03 21:25:59 +02:00
|
|
|
|
|
2019-07-27 15:46:04 +02:00
|
|
|
|
return msize;
|
2019-06-03 21:25:59 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
struct ipc_error ipc_message_format_read (struct ipc_message *m, const char *buf, size_t msize)
|
2019-07-27 15:46:04 +02:00
|
|
|
|
{
|
2020-01-01 12:11:34 +01:00
|
|
|
|
T_R ((m == NULL), IPC_ERROR_MESSAGE_FORMAT_READ__EMPTY_MESSAGE);
|
|
|
|
|
T_R ((buf == NULL), IPC_ERROR_MESSAGE_FORMAT_READ__EMPTY_BUFFER);
|
|
|
|
|
T_R ((msize > IPC_MAX_MESSAGE_SIZE), IPC_ERROR_MESSAGE_FORMAT_READ__PARAM_MESSAGE_SIZE);
|
2016-12-21 01:26:47 +01:00
|
|
|
|
|
2019-06-04 01:35:33 +02:00
|
|
|
|
// message format:
|
|
|
|
|
// Type (1 B) | Length (4 B) | UserType (1 B) | Payload (Length B)
|
2020-01-01 12:11:34 +01:00
|
|
|
|
m->type = buf[0];
|
2019-07-27 15:46:04 +02:00
|
|
|
|
uint32_t unformated_size = 0;
|
2020-01-01 12:11:34 +01:00
|
|
|
|
memcpy (&unformated_size, buf + 1, sizeof (uint32_t));
|
2019-06-12 15:02:43 +02:00
|
|
|
|
m->length = ntohl (unformated_size);
|
2019-06-04 01:35:33 +02:00
|
|
|
|
m->user_type = buf[1 + sizeof m->length];
|
2016-12-21 01:26:47 +01:00
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
T_R ((m->length > IPC_MAX_MESSAGE_SIZE), IPC_ERROR_MESSAGE_FORMAT_READ__MESSAGE_TOO_LONG);
|
2018-10-10 23:18:15 +02:00
|
|
|
|
#if defined(IPC_WITH_ERRORS) && IPC_WITH_ERRORS > 2
|
2020-01-01 12:11:34 +01:00
|
|
|
|
LOG_INFO ("receiving msg: type %d, paylen %u, total %lu", m->type, m->length, msize);
|
2018-10-10 23:18:15 +02:00
|
|
|
|
#endif
|
2020-01-01 12:11:34 +01:00
|
|
|
|
T_R ((m->length != msize - IPC_HEADER_SIZE && m->length != 0)
|
|
|
|
|
, IPC_ERROR_MESSAGE_FORMAT_READ__READ_MESSAGE_SIZE);
|
2016-12-21 01:26:47 +01:00
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
if (m->payload != NULL) {
|
|
|
|
|
free (m->payload);
|
2018-10-30 13:18:53 +01:00
|
|
|
|
m->payload = NULL;
|
|
|
|
|
}
|
2016-12-21 01:26:47 +01:00
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
if (m->length > 0) {
|
|
|
|
|
m->payload = malloc (m->length);
|
|
|
|
|
memcpy (m->payload, buf + IPC_HEADER_SIZE, m->length);
|
|
|
|
|
} else {
|
|
|
|
|
m->payload = malloc (1);
|
2019-06-12 15:02:43 +02:00
|
|
|
|
}
|
2016-12-21 01:26:47 +01:00
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
IPC_RETURN_NO_ERROR;
|
2016-12-21 01:26:47 +01:00
|
|
|
|
}
|
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
struct ipc_error ipc_message_format_write (const struct ipc_message *m, char **buf, size_t * msize)
|
2016-12-21 01:26:47 +01:00
|
|
|
|
{
|
2020-01-01 12:11:34 +01:00
|
|
|
|
T_R ((m == NULL), IPC_ERROR_MESSAGE_FORMAT_WRITE__EMPTY_MESSAGE);
|
|
|
|
|
T_R ((buf == NULL), IPC_ERROR_MESSAGE_FORMAT_WRITE__EMPTY_BUFFER);
|
|
|
|
|
T_R ((msize == NULL), IPC_ERROR_MESSAGE_FORMAT_WRITE__EMPTY_MSIZE);
|
|
|
|
|
T_R ((m->length > IPC_MAX_MESSAGE_SIZE), IPC_ERROR_MESSAGE_FORMAT_WRITE__MESSAGE_LENGTH);
|
2016-12-21 01:26:47 +01:00
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
if (*buf == NULL) {
|
|
|
|
|
*buf = malloc (IPC_HEADER_SIZE + m->length);
|
2018-10-12 01:59:56 +02:00
|
|
|
|
memset (*buf, 0, IPC_HEADER_SIZE + m->length);
|
2020-01-01 12:11:34 +01:00
|
|
|
|
}
|
2016-12-21 02:56:52 +01:00
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
char *buffer = *buf;
|
|
|
|
|
uint32_t net_paylen = htonl (m->length);
|
2016-12-21 01:26:47 +01:00
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
buffer[0] = m->type;
|
|
|
|
|
memcpy (buffer + 1, &net_paylen, sizeof (uint32_t));
|
|
|
|
|
buffer[1 + sizeof m->length] = m->user_type;
|
2019-06-12 15:02:43 +02:00
|
|
|
|
if (m->payload != NULL && m->length > 0) {
|
2018-10-12 01:59:56 +02:00
|
|
|
|
memcpy (buffer + IPC_HEADER_SIZE, m->payload, m->length);
|
2018-10-04 22:51:31 +02:00
|
|
|
|
}
|
2016-12-21 02:56:52 +01:00
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
*msize = IPC_HEADER_SIZE + m->length;
|
2016-12-21 01:26:47 +01:00
|
|
|
|
|
2018-10-10 23:18:15 +02:00
|
|
|
|
#if defined(IPC_WITH_ERRORS) && IPC_WITH_ERRORS > 2
|
2019-07-27 15:46:04 +02:00
|
|
|
|
LOG_INFO ("sending msg: type %u, paylen %u, msize %lu", m->type, m->length, *msize);
|
2018-10-10 23:18:15 +02:00
|
|
|
|
#endif
|
2018-10-04 22:51:31 +02:00
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
IPC_RETURN_NO_ERROR;
|
2016-12-21 01:26:47 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MSG FORMAT
|
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
struct ipc_error ipc_message_format (struct ipc_message *m, char type, char utype, const char *payload, size_t length)
|
2016-12-21 01:26:47 +01:00
|
|
|
|
{
|
2019-07-27 15:46:04 +02:00
|
|
|
|
T_R ((m == NULL), IPC_ERROR_MESSAGE_FORMAT__NO_MESSAGE_PARAM);
|
|
|
|
|
T_R ((length > IPC_MAX_MESSAGE_SIZE), IPC_ERROR_MESSAGE_FORMAT__MESSAGE_SIZE);
|
|
|
|
|
T_R (((length == 0 && payload != NULL) || (length > 0 && payload == NULL))
|
2020-01-01 12:11:34 +01:00
|
|
|
|
, IPC_ERROR_MESSAGE_FORMAT__INCONSISTENT_PARAMS);
|
2016-12-21 01:26:47 +01:00
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
m->type = type;
|
|
|
|
|
m->user_type = utype;
|
|
|
|
|
m->length = (uint32_t) length;
|
2016-12-21 02:56:52 +01:00
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
if (payload != NULL) {
|
2018-10-04 22:51:31 +02:00
|
|
|
|
if (m->payload != NULL) {
|
|
|
|
|
free (m->payload);
|
|
|
|
|
}
|
2018-10-08 15:18:56 +02:00
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
SECURE_BUFFER_HEAP_ALLOCATION_R (m->payload, length,, IPC_ERROR_MESSAGE_FORMAT__HEAP_ALLOCATION);
|
2018-10-04 22:51:31 +02:00
|
|
|
|
}
|
2016-12-21 02:56:52 +01:00
|
|
|
|
|
2018-10-04 22:51:31 +02:00
|
|
|
|
if (payload != NULL) {
|
|
|
|
|
memcpy (m->payload, payload, length);
|
|
|
|
|
}
|
2020-01-01 12:11:34 +01:00
|
|
|
|
IPC_RETURN_NO_ERROR;
|
2016-12-21 01:26:47 +01:00
|
|
|
|
}
|
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
struct ipc_error ipc_message_format_data (struct ipc_message *m, char utype, const char *payload, size_t length)
|
2016-12-21 01:26:47 +01:00
|
|
|
|
{
|
2020-01-01 12:11:34 +01:00
|
|
|
|
return ipc_message_format (m, MSG_TYPE_DATA, utype, payload, length);
|
2016-12-21 01:26:47 +01:00
|
|
|
|
}
|
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
struct ipc_error ipc_message_format_server_close (struct ipc_message *m)
|
2018-10-04 22:51:31 +02:00
|
|
|
|
{
|
2020-01-01 12:11:34 +01:00
|
|
|
|
return ipc_message_format (m, MSG_TYPE_SERVER_CLOSE, 0, NULL, 0);
|
2018-10-04 22:51:31 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
struct ipc_error ipc_message_empty (struct ipc_message *m)
|
2016-12-21 01:26:47 +01:00
|
|
|
|
{
|
2020-01-01 12:11:34 +01:00
|
|
|
|
T_R ((m == NULL), IPC_ERROR_MESSAGE_EMPTY__EMPTY_MESSAGE_LIST);
|
2016-12-21 01:26:47 +01:00
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
if (m->payload != NULL) {
|
|
|
|
|
free (m->payload);
|
2018-10-30 13:18:53 +01:00
|
|
|
|
m->payload = NULL;
|
|
|
|
|
}
|
2016-12-21 02:56:52 +01:00
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
m->length = 0;
|
2016-12-21 01:26:47 +01:00
|
|
|
|
|
2020-01-01 12:11:34 +01:00
|
|
|
|
IPC_RETURN_NO_ERROR;
|
2016-12-21 01:26:47 +01:00
|
|
|
|
}
|
2020-07-13 14:12:08 +02:00
|
|
|
|
|
|
|
|
|
// store and remove only pointers on allocated structures
|
|
|
|
|
struct ipc_error ipc_messages_add (struct ipc_messages *messages, const struct ipc_message *message)
|
|
|
|
|
{
|
|
|
|
|
T_R ((messages == NULL), IPC_ERROR_ADD_MESSAGE_TO_SEND__NO_PARAM_MESSAGES);
|
|
|
|
|
T_R ((message == NULL), IPC_ERROR_ADD_MESSAGE_TO_SEND__NO_PARAM_MESSAGE);
|
|
|
|
|
|
|
|
|
|
messages->size++;
|
|
|
|
|
if (messages->size == 1 && messages->messages == NULL) {
|
|
|
|
|
// first allocation
|
|
|
|
|
SECURE_BUFFER_HEAP_ALLOCATION_R (messages->messages, sizeof (struct ipc_message),,
|
|
|
|
|
IPC_ERROR_ADD_MESSAGE_TO_SEND__MALLOC);
|
|
|
|
|
} else {
|
|
|
|
|
messages->messages = realloc (messages->messages, sizeof (struct ipc_message) * messages->size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
T_R ((messages->messages == NULL), IPC_ERROR_ADD_MESSAGE_TO_SEND__EMPTY_LIST);
|
|
|
|
|
|
|
|
|
|
// DEEP COPY.
|
|
|
|
|
messages->messages[messages->size -1] = *message;
|
|
|
|
|
if (message->length > 0 && message->payload != NULL) {
|
|
|
|
|
messages->messages[messages->size -1].payload = malloc(message->length * sizeof (char));
|
|
|
|
|
strncpy(messages->messages[messages->size -1].payload, message->payload, message->length);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
messages->messages[messages->size -1].payload = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IPC_RETURN_NO_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Remove only pointers on allocated structures.
|
|
|
|
|
struct ipc_error ipc_messages_del (struct ipc_messages *messages, uint32_t index)
|
|
|
|
|
{
|
|
|
|
|
T_R ((messages == NULL), IPC_ERROR_DEL_MESSAGE_TO_SEND__NO_PARAM_MESSAGES);
|
|
|
|
|
T_R ((messages->size == 0 || index >= messages->size), IPC_ERROR_MESSAGE_DEL__INDEX_ERROR);
|
|
|
|
|
|
|
|
|
|
// NOT A DEEP COPY.
|
|
|
|
|
messages->size--;
|
|
|
|
|
if (messages->size == 0) {
|
|
|
|
|
free (messages->messages);
|
|
|
|
|
messages->messages = NULL;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
messages->messages[index] = messages->messages[messages->size];
|
|
|
|
|
messages->messages = realloc (messages->messages, sizeof (struct ipc_message) * messages->size);
|
|
|
|
|
T_R ((messages->messages == NULL), IPC_ERROR_MESSAGE_DEL__EMPTY_LIST);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IPC_RETURN_NO_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ipc_message_copy (struct ipc_message *m
|
|
|
|
|
, uint32_t fd
|
|
|
|
|
, uint8_t type
|
|
|
|
|
, uint8_t utype
|
|
|
|
|
, char *payload
|
|
|
|
|
, uint32_t paylen)
|
|
|
|
|
{
|
|
|
|
|
// printf("starting the message copy\n");
|
|
|
|
|
m->fd = fd;
|
|
|
|
|
m->type = type;
|
|
|
|
|
m->user_type = utype;
|
|
|
|
|
m->length = paylen;
|
|
|
|
|
if (m->payload != NULL) {
|
|
|
|
|
free(m->payload);
|
|
|
|
|
}
|
|
|
|
|
// printf("BEFORE THE PAYLOAD COPY\n");
|
|
|
|
|
m->payload = malloc(sizeof(char) * paylen);
|
|
|
|
|
memcpy(m->payload, payload, paylen);
|
|
|
|
|
// printf("PAYLOAD COPY DONE\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ipc_messages_free (struct ipc_messages *messages)
|
|
|
|
|
{
|
|
|
|
|
if (messages != NULL)
|
|
|
|
|
{
|
|
|
|
|
if (messages->messages != NULL)
|
|
|
|
|
{
|
|
|
|
|
free(messages->messages);
|
|
|
|
|
messages->messages = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|