This commit is contained in:
Erayd 2025-10-27 02:47:00 +00:00 committed by GitHub
commit 2283d530c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 79 additions and 56 deletions

View File

@ -52,6 +52,7 @@ PacketCacheEntry *PacketCache::cache(const meshtastic_MeshPacket *p, bool preser
m.reply_id = p->decoded.reply_id; m.reply_id = p->decoded.reply_id;
else if (p->decoded.request_id) else if (p->decoded.request_id)
m.request_id = p->decoded.request_id; m.request_id = p->decoded.request_id;
m.tx_unencrypted = !!p->decoded.tx_unencrypted;
} }
e->payload_len = p->decoded.payload.size; e->payload_len = p->decoded.payload.size;
memcpy(((unsigned char *)e) + sizeof(PacketCacheEntry), p->decoded.payload.bytes, p->decoded.payload.size); memcpy(((unsigned char *)e) + sizeof(PacketCacheEntry), p->decoded.payload.bytes, p->decoded.payload.size);
@ -203,6 +204,7 @@ void PacketCache::rehydrate(const PacketCacheEntry *e, meshtastic_MeshPacket *p)
p->decoded.reply_id = m.reply_id; p->decoded.reply_id = m.reply_id;
else if (m.request_id) else if (m.request_id)
p->decoded.request_id = m.request_id; p->decoded.request_id = m.request_id;
p->decoded.tx_unencrypted = m.tx_unencrypted;
} }
} }
} }

View File

@ -45,7 +45,7 @@ typedef struct PacketCacheMetadata {
uint8_t _bitfield2; uint8_t _bitfield2;
union { union {
uint8_t priority : 7; // meshtastic_MeshPacket::priority uint8_t priority : 7; // meshtastic_MeshPacket::priority
uint8_t reserved : 1; // Reserved for future use uint8_t tx_unencrypted : 1; // meshtastic_MeshPacket::tx_unencrypted
}; };
}; };
} PacketCacheMetadata; } PacketCacheMetadata;

View File

