|
|
@ -326,8 +326,7 @@ namespace transport |
|
|
|
{ |
|
|
|
{ |
|
|
|
Fragment * fragment = new Fragment; |
|
|
|
Fragment * fragment = new Fragment; |
|
|
|
fragment->fragmentNum = fragmentNum; |
|
|
|
fragment->fragmentNum = fragmentNum; |
|
|
|
uint8_t * buf = fragment->buf; |
|
|
|
uint8_t * payload = fragment->buf + sizeof (SSUHeader); |
|
|
|
uint8_t * payload = buf + sizeof (SSUHeader); |
|
|
|
|
|
|
|
*payload = DATA_FLAG_WANT_REPLY; // for compatibility
|
|
|
|
*payload = DATA_FLAG_WANT_REPLY; // for compatibility
|
|
|
|
payload++; |
|
|
|
payload++; |
|
|
|
*payload = 1; // always 1 message fragment per message
|
|
|
|
*payload = 1; // always 1 message fragment per message
|
|
|
@ -346,14 +345,20 @@ namespace transport |
|
|
|
payload += 3; |
|
|
|
payload += 3; |
|
|
|
memcpy (payload, msgBuf, size); |
|
|
|
memcpy (payload, msgBuf, size); |
|
|
|
|
|
|
|
|
|
|
|
size += payload - buf; |
|
|
|
size += payload - fragment->buf; |
|
|
|
if (size & 0x0F) // make sure 16 bytes boundary
|
|
|
|
uint8_t rem = size & 0x0F; |
|
|
|
size = ((size >> 4) + 1) << 4; // (/16 + 1)*16
|
|
|
|
if (rem) // make sure 16 bytes boundary
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto padding = 16 - rem; |
|
|
|
|
|
|
|
memset (fragment->buf + size, 0, padding); |
|
|
|
|
|
|
|
size += padding; |
|
|
|
|
|
|
|
} |
|
|
|
fragment->len = size; |
|
|
|
fragment->len = size; |
|
|
|
fragments.push_back (std::unique_ptr<Fragment> (fragment)); |
|
|
|
fragments.push_back (std::unique_ptr<Fragment> (fragment)); |
|
|
|
|
|
|
|
|
|
|
|
// encrypt message with session key
|
|
|
|
// encrypt message with session key
|
|
|
|
m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, buf, size); |
|
|
|
uint8_t buf[SSU_V4_MAX_PACKET_SIZE + 18]; |
|
|
|
|
|
|
|
m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, fragment->buf, size, buf); |
|
|
|
try |
|
|
|
try |
|
|
|
{ |
|
|
|
{ |
|
|
|
m_Session.Send (buf, size); |
|
|
|
m_Session.Send (buf, size); |
|
|
@ -432,6 +437,7 @@ namespace transport |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (ecode != boost::asio::error::operation_aborted) |
|
|
|
if (ecode != boost::asio::error::operation_aborted) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
uint8_t buf[SSU_V4_MAX_PACKET_SIZE + 18]; |
|
|
|
uint32_t ts = i2p::util::GetSecondsSinceEpoch (); |
|
|
|
uint32_t ts = i2p::util::GetSecondsSinceEpoch (); |
|
|
|
int numResent = 0; |
|
|
|
int numResent = 0; |
|
|
|
for (auto it = m_SentMessages.begin (); it != m_SentMessages.end ();) |
|
|
|
for (auto it = m_SentMessages.begin (); it != m_SentMessages.end ();) |
|
|
@ -445,7 +451,8 @@ namespace transport |
|
|
|
{ |
|
|
|
{ |
|
|
|
try |
|
|
|
try |
|
|
|
{ |
|
|
|
{ |
|
|
|
m_Session.Send (f->buf, f->len); // resend
|
|
|
|
m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, f->buf, f->len, buf); |
|
|
|
|
|
|
|
m_Session.Send (buf, f->len); // resend
|
|
|
|
numResent++; |
|
|
|
numResent++; |
|
|
|
} |
|
|
|
} |
|
|
|
catch (boost::system::system_error& ec) |
|
|
|
catch (boost::system::system_error& ec) |
|
|
|