| 1006 | } |
| 1007 | |
| 1008 | void NTCP2Session::EstablishSessionAfterSessionConfirmed (std::shared_ptr<std::vector<uint8_t> > buf, size_t size) |
| 1009 | { |
| 1010 | // run on main NTCP2 thread |
| 1011 | KeyDerivationFunctionDataPhase (); |
| 1012 | // Bob data phase keys |
| 1013 | m_SendKey = m_Kba; |
| 1014 | m_ReceiveKey = m_Kab; |
| 1015 | SetSipKeys (m_Sipkeysba, m_Sipkeysab); |
| 1016 | memcpy (m_ReceiveIV.buf, m_Sipkeysab + 16, 8); |
| 1017 | memcpy (m_SendIV.buf, m_Sipkeysba + 16, 8); |
| 1018 | // we need to set keys for SendTerminationAndTerminate |
| 1019 | // TODO: check flag |
| 1020 | i2p::data::RouterInfo ri (buf->data () + 4, size - 1); // 1 byte block type + 2 bytes size + 1 byte flag |
| 1021 | if (ri.IsUnreachable ()) |
| 1022 | { |
| 1023 | LogPrint (eLogError, "NTCP2: RouterInfo verification failed in SessionConfirmed from ", GetRemoteEndpoint ()); |
| 1024 | SendTerminationAndTerminate (eNTCP2RouterInfoSignatureVerificationFail); |
| 1025 | return; |
| 1026 | } |
| 1027 | LogPrint(eLogDebug, "NTCP2: SessionConfirmed from ", GetRemoteEndpoint (), |
| 1028 | " (", i2p::data::GetIdentHashAbbreviation (ri.GetIdentHash ()), ")"); |
| 1029 | auto ts = i2p::util::GetMillisecondsSinceEpoch (); |
| 1030 | if (ts > ri.GetTimestamp () + i2p::data::NETDB_MIN_EXPIRATION_TIMEOUT*1000LL) // 90 minutes |
| 1031 | { |
| 1032 | LogPrint (eLogError, "NTCP2: RouterInfo is too old in SessionConfirmed for ", (ts - ri.GetTimestamp ())/1000LL, " seconds"); |
| 1033 | SendTerminationAndTerminate (eNTCP2Message3Error); |
| 1034 | return; |
| 1035 | } |
| 1036 | if (ts + i2p::data::NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL < ri.GetTimestamp ()) // 2 minutes |
| 1037 | { |
| 1038 | LogPrint (eLogError, "NTCP2: RouterInfo is from future for ", (ri.GetTimestamp () - ts)/1000LL, " seconds"); |
| 1039 | SendTerminationAndTerminate (eNTCP2Message3Error); |
| 1040 | return; |
| 1041 | } |
| 1042 | if (ri.GetVersion () < i2p::data::NETDB_MIN_ALLOWED_VERSION && !ri.IsHighBandwidth ()) |
| 1043 | { |
| 1044 | LogPrint (eLogInfo, "NTCP2: Router version ", ri.GetVersion (), " is too old in SessionConfirmed"); |
| 1045 | SendTerminationAndTerminate (eNTCP2Banned); |
| 1046 | return; |
| 1047 | } |
| 1048 | // update RouterInfo in netdb |
| 1049 | auto ri1 = i2p::data::netdb.AddRouterInfo (ri.GetBuffer (), ri.GetBufferLen ()); // ri1 points to one from netdb now |
| 1050 | if (!ri1) |
| 1051 | { |
| 1052 | LogPrint (eLogError, "NTCP2: Couldn't update RouterInfo from SessionConfirmed in netdb"); |
| 1053 | Terminate (); |
| 1054 | return; |
| 1055 | } |
| 1056 | |
| 1057 | bool isOlder = false; |
| 1058 | if (ri.GetTimestamp () + i2p::data::NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL < ri1->GetTimestamp ()) |
| 1059 | { |
| 1060 | // received RouterInfo is older than one in netdb |
| 1061 | isOlder = true; |
| 1062 | if (ri1->HasProfile ()) |
| 1063 | { |
| 1064 | auto profile = i2p::data::GetRouterProfile (ri1->GetIdentHash ()); // retrieve profile |
| 1065 | if (profile && profile->IsDuplicated ()) |
no test coverage detected