aboutsummaryrefslogtreecommitdiff
path: root/src/fs/gnunet-service-fs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/gnunet-service-fs.c')
-rw-r--r--src/fs/gnunet-service-fs.c175
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;
680static struct GNUNET_DATASTORE_QueueEntry *mig_qe; 691static struct GNUNET_DATASTORE_QueueEntry *mig_qe;
681 692
682/** 693/**
694 * Where do we store trust information?
695 */
696static char *trustDirectory;
697
698/**
683 * ID of task that collects blocks for migration. 699 * ID of task that collects blocks for migration.
684 */ 700 */
685static GNUNET_SCHEDULER_TaskIdentifier mig_task; 701static 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 */
725static char *
726get_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 */
1220static int
1221change_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 */
1256static int
1257flush_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 */
1293static void
1294cron_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
2954bound_priority (uint32_t prio_in, 3099bound_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,