|
|
@ -252,6 +252,7 @@ namespace client
|
|
|
|
Terminate ();
|
|
|
|
Terminate ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
LogPrint (eLogWarning, "SAM: incomplete message ", bytes_transferred);
|
|
|
|
LogPrint (eLogWarning, "SAM: incomplete message ", bytes_transferred);
|
|
|
@ -278,6 +279,29 @@ namespace client
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<boost::asio::ip::udp::endpoint> forward = nullptr;
|
|
|
|
|
|
|
|
if (style == SAM_VALUE_DATAGRAM && params.find(SAM_VALUE_HOST) != params.end() && params.find(SAM_VALUE_PORT) != params.end())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// udp forward selected
|
|
|
|
|
|
|
|
boost::system::error_code e;
|
|
|
|
|
|
|
|
// TODO: support hostnames in udp forward
|
|
|
|
|
|
|
|
auto addr = boost::asio::ip::address::from_string(params[SAM_VALUE_HOST], e);
|
|
|
|
|
|
|
|
if (e)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// not an ip address
|
|
|
|
|
|
|
|
SendI2PError("Invalid IP Address in HOST");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto port = std::stoi(params[SAM_VALUE_PORT]);
|
|
|
|
|
|
|
|
if (port == -1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
SendI2PError("Invalid port");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
forward = std::make_shared<boost::asio::ip::udp::endpoint>(addr, port);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// create destination
|
|
|
|
// create destination
|
|
|
|
m_Session = m_Owner.CreateSession (id, destination == SAM_VALUE_TRANSIENT ? "" : destination, ¶ms);
|
|
|
|
m_Session = m_Owner.CreateSession (id, destination == SAM_VALUE_TRANSIENT ? "" : destination, ¶ms);
|
|
|
|
if (m_Session)
|
|
|
|
if (m_Session)
|
|
|
@ -285,6 +309,7 @@ namespace client
|
|
|
|
m_SocketType = eSAMSocketTypeSession;
|
|
|
|
m_SocketType = eSAMSocketTypeSession;
|
|
|
|
if (style == SAM_VALUE_DATAGRAM)
|
|
|
|
if (style == SAM_VALUE_DATAGRAM)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
m_Session->UDPEndpoint = forward;
|
|
|
|
auto dest = m_Session->localDestination->CreateDatagramDestination ();
|
|
|
|
auto dest = m_Session->localDestination->CreateDatagramDestination ();
|
|
|
|
dest->SetReceiver (std::bind (&SAMSocket::HandleI2PDatagramReceive, shared_from_this (),
|
|
|
|
dest->SetReceiver (std::bind (&SAMSocket::HandleI2PDatagramReceive, shared_from_this (),
|
|
|
|
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
|
|
|
|
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
|
|
|
@ -491,6 +516,17 @@ namespace client
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SAMSocket::SendI2PError(const std::string & msg)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
LogPrint (eLogError, "SAM: i2p error ", msg);
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
|
|
|
|
size_t len = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_SESSION_STATUS_I2P_ERROR, msg.c_str());
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
size_t len = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_SESSION_STATUS_I2P_ERROR, msg.c_str());
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
SendMessageReply (m_Buffer, len, true);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SAMSocket::HandleNamingLookupLeaseSetRequestComplete (std::shared_ptr<i2p::data::LeaseSet> leaseSet, i2p::data::IdentHash ident)
|
|
|
|
void SAMSocket::HandleNamingLookupLeaseSetRequestComplete (std::shared_ptr<i2p::data::LeaseSet> leaseSet, i2p::data::IdentHash ident)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (leaseSet)
|
|
|
|
if (leaseSet)
|
|
|
@ -692,6 +728,26 @@ namespace client
|
|
|
|
{
|
|
|
|
{
|
|
|
|
LogPrint (eLogDebug, "SAM: datagram received ", len);
|
|
|
|
LogPrint (eLogDebug, "SAM: datagram received ", len);
|
|
|
|
auto base64 = from.ToBase64 ();
|
|
|
|
auto base64 = from.ToBase64 ();
|
|
|
|
|
|
|
|
auto ep = m_Session->UDPEndpoint;
|
|
|
|
|
|
|
|
if (ep)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// udp forward enabled
|
|
|
|
|
|
|
|
size_t bsz = base64.size();
|
|
|
|
|
|
|
|
size_t sz = bsz + 1 + len;
|
|
|
|
|
|
|
|
// build datagram body
|
|
|
|
|
|
|
|
uint8_t * data = new uint8_t[sz];
|
|
|
|
|
|
|
|
// Destination
|
|
|
|
|
|
|
|
memcpy(data, base64.c_str(), bsz);
|
|
|
|
|
|
|
|
// linefeed
|
|
|
|
|
|
|
|
data[bsz] = '\n';
|
|
|
|
|
|
|
|
// Payload
|
|
|
|
|
|
|
|
memcpy(data+bsz+1, buf, len);
|
|
|
|
|
|
|
|
// send to remote endpoint
|
|
|
|
|
|
|
|
m_Owner.SendTo(data, sz, ep);
|
|
|
|
|
|
|
|
delete [] data;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
size_t l = sprintf_s ((char *)m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE, SAM_DATAGRAM_RECEIVED, base64.c_str (), (long unsigned int)len);
|
|
|
|
size_t l = sprintf_s ((char *)m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE, SAM_DATAGRAM_RECEIVED, base64.c_str (), (long unsigned int)len);
|
|
|
|
#else
|
|
|
|
#else
|
|
|
@ -706,9 +762,11 @@ namespace client
|
|
|
|
else
|
|
|
|
else
|
|
|
|
LogPrint (eLogWarning, "SAM: received datagram size ", len," exceeds buffer");
|
|
|
|
LogPrint (eLogWarning, "SAM: received datagram size ", len," exceeds buffer");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SAMSession::SAMSession (std::shared_ptr<ClientDestination> dest):
|
|
|
|
SAMSession::SAMSession (std::shared_ptr<ClientDestination> dest):
|
|
|
|
localDestination (dest)
|
|
|
|
localDestination (dest),
|
|
|
|
|
|
|
|
UDPEndpoint(nullptr)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -873,6 +931,14 @@ namespace client
|
|
|
|
return nullptr;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SAMBridge::SendTo(const uint8_t * buf, size_t len, std::shared_ptr<boost::asio::ip::udp::endpoint> remote)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if(remote)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
m_DatagramSocket.send_to(boost::asio::buffer(buf, len), *remote);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SAMBridge::ReceiveDatagram ()
|
|
|
|
void SAMBridge::ReceiveDatagram ()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
m_DatagramSocket.async_receive_from (
|
|
|
|
m_DatagramSocket.async_receive_from (
|
|
|
|