aboutsummaryrefslogtreecommitdiff
path: root/src/fs
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2014-11-02 11:24:37 +0000
committerChristian Grothoff <christian@grothoff.org>2014-11-02 11:24:37 +0000
commit6ee12e6c9d2a7b6596b20b918f761702bfbf05eb (patch)
treeabb298b97798d4ba4d58a94441d0baa03a9d86d6 /src/fs
parent6c4dab891b8ce1a5a7291d1685b2913412571846 (diff)
downloadgnunet-6ee12e6c9d2a7b6596b20b918f761702bfbf05eb.tar.gz
gnunet-6ee12e6c9d2a7b6596b20b918f761702bfbf05eb.zip
-fix #3556
Diffstat (limited to 'src/fs')
-rw-r--r--src/fs/fs_search.c72
1 files changed, 42 insertions, 30 deletions
diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c
index be7f4bdc5..c79328834 100644
--- a/src/fs/fs_search.c
+++ b/src/fs/fs_search.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2001-2013 Christian Grothoff (and other contributing authors) 3 (C) 2001-2014 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -1006,7 +1006,9 @@ struct MessageBuilderContext
1006 * @return #GNUNET_OK to continue iterating 1006 * @return #GNUNET_OK to continue iterating
1007 */ 1007 */
1008static int 1008static int
1009build_result_set (void *cls, const struct GNUNET_HashCode * key, void *value) 1009build_result_set (void *cls,
1010 const struct GNUNET_HashCode *key,
1011 void *value)
1010{ 1012{
1011 struct MessageBuilderContext *mbc = cls; 1013 struct MessageBuilderContext *mbc = cls;
1012 struct GNUNET_FS_SearchResult *sr = value; 1014 struct GNUNET_FS_SearchResult *sr = value;
@@ -1029,9 +1031,8 @@ build_result_set (void *cls, const struct GNUNET_HashCode * key, void *value)
1029 1031
1030 1032
1031/** 1033/**
1032 * Iterating over the known results, count those 1034 * Iterating over the known results, count those matching the given
1033 * matching the given result range and increment 1035 * result range and increment put count for each.
1034 * put count for each.
1035 * 1036 *
1036 * @param cls the `struct MessageBuilderContext` 1037 * @param cls the `struct MessageBuilderContext`
1037 * @param key key for a result 1038 * @param key key for a result
@@ -1039,7 +1040,9 @@ build_result_set (void *cls, const struct GNUNET_HashCode * key, void *value)
1039 * @return #GNUNET_OK to continue iterating 1040 * @return #GNUNET_OK to continue iterating
1040 */ 1041 */
1041static int 1042static int
1042find_result_set (void *cls, const struct GNUNET_HashCode * key, void *value) 1043find_result_set (void *cls,
1044 const struct GNUNET_HashCode *key,
1045 void *value)
1043{ 1046{
1044 struct MessageBuilderContext *mbc = cls; 1047 struct MessageBuilderContext *mbc = cls;
1045 struct GNUNET_FS_SearchResult *sr = value; 1048 struct GNUNET_FS_SearchResult *sr = value;
@@ -1053,8 +1056,9 @@ find_result_set (void *cls, const struct GNUNET_HashCode * key, void *value)
1053 1056
1054 1057
1055/** 1058/**
1056 * We're ready to transmit the search request to the 1059 * We're ready to transmit the search request to the file-sharing
1057 * file-sharing service. Do it. 1060 * service. Do it. If the request is too large to fit into a single
1061 * message, transmit in increments.
1058 * 1062 *
1059 * @param cls closure 1063 * @param cls closure
1060 * @param size number of bytes available in @a buf 1064 * @param size number of bytes available in @a buf
@@ -1069,7 +1073,8 @@ transmit_search_request (void *cls, size_t size, void *buf)
1069 size_t msize; 1073 size_t msize;
1070 struct SearchMessage *sm; 1074 struct SearchMessage *sm;
1071 struct GNUNET_CRYPTO_EcdsaPublicKey dpub; 1075 struct GNUNET_CRYPTO_EcdsaPublicKey dpub;
1072 unsigned int sqms; 1076 unsigned int total_seen_results; /* total number of result hashes to send */
1077 unsigned int message_size_limit;
1073 uint32_t options; 1078 uint32_t options;
1074 1079
1075 if (NULL == buf) 1080 if (NULL == buf)
@@ -1081,7 +1086,7 @@ transmit_search_request (void *cls, size_t size, void *buf)
1081 mbc.skip_cnt = sc->search_request_map_offset; 1086 mbc.skip_cnt = sc->search_request_map_offset;
1082 sm = buf; 1087 sm = buf;
1083 sm->header.type = htons (GNUNET_MESSAGE_TYPE_FS_START_SEARCH); 1088 sm->header.type = htons (GNUNET_MESSAGE_TYPE_FS_START_SEARCH);
1084 mbc.xoff = (struct GNUNET_HashCode *) & sm[1]; 1089 mbc.xoff = (struct GNUNET_HashCode *) &sm[1];
1085 options = SEARCH_MESSAGE_OPTION_NONE; 1090 options = SEARCH_MESSAGE_OPTION_NONE;
1086 if (0 != (sc->options & GNUNET_FS_SEARCH_OPTION_LOOPBACK_ONLY)) 1091 if (0 != (sc->options & GNUNET_FS_SEARCH_OPTION_LOOPBACK_ONLY))
1087 options |= SEARCH_MESSAGE_OPTION_LOOPBACK_ONLY; 1092 options |= SEARCH_MESSAGE_OPTION_LOOPBACK_ONLY;
@@ -1090,15 +1095,16 @@ transmit_search_request (void *cls, size_t size, void *buf)
1090 msize = sizeof (struct SearchMessage); 1095 msize = sizeof (struct SearchMessage);
1091 GNUNET_assert (size >= msize); 1096 GNUNET_assert (size >= msize);
1092 mbc.keyword_offset = sc->keyword_offset; 1097 mbc.keyword_offset = sc->keyword_offset;
1093 /* calculate total number of known results (in put_cnt => sqms) */ 1098 /* calculate total number of known results (in put_cnt => total_seen_results) */
1094 mbc.put_cnt = 0; 1099 mbc.put_cnt = 0;
1095 GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map, 1100 GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map,
1096 &find_result_set, &mbc); 1101 &find_result_set, &mbc);
1097 sqms = mbc.put_cnt; 1102 total_seen_results = mbc.put_cnt;
1098 /* calculate how many results we can send in this message */ 1103 /* calculate how many results we can send in this message */
1099 mbc.put_cnt = (size - msize) / sizeof (struct GNUNET_HashCode); 1104 message_size_limit = (size - msize) / sizeof (struct GNUNET_HashCode);
1100 mbc.put_cnt = GNUNET_MIN (mbc.put_cnt, sqms - mbc.skip_cnt); 1105 mbc.put_cnt = GNUNET_MIN (message_size_limit,
1101 if (sc->search_request_map_offset < sqms) 1106 total_seen_results - mbc.skip_cnt);
1107 if (sc->search_request_map_offset < total_seen_results)
1102 GNUNET_assert (mbc.put_cnt > 0); 1108 GNUNET_assert (mbc.put_cnt > 0);
1103 1109
1104 /* now build message */ 1110 /* now build message */
@@ -1110,8 +1116,9 @@ transmit_search_request (void *cls, size_t size, void *buf)
1110 sm->query = sc->requests[sc->keyword_offset].uquery; 1116 sm->query = sc->requests[sc->keyword_offset].uquery;
1111 GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map, 1117 GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map,
1112 &build_result_set, &mbc); 1118 &build_result_set, &mbc);
1113 GNUNET_assert (sqms >= sc->search_request_map_offset); 1119 GNUNET_assert (0 == mbc->put_cnt);
1114 if (sqms != sc->search_request_map_offset) 1120 GNUNET_assert (total_seen_results >= sc->search_request_map_offset);
1121 if (total_seen_results != sc->search_request_map_offset)
1115 { 1122 {
1116 /* more requesting to be done... */ 1123 /* more requesting to be done... */
1117 sm->options = htonl (options | SEARCH_MESSAGE_OPTION_CONTINUED); 1124 sm->options = htonl (options | SEARCH_MESSAGE_OPTION_CONTINUED);
@@ -1120,6 +1127,7 @@ transmit_search_request (void *cls, size_t size, void *buf)
1120 } 1127 }
1121 sm->options = htonl (options); 1128 sm->options = htonl (options);
1122 sc->keyword_offset++; 1129 sc->keyword_offset++;
1130 sc->search_request_map_offset = 0;
1123 if (sc->uri->data.ksk.keywordCount != sc->keyword_offset) 1131 if (sc->uri->data.ksk.keywordCount != sc->keyword_offset)
1124 { 1132 {
1125 /* more requesting to be done... */ 1133 /* more requesting to be done... */
@@ -1142,18 +1150,19 @@ transmit_search_request (void *cls, size_t size, void *buf)
1142 GNUNET_CRYPTO_hash (&dpub, 1150 GNUNET_CRYPTO_hash (&dpub,
1143 sizeof (dpub), 1151 sizeof (dpub),
1144 &sm->query); 1152 &sm->query);
1145 mbc.put_cnt = (size - msize) / sizeof (struct GNUNET_HashCode); 1153 message_size_limit = (size - msize) / sizeof (struct GNUNET_HashCode);
1146 sqms = GNUNET_CONTAINER_multihashmap_size (sc->master_result_map); 1154 total_seen_results = GNUNET_CONTAINER_multihashmap_size (sc->master_result_map);
1147 mbc.put_cnt = GNUNET_MIN (mbc.put_cnt, sqms - mbc.skip_cnt); 1155 mbc.put_cnt = GNUNET_MIN (message_size_limit,
1156 total_seen_results - mbc.skip_cnt);
1148 mbc.keyword_offset = 0; 1157 mbc.keyword_offset = 0;
1149 if (sc->search_request_map_offset < sqms) 1158 if (sc->search_request_map_offset < total_seen_results)
1150 GNUNET_assert (mbc.put_cnt > 0); 1159 GNUNET_assert (mbc.put_cnt > 0);
1151 msize += sizeof (struct GNUNET_HashCode) * mbc.put_cnt; 1160 msize += sizeof (struct GNUNET_HashCode) * mbc.put_cnt;
1152 GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map, 1161 GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map,
1153 &build_result_set, &mbc); 1162 &build_result_set, &mbc);
1154 sm->header.size = htons (msize); 1163 sm->header.size = htons (msize);
1155 GNUNET_assert (sqms >= sc->search_request_map_offset); 1164 GNUNET_assert (total_seen_results >= sc->search_request_map_offset);
1156 if (sqms != sc->search_request_map_offset) 1165 if (total_seen_results != sc->search_request_map_offset)
1157 { 1166 {
1158 /* more requesting to be done... */ 1167 /* more requesting to be done... */
1159 sm->options = htonl (options | SEARCH_MESSAGE_OPTION_CONTINUED); 1168 sm->options = htonl (options | SEARCH_MESSAGE_OPTION_CONTINUED);
@@ -1162,7 +1171,8 @@ transmit_search_request (void *cls, size_t size, void *buf)
1162 } 1171 }
1163 sm->options = htonl (options); 1172 sm->options = htonl (options);
1164 } 1173 }
1165 GNUNET_CLIENT_receive (sc->client, &receive_results, sc, 1174 GNUNET_CLIENT_receive (sc->client,
1175 &receive_results, sc,
1166 GNUNET_TIME_UNIT_FOREVER_REL); 1176 GNUNET_TIME_UNIT_FOREVER_REL);
1167 return msize; 1177 return msize;
1168} 1178}
@@ -1178,20 +1188,21 @@ static void
1178schedule_transmit_search_request (struct GNUNET_FS_SearchContext *sc) 1188schedule_transmit_search_request (struct GNUNET_FS_SearchContext *sc)
1179{ 1189{
1180 size_t size; 1190 size_t size;
1181 unsigned int sqms; 1191 unsigned int left;
1182 unsigned int fit; 1192 unsigned int fit;
1193 unsigned int request;
1183 1194
1184 size = sizeof (struct SearchMessage); 1195 size = sizeof (struct SearchMessage);
1185 sqms = 1196 left =
1186 GNUNET_CONTAINER_multihashmap_size (sc->master_result_map) - 1197 GNUNET_CONTAINER_multihashmap_size (sc->master_result_map) -
1187 sc->search_request_map_offset; 1198 sc->search_request_map_offset;
1188 fit = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - size) / sizeof (struct GNUNET_HashCode); 1199 fit = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - size) / sizeof (struct GNUNET_HashCode);
1189 fit = GNUNET_MIN (fit, sqms); 1200 request = GNUNET_MIN (fit, left);
1190 size += sizeof (struct GNUNET_HashCode) * fit; 1201 size += sizeof (struct GNUNET_HashCode) * request;
1191 GNUNET_CLIENT_notify_transmit_ready (sc->client, size, 1202 GNUNET_CLIENT_notify_transmit_ready (sc->client, size,
1192 GNUNET_CONSTANTS_SERVICE_TIMEOUT, 1203 GNUNET_CONSTANTS_SERVICE_TIMEOUT,
1193 GNUNET_NO, &transmit_search_request, sc); 1204 GNUNET_NO,
1194 1205 &transmit_search_request, sc);
1195} 1206}
1196 1207
1197 1208
@@ -1374,6 +1385,7 @@ GNUNET_FS_search_start_searching_ (struct GNUNET_FS_SearchContext *sc)
1374 sc->client = GNUNET_CLIENT_connect ("fs", sc->h->cfg); 1385 sc->client = GNUNET_CLIENT_connect ("fs", sc->h->cfg);
1375 if (NULL == sc->client) 1386 if (NULL == sc->client)
1376 return GNUNET_SYSERR; 1387 return GNUNET_SYSERR;
1388 sc->search_request_map_offset = 0;
1377 schedule_transmit_search_request (sc); 1389 schedule_transmit_search_request (sc);
1378 return GNUNET_OK; 1390 return GNUNET_OK;
1379} 1391}