mirror of
				https://github.com/PurpleI2P/i2pd.git
				synced 2025-11-04 00:20:46 +00:00 
			
		
		
		
	handle RelayResponse
This commit is contained in:
		
							parent
							
								
									eb6437050f
								
							
						
					
					
						commit
						40340cf9c2
					
				
					 2 changed files with 48 additions and 25 deletions
				
			
		| 
						 | 
					@ -823,6 +823,8 @@ namespace transport
 | 
				
			||||||
					HandleRelayRequest (buf + offset, size);
 | 
										HandleRelayRequest (buf + offset, size);
 | 
				
			||||||
				break;	
 | 
									break;	
 | 
				
			||||||
				case eSSU2BlkRelayResponse:
 | 
									case eSSU2BlkRelayResponse:
 | 
				
			||||||
 | 
										LogPrint (eLogDebug, "SSU2: RelayResponse");
 | 
				
			||||||
 | 
										HandleRelayResponse (buf + offset, size);
 | 
				
			||||||
				break;	
 | 
									break;	
 | 
				
			||||||
				case eSSU2BlkRelayIntro:
 | 
									case eSSU2BlkRelayIntro:
 | 
				
			||||||
				break;	
 | 
									break;	
 | 
				
			||||||
| 
						 | 
					@ -1023,19 +1025,9 @@ namespace transport
 | 
				
			||||||
			LogPrint (eLogWarning, "SSU2: Session with relay tag ", relayTag, " not found");
 | 
								LogPrint (eLogWarning, "SSU2: Session with relay tag ", relayTag, " not found");
 | 
				
			||||||
			return; // TODO: send relay response
 | 
								return; // TODO: send relay response
 | 
				
			||||||
		}	
 | 
							}	
 | 
				
			||||||
		SignedData s;
 | 
							session->m_RelaySessions.emplace (bufbe32toh (buf + 1), // nonce
 | 
				
			||||||
		s.Insert ((const uint8_t *)"RelayRequestData", 16); // prologue
 | 
								std::make_pair (shared_from_this (), i2p::util::GetSecondsSinceEpoch ()) ); 
 | 
				
			||||||
		s.Insert (i2p::context.GetIdentHash (), 32); // bhash
 | 
							
 | 
				
			||||||
		s.Insert (session->GetRemoteIdentity ()->GetIdentHash (), 32); // chash
 | 
					 | 
				
			||||||
		s.Insert (buf + 1, 14); // nonce, relay tag, timestamp, ver, asz
 | 
					 | 
				
			||||||
		uint8_t asz = buf[14];
 | 
					 | 
				
			||||||
		s.Insert (buf + 15, asz); // Alice Port, Alice IP
 | 
					 | 
				
			||||||
		if (!s.Verify (GetRemoteIdentity (), buf + 15 + asz))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			LogPrint (eLogWarning, "SSU2: RelayRequest signature verification failed");
 | 
					 | 
				
			||||||
			return; // TODO: send relay response
 | 
					 | 
				
			||||||
		}	
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// send relay intro to Charlie
 | 
							// send relay intro to Charlie
 | 
				
			||||||
		uint8_t payload[SSU2_MTU];
 | 
							uint8_t payload[SSU2_MTU];
 | 
				
			||||||
		size_t payloadSize = CreateRelayIntroBlock (payload, SSU2_MTU, buf + 1, len -1);
 | 
							size_t payloadSize = CreateRelayIntroBlock (payload, SSU2_MTU, buf + 1, len -1);
 | 
				
			||||||
