mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-11 09:16:59 +08:00
cstp_recv_nb: improve operation under receiving from UNIX socket
That is, ensure that all possible packet size combinations are correctly received. Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
This commit is contained in:
committed by
Nikos Mavrogiannopoulos
parent
aa28f0b9d2
commit
409f114d9e
86
src/tlslib.c
86
src/tlslib.c
@@ -190,6 +190,33 @@ ssize_t cstp_recv(worker_st *ws, void *data, size_t data_size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
int recv_remaining(int fd, uint8_t *p, int left)
|
||||
{
|
||||
int counter = 100; /* allow 10 seconds for a full packet */
|
||||
unsigned total = 0;
|
||||
int ret;
|
||||
|
||||
while(left > 0) {
|
||||
ret = recv(fd, p, left, 0);
|
||||
if (ret == -1 && counter > 0 && (errno == EINTR || errno == EAGAIN)) {
|
||||
counter--;
|
||||
ms_sleep(100);
|
||||
continue;
|
||||
}
|
||||
if (ret == 0)
|
||||
ret = GNUTLS_E_PREMATURE_TERMINATION;
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
left -= ret;
|
||||
p += ret;
|
||||
total += ret;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
ssize_t cstp_recv_nb(worker_st *ws, void *data, size_t data_size)
|
||||
{
|
||||
int ret;
|
||||
@@ -203,45 +230,46 @@ ssize_t cstp_recv_nb(worker_st *ws, void *data, size_t data_size)
|
||||
* incomplete CSTP packet. In that case we attempt to read
|
||||
* a full CSTP packet.
|
||||
*/
|
||||
int counter = 100; /* allow 10 seconds for a full packet */
|
||||
unsigned pktlen;
|
||||
unsigned total = 0;
|
||||
int left = data_size;
|
||||
uint8_t *p = data;
|
||||
|
||||
ret = recv(ws->conn_fd, p, left, 0);
|
||||
if (ret > 6) {
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
if (ret < 8) {
|
||||
/* ensure we have the CSTP header */
|
||||
p += ret;
|
||||
left = 8 - ret;
|
||||
|
||||
ret = recv_remaining(ws->conn_fd, p, left);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
total = 8;
|
||||
p += 8;
|
||||
} else {
|
||||
total += ret;
|
||||
/* get the actual length from headers */
|
||||
pktlen = (p[4] << 8) + p[5];
|
||||
if (pktlen+8 > data_size) {
|
||||
oclog(ws, LOG_ERR, "error in CSTP packet length");
|
||||
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
|
||||
}
|
||||
|
||||
p = p + ret;
|
||||
left = pktlen+8 - ret;
|
||||
|
||||
while(left > 0) {
|
||||
ret = recv(ws->conn_fd, p, left, 0);
|
||||
if (ret == -1 && counter > 0 && (errno == EINTR || errno == EAGAIN)) {
|
||||
counter--;
|
||||
ms_sleep(100);
|
||||
continue;
|
||||
}
|
||||
if (ret == 0)
|
||||
ret = GNUTLS_E_PREMATURE_TERMINATION;
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
left -= ret;
|
||||
p += ret;
|
||||
total += ret;
|
||||
}
|
||||
p += ret;
|
||||
}
|
||||
|
||||
ret = total;
|
||||
/* get the actual length from headers */
|
||||
pktlen = (p[4] << 8) + p[5];
|
||||
if (pktlen+8 > data_size) {
|
||||
oclog(ws, LOG_ERR, "error in CSTP packet length");
|
||||
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
|
||||
}
|
||||
|
||||
left = pktlen+8 - total;
|
||||
|
||||
ret = recv_remaining(ws->conn_fd, p, left);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
total += ret;
|
||||
ret = total;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
Reference in New Issue
Block a user