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 <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
00151
00152
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
00205
00206
00207
00208 DBusAuthState auth_state;
00209
00210 auth_state = _dbus_auth_do_work (transport->auth);
00211
00212
00213
00214
00215
00216
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
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
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 ;
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
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
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
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
00369
00370
00371
00372
00373
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
00414
00415
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
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
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
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
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
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
00657
00658
00659
00660
00661
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
00668
00669
00670
00671
00672
00673
00674
00675
00676 else if (_dbus_get_is_errno_etoomanyrefs (saved_errno))
00677 {
00678
00679
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
00691
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
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
00749 if (!_dbus_transport_try_to_authenticate (transport))
00750 return TRUE;
00751
00752 oom = FALSE;
00753
00754 total = 0;
00755
00756 again:
00757
00758
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
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
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
00899
00900
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
00923
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
00943
00944
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
00965
00966
00967
00968
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
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
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
01090
01091
01092
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
01101
01102
01103
01104
01105
01106
01107
01108
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
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
01156
01157
01158
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;
01183
01184
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
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
01220
01221
01222
01223
01224
01225
01226
01227
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
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
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