00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "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
00150
00151
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
00203
00204
00205
00206 DBusAuthState auth_state;
00207
00208 auth_state = _dbus_auth_do_work (transport->auth);
00209
00210
00211
00212
00213
00214
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
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
00269
00270 if (_dbus_get_is_errno_enomem ())
00271 {
00272 *oom = TRUE;
00273 }
00274 else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
00275 ;
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
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
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
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
00364
00365
00366
00367
00368
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
00409
00410
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
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
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
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
00618
00619
00620
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
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
00677 if (!_dbus_transport_get_is_authenticated (transport))
00678 return TRUE;
00679
00680 oom = FALSE;
00681
00682 total = 0;
00683
00684 again:
00685
00686
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
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
00800
00801
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
00824
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
00844
00845
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
00866
00867
00868
00869
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
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
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
00991
00992
00993
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
01002
01003
01004
01005
01006
01007
01008
01009
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
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
01055
01056
01057
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;
01081
01082
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
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
01118
01119
01120
01121
01122
01123
01124
01125
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
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
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 if (transport == NULL)
01292 {
01293 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01294 _dbus_close_socket (fd, NULL);
01295 _dbus_string_free (&address);
01296 fd = -1;
01297 }
01298
01299 _dbus_string_free (&address);
01300
01301 return transport;
01302
01303 error:
01304 _dbus_string_free (&address);
01305 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01306 return NULL;
01307 }
01308
01317 DBusTransportOpenResult
01318 _dbus_transport_open_socket(DBusAddressEntry *entry,
01319 DBusTransport **transport_p,
01320 DBusError *error)
01321 {
01322 const char *method;
01323
01324 method = dbus_address_entry_get_method (entry);
01325 _dbus_assert (method != NULL);
01326
01327 if (strcmp (method, "tcp") == 0)
01328 {
01329 const char *host = dbus_address_entry_get_value (entry, "host");
01330 const char *port = dbus_address_entry_get_value (entry, "port");
01331 const char *family = dbus_address_entry_get_value (entry, "family");
01332
01333 if (port == NULL)
01334 {
01335 _dbus_set_bad_address (error, "tcp", "port", NULL);
01336 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
01337 }
01338
01339 *transport_p = _dbus_transport_new_for_tcp_socket (host, port, family, error);
01340 if (*transport_p == NULL)
01341 {
01342 _DBUS_ASSERT_ERROR_IS_SET (error);
01343 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
01344 }
01345 else
01346 {
01347 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01348 return DBUS_TRANSPORT_OPEN_OK;
01349 }
01350 }
01351 else
01352 {
01353 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01354 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
01355 }
01356 }
01357