Some refactoring of proxy code

This commit is contained in:
Maxim Biro 2014-12-21 19:59:00 -05:00
parent 377da127a1
commit e9bf38499e
8 changed files with 132 additions and 55 deletions

View File

@ -1595,11 +1595,7 @@ Messenger *new_messenger(Messenger_Options *options)
return NULL;
}
if (options->proxy_enabled) {
m->net_crypto = new_net_crypto(m->dht, &options->proxy_info);
} else {
m->net_crypto = new_net_crypto(m->dht, 0);
}
if (m->net_crypto == NULL) {
kill_networking(m->net);

View File

@ -75,7 +75,6 @@
typedef struct {
uint8_t ipv6enabled;
uint8_t udp_disabled;
uint8_t proxy_enabled;
TCP_Proxy_Info proxy_info;
} Messenger_Options;

View File

@ -37,8 +37,16 @@
*/
static int connect_sock_to(sock_t sock, IP_Port ip_port, TCP_Proxy_Info *proxy_info)
{
if (proxy_info)
ip_port = proxy_info->ip_port;
switch (proxy_info->proxy_type) {
case TCP_PROXY_HTTP:
ip_port = ((TCP_Proxy_HTTP*)proxy_info->proxy)->ip_port;
break;
case TCP_PROXY_SOCKS5:
ip_port = ((TCP_Proxy_SOCKS5*)proxy_info->proxy)->ip_port;
break;
case TCP_PROXY_NONE:
break;
}
struct sockaddr_storage addr = {0};
size_t addrsize;
@ -80,7 +88,7 @@ static int proxy_http_generate_connection_request(TCP_Client_Connection *TCP_con
return 0;
}
const uint16_t port = ntohs(TCP_conn->ip_port.port);
const int written = sprintf(TCP_conn->last_packet, "%s%s:%hu%s%s:%hu%s", one, ip, port, two, ip, port, three);
const int written = snprintf(TCP_conn->last_packet, MAX_PACKET_SIZE, "%s%s:%hu%s%s:%hu%s", one, ip, port, two, ip, port, three);
if (written < 0) {
return 0;
}
@ -605,8 +613,16 @@ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, const uint8_t *public
uint8_t family = ip_port.ip.family;
if (proxy_info)
family = proxy_info->ip_port.ip.family;
switch (proxy_info->proxy_type) {
case TCP_PROXY_HTTP:
family = ((TCP_Proxy_HTTP*)proxy_info->proxy)->ip_port.ip.family;
break;
case TCP_PROXY_SOCKS5:
family = ((TCP_Proxy_SOCKS5*)proxy_info->proxy)->ip_port.ip.family;
break;
case TCP_PROXY_NONE:
break;
}
sock_t sock = socket(family, SOCK_STREAM, IPPROTO_TCP);
@ -636,16 +652,18 @@ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, const uint8_t *public
memcpy(temp->self_public_key, self_public_key, crypto_box_PUBLICKEYBYTES);
encrypt_precompute(temp->public_key, self_secret_key, temp->shared_key);
temp->ip_port = ip_port;
temp->proxy_info = *proxy_info;
if (proxy_info && proxy_info->is_http) {
switch (proxy_info->proxy_type) {
case TCP_PROXY_HTTP:
temp->status = TCP_CLIENT_PROXY_HTTP_CONNECTING;
temp->proxy_info = *proxy_info;
proxy_http_generate_connection_request(temp);
} else if (proxy_info && !proxy_info->is_http) {
break;
case TCP_PROXY_SOCKS5:
temp->status = TCP_CLIENT_PROXY_SOCKS5_CONNECTING;
temp->proxy_info = *proxy_info;
proxy_socks5_generate_handshake(temp);
} else {
break;
case TCP_PROXY_NONE:
temp->status = TCP_CLIENT_CONNECTING;
if (generate_handshake(temp) == -1) {
@ -653,6 +671,7 @@ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, const uint8_t *public
free(temp);
return NULL;
}
break;
}
temp->kill_at = unix_time() + TCP_CONNECTION_TIMEOUT;

View File

@ -29,9 +29,25 @@
#define TCP_CONNECTION_TIMEOUT 10
typedef enum {
TCP_PROXY_NONE,
TCP_PROXY_HTTP,
TCP_PROXY_SOCKS5
} TCP_PROXY_TYPE;
typedef struct {
IP_Port ip_port;
int is_http; /* HTTP proxy on true, SOCKS5 on false */
} TCP_Proxy_HTTP;
typedef struct {
IP_Port ip_port;
} TCP_Proxy_SOCKS5;
typedef struct {
uint8_t proxy_type; // a value from TCP_PROXY_TYPE
void* proxy; // pointer to the corresponding proxy type struct
} TCP_Proxy_Info;
enum {

View File

@ -1999,13 +1999,8 @@ int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key)
for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
if (c->tcp_connections_new[i] == NULL) {
if (c->proxy_set) {
c->tcp_connections_new[i] = new_TCP_connection(ip_port, public_key, c->dht->self_public_key, c->dht->self_secret_key,
&c->proxy_info);
} else {
c->tcp_connections_new[i] = new_TCP_connection(ip_port, public_key, c->dht->self_public_key, c->dht->self_secret_key,
0);
}
return 0;
}
@ -2738,10 +2733,7 @@ Net_Crypto *new_net_crypto(DHT *dht, TCP_Proxy_Info *proxy_info)
bs_list_init(&temp->ip_port_list, sizeof(IP_Port), 8);
if (proxy_info) {
temp->proxy_info = *proxy_info;
temp->proxy_set = 1;
}
return temp;
}

View File

@ -213,7 +213,6 @@ typedef struct {
int (*tcp_onion_callback)(void *object, const uint8_t *data, uint16_t length);
void *tcp_onion_callback_object;
uint8_t proxy_set;
TCP_Proxy_Info proxy_info;
} Net_Crypto;

View File

@ -1020,19 +1020,63 @@ Tox *tox_new(Tox_Options *options)
} else {
m_options.ipv6enabled = options->ipv6enabled;
m_options.udp_disabled = options->udp_disabled;
m_options.proxy_enabled = options->proxy_enabled;
m_options.proxy_info.is_http = options->proxy_is_http;
if (m_options.proxy_enabled) {
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;
if (!addr_resolve_or_parse_ip(options->proxy_address, &m_options.proxy_info.ip_port.ip, NULL))
switch (options->proxy_type) {
case TOX_PROXY_HTTP: {
m_options.proxy_info.proxy_type = TCP_PROXY_HTTP;
m_options.proxy_info.proxy = malloc(sizeof(TCP_Proxy_HTTP));
if (!m_options.proxy_info.proxy) {
return NULL;
}
m_options.proxy_info.ip_port.port = htons(options->proxy_port);
TCP_Proxy_HTTP* m_proxy = (TCP_Proxy_HTTP*)m_options.proxy_info.proxy;
Tox_Proxy_HTTP* tox_proxy = (Tox_Proxy_HTTP*)options->proxy;
ip_init(&m_proxy->ip_port.ip, m_options.ipv6enabled);
if (m_options.ipv6enabled) {
m_proxy->ip_port.ip.family = AF_UNSPEC;
}
if (!addr_resolve_or_parse_ip(tox_proxy->address, &m_proxy->ip_port.ip, NULL)) {
return NULL;
}
m_proxy->ip_port.port = htons(tox_proxy->port);
break;
}
case TOX_PROXY_SOCKS5: {
m_options.proxy_info.proxy_type = TCP_PROXY_SOCKS5;
m_options.proxy_info.proxy = malloc(sizeof(TCP_Proxy_SOCKS5));
if (!m_options.proxy_info.proxy) {
return NULL;
}
TCP_Proxy_SOCKS5* m_proxy = (TCP_Proxy_SOCKS5*)m_options.proxy_info.proxy;
Tox_Proxy_SOCKS5* tox_proxy = (Tox_Proxy_SOCKS5*)options->proxy;
ip_init(&m_proxy->ip_port.ip, m_options.ipv6enabled);
if (m_options.ipv6enabled) {
m_proxy->ip_port.ip.family = AF_UNSPEC;
}
if (!addr_resolve_or_parse_ip(tox_proxy->address, &m_proxy->ip_port.ip, NULL)) {
return NULL;
}
m_proxy->ip_port.port = htons(tox_proxy->port);
break;
}
case TOX_PROXY_NONE: {
m_options.proxy_info.proxy_type = TCP_PROXY_NONE;
break;
}
}
}

View File

@ -873,6 +873,22 @@ int tox_add_tcp_relay(Tox *tox, const char *address, uint16_t port, const uint8_
*/
int tox_isconnected(const Tox *tox);
typedef enum {
TOX_PROXY_NONE,
TOX_PROXY_HTTP,
TOX_PROXY_SOCKS5
} TOX_PROXY_TYPE;
typedef struct {
char address[256]; /* Proxy ip or domain in NULL terminated string format. */
uint16_t port; /* Proxy port: in host byte order. */
} Tox_Proxy_HTTP;
typedef struct {
char address[256]; /* Proxy ip or domain in NULL terminated string format. */
uint16_t port; /* Proxy port: in host byte order. */
} Tox_Proxy_SOCKS5;
typedef struct {
/*
* The type of UDP socket created depends on ipv6enabled:
@ -885,14 +901,10 @@ typedef struct {
/* Set to 1 to disable udp support. (default: 0)
This will force Tox to use TCP only which may slow things down.
Disabling udp support is necessary when using anonymous proxies or Tor.*/
Disabling udp support is necessary when using proxies or Tor.*/
uint8_t udp_disabled;
/* Enable proxy support. (only basic TCP socks5 proxy currently supported.) (default: 0 (disabled))*/
uint8_t proxy_enabled;
char proxy_address[256]; /* Proxy ip or domain in NULL terminated string format. */
uint16_t proxy_port; /* Proxy port: in host byte order. */
uint8_t proxy_is_http; /*1: HTTP proxy, 0: SOCKS5 proxy*/
uint8_t proxy_type; // a value from TOX_PROXY_TYPE
void* proxy; // pointer to the corresponding proxy type struct
} Tox_Options;
/*