SwitchCore.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  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 <http://www.gnu.org/licenses/>.
  14. */
  15. #include "memory/Allocator.h"
  16. #include "interface/Interface.h"
  17. #include "util/log/Log.h"
  18. #include "switch/SwitchCore.h"
  19. #include "switch/NumberCompress.h"
  20. #include "switch/Penalty.h"
  21. #include "util/Bits.h"
  22. #include "util/Checksum.h"
  23. #include "util/Endian.h"
  24. #include "wire/Control.h"
  25. #include "wire/Error.h"
  26. #include "wire/Headers.h"
  27. #include "wire/SwitchHeader.h"
  28. #include "wire/Message.h"
  29. #include <inttypes.h>
  30. #include <stdbool.h>
  31. struct SwitchInterface
  32. {
  33. struct Interface* iface;
  34. struct SwitchCore* core;
  35. struct Penalty* penalty;
  36. struct Allocator_OnFreeJob* onFree;
  37. Identity
  38. };
  39. struct SwitchCore
  40. {
  41. struct SwitchInterface interfaces[NumberCompress_INTERFACES];
  42. uint32_t interfaceCount;
  43. bool routerAdded;
  44. struct Log* logger;
  45. struct EventBase* eventBase;
  46. struct Allocator* allocator;
  47. };
  48. struct SwitchCore* SwitchCore_new(struct Log* logger,
  49. struct Allocator* allocator,
  50. struct EventBase* base)
  51. {
  52. struct SwitchCore* core = Allocator_calloc(allocator, sizeof(struct SwitchCore), 1);
  53. core->allocator = allocator;
  54. core->interfaceCount = 0;
  55. core->logger = logger;
  56. core->eventBase = base;
  57. return core;
  58. }
  59. static inline uint16_t sendMessage(const struct SwitchInterface* switchIf,
  60. struct Message* toSend,
  61. struct Log* logger)
  62. {
  63. return Interface_sendMessage(switchIf->iface, toSend);
  64. }
  65. #ifdef Version_7_COMPAT
  66. struct ErrorPacket7 {
  67. struct SwitchHeader switchHeader;
  68. struct Control ctrl;
  69. };
  70. Assert_compileTime(sizeof(struct ErrorPacket7) == SwitchHeader_SIZE + sizeof(struct Control));
  71. static inline void sendError7(struct SwitchInterface* iface,
  72. struct Message* cause,
  73. uint32_t code,
  74. struct Log* logger)
  75. {
  76. struct SwitchHeader* header = (struct SwitchHeader*) cause->bytes;
  77. if (SwitchHeader_isV7Ctrl(header)
  78. && ((struct ErrorPacket7*) cause->bytes)->ctrl.type_be == Control_ERROR_be)
  79. {
  80. // Errors never cause other errors to be sent.
  81. return;
  82. }
  83. // limit of 256 bytes
  84. cause->length =
  85. (cause->length < Control_Error_MAX_SIZE) ? cause->length : Control_Error_MAX_SIZE;
  86. // Shift back so we can add another header.
  87. Message_shift(cause,
  88. SwitchHeader_SIZE + Control_HEADER_SIZE + Control_Error_HEADER_SIZE,
  89. NULL);
  90. struct ErrorPacket7* err = (struct ErrorPacket7*) cause->bytes;
  91. err->switchHeader.label_be = Bits_bitReverse64(header->label_be);
  92. SwitchHeader_setSuppressErrors(&err->switchHeader, true);
  93. // set version to 0 so that other node will not change congestion field.
  94. SwitchHeader_setVersion(&err->switchHeader, 0);
  95. SwitchHeader_setPenalty(&err->switchHeader, 0);
  96. SwitchHeader_setCongestion(&err->switchHeader, 0);
  97. err->ctrl.type_be = Control_ERROR_be;
  98. err->ctrl.content.error.errorType_be = Endian_hostToBigEndian32(code);
  99. err->ctrl.checksum_be = 0;
  100. err->ctrl.checksum_be =
  101. Checksum_engine((uint8_t*) &err->ctrl, cause->length - SwitchHeader_SIZE);
  102. sendMessage(iface, cause, logger);
  103. }
  104. #endif
  105. struct ErrorPacket8 {
  106. struct SwitchHeader switchHeader;
  107. uint32_t handle;
  108. struct Control ctrl;
  109. };
  110. Assert_compileTime(sizeof(struct ErrorPacket8) == SwitchHeader_SIZE + 4 + sizeof(struct Control));
  111. static inline void sendError8(struct SwitchInterface* iface,
  112. struct Message* cause,
  113. uint32_t code,
  114. struct Log* logger)
  115. {
  116. if (cause->length < SwitchHeader_SIZE + 4) {
  117. Log_debug(logger, "runt");
  118. return;
  119. }
  120. struct SwitchHeader* header = (struct SwitchHeader*) cause->bytes;
  121. if (SwitchHeader_getSuppressErrors(header)) {
  122. // don't send errors if they're asking us to suppress them!
  123. return;
  124. }
  125. // limit of 256 bytes
  126. cause->length =
  127. (cause->length < Control_Error_MAX_SIZE) ? cause->length : Control_Error_MAX_SIZE;
  128. // Shift back so we can add another header.
  129. Message_shift(cause,
  130. SwitchHeader_SIZE + 4 + Control_HEADER_SIZE + Control_Error_HEADER_SIZE,
  131. NULL);
  132. struct ErrorPacket8* err = (struct ErrorPacket8*) cause->bytes;
  133. err->switchHeader.label_be = Bits_bitReverse64(header->label_be);
  134. SwitchHeader_setSuppressErrors(header, true);
  135. SwitchHeader_setVersion(header, SwitchHeader_CURRENT_VERSION);
  136. SwitchHeader_setPenalty(header, 0);
  137. SwitchHeader_setCongestion(header, 0);
  138. err->handle = 0xffffffff;
  139. err->ctrl.type_be = Control_ERROR_be;
  140. err->ctrl.content.error.errorType_be = Endian_hostToBigEndian32(code);
  141. err->ctrl.checksum_be = 0;
  142. err->ctrl.checksum_be =
  143. Checksum_engine((uint8_t*) &err->ctrl, cause->length - SwitchHeader_SIZE - 4);
  144. sendMessage(iface, cause, logger);
  145. }
  146. static inline void sendError(struct SwitchInterface* iface,
  147. struct Message* cause,
  148. uint32_t code,
  149. struct Log* logger)
  150. {
  151. struct SwitchHeader* header = (struct SwitchHeader*) cause->bytes;
  152. #ifdef Version_8_COMPAT
  153. if (SwitchHeader_getCongestion(header)) {
  154. // new version packet.
  155. sendError8(iface, cause, code, logger);
  156. return;
  157. } else if (cause->length > SwitchHeader_SIZE + 4 &&
  158. ((uint32_t*)(&header[1]))[0] == 0xffffffff)
  159. {
  160. // ctrl packet which is being sent to a possibly-old-version node.
  161. sendError8(iface, cause, code, logger);
  162. return;
  163. }
  164. #ifdef Version_7_COMPAT
  165. sendError7(iface, cause, code, logger);
  166. return;
  167. #endif
  168. #endif
  169. sendError8(iface, cause, code, logger);
  170. }
  171. #define DEBUG_SRC_DST(logger, message) \
  172. Log_debug(logger, message " ([%u] to [%u])", sourceIndex, destIndex)
  173. /** This never returns an error, it sends an error packet instead. */
  174. static uint8_t receiveMessage(struct Message* message, struct Interface* iface)
  175. {
  176. struct SwitchInterface* sourceIf =
  177. Identity_check((struct SwitchInterface*) iface->receiverContext);
  178. if (message->length < SwitchHeader_SIZE) {
  179. Log_debug(sourceIf->core->logger, "DROP runt packet.");
  180. return Error_NONE;
  181. }
  182. struct SwitchCore* core = sourceIf->core;
  183. struct SwitchHeader* header = (struct SwitchHeader*) message->bytes;
  184. const uint64_t label = Endian_bigEndianToHost64(header->label_be);
  185. uint32_t bits = NumberCompress_bitsUsedForLabel(label);
  186. const uint32_t sourceIndex = sourceIf - core->interfaces;
  187. const uint32_t destIndex = NumberCompress_getDecompressed(label, bits);
  188. const uint32_t sourceBits = NumberCompress_bitsUsedForNumber(sourceIndex);
  189. Assert_true(destIndex < NumberCompress_INTERFACES);
  190. Assert_true(sourceIndex < NumberCompress_INTERFACES);
  191. if (1 == destIndex) {
  192. if (1 != (label & 0xf)) {
  193. /* routing interface: must always be compressed as 0001 */
  194. DEBUG_SRC_DST(sourceIf->core->logger,
  195. "DROP packet for this router because the destination "
  196. "discriminator was wrong");
  197. sendError(sourceIf, message, Error_MALFORMED_ADDRESS, sourceIf->core->logger);
  198. return Error_NONE;
  199. }
  200. //Assert_true(bits == 4);
  201. }
  202. if (sourceBits > bits) {
  203. if (destIndex == 1) {
  204. // If the destination index is this router, don't drop the packet since there no
  205. // way for a node to know the size of the representation of its source label.
  206. // - label ends in 0001; if there are enough zeroes at the end after removing the 1,
  207. // we can still fit in the source discriminator
  208. // - the return path probably doesn't start with 3 zeroes, but it will still be working,
  209. // as the source discriminator is large enough to make space for 3 zeroes between
  210. // reverse return path and forward path (see below)
  211. if (0 != ((label ^ 1) & (UINT64_MAX >> (64 - sourceBits - 4)))) {
  212. // This is a bug.
  213. // https://github.com/cjdelisle/cjdns/issues/93
  214. // The problem is that there is no way to splice a route and know for certain
  215. // that you've not spliced one which will end up in this if statement.
  216. // Unfortunately there seems no clean way around this issue at the moment.
  217. // If this router and switch communicated using labels with "64 + four less
  218. // than the number of bits in largest discriminator" bits wide, it could handle
  219. // this situation, this solution is obviously non-trivial.
  220. DEBUG_SRC_DST(sourceIf->core->logger,
  221. "DROP packet for this router because there is no way to "
  222. "represent the return path.");
  223. sendError(sourceIf, message, Error_RETURN_PATH_INVALID, sourceIf->core->logger);
  224. return Error_NONE;
  225. }
  226. bits = sourceBits;
  227. } else if (1 == sourceIndex) {
  228. // - we need at least 3 zeroes between reverse return path and forward path:
  229. // right now the label only contains the forward path
  230. // - sourceBits == 4, bits < 4 -> bits + 64 - sourceBits < 64
  231. // - the reverse source discriminator "1000" and the target discriminator "0001"
  232. // can overlap as "10001" (or "100001" or ...)
  233. if (0 != label >> (bits + 64 - sourceBits)) {
  234. // not enough zeroes
  235. DEBUG_SRC_DST(sourceIf->core->logger, "DROP packet because source address is "
  236. "larger than destination address.");
  237. sendError(sourceIf, message, Error_MALFORMED_ADDRESS, sourceIf->core->logger);
  238. return Error_NONE;
  239. }
  240. } else {
  241. Log_info(sourceIf->core->logger, "source exceeds dest");
  242. DEBUG_SRC_DST(sourceIf->core->logger, "DROP packet because source address is "
  243. "larger than destination address.");
  244. sendError(sourceIf, message, Error_MALFORMED_ADDRESS, sourceIf->core->logger);
  245. return Error_NONE;
  246. }
  247. }
  248. if (core->interfaces[destIndex].iface == NULL) {
  249. Log_info(sourceIf->core->logger, "no such iface");
  250. DEBUG_SRC_DST(sourceIf->core->logger, "DROP packet because there is no interface "
  251. "where the bits specify.");
  252. sendError(sourceIf, message, Error_MALFORMED_ADDRESS, sourceIf->core->logger);
  253. return Error_NONE;
  254. }
  255. /*if (sourceIndex == destIndex && sourceIndex != 1) {
  256. DEBUG_SRC_DST(sourceIf->core->logger, "DROP Packet with redundant route.");
  257. sendError(sourceIf, message, Error_LOOP_ROUTE, sourceIf->core->logger);
  258. return Error_NONE;
  259. }*/
  260. uint64_t sourceLabel = Bits_bitReverse64(NumberCompress_getCompressed(sourceIndex, bits));
  261. uint64_t targetLabel = (label >> bits) | sourceLabel;
  262. int cloneLength = (message->length < Control_Error_MAX_SIZE) ?
  263. message->length : Control_Error_MAX_SIZE;
  264. uint8_t messageClone[Control_Error_MAX_SIZE];
  265. Bits_memcpy(messageClone, message->bytes, cloneLength);
  266. // Update the header
  267. header->label_be = Endian_hostToBigEndian64(targetLabel);
  268. uint32_t labelShift = SwitchHeader_getLabelShift(header) + bits;
  269. if (labelShift > 63) {
  270. // TODO(cjd): hmm should we return an error packet?
  271. Log_debug(sourceIf->core->logger, "Label rolled over");
  272. return Error_NONE;
  273. }
  274. SwitchHeader_setLabelShift(header, labelShift);
  275. Penalty_apply(sourceIf->penalty, header, message->length);
  276. const uint16_t err = sendMessage(&core->interfaces[destIndex], message, sourceIf->core->logger);
  277. if (err) {
  278. Log_debug(sourceIf->core->logger, "Sending packet caused an error [%s]",
  279. Error_strerror(err));
  280. // be careful, the message could have decrypted content in it
  281. // and we don't want to spill it out over the wire.
  282. message->length = message->capacity;
  283. Message_shift(message, -message->length, NULL);
  284. Message_shift(message, Control_Error_MAX_SIZE, NULL);
  285. Bits_memcpy(message->bytes, messageClone, cloneLength);
  286. message->length = cloneLength;
  287. sendError(sourceIf, message, err, sourceIf->core->logger);
  288. return Error_NONE;
  289. }
  290. return Error_NONE;
  291. }
  292. static int removeInterface(struct Allocator_OnFreeJob* job)
  293. {
  294. struct SwitchInterface* si = Identity_check((struct SwitchInterface*) job->userData);
  295. Bits_memset(si, 0, sizeof(struct SwitchInterface));
  296. return 0;
  297. }
  298. void SwitchCore_swapInterfaces(struct Interface* if1, struct Interface* if2)
  299. {
  300. struct SwitchInterface* si1 = Identity_check((struct SwitchInterface*) if1->receiverContext);
  301. struct SwitchInterface* si2 = Identity_check((struct SwitchInterface*) if2->receiverContext);
  302. Assert_true(Allocator_cancelOnFree(si1->onFree) > -1);
  303. Assert_true(Allocator_cancelOnFree(si2->onFree) > -1);
  304. struct SwitchInterface si3;
  305. Bits_memcpyConst(&si3, si1, sizeof(struct SwitchInterface));
  306. Bits_memcpyConst(si1, si2, sizeof(struct SwitchInterface));
  307. Bits_memcpyConst(si2, &si3, sizeof(struct SwitchInterface));
  308. // Now the if#'s are in reverse order :)
  309. si1->onFree = Allocator_onFree(if2->allocator, removeInterface, si1);
  310. si2->onFree = Allocator_onFree(if1->allocator, removeInterface, si2);
  311. if1->receiverContext = si2;
  312. if2->receiverContext = si1;
  313. }
  314. /**
  315. * @param trust a positive integer representing how much you trust the
  316. * connected node not to send a flood.
  317. * @param labelOut an integer pointer which will be set to the path to the newly added node
  318. * in host endian order.
  319. * @return 0 if all goes well, -1 if the list is full.
  320. */
  321. int SwitchCore_addInterface(struct Interface* iface,
  322. const uint64_t trust,
  323. uint64_t* labelOut,
  324. struct SwitchCore* core)
  325. {
  326. // This is some hackery to make sure the router interface is always index 1.
  327. uint32_t ifIndex = core->interfaceCount;
  328. if (ifIndex > 0 && !core->routerAdded) {
  329. ifIndex++;
  330. } else if (ifIndex == 1) {
  331. ifIndex--;
  332. }
  333. // If there's a vacent spot where another iface was before it was removed, use that.
  334. for (uint32_t i = 0; i < ifIndex; i++) {
  335. if (core->interfaces[i].iface == NULL && i != 1) {
  336. ifIndex = i;
  337. break;
  338. }
  339. }
  340. if (ifIndex == NumberCompress_INTERFACES) {
  341. return SwitchCore_addInterface_OUT_OF_SPACE;
  342. }
  343. struct SwitchInterface* newIf = &core->interfaces[ifIndex];
  344. Bits_memcpyConst(newIf, (&(struct SwitchInterface) {
  345. .iface = iface,
  346. .core = core
  347. }), sizeof(struct SwitchInterface));
  348. newIf->penalty = Penalty_new(iface->allocator, core->eventBase, core->logger);
  349. newIf->onFree = Allocator_onFree(iface->allocator, removeInterface, newIf);
  350. Identity_set(newIf);
  351. iface->receiverContext = &core->interfaces[ifIndex];
  352. iface->receiveMessage = receiveMessage;
  353. uint32_t bits = NumberCompress_bitsUsedForNumber(ifIndex);
  354. *labelOut = NumberCompress_getCompressed(ifIndex, bits) | (1 << bits);
  355. core->interfaceCount++;
  356. return 0;
  357. }
  358. int SwitchCore_setRouterInterface(struct Interface* iface, struct SwitchCore* core)
  359. {
  360. Bits_memcpyConst(&core->interfaces[1], (&(struct SwitchInterface) {
  361. .iface = iface,
  362. .core = core
  363. }), sizeof(struct SwitchInterface));
  364. Identity_set(&core->interfaces[1]);
  365. core->interfaces[1].penalty = Penalty_new(iface->allocator, core->eventBase, core->logger);
  366. iface->receiverContext = &core->interfaces[1];
  367. iface->receiveMessage = receiveMessage;
  368. core->interfaceCount++;
  369. core->routerAdded = true;
  370. return 0;
  371. }