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;
00342
00343 _dbus_verbose ("exchange_credentials: do_reading = %d, do_writing = %d\n",
00344 do_reading, do_writing);
00345
00346 dbus_error_init (&error);
00347 if (do_writing && transport->send_credentials_pending)
00348 {
00349 if (_dbus_send_credentials_socket (socket_transport->fd,
00350 &error))
00351 {
00352 transport->send_credentials_pending = FALSE;
00353 }
00354 else
00355 {
00356 _dbus_verbose ("Failed to write credentials: %s\n", error.message);
00357 dbus_error_free (&error);
00358 do_io_error (transport);
00359 }
00360 }
00361
00362 if (do_reading && transport->receive_credentials_pending)
00363 {
00364
00365
00366
00367
00368
00369
00370
00371 if (_dbus_read_credentials_socket (socket_transport->fd,
00372 transport->credentials,
00373 &error))
00374 {
00375 transport->receive_credentials_pending = FALSE;
00376 }
00377 else
00378 {
00379 _dbus_verbose ("Failed to read credentials %s\n", error.message);
00380 dbus_error_free (&error);
00381 do_io_error (transport);
00382 }
00383 }
00384
00385 if (!(transport->send_credentials_pending ||
00386 transport->receive_credentials_pending))
00387 {
00388 if (!_dbus_auth_set_credentials (transport->auth,
00389 transport->credentials))
00390 return FALSE;
00391 }
00392
00393 return TRUE;
00394 }
00395
00396 static dbus_bool_t
00397 do_authentication (DBusTransport *transport,
00398 dbus_bool_t do_reading,
00399 dbus_bool_t do_writing,
00400 dbus_bool_t *auth_completed)
00401 {
00402 dbus_bool_t oom;
00403 dbus_bool_t orig_auth_state;
00404
00405 oom = FALSE;
00406
00407 orig_auth_state = _dbus_transport_get_is_authenticated (transport);
00408
00409
00410
00411
00412
00413 if (orig_auth_state)
00414 {
00415 if (auth_completed)
00416 *auth_completed = FALSE;
00417 return TRUE;
00418 }
00419
00420 _dbus_transport_ref (transport);
00421
00422 while (!_dbus_transport_get_is_authenticated (transport) &&
00423 _dbus_transport_get_is_connected (transport))
00424 {
00425 if (!exchange_credentials (transport, do_reading, do_writing))
00426 {
00427
00428 oom = TRUE;
00429 goto out;
00430 }
00431
00432 if (transport->send_credentials_pending ||
00433 transport->receive_credentials_pending)
00434 {
00435 _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
00436 transport->send_credentials_pending,
00437 transport->receive_credentials_pending);
00438 goto out;
00439 }
00440
00441 #define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client")
00442 switch (_dbus_auth_do_work (transport->auth))
00443 {
00444 case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
00445 _dbus_verbose (" %s auth state: waiting for input\n",
00446 TRANSPORT_SIDE (transport));
00447 if (!do_reading || !read_data_into_auth (transport, &oom))
00448 goto out;
00449 break;
00450
00451 case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
00452 _dbus_verbose (" %s auth state: waiting for memory\n",
00453 TRANSPORT_SIDE (transport));
00454 oom = TRUE;
00455 goto out;
00456 break;
00457
00458 case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
00459 _dbus_verbose (" %s auth state: bytes to send\n",
00460 TRANSPORT_SIDE (transport));
00461 if (!do_writing || !write_data_from_auth (transport))
00462 goto out;
00463 break;
00464
00465 case DBUS_AUTH_STATE_NEED_DISCONNECT:
00466 _dbus_verbose (" %s auth state: need to disconnect\n",
00467 TRANSPORT_SIDE (transport));
00468 do_io_error (transport);
00469 break;
00470
00471 case DBUS_AUTH_STATE_AUTHENTICATED:
00472 _dbus_verbose (" %s auth state: authenticated\n",
00473 TRANSPORT_SIDE (transport));
00474 break;
00475 }
00476 }
00477
00478 out:
00479 if (auth_completed)
00480 *auth_completed = (orig_auth_state != _dbus_transport_get_is_authenticated (transport));
00481
00482 check_read_watch (transport);
00483 check_write_watch (transport);
00484 _dbus_transport_unref (transport);
00485
00486 if (oom)
00487 return FALSE;
00488 else
00489 return TRUE;
00490 }
00491
00492
00493 static dbus_bool_t
00494 do_writing (DBusTransport *transport)
00495 {
00496 int total;
00497 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00498 dbus_bool_t oom;
00499
00500
00501 if (!_dbus_transport_get_is_authenticated (transport))
00502 {
00503 _dbus_verbose ("Not authenticated, not writing anything\n");
00504 return TRUE;
00505 }
00506
00507 if (transport->disconnected)
00508 {
00509 _dbus_verbose ("Not connected, not writing anything\n");
00510 return TRUE;
00511 }
00512
00513 #if 1
00514 _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n",
00515 _dbus_connection_has_messages_to_send_unlocked (transport->connection),
00516 socket_transport->fd);
00517 #endif
00518
00519 oom = FALSE;
00520 total = 0;
00521
00522 while (!transport->disconnected &&
00523 _dbus_connection_has_messages_to_send_unlocked (transport->connection))
00524 {
00525 int bytes_written;
00526 DBusMessage *message;
00527 const DBusString *header;
00528 const DBusString *body;
00529 int header_len, body_len;
00530 int total_bytes_to_write;
00531
00532 if (total > socket_transport->max_bytes_written_per_iteration)
00533 {
00534 _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
00535 total, socket_transport->max_bytes_written_per_iteration);
00536 goto out;
00537 }
00538
00539 message = _dbus_connection_get_message_to_send (transport->connection);
00540 _dbus_assert (message != NULL);
00541 _dbus_message_lock (message);
00542
00543 #if 0
00544 _dbus_verbose ("writing message %p\n", message);
00545 #endif
00546
00547 _dbus_message_get_network_data (message,
00548 &header, &body);
00549
00550 header_len = _dbus_string_get_length (header);
00551 body_len = _dbus_string_get_length (body);
00552
00553 if (_dbus_auth_needs_encoding (transport->auth))
00554 {
00555 if (_dbus_string_get_length (&socket_transport->encoded_outgoing) == 0)
00556 {
00557 if (!_dbus_auth_encode_data (transport->auth,
00558 header, &socket_transport->encoded_outgoing))
00559 {
00560 oom = TRUE;
00561 goto out;
00562 }
00563
00564 if (!_dbus_auth_encode_data (transport->auth,
00565 body, &socket_transport->encoded_outgoing))
00566 {
00567 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
00568 oom = TRUE;
00569 goto out;
00570 }
00571 }
00572
00573 total_bytes_to_write = _dbus_string_get_length (&socket_transport->encoded_outgoing);
00574
00575 #if 0
00576 _dbus_verbose ("encoded message is %d bytes\n",
00577 total_bytes_to_write);
00578 #endif
00579
00580 bytes_written =
00581 _dbus_write_socket (socket_transport->fd,
00582 &socket_transport->encoded_outgoing,
00583 socket_transport->message_bytes_written,
00584 total_bytes_to_write - socket_transport->message_bytes_written);
00585 }
00586 else
00587 {
00588 total_bytes_to_write = header_len + body_len;
00589
00590 #if 0
00591 _dbus_verbose ("message is %d bytes\n",
00592 total_bytes_to_write);
00593 #endif
00594
00595 if (socket_transport->message_bytes_written < header_len)
00596 {
00597 bytes_written =
00598 _dbus_write_socket_two (socket_transport->fd,
00599 header,
00600 socket_transport->message_bytes_written,
00601 header_len - socket_transport->message_bytes_written,
00602 body,
00603 0, body_len);
00604 }
00605 else
00606 {
00607 bytes_written =
00608 _dbus_write_socket (socket_transport->fd,
00609 body,
00610 (socket_transport->message_bytes_written - header_len),
00611 body_len -
00612 (socket_transport->message_bytes_written - header_len));
00613 }
00614 }
00615
00616 if (bytes_written < 0)
00617 {
00618
00619
00620 if (_dbus_get_is_errno_eagain_or_ewouldblock ())
00621 goto out;
00622 else
00623 {
00624 _dbus_verbose ("Error writing to remote app: %s\n",
00625 _dbus_strerror_from_errno ());
00626 do_io_error (transport);
00627 goto out;
00628 }
00629 }
00630 else
00631 {
00632 _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
00633 total_bytes_to_write);
00634
00635 total += bytes_written;
00636 socket_transport->message_bytes_written += bytes_written;
00637
00638 _dbus_assert (socket_transport->message_bytes_written <=
00639 total_bytes_to_write);
00640
00641 if (socket_transport->message_bytes_written == total_bytes_to_write)
00642 {
00643 socket_transport->message_bytes_written = 0;
00644 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
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 oom = TRUE;
00728 goto out;
00729 }
00730
00731 _dbus_message_loader_return_buffer (transport->loader,
00732 buffer,
00733 _dbus_string_get_length (buffer) - orig_len);
00734
00735 _dbus_string_set_length (&socket_transport->encoded_incoming, 0);
00736 }
00737 }
00738 else
00739 {
00740 _dbus_message_loader_get_buffer (transport->loader,
00741 &buffer);
00742
00743 bytes_read = _dbus_read_socket (socket_transport->fd,
00744 buffer, socket_transport->max_bytes_read_per_iteration);
00745
00746 _dbus_message_loader_return_buffer (transport->loader,
00747 buffer,
00748 bytes_read < 0 ? 0 : bytes_read);
00749 }
00750
00751 if (bytes_read < 0)
00752 {
00753
00754
00755 if (_dbus_get_is_errno_enomem ())
00756 {
00757 _dbus_verbose ("Out of memory in read()/do_reading()\n");
00758 oom = TRUE;
00759 goto out;
00760 }
00761 else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
00762 goto out;
00763 else
00764 {
00765 _dbus_verbose ("Error reading from remote app: %s\n",
00766 _dbus_strerror_from_errno ());
00767 do_io_error (transport);
00768 goto out;
00769 }
00770 }
00771 else if (bytes_read == 0)
00772 {
00773 _dbus_verbose ("Disconnected from remote app\n");
00774 do_io_error (transport);
00775 goto out;
00776 }
00777 else
00778 {
00779 _dbus_verbose (" read %d bytes\n", bytes_read);
00780
00781 total += bytes_read;
00782
00783 if (!_dbus_transport_queue_messages (transport))
00784 {
00785 oom = TRUE;
00786 _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
00787 goto out;
00788 }
00789
00790
00791
00792
00793
00794 goto again;
00795 }
00796
00797 out:
00798 if (oom)
00799 return FALSE;
00800 else
00801 return TRUE;
00802 }
00803
00804 static dbus_bool_t
00805 socket_handle_watch (DBusTransport *transport,
00806 DBusWatch *watch,
00807 unsigned int flags)
00808 {
00809 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00810
00811 _dbus_assert (watch == socket_transport->read_watch ||
00812 watch == socket_transport->write_watch);
00813 _dbus_assert (watch != NULL);
00814
00815
00816
00817
00818
00819
00820
00821 if ((flags & DBUS_WATCH_ERROR) ||
00822 ((flags & DBUS_WATCH_HANGUP) && !(flags & DBUS_WATCH_READABLE)))
00823 {
00824 _dbus_verbose ("Hang up or error on watch\n");
00825 _dbus_transport_disconnect (transport);
00826 return TRUE;
00827 }
00828
00829 if (watch == socket_transport->read_watch &&
00830 (flags & DBUS_WATCH_READABLE))
00831 {
00832 dbus_bool_t auth_finished;
00833 #if 1
00834 _dbus_verbose ("handling read watch %p flags = %x\n",
00835 watch, flags);
00836 #endif
00837 if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
00838 return FALSE;
00839
00840
00841
00842
00843
00844
00845
00846 if (!auth_finished)
00847 {
00848 if (!do_reading (transport))
00849 {
00850 _dbus_verbose ("no memory to read\n");
00851 return FALSE;
00852 }
00853 }
00854 else
00855 {
00856 _dbus_verbose ("Not reading anything since we just completed the authentication\n");
00857 }
00858 }
00859 else if (watch == socket_transport->write_watch &&
00860 (flags & DBUS_WATCH_WRITABLE))
00861 {
00862 #if 1
00863 _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
00864 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
00865 #endif
00866 if (!do_authentication (transport, FALSE, TRUE, NULL))
00867 return FALSE;
00868
00869 if (!do_writing (transport))
00870 {
00871 _dbus_verbose ("no memory to write\n");
00872 return FALSE;
00873 }
00874
00875
00876 check_write_watch (transport);
00877 }
00878 #ifdef DBUS_ENABLE_VERBOSE_MODE
00879 else
00880 {
00881 if (watch == socket_transport->read_watch)
00882 _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
00883 flags);
00884 else if (watch == socket_transport->write_watch)
00885 _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
00886 flags);
00887 else
00888 _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
00889 watch, dbus_watch_get_socket (watch));
00890 }
00891 #endif
00892
00893 return TRUE;
00894 }
00895
00896 static void
00897 socket_disconnect (DBusTransport *transport)
00898 {
00899 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00900
00901 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
00902
00903 free_watches (transport);
00904
00905 _dbus_close_socket (socket_transport->fd, NULL);
00906 socket_transport->fd = -1;
00907 }
00908
00909 static dbus_bool_t
00910 socket_connection_set (DBusTransport *transport)
00911 {
00912 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00913
00914 _dbus_watch_set_handler (socket_transport->write_watch,
00915 _dbus_connection_handle_watch,
00916 transport->connection, NULL);
00917
00918 _dbus_watch_set_handler (socket_transport->read_watch,
00919 _dbus_connection_handle_watch,
00920 transport->connection, NULL);
00921
00922 if (!_dbus_connection_add_watch_unlocked (transport->connection,
00923 socket_transport->write_watch))
00924 return FALSE;
00925
00926 if (!_dbus_connection_add_watch_unlocked (transport->connection,
00927 socket_transport->read_watch))
00928 {
00929 _dbus_connection_remove_watch_unlocked (transport->connection,
00930 socket_transport->write_watch);
00931 return FALSE;
00932 }
00933
00934 check_read_watch (transport);
00935 check_write_watch (transport);
00936
00937 return TRUE;
00938 }
00939
00947 static void
00948 socket_do_iteration (DBusTransport *transport,
00949 unsigned int flags,
00950 int timeout_milliseconds)
00951 {
00952 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00953 DBusPollFD poll_fd;
00954 int poll_res;
00955 int poll_timeout;
00956
00957 _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
00958 flags & DBUS_ITERATION_DO_READING ? "read" : "",
00959 flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
00960 timeout_milliseconds,
00961 socket_transport->read_watch,
00962 socket_transport->write_watch,
00963 socket_transport->fd);
00964
00965
00966
00967
00968
00969
00970
00971 poll_fd.fd = socket_transport->fd;
00972 poll_fd.events = 0;
00973
00974 if (_dbus_transport_get_is_authenticated (transport))
00975 {
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986 if ((flags & DBUS_ITERATION_DO_WRITING) &&
00987 !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
00988 !transport->disconnected &&
00989 _dbus_connection_has_messages_to_send_unlocked (transport->connection))
00990 {
00991 do_writing (transport);
00992
00993 if (transport->disconnected ||
00994 !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
00995 goto out;
00996 }
00997
00998
00999 _dbus_assert (socket_transport->read_watch);
01000 if (flags & DBUS_ITERATION_DO_READING)
01001 poll_fd.events |= _DBUS_POLLIN;
01002
01003 _dbus_assert (socket_transport->write_watch);
01004 if (flags & DBUS_ITERATION_DO_WRITING)
01005 poll_fd.events |= _DBUS_POLLOUT;
01006 }
01007 else
01008 {
01009 DBusAuthState auth_state;
01010
01011 auth_state = _dbus_auth_do_work (transport->auth);
01012
01013 if (transport->receive_credentials_pending ||
01014 auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
01015 poll_fd.events |= _DBUS_POLLIN;
01016
01017 if (transport->send_credentials_pending ||
01018 auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
01019 poll_fd.events |= _DBUS_POLLOUT;
01020 }
01021
01022 if (poll_fd.events)
01023 {
01024 if (flags & DBUS_ITERATION_BLOCK)
01025 poll_timeout = timeout_milliseconds;
01026 else
01027 poll_timeout = 0;
01028
01029
01030
01031
01032
01033
01034 if (flags & DBUS_ITERATION_BLOCK)
01035 {
01036 _dbus_verbose ("unlock %s pre poll\n", _DBUS_FUNCTION_NAME);
01037 _dbus_connection_unlock (transport->connection);
01038 }
01039
01040 again:
01041 poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
01042
01043 if (poll_res < 0 && _dbus_get_is_errno_eintr ())
01044 goto again;
01045
01046 if (flags & DBUS_ITERATION_BLOCK)
01047 {
01048 _dbus_verbose ("lock %s post poll\n", _DBUS_FUNCTION_NAME);
01049 _dbus_connection_lock (transport->connection);
01050 }
01051
01052 if (poll_res >= 0)
01053 {
01054 if (poll_res == 0)
01055 poll_fd.revents = 0;
01056
01057
01058
01059
01060 if (poll_fd.revents & _DBUS_POLLERR)
01061 do_io_error (transport);
01062 else
01063 {
01064 dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
01065 dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
01066 dbus_bool_t authentication_completed;
01067
01068 _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
01069 need_read, need_write);
01070 do_authentication (transport, need_read, need_write,
01071 &authentication_completed);
01072
01073
01074 if (authentication_completed)
01075 goto out;
01076
01077 if (need_read && (flags & DBUS_ITERATION_DO_READING))
01078 do_reading (transport);
01079 if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
01080 do_writing (transport);
01081 }
01082 }
01083 else
01084 {
01085 _dbus_verbose ("Error from _dbus_poll(): %s\n",
01086 _dbus_strerror_from_errno ());
01087 }
01088 }
01089
01090
01091 out:
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102 check_write_watch (transport);
01103
01104 _dbus_verbose (" ... leaving do_iteration()\n");
01105 }
01106
01107 static void
01108 socket_live_messages_changed (DBusTransport *transport)
01109 {
01110
01111 check_read_watch (transport);
01112 }
01113
01114
01115 static dbus_bool_t
01116 socket_get_socket_fd (DBusTransport *transport,
01117 int *fd_p)
01118 {
01119 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
01120
01121 *fd_p = socket_transport->fd;
01122
01123 return TRUE;
01124 }
01125
01126 static const DBusTransportVTable socket_vtable = {
01127 socket_finalize,
01128 socket_handle_watch,
01129 socket_disconnect,
01130 socket_connection_set,
01131 socket_do_iteration,
01132 socket_live_messages_changed,
01133 socket_get_socket_fd
01134 };
01135
01147 DBusTransport*
01148 _dbus_transport_new_for_socket (int fd,
01149 const DBusString *server_guid,
01150 const DBusString *address)
01151 {
01152 DBusTransportSocket *socket_transport;
01153
01154 socket_transport = dbus_new0 (DBusTransportSocket, 1);
01155 if (socket_transport == NULL)
01156 return NULL;
01157
01158 if (!_dbus_string_init (&socket_transport->encoded_outgoing))
01159 goto failed_0;
01160
01161 if (!_dbus_string_init (&socket_transport->encoded_incoming))
01162 goto failed_1;
01163
01164 socket_transport->write_watch = _dbus_watch_new (fd,
01165 DBUS_WATCH_WRITABLE,
01166 FALSE,
01167 NULL, NULL, NULL);
01168 if (socket_transport->write_watch == NULL)
01169 goto failed_2;
01170
01171 socket_transport->read_watch = _dbus_watch_new (fd,
01172 DBUS_WATCH_READABLE,
01173 FALSE,
01174 NULL, NULL, NULL);
01175 if (socket_transport->read_watch == NULL)
01176 goto failed_3;
01177
01178 if (!_dbus_transport_init_base (&socket_transport->base,
01179 &socket_vtable,
01180 server_guid, address))
01181 goto failed_4;
01182
01183 socket_transport->fd = fd;
01184 socket_transport->message_bytes_written = 0;
01185
01186
01187 socket_transport->max_bytes_read_per_iteration = 2048;
01188 socket_transport->max_bytes_written_per_iteration = 2048;
01189
01190 return (DBusTransport*) socket_transport;
01191
01192 failed_4:
01193 _dbus_watch_unref (socket_transport->read_watch);
01194 failed_3:
01195 _dbus_watch_unref (socket_transport->write_watch);
01196 failed_2:
01197 _dbus_string_free (&socket_transport->encoded_incoming);
01198 failed_1:
01199 _dbus_string_free (&socket_transport->encoded_outgoing);
01200 failed_0:
01201 dbus_free (socket_transport);
01202 return NULL;
01203 }
01204
01215 DBusTransport*
01216 _dbus_transport_new_for_tcp_socket (const char *host,
01217 const char *port,
01218 const char *family,
01219 DBusError *error)
01220 {
01221 int fd;
01222 DBusTransport *transport;
01223 DBusString address;
01224
01225 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01226
01227 if (!_dbus_string_init (&address))
01228 {
01229 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01230 return NULL;
01231 }
01232
01233 if (host == NULL)
01234 host = "localhost";
01235
01236 if (!_dbus_string_append (&address, "tcp:"))
01237 goto error;
01238
01239 if (!_dbus_string_append (&address, "host=") ||
01240 !_dbus_string_append (&address, host))
01241 goto error;
01242
01243 if (!_dbus_string_append (&address, ",port=") ||
01244 !_dbus_string_append (&address, port))
01245 goto error;
01246
01247 if (family != NULL &&
01248 (!_dbus_string_append (&address, "family=") ||
01249 !_dbus_string_append (&address, family)))
01250 goto error;
01251
01252 fd = _dbus_connect_tcp_socket (host, port, family, error);
01253 if (fd < 0)
01254 {
01255 _DBUS_ASSERT_ERROR_IS_SET (error);
01256 _dbus_string_free (&address);
01257 return NULL;
01258 }
01259
01260 _dbus_fd_set_close_on_exec (fd);
01261
01262 _dbus_verbose ("Successfully connected to tcp socket %s:%s\n",
01263 host, port);
01264
01265 transport = _dbus_transport_new_for_socket (fd, NULL, &address);
01266 if (transport == NULL)
01267 {
01268 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01269 _dbus_close_socket (fd, NULL);
01270 _dbus_string_free (&address);
01271 fd = -1;
01272 }
01273
01274 _dbus_string_free (&address);
01275
01276 return transport;
01277
01278 error:
01279 _dbus_string_free (&address);
01280 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01281 return NULL;
01282 }
01283
01292 DBusTransportOpenResult
01293 _dbus_transport_open_socket(DBusAddressEntry *entry,
01294 DBusTransport **transport_p,
01295 DBusError *error)
01296 {
01297 const char *method;
01298
01299 method = dbus_address_entry_get_method (entry);
01300 _dbus_assert (method != NULL);
01301
01302 if (strcmp (method, "tcp") == 0)
01303 {
01304 const char *host = dbus_address_entry_get_value (entry, "host");
01305 const char *port = dbus_address_entry_get_value (entry, "port");
01306 const char *family = dbus_address_entry_get_value (entry, "family");
01307
01308 if (port == NULL)
01309 {
01310 _dbus_set_bad_address (error, "tcp", "port", NULL);
01311 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
01312 }
01313
01314 *transport_p = _dbus_transport_new_for_tcp_socket (host, port, family, error);
01315 if (*transport_p == NULL)
01316 {
01317 _DBUS_ASSERT_ERROR_IS_SET (error);
01318 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
01319 }
01320 else
01321 {
01322 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01323 return DBUS_TRANSPORT_OPEN_OK;
01324 }
01325 }
01326 else
01327 {
01328 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01329 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
01330 }
01331 }
01332