mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
circuit: Implement haproxy
This commit is contained in:
committed by
Nick Mathewson
parent
52e59640f9
commit
119004e87d
@@ -63,6 +63,7 @@ LIBTOR_APP_A_SOURCES = \
|
||||
src/core/proto/proto_cell.c \
|
||||
src/core/proto/proto_control0.c \
|
||||
src/core/proto/proto_ext_or.c \
|
||||
src/core/proto/proto_haproxy.c \
|
||||
src/core/proto/proto_http.c \
|
||||
src/core/proto/proto_socks.c \
|
||||
src/feature/api/tor_api.c \
|
||||
@@ -295,6 +296,7 @@ noinst_HEADERS += \
|
||||
src/core/proto/proto_cell.h \
|
||||
src/core/proto/proto_control0.h \
|
||||
src/core/proto/proto_ext_or.h \
|
||||
src/core/proto/proto_haproxy.h \
|
||||
src/core/proto/proto_http.h \
|
||||
src/core/proto/proto_socks.h \
|
||||
src/feature/api/tor_api_internal.h \
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
#include "core/or/reasons.h"
|
||||
#include "core/or/relay.h"
|
||||
#include "core/or/crypt_path.h"
|
||||
#include "core/proto/proto_haproxy.h"
|
||||
#include "core/proto/proto_http.h"
|
||||
#include "core/proto/proto_socks.h"
|
||||
#include "feature/client/dnsserv.h"
|
||||
@@ -2317,7 +2318,11 @@ conn_get_proxy_type(const connection_t *conn)
|
||||
return PROXY_SOCKS4;
|
||||
else if (options->Socks5Proxy)
|
||||
return PROXY_SOCKS5;
|
||||
else
|
||||
else if (options->TCPProxy) {
|
||||
/* The only supported protocol in TCPProxy is haproxy. */
|
||||
tor_assert(options->TCPProxyProtocol == TCP_PROXY_PROTOCOL_HAPROXY);
|
||||
return PROXY_HAPROXY;
|
||||
} else
|
||||
return PROXY_NONE;
|
||||
}
|
||||
|
||||
@@ -2489,6 +2494,35 @@ connection_socks5_proxy_connect(connection_t *conn)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Write a proxy request of haproxy to conn for conn->addr:conn->port.
|
||||
*
|
||||
* Returns -1 if conn->addr is incompatible with the proxy protocol, and
|
||||
* 0 otherwise.
|
||||
*/
|
||||
static int
|
||||
connection_haproxy_proxy_connect(connection_t *conn)
|
||||
{
|
||||
int ret = 0;
|
||||
tor_addr_port_t *addr_port = tor_addr_port_new(&conn->addr, conn->port);
|
||||
char *buf = haproxy_format_proxy_header_line(addr_port);
|
||||
|
||||
if (buf == NULL) {
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
connection_buf_add(buf, strlen(buf), conn);
|
||||
/* In haproxy, we don't have to wait for the response, but we wait for ack.
|
||||
* So we can set the state to be PROXY_HAPROXY_WAIT_FOR_FLUSH. */
|
||||
conn->proxy_state = PROXY_HAPROXY_WAIT_FOR_FLUSH;
|
||||
|
||||
ret = 0;
|
||||
done:
|
||||
tor_free(buf);
|
||||
tor_free(addr_port);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Write a proxy request of <b>type</b> (socks4, socks5, https, haproxy)
|
||||
* to conn for conn->addr:conn->port, authenticating with the auth details
|
||||
* given in the configuration (if available). SOCKS 5 and HTTP CONNECT
|
||||
@@ -2519,6 +2553,10 @@ connection_proxy_connect(connection_t *conn, int type)
|
||||
ret = connection_socks5_proxy_connect(conn);
|
||||
break;
|
||||
|
||||
case PROXY_HAPROXY:
|
||||
ret = connection_haproxy_proxy_connect(conn);
|
||||
break;
|
||||
|
||||
default:
|
||||
log_err(LD_BUG, "Invalid proxy protocol, %d", type);
|
||||
tor_fragile_assert();
|
||||
@@ -5498,6 +5536,13 @@ get_proxy_addrport(tor_addr_t *addr, uint16_t *port, int *proxy_type,
|
||||
*port = options->Socks5ProxyPort;
|
||||
*proxy_type = PROXY_SOCKS5;
|
||||
return 0;
|
||||
} else if (options->TCPProxy) {
|
||||
tor_addr_copy(addr, &options->TCPProxyAddr);
|
||||
*port = options->TCPProxyPort;
|
||||
/* The only supported protocol in TCPProxy is haproxy. */
|
||||
tor_assert(options->TCPProxyProtocol == TCP_PROXY_PROTOCOL_HAPROXY);
|
||||
*proxy_type = PROXY_HAPROXY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tor_addr_make_unspec(addr);
|
||||
@@ -5535,6 +5580,7 @@ proxy_type_to_string(int proxy_type)
|
||||
case PROXY_CONNECT: return "HTTP";
|
||||
case PROXY_SOCKS4: return "SOCKS4";
|
||||
case PROXY_SOCKS5: return "SOCKS5";
|
||||
case PROXY_HAPROXY: return "HAPROXY";
|
||||
case PROXY_PLUGGABLE: return "pluggable transports SOCKS";
|
||||
case PROXY_NONE: return "NULL";
|
||||
default: tor_assert(0);
|
||||
|
||||
@@ -75,8 +75,10 @@ struct buf_t;
|
||||
#define PROXY_SOCKS5_WANT_AUTH_RFC1929_OK 6
|
||||
/* We use a SOCKS5 proxy and we just sent our CONNECT command. */
|
||||
#define PROXY_SOCKS5_WANT_CONNECT_OK 7
|
||||
/* We use an HAPROXY proxy and we just sent the proxy header. */
|
||||
#define PROXY_HAPROXY_WAIT_FOR_FLUSH 8
|
||||
/* We use a proxy and we CONNECTed successfully!. */
|
||||
#define PROXY_CONNECTED 8
|
||||
#define PROXY_CONNECTED 9
|
||||
|
||||
/** State for any listener connection. */
|
||||
#define LISTENER_STATE_READY 0
|
||||
|
||||
@@ -726,6 +726,18 @@ connection_or_finished_flushing(or_connection_t *conn)
|
||||
|
||||
switch (conn->base_.state) {
|
||||
case OR_CONN_STATE_PROXY_HANDSHAKING:
|
||||
/* PROXY_HAPROXY gets connected by receiving an ack. */
|
||||
if (conn->proxy_type == PROXY_HAPROXY) {
|
||||
tor_assert(TO_CONN(conn)->proxy_state == PROXY_HAPROXY_WAIT_FOR_FLUSH);
|
||||
TO_CONN(conn)->proxy_state = PROXY_CONNECTED;
|
||||
|
||||
if (connection_tls_start_handshake(conn, 0) < 0) {
|
||||
/* TLS handshaking error of some kind. */
|
||||
connection_or_close_for_error(conn, 0);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OR_CONN_STATE_OPEN:
|
||||
case OR_CONN_STATE_OR_HANDSHAKING_V2:
|
||||
case OR_CONN_STATE_OR_HANDSHAKING_V3:
|
||||
@@ -765,8 +777,9 @@ connection_or_finished_connecting(or_connection_t *or_conn)
|
||||
return -1;
|
||||
}
|
||||
|
||||
connection_start_reading(conn);
|
||||
connection_or_change_state(or_conn, OR_CONN_STATE_PROXY_HANDSHAKING);
|
||||
connection_start_reading(conn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -168,12 +168,13 @@ struct curve25519_public_key_t;
|
||||
#define PROXY_CONNECT 1
|
||||
#define PROXY_SOCKS4 2
|
||||
#define PROXY_SOCKS5 3
|
||||
/* !!!! If there is ever a PROXY_* type over 3, we must grow the proxy_type
|
||||
#define PROXY_HAPROXY 4
|
||||
/* !!!! If there is ever a PROXY_* type over 7, we must grow the proxy_type
|
||||
* field in or_connection_t */
|
||||
|
||||
/* Pluggable transport proxy type. Don't use this in or_connection_t,
|
||||
* instead use the actual underlying proxy type (see above). */
|
||||
#define PROXY_PLUGGABLE 4
|
||||
#define PROXY_PLUGGABLE 5
|
||||
|
||||
/** How many circuits do we want simultaneously in-progress to handle
|
||||
* a given stream? */
|
||||
|
||||
@@ -58,7 +58,7 @@ struct or_connection_t {
|
||||
|
||||
/** True iff this is an outgoing connection. */
|
||||
unsigned int is_outgoing:1;
|
||||
unsigned int proxy_type:2; /**< One of PROXY_NONE...PROXY_SOCKS5 */
|
||||
unsigned int proxy_type:3; /**< One of PROXY_NONE...PROXY_HAPROXY */
|
||||
unsigned int wide_circ_ids:1;
|
||||
/** True iff this connection has had its bootstrap failure logged with
|
||||
* control_event_bootstrap_problem. */
|
||||
|
||||
@@ -4,7 +4,11 @@ orconfig.h
|
||||
|
||||
lib/crypt_ops/*.h
|
||||
lib/buf/*.h
|
||||
lib/malloc/*.h
|
||||
lib/string/*.h
|
||||
|
||||
lib/net/address.h
|
||||
|
||||
trunnel/*.h
|
||||
|
||||
core/proto/*.h
|
||||
core/proto/*.h
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/* Copyright (c) 2019, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
#define PROTO_HAPROXY_PRIVATE
|
||||
#include "lib/malloc/malloc.h"
|
||||
#include "lib/net/address.h"
|
||||
#include "lib/string/printf.h"
|
||||
#include "core/proto/proto_haproxy.h"
|
||||
|
||||
/** Return a newly allocated PROXY header null-terminated string. Returns NULL
|
||||
* if addr_port->addr is incompatible with the proxy protocol.
|
||||
*/
|
||||
char *
|
||||
haproxy_format_proxy_header_line(const tor_addr_port_t *addr_port)
|
||||
{
|
||||
tor_assert(addr_port);
|
||||
|
||||
sa_family_t family = tor_addr_family(&addr_port->addr);
|
||||
const char *family_string = NULL;
|
||||
const char *src_addr_string = NULL;
|
||||
|
||||
switch (family) {
|
||||
case AF_INET:
|
||||
family_string = "TCP4";
|
||||
src_addr_string = "0.0.0.0";
|
||||
break;
|
||||
case AF_INET6:
|
||||
family_string = "TCP6";
|
||||
src_addr_string = "::";
|
||||
break;
|
||||
default:
|
||||
/* Unknown family. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *buf;
|
||||
char addrbuf[TOR_ADDR_BUF_LEN];
|
||||
|
||||
tor_addr_to_str(addrbuf, &addr_port->addr, sizeof(addrbuf), 0);
|
||||
|
||||
tor_asprintf(&buf, "PROXY %s %s %s 0 %d\r\n", family_string, src_addr_string,
|
||||
addrbuf, addr_port->port);
|
||||
|
||||
return buf;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/* Copyright (c) 2019, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
#ifndef TOR_PROTO_HAPROXY_H
|
||||
#define TOR_PROTO_HAPROXY_H
|
||||
|
||||
struct tor_addr_port_t;
|
||||
|
||||
char *haproxy_format_proxy_header_line(
|
||||
const struct tor_addr_port_t *addr_port);
|
||||
|
||||
#endif /* !defined(TOR_PROTO_HAPROXY_H) */
|
||||
@@ -45,6 +45,7 @@ using_proxy(const bt_orconn_t *bto)
|
||||
case PROXY_CONNECT:
|
||||
case PROXY_SOCKS4:
|
||||
case PROXY_SOCKS5:
|
||||
case PROXY_HAPROXY:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user