D-Bus 1.2.24
|
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 00002 /* dbus-server-socket.c Server implementation for sockets 00003 * 00004 * Copyright (C) 2002, 2003, 2004, 2006 Red Hat Inc. 00005 * 00006 * Licensed under the Academic Free License version 2.1 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 /* Return value is just for memory, not other failures. */ 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 /* note that client_fd is now owned by the transport, and will be 00114 * closed on transport disconnection/finalization 00115 */ 00116 00117 connection = _dbus_connection_new_for_transport (transport); 00118 _dbus_transport_unref (transport); 00119 transport = NULL; /* now under the connection lock */ 00120 00121 if (connection == NULL) 00122 { 00123 SERVER_UNLOCK (server); 00124 return FALSE; 00125 } 00126 00127 /* See if someone wants to handle this new connection, self-referencing 00128 * for paranoia. 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 /* If no one grabbed a reference, the connection will die. */ 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 /* EINTR handled for us */ 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