/* Add a TCP relay tied to a connection. * * return 0 on success. * return -1 on failure. */ int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, IP_Port ip_port, const uint8_t *relay_pk) { TCP_Connection_to *con_to = get_connection(tcp_c, connections_number); if (!con_to) return -1; int tcp_connections_number = find_tcp_connection_relay(tcp_c, relay_pk); if (tcp_connections_number != -1) { return add_tcp_number_relay_connection(tcp_c, connections_number, tcp_connections_number); } else { int tcp_connections_number = add_tcp_relay(tcp_c, ip_port, relay_pk); if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1) { return -1; } TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); if (!tcp_con) return -1; ++tcp_con->lock_count; return 0; } }
/* Like tox_bootstrap_from_address but for TCP relays only. * * return 0 on failure. * return 1 on success. */ int tox_add_tcp_relay(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key) { Messenger *m = tox; 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 0; IP *ip_extra = NULL; ip_init(&ip_port.ip, m->options.ipv6enabled); if (m->options.ipv6enabled) { /* 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 0; } ip_port.port = htons(port); add_tcp_relay(m->net_crypto, ip_port, public_key); onion_add_path_node(m->onion_c, ip_port, public_key); //TODO: move this return 1; }
/* Add a TCP relay to the instance. * * return 0 on success. * return -1 on failure. */ int add_tcp_relay_global(TCP_Connections *tcp_c, IP_Port ip_port, const uint8_t *relay_pk) { int tcp_connections_number = find_tcp_connection_relay(tcp_c, relay_pk); if (tcp_connections_number != -1) return -1; if (add_tcp_relay(tcp_c, ip_port, relay_pk) == -1) return -1; return 0; }
/* callback for recv TCP relay nodes. */ static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_port, const uint8_t *public_key) { Friend_Connections *fr_c = object; Friend_Conn *friend_con = get_conn(fr_c, number); if (!friend_con) return -1; if (friend_con->crypt_connection_id != -1) { return friend_add_tcp_relay(fr_c, number, ip_port, public_key); } else { return add_tcp_relay(fr_c->net_crypto, ip_port, public_key); } }
/* Add a TCP relay tied to a connection. * * return 0 on success. * return -1 on failure. */ int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, IP_Port ip_port, const uint8_t *relay_pk) { TCP_Connection_to *con_to = get_connection(tcp_c, connections_number); if (!con_to) return -1; int tcp_connections_number = find_tcp_connection_relay(tcp_c, relay_pk); if (tcp_connections_number != -1) { if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1) return -1; TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); if (!tcp_con) return -1; ++tcp_con->lock_count; if (tcp_con->status == TCP_CONN_CONNECTED) { send_tcp_relay_routing_request(tcp_c, tcp_connections_number, con_to->public_key); } return 0; } else { int tcp_connections_number = add_tcp_relay(tcp_c, ip_port, relay_pk); if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1) { return -1; } TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); if (!tcp_con) return -1; ++tcp_con->lock_count; return 0; } }
/* TODO: expose this properly. */ static int tox_add_tcp_relay(Tox *tox, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) { Messenger *m = tox; IP_Port ip_port_v64; IP *ip_extra = NULL; IP_Port ip_port_v4; ip_init(&ip_port_v64.ip, ipv6enabled); if (ipv6enabled) { /* setup for getting BOTH: an IPv6 AND an IPv4 address */ ip_port_v64.ip.family = AF_UNSPEC; ip_reset(&ip_port_v4.ip); ip_extra = &ip_port_v4.ip; } if (addr_resolve_or_parse_ip(address, &ip_port_v64.ip, ip_extra)) { ip_port_v64.port = port; add_tcp_relay(m->net_crypto, ip_port_v64, public_key); return 1; } else { return 0; } }