View | Details | Raw Unified | Return to bug 3405
Collapse All | Expand All

(-)a/channels.c (-100 / +106 lines)
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);
(-)a/channels.h (-1 / +1 lines)
Lines 138-144 struct Channel { Link Here
138
	int     sock;		/* sock fd */
138
	int     sock;		/* sock fd */
139
	u_int	io_want;	/* bitmask of SSH_CHAN_IO_* */
139
	u_int	io_want;	/* bitmask of SSH_CHAN_IO_* */
140
	u_int	io_ready;	/* bitmask of SSH_CHAN_IO_* */
140
	u_int	io_ready;	/* bitmask of SSH_CHAN_IO_* */
141
	int	pollfd_offset;	/* base offset into pollfd array (or -1) */
141
	int	pfds[4];	/* pollfd entries for rfd/wfd/efd/sock */
142
	int     ctl_chan;	/* control channel (multiplexed connections) */
142
	int     ctl_chan;	/* control channel (multiplexed connections) */
143
	int     isatty;		/* rfd is a tty */
143
	int     isatty;		/* rfd is a tty */
144
#ifdef _AIX
144
#ifdef _AIX

Return to bug 3405