udht-ubus.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include <libubus.h>
  2. #include "udht.h"
  3. #include "curve25519.h"
  4. static struct ubus_auto_conn conn;
  5. static struct blob_buf b;
  6. static void
  7. udht_ubus_network_add(struct blob_attr *data, int seq)
  8. {
  9. static const struct blobmsg_policy net_policy =
  10. { "config", BLOBMSG_TYPE_TABLE };
  11. enum {
  12. CONFIG_ATTR_AUTH_KEY,
  13. CONFIG_ATTR_DHT,
  14. __CONFIG_ATTR_MAX
  15. };
  16. static const struct blobmsg_policy policy[__CONFIG_ATTR_MAX] = {
  17. [CONFIG_ATTR_AUTH_KEY] = { "auth_key", BLOBMSG_TYPE_STRING },
  18. [CONFIG_ATTR_DHT] = { "dht", BLOBMSG_TYPE_BOOL },
  19. };
  20. struct blob_attr *tb[__CONFIG_ATTR_MAX];
  21. struct blob_attr *config, *cur;
  22. uint8_t auth_key[CURVE25519_KEY_SIZE];
  23. blobmsg_parse(&net_policy, 1, &config, blobmsg_data(data), blobmsg_len(data));
  24. if (!config)
  25. return;
  26. blobmsg_parse(policy, __CONFIG_ATTR_MAX, tb, blobmsg_data(config), blobmsg_len(config));
  27. if ((cur = tb[CONFIG_ATTR_DHT]) == NULL || !blobmsg_get_u8(cur))
  28. return;
  29. if ((cur = tb[CONFIG_ATTR_AUTH_KEY]) == NULL ||
  30. (b64_decode(blobmsg_get_string(cur), auth_key, CURVE25519_KEY_SIZE) !=
  31. CURVE25519_KEY_SIZE))
  32. return;
  33. udht_network_add(auth_key, seq);
  34. }
  35. static void
  36. udht_ubus_network_cb(struct ubus_request *req, int type,
  37. struct blob_attr *msg)
  38. {
  39. static const struct blobmsg_policy policy =
  40. { "networks", BLOBMSG_TYPE_TABLE };
  41. struct blob_attr *networks, *cur;
  42. int *seq = req->priv;
  43. int rem;
  44. blobmsg_parse(&policy, 1, &networks, blobmsg_data(msg), blobmsg_len(msg));
  45. if (!networks)
  46. return;
  47. blobmsg_for_each_attr(cur, networks, rem)
  48. udht_ubus_network_add(cur, *seq);
  49. }
  50. static void
  51. udht_ubus_update_networks(struct ubus_context *ctx)
  52. {
  53. static int seq;
  54. uint32_t id;
  55. seq++;
  56. if (ubus_lookup_id(ctx, "unetd", &id) == 0)
  57. ubus_invoke(ctx, id, "network_get", b.head, udht_ubus_network_cb, &seq, 5000);
  58. udht_network_flush(seq);
  59. }
  60. static int
  61. udht_ubus_unetd_cb(struct ubus_context *ctx, struct ubus_object *obj,
  62. struct ubus_request_data *req, const char *method,
  63. struct blob_attr *msg)
  64. {
  65. udht_ubus_update_networks(ctx);
  66. return 0;
  67. }
  68. static void
  69. udht_subscribe_unetd(struct ubus_context *ctx)
  70. {
  71. static struct ubus_subscriber sub = {
  72. .cb = udht_ubus_unetd_cb
  73. };
  74. uint32_t id;
  75. if (!sub.obj.id && ubus_register_subscriber(ctx, &sub))
  76. return;
  77. if (ubus_lookup_id(ctx, "unetd", &id))
  78. return;
  79. ubus_subscribe(ctx, &sub, id);
  80. /* ensure that unetd's socket is ready by testing if it's reachable over ubus */
  81. if (ubus_invoke(ctx, id, "network_get", b.head, NULL, NULL, 10000))
  82. return;
  83. udht_reconnect();
  84. udht_ubus_update_networks(ctx);
  85. }
  86. static void
  87. udht_ubus_event_cb(struct ubus_context *ctx, struct ubus_event_handler *ev,
  88. const char *type, struct blob_attr *msg)
  89. {
  90. static const struct blobmsg_policy policy =
  91. { "path", BLOBMSG_TYPE_STRING };
  92. struct blob_attr *attr;
  93. blobmsg_parse(&policy, 1, &attr, blobmsg_data(msg), blobmsg_len(msg));
  94. if (!attr)
  95. return;
  96. if (!strcmp(blobmsg_get_string(attr), "unetd"))
  97. udht_subscribe_unetd(ctx);
  98. }
  99. static void
  100. ubus_connect_handler(struct ubus_context *ctx)
  101. {
  102. static struct ubus_event_handler ev = {
  103. .cb = udht_ubus_event_cb,
  104. };
  105. ubus_register_event_handler(ctx, &ev, "ubus.object.add");
  106. udht_subscribe_unetd(ctx);
  107. }
  108. void udht_ubus_init(void)
  109. {
  110. blob_buf_init(&b, 0);
  111. conn.cb = ubus_connect_handler;
  112. ubus_auto_connect(&conn);
  113. }