mirror of
https://github.com/coturn/coturn.git
synced 2025-10-31 23:11:28 +01:00
Add support for proxy protocol V1
This commit is contained in:
parent
ae2ee1f4e4
commit
c00d69e67f
@ -2166,6 +2166,101 @@ static TURN_TLS_TYPE check_tentative_tls(ioa_socket_raw fd)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static size_t proxy_string_field(char *field, size_t max, uint8_t *buf, size_t index, size_t len)
|
||||
{
|
||||
size_t count = 0;
|
||||
while((index < len) && (count < max)) {
|
||||
if((0x20 == buf[index]) || (0x0D == buf[index])) {
|
||||
field[count] = 0x00;
|
||||
return ++index;
|
||||
}
|
||||
field[count++] = buf[index++];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t socket_parse_proxy_v1(ioa_socket_handle s, uint8_t *buf, size_t len)
|
||||
{
|
||||
if(len < 11) {
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/* Check for proxy-v1 magic field */
|
||||
char magic[] = {0x50, 0x52, 0x4F, 0x58, 0x59, 0x20};
|
||||
if(memcmp(magic, buf, sizeof(magic))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read family */
|
||||
char tcp4[] = {0x54, 0x43, 0x50, 0x34, 0x20};
|
||||
char tcp6[] = {0x54, 0x43, 0x50, 0x36, 0x20};
|
||||
int family;
|
||||
if(0 == memcmp(tcp4, &buf[6], sizeof(tcp4))) { /* IPv4 */
|
||||
family = AF_INET;
|
||||
} else if(0 == memcmp(tcp6, &buf[6], sizeof(tcp6))) { /* IPv6 */
|
||||
family = AF_INET6;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char saddr[40];
|
||||
char daddr[40];
|
||||
char sport[6];
|
||||
char dport[6];
|
||||
|
||||
size_t tlen = 11;
|
||||
/* Read source address */
|
||||
tlen = proxy_string_field(saddr, sizeof(saddr), buf, tlen, len);
|
||||
if(0 == tlen) return -1;
|
||||
|
||||
/* Read dest address */
|
||||
tlen = proxy_string_field(daddr, sizeof(daddr), buf, tlen, len);
|
||||
if(0 == tlen) return -1;
|
||||
|
||||
/* Read source port */
|
||||
tlen = proxy_string_field(sport, sizeof(sport), buf, tlen, len);
|
||||
if(0 == tlen) return -1;
|
||||
|
||||
/* Read dest port */
|
||||
tlen = proxy_string_field(dport, sizeof(dport), buf, tlen, len);
|
||||
if(0 == tlen) return -1;
|
||||
|
||||
/* Final line feed */
|
||||
if ((len <= tlen) || (0x0A != buf[tlen])) return -1;
|
||||
|
||||
tlen++;
|
||||
|
||||
int sport_int = atoi(sport);
|
||||
int dport_int = atoi(dport);
|
||||
if((sport_int < 0) || (0xFFFF < sport_int)) return -1;
|
||||
if((dport_int < 0) || (0xFFFF < dport_int)) return -1;
|
||||
|
||||
if (AF_INET == family) {
|
||||
struct sockaddr_in remote, local;
|
||||
remote.sin_family = local.sin_family = AF_INET;
|
||||
if(1 != inet_pton(AF_INET, saddr, &remote.sin_addr.s_addr)) return -1;
|
||||
if(1 != inet_pton(AF_INET, daddr, &local.sin_addr.s_addr)) return -1;
|
||||
remote.sin_port = htons((uint16_t)sport_int);
|
||||
local.sin_port = htons((uint16_t)dport_int);
|
||||
|
||||
addr_cpy4(&(s->local_addr), &local);
|
||||
addr_cpy4(&(s->remote_addr), &remote);
|
||||
|
||||
} else {
|
||||
struct sockaddr_in6 remote, local;
|
||||
remote.sin6_family = local.sin6_family = AF_INET6;
|
||||
if(1 != inet_pton(AF_INET6, saddr, &remote.sin6_addr.s6_addr)) return -1;
|
||||
if(1 != inet_pton(AF_INET6, daddr, &local.sin6_addr.s6_addr)) return -1;
|
||||
remote.sin6_port = htons((uint16_t)sport_int);
|
||||
local.sin6_port = htons((uint16_t)dport_int);
|
||||
|
||||
addr_cpy6(&(s->local_addr), &local);
|
||||
addr_cpy6(&(s->remote_addr), &remote);
|
||||
}
|
||||
return tlen;
|
||||
}
|
||||
|
||||
static ssize_t socket_parse_proxy_v2(ioa_socket_handle s, uint8_t *buf, size_t len)
|
||||
{
|
||||
if(len < 16){
|
||||
@ -2227,6 +2322,16 @@ static ssize_t socket_parse_proxy_v2(ioa_socket_handle s, uint8_t *buf, size_t l
|
||||
return tlen;
|
||||
}
|
||||
|
||||
static ssize_t socket_parse_proxy(ioa_socket_handle s, uint8_t *buf, size_t len)
|
||||
{
|
||||
ssize_t tlen = socket_parse_proxy_v2(s, buf, len);
|
||||
if(-1 == tlen) {
|
||||
tlen = socket_parse_proxy_v1(s, buf, len);
|
||||
}
|
||||
|
||||
return tlen;
|
||||
}
|
||||
|
||||
static int socket_input_worker(ioa_socket_handle s)
|
||||
{
|
||||
int len = 0;
|
||||
@ -2450,7 +2555,7 @@ static int socket_input_worker(ioa_socket_handle s)
|
||||
blen=(ev_ssize_t)STUN_BUFFER_SIZE;
|
||||
|
||||
if(s->st == TCP_SOCKET_PROXY){
|
||||
ssize_t tlen = socket_parse_proxy_v2(s, buf_elem->buf.buf, blen);
|
||||
ssize_t tlen = socket_parse_proxy(s, buf_elem->buf.buf, blen);
|
||||
blen = 0;
|
||||
if (tlen < 0){
|
||||
s->tobeclosed = 1;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user