UDPInterface_admin.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  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 "exception/Jmp.h"
  18. #include "memory/Allocator.h"
  19. #include "net/InterfaceController.h"
  20. #include "util/events/EventBase.h"
  21. #include "util/events/FakeNetwork.h"
  22. #include "util/platform/Sockaddr.h"
  23. #include "crypto/Key.h"
  24. #include "interface/UDPInterface_admin.h"
  25. #include "interface/UDPInterface.h"
  26. #include "util/Identity.h"
  27. #define ArrayList_TYPE struct UDPInterface
  28. #define ArrayList_NAME UDPInterface
  29. #include "util/ArrayList.h"
  30. struct Context
  31. {
  32. struct EventBase* eventBase;
  33. struct Allocator* alloc;
  34. struct Log* logger;
  35. struct Admin* admin;
  36. struct ArrayList_UDPInterface* ifaces;
  37. struct InterfaceController* ic;
  38. struct FakeNetwork* fakeNet;
  39. struct GlobalConfig* globalConf;
  40. Identity
  41. };
  42. static struct UDPInterface* getIface(struct Context* ctx,
  43. Dict* args,
  44. String* txid,
  45. struct Allocator* requestAlloc,
  46. uint32_t* ifNumP)
  47. {
  48. int64_t* interfaceNumber = Dict_getIntC(args, "interfaceNumber");
  49. uint32_t ifNum = (interfaceNumber) ? ((uint32_t) *interfaceNumber) : 0;
  50. if (ifNumP) { *ifNumP = ifNum; }
  51. struct UDPInterface* udpif = ArrayList_UDPInterface_get(ctx->ifaces, ifNum);
  52. if (!udpif) {
  53. Dict* out = Dict_new(requestAlloc);
  54. Dict_putStringCC(out, "error", "no such interface for interfaceNumber", requestAlloc);
  55. Admin_sendMessage(out, txid, ctx->admin);
  56. }
  57. return udpif;
  58. }
  59. static void beginConnection(Dict* args,
  60. void* vcontext,
  61. String* txid,
  62. struct Allocator* requestAlloc)
  63. {
  64. struct Context* ctx = Identity_check((struct Context*) vcontext);
  65. uint32_t ifNum = 0;
  66. struct UDPInterface* udpIf = getIface(ctx, args, txid, requestAlloc, &ifNum);
  67. if (!udpIf) { return; }
  68. String* password = Dict_getStringC(args, "password");
  69. String* login = Dict_getStringC(args, "login");
  70. String* publicKey = Dict_getStringC(args, "publicKey");
  71. String* address = Dict_getStringC(args, "address");
  72. String* peerName = Dict_getStringC(args, "peerName");
  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, ctx->alloc);
  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 UDPInterface* udpIf = NULL;
  136. struct Jmp jmp;
  137. Jmp_try(jmp) {
  138. udpIf = UDPInterface_new(
  139. ctx->eventBase, addr, beaconPort, alloc, &jmp.handler, ctx->logger, ctx->globalConf);
  140. if (dscp) {
  141. if (UDPInterface_setDSCP(udpIf, dscp)) {
  142. Log_warn(ctx->logger, "Set DSCP failed");
  143. }
  144. }
  145. } Jmp_catch {
  146. Dict* out = Dict_new(alloc);
  147. Dict_putStringCC(out, "error", jmp.message, alloc);
  148. Admin_sendMessage(out, txid, ctx->admin);
  149. Allocator_free(alloc);
  150. return NULL;
  151. }
  152. return udpIf;
  153. }
  154. static void newInterface2(struct Context* ctx,
  155. struct Sockaddr* addr,
  156. uint8_t dscp,
  157. String* txid,
  158. struct Allocator* requestAlloc,
  159. uint16_t beaconPort)
  160. {
  161. struct Allocator* const alloc = Allocator_child(ctx->alloc);
  162. struct UDPInterface* udpif = setupLibuvUDP(ctx, addr, beaconPort, dscp, txid, alloc);
  163. if (!udpif) { return; }
  164. String* name = String_printf(requestAlloc, "UDP/IPv%d/%s",
  165. (Sockaddr_getFamily(addr) == Sockaddr_AF_INET ? 4 : 6),
  166. Sockaddr_print(addr, requestAlloc));
  167. struct InterfaceController_Iface* ici =
  168. InterfaceController_newIface(ctx->ic, name, alloc);
  169. Iface_plumb(&ici->addrIf, &udpif->generic.iface);
  170. ArrayList_UDPInterface_put(ctx->ifaces, ici->ifNum, udpif);
  171. Dict* out = Dict_new(requestAlloc);
  172. Dict_putStringCC(out, "error", "none", requestAlloc);
  173. Dict_putIntC(out, "interfaceNumber", ici->ifNum, requestAlloc);
  174. char* printedAddr = Sockaddr_print(udpif->generic.addr, requestAlloc);
  175. Dict_putStringCC(out,
  176. "bindAddress",
  177. printedAddr,
  178. requestAlloc);
  179. Admin_sendMessage(out, txid, ctx->admin);
  180. }
  181. static void newInterface(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
  182. {
  183. struct Context* ctx = Identity_check((struct Context*) vcontext);
  184. String* bindAddress = Dict_getStringC(args, "bindAddress");
  185. int64_t* dscpValue = Dict_getIntC(args, "dscp");
  186. uint8_t dscp = dscpValue ? ((uint8_t) *dscpValue) : 0;
  187. int64_t* beaconPort_p = Dict_getIntC(args, "beaconPort");
  188. uint16_t beaconPort = beaconPort_p ? ((uint16_t) *beaconPort_p) : 0;
  189. struct Sockaddr_storage addr;
  190. if (Sockaddr_parse((bindAddress) ? bindAddress->bytes : "0.0.0.0", &addr)) {
  191. Dict out = Dict_CONST(
  192. String_CONST("error"), String_OBJ(String_CONST("Failed to parse address")), NULL
  193. );
  194. Admin_sendMessage(&out, txid, ctx->admin);
  195. return;
  196. }
  197. newInterface2(ctx, &addr.addr, dscp, txid, requestAlloc, beaconPort);
  198. }
  199. static void listDevices(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
  200. {
  201. struct Context* ctx = Identity_check((struct Context*) vcontext);
  202. Dict* out = Dict_new(requestAlloc);
  203. struct Jmp jmp;
  204. Jmp_try(jmp) {
  205. List* list = UDPInterface_listDevices(requestAlloc, &jmp.handler);
  206. Dict_putListC(out, "ret", list, requestAlloc);
  207. } Jmp_catch {
  208. Dict_putStringCC(out, "error", jmp.message, requestAlloc);
  209. }
  210. Admin_sendMessage(out, txid, ctx->admin);
  211. }
  212. static void setBroadcastDevices(
  213. Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
  214. {
  215. struct Context* ctx = Identity_check((struct Context*) vcontext);
  216. struct UDPInterface* udpif = getIface(ctx, args, txid, requestAlloc, NULL);
  217. if (!udpif) { return; }
  218. UDPInterface_setBroadcastDevices(udpif, Dict_getListC(args, "devices"));
  219. Dict* out = Dict_new(requestAlloc);
  220. Dict_putStringCC(out, "error", "none", requestAlloc);
  221. Admin_sendMessage(out, txid, ctx->admin);
  222. }
  223. static void getBroadcastDevices(
  224. Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
  225. {
  226. struct Context* ctx = Identity_check((struct Context*) vcontext);
  227. struct UDPInterface* udpif = getIface(ctx, args, txid, requestAlloc, NULL);
  228. if (!udpif) { return; }
  229. Dict* out = Dict_new(requestAlloc);
  230. Dict_putStringCC(out, "error", "none", requestAlloc);
  231. List* devices = UDPInterface_getBroadcastDevices(udpif, requestAlloc);
  232. Dict_putListC(out, "devices", devices, requestAlloc);
  233. Admin_sendMessage(out, txid, ctx->admin);
  234. }
  235. static void getBroadcastAddrs(
  236. Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
  237. {
  238. struct Context* ctx = Identity_check((struct Context*) vcontext);
  239. struct UDPInterface* udpif = getIface(ctx, args, txid, requestAlloc, NULL);
  240. if (!udpif) { return; }
  241. Dict* out = Dict_new(requestAlloc);
  242. Dict_putStringCC(out, "error", "none", requestAlloc);
  243. List* addrs = UDPInterface_getBroadcastAddrs(udpif, requestAlloc);
  244. Dict_putListC(out, "addrs", addrs, requestAlloc);
  245. Admin_sendMessage(out, txid, ctx->admin);
  246. }
  247. static void beacon(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
  248. {
  249. int64_t* stateP = Dict_getIntC(args, "state");
  250. int64_t* ifNumP = Dict_getIntC(args, "interfaceNumber");
  251. uint32_t ifNum = (ifNumP) ? ((uint32_t) *ifNumP) : 0;
  252. uint32_t state = (stateP) ? ((uint32_t) *stateP) : 0xffffffff;
  253. struct Context* ctx = Identity_check((struct Context*) vcontext);
  254. char* error = NULL;
  255. int ret = InterfaceController_beaconState(ctx->ic, ifNum, state);
  256. if (ret == InterfaceController_beaconState_NO_SUCH_IFACE) {
  257. error = "invalid interfaceNumber";
  258. } else if (ret == InterfaceController_beaconState_INVALID_STATE) {
  259. error = "invalid state";
  260. } else if (ret) {
  261. error = "internal";
  262. }
  263. if (error) {
  264. Dict* out = Dict_new(requestAlloc);
  265. Dict_putStringCC(out, "error", error, requestAlloc);
  266. Admin_sendMessage(out, txid, ctx->admin);
  267. return;
  268. }
  269. char* stateStr = "disabled";
  270. if (state == InterfaceController_beaconState_newState_ACCEPT) {
  271. stateStr = "accepting";
  272. } else if (state == InterfaceController_beaconState_newState_SEND) {
  273. stateStr = "sending and accepting";
  274. }
  275. Dict out = Dict_CONST(
  276. String_CONST("error"), String_OBJ(String_CONST("none")), Dict_CONST(
  277. String_CONST("state"), Int_OBJ(state), Dict_CONST(
  278. String_CONST("stateName"), String_OBJ(String_CONST(stateStr)), NULL
  279. )));
  280. Admin_sendMessage(&out, txid, ctx->admin);
  281. }
  282. void UDPInterface_admin_register(struct EventBase* base,
  283. struct Allocator* alloc,
  284. struct Log* logger,
  285. struct Admin* admin,
  286. struct InterfaceController* ic,
  287. struct FakeNetwork* fakeNet,
  288. struct GlobalConfig* globalConf)
  289. {
  290. struct Context* ctx = Allocator_clone(alloc, (&(struct Context) {
  291. .eventBase = base,
  292. .alloc = alloc,
  293. .logger = logger,
  294. .admin = admin,
  295. .ic = ic,
  296. .fakeNet = fakeNet,
  297. .globalConf = globalConf
  298. }));
  299. Identity_set(ctx);
  300. ctx->ifaces = ArrayList_UDPInterface_new(alloc);
  301. Admin_registerFunction("UDPInterface_new", newInterface, ctx, true,
  302. ((struct Admin_FunctionArg[]) {
  303. { .name = "bindAddress", .required = 0, .type = "String" },
  304. { .name = "dscp", .required = 0, .type = "Int" },
  305. { .name = "beaconPort", .required = 0, .type = "Int" }
  306. }), admin);
  307. Admin_registerFunction("UDPInterface_beginConnection", beginConnection, ctx, true,
  308. ((struct Admin_FunctionArg[]) {
  309. { .name = "interfaceNumber", .required = 0, .type = "Int" },
  310. { .name = "password", .required = 0, .type = "String" },
  311. { .name = "publicKey", .required = 1, .type = "String" },
  312. { .name = "address", .required = 1, .type = "String" },
  313. { .name = "login", .required = 0, .type = "String" }
  314. }), admin);
  315. Admin_registerFunction("UDPInterface_listDevices", listDevices, ctx, true, NULL, admin);
  316. Admin_registerFunction("UDPInterface_setBroadcastDevices", setBroadcastDevices, ctx, true,
  317. ((struct Admin_FunctionArg[]) {
  318. { .name = "interfaceNumber", .required = 0, .type = "Int" },
  319. { .name = "devices", .required = 1, .type = "List" }
  320. }), admin);
  321. Admin_registerFunction("UDPInterface_getBroadcastDevices", getBroadcastDevices, ctx, true,
  322. ((struct Admin_FunctionArg[]) {
  323. { .name = "interfaceNumber", .required = 0, .type = "Int" }
  324. }), admin);
  325. Admin_registerFunction("UDPInterface_getBroadcastAddrs", getBroadcastAddrs, ctx, true,
  326. ((struct Admin_FunctionArg[]) {
  327. { .name = "interfaceNumber", .required = 0, .type = "Int" }
  328. }), admin);
  329. Admin_registerFunction("UDPInterface_beacon", beacon, ctx, true,
  330. ((struct Admin_FunctionArg[]) {
  331. { .name = "interfaceNumber", .required = 0, .type = "Int" },
  332. { .name = "state", .required = 0, .type = "Int" }
  333. }), admin);
  334. }