aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mds-server.c69
-rw-r--r--src/mds-server.h27
2 files changed, 92 insertions, 4 deletions
diff --git a/src/mds-server.c b/src/mds-server.c
index 517ad8c..9145033 100644
--- a/src/mds-server.c
+++ b/src/mds-server.c
@@ -921,7 +921,10 @@ void multicast_message(char* message, size_t length)
size_t* hashes = NULL;
char** headers = NULL;
char** header_values = NULL;
+ queued_interception_t* interceptions = NULL;
+ size_t interceptions_count = 0;
size_t i;
+ ssize_t node;
/* Count the number of headers. */
for (i = 0; i < n; i++)
@@ -949,14 +952,12 @@ void multicast_message(char* message, size_t length)
*end = '\0';
if ((header_values[i] = strdup(message)) == NULL)
{
- perror(*argv);
header_count = i;
goto fail;
}
*colon = '\0';
if ((headers[i] = strdup(message)) == NULL)
{
- perror(*argv);
free(headers[i]);
header_count = i;
goto fail;
@@ -968,15 +969,77 @@ void multicast_message(char* message, size_t length)
message = end + 1;
}
+ /* Get intercepting clients. */
+ with_mutex(slave_mutex,
+ /* Count clients. */
+ n = 0;
+ foreach_linked_list_node (client_list, node)
+ n++;
+
+ /* Allocate interceptor list. */
+ interceptions = malloc(n * sizeof(queued_interception_t*));
+
+ /* Search clients. */
+ if (interceptions != NULL)
+ foreach_linked_list_node (client_list, node)
+ {
+ client_t* client = (client_t*)(void*)(client_list.values[node]);
+ pthread_mutex_t mutex = client->mutex;
+ interception_condition_t* conds = client->interception_conditions;
+ int64_t priority = 0; /* Initialise to stop incorrect warning. */
+ int modifying = 0; /* Initialise to stop incorrect warning. */
+ size_t j;
+
+ /* Look for a matching condition. */
+ n = client->interception_conditions_count;
+ with_mutex(mutex,
+ for (i = 0; i < n; i++)
+ {
+ interception_condition_t* cond = conds + i;
+ for (j = 0; j < header_count; j++)
+ {
+ if (cond->header_hash == hashes[j])
+ if ((*(cond->condition) == '\0') ||
+ strequals(cond->condition, headers[j]) ||
+ strequals(cond->condition, header_values[j]))
+ break;
+ }
+ if (j < header_count)
+ {
+ priority = cond->priority;
+ modifying = cond->modifying;
+ break;
+ }
+ }
+ );
+
+ /* List client of there was a matching condition. */
+ if (i < n)
+ {
+ interceptions[interceptions_count].client = client;
+ interceptions[interceptions_count].priority = priority;
+ interceptions[interceptions_count].modifying = modifying;
+ interceptions_count++;
+ }
+ }
+ );
+ if (interceptions == NULL)
+ goto fail;
+
+ /* Sort interceptors. */
/* TODO */
- fail: /* This is done before this function returns even if there was no error */
+ errno = 0;
+ fail: /* This is done before this function returns even if there was no error. */
+ if (errno != 0)
+ perror(*argv);
/* Release resources. */
for (i = 0; i < header_count; i++)
{
if (headers[i] != NULL) free(headers[i]);
if (header_values[i] != NULL) free(header_values[i]);
}
+ if (interceptions != NULL) free(interceptions);
if (headers != NULL) free(headers);
if (header_values != NULL) free(header_values);
if (hashes != NULL) free(hashes);
diff --git a/src/mds-server.h b/src/mds-server.h
index be8678e..6269e9b 100644
--- a/src/mds-server.h
+++ b/src/mds-server.h
@@ -44,7 +44,9 @@ typedef struct interception_condition
size_t header_hash;
/**
- * The interception priority
+ * The interception priority. The client should be
+ * consistent with the priority for conditions that
+ * are not mutually exclusive.
*/
int64_t priority;
@@ -110,6 +112,29 @@ typedef struct client
} 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;
+
+
/**
* Master function for slave threads