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