Created
May 8, 2022 11:52
-
-
Save zoff99/584e5145453281d4f3f2e05afb186969 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _GNU_SOURCE | |
#include <ctype.h> | |
#include <stdio.h> | |
#include <stdint.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <stdarg.h> | |
#include <time.h> | |
#include <dirent.h> | |
#include <sys/types.h> | |
#include <sys/time.h> | |
#include <sys/stat.h> | |
#include <sys/ioctl.h> | |
#include <unistd.h> | |
#include <getopt.h> | |
#include <fcntl.h> | |
#include <assert.h> | |
#include <errno.h> | |
#include <limits.h> | |
#include <arpa/inet.h> | |
#include <netinet/in.h> | |
#include <pthread.h> | |
#include <semaphore.h> | |
#include <signal.h> | |
#include <linux/sched.h> | |
#include <tox/tox.h> | |
#define CURRENT_LOG_LEVEL 9 // 0 -> error, 1 -> warn, 2 -> info, 9 -> debug | |
const char *log_filename = "output.log"; | |
FILE *logfile = NULL; | |
int f_online[3] = { 0, 0, 0}; | |
struct Node1 { | |
char *ip; | |
char *key; | |
uint16_t udp_port; | |
uint16_t tcp_port; | |
} nodes1[] = { | |
{ "tox.plastiras.org", "8E8B63299B3D520FB377FE5100E65E3322F7AE5B20A0ACED2981769FC5B43725", 33445, 443 }, | |
{ NULL, NULL, 0, 0 } | |
}; | |
struct Node2 { | |
char *ip; | |
char *key; | |
uint16_t udp_port; | |
uint16_t tcp_port; | |
} nodes2[] = { | |
{ "tox.verdict.gg", "1C5293AEF2114717547B39DA8EA6F1E331E5E358B35F9B6B5F19317911C5F976", 33445, 33445 }, | |
{ NULL, NULL, 0, 0 } | |
}; | |
void dbg(int level, const char *fmt, ...) | |
{ | |
char *level_and_format = NULL; | |
char *fmt_copy = NULL; | |
if (fmt == NULL) | |
{ | |
return; | |
} | |
if (strlen(fmt) < 1) | |
{ | |
return; | |
} | |
if (!logfile) | |
{ | |
return; | |
} | |
if ((level < 0) || (level > 9)) | |
{ | |
level = 0; | |
} | |
level_and_format = calloc(1, strlen(fmt) + 3 + 1); | |
if (!level_and_format) | |
{ | |
// dbg(9, stderr, "free:000a\n"); | |
return; | |
} | |
fmt_copy = level_and_format + 2; | |
strcpy(fmt_copy, fmt); | |
level_and_format[1] = ':'; | |
if (level == 0) | |
{ | |
level_and_format[0] = 'E'; | |
} | |
else if (level == 1) | |
{ | |
level_and_format[0] = 'W'; | |
} | |
else if (level == 2) | |
{ | |
level_and_format[0] = 'I'; | |
} | |
else | |
{ | |
level_and_format[0] = 'D'; | |
} | |
level_and_format[(strlen(fmt) + 2)] = '\0'; // '\0' or '\n' | |
level_and_format[(strlen(fmt) + 3)] = '\0'; | |
struct timeval tv; | |
gettimeofday(&tv, NULL); | |
time_t t3 = time(NULL); | |
struct tm tm3 = *localtime(&t3); | |
char *level_and_format_2 = calloc(1, strlen(level_and_format) + 5 + 3 + 3 + 1 + 3 + 3 + 3 + 7 + 1); | |
level_and_format_2[0] = '\0'; | |
snprintf(level_and_format_2, (strlen(level_and_format) + 5 + 3 + 3 + 1 + 3 + 3 + 3 + 7 + 1), | |
"%04d-%02d-%02d %02d:%02d:%02d.%06ld:%s", | |
tm3.tm_year + 1900, tm3.tm_mon + 1, tm3.tm_mday, | |
tm3.tm_hour, tm3.tm_min, tm3.tm_sec, tv.tv_usec, level_and_format); | |
if (level <= CURRENT_LOG_LEVEL) | |
{ | |
va_list ap; | |
va_start(ap, fmt); | |
vfprintf(logfile, level_and_format_2, ap); | |
va_end(ap); | |
} | |
// dbg(9, "free:001\n"); | |
if (level_and_format) | |
{ | |
// dbg(9, "free:001.a\n"); | |
free(level_and_format); | |
} | |
if (level_and_format_2) | |
{ | |
free(level_and_format_2); | |
} | |
// dbg(9, "free:002\n"); | |
} | |
void tox_log_cb__custom1(Tox *tox, TOX_LOG_LEVEL level, const char *file, uint32_t line, const char *func, | |
const char *message, void *user_data) | |
{ | |
dbg(9, "C-TOXCORE:1:%d:%s:%d:%s:%s\n", (int)level, file, (int)line, func, message); | |
} | |
void tox_log_cb__custom2(Tox *tox, TOX_LOG_LEVEL level, const char *file, uint32_t line, const char *func, | |
const char *message, void *user_data) | |
{ | |
dbg(9, "C-TOXCORE:2:%d:%s:%d:%s:%s\n", (int)level, file, (int)line, func, message); | |
} | |
static void hex_string_to_bin(const char *hex_string, uint8_t *output) { | |
size_t len = strlen(hex_string) / 2; | |
size_t i = len; | |
if (!output) { | |
return; | |
} | |
const char *pos = hex_string; | |
for (i = 0; i < len; ++i, pos += 2) { | |
sscanf(pos, "%2hhx", &output[i]); | |
} | |
} | |
static Tox* tox_init(int num) | |
{ | |
Tox *tox = NULL; | |
struct Tox_Options options; | |
tox_options_default(&options); | |
// ----- set options ------ | |
options.ipv6_enabled = false; | |
options.local_discovery_enabled = false; | |
options.hole_punching_enabled = true; | |
options.udp_enabled = false; | |
options.tcp_port = 0; // disable tcp relay function! | |
// ----- set options ------ | |
if (num == 1) | |
{ | |
options.log_callback = tox_log_cb__custom1; | |
} | |
else | |
{ | |
options.log_callback = tox_log_cb__custom2; | |
} | |
tox = tox_new(&options, NULL); | |
return tox; | |
} | |
static bool tox_connect(Tox *tox, int num) { | |
dbg(9, "[%d]:bootstrapping ...\n", num); | |
if (num == 1) | |
{ | |
for (int i = 0; nodes1[i].ip; i++) { | |
uint8_t *key = (uint8_t *)calloc(1, 100); | |
hex_string_to_bin(nodes1[i].key, key); | |
if (!key) { | |
return false; // Return because it will most likely fail again | |
} | |
tox_bootstrap(tox, nodes1[i].ip, nodes1[i].udp_port, key, NULL); | |
if (nodes1[i].tcp_port != 0) { | |
tox_add_tcp_relay(tox, nodes1[i].ip, nodes1[i].tcp_port, key, NULL); | |
} | |
free(key); | |
} | |
} | |
else | |
{ | |
for (int i = 0; nodes2[i].ip; i++) { | |
uint8_t *key = (uint8_t *)calloc(1, 100); | |
hex_string_to_bin(nodes2[i].key, key); | |
if (!key) { | |
return false; // Return because it will most likely fail again | |
} | |
tox_bootstrap(tox, nodes2[i].ip, nodes2[i].udp_port, key, NULL); | |
if (nodes2[i].tcp_port != 0) { | |
tox_add_tcp_relay(tox, nodes2[i].ip, nodes2[i].tcp_port, key, NULL); | |
} | |
free(key); | |
} | |
} | |
dbg(9, "[%d]:bootstrapping done.\n", num); | |
return true; | |
} | |
static void to_hex(char *out, uint8_t *in, int size) { | |
while (size--) { | |
if (*in >> 4 < 0xA) { | |
*out++ = '0' + (*in >> 4); | |
} else { | |
*out++ = 'A' + (*in >> 4) - 0xA; | |
} | |
if ((*in & 0xf) < 0xA) { | |
*out++ = '0' + (*in & 0xF); | |
} else { | |
*out++ = 'A' + (*in & 0xF) - 0xA; | |
} | |
in++; | |
} | |
} | |
static void self_connection_change_callback(Tox *tox, TOX_CONNECTION status, void *userdata) { | |
tox; | |
uint8_t* unum = (uint8_t *)userdata; | |
uint8_t num = *unum; | |
switch (status) { | |
case TOX_CONNECTION_NONE: | |
dbg(9, "[%d]:Lost connection to the Tox network.\n", num); | |
break; | |
case TOX_CONNECTION_TCP: | |
dbg(9, "[%d]:Connected using TCP.\n", num); | |
break; | |
case TOX_CONNECTION_UDP: | |
dbg(9, "[%d]:Connected using UDP.\n", num); | |
break; | |
} | |
} | |
static void friend_connection_status_callback(Tox *tox, uint32_t friend_number, Tox_Connection connection_status, | |
void *userdata) | |
{ | |
tox; | |
uint8_t* unum = (uint8_t *)userdata; | |
uint8_t num = *unum; | |
switch (connection_status) { | |
case TOX_CONNECTION_NONE: | |
dbg(9, "[%d]:Lost connection to friend %d\n", num, friend_number); | |
f_online[num] = 0; | |
break; | |
case TOX_CONNECTION_TCP: | |
dbg(9, "[%d]:Connected to friend %d using TCP\n", num, friend_number); | |
f_online[num] = 1; | |
break; | |
case TOX_CONNECTION_UDP: | |
dbg(9, "[%d]:Connected to friend %d using UDP\n", num, friend_number); | |
f_online[num] = 2; | |
break; | |
} | |
} | |
static void friend_request_callback(Tox *tox, const uint8_t *public_key, const uint8_t *message, size_t length, | |
void *userdata) { | |
tox; | |
uint8_t* unum = (uint8_t *)userdata; | |
uint8_t num = *unum; | |
TOX_ERR_FRIEND_ADD err; | |
tox_friend_add_norequest(tox, public_key, &err); | |
dbg(9, "[%d]:accepting friend request. res=%d\n", num, err); | |
} | |
static void group_invite_cb(Tox *tox, uint32_t friend_number, const uint8_t *invite_data, size_t length, | |
const uint8_t *group_name, size_t group_name_length, void *userdata) | |
{ | |
uint8_t* unum = (uint8_t *)userdata; | |
uint8_t num = *unum; | |
Tox_Err_Group_Invite_Accept error; | |
tox_group_invite_accept(tox, friend_number, invite_data, length, | |
(const uint8_t *)"tt", 2, NULL, 0, | |
&error); | |
dbg(9, "[%d]:tox_group_invite_accept:%d\n", num, error); | |
} | |
static void group_peer_join_cb(Tox *tox, uint32_t group_number, uint32_t peer_id, void *userdata) | |
{ | |
tox; | |
uint8_t* unum = (uint8_t *)userdata; | |
uint8_t num = *unum; | |
dbg(9, "[%d]:Peer %d joined group %d\n", num, peer_id, group_number); | |
} | |
static void group_self_join_cb(Tox *tox, uint32_t group_number, void *userdata) | |
{ | |
tox; | |
uint8_t* unum = (uint8_t *)userdata; | |
uint8_t num = *unum; | |
dbg(9, "[%d]:You joined group %d\n", num, group_number); | |
} | |
int main(int argc, char *argv[]) | |
{ | |
logfile = stdout; | |
// logfile = fopen(log_filename, "wb"); | |
setvbuf(logfile, NULL, _IOLBF, 0); | |
dbg(9, "--start--\n"); | |
uint8_t num1 = 1; | |
uint8_t num2 = 2; | |
f_online[1] = 0; | |
f_online[2] = 0; | |
Tox *tox1 = tox_init(1); | |
Tox *tox2 = tox_init(2); | |
uint8_t public_key_bin1[TOX_ADDRESS_SIZE]; | |
char public_key_str1[TOX_ADDRESS_SIZE * 2]; | |
tox_self_get_address(tox1, public_key_bin1); | |
to_hex(public_key_str1, public_key_bin1, TOX_ADDRESS_SIZE); | |
dbg(9, "[%d]:ID:1: %.*s\n", 1, TOX_ADDRESS_SIZE * 2, public_key_str1); | |
uint8_t public_key_bin2[TOX_ADDRESS_SIZE]; | |
char public_key_str2[TOX_ADDRESS_SIZE * 2]; | |
tox_self_get_address(tox2, public_key_bin2); | |
to_hex(public_key_str2, public_key_bin2, TOX_ADDRESS_SIZE); | |
dbg(9, "[%d]:ID:2: %.*s\n", 2, TOX_ADDRESS_SIZE * 2, public_key_str2); | |
tox_connect(tox1, 1); | |
tox_connect(tox2, 2); | |
tox_iterate(tox1, (void *)&num1); | |
tox_iterate(tox2, (void *)&num2); | |
Tox_Err_Friend_Add err1; | |
tox_friend_add(tox1, public_key_bin2, "1", 1, &err1); | |
dbg(9, "[%d]:add friend res=%d\n", 1, err1); | |
// Tox_Err_Friend_Add err2; | |
// tox_friend_add(tox2, public_key_bin1, "2", 1, &err2); | |
// dbg(9, "[%d]:add friend res=%d\n", 2, err2); | |
tox_callback_self_connection_status(tox1, self_connection_change_callback); | |
tox_callback_friend_connection_status(tox1, friend_connection_status_callback); | |
tox_callback_friend_request(tox1, friend_request_callback); | |
tox_callback_group_invite(tox1, group_invite_cb); | |
tox_callback_group_peer_join(tox1, group_peer_join_cb); | |
tox_callback_group_self_join(tox1, group_self_join_cb); | |
/* | |
tox_callback_friend_message(tox1, friend_message_callback); | |
tox_callback_group_message(tox1, group_message_callback); | |
tox_callback_group_peer_exit(tox1, group_peer_exit_cb); | |
tox_callback_group_join_fail(tox1, group_join_fail_cb); | |
*/ | |
tox_callback_self_connection_status(tox2, self_connection_change_callback); | |
tox_callback_friend_connection_status(tox2, friend_connection_status_callback); | |
tox_callback_friend_request(tox2, friend_request_callback); | |
tox_callback_group_invite(tox2, group_invite_cb); | |
tox_callback_group_peer_join(tox2, group_peer_join_cb); | |
tox_callback_group_self_join(tox2, group_self_join_cb); | |
/* | |
tox_callback_friend_message(tox2, friend_message_callback); | |
tox_callback_group_message(tox2, group_message_callback); | |
tox_callback_group_peer_exit(tox2, group_peer_exit_cb); | |
tox_callback_group_join_fail(tox2, group_join_fail_cb); | |
*/ | |
while (1 == 1) { | |
tox_iterate(tox1, (void *)&num1); | |
usleep(tox_iteration_interval(tox1)); | |
tox_iterate(tox2, (void *)&num2); | |
usleep(tox_iteration_interval(tox2)); | |
if ((f_online[1] > 0) && (f_online[2] > 0)) | |
{ | |
break; | |
} | |
} | |
dbg(9, "[%d]:friends online\n", 0); | |
// tox1 creates a new private group | |
Tox_Err_Group_New err_g1; | |
tox_group_new(tox1, TOX_GROUP_PRIVACY_STATE_PRIVATE, (const uint8_t *)"g1", 2, (const uint8_t *)"peer1", 4, &err_g1); | |
dbg(9, "[%d]:created group res=%d\n", 1, err_g1); | |
for (int i=0;i<100;i++) { | |
tox_iterate(tox1, (void *)&num1); | |
usleep(tox_iteration_interval(tox1)); | |
tox_iterate(tox2, (void *)&num2); | |
usleep(tox_iteration_interval(tox2)); | |
} | |
// tox1 invites tox2 to the new private group | |
Tox_Err_Group_Invite_Friend err_g2; | |
tox_group_invite_friend(tox1, 0, 0, &err_g2); | |
dbg(9, "[%d]:invited friend to group res=%d\n", 1, err_g1); | |
while (1 == 1) { | |
tox_iterate(tox1, (void *)&num1); | |
usleep(tox_iteration_interval(tox1)); | |
tox_iterate(tox2, (void *)&num2); | |
usleep(tox_iteration_interval(tox2)); | |
} | |
fclose(logfile); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment