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 int 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_get_is_authenticated (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 = %d outgoing messages exist %d\n",
00163 needed, transport->connection, socket_transport->write_watch,
00164 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 = %d\n",socket_transport->fd);
00181
00182 if (transport->connection == NULL)
00183 return;
00184
00185 if (transport->disconnected)
00186 {
00187 _dbus_assert (socket_transport->read_watch == NULL);
00188 return;
00189 }
00190
00191 _dbus_transport_ref (transport);
00192
00193 if (_dbus_transport_get_is_authenticated (transport))
00194 need_read_watch =
00195 (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
00196 (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
00197 else
00198 {
00199 if (transport->receive_credentials_pending)
00200 need_read_watch = TRUE;
00201 else
00202 {
00203
00204
00205
00206
00207 DBusAuthState auth_state;
00208
00209 auth_state = _dbus_auth_do_work (transport->auth);
00210
00211
00212
00213
00214
00215
00216
00217 if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT ||
00218 auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY ||
00219 auth_state == DBUS_AUTH_STATE_AUTHENTICATED)
00220 need_read_watch = TRUE;
00221 else
00222 need_read_watch = FALSE;
00223 }
00224 }
00225
00226 _dbus_verbose (" setting read watch enabled = %d\n", need_read_watch);
00227 _dbus_connection_toggle_watch_unlocked (transport->connection,
00228 socket_transport->read_watch,
00229 need_read_watch);
00230
00231 _dbus_transport_unref (transport);
00232 }
00233
00234 static void
00235 do_io_error (DBusTransport *transport)
00236 {
00237 _dbus_transport_ref (transport);
00238 _dbus_transport_disconnect (transport);
00239 _dbus_transport_unref (transport);
00240 }
00241
00242
00243 static dbus_bool_t
00244 read_data_into_auth (DBusTransport *transport,
00245 dbus_bool_t *oom)
00246 {
00247 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00248 DBusString *buffer;
00249 int bytes_read;
00250
00251 *oom = FALSE;
00252
00253 _dbus_auth_get_buffer (transport->auth, &buffer);
00254
00255 bytes_read = _dbus_read_socket (socket_transport->fd,
00256 buffer, socket_transport->max_bytes_read_per_iteration);
00257
00258 _dbus_auth_return_buffer (transport->auth, buffer,
00259 bytes_read > 0 ? bytes_read : 0);
00260
00261 if (bytes_read > 0)
00262 {
00263 _dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
00264
00265 return TRUE;
00266 }
00267 else if (bytes_read < 0)
00268 {
00269
00270
00271 if (_dbus_get_is_errno_enomem ())
00272 {
00273 *oom = TRUE;
00274 }
00275 else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
00276 ;
00277 else
00278 {
00279 _dbus_verbose ("Error reading from remote app: %s\n",
00280 _dbus_strerror_from_errno ());
00281 do_io_error (transport);
00282 }
00283
00284 return FALSE;
00285 }
00286 else
00287 {
00288 _dbus_assert (bytes_read == 0);
00289
00290 _dbus_verbose ("Disconnected from remote app\n");
00291 do_io_error (transport);
00292
00293 return FALSE;
00294 }
00295 }
00296
00297
00298 static dbus_bool_t
00299 write_data_from_auth (DBusTransport *transport)
00300 {
00301 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00302 int bytes_written;
00303 const DBusString *buffer;
00304
00305 if (!_dbus_auth_get_bytes_to_send (transport->auth,
00306 &buffer))
00307 return FALSE;
00308
00309 bytes_written = _dbus_write_socket (socket_transport->fd,
00310 buffer,
00311 0, _dbus_string_get_length (buffer));
00312
00313 if (bytes_written > 0)
00314 {
00315 _dbus_auth_bytes_sent (transport->auth, bytes_written);
00316 return TRUE;
00317 }
00318 else if (bytes_written < 0)
00319 {
00320
00321
00322 if (_dbus_get_is_errno_eagain_or_ewouldblock ())
00323 ;
00324 else
00325 {
00326 _dbus_verbose ("Error writing to remote app: %s\n",
00327 _dbus_strerror_from_errno ());
00328 do_io_error (transport);
00329 }
00330 }
00331
00332 return FALSE;
00333 }
00334
00335
00336 static dbus_bool_t
00337 exchange_credentials (DBusTransport *transport,
00338 dbus_bool_t do_reading,
00339 dbus_bool_t do_writing)
00340 {
00341 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00342 DBusError error = DBUS_ERROR_INIT;
00343
00344 _dbus_verbose ("exchange_credentials: do_reading = %d, do_writing = %d\n",
00345 do_reading, do_writing);
00346
00347 if (do_writing && transport->send_credentials_pending)
00348 {
00349 if (_dbus_send_credentials_socket (socket_transport->fd,
00350 &error))
00351 {
00352 transport->send_credentials_pending = FALSE;
00353 }
00354 else
00355 {
00356 _dbus_verbose ("Failed to write credentials: %s\n", error.message);
00357 dbus_error_free (&error);
00358 do_io_error (transport);
00359 }
00360 }
00361
00362 if (do_reading && transport->receive_credentials_pending)
00363 {
00364
00365
00366
00367
00368
00369
00370
00371 if (_dbus_read_credentials_socket (socket_transport->fd,
00372 transport->credentials,
00373 &error))
00374 {
00375 transport->receive_credentials_pending = FALSE;
00376 }
00377 else
00378 {
00379 _dbus_verbose ("Failed to read credentials %s\n", error.message);
00380 dbus_error_free (&error);
00381 do_io_error (transport);
00382 }
00383 }
00384
00385 if (!(transport->send_credentials_pending ||
00386 transport->receive_credentials_pending))
00387 {
00388 if (!_dbus_auth_set_credentials (transport->auth,
00389 transport->credentials))
00390 return FALSE;
00391 }
00392
00393 return TRUE;
00394 }
00395
00396 static dbus_bool_t
00397 do_authentication (DBusTransport *transport,
00398 dbus_bool_t do_reading,
00399 dbus_bool_t do_writing,
00400 dbus_bool_t *auth_completed)
00401 {
00402 dbus_bool_t oom;
00403 dbus_bool_t orig_auth_state;
00404
00405 oom = FALSE;
00406
00407 orig_auth_state = _dbus_transport_get_is_authenticated (transport);
00408
00409
00410
00411
00412
00413 if (orig_auth_state)
00414 {
00415 if (auth_completed)
00416 *auth_completed = FALSE;
00417 return TRUE;
00418 }
00419
00420 _dbus_transport_ref (transport);
00421
00422 while (!_dbus_transport_get_is_authenticated (transport) &&
00423 _dbus_transport_get_is_connected (transport))
00424 {
00425 if (!exchange_credentials (transport, do_reading, do_writing))
00426 {
00427
00428 oom = TRUE;
00429 goto out;
00430 }
00431
00432 if (transport->send_credentials_pending ||
00433 transport->receive_credentials_pending)
00434 {
00435 _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
00436 transport->send_credentials_pending,
00437 transport->receive_credentials_pending);
00438 goto out;
00439 }
00440
00441 #define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client")
00442 switch (_dbus_auth_do_work (transport->auth))
00443 {
00444 case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
00445 _dbus_verbose (" %s auth state: waiting for input\n",
00446 TRANSPORT_SIDE (transport));
00447 if (!do_reading || !read_data_into_auth (transport, &oom))
00448 goto out;
00449 break;
00450
00451 case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
00452 _dbus_verbose (" %s auth state: waiting for memory\n",
00453 TRANSPORT_SIDE (transport));
00454 oom = TRUE;
00455 goto out;
00456 break;
00457
00458 case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
00459 _dbus_verbose (" %s auth state: bytes to send\n",
00460 TRANSPORT_SIDE (transport));
00461 if (!do_writing || !write_data_from_auth (transport))
00462 goto out;
00463 break;
00464
00465 case DBUS_AUTH_STATE_NEED_DISCONNECT:
00466 _dbus_verbose (" %s auth state: need to disconnect\n",
00467 TRANSPORT_SIDE (transport));
00468 do_io_error (transport);
00469 break;
00470
00471 case DBUS_AUTH_STATE_AUTHENTICATED:
00472 _dbus_verbose (" %s auth state: authenticated\n",
00473 TRANSPORT_SIDE (transport));
00474 break;
00475 }
00476 }
00477
00478 out:
00479 if (auth_completed)
00480 *auth_completed = (orig_auth_state != _dbus_transport_get_is_authenticated (transport));
00481
00482 check_read_watch (transport);
00483 check_write_watch (transport);
00484 _dbus_transport_unref (transport);
00485
00486 if (oom)
00487 return FALSE;
00488 else
00489 return TRUE;
00490 }
00491
00492
00493 static dbus_bool_t
00494 do_writing (DBusTransport *transport)
00495 {
00496 int total;
00497 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00498 dbus_bool_t oom;
00499
00500
00501 if (!_dbus_transport_get_is_authenticated (transport))
00502 {
00503 _dbus_verbose ("Not authenticated, not writing anything\n");
00504 return TRUE;
00505 }
00506
00507 if (transport->disconnected)
00508 {
00509 _dbus_verbose ("Not connected, not writing anything\n");
00510 return TRUE;
00511 }
00512
00513 #if 1
00514 _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n",
00515 _dbus_connection_has_messages_to_send_unlocked (transport->connection),
00516 socket_transport->fd);
00517 #endif
00518
00519 oom = FALSE;
00520 total = 0;
00521
00522 while (!transport->disconnected &&
00523 _dbus_connection_has_messages_to_send_unlocked (transport->connection))
00524 {
00525 int bytes_written;
00526 DBusMessage *message;
00527 const DBusString *header;
00528 const DBusString *body;
00529 int header_len, body_len;
00530 int total_bytes_to_write;
00531
00532 if (total > socket_transport->max_bytes_written_per_iteration)
00533 {
00534 _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
00535 total, socket_transport->max_bytes_written_per_iteration);
00536 goto out;
00537 }
00538
00539 message = _dbus_connection_get_message_to_send (transport->connection);
00540 _dbus_assert (message != NULL);
00541 dbus_message_lock (message);
00542
00543 #if 0
00544 _dbus_verbose ("writing message %p\n", message);
00545 #endif
00546
00547 _dbus_message_get_network_data (message,
00548 &header, &body);
00549
00550 header_len = _dbus_string_get_length (header);
00551 body_len = _dbus_string_get_length (body);
00552
00553 if (_dbus_auth_needs_encoding (transport->auth))
00554 {
00555
00556 _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport));
00557
00558 if (_dbus_string_get_length (&socket_transport->encoded_outgoing) == 0)
00559 {
00560 if (!_dbus_auth_encode_data (transport->auth,
00561 header, &socket_transport->encoded_outgoing))
00562 {
00563 oom = TRUE;
00564 goto out;
00565 }
00566
00567 if (!_dbus_auth_encode_data (transport->auth,
00568 body, &socket_transport->encoded_outgoing))
00569 {
00570 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
00571 oom = TRUE;
00572 goto out;
00573 }
00574 }
00575
00576 total_bytes_to_write = _dbus_string_get_length (&socket_transport->encoded_outgoing);
00577
00578 #if 0
00579 _dbus_verbose ("encoded message is %d bytes\n",
00580 total_bytes_to_write);
00581 #endif
00582
00583 bytes_written =
00584 _dbus_write_socket (socket_transport->fd,
00585 &socket_transport->encoded_outgoing,
00586 socket_transport->message_bytes_written,
00587 total_bytes_to_write - socket_transport->message_bytes_written);
00588 }
00589 else
00590 {
00591 total_bytes_to_write = header_len + body_len;
00592
00593 #if 0
00594 _dbus_verbose ("message is %d bytes\n",
00595 total_bytes_to_write);
00596 #endif
00597
00598 #ifdef HAVE_UNIX_FD_PASSING
00599 if (socket_transport->message_bytes_written <= 0 && DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport))
00600 {
00601
00602 const int *unix_fds;
00603 unsigned n;
00604
00605 _dbus_message_get_unix_fds(message, &unix_fds, &n);
00606
00607 bytes_written =
00608 _dbus_write_socket_with_unix_fds_two (socket_transport->fd,
00609 header,
00610 socket_transport->message_bytes_written,
00611 header_len - socket_transport->message_bytes_written,
00612 body,
00613 0, body_len,
00614 unix_fds,
00615 n);
00616
00617 if (bytes_written > 0 && n > 0)
00618 _dbus_verbose("Wrote %i unix fds\n", n);
00619 }
00620 else
00621 #endif
00622 {
00623 if (socket_transport->message_bytes_written < header_len)
00624 {
00625 bytes_written =
00626 _dbus_write_socket_two (socket_transport->fd,
00627 header,
00628 socket_transport->message_bytes_written,
00629 header_len - socket_transport->message_bytes_written,
00630 body,
00631 0, body_len);
00632 }
00633 else
00634 {
00635 bytes_written =
00636 _dbus_write_socket (socket_transport->fd,
00637 body,
00638 (socket_transport->message_bytes_written - header_len),
00639 body_len -
00640 (socket_transport->message_bytes_written - header_len));
00641 }
00642 }
00643 }
00644
00645 if (bytes_written < 0)
00646 {
00647
00648
00649
00650
00651
00652
00653
00654
00655 if (_dbus_get_is_errno_eagain_or_ewouldblock () || _dbus_get_is_errno_epipe ())
00656 goto out;
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667 else if (_dbus_get_is_errno_etoomanyrefs ())
00668 {
00669
00670
00671
00672 _dbus_assert (socket_transport->message_bytes_written == 0);
00673
00674 _dbus_verbose (" discard message of %d bytes due to ETOOMANYREFS\n",
00675 total_bytes_to_write);
00676
00677 socket_transport->message_bytes_written = 0;
00678 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
00679 _dbus_string_compact (&socket_transport->encoded_outgoing, 2048);
00680
00681
00682
00683
00684 _dbus_connection_message_sent (transport->connection,
00685 message);
00686 }
00687 else
00688 {
00689 _dbus_verbose ("Error writing to remote app: %s\n",
00690 _dbus_strerror_from_errno ());
00691 do_io_error (transport);
00692 goto out;
00693 }
00694 }
00695 else
00696 {
00697 _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
00698 total_bytes_to_write);
00699
00700 total += bytes_written;
00701 socket_transport->message_bytes_written += bytes_written;
00702
00703 _dbus_assert (socket_transport->message_bytes_written <=
00704 total_bytes_to_write);
00705
00706 if (socket_transport->message_bytes_written == total_bytes_to_write)
00707 {
00708 socket_transport->message_bytes_written = 0;
00709 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
00710 _dbus_string_compact (&socket_transport->encoded_outgoing, 2048);
00711
00712 _dbus_connection_message_sent (transport->connection,
00713 message);
00714 }
00715 }
00716 }
00717
00718 out:
00719 if (oom)
00720 return FALSE;
00721 else
00722 return TRUE;
00723 }
00724
00725
00726 static dbus_bool_t
00727 do_reading (DBusTransport *transport)
00728 {
00729 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00730 DBusString *buffer;
00731 int bytes_read;
00732 int total;
00733 dbus_bool_t oom;
00734
00735 _dbus_verbose ("fd = %d\n",socket_transport->fd);
00736
00737
00738 if (!_dbus_transport_get_is_authenticated (transport))
00739 return TRUE;
00740
00741 oom = FALSE;
00742
00743 total = 0;
00744
00745 again:
00746
00747
00748 check_read_watch (transport);
00749
00750 if (total > socket_transport->max_bytes_read_per_iteration)
00751 {
00752 _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
00753 total, socket_transport->max_bytes_read_per_iteration);
00754 goto out;
00755 }
00756
00757 _dbus_assert (socket_transport->read_watch != NULL ||
00758 transport->disconnected);
00759
00760 if (transport->disconnected)
00761 goto out;
00762
00763 if (!dbus_watch_get_enabled (socket_transport->read_watch))
00764 return TRUE;
00765
00766 if (_dbus_auth_needs_decoding (transport->auth))
00767 {
00768
00769 _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport));
00770
00771 if (_dbus_string_get_length (&socket_transport->encoded_incoming) > 0)
00772 bytes_read = _dbus_string_get_length (&socket_transport->encoded_incoming);
00773 else
00774 bytes_read = _dbus_read_socket (socket_transport->fd,
00775 &socket_transport->encoded_incoming,
00776 socket_transport->max_bytes_read_per_iteration);
00777
00778 _dbus_assert (_dbus_string_get_length (&socket_transport->encoded_incoming) ==
00779 bytes_read);
00780
00781 if (bytes_read > 0)
00782 {
00783 int orig_len;
00784
00785 _dbus_message_loader_get_buffer (transport->loader,
00786 &buffer);
00787
00788 orig_len = _dbus_string_get_length (buffer);
00789
00790 if (!_dbus_auth_decode_data (transport->auth,
00791 &socket_transport->encoded_incoming,
00792 buffer))
00793 {
00794 _dbus_verbose ("Out of memory decoding incoming data\n");
00795 _dbus_message_loader_return_buffer (transport->loader,
00796 buffer,
00797 _dbus_string_get_length (buffer) - orig_len);
00798
00799 oom = TRUE;
00800 goto out;
00801 }
00802
00803 _dbus_message_loader_return_buffer (transport->loader,
00804 buffer,
00805 _dbus_string_get_length (buffer) - orig_len);
00806
00807 _dbus_string_set_length (&socket_transport->encoded_incoming, 0);
00808 _dbus_string_compact (&socket_transport->encoded_incoming, 2048);
00809 }
00810 }
00811 else
00812 {
00813 _dbus_message_loader_get_buffer (transport->loader,
00814 &buffer);
00815
00816 #ifdef HAVE_UNIX_FD_PASSING
00817 if (DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport))
00818 {
00819 int *fds, n_fds;
00820
00821 if (!_dbus_message_loader_get_unix_fds(transport->loader, &fds, &n_fds))
00822 {
00823 _dbus_verbose ("Out of memory reading file descriptors\n");
00824 _dbus_message_loader_return_buffer (transport->loader, buffer, 0);
00825 oom = TRUE;
00826 goto out;
00827 }
00828
00829 bytes_read = _dbus_read_socket_with_unix_fds(socket_transport->fd,
00830 buffer,
00831 socket_transport->max_bytes_read_per_iteration,
00832 fds, &n_fds);
00833
00834 if (bytes_read >= 0 && n_fds > 0)
00835 _dbus_verbose("Read %i unix fds\n", n_fds);
00836
00837 _dbus_message_loader_return_unix_fds(transport->loader, fds, bytes_read < 0 ? 0 : n_fds);
00838 }
00839 else
00840 #endif
00841 {
00842 bytes_read = _dbus_read_socket (socket_transport->fd,
00843 buffer, socket_transport->max_bytes_read_per_iteration);
00844 }
00845
00846 _dbus_message_loader_return_buffer (transport->loader,
00847 buffer,
00848 bytes_read < 0 ? 0 : bytes_read);
00849 }
00850
00851 if (bytes_read < 0)
00852 {
00853
00854
00855 if (_dbus_get_is_errno_enomem ())
00856 {
00857 _dbus_verbose ("Out of memory in read()/do_reading()\n");
00858 oom = TRUE;
00859 goto out;
00860 }
00861 else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
00862 goto out;
00863 else
00864 {
00865 _dbus_verbose ("Error reading from remote app: %s\n",
00866 _dbus_strerror_from_errno ());
00867 do_io_error (transport);
00868 goto out;
00869 }
00870 }
00871 else if (bytes_read == 0)
00872 {
00873 _dbus_verbose ("Disconnected from remote app\n");
00874 do_io_error (transport);
00875 goto out;
00876 }
00877 else
00878 {
00879 _dbus_verbose (" read %d bytes\n", bytes_read);
00880
00881 total += bytes_read;
00882
00883 if (!_dbus_transport_queue_messages (transport))
00884 {
00885 oom = TRUE;
00886 _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
00887 goto out;
00888 }
00889
00890
00891
00892
00893
00894 goto again;
00895 }
00896
00897 out:
00898 if (oom)
00899 return FALSE;
00900 else
00901 return TRUE;
00902 }
00903
00904 static dbus_bool_t
00905 unix_error_with_read_to_come (DBusTransport *itransport,
00906 DBusWatch *watch,
00907 unsigned int flags)
00908 {
00909 DBusTransportSocket *transport = (DBusTransportSocket *) itransport;
00910
00911 if (!(flags & DBUS_WATCH_HANGUP || flags & DBUS_WATCH_ERROR))
00912 return FALSE;
00913
00914
00915
00916 if (watch != transport->read_watch &&
00917 _dbus_watch_get_enabled (transport->read_watch))
00918 return FALSE;
00919
00920 return TRUE;
00921 }
00922
00923 static dbus_bool_t
00924 socket_handle_watch (DBusTransport *transport,
00925 DBusWatch *watch,
00926 unsigned int flags)
00927 {
00928 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00929
00930 _dbus_assert (watch == socket_transport->read_watch ||
00931 watch == socket_transport->write_watch);
00932 _dbus_assert (watch != NULL);
00933
00934
00935
00936
00937
00938 if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags))
00939 {
00940 _dbus_verbose ("Hang up or error on watch\n");
00941 _dbus_transport_disconnect (transport);
00942 return TRUE;
00943 }
00944
00945 if (watch == socket_transport->read_watch &&
00946 (flags & DBUS_WATCH_READABLE))
00947 {
00948 dbus_bool_t auth_finished;
00949 #if 1
00950 _dbus_verbose ("handling read watch %p flags = %x\n",
00951 watch, flags);
00952 #endif
00953 if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
00954 return FALSE;
00955
00956
00957
00958
00959
00960
00961
00962 if (!auth_finished)
00963 {
00964 if (!do_reading (transport))
00965 {
00966 _dbus_verbose ("no memory to read\n");
00967 return FALSE;
00968 }
00969 }
00970 else
00971 {
00972 _dbus_verbose ("Not reading anything since we just completed the authentication\n");
00973 }
00974 }
00975 else if (watch == socket_transport->write_watch &&
00976 (flags & DBUS_WATCH_WRITABLE))
00977 {
00978 #if 1
00979 _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
00980 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
00981 #endif
00982 if (!do_authentication (transport, FALSE, TRUE, NULL))
00983 return FALSE;
00984
00985 if (!do_writing (transport))
00986 {
00987 _dbus_verbose ("no memory to write\n");
00988 return FALSE;
00989 }
00990
00991
00992 check_write_watch (transport);
00993 }
00994 #ifdef DBUS_ENABLE_VERBOSE_MODE
00995 else
00996 {
00997 if (watch == socket_transport->read_watch)
00998 _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
00999 flags);
01000 else if (watch == socket_transport->write_watch)
01001 _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
01002 flags);
01003 else
01004 _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
01005 watch, dbus_watch_get_socket (watch));
01006 }
01007 #endif
01008
01009 return TRUE;
01010 }
01011
01012 static void
01013 socket_disconnect (DBusTransport *transport)
01014 {
01015 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
01016
01017 _dbus_verbose ("\n");
01018
01019 free_watches (transport);
01020
01021 _dbus_close_socket (socket_transport->fd, NULL);
01022 socket_transport->fd = -1;
01023 }
01024
01025 static dbus_bool_t
01026 socket_connection_set (DBusTransport *transport)
01027 {
01028 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
01029
01030 _dbus_watch_set_handler (socket_transport->write_watch,
01031 _dbus_connection_handle_watch,
01032 transport->connection, NULL);
01033
01034 _dbus_watch_set_handler (socket_transport->read_watch,
01035 _dbus_connection_handle_watch,
01036 transport->connection, NULL);
01037
01038 if (!_dbus_connection_add_watch_unlocked (transport->connection,
01039 socket_transport->write_watch))
01040 return FALSE;
01041
01042 if (!_dbus_connection_add_watch_unlocked (transport->connection,
01043 socket_transport->read_watch))
01044 {
01045 _dbus_connection_remove_watch_unlocked (transport->connection,
01046 socket_transport->write_watch);
01047 return FALSE;
01048 }
01049
01050 check_read_watch (transport);
01051 check_write_watch (transport);
01052
01053 return TRUE;
01054 }
01055
01063 static void
01064 socket_do_iteration (DBusTransport *transport,
01065 unsigned int flags,
01066 int timeout_milliseconds)
01067 {
01068 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
01069 DBusPollFD poll_fd;
01070 int poll_res;
01071 int poll_timeout;
01072
01073 _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
01074 flags & DBUS_ITERATION_DO_READING ? "read" : "",
01075 flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
01076 timeout_milliseconds,
01077 socket_transport->read_watch,
01078 socket_transport->write_watch,
01079 socket_transport->fd);
01080
01081
01082
01083
01084
01085
01086
01087 poll_fd.fd = socket_transport->fd;
01088 poll_fd.events = 0;
01089
01090 if (_dbus_transport_get_is_authenticated (transport))
01091 {
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102 if ((flags & DBUS_ITERATION_DO_WRITING) &&
01103 !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
01104 !transport->disconnected &&
01105 _dbus_connection_has_messages_to_send_unlocked (transport->connection))
01106 {
01107 do_writing (transport);
01108
01109 if (transport->disconnected ||
01110 !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
01111 goto out;
01112 }
01113
01114
01115 _dbus_assert (socket_transport->read_watch);
01116 if (flags & DBUS_ITERATION_DO_READING)
01117 poll_fd.events |= _DBUS_POLLIN;
01118
01119 _dbus_assert (socket_transport->write_watch);
01120 if (flags & DBUS_ITERATION_DO_WRITING)
01121 poll_fd.events |= _DBUS_POLLOUT;
01122 }
01123 else
01124 {
01125 DBusAuthState auth_state;
01126
01127 auth_state = _dbus_auth_do_work (transport->auth);
01128
01129 if (transport->receive_credentials_pending ||
01130 auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
01131 poll_fd.events |= _DBUS_POLLIN;
01132
01133 if (transport->send_credentials_pending ||
01134 auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
01135 poll_fd.events |= _DBUS_POLLOUT;
01136 }
01137
01138 if (poll_fd.events)
01139 {
01140 if (flags & DBUS_ITERATION_BLOCK)
01141 poll_timeout = timeout_milliseconds;
01142 else
01143 poll_timeout = 0;
01144
01145
01146
01147
01148
01149
01150 if (flags & DBUS_ITERATION_BLOCK)
01151 {
01152 _dbus_verbose ("unlock pre poll\n");
01153 _dbus_connection_unlock (transport->connection);
01154 }
01155
01156 again:
01157 poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
01158
01159 if (poll_res < 0 && _dbus_get_is_errno_eintr ())
01160 goto again;
01161
01162 if (flags & DBUS_ITERATION_BLOCK)
01163 {
01164 _dbus_verbose ("lock post poll\n");
01165 _dbus_connection_lock (transport->connection);
01166 }
01167
01168 if (poll_res >= 0)
01169 {
01170 if (poll_res == 0)
01171 poll_fd.revents = 0;
01172
01173
01174
01175
01176 if (poll_fd.revents & _DBUS_POLLERR)
01177 do_io_error (transport);
01178 else
01179 {
01180 dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
01181 dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
01182 dbus_bool_t authentication_completed;
01183
01184 _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
01185 need_read, need_write);
01186 do_authentication (transport, need_read, need_write,
01187 &authentication_completed);
01188
01189
01190 if (authentication_completed)
01191 goto out;
01192
01193 if (need_read && (flags & DBUS_ITERATION_DO_READING))
01194 do_reading (transport);
01195 if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
01196 do_writing (transport);
01197 }
01198 }
01199 else
01200 {
01201 _dbus_verbose ("Error from _dbus_poll(): %s\n",
01202 _dbus_strerror_from_errno ());
01203 }
01204 }
01205
01206
01207 out:
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218 check_write_watch (transport);
01219
01220 _dbus_verbose (" ... leaving do_iteration()\n");
01221 }
01222
01223 static void
01224 socket_live_messages_changed (DBusTransport *transport)
01225 {
01226
01227 check_read_watch (transport);
01228 }
01229
01230
01231 static dbus_bool_t
01232 socket_get_socket_fd (DBusTransport *transport,
01233 int *fd_p)
01234 {
01235 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
01236
01237 *fd_p = socket_transport->fd;
01238
01239 return TRUE;
01240 }
01241
01242 static const DBusTransportVTable socket_vtable = {
01243 socket_finalize,
01244 socket_handle_watch,
01245 socket_disconnect,
01246 socket_connection_set,
01247 socket_do_iteration,
01248 socket_live_messages_changed,
01249 socket_get_socket_fd
01250 };
01251
01263 DBusTransport*
01264 _dbus_transport_new_for_socket (int fd,
01265 const DBusString *server_guid,
01266 const DBusString *address)
01267 {
01268 DBusTransportSocket *socket_transport;
01269
01270 socket_transport = dbus_new0 (DBusTransportSocket, 1);
01271 if (socket_transport == NULL)
01272 return NULL;
01273
01274 if (!_dbus_string_init (&socket_transport->encoded_outgoing))
01275 goto failed_0;
01276
01277 if (!_dbus_string_init (&socket_transport->encoded_incoming))
01278 goto failed_1;
01279
01280 socket_transport->write_watch = _dbus_watch_new (fd,
01281 DBUS_WATCH_WRITABLE,
01282 FALSE,
01283 NULL, NULL, NULL);
01284 if (socket_transport->write_watch == NULL)
01285 goto failed_2;
01286
01287 socket_transport->read_watch = _dbus_watch_new (fd,
01288 DBUS_WATCH_READABLE,
01289 FALSE,
01290 NULL, NULL, NULL);
01291 if (socket_transport->read_watch == NULL)
01292 goto failed_3;
01293
01294 if (!_dbus_transport_init_base (&socket_transport->base,
01295 &socket_vtable,
01296 server_guid, address))
01297 goto failed_4;
01298
01299 #ifdef HAVE_UNIX_FD_PASSING
01300 _dbus_auth_set_unix_fd_possible(socket_transport->base.auth, _dbus_socket_can_pass_unix_fd(fd));
01301 #endif
01302
01303 socket_transport->fd = fd;
01304 socket_transport->message_bytes_written = 0;
01305
01306
01307 socket_transport->max_bytes_read_per_iteration = 2048;
01308 socket_transport->max_bytes_written_per_iteration = 2048;
01309
01310 return (DBusTransport*) socket_transport;
01311
01312 failed_4:
01313 _dbus_watch_unref (socket_transport->read_watch);
01314 failed_3:
01315 _dbus_watch_unref (socket_transport->write_watch);
01316 failed_2:
01317 _dbus_string_free (&socket_transport->encoded_incoming);
01318 failed_1:
01319 _dbus_string_free (&socket_transport->encoded_outgoing);
01320 failed_0:
01321 dbus_free (socket_transport);
01322 return NULL;
01323 }
01324
01336 DBusTransport*
01337 _dbus_transport_new_for_tcp_socket (const char *host,
01338 const char *port,
01339 const char *family,
01340 const char *noncefile,
01341 DBusError *error)
01342 {
01343 int fd;
01344 DBusTransport *transport;
01345 DBusString address;
01346
01347 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01348
01349 if (!_dbus_string_init (&address))
01350 {
01351 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01352 return NULL;
01353 }
01354
01355 if (host == NULL)
01356 host = "localhost";
01357
01358 if (!_dbus_string_append (&address, noncefile ? "nonce-tcp:" : "tcp:"))
01359 goto error;
01360
01361 if (!_dbus_string_append (&address, "host=") ||
01362 !_dbus_string_append (&address, host))
01363 goto error;
01364
01365 if (!_dbus_string_append (&address, ",port=") ||
01366 !_dbus_string_append (&address, port))
01367 goto error;
01368
01369 if (family != NULL &&
01370 (!_dbus_string_append (&address, "family=") ||
01371 !_dbus_string_append (&address, family)))
01372 goto error;
01373
01374 if (noncefile != NULL &&
01375 (!_dbus_string_append (&address, "noncefile=") ||
01376 !_dbus_string_append (&address, noncefile)))
01377 goto error;
01378
01379 fd = _dbus_connect_tcp_socket_with_nonce (host, port, family, noncefile, error);
01380 if (fd < 0)
01381 {
01382 _DBUS_ASSERT_ERROR_IS_SET (error);
01383 _dbus_string_free (&address);
01384 return NULL;
01385 }
01386
01387 _dbus_verbose ("Successfully connected to tcp socket %s:%s\n",
01388 host, port);
01389
01390 transport = _dbus_transport_new_for_socket (fd, NULL, &address);
01391 _dbus_string_free (&address);
01392 if (transport == NULL)
01393 {
01394 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01395 _dbus_close_socket (fd, NULL);
01396 fd = -1;
01397 }
01398
01399 return transport;
01400
01401 error:
01402 _dbus_string_free (&address);
01403 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01404 return NULL;
01405 }
01406
01415 DBusTransportOpenResult
01416 _dbus_transport_open_socket(DBusAddressEntry *entry,
01417 DBusTransport **transport_p,
01418 DBusError *error)
01419 {
01420 const char *method;
01421 dbus_bool_t isTcp;
01422 dbus_bool_t isNonceTcp;
01423
01424 method = dbus_address_entry_get_method (entry);
01425 _dbus_assert (method != NULL);
01426
01427 isTcp = strcmp (method, "tcp") == 0;
01428 isNonceTcp = strcmp (method, "nonce-tcp") == 0;
01429
01430 if (isTcp || isNonceTcp)
01431 {
01432 const char *host = dbus_address_entry_get_value (entry, "host");
01433 const char *port = dbus_address_entry_get_value (entry, "port");
01434 const char *family = dbus_address_entry_get_value (entry, "family");
01435 const char *noncefile = dbus_address_entry_get_value (entry, "noncefile");
01436
01437 if ((isNonceTcp == TRUE) != (noncefile != NULL)) {
01438 _dbus_set_bad_address (error, method, "noncefile", NULL);
01439 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
01440 }
01441
01442 if (port == NULL)
01443 {
01444 _dbus_set_bad_address (error, method, "port", NULL);
01445 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
01446 }
01447
01448 *transport_p = _dbus_transport_new_for_tcp_socket (host, port, family, noncefile, error);
01449 if (*transport_p == NULL)
01450 {
01451 _DBUS_ASSERT_ERROR_IS_SET (error);
01452 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
01453 }
01454 else
01455 {
01456 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01457 return DBUS_TRANSPORT_OPEN_OK;
01458 }
01459 }
01460 else
01461 {
01462 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01463 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
01464 }
01465 }
01466