XMMS2
socket_tcp.c
Go to the documentation of this file.
1/* XMMS2 - X Music Multiplexer System
2 * Copyright (C) 2003-2011 XMMS2 Team
3 *
4 * PLUGINS ARE NOT CONSIDERED TO BE DERIVED WORK !!!
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 */
16
17
18#include <stdio.h>
19#include <string.h>
20#include <stdlib.h>
21#include <signal.h>
22#include <assert.h>
23
25#include "xmmsc/xmmsc_util.h"
26#include "xmmsc/xmmsc_sockets.h"
27#include "xmmsc/xmmsc_unistd.h"
28#include "url.h"
29#include "socket_tcp.h"
30
31static void
32xmms_ipc_tcp_destroy (xmms_ipc_transport_t *ipct)
33{
34 free (ipct->path);
35 close (ipct->fd);
36}
37
38static int
39xmms_ipc_tcp_read (xmms_ipc_transport_t *ipct, char *buffer, int len)
40{
42 int ret;
43 x_return_val_if_fail (ipct, -1);
44 x_return_val_if_fail (buffer, -1);
45
46 fd = ipct->fd;
47
48 ret = recv (fd, buffer, len, 0);
49
50 return ret;
51}
52
53static int
54xmms_ipc_tcp_write (xmms_ipc_transport_t *ipct, char *buffer, int len)
55{
57 x_return_val_if_fail (ipct, -1);
58 x_return_val_if_fail (buffer, -1);
59
60 fd = ipct->fd;
61
62 return send (fd, buffer, len, 0);
63
64}
65
68{
69 xmms_socket_t fd = -1;
71 struct addrinfo hints;
72 struct addrinfo *addrinfo;
73 struct addrinfo *addrinfos;
74 int gai_errno;
75
77 return NULL;
78 }
79
80 memset (&hints, 0, sizeof (hints));
81 hints.ai_flags = 0;
82 hints.ai_family = url->host[0] ? (ipv6 ? PF_INET6 : PF_INET) : PF_UNSPEC;
83 hints.ai_socktype = SOCK_STREAM;
84 hints.ai_protocol = 0;
85
86 if ((gai_errno = xmms_getaddrinfo (url->host[0] ? url->host : NULL, url->port[0] ? url->port : XMMS_STRINGIFY (XMMS_DEFAULT_TCP_PORT), &hints, &addrinfos))) {
87 return NULL;
88 }
89
90 for (addrinfo = addrinfos; addrinfo; addrinfo = addrinfo->ai_next) {
91 int _reuseaddr = 1;
92 const char* reuseaddr = (const char*)&_reuseaddr;
93
94 fd = socket (addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol);
95 if (!xmms_socket_valid (fd)) {
96 return NULL;
97 }
98
99 setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, reuseaddr, sizeof (_reuseaddr));
100
101 if (connect (fd, addrinfo->ai_addr, addrinfo->ai_addrlen) == 0) {
102 break;
103 }
104
105 close (fd);
106 }
107
108 xmms_freeaddrinfo (addrinfos);
109
110 if (!addrinfo) {
111 return NULL;
112 }
113
114 assert (fd != -1);
115
116 if (!xmms_socket_set_nonblock (fd)) {
117 close (fd);
118 return NULL;
119 }
120
121 ipct = x_new0 (xmms_ipc_transport_t, 1);
122 ipct->fd = fd;
123 ipct->path = strdup (url->host);
124 ipct->read_func = xmms_ipc_tcp_read;
125 ipct->write_func = xmms_ipc_tcp_write;
126 ipct->destroy_func = xmms_ipc_tcp_destroy;
127
128 return ipct;
129}
130
132xmms_ipc_tcp_accept (xmms_ipc_transport_t *transport)
133{
134 xmms_socket_t fd;
135 struct sockaddr sockaddr;
136 socklen_t socklen;
137
138 x_return_val_if_fail (transport, NULL);
139
140 socklen = sizeof (sockaddr);
141
142 fd = accept (transport->fd, &sockaddr, &socklen);
143 if (xmms_socket_valid (fd)) {
144 int _reuseaddr = 1;
145 int _nodelay = 1;
146 const char* reuseaddr = (const char*)&_reuseaddr;
147 const char* nodelay = (const char*)&_nodelay;
149
150 if (!xmms_socket_set_nonblock (fd)) {
151 close (fd);
152 return NULL;
153 }
154
155 setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, reuseaddr, sizeof (_reuseaddr));
156 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, nodelay, sizeof (_nodelay));
157
158 ret = x_new0 (xmms_ipc_transport_t, 1);
159 ret->fd = fd;
160 ret->read_func = xmms_ipc_tcp_read;
161 ret->write_func = xmms_ipc_tcp_write;
162 ret->destroy_func = xmms_ipc_tcp_destroy;
163
164 return ret;
165 }
166
167 return NULL;
168}
169
172{
173 xmms_socket_t fd = -1;
175 struct addrinfo hints;
176 struct addrinfo *addrinfo;
177 struct addrinfo *addrinfos;
178 int gai_errno;
179
180 if (!xmms_sockets_initialize ()) {
181 return NULL;
182 }
183
184 memset (&hints, 0, sizeof (hints));
185 hints.ai_flags = AI_PASSIVE;
186 hints.ai_family = url->host[0] ? (ipv6 ? PF_INET6 : PF_INET) : PF_UNSPEC;
187 hints.ai_socktype = SOCK_STREAM;
188 hints.ai_protocol = 0;
189
190 if ((gai_errno = xmms_getaddrinfo (url->host[0] ? url->host : NULL, url->port[0] ? url->port : XMMS_STRINGIFY (XMMS_DEFAULT_TCP_PORT), &hints, &addrinfos))) {
191 return NULL;
192 }
193
194 for (addrinfo = addrinfos; addrinfo; addrinfo = addrinfo->ai_next) {
195 int _reuseaddr = 1;
196 int _nodelay = 1;
197 const char* reuseaddr = (const char*)&_reuseaddr;
198 const char* nodelay = (const char*)&_nodelay;
199
200 fd = socket (addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol);
201 if (!xmms_socket_valid (fd)) {
202 return NULL;
203 }
204
205 setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, reuseaddr, sizeof (_reuseaddr));
206 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, nodelay, sizeof (_nodelay));
207
208 if (bind (fd, addrinfo->ai_addr, addrinfo->ai_addrlen) != SOCKET_ERROR &&
209 listen (fd, SOMAXCONN) != SOCKET_ERROR) {
210 break;
211 }
212 close (fd);
213 }
214
215 xmms_freeaddrinfo (addrinfos);
216
217 if (!addrinfo) {
218 return NULL;
219 }
220
221 assert (fd != -1);
222
223 if (!xmms_socket_set_nonblock (fd)) {
224 close (fd);
225 return NULL;
226 }
227
228 ipct = x_new0 (xmms_ipc_transport_t, 1);
229 ipct->fd = fd;
230 ipct->path = strdup (url->host);
231 ipct->read_func = xmms_ipc_tcp_read;
232 ipct->write_func = xmms_ipc_tcp_write;
233 ipct->accept_func = xmms_ipc_tcp_accept;
234 ipct->destroy_func = xmms_ipc_tcp_destroy;
235
236 return ipct;
237}
238
xmms_ipc_transport_t * xmms_ipc_tcp_server_init(const xmms_url_t *url, int ipv6)
Definition socket_tcp.c:171
xmms_ipc_transport_t * xmms_ipc_tcp_client_init(const xmms_url_t *url, int ipv6)
Definition socket_tcp.c:67
xmms_ipc_accept_func accept_func
xmms_ipc_read_func read_func
xmms_ipc_destroy_func destroy_func
xmms_ipc_write_func write_func
char * port
Definition url.h:9
char * host
Definition url.h:9
#define SOCKET_ERROR
int xmms_sockets_initialize(void)
Definition socket_unix.c:5
int xmms_socket_t
void xmms_freeaddrinfo(struct addrinfo *res)
int xmms_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res)
int xmms_socket_valid(xmms_socket_t socket)
Definition socket_unix.c:36
int xmms_socket_set_nonblock(xmms_socket_t socket)
Tries to set socket to non-blocking mode.
Definition socket_unix.c:15
#define XMMS_DEFAULT_TCP_PORT
Definition xmmsc_util.h:46
#define XMMS_STRINGIFY(x)
Definition xmmsc_util.h:10
#define x_return_val_if_fail(expr, val)
Definition xmmsc_util.h:13
#define x_new0(type, num)
Definition xmmsc_util.h:16