| 694 | } |
| 695 | |
| 696 | void SSU2Server::ProcessNextPacket (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint) |
| 697 | { |
| 698 | if (len < 24) return; |
| 699 | uint64_t connID; |
| 700 | memcpy (&connID, buf, 8); |
| 701 | connID ^= CreateHeaderMask (i2p::context.GetSSU2IntroKey (), buf + (len - 24)); |
| 702 | if (!m_LastSession || m_LastSession->GetConnID () != connID) |
| 703 | { |
| 704 | if (m_LastSession) m_LastSession->FlushData (); |
| 705 | auto it = m_Sessions.find (connID); |
| 706 | if (it != m_Sessions.end ()) |
| 707 | m_LastSession = it->second; |
| 708 | else |
| 709 | m_LastSession = nullptr; |
| 710 | } |
| 711 | if (m_LastSession) |
| 712 | { |
| 713 | switch (m_LastSession->GetState ()) |
| 714 | { |
| 715 | case eSSU2SessionStateEstablished: |
| 716 | case eSSU2SessionStateSessionConfirmedSent: |
| 717 | m_LastSession->ProcessData (buf, len, senderEndpoint); |
| 718 | break; |
| 719 | case eSSU2SessionStateSessionCreatedSent: |
| 720 | if (!m_LastSession->ProcessSessionConfirmed (buf, len)) |
| 721 | { |
| 722 | m_LastSession->Done (); |
| 723 | m_LastSession = nullptr; |
| 724 | } |
| 725 | break; |
| 726 | case eSSU2SessionStateIntroduced: |
| 727 | if (m_LastSession->GetRemoteEndpoint ().address ().is_unspecified ()) |
| 728 | m_LastSession->SetRemoteEndpoint (senderEndpoint); |
| 729 | if (m_LastSession->GetRemoteEndpoint ().address () == senderEndpoint.address ()) // port might be different |
| 730 | m_LastSession->ProcessHolePunch (buf, len); |
| 731 | else |
| 732 | { |
| 733 | LogPrint (eLogWarning, "SSU2: HolePunch address ", senderEndpoint.address (), |
| 734 | " doesn't match RelayResponse ", m_LastSession->GetRemoteEndpoint ().address ()); |
| 735 | m_LastSession->Done (); |
| 736 | m_LastSession = nullptr; |
| 737 | } |
| 738 | break; |
| 739 | case eSSU2SessionStatePeerTest: |
| 740 | m_LastSession->SetRemoteEndpoint (senderEndpoint); |
| 741 | m_LastSession->ProcessPeerTest (buf, len); |
| 742 | break; |
| 743 | case eSSU2SessionStateHolePunch: |
| 744 | m_LastSession->ProcessFirstIncomingMessage (connID, buf, len); // SessionRequest |
| 745 | break; |
| 746 | case eSSU2SessionStateClosing: |
| 747 | m_LastSession->ProcessData (buf, len, senderEndpoint); // we might receive termintaion block |
| 748 | if (m_LastSession && m_LastSession->GetState () == eSSU2SessionStateClosing) |
| 749 | m_LastSession->RequestTermination (eSSU2TerminationReasonIdleTimeout); // send termination again |
| 750 | break; |
| 751 | case eSSU2SessionStateClosingConfirmed: |
| 752 | case eSSU2SessionStateTerminated: |
| 753 | m_LastSession = nullptr; |
nothing calls this directly
no test coverage detected