| 1753 | } |
| 1754 | |
| 1755 | void SSU2Session::HandlePayload (const uint8_t * buf, size_t len) |
| 1756 | { |
| 1757 | size_t offset = 0; |
| 1758 | while (offset < len) |
| 1759 | { |
| 1760 | uint8_t blk = buf[offset]; |
| 1761 | offset++; |
| 1762 | auto size = bufbe16toh (buf + offset); |
| 1763 | offset += 2; |
| 1764 | LogPrint (eLogDebug, "SSU2: Block type ", (int)blk, " of size ", size); |
| 1765 | if (offset + size > len) |
| 1766 | { |
| 1767 | LogPrint (eLogError, "SSU2: Unexpected block length ", size); |
| 1768 | break; |
| 1769 | } |
| 1770 | switch (blk) |
| 1771 | { |
| 1772 | case eSSU2BlkDateTime: |
| 1773 | LogPrint (eLogDebug, "SSU2: Datetime"); |
| 1774 | HandleDateTime (buf + offset, size); |
| 1775 | break; |
| 1776 | case eSSU2BlkOptions: |
| 1777 | LogPrint (eLogDebug, "SSU2: Options"); |
| 1778 | break; |
| 1779 | case eSSU2BlkRouterInfo: |
| 1780 | LogPrint (eLogDebug, "SSU2: RouterInfo"); |
| 1781 | HandleRouterInfo (buf + offset, size); |
| 1782 | break; |
| 1783 | case eSSU2BlkI2NPMessage: |
| 1784 | { |
| 1785 | LogPrint (eLogDebug, "SSU2: I2NP message"); |
| 1786 | auto nextMsg = (buf[offset] == eI2NPTunnelData) ? NewI2NPTunnelMessage (true) : NewI2NPShortMessage (); |
| 1787 | nextMsg->len = nextMsg->offset + size + 7; // 7 more bytes for full I2NP header |
| 1788 | memcpy (nextMsg->GetNTCP2Header (), buf + offset, size); |
| 1789 | nextMsg->FromNTCP2 (); // SSU2 has the same format as NTCP2 |
| 1790 | HandleI2NPMsg (std::move (nextMsg)); |
| 1791 | m_IsDataReceived = true; |
| 1792 | break; |
| 1793 | } |
| 1794 | case eSSU2BlkFirstFragment: |
| 1795 | LogPrint (eLogDebug, "SSU2: First fragment"); |
| 1796 | HandleFirstFragment (buf + offset, size); |
| 1797 | m_IsDataReceived = true; |
| 1798 | break; |
| 1799 | case eSSU2BlkFollowOnFragment: |
| 1800 | LogPrint (eLogDebug, "SSU2: Follow-on fragment"); |
| 1801 | HandleFollowOnFragment (buf + offset, size); |
| 1802 | m_IsDataReceived = true; |
| 1803 | break; |
| 1804 | case eSSU2BlkTermination: |
| 1805 | { |
| 1806 | if (size >= 9) |
| 1807 | { |
| 1808 | uint8_t rsn = buf[offset + 8]; // reason |
| 1809 | LogPrint (eLogDebug, "SSU2: Termination reason=", (int)rsn); |
| 1810 | if (IsEstablished () && rsn != eSSU2TerminationReasonTerminationReceived) |
| 1811 | RequestTermination (eSSU2TerminationReasonTerminationReceived); |
| 1812 | else if (m_State != eSSU2SessionStateTerminated) |
nothing calls this directly
no test coverage detected