more fixes of misalignment

This commit is contained in:
orignal 2015-01-01 23:00:33 -05:00
parent fa4009821e
commit 29d1aa0146
7 changed files with 55 additions and 64 deletions

View File

@ -190,18 +190,17 @@ namespace client
void ClientDestination::HandleI2NPMessage (const uint8_t * buf, size_t len, i2p::tunnel::InboundTunnel * from)
{
//TODO: since we are accessing a uint8_t this is unlikely to crash due to alignment but should be improved
I2NPHeader * header = (I2NPHeader *)buf;
switch (header->typeID)
uint8_t typeID = buf[I2NP_HEADER_TYPEID_OFFSET];
switch (typeID)
{
case eI2NPData:
HandleDataMessage (buf + sizeof (I2NPHeader), be16toh (header->size));
HandleDataMessage (buf + I2NP_HEADER_SIZE, bufbe16toh (buf + I2NP_HEADER_SIZE_OFFSET));
break;
case eI2NPDatabaseStore:
HandleDatabaseStoreMessage (buf + sizeof (I2NPHeader), be16toh (header->size));
HandleDatabaseStoreMessage (buf + I2NP_HEADER_SIZE, bufbe16toh (buf + I2NP_HEADER_SIZE_OFFSET));
break;
case eI2NPDatabaseSearchReply:
HandleDatabaseSearchReplyMessage (buf + sizeof (I2NPHeader), be16toh (header->size));
HandleDatabaseSearchReplyMessage (buf + I2NP_HEADER_SIZE, bufbe16toh (buf + I2NP_HEADER_SIZE_OFFSET));
break;
default:
i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from));

View File

@ -545,19 +545,18 @@ namespace i2p
size_t GetI2NPMessageLength (const uint8_t * msg)
{
I2NPHeader * header = (I2NPHeader *)msg;
return be16toh (header->size) + sizeof (I2NPHeader);
return bufbe16toh (msg + I2NP_HEADER_SIZE_OFFSET) + I2NP_HEADER_SIZE;
}
void HandleI2NPMessage (uint8_t * msg, size_t len)
{
I2NPHeader * header = (I2NPHeader *)msg;
uint32_t msgID = be32toh (header->msgID);
LogPrint ("I2NP msg received len=", len,", type=", (int)header->typeID, ", msgID=", (unsigned int)msgID);
uint8_t typeID = msg[I2NP_HEADER_TYPEID_OFFSET];
uint32_t msgID = bufbe32toh (msg + I2NP_HEADER_MSGID_OFFSET);
LogPrint ("I2NP msg received len=", len,", type=", (int)typeID, ", msgID=", (unsigned int)msgID);
uint8_t * buf = msg + sizeof (I2NPHeader);
int size = be16toh (header->size);
switch (header->typeID)
uint8_t * buf = msg + I2NP_HEADER_SIZE;
int size = bufbe16toh (msg + I2NP_HEADER_SIZE_OFFSET);
switch (typeID)
{
case eI2NPVariableTunnelBuild:
LogPrint ("VariableTunnelBuild");
@ -576,7 +575,7 @@ namespace i2p
// TODO:
break;
default:
LogPrint ("Unexpected message ", (int)header->typeID);
LogPrint ("Unexpected message ", (int)typeID);
}
}

View File

@ -19,6 +19,11 @@ namespace i2p
const size_t I2NP_HEADER_SIZE_OFFSET = I2NP_HEADER_EXPIRATION_OFFSET + 8;
const size_t I2NP_HEADER_CHKS_OFFSET = I2NP_HEADER_SIZE_OFFSET + 2;
const size_t I2NP_HEADER_SIZE = I2NP_HEADER_CHKS_OFFSET + 1;
// I2NP short header
const size_t I2NP_SHORT_HEADER_TYPEID_OFFSET = 0;
const size_t I2NP_SHORT_HEADER_EXPIRATION_OFFSET = I2NP_SHORT_HEADER_TYPEID_OFFSET + 1;
const size_t I2NP_SHORT_HEADER_SIZE = I2NP_SHORT_HEADER_EXPIRATION_OFFSET + 4;
// Tunnel Gateway header
const size_t TUNNEL_GATEWAY_HEADER_TUNNELID_OFFSET = 0;
@ -27,21 +32,6 @@ namespace i2p
#pragma pack (1)
struct I2NPHeader
{
uint8_t typeID;
uint32_t msgID;
uint64_t expiration;
uint16_t size;
uint8_t chks;
};
struct I2NPHeaderShort
{
uint8_t typeID;
uint32_t shortExpiration;
};
struct I2NPDatabaseStoreMsg
{
uint8_t key[32];
@ -118,10 +108,10 @@ namespace tunnel
size_t len, offset, maxLen;
i2p::tunnel::InboundTunnel * from;
I2NPMessage (): buf (nullptr),len (sizeof (I2NPHeader) + 2),
I2NPMessage (): buf (nullptr),len (I2NP_HEADER_SIZE + 2),
offset(2), maxLen (0), from (nullptr) {};
// reserve 2 bytes for NTCP header
I2NPHeader * GetHeader () { return (I2NPHeader *)GetBuffer (); }; // depricated
// I2NPHeader * GetHeader () { return (I2NPHeader *)GetBuffer (); }; // depricated
// header accessors
uint8_t * GetHeaderBuffer () { return GetBuffer (); };
const uint8_t * GetHeaderBuffer () const { return GetBuffer (); };
@ -131,8 +121,10 @@ namespace tunnel
uint32_t GetMsgID () const { return bufbe32toh (GetHeaderBuffer () + I2NP_HEADER_MSGID_OFFSET); };
void SetExpiration (uint64_t expiration) { htobe64buf (GetHeaderBuffer () + I2NP_HEADER_EXPIRATION_OFFSET, expiration); };
uint64_t GetExpiration () const { return bufbe64toh (GetHeaderBuffer () + I2NP_HEADER_EXPIRATION_OFFSET); };
void SetSize (uint16_t size) { htobe16buf (GetHeaderBuffer () + I2NP_HEADER_SIZE_OFFSET, size); };
uint16_t GetSize () const { return bufbe16toh (GetHeaderBuffer () + I2NP_HEADER_SIZE_OFFSET); };
void UpdateSize () { htobe16buf (GetHeaderBuffer () + I2NP_HEADER_SIZE_OFFSET, GetPayloadLength ()); };
void UpdateSize () { SetSize (GetPayloadLength ()); };
void SetChks (uint8_t chks) { GetHeaderBuffer ()[I2NP_HEADER_CHKS_OFFSET] = chks; };
void UpdateChks ()
{
uint8_t hash[32];
@ -141,11 +133,11 @@ namespace tunnel
}
// payload
uint8_t * GetPayload () { return GetBuffer () + sizeof(I2NPHeader); };
uint8_t * GetPayload () { return GetBuffer () + I2NP_HEADER_SIZE; };
uint8_t * GetBuffer () { return buf + offset; };
const uint8_t * GetBuffer () const { return buf + offset; };
size_t GetLength () const { return len - offset; };
size_t GetPayloadLength () const { return GetLength () - sizeof(I2NPHeader); };
size_t GetPayloadLength () const { return GetLength () - I2NP_HEADER_SIZE; };
void Align (size_t alignment)
{
@ -166,25 +158,25 @@ namespace tunnel
}
// for SSU only
uint8_t * GetSSUHeader () { return buf + offset + sizeof(I2NPHeader) - sizeof(I2NPHeaderShort); };
uint8_t * GetSSUHeader () { return buf + offset + I2NP_HEADER_SIZE - I2NP_SHORT_HEADER_SIZE; };
void FromSSU (uint32_t msgID) // we have received SSU message and convert it to regular
{
I2NPHeaderShort ssu = *(I2NPHeaderShort *)GetSSUHeader ();
I2NPHeader * header = GetHeader ();
header->typeID = ssu.typeID;
header->msgID = htobe32 (msgID);
header->expiration = htobe64 (be32toh (ssu.shortExpiration)*1000LL);
header->size = htobe16 (len - offset - sizeof (I2NPHeader));
header->chks = 0;
const uint8_t * ssu = GetSSUHeader ();
GetHeaderBuffer ()[I2NP_HEADER_TYPEID_OFFSET] = ssu[I2NP_SHORT_HEADER_TYPEID_OFFSET]; // typeid
SetMsgID (msgID);
SetExpiration (bufbe32toh (ssu + I2NP_SHORT_HEADER_EXPIRATION_OFFSET)*1000LL);
SetSize (len - offset - I2NP_HEADER_SIZE);
SetChks (0);
}
uint32_t ToSSU () // return msgID
{
I2NPHeader header = *GetHeader ();
I2NPHeaderShort * ssu = (I2NPHeaderShort *)GetSSUHeader ();
ssu->typeID = header.typeID;
ssu->shortExpiration = htobe32 (be64toh (header.expiration)/1000LL);
len = offset + sizeof (I2NPHeaderShort) + be16toh (header.size);
return be32toh (header.msgID);
uint8_t header[I2NP_HEADER_SIZE];
memcpy (header, GetHeaderBuffer (), I2NP_HEADER_SIZE);
uint8_t * ssu = GetSSUHeader ();
ssu[I2NP_SHORT_HEADER_TYPEID_OFFSET] = header[I2NP_HEADER_TYPEID_OFFSET]; // typeid
htobe32buf (ssu + I2NP_SHORT_HEADER_EXPIRATION_OFFSET, bufbe64toh (header + I2NP_HEADER_EXPIRATION_OFFSET)/1000LL);
len = offset + I2NP_SHORT_HEADER_SIZE + bufbe16toh (header + I2NP_HEADER_SIZE_OFFSET);
return bufbe32toh (header + I2NP_HEADER_MSGID_OFFSET);
}
};

View File

@ -122,7 +122,7 @@ namespace data
{
while (msg)
{
switch (msg->GetHeader ()->typeID)
switch (msg->GetTypeID ())
{
case eI2NPDatabaseStore:
LogPrint ("DatabaseStore");
@ -137,7 +137,7 @@ namespace data
HandleDatabaseLookupMsg (msg);
break;
default: // WTF?
LogPrint ("NetDb: unexpected message type ", msg->GetHeader ()->typeID);
LogPrint ("NetDb: unexpected message type ", msg->GetTypeID ());
i2p::HandleI2NPMessage (msg);
}
msg = m_Queue.Get ();
@ -424,7 +424,7 @@ namespace data
void NetDb::HandleDatabaseStoreMsg (I2NPMessage * m)
{
const uint8_t * buf = m->GetPayload ();
size_t len = be16toh (m->GetHeader ()->size);
size_t len = m->GetSize ();
I2NPDatabaseStoreMsg msg;
memcpy (&msg, buf, sizeof (I2NPDatabaseStoreMsg));
size_t offset = sizeof (I2NPDatabaseStoreMsg);

View File

@ -168,7 +168,7 @@ namespace transport
{
// create new message
msg = NewI2NPMessage ();
msg->len -= sizeof (I2NPHeaderShort);
msg->len -= I2NP_SHORT_HEADER_SIZE;
incompleteMessage = new IncompleteMessage (msg);
m_IncomleteMessages[msgID] = incompleteMessage;
}
@ -246,13 +246,13 @@ namespace transport
else
{
// we expect DeliveryStatus
if (msg->GetHeader ()->typeID == eI2NPDeliveryStatus)
if (msg->GetTypeID () == eI2NPDeliveryStatus)
{
LogPrint ("SSU session established");
m_Session.Established ();
}
else
LogPrint (eLogError, "SSU unexpected message ", (int)msg->GetHeader ()->typeID);
LogPrint (eLogError, "SSU unexpected message ", (int)msg->GetTypeID ());
DeleteI2NPMessage (msg);
}
}
@ -316,7 +316,7 @@ namespace transport
payload++;
*payload = 1; // always 1 message fragment per message
payload++;
htobuf32(payload, msgID);
*(uint32_t *)payload = msgID;
payload += 4;
bool isLast = (len <= payloadSize);
size_t size = isLast ? len : payloadSize;
@ -359,7 +359,7 @@ namespace transport
payload++;
*payload = 1; // number of ACKs
payload++;
htobe32buf (payload, msgID); // msgID
*(uint32_t *)(payload) = htobe32 (msgID); // msgID
payload += 4;
*payload = 0; // number of fragments
@ -382,7 +382,7 @@ namespace transport
*payload = 1; // number of ACK bitfields
payload++;
// one ack
htobe32buf (payload, msgID); // msgID
*(uint32_t *)(payload) = htobe32 (msgID); // msgID
payload += 4;
div_t d = div (fragmentNum, 7);
memset (payload, 0x80, d.quot); // 0x80 means non-last

View File

@ -228,7 +228,7 @@ namespace tunnel
void TunnelEndpoint::HandleNextMessage (const TunnelMessageBlock& msg)
{
LogPrint ("TunnelMessage: handle fragment of ", msg.data->GetLength ()," bytes. Msg type ", (int)msg.data->GetHeader()->typeID);
LogPrint ("TunnelMessage: handle fragment of ", msg.data->GetLength ()," bytes. Msg type ", (int)msg.data->GetTypeID ());
switch (msg.deliveryType)
{
case eDeliveryTypeLocal:
@ -245,8 +245,8 @@ namespace tunnel
// to somebody else
if (!m_IsInbound) // outbound transit tunnel
{
if (msg.data->GetHeader()->typeID == eI2NPDatabaseStore ||
msg.data->GetHeader()->typeID == eI2NPDatabaseSearchReply )
auto typeID = msg.data->GetTypeID ();
if (typeID == eI2NPDatabaseStore || typeID == eI2NPDatabaseSearchReply )
{
// catch RI or reply with new list of routers
auto ds = NewI2NPMessage ();

View File

@ -68,7 +68,8 @@ namespace tunnel
if (diLen + 6 <= m_RemainingSize)
{
// delivery instructions fit
uint32_t msgID = msg->GetHeader ()->msgID; // in network bytes order
uint32_t msgID;
memcpy (&msgID, msg->GetHeaderBuffer () + I2NP_HEADER_MSGID_OFFSET, 4); // in network bytes order
size_t size = m_RemainingSize - diLen - 6; // 6 = 4 (msgID) + 2 (size)
// first fragment
@ -134,7 +135,7 @@ namespace tunnel
m_CurrentTunnelDataMsg = NewI2NPMessage ();
m_CurrentTunnelDataMsg->Align (12);
// we reserve space for padding
m_CurrentTunnelDataMsg->offset += TUNNEL_DATA_MSG_SIZE + sizeof (I2NPHeader);
m_CurrentTunnelDataMsg->offset += TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE;
m_CurrentTunnelDataMsg->len = m_CurrentTunnelDataMsg->offset;
m_RemainingSize = TUNNEL_DATA_MAX_PAYLOAD_SIZE;
}
@ -145,7 +146,7 @@ namespace tunnel
uint8_t * payload = m_CurrentTunnelDataMsg->GetBuffer ();
size_t size = m_CurrentTunnelDataMsg->len - m_CurrentTunnelDataMsg->offset;
m_CurrentTunnelDataMsg->offset = m_CurrentTunnelDataMsg->len - TUNNEL_DATA_MSG_SIZE - sizeof (I2NPHeader);
m_CurrentTunnelDataMsg->offset = m_CurrentTunnelDataMsg->len - TUNNEL_DATA_MSG_SIZE - I2NP_HEADER_SIZE;
uint8_t * buf = m_CurrentTunnelDataMsg->GetPayload ();
htobe32buf (buf, m_TunnelID);
CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator ();