]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/thrift/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.c
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / jaegertracing / thrift / lib / c_glib / src / thrift / c_glib / transport / thrift_server_socket.c
1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 #include <errno.h>
21 #include <netdb.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <sys/socket.h>
26 #include <sys/un.h>
27 #include <netinet/in.h>
28
29 #include <thrift/c_glib/thrift.h>
30 #include <thrift/c_glib/transport/thrift_socket.h>
31 #include <thrift/c_glib/transport/thrift_transport.h>
32 #include <thrift/c_glib/transport/thrift_server_transport.h>
33 #include <thrift/c_glib/transport/thrift_server_socket.h>
34
35 /* object properties */
36 enum _ThriftServerSocketProperties
37 {
38 PROP_0,
39 PROP_THRIFT_SERVER_SOCKET_PORT,
40 PROP_THRIFT_SERVER_SOCKET_PATH,
41 PROP_THRIFT_SERVER_SOCKET_BACKLOG
42 };
43
44 /* define the GError domain string */
45 #define THRIFT_SERVER_SOCKET_ERROR_DOMAIN "thrift-server-socket-error-quark"
46
47 G_DEFINE_TYPE(ThriftServerSocket, thrift_server_socket, THRIFT_TYPE_SERVER_TRANSPORT)
48
49 gboolean
50 thrift_server_socket_listen (ThriftServerTransport *transport, GError **error)
51 {
52 int enabled = 1; /* for setsockopt() */
53 ThriftServerSocket *tsocket = THRIFT_SERVER_SOCKET (transport);
54
55 const int socket_domain = tsocket->path ? PF_UNIX : AF_INET;
56
57 /* create a socket */
58 if ((tsocket->sd = socket (socket_domain, SOCK_STREAM, 0)) == -1)
59 {
60 g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
61 THRIFT_SERVER_SOCKET_ERROR_SOCKET,
62 "failed to create socket - %s", strerror (errno));
63 return FALSE;
64 }
65
66 if (setsockopt(tsocket->sd, SOL_SOCKET, SO_REUSEADDR, &enabled,
67 sizeof(enabled)) == -1)
68 {
69 g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
70 THRIFT_SERVER_SOCKET_ERROR_SETSOCKOPT,
71 "unable to set SO_REUSEADDR - %s", strerror(errno));
72 return FALSE;
73 }
74
75 /* bind to the socket */
76 if (tsocket->path)
77 {
78 /* create a socket structure */
79 struct sockaddr_un pin;
80 memset (&pin, 0, sizeof(pin));
81 pin.sun_family = AF_UNIX;
82 memcpy(pin.sun_path, tsocket->path, strlen(tsocket->path) + 1);
83
84 if (bind(tsocket->sd, (struct sockaddr *) &pin, sizeof(pin)) == -1)
85 {
86 g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
87 THRIFT_SERVER_SOCKET_ERROR_BIND,
88 "failed to bind to path %s: - %s",
89 tsocket->path, strerror(errno));
90 return FALSE;
91 }
92 }
93 else
94 {
95 /* create a address structure */
96 struct sockaddr_in pin;
97 memset (&pin, 0, sizeof(pin));
98 pin.sin_family = AF_INET;
99 pin.sin_addr.s_addr = INADDR_ANY;
100 pin.sin_port = htons(tsocket->port);
101
102 if (bind(tsocket->sd, (struct sockaddr *) &pin, sizeof(pin)) == -1)
103 {
104 g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
105 THRIFT_SERVER_SOCKET_ERROR_BIND,
106 "failed to bind to port %d - %s",
107 tsocket->port, strerror(errno));
108 return FALSE;
109 }
110 }
111
112 if (listen(tsocket->sd, tsocket->backlog) == -1)
113 {
114 if (tsocket->path)
115 {
116 g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
117 THRIFT_SERVER_SOCKET_ERROR_BIND,
118 "failed to bind to path %s: - %s",
119 tsocket->path, strerror(errno));
120 return FALSE;
121 }
122 else
123 {
124 g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
125 THRIFT_SERVER_SOCKET_ERROR_LISTEN,
126 "failed to listen to port %d - %s",
127 tsocket->port, strerror(errno));
128 return FALSE;
129 }
130 }
131
132 return TRUE;
133 }
134
135 ThriftTransport *
136 thrift_server_socket_accept (ThriftServerTransport *transport, GError **error)
137 {
138 int sd = THRIFT_INVALID_SOCKET;
139 guint addrlen = 0;
140 struct sockaddr_in address;
141 ThriftSocket *socket = NULL;
142
143 ThriftServerSocket *tsocket = THRIFT_SERVER_SOCKET (transport);
144
145 if ((sd = accept(tsocket->sd, (struct sockaddr *) &address, &addrlen)) == -1)
146 {
147 g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
148 THRIFT_SERVER_SOCKET_ERROR_ACCEPT,
149 "failed to accept connection - %s",
150 strerror(errno));
151 return FALSE;
152 }
153
154 socket = g_object_new (THRIFT_TYPE_SOCKET, NULL);
155 socket->sd = sd;
156
157 return THRIFT_TRANSPORT(socket);
158 }
159
160 gboolean
161 thrift_server_socket_close (ThriftServerTransport *transport, GError **error)
162 {
163 ThriftServerSocket *tsocket = THRIFT_SERVER_SOCKET (transport);
164
165 if (close (tsocket->sd) == -1)
166 {
167 g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
168 THRIFT_SERVER_SOCKET_ERROR_CLOSE,
169 "unable to close socket - %s", strerror(errno));
170 return FALSE;
171 }
172 tsocket->sd = THRIFT_INVALID_SOCKET;
173
174 return TRUE;
175 }
176
177 /* define the GError domain for this implementation */
178 GQuark
179 thrift_server_socket_error_quark (void)
180 {
181 return g_quark_from_static_string(THRIFT_SERVER_SOCKET_ERROR_DOMAIN);
182 }
183
184 /* initializes the instance */
185 static void
186 thrift_server_socket_init (ThriftServerSocket *socket)
187 {
188 socket->sd = THRIFT_INVALID_SOCKET;
189 }
190
191 /* destructor */
192 static void
193 thrift_server_socket_finalize (GObject *object)
194 {
195 ThriftServerSocket *socket = THRIFT_SERVER_SOCKET (object);
196
197 if (socket->sd != THRIFT_INVALID_SOCKET)
198 {
199 close (socket->sd);
200 }
201 socket->sd = THRIFT_INVALID_SOCKET;
202 }
203
204 /* property accessor */
205 void
206 thrift_server_socket_get_property (GObject *object, guint property_id,
207 GValue *value, GParamSpec *pspec)
208 {
209 ThriftServerSocket *socket = THRIFT_SERVER_SOCKET (object);
210
211 switch (property_id)
212 {
213 case PROP_THRIFT_SERVER_SOCKET_PORT:
214 g_value_set_uint (value, socket->port);
215 break;
216 case PROP_THRIFT_SERVER_SOCKET_PATH:
217 g_value_set_string (value, socket->path);
218 break;
219 case PROP_THRIFT_SERVER_SOCKET_BACKLOG:
220 g_value_set_uint (value, socket->backlog);
221 break;
222 default:
223 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
224 break;
225 }
226 }
227
228 /* property mutator */
229 void
230 thrift_server_socket_set_property (GObject *object, guint property_id,
231 const GValue *value, GParamSpec *pspec)
232 {
233 ThriftServerSocket *socket = THRIFT_SERVER_SOCKET (object);
234
235 switch (property_id)
236 {
237 case PROP_THRIFT_SERVER_SOCKET_PORT:
238 socket->port = g_value_get_uint (value);
239 break;
240 case PROP_THRIFT_SERVER_SOCKET_PATH:
241 if (socket->path) {
242 g_free(socket->path);
243 }
244 socket->path = g_strdup (g_value_get_string (value));
245 break;
246 case PROP_THRIFT_SERVER_SOCKET_BACKLOG:
247 socket->backlog = g_value_get_uint (value);
248 break;
249 default:
250 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
251 break;
252 }
253 }
254
255 /* initializes the class */
256 static void
257 thrift_server_socket_class_init (ThriftServerSocketClass *cls)
258 {
259 ThriftServerTransportClass *tstc = THRIFT_SERVER_TRANSPORT_CLASS (cls);
260 GObjectClass *gobject_class = G_OBJECT_CLASS (cls);
261 GParamSpec *param_spec = NULL;
262
263 /* setup accessors and mutators */
264 gobject_class->get_property = thrift_server_socket_get_property;
265 gobject_class->set_property = thrift_server_socket_set_property;
266
267 param_spec = g_param_spec_uint ("port",
268 "port (construct)",
269 "Set the port to listen to",
270 0, /* min */
271 65535, /* max */
272 9090, /* default by convention */
273 G_PARAM_CONSTRUCT_ONLY |
274 G_PARAM_READWRITE);
275 g_object_class_install_property (gobject_class,
276 PROP_THRIFT_SERVER_SOCKET_PORT,
277 param_spec);
278
279 param_spec = g_param_spec_string ("path",
280 "path (construct)",
281 "Set the path to listen to",
282 NULL, /* default value */
283 G_PARAM_CONSTRUCT_ONLY |
284 G_PARAM_READWRITE);
285 g_object_class_install_property (gobject_class,
286 PROP_THRIFT_SERVER_SOCKET_PATH,
287 param_spec);
288
289 param_spec = g_param_spec_uint ("backlog",
290 "backlog (construct)",
291 "Set the accept backlog",
292 0, /* max */
293 65534, /* max */
294 1024, /* default */
295 G_PARAM_CONSTRUCT_ONLY |
296 G_PARAM_READWRITE);
297 g_object_class_install_property (gobject_class,
298 PROP_THRIFT_SERVER_SOCKET_BACKLOG,
299 param_spec);
300
301 gobject_class->finalize = thrift_server_socket_finalize;
302
303 tstc->listen = thrift_server_socket_listen;
304 tstc->accept = thrift_server_socket_accept;
305 tstc->close = thrift_server_socket_close;
306 }
307