summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c67
1 files changed, 58 insertions, 9 deletions
diff --git a/channels.c b/channels.c
index f6e9b4d8c..7791febd7 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.c,v 1.315 2011/09/23 07:45:05 markus Exp $ */ 1/* $OpenBSD: channels.c,v 1.318 2012/04/23 08:18:17 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -311,6 +311,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
311 c->istate = CHAN_INPUT_OPEN; 311 c->istate = CHAN_INPUT_OPEN;
312 c->flags = 0; 312 c->flags = 0;
313 channel_register_fds(c, rfd, wfd, efd, extusage, nonblock, 0); 313 channel_register_fds(c, rfd, wfd, efd, extusage, nonblock, 0);
314 c->notbefore = 0;
314 c->self = found; 315 c->self = found;
315 c->type = type; 316 c->type = type;
316 c->ctype = ctype; 317 c->ctype = ctype;
@@ -1339,6 +1340,8 @@ channel_post_x11_listener(Channel *c, fd_set *readset, fd_set *writeset)
1339 } 1340 }
1340 if (newsock < 0) { 1341 if (newsock < 0) {
1341 error("accept: %.100s", strerror(errno)); 1342 error("accept: %.100s", strerror(errno));
1343 if (errno == EMFILE || errno == ENFILE)
1344 c->notbefore = time(NULL) + 1;
1342 return; 1345 return;
1343 } 1346 }
1344 set_nodelay(newsock); 1347 set_nodelay(newsock);
@@ -1482,6 +1485,8 @@ channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset)
1482 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); 1485 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);
1483 if (newsock < 0) { 1486 if (newsock < 0) {
1484 error("accept: %.100s", strerror(errno)); 1487 error("accept: %.100s", strerror(errno));
1488 if (errno == EMFILE || errno == ENFILE)
1489 c->notbefore = time(NULL) + 1;
1485 return; 1490 return;
1486 } 1491 }
1487 set_nodelay(newsock); 1492 set_nodelay(newsock);
@@ -1514,7 +1519,10 @@ channel_post_auth_listener(Channel *c, fd_set *readset, fd_set *writeset)
1514 addrlen = sizeof(addr); 1519 addrlen = sizeof(addr);
1515 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); 1520 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);
1516 if (newsock < 0) { 1521 if (newsock < 0) {
1517 error("accept from auth socket: %.100s", strerror(errno)); 1522 error("accept from auth socket: %.100s",
1523 strerror(errno));
1524 if (errno == EMFILE || errno == ENFILE)
1525 c->notbefore = time(NULL) + 1;
1518 return; 1526 return;
1519 } 1527 }
1520 nc = channel_new("accepted auth socket", 1528 nc = channel_new("accepted auth socket",
@@ -1917,6 +1925,8 @@ channel_post_mux_listener(Channel *c, fd_set *readset, fd_set *writeset)
1917 if ((newsock = accept(c->sock, (struct sockaddr*)&addr, 1925 if ((newsock = accept(c->sock, (struct sockaddr*)&addr,
1918 &addrlen)) == -1) { 1926 &addrlen)) == -1) {
1919 error("%s accept: %s", __func__, strerror(errno)); 1927 error("%s accept: %s", __func__, strerror(errno));
1928 if (errno == EMFILE || errno == ENFILE)
1929 c->notbefore = time(NULL) + 1;
1920 return; 1930 return;
1921 } 1931 }
1922 1932
@@ -2067,16 +2077,21 @@ channel_garbage_collect(Channel *c)
2067} 2077}
2068 2078
2069static void 2079static void
2070channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset) 2080channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset,
2081 time_t *unpause_secs)
2071{ 2082{
2072 static int did_init = 0; 2083 static int did_init = 0;
2073 u_int i, oalloc; 2084 u_int i, oalloc;
2074 Channel *c; 2085 Channel *c;
2086 time_t now;
2075 2087
2076 if (!did_init) { 2088 if (!did_init) {
2077 channel_handler_init(); 2089 channel_handler_init();
2078 did_init = 1; 2090 did_init = 1;
2079 } 2091 }
2092 now = time(NULL);
2093 if (unpause_secs != NULL)
2094 *unpause_secs = 0;
2080 for (i = 0, oalloc = channels_alloc; i < oalloc; i++) { 2095 for (i = 0, oalloc = channels_alloc; i < oalloc; i++) {
2081 c = channels[i]; 2096 c = channels[i];
2082 if (c == NULL) 2097 if (c == NULL)
@@ -2087,10 +2102,30 @@ channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset)
2087 else 2102 else
2088 continue; 2103 continue;
2089 } 2104 }
2090 if (ftab[c->type] != NULL) 2105 if (ftab[c->type] != NULL) {
2091 (*ftab[c->type])(c, readset, writeset); 2106 /*
2107 * Run handlers that are not paused.
2108 */
2109 if (c->notbefore <= now)
2110 (*ftab[c->type])(c, readset, writeset);
2111 else if (unpause_secs != NULL) {
2112 /*
2113 * Collect the time that the earliest
2114 * channel comes off pause.
2115 */
2116 debug3("%s: chan %d: skip for %d more seconds",
2117 __func__, c->self,
2118 (int)(c->notbefore - now));
2119 if (*unpause_secs == 0 ||
2120 (c->notbefore - now) < *unpause_secs)
2121 *unpause_secs = c->notbefore - now;
2122 }
2123 }
2092 channel_garbage_collect(c); 2124 channel_garbage_collect(c);
2093 } 2125 }
2126 if (unpause_secs != NULL && *unpause_secs != 0)
2127 debug3("%s: first channel unpauses in %d seconds",
2128 __func__, (int)*unpause_secs);
2094} 2129}
2095 2130
2096/* 2131/*
@@ -2099,7 +2134,7 @@ channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset)
2099 */ 2134 */
2100void 2135void
2101channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, 2136channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
2102 u_int *nallocp, int rekeying) 2137 u_int *nallocp, time_t *minwait_secs, int rekeying)
2103{ 2138{
2104 u_int n, sz, nfdset; 2139 u_int n, sz, nfdset;
2105 2140
@@ -2122,7 +2157,8 @@ channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
2122 memset(*writesetp, 0, sz); 2157 memset(*writesetp, 0, sz);
2123 2158
2124 if (!rekeying) 2159 if (!rekeying)
2125 channel_handler(channel_pre, *readsetp, *writesetp); 2160 channel_handler(channel_pre, *readsetp, *writesetp,
2161 minwait_secs);
2126} 2162}
2127 2163
2128/* 2164/*
@@ -2132,7 +2168,7 @@ channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
2132void 2168void
2133channel_after_select(fd_set *readset, fd_set *writeset) 2169channel_after_select(fd_set *readset, fd_set *writeset)
2134{ 2170{
2135 channel_handler(channel_post, readset, writeset); 2171 channel_handler(channel_post, readset, writeset, NULL);
2136} 2172}
2137 2173
2138 2174
@@ -3127,6 +3163,17 @@ channel_add_adm_permitted_opens(char *host, int port)
3127} 3163}
3128 3164
3129void 3165void
3166channel_disable_adm_local_opens(void)
3167{
3168 if (num_adm_permitted_opens == 0) {
3169 permitted_adm_opens = xmalloc(sizeof(*permitted_adm_opens));
3170 permitted_adm_opens[num_adm_permitted_opens].host_to_connect
3171 = NULL;
3172 num_adm_permitted_opens = 1;
3173 }
3174}
3175
3176void
3130channel_clear_permitted_opens(void) 3177channel_clear_permitted_opens(void)
3131{ 3178{
3132 int i; 3179 int i;
@@ -3167,7 +3214,9 @@ channel_print_adm_permitted_opens(void)
3167 return; 3214 return;
3168 } 3215 }
3169 for (i = 0; i < num_adm_permitted_opens; i++) 3216 for (i = 0; i < num_adm_permitted_opens; i++)
3170 if (permitted_adm_opens[i].host_to_connect != NULL) 3217 if (permitted_adm_opens[i].host_to_connect == NULL)
3218 printf(" none");
3219 else
3171 printf(" %s:%d", permitted_adm_opens[i].host_to_connect, 3220 printf(" %s:%d", permitted_adm_opens[i].host_to_connect,
3172 permitted_adm_opens[i].port_to_connect); 3221 permitted_adm_opens[i].port_to_connect);
3173 printf("\n"); 3222 printf("\n");