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