mirror of https://github.com/PurpleI2P/i2pd
Merge branch 'master' of github-meeh420:PrivacySolutions/i2pd
Note; we use _MSC_VER instead of _WIN32 for MSVC spesific code. * 'master' of github-meeh420:PrivacySolutions/i2pd: (35 commits) handle incoming datagramms send datagram through destination's thread incoming ipv6 connections support ipv6 for outgoing NTCP connections some cleanup Update Daemon.cpp Add Upstart job to debian packaging Implement reload in init script Rename init.d to i2pd.init Decouple logging and daemonization verify signature through remore identity moved remote RI and identity to TransportSession set unreachable trough NetDb moved AddressBook to ClientContext initialize router identity don't specify RI for inbound NTCP connections use remote router indentity take identity of local RI from private keys send datagram from SAM fixed windows build ... Conflicts: SAM.cpppull/106/head
commit
af0bdc2a5e
@ -0,0 +1,132 @@
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
#include <cryptopp/sha.h>
|
||||
#include <cryptopp/gzip.h>
|
||||
#include "Log.h"
|
||||
#include "TunnelBase.h"
|
||||
#include "RouterContext.h"
|
||||
#include "Destination.h"
|
||||
#include "Datagram.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace datagram
|
||||
{
|
||||
DatagramDestination::DatagramDestination (i2p::client::ClientDestination& owner):
|
||||
m_Owner (owner)
|
||||
{
|
||||
}
|
||||
|
||||
void DatagramDestination::SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::LeaseSet& remote)
|
||||
{
|
||||
uint8_t buf[MAX_DATAGRAM_SIZE];
|
||||
auto identityLen = m_Owner.GetIdentity ().ToBuffer (buf, MAX_DATAGRAM_SIZE);
|
||||
uint8_t * signature = buf + identityLen;
|
||||
auto signatureLen = m_Owner.GetIdentity ().GetSignatureLen ();
|
||||
uint8_t * buf1 = signature + signatureLen;
|
||||
size_t headerLen = identityLen + signatureLen;
|
||||
|
||||
memcpy (buf1, payload, len);
|
||||
if (m_Owner.GetIdentity ().GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1)
|
||||
{
|
||||
uint8_t hash[32];
|
||||
CryptoPP::SHA256().CalculateDigest (hash, buf1, len);
|
||||
m_Owner.Sign (hash, 32, signature);
|
||||
}
|
||||
else
|
||||
m_Owner.Sign (buf1, len, signature);
|
||||
|
||||
auto service = m_Owner.GetService ();
|
||||
if (service)
|
||||
service->post (boost::bind (&DatagramDestination::SendMsg, this,
|
||||
CreateDataMessage (buf, len + headerLen), remote));
|
||||
else
|
||||
LogPrint ("Failed to send datagram. Destination is not running");
|
||||
}
|
||||
|
||||
void DatagramDestination::SendMsg (I2NPMessage * msg, const i2p::data::LeaseSet& remote)
|
||||
{
|
||||
auto leases = remote.GetNonExpiredLeases ();
|
||||
if (!leases.empty ())
|
||||
{
|
||||
std::vector<i2p::tunnel::TunnelMessageBlock> msgs;
|
||||
uint32_t i = i2p::context.GetRandomNumberGenerator ().GenerateWord32 (0, leases.size () - 1);
|
||||
auto garlic = m_Owner.WrapMessage (remote, msg, true);
|
||||
msgs.push_back (i2p::tunnel::TunnelMessageBlock
|
||||
{
|
||||
i2p::tunnel::eDeliveryTypeTunnel,
|
||||
leases[i].tunnelGateway, leases[i].tunnelID,
|
||||
garlic
|
||||
});
|
||||
m_Owner.SendTunnelDataMsgs (msgs);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint ("Failed to send datagram. All leases expired");
|
||||
DeleteI2NPMessage (msg);
|
||||
}
|
||||
}
|
||||
|
||||
void DatagramDestination::HandleDatagram (const uint8_t * buf, size_t len)
|
||||
{
|
||||
i2p::data::IdentityEx identity;
|
||||
size_t identityLen = identity.FromBuffer (buf, len);
|
||||
const uint8_t * signature = buf + identityLen;
|
||||
size_t headerLen = identityLen + identity.GetSignatureLen ();
|
||||
|
||||
bool verified = false;
|
||||
if (identity.GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1)
|
||||
{
|
||||
uint8_t hash[32];
|
||||
CryptoPP::SHA256().CalculateDigest (hash, buf + headerLen, len - headerLen);
|
||||
verified = identity.Verify (hash, 32, signature);
|
||||
}
|
||||
else
|
||||
verified = identity.Verify (buf + headerLen, len - headerLen, signature);
|
||||
|
||||
if (verified)
|
||||
{
|
||||
// TODO: invoke datagram handler
|
||||
}
|
||||
else
|
||||
LogPrint ("Datagram signature verification failed");
|
||||
}
|
||||
|
||||
void DatagramDestination::HandleDataMessagePayload (const uint8_t * buf, size_t len)
|
||||
{
|
||||
// unzip it
|
||||
CryptoPP::Gunzip decompressor;
|
||||
decompressor.Put (buf, len);
|
||||
decompressor.MessageEnd();
|
||||
uint8_t uncompressed[MAX_DATAGRAM_SIZE];
|
||||
auto uncompressedLen = decompressor.MaxRetrievable ();
|
||||
if (uncompressedLen <= MAX_DATAGRAM_SIZE)
|
||||
{
|
||||
decompressor.Get (uncompressed, uncompressedLen);
|
||||
HandleDatagram (uncompressed, uncompressedLen);
|
||||
}
|
||||
else
|
||||
LogPrint ("Received datagram size ", uncompressedLen, " exceeds max size");
|
||||
|
||||
}
|
||||
|
||||
I2NPMessage * DatagramDestination::CreateDataMessage (const uint8_t * payload, size_t len)
|
||||
{
|
||||
I2NPMessage * msg = NewI2NPMessage ();
|
||||
CryptoPP::Gzip compressor; // default level
|
||||
compressor.Put (payload, len);
|
||||
compressor.MessageEnd();
|
||||
int size = compressor.MaxRetrievable ();
|
||||
uint8_t * buf = msg->GetPayload ();
|
||||
*(uint32_t *)buf = htobe32 (size); // length
|
||||
buf += 4;
|
||||
compressor.Get (buf, size);
|
||||
memset (buf + 4, 0, 4); // source and destination are zeroes
|
||||
buf[9] = i2p::client::PROTOCOL_TYPE_DATAGRAM; // datagram protocol
|
||||
msg->len += size + 4;
|
||||
FillI2NPMessageHeader (msg, eI2NPData);
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,41 @@
|
||||
#ifndef DATAGRAM_H__
|
||||
#define DATAGRAM_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "LeaseSet.h"
|
||||
#include "I2NPProtocol.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace client
|
||||
{
|
||||
class ClientDestination;
|
||||
}
|
||||
namespace datagram
|
||||
{
|
||||
const size_t MAX_DATAGRAM_SIZE = 32768;
|
||||
class DatagramDestination
|
||||
{
|
||||
public:
|
||||
|
||||
DatagramDestination (i2p::client::ClientDestination& owner);
|
||||
~DatagramDestination () {};
|
||||
|
||||
void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::LeaseSet& remote);
|
||||
void HandleDataMessagePayload (const uint8_t * buf, size_t len);
|
||||
|
||||
private:
|
||||
|
||||
I2NPMessage * CreateDataMessage (const uint8_t * payload, size_t len);
|
||||
void SendMsg (I2NPMessage * msg, const i2p::data::LeaseSet& remote);
|
||||
void HandleDatagram (const uint8_t * buf, size_t len);
|
||||
|
||||
private:
|
||||
|
||||
i2p::client::ClientDestination& m_Owner;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,43 @@
|
||||
#ifndef TRANSPORT_SESSION_H__
|
||||
#define TRANSPORT_SESSION_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "Identity.h"
|
||||
#include "RouterInfo.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace transport
|
||||
{
|
||||
struct DHKeysPair // transient keys for transport sessions
|
||||
{
|
||||
uint8_t publicKey[256];
|
||||
uint8_t privateKey[256];
|
||||
};
|
||||
|
||||
class TransportSession
|
||||
{
|
||||
public:
|
||||
|
||||
TransportSession (const i2p::data::RouterInfo * in_RemoteRouter):
|
||||
m_RemoteRouter (in_RemoteRouter), m_DHKeysPair (nullptr)
|
||||
{
|
||||
if (m_RemoteRouter)
|
||||
m_RemoteIdentity = m_RemoteRouter->GetRouterIdentity ();
|
||||
}
|
||||
|
||||
virtual ~TransportSession () { delete m_DHKeysPair; };
|
||||
|
||||
const i2p::data::RouterInfo * GetRemoteRouter () { return m_RemoteRouter; };
|
||||
const i2p::data::IdentityEx& GetRemoteIdentity () { return m_RemoteIdentity; };
|
||||
|
||||
protected:
|
||||
|
||||
const i2p::data::RouterInfo * m_RemoteRouter;
|
||||
i2p::data::IdentityEx m_RemoteIdentity;
|
||||
DHKeysPair * m_DHKeysPair; // X - for client and Y - for server
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,10 @@
|
||||
description "i2p client daemon"
|
||||
|
||||
start on runlevel [2345]
|
||||
stop on runlevel [016] or unmounting-filesystem
|
||||
|
||||
# these can be overridden in /etc/init/i2pd.override
|
||||
env I2P_HOST="1.2.3.4"
|
||||
env I2P_PORT="4567"
|
||||
|
||||
exec /usr/sbin/i2pd --daemon=0 --log=1 --host=$I2P_HOST --port=$I2P_PORT
|
Loading…
Reference in New Issue