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 if (_dbus_get_is_errno_eagain_or_ewouldblock ())
00620 goto out;
00621 else
00622 {
00623 _dbus_verbose ("Error writing to remote app: %s\n",
00624 _dbus_strerror_from_errno ());
00625 do_io_error (transport);
00626 goto out;
00627 }
00628 }
00629 else
00630 {
00631 _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
00632 total_bytes_to_write);
00633
00634 total += bytes_written;
00635 socket_transport->message_bytes_written += bytes_written;
00636
00637 _dbus_assert (socket_transport->message_bytes_written <=
00638 total_bytes_to_write);
00639
00640 if (socket_transport->message_bytes_written == total_bytes_to_write)
00641 {
00642 socket_transport->message_bytes_written = 0;
00643 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
00644 _dbus_string_compact (&socket_transport->encoded_outgoing, 2048);
00645
00646 _dbus_connection_message_sent (transport->connection,
00647 message);
00648 }
00649 }
00650 }
00651
00652 out:
00653 if (oom)
00654 return FALSE;
00655 else
00656 return TRUE;
00657 }
00658
00659
00660 static dbus_bool_t
00661 do_reading (DBusTransport *transport)
00662 {
00663 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00664 DBusString *buffer;
00665 int bytes_read;
00666 int total;
00667 dbus_bool_t oom;
00668
00669 _dbus_verbose ("%s: fd = %d\n", _DBUS_FUNCTION_NAME,
00670 socket_transport->fd);
00671
00672
00673 if (!_dbus_transport_get_is_authenticated (transport))
00674 return TRUE;
00675
00676 oom = FALSE;
00677
00678 total = 0;
00679
00680 again:
00681
00682
00683 check_read_watch (transport);
00684
00685 if (total > socket_transport->max_bytes_read_per_iteration)
00686 {
00687 _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
00688 total, socket_transport->max_bytes_read_per_iteration);
00689 goto out;
00690 }
00691
00692 _dbus_assert (socket_transport->read_watch != NULL ||
00693 transport->disconnected);
00694
00695 if (transport->disconnected)
00696 goto out;
00697
00698 if (!dbus_watch_get_enabled (socket_transport->read_watch))
00699 return TRUE;
00700
00701 if (_dbus_auth_needs_decoding (transport->auth))
00702 {
00703 if (_dbus_string_get_length (&socket_transport->encoded_incoming) > 0)
00704 bytes_read = _dbus_string_get_length (&socket_transport->encoded_incoming);
00705 else
00706 bytes_read = _dbus_read_socket (socket_transport->fd,
00707 &socket_transport->encoded_incoming,
00708 socket_transport->max_bytes_read_per_iteration);
00709
00710 _dbus_assert (_dbus_string_get_length (&socket_transport->encoded_incoming) ==
00711 bytes_read);
00712
00713 if (bytes_read > 0)
00714 {
00715 int orig_len;
00716
00717 _dbus_message_loader_get_buffer (transport->loader,
00718 &buffer);
00719
00720 orig_len = _dbus_string_get_length (buffer);
00721
00722 if (!_dbus_auth_decode_data (transport->auth,
00723 &socket_transport->encoded_incoming,
00724 buffer))
00725 {
00726 _dbus_verbose ("Out of memory decoding incoming data\n");
00727 _dbus_message_loader_return_buffer (transport->loader,
00728 buffer,
00729 _dbus_string_get_length (buffer) - orig_len);
00730
00731 oom = TRUE;
00732 goto out;
00733 }
00734
00735 _dbus_message_loader_return_buffer (transport->loader,
00736 buffer,
00737 _dbus_string_get_length (buffer) - orig_len);
00738
00739 _dbus_string_set_length (&socket_transport->encoded_incoming, 0);
00740 _dbus_string_compact (&socket_transport->encoded_incoming, 2048);
00741 }
00742 }
00743 else
00744 {
00745 _dbus_message_loader_get_buffer (transport->loader,
00746 &buffer);
00747
00748 bytes_read = _dbus_read_socket (socket_transport->fd,
00749 buffer, socket_transport->max_bytes_read_per_iteration);
00750
00751 _dbus_message_loader_return_buffer (transport->loader,
00752 buffer,
00753 bytes_read < 0 ? 0 : bytes_read);
00754 }
00755
00756 if (bytes_read < 0)
00757 {
00758
00759
00760 if (_dbus_get_is_errno_enomem ())
00761 {
00762 _dbus_verbose ("Out of memory in read()/do_reading()\n");
00763 oom = TRUE;
00764 goto out;
00765 }
00766 else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
00767 goto out;
00768 else
00769 {
00770 _dbus_verbose ("Error reading from remote app: %s\n",
00771 _dbus_strerror_from_errno ());
00772 do_io_error (transport);
00773 goto out;
00774 }
00775 }
00776 else if (bytes_read == 0)
00777 {
00778 _dbus_verbose ("Disconnected from remote app\n");
00779 do_io_error (transport);
00780 goto out;
00781 }
00782 else
00783 {
00784 _dbus_verbose (" read %d bytes\n", bytes_read);
00785
00786 total += bytes_read;
00787
00788 if (!_dbus_transport_queue_messages (transport))
00789 {
00790 oom = TRUE;
00791 _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
00792 goto out;
00793 }
00794
00795
00796
00797
00798
00799 goto again;
00800 }
00801
00802 out:
00803 if (oom)
00804 return FALSE;
00805 else
00806 return TRUE;
00807 }
00808
00809 static dbus_bool_t
00810 socket_handle_watch (DBusTransport *transport,
00811 DBusWatch *watch,
00812 unsigned int flags)
00813 {
00814 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00815
00816 _dbus_assert (watch == socket_transport->read_watch ||
00817 watch == socket_transport->write_watch);
00818 _dbus_assert (watch != NULL);
00819
00820
00821
00822
00823
00824
00825
00826 if ((flags & DBUS_WATCH_ERROR) ||
00827 ((flags & DBUS_WATCH_HANGUP) && !(flags & DBUS_WATCH_READABLE)))
00828 {
00829 _dbus_verbose ("Hang up or error on watch\n");
00830 _dbus_transport_disconnect (transport);
00831 return TRUE;
00832 }
00833
00834 if (watch == socket_transport->read_watch &&
00835 (flags & DBUS_WATCH_READABLE))
00836 {
00837 dbus_bool_t auth_finished;
00838 #if 1
00839 _dbus_verbose ("handling read watch %p flags = %x\n",
00840 watch, flags);
00841 #endif
00842 if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
00843 return FALSE;
00844
00845
00846
00847
00848
00849
00850
00851 if (!auth_finished)
00852 {
00853 if (!do_reading (transport))
00854 {
00855 _dbus_verbose ("no memory to read\n");
00856 return FALSE;
00857 }
00858 }
00859 else
00860 {
00861 _dbus_verbose ("Not reading anything since we just completed the authentication\n");
00862 }
00863 }
00864 else if (watch == socket_transport->write_watch &&
00865 (flags & DBUS_WATCH_WRITABLE))
00866 {
00867 #if 1
00868 _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
00869 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
00870 #endif
00871 if (!do_authentication (transport, FALSE, TRUE, NULL))
00872 return FALSE;
00873
00874 if (!do_writing (transport))
00875 {
00876 _dbus_verbose ("no memory to write\n");
00877 return FALSE;
00878 }
00879
00880
00881 check_write_watch (transport);
00882 }
00883 #ifdef DBUS_ENABLE_VERBOSE_MODE
00884 else
00885 {
00886 if (watch == socket_transport->read_watch)
00887 _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
00888 flags);
00889 else if (watch == socket_transport->write_watch)
00890 _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
00891 flags);
00892 else
00893 _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
00894 watch, dbus_watch_get_socket (watch));
00895 }
00896 #endif
00897
00898 return TRUE;
00899 }
00900
00901 static void
00902 socket_disconnect (DBusTransport *transport)
00903 {
00904 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00905
00906 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
00907
00908 free_watches (transport);
00909
00910 _dbus_close_socket (socket_transport->fd, NULL);
00911 socket_transport->fd = -1;
00912 }
00913
00914 static dbus_bool_t
00915 socket_connection_set (DBusTransport *transport)
00916 {
00917 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00918
00919 _dbus_watch_set_handler (socket_transport->write_watch,
00920 _dbus_connection_handle_watch,
00921 transport->connection, NULL);
00922
00923 _dbus_watch_set_handler (socket_transport->read_watch,
00924 _dbus_connection_handle_watch,
00925 transport->connection, NULL);
00926
00927 if (!_dbus_connection_add_watch_unlocked (transport->connection,
00928 socket_transport->write_watch))
00929 return FALSE;
00930
00931 if (!_dbus_connection_add_watch_unlocked (transport->connection,
00932 socket_transport->read_watch))
00933 {
00934 _dbus_connection_remove_watch_unlocked (transport->connection,
00935 socket_transport->write_watch);
00936 return FALSE;
00937 }
00938
00939 check_read_watch (transport);
00940 check_write_watch (transport);
00941
00942 return TRUE;
00943 }
00944
00952 static void
00953 socket_do_iteration (DBusTransport *transport,
00954 unsigned int flags,
00955 int timeout_milliseconds)
00956 {
00957 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00958 DBusPollFD poll_fd;
00959 int poll_res;
00960 int poll_timeout;
00961
00962 _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
00963 flags & DBUS_ITERATION_DO_READING ? "read" : "",
00964 flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
00965 timeout_milliseconds,
00966 socket_transport->read_watch,
00967 socket_transport->write_watch,
00968 socket_transport->fd);
00969
00970
00971
00972
00973
00974
00975
00976 poll_fd.fd = socket_transport->fd;
00977 poll_fd.events = 0;
00978
00979 if (_dbus_transport_get_is_authenticated (transport))
00980 {
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991 if ((flags & DBUS_ITERATION_DO_WRITING) &&
00992 !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
00993 !transport->disconnected &&
00994 _dbus_connection_has_messages_to_send_unlocked (transport->connection))
00995 {
00996 do_writing (transport);
00997
00998 if (transport->disconnected ||
00999 !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
01000 goto out;
01001 }
01002
01003
01004 _dbus_assert (socket_transport->read_watch);
01005 if (flags & DBUS_ITERATION_DO_READING)
01006 poll_fd.events |= _DBUS_POLLIN;
01007
01008 _dbus_assert (socket_transport->write_watch);
01009 if (flags & DBUS_ITERATION_DO_WRITING)
01010 poll_fd.events |= _DBUS_POLLOUT;
01011 }
01012 else
01013 {
01014 DBusAuthState auth_state;
01015
01016 auth_state = _dbus_auth_do_work (transport->auth);
01017
01018 if (transport->receive_credentials_pending ||
01019 auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
01020 poll_fd.events |= _DBUS_POLLIN;
01021
01022 if (transport->send_credentials_pending ||
01023 auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
01024 poll_fd.events |= _DBUS_POLLOUT;
01025 }
01026
01027 if (poll_fd.events)
01028 {
01029 if (flags & DBUS_ITERATION_BLOCK)
01030 poll_timeout = timeout_milliseconds;
01031 else
01032 poll_timeout = 0;
01033
01034
01035
01036
01037
01038
01039 if (flags & DBUS_ITERATION_BLOCK)
01040 {
01041 _dbus_verbose ("unlock %s pre poll\n", _DBUS_FUNCTION_NAME);
01042 _dbus_connection_unlock (transport->connection);
01043 }
01044
01045 again:
01046 poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
01047
01048 if (poll_res < 0 && _dbus_get_is_errno_eintr ())
01049 goto again;
01050
01051 if (flags & DBUS_ITERATION_BLOCK)
01052 {
01053 _dbus_verbose ("lock %s post poll\n", _DBUS_FUNCTION_NAME);
01054 _dbus_connection_lock (transport->connection);
01055 }
01056
01057 if (poll_res >= 0)
01058 {
01059 if (poll_res == 0)
01060 poll_fd.revents = 0;
01061
01062
01063
01064
01065 if (poll_fd.revents & _DBUS_POLLERR)
01066 do_io_error (transport);
01067 else
01068 {
01069 dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
01070 dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
01071 dbus_bool_t authentication_completed;
01072
01073 _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
01074 need_read, need_write);
01075 do_authentication (transport, need_read, need_write,
01076 &authentication_completed);
01077
01078
01079 if (authentication_completed)
01080 goto out;
01081
01082 if (need_read && (flags & DBUS_ITERATION_DO_READING))
01083 do_reading (transport);
01084 if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
01085 do_writing (transport);
01086 }
01087 }
01088 else
01089 {
01090 _dbus_verbose ("Error from _dbus_poll(): %s\n",
01091 _dbus_strerror_from_errno ());
01092 }
01093 }
01094
01095
01096 out:
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107 check_write_watch (transport);
01108
01109 _dbus_verbose (" ... leaving do_iteration()\n");
01110 }
01111
01112 static void
01113 socket_live_messages_changed (DBusTransport *transport)
01114 {
01115
01116 check_read_watch (transport);
01117 }
01118
01119
01120 static dbus_bool_t
01121 socket_get_socket_fd (DBusTransport *transport,
01122 int *fd_p)
01123 {
01124 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
01125
01126 *fd_p = socket_transport->fd;
01127
01128 return TRUE;
01129 }
01130
01131 static const DBusTransportVTable socket_vtable = {
01132 socket_finalize,
01133 socket_handle_watch,
01134 socket_disconnect,
01135 socket_connection_set,
01136 socket_do_iteration,
01137 socket_live_messages_changed,
01138 socket_get_socket_fd
01139 };
01140
01152 DBusTransport*
01153 _dbus_transport_new_for_socket (int fd,
01154 const DBusString *server_guid,
01155 const DBusString *address)
01156 {
01157 DBusTransportSocket *socket_transport;
01158
01159 socket_transport = dbus_new0 (DBusTransportSocket, 1);
01160 if (socket_transport == NULL)
01161 return NULL;
01162
01163 if (!_dbus_string_init (&socket_transport->encoded_outgoing))
01164 goto failed_0;
01165
01166 if (!_dbus_string_init (&socket_transport->encoded_incoming))
01167 goto failed_1;
01168
01169 socket_transport->write_watch = _dbus_watch_new (fd,
01170 DBUS_WATCH_WRITABLE,
01171 FALSE,
01172 NULL, NULL, NULL);
01173 if (socket_transport->write_watch == NULL)
01174 goto failed_2;
01175
01176 socket_transport->read_watch = _dbus_watch_new (fd,
01177 DBUS_WATCH_READABLE,
01178 FALSE,
01179 NULL, NULL, NULL);
01180 if (socket_transport->read_watch == NULL)
01181 goto failed_3;
01182
01183 if (!_dbus_transport_init_base (&socket_transport->base,
01184 &socket_vtable,
01185 server_guid, address))
01186 goto failed_4;
01187
01188 socket_transport->fd = fd;
01189 socket_transport->message_bytes_written = 0;
01190
01191
01192 socket_transport->max_bytes_read_per_iteration = 2048;
01193 socket_transport->max_bytes_written_per_iteration = 2048;
01194
01195 return (DBusTransport*) socket_transport;
01196
01197 failed_4:
01198 _dbus_watch_unref (socket_transport->read_watch);
01199 failed_3:
01200 _dbus_watch_unref (socket_transport->write_watch);
01201 failed_2:
01202 _dbus_string_free (&socket_transport->encoded_incoming);
01203 failed_1:
01204 _dbus_string_free (&socket_transport->encoded_outgoing);
01205 failed_0:
01206 dbus_free (socket_transport);
01207 return NULL;
01208 }
01209
01220 DBusTransport*
01221 _dbus_transport_new_for_tcp_socket (const char *host,
01222 const char *port,
01223 const char *family,
01224 DBusError *error)
01225 {
01226 int fd;
01227 DBusTransport *transport;
01228 DBusString address;
01229
01230 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01231
01232 if (!_dbus_string_init (&address))
01233 {
01234 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01235 return NULL;
01236 }
01237
01238 if (host == NULL)
01239 host = "localhost";
01240
01241 if (!_dbus_string_append (&address, "tcp:"))
01242 goto error;
01243
01244 if (!_dbus_string_append (&address, "host=") ||
01245 !_dbus_string_append (&address, host))
01246 goto error;
01247
01248 if (!_dbus_string_append (&address, ",port=") ||
01249 !_dbus_string_append (&address, port))
01250 goto error;
01251
01252 if (family != NULL &&
01253 (!_dbus_string_append (&address, "family=") ||
01254 !_dbus_string_append (&address, family)))
01255 goto error;
01256
01257 fd = _dbus_connect_tcp_socket (host, port, family, error);
01258 if (fd < 0)
01259 {
01260 _DBUS_ASSERT_ERROR_IS_SET (error);
01261 _dbus_string_free (&address);
01262 return NULL;
01263 }
01264
01265 _dbus_fd_set_close_on_exec (fd);
01266
01267 _dbus_verbose ("Successfully connected to tcp socket %s:%s\n",
01268 host, port);
01269
01270 transport = _dbus_transport_new_for_socket (fd, NULL, &address);
01271 if (transport == NULL)
01272 {
01273 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01274 _dbus_close_socket (fd, NULL);
01275 _dbus_string_free (&address);
01276 fd = -1;
01277 }
01278
01279 _dbus_string_free (&address);
01280
01281 return transport;
01282
01283 error:
01284 _dbus_string_free (&address);
01285 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01286 return NULL;
01287 }
01288
01297 DBusTransportOpenResult
01298 _dbus_transport_open_socket(DBusAddressEntry *entry,
01299 DBusTransport **transport_p,
01300 DBusError *error)
01301 {
01302 const char *method;
01303
01304 method = dbus_address_entry_get_method (entry);
01305 _dbus_assert (method != NULL);
01306
01307 if (strcmp (method, "tcp") == 0)
01308 {
01309 const char *host = dbus_address_entry_get_value (entry, "host");
01310 const char *port = dbus_address_entry_get_value (entry, "port");
01311 const char *family = dbus_address_entry_get_value (entry, "family");
01312
01313 if (port == NULL)
01314 {
01315 _dbus_set_bad_address (error, "tcp", "port", NULL);
01316 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
01317 }
01318
01319 *transport_p = _dbus_transport_new_for_tcp_socket (host, port, family, error);
01320 if (*transport_p == NULL)
01321 {
01322 _DBUS_ASSERT_ERROR_IS_SET (error);
01323 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
01324 }
01325 else
01326 {
01327 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01328 return DBUS_TRANSPORT_OPEN_OK;
01329 }
01330 }
01331 else
01332 {
01333 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01334 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
01335 }
01336 }
01337