1
0

FakeNetwork.c 5.5 KB

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