UDPInterface_admin.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  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. #include "benc/Int.h"
  16. #include "admin/Admin.h"
  17. #include "memory/Allocator.h"
  18. #include "net/InterfaceController.h"
  19. #include "util/events/EventBase.h"
  20. #include "util/platform/Sockaddr.h"
  21. #include "crypto/Key.h"
  22. #include "interface/UDPInterface_admin.h"
  23. #include "interface/UDPInterface.h"
  24. #include "util/Identity.h"
  25. #define ArrayList_TYPE struct UDPInterface
  26. #define ArrayList_NAME UDPInterface
  27. #include "util/ArrayList.h"
  28. struct Context
  29. {
  30. struct EventBase* eventBase;
  31. struct Allocator* alloc;
  32. struct Log* logger;
  33. struct Admin* admin;
  34. struct ArrayList_UDPInterface* ifaces;
  35. struct InterfaceController* ic;
  36. struct GlobalConfig* globalConf;
  37. Identity
  38. };
  39. static struct UDPInterface* getIface(struct Context* ctx,
  40. Dict* args,
  41. String* txid,
  42. struct Allocator* requestAlloc,
  43. uint32_t* ifNumP)
  44. {
  45. int64_t* interfaceNumber = Dict_getIntC(args, "interfaceNumber");
  46. uint32_t ifNum = (interfaceNumber) ? ((uint32_t) *interfaceNumber) : 0;
  47. if (ifNumP) { *ifNumP = ifNum; }
  48. struct UDPInterface* udpif = ArrayList_UDPInterface_get(ctx->ifaces, ifNum);
  49. if (!udpif) {
  50. Dict* out = Dict_new(requestAlloc);
  51. Dict_putStringCC(out, "error", "no such interface for interfaceNumber", requestAlloc);
  52. Admin_sendMessage(out, txid, ctx->admin);
  53. }
  54. return udpif;
  55. }
  56. static void beginConnection(Dict* args,
  57. void* vcontext,
  58. String* txid,
  59. struct Allocator* requestAlloc)
  60. {
  61. struct Context* ctx = Identity_check((struct Context*) vcontext);
  62. uint32_t ifNum = 0;
  63. struct UDPInterface* udpIf = getIface(ctx, args, txid, requestAlloc, &ifNum);
  64. if (!udpIf) { return; }
  65. String* password = Dict_getStringC(args, "password");
  66. String* login = Dict_getStringC(args, "login");
  67. String* publicKey = Dict_getStringC(args, "publicKey");
  68. String* address = Dict_getStringC(args, "address");
  69. String* peerName = Dict_getStringC(args, "peerName");
  70. int64_t* versionP = Dict_getIntC(args, "version");
  71. int version = Version_DEFAULT_ASSUMPTION;
  72. if (versionP) { version = *versionP; }
  73. char* error = NULL;
  74. Log_debug(ctx->logger, "Peering with [%s]", publicKey->bytes);
  75. struct Sockaddr_storage ss;
  76. uint8_t pkBytes[32];
  77. int ret;
  78. if ((ret = Key_parse(publicKey, pkBytes, NULL))) {
  79. error = Key_parse_strerror(ret);
  80. } else if (Sockaddr_parse(address->bytes, &ss)) {
  81. error = "unable to parse ip address and port.";
  82. } else if (Sockaddr_getFamily(&ss.addr) != Sockaddr_getFamily(udpIf->generic.addr)) {
  83. error = "different address type than this socket is bound to.";
  84. } else {
  85. struct Sockaddr* addr = &ss.addr;
  86. char* addrPtr = NULL;
  87. int addrLen = Sockaddr_getAddress(&ss.addr, &addrPtr);
  88. Assert_true(addrLen > 0);
  89. struct Allocator* tempAlloc = Allocator_child(ctx->alloc);
  90. if (Bits_isZero(addrPtr, addrLen)) {
  91. // unspec'd address, convert to loopback
  92. if (Sockaddr_getFamily(addr) == Sockaddr_AF_INET) {
  93. addr = Sockaddr_clone(Sockaddr_LOOPBACK, tempAlloc);
  94. } else if (Sockaddr_getFamily(addr) == Sockaddr_AF_INET6) {
  95. addr = Sockaddr_clone(Sockaddr_LOOPBACK6, tempAlloc);
  96. } else {
  97. Assert_failure("Sockaddr which is not AF_INET nor AF_INET6");
  98. }
  99. Sockaddr_setPort(addr, Sockaddr_getPort(&ss.addr));
  100. }
  101. int ret = InterfaceController_bootstrapPeer(
  102. ctx->ic, ifNum, pkBytes, addr, password, login, peerName, version);
  103. Allocator_free(tempAlloc);
  104. if (ret) {
  105. switch(ret) {
  106. case InterfaceController_bootstrapPeer_BAD_IFNUM:
  107. // Should never happen, should be caught in getIface()
  108. error = "interface deregistered";
  109. break;
  110. case InterfaceController_bootstrapPeer_BAD_KEY:
  111. error = "invalid cjdns public key.";
  112. break;
  113. case InterfaceController_bootstrapPeer_OUT_OF_SPACE:
  114. error = "no more space to register with the switch.";
  115. break;
  116. default:
  117. error = "unknown error";
  118. break;
  119. }
  120. } else {
  121. error = "none";
  122. }
  123. }
  124. Dict* out = Dict_new(requestAlloc);
  125. Dict_putStringCC(out, "error", error, requestAlloc);
  126. Admin_sendMessage(out, txid, ctx->admin);
  127. }
  128. static struct UDPInterface* setupLibuvUDP(struct Context* ctx,
  129. struct Sockaddr* addr,
  130. uint16_t beaconPort,
  131. uint8_t dscp,
  132. String* txid,
  133. struct Allocator* alloc)
  134. {
  135. struct Er_Ret* er = NULL;
  136. struct UDPInterface* udpIf = Er_check(&er, UDPInterface_new(
  137. ctx->eventBase, addr, beaconPort, alloc, ctx->logger, ctx->globalConf));
  138. if (er) {
  139. Dict* out = Dict_new(alloc);
  140. Dict_putStringCC(out, "error", er->message, alloc);
  141. Admin_sendMessage(out, txid, ctx->admin);
  142. Allocator_free(alloc);
  143. return NULL;
  144. } else if (dscp) {
  145. if (UDPInterface_setDSCP(udpIf, dscp)) {
  146. Log_warn(ctx->logger, "Set DSCP failed");
  147. }
  148. }
  149. return udpIf;
  150. }
  151. static void newInterface2(struct Context* ctx,
  152. struct Sockaddr* addr,
  153. uint8_t dscp,
  154. String* txid,
  155. struct Allocator* requestAlloc,
  156. uint16_t beaconPort)
  157. {
  158. struct Allocator* const alloc = Allocator_child(ctx->alloc);
  159. struct UDPInterface* udpif = setupLibuvUDP(ctx, addr, beaconPort, dscp, txid, alloc);
  160. if (!udpif) { return; }
  161. String* name = String_printf(requestAlloc, "UDP/IPv%d/%s",
  162. (Sockaddr_getFamily(addr) == Sockaddr_AF_INET ? 4 : 6),
  163. Sockaddr_print(addr, requestAlloc));
  164. struct InterfaceController_Iface* ici =
  165. InterfaceController_newIface(ctx->ic, name, alloc);
  166. Iface_plumb(&ici->addrIf, udpif->generic.iface);
  167. ArrayList_UDPInterface_put(ctx->ifaces, ici->ifNum, udpif);
  168. Dict* out = Dict_new(requestAlloc);
  169. Dict_putStringCC(out, "error", "none", requestAlloc);
  170. Dict_putIntC(out, "interfaceNumber", ici->ifNum, requestAlloc);
  171. char* printedAddr = Sockaddr_print(udpif->generic.addr, requestAlloc);
  172. Dict_putStringCC(out,
  173. "bindAddress",
  174. printedAddr,
  175. requestAlloc);
  176. Admin_sendMessage(out, txid, ctx->admin);
  177. }
  178. static void newInterface(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
  179. {
  180. struct Context* ctx = Identity_check((struct Context*) vcontext);
  181. String* bindAddress = Dict_getStringC(args, "bindAddress");
  182. int64_t* dscpValue = Dict_getIntC(args, "dscp");
  183. uint8_t dscp = dscpValue ? ((uint8_t) *dscpValue) : 0;
  184. int64_t* beaconPort_p = Dict_getIntC(args, "beaconPort");
  185. uint16_t beaconPort = beaconPort_p ? ((uint16_t) *beaconPort_p) : 0;
  186. struct Sockaddr_storage addr;
  187. if (Sockaddr_parse((bindAddress) ? bindAddress->bytes : "0.0.0.0", &addr)) {
  188. Dict out = Dict_CONST(
  189. String_CONST("error"), String_OBJ(String_CONST("Failed to parse address")), NULL
  190. );
  191. Admin_sendMessage(&out, txid, ctx->admin);
  192. return;
  193. }
  194. newInterface2(ctx, &addr.addr, dscp, txid, requestAlloc, beaconPort);
  195. }
  196. static void listDevices(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
  197. {
  198. struct Context* ctx = Identity_check((struct Context*) vcontext);
  199. Dict* out = Dict_new(requestAlloc);
  200. struct Er_Ret* er = NULL;
  201. List* list = Er_check(&er, UDPInterface_listDevices(requestAlloc));
  202. if (er) {
  203. Dict_putStringCC(out, "error", er->message, requestAlloc);
  204. } else {
  205. Dict_putListC(out, "ret", list, requestAlloc);
  206. }
  207. Admin_sendMessage(out, txid, ctx->admin);
  208. }
  209. static void setBroadcastDevices(
  210. Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
  211. {
  212. struct Context* ctx = Identity_check((struct Context*) vcontext);
  213. struct UDPInterface* udpif = getIface(ctx, args, txid, requestAlloc, NULL);
  214. if (!udpif) { return; }
  215. UDPInterface_setBroadcastDevices(udpif, Dict_getListC(args, "devices"));
  216. Dict* out = Dict_new(requestAlloc);
  217. Dict_putStringCC(out, "error", "none", requestAlloc);
  218. Admin_sendMessage(out, txid, ctx->admin);
  219. }
  220. static void getBroadcastDevices(
  221. Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
  222. {
  223. struct Context* ctx = Identity_check((struct Context*) vcontext);
  224. struct UDPInterface* udpif = getIface(ctx, args, txid, requestAlloc, NULL);
  225. if (!udpif) { return; }
  226. Dict* out = Dict_new(requestAlloc);
  227. Dict_putStringCC(out, "error", "none", requestAlloc);
  228. List* devices = UDPInterface_getBroadcastDevices(udpif, requestAlloc);
  229. Dict_putListC(out, "devices", devices, requestAlloc);
  230. Admin_sendMessage(out, txid, ctx->admin);
  231. }
  232. static void getBroadcastAddrs(
  233. Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
  234. {
  235. struct Context* ctx = Identity_check((struct Context*) vcontext);
  236. struct UDPInterface* udpif = getIface(ctx, args, txid, requestAlloc, NULL);
  237. if (!udpif) { return; }
  238. Dict* out = Dict_new(requestAlloc);
  239. Dict_putStringCC(out, "error", "none", requestAlloc);
  240. List* addrs = UDPInterface_getBroadcastAddrs(udpif, requestAlloc);
  241. Dict_putListC(out, "addrs", addrs, requestAlloc);
  242. Admin_sendMessage(out, txid, ctx->admin);
  243. }
  244. static void beacon(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
  245. {
  246. int64_t* stateP = Dict_getIntC(args, "state");
  247. int64_t* ifNumP = Dict_getIntC(args, "interfaceNumber");
  248. uint32_t ifNum = (ifNumP) ? ((uint32_t) *ifNumP) : 0;
  249. uint32_t state = (stateP) ? ((uint32_t) *stateP) : 0xffffffff;
  250. struct Context* ctx = Identity_check((struct Context*) vcontext);
  251. char* error = NULL;
  252. int ret = InterfaceController_beaconState(ctx->ic, ifNum, state);
  253. if (ret == InterfaceController_beaconState_NO_SUCH_IFACE) {
  254. error = "invalid interfaceNumber";
  255. } else if (ret == InterfaceController_beaconState_INVALID_STATE) {
  256. error = "invalid state";
  257. } else if (ret) {
  258. error = "internal";
  259. }
  260. if (error) {
  261. Dict* out = Dict_new(requestAlloc);
  262. Dict_putStringCC(out, "error", error, requestAlloc);
  263. Admin_sendMessage(out, txid, ctx->admin);
  264. return;
  265. }
  266. char* stateStr = "disabled";
  267. if (state == InterfaceController_beaconState_newState_ACCEPT) {
  268. stateStr = "accepting";
  269. } else if (state == InterfaceController_beaconState_newState_SEND) {
  270. stateStr = "sending and accepting";
  271. }
  272. Dict out = Dict_CONST(
  273. String_CONST("error"), String_OBJ(String_CONST("none")), Dict_CONST(
  274. String_CONST("state"), Int_OBJ(state), Dict_CONST(
  275. String_CONST("stateName"), String_OBJ(String_CONST(stateStr)), NULL
  276. )));
  277. Admin_sendMessage(&out, txid, ctx->admin);
  278. }
  279. static void getFd(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
  280. {
  281. struct Context* ctx = Identity_check((struct Context*) vcontext);
  282. struct UDPInterface* udpif = getIface(ctx, args, txid, requestAlloc, NULL);
  283. if (!udpif) {
  284. return;
  285. }
  286. int fd = UDPInterface_getFd(udpif);
  287. Dict* out = Dict_new(requestAlloc);
  288. Dict_putIntC(out, "fd", fd, requestAlloc);
  289. Dict_putStringCC(out, "error", "none", requestAlloc);
  290. Admin_sendMessage(out, txid, ctx->admin);
  291. }
  292. void UDPInterface_admin_register(struct EventBase* base,
  293. struct Allocator* alloc,
  294. struct Log* logger,
  295. struct Admin* admin,
  296. struct InterfaceController* ic,
  297. struct GlobalConfig* globalConf)
  298. {
  299. struct Context* ctx = Allocator_clone(alloc, (&(struct Context) {
  300. .eventBase = base,
  301. .alloc = alloc,
  302. .logger = logger,
  303. .admin = admin,
  304. .ic = ic,
  305. .globalConf = globalConf
  306. }));
  307. Identity_set(ctx);
  308. ctx->ifaces = ArrayList_UDPInterface_new(alloc);
  309. Admin_registerFunction("UDPInterface_new", newInterface, ctx, true,
  310. ((struct Admin_FunctionArg[]) {
  311. { .name = "bindAddress", .required = 0, .type = "String" },
  312. { .name = "dscp", .required = 0, .type = "Int" },
  313. { .name = "beaconPort", .required = 0, .type = "Int" }
  314. }), admin);
  315. Admin_registerFunction("UDPInterface_beginConnection", beginConnection, ctx, true,
  316. ((struct Admin_FunctionArg[]) {
  317. { .name = "interfaceNumber", .required = 0, .type = "Int" },
  318. { .name = "password", .required = 0, .type = "String" },
  319. { .name = "publicKey", .required = 1, .type = "String" },
  320. { .name = "address", .required = 1, .type = "String" },
  321. { .name = "login", .required = 0, .type = "String" },
  322. { .name = "peerName", .required = 0, .type = "String" },
  323. { .name = "version", .required = 0, .type = "Int" },
  324. }), admin);
  325. Admin_registerFunction("UDPInterface_listDevices", listDevices, ctx, true, NULL, admin);
  326. Admin_registerFunction("UDPInterface_setBroadcastDevices", setBroadcastDevices, ctx, true,
  327. ((struct Admin_FunctionArg[]) {
  328. { .name = "interfaceNumber", .required = 0, .type = "Int" },
  329. { .name = "devices", .required = 1, .type = "List" }
  330. }), admin);
  331. Admin_registerFunction("UDPInterface_getBroadcastDevices", getBroadcastDevices, ctx, true,
  332. ((struct Admin_FunctionArg[]) {
  333. { .name = "interfaceNumber", .required = 0, .type = "Int" }
  334. }), admin);
  335. Admin_registerFunction("UDPInterface_getBroadcastAddrs", getBroadcastAddrs, ctx, true,
  336. ((struct Admin_FunctionArg[]) {
  337. { .name = "interfaceNumber", .required = 0, .type = "Int" }
  338. }), admin);
  339. Admin_registerFunction("UDPInterface_beacon", beacon, ctx, true,
  340. ((struct Admin_FunctionArg[]) {
  341. { .name = "interfaceNumber", .required = 0, .type = "Int" },
  342. { .name = "state", .required = 0, .type = "Int" }
  343. }), admin);
  344. Admin_registerFunction("UDPInterface_getFd", getFd, ctx, true,
  345. ((struct Admin_FunctionArg[]) {
  346. { .name = "interfaceNumber", .required = 0, .type = "Int" },
  347. }), admin);
  348. }