pull/40/head
Meeh 10 years ago
commit 6a907dbe97

@ -4,7 +4,8 @@ CFLAGS = -g -Wall -std=c++0x
OBJECTS = obj/i2p.o obj/base64.o obj/NTCPSession.o obj/RouterInfo.o obj/Transports.o \
obj/RouterContext.o obj/NetDb.o obj/LeaseSet.o obj/Tunnel.o obj/TunnelEndpoint.o \
obj/TunnelGateway.o obj/TransitTunnel.o obj/I2NPProtocol.o obj/Log.o obj/Garlic.o \
obj/HTTPServer.o obj/Streaming.o obj/Identity.o obj/SSU.o obj/util.o obj/Reseed.o
obj/HTTPServer.o obj/Streaming.o obj/Identity.o obj/SSU.o obj/util.o obj/Reseed.o \
obj/UPnP.o
INCFLAGS =
LDFLAGS = -Wl,-rpath,/usr/local/lib -lcryptopp -lboost_system -lboost_filesystem -lboost_regex -lboost_program_options -lpthread
LIBS =

@ -43,7 +43,7 @@ namespace i2p
void RouterContext::OverrideNTCPAddress (const char * host, int port)
{
m_RouterInfo.CreateBuffer ();
auto address = m_RouterInfo.GetNTCPAddress ();
auto address = const_cast<i2p::data::RouterInfo::Address *>(m_RouterInfo.GetNTCPAddress ());
if (address)
{
address->host = boost::asio::ip::address::from_string (host);

@ -303,17 +303,17 @@ namespace data
return m_SupportedTransports & (eSSUV4 | eSSUV6);
}
RouterInfo::Address * RouterInfo::GetNTCPAddress (bool v4only)
const RouterInfo::Address * RouterInfo::GetNTCPAddress (bool v4only) const
{
return GetAddress (eTransportNTCP, v4only);
}
RouterInfo::Address * RouterInfo::GetSSUAddress (bool v4only)
const RouterInfo::Address * RouterInfo::GetSSUAddress (bool v4only) const
{
return GetAddress (eTransportSSU, v4only);
}
RouterInfo::Address * RouterInfo::GetAddress (TransportStyle s, bool v4only)
const RouterInfo::Address * RouterInfo::GetAddress (TransportStyle s, bool v4only) const
{
for (auto& address : m_Addresses)
{

@ -54,8 +54,8 @@ namespace data
const char * GetIdentHashAbbreviation () const { return m_IdentHashAbbreviation; };
uint64_t GetTimestamp () const { return m_Timestamp; };
std::vector<Address>& GetAddresses () { return m_Addresses; };
Address * GetNTCPAddress (bool v4only = true);
Address * GetSSUAddress (bool v4only = true);
const Address * GetNTCPAddress (bool v4only = true) const;
const Address * GetSSUAddress (bool v4only = true) const;
const RoutingKey& GetRoutingKey () const { return m_RoutingKey; };
void AddNTCPAddress (const char * host, int port);
@ -91,7 +91,7 @@ namespace data
size_t ReadString (char * str, std::istream& s);
void WriteString (const std::string& str, std::ostream& s);
void UpdateIdentHashBase64 ();
Address * GetAddress (TransportStyle s, bool v4only);
const Address * GetAddress (TransportStyle s, bool v4only) const;
private:

@ -14,8 +14,8 @@ namespace i2p
namespace ssu
{
SSUSession::SSUSession (SSUServer * server, const boost::asio::ip::udp::endpoint& remoteEndpoint,
i2p::data::RouterInfo * router): m_Server (server), m_RemoteEndpoint (remoteEndpoint),
SSUSession::SSUSession (SSUServer * server, boost::asio::ip::udp::endpoint& remoteEndpoint,
const i2p::data::RouterInfo * router): m_Server (server), m_RemoteEndpoint (remoteEndpoint),
m_RemoteRouter (router), m_State (eSessionStateUnknown)
{
}
@ -273,7 +273,7 @@ namespace ssu
m_Server->Send (buf, 480, m_RemoteEndpoint);
}
bool SSUSession::ProcessIntroKeyEncryptedMessage (uint8_t expectedPayloadType, i2p::data::RouterInfo& r, uint8_t * buf, size_t len)
bool SSUSession::ProcessIntroKeyEncryptedMessage (uint8_t expectedPayloadType, const i2p::data::RouterInfo& r, uint8_t * buf, size_t len)
{
auto address = r.GetSSUAddress ();
if (address)
@ -299,7 +299,8 @@ namespace ssu
return false;
}
void SSUSession::FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len, uint8_t * aesKey, uint8_t * iv, uint8_t * macKey)
void SSUSession::FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len,
const uint8_t * aesKey, const uint8_t * iv, const uint8_t * macKey)
{
if (len < sizeof (SSUHeader))
{
@ -320,7 +321,7 @@ namespace ssu
i2p::crypto::HMACMD5Digest (encrypted, encryptedLen + 18, macKey, header->mac);
}
void SSUSession::Decrypt (uint8_t * buf, size_t len, uint8_t * aesKey)
void SSUSession::Decrypt (uint8_t * buf, size_t len, const uint8_t * aesKey)
{
if (len < sizeof (SSUHeader))
{
@ -335,7 +336,7 @@ namespace ssu
m_Decryption.ProcessData (encrypted, encrypted, encryptedLen);
}
bool SSUSession::Validate (uint8_t * buf, size_t len, uint8_t * macKey)
bool SSUSession::Validate (uint8_t * buf, size_t len, const uint8_t * macKey)
{
if (len < sizeof (SSUHeader))
{
@ -535,7 +536,7 @@ namespace ssu
LogPrint ("SSU receive error: ", ecode.message ());
}
SSUSession * SSUServer::GetSession (i2p::data::RouterInfo * router)
SSUSession * SSUServer::GetSession (const i2p::data::RouterInfo * router)
{
SSUSession * session = nullptr;
if (router)

16
SSU.h

@ -62,8 +62,8 @@ namespace ssu
{
public:
SSUSession (SSUServer * server, const boost::asio::ip::udp::endpoint& remoteEndpoint,
i2p::data::RouterInfo * router = nullptr);
SSUSession (SSUServer * server, boost::asio::ip::udp::endpoint& remoteEndpoint,
const i2p::data::RouterInfo * router = nullptr);
void ProcessNextMessage (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint);
void Connect ();
@ -86,16 +86,16 @@ namespace ssu
void SendMsgAck (uint32_t msgID);
void SendSesionDestroyed ();
bool ProcessIntroKeyEncryptedMessage (uint8_t expectedPayloadType, i2p::data::RouterInfo& r, uint8_t * buf, size_t len);
void FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len, uint8_t * aesKey, uint8_t * iv, uint8_t * macKey);
void Decrypt (uint8_t * buf, size_t len, uint8_t * aesKey);
bool Validate (uint8_t * buf, size_t len, uint8_t * macKey);
bool ProcessIntroKeyEncryptedMessage (uint8_t expectedPayloadType, const i2p::data::RouterInfo& r, uint8_t * buf, size_t len);
void FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len, const uint8_t * aesKey, const uint8_t * iv, const uint8_t * macKey);
void Decrypt (uint8_t * buf, size_t len, const uint8_t * aesKey);
bool Validate (uint8_t * buf, size_t len, const uint8_t * macKey);
private:
SSUServer * m_Server;
boost::asio::ip::udp::endpoint m_RemoteEndpoint;
i2p::data::RouterInfo * m_RemoteRouter;
const i2p::data::RouterInfo * m_RemoteRouter;
SessionState m_State;
CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption m_Encryption;
CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption m_Decryption;
@ -111,7 +111,7 @@ namespace ssu
~SSUServer ();
void Start ();
void Stop ();
SSUSession * GetSession (i2p::data::RouterInfo * router);
SSUSession * GetSession (const i2p::data::RouterInfo * router);
void DeleteSession (SSUSession * session);
void DeleteAllSessions ();

@ -55,8 +55,7 @@ namespace i2p
}
}
// TODO: do it for SSU only
DetectExternalIP ();
//DetectExternalIP ();
}
void Transports::Stop ()
@ -189,7 +188,7 @@ namespace i2p
{
auto router = i2p::data::netdb.GetRandomRouter ();
if (router && router->IsSSU () && m_SSUServer)
m_SSUServer->GetSession (const_cast<i2p::data::RouterInfo *>(router)); //TODO
m_SSUServer->GetSession (router);
}
if (m_Timer)
{

@ -0,0 +1,68 @@
#include <string>
#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>
#include "Log.h"
#include "UPnP.h"
namespace i2p
{
UPnP::UPnP (): m_Timer (m_Service),
m_Endpoint (boost::asio::ip::udp::v4 (), UPNP_REPLY_PORT),
m_MulticastEndpoint (boost::asio::ip::address::from_string (UPNP_GROUP), UPNP_PORT),
m_Socket (m_Service, m_Endpoint.protocol ())
{
m_Socket.set_option (boost::asio::socket_base::receive_buffer_size (65535));
m_Socket.set_option (boost::asio::socket_base::send_buffer_size (65535));
m_Socket.set_option(boost::asio::ip::udp::socket::reuse_address(true));
}
UPnP::~UPnP ()
{
}
void UPnP::Run ()
{
DiscoverRouter ();
m_Service.run ();
}
void UPnP::DiscoverRouter ()
{
m_Timer.expires_from_now (boost::posix_time::seconds(5)); // 5 seconds
m_Timer.async_wait (boost::bind (&UPnP::HandleTimer, this, boost::asio::placeholders::error));
std::string address = UPNP_GROUP;
address += ":" + boost::lexical_cast<std::string>(UPNP_PORT);
std::string request = "M-SEARCH * HTTP/1.1\r\n"
"HOST: " + address + "\r\n"
"ST:" + UPNP_ROUTER + "\r\n"
"MAN:\"ssdp:discover\"\r\n"
"MX:3\r\n"
"\r\n\r\n";
m_Socket.send_to (boost::asio::buffer (request.c_str (), request.length ()), m_MulticastEndpoint);
Receive ();
}
void UPnP::Receive ()
{
m_Socket.async_receive_from (boost::asio::buffer (m_ReceiveBuffer, UPNP_MAX_PACKET_LEN), m_SenderEndpoint,
boost::bind (&UPnP::HandleReceivedFrom, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
void UPnP::HandleReceivedFrom (const boost::system::error_code& ecode, size_t bytes_transferred)
{
LogPrint ("UPnP: ", bytes_transferred, " received from ", m_SenderEndpoint.address ());
std::string str (m_ReceiveBuffer, bytes_transferred);
LogPrint (str);
m_Timer.cancel ();
}
void UPnP::HandleTimer (const boost::system::error_code& ecode)
{
if (ecode != boost::asio::error::operation_aborted)
{
LogPrint ("UPnP: timeout expired");
m_Service.stop ();
}
}
}

@ -0,0 +1,41 @@
#ifndef UPNP_H__
#define UPNP_H__
#include <boost/asio.hpp>
namespace i2p
{
const int UPNP_MAX_PACKET_LEN = 1500;
const char UPNP_GROUP[] = "239.255.255.250";
const int UPNP_PORT = 1900;
const int UPNP_REPLY_PORT = 1901;
const char UPNP_ROUTER[] = "urn:schemas-upnp-org:device:InternetGatewayDevice:1";
class UPnP
{
public:
UPnP ();
~UPnP ();
void Run ();
private:
void DiscoverRouter ();
void Receive ();
void HandleReceivedFrom (const boost::system::error_code& ecode, size_t bytes_transferred);
void HandleTimer (const boost::system::error_code& ecode);
private:
boost::asio::io_service m_Service;
boost::asio::deadline_timer m_Timer;
boost::asio::ip::udp::endpoint m_Endpoint, m_MulticastEndpoint, m_SenderEndpoint;
boost::asio::ip::udp::socket m_Socket;
char m_ReceiveBuffer[UPNP_MAX_PACKET_LEN];
};
}
#endif

@ -13,7 +13,7 @@ namespace crypto
const uint64_t IPAD = 0x3636363636363636;
const uint64_t OPAD = 0x5C5C5C5C5C5C5C5C;
inline void HMACMD5Digest (uint8_t * msg, size_t len, uint8_t * key, uint8_t * digest)
inline void HMACMD5Digest (uint8_t * msg, size_t len, const uint8_t * key, uint8_t * digest)
// key is 32 bytes
// digest is 16 bytes
// block size is 64 bytes

Loading…
Cancel
Save