version 1.301, 2021/07/16 09:00:23 |
version 1.302, 2021/11/13 21:14:13 |
|
|
{ |
{ |
struct session_state *state = ssh->state; |
struct session_state *state = ssh->state; |
int len, r, ms_remain; |
int len, r, ms_remain; |
fd_set *setp; |
struct pollfd pfd; |
char buf[8192]; |
char buf[8192]; |
struct timeval timeout, start, *timeoutp = NULL; |
struct timeval start; |
|
struct timespec timespec, *timespecp = NULL; |
|
|
DBG(debug("packet_read()")); |
DBG(debug("packet_read()")); |
|
|
setp = calloc(howmany(state->connection_in + 1, |
|
NFDBITS), sizeof(fd_mask)); |
|
if (setp == NULL) |
|
return SSH_ERR_ALLOC_FAIL; |
|
|
|
/* |
/* |
* Since we are blocking, ensure that all written packets have |
* Since we are blocking, ensure that all written packets have |
* been sent. |
* been sent. |
|
|
* Otherwise, wait for some data to arrive, add it to the |
* Otherwise, wait for some data to arrive, add it to the |
* buffer, and try again. |
* buffer, and try again. |
*/ |
*/ |
memset(setp, 0, howmany(state->connection_in + 1, |
pfd.fd = state->connection_in; |
NFDBITS) * sizeof(fd_mask)); |
pfd.events = POLLIN; |
FD_SET(state->connection_in, setp); |
|
|
|
if (state->packet_timeout_ms > 0) { |
if (state->packet_timeout_ms > 0) { |
ms_remain = state->packet_timeout_ms; |
ms_remain = state->packet_timeout_ms; |
timeoutp = &timeout; |
timespecp = ×pec; |
} |
} |
/* Wait for some data to arrive. */ |
/* Wait for some data to arrive. */ |
for (;;) { |
for (;;) { |
if (state->packet_timeout_ms > 0) { |
if (state->packet_timeout_ms > 0) { |
ms_to_timeval(&timeout, ms_remain); |
ms_to_timespec(×pec, ms_remain); |
monotime_tv(&start); |
monotime_tv(&start); |
} |
} |
if ((r = select(state->connection_in + 1, setp, |
if ((r = ppoll(&pfd, 1, timespecp, NULL)) >= 0) |
NULL, NULL, timeoutp)) >= 0) |
|
break; |
break; |
if (errno != EAGAIN && errno != EINTR) { |
if (errno != EAGAIN && errno != EINTR) { |
r = SSH_ERR_SYSTEM_ERROR; |
r = SSH_ERR_SYSTEM_ERROR; |
|
|
goto out; |
goto out; |
} |
} |
out: |
out: |
free(setp); |
|
return r; |
return r; |
} |
} |
|
|
|
|
int |
int |
ssh_packet_write_wait(struct ssh *ssh) |
ssh_packet_write_wait(struct ssh *ssh) |
{ |
{ |
fd_set *setp; |
|
int ret, r, ms_remain = 0; |
int ret, r, ms_remain = 0; |
struct timeval start, timeout, *timeoutp = NULL; |
struct timeval start; |
|
struct timespec timespec, *timespecp = NULL; |
struct session_state *state = ssh->state; |
struct session_state *state = ssh->state; |
|
struct pollfd pfd; |
|
|
setp = calloc(howmany(state->connection_out + 1, |
if ((r = ssh_packet_write_poll(ssh)) != 0) |
NFDBITS), sizeof(fd_mask)); |
|
if (setp == NULL) |
|
return SSH_ERR_ALLOC_FAIL; |
|
if ((r = ssh_packet_write_poll(ssh)) != 0) { |
|
free(setp); |
|
return r; |
return r; |
} |
|
while (ssh_packet_have_data_to_write(ssh)) { |
while (ssh_packet_have_data_to_write(ssh)) { |
memset(setp, 0, howmany(state->connection_out + 1, |
pfd.fd = state->connection_out; |
NFDBITS) * sizeof(fd_mask)); |
pfd.events = POLLOUT; |
FD_SET(state->connection_out, setp); |
|
|
|
if (state->packet_timeout_ms > 0) { |
if (state->packet_timeout_ms > 0) { |
ms_remain = state->packet_timeout_ms; |
ms_remain = state->packet_timeout_ms; |
timeoutp = &timeout; |
timespecp = ×pec; |
} |
} |
for (;;) { |
for (;;) { |
if (state->packet_timeout_ms > 0) { |
if (state->packet_timeout_ms > 0) { |
ms_to_timeval(&timeout, ms_remain); |
ms_to_timespec(×pec, ms_remain); |
monotime_tv(&start); |
monotime_tv(&start); |
} |
} |
if ((ret = select(state->connection_out + 1, |
if ((ret = ppoll(&pfd, 1, timespecp, NULL)) >= 0) |
NULL, setp, NULL, timeoutp)) >= 0) |
|
break; |
break; |
if (errno != EAGAIN && errno != EINTR) |
if (errno != EAGAIN && errno != EINTR) |
break; |
break; |
|
|
break; |
break; |
} |
} |
} |
} |
if (ret == 0) { |
if (ret == 0) |
free(setp); |
|
return SSH_ERR_CONN_TIMEOUT; |
return SSH_ERR_CONN_TIMEOUT; |
} |
if ((r = ssh_packet_write_poll(ssh)) != 0) |
if ((r = ssh_packet_write_poll(ssh)) != 0) { |
|
free(setp); |
|
return r; |
return r; |
} |
|
} |
} |
free(setp); |
|
return 0; |
return 0; |
} |
} |
|
|