| 
						 | 
					@ -1067,7 +1059,7 @@ namespace transport
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// send relay response to Bob
 | 
							// send relay response to Bob
 | 
				
			||||||
		uint8_t payload[SSU2_MTU];
 | 
							uint8_t payload[SSU2_MTU];
 | 
				
			||||||
		size_t payloadSize = CreateRelayResponseBlock (payload, SSU2_MTU, bufbe32toh (buf + 33), bufbe32toh (buf + 37));
 | 
							size_t payloadSize = CreateRelayResponseBlock (payload, SSU2_MTU, bufbe32toh (buf + 33));
 | 
				
			||||||
		payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MTU - payloadSize);
 | 
							payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MTU - payloadSize);
 | 
				
			||||||
		SendData (payload, payloadSize);
 | 
							SendData (payload, payloadSize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1076,6 +1068,24 @@ namespace transport
 | 
				
			||||||
		if (ExtractEndpoint (buf + 47, asz, ep))
 | 
							if (ExtractEndpoint (buf + 47, asz, ep))
 | 
				
			||||||
			m_Server.SendHolePunch (ep);
 | 
								m_Server.SendHolePunch (ep);
 | 
				
			||||||
	}	
 | 
						}	
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void SSU2Session::HandleRelayResponse (const uint8_t * buf, size_t len)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							auto it = m_RelaySessions.find (bufbe32toh (buf + 2)); // nonce
 | 
				
			||||||
 | 
							if (it != m_RelaySessions.end ())
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (it->second.first && it->second.first->IsEstablished ())
 | 
				
			||||||
 | 
									// we are Bob, message from Charlie
 | 
				
			||||||
 | 
									it->second.first->SendData (buf, len); // forward to Alice as is
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									// we are Alice, message from Bob
 | 
				
			||||||
 | 
								}	
 | 
				
			||||||
 | 
								m_RelaySessions.erase (it);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								LogPrint (eLogWarning, "SSU2: RelayResponse unknown nonce ", bufbe32toh (buf + 2)); 
 | 
				
			||||||
 | 
						}	
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
	bool SSU2Session::ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep)
 | 
						bool SSU2Session::ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -1261,25 +1271,24 @@ namespace transport
 | 
				
			||||||
		return payloadSize + 3;
 | 
							return payloadSize + 3;
 | 
				
			||||||
	}	
 | 
						}	
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	size_t SSU2Session::CreateRelayResponseBlock (uint8_t * buf, size_t len, uint32_t nonce, uint32_t relayTag)
 | 
						size_t SSU2Session::CreateRelayResponseBlock (uint8_t * buf, size_t len, uint32_t nonce)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		buf[0] = eSSU2BlkRelayResponse;
 | 
							buf[0] = eSSU2BlkRelayResponse;
 | 
				
			||||||
		buf[3] = 0; // flag
 | 
							buf[3] = 0; // flag
 | 
				
			||||||
		buf[4] = 0;  // code, accept
 | 
							buf[4] = 0;  // code, accept
 | 
				
			||||||
		htobe32buf (buf + 5, nonce); // nonce
 | 
							htobe32buf (buf + 5, nonce); // nonce
 | 
				
			||||||
		htobe32buf (buf + 9, relayTag); // relayTag
 | 
							htobe32buf (buf + 9, i2p::util::GetSecondsSinceEpoch ()); // timestamp
 | 
				
			||||||
		htobe32buf (buf + 13, i2p::util::GetSecondsSinceEpoch ()); // timestamp
 | 
							buf[13] = 2; // ver
 | 
				
			||||||
		buf[17] = 2; // ver
 | 
							size_t csz = CreateEndpoint (buf + 15, len - 15, boost::asio::ip::udp::endpoint (m_Address->host, m_Address->port));
 | 
				
			||||||
		size_t csz = CreateEndpoint (buf + 19, len - 19, boost::asio::ip::udp::endpoint (m_Address->host, m_Address->port));
 | 
					 | 
				
			||||||
		if (!csz) return 0;
 | 
							if (!csz) return 0;
 | 
				
			||||||
		buf[18] = csz; // csz
 | 
							buf[14] = csz; // csz
 | 
				
			||||||
		// signature
 | 
							// signature
 | 
				
			||||||
		SignedData s;
 | 
							SignedData s;
 | 
				
			||||||
		s.Insert ((const uint8_t *)"RelayAgreementOK", 16); // prologue
 | 
							s.Insert ((const uint8_t *)"RelayAgreementOK", 16); // prologue
 | 
				
			||||||
		s.Insert (GetRemoteIdentity ()->GetIdentHash (), 32); // bhash
 | 
							s.Insert (GetRemoteIdentity ()->GetIdentHash (), 32); // bhash
 | 
				
			||||||
		s.Insert (buf + 9, 10 + csz); // relay tag, timestamp, ver, csz and Charlie's endpoint
 | 
							s.Insert (buf + 5, 10 + csz); // nonce, timestamp, ver, csz and Charlie's endpoint
 | 
				
			||||||
		s.Sign (i2p::context.GetPrivateKeys (), buf + 19 + csz);
 | 
							s.Sign (i2p::context.GetPrivateKeys (), buf + 15 + csz);
 | 
				
			||||||
		size_t payloadSize = 16 + csz + i2p::context.GetIdentity ()->GetSignatureLen ();
 | 
							size_t payloadSize = 12 + csz + i2p::context.GetIdentity ()->GetSignatureLen ();
 | 
				
			||||||
		htobe16buf (buf + 1, payloadSize); // size
 | 
							htobe16buf (buf + 1, payloadSize); // size
 | 
				
			||||||
		return payloadSize + 3;
 | 
							return payloadSize + 3;
 | 
				
			||||||
	}	
 | 
						}	
 | 
				
			||||||
