Esempio n. 1
0
	void HandleI2NPMessage (std::shared_ptr<I2NPMessage> msg)
	{
		if (msg)
		{	
			uint8_t typeID = msg->GetTypeID ();
			LogPrint (eLogDebug, "I2NP: Handling message with type ", (int)typeID);
			switch (typeID)
			{	
				case eI2NPTunnelData:
					i2p::tunnel::tunnels.PostTunnelData (msg);
				break;	
				case eI2NPTunnelGateway:
					i2p::tunnel::tunnels.PostTunnelData (msg);
				break;
				case eI2NPGarlic:
				{
					if (msg->from)
					{
						if (msg->from->GetTunnelPool ())
							msg->from->GetTunnelPool ()->ProcessGarlicMessage (msg);
						else
							LogPrint (eLogInfo, "I2NP: Local destination for garlic doesn't exist anymore");
					}
					else
						i2p::context.ProcessGarlicMessage (msg); 
					break;
				}
				case eI2NPDatabaseStore:
				case eI2NPDatabaseSearchReply:
				case eI2NPDatabaseLookup:
					// forward to netDb
					i2p::data::netdb.PostI2NPMsg (msg);
				break;
				case eI2NPDeliveryStatus:
				{
					if (msg->from && msg->from->GetTunnelPool ())
						msg->from->GetTunnelPool ()->ProcessDeliveryStatus (msg);
					else
						i2p::context.ProcessDeliveryStatusMessage (msg);
					break;	
				}
				case eI2NPVariableTunnelBuild:		
				case eI2NPVariableTunnelBuildReply:
				case eI2NPTunnelBuild:
				case eI2NPTunnelBuildReply:	
					// forward to tunnel thread
					i2p::tunnel::tunnels.PostTunnelData (msg);
				break;	
				default:
					HandleI2NPMessage (msg->GetBuffer (), msg->GetLength ());
			}	
		}	
	}	
Esempio n. 2
0
	void I2NPMessagesHandler::PutNextMessage (std::shared_ptr<I2NPMessage>  msg)
	{
		if (msg)
		{
			switch (msg->GetTypeID ())
			{	
				case eI2NPTunnelData:
					m_TunnelMsgs.push_back (msg);
				break;
				case eI2NPTunnelGateway:	
					m_TunnelGatewayMsgs.push_back (msg);
				break;	
				default:
					HandleI2NPMessage (msg);
			}		
		}	
	}
Esempio n. 3
0
	void HandleI2NPMessage (I2NPMessage * msg)
	{
		if (msg)
		{	
			switch (msg->GetHeader ()->typeID)
			{	
				case eI2NPTunnelData:
					LogPrint ("TunnelData");
					i2p::tunnel::tunnels.PostTunnelData (msg);
				break;	
				case eI2NPTunnelGateway:
					LogPrint ("TunnelGateway");
					HandleTunnelGatewayMsg (msg);
				break;
				case eI2NPGarlic:
					LogPrint ("Garlic");
					if (msg->from && msg->from->GetTunnelPool ())
						msg->from->GetTunnelPool ()->GetLocalDestination ().ProcessGarlicMessage (msg);
					else
						i2p::context.ProcessGarlicMessage (msg); 
				break;
				case eI2NPDatabaseStore:
				case eI2NPDatabaseSearchReply:
				case eI2NPDatabaseLookup:
					// forward to netDb
					i2p::data::netdb.PostI2NPMsg (msg);
				break;
				case eI2NPDeliveryStatus:
					LogPrint ("DeliveryStatus");
					if (msg->from && msg->from->GetTunnelPool ())
						msg->from->GetTunnelPool ()->ProcessDeliveryStatus (msg);
					else
						i2p::context.ProcessDeliveryStatusMessage (msg);
				break;	
				default:
					HandleI2NPMessage (msg->GetBuffer (), msg->GetLength ());
					DeleteI2NPMessage (msg);
			}	
		}	
	}	
