diff options
Diffstat (limited to 'src/mesh/gnunet-service-mesh_tunnel.c')
-rw-r--r-- | src/mesh/gnunet-service-mesh_tunnel.c | 201 |
1 files changed, 142 insertions, 59 deletions
diff --git a/src/mesh/gnunet-service-mesh_tunnel.c b/src/mesh/gnunet-service-mesh_tunnel.c index a13d88fd5..56b27147e 100644 --- a/src/mesh/gnunet-service-mesh_tunnel.c +++ b/src/mesh/gnunet-service-mesh_tunnel.c | |||
@@ -82,9 +82,14 @@ struct MeshTunnel3 | |||
82 | struct MeshPeer *peer; | 82 | struct MeshPeer *peer; |
83 | 83 | ||
84 | /** | 84 | /** |
85 | * State of the tunnel. | 85 | * State of the tunnel connectivity. |
86 | */ | 86 | */ |
87 | enum MeshTunnel3State state; | 87 | enum MeshTunnel3CState cstate; |
88 | |||
89 | /** | ||
90 | * State of the tunnel encryption. | ||
91 | */ | ||
92 | enum MeshTunnel3EState estate; | ||
88 | 93 | ||
89 | /** | 94 | /** |
90 | * Key eXchange context. | 95 | * Key eXchange context. |
@@ -247,18 +252,18 @@ static struct GNUNET_TIME_Relative rekey_period; | |||
247 | /******************************************************************************/ | 252 | /******************************************************************************/ |
248 | 253 | ||
249 | /** | 254 | /** |
250 | * Get string description for tunnel state. | 255 | * Get string description for tunnel connectivity state. |
251 | * | 256 | * |
252 | * @param s Tunnel state. | 257 | * @param cs Tunnel state. |
253 | * | 258 | * |
254 | * @return String representation. | 259 | * @return String representation. |
255 | */ | 260 | */ |
256 | static const char * | 261 | static const char * |
257 | GMT_state2s (enum MeshTunnel3State s) | 262 | cstate2s (enum MeshTunnel3CState cs) |
258 | { | 263 | { |
259 | static char buf[128]; | 264 | static char buf[128]; |
260 | 265 | ||
261 | switch (s) | 266 | switch (cs) |
262 | { | 267 | { |
263 | case MESH_TUNNEL3_NEW: | 268 | case MESH_TUNNEL3_NEW: |
264 | return "MESH_TUNNEL3_NEW"; | 269 | return "MESH_TUNNEL3_NEW"; |
@@ -266,19 +271,63 @@ GMT_state2s (enum MeshTunnel3State s) | |||
266 | return "MESH_TUNNEL3_SEARCHING"; | 271 | return "MESH_TUNNEL3_SEARCHING"; |
267 | case MESH_TUNNEL3_WAITING: | 272 | case MESH_TUNNEL3_WAITING: |
268 | return "MESH_TUNNEL3_WAITING"; | 273 | return "MESH_TUNNEL3_WAITING"; |
269 | case MESH_TUNNEL3_KEY_SENT: | ||
270 | return "MESH_TUNNEL3_KEY_SENT"; | ||
271 | case MESH_TUNNEL3_READY: | 274 | case MESH_TUNNEL3_READY: |
272 | return "MESH_TUNNEL3_READY"; | 275 | return "MESH_TUNNEL3_READY"; |
273 | case MESH_TUNNEL3_RECONNECTING: | ||
274 | return "MESH_TUNNEL3_RECONNECTING"; | ||
275 | case MESH_TUNNEL3_REKEY: | ||
276 | return "MESH_TUNNEL3_REKEY"; | ||
277 | 276 | ||
278 | default: | 277 | default: |
279 | sprintf (buf, "%u (UNKNOWN STATE)", s); | 278 | sprintf (buf, "%u (UNKNOWN STATE)", cs); |
280 | return buf; | 279 | return buf; |
281 | } | 280 | } |
281 | return ""; | ||
282 | } | ||
283 | |||
284 | |||
285 | /** | ||
286 | * Get string description for tunnel encryption state. | ||
287 | * | ||
288 | * @param es Tunnel state. | ||
289 | * | ||
290 | * @return String representation. | ||
291 | */ | ||
292 | static const char * | ||
293 | estate2s (enum MeshTunnel3EState es) | ||
294 | { | ||
295 | static char buf[128]; | ||
296 | |||
297 | switch (es) | ||
298 | { | ||
299 | case MESH_TUNNEL3_KEY_UNINITIALIZED: | ||
300 | return "MESH_TUNNEL3_KEY_UNINITIALIZED"; | ||
301 | case MESH_TUNNEL3_KEY_SENT: | ||
302 | return "MESH_TUNNEL3_KEY_SENT"; | ||
303 | case MESH_TUNNEL3_KEY_PING: | ||
304 | return "MESH_TUNNEL3_KEY_PING"; | ||
305 | case MESH_TUNNEL3_KEY_OK: | ||
306 | return "MESH_TUNNEL3_KEY_OK"; | ||
307 | |||
308 | default: | ||
309 | sprintf (buf, "%u (UNKNOWN STATE)", es); | ||
310 | return buf; | ||
311 | } | ||
312 | return ""; | ||
313 | } | ||
314 | |||
315 | |||
316 | /** | ||
317 | * @brief Check if tunnel is ready to send traffic. | ||
318 | * | ||
319 | * Tunnel must be connected and with encryption correctly set up. | ||
320 | * | ||
321 | * @param t Tunnel to check. | ||
322 | * | ||
323 | * @return #GNUNET_YES if ready, #GNUNET_NO otherwise | ||
324 | */ | ||
325 | static int | ||
326 | is_ready (struct MeshTunnel3 *t) | ||
327 | { | ||
328 | return (MESH_TUNNEL3_READY == t->cstate | ||
329 | && MESH_TUNNEL3_KEY_OK == t->estate) | ||
330 | || GMT_is_loopback (t); | ||
282 | } | 331 | } |
283 | 332 | ||
284 | 333 | ||
@@ -531,7 +580,7 @@ tunnel_get_connection (struct MeshTunnel3 *t) | |||
531 | for (iter = t->connection_head; NULL != iter; iter = iter->next) | 580 | for (iter = t->connection_head; NULL != iter; iter = iter->next) |
532 | { | 581 | { |
533 | LOG (GNUNET_ERROR_TYPE_DEBUG, " connection %s: %u\n", | 582 | LOG (GNUNET_ERROR_TYPE_DEBUG, " connection %s: %u\n", |
534 | GNUNET_h2s (GMC_get_id (iter->c)), GMC_get_state (iter->c)); | 583 | GMC_2s (iter->c), GMC_get_state (iter->c)); |
535 | if (MESH_CONNECTION_READY == GMC_get_state (iter->c)) | 584 | if (MESH_CONNECTION_READY == GMC_get_state (iter->c)) |
536 | { | 585 | { |
537 | qn = GMC_get_qn (iter->c, GMC_is_origin (iter->c, GNUNET_YES)); | 586 | qn = GMC_get_qn (iter->c, GMC_is_origin (iter->c, GNUNET_YES)); |
@@ -543,6 +592,7 @@ tunnel_get_connection (struct MeshTunnel3 *t) | |||
543 | } | 592 | } |
544 | } | 593 | } |
545 | } | 594 | } |
595 | LOG (GNUNET_ERROR_TYPE_DEBUG, " selected: connection %s\n", GMC_2s (best)); | ||
546 | return best; | 596 | return best; |
547 | } | 597 | } |
548 | 598 | ||
@@ -569,6 +619,13 @@ send_queued_data (struct MeshTunnel3 *t) | |||
569 | return; | 619 | return; |
570 | } | 620 | } |
571 | 621 | ||
622 | if (GNUNET_NO == is_ready (t)) | ||
623 | { | ||
624 | LOG (GNUNET_ERROR_TYPE_DEBUG, " not ready yet: %s/%s\n", | ||
625 | estate2s (t->estate), cstate2s (t->cstate)); | ||
626 | return; | ||
627 | } | ||
628 | |||
572 | room = GMT_get_connections_buffer (t); | 629 | room = GMT_get_connections_buffer (t); |
573 | LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer space: %u\n", room); | 630 | LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer space: %u\n", room); |
574 | for (tq = t->tq_head; NULL != tq && room > 0; tq = next) | 631 | for (tq = t->tq_head; NULL != tq && room > 0; tq = next) |
@@ -606,7 +663,9 @@ queue_data (struct MeshTunnel3 *t, | |||
606 | struct MeshTunnelDelayed *tq; | 663 | struct MeshTunnelDelayed *tq; |
607 | uint16_t size = ntohs (msg->size); | 664 | uint16_t size = ntohs (msg->size); |
608 | 665 | ||
609 | if (MESH_TUNNEL3_READY == t->state) | 666 | LOG (GNUNET_ERROR_TYPE_DEBUG, "queue data on Tunnel %s\n", GMT_2s (t)); |
667 | |||
668 | if (GNUNET_YES == is_ready (t)) | ||
610 | { | 669 | { |
611 | GNUNET_break (0); | 670 | GNUNET_break (0); |
612 | return; | 671 | return; |
@@ -696,7 +755,7 @@ send_ephemeral (struct MeshTunnel3 *t) | |||
696 | { | 755 | { |
697 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __FUNCTION__); | 756 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __FUNCTION__); |
698 | 757 | ||
699 | kx_msg.sender_status = htonl (t->state); | 758 | kx_msg.sender_status = htonl (t->estate); |
700 | send_kx (t, &kx_msg.header); | 759 | send_kx (t, &kx_msg.header); |
701 | } | 760 | } |
702 | 761 | ||
@@ -777,18 +836,20 @@ rekey_tunnel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
777 | t->kx_ctx->d_key_old = t->d_key; | 836 | t->kx_ctx->d_key_old = t->d_key; |
778 | } | 837 | } |
779 | send_ephemeral (t); | 838 | send_ephemeral (t); |
780 | if (MESH_TUNNEL3_READY == t->state || MESH_TUNNEL3_REKEY == t->state) | 839 | switch (t->estate) |
781 | { | ||
782 | send_ping (t); | ||
783 | t->state = MESH_TUNNEL3_REKEY; | ||
784 | } | ||
785 | else if (MESH_TUNNEL3_WAITING == t->state) | ||
786 | { | 840 | { |
787 | t->state = MESH_TUNNEL3_KEY_SENT; | 841 | case MESH_TUNNEL3_KEY_UNINITIALIZED: |
788 | } | 842 | t->estate = MESH_TUNNEL3_KEY_SENT; |
789 | else | 843 | break; |
790 | { | 844 | case MESH_TUNNEL3_KEY_SENT: |
791 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Unexpected state %u\n", t->state); | 845 | break; |
846 | case MESH_TUNNEL3_KEY_PING: | ||
847 | case MESH_TUNNEL3_KEY_OK: | ||
848 | send_ping (t); | ||
849 | t->estate = MESH_TUNNEL3_KEY_PING; | ||
850 | break; | ||
851 | default: | ||
852 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Unexpected state %u\n", t->estate); | ||
792 | } | 853 | } |
793 | 854 | ||
794 | LOG (GNUNET_ERROR_TYPE_DEBUG, " next call in %s\n", | 855 | LOG (GNUNET_ERROR_TYPE_DEBUG, " next call in %s\n", |
@@ -932,7 +993,7 @@ handle_data (struct MeshTunnel3 *t, | |||
932 | return; | 993 | return; |
933 | } | 994 | } |
934 | 995 | ||
935 | GMT_change_state (t, MESH_TUNNEL3_READY); | 996 | GMT_change_cstate (t, MESH_TUNNEL3_READY); |
936 | GMCH_handle_data (ch, msg, fwd); | 997 | GMCH_handle_data (ch, msg, fwd); |
937 | } | 998 | } |
938 | 999 | ||
@@ -1154,11 +1215,11 @@ handle_ephemeral (struct MeshTunnel3 *t, | |||
1154 | LOG (GNUNET_ERROR_TYPE_DEBUG, " km is %s\n", GNUNET_h2s (&km)); | 1215 | LOG (GNUNET_ERROR_TYPE_DEBUG, " km is %s\n", GNUNET_h2s (&km)); |
1155 | derive_symmertic (&t->e_key, &my_full_id, GMP_get_id (t->peer), &km); | 1216 | derive_symmertic (&t->e_key, &my_full_id, GMP_get_id (t->peer), &km); |
1156 | derive_symmertic (&t->d_key, GMP_get_id (t->peer), &my_full_id, &km); | 1217 | derive_symmertic (&t->d_key, GMP_get_id (t->peer), &my_full_id, &km); |
1157 | if (MESH_TUNNEL3_KEY_SENT == t->state) | 1218 | if (MESH_TUNNEL3_KEY_SENT == t->estate) |
1158 | { | 1219 | { |
1159 | LOG (GNUNET_ERROR_TYPE_DEBUG, " our key was sent, send ping\n"); | 1220 | LOG (GNUNET_ERROR_TYPE_DEBUG, " our key was sent, send ping\n"); |
1160 | send_ping (t); | 1221 | send_ping (t); |
1161 | t->state = MESH_TUNNEL3_REKEY; | 1222 | t->estate = MESH_TUNNEL3_KEY_PING; |
1162 | } | 1223 | } |
1163 | } | 1224 | } |
1164 | 1225 | ||
@@ -1232,8 +1293,7 @@ handle_pong (struct MeshTunnel3 *t, | |||
1232 | t->rekey_task = GNUNET_SCHEDULER_NO_TASK; | 1293 | t->rekey_task = GNUNET_SCHEDULER_NO_TASK; |
1233 | GNUNET_free (t->kx_ctx); | 1294 | GNUNET_free (t->kx_ctx); |
1234 | t->kx_ctx = NULL; | 1295 | t->kx_ctx = NULL; |
1235 | t->state = MESH_TUNNEL3_READY; | 1296 | GMT_change_estate (t, MESH_TUNNEL3_KEY_OK); |
1236 | send_queued_data (t); | ||
1237 | } | 1297 | } |
1238 | 1298 | ||
1239 | 1299 | ||
@@ -1450,44 +1510,65 @@ GMT_new (struct MeshPeer *destination) | |||
1450 | 1510 | ||
1451 | 1511 | ||
1452 | /** | 1512 | /** |
1453 | * Change the tunnel state. | 1513 | * Change the tunnel's connection state. |
1454 | * | 1514 | * |
1455 | * @param t Tunnel whose state to change. | 1515 | * @param t Tunnel whose connection state to change. |
1456 | * @param state New state. | 1516 | * @param cstate New connection state. |
1457 | */ | 1517 | */ |
1458 | void | 1518 | void |
1459 | GMT_change_state (struct MeshTunnel3* t, enum MeshTunnel3State state) | 1519 | GMT_change_cstate (struct MeshTunnel3* t, enum MeshTunnel3CState state) |
1460 | { | 1520 | { |
1461 | if (NULL == t) | 1521 | if (NULL == t) |
1462 | return; | 1522 | return; |
1463 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1523 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1464 | "Tunnel %s state was %s\n", | 1524 | "Tunnel %s cstate was %s\n", |
1465 | GMP_2s (t->peer), | 1525 | GMP_2s (t->peer), cstate2s (t->cstate)); |
1466 | GMT_state2s (t->state)); | ||
1467 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1526 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1468 | "Tunnel %s state is now %s\n", | 1527 | "Tunnel %s cstate is now %s\n", |
1469 | GMP_2s (t->peer), | 1528 | GMP_2s (t->peer), cstate2s (state)); |
1470 | GMT_state2s (state)); | ||
1471 | if (myid != GMP_get_short_id (t->peer) && | 1529 | if (myid != GMP_get_short_id (t->peer) && |
1472 | MESH_TUNNEL3_WAITING == t->state && MESH_TUNNEL3_READY == state) | 1530 | MESH_TUNNEL3_READY != t->cstate && |
1531 | MESH_TUNNEL3_READY == state && | ||
1532 | MESH_TUNNEL3_KEY_UNINITIALIZED == t->estate) | ||
1473 | { | 1533 | { |
1474 | LOG (GNUNET_ERROR_TYPE_DEBUG, " triggered rekey\n"); | 1534 | LOG (GNUNET_ERROR_TYPE_DEBUG, " triggered rekey\n"); |
1475 | rekey_tunnel (t, NULL); | 1535 | rekey_tunnel (t, NULL); |
1476 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1477 | "Tunnel %s state is now %s\n", | ||
1478 | GMP_2s (t->peer), | ||
1479 | GMT_state2s (t->state)); | ||
1480 | } | ||
1481 | else | ||
1482 | { | ||
1483 | t->state = state; | ||
1484 | } | 1536 | } |
1537 | t->cstate = state; | ||
1538 | |||
1485 | if (MESH_TUNNEL3_READY == state && 3 <= GMT_count_connections (t)) | 1539 | if (MESH_TUNNEL3_READY == state && 3 <= GMT_count_connections (t)) |
1486 | { | 1540 | { |
1487 | GMP_stop_search (t->peer); | 1541 | GMP_stop_search (t->peer); |
1488 | } | 1542 | } |
1489 | } | 1543 | } |
1490 | 1544 | ||
1545 | /** | ||
1546 | * Change the tunnel encryption state. | ||
1547 | * | ||
1548 | * @param t Tunnel whose encryption state to change. | ||
1549 | * @param state New encryption state. | ||
1550 | */ | ||
1551 | void | ||
1552 | GMT_change_estate (struct MeshTunnel3* t, enum MeshTunnel3EState state) | ||
1553 | { | ||
1554 | if (NULL == t) | ||
1555 | return; | ||
1556 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1557 | "Tunnel %s estate was %s\n", | ||
1558 | GMP_2s (t->peer), estate2s (t->estate)); | ||
1559 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1560 | "Tunnel %s estate is now %s\n", | ||
1561 | GMP_2s (t->peer), estate2s (state)); | ||
1562 | if (myid != GMP_get_short_id (t->peer) && | ||
1563 | MESH_TUNNEL3_KEY_OK != t->estate && MESH_TUNNEL3_KEY_OK == state) | ||
1564 | { | ||
1565 | t->estate = state; | ||
1566 | send_queued_data (t); | ||
1567 | return; | ||
1568 | } | ||
1569 | t->estate = state; | ||
1570 | } | ||
1571 | |||
1491 | 1572 | ||
1492 | /** | 1573 | /** |
1493 | * Add a connection to a tunnel. | 1574 | * Add a connection to a tunnel. |
@@ -1781,21 +1862,21 @@ GMT_count_channels (struct MeshTunnel3 *t) | |||
1781 | 1862 | ||
1782 | 1863 | ||
1783 | /** | 1864 | /** |
1784 | * Get the state of a tunnel. | 1865 | * Get the connectivity state of a tunnel. |
1785 | * | 1866 | * |
1786 | * @param t Tunnel. | 1867 | * @param t Tunnel. |
1787 | * | 1868 | * |
1788 | * @return Tunnel's state. | 1869 | * @return Tunnel's connectivity state. |
1789 | */ | 1870 | */ |
1790 | enum MeshTunnel3State | 1871 | enum MeshTunnel3CState |
1791 | GMT_get_state (struct MeshTunnel3 *t) | 1872 | GMT_get_cstate (struct MeshTunnel3 *t) |
1792 | { | 1873 | { |
1793 | if (NULL == t) | 1874 | if (NULL == t) |
1794 | { | 1875 | { |
1795 | GNUNET_break (0); | 1876 | GNUNET_break (0); |
1796 | return (enum MeshTunnel3State) -1; | 1877 | return (enum MeshTunnel3CState) -1; |
1797 | } | 1878 | } |
1798 | return t->state; | 1879 | return t->cstate; |
1799 | } | 1880 | } |
1800 | 1881 | ||
1801 | 1882 | ||
@@ -2050,6 +2131,7 @@ GMT_cancel (struct MeshTunnel3Queue *q) | |||
2050 | /* message_sent() will be called and free q */ | 2131 | /* message_sent() will be called and free q */ |
2051 | } | 2132 | } |
2052 | 2133 | ||
2134 | |||
2053 | /** | 2135 | /** |
2054 | * Sends an already built message on a tunnel, encrypting it and | 2136 | * Sends an already built message on a tunnel, encrypting it and |
2055 | * choosing the best connection. | 2137 | * choosing the best connection. |
@@ -2078,13 +2160,14 @@ GMT_send_prebuilt_message (const struct GNUNET_MessageHeader *message, | |||
2078 | uint32_t iv; | 2160 | uint32_t iv; |
2079 | uint16_t type; | 2161 | uint16_t type; |
2080 | 2162 | ||
2081 | if (MESH_TUNNEL3_READY != t->state) | 2163 | LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT Send on Tunnel %s\n", GMT_2s (t)); |
2164 | |||
2165 | if (GNUNET_NO == is_ready (t)) | ||
2082 | { | 2166 | { |
2083 | queue_data (t, ch, message); | 2167 | queue_data (t, ch, message); |
2084 | /* FIXME */ | 2168 | /* FIXME */ |
2085 | return NULL; | 2169 | return NULL; |
2086 | } | 2170 | } |
2087 | LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT Send on Tunnel %s\n", GMT_2s (t)); | ||
2088 | 2171 | ||
2089 | if (GMT_is_loopback (t)) | 2172 | if (GMT_is_loopback (t)) |
2090 | { | 2173 | { |