[BACK]Return to channels.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/channels.c between version 1.425 and 1.426

version 1.425, 2023/01/06 02:42:34 version 1.426, 2023/01/06 02:47:18
Line 143 
Line 143 
         int all_permitted;          int all_permitted;
 };  };
   
   /* Used to record timeouts per channel type */
   struct ssh_channel_timeout {
           char *type_pattern;
           u_int timeout_secs;
   };
   
 /* Master structure for channels state */  /* Master structure for channels state */
 struct ssh_channels {  struct ssh_channels {
         /*          /*
Line 196 
Line 202 
   
         /* AF_UNSPEC or AF_INET or AF_INET6 */          /* AF_UNSPEC or AF_INET or AF_INET6 */
         int IPv4or6;          int IPv4or6;
   
           /* Channel timeouts by type */
           struct ssh_channel_timeout *timeouts;
           size_t ntimeouts;
 };  };
   
 /* helper */  /* helper */
Line 289 
Line 299 
 }  }
   
 /*  /*
    * Add a timeout for open channels whose c->ctype (or c->xctype if it is set)
    * match type_pattern.
    */
   void
   channel_add_timeout(struct ssh *ssh, const char *type_pattern,
       u_int timeout_secs)
   {
           struct ssh_channels *sc = ssh->chanctxt;
   
           debug2_f("channel type \"%s\" timeout %u seconds",
               type_pattern, timeout_secs);
           sc->timeouts = xrecallocarray(sc->timeouts, sc->ntimeouts,
               sc->ntimeouts + 1, sizeof(*sc->timeouts));
           sc->timeouts[sc->ntimeouts].type_pattern = xstrdup(type_pattern);
           sc->timeouts[sc->ntimeouts].timeout_secs = timeout_secs;
           sc->ntimeouts++;
   }
   
   /* Clears all previously-added channel timeouts */
   void
   channel_clear_timeouts(struct ssh *ssh)
   {
           struct ssh_channels *sc = ssh->chanctxt;
           size_t i;
   
           debug3_f("clearing");
           for (i = 0; i < sc->ntimeouts; i++)
                   free(sc->timeouts[i].type_pattern);
           free(sc->timeouts);
           sc->timeouts = NULL;
           sc->ntimeouts = 0;
   }
   
   static u_int
   lookup_timeout(struct ssh *ssh, const char *type)
   {
           struct ssh_channels *sc = ssh->chanctxt;
           size_t i;
   
           for (i = 0; i < sc->ntimeouts; i++) {
                   if (match_pattern(type, sc->timeouts[i].type_pattern))
                           return sc->timeouts[i].timeout_secs;
           }
   
           return 0;
   }
   
   /*
  * Sets "extended type" of a channel; used by session layer to add additional   * Sets "extended type" of a channel; used by session layer to add additional
  * information about channel types (e.g. shell, login, subsystem) that can then   * information about channel types (e.g. shell, login, subsystem) that can then
  * be used to select timeouts.   * be used to select timeouts.
    * Will reset c->inactive_deadline as a side-effect.
  */   */
 void  void
 channel_set_xtype(struct ssh *ssh, int id, const char *xctype)  channel_set_xtype(struct ssh *ssh, int id, const char *xctype)
Line 303 
Line 362 
         if (c->xctype != NULL)          if (c->xctype != NULL)
                 free(c->xctype);                  free(c->xctype);
         c->xctype = xstrdup(xctype);          c->xctype = xstrdup(xctype);
         debug2_f("labeled channel %d as %s", id, xctype);          /* Type has changed, so look up inactivity deadline again */
           c->inactive_deadline = lookup_timeout(ssh, c->xctype);
           debug2_f("labeled channel %d as %s (inactive timeout %u)", id, xctype,
               c->inactive_deadline);
 }  }
   
 /*  /*
Line 421 
Line 483 
         c->remote_name = xstrdup(remote_name);          c->remote_name = xstrdup(remote_name);
         c->ctl_chan = -1;          c->ctl_chan = -1;
         c->delayed = 1;         /* prevent call to channel_post handler */          c->delayed = 1;         /* prevent call to channel_post handler */
           c->inactive_deadline = lookup_timeout(ssh, c->ctype);
         TAILQ_INIT(&c->status_confirms);          TAILQ_INIT(&c->status_confirms);
         debug("channel %d: new [%s]", found, remote_name);          debug("channel %d: new %s [%s] (inactive timeout: %u)",
               found, c->ctype, remote_name, c->inactive_deadline);
         return c;          return c;
 }  }
   