@ -23,6 +23,8 @@
#include "serialization/MeshPacketSerializer.h" #include "serialization/MeshPacketSerializer.h"
#endif #endif
#define UNENCRYPTED_MAGIC 0x55 // Magic number to verify that an unencrypted protobuf decode is actually supposed to be such
#define MAX_RX_FROMRADIO \ #define MAX_RX_FROMRADIO \
4 // max number of packets destined to our queue, we dispatch packets quickly so it doesn't need to be big 4 // max number of packets destined to our queue, we dispatch packets quickly so it doesn't need to be big
@ -425,6 +427,16 @@ DecodeState perhapsDecode(meshtastic_MeshPacket *p)
} }
bool decrypted = false; bool decrypted = false;
ChannelIndex chIndex = 0; ChannelIndex chIndex = 0;
// Attempt unencrypted decode
meshtastic_Data decodedtmp{};
if (pb_decode_from_bytes(p->encrypted.bytes, rawSize, meshtastic_Data_fields, &decodedtmp, true) &&
decodedtmp.tx_unencrypted == UNENCRYPTED_MAGIC) {
p->which_payload_variant = meshtastic_MeshPacket_decoded_tag;
memcpy(&p->decoded, &decodedtmp, sizeof(decodedtmp));
return DecodeState::DECODE_SUCCESS;
}
#if !(MESHTASTIC_EXCLUDE_PKI) #if !(MESHTASTIC_EXCLUDE_PKI)
// Attempt PKI decryption first // Attempt PKI decryption first
if (p->channel == 0 && isToUs(p) && p->to > 0 && !isBroadcast(p->to) && nodeDB->getMeshNode(p->from) != nullptr && if (p->channel == 0 && isToUs(p) && p->to > 0 && !isBroadcast(p->to) && nodeDB->getMeshNode(p->from) != nullptr &&
@ -546,6 +558,8 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p)
p->decoded.bitfield |= (p->decoded.want_response << BITFIELD_WANT_RESPONSE_SHIFT); p->decoded.bitfield |= (p->decoded.want_response << BITFIELD_WANT_RESPONSE_SHIFT);
} }
if (p->decoded.tx_unencrypted)
p->decoded.tx_unencrypted = UNENCRYPTED_MAGIC;
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded); size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded);
/* Not actually used, so save the cycles /* Not actually used, so save the cycles
@ -590,11 +604,13 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p)
ChannelIndex chIndex = p->channel; // keep as a local because we are about to change it ChannelIndex chIndex = p->channel; // keep as a local because we are about to change it
if (p->decoded.tx_unencrypted) {
memcpy(p->encrypted.bytes, bytes, numbytes); // Just copy across with no further action
} else {
#if !(MESHTASTIC_EXCLUDE_PKI) #if !(MESHTASTIC_EXCLUDE_PKI)
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(p->to); meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(p->to);
// We may want to retool things so we can send a PKC packet when the client specifies a key and nodenum, even if the node // We may want to retool things so we can send a PKC packet when the client specifies a key and nodenum, even if the
// is not in the local nodedb // node is not in the local nodedb First, only PKC encrypt packets we are originating
// First, only PKC encrypt packets we are originating
if (isFromUs(p) && if (isFromUs(p) &&
#if ARCH_PORTDUINO #if ARCH_PORTDUINO
// Sim radio via the cli flag skips PKC // Sim radio via the cli flag skips PKC
@ -610,8 +626,9 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p)
// Check for a known public key for the destination // Check for a known public key for the destination
(node->user.public_key.size == 32) && (node->user.public_key.size == 32) &&
// Some portnums either make no sense to send with PKC // Some portnums either make no sense to send with PKC
p->decoded.portnum != meshtastic_PortNum_TRACEROUTE_APP && p->decoded.portnum != meshtastic_PortNum_NODEINFO_APP && p->decoded.portnum != meshtastic_PortNum_TRACEROUTE_APP &&
p->decoded.portnum != meshtastic_PortNum_ROUTING_APP && p->decoded.portnum != meshtastic_PortNum_POSITION_APP) { p->decoded.portnum != meshtastic_PortNum_NODEINFO_APP && p->decoded.portnum != meshtastic_PortNum_ROUTING_APP &&
p->decoded.portnum != meshtastic_PortNum_POSITION_APP) {
LOG_DEBUG("Use PKI!"); LOG_DEBUG("Use PKI!");
if (numbytes + MESHTASTIC_HEADER_LENGTH + MESHTASTIC_PKC_OVERHEAD > MAX_LORA_PAYLOAD_LEN) if (numbytes + MESHTASTIC_HEADER_LENGTH + MESHTASTIC_PKC_OVERHEAD > MAX_LORA_PAYLOAD_LEN)
return meshtastic_Routing_Error_TOO_LARGE; return meshtastic_Routing_Error_TOO_LARGE;
@ -657,6 +674,7 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p)
crypto->encryptPacket(getFrom(p), p->id, numbytes, bytes); crypto->encryptPacket(getFrom(p), p->id, numbytes, bytes);
memcpy(p->encrypted.bytes, bytes, numbytes); memcpy(p->encrypted.bytes, bytes, numbytes);
#endif #endif
}
// Copy back into the packet and set the variant type // Copy back into the packet and set the variant type
p->encrypted.size = numbytes; p->encrypted.size = numbytes;

View File

@ -21,10 +21,12 @@ size_t pb_encode_to_bytes(uint8_t *destbuf, size_t destbufsize, const pb_msgdesc
} }
/// helper function for decoding a record as a protobuf, we will return false if the decoding failed /// helper function for decoding a record as a protobuf, we will return false if the decoding failed
bool pb_decode_from_bytes(const uint8_t *srcbuf, size_t srcbufsize, const pb_msgdesc_t *fields, void *dest_struct) bool pb_decode_from_bytes(const uint8_t *srcbuf, size_t srcbufsize, const pb_msgdesc_t *fields, void *dest_struct,
bool suppress_errors)
{ {
pb_istream_t stream = pb_istream_from_buffer(srcbuf, srcbufsize); pb_istream_t stream = pb_istream_from_buffer(srcbuf, srcbufsize);
if (!pb_decode(&stream, fields, dest_struct)) { if (!pb_decode(&stream, fields, dest_struct)) {
if (!suppress_errors)
LOG_ERROR("Can't decode protobuf reason='%s', pb_msgdesc %p", PB_GET_ERROR(&stream), fields); LOG_ERROR("Can't decode protobuf reason='%s', pb_msgdesc %p", PB_GET_ERROR(&stream), fields);
return false; return false;
} else { } else {

View File

@ -74,7 +74,8 @@ static inline int get_max_num_nodes()
size_t pb_encode_to_bytes(uint8_t *destbuf, size_t destbufsize, const pb_msgdesc_t *fields, const void *src_struct); size_t pb_encode_to_bytes(uint8_t *destbuf, size_t destbufsize, const pb_msgdesc_t *fields, const void *src_struct);
/// helper function for decoding a record as a protobuf, we will return false if the decoding failed /// helper function for decoding a record as a protobuf, we will return false if the decoding failed
bool pb_decode_from_bytes(const uint8_t *srcbuf, size_t srcbufsize, const pb_msgdesc_t *fields, void *dest_struct); bool pb_decode_from_bytes(const uint8_t *srcbuf, size_t srcbufsize, const pb_msgdesc_t *fields, void *dest_struct,
bool suppress_errors = false);
/// Read from an Arduino File /// Read from an Arduino File
bool readcb(pb_istream_t *stream, uint8_t *buf, size_t count); bool readcb(pb_istream_t *stream, uint8_t *buf, size_t count);