TunnelGateway.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. #include <string.h>
  2. #include "Crypto.h"
  3. #include "I2PEndian.h"
  4. #include "Log.h"
  5. #include "RouterContext.h"
  6. #include "Transports.h"
  7. #include "TunnelGateway.h"
  8. namespace i2p
  9. {
  10. namespace tunnel
  11. {
  12. TunnelGatewayBuffer::TunnelGatewayBuffer ():
  13. m_CurrentTunnelDataMsg (nullptr), m_RemainingSize (0)
  14. {
  15. RAND_bytes (m_NonZeroRandomBuffer, TUNNEL_DATA_MAX_PAYLOAD_SIZE);
  16. for (size_t i = 0; i < TUNNEL_DATA_MAX_PAYLOAD_SIZE; i++)
  17. if (!m_NonZeroRandomBuffer[i]) m_NonZeroRandomBuffer[i] = 1;
  18. }
  19. TunnelGatewayBuffer::~TunnelGatewayBuffer ()
  20. {
  21. ClearTunnelDataMsgs ();
  22. }
  23. void TunnelGatewayBuffer::PutI2NPMsg (const TunnelMessageBlock& block)
  24. {
  25. bool messageCreated = false;
  26. if (!m_CurrentTunnelDataMsg)
  27. {
  28. CreateCurrentTunnelDataMessage ();
  29. messageCreated = true;
  30. }
  31. // create delivery instructions
  32. uint8_t di[43]; // max delivery instruction length is 43 for tunnel
  33. size_t diLen = 1;// flag
  34. if (block.deliveryType != eDeliveryTypeLocal) // tunnel or router
  35. {
  36. if (block.deliveryType == eDeliveryTypeTunnel)
  37. {
  38. htobe32buf (di + diLen, block.tunnelID);
  39. diLen += 4; // tunnelID
  40. }
  41. memcpy (di + diLen, block.hash, 32);
  42. diLen += 32; //len
  43. }
  44. di[0] = block.deliveryType << 5; // set delivery type
  45. // create fragments
  46. const std::shared_ptr<I2NPMessage> & msg = block.data;
  47. size_t fullMsgLen = diLen + msg->GetLength () + 2; // delivery instructions + payload + 2 bytes length
  48. if (!messageCreated && fullMsgLen > m_RemainingSize) // check if we should complete previous message
  49. {
  50. size_t numFollowOnFragments = fullMsgLen / TUNNEL_DATA_MAX_PAYLOAD_SIZE;
  51. // length of bytes doesn't fit full tunnel message
  52. // every follow-on fragment adds 7 bytes
  53. size_t nonFit = (fullMsgLen + numFollowOnFragments*7) % TUNNEL_DATA_MAX_PAYLOAD_SIZE;
  54. if (!nonFit || nonFit > m_RemainingSize)
  55. {
  56. CompleteCurrentTunnelDataMessage ();
  57. CreateCurrentTunnelDataMessage ();
  58. }
  59. }
  60. if (fullMsgLen <= m_RemainingSize)
  61. {
  62. // message fits. First and last fragment
  63. htobe16buf (di + diLen, msg->GetLength ());
  64. diLen += 2; // size
  65. memcpy (m_CurrentTunnelDataMsg->buf + m_CurrentTunnelDataMsg->len, di, diLen);
  66. memcpy (m_CurrentTunnelDataMsg->buf + m_CurrentTunnelDataMsg->len + diLen, msg->GetBuffer (), msg->GetLength ());
  67. m_CurrentTunnelDataMsg->len += diLen + msg->GetLength ();
  68. m_RemainingSize -= diLen + msg->GetLength ();
  69. if (!m_RemainingSize)
  70. CompleteCurrentTunnelDataMessage ();
  71. }
  72. else
  73. {
  74. if (diLen + 6 <= m_RemainingSize)
  75. {
  76. // delivery instructions fit
  77. uint32_t msgID;
  78. memcpy (&msgID, msg->GetHeader () + I2NP_HEADER_MSGID_OFFSET, 4); // in network bytes order
  79. size_t size = m_RemainingSize - diLen - 6; // 6 = 4 (msgID) + 2 (size)
  80. // first fragment
  81. di[0] |= 0x08; // fragmented
  82. htobuf32 (di + diLen, msgID);
  83. diLen += 4; // Message ID
  84. htobe16buf (di + diLen, size);
  85. diLen += 2; // size
  86. memcpy (m_CurrentTunnelDataMsg->buf + m_CurrentTunnelDataMsg->len, di, diLen);
  87. memcpy (m_CurrentTunnelDataMsg->buf + m_CurrentTunnelDataMsg->len + diLen, msg->GetBuffer (), size);
  88. m_CurrentTunnelDataMsg->len += diLen + size;
  89. CompleteCurrentTunnelDataMessage ();
  90. // follow on fragments
  91. int fragmentNumber = 1;
  92. while (size < msg->GetLength ())
  93. {
  94. CreateCurrentTunnelDataMessage ();
  95. uint8_t * buf = m_CurrentTunnelDataMsg->GetBuffer ();
  96. buf[0] = 0x80 | (fragmentNumber << 1); // frag
  97. bool isLastFragment = false;
  98. size_t s = msg->GetLength () - size;
  99. if (s > TUNNEL_DATA_MAX_PAYLOAD_SIZE - 7) // 7 follow on instructions
  100. s = TUNNEL_DATA_MAX_PAYLOAD_SIZE - 7;
  101. else // last fragment
  102. {
  103. buf[0] |= 0x01;
  104. isLastFragment = true;
  105. }
  106. htobuf32 (buf + 1, msgID); //Message ID
  107. htobe16buf (buf + 5, s); // size
  108. memcpy (buf + 7, msg->GetBuffer () + size, s);
  109. m_CurrentTunnelDataMsg->len += s+7;
  110. if (isLastFragment)
  111. {
  112. if(m_RemainingSize < (s+7)) {
  113. LogPrint (eLogError, "TunnelGateway: remaining size overflow: ", m_RemainingSize, " < ", s+7);
  114. } else {
  115. m_RemainingSize -= s+7;
  116. if (m_RemainingSize == 0)
  117. CompleteCurrentTunnelDataMessage ();
  118. }
  119. }
  120. else
  121. CompleteCurrentTunnelDataMessage ();
  122. size += s;
  123. fragmentNumber++;
  124. }
  125. }
  126. else
  127. {
  128. // delivery instructions don't fit. Create new message
  129. CompleteCurrentTunnelDataMessage ();
  130. PutI2NPMsg (block);
  131. // don't delete msg because it's taken care inside
  132. }
  133. }
  134. }
  135. void TunnelGatewayBuffer::ClearTunnelDataMsgs ()
  136. {
  137. m_TunnelDataMsgs.clear ();
  138. m_CurrentTunnelDataMsg = nullptr;
  139. }
  140. void TunnelGatewayBuffer::CreateCurrentTunnelDataMessage ()
  141. {
  142. m_CurrentTunnelDataMsg = nullptr;
  143. m_CurrentTunnelDataMsg = NewI2NPShortMessage ();
  144. m_CurrentTunnelDataMsg->Align (12);
  145. // we reserve space for padding
  146. m_CurrentTunnelDataMsg->offset += TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE;
  147. m_CurrentTunnelDataMsg->len = m_CurrentTunnelDataMsg->offset;
  148. m_RemainingSize = TUNNEL_DATA_MAX_PAYLOAD_SIZE;
  149. }
  150. void TunnelGatewayBuffer::CompleteCurrentTunnelDataMessage ()
  151. {
  152. if (!m_CurrentTunnelDataMsg) return;
  153. uint8_t * payload = m_CurrentTunnelDataMsg->GetBuffer ();
  154. size_t size = m_CurrentTunnelDataMsg->len - m_CurrentTunnelDataMsg->offset;
  155. m_CurrentTunnelDataMsg->offset = m_CurrentTunnelDataMsg->len - TUNNEL_DATA_MSG_SIZE - I2NP_HEADER_SIZE;
  156. uint8_t * buf = m_CurrentTunnelDataMsg->GetPayload ();
  157. RAND_bytes (buf + 4, 16); // original IV
  158. memcpy (payload + size, buf + 4, 16); // copy IV for checksum
  159. uint8_t hash[32];
  160. SHA256(payload, size+16, hash);
  161. memcpy (buf+20, hash, 4); // checksum
  162. payload[-1] = 0; // zero
  163. ptrdiff_t paddingSize = payload - buf - 25; // 25 = 24 + 1
  164. if (paddingSize > 0)
  165. {
  166. // non-zero padding
  167. auto randomOffset = rand () % (TUNNEL_DATA_MAX_PAYLOAD_SIZE - paddingSize + 1);
  168. memcpy (buf + 24, m_NonZeroRandomBuffer + randomOffset, paddingSize);
  169. }
  170. // we can't fill message header yet because encryption is required
  171. m_TunnelDataMsgs.push_back (m_CurrentTunnelDataMsg);
  172. m_CurrentTunnelDataMsg = nullptr;
  173. }
  174. void TunnelGateway::SendTunnelDataMsg (const TunnelMessageBlock& block)
  175. {
  176. if (block.data)
  177. {
  178. PutTunnelDataMsg (block);
  179. SendBuffer ();
  180. }
  181. }
  182. void TunnelGateway::PutTunnelDataMsg (const TunnelMessageBlock& block)
  183. {
  184. if (block.data)
  185. m_Buffer.PutI2NPMsg (block);
  186. }
  187. void TunnelGateway::SendBuffer ()
  188. {
  189. m_Buffer.CompleteCurrentTunnelDataMessage ();
  190. std::vector<std::shared_ptr<I2NPMessage> > newTunnelMsgs;
  191. const auto& tunnelDataMsgs = m_Buffer.GetTunnelDataMsgs ();
  192. for (auto& tunnelMsg : tunnelDataMsgs)
  193. {
  194. auto newMsg = CreateEmptyTunnelDataMsg ();
  195. m_Tunnel->EncryptTunnelMsg (tunnelMsg, newMsg);
  196. htobe32buf (newMsg->GetPayload (), m_Tunnel->GetNextTunnelID ());
  197. newMsg->FillI2NPMessageHeader (eI2NPTunnelData);
  198. newTunnelMsgs.push_back (newMsg);
  199. m_NumSentBytes += TUNNEL_DATA_MSG_SIZE;
  200. }
  201. m_Buffer.ClearTunnelDataMsgs ();
  202. i2p::transport::transports.SendMessages (m_Tunnel->GetNextIdentHash (), newTunnelMsgs);
  203. }
  204. }
  205. }