1
0

AddrIfaceMuxer.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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 "interface/addressable/AddrIfaceMuxer.h"
  16. #include "memory/Allocator.h"
  17. #include "util/platform/Sockaddr.h"
  18. #include "util/Assert.h"
  19. #include "util/Identity.h"
  20. #include "wire/Message.h"
  21. #include "wire/Error.h"
  22. #include "util/Hex.h"
  23. struct AddrIfaceMuxer_pvt;
  24. struct AddrIfaceMuxer_Iface {
  25. struct Iface iface;
  26. struct AddrIfaceMuxer_pvt* muxer;
  27. struct Allocator* alloc;
  28. struct Sockaddr addr;
  29. Identity
  30. };
  31. #define Map_NAME Ifaces
  32. #define Map_ENABLE_HANDLES
  33. #define Map_VALUE_TYPE struct AddrIfaceMuxer_Iface*
  34. #include "util/Map.h"
  35. struct AddrIfaceMuxer_pvt
  36. {
  37. struct AddrIfaceMuxer pub;
  38. Iface_t iface;
  39. struct Map_Ifaces ifaces;
  40. struct Log* log;
  41. Identity
  42. };
  43. static Iface_DEFUN incomingFromAddrIf(struct Message* msg, struct Iface* addrIf)
  44. {
  45. struct AddrIfaceMuxer_pvt* ctx =
  46. Identity_containerOf(addrIf, struct AddrIfaceMuxer_pvt, iface);
  47. struct Sockaddr* addr = Er_assert(AddrIface_popAddr(msg));
  48. if (addr->addrLen > sizeof(struct Sockaddr)) {
  49. // There's another address packed under this one
  50. struct Sockaddr* subaddr = &addr[1];
  51. Assert_true(subaddr->addrLen == addr->addrLen - sizeof(struct Sockaddr));
  52. // Move the needle back to include it
  53. Er_assert(Message_eshift(msg, subaddr->addrLen));
  54. addr->addrLen -= subaddr->addrLen;
  55. }
  56. uint32_t handle = Sockaddr_addrHandle(addr);
  57. int idx = Map_Ifaces_indexForHandle(handle, &ctx->ifaces);
  58. if (idx < 0) {
  59. Log_info(ctx->log, "DROP message to nonexistant iface [0x%x]", handle);
  60. return Error(msg, "UNHANDLED (no such iface)");
  61. }
  62. return Iface_next(&ctx->ifaces.values[idx]->iface, msg);
  63. }
  64. static Iface_DEFUN incomingFromInputIf(struct Message* msg, struct Iface* inputIf)
  65. {
  66. struct AddrIfaceMuxer_Iface* cli =
  67. Identity_containerOf(inputIf, struct AddrIfaceMuxer_Iface, iface);
  68. struct AddrIfaceMuxer_pvt* ctx = Identity_check(cli->muxer);
  69. if (Message_getLength(msg) < (int)sizeof(struct Sockaddr)) {
  70. Log_info(ctx->log, "DROP runt");
  71. return Error(msg, "RUNT");
  72. }
  73. uint16_t addrLen = Bits_get16(msg->msgbytes);
  74. Er_assert(AddrIface_pushAddr(msg, &cli->addr));
  75. // After pushing the address, tweak the length
  76. Bits_put16(msg->msgbytes, cli->addr.addrLen + addrLen);
  77. return Iface_next(ctx->pub.iface.iface, msg);
  78. }
  79. static int removeIfaceOnFree(struct Allocator_OnFreeJob* job)
  80. {
  81. struct AddrIfaceMuxer_Iface* cli = Identity_check((struct AddrIfaceMuxer_Iface*)job->userData);
  82. struct AddrIfaceMuxer_pvt* m = Identity_check(cli->muxer);
  83. uint32_t handle = Sockaddr_addrHandle(&cli->addr);
  84. int idx = Map_Ifaces_indexForHandle(handle, &m->ifaces);
  85. if (idx > -1) {
  86. Map_Ifaces_remove(idx, &m->ifaces);
  87. }
  88. return 0;
  89. }
  90. struct Iface* AddrIfaceMuxer_registerIface(struct AddrIfaceMuxer* muxer, struct Allocator* alloc)
  91. {
  92. struct AddrIfaceMuxer_pvt* m = Identity_check((struct AddrIfaceMuxer_pvt*) muxer);
  93. struct AddrIfaceMuxer_Iface* cli =
  94. Allocator_calloc(alloc, sizeof(struct AddrIfaceMuxer_Iface), 1);
  95. cli->iface.send = incomingFromInputIf;
  96. cli->muxer = m;
  97. cli->alloc = alloc;
  98. Identity_set(cli);
  99. int idx = Map_Ifaces_put(&cli, &m->ifaces);
  100. uint32_t handle = m->ifaces.handles[idx];
  101. Sockaddr_addrFromHandle(&cli->addr, handle);
  102. Allocator_onFree(alloc, removeIfaceOnFree, cli);
  103. return &cli->iface;
  104. }
  105. struct AddrIfaceMuxer* AddrIfaceMuxer_new(struct Log* log, struct Allocator* alloc)
  106. {
  107. struct AddrIfaceMuxer_pvt* ctx = Allocator_clone(alloc, (&(struct AddrIfaceMuxer_pvt) {
  108. .pub = { .iface.alloc = alloc },
  109. .iface = { .send = incomingFromAddrIf },
  110. .log = log,
  111. .ifaces = { .allocator = alloc },
  112. }));
  113. ctx->pub.iface.iface = &ctx->iface;
  114. Identity_set(ctx);
  115. return &ctx->pub;
  116. }