Esempio n. 4
0
	void GarlicDestination::HandleGarlicPayload (uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from)
	{
		if (len < 1)
		{
			LogPrint (eLogError, "Garlic: payload is too short");
			return;
		}
		int numCloves = buf[0];
		LogPrint (eLogDebug, "Garlic: ", numCloves," cloves");
		buf++; len--;
		for (int i = 0; i < numCloves; i++)
		{
			const uint8_t * buf1 = buf;
			// delivery instructions
			uint8_t flag = buf[0];
			buf++; // flag
			if (flag & 0x80) // encrypted?
			{
				// TODO: implement
				LogPrint (eLogWarning, "Garlic: clove encrypted");
				buf += 32;
			}
			ptrdiff_t offset = buf - buf1;
			GarlicDeliveryType deliveryType = (GarlicDeliveryType)((flag >> 5) & 0x03);
			switch (deliveryType)
			{
				case eGarlicDeliveryTypeLocal:
					LogPrint (eLogDebug, "Garlic: type local");
					if (offset > (int)len)
					{
						LogPrint (eLogError, "Garlic: message is too short");
						break;
					}
					HandleI2NPMessage (buf, len - offset, from);
				break;
				case eGarlicDeliveryTypeDestination:
					LogPrint (eLogDebug, "Garlic: type destination");
					buf += 32; // destination. check it later or for multiple destinations
					offset = buf - buf1;
					if (offset > (int)len)
					{
						LogPrint (eLogError, "Garlic: message is too short");
						break;
					}
					HandleI2NPMessage (buf, len - offset, from);
				break;
				case eGarlicDeliveryTypeTunnel:
				{
					LogPrint (eLogDebug, "Garlic: type tunnel");
					// gwHash and gwTunnel sequence is reverted
					uint8_t * gwHash = buf;
					buf += 32;
					offset = buf - buf1;
					if (offset + 4 > (int)len)
					{
						LogPrint (eLogError, "Garlic: message is too short");
						break;
					}
					uint32_t gwTunnel = bufbe32toh (buf);
					buf += 4; offset += 4;
					auto msg = CreateI2NPMessage (buf, GetI2NPMessageLength (buf, len - offset), from);
					if (from) // received through an inbound tunnel
					{
						std::shared_ptr<i2p::tunnel::OutboundTunnel> tunnel;
						if (from->GetTunnelPool ())
							tunnel = from->GetTunnelPool ()->GetNextOutboundTunnel ();
						else
							LogPrint (eLogError, "Garlic: Tunnel pool is not set for inbound tunnel");
						if (tunnel) // we have send it through an outbound tunnel
							tunnel->SendTunnelDataMsg (gwHash, gwTunnel, msg);
						else
							LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove");
					}
					else // received directly
						i2p::transport::transports.SendMessage (gwHash, i2p::CreateTunnelGatewayMsg (gwTunnel, msg)); // send directly
					break;
				}
				case eGarlicDeliveryTypeRouter:
				{
					uint8_t * ident = buf;
					buf += 32;
					offset = buf - buf1;
					if (!from) // received directly
					{
						if (offset > (int)len)
						{
							LogPrint (eLogError, "Garlic: message is too short");
							break;
						}
						i2p::transport::transports.SendMessage (ident,
							CreateI2NPMessage (buf, GetI2NPMessageLength (buf, len - offset)));
					}
					else
						LogPrint (eLogWarning, "Garlic: type router for inbound tunnels not supported");
					break;
				}
				default:
					LogPrint (eLogWarning, "Garlic: unknown delivery type ", (int)deliveryType);
			}
			if (offset > (int)len)
			{
				LogPrint (eLogError, "Garlic: message is too short");
				break;
			}
			buf += GetI2NPMessageLength (buf, len - offset); //  I2NP
			buf += 4; // CloveID
			buf += 8; // Date
			buf += 3; // Certificate
			offset = buf - buf1;
			if (offset > (int)len)
			{
				LogPrint (eLogError, "Garlic: clove is too long");
				break;
			}
			len -= offset;
		}
	}
Esempio n. 5
0
	void GarlicDestination::HandleGarlicPayload (uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from)
	{
		const uint8_t * buf1 = buf;
		int numCloves = buf[0];
		LogPrint (eLogDebug, "Garlic: ", numCloves," cloves");
		buf++;
		for (int i = 0; i < numCloves; i++)
		{
			// delivery instructions
			uint8_t flag = buf[0];
			buf++; // flag
			if (flag & 0x80) // encrypted?
			{
				// TODO: implement
				LogPrint (eLogWarning, "Garlic: clove encrypted");
				buf += 32; 
			}	
			GarlicDeliveryType deliveryType = (GarlicDeliveryType)((flag >> 5) & 0x03);
			switch (deliveryType)
			{
				case eGarlicDeliveryTypeLocal:
					LogPrint (eLogDebug, "Garlic: type local");
					HandleI2NPMessage (buf, len, from);
				break;	
				case eGarlicDeliveryTypeDestination:	
					LogPrint (eLogDebug, "Garlic: type destination");
					buf += 32; // destination. check it later or for multiple destinations
					HandleI2NPMessage (buf, len, from);
				break;
				case eGarlicDeliveryTypeTunnel:
				{	
					LogPrint (eLogDebug, "Garlic: type tunnel");
					// gwHash and gwTunnel sequence is reverted
					uint8_t * gwHash = buf;
					buf += 32;
					uint32_t gwTunnel = bufbe32toh (buf);
					buf += 4;
					std::shared_ptr<i2p::tunnel::OutboundTunnel> tunnel;
					if (from && from->GetTunnelPool ())
						tunnel = from->GetTunnelPool ()->GetNextOutboundTunnel ();
					if (tunnel) // we have send it through an outbound tunnel
					{	
						auto msg = CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from);
						tunnel->SendTunnelDataMsg (gwHash, gwTunnel, msg);
					}	
					else
						LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove");
					break;
				}
				case eGarlicDeliveryTypeRouter:
					LogPrint (eLogWarning, "Garlic: type router not supported");
					buf += 32;
				break;	
				default:
					LogPrint (eLogWarning, "Garlic: unknown delivery type ", (int)deliveryType);
			}
			buf += GetI2NPMessageLength (buf); //  I2NP
			buf += 4; // CloveID
			buf += 8; // Date
			buf += 3; // Certificate
			if (buf - buf1  > (int)len)
			{
				LogPrint (eLogError, "Garlic: clove is too long");
				break;
			}	
		}	
	}