InterfaceController.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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 "crypto/CryptoAuth.h"
  21. #include "dht/dhtcore/Router.h"
  22. #include "dht/dhtcore/RumorMill.h"
  23. #include "interface/Interface.h"
  24. #include "memory/Allocator.h"
  25. #include "switch/SwitchCore.h"
  26. #include "net/SwitchPinger.h"
  27. #include "util/log/Log.h"
  28. #include "util/Linker.h"
  29. Linker_require("interface/InterfaceController.c")
  30. #include <stdint.h>
  31. #include <stdbool.h>
  32. enum InterfaceController_PeerState
  33. {
  34. /**
  35. * In state >= NEW, a valid packet has been received but it could still be a replay.
  36. * Or it's an outgoing connection so we don't care about authentication.
  37. */
  38. InterfaceController_PeerState_NEW = CryptoAuth_NEW,
  39. InterfaceController_PeerState_HANDSHAKE1 = CryptoAuth_HANDSHAKE1,
  40. InterfaceController_PeerState_HANDSHAKE2 = CryptoAuth_HANDSHAKE2,
  41. InterfaceController_PeerState_HANDSHAKE3 = CryptoAuth_HANDSHAKE3,
  42. /** In state == ESTABLISHED, we know the node at the other end is authentic. */
  43. InterfaceController_PeerState_ESTABLISHED = CryptoAuth_ESTABLISHED,
  44. /** If state == UNRESPONSIVE, the peer has not responded to pings in the required timeframe. */
  45. InterfaceController_PeerState_UNRESPONSIVE = -1,
  46. /** If state is UNAUTHENTICATED, the other node has not sent a single valid packet. */
  47. InterfaceController_PeerState_UNAUTHENTICATED = -2,
  48. };
  49. Assert_compileTime(CryptoAuth_STATE_COUNT == 5);
  50. static inline char* InterfaceController_stateString(enum InterfaceController_PeerState ps)
  51. {
  52. switch (ps) {
  53. case InterfaceController_PeerState_NEW: return "NEW";
  54. case InterfaceController_PeerState_HANDSHAKE1: return "HANDSHAKE1";
  55. case InterfaceController_PeerState_HANDSHAKE2: return "HANDSHAKE2";
  56. case InterfaceController_PeerState_HANDSHAKE3: return "HANDSHAKE3";
  57. case InterfaceController_PeerState_ESTABLISHED: return "ESTABLISHED";
  58. case InterfaceController_PeerState_UNRESPONSIVE: return "UNRESPONSIVE";
  59. case InterfaceController_PeerState_UNAUTHENTICATED: return "UNAUTHENTICATED";
  60. default: return "INVALID";
  61. }
  62. }
  63. /**
  64. * Stats about a peer
  65. */
  66. struct InterfaceController_peerStats
  67. {
  68. uint8_t* pubKey;
  69. int state;
  70. uint64_t timeOfLastMessage;
  71. uint64_t bytesOut;
  72. uint64_t bytesIn;
  73. uint64_t switchLabel;
  74. bool isIncomingConnection;
  75. String* user;
  76. /** Packet loss/duplication statistics. see: ReplayProtector */
  77. uint32_t duplicates;
  78. uint32_t lostPackets;
  79. uint32_t receivedOutOfRange;
  80. };
  81. struct InterfaceController
  82. {
  83. /** If set, this will override the default registerPeer function */
  84. int (* registerPeer)(struct InterfaceController* ifController,
  85. uint8_t herPublicKey[32],
  86. String* password,
  87. bool requireAuth,
  88. bool isIncomingConnection,
  89. struct Interface* externalInterface);
  90. /** If set, this will override the default getPeer function. */
  91. struct InterfaceController_Peer* (* getPeer)(struct InterfaceController* ifc,
  92. struct Interface* iface);
  93. };
  94. struct InterfaceController_Peer
  95. {
  96. /** The interface which is registered with the switch. */
  97. struct Interface switchIf;
  98. /** The internal (wrapped by CryptoAuth) interface. */
  99. struct Interface* cryptoAuthIf;
  100. /** The external (network side) interface. */
  101. struct Interface* external;
  102. /** The label for this endpoint, needed to ping the endpoint. */
  103. uint64_t switchLabel;
  104. /** Milliseconds since the epoch when the last *valid* message was received. */
  105. uint64_t timeOfLastMessage;
  106. /** Time when the last switch ping response was received from this node. */
  107. uint64_t timeOfLastPing;
  108. /** A counter to allow for 3/4 of all pings to be skipped when a node is definitely down. */
  109. uint32_t pingCount;
  110. /** The handle which can be used to look up this endpoint in the endpoint set. */
  111. uint32_t handle;
  112. /** True if we should forget about the peer if they do not respond. */
  113. bool isIncomingConnection;
  114. /**
  115. * If InterfaceController_PeerState_UNAUTHENTICATED, no permanent state will be kept.
  116. * During transition from HANDSHAKE to ESTABLISHED, a check is done for a registeration of a
  117. * node which is already registered in a different switch slot, if there is one and the
  118. * handshake completes, it will be moved.
  119. */
  120. enum InterfaceController_PeerState state;
  121. // traffic counters
  122. uint64_t bytesOut;
  123. uint64_t bytesIn;
  124. Identity
  125. };
  126. /**
  127. * Add a new peer.
  128. * Called from the network interface when it is asked to make a connection or it autoconnects.
  129. * If the peer which is connected to becomes unresponsive, IC will *not* remove it but will
  130. * set it's state to UNRESPONSIVE and it is the job of the caller to remove the peer by freeing
  131. * the allocator which is provided with iface.
  132. *
  133. * BEWARE: the interface allocator you provide here may be freed by this code!
  134. *
  135. * The following cases will cause the allocator to be freed:
  136. *
  137. * 1. If a peer is registered and it turns out to have the same cryptographic key as an
  138. * existing peer, the existing one will be freed by the IC and the new one will take it's
  139. * place.
  140. *
  141. * 2. If a peer which is registered as "transient" and is unresponsive for more than
  142. * FORGET_AFTER_MILLISECONDS milliseconds then the session will be removed.
  143. *
  144. * @param ic the interface controller.
  145. * @param herPublicKey the public key of the foreign node, NULL if unknown.
  146. * @param password the password for authenticating with the other node or NULL if unspecified.
  147. * @param requireAuth true if the other node must authenticate (incoming connection).
  148. * @param transient if true then this peer may be forgotten.
  149. * @param iface an interface which pipes messages to/from this peer. The peer will be
  150. * deregistered if this allocator is freed.
  151. *
  152. * @return 0 if all goes well.
  153. * InterfaceController_registerPeer_OUT_OF_SPACE if there is no space to store the peer.
  154. * InterfaceController_registerPeer_BAD_KEY the provided herPublicKey is not valid.
  155. * InterfaceController_registerPeer_INTERNAL unspecified error.
  156. */
  157. #define InterfaceController_registerPeer_INTERNAL -3
  158. #define InterfaceController_registerPeer_BAD_KEY -2
  159. #define InterfaceController_registerPeer_OUT_OF_SPACE -1
  160. int InterfaceController_registerPeer(struct InterfaceController* ifController,
  161. uint8_t herPublicKey[32],
  162. String* password,
  163. bool requireAuth,
  164. bool isIncomingConnection,
  165. struct Interface* externalInterface);
  166. /**
  167. * Disconnect a previously registered peer.
  168. *
  169. * @param ic the if controller
  170. * @param herPublicKey the public key of the foreign node
  171. * @retrun 0 if all goes well.
  172. * InterfaceController_disconnectPeer_NOTFOUND if no peer with herPublicKey is found.
  173. */
  174. #define InterfaceController_disconnectPeer_NOTFOUND -1
  175. int InterfaceController_disconnectPeer(struct InterfaceController* ifController,
  176. uint8_t herPublicKey[32]);
  177. /**
  178. * Populate an empty beacon with password, public key, and version.
  179. * Each startup, a password is generated consisting of Headers_Beacon_PASSWORD_LEN bytes.
  180. * If beaconing is enabled for an interface, this password is sent out in each beacon message
  181. * so that others can connect.
  182. * NOTE: Anyone can connect to any interface, even those not beaconing, using this password.
  183. * The public key attached to the beacon message is the public key for this node.
  184. *
  185. * @param ic the if controller
  186. * @param beacon an empty buffer to place the beacon information in.
  187. */
  188. void InterfaceController_populateBeacon(struct InterfaceController* ifc,
  189. struct Headers_Beacon* beacon);
  190. /** Get the IfController peer for a registered interface. */
  191. struct InterfaceController_Peer* InterfaceController_getPeer(struct InterfaceController* ifc,
  192. struct Interface* iface);
  193. /**
  194. * Get stats for the connected peers.
  195. *
  196. * @params ic the if controller
  197. * @params alloc the Allocator to use for the peerStats array in statsOut
  198. * @params statsOut pointer to the InterfaceController_peerStats array
  199. * @return the number of InterfaceController_peerStats in statsOut
  200. */
  201. int InterfaceController_getPeerStats(struct InterfaceController* ic,
  202. struct Allocator* alloc,
  203. struct InterfaceController_peerStats** statsOut);
  204. struct InterfaceController* InterfaceController_new(struct CryptoAuth* ca,
  205. struct SwitchCore* switchCore,
  206. struct Router* router,
  207. struct RumorMill* rumorMill,
  208. struct Log* logger,
  209. struct EventBase* eventBase,
  210. struct SwitchPinger* switchPinger,
  211. struct Random* rand,
  212. struct Allocator* allocator);
  213. #endif