static void server_connect_callback_init_ssl(SERVER_REC *server, GIOChannel *handle) { int error; g_return_if_fail(IS_SERVER(server)); error = irssi_ssl_handshake(handle); if (error == -1) { server->connection_lost = TRUE; server_connect_failed(server, NULL); return; } if (error & 1) { if (server->connect_tag != -1) g_source_remove(server->connect_tag); server->connect_tag = g_input_add(handle, error == 1 ? G_INPUT_READ : G_INPUT_WRITE, (GInputFunction) server_connect_callback_init_ssl, server); return; } lookup_servers = g_slist_remove(lookup_servers, server); if (server->connect_tag != -1) { g_source_remove(server->connect_tag); server->connect_tag = -1; } server_connect_finished(server); }
static void lm_auth_cb(LmConnection *connection, gboolean success, gpointer user_data) { XMPP_SERVER_REC *server; if ((server = XMPP_SERVER(user_data)) == NULL) return; if (!success) { server_connect_failed(SERVER(server), "Authentication failed"); return; } signal_emit("xmpp server status", 2, server, "Authenticated successfully."); /* finnish connection process */ lookup_servers = g_slist_remove(lookup_servers, server); g_source_remove(server->connect_tag); server->connect_tag = -1; server->show = XMPP_PRESENCE_AVAILABLE; server->connected = TRUE; if (server->timeout_tag) { g_source_remove(server->timeout_tag); server->timeout_tag = 0; } server_connect_finished(SERVER(server)); server->real_connect_time = server->connect_time; }
static void server_real_connect(SERVER_REC *server, IPADDR *ip, const char *unix_socket) { GIOChannel *handle; IPADDR *own_ip = NULL; const char *errmsg; char *errmsg2; char ipaddr[MAX_IP_LEN]; int port, protonum; 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 = IPADDR_IS_V6(ip) ? server->connrec->own_ip6 : server->connrec->own_ip4; port = server->connrec->proxy != NULL ? server->connrec->proxy_port : server->connrec->port; protonum = server->connrec->use_sctp ? 132 : 0; handle = server->connrec->use_ssl ? net_connect_ip_ssl(ip, port, own_ip, server, protonum) : net_connect_ip(ip, port, own_ip, protonum); } else { handle = net_connect_unix(unix_socket); } 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, errmsg2 ? errmsg2 : errmsg); g_free(errmsg2); } else { server->handle = net_sendbuffer_create(handle, 0); #ifdef HAVE_OPENSSL if (server->connrec->use_ssl) server_connect_callback_init_ssl(server, handle); else #endif server->connect_tag = g_input_add(handle, G_INPUT_WRITE | G_INPUT_READ, (GInputFunction) server_connect_callback_init, server); } }
void xmpp_server_connect(XMPP_SERVER_REC *server) { GError *error; const char *err_msg; if (!IS_XMPP_SERVER(server)) return; error = NULL; err_msg = NULL; if (server->connrec->use_ssl) { if (!set_ssl(server->lmconn, &error, server, FALSE)) { err_msg = "Cannot init ssl"; goto err; } } else set_ssl(server->lmconn, &error, server, TRUE); if (settings_get_bool("xmpp_use_proxy") && !set_proxy(server->lmconn, &error)) { err_msg = "Cannot set proxy"; goto err; } lm_connection_set_disconnect_function(server->lmconn, lm_close_cb, server, NULL); lookup_servers = g_slist_append(lookup_servers, server); signal_emit("server looking", 1, server); server->timeout_tag = g_timeout_add( settings_get_time("server_connect_timeout"), (GSourceFunc)check_connection_timeout, server); if (!lm_connection_open(server->lmconn, lm_open_cb, server, NULL, &error)) { err_msg = "Connection failed"; goto err; } return; err: server->connection_lost = TRUE; if (error != NULL) { server_connect_failed(SERVER(server), error->message); g_error_free(error); } else server_connect_failed(SERVER(server), err_msg); }
static void lm_auth_cb(LmConnection *connection, gboolean success, gpointer user_data) { XMPP_SERVER_REC *server; if ((server = XMPP_SERVER(user_data)) == NULL) return; if (!success) { server_connect_failed(SERVER(server), "Authentication failed"); return; } signal_emit("xmpp server status", 2, server, "Authenticated successfully."); }
static void disconnect_all(void) { GSList *tmp, *next; for (tmp = lookup_servers; tmp != NULL; tmp = next) { next = tmp->next; if (IS_XMPP_SERVER(tmp->data)) server_connect_failed(SERVER(tmp->data), NULL); } for (tmp = servers; tmp != NULL; tmp = next) { next = tmp->next; if (IS_XMPP_SERVER(tmp->data)) server_disconnect(SERVER(tmp->data)); } }
void server_disconnect(SERVER_REC *server) { int chans; g_return_if_fail(IS_SERVER(server)); if (server->disconnected) return; if (server->connect_tag != -1) { /* still connecting to server.. */ if (server->connect_pid != -1) net_disconnect_nonblock(server->connect_pid); server_connect_failed(server, NULL); return; } servers = g_slist_remove(servers, server); server->disconnected = TRUE; signal_emit("server disconnected", 1, server); /* close all channels */ chans = server_remove_channels(server); if (server->handle != NULL) { if (!chans || server->connection_lost) net_sendbuffer_destroy(server->handle, TRUE); else { /* we were on some channels, try to let the server disconnect so that our quit message is guaranteed to get displayed */ net_disconnect_later(net_sendbuffer_handle(server->handle)); net_sendbuffer_destroy(server->handle, FALSE); } server->handle = NULL; } if (server->readtag > 0) { g_source_remove(server->readtag); server->readtag = -1; } server_unref(server); }
static void server_real_connect(SERVER_REC *server, IPADDR *ip, const char *unix_socket) { GIOChannel *handle; IPADDR *own_ip; 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 : server->connrec->own_ip4); 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, 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); } if (handle == NULL) { /* failed */ if (errno == EADDRNOTAVAIL || (server->connrec->use_ssl && errno == ENOSYS)) server->no_reconnect = TRUE; server->connection_lost = TRUE; server_connect_failed(server, g_strerror(errno)); } else { server->handle = net_sendbuffer_create(handle, 0); server->connect_tag = g_input_add(handle, G_INPUT_WRITE | G_INPUT_READ, (GInputFunction) server_connect_callback_init, server); } }
static void server_connect_callback_init(SERVER_REC *server, GIOChannel *handle) { int error; g_return_if_fail(IS_SERVER(server)); error = net_geterror(handle); if (error != 0) { server->connection_lost = TRUE; server_connect_failed(server, g_strerror(error)); return; } lookup_servers = g_slist_remove(lookup_servers, server); g_source_remove(server->connect_tag); server->connect_tag = -1; server_connect_finished(server); }
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; net_gethostbyname_return(server->connect_pipe[0], &iprec); g_io_channel_close(server->connect_pipe[0]); g_io_channel_unref(server->connect_pipe[0]); g_io_channel_close(server->connect_pipe[1]); g_io_channel_unref(server->connect_pipe[1]); server->connect_pipe[0] = NULL; server->connect_pipe[1] = NULL; /* figure out if we should use IPv4 or v6 address */ if (iprec.error != 0) { /* error */ ip = NULL; } 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. */ 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 { if (iprec.error == 0 || net_hosterror_notfound(iprec.error)) { /* IP wasn't found for the host, don't try to reconnect back to this server */ server->dns_error = TRUE; } if (iprec.error == 0) { /* forced IPv4 or IPv6 address but it wasn't found */ errormsg = server->connrec->family == AF_INET ? "IPv4 address not found for host" : "IPv6 address not found for host"; } else { /* gethostbyname() failed */ errormsg = iprec.errorstr != NULL ? iprec.errorstr : "Host lookup failed"; } server->connection_lost = TRUE; server_connect_failed(server, errormsg); } g_free(iprec.errorstr); g_free(iprec.host4); g_free(iprec.host6); }