Added SILC Thread Queue API
[crypto.git] / apps / irssi / src / core / servers.c
index 92a6e5ac7b3c65d2b5ab3e20b865ca6d31124cf4..ca18914ae79259994f62faaf00f3f6e4cab23ee6 100644 (file)
@@ -171,13 +171,19 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip,
                                const char *unix_socket)
 {
        GIOChannel *handle;
-        IPADDR *own_ip;
+       IPADDR *own_ip = NULL;
+       const char *errmsg;
+       char *errmsg2;
+       char ipaddr[MAX_IP_LEN];
         int port;
 
        g_return_if_fail(ip != NULL || unix_socket != NULL);
 
        signal_emit("server connecting", 2, server, ip);
 
+       if (server->connrec->no_connect)
+               return;
+
        if (ip != NULL) {
                own_ip = ip == NULL ? NULL :
                        (IPADDR_IS_V6(ip) ? server->connrec->own_ip6 :
@@ -185,7 +191,8 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip,
                port = server->connrec->proxy != NULL ?
                        server->connrec->proxy_port : server->connrec->port;
                handle = server->connrec->use_ssl ?
-                       net_connect_ip_ssl(ip, port, own_ip) :
+                       net_connect_ip_ssl(ip, port, own_ip, server->connrec->ssl_cert, server->connrec->ssl_pkey,
+server->connrec->ssl_cafile, server->connrec->ssl_capath, server->connrec->ssl_verify) :
                        net_connect_ip(ip, port, own_ip);
        } else {
                handle = net_connect_unix(unix_socket);
@@ -193,11 +200,22 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip,
 
        if (handle == NULL) {
                /* failed */
+               errmsg = g_strerror(errno);
+               errmsg2 = NULL;
+               if (errno == EADDRNOTAVAIL) {
+                       if (own_ip != NULL) {
+                               /* show the IP which is causing the error */
+                               net_ip2host(own_ip, ipaddr);
+                               errmsg2 = g_strconcat(errmsg, ": ", ipaddr, NULL);
+                       }
+                       server->no_reconnect = TRUE;
+               }
                if (server->connrec->use_ssl && errno == ENOSYS)
                        server->no_reconnect = TRUE;
 
                server->connection_lost = TRUE;
-               server_connect_failed(server, g_strerror(errno));
+               server_connect_failed(server, errmsg2 ? errmsg2 : errmsg);
+               g_free(errmsg2);
        } else {
                server->handle = net_sendbuffer_create(handle, 0);
                server->connect_tag =
@@ -213,6 +231,7 @@ static void server_connect_callback_readpipe(SERVER_REC *server)
        RESOLVED_IP_REC iprec;
         IPADDR *ip;
        const char *errormsg;
+       char *servername = NULL;
 
        g_source_remove(server->connect_tag);
        server->connect_tag = -1;
@@ -234,20 +253,31 @@ static void server_connect_callback_readpipe(SERVER_REC *server)
        } else if (server->connrec->family == AF_INET) {
                /* force IPv4 connection */
                ip = iprec.ip4.family == 0 ? NULL : &iprec.ip4;
+               servername = iprec.host4;
        } else if (server->connrec->family == AF_INET6) {
                /* force IPv6 connection */
                ip = iprec.ip6.family == 0 ? NULL : &iprec.ip6;
+               servername = iprec.host6;
        } else {
                /* pick the one that was found, or if both do it like
                   /SET resolve_prefer_ipv6 says. */
-               ip = iprec.ip4.family == 0 ||
-                       (iprec.ip6.family != 0 &&
-                        settings_get_bool("resolve_prefer_ipv6")) ?
-                       &iprec.ip6 : &iprec.ip4;
+               if (iprec.ip4.family == 0 ||
+                   (iprec.ip6.family != 0 &&
+                    settings_get_bool("resolve_prefer_ipv6"))) {
+                       ip = &iprec.ip6;
+                       servername = iprec.host6;
+               } else {
+                       ip = &iprec.ip4;
+                       servername = iprec.host4;
+               }
        }
 
        if (ip != NULL) {
                /* host lookup ok */
+               if (servername) {
+                       g_free(server->connrec->address);
+                       server->connrec->address = g_strdup(servername);
+               }
                server_real_connect(server, ip, NULL);
                errormsg = NULL;
        } else {
@@ -273,6 +303,8 @@ static void server_connect_callback_readpipe(SERVER_REC *server)
        }
 
        g_free(iprec.errorstr);
+       g_free(iprec.host4);
+       g_free(iprec.host6);
 }
 
 SERVER_REC *server_connect(SERVER_CONNECT_REC *conn)
@@ -356,7 +388,8 @@ int server_start_connect(SERVER_REC *server)
                        server->connrec->proxy : server->connrec->address;
                server->connect_pid =
                        net_gethostbyname_nonblock(connect_address,
-                                                  server->connect_pipe[1]);
+                                                  server->connect_pipe[1],
+                                                  settings_get_bool("resolve_reverse_lookup"));
                server->connect_tag =
                        g_input_add(server->connect_pipe[0], G_INPUT_READ,
                                    (GInputFunction)
@@ -565,6 +598,11 @@ void server_connect_unref(SERVER_CONNECT_REC *conn)
         g_free_not_null(conn->username);
        g_free_not_null(conn->realname);
 
+       g_free_not_null(conn->ssl_cert);
+       g_free_not_null(conn->ssl_pkey);
+       g_free_not_null(conn->ssl_cafile);
+       g_free_not_null(conn->ssl_capath);
+
        g_free_not_null(conn->channels);
         g_free_not_null(conn->away_reason);
 
@@ -666,6 +704,7 @@ static void sig_chat_protocol_deinit(CHAT_PROTOCOL_REC *proto)
 void servers_init(void)
 {
        settings_add_bool("server", "resolve_prefer_ipv6", FALSE);
+       settings_add_bool("server", "resolve_reverse_lookup", FALSE);
        lookup_servers = servers = NULL;
 
        signal_add("chat protocol deinit", (SIGNAL_FUNC) sig_chat_protocol_deinit);