Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

Commit 047c0cf2 authored by Deucе's avatar Deucе 👌🏾

Move HAPROXY support into multisock.c and change parsing code.

parent db690fad
......@@ -6233,7 +6233,7 @@ void DLLCALL ftp_server(void* arg)
/* now wait for connection */
client_addr_len = sizeof(client_addr);
client_socket = xpms_accept(ftp_set, &client_addr, &client_addr_len, startup->sem_chk_freq*1000, NULL);
client_socket = xpms_accept(ftp_set, &client_addr, &client_addr_len, startup->sem_chk_freq*1000, 0, NULL);
if(client_socket == INVALID_SOCKET)
continue;
......
......@@ -691,7 +691,7 @@ js_accept(JSContext *cx, uintN argc, jsval *arglist)
rc=JS_SUSPENDREQUEST(cx);
if(p->set) {
if((new_socket=xpms_accept(p->set,&(p->remote_addr),&addrlen,XPMS_FOREVER,NULL))==INVALID_SOCKET) {
if((new_socket=xpms_accept(p->set,&(p->remote_addr),&addrlen,XPMS_FOREVER,0,NULL))==INVALID_SOCKET) {
p->last_error=ERROR_VALUE;
dbprintf(TRUE, p, "accept failed with error %d",ERROR_VALUE);
JS_RESUMEREQUEST(cx, rc);
......
......@@ -6337,7 +6337,7 @@ void DLLCALL mail_server(void* arg)
/* now wait for connection */
client_addr_len = sizeof(client_addr);
client_socket = xpms_accept(mail_set,&client_addr, &client_addr_len, startup->sem_chk_freq*1000, (void**)&servprot);
client_socket = xpms_accept(mail_set,&client_addr, &client_addr_len, startup->sem_chk_freq*1000, 0, (void**)&servprot);
if(client_socket != INVALID_SOCKET) {
bool is_smtp = (servprot != servprot_pop3 && servprot != servprot_pop3s);
if(startup->socket_open!=NULL)
......
......@@ -42,7 +42,6 @@
#include "js_rtpool.h"
#include "js_request.h"
#include "ssl.h"
#include "haproxy.h"
#include <multisock.h>
#include <limits.h> // HOST_NAME_MAX
......@@ -361,72 +360,6 @@ int close_socket(SOCKET sock)
return(result);
}
static bool read_socket(SOCKET sock,unsigned char *buffer,int len)
{
fd_set socket_set;
struct timeval tv;
int i,j,rd;
char ch;
char err[128];
// Clear our buffer
memset(buffer,'\0',len);
for (i=0;i<len;i++) {
FD_ZERO(&socket_set);
FD_SET(sock,&socket_set);
// We'll wait 1 secs to read from the socket.
tv.tv_sec=1;
tv.tv_usec=0;
#ifdef _DEBUG
lprintf(LOG_DEBUG,"%04d Read Socket - select (%d of %d)",sock,i,len);
#endif
if((j=select(sock+1,&socket_set,NULL,NULL,&tv))>0) {
#ifdef _DEBUG
lprintf(LOG_DEBUG,"%04d Read Socket - read",sock);
#endif
rd = recv(sock,&ch,1,0);
#ifdef _DEBUG
lprintf(LOG_DEBUG,"%04d Read Socket - got [%02x] (%x)",sock,ch,rd);
#endif
if(FD_ISSET(sock,&socket_set) && rd) {
buffer[i] = ch;
} else {
lprintf(LOG_WARNING,"%04d Read Socket - failed to read from socket. Got [%d] with error [%s]",sock,rd,socket_strerror(socket_errno,err,sizeof(err)));
return false;
}
} else if (j==0) {
lprintf(LOG_WARNING,"%04d Read Socket - No data?",sock);
return false;
} else {
lprintf(LOG_WARNING,"%04d Read Socket - Something else [%d] with error [%s].",sock,j,socket_strerror(socket_errno,err,sizeof(err)));
return false;
}
}
#ifdef _DEBUG
lprintf(LOG_DEBUG,"%04d Read Socket - Returning [%.*s]",sock,i,buffer);
#endif
return true;
}
/* Convert a binary variable into a hex string - used for printing in the debug log */
static void btox(char *hexstr, const unsigned char *srcbuf, int srcbuflen, int hexstrlen)
{
if (hexstrlen < srcbuflen*2) {
lprintf(LOG_WARNING,"btox Hexstr buffer too small [%d] - not all data will be shown",hexstrlen);
srcbuflen = hexstrlen/2;
}
*hexstr = '\0';
for (int i=0;i<srcbuflen;i++) sprintf(hexstr+strlen(hexstr),"%02X",srcbuf[i]);
}
/* TODO: IPv6 */
u_long resolve_ip(char *addr)
{
......@@ -5001,10 +4934,6 @@ static void cleanup(int code)
void DLLCALL bbs_thread(void* arg)
{
struct addrinfo *res;
unsigned char hapstr[128];
char haphex[256];
char host_name[256];
char* identity;
char* p;
......@@ -5014,7 +4943,7 @@ void DLLCALL bbs_thread(void* arg)
union xp_sockaddr client_addr;
socklen_t client_addr_len;
SOCKET client_socket=INVALID_SOCKET;
int i,l;
int i;
int file;
int result;
time_t t;
......@@ -5433,7 +5362,7 @@ NO_SSH:
/* now wait for connection */
client_addr_len = sizeof(client_addr);
client_socket=xpms_accept(ts_set, &client_addr
,&client_addr_len, startup->sem_chk_freq*1000, &ts_cb);
,&client_addr_len, startup->sem_chk_freq*1000, (startup->options & BBS_OPT_HAPROXY_PROTO) ? XPMS_ACCEPT_FLAG_HAPROXY : 0, &ts_cb);
if(terminate_server) /* terminated */
break;
......@@ -5521,212 +5450,7 @@ NO_SSH:
}
char host_ip[INET6_ADDRSTRLEN];
// Set host_ip from haproxy protocol, if its used
// http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt
if(startup->options&BBS_OPT_HAPROXY_PROTO) {
lprintf(LOG_INFO,"%04d Working out client address from HAPROXY PROTO",client_socket);
memset(hapstr,'\0',sizeof(hapstr));
memset(host_ip,'\0',sizeof(host_ip));
// Read the first 5 chars to work out what we are dealing with
if (read_socket(client_socket,hapstr,6)==false) {
lprintf(LOG_ERR,"%04d * HAPROXY, looking for version - failed [%s]",client_socket,hapstr);
close_socket(client_socket);
continue;
}
#ifdef _DEBUG
lprintf(LOG_DEBUG,"%04d * HAPROXY, looking for version - received [%s]",client_socket,hapstr);
#endif
// v1 of the protocol uses plain text, starting with "PROXY "
// eg: "PROXY TCP4 255.255.255.255 255.255.255.255 65535 65535\r\n"
if (strcmp((char *)hapstr,"PROXY ") == 0) {
lprintf(LOG_DEBUG,"%04d * HAPROXY PROTO v1",client_socket);
// Get Protocol
memset(hapstr,'\0',sizeof(hapstr));
if (read_socket(client_socket,hapstr,5)==false) {
lprintf(LOG_ERR,"%04d * HAPROXY, looking for protocol - failed [%s]",client_socket,hapstr);
close_socket(client_socket);
continue;
}
#ifdef _DEBUG
lprintf(LOG_DEBUG,"%04d * HAPROXY, looking for protocol - received [%s]",client_socket,hapstr);
#endif
// IPV4
if (strcmp((char *)hapstr,"TCP4 ") == 0) {
lprintf(LOG_DEBUG,"%04d * HAPROXY Proto [%s]",client_socket,hapstr);
// Source Address
if (read_socket(client_socket,hapstr,16)==false) {
lprintf(LOG_ERR,"%04d * HAPROXY, looking for IPv4 source - failed [%s]",client_socket,hapstr);
close_socket(client_socket);
continue;
}
// IPV6
} else if (strcmp((char *)hapstr,"TCP6 ") == 0) {
lprintf(LOG_DEBUG,"%04d * HAPROXY Proto %s",client_socket,hapstr);
// Source Address
if (read_socket(client_socket,hapstr,40)==false) {
lprintf(LOG_ERR,"%04d * HAPROXY, looking for IPv6 source - failed [%s]",client_socket,hapstr);
close_socket(client_socket);
continue;
}
// Unknown?
} else if (strcmp((char *)hapstr,"UNKNO") == 0) {
lprintf(LOG_ERR,"%04d * HAPROXY Unknown Protocol [%s]",client_socket,hapstr);
close_socket(client_socket);
continue;
}
// Look for the space between the next IP
for(i=0;i<sizeof(hapstr);i++) {
if (hapstr[i] == ' ')
break;
}
// If we didnt find our space...
if (i == sizeof(hapstr)) {
lprintf(LOG_ERR,"%04d * HAPROXY Something went wrong [%s]",client_socket,hapstr);
close_socket(client_socket);
continue;
}
// IPv4 address in IPv6 ::ffff:n.n.n.n
if (hapstr[0] == ':' && hapstr[1] == ':' && i>7) {
sprintf(host_ip,"%.*s",i-7,hapstr+7);
lprintf(LOG_DEBUG,"%04d * HAPROXY IPv4 address in IPv6 [%s]",client_socket,host_ip);
} else {
memcpy(host_ip,hapstr,i);
}
// v2 is in binary with the first 12 bytes "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A"
// we'll compare the 1st 6 bytes here, since we are determining if we are v1 or v2.
} else if (memcmp((char *)hapstr,"\r\n\r\n\x00\r",6) == 0) {
lprintf(LOG_DEBUG,"%04d * HAPROXY PROTO v2",client_socket);
// OK, just for sanity, our next 6 chars should be v2...
if (read_socket(client_socket,hapstr,6)==false || strcmp((char *)hapstr,"\nQUIT\n") != 0) {
btox(haphex,hapstr,6,sizeof(haphex));
lprintf(LOG_ERR,"%04d * HAPROXY Something went wrong [%s] incomplete v2 setup",client_socket,haphex);
close_socket(client_socket);
continue;
}
// Command and Version
if (read_socket(client_socket,hapstr,1)==false) {
btox(haphex,hapstr,1,sizeof(haphex));
lprintf(LOG_ERR,"%04d * HAPROXY, looking for Verson/Command - failed [%s]",client_socket,haphex);
close_socket(client_socket);
continue;
}
lprintf(LOG_DEBUG,"%04d * HAPROXY Version [%x]",client_socket,hapstr[0]&0x0f); //Should be 2
lprintf(LOG_DEBUG,"%04d * HAPROXY Command [%x]",client_socket,(hapstr[0]>>4)&0x0f); //0=Local/1=Proxy
// Protocol and Family
if (read_socket(client_socket,hapstr,1)==false) {
btox(haphex,hapstr,1,sizeof(haphex));
lprintf(LOG_ERR,"%04d * HAPROXY, looking for Protocol/Family - failed [%s]",client_socket,haphex);
close_socket(client_socket);
continue;
}
lprintf(LOG_DEBUG,"%04d * HAPROXY Protocol [%x]",client_socket,hapstr[0]&0x0f); //0=Unspec/1=AF_INET/2=AF_INET6/3=AF_UNIX
l = (hapstr[0]>>4)&0x0f;
lprintf(LOG_DEBUG,"%04d * HAPROXY Family [%x]",client_socket,l); //0=UNSPEC/1=STREAM/2=DGRAM
// Address Length - 2 bytes
if (read_socket(client_socket,hapstr,2)==false) {
btox(haphex,hapstr,2,sizeof(haphex));
lprintf(LOG_ERR,"%04d * HAPROXY, looking for address length - failed [%s]",client_socket,haphex);
close_socket(client_socket);
continue;
}
i = ntohs(*(uint16_t*)hapstr);
lprintf(LOG_DEBUG,"%04d * HAPROXY Address Length [%d]",client_socket,i);
switch (l) {
// IPv4 - AF_INET
case HAPROXY_AFINET:
if (i < 4) {
lprintf(LOG_ERR,"%04d * HAPROXY Something went wrong - IPv4 address length too small.",client_socket);
close_socket(client_socket);
continue;
}
if (read_socket(client_socket,hapstr,i)==false) {
btox(haphex,hapstr,i,sizeof(haphex));
lprintf(LOG_ERR,"%04d * HAPROXY looking for IPv4 address - failed [%s]",client_socket,haphex);
close_socket(client_socket);
continue;
}
inet_ntop(AF_INET,hapstr,host_ip,sizeof(host_ip));
break;
// IPv6 - AF_INET6
case HAPROXY_AFINET6:
if (i < 16) {
lprintf(LOG_ERR,"%04d * HAPROXY Something went wrong - IPv6 address length too small.",client_socket);
close_socket(client_socket);
continue;
}
if (read_socket(client_socket,hapstr,i)==false) {
btox(haphex,hapstr,i,sizeof(haphex));
lprintf(LOG_ERR,"%04d * HAPROXY looking for IPv6 address - failed [%s]",client_socket,haphex);
close_socket(client_socket);
continue;
}
// IPv4 address in IPv6 ::ffff:n.n.n.n
// 0000:0000:0000:0000:0000:ffff:0a01:039c
for(i=0;i<10;i++) {
if (hapstr[i] != 0x00)
break;
}
if ((i==10) && (hapstr[i] == 0xff) && (hapstr[i+1] == 0xff)) {
inet_ntop(AF_INET,&hapstr[12],host_ip,sizeof(host_ip));
lprintf(LOG_DEBUG,"%04d * HAPROXY IPv4 address in IPv6 [%s]",client_socket,host_ip);
} else {
inet_ntop(AF_INET6,hapstr,host_ip,sizeof(host_ip));
}
break;
default:
lprintf(LOG_ERR,"%04d * HAPROXY Unknown Family [%x]",client_socket,l);
close_socket(client_socket);
continue;
}
} else {
lprintf(LOG_ERR,"%04d Unknown HAProxy Initialisation - is HAProxy used?",client_socket);
close_socket(client_socket);
continue;
}
lprintf(LOG_INFO,"%04d * HAPROXY Source [%s]",client_socket,host_ip);
if ((i=getaddrinfo(host_ip,NULL,NULL,&res)) !=0) {
lprintf(LOG_ERR,"!ERROR resolve_ip %s failed with error %d",host_ip,i);
freeaddrinfo(res);
close_socket(client_socket);
continue;
}
memcpy(&client_addr.addr,res->ai_addr,res->ai_addrlen);
freeaddrinfo(res);
} else {
inet_addrtop(&client_addr,host_ip,sizeof(host_ip));
}
inet_addrtop(&client_addr, host_ip, sizeof(host_ip));
if(trashcan(&scfg,host_ip,"ip-silent")) {
close_socket(client_socket);
......
......@@ -7189,7 +7189,7 @@ void DLLCALL web_server(void* arg)
/* now wait for connection */
client_addr_len = sizeof(client_addr);
client_socket = xpms_accept(ws_set, &client_addr, &client_addr_len, startup->sem_chk_freq*1000, &acc_type);
client_socket = xpms_accept(ws_set, &client_addr, &client_addr_len, startup->sem_chk_freq*1000, 0, &acc_type);
if(client_socket == INVALID_SOCKET)
continue;
......
......@@ -7,6 +7,7 @@
#include "sockwrap.h"
#include "dirwrap.h"
#include "multisock.h"
#include "haproxy.h"
#include <stdarg.h>
struct xpms_set* DLLCALL xpms_create(unsigned int retries, unsigned int wait_secs,
......@@ -236,15 +237,91 @@ BOOL DLLCALL xpms_add_chararray_list(struct xpms_set *xpms_set, int domain, int
return ret;
}
/* Convert a binary variable into a hex string - used for printing in the debug log */
static void btox(char *hexstr, const char *srcbuf, int srcbuflen, int hexstrlen, int (*lprintf)(int level, const char *fmt, ...))
{
if (hexstrlen < srcbuflen*2) {
lprintf(LOG_WARNING,"btox Hexstr buffer too small [%d] - not all data will be shown",hexstrlen);
srcbuflen = hexstrlen/2;
}
*hexstr = '\0';
for (int i=0;i<srcbuflen;i++) sprintf(hexstr+strlen(hexstr),"%02X",srcbuf[i]);
}
static BOOL read_socket(SOCKET sock, char *buffer, int len, int (*lprintf)(int level, const char *fmt, ...))
{
fd_set socket_set;
struct timeval tv;
int i,j,rd;
char ch;
char err[128];
for (i=0;i<len;i++) {
FD_ZERO(&socket_set);
FD_SET(sock,&socket_set);
// We'll wait 1 secs to read from the socket.
tv.tv_sec=1;
tv.tv_usec=0;
if((j=select(sock+1,&socket_set,NULL,NULL,&tv))>0) {
rd = recv(sock,&ch,1,0);
if (rd == 1) {
buffer[i] = ch;
} else {
lprintf(LOG_WARNING,"%04d multisock read_socket() - failed to read from socket. Got [%d] with error [%s]",sock,rd,socket_strerror(socket_errno,err,sizeof(err)));
return TRUE;
}
} else if (j==0) {
lprintf(LOG_WARNING,"%04d multisock read_socket() - No data?",sock);
return TRUE;
} else {
lprintf(LOG_WARNING,"%04d multisock read_socket() - select() returned [%d] with error [%s].",sock,j,socket_strerror(socket_errno,err,sizeof(err)));
return TRUE;
}
}
return TRUE;
}
static BOOL read_socket_line(SOCKET sock, char *buffer, int buflen, int (*lprintf)(int level, const char *fmt, ...))
{
int i;
for (i = 0; i < buflen - 1; i++) {
if (read_socket(sock, &buffer[i], 1, lprintf)) {
switch(buffer[i]) {
case 0:
return TRUE;
case '\n':
buffer[i+1] = '\0';
return TRUE;
}
}
else {
buffer[i] = 0;
return TRUE;
}
}
buffer[i] = 0;
return TRUE;
}
SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr,
socklen_t * addrlen, unsigned int timeout, void **cb_data)
socklen_t * addrlen, unsigned int timeout, uint32_t flags, void **cb_data)
{
fd_set read_fs;
size_t i;
struct timeval tv;
struct timeval *tvp;
SOCKET max_sock=0;
fd_set read_fs;
size_t i;
struct timeval tv;
struct timeval *tvp;
SOCKET max_sock=0;
SOCKET ret;
char hapstr[128];
char haphex[256];
char *p, *tok;
long l;
FD_ZERO(&read_fs);
for(i=0; i<xpms_set->sock_count; i++) {
if(xpms_set->socks[i].sock == INVALID_SOCKET)
......@@ -273,7 +350,188 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr,
if(FD_ISSET(xpms_set->socks[i].sock, &read_fs)) {
if(cb_data)
*cb_data=xpms_set->socks[i].cb_data;
return accept(xpms_set->socks[i].sock, &addr->addr, addrlen);
ret = accept(xpms_set->socks[i].sock, &addr->addr, addrlen);
if (ret == INVALID_SOCKET)
return ret;
// Set host_ip from haproxy protocol, if its used
// http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt
if (flags & XPMS_ACCEPT_FLAG_HAPROXY) {
xpms_set->lprintf(LOG_INFO,"%04d Working out client address from HAPROXY PROTO",ret);
// Read the first line
if (read_socket_line(ret, hapstr, 108, xpms_set->lprintf)) {
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY, looking for version - failed [%s]",ret,hapstr);
closesocket(ret);
return INVALID_SOCKET;
}
xpms_set->lprintf(LOG_DEBUG,"%04d * HAPROXY, looking for version - received [%s]",ret,hapstr);
// v1 of the protocol uses plain text, starting with "PROXY "
// eg: "PROXY TCP4 255.255.255.255 255.255.255.255 65535 65535\r\n"
if (strncmp((char *)hapstr,"PROXY ",6) == 0) {
xpms_set->lprintf(LOG_DEBUG,"%04d * HAPROXY PROTO v1",ret);
tok = &hapstr[6];
// IPV4
if (strncmp(tok, "TCP4 ", 5) == 0) {
tok += 5;
xpms_set->lprintf(LOG_DEBUG,"%04d * HAPROXY Proto [TCP4]",ret,hapstr);
addr->addr.sa_family = AF_INET;
addr->addr.sa_len = sizeof(struct sockaddr_in);
// IPV6
} else if (strncmp(tok,"TCP6 ",5) == 0) {
tok += 5;
xpms_set->lprintf(LOG_DEBUG,"%04d * HAPROXY Proto TCP6",ret,hapstr);
addr->addr.sa_family = AF_INET6;
addr->addr.sa_len = sizeof(struct sockaddr_in6);
// Unknown?
} else {
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Unknown Protocol",ret);
closesocket(ret);
return INVALID_SOCKET;
}
// Look for the space between the next IP
p = strchr(tok, ' ');
if (p == NULL) {
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Something went wrong",ret);
closesocket(ret);
return INVALID_SOCKET;
}
*p = 0;
if (inet_pton(addr->addr.sa_family, tok, addr->addr.sa_data) != 1) {
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Unable to parse %s address [%s]",addr->addr.sa_family == AF_INET ? "IPv4" : "IPv6", tok);
closesocket(ret);
return INVALID_SOCKET;
}
tok = p + 1;
// Look for the space before the port number
p = strchr(tok, ' ');
if (p == NULL) {
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Something went wrong",ret);
closesocket(ret);
return INVALID_SOCKET;
}
tok = p + 1;
l = strtol(tok, NULL, 10);
if (l <= 0 || l > UINT16_MAX) {
xpms_set->lprintf(LOG_ERR,"%04d * Source port out of range",ret);
closesocket(ret);
return INVALID_SOCKET;
}
switch(addr->addr.sa_family) {
case AF_INET:
addr->in.sin_port = htons(l);
break;
case AF_INET6:
addr->in6.sin6_port = htons(l);
break;
}
// v2 is in binary with the first 12 bytes "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A"
// we'll compare the 1st 6 bytes here, since we are determining if we are v1 or v2.
} else if (strcmp((char *)hapstr,"\r\n") == 0) {
xpms_set->lprintf(LOG_DEBUG,"%04d * HAPROXY PROTO v2",ret);
// OK, just for sanity, our next 10 chars should be v2...
memset(hapstr, 0, 10);
if (read_socket(ret,hapstr,10,xpms_set->lprintf) || memcmp(hapstr, "\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A", 10) != 0) {
btox(haphex,hapstr,6,sizeof(haphex), xpms_set->lprintf);
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Something went wrong [%s] incomplete v2 setup",ret,haphex);
closesocket(ret);
return INVALID_SOCKET;
}
// Command and Version
if (read_socket(ret,hapstr,1,xpms_set->lprintf)) {
btox(haphex,hapstr,1,sizeof(haphex), xpms_set->lprintf);
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY, looking for Verson/Command - failed [%s]",ret,haphex);
closesocket(ret);
return INVALID_SOCKET;
}
xpms_set->lprintf(LOG_DEBUG,"%04d * HAPROXY Version [%x]",ret,hapstr[0]&0x0f); //Should be 2
xpms_set->lprintf(LOG_DEBUG,"%04d * HAPROXY Command [%x]",ret,(hapstr[0]>>4)&0x0f); //0=Local/1=Proxy
// Protocol and Family
if (read_socket(ret,hapstr,1,xpms_set->lprintf)) {
btox(haphex,hapstr,1,sizeof(haphex), xpms_set->lprintf);
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY, looking for Protocol/Family - failed [%s]",ret,haphex);
closesocket(ret);
return INVALID_SOCKET;
}
xpms_set->lprintf(LOG_DEBUG,"%04d * HAPROXY Protocol [%x]",ret,hapstr[0]&0x0f); //0=Unspec/1=AF_INET/2=AF_INET6/3=AF_UNIX
l = (hapstr[0]>>4)&0x0f;
xpms_set->lprintf(LOG_DEBUG,"%04d * HAPROXY Family [%x]",ret,l); //0=UNSPEC/1=STREAM/2=DGRAM
// Address Length - 2 bytes
if (read_socket(ret,hapstr,2,xpms_set->lprintf)) {
btox(haphex,hapstr,2,sizeof(haphex), xpms_set->lprintf);
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY, looking for address length - failed [%s]",ret,haphex);
closesocket(ret);
return INVALID_SOCKET;
}
i = ntohs(*(uint16_t*)hapstr);
xpms_set->lprintf(LOG_DEBUG,"%04d * HAPROXY Address Length [%d]",ret,i);
switch (l) {
// IPv4 - AF_INET
case HAPROXY_AFINET:
if (i != 12) {