aboutsummaryrefslogtreecommitdiffstats
path: root/src/mds-server/interceptors.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mds-server/interceptors.c')
-rw-r--r--src/mds-server/interceptors.c376
1 files changed, 185 insertions, 191 deletions
diff --git a/src/mds-server/interceptors.c b/src/mds-server/interceptors.c
index fccb0fa..a39e0d6 100644
--- a/src/mds-server/interceptors.c
+++ b/src/mds-server/interceptors.c
@@ -38,28 +38,26 @@
* @param client The intercepting client
* @param index The index of the condition
*/
-__attribute__((nonnull))
-static void remove_intercept_condition(client_t* client, size_t index)
+static void __attribute__((nonnull))
+remove_intercept_condition(client_t *client, size_t index)
{
- interception_condition_t* conds = client->interception_conditions;
- size_t n = client->interception_conditions_count;
-
- /* Remove the condition from the list. */
- free(conds[index].condition);
- memmove(conds + index, conds + index + 1, --n - index);
- client->interception_conditions_count--;
-
- /* Shrink the list. */
- if (client->interception_conditions_count == 0)
- {
- free(conds);
- client->interception_conditions = NULL;
- }
- else
- if (xrealloc(conds, n, interception_condition_t))
- xperror(*argv);
- else
- client->interception_conditions = conds;
+ interception_condition_t *conds = client->interception_conditions;
+ size_t n = client->interception_conditions_count;
+
+ /* Remove the condition from the list. */
+ free(conds[index].condition);
+ memmove(conds + index, conds + index + 1, --n - index);
+ client->interception_conditions_count--;
+
+ /* Shrink the list. */
+ if (!client->interception_conditions_count) {
+ free(conds);
+ client->interception_conditions = NULL;
+ } else if (xrealloc(conds, n, interception_condition_t)) {
+ xperror(*argv);
+ } else {
+ client->interception_conditions = conds;
+ }
}
@@ -72,106 +70,100 @@ static void remove_intercept_condition(client_t* client, size_t index)
* @param modifying Whether the client may modify the messages
* @param stop Whether the condition should be removed rather than added
*/
-void add_intercept_condition(client_t* client, char* condition, int64_t priority, int modifying, int stop)
+void
+add_intercept_condition(client_t *client, char *condition, int64_t priority, int modifying, int stop)
{
- size_t n = client->interception_conditions_count;
- interception_condition_t* conds = client->interception_conditions;
- ssize_t nonmodifying = -1;
- char* header = condition;
- char* colon = NULL;
- char* value;
- size_t hash;
- size_t i;
-
- /* Split header and value apart. */
- if ((value = strchr(header, ':')) != NULL)
- {
- *value = '\0'; /* NUL-terminate header. */
- colon = value; /* End of header. */
- value += 2; /* Skip over delimiter. */
- }
-
- /* Calcuate header hash (comparison optimisation) */
- hash = string_hash(header);
- /* Undo header–value splitting. */
- if (colon != NULL)
- *colon = ':';
-
- /* Remove of update condition of already registered,
- also look for non-modifying condition to swap position
- with for optimisation. */
- for (i = 0; i < n; i++)
- {
- if ((conds[i].header_hash != hash) || !strequals(conds[i].condition, condition))
- {
- /* Look for the first non-modifying, this is a part of the
- optimisation where we put all modifying conditions at the
- beginning. */
- if ((nonmodifying < 0) && conds[i].modifying)
- nonmodifying = (ssize_t)i;
- continue;
+ size_t n = client->interception_conditions_count;
+ interception_condition_t *conds = client->interception_conditions;
+ ssize_t nonmodifying = -1;
+ char *header = condition;
+ char *colon = NULL;
+ char *value;
+ size_t hash, i;
+ interception_condition_t temp;
+
+ /* Split header and value apart. */
+ if ((value = strchr(header, ':'))) {
+ *value = '\0'; /* NUL-terminate header. */
+ colon = value; /* End of header. */
+ value += 2; /* Skip over delimiter. */
}
-
- if (stop)
- remove_intercept_condition(client, i);
- else
- {
- /* Update parameters. */
- conds[i].priority = priority;
- conds[i].modifying = modifying;
-
- if (modifying && (nonmodifying >= 0))
- {
- /* Optimisation: put conditions that are modifying
- at the beginning. When a client is intercepting
- we most know if any satisfying condition is
- modifying. With this optimisation the first
- satisfying condition will tell us if there is
- any satisfying condition that is modifying. */
- interception_condition_t temp = conds[nonmodifying];
- conds[nonmodifying] = conds[i];
- conds[i] = temp;
- }
+
+ /* Calcuate header hash (comparison optimisation) */
+ hash = string_hash(header);
+ /* Undo header–value splitting. */
+ if (colon)
+ *colon = ':';
+
+ /* Remove of update condition of already registered,
+ also look for non-modifying condition to swap position
+ with for optimisation. */
+ for (i = 0; i < n; i++) {
+ if ((conds[i].header_hash != hash) || !strequals(conds[i].condition, condition)) {
+ /* Look for the first non-modifying, this is a part of the
+ optimisation where we put all modifying conditions at the
+ beginning. */
+ if (nonmodifying < 0 && conds[i].modifying)
+ nonmodifying = (ssize_t)i;
+ continue;
+ }
+
+ if (stop) {
+ remove_intercept_condition(client, i);
+ } else {
+ /* Update parameters. */
+ conds[i].priority = priority;
+ conds[i].modifying = modifying;
+
+ if (modifying && nonmodifying >= 0) {
+ /* Optimisation: put conditions that are modifying
+ at the beginning. When a client is intercepting
+ we most know if any satisfying condition is
+ modifying. With this optimisation the first
+ satisfying condition will tell us if there is
+ any satisfying condition that is modifying. */
+ temp = conds[nonmodifying];
+ conds[nonmodifying] = conds[i];
+ conds[i] = temp;
+ }
+ }
+ return;
}
- return;
- }
-
- if (stop)
- eprint("client tried to stop intercepting messages that it does not intercept.");
- else
- {
- /* Duplicate condition string. */
- fail_if (xstrdup_nn(condition, condition));
-
- /* Grow the interception condition list. */
- fail_if (xrealloc(conds, n + 1, interception_condition_t));
- client->interception_conditions = conds;
- /* Store condition. */
- client->interception_conditions_count++;
- conds[n].condition = condition;
- conds[n].header_hash = hash;
- conds[n].priority = priority;
- conds[n].modifying = modifying;
-
- if (modifying && (nonmodifying >= 0))
- {
- /* Optimisation: put conditions that are modifying
- at the beginning. When a client is intercepting
- we most know if any satisfying condition is
- modifying. With this optimisation the first
- satisfying condition will tell us if there is
- any satisfying condition that is modifying. */
- interception_condition_t temp = conds[nonmodifying];
- conds[nonmodifying] = conds[n];
- conds[n] = temp;
+
+ if (stop) {
+ eprint("client tried to stop intercepting messages that it does not intercept.");
+ } else {
+ /* Duplicate condition string. */
+ fail_if (xstrdup_nn(condition, condition));
+
+ /* Grow the interception condition list. */
+ fail_if (xrealloc(conds, n + 1, interception_condition_t));
+ client->interception_conditions = conds;
+ /* Store condition. */
+ client->interception_conditions_count++;
+ conds[n].condition = condition;
+ conds[n].header_hash = hash;
+ conds[n].priority = priority;
+ conds[n].modifying = modifying;
+
+ if (modifying && nonmodifying >= 0) {
+ /* Optimisation: put conditions that are modifying
+ at the beginning. When a client is intercepting
+ we most know if any satisfying condition is
+ modifying. With this optimisation the first
+ satisfying condition will tell us if there is
+ any satisfying condition that is modifying. */
+ temp = conds[nonmodifying];
+ conds[nonmodifying] = conds[n];
+ conds[n] = temp;
+ }
}
- }
- return;
- fail:
- xperror(*argv);
- free(condition);
- return;
+ return;
+fail:
+ xperror(*argv);
+ free(condition);
+ return;
}
@@ -185,18 +177,20 @@ void add_intercept_condition(client_t* client, char* condition, int64_t priority
* @param count The number of accepted patterns
* @return Evaluates to true if and only if a matching pattern was found
*/
-int is_condition_matching(interception_condition_t* cond, size_t* hashes,
- char** keys, char** headers, size_t count)
+int
+is_condition_matching(interception_condition_t *cond, size_t *hashes,
+ char **keys, char **headers, size_t count)
{
- size_t i;
- for (i = 0; i < count; i++)
- if (*(cond->condition) == '\0')
- return 1;
- else if ((cond->header_hash == hashes[i]) &&
- (strequals(cond->condition, keys[i]) ||
- strequals(cond->condition, headers[i])))
- return 1;
- return 0;
+ size_t i;
+ for (i = 0; i < count; i++) {
+ if (*cond->condition == '\0')
+ return 1;
+ else if ((cond->header_hash == hashes[i]) &&
+ (strequals(cond->condition, keys[i]) ||
+ strequals(cond->condition, headers[i])))
+ return 1;
+ }
+ return 0;
}
@@ -211,33 +205,34 @@ int is_condition_matching(interception_condition_t* cond, size_t* hashes,
* @param interception_out Storage slot for found interception
* @return -1 on error, otherwise: evalutes to true iff a matching condition was found
*/
-int find_matching_condition(client_t* client, size_t* hashes, char** keys, char** headers,
- size_t count, queued_interception_t* interception_out)
+int
+find_matching_condition(client_t *client, size_t *hashes, char **keys, char **headers,
+ size_t count, queued_interception_t *interception_out)
{
- pthread_mutex_t mutex = client->mutex;
- interception_condition_t* conds = client->interception_conditions;
- size_t n = 0, i;
-
- fail_if ((errno = pthread_mutex_lock(&(mutex))));
-
- /* Look for a matching condition. */
- if (client->open)
- n = client->interception_conditions_count;
- for (i = 0; i < n; i++)
- if (is_condition_matching(conds + i, hashes, keys, headers, count))
- {
- /* Report matching condition. */
- interception_out->client = client;
- interception_out->priority = conds[i].priority;
- interception_out->modifying = conds[i].modifying;
- break;
- }
-
- pthread_mutex_unlock(&(mutex));
-
- return i < n;
- fail:
- return -1;
+ pthread_mutex_t mutex = client->mutex;
+ interception_condition_t *conds = client->interception_conditions;
+ size_t n = 0, i;
+
+ fail_if ((errno = pthread_mutex_lock(&(mutex))));
+
+ /* Look for a matching condition. */
+ if (client->open)
+ n = client->interception_conditions_count;
+ for (i = 0; i < n; i++) {
+ if (is_condition_matching(conds + i, hashes, keys, headers, count)) {
+ /* Report matching condition. */
+ interception_out->client = client;
+ interception_out->priority = conds[i].priority;
+ interception_out->modifying = conds[i].modifying;
+ break;
+ }
+ }
+
+ pthread_mutex_unlock(&mutex);
+
+ return i < n;
+fail:
+ return -1;
}
@@ -252,44 +247,43 @@ int find_matching_condition(client_t* client, size_t* hashes, char** keys, char*
* @param interceptions_count_out Slot at where to store the number of found interceptors
* @return The found interceptors, `NULL` on error
*/
-queued_interception_t* get_interceptors(client_t* sender, size_t* hashes, char** keys, char** headers,
- size_t count, size_t* interceptions_count_out)
+queued_interception_t *
+get_interceptors(client_t *sender, size_t *hashes, char **keys, char **headers,
+ size_t count, size_t *interceptions_count_out)
{
- queued_interception_t* interceptions = NULL;
- size_t interceptions_count = 0, n = 0;
- ssize_t node;
- int saved_errno;
-
- /* Count clients. */
- foreach_linked_list_node (client_list, node)
- n++;
-
- /* Allocate interceptor list. */
- fail_if (xmalloc(interceptions, n, queued_interception_t));
-
- /* Search clients. */
- foreach_linked_list_node (client_list, node)
- {
- client_t* client = (client_t*)(void*)(client_list.values[node]);
-
- /* Look for and list a matching condition. */
- if (client->open && (client != sender))
- {
- int r = find_matching_condition(client, hashes, keys, headers, count,
- interceptions + interceptions_count);
- fail_if (r == -1);
- if (r)
- /* List client of there was a matching condition. */
- interceptions_count++;
+ queued_interception_t *interceptions = NULL;
+ size_t interceptions_count = 0, n = 0;
+ ssize_t node;
+ int saved_errno, r;
+ client_t *client;
+
+ /* Count clients. */
+ foreach_linked_list_node (client_list, node)
+ n++;
+
+ /* Allocate interceptor list. */
+ fail_if (xmalloc(interceptions, n, queued_interception_t));
+
+ /* Search clients. */
+ foreach_linked_list_node (client_list, node) {
+ client = (void *)(client_list.values[node]);
+
+ /* Look for and list a matching condition. */
+ if (client->open && (client != sender)) {
+ r = find_matching_condition(client, hashes, keys, headers, count,
+ interceptions + interceptions_count);
+ fail_if (r == -1);
+ if (r)
+ /* List client of there was a matching condition. */
+ interceptions_count++;
+ }
}
- }
-
- *interceptions_count_out = interceptions_count;
- return interceptions;
-
- fail:
- saved_errno = errno;
- free(interceptions);
- return errno = saved_errno, NULL;
-}
+ *interceptions_count_out = interceptions_count;
+ return interceptions;
+
+fail:
+ saved_errno = errno;
+ free(interceptions);
+ return errno = saved_errno, NULL;
+}