Example #1
0
static bool
setup_socket (xmmsc_connection_t *c, xmmsc_vis_udp_t *t, int32_t id, int32_t port) {
	struct addrinfo hints;
	struct addrinfo *result, *rp;
	char *host;
	char portstr[10];
	char packet[1 + sizeof(int32_t)];
	int32_t* packet_id = (int32_t*)&packet[1];
	sprintf (portstr, "%d", port);

	memset (&hints, 0, sizeof (hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_DGRAM;
	hints.ai_flags = 0;
	hints.ai_protocol = 0;

	host = xmms_ipc_hostname (c->path);
	if (!host) {
		host = strdup ("localhost");
	}

	if (xmms_getaddrinfo (host, portstr, &hints, &result) != 0)
	{
		c->error = strdup("Couldn't setup socket!");
		return false;
	}
	free (host);

	for (rp = result; rp != NULL; rp = rp->ai_next) {
		if (!xmms_socket_valid (t->socket[0] = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol))) {
			continue;
		}
		if (connect (t->socket[0], rp->ai_addr, rp->ai_addrlen) != -1) {
			/* Windows doesn't support MSG_DONTWAIT.
			   Why should it? Ripping off BSD, but without mutilating it? No! */
			xmms_socket_set_nonblock (t->socket[0]);
			/* init fallback socket for timing stuff */
			t->socket[1] = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
			connect (t->socket[1], rp->ai_addr, rp->ai_addrlen);
			break;
		} else {
			xmms_socket_close (t->socket[0]);
		}
	}
	if (rp == NULL) {
		c->error = strdup("Could not connect!");
		return false;
	}
	xmms_freeaddrinfo (result);

	packet[0] = 'H';
	*packet_id = htonl (id);
	send (t->socket[0], &packet, sizeof (packet), 0);

	t->timediff = udp_timediff (id, t->socket[1]);
/*	printf ("diff: %f\n", t->timediff); */
	return true;
}
Example #2
0
static xmms_ipc_transport_t *
xmms_ipc_tcp_accept (xmms_ipc_transport_t *transport)
{
	xmms_socket_t fd;
	struct sockaddr sockaddr;
	socklen_t socklen;

	x_return_val_if_fail (transport, NULL);

	socklen = sizeof (sockaddr);

	fd = accept (transport->fd, &sockaddr, &socklen);
	if (xmms_socket_valid (fd)) {
		int _reuseaddr = 1;
		int _nodelay = 1;
		const char* reuseaddr = (const char*)&_reuseaddr;
		const char* nodelay = (const char*)&_nodelay;
		xmms_ipc_transport_t *ret;

		if (!xmms_socket_set_nonblock (fd)) {
			close (fd);
			return NULL;
		}

		setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, reuseaddr, sizeof (_reuseaddr));
		setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, nodelay, sizeof (_nodelay));

		ret = x_new0 (xmms_ipc_transport_t, 1);
		ret->fd = fd;
		ret->read_func = xmms_ipc_tcp_read;
		ret->write_func = xmms_ipc_tcp_write;
		ret->destroy_func = xmms_ipc_tcp_destroy;

		return ret;
	}

	return NULL;
}
Example #3
0
xmms_ipc_transport_t *
xmms_ipc_tcp_client_init (const xmms_url_t *url, int ipv6)
{
	xmms_socket_t fd = -1;
	xmms_ipc_transport_t *ipct;
	struct addrinfo hints;
	struct addrinfo *addrinfo;
	struct addrinfo *addrinfos;
	int gai_errno;

	if (!xmms_sockets_initialize ()) {
		return NULL;
	}

	memset (&hints, 0, sizeof (hints));
	hints.ai_flags = 0;
	hints.ai_family = url->host[0] ? (ipv6 ? PF_INET6 : PF_INET) : PF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = 0;

	if ((gai_errno = xmms_getaddrinfo (url->host[0] ? url->host : NULL, url->port[0] ? url->port : XMMS_STRINGIFY (XMMS_DEFAULT_TCP_PORT), &hints, &addrinfos))) {
		return NULL;
	}

	for (addrinfo = addrinfos; addrinfo; addrinfo = addrinfo->ai_next) {
		int _reuseaddr = 1;
		const char* reuseaddr = (const char*)&_reuseaddr;

		fd = socket (addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol);
		if (!xmms_socket_valid (fd)) {
			return NULL;
		}

		setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, reuseaddr, sizeof (_reuseaddr));

		if (connect (fd, addrinfo->ai_addr, addrinfo->ai_addrlen) == 0) {
			break;
		}

		close (fd);
	}

	xmms_freeaddrinfo (addrinfos);

	if (!addrinfo) {
		return NULL;
	}

	assert (fd != -1);

	if (!xmms_socket_set_nonblock (fd)) {
		close (fd);
		return NULL;
	}

	ipct = x_new0 (xmms_ipc_transport_t, 1);
	ipct->fd = fd;
	ipct->path = strdup (url->host);
	ipct->read_func = xmms_ipc_tcp_read;
	ipct->write_func = xmms_ipc_tcp_write;
	ipct->destroy_func = xmms_ipc_tcp_destroy;

	return ipct;
}