Port of the c-toxcore Tox library
Port of the C reference implementation of the Tox chat protocol. Includes a native DHT bootstrap node, see run/tox_dht_bootstrap. https://tox.chat/
This commit is contained in:
committed by
Norman Feske
parent
a09355d77d
commit
c042419226
72
include/toxcore/toxcore/genode_logger.h
Normal file
72
include/toxcore/toxcore/genode_logger.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Text logging abstraction.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is part of Tox, the free peer to peer instant messenger.
|
||||
*
|
||||
* Tox is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TOXCORE__GENODE_LOGGER_H_
|
||||
#define _TOXCORE__GENODE_LOGGER_H_
|
||||
|
||||
|
||||
/* Libc includes */
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
|
||||
|
||||
namespace Toxcore {
|
||||
|
||||
/* Toxcore includes */
|
||||
extern "C" {
|
||||
#include "toxcore/logger.h"
|
||||
}
|
||||
|
||||
static void logger_genode_handler(void *context, Logger_Level level,
|
||||
const char *file, int line, const char *func,
|
||||
const char *message, void *userdata)
|
||||
{
|
||||
(void)context;
|
||||
(void)userdata;
|
||||
|
||||
switch (level) {
|
||||
case LOGGER_LEVEL_ERROR:
|
||||
Genode::error(file, ":", line, "(", func, "): ", message);\
|
||||
break;
|
||||
case LOGGER_LEVEL_WARNING:
|
||||
Genode::warning(file, ":", line, "(", func, "): ", message);
|
||||
break;
|
||||
default:
|
||||
Genode::log(file, ":", line, "(", func, "): ", message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Logger *new_genode_logger()
|
||||
{
|
||||
Logger *l = logger_new();
|
||||
logger_callback_log(l, logger_genode_handler, nullptr, nullptr);
|
||||
return l;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
4
lib/import/import-c-toxcore.mk
Normal file
4
lib/import/import-c-toxcore.mk
Normal file
@@ -0,0 +1,4 @@
|
||||
TOXCORE_PORT_DIR := $(call select_from_ports,c-toxcore)
|
||||
|
||||
INC_DIR += $(TOXCORE_PORT_DIR)/include
|
||||
INC_DIR += $(call select_from_repositories,include/toxcore)
|
||||
17
lib/mk/c-toxcore.mk
Normal file
17
lib/mk/c-toxcore.mk
Normal file
@@ -0,0 +1,17 @@
|
||||
include $(REP_DIR)/lib/import/import-c-toxcore.mk
|
||||
|
||||
TOXCORE_SRC_DIR = $(TOXCORE_PORT_DIR)/src/lib/c-toxcore
|
||||
|
||||
CC_C_OPT += -std=c99 -D_XOPEN_SOURCE
|
||||
|
||||
INC_DIR += $(TOXCORE_SRC_DIR)/toxcore
|
||||
|
||||
TOXCORE_SRC_C := $(notdir $(wildcard $(TOXCORE_SRC_DIR)/toxcore/*.c))
|
||||
|
||||
SRC_C += $(filter-out $(TOXCORE_SRC_FILTER),$(TOXCORE_SRC_C))
|
||||
|
||||
LIBS := libsodium libc
|
||||
|
||||
vpath %.c $(TOXCORE_SRC_DIR)/toxcore
|
||||
|
||||
SHARED_LIB = yes
|
||||
1
ports/c-toxcore.hash
Normal file
1
ports/c-toxcore.hash
Normal file
@@ -0,0 +1 @@
|
||||
a240750d0b89cfddd31bb9f79484e93fc83561a4
|
||||
13
ports/c-toxcore.port
Normal file
13
ports/c-toxcore.port
Normal file
@@ -0,0 +1,13 @@
|
||||
LICENSE := GPLv3
|
||||
VERSION := 0.2.8
|
||||
DOWNLOADS := c-toxcore.archive
|
||||
|
||||
OWNER := TokTok
|
||||
REPO := c-toxcore
|
||||
REV := 3f35a84968f100e1e6d3c9df467fd3c82a9ebb13
|
||||
URL(c-toxcore) := https://github.com/$(OWNER)/$(REPO)/archive/$(REV).tar.gz
|
||||
SHA(c-toxcore) := ff67bf686f5322c3b5a08d0562d5e6fd20e26cf9f4aebba78b948c8f365dae8e
|
||||
DIR(c-toxcore) := src/lib/c-toxcore
|
||||
|
||||
DIRS := include/toxcore
|
||||
DIR_CONTENT(include/toxcore) = src/lib/c-toxcore/toxcore/*.h
|
||||
144
run/tox_dht_bootstrap.run
Normal file
144
run/tox_dht_bootstrap.run
Normal file
@@ -0,0 +1,144 @@
|
||||
#
|
||||
# \brief Test of Tox DHT bootstrap daemon
|
||||
# \author Emery Hemingway
|
||||
#
|
||||
|
||||
if {[have_spec odroid_xu] || [have_spec linux] ||
|
||||
[expr [have_spec imx53] && [have_spec trustzone]]} {
|
||||
puts "Run script does not support this platform."
|
||||
exit 0
|
||||
}
|
||||
|
||||
set build_components {
|
||||
app/tox_dht_bootstrap
|
||||
drivers/nic
|
||||
lib/vfs/import
|
||||
lib/vfs/lwip
|
||||
server/report_rom
|
||||
}
|
||||
|
||||
proc gpio_drv { } { if {[have_spec rpi] && [have_spec hw]} { return hw_gpio_drv }
|
||||
if {[have_spec rpi] && [have_spec foc]} { return foc_gpio_drv }
|
||||
return gpio_drv }
|
||||
|
||||
lappend_if [have_spec gpio] build_components drivers/gpio
|
||||
|
||||
source ${genode_dir}/repos/base/run/platform_drv.inc
|
||||
append_platform_drv_build_components
|
||||
|
||||
lappend_if [expr {[nic_drv_binary] == "nic_drv"}] build_components drivers/nic
|
||||
lappend_if [expr {[nic_drv_binary] == "usb_drv"}] build_components drivers/usb
|
||||
|
||||
build $build_components
|
||||
|
||||
create_boot_directory
|
||||
|
||||
import_from_depot \
|
||||
genodelabs/src/[base_src] \
|
||||
genodelabs/src/init \
|
||||
|
||||
append config {
|
||||
<config>
|
||||
<parent-provides>
|
||||
<service name="CPU"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="LOG"/>
|
||||
<service name="PD"/>
|
||||
<service name="RAM"/>
|
||||
<service name="RM"/>
|
||||
<service name="ROM"/>
|
||||
</parent-provides>
|
||||
<default caps="100"/>
|
||||
<default-route>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>}
|
||||
|
||||
append_platform_drv_config
|
||||
|
||||
append_if [have_spec gpio] config "
|
||||
<start name=\"[gpio_drv]\" caps=\"140\">
|
||||
<resource name=\"RAM\" quantum=\"4M\"/>
|
||||
<provides><service name=\"Gpio\"/></provides>
|
||||
<config/>
|
||||
</start>"
|
||||
|
||||
append config {
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Timer"/> </provides>
|
||||
</start>
|
||||
<start name="nic_drv" caps="120">
|
||||
<binary name="} [nic_drv_binary] {"/>
|
||||
<resource name="RAM" quantum="16M"/>
|
||||
<provides> <service name="Nic"/> </provides>
|
||||
} [nic_drv_config] {
|
||||
</start>
|
||||
|
||||
<start name="report_rom">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<provides> <service name="Report"/> </provides>
|
||||
<config verbose="yes"/>
|
||||
</start>
|
||||
|
||||
<start name="tox_dht_bootstrap" caps="500">
|
||||
<resource name="RAM" quantum="32M"/>
|
||||
<config>
|
||||
<report dht="yes"/>
|
||||
<vfs>
|
||||
<ram/>
|
||||
<dir name="dev">
|
||||
<log/>
|
||||
<null/>
|
||||
<inline name="rtc">2000-01-01 00:00</inline>
|
||||
<inline name="random">01234567890123456789</inline>
|
||||
<inline name="urandom">01234567890123456789</inline>
|
||||
</dir>
|
||||
<dir name="socket"> <lwip dhcp="yes"/> </dir>
|
||||
</vfs>
|
||||
<libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc" socket="/socket"/>
|
||||
<bootstrap key="257744DBF57BE3E117FE05D145B5F806089428D4DCE4E3D0D50616AA16D9417E" ip="95.31.18.227"/>
|
||||
<bootstrap key="3CEE1F054081E7A011234883BC4FC39F661A55B73637A5AC293DDF1251D9432B" ip="194.249.212.109"/>
|
||||
<bootstrap key="B38255EE4B054924F6D79A5E6E5889EC94B6ADF6FE9906F97A3D01E3D083223A" ip="80.87.193.193"/>
|
||||
<bootstrap key="2555763C8C460495B14157D234DD56B86300A2395554BCAE4621AC345B8C1B1B" ip="185.14.30.213" port="443"/>
|
||||
<bootstrap key="02807CF4F8BB8FB390CC3794BDF1E8449E9A8392C5D3F2200019DA9F1E812E46" ip="78.46.73.141"/>
|
||||
<bootstrap key="8E7D0B859922EF569298B4D261A8CCB5FEA14FB91ED412A7603A585A25698832" ip="85.172.30.117"/>
|
||||
<bootstrap key="1D5A5F2F5D6233058BF0259B09622FB40B482E4FA0931EB8FD3AB8E7BF7DAF6F" ip="198.98.51.198"/>
|
||||
<bootstrap key="E59A0E71ADA20D35BD1B0957059D7EF7E7792B3D680AE25C6F4DBBA09114D165" ip="37.97.185.116"/>
|
||||
</config>
|
||||
</start>
|
||||
</config>
|
||||
}
|
||||
|
||||
install_config $config
|
||||
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
libc.lib.so
|
||||
libm.lib.so
|
||||
libsodium.lib.so
|
||||
posix.lib.so
|
||||
c-toxcore.lib.so
|
||||
tox_dht_bootstrap
|
||||
vfs.lib.so
|
||||
vfs_lwip.lib.so
|
||||
report_rom
|
||||
}
|
||||
|
||||
# platform-specific modules
|
||||
append_platform_drv_boot_modules
|
||||
|
||||
lappend boot_modules [nic_drv_binary]
|
||||
|
||||
lappend_if [have_spec gpio] boot_modules [gpio_drv]
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
append_if [have_spec x86] qemu_args " -net nic,model=e1000 "
|
||||
append_if [have_spec lan9118] qemu_args " -net nic,model=lan9118 "
|
||||
append qemu_args " -net user -net dump,file=[run_dir].pcap"
|
||||
append qemu_args " -nographic"
|
||||
|
||||
run_genode_until forever
|
||||
272
src/app/tox_dht_bootstrap/component.cc
Normal file
272
src/app/tox_dht_bootstrap/component.cc
Normal file
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* A simple DHT boostrap node for tox.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright © 2018 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of Tox, the free peer to peer instant messenger.
|
||||
*
|
||||
* Tox is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
#include "toxcore/tox.h"
|
||||
#include "toxcore/DHT.h"
|
||||
#include "toxcore/LAN_discovery.h"
|
||||
#include "toxcore/friend_requests.h"
|
||||
#include "toxcore/logger.h"
|
||||
#include "toxcore/mono_time.h"
|
||||
#include "toxcore/tox.h"
|
||||
#include "toxcore/util.h"
|
||||
}
|
||||
#include "toxcore/genode_logger.h"
|
||||
|
||||
/* Genode includes */
|
||||
#include <os/reporter.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <libc/component.h>
|
||||
|
||||
|
||||
namespace Tox_dht_bootstrap {
|
||||
|
||||
struct Main;
|
||||
|
||||
enum {
|
||||
IPV6_ENABLE = false,
|
||||
PORT = 33445
|
||||
};
|
||||
|
||||
|
||||
typedef Genode::String<65> Key_string;
|
||||
|
||||
|
||||
static bool non_zero(Client_data const &peer)
|
||||
{
|
||||
for (int i = 0; i < CRYPTO_PUBLIC_KEY_SIZE; ++i)
|
||||
if (peer.public_key[i]) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static Key_string encode_key(uint8_t const *bin)
|
||||
{
|
||||
static const char alphabet[] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
|
||||
};
|
||||
|
||||
char buf[CRYPTO_PUBLIC_KEY_SIZE*2];
|
||||
for (int i = 0; i < CRYPTO_PUBLIC_KEY_SIZE; ++i) {
|
||||
buf[(i<<1)] = alphabet[bin[i]>>4];
|
||||
buf[(i<<1)|1] = alphabet[bin[i]&0xf];
|
||||
}
|
||||
|
||||
return Key_string(Genode::Cstring(buf, CRYPTO_PUBLIC_KEY_SIZE*2));
|
||||
}
|
||||
|
||||
static uint8_t *hex_string_to_bin(const char *hex_string)
|
||||
{
|
||||
if (strlen(hex_string) % 2 != 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t len = strlen(hex_string) / 2;
|
||||
uint8_t *ret = (uint8_t *)malloc(len);
|
||||
|
||||
const char *pos = hex_string;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; ++i, pos += 2) {
|
||||
unsigned int val;
|
||||
sscanf(pos, "%02x", &val);
|
||||
ret[i] = val;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void bootstrap_from_config(DHT *dht, Genode::Xml_node const &config)
|
||||
{
|
||||
typedef Genode::String<TOX_ADDRESS_SIZE*2> Key;
|
||||
typedef Genode::String<TOX_MAX_HOSTNAME_LENGTH> Host;
|
||||
|
||||
auto const bs_fn = [&] (Genode::Xml_node const &node) {
|
||||
Key key;
|
||||
Host host;
|
||||
uint16_t port = PORT;
|
||||
|
||||
try {
|
||||
node.attribute("ip").value(&host);
|
||||
node.attribute("key").value(&key);
|
||||
port = node.attribute_value("port", port);
|
||||
}
|
||||
catch (...) {
|
||||
Genode::error("Invalid bootstrap node ", node);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *bootstrap_key = hex_string_to_bin(key.string());
|
||||
int res = dht_bootstrap_from_address(
|
||||
dht, host.string(), IPV6_ENABLE, net_htons(port), bootstrap_key);
|
||||
free(bootstrap_key);
|
||||
if (!res)
|
||||
Genode::error("Failed to connect to ", node);
|
||||
};
|
||||
|
||||
config.for_each_sub_node("bootstrap", bs_fn);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
struct Tox_dht_bootstrap::Main
|
||||
{
|
||||
Main(const Main&);
|
||||
Main &operator=(const Main&);
|
||||
|
||||
Libc::Env &_env;
|
||||
|
||||
Timer::Connection _timer { _env, "periodic-timeout" };
|
||||
|
||||
Genode::Expanding_reporter _reporter { _env, "dht_state", "dht_state" };
|
||||
|
||||
Logger *logger = Toxcore::new_genode_logger();
|
||||
|
||||
Mono_Time *_mono_time = mono_time_new();
|
||||
|
||||
uint64_t last_LANdiscovery = 0;
|
||||
|
||||
int is_waiting_for_dht_connection = 1;
|
||||
|
||||
DHT *init_dht()
|
||||
{
|
||||
/* Initialize networking -
|
||||
Bind to ip 0.0.0.0 / [::] : PORT */
|
||||
IP ip;
|
||||
ip_init(&ip, IPV6_ENABLE);
|
||||
|
||||
DHT *dht = new_dht(logger, _mono_time, new_networking(logger, ip, PORT), true);
|
||||
Onion *onion = new_onion(_mono_time, dht);
|
||||
Onion_Announce *onion_a = new_onion_announce(_mono_time, dht);
|
||||
|
||||
if (!(onion && onion_a)) {
|
||||
Genode::error("Something failed to initialize");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Genode::log("Listening on UDP port ", net_ntohs(net_port(dht_get_net(dht))));
|
||||
|
||||
_env.config([&] (Genode::Xml_node const &config) {
|
||||
bootstrap_from_config(dht, config); });
|
||||
|
||||
lan_discovery_init(dht);
|
||||
|
||||
_env.config([&] (Genode::Xml_node const &config) {
|
||||
config.for_each_sub_node("report", [&] (Genode::Xml_node const &node) {
|
||||
if (node.attribute_value("dht", false)) {
|
||||
_report_timeout.construct(_timer, *this, &Main::report, Genode::Microseconds(4*1000*1000));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return dht;
|
||||
}
|
||||
|
||||
DHT *_dht = init_dht();
|
||||
|
||||
Timer::Periodic_timeout<Main> _periodic_timeout {
|
||||
_timer, *this, &Main::run, Genode::Microseconds(1000*1000) };
|
||||
|
||||
Genode::Constructible<Timer::Periodic_timeout<Main>> _report_timeout { };
|
||||
|
||||
Main(Libc::Env &env) : _env(env) { }
|
||||
|
||||
|
||||
void report(Genode::Duration);
|
||||
void run(Genode::Duration);
|
||||
|
||||
template<typename FUNC>
|
||||
void for_each_close_peer(FUNC const &func)
|
||||
{
|
||||
for (uint32_t i = 0; i < LCLIENT_LIST; i += LCLIENT_NODES) {
|
||||
for (uint32_t j = 0; j < LCLIENT_NODES; ++j) {
|
||||
Client_data const *peer = dht_get_close_client(_dht, i+j);
|
||||
if (!non_zero(*peer)) break;
|
||||
func((Client_data const &)*peer);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Tox_dht_bootstrap::Main::report(Genode::Duration)
|
||||
{
|
||||
mono_time_update(_mono_time);
|
||||
|
||||
Libc::with_libc([&] () {
|
||||
_reporter.generate([&] (Genode::Xml_generator &gen) {
|
||||
uint64_t now = mono_time_get(_mono_time);
|
||||
gen.attribute("timestamp", now);
|
||||
gen.node("base", [&] () {
|
||||
gen.attribute("public", encode_key(dht_get_self_public_key(_dht)));
|
||||
//gen.attribute("secret", encode_key(dht_get_self_secret_key(_dht)));
|
||||
});
|
||||
|
||||
for_each_close_peer([&] (Client_data const &peer) {
|
||||
gen.node("close", [&] () {
|
||||
gen.attribute("public", encode_key(peer.public_key));
|
||||
|
||||
char ip_buf[IP_NTOA_LEN];
|
||||
ip_ntoa(&peer.assoc4.ip_port.ip, ip_buf, sizeof(ip_buf));
|
||||
gen.attribute("ip", (char const *)ip_buf);
|
||||
gen.attribute("port", peer.assoc4.ip_port.port);
|
||||
gen.attribute("timestamp", now - peer.assoc4.timestamp);
|
||||
gen.attribute("last_pinged", now - peer.assoc4.last_pinged);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void Tox_dht_bootstrap::Main::run(Genode::Duration)
|
||||
{
|
||||
Libc::with_libc([&] () {
|
||||
mono_time_update(_mono_time);
|
||||
|
||||
if (is_waiting_for_dht_connection && dht_isconnected(_dht)) {
|
||||
Genode::log("Connected to other bootstrap node successfully.\n");
|
||||
is_waiting_for_dht_connection = 0;
|
||||
}
|
||||
|
||||
do_dht(_dht);
|
||||
|
||||
if (mono_time_is_timeout(_mono_time, last_LANdiscovery, is_waiting_for_dht_connection ? 5 : LAN_DISCOVERY_INTERVAL)) {
|
||||
lan_discovery_send(net_htons(PORT), _dht);
|
||||
last_LANdiscovery = mono_time_get(_mono_time);
|
||||
}
|
||||
|
||||
networking_poll(dht_get_net(_dht), nullptr);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void Libc::Component::construct(Libc::Env &env)
|
||||
{
|
||||
Libc::with_libc([&] () {
|
||||
static Tox_dht_bootstrap::Main inst(env);
|
||||
});
|
||||
}
|
||||
7
src/app/tox_dht_bootstrap/target.mk
Normal file
7
src/app/tox_dht_bootstrap/target.mk
Normal file
@@ -0,0 +1,7 @@
|
||||
TARGET = tox_dht_bootstrap
|
||||
LIBS += c-toxcore libc
|
||||
SRC_CC += component.cc
|
||||
|
||||
TOX_PORT := $(call select_from_ports,c-toxcore)
|
||||
|
||||
INC_DIR += $(TOX_PORT)/src/lib/toxcore/other
|
||||
Reference in New Issue
Block a user