diff options
author | Bart Polot <bart@net.in.tum.de> | 2012-01-04 20:00:59 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2012-01-04 20:00:59 +0000 |
commit | 09372b5120f5905546bd4e73f02f8afeec7e1b1e (patch) | |
tree | c9f301491073ca43d34152683d7b108a52e24288 /src/dht | |
parent | c3a877682c2ce72aa38c58642875563b918aca86 (diff) | |
download | gnunet-09372b5120f5905546bd4e73f02f8afeec7e1b1e.tar.gz gnunet-09372b5120f5905546bd4e73f02f8afeec7e1b1e.zip |
New DHT-monitor functionality
Diffstat (limited to 'src/dht')
-rw-r--r-- | src/dht/dht.h | 63 | ||||
-rw-r--r-- | src/dht/dht_api.c | 181 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_clients.c | 175 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_clients.h | 29 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_neighbours.c | 14 |
5 files changed, 462 insertions, 0 deletions
diff --git a/src/dht/dht.h b/src/dht/dht.h index c9fdd3479..9894be89c 100644 --- a/src/dht/dht.h +++ b/src/dht/dht.h | |||
@@ -193,6 +193,69 @@ struct GNUNET_DHT_ClientPutMessage | |||
193 | /* DATA copied to end of this message */ | 193 | /* DATA copied to end of this message */ |
194 | 194 | ||
195 | }; | 195 | }; |
196 | |||
197 | |||
198 | /** | ||
199 | * Message to monitor requests going through peer, clients <--> DHT service. | ||
200 | */ | ||
201 | struct GNUNET_DHT_MonitorMessage | ||
202 | { | ||
203 | /** | ||
204 | * Type: GNUNET_MESSAGE_TYPE_DHT_MONITOR_{GET, PUT, GET_RESP, PUT_RESP*} | ||
205 | * (*) not yet implemented, necessary for key randomization | ||
206 | */ | ||
207 | struct GNUNET_MessageHeader header; | ||
208 | |||
209 | /** | ||
210 | * The type of data in the request. | ||
211 | */ | ||
212 | uint32_t type GNUNET_PACKED; | ||
213 | |||
214 | /** | ||
215 | * Message options, actually an 'enum GNUNET_DHT_RouteOption' value. | ||
216 | */ | ||
217 | uint32_t options GNUNET_PACKED; | ||
218 | |||
219 | /** | ||
220 | * Replication level for this message | ||
221 | */ | ||
222 | uint32_t desired_replication_level GNUNET_PACKED; | ||
223 | |||
224 | /** | ||
225 | * Number of peers recorded in the outgoing path from source to the | ||
226 | * storgage location of this message. | ||
227 | */ | ||
228 | uint32_t put_path_length GNUNET_PACKED; | ||
229 | |||
230 | /** | ||
231 | * The number of peer identities recorded from the storage location | ||
232 | * to this peer. | ||
233 | */ | ||
234 | uint32_t get_path_length GNUNET_PACKED; | ||
235 | |||
236 | /** | ||
237 | * Unique ID for GET / GET responses. | ||
238 | */ | ||
239 | uint64_t unique_id GNUNET_PACKED; | ||
240 | |||
241 | /** | ||
242 | * How long should this data persist? | ||
243 | */ | ||
244 | struct GNUNET_TIME_AbsoluteNBO expiration; | ||
245 | |||
246 | /** | ||
247 | * The key to store the value under. | ||
248 | */ | ||
249 | GNUNET_HashCode key; | ||
250 | |||
251 | /* put path (if tracked) */ | ||
252 | |||
253 | /* get path (if tracked) */ | ||
254 | |||
255 | /* Payload */ | ||
256 | |||
257 | }; | ||
258 | |||
196 | GNUNET_NETWORK_STRUCT_END | 259 | GNUNET_NETWORK_STRUCT_END |
197 | 260 | ||
198 | #endif | 261 | #endif |
diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c index ac69b7a4e..3f0d709e0 100644 --- a/src/dht/dht_api.c +++ b/src/dht/dht_api.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "gnunet_protocols.h" | 33 | #include "gnunet_protocols.h" |
34 | #include "gnunet_dht_service.h" | 34 | #include "gnunet_dht_service.h" |
35 | #include "dht.h" | 35 | #include "dht.h" |
36 | #include <gnunet_dnsparser_lib.h> | ||
36 | 37 | ||
37 | #define DEBUG_DHT_API GNUNET_EXTRA_LOGGING | 38 | #define DEBUG_DHT_API GNUNET_EXTRA_LOGGING |
38 | 39 | ||
@@ -143,6 +144,49 @@ struct GNUNET_DHT_GetHandle | |||
143 | 144 | ||
144 | 145 | ||
145 | /** | 146 | /** |
147 | * Handle to a monitoring request. | ||
148 | */ | ||
149 | struct GNUNET_DHT_MonitorHandle | ||
150 | { | ||
151 | /** | ||
152 | * DLL. | ||
153 | */ | ||
154 | struct GNUNET_DHT_MonitorHandle *next; | ||
155 | |||
156 | /** | ||
157 | * DLL. | ||
158 | */ | ||
159 | struct GNUNET_DHT_MonitorHandle *prev; | ||
160 | |||
161 | /** | ||
162 | * Main handle to this DHT api. | ||
163 | */ | ||
164 | struct GNUNET_DHT_Handle *dht_handle; | ||
165 | |||
166 | /** | ||
167 | * Type of block looked for. | ||
168 | */ | ||
169 | enum GNUNET_BLOCK_Type type; | ||
170 | |||
171 | /** | ||
172 | * Key being looked for, NULL == all. | ||
173 | */ | ||
174 | GNUNET_HashCode *key; | ||
175 | |||
176 | /** | ||
177 | * Callback for each received message of interest. | ||
178 | */ | ||
179 | GNUNET_DHT_MonitorCB cb; | ||
180 | |||
181 | /** | ||
182 | * Closure for cb. | ||
183 | */ | ||
184 | void *cb_cls; | ||
185 | |||
186 | }; | ||
187 | |||
188 | |||
189 | /** | ||
146 | * Connection to the DHT service. | 190 | * Connection to the DHT service. |
147 | */ | 191 | */ |
148 | struct GNUNET_DHT_Handle | 192 | struct GNUNET_DHT_Handle |
@@ -174,6 +218,16 @@ struct GNUNET_DHT_Handle | |||
174 | struct PendingMessage *pending_tail; | 218 | struct PendingMessage *pending_tail; |
175 | 219 | ||
176 | /** | 220 | /** |
221 | * Head of linked list of messages we would like to monitor. | ||
222 | */ | ||
223 | struct GNUNET_DHT_MonitorHandle *monitor_head; | ||
224 | |||
225 | /** | ||
226 | * Tail of linked list of messages we would like to monitor. | ||
227 | */ | ||
228 | struct GNUNET_DHT_MonitorHandle *monitor_tail; | ||
229 | |||
230 | /** | ||
177 | * Hash map containing the current outstanding unique requests | 231 | * Hash map containing the current outstanding unique requests |
178 | * (values are of type 'struct GNUNET_DHT_RouteHandle'). | 232 | * (values are of type 'struct GNUNET_DHT_RouteHandle'). |
179 | */ | 233 | */ |
@@ -501,6 +555,62 @@ process_reply (void *cls, const GNUNET_HashCode * key, void *value) | |||
501 | 555 | ||
502 | 556 | ||
503 | /** | 557 | /** |
558 | * Process a monitoring message from the service. | ||
559 | * | ||
560 | * @param handle The DHT handle. | ||
561 | * @param msg Message from the service. | ||
562 | * | ||
563 | * @return GNUNET_OK if everything went fine, | ||
564 | * GNUNET_SYSERR if the message is malformed. | ||
565 | */ | ||
566 | static int | ||
567 | process_monitor_message (struct GNUNET_DHT_Handle *handle, | ||
568 | const struct GNUNET_MessageHeader *msg) | ||
569 | { | ||
570 | struct GNUNET_DHT_MonitorMessage *m; | ||
571 | struct GNUNET_DHT_MonitorHandle *h; | ||
572 | size_t msize; | ||
573 | |||
574 | if (ntohs (msg->type) < GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET || | ||
575 | ntohs (msg->type) > GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT) | ||
576 | return GNUNET_SYSERR; | ||
577 | msize = ntohs (msg->size); | ||
578 | if (msize < sizeof (struct GNUNET_DHT_MonitorMessage)) | ||
579 | return GNUNET_SYSERR; | ||
580 | |||
581 | m = (struct GNUNET_DHT_MonitorMessage *) msg; | ||
582 | h = handle->monitor_head; | ||
583 | while (NULL != h) | ||
584 | { | ||
585 | if (h->type == ntohl(m->type) && | ||
586 | (NULL == h->key || | ||
587 | memcmp (h->key, &m->key, sizeof (GNUNET_HashCode)) == 0)) | ||
588 | { | ||
589 | struct GNUNET_PeerIdentity *path; | ||
590 | uint32_t getl; | ||
591 | uint32_t putl; | ||
592 | |||
593 | path = (struct GNUNET_PeerIdentity *) &m[1]; | ||
594 | getl = ntohl (m->get_path_length); | ||
595 | putl = ntohl (m->put_path_length); | ||
596 | h->cb (h->cb_cls, ntohs(msg->type), | ||
597 | GNUNET_TIME_absolute_ntoh(m->expiration), | ||
598 | &m->key, | ||
599 | &path[getl], putl, path, getl, | ||
600 | ntohl (m->desired_replication_level), | ||
601 | ntohl (m->options), ntohl (m->type), | ||
602 | (void *) &path[getl + putl], | ||
603 | ntohs (msg->size) - | ||
604 | sizeof (struct GNUNET_DHT_MonitorMessage) - | ||
605 | sizeof (struct GNUNET_PeerIdentity) * (putl + getl)); | ||
606 | } | ||
607 | h = h->next; | ||
608 | } | ||
609 | |||
610 | return GNUNET_OK; | ||
611 | } | ||
612 | |||
613 | /** | ||
504 | * Handler for messages received from the DHT service | 614 | * Handler for messages received from the DHT service |
505 | * a demultiplexer which handles numerous message types | 615 | * a demultiplexer which handles numerous message types |
506 | * | 616 | * |
@@ -524,6 +634,8 @@ service_message_handler (void *cls, const struct GNUNET_MessageHeader *msg) | |||
524 | } | 634 | } |
525 | if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT) | 635 | if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT) |
526 | { | 636 | { |
637 | if (process_monitor_message (handle, msg) == GNUNET_OK) | ||
638 | return; | ||
527 | GNUNET_break (0); | 639 | GNUNET_break (0); |
528 | do_disconnect (handle); | 640 | do_disconnect (handle); |
529 | return; | 641 | return; |
@@ -832,4 +944,73 @@ GNUNET_DHT_get_stop (struct GNUNET_DHT_GetHandle *get_handle) | |||
832 | } | 944 | } |
833 | 945 | ||
834 | 946 | ||
947 | /** | ||
948 | * Start monitoring the local DHT service. | ||
949 | * | ||
950 | * @param handle Handle to the DHT service. | ||
951 | * @param type Type of blocks that are of interest. | ||
952 | * @param key Key of data of interest, NULL for all. | ||
953 | * @param cb Callback to process all monitored data. | ||
954 | * @param cb_cls Closure for cb. | ||
955 | * | ||
956 | * @return Handle to stop monitoring. | ||
957 | */ | ||
958 | struct GNUNET_DHT_MonitorHandle * | ||
959 | GNUNET_DHT_monitor_start (struct GNUNET_DHT_Handle *handle, | ||
960 | enum GNUNET_BLOCK_Type type, | ||
961 | const GNUNET_HashCode *key, | ||
962 | GNUNET_DHT_MonitorCB cb, | ||
963 | void *cb_cls) | ||
964 | { | ||
965 | struct GNUNET_DHT_MonitorHandle *h; | ||
966 | struct GNUNET_DHT_MonitorMessage *m; | ||
967 | struct PendingMessage *pending; | ||
968 | |||
969 | h = GNUNET_malloc (sizeof (struct GNUNET_DHT_MonitorHandle)); | ||
970 | GNUNET_CONTAINER_DLL_insert(handle->monitor_head, handle->monitor_tail, h); | ||
971 | |||
972 | h->cb = cb; | ||
973 | h->cb_cls = cb_cls; | ||
974 | h->type = type; | ||
975 | h->dht_handle = handle; | ||
976 | if (NULL != key) | ||
977 | { | ||
978 | h->key = GNUNET_malloc (sizeof(GNUNET_HashCode)); | ||
979 | memcpy (h->key, key, sizeof(GNUNET_HashCode)); | ||
980 | } | ||
981 | |||
982 | pending = GNUNET_malloc (sizeof (struct GNUNET_DHT_MonitorMessage) + | ||
983 | sizeof (struct PendingMessage)); | ||
984 | m = (struct GNUNET_DHT_MonitorMessage *) &pending[1]; | ||
985 | pending->msg = &m->header; | ||
986 | pending->handle = handle; | ||
987 | pending->free_on_send = GNUNET_YES; | ||
988 | GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail, | ||
989 | pending); | ||
990 | pending->in_pending_queue = GNUNET_YES; | ||
991 | process_pending_messages (handle); | ||
992 | |||
993 | return h; | ||
994 | } | ||
995 | |||
996 | |||
997 | /** | ||
998 | * Stop monitoring. | ||
999 | * | ||
1000 | * @param handle The handle to the monitor request returned by monitor_start. | ||
1001 | * | ||
1002 | * On return get_handle will no longer be valid, caller must not use again!!! | ||
1003 | */ | ||
1004 | void | ||
1005 | GNUNET_DHT_monitor_stop (struct GNUNET_DHT_MonitorHandle *handle) | ||
1006 | { | ||
1007 | GNUNET_free_non_null (handle->key); | ||
1008 | GNUNET_CONTAINER_DLL_remove (handle->dht_handle->monitor_head, | ||
1009 | handle->dht_handle->monitor_tail, | ||
1010 | handle); | ||
1011 | GNUNET_free (handle); | ||
1012 | } | ||
1013 | |||
1014 | |||
1015 | |||
835 | /* end of dht_api.c */ | 1016 | /* end of dht_api.c */ |
diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c index dde8c6d7a..7642dc6c3 100644 --- a/src/dht/gnunet-service-dht_clients.c +++ b/src/dht/gnunet-service-dht_clients.c | |||
@@ -178,6 +178,39 @@ struct ClientQueryRecord | |||
178 | 178 | ||
179 | 179 | ||
180 | /** | 180 | /** |
181 | * Struct containing paremeters of monitoring requests. | ||
182 | */ | ||
183 | struct ClientMonitorRecord | ||
184 | { | ||
185 | |||
186 | /** | ||
187 | * Next element in DLL. | ||
188 | */ | ||
189 | struct ClientMonitorRecord *next; | ||
190 | |||
191 | /** | ||
192 | * Previous element in DLL. | ||
193 | */ | ||
194 | struct ClientMonitorRecord *prev; | ||
195 | |||
196 | /** | ||
197 | * Type of blocks that are of interest | ||
198 | */ | ||
199 | enum GNUNET_BLOCK_Type type; | ||
200 | |||
201 | /** | ||
202 | * Key of data of interest, NULL for all. | ||
203 | */ | ||
204 | GNUNET_HashCode *key; | ||
205 | |||
206 | /** | ||
207 | * Client to notify of these requests. | ||
208 | */ | ||
209 | struct ClientList *client; | ||
210 | }; | ||
211 | |||
212 | |||
213 | /** | ||
181 | * List of active clients. | 214 | * List of active clients. |
182 | */ | 215 | */ |
183 | static struct ClientList *client_head; | 216 | static struct ClientList *client_head; |
@@ -188,6 +221,16 @@ static struct ClientList *client_head; | |||
188 | static struct ClientList *client_tail; | 221 | static struct ClientList *client_tail; |
189 | 222 | ||
190 | /** | 223 | /** |
224 | * List of active monitoring requests. | ||
225 | */ | ||
226 | static struct ClientMonitorRecord *monitor_head; | ||
227 | |||
228 | /** | ||
229 | * List of active monitoring requests.. | ||
230 | */ | ||
231 | static struct ClientMonitorRecord *monitor_tail; | ||
232 | |||
233 | /** | ||
191 | * Hashmap for fast key based lookup, maps keys to 'struct ClientQueryRecord' entries. | 234 | * Hashmap for fast key based lookup, maps keys to 'struct ClientQueryRecord' entries. |
192 | */ | 235 | */ |
193 | static struct GNUNET_CONTAINER_MultiHashMap *forward_map; | 236 | static struct GNUNET_CONTAINER_MultiHashMap *forward_map; |
@@ -275,6 +318,7 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) | |||
275 | { | 318 | { |
276 | struct ClientList *pos; | 319 | struct ClientList *pos; |
277 | struct PendingMessage *reply; | 320 | struct PendingMessage *reply; |
321 | struct ClientMonitorRecord *monitor; | ||
278 | 322 | ||
279 | #if DEBUG_DHT | 323 | #if DEBUG_DHT |
280 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Local client %p disconnects\n", client); | 324 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Local client %p disconnects\n", client); |
@@ -288,6 +332,22 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) | |||
288 | GNUNET_CONTAINER_DLL_remove (pos->pending_head, pos->pending_tail, reply); | 332 | GNUNET_CONTAINER_DLL_remove (pos->pending_head, pos->pending_tail, reply); |
289 | GNUNET_free (reply); | 333 | GNUNET_free (reply); |
290 | } | 334 | } |
335 | monitor = monitor_head; | ||
336 | while (NULL != monitor) | ||
337 | { | ||
338 | if (monitor->client == pos) | ||
339 | { | ||
340 | struct ClientMonitorRecord *next; | ||
341 | |||
342 | GNUNET_free_non_null (monitor->key); | ||
343 | next = monitor->next; | ||
344 | GNUNET_CONTAINER_DLL_remove (monitor_head, monitor_tail, monitor); | ||
345 | GNUNET_free (monitor); | ||
346 | monitor = next; | ||
347 | } | ||
348 | else | ||
349 | monitor = monitor->next; | ||
350 | } | ||
291 | GNUNET_CONTAINER_multihashmap_iterate (forward_map, &remove_client_records, | 351 | GNUNET_CONTAINER_multihashmap_iterate (forward_map, &remove_client_records, |
292 | pos); | 352 | pos); |
293 | GNUNET_free (pos); | 353 | GNUNET_free (pos); |
@@ -576,6 +636,41 @@ handle_dht_local_get_stop (void *cls, struct GNUNET_SERVER_Client *client, | |||
576 | 636 | ||
577 | 637 | ||
578 | /** | 638 | /** |
639 | * Handler for monitor messages | ||
640 | * | ||
641 | * @param cls closure for the service | ||
642 | * @param client the client we received this message from | ||
643 | * @param message the actual message received | ||
644 | * | ||
645 | */ | ||
646 | static void | ||
647 | handle_dht_local_monitor (void *cls, struct GNUNET_SERVER_Client *client, | ||
648 | const struct GNUNET_MessageHeader *message) | ||
649 | { | ||
650 | struct ClientMonitorRecord *r; | ||
651 | const struct GNUNET_DHT_MonitorMessage *msg; | ||
652 | unsigned int i; | ||
653 | char *c; | ||
654 | |||
655 | msg = (struct GNUNET_DHT_MonitorMessage *) message; | ||
656 | r = GNUNET_malloc (sizeof(struct ClientMonitorRecord)); | ||
657 | |||
658 | r->client = find_active_client(client); | ||
659 | r->type = ntohl(msg->type); | ||
660 | c = (char *) &msg->key; | ||
661 | for (i = 0; i < sizeof (GNUNET_HashCode) && c[i] == 0; i++); | ||
662 | if (sizeof (GNUNET_HashCode) == i) | ||
663 | r->key = NULL; | ||
664 | else | ||
665 | { | ||
666 | r->key = GNUNET_malloc (sizeof (GNUNET_HashCode)); | ||
667 | memcpy (r->key, &msg->key, sizeof (GNUNET_HashCode)); | ||
668 | } | ||
669 | |||
670 | } | ||
671 | |||
672 | |||
673 | /** | ||
579 | * Task run to check for messages that need to be sent to a client. | 674 | * Task run to check for messages that need to be sent to a client. |
580 | * | 675 | * |
581 | * @param client a ClientList, containing the client and any messages to be sent to it | 676 | * @param client a ClientList, containing the client and any messages to be sent to it |
@@ -930,6 +1025,83 @@ GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, | |||
930 | 1025 | ||
931 | 1026 | ||
932 | /** | 1027 | /** |
1028 | * Check if some client is monitoring messages of this type and notify | ||
1029 | * him in that case. | ||
1030 | * | ||
1031 | * @param mtype Type of the DHT message. | ||
1032 | * @param exp When will this value expire. | ||
1033 | * @param key Key of the result/request. | ||
1034 | * @param get_path Peers on reply path (or NULL if not recorded). | ||
1035 | * @param get_path_length number of entries in get_path. | ||
1036 | * @param put_path peers on the PUT path (or NULL if not recorded). | ||
1037 | * @param put_path_length number of entries in get_path. | ||
1038 | * @param desired_replication_level Desired replication level. | ||
1039 | * @param type Type of the result/request. | ||
1040 | * @param data Pointer to the result data. | ||
1041 | * @param size Number of bytes in data. | ||
1042 | */ | ||
1043 | void | ||
1044 | GDS_CLIENTS_process_monitor (uint16_t mtype, | ||
1045 | const struct GNUNET_TIME_Absolute exp, | ||
1046 | const GNUNET_HashCode *key, | ||
1047 | uint32_t putl, | ||
1048 | const struct GNUNET_PeerIdentity *put_path, | ||
1049 | uint32_t getl, | ||
1050 | const struct GNUNET_PeerIdentity *get_path, | ||
1051 | uint32_t replevel, | ||
1052 | enum GNUNET_BLOCK_Type type, | ||
1053 | const struct GNUNET_MessageHeader *data, | ||
1054 | uint16_t size) | ||
1055 | { | ||
1056 | struct ClientMonitorRecord *m; | ||
1057 | struct ClientList **cl; | ||
1058 | unsigned int cl_size; | ||
1059 | |||
1060 | cl = NULL; | ||
1061 | cl_size = 0; | ||
1062 | for (m = monitor_head; NULL != m; m = m->next) | ||
1063 | { | ||
1064 | if (m->type == type && | ||
1065 | (NULL == m->key || | ||
1066 | memcmp (key, m->key, sizeof(GNUNET_HashCode)) == 0)) | ||
1067 | { | ||
1068 | struct PendingMessage *pm; | ||
1069 | struct GNUNET_DHT_MonitorMessage *mmsg; | ||
1070 | struct GNUNET_PeerIdentity *path; | ||
1071 | size_t msize; | ||
1072 | unsigned int i; | ||
1073 | |||
1074 | /* Don't send duplicates */ | ||
1075 | for (i = 0; i < cl_size; i++) | ||
1076 | if (cl[i] == m->client) | ||
1077 | break; | ||
1078 | if (i < cl_size) | ||
1079 | continue; | ||
1080 | GNUNET_array_append (cl, cl_size, m->client); | ||
1081 | |||
1082 | msize = size; | ||
1083 | msize += (getl + putl) * sizeof (struct GNUNET_PeerIdentity); | ||
1084 | msize += sizeof (struct GNUNET_DHT_MonitorMessage); | ||
1085 | msize += sizeof (struct PendingMessage); | ||
1086 | pm = (struct PendingMessage *) GNUNET_malloc (msize); | ||
1087 | mmsg = (struct GNUNET_DHT_MonitorMessage *) &pm[1]; | ||
1088 | pm->msg = (struct GNUNET_MessageHeader *) mmsg; | ||
1089 | mmsg->header.size = htons (msize - sizeof (struct PendingMessage)); | ||
1090 | mmsg->header.type = htons (mtype); | ||
1091 | mmsg->expiration = GNUNET_TIME_absolute_hton(exp); | ||
1092 | path = (struct GNUNET_PeerIdentity *) &mmsg[1]; | ||
1093 | memcpy (path, put_path, putl * sizeof (struct GNUNET_PeerIdentity)); | ||
1094 | path = &path[putl]; | ||
1095 | memcpy (path, get_path, getl * sizeof (struct GNUNET_PeerIdentity)); | ||
1096 | memcpy (&path[getl], data, size); | ||
1097 | add_pending_message (m->client, pm); | ||
1098 | } | ||
1099 | } | ||
1100 | GNUNET_free_non_null (cl); | ||
1101 | } | ||
1102 | |||
1103 | |||
1104 | /** | ||
933 | * Initialize client subsystem. | 1105 | * Initialize client subsystem. |
934 | * | 1106 | * |
935 | * @param server the initialized server | 1107 | * @param server the initialized server |
@@ -945,6 +1117,9 @@ GDS_CLIENTS_init (struct GNUNET_SERVER_Handle *server) | |||
945 | {&handle_dht_local_get_stop, NULL, | 1117 | {&handle_dht_local_get_stop, NULL, |
946 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_STOP, | 1118 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_STOP, |
947 | sizeof (struct GNUNET_DHT_ClientGetStopMessage)}, | 1119 | sizeof (struct GNUNET_DHT_ClientGetStopMessage)}, |
1120 | {&handle_dht_local_monitor, NULL, | ||
1121 | GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET, | ||
1122 | sizeof (struct GNUNET_DHT_MonitorMessage)}, | ||
948 | {NULL, NULL, 0, 0} | 1123 | {NULL, NULL, 0, 0} |
949 | }; | 1124 | }; |
950 | forward_map = GNUNET_CONTAINER_multihashmap_create (1024); | 1125 | forward_map = GNUNET_CONTAINER_multihashmap_create (1024); |
diff --git a/src/dht/gnunet-service-dht_clients.h b/src/dht/gnunet-service-dht_clients.h index 21b2343e7..a8241d289 100644 --- a/src/dht/gnunet-service-dht_clients.h +++ b/src/dht/gnunet-service-dht_clients.h | |||
@@ -57,6 +57,35 @@ GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, | |||
57 | 57 | ||
58 | 58 | ||
59 | /** | 59 | /** |
60 | * Check if some client is monitoring messages of this type and notify | ||
61 | * him in that case. | ||
62 | * | ||
63 | * @param mtype Type of the DHT message. | ||
64 | * @param exp When will this value expire. | ||
65 | * @param key Key of the result/request. | ||
66 | * @param get_path Peers on reply path (or NULL if not recorded). | ||
67 | * @param get_path_length number of entries in get_path. | ||
68 | * @param put_path peers on the PUT path (or NULL if not recorded). | ||
69 | * @param put_path_length number of entries in get_path. | ||
70 | * @param desired_replication_level Desired replication level. | ||
71 | * @param type Type of the result/request. | ||
72 | * @param data Pointer to the result data. | ||
73 | * @param size Number of bytes in data. | ||
74 | */ | ||
75 | void | ||
76 | GDS_CLIENTS_process_monitor (uint16_t mtype, | ||
77 | const struct GNUNET_TIME_Absolute exp, | ||
78 | const GNUNET_HashCode *key, | ||
79 | uint32_t putl, | ||
80 | const struct GNUNET_PeerIdentity *put_path, | ||
81 | uint32_t getl, | ||
82 | const struct GNUNET_PeerIdentity *get_path, | ||
83 | uint32_t replevel, | ||
84 | enum GNUNET_BLOCK_Type type, | ||
85 | const struct GNUNET_MessageHeader *data, | ||
86 | uint16_t size); | ||
87 | |||
88 | /** | ||
60 | * Initialize client subsystem. | 89 | * Initialize client subsystem. |
61 | * | 90 | * |
62 | * @param server the initialized server | 91 | * @param server the initialized server |
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c index 907de9950..8c1f42499 100644 --- a/src/dht/gnunet-service-dht_neighbours.c +++ b/src/dht/gnunet-service-dht_neighbours.c | |||
@@ -1617,6 +1617,10 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1617 | pp, payload, payload_size); | 1617 | pp, payload, payload_size); |
1618 | } | 1618 | } |
1619 | GNUNET_CONTAINER_bloomfilter_free (bf); | 1619 | GNUNET_CONTAINER_bloomfilter_free (bf); |
1620 | GDS_CLIENTS_process_monitor (GNUNET_MESSAGE_TYPE_DHT_P2P_PUT, | ||
1621 | GNUNET_TIME_absolute_ntoh (put->expiration_time), &put->key, | ||
1622 | putlen, put_path, 0, NULL, ntohl(put->desired_replication_level), | ||
1623 | ntohl (put->type), payload, payload_size); | ||
1620 | return GNUNET_YES; | 1624 | return GNUNET_YES; |
1621 | } | 1625 | } |
1622 | 1626 | ||
@@ -1822,6 +1826,10 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1822 | 1, GNUNET_NO); | 1826 | 1, GNUNET_NO); |
1823 | } | 1827 | } |
1824 | 1828 | ||
1829 | GDS_CLIENTS_process_monitor (GNUNET_MESSAGE_TYPE_DHT_P2P_GET, | ||
1830 | GNUNET_TIME_UNIT_FOREVER_ABS, &get->key, 0, NULL, 0, NULL, | ||
1831 | ntohl (get->desired_replication_level), type, NULL, 0); | ||
1832 | |||
1825 | /* P2P forwarding */ | 1833 | /* P2P forwarding */ |
1826 | if (eval != GNUNET_BLOCK_EVALUATION_OK_LAST) | 1834 | if (eval != GNUNET_BLOCK_EVALUATION_OK_LAST) |
1827 | GDS_NEIGHBOURS_handle_get (type, options, | 1835 | GDS_NEIGHBOURS_handle_get (type, options, |
@@ -1953,6 +1961,12 @@ handle_dht_p2p_result (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1953 | &prm->key, put_path_length, put_path, get_path_length, | 1961 | &prm->key, put_path_length, put_path, get_path_length, |
1954 | xget_path, data, data_size); | 1962 | xget_path, data, data_size); |
1955 | } | 1963 | } |
1964 | |||
1965 | GDS_CLIENTS_process_monitor (GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT, | ||
1966 | GNUNET_TIME_absolute_ntoh (prm->expiration_time), &prm->key, | ||
1967 | put_path_length, put_path, get_path_length, get_path, | ||
1968 | 0, type, data, data_size); | ||
1969 | |||
1956 | return GNUNET_YES; | 1970 | return GNUNET_YES; |
1957 | } | 1971 | } |
1958 | 1972 | ||