MultiInterface.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  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 <http://www.gnu.org/licenses/>.
  14. */
  15. #include "interface/MultiInterface.h"
  16. #include "interface/Interface.h"
  17. #include "interface/InterfaceController.h"
  18. #include "memory/Allocator.h"
  19. #include "util/Identity.h"
  20. #include "util/log/Log.h"
  21. #include "util/Hex.h"
  22. /*
  23. * An Interface such as Ethernet or UDP which may connect to multiple peers
  24. * through the same socket, Interfaces are MultiInterface must send and expect
  25. * a configurable length key to be sent in front of the message, this key
  26. * indicates which peer the message is from/to.
  27. */
  28. // if no key size is specified.
  29. #define DEFAULT_KEYSIZE 4
  30. struct MapKey
  31. {
  32. int keySize;
  33. /** Variable size. */
  34. uint8_t bytes[DEFAULT_KEYSIZE];
  35. };
  36. struct Peer
  37. {
  38. /** The InterfaceController facing iface. */
  39. struct Interface internalIf;
  40. /** The multi-iface containing this peer. */
  41. struct MultiInterface* multiIface;
  42. /** The InterfaceController's structure which is used to detect unresponsive peers. */
  43. struct InterfaceController_Peer* ifcPeer;
  44. Identity
  45. /** Variable size. */
  46. struct MapKey key;
  47. };
  48. #define Map_USE_HASH
  49. #define Map_USE_COMPARATOR
  50. #define Map_NAME OfPeersByKey
  51. #define Map_KEY_TYPE struct MapKey*
  52. #define Map_VALUE_TYPE struct Peer*
  53. #include "util/Map.h"
  54. static inline uint32_t Map_OfPeersByKey_hash(struct MapKey** key)
  55. {
  56. uint32_t* k = (uint32_t*) ((*key)->bytes);
  57. return k[ ((*key)->keySize / 4)-1 ];
  58. }
  59. static inline int Map_OfPeersByKey_compare(struct MapKey** keyA, struct MapKey** keyB)
  60. {
  61. return Bits_memcmp(*keyA, *keyB, (*keyA)->keySize+4);
  62. }
  63. struct MultiInterface_pvt
  64. {
  65. struct MultiInterface pub;
  66. /** Endpoints by their key. */
  67. struct Map_OfPeersByKey peerMap;
  68. struct InterfaceController* ic;
  69. struct Allocator* allocator;
  70. struct MapKey* workSpace;
  71. struct Log* logger;
  72. Identity
  73. };
  74. static uint8_t sendMessage(struct Message* msg, struct Interface* peerIface)
  75. {
  76. struct Peer* p = Identity_check((struct Peer*) peerIface);
  77. Message_push(msg, p->key.bytes, p->key.keySize, NULL);
  78. return p->multiIface->iface->sendMessage(msg, p->multiIface->iface);
  79. }
  80. static int removePeer(struct Allocator_OnFreeJob* job)
  81. {
  82. struct Peer* p = Identity_check((struct Peer*) job->userData);
  83. struct MultiInterface_pvt* mif = Identity_check((struct MultiInterface_pvt*) p->multiIface);
  84. struct Map_OfPeersByKey* peerMap = &mif->peerMap;
  85. for (int i = 0; i < (int)peerMap->count; i++) {
  86. if (peerMap->values[i] == p) {
  87. Map_OfPeersByKey_remove(i, peerMap);
  88. }
  89. }
  90. return 0;
  91. }
  92. static inline struct Peer* peerForKey(struct MultiInterface_pvt* mif,
  93. struct MapKey* key,
  94. bool regIfNew)
  95. {
  96. int index = Map_OfPeersByKey_indexForKey(&key, &mif->peerMap);
  97. if (index >= 0) {
  98. return mif->peerMap.values[index];
  99. }
  100. #ifdef Log_DEBUG
  101. uint8_t keyHex[256] = {0};
  102. Assert_true(Hex_encode(keyHex, 255, (uint8_t*)key, key->keySize+4));
  103. Log_debug(mif->logger, "New incoming message from [%s]", keyHex);
  104. #endif
  105. // Per peer allocator.
  106. struct Allocator* alloc = Allocator_child(mif->allocator);
  107. size_t size = sizeof(struct Peer) + (mif->pub.keySize - DEFAULT_KEYSIZE);
  108. struct Peer* peer = Allocator_malloc(alloc, size);
  109. Bits_memcpyConst(peer, (&(struct Peer) {
  110. .internalIf = {
  111. .sendMessage = sendMessage,
  112. .allocator = alloc
  113. },
  114. .multiIface = &mif->pub,
  115. .key = { .keySize = mif->pub.keySize }
  116. }), sizeof(struct Peer));
  117. Bits_memcpy(peer->key.bytes, key->bytes, mif->pub.keySize);
  118. Identity_set(peer);
  119. struct MapKey* kptr = &peer->key;
  120. index = Map_OfPeersByKey_put(&kptr, &peer, &mif->peerMap);
  121. // remove the peer from the map when the allocator is freed.
  122. Allocator_onFree(alloc, removePeer, peer);
  123. if (regIfNew) {
  124. InterfaceController_registerPeer(mif->ic, NULL, NULL, true, true, &peer->internalIf);
  125. }
  126. return peer;
  127. }
  128. /** Incoming from the network interface */
  129. static uint8_t receiveMessage(struct Message* msg, struct Interface* external)
  130. {
  131. struct MultiInterface_pvt* mif =
  132. Identity_check((struct MultiInterface_pvt*) external->receiverContext);
  133. // push the key size to the message.
  134. Message_push(msg, &mif->pub.keySize, 4, NULL);
  135. struct Peer* p = peerForKey(mif, (struct MapKey*) msg->bytes, true);
  136. // pop the key size and key
  137. Message_shift(msg, -(mif->pub.keySize + 4), NULL);
  138. // into the core.
  139. uint8_t ret = Interface_receiveMessage(&p->internalIf, msg);
  140. struct InterfaceController_Peer* icPeer = InterfaceController_getPeer(mif->ic, &p->internalIf);
  141. if (icPeer->state == InterfaceController_PeerState_UNAUTHENTICATED) {
  142. // some random stray packet wandered in to the interface....
  143. // This removes all of the state associated with the endpoint.
  144. Allocator_free(p->internalIf.allocator);
  145. }
  146. return ret;
  147. }
  148. struct Interface* MultiInterface_ifaceForKey(struct MultiInterface* mIface, void* key)
  149. {
  150. struct MultiInterface_pvt* mif = Identity_check((struct MultiInterface_pvt*) mIface);
  151. mif->workSpace->keySize = mif->pub.keySize;
  152. Bits_memcpy(mif->workSpace->bytes, key, mif->pub.keySize);
  153. struct Peer* p = peerForKey(mif, mif->workSpace, false);
  154. return &p->internalIf;
  155. }
  156. struct MultiInterface* MultiInterface_new(int keySize,
  157. struct Interface* external,
  158. struct InterfaceController* ic,
  159. struct Log* logger)
  160. {
  161. Assert_true(!(keySize % 4));
  162. Assert_true(keySize > 4);
  163. struct MultiInterface_pvt* out =
  164. Allocator_clone(external->allocator, (&(struct MultiInterface_pvt) {
  165. .pub = {
  166. .iface = external,
  167. .keySize = keySize,
  168. },
  169. .peerMap = { .allocator = external->allocator },
  170. .ic = ic,
  171. .allocator = external->allocator,
  172. .logger = logger
  173. }));
  174. Identity_set(out);
  175. out->workSpace = Allocator_malloc(external->allocator, keySize + 4);
  176. external->receiveMessage = receiveMessage;
  177. external->receiverContext = out;
  178. return &out->pub;
  179. }