aboutsummaryrefslogtreecommitdiff
path: root/src/fs/fs_search.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-05-03 08:48:06 +0000
committerChristian Grothoff <christian@grothoff.org>2010-05-03 08:48:06 +0000
commit014972b06f9180cc39ad10b34559b441edc3a33f (patch)
tree69660df5b492f5248ab7a391435a73168ab51c6e /src/fs/fs_search.c
parenta894ddc0a376fa59850b410b43d3c9331c847677 (diff)
downloadgnunet-014972b06f9180cc39ad10b34559b441edc3a33f.tar.gz
gnunet-014972b06f9180cc39ad10b34559b441edc3a33f.zip
search deserialization
Diffstat (limited to 'src/fs/fs_search.c')
-rw-r--r--src/fs/fs_search.c150
1 files changed, 90 insertions, 60 deletions
diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c
index efe5bf34a..a9670cb43 100644
--- a/src/fs/fs_search.c
+++ b/src/fs/fs_search.c
@@ -24,10 +24,11 @@
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * 25 *
26 * TODO: 26 * TODO:
27 * - insert code for serialization where needed
28 * - remove *directory* with search results upon completion
29 * - centralize code that sprintf's the 'pbuf[32]' strings
27 * - add support for pushing "already seen" information 30 * - add support for pushing "already seen" information
28 * to FS service for bloomfilter (can wait) 31 * to FS service for bloomfilter (can wait)
29 * - handle availability probes (can wait)
30 * - make operations persistent (can wait)
31 */ 32 */
32 33
33#include "platform.h" 34#include "platform.h"
@@ -41,16 +42,16 @@
41 42
42 43
43/** 44/**
44 * Fill in all of the generic fields for 45 * Fill in all of the generic fields for a search event and
45 * a search event. 46 * call the callback.
46 * 47 *
47 * @param pi structure to fill in 48 * @param pi structure to fill in
48 * @param sc overall search context 49 * @param sc overall search context
49 * @return value returned by the callback 50 * @return value returned by the callback
50 */ 51 */
51static void * 52void *
52make_search_status (struct GNUNET_FS_ProgressInfo *pi, 53GNUNET_FS_search_make_status_ (struct GNUNET_FS_ProgressInfo *pi,
53 struct GNUNET_FS_SearchContext *sc) 54 struct GNUNET_FS_SearchContext *sc)
54{ 55{
55 pi->value.search.sc = sc; 56 pi->value.search.sc = sc;
56 pi->value.search.cctx 57 pi->value.search.cctx
@@ -108,7 +109,7 @@ notify_client_chk_result (struct GNUNET_FS_SearchContext *sc,
108 pi.status = GNUNET_FS_STATUS_SEARCH_RESULT; 109 pi.status = GNUNET_FS_STATUS_SEARCH_RESULT;
109 pi.value.search.specifics.result.meta = sr->meta; 110 pi.value.search.specifics.result.meta = sr->meta;
110 pi.value.search.specifics.result.uri = sr->uri; 111 pi.value.search.specifics.result.uri = sr->uri;
111 sr->client_info = make_search_status (&pi, sc); 112 sr->client_info = GNUNET_FS_search_make_status_ (&pi, sc);
112} 113}
113 114
114 115
@@ -135,7 +136,7 @@ notify_client_chk_update (struct GNUNET_FS_SearchContext *sc,
135 = sr->availability_trials; 136 = sr->availability_trials;
136 pi.value.search.specifics.update.applicability_rank 137 pi.value.search.specifics.update.applicability_rank
137 = sr->optional_support; 138 = sr->optional_support;
138 sr->client_info = make_search_status (&pi, sc); 139 sr->client_info = GNUNET_FS_search_make_status_ (&pi, sc);
139} 140}
140 141
141 142
@@ -183,15 +184,6 @@ get_result_present (void *cls,
183 184
184 185
185/** 186/**
186 * Start download probes for the given search result.
187 *
188 * @param sr the search result
189 */
190static void
191start_probe (struct SearchResult *sr);
192
193
194/**
195 * Signal result of last probe to client and then schedule next 187 * Signal result of last probe to client and then schedule next
196 * probe. 188 * probe.
197 */ 189 */
@@ -207,8 +199,8 @@ signal_probe_result (struct SearchResult *sr)
207 pi.value.search.specifics.update.availability_rank = sr->availability_success; 199 pi.value.search.specifics.update.availability_rank = sr->availability_success;
208 pi.value.search.specifics.update.availability_certainty = sr->availability_trials; 200 pi.value.search.specifics.update.availability_certainty = sr->availability_trials;
209 pi.value.search.specifics.update.applicability_rank = sr->optional_support; 201 pi.value.search.specifics.update.applicability_rank = sr->optional_support;
210 sr->sc->client_info = make_search_status (&pi, sr->sc); 202 sr->sc->client_info = GNUNET_FS_search_make_status_ (&pi, sr->sc);
211 start_probe (sr); 203 GNUNET_FS_search_start_probe_ (sr);
212} 204}
213 205
214 206
@@ -343,8 +335,8 @@ GNUNET_FS_search_probe_progress_ (void *cls,
343 * 335 *
344 * @param sr the search result 336 * @param sr the search result
345 */ 337 */
346static void 338void
347start_probe (struct SearchResult *sr) 339GNUNET_FS_search_start_probe_ (struct SearchResult *sr)
348{ 340{
349 uint64_t off; 341 uint64_t off;
350 uint64_t len; 342 uint64_t len;
@@ -447,7 +439,7 @@ process_ksk_result (struct GNUNET_FS_SearchContext *sc,
447 notify_client_chk_result (sc, sr); 439 notify_client_chk_result (sc, sr);
448 else 440 else
449 notify_client_chk_update (sc, sr); 441 notify_client_chk_update (sc, sr);
450 start_probe (sr); 442 GNUNET_FS_search_start_probe_ (sr);
451} 443}
452 444
453 445
@@ -510,7 +502,7 @@ process_sks_result (struct GNUNET_FS_SearchContext *sc,
510 &key, 502 &key,
511 sr, 503 sr,
512 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 504 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
513 start_probe (sr); 505 GNUNET_FS_search_start_probe_ (sr);
514 /* notify client */ 506 /* notify client */
515 notify_client_chk_result (sc, sr); 507 notify_client_chk_result (sc, sr);
516 /* search for updates */ 508 /* search for updates */
@@ -1067,46 +1059,69 @@ search_start (struct GNUNET_FS_Handle *h,
1067 struct GNUNET_FS_SearchContext *parent) 1059 struct GNUNET_FS_SearchContext *parent)
1068{ 1060{
1069 struct GNUNET_FS_SearchContext *sc; 1061 struct GNUNET_FS_SearchContext *sc;
1070 struct GNUNET_CLIENT_Connection *client;
1071 struct GNUNET_FS_ProgressInfo pi; 1062 struct GNUNET_FS_ProgressInfo pi;
1072 size_t size; 1063
1064 sc = GNUNET_malloc (sizeof(struct GNUNET_FS_SearchContext));
1065 sc->h = h;
1066 sc->options = options;
1067 sc->uri = GNUNET_FS_uri_dup (uri);
1068 sc->anonymity = anonymity;
1069 sc->start_time = GNUNET_TIME_absolute_get ();
1070 sc->parent = parent;
1071 sc->master_result_map = GNUNET_CONTAINER_multihashmap_create (16);
1072 sc->client_info = cctx;
1073 if (NULL != parent)
1074 GNUNET_CONTAINER_DLL_insert (parent->child_head,
1075 parent->child_tail,
1076 sc);
1077 if (GNUNET_OK !=
1078 GNUNET_FS_search_start_searching_ (sc))
1079 {
1080 GNUNET_FS_uri_destroy (sc->uri);
1081 GNUNET_CONTAINER_multihashmap_destroy (sc->master_result_map);
1082 GNUNET_free (sc);
1083 return NULL;
1084 }
1085 pi.status = GNUNET_FS_STATUS_SEARCH_START;
1086 sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc);
1087 return sc;
1088}
1089
1090
1091/**
1092 * Build the request and actually initiate the search using the
1093 * GNUnet FS service.
1094 *
1095 * @param sc search context
1096 * @return GNUNET_OK on success, GNUNET_SYSERR on error
1097 */
1098int
1099GNUNET_FS_search_start_searching_ (struct GNUNET_FS_SearchContext *sc)
1100{
1073 unsigned int i; 1101 unsigned int i;
1074 const char *keyword; 1102 const char *keyword;
1075 GNUNET_HashCode hc; 1103 GNUNET_HashCode hc;
1076 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub; 1104 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
1077 struct GNUNET_CRYPTO_RsaPrivateKey *pk; 1105 struct GNUNET_CRYPTO_RsaPrivateKey *pk;
1106 size_t size;
1078 1107
1079 if (GNUNET_FS_uri_test_ksk (uri)) 1108 GNUNET_assert (NULL == sc->client);
1109 if (GNUNET_FS_uri_test_ksk (sc->uri))
1080 { 1110 {
1081 size = sizeof (struct SearchMessage) * uri->data.ksk.keywordCount; 1111 size = sizeof (struct SearchMessage) * sc->uri->data.ksk.keywordCount;
1082 } 1112 }
1083 else 1113 else
1084 { 1114 {
1085 GNUNET_assert (GNUNET_FS_uri_test_sks (uri)); 1115 GNUNET_assert (GNUNET_FS_uri_test_sks (sc->uri));
1086 size = sizeof (struct SearchMessage); 1116 size = sizeof (struct SearchMessage);
1087 } 1117 }
1088 if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 1118 if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1089 { 1119 {
1090 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1120 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1091 _("Too many keywords specified for a single search.")); 1121 _("Too many keywords specified for a single search."));
1092 return NULL; 1122 return GNUNET_SYSERR;
1093 } 1123 }
1094 client = GNUNET_CLIENT_connect (h->sched, 1124 if (GNUNET_FS_uri_test_ksk (sc->uri))
1095 "fs",
1096 h->cfg);
1097 if (NULL == client)
1098 return NULL;
1099 sc = GNUNET_malloc (sizeof(struct GNUNET_FS_SearchContext));
1100 sc->h = h;
1101 sc->options = options;
1102 sc->uri = GNUNET_FS_uri_dup (uri);
1103 sc->anonymity = anonymity;
1104 sc->start_time = GNUNET_TIME_absolute_get ();
1105 sc->client = client;
1106 sc->parent = parent;
1107 sc->master_result_map = GNUNET_CONTAINER_multihashmap_create (16);
1108 sc->client_info = cctx;
1109 if (GNUNET_FS_uri_test_ksk (uri))
1110 { 1125 {
1111 GNUNET_assert (0 != sc->uri->data.ksk.keywordCount); 1126 GNUNET_assert (0 != sc->uri->data.ksk.keywordCount);
1112 sc->requests = GNUNET_malloc (sizeof (struct SearchRequestEntry) * 1127 sc->requests = GNUNET_malloc (sizeof (struct SearchRequestEntry) *
@@ -1130,22 +1145,23 @@ search_start (struct GNUNET_FS_Handle *h,
1130 &sc->requests[i].key); 1145 &sc->requests[i].key);
1131 } 1146 }
1132 } 1147 }
1133 if (NULL != parent) 1148 sc->client = GNUNET_CLIENT_connect (sc->h->sched,
1134 GNUNET_CONTAINER_DLL_insert (parent->child_head, 1149 "fs",
1135 parent->child_tail, 1150 sc->h->cfg);
1136 sc); 1151 if (NULL == sc->client)
1137 pi.status = GNUNET_FS_STATUS_SEARCH_START; 1152 return GNUNET_SYSERR;
1138 sc->client_info = make_search_status (&pi, sc); 1153 GNUNET_CLIENT_notify_transmit_ready (sc->client,
1139 GNUNET_CLIENT_notify_transmit_ready (client,
1140 size, 1154 size,
1141 GNUNET_CONSTANTS_SERVICE_TIMEOUT, 1155 GNUNET_CONSTANTS_SERVICE_TIMEOUT,
1142 GNUNET_NO, 1156 GNUNET_NO,
1143 &transmit_search_request, 1157 &transmit_search_request,
1144 sc); 1158 sc);
1145 return sc; 1159 return GNUNET_OK;
1146} 1160}
1147 1161
1148 1162
1163
1164
1149/** 1165/**
1150 * Start search for content. 1166 * Start search for content.
1151 * 1167 *
@@ -1188,7 +1204,7 @@ GNUNET_FS_search_pause (struct GNUNET_FS_SearchContext *sc)
1188 // FIXME: make persistent! 1204 // FIXME: make persistent!
1189 // FIXME: should this freeze all active probes? 1205 // FIXME: should this freeze all active probes?
1190 pi.status = GNUNET_FS_STATUS_SEARCH_PAUSED; 1206 pi.status = GNUNET_FS_STATUS_SEARCH_PAUSED;
1191 sc->client_info = make_search_status (&pi, sc); 1207 sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc);
1192} 1208}
1193 1209
1194 1210
@@ -1207,7 +1223,7 @@ GNUNET_FS_search_continue (struct GNUNET_FS_SearchContext *sc)
1207 do_reconnect (sc, NULL); 1223 do_reconnect (sc, NULL);
1208 // FIXME: make persistent! 1224 // FIXME: make persistent!
1209 pi.status = GNUNET_FS_STATUS_SEARCH_CONTINUED; 1225 pi.status = GNUNET_FS_STATUS_SEARCH_CONTINUED;
1210 sc->client_info = make_search_status (&pi, sc); 1226 sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc);
1211} 1227}
1212 1228
1213 1229
@@ -1226,6 +1242,7 @@ search_result_free (void *cls,
1226{ 1242{
1227 struct GNUNET_FS_SearchContext *sc = cls; 1243 struct GNUNET_FS_SearchContext *sc = cls;
1228 struct GNUNET_FS_Handle *h = sc->h; 1244 struct GNUNET_FS_Handle *h = sc->h;
1245 char pbuf[32];
1229 struct SearchResult *sr = value; 1246 struct SearchResult *sr = value;
1230 struct GNUNET_FS_ProgressInfo pi; 1247 struct GNUNET_FS_ProgressInfo pi;
1231 1248
@@ -1233,9 +1250,21 @@ search_result_free (void *cls,
1233 pi.value.search.specifics.result_stopped.cctx = sr->client_info; 1250 pi.value.search.specifics.result_stopped.cctx = sr->client_info;
1234 pi.value.search.specifics.result_stopped.meta = sr->meta; 1251 pi.value.search.specifics.result_stopped.meta = sr->meta;
1235 pi.value.search.specifics.result_stopped.uri = sr->uri; 1252 pi.value.search.specifics.result_stopped.uri = sr->uri;
1236 sr->client_info = make_search_status (&pi, sc); 1253 sr->client_info = GNUNET_FS_search_make_status_ (&pi, sc);
1237 GNUNET_break (NULL == sr->client_info); 1254 GNUNET_break (NULL == sr->client_info);
1238 1255 if (sr->serialization != NULL)
1256 {
1257 GNUNET_snprintf (pbuf,
1258 sizeof (pbuf),
1259 "%s%s%s",
1260 "search-results",
1261 DIR_SEPARATOR_STR,
1262 sc->serialization);
1263 GNUNET_FS_remove_sync_file_ (sc->h,
1264 pbuf,
1265 sr->serialization);
1266 GNUNET_free (sr->serialization);
1267 }
1239 GNUNET_FS_uri_destroy (sr->uri); 1268 GNUNET_FS_uri_destroy (sr->uri);
1240 GNUNET_CONTAINER_meta_data_destroy (sr->meta); 1269 GNUNET_CONTAINER_meta_data_destroy (sr->meta);
1241 if (sr->probe_ctx != NULL) 1270 if (sr->probe_ctx != NULL)
@@ -1274,7 +1303,7 @@ GNUNET_FS_search_stop (struct GNUNET_FS_SearchContext *sc)
1274 &search_result_free, 1303 &search_result_free,
1275 sc); 1304 sc);
1276 pi.status = GNUNET_FS_STATUS_SEARCH_STOPPED; 1305 pi.status = GNUNET_FS_STATUS_SEARCH_STOPPED;
1277 sc->client_info = make_search_status (&pi, sc); 1306 sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc);
1278 GNUNET_break (NULL == sc->client_info); 1307 GNUNET_break (NULL == sc->client_info);
1279 if (sc->task != GNUNET_SCHEDULER_NO_TASK) 1308 if (sc->task != GNUNET_SCHEDULER_NO_TASK)
1280 GNUNET_SCHEDULER_cancel (sc->h->sched, 1309 GNUNET_SCHEDULER_cancel (sc->h->sched,
@@ -1289,6 +1318,7 @@ GNUNET_FS_search_stop (struct GNUNET_FS_SearchContext *sc)
1289 GNUNET_CONTAINER_multihashmap_destroy (sc->requests[i].results); 1318 GNUNET_CONTAINER_multihashmap_destroy (sc->requests[i].results);
1290 } 1319 }
1291 GNUNET_free_non_null (sc->requests); 1320 GNUNET_free_non_null (sc->requests);
1321 GNUNET_free_non_null (sc->emsg);
1292 GNUNET_FS_uri_destroy (sc->uri); 1322 GNUNET_FS_uri_destroy (sc->uri);
1293 GNUNET_free (sc); 1323 GNUNET_free (sc);
1294} 1324}