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 if (flags & DBUS_WATCH_ERROR)
00820 return TRUE;
00821
00822 if ((flags & DBUS_WATCH_HANGUP) && !(flags & DBUS_WATCH_READABLE))
00823 {
00824
00825
00826 if (watch != transport->read_watch &&
00827 _dbus_watch_get_enabled (transport->read_watch))
00828 return FALSE;
00829
00830 return TRUE;
00831 }
00832 return FALSE;
00833 }
00834
00835 static dbus_bool_t
00836 socket_handle_watch (DBusTransport *transport,
00837 DBusWatch *watch,
00838 unsigned int flags)
00839 {
00840 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00841
00842 _dbus_assert (watch == socket_transport->read_watch ||
00843 watch == socket_transport->write_watch);
00844 _dbus_assert (watch != NULL);
00845
00846
00847
00848
00849
00850
00851
00852 if (unix_error_with_read_to_come (transport, watch, flags))
00853 {
00854 _dbus_verbose ("Hang up or error on watch\n");
00855 _dbus_transport_disconnect (transport);
00856 return TRUE;
00857 }
00858
00859 if (watch == socket_transport->read_watch &&
00860 (flags & DBUS_WATCH_READABLE))
00861 {
00862 dbus_bool_t auth_finished;
00863 #if 1
00864 _dbus_verbose ("handling read watch %p flags = %x\n",
00865 watch, flags);
00866 #endif
00867 if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
00868 return FALSE;
00869
00870
00871
00872
00873
00874
00875
00876 if (!auth_finished)
00877 {
00878 if (!do_reading (transport))
00879 {
00880 _dbus_verbose ("no memory to read\n");
00881 return FALSE;
00882 }
00883 }
00884 else
00885 {
00886 _dbus_verbose ("Not reading anything since we just completed the authentication\n");
00887 }
00888 }
00889 else if (watch == socket_transport->write_watch &&
00890 (flags & DBUS_WATCH_WRITABLE))
00891 {
00892 #if 1
00893 _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
00894 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
00895 #endif
00896 if (!do_authentication (transport, FALSE, TRUE, NULL))
00897 return FALSE;
00898
00899 if (!do_writing (transport))
00900 {
00901 _dbus_verbose ("no memory to write\n");
00902 return FALSE;
00903 }
00904
00905
00906 check_write_watch (transport);
00907 }
00908 #ifdef DBUS_ENABLE_VERBOSE_MODE
00909 else
00910 {
00911 if (watch == socket_transport->read_watch)
00912 _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
00913 flags);
00914 else if (watch == socket_transport->write_watch)
00915 _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
00916 flags);
00917 else
00918 _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
00919 watch, dbus_watch_get_socket (watch));
00920 }
00921 #endif
00922
00923 return TRUE;
00924 }
00925
00926 static void
00927 socket_disconnect (DBusTransport *transport)
00928 {
00929 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00930
00931 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
00932
00933 free_watches (transport);
00934
00935 _dbus_close_socket (socket_transport->fd, NULL);
00936 socket_transport->fd = -1;
00937 }
00938
00939 static dbus_bool_t
00940 socket_connection_set (DBusTransport *transport)
00941 {
00942 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00943
00944 _dbus_watch_set_handler (socket_transport->write_watch,
00945 _dbus_connection_handle_watch,
00946 transport->connection, NULL);
00947
00948 _dbus_watch_set_handler (socket_transport->read_watch,
00949 _dbus_connection_handle_watch,
00950 transport->connection, NULL);
00951
00952 if (!_dbus_connection_add_watch_unlocked (transport->connection,
00953 socket_transport->write_watch))
00954 return FALSE;
00955
00956 if (!_dbus_connection_add_watch_unlocked (transport->connection,
00957 socket_transport->read_watch))
00958 {
00959 _dbus_connection_remove_watch_unlocked (transport->connection,
00960 socket_transport->write_watch);
00961 return FALSE;
00962 }
00963
00964 check_read_watch (transport);
00965 check_write_watch (transport);
00966
00967 return TRUE;
00968 }
00969
00977 static void
00978 socket_do_iteration (DBusTransport *transport,
00979 unsigned int flags,
00980 int timeout_milliseconds)
00981 {
00982 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00983 DBusPollFD poll_fd;
00984 int poll_res;
00985 int poll_timeout;
00986
00987 _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
00988 flags & DBUS_ITERATION_DO_READING ? "read" : "",
00989 flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
00990 timeout_milliseconds,
00991 socket_transport->read_watch,
00992 socket_transport->write_watch,
00993 socket_transport->fd);
00994
00995
00996
00997
00998
00999
01000
01001 poll_fd.fd = socket_transport->fd;
01002 poll_fd.events = 0;
01003
01004 if (_dbus_transport_get_is_authenticated (transport))
01005 {
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016 if ((flags & DBUS_ITERATION_DO_WRITING) &&
01017 !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
01018 !transport->disconnected &&
01019 _dbus_connection_has_messages_to_send_unlocked (transport->connection))
01020 {
01021 do_writing (transport);
01022
01023 if (transport->disconnected ||
01024 !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
01025 goto out;
01026 }
01027
01028
01029 _dbus_assert (socket_transport->read_watch);
01030 if (flags & DBUS_ITERATION_DO_READING)
01031 poll_fd.events |= _DBUS_POLLIN;
01032
01033 _dbus_assert (socket_transport->write_watch);
01034 if (flags & DBUS_ITERATION_DO_WRITING)
01035 poll_fd.events |= _DBUS_POLLOUT;
01036 }
01037 else
01038 {
01039 DBusAuthState auth_state;
01040
01041 auth_state = _dbus_auth_do_work (transport->auth);
01042
01043 if (transport->receive_credentials_pending ||
01044 auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
01045 poll_fd.events |= _DBUS_POLLIN;
01046
01047 if (transport->send_credentials_pending ||
01048 auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
01049 poll_fd.events |= _DBUS_POLLOUT;
01050 }
01051
01052 if (poll_fd.events)
01053 {
01054 if (flags & DBUS_ITERATION_BLOCK)
01055 poll_timeout = timeout_milliseconds;
01056 else
01057 poll_timeout = 0;
01058
01059
01060
01061
01062
01063
01064 if (flags & DBUS_ITERATION_BLOCK)
01065 {
01066 _dbus_verbose ("unlock %s pre poll\n", _DBUS_FUNCTION_NAME);
01067 _dbus_connection_unlock (transport->connection);
01068 }
01069
01070 again:
01071 poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
01072
01073 if (poll_res < 0 && _dbus_get_is_errno_eintr ())
01074 goto again;
01075
01076 if (flags & DBUS_ITERATION_BLOCK)
01077 {
01078 _dbus_verbose ("lock %s post poll\n", _DBUS_FUNCTION_NAME);
01079 _dbus_connection_lock (transport->connection);
01080 }
01081
01082 if (poll_res >= 0)
01083 {
01084 if (poll_res == 0)
01085 poll_fd.revents = 0;
01086
01087
01088
01089
01090 if (poll_fd.revents & _DBUS_POLLERR)
01091 do_io_error (transport);
01092 else
01093 {
01094 dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
01095 dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
01096 dbus_bool_t authentication_completed;
01097
01098 _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
01099 need_read, need_write);
01100 do_authentication (transport, need_read, need_write,
01101 &authentication_completed);
01102
01103
01104 if (authentication_completed)
01105 goto out;
01106
01107 if (need_read && (flags & DBUS_ITERATION_DO_READING))
01108 do_reading (transport);
01109 if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
01110 do_writing (transport);
01111 }
01112 }
01113 else
01114 {
01115 _dbus_verbose ("Error from _dbus_poll(): %s\n",
01116 _dbus_strerror_from_errno ());
01117 }
01118 }
01119
01120
01121 out:
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132 check_write_watch (transport);
01133
01134 _dbus_verbose (" ... leaving do_iteration()\n");
01135 }
01136
01137 static void
01138 socket_live_messages_changed (DBusTransport *transport)
01139 {
01140
01141 check_read_watch (transport);
01142 }
01143
01144
01145 static dbus_bool_t
01146 socket_get_socket_fd (DBusTransport *transport,
01147 int *fd_p)
01148 {
01149 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
01150
01151 *fd_p = socket_transport->fd;
01152
01153 return TRUE;
01154 }
01155
01156 static const DBusTransportVTable socket_vtable = {
01157 socket_finalize,
01158 socket_handle_watch,
01159 socket_disconnect,
01160 socket_connection_set,
01161 socket_do_iteration,
01162 socket_live_messages_changed,
01163 socket_get_socket_fd
01164 };
01165
01177 DBusTransport*
01178 _dbus_transport_new_for_socket (int fd,
01179 const DBusString *server_guid,
01180 const DBusString *address)
01181 {
01182 DBusTransportSocket *socket_transport;
01183
01184 socket_transport = dbus_new0 (DBusTransportSocket, 1);
01185 if (socket_transport == NULL)
01186 return NULL;
01187
01188 if (!_dbus_string_init (&socket_transport->encoded_outgoing))
01189 goto failed_0;
01190
01191 if (!_dbus_string_init (&socket_transport->encoded_incoming))
01192 goto failed_1;
01193
01194 socket_transport->write_watch = _dbus_watch_new (fd,
01195 DBUS_WATCH_WRITABLE,
01196 FALSE,
01197 NULL, NULL, NULL);
01198 if (socket_transport->write_watch == NULL)
01199 goto failed_2;
01200
01201 socket_transport->read_watch = _dbus_watch_new (fd,
01202 DBUS_WATCH_READABLE,
01203 FALSE,
01204 NULL, NULL, NULL);
01205 if (socket_transport->read_watch == NULL)
01206 goto failed_3;
01207
01208 if (!_dbus_transport_init_base (&socket_transport->base,
01209 &socket_vtable,
01210 server_guid, address))
01211 goto failed_4;
01212
01213 socket_transport->fd = fd;
01214 socket_transport->message_bytes_written = 0;
01215
01216
01217 socket_transport->max_bytes_read_per_iteration = 2048;
01218 socket_transport->max_bytes_written_per_iteration = 2048;
01219
01220 return (DBusTransport*) socket_transport;
01221
01222 failed_4:
01223 _dbus_watch_unref (socket_transport->read_watch);
01224 failed_3:
01225 _dbus_watch_unref (socket_transport->write_watch);
01226 failed_2:
01227 _dbus_string_free (&socket_transport->encoded_incoming);
01228 failed_1:
01229 _dbus_string_free (&socket_transport->encoded_outgoing);
01230 failed_0:
01231 dbus_free (socket_transport);
01232 return NULL;
01233 }
01234
01245 DBusTransport*
01246 _dbus_transport_new_for_tcp_socket (const char *host,
01247 const char *port,
01248 const char *family,
01249 DBusError *error)
01250 {
01251 int fd;
01252 DBusTransport *transport;
01253 DBusString address;
01254
01255 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01256
01257 if (!_dbus_string_init (&address))
01258 {
01259 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01260 return NULL;
01261 }
01262
01263 if (host == NULL)
01264 host = "localhost";
01265
01266 if (!_dbus_string_append (&address, "tcp:"))
01267 goto error;
01268
01269 if (!_dbus_string_append (&address, "host=") ||
01270 !_dbus_string_append (&address, host))
01271 goto error;
01272
01273 if (!_dbus_string_append (&address, ",port=") ||
01274 !_dbus_string_append (&address, port))
01275 goto error;
01276
01277 if (family != NULL &&
01278 (!_dbus_string_append (&address, "family=") ||
01279 !_dbus_string_append (&address, family)))
01280 goto error;
01281
01282 fd = _dbus_connect_tcp_socket (host, port, family, error);
01283 if (fd < 0)
01284 {
01285 _DBUS_ASSERT_ERROR_IS_SET (error);
01286 _dbus_string_free (&address);
01287 return NULL;
01288 }
01289
01290 _dbus_fd_set_close_on_exec (fd);
01291
01292 _dbus_verbose ("Successfully connected to tcp socket %s:%s\n",
01293 host, port);
01294
01295 transport = _dbus_transport_new_for_socket (fd, NULL, &address);
01296 if (transport == NULL)
01297 {
01298 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01299 _dbus_close_socket (fd, NULL);
01300 _dbus_string_free (&address);
01301 fd = -1;
01302 }
01303
01304 _dbus_string_free (&address);
01305
01306 return transport;
01307
01308 error:
01309 _dbus_string_free (&address);
01310 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01311 return NULL;
01312 }
01313
01322 DBusTransportOpenResult
01323 _dbus_transport_open_socket(DBusAddressEntry *entry,
01324 DBusTransport **transport_p,
01325 DBusError *error)
01326 {
01327 const char *method;
01328
01329 method = dbus_address_entry_get_method (entry);
01330 _dbus_assert (method != NULL);
01331
01332 if (strcmp (method, "tcp") == 0)
01333 {
01334 const char *host = dbus_address_entry_get_value (entry, "host");
01335 const char *port = dbus_address_entry_get_value (entry, "port");
01336 const char *family = dbus_address_entry_get_value (entry, "family");
01337
01338 if (port == NULL)
01339 {
01340 _dbus_set_bad_address (error, "tcp", "port", NULL);
01341 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
01342 }
01343
01344 *transport_p = _dbus_transport_new_for_tcp_socket (host, port, family, error);
01345 if (*transport_p == NULL)
01346 {
01347 _DBUS_ASSERT_ERROR_IS_SET (error);
01348 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
01349 }
01350 else
01351 {
01352 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01353 return DBUS_TRANSPORT_OPEN_OK;
01354 }
01355 }
01356 else
01357 {
01358 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01359 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
01360 }
01361 }
01362