1
0

InterfaceController.h 6.8 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 <http://www.gnu.org/licenses/>.
  14. */
  15. #ifndef InterfaceController_H
  16. #define InterfaceController_H
  17. #include "benc/String.h"
  18. #include "interface/Interface.h"
  19. #include "wire/Headers.h"
  20. #include <stdint.h>
  21. #include <stdbool.h>
  22. enum InterfaceController_PeerState
  23. {
  24. /** If state is UNAUTHENTICATED, the other node has not sent a single valid packet. */
  25. InterfaceController_PeerState_UNAUTHENTICATED = 0,
  26. /** In state == HANDSHAKE, a valid packet has been received but it could still be a replay. */
  27. InterfaceController_PeerState_HANDSHAKE,
  28. /** In state == ESTABLISHED, we know the node at the other end is authentic. */
  29. InterfaceController_PeerState_ESTABLISHED,
  30. /** If state == UNRESPONSIVE, the peer has not responded to pings in the required timeframe. */
  31. InterfaceController_PeerState_UNRESPONSIVE
  32. };
  33. static inline char* InterfaceController_stateString(enum InterfaceController_PeerState ps)
  34. {
  35. switch (ps) {
  36. case InterfaceController_PeerState_UNAUTHENTICATED: return "UNAUTHENTICATED";
  37. case InterfaceController_PeerState_HANDSHAKE: return "HANDSHAKE";
  38. case InterfaceController_PeerState_ESTABLISHED: return "ESTABLISHED";
  39. case InterfaceController_PeerState_UNRESPONSIVE: return "UNRESPONSIVE";
  40. default: return "INVALID";
  41. }
  42. }
  43. /**
  44. * Stats about a peer
  45. */
  46. struct InterfaceController_peerStats
  47. {
  48. uint8_t* pubKey;
  49. int state;
  50. uint64_t timeOfLastMessage;
  51. uint64_t bytesOut;
  52. uint64_t bytesIn;
  53. uint64_t switchLabel;
  54. bool isIncomingConnection;
  55. String* user;
  56. /** Packet loss/duplication statistics. see: ReplayProtector */
  57. uint32_t duplicates;
  58. uint32_t lostPackets;
  59. uint32_t receivedOutOfRange;
  60. };
  61. struct InterfaceController
  62. {
  63. /**
  64. * Add a new peer.
  65. * Called from the network interface when it is asked to make a connection or it autoconnects.
  66. * If the peer which is connected to becomes unresponsive, IC will *not* remove it but will
  67. * set it's state to UNRESPONSIVE and it is the job of the caller to remove the peer by freeing
  68. * the allocator which is provided with iface.
  69. *
  70. * BEWARE: the interface allocator you provide here may be freed by this code!
  71. *
  72. * The following cases will cause the allocator to be freed:
  73. *
  74. * 1. If a peer is registered and it turns out to have the same cryptographic key as an
  75. * existing peer, the existing one will be freed by the IC and the new one will take it's
  76. * place.
  77. *
  78. * 2. If a peer which is registered as "transient" and is unresponsive for more than
  79. * FORGET_AFTER_MILLISECONDS milliseconds then the session will be removed.
  80. *
  81. * @param ic the interface controller.
  82. * @param herPublicKey the public key of the foreign node, NULL if unknown.
  83. * @param password the password for authenticating with the other node or NULL if unspecified.
  84. * @param requireAuth true if the other node must authenticate (incoming connection).
  85. * @param transient if true then this peer may be forgotten.
  86. * @param iface an interface which pipes messages to/from this peer. The peer will be
  87. * deregistered if this allocator is freed.
  88. *
  89. * @return 0 if all goes well.
  90. * InterfaceController_registerPeer_OUT_OF_SPACE if there is no space to store the peer.
  91. * InterfaceController_registerPeer_BAD_KEY the provided herPublicKey is not valid.
  92. * InterfaceController_registerPeer_INTERNAL unspecified error.
  93. */
  94. #define InterfaceController_registerPeer_INTERNAL -3
  95. #define InterfaceController_registerPeer_BAD_KEY -2
  96. #define InterfaceController_registerPeer_OUT_OF_SPACE -1
  97. int (* const registerPeer)(struct InterfaceController* ic,
  98. uint8_t herPublicKey[32],
  99. String* password,
  100. bool requireAuth,
  101. bool transient,
  102. struct Interface* iface);
  103. /**
  104. * Disconnect a previously registered peer.
  105. *
  106. * @param ic the if controller
  107. * @param herPublicKey the public key of the foreign node
  108. * @retrun 0 if all goes well.
  109. * InterfaceController_disconnectPeer_NOTFOUND if no peer with herPublicKey is found.
  110. */
  111. #define InterfaceController_disconnectPeer_NOTFOUND -1
  112. int (* const disconnectPeer)(struct InterfaceController* ic,
  113. uint8_t herPublicKey[32]);
  114. /**
  115. * Populate an empty beacon with password, public key, and version.
  116. * Each startup, a password is generated consisting of Headers_Beacon_PASSWORD_LEN bytes.
  117. * If beaconing is enabled for an interface, this password is sent out in each beacon message
  118. * so that others can connect.
  119. * NOTE: Anyone can connect to any interface, even those not beaconing, using this password.
  120. * The public key attached to the beacon message is the public key for this node.
  121. *
  122. * @param ic the if controller
  123. * @param beacon an empty buffer to place the beacon information in.
  124. */
  125. void (* const populateBeacon)(struct InterfaceController* ic, struct Headers_Beacon* beacon);
  126. /** Get the current state of a registered interface. */
  127. enum InterfaceController_PeerState (* const getPeerState)(struct Interface* iface);
  128. /**
  129. * Get stats for the connected peers.
  130. *
  131. * @params ic the if controller
  132. * @params alloc the Allocator to use for the peerStats array in statsOut
  133. * @params statsOut pointer to the InterfaceController_peerStats array
  134. * @return the number of InterfaceController_peerStats in statsOut
  135. */
  136. int (* const getPeerStats)(struct InterfaceController* ic,
  137. struct Allocator* alloc,
  138. struct InterfaceController_peerStats** statsOut);
  139. };
  140. #define InterfaceController_getPeerState(ic, iface) \
  141. ((ic)->getPeerState(iface))
  142. #define InterfaceController_registerPeer(ic, herPublicKey, password, requireAuth, transient, iface)\
  143. ((ic)->registerPeer((ic), (herPublicKey), (password), (requireAuth), (transient), (iface)))
  144. #define InterfaceController_populateBeacon(ic, beacon) \
  145. ((ic)->populateBeacon((ic), (beacon)))
  146. #endif