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 _dbus_string_init_const (&host_str, host);
00328 if (!_dbus_string_append (&address, "tcp:host=") ||
00329 !_dbus_address_append_escaped (&address, &host_str) ||
00330 !_dbus_string_append (&address, ",port=") ||
00331 !_dbus_string_append_int (&address, port))
00332 {
00333 _dbus_string_free (&address);
00334 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00335 return NULL;
00336 }
00337
00338 listen_fd = _dbus_listen_tcp_socket (host, port, error);
00339 _dbus_fd_set_close_on_exec (listen_fd);
00340
00341 if (listen_fd < 0)
00342 {
00343 _dbus_string_free (&address);
00344 return NULL;
00345 }
00346
00347 server = _dbus_server_new_for_socket (listen_fd, &address);
00348 if (server == NULL)
00349 {
00350 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00351 _dbus_close_socket (listen_fd, NULL);
00352 _dbus_string_free (&address);
00353 return NULL;
00354 }
00355
00356 _dbus_string_free (&address);
00357
00358 return server;
00359
00360
00361 }
00362
00375 DBusServerListenResult
00376 _dbus_server_listen_socket (DBusAddressEntry *entry,
00377 DBusServer **server_p,
00378 DBusError *error)
00379 {
00380 const char *method;
00381
00382 *server_p = NULL;
00383
00384 method = dbus_address_entry_get_method (entry);
00385
00386 if (strcmp (method, "tcp") == 0)
00387 {
00388 const char *host = dbus_address_entry_get_value (entry, "host");
00389 const char *port = dbus_address_entry_get_value (entry, "port");
00390 DBusString str;
00391 long lport;
00392 dbus_bool_t sresult;
00393
00394 if (port == NULL)
00395 {
00396 _dbus_set_bad_address(error, "tcp", "port", NULL);
00397 return DBUS_SERVER_LISTEN_BAD_ADDRESS;
00398 }
00399
00400 _dbus_string_init_const (&str, port);
00401 sresult = _dbus_string_parse_int (&str, 0, &lport, NULL);
00402 _dbus_string_free (&str);
00403
00404 if (sresult == FALSE || lport <= 0 || lport > 65535)
00405 {
00406 _dbus_set_bad_address(error, NULL, NULL,
00407 "Port is not an integer between 0 and 65535");
00408 return DBUS_SERVER_LISTEN_BAD_ADDRESS;
00409 }
00410
00411 *server_p = _dbus_server_new_for_tcp_socket (host, lport, error);
00412
00413 if (*server_p)
00414 {
00415 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00416 return DBUS_SERVER_LISTEN_OK;
00417 }
00418 else
00419 {
00420 _DBUS_ASSERT_ERROR_IS_SET(error);
00421 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00422 }
00423 }
00424 else
00425 {
00426 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00427 return DBUS_SERVER_LISTEN_NOT_HANDLED;
00428 }
00429 }
00430
00440 void
00441 _dbus_server_socket_own_filename (DBusServer *server,
00442 char *filename)
00443 {
00444 DBusServerSocket *socket_server = (DBusServerSocket*) server;
00445
00446 socket_server->socket_name = filename;
00447 }
00448
00449