InterfaceController.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  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. #ifndef InterfaceController_H
  16. #define InterfaceController_H
  17. #include "benc/String.h"
  18. #include "crypto/CryptoAuth.h"
  19. #include "dht/Address.h"
  20. #include "interface/Iface.h"
  21. #include "memory/Allocator.h"
  22. #include "switch/SwitchCore.h"
  23. #include "net/SwitchPinger.h"
  24. #include "net/EventEmitter.h"
  25. #include "util/platform/Sockaddr.h"
  26. #include "util/log/Log.h"
  27. #include "util/Linker.h"
  28. Linker_require("net/InterfaceController.c");
  29. #include <stdint.h>
  30. #include <stdbool.h>
  31. enum InterfaceController_PeerState
  32. {
  33. /**
  34. * In state >= NEW, a valid packet has been received but it could still be a replay.
  35. * Or it's an outgoing connection so we don't care about authentication.
  36. */
  37. InterfaceController_PeerState_INIT = CryptoAuth_State_INIT,
  38. InterfaceController_PeerState_SENT_HELLO = CryptoAuth_State_SENT_HELLO,
  39. InterfaceController_PeerState_RECEIVED_HELLO = CryptoAuth_State_RECEIVED_HELLO,
  40. InterfaceController_PeerState_SENT_KEY = CryptoAuth_State_SENT_KEY,
  41. InterfaceController_PeerState_RECEIVED_KEY = CryptoAuth_State_RECEIVED_KEY,
  42. /** In state == ESTABLISHED, we know the node at the other end is authentic. */
  43. InterfaceController_PeerState_ESTABLISHED = CryptoAuth_State_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. // The other node has a version which is incompatible with ours, no communication is possible
  49. InterfaceController_PeerState_INCOMPATIBLE = -3,
  50. };
  51. static inline char* InterfaceController_stateString(enum InterfaceController_PeerState ps)
  52. {
  53. switch (ps) {
  54. case InterfaceController_PeerState_INIT: return "INIT";
  55. case InterfaceController_PeerState_SENT_HELLO: return "SENT_HELLO";
  56. case InterfaceController_PeerState_RECEIVED_HELLO: return "RECEIVED_HELLO";
  57. case InterfaceController_PeerState_SENT_KEY: return "SENT_KEY";
  58. case InterfaceController_PeerState_RECEIVED_KEY: return "RECEIVED_KEY";
  59. case InterfaceController_PeerState_ESTABLISHED: return "ESTABLISHED";
  60. case InterfaceController_PeerState_UNRESPONSIVE: return "UNRESPONSIVE";
  61. case InterfaceController_PeerState_UNAUTHENTICATED: return "UNAUTHENTICATED";
  62. case InterfaceController_PeerState_INCOMPATIBLE: return "INCOMPATIBLE";
  63. default: return "INVALID";
  64. }
  65. }
  66. enum InterfaceController_BeaconState
  67. {
  68. InterfaceController_BeaconState_DISABLED,
  69. InterfaceController_BeaconState_ACCEPTING,
  70. InterfaceController_BeaconState_SENDING
  71. };
  72. static inline char* InterfaceController_beaconStateString(enum InterfaceController_BeaconState bs)
  73. {
  74. switch (bs) {
  75. case InterfaceController_BeaconState_DISABLED: return "DISABLED";
  76. case InterfaceController_BeaconState_ACCEPTING: return "ACCEPTING";
  77. case InterfaceController_BeaconState_SENDING: return "SENDING";
  78. default: return "INVALID";
  79. }
  80. }
  81. /**
  82. * Stats about a peer
  83. */
  84. struct InterfaceController_PeerStats
  85. {
  86. struct Address addr;
  87. struct Sockaddr* lladdr;
  88. int state;
  89. int ifNum;
  90. uint64_t timeOfLastMessage;
  91. uint64_t bytesOut;
  92. uint64_t bytesIn;
  93. bool isIncomingConnection;
  94. String* user;
  95. /** Packet loss/duplication statistics. see: ReplayProtector */
  96. uint32_t duplicates;
  97. uint32_t lostPackets;
  98. uint32_t receivedPackets;
  99. uint32_t receivedOutOfRange;
  100. uint32_t sendKbps;
  101. uint32_t recvKbps;
  102. };
  103. struct InterfaceController
  104. {
  105. /*
  106. * If set to true, high resolution timestamp data will be collected for each
  107. * packet to help with estimating available bandwidth. Caution: this implies
  108. * an extra syscall per packet.
  109. */
  110. bool timestampPackets;
  111. };
  112. struct InterfaceController_Iface
  113. {
  114. struct Iface addrIf;
  115. /** Interface number within InterfaceController. */
  116. int ifNum;
  117. enum InterfaceController_BeaconState beaconState;
  118. String* name;
  119. };
  120. /**
  121. * Register an Ethernet-like interface.
  122. * Ethernet-like means the interface is capable of sending messages to one or more nodes
  123. * and differentiates between them using an address.
  124. *
  125. * @param ifc the interface controller
  126. * @param name a string which will identify this interface
  127. * @param alloc an allocator, the interface will be removed when this is freed.
  128. */
  129. struct InterfaceController_Iface* InterfaceController_newIface(struct InterfaceController* ifc,
  130. String* name,
  131. struct Allocator* alloc);
  132. /** Get the number of interfaces registered with the controller. */
  133. int InterfaceController_ifaceCount(struct InterfaceController* ifc);
  134. /** Get an interface from the InterfaceController. */
  135. struct InterfaceController_Iface* InterfaceController_getIface(struct InterfaceController* ifc,
  136. int ifNum);
  137. /**
  138. * Add a new peer.
  139. * Called from the network interface when it is asked to make a connection or it autoconnects.
  140. * If the peer which is connected to becomes unresponsive, IC will *not* remove it but will
  141. * set it's state to UNRESPONSIVE and it is the job of the caller to remove the peer by freeing
  142. * the allocator which is provided with iface.
  143. *
  144. * @param ifc the interface controller.
  145. * @param interfaceNumber a number for the interface to use, see regIface.
  146. * @param herPublicKey the public key of the foreign node, NULL if unknown.
  147. * @param lladdr the link level address, must be the size given by the interface for interfaceNumber
  148. * @param password the password for authenticating with the other node.
  149. * @param login an identity to provide to the other node with the password,
  150. * if null then authtype 1 will be used.
  151. * @param displayName the username to assign the other node in the CryptoAuth session. May be null.
  152. * @param alloc the peer will be dropped if this is freed.
  153. *
  154. * @return 0 if all goes well.
  155. * InterfaceController_bootstrapPeer_BAD_IFNUM if there is no such interface for this num.
  156. * InterfaceController_bootstrapPeer_OUT_OF_SPACE if there is no space to store the peer.
  157. * InterfaceController_bootstrapPeer_BAD_KEY the provided herPublicKey is not valid.
  158. * InterfaceController_bootstrapPeer_INTERNAL unspecified error.
  159. */
  160. #define InterfaceController_bootstrapPeer_BAD_IFNUM -1
  161. #define InterfaceController_bootstrapPeer_BAD_KEY -2
  162. #define InterfaceController_bootstrapPeer_OUT_OF_SPACE -3
  163. #define InterfaceController_bootstrapPeer_INTERNAL -4
  164. int InterfaceController_bootstrapPeer(struct InterfaceController* ifc,
  165. int interfaceNumber,
  166. uint8_t* herPublicKey,
  167. const struct Sockaddr* lladdr,
  168. String* password,
  169. String* login,
  170. String* displayName,
  171. struct Allocator* alloc);
  172. #define InterfaceController_beaconState_newState_OFF 0
  173. #define InterfaceController_beaconState_newState_ACCEPT 1
  174. #define InterfaceController_beaconState_newState_SEND 2
  175. #define InterfaceController_beaconState_NO_SUCH_IFACE -1
  176. #define InterfaceController_beaconState_INVALID_STATE -2
  177. int InterfaceController_beaconState(struct InterfaceController* ifc,
  178. int interfaceNumber,
  179. int newState);
  180. /**
  181. * CryptoAuth_reset() a peer to reestablish the connection.
  182. *
  183. * @param ic the if controller
  184. * @param herPublicKey the public key of the foreign node or NULL for all peers
  185. * @return void
  186. */
  187. void InterfaceController_resetPeering(struct InterfaceController* ifController,
  188. uint8_t herPublicKey[32]);
  189. /**
  190. * Disconnect a previously registered peer.
  191. *
  192. * @param ic the if controller
  193. * @param herPublicKey the public key of the foreign node
  194. * @return 0 if all goes well.
  195. * InterfaceController_disconnectPeer_NOTFOUND if no peer with herPublicKey is found.
  196. */
  197. #define InterfaceController_disconnectPeer_NOTFOUND -1
  198. int InterfaceController_disconnectPeer(struct InterfaceController* ifc, uint8_t herPublicKey[32]);
  199. /**
  200. * Get stats for the connected peers.
  201. *
  202. * @params ic the if controller
  203. * @params alloc the Allocator to use for the peerStats array in statsOut
  204. * @params statsOut pointer to the InterfaceController_peerStats array
  205. * @return the number of InterfaceController_peerStats in statsOut
  206. */
  207. int InterfaceController_getPeerStats(struct InterfaceController* ic,
  208. struct Allocator* alloc,
  209. struct InterfaceController_PeerStats** statsOut);
  210. struct InterfaceController* InterfaceController_new(struct CryptoAuth* ca,
  211. struct SwitchCore* switchCore,
  212. struct Log* logger,
  213. struct EventBase* eventBase,
  214. struct SwitchPinger* switchPinger,
  215. struct Random* rand,
  216. struct Allocator* allocator,
  217. struct EventEmitter* ee);
  218. #endif