diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-10-06 21:32:05 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-10-06 21:32:05 +0000 |
commit | ca1cd117f6a59c0d19f841f72ac37340284ada57 (patch) | |
tree | 698e924a91c96d6ff79b738262a463f0d5004be6 /src/core | |
parent | 68f027903ee06b86c56c9f16dba9a83333936dbe (diff) | |
download | gnunet-ca1cd117f6a59c0d19f841f72ac37340284ada57.tar.gz gnunet-ca1cd117f6a59c0d19f841f72ac37340284ada57.zip |
towards KX
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/gnunet-service-core-new.c | 31 | ||||
-rw-r--r-- | src/core/gnunet-service-core_kx.c | 1307 | ||||
-rw-r--r-- | src/core/gnunet-service-core_kx.h | 112 | ||||
-rw-r--r-- | src/core/gnunet-service-core_neighbours.c | 6 | ||||
-rw-r--r-- | src/core/gnunet-service-core_neighbours.h | 2 | ||||
-rw-r--r-- | src/core/gnunet-service-core_sessions.c | 117 | ||||
-rw-r--r-- | src/core/gnunet-service-core_sessions.h | 22 |
7 files changed, 699 insertions, 898 deletions
diff --git a/src/core/gnunet-service-core-new.c b/src/core/gnunet-service-core-new.c index d67ae47b5..afdc22d9d 100644 --- a/src/core/gnunet-service-core-new.c +++ b/src/core/gnunet-service-core-new.c | |||
@@ -145,37 +145,6 @@ | |||
145 | #define MAX_MESSAGE_AGE GNUNET_TIME_UNIT_DAYS | 145 | #define MAX_MESSAGE_AGE GNUNET_TIME_UNIT_DAYS |
146 | 146 | ||
147 | 147 | ||
148 | /** | ||
149 | * State machine for our P2P encryption handshake. Everyone starts in | ||
150 | * "DOWN", if we receive the other peer's key (other peer initiated) | ||
151 | * we start in state RECEIVED (since we will immediately send our | ||
152 | * own); otherwise we start in SENT. If we get back a PONG from | ||
153 | * within either state, we move up to CONFIRMED (the PONG will always | ||
154 | * be sent back encrypted with the key we sent to the other peer). | ||
155 | */ | ||
156 | enum PeerStateMachine | ||
157 | { | ||
158 | /** | ||
159 | * No handshake yet. | ||
160 | */ | ||
161 | PEER_STATE_DOWN, | ||
162 | |||
163 | /** | ||
164 | * We've sent our session key. | ||
165 | */ | ||
166 | PEER_STATE_KEY_SENT, | ||
167 | |||
168 | /** | ||
169 | * We've received the other peers session key. | ||
170 | */ | ||
171 | PEER_STATE_KEY_RECEIVED, | ||
172 | |||
173 | /** | ||
174 | * The other peer has confirmed our session key with a message | ||
175 | * encrypted with his session key (which we got). Session is now fully up. | ||
176 | */ | ||
177 | PEER_STATE_KEY_CONFIRMED | ||
178 | }; | ||
179 | 148 | ||
180 | /** | 149 | /** |
181 | * Number of bytes (at the beginning) of "struct EncryptedMessage" | 150 | * Number of bytes (at the beginning) of "struct EncryptedMessage" |
diff --git a/src/core/gnunet-service-core_kx.c b/src/core/gnunet-service-core_kx.c index 1ab31cb2b..efc6ca1c2 100644 --- a/src/core/gnunet-service-core_kx.c +++ b/src/core/gnunet-service-core_kx.c | |||
@@ -199,6 +199,10 @@ static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key; | |||
199 | */ | 199 | */ |
200 | static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key; | 200 | static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key; |
201 | 201 | ||
202 | /** | ||
203 | * Our message stream tokenizer (for encrypted payload). | ||
204 | */ | ||
205 | static struct GNUNET_SERVER_MessageStreamTokenizer *mst; | ||
202 | 206 | ||
203 | 207 | ||
204 | 208 | ||
@@ -258,7 +262,7 @@ derive_pong_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv, | |||
258 | * Encrypt size bytes from in and write the result to out. Use the | 262 | * Encrypt size bytes from in and write the result to out. Use the |
259 | * key for outbound traffic of the given neighbour. | 263 | * key for outbound traffic of the given neighbour. |
260 | * | 264 | * |
261 | * @param n neighbour we are sending to | 265 | * @param kx key information context |
262 | * @param iv initialization vector to use | 266 | * @param iv initialization vector to use |
263 | * @param in ciphertext | 267 | * @param in ciphertext |
264 | * @param out plaintext | 268 | * @param out plaintext |
@@ -266,7 +270,7 @@ derive_pong_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv, | |||
266 | * @return GNUNET_OK on success | 270 | * @return GNUNET_OK on success |
267 | */ | 271 | */ |
268 | static int | 272 | static int |
269 | do_encrypt (struct Neighbour *n, | 273 | do_encrypt (struct GSC_KeyExchangeInfo *kx, |
270 | const struct GNUNET_CRYPTO_AesInitializationVector *iv, | 274 | const struct GNUNET_CRYPTO_AesInitializationVector *iv, |
271 | const void *in, void *out, size_t size) | 275 | const void *in, void *out, size_t size) |
272 | { | 276 | { |
@@ -277,14 +281,14 @@ do_encrypt (struct Neighbour *n, | |||
277 | } | 281 | } |
278 | GNUNET_assert (size == | 282 | GNUNET_assert (size == |
279 | GNUNET_CRYPTO_aes_encrypt (in, (uint16_t) size, | 283 | GNUNET_CRYPTO_aes_encrypt (in, (uint16_t) size, |
280 | &n->encrypt_key, iv, out)); | 284 | &kx->encrypt_key, iv, out)); |
281 | GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes encrypted"), size, | 285 | GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes encrypted"), size, |
282 | GNUNET_NO); | 286 | GNUNET_NO); |
283 | #if DEBUG_CORE > 2 | 287 | #if DEBUG_CORE > 2 |
284 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 288 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
285 | "Encrypted %u bytes for `%4s' using key %u, IV %u\n", | 289 | "Encrypted %u bytes for `%4s' using key %u, IV %u\n", |
286 | (unsigned int) size, GNUNET_i2s (&n->peer), | 290 | (unsigned int) size, GNUNET_i2s (&kx->peer), |
287 | (unsigned int) n->encrypt_key.crc32, GNUNET_CRYPTO_crc32_n (iv, | 291 | (unsigned int) kx->encrypt_key.crc32, GNUNET_CRYPTO_crc32_n (iv, |
288 | sizeof | 292 | sizeof |
289 | (iv))); | 293 | (iv))); |
290 | #endif | 294 | #endif |
@@ -299,7 +303,7 @@ do_encrypt (struct Neighbour *n, | |||
299 | * key for inbound traffic of the given neighbour. This function does | 303 | * key for inbound traffic of the given neighbour. This function does |
300 | * NOT do any integrity-checks on the result. | 304 | * NOT do any integrity-checks on the result. |
301 | * | 305 | * |
302 | * @param n neighbour we are receiving from | 306 | * @param kx key information context |
303 | * @param iv initialization vector to use | 307 | * @param iv initialization vector to use |
304 | * @param in ciphertext | 308 | * @param in ciphertext |
305 | * @param out plaintext | 309 | * @param out plaintext |
@@ -307,7 +311,7 @@ do_encrypt (struct Neighbour *n, | |||
307 | * @return GNUNET_OK on success | 311 | * @return GNUNET_OK on success |
308 | */ | 312 | */ |
309 | static int | 313 | static int |
310 | do_decrypt (struct Neighbour *n, | 314 | do_decrypt (struct GSC_KeyExchangeInfo *kx, |
311 | const struct GNUNET_CRYPTO_AesInitializationVector *iv, | 315 | const struct GNUNET_CRYPTO_AesInitializationVector *iv, |
312 | const void *in, void *out, size_t size) | 316 | const void *in, void *out, size_t size) |
313 | { | 317 | { |
@@ -316,14 +320,14 @@ do_decrypt (struct Neighbour *n, | |||
316 | GNUNET_break (0); | 320 | GNUNET_break (0); |
317 | return GNUNET_NO; | 321 | return GNUNET_NO; |
318 | } | 322 | } |
319 | if ((n->status != PEER_STATE_KEY_RECEIVED) && | 323 | if ((kx->status != KX_STATE_KEY_RECEIVED) && |
320 | (n->status != PEER_STATE_KEY_CONFIRMED)) | 324 | (kx->status != KX_STATE_UP)) |
321 | { | 325 | { |
322 | GNUNET_break_op (0); | 326 | GNUNET_break_op (0); |
323 | return GNUNET_SYSERR; | 327 | return GNUNET_SYSERR; |
324 | } | 328 | } |
325 | if (size != | 329 | if (size != |
326 | GNUNET_CRYPTO_aes_decrypt (in, (uint16_t) size, &n->decrypt_key, iv, out)) | 330 | GNUNET_CRYPTO_aes_decrypt (in, (uint16_t) size, &kx->decrypt_key, iv, out)) |
327 | { | 331 | { |
328 | GNUNET_break (0); | 332 | GNUNET_break (0); |
329 | return GNUNET_SYSERR; | 333 | return GNUNET_SYSERR; |
@@ -333,8 +337,8 @@ do_decrypt (struct Neighbour *n, | |||
333 | #if DEBUG_CORE > 1 | 337 | #if DEBUG_CORE > 1 |
334 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 338 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
335 | "Decrypted %u bytes from `%4s' using key %u, IV %u\n", | 339 | "Decrypted %u bytes from `%4s' using key %u, IV %u\n", |
336 | (unsigned int) size, GNUNET_i2s (&n->peer), | 340 | (unsigned int) size, GNUNET_i2s (&kx->peer), |
337 | (unsigned int) n->decrypt_key.crc32, GNUNET_CRYPTO_crc32_n (iv, | 341 | (unsigned int) kx->decrypt_key.crc32, GNUNET_CRYPTO_crc32_n (iv, |
338 | sizeof | 342 | sizeof |
339 | (*iv))); | 343 | (*iv))); |
340 | #endif | 344 | #endif |
@@ -342,6 +346,104 @@ do_decrypt (struct Neighbour *n, | |||
342 | } | 346 | } |
343 | 347 | ||
344 | 348 | ||
349 | |||
350 | /** | ||
351 | * Task that will retry "send_key" if our previous attempt failed. | ||
352 | * | ||
353 | * @param cls our 'struct GSC_KeyExchangeInfo' | ||
354 | * @param tc scheduler context | ||
355 | */ | ||
356 | static void | ||
357 | set_key_retry_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
358 | { | ||
359 | struct GSC_KeyExchangeInfo *kx = cls; | ||
360 | |||
361 | kx->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK; | ||
362 | kx->set_key_retry_frequency = GNUNET_TIME_relative_multiply (kx->set_key_retry_frequency, 2); | ||
363 | send_key (kx); | ||
364 | } | ||
365 | |||
366 | |||
367 | /** | ||
368 | * PEERINFO is giving us a HELLO for a peer. Add the public key to | ||
369 | * the neighbour's struct and continue with the key exchange. Or, if | ||
370 | * we did not get a HELLO, just do nothing. | ||
371 | * | ||
372 | * @param cls the 'struct GSC_KeyExchangeInfo' to retry sending the key for | ||
373 | * @param peer the peer for which this is the HELLO | ||
374 | * @param hello HELLO message of that peer | ||
375 | * @param err_msg NULL if successful, otherwise contains error message | ||
376 | */ | ||
377 | static void | ||
378 | process_hello (void *cls, const struct GNUNET_PeerIdentity *peer, | ||
379 | const struct GNUNET_HELLO_Message *hello, | ||
380 | const char *err_msg) | ||
381 | { | ||
382 | struct GSC_KeyExchangeInfo *kx = cls; | ||
383 | struct SetKeyMessage *skm; | ||
384 | |||
385 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == n->retry_set_key_task); | ||
386 | if (err_msg != NULL) | ||
387 | { | ||
388 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
389 | _("Error in communication with PEERINFO service\n")); | ||
390 | kx->pitr = NULL; | ||
391 | return; | ||
392 | } | ||
393 | if (peer == NULL) | ||
394 | { | ||
395 | kx->pitr = NULL; | ||
396 | if (kx->public_key != NULL) | ||
397 | return; /* done here */ | ||
398 | #if DEBUG_CORE | ||
399 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
400 | "Failed to obtain public key for peer `%4s', delaying processing of SET_KEY\n", | ||
401 | GNUNET_i2s (&kx->peer)); | ||
402 | #endif | ||
403 | GNUNET_STATISTICS_update (stats, | ||
404 | gettext_noop | ||
405 | ("# Delayed connecting due to lack of public key"), | ||
406 | 1, GNUNET_NO); | ||
407 | kx->retry_set_key_task = | ||
408 | GNUNET_SCHEDULER_add_delayed (kx->set_key_retry_frequency, | ||
409 | &set_key_retry_task, kx); | ||
410 | return; | ||
411 | } | ||
412 | if (kx->public_key != NULL) | ||
413 | { | ||
414 | /* already have public key, why are we here? */ | ||
415 | GNUNET_break (0); | ||
416 | return; | ||
417 | } | ||
418 | kx->public_key = | ||
419 | GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); | ||
420 | if (GNUNET_OK != GNUNET_HELLO_get_key (hello, n->public_key)) | ||
421 | { | ||
422 | GNUNET_break (0); | ||
423 | GNUNET_free (kx->public_key); | ||
424 | kx->public_key = NULL; | ||
425 | return; | ||
426 | } | ||
427 | send_key (kx); | ||
428 | if (NULL != kx->skm_received) | ||
429 | { | ||
430 | skm = kx->skm_received; | ||
431 | kx->skm_received = NULL; | ||
432 | GSC_KX_handle_set_key (kx, &skm->header); | ||
433 | GNUNET_free (skm); | ||
434 | } | ||
435 | } | ||
436 | |||
437 | |||
438 | /** | ||
439 | * Send our key (and encrypted PING) to the other peer. | ||
440 | * | ||
441 | * @param kx key exchange context | ||
442 | */ | ||
443 | static void | ||
444 | send_key (struct GSC_KeyExchangeInfo *kx); | ||
445 | |||
446 | |||
345 | /** | 447 | /** |
346 | * Start the key exchange with the given peer. | 448 | * Start the key exchange with the given peer. |
347 | * | 449 | * |
@@ -353,7 +455,14 @@ GSC_KX_start (const struct GNUNET_PeerIdentity *pid) | |||
353 | { | 455 | { |
354 | struct GSC_KeyExchangeInfo *kx; | 456 | struct GSC_KeyExchangeInfo *kx; |
355 | 457 | ||
356 | kx = NULL; | 458 | kx = GNUNET_malloc (sizeof (struct GSC_KeyExchangeInfo)); |
459 | kx->peer = *pid; | ||
460 | n->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY; | ||
461 | kx->pitr = GNUNET_PEERINFO_iterate (peerinfo, | ||
462 | pid, | ||
463 | GNUNET_TIME_UNIT_FOREVER_REL /* timeout? */, | ||
464 | &process_hello, | ||
465 | kx); | ||
357 | return kx; | 466 | return kx; |
358 | } | 467 | } |
359 | 468 | ||
@@ -371,11 +480,19 @@ GSC_KX_stop (struct GSC_KeyExchangeInfo *kx) | |||
371 | GNUNET_PEERINFO_iterate_cancel (kx->pitr); | 480 | GNUNET_PEERINFO_iterate_cancel (kx->pitr); |
372 | kx->pitr = NULL; | 481 | kx->pitr = NULL; |
373 | } | 482 | } |
374 | |||
375 | GNUNET_SCHEDULER_cancel (n->dead_clean_task); | ||
376 | if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK) | ||
377 | if (kx->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK) | 483 | if (kx->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK) |
484 | { | ||
378 | GNUNET_SCHEDULER_cancel (kx->retry_set_key_task); | 485 | GNUNET_SCHEDULER_cancel (kx->retry_set_key_task); |
486 | kx->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK; | ||
487 | } | ||
488 | if (kx->keep_alive_task != GNUNET_SCHEDULER_NO_TASK) | ||
489 | { | ||
490 | GNUNET_SCHEDULER_cancel (n->keep_alive_task); | ||
491 | kx->keep_alive_task = GNUNET_SCHEDULER_NO_TASK; | ||
492 | } | ||
493 | GNUNET_free_non_null (kx->skm_received); | ||
494 | GNUNET_free_non_null (kx->ping_received); | ||
495 | GNUNET_free_non_null (kx->pong_received); | ||
379 | GNUNET_free_non_null (kx->public_key); | 496 | GNUNET_free_non_null (kx->public_key); |
380 | GNUNET_free (kx); | 497 | GNUNET_free (kx); |
381 | } | 498 | } |
@@ -385,15 +502,12 @@ GSC_KX_stop (struct GSC_KeyExchangeInfo *kx) | |||
385 | * We received a SET_KEY message. Validate and update | 502 | * We received a SET_KEY message. Validate and update |
386 | * our key material and status. | 503 | * our key material and status. |
387 | * | 504 | * |
388 | * @param n the neighbour from which we received message m | 505 | * @param kx key exchange status for the corresponding peer |
389 | * @param m the set key message we received | 506 | * @param msg the set key message we received |
390 | * @param ats performance data | ||
391 | * @param ats_count number of entries in ats (excluding 0-termination) | ||
392 | */ | 507 | */ |
393 | void | 508 | void |
394 | GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *n, const struct GNUNET_MessageHandler *msg, | 509 | GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *kx, |
395 | const struct GNUNET_TRANSPORT_ATS_Information *ats, | 510 | const struct GNUNET_MessageHandler *msg) |
396 | uint32_t ats_count) | ||
397 | { | 511 | { |
398 | const struct SetKeyMessage *m; | 512 | const struct SetKeyMessage *m; |
399 | struct SetKeyMessage *m_cpy; | 513 | struct SetKeyMessage *m_cpy; |
@@ -417,43 +531,19 @@ GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *n, const struct GNUNET_Messag | |||
417 | #if DEBUG_CORE | 531 | #if DEBUG_CORE |
418 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 532 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
419 | "Core service receives `%s' request from `%4s'.\n", "SET_KEY", | 533 | "Core service receives `%s' request from `%4s'.\n", "SET_KEY", |
420 | GNUNET_i2s (&n->peer)); | 534 | GNUNET_i2s (&kx->peer)); |
421 | #endif | 535 | #endif |
422 | if (n->public_key == NULL) | 536 | if (kx->public_key == NULL) |
423 | { | 537 | { |
424 | if (n->pitr != NULL) | 538 | GNUNET_free_non_null (kx->skm_received); |
425 | { | 539 | kx->skm_received = GNUNET_copy_message (msg); |
426 | #if DEBUG_CORE | ||
427 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
428 | "Ignoring `%s' message due to lack of public key for peer (still trying to obtain one).\n", | ||
429 | "SET_KEY"); | ||
430 | #endif | ||
431 | return; | ||
432 | } | ||
433 | #if DEBUG_CORE | ||
434 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
435 | "Lacking public key for peer, trying to obtain one (handle_set_key).\n"); | ||
436 | #endif | ||
437 | m_cpy = GNUNET_malloc (sizeof (struct SetKeyMessage)); | ||
438 | memcpy (m_cpy, m, sizeof (struct SetKeyMessage)); | ||
439 | /* lookup n's public key, then try again */ | ||
440 | GNUNET_assert (n->skm == NULL); | ||
441 | n->skm = m_cpy; | ||
442 | n->pitr = | ||
443 | GNUNET_PEERINFO_iterate (peerinfo, &n->peer, GNUNET_TIME_UNIT_MINUTES, | ||
444 | &process_hello_retry_handle_set_key, n); | ||
445 | GNUNET_STATISTICS_update (stats, | ||
446 | gettext_noop | ||
447 | ("# SET_KEY messages deferred (need public key)"), | ||
448 | 1, GNUNET_NO); | ||
449 | return; | 540 | return; |
450 | } | 541 | } |
451 | if (0 != | 542 | if (0 != |
452 | memcmp (&m->target, &my_identity, sizeof (struct GNUNET_PeerIdentity))) | 543 | memcmp (&m->target, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity))) |
453 | { | 544 | { |
454 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 545 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
455 | _ | 546 | _("`%s' is for `%s', not for me. Ignoring.\n"), |
456 | ("Received `%s' message that was for `%s', not for me. Ignoring.\n"), | ||
457 | "SET_KEY", GNUNET_i2s (&m->target)); | 547 | "SET_KEY", GNUNET_i2s (&m->target)); |
458 | return; | 548 | return; |
459 | } | 549 | } |
@@ -464,16 +554,16 @@ GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *n, const struct GNUNET_Messag | |||
464 | sizeof (struct GNUNET_PeerIdentity)) || | 554 | sizeof (struct GNUNET_PeerIdentity)) || |
465 | (GNUNET_OK != | 555 | (GNUNET_OK != |
466 | GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_SET_KEY, &m->purpose, | 556 | GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_SET_KEY, &m->purpose, |
467 | &m->signature, n->public_key))) | 557 | &m->signature, kx->public_key))) |
468 | { | 558 | { |
469 | /* invalid signature */ | 559 | /* invalid signature */ |
470 | GNUNET_break_op (0); | 560 | GNUNET_break_op (0); |
471 | return; | 561 | return; |
472 | } | 562 | } |
473 | t = GNUNET_TIME_absolute_ntoh (m->creation_time); | 563 | t = GNUNET_TIME_absolute_ntoh (m->creation_time); |
474 | if (((n->status == PEER_STATE_KEY_RECEIVED) || | 564 | if (((kx->status == KX_STATE_KEY_RECEIVED) || |
475 | (n->status == PEER_STATE_KEY_CONFIRMED)) && | 565 | (kx->status == KX_STATE_UP)) && |
476 | (t.abs_value < n->decrypt_key_created.abs_value)) | 566 | (t.abs_value < kx->decrypt_key_created.abs_value)) |
477 | { | 567 | { |
478 | /* this could rarely happen due to massive re-ordering of | 568 | /* this could rarely happen due to massive re-ordering of |
479 | * messages on the network level, but is most likely either | 569 | * messages on the network level, but is most likely either |
@@ -481,9 +571,6 @@ GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *n, const struct GNUNET_Messag | |||
481 | GNUNET_break_op (0); | 571 | GNUNET_break_op (0); |
482 | return; | 572 | return; |
483 | } | 573 | } |
484 | #if DEBUG_CORE | ||
485 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decrypting key material.\n"); | ||
486 | #endif | ||
487 | if ((GNUNET_CRYPTO_rsa_decrypt | 574 | if ((GNUNET_CRYPTO_rsa_decrypt |
488 | (my_private_key, &m->encrypted_key, &k, | 575 | (my_private_key, &m->encrypted_key, &k, |
489 | sizeof (struct GNUNET_CRYPTO_AesSessionKey)) != | 576 | sizeof (struct GNUNET_CRYPTO_AesSessionKey)) != |
@@ -497,68 +584,50 @@ GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *n, const struct GNUNET_Messag | |||
497 | GNUNET_STATISTICS_update (stats, | 584 | GNUNET_STATISTICS_update (stats, |
498 | gettext_noop ("# SET_KEY messages decrypted"), 1, | 585 | gettext_noop ("# SET_KEY messages decrypted"), 1, |
499 | GNUNET_NO); | 586 | GNUNET_NO); |
500 | n->decrypt_key = k; | 587 | kx->decrypt_key = k; |
501 | if (n->decrypt_key_created.abs_value != t.abs_value) | 588 | if (kx->decrypt_key_created.abs_value != t.abs_value) |
502 | { | 589 | { |
503 | /* fresh key, reset sequence numbers */ | 590 | /* fresh key, reset sequence numbers */ |
504 | n->last_sequence_number_received = 0; | 591 | kx->last_sequence_number_received = 0; |
505 | n->last_packets_bitmap = 0; | 592 | kx->last_packets_bitmap = 0; |
506 | n->decrypt_key_created = t; | 593 | kx->decrypt_key_created = t; |
507 | } | 594 | } |
508 | update_neighbour_performance (n, ats, ats_count); | ||
509 | sender_status = (enum PeerStateMachine) ntohl (m->sender_status); | 595 | sender_status = (enum PeerStateMachine) ntohl (m->sender_status); |
510 | switch (n->status) | 596 | |
597 | switch (kx->status) | ||
511 | { | 598 | { |
512 | case PEER_STATE_DOWN: | 599 | case KX_STATE_DOWN: |
513 | n->status = PEER_STATE_KEY_RECEIVED; | 600 | kx->status = PEER_STATE_KEY_RECEIVED; |
514 | #if DEBUG_CORE | 601 | /* we're not up, so we are already doing 'send_key' */ |
515 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
516 | "Responding to `%s' with my own key.\n", "SET_KEY"); | ||
517 | #endif | ||
518 | send_key (n); | ||
519 | break; | 602 | break; |
520 | case PEER_STATE_KEY_SENT: | 603 | case KX_STATE_KEY_SENT: |
521 | case PEER_STATE_KEY_RECEIVED: | ||
522 | n->status = PEER_STATE_KEY_RECEIVED; | 604 | n->status = PEER_STATE_KEY_RECEIVED; |
523 | if ((sender_status != PEER_STATE_KEY_RECEIVED) && | 605 | /* we're not up, so we are already doing 'send_key' */ |
524 | (sender_status != PEER_STATE_KEY_CONFIRMED)) | ||
525 | { | ||
526 | #if DEBUG_CORE | ||
527 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
528 | "Responding to `%s' with my own key (other peer has status %u).\n", | ||
529 | "SET_KEY", (unsigned int) sender_status); | ||
530 | #endif | ||
531 | send_key (n); | ||
532 | } | ||
533 | break; | 606 | break; |
534 | case PEER_STATE_KEY_CONFIRMED: | 607 | case KX_STATE_KEY_RECEIVED: |
535 | if ((sender_status != PEER_STATE_KEY_RECEIVED) && | 608 | /* we're not up, so we are already doing 'send_key' */ |
536 | (sender_status != PEER_STATE_KEY_CONFIRMED)) | 609 | break; |
537 | { | 610 | case KX_STATE_UP: |
538 | #if DEBUG_CORE | 611 | if ( (sender_status == KX_STATE_DOWN) || |
539 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 612 | (sender_status == KX_PEER_STATE_KEY_SENT) ) |
540 | "Responding to `%s' with my own key (other peer has status %u), I was already fully up.\n", | 613 | send_key (kx); /* we are up, but other peer is not! */ |
541 | "SET_KEY", (unsigned int) sender_status); | ||
542 | #endif | ||
543 | send_key (n); | ||
544 | } | ||
545 | break; | 614 | break; |
546 | default: | 615 | default: |
547 | GNUNET_break (0); | 616 | GNUNET_break (0); |
548 | break; | 617 | break; |
549 | } | 618 | } |
550 | if (n->pending_ping != NULL) | 619 | if (kx->ping_received != NULL) |
551 | { | 620 | { |
552 | ping = n->pending_ping; | 621 | ping = kx->ping_received; |
553 | n->pending_ping = NULL; | 622 | kx->ping_received = NULL; |
554 | handle_ping (n, ping, NULL, 0); | 623 | GSC_KX_handle_ping (kx, &ping->header); |
555 | GNUNET_free (ping); | 624 | GNUNET_free (ping); |
556 | } | 625 | } |
557 | if (n->pending_pong != NULL) | 626 | if (kx->pong_received != NULL) |
558 | { | 627 | { |
559 | pong = n->pending_pong; | 628 | pong = kx->pong_received; |
560 | n->pending_pong = NULL; | 629 | kx->pong_received = NULL; |
561 | handle_pong (n, pong, NULL, 0); | 630 | GSC_KX_handle_pong (kx, &pong->header); |
562 | GNUNET_free (pong); | 631 | GNUNET_free (pong); |
563 | } | 632 | } |
564 | } | 633 | } |
@@ -566,25 +635,20 @@ GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *n, const struct GNUNET_Messag | |||
566 | 635 | ||
567 | /** | 636 | /** |
568 | * We received a PING message. Validate and transmit | 637 | * We received a PING message. Validate and transmit |
569 | * PONG. | 638 | * a PONG message. |
570 | * | 639 | * |
571 | * @param n sender of the PING | 640 | * @param kx key exchange status for the corresponding peer |
572 | * @param m the encrypted PING message itself | 641 | * @param msg the encrypted PING message itself |
573 | * @param ats performance data | ||
574 | * @param ats_count number of entries in ats (excluding 0-termination) | ||
575 | */ | 642 | */ |
576 | void | 643 | void |
577 | GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *n, const struct GNUNET_MessageHeader *msg, | 644 | GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *n, const struct GNUNET_MessageHeader *msg) |
578 | const struct GNUNET_TRANSPORT_ATS_Information *ats, | ||
579 | uint32_t ats_count) | ||
580 | { | 645 | { |
581 | const struct PingMessage *m; | 646 | const struct PingMessage *m; |
582 | struct PingMessage t; | 647 | struct PingMessage t; |
583 | struct PongMessage tx; | 648 | struct PongMessage tx; |
584 | struct PongMessage *tp; | 649 | struct PongMessage tp; |
585 | struct MessageEntry *me; | ||
586 | struct GNUNET_CRYPTO_AesInitializationVector iv; | 650 | struct GNUNET_CRYPTO_AesInitializationVector iv; |
587 | size_t size; | 651 | uint16_t msize; |
588 | 652 | ||
589 | msize = ntohs (msg->size); | 653 | msize = ntohs (msg->size); |
590 | if (msize != sizeof (struct PingMessage)) | 654 | if (msize != sizeof (struct PingMessage)) |
@@ -592,49 +656,34 @@ GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *n, const struct GNUNET_MessageHe | |||
592 | GNUNET_break_op (0); | 656 | GNUNET_break_op (0); |
593 | return; | 657 | return; |
594 | } | 658 | } |
595 | GNUNET_STATISTICS_update (stats, gettext_noop ("# PING messages received"), | 659 | GNUNET_STATISTICS_update (GSC_stats, |
660 | gettext_noop ("# PING messages received"), | ||
596 | 1, GNUNET_NO); | 661 | 1, GNUNET_NO); |
597 | 662 | if ( (kx->status != KX_STATE_KEY_RECEIVED) && | |
598 | #if FIXME | 663 | (kx->status != KX_STATE_UP) ) |
599 | if ((n->status != PEER_STATE_KEY_RECEIVED) && | ||
600 | (n->status != PEER_STATE_KEY_CONFIRMED)) | ||
601 | { | 664 | { |
602 | #if DEBUG_CORE > 1 | 665 | /* defer */ |
603 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
604 | "Core service receives `%s' request from `%4s' but have not processed key; marking as pending.\n", | ||
605 | "PING", GNUNET_i2s (&n->peer)); | ||
606 | #endif | ||
607 | GNUNET_free_non_null (n->pending_ping); | 666 | GNUNET_free_non_null (n->pending_ping); |
608 | n->pending_ping = GNUNET_malloc (sizeof (struct PingMessage)); | 667 | n->pending_ping = GNUNET_copy_message (msg); |
609 | memcpy (n->pending_ping, message, sizeof (struct PingMessage)); | ||
610 | return; | 668 | return; |
611 | } | 669 | } |
612 | #endif | 670 | m = (const struct PingMessage*) msg; |
613 | m = (const struct PingMessage*) msg; | ||
614 | #if DEBUG_CORE | 671 | #if DEBUG_CORE |
615 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 672 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
616 | "Core service receives `%s' request from `%4s'.\n", "PING", | 673 | "Core service receives `%s' request from `%4s'.\n", "PING", |
617 | GNUNET_i2s (&n->peer)); | 674 | GNUNET_i2s (&n->peer)); |
618 | #endif | 675 | #endif |
619 | derive_iv (&iv, &n->decrypt_key, m->iv_seed, &my_identity); | 676 | derive_iv (&iv, &kx->decrypt_key, m->iv_seed, &GSC_my_identity); |
620 | if (GNUNET_OK != | 677 | if (GNUNET_OK != |
621 | do_decrypt (n, &iv, &m->target, &t.target, | 678 | do_decrypt (kx, &iv, &m->target, &t.target, |
622 | sizeof (struct PingMessage) - ((void *) &m->target - | 679 | sizeof (struct PingMessage) - ((void *) &m->target - |
623 | (void *) m))) | 680 | (void *) m))) |
681 | { | ||
682 | GNUNET_break_op (0); | ||
624 | return; | 683 | return; |
625 | #if DEBUG_HANDSHAKE | 684 | } |
626 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
627 | "Decrypted `%s' to `%4s' with challenge %u decrypted using key %u, IV %u (salt %u)\n", | ||
628 | "PING", GNUNET_i2s (&t.target), (unsigned int) t.challenge, | ||
629 | (unsigned int) n->decrypt_key.crc32, GNUNET_CRYPTO_crc32_n (&iv, | ||
630 | sizeof | ||
631 | (iv)), | ||
632 | m->iv_seed); | ||
633 | #endif | ||
634 | GNUNET_STATISTICS_update (stats, gettext_noop ("# PING messages decrypted"), | ||
635 | 1, GNUNET_NO); | ||
636 | if (0 != | 685 | if (0 != |
637 | memcmp (&t.target, &my_identity, sizeof (struct GNUNET_PeerIdentity))) | 686 | memcmp (&t.target, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity))) |
638 | { | 687 | { |
639 | char sender[9]; | 688 | char sender[9]; |
640 | char peer[9]; | 689 | char peer[9]; |
@@ -642,60 +691,135 @@ GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *n, const struct GNUNET_MessageHe | |||
642 | GNUNET_snprintf (sender, sizeof (sender), "%8s", GNUNET_i2s (&n->peer)); | 691 | GNUNET_snprintf (sender, sizeof (sender), "%8s", GNUNET_i2s (&n->peer)); |
643 | GNUNET_snprintf (peer, sizeof (peer), "%8s", GNUNET_i2s (&t.target)); | 692 | GNUNET_snprintf (peer, sizeof (peer), "%8s", GNUNET_i2s (&t.target)); |
644 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 693 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
645 | _ | 694 | _("Received PING from `%s' for different identity: I am `%s', PONG identity: `%s'\n"), |
646 | ("Received PING from `%s' for different identity: I am `%s', PONG identity: `%s'\n"), | ||
647 | sender, GNUNET_i2s (&my_identity), peer); | 695 | sender, GNUNET_i2s (&my_identity), peer); |
648 | GNUNET_break_op (0); | 696 | GNUNET_break_op (0); |
649 | return; | 697 | return; |
650 | } | 698 | } |
651 | update_neighbour_performance (n, ats, ats_count); | 699 | /* construct PONG */ |
652 | me = GNUNET_malloc (sizeof (struct MessageEntry) + | ||
653 | sizeof (struct PongMessage)); | ||
654 | GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head, n->encrypted_tail, | ||
655 | n->encrypted_tail, me); | ||
656 | me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PONG_DELAY); | ||
657 | me->priority = PONG_PRIORITY; | ||
658 | me->size = sizeof (struct PongMessage); | ||
659 | tx.inbound_bw_limit = n->bw_in; | 700 | tx.inbound_bw_limit = n->bw_in; |
660 | tx.challenge = t.challenge; | 701 | tx.challenge = t.challenge; |
661 | tx.target = t.target; | 702 | tx.target = t.target; |
662 | tp = (struct PongMessage *) &me[1]; | 703 | tp.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PONG); |
663 | tp->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PONG); | 704 | tp.header.size = htons (sizeof (struct PongMessage)); |
664 | tp->header.size = htons (sizeof (struct PongMessage)); | 705 | tp.iv_seed = |
665 | tp->iv_seed = | ||
666 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX); | 706 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX); |
667 | derive_pong_iv (&iv, &n->encrypt_key, tp->iv_seed, t.challenge, &n->peer); | 707 | derive_pong_iv (&iv, &n->encrypt_key, tp.iv_seed, t.challenge, &kx->peer); |
668 | do_encrypt (n, &iv, &tx.challenge, &tp->challenge, | 708 | do_encrypt (n, &iv, &tx.challenge, &tp.challenge, |
669 | sizeof (struct PongMessage) - ((void *) &tp->challenge - | 709 | sizeof (struct PongMessage) - ((void *) &tp.challenge - |
670 | (void *) tp)); | 710 | (void *) tp)); |
671 | GNUNET_STATISTICS_update (stats, gettext_noop ("# PONG messages created"), 1, | 711 | GNUNET_STATISTICS_update (GSC_stats, |
712 | gettext_noop ("# PONG messages created"), 1, | ||
672 | GNUNET_NO); | 713 | GNUNET_NO); |
673 | #if DEBUG_HANDSHAKE | 714 | GSC_NEIGHBOURS_transmit (&kx->peer, |
674 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 715 | &tp.header, |
675 | "Encrypting `%s' with challenge %u using key %u, IV %u (salt %u)\n", | 716 | GNUNET_TIME_UNIT_FOREVER_REL /* FIXME: timeout */); |
676 | "PONG", (unsigned int) t.challenge, | 717 | } |
677 | (unsigned int) n->encrypt_key.crc32, GNUNET_CRYPTO_crc32_n (&iv, | 718 | |
678 | sizeof | 719 | |
679 | (iv)), | 720 | /** |
680 | tp->iv_seed); | 721 | * Create a fresh SET KEY message for transmission to the other peer. |
681 | #endif | 722 | * Also creates a new key. |
682 | /* trigger queue processing */ | 723 | * |
683 | process_encrypted_neighbour_queue (n); | 724 | * @param kx key exchange context to create SET KEY message for |
725 | */ | ||
726 | static void | ||
727 | setup_fresh_setkey (struct GSC_KeyExchangeInfo *kx) | ||
728 | { | ||
729 | struct SetKeyMessage *skm; | ||
730 | |||
731 | GNUNET_CRYPTO_aes_create_session_key (&kx->encrypt_key); | ||
732 | kx->encrypt_key_created = GNUNET_TIME_absolute_get (); | ||
733 | skm = &kx->skm; | ||
734 | skm->header.size = htons (sizeof (struct SetKeyMessage)); | ||
735 | skm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SET_KEY); | ||
736 | skm->purpose.size = | ||
737 | htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + | ||
738 | sizeof (struct GNUNET_TIME_AbsoluteNBO) + | ||
739 | sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) + | ||
740 | sizeof (struct GNUNET_PeerIdentity)); | ||
741 | skm->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SET_KEY); | ||
742 | skm->creation_time = GNUNET_TIME_absolute_hton (kx->encrypt_key_created); | ||
743 | skm->target = kx->peer; | ||
744 | GNUNET_assert (GNUNET_OK == | ||
745 | GNUNET_CRYPTO_rsa_encrypt (&kx->encrypt_key, | ||
746 | sizeof (struct | ||
747 | GNUNET_CRYPTO_AesSessionKey), | ||
748 | kx->public_key, &skm->encrypted_key)); | ||
749 | GNUNET_assert (GNUNET_OK == | ||
750 | GNUNET_CRYPTO_rsa_sign (my_private_key, &skm->purpose, | ||
751 | &skm->signature)); | ||
752 | } | ||
753 | |||
754 | |||
755 | /** | ||
756 | * Create a fresh PING message for transmission to the other peer. | ||
757 | * | ||
758 | * @param kx key exchange context to create PING for | ||
759 | */ | ||
760 | static void | ||
761 | setup_fresh_ping (struct GSC_KeyExchangeInfo *kx) | ||
762 | { | ||
763 | struct PingMessage pp; | ||
764 | struct PingMessage *pm; | ||
765 | |||
766 | pm = &kx->ping; | ||
767 | pm->header.size = htons (sizeof (struct PingMessage)); | ||
768 | pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING); | ||
769 | pm->iv_seed = | ||
770 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX); | ||
771 | derive_iv (&iv, &kx->encrypt_key, pm->iv_seed, &kx->peer); | ||
772 | pp.challenge = kx->ping_challenge; | ||
773 | pp.target = kx->peer; | ||
774 | do_encrypt (kx, &iv, &pp.target, &pm->target, | ||
775 | sizeof (struct PingMessage) - ((void *) &pm->target - | ||
776 | (void *) pm)); | ||
777 | } | ||
778 | |||
779 | |||
780 | /** | ||
781 | * Task triggered when a neighbour entry is about to time out | ||
782 | * (and we should prevent this by sending a PING). | ||
783 | * | ||
784 | * @param cls the 'struct GSC_KeyExchangeInfo' | ||
785 | * @param tc scheduler context (not used) | ||
786 | */ | ||
787 | static void | ||
788 | send_keep_alive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
789 | { | ||
790 | struct GSC_KeyExchangeInfo *kx = cls; | ||
791 | struct GNUNET_TIME_Relative retry; | ||
792 | struct GNUNET_TIME_Relative left; | ||
793 | |||
794 | kx->keep_alive_task = GNUNET_SCHEDULER_NO_TASK; | ||
795 | left = GNUNET_TIME_absolute_get_remaining (kx->timeout); | ||
796 | if (left.rel_value == 0) | ||
797 | { | ||
798 | GSC_SESSIONS_end (&kx->peer); | ||
799 | kx->status = KX_STATE_DOWN; | ||
800 | return; | ||
801 | } | ||
802 | setup_fresh_ping (kx); | ||
803 | GDS_NEIGHBOURS_transmit (&kx->peer, | ||
804 | &kx->ping.header, | ||
805 | kx->set_key_retry_frequency); | ||
806 | retry = | ||
807 | GNUNET_TIME_relative_max (GNUNET_TIME_relative_divide (left, 2), | ||
808 | MIN_PING_FREQUENCY); | ||
809 | kx->keep_alive_task = | ||
810 | GNUNET_SCHEDULER_add_delayed (retry, &send_keep_alive, kx); | ||
811 | |||
684 | } | 812 | } |
685 | 813 | ||
686 | 814 | ||
687 | /** | 815 | /** |
688 | * We received a PONG message. Validate and update our status. | 816 | * We received a PONG message. Validate and update our status. |
689 | * | 817 | * |
690 | * @param n sender of the PONG | 818 | * @param kx key exchange context for the the PONG |
691 | * @param m the encrypted PONG message itself | 819 | * @param m the encrypted PONG message itself |
692 | * @param ats performance data | ||
693 | * @param ats_count number of entries in ats (excluding 0-termination) | ||
694 | */ | 820 | */ |
695 | void | 821 | void |
696 | GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *n, const struct GNUNET_MessageHeader *msg, | 822 | GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx, const struct GNUNET_MessageHeader *msg) |
697 | const struct GNUNET_TRANSPORT_ATS_Information *ats, | ||
698 | uint32_t ats_count) | ||
699 | { | 823 | { |
700 | const struct PongMessage *m; | 824 | const struct PongMessage *m; |
701 | struct PongMessage t; | 825 | struct PongMessage t; |
@@ -708,41 +832,35 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *n, const struct GNUNET_MessageHe | |||
708 | 832 | ||
709 | msize = ntohs (msg->size); | 833 | msize = ntohs (msg->size); |
710 | if (msize != sizeof (struct PongMessage)) | 834 | if (msize != sizeof (struct PongMessage)) |
711 | { | 835 | { |
712 | GNUNET_break_op (0); | 836 | GNUNET_break_op (0); |
713 | return; | 837 | return; |
714 | } | 838 | } |
715 | GNUNET_STATISTICS_update (stats, gettext_noop ("# PONG messages received"), | 839 | GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# PONG messages received"), |
716 | 1, GNUNET_NO); | 840 | 1, GNUNET_NO); |
717 | 841 | ||
718 | #if FIXME | 842 | if ( (kx->status != KX_STATE_KEY_RECEIVED) && |
719 | if ((n->status != PEER_STATE_KEY_RECEIVED) && | 843 | (kx->status != KX_STATE_UP) ) |
720 | (n->status != PEER_STATE_KEY_CONFIRMED)) | 844 | { |
845 | if (kx->status == KX_STATE_KEY_SENT) | ||
721 | { | 846 | { |
722 | #if DEBUG_CORE > 1 | ||
723 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
724 | "Core service receives `%s' request from `%4s' but have not processed key; marking as pending.\n", | ||
725 | "PONG", GNUNET_i2s (&n->peer)); | ||
726 | #endif | ||
727 | GNUNET_free_non_null (n->pending_pong); | 847 | GNUNET_free_non_null (n->pending_pong); |
728 | n->pending_pong = GNUNET_malloc (sizeof (struct PongMessage)); | 848 | n->pending_pong = GNUNET_copy_message (msg); |
729 | memcpy (n->pending_pong, message, sizeof (struct PongMessage)); | ||
730 | return; | ||
731 | } | 849 | } |
732 | #endif | 850 | return; |
733 | 851 | } | |
734 | m = (const struct PongMessage*) msg; | 852 | m = (const struct PongMessage*) msg; |
735 | #if DEBUG_HANDSHAKE | 853 | #if DEBUG_HANDSHAKE |
736 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 854 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
737 | "Core service receives `%s' response from `%4s'.\n", "PONG", | 855 | "Core service receives `%s' response from `%4s'.\n", "PONG", |
738 | GNUNET_i2s (&n->peer)); | 856 | GNUNET_i2s (&kx->peer)); |
739 | #endif | 857 | #endif |
740 | /* mark as garbage, just to be sure */ | 858 | /* mark as garbage, just to be sure */ |
741 | memset (&t, 255, sizeof (t)); | 859 | memset (&t, 255, sizeof (t)); |
742 | derive_pong_iv (&iv, &n->decrypt_key, m->iv_seed, n->ping_challenge, | 860 | derive_pong_iv (&iv, &kx->decrypt_key, m->iv_seed, kx->ping_challenge, |
743 | &my_identity); | 861 | &my_identity); |
744 | if (GNUNET_OK != | 862 | if (GNUNET_OK != |
745 | do_decrypt (n, &iv, &m->challenge, &t.challenge, | 863 | do_decrypt (kx, &iv, &m->challenge, &t.challenge, |
746 | sizeof (struct PongMessage) - ((void *) &m->challenge - | 864 | sizeof (struct PongMessage) - ((void *) &m->challenge - |
747 | (void *) m))) | 865 | (void *) m))) |
748 | { | 866 | { |
@@ -751,17 +869,8 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *n, const struct GNUNET_MessageHe | |||
751 | } | 869 | } |
752 | GNUNET_STATISTICS_update (stats, gettext_noop ("# PONG messages decrypted"), | 870 | GNUNET_STATISTICS_update (stats, gettext_noop ("# PONG messages decrypted"), |
753 | 1, GNUNET_NO); | 871 | 1, GNUNET_NO); |
754 | #if DEBUG_HANDSHAKE | 872 | if ((0 != memcmp (&t.target, &kx->peer, sizeof (struct GNUNET_PeerIdentity))) |
755 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 873 | || (kx->ping_challenge != t.challenge)) |
756 | "Decrypted `%s' from `%4s' with challenge %u using key %u, IV %u (salt %u)\n", | ||
757 | "PONG", GNUNET_i2s (&t.target), (unsigned int) t.challenge, | ||
758 | (unsigned int) n->decrypt_key.crc32, GNUNET_CRYPTO_crc32_n (&iv, | ||
759 | sizeof | ||
760 | (iv)), | ||
761 | m->iv_seed); | ||
762 | #endif | ||
763 | if ((0 != memcmp (&t.target, &n->peer, sizeof (struct GNUNET_PeerIdentity))) | ||
764 | || (n->ping_challenge != t.challenge)) | ||
765 | { | 874 | { |
766 | /* PONG malformed */ | 875 | /* PONG malformed */ |
767 | #if DEBUG_CORE | 876 | #if DEBUG_CORE |
@@ -773,490 +882,99 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *n, const struct GNUNET_MessageHe | |||
773 | "Received malformed `%s' received from `%4s' with challenge %u\n", | 882 | "Received malformed `%s' received from `%4s' with challenge %u\n", |
774 | "PONG", GNUNET_i2s (&t.target), (unsigned int) t.challenge); | 883 | "PONG", GNUNET_i2s (&t.target), (unsigned int) t.challenge); |
775 | #endif | 884 | #endif |
776 | GNUNET_break_op (n->ping_challenge != t.challenge); | ||
777 | return; | 885 | return; |
778 | } | 886 | } |
779 | switch (n->status) | 887 | switch (kx->status) |
780 | { | 888 | { |
781 | case PEER_STATE_DOWN: | 889 | case KX_STATE_DOWN: |
782 | GNUNET_break (0); /* should be impossible */ | 890 | GNUNET_break (0); /* should be impossible */ |
783 | return; | 891 | return; |
784 | case PEER_STATE_KEY_SENT: | 892 | case KX_STATE_KEY_SENT: |
785 | GNUNET_break (0); /* should be impossible, how did we decrypt? */ | 893 | GNUNET_break (0); /* should be impossible */ |
786 | return; | 894 | return; |
787 | case PEER_STATE_KEY_RECEIVED: | 895 | case KX_STATE_KEY_RECEIVED: |
788 | GNUNET_STATISTICS_update (stats, | 896 | GNUNET_STATISTICS_update (stats, |
789 | gettext_noop | 897 | gettext_noop |
790 | ("# Session keys confirmed via PONG"), 1, | 898 | ("# Session keys confirmed via PONG"), 1, |
791 | GNUNET_NO); | 899 | GNUNET_NO); |
792 | n->status = PEER_STATE_KEY_CONFIRMED; | 900 | kx->status = KX_STATE_UP; |
793 | { | 901 | GSC_SESSIONS_create (&kx->peer); |
794 | struct GNUNET_MessageHeader *hdr; | 902 | GNUNET_assert (kx->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK); |
795 | 903 | GNUNET_SCHEDULER_cancel (kx->retry_set_key_task); | |
796 | hdr = compute_type_map_message (); | 904 | kx->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK; |
797 | send_type_map_to_neighbour (hdr, &n->peer.hashPubKey, n); | 905 | GNUNET_assert (kx->keep_alive_task == GNUNET_SCHEDULER_NO_TASK); |
798 | GNUNET_free (hdr); | 906 | update_timeout (kx); |
799 | } | 907 | break; |
800 | if (n->bw_out_external_limit.value__ != t.inbound_bw_limit.value__) | ||
801 | { | ||
802 | n->bw_out_external_limit = t.inbound_bw_limit; | ||
803 | n->bw_out = | ||
804 | GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit, | ||
805 | n->bw_out_internal_limit); | ||
806 | GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window, | ||
807 | n->bw_out); | ||
808 | GNUNET_TRANSPORT_set_quota (transport, &n->peer, n->bw_in, n->bw_out); | ||
809 | } | ||
810 | #if DEBUG_CORE | ||
811 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
812 | "Confirmed key via `%s' message for peer `%4s'\n", "PONG", | ||
813 | GNUNET_i2s (&n->peer)); | ||
814 | #endif | ||
815 | if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK) | ||
816 | { | ||
817 | GNUNET_SCHEDULER_cancel (n->retry_set_key_task); | ||
818 | n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK; | ||
819 | } | ||
820 | update_neighbour_performance (n, ats, ats_count); | ||
821 | size = | ||
822 | sizeof (struct ConnectNotifyMessage) + | ||
823 | (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information); | ||
824 | if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
825 | { | ||
826 | GNUNET_break (0); | ||
827 | /* recovery strategy: throw away performance data */ | ||
828 | GNUNET_array_grow (n->ats, n->ats_count, 0); | ||
829 | size = | ||
830 | sizeof (struct PeerStatusNotifyMessage) + | ||
831 | n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information); | ||
832 | } | ||
833 | cnm = (struct ConnectNotifyMessage *) buf; | ||
834 | cnm->header.size = htons (size); | ||
835 | cnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT); | ||
836 | cnm->ats_count = htonl (n->ats_count); | ||
837 | cnm->peer = n->peer; | ||
838 | mats = &cnm->ats; | ||
839 | memcpy (mats, n->ats, | ||
840 | n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information)); | ||
841 | mats[n->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); | ||
842 | mats[n->ats_count].value = htonl (0); | ||
843 | send_to_all_clients (&cnm->header, GNUNET_NO, | ||
844 | GNUNET_CORE_OPTION_SEND_CONNECT); | ||
845 | process_encrypted_neighbour_queue (n); | ||
846 | /* fall-through! */ | ||
847 | case PEER_STATE_KEY_CONFIRMED: | 908 | case PEER_STATE_KEY_CONFIRMED: |
848 | n->last_activity = GNUNET_TIME_absolute_get (); | 909 | update_timeout (kx); |
849 | if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK) | ||
850 | GNUNET_SCHEDULER_cancel (n->keep_alive_task); | ||
851 | n->keep_alive_task = | ||
852 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide | ||
853 | (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
854 | 2), &send_keep_alive, n); | ||
855 | handle_peer_status_change (n); | ||
856 | break; | 910 | break; |
857 | default: | 911 | default: |
858 | GNUNET_break (0); | 912 | GNUNET_break (0); |
859 | break; | 913 | break; |
860 | } | 914 | } |
861 | |||
862 | #if FIXME | ||
863 | if (n->status == PEER_STATE_KEY_CONFIRMED) | ||
864 | { | ||
865 | now = GNUNET_TIME_absolute_get (); | ||
866 | n->last_activity = now; | ||
867 | changed = GNUNET_YES; | ||
868 | if (!up) | ||
869 | { | ||
870 | GNUNET_STATISTICS_update (stats, gettext_noop ("# established sessions"), | ||
871 | 1, GNUNET_NO); | ||
872 | n->time_established = now; | ||
873 | } | ||
874 | if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK) | ||
875 | GNUNET_SCHEDULER_cancel (n->keep_alive_task); | ||
876 | n->keep_alive_task = | ||
877 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide | ||
878 | (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
879 | 2), &send_keep_alive, n); | ||
880 | } | ||
881 | if (changed) | ||
882 | handle_peer_status_change (n); | ||
883 | #endif | ||
884 | } | ||
885 | |||
886 | |||
887 | |||
888 | /** | ||
889 | * PEERINFO is giving us a HELLO for a peer. Add the public key to | ||
890 | * the neighbour's struct and retry send_key. Or, if we did not get a | ||
891 | * HELLO, just do nothing. | ||
892 | * | ||
893 | * @param cls the 'struct Neighbour' to retry sending the key for | ||
894 | * @param peer the peer for which this is the HELLO | ||
895 | * @param hello HELLO message of that peer | ||
896 | * @param err_msg NULL if successful, otherwise contains error message | ||
897 | */ | ||
898 | static void | ||
899 | process_hello_retry_send_key (void *cls, const struct GNUNET_PeerIdentity *peer, | ||
900 | const struct GNUNET_HELLO_Message *hello, | ||
901 | const char *err_msg) | ||
902 | { | ||
903 | struct Neighbour *n = cls; | ||
904 | |||
905 | if (err_msg != NULL) | ||
906 | { | ||
907 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
908 | _("Error in communication with PEERINFO service\n")); | ||
909 | /* return; */ | ||
910 | } | ||
911 | |||
912 | if (peer == NULL) | ||
913 | { | ||
914 | #if DEBUG_CORE | ||
915 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Entered `%s' and `%s' is NULL!\n", | ||
916 | "process_hello_retry_send_key", "peer"); | ||
917 | #endif | ||
918 | n->pitr = NULL; | ||
919 | if (n->public_key != NULL) | ||
920 | { | ||
921 | if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK) | ||
922 | { | ||
923 | GNUNET_SCHEDULER_cancel (n->retry_set_key_task); | ||
924 | n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK; | ||
925 | } | ||
926 | GNUNET_STATISTICS_update (stats, | ||
927 | gettext_noop | ||
928 | ("# SET_KEY messages deferred (need public key)"), | ||
929 | -1, GNUNET_NO); | ||
930 | send_key (n); | ||
931 | } | ||
932 | else | ||
933 | { | ||
934 | #if DEBUG_CORE | ||
935 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
936 | "Failed to obtain public key for peer `%4s', delaying processing of SET_KEY\n", | ||
937 | GNUNET_i2s (&n->peer)); | ||
938 | #endif | ||
939 | GNUNET_STATISTICS_update (stats, | ||
940 | gettext_noop | ||
941 | ("# Delayed connecting due to lack of public key"), | ||
942 | 1, GNUNET_NO); | ||
943 | if (GNUNET_SCHEDULER_NO_TASK == n->retry_set_key_task) | ||
944 | n->retry_set_key_task = | ||
945 | GNUNET_SCHEDULER_add_delayed (n->set_key_retry_frequency, | ||
946 | &set_key_retry_task, n); | ||
947 | } | ||
948 | return; | ||
949 | } | ||
950 | |||
951 | #if DEBUG_CORE | ||
952 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Entered `%s' for peer `%4s'\n", | ||
953 | "process_hello_retry_send_key", GNUNET_i2s (peer)); | ||
954 | #endif | ||
955 | if (n->public_key != NULL) | ||
956 | { | ||
957 | /* already have public key, why are we here? */ | ||
958 | GNUNET_break (0); | ||
959 | return; | ||
960 | } | ||
961 | |||
962 | #if DEBUG_CORE | ||
963 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
964 | "Received new `%s' message for `%4s', initiating key exchange.\n", | ||
965 | "HELLO", GNUNET_i2s (peer)); | ||
966 | #endif | ||
967 | n->public_key = | ||
968 | GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); | ||
969 | if (GNUNET_OK != GNUNET_HELLO_get_key (hello, n->public_key)) | ||
970 | { | ||
971 | GNUNET_STATISTICS_update (stats, | ||
972 | gettext_noop | ||
973 | ("# Error extracting public key from HELLO"), 1, | ||
974 | GNUNET_NO); | ||
975 | GNUNET_free (n->public_key); | ||
976 | n->public_key = NULL; | ||
977 | #if DEBUG_CORE | ||
978 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
979 | "GNUNET_HELLO_get_key returned awfully\n"); | ||
980 | #endif | ||
981 | return; | ||
982 | } | ||
983 | } | 915 | } |
984 | 916 | ||
985 | 917 | ||
986 | /** | 918 | /** |
987 | * Send our key (and encrypted PING) to the other peer. | 919 | * Send our key (and encrypted PING) to the other peer. |
988 | * | 920 | * |
989 | * @param n the other peer | 921 | * @param kx key exchange context |
990 | */ | 922 | */ |
991 | static void | 923 | static void |
992 | send_key (struct Neighbour *n) | 924 | send_key (struct GSC_KeyExchangeInfo *kx) |
993 | { | 925 | { |
994 | struct MessageEntry *pos; | ||
995 | struct SetKeyMessage *sm; | ||
996 | struct MessageEntry *me; | ||
997 | struct PingMessage pp; | ||
998 | struct PingMessage *pm; | ||
999 | struct GNUNET_CRYPTO_AesInitializationVector iv; | 926 | struct GNUNET_CRYPTO_AesInitializationVector iv; |
1000 | 927 | ||
1001 | if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK) | 928 | GNUNET_assert (kx->retry_set_key_task == GNUNET_SCHEDULER_NO_TASK); |
1002 | { | 929 | if (KX_STATE_UP == kx->status) |
1003 | GNUNET_SCHEDULER_cancel (n->retry_set_key_task); | 930 | return; /* nothing to do */ |
1004 | n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK; | 931 | if (kx->public_key == NULL) |
1005 | } | ||
1006 | if (n->pitr != NULL) | ||
1007 | { | ||
1008 | #if DEBUG_CORE | ||
1009 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1010 | "Key exchange in progress with `%4s'.\n", | ||
1011 | GNUNET_i2s (&n->peer)); | ||
1012 | #endif | ||
1013 | return; /* already in progress */ | ||
1014 | } | ||
1015 | if (GNUNET_YES != n->is_connected) | ||
1016 | { | 932 | { |
1017 | GNUNET_STATISTICS_update (stats, | 933 | /* lookup public key, then try again */ |
1018 | gettext_noop | 934 | kx->pitr = |
1019 | ("# Asking transport to connect (for SET_KEY)"), | 935 | GNUNET_PEERINFO_iterate (peerinfo, &kx->peer, |
1020 | 1, GNUNET_NO); | 936 | GNUNET_TIME_UNIT_FOREVER_REL /* timeout? */, |
1021 | GNUNET_TRANSPORT_try_connect (transport, &n->peer); | 937 | &process_hello, kx); |
1022 | return; | 938 | return; |
1023 | } | 939 | } |
1024 | #if DEBUG_CORE | ||
1025 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1026 | "Asked to perform key exchange with `%4s'.\n", | ||
1027 | GNUNET_i2s (&n->peer)); | ||
1028 | #endif | ||
1029 | if (n->public_key == NULL) | ||
1030 | { | ||
1031 | /* lookup n's public key, then try again */ | ||
1032 | #if DEBUG_CORE | ||
1033 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1034 | "Lacking public key for `%4s', trying to obtain one (send_key).\n", | ||
1035 | GNUNET_i2s (&n->peer)); | ||
1036 | #endif | ||
1037 | GNUNET_assert (n->pitr == NULL); | ||
1038 | n->pitr = | ||
1039 | GNUNET_PEERINFO_iterate (peerinfo, &n->peer, | ||
1040 | GNUNET_TIME_relative_multiply | ||
1041 | (GNUNET_TIME_UNIT_SECONDS, 20), | ||
1042 | &process_hello_retry_send_key, n); | ||
1043 | return; | ||
1044 | } | ||
1045 | pos = n->encrypted_head; | ||
1046 | while (pos != NULL) | ||
1047 | { | ||
1048 | if (GNUNET_YES == pos->is_setkey) | ||
1049 | { | ||
1050 | if (pos->sender_status == n->status) | ||
1051 | { | ||
1052 | #if DEBUG_CORE | ||
1053 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1054 | "`%s' message for `%4s' queued already\n", "SET_KEY", | ||
1055 | GNUNET_i2s (&n->peer)); | ||
1056 | #endif | ||
1057 | goto trigger_processing; | ||
1058 | } | ||
1059 | GNUNET_CONTAINER_DLL_remove (n->encrypted_head, n->encrypted_tail, pos); | ||
1060 | GNUNET_free (pos); | ||
1061 | #if DEBUG_CORE | ||
1062 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1063 | "Removing queued `%s' message for `%4s', will create a new one\n", | ||
1064 | "SET_KEY", GNUNET_i2s (&n->peer)); | ||
1065 | #endif | ||
1066 | break; | ||
1067 | } | ||
1068 | pos = pos->next; | ||
1069 | } | ||
1070 | 940 | ||
1071 | /* update status */ | 941 | /* update status */ |
1072 | switch (n->status) | 942 | switch (n->status) |
1073 | { | 943 | { |
1074 | case PEER_STATE_DOWN: | 944 | case KX_STATE_DOWN: |
1075 | n->status = PEER_STATE_KEY_SENT; | 945 | n->status = PEER_STATE_KEY_SENT; |
1076 | break; | 946 | /* setup SET KEY message */ |
1077 | case PEER_STATE_KEY_SENT: | 947 | setup_fresh_set_key (kx); |
948 | setup_fresh_ping (kx); | ||
949 | GNUNET_STATISTICS_update (stats, | ||
950 | gettext_noop | ||
951 | ("# SET_KEY and PING messages created"), 1, | ||
952 | GNUNET_NO); | ||
1078 | break; | 953 | break; |
1079 | case PEER_STATE_KEY_RECEIVED: | 954 | case KX_STATE_KEY_SENT: |
1080 | break; | 955 | break; |
1081 | case PEER_STATE_KEY_CONFIRMED: | 956 | case KX_STATE_KEY_RECEIVED: |
1082 | break; | 957 | break; |
958 | case KX_STATE_KEY_CONFIRMED: | ||
959 | GNUNET_break (0); | ||
960 | return; | ||
1083 | default: | 961 | default: |
1084 | GNUNET_break (0); | 962 | GNUNET_break (0); |
1085 | break; | ||
1086 | } | ||
1087 | |||
1088 | |||
1089 | /* first, set key message */ | ||
1090 | me = GNUNET_malloc (sizeof (struct MessageEntry) + | ||
1091 | sizeof (struct SetKeyMessage) + | ||
1092 | sizeof (struct PingMessage)); | ||
1093 | me->deadline = GNUNET_TIME_relative_to_absolute (MAX_SET_KEY_DELAY); | ||
1094 | me->priority = SET_KEY_PRIORITY; | ||
1095 | me->size = sizeof (struct SetKeyMessage) + sizeof (struct PingMessage); | ||
1096 | me->is_setkey = GNUNET_YES; | ||
1097 | me->got_slack = GNUNET_YES; /* do not defer this one! */ | ||
1098 | me->sender_status = n->status; | ||
1099 | GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head, n->encrypted_tail, | ||
1100 | n->encrypted_tail, me); | ||
1101 | sm = (struct SetKeyMessage *) &me[1]; | ||
1102 | sm->header.size = htons (sizeof (struct SetKeyMessage)); | ||
1103 | sm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SET_KEY); | ||
1104 | sm->sender_status = | ||
1105 | htonl ((int32_t) | ||
1106 | ((n->status == | ||
1107 | PEER_STATE_DOWN) ? PEER_STATE_KEY_SENT : n->status)); | ||
1108 | sm->purpose.size = | ||
1109 | htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + | ||
1110 | sizeof (struct GNUNET_TIME_AbsoluteNBO) + | ||
1111 | sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) + | ||
1112 | sizeof (struct GNUNET_PeerIdentity)); | ||
1113 | sm->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SET_KEY); | ||
1114 | sm->creation_time = GNUNET_TIME_absolute_hton (n->encrypt_key_created); | ||
1115 | sm->target = n->peer; | ||
1116 | GNUNET_assert (GNUNET_OK == | ||
1117 | GNUNET_CRYPTO_rsa_encrypt (&n->encrypt_key, | ||
1118 | sizeof (struct | ||
1119 | GNUNET_CRYPTO_AesSessionKey), | ||
1120 | n->public_key, &sm->encrypted_key)); | ||
1121 | GNUNET_assert (GNUNET_OK == | ||
1122 | GNUNET_CRYPTO_rsa_sign (my_private_key, &sm->purpose, | ||
1123 | &sm->signature)); | ||
1124 | pm = (struct PingMessage *) &sm[1]; | ||
1125 | pm->header.size = htons (sizeof (struct PingMessage)); | ||
1126 | pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING); | ||
1127 | pm->iv_seed = | ||
1128 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX); | ||
1129 | derive_iv (&iv, &n->encrypt_key, pm->iv_seed, &n->peer); | ||
1130 | pp.challenge = n->ping_challenge; | ||
1131 | pp.target = n->peer; | ||
1132 | #if DEBUG_HANDSHAKE | ||
1133 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1134 | "Encrypting `%s' and `%s' messages with challenge %u for `%4s' using key %u, IV %u (salt %u).\n", | ||
1135 | "SET_KEY", "PING", (unsigned int) n->ping_challenge, | ||
1136 | GNUNET_i2s (&n->peer), (unsigned int) n->encrypt_key.crc32, | ||
1137 | GNUNET_CRYPTO_crc32_n (&iv, sizeof (iv)), pm->iv_seed); | ||
1138 | #endif | ||
1139 | do_encrypt (n, &iv, &pp.target, &pm->target, | ||
1140 | sizeof (struct PingMessage) - ((void *) &pm->target - | ||
1141 | (void *) pm)); | ||
1142 | GNUNET_STATISTICS_update (stats, | ||
1143 | gettext_noop | ||
1144 | ("# SET_KEY and PING messages created"), 1, | ||
1145 | GNUNET_NO); | ||
1146 | #if DEBUG_CORE | ||
1147 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1148 | "Have %llu ms left for `%s' transmission.\n", | ||
1149 | (unsigned long long) | ||
1150 | GNUNET_TIME_absolute_get_remaining (me->deadline).rel_value, | ||
1151 | "SET_KEY"); | ||
1152 | #endif | ||
1153 | trigger_processing: | ||
1154 | /* trigger queue processing */ | ||
1155 | process_encrypted_neighbour_queue (n); | ||
1156 | if ((n->status != PEER_STATE_KEY_CONFIRMED) && | ||
1157 | (GNUNET_SCHEDULER_NO_TASK == n->retry_set_key_task)) | ||
1158 | n->retry_set_key_task = | ||
1159 | GNUNET_SCHEDULER_add_delayed (n->set_key_retry_frequency, | ||
1160 | &set_key_retry_task, n); | ||
1161 | } | ||
1162 | |||
1163 | |||
1164 | /** | ||
1165 | * We received a SET_KEY message. Validate and update | ||
1166 | * our key material and status. | ||
1167 | * | ||
1168 | * @param n the neighbour from which we received message m | ||
1169 | * @param m the set key message we received | ||
1170 | * @param ats performance data | ||
1171 | * @param ats_count number of entries in ats (excluding 0-termination) | ||
1172 | */ | ||
1173 | static void | ||
1174 | handle_set_key (struct Neighbour *n, const struct SetKeyMessage *m, | ||
1175 | const struct GNUNET_TRANSPORT_ATS_Information *ats, | ||
1176 | uint32_t ats_count); | ||
1177 | |||
1178 | |||
1179 | |||
1180 | /** | ||
1181 | * PEERINFO is giving us a HELLO for a peer. Add the public key to | ||
1182 | * the neighbour's struct and retry handling the set_key message. Or, | ||
1183 | * if we did not get a HELLO, just free the set key message. | ||
1184 | * | ||
1185 | * @param cls pointer to the set key message | ||
1186 | * @param peer the peer for which this is the HELLO | ||
1187 | * @param hello HELLO message of that peer | ||
1188 | * @param err_msg NULL if successful, otherwise contains error message | ||
1189 | */ | ||
1190 | static void | ||
1191 | process_hello_retry_handle_set_key (void *cls, | ||
1192 | const struct GNUNET_PeerIdentity *peer, | ||
1193 | const struct GNUNET_HELLO_Message *hello, | ||
1194 | const char *err_msg) | ||
1195 | { | ||
1196 | struct Neighbour *n = cls; | ||
1197 | struct SetKeyMessage *sm = n->skm; | ||
1198 | |||
1199 | if (err_msg != NULL) | ||
1200 | { | ||
1201 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1202 | _("Error in communication with PEERINFO service\n")); | ||
1203 | /* return; */ | ||
1204 | } | ||
1205 | |||
1206 | if (peer == NULL) | ||
1207 | { | ||
1208 | n->skm = NULL; | ||
1209 | n->pitr = NULL; | ||
1210 | if (n->public_key != NULL) | ||
1211 | { | ||
1212 | #if DEBUG_CORE | ||
1213 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1214 | "Received `%s' for `%4s', continuing processing of `%s' message.\n", | ||
1215 | "HELLO", GNUNET_i2s (&n->peer), "SET_KEY"); | ||
1216 | #endif | ||
1217 | handle_set_key (n, sm, NULL, 0); | ||
1218 | } | ||
1219 | else | ||
1220 | { | ||
1221 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1222 | _ | ||
1223 | ("Ignoring `%s' message due to lack of public key for peer `%4s' (failed to obtain one).\n"), | ||
1224 | "SET_KEY", GNUNET_i2s (&n->peer)); | ||
1225 | } | ||
1226 | GNUNET_free (sm); | ||
1227 | return; | 963 | return; |
1228 | } | 964 | } |
1229 | if (n->public_key != NULL) | ||
1230 | return; /* multiple HELLOs match!? */ | ||
1231 | n->public_key = | ||
1232 | GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); | ||
1233 | if (GNUNET_OK != GNUNET_HELLO_get_key (hello, n->public_key)) | ||
1234 | { | ||
1235 | GNUNET_break_op (0); | ||
1236 | GNUNET_free (n->public_key); | ||
1237 | n->public_key = NULL; | ||
1238 | } | ||
1239 | } | ||
1240 | |||
1241 | |||
1242 | 965 | ||
1243 | /** | 966 | /* always update sender status in SET KEY message */ |
1244 | * Task that will retry "send_key" if our previous attempt failed | 967 | kx->skm.sender_status = htonl ((int32_t) kx->status); |
1245 | * to yield a PONG. | ||
1246 | */ | ||
1247 | static void | ||
1248 | set_key_retry_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1249 | { | ||
1250 | struct Neighbour *n = cls; | ||
1251 | 968 | ||
1252 | #if DEBUG_CORE | 969 | GDS_NEIGHBOURS_transmit (&kx->peer, |
1253 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Retrying key transmission to `%4s'\n", | 970 | &kx->skm.header, |
1254 | GNUNET_i2s (&n->peer)); | 971 | kx->set_key_retry_frequency); |
1255 | #endif | 972 | GDS_NEIGHBOURS_transmit (&kx->peer, |
1256 | n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK; | 973 | &kx->ping.header, |
1257 | n->set_key_retry_frequency = | 974 | kx->set_key_retry_frequency); |
1258 | GNUNET_TIME_relative_multiply (n->set_key_retry_frequency, 2); | 975 | kx->retry_set_key_task = |
1259 | send_key (n); | 976 | GNUNET_SCHEDULER_add_delayed (kx->set_key_retry_frequency, |
977 | &set_key_retry_task, kx); | ||
1260 | } | 978 | } |
1261 | 979 | ||
1262 | 980 | ||
@@ -1264,71 +982,53 @@ set_key_retry_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1264 | * Encrypt and transmit a message with the given payload. | 982 | * Encrypt and transmit a message with the given payload. |
1265 | * | 983 | * |
1266 | * @param kx key exchange context | 984 | * @param kx key exchange context |
985 | * @param bw_in bandwidth limit to transmit to the other peer; | ||
986 | * the other peer shall not send us more than the | ||
987 | * given rate | ||
1267 | * @param payload payload of the message | 988 | * @param payload payload of the message |
1268 | * @param payload_size number of bytes in 'payload' | 989 | * @param payload_size number of bytes in 'payload' |
1269 | */ | 990 | */ |
1270 | void | 991 | void |
1271 | GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx, | 992 | GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx, |
993 | struct GNUNET_BANDWIDTH_Value32NBO bw_in, | ||
1272 | const void *payload, | 994 | const void *payload, |
1273 | size_t payload_size) | 995 | size_t payload_size) |
1274 | { | 996 | { |
1275 | char pbuf[GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE + sizeof (struct EncryptedMessage)]; /* plaintext */ | 997 | size_t used = payload_size + sizeof (struct EncryptedMessage); |
1276 | size_t used; | 998 | char pbuf[used]; /* plaintext */ |
999 | char cbuf[used]; /* ciphertext */ | ||
1277 | struct EncryptedMessage *em; /* encrypted message */ | 1000 | struct EncryptedMessage *em; /* encrypted message */ |
1278 | struct EncryptedMessage *ph; /* plaintext header */ | 1001 | struct EncryptedMessage *ph; /* plaintext header */ |
1279 | struct MessageEntry *me; | ||
1280 | unsigned int priority; | ||
1281 | struct GNUNET_TIME_Absolute deadline; | ||
1282 | struct GNUNET_TIME_Relative retry_time; | ||
1283 | struct GNUNET_CRYPTO_AesInitializationVector iv; | 1002 | struct GNUNET_CRYPTO_AesInitializationVector iv; |
1284 | struct GNUNET_CRYPTO_AuthKey auth_key; | 1003 | struct GNUNET_CRYPTO_AuthKey auth_key; |
1285 | 1004 | ||
1286 | #if DEBUG_CORE_QUOTA | 1005 | #if DEBUG_CORE_QUOTA |
1287 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1006 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1288 | "Sending %u b/s as new limit to peer `%4s'\n", | 1007 | "Sending %u b/s as new limit to peer `%4s'\n", |
1289 | (unsigned int) ntohl (n->bw_in.value__), GNUNET_i2s (&n->peer)); | 1008 | (unsigned int) ntohl (bw_in.value__), |
1009 | GNUNET_i2s (&kx->peer)); | ||
1290 | #endif | 1010 | #endif |
1011 | ph = (struct EncryptedMessage*) pbuf; | ||
1291 | ph->iv_seed = | 1012 | ph->iv_seed = |
1292 | htonl (GNUNET_CRYPTO_random_u32 | 1013 | htonl (GNUNET_CRYPTO_random_u32 |
1293 | (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX)); | 1014 | (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX)); |
1294 | ph->sequence_number = htonl (++n->last_sequence_number_sent); | 1015 | ph->sequence_number = htonl (++kx->last_sequence_number_sent); |
1295 | ph->inbound_bw_limit = n->bw_in; | 1016 | ph->inbound_bw_limit = bw_in; |
1296 | ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); | 1017 | ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); |
1018 | memcpy (&ph[1], payload, payload_size); | ||
1297 | 1019 | ||
1298 | /* setup encryption message header */ | 1020 | em = (struct EncryptedMessage *) cbuf; |
1299 | me = GNUNET_malloc (sizeof (struct MessageEntry) + used); | ||
1300 | me->deadline = deadline; | ||
1301 | me->priority = priority; | ||
1302 | me->size = used; | ||
1303 | em = (struct EncryptedMessage *) &me[1]; | ||
1304 | em->header.size = htons (used); | 1021 | em->header.size = htons (used); |
1305 | em->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE); | 1022 | em->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE); |
1306 | em->iv_seed = ph->iv_seed; | 1023 | em->iv_seed = ph->iv_seed; |
1307 | derive_iv (&iv, &n->encrypt_key, ph->iv_seed, &n->peer); | 1024 | derive_iv (&iv, &kx->encrypt_key, ph->iv_seed, &kx->peer); |
1308 | /* encrypt */ | ||
1309 | #if DEBUG_HANDSHAKE | ||
1310 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1311 | "Encrypting %u bytes of plaintext messages for `%4s' for transmission in %llums.\n", | ||
1312 | (unsigned int) used - ENCRYPTED_HEADER_SIZE, | ||
1313 | GNUNET_i2s (&n->peer), | ||
1314 | (unsigned long long) | ||
1315 | GNUNET_TIME_absolute_get_remaining (deadline).rel_value); | ||
1316 | #endif | ||
1317 | GNUNET_assert (GNUNET_OK == | 1025 | GNUNET_assert (GNUNET_OK == |
1318 | do_encrypt (n, &iv, &ph->sequence_number, &em->sequence_number, | 1026 | do_encrypt (kx, &iv, &ph->sequence_number, &em->sequence_number, |
1319 | used - ENCRYPTED_HEADER_SIZE)); | 1027 | used - ENCRYPTED_HEADER_SIZE)); |
1320 | derive_auth_key (&auth_key, &n->encrypt_key, ph->iv_seed, | 1028 | derive_auth_key (&auth_key, &kx->encrypt_key, ph->iv_seed, |
1321 | n->encrypt_key_created); | 1029 | kx->encrypt_key_created); |
1322 | GNUNET_CRYPTO_hmac (&auth_key, &em->sequence_number, | 1030 | GNUNET_CRYPTO_hmac (&auth_key, &em->sequence_number, |
1323 | used - ENCRYPTED_HEADER_SIZE, &em->hmac); | 1031 | used - ENCRYPTED_HEADER_SIZE, &em->hmac); |
1324 | #if DEBUG_HANDSHAKE | ||
1325 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1326 | "Authenticated %u bytes of ciphertext %u: `%s'\n", | ||
1327 | used - ENCRYPTED_HEADER_SIZE, | ||
1328 | GNUNET_CRYPTO_crc32_n (&em->sequence_number, | ||
1329 | used - ENCRYPTED_HEADER_SIZE), | ||
1330 | GNUNET_h2s (&em->hmac)); | ||
1331 | #endif | ||
1332 | GDS_NEIGHBOURS_transmit (&kx->peer, | 1032 | GDS_NEIGHBOURS_transmit (&kx->peer, |
1333 | &em->header, | 1033 | &em->header, |
1334 | GNUNET_TIME_UNIT_FOREVER_REL); | 1034 | GNUNET_TIME_UNIT_FOREVER_REL); |
@@ -1336,19 +1036,39 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx, | |||
1336 | 1036 | ||
1337 | 1037 | ||
1338 | /** | 1038 | /** |
1039 | * We've seen a valid message from the other peer. | ||
1040 | * Update the time when the session would time out | ||
1041 | * and delay sending our keep alive message further. | ||
1042 | * | ||
1043 | * @param kx key exchange where we saw activity | ||
1044 | */ | ||
1045 | static void | ||
1046 | update_timeout (struct GSC_KeyExchangeInfo *kx) | ||
1047 | { | ||
1048 | kx->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); | ||
1049 | if (kx->keep_alive_task != GNUNET_SCHEDULER_NO_TASK) | ||
1050 | GNUNET_SCHEDULER_cancel (n->keep_alive_task); | ||
1051 | kx->keep_alive_task = | ||
1052 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide | ||
1053 | (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
1054 | 2), &send_keep_alive, kx); | ||
1055 | } | ||
1056 | |||
1057 | |||
1058 | /** | ||
1339 | * We received an encrypted message. Decrypt, validate and | 1059 | * We received an encrypted message. Decrypt, validate and |
1340 | * pass on to the appropriate clients. | 1060 | * pass on to the appropriate clients. |
1341 | * | 1061 | * |
1342 | * @param n target of the message | 1062 | * @param n target of the message |
1343 | * @param m encrypted message | 1063 | * @param m encrypted message |
1344 | * @param ats performance data | 1064 | * @param atsi performance data |
1345 | * @param ats_count number of entries in ats (excluding 0-termination) | 1065 | * @param atsi_count number of entries in ats (excluding 0-termination) |
1346 | */ | 1066 | */ |
1347 | void | 1067 | void |
1348 | GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *n, | 1068 | GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *n, |
1349 | const struct GNUNET_MessageHeader *msg, | 1069 | const struct GNUNET_MessageHeader *msg, |
1350 | const struct GNUNET_TRANSPORT_ATS_Information *ats, | 1070 | const struct GNUNET_TRANSPORT_ATS_Information *atsi, |
1351 | uint32_t ats_count) | 1071 | uint32_t atsi_count) |
1352 | { | 1072 | { |
1353 | const struct EncryptedMessage *m; | 1073 | const struct EncryptedMessage *m; |
1354 | char buf[size]; | 1074 | char buf[size]; |
@@ -1362,86 +1082,68 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *n, | |||
1362 | 1082 | ||
1363 | if (size < | 1083 | if (size < |
1364 | sizeof (struct EncryptedMessage) + sizeof (struct GNUNET_MessageHeader)) | 1084 | sizeof (struct EncryptedMessage) + sizeof (struct GNUNET_MessageHeader)) |
1365 | { | 1085 | { |
1366 | GNUNET_break_op (0); | 1086 | GNUNET_break_op (0); |
1367 | return; | 1087 | return; |
1368 | } | 1088 | } |
1369 | m = (const struct EncryptedMessage*) msg; | 1089 | m = (const struct EncryptedMessage*) msg; |
1370 | #if FIXME | 1090 | if ( (kx->status != KX_STATE_KEY_RECEIVED) && |
1371 | if ((n->status != PEER_STATE_KEY_RECEIVED) && | 1091 | (kx->status != KX_STATE_UP) ) |
1372 | (n->status != PEER_STATE_KEY_CONFIRMED)) | 1092 | { |
1373 | { | 1093 | GNUNET_STATISTICS_update (stats, |
1374 | GNUNET_STATISTICS_update (stats, | 1094 | gettext_noop |
1375 | gettext_noop | 1095 | ("# failed to decrypt message (no session key)"), |
1376 | ("# failed to decrypt message (no session key)"), | 1096 | 1, GNUNET_NO); |
1377 | 1, GNUNET_NO); | 1097 | return; |
1378 | send_key (n); | 1098 | } |
1379 | return; | ||
1380 | } | ||
1381 | #endif | ||
1382 | |||
1383 | #if DEBUG_CORE | ||
1384 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1385 | "Core service receives `%s' request from `%4s'.\n", | ||
1386 | "ENCRYPTED_MESSAGE", GNUNET_i2s (&n->peer)); | ||
1387 | #endif | ||
1388 | /* validate hash */ | 1099 | /* validate hash */ |
1389 | derive_auth_key (&auth_key, &n->decrypt_key, m->iv_seed, | 1100 | derive_auth_key (&auth_key, &kx->decrypt_key, m->iv_seed, |
1390 | n->decrypt_key_created); | 1101 | kx->decrypt_key_created); |
1391 | GNUNET_CRYPTO_hmac (&auth_key, &m->sequence_number, | 1102 | GNUNET_CRYPTO_hmac (&auth_key, &m->sequence_number, |
1392 | size - ENCRYPTED_HEADER_SIZE, &ph); | 1103 | size - ENCRYPTED_HEADER_SIZE, &ph); |
1393 | #if DEBUG_HANDSHAKE | ||
1394 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1395 | "Re-Authenticated %u bytes of ciphertext (`%u'): `%s'\n", | ||
1396 | (unsigned int) size - ENCRYPTED_HEADER_SIZE, | ||
1397 | GNUNET_CRYPTO_crc32_n (&m->sequence_number, | ||
1398 | size - ENCRYPTED_HEADER_SIZE), | ||
1399 | GNUNET_h2s (&ph)); | ||
1400 | #endif | ||
1401 | |||
1402 | if (0 != memcmp (&ph, &m->hmac, sizeof (GNUNET_HashCode))) | 1104 | if (0 != memcmp (&ph, &m->hmac, sizeof (GNUNET_HashCode))) |
1403 | { | 1105 | { |
1404 | /* checksum failed */ | 1106 | /* checksum failed */ |
1405 | GNUNET_break_op (0); | 1107 | GNUNET_break_op (0); |
1406 | return; | 1108 | return; |
1407 | } | 1109 | } |
1408 | derive_iv (&iv, &n->decrypt_key, m->iv_seed, &my_identity); | 1110 | derive_iv (&iv, &kx->decrypt_key, m->iv_seed, &GSC_my_identity); |
1409 | /* decrypt */ | 1111 | /* decrypt */ |
1410 | if (GNUNET_OK != | 1112 | if (GNUNET_OK != |
1411 | do_decrypt (n, &iv, &m->sequence_number, &buf[ENCRYPTED_HEADER_SIZE], | 1113 | do_decrypt (kx, &iv, &m->sequence_number, &buf[ENCRYPTED_HEADER_SIZE], |
1412 | size - ENCRYPTED_HEADER_SIZE)) | 1114 | size - ENCRYPTED_HEADER_SIZE)) |
1413 | return; | 1115 | return; |
1414 | pt = (struct EncryptedMessage *) buf; | 1116 | pt = (struct EncryptedMessage *) buf; |
1415 | 1117 | ||
1416 | /* validate sequence number */ | 1118 | /* validate sequence number */ |
1417 | snum = ntohl (pt->sequence_number); | 1119 | snum = ntohl (pt->sequence_number); |
1418 | if (n->last_sequence_number_received == snum) | 1120 | if (kx->last_sequence_number_received == snum) |
1419 | { | 1121 | { |
1420 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1122 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1421 | "Received duplicate message, ignoring.\n"); | 1123 | "Received duplicate message, ignoring.\n"); |
1422 | /* duplicate, ignore */ | 1124 | /* duplicate, ignore */ |
1423 | GNUNET_STATISTICS_update (stats, | 1125 | GNUNET_STATISTICS_update (GSC_stats, |
1424 | gettext_noop ("# bytes dropped (duplicates)"), | 1126 | gettext_noop ("# bytes dropped (duplicates)"), |
1425 | size, GNUNET_NO); | 1127 | size, GNUNET_NO); |
1426 | return; | 1128 | return; |
1427 | } | 1129 | } |
1428 | if ((n->last_sequence_number_received > snum) && | 1130 | if ((kx->last_sequence_number_received > snum) && |
1429 | (n->last_sequence_number_received - snum > 32)) | 1131 | (kx->last_sequence_number_received - snum > 32)) |
1430 | { | 1132 | { |
1431 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1133 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1432 | "Received ancient out of sequence message, ignoring.\n"); | 1134 | "Received ancient out of sequence message, ignoring.\n"); |
1433 | /* ancient out of sequence, ignore */ | 1135 | /* ancient out of sequence, ignore */ |
1434 | GNUNET_STATISTICS_update (stats, | 1136 | GNUNET_STATISTICS_update (GSC_stats, |
1435 | gettext_noop | 1137 | gettext_noop |
1436 | ("# bytes dropped (out of sequence)"), size, | 1138 | ("# bytes dropped (out of sequence)"), size, |
1437 | GNUNET_NO); | 1139 | GNUNET_NO); |
1438 | return; | 1140 | return; |
1439 | } | 1141 | } |
1440 | if (n->last_sequence_number_received > snum) | 1142 | if (kx->last_sequence_number_received > snum) |
1441 | { | 1143 | { |
1442 | unsigned int rotbit = 1 << (n->last_sequence_number_received - snum - 1); | 1144 | unsigned int rotbit = 1 << (kx->last_sequence_number_received - snum - 1); |
1443 | 1145 | ||
1444 | if ((n->last_packets_bitmap & rotbit) != 0) | 1146 | if ((kx->last_packets_bitmap & rotbit) != 0) |
1445 | { | 1147 | { |
1446 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1148 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1447 | "Received duplicate message, ignoring.\n"); | 1149 | "Received duplicate message, ignoring.\n"); |
@@ -1451,17 +1153,17 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *n, | |||
1451 | /* duplicate, ignore */ | 1153 | /* duplicate, ignore */ |
1452 | return; | 1154 | return; |
1453 | } | 1155 | } |
1454 | n->last_packets_bitmap |= rotbit; | 1156 | kx->last_packets_bitmap |= rotbit; |
1455 | } | 1157 | } |
1456 | if (n->last_sequence_number_received < snum) | 1158 | if (kx->last_sequence_number_received < snum) |
1457 | { | 1159 | { |
1458 | int shift = (snum - n->last_sequence_number_received); | 1160 | unsigned int shift = (snum - kx->last_sequence_number_received); |
1459 | 1161 | ||
1460 | if (shift >= 8 * sizeof (n->last_packets_bitmap)) | 1162 | if (shift >= 8 * sizeof (kx->last_packets_bitmap)) |
1461 | n->last_packets_bitmap = 0; | 1163 | kx->last_packets_bitmap = 0; |
1462 | else | 1164 | else |
1463 | n->last_packets_bitmap <<= shift; | 1165 | kx->last_packets_bitmap <<= shift; |
1464 | n->last_sequence_number_received = snum; | 1166 | kx->last_sequence_number_received = snum; |
1465 | } | 1167 | } |
1466 | 1168 | ||
1467 | /* check timestamp */ | 1169 | /* check timestamp */ |
@@ -1480,104 +1182,49 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *n, | |||
1480 | } | 1182 | } |
1481 | 1183 | ||
1482 | /* process decrypted message(s) */ | 1184 | /* process decrypted message(s) */ |
1483 | if (n->bw_out_external_limit.value__ != pt->inbound_bw_limit.value__) | 1185 | update_timeout (kx); |
1484 | { | 1186 | GSC_SESSIONS_update (&kx->peer, |
1485 | #if DEBUG_CORE_SET_QUOTA | 1187 | pt->inbound_bw_limit, |
1486 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1188 | atsi, atsi_count); // FIXME: does 'SESSIONS' need atsi!? |
1487 | "Received %u b/s as new inbound limit for peer `%4s'\n", | ||
1488 | (unsigned int) ntohl (pt->inbound_bw_limit.value__), | ||
1489 | GNUNET_i2s (&n->peer)); | ||
1490 | #endif | ||
1491 | n->bw_out_external_limit = pt->inbound_bw_limit; | ||
1492 | n->bw_out = | ||
1493 | GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit, | ||
1494 | n->bw_out_internal_limit); | ||
1495 | GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window, | ||
1496 | n->bw_out); | ||
1497 | GNUNET_TRANSPORT_set_quota (transport, &n->peer, n->bw_in, n->bw_out); | ||
1498 | } | ||
1499 | n->last_activity = GNUNET_TIME_absolute_get (); | ||
1500 | if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK) | ||
1501 | GNUNET_SCHEDULER_cancel (n->keep_alive_task); | ||
1502 | n->keep_alive_task = | ||
1503 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide | ||
1504 | (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
1505 | 2), &send_keep_alive, n); | ||
1506 | GNUNET_STATISTICS_update (stats, | 1189 | GNUNET_STATISTICS_update (stats, |
1507 | gettext_noop ("# bytes of payload decrypted"), | 1190 | gettext_noop ("# bytes of payload decrypted"), |
1508 | size - sizeof (struct EncryptedMessage), GNUNET_NO); | 1191 | size - sizeof (struct EncryptedMessage), GNUNET_NO); |
1509 | handle_peer_status_change (n); | ||
1510 | update_neighbour_performance (n, ats, ats_count); | ||
1511 | if (GNUNET_OK != | 1192 | if (GNUNET_OK != |
1512 | GNUNET_SERVER_mst_receive (mst, n, &buf[sizeof (struct EncryptedMessage)], | 1193 | GNUNET_SERVER_mst_receive (mst, kx, &buf[sizeof (struct EncryptedMessage)], |
1513 | size - sizeof (struct EncryptedMessage), | 1194 | size - sizeof (struct EncryptedMessage), |
1514 | GNUNET_YES, GNUNET_NO)) | 1195 | GNUNET_YES, GNUNET_NO)) |
1515 | GNUNET_break_op (0); | 1196 | GNUNET_break_op (0); |
1516 | } | 1197 | } |
1517 | 1198 | ||
1518 | 1199 | ||
1200 | |||
1201 | |||
1519 | /** | 1202 | /** |
1520 | * Task triggered when a neighbour entry is about to time out | 1203 | * Deliver P2P message to interested clients. |
1521 | * (and we should prevent this by sending a PING). | ||
1522 | * | 1204 | * |
1523 | * @param cls the 'struct Neighbour' | 1205 | * @param cls always NULL |
1524 | * @param tc scheduler context (not used) | 1206 | * @param client who sent us the message (struct GSC_KeyExchangeInfo) |
1207 | * @param m the message | ||
1525 | */ | 1208 | */ |
1526 | static void | 1209 | static void |
1527 | send_keep_alive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 1210 | deliver_message (void *cls, void *client, const struct GNUNET_MessageHeader *m) |
1528 | { | 1211 | { |
1529 | struct Neighbour *n = cls; | 1212 | struct GSC_KeyExchangeInfo *kx = client; |
1530 | struct GNUNET_TIME_Relative retry; | 1213 | |
1531 | struct GNUNET_TIME_Relative left; | 1214 | // FIXME (need to check stuff, need ATSI, etc.) |
1532 | struct MessageEntry *me; | 1215 | // FIXME: does clients work properly if never called with option 'NOTHING'!? |
1533 | struct PingMessage pp; | 1216 | GSC_CLIENTS_deliver_message (&kx->peer, |
1534 | struct PingMessage *pm; | 1217 | NULL, 0, // kx->atsi... |
1535 | struct GNUNET_CRYPTO_AesInitializationVector iv; | 1218 | m, |
1536 | 1219 | ntohs (m->size), | |
1537 | n->keep_alive_task = GNUNET_SCHEDULER_NO_TASK; | 1220 | GNUNET_CORE_OPTION_SEND_FULL_INBOUND); |
1538 | /* send PING */ | 1221 | GSC_CLIENTS_deliver_message (&kx->peer, |
1539 | me = GNUNET_malloc (sizeof (struct MessageEntry) + | 1222 | NULL, 0, // kx->atsi... |
1540 | sizeof (struct PingMessage)); | 1223 | m, |
1541 | me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PING_DELAY); | 1224 | sizeof (struct GNUNET_MessageHeader), |
1542 | me->priority = PING_PRIORITY; | 1225 | GNUNET_CORE_OPTION_SEND_HDR_INBOUND); |
1543 | me->size = sizeof (struct PingMessage); | ||
1544 | GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head, n->encrypted_tail, | ||
1545 | n->encrypted_tail, me); | ||
1546 | pm = (struct PingMessage *) &me[1]; | ||
1547 | pm->header.size = htons (sizeof (struct PingMessage)); | ||
1548 | pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING); | ||
1549 | pm->iv_seed = | ||
1550 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX); | ||
1551 | derive_iv (&iv, &n->encrypt_key, pm->iv_seed, &n->peer); | ||
1552 | pp.challenge = n->ping_challenge; | ||
1553 | pp.target = n->peer; | ||
1554 | #if DEBUG_HANDSHAKE | ||
1555 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1556 | "Encrypting `%s' message with challenge %u for `%4s' using key %u, IV %u (salt %u).\n", | ||
1557 | "PING", (unsigned int) n->ping_challenge, GNUNET_i2s (&n->peer), | ||
1558 | (unsigned int) n->encrypt_key.crc32, GNUNET_CRYPTO_crc32_n (&iv, | ||
1559 | sizeof | ||
1560 | (iv)), | ||
1561 | pm->iv_seed); | ||
1562 | #endif | ||
1563 | do_encrypt (n, &iv, &pp.target, &pm->target, | ||
1564 | sizeof (struct PingMessage) - ((void *) &pm->target - | ||
1565 | (void *) pm)); | ||
1566 | process_encrypted_neighbour_queue (n); | ||
1567 | /* reschedule PING job */ | ||
1568 | left = GNUNET_TIME_absolute_get_remaining (get_neighbour_timeout (n)); | ||
1569 | retry = | ||
1570 | GNUNET_TIME_relative_max (GNUNET_TIME_relative_divide (left, 2), | ||
1571 | MIN_PING_FREQUENCY); | ||
1572 | n->keep_alive_task = | ||
1573 | GNUNET_SCHEDULER_add_delayed (retry, &send_keep_alive, n); | ||
1574 | |||
1575 | } | 1226 | } |
1576 | 1227 | ||
1577 | |||
1578 | |||
1579 | |||
1580 | |||
1581 | /** | 1228 | /** |
1582 | * Initialize KX subsystem. | 1229 | * Initialize KX subsystem. |
1583 | * | 1230 | * |
@@ -1616,6 +1263,7 @@ GSC_KX_init () | |||
1616 | my_private_key = NULL; | 1263 | my_private_key = NULL; |
1617 | return GNUNET_SYSERR; | 1264 | return GNUNET_SYSERR; |
1618 | } | 1265 | } |
1266 | mst = GNUNET_SERVER_mst_create (&deliver_message, NULL); | ||
1619 | return GNUNET_OK; | 1267 | return GNUNET_OK; |
1620 | } | 1268 | } |
1621 | 1269 | ||
@@ -1632,10 +1280,15 @@ GSC_KX_done () | |||
1632 | my_private_key = NULL; | 1280 | my_private_key = NULL; |
1633 | } | 1281 | } |
1634 | if (peerinfo != NULL) | 1282 | if (peerinfo != NULL) |
1635 | { | 1283 | { |
1636 | GNUNET_PEERINFO_disconnect (peerinfo); | 1284 | GNUNET_PEERINFO_disconnect (peerinfo); |
1637 | peerinfo = NULL; | 1285 | peerinfo = NULL; |
1638 | } | 1286 | } |
1287 | if (mst != NULL) | ||
1288 | { | ||
1289 | GNUNET_SERVER_mst_destroy (mst); | ||
1290 | mst = NULL; | ||
1291 | } | ||
1639 | } | 1292 | } |
1640 | 1293 | ||
1641 | /* end of gnunet-service-core_kx.c */ | 1294 | /* end of gnunet-service-core_kx.c */ |
diff --git a/src/core/gnunet-service-core_kx.h b/src/core/gnunet-service-core_kx.h index 104aed5e4..071665a19 100644 --- a/src/core/gnunet-service-core_kx.h +++ b/src/core/gnunet-service-core_kx.h | |||
@@ -30,16 +30,76 @@ | |||
30 | 30 | ||
31 | 31 | ||
32 | /** | 32 | /** |
33 | * State machine for our P2P encryption handshake. Everyone starts in | ||
34 | * "DOWN", if we receive the other peer's key (other peer initiated) | ||
35 | * we start in state RECEIVED (since we will immediately send our | ||
36 | * own); otherwise we start in SENT. If we get back a PONG from | ||
37 | * within either state, we move up to CONFIRMED (the PONG will always | ||
38 | * be sent back encrypted with the key we sent to the other peer). | ||
39 | */ | ||
40 | enum KxStateMachine | ||
41 | { | ||
42 | /** | ||
43 | * No handshake yet. | ||
44 | */ | ||
45 | KX_STATE_DOWN, | ||
46 | |||
47 | /** | ||
48 | * We've sent our session key. | ||
49 | */ | ||
50 | KX_STATE_KEY_SENT, | ||
51 | |||
52 | /** | ||
53 | * We've received the other peers session key. | ||
54 | */ | ||
55 | KX_STATE_KEY_RECEIVED, | ||
56 | |||
57 | /** | ||
58 | * The other peer has confirmed our session key with a message | ||
59 | * encrypted with his session key (which we got). Key exchange | ||
60 | * is done. | ||
61 | */ | ||
62 | KX_STATE_UP | ||
63 | }; | ||
64 | |||
65 | |||
66 | /** | ||
33 | * Information about the status of a key exchange with another peer. | 67 | * Information about the status of a key exchange with another peer. |
34 | */ | 68 | */ |
35 | struct GSC_KeyExchangeInfo | 69 | struct GSC_KeyExchangeInfo |
36 | { | 70 | { |
71 | /** | ||
72 | * Identity of the peer. | ||
73 | */ | ||
74 | struct GNUNET_PeerIdentity peer; | ||
37 | 75 | ||
38 | /** | 76 | /** |
39 | * SetKeyMessage to transmit, NULL if we are not currently trying | 77 | * SetKeyMessage to transmit (initialized the first |
40 | * to send one. | 78 | * time our status goes past 'KX_STATE_KEY_SENT'). |
41 | */ | 79 | */ |
42 | struct SetKeyMessage *skm; | 80 | struct SetKeyMessage skm; |
81 | |||
82 | /** | ||
83 | * PING message we transmit to the other peer. | ||
84 | */ | ||
85 | struct PingMessage ping; | ||
86 | |||
87 | /** | ||
88 | * SetKeyMessage we received and did not process yet. | ||
89 | */ | ||
90 | struct SetKeyMessage *skm_received; | ||
91 | |||
92 | /** | ||
93 | * PING message we received from the other peer and | ||
94 | * did not process yet (or NULL). | ||
95 | */ | ||
96 | struct PingMessage *ping_received; | ||
97 | |||
98 | /** | ||
99 | * PONG message we received from the other peer and | ||
100 | * did not process yet (or NULL). | ||
101 | */ | ||
102 | struct PongMessage *pong_received; | ||
43 | 103 | ||
44 | /** | 104 | /** |
45 | * Non-NULL if we are currently looking up HELLOs for this peer. | 105 | * Non-NULL if we are currently looking up HELLOs for this peer. |
@@ -53,13 +113,6 @@ struct GSC_KeyExchangeInfo | |||
53 | struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key; | 113 | struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key; |
54 | 114 | ||
55 | /** | 115 | /** |
56 | * We received a PING message before we got the "public_key" | ||
57 | * (or the SET_KEY). We keep it here until we have a key | ||
58 | * to decrypt it. NULL if no PING is pending. | ||
59 | */ | ||
60 | struct PingMessage *pending_ping; | ||
61 | |||
62 | /** | ||
63 | * We received a PONG message before we got the "public_key" | 116 | * We received a PONG message before we got the "public_key" |
64 | * (or the SET_KEY). We keep it here until we have a key | 117 | * (or the SET_KEY). We keep it here until we have a key |
65 | * to decrypt it. NULL if no PONG is pending. | 118 | * to decrypt it. NULL if no PONG is pending. |
@@ -89,6 +142,11 @@ struct GSC_KeyExchangeInfo | |||
89 | struct GNUNET_TIME_Absolute decrypt_key_created; | 142 | struct GNUNET_TIME_Absolute decrypt_key_created; |
90 | 143 | ||
91 | /** | 144 | /** |
145 | * When should the session time out (if there are no PONGs)? | ||
146 | */ | ||
147 | struct GNUNET_TIME_Absolute timeout; | ||
148 | |||
149 | /** | ||
92 | * At what frequency are we currently re-trying SET_KEY messages? | 150 | * At what frequency are we currently re-trying SET_KEY messages? |
93 | */ | 151 | */ |
94 | struct GNUNET_TIME_Relative set_key_retry_frequency; | 152 | struct GNUNET_TIME_Relative set_key_retry_frequency; |
@@ -111,7 +169,7 @@ struct GSC_KeyExchangeInfo | |||
111 | /** | 169 | /** |
112 | * What is our connection status? | 170 | * What is our connection status? |
113 | */ | 171 | */ |
114 | enum PeerStateMachine status; | 172 | enum KxStateMachine status; |
115 | 173 | ||
116 | }; | 174 | }; |
117 | 175 | ||
@@ -122,14 +180,10 @@ struct GSC_KeyExchangeInfo | |||
122 | * | 180 | * |
123 | * @param kx key exchange status for the corresponding peer | 181 | * @param kx key exchange status for the corresponding peer |
124 | * @param msg the set key message we received | 182 | * @param msg the set key message we received |
125 | * @param ats performance data | ||
126 | * @param ats_count number of entries in ats (excluding 0-termination) | ||
127 | */ | 183 | */ |
128 | void | 184 | void |
129 | GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *n, | 185 | GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *kx, |
130 | const struct GNUNET_MessageHandler *msg, | 186 | const struct GNUNET_MessageHandler *msg); |
131 | const struct GNUNET_TRANSPORT_ATS_Information *ats, | ||
132 | uint32_t ats_count); | ||
133 | 187 | ||
134 | 188 | ||
135 | /** | 189 | /** |
@@ -138,14 +192,10 @@ GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *n, | |||
138 | * | 192 | * |
139 | * @param kx key exchange status for the corresponding peer | 193 | * @param kx key exchange status for the corresponding peer |
140 | * @param msg the encrypted PING message itself | 194 | * @param msg the encrypted PING message itself |
141 | * @param ats performance data | ||
142 | * @param ats_count number of entries in ats (excluding 0-termination) | ||
143 | */ | 195 | */ |
144 | void | 196 | void |
145 | GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx, | 197 | GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx, |
146 | const struct GNUNET_MessageHeader *msg, | 198 | const struct GNUNET_MessageHeader *msg); |
147 | const struct GNUNET_TRANSPORT_ATS_Information *ats, | ||
148 | uint32_t ats_count); | ||
149 | 199 | ||
150 | 200 | ||
151 | /** | 201 | /** |
@@ -153,25 +203,25 @@ GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx, | |||
153 | * | 203 | * |
154 | * @param kx key exchange status for the corresponding peer | 204 | * @param kx key exchange status for the corresponding peer |
155 | * @param msg the encrypted PONG message itself | 205 | * @param msg the encrypted PONG message itself |
156 | * @param ats performance data | ||
157 | * @param ats_count number of entries in ats (excluding 0-termination) | ||
158 | */ | 206 | */ |
159 | void | 207 | void |
160 | GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx, | 208 | GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx, |
161 | const struct GNUNET_MessageHeader *msg, | 209 | const struct GNUNET_MessageHeader *msg); |
162 | const struct GNUNET_TRANSPORT_ATS_Information *ats, | ||
163 | uint32_t ats_count); | ||
164 | 210 | ||
165 | 211 | ||
166 | /** | 212 | /** |
167 | * Encrypt and transmit a message with the given payload. | 213 | * Encrypt and transmit a message with the given payload. |
168 | * | 214 | * |
169 | * @param kx key exchange context | 215 | * @param kx key exchange context |
216 | * @param bw_in bandwidth limit to transmit to the other peer; | ||
217 | * the other peer shall not send us more than the | ||
218 | * given rate | ||
170 | * @param payload payload of the message | 219 | * @param payload payload of the message |
171 | * @param payload_size number of bytes in 'payload' | 220 | * @param payload_size number of bytes in 'payload' |
172 | */ | 221 | */ |
173 | void | 222 | void |
174 | GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx, | 223 | GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx, |
224 | struct GNUNET_BANDWIDTH_Value32NBO bw_in, | ||
175 | const void *payload, | 225 | const void *payload, |
176 | size_t payload_size); | 226 | size_t payload_size); |
177 | 227 | ||
@@ -182,14 +232,14 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx, | |||
182 | * | 232 | * |
183 | * @param kx key exchange information context | 233 | * @param kx key exchange information context |
184 | * @param msg encrypted message | 234 | * @param msg encrypted message |
185 | * @param ats performance data | 235 | * @param atsi performance data |
186 | * @param ats_count number of entries in ats (excluding 0-termination) | 236 | * @param atsi_count number of entries in ats (excluding 0-termination) |
187 | */ | 237 | */ |
188 | void | 238 | void |
189 | GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx, | 239 | GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx, |
190 | const struct GNUNET_MessageHeader *msg, | 240 | const struct GNUNET_MessageHeader *msg, |
191 | const struct GNUNET_TRANSPORT_ATS_Information *ats, | 241 | const struct GNUNET_TRANSPORT_ATS_Information *atsi, |
192 | uint32_t ats_count); | 242 | uint32_t atsi_count); |
193 | 243 | ||
194 | 244 | ||
195 | /** | 245 | /** |
diff --git a/src/core/gnunet-service-core_neighbours.c b/src/core/gnunet-service-core_neighbours.c index 8a0677c88..d78f696e6 100644 --- a/src/core/gnunet-service-core_neighbours.c +++ b/src/core/gnunet-service-core_neighbours.c | |||
@@ -428,13 +428,13 @@ handle_transport_receive (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
428 | switch (type) | 428 | switch (type) |
429 | { | 429 | { |
430 | case GNUNET_MESSAGE_TYPE_CORE_SET_KEY: | 430 | case GNUNET_MESSAGE_TYPE_CORE_SET_KEY: |
431 | GSC_KX_handle_set_key (n->kxinfo, message, ats, ats_count); | 431 | GSC_KX_handle_set_key (n->kxinfo, message); |
432 | break; | 432 | break; |
433 | case GNUNET_MESSAGE_TYPE_CORE_PING: | 433 | case GNUNET_MESSAGE_TYPE_CORE_PING: |
434 | GSC_KX_handle_ping (n->kxinfo, message, ats, ats_count); | 434 | GSC_KX_handle_ping (n->kxinfo, message); |
435 | break; | 435 | break; |
436 | case GNUNET_MESSAGE_TYPE_CORE_PONG: | 436 | case GNUNET_MESSAGE_TYPE_CORE_PONG: |
437 | GSC_KX_handle_pong (n->kxinfo, message, ats, ats_count); | 437 | GSC_KX_handle_pong (n->kxinfo, message); |
438 | break; | 438 | break; |
439 | case GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE: | 439 | case GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE: |
440 | GSC_KX_handle_encrypted_message (peer, | 440 | GSC_KX_handle_encrypted_message (peer, |
diff --git a/src/core/gnunet-service-core_neighbours.h b/src/core/gnunet-service-core_neighbours.h index 8dad1aafe..36682770e 100644 --- a/src/core/gnunet-service-core_neighbours.h +++ b/src/core/gnunet-service-core_neighbours.h | |||
@@ -41,7 +41,7 @@ | |||
41 | * @param timeout by when should the transmission be done? | 41 | * @param timeout by when should the transmission be done? |
42 | */ | 42 | */ |
43 | void | 43 | void |
44 | GDS_NEIGHBOURS_transmit (const struct GNUNET_PeerIdentity *target, | 44 | GSC_NEIGHBOURS_transmit (const struct GNUNET_PeerIdentity *target, |
45 | const struct GNUNET_MessageHeader *msg, | 45 | const struct GNUNET_MessageHeader *msg, |
46 | struct GNUNET_TIME_Relative timeout); | 46 | struct GNUNET_TIME_Relative timeout); |
47 | 47 | ||
diff --git a/src/core/gnunet-service-core_sessions.c b/src/core/gnunet-service-core_sessions.c index b72a0e0b3..a2b662252 100644 --- a/src/core/gnunet-service-core_sessions.c +++ b/src/core/gnunet-service-core_sessions.c | |||
@@ -1123,11 +1123,7 @@ create_neighbour (const struct GNUNET_PeerIdentity *pid) | |||
1123 | #endif | 1123 | #endif |
1124 | n = GNUNET_malloc (sizeof (struct Neighbour)); | 1124 | n = GNUNET_malloc (sizeof (struct Neighbour)); |
1125 | n->peer = *pid; | 1125 | n->peer = *pid; |
1126 | GNUNET_CRYPTO_aes_create_session_key (&n->encrypt_key); | 1126 | n->last_activity = GNUNET_TIME_absolute_get (); |
1127 | now = GNUNET_TIME_absolute_get (); | ||
1128 | n->encrypt_key_created = now; | ||
1129 | n->last_activity = now; | ||
1130 | n->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY; | ||
1131 | n->bw_in = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT; | 1127 | n->bw_in = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT; |
1132 | n->bw_out = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT; | 1128 | n->bw_out = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT; |
1133 | n->bw_out_internal_limit = GNUNET_BANDWIDTH_value_init (UINT32_MAX); | 1129 | n->bw_out_internal_limit = GNUNET_BANDWIDTH_value_init (UINT32_MAX); |
@@ -1673,7 +1669,118 @@ GSC_SESSIONS_handle_client_request_info (void *cls, struct GNUNET_SERVER_Client | |||
1673 | } | 1669 | } |
1674 | 1670 | ||
1675 | 1671 | ||
1672 | /** | ||
1673 | * Create a session, a key exchange was just completed. | ||
1674 | */ | ||
1675 | void | ||
1676 | GSC_SESSIONS_create (const struct GNUNET_PeerIdentity *peer) | ||
1677 | { | ||
1678 | { | ||
1679 | struct GNUNET_MessageHeader *hdr; | ||
1680 | |||
1681 | hdr = compute_type_map_message (); | ||
1682 | send_type_map_to_neighbour (hdr, &n->peer.hashPubKey, n); | ||
1683 | GNUNET_free (hdr); | ||
1684 | } | ||
1685 | if (n->bw_out_external_limit.value__ != t.inbound_bw_limit.value__) | ||
1686 | { | ||
1687 | n->bw_out_external_limit = t.inbound_bw_limit; | ||
1688 | n->bw_out = | ||
1689 | GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit, | ||
1690 | n->bw_out_internal_limit); | ||
1691 | GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window, | ||
1692 | n->bw_out); | ||
1693 | GNUNET_TRANSPORT_set_quota (transport, &n->peer, n->bw_in, n->bw_out); | ||
1694 | } | ||
1695 | #if DEBUG_CORE | ||
1696 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1697 | "Confirmed key via `%s' message for peer `%4s'\n", "PONG", | ||
1698 | GNUNET_i2s (&n->peer)); | ||
1699 | #endif | ||
1700 | |||
1701 | |||
1702 | size = | ||
1703 | sizeof (struct ConnectNotifyMessage) + | ||
1704 | (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information); | ||
1705 | if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
1706 | { | ||
1707 | GNUNET_break (0); | ||
1708 | /* recovery strategy: throw away performance data */ | ||
1709 | GNUNET_array_grow (n->ats, n->ats_count, 0); | ||
1710 | size = | ||
1711 | sizeof (struct PeerStatusNotifyMessage) + | ||
1712 | n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information); | ||
1713 | } | ||
1714 | cnm = (struct ConnectNotifyMessage *) buf; | ||
1715 | cnm->header.size = htons (size); | ||
1716 | cnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT); | ||
1717 | cnm->ats_count = htonl (n->ats_count); | ||
1718 | cnm->peer = n->peer; | ||
1719 | mats = &cnm->ats; | ||
1720 | memcpy (mats, n->ats, | ||
1721 | n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information)); | ||
1722 | mats[n->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); | ||
1723 | mats[n->ats_count].value = htonl (0); | ||
1724 | send_to_all_clients (&cnm->header, GNUNET_NO, | ||
1725 | GNUNET_CORE_OPTION_SEND_CONNECT); | ||
1726 | process_encrypted_neighbour_queue (n); | ||
1727 | n->last_activity = GNUNET_TIME_absolute_get (); | ||
1728 | |||
1729 | if (n->status == PEER_STATE_KEY_CONFIRMED) | ||
1730 | { | ||
1731 | now = GNUNET_TIME_absolute_get (); | ||
1732 | n->last_activity = now; | ||
1733 | changed = GNUNET_YES; | ||
1734 | if (!up) | ||
1735 | { | ||
1736 | GNUNET_STATISTICS_update (stats, gettext_noop ("# established sessions"), | ||
1737 | 1, GNUNET_NO); | ||
1738 | n->time_established = now; | ||
1739 | } | ||
1740 | if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK) | ||
1741 | GNUNET_SCHEDULER_cancel (n->keep_alive_task); | ||
1742 | n->keep_alive_task = | ||
1743 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide | ||
1744 | (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
1745 | 2), &send_keep_alive, n); | ||
1746 | } | ||
1747 | |||
1748 | |||
1749 | } | ||
1750 | |||
1751 | |||
1752 | /** | ||
1753 | * Update information about a session. | ||
1754 | * | ||
1755 | * @param peer peer who's session should be updated | ||
1756 | * @param bw_out new outbound bandwidth limit for the peer | ||
1757 | * @param atsi performance information | ||
1758 | * @param atsi_count number of performance records supplied | ||
1759 | */ | ||
1760 | void | ||
1761 | GSC_SESSIONS_update (const struct GNUNET_PeerIdentity *peer, | ||
1762 | struct GNUNET_BANDWIDTH_Value32NBO bw_out, | ||
1763 | const struct GNUNET_TRANSPORT_ATS_Information *atsi, | ||
1764 | uint32_t atsi_count) | ||
1765 | { | ||
1766 | if (bw_out_external_limit.value__ != pt->inbound_bw_limit.value__) | ||
1767 | { | ||
1768 | #if DEBUG_CORE_SET_QUOTA | ||
1769 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1770 | "Received %u b/s as new inbound limit for peer `%4s'\n", | ||
1771 | (unsigned int) ntohl (pt->inbound_bw_limit.value__), | ||
1772 | GNUNET_i2s (&n->peer)); | ||
1773 | #endif | ||
1774 | n->bw_out_external_limit = pt->inbound_bw_limit; | ||
1775 | n->bw_out = | ||
1776 | GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit, | ||
1777 | n->bw_out_internal_limit); | ||
1778 | GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window, | ||
1779 | n->bw_out); | ||
1780 | GNUNET_TRANSPORT_set_quota (transport, &n->peer, n->bw_in, n->bw_out); | ||
1781 | } | ||
1676 | 1782 | ||
1783 | } | ||
1677 | 1784 | ||
1678 | 1785 | ||
1679 | /** | 1786 | /** |
diff --git a/src/core/gnunet-service-core_sessions.h b/src/core/gnunet-service-core_sessions.h index fc5944cda..781398d44 100644 --- a/src/core/gnunet-service-core_sessions.h +++ b/src/core/gnunet-service-core_sessions.h | |||
@@ -147,6 +147,28 @@ GSC_SESSIONS_handle_client_request_info (void *cls, struct GNUNET_SERVER_Client | |||
147 | 147 | ||
148 | 148 | ||
149 | /** | 149 | /** |
150 | * Create a session, a key exchange was just completed. | ||
151 | */ | ||
152 | void | ||
153 | GSC_SESSIONS_create (const struct GNUNET_PeerIdentity *peer); | ||
154 | |||
155 | /** | ||
156 | * Update information about a session. | ||
157 | * | ||
158 | * @param peer peer who's session should be updated | ||
159 | * @param bw_out new outbound bandwidth limit for the peer | ||
160 | * @param atsi performance information | ||
161 | * @param atsi_count number of performance records supplied | ||
162 | */ | ||
163 | void | ||
164 | GSC_SESSIONS_update (const struct GNUNET_PeerIdentity *peer, | ||
165 | struct GNUNET_BANDWIDTH_Value32NBO bw_out, | ||
166 | const struct GNUNET_TRANSPORT_ATS_Information *atsi, | ||
167 | uint32_t atsi_count); | ||
168 | |||
169 | |||
170 | |||
171 | /** | ||
150 | * Initialize sessions subsystem. | 172 | * Initialize sessions subsystem. |
151 | */ | 173 | */ |
152 | void | 174 | void |