AddrIfaceMuxer.c 4.3 KB

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