Line 1095 
Line 1159 
   
         channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, is_tty);          channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, is_tty);
         c->type = SSH_CHANNEL_OPEN;          c->type = SSH_CHANNEL_OPEN;
           c->lastused = monotime();
         c->local_window = c->local_window_max = window_max;          c->local_window = c->local_window_max = window_max;
   
         if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_WINDOW_ADJUST)) != 0 ||          if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_WINDOW_ADJUST)) != 0 ||
Line 1251 
Line 1316 
                 channel_close_fd(ssh, c, &c->efd);                  channel_close_fd(ssh, c, &c->efd);
         if (abandon)          if (abandon)
                 c->type = SSH_CHANNEL_ABANDONED;                  c->type = SSH_CHANNEL_ABANDONED;
           /* exempt from inactivity timeouts */
           c->inactive_deadline = 0;
           c->lastused = 0;
 }  }
   
 static void  static void
Line 1262 
Line 1330 
   
         if (ret == 1) {          if (ret == 1) {
                 c->type = SSH_CHANNEL_OPEN;                  c->type = SSH_CHANNEL_OPEN;
                   c->lastused = monotime();
                 channel_pre_open(ssh, c);                  channel_pre_open(ssh, c);
         } else if (ret == -1) {          } else if (ret == -1) {
                 logit("X11 connection rejected because of wrong "                  logit("X11 connection rejected because of wrong "
Line 1905 
Line 1974 
                     c->self, c->connect_ctx.host, c->connect_ctx.port);                      c->self, c->connect_ctx.host, c->connect_ctx.port);
                 channel_connect_ctx_free(&c->connect_ctx);                  channel_connect_ctx_free(&c->connect_ctx);
                 c->type = SSH_CHANNEL_OPEN;                  c->type = SSH_CHANNEL_OPEN;
                   c->lastused = monotime();
                 if (isopen) {                  if (isopen) {
                         /* no message necessary */                          /* no message necessary */
                 } else {                  } else {
Line 1953 
Line 2023 
         char buf[CHAN_RBUF];          char buf[CHAN_RBUF];
         ssize_t len;          ssize_t len;
         int r;          int r;
         size_t have, avail, maxlen = CHANNEL_MAX_READ;          size_t nr = 0, have, avail, maxlen = CHANNEL_MAX_READ;
   
         if ((c->io_ready & SSH_CHAN_IO_RFD) == 0)          if ((c->io_ready & SSH_CHAN_IO_RFD) == 0)
                 return 1; /* Shouldn't happen */                  return 1; /* Shouldn't happen */
Line 1974 
Line 2044 
                 }                  }
                 if (maxlen > avail)                  if (maxlen > avail)
                         maxlen = avail;                          maxlen = avail;
                 if ((r = sshbuf_read(c->rfd, c->input, maxlen, NULL)) != 0) {                  if ((r = sshbuf_read(c->rfd, c->input, maxlen, &nr)) != 0) {
                         if (errno == EINTR || errno == EAGAIN)                          if (errno == EINTR || errno == EAGAIN)
                                 return 1;                                  return 1;
                         debug2("channel %d: read failed rfd %d maxlen %zu: %s",                          debug2("channel %d: read failed rfd %d maxlen %zu: %s",
                             c->self, c->rfd, maxlen, ssh_err(r));                              c->self, c->rfd, maxlen, ssh_err(r));
                         goto rfail;                          goto rfail;
                 }                  }
                   if (nr != 0)
                           c->lastused = monotime();
                 return 1;                  return 1;
         }          }
   
