|
Lines 2475-2484
dump_channel_poll(const char *func, const char *what, Channel *c,
Link Here
|
| 2475 |
u_int pollfd_offset, struct pollfd *pfd) |
2475 |
u_int pollfd_offset, struct pollfd *pfd) |
| 2476 |
{ |
2476 |
{ |
| 2477 |
#ifdef DEBUG_CHANNEL_POLL |
2477 |
#ifdef DEBUG_CHANNEL_POLL |
| 2478 |
debug3_f("channel %d: rfd r%d w%d e%d s%d " |
2478 |
debug3("%s: channel %d: rfd r%d w%d e%d s%d pfd[%u].fd=%d %s " |
| 2479 |
"pfd[%u].fd=%d want 0x%02x ev 0x%02x ready 0x%02x rev 0x%02x", |
2479 |
"io_want 0x%02x pfd.ev 0x%02x io_ready 0x%02x pfd.rev 0x%02x " |
| 2480 |
c->self, c->rfd, c->wfd, c->efd, c->sock, pollfd_offset, pfd->fd, |
2480 |
"pfds [ %d %d %d %d ]", func, c->self, |
| 2481 |
c->io_want, pfd->events, c->io_ready, pfd->revents); |
2481 |
c->rfd, c->wfd, c->efd, c->sock, |
|
|
2482 |
pollfd_offset, pfd->fd, what, |
| 2483 |
c->io_want, pfd->events, c->io_ready, pfd->revents, |
| 2484 |
c->pfds[0], c->pfds[1], c->pfds[2], c->pfds[3]); |
| 2482 |
#endif |
2485 |
#endif |
| 2483 |
} |
2486 |
} |
| 2484 |
|
2487 |
|
|
Lines 2487-2493
static void
Link Here
|
| 2487 |
channel_prepare_pollfd(Channel *c, u_int *next_pollfd, |
2490 |
channel_prepare_pollfd(Channel *c, u_int *next_pollfd, |
| 2488 |
struct pollfd *pfd, u_int npfd) |
2491 |
struct pollfd *pfd, u_int npfd) |
| 2489 |
{ |
2492 |
{ |
| 2490 |
u_int p = *next_pollfd; |
2493 |
u_int ev, p = *next_pollfd; |
| 2491 |
|
2494 |
|
| 2492 |
if (c == NULL) |
2495 |
if (c == NULL) |
| 2493 |
return; |
2496 |
return; |
|
Lines 2496-2502
channel_prepare_pollfd(Channel *c, u_int *next_pollfd,
Link Here
|
| 2496 |
fatal_f("channel %d: bad pfd offset %u (max %u)", |
2499 |
fatal_f("channel %d: bad pfd offset %u (max %u)", |
| 2497 |
c->self, p, npfd); |
2500 |
c->self, p, npfd); |
| 2498 |
} |
2501 |
} |
| 2499 |
c->pollfd_offset = -1; |
2502 |
c->pfds[0] = c->pfds[1] = c->pfds[2] = c->pfds[3] = -1; |
| 2500 |
/* |
2503 |
/* |
| 2501 |
* prepare c->rfd |
2504 |
* prepare c->rfd |
| 2502 |
* |
2505 |
* |
|
Lines 2505-2573
channel_prepare_pollfd(Channel *c, u_int *next_pollfd,
Link Here
|
| 2505 |
* IO too. |
2508 |
* IO too. |
| 2506 |
*/ |
2509 |
*/ |
| 2507 |
if (c->rfd != -1) { |
2510 |
if (c->rfd != -1) { |
| 2508 |
if (c->pollfd_offset == -1) |
2511 |
ev = 0; |
| 2509 |
c->pollfd_offset = p; |
|
|
| 2510 |
pfd[p].fd = c->rfd; |
| 2511 |
pfd[p].events = 0; |
| 2512 |
if ((c->io_want & SSH_CHAN_IO_RFD) != 0) |
2512 |
if ((c->io_want & SSH_CHAN_IO_RFD) != 0) |
| 2513 |
pfd[p].events |= POLLIN; |
2513 |
ev |= POLLIN; |
| 2514 |
/* rfd == wfd */ |
2514 |
/* rfd == wfd */ |
| 2515 |
if (c->wfd == c->rfd && |
2515 |
if (c->wfd == c->rfd) { |
| 2516 |
(c->io_want & SSH_CHAN_IO_WFD) != 0) |
2516 |
if ((c->io_want & SSH_CHAN_IO_WFD) != 0) |
| 2517 |
pfd[p].events |= POLLOUT; |
2517 |
ev |= POLLOUT; |
|
|
2518 |
} |
| 2518 |
/* rfd == efd */ |
2519 |
/* rfd == efd */ |
| 2519 |
if (c->efd == c->rfd && |
2520 |
if (c->efd == c->rfd) { |
| 2520 |
(c->io_want & SSH_CHAN_IO_EFD_R) != 0) |
2521 |
if ((c->io_want & SSH_CHAN_IO_EFD_R) != 0) |
| 2521 |
pfd[p].events |= POLLIN; |
2522 |
ev |= POLLIN; |
| 2522 |
if (c->efd == c->rfd && |
2523 |
if ((c->io_want & SSH_CHAN_IO_EFD_W) != 0) |
| 2523 |
(c->io_want & SSH_CHAN_IO_EFD_W) != 0) |
2524 |
ev |= POLLOUT; |
| 2524 |
pfd[p].events |= POLLOUT; |
2525 |
} |
| 2525 |
/* rfd == sock */ |
2526 |
/* rfd == sock */ |
| 2526 |
if (c->sock == c->rfd && |
2527 |
if (c->sock == c->rfd) { |
| 2527 |
(c->io_want & SSH_CHAN_IO_SOCK_R) != 0) |
2528 |
if ((c->io_want & SSH_CHAN_IO_SOCK_R) != 0) |
| 2528 |
pfd[p].events |= POLLIN; |
2529 |
ev |= POLLIN; |
| 2529 |
if (c->sock == c->rfd && |
2530 |
if ((c->io_want & SSH_CHAN_IO_SOCK_W) != 0) |
| 2530 |
(c->io_want & SSH_CHAN_IO_SOCK_W) != 0) |
2531 |
ev |= POLLOUT; |
| 2531 |
pfd[p].events |= POLLOUT; |
2532 |
} |
| 2532 |
dump_channel_poll(__func__, "rfd", c, p, &pfd[p]); |
2533 |
/* Pack a pfd entry if any event armed for this fd */ |
| 2533 |
p++; |
2534 |
if (ev != 0) { |
|
|
2535 |
c->pfds[0] = p; |
| 2536 |
pfd[p].fd = c->rfd; |
| 2537 |
pfd[p].events = ev; |
| 2538 |
dump_channel_poll(__func__, "rfd", c, p, &pfd[p]); |
| 2539 |
p++; |
| 2540 |
} |
| 2534 |
} |
2541 |
} |
| 2535 |
/* prepare c->wfd (if not already handled above) */ |
2542 |
/* prepare c->wfd if wanting IO and not already handled above */ |
| 2536 |
if (c->wfd != -1 && c->rfd != c->wfd) { |
2543 |
if (c->wfd != -1 && c->rfd != c->wfd) { |
| 2537 |
if (c->pollfd_offset == -1) |
2544 |
ev = 0; |
| 2538 |
c->pollfd_offset = p; |
2545 |
if ((c->io_want & SSH_CHAN_IO_WFD)) |
| 2539 |
pfd[p].fd = c->wfd; |
2546 |
ev |= POLLOUT; |
| 2540 |
pfd[p].events = 0; |
2547 |
/* Pack a pfd entry if any event armed for this fd */ |
| 2541 |
if ((c->io_want & SSH_CHAN_IO_WFD) != 0) |
2548 |
if (ev != 0) { |
| 2542 |
pfd[p].events = POLLOUT; |
2549 |
c->pfds[1] = p; |
| 2543 |
dump_channel_poll(__func__, "wfd", c, p, &pfd[p]); |
2550 |
pfd[p].fd = c->wfd; |
| 2544 |
p++; |
2551 |
pfd[p].events = ev; |
|
|
2552 |
dump_channel_poll(__func__, "wfd", c, p, &pfd[p]); |
| 2553 |
p++; |
| 2554 |
} |
| 2545 |
} |
2555 |
} |
| 2546 |
/* prepare c->efd (if not already handled above) */ |
2556 |
/* prepare c->efd if wanting IO and not already handled above */ |
| 2547 |
if (c->efd != -1 && c->rfd != c->efd) { |
2557 |
if (c->efd != -1 && c->rfd != c->efd) { |
| 2548 |
if (c->pollfd_offset == -1) |
2558 |
ev = 0; |
| 2549 |
c->pollfd_offset = p; |
|
|
| 2550 |
pfd[p].fd = c->efd; |
| 2551 |
pfd[p].events = 0; |
| 2552 |
if ((c->io_want & SSH_CHAN_IO_EFD_R) != 0) |
2559 |
if ((c->io_want & SSH_CHAN_IO_EFD_R) != 0) |
| 2553 |
pfd[p].events |= POLLIN; |
2560 |
ev |= POLLIN; |
| 2554 |
if ((c->io_want & SSH_CHAN_IO_EFD_W) != 0) |
2561 |
if ((c->io_want & SSH_CHAN_IO_EFD_W) != 0) |
| 2555 |
pfd[p].events |= POLLOUT; |
2562 |
ev |= POLLOUT; |
| 2556 |
dump_channel_poll(__func__, "efd", c, p, &pfd[p]); |
2563 |
/* Pack a pfd entry if any event armed for this fd */ |
| 2557 |
p++; |
2564 |
if (ev != 0) { |
|
|
2565 |
c->pfds[2] = p; |
| 2566 |
pfd[p].fd = c->efd; |
| 2567 |
pfd[p].events = ev; |
| 2568 |
dump_channel_poll(__func__, "efd", c, p, &pfd[p]); |
| 2569 |
p++; |
| 2570 |
} |
| 2558 |
} |
2571 |
} |
| 2559 |
/* prepare c->sock (if not already handled above) */ |
2572 |
/* prepare c->sock if wanting IO and not already handled above */ |
| 2560 |
if (c->sock != -1 && c->rfd != c->sock) { |
2573 |
if (c->sock != -1 && c->rfd != c->sock) { |
| 2561 |
if (c->pollfd_offset == -1) |
2574 |
ev = 0; |
| 2562 |
c->pollfd_offset = p; |
|
|
| 2563 |
pfd[p].fd = c->sock; |
| 2564 |
pfd[p].events = 0; |
| 2565 |
if ((c->io_want & SSH_CHAN_IO_SOCK_R) != 0) |
2575 |
if ((c->io_want & SSH_CHAN_IO_SOCK_R) != 0) |
| 2566 |
pfd[p].events |= POLLIN; |
2576 |
ev |= POLLIN; |
| 2567 |
if ((c->io_want & SSH_CHAN_IO_SOCK_W) != 0) |
2577 |
if ((c->io_want & SSH_CHAN_IO_SOCK_W) != 0) |
| 2568 |
pfd[p].events |= POLLOUT; |
2578 |
ev |= POLLOUT; |
| 2569 |
dump_channel_poll(__func__, "sock", c, p, &pfd[p]); |
2579 |
/* Pack a pfd entry if any event armed for this fd */ |
| 2570 |
p++; |
2580 |
if (ev != 0) { |
|
|
2581 |
c->pfds[3] = p; |
| 2582 |
pfd[p].fd = c->sock; |
| 2583 |
pfd[p].events = 0; |
| 2584 |
dump_channel_poll(__func__, "sock", c, p, &pfd[p]); |
| 2585 |
p++; |
| 2586 |
} |
| 2571 |
} |
2587 |
} |
| 2572 |
*next_pollfd = p; |
2588 |
*next_pollfd = p; |
| 2573 |
} |
2589 |
} |
|
Lines 2614-2626
channel_prepare_poll(struct ssh *ssh, struct pollfd **pfdp, u_int *npfd_allocp,
Link Here
|
| 2614 |
} |
2630 |
} |
| 2615 |
|
2631 |
|
| 2616 |
static void |
2632 |
static void |
| 2617 |
fd_ready(Channel *c, u_int p, struct pollfd *pfds, int fd, |
2633 |
fd_ready(Channel *c, int p, struct pollfd *pfds, u_int npfd, int fd, |
| 2618 |
const char *what, u_int revents_mask, u_int ready) |
2634 |
const char *what, u_int revents_mask, u_int ready) |
| 2619 |
{ |
2635 |
{ |
| 2620 |
struct pollfd *pfd = &pfds[p]; |
2636 |
struct pollfd *pfd = &pfds[p]; |
| 2621 |
|
2637 |
|
| 2622 |
if (fd == -1) |
2638 |
if (fd == -1) |
| 2623 |
return; |
2639 |
return; |
|
|
2640 |
if (p == -1 || (u_int)p >= npfd) |
| 2641 |
fatal_f("channel %d: bad pfd %d (max %u)", c->self, p, npfd); |
| 2624 |
dump_channel_poll(__func__, what, c, p, pfd); |
2642 |
dump_channel_poll(__func__, what, c, p, pfd); |
| 2625 |
if (pfd->fd != fd) { |
2643 |
if (pfd->fd != fd) { |
| 2626 |
fatal("channel %d: inconsistent %s fd=%d pollfd[%u].fd %d " |
2644 |
fatal("channel %d: inconsistent %s fd=%d pollfd[%u].fd %d " |
|
Lines 2643-2649
void
Link Here
|
| 2643 |
channel_after_poll(struct ssh *ssh, struct pollfd *pfd, u_int npfd) |
2661 |
channel_after_poll(struct ssh *ssh, struct pollfd *pfd, u_int npfd) |
| 2644 |
{ |
2662 |
{ |
| 2645 |
struct ssh_channels *sc = ssh->chanctxt; |
2663 |
struct ssh_channels *sc = ssh->chanctxt; |
| 2646 |
u_int i, p; |
2664 |
u_int i; |
|
|
2665 |
int p; |
| 2647 |
Channel *c; |
2666 |
Channel *c; |
| 2648 |
|
2667 |
|
| 2649 |
#ifdef DEBUG_CHANNEL_POLL |
2668 |
#ifdef DEBUG_CHANNEL_POLL |
|
Lines 2658-2670
channel_after_poll(struct ssh *ssh, struct pollfd *pfd, u_int npfd)
Link Here
|
| 2658 |
/* Convert pollfd into c->io_ready */ |
2677 |
/* Convert pollfd into c->io_ready */ |
| 2659 |
for (i = 0; i < sc->channels_alloc; i++) { |
2678 |
for (i = 0; i < sc->channels_alloc; i++) { |
| 2660 |
c = sc->channels[i]; |
2679 |
c = sc->channels[i]; |
| 2661 |
if (c == NULL || c->pollfd_offset < 0) |
2680 |
if (c == NULL) |
| 2662 |
continue; |
2681 |
continue; |
| 2663 |
if ((u_int)c->pollfd_offset >= npfd) { |
|
|
| 2664 |
/* shouldn't happen */ |
| 2665 |
fatal_f("channel %d: (before) bad pfd %u (max %u)", |
| 2666 |
c->self, c->pollfd_offset, npfd); |
| 2667 |
} |
| 2668 |
/* if rfd is shared with efd/sock then wfd should be too */ |
2682 |
/* if rfd is shared with efd/sock then wfd should be too */ |
| 2669 |
if (c->rfd != -1 && c->wfd != -1 && c->rfd != c->wfd && |
2683 |
if (c->rfd != -1 && c->wfd != -1 && c->rfd != c->wfd && |
| 2670 |
(c->rfd == c->efd || c->rfd == c->sock)) { |
2684 |
(c->rfd == c->efd || c->rfd == c->sock)) { |
|
Lines 2673-2728
channel_after_poll(struct ssh *ssh, struct pollfd *pfd, u_int npfd)
Link Here
|
| 2673 |
c->self, c->rfd, c->wfd, c->efd, c->sock); |
2687 |
c->self, c->rfd, c->wfd, c->efd, c->sock); |
| 2674 |
} |
2688 |
} |
| 2675 |
c->io_ready = 0; |
2689 |
c->io_ready = 0; |
| 2676 |
p = c->pollfd_offset; |
|
|
| 2677 |
/* rfd, potentially shared with wfd, efd and sock */ |
2690 |
/* rfd, potentially shared with wfd, efd and sock */ |
| 2678 |
if (c->rfd != -1) { |
2691 |
if (c->rfd != -1 && (p = c->pfds[0]) != -1) { |
| 2679 |
fd_ready(c, p, pfd, c->rfd, "rfd", POLLIN, |
2692 |
fd_ready(c, p, pfd, npfd, c->rfd, |
| 2680 |
SSH_CHAN_IO_RFD); |
2693 |
"rfd", POLLIN, SSH_CHAN_IO_RFD); |
| 2681 |
if (c->rfd == c->wfd) { |
2694 |
if (c->rfd == c->wfd) { |
| 2682 |
fd_ready(c, p, pfd, c->wfd, "wfd/r", POLLOUT, |
2695 |
fd_ready(c, p, pfd, npfd, c->wfd, |
| 2683 |
SSH_CHAN_IO_WFD); |
2696 |
"wfd/r", POLLOUT, SSH_CHAN_IO_WFD); |
| 2684 |
} |
2697 |
} |
| 2685 |
if (c->rfd == c->efd) { |
2698 |
if (c->rfd == c->efd) { |
| 2686 |
fd_ready(c, p, pfd, c->efd, "efdr/r", POLLIN, |
2699 |
fd_ready(c, p, pfd, npfd, c->efd, |
| 2687 |
SSH_CHAN_IO_EFD_R); |
2700 |
"efdr/r", POLLIN, SSH_CHAN_IO_EFD_R); |
| 2688 |
fd_ready(c, p, pfd, c->efd, "efdw/r", POLLOUT, |
2701 |
fd_ready(c, p, pfd, npfd, c->efd, |
| 2689 |
SSH_CHAN_IO_EFD_W); |
2702 |
"efdw/r", POLLOUT, SSH_CHAN_IO_EFD_W); |
| 2690 |
} |
2703 |
} |
| 2691 |
if (c->rfd == c->sock) { |
2704 |
if (c->rfd == c->sock) { |
| 2692 |
fd_ready(c, p, pfd, c->sock, "sockr/r", POLLIN, |
2705 |
fd_ready(c, p, pfd, npfd, c->sock, |
| 2693 |
SSH_CHAN_IO_SOCK_R); |
2706 |
"sockr/r", POLLIN, SSH_CHAN_IO_SOCK_R); |
| 2694 |
fd_ready(c, p, pfd, c->sock, "sockw/r", POLLOUT, |
2707 |
fd_ready(c, p, pfd, npfd, c->sock, |
| 2695 |
SSH_CHAN_IO_SOCK_W); |
2708 |
"sockw/r", POLLOUT, SSH_CHAN_IO_SOCK_W); |
| 2696 |
} |
2709 |
} |
| 2697 |
p++; |
|
|
| 2698 |
} |
2710 |
} |
| 2699 |
/* wfd */ |
2711 |
/* wfd */ |
| 2700 |
if (c->wfd != -1 && c->wfd != c->rfd) { |
2712 |
if (c->wfd != -1 && c->wfd != c->rfd && |
| 2701 |
fd_ready(c, p, pfd, c->wfd, "wfd", POLLOUT, |
2713 |
(p = c->pfds[1]) != -1) { |
| 2702 |
SSH_CHAN_IO_WFD); |
2714 |
fd_ready(c, p, pfd, npfd, c->wfd, |
| 2703 |
p++; |
2715 |
"wfd", POLLOUT, SSH_CHAN_IO_WFD); |
| 2704 |
} |
2716 |
} |
| 2705 |
/* efd */ |
2717 |
/* efd */ |
| 2706 |
if (c->efd != -1 && c->efd != c->rfd) { |
2718 |
if (c->efd != -1 && c->efd != c->rfd && |
| 2707 |
fd_ready(c, p, pfd, c->efd, "efdr", POLLIN, |
2719 |
(p = c->pfds[2]) != -1) { |
| 2708 |
SSH_CHAN_IO_EFD_R); |
2720 |
fd_ready(c, p, pfd, npfd, c->efd, |
| 2709 |
fd_ready(c, p, pfd, c->efd, "efdw", POLLOUT, |
2721 |
"efdr", POLLIN, SSH_CHAN_IO_EFD_R); |
| 2710 |
SSH_CHAN_IO_EFD_W); |
2722 |
fd_ready(c, p, pfd, npfd, c->efd, |
| 2711 |
p++; |
2723 |
"efdw", POLLOUT, SSH_CHAN_IO_EFD_W); |
| 2712 |
} |
2724 |
} |
| 2713 |
/* sock */ |
2725 |
/* sock */ |
| 2714 |
if (c->sock != -1 && c->sock != c->rfd) { |
2726 |
if (c->sock != -1 && c->sock != c->rfd && |
| 2715 |
fd_ready(c, p, pfd, c->sock, "sockr", POLLIN, |
2727 |
(p = c->pfds[3]) != -1) { |
| 2716 |
SSH_CHAN_IO_SOCK_R); |
2728 |
fd_ready(c, p, pfd, npfd, c->sock, |
| 2717 |
fd_ready(c, p, pfd, c->sock, "sockw", POLLOUT, |
2729 |
"sockr", POLLIN, SSH_CHAN_IO_SOCK_R); |
| 2718 |
SSH_CHAN_IO_SOCK_W); |
2730 |
fd_ready(c, p, pfd, npfd, c->sock, |
| 2719 |
p++; |
2731 |
"sockw", POLLOUT, SSH_CHAN_IO_SOCK_W); |
| 2720 |
} |
|
|
| 2721 |
|
| 2722 |
if (p > npfd) { |
| 2723 |
/* shouldn't happen */ |
| 2724 |
fatal_f("channel %d: (after) bad pfd %u (max %u)", |
| 2725 |
c->self, c->pollfd_offset, npfd); |
| 2726 |
} |
2732 |
} |
| 2727 |
} |
2733 |
} |
| 2728 |
channel_handler(ssh, CHAN_POST, NULL); |
2734 |
channel_handler(ssh, CHAN_POST, NULL); |