UDPInterface_admin.c 15 KB

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