Mesh.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. #include "Mesh.h"
  2. //#include <Arduino.h>
  3. namespace mesh {
  4. void Mesh::begin() {
  5. Dispatcher::begin();
  6. }
  7. void Mesh::loop() {
  8. Dispatcher::loop();
  9. }
  10. bool Mesh::allowPacketForward(const mesh::Packet* packet) {
  11. return false; // by default, Transport NOT enabled
  12. }
  13. uint32_t Mesh::getRetransmitDelay(const mesh::Packet* packet) {
  14. uint32_t t = (_radio->getEstAirtimeFor(packet->path_len + packet->payload_len + 2) * 52 / 50) / 2;
  15. return _rng->nextInt(0, 5)*t;
  16. }
  17. int Mesh::searchPeersByHash(const uint8_t* hash) {
  18. return 0; // not found
  19. }
  20. int Mesh::searchChannelsByHash(const uint8_t* hash, GroupChannel channels[], int max_matches) {
  21. return 0; // not found
  22. }
  23. DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
  24. if (pkt->getPayloadVer() > PAYLOAD_VER_1) { // not supported in this firmware version
  25. MESH_DEBUG_PRINTLN("Mesh::onRecvPacket(): unsupported packet version");
  26. return ACTION_RELEASE;
  27. }
  28. if (pkt->isRouteDirect() && pkt->path_len >= PATH_HASH_SIZE) {
  29. if (self_id.isHashMatch(pkt->path) && allowPacketForward(pkt)) {
  30. if (_tables->hasSeen(pkt)) return ACTION_RELEASE; // don't retransmit!
  31. // remove our hash from 'path', then re-broadcast
  32. pkt->path_len -= PATH_HASH_SIZE;
  33. memcpy(pkt->path, &pkt->path[PATH_HASH_SIZE], pkt->path_len);
  34. return ACTION_RETRANSMIT(0); // Routed traffic is HIGHEST priority (and NO per-hop delay)
  35. }
  36. return ACTION_RELEASE; // this node is NOT the next hop (OR this packet has already been forwarded), so discard.
  37. }
  38. DispatcherAction action = ACTION_RELEASE;
  39. switch (pkt->getPayloadType()) {
  40. case PAYLOAD_TYPE_ACK: {
  41. int i = 0;
  42. uint32_t ack_crc;
  43. memcpy(&ack_crc, &pkt->payload[i], 4); i += 4;
  44. if (i > pkt->payload_len) {
  45. MESH_DEBUG_PRINTLN("Mesh::onRecvPacket(): incomplete ACK packet");
  46. } else if (!_tables->hasSeen(pkt)) {
  47. onAckRecv(pkt, ack_crc);
  48. action = routeRecvPacket(pkt);
  49. }
  50. break;
  51. }
  52. case PAYLOAD_TYPE_PATH:
  53. case PAYLOAD_TYPE_REQ:
  54. case PAYLOAD_TYPE_RESPONSE:
  55. case PAYLOAD_TYPE_TXT_MSG: {
  56. int i = 0;
  57. uint8_t dest_hash = pkt->payload[i++];
  58. uint8_t src_hash = pkt->payload[i++];
  59. uint8_t* macAndData = &pkt->payload[i]; // MAC + encrypted data
  60. if (i + 2 >= pkt->payload_len) {
  61. MESH_DEBUG_PRINTLN("Mesh::onRecvPacket(): incomplete data packet");
  62. } else if (!_tables->hasSeen(pkt)) {
  63. // NOTE: this is a 'first packet wins' impl. When receiving from multiple paths, the first to arrive wins.
  64. // For flood mode, the path may not be the 'best' in terms of hops.
  65. // FUTURE: could send back multiple paths, using createPathReturn(), and let sender choose which to use(?)
  66. if (self_id.isHashMatch(&dest_hash)) {
  67. // scan contacts DB, for all matching hashes of 'src_hash' (max 4 matches supported ATM)
  68. int num = searchPeersByHash(&src_hash);
  69. // for each matching contact, try to decrypt data
  70. bool found = false;
  71. for (int j = 0; j < num; j++) {
  72. uint8_t secret[PUB_KEY_SIZE];
  73. getPeerSharedSecret(secret, j);
  74. // decrypt, checking MAC is valid
  75. uint8_t data[MAX_PACKET_PAYLOAD];
  76. int len = Utils::MACThenDecrypt(secret, data, macAndData, pkt->payload_len - i);
  77. if (len > 0) { // success!
  78. if (pkt->getPayloadType() == PAYLOAD_TYPE_PATH) {
  79. int k = 0;
  80. uint8_t path_len = data[k++];
  81. uint8_t* path = &data[k]; k += path_len;
  82. uint8_t extra_type = data[k++];
  83. uint8_t* extra = &data[k];
  84. uint8_t extra_len = len - k; // remainder of packet (may be padded with zeroes!)
  85. if (onPeerPathRecv(pkt, j, secret, path, path_len, extra_type, extra, extra_len)) {
  86. if (pkt->isRouteFlood()) {
  87. // send a reciprocal return path to sender, but send DIRECTLY!
  88. mesh::Packet* rpath = createPathReturn(&src_hash, secret, pkt->path, pkt->path_len, 0, NULL, 0);
  89. if (rpath) sendDirect(rpath, path, path_len);
  90. }
  91. }
  92. } else {
  93. onPeerDataRecv(pkt, pkt->getPayloadType(), j, secret, data, len);
  94. }
  95. found = true;
  96. break;
  97. }
  98. }
  99. if (!found) {
  100. MESH_DEBUG_PRINTLN("recv matches no peers, src_hash=%02X", (uint32_t)src_hash);
  101. }
  102. }
  103. action = routeRecvPacket(pkt);
  104. }
  105. break;
  106. }
  107. case PAYLOAD_TYPE_ANON_REQ: {
  108. int i = 0;
  109. uint8_t dest_hash = pkt->payload[i++];
  110. uint8_t* sender_pub_key = &pkt->payload[i]; i += PUB_KEY_SIZE;
  111. uint8_t* macAndData = &pkt->payload[i]; // MAC + encrypted data
  112. if (i + 2 >= pkt->payload_len) {
  113. MESH_DEBUG_PRINTLN("Mesh::onRecvPacket(): incomplete data packet");
  114. } else if (!_tables->hasSeen(pkt)) {
  115. if (self_id.isHashMatch(&dest_hash)) {
  116. Identity sender(sender_pub_key);
  117. uint8_t secret[PUB_KEY_SIZE];
  118. self_id.calcSharedSecret(secret, sender);
  119. // decrypt, checking MAC is valid
  120. uint8_t data[MAX_PACKET_PAYLOAD];
  121. int len = Utils::MACThenDecrypt(secret, data, macAndData, pkt->payload_len - i);
  122. if (len > 0) { // success!
  123. onAnonDataRecv(pkt, pkt->getPayloadType(), sender, data, len);
  124. }
  125. }
  126. action = routeRecvPacket(pkt);
  127. }
  128. break;
  129. }
  130. case PAYLOAD_TYPE_GRP_DATA:
  131. case PAYLOAD_TYPE_GRP_TXT: {
  132. int i = 0;
  133. uint8_t channel_hash = pkt->payload[i++];
  134. uint8_t* macAndData = &pkt->payload[i]; // MAC + encrypted data
  135. if (i + 2 >= pkt->payload_len) {
  136. MESH_DEBUG_PRINTLN("Mesh::onRecvPacket(): incomplete data packet");
  137. } else if (!_tables->hasSeen(pkt)) {
  138. // scan channels DB, for all matching hashes of 'channel_hash' (max 2 matches supported ATM)
  139. GroupChannel channels[2];
  140. int num = searchChannelsByHash(&channel_hash, channels, 2);
  141. // for each matching channel, try to decrypt data
  142. for (int j = 0; j < num; j++) {
  143. // decrypt, checking MAC is valid
  144. uint8_t data[MAX_PACKET_PAYLOAD];
  145. int len = Utils::MACThenDecrypt(channels[j].secret, data, macAndData, pkt->payload_len - i);
  146. if (len > 0) { // success!
  147. onGroupDataRecv(pkt, pkt->getPayloadType(), channels[j], data, len);
  148. break;
  149. }
  150. }
  151. action = routeRecvPacket(pkt);
  152. }
  153. break;
  154. }
  155. case PAYLOAD_TYPE_ADVERT: {
  156. int i = 0;
  157. Identity id;
  158. memcpy(id.pub_key, &pkt->payload[i], PUB_KEY_SIZE); i += PUB_KEY_SIZE;
  159. uint32_t timestamp;
  160. memcpy(&timestamp, &pkt->payload[i], 4); i += 4;
  161. const uint8_t* signature = &pkt->payload[i]; i += SIGNATURE_SIZE;
  162. if (i > pkt->payload_len) {
  163. MESH_DEBUG_PRINTLN("Mesh::onRecvPacket(): incomplete advertisement packet");
  164. } else if (!_tables->hasSeen(pkt)) {
  165. uint8_t* app_data = &pkt->payload[i];
  166. int app_data_len = pkt->payload_len - i;
  167. if (app_data_len > MAX_ADVERT_DATA_SIZE) { app_data_len = MAX_ADVERT_DATA_SIZE; }
  168. // check that signature is valid
  169. bool is_ok;
  170. {
  171. uint8_t message[PUB_KEY_SIZE + 4 + MAX_ADVERT_DATA_SIZE];
  172. int msg_len = 0;
  173. memcpy(&message[msg_len], id.pub_key, PUB_KEY_SIZE); msg_len += PUB_KEY_SIZE;
  174. memcpy(&message[msg_len], &timestamp, 4); msg_len += 4;
  175. memcpy(&message[msg_len], app_data, app_data_len); msg_len += app_data_len;
  176. is_ok = id.verify(signature, message, msg_len);
  177. }
  178. if (is_ok) {
  179. MESH_DEBUG_PRINTLN("Mesh::onRecvPacket(): valid advertisement received!");
  180. onAdvertRecv(pkt, id, timestamp, app_data, app_data_len);
  181. action = routeRecvPacket(pkt);
  182. } else {
  183. MESH_DEBUG_PRINTLN("Mesh::onRecvPacket(): received advertisement with forged signature! (app_data_len=%d)", app_data_len);
  184. }
  185. }
  186. break;
  187. }
  188. default:
  189. MESH_DEBUG_PRINTLN("Mesh::onRecvPacket(): unknown payload type, header: %d", (int) pkt->header);
  190. // Don't flood route unknown packet types! action = routeRecvPacket(pkt);
  191. break;
  192. }
  193. return action;
  194. }
  195. DispatcherAction Mesh::routeRecvPacket(Packet* packet) {
  196. if (packet->isRouteFlood() && packet->path_len + PATH_HASH_SIZE <= MAX_PATH_SIZE && allowPacketForward(packet)) {
  197. // append this node's hash to 'path'
  198. packet->path_len += self_id.copyHashTo(&packet->path[packet->path_len]);
  199. uint32_t d = getRetransmitDelay(packet);
  200. // as this propagates outwards, give it lower and lower priority
  201. return ACTION_RETRANSMIT_DELAYED(packet->path_len, d); // give priority to closer sources, than ones further away
  202. }
  203. return ACTION_RELEASE;
  204. }
  205. Packet* Mesh::createAdvert(const LocalIdentity& id, const uint8_t* app_data, size_t app_data_len) {
  206. if (app_data_len > MAX_ADVERT_DATA_SIZE) return NULL;
  207. Packet* packet = obtainNewPacket();
  208. if (packet == NULL) {
  209. MESH_DEBUG_PRINTLN("Mesh::createAdvert(): error, packet pool empty");
  210. return NULL;
  211. }
  212. packet->header = (PAYLOAD_TYPE_ADVERT << PH_TYPE_SHIFT); // ROUTE_TYPE_* is set later
  213. int len = 0;
  214. memcpy(&packet->payload[len], id.pub_key, PUB_KEY_SIZE); len += PUB_KEY_SIZE;
  215. uint32_t emitted_timestamp = _rtc->getCurrentTime();
  216. memcpy(&packet->payload[len], &emitted_timestamp, 4); len += 4;
  217. uint8_t* signature = &packet->payload[len]; len += SIGNATURE_SIZE; // will fill this in later
  218. memcpy(&packet->payload[len], app_data, app_data_len); len += app_data_len;
  219. packet->payload_len = len;
  220. {
  221. uint8_t message[PUB_KEY_SIZE + 4 + MAX_ADVERT_DATA_SIZE];
  222. int msg_len = 0;
  223. memcpy(&message[msg_len], id.pub_key, PUB_KEY_SIZE); msg_len += PUB_KEY_SIZE;
  224. memcpy(&message[msg_len], &emitted_timestamp, 4); msg_len += 4;
  225. memcpy(&message[msg_len], app_data, app_data_len); msg_len += app_data_len;
  226. id.sign(signature, message, msg_len);
  227. }
  228. return packet;
  229. }
  230. #define MAX_COMBINED_PATH (MAX_PACKET_PAYLOAD - 2 - CIPHER_BLOCK_SIZE)
  231. Packet* Mesh::createPathReturn(const Identity& dest, const uint8_t* secret, const uint8_t* path, uint8_t path_len, uint8_t extra_type, const uint8_t*extra, size_t extra_len) {
  232. uint8_t dest_hash[PATH_HASH_SIZE];
  233. dest.copyHashTo(dest_hash);
  234. return createPathReturn(dest_hash, secret, path, path_len, extra_type, extra, extra_len);
  235. }
  236. Packet* Mesh::createPathReturn(const uint8_t* dest_hash, const uint8_t* secret, const uint8_t* path, uint8_t path_len, uint8_t extra_type, const uint8_t*extra, size_t extra_len) {
  237. if (path_len + extra_len + 5 > MAX_COMBINED_PATH) return NULL; // too long!!
  238. Packet* packet = obtainNewPacket();
  239. if (packet == NULL) {
  240. MESH_DEBUG_PRINTLN("Mesh::createPathReturn(): error, packet pool empty");
  241. return NULL;
  242. }
  243. packet->header = (PAYLOAD_TYPE_PATH << PH_TYPE_SHIFT); // ROUTE_TYPE_* set later
  244. int len = 0;
  245. memcpy(&packet->payload[len], dest_hash, PATH_HASH_SIZE); len += PATH_HASH_SIZE; // dest hash
  246. len += self_id.copyHashTo(&packet->payload[len]); // src hash
  247. {
  248. int data_len = 0;
  249. uint8_t data[MAX_PACKET_PAYLOAD];
  250. data[data_len++] = path_len;
  251. memcpy(&data[data_len], path, path_len); data_len += path_len;
  252. if (extra_len > 0) {
  253. data[data_len++] = extra_type;
  254. memcpy(&data[data_len], extra, extra_len); data_len += extra_len;
  255. } else {
  256. // append a timestamp, or random blob (to make packet_hash unique)
  257. data[data_len++] = 0xFF; // dummy payload type
  258. getRNG()->random(&data[data_len], 4); data_len += 4;
  259. }
  260. len += Utils::encryptThenMAC(secret, &packet->payload[len], data, data_len);
  261. }
  262. packet->payload_len = len;
  263. return packet;
  264. }
  265. Packet* Mesh::createDatagram(uint8_t type, const Identity& dest, const uint8_t* secret, const uint8_t* data, size_t data_len) {
  266. if (type == PAYLOAD_TYPE_TXT_MSG || type == PAYLOAD_TYPE_REQ || type == PAYLOAD_TYPE_RESPONSE) {
  267. if (data_len + 2 + CIPHER_BLOCK_SIZE-1 > MAX_PACKET_PAYLOAD) return NULL;
  268. } else {
  269. return NULL; // invalid type
  270. }
  271. Packet* packet = obtainNewPacket();
  272. if (packet == NULL) {
  273. MESH_DEBUG_PRINTLN("Mesh::createDatagram(): error, packet pool empty");
  274. return NULL;
  275. }
  276. packet->header = (type << PH_TYPE_SHIFT); // ROUTE_TYPE_* set later
  277. int len = 0;
  278. len += dest.copyHashTo(&packet->payload[len]); // dest hash
  279. len += self_id.copyHashTo(&packet->payload[len]); // src hash
  280. len += Utils::encryptThenMAC(secret, &packet->payload[len], data, data_len);
  281. packet->payload_len = len;
  282. return packet;
  283. }
  284. Packet* Mesh::createAnonDatagram(uint8_t type, const LocalIdentity& sender, const Identity& dest, const uint8_t* secret, const uint8_t* data, size_t data_len) {
  285. if (type == PAYLOAD_TYPE_ANON_REQ) {
  286. if (data_len + 1 + PUB_KEY_SIZE + CIPHER_BLOCK_SIZE-1 > MAX_PACKET_PAYLOAD) return NULL;
  287. } else {
  288. return NULL; // invalid type
  289. }
  290. Packet* packet = obtainNewPacket();
  291. if (packet == NULL) {
  292. MESH_DEBUG_PRINTLN("Mesh::createAnonDatagram(): error, packet pool empty");
  293. return NULL;
  294. }
  295. packet->header = (type << PH_TYPE_SHIFT); // ROUTE_TYPE_* set later
  296. int len = 0;
  297. if (type == PAYLOAD_TYPE_ANON_REQ) {
  298. len += dest.copyHashTo(&packet->payload[len]); // dest hash
  299. memcpy(&packet->payload[len], sender.pub_key, PUB_KEY_SIZE); len += PUB_KEY_SIZE; // sender pub_key
  300. } else {
  301. // FUTURE:
  302. }
  303. len += Utils::encryptThenMAC(secret, &packet->payload[len], data, data_len);
  304. packet->payload_len = len;
  305. return packet;
  306. }
  307. Packet* Mesh::createGroupDatagram(uint8_t type, const GroupChannel& channel, const uint8_t* data, size_t data_len) {
  308. if (!(type == PAYLOAD_TYPE_GRP_TXT || type == PAYLOAD_TYPE_GRP_DATA)) return NULL; // invalid type
  309. if (data_len + 1 + CIPHER_BLOCK_SIZE-1 > MAX_PACKET_PAYLOAD) return NULL; // too long
  310. Packet* packet = obtainNewPacket();
  311. if (packet == NULL) {
  312. MESH_DEBUG_PRINTLN("Mesh::createGroupDatagram(): error, packet pool empty");
  313. return NULL;
  314. }
  315. packet->header = (type << PH_TYPE_SHIFT); // ROUTE_TYPE_* set later
  316. int len = 0;
  317. memcpy(&packet->payload[len], channel.hash, PATH_HASH_SIZE); len += PATH_HASH_SIZE;
  318. len += Utils::encryptThenMAC(channel.secret, &packet->payload[len], data, data_len);
  319. packet->payload_len = len;
  320. return packet;
  321. }
  322. Packet* Mesh::createAck(uint32_t ack_crc) {
  323. Packet* packet = obtainNewPacket();
  324. if (packet == NULL) {
  325. MESH_DEBUG_PRINTLN("Mesh::createAck(): error, packet pool empty");
  326. return NULL;
  327. }
  328. packet->header = (PAYLOAD_TYPE_ACK << PH_TYPE_SHIFT); // ROUTE_TYPE_* set later
  329. memcpy(packet->payload, &ack_crc, 4);
  330. packet->payload_len = 4;
  331. return packet;
  332. }
  333. void Mesh::sendFlood(Packet* packet, uint32_t delay_millis) {
  334. packet->header &= ~PH_ROUTE_MASK;
  335. packet->header |= ROUTE_TYPE_FLOOD;
  336. packet->path_len = 0;
  337. _tables->hasSeen(packet); // mark this packet as already sent in case it is rebroadcast back to us
  338. uint8_t pri;
  339. if (packet->getPayloadType() == PAYLOAD_TYPE_PATH) {
  340. pri = 2;
  341. } else if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT) {
  342. pri = 3; // de-prioritie these
  343. } else {
  344. pri = 1;
  345. }
  346. sendPacket(packet, pri, delay_millis);
  347. }
  348. void Mesh::sendDirect(Packet* packet, const uint8_t* path, uint8_t path_len, uint32_t delay_millis) {
  349. packet->header &= ~PH_ROUTE_MASK;
  350. packet->header |= ROUTE_TYPE_DIRECT;
  351. memcpy(packet->path, path, packet->path_len = path_len);
  352. _tables->hasSeen(packet); // mark this packet as already sent in case it is rebroadcast back to us
  353. sendPacket(packet, 0, delay_millis);
  354. }
  355. void Mesh::sendZeroHop(Packet* packet, uint32_t delay_millis) {
  356. packet->header &= ~PH_ROUTE_MASK;
  357. packet->header |= ROUTE_TYPE_DIRECT;
  358. packet->path_len = 0; // path_len of zero means Zero Hop
  359. _tables->hasSeen(packet); // mark this packet as already sent in case it is rebroadcast back to us
  360. sendPacket(packet, 0, delay_millis);
  361. }
  362. }