diff options
Diffstat (limited to 'src/stream/stream_api.c')
-rw-r--r-- | src/stream/stream_api.c | 415 |
1 files changed, 319 insertions, 96 deletions
diff --git a/src/stream/stream_api.c b/src/stream/stream_api.c index 9ae34752c..ef0065b22 100644 --- a/src/stream/stream_api.c +++ b/src/stream/stream_api.c | |||
@@ -696,7 +696,7 @@ ack_task (void *cls, | |||
696 | return; | 696 | return; |
697 | } | 697 | } |
698 | 698 | ||
699 | socket->ack_task_id = 0; | 699 | socket->ack_task_id = GNUNET_SCHEDULER_NO_TASK; |
700 | 700 | ||
701 | /* Create the ACK Message */ | 701 | /* Create the ACK Message */ |
702 | ack_msg = GNUNET_malloc (sizeof (struct GNUNET_STREAM_AckMessage)); | 702 | ack_msg = GNUNET_malloc (sizeof (struct GNUNET_STREAM_AckMessage)); |
@@ -1562,6 +1562,141 @@ client_handle_transmit_close (void *cls, | |||
1562 | 1562 | ||
1563 | 1563 | ||
1564 | /** | 1564 | /** |
1565 | * Generic handler for GNUNET_MESSAGE_TYPE_STREAM_*_CLOSE_ACK messages | ||
1566 | * | ||
1567 | * @param socket the socket | ||
1568 | * @param tunnel connection to the other end | ||
1569 | * @param sender who sent the message | ||
1570 | * @param message the actual message | ||
1571 | * @param atsi performance data for the connection | ||
1572 | * @param operation the close operation which is being ACK'ed | ||
1573 | * @return GNUNET_OK to keep the connection open, | ||
1574 | * GNUNET_SYSERR to close it (signal serious error) | ||
1575 | */ | ||
1576 | static int | ||
1577 | handle_generic_close_ack (struct GNUNET_STREAM_Socket *socket, | ||
1578 | struct GNUNET_MESH_Tunnel *tunnel, | ||
1579 | const struct GNUNET_PeerIdentity *sender, | ||
1580 | const struct GNUNET_STREAM_MessageHeader *message, | ||
1581 | const struct GNUNET_ATS_Information *atsi, | ||
1582 | int operation) | ||
1583 | { | ||
1584 | struct GNUNET_STREAM_ShutdownHandle *shutdown_handle; | ||
1585 | |||
1586 | shutdown_handle = socket->shutdown_handle; | ||
1587 | if (NULL == shutdown_handle) | ||
1588 | { | ||
1589 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1590 | "%x: Received *CLOSE_ACK when shutdown handle is NULL\n", | ||
1591 | socket->our_id); | ||
1592 | return GNUNET_OK; | ||
1593 | } | ||
1594 | |||
1595 | switch (operation) | ||
1596 | { | ||
1597 | case SHUT_RDWR: | ||
1598 | switch (socket->state) | ||
1599 | { | ||
1600 | case STATE_CLOSE_WAIT: | ||
1601 | if (SHUT_RDWR != shutdown_handle->operation) | ||
1602 | { | ||
1603 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1604 | "%x: Received CLOSE_ACK when shutdown handle " | ||
1605 | "is not for SHUT_RDWR\n", | ||
1606 | socket->our_id); | ||
1607 | return GNUNET_OK; | ||
1608 | } | ||
1609 | |||
1610 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1611 | "%x: Received CLOSE_ACK from %x\n", | ||
1612 | socket->our_id, | ||
1613 | socket->other_peer); | ||
1614 | socket->state = STATE_CLOSED; | ||
1615 | break; | ||
1616 | default: | ||
1617 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1618 | "%x: Received CLOSE_ACK when in it not expected\n", | ||
1619 | socket->our_id); | ||
1620 | return GNUNET_OK; | ||
1621 | } | ||
1622 | break; | ||
1623 | |||
1624 | case SHUT_RD: | ||
1625 | switch (socket->state) | ||
1626 | { | ||
1627 | case STATE_RECEIVE_CLOSE_WAIT: | ||
1628 | if (SHUT_RD != shutdown_handle->operation) | ||
1629 | { | ||
1630 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1631 | "%x: Received RECEIVE_CLOSE_ACK when shutdown handle " | ||
1632 | "is not for SHUT_RD\n", | ||
1633 | socket->our_id); | ||
1634 | return GNUNET_OK; | ||
1635 | } | ||
1636 | |||
1637 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1638 | "%x: Received RECEIVE_CLOSE_ACK from %x\n", | ||
1639 | socket->our_id, | ||
1640 | socket->other_peer); | ||
1641 | socket->state = STATE_RECEIVE_CLOSED; | ||
1642 | break; | ||
1643 | default: | ||
1644 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1645 | "%x: Received RECEIVE_CLOSE_ACK when in it not expected\n", | ||
1646 | socket->our_id); | ||
1647 | return GNUNET_OK; | ||
1648 | } | ||
1649 | |||
1650 | break; | ||
1651 | case SHUT_WR: | ||
1652 | switch (socket->state) | ||
1653 | { | ||
1654 | case STATE_TRANSMIT_CLOSE_WAIT: | ||
1655 | if (SHUT_WR != shutdown_handle->operation) | ||
1656 | { | ||
1657 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1658 | "%x: Received TRANSMIT_CLOSE_ACK when shutdown handle " | ||
1659 | "is not for SHUT_WR\n", | ||
1660 | socket->our_id); | ||
1661 | return GNUNET_OK; | ||
1662 | } | ||
1663 | |||
1664 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1665 | "%x: Received TRAMSMIT_CLOSE_ACK from %x\n", | ||
1666 | socket->our_id, | ||
1667 | socket->other_peer); | ||
1668 | socket->state = STATE_TRANSMIT_CLOSED; | ||
1669 | break; | ||
1670 | default: | ||
1671 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1672 | "%x: Received TRANSMIT_CLOSE_ACK when in it not expected\n", | ||
1673 | socket->our_id); | ||
1674 | |||
1675 | return GNUNET_OK; | ||
1676 | } | ||
1677 | break; | ||
1678 | default: | ||
1679 | GNUNET_assert (0); | ||
1680 | } | ||
1681 | |||
1682 | if (NULL != shutdown_handle->completion_cb) /* Shutdown completion */ | ||
1683 | shutdown_handle->completion_cb(shutdown_handle->completion_cls, | ||
1684 | operation); | ||
1685 | GNUNET_free (shutdown_handle); /* Free shutdown handle */ | ||
1686 | socket->shutdown_handle = NULL; | ||
1687 | if (GNUNET_SCHEDULER_NO_TASK | ||
1688 | != shutdown_handle->close_msg_retransmission_task_id) | ||
1689 | { | ||
1690 | GNUNET_SCHEDULER_cancel | ||
1691 | (shutdown_handle->close_msg_retransmission_task_id); | ||
1692 | shutdown_handle->close_msg_retransmission_task_id = | ||
1693 | GNUNET_SCHEDULER_NO_TASK; | ||
1694 | } | ||
1695 | return GNUNET_OK; | ||
1696 | } | ||
1697 | |||
1698 | |||
1699 | /** | ||
1565 | * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_TRANSMIT_CLOSE_ACK | 1700 | * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_TRANSMIT_CLOSE_ACK |
1566 | * | 1701 | * |
1567 | * @param cls the socket (set from GNUNET_MESH_connect) | 1702 | * @param cls the socket (set from GNUNET_MESH_connect) |
@@ -1583,6 +1718,67 @@ client_handle_transmit_close_ack (void *cls, | |||
1583 | { | 1718 | { |
1584 | struct GNUNET_STREAM_Socket *socket = cls; | 1719 | struct GNUNET_STREAM_Socket *socket = cls; |
1585 | 1720 | ||
1721 | return handle_generic_close_ack (socket, | ||
1722 | tunnel, | ||
1723 | sender, | ||
1724 | (const struct GNUNET_STREAM_MessageHeader *) | ||
1725 | message, | ||
1726 | atsi, | ||
1727 | SHUT_WR); | ||
1728 | } | ||
1729 | |||
1730 | |||
1731 | /** | ||
1732 | * Generic handler for GNUNET_MESSAGE_TYPE_STREAM_RECEIVE_CLOSE | ||
1733 | * | ||
1734 | * @param socket the socket | ||
1735 | * @param tunnel connection to the other end | ||
1736 | * @param sender who sent the message | ||
1737 | * @param message the actual message | ||
1738 | * @param atsi performance data for the connection | ||
1739 | * @return GNUNET_OK to keep the connection open, | ||
1740 | * GNUNET_SYSERR to close it (signal serious error) | ||
1741 | */ | ||
1742 | static int | ||
1743 | handle_receive_close (struct GNUNET_STREAM_Socket *socket, | ||
1744 | struct GNUNET_MESH_Tunnel *tunnel, | ||
1745 | const struct GNUNET_PeerIdentity *sender, | ||
1746 | const struct GNUNET_STREAM_MessageHeader *message, | ||
1747 | const struct GNUNET_ATS_Information *atsi) | ||
1748 | { | ||
1749 | struct GNUNET_STREAM_MessageHeader *receive_close_ack; | ||
1750 | |||
1751 | switch (socket->state) | ||
1752 | { | ||
1753 | case STATE_INIT: | ||
1754 | case STATE_LISTEN: | ||
1755 | case STATE_HELLO_WAIT: | ||
1756 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1757 | "%x: Ignoring RECEIVE_CLOSE as it cannot be handled now\n", | ||
1758 | socket->our_id); | ||
1759 | return GNUNET_OK; | ||
1760 | default: | ||
1761 | break; | ||
1762 | } | ||
1763 | |||
1764 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1765 | "%x: Received RECEIVE_CLOSE from %x\n", | ||
1766 | socket->our_id, | ||
1767 | socket->other_peer); | ||
1768 | receive_close_ack = | ||
1769 | GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader)); | ||
1770 | receive_close_ack->header.size = | ||
1771 | htons (sizeof (struct GNUNET_STREAM_MessageHeader)); | ||
1772 | receive_close_ack->header.type = | ||
1773 | htons (GNUNET_MESSAGE_TYPE_STREAM_RECEIVE_CLOSE_ACK); | ||
1774 | queue_message (socket, | ||
1775 | receive_close_ack, | ||
1776 | &set_state_closed, | ||
1777 | NULL); | ||
1778 | |||
1779 | /* FIXME: Handle the case where write handle is present; the write operation | ||
1780 | should be deemed as finised and the write continuation callback | ||
1781 | has to be called with the stream status GNUNET_STREAM_SHUTDOWN */ | ||
1586 | return GNUNET_OK; | 1782 | return GNUNET_OK; |
1587 | } | 1783 | } |
1588 | 1784 | ||
@@ -1609,7 +1805,12 @@ client_handle_receive_close (void *cls, | |||
1609 | { | 1805 | { |
1610 | struct GNUNET_STREAM_Socket *socket = cls; | 1806 | struct GNUNET_STREAM_Socket *socket = cls; |
1611 | 1807 | ||
1612 | return GNUNET_OK; | 1808 | return |
1809 | handle_receive_close (socket, | ||
1810 | tunnel, | ||
1811 | sender, | ||
1812 | (const struct GNUNET_STREAM_MessageHeader *) message, | ||
1813 | atsi); | ||
1613 | } | 1814 | } |
1614 | 1815 | ||
1615 | 1816 | ||
@@ -1635,7 +1836,13 @@ client_handle_receive_close_ack (void *cls, | |||
1635 | { | 1836 | { |
1636 | struct GNUNET_STREAM_Socket *socket = cls; | 1837 | struct GNUNET_STREAM_Socket *socket = cls; |
1637 | 1838 | ||
1638 | return GNUNET_OK; | 1839 | return handle_generic_close_ack (socket, |
1840 | tunnel, | ||
1841 | sender, | ||
1842 | (const struct GNUNET_STREAM_MessageHeader *) | ||
1843 | message, | ||
1844 | atsi, | ||
1845 | SHUT_RD); | ||
1639 | } | 1846 | } |
1640 | 1847 | ||
1641 | 1848 | ||
@@ -1659,6 +1866,19 @@ handle_close (struct GNUNET_STREAM_Socket *socket, | |||
1659 | { | 1866 | { |
1660 | struct GNUNET_STREAM_MessageHeader *close_ack; | 1867 | struct GNUNET_STREAM_MessageHeader *close_ack; |
1661 | 1868 | ||
1869 | switch (socket->state) | ||
1870 | { | ||
1871 | case STATE_INIT: | ||
1872 | case STATE_LISTEN: | ||
1873 | case STATE_HELLO_WAIT: | ||
1874 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1875 | "%x: Ignoring RECEIVE_CLOSE as it cannot be handled now\n", | ||
1876 | socket->our_id); | ||
1877 | return GNUNET_OK; | ||
1878 | default: | ||
1879 | break; | ||
1880 | } | ||
1881 | |||
1662 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1882 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1663 | "%x: Received CLOSE from %x\n", | 1883 | "%x: Received CLOSE from %x\n", |
1664 | socket->our_id, | 1884 | socket->our_id, |
@@ -1711,69 +1931,6 @@ client_handle_close (void *cls, | |||
1711 | 1931 | ||
1712 | 1932 | ||
1713 | /** | 1933 | /** |
1714 | * Generic handler for GNUNET_MESSAGE_TYPE_STREAM_CLOSE_ACK | ||
1715 | * | ||
1716 | * @param socket the socket | ||
1717 | * @param tunnel connection to the other end | ||
1718 | * @param sender who sent the message | ||
1719 | * @param message the actual message | ||
1720 | * @param atsi performance data for the connection | ||
1721 | * @return GNUNET_OK to keep the connection open, | ||
1722 | * GNUNET_SYSERR to close it (signal serious error) | ||
1723 | */ | ||
1724 | static int | ||
1725 | handle_close_ack (struct GNUNET_STREAM_Socket *socket, | ||
1726 | struct GNUNET_MESH_Tunnel *tunnel, | ||
1727 | const struct GNUNET_PeerIdentity *sender, | ||
1728 | const struct GNUNET_STREAM_MessageHeader *message, | ||
1729 | const struct GNUNET_ATS_Information *atsi) | ||
1730 | { | ||
1731 | struct GNUNET_STREAM_ShutdownHandle *shutdown_handle; | ||
1732 | |||
1733 | shutdown_handle = socket->shutdown_handle; | ||
1734 | switch (socket->state) | ||
1735 | { | ||
1736 | case STATE_CLOSE_WAIT: | ||
1737 | if ( (NULL == shutdown_handle) || | ||
1738 | (SHUT_RDWR != shutdown_handle->operation) ) | ||
1739 | { | ||
1740 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1741 | "%x: Received CLOSE_ACK when shutdown handle is NULL or " | ||
1742 | "not for SHUT_RDWR\n", | ||
1743 | socket->our_id); | ||
1744 | return GNUNET_OK; | ||
1745 | } | ||
1746 | |||
1747 | if (GNUNET_SCHEDULER_NO_TASK | ||
1748 | != shutdown_handle->close_msg_retransmission_task_id) | ||
1749 | { | ||
1750 | GNUNET_SCHEDULER_cancel | ||
1751 | (shutdown_handle->close_msg_retransmission_task_id); | ||
1752 | shutdown_handle->close_msg_retransmission_task_id = | ||
1753 | GNUNET_SCHEDULER_NO_TASK; | ||
1754 | } | ||
1755 | |||
1756 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1757 | "%x: Received CLOSE_ACK from %x\n", | ||
1758 | socket->our_id, | ||
1759 | socket->other_peer); | ||
1760 | socket->state = STATE_CLOSED; | ||
1761 | if (NULL != shutdown_handle->completion_cb) /* Shutdown completion */ | ||
1762 | shutdown_handle->completion_cb(shutdown_handle->completion_cls, | ||
1763 | SHUT_RDWR); | ||
1764 | GNUNET_free (shutdown_handle); /* Free shutdown handle */ | ||
1765 | break; | ||
1766 | default: | ||
1767 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1768 | "%x: Received CLOSE_ACK when in it not expected\n", | ||
1769 | socket->our_id); | ||
1770 | break; | ||
1771 | } | ||
1772 | return GNUNET_OK; | ||
1773 | } | ||
1774 | |||
1775 | |||
1776 | /** | ||
1777 | * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_CLOSE_ACK | 1934 | * Client's message handler for GNUNET_MESSAGE_TYPE_STREAM_CLOSE_ACK |
1778 | * | 1935 | * |
1779 | * @param cls the socket (set from GNUNET_MESH_connect) | 1936 | * @param cls the socket (set from GNUNET_MESH_connect) |
@@ -1795,12 +1952,13 @@ client_handle_close_ack (void *cls, | |||
1795 | { | 1952 | { |
1796 | struct GNUNET_STREAM_Socket *socket = cls; | 1953 | struct GNUNET_STREAM_Socket *socket = cls; |
1797 | 1954 | ||
1798 | return handle_close_ack (socket, | 1955 | return handle_generic_close_ack (socket, |
1799 | tunnel, | 1956 | tunnel, |
1800 | sender, | 1957 | sender, |
1801 | (const struct GNUNET_STREAM_MessageHeader *) | 1958 | (const struct GNUNET_STREAM_MessageHeader *) |
1802 | message, | 1959 | message, |
1803 | atsi); | 1960 | atsi, |
1961 | SHUT_RDWR); | ||
1804 | } | 1962 | } |
1805 | 1963 | ||
1806 | /*****************************/ | 1964 | /*****************************/ |
@@ -2027,7 +2185,13 @@ server_handle_transmit_close_ack (void *cls, | |||
2027 | { | 2185 | { |
2028 | struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; | 2186 | struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; |
2029 | 2187 | ||
2030 | return GNUNET_OK; | 2188 | return handle_generic_close_ack (socket, |
2189 | tunnel, | ||
2190 | sender, | ||
2191 | (const struct GNUNET_STREAM_MessageHeader *) | ||
2192 | message, | ||
2193 | atsi, | ||
2194 | SHUT_WR); | ||
2031 | } | 2195 | } |
2032 | 2196 | ||
2033 | 2197 | ||
@@ -2053,7 +2217,12 @@ server_handle_receive_close (void *cls, | |||
2053 | { | 2217 | { |
2054 | struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; | 2218 | struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; |
2055 | 2219 | ||
2056 | return GNUNET_OK; | 2220 | return |
2221 | handle_receive_close (socket, | ||
2222 | tunnel, | ||
2223 | sender, | ||
2224 | (const struct GNUNET_STREAM_MessageHeader *) message, | ||
2225 | atsi); | ||
2057 | } | 2226 | } |
2058 | 2227 | ||
2059 | 2228 | ||
@@ -2079,7 +2248,13 @@ server_handle_receive_close_ack (void *cls, | |||
2079 | { | 2248 | { |
2080 | struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; | 2249 | struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; |
2081 | 2250 | ||
2082 | return GNUNET_OK; | 2251 | return handle_generic_close_ack (socket, |
2252 | tunnel, | ||
2253 | sender, | ||
2254 | (const struct GNUNET_STREAM_MessageHeader *) | ||
2255 | message, | ||
2256 | atsi, | ||
2257 | SHUT_RD); | ||
2083 | } | 2258 | } |
2084 | 2259 | ||
2085 | 2260 | ||
@@ -2136,16 +2311,18 @@ server_handle_close_ack (void *cls, | |||
2136 | { | 2311 | { |
2137 | struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; | 2312 | struct GNUNET_STREAM_Socket *socket = *tunnel_ctx; |
2138 | 2313 | ||
2139 | return handle_close_ack (socket, | 2314 | return handle_generic_close_ack (socket, |
2140 | tunnel, | 2315 | tunnel, |
2141 | sender, | 2316 | sender, |
2142 | (const struct GNUNET_STREAM_MessageHeader *) message, | 2317 | (const struct GNUNET_STREAM_MessageHeader *) |
2143 | atsi); | 2318 | message, |
2319 | atsi, | ||
2320 | SHUT_RDWR); | ||
2144 | } | 2321 | } |
2145 | 2322 | ||
2146 | 2323 | ||
2147 | /** | 2324 | /** |
2148 | * Message Handler for mesh | 2325 | * Handler for DATA_ACK messages |
2149 | * | 2326 | * |
2150 | * @param socket the socket through which the ack was received | 2327 | * @param socket the socket through which the ack was received |
2151 | * @param tunnel connection to the other end | 2328 | * @param tunnel connection to the other end |
@@ -2177,6 +2354,8 @@ handle_ack (struct GNUNET_STREAM_Socket *socket, | |||
2177 | switch (socket->state) | 2354 | switch (socket->state) |
2178 | { | 2355 | { |
2179 | case (STATE_ESTABLISHED): | 2356 | case (STATE_ESTABLISHED): |
2357 | case (STATE_RECEIVE_CLOSED): | ||
2358 | case (STATE_RECEIVE_CLOSE_WAIT): | ||
2180 | if (NULL == socket->write_handle) | 2359 | if (NULL == socket->write_handle) |
2181 | { | 2360 | { |
2182 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2361 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -2284,7 +2463,7 @@ handle_ack (struct GNUNET_STREAM_Socket *socket, | |||
2284 | 2463 | ||
2285 | 2464 | ||
2286 | /** | 2465 | /** |
2287 | * Message Handler for mesh | 2466 | * Handler for DATA_ACK messages |
2288 | * | 2467 | * |
2289 | * @param cls the 'struct GNUNET_STREAM_Socket' | 2468 | * @param cls the 'struct GNUNET_STREAM_Socket' |
2290 | * @param tunnel connection to the other end | 2469 | * @param tunnel connection to the other end |
@@ -2311,7 +2490,7 @@ client_handle_ack (void *cls, | |||
2311 | 2490 | ||
2312 | 2491 | ||
2313 | /** | 2492 | /** |
2314 | * Message Handler for mesh | 2493 | * Handler for DATA_ACK messages |
2315 | * | 2494 | * |
2316 | * @param cls the server's listen socket | 2495 | * @param cls the server's listen socket |
2317 | * @param tunnel connection to the other end | 2496 | * @param tunnel connection to the other end |
@@ -2855,15 +3034,22 @@ GNUNET_STREAM_listen_close (struct GNUNET_STREAM_ListenSocket *lsocket) | |||
2855 | 3034 | ||
2856 | 3035 | ||
2857 | /** | 3036 | /** |
2858 | * Tries to write the given data to the stream | 3037 | * Tries to write the given data to the stream. The maximum size of data that |
3038 | * can be written as part of a write operation is (64 * (64000 - sizeof (struct | ||
3039 | * GNUNET_STREAM_DataMessage))). If size is greater than this it is not an API | ||
3040 | * violation, however only the said number of maximum bytes will be written. | ||
2859 | * | 3041 | * |
2860 | * @param socket the socket representing a stream | 3042 | * @param socket the socket representing a stream |
2861 | * @param data the data buffer from where the data is written into the stream | 3043 | * @param data the data buffer from where the data is written into the stream |
2862 | * @param size the number of bytes to be written from the data buffer | 3044 | * @param size the number of bytes to be written from the data buffer |
2863 | * @param timeout the timeout period | 3045 | * @param timeout the timeout period |
2864 | * @param write_cont the function to call upon writing some bytes into the stream | 3046 | * @param write_cont the function to call upon writing some bytes into the |
3047 | * stream | ||
2865 | * @param write_cont_cls the closure | 3048 | * @param write_cont_cls the closure |
2866 | * @return handle to cancel the operation | 3049 | * |
3050 | * @return handle to cancel the operation; if a previous write is pending or | ||
3051 | * the stream has been shutdown for this operation then write_cont is | ||
3052 | * immediately called and NULL is returned. | ||
2867 | */ | 3053 | */ |
2868 | struct GNUNET_STREAM_IOWriteHandle * | 3054 | struct GNUNET_STREAM_IOWriteHandle * |
2869 | GNUNET_STREAM_write (struct GNUNET_STREAM_Socket *socket, | 3055 | GNUNET_STREAM_write (struct GNUNET_STREAM_Socket *socket, |
@@ -2891,16 +3077,33 @@ GNUNET_STREAM_write (struct GNUNET_STREAM_Socket *socket, | |||
2891 | GNUNET_break (0); | 3077 | GNUNET_break (0); |
2892 | return NULL; | 3078 | return NULL; |
2893 | } | 3079 | } |
2894 | if (!((STATE_ESTABLISHED == socket->state) | 3080 | |
2895 | || (STATE_RECEIVE_CLOSE_WAIT == socket->state) | 3081 | switch (socket->state) |
2896 | || (STATE_RECEIVE_CLOSED == socket->state))) | ||
2897 | { | 3082 | { |
2898 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 3083 | case STATE_TRANSMIT_CLOSED: |
2899 | "%x: Attempting to write on a closed (OR) not-yet-established" | 3084 | case STATE_TRANSMIT_CLOSE_WAIT: |
2900 | "stream\n", | 3085 | case STATE_CLOSED: |
2901 | socket->our_id); | 3086 | case STATE_CLOSE_WAIT: |
3087 | if (NULL != write_cont) | ||
3088 | write_cont (write_cont_cls, GNUNET_STREAM_SHUTDOWN, 0); | ||
3089 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3090 | "%s() END\n", __func__); | ||
3091 | return NULL; | ||
3092 | case STATE_INIT: | ||
3093 | case STATE_LISTEN: | ||
3094 | case STATE_HELLO_WAIT: | ||
3095 | if (NULL != write_cont) | ||
3096 | /* FIXME: GNUNET_STREAM_SYSERR?? */ | ||
3097 | write_cont (write_cont_cls, GNUNET_STREAM_SYSERR, 0); | ||
3098 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3099 | "%s() END\n", __func__); | ||
2902 | return NULL; | 3100 | return NULL; |
2903 | } | 3101 | case STATE_ESTABLISHED: |
3102 | case STATE_RECEIVE_CLOSED: | ||
3103 | case STATE_RECEIVE_CLOSE_WAIT: | ||
3104 | break; | ||
3105 | } | ||
3106 | |||
2904 | if (GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH * max_payload_size < size) | 3107 | if (GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH * max_payload_size < size) |
2905 | size = GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH * max_payload_size; | 3108 | size = GNUNET_STREAM_ACK_BITMAP_BIT_LENGTH * max_payload_size; |
2906 | num_needed_packets = (size + (max_payload_size - 1)) / max_payload_size; | 3109 | num_needed_packets = (size + (max_payload_size - 1)) / max_payload_size; |
@@ -2957,14 +3160,18 @@ GNUNET_STREAM_write (struct GNUNET_STREAM_Socket *socket, | |||
2957 | } | 3160 | } |
2958 | 3161 | ||
2959 | 3162 | ||
3163 | |||
2960 | /** | 3164 | /** |
2961 | * Tries to read data from the stream | 3165 | * Tries to read data from the stream. |
2962 | * | 3166 | * |
2963 | * @param socket the socket representing a stream | 3167 | * @param socket the socket representing a stream |
2964 | * @param timeout the timeout period | 3168 | * @param timeout the timeout period |
2965 | * @param proc function to call with data (once only) | 3169 | * @param proc function to call with data (once only) |
2966 | * @param proc_cls the closure for proc | 3170 | * @param proc_cls the closure for proc |
2967 | * @return handle to cancel the operation | 3171 | * |
3172 | * @return handle to cancel the operation; if the stream has been shutdown for | ||
3173 | * this type of opeartion then the DataProcessor is immediately | ||
3174 | * called with GNUNET_STREAM_SHUTDOWN as status and NULL if returned | ||
2968 | */ | 3175 | */ |
2969 | struct GNUNET_STREAM_IOReadHandle * | 3176 | struct GNUNET_STREAM_IOReadHandle * |
2970 | GNUNET_STREAM_read (struct GNUNET_STREAM_Socket *socket, | 3177 | GNUNET_STREAM_read (struct GNUNET_STREAM_Socket *socket, |
@@ -2985,6 +3192,22 @@ GNUNET_STREAM_read (struct GNUNET_STREAM_Socket *socket, | |||
2985 | 3192 | ||
2986 | GNUNET_assert (NULL != proc); | 3193 | GNUNET_assert (NULL != proc); |
2987 | 3194 | ||
3195 | switch (socket->state) | ||
3196 | { | ||
3197 | case STATE_RECEIVE_CLOSED: | ||
3198 | case STATE_RECEIVE_CLOSE_WAIT: | ||
3199 | case STATE_CLOSED: | ||
3200 | case STATE_CLOSE_WAIT: | ||
3201 | proc (proc_cls, GNUNET_STREAM_SHUTDOWN, NULL, 0); | ||
3202 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3203 | "%x: %s() END\n", | ||
3204 | socket->our_id, | ||
3205 | __func__); | ||
3206 | return NULL; | ||
3207 | default: | ||
3208 | break; | ||
3209 | } | ||
3210 | |||
2988 | read_handle = GNUNET_malloc (sizeof (struct GNUNET_STREAM_IOReadHandle)); | 3211 | read_handle = GNUNET_malloc (sizeof (struct GNUNET_STREAM_IOReadHandle)); |
2989 | read_handle->proc = proc; | 3212 | read_handle->proc = proc; |
2990 | read_handle->proc_cls = proc_cls; | 3213 | read_handle->proc_cls = proc_cls; |