mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-08-13 04:42:23 +03:00
Improve ssh_connect_host().
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@728 7dcaeef0-15fb-0310-b436-a5af3365683c
This commit is contained in:
@@ -168,79 +168,97 @@ static int ssh_connect_ai_timeout(SSH_SESSION *session, const char *host,
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \internal
|
/**
|
||||||
* \brief connect_host connects to an IPv4 (or IPv6) host
|
* @internal
|
||||||
* specified by its IP address or hostname.
|
*
|
||||||
* \returns file descriptor
|
* @brief Connect to an IPv4 or IPv6 host specified by its IP address or
|
||||||
* \returns less than 0 value
|
* hostname.
|
||||||
|
*
|
||||||
|
* @returns A file descriptor, < 0 on error.
|
||||||
*/
|
*/
|
||||||
|
socket_t ssh_connect_host(SSH_SESSION *session, const char *host,
|
||||||
socket_t ssh_connect_host(SSH_SESSION *session, const char *host, const char
|
const char *bind_addr, int port, long timeout, long usec) {
|
||||||
*bind_addr, int port,long timeout, long usec){
|
|
||||||
socket_t s = -1;
|
socket_t s = -1;
|
||||||
int my_errno;
|
int rc;
|
||||||
struct addrinfo *ai, *ai2;
|
struct addrinfo *ai;
|
||||||
|
struct addrinfo *itr;
|
||||||
|
|
||||||
enter_function();
|
enter_function();
|
||||||
my_errno=getai(host, port, &ai);
|
|
||||||
if (my_errno){
|
rc = getai(host, port, &ai);
|
||||||
ssh_set_error(session,SSH_FATAL,"Failed to resolve hostname %s (%s)",host,gai_strerror(my_errno));
|
if (rc != 0) {
|
||||||
|
ssh_set_error(session, SSH_FATAL,
|
||||||
|
"Failed to resolve hostname %s (%s)", host, gai_strerror(rc));
|
||||||
leave_function();
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(ai2=ai;ai2!=NULL;ai2=ai2->ai_next){
|
for (itr = ai; itr != NULL; itr = itr->ai_next){
|
||||||
/* create socket */
|
/* create socket */
|
||||||
s=socket(ai2->ai_family,ai2->ai_socktype,ai2->ai_protocol);
|
s = socket(itr->ai_family, itr->ai_socktype, itr->ai_protocol);
|
||||||
if (s < 0) {
|
if (s < 0) {
|
||||||
ssh_set_error(session,SSH_FATAL,"socket : %s",strerror(errno));
|
ssh_set_error(session, SSH_FATAL,
|
||||||
|
"Socket create failed: %s", strerror(errno));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bind_addr) {
|
if (bind_addr) {
|
||||||
struct addrinfo *bind_ai, *bind_ai2;
|
struct addrinfo *bind_ai;
|
||||||
|
struct addrinfo *bind_itr;
|
||||||
|
|
||||||
ssh_log(session,SSH_LOG_PACKET,"resolving %s\n",bind_addr);
|
ssh_log(session, SSH_LOG_PACKET, "Resolving %s\n", bind_addr);
|
||||||
my_errno=getai(host,0,&bind_ai);
|
|
||||||
if (my_errno){
|
rc = getai(host, 0, &bind_ai);
|
||||||
ssh_set_error(session,SSH_FATAL,"Failed to resolve bind address %s (%s)",bind_addr,gai_strerror(my_errno));
|
if (rc != 0) {
|
||||||
|
ssh_set_error(session, SSH_FATAL,
|
||||||
|
"Failed to resolve bind address %s (%s)",
|
||||||
|
bind_addr,
|
||||||
|
gai_strerror(rc));
|
||||||
leave_function();
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(bind_ai2=bind_ai;bind_ai2!=NULL;bind_ai2=bind_ai2->ai_next){
|
for (bind_itr = bind_ai; bind_itr != NULL; bind_itr = bind_itr->ai_next) {
|
||||||
if(bind(s,bind_ai2->ai_addr,bind_ai2->ai_addrlen)<0){
|
if (bind(s, bind_itr->ai_addr, bind_itr->ai_addrlen) < 0) {
|
||||||
ssh_set_error(session,SSH_FATAL,"Binding local address : %s",strerror(errno));
|
ssh_set_error(session, SSH_FATAL,
|
||||||
|
"Binding local address: %s", strerror(errno));
|
||||||
continue;
|
continue;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
freeaddrinfo(bind_ai);
|
freeaddrinfo(bind_ai);
|
||||||
if(bind_ai2==NULL){ /*cannot bind to any local addresses*/
|
|
||||||
|
/* Cannot bind to any local addresses */
|
||||||
|
if (bind_itr == NULL) {
|
||||||
close(s);
|
close(s);
|
||||||
s = -1;
|
s = -1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeout || usec) {
|
if (timeout || usec) {
|
||||||
socket_t ret=ssh_connect_ai_timeout(session,host,port,ai2,timeout,usec,s);
|
socket_t ret = ssh_connect_ai_timeout(session, host, port, itr,
|
||||||
|
timeout, usec, s);
|
||||||
leave_function();
|
leave_function();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if(connect(s,ai2->ai_addr,ai2->ai_addrlen)<0){
|
|
||||||
ssh_set_error(session,SSH_FATAL,"connect: %s",strerror(errno));
|
if (connect(s, itr->ai_addr, itr->ai_addrlen) < 0) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Connect failed: %s", strerror(errno));
|
||||||
close(s);
|
close(s);
|
||||||
s = -1;
|
s = -1;
|
||||||
leave_function();
|
leave_function();
|
||||||
continue;
|
continue;
|
||||||
}
|
} else {
|
||||||
else{ /*we are connected*/
|
/* We are connected */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
freeaddrinfo(ai);
|
freeaddrinfo(ai);
|
||||||
leave_function();
|
leave_function();
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user