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

Diff for /src/usr.bin/ssh/sshconnect.c between version 1.281 and 1.282

version 1.281, 2017/06/24 05:35:05 version 1.282, 2017/06/24 05:37:44
Line 26 
Line 26 
 #include <fcntl.h>  #include <fcntl.h>
 #include <netdb.h>  #include <netdb.h>
 #include <paths.h>  #include <paths.h>
   #include <poll.h>
 #include <signal.h>  #include <signal.h>
 #include <pwd.h>  #include <pwd.h>
 #include <stdio.h>  #include <stdio.h>
Line 318 
Line 319 
         return sock;          return sock;
 }  }
   
   /*
    * Wait up to *timeoutp milliseconds for fd to be readable. Updates
    * *timeoutp with time remaining.
    * Returns 0 if fd ready or -1 on timeout or error (see errno).
    */
 static int  static int
 timeout_connect(int sockfd, const struct sockaddr *serv_addr,  waitrfd(int fd, int *timeoutp)
     socklen_t addrlen, int *timeoutp)  
 {  {
         fd_set *fdset;          struct pollfd pfd;
         struct timeval tv, t_start;          struct timeval t_start;
         socklen_t optlen;          int oerrno, r;
         int optval, rc, result = -1;  
   
         gettimeofday(&t_start, NULL);          gettimeofday(&t_start, NULL);
           pfd.fd = fd;
         if (*timeoutp <= 0) {          pfd.events = POLLIN;
                 result = connect(sockfd, serv_addr, addrlen);          for (; *timeoutp >= 0;) {
                 goto done;                  r = poll(&pfd, 1, *timeoutp);
                   oerrno = errno;
                   ms_subtract_diff(&t_start, timeoutp);
                   errno = oerrno;
                   if (r > 0)
                           return 0;
                   else if (r == -1 && errno != EAGAIN)
                           return -1;
                   else if (r == 0)
                           break;
         }          }
           /* timeout */
           errno = ETIMEDOUT;
           return -1;
   }
   
         set_nonblock(sockfd);  static int
         rc = connect(sockfd, serv_addr, addrlen);  timeout_connect(int sockfd, const struct sockaddr *serv_addr,
         if (rc == 0) {      socklen_t addrlen, int *timeoutp)
                 unset_nonblock(sockfd);  {
                 result = 0;          int optval = 0;
                 goto done;          socklen_t optlen = sizeof(optval);
         }  
         if (errno != EINPROGRESS) {  
                 result = -1;  
                 goto done;  
         }  
   
         fdset = xcalloc(howmany(sockfd + 1, NFDBITS),          /* No timeout: just do a blocking connect() */
             sizeof(fd_mask));          if (*timeoutp <= 0)
         FD_SET(sockfd, fdset);                  return connect(sockfd, serv_addr, addrlen);
         ms_to_timeval(&tv, *timeoutp);  
   
         for (;;) {          set_nonblock(sockfd);
                 rc = select(sockfd + 1, NULL, fdset, NULL, &tv);          if (connect(sockfd, serv_addr, addrlen) == 0) {
                 if (rc != -1 || errno != EINTR)                  /* Succeeded already? */
                         break;  
         }  
   
         switch (rc) {  
         case 0:  
                 /* Timed out */  
                 errno = ETIMEDOUT;  
                 break;  
         case -1:  
                 /* Select error */  
                 debug("select: %s", strerror(errno));  
                 break;  
         case 1:  
                 /* Completed or failed */  
                 optval = 0;  
                 optlen = sizeof(optval);  
                 if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval,  
                     &optlen) == -1) {  
                         debug("getsockopt: %s", strerror(errno));  
                         break;  
                 }  
                 if (optval != 0) {  
                         errno = optval;  
                         break;  
                 }  
                 result = 0;  
                 unset_nonblock(sockfd);                  unset_nonblock(sockfd);
                 break;                  return 0;
         default:          } else if (errno != EINPROGRESS)
                 /* Should not occur */                  return -1;
                 fatal("Bogus return (%d) from select()", rc);  
         }  
   
         free(fdset);          if (waitrfd(sockfd, timeoutp) == -1)
                   return -1;
   
  done:          /* Completed or failed */
         if (result == 0 && *timeoutp > 0) {          if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1) {
                 ms_subtract_diff(&t_start, timeoutp);                  debug("getsockopt: %s", strerror(errno));
                 if (*timeoutp <= 0) {                  return -1;
                         errno = ETIMEDOUT;  
                         result = -1;  
                 }  
         }          }
           if (optval != 0) {
         return (result);                  errno = optval;
                   return -1;
           }
           unset_nonblock(sockfd);
           return 0;
 }  }
   
 /*  /*
Line 536 
Line 521 
         int connection_out = packet_get_connection_out();          int connection_out = packet_get_connection_out();
         u_int i, n;          u_int i, n;
         size_t len;          size_t len;
         int fdsetsz, remaining, rc;          int rc;
         struct timeval t_start, t_remaining;  
         fd_set *fdset;  
   
         fdsetsz = howmany(connection_in + 1, NFDBITS) * sizeof(fd_mask);  
         fdset = xcalloc(1, fdsetsz);  
   
         send_client_banner(connection_out, 0);          send_client_banner(connection_out, 0);
   
         /* Read other side's version identification. */          /* Read other side's version identification. */
         remaining = timeout_ms;  
         for (n = 0;;) {          for (n = 0;;) {
                 for (i = 0; i < sizeof(buf) - 1; i++) {                  for (i = 0; i < sizeof(buf) - 1; i++) {
                         if (timeout_ms > 0) {                          if (timeout_ms > 0) {
                                 gettimeofday(&t_start, NULL);                                  rc = waitrfd(connection_in, &timeout_ms);
                                 ms_to_timeval(&t_remaining, remaining);                                  if (rc == -1 && errno == ETIMEDOUT) {
                                 FD_SET(connection_in, fdset);  
                                 rc = select(connection_in + 1, fdset, NULL,  
                                     fdset, &t_remaining);  
                                 ms_subtract_diff(&t_start, &remaining);  
                                 if (rc == 0 || remaining <= 0)  
                                         fatal("Connection timed out during "                                          fatal("Connection timed out during "
                                             "banner exchange");                                              "banner exchange");
                                 if (rc == -1) {                                  } else if (rc == -1) {
                                         if (errno == EINTR)                                          fatal("%s: %s",
                                                 continue;                                              __func__, strerror(errno));
                                         fatal("ssh_exchange_identification: "  
                                             "select: %s", strerror(errno));  
                                 }                                  }
                         }                          }
   
                         len = atomicio(read, connection_in, &buf[i], 1);                          len = atomicio(read, connection_in, &buf[i], 1);
   
                         if (len != 1 && errno == EPIPE)                          if (len != 1 && errno == EPIPE)
                                 fatal("ssh_exchange_identification: "                                  fatal("ssh_exchange_identification: "
                                     "Connection closed by remote host");                                      "Connection closed by remote host");
Line 594 
Line 565 
                 debug("ssh_exchange_identification: %s", buf);                  debug("ssh_exchange_identification: %s", buf);
         }          }
         server_version_string = xstrdup(buf);          server_version_string = xstrdup(buf);
         free(fdset);  
   
         /*          /*
          * Check that the versions match.  In future this might accept           * Check that the versions match.  In future this might accept

Legend:
Removed from v.1.281  
changed lines
  Added in v.1.282