SessionManager.c 36 KB

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