Exemple #1
0
/* 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;
}
Exemple #2
0
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);
	}
}
Exemple #3
0
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;
}
Exemple #4
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);
}
Exemple #5
0
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);
}
Exemple #6
0
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;
}
Exemple #7
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);
	}
}
Exemple #8
0
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;
}
Exemple #9
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);
}
Exemple #10
0
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;
}
Exemple #11
0
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);
	}
}
Exemple #12
0
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;
}
Exemple #13
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;
}
Exemple #14
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;
}
Exemple #15
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);
}
Exemple #17
0
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);
	}
}
Exemple #18
0
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;
}
Exemple #19
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");
}
Exemple #20
0
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));
	}
}