Line 2001 
Line 2073 
                 }                  }
                 return -1;                  return -1;
         }          }
           c->lastused = monotime();
         if (c->input_filter != NULL) {          if (c->input_filter != NULL) {
                 if (c->input_filter(ssh, c, buf, len) == -1) {                  if (c->input_filter(ssh, c, buf, len) == -1) {
                         debug2("channel %d: filter stops", c->self);                          debug2("channel %d: filter stops", c->self);
Line 2071 
Line 2144 
                 }                  }
                 return -1;                  return -1;
         }          }
           c->lastused = monotime();
         if (c->isatty && dlen >= 1 && buf[0] != '\r') {          if (c->isatty && dlen >= 1 && buf[0] != '\r') {
                 if (tcgetattr(c->wfd, &tio) == 0 &&                  if (tcgetattr(c->wfd, &tio) == 0 &&
                     !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {                      !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
Line 2116 
Line 2190 
                 if ((r = sshbuf_consume(c->extended, len)) != 0)                  if ((r = sshbuf_consume(c->extended, len)) != 0)
                         fatal_fr(r, "channel %i: consume", c->self);                          fatal_fr(r, "channel %i: consume", c->self);
                 c->local_consumed += len;                  c->local_consumed += len;
                   c->lastused = monotime();
         }          }
         return 1;          return 1;
 }  }
Line 2137 
Line 2212 
         if (len <= 0) {          if (len <= 0) {
                 debug2("channel %d: closing read-efd %d", c->self, c->efd);                  debug2("channel %d: closing read-efd %d", c->self, c->efd);
                 channel_close_fd(ssh, c, &c->efd);                  channel_close_fd(ssh, c, &c->efd);
         } else if (c->extended_usage == CHAN_EXTENDED_IGNORE)                  return 1;
           }
           c->lastused = monotime();
           if (c->extended_usage == CHAN_EXTENDED_IGNORE)
                 debug3("channel %d: discard efd", c->self);                  debug3("channel %d: discard efd", c->self);
         else if ((r = sshbuf_put(c->extended, buf, len)) != 0)          else if ((r = sshbuf_put(c->extended, buf, len)) != 0)
                 fatal_fr(r, "channel %i: append", c->self);                  fatal_fr(r, "channel %i: append", c->self);
Line 2426 
Line 2504 
                                 continue;                                  continue;
                 }                  }
                 if (ftab[c->type] != NULL) {                  if (ftab[c->type] != NULL) {
                         /*                          if (table == CHAN_PRE &&
                          * Run handlers that are not paused.                              c->type == SSH_CHANNEL_OPEN &&
                          */                              c->inactive_deadline != 0 && c->lastused != 0 &&
                         if (c->notbefore <= now)                              now >= c->lastused + c->inactive_deadline) {
                                   /* channel closed for inactivity */
                                   verbose("channel %d: closing after %u seconds "
                                       "of inactivity", c->self,
                                       c->inactive_deadline);
                                   channel_force_close(ssh, c, 1);
                           } else if (c->notbefore <= now) {
                                   /* Run handlers that are not paused. */
                                 (*ftab[c->type])(ssh, c);                                  (*ftab[c->type])(ssh, c);
                         else if (timeout != NULL) {                                  /* inactivity timeouts must interrupt poll() */
                                   if (timeout != NULL &&
                                       c->type == SSH_CHANNEL_OPEN &&
                                       c->lastused != 0 &&
                                       c->inactive_deadline != 0) {
                                           ptimeout_deadline_monotime(timeout,
                                               c->lastused + c->inactive_deadline);
                                   }
                           } else if (timeout != NULL) {
                                 /*                                  /*
                                  * Arrange for poll wakeup when channel pause                                   * Arrange for poll() wakeup when channel pause
                                  * timer expires.                                   * timer expires.
                                  */                                   */
                                 ptimeout_deadline_monotime(timeout,                                  ptimeout_deadline_monotime(timeout,
Line 3370 
Line 3463 
                 c->open_confirm(ssh, c->self, 1, c->open_confirm_ctx);                  c->open_confirm(ssh, c->self, 1, c->open_confirm_ctx);
                 debug2_f("channel %d: callback done", c->self);                  debug2_f("channel %d: callback done", c->self);
         }          }
           c->lastused = monotime();
         debug2("channel %d: open confirm rwindow %u rmax %u", c->self,          debug2("channel %d: open confirm rwindow %u rmax %u", c->self,
             c->remote_window, c->remote_maxpacket);              c->remote_window, c->remote_maxpacket);
         return 0;          return 0;

Legend:
Removed from v.1.425  
changed lines
  Added in v.1.426