diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mesh/gnunet-service-mesh-enc.c | 404 | ||||
-rw-r--r-- | src/mesh/gnunet-service-mesh_channel.c | 353 | ||||
-rw-r--r-- | src/mesh/gnunet-service-mesh_channel.h | 72 | ||||
-rw-r--r-- | src/mesh/gnunet-service-mesh_peer.c | 2 |
4 files changed, 422 insertions, 409 deletions
diff --git a/src/mesh/gnunet-service-mesh-enc.c b/src/mesh/gnunet-service-mesh-enc.c index be72963c3..c9a182651 100644 --- a/src/mesh/gnunet-service-mesh-enc.c +++ b/src/mesh/gnunet-service-mesh-enc.c | |||
@@ -312,65 +312,6 @@ static struct GNUNET_CRYPTO_EccPrivateKey *my_private_key; | |||
312 | /******************************************************************************/ | 312 | /******************************************************************************/ |
313 | 313 | ||
314 | /** | 314 | /** |
315 | * Function to process paths received for a new peer addition. The recorded | ||
316 | * paths form the initial tunnel, which can be optimized later. | ||
317 | * Called on each result obtained for the DHT search. | ||
318 | * | ||
319 | * @param cls closure | ||
320 | * @param exp when will this value expire | ||
321 | * @param key key of the result | ||
322 | * @param type type of the result | ||
323 | * @param size number of bytes in data | ||
324 | * @param data pointer to the result data | ||
325 | */ | ||
326 | static void | ||
327 | dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp, | ||
328 | const struct GNUNET_HashCode * key, | ||
329 | const struct GNUNET_PeerIdentity *get_path, | ||
330 | unsigned int get_path_length, | ||
331 | const struct GNUNET_PeerIdentity *put_path, | ||
332 | unsigned int put_path_length, enum GNUNET_BLOCK_Type type, | ||
333 | size_t size, const void *data); | ||
334 | |||
335 | |||
336 | /** | ||
337 | * Retrieve the MeshPeer stucture associated with the peer, create one | ||
338 | * and insert it in the appropriate structures if the peer is not known yet. | ||
339 | * | ||
340 | * @param peer Full identity of the peer. | ||
341 | * | ||
342 | * @return Existing or newly created peer info. | ||
343 | */ | ||
344 | static struct MeshPeer * | ||
345 | peer_get (const struct GNUNET_PeerIdentity *peer); | ||
346 | |||
347 | |||
348 | /** | ||
349 | * Retrieve the MeshPeer stucture associated with the peer, create one | ||
350 | * and insert it in the appropriate structures if the peer is not known yet. | ||
351 | * | ||
352 | * @param peer Short identity of the peer. | ||
353 | * | ||
354 | * @return Existing or newly created peer info. | ||
355 | */ | ||
356 | static struct MeshPeer * | ||
357 | peer_get_short (const GNUNET_PEER_Id peer); | ||
358 | |||
359 | |||
360 | /** | ||
361 | * Build a PeerPath from the paths returned from the DHT, reversing the paths | ||
362 | * to obtain a local peer -> destination path and interning the peer ids. | ||
363 | * | ||
364 | * @return Newly allocated and created path | ||
365 | */ | ||
366 | static struct MeshPeerPath * | ||
367 | path_build_from_dht (const struct GNUNET_PeerIdentity *get_path, | ||
368 | unsigned int get_path_length, | ||
369 | const struct GNUNET_PeerIdentity *put_path, | ||
370 | unsigned int put_path_length); | ||
371 | |||
372 | |||
373 | /** | ||
374 | * Adds a path to the data structs of all the peers in the path | 315 | * Adds a path to the data structs of all the peers in the path |
375 | * | 316 | * |
376 | * @param p Path to process. | 317 | * @param p Path to process. |
@@ -1406,349 +1347,6 @@ tunnel_destroy_if_empty (struct MeshTunnel2 *t) | |||
1406 | /******************** MESH NETWORK HANDLERS **************************/ | 1347 | /******************** MESH NETWORK HANDLERS **************************/ |
1407 | /******************************************************************************/ | 1348 | /******************************************************************************/ |
1408 | 1349 | ||
1409 | |||
1410 | /** | ||
1411 | * Generic handler for mesh network payload traffic. | ||
1412 | * | ||
1413 | * @param t Tunnel on which we got this message. | ||
1414 | * @param message Unencryted data message. | ||
1415 | * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; | ||
1416 | */ | ||
1417 | static void | ||
1418 | handle_data (struct MeshTunnel2 *t, const struct GNUNET_MESH_Data *msg, int fwd) | ||
1419 | { | ||
1420 | struct MeshChannelReliability *rel; | ||
1421 | struct MeshChannel *ch; | ||
1422 | struct MeshClient *c; | ||
1423 | uint32_t mid; | ||
1424 | uint16_t type; | ||
1425 | size_t size; | ||
1426 | |||
1427 | /* Check size */ | ||
1428 | size = ntohs (msg->header.size); | ||
1429 | if (size < | ||
1430 | sizeof (struct GNUNET_MESH_Data) + | ||
1431 | sizeof (struct GNUNET_MessageHeader)) | ||
1432 | { | ||
1433 | GNUNET_break (0); | ||
1434 | return; | ||
1435 | } | ||
1436 | type = ntohs (msg->header.type); | ||
1437 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a %s message\n", | ||
1438 | GNUNET_MESH_DEBUG_M2S (type)); | ||
1439 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " payload of type %s\n", | ||
1440 | GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type))); | ||
1441 | |||
1442 | /* Check channel */ | ||
1443 | ch = channel_get (t, ntohl (msg->chid)); | ||
1444 | if (NULL == ch) | ||
1445 | { | ||
1446 | GNUNET_STATISTICS_update (stats, "# data on unknown channel", 1, GNUNET_NO); | ||
1447 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n", | ||
1448 | ntohl (msg->chid)); | ||
1449 | return; | ||
1450 | } | ||
1451 | |||
1452 | /* Initialize FWD/BCK data */ | ||
1453 | c = fwd ? ch->dest : ch->root; | ||
1454 | rel = fwd ? ch->dest_rel : ch->root_rel; | ||
1455 | |||
1456 | if (NULL == c) | ||
1457 | { | ||
1458 | GNUNET_break (0); | ||
1459 | return; | ||
1460 | } | ||
1461 | |||
1462 | tunnel_change_state (t, MESH_TUNNEL_READY); | ||
1463 | |||
1464 | GNUNET_STATISTICS_update (stats, "# data received", 1, GNUNET_NO); | ||
1465 | |||
1466 | mid = ntohl (msg->mid); | ||
1467 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " mid %u\n", mid); | ||
1468 | |||
1469 | if (GNUNET_NO == ch->reliable || | ||
1470 | ( !GMC_is_pid_bigger (rel->mid_recv, mid) && | ||
1471 | GMC_is_pid_bigger (rel->mid_recv + 64, mid) ) ) | ||
1472 | { | ||
1473 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! RECV %u\n", mid); | ||
1474 | if (GNUNET_YES == ch->reliable) | ||
1475 | { | ||
1476 | /* Is this the exact next expected messasge? */ | ||
1477 | if (mid == rel->mid_recv) | ||
1478 | { | ||
1479 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "as expected\n"); | ||
1480 | rel->mid_recv++; | ||
1481 | channel_send_client_data (ch, msg, fwd); | ||
1482 | } | ||
1483 | else | ||
1484 | { | ||
1485 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "save for later\n"); | ||
1486 | channel_rel_add_buffered_data (msg, rel); | ||
1487 | } | ||
1488 | } | ||
1489 | else | ||
1490 | { | ||
1491 | /* Tunnel is unreliable: send to clients directly */ | ||
1492 | /* FIXME: accept Out Of Order traffic */ | ||
1493 | rel->mid_recv = mid + 1; | ||
1494 | channel_send_client_data (ch, msg, fwd); | ||
1495 | } | ||
1496 | } | ||
1497 | else | ||
1498 | { | ||
1499 | GNUNET_break_op (0); | ||
1500 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1501 | " MID %u not expected (%u - %u), dropping!\n", | ||
1502 | mid, rel->mid_recv, rel->mid_recv + 64); | ||
1503 | } | ||
1504 | |||
1505 | channel_send_data_ack (ch, fwd); | ||
1506 | } | ||
1507 | |||
1508 | /** | ||
1509 | * Handler for mesh network traffic end-to-end ACKs. | ||
1510 | * | ||
1511 | * @param t Tunnel on which we got this message. | ||
1512 | * @param message Data message. | ||
1513 | * @param fwd Is this a fwd ACK? (dest->orig) | ||
1514 | */ | ||
1515 | static void | ||
1516 | handle_data_ack (struct MeshTunnel2 *t, | ||
1517 | const struct GNUNET_MESH_DataACK *msg, int fwd) | ||
1518 | { | ||
1519 | struct MeshChannelReliability *rel; | ||
1520 | struct MeshReliableMessage *copy; | ||
1521 | struct MeshReliableMessage *next; | ||
1522 | struct MeshChannel *ch; | ||
1523 | uint32_t ack; | ||
1524 | uint16_t type; | ||
1525 | int work; | ||
1526 | |||
1527 | type = ntohs (msg->header.type); | ||
1528 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a %s message!\n", | ||
1529 | GNUNET_MESH_DEBUG_M2S (type)); | ||
1530 | ch = channel_get (t, ntohl (msg->chid)); | ||
1531 | if (NULL == ch) | ||
1532 | { | ||
1533 | GNUNET_STATISTICS_update (stats, "# ack on unknown channel", 1, GNUNET_NO); | ||
1534 | return; | ||
1535 | } | ||
1536 | ack = ntohl (msg->mid); | ||
1537 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! %s ACK %u\n", | ||
1538 | (GNUNET_YES == fwd) ? "FWD" : "BCK", ack); | ||
1539 | |||
1540 | if (GNUNET_YES == fwd) | ||
1541 | { | ||
1542 | rel = ch->root_rel; | ||
1543 | } | ||
1544 | else | ||
1545 | { | ||
1546 | rel = ch->dest_rel; | ||
1547 | } | ||
1548 | if (NULL == rel) | ||
1549 | { | ||
1550 | GNUNET_break (0); | ||
1551 | return; | ||
1552 | } | ||
1553 | |||
1554 | for (work = GNUNET_NO, copy = rel->head_sent; copy != NULL; copy = next) | ||
1555 | { | ||
1556 | if (GMC_is_pid_bigger (copy->mid, ack)) | ||
1557 | { | ||
1558 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! head %u, out!\n", copy->mid); | ||
1559 | channel_rel_free_sent (rel, msg); | ||
1560 | break; | ||
1561 | } | ||
1562 | work = GNUNET_YES; | ||
1563 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! id %u\n", copy->mid); | ||
1564 | next = copy->next; | ||
1565 | rel_message_free (copy); | ||
1566 | } | ||
1567 | /* ACK client if needed */ | ||
1568 | // channel_send_ack (t, type, GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK == type); | ||
1569 | |||
1570 | /* If some message was free'd, update the retransmission delay*/ | ||
1571 | if (GNUNET_YES == work) | ||
1572 | { | ||
1573 | if (GNUNET_SCHEDULER_NO_TASK != rel->retry_task) | ||
1574 | { | ||
1575 | GNUNET_SCHEDULER_cancel (rel->retry_task); | ||
1576 | if (NULL == rel->head_sent) | ||
1577 | { | ||
1578 | rel->retry_task = GNUNET_SCHEDULER_NO_TASK; | ||
1579 | } | ||
1580 | else | ||
1581 | { | ||
1582 | struct GNUNET_TIME_Absolute new_target; | ||
1583 | struct GNUNET_TIME_Relative delay; | ||
1584 | |||
1585 | delay = GNUNET_TIME_relative_multiply (rel->retry_timer, | ||
1586 | MESH_RETRANSMIT_MARGIN); | ||
1587 | new_target = GNUNET_TIME_absolute_add (rel->head_sent->timestamp, | ||
1588 | delay); | ||
1589 | delay = GNUNET_TIME_absolute_get_remaining (new_target); | ||
1590 | rel->retry_task = | ||
1591 | GNUNET_SCHEDULER_add_delayed (delay, | ||
1592 | &channel_retransmit_message, | ||
1593 | rel); | ||
1594 | } | ||
1595 | } | ||
1596 | else | ||
1597 | GNUNET_break (0); | ||
1598 | } | ||
1599 | } | ||
1600 | |||
1601 | |||
1602 | |||
1603 | |||
1604 | /** | ||
1605 | * Handler for channel create messages. | ||
1606 | * | ||
1607 | * @param t Tunnel this channel is to be created in. | ||
1608 | * @param msg Message. | ||
1609 | * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; | ||
1610 | */ | ||
1611 | static void | ||
1612 | handle_channel_create (struct MeshTunnel2 *t, | ||
1613 | struct GNUNET_MESH_ChannelCreate *msg, | ||
1614 | int fwd) | ||
1615 | { | ||
1616 | MESH_ChannelNumber chid; | ||
1617 | struct MeshChannel *ch; | ||
1618 | struct MeshClient *c; | ||
1619 | uint32_t port; | ||
1620 | |||
1621 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received Channel Create\n"); | ||
1622 | /* Check message size */ | ||
1623 | if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelCreate)) | ||
1624 | { | ||
1625 | GNUNET_break_op (0); | ||
1626 | return; | ||
1627 | } | ||
1628 | |||
1629 | /* Check if channel exists */ | ||
1630 | chid = ntohl (msg->chid); | ||
1631 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " chid %u\n", chid); | ||
1632 | ch = channel_get (t, chid); | ||
1633 | if (NULL != ch) | ||
1634 | { | ||
1635 | /* Probably a retransmission, safe to ignore */ | ||
1636 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " already exists...\n"); | ||
1637 | if (NULL != ch->dest) | ||
1638 | { | ||
1639 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " duplicate CC!!\n"); | ||
1640 | channel_send_ack (ch, !fwd); | ||
1641 | return; | ||
1642 | } | ||
1643 | } | ||
1644 | else | ||
1645 | { | ||
1646 | /* Create channel */ | ||
1647 | ch = channel_new (t, NULL, 0); | ||
1648 | ch->gid = chid; | ||
1649 | channel_set_options (ch, ntohl (msg->opt)); | ||
1650 | } | ||
1651 | |||
1652 | /* Find a destination client */ | ||
1653 | port = ntohl (msg->port); | ||
1654 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " port %u\n", port); | ||
1655 | c = GNUNET_CONTAINER_multihashmap32_get (ports, port); | ||
1656 | if (NULL == c) | ||
1657 | { | ||
1658 | /* TODO send reject */ | ||
1659 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " no client has port registered\n"); | ||
1660 | /* TODO free ch */ | ||
1661 | return; | ||
1662 | } | ||
1663 | |||
1664 | channel_add_client (ch, c); | ||
1665 | if (GNUNET_YES == ch->reliable) | ||
1666 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! Reliable\n"); | ||
1667 | |||
1668 | send_local_channel_create (ch); | ||
1669 | channel_send_ack (ch, fwd); | ||
1670 | send_local_ack (ch, !fwd); | ||
1671 | } | ||
1672 | |||
1673 | |||
1674 | /** | ||
1675 | * Handler for channel ack messages. | ||
1676 | * | ||
1677 | * @param t Tunnel this channel is to be created in. | ||
1678 | * @param msg Message. | ||
1679 | * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; | ||
1680 | */ | ||
1681 | static void | ||
1682 | handle_channel_ack (struct MeshTunnel2 *t, | ||
1683 | struct GNUNET_MESH_ChannelManage *msg, | ||
1684 | int fwd) | ||
1685 | { | ||
1686 | MESH_ChannelNumber chid; | ||
1687 | struct MeshChannel *ch; | ||
1688 | |||
1689 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received Channel ACK\n"); | ||
1690 | /* Check message size */ | ||
1691 | if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelManage)) | ||
1692 | { | ||
1693 | GNUNET_break_op (0); | ||
1694 | return; | ||
1695 | } | ||
1696 | |||
1697 | /* Check if channel exists */ | ||
1698 | chid = ntohl (msg->chid); | ||
1699 | ch = channel_get (t, chid); | ||
1700 | if (NULL == ch) | ||
1701 | { | ||
1702 | GNUNET_break_op (0); | ||
1703 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " channel %u unknown!!\n", chid); | ||
1704 | return; | ||
1705 | } | ||
1706 | |||
1707 | channel_confirm (ch, !fwd); | ||
1708 | } | ||
1709 | |||
1710 | |||
1711 | /** | ||
1712 | * Handler for channel destroy messages. | ||
1713 | * | ||
1714 | * @param t Tunnel this channel is to be destroyed of. | ||
1715 | * @param msg Message. | ||
1716 | * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; | ||
1717 | */ | ||
1718 | static void | ||
1719 | handle_channel_destroy (struct MeshTunnel2 *t, | ||
1720 | struct GNUNET_MESH_ChannelManage *msg, | ||
1721 | int fwd) | ||
1722 | { | ||
1723 | MESH_ChannelNumber chid; | ||
1724 | struct MeshChannel *ch; | ||
1725 | |||
1726 | /* Check message size */ | ||
1727 | if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelManage)) | ||
1728 | { | ||
1729 | GNUNET_break_op (0); | ||
1730 | return; | ||
1731 | } | ||
1732 | |||
1733 | /* Check if channel exists */ | ||
1734 | chid = ntohl (msg->chid); | ||
1735 | ch = channel_get (t, chid); | ||
1736 | if (NULL == ch) | ||
1737 | { | ||
1738 | /* Probably a retransmission, safe to ignore */ | ||
1739 | return; | ||
1740 | } | ||
1741 | if ( (fwd && NULL == ch->dest) || (!fwd && NULL == ch->root) ) | ||
1742 | { | ||
1743 | /* Not for us (don't destroy twice a half-open loopback channel) */ | ||
1744 | return; | ||
1745 | } | ||
1746 | |||
1747 | send_local_channel_destroy (ch, fwd); | ||
1748 | channel_destroy (ch); | ||
1749 | } | ||
1750 | |||
1751 | |||
1752 | static void | 1350 | static void |
1753 | handle_decrypted (struct MeshTunnel2 *t, | 1351 | handle_decrypted (struct MeshTunnel2 *t, |
1754 | const struct GNUNET_MessageHeader *msgh, | 1352 | const struct GNUNET_MessageHeader *msgh, |
@@ -1802,7 +1400,7 @@ handle_decrypted (struct MeshTunnel2 *t, | |||
1802 | static void | 1400 | static void |
1803 | search_handler (void *cls, struct MeshPeerPath *path) | 1401 | search_handler (void *cls, struct MeshPeerPath *path) |
1804 | { | 1402 | { |
1805 | struct MeshConnection *c; | 1403 | // struct MeshConnection *c; |
1806 | unsigned int connection_count; | 1404 | unsigned int connection_count; |
1807 | 1405 | ||
1808 | path_add_to_peers (path, GNUNET_NO); | 1406 | path_add_to_peers (path, GNUNET_NO); |
diff --git a/src/mesh/gnunet-service-mesh_channel.c b/src/mesh/gnunet-service-mesh_channel.c index 822e7e5fe..443193d68 100644 --- a/src/mesh/gnunet-service-mesh_channel.c +++ b/src/mesh/gnunet-service-mesh_channel.c | |||
@@ -920,7 +920,7 @@ channel_destroy (struct MeshChannel *ch) | |||
920 | 920 | ||
921 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying channel %s:%u\n", | 921 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying channel %s:%u\n", |
922 | peer2s (ch->t->peer), ch->gid); | 922 | peer2s (ch->t->peer), ch->gid); |
923 | channel_debug (ch); | 923 | GMCH_debug (ch); |
924 | 924 | ||
925 | c = ch->root; | 925 | c = ch->root; |
926 | if (NULL != c) | 926 | if (NULL != c) |
@@ -1051,6 +1051,7 @@ channel_destroy_iterator (void *cls, | |||
1051 | } | 1051 | } |
1052 | 1052 | ||
1053 | t = ch->t; | 1053 | t = ch->t; |
1054 | GMCH_send_destroy (ch); | ||
1054 | channel_send_destroy (ch); | 1055 | channel_send_destroy (ch); |
1055 | channel_destroy (ch); | 1056 | channel_destroy (ch); |
1056 | tunnel_destroy_if_empty (t); | 1057 | tunnel_destroy_if_empty (t); |
@@ -1107,7 +1108,7 @@ send (const struct GNUNET_MessageHeader *message, | |||
1107 | * @param ch Channel that was created. | 1108 | * @param ch Channel that was created. |
1108 | */ | 1109 | */ |
1109 | void | 1110 | void |
1110 | GMCH_send_channel_create (struct MeshChannel *ch) | 1111 | GMCH_send_create (struct MeshChannel *ch) |
1111 | { | 1112 | { |
1112 | struct GNUNET_MESH_ChannelMessage msg; | 1113 | struct GNUNET_MESH_ChannelMessage msg; |
1113 | struct MeshTunnel2 *t = ch->t; | 1114 | struct MeshTunnel2 *t = ch->t; |
@@ -1131,13 +1132,16 @@ GMCH_send_channel_create (struct MeshChannel *ch) | |||
1131 | * @param fwd Forward notification (owner->dest)? | 1132 | * @param fwd Forward notification (owner->dest)? |
1132 | */ | 1133 | */ |
1133 | void | 1134 | void |
1134 | GMCH_send_channel_destroy (struct MeshChannel *ch, int fwd) | 1135 | GMCH_send_destroy (struct MeshChannel *ch, int fwd) |
1135 | { | 1136 | { |
1136 | struct GNUNET_MeshClient *c = fwd ? ch->dest : ch->root; | 1137 | struct GNUNET_MeshClient *c = fwd ? ch->dest : ch->root; |
1137 | uint32_t id = fwd ? ch->lid_dest : ch->lid_root; | 1138 | uint32_t id = fwd ? ch->lid_dest : ch->lid_root; |
1138 | 1139 | ||
1139 | if (NULL == c) | 1140 | if (NULL == c) |
1141 | { | ||
1142 | // TODO: send on connection? | ||
1140 | return; | 1143 | return; |
1144 | } | ||
1141 | 1145 | ||
1142 | GML_send_channel_destroy (c, id); | 1146 | GML_send_channel_destroy (c, id); |
1143 | } | 1147 | } |
@@ -1250,3 +1254,346 @@ GMCH_debug (struct MeshChannel *ch) | |||
1250 | } | 1254 | } |
1251 | 1255 | ||
1252 | 1256 | ||
1257 | /** | ||
1258 | * Handler for mesh network payload traffic. | ||
1259 | * | ||
1260 | * @param t Tunnel on which we got this message. | ||
1261 | * @param message Unencryted data message. | ||
1262 | * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; | ||
1263 | */ | ||
1264 | void | ||
1265 | GMCH_handle_data (struct MeshTunnel2 *t, | ||
1266 | const struct GNUNET_MESH_Data *msg, | ||
1267 | int fwd) | ||
1268 | { | ||
1269 | struct MeshChannelReliability *rel; | ||
1270 | struct MeshChannel *ch; | ||
1271 | struct MeshClient *c; | ||
1272 | uint32_t mid; | ||
1273 | uint16_t type; | ||
1274 | size_t size; | ||
1275 | |||
1276 | /* Check size */ | ||
1277 | size = ntohs (msg->header.size); | ||
1278 | if (size < | ||
1279 | sizeof (struct GNUNET_MESH_Data) + | ||
1280 | sizeof (struct GNUNET_MessageHeader)) | ||
1281 | { | ||
1282 | GNUNET_break (0); | ||
1283 | return; | ||
1284 | } | ||
1285 | type = ntohs (msg->header.type); | ||
1286 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a %s message\n", | ||
1287 | GNUNET_MESH_DEBUG_M2S (type)); | ||
1288 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " payload of type %s\n", | ||
1289 | GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type))); | ||
1290 | |||
1291 | /* Check channel */ | ||
1292 | ch = channel_get (t, ntohl (msg->chid)); | ||
1293 | if (NULL == ch) | ||
1294 | { | ||
1295 | GNUNET_STATISTICS_update (stats, "# data on unknown channel", 1, GNUNET_NO); | ||
1296 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n", | ||
1297 | ntohl (msg->chid)); | ||
1298 | return; | ||
1299 | } | ||
1300 | |||
1301 | /* Initialize FWD/BCK data */ | ||
1302 | c = fwd ? ch->dest : ch->root; | ||
1303 | rel = fwd ? ch->dest_rel : ch->root_rel; | ||
1304 | |||
1305 | if (NULL == c) | ||
1306 | { | ||
1307 | GNUNET_break (0); | ||
1308 | return; | ||
1309 | } | ||
1310 | |||
1311 | tunnel_change_state (t, MESH_TUNNEL_READY); | ||
1312 | |||
1313 | GNUNET_STATISTICS_update (stats, "# data received", 1, GNUNET_NO); | ||
1314 | |||
1315 | mid = ntohl (msg->mid); | ||
1316 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " mid %u\n", mid); | ||
1317 | |||
1318 | if (GNUNET_NO == ch->reliable || | ||
1319 | ( !GMC_is_pid_bigger (rel->mid_recv, mid) && | ||
1320 | GMC_is_pid_bigger (rel->mid_recv + 64, mid) ) ) | ||
1321 | { | ||
1322 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! RECV %u\n", mid); | ||
1323 | if (GNUNET_YES == ch->reliable) | ||
1324 | { | ||
1325 | /* Is this the exact next expected messasge? */ | ||
1326 | if (mid == rel->mid_recv) | ||
1327 | { | ||
1328 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "as expected\n"); | ||
1329 | rel->mid_recv++; | ||
1330 | send_client_data (ch, msg, fwd); | ||
1331 | } | ||
1332 | else | ||
1333 | { | ||
1334 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "save for later\n"); | ||
1335 | add_buffered_data (msg, rel); | ||
1336 | } | ||
1337 | } | ||
1338 | else | ||
1339 | { | ||
1340 | /* Tunnel is unreliable: send to clients directly */ | ||
1341 | /* FIXME: accept Out Of Order traffic */ | ||
1342 | rel->mid_recv = mid + 1; | ||
1343 | send_client_data (ch, msg, fwd); | ||
1344 | } | ||
1345 | } | ||
1346 | else | ||
1347 | { | ||
1348 | GNUNET_break_op (0); | ||
1349 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1350 | " MID %u not expected (%u - %u), dropping!\n", | ||
1351 | mid, rel->mid_recv, rel->mid_recv + 64); | ||
1352 | } | ||
1353 | |||
1354 | GMCH_send_ack (ch, fwd); | ||
1355 | } | ||
1356 | |||
1357 | |||
1358 | /** | ||
1359 | * Handler for mesh network traffic end-to-end ACKs. | ||
1360 | * | ||
1361 | * @param t Tunnel on which we got this message. | ||
1362 | * @param message Data message. | ||
1363 | * @param fwd Is this a fwd ACK? (dest->orig) | ||
1364 | */ | ||
1365 | void | ||
1366 | GMCH_handle_data_ack (struct MeshTunnel2 *t, | ||
1367 | const struct GNUNET_MESH_DataACK *msg, | ||
1368 | int fwd) | ||
1369 | { | ||
1370 | struct MeshChannelReliability *rel; | ||
1371 | struct MeshReliableMessage *copy; | ||
1372 | struct MeshReliableMessage *next; | ||
1373 | struct MeshChannel *ch; | ||
1374 | uint32_t ack; | ||
1375 | uint16_t type; | ||
1376 | int work; | ||
1377 | |||
1378 | type = ntohs (msg->header.type); | ||
1379 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a %s message!\n", | ||
1380 | GNUNET_MESH_DEBUG_M2S (type)); | ||
1381 | ch = channel_get (t, ntohl (msg->chid)); | ||
1382 | if (NULL == ch) | ||
1383 | { | ||
1384 | GNUNET_STATISTICS_update (stats, "# ack on unknown channel", 1, GNUNET_NO); | ||
1385 | return; | ||
1386 | } | ||
1387 | ack = ntohl (msg->mid); | ||
1388 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! %s ACK %u\n", | ||
1389 | (GNUNET_YES == fwd) ? "FWD" : "BCK", ack); | ||
1390 | |||
1391 | if (GNUNET_YES == fwd) | ||
1392 | { | ||
1393 | rel = ch->root_rel; | ||
1394 | } | ||
1395 | else | ||
1396 | { | ||
1397 | rel = ch->dest_rel; | ||
1398 | } | ||
1399 | if (NULL == rel) | ||
1400 | { | ||
1401 | GNUNET_break (0); | ||
1402 | return; | ||
1403 | } | ||
1404 | |||
1405 | for (work = GNUNET_NO, copy = rel->head_sent; copy != NULL; copy = next) | ||
1406 | { | ||
1407 | if (GMC_is_pid_bigger (copy->mid, ack)) | ||
1408 | { | ||
1409 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! head %u, out!\n", copy->mid); | ||
1410 | channel_rel_free_sent (rel, msg); | ||
1411 | break; | ||
1412 | } | ||
1413 | work = GNUNET_YES; | ||
1414 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! id %u\n", copy->mid); | ||
1415 | next = copy->next; | ||
1416 | rel_message_free (copy); | ||
1417 | } | ||
1418 | /* ACK client if needed */ | ||
1419 | // channel_send_ack (t, type, GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK == type); | ||
1420 | |||
1421 | /* If some message was free'd, update the retransmission delay*/ | ||
1422 | if (GNUNET_YES == work) | ||
1423 | { | ||
1424 | if (GNUNET_SCHEDULER_NO_TASK != rel->retry_task) | ||
1425 | { | ||
1426 | GNUNET_SCHEDULER_cancel (rel->retry_task); | ||
1427 | if (NULL == rel->head_sent) | ||
1428 | { | ||
1429 | rel->retry_task = GNUNET_SCHEDULER_NO_TASK; | ||
1430 | } | ||
1431 | else | ||
1432 | { | ||
1433 | struct GNUNET_TIME_Absolute new_target; | ||
1434 | struct GNUNET_TIME_Relative delay; | ||
1435 | |||
1436 | delay = GNUNET_TIME_relative_multiply (rel->retry_timer, | ||
1437 | MESH_RETRANSMIT_MARGIN); | ||
1438 | new_target = GNUNET_TIME_absolute_add (rel->head_sent->timestamp, | ||
1439 | delay); | ||
1440 | delay = GNUNET_TIME_absolute_get_remaining (new_target); | ||
1441 | rel->retry_task = | ||
1442 | GNUNET_SCHEDULER_add_delayed (delay, | ||
1443 | &channel_retransmit_message, | ||
1444 | rel); | ||
1445 | } | ||
1446 | } | ||
1447 | else | ||
1448 | GNUNET_break (0); | ||
1449 | } | ||
1450 | } | ||
1451 | |||
1452 | |||
1453 | /** | ||
1454 | * Handler for channel create messages. | ||
1455 | * | ||
1456 | * @param t Tunnel this channel is to be created in. | ||
1457 | * @param msg Message. | ||
1458 | * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; | ||
1459 | */ | ||
1460 | void | ||
1461 | GMCH_handle_create (struct MeshTunnel2 *t, | ||
1462 | struct GNUNET_MESH_ChannelCreate *msg, | ||
1463 | int fwd) | ||
1464 | { | ||
1465 | MESH_ChannelNumber chid; | ||
1466 | struct MeshChannel *ch; | ||
1467 | struct MeshClient *c; | ||
1468 | uint32_t port; | ||
1469 | |||
1470 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received Channel Create\n"); | ||
1471 | /* Check message size */ | ||
1472 | if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelCreate)) | ||
1473 | { | ||
1474 | GNUNET_break_op (0); | ||
1475 | return; | ||
1476 | } | ||
1477 | |||
1478 | /* Check if channel exists */ | ||
1479 | chid = ntohl (msg->chid); | ||
1480 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " chid %u\n", chid); | ||
1481 | ch = channel_get (t, chid); | ||
1482 | if (NULL != ch) | ||
1483 | { | ||
1484 | /* Probably a retransmission, safe to ignore */ | ||
1485 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " already exists...\n"); | ||
1486 | if (NULL != ch->dest) | ||
1487 | { | ||
1488 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " duplicate CC!!\n"); | ||
1489 | GMCH_send_ack (ch, !fwd); | ||
1490 | return; | ||
1491 | } | ||
1492 | } | ||
1493 | else | ||
1494 | { | ||
1495 | /* Create channel */ | ||
1496 | ch = channel_new (t, NULL, 0); | ||
1497 | ch->gid = chid; | ||
1498 | channel_set_options (ch, ntohl (msg->opt)); | ||
1499 | } | ||
1500 | |||
1501 | /* Find a destination client */ | ||
1502 | port = ntohl (msg->port); | ||
1503 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " port %u\n", port); | ||
1504 | c = GNUNET_CONTAINER_multihashmap32_get (ports, port); | ||
1505 | if (NULL == c) | ||
1506 | { | ||
1507 | /* TODO send reject */ | ||
1508 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " no client has port registered\n"); | ||
1509 | /* TODO free ch */ | ||
1510 | return; | ||
1511 | } | ||
1512 | |||
1513 | channel_add_client (ch, c); | ||
1514 | if (GNUNET_YES == ch->reliable) | ||
1515 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! Reliable\n"); | ||
1516 | |||
1517 | GMCH_send_create (ch); | ||
1518 | GMCH_send_ack (ch, fwd); | ||
1519 | GML_send_ack (ch, !fwd); | ||
1520 | } | ||
1521 | |||
1522 | |||
1523 | /** | ||
1524 | * Handler for channel ack messages. | ||
1525 | * | ||
1526 | * @param t Tunnel this channel is to be created in. | ||
1527 | * @param msg Message. | ||
1528 | * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; | ||
1529 | */ | ||
1530 | void | ||
1531 | GMCH_handle_ack (struct MeshTunnel2 *t, | ||
1532 | struct GNUNET_MESH_ChannelManage *msg, | ||
1533 | int fwd) | ||
1534 | { | ||
1535 | MESH_ChannelNumber chid; | ||
1536 | struct MeshChannel *ch; | ||
1537 | |||
1538 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received Channel ACK\n"); | ||
1539 | /* Check message size */ | ||
1540 | if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelManage)) | ||
1541 | { | ||
1542 | GNUNET_break_op (0); | ||
1543 | return; | ||
1544 | } | ||
1545 | |||
1546 | /* Check if channel exists */ | ||
1547 | chid = ntohl (msg->chid); | ||
1548 | ch = channel_get (t, chid); | ||
1549 | if (NULL == ch) | ||
1550 | { | ||
1551 | GNUNET_break_op (0); | ||
1552 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " channel %u unknown!!\n", chid); | ||
1553 | return; | ||
1554 | } | ||
1555 | |||
1556 | channel_confirm (ch, !fwd); | ||
1557 | } | ||
1558 | |||
1559 | |||
1560 | /** | ||
1561 | * Handler for channel destroy messages. | ||
1562 | * | ||
1563 | * @param t Tunnel this channel is to be destroyed of. | ||
1564 | * @param msg Message. | ||
1565 | * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; | ||
1566 | */ | ||
1567 | void | ||
1568 | GMCH_handle_destroy (struct MeshTunnel2 *t, | ||
1569 | struct GNUNET_MESH_ChannelManage *msg, | ||
1570 | int fwd) | ||
1571 | { | ||
1572 | MESH_ChannelNumber chid; | ||
1573 | struct MeshChannel *ch; | ||
1574 | |||
1575 | /* Check message size */ | ||
1576 | if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelManage)) | ||
1577 | { | ||
1578 | GNUNET_break_op (0); | ||
1579 | return; | ||
1580 | } | ||
1581 | |||
1582 | /* Check if channel exists */ | ||
1583 | chid = ntohl (msg->chid); | ||
1584 | ch = channel_get (t, chid); | ||
1585 | if (NULL == ch) | ||
1586 | { | ||
1587 | /* Probably a retransmission, safe to ignore */ | ||
1588 | return; | ||
1589 | } | ||
1590 | if ( (fwd && NULL == ch->dest) || (!fwd && NULL == ch->root) ) | ||
1591 | { | ||
1592 | /* Not for us (don't destroy twice a half-open loopback channel) */ | ||
1593 | return; | ||
1594 | } | ||
1595 | |||
1596 | GMCH_send_destroy (ch, fwd); | ||
1597 | channel_destroy (ch); | ||
1598 | } | ||
1599 | |||
diff --git a/src/mesh/gnunet-service-mesh_channel.h b/src/mesh/gnunet-service-mesh_channel.h index 75136b4de..4ee251cac 100644 --- a/src/mesh/gnunet-service-mesh_channel.h +++ b/src/mesh/gnunet-service-mesh_channel.h | |||
@@ -76,7 +76,7 @@ GMCH_send_data (struct MeshChannel *ch, | |||
76 | * @param ch Channel that was created. | 76 | * @param ch Channel that was created. |
77 | */ | 77 | */ |
78 | void | 78 | void |
79 | GMCH_send_channel_create (struct MeshChannel *ch); | 79 | GMCH_send_create (struct MeshChannel *ch); |
80 | 80 | ||
81 | 81 | ||
82 | /** | 82 | /** |
@@ -86,7 +86,7 @@ GMCH_send_channel_create (struct MeshChannel *ch); | |||
86 | * @param fwd Forward notification (owner->dest)? | 86 | * @param fwd Forward notification (owner->dest)? |
87 | */ | 87 | */ |
88 | void | 88 | void |
89 | GMCH_send_channel_destroy (struct MeshChannel *ch, int fwd); | 89 | GMCH_send_destroy (struct MeshChannel *ch, int fwd); |
90 | 90 | ||
91 | 91 | ||
92 | /** | 92 | /** |
@@ -97,6 +97,74 @@ GMCH_send_channel_destroy (struct MeshChannel *ch, int fwd); | |||
97 | void | 97 | void |
98 | GMCH_debug (struct MeshChannel *ch); | 98 | GMCH_debug (struct MeshChannel *ch); |
99 | 99 | ||
100 | |||
101 | /** | ||
102 | * Handler for mesh network payload traffic. | ||
103 | * | ||
104 | * @param t Tunnel on which we got this message. | ||
105 | * @param message Unencryted data message. | ||
106 | * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; | ||
107 | */ | ||
108 | void | ||
109 | GMCH_handle_data (struct MeshTunnel2 *t, | ||
110 | const struct GNUNET_MESH_Data *msg, | ||
111 | int fwd); | ||
112 | |||
113 | |||
114 | /** | ||
115 | * Handler for mesh network traffic end-to-end ACKs. | ||
116 | * | ||
117 | * @param t Tunnel on which we got this message. | ||
118 | * @param message Data message. | ||
119 | * @param fwd Is this a fwd ACK? (dest->orig) | ||
120 | */ | ||
121 | void | ||
122 | GMCH_handle_data_ack (struct MeshTunnel2 *t, | ||
123 | const struct GNUNET_MESH_DataACK *msg, | ||
124 | int fwd); | ||
125 | |||
126 | |||
127 | /** | ||
128 | * Handler for channel create messages. | ||
129 | * | ||
130 | * @param t Tunnel this channel is to be created in. | ||
131 | * @param msg Message. | ||
132 | * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; | ||
133 | */ | ||
134 | void | ||
135 | GMCH_handle_create (struct MeshTunnel2 *t, | ||
136 | struct GNUNET_MESH_ChannelCreate *msg, | ||
137 | int fwd); | ||
138 | |||
139 | |||
140 | /** | ||
141 | * Handler for channel ack messages. | ||
142 | * | ||
143 | * @param t Tunnel this channel is to be created in. | ||
144 | * @param msg Message. | ||
145 | * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; | ||
146 | */ | ||
147 | void | ||
148 | GMCH_handle_ack (struct MeshTunnel2 *t, | ||
149 | struct GNUNET_MESH_ChannelManage *msg, | ||
150 | int fwd); | ||
151 | |||
152 | |||
153 | /** | ||
154 | * Handler for channel destroy messages. | ||
155 | * | ||
156 | * @param t Tunnel this channel is to be destroyed of. | ||
157 | * @param msg Message. | ||
158 | * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; | ||
159 | */ | ||
160 | void | ||
161 | GMCH_handle_destroy (struct MeshTunnel2 *t, | ||
162 | struct GNUNET_MESH_ChannelManage *msg, | ||
163 | int fwd); | ||
164 | |||
165 | |||
166 | |||
167 | |||
100 | #if 0 /* keep Emacsens' auto-indent happy */ | 168 | #if 0 /* keep Emacsens' auto-indent happy */ |
101 | { | 169 | { |
102 | #endif | 170 | #endif |
diff --git a/src/mesh/gnunet-service-mesh_peer.c b/src/mesh/gnunet-service-mesh_peer.c index ece4470e2..c1e3f935b 100644 --- a/src/mesh/gnunet-service-mesh_peer.c +++ b/src/mesh/gnunet-service-mesh_peer.c | |||
@@ -354,7 +354,7 @@ peer_get_path_cost (const struct MeshPeer *peer, | |||
354 | } | 354 | } |
355 | } | 355 | } |
356 | } | 356 | } |
357 | return (path->length + overlap) * (path->score * -1); | 357 | return (path->length + overlap) * (path->score * -1); |
358 | } | 358 | } |
359 | 359 | ||
360 | 360 | ||