|
|
@ -47,7 +47,7 @@ namespace ssu |
|
|
|
{ |
|
|
|
{ |
|
|
|
switch (m_State) |
|
|
|
switch (m_State) |
|
|
|
{ |
|
|
|
{ |
|
|
|
case eSessionStateEstablised: |
|
|
|
case eSessionStateEstablished: |
|
|
|
// most common case
|
|
|
|
// most common case
|
|
|
|
ProcessMessage (buf, len); |
|
|
|
ProcessMessage (buf, len); |
|
|
|
break; |
|
|
|
break; |
|
|
@ -131,7 +131,7 @@ namespace ssu |
|
|
|
LogPrint ("Our external address is ", ourIP.to_string (), ":", ourPort); |
|
|
|
LogPrint ("Our external address is ", ourIP.to_string (), ":", ourPort); |
|
|
|
uint32_t relayTag = be32toh (*(uint32_t *)(buf + sizeof (SSUHeader) + 263)); |
|
|
|
uint32_t relayTag = be32toh (*(uint32_t *)(buf + sizeof (SSUHeader) + 263)); |
|
|
|
SendSessionConfirmed (buf + sizeof (SSUHeader), ourAddress, relayTag); |
|
|
|
SendSessionConfirmed (buf + sizeof (SSUHeader), ourAddress, relayTag); |
|
|
|
m_State = eSessionStateEstablised; |
|
|
|
m_State = eSessionStateEstablished; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -147,7 +147,7 @@ namespace ssu |
|
|
|
m_State = eSessionStateConfirmedReceived; |
|
|
|
m_State = eSessionStateConfirmedReceived; |
|
|
|
LogPrint ("Session confirmed received"); |
|
|
|
LogPrint ("Session confirmed received"); |
|
|
|
// TODO:
|
|
|
|
// TODO:
|
|
|
|
m_State = eSessionStateEstablised; |
|
|
|
m_State = eSessionStateEstablished; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
LogPrint ("Unexpected payload type ", (int)(header->flag >> 4)); |
|
|
|
LogPrint ("Unexpected payload type ", (int)(header->flag >> 4)); |
|
|
@ -368,6 +368,28 @@ namespace ssu |
|
|
|
uint8_t flag = *buf; |
|
|
|
uint8_t flag = *buf; |
|
|
|
buf++; |
|
|
|
buf++; |
|
|
|
LogPrint ("Process SSU data flags=", (int)flag); |
|
|
|
LogPrint ("Process SSU data flags=", (int)flag); |
|
|
|
|
|
|
|
if (flag & DATA_FLAG_EXPLICIT_ACKS_INCLUDED) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// explicit ACKs
|
|
|
|
|
|
|
|
uint8_t numAcks =*buf; |
|
|
|
|
|
|
|
buf++; |
|
|
|
|
|
|
|
// TODO: process ACKs
|
|
|
|
|
|
|
|
buf += numAcks*4; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (flag & DATA_FLAG_ACK_BITFIELDS_INCLUDED) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// explicit ACK bitfields
|
|
|
|
|
|
|
|
uint8_t numBitfields =*buf; |
|
|
|
|
|
|
|
buf++; |
|
|
|
|
|
|
|
for (int i = 0; i < numBitfields; i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
buf += 4; // msgID
|
|
|
|
|
|
|
|
// TODO: process ACH bitfields
|
|
|
|
|
|
|
|
while (*buf & 0x80) // not last
|
|
|
|
|
|
|
|
buf++; |
|
|
|
|
|
|
|
buf++; // last byte
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
uint8_t numFragments = *buf; // number of fragments
|
|
|
|
uint8_t numFragments = *buf; // number of fragments
|
|
|
|
buf++; |
|
|
|
buf++; |
|
|
|
for (int i = 0; i < numFragments; i++) |
|
|
|
for (int i = 0; i < numFragments; i++) |
|
|
@ -425,16 +447,19 @@ namespace ssu |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint8_t buf[48]; // actual length is 44 = 37 + 7 but pad it to multiple of 16
|
|
|
|
uint8_t buf[48]; // actual length is 44 = 37 + 7 but pad it to multiple of 16
|
|
|
|
uint8_t iv[16]; |
|
|
|
uint8_t iv[16]; |
|
|
|
*buf = DATA_FLAG_EXPLICIT_ACKS_INCLUDED; // flag
|
|
|
|
uint8_t * payload = buf + sizeof (SSUHeader); |
|
|
|
buf[1] = 1; // number of ACKs
|
|
|
|
*payload = DATA_FLAG_EXPLICIT_ACKS_INCLUDED; // flag
|
|
|
|
*(uint32_t *)(buf + 2) = htobe32 (msgID); // msgID
|
|
|
|
payload++; |
|
|
|
buf[6] = 0; // number of fragments
|
|
|
|
*payload = 1; // number of ACKs
|
|
|
|
|
|
|
|
payload++; |
|
|
|
|
|
|
|
*(uint32_t *)(payload) = htobe32 (msgID); // msgID
|
|
|
|
|
|
|
|
payload += 4; |
|
|
|
|
|
|
|
*payload = 0; // number of fragments
|
|
|
|
|
|
|
|
|
|
|
|
CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator (); |
|
|
|
CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator (); |
|
|
|
rnd.GenerateBlock (iv, 16); // random iv
|
|
|
|
rnd.GenerateBlock (iv, 16); // random iv
|
|
|
|
// encrypt message with session key
|
|
|
|
// encrypt message with session key
|
|
|
|
FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, buf, 48, m_SessionKey, iv, m_MacKey); |
|
|
|
FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, buf, 48, m_SessionKey, iv, m_MacKey); |
|
|
|
m_State = eSessionStateConfirmedSent; |
|
|
|
|
|
|
|
m_Server->Send (buf, 48, m_RemoteEndpoint); |
|
|
|
m_Server->Send (buf, 48, m_RemoteEndpoint); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|