mirror of
https://github.com/LBRYFoundation/pool.git
synced 2025-08-23 09:27:25 +00:00
stratum: handle proxy protocol (#196)
Implemented PROXY v2 protocol (https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) so that stratum can be run behind an haproxy instance. iptables/ipset still work if haproxy is run on local machine. if run on remote machine switch to using client_block_ipset() and periodically sync the ipset to the machine running haproxy. haproxy must be configured with send-proxy-v2, version 1 does not work
This commit is contained in:
parent
117c7b3c9c
commit
1f9bfd006a
2 changed files with 74 additions and 9 deletions
|
@ -8,6 +8,48 @@ bool socket_connected(YAAMP_SOCKET *s)
|
||||||
return s->sock > 0;
|
return s->sock > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void socket_real_ip(YAAMP_SOCKET *s)
|
||||||
|
{
|
||||||
|
// get real ip if we are using haproxy or similar that use PROXY protocol
|
||||||
|
// https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt
|
||||||
|
int size, ret;
|
||||||
|
const char v2sig[] = "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A";
|
||||||
|
|
||||||
|
do {
|
||||||
|
ret = recv(s->sock, &hdr, sizeof(hdr), MSG_PEEK);
|
||||||
|
} while (ret == -1 && errno == EINTR);
|
||||||
|
|
||||||
|
if (ret >= (16 + ntohs(hdr.v2.len)) &&
|
||||||
|
memcmp(&hdr.v2, v2sig, 12) == 0 &&
|
||||||
|
((hdr.v2.ver_cmd & 0xF0) == 0x20) &&
|
||||||
|
hdr.v2.fam == 0x11) {
|
||||||
|
// we received a proxy v2 header
|
||||||
|
inet_ntop(AF_INET, &hdr.v2.addr.ip4.src_addr, s->ip, 64);
|
||||||
|
s->port = ntohs(hdr.v2.addr.ip4.src_port);
|
||||||
|
|
||||||
|
// we need to consume the appropriate amount of data from the socket
|
||||||
|
// read the buffer without PEEK'ing so that we begin at the real data later in socket_nextjson
|
||||||
|
size = 16 + ntohs(hdr.v2.len);
|
||||||
|
do {
|
||||||
|
ret = recv(s->sock, &hdr, size, 0);
|
||||||
|
} while (ret == -1 && errno == EINTR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// not received any proxy header
|
||||||
|
struct sockaddr_in name;
|
||||||
|
socklen_t len = sizeof(name);
|
||||||
|
memset(&name, 0, len);
|
||||||
|
|
||||||
|
int res = getpeername(s->sock, (struct sockaddr *)&name, &len);
|
||||||
|
inet_ntop(AF_INET, &name.sin_addr, s->ip, 64);
|
||||||
|
|
||||||
|
res = getsockname(s->sock, (struct sockaddr *)&name, &len);
|
||||||
|
s->port = ntohs(name.sin_port);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
YAAMP_SOCKET *socket_initialize(int sock)
|
YAAMP_SOCKET *socket_initialize(int sock)
|
||||||
{
|
{
|
||||||
YAAMP_SOCKET *s = new YAAMP_SOCKET;
|
YAAMP_SOCKET *s = new YAAMP_SOCKET;
|
||||||
|
@ -19,15 +61,7 @@ YAAMP_SOCKET *socket_initialize(int sock)
|
||||||
// yaamp_create_mutex(&s->mutex);
|
// yaamp_create_mutex(&s->mutex);
|
||||||
// pthread_mutex_lock(&s->mutex);
|
// pthread_mutex_lock(&s->mutex);
|
||||||
|
|
||||||
struct sockaddr_in name;
|
socket_real_ip(s);
|
||||||
socklen_t len = sizeof(name);
|
|
||||||
memset(&name, 0, len);
|
|
||||||
|
|
||||||
int res = getpeername(s->sock, (struct sockaddr *)&name, &len);
|
|
||||||
inet_ntop(AF_INET, &name.sin_addr, s->ip, 64);
|
|
||||||
|
|
||||||
res = getsockname(s->sock, (struct sockaddr *)&name, &len);
|
|
||||||
s->port = ntohs(name.sin_port);
|
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@ struct YAAMP_SOCKET
|
||||||
|
|
||||||
bool socket_connected(YAAMP_SOCKET *s);
|
bool socket_connected(YAAMP_SOCKET *s);
|
||||||
|
|
||||||
|
void socket_real_ip(YAAMP_SOCKET *s);
|
||||||
|
|
||||||
YAAMP_SOCKET *socket_initialize(int sock);
|
YAAMP_SOCKET *socket_initialize(int sock);
|
||||||
void socket_close(YAAMP_SOCKET *s);
|
void socket_close(YAAMP_SOCKET *s);
|
||||||
|
|
||||||
|
@ -26,3 +28,32 @@ int socket_send(YAAMP_SOCKET *s, const char *format, ...);
|
||||||
|
|
||||||
int socket_send_raw(YAAMP_SOCKET *s, const char *buffer, int size);
|
int socket_send_raw(YAAMP_SOCKET *s, const char *buffer, int size);
|
||||||
|
|
||||||
|
static union {
|
||||||
|
struct {
|
||||||
|
char line[108];
|
||||||
|
} v1;
|
||||||
|
struct {
|
||||||
|
uint8_t sig[12];
|
||||||
|
uint8_t ver_cmd;
|
||||||
|
uint8_t fam;
|
||||||
|
uint16_t len;
|
||||||
|
union {
|
||||||
|
struct { /* for TCP/UDP over IPv4, len = 12 */
|
||||||
|
uint32_t src_addr;
|
||||||
|
uint32_t dst_addr;
|
||||||
|
uint16_t src_port;
|
||||||
|
uint16_t dst_port;
|
||||||
|
} ip4;
|
||||||
|
struct { /* for TCP/UDP over IPv6, len = 36 */
|
||||||
|
uint8_t src_addr[16];
|
||||||
|
uint8_t dst_addr[16];
|
||||||
|
uint16_t src_port;
|
||||||
|
uint16_t dst_port;
|
||||||
|
} ip6;
|
||||||
|
struct { /* for AF_UNIX sockets, len = 216 */
|
||||||
|
uint8_t src_addr[108];
|
||||||
|
uint8_t dst_addr[108];
|
||||||
|
} unx;
|
||||||
|
} addr;
|
||||||
|
} v2;
|
||||||
|
} hdr;
|
||||||
|
|
Loading…
Add table
Reference in a new issue