tox_bootstrap_json.c 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <errno.h>
  4. #include <string.h>
  5. #include <tox/tox.h>
  6. #include "cJSON.h"
  7. #include "log.h"
  8. #include "util.h"
  9. void do_bootstrap_file(Tox *tox, const char *json_file)
  10. {
  11. char *buffer = NULL;
  12. long length;
  13. const cJSON *node = NULL;
  14. const cJSON *nodes = NULL;
  15. const cJSON *tcp_ports = NULL;
  16. const cJSON *tcp_port = NULL;
  17. unsigned char key_bin[TOX_PUBLIC_KEY_SIZE];
  18. FILE * f = fopen(json_file, "rb");
  19. if (f) {
  20. fseek (f, 0, SEEK_END);
  21. length = ftell (f);
  22. fseek (f, 0, SEEK_SET);
  23. buffer = malloc (length);
  24. if (buffer) {
  25. fread (buffer, 1, length, f);
  26. }
  27. fclose (f);
  28. } else {
  29. log_printf(L_INFO, "Could not find Tox bootstrap nodes. Using hardcoded.\n");
  30. return;
  31. }
  32. if (!buffer) {
  33. log_printf(L_WARNING, "Could not read Tox bootstrap nodes.");
  34. return;
  35. }
  36. cJSON *nodes_json = cJSON_Parse(buffer);
  37. if (nodes_json == NULL) {
  38. const char *error_ptr = cJSON_GetErrorPtr();
  39. if (error_ptr != NULL) {
  40. log_printf(L_WARNING, "Error reading JSON before: %s\n", error_ptr);
  41. }
  42. goto end;
  43. }
  44. nodes = cJSON_GetObjectItemCaseSensitive(nodes_json, "nodes");
  45. cJSON_ArrayForEach(node, nodes) {
  46. cJSON *port = cJSON_GetObjectItemCaseSensitive(node, "port");
  47. cJSON *ipv4 = cJSON_GetObjectItemCaseSensitive(node, "ipv4");
  48. cJSON *ipv6 = cJSON_GetObjectItemCaseSensitive(node, "ipv6");
  49. cJSON *pk = cJSON_GetObjectItemCaseSensitive(node, "public_key");
  50. if (!cJSON_IsNumber(port) || !cJSON_IsString(ipv4) ||
  51. !cJSON_IsString(ipv6) || !cJSON_IsString(pk) ) {
  52. continue;
  53. }
  54. if (!is_valid_ipv4(ipv4->valuestring) && !is_valid_ipv6(ipv6->valuestring)) {
  55. log_printf(L_INFO, "Skipping \"%s:%d\" %s\n", ipv4->valuestring, port->valueint, pk->valuestring);
  56. continue;
  57. }
  58. /* Could have used sodium here, but did not want to change dependencies. Alternative is:
  59. sodium_hex2bin(key_bin, sizeof(key_bin), pk->valuestring, sizeof(pk->valuestring)-1, NULL, NULL, NULL);
  60. */
  61. hex_string_to_bin(pk->valuestring, sizeof(pk->valuestring)-1, key_bin);
  62. if(is_valid_ipv4(ipv4->valuestring))
  63. {
  64. tox_bootstrap(tox, ipv4->valuestring, port->valueint, key_bin, NULL);
  65. log_printf(L_INFO, "Bootstrapping from \"%s:%d\" %s\n", ipv4->valuestring, port->valueint, pk->valuestring);
  66. }
  67. if(is_valid_ipv6(ipv6->valuestring))
  68. {
  69. tox_bootstrap(tox, ipv6->valuestring, port->valueint, key_bin, NULL);
  70. log_printf(L_INFO, "Bootstrapping from \"%s:%d\" %s\n", ipv6->valuestring, port->valueint, pk->valuestring);
  71. }
  72. tcp_ports = cJSON_GetObjectItemCaseSensitive(node, "tcp_ports");
  73. cJSON_ArrayForEach(tcp_port, tcp_ports) {
  74. if (cJSON_IsNumber(tcp_port)) {
  75. log_printf(L_INFO, " Also adding TCP-realy %d\n", tcp_port->valueint);
  76. tox_add_tcp_relay(tox, ipv4->valuestring, tcp_port->valueint, key_bin, 0);
  77. }
  78. }
  79. }
  80. end:
  81. cJSON_Delete(nodes_json);
  82. free(buffer);
  83. }