1
0

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