diff options
-rw-r--r-- | src/dht/gnunet-service-dht.h | 2 | ||||
-rw-r--r-- | src/dht/gnunet-service-dht_clients.c | 539 |
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 | */ |
91 | void | 91 | void |
92 | GDS_CLIENTS_process_get (uint32_t options, | 92 | GDS_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 | */ | ||
865 | static void | ||
866 | handle_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 | */ | ||
893 | static void | ||
894 | handle_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 | */ |
933 | struct ForwardReplyContext | 861 | struct 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 | */ |
1147 | void | 1073 | static void |
1148 | GDS_CLIENTS_process_get (uint32_t options, | 1074 | handle_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 | */ | ||
1101 | static void | ||
1102 | handle_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 | */ | ||
1144 | typedef 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 | */ | ||
1158 | static void | ||
1159 | for_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 | */ | ||
1200 | struct 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 | */ | ||
1219 | static void | ||
1220 | get_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 | */ | ||
1260 | void | ||
1261 | GDS_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 | */ | ||
1289 | struct 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 | */ | ||
1304 | static void | ||
1305 | response_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 | |||
1207 | void | 1343 | void |
1208 | GDS_CLIENTS_process_get_resp (const struct GDS_DATACACHE_BlockData *bd, | 1344 | GDS_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) | 1364 | struct 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]; | 1380 | static void |
1252 | GNUNET_memcpy (path, | 1381 | put_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 | */ |
1336 | static void | 1441 | static void |
1337 | GDS_CLIENTS_init () | 1442 | GDS_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 | */ |
1350 | static void | 1455 | static void |
1351 | GDS_CLIENTS_stop () | 1456 | GDS_CLIENTS_stop (void) |
1352 | { | 1457 | { |
1353 | if (NULL != retry_task) | 1458 | if (NULL != retry_task) |
1354 | { | 1459 | { |