dbus-server.c revision 6d22cfa65a3b77e91d2282d52d37bab9fff3db8d
1/* -*- mode: C; c-file-style: "gnu" -*- */ 2/* dbus-server.c DBusServer object 3 * 4 * Copyright (C) 2002 Red Hat Inc. 5 * 6 * Licensed under the Academic Free License version 1.2 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * 22 */ 23#include "dbus-server.h" 24#include "dbus-server-unix.h" 25#ifdef DBUS_BUILD_TESTS 26#include "dbus-server-debug.h" 27#endif 28#include "dbus-address.h" 29 30/** 31 * @defgroup DBusServer DBusServer 32 * @ingroup DBus 33 * @brief Server that listens for new connections. 34 * 35 * Types and functions related to DBusServer. 36 * A DBusServer represents a server that other applications 37 * can connect to. Each connection from another application 38 * is represented by a DBusConnection. 39 */ 40 41/** 42 * @defgroup DBusServerInternals DBusServer implementation details 43 * @ingroup DBusInternals 44 * @brief Implementation details of DBusServer 45 * 46 * @{ 47 */ 48 49/** 50 * Initializes the members of the DBusServer base class. 51 * Chained up to by subclass constructors. 52 * 53 * @param server the server. 54 * @param vtable the vtable for the subclass. 55 * @returns #TRUE on success. 56 */ 57dbus_bool_t 58_dbus_server_init_base (DBusServer *server, 59 const DBusServerVTable *vtable) 60{ 61 server->vtable = vtable; 62 server->refcount = 1; 63 64 server->watches = _dbus_watch_list_new (); 65 if (server->watches == NULL) 66 return FALSE; 67 68 server->timeouts = _dbus_timeout_list_new (); 69 if (server->timeouts == NULL) 70 { 71 _dbus_watch_list_free (server->watches); 72 server->watches = NULL; 73 return FALSE; 74 } 75 76 server->connection_counter = _dbus_counter_new (); 77 if (server->connection_counter == NULL) 78 { 79 _dbus_watch_list_free (server->watches); 80 server->watches = NULL; 81 _dbus_timeout_list_free (server->timeouts); 82 server->timeouts = NULL; 83 84 return FALSE; 85 } 86 87 server->max_connections = 256; /* same as an X server, seems like a nice default */ 88 89 return TRUE; 90} 91 92/** 93 * Finalizes the members of the DBusServer base class. 94 * Chained up to by subclass finalizers. 95 * 96 * @param server the server. 97 */ 98void 99_dbus_server_finalize_base (DBusServer *server) 100{ 101 dbus_server_set_new_connection_function (server, NULL, NULL, NULL); 102 103 if (!server->disconnected) 104 dbus_server_disconnect (server); 105 106 _dbus_watch_list_free (server->watches); 107 _dbus_timeout_list_free (server->timeouts); 108 _dbus_counter_unref (server->connection_counter); 109} 110 111/** 112 * Adds a watch for this server, chaining out to application-provided 113 * watch handlers. 114 * 115 * @param server the server. 116 * @param watch the watch to add. 117 */ 118dbus_bool_t 119_dbus_server_add_watch (DBusServer *server, 120 DBusWatch *watch) 121{ 122 return _dbus_watch_list_add_watch (server->watches, watch); 123} 124 125/** 126 * Removes a watch previously added with _dbus_server_remove_watch(). 127 * 128 * @param server the server. 129 * @param watch the watch to remove. 130 */ 131void 132_dbus_server_remove_watch (DBusServer *server, 133 DBusWatch *watch) 134{ 135 _dbus_watch_list_remove_watch (server->watches, watch); 136} 137 138/** 139 * Adds a timeout for this server, chaining out to application-provided 140 * timeout handlers. 141 * 142 * @param server the server. 143 * @param timeout the timeout to add. 144 */ 145dbus_bool_t 146_dbus_server_add_timeout (DBusServer *server, 147 DBusTimeout *timeout) 148{ 149 return _dbus_timeout_list_add_timeout (server->timeouts, timeout); 150} 151 152/** 153 * Removes a timeout previously added with _dbus_server_add_timeout(). 154 * 155 * @param server the server. 156 * @param timeout the timeout to remove. 157 */ 158void 159_dbus_server_remove_timeout (DBusServer *server, 160 DBusTimeout *timeout) 161{ 162 _dbus_timeout_list_remove_timeout (server->timeouts, timeout); 163} 164 165/** @} */ 166 167/** 168 * @addtogroup DBusServer 169 * 170 * @{ 171 */ 172 173 174/** 175 * @typedef DBusServer 176 * 177 * An opaque object representing a server that listens for 178 * connections from other applications. Each time a connection 179 * is made, a new DBusConnection is created and made available 180 * via an application-provided DBusNewConnectionFunction. 181 * The DBusNewConnectionFunction is provided with 182 * dbus_server_set_new_connection_function(). 183 * 184 */ 185 186/** 187 * Listens for new connections on the given address. 188 * Returns #NULL if listening fails for any reason. 189 * Otherwise returns a new #DBusServer. 190 * dbus_server_set_new_connection_function() and 191 * dbus_server_set_watch_functions() should be called 192 * immediately to render the server fully functional. 193 * 194 * @todo error messages on bad address could really be better. 195 * DBusResultCode is a bit limiting here. 196 * 197 * @param address the address of this server. 198 * @param result location to store rationale for failure. 199 * @returns a new DBusServer, or #NULL on failure. 200 * 201 */ 202DBusServer* 203dbus_server_listen (const char *address, 204 DBusResultCode *result) 205{ 206 DBusServer *server; 207 DBusAddressEntry **entries; 208 int len, i; 209 210 if (!dbus_parse_address (address, &entries, &len, result)) 211 return NULL; 212 213 server = NULL; 214 215 for (i = 0; i < len; i++) 216 { 217 const char *method = dbus_address_entry_get_method (entries[i]); 218 219 if (strcmp (method, "unix") == 0) 220 { 221 const char *path = dbus_address_entry_get_value (entries[i], "path"); 222 223 if (path == NULL) 224 goto bad_address; 225 226 server = _dbus_server_new_for_domain_socket (path, result); 227 228 if (server) 229 break; 230 } 231#ifdef DBUS_BUILD_TESTS 232 else if (strcmp (method, "debug") == 0) 233 { 234 const char *name = dbus_address_entry_get_value (entries[i], "name"); 235 236 if (name == NULL) 237 goto bad_address; 238 239 server = _dbus_server_debug_new (name, result); 240 241 if (server) 242 break; 243 } 244#endif 245 else 246 goto bad_address; 247 } 248 249 dbus_address_entries_free (entries); 250 return server; 251 252 bad_address: 253 dbus_address_entries_free (entries); 254 dbus_set_result (result, DBUS_RESULT_BAD_ADDRESS); 255 256 return NULL; 257} 258 259/** 260 * Increments the reference count of a DBusServer. 261 * 262 * @param server the server. 263 */ 264void 265dbus_server_ref (DBusServer *server) 266{ 267 server->refcount += 1; 268} 269 270/** 271 * Decrements the reference count of a DBusServer. Finalizes the 272 * server if the reference count reaches zero. The server connection 273 * will be closed as with dbus_server_disconnect() when the server is 274 * finalized. 275 * 276 * @param server the server. 277 */ 278void 279dbus_server_unref (DBusServer *server) 280{ 281 _dbus_assert (server != NULL); 282 _dbus_assert (server->refcount > 0); 283 284 server->refcount -= 1; 285 if (server->refcount == 0) 286 { 287 _dbus_assert (server->vtable->finalize != NULL); 288 289 (* server->vtable->finalize) (server); 290 } 291} 292 293/** 294 * Releases the server's address and stops listening for 295 * new clients. If called more than once, only the first 296 * call has an effect. Does not modify the server's 297 * reference count. 298 * 299 * @param server the server. 300 */ 301void 302dbus_server_disconnect (DBusServer *server) 303{ 304 _dbus_assert (server->vtable->disconnect != NULL); 305 306 if (server->disconnected) 307 return; 308 309 (* server->vtable->disconnect) (server); 310 server->disconnected = TRUE; 311} 312 313/** 314 * Returns #TRUE if the server is still listening for new connections. 315 * 316 * @param server the server. 317 */ 318dbus_bool_t 319dbus_server_get_is_connected (DBusServer *server) 320{ 321 return !server->disconnected; 322} 323 324/** 325 * Sets a function to be used for handling new connections. The given 326 * function is passed each new connection as the connection is 327 * created. If the new connection function increments the connection's 328 * reference count, the connection will stay alive. Otherwise, the 329 * connection will be unreferenced and closed. 330 * 331 * @param server the server. 332 * @param function a function to handle new connections. 333 * @param data data to pass to the new connection handler. 334 * @param free_data_function function to free the data. 335 */ 336void 337dbus_server_set_new_connection_function (DBusServer *server, 338 DBusNewConnectionFunction function, 339 void *data, 340 DBusFreeFunction free_data_function) 341{ 342 if (server->new_connection_free_data_function != NULL) 343 (* server->new_connection_free_data_function) (server->new_connection_data); 344 345 server->new_connection_function = function; 346 server->new_connection_data = data; 347 server->new_connection_free_data_function = free_data_function; 348} 349 350/** 351 * Sets the watch functions for the connection. These functions are 352 * responsible for making the application's main loop aware of file 353 * descriptors that need to be monitored for events. 354 * 355 * This function behaves exactly like dbus_connection_set_watch_functions(); 356 * see the documentation for that routine. 357 * 358 * @param server the server. 359 * @param add_function function to begin monitoring a new descriptor. 360 * @param remove_function function to stop monitoring a descriptor. 361 * @param data data to pass to add_function and remove_function. 362 * @param free_data_function function to be called to free the data. 363 */ 364void 365dbus_server_set_watch_functions (DBusServer *server, 366 DBusAddWatchFunction add_function, 367 DBusRemoveWatchFunction remove_function, 368 void *data, 369 DBusFreeFunction free_data_function) 370{ 371 _dbus_watch_list_set_functions (server->watches, 372 add_function, 373 remove_function, 374 data, 375 free_data_function); 376} 377 378/** 379 * Sets the timeout functions for the connection. These functions are 380 * responsible for making the application's main loop aware of timeouts. 381 * 382 * This function behaves exactly like dbus_connection_set_timeout_functions(); 383 * see the documentation for that routine. 384 * 385 * @param server the server. 386 * @param add_function function to add a timeout. 387 * @param remove_function function to remove a timeout. 388 * @param data data to pass to add_function and remove_function. 389 * @param free_data_function function to be called to free the data. 390 */ 391void 392dbus_server_set_timeout_functions (DBusServer *server, 393 DBusAddTimeoutFunction add_function, 394 DBusRemoveTimeoutFunction remove_function, 395 void *data, 396 DBusFreeFunction free_data_function) 397{ 398 _dbus_timeout_list_set_functions (server->timeouts, 399 add_function, remove_function, 400 data, free_data_function); 401} 402 403/** 404 * Called to notify the server when a previously-added watch 405 * is ready for reading or writing, or has an exception such 406 * as a hangup. 407 * 408 * @param server the server. 409 * @param watch the watch. 410 * @param condition the current condition of the file descriptors being watched. 411 */ 412void 413dbus_server_handle_watch (DBusServer *server, 414 DBusWatch *watch, 415 unsigned int condition) 416{ 417 _dbus_assert (server->vtable->handle_watch != NULL); 418 419 _dbus_watch_sanitize_condition (watch, &condition); 420 421 (* server->vtable->handle_watch) (server, watch, condition); 422} 423 424/** 425 * Sets the maximum number of connections that can be open at one 426 * time for this server. If the maximum is reached, and another 427 * client tries to connect, then the oldest unauthenticated client 428 * will be dropped. If no unauthenticated client exists, then 429 * the new connection will be refused. 430 * 431 * If the maximum is set to a number lower than the current 432 * number of connections, no current connections are 433 * disconnected. 434 * 435 * @todo honoring max_connections has not been implemented 436 * yet. The only real work involved is keeping a list 437 * of live connections on the DBusServer so the oldest 438 * unauthenticated client can be located when required. 439 * 440 * @todo for a systemwide daemon, we need a max number of connections 441 * per user, since any user can authenticate a bunch of connections 442 * and create a DOS. 443 * 444 * @todo a single process might listen on multiple mechanisms 445 * (multiple DBusServer) and might want the max connections 446 * value to span all those servers. Should consider 447 * changing the API accordingly, though I'm inclined to 448 * punt this to the app that wants to do it instead of 449 * putting it in the library. 450 * 451 * @param server the server 452 * @param max_connections maximum number of connections allowed 453 */ 454void 455dbus_server_set_max_connections (DBusServer *server, 456 int max_connections) 457{ 458 server->max_connections = max_connections; 459} 460 461/** 462 * Gets the maximum number of connections that can be active 463 * at a time for this server. 464 * 465 * @param server the server 466 * @returns maximum number of connections at once 467 */ 468int 469dbus_server_get_max_connections (DBusServer *server) 470{ 471 return server->max_connections; 472} 473 474/** 475 * Gets the number of #DBusConnection to this server that 476 * have not yet been finalized. i.e. all #DBusConnection that 477 * were passed to #DBusNewConnectionFunction and have not yet been 478 * finalized will count in this total. 479 * 480 * @param server the server 481 * @returns the number of connections 482 */ 483int 484dbus_server_get_n_connections (DBusServer *server) 485{ 486 return _dbus_counter_get_value (server->connection_counter); 487} 488 489/** @} */ 490 491