begin multichannel hash impl

This commit is contained in:
Kevin Hester
2021-02-22 12:57:26 +08:00
parent 923ecc9d8a
commit 94cd96cfde
11 changed files with 129 additions and 59 deletions

View File

@@ -1,9 +1,10 @@
#include "Router.h"
#include "Channels.h"
#include "CryptoEngine.h"
#include "NodeDB.h"
#include "RTC.h"
#include "configuration.h"
#include "mesh-pb-constants.h"
#include <NodeDB.h>
#include "plugins/RoutingPlugin.h"
/**
@@ -107,7 +108,12 @@ void Router::sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom)
routingPlugin->sendAckNak(err, to, idFrom);
}
void Router::abortSendAndNak(Routing_Error err, MeshPacket *p)
{
DEBUG_MSG("Error=%d, returning NAK and dropping packet.\n", err);
sendAckNak(Routing_Error_NO_INTERFACE, p->from, p->id);
packetPool.release(p);
}
ErrorCode Router::sendLocal(MeshPacket *p)
{
@@ -118,11 +124,7 @@ ErrorCode Router::sendLocal(MeshPacket *p)
return ERRNO_OK;
} else if (!iface) {
// We must be sending to remote nodes also, fail if no interface found
// ERROR! no radio found, report failure back to the client and drop the packet
DEBUG_MSG("Error: No interface, returning NAK and dropping packet.\n");
sendAckNak(Routing_Error_NO_INTERFACE, p->from, p->id);
packetPool.release(p);
abortSendAndNak(Routing_Error_NO_INTERFACE, p);
return ERRNO_NO_INTERFACES;
} else {
@@ -146,7 +148,8 @@ ErrorCode Router::send(MeshPacket *p)
assert(p->to != nodeDB.getNodeNum()); // should have already been handled by sendLocal
// PacketId nakId = p->decoded.which_ackVariant == SubPacket_fail_id_tag ? p->decoded.ackVariant.fail_id : 0;
// assert(!nakId); // I don't think we ever send 0hop naks over the wire (other than to the phone), test that assumption with assert
// assert(!nakId); // I don't think we ever send 0hop naks over the wire (other than to the phone), test that assumption with
// assert
// Never set the want_ack flag on broadcast packets sent over the air.
if (p->to == NODENUM_BROADCAST)
@@ -163,7 +166,20 @@ ErrorCode Router::send(MeshPacket *p)
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), Data_fields, &p->decoded);
assert(numbytes <= MAX_RHPACKETLEN);
if (numbytes > MAX_RHPACKETLEN) {
abortSendAndNak(Routing_Error_TOO_LARGE, p);
return ERRNO_TOO_LARGE;
}
auto hash = channels.setActiveByIndex(p->channel);
if (hash < 0) {
// No suitable channel could be found for sending
abortSendAndNak(Routing_Error_NO_CHANNEL, p);
return ERRNO_NO_CHANNEL;
}
// Now that we are encrypting the packet channel should be the hash (no longer the index)
p->channel = hash;
crypto->encrypt(p->from, p->id, numbytes, bytes);
// Copy back into the packet and set the variant type
@@ -173,23 +189,15 @@ ErrorCode Router::send(MeshPacket *p)
}
assert(iface); // This should have been detected already in sendLocal (or we just received a packet from outside)
// if (iface) {
// DEBUG_MSG("Sending packet via interface fr=0x%x,to=0x%x,id=%d\n", p->from, p->to, p->id);
return iface->send(p);
/* } else {
DEBUG_MSG("Dropping packet - no interfaces - fr=0x%x,to=0x%x,id=%d\n", p->from, p->to, p->id);
packetPool.release(p);
return ERRNO_NO_INTERFACES;
} */
}
/** Attempt to cancel a previously sent packet. Returns true if a packet was found we could cancel */
bool Router::cancelSending(NodeNum from, PacketId id) {
bool Router::cancelSending(NodeNum from, PacketId id)
{
return iface ? iface->cancelSending(from, id) : false;
}
/**
* Every (non duplicate) packet this node receives will be passed through this method. This allows subclasses to
* update routing tables etc... based on what we overhear (even for messages not destined to our node)
@@ -207,22 +215,30 @@ bool Router::perhapsDecode(MeshPacket *p)
assert(p->which_payloadVariant == MeshPacket_encrypted_tag);
// FIXME - someday don't send routing packets encrypted. That would allow us to route for other channels without
// being able to decrypt their data.
// Try to decrypt the packet if we can
static uint8_t bytes[MAX_RHPACKETLEN];
memcpy(bytes, p->encrypted.bytes,
p->encrypted.size); // we have to copy into a scratch buffer, because these bytes are a union with the decoded protobuf
crypto->decrypt(p->from, p->id, p->encrypted.size, bytes);
// Take those raw bytes and convert them back into a well structured protobuf we can understand
if (!pb_decode_from_bytes(bytes, p->encrypted.size, Data_fields, &p->decoded)) {
DEBUG_MSG("Invalid protobufs in received mesh packet!\n");
ChannelHash chHash = p->channel;
int16_t chIndex = channels.setActiveByHash(chHash);
if (chIndex < 0) {
DEBUG_MSG("No suitable channel found for decoding, hash was 0x%x!\n", chHash);
return false;
} else {
// parsing was successful
p->which_payloadVariant = MeshPacket_decoded_tag;
return true;
p->channel = chIndex;
// Try to decrypt the packet if we can
static uint8_t bytes[MAX_RHPACKETLEN];
memcpy(bytes, p->encrypted.bytes,
p->encrypted
.size); // we have to copy into a scratch buffer, because these bytes are a union with the decoded protobuf
crypto->decrypt(p->from, p->id, p->encrypted.size, bytes);
// Take those raw bytes and convert them back into a well structured protobuf we can understand
if (!pb_decode_from_bytes(bytes, p->encrypted.size, Data_fields, &p->decoded)) {
DEBUG_MSG("Invalid protobufs in received mesh packet!\n");
return false;
} else {
// parsing was successful
p->which_payloadVariant = MeshPacket_decoded_tag;
return true;
}
}
}
@@ -244,7 +260,7 @@ void Router::handleReceived(MeshPacket *p)
if (perhapsDecode(p)) {
// parsing was successful, queue for our recipient
// call any promiscious plugins here, make a (non promisiocous) plugin for forwarding messages to phone api
// call any promiscious plugins here, make a (non promisiocous) plugin for forwarding messages to phone api
// sniffReceived(p);
MeshPlugin::callPlugins(*p);
}