aboutsummaryrefslogtreecommitdiff
path: root/src/dht
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2022-01-02 20:46:06 +0100
committerChristian Grothoff <christian@grothoff.org>2022-01-02 20:46:06 +0100
commitc891e4d29ca772b6b246b928a1bda8d8c9ef499f (patch)
tree69de8e9653d99d5f52e784b0ad9ef9e031257efc /src/dht
parente3ff017054eb35dedd95ae4fe66c82b88e3bbdc3 (diff)
downloadgnunet-c891e4d29ca772b6b246b928a1bda8d8c9ef499f.tar.gz
gnunet-c891e4d29ca772b6b246b928a1bda8d8c9ef499f.zip
-DHT: deduplicate monitor matching logic
Diffstat (limited to 'src/dht')
-rw-r--r--src/dht/gnunet-service-dht.h2
-rw-r--r--src/dht/gnunet-service-dht_clients.c539
2 files changed, 323 insertions, 218 deletions
diff --git a/src/dht/gnunet-service-dht.h b/src/dht/gnunet-service-dht.h
index d520cc905..e9b1ff63a 100644
--- a/src/dht/gnunet-service-dht.h
+++ b/src/dht/gnunet-service-dht.h
@@ -89,7 +89,7 @@ GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd,
89 * @param key Key of the requested data. 89 * @param key Key of the requested data.
90 */ 90 */
91void 91void
92GDS_CLIENTS_process_get (uint32_t options, 92GDS_CLIENTS_process_get (enum GNUNET_DHT_RouteOption options,
93 enum GNUNET_BLOCK_Type type, 93 enum GNUNET_BLOCK_Type type,
94 uint32_t hop_count, 94 uint32_t hop_count,
95 uint32_t desired_replication_level, 95 uint32_t desired_replication_level,
diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c
index b520cda41..8acde2fe7 100644
--- a/src/dht/gnunet-service-dht_clients.c
+++ b/src/dht/gnunet-service-dht_clients.c
@@ -856,78 +856,6 @@ handle_dht_local_get_stop (
856 856
857 857
858/** 858/**
859 * Handler for monitor start messages
860 *
861 * @param cls the client we received this message from
862 * @param msg the actual message received
863 *
864 */
865static void
866handle_dht_local_monitor (void *cls,
867 const struct GNUNET_DHT_MonitorStartStopMessage *msg)
868{
869 struct ClientHandle *ch = cls;
870 struct ClientMonitorRecord *r;
871
872 r = GNUNET_new (struct ClientMonitorRecord);
873 r->ch = ch;
874 r->type = ntohl (msg->type);
875 r->get = ntohs (msg->get);
876 r->get_resp = ntohs (msg->get_resp);
877 r->put = ntohs (msg->put);
878 if (0 != ntohs (msg->filter_key))
879 r->key = msg->key;
880 GNUNET_CONTAINER_DLL_insert (monitor_head,
881 monitor_tail,
882 r);
883 GNUNET_SERVICE_client_continue (ch->client);
884}
885
886
887/**
888 * Handler for monitor stop messages
889 *
890 * @param cls the client we received this message from
891 * @param msg the actual message received
892 */
893static void
894handle_dht_local_monitor_stop (
895 void *cls,
896 const struct GNUNET_DHT_MonitorStartStopMessage *msg)
897{
898 struct ClientHandle *ch = cls;
899
900 GNUNET_SERVICE_client_continue (ch->client);
901 for (struct ClientMonitorRecord *r = monitor_head;
902 NULL != r;
903 r = r->next)
904 {
905 bool keys_match;
906
907 keys_match =
908 (GNUNET_is_zero (&r->key))
909 ? (0 == ntohs (msg->filter_key))
910 : ( (0 != ntohs (msg->filter_key)) &&
911 (! GNUNET_memcmp (&r->key,
912 &msg->key)) );
913 if ( (ch == r->ch) &&
914 (ntohl (msg->type) == r->type) &&
915 (r->get == msg->get) &&
916 (r->get_resp == msg->get_resp) &&
917 (r->put == msg->put) &&
918 keys_match)
919 {
920 GNUNET_CONTAINER_DLL_remove (monitor_head,
921 monitor_tail,
922 r);
923 GNUNET_free (r);
924 return; /* Delete only ONE entry */
925 }
926 }
927}
928
929
930/**
931 * Closure for #forward_reply() 859 * Closure for #forward_reply()
932 */ 860 */
933struct ForwardReplyContext 861struct ForwardReplyContext
@@ -1132,26 +1060,106 @@ GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd,
1132} 1060}
1133 1061
1134 1062
1063/* ************* logic for monitors ************** */
1064
1065
1135/** 1066/**
1136 * Check if some client is monitoring GET messages and notify 1067 * Handler for monitor start messages
1137 * them in that case. If tracked, @a path should include the local peer. 1068 *
1069 * @param cls the client we received this message from
1070 * @param msg the actual message received
1138 * 1071 *
1139 * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
1140 * @param type The type of data in the request.
1141 * @param hop_count Hop count so far.
1142 * @param path_length number of entries in path (or 0 if not recorded).
1143 * @param path peers on the GET path (or NULL if not recorded).
1144 * @param desired_replication_level Desired replication level.
1145 * @param key Key of the requested data.
1146 */ 1072 */
1147void 1073static void
1148GDS_CLIENTS_process_get (uint32_t options, 1074handle_dht_local_monitor (void *cls,
1149 enum GNUNET_BLOCK_Type type, 1075 const struct GNUNET_DHT_MonitorStartStopMessage *msg)
1150 uint32_t hop_count, 1076{
1151 uint32_t desired_replication_level, 1077 struct ClientHandle *ch = cls;
1152 unsigned int path_length, 1078 struct ClientMonitorRecord *r;
1153 const struct GNUNET_PeerIdentity *path, 1079
1154 const struct GNUNET_HashCode *key) 1080 r = GNUNET_new (struct ClientMonitorRecord);
1081 r->ch = ch;
1082 r->type = ntohl (msg->type);
1083 r->get = ntohs (msg->get);
1084 r->get_resp = ntohs (msg->get_resp);
1085 r->put = ntohs (msg->put);
1086 if (0 != ntohs (msg->filter_key))
1087 r->key = msg->key;
1088 GNUNET_CONTAINER_DLL_insert (monitor_head,
1089 monitor_tail,
1090 r);
1091 GNUNET_SERVICE_client_continue (ch->client);
1092}
1093
1094
1095/**
1096 * Handler for monitor stop messages
1097 *
1098 * @param cls the client we received this message from
1099 * @param msg the actual message received
1100 */
1101static void
1102handle_dht_local_monitor_stop (
1103 void *cls,
1104 const struct GNUNET_DHT_MonitorStartStopMessage *msg)
1105{
1106 struct ClientHandle *ch = cls;
1107
1108 GNUNET_SERVICE_client_continue (ch->client);
1109 for (struct ClientMonitorRecord *r = monitor_head;
1110 NULL != r;
1111 r = r->next)
1112 {
1113 bool keys_match;
1114
1115 keys_match =
1116 (GNUNET_is_zero (&r->key))
1117 ? (0 == ntohs (msg->filter_key))
1118 : ( (0 != ntohs (msg->filter_key)) &&
1119 (! GNUNET_memcmp (&r->key,
1120 &msg->key)) );
1121 if ( (ch == r->ch) &&
1122 (ntohl (msg->type) == r->type) &&
1123 (r->get == msg->get) &&
1124 (r->get_resp == msg->get_resp) &&
1125 (r->put == msg->put) &&
1126 keys_match)
1127 {
1128 GNUNET_CONTAINER_DLL_remove (monitor_head,
1129 monitor_tail,
1130 r);
1131 GNUNET_free (r);
1132 return; /* Delete only ONE entry */
1133 }
1134 }
1135}
1136
1137
1138/**
1139 * Function to call by #for_matching_monitors().
1140 *
1141 * @param cls closure
1142 * @param m a matching monitor
1143 */
1144typedef void
1145(*MonitorAction)(void *cls,
1146 struct ClientMonitorRecord *m);
1147
1148
1149/**
1150 * Call @a cb on all monitors that watch for blocks of @a type
1151 * and key @a key.
1152 *
1153 * @param type the type to match
1154 * @param key the key to match
1155 * @param cb function to call
1156 * @param cb_cls closure for @a cb
1157 */
1158static void
1159for_matching_monitors (enum GNUNET_BLOCK_Type type,
1160 const struct GNUNET_HashCode *key,
1161 MonitorAction cb,
1162 void *cb_cls)
1155{ 1163{
1156 struct ClientHandle **cl = NULL; 1164 struct ClientHandle **cl = NULL;
1157 unsigned int cl_size = 0; 1165 unsigned int cl_size = 0;
@@ -1161,16 +1169,12 @@ GDS_CLIENTS_process_get (uint32_t options,
1161 m = m->next) 1169 m = m->next)
1162 { 1170 {
1163 if ( ( (GNUNET_BLOCK_TYPE_ANY == m->type) || 1171 if ( ( (GNUNET_BLOCK_TYPE_ANY == m->type) ||
1164 (m->type == type)) && 1172 (m->type == type) ) &&
1165 ( (GNUNET_is_zero (&m->key)) || 1173 ( (GNUNET_is_zero (&m->key)) ||
1166 (0 == 1174 (0 ==
1167 GNUNET_memcmp (key, 1175 GNUNET_memcmp (key,
1168 &m->key)))) 1176 &m->key)) ) )
1169 { 1177 {
1170 struct GNUNET_MQ_Envelope *env;
1171 struct GNUNET_DHT_MonitorGetMessage *mmsg;
1172 struct GNUNET_PeerIdentity *msg_path;
1173 size_t msize;
1174 unsigned int i; 1178 unsigned int i;
1175 1179
1176 /* Don't send duplicates */ 1180 /* Don't send duplicates */
@@ -1182,87 +1186,230 @@ GDS_CLIENTS_process_get (uint32_t options,
1182 GNUNET_array_append (cl, 1186 GNUNET_array_append (cl,
1183 cl_size, 1187 cl_size,
1184 m->ch); 1188 m->ch);
1185 msize = path_length * sizeof(struct GNUNET_PeerIdentity); 1189 cb (cb_cls,
1186 env = GNUNET_MQ_msg_extra (mmsg, 1190 m);
1187 msize,
1188 GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET);
1189 mmsg->options = htonl (options);
1190 mmsg->type = htonl (type);
1191 mmsg->hop_count = htonl (hop_count);
1192 mmsg->desired_replication_level = htonl (desired_replication_level);
1193 mmsg->get_path_length = htonl (path_length);
1194 mmsg->key = *key;
1195 msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1];
1196 GNUNET_memcpy (msg_path,
1197 path,
1198 path_length * sizeof(struct GNUNET_PeerIdentity));
1199 GNUNET_MQ_send (m->ch->mq,
1200 env);
1201 } 1191 }
1202 } 1192 }
1203 GNUNET_free (cl); 1193 GNUNET_free (cl);
1204} 1194}
1205 1195
1206 1196
1197/**
1198 * Closure for #get_action();
1199 */
1200struct GetActionContext
1201{
1202 enum GNUNET_DHT_RouteOption options;
1203 enum GNUNET_BLOCK_Type type;
1204 uint32_t hop_count;
1205 uint32_t desired_replication_level;
1206 unsigned int get_path_length;
1207 const struct GNUNET_PeerIdentity *get_path;
1208 const struct GNUNET_HashCode *key;
1209};
1210
1211
1212/**
1213 * Function called on monitors that match a GET.
1214 * Sends the GET notification to the monitor.
1215 *
1216 * @param cls a `struct GetActionContext`
1217 * @param m a matching monitor
1218 */
1219static void
1220get_action (void *cls,
1221 struct ClientMonitorRecord *m)
1222{
1223 struct GetActionContext *gac = cls;
1224 struct GNUNET_MQ_Envelope *env;
1225 struct GNUNET_DHT_MonitorGetMessage *mmsg;
1226 struct GNUNET_PeerIdentity *msg_path;
1227 size_t msize;
1228
1229 msize = gac->get_path_length * sizeof(struct GNUNET_PeerIdentity);
1230 env = GNUNET_MQ_msg_extra (mmsg,
1231 msize,
1232 GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET);
1233 mmsg->options = htonl (gac->options);
1234 mmsg->type = htonl (gac->type);
1235 mmsg->hop_count = htonl (gac->hop_count);
1236 mmsg->desired_replication_level = htonl (gac->desired_replication_level);
1237 mmsg->get_path_length = htonl (gac->get_path_length);
1238 mmsg->key = *gac->key;
1239 msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1];
1240 GNUNET_memcpy (msg_path,
1241 gac->get_path,
1242 gac->get_path_length * sizeof(struct GNUNET_PeerIdentity));
1243 GNUNET_MQ_send (m->ch->mq,
1244 env);
1245}
1246
1247
1248/**
1249 * Check if some client is monitoring GET messages and notify
1250 * them in that case. If tracked, @a path should include the local peer.
1251 *
1252 * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
1253 * @param type The type of data in the request.
1254 * @param hop_count Hop count so far.
1255 * @param path_length number of entries in path (or 0 if not recorded).
1256 * @param path peers on the GET path (or NULL if not recorded).
1257 * @param desired_replication_level Desired replication level.
1258 * @param key Key of the requested data.
1259 */
1260void
1261GDS_CLIENTS_process_get (enum GNUNET_DHT_RouteOption options,
1262 enum GNUNET_BLOCK_Type type,
1263 uint32_t hop_count,
1264 uint32_t desired_replication_level,
1265 unsigned int path_length,
1266 const struct GNUNET_PeerIdentity *path,
1267 const struct GNUNET_HashCode *key)
1268{
1269 struct GetActionContext gac = {
1270 .options = options,
1271 .type = type,
1272 .hop_count = hop_count,
1273 .desired_replication_level = desired_replication_level,
1274 .get_path_length = path_length,
1275 .get_path = path,
1276 .key = key
1277 };
1278
1279 for_matching_monitors (type,
1280 key,
1281 &get_action,
1282 &gac);
1283}
1284
1285
1286/**
1287 * Closure for response_action().
1288 */
1289struct ResponseActionContext
1290{
1291 const struct GDS_DATACACHE_BlockData *bd;
1292 const struct GNUNET_PeerIdentity *get_path;
1293 unsigned int get_path_length;
1294};
1295
1296
1297/**
1298 * Function called on monitors that match a response.
1299 * Sends the response notification to the monitor.
1300 *
1301 * @param cls a `struct ResponseActionContext`
1302 * @param m a matching monitor
1303 */
1304static void
1305response_action (void *cls,
1306 struct ClientMonitorRecord *m)
1307{
1308 const struct ResponseActionContext *resp_ctx = cls;
1309 const struct GDS_DATACACHE_BlockData *bd = resp_ctx->bd;
1310
1311 struct GNUNET_MQ_Envelope *env;
1312 struct GNUNET_DHT_MonitorGetRespMessage *mmsg;
1313 struct GNUNET_PeerIdentity *path;
1314 size_t msize;
1315
1316 msize = bd->data_size;
1317 msize += (resp_ctx->get_path_length + bd->put_path_length)
1318 * sizeof(struct GNUNET_PeerIdentity);
1319 env = GNUNET_MQ_msg_extra (mmsg,
1320 msize,
1321 GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP);
1322 mmsg->type = htonl (bd->type);
1323 mmsg->put_path_length = htonl (bd->put_path_length);
1324 mmsg->get_path_length = htonl (resp_ctx->get_path_length);
1325 mmsg->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time);
1326 mmsg->key = bd->key;
1327 path = (struct GNUNET_PeerIdentity *) &mmsg[1];
1328 GNUNET_memcpy (path,
1329 bd->put_path,
1330 bd->put_path_length * sizeof(struct GNUNET_PeerIdentity));
1331 GNUNET_memcpy (path,
1332 resp_ctx->get_path,
1333 resp_ctx->get_path_length * sizeof(struct
1334 GNUNET_PeerIdentity));
1335 GNUNET_memcpy (&path[resp_ctx->get_path_length],
1336 bd->data,
1337 bd->data_size);
1338 GNUNET_MQ_send (m->ch->mq,
1339 env);
1340}
1341
1342
1207void 1343void
1208GDS_CLIENTS_process_get_resp (const struct GDS_DATACACHE_BlockData *bd, 1344GDS_CLIENTS_process_get_resp (const struct GDS_DATACACHE_BlockData *bd,
1209 const struct GNUNET_PeerIdentity *get_path, 1345 const struct GNUNET_PeerIdentity *get_path,
1210 unsigned int get_path_length) 1346 unsigned int get_path_length)
1211{ 1347{
1212 struct ClientHandle **cl = NULL; 1348 struct ResponseActionContext rac = {
1213 unsigned int cl_size = 0; 1349 .bd = bd,
1350 .get_path = get_path,
1351 .get_path_length = get_path_length
1352 };
1214 1353
1215 for (struct ClientMonitorRecord *m = monitor_head; 1354 for_matching_monitors (bd->type,
1216 NULL != m; 1355 &bd->key,
1217 m = m->next) 1356 &response_action,
1218 { 1357 &rac);
1219 if ( ( (GNUNET_BLOCK_TYPE_ANY == m->type) || 1358}
1220 (m->type == bd->type) ) &&
1221 ( (GNUNET_is_zero (&m->key)) ||
1222 (0 == GNUNET_memcmp (&bd->key,
1223 &m->key)) ) )
1224 {
1225 struct GNUNET_MQ_Envelope *env;
1226 struct GNUNET_DHT_MonitorGetRespMessage *mmsg;
1227 struct GNUNET_PeerIdentity *path;
1228 size_t msize;
1229 unsigned int i;
1230 1359
1231 /* Don't send duplicates */ 1360
1232 for (i = 0; i < cl_size; i++) 1361/**
1233 if (cl[i] == m->ch) 1362 * Closure for put_action().
1234 break; 1363 */
1235 if (i < cl_size) 1364struct PutActionContext
1236 continue; 1365{
1237 GNUNET_array_append (cl, 1366 const struct GDS_DATACACHE_BlockData *bd;
1238 cl_size, 1367 enum GNUNET_DHT_RouteOption options;
1239 m->ch); 1368 uint32_t hop_count;
1240 msize = bd->data_size; 1369 uint32_t desired_replication_level;
1241 msize += (get_path_length + bd->put_path_length) 1370};
1242 * sizeof(struct GNUNET_PeerIdentity); 1371
1243 env = GNUNET_MQ_msg_extra (mmsg, 1372
1244 msize, 1373/**
1245 GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP); 1374 * Function called on monitors that match a PUT.
1246 mmsg->type = htonl (bd->type); 1375 * Sends the PUT notification to the monitor.
1247 mmsg->put_path_length = htonl (bd->put_path_length); 1376 *
1248 mmsg->get_path_length = htonl (get_path_length); 1377 * @param cls a `struct PutActionContext`
1249 mmsg->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time); 1378 * @param m a matching monitor
1250 mmsg->key = bd->key; 1379 */
1251 path = (struct GNUNET_PeerIdentity *) &mmsg[1]; 1380static void
1252 GNUNET_memcpy (path, 1381put_action (void *cls,
1253 bd->put_path, 1382 struct ClientMonitorRecord *m)
1254 bd->put_path_length * sizeof(struct GNUNET_PeerIdentity)); 1383{
1255 GNUNET_memcpy (path, 1384 const struct PutActionContext *put_ctx = cls;
1256 get_path, 1385 const struct GDS_DATACACHE_BlockData *bd = put_ctx->bd;
1257 get_path_length * sizeof(struct GNUNET_PeerIdentity)); 1386 struct GNUNET_MQ_Envelope *env;
1258 GNUNET_memcpy (&path[get_path_length], 1387 struct GNUNET_DHT_MonitorPutMessage *mmsg;
1259 bd->data, 1388 struct GNUNET_PeerIdentity *msg_path;
1260 bd->data_size); 1389 size_t msize;
1261 GNUNET_MQ_send (m->ch->mq, 1390
1262 env); 1391 msize = bd->data_size
1263 } 1392 + bd->put_path_length
1264 } 1393 * sizeof(struct GNUNET_PeerIdentity);
1265 GNUNET_free (cl); 1394 env = GNUNET_MQ_msg_extra (mmsg,
1395 msize,
1396 GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT);
1397 mmsg->options = htonl (put_ctx->options);
1398 mmsg->type = htonl (bd->type);
1399 mmsg->hop_count = htonl (put_ctx->hop_count);
1400 mmsg->desired_replication_level = htonl (put_ctx->desired_replication_level);
1401 mmsg->put_path_length = htonl (bd->put_path_length);
1402 mmsg->key = bd->key;
1403 mmsg->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time);
1404 msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1];
1405 GNUNET_memcpy (msg_path,
1406 bd->put_path,
1407 bd->put_path_length * sizeof(struct GNUNET_PeerIdentity));
1408 GNUNET_memcpy (&msg_path[bd->put_path_length],
1409 bd->data,
1410 bd->data_size);
1411 GNUNET_MQ_send (m->ch->mq,
1412 env);
1266} 1413}
1267 1414
1268 1415
@@ -1272,59 +1419,17 @@ GDS_CLIENTS_process_put (enum GNUNET_DHT_RouteOption options,
1272 uint32_t hop_count, 1419 uint32_t hop_count,
1273 uint32_t desired_replication_level) 1420 uint32_t desired_replication_level)
1274{ 1421{
1275 struct ClientHandle **cl = NULL; 1422 struct PutActionContext put_ctx = {
1276 unsigned int cl_size = 0; 1423 .bd = bd,
1277 1424 .hop_count = hop_count,
1278 for (struct ClientMonitorRecord *m = monitor_head; 1425 .desired_replication_level = desired_replication_level,
1279 NULL != m; 1426 .options = options
1280 m = m->next) 1427 };
1281 {
1282 if ( ( (GNUNET_BLOCK_TYPE_ANY == m->type) ||
1283 (m->type == bd->type) ) &&
1284 ( (GNUNET_is_zero (&m->key)) ||
1285 (0 ==
1286 GNUNET_memcmp (&bd->key,
1287 &m->key)) ) )
1288 {
1289 struct GNUNET_MQ_Envelope *env;
1290 struct GNUNET_DHT_MonitorPutMessage *mmsg;
1291 struct GNUNET_PeerIdentity *msg_path;
1292 size_t msize;
1293 unsigned int i;
1294 1428
1295 /* Don't send duplicates */ 1429 for_matching_monitors (bd->type,
1296 for (i = 0; i < cl_size; i++) 1430 &bd->key,
1297 if (cl[i] == m->ch) 1431 &put_action,
1298 break; 1432 &put_ctx);
1299 if (i < cl_size)
1300 continue;
1301 GNUNET_array_append (cl,
1302 cl_size,
1303 m->ch);
1304 msize = bd->data_size;
1305 msize += bd->put_path_length * sizeof(struct GNUNET_PeerIdentity);
1306 env = GNUNET_MQ_msg_extra (mmsg,
1307 msize,
1308 GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT);
1309 mmsg->options = htonl (options);
1310 mmsg->type = htonl (bd->type);
1311 mmsg->hop_count = htonl (hop_count);
1312 mmsg->desired_replication_level = htonl (desired_replication_level);
1313 mmsg->put_path_length = htonl (bd->put_path_length);
1314 mmsg->key = bd->key;
1315 mmsg->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time);
1316 msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1];
1317 GNUNET_memcpy (msg_path,
1318 bd->put_path,
1319 bd->put_path_length * sizeof(struct GNUNET_PeerIdentity));
1320 GNUNET_memcpy (&msg_path[bd->put_path_length],
1321 bd->data,
1322 bd->data_size);
1323 GNUNET_MQ_send (m->ch->mq,
1324 env);
1325 }
1326 }
1327 GNUNET_free (cl);
1328} 1433}
1329 1434
1330 1435
@@ -1334,7 +1439,7 @@ GDS_CLIENTS_process_put (enum GNUNET_DHT_RouteOption options,
1334 * @param server the initialized server 1439 * @param server the initialized server
1335 */ 1440 */
1336static void 1441static void
1337GDS_CLIENTS_init () 1442GDS_CLIENTS_init (void)
1338{ 1443{
1339 forward_map 1444 forward_map
1340 = GNUNET_CONTAINER_multihashmap_create (1024, 1445 = GNUNET_CONTAINER_multihashmap_create (1024,
@@ -1348,7 +1453,7 @@ GDS_CLIENTS_init ()
1348 * Shutdown client subsystem. 1453 * Shutdown client subsystem.
1349 */ 1454 */
1350static void 1455static void
1351GDS_CLIENTS_stop () 1456GDS_CLIENTS_stop (void)
1352{ 1457{
1353 if (NULL != retry_task) 1458 if (NULL != retry_task)
1354 { 1459 {