MultiInterface.c 6.4 KB

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