00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "dbus-internals.h"
00025 #include "dbus-server-socket.h"
00026 #include "dbus-transport-socket.h"
00027 #include "dbus-connection-internal.h"
00028 #include "dbus-string.h"
00029
00041 typedef struct DBusServerSocket DBusServerSocket;
00042
00047 struct DBusServerSocket
00048 {
00049 DBusServer base;
00050 int n_fds;
00051 int *fds;
00052 DBusWatch **watch;
00053 char *socket_name;
00054 };
00055
00056 static void
00057 socket_finalize (DBusServer *server)
00058 {
00059 DBusServerSocket *socket_server = (DBusServerSocket*) server;
00060 int i;
00061
00062 _dbus_server_finalize_base (server);
00063
00064 for (i = 0 ; i < socket_server->n_fds ; i++)
00065 if (socket_server->watch[i])
00066 {
00067 _dbus_watch_unref (socket_server->watch[i]);
00068 socket_server->watch[i] = NULL;
00069 }
00070
00071 dbus_free (socket_server->fds);
00072 dbus_free (socket_server->watch);
00073 dbus_free (socket_server->socket_name);
00074 dbus_free (server);
00075 }
00076
00077
00078 static dbus_bool_t
00079 handle_new_client_fd_and_unlock (DBusServer *server,
00080 int client_fd)
00081 {
00082 DBusConnection *connection;
00083 DBusTransport *transport;
00084 DBusNewConnectionFunction new_connection_function;
00085 void *new_connection_data;
00086
00087 _dbus_verbose ("Creating new client connection with fd %d\n", client_fd);
00088
00089 HAVE_LOCK_CHECK (server);
00090
00091 if (!_dbus_set_fd_nonblocking (client_fd, NULL))
00092 {
00093 SERVER_UNLOCK (server);
00094 return TRUE;
00095 }
00096
00097 transport = _dbus_transport_new_for_socket (client_fd, &server->guid_hex, NULL);
00098 if (transport == NULL)
00099 {
00100 _dbus_close_socket (client_fd, NULL);
00101 SERVER_UNLOCK (server);
00102 return FALSE;
00103 }
00104
00105 if (!_dbus_transport_set_auth_mechanisms (transport,
00106 (const char **) server->auth_mechanisms))
00107 {
00108 _dbus_transport_unref (transport);
00109 SERVER_UNLOCK (server);
00110 return FALSE;
00111 }
00112
00113
00114
00115
00116
00117 connection = _dbus_connection_new_for_transport (transport);
00118 _dbus_transport_unref (transport);
00119 transport = NULL;
00120
00121 if (connection == NULL)
00122 {
00123 SERVER_UNLOCK (server);
00124 return FALSE;
00125 }
00126
00127
00128
00129
00130 new_connection_function = server->new_connection_function;
00131 new_connection_data = server->new_connection_data;
00132
00133 _dbus_server_ref_unlocked (server);
00134 SERVER_UNLOCK (server);
00135
00136 if (new_connection_function)
00137 {
00138 (* new_connection_function) (server, connection,
00139 new_connection_data);
00140 }
00141 dbus_server_unref (server);
00142
00143
00144 _dbus_connection_close_if_only_one_ref (connection);
00145 dbus_connection_unref (connection);
00146
00147 return TRUE;
00148 }
00149
00150 static dbus_bool_t
00151 socket_handle_watch (DBusWatch *watch,
00152 unsigned int flags,
00153 void *data)
00154 {
00155 DBusServer *server = data;
00156 #ifndef DBUS_DISABLE_ASSERT
00157 DBusServerSocket *socket_server = data;
00158 int i;
00159 dbus_bool_t found = FALSE;
00160 #endif
00161
00162 SERVER_LOCK (server);
00163
00164 #ifndef DBUS_DISABLE_ASSERT
00165 for (i = 0 ; i < socket_server->n_fds ; i++)
00166 {
00167 if (socket_server->watch[i] == watch)
00168 found = TRUE;
00169 }
00170 _dbus_assert (found);
00171 #endif
00172
00173 _dbus_verbose ("Handling client connection, flags 0x%x\n", flags);
00174
00175 if (flags & DBUS_WATCH_READABLE)
00176 {
00177 int client_fd;
00178 int listen_fd;
00179
00180 listen_fd = dbus_watch_get_socket (watch);
00181
00182 client_fd = _dbus_accept (listen_fd);
00183
00184 if (client_fd < 0)
00185 {
00186
00187
00188 if (_dbus_get_is_errno_eagain_or_ewouldblock ())
00189 _dbus_verbose ("No client available to accept after all\n");
00190 else
00191 _dbus_verbose ("Failed to accept a client connection: %s\n",
00192 _dbus_strerror_from_errno ());
00193
00194 SERVER_UNLOCK (server);
00195 }
00196 else
00197 {
00198 _dbus_fd_set_close_on_exec (client_fd);
00199
00200 if (!handle_new_client_fd_and_unlock (server, client_fd))
00201 _dbus_verbose ("Rejected client connection due to lack of memory\n");
00202 }
00203 }
00204
00205 if (flags & DBUS_WATCH_ERROR)
00206 _dbus_verbose ("Error on server listening socket\n");
00207
00208 if (flags & DBUS_WATCH_HANGUP)
00209 _dbus_verbose ("Hangup on server listening socket\n");
00210
00211 return TRUE;
00212 }
00213
00214 static void
00215 socket_disconnect (DBusServer *server)
00216 {
00217 DBusServerSocket *socket_server = (DBusServerSocket*) server;
00218 int i;
00219
00220 HAVE_LOCK_CHECK (server);
00221
00222 for (i = 0 ; i < socket_server->n_fds ; i++)
00223 {
00224 if (socket_server->watch[i])
00225 {
00226 _dbus_server_remove_watch (server,
00227 socket_server->watch[i]);
00228 _dbus_watch_unref (socket_server->watch[i]);
00229 socket_server->watch[i] = NULL;
00230 }
00231
00232 _dbus_close_socket (socket_server->fds[i], NULL);
00233 socket_server->fds[i] = -1;
00234 }
00235
00236 if (socket_server->socket_name != NULL)
00237 {
00238 DBusString tmp;
00239 _dbus_string_init_const (&tmp, socket_server->socket_name);
00240 _dbus_delete_file (&tmp, NULL);
00241 }
00242
00243 HAVE_LOCK_CHECK (server);
00244 }
00245
00246 static const DBusServerVTable socket_vtable = {
00247 socket_finalize,
00248 socket_disconnect
00249 };
00250
00265 DBusServer*
00266 _dbus_server_new_for_socket (int *fds,
00267 int n_fds,
00268 const DBusString *address)
00269 {
00270 DBusServerSocket *socket_server;
00271 DBusServer *server;
00272 int i;
00273
00274 socket_server = dbus_new0 (DBusServerSocket, 1);
00275 if (socket_server == NULL)
00276 return NULL;
00277
00278 socket_server->fds = dbus_new (int, n_fds);
00279 if (!socket_server->fds)
00280 goto failed_0;
00281
00282 socket_server->watch = dbus_new0 (DBusWatch *, n_fds);
00283 if (!socket_server->watch)
00284 goto failed_1;
00285
00286 for (i = 0 ; i < n_fds ; i++)
00287 {
00288 DBusWatch *watch;
00289
00290 watch = _dbus_watch_new (fds[i],
00291 DBUS_WATCH_READABLE,
00292 TRUE,
00293 socket_handle_watch, socket_server,
00294 NULL);
00295 if (watch == NULL)
00296 goto failed_2;
00297
00298 socket_server->n_fds++;
00299 socket_server->fds[i] = fds[i];
00300 socket_server->watch[i] = watch;
00301 }
00302
00303 if (!_dbus_server_init_base (&socket_server->base,
00304 &socket_vtable, address))
00305 goto failed_2;
00306
00307 server = (DBusServer*)socket_server;
00308
00309 SERVER_LOCK (server);
00310
00311 for (i = 0 ; i < n_fds ; i++)
00312 {
00313 if (!_dbus_server_add_watch (&socket_server->base,
00314 socket_server->watch[i]))
00315 {
00316 int j;
00317 for (j = 0 ; j < i ; j++)
00318 _dbus_server_remove_watch (server,
00319 socket_server->watch[j]);
00320
00321 SERVER_UNLOCK (server);
00322 _dbus_server_finalize_base (&socket_server->base);
00323 goto failed_2;
00324 }
00325 }
00326
00327 SERVER_UNLOCK (server);
00328
00329 return (DBusServer*) socket_server;
00330
00331 failed_2:
00332 for (i = 0 ; i < n_fds ; i++)
00333 {
00334 if (socket_server->watch[i] != NULL)
00335 {
00336 _dbus_watch_unref (socket_server->watch[i]);
00337 socket_server->watch[i] = NULL;
00338 }
00339 }
00340 dbus_free (socket_server->watch);
00341
00342 failed_1:
00343 dbus_free (socket_server->fds);
00344
00345 failed_0:
00346 dbus_free (socket_server);
00347 return NULL;
00348 }
00349
00368 DBusServer*
00369 _dbus_server_new_for_tcp_socket (const char *host,
00370 const char *bind,
00371 const char *port,
00372 const char *family,
00373 DBusError *error)
00374 {
00375 DBusServer *server;
00376 int *listen_fds = NULL;
00377 int nlisten_fds = 0, i;
00378 DBusString address;
00379 DBusString host_str;
00380 DBusString port_str;
00381
00382 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00383
00384 if (!_dbus_string_init (&address))
00385 {
00386 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00387 return NULL;
00388 }
00389
00390 if (!_dbus_string_init (&port_str))
00391 {
00392 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00393 goto failed_0;
00394 }
00395
00396 if (host == NULL)
00397 host = "localhost";
00398
00399 if (port == NULL)
00400 port = "0";
00401
00402 if (bind == NULL)
00403 bind = host;
00404 else if (strcmp (bind, "*") == 0)
00405 bind = NULL;
00406
00407 nlisten_fds =_dbus_listen_tcp_socket (bind, port, family,
00408 &port_str,
00409 &listen_fds, error);
00410 if (nlisten_fds <= 0)
00411 {
00412 _DBUS_ASSERT_ERROR_IS_SET(error);
00413 goto failed_1;
00414 }
00415
00416 for (i = 0 ; i < nlisten_fds ; i++)
00417 _dbus_fd_set_close_on_exec (listen_fds[i]);
00418
00419 _dbus_string_init_const (&host_str, host);
00420 if (!_dbus_string_append (&address, "tcp:host=") ||
00421 !_dbus_address_append_escaped (&address, &host_str) ||
00422 !_dbus_string_append (&address, ",port=") ||
00423 !_dbus_string_append (&address, _dbus_string_get_const_data(&port_str)))
00424 {
00425 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00426 goto failed_2;
00427 }
00428 if (family &&
00429 (!_dbus_string_append (&address, ",family=") ||
00430 !_dbus_string_append (&address, family)))
00431 {
00432 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00433 goto failed_2;
00434 }
00435
00436 server = _dbus_server_new_for_socket (listen_fds, nlisten_fds, &address);
00437 if (server == NULL)
00438 {
00439 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00440 goto failed_2;
00441 }
00442
00443 _dbus_string_free (&port_str);
00444 _dbus_string_free (&address);
00445 dbus_free(listen_fds);
00446
00447 return server;
00448
00449 failed_2:
00450 for (i = 0 ; i < nlisten_fds ; i++)
00451 _dbus_close_socket (listen_fds[i], NULL);
00452 dbus_free(listen_fds);
00453
00454 failed_1:
00455 _dbus_string_free (&port_str);
00456
00457 failed_0:
00458 _dbus_string_free (&address);
00459
00460 return NULL;
00461 }
00462
00475 DBusServerListenResult
00476 _dbus_server_listen_socket (DBusAddressEntry *entry,
00477 DBusServer **server_p,
00478 DBusError *error)
00479 {
00480 const char *method;
00481
00482 *server_p = NULL;
00483
00484 method = dbus_address_entry_get_method (entry);
00485
00486 if (strcmp (method, "tcp") == 0)
00487 {
00488 const char *host;
00489 const char *port;
00490 const char *bind;
00491 const char *family;
00492
00493 host = dbus_address_entry_get_value (entry, "host");
00494 bind = dbus_address_entry_get_value (entry, "bind");
00495 port = dbus_address_entry_get_value (entry, "port");
00496 family = dbus_address_entry_get_value (entry, "family");
00497
00498 *server_p = _dbus_server_new_for_tcp_socket (host, bind, port,
00499 family, error);
00500
00501 if (*server_p)
00502 {
00503 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00504 return DBUS_SERVER_LISTEN_OK;
00505 }
00506 else
00507 {
00508 _DBUS_ASSERT_ERROR_IS_SET(error);
00509 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00510 }
00511 }
00512 else
00513 {
00514 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00515 return DBUS_SERVER_LISTEN_NOT_HANDLED;
00516 }
00517 }
00518
00528 void
00529 _dbus_server_socket_own_filename (DBusServer *server,
00530 char *filename)
00531 {
00532 DBusServerSocket *socket_server = (DBusServerSocket*) server;
00533
00534 socket_server->socket_name = filename;
00535 }
00536
00537