예제 #1
0
파일: udp.c 프로젝트: kfihihc/xmms2-devel
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;
}
예제 #2
0
static void
xmms_visualization_destroy (xmms_object_t *object)
{
	XMMS_DBG ("Deactivating visualization object.");

	xmms_object_unref (vis->output);

	/* TODO: assure that the xform is already dead! */
	g_mutex_clear (&vis->clientlock);
	xmms_log_debug ("starting cleanup of %d vis clients", vis->clientc);
	for (; vis->clientc > 0; --vis->clientc) {
		delete_client (vis->clientc - 1);
	}

	if (xmms_socket_valid (vis->socket)) {
		/* it seems there is no way to remove the watch */
		g_io_channel_shutdown (vis->socketio, FALSE, NULL);
		xmms_socket_close (vis->socket);
	}

	xmms_visualization_unregister_ipc_commands ();
}
예제 #3
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;
}
예제 #4
0
파일: udp.c 프로젝트: theefer/xmms2
int32_t
init_udp (xmms_visualization_t *vis, int32_t id, xmms_error_t *err)
{
	// TODO: we need the currently used port, not only the default one! */
	int32_t port = XMMS_DEFAULT_TCP_PORT;
	xmms_vis_client_t *c;

	// setup socket if needed
	if (!xmms_socket_valid (vis->socket)) {
		struct addrinfo hints;
		struct addrinfo *result, *rp;
		int s;

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

		if ((s = getaddrinfo (NULL, G_STRINGIFY (XMMS_DEFAULT_TCP_PORT), &hints, &result)) != 0)
		{
			xmms_log_error ("Could not setup socket! getaddrinfo: %s", gai_strerror (s));
			xmms_error_set (err, XMMS_ERROR_NO_SAUSAGE, "Could not setup socket!");
			return -1;
		}

		for (rp = result; rp != NULL; rp = rp->ai_next) {
			vis->socket = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol);
			if (!xmms_socket_valid (vis->socket)) {
				continue;
			}
			if (bind (vis->socket, rp->ai_addr, rp->ai_addrlen) != -1) {
				break;
			} else {
				close (vis->socket);
			}
		}
		if (rp == NULL) {
			xmms_log_error ("Could not bind socket!");
			xmms_error_set (err, XMMS_ERROR_NO_SAUSAGE, "Could not bind socket!");
			freeaddrinfo (result);
			return -1;
		}
		freeaddrinfo (result);

		/* register into mainloop: */
/* perhaps needed, perhaps not .. #ifdef __WIN32__
		vis->socketio = g_io_channel_win32_new_socket (vis->socket);
#else */
		vis->socketio = g_io_channel_unix_new (vis->socket);
/*#endif */
		g_io_channel_set_encoding (vis->socketio, NULL, NULL);
		g_io_channel_set_buffered (vis->socketio, FALSE);
		g_io_add_watch (vis->socketio, G_IO_IN, (GIOFunc) udpwatcher, vis);
	}

	/* set up client structure */
	x_fetch_client (id);
	c->type = VIS_UDP;
	memset (&c->transport.udp.addr, 0, sizeof (c->transport.udp.addr));
	c->transport.udp.socket[0] = 0;
	x_release_client ();

	xmms_log_info ("Visualization client %d initialised using UDP", id);
	return port;
}
예제 #5
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;
}