diff options
Diffstat (limited to '')
-rw-r--r-- | src/libmdsserver/mds-message.c | 12 | ||||
-rw-r--r-- | src/libmdsserver/mds-message.h | 12 | ||||
-rw-r--r-- | src/mds-server/client.c | 124 | ||||
-rw-r--r-- | src/mds-server/client.h | 126 | ||||
-rw-r--r-- | src/mds-server/interception_condition.c | 76 | ||||
-rw-r--r-- | src/mds-server/interception_condition.h | 86 | ||||
-rw-r--r-- | src/mds-server/mds-server.c | 3 | ||||
-rw-r--r-- | src/mds-server/mds-server.h | 125 | ||||
-rw-r--r-- | src/mds-server/queued_interception.h | 51 |
9 files changed, 480 insertions, 135 deletions
diff --git a/src/libmdsserver/mds-message.c b/src/libmdsserver/mds-message.c index eb5db4c..1f05579 100644 --- a/src/libmdsserver/mds-message.c +++ b/src/libmdsserver/mds-message.c @@ -34,7 +34,7 @@ * @return Non-zero on error, errno will be set accordingly. * Destroy the message on error. */ -int mds_message_initialise(mds_message_t* this) +int mds_message_initialise(mds_message_t* restrict this) { this->headers = NULL; this->header_count = 0; @@ -56,7 +56,7 @@ int mds_message_initialise(mds_message_t* this) * * @param this The message */ -void mds_message_destroy(mds_message_t* this) +void mds_message_destroy(mds_message_t* restrict this) { if (this->headers != NULL) { @@ -82,7 +82,7 @@ void mds_message_destroy(mds_message_t* this) * -2 indicates that the message is malformated, * which is a state that cannot be recovered from. */ -int mds_message_read(mds_message_t* this, int fd) +int mds_message_read(mds_message_t* restrict this, int fd) { size_t header_commit_buffer = 0; @@ -285,7 +285,7 @@ int mds_message_read(mds_message_t* this, int fd) * @param include_buffer Whether buffer should be marshalled (state serialisation, not communication) * @return The size of the message when marshalled */ -size_t mds_message_marshal_size(mds_message_t* this, int include_buffer) +size_t mds_message_marshal_size(const mds_message_t* restrict this, int include_buffer) { size_t rc = this->header_count + this->payload_size; size_t i; @@ -307,7 +307,7 @@ size_t mds_message_marshal_size(mds_message_t* this, int include_buffer) * @param data Output buffer for the marshalled data * @param include_buffer Whether buffer should be marshalled (state serialisation, not communication) */ -void mds_message_marshal(mds_message_t* this, char* data, int include_buffer) +void mds_message_marshal(const mds_message_t* restrict this, char* restrict data, int include_buffer) { size_t i, n; @@ -351,7 +351,7 @@ void mds_message_marshal(mds_message_t* this, char* data, int include_buffer) * @return Non-zero on error, errno will be set accordingly. * Destroy the message on error. */ -int mds_message_unmarshal(mds_message_t* this, char* data) +int mds_message_unmarshal(mds_message_t* restrict this, char* restrict data) { size_t i, n, header_count; diff --git a/src/libmdsserver/mds-message.h b/src/libmdsserver/mds-message.h index 0f07830..96a4d28 100644 --- a/src/libmdsserver/mds-message.h +++ b/src/libmdsserver/mds-message.h @@ -90,7 +90,7 @@ typedef struct mds_message * @return Non-zero on error, errno will be set accordingly. * Destroy the message on error. */ -int mds_message_initialise(mds_message_t* this); +int mds_message_initialise(mds_message_t* restrict this); /** * Release all resources in a message, should @@ -98,7 +98,7 @@ int mds_message_initialise(mds_message_t* this); * * @param this The message */ -void mds_message_destroy(mds_message_t* this); +void mds_message_destroy(mds_message_t* restrict this); /** * Read the next message from a file descriptor @@ -113,7 +113,7 @@ void mds_message_destroy(mds_message_t* this); * -2 indicates that the message is malformated, * which is a state that cannot be recovered from. */ -int mds_message_read(mds_message_t* this, int fd); +int mds_message_read(mds_message_t* restrict this, int fd); /** * Get the required allocation size for `data` of the @@ -123,7 +123,7 @@ int mds_message_read(mds_message_t* this, int fd); * @param include_buffer Whether buffer should be marshalled (state serialisation, not communication) * @return The size of the message when marshalled */ -size_t mds_message_marshal_size(mds_message_t* this, int include_buffer) __attribute__((pure)); +size_t mds_message_marshal_size(const mds_message_t* restrict this, int include_buffer) __attribute__((pure)); /** * Marshal a message, this can be used both when serialising @@ -134,7 +134,7 @@ size_t mds_message_marshal_size(mds_message_t* this, int include_buffer) __attri * @param data Output buffer for the marshalled data * @param include_buffer Whether buffer should be marshalled (state serialisation, not communication) */ -void mds_message_marshal(mds_message_t* this, char* data, int include_buffer); +void mds_message_marshal(const mds_message_t* restrict this, char* restrict data, int include_buffer); /** * Unmarshal a message, it is assumed that the buffer is marshalled @@ -144,7 +144,7 @@ void mds_message_marshal(mds_message_t* this, char* data, int include_buffer); * @return Non-zero on error, errno will be set accordingly. * Destroy the message on error. */ -int mds_message_unmarshal(mds_message_t* this, char* data); +int mds_message_unmarshal(mds_message_t* restrict this, char* restrict data); #endif diff --git a/src/mds-server/client.c b/src/mds-server/client.c new file mode 100644 index 0000000..13b291c --- /dev/null +++ b/src/mds-server/client.c @@ -0,0 +1,124 @@ +/** + * mds — A micro-display server + * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include "client.h" + +#include <libmdsserver/macros.h> + +#include <stdlib.h> +#include <string.h> + + + +/** + * Calculate the buffer size need to marshal client information + * + * @param this The client information + * @return The number of bytes to allocate to the output buffer + */ +size_t client_marshal_size(const client_t* restrict this) +{ + size_t n = sizeof(ssize_t) + 2 * sizeof(int) + sizeof(uint64_t) + 3 * sizeof(size_t); + size_t i; + + n += mds_message_marshal_size(&(this->message), 1); + for (i = 0; i < this->interception_conditions_count; i++) + n += interception_condition_marshal_size(this->interception_conditions + i); + n += this->send_pending_size * sizeof(char); + + return n; +} + + +/** + * Marshals an client information + * + * @param this The client information + * @param data Output buffer for the marshalled data + * @return The number of bytes that have been written (everything will be written) + */ +size_t client_marshal(const client_t* restrict this, char* restrict data) +{ + size_t i, n; + buf_set_next(data, ssize_t, this->list_entry); + buf_set_next(data, int, this->socket_fd); + buf_set_next(data, int, this->open); + buf_set_next(data, uint64_t, this->id); + n = mds_message_marshal_size(&(this->message), 1);; + buf_set_next(data, size_t, n); + mds_message_marshal(&(this->message), data, 1); + data += n / sizeof(char); + buf_set_next(data, size_t, this->interception_conditions_count); + for (i = 0; i < this->interception_conditions_count; i++) + data += interception_condition_marshal(this->interception_conditions + i, data) / sizeof(char); + buf_set_next(data, size_t, this->send_pending_size); + if (this->send_pending_size > 0) + memcpy(data, this->send_pending, this->send_pending_size * sizeof(char)); + return client_marshal_size(this); +} + + +/** + * Unmarshals an client information + * + * @param this Memory slot in which to store the new client information + * @param data In buffer with the marshalled data + * @return Zero on error, errno will be set accordingly, otherwise the number of read bytes + */ +size_t client_unmarshal(client_t* restrict this, char* restrict data) +{ + size_t i, n, rc = sizeof(ssize_t) + 2 * sizeof(int) + sizeof(uint64_t) + 3 * sizeof(size_t); + this->interception_conditions = NULL; + this->send_pending = NULL; + buf_get_next(data, ssize_t, this->list_entry); + buf_get_next(data, int, this->socket_fd); + buf_get_next(data, int, this->open); + buf_get_next(data, uint64_t, this->id); + buf_get_next(data, size_t, n); + if (mds_message_unmarshal(&(this->message), data)) + return 0; + data += n / sizeof(char); + rc += n; + buf_get_next(data, size_t, this->interception_conditions_count); + for (i = 0; i < this->interception_conditions_count; i++) + { + n = interception_condition_unmarshal(this->interception_conditions + i, data); + if (n == 0) + { + this->interception_conditions_count = i - 1; + goto fail; + } + data += n / sizeof(char); + rc += n; + } + buf_get_next(data, size_t, this->send_pending_size); + if (this->send_pending_size > 0) + { + if (xmalloc(this->send_pending, this->send_pending_size, char)) + goto fail; + memcpy(this->send_pending, data, this->send_pending_size * sizeof(char)); + } + return rc; + + fail: + for (i = 0; i < this->interception_conditions_count; i++) + free(this->interception_conditions[i].condition); + free(this->interception_conditions); + free(this->send_pending); + return 0; +} + diff --git a/src/mds-server/client.h b/src/mds-server/client.h new file mode 100644 index 0000000..a63f2b6 --- /dev/null +++ b/src/mds-server/client.h @@ -0,0 +1,126 @@ +/** + * mds — A micro-display server + * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef MDS_MDS_SERVER_CLIENT_H +#define MDS_MDS_SERVER_CLIENT_H + + +#include "interception_condition.h" + +#include <libmdsserver/mds-message.h> + +#include <stdlib.h> +#include <pthread.h> +#include <stdint.h> + + + +/** + * Client information structure + */ +typedef struct client +{ + /** + * The client's entry in the list of clients + */ + ssize_t list_entry; + + /** + * The socket file descriptor for the socket connected to the client + */ + int socket_fd; + + /** + * Whether the socket is open + */ + int open; + + /** + * Message read buffer for the client + */ + mds_message_t message; + + /** + * The read thread for the client + */ + pthread_t thread; + + /** + * The client's ID + */ + uint64_t id; + + /** + * Mutex for sending data and other + * actions that only affacts this client + */ + pthread_mutex_t mutex; + + /** + * The messages interception conditions conditions + * for the client + */ + interception_condition_t* interception_conditions; + + /** + * The number of interception conditions + */ + size_t interception_conditions_count; + + /** + * Messages pending to be sent (concatenated) + */ + char* send_pending; + + /** + * The character length of the messages pending to be sent + */ + size_t send_pending_size; + +} client_t; + + +/** + * Calculate the buffer size need to marshal client information + * + * @param this The client information + * @return The number of bytes to allocate to the output buffer + */ +size_t client_marshal_size(const client_t* restrict this) __attribute__((pure)); + +/** + * Marshals an client information + * + * @param this The client information + * @param data Output buffer for the marshalled data + * @return The number of bytes that have been written (everything will be written) + */ +size_t client_marshal(const client_t* restrict this, char* restrict data); + +/** + * Unmarshals an client information + * + * @param this Memory slot in which to store the new client information + * @param data In buffer with the marshalled data + * @return Zero on error, errno will be set accordingly, otherwise the number of read bytes. + * Destroy the client information on error. + */ +size_t client_unmarshal(client_t* restrict this, char* restrict data); + + +#endif + diff --git a/src/mds-server/interception_condition.c b/src/mds-server/interception_condition.c new file mode 100644 index 0000000..076bc19 --- /dev/null +++ b/src/mds-server/interception_condition.c @@ -0,0 +1,76 @@ +/** + * mds — A micro-display server + * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include "interception_condition.h" + +#include <libmdsserver/macros.h> + +#include <string.h> +#include <stdlib.h> + + + +/** + * Calculate the buffer size need to marshal an interception condition + * + * @param this The interception condition + * @return The number of bytes to allocate to the output buffer + */ +size_t interception_condition_marshal_size(const interception_condition_t* restrict this) +{ + return sizeof(size_t) + sizeof(int64_t) + sizeof(int) + (strlen(this->condition) + 1) * sizeof(char); +} + +/** + * Marshals an interception condition + * + * @param this The interception condition + * @param data Output buffer for the marshalled data + * @return The number of bytes that have been written (everything will be written) + */ +size_t interception_condition_marshal(const interception_condition_t* restrict this, char* restrict data) +{ + size_t n = (strlen(this->condition) + 1) * sizeof(char);; + buf_set_next(data, size_t, this->header_hash); + buf_set_next(data, int64_t, this->priority); + buf_set_next(data, int, this->modifying); + memcpy(data, this->condition, n); + return sizeof(size_t) + sizeof(int64_t) + sizeof(int) + n; +} + + +/** + * Unmarshals an interception condition + * + * @param this Memory slot in which to store the new interception condition + * @param data In buffer with the marshalled data + * @return Zero on error, errno will be set accordingly, otherwise the number of read bytes + */ +size_t interception_condition_unmarshal(interception_condition_t* restrict this, char* restrict data) +{ + size_t n; + this->condition = NULL; + buf_get_next(data, size_t, this->header_hash); + buf_get_next(data, int64_t, this->priority); + buf_get_next(data, int, this->modifying); + n = (strlen(data) + 1) * sizeof(char); + if ((this->condition = malloc(n)) == NULL) + return 0; + memcpy(this->condition, data, n); + return sizeof(size_t) + sizeof(int64_t) + sizeof(int) + n; +} + diff --git a/src/mds-server/interception_condition.h b/src/mds-server/interception_condition.h new file mode 100644 index 0000000..c80fab0 --- /dev/null +++ b/src/mds-server/interception_condition.h @@ -0,0 +1,86 @@ +/** + * mds — A micro-display server + * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef MDS_MDS_SERVER_INTERCEPTION_CONDITION_H +#define MDS_MDS_SERVER_INTERCEPTION_CONDITION_H + + +#include <stddef.h> +#include <stdint.h> + + +/** + * A condition for a message being intercepted by a client + */ +typedef struct interception_condition +{ + /** + * The header of messages to intercept, optionally with a value, + * empty (most not be NULL) for all messages. + */ + char* condition; + + /** + * The hash of the header of messages to intercept + */ + size_t header_hash; + + /** + * The interception priority. The client should be + * consistent with the priority for conditions that + * are not mutually exclusive. + */ + int64_t priority; + + /** + * Whether the messages may get modified by the client + */ + int modifying; + +} interception_condition_t; + + +/** + * Calculate the buffer size need to marshal an interception condition + * + * @param this The interception condition + * @return The number of bytes to allocate to the output buffer + */ +size_t interception_condition_marshal_size(const interception_condition_t* restrict this) __attribute__((pure)); + +/** + * Marshals an interception condition + * + * @param this The interception condition + * @param data Output buffer for the marshalled data + * @return The number of bytes that have been written (everything will be written) + */ +size_t interception_condition_marshal(const interception_condition_t* restrict this, char* restrict data); + +/** + * Unmarshals an interception condition + * + * @param this Memory slot in which to store the new interception condition + * @param data In buffer with the marshalled data + * @return Zero on error, errno will be set accordingly, otherwise the number of read bytes. + * Destroy the interception condition on error. + */ +size_t interception_condition_unmarshal(interception_condition_t* restrict this, char* restrict data); + + +#endif + diff --git a/src/mds-server/mds-server.c b/src/mds-server/mds-server.c index d707eab..f0fa701 100644 --- a/src/mds-server/mds-server.c +++ b/src/mds-server/mds-server.c @@ -16,6 +16,9 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "mds-server.h" +#include "interception_condition.h" +#include "client.h" +#include "queued_interception.h" #include <libmdsserver/config.h> #include <libmdsserver/linked-list.h> diff --git a/src/mds-server/mds-server.h b/src/mds-server/mds-server.h index 1e3869f..b2dafd4 100644 --- a/src/mds-server/mds-server.h +++ b/src/mds-server/mds-server.h @@ -19,130 +19,9 @@ #define MDS_MDS_SERVER_H -#include <libmdsserver/mds-message.h> +#include "client.h" -#include <stdlib.h> -#include <pthread.h> -#include <stdint.h> - - - -/** - * A condition for a message being intercepted by a client - */ -typedef struct interception_condition -{ - /** - * The header of messages to intercept, optionally with a value, - * empty (most not be NULL) for all messages. - */ - char* condition; - - /** - * The hash of the header of messages to intercept - */ - size_t header_hash; - - /** - * The interception priority. The client should be - * consistent with the priority for conditions that - * are not mutually exclusive. - */ - int64_t priority; - - /** - * Whether the messages may get modified by the client - */ - int modifying; - -} interception_condition_t; - - -/** - * Client information structure - */ -typedef struct client -{ - /** - * The client's entry in the list of clients - */ - ssize_t list_entry; - - /** - * The socket file descriptor for the socket connected to the client - */ - int socket_fd; - - /** - * Whether the socket is open - */ - int open; - - /** - * Message read buffer for the client - */ - mds_message_t message; - - /** - * The read thread for the client - */ - pthread_t thread; - - /** - * The client's ID - */ - uint64_t id; - - /** - * Mutex for sending data and other - * actions that only affacts this client - */ - pthread_mutex_t mutex; - - /** - * The messages interception conditions conditions - * for the client - */ - interception_condition_t* interception_conditions; - - /** - * The number of interception conditions - */ - size_t interception_conditions_count; - - /** - * Messages pending to be sent (concatenated) - */ - char* send_pending; - - /** - * The character length of the messages pending to be sent - */ - size_t send_pending_size; - -} client_t; - -/** - * A queued interception - */ -typedef struct queued_interception -{ - /** - * The intercepting client - */ - client_t* client; - - /** - * The interception priority - */ - int64_t priority; - - /** - * Whether the messages may get modified by the client - */ - int modifying; - -} queued_interception_t; +#include <stddef.h> diff --git a/src/mds-server/queued_interception.h b/src/mds-server/queued_interception.h new file mode 100644 index 0000000..6f08a8a --- /dev/null +++ b/src/mds-server/queued_interception.h @@ -0,0 +1,51 @@ +/** + * mds — A micro-display server + * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef MDS_MDS_SERVER_QUEUED_INTERCEPTION_H +#define MDS_MDS_SERVER_QUEUED_INTERCEPTION_H + + +#include "client.h" + +#include <stdint.h> + + +/** + * A queued interception + */ +typedef struct queued_interception +{ + /** + * The intercepting client + */ + client_t* client; + + /** + * The interception priority + */ + int64_t priority; + + /** + * Whether the messages may get modified by the client + */ + int modifying; + +} queued_interception_t; + + +#endif + |