1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 2 /* dbus-transport-socket.c Socket subclasses of DBusTransport 3 * 4 * Copyright (C) 2002, 2003, 2004, 2006 Red Hat Inc. 5 * 6 * Licensed under the Academic Free License version 2.1 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 * 22 */ 23 24 #include <config.h> 25 #include "dbus-internals.h" 26 #include "dbus-connection-internal.h" 27 #include "dbus-nonce.h" 28 #include "dbus-transport-socket.h" 29 #include "dbus-transport-protected.h" 30 #include "dbus-watch.h" 31 #include "dbus-credentials.h" 32 33 /** 34 * @defgroup DBusTransportSocket DBusTransport implementations for sockets 35 * @ingroup DBusInternals 36 * @brief Implementation details of DBusTransport on sockets 37 * 38 * @{ 39 */ 40 41 /** 42 * Opaque object representing a socket file descriptor transport. 43 */ 44 typedef struct DBusTransportSocket DBusTransportSocket; 45 46 /** 47 * Implementation details of DBusTransportSocket. All members are private. 48 */ 49 struct DBusTransportSocket 50 { 51 DBusTransport base; /**< Parent instance */ 52 int fd; /**< File descriptor. */ 53 DBusWatch *read_watch; /**< Watch for readability. */ 54 DBusWatch *write_watch; /**< Watch for writability. */ 55 56 int max_bytes_read_per_iteration; /**< To avoid blocking too long. */ 57 int max_bytes_written_per_iteration; /**< To avoid blocking too long. */ 58 59 int message_bytes_written; /**< Number of bytes of current 60 * outgoing message that have 61 * been written. 62 */ 63 DBusString encoded_outgoing; /**< Encoded version of current 64 * outgoing message. 65 */ 66 DBusString encoded_incoming; /**< Encoded version of current 67 * incoming data. 68 */ 69 }; 70 71 static void 72 free_watches (DBusTransport *transport) 73 { 74 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 75 76 _dbus_verbose ("start\n"); 77 78 if (socket_transport->read_watch) 79 { 80 if (transport->connection) 81 _dbus_connection_remove_watch_unlocked (transport->connection, 82 socket_transport->read_watch); 83 _dbus_watch_invalidate (socket_transport->read_watch); 84 _dbus_watch_unref (socket_transport->read_watch); 85 socket_transport->read_watch = NULL; 86 } 87 88 if (socket_transport->write_watch) 89 { 90 if (transport->connection) 91 _dbus_connection_remove_watch_unlocked (transport->connection, 92 socket_transport->write_watch); 93 _dbus_watch_invalidate (socket_transport->write_watch); 94 _dbus_watch_unref (socket_transport->write_watch); 95 socket_transport->write_watch = NULL; 96 } 97 98 _dbus_verbose ("end\n"); 99 } 100 101 static void 102 socket_finalize (DBusTransport *transport) 103 { 104 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 105 106 _dbus_verbose ("\n"); 107 108 free_watches (transport); 109 110 _dbus_string_free (&socket_transport->encoded_outgoing); 111 _dbus_string_free (&socket_transport->encoded_incoming); 112 113 _dbus_transport_finalize_base (transport); 114 115 _dbus_assert (socket_transport->read_watch == NULL); 116 _dbus_assert (socket_transport->write_watch == NULL); 117 118 dbus_free (transport); 119 } 120 121 static void 122 check_write_watch (DBusTransport *transport) 123 { 124 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 125 dbus_bool_t needed; 126 127 if (transport->connection == NULL) 128 return; 129 130 if (transport->disconnected) 131 { 132 _dbus_assert (socket_transport->write_watch == NULL); 133 return; 134 } 135 136 _dbus_transport_ref (transport); 137 138 if (_dbus_transport_get_is_authenticated (transport)) 139 needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection); 140 else 141 { 142 if (transport->send_credentials_pending) 143 needed = TRUE; 144 else 145 { 146 DBusAuthState auth_state; 147 148 auth_state = _dbus_auth_do_work (transport->auth); 149 150 /* If we need memory we install the write watch just in case, 151 * if there's no need for it, it will get de-installed 152 * next time we try reading. 153 */ 154 if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND || 155 auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY) 156 needed = TRUE; 157 else 158 needed = FALSE; 159 } 160 } 161 162 _dbus_verbose ("check_write_watch(): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n", 163 needed, transport->connection, socket_transport->write_watch, 164 socket_transport->fd, 165 _dbus_connection_has_messages_to_send_unlocked (transport->connection)); 166 167 _dbus_connection_toggle_watch_unlocked (transport->connection, 168 socket_transport->write_watch, 169 needed); 170 171 _dbus_transport_unref (transport); 172 } 173 174 static void 175 check_read_watch (DBusTransport *transport) 176 { 177 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 178 dbus_bool_t need_read_watch; 179 180 _dbus_verbose ("fd = %d\n",socket_transport->fd); 181 182 if (transport->connection == NULL) 183 return; 184 185 if (transport->disconnected) 186 { 187 _dbus_assert (socket_transport->read_watch == NULL); 188 return; 189 } 190 191 _dbus_transport_ref (transport); 192 193 if (_dbus_transport_get_is_authenticated (transport)) 194 need_read_watch = 195 (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) && 196 (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds); 197 else 198 { 199 if (transport->receive_credentials_pending) 200 need_read_watch = TRUE; 201 else 202 { 203 /* The reason to disable need_read_watch when not WAITING_FOR_INPUT 204 * is to avoid spinning on the file descriptor when we're waiting 205 * to write or for some other part of the auth process 206 */ 207 DBusAuthState auth_state; 208 209 auth_state = _dbus_auth_do_work (transport->auth); 210 211 /* If we need memory we install the read watch just in case, 212 * if there's no need for it, it will get de-installed 213 * next time we try reading. If we're authenticated we 214 * install it since we normally have it installed while 215 * authenticated. 216 */ 217 if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT || 218 auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY || 219 auth_state == DBUS_AUTH_STATE_AUTHENTICATED) 220 need_read_watch = TRUE; 221 else 222 need_read_watch = FALSE; 223 } 224 } 225 226 _dbus_verbose (" setting read watch enabled = %d\n", need_read_watch); 227 _dbus_connection_toggle_watch_unlocked (transport->connection, 228 socket_transport->read_watch, 229 need_read_watch); 230 231 _dbus_transport_unref (transport); 232 } 233 234 static void 235 do_io_error (DBusTransport *transport) 236 { 237 _dbus_transport_ref (transport); 238 _dbus_transport_disconnect (transport); 239 _dbus_transport_unref (transport); 240 } 241 242 /* return value is whether we successfully read any new data. */ 243 static dbus_bool_t 244 read_data_into_auth (DBusTransport *transport, 245 dbus_bool_t *oom) 246 { 247 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 248 DBusString *buffer; 249 int bytes_read; 250 251 *oom = FALSE; 252 253 _dbus_auth_get_buffer (transport->auth, &buffer); 254 255 bytes_read = _dbus_read_socket (socket_transport->fd, 256 buffer, socket_transport->max_bytes_read_per_iteration); 257 258 _dbus_auth_return_buffer (transport->auth, buffer, 259 bytes_read > 0 ? bytes_read : 0); 260 261 if (bytes_read > 0) 262 { 263 _dbus_verbose (" read %d bytes in auth phase\n", bytes_read); 264 265 return TRUE; 266 } 267 else if (bytes_read < 0) 268 { 269 /* EINTR already handled for us */ 270 271 if (_dbus_get_is_errno_enomem ()) 272 { 273 *oom = TRUE; 274 } 275 else if (_dbus_get_is_errno_eagain_or_ewouldblock ()) 276 ; /* do nothing, just return FALSE below */ 277 else 278 { 279 _dbus_verbose ("Error reading from remote app: %s\n", 280 _dbus_strerror_from_errno ()); 281 do_io_error (transport); 282 } 283 284 return FALSE; 285 } 286 else 287 { 288 _dbus_assert (bytes_read == 0); 289 290 _dbus_verbose ("Disconnected from remote app\n"); 291 do_io_error (transport); 292 293 return FALSE; 294 } 295 } 296 297 /* Return value is whether we successfully wrote any bytes */ 298 static dbus_bool_t 299 write_data_from_auth (DBusTransport *transport) 300 { 301 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 302 int bytes_written; 303 const DBusString *buffer; 304 305 if (!_dbus_auth_get_bytes_to_send (transport->auth, 306 &buffer)) 307 return FALSE; 308 309 bytes_written = _dbus_write_socket (socket_transport->fd, 310 buffer, 311 0, _dbus_string_get_length (buffer)); 312 313 if (bytes_written > 0) 314 { 315 _dbus_auth_bytes_sent (transport->auth, bytes_written); 316 return TRUE; 317 } 318 else if (bytes_written < 0) 319 { 320 /* EINTR already handled for us */ 321 322 if (_dbus_get_is_errno_eagain_or_ewouldblock ()) 323 ; 324 else 325 { 326 _dbus_verbose ("Error writing to remote app: %s\n", 327 _dbus_strerror_from_errno ()); 328 do_io_error (transport); 329 } 330 } 331 332 return FALSE; 333 } 334 335 /* FALSE on OOM */ 336 static dbus_bool_t 337 exchange_credentials (DBusTransport *transport, 338 dbus_bool_t do_reading, 339 dbus_bool_t do_writing) 340 { 341 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 342 DBusError error = DBUS_ERROR_INIT; 343 344 _dbus_verbose ("exchange_credentials: do_reading = %d, do_writing = %d\n", 345 do_reading, do_writing); 346 347 if (do_writing && transport->send_credentials_pending) 348 { 349 if (_dbus_send_credentials_socket (socket_transport->fd, 350 &error)) 351 { 352 transport->send_credentials_pending = FALSE; 353 } 354 else 355 { 356 _dbus_verbose ("Failed to write credentials: %s\n", error.message); 357 dbus_error_free (&error); 358 do_io_error (transport); 359 } 360 } 361 362 if (do_reading && transport->receive_credentials_pending) 363 { 364 /* FIXME this can fail due to IO error _or_ OOM, broken 365 * (somewhat tricky to fix since the OOM error can be set after 366 * we already read the credentials byte, so basically we need to 367 * separate reading the byte and storing it in the 368 * transport->credentials). Does not really matter for now 369 * because storing in credentials never actually fails on unix. 370 */ 371 if (_dbus_read_credentials_socket (socket_transport->fd, 372 transport->credentials, 373 &error)) 374 { 375 transport->receive_credentials_pending = FALSE; 376 } 377 else 378 { 379 _dbus_verbose ("Failed to read credentials %s\n", error.message); 380 dbus_error_free (&error); 381 do_io_error (transport); 382 } 383 } 384 385 if (!(transport->send_credentials_pending || 386 transport->receive_credentials_pending)) 387 { 388 if (!_dbus_auth_set_credentials (transport->auth, 389 transport->credentials)) 390 return FALSE; 391 } 392 393 return TRUE; 394 } 395 396 static dbus_bool_t 397 do_authentication (DBusTransport *transport, 398 dbus_bool_t do_reading, 399 dbus_bool_t do_writing, 400 dbus_bool_t *auth_completed) 401 { 402 dbus_bool_t oom; 403 dbus_bool_t orig_auth_state; 404 405 oom = FALSE; 406 407 orig_auth_state = _dbus_transport_get_is_authenticated (transport); 408 409 /* This is essential to avoid the check_write_watch() at the end, 410 * we don't want to add a write watch in do_iteration before 411 * we try writing and get EAGAIN 412 */ 413 if (orig_auth_state) 414 { 415 if (auth_completed) 416 *auth_completed = FALSE; 417 return TRUE; 418 } 419 420 _dbus_transport_ref (transport); 421 422 while (!_dbus_transport_get_is_authenticated (transport) && 423 _dbus_transport_get_is_connected (transport)) 424 { 425 if (!exchange_credentials (transport, do_reading, do_writing)) 426 { 427 /* OOM */ 428 oom = TRUE; 429 goto out; 430 } 431 432 if (transport->send_credentials_pending || 433 transport->receive_credentials_pending) 434 { 435 _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n", 436 transport->send_credentials_pending, 437 transport->receive_credentials_pending); 438 goto out; 439 } 440 441 #define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client") 442 switch (_dbus_auth_do_work (transport->auth)) 443 { 444 case DBUS_AUTH_STATE_WAITING_FOR_INPUT: 445 _dbus_verbose (" %s auth state: waiting for input\n", 446 TRANSPORT_SIDE (transport)); 447 if (!do_reading || !read_data_into_auth (transport, &oom)) 448 goto out; 449 break; 450 451 case DBUS_AUTH_STATE_WAITING_FOR_MEMORY: 452 _dbus_verbose (" %s auth state: waiting for memory\n", 453 TRANSPORT_SIDE (transport)); 454 oom = TRUE; 455 goto out; 456 break; 457 458 case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND: 459 _dbus_verbose (" %s auth state: bytes to send\n", 460 TRANSPORT_SIDE (transport)); 461 if (!do_writing || !write_data_from_auth (transport)) 462 goto out; 463 break; 464 465 case DBUS_AUTH_STATE_NEED_DISCONNECT: 466 _dbus_verbose (" %s auth state: need to disconnect\n", 467 TRANSPORT_SIDE (transport)); 468 do_io_error (transport); 469 break; 470 471 case DBUS_AUTH_STATE_AUTHENTICATED: 472 _dbus_verbose (" %s auth state: authenticated\n", 473 TRANSPORT_SIDE (transport)); 474 break; 475 } 476 } 477 478 out: 479 if (auth_completed) 480 *auth_completed = (orig_auth_state != _dbus_transport_get_is_authenticated (transport)); 481 482 check_read_watch (transport); 483 check_write_watch (transport); 484 _dbus_transport_unref (transport); 485 486 if (oom) 487 return FALSE; 488 else 489 return TRUE; 490 } 491 492 /* returns false on oom */ 493 static dbus_bool_t 494 do_writing (DBusTransport *transport) 495 { 496 int total; 497 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 498 dbus_bool_t oom; 499 500 /* No messages without authentication! */ 501 if (!_dbus_transport_get_is_authenticated (transport)) 502 { 503 _dbus_verbose ("Not authenticated, not writing anything\n"); 504 return TRUE; 505 } 506 507 if (transport->disconnected) 508 { 509 _dbus_verbose ("Not connected, not writing anything\n"); 510 return TRUE; 511 } 512 513 #if 1 514 _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n", 515 _dbus_connection_has_messages_to_send_unlocked (transport->connection), 516 socket_transport->fd); 517 #endif 518 519 oom = FALSE; 520 total = 0; 521 522 while (!transport->disconnected && 523 _dbus_connection_has_messages_to_send_unlocked (transport->connection)) 524 { 525 int bytes_written; 526 DBusMessage *message; 527 const DBusString *header; 528 const DBusString *body; 529 int header_len, body_len; 530 int total_bytes_to_write; 531 532 if (total > socket_transport->max_bytes_written_per_iteration) 533 { 534 _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n", 535 total, socket_transport->max_bytes_written_per_iteration); 536 goto out; 537 } 538 539 message = _dbus_connection_get_message_to_send (transport->connection); 540 _dbus_assert (message != NULL); 541 dbus_message_lock (message); 542 543 #if 0 544 _dbus_verbose ("writing message %p\n", message); 545 #endif 546 547 _dbus_message_get_network_data (message, 548 &header, &body); 549 550 header_len = _dbus_string_get_length (header); 551 body_len = _dbus_string_get_length (body); 552 553 if (_dbus_auth_needs_encoding (transport->auth)) 554 { 555 /* Does fd passing even make sense with encoded data? */ 556 _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport)); 557 558 if (_dbus_string_get_length (&socket_transport->encoded_outgoing) == 0) 559 { 560 if (!_dbus_auth_encode_data (transport->auth, 561 header, &socket_transport->encoded_outgoing)) 562 { 563 oom = TRUE; 564 goto out; 565 } 566 567 if (!_dbus_auth_encode_data (transport->auth, 568 body, &socket_transport->encoded_outgoing)) 569 { 570 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0); 571 oom = TRUE; 572 goto out; 573 } 574 } 575 576 total_bytes_to_write = _dbus_string_get_length (&socket_transport->encoded_outgoing); 577 578 #if 0 579 _dbus_verbose ("encoded message is %d bytes\n", 580 total_bytes_to_write); 581 #endif 582 583 bytes_written = 584 _dbus_write_socket (socket_transport->fd, 585 &socket_transport->encoded_outgoing, 586 socket_transport->message_bytes_written, 587 total_bytes_to_write - socket_transport->message_bytes_written); 588 } 589 else 590 { 591 total_bytes_to_write = header_len + body_len; 592 593 #if 0 594 _dbus_verbose ("message is %d bytes\n", 595 total_bytes_to_write); 596 #endif 597 598 #ifdef HAVE_UNIX_FD_PASSING 599 if (socket_transport->message_bytes_written <= 0 && DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport)) 600 { 601 /* Send the fds along with the first byte of the message */ 602 const int *unix_fds; 603 unsigned n; 604 605 _dbus_message_get_unix_fds(message, &unix_fds, &n); 606 607 bytes_written = 608 _dbus_write_socket_with_unix_fds_two (socket_transport->fd, 609 header, 610 socket_transport->message_bytes_written, 611 header_len - socket_transport->message_bytes_written, 612 body, 613 0, body_len, 614 unix_fds, 615 n); 616 617 if (bytes_written > 0 && n > 0) 618 _dbus_verbose("Wrote %i unix fds\n", n); 619 } 620 else 621 #endif 622 { 623 if (socket_transport->message_bytes_written < header_len) 624 { 625 bytes_written = 626 _dbus_write_socket_two (socket_transport->fd, 627 header, 628 socket_transport->message_bytes_written, 629 header_len - socket_transport->message_bytes_written, 630 body, 631 0, body_len); 632 } 633 else 634 { 635 bytes_written = 636 _dbus_write_socket (socket_transport->fd, 637 body, 638 (socket_transport->message_bytes_written - header_len), 639 body_len - 640 (socket_transport->message_bytes_written - header_len)); 641 } 642 } 643 } 644 645 if (bytes_written < 0) 646 { 647 /* EINTR already handled for us */ 648 649 /* For some discussion of why we also ignore EPIPE here, see 650 * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html 651 */ 652 653 if (_dbus_get_is_errno_eagain_or_ewouldblock () || _dbus_get_is_errno_epipe ()) 654 goto out; 655 else 656 { 657 _dbus_verbose ("Error writing to remote app: %s\n", 658 _dbus_strerror_from_errno ()); 659 do_io_error (transport); 660 goto out; 661 } 662 } 663 else 664 { 665 _dbus_verbose (" wrote %d bytes of %d\n", bytes_written, 666 total_bytes_to_write); 667 668 total += bytes_written; 669 socket_transport->message_bytes_written += bytes_written; 670 671 _dbus_assert (socket_transport->message_bytes_written <= 672 total_bytes_to_write); 673 674 if (socket_transport->message_bytes_written == total_bytes_to_write) 675 { 676 socket_transport->message_bytes_written = 0; 677 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0); 678 _dbus_string_compact (&socket_transport->encoded_outgoing, 2048); 679 680 _dbus_connection_message_sent_unlocked (transport->connection, 681 message); 682 } 683 } 684 } 685 686 out: 687 if (oom) 688 return FALSE; 689 else 690 return TRUE; 691 } 692 693 /* returns false on out-of-memory */ 694 static dbus_bool_t 695 do_reading (DBusTransport *transport) 696 { 697 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 698 DBusString *buffer; 699 int bytes_read; 700 int total; 701 dbus_bool_t oom; 702 703 _dbus_verbose ("fd = %d\n",socket_transport->fd); 704 705 /* No messages without authentication! */ 706 if (!_dbus_transport_get_is_authenticated (transport)) 707 return TRUE; 708 709 oom = FALSE; 710 711 total = 0; 712 713 again: 714 715 /* See if we've exceeded max messages and need to disable reading */ 716 check_read_watch (transport); 717 718 if (total > socket_transport->max_bytes_read_per_iteration) 719 { 720 _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n", 721 total, socket_transport->max_bytes_read_per_iteration); 722 goto out; 723 } 724 725 _dbus_assert (socket_transport->read_watch != NULL || 726 transport->disconnected); 727 728 if (transport->disconnected) 729 goto out; 730 731 if (!dbus_watch_get_enabled (socket_transport->read_watch)) 732 return TRUE; 733 734 if (_dbus_auth_needs_decoding (transport->auth)) 735 { 736 /* Does fd passing even make sense with encoded data? */ 737 _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport)); 738 739 if (_dbus_string_get_length (&socket_transport->encoded_incoming) > 0) 740 bytes_read = _dbus_string_get_length (&socket_transport->encoded_incoming); 741 else 742 bytes_read = _dbus_read_socket (socket_transport->fd, 743 &socket_transport->encoded_incoming, 744 socket_transport->max_bytes_read_per_iteration); 745 746 _dbus_assert (_dbus_string_get_length (&socket_transport->encoded_incoming) == 747 bytes_read); 748 749 if (bytes_read > 0) 750 { 751 int orig_len; 752 753 _dbus_message_loader_get_buffer (transport->loader, 754 &buffer); 755 756 orig_len = _dbus_string_get_length (buffer); 757 758 if (!_dbus_auth_decode_data (transport->auth, 759 &socket_transport->encoded_incoming, 760 buffer)) 761 { 762 _dbus_verbose ("Out of memory decoding incoming data\n"); 763 _dbus_message_loader_return_buffer (transport->loader, 764 buffer, 765 _dbus_string_get_length (buffer) - orig_len); 766 767 oom = TRUE; 768 goto out; 769 } 770 771 _dbus_message_loader_return_buffer (transport->loader, 772 buffer, 773 _dbus_string_get_length (buffer) - orig_len); 774 775 _dbus_string_set_length (&socket_transport->encoded_incoming, 0); 776 _dbus_string_compact (&socket_transport->encoded_incoming, 2048); 777 } 778 } 779 else 780 { 781 _dbus_message_loader_get_buffer (transport->loader, 782 &buffer); 783 784 #ifdef HAVE_UNIX_FD_PASSING 785 if (DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport)) 786 { 787 int *fds, n_fds; 788 789 if (!_dbus_message_loader_get_unix_fds(transport->loader, &fds, &n_fds)) 790 { 791 _dbus_verbose ("Out of memory reading file descriptors\n"); 792 _dbus_message_loader_return_buffer (transport->loader, buffer, 0); 793 oom = TRUE; 794 goto out; 795 } 796 797 bytes_read = _dbus_read_socket_with_unix_fds(socket_transport->fd, 798 buffer, 799 socket_transport->max_bytes_read_per_iteration, 800 fds, &n_fds); 801 802 if (bytes_read >= 0 && n_fds > 0) 803 _dbus_verbose("Read %i unix fds\n", n_fds); 804 805 _dbus_message_loader_return_unix_fds(transport->loader, fds, bytes_read < 0 ? 0 : n_fds); 806 } 807 else 808 #endif 809 { 810 bytes_read = _dbus_read_socket (socket_transport->fd, 811 buffer, socket_transport->max_bytes_read_per_iteration); 812 } 813 814 _dbus_message_loader_return_buffer (transport->loader, 815 buffer, 816 bytes_read < 0 ? 0 : bytes_read); 817 } 818 819 if (bytes_read < 0) 820 { 821 /* EINTR already handled for us */ 822 823 if (_dbus_get_is_errno_enomem ()) 824 { 825 _dbus_verbose ("Out of memory in read()/do_reading()\n"); 826 oom = TRUE; 827 goto out; 828 } 829 else if (_dbus_get_is_errno_eagain_or_ewouldblock ()) 830 goto out; 831 else 832 { 833 _dbus_verbose ("Error reading from remote app: %s\n", 834 _dbus_strerror_from_errno ()); 835 do_io_error (transport); 836 goto out; 837 } 838 } 839 else if (bytes_read == 0) 840 { 841 _dbus_verbose ("Disconnected from remote app\n"); 842 do_io_error (transport); 843 goto out; 844 } 845 else 846 { 847 _dbus_verbose (" read %d bytes\n", bytes_read); 848 849 total += bytes_read; 850 851 if (!_dbus_transport_queue_messages (transport)) 852 { 853 oom = TRUE; 854 _dbus_verbose (" out of memory when queueing messages we just read in the transport\n"); 855 goto out; 856 } 857 858 /* Try reading more data until we get EAGAIN and return, or 859 * exceed max bytes per iteration. If in blocking mode of 860 * course we'll block instead of returning. 861 */ 862 goto again; 863 } 864 865 out: 866 if (oom) 867 return FALSE; 868 else 869 return TRUE; 870 } 871 872 static dbus_bool_t 873 unix_error_with_read_to_come (DBusTransport *itransport, 874 DBusWatch *watch, 875 unsigned int flags) 876 { 877 DBusTransportSocket *transport = (DBusTransportSocket *) itransport; 878 879 if (!(flags & DBUS_WATCH_HANGUP || flags & DBUS_WATCH_ERROR)) 880 return FALSE; 881 882 /* If we have a read watch enabled ... 883 we -might have data incoming ... => handle the HANGUP there */ 884 if (watch != transport->read_watch && 885 _dbus_watch_get_enabled (transport->read_watch)) 886 return FALSE; 887 888 return TRUE; 889 } 890 891 static dbus_bool_t 892 socket_handle_watch (DBusTransport *transport, 893 DBusWatch *watch, 894 unsigned int flags) 895 { 896 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 897 898 _dbus_assert (watch == socket_transport->read_watch || 899 watch == socket_transport->write_watch); 900 _dbus_assert (watch != NULL); 901 902 /* If we hit an error here on a write watch, don't disconnect the transport yet because data can 903 * still be in the buffer and do_reading may need several iteration to read 904 * it all (because of its max_bytes_read_per_iteration limit). 905 */ 906 if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags)) 907 { 908 _dbus_verbose ("Hang up or error on watch\n"); 909 _dbus_transport_disconnect (transport); 910 return TRUE; 911 } 912 913 if (watch == socket_transport->read_watch && 914 (flags & DBUS_WATCH_READABLE)) 915 { 916 dbus_bool_t auth_finished; 917 #if 1 918 _dbus_verbose ("handling read watch %p flags = %x\n", 919 watch, flags); 920 #endif 921 if (!do_authentication (transport, TRUE, FALSE, &auth_finished)) 922 return FALSE; 923 924 /* We don't want to do a read immediately following 925 * a successful authentication. This is so we 926 * have a chance to propagate the authentication 927 * state further up. Specifically, we need to 928 * process any pending data from the auth object. 929 */ 930 if (!auth_finished) 931 { 932 if (!do_reading (transport)) 933 { 934 _dbus_verbose ("no memory to read\n"); 935 return FALSE; 936 } 937 } 938 else 939 { 940 _dbus_verbose ("Not reading anything since we just completed the authentication\n"); 941 } 942 } 943 else if (watch == socket_transport->write_watch && 944 (flags & DBUS_WATCH_WRITABLE)) 945 { 946 #if 1 947 _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n", 948 _dbus_connection_has_messages_to_send_unlocked (transport->connection)); 949 #endif 950 if (!do_authentication (transport, FALSE, TRUE, NULL)) 951 return FALSE; 952 953 if (!do_writing (transport)) 954 { 955 _dbus_verbose ("no memory to write\n"); 956 return FALSE; 957 } 958 959 /* See if we still need the write watch */ 960 check_write_watch (transport); 961 } 962 #ifdef DBUS_ENABLE_VERBOSE_MODE 963 else 964 { 965 if (watch == socket_transport->read_watch) 966 _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n", 967 flags); 968 else if (watch == socket_transport->write_watch) 969 _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n", 970 flags); 971 else 972 _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n", 973 watch, dbus_watch_get_socket (watch)); 974 } 975 #endif /* DBUS_ENABLE_VERBOSE_MODE */ 976 977 return TRUE; 978 } 979 980 static void 981 socket_disconnect (DBusTransport *transport) 982 { 983 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 984 985 _dbus_verbose ("\n"); 986 987 free_watches (transport); 988 989 _dbus_close_socket (socket_transport->fd, NULL); 990 socket_transport->fd = -1; 991 } 992 993 static dbus_bool_t 994 socket_connection_set (DBusTransport *transport) 995 { 996 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 997 998 _dbus_watch_set_handler (socket_transport->write_watch, 999 _dbus_connection_handle_watch, 1000 transport->connection, NULL); 1001 1002 _dbus_watch_set_handler (socket_transport->read_watch, 1003 _dbus_connection_handle_watch, 1004 transport->connection, NULL); 1005 1006 if (!_dbus_connection_add_watch_unlocked (transport->connection, 1007 socket_transport->write_watch)) 1008 return FALSE; 1009 1010 if (!_dbus_connection_add_watch_unlocked (transport->connection, 1011 socket_transport->read_watch)) 1012 { 1013 _dbus_connection_remove_watch_unlocked (transport->connection, 1014 socket_transport->write_watch); 1015 return FALSE; 1016 } 1017 1018 check_read_watch (transport); 1019 check_write_watch (transport); 1020 1021 return TRUE; 1022 } 1023 1024 /** 1025 * @todo We need to have a way to wake up the select sleep if 1026 * a new iteration request comes in with a flag (read/write) that 1027 * we're not currently serving. Otherwise a call that just reads 1028 * could block a write call forever (if there are no incoming 1029 * messages). 1030 */ 1031 static void 1032 socket_do_iteration (DBusTransport *transport, 1033 unsigned int flags, 1034 int timeout_milliseconds) 1035 { 1036 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 1037 DBusPollFD poll_fd; 1038 int poll_res; 1039 int poll_timeout; 1040 1041 _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n", 1042 flags & DBUS_ITERATION_DO_READING ? "read" : "", 1043 flags & DBUS_ITERATION_DO_WRITING ? "write" : "", 1044 timeout_milliseconds, 1045 socket_transport->read_watch, 1046 socket_transport->write_watch, 1047 socket_transport->fd); 1048 1049 /* the passed in DO_READING/DO_WRITING flags indicate whether to 1050 * read/write messages, but regardless of those we may need to block 1051 * for reading/writing to do auth. But if we do reading for auth, 1052 * we don't want to read any messages yet if not given DO_READING. 1053 */ 1054 1055 poll_fd.fd = socket_transport->fd; 1056 poll_fd.events = 0; 1057 1058 if (_dbus_transport_get_is_authenticated (transport)) 1059 { 1060 /* This is kind of a hack; if we have stuff to write, then try 1061 * to avoid the poll. This is probably about a 5% speedup on an 1062 * echo client/server. 1063 * 1064 * If both reading and writing were requested, we want to avoid this 1065 * since it could have funky effects: 1066 * - both ends spinning waiting for the other one to read 1067 * data so they can finish writing 1068 * - prioritizing all writing ahead of reading 1069 */ 1070 if ((flags & DBUS_ITERATION_DO_WRITING) && 1071 !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) && 1072 !transport->disconnected && 1073 _dbus_connection_has_messages_to_send_unlocked (transport->connection)) 1074 { 1075 do_writing (transport); 1076 1077 if (transport->disconnected || 1078 !_dbus_connection_has_messages_to_send_unlocked (transport->connection)) 1079 goto out; 1080 } 1081 1082 /* If we get here, we decided to do the poll() after all */ 1083 _dbus_assert (socket_transport->read_watch); 1084 if (flags & DBUS_ITERATION_DO_READING) 1085 poll_fd.events |= _DBUS_POLLIN; 1086 1087 _dbus_assert (socket_transport->write_watch); 1088 if (flags & DBUS_ITERATION_DO_WRITING) 1089 poll_fd.events |= _DBUS_POLLOUT; 1090 } 1091 else 1092 { 1093 DBusAuthState auth_state; 1094 1095 auth_state = _dbus_auth_do_work (transport->auth); 1096 1097 if (transport->receive_credentials_pending || 1098 auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT) 1099 poll_fd.events |= _DBUS_POLLIN; 1100 1101 if (transport->send_credentials_pending || 1102 auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND) 1103 poll_fd.events |= _DBUS_POLLOUT; 1104 } 1105 1106 if (poll_fd.events) 1107 { 1108 if (flags & DBUS_ITERATION_BLOCK) 1109 poll_timeout = timeout_milliseconds; 1110 else 1111 poll_timeout = 0; 1112 1113 /* For blocking selects we drop the connection lock here 1114 * to avoid blocking out connection access during a potentially 1115 * indefinite blocking call. The io path is still protected 1116 * by the io_path_cond condvar, so we won't reenter this. 1117 */ 1118 if (flags & DBUS_ITERATION_BLOCK) 1119 { 1120 _dbus_verbose ("unlock pre poll\n"); 1121 _dbus_connection_unlock (transport->connection); 1122 } 1123 1124 again: 1125 poll_res = _dbus_poll (&poll_fd, 1, poll_timeout); 1126 1127 if (poll_res < 0 && _dbus_get_is_errno_eintr ()) 1128 goto again; 1129 1130 if (flags & DBUS_ITERATION_BLOCK) 1131 { 1132 _dbus_verbose ("lock post poll\n"); 1133 _dbus_connection_lock (transport->connection); 1134 } 1135 1136 if (poll_res >= 0) 1137 { 1138 if (poll_res == 0) 1139 poll_fd.revents = 0; /* some concern that posix does not guarantee this; 1140 * valgrind flags it as an error. though it probably 1141 * is guaranteed on linux at least. 1142 */ 1143 1144 if (poll_fd.revents & _DBUS_POLLERR) 1145 do_io_error (transport); 1146 else 1147 { 1148 dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0; 1149 dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0; 1150 dbus_bool_t authentication_completed; 1151 1152 _dbus_verbose ("in iteration, need_read=%d need_write=%d\n", 1153 need_read, need_write); 1154 do_authentication (transport, need_read, need_write, 1155 &authentication_completed); 1156 1157 /* See comment in socket_handle_watch. */ 1158 if (authentication_completed) 1159 goto out; 1160 1161 if (need_read && (flags & DBUS_ITERATION_DO_READING)) 1162 do_reading (transport); 1163 if (need_write && (flags & DBUS_ITERATION_DO_WRITING)) 1164 do_writing (transport); 1165 } 1166 } 1167 else 1168 { 1169 _dbus_verbose ("Error from _dbus_poll(): %s\n", 1170 _dbus_strerror_from_errno ()); 1171 } 1172 } 1173 1174 1175 out: 1176 /* We need to install the write watch only if we did not 1177 * successfully write everything. Note we need to be careful that we 1178 * don't call check_write_watch *before* do_writing, since it's 1179 * inefficient to add the write watch, and we can avoid it most of 1180 * the time since we can write immediately. 1181 * 1182 * However, we MUST always call check_write_watch(); DBusConnection code 1183 * relies on the fact that running an iteration will notice that 1184 * messages are pending. 1185 */ 1186 check_write_watch (transport); 1187 1188 _dbus_verbose (" ... leaving do_iteration()\n"); 1189 } 1190 1191 static void 1192 socket_live_messages_changed (DBusTransport *transport) 1193 { 1194 /* See if we should look for incoming messages again */ 1195 check_read_watch (transport); 1196 } 1197 1198 1199 static dbus_bool_t 1200 socket_get_socket_fd (DBusTransport *transport, 1201 int *fd_p) 1202 { 1203 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; 1204 1205 *fd_p = socket_transport->fd; 1206 1207 return TRUE; 1208 } 1209 1210 static const DBusTransportVTable socket_vtable = { 1211 socket_finalize, 1212 socket_handle_watch, 1213 socket_disconnect, 1214 socket_connection_set, 1215 socket_do_iteration, 1216 socket_live_messages_changed, 1217 socket_get_socket_fd 1218 }; 1219 1220 /** 1221 * Creates a new transport for the given socket file descriptor. The file 1222 * descriptor must be nonblocking (use _dbus_set_fd_nonblocking() to 1223 * make it so). This function is shared by various transports that 1224 * boil down to a full duplex file descriptor. 1225 * 1226 * @param fd the file descriptor. 1227 * @param server_guid non-#NULL if this transport is on the server side of a connection 1228 * @param address the transport's address 1229 * @returns the new transport, or #NULL if no memory. 1230 */ 1231 DBusTransport* 1232 _dbus_transport_new_for_socket (int fd, 1233 const DBusString *server_guid, 1234 const DBusString *address) 1235 { 1236 DBusTransportSocket *socket_transport; 1237 1238 socket_transport = dbus_new0 (DBusTransportSocket, 1); 1239 if (socket_transport == NULL) 1240 return NULL; 1241 1242 if (!_dbus_string_init (&socket_transport->encoded_outgoing)) 1243 goto failed_0; 1244 1245 if (!_dbus_string_init (&socket_transport->encoded_incoming)) 1246 goto failed_1; 1247 1248 socket_transport->write_watch = _dbus_watch_new (fd, 1249 DBUS_WATCH_WRITABLE, 1250 FALSE, 1251 NULL, NULL, NULL); 1252 if (socket_transport->write_watch == NULL) 1253 goto failed_2; 1254 1255 socket_transport->read_watch = _dbus_watch_new (fd, 1256 DBUS_WATCH_READABLE, 1257 FALSE, 1258 NULL, NULL, NULL); 1259 if (socket_transport->read_watch == NULL) 1260 goto failed_3; 1261 1262 if (!_dbus_transport_init_base (&socket_transport->base, 1263 &socket_vtable, 1264 server_guid, address)) 1265 goto failed_4; 1266 1267 #ifdef HAVE_UNIX_FD_PASSING 1268 _dbus_auth_set_unix_fd_possible(socket_transport->base.auth, _dbus_socket_can_pass_unix_fd(fd)); 1269 #endif 1270 1271 socket_transport->fd = fd; 1272 socket_transport->message_bytes_written = 0; 1273 1274 /* These values should probably be tunable or something. */ 1275 socket_transport->max_bytes_read_per_iteration = 2048; 1276 socket_transport->max_bytes_written_per_iteration = 2048; 1277 1278 return (DBusTransport*) socket_transport; 1279 1280 failed_4: 1281 _dbus_watch_invalidate (socket_transport->read_watch); 1282 _dbus_watch_unref (socket_transport->read_watch); 1283 failed_3: 1284 _dbus_watch_invalidate (socket_transport->write_watch); 1285 _dbus_watch_unref (socket_transport->write_watch); 1286 failed_2: 1287 _dbus_string_free (&socket_transport->encoded_incoming); 1288 failed_1: 1289 _dbus_string_free (&socket_transport->encoded_outgoing); 1290 failed_0: 1291 dbus_free (socket_transport); 1292 return NULL; 1293 } 1294 1295 /** 1296 * Creates a new transport for the given hostname and port. 1297 * If host is NULL, it will default to localhost 1298 * 1299 * @param host the host to connect to 1300 * @param port the port to connect to 1301 * @param family the address family to connect to 1302 * @param path to nonce file 1303 * @param error location to store reason for failure. 1304 * @returns a new transport, or #NULL on failure. 1305 */ 1306 DBusTransport* 1307 _dbus_transport_new_for_tcp_socket (const char *host, 1308 const char *port, 1309 const char *family, 1310 const char *noncefile, 1311 DBusError *error) 1312 { 1313 int fd; 1314 DBusTransport *transport; 1315 DBusString address; 1316 1317 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1318 1319 if (!_dbus_string_init (&address)) 1320 { 1321 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1322 return NULL; 1323 } 1324 1325 if (host == NULL) 1326 host = "localhost"; 1327 1328 if (!_dbus_string_append (&address, noncefile ? "nonce-tcp:" : "tcp:")) 1329 goto error; 1330 1331 if (!_dbus_string_append (&address, "host=") || 1332 !_dbus_string_append (&address, host)) 1333 goto error; 1334 1335 if (!_dbus_string_append (&address, ",port=") || 1336 !_dbus_string_append (&address, port)) 1337 goto error; 1338 1339 if (family != NULL && 1340 (!_dbus_string_append (&address, ",family=") || 1341 !_dbus_string_append (&address, family))) 1342 goto error; 1343 1344 if (noncefile != NULL && 1345 (!_dbus_string_append (&address, ",noncefile=") || 1346 !_dbus_string_append (&address, noncefile))) 1347 goto error; 1348 1349 fd = _dbus_connect_tcp_socket_with_nonce (host, port, family, noncefile, error); 1350 if (fd < 0) 1351 { 1352 _DBUS_ASSERT_ERROR_IS_SET (error); 1353 _dbus_string_free (&address); 1354 return NULL; 1355 } 1356 1357 _dbus_verbose ("Successfully connected to tcp socket %s:%s\n", 1358 host, port); 1359 1360 transport = _dbus_transport_new_for_socket (fd, NULL, &address); 1361 _dbus_string_free (&address); 1362 if (transport == NULL) 1363 { 1364 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1365 _dbus_close_socket (fd, NULL); 1366 fd = -1; 1367 } 1368 1369 return transport; 1370 1371 error: 1372 _dbus_string_free (&address); 1373 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1374 return NULL; 1375 } 1376 1377 /** 1378 * Opens a TCP socket transport. 1379 * 1380 * @param entry the address entry to try opening as a tcp transport. 1381 * @param transport_p return location for the opened transport 1382 * @param error error to be set 1383 * @returns result of the attempt 1384 */ 1385 DBusTransportOpenResult 1386 _dbus_transport_open_socket(DBusAddressEntry *entry, 1387 DBusTransport **transport_p, 1388 DBusError *error) 1389 { 1390 const char *method; 1391 dbus_bool_t isTcp; 1392 dbus_bool_t isNonceTcp; 1393 1394 method = dbus_address_entry_get_method (entry); 1395 _dbus_assert (method != NULL); 1396 1397 isTcp = strcmp (method, "tcp") == 0; 1398 isNonceTcp = strcmp (method, "nonce-tcp") == 0; 1399 1400 if (isTcp || isNonceTcp) 1401 { 1402 const char *host = dbus_address_entry_get_value (entry, "host"); 1403 const char *port = dbus_address_entry_get_value (entry, "port"); 1404 const char *family = dbus_address_entry_get_value (entry, "family"); 1405 const char *noncefile = dbus_address_entry_get_value (entry, "noncefile"); 1406 1407 if ((isNonceTcp == TRUE) != (noncefile != NULL)) { 1408 _dbus_set_bad_address (error, method, "noncefile", NULL); 1409 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS; 1410 } 1411 1412 if (port == NULL) 1413 { 1414 _dbus_set_bad_address (error, method, "port", NULL); 1415 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS; 1416 } 1417 1418 *transport_p = _dbus_transport_new_for_tcp_socket (host, port, family, noncefile, error); 1419 if (*transport_p == NULL) 1420 { 1421 _DBUS_ASSERT_ERROR_IS_SET (error); 1422 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT; 1423 } 1424 else 1425 { 1426 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1427 return DBUS_TRANSPORT_OPEN_OK; 1428 } 1429 } 1430 else 1431 { 1432 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1433 return DBUS_TRANSPORT_OPEN_NOT_HANDLED; 1434 } 1435 } 1436 1437 /** @} */ 1438 1439