aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-communicator-tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-communicator-tcp.c')
-rw-r--r--src/transport/gnunet-communicator-tcp.c85
1 files changed, 43 insertions, 42 deletions
diff --git a/src/transport/gnunet-communicator-tcp.c b/src/transport/gnunet-communicator-tcp.c
index 50264cf45..576c20278 100644
--- a/src/transport/gnunet-communicator-tcp.c
+++ b/src/transport/gnunet-communicator-tcp.c
@@ -429,13 +429,6 @@ struct Queue
429 int destroyed; 429 int destroyed;
430 430
431 /** 431 /**
432 * #GNUNET_YES after #inject_key() placed the rekey message into the
433 * plaintext buffer. Once the plaintext buffer is drained, this
434 * means we must switch to the new key material.
435 */
436 int rekey_state;
437
438 /**
439 * #GNUNET_YES if we just rekeyed and must thus possibly 432 * #GNUNET_YES if we just rekeyed and must thus possibly
440 * re-decrypt ciphertext. 433 * re-decrypt ciphertext.
441 */ 434 */
@@ -886,6 +879,7 @@ do_rekey (struct Queue *queue, const struct TCPRekey *rekey)
886 thp.receiver = my_identity; 879 thp.receiver = my_identity;
887 thp.ephemeral = rekey->ephemeral; 880 thp.ephemeral = rekey->ephemeral;
888 thp.monotonic_time = rekey->monotonic_time; 881 thp.monotonic_time = rekey->monotonic_time;
882 /* FIXME: check monotonic time is monotonic... */
889 if (GNUNET_OK != 883 if (GNUNET_OK !=
890 GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY, 884 GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY,
891 &thp.purpose, 885 &thp.purpose,
@@ -1048,8 +1042,8 @@ queue_read (void *cls)
1048 /* 'done' bytes of plaintext were used, shift buffer */ 1042 /* 'done' bytes of plaintext were used, shift buffer */
1049 GNUNET_assert (done <= queue->pread_off); 1043 GNUNET_assert (done <= queue->pread_off);
1050 /* NOTE: this memmove() could possibly sometimes be 1044 /* NOTE: this memmove() could possibly sometimes be
1051 avoided if we pass 'total' into try_handle_plaintext() 1045 avoided if we pass 'total' into try_handle_plaintext()
1052 and use it at an offset into the buffer there! */ 1046 and use it at an offset into the buffer there! */
1053 memmove (queue->pread_buf, 1047 memmove (queue->pread_buf,
1054 &queue->pread_buf[done], 1048 &queue->pread_buf[done],
1055 queue->pread_off - done); 1049 queue->pread_off - done);
@@ -1271,20 +1265,7 @@ inject_rekey (struct Queue *queue)
1271 &rekey.sender_sig)); 1265 &rekey.sender_sig));
1272 calculate_hmac (&queue->out_hmac, &rekey, sizeof (rekey), &rekey.hmac); 1266 calculate_hmac (&queue->out_hmac, &rekey, sizeof (rekey), &rekey.hmac);
1273 memcpy (queue->pwrite_buf, &rekey, sizeof (rekey)); 1267 memcpy (queue->pwrite_buf, &rekey, sizeof (rekey));
1274 queue->rekey_state = GNUNET_YES; 1268 queue->pwrite_off = sizeof (rekey);
1275}
1276
1277
1278/**
1279 * We encrypted the rekey message, now update actually swap the key
1280 * material and update the key freshness parameters of @a queue.
1281 */
1282static void
1283switch_key (struct Queue *queue)
1284{
1285 queue->rekey_state = GNUNET_NO;
1286 gcry_cipher_close (queue->out_cipher);
1287 setup_out_cipher (queue);
1288} 1269}
1289 1270
1290 1271
@@ -1301,27 +1282,31 @@ queue_write (void *cls)
1301 ssize_t sent; 1282 ssize_t sent;
1302 1283
1303 queue->write_task = NULL; 1284 queue->write_task = NULL;
1304 sent = GNUNET_NETWORK_socket_send (queue->sock, 1285 if (0 != queue->cwrite_off)
1305 queue->cwrite_buf,
1306 queue->cwrite_off);
1307 if ((-1 == sent) && (EAGAIN != errno) && (EINTR != errno))
1308 { 1286 {
1309 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send"); 1287 sent = GNUNET_NETWORK_socket_send (queue->sock,
1310 queue_destroy (queue); 1288 queue->cwrite_buf,
1311 return; 1289 queue->cwrite_off);
1312 } 1290 if ((-1 == sent) && (EAGAIN != errno) && (EINTR != errno))
1313 if (sent > 0) 1291 {
1314 { 1292 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send");
1315 size_t usent = (size_t) sent; 1293 queue_destroy (queue);
1294 return;
1295 }
1296 if (sent > 0)
1297 {
1298 size_t usent = (size_t) sent;
1316 1299
1317 memmove (queue->cwrite_buf, 1300 memmove (queue->cwrite_buf,
1318 &queue->cwrite_buf[usent], 1301 &queue->cwrite_buf[usent],
1319 queue->cwrite_off - usent); 1302 queue->cwrite_off - usent);
1320 reschedule_queue_timeout (queue); 1303 reschedule_queue_timeout (queue);
1304 }
1321 } 1305 }
1322 /* can we encrypt more? (always encrypt full messages, needed 1306 /* can we encrypt more? (always encrypt full messages, needed
1323 such that #mq_cancel() can work!) */ 1307 such that #mq_cancel() can work!) */
1324 if (queue->cwrite_off + queue->pwrite_off <= BUF_SIZE) 1308 if ((0 < queue->rekey_left_bytes) &&
1309 (queue->cwrite_off + queue->pwrite_off <= BUF_SIZE))
1325 { 1310 {
1326 GNUNET_assert (0 == 1311 GNUNET_assert (0 ==
1327 gcry_cipher_encrypt (queue->out_cipher, 1312 gcry_cipher_encrypt (queue->out_cipher,
@@ -1336,13 +1321,15 @@ queue_write (void *cls)
1336 queue->cwrite_off += queue->pwrite_off; 1321 queue->cwrite_off += queue->pwrite_off;
1337 queue->pwrite_off = 0; 1322 queue->pwrite_off = 0;
1338 } 1323 }
1339 if ((GNUNET_YES == queue->rekey_state) && (0 == queue->pwrite_off))
1340 switch_key (queue);
1341 if ((0 == queue->pwrite_off) && 1324 if ((0 == queue->pwrite_off) &&
1342 ((0 == queue->rekey_left_bytes) || 1325 ((0 == queue->rekey_left_bytes) ||
1343 (0 == 1326 (0 ==
1344 GNUNET_TIME_absolute_get_remaining (queue->rekey_time).rel_value_us))) 1327 GNUNET_TIME_absolute_get_remaining (queue->rekey_time).rel_value_us)))
1328 {
1329 gcry_cipher_close (queue->out_cipher);
1330 setup_out_cipher (queue);
1345 inject_rekey (queue); 1331 inject_rekey (queue);
1332 }
1346 if ((0 == queue->pwrite_off) && (! queue->finishing) && 1333 if ((0 == queue->pwrite_off) && (! queue->finishing) &&
1347 (queue->mq_awaits_continue)) 1334 (queue->mq_awaits_continue))
1348 { 1335 {
@@ -1356,7 +1343,7 @@ queue_write (void *cls)
1356 return; 1343 return;
1357 } 1344 }
1358 /* do we care to write more? */ 1345 /* do we care to write more? */
1359 if (0 < queue->cwrite_off) 1346 if ((0 < queue->cwrite_off) || (0 < queue->pwrite_off))
1360 queue->write_task = 1347 queue->write_task =
1361 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, 1348 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1362 queue->sock, 1349 queue->sock,
@@ -1617,6 +1604,8 @@ decrypt_and_check_tc (struct Queue *queue,
1617 ths.receiver = my_identity; 1604 ths.receiver = my_identity;
1618 memcpy (&ths.ephemeral, ibuf, sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); 1605 memcpy (&ths.ephemeral, ibuf, sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1619 ths.monotonic_time = tc->monotonic_time; 1606 ths.monotonic_time = tc->monotonic_time;
1607 /* FIXME: check monotonic time against previous mono times
1608 from this sender! */
1620 return GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE, 1609 return GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE,
1621 &ths.purpose, 1610 &ths.purpose,
1622 &tc->sender_sig, 1611 &tc->sender_sig,
@@ -1709,6 +1698,11 @@ proto_read_kx (void *cls)
1709 queue->sock, 1698 queue->sock,
1710 &queue_read, 1699 &queue_read,
1711 queue); 1700 queue);
1701 queue->write_task =
1702 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1703 queue->sock,
1704 &queue_write,
1705 queue);
1712 GNUNET_CONTAINER_DLL_remove (proto_head, proto_tail, pq); 1706 GNUNET_CONTAINER_DLL_remove (proto_head, proto_tail, pq);
1713 GNUNET_free (pq); 1707 GNUNET_free (pq);
1714} 1708}
@@ -1910,6 +1904,11 @@ mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
1910 &queue_read_kx, 1904 &queue_read_kx,
1911 queue); 1905 queue);
1912 start_initial_kx_out (queue); 1906 start_initial_kx_out (queue);
1907 queue->write_task =
1908 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1909 queue->sock,
1910 &queue_write,
1911 queue);
1913 return GNUNET_OK; 1912 return GNUNET_OK;
1914} 1913}
1915 1914
@@ -1944,6 +1943,8 @@ get_queue_delete_it (void *cls,
1944static void 1943static void
1945do_shutdown (void *cls) 1944do_shutdown (void *cls)
1946{ 1945{
1946 while (NULL != proto_head)
1947 free_proto_queue (proto_head);
1947 if (NULL != nat) 1948 if (NULL != nat)
1948 { 1949 {
1949 GNUNET_NAT_unregister (nat); 1950 GNUNET_NAT_unregister (nat);