| 
						 | 
					@ -1368,6 +1377,16 @@ namespace transport
 | 
				
			||||||
			m_ReceivePacketNum = *m_OutOfSequencePackets.rbegin ();
 | 
								m_ReceivePacketNum = *m_OutOfSequencePackets.rbegin ();
 | 
				
			||||||
			m_OutOfSequencePackets.clear ();
 | 
								m_OutOfSequencePackets.clear ();
 | 
				
			||||||
		}	
 | 
							}	
 | 
				
			||||||
 | 
							for (auto it = m_RelaySessions.begin (); it != m_RelaySessions.end ();)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (ts > it->second.second + SSU2_RELAY_NONCE_EXPIRATION_TIMEOUT)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									LogPrint (eLogWarning, "SSU2: noce ", it->first, " was not responded in ", SSU2_RELAY_NONCE_EXPIRATION_TIMEOUT, " seconds, deleted");
 | 
				
			||||||
 | 
									it = m_RelaySessions.erase (it);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									++it;
 | 
				
			||||||
 | 
							}	
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void SSU2Session::FlushData ()
 | 
						void SSU2Session::FlushData ()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,8 @@ namespace transport
 | 
				
			||||||
	const int SSU2_CONNECT_TIMEOUT = 5; // 5 seconds
 | 
						const int SSU2_CONNECT_TIMEOUT = 5; // 5 seconds
 | 
				
			||||||
	const int SSU2_TERMINATION_TIMEOUT = 330; // 5.5 minutes
 | 
						const int SSU2_TERMINATION_TIMEOUT = 330; // 5.5 minutes
 | 
				
			||||||
	const int SSU2_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds
 | 
						const int SSU2_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds
 | 
				
			||||||
	const int SSU2_TOKEN_EXPIRATION_TIMEOUT = 9; // in second
 | 
						const int SSU2_TOKEN_EXPIRATION_TIMEOUT = 9; // in seconds
 | 
				
			||||||
 | 
						const int SSU2_RELAY_NONCE_EXPIRATION_TIMEOUT = 10; // in seconds
 | 
				
			||||||
	const size_t SSU2_SOCKET_RECEIVE_BUFFER_SIZE = 0x1FFFF; // 128K
 | 
						const size_t SSU2_SOCKET_RECEIVE_BUFFER_SIZE = 0x1FFFF; // 128K
 | 
				
			||||||
	const size_t SSU2_SOCKET_SEND_BUFFER_SIZE = 0x1FFFF; // 128K
 | 
						const size_t SSU2_SOCKET_SEND_BUFFER_SIZE = 0x1FFFF; // 128K
 | 
				
			||||||
	const size_t SSU2_MTU = 1488;
 | 
						const size_t SSU2_MTU = 1488;
 | 
				
			||||||
| 
						 | 
					@ -74,6 +75,7 @@ namespace transport
 | 
				
			||||||
	enum SSU2SessionState
 | 
						enum SSU2SessionState
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		eSSU2SessionStateUnknown,
 | 
							eSSU2SessionStateUnknown,
 | 
				
			||||||
 | 
							eSSU2SessionStateIntroduced,
 | 
				
			||||||
		eSSU2SessionStateEstablished,
 | 
							eSSU2SessionStateEstablished,
 | 
				
			||||||
		eSSU2SessionStateTerminated,
 | 
							eSSU2SessionStateTerminated,
 | 
				
			||||||
		eSSU2SessionStateFailed
 | 
							eSSU2SessionStateFailed
 | 
				
			||||||
| 
						 | 
					@ -188,6 +190,7 @@ namespace transport
 | 
				
			||||||
			bool ConcatOutOfSequenceFragments (std::shared_ptr<SSU2IncompleteMessage> m); // true if message complete
 | 
								bool ConcatOutOfSequenceFragments (std::shared_ptr<SSU2IncompleteMessage> m); // true if message complete
 | 
				
			||||||
			void HandleRelayRequest (const uint8_t * buf, size_t len);
 | 
								void HandleRelayRequest (const uint8_t * buf, size_t len);
 | 
				
			||||||
			void HandleRelayIntro (const uint8_t * buf, size_t len);
 | 
								void HandleRelayIntro (const uint8_t * buf, size_t len);
 | 
				
			||||||
 | 
								void HandleRelayResponse (const uint8_t * buf, size_t len);
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			size_t CreateAddressBlock (const boost::asio::ip::udp::endpoint& ep, uint8_t * buf, size_t len);
 | 
								size_t CreateAddressBlock (const boost::asio::ip::udp::endpoint& ep, uint8_t * buf, size_t len);
 | 
				
			||||||
			size_t CreateAckBlock (uint8_t * buf, size_t len);
 | 
								size_t CreateAckBlock (uint8_t * buf, size_t len);
 | 
				
			||||||
| 
						 | 
					@ -196,7 +199,7 @@ namespace transport
 | 
				
			||||||
			size_t CreateFirstFragmentBlock (uint8_t * buf, size_t len, std::shared_ptr<I2NPMessage> msg);
 | 
								size_t CreateFirstFragmentBlock (uint8_t * buf, size_t len, std::shared_ptr<I2NPMessage> msg);
 | 
				
			||||||
			size_t CreateFollowOnFragmentBlock (uint8_t * buf, size_t len, std::shared_ptr<I2NPMessage> msg, uint8_t& fragmentNum, uint32_t msgID);
 | 
								size_t CreateFollowOnFragmentBlock (uint8_t * buf, size_t len, std::shared_ptr<I2NPMessage> msg, uint8_t& fragmentNum, uint32_t msgID);
 | 
				
			||||||
			size_t CreateRelayIntroBlock (uint8_t * buf, size_t len, const uint8_t * introData, size_t introDataLen);
 | 
								size_t CreateRelayIntroBlock (uint8_t * buf, size_t len, const uint8_t * introData, size_t introDataLen);
 | 
				
			||||||
			size_t CreateRelayResponseBlock (uint8_t * buf, size_t len, uint32_t nonce, uint32_t relayTag); // Charlie
 | 
								size_t CreateRelayResponseBlock (uint8_t * buf, size_t len, uint32_t nonce); // Charlie
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
		private:
 | 
							private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -213,6 +216,7 @@ namespace transport
 | 
				
			||||||
			std::set<uint32_t> m_OutOfSequencePackets; // packet nums > receive packet num
 | 
								std::set<uint32_t> m_OutOfSequencePackets; // packet nums > receive packet num
 | 
				
			||||||
			std::map<uint32_t, std::shared_ptr<SentPacket> > m_SentPackets; // packetNum -> packet
 | 
								std::map<uint32_t, std::shared_ptr<SentPacket> > m_SentPackets; // packetNum -> packet
 | 
				
			||||||
			std::map<uint32_t, std::shared_ptr<SSU2IncompleteMessage> > m_IncompleteMessages; // I2NP
 | 
								std::map<uint32_t, std::shared_ptr<SSU2IncompleteMessage> > m_IncompleteMessages; // I2NP
 | 
				
			||||||
 | 
								std::map<uint32_t, std::pair <std::shared_ptr<SSU2Session>, uint64_t > > m_RelaySessions; // nonce->(Alice, timestamp) for Bob or nonce->(Charlie, timestamp) for Alice 
 | 
				
			||||||
			std::list<std::shared_ptr<I2NPMessage> > m_SendQueue;
 | 
								std::list<std::shared_ptr<I2NPMessage> > m_SendQueue;
 | 
				
			||||||
			i2p::I2NPMessagesHandler m_Handler;
 | 
								i2p::I2NPMessagesHandler m_Handler;
 | 
				
			||||||
			bool m_IsDataReceived;
 | 
								bool m_IsDataReceived;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue