mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 04:04:16 +00:00
Merge pull request #19 from orignal/master
Merge pull request from orignal/master
This commit is contained in:
commit
57a520889a
12
SSU.cpp
12
SSU.cpp
@ -796,6 +796,18 @@ namespace ssu
|
|||||||
LogPrint ("SSU receive error: ", ecode.message ());
|
LogPrint ("SSU receive error: ", ecode.message ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SSUSession * SSUServer::FindSession (const i2p::data::RouterInfo * router)
|
||||||
|
{
|
||||||
|
if (!router) return nullptr;
|
||||||
|
auto address = router->GetSSUAddress ();
|
||||||
|
if (!address) return nullptr;
|
||||||
|
auto it = m_Sessions.find (boost::asio::ip::udp::endpoint (address->host, address->port));
|
||||||
|
if (it != m_Sessions.end ())
|
||||||
|
return it->second;
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
SSUSession * SSUServer::GetSession (const i2p::data::RouterInfo * router)
|
SSUSession * SSUServer::GetSession (const i2p::data::RouterInfo * router)
|
||||||
{
|
{
|
||||||
SSUSession * session = nullptr;
|
SSUSession * session = nullptr;
|
||||||
|
1
SSU.h
1
SSU.h
@ -126,6 +126,7 @@ namespace ssu
|
|||||||
void Start ();
|
void Start ();
|
||||||
void Stop ();
|
void Stop ();
|
||||||
SSUSession * GetSession (const i2p::data::RouterInfo * router);
|
SSUSession * GetSession (const i2p::data::RouterInfo * router);
|
||||||
|
SSUSession * FindSession (const i2p::data::RouterInfo * router);
|
||||||
void DeleteSession (SSUSession * session);
|
void DeleteSession (SSUSession * session);
|
||||||
void DeleteAllSessions ();
|
void DeleteAllSessions ();
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <boost/bind.hpp>
|
|
||||||
#include <cryptopp/gzip.h>
|
#include <cryptopp/gzip.h>
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "RouterInfo.h"
|
#include "RouterInfo.h"
|
||||||
@ -19,7 +18,7 @@ namespace stream
|
|||||||
const i2p::data::LeaseSet& remote): m_Service (service), m_SendStreamID (0),
|
const i2p::data::LeaseSet& remote): m_Service (service), m_SendStreamID (0),
|
||||||
m_SequenceNumber (0), m_LastReceivedSequenceNumber (0), m_IsOpen (false),
|
m_SequenceNumber (0), m_LastReceivedSequenceNumber (0), m_IsOpen (false),
|
||||||
m_LeaseSetUpdated (true), m_LocalDestination (local), m_RemoteLeaseSet (remote),
|
m_LeaseSetUpdated (true), m_LocalDestination (local), m_RemoteLeaseSet (remote),
|
||||||
m_OutboundTunnel (nullptr)
|
m_OutboundTunnel (nullptr), m_ReceiveTimer (m_Service)
|
||||||
{
|
{
|
||||||
m_RecvStreamID = i2p::context.GetRandomNumberGenerator ().GenerateWord32 ();
|
m_RecvStreamID = i2p::context.GetRandomNumberGenerator ().GenerateWord32 ();
|
||||||
UpdateCurrentRemoteLease ();
|
UpdateCurrentRemoteLease ();
|
||||||
@ -27,6 +26,7 @@ namespace stream
|
|||||||
|
|
||||||
Stream::~Stream ()
|
Stream::~Stream ()
|
||||||
{
|
{
|
||||||
|
m_ReceiveTimer.cancel ();
|
||||||
while (auto packet = m_ReceiveQueue.Get ())
|
while (auto packet = m_ReceiveQueue.Get ())
|
||||||
delete packet;
|
delete packet;
|
||||||
for (auto it: m_SavedPackets)
|
for (auto it: m_SavedPackets)
|
||||||
@ -57,7 +57,10 @@ namespace stream
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// send ack for last message
|
||||||
|
SendQuickAck ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -117,13 +120,13 @@ namespace stream
|
|||||||
delete packet;
|
delete packet;
|
||||||
|
|
||||||
m_LastReceivedSequenceNumber = receivedSeqn;
|
m_LastReceivedSequenceNumber = receivedSeqn;
|
||||||
SendQuickAck ();
|
|
||||||
|
|
||||||
if (flags & PACKET_FLAG_CLOSE)
|
if (flags & PACKET_FLAG_CLOSE)
|
||||||
{
|
{
|
||||||
LogPrint ("Closed");
|
LogPrint ("Closed");
|
||||||
m_IsOpen = false;
|
m_IsOpen = false;
|
||||||
m_ReceiveQueue.WakeUp ();
|
m_ReceiveQueue.WakeUp ();
|
||||||
|
m_ReceiveTimer.cancel ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +144,9 @@ namespace stream
|
|||||||
void Stream::ConnectAndSend (uint8_t * buf, size_t len)
|
void Stream::ConnectAndSend (uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
m_IsOpen = true;
|
m_IsOpen = true;
|
||||||
uint8_t packet[STREAMING_MTU];
|
Packet * p = new Packet ();
|
||||||
|
uint8_t * packet = p->GetBuffer ();
|
||||||
|
// TODO: implement setters
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
*(uint32_t *)(packet + size) = htobe32 (m_SendStreamID);
|
*(uint32_t *)(packet + size) = htobe32 (m_SendStreamID);
|
||||||
size += 4; // sendStreamID
|
size += 4; // sendStreamID
|
||||||
@ -167,18 +172,18 @@ namespace stream
|
|||||||
size += 2; // max packet size
|
size += 2; // max packet size
|
||||||
uint8_t * signature = packet + size; // set it later
|
uint8_t * signature = packet + size; // set it later
|
||||||
memset (signature, 0, 40); // zeroes for now
|
memset (signature, 0, 40); // zeroes for now
|
||||||
size += 40; // signature
|
size += 40; // signature
|
||||||
|
|
||||||
memcpy (packet + size, buf, len);
|
memcpy (packet + size, buf, len);
|
||||||
size += len; // payload
|
size += len; // payload
|
||||||
m_LocalDestination->Sign (packet, size, signature);
|
m_LocalDestination->Sign (packet, size, signature);
|
||||||
|
p->len = size;
|
||||||
|
|
||||||
SendPacket (packet, size);
|
m_Service.post (boost::bind (&Stream::SendPacket, this, p));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stream::SendQuickAck ()
|
void Stream::SendQuickAck ()
|
||||||
{
|
{
|
||||||
uint8_t packet[STREAMING_MTU];
|
uint8_t packet[MAX_PACKET_SIZE];
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
*(uint32_t *)(packet + size) = htobe32 (m_SendStreamID);
|
*(uint32_t *)(packet + size) = htobe32 (m_SendStreamID);
|
||||||
size += 4; // sendStreamID
|
size += 4; // sendStreamID
|
||||||
@ -195,7 +200,7 @@ namespace stream
|
|||||||
size += 2; // flags
|
size += 2; // flags
|
||||||
*(uint16_t *)(packet + size) = 0; // no options
|
*(uint16_t *)(packet + size) = 0; // no options
|
||||||
size += 2; // options size
|
size += 2; // options size
|
||||||
|
|
||||||
if (SendPacket (packet, size))
|
if (SendPacket (packet, size))
|
||||||
LogPrint ("Quick Ack sent");
|
LogPrint ("Quick Ack sent");
|
||||||
}
|
}
|
||||||
@ -205,7 +210,7 @@ namespace stream
|
|||||||
if (m_IsOpen)
|
if (m_IsOpen)
|
||||||
{
|
{
|
||||||
m_IsOpen = false;
|
m_IsOpen = false;
|
||||||
uint8_t packet[STREAMING_MTU];
|
uint8_t packet[MAX_PACKET_SIZE];
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
*(uint32_t *)(packet + size) = htobe32 (m_SendStreamID);
|
*(uint32_t *)(packet + size) = htobe32 (m_SendStreamID);
|
||||||
size += 4; // sendStreamID
|
size += 4; // sendStreamID
|
||||||
@ -226,7 +231,7 @@ namespace stream
|
|||||||
memset (packet + size, 0, 40);
|
memset (packet + size, 0, 40);
|
||||||
size += 40; // signature
|
size += 40; // signature
|
||||||
m_LocalDestination->Sign (packet, size, signature);
|
m_LocalDestination->Sign (packet, size, signature);
|
||||||
|
|
||||||
if (SendPacket (packet, size))
|
if (SendPacket (packet, size))
|
||||||
LogPrint ("FIN sent");
|
LogPrint ("FIN sent");
|
||||||
m_ReceiveQueue.WakeUp ();
|
m_ReceiveQueue.WakeUp ();
|
||||||
@ -266,7 +271,19 @@ namespace stream
|
|||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Stream::SendPacket (uint8_t * packet, size_t size)
|
bool Stream::SendPacket (Packet * packet)
|
||||||
|
{
|
||||||
|
if (packet)
|
||||||
|
{
|
||||||
|
bool ret = SendPacket (packet->GetBuffer (), packet->GetLength ());
|
||||||
|
delete packet;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Stream::SendPacket (const uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
const I2NPMessage * leaseSet = nullptr;
|
const I2NPMessage * leaseSet = nullptr;
|
||||||
if (m_LeaseSetUpdated)
|
if (m_LeaseSetUpdated)
|
||||||
@ -275,7 +292,7 @@ namespace stream
|
|||||||
m_LeaseSetUpdated = false;
|
m_LeaseSetUpdated = false;
|
||||||
}
|
}
|
||||||
I2NPMessage * msg = i2p::garlic::routing.WrapMessage (m_RemoteLeaseSet,
|
I2NPMessage * msg = i2p::garlic::routing.WrapMessage (m_RemoteLeaseSet,
|
||||||
CreateDataMessage (this, packet, size), leaseSet);
|
CreateDataMessage (this, buf, len), leaseSet);
|
||||||
if (!m_OutboundTunnel)
|
if (!m_OutboundTunnel)
|
||||||
m_OutboundTunnel = m_LocalDestination->GetTunnelPool ()->GetNextOutboundTunnel ();
|
m_OutboundTunnel = m_LocalDestination->GetTunnelPool ()->GetNextOutboundTunnel ();
|
||||||
if (m_OutboundTunnel)
|
if (m_OutboundTunnel)
|
||||||
@ -540,7 +557,7 @@ namespace stream
|
|||||||
LogPrint ("Data: protocol ", buf[9], " is not supported");
|
LogPrint ("Data: protocol ", buf[9], " is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
I2NPMessage * CreateDataMessage (Stream * s, uint8_t * payload, size_t len)
|
I2NPMessage * CreateDataMessage (Stream * s, const uint8_t * payload, size_t len)
|
||||||
{
|
{
|
||||||
I2NPMessage * msg = NewI2NPMessage ();
|
I2NPMessage * msg = NewI2NPMessage ();
|
||||||
CryptoPP::Gzip compressor;
|
CryptoPP::Gzip compressor;
|
||||||
|
39
Streaming.h
39
Streaming.h
@ -7,6 +7,7 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
|
#include <boost/bind.hpp>
|
||||||
#include <cryptopp/dsa.h>
|
#include <cryptopp/dsa.h>
|
||||||
#include "I2PEndian.h"
|
#include "I2PEndian.h"
|
||||||
#include "Queue.h"
|
#include "Queue.h"
|
||||||
@ -37,7 +38,7 @@ namespace stream
|
|||||||
|
|
||||||
struct Packet
|
struct Packet
|
||||||
{
|
{
|
||||||
uint8_t buf[1754];
|
uint8_t buf[MAX_PACKET_SIZE];
|
||||||
size_t len, offset;
|
size_t len, offset;
|
||||||
|
|
||||||
Packet (): len (0), offset (0) {};
|
Packet (): len (0), offset (0) {};
|
||||||
@ -80,21 +81,28 @@ namespace stream
|
|||||||
void HandleNextPacket (Packet * packet);
|
void HandleNextPacket (Packet * packet);
|
||||||
size_t Send (uint8_t * buf, size_t len, int timeout); // timeout in seconds
|
size_t Send (uint8_t * buf, size_t len, int timeout); // timeout in seconds
|
||||||
size_t Receive (uint8_t * buf, size_t len, int timeout = 0); // returns 0 if timeout expired
|
size_t Receive (uint8_t * buf, size_t len, int timeout = 0); // returns 0 if timeout expired
|
||||||
|
template<typename Buffer, typename ReceiveHandler>
|
||||||
|
void AsyncReceive (const Buffer& buffer, ReceiveHandler handler, int timeout = 0);
|
||||||
|
|
||||||
void Close ();
|
void Close ();
|
||||||
|
|
||||||
void SetLeaseSetUpdated () { m_LeaseSetUpdated = true; };
|
void SetLeaseSetUpdated () { m_LeaseSetUpdated = true; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void ConnectAndSend (uint8_t * buf, size_t len);
|
void ConnectAndSend (uint8_t * buf, size_t len);
|
||||||
void SendQuickAck ();
|
void SendQuickAck ();
|
||||||
bool SendPacket (uint8_t * packet, size_t size);
|
bool SendPacket (Packet * packet);
|
||||||
|
bool SendPacket (const uint8_t * buf, size_t len);
|
||||||
|
|
||||||
void SavePacket (Packet * packet);
|
void SavePacket (Packet * packet);
|
||||||
void ProcessPacket (Packet * packet);
|
void ProcessPacket (Packet * packet);
|
||||||
|
|
||||||
void UpdateCurrentRemoteLease ();
|
void UpdateCurrentRemoteLease ();
|
||||||
|
|
||||||
|
template<typename Buffer, typename ReceiveHandler>
|
||||||
|
void HandleReceiveTimer (const boost::system::error_code& ecode, const Buffer& buffer, ReceiveHandler handler);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
boost::asio::io_service& m_Service;
|
boost::asio::io_service& m_Service;
|
||||||
@ -106,6 +114,7 @@ namespace stream
|
|||||||
i2p::util::Queue<Packet> m_ReceiveQueue;
|
i2p::util::Queue<Packet> m_ReceiveQueue;
|
||||||
std::set<Packet *, PacketCmp> m_SavedPackets;
|
std::set<Packet *, PacketCmp> m_SavedPackets;
|
||||||
i2p::tunnel::OutboundTunnel * m_OutboundTunnel;
|
i2p::tunnel::OutboundTunnel * m_OutboundTunnel;
|
||||||
|
boost::asio::deadline_timer m_ReceiveTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StreamingDestination: public i2p::data::LocalDestination
|
class StreamingDestination: public i2p::data::LocalDestination
|
||||||
@ -183,7 +192,29 @@ namespace stream
|
|||||||
|
|
||||||
// assuming data is I2CP message
|
// assuming data is I2CP message
|
||||||
void HandleDataMessage (i2p::data::IdentHash destination, const uint8_t * buf, size_t len);
|
void HandleDataMessage (i2p::data::IdentHash destination, const uint8_t * buf, size_t len);
|
||||||
I2NPMessage * CreateDataMessage (Stream * s, uint8_t * payload, size_t len);
|
I2NPMessage * CreateDataMessage (Stream * s, const uint8_t * payload, size_t len);
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
template<typename Buffer, typename ReceiveHandler>
|
||||||
|
void Stream::AsyncReceive (const Buffer& buffer, ReceiveHandler handler, int timeout)
|
||||||
|
{
|
||||||
|
m_ReceiveTimer.expires_from_now (boost::posix_time::seconds(timeout));
|
||||||
|
m_ReceiveTimer.async_wait (boost::bind (&Stream::HandleReceiveTimer,
|
||||||
|
this, boost::asio::placeholders::error, buffer, handler));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Buffer, typename ReceiveHandler>
|
||||||
|
void Stream::HandleReceiveTimer (const boost::system::error_code& ecode, const Buffer& buffer, ReceiveHandler handler)
|
||||||
|
{
|
||||||
|
// TODO:
|
||||||
|
if (ecode == boost::asio::error::operation_aborted)
|
||||||
|
// timeout not expired
|
||||||
|
handler (boost::system::error_code (), 0);
|
||||||
|
else
|
||||||
|
// timeout expired
|
||||||
|
handler (boost::asio::error::make_error_code (boost::asio::error::timed_out), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,34 +156,36 @@ namespace i2p
|
|||||||
void Transports::PostMessage (const i2p::data::IdentHash& ident, i2p::I2NPMessage * msg)
|
void Transports::PostMessage (const i2p::data::IdentHash& ident, i2p::I2NPMessage * msg)
|
||||||
{
|
{
|
||||||
auto session = FindNTCPSession (ident);
|
auto session = FindNTCPSession (ident);
|
||||||
if (!session)
|
if (session)
|
||||||
|
session->SendI2NPMessage (msg);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
RouterInfo * r = netdb.FindRouter (ident);
|
RouterInfo * r = netdb.FindRouter (ident);
|
||||||
if (r)
|
if (r)
|
||||||
{
|
{
|
||||||
auto address = r->GetNTCPAddress ();
|
auto ssuSession = m_SSUServer ? m_SSUServer->FindSession (r) : nullptr;
|
||||||
if (address)
|
if (ssuSession)
|
||||||
{
|
ssuSession->SendI2NPMessage (msg);
|
||||||
session = new i2p::ntcp::NTCPClient (m_Service, address->host, address->port, *r);
|
|
||||||
AddNTCPSession (session);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// SSU always have lower prioprity than NTCP
|
// existing session not found. create new
|
||||||
// TODO: it shouldn't
|
// try NTCP first
|
||||||
LogPrint ("No NTCP addresses available. Trying SSU");
|
auto address = r->GetNTCPAddress ();
|
||||||
address = r->GetSSUAddress ();
|
if (address)
|
||||||
if (address && m_SSUServer)
|
{
|
||||||
{
|
auto s = new i2p::ntcp::NTCPClient (m_Service, address->host, address->port, *r);
|
||||||
auto s = m_SSUServer->GetSession (r);
|
AddNTCPSession (s);
|
||||||
if (s)
|
s->SendI2NPMessage (msg);
|
||||||
{
|
}
|
||||||
s->SendI2NPMessage (msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
LogPrint ("No SSU addresses available");
|
{
|
||||||
|
// then SSU
|
||||||
|
auto s = m_SSUServer ? m_SSUServer->GetSession (r) : nullptr;
|
||||||
|
if (s)
|
||||||
|
s->SendI2NPMessage (msg);
|
||||||
|
else
|
||||||
|
LogPrint ("No NTCP and SSU addresses available");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -192,10 +194,6 @@ namespace i2p
|
|||||||
i2p::data::netdb.RequestDestination (ident);
|
i2p::data::netdb.RequestDestination (ident);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (session)
|
|
||||||
session->SendI2NPMessage (msg);
|
|
||||||
else
|
|
||||||
LogPrint ("Session not found");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transports::DetectExternalIP ()
|
void Transports::DetectExternalIP ()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user