version 1.316, 2012/03/29 23:54:36 |
version 1.317, 2012/04/11 13:16:19 |
|
|
c->istate = CHAN_INPUT_OPEN; |
c->istate = CHAN_INPUT_OPEN; |
c->flags = 0; |
c->flags = 0; |
channel_register_fds(c, rfd, wfd, efd, extusage, nonblock, 0); |
channel_register_fds(c, rfd, wfd, efd, extusage, nonblock, 0); |
|
c->notbefore = 0; |
c->self = found; |
c->self = found; |
c->type = type; |
c->type = type; |
c->ctype = ctype; |
c->ctype = ctype; |
|
|
} |
} |
if (newsock < 0) { |
if (newsock < 0) { |
error("accept: %.100s", strerror(errno)); |
error("accept: %.100s", strerror(errno)); |
|
if (errno == EMFILE || errno == ENFILE) |
|
c->notbefore = time(NULL) + 1; |
return; |
return; |
} |
} |
set_nodelay(newsock); |
set_nodelay(newsock); |
|
|
newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); |
newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); |
if (newsock < 0) { |
if (newsock < 0) { |
error("accept: %.100s", strerror(errno)); |
error("accept: %.100s", strerror(errno)); |
|
if (errno == EMFILE || errno == ENFILE) |
|
c->notbefore = time(NULL) + 1; |
return; |
return; |
} |
} |
set_nodelay(newsock); |
set_nodelay(newsock); |
|
|
addrlen = sizeof(addr); |
addrlen = sizeof(addr); |
newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); |
newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); |
if (newsock < 0) { |
if (newsock < 0) { |
error("accept from auth socket: %.100s", strerror(errno)); |
error("accept from auth socket: %.100s", |
|
strerror(errno)); |
|
if (errno == EMFILE || errno == ENFILE) |
|
c->notbefore = time(NULL) + 1; |
return; |
return; |
} |
} |
nc = channel_new("accepted auth socket", |
nc = channel_new("accepted auth socket", |
|
|
if ((newsock = accept(c->sock, (struct sockaddr*)&addr, |
if ((newsock = accept(c->sock, (struct sockaddr*)&addr, |
&addrlen)) == -1) { |
&addrlen)) == -1) { |
error("%s accept: %s", __func__, strerror(errno)); |
error("%s accept: %s", __func__, strerror(errno)); |
|
if (errno == EMFILE || errno == ENFILE) |
|
c->notbefore = time(NULL) + 1; |
return; |
return; |
} |
} |
|
|
|
|
} |
} |
|
|
static void |
static void |
channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset) |
channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset, |
|
time_t *unpause_secs) |
{ |
{ |
static int did_init = 0; |
static int did_init = 0; |
u_int i, oalloc; |
u_int i, oalloc; |
Channel *c; |
Channel *c; |
|
time_t now; |
|
|
if (!did_init) { |
if (!did_init) { |
channel_handler_init(); |
channel_handler_init(); |
did_init = 1; |
did_init = 1; |
} |
} |
|
now = time(NULL); |
|
if (unpause_secs != NULL) |
|
*unpause_secs = 0; |
for (i = 0, oalloc = channels_alloc; i < oalloc; i++) { |
for (i = 0, oalloc = channels_alloc; i < oalloc; i++) { |
c = channels[i]; |
c = channels[i]; |
if (c == NULL) |
if (c == NULL) |
|
|
else |
else |
continue; |
continue; |
} |
} |
if (ftab[c->type] != NULL) |
if (ftab[c->type] != NULL) { |
(*ftab[c->type])(c, readset, writeset); |
/* |
|
* Run handlers that are not paused. |
|
*/ |
|
if (c->notbefore <= now) |
|
(*ftab[c->type])(c, readset, writeset); |
|
else if (unpause_secs != NULL) { |
|
/* |
|
* Collect the time that the earliest |
|
* channel comes off pause. |
|
*/ |
|
debug3("%s: chan %d: skip for %d more seconds", |
|
__func__, c->self, |
|
(int)(c->notbefore - now)); |
|
if (*unpause_secs == 0 || |
|
(c->notbefore - now) < *unpause_secs) |
|
*unpause_secs = c->notbefore - now; |
|
} |
|
} |
channel_garbage_collect(c); |
channel_garbage_collect(c); |
} |
} |
|
if (unpause_secs != NULL && *unpause_secs != 0) |
|
debug3("%s: first channel unpauses in %d seconds", |
|
__func__, (int)*unpause_secs); |
} |
} |
|
|
/* |
/* |
|
|
*/ |
*/ |
void |
void |
channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, |
channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, |
u_int *nallocp, int rekeying) |
u_int *nallocp, int *minwait_secs, int rekeying) |
{ |
{ |
u_int n, sz, nfdset; |
u_int n, sz, nfdset; |
|
|
|
|
memset(*writesetp, 0, sz); |
memset(*writesetp, 0, sz); |
|
|
if (!rekeying) |
if (!rekeying) |
channel_handler(channel_pre, *readsetp, *writesetp); |
channel_handler(channel_pre, *readsetp, *writesetp, |
|
minwait_secs); |
} |
} |
|
|
/* |
/* |
|
|
void |
void |
channel_after_select(fd_set *readset, fd_set *writeset) |
channel_after_select(fd_set *readset, fd_set *writeset) |
{ |
{ |
channel_handler(channel_post, readset, writeset); |
channel_handler(channel_post, readset, writeset, NULL); |
} |
} |
|
|
|
|