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 fd;
00051 DBusWatch *watch;
00052 char *socket_name;
00053 };
00054
00055 static void
00056 socket_finalize (DBusServer *server)
00057 {
00058 DBusServerSocket *socket_server = (DBusServerSocket*) server;
00059
00060 _dbus_server_finalize_base (server);
00061
00062 if (socket_server->watch)
00063 {
00064 _dbus_watch_unref (socket_server->watch);
00065 socket_server->watch = NULL;
00066 }
00067
00068 dbus_free (socket_server->socket_name);
00069 dbus_free (server);
00070 }
00071
00072
00073 static dbus_bool_t
00074 handle_new_client_fd_and_unlock (DBusServer *server,
00075 int client_fd)
00076 {
00077 DBusConnection *connection;
00078 DBusTransport *transport;
00079 DBusNewConnectionFunction new_connection_function;
00080 void *new_connection_data;
00081
00082 _dbus_verbose ("Creating new client connection with fd %d\n", client_fd);
00083
00084 HAVE_LOCK_CHECK (server);
00085
00086 if (!_dbus_set_fd_nonblocking (client_fd, NULL))
00087 {
00088 SERVER_UNLOCK (server);
00089 return TRUE;
00090 }
00091
00092 transport = _dbus_transport_new_for_socket (client_fd, &server->guid_hex, NULL);
00093 if (transport == NULL)
00094 {
00095 _dbus_close_socket (client_fd, NULL);
00096 SERVER_UNLOCK (server);
00097 return FALSE;
00098 }
00099
00100 if (!_dbus_transport_set_auth_mechanisms (transport,
00101 (const char **) server->auth_mechanisms))
00102 {
00103 _dbus_transport_unref (transport);
00104 SERVER_UNLOCK (server);
00105 return FALSE;
00106 }
00107
00108
00109
00110
00111
00112 connection = _dbus_connection_new_for_transport (transport);
00113 _dbus_transport_unref (transport);
00114 transport = NULL;
00115
00116 if (connection == NULL)
00117 {
00118 SERVER_UNLOCK (server);
00119 return FALSE;
00120 }
00121
00122
00123
00124
00125 new_connection_function = server->new_connection_function;
00126 new_connection_data = server->new_connection_data;
00127
00128 _dbus_server_ref_unlocked (server);
00129 SERVER_UNLOCK (server);
00130
00131 if (new_connection_function)
00132 {
00133 (* new_connection_function) (server, connection,
00134 new_connection_data);
00135 }
00136 dbus_server_unref (server);
00137
00138
00139 _dbus_connection_close_if_only_one_ref (connection);
00140 dbus_connection_unref (connection);
00141
00142 return TRUE;
00143 }
00144
00145 static dbus_bool_t
00146 socket_handle_watch (DBusWatch *watch,
00147 unsigned int flags,
00148 void *data)
00149 {
00150 DBusServer *server = data;
00151 DBusServerSocket *socket_server = data;
00152
00153 SERVER_LOCK (server);
00154
00155 _dbus_assert (watch == socket_server->watch);
00156
00157 _dbus_verbose ("Handling client connection, flags 0x%x\n", flags);
00158
00159 if (flags & DBUS_WATCH_READABLE)
00160 {
00161 int client_fd;
00162 int listen_fd;
00163
00164 listen_fd = dbus_watch_get_fd (watch);
00165
00166 client_fd = _dbus_accept (listen_fd);
00167
00168 if (client_fd < 0)
00169 {
00170
00171
00172 if (errno == EAGAIN || errno == EWOULDBLOCK)
00173 _dbus_verbose ("No client available to accept after all\n");
00174 else
00175 _dbus_verbose ("Failed to accept a client connection: %s\n",
00176 _dbus_strerror (errno));
00177
00178 SERVER_UNLOCK (server);
00179 }
00180 else
00181 {
00182 _dbus_fd_set_close_on_exec (client_fd);
00183
00184 if (!handle_new_client_fd_and_unlock (server, client_fd))
00185 _dbus_verbose ("Rejected client connection due to lack of memory\n");
00186 }
00187 }
00188
00189 if (flags & DBUS_WATCH_ERROR)
00190 _dbus_verbose ("Error on server listening socket\n");
00191
00192 if (flags & DBUS_WATCH_HANGUP)
00193 _dbus_verbose ("Hangup on server listening socket\n");
00194
00195 return TRUE;
00196 }
00197
00198 static void
00199 socket_disconnect (DBusServer *server)
00200 {
00201 DBusServerSocket *socket_server = (DBusServerSocket*) server;
00202
00203 HAVE_LOCK_CHECK (server);
00204
00205 if (socket_server->watch)
00206 {
00207 _dbus_server_remove_watch (server,
00208 socket_server->watch);
00209 _dbus_watch_unref (socket_server->watch);
00210 socket_server->watch = NULL;
00211 }
00212
00213 _dbus_close_socket (socket_server->fd, NULL);
00214 socket_server->fd = -1;
00215
00216 if (socket_server->socket_name != NULL)
00217 {
00218 DBusString tmp;
00219 _dbus_string_init_const (&tmp, socket_server->socket_name);
00220 _dbus_delete_file (&tmp, NULL);
00221 }
00222
00223 HAVE_LOCK_CHECK (server);
00224 }
00225
00226 static const DBusServerVTable socket_vtable = {
00227 socket_finalize,
00228 socket_disconnect
00229 };
00230
00244 DBusServer*
00245 _dbus_server_new_for_socket (int fd,
00246 const DBusString *address)
00247 {
00248 DBusServerSocket *socket_server;
00249 DBusServer *server;
00250 DBusWatch *watch;
00251
00252 socket_server = dbus_new0 (DBusServerSocket, 1);
00253 if (socket_server == NULL)
00254 return NULL;
00255
00256 watch = _dbus_watch_new (fd,
00257 DBUS_WATCH_READABLE,
00258 TRUE,
00259 socket_handle_watch, socket_server,
00260 NULL);
00261 if (watch == NULL)
00262 {
00263 dbus_free (socket_server);
00264 return NULL;
00265 }
00266
00267 if (!_dbus_server_init_base (&socket_server->base,
00268 &socket_vtable, address))
00269 {
00270 _dbus_watch_unref (watch);
00271 dbus_free (socket_server);
00272 return NULL;
00273 }
00274
00275 server = (DBusServer*) socket_server;
00276
00277 SERVER_LOCK (server);
00278
00279 if (!_dbus_server_add_watch (&socket_server->base,
00280 watch))
00281 {
00282 SERVER_UNLOCK (server);
00283 _dbus_server_finalize_base (&socket_server->base);
00284 _dbus_watch_unref (watch);
00285 dbus_free (socket_server);
00286 return NULL;
00287 }
00288
00289 socket_server->fd = fd;
00290 socket_server->watch = watch;
00291
00292 SERVER_UNLOCK (server);
00293
00294 return (DBusServer*) socket_server;
00295 }
00296
00306 DBusServer*
00307 _dbus_server_new_for_tcp_socket (const char *host,
00308 dbus_uint32_t port,
00309 DBusError *error)
00310 {
00311 DBusServer *server;
00312 int listen_fd;
00313 DBusString address;
00314 DBusString host_str;
00315
00316 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00317
00318 if (!_dbus_string_init (&address))
00319 {
00320 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00321 return NULL;
00322 }
00323
00324 if (host == NULL)
00325 host = "localhost";
00326
00327 listen_fd = _dbus_listen_tcp_socket (host, &port, error);
00328 _dbus_fd_set_close_on_exec (listen_fd);
00329
00330 _dbus_string_init_const (&host_str, host);
00331 if (!_dbus_string_append (&address, "tcp:host=") ||
00332 !_dbus_address_append_escaped (&address, &host_str) ||
00333 !_dbus_string_append (&address, ",port=") ||
00334 !_dbus_string_append_int (&address, port))
00335 {
00336 _dbus_string_free (&address);
00337 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00338 return NULL;
00339 }
00340
00341
00342 if (listen_fd < 0)
00343 {
00344 _dbus_string_free (&address);
00345 return NULL;
00346 }
00347
00348 server = _dbus_server_new_for_socket (listen_fd, &address);
00349 if (server == NULL)
00350 {
00351 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00352 _dbus_close_socket (listen_fd, NULL);
00353 _dbus_string_free (&address);
00354 return NULL;
00355 }
00356
00357 _dbus_string_free (&address);
00358
00359 return server;
00360
00361
00362 }
00363
00376 DBusServerListenResult
00377 _dbus_server_listen_socket (DBusAddressEntry *entry,
00378 DBusServer **server_p,
00379 DBusError *error)
00380 {
00381 const char *method;
00382
00383 *server_p = NULL;
00384
00385 method = dbus_address_entry_get_method (entry);
00386
00387 if (strcmp (method, "tcp") == 0)
00388 {
00389 const char *host = dbus_address_entry_get_value (entry, "host");
00390 const char *port = dbus_address_entry_get_value (entry, "port");
00391 DBusString str;
00392 long lport;
00393 dbus_bool_t sresult;
00394
00395 if (port == NULL)
00396 {
00397 _dbus_set_bad_address(error, "tcp", "port", NULL);
00398 return DBUS_SERVER_LISTEN_BAD_ADDRESS;
00399 }
00400
00401 _dbus_string_init_const (&str, port);
00402 sresult = _dbus_string_parse_int (&str, 0, &lport, NULL);
00403 _dbus_string_free (&str);
00404
00405 if (sresult == FALSE || lport < 0 || lport > 65535)
00406 {
00407 _dbus_set_bad_address(error, NULL, NULL,
00408 "Port is not an integer between 0 and 65535");
00409 return DBUS_SERVER_LISTEN_BAD_ADDRESS;
00410 }
00411
00412 *server_p = _dbus_server_new_for_tcp_socket (host, lport, error);
00413
00414 if (*server_p)
00415 {
00416 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00417 return DBUS_SERVER_LISTEN_OK;
00418 }
00419 else
00420 {
00421 _DBUS_ASSERT_ERROR_IS_SET(error);
00422 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00423 }
00424 }
00425 else
00426 {
00427 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00428 return DBUS_SERVER_LISTEN_NOT_HANDLED;
00429 }
00430 }
00431
00441 void
00442 _dbus_server_socket_own_filename (DBusServer *server,
00443 char *filename)
00444 {
00445 DBusServerSocket *socket_server = (DBusServerSocket*) server;
00446
00447 socket_server->socket_name = filename;
00448 }
00449
00450