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