+ }
+ GNUNET_free_non_null (cl);
+}
+
+
+/**
+ * Check if some client is monitoring GET RESP messages and notify
+ * them in that case.
+ *
+ * @param type The type of data in the result.
+ * @param get_path Peers on GET path (or NULL if not recorded).
+ * @param get_path_length number of entries in get_path.
+ * @param put_path peers on the PUT path (or NULL if not recorded).
+ * @param put_path_length number of entries in get_path.
+ * @param exp Expiration time of the data.
+ * @param key Key of the data.
+ * @param data Pointer to the result data.
+ * @param size Number of bytes in @a data.
+ */
+void
+GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type,
+ const struct GNUNET_PeerIdentity *get_path,
+ unsigned int get_path_length,
+ const struct GNUNET_PeerIdentity *put_path,
+ unsigned int put_path_length,
+ struct GNUNET_TIME_Absolute exp,
+ const struct GNUNET_HashCode * key,
+ const void *data,
+ size_t size)
+{
+ struct ClientMonitorRecord *m;
+ struct ClientHandle **cl;
+ unsigned int cl_size;
+
+ cl = NULL;
+ cl_size = 0;
+ for (m = monitor_head; NULL != m; m = m->next)
+ {
+ if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) &&
+ (NULL == m->key ||
+ memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0))
+ {
+ struct GNUNET_MQ_Envelope *env;
+ struct GNUNET_DHT_MonitorGetRespMessage *mmsg;
+ struct GNUNET_PeerIdentity *path;
+ size_t msize;
+ unsigned int i;
+
+ /* Don't send duplicates */
+ for (i = 0; i < cl_size; i++)
+ if (cl[i] == m->ch)
+ break;
+ if (i < cl_size)
+ continue;
+ GNUNET_array_append (cl,
+ cl_size,
+ m->ch);
+
+ msize = size;
+ msize += (get_path_length + put_path_length)
+ * sizeof (struct GNUNET_PeerIdentity);
+ env = GNUNET_MQ_msg_extra (mmsg,
+ msize,
+ GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP);
+ mmsg->type = htonl(type);
+ mmsg->put_path_length = htonl(put_path_length);
+ mmsg->get_path_length = htonl(get_path_length);
+ mmsg->expiration_time = GNUNET_TIME_absolute_hton(exp);
+ mmsg->key = *key;
+ path = (struct GNUNET_PeerIdentity *) &mmsg[1];
+ GNUNET_memcpy (path,
+ put_path,
+ put_path_length * sizeof (struct GNUNET_PeerIdentity));
+ GNUNET_memcpy (path,
+ get_path,
+ get_path_length * sizeof (struct GNUNET_PeerIdentity));
+ GNUNET_memcpy (&path[get_path_length],
+ data,
+ size);
+ GNUNET_MQ_send (m->ch->mq,
+ env);
+ }
+ }
+ GNUNET_free_non_null (cl);
+}
+
+
+/**
+ * Check if some client is monitoring PUT messages and notify
+ * them in that case.
+ *
+ * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
+ * @param type The type of data in the request.
+ * @param hop_count Hop count so far.
+ * @param path_length number of entries in path (or 0 if not recorded).
+ * @param path peers on the PUT path (or NULL if not recorded).
+ * @param desired_replication_level Desired replication level.
+ * @param exp Expiration time of the data.
+ * @param key Key under which data is to be stored.
+ * @param data Pointer to the data carried.
+ * @param size Number of bytes in data.
+ */
+void
+GDS_CLIENTS_process_put (uint32_t options,
+ enum GNUNET_BLOCK_Type type,
+ uint32_t hop_count,
+ uint32_t desired_replication_level,
+ unsigned int path_length,
+ const struct GNUNET_PeerIdentity *path,
+ struct GNUNET_TIME_Absolute exp,
+ const struct GNUNET_HashCode *key,
+ const void *data,
+ size_t size)
+{
+ struct ClientMonitorRecord *m;
+ struct ClientHandle **cl;
+ unsigned int cl_size;
+
+ cl = NULL;
+ cl_size = 0;
+ for (m = monitor_head; NULL != m; m = m->next)
+ {
+ if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) &&
+ (NULL == m->key ||
+ memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0))
+ {
+ struct GNUNET_MQ_Envelope *env;
+ struct GNUNET_DHT_MonitorPutMessage *mmsg;
+ struct GNUNET_PeerIdentity *msg_path;
+ size_t msize;
+ unsigned int i;
+
+ /* Don't send duplicates */
+ for (i = 0; i < cl_size; i++)
+ if (cl[i] == m->ch)
+ break;
+ if (i < cl_size)
+ continue;
+ GNUNET_array_append (cl,
+ cl_size,
+ m->ch);
+
+ msize = size;
+ msize += path_length * sizeof (struct GNUNET_PeerIdentity);
+ env = GNUNET_MQ_msg_extra (mmsg,
+ msize,
+ GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT);
+ mmsg->options = htonl(options);
+ mmsg->type = htonl(type);
+ mmsg->hop_count = htonl(hop_count);
+ mmsg->desired_replication_level = htonl (desired_replication_level);
+ mmsg->put_path_length = htonl (path_length);
+ mmsg->key = *key;
+ mmsg->expiration_time = GNUNET_TIME_absolute_hton (exp);
+ msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1];
+ GNUNET_memcpy (msg_path,
+ path,
+ path_length * sizeof (struct GNUNET_PeerIdentity));
+ GNUNET_memcpy (&msg_path[path_length],
+ data,
+ size);
+ GNUNET_MQ_send (m->ch->mq,
+ env);
+ }
+ }
+ GNUNET_free_non_null (cl);