1
0

FakeNetwork.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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 "util/events/FakeNetwork.h"
  16. #include "exception/Except.h"
  17. #include "interface/Iface.h"
  18. #include "interface/addressable/AddrIface.h"
  19. #include "memory/Allocator.h"
  20. #include "util/events/EventBase.h"
  21. #include "util/log/Log.h"
  22. #include "interface/ASynchronizer.h"
  23. #include "wire/Error.h"
  24. #define Map_USE_HASH
  25. #define Map_USE_COMPARATOR
  26. #define Map_NAME OfIfaces
  27. #define Map_KEY_TYPE struct Sockaddr*
  28. #define Map_VALUE_TYPE struct FakeNetwork_UDPIface_pvt*
  29. #include "util/Map.h"
  30. static inline uint32_t Map_OfIfaces_hash(struct Sockaddr** key)
  31. {
  32. return Sockaddr_hash(*key);
  33. }
  34. static inline int Map_OfIfaces_compare(struct Sockaddr** keyA, struct Sockaddr** keyB)
  35. {
  36. return Sockaddr_compare(*keyA, *keyB);
  37. }
  38. struct FakeNetwork_pvt
  39. {
  40. struct FakeNetwork pub;
  41. struct Allocator* alloc;
  42. struct Log* log;
  43. struct EventBase* base;
  44. struct ASynchronizer* async;
  45. struct Iface fromAsync;
  46. struct Iface toAsync;
  47. uint16_t lastPort;
  48. struct Map_OfIfaces map;
  49. Identity
  50. };
  51. struct FakeNetwork_UDPIface_pvt
  52. {
  53. struct FakeNetwork_UDPIface pub;
  54. struct FakeNetwork_pvt* fnp;
  55. Identity
  56. };
  57. static void popSockaddr(struct Message* msg, struct Sockaddr_storage* ss)
  58. {
  59. uint64_t length = 0;
  60. Er_assert(Message_epop(msg, &length, 8));
  61. Er_assert(Message_eshift(msg, 8));
  62. Assert_true(length >= Sockaddr_OVERHEAD);
  63. Assert_true(length <= sizeof(struct Sockaddr_storage));
  64. Er_assert(Message_epop(msg, ss, length));
  65. }
  66. static void pushSockaddr(struct Message* msg, struct Sockaddr* sa)
  67. {
  68. Er_assert(Message_epush(msg, sa, sa->addrLen));
  69. }
  70. static Iface_DEFUN fromAsync(struct Message* msg, struct Iface* fnpFromAsync)
  71. {
  72. struct FakeNetwork_pvt* fnp =
  73. Identity_containerOf(fnpFromAsync, struct FakeNetwork_pvt, fromAsync);
  74. struct Sockaddr_storage dest;
  75. struct Sockaddr* dp = &dest.addr;
  76. popSockaddr(msg, &dest);
  77. int idx = Map_OfIfaces_indexForKey(&dp, &fnp->map);
  78. if (idx == -1) {
  79. char* destAddr = Sockaddr_print(dp, Message_getAlloc(msg));
  80. // hack, the 'dest' becomes the source.
  81. popSockaddr(msg, &dest);
  82. char* srcAddr = Sockaddr_print(dp, Message_getAlloc(msg));
  83. Log_debug(fnp->log, "Message with unknown dest address [%s] from [%s]", destAddr, srcAddr);
  84. return Error(msg, "INVALID");
  85. }
  86. struct FakeNetwork_UDPIface_pvt* fnip = Identity_check(fnp->map.values[idx]);
  87. return Iface_next(&fnip->pub.generic.iface, msg);
  88. }
  89. static Iface_DEFUN incoming(struct Message* msg, struct Iface* iface)
  90. {
  91. struct FakeNetwork_UDPIface_pvt* fnip =
  92. Identity_check((struct FakeNetwork_UDPIface_pvt*) iface);
  93. struct FakeNetwork_pvt* fnp = Identity_check(fnip->fnp);
  94. // Swap so that the message contains [dest][src][content]
  95. struct Sockaddr_storage dest;
  96. popSockaddr(msg, &dest);
  97. pushSockaddr(msg, fnip->pub.generic.addr);
  98. pushSockaddr(msg, &dest.addr);
  99. return Iface_next(&fnp->toAsync, msg);
  100. }
  101. struct FakeNetwork_UDPIface* FakeNetwork_iface(struct FakeNetwork* net,
  102. struct Sockaddr* bindAddress,
  103. struct Allocator* allocator)
  104. {
  105. struct FakeNetwork_pvt* fnp = Identity_check((struct FakeNetwork_pvt*) net);
  106. struct Allocator* alloc = Allocator_child(allocator);
  107. struct Sockaddr* addr = Sockaddr_clone(bindAddress, alloc);
  108. uint8_t* addrBytes;
  109. int addrLen = Sockaddr_getAddress(addr, &addrBytes);
  110. if (Sockaddr_getPort(addr) == 0) {
  111. Sockaddr_setPort(addr, ++fnp->lastPort);
  112. // Check for wrapping.
  113. Assert_true(fnp->lastPort != 0);
  114. Assert_true(addrLen == 4);
  115. Bits_memcpy(addrBytes, ((uint8_t[]){127, 0, 0, 1}), 4);
  116. } else if (addrLen == 4 && !Bits_memcmp(addrBytes, "\0\0\0\0", 4)) {
  117. Assert_failure("Address 0 with port specified is not allowed");
  118. }
  119. if (Map_OfIfaces_indexForKey(&addr, &fnp->map) != -1) {
  120. return NULL;
  121. }
  122. struct FakeNetwork_UDPIface_pvt* fnip =
  123. Allocator_calloc(alloc, sizeof(struct FakeNetwork_UDPIface_pvt), 1);
  124. Map_OfIfaces_put(&addr, &fnip, &fnp->map);
  125. fnip->fnp = fnp;
  126. fnip->pub.generic.alloc = alloc;
  127. fnip->pub.generic.addr = addr;
  128. fnip->pub.generic.iface.send = incoming;
  129. Identity_set(fnip);
  130. return &fnip->pub;
  131. }
  132. struct FakeNetwork* FakeNetwork_new(struct EventBase* base,
  133. struct Allocator* allocator,
  134. struct Log* logger)
  135. {
  136. struct Allocator* alloc = Allocator_child(allocator);
  137. struct FakeNetwork_pvt* fnp = Allocator_calloc(alloc, sizeof(struct FakeNetwork_pvt), 1);
  138. fnp->alloc = alloc;
  139. fnp->log = logger;
  140. fnp->base = base;
  141. fnp->map.allocator = alloc;
  142. fnp->async = ASynchronizer_new(alloc, base, logger);
  143. fnp->fromAsync.send = fromAsync;
  144. Iface_plumb(&fnp->fromAsync, &fnp->async->ifB);
  145. Iface_plumb(&fnp->toAsync, &fnp->async->ifA);
  146. Identity_set(fnp);
  147. return &fnp->pub;
  148. }