/* Connect to specified IP address using the correct own_ip. */ GIOChannel *dcc_connect_ip(IPADDR *ip, int port) { IPADDR *own_ip, temp_ip; const char *own_ip_str; GIOChannel *handle; own_ip_str = settings_get_str("dcc_own_ip"); own_ip = NULL; if (*own_ip_str != '\0') { /* use the specified interface for connecting */ net_host2ip(own_ip_str, &temp_ip); if (IPADDR_IS_V6(ip) == IPADDR_IS_V6(&temp_ip)) own_ip = &temp_ip; } if (own_ip == NULL) own_ip = IPADDR_IS_V6(ip) ? source_host_ip6 : source_host_ip4; handle = net_connect_ip(ip, port, own_ip); if (handle == NULL && errno == EADDRNOTAVAIL && own_ip != NULL) { /* dcc_own_ip is external address */ own_ip = IPADDR_IS_V6(ip) ? source_host_ip6 : source_host_ip4; handle = net_connect_ip(ip, port, own_ip); } return handle; }
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); } }
static int login_proxy_connect(struct login_proxy *proxy) { struct login_proxy_record *rec; rec = login_proxy_state_get(proxy_state, &proxy->ip, proxy->port); if (timeval_cmp(&rec->last_failure, &rec->last_success) > 0 && rec->last_failure.tv_sec - rec->last_success.tv_sec > PROXY_IMMEDIATE_FAILURE_SECS && rec->num_waiting_connections != 0) { /* the server is down. fail immediately */ i_error("proxy(%s): Host %s:%u is down", proxy->client->virtual_user, proxy->host, proxy->port); login_proxy_free(&proxy); return -1; } proxy->server_fd = net_connect_ip(&proxy->ip, proxy->port, NULL); if (proxy->server_fd == -1) { proxy_log_connect_error(proxy); login_proxy_free(&proxy); return -1; } proxy->server_io = io_add(proxy->server_fd, IO_WRITE, proxy_wait_connect, proxy); if (proxy->connect_timeout_msecs != 0) { proxy->to = timeout_add(proxy->connect_timeout_msecs, proxy_connect_timeout, proxy); } proxy->state_rec = rec; proxy->state_rec->num_waiting_connections++; return 0; }
/* Connect to socket */ GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip) { IPADDR ip4, ip6, *ip; int family; g_return_val_if_fail(addr != NULL, NULL); family = my_ip == NULL ? 0 : my_ip->family; if (net_gethostbyname(addr, &ip4, &ip6) == -1) return NULL; if (my_ip == NULL) { /* prefer IPv4 addresses */ ip = ip4.family != 0 ? &ip4 : &ip6; } else if (IPADDR_IS_V6(my_ip)) { /* my_ip is IPv6 address, use it if possible */ if (ip6.family != 0) ip = &ip6; else { my_ip = NULL; ip = &ip4; } } else { /* my_ip is IPv4 address, use it if possible */ if (ip4.family != 0) ip = &ip4; else { my_ip = NULL; ip = &ip6; } } return net_connect_ip(ip, port, my_ip); }
static void simple_readpipe(SIMPLE_THREAD_REC *rec, GIOChannel *pipe) { RESOLVED_IP_REC iprec; GIOChannel *handle; IPADDR *ip; g_return_if_fail(rec != NULL); g_source_remove(rec->tag); net_gethostbyname_return(pipe, &iprec); g_free_not_null(iprec.errorstr); g_io_channel_shutdown(rec->pipes[0], TRUE, NULL); g_io_channel_unref(rec->pipes[0]); g_io_channel_shutdown(rec->pipes[1], TRUE, NULL); g_io_channel_unref(rec->pipes[1]); ip = iprec.ip4.family != 0 ? &iprec.ip4 : &iprec.ip6; handle = iprec.error == -1 ? NULL : net_connect_ip(ip, rec->port, rec->my_ip); g_free_not_null(rec->my_ip); if (handle == NULL) { /* failed */ rec->func(NULL, rec->data); g_free(rec); return; } rec->tag = g_input_add(handle, G_INPUT_READ | G_INPUT_WRITE, (GInputFunction) simple_init, rec); }
int connection_client_connect(struct connection *conn) { const struct connection_settings *set = &conn->list->set; int fd; i_assert(conn->list->set.client); i_assert(conn->fd_in == -1); if (conn->port != 0) fd = net_connect_ip(&conn->ip, conn->port, NULL); else fd = net_connect_unix(conn->name); if (fd == -1) return -1; conn->fd_in = conn->fd_out = fd; if (conn->port != 0) { conn->io = io_add(conn->fd_out, IO_WRITE, connection_ip_connected, conn); if (set->client_connect_timeout_msecs != 0) { conn->to = timeout_add(set->client_connect_timeout_msecs, connection_connect_timeout, conn); } } else { connection_client_connected(conn, TRUE); } return 0; }
static void pop3c_client_connect_ip(struct pop3c_client *client) { struct stat st; client->fd = net_connect_ip(&client->ip, client->set.port, NULL); if (client->fd == -1) { pop3c_client_disconnect(client); return; } client->input = client->raw_input = i_stream_create_fd(client->fd, POP3C_MAX_INBUF_SIZE, FALSE); client->output = client->raw_output = o_stream_create_fd(client->fd, (size_t)-1, FALSE); o_stream_set_no_error_handling(client->output, TRUE); if (*client->set.rawlog_dir != '\0' && client->set.ssl_mode != POP3C_CLIENT_SSL_MODE_IMMEDIATE && stat(client->set.rawlog_dir, &st) == 0) { iostream_rawlog_create(client->set.rawlog_dir, &client->input, &client->output); } client->io = io_add(client->fd, IO_WRITE, pop3c_client_connected, client); client->to = timeout_add(POP3C_CONNECT_TIMEOUT_MSECS, pop3c_client_timeout, client); if (client->set.debug) { i_debug("pop3c(%s): Connecting to %s:%u", client->set.host, net_ip2addr(&client->ip), client->set.port); } }
static int lmtp_client_connect(struct lmtp_client *client) { i_assert(client->fd == -1); client->times.connect_started = ioloop_timeval; client->fd = net_connect_ip(&client->ip, client->port, NULL); if (client->fd == -1) { i_error("lmtp client: connect(%s, %u) failed: %m", client->host, client->port); return -1; } client->input = i_stream_create_fd(client->fd, LMTP_MAX_LINE_LEN); client->output = o_stream_create_fd(client->fd, (size_t)-1); o_stream_set_no_error_handling(client->output, TRUE); o_stream_set_flush_callback(client->output, lmtp_client_output, client); /* we're already sending data in ostream, so can't use IO_WRITE here */ client->io = io_add(client->fd, IO_READ, lmtp_client_wait_connect, client); if (client->set.timeout_secs > 0) { client->to = timeout_add(client->set.timeout_secs*1000, lmtp_client_connect_timeout, client); } return 0; }
/* Connect to socket */ int net_connect(const char *addr, int port, IPADDR *my_ip) { IPADDR ip; g_return_val_if_fail(addr != NULL, -1); if (net_gethostbyname(addr, &ip) == -1) return -1; return net_connect_ip(&ip, port, my_ip); }
GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, IPADDR *my_ip, SERVER_REC *server) { GIOChannel *handle, *ssl_handle; handle = net_connect_ip(ip, port, my_ip); if (handle == NULL) return NULL; ssl_handle = irssi_ssl_get_iochannel(handle, port, server); if (ssl_handle == NULL) g_io_channel_unref(handle); return ssl_handle; }
static void dcc_get_connect(DCC_REC *dcc) { dcc->handle = net_connect_ip(&dcc->addr, dcc->port, source_host_ok ? source_host_ip : NULL); if (dcc->handle != -1) { dcc->tagread = g_input_add(dcc->handle, G_INPUT_WRITE|G_INPUT_READ|G_INPUT_EXCEPTION, (GInputFunction) sig_dccget_connected, dcc); } else { /* error connecting */ signal_emit("dcc error connect", 1, dcc); dcc_destroy(dcc); } }
int stats_carbon_send(const char *endpoint, const char *data, void (*callback)(void *), void *cb_ctx, struct stats_send_ctx **ctx_r) { const char *host; in_port_t port; struct ip_addr ip; if (net_str2hostport(endpoint, CARBON_SERVER_DEFAULT_PORT, &host, &port) < 0 || net_addr2ip(host, &ip) < 0) { i_error("stats_submit: Cannot parse endpoint '%s'", endpoint); return -1; } pool_t pool = pool_alloconly_create("stats carbon send", 1024); struct stats_send_ctx *ctx = p_new(pool, struct stats_send_ctx, 1); ctx->pool = pool; ctx->str = p_strdup(ctx->pool, data); ctx->fd = net_connect_ip(&ip, port, NULL); if (ctx->fd < 0) { i_error("connect(%s) failed: %m", endpoint); stats_carbon_callback(ctx); return -1; } ctx->io = io_add(ctx->fd, IO_WRITE, stats_carbon_connected, ctx); /* give time for almost until next update this is to ensure we leave a little pause between attempts. Multiplier 800 gives us 20% window, and ensures the number stays positive. */ ctx->to_msecs = stats_settings->carbon_interval*800; ctx->to = timeout_add(ctx->to_msecs, stats_carbon_timeout, ctx); if (net_ipport2str(&ip, port, &host) < 0) i_unreached(); ctx->endpoint = p_strdup(ctx->pool, host); ctx->callback = callback; ctx->ctx = cb_ctx; *ctx_r = ctx; return 0; }
static int login_proxy_connect(struct login_proxy *proxy) { struct login_proxy_record *rec = proxy->state_rec; /* this needs to be done early, since login_proxy_free() shrinks num_waiting_connections. */ proxy->num_waiting_connections_updated = FALSE; rec->num_waiting_connections++; if (proxy->ip.family == 0 && net_addr2ip(proxy->host, &proxy->ip) < 0) { client_log_err(proxy->client, t_strdup_printf( "proxy(%s): BUG: host %s is not an IP " "(auth should have changed it)", proxy->client->virtual_user, proxy->host)); return -1; } if (rec->last_success.tv_sec == 0) { /* first connect to this IP. don't start immediately failing the check below. */ rec->last_success.tv_sec = ioloop_timeval.tv_sec - 1; } if (timeval_cmp(&rec->last_failure, &rec->last_success) > 0 && rec->last_failure.tv_sec - rec->last_success.tv_sec > PROXY_IMMEDIATE_FAILURE_SECS && rec->num_waiting_connections > 1) { /* the server is down. fail immediately */ client_log_err(proxy->client, t_strdup_printf( "proxy(%s): Host %s:%u is down", proxy->client->virtual_user, proxy->host, proxy->port)); return -1; } proxy->server_fd = net_connect_ip(&proxy->ip, proxy->port, proxy->source_ip.family == 0 ? NULL : &proxy->source_ip); if (proxy->server_fd == -1) { proxy_log_connect_error(proxy); return -1; } proxy->server_io = io_add(proxy->server_fd, IO_WRITE, proxy_wait_connect, proxy); if (proxy->connect_timeout_msecs != 0) { proxy->to = timeout_add(proxy->connect_timeout_msecs, proxy_connect_timeout, proxy); } return 0; }
static int lmtp_client_connect(struct lmtp_client *client) { client->fd = net_connect_ip(&client->ip, client->port, NULL); if (client->fd == -1) { i_error("lmtp client: connect(%s, %u) failed: %m", client->host, client->port); return -1; } client->input = i_stream_create_fd(client->fd, LMTP_MAX_LINE_LEN, FALSE); client->output = o_stream_create_fd(client->fd, (size_t)-1, FALSE); o_stream_set_flush_callback(client->output, lmtp_client_output, client); /* we're already sending data in ostream, so can't use IO_WRITE here */ client->io = io_add(client->fd, IO_READ, lmtp_client_wait_connect, client); return 0; }
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 replicator_connection_connect(struct replicator_connection *conn) { unsigned int n; int fd = -1; if (conn->fd != -1) return; if (conn->port == 0) { fd = net_connect_unix(conn->path); if (fd == -1) i_error("net_connect_unix(%s) failed: %m", conn->path); } else { for (n = 0; n < conn->ips_count; n++) { unsigned int idx = conn->ip_idx; conn->ip_idx = (conn->ip_idx + 1) % conn->ips_count; fd = net_connect_ip(&conn->ips[idx], conn->port, NULL); if (fd != -1) break; i_error("connect(%s, %u) failed: %m", net_ip2addr(&conn->ips[idx]), conn->port); } } if (fd == -1) { if (conn->to == NULL) { conn->to = timeout_add(REPLICATOR_RECONNECT_MSECS, replicator_connection_connect, conn); } return; } if (conn->to != NULL) timeout_remove(&conn->to); conn->fd = fd; conn->io = io_add(fd, IO_READ, replicator_input, conn); conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE); o_stream_set_no_error_handling(conn->output, TRUE); o_stream_nsend_str(conn->output, REPLICATOR_HANDSHAKE); o_stream_set_flush_callback(conn->output, replicator_output, conn); }
static void dcc_chat_connect(DCC_REC *dcc) { g_return_if_fail(dcc != NULL); if (dcc->addrstr[0] == '\0' || dcc->starttime != 0) { /* already sent a chat request / already chatting */ return; } dcc->handle = net_connect_ip(&dcc->addr, dcc->port, source_host_ok ? source_host_ip : NULL); if (dcc->handle != -1) { dcc->tagread = g_input_add(dcc->handle, G_INPUT_WRITE|G_INPUT_READ|G_INPUT_EXCEPTION, (GInputFunction) sig_chat_connected, dcc); } else { /* error connecting */ signal_emit("dcc error connect", 1, dcc); dcc_destroy(dcc); } }
static int login_proxy_connect(struct login_proxy *proxy) { struct login_proxy_record *rec = proxy->state_rec; if (rec->last_success.tv_sec == 0) { /* first connect to this IP. don't start immediately failing the check below. */ rec->last_success.tv_sec = ioloop_timeval.tv_sec - 1; } if (timeval_cmp(&rec->last_failure, &rec->last_success) > 0 && rec->last_failure.tv_sec - rec->last_success.tv_sec > PROXY_IMMEDIATE_FAILURE_SECS && rec->num_waiting_connections != 0) { /* the server is down. fail immediately */ i_error("proxy(%s): Host %s:%u is down", proxy->client->virtual_user, proxy->host, proxy->port); login_proxy_free(&proxy); return -1; } proxy->server_fd = net_connect_ip(&proxy->ip, proxy->port, proxy->source_ip.family == 0 ? NULL : &proxy->source_ip); if (proxy->server_fd == -1) { proxy_log_connect_error(proxy); login_proxy_free(&proxy); return -1; } proxy->server_io = io_add(proxy->server_fd, IO_WRITE, proxy_wait_connect, proxy); if (proxy->connect_timeout_msecs != 0) { proxy->to = timeout_add(proxy->connect_timeout_msecs, proxy_connect_timeout, proxy); } proxy->num_waiting_connections_updated = FALSE; proxy->state_rec = rec; proxy->state_rec->num_waiting_connections++; return 0; }
static void cmd_zlibconnect(int argc ATTR_UNUSED, char *argv[]) { struct client client; struct ip_addr *ips; unsigned int ips_count; in_port_t port = 143; int fd, ret; if (argv[1] == NULL || (argv[2] != NULL && net_str2port(argv[2], &port) < 0)) help(&doveadm_cmd_zlibconnect); ret = net_gethostbyname(argv[1], &ips, &ips_count); if (ret != 0) { i_fatal("Host %s lookup failed: %s", argv[1], net_gethosterror(ret)); } if ((fd = net_connect_ip(&ips[0], port, NULL)) == -1) i_fatal("connect(%s, %u) failed: %m", argv[1], port); i_info("Connected to %s port %u. Ctrl-D starts compression", net_ip2addr(&ips[0]), port); memset(&client, 0, sizeof(client)); client.fd = fd; client.input = i_stream_create_fd(fd, (size_t)-1); client.output = o_stream_create_fd(fd, 0); o_stream_set_no_error_handling(client.output, TRUE); client.io_client = io_add(STDIN_FILENO, IO_READ, client_input, &client); client.io_server = io_add(fd, IO_READ, server_input, &client); master_service_run(master_service, NULL); io_remove(&client.io_client); io_remove(&client.io_server); i_stream_unref(&client.input); o_stream_unref(&client.output); if (close(fd) < 0) i_fatal("close() failed: %m"); }
void dcc_get_connect(GET_DCC_REC *dcc) { if (dcc->get_type == DCC_GET_DEFAULT) { dcc->get_type = settings_get_bool("dcc_autorename") ? DCC_GET_RENAME : DCC_GET_OVERWRITE; } dcc->handle = net_connect_ip(&dcc->addr, dcc->port, source_host_ok ? source_host_ip : NULL); if (dcc->handle != NULL) { dcc->tagconn = g_input_add(dcc->handle, G_INPUT_WRITE | G_INPUT_READ, (GInputFunction) sig_dccget_connected, dcc); } else { /* error connecting */ signal_emit("dcc error connect", 1, dcc); dcc_destroy(DCC(dcc)); } }