Merged silc_1_0_branch to trunk.
[silc.git] / lib / silcutil / unix / silcunixnet.c
index 31c11370a4a4a5a6d7d65d0246ebc464ed0c7538..d2e52e936a1d75ff444926ab27e8d6e75bbc949d 100644 (file)
@@ -191,12 +191,20 @@ int silc_net_create_connection(const char *local_ip, int port,
 
     /* Set sockaddr for local listener, and try to bind it. */
     if (silc_net_set_sockaddr(&local, local_ip, 0))
-      bind(sock, &local.sa, sizeof(local));
+      bind(sock, &local.sa, SIZEOF_SOCKADDR(local));
   }
 
   /* Connect to the host */
-  rval = connect(sock, &desthost.sa, sizeof(desthost));
+  rval = connect(sock, &desthost.sa, SIZEOF_SOCKADDR(desthost));
   if (rval < 0) {
+    /* retry using an IPv4 adress, if IPv6 didn't work */
+    if (prefer_ipv6 && silc_net_is_ip6(ip_addr)) {
+      shutdown(sock, 2);
+      close(sock);
+
+      prefer_ipv6 = FALSE;
+      goto retry;
+    }
     SILC_LOG_ERROR(("Cannot connect to remote host: %s", strerror(errno)));
     shutdown(sock, 2);
     close(sock);
@@ -262,16 +270,25 @@ int silc_net_create_connection_async(const char *local_ip, int port,
 
     /* Set sockaddr for local listener, and try to bind it. */
     if (silc_net_set_sockaddr(&local, local_ip, 0))
-      bind(sock, &local.sa, sizeof(local));
+      bind(sock, &local.sa, SIZEOF_SOCKADDR(local));
   }
 
   /* Set the socket to non-blocking mode */
   silc_net_set_socket_nonblock(sock);
 
   /* Connect to the host */
-  rval = connect(sock, &desthost.sa, sizeof(desthost));
+  rval = connect(sock, &desthost.sa, SIZEOF_SOCKADDR(desthost));
   if (rval < 0) {
     if (errno !=  EINPROGRESS) {
+      /* retry using an IPv4 adress, if IPv6 didn't work */
+      if (prefer_ipv6 && silc_net_is_ip6(ip_addr)) {
+        shutdown(sock, 2);
+        close(sock);
+
+        prefer_ipv6 = FALSE;
+        goto retry;
+      }
+
       SILC_LOG_ERROR(("Cannot connect to remote host: %s", strerror(errno)));
       shutdown(sock, 2);
       close(sock);