|
Lines 212-217
Link Here
|
| 212 |
return sock; |
212 |
return sock; |
| 213 |
} |
213 |
} |
| 214 |
|
214 |
|
|
|
215 |
int |
| 216 |
timeout_connect(int sockfd, const struct sockaddr *serv_addr, |
| 217 |
socklen_t addrlen, int timeout) |
| 218 |
{ |
| 219 |
fd_set *fdset; |
| 220 |
struct timeval tv; |
| 221 |
socklen_t optlen; |
| 222 |
int fdsetsz, optval, rc; |
| 223 |
|
| 224 |
if (timeout <= 0) |
| 225 |
return(connect(sockfd, serv_addr, addrlen)); |
| 226 |
|
| 227 |
if (fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) |
| 228 |
return -1; |
| 229 |
|
| 230 |
rc = connect(sockfd, serv_addr, addrlen); |
| 231 |
if (rc == 0) |
| 232 |
return 0; |
| 233 |
if (errno != EINPROGRESS) |
| 234 |
return -1; |
| 235 |
|
| 236 |
fdsetsz = howmany(sockfd+1, NFDBITS) * sizeof(fd_mask); |
| 237 |
fdset = (fd_set *)xmalloc(fdsetsz); |
| 238 |
memset(fdset, 0, fdsetsz); |
| 239 |
FD_SET(sockfd, fdset); |
| 240 |
tv.tv_sec = timeout; |
| 241 |
tv.tv_usec = 0; |
| 242 |
rc=select(sockfd+1, NULL, fdset, NULL, &tv); |
| 243 |
|
| 244 |
switch(rc) { |
| 245 |
case 0: |
| 246 |
errno = ETIMEDOUT; |
| 247 |
case -1: |
| 248 |
return -1; |
| 249 |
break; |
| 250 |
case 1: |
| 251 |
optval = 0; |
| 252 |
optlen = sizeof(optval); |
| 253 |
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1) |
| 254 |
return -1; |
| 255 |
if (optval != 0) |
| 256 |
{ |
| 257 |
errno = optval; |
| 258 |
return -1; |
| 259 |
} |
| 260 |
return 0; |
| 261 |
|
| 262 |
default: |
| 263 |
/* Should not occur */ |
| 264 |
return -1; |
| 265 |
break; |
| 266 |
} |
| 267 |
return -1; |
| 268 |
} |
| 269 |
|
| 215 |
/* |
270 |
/* |
| 216 |
* Opens a TCP/IP connection to the remote server on the given host. |
271 |
* Opens a TCP/IP connection to the remote server on the given host. |
| 217 |
* The address of the remote host will be returned in hostaddr. |
272 |
* The address of the remote host will be returned in hostaddr. |
|
Lines 231-237
Link Here
|
| 231 |
*/ |
286 |
*/ |
| 232 |
int |
287 |
int |
| 233 |
ssh_connect(const char *host, struct sockaddr_storage * hostaddr, |
288 |
ssh_connect(const char *host, struct sockaddr_storage * hostaddr, |
| 234 |
u_short port, int family, int connection_attempts, |
289 |
u_short port, int family, int connection_attempts, int connection_timeout, |
| 235 |
int needpriv, const char *proxy_command) |
290 |
int needpriv, const char *proxy_command) |
| 236 |
{ |
291 |
{ |
| 237 |
int gaierr; |
292 |
int gaierr; |
|
Lines 300-306
Link Here
|
| 300 |
/* Any error is already output */ |
355 |
/* Any error is already output */ |
| 301 |
continue; |
356 |
continue; |
| 302 |
|
357 |
|
| 303 |
if (connect(sock, ai->ai_addr, ai->ai_addrlen) >= 0) { |
358 |
if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen, |
|
|
359 |
connection_timeout) >= 0) { |
| 304 |
/* Successful connection. */ |
360 |
/* Successful connection. */ |
| 305 |
memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); |
361 |
memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); |
| 306 |
break; |
362 |
break; |