SessionManager.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #include "memory/Allocator.h"
  16. #include "wire/CryptoHeader.h"
  17. #include "wire/PFChan.h"
  18. #include "net/SessionManager.h"
  19. #include "crypto/AddressCalc.h"
  20. #include "util/AddrTools.h"
  21. #include "wire/Error.h"
  22. #include "util/events/Time.h"
  23. #include "util/Defined.h"
  24. #include "wire/RouteHeader.h"
  25. #include "util/events/Timeout.h"
  26. #include "util/Checksum.h"
  27. #include "wire/Metric.h"
  28. /** Handle numbers 0-3 are reserved for CryptoAuth nonces. */
  29. #define MIN_FIRST_HANDLE 4
  30. #define MAX_FIRST_HANDLE 100000
  31. struct BufferedMessage
  32. {
  33. Message_t* msg;
  34. struct Allocator* alloc;
  35. uint64_t timeSentMilliseconds;
  36. };
  37. struct Ip6 {
  38. uint8_t bytes[16];
  39. };
  40. #define Map_KEY_TYPE struct Ip6
  41. #define Map_VALUE_TYPE struct BufferedMessage*
  42. #define Map_NAME BufferedMessages
  43. #include "util/Map.h"
  44. #define Map_KEY_TYPE struct Ip6
  45. #define Map_VALUE_TYPE struct SessionManager_Session_pvt*
  46. #define Map_NAME OfSessionsByIp6
  47. #define Map_ENABLE_HANDLES
  48. #include "util/Map.h"
  49. struct SessionManager_pvt
  50. {
  51. struct SessionManager pub;
  52. struct Iface eventIf;
  53. struct Allocator* alloc;
  54. struct Map_BufferedMessages bufMap;
  55. struct Map_OfSessionsByIp6 ifaceMap;
  56. struct Log* log;
  57. Ca_t* cryptoAuth;
  58. EventBase_t* eventBase;
  59. uint32_t firstHandle;
  60. uint8_t ourPubKey[32];
  61. Identity
  62. };
  63. struct SessionManager_Session_pvt
  64. {
  65. struct SessionManager_Session pub;
  66. struct Iface plaintext;
  67. struct Iface ciphertext;
  68. struct SessionManager_pvt* sessionManager;
  69. struct Allocator* alloc;
  70. bool foundKey;
  71. Identity
  72. };
  73. #define debugHandlesAndLabel(logger, session, label, message, ...) \
  74. do { \
  75. if (!Defined(Log_DEBUG)) { break; } \
  76. uint8_t path[20]; \
  77. AddrTools_printPath(path, label); \
  78. uint8_t ip[40]; \
  79. uint8_t ipb[16]; \
  80. Ca_getHerIp6(session->pub.caSession, ipb); \
  81. AddrTools_printIp(ip, ipb); \
  82. Log_debug(logger, "ver[%u] send[%d] recv[%u] ip[%s] path[%s] " message, \
  83. session->pub.version, \
  84. session->pub.sendHandle, \
  85. session->pub.receiveHandle, \
  86. ip, \
  87. path, \
  88. __VA_ARGS__); \
  89. } while (0)
  90. //CHECKFILES_IGNORE expecting a ;
  91. #define debugHandlesAndLabel0(logger, session, label, message) \
  92. debugHandlesAndLabel(logger, session, label, "%s", message)
  93. #define debugSession(logger, session, label, message, ...) \
  94. do { \
  95. if (!Defined(Log_DEBUG)) { break; } \
  96. uint8_t sendPath[20]; \
  97. uint8_t ip[40]; \
  98. uint8_t ipb[16]; \
  99. Ca_getHerIp6(session->pub.caSession, ipb); \
  100. AddrTools_printIp(ip, ipb); \
  101. AddrTools_printPath(sendPath, (label)); \
  102. Log_debug((logger), "Session[%p] [%s.%s] " message, \
  103. (void*)session, \
  104. sendPath, \
  105. ip, \
  106. __VA_ARGS__); \
  107. } while (0)
  108. //CHECKFILES_IGNORE ;
  109. #define debugSession0(logger, session, label, message) \
  110. debugSession(logger, session, label, "%s", message)
  111. static void sendSession(struct SessionManager_Session_pvt* sess,
  112. SessionManager_Path_t* path,
  113. uint32_t destPf,
  114. enum PFChan_Core ev)
  115. {
  116. struct PFChan_Node session = {
  117. .path_be = Endian_hostToBigEndian64(path->label),
  118. .metric_be = Endian_bigEndianToHost32(path->metric),
  119. .version_be = Endian_hostToBigEndian32(sess->pub.version)
  120. };
  121. Ca_getHerPubKey(sess->pub.caSession, session.publicKey);
  122. Ca_getHerIp6(sess->pub.caSession, session.ip6);
  123. struct Allocator* alloc = Allocator_child(sess->alloc);
  124. Message_t* msg = Message_new(0, PFChan_Node_SIZE + 512, alloc);
  125. Err_assert(Message_epush(msg, &session, PFChan_Node_SIZE));
  126. Err_assert(Message_epush32be(msg, destPf));
  127. Err_assert(Message_epush32be(msg, ev));
  128. Iface_send(&sess->sessionManager->eventIf, msg);
  129. Allocator_free(alloc);
  130. }
  131. static inline void check(struct SessionManager_pvt* sm, int mapIndex)
  132. {
  133. struct SessionManager_Session_pvt* ssp = Identity_check(sm->ifaceMap.values[mapIndex]);
  134. if (ssp->foundKey) { return; }
  135. uint8_t herPubKey[32];
  136. Ca_getHerPubKey(ssp->pub.caSession, herPubKey);
  137. if (!Bits_isZero(herPubKey, 32)) {
  138. uint8_t ip6[16];
  139. AddressCalc_addressForPublicKey(ip6, herPubKey);
  140. Assert_true(!Bits_memcmp(&sm->ifaceMap.keys[mapIndex], ip6, 16));
  141. ssp->foundKey = true;
  142. }
  143. }
  144. static inline struct SessionManager_Session_pvt* sessionForHandle(uint32_t handle,
  145. struct SessionManager_pvt* sm)
  146. {
  147. int index = Map_OfSessionsByIp6_indexForHandle(handle - sm->firstHandle, &sm->ifaceMap);
  148. if (index < 0) { return NULL; }
  149. check(sm, index);
  150. return Identity_check(sm->ifaceMap.values[index]);
  151. }
  152. struct SessionManager_Session* SessionManager_sessionForHandle(uint32_t handle,
  153. struct SessionManager* manager)
  154. {
  155. struct SessionManager_pvt* sm = Identity_check((struct SessionManager_pvt*) manager);
  156. return (struct SessionManager_Session*) sessionForHandle(handle, sm);
  157. }
  158. static inline struct SessionManager_Session_pvt* sessionForIp6(uint8_t ip6[16],
  159. struct SessionManager_pvt* sm)
  160. {
  161. int ifaceIndex = Map_OfSessionsByIp6_indexForKey((struct Ip6*)ip6, &sm->ifaceMap);
  162. if (ifaceIndex == -1) { return NULL; }
  163. check(sm, ifaceIndex);
  164. return Identity_check(sm->ifaceMap.values[ifaceIndex]);
  165. }
  166. struct SessionManager_Session* SessionManager_sessionForIp6(uint8_t* ip6,
  167. struct SessionManager* manager)
  168. {
  169. struct SessionManager_pvt* sm = Identity_check((struct SessionManager_pvt*) manager);
  170. return (struct SessionManager_Session*) sessionForIp6(ip6, sm);
  171. }
  172. struct SessionManager_HandleList* SessionManager_getHandleList(struct SessionManager* manager,
  173. struct Allocator* alloc)
  174. {
  175. struct SessionManager_pvt* sm = Identity_check((struct SessionManager_pvt*) manager);
  176. struct SessionManager_HandleList* out =
  177. Allocator_calloc(alloc, sizeof(struct SessionManager_HandleList), 1);
  178. uint32_t* buff = Allocator_calloc(alloc, 4, sm->ifaceMap.count);
  179. out->length = sm->ifaceMap.count;
  180. out->handles = buff;
  181. for (int i = 0; i < out->length; i++) {
  182. buff[i] = sm->ifaceMap.handles[i] + sm->firstHandle;
  183. }
  184. return out;
  185. }
  186. int SessionManager_handleCount(struct SessionManager* manager)
  187. {
  188. struct SessionManager_pvt* sm = Identity_check((struct SessionManager_pvt*) manager);
  189. return sm->ifaceMap.count;
  190. }
  191. static uint32_t effectiveMetric(struct SessionManager_pvt* sm,
  192. SessionManager_Path_t* path)
  193. {
  194. int64_t x = Time_currentTimeMilliseconds() - path->timeLastValidated;
  195. x += path->metric;
  196. return (x > Metric_NO_INFO) ? Metric_NO_INFO : x;
  197. }
  198. uint32_t SessionManager_effectiveMetric(struct SessionManager_Session* session)
  199. {
  200. struct SessionManager_Session_pvt* sess =
  201. Identity_check((struct SessionManager_Session_pvt*) session);
  202. return effectiveMetric(sess->sessionManager, &sess->pub.paths[0]);
  203. }
  204. static SessionManager_Path_t* pathForLabel(struct SessionManager_Session_pvt* sess, uint64_t label)
  205. {
  206. for (int i = 0; i < SessionManager_PATH_COUNT; i++) {
  207. if (sess->pub.paths[i].label == label) {
  208. return &sess->pub.paths[i];
  209. }
  210. }
  211. return NULL;
  212. }
  213. static SessionManager_Path_t* worstPath(struct SessionManager_Session_pvt* sess)
  214. {
  215. uint32_t worstEm = 0;
  216. int worstI = 0;
  217. for (int i = 0; i < SessionManager_PATH_COUNT; i++) {
  218. uint32_t em = effectiveMetric(sess->sessionManager, &sess->pub.paths[i]);
  219. if (em > worstEm) {
  220. worstEm = em;
  221. worstI = i;
  222. }
  223. }
  224. return &sess->pub.paths[worstI];
  225. }
  226. static void rerankPaths(struct SessionManager_Session_pvt* sess)
  227. {
  228. uint32_t bestEm = Metric_DEAD_LINK;
  229. int bestI = 0;
  230. for (int i = 0; i < SessionManager_PATH_COUNT; i++) {
  231. uint32_t em = effectiveMetric(sess->sessionManager, &sess->pub.paths[i]);
  232. if (em < bestEm) {
  233. bestEm = em;
  234. bestI = i;
  235. }
  236. }
  237. if (bestI != 0) {
  238. SessionManager_Path_t path0;
  239. Bits_memcpy(&path0, &sess->pub.paths[0], sizeof(path0));
  240. Bits_memcpy(&sess->pub.paths[0], &sess->pub.paths[bestI], sizeof(path0));
  241. Bits_memcpy(&sess->pub.paths[bestI], &path0, sizeof(path0));
  242. }
  243. }
  244. // Return true if the new path is an improvement
  245. static bool discoverPath(struct SessionManager_Session_pvt* sess,
  246. uint64_t label,
  247. uint32_t metric)
  248. {
  249. if (!label) {
  250. return false;
  251. }
  252. SessionManager_Path_t* path = pathForLabel(sess, label);
  253. uint64_t now = Time_currentTimeMilliseconds();
  254. if (path) {
  255. if (metric != Metric_DEAD_LINK && effectiveMetric(sess->sessionManager, path) <= metric) {
  256. // already have a better source of truth
  257. return false;
  258. }
  259. path->metric = metric;
  260. path->timeLastValidated = now;
  261. rerankPaths(sess);
  262. return (sess->pub.paths[0].label == label);
  263. } else {
  264. path = worstPath(sess);
  265. if (effectiveMetric(sess->sessionManager, path) <= metric) {
  266. return false;
  267. }
  268. path->label = label;
  269. path->metric = metric;
  270. path->timeLastValidated = now;
  271. rerankPaths(sess);
  272. if (sess->pub.paths[0].label == label) {
  273. sendSession(sess, &sess->pub.paths[0], 0xffffffff, PFChan_Core_DISCOVERED_PATH);
  274. return true;
  275. }
  276. return false;
  277. }
  278. }
  279. static Iface_DEFUN failedDecrypt(Message_t* msg,
  280. uint64_t label_be,
  281. struct SessionManager_pvt* sm)
  282. {
  283. Err(Message_epush32be(msg, Error_AUTHENTICATION));
  284. Err(Message_epush16be(msg, Control_ERROR));
  285. Err(Message_epush16be(msg, 0));
  286. uint16_t csum_be = Checksum_engine_be(Message_bytes(msg), Message_getLength(msg));
  287. Err(Message_epop(msg, NULL, 2));
  288. Err(Message_epush16h(msg, csum_be));
  289. Err(Message_epush32be(msg, 0xffffffff));
  290. struct SwitchHeader sh;
  291. Bits_memset(&sh, 0, SwitchHeader_SIZE);
  292. SwitchHeader_setSuppressErrors(&sh, true);
  293. SwitchHeader_setVersion(&sh, SwitchHeader_CURRENT_VERSION);
  294. sh.label_be = label_be;
  295. Err(Message_epush(msg, &sh, SwitchHeader_SIZE));
  296. return Iface_next(&sm->pub.switchIf, msg);
  297. }
  298. static Iface_DEFUN postDecryption(Message_t* msg, struct Iface* iface)
  299. {
  300. struct SessionManager_Session_pvt* session =
  301. Identity_containerOf(iface, struct SessionManager_Session_pvt, plaintext);
  302. // The switch header is pushed as associated data
  303. uint32_t nonceOrHandle = 0xffffffff;
  304. Err(Message_epopAd(msg, &nonceOrHandle, 4));
  305. struct RouteHeader header = {
  306. .flags = RouteHeader_flags_INCOMING,
  307. .version_be = Endian_hostToBigEndian32(session->pub.version),
  308. };
  309. Err(Message_epopAd(msg, &header.sh, SwitchHeader_SIZE));
  310. Ca_getHerPubKey(session->pub.caSession, header.publicKey);
  311. Ca_getHerIp6(session->pub.caSession, header.ip6);
  312. uint64_t label = Endian_bigEndianToHost64(header.sh.label_be);
  313. enum Ca_DecryptErr ret = -1;
  314. Err(Message_epop32h(&ret, msg));
  315. if (ret) {
  316. // If CryptoAuth fails to decrypt then it gives us:
  317. // * Ca_DecryptErr - we already popped this
  318. // * first16
  319. // * Ca_DecryptErr
  320. // * state
  321. debugHandlesAndLabel(session->sessionManager->log, session,
  322. label,
  323. "DROP Failed decrypting message NoH[%d] state[%s]",
  324. nonceOrHandle,
  325. Ca_stateString(Ca_getState(session->pub.caSession)));
  326. uint64_t label_be = header.sh.label_be;
  327. // We want to preserve it "as it was" here
  328. header.sh.label_be = Bits_bitReverse64(header.sh.label_be);
  329. Err(Message_epush(msg, &header.sh, SwitchHeader_SIZE));
  330. return failedDecrypt(msg, label_be, session->sessionManager);
  331. }
  332. if (nonceOrHandle <= 3) {
  333. Err(Message_epop32be(&session->pub.sendHandle, msg));
  334. debugHandlesAndLabel0(
  335. session->sessionManager->log, session, label, "received start message");
  336. }
  337. session->pub.bytesIn += Message_getLength(msg);
  338. Err(Message_epush(msg, &header, sizeof header));
  339. discoverPath(session, label, Metric_SM_INCOMING);
  340. return Iface_next(&session->sessionManager->pub.insideIf, msg);
  341. }
  342. static Iface_DEFUN afterEncrypt(Message_t* msg, struct Iface* iface)
  343. {
  344. //Assert_true(!Ca_encrypt(sess->pub.caSession, msg));
  345. struct SessionManager_Session_pvt* sess =
  346. Identity_containerOf(iface, struct SessionManager_Session_pvt, ciphertext);
  347. struct RouteHeader header;
  348. Err(Message_epopAd(msg, &header, RouteHeader_SIZE));
  349. if (Ca_getState(sess->pub.caSession) >= Ca_State_RECEIVED_KEY) {
  350. if (0) { // Noisy
  351. debugHandlesAndLabel0(sess->sessionManager->log,
  352. sess,
  353. Endian_bigEndianToHost64(header.sh.label_be),
  354. "sending run message");
  355. }
  356. Err(Message_epush32be(msg, sess->pub.sendHandle));
  357. } else {
  358. debugHandlesAndLabel0(sess->sessionManager->log,
  359. sess,
  360. Endian_bigEndianToHost64(header.sh.label_be),
  361. "sending start message");
  362. }
  363. if (!header.sh.label_be) {
  364. Bits_memset(&header.sh, 0, SwitchHeader_SIZE);
  365. header.sh.label_be = Endian_hostToBigEndian64(sess->pub.paths[0].label);
  366. SwitchHeader_setVersion(&header.sh, SwitchHeader_CURRENT_VERSION);
  367. }
  368. Err_assert(Message_epush(msg, &header.sh, SwitchHeader_SIZE));
  369. return Iface_next(&sess->sessionManager->pub.switchIf, msg);
  370. }
  371. static struct SessionManager_Session_pvt* getSession(struct SessionManager_pvt* sm,
  372. uint8_t ip6[16],
  373. uint8_t pubKey[32],
  374. uint32_t version,
  375. uint64_t label,
  376. uint32_t metric)
  377. {
  378. Assert_true(AddressCalc_validAddress(ip6));
  379. if (!label) { metric = Metric_DEAD_LINK; }
  380. struct SessionManager_Session_pvt* sess = sessionForIp6(ip6, sm);
  381. if (sess) {
  382. sess->pub.version = (sess->pub.version) ? sess->pub.version : version;
  383. if (discoverPath(sess, label, metric)) {
  384. sess->pub.version = (version) ? version : sess->pub.version;
  385. }
  386. return sess;
  387. }
  388. struct Allocator* alloc = Allocator_child(sm->alloc);
  389. sess = Allocator_calloc(alloc, sizeof(struct SessionManager_Session_pvt), 1);
  390. Identity_set(sess);
  391. sess->plaintext.send = postDecryption;
  392. sess->ciphertext.send = afterEncrypt;
  393. sess->pub.caSession = Ca_newSession(sm->cryptoAuth, alloc, pubKey, false, "inner", false);
  394. Iface_plumb(sess->pub.caSession->plaintext, &sess->plaintext);
  395. Iface_plumb(sess->pub.caSession->ciphertext, &sess->ciphertext);
  396. sess->foundKey = !Bits_isZero(pubKey, 32);
  397. if (sess->foundKey) {
  398. uint8_t realIp6[16];
  399. AddressCalc_addressForPublicKey(realIp6, pubKey);
  400. Assert_true(!Bits_memcmp(realIp6, ip6, 16));
  401. }
  402. int ifaceIndex = Map_OfSessionsByIp6_put((struct Ip6*)ip6, &sess, &sm->ifaceMap);
  403. sess->pub.receiveHandle = sm->ifaceMap.handles[ifaceIndex] + sm->firstHandle;
  404. if (Defined(Log_DEBUG)) {
  405. uint8_t printedIp6[40];
  406. AddrTools_printIp(printedIp6, ip6);
  407. Log_debug(sm->log, "Created session for [%s] handle [%u]",
  408. printedIp6, sess->pub.receiveHandle);
  409. }
  410. int64_t now = Time_currentTimeMilliseconds();
  411. sess->alloc = alloc;
  412. sess->sessionManager = sm;
  413. sess->pub.version = version;
  414. sess->pub.paths[0].timeLastValidated = now;
  415. sess->pub.paths[0].label = label;
  416. sess->pub.paths[0].metric = metric;
  417. //Allocator_onFree(alloc, sessionCleanup, sess);
  418. sendSession(sess, &sess->pub.paths[0], 0xffffffff, PFChan_Core_SESSION);
  419. check(sm, ifaceIndex);
  420. return sess;
  421. }
  422. static Iface_DEFUN ctrlFrame(Message_t* msg, struct SessionManager_pvt* sm)
  423. {
  424. struct RouteHeader rh;
  425. Bits_memset(&rh, 0, RouteHeader_SIZE);
  426. Err(Message_epop(msg, &rh.sh, SwitchHeader_SIZE));
  427. Err(Message_epop(msg, NULL, 4));
  428. rh.flags = RouteHeader_flags_INCOMING | RouteHeader_flags_CTRLMSG;
  429. Err(Message_epush(msg, &rh, RouteHeader_SIZE));
  430. return Iface_next(&sm->pub.insideIf, msg);
  431. }
  432. static const uint8_t ADDR_PFX[8] = { 0xff, 0xfb, 0, 0, 0, 0, 0, 0 };
  433. static Iface_DEFUN incomingFromSwitchIf(Message_t* msg, struct Iface* iface)
  434. {
  435. struct SessionManager_pvt* sm =
  436. Identity_containerOf(iface, struct SessionManager_pvt, pub.switchIf);
  437. // SwitchHeader, handle, 0 or more bytes of control frame
  438. if (Message_getLength(msg) < SwitchHeader_SIZE + 4) {
  439. Log_debug(sm->log, "DROP runt");
  440. return Error(msg, "RUNT");
  441. }
  442. struct SwitchHeader switchHeader;
  443. Err(Message_epop(msg, &switchHeader, SwitchHeader_SIZE));
  444. // The label comes in reversed from the switch because the switch doesn't know that we aren't
  445. // another switch ready to parse more bits, bit reversing the label yields the source address.
  446. // (the field is still big endian!)
  447. switchHeader.label_be = Bits_bitReverse64(switchHeader.label_be);
  448. struct SessionManager_Session_pvt* session = NULL;
  449. uint32_t nonceOrHandle = Endian_bigEndianToHost32(((uint32_t*)Message_bytes(msg))[0]);
  450. if (nonceOrHandle == 0xffffffff) {
  451. Err(Message_epush(msg, &switchHeader, SwitchHeader_SIZE));
  452. return ctrlFrame(msg, sm);
  453. }
  454. // handle, small cryptoAuth header
  455. if (Message_getLength(msg) < 4 + 20) {
  456. Log_debug(sm->log, "DROP runt");
  457. return Error(msg, "RUNT");
  458. }
  459. if (nonceOrHandle > 3) {
  460. // > 3 it's a handle.
  461. session = sessionForHandle(nonceOrHandle, sm);
  462. if (!session) {
  463. Log_debug(sm->log, "DROP message with unrecognized handle [%u]", nonceOrHandle);
  464. return Error(msg, "INVALID");
  465. }
  466. Err(Message_eshift(msg, -4));
  467. uint32_t nonce = Endian_bigEndianToHost32(((uint32_t*)Message_bytes(msg))[0]);
  468. if (nonce < 4) {
  469. Log_debug(sm->log, "DROP setup message [%u] with specified handle [%u]",
  470. nonce, nonceOrHandle);
  471. return Error(msg, "INVALID");
  472. }
  473. } else {
  474. // handle + big cryptoauth header
  475. if (Message_getLength(msg) < CryptoHeader_SIZE + 4) {
  476. Log_debug(sm->log, "DROP runt");
  477. return Error(msg, "RUNT");
  478. }
  479. struct CryptoHeader* caHeader = (struct CryptoHeader*) Message_bytes(msg);
  480. uint8_t ip6[16];
  481. // a packet which claims to be "from us" causes problems
  482. if (!AddressCalc_addressForPublicKey(ip6, caHeader->publicKey)) {
  483. Log_debug(sm->log, "DROP Handshake with non-fc key");
  484. return Error(msg, "INVALID");
  485. }
  486. if (!Bits_memcmp(caHeader->publicKey, sm->ourPubKey, 32)) {
  487. Log_debug(sm->log, "DROP Handshake from 'ourselves'");
  488. return Error(msg, "INVALID");
  489. }
  490. uint64_t label = Endian_bigEndianToHost64(switchHeader.label_be);
  491. session = getSession(sm, ip6, caHeader->publicKey, 0, label, Metric_SM_INCOMING);
  492. Ca_resetIfTimeout(session->pub.caSession);
  493. debugHandlesAndLabel(sm->log, session, label, "new session nonce[%d]", nonceOrHandle);
  494. }
  495. Err(Message_epushAd(msg, &switchHeader, SwitchHeader_SIZE));
  496. Err(Message_epushAd(msg, &nonceOrHandle, 4));
  497. Err(Message_epush(msg, &switchHeader.label_be, 8));
  498. Err(Message_epush(msg, ADDR_PFX, 8));
  499. return Iface_next(&session->ciphertext, msg);
  500. }
  501. static void checkTimedOutBuffers(struct SessionManager_pvt* sm)
  502. {
  503. for (int i = 0; i < (int)sm->bufMap.count; i++) {
  504. struct BufferedMessage* buffered = sm->bufMap.values[i];
  505. int64_t lag = Time_currentTimeMilliseconds() - buffered->timeSentMilliseconds;
  506. if (lag < 10000) { continue; }
  507. Map_BufferedMessages_remove(i, &sm->bufMap);
  508. Allocator_free(buffered->alloc);
  509. i--;
  510. }
  511. }
  512. static void unsetupSession(struct SessionManager_pvt* sm, struct SessionManager_Session_pvt* sess)
  513. {
  514. if (!sess->pub.version || sess->pub.paths[0].metric == Metric_DEAD_LINK) {
  515. // Nothing we can do here because it's not ok to send traffic without a version and path.
  516. return;
  517. }
  518. struct Allocator* eventAlloc = Allocator_child(sm->alloc);
  519. Message_t* eventMsg = Message_new(0, 512, eventAlloc);
  520. struct PFChan_Node n = { .metric_be = Endian_hostToBigEndian32(Metric_DEAD_LINK) };
  521. n.path_be = Endian_hostToBigEndian64(sess->pub.paths[0].label);
  522. Assert_true(n.path_be);
  523. n.version_be = Endian_hostToBigEndian32(sess->pub.version);
  524. n.metric_be = Endian_bigEndianToHost32(sess->pub.paths[0].metric);
  525. Ca_getHerPubKey(sess->pub.caSession, n.publicKey);
  526. Ca_getHerIp6(sess->pub.caSession, n.ip6);
  527. Err_assert(Message_epush(eventMsg, &n, PFChan_Node_SIZE));
  528. Err_assert(Message_epush32be(eventMsg, 0xffffffff));
  529. Err_assert(Message_epush32be(eventMsg, PFChan_Core_UNSETUP_SESSION));
  530. Iface_send(&sm->eventIf, eventMsg);
  531. Allocator_free(eventAlloc);
  532. }
  533. static void triggerSearch(struct SessionManager_pvt* sm, uint8_t target[16], uint32_t version)
  534. {
  535. struct Allocator* eventAlloc = Allocator_child(sm->alloc);
  536. Message_t* eventMsg = Message_new(0, 512, eventAlloc);
  537. Err_assert(Message_epush32be(eventMsg, version));
  538. Err_assert(Message_epush32be(eventMsg, 0));
  539. Err_assert(Message_epush(eventMsg, target, 16));
  540. Err_assert(Message_epush32be(eventMsg, 0xffffffff));
  541. Err_assert(Message_epush32be(eventMsg, PFChan_Core_SEARCH_REQ));
  542. Iface_send(&sm->eventIf, eventMsg);
  543. Allocator_free(eventAlloc);
  544. }
  545. static SessionManager_Path_t* mostRecentValidatedPath(struct SessionManager_Session_pvt* sess)
  546. {
  547. int64_t bestTime = 0;
  548. int bestI = 0;
  549. for (int i = 0; i < SessionManager_PATH_COUNT; i++) {
  550. if (sess->pub.paths[i].timeLastValidated > bestTime) {
  551. bestTime = sess->pub.paths[i].timeLastValidated;
  552. bestI = i;
  553. }
  554. }
  555. return &sess->pub.paths[bestI];
  556. }
  557. static void checkTimedOutSessions(struct SessionManager_pvt* sm)
  558. {
  559. for (int i = (int)sm->ifaceMap.count - 1; i >= 0; i--) {
  560. struct SessionManager_Session_pvt* sess = sm->ifaceMap.values[i];
  561. int64_t now = Time_currentTimeMilliseconds();
  562. // Check if the session is timed out...
  563. SessionManager_Path_t* path = mostRecentValidatedPath(sess);
  564. if (now - path->timeLastValidated > sm->pub.sessionTimeoutMilliseconds) {
  565. debugSession0(sm->log, sess, path->label, "ended");
  566. // Only need to send this once because PFChan_Core_SESSION_ENDED
  567. // means the whole session is done
  568. sendSession(sess, path, 0xffffffff, PFChan_Core_SESSION_ENDED);
  569. Map_OfSessionsByIp6_remove(i, &sm->ifaceMap);
  570. Allocator_free(sess->alloc);
  571. continue;
  572. }
  573. if (now - sess->pub.timeOfLastUsage > sm->pub.sessionTimeoutMilliseconds) {
  574. // This session is either only used by the pathfinder or it is nolonger used
  575. // let the pathfinder maintain it if it wants to, otherwise let it drop.
  576. //
  577. // This is a convenience for user tools to know that it's unmanaged.
  578. sess->pub.timeOfLastUsage = 0;
  579. } else if (now - sess->pub.lastSearchTime >= sm->pub.sessionSearchAfterMilliseconds) {
  580. // Session is not in idle state and requires a search
  581. debugSession0(sm->log, sess, sess->pub.paths[0].label,
  582. "it's been a while, triggering search");
  583. uint8_t herIp6[16];
  584. Ca_getHerIp6(sess->pub.caSession, herIp6);
  585. triggerSearch(sm, herIp6, sess->pub.version);
  586. sess->pub.lastSearchTime = now;
  587. } else if (Ca_getState(sess->pub.caSession) < Ca_State_ESTABLISHED) {
  588. debugSession0(sm->log, sess, sess->pub.paths[0].label, "triggering unsetupSession");
  589. unsetupSession(sm, sess);
  590. }
  591. }
  592. }
  593. static void periodically(void* vSessionManager)
  594. {
  595. struct SessionManager_pvt* sm = Identity_check((struct SessionManager_pvt*) vSessionManager);
  596. checkTimedOutSessions(sm);
  597. checkTimedOutBuffers(sm);
  598. }
  599. static void bufferPacket(struct SessionManager_pvt* sm, Message_t* msg)
  600. {
  601. Assert_true(Message_getLength(msg) >= (RouteHeader_SIZE + DataHeader_SIZE));
  602. struct RouteHeader* header = (struct RouteHeader*) Message_bytes(msg);
  603. // We should never be sending CJDHT messages without full version, key, path known.
  604. struct DataHeader* dataHeader = (struct DataHeader*) &header[1];
  605. Assert_true(DataHeader_getContentType(dataHeader) != ContentType_CJDHT);
  606. uint8_t ipStr[40];
  607. AddrTools_printIp(ipStr, header->ip6);
  608. int index = Map_BufferedMessages_indexForKey((struct Ip6*)header->ip6, &sm->bufMap);
  609. if (index > -1) {
  610. struct BufferedMessage* buffered = sm->bufMap.values[index];
  611. Map_BufferedMessages_remove(index, &sm->bufMap);
  612. Allocator_free(buffered->alloc);
  613. Log_debug(sm->log, "Buffering a packet to [%s] DROP replacing one in the buffer", ipStr);
  614. } else {
  615. Log_debug(sm->log, "Buffering a packet to [%s]", ipStr);
  616. }
  617. if ((int)sm->bufMap.count >= sm->pub.maxBufferedMessages) {
  618. checkTimedOutBuffers(sm);
  619. if ((int)sm->bufMap.count >= sm->pub.maxBufferedMessages) {
  620. Log_debug(sm->log, "DROP message needing lookup maxBufferedMessages ([%d]) is reached",
  621. sm->pub.maxBufferedMessages);
  622. return;
  623. }
  624. }
  625. struct Allocator* lookupAlloc = Allocator_child(sm->alloc);
  626. struct BufferedMessage* buffered =
  627. Allocator_calloc(lookupAlloc, sizeof(struct BufferedMessage), 1);
  628. buffered->msg = msg;
  629. buffered->alloc = lookupAlloc;
  630. buffered->timeSentMilliseconds = Time_currentTimeMilliseconds();
  631. Allocator_adopt(lookupAlloc, Message_getAlloc(msg));
  632. Assert_true(Map_BufferedMessages_put((struct Ip6*)header->ip6, &buffered, &sm->bufMap) > -1);
  633. }
  634. static void needsLookup(struct SessionManager_pvt* sm, Message_t* msg)
  635. {
  636. struct RouteHeader* header = (struct RouteHeader*) Message_bytes(msg);
  637. bufferPacket(sm, msg);
  638. triggerSearch(sm, header->ip6, Endian_hostToBigEndian32(header->version_be));
  639. }
  640. static Iface_DEFUN readyToSend(Message_t* msg,
  641. struct SessionManager_pvt* sm,
  642. struct SessionManager_Session_pvt* sess)
  643. {
  644. struct RouteHeader header;
  645. Err(Message_epop(msg, &header, RouteHeader_SIZE));
  646. Assert_true(header.sh.label_be != 0xffffffffffffffffull);
  647. Ca_resetIfTimeout(sess->pub.caSession);
  648. if (Ca_getState(sess->pub.caSession) < Ca_State_RECEIVED_KEY) {
  649. // Put the handle into the message so that the other end knows how to address the session
  650. Err(Message_epush32be(msg, sess->pub.receiveHandle));
  651. }
  652. sess->pub.bytesOut += Message_getLength(msg);
  653. // Move the route header to additional data
  654. Err(Message_epushAd(msg, &header, RouteHeader_SIZE));
  655. return Iface_next(&sess->plaintext, msg); // --> afterEncrypt
  656. }
  657. static Iface_DEFUN outgoingCtrlFrame(Message_t* msg, struct SessionManager_pvt* sm)
  658. {
  659. Assert_true(Message_getLength(msg) >= RouteHeader_SIZE);
  660. struct RouteHeader* header = (struct RouteHeader*) Message_bytes(msg);
  661. if (!Bits_isZero(header->publicKey, 32) || !Bits_isZero(header->ip6, 16)) {
  662. Log_debug(sm->log, "DROP Ctrl frame with non-zero destination key or IP");
  663. return Error(msg, "INVALID");
  664. }
  665. if (!(header->flags & RouteHeader_flags_CTRLMSG)) {
  666. Log_debug(sm->log, "DROP Ctrl frame w/o RouteHeader_flags_CTRLMSG flag");
  667. return Error(msg, "INVALID");
  668. }
  669. struct SwitchHeader sh;
  670. Bits_memcpy(&sh, &header->sh, SwitchHeader_SIZE);
  671. Err(Message_epop(msg, NULL, RouteHeader_SIZE));
  672. Err(Message_epush32be(msg, 0xffffffff));
  673. Err(Message_epush(msg, &sh, SwitchHeader_SIZE));
  674. return Iface_next(&sm->pub.switchIf, msg);
  675. }
  676. static Iface_DEFUN incomingFromInsideIf(Message_t* msg, struct Iface* iface)
  677. {
  678. struct SessionManager_pvt* sm =
  679. Identity_containerOf(iface, struct SessionManager_pvt, pub.insideIf);
  680. Assert_true(Message_getLength(msg) >= RouteHeader_SIZE);
  681. struct RouteHeader* header = (struct RouteHeader*) Message_bytes(msg);
  682. if (header->flags & RouteHeader_flags_CTRLMSG) {
  683. return outgoingCtrlFrame(msg, sm);
  684. }
  685. Assert_true(Message_getLength(msg) >= RouteHeader_SIZE + DataHeader_SIZE);
  686. struct DataHeader* dataHeader = (struct DataHeader*) &header[1];
  687. struct SessionManager_Session_pvt* sess = sessionForIp6(header->ip6, sm);
  688. if (!sess) {
  689. if (!Bits_isZero(header->publicKey, 32) && header->version_be) {
  690. sess = getSession(sm,
  691. header->ip6,
  692. header->publicKey,
  693. Endian_bigEndianToHost32(header->version_be),
  694. Endian_bigEndianToHost64(header->sh.label_be),
  695. ((header->sh.label_be) ? Metric_SM_SEND : Metric_DEAD_LINK));
  696. } else {
  697. needsLookup(sm, msg);
  698. return NULL;
  699. }
  700. }
  701. if (!(header->flags & RouteHeader_flags_PATHFINDER)) {
  702. // It's real life user traffic, lets tag the time of last use
  703. sess->pub.timeOfLastUsage = Time_currentTimeMilliseconds();
  704. }
  705. if (header->version_be) { sess->pub.version = Endian_bigEndianToHost32(header->version_be); }
  706. if (!sess->pub.version) {
  707. needsLookup(sm, msg);
  708. return NULL;
  709. }
  710. if (header->sh.label_be) {
  711. // fallthrough
  712. } else if (sess->pub.paths[0].metric < Metric_DEAD_LINK) {
  713. Bits_memset(&header->sh, 0, SwitchHeader_SIZE);
  714. header->sh.label_be = Endian_hostToBigEndian64(sess->pub.paths[0].label);
  715. SwitchHeader_setVersion(&header->sh, SwitchHeader_CURRENT_VERSION);
  716. } else {
  717. needsLookup(sm, msg);
  718. return NULL;
  719. }
  720. // Forward secrecy, only send dht messages until the session is setup.
  721. Ca_resetIfTimeout(sess->pub.caSession);
  722. if (Ca_getState(sess->pub.caSession) < Ca_State_RECEIVED_KEY) {
  723. if (DataHeader_getContentType(dataHeader) == ContentType_CJDHT) {
  724. if (sess->pub.timeOfLastUsage) {
  725. // Any time any message of any kind is sent down a link that is
  726. // currently in use, keep firing off unsetupSession
  727. unsetupSession(sm, sess);
  728. }
  729. } else {
  730. debugSession0(sm->log, sess,
  731. Endian_bigEndianToHost64(header->sh.label_be), "user traffic, unsetupSession");
  732. bufferPacket(sm, msg);
  733. unsetupSession(sm, sess);
  734. return NULL;
  735. }
  736. }
  737. return readyToSend(msg, sm, sess);
  738. }
  739. static Iface_DEFUN sessions(struct SessionManager_pvt* sm,
  740. uint32_t sourcePf,
  741. struct Allocator* tempAlloc)
  742. {
  743. for (int i = 0; i < (int)sm->ifaceMap.count; i++) {
  744. struct SessionManager_Session_pvt* sess = sm->ifaceMap.values[i];
  745. sendSession(sess, &sess->pub.paths[0], sourcePf, PFChan_Core_SESSION);
  746. }
  747. return NULL;
  748. }
  749. static Iface_DEFUN incomingFromEventIf(Message_t* msg, struct Iface* iface)
  750. {
  751. struct SessionManager_pvt* sm = Identity_containerOf(iface, struct SessionManager_pvt, eventIf);
  752. enum PFChan_Pathfinder ev = 0;
  753. Err(Message_epop32be(&ev, msg));
  754. uint32_t sourcePf = 0;
  755. Err(Message_epop32be(&sourcePf, msg));
  756. if (ev == PFChan_Pathfinder_SESSIONS) {
  757. Assert_true(!Message_getLength(msg));
  758. return sessions(sm, sourcePf, Message_getAlloc(msg));
  759. }
  760. Assert_true(ev == PFChan_Pathfinder_NODE);
  761. struct PFChan_Node node;
  762. Err(Message_epop(msg, &node, PFChan_Node_SIZE));
  763. Assert_true(!Message_getLength(msg));
  764. int index = Map_BufferedMessages_indexForKey((struct Ip6*)node.ip6, &sm->bufMap);
  765. struct SessionManager_Session_pvt* sess = sessionForIp6(node.ip6, sm);
  766. if (!sess) {
  767. // Node we don't care about.
  768. if (index == -1) { return NULL; }
  769. // Broken path to a node we don't have a session for...
  770. if (node.metric_be == Metric_DEAD_LINK) { return NULL; }
  771. }
  772. sess = getSession(sm,
  773. node.ip6,
  774. node.publicKey,
  775. Endian_bigEndianToHost32(node.version_be),
  776. Endian_bigEndianToHost64(node.path_be),
  777. Endian_bigEndianToHost32(node.metric_be));
  778. // Send what's on the buffer...
  779. if (index > -1 && Ca_getState(sess->pub.caSession) >= Ca_State_RECEIVED_KEY) {
  780. struct BufferedMessage* bm = sm->bufMap.values[index];
  781. Iface_CALL(readyToSend, bm->msg, sm, sess);
  782. Map_BufferedMessages_remove(index, &sm->bufMap);
  783. Allocator_free(bm->alloc);
  784. }
  785. return NULL;
  786. }
  787. struct SessionManager* SessionManager_new(struct Allocator* allocator,
  788. EventBase_t* eventBase,
  789. Ca_t* cryptoAuth,
  790. struct Random* rand,
  791. struct Log* log,
  792. struct EventEmitter* ee)
  793. {
  794. struct Allocator* alloc = Allocator_child(allocator);
  795. struct SessionManager_pvt* sm = Allocator_calloc(alloc, sizeof(struct SessionManager_pvt), 1);
  796. sm->alloc = alloc;
  797. sm->pub.switchIf.send = incomingFromSwitchIf;
  798. sm->pub.insideIf.send = incomingFromInsideIf;
  799. sm->bufMap.allocator = alloc;
  800. sm->ifaceMap.allocator = alloc;
  801. sm->log = log;
  802. sm->cryptoAuth = cryptoAuth;
  803. sm->eventBase = eventBase;
  804. sm->pub.sessionTimeoutMilliseconds = SessionManager_SESSION_TIMEOUT_MILLISECONDS_DEFAULT;
  805. sm->pub.maxBufferedMessages = SessionManager_MAX_BUFFERED_MESSAGES_DEFAULT;
  806. sm->pub.sessionSearchAfterMilliseconds =
  807. SessionManager_SESSION_SEARCH_AFTER_MILLISECONDS_DEFAULT;
  808. Ca_getPubKey(cryptoAuth, sm->ourPubKey);
  809. sm->eventIf.send = incomingFromEventIf;
  810. EventEmitter_regCore(ee, &sm->eventIf, PFChan_Pathfinder_NODE);
  811. EventEmitter_regCore(ee, &sm->eventIf, PFChan_Pathfinder_SESSIONS);
  812. sm->firstHandle =
  813. (Random_uint32(rand) % (MAX_FIRST_HANDLE - MIN_FIRST_HANDLE)) + MIN_FIRST_HANDLE;
  814. Timeout_setInterval(periodically, sm, 1000, eventBase, alloc);
  815. Identity_set(sm);
  816. return &sm->pub;
  817. }