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
/* 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);
}
const char *client_get_session_id(struct client *client)
{
	buffer_t *buf, *base64_buf;
	struct timeval tv;
	uint64_t timestamp;
	unsigned int i;

	if (client->session_id != NULL)
		return client->session_id;

	buf = buffer_create_dynamic(pool_datastack_create(), 24);
	base64_buf = buffer_create_dynamic(pool_datastack_create(), 24*2);

	if (gettimeofday(&tv, NULL) < 0)
		i_fatal("gettimeofday(): %m");
	timestamp = tv.tv_usec + (long long)tv.tv_sec * 1000ULL*1000ULL;

	/* add lowest 48 bits of the timestamp. this gives us a bit less than
	   9 years until it wraps */
	for (i = 0; i < 48; i += 8)
		buffer_append_c(buf, (timestamp >> i) & 0xff);

	buffer_append_c(buf, client->remote_port & 0xff);
	buffer_append_c(buf, (client->remote_port >> 16) & 0xff);
#ifdef HAVE_IPV6
	if (IPADDR_IS_V6(&client->ip))
		buffer_append(buf, &client->ip.u.ip6, sizeof(client->ip.u.ip6));
	else
#endif
		buffer_append(buf, &client->ip.u.ip4, sizeof(client->ip.u.ip4));
	base64_encode(buf->data, buf->used, base64_buf);
	client->session_id = p_strdup(client->pool, str_c(base64_buf));
	return client->session_id;
}
Exemple #4
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 #5
0
/* Start listening for incoming connections */
static GIOChannel *dcc_listen_port(GIOChannel *iface, IPADDR *ip, int port)
{
	if (net_getsockname(iface, ip, NULL) == -1)
		return NULL;

	if (IPADDR_IS_V6(ip))
		return net_listen(NULL, &port);
	else
		return net_listen(&ip4_any, &port);
}
Exemple #6
0
/* Start listening for incoming connections */
GIOChannel *dcc_listen(GIOChannel *iface, IPADDR *ip, int *port)
{
        GIOChannel *handle;
	IPADDR *listen_ip = NULL;
	const char *dcc_port, *p, *own_ip;
	int first, last;

	if (net_getsockname(iface, ip, NULL) == -1)
		return NULL;

	/* figure out if we want to listen in IPv4 address or in "any" address,
	   which may mean IPv4+IPv6 or just IPv6 depending on OS. */
	own_ip = settings_get_str("dcc_own_ip");
	if (*own_ip != '\0') {
		if (is_ipv4_address(own_ip))
			listen_ip = &ip4_any;
	} else {
		if (!IPADDR_IS_V6(ip))
			listen_ip = &ip4_any;
	}

        /* get first port */
	dcc_port = settings_get_str("dcc_port");
	first = atoi(dcc_port);
	if (first == 0) {
                /* random port */
		*port = 0;
		return net_listen(listen_ip, port);
	}

        /* get last port */
	p = strchr(dcc_port, ' ');
	if (p == NULL) p = strchr(dcc_port, '-');

	dcc_port = p;
	if (dcc_port == NULL)
		last = first;
	else {
		last = atoi(dcc_port+1);
		if (last == 0)
			last = first;
	}

        /* use the first available port */
	for (*port = first; *port <= last; (*port)++) {
		handle = net_listen(listen_ip, port);
		if (handle != NULL)
                        return handle;
	}

        return NULL;
}
Exemple #7
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);
	}
}
Exemple #8
0
void dcc_ip2str(IPADDR *ip, char *host)
{
	IPADDR temp_ip;
	guint32 addr;

	if (*settings_get_str("dcc_own_ip") != '\0') {
                /* overridden IP address */
		net_host2ip(settings_get_str("dcc_own_ip"), &temp_ip);
                ip = &temp_ip;
	}

	if (IPADDR_IS_V6(ip)) {
		/* IPv6 */
		net_ip2host(ip, host);
	} else {
		memcpy(&addr, &ip->ip, sizeof(addr));
		g_snprintf(host, MAX_IP_LEN, "%lu",
			   (unsigned long) htonl(addr));
	}
}