D-Bus
1.10.12
|
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 00002 /* dbus-transport-socket.c Socket subclasses of DBusTransport 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 <config.h> 00025 #include "dbus-internals.h" 00026 #include "dbus-connection-internal.h" 00027 #include "dbus-nonce.h" 00028 #include "dbus-transport-socket.h" 00029 #include "dbus-transport-protected.h" 00030 #include "dbus-watch.h" 00031 #include "dbus-credentials.h" 00032 00044 typedef struct DBusTransportSocket DBusTransportSocket; 00045 00049 struct DBusTransportSocket 00050 { 00051 DBusTransport base; 00052 DBusSocket fd; 00053 DBusWatch *read_watch; 00054 DBusWatch *write_watch; 00056 int max_bytes_read_per_iteration; 00057 int max_bytes_written_per_iteration; 00059 int message_bytes_written; 00063 DBusString encoded_outgoing; 00066 DBusString encoded_incoming; 00069 }; 00070 00071 static void 00072 free_watches (DBusTransport *transport) 00073 { 00074 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 00075 00076 _dbus_verbose ("start\n"); 00077 00078 if (socket_transport->read_watch) 00079 { 00080 if (transport->connection) 00081 _dbus_connection_remove_watch_unlocked (transport->connection, 00082 socket_transport->read_watch); 00083 _dbus_watch_invalidate (socket_transport->read_watch); 00084 _dbus_watch_unref (socket_transport->read_watch); 00085 socket_transport->read_watch = NULL; 00086 } 00087 00088 if (socket_transport->write_watch) 00089 { 00090 if (transport->connection) 00091 _dbus_connection_remove_watch_unlocked (transport->connection, 00092 socket_transport->write_watch); 00093 _dbus_watch_invalidate (socket_transport->write_watch); 00094 _dbus_watch_unref (socket_transport->write_watch); 00095 socket_transport->write_watch = NULL; 00096 } 00097 00098 _dbus_verbose ("end\n"); 00099 } 00100 00101 static void 00102 socket_finalize (DBusTransport *transport) 00103 { 00104 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 00105 00106 _dbus_verbose ("\n"); 00107 00108 free_watches (transport); 00109 00110 _dbus_string_free (&socket_transport->encoded_outgoing); 00111 _dbus_string_free (&socket_transport->encoded_incoming); 00112 00113 _dbus_transport_finalize_base (transport); 00114 00115 _dbus_assert (socket_transport->read_watch == NULL); 00116 _dbus_assert (socket_transport->write_watch == NULL); 00117 00118 dbus_free (transport); 00119 } 00120 00121 static void 00122 check_write_watch (DBusTransport *transport) 00123 { 00124 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 00125 dbus_bool_t needed; 00126 00127 if (transport->connection == NULL) 00128 return; 00129 00130 if (transport->disconnected) 00131 { 00132 _dbus_assert (socket_transport->write_watch == NULL); 00133 return; 00134 } 00135 00136 _dbus_transport_ref (transport); 00137 00138 if (_dbus_transport_try_to_authenticate (transport)) 00139 needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection); 00140 else 00141 { 00142 if (transport->send_credentials_pending) 00143 needed = TRUE; 00144 else 00145 { 00146 DBusAuthState auth_state; 00147 00148 auth_state = _dbus_auth_do_work (transport->auth); 00149 00150 /* If we need memory we install the write watch just in case, 00151 * if there's no need for it, it will get de-installed 00152 * next time we try reading. 00153 */ 00154 if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND || 00155 auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY) 00156 needed = TRUE; 00157 else 00158 needed = FALSE; 00159 } 00160 } 00161 00162 _dbus_verbose ("check_write_watch(): needed = %d on connection %p watch %p fd = %" DBUS_SOCKET_FORMAT " outgoing messages exist %d\n", 00163 needed, transport->connection, socket_transport->write_watch, 00164 _dbus_socket_printable (socket_transport->fd), 00165 _dbus_connection_has_messages_to_send_unlocked (transport->connection)); 00166 00167 _dbus_connection_toggle_watch_unlocked (transport->connection, 00168 socket_transport->write_watch, 00169 needed); 00170 00171 _dbus_transport_unref (transport); 00172 } 00173 00174 static void 00175 check_read_watch (DBusTransport *transport) 00176 { 00177 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 00178 dbus_bool_t need_read_watch; 00179 00180 _dbus_verbose ("fd = %" DBUS_SOCKET_FORMAT "\n", 00181 _dbus_socket_printable (socket_transport->fd)); 00182 00183 if (transport->connection == NULL) 00184 return; 00185 00186 if (transport->disconnected) 00187 { 00188 _dbus_assert (socket_transport->read_watch == NULL); 00189 return; 00190 } 00191 00192 _dbus_transport_ref (transport); 00193 00194 if (_dbus_transport_try_to_authenticate (transport)) 00195 need_read_watch = 00196 (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) && 00197 (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds); 00198 else 00199 { 00200 if (transport->receive_credentials_pending) 00201 need_read_watch = TRUE; 00202 else 00203 { 00204 /* The reason to disable need_read_watch when not WAITING_FOR_INPUT 00205 * is to avoid spinning on the file descriptor when we're waiting 00206 * to write or for some other part of the auth process 00207 */ 00208 DBusAuthState auth_state; 00209 00210 auth_state = _dbus_auth_do_work (transport->auth); 00211 00212 /* If we need memory we install the read watch just in case, 00213 * if there's no need for it, it will get de-installed 00214 * next time we try reading. If we're authenticated we 00215 * install it since we normally have it installed while 00216 * authenticated. 00217 */ 00218 if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT || 00219 auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY || 00220 auth_state == DBUS_AUTH_STATE_AUTHENTICATED) 00221 need_read_watch = TRUE; 00222 else 00223 need_read_watch = FALSE; 00224 } 00225 } 00226 00227 _dbus_verbose (" setting read watch enabled = %d\n", need_read_watch); 00228 _dbus_connection_toggle_watch_unlocked (transport->connection, 00229 socket_transport->read_watch, 00230 need_read_watch); 00231 00232 _dbus_transport_unref (transport); 00233 } 00234 00235 static void 00236 do_io_error (DBusTransport *transport) 00237 { 00238 _dbus_transport_ref (transport); 00239 _dbus_transport_disconnect (transport); 00240 _dbus_transport_unref (transport); 00241 } 00242 00243 /* return value is whether we successfully read any new data. */ 00244 static dbus_bool_t 00245 read_data_into_auth (DBusTransport *transport, 00246 dbus_bool_t *oom) 00247 { 00248 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 00249 DBusString *buffer; 00250 int bytes_read; 00251 int saved_errno; 00252 00253 *oom = FALSE; 00254 00255 _dbus_auth_get_buffer (transport->auth, &buffer); 00256 00257 bytes_read = _dbus_read_socket (socket_transport->fd, 00258 buffer, socket_transport->max_bytes_read_per_iteration); 00259 saved_errno = _dbus_save_socket_errno (); 00260 00261 _dbus_auth_return_buffer (transport->auth, buffer); 00262 00263 if (bytes_read > 0) 00264 { 00265 _dbus_verbose (" read %d bytes in auth phase\n", bytes_read); 00266 00267 return TRUE; 00268 } 00269 else if (bytes_read < 0) 00270 { 00271 /* EINTR already handled for us */ 00272 00273 if (_dbus_get_is_errno_enomem (saved_errno)) 00274 { 00275 *oom = TRUE; 00276 } 00277 else if (_dbus_get_is_errno_eagain_or_ewouldblock (saved_errno)) 00278 ; /* do nothing, just return FALSE below */ 00279 else 00280 { 00281 _dbus_verbose ("Error reading from remote app: %s\n", 00282 _dbus_strerror (saved_errno)); 00283 do_io_error (transport); 00284 } 00285 00286 return FALSE; 00287 } 00288 else 00289 { 00290 _dbus_assert (bytes_read == 0); 00291 00292 _dbus_verbose ("Disconnected from remote app\n"); 00293 do_io_error (transport); 00294 00295 return FALSE; 00296 } 00297 } 00298 00299 /* Return value is whether we successfully wrote any bytes */ 00300 static dbus_bool_t 00301 write_data_from_auth (DBusTransport *transport) 00302 { 00303 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 00304 int bytes_written; 00305 int saved_errno; 00306 const DBusString *buffer; 00307 00308 if (!_dbus_auth_get_bytes_to_send (transport->auth, 00309 &buffer)) 00310 return FALSE; 00311 00312 bytes_written = _dbus_write_socket (socket_transport->fd, 00313 buffer, 00314 0, _dbus_string_get_length (buffer)); 00315 saved_errno = _dbus_save_socket_errno (); 00316 00317 if (bytes_written > 0) 00318 { 00319 _dbus_auth_bytes_sent (transport->auth, bytes_written); 00320 return TRUE; 00321 } 00322 else if (bytes_written < 0) 00323 { 00324 /* EINTR already handled for us */ 00325 00326 if (_dbus_get_is_errno_eagain_or_ewouldblock (saved_errno)) 00327 ; 00328 else 00329 { 00330 _dbus_verbose ("Error writing to remote app: %s\n", 00331 _dbus_strerror (saved_errno)); 00332 do_io_error (transport); 00333 } 00334 } 00335 00336 return FALSE; 00337 } 00338 00339 /* FALSE on OOM */ 00340 static dbus_bool_t 00341 exchange_credentials (DBusTransport *transport, 00342 dbus_bool_t do_reading, 00343 dbus_bool_t do_writing) 00344 { 00345 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 00346 DBusError error = DBUS_ERROR_INIT; 00347 00348 _dbus_verbose ("exchange_credentials: do_reading = %d, do_writing = %d\n", 00349 do_reading, do_writing); 00350 00351 if (do_writing && transport->send_credentials_pending) 00352 { 00353 if (_dbus_send_credentials_socket (socket_transport->fd, 00354 &error)) 00355 { 00356 transport->send_credentials_pending = FALSE; 00357 } 00358 else 00359 { 00360 _dbus_verbose ("Failed to write credentials: %s\n", error.message); 00361 dbus_error_free (&error); 00362 do_io_error (transport); 00363 } 00364 } 00365 00366 if (do_reading && transport->receive_credentials_pending) 00367 { 00368 /* FIXME this can fail due to IO error _or_ OOM, broken 00369 * (somewhat tricky to fix since the OOM error can be set after 00370 * we already read the credentials byte, so basically we need to 00371 * separate reading the byte and storing it in the 00372 * transport->credentials). Does not really matter for now 00373 * because storing in credentials never actually fails on unix. 00374 */ 00375 if (_dbus_read_credentials_socket (socket_transport->fd, 00376 transport->credentials, 00377 &error)) 00378 { 00379 transport->receive_credentials_pending = FALSE; 00380 } 00381 else 00382 { 00383 _dbus_verbose ("Failed to read credentials %s\n", error.message); 00384 dbus_error_free (&error); 00385 do_io_error (transport); 00386 } 00387 } 00388 00389 if (!(transport->send_credentials_pending || 00390 transport->receive_credentials_pending)) 00391 { 00392 if (!_dbus_auth_set_credentials (transport->auth, 00393 transport->credentials)) 00394 return FALSE; 00395 } 00396 00397 return TRUE; 00398 } 00399 00400 static dbus_bool_t 00401 do_authentication (DBusTransport *transport, 00402 dbus_bool_t do_reading, 00403 dbus_bool_t do_writing, 00404 dbus_bool_t *auth_completed) 00405 { 00406 dbus_bool_t oom; 00407 dbus_bool_t orig_auth_state; 00408 00409 oom = FALSE; 00410 00411 orig_auth_state = _dbus_transport_try_to_authenticate (transport); 00412 00413 /* This is essential to avoid the check_write_watch() at the end, 00414 * we don't want to add a write watch in do_iteration before 00415 * we try writing and get EAGAIN 00416 */ 00417 if (orig_auth_state) 00418 { 00419 if (auth_completed) 00420 *auth_completed = FALSE; 00421 return TRUE; 00422 } 00423 00424 _dbus_transport_ref (transport); 00425 00426 while (!_dbus_transport_try_to_authenticate (transport) && 00427 _dbus_transport_get_is_connected (transport)) 00428 { 00429 if (!exchange_credentials (transport, do_reading, do_writing)) 00430 { 00431 /* OOM */ 00432 oom = TRUE; 00433 goto out; 00434 } 00435 00436 if (transport->send_credentials_pending || 00437 transport->receive_credentials_pending) 00438 { 00439 _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n", 00440 transport->send_credentials_pending, 00441 transport->receive_credentials_pending); 00442 goto out; 00443 } 00444 00445 #define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client") 00446 switch (_dbus_auth_do_work (transport->auth)) 00447 { 00448 case DBUS_AUTH_STATE_WAITING_FOR_INPUT: 00449 _dbus_verbose (" %s auth state: waiting for input\n", 00450 TRANSPORT_SIDE (transport)); 00451 if (!do_reading || !read_data_into_auth (transport, &oom)) 00452 goto out; 00453 break; 00454 00455 case DBUS_AUTH_STATE_WAITING_FOR_MEMORY: 00456 _dbus_verbose (" %s auth state: waiting for memory\n", 00457 TRANSPORT_SIDE (transport)); 00458 oom = TRUE; 00459 goto out; 00460 break; 00461 00462 case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND: 00463 _dbus_verbose (" %s auth state: bytes to send\n", 00464 TRANSPORT_SIDE (transport)); 00465 if (!do_writing || !write_data_from_auth (transport)) 00466 goto out; 00467 break; 00468 00469 case DBUS_AUTH_STATE_NEED_DISCONNECT: 00470 _dbus_verbose (" %s auth state: need to disconnect\n", 00471 TRANSPORT_SIDE (transport)); 00472 do_io_error (transport); 00473 break; 00474 00475 case DBUS_AUTH_STATE_AUTHENTICATED: 00476 _dbus_verbose (" %s auth state: authenticated\n", 00477 TRANSPORT_SIDE (transport)); 00478 break; 00479 } 00480 } 00481 00482 out: 00483 if (auth_completed) 00484 *auth_completed = (orig_auth_state != _dbus_transport_try_to_authenticate (transport)); 00485 00486 check_read_watch (transport); 00487 check_write_watch (transport); 00488 _dbus_transport_unref (transport); 00489 00490 if (oom) 00491 return FALSE; 00492 else 00493 return TRUE; 00494 } 00495 00496 /* returns false on oom */ 00497 static dbus_bool_t 00498 do_writing (DBusTransport *transport) 00499 { 00500 int total; 00501 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 00502 dbus_bool_t oom; 00503 00504 /* No messages without authentication! */ 00505 if (!_dbus_transport_try_to_authenticate (transport)) 00506 { 00507 _dbus_verbose ("Not authenticated, not writing anything\n"); 00508 return TRUE; 00509 } 00510 00511 if (transport->disconnected) 00512 { 00513 _dbus_verbose ("Not connected, not writing anything\n"); 00514 return TRUE; 00515 } 00516 00517 #if 1 00518 _dbus_verbose ("do_writing(), have_messages = %d, fd = %" DBUS_SOCKET_FORMAT "\n", 00519 _dbus_connection_has_messages_to_send_unlocked (transport->connection), 00520 _dbus_socket_printable (socket_transport->fd)); 00521 #endif 00522 00523 oom = FALSE; 00524 total = 0; 00525 00526 while (!transport->disconnected && 00527 _dbus_connection_has_messages_to_send_unlocked (transport->connection)) 00528 { 00529 int bytes_written; 00530 DBusMessage *message; 00531 const DBusString *header; 00532 const DBusString *body; 00533 int header_len, body_len; 00534 int total_bytes_to_write; 00535 int saved_errno; 00536 00537 if (total > socket_transport->max_bytes_written_per_iteration) 00538 { 00539 _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n", 00540 total, socket_transport->max_bytes_written_per_iteration); 00541 goto out; 00542 } 00543 00544 message = _dbus_connection_get_message_to_send (transport->connection); 00545 _dbus_assert (message != NULL); 00546 dbus_message_lock (message); 00547 00548 #if 0 00549 _dbus_verbose ("writing message %p\n", message); 00550 #endif 00551 00552 _dbus_message_get_network_data (message, 00553 &header, &body); 00554 00555 header_len = _dbus_string_get_length (header); 00556 body_len = _dbus_string_get_length (body); 00557 00558 if (_dbus_auth_needs_encoding (transport->auth)) 00559 { 00560 /* Does fd passing even make sense with encoded data? */ 00561 _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport)); 00562 00563 if (_dbus_string_get_length (&socket_transport->encoded_outgoing) == 0) 00564 { 00565 if (!_dbus_auth_encode_data (transport->auth, 00566 header, &socket_transport->encoded_outgoing)) 00567 { 00568 oom = TRUE; 00569 goto out; 00570 } 00571 00572 if (!_dbus_auth_encode_data (transport->auth, 00573 body, &socket_transport->encoded_outgoing)) 00574 { 00575 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0); 00576 oom = TRUE; 00577 goto out; 00578 } 00579 } 00580 00581 total_bytes_to_write = _dbus_string_get_length (&socket_transport->encoded_outgoing); 00582 00583 #if 0 00584 _dbus_verbose ("encoded message is %d bytes\n", 00585 total_bytes_to_write); 00586 #endif 00587 00588 bytes_written = 00589 _dbus_write_socket (socket_transport->fd, 00590 &socket_transport->encoded_outgoing, 00591 socket_transport->message_bytes_written, 00592 total_bytes_to_write - socket_transport->message_bytes_written); 00593 saved_errno = _dbus_save_socket_errno (); 00594 } 00595 else 00596 { 00597 total_bytes_to_write = header_len + body_len; 00598 00599 #if 0 00600 _dbus_verbose ("message is %d bytes\n", 00601 total_bytes_to_write); 00602 #endif 00603 00604 #ifdef HAVE_UNIX_FD_PASSING 00605 if (socket_transport->message_bytes_written <= 0 && DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport)) 00606 { 00607 /* Send the fds along with the first byte of the message */ 00608 const int *unix_fds; 00609 unsigned n; 00610 00611 _dbus_message_get_unix_fds(message, &unix_fds, &n); 00612 00613 bytes_written = 00614 _dbus_write_socket_with_unix_fds_two (socket_transport->fd, 00615 header, 00616 socket_transport->message_bytes_written, 00617 header_len - socket_transport->message_bytes_written, 00618 body, 00619 0, body_len, 00620 unix_fds, 00621 n); 00622 saved_errno = _dbus_save_socket_errno (); 00623 00624 if (bytes_written > 0 && n > 0) 00625 _dbus_verbose("Wrote %i unix fds\n", n); 00626 } 00627 else 00628 #endif 00629 { 00630 if (socket_transport->message_bytes_written < header_len) 00631 { 00632 bytes_written = 00633 _dbus_write_socket_two (socket_transport->fd, 00634 header, 00635 socket_transport->message_bytes_written, 00636 header_len - socket_transport->message_bytes_written, 00637 body, 00638 0, body_len); 00639 } 00640 else 00641 { 00642 bytes_written = 00643 _dbus_write_socket (socket_transport->fd, 00644 body, 00645 (socket_transport->message_bytes_written - header_len), 00646 body_len - 00647 (socket_transport->message_bytes_written - header_len)); 00648 } 00649 00650 saved_errno = _dbus_save_socket_errno (); 00651 } 00652 } 00653 00654 if (bytes_written < 0) 00655 { 00656 /* EINTR already handled for us */ 00657 00658 /* If the other end closed the socket with close() or shutdown(), we 00659 * receive EPIPE here but we must not close the socket yet: there 00660 * might still be some data to read. See: 00661 * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html 00662 */ 00663 00664 if (_dbus_get_is_errno_eagain_or_ewouldblock (saved_errno) || _dbus_get_is_errno_epipe (saved_errno)) 00665 goto out; 00666 00667 /* Since Linux commit 25888e (from 2.6.37-rc4, Nov 2010), sendmsg() 00668 * on Unix sockets returns -1 errno=ETOOMANYREFS when the passfd 00669 * mechanism (SCM_RIGHTS) is used recursively with a recursion level 00670 * of maximum 4. The kernel does not have an API to check whether 00671 * the passed fds can be forwarded and it can change asynchronously. 00672 * See: 00673 * https://bugs.freedesktop.org/show_bug.cgi?id=80163 00674 */ 00675 00676 else if (_dbus_get_is_errno_etoomanyrefs (saved_errno)) 00677 { 00678 /* We only send fds in the first byte of the message. 00679 * ETOOMANYREFS cannot happen after. 00680 */ 00681 _dbus_assert (socket_transport->message_bytes_written == 0); 00682 00683 _dbus_verbose (" discard message of %d bytes due to ETOOMANYREFS\n", 00684 total_bytes_to_write); 00685 00686 socket_transport->message_bytes_written = 0; 00687 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0); 00688 _dbus_string_compact (&socket_transport->encoded_outgoing, 2048); 00689 00690 /* The message was not actually sent but it needs to be removed 00691 * from the outgoing queue 00692 */ 00693 _dbus_connection_message_sent_unlocked (transport->connection, 00694 message); 00695 } 00696 else 00697 { 00698 _dbus_verbose ("Error writing to remote app: %s\n", 00699 _dbus_strerror (saved_errno)); 00700 do_io_error (transport); 00701 goto out; 00702 } 00703 } 00704 else 00705 { 00706 _dbus_verbose (" wrote %d bytes of %d\n", bytes_written, 00707 total_bytes_to_write); 00708 00709 total += bytes_written; 00710 socket_transport->message_bytes_written += bytes_written; 00711 00712 _dbus_assert (socket_transport->message_bytes_written <= 00713 total_bytes_to_write); 00714 00715 if (socket_transport->message_bytes_written == total_bytes_to_write) 00716 { 00717 socket_transport->message_bytes_written = 0; 00718 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0); 00719 _dbus_string_compact (&socket_transport->encoded_outgoing, 2048); 00720 00721 _dbus_connection_message_sent_unlocked (transport->connection, 00722 message); 00723 } 00724 } 00725 } 00726 00727 out: 00728 if (oom) 00729 return FALSE; 00730 else 00731 return TRUE; 00732 } 00733 00734 /* returns false on out-of-memory */ 00735 static dbus_bool_t 00736 do_reading (DBusTransport *transport) 00737 { 00738 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 00739 DBusString *buffer; 00740 int bytes_read; 00741 int total; 00742 dbus_bool_t oom; 00743 int saved_errno; 00744 00745 _dbus_verbose ("fd = %" DBUS_SOCKET_FORMAT "\n", 00746 _dbus_socket_printable (socket_transport->fd)); 00747 00748 /* No messages without authentication! */ 00749 if (!_dbus_transport_try_to_authenticate (transport)) 00750 return TRUE; 00751 00752 oom = FALSE; 00753 00754 total = 0; 00755 00756 again: 00757 00758 /* See if we've exceeded max messages and need to disable reading */ 00759 check_read_watch (transport); 00760 00761 if (total > socket_transport->max_bytes_read_per_iteration) 00762 { 00763 _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n", 00764 total, socket_transport->max_bytes_read_per_iteration); 00765 goto out; 00766 } 00767 00768 _dbus_assert (socket_transport->read_watch != NULL || 00769 transport->disconnected); 00770 00771 if (transport->disconnected) 00772 goto out; 00773 00774 if (!dbus_watch_get_enabled (socket_transport->read_watch)) 00775 return TRUE; 00776 00777 if (_dbus_auth_needs_decoding (transport->auth)) 00778 { 00779 /* Does fd passing even make sense with encoded data? */ 00780 _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport)); 00781 00782 if (_dbus_string_get_length (&socket_transport->encoded_incoming) > 0) 00783 bytes_read = _dbus_string_get_length (&socket_transport->encoded_incoming); 00784 else 00785 bytes_read = _dbus_read_socket (socket_transport->fd, 00786 &socket_transport->encoded_incoming, 00787 socket_transport->max_bytes_read_per_iteration); 00788 00789 saved_errno = _dbus_save_socket_errno (); 00790 00791 _dbus_assert (_dbus_string_get_length (&socket_transport->encoded_incoming) == 00792 bytes_read); 00793 00794 if (bytes_read > 0) 00795 { 00796 _dbus_message_loader_get_buffer (transport->loader, 00797 &buffer); 00798 00799 if (!_dbus_auth_decode_data (transport->auth, 00800 &socket_transport->encoded_incoming, 00801 buffer)) 00802 { 00803 _dbus_verbose ("Out of memory decoding incoming data\n"); 00804 _dbus_message_loader_return_buffer (transport->loader, 00805 buffer); 00806 00807 oom = TRUE; 00808 goto out; 00809 } 00810 00811 _dbus_message_loader_return_buffer (transport->loader, 00812 buffer); 00813 00814 _dbus_string_set_length (&socket_transport->encoded_incoming, 0); 00815 _dbus_string_compact (&socket_transport->encoded_incoming, 2048); 00816 } 00817 } 00818 else 00819 { 00820 _dbus_message_loader_get_buffer (transport->loader, 00821 &buffer); 00822 00823 #ifdef HAVE_UNIX_FD_PASSING 00824 if (DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport)) 00825 { 00826 int *fds, n_fds; 00827 00828 if (!_dbus_message_loader_get_unix_fds(transport->loader, &fds, &n_fds)) 00829 { 00830 _dbus_verbose ("Out of memory reading file descriptors\n"); 00831 _dbus_message_loader_return_buffer (transport->loader, buffer); 00832 oom = TRUE; 00833 goto out; 00834 } 00835 00836 bytes_read = _dbus_read_socket_with_unix_fds(socket_transport->fd, 00837 buffer, 00838 socket_transport->max_bytes_read_per_iteration, 00839 fds, &n_fds); 00840 saved_errno = _dbus_save_socket_errno (); 00841 00842 if (bytes_read >= 0 && n_fds > 0) 00843 _dbus_verbose("Read %i unix fds\n", n_fds); 00844 00845 _dbus_message_loader_return_unix_fds(transport->loader, fds, bytes_read < 0 ? 0 : n_fds); 00846 } 00847 else 00848 #endif 00849 { 00850 bytes_read = _dbus_read_socket (socket_transport->fd, 00851 buffer, socket_transport->max_bytes_read_per_iteration); 00852 saved_errno = _dbus_save_socket_errno (); 00853 } 00854 00855 _dbus_message_loader_return_buffer (transport->loader, 00856 buffer); 00857 } 00858 00859 if (bytes_read < 0) 00860 { 00861 /* EINTR already handled for us */ 00862 00863 if (_dbus_get_is_errno_enomem (saved_errno)) 00864 { 00865 _dbus_verbose ("Out of memory in read()/do_reading()\n"); 00866 oom = TRUE; 00867 goto out; 00868 } 00869 else if (_dbus_get_is_errno_eagain_or_ewouldblock (saved_errno)) 00870 goto out; 00871 else 00872 { 00873 _dbus_verbose ("Error reading from remote app: %s\n", 00874 _dbus_strerror (saved_errno)); 00875 do_io_error (transport); 00876 goto out; 00877 } 00878 } 00879 else if (bytes_read == 0) 00880 { 00881 _dbus_verbose ("Disconnected from remote app\n"); 00882 do_io_error (transport); 00883 goto out; 00884 } 00885 else 00886 { 00887 _dbus_verbose (" read %d bytes\n", bytes_read); 00888 00889 total += bytes_read; 00890 00891 if (!_dbus_transport_queue_messages (transport)) 00892 { 00893 oom = TRUE; 00894 _dbus_verbose (" out of memory when queueing messages we just read in the transport\n"); 00895 goto out; 00896 } 00897 00898 /* Try reading more data until we get EAGAIN and return, or 00899 * exceed max bytes per iteration. If in blocking mode of 00900 * course we'll block instead of returning. 00901 */ 00902 goto again; 00903 } 00904 00905 out: 00906 if (oom) 00907 return FALSE; 00908 else 00909 return TRUE; 00910 } 00911 00912 static dbus_bool_t 00913 unix_error_with_read_to_come (DBusTransport *itransport, 00914 DBusWatch *watch, 00915 unsigned int flags) 00916 { 00917 DBusTransportSocket *transport = (DBusTransportSocket *) itransport; 00918 00919 if (!(flags & DBUS_WATCH_HANGUP || flags & DBUS_WATCH_ERROR)) 00920 return FALSE; 00921 00922 /* If we have a read watch enabled ... 00923 we -might have data incoming ... => handle the HANGUP there */ 00924 if (watch != transport->read_watch && 00925 _dbus_watch_get_enabled (transport->read_watch)) 00926 return FALSE; 00927 00928 return TRUE; 00929 } 00930 00931 static dbus_bool_t 00932 socket_handle_watch (DBusTransport *transport, 00933 DBusWatch *watch, 00934 unsigned int flags) 00935 { 00936 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 00937 00938 _dbus_assert (watch == socket_transport->read_watch || 00939 watch == socket_transport->write_watch); 00940 _dbus_assert (watch != NULL); 00941 00942 /* If we hit an error here on a write watch, don't disconnect the transport yet because data can 00943 * still be in the buffer and do_reading may need several iteration to read 00944 * it all (because of its max_bytes_read_per_iteration limit). 00945 */ 00946 if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags)) 00947 { 00948 _dbus_verbose ("Hang up or error on watch\n"); 00949 _dbus_transport_disconnect (transport); 00950 return TRUE; 00951 } 00952 00953 if (watch == socket_transport->read_watch && 00954 (flags & DBUS_WATCH_READABLE)) 00955 { 00956 dbus_bool_t auth_finished; 00957 #if 1 00958 _dbus_verbose ("handling read watch %p flags = %x\n", 00959 watch, flags); 00960 #endif 00961 if (!do_authentication (transport, TRUE, FALSE, &auth_finished)) 00962 return FALSE; 00963 00964 /* We don't want to do a read immediately following 00965 * a successful authentication. This is so we 00966 * have a chance to propagate the authentication 00967 * state further up. Specifically, we need to 00968 * process any pending data from the auth object. 00969 */ 00970 if (!auth_finished) 00971 { 00972 if (!do_reading (transport)) 00973 { 00974 _dbus_verbose ("no memory to read\n"); 00975 return FALSE; 00976 } 00977 } 00978 else 00979 { 00980 _dbus_verbose ("Not reading anything since we just completed the authentication\n"); 00981 } 00982 } 00983 else if (watch == socket_transport->write_watch && 00984 (flags & DBUS_WATCH_WRITABLE)) 00985 { 00986 #if 1 00987 _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n", 00988 _dbus_connection_has_messages_to_send_unlocked (transport->connection)); 00989 #endif 00990 if (!do_authentication (transport, FALSE, TRUE, NULL)) 00991 return FALSE; 00992 00993 if (!do_writing (transport)) 00994 { 00995 _dbus_verbose ("no memory to write\n"); 00996 return FALSE; 00997 } 00998 00999 /* See if we still need the write watch */ 01000 check_write_watch (transport); 01001 } 01002 #ifdef DBUS_ENABLE_VERBOSE_MODE 01003 else 01004 { 01005 if (watch == socket_transport->read_watch) 01006 _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n", 01007 flags); 01008 else if (watch == socket_transport->write_watch) 01009 _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n", 01010 flags); 01011 else 01012 _dbus_verbose ("asked to handle watch %p on fd %" DBUS_SOCKET_FORMAT " that we don't recognize\n", 01013 watch, dbus_watch_get_socket (watch)); 01014 } 01015 #endif /* DBUS_ENABLE_VERBOSE_MODE */ 01016 01017 return TRUE; 01018 } 01019 01020 static void 01021 socket_disconnect (DBusTransport *transport) 01022 { 01023 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 01024 01025 _dbus_verbose ("\n"); 01026 01027 free_watches (transport); 01028 01029 _dbus_close_socket (socket_transport->fd, NULL); 01030 _dbus_socket_invalidate (&socket_transport->fd); 01031 } 01032 01033 static dbus_bool_t 01034 socket_connection_set (DBusTransport *transport) 01035 { 01036 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 01037 01038 _dbus_watch_set_handler (socket_transport->write_watch, 01039 _dbus_connection_handle_watch, 01040 transport->connection, NULL); 01041 01042 _dbus_watch_set_handler (socket_transport->read_watch, 01043 _dbus_connection_handle_watch, 01044 transport->connection, NULL); 01045 01046 if (!_dbus_connection_add_watch_unlocked (transport->connection, 01047 socket_transport->write_watch)) 01048 return FALSE; 01049 01050 if (!_dbus_connection_add_watch_unlocked (transport->connection, 01051 socket_transport->read_watch)) 01052 { 01053 _dbus_connection_remove_watch_unlocked (transport->connection, 01054 socket_transport->write_watch); 01055 return FALSE; 01056 } 01057 01058 check_read_watch (transport); 01059 check_write_watch (transport); 01060 01061 return TRUE; 01062 } 01063 01071 static void 01072 socket_do_iteration (DBusTransport *transport, 01073 unsigned int flags, 01074 int timeout_milliseconds) 01075 { 01076 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 01077 DBusPollFD poll_fd; 01078 int poll_res; 01079 int poll_timeout; 01080 01081 _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %" DBUS_SOCKET_FORMAT "\n", 01082 flags & DBUS_ITERATION_DO_READING ? "read" : "", 01083 flags & DBUS_ITERATION_DO_WRITING ? "write" : "", 01084 timeout_milliseconds, 01085 socket_transport->read_watch, 01086 socket_transport->write_watch, 01087 _dbus_socket_printable (socket_transport->fd)); 01088 01089 /* the passed in DO_READING/DO_WRITING flags indicate whether to 01090 * read/write messages, but regardless of those we may need to block 01091 * for reading/writing to do auth. But if we do reading for auth, 01092 * we don't want to read any messages yet if not given DO_READING. 01093 */ 01094 01095 poll_fd.fd = _dbus_socket_get_pollable (socket_transport->fd); 01096 poll_fd.events = 0; 01097 01098 if (_dbus_transport_try_to_authenticate (transport)) 01099 { 01100 /* This is kind of a hack; if we have stuff to write, then try 01101 * to avoid the poll. This is probably about a 5% speedup on an 01102 * echo client/server. 01103 * 01104 * If both reading and writing were requested, we want to avoid this 01105 * since it could have funky effects: 01106 * - both ends spinning waiting for the other one to read 01107 * data so they can finish writing 01108 * - prioritizing all writing ahead of reading 01109 */ 01110 if ((flags & DBUS_ITERATION_DO_WRITING) && 01111 !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) && 01112 !transport->disconnected && 01113 _dbus_connection_has_messages_to_send_unlocked (transport->connection)) 01114 { 01115 do_writing (transport); 01116 01117 if (transport->disconnected || 01118 !_dbus_connection_has_messages_to_send_unlocked (transport->connection)) 01119 goto out; 01120 } 01121 01122 /* If we get here, we decided to do the poll() after all */ 01123 _dbus_assert (socket_transport->read_watch); 01124 if (flags & DBUS_ITERATION_DO_READING) 01125 poll_fd.events |= _DBUS_POLLIN; 01126 01127 _dbus_assert (socket_transport->write_watch); 01128 if (flags & DBUS_ITERATION_DO_WRITING) 01129 poll_fd.events |= _DBUS_POLLOUT; 01130 } 01131 else 01132 { 01133 DBusAuthState auth_state; 01134 01135 auth_state = _dbus_auth_do_work (transport->auth); 01136 01137 if (transport->receive_credentials_pending || 01138 auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT) 01139 poll_fd.events |= _DBUS_POLLIN; 01140 01141 if (transport->send_credentials_pending || 01142 auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND) 01143 poll_fd.events |= _DBUS_POLLOUT; 01144 } 01145 01146 if (poll_fd.events) 01147 { 01148 int saved_errno; 01149 01150 if (flags & DBUS_ITERATION_BLOCK) 01151 poll_timeout = timeout_milliseconds; 01152 else 01153 poll_timeout = 0; 01154 01155 /* For blocking selects we drop the connection lock here 01156 * to avoid blocking out connection access during a potentially 01157 * indefinite blocking call. The io path is still protected 01158 * by the io_path_cond condvar, so we won't reenter this. 01159 */ 01160 if (flags & DBUS_ITERATION_BLOCK) 01161 { 01162 _dbus_verbose ("unlock pre poll\n"); 01163 _dbus_connection_unlock (transport->connection); 01164 } 01165 01166 again: 01167 poll_res = _dbus_poll (&poll_fd, 1, poll_timeout); 01168 saved_errno = _dbus_save_socket_errno (); 01169 01170 if (poll_res < 0 && _dbus_get_is_errno_eintr (saved_errno)) 01171 goto again; 01172 01173 if (flags & DBUS_ITERATION_BLOCK) 01174 { 01175 _dbus_verbose ("lock post poll\n"); 01176 _dbus_connection_lock (transport->connection); 01177 } 01178 01179 if (poll_res >= 0) 01180 { 01181 if (poll_res == 0) 01182 poll_fd.revents = 0; /* some concern that posix does not guarantee this; 01183 * valgrind flags it as an error. though it probably 01184 * is guaranteed on linux at least. 01185 */ 01186 01187 if (poll_fd.revents & _DBUS_POLLERR) 01188 do_io_error (transport); 01189 else 01190 { 01191 dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0; 01192 dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0; 01193 dbus_bool_t authentication_completed; 01194 01195 _dbus_verbose ("in iteration, need_read=%d need_write=%d\n", 01196 need_read, need_write); 01197 do_authentication (transport, need_read, need_write, 01198 &authentication_completed); 01199 01200 /* See comment in socket_handle_watch. */ 01201 if (authentication_completed) 01202 goto out; 01203 01204 if (need_read && (flags & DBUS_ITERATION_DO_READING)) 01205 do_reading (transport); 01206 if (need_write && (flags & DBUS_ITERATION_DO_WRITING)) 01207 do_writing (transport); 01208 } 01209 } 01210 else 01211 { 01212 _dbus_verbose ("Error from _dbus_poll(): %s\n", 01213 _dbus_strerror (saved_errno)); 01214 } 01215 } 01216 01217 01218 out: 01219 /* We need to install the write watch only if we did not 01220 * successfully write everything. Note we need to be careful that we 01221 * don't call check_write_watch *before* do_writing, since it's 01222 * inefficient to add the write watch, and we can avoid it most of 01223 * the time since we can write immediately. 01224 * 01225 * However, we MUST always call check_write_watch(); DBusConnection code 01226 * relies on the fact that running an iteration will notice that 01227 * messages are pending. 01228 */ 01229 check_write_watch (transport); 01230 01231 _dbus_verbose (" ... leaving do_iteration()\n"); 01232 } 01233 01234 static void 01235 socket_live_messages_changed (DBusTransport *transport) 01236 { 01237 /* See if we should look for incoming messages again */ 01238 check_read_watch (transport); 01239 } 01240 01241 01242 static dbus_bool_t 01243 socket_get_socket_fd (DBusTransport *transport, 01244 DBusSocket *fd_p) 01245 { 01246 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 01247 01248 *fd_p = socket_transport->fd; 01249 01250 return TRUE; 01251 } 01252 01253 static const DBusTransportVTable socket_vtable = { 01254 socket_finalize, 01255 socket_handle_watch, 01256 socket_disconnect, 01257 socket_connection_set, 01258 socket_do_iteration, 01259 socket_live_messages_changed, 01260 socket_get_socket_fd 01261 }; 01262 01274 DBusTransport* 01275 _dbus_transport_new_for_socket (DBusSocket fd, 01276 const DBusString *server_guid, 01277 const DBusString *address) 01278 { 01279 DBusTransportSocket *socket_transport; 01280 01281 socket_transport = dbus_new0 (DBusTransportSocket, 1); 01282 if (socket_transport == NULL) 01283 return NULL; 01284 01285 if (!_dbus_string_init (&socket_transport->encoded_outgoing)) 01286 goto failed_0; 01287 01288 if (!_dbus_string_init (&socket_transport->encoded_incoming)) 01289 goto failed_1; 01290 01291 socket_transport->write_watch = _dbus_watch_new (_dbus_socket_get_pollable (fd), 01292 DBUS_WATCH_WRITABLE, 01293 FALSE, 01294 NULL, NULL, NULL); 01295 if (socket_transport->write_watch == NULL) 01296 goto failed_2; 01297 01298 socket_transport->read_watch = _dbus_watch_new (_dbus_socket_get_pollable (fd), 01299 DBUS_WATCH_READABLE, 01300 FALSE, 01301 NULL, NULL, NULL); 01302 if (socket_transport->read_watch == NULL) 01303 goto failed_3; 01304 01305 if (!_dbus_transport_init_base (&socket_transport->base, 01306 &socket_vtable, 01307 server_guid, address)) 01308 goto failed_4; 01309 01310 #ifdef HAVE_UNIX_FD_PASSING 01311 _dbus_auth_set_unix_fd_possible(socket_transport->base.auth, _dbus_socket_can_pass_unix_fd(fd)); 01312 #endif 01313 01314 socket_transport->fd = fd; 01315 socket_transport->message_bytes_written = 0; 01316 01317 /* These values should probably be tunable or something. */ 01318 socket_transport->max_bytes_read_per_iteration = 2048; 01319 socket_transport->max_bytes_written_per_iteration = 2048; 01320 01321 return (DBusTransport*) socket_transport; 01322 01323 failed_4: 01324 _dbus_watch_invalidate (socket_transport->read_watch); 01325 _dbus_watch_unref (socket_transport->read_watch); 01326 failed_3: 01327 _dbus_watch_invalidate (socket_transport->write_watch); 01328 _dbus_watch_unref (socket_transport->write_watch); 01329 failed_2: 01330 _dbus_string_free (&socket_transport->encoded_incoming); 01331 failed_1: 01332 _dbus_string_free (&socket_transport->encoded_outgoing); 01333 failed_0: 01334 dbus_free (socket_transport); 01335 return NULL; 01336 } 01337 01349 DBusTransport* 01350 _dbus_transport_new_for_tcp_socket (const char *host, 01351 const char *port, 01352 const char *family, 01353 const char *noncefile, 01354 DBusError *error) 01355 { 01356 DBusSocket fd; 01357 DBusTransport *transport; 01358 DBusString address; 01359 01360 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01361 01362 if (!_dbus_string_init (&address)) 01363 { 01364 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01365 return NULL; 01366 } 01367 01368 if (host == NULL) 01369 host = "localhost"; 01370 01371 if (!_dbus_string_append (&address, noncefile ? "nonce-tcp:" : "tcp:")) 01372 goto error; 01373 01374 if (!_dbus_string_append (&address, "host=") || 01375 !_dbus_string_append (&address, host)) 01376 goto error; 01377 01378 if (!_dbus_string_append (&address, ",port=") || 01379 !_dbus_string_append (&address, port)) 01380 goto error; 01381 01382 if (family != NULL && 01383 (!_dbus_string_append (&address, ",family=") || 01384 !_dbus_string_append (&address, family))) 01385 goto error; 01386 01387 if (noncefile != NULL && 01388 (!_dbus_string_append (&address, ",noncefile=") || 01389 !_dbus_string_append (&address, noncefile))) 01390 goto error; 01391 01392 fd = _dbus_connect_tcp_socket_with_nonce (host, port, family, noncefile, error); 01393 if (!_dbus_socket_is_valid (fd)) 01394 { 01395 _DBUS_ASSERT_ERROR_IS_SET (error); 01396 _dbus_string_free (&address); 01397 return NULL; 01398 } 01399 01400 _dbus_verbose ("Successfully connected to tcp socket %s:%s\n", 01401 host, port); 01402 01403 transport = _dbus_transport_new_for_socket (fd, NULL, &address); 01404 _dbus_string_free (&address); 01405 if (transport == NULL) 01406 { 01407 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01408 _dbus_close_socket (fd, NULL); 01409 _dbus_socket_invalidate (&fd); 01410 } 01411 01412 return transport; 01413 01414 error: 01415 _dbus_string_free (&address); 01416 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01417 return NULL; 01418 } 01419 01428 DBusTransportOpenResult 01429 _dbus_transport_open_socket(DBusAddressEntry *entry, 01430 DBusTransport **transport_p, 01431 DBusError *error) 01432 { 01433 const char *method; 01434 dbus_bool_t isTcp; 01435 dbus_bool_t isNonceTcp; 01436 01437 method = dbus_address_entry_get_method (entry); 01438 _dbus_assert (method != NULL); 01439 01440 isTcp = strcmp (method, "tcp") == 0; 01441 isNonceTcp = strcmp (method, "nonce-tcp") == 0; 01442 01443 if (isTcp || isNonceTcp) 01444 { 01445 const char *host = dbus_address_entry_get_value (entry, "host"); 01446 const char *port = dbus_address_entry_get_value (entry, "port"); 01447 const char *family = dbus_address_entry_get_value (entry, "family"); 01448 const char *noncefile = dbus_address_entry_get_value (entry, "noncefile"); 01449 01450 if ((isNonceTcp == TRUE) != (noncefile != NULL)) { 01451 _dbus_set_bad_address (error, method, "noncefile", NULL); 01452 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS; 01453 } 01454 01455 if (port == NULL) 01456 { 01457 _dbus_set_bad_address (error, method, "port", NULL); 01458 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS; 01459 } 01460 01461 *transport_p = _dbus_transport_new_for_tcp_socket (host, port, family, noncefile, error); 01462 if (*transport_p == NULL) 01463 { 01464 _DBUS_ASSERT_ERROR_IS_SET (error); 01465 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT; 01466 } 01467 else 01468 { 01469 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01470 return DBUS_TRANSPORT_OPEN_OK; 01471 } 01472 } 01473 else 01474 { 01475 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01476 return DBUS_TRANSPORT_OPEN_NOT_HANDLED; 01477 } 01478 } 01479