Skip to content
Snippets Groups Projects
Commit 85dcf5e5 authored by Deucе's avatar Deucе :ok_hand_tone4:
Browse files

Fix memory leaks and logic errors in multisock accept()

This likely unbreaks the things.
parent 5ca84955
No related branches found
No related tags found
1 merge request!463MRC mods by Codefenix (2024-10-20)
Pipeline #1597 passed
...@@ -379,8 +379,10 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr, ...@@ -379,8 +379,10 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr,
switch (poll(fds, scnt, poll_timeout)) { switch (poll(fds, scnt, poll_timeout)) {
case 0: case 0:
free(fds);
return INVALID_SOCKET; return INVALID_SOCKET;
case -1: case -1:
free(fds);
return SOCKET_ERROR; return SOCKET_ERROR;
default: default:
scnt = 0; scnt = 0;
...@@ -388,18 +390,20 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr, ...@@ -388,18 +390,20 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr,
if(xpms_set->socks[i].sock == INVALID_SOCKET) if(xpms_set->socks[i].sock == INVALID_SOCKET)
continue; continue;
if (fds[scnt].revents & (POLLERR | POLLNVAL)) { if (fds[scnt].revents & (POLLERR | POLLNVAL)) {
scnt++;
closesocket(xpms_set->socks[i].sock); closesocket(xpms_set->socks[i].sock);
xpms_set->lprintf(LOG_ERR, "%04d * Listening socket went bad", xpms_set->socks[i].sock); xpms_set->lprintf(LOG_ERR, "%04d * Listening socket went bad", xpms_set->socks[i].sock);
xpms_set->socks[i].sock = INVALID_SOCKET; xpms_set->socks[i].sock = INVALID_SOCKET;
continue; continue;
} }
else { if (fds[scnt++].revents & POLLIN) {
#endif #endif
if(cb_data) if(cb_data)
*cb_data=xpms_set->socks[i].cb_data; *cb_data=xpms_set->socks[i].cb_data;
ret = accept(xpms_set->socks[i].sock, &addr->addr, addrlen); ret = accept(xpms_set->socks[i].sock, &addr->addr, addrlen);
if (ret == INVALID_SOCKET) if (ret == INVALID_SOCKET) {
return ret; goto error_return;
}
// Set host_ip from haproxy protocol, if its used // Set host_ip from haproxy protocol, if its used
// http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt // http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt
...@@ -415,7 +419,7 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr, ...@@ -415,7 +419,7 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr,
btox(haphex,hapstr,strlen(hapstr),sizeof(haphex), xpms_set->lprintf); btox(haphex,hapstr,strlen(hapstr),sizeof(haphex), xpms_set->lprintf);
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY looking for version - failed [%s]",ret,haphex); xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY looking for version - failed [%s]",ret,haphex);
closesocket(ret); closesocket(ret);
return INVALID_SOCKET; goto error_return;
} }
btox(haphex,hapstr,strlen(hapstr)>16 ? 16 : strlen(hapstr),sizeof(haphex), xpms_set->lprintf); btox(haphex,hapstr,strlen(hapstr)>16 ? 16 : strlen(hapstr),sizeof(haphex), xpms_set->lprintf);
...@@ -447,7 +451,7 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr, ...@@ -447,7 +451,7 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr,
} else { } else {
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Unknown Protocol",ret); xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Unknown Protocol",ret);
closesocket(ret); closesocket(ret);
return INVALID_SOCKET; goto error_return;
} }
// Look for the space between the next IP // Look for the space between the next IP
...@@ -455,13 +459,13 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr, ...@@ -455,13 +459,13 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr,
if (p == NULL) { if (p == NULL) {
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Couldnt find IP address",ret); xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Couldnt find IP address",ret);
closesocket(ret); closesocket(ret);
return INVALID_SOCKET; goto error_return;
} }
*p = 0; *p = 0;
if (inet_pton(addr->addr.sa_family, tok, vp) != 1) { if (inet_pton(addr->addr.sa_family, tok, vp) != 1) {
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Unable to parse %s address [%s]",addr->addr.sa_family == AF_INET ? "IPv4" : "IPv6", tok); xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Unable to parse %s address [%s]",addr->addr.sa_family == AF_INET ? "IPv4" : "IPv6", tok);
closesocket(ret); closesocket(ret);
return INVALID_SOCKET; goto error_return;
} }
tok = p + 1; tok = p + 1;
// Look for the space before the port number // Look for the space before the port number
...@@ -469,14 +473,14 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr, ...@@ -469,14 +473,14 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr,
if (p == NULL) { if (p == NULL) {
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Couldnt find port",ret); xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Couldnt find port",ret);
closesocket(ret); closesocket(ret);
return INVALID_SOCKET; goto error_return;
} }
tok = p + 1; tok = p + 1;
l = strtol(tok, NULL, 10); l = strtol(tok, NULL, 10);
if (l <= 0 || l > UINT16_MAX) { if (l <= 0 || l > UINT16_MAX) {
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Source port out of range",ret); xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Source port out of range",ret);
closesocket(ret); closesocket(ret);
return INVALID_SOCKET; goto error_return;
} }
switch(addr->addr.sa_family) { switch(addr->addr.sa_family) {
case AF_INET: case AF_INET:
...@@ -498,7 +502,7 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr, ...@@ -498,7 +502,7 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr,
btox(haphex,hapstr,10,sizeof(haphex), xpms_set->lprintf); btox(haphex,hapstr,10,sizeof(haphex), xpms_set->lprintf);
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Something went wrong - incomplete v2 setup [%s]",ret,haphex); xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Something went wrong - incomplete v2 setup [%s]",ret,haphex);
closesocket(ret); closesocket(ret);
return INVALID_SOCKET; goto error_return;
} }
// Command and Version // Command and Version
...@@ -506,7 +510,7 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr, ...@@ -506,7 +510,7 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr,
btox(haphex,hapstr,1,sizeof(haphex), 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); xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY looking for Verson/Command - failed [%s]",ret,haphex);
closesocket(ret); closesocket(ret);
return INVALID_SOCKET; goto error_return;
} }
xpms_set->lprintf(LOG_DEBUG,"%04d * HAPROXY Version [%x]",ret,(hapstr[0]>>4)&0x0f); //Should be 2 xpms_set->lprintf(LOG_DEBUG,"%04d * HAPROXY Version [%x]",ret,(hapstr[0]>>4)&0x0f); //Should be 2
...@@ -517,7 +521,7 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr, ...@@ -517,7 +521,7 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr,
default: default:
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY invalid version [%x]",ret,(hapstr[0]>>4)&0x0f); xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY invalid version [%x]",ret,(hapstr[0]>>4)&0x0f);
closesocket(ret); closesocket(ret);
return INVALID_SOCKET; goto error_return;
} }
xpms_set->lprintf(LOG_DEBUG,"%04d * HAPROXY Command [%x]",ret,hapstr[0]&0x0f); //0=Local/1=Proxy xpms_set->lprintf(LOG_DEBUG,"%04d * HAPROXY Command [%x]",ret,hapstr[0]&0x0f); //0=Local/1=Proxy
...@@ -527,13 +531,13 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr, ...@@ -527,13 +531,13 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr,
case HAPROXY_LOCAL: case HAPROXY_LOCAL:
xpms_set->lprintf(LOG_INFO,"%04d * HAPROXY health check - we are alive!",ret); xpms_set->lprintf(LOG_INFO,"%04d * HAPROXY health check - we are alive!",ret);
closesocket(ret); closesocket(ret);
return INVALID_SOCKET; goto error_return;
case HAPROXY_PROXY: case HAPROXY_PROXY:
break; break;
default: default:
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY invalid command [%x]",ret,hapstr[0]&0x0f); xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY invalid command [%x]",ret,hapstr[0]&0x0f);
closesocket(ret); closesocket(ret);
return INVALID_SOCKET; goto error_return;
} }
// Protocol and Family // Protocol and Family
...@@ -541,7 +545,7 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr, ...@@ -541,7 +545,7 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr,
btox(haphex,hapstr,1,sizeof(haphex), 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); xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY looking for Protocol/Family - failed [%s]",ret,haphex);
closesocket(ret); closesocket(ret);
return INVALID_SOCKET; goto error_return;
} }
xpms_set->lprintf(LOG_DEBUG,"%04d * HAPROXY Protocol [%x]",ret,hapstr[0]&0x0f); //0=Unspec/1=AF_INET/2=AF_INET6/3=AF_UNIX 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; l = (hapstr[0]>>4)&0x0f;
...@@ -552,7 +556,7 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr, ...@@ -552,7 +556,7 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr,
btox(haphex,hapstr,2,sizeof(haphex), 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); xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY looking for address length - failed [%s]",ret,haphex);
closesocket(ret); closesocket(ret);
return INVALID_SOCKET; goto error_return;
} }
i = ntohs(*(uint16_t*)hapstr); i = ntohs(*(uint16_t*)hapstr);
xpms_set->lprintf(LOG_DEBUG,"%04d * HAPROXY Address Length [%d]",ret,i); xpms_set->lprintf(LOG_DEBUG,"%04d * HAPROXY Address Length [%d]",ret,i);
...@@ -563,13 +567,13 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr, ...@@ -563,13 +567,13 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr,
if (i != 12) { if (i != 12) {
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Something went wrong - IPv4 address length is incorrect",ret); xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Something went wrong - IPv4 address length is incorrect",ret);
closesocket(ret); closesocket(ret);
return INVALID_SOCKET; goto error_return;
} }
addr->in.sin_family = AF_INET; addr->in.sin_family = AF_INET;
if (read_socket(ret, hapstr, i, xpms_set->lprintf)==FALSE) { if (read_socket(ret, hapstr, i, xpms_set->lprintf)==FALSE) {
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY looking for IPv4 address - failed",ret); xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY looking for IPv4 address - failed",ret);
closesocket(ret); closesocket(ret);
return INVALID_SOCKET; goto error_return;
} }
memcpy(&addr->in.sin_addr.s_addr, hapstr, 4); memcpy(&addr->in.sin_addr.s_addr, hapstr, 4);
memcpy(&addr->in.sin_port, &hapstr[8], 2); memcpy(&addr->in.sin_port, &hapstr[8], 2);
...@@ -583,13 +587,13 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr, ...@@ -583,13 +587,13 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr,
if (i != 36) { if (i != 36) {
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Something went wrong - IPv6 address length is incorrect.",ret); xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Something went wrong - IPv6 address length is incorrect.",ret);
closesocket(ret); closesocket(ret);
return INVALID_SOCKET; goto error_return;
} }
addr->in6.sin6_family = AF_INET6; addr->in6.sin6_family = AF_INET6;
if (read_socket(ret,hapstr,i,xpms_set->lprintf)==FALSE) { if (read_socket(ret,hapstr,i,xpms_set->lprintf)==FALSE) {
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY looking for IPv6 address - failed",ret); xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY looking for IPv6 address - failed",ret);
closesocket(ret); closesocket(ret);
return INVALID_SOCKET; goto error_return;
} }
memcpy(&addr->in6.sin6_addr.s6_addr, hapstr, 16); memcpy(&addr->in6.sin6_addr.s6_addr, hapstr, 16);
memcpy(&addr->in6.sin6_port, &hapstr[32], 2); memcpy(&addr->in6.sin6_port, &hapstr[32], 2);
...@@ -601,26 +605,36 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr, ...@@ -601,26 +605,36 @@ SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr,
default: default:
xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Unknown Family [%x]",ret,l); xpms_set->lprintf(LOG_ERR,"%04d * HAPROXY Unknown Family [%x]",ret,l);
closesocket(ret); closesocket(ret);
return INVALID_SOCKET; goto error_return;
} }
} else { } else {
xpms_set->lprintf(LOG_ERR,"%04d Unknown HAProxy Initialisation - is HAProxy used?",ret); xpms_set->lprintf(LOG_ERR,"%04d Unknown HAProxy Initialisation - is HAProxy used?",ret);
closesocket(ret); closesocket(ret);
return INVALID_SOCKET; goto error_return;
} }
hapstr[0] = 0; hapstr[0] = 0;
inet_addrtop(addr, hapstr, sizeof(hapstr)); inet_addrtop(addr, hapstr, sizeof(hapstr));
xpms_set->lprintf(LOG_INFO,"%04d * HAPROXY Source [%s]",ret,hapstr); xpms_set->lprintf(LOG_INFO,"%04d * HAPROXY Source [%s]",ret,hapstr);
#ifndef _WIN32
free(fds);
#endif
return ret; return ret;
} else { } else {
#ifndef _WIN32
free(fds);
#endif
return ret; return ret;
} }
} }
} }
} }
error_return:
#ifndef _WIN32
free(fds);
#endif
return INVALID_SOCKET; return INVALID_SOCKET;
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment