summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabor X Toth <*@tg-x.net>2016-01-15 22:12:29 +0000
committerGabor X Toth <*@tg-x.net>2016-01-15 22:12:29 +0000
commit377e7340cce5136867734fb19e89a5fc51ac0c99 (patch)
tree8dbf1f5ccec45b91367c32b67a031a7a73a4ab2d /src
parent61e8794662ce2fc6ca669906822840a3743b4b78 (diff)
social: set/clear msg proc flags
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_protocols.h7
-rw-r--r--src/include/gnunet_psyc_slicer.h73
-rw-r--r--src/include/gnunet_social_service.h28
-rw-r--r--src/psycutil/psyc_slicer.c101
-rw-r--r--src/social/gnunet-service-social.c379
-rw-r--r--src/social/social.h13
-rw-r--r--src/social/social_api.c118
7 files changed, 556 insertions, 163 deletions
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index 0251c57fe..7c63f60a3 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -2646,8 +2646,11 @@ extern "C"
/** S->C: notify about an existing place */
#define GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE 854
-/** S->C: */
-#define GNUNET_MESSAGE_TYPE_SOCIAL_HOST_RELAY 855
+/** C->S: set message processing flags */
+#define GNUNET_MESSAGE_TYPE_SOCIAL_MSG_PROC_SET 860
+
+/** C->S: clear message processing flags */
+#define GNUNET_MESSAGE_TYPE_SOCIAL_MSG_PROC_CLEAR 860
/*******************************************************************************
* X-VINE DHT messages
diff --git a/src/include/gnunet_psyc_slicer.h b/src/include/gnunet_psyc_slicer.h
index 1851a6002..077c0c5bd 100644
--- a/src/include/gnunet_psyc_slicer.h
+++ b/src/include/gnunet_psyc_slicer.h
@@ -250,9 +250,9 @@ GNUNET_PSYC_slicer_method_remove (struct GNUNET_PSYC_Slicer *slicer,
*/
void
GNUNET_PSYC_slicer_modifier_add (struct GNUNET_PSYC_Slicer *slicer,
- const char *object_filter,
- GNUNET_PSYC_ModifierCallback modifier_cb,
- void *cls);
+ const char *object_filter,
+ GNUNET_PSYC_ModifierCallback modifier_cb,
+ void *cls);
/**
@@ -270,30 +270,75 @@ GNUNET_PSYC_slicer_modifier_add (struct GNUNET_PSYC_Slicer *slicer,
*/
int
GNUNET_PSYC_slicer_modifier_remove (struct GNUNET_PSYC_Slicer *slicer,
- const char *object_filter,
- GNUNET_PSYC_ModifierCallback modifier_cb);
+ const char *object_filter,
+ GNUNET_PSYC_ModifierCallback modifier_cb);
+
+
+/**
+ * Process an incoming message and call matching handlers.
+ *
+ * @param slicer
+ * The slicer to use.
+ * @param msg
+ * The message as it arrived from the network.
+ */
+void
+GNUNET_PSYC_slicer_message (struct GNUNET_PSYC_Slicer *slicer,
+ const struct GNUNET_PSYC_MessageHeader *msg);
/**
* Process an incoming message part and call matching handlers.
*
- * @param cls
- * Closure.
+ * @param slicer
+ * The slicer to use.
* @param message_id
* ID of the message.
* @param flags
* Flags for the message.
* @see enum GNUNET_PSYC_MessageFlags
+ * @param fragment offset
+ * Fragment offset of the message.
* @param msg
- * The message part. as it arrived from the network.
+ * The message part as it arrived from the network.
+ */
+void
+GNUNET_PSYC_slicer_message_part (struct GNUNET_PSYC_Slicer *slicer,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_pub_key,
+ uint64_t message_id,
+ uint32_t flags,
+ uint64_t fragment_offset,
+ const struct GNUNET_MessageHeader *msg);
+
+
+/**
+ * Remove all registered method handlers.
+ *
+ * @param slicer
+ * Slicer to clear.
+ */
+void
+GNUNET_PSYC_slicer_method_clear (struct GNUNET_PSYC_Slicer *slicer);
+
+
+/**
+ * Remove all registered modifier handlers.
+ *
+ * @param slicer
+ * Slicer to clear.
+ */
+void
+GNUNET_PSYC_slicer_modifier_clear (struct GNUNET_PSYC_Slicer *slicer);
+
+
+/**
+ * Remove all registered method & modifier handlers.
+ *
+ * @param slicer
+ * Slicer to clear.
*/
void
-GNUNET_PSYC_slicer_message (void *cls,
- const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_pub_key,
- uint64_t message_id,
- uint32_t flags,
- uint64_t fragment_offset,
- const struct GNUNET_MessageHeader *msg);
+GNUNET_PSYC_slicer_clear (struct GNUNET_PSYC_Slicer *slicer);
/**
diff --git a/src/include/gnunet_social_service.h b/src/include/gnunet_social_service.h
index 4ad6036a9..75038407b 100644
--- a/src/include/gnunet_social_service.h
+++ b/src/include/gnunet_social_service.h
@@ -232,6 +232,12 @@ extern "C"
*/
#define GNUNET_SOCIAL_APP_MAX_ID_SIZE 256
+enum GNUNET_SOCIAL_MsgProcFlags {
+ GNUNET_SOCIAL_MSG_PROC_NONE = 0,
+ GNUNET_SOCIAL_MSG_PROC_RELAY = 1,
+ GNUNET_SOCIAL_MSG_PROC_SAVE= 2,
+};
+
/**
* Handle for an application.
*/
@@ -1063,6 +1069,28 @@ struct GNUNET_SOCIAL_HistoryRequest;
/**
+ * Set message processing @a flags for a @a method_prefix.
+ *
+ * @param plc
+ * Place.
+ * @param method_prefix
+ * Method prefix @a flags apply to.
+ * @param flags
+ * The flags that apply to a matching @a method_prefix.
+ */
+void
+GNUNET_SOCIAL_place_msg_proc_set (struct GNUNET_SOCIAL_Place *plc,
+ const char *method_prefix,
+ enum GNUNET_SOCIAL_MsgProcFlags flags);
+
+/**
+ * Clear all message processing flags previously set for this place.
+ */
+void
+GNUNET_SOCIAL_place_msg_proc_clear (struct GNUNET_SOCIAL_Place *plc);
+
+
+/**
* Learn about the history of a place.
*
* Messages are returned through the @a slicer function
diff --git a/src/psycutil/psyc_slicer.c b/src/psycutil/psyc_slicer.c
index fe9912416..e372d3ae2 100644
--- a/src/psycutil/psyc_slicer.c
+++ b/src/psycutil/psyc_slicer.c
@@ -50,6 +50,11 @@ struct GNUNET_PSYC_Slicer
struct GNUNET_CONTAINER_MultiHashMap *modifier_handlers;
/**
+ * Receive handle for incoming messages.
+ */
+ struct GNUNET_PSYC_ReceiveHandle *recv;
+
+ /**
* Currently being processed message part.
*/
const struct GNUNET_MessageHeader *msg;
@@ -151,7 +156,7 @@ struct SlicerModifierRemoveClosure
/**
* Call a method handler for an incoming message part.
*/
-int
+static int
slicer_method_handler_notify (void *cls, const struct GNUNET_HashCode *key,
void *value)
{
@@ -229,7 +234,7 @@ slicer_method_handler_notify (void *cls, const struct GNUNET_HashCode *key,
/**
* Call a method handler for an incoming message part.
*/
-int
+static int
slicer_modifier_handler_notify (void *cls, const struct GNUNET_HashCode *key,
void *value)
{
@@ -244,6 +249,22 @@ slicer_modifier_handler_notify (void *cls, const struct GNUNET_HashCode *key,
/**
+ * Process an incoming message and call matching handlers.
+ *
+ * @param slicer
+ * The slicer to use.
+ * @param msg
+ * The message as it arrived from the network.
+ */
+void
+GNUNET_PSYC_slicer_message (struct GNUNET_PSYC_Slicer *slicer,
+ const struct GNUNET_PSYC_MessageHeader *msg)
+{
+ GNUNET_PSYC_receive_message (slicer->recv, msg);
+}
+
+
+/**
* Process an incoming message part and call matching handlers.
*
* @param cls
@@ -257,11 +278,13 @@ slicer_modifier_handler_notify (void *cls, const struct GNUNET_HashCode *key,
* The message part. as it arrived from the network.
*/
void
-GNUNET_PSYC_slicer_message (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_pub_key,
- uint64_t message_id, uint32_t flags, uint64_t fragment_offset,
- const struct GNUNET_MessageHeader *msg)
+GNUNET_PSYC_slicer_message_part (struct GNUNET_PSYC_Slicer *slicer,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_pub_key,
+ uint64_t message_id,
+ uint32_t flags,
+ uint64_t fragment_offset,
+ const struct GNUNET_MessageHeader *msg)
{
- struct GNUNET_PSYC_Slicer *slicer = cls;
slicer->nym_pub_key = *slave_pub_key;
uint16_t ptype = ntohs (msg->type);
@@ -381,6 +404,10 @@ GNUNET_PSYC_slicer_create (void)
struct GNUNET_PSYC_Slicer *slicer = GNUNET_malloc (sizeof (*slicer));
slicer->method_handlers = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
slicer->modifier_handlers = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
+ slicer->recv = GNUNET_PSYC_receive_create (NULL,
+ (GNUNET_PSYC_MessagePartCallback)
+ GNUNET_PSYC_slicer_message_part,
+ slicer);
return slicer;
}
@@ -430,7 +457,7 @@ GNUNET_PSYC_slicer_method_add (struct GNUNET_PSYC_Slicer *slicer,
}
-int
+static int
slicer_method_remove (void *cls, const struct GNUNET_HashCode *key, void *value)
{
struct SlicerMethodRemoveClosure *rm_cls = cls;
@@ -531,7 +558,7 @@ GNUNET_PSYC_slicer_modifier_add (struct GNUNET_PSYC_Slicer *slicer,
}
-int
+static int
slicer_modifier_remove (void *cls, const struct GNUNET_HashCode *key, void *value)
{
struct SlicerModifierRemoveClosure *rm_cls = cls;
@@ -585,7 +612,7 @@ GNUNET_PSYC_slicer_modifier_remove (struct GNUNET_PSYC_Slicer *slicer,
}
-int
+static int
slicer_method_free (void *cls, const struct GNUNET_HashCode *key, void *value)
{
struct SlicerMethodCallbacks *cbs = value;
@@ -594,6 +621,57 @@ slicer_method_free (void *cls, const struct GNUNET_HashCode *key, void *value)
}
+static int
+slicer_modifier_free (void *cls, const struct GNUNET_HashCode *key, void *value)
+{
+ struct SlicerModifierCallbacks *cbs = value;
+ GNUNET_free (cbs);
+ return GNUNET_YES;
+}
+
+
+/**
+ * Remove all registered method handlers.
+ *
+ * @param slicer
+ * Slicer to clear.
+ */
+void
+GNUNET_PSYC_slicer_method_clear (struct GNUNET_PSYC_Slicer *slicer)
+{
+ GNUNET_CONTAINER_multihashmap_iterate (slicer->method_handlers,
+ slicer_method_free, NULL);
+}
+
+
+/**
+ * Remove all registered modifier handlers.
+ *
+ * @param slicer
+ * Slicer to clear.
+ */
+void
+GNUNET_PSYC_slicer_modifier_clear (struct GNUNET_PSYC_Slicer *slicer)
+{
+ GNUNET_CONTAINER_multihashmap_iterate (slicer->modifier_handlers,
+ slicer_modifier_free, NULL);
+}
+
+
+/**
+ * Remove all registered method & modifier handlers.
+ *
+ * @param slicer
+ * Slicer to clear.
+ */
+void
+GNUNET_PSYC_slicer_clear (struct GNUNET_PSYC_Slicer *slicer)
+{
+ GNUNET_PSYC_slicer_method_clear (slicer);
+ GNUNET_PSYC_slicer_modifier_clear (slicer);
+}
+
+
/**
* Destroy a given try-and-slice instance.
*
@@ -603,8 +681,9 @@ slicer_method_free (void *cls, const struct GNUNET_HashCode *key, void *value)
void
GNUNET_PSYC_slicer_destroy (struct GNUNET_PSYC_Slicer *slicer)
{
- GNUNET_CONTAINER_multihashmap_iterate (slicer->method_handlers,
- slicer_method_free, NULL);
+ GNUNET_PSYC_slicer_clear (slicer);
GNUNET_CONTAINER_multihashmap_destroy (slicer->method_handlers);
+ GNUNET_CONTAINER_multihashmap_destroy (slicer->modifier_handlers);
+ GNUNET_PSYC_receive_destroy (slicer->recv);
GNUNET_free (slicer);
}
diff --git a/src/social/gnunet-service-social.c b/src/social/gnunet-service-social.c
index d4dfe9b0f..f3eacd6f9 100644
--- a/src/social/gnunet-service-social.c
+++ b/src/social/gnunet-service-social.c
@@ -229,10 +229,10 @@ struct Place
*/
struct GNUNET_HashCode ego_pub_hash;
- uint64_t file_message_id;
- uint64_t file_fragment_offset;
- uint64_t file_size;
- uint64_t file_offset;
+ /**
+ * Slicer for processing incoming messages.
+ */
+ struct GNUNET_PSYC_Slicer *slicer;
/**
* Last message ID received for the place.
@@ -241,6 +241,16 @@ struct Place
uint64_t max_message_id;
/**
+ * Offset where the file is currently being written.
+ */
+ uint64_t file_offset;
+
+ /**
+ * Whether or not to save the file (#GNUNET_YES or #GNUNET_NO)
+ */
+ uint8_t file_save;
+
+ /**
* Is this a host (#GNUNET_YES), or guest (#GNUNET_NO)?
*/
uint8_t is_host;
@@ -509,6 +519,8 @@ cleanup_place (struct Place *plc)
(GNUNET_YES == plc->is_host)
? cleanup_host ((struct Host *) plc)
: cleanup_guest ((struct Guest *) plc);
+
+ GNUNET_PSYC_slicer_destroy (plc->slicer);
GNUNET_free (plc);
}
@@ -728,34 +740,132 @@ psyc_recv_join_dcsn (void *cls,
place_send_msg (&gst->plc, &dcsn->header);
}
+
/**
- * Save _file data to disk.
+ * Called when a PSYC master or slave receives a message.
*/
-void
-psyc_recv_file (struct Place *plc, const struct GNUNET_PSYC_MessageHeader *msg,
- uint32_t flags, uint64_t message_id, uint64_t fragment_offset,
- const char *method_name, struct GNUNET_PSYC_Environment *env,
- const void *data, uint16_t data_size)
+static void
+psyc_recv_message (void *cls,
+ uint64_t message_id,
+ uint32_t flags,
+ const struct GNUNET_PSYC_MessageHeader *msg)
+{
+ struct Place *plc = cls;
+
+ char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&msg->slave_pub_key);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "%p Received PSYC message of size %u from %s.\n",
+ plc, ntohs (msg->header.size), str);
+ GNUNET_free (str);
+
+ GNUNET_PSYC_slicer_message (plc->slicer, msg);
+
+ place_send_msg (plc, &msg->header);
+}
+
+
+static void
+place_recv_relay_method (void *cls,
+ const struct GNUNET_PSYC_MessageMethod *meth,
+ uint64_t message_id,
+ uint32_t flags,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *nym_pub_key,
+ const char *method_name)
+{
+ struct Host *hst = cls;
+ struct Place *plc = &hst->plc;
+
+ // FIXME: relay message
+}
+
+
+static void
+place_recv_relay_modifier (void *cls,
+ const struct GNUNET_MessageHeader *msg,
+ uint64_t message_id,
+ enum GNUNET_PSYC_Operator oper,
+ const char *name,
+ const void *value,
+ uint16_t value_size,
+ uint16_t full_value_size)
{
- if (plc->file_message_id != message_id)
- {
- if (0 != fragment_offset)
- {
- /* unexpected message ID */
- GNUNET_break (0);
- return;
- }
- /* new file */
- plc->file_offset = 0;
+}
+
+
+static void
+place_recv_relay_eom (void *cls,
+ const struct GNUNET_MessageHeader *msg,
+ uint64_t message_id,
+ uint8_t cancelled)
+{
+
+}
+
+
+static void
+place_recv_relay_data (void *cls,
+ const struct GNUNET_MessageHeader *msg,
+ uint64_t message_id,
+ uint64_t data_offset,
+ const void *data,
+ uint16_t data_size)
+{
+
+}
+
+
+static void
+place_recv_save_method (void *cls,
+ const struct GNUNET_PSYC_MessageMethod *meth,
+ uint64_t message_id,
+ uint32_t flags,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *nym_pub_key,
+ const char *method_name)
+{
+ struct Place *plc = cls;
+ plc->file_offset = 0;
+ plc->file_save = GNUNET_NO;
+
+ struct GNUNET_CRYPTO_HashAsciiEncoded place_pub_hash_ascii;
+ memcpy (&place_pub_hash_ascii.encoding,
+ GNUNET_h2s_full (&plc->pub_key_hash), sizeof (place_pub_hash_ascii));
+
+ char *filename = NULL;
+ GNUNET_asprintf (&filename, "%s%c%s%c%s%c%.part" PRIu64,
+ dir_social, DIR_SEPARATOR,
+ "files", DIR_SEPARATOR,
+ place_pub_hash_ascii.encoding, DIR_SEPARATOR,
+ message_id);
+
+ /* save if does not already exist */
+ if (GNUNET_NO == GNUNET_DISK_file_test (filename))
+ {
+ plc->file_save = GNUNET_YES;
}
+ GNUNET_free (filename);
+}
+
+
+static void
+place_recv_save_data (void *cls,
+ const struct GNUNET_MessageHeader *msg,
+ uint64_t message_id,
+ uint64_t data_offset,
+ const void *data,
+ uint16_t data_size)
+{
+ struct Place *plc = cls;
+ if (GNUNET_YES != plc->file_save)
+ return;
+
struct GNUNET_CRYPTO_HashAsciiEncoded place_pub_hash_ascii;
memcpy (&place_pub_hash_ascii.encoding,
GNUNET_h2s_full (&plc->pub_key_hash), sizeof (place_pub_hash_ascii));
char *filename = NULL;
- GNUNET_asprintf (&filename, "%s%c%s%c%s%c%" PRIu64,
+ GNUNET_asprintf (&filename, "%s%c%s%c%s%c%.part" PRIu64,
dir_social, DIR_SEPARATOR,
"files", DIR_SEPARATOR,
place_pub_hash_ascii.encoding, DIR_SEPARATOR,
@@ -774,50 +884,38 @@ psyc_recv_file (struct Place *plc, const struct GNUNET_PSYC_MessageHeader *msg,
}
-/**
- * Called when a PSYC master or slave receives a message.
- */
static void
-psyc_recv_message (void *cls,
- uint64_t message_id,
- uint32_t flags,
- const struct GNUNET_PSYC_MessageHeader *msg)
+place_recv_save_eom (void *cls,
+ const struct GNUNET_MessageHeader *msg,
+ uint64_t message_id,
+ uint8_t cancelled)
{
struct Place *plc = cls;
+ if (GNUNET_YES != plc->file_save)
+ return;
- char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&msg->slave_key);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%p Received PSYC message of size %u from %s.\n",
- plc, ntohs (msg->header.size), str);
- GNUNET_free (str);
+ struct GNUNET_CRYPTO_HashAsciiEncoded place_pub_hash_ascii;
+ memcpy (&place_pub_hash_ascii.encoding,
+ GNUNET_h2s_full (&plc->pub_key_hash), sizeof (place_pub_hash_ascii));
- /* process message */
- /* FIXME: use slicer */
- const char *method_name = NULL;
- struct GNUNET_PSYC_Environment *env = GNUNET_PSYC_env_create ();
- const void *data = NULL;
- uint16_t data_size = 0;
+ char *fn_part = NULL;
+ GNUNET_asprintf (&fn_part, "%s%c%s%c%s%c%.part" PRIu64,
+ dir_social, DIR_SEPARATOR,
+ "files", DIR_SEPARATOR,
+ place_pub_hash_ascii.encoding, DIR_SEPARATOR,
+ message_id);
- if (GNUNET_SYSERR == GNUNET_PSYC_message_parse (msg, &method_name, env, &data, &data_size))
- {
- GNUNET_break (0);
- }
- else
- {
- char *method_found = strstr (method_name, "_file");
- if (method_name == method_found)
- {
- method_found += strlen ("_file");
- if (('\0' == *method_found) || ('_' == *method_found))
- {
- psyc_recv_file (plc, msg, flags, message_id, GNUNET_ntohll (msg->fragment_offset),
- method_name, env, data, data_size);
- }
- }
- }
- GNUNET_PSYC_env_destroy (env);
+ char *fn = NULL;
+ GNUNET_asprintf (&fn, "%s%c%s%c%s%c%" PRIu64,
+ dir_social, DIR_SEPARATOR,
+ "files", DIR_SEPARATOR,
+ place_pub_hash_ascii.encoding, DIR_SEPARATOR,
+ message_id);
- place_send_msg (plc, &msg->header);
+ rename (fn_part, fn);
+
+ GNUNET_free (fn);
+ GNUNET_free (fn_part);
}
@@ -1118,6 +1216,7 @@ host_enter (const struct HostEnterRequest *hreq, struct Host **ret_hst)
plc->is_host = GNUNET_YES;
plc->pub_key = hreq->place_pub_key;
plc->pub_key_hash = place_pub_hash;
+ plc->slicer = GNUNET_PSYC_slicer_create ();
GNUNET_CONTAINER_multihashmap_put (hosts, &plc->pub_key_hash, plc,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
@@ -1125,7 +1224,7 @@ host_enter (const struct HostEnterRequest *hreq, struct Host **ret_hst)
&psyc_master_started,
&psyc_recv_join_request,
&psyc_recv_message, NULL, hst);
- hst->plc.channel = GNUNET_PSYC_master_get_channel (hst->master);
+ plc->channel = GNUNET_PSYC_master_get_channel (hst->master);
ret = GNUNET_YES;
}
@@ -1135,6 +1234,115 @@ host_enter (const struct HostEnterRequest *hreq, struct Host **ret_hst)
}
+const struct MsgProcRequest *
+relay_req_parse (const struct GNUNET_MessageHeader *msg,
+ uint32_t *flags,
+ const char **method_prefix,
+ struct GNUNET_HashCode *method_hash)
+{
+ const struct MsgProcRequest *mpreq = (const struct MsgProcRequest *) msg;
+ uint8_t method_size = ntohs (mpreq->header.size) - sizeof (*mpreq);
+ uint16_t offset = GNUNET_STRINGS_buffer_tokenize ((const char *) &mpreq[1],
+ method_size, 1, method_prefix);
+
+ if (0 == offset || offset != method_size || *method_prefix == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "offset = %u, method_size = %u, method_name = %s\n",
+ offset, method_size, *method_prefix);
+ return NULL;
+ }
+
+ GNUNET_CRYPTO_hash (*method_prefix, method_size, method_hash);
+ *flags = ntohl (mpreq->flags);
+ return mpreq;
+}
+
+
+/**
+ * Handle a client setting message proccesing flags for a method prefix.
+ */
+static void
+client_recv_msg_proc_set (void *cls, struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *msg)
+{
+ struct Client *
+ ctx = GNUNET_SERVER_client_get_user_context (client, struct Client);
+ GNUNET_assert (NULL != ctx);
+ struct Place *plc = ctx->plc;
+
+ const char *method_prefix = NULL;
+ uint32_t flags = 0;
+ struct GNUNET_HashCode method_hash;
+ const struct MsgProcRequest *
+ mpreq = relay_req_parse (msg, &flags, &method_prefix, &method_hash);
+
+ if (NULL == mpreq) {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+
+ GNUNET_PSYC_slicer_method_remove (plc->slicer, method_prefix,
+ place_recv_relay_method,
+ place_recv_relay_modifier,
+ place_recv_relay_data,
+ place_recv_relay_eom);
+ GNUNET_PSYC_slicer_method_remove (plc->slicer, method_prefix,
+ place_recv_save_method,
+ NULL,
+ place_recv_save_data,
+ place_recv_save_eom);
+
+ if (flags & GNUNET_SOCIAL_MSG_PROC_RELAY)
+ {
+ GNUNET_PSYC_slicer_method_add (plc->slicer, method_prefix,
+ place_recv_relay_method,
+ place_recv_relay_modifier,
+ place_recv_relay_data,
+ place_recv_relay_eom,
+ plc);
+ }
+ if (flags & GNUNET_SOCIAL_MSG_PROC_SAVE)
+ {
+ GNUNET_PSYC_slicer_method_add (plc->slicer, method_prefix,
+ place_recv_save_method,
+ NULL,
+ place_recv_save_data,
+ place_recv_save_eom,
+ plc);
+ }
+
+ /** @todo Save flags to be able to resume relaying/saving after restart */
+
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+}
+
+
+/**
+ * Handle a connecting client requesting to clear all relay rules.
+ */
+static void
+client_recv_msg_proc_clear (void *cls, struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *msg)
+{
+ struct Client *
+ ctx = GNUNET_SERVER_client_get_user_context (client, struct Client);
+ GNUNET_assert (NULL != ctx);
+ struct Place *plc = ctx->plc;
+ if (GNUNET_YES != plc->is_host) {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ struct Host *hst = (struct Host *) plc;
+
+ GNUNET_PSYC_slicer_clear (plc->slicer);
+
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+}
+
+
/**
* Handle a connecting client entering a place as host.
*/
@@ -1320,6 +1528,7 @@ guest_enter (const struct GuestEnterRequest *greq, struct Guest **ret_gst)
plc->ego_pub_key = ego_pub_key;
plc->ego_pub_hash = ego_pub_hash;
plc->ego_key = ego->key;
+ plc->slicer = GNUNET_PSYC_slicer_create ();
if (NULL == plc_gst)
{
@@ -1339,7 +1548,7 @@ guest_enter (const struct GuestEnterRequest *greq, struct Guest **ret_gst)
&psyc_slave_connected,
&psyc_recv_join_dcsn,
gst, join_msg);
- gst->plc.channel = GNUNET_PSYC_slave_get_channel (gst->slave);
+ plc->channel = GNUNET_PSYC_slave_get_channel (gst->slave);
ret = GNUNET_YES;
}
@@ -1805,7 +2014,11 @@ client_recv_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
ctx = GNUNET_SERVER_client_get_user_context (client, struct Client);
GNUNET_assert (NULL != ctx);
struct Place *plc = ctx->plc;
- GNUNET_assert (GNUNET_YES == plc->is_host);
+ if (GNUNET_YES != plc->is_host) {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
struct Host *hst = (struct Host *) plc;
struct GNUNET_PSYC_JoinDecisionMessage *
@@ -1817,20 +2030,20 @@ client_recv_join_decision (void *cls, struct GNUNET_SERVER_Client *client,
? (struct GNUNET_PSYC_Message *) &dcsn[1]
: NULL;
- struct GNUNET_HashCode slave_key_hash;
- GNUNET_CRYPTO_hash (&dcsn->slave_key, sizeof (dcsn->slave_key),
- &slave_key_hash);
+ struct GNUNET_HashCode slave_pub_hash;
+ GNUNET_CRYPTO_hash (&dcsn->slave_pub_key, sizeof (dcsn->slave_pub_key),
+ &slave_pub_hash);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"%p Got join decision (%d) from client for place %s..\n",
hst, jcls.is_admitted, GNUNET_h2s (&plc->pub_key_hash));
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"%p ..and slave %s.\n",
- hst, GNUNET_h2s (&slave_key_hash));
+ hst, GNUNET_h2s (&slave_pub_hash));
- GNUNET_CONTAINER_multihashmap_get_multiple (hst->join_reqs, &slave_key_hash,
+ GNUNET_CONTAINER_multihashmap_get_multiple (hst->join_reqs, &slave_pub_hash,
&psyc_send_join_decision, &jcls);
- GNUNET_CONTAINER_multihashmap_remove_all (hst->join_reqs, &slave_key_hash);
+ GNUNET_CONTAINER_multihashmap_remove_all (hst->join_reqs, &slave_pub_hash);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
@@ -2832,45 +3045,51 @@ client_recv_zone_add_nym (void *cls, struct GNUNET_SERVER_Client *client,
static const struct GNUNET_SERVER_MessageHandler handlers[] = {
- { &client_recv_host_enter, NULL,
+ { client_recv_host_enter, NULL,
GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER, 0 },
- { &client_recv_guest_enter, NULL,
+ { client_recv_guest_enter, NULL,
GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER, 0 },
- { &client_recv_guest_enter_by_name, NULL,
+ { client_recv_guest_enter_by_name, NULL,
GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_BY_NAME, 0 },
- { &client_recv_join_decision, NULL,
+ { client_recv_join_decision, NULL,
GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION, 0 },
- { &client_recv_psyc_message, NULL,
+ { client_recv_psyc_message, NULL,
GNUNET_MESSAGE_TYPE_PSYC_MESSAGE, 0 },
- { &client_recv_history_replay, NULL,
+ { client_recv_history_replay, NULL,
GNUNET_MESSAGE_TYPE_PSYC_HISTORY_REPLAY, 0 },
- { &client_recv_state_get, NULL,
+ { client_recv_state_get, NULL,
GNUNET_MESSAGE_TYPE_PSYC_STATE_GET, 0 },
- { &client_recv_state_get, NULL,
+ { client_recv_state_get, NULL,
GNUNET_MESSAGE_TYPE_PSYC_STATE_GET_PREFIX, 0 },
- { &client_recv_zone_add_place, NULL,
+ { client_recv_zone_add_place, NULL,
GNUNET_MESSAGE_TYPE_SOCIAL_ZONE_ADD_PLACE, 0 },
- { &client_recv_zone_add_nym, NULL,
+ { client_recv_zone_add_nym, NULL,
GNUNET_MESSAGE_TYPE_SOCIAL_ZONE_ADD_NYM, 0 },
- { &client_recv_app_connect, NULL,
+ { client_recv_app_connect, NULL,
GNUNET_MESSAGE_TYPE_SOCIAL_APP_CONNECT, 0 },
- { &client_recv_app_detach, NULL,
+ { client_recv_app_detach, NULL,
GNUNET_MESSAGE_TYPE_SOCIAL_APP_DETACH, 0 },
- { &client_recv_place_leave, NULL,
+ { client_recv_place_leave, NULL,
GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE, 0 },
+ { client_recv_msg_proc_set, NULL,
+ GNUNET_MESSAGE_TYPE_SOCIAL_MSG_PROC_SET, 0 },
+
+ { client_recv_msg_proc_clear, NULL,
+ GNUNET_MESSAGE_TYPE_SOCIAL_MSG_PROC_CLEAR, 0 },
+
{ NULL, NULL, 0, 0 }
};
diff --git a/src/social/social.h b/src/social/social.h
index 0980cbf5c..d24515309 100644
--- a/src/social/social.h
+++ b/src/social/social.h
@@ -80,16 +80,19 @@ struct AppDetachRequest
};
-struct HostRelayRequest
+struct MsgProcRequest
{
/**
- * Types:
- * - GNUNET_MESSAGE_TYPE_SOCIAL_HOST_RELAY_START
- * - GNUNET_MESSAGE_TYPE_SOCIAL_HOST_RELAY_STOP
+ * Type: GNUNET_MESSAGE_TYPE_SOCIAL_MSG_PROC_SET
*/
struct GNUNET_MessageHeader header;
- /* Followed by char *method_name */
+ /**
+ * @see enum GNUNET_SOCIAL_MsgProcFlags
+ */
+ uint32_t flags;
+
+ /* Followed by char *method_prefix */
};
diff --git a/src/social/social_api.c b/src/social/social_api.c
index 3404160a9..a8433ee24 100644
--- a/src/social/social_api.c
+++ b/src/social/social_api.c
@@ -149,12 +149,7 @@ struct GNUNET_SOCIAL_Place
struct GNUNET_PSYC_TransmitHandle *tmit;
/**
- * Receipt handle.
- */
- struct GNUNET_PSYC_ReceiveHandle *recv;
-
- /**
- * Slicer for processing incoming methods.
+ * Slicer for processing incoming messages.
*/
struct GNUNET_PSYC_Slicer *slicer;
@@ -204,12 +199,7 @@ struct GNUNET_SOCIAL_Host
struct GNUNET_SOCIAL_Place plc;
/**
- * Receipt handle.
- */
- struct GNUNET_PSYC_ReceiveHandle *recv;
-
- /**
- * Slicer for processing incoming methods.
+ * Slicer for processing incoming messages from guests.
*/
struct GNUNET_PSYC_Slicer *slicer;
@@ -236,16 +226,6 @@ struct GNUNET_SOCIAL_Guest
{
struct GNUNET_SOCIAL_Place plc;
- /**
- * Receipt handle.
- */
- struct GNUNET_PSYC_ReceiveHandle *recv;
-
- /**
- * Slicer for processing incoming methods.
- */
- struct GNUNET_PSYC_Slicer *slicer;
-
GNUNET_SOCIAL_GuestEnterCallback enter_cb;
GNUNET_SOCIAL_EntryDecisionCallback entry_dcsn_cb;
@@ -298,9 +278,9 @@ struct GNUNET_SOCIAL_HistoryRequest
uint64_t op_id;
/**
- * Message handler.
+ * Slicer for processing incoming messages.
*/
- struct GNUNET_PSYC_ReceiveHandle *recv;
+ struct GNUNET_PSYC_Slicer *slicer;
/**
* Function to call when the operation finished.
@@ -519,6 +499,7 @@ app_send_connect_msg (struct GNUNET_SOCIAL_App *app)
struct GNUNET_MessageHeader * cmsg = GNUNET_malloc (cmsg_size);
memcpy (cmsg, app->connect_msg, cmsg_size);
GNUNET_CLIENT_MANAGER_transmit_now (app->client, cmsg);
+ GNUNET_free (cmsg);
}
@@ -545,6 +526,7 @@ place_send_connect_msg (struct GNUNET_SOCIAL_Place *plc)
struct GNUNET_MessageHeader * cmsg = GNUNET_malloc (cmsg_size);
memcpy (cmsg, plc->connect_msg, cmsg_size);
GNUNET_CLIENT_MANAGER_transmit_now (plc->client, cmsg);
+ GNUNET_free (cmsg);
}
@@ -625,7 +607,6 @@ op_recv_history_result (void *cls, int64_t result,
if (NULL != hist->result_cb)
hist->result_cb (hist->cls, result, err_msg, err_msg_size);
- GNUNET_PSYC_receive_destroy (hist->recv);
GNUNET_free (hist);
}
@@ -684,8 +665,8 @@ place_recv_history_result (void *cls,
return;
}
- GNUNET_PSYC_receive_message (hist->recv,
- (const struct GNUNET_PSYC_MessageHeader *) pmsg);
+ GNUNET_PSYC_slicer_message (hist->slicer,
+ (const struct GNUNET_PSYC_MessageHeader *) pmsg);
}
@@ -781,7 +762,7 @@ place_recv_message (void *cls,
{
struct GNUNET_SOCIAL_Place *
plc = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (*plc));
- GNUNET_PSYC_receive_message (plc->recv,
+ GNUNET_PSYC_slicer_message (plc->slicer,
(const struct GNUNET_PSYC_MessageHeader *) msg);
}
@@ -793,10 +774,10 @@ host_recv_message (void *cls,
{
struct GNUNET_SOCIAL_Host *
hst = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (hst->plc));
- GNUNET_PSYC_receive_message (hst->recv,
- (const struct GNUNET_PSYC_MessageHeader *) msg);
- GNUNET_PSYC_receive_message (hst->plc.recv,
- (const struct GNUNET_PSYC_MessageHeader *) msg);
+ GNUNET_PSYC_slicer_message (hst->slicer,
+ (const struct GNUNET_PSYC_MessageHeader *) msg);
+ GNUNET_PSYC_slicer_message (hst->plc.slicer,
+ (const struct GNUNET_PSYC_MessageHeader *) msg);
}
@@ -855,7 +836,7 @@ host_recv_enter_request (void *cls,
&data, &data_size))
{
GNUNET_break_op (0);
- str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&req->slave_key);
+ str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&req->slave_pub_key);
LOG (GNUNET_ERROR_TYPE_WARNING,
"Ignoring invalid entry request from nym %s.\n",
str);
@@ -864,7 +845,7 @@ host_recv_enter_request (void *cls,
}
}
- struct GNUNET_SOCIAL_Nym *nym = nym_get_or_create (&req->slave_key);
+ struct GNUNET_SOCIAL_Nym *nym = nym_get_or_create (&req->slave_pub_key);
hst->answer_door_cb (hst->cb_cls, nym, method_name, env,
data_size, data);
} while (0);
@@ -1098,8 +1079,6 @@ place_cleanup (struct GNUNET_SOCIAL_Place *plc)
{
if (NULL != plc->tmit)
GNUNET_PSYC_transmit_destroy (plc->tmit);
- if (NULL != plc->recv)
- GNUNET_PSYC_receive_destroy (plc->recv);
if (NULL != plc->connect_msg)
GNUNET_free (plc->connect_msg);
if (NULL != plc->disconnect_cb)
@@ -1112,11 +1091,6 @@ host_cleanup (void *cls)
{
struct GNUNET_SOCIAL_Host *hst = cls;
place_cleanup (&hst->plc);
- if (NULL != hst->recv)
- {
- GNUNET_PSYC_receive_destroy (hst->recv);
- hst->recv = NULL;
- }
if (NULL != hst->slicer)
{
GNUNET_PSYC_slicer_destroy (hst->slicer);
@@ -1191,14 +1165,12 @@ GNUNET_SOCIAL_host_enter (const struct GNUNET_SOCIAL_App *app,
GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, hst, sizeof (*plc));
plc->tmit = GNUNET_PSYC_transmit_create (plc->client);
- plc->recv = GNUNET_PSYC_receive_create (NULL, GNUNET_PSYC_slicer_message, plc->slicer);
hst->slicer = GNUNET_PSYC_slicer_create ();
GNUNET_PSYC_slicer_method_add (hst->slicer, "_notice_place_leave",
host_recv_notice_place_leave_method,
host_recv_notice_place_leave_modifier,
NULL, host_recv_notice_place_leave_eom, hst);
- hst->recv = GNUNET_PSYC_receive_create (NULL, GNUNET_PSYC_slicer_message, hst->slicer);
uint16_t app_id_size = strlen (app->id) + 1;
struct HostEnterRequest *hreq = GNUNET_malloc (sizeof (*hreq) + app_id_size);
@@ -1263,14 +1235,12 @@ GNUNET_SOCIAL_host_enter_reconnect (struct GNUNET_SOCIAL_HostConnection *hconn,
GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, hst, sizeof (*plc));
plc->tmit = GNUNET_PSYC_transmit_create (plc->client);
- plc->recv = GNUNET_PSYC_receive_create (NULL, GNUNET_PSYC_slicer_message, plc->slicer);
hst->slicer = GNUNET_PSYC_slicer_create ();
GNUNET_PSYC_slicer_method_add (hst->slicer, "_notice_place_leave",
host_recv_notice_place_leave_method,
host_recv_notice_place_leave_modifier,
NULL, host_recv_notice_place_leave_eom, hst);
- hst->recv = GNUNET_PSYC_receive_create (NULL, GNUNET_PSYC_slicer_message, hst->slicer);
hreq->header.size = htons (sizeof (*hreq) + app_id_size);
hreq->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER);
@@ -1325,12 +1295,13 @@ GNUNET_SOCIAL_host_entry_decision (struct GNUNET_SOCIAL_Host *hst,
dcsn->header.size = htons (sizeof (*dcsn) + entry_resp_size);
dcsn->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION);
dcsn->is_admitted = htonl (is_admitted);
- dcsn->slave_key = nym->pub_key;
+ dcsn->slave_pub_key = nym->pub_key;
if (0 < entry_resp_size)
memcpy (&dcsn[1], entry_resp, entry_resp_size);
GNUNET_CLIENT_MANAGER_transmit (hst->plc.client, &dcsn->header);
+ GNUNET_free (dcsn);
return GNUNET_OK;
}
@@ -1690,7 +1661,6 @@ GNUNET_SOCIAL_guest_enter (const struct GNUNET_SOCIAL_App *app,
GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, gst, sizeof (*plc));
plc->tmit = GNUNET_PSYC_transmit_create (plc->client);
- plc->recv = GNUNET_PSYC_receive_create (NULL, GNUNET_PSYC_slicer_message, plc->slicer);
struct GuestEnterRequest *
greq = guest_enter_request_create (app->id, &ego->pub_key, &plc->pub_key,
@@ -1782,7 +1752,6 @@ GNUNET_SOCIAL_guest_enter_by_name (const struct GNUNET_SOCIAL_App *app,
GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, gst, sizeof (*plc));
plc->tmit = GNUNET_PSYC_transmit_create (plc->client);
- plc->recv = GNUNET_PSYC_receive_create (NULL, GNUNET_PSYC_slicer_message, plc->slicer);
plc->connect_msg = &greq->header;
place_send_connect_msg (plc);
@@ -1842,7 +1811,6 @@ GNUNET_SOCIAL_guest_enter_reconnect (struct GNUNET_SOCIAL_GuestConnection *gconn
GNUNET_CLIENT_MANAGER_set_user_context_ (plc->client, gst, sizeof (*plc));
plc->tmit = GNUNET_PSYC_transmit_create (plc->client);
- plc->recv = GNUNET_PSYC_receive_create (NULL, GNUNET_PSYC_slicer_message, plc->slicer);
plc->connect_msg = &greq->header;
place_send_connect_msg (plc);
@@ -1994,6 +1962,52 @@ GNUNET_SOCIAL_place_get_key (struct GNUNET_SOCIAL_Place *plc)
}
+/**
+ * Set message processing @a flags for a @a method_prefix.
+ *
+ * @param plc
+ * Place.
+ * @param method_prefix
+ * Method prefix @a flags apply to.
+ * @param flags
+ * The flags that apply to a matching @a method_prefix.
+ */
+void
+GNUNET_SOCIAL_place_msg_proc_set (struct GNUNET_SOCIAL_Place *plc,
+ const char *method_prefix,
+ enum GNUNET_SOCIAL_MsgProcFlags flags)
+{
+ GNUNET_assert (NULL != method_prefix);
+ struct MsgProcRequest *mpreq;
+ uint16_t method_size = strnlen (method_prefix,
+ GNUNET_SERVER_MAX_MESSAGE_SIZE
+ - sizeof (*mpreq)) + 1;
+ GNUNET_assert ('\0' == method_prefix[method_size - 1]);
+ mpreq = GNUNET_malloc (sizeof (*mpreq) + method_size);
+
+ mpreq->header.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_MSG_PROC_SET);
+ mpreq->header.size = htons (sizeof (*mpreq) + method_size);
+ mpreq->flags = htonl (flags);
+ memcpy (&mpreq[1], method_prefix, method_size);
+
+ GNUNET_CLIENT_MANAGER_transmit (plc->client, &mpreq->header);
+ GNUNET_free (mpreq);
+}
+
+
+/**
+ * Clear all message processing flags previously set for this place.
+ */
+void
+GNUNET_SOCIAL_place_msg_proc_clear (struct GNUNET_SOCIAL_Place *plc)
+{
+ struct GNUNET_MessageHeader req;
+ req.type = htons (GNUNET_MESSAGE_TYPE_SOCIAL_MSG_PROC_CLEAR);
+ req.size = htons (sizeof (req));
+ GNUNET_CLIENT_MANAGER_transmit (plc->client, &req);
+}
+
+
static struct GNUNET_SOCIAL_HistoryRequest *
place_history_replay (struct GNUNET_SOCIAL_Place *plc,
uint64_t start_message_id,
@@ -2008,7 +2022,7 @@ place_history_replay (struct GNUNET_SOCIAL_Place *plc,
struct GNUNET_PSYC_HistoryRequestMessage *req;
struct GNUNET_SOCIAL_HistoryRequest *hist = GNUNET_malloc (sizeof (*hist));
hist->plc = plc;
- hist->recv = GNUNET_PSYC_receive_create (NULL, GNUNET_PSYC_slicer_message, slicer);
+ hist->slicer = slicer;
hist->result_cb = result_cb;
hist->cls = cls;
hist->op_id = GNUNET_CLIENT_MANAGER_op_add (plc->client,
@@ -2030,6 +2044,7 @@ place_history_replay (struct GNUNET_SOCIAL_Place *plc,
memcpy (&req[1], method_prefix, method_size);
GNUNET_CLIENT_MANAGER_transmit (plc->client, &req->header);
+ GNUNET_free (req);
return hist;
}
@@ -2118,7 +2133,6 @@ GNUNET_SOCIAL_place_history_replay_latest (struct GNUNET_SOCIAL_Place *plc,
void
GNUNET_SOCIAL_place_history_replay_cancel (struct GNUNET_SOCIAL_HistoryRequest *hist)
{
- GNUNET_PSYC_receive_destroy (hist->recv);
GNUNET_CLIENT_MANAGER_op_cancel (hist->plc->client, hist->op_id);
GNUNET_free (hist);
}
@@ -2152,6 +2166,7 @@ place_state_get (struct GNUNET_SOCIAL_Place *plc,
memcpy (&req[1], name, name_size);
GNUNET_CLIENT_MANAGER_transmit (plc->client, &req->header);
+ GNUNET_free (req);
return look;
}
@@ -2314,6 +2329,7 @@ GNUNET_SOCIAL_zone_add_place (const struct GNUNET_SOCIAL_App *app,
op_recv_zone_add_place_result,
add_plc));
GNUNET_CLIENT_MANAGER_transmit_now (app->client, &preq->header);
+ GNUNET_free (preq);
return GNUNET_OK;
}