diff options
Diffstat (limited to 'src/fs/gnunet-service-fs.c')
-rw-r--r-- | src/fs/gnunet-service-fs.c | 175 |
1 files changed, 164 insertions, 11 deletions
diff --git a/src/fs/gnunet-service-fs.c b/src/fs/gnunet-service-fs.c index e2d90f786..ea79d0711 100644 --- a/src/fs/gnunet-service-fs.c +++ b/src/fs/gnunet-service-fs.c | |||
@@ -55,6 +55,12 @@ | |||
55 | #define MAX_QUEUE_PER_PEER 16 | 55 | #define MAX_QUEUE_PER_PEER 16 |
56 | 56 | ||
57 | /** | 57 | /** |
58 | * How often do we flush trust values to disk? | ||
59 | */ | ||
60 | #define TRUST_FLUSH_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) | ||
61 | |||
62 | |||
63 | /** | ||
58 | * Inverse of the probability that we will submit the same query | 64 | * Inverse of the probability that we will submit the same query |
59 | * to the same peer again. If the same peer already got the query | 65 | * to the same peer again. If the same peer already got the query |
60 | * repeatedly recently, the probability is multiplied by the inverse | 66 | * repeatedly recently, the probability is multiplied by the inverse |
@@ -211,9 +217,14 @@ struct ConnectedPeer | |||
211 | uint64_t inc_preference; | 217 | uint64_t inc_preference; |
212 | 218 | ||
213 | /** | 219 | /** |
214 | * Trust delta to still commit to the system. | 220 | * Trust rating for this peer |
215 | */ | 221 | */ |
216 | uint32_t trust_delta; | 222 | uint32_t trust; |
223 | |||
224 | /** | ||
225 | * Trust rating for this peer on disk. | ||
226 | */ | ||
227 | uint32_t disk_trust; | ||
217 | 228 | ||
218 | /** | 229 | /** |
219 | * The peer's identity. | 230 | * The peer's identity. |
@@ -680,6 +691,11 @@ static struct MigrationReadyBlock *mig_tail; | |||
680 | static struct GNUNET_DATASTORE_QueueEntry *mig_qe; | 691 | static struct GNUNET_DATASTORE_QueueEntry *mig_qe; |
681 | 692 | ||
682 | /** | 693 | /** |
694 | * Where do we store trust information? | ||
695 | */ | ||
696 | static char *trustDirectory; | ||
697 | |||
698 | /** | ||
683 | * ID of task that collects blocks for migration. | 699 | * ID of task that collects blocks for migration. |
684 | */ | 700 | */ |
685 | static GNUNET_SCHEDULER_TaskIdentifier mig_task; | 701 | static GNUNET_SCHEDULER_TaskIdentifier mig_task; |
@@ -702,6 +718,24 @@ static int active_migration; | |||
702 | 718 | ||
703 | 719 | ||
704 | /** | 720 | /** |
721 | * Get the filename under which we would store the GNUNET_HELLO_Message | ||
722 | * for the given host and protocol. | ||
723 | * @return filename of the form DIRECTORY/HOSTID | ||
724 | */ | ||
725 | static char * | ||
726 | get_trust_filename (const struct GNUNET_PeerIdentity *id) | ||
727 | { | ||
728 | struct GNUNET_CRYPTO_HashAsciiEncoded fil; | ||
729 | char *fn; | ||
730 | |||
731 | GNUNET_CRYPTO_hash_to_enc (&id->hashPubKey, &fil); | ||
732 | GNUNET_asprintf (&fn, "%s%s%s", trustDirectory, DIR_SEPARATOR_STR, &fil); | ||
733 | return fn; | ||
734 | } | ||
735 | |||
736 | |||
737 | |||
738 | /** | ||
705 | * Transmit messages by copying it to the target buffer | 739 | * Transmit messages by copying it to the target buffer |
706 | * "buf". "buf" will be NULL and "size" zero if the socket was closed | 740 | * "buf". "buf" will be NULL and "size" zero if the socket was closed |
707 | * for writing in the meantime. In that case, do nothing | 741 | * for writing in the meantime. In that case, do nothing |
@@ -1148,9 +1182,18 @@ peer_connect_handler (void *cls, | |||
1148 | { | 1182 | { |
1149 | struct ConnectedPeer *cp; | 1183 | struct ConnectedPeer *cp; |
1150 | struct MigrationReadyBlock *pos; | 1184 | struct MigrationReadyBlock *pos; |
1185 | char *fn; | ||
1186 | uint32_t trust; | ||
1151 | 1187 | ||
1152 | cp = GNUNET_malloc (sizeof (struct ConnectedPeer)); | 1188 | cp = GNUNET_malloc (sizeof (struct ConnectedPeer)); |
1153 | cp->pid = GNUNET_PEER_intern (peer); | 1189 | cp->pid = GNUNET_PEER_intern (peer); |
1190 | |||
1191 | fn = get_trust_filename (peer); | ||
1192 | if ((GNUNET_DISK_file_test (fn) == GNUNET_YES) && | ||
1193 | (sizeof (trust) == GNUNET_DISK_fn_read (fn, &trust, sizeof (trust)))) | ||
1194 | cp->disk_trust = cp->trust = ntohl (trust); | ||
1195 | GNUNET_free (fn); | ||
1196 | |||
1154 | GNUNET_break (GNUNET_OK == | 1197 | GNUNET_break (GNUNET_OK == |
1155 | GNUNET_CONTAINER_multihashmap_put (connected_peers, | 1198 | GNUNET_CONTAINER_multihashmap_put (connected_peers, |
1156 | &peer->hashPubKey, | 1199 | &peer->hashPubKey, |
@@ -1166,6 +1209,105 @@ peer_connect_handler (void *cls, | |||
1166 | } | 1209 | } |
1167 | 1210 | ||
1168 | 1211 | ||
1212 | /** | ||
1213 | * Increase the host credit by a value. | ||
1214 | * | ||
1215 | * @param host which peer to change the trust value on | ||
1216 | * @param value is the int value by which the | ||
1217 | * host credit is to be increased or decreased | ||
1218 | * @returns the actual change in trust (positive or negative) | ||
1219 | */ | ||
1220 | static int | ||
1221 | change_host_trust (struct ConnectedPeer *host, int value) | ||
1222 | { | ||
1223 | unsigned int old_trust; | ||
1224 | |||
1225 | if (value == 0) | ||
1226 | return 0; | ||
1227 | GNUNET_assert (host != NULL); | ||
1228 | old_trust = host->trust; | ||
1229 | if (value > 0) | ||
1230 | { | ||
1231 | if (host->trust + value < host->trust) | ||
1232 | { | ||
1233 | value = UINT32_MAX - host->trust; | ||
1234 | host->trust = UINT32_MAX; | ||
1235 | } | ||
1236 | else | ||
1237 | host->trust += value; | ||
1238 | } | ||
1239 | else | ||
1240 | { | ||
1241 | if (host->trust < -value) | ||
1242 | { | ||
1243 | value = -host->trust; | ||
1244 | host->trust = 0; | ||
1245 | } | ||
1246 | else | ||
1247 | host->trust += value; | ||
1248 | } | ||
1249 | return value; | ||
1250 | } | ||
1251 | |||
1252 | |||
1253 | /** | ||
1254 | * Write host-trust information to a file - flush the buffer entry! | ||
1255 | */ | ||
1256 | static int | ||
1257 | flush_trust (void *cls, | ||
1258 | const GNUNET_HashCode *key, | ||
1259 | void *value) | ||
1260 | { | ||
1261 | struct ConnectedPeer *host = value; | ||
1262 | char *fn; | ||
1263 | uint32_t trust; | ||
1264 | struct GNUNET_PeerIdentity pid; | ||
1265 | |||
1266 | if (host->trust == host->disk_trust) | ||
1267 | return GNUNET_OK; /* unchanged */ | ||
1268 | GNUNET_PEER_resolve (host->pid, | ||
1269 | &pid); | ||
1270 | fn = get_trust_filename (&pid); | ||
1271 | if (host->trust == 0) | ||
1272 | { | ||
1273 | if ((0 != UNLINK (fn)) && (errno != ENOENT)) | ||
1274 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING | | ||
1275 | GNUNET_ERROR_TYPE_BULK, "unlink", fn); | ||
1276 | } | ||
1277 | else | ||
1278 | { | ||
1279 | trust = htonl (host->trust); | ||
1280 | if (sizeof(uint32_t) == GNUNET_DISK_fn_write (fn, &trust, | ||
1281 | sizeof(uint32_t), | ||
1282 | GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE | ||
1283 | | GNUNET_DISK_PERM_GROUP_READ | GNUNET_DISK_PERM_OTHER_READ)) | ||
1284 | host->disk_trust = host->trust; | ||
1285 | } | ||
1286 | GNUNET_free (fn); | ||
1287 | return GNUNET_OK; | ||
1288 | } | ||
1289 | |||
1290 | /** | ||
1291 | * Call this method periodically to scan data/hosts for new hosts. | ||
1292 | */ | ||
1293 | static void | ||
1294 | cron_flush_trust (void *cls, | ||
1295 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1296 | { | ||
1297 | |||
1298 | if (NULL == connected_peers) | ||
1299 | return; | ||
1300 | GNUNET_CONTAINER_multihashmap_iterate (connected_peers, | ||
1301 | &flush_trust, | ||
1302 | NULL); | ||
1303 | if (NULL == tc) | ||
1304 | return; | ||
1305 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | ||
1306 | return; | ||
1307 | GNUNET_SCHEDULER_add_delayed (tc->sched, | ||
1308 | TRUST_FLUSH_FREQ, &cron_flush_trust, NULL); | ||
1309 | } | ||
1310 | |||
1169 | 1311 | ||
1170 | /** | 1312 | /** |
1171 | * Free (each) request made by the peer. | 1313 | * Free (each) request made by the peer. |
@@ -1253,7 +1395,7 @@ peer_disconnect_handler (void *cls, | |||
1253 | &consider_migration, | 1395 | &consider_migration, |
1254 | pos); | 1396 | pos); |
1255 | } | 1397 | } |
1256 | if (cp->trust_delta > 0) | 1398 | if (cp->trust > 0) |
1257 | { | 1399 | { |
1258 | /* FIXME: push trust back to peerinfo! | 1400 | /* FIXME: push trust back to peerinfo! |
1259 | (need better peerinfo API!) */ | 1401 | (need better peerinfo API!) */ |
@@ -1400,6 +1542,7 @@ shutdown_task (void *cls, | |||
1400 | while (client_list != NULL) | 1542 | while (client_list != NULL) |
1401 | handle_client_disconnect (NULL, | 1543 | handle_client_disconnect (NULL, |
1402 | client_list->client); | 1544 | client_list->client); |
1545 | cron_flush_trust (NULL, NULL); | ||
1403 | GNUNET_CONTAINER_multihashmap_iterate (connected_peers, | 1546 | GNUNET_CONTAINER_multihashmap_iterate (connected_peers, |
1404 | &clean_peer, | 1547 | &clean_peer, |
1405 | NULL); | 1548 | NULL); |
@@ -1430,6 +1573,8 @@ shutdown_task (void *cls, | |||
1430 | dsh = NULL; | 1573 | dsh = NULL; |
1431 | sched = NULL; | 1574 | sched = NULL; |
1432 | cfg = NULL; | 1575 | cfg = NULL; |
1576 | GNUNET_free_non_null (trustDirectory); | ||
1577 | trustDirectory = NULL; | ||
1433 | } | 1578 | } |
1434 | 1579 | ||
1435 | 1580 | ||
@@ -2674,7 +2819,7 @@ handle_p2p_put (void *cls, | |||
2674 | if (prq.sender != NULL) | 2819 | if (prq.sender != NULL) |
2675 | { | 2820 | { |
2676 | prq.sender->inc_preference += CONTENT_BANDWIDTH_VALUE + 1000 * prq.priority; | 2821 | prq.sender->inc_preference += CONTENT_BANDWIDTH_VALUE + 1000 * prq.priority; |
2677 | prq.sender->trust_delta += prq.priority; | 2822 | prq.sender->trust += prq.priority; |
2678 | } | 2823 | } |
2679 | if (GNUNET_YES == active_migration) | 2824 | if (GNUNET_YES == active_migration) |
2680 | { | 2825 | { |
@@ -2954,13 +3099,9 @@ static uint32_t | |||
2954 | bound_priority (uint32_t prio_in, | 3099 | bound_priority (uint32_t prio_in, |
2955 | struct ConnectedPeer *cp) | 3100 | struct ConnectedPeer *cp) |
2956 | { | 3101 | { |
2957 | if (cp->trust_delta > prio_in) | 3102 | /* FIXME: check if load is low and we |
2958 | { | 3103 | hence should not charge... */ |
2959 | cp->trust_delta -= prio_in; | 3104 | return change_host_trust (cp, prio_in); |
2960 | return prio_in; | ||
2961 | } | ||
2962 | // FIXME: get out trust in the target peer from peerinfo! | ||
2963 | return 0; | ||
2964 | } | 3105 | } |
2965 | 3106 | ||
2966 | 3107 | ||
@@ -3510,6 +3651,7 @@ main_init (struct GNUNET_SCHEDULER_Handle *s, | |||
3510 | NULL, | 3651 | NULL, |
3511 | &peer_connect_handler, | 3652 | &peer_connect_handler, |
3512 | &peer_disconnect_handler, | 3653 | &peer_disconnect_handler, |
3654 | NULL, | ||
3513 | NULL, GNUNET_NO, | 3655 | NULL, GNUNET_NO, |
3514 | NULL, GNUNET_NO, | 3656 | NULL, GNUNET_NO, |
3515 | p2p_handlers); | 3657 | p2p_handlers); |
@@ -3543,6 +3685,17 @@ main_init (struct GNUNET_SCHEDULER_Handle *s, | |||
3543 | GNUNET_SERVER_disconnect_notify (server, | 3685 | GNUNET_SERVER_disconnect_notify (server, |
3544 | &handle_client_disconnect, | 3686 | &handle_client_disconnect, |
3545 | NULL); | 3687 | NULL); |
3688 | GNUNET_assert (GNUNET_OK == | ||
3689 | GNUNET_CONFIGURATION_get_value_filename (cfg, | ||
3690 | "fs", | ||
3691 | "TRUST", | ||
3692 | &trustDirectory)); | ||
3693 | GNUNET_DISK_directory_create (trustDirectory); | ||
3694 | GNUNET_SCHEDULER_add_with_priority (sched, | ||
3695 | GNUNET_SCHEDULER_PRIORITY_HIGH, | ||
3696 | &cron_flush_trust, NULL); | ||
3697 | |||
3698 | |||
3546 | GNUNET_SERVER_add_handlers (server, handlers); | 3699 | GNUNET_SERVER_add_handlers (server, handlers); |
3547 | GNUNET_SCHEDULER_add_delayed (sched, | 3700 | GNUNET_SCHEDULER_add_delayed (sched, |
3548 | GNUNET_TIME_UNIT_FOREVER_REL, | 3701 | GNUNET_TIME_UNIT_FOREVER_REL, |