Skip to content
This repository has been archived by the owner on Sep 1, 2022. It is now read-only.

Commit

Permalink
Kovri: implement native-endian bytestream read
Browse files Browse the repository at this point in the history
Removes i2pd's native-endian read implementation

Note: i2pd's free function call design procured spaghetti code. This
commit does not resolve that design issue but a bytstream refactor will.
See the TODOs regarding bytestream refactor.
  • Loading branch information
anonimal committed Feb 8, 2018
1 parent 2809972 commit ffb2fff
Show file tree
Hide file tree
Showing 18 changed files with 144 additions and 157 deletions.
5 changes: 3 additions & 2 deletions src/client/api/streaming.cc
@@ -1,5 +1,5 @@
/** //
* Copyright (c) 2013-2017, The Kovri I2P Router Project //
* Copyright (c) 2013-2018, The Kovri I2P Router Project //
* //
* All rights reserved. //
* //
Expand Down Expand Up @@ -262,7 +262,8 @@ void Stream::ProcessPacket(
<< m_RemoteIdentity.GetIdentHash().ToBase64();
}
if (flags & PACKET_FLAG_MAX_PACKET_SIZE_INCLUDED) {
std::uint16_t max_packet_size = bufbe16toh(option_data);
std::uint16_t const max_packet_size =
core::InputByteStream::Read<std::uint16_t>(option_data);
LOG(debug) << "Stream: max packet size " << max_packet_size;
option_data += 2;
}
Expand Down
21 changes: 12 additions & 9 deletions src/client/api/streaming.h
@@ -1,5 +1,5 @@
/** //
* Copyright (c) 2013-2017, The Kovri I2P Router Project //
* Copyright (c) 2013-2018, The Kovri I2P Router Project //
* //
* All rights reserved. //
* //
Expand Down Expand Up @@ -84,9 +84,10 @@ const int MAX_WINDOW_SIZE = 128;
const int INITIAL_RTT = 8000; // in milliseconds
const int INITIAL_RTO = 9000; // in milliseconds

// TODO(anonimal): bytestream refactor
struct Packet {
std::size_t len, offset;
std::uint8_t buf[MAX_PACKET_SIZE];
std::uint8_t buf[MAX_PACKET_SIZE]; // TODO(anonimal): zero-initialize
std::uint64_t send_time;

Packet()
Expand All @@ -102,39 +103,41 @@ struct Packet {
return len - offset;
}

// TODO(anonimal): the excessive amount of static member calls will be replaced by the bytestream refactor

std::uint32_t GetSendStreamID() const {
return bufbe32toh(buf);
return core::InputByteStream::Read<std::uint32_t>(buf);
}

std::uint32_t GetReceiveStreamID() const {
return bufbe32toh(buf + 4);
return core::InputByteStream::Read<std::uint32_t>(buf + 4);
}

std::uint32_t GetSeqn() const {
return bufbe32toh(buf + 8);
return core::InputByteStream::Read<std::uint32_t>(buf + 8);
}

std::uint32_t GetAckThrough() const {
return bufbe32toh(buf + 12);
return core::InputByteStream::Read<std::uint32_t>(buf + 12);
}

std::uint8_t GetNACKCount() const {
return buf[16];
}

std::uint32_t GetNACK(int i) const {
return bufbe32toh(buf + 17 + 4 * i);
return core::InputByteStream::Read<std::uint32_t>(buf + 17 + 4 * i);
}

const std::uint8_t* GetOption() const {
return buf + 17 + GetNACKCount() * 4 + 3;
} // 3 = resendDelay + flags

std::uint16_t GetFlags() const {
return bufbe16toh(GetOption() - 2);
return core::InputByteStream::Read<std::uint16_t>(GetOption() - 2);
}
std::uint16_t GetOptionSize() const {
return bufbe16toh(GetOption ());
return core::InputByteStream::Read<std::uint16_t>(GetOption());
}
const std::uint8_t* GetOptionData() const {
return GetOption() + 2;
Expand Down
18 changes: 11 additions & 7 deletions src/client/destination.cc
Expand Up @@ -50,6 +50,8 @@
namespace kovri {
namespace client {

// TODO(anonimal): bytestream refactor

ClientDestination::ClientDestination(
const kovri::core::PrivateKeys& keys,
bool is_public,
Expand Down Expand Up @@ -285,9 +287,10 @@ void ClientDestination::HandleI2NPMessage(
case kovri::core::I2NPData:
HandleDataMessage(
buf + kovri::core::I2NP_HEADER_SIZE,
bufbe16toh(
// TODO(unassigned): unused
core::InputByteStream::Read<std::uint16_t>(
buf + kovri::core::I2NP_HEADER_SIZE_OFFSET));
break;
break;
case kovri::core::I2NPDeliveryStatus:
// we assume tunnel tests non-encrypted
HandleDeliveryStatusMessage(
Expand All @@ -299,13 +302,13 @@ void ClientDestination::HandleI2NPMessage(
case kovri::core::I2NPDatabaseStore:
HandleDatabaseStoreMessage(
buf + kovri::core::I2NP_HEADER_SIZE,
bufbe16toh(
core::InputByteStream::Read<std::uint16_t>(
buf + kovri::core::I2NP_HEADER_SIZE_OFFSET));
break;
case kovri::core::I2NPDatabaseSearchReply:
HandleDatabaseSearchReplyMessage(
buf + kovri::core::I2NP_HEADER_SIZE,
bufbe16toh(
core::InputByteStream::Read<std::uint16_t>(
buf + kovri::core::I2NP_HEADER_SIZE_OFFSET));
break;
default:
Expand All @@ -320,7 +323,8 @@ void ClientDestination::HandleI2NPMessage(
void ClientDestination::HandleDatabaseStoreMessage(
const std::uint8_t* buf,
std::size_t len) {
std::uint32_t reply_token = bufbe32toh(buf + kovri::core::DATABASE_STORE_REPLY_TOKEN_OFFSET);
std::uint32_t const reply_token = core::InputByteStream::Read<std::uint32_t>(
buf + core::DATABASE_STORE_REPLY_TOKEN_OFFSET);
std::size_t offset = kovri::core::DATABASE_STORE_HEADER_SIZE;
if (reply_token) {
LOG(debug) << "ClientDestination: reply token is ignored for DatabaseStore";
Expand Down Expand Up @@ -416,8 +420,8 @@ void ClientDestination::HandleDatabaseSearchReplyMessage(

void ClientDestination::HandleDeliveryStatusMessage(
std::shared_ptr<kovri::core::I2NPMessage> msg) {
std::uint32_t msg_ID =
bufbe32toh(msg->GetPayload() + kovri::core::DELIVERY_STATUS_MSGID_OFFSET);
std::uint32_t const msg_ID = core::InputByteStream::Read<std::uint32_t>(
msg->GetPayload() + kovri::core::DELIVERY_STATUS_MSGID_OFFSET);
if (msg_ID == m_PublishReplyToken) {
LOG(debug) << "ClientDestination: publishing confirmed";
m_ExcludedFloodfills.clear();
Expand Down
17 changes: 11 additions & 6 deletions src/core/router/garlic.cc
@@ -1,5 +1,5 @@
/** //
* Copyright (c) 2013-2017, The Kovri I2P Router Project //
* Copyright (c) 2013-2018, The Kovri I2P Router Project //
* //
* All rights reserved. //
* //
Expand Down Expand Up @@ -47,6 +47,8 @@
namespace kovri {
namespace core {

// TODO(anonimal): bytestream refactor

GarlicRoutingSession::GarlicRoutingSession(
GarlicDestination* owner,
std::shared_ptr<const kovri::core::RoutingDestination> destination,
Expand Down Expand Up @@ -442,7 +444,7 @@ void GarlicDestination::HandleGarlicMessage(
// TODO(anonimal): this try block should be handled entirely by caller
try {
std::uint8_t* buf = msg->GetPayload();
std::uint32_t length = bufbe32toh(buf);
std::uint32_t length = core::InputByteStream::Read<std::uint32_t>(buf);
if (length > msg->GetLength()) {
LOG(error)
<< "GarlicDestination: message length " << length
Expand Down Expand Up @@ -530,7 +532,8 @@ void GarlicDestination::HandleAESBlock(
std::shared_ptr<kovri::core::InboundTunnel> from) {
// TODO(anonimal): this try block should be handled entirely by caller
try {
std::uint16_t tag_count = bufbe16toh(buf);
std::uint16_t const tag_count =
core::InputByteStream::Read<std::uint16_t>(buf);
buf += 2;
len -= 2;
if (tag_count > 0) {
Expand All @@ -546,7 +549,8 @@ void GarlicDestination::HandleAESBlock(
}
buf += tag_count * 32;
len -= tag_count * 32;
std::uint32_t payload_size = bufbe32toh(buf);
std::uint32_t const payload_size =
core::InputByteStream::Read<std::uint32_t>(buf);
if (payload_size > len) {
LOG(error) << "GarlicDestination: unexpected payload size " << payload_size;
return;
Expand Down Expand Up @@ -642,7 +646,8 @@ void GarlicDestination::HandleGarlicPayload(
// gateway_hash and gateway_tunnel sequence is reverted
std::uint8_t* gateway_hash = buf;
buf += 32;
std::uint32_t gateway_tunnel = bufbe32toh(buf);
std::uint32_t const gateway_tunnel =
core::InputByteStream::Read<std::uint32_t>(buf);
buf += 4;
std::shared_ptr<kovri::core::OutboundTunnel> tunnel;
if (from && from->GetTunnelPool())
Expand Down Expand Up @@ -726,7 +731,7 @@ void GarlicDestination::DeliveryStatusSent(
// TODO(anonimal): at worst, the message isn't ACKd
void GarlicDestination::HandleDeliveryStatusMessage(
std::shared_ptr<I2NPMessage> msg) {
std::uint32_t msg_ID = bufbe32toh(msg->GetPayload()); {
std::uint32_t const msg_ID = core::InputByteStream::Read<std::uint32_t>(msg->GetPayload()); {
auto it = m_CreatedSessions.find(msg_ID);
if (it != m_CreatedSessions.end()) {
it->second->MessageConfirmed(msg_ID);
Expand Down
32 changes: 19 additions & 13 deletions src/core/router/i2np.cc
@@ -1,5 +1,5 @@
/** //
* Copyright (c) 2013-2017, The Kovri I2P Router Project //
* Copyright (c) 2013-2018, The Kovri I2P Router Project //
* //
* All rights reserved. //
* //
Expand Down Expand Up @@ -54,6 +54,8 @@
namespace kovri {
namespace core {

// TODO(anonimal): bytestream refactor

std::unique_ptr<I2NPMessage> NewI2NPMessage() {
return std::make_unique<I2NPMessageBuffer<I2NP_MAX_MESSAGE_SIZE>>();
}
Expand Down Expand Up @@ -380,9 +382,9 @@ bool HandleBuildRequestRecords(
!kovri::core::transports.IsBandwidthExceeded()) {
kovri::core::TransitTunnel* transit_tunnel =
kovri::core::CreateTransitTunnel(
bufbe32toh(clear_text + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
core::InputByteStream::Read<std::uint32_t>(clear_text + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
clear_text + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
bufbe32toh(clear_text + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
core::InputByteStream::Read<std::uint32_t>(clear_text + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
clear_text + BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET,
clear_text + BUILD_REQUEST_RECORD_IV_KEY_OFFSET,
clear_text[BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x80,
Expand Down Expand Up @@ -489,12 +491,12 @@ void HandleVariableTunnelBuildMsg(
clear_text + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
ToSharedI2NPMessage(
CreateTunnelGatewayMsg(
bufbe32toh(
core::InputByteStream::Read<std::uint32_t>(
clear_text + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
I2NPVariableTunnelBuildReply,
buf,
len,
bufbe32toh(
core::InputByteStream::Read<std::uint32_t>(
clear_text + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))));
} else {
kovri::core::transports.SendMessage(
Expand All @@ -504,7 +506,7 @@ void HandleVariableTunnelBuildMsg(
I2NPVariableTunnelBuild,
buf,
len,
bufbe32toh(
core::InputByteStream::Read<std::uint32_t>(
clear_text + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))));
}
}
Expand All @@ -523,12 +525,12 @@ void HandleTunnelBuildMsg(
clear_text + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
ToSharedI2NPMessage(
CreateTunnelGatewayMsg(
bufbe32toh(
core::InputByteStream::Read<std::uint32_t>(
clear_text + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
I2NPTunnelBuildReply,
buf,
len,
bufbe32toh(
core::InputByteStream::Read<std::uint32_t>(
clear_text + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))));
} else {
kovri::core::transports.SendMessage(
Expand All @@ -538,7 +540,7 @@ void HandleTunnelBuildMsg(
I2NPTunnelBuild,
buf,
len,
bufbe32toh(
core::InputByteStream::Read<std::uint32_t>(
clear_text + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))));
}
}
Expand Down Expand Up @@ -659,20 +661,24 @@ std::unique_ptr<I2NPMessage> CreateTunnelGatewayMsg(
// TODO(anonimal): s/size_t/uint16_t/
std::size_t GetI2NPMessageLength(
const std::uint8_t* msg) {
return bufbe16toh(msg + I2NP_HEADER_SIZE_OFFSET) + I2NP_HEADER_SIZE;
return core::InputByteStream::Read<std::uint16_t>(
msg + I2NP_HEADER_SIZE_OFFSET)
+ I2NP_HEADER_SIZE;
}

void HandleI2NPMessage(
std::uint8_t* msg,
std::size_t len) {
std::uint8_t type_ID = msg[I2NP_HEADER_TYPEID_OFFSET];
std::uint32_t msg_ID = bufbe32toh(msg + I2NP_HEADER_MSGID_OFFSET);
std::uint32_t const msg_ID = core::InputByteStream::Read<std::uint32_t>(
msg + I2NP_HEADER_MSGID_OFFSET);
LOG(debug)
<< "I2NPMessage: msg received len=" << len
<< ", type=" << static_cast<int>(type_ID)
<< ", msg_ID=" << (unsigned int)msg_ID;
<< ", msg_ID=" << msg_ID;
std::uint8_t* buf = msg + I2NP_HEADER_SIZE;
int size = bufbe16toh(msg + I2NP_HEADER_SIZE_OFFSET);
std::uint16_t const size =
core::InputByteStream::Read<std::uint16_t>(msg + I2NP_HEADER_SIZE_OFFSET);
switch (type_ID) {
case I2NPVariableTunnelBuild:
LOG(debug) << "I2NPMessage: VariableTunnelBuild";
Expand Down
29 changes: 18 additions & 11 deletions src/core/router/i2np.h
@@ -1,5 +1,5 @@
/** //
* Copyright (c) 2013-2017, The Kovri I2P Router Project //
* Copyright (c) 2013-2018, The Kovri I2P Router Project //
* //
* All rights reserved. //
* //
Expand Down Expand Up @@ -150,6 +150,7 @@ enum I2NPMessageType {
class InboundTunnel;
class TunnelPool;

// TODO(anonimal): bytestream refactor
struct I2NPMessage {
std::uint8_t* buf;
std::size_t len, offset, max_len;
Expand Down Expand Up @@ -185,23 +186,26 @@ struct I2NPMessage {
}

std::uint32_t GetMsgID() const {
return bufbe32toh(GetHeader() + I2NP_HEADER_MSGID_OFFSET);
return core::InputByteStream::Read<std::uint32_t>(
GetHeader() + I2NP_HEADER_MSGID_OFFSET);
}

void SetExpiration(std::uint64_t expiration) {
htobe64buf(GetHeader() + I2NP_HEADER_EXPIRATION_OFFSET, expiration);
}

std::uint64_t GetExpiration() const {
return bufbe64toh(GetHeader() + I2NP_HEADER_EXPIRATION_OFFSET);
return core::InputByteStream::Read<std::uint64_t>(
GetHeader() + I2NP_HEADER_EXPIRATION_OFFSET);
}

void SetSize(std::uint16_t size) {
htobe16buf(GetHeader() + I2NP_HEADER_SIZE_OFFSET, size);
}

std::uint16_t GetSize() const {
return bufbe16toh(GetHeader () + I2NP_HEADER_SIZE_OFFSET);
return core::InputByteStream::Read<std::uint16_t>(
GetHeader() + I2NP_HEADER_SIZE_OFFSET);
}

void UpdateSize() {
Expand Down Expand Up @@ -277,8 +281,9 @@ struct I2NPMessage {
ssu[I2NP_SHORT_HEADER_TYPEID_OFFSET]; // typeid
SetMsgID(msg_ID);
SetExpiration(
bufbe32toh(
ssu + I2NP_SHORT_HEADER_EXPIRATION_OFFSET) * 1000LL);
core::InputByteStream::Read<std::uint32_t>(
ssu + I2NP_SHORT_HEADER_EXPIRATION_OFFSET)
* 1000LL);
SetSize(len - offset - I2NP_HEADER_SIZE);
SetChks(0);
}
Expand All @@ -292,11 +297,13 @@ struct I2NPMessage {
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);
core::InputByteStream::Read<std::uint64_t>(
header + I2NP_HEADER_EXPIRATION_OFFSET) / 1000LL);
len = offset + I2NP_SHORT_HEADER_SIZE
+ core::InputByteStream::Read<std::uint16_t>(
header + I2NP_HEADER_SIZE_OFFSET);
return core::InputByteStream::Read<std::uint32_t>(
header + I2NP_HEADER_MSGID_OFFSET);
}

void FillI2NPMessageHeader(
Expand Down

0 comments on commit ffb2fff

Please sign in to comment.