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