aboutsummaryrefslogtreecommitdiff
path: root/libssh
diff options
context:
space:
mode:
authorAndreas Schneider <mail@cynapses.org>2009-05-05 08:05:03 +0000
committerAndreas Schneider <mail@cynapses.org>2009-05-05 08:05:03 +0000
commit4bf12aaf56e64eaa9f2894fc18583bff89d2018c (patch)
treedf66a6a1c7ee42ac47112f08ff859f2339f40264 /libssh
parent7568e42f4edcb53ef02469f12013eb9a6f615020 (diff)
downloadlibssh-4bf12aaf56e64eaa9f2894fc18583bff89d2018c.tar.gz
libssh-4bf12aaf56e64eaa9f2894fc18583bff89d2018c.tar.xz
libssh-4bf12aaf56e64eaa9f2894fc18583bff89d2018c.zip
Improve ssh_connect_host().
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@728 7dcaeef0-15fb-0310-b436-a5af3365683c
Diffstat (limited to 'libssh')
-rw-r--r--libssh/connect.c148
1 files changed, 83 insertions, 65 deletions
diff --git a/libssh/connect.c b/libssh/connect.c
index d030773..89ec9bf 100644
--- a/libssh/connect.c
+++ b/libssh/connect.c
@@ -168,80 +168,98 @@ static int ssh_connect_ai_timeout(SSH_SESSION *session, const char *host,
return s;
}
-/** \internal
- * \brief connect_host connects to an IPv4 (or IPv6) host
- * specified by its IP address or hostname.
- * \returns file descriptor
- * \returns less than 0 value
+/**
+ * @internal
+ *
+ * @brief Connect to an IPv4 or IPv6 host specified by its IP address or
+ * hostname.
+ *
+ * @returns A file descriptor, < 0 on error.
*/
+socket_t ssh_connect_host(SSH_SESSION *session, const char *host,
+ const char *bind_addr, int port, long timeout, long usec) {
+ socket_t s = -1;
+ int rc;
+ struct addrinfo *ai;
+ struct addrinfo *itr;
+
+ enter_function();
+
+ rc = getai(host, port, &ai);
+ if (rc != 0) {
+ ssh_set_error(session, SSH_FATAL,
+ "Failed to resolve hostname %s (%s)", host, gai_strerror(rc));
+ leave_function();
+ return -1;
+ }
+
+ for (itr = ai; itr != NULL; itr = itr->ai_next){
+ /* create socket */
+ s = socket(itr->ai_family, itr->ai_socktype, itr->ai_protocol);
+ if (s < 0) {
+ ssh_set_error(session, SSH_FATAL,
+ "Socket create failed: %s", strerror(errno));
+ continue;
+ }
-socket_t ssh_connect_host(SSH_SESSION *session, const char *host, const char
- *bind_addr, int port,long timeout, long usec){
- socket_t s=-1;
- int my_errno;
- struct addrinfo *ai, *ai2;
- enter_function();
- my_errno=getai(host, port, &ai);
- if (my_errno){
- ssh_set_error(session,SSH_FATAL,"Failed to resolve hostname %s (%s)",host,gai_strerror(my_errno));
+ if (bind_addr) {
+ struct addrinfo *bind_ai;
+ struct addrinfo *bind_itr;
+
+ ssh_log(session, SSH_LOG_PACKET, "Resolving %s\n", bind_addr);
+
+ rc = getai(host, 0, &bind_ai);
+ if (rc != 0) {
+ ssh_set_error(session, SSH_FATAL,
+ "Failed to resolve bind address %s (%s)",
+ bind_addr,
+ gai_strerror(rc));
leave_function();
return -1;
+ }
+
+ for (bind_itr = bind_ai; bind_itr != NULL; bind_itr = bind_itr->ai_next) {
+ if (bind(s, bind_itr->ai_addr, bind_itr->ai_addrlen) < 0) {
+ ssh_set_error(session, SSH_FATAL,
+ "Binding local address: %s", strerror(errno));
+ continue;
+ } else {
+ break;
+ }
+ }
+ freeaddrinfo(bind_ai);
+
+ /* Cannot bind to any local addresses */
+ if (bind_itr == NULL) {
+ close(s);
+ s = -1;
+ continue;
+ }
}
- for(ai2=ai;ai2!=NULL;ai2=ai2->ai_next){
- /* create socket */
- s=socket(ai2->ai_family,ai2->ai_socktype,ai2->ai_protocol);
- if(s<0){
- ssh_set_error(session,SSH_FATAL,"socket : %s",strerror(errno));
- continue;
- }
+ if (timeout || usec) {
+ socket_t ret = ssh_connect_ai_timeout(session, host, port, itr,
+ timeout, usec, s);
+ leave_function();
+ return ret;
+ }
- if(bind_addr){
- struct addrinfo *bind_ai, *bind_ai2;
+ if (connect(s, itr->ai_addr, itr->ai_addrlen) < 0) {
+ ssh_set_error(session, SSH_FATAL, "Connect failed: %s", strerror(errno));
+ close(s);
+ s = -1;
+ leave_function();
+ continue;
+ } else {
+ /* We are connected */
+ break;
+ }
+ }
- ssh_log(session,SSH_LOG_PACKET,"resolving %s\n",bind_addr);
- my_errno=getai(host,0,&bind_ai);
- if (my_errno){
- ssh_set_error(session,SSH_FATAL,"Failed to resolve bind address %s (%s)",bind_addr,gai_strerror(my_errno));
- leave_function();
- return -1;
- }
+ freeaddrinfo(ai);
+ leave_function();
- for(bind_ai2=bind_ai;bind_ai2!=NULL;bind_ai2=bind_ai2->ai_next){
- if(bind(s,bind_ai2->ai_addr,bind_ai2->ai_addrlen)<0){
- ssh_set_error(session,SSH_FATAL,"Binding local address : %s",strerror(errno));
- continue;
- }
- else{
- break;
- }
- }
- freeaddrinfo(bind_ai);
- if(bind_ai2==NULL){ /*cannot bind to any local addresses*/
- close(s);
- s=-1;
- continue;
- }
- }
- if(timeout||usec){
- socket_t ret=ssh_connect_ai_timeout(session,host,port,ai2,timeout,usec,s);
- leave_function();
- return ret;
- }
- if(connect(s,ai2->ai_addr,ai2->ai_addrlen)<0){
- ssh_set_error(session,SSH_FATAL,"connect: %s",strerror(errno));
- close(s);
- s=-1;
- leave_function();
- continue;
- }
- else{ /*we are connected*/
- break;
- }
- }
- freeaddrinfo(ai);
- leave_function();
- return s;
+ return s;
}
/** \addtogroup ssh_session