|
Lines 161-166
Link Here
|
| 161 |
}; |
161 |
}; |
| 162 |
TAILQ_HEAD(, packet) outgoing; |
162 |
TAILQ_HEAD(, packet) outgoing; |
| 163 |
|
163 |
|
|
|
164 |
/* Idle timeout variables */ |
| 165 |
static time_t idletime_last=0; |
| 166 |
static int idletimeout=0; |
| 167 |
|
| 168 |
|
| 169 |
void |
| 170 |
packet_set_idletimeout(int max_idle_seconds) |
| 171 |
{ |
| 172 |
idletimeout=max_idle_seconds; |
| 173 |
if (max_idle_seconds>0) { |
| 174 |
/* Initialize */ |
| 175 |
time(&idletime_last); |
| 176 |
} |
| 177 |
} |
| 178 |
|
| 179 |
/* Called by whenever packets are sent or received. |
| 180 |
* This function decides on which packets idletimeout should |
| 181 |
* be reset */ |
| 182 |
void |
| 183 |
idletimeout_check(int type) |
| 184 |
{ |
| 185 |
/* No-op, if idletimeouts are not configured */ |
| 186 |
if (idletimeout==0) return; |
| 187 |
|
| 188 |
/* The following packets reset idletimeout on input or output. |
| 189 |
* Note that only actual data resets idletimeout, control packets |
| 190 |
* do not. */ |
| 191 |
if (compat20) { |
| 192 |
switch(type) { |
| 193 |
case SSH2_MSG_CHANNEL_DATA: |
| 194 |
case SSH2_MSG_CHANNEL_EXTENDED_DATA: |
| 195 |
time(&idletime_last); |
| 196 |
} |
| 197 |
} else { |
| 198 |
switch(type) { |
| 199 |
case SSH_MSG_CHANNEL_DATA: |
| 200 |
case SSH_CMSG_STDIN_DATA: |
| 201 |
case SSH_SMSG_STDOUT_DATA: |
| 202 |
case SSH_SMSG_STDERR_DATA: |
| 203 |
time(&idletime_last); |
| 204 |
} |
| 205 |
} |
| 206 |
} |
| 207 |
|
| 208 |
int |
| 209 |
packet_select(int maxfds, |
| 210 |
fd_set *readset, fd_set *writeset, fd_set *exceptset, |
| 211 |
int max_time_milliseconds) |
| 212 |
{ |
| 213 |
struct timeval tv, *tvp=NULL; |
| 214 |
int ret; |
| 215 |
|
| 216 |
if (idletimeout>0) { |
| 217 |
/* Count the time to idletimeout */ |
| 218 |
time_t diff=time(NULL)-idletime_last; |
| 219 |
if (diff>=idletimeout) |
| 220 |
tv.tv_sec=1; |
| 221 |
else |
| 222 |
tv.tv_sec=idletimeout-diff+1; |
| 223 |
tv.tv_usec=0; |
| 224 |
tvp = &tv; |
| 225 |
debug("idletimeout after %ld seconds",tv.tv_sec); |
| 226 |
} |
| 227 |
/* If a timeout value was given and the timeout happens before |
| 228 |
* idletimeout, use it */ |
| 229 |
if (max_time_milliseconds>0 && |
| 230 |
(tvp==NULL || max_time_milliseconds/1000<tv.tv_sec)) { |
| 231 |
tv.tv_sec = max_time_milliseconds / 1000; |
| 232 |
tv.tv_usec = 1000 * (max_time_milliseconds % 1000); |
| 233 |
tvp = &tv; |
| 234 |
debug("timeout after %d milliseconds",max_time_milliseconds); |
| 235 |
} |
| 236 |
if (tvp==NULL) debug("no timeout"); |
| 237 |
|
| 238 |
ret = select( maxfds, readset, writeset, exceptset, tvp ); |
| 239 |
if (ret<0 && errno!=EAGAIN && errno!=EINTR) { |
| 240 |
error("select: %.100s", strerror(errno)); |
| 241 |
} |
| 242 |
|
| 243 |
/* Disconnect on idletimeout */ |
| 244 |
if (idletimeout>0 && ret==0 && |
| 245 |
time(NULL)-idletime_last>idletimeout) { |
| 246 |
packet_disconnect("Idletimeout."); |
| 247 |
idletimeout=0; |
| 248 |
} |
| 249 |
return ret; |
| 250 |
} |
| 164 |
/* |
251 |
/* |
| 165 |
* Sets the descriptors used for communication. Disables encryption until |
252 |
* Sets the descriptors used for communication. Disables encryption until |
| 166 |
* packet_set_encryption_key is called. |
253 |
* packet_set_encryption_key is called. |
|
Lines 472-477
Link Here
|
| 472 |
int len; |
559 |
int len; |
| 473 |
|
560 |
|
| 474 |
DBG(debug("packet_start[%d]", type)); |
561 |
DBG(debug("packet_start[%d]", type)); |
|
|
562 |
|
| 563 |
idletimeout_check(type); |
| 564 |
|
| 475 |
len = compat20 ? 6 : 9; |
565 |
len = compat20 ? 6 : 9; |
| 476 |
memset(buf, 0, len - 1); |
566 |
memset(buf, 0, len - 1); |
| 477 |
buf[len - 1] = type; |
567 |
buf[len - 1] = type; |
|
Lines 833-838
Link Here
|
| 833 |
cp = buffer_ptr(&outgoing_packet); |
923 |
cp = buffer_ptr(&outgoing_packet); |
| 834 |
type = cp[5]; |
924 |
type = cp[5]; |
| 835 |
|
925 |
|
|
|
926 |
idletimeout_check(type); |
| 927 |
|
| 836 |
/* during rekeying we can only send key exchange messages */ |
928 |
/* during rekeying we can only send key exchange messages */ |
| 837 |
if (rekeying) { |
929 |
if (rekeying) { |
| 838 |
if (!((type >= SSH2_MSG_TRANSPORT_MIN) && |
930 |
if (!((type >= SSH2_MSG_TRANSPORT_MIN) && |
|
Lines 912-931
Link Here
|
| 912 |
/* If we got a packet, return it. */ |
1004 |
/* If we got a packet, return it. */ |
| 913 |
if (type != SSH_MSG_NONE) { |
1005 |
if (type != SSH_MSG_NONE) { |
| 914 |
xfree(setp); |
1006 |
xfree(setp); |
|
|
1007 |
idletimeout_check(type); |
| 915 |
return type; |
1008 |
return type; |
| 916 |
} |
1009 |
} |
| 917 |
/* |
1010 |
/* |
| 918 |
* Otherwise, wait for some data to arrive, add it to the |
1011 |
* Otherwise, wait for some data to arrive, add it to the |
| 919 |
* buffer, and try again. |
1012 |
* buffer, and try again. |
| 920 |
*/ |
1013 |
*/ |
| 921 |
memset(setp, 0, howmany(connection_in + 1, NFDBITS) * |
1014 |
do { |
| 922 |
sizeof(fd_mask)); |
1015 |
memset(setp, 0, howmany(connection_in + 1, NFDBITS) * |
| 923 |
FD_SET(connection_in, setp); |
1016 |
sizeof(fd_mask)); |
| 924 |
|
1017 |
FD_SET(connection_in, setp); |
| 925 |
/* Wait for some data to arrive. */ |
1018 |
|
| 926 |
while (select(connection_in + 1, setp, NULL, NULL, NULL) == -1 && |
1019 |
/* Wait for some data to arrive. */ |
| 927 |
(errno == EAGAIN || errno == EINTR)) |
1020 |
} while (packet_select(connection_in + 1, |
| 928 |
; |
1021 |
setp, NULL, NULL, 0) == -1); |
| 929 |
|
1022 |
|
| 930 |
/* Read data from the socket. */ |
1023 |
/* Read data from the socket. */ |
| 931 |
len = read(connection_in, buf, sizeof(buf)); |
1024 |
len = read(connection_in, buf, sizeof(buf)); |
|
Lines 1446-1457
Link Here
|
| 1446 |
sizeof(fd_mask)); |
1539 |
sizeof(fd_mask)); |
| 1447 |
packet_write_poll(); |
1540 |
packet_write_poll(); |
| 1448 |
while (packet_have_data_to_write()) { |
1541 |
while (packet_have_data_to_write()) { |
| 1449 |
memset(setp, 0, howmany(connection_out + 1, NFDBITS) * |
1542 |
do { |
| 1450 |
sizeof(fd_mask)); |
1543 |
memset(setp, 0, howmany(connection_out + 1, NFDBITS) * |
| 1451 |
FD_SET(connection_out, setp); |
1544 |
sizeof(fd_mask)); |
| 1452 |
while (select(connection_out + 1, NULL, setp, NULL, NULL) == -1 && |
1545 |
FD_SET(connection_out, setp); |
| 1453 |
(errno == EAGAIN || errno == EINTR)) |
1546 |
} while (packet_select(connection_out + 1, |
| 1454 |
; |
1547 |
NULL, setp, NULL, 0) == -1); |
| 1455 |
packet_write_poll(); |
1548 |
packet_write_poll(); |
| 1456 |
} |
1549 |
} |
| 1457 |
xfree(setp); |
1550 |
xfree(setp); |