2013-08-23 22:29:13 +08:00
|
|
|
/* tox.c
|
|
|
|
*
|
|
|
|
* The Tox public API.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2013 Tox project All Rights Reserved.
|
|
|
|
*
|
|
|
|
* This file is part of Tox.
|
|
|
|
*
|
|
|
|
* 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/>.
|
|
|
|
*
|
|
|
|
*/
|
2015-02-16 09:20:06 +08:00
|
|
|
|
2013-09-05 18:02:26 +08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2013-08-23 22:29:13 +08:00
|
|
|
#include "Messenger.h"
|
2014-09-27 01:25:52 +08:00
|
|
|
#include "group.h"
|
2014-04-28 01:21:26 +08:00
|
|
|
#include "logger.h"
|
2013-10-02 22:38:54 +08:00
|
|
|
|
2015-02-15 12:00:12 +08:00
|
|
|
#include "../toxencryptsave/defines.h"
|
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
#define TOX_DEFINED
|
2013-10-02 22:38:54 +08:00
|
|
|
typedef struct Messenger Tox;
|
|
|
|
|
|
|
|
#include "tox.h"
|
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
#define SET_ERROR_PARAMETER(param, x) {if(param) {*param = x;}}
|
2014-09-06 09:31:35 +08:00
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
uint32_t tox_version_major(void)
|
2014-11-20 10:36:09 +08:00
|
|
|
{
|
2015-02-14 05:18:02 +08:00
|
|
|
return 0;
|
2014-11-20 10:36:09 +08:00
|
|
|
}
|
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
uint32_t tox_version_minor(void)
|
2014-10-15 07:43:54 +08:00
|
|
|
{
|
2015-02-14 05:18:02 +08:00
|
|
|
return 0;
|
2014-10-15 07:43:54 +08:00
|
|
|
}
|
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
uint32_t tox_version_patch(void)
|
2013-11-23 12:31:55 +08:00
|
|
|
{
|
2015-02-14 05:18:02 +08:00
|
|
|
return 0;
|
2013-11-23 12:31:55 +08:00
|
|
|
}
|
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
bool tox_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch)
|
2013-11-19 12:05:35 +08:00
|
|
|
{
|
2015-02-14 05:18:02 +08:00
|
|
|
//TODO
|
|
|
|
return 1;
|
2014-09-23 03:12:48 +08:00
|
|
|
}
|
|
|
|
|
2013-09-13 08:29:30 +08:00
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
void tox_options_default(struct Tox_Options *options)
|
2013-08-23 22:29:13 +08:00
|
|
|
{
|
2015-02-14 05:18:02 +08:00
|
|
|
if (options) {
|
|
|
|
memset(options, 0, sizeof(struct Tox_Options));
|
2015-02-15 12:00:12 +08:00
|
|
|
options->ipv6_enabled = 1;
|
|
|
|
options->udp_enabled = 1;
|
|
|
|
options->proxy_type = TOX_PROXY_TYPE_NONE;
|
2014-05-20 06:10:40 +08:00
|
|
|
}
|
2013-08-23 22:29:13 +08:00
|
|
|
}
|
2013-10-02 22:38:54 +08:00
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
struct Tox_Options *tox_options_new(TOX_ERR_OPTIONS_NEW *error)
|
2013-09-10 01:17:21 +08:00
|
|
|
{
|
2015-02-14 05:18:02 +08:00
|
|
|
struct Tox_Options *options = calloc(sizeof(struct Tox_Options), 1);
|
2014-09-21 22:12:55 +08:00
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
if (options) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_OK);
|
|
|
|
return options;
|
2014-09-21 00:19:21 +08:00
|
|
|
}
|
2013-08-23 22:29:13 +08:00
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_MALLOC);
|
|
|
|
return NULL;
|
2013-08-23 22:29:13 +08:00
|
|
|
}
|
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
void tox_options_free(struct Tox_Options *options)
|
2014-05-31 01:20:36 +08:00
|
|
|
{
|
2015-02-14 05:18:02 +08:00
|
|
|
free(options);
|
2014-05-31 01:20:36 +08:00
|
|
|
}
|
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
Tox *tox_new(struct Tox_Options const *options, uint8_t const *data, size_t length, TOX_ERR_NEW *error)
|
2013-09-10 02:14:24 +08:00
|
|
|
{
|
2015-02-15 12:00:12 +08:00
|
|
|
if (!logger_get_global())
|
|
|
|
logger_set_global(logger_new(LOGGER_OUTPUT_FILE, LOGGER_LEVEL, "toxcore"));
|
|
|
|
|
|
|
|
if (data) {
|
|
|
|
if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_ENCRYPTED);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Messenger_Options m_options = {0};
|
|
|
|
|
|
|
|
if (options == NULL) {
|
|
|
|
m_options.ipv6enabled = TOX_ENABLE_IPV6_DEFAULT;
|
|
|
|
} else {
|
|
|
|
m_options.ipv6enabled = options->ipv6_enabled;
|
|
|
|
m_options.udp_disabled = !options->udp_enabled;
|
|
|
|
|
|
|
|
switch (options->proxy_type) {
|
|
|
|
case TOX_PROXY_TYPE_HTTP:
|
|
|
|
m_options.proxy_info.proxy_type = TCP_PROXY_HTTP;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TOX_PROXY_TYPE_SOCKS5:
|
|
|
|
m_options.proxy_info.proxy_type = TCP_PROXY_SOCKS5;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TOX_PROXY_TYPE_NONE:
|
|
|
|
m_options.proxy_info.proxy_type = TCP_PROXY_NONE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_PROXY_TYPE);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_options.proxy_info.proxy_type != TCP_PROXY_NONE) {
|
|
|
|
if (options->proxy_port == 0) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_PORT);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ip_init(&m_options.proxy_info.ip_port.ip, m_options.ipv6enabled);
|
|
|
|
|
|
|
|
if (m_options.ipv6enabled)
|
|
|
|
m_options.proxy_info.ip_port.ip.family = AF_UNSPEC;
|
2014-08-15 06:34:20 +08:00
|
|
|
|
2015-02-15 12:00:12 +08:00
|
|
|
if (!addr_resolve_or_parse_ip(options->proxy_address, &m_options.proxy_info.ip_port.ip, NULL)) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_HOST);
|
|
|
|
//TODO: TOX_ERR_NEW_PROXY_NOT_FOUND if domain.
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_options.proxy_info.ip_port.port = htons(options->proxy_port);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Messenger *m = new_messenger(&m_options);
|
|
|
|
//TODO: TOX_ERR_NEW_MALLOC
|
|
|
|
//TODO: TOX_ERR_NEW_PORT_ALLOC
|
|
|
|
|
|
|
|
if (!new_groupchats(m)) {
|
|
|
|
kill_messenger(m);
|
2015-02-16 09:20:06 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
|
2015-02-15 12:00:12 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (messenger_load(m, data, length) == -1) {
|
|
|
|
/* TODO: uncomment this when tox is stable.
|
|
|
|
tox_kill(m);
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT);
|
|
|
|
return NULL;
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_OK);
|
|
|
|
return m;
|
2013-09-10 02:14:24 +08:00
|
|
|
}
|
2013-08-23 22:29:13 +08:00
|
|
|
|
2013-10-02 22:38:54 +08:00
|
|
|
void tox_kill(Tox *tox)
|
2013-08-23 22:29:13 +08:00
|
|
|
{
|
2015-02-15 12:00:12 +08:00
|
|
|
Messenger *m = tox;
|
|
|
|
kill_groupchats(m->group_chat_object);
|
|
|
|
kill_messenger(m);
|
|
|
|
logger_kill_global();
|
2013-08-23 22:29:13 +08:00
|
|
|
}
|
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
size_t tox_save_size(Tox const *tox)
|
2013-08-23 22:29:13 +08:00
|
|
|
{
|
2015-02-15 12:00:12 +08:00
|
|
|
const Messenger *m = tox;
|
|
|
|
return messenger_size(m);
|
2013-08-23 22:29:13 +08:00
|
|
|
}
|
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
void tox_save(Tox const *tox, uint8_t *data)
|
2013-08-23 22:29:13 +08:00
|
|
|
{
|
2015-02-15 12:00:12 +08:00
|
|
|
const Messenger *m = tox;
|
|
|
|
messenger_save(m, data);
|
2013-08-23 22:29:13 +08:00
|
|
|
}
|
2015-02-16 09:20:06 +08:00
|
|
|
|
|
|
|
static int address_to_ip(Messenger *m, char const *address, IP_Port *ip_port, IP_Port *ip_port_v4)
|
|
|
|
{
|
|
|
|
if (!addr_parse_ip(address, &ip_port->ip)) {
|
|
|
|
if (m->options.udp_disabled) { /* Disable DNS when udp is disabled. */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
IP *ip_extra = NULL;
|
|
|
|
ip_init(&ip_port->ip, m->options.ipv6enabled);
|
|
|
|
|
|
|
|
if (m->options.ipv6enabled && ip_port_v4) {
|
|
|
|
/* setup for getting BOTH: an IPv6 AND an IPv4 address */
|
|
|
|
ip_port->ip.family = AF_UNSPEC;
|
|
|
|
ip_reset(&ip_port_v4->ip);
|
|
|
|
ip_extra = &ip_port_v4->ip;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!addr_resolve(address, &ip_port->ip, ip_extra)) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool tox_bootstrap(Tox *tox, char const *address, uint16_t port, uint8_t const *public_key, TOX_ERR_BOOTSTRAP *error)
|
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
bool ret = tox_add_tcp_relay(tox, address, port, public_key, error);
|
|
|
|
|
|
|
|
if (!ret) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m->options.udp_disabled) {
|
|
|
|
return ret;
|
|
|
|
} else { /* DHT only works on UDP. */
|
|
|
|
if (DHT_bootstrap_from_address(m->dht, address, m->options.ipv6enabled, htons(port), public_key) == 0) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_ADDRESS);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_OK);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool tox_add_tcp_relay(Tox *tox, char const *address, uint16_t port, uint8_t const *public_key,
|
|
|
|
TOX_ERR_BOOTSTRAP *error)
|
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
IP_Port ip_port, ip_port_v4;
|
|
|
|
|
|
|
|
if (port == 0) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_PORT);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (address_to_ip(m, address, &ip_port, &ip_port_v4) == -1) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_ADDRESS);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
ip_port.port = htons(port);
|
|
|
|
add_tcp_relay(m->net_crypto, ip_port, public_key);
|
|
|
|
onion_add_bs_path_node(m->onion_c, ip_port, public_key); //TODO: move this
|
|
|
|
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_OK);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
TOX_CONNECTION tox_get_connection_status(Tox const *tox)
|
|
|
|
{
|
|
|
|
const Messenger *m = tox;
|
|
|
|
|
|
|
|
if (onion_isconnected(m->onion_c)) {
|
|
|
|
if (DHT_non_lan_connected(m->dht)) {
|
|
|
|
return TOX_CONNECTION_UDP;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TOX_CONNECTION_TCP;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TOX_CONNECTION_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void tox_callback_connection_status(Tox *tox, tox_connection_status_cb *function, void *user_data)
|
|
|
|
{
|
|
|
|
//TODO
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t tox_iteration_interval(Tox const *tox)
|
|
|
|
{
|
|
|
|
const Messenger *m = tox;
|
|
|
|
return messenger_run_interval(m);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tox_iteration(Tox *tox)
|
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
do_messenger(m);
|
|
|
|
do_groupchats(m->group_chat_object);
|
|
|
|
}
|
|
|
|
|