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
00030
00042 typedef struct DBusTransportSocket DBusTransportSocket;
00043
00047 struct DBusTransportSocket
00048 {
00049 DBusTransport base;
00050 int fd;
00051 DBusWatch *read_watch;
00052 DBusWatch *write_watch;
00054 int max_bytes_read_per_iteration;
00055 int max_bytes_written_per_iteration;
00057 int message_bytes_written;
00061 DBusString encoded_outgoing;
00064 DBusString encoded_incoming;
00067 };
00068
00069 static void
00070 free_watches (DBusTransport *transport)
00071 {
00072 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00073
00074 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
00075
00076 if (socket_transport->read_watch)
00077 {
00078 if (transport->connection)
00079 _dbus_connection_remove_watch_unlocked (transport->connection,
00080 socket_transport->read_watch);
00081 _dbus_watch_invalidate (socket_transport->read_watch);
00082 _dbus_watch_unref (socket_transport->read_watch);
00083 socket_transport->read_watch = NULL;
00084 }
00085
00086 if (socket_transport->write_watch)
00087 {
00088 if (transport->connection)
00089 _dbus_connection_remove_watch_unlocked (transport->connection,
00090 socket_transport->write_watch);
00091 _dbus_watch_invalidate (socket_transport->write_watch);
00092 _dbus_watch_unref (socket_transport->write_watch);
00093 socket_transport->write_watch = NULL;
00094 }
00095
00096 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
00097 }
00098
00099 static void
00100 socket_finalize (DBusTransport *transport)
00101 {
00102 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00103
00104 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
00105
00106 free_watches (transport);
00107
00108 _dbus_string_free (&socket_transport->encoded_outgoing);
00109 _dbus_string_free (&socket_transport->encoded_incoming);
00110
00111 _dbus_transport_finalize_base (transport);
00112
00113 _dbus_assert (socket_transport->read_watch == NULL);
00114 _dbus_assert (socket_transport->write_watch == NULL);
00115
00116 dbus_free (transport);
00117 }
00118
00119 static void
00120 check_write_watch (DBusTransport *transport)
00121 {
00122 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00123 dbus_bool_t needed;
00124
00125 if (transport->connection == NULL)
00126 return;
00127
00128 if (transport->disconnected)
00129 {
00130 _dbus_assert (socket_transport->write_watch == NULL);
00131 return;
00132 }
00133
00134 _dbus_transport_ref (transport);
00135
00136 if (_dbus_transport_get_is_authenticated (transport))
00137 needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
00138 else
00139 {
00140 if (transport->send_credentials_pending)
00141 needed = TRUE;
00142 else
00143 {
00144 DBusAuthState auth_state;
00145
00146 auth_state = _dbus_auth_do_work (transport->auth);
00147
00148
00149
00150
00151
00152 if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND ||
00153 auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
00154 needed = TRUE;
00155 else
00156 needed = FALSE;
00157 }
00158 }
00159
00160 _dbus_verbose ("check_write_watch(): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
00161 needed, transport->connection, socket_transport->write_watch,
00162 socket_transport->fd,
00163 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
00164
00165 _dbus_connection_toggle_watch_unlocked (transport->connection,
00166 socket_transport->write_watch,
00167 needed);
00168
00169 _dbus_transport_unref (transport);
00170 }
00171
00172 static void
00173 check_read_watch (DBusTransport *transport)
00174 {
00175 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00176 dbus_bool_t need_read_watch;
00177
00178 _dbus_verbose ("%s: fd = %d\n",
00179 _DBUS_FUNCTION_NAME, socket_transport->fd);
00180
00181 if (transport->connection == NULL)
00182 return;
00183
00184 if (transport->disconnected)
00185 {
00186 _dbus_assert (socket_transport->read_watch == NULL);
00187 return;
00188 }
00189
00190 _dbus_transport_ref (transport);
00191
00192 if (_dbus_transport_get_is_authenticated (transport))
00193 need_read_watch =
00194 _dbus_counter_get_value (transport->live_messages_size) < transport->max_live_messages_size;
00195 else
00196 {
00197 if (transport->receive_credentials_pending)
00198 need_read_watch = TRUE;
00199 else
00200 {
00201
00202
00203
00204
00205 DBusAuthState auth_state;
00206
00207 auth_state = _dbus_auth_do_work (transport->auth);
00208
00209
00210
00211
00212
00213
00214
00215 if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT ||
00216 auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY ||
00217 auth_state == DBUS_AUTH_STATE_AUTHENTICATED)
00218 need_read_watch = TRUE;
00219 else
00220 need_read_watch = FALSE;
00221 }
00222 }
00223
00224 _dbus_verbose (" setting read watch enabled = %d\n", need_read_watch);
00225 _dbus_connection_toggle_watch_unlocked (transport->connection,
00226 socket_transport->read_watch,
00227 need_read_watch);
00228
00229 _dbus_transport_unref (transport);
00230 }
00231
00232 static void
00233 do_io_error (DBusTransport *transport)
00234 {
00235 _dbus_transport_ref (transport);
00236 _dbus_transport_disconnect (transport);
00237 _dbus_transport_unref (transport);
00238 }
00239
00240
00241 static dbus_bool_t
00242 read_data_into_auth (DBusTransport *transport,
00243 dbus_bool_t *oom)
00244 {
00245 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00246 DBusString *buffer;
00247 int bytes_read;
00248
00249 *oom = FALSE;
00250
00251 _dbus_auth_get_buffer (transport->auth, &buffer);
00252
00253 bytes_read = _dbus_read_socket (socket_transport->fd,
00254 buffer, socket_transport->max_bytes_read_per_iteration);
00255
00256 _dbus_auth_return_buffer (transport->auth, buffer,
00257 bytes_read > 0 ? bytes_read : 0);
00258
00259 if (bytes_read > 0)
00260 {
00261 _dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
00262
00263 return TRUE;
00264 }
00265 else if (bytes_read < 0)
00266 {
00267
00268
00269 if (errno == ENOMEM)
00270 {
00271 *oom = TRUE;
00272 }
00273 else if (errno == EAGAIN ||
00274 errno == EWOULDBLOCK)
00275 ;
00276 else
00277 {
00278 _dbus_verbose ("Error reading from remote app: %s\n",
00279 _dbus_strerror (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 (errno == EAGAIN ||
00322 errno == EWOULDBLOCK)
00323 ;
00324 else
00325 {
00326 _dbus_verbose ("Error writing to remote app: %s\n",
00327 _dbus_strerror (errno));
00328 do_io_error (transport);
00329 }
00330 }
00331
00332 return FALSE;
00333 }
00334
00335 static void
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_unix_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 if (_dbus_read_credentials_unix_socket (socket_transport->fd,
00365 &transport->credentials,
00366 &error))
00367 {
00368 transport->receive_credentials_pending = FALSE;
00369 }
00370 else
00371 {
00372 _dbus_verbose ("Failed to read credentials %s\n", error.message);
00373 dbus_error_free (&error);
00374 do_io_error (transport);
00375 }
00376 }
00377
00378 if (!(transport->send_credentials_pending ||
00379 transport->receive_credentials_pending))
00380 {
00381 _dbus_auth_set_credentials (transport->auth,
00382 &transport->credentials);
00383 }
00384 }
00385
00386 static dbus_bool_t
00387 do_authentication (DBusTransport *transport,
00388 dbus_bool_t do_reading,
00389 dbus_bool_t do_writing,
00390 dbus_bool_t *auth_completed)
00391 {
00392 dbus_bool_t oom;
00393 dbus_bool_t orig_auth_state;
00394
00395 oom = FALSE;
00396
00397 orig_auth_state = _dbus_transport_get_is_authenticated (transport);
00398
00399
00400
00401
00402
00403 if (orig_auth_state)
00404 {
00405 if (auth_completed)
00406 *auth_completed = FALSE;
00407 return TRUE;
00408 }
00409
00410 _dbus_transport_ref (transport);
00411
00412 while (!_dbus_transport_get_is_authenticated (transport) &&
00413 _dbus_transport_get_is_connected (transport))
00414 {
00415 exchange_credentials (transport, do_reading, do_writing);
00416
00417 if (transport->send_credentials_pending ||
00418 transport->receive_credentials_pending)
00419 {
00420 _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
00421 transport->send_credentials_pending,
00422 transport->receive_credentials_pending);
00423 goto out;
00424 }
00425
00426 #define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client")
00427 switch (_dbus_auth_do_work (transport->auth))
00428 {
00429 case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
00430 _dbus_verbose (" %s auth state: waiting for input\n",
00431 TRANSPORT_SIDE (transport));
00432 if (!do_reading || !read_data_into_auth (transport, &oom))
00433 goto out;
00434 break;
00435
00436 case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
00437 _dbus_verbose (" %s auth state: waiting for memory\n",
00438 TRANSPORT_SIDE (transport));
00439 oom = TRUE;
00440 goto out;
00441 break;
00442
00443 case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
00444 _dbus_verbose (" %s auth state: bytes to send\n",
00445 TRANSPORT_SIDE (transport));
00446 if (!do_writing || !write_data_from_auth (transport))
00447 goto out;
00448 break;
00449
00450 case DBUS_AUTH_STATE_NEED_DISCONNECT:
00451 _dbus_verbose (" %s auth state: need to disconnect\n",
00452 TRANSPORT_SIDE (transport));
00453 do_io_error (transport);
00454 break;
00455
00456 case DBUS_AUTH_STATE_AUTHENTICATED:
00457 _dbus_verbose (" %s auth state: authenticated\n",
00458 TRANSPORT_SIDE (transport));
00459 break;
00460 }
00461 }
00462
00463 out:
00464 if (auth_completed)
00465 *auth_completed = (orig_auth_state != _dbus_transport_get_is_authenticated (transport));
00466
00467 check_read_watch (transport);
00468 check_write_watch (transport);
00469 _dbus_transport_unref (transport);
00470
00471 if (oom)
00472 return FALSE;
00473 else
00474 return TRUE;
00475 }
00476
00477
00478 static dbus_bool_t
00479 do_writing (DBusTransport *transport)
00480 {
00481 int total;
00482 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00483 dbus_bool_t oom;
00484
00485
00486 if (!_dbus_transport_get_is_authenticated (transport))
00487 {
00488 _dbus_verbose ("Not authenticated, not writing anything\n");
00489 return TRUE;
00490 }
00491
00492 if (transport->disconnected)
00493 {
00494 _dbus_verbose ("Not connected, not writing anything\n");
00495 return TRUE;
00496 }
00497
00498 #if 1
00499 _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n",
00500 _dbus_connection_has_messages_to_send_unlocked (transport->connection),
00501 socket_transport->fd);
00502 #endif
00503
00504 oom = FALSE;
00505 total = 0;
00506
00507 while (!transport->disconnected &&
00508 _dbus_connection_has_messages_to_send_unlocked (transport->connection))
00509 {
00510 int bytes_written;
00511 DBusMessage *message;
00512 const DBusString *header;
00513 const DBusString *body;
00514 int header_len, body_len;
00515 int total_bytes_to_write;
00516
00517 if (total > socket_transport->max_bytes_written_per_iteration)
00518 {
00519 _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
00520 total, socket_transport->max_bytes_written_per_iteration);
00521 goto out;
00522 }
00523
00524 message = _dbus_connection_get_message_to_send (transport->connection);
00525 _dbus_assert (message != NULL);
00526 _dbus_message_lock (message);
00527
00528 #if 0
00529 _dbus_verbose ("writing message %p\n", message);
00530 #endif
00531
00532 _dbus_message_get_network_data (message,
00533 &header, &body);
00534
00535 header_len = _dbus_string_get_length (header);
00536 body_len = _dbus_string_get_length (body);
00537
00538 if (_dbus_auth_needs_encoding (transport->auth))
00539 {
00540 if (_dbus_string_get_length (&socket_transport->encoded_outgoing) == 0)
00541 {
00542 if (!_dbus_auth_encode_data (transport->auth,
00543 header, &socket_transport->encoded_outgoing))
00544 {
00545 oom = TRUE;
00546 goto out;
00547 }
00548
00549 if (!_dbus_auth_encode_data (transport->auth,
00550 body, &socket_transport->encoded_outgoing))
00551 {
00552 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
00553 oom = TRUE;
00554 goto out;
00555 }
00556 }
00557
00558 total_bytes_to_write = _dbus_string_get_length (&socket_transport->encoded_outgoing);
00559
00560 #if 0
00561 _dbus_verbose ("encoded message is %d bytes\n",
00562 total_bytes_to_write);
00563 #endif
00564
00565 bytes_written =
00566 _dbus_write_socket (socket_transport->fd,
00567 &socket_transport->encoded_outgoing,
00568 socket_transport->message_bytes_written,
00569 total_bytes_to_write - socket_transport->message_bytes_written);
00570 }
00571 else
00572 {
00573 total_bytes_to_write = header_len + body_len;
00574
00575 #if 0
00576 _dbus_verbose ("message is %d bytes\n",
00577 total_bytes_to_write);
00578 #endif
00579
00580 if (socket_transport->message_bytes_written < header_len)
00581 {
00582 bytes_written =
00583 _dbus_write_socket_two (socket_transport->fd,
00584 header,
00585 socket_transport->message_bytes_written,
00586 header_len - socket_transport->message_bytes_written,
00587 body,
00588 0, body_len);
00589 }
00590 else
00591 {
00592 bytes_written =
00593 _dbus_write_socket (socket_transport->fd,
00594 body,
00595 (socket_transport->message_bytes_written - header_len),
00596 body_len -
00597 (socket_transport->message_bytes_written - header_len));
00598 }
00599 }
00600
00601 if (bytes_written < 0)
00602 {
00603
00604
00605 if (errno == EAGAIN ||
00606 errno == EWOULDBLOCK)
00607 goto out;
00608 else
00609 {
00610 _dbus_verbose ("Error writing to remote app: %s\n",
00611 _dbus_strerror (errno));
00612 do_io_error (transport);
00613 goto out;
00614 }
00615 }
00616 else
00617 {
00618 _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
00619 total_bytes_to_write);
00620
00621 total += bytes_written;
00622 socket_transport->message_bytes_written += bytes_written;
00623
00624 _dbus_assert (socket_transport->message_bytes_written <=
00625 total_bytes_to_write);
00626
00627 if (socket_transport->message_bytes_written == total_bytes_to_write)
00628 {
00629 socket_transport->message_bytes_written = 0;
00630 _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
00631
00632 _dbus_connection_message_sent (transport->connection,
00633 message);
00634 }
00635 }
00636 }
00637
00638 out:
00639 if (oom)
00640 return FALSE;
00641 else
00642 return TRUE;
00643 }
00644
00645
00646 static dbus_bool_t
00647 do_reading (DBusTransport *transport)
00648 {
00649 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00650 DBusString *buffer;
00651 int bytes_read;
00652 int total;
00653 dbus_bool_t oom;
00654
00655 _dbus_verbose ("%s: fd = %d\n", _DBUS_FUNCTION_NAME,
00656 socket_transport->fd);
00657
00658
00659 if (!_dbus_transport_get_is_authenticated (transport))
00660 return TRUE;
00661
00662 oom = FALSE;
00663
00664 total = 0;
00665
00666 again:
00667
00668
00669 check_read_watch (transport);
00670
00671 if (total > socket_transport->max_bytes_read_per_iteration)
00672 {
00673 _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
00674 total, socket_transport->max_bytes_read_per_iteration);
00675 goto out;
00676 }
00677
00678 _dbus_assert (socket_transport->read_watch != NULL ||
00679 transport->disconnected);
00680
00681 if (transport->disconnected)
00682 goto out;
00683
00684 if (!dbus_watch_get_enabled (socket_transport->read_watch))
00685 return TRUE;
00686
00687 if (_dbus_auth_needs_decoding (transport->auth))
00688 {
00689 if (_dbus_string_get_length (&socket_transport->encoded_incoming) > 0)
00690 bytes_read = _dbus_string_get_length (&socket_transport->encoded_incoming);
00691 else
00692 bytes_read = _dbus_read_socket (socket_transport->fd,
00693 &socket_transport->encoded_incoming,
00694 socket_transport->max_bytes_read_per_iteration);
00695
00696 _dbus_assert (_dbus_string_get_length (&socket_transport->encoded_incoming) ==
00697 bytes_read);
00698
00699 if (bytes_read > 0)
00700 {
00701 int orig_len;
00702
00703 _dbus_message_loader_get_buffer (transport->loader,
00704 &buffer);
00705
00706 orig_len = _dbus_string_get_length (buffer);
00707
00708 if (!_dbus_auth_decode_data (transport->auth,
00709 &socket_transport->encoded_incoming,
00710 buffer))
00711 {
00712 _dbus_verbose ("Out of memory decoding incoming data\n");
00713 oom = TRUE;
00714 goto out;
00715 }
00716
00717 _dbus_message_loader_return_buffer (transport->loader,
00718 buffer,
00719 _dbus_string_get_length (buffer) - orig_len);
00720
00721 _dbus_string_set_length (&socket_transport->encoded_incoming, 0);
00722 }
00723 }
00724 else
00725 {
00726 _dbus_message_loader_get_buffer (transport->loader,
00727 &buffer);
00728
00729 bytes_read = _dbus_read_socket (socket_transport->fd,
00730 buffer, socket_transport->max_bytes_read_per_iteration);
00731
00732 _dbus_message_loader_return_buffer (transport->loader,
00733 buffer,
00734 bytes_read < 0 ? 0 : bytes_read);
00735 }
00736
00737 if (bytes_read < 0)
00738 {
00739
00740
00741 if (errno == ENOMEM)
00742 {
00743 _dbus_verbose ("Out of memory in read()/do_reading()\n");
00744 oom = TRUE;
00745 goto out;
00746 }
00747 else if (errno == EAGAIN ||
00748 errno == EWOULDBLOCK ||
00749 errno == 0 || errno == 2)
00750 goto out;
00751 else
00752 {
00753 _dbus_verbose ("Error reading from remote app: %s\n",
00754 _dbus_strerror (errno));
00755 do_io_error (transport);
00756 goto out;
00757 }
00758 }
00759 else if (bytes_read == 0)
00760 {
00761 _dbus_verbose ("Disconnected from remote app\n");
00762 do_io_error (transport);
00763 goto out;
00764 }
00765 else
00766 {
00767 _dbus_verbose (" read %d bytes\n", bytes_read);
00768
00769 total += bytes_read;
00770
00771 if (!_dbus_transport_queue_messages (transport))
00772 {
00773 oom = TRUE;
00774 _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
00775 goto out;
00776 }
00777
00778
00779
00780
00781
00782 goto again;
00783 }
00784
00785 out:
00786 if (oom)
00787 return FALSE;
00788 else
00789 return TRUE;
00790 }
00791
00792 static dbus_bool_t
00793 socket_handle_watch (DBusTransport *transport,
00794 DBusWatch *watch,
00795 unsigned int flags)
00796 {
00797 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00798
00799 _dbus_assert (watch == socket_transport->read_watch ||
00800 watch == socket_transport->write_watch);
00801 _dbus_assert (watch != NULL);
00802
00803
00804
00805
00806
00807
00808
00809 if ((flags & DBUS_WATCH_ERROR) ||
00810 ((flags & DBUS_WATCH_HANGUP) && !(flags & DBUS_WATCH_READABLE)))
00811 {
00812 _dbus_verbose ("Hang up or error on watch\n");
00813 _dbus_transport_disconnect (transport);
00814 return TRUE;
00815 }
00816
00817 if (watch == socket_transport->read_watch &&
00818 (flags & DBUS_WATCH_READABLE))
00819 {
00820 dbus_bool_t auth_finished;
00821 #if 1
00822 _dbus_verbose ("handling read watch %p flags = %x\n",
00823 watch, flags);
00824 #endif
00825 if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
00826 return FALSE;
00827
00828
00829
00830
00831
00832
00833
00834 if (!auth_finished)
00835 {
00836 if (!do_reading (transport))
00837 {
00838 _dbus_verbose ("no memory to read\n");
00839 return FALSE;
00840 }
00841 }
00842 else
00843 {
00844 _dbus_verbose ("Not reading anything since we just completed the authentication\n");
00845 }
00846 }
00847 else if (watch == socket_transport->write_watch &&
00848 (flags & DBUS_WATCH_WRITABLE))
00849 {
00850 #if 1
00851 _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
00852 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
00853 #endif
00854 if (!do_authentication (transport, FALSE, TRUE, NULL))
00855 return FALSE;
00856
00857 if (!do_writing (transport))
00858 {
00859 _dbus_verbose ("no memory to write\n");
00860 return FALSE;
00861 }
00862
00863
00864 check_write_watch (transport);
00865 }
00866 #ifdef DBUS_ENABLE_VERBOSE_MODE
00867 else
00868 {
00869 if (watch == socket_transport->read_watch)
00870 _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
00871 flags);
00872 else if (watch == socket_transport->write_watch)
00873 _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
00874 flags);
00875 else
00876 _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
00877 watch, dbus_watch_get_fd (watch));
00878 }
00879 #endif
00880
00881 return TRUE;
00882 }
00883
00884 static void
00885 socket_disconnect (DBusTransport *transport)
00886 {
00887 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00888
00889 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
00890
00891 free_watches (transport);
00892
00893 _dbus_close_socket (socket_transport->fd, NULL);
00894 socket_transport->fd = -1;
00895 }
00896
00897 static dbus_bool_t
00898 socket_connection_set (DBusTransport *transport)
00899 {
00900 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00901
00902 _dbus_watch_set_handler (socket_transport->write_watch,
00903 _dbus_connection_handle_watch,
00904 transport->connection, NULL);
00905
00906 _dbus_watch_set_handler (socket_transport->read_watch,
00907 _dbus_connection_handle_watch,
00908 transport->connection, NULL);
00909
00910 if (!_dbus_connection_add_watch_unlocked (transport->connection,
00911 socket_transport->write_watch))
00912 return FALSE;
00913
00914 if (!_dbus_connection_add_watch_unlocked (transport->connection,
00915 socket_transport->read_watch))
00916 {
00917 _dbus_connection_remove_watch_unlocked (transport->connection,
00918 socket_transport->write_watch);
00919 return FALSE;
00920 }
00921
00922 check_read_watch (transport);
00923 check_write_watch (transport);
00924
00925 return TRUE;
00926 }
00927
00935 static void
00936 socket_do_iteration (DBusTransport *transport,
00937 unsigned int flags,
00938 int timeout_milliseconds)
00939 {
00940 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00941 DBusPollFD poll_fd;
00942 int poll_res;
00943 int poll_timeout;
00944
00945 _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
00946 flags & DBUS_ITERATION_DO_READING ? "read" : "",
00947 flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
00948 timeout_milliseconds,
00949 socket_transport->read_watch,
00950 socket_transport->write_watch,
00951 socket_transport->fd);
00952
00953
00954
00955
00956
00957
00958
00959 poll_fd.fd = socket_transport->fd;
00960 poll_fd.events = 0;
00961
00962 if (_dbus_transport_get_is_authenticated (transport))
00963 {
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974 if ((flags & DBUS_ITERATION_DO_WRITING) &&
00975 !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
00976 !transport->disconnected &&
00977 _dbus_connection_has_messages_to_send_unlocked (transport->connection))
00978 {
00979 do_writing (transport);
00980
00981 if (transport->disconnected ||
00982 !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
00983 goto out;
00984 }
00985
00986
00987 _dbus_assert (socket_transport->read_watch);
00988 if (flags & DBUS_ITERATION_DO_READING)
00989 poll_fd.events |= _DBUS_POLLIN;
00990
00991 _dbus_assert (socket_transport->write_watch);
00992 if (flags & DBUS_ITERATION_DO_WRITING)
00993 poll_fd.events |= _DBUS_POLLOUT;
00994 }
00995 else
00996 {
00997 DBusAuthState auth_state;
00998
00999 auth_state = _dbus_auth_do_work (transport->auth);
01000
01001 if (transport->receive_credentials_pending ||
01002 auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
01003 poll_fd.events |= _DBUS_POLLIN;
01004
01005 if (transport->send_credentials_pending ||
01006 auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
01007 poll_fd.events |= _DBUS_POLLOUT;
01008 }
01009
01010 if (poll_fd.events)
01011 {
01012 if (flags & DBUS_ITERATION_BLOCK)
01013 poll_timeout = timeout_milliseconds;
01014 else
01015 poll_timeout = 0;
01016
01017
01018
01019
01020
01021
01022 if (flags & DBUS_ITERATION_BLOCK)
01023 {
01024 _dbus_verbose ("unlock %s pre poll\n", _DBUS_FUNCTION_NAME);
01025 _dbus_connection_unlock (transport->connection);
01026 }
01027
01028 again:
01029 poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
01030
01031 if (poll_res < 0 && errno == EINTR)
01032 goto again;
01033
01034 if (flags & DBUS_ITERATION_BLOCK)
01035 {
01036 _dbus_verbose ("lock %s post poll\n", _DBUS_FUNCTION_NAME);
01037 _dbus_connection_lock (transport->connection);
01038 }
01039
01040 if (poll_res >= 0)
01041 {
01042 if (poll_res == 0)
01043 poll_fd.revents = 0;
01044
01045
01046
01047
01048 if (poll_fd.revents & _DBUS_POLLERR)
01049 do_io_error (transport);
01050 else
01051 {
01052 dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
01053 dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
01054 dbus_bool_t authentication_completed;
01055
01056 _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
01057 need_read, need_write);
01058 do_authentication (transport, need_read, need_write,
01059 &authentication_completed);
01060
01061
01062 if (authentication_completed)
01063 goto out;
01064
01065 if (need_read && (flags & DBUS_ITERATION_DO_READING))
01066 do_reading (transport);
01067 if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
01068 do_writing (transport);
01069 }
01070 }
01071 else
01072 {
01073 _dbus_verbose ("Error from _dbus_poll(): %s\n",
01074 _dbus_strerror (errno));
01075 }
01076 }
01077
01078
01079 out:
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090 check_write_watch (transport);
01091
01092 _dbus_verbose (" ... leaving do_iteration()\n");
01093 }
01094
01095 static void
01096 socket_live_messages_changed (DBusTransport *transport)
01097 {
01098
01099 check_read_watch (transport);
01100 }
01101
01102
01103 static dbus_bool_t
01104 socket_get_socket_fd (DBusTransport *transport,
01105 int *fd_p)
01106 {
01107 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
01108
01109 *fd_p = socket_transport->fd;
01110
01111 return TRUE;
01112 }
01113
01114 static const DBusTransportVTable socket_vtable = {
01115 socket_finalize,
01116 socket_handle_watch,
01117 socket_disconnect,
01118 socket_connection_set,
01119 socket_do_iteration,
01120 socket_live_messages_changed,
01121 socket_get_socket_fd
01122 };
01123
01135 DBusTransport*
01136 _dbus_transport_new_for_socket (int fd,
01137 const DBusString *server_guid,
01138 const DBusString *address)
01139 {
01140 DBusTransportSocket *socket_transport;
01141
01142 socket_transport = dbus_new0 (DBusTransportSocket, 1);
01143 if (socket_transport == NULL)
01144 return NULL;
01145
01146 if (!_dbus_string_init (&socket_transport->encoded_outgoing))
01147 goto failed_0;
01148
01149 if (!_dbus_string_init (&socket_transport->encoded_incoming))
01150 goto failed_1;
01151
01152 socket_transport->write_watch = _dbus_watch_new (fd,
01153 DBUS_WATCH_WRITABLE,
01154 FALSE,
01155 NULL, NULL, NULL);
01156 if (socket_transport->write_watch == NULL)
01157 goto failed_2;
01158
01159 socket_transport->read_watch = _dbus_watch_new (fd,
01160 DBUS_WATCH_READABLE,
01161 FALSE,
01162 NULL, NULL, NULL);
01163 if (socket_transport->read_watch == NULL)
01164 goto failed_3;
01165
01166 if (!_dbus_transport_init_base (&socket_transport->base,
01167 &socket_vtable,
01168 server_guid, address))
01169 goto failed_4;
01170
01171 socket_transport->fd = fd;
01172 socket_transport->message_bytes_written = 0;
01173
01174
01175 socket_transport->max_bytes_read_per_iteration = 2048;
01176 socket_transport->max_bytes_written_per_iteration = 2048;
01177
01178 return (DBusTransport*) socket_transport;
01179
01180 failed_4:
01181 _dbus_watch_unref (socket_transport->read_watch);
01182 failed_3:
01183 _dbus_watch_unref (socket_transport->write_watch);
01184 failed_2:
01185 _dbus_string_free (&socket_transport->encoded_incoming);
01186 failed_1:
01187 _dbus_string_free (&socket_transport->encoded_outgoing);
01188 failed_0:
01189 dbus_free (socket_transport);
01190 return NULL;
01191 }
01192
01201 DBusTransport*
01202 _dbus_transport_new_for_tcp_socket (const char *host,
01203 dbus_int32_t port,
01204 DBusError *error)
01205 {
01206 int fd;
01207 DBusTransport *transport;
01208 DBusString address;
01209
01210 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01211
01212 if (!_dbus_string_init (&address))
01213 {
01214 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01215 return NULL;
01216 }
01217
01218 if (!_dbus_string_append (&address, "tcp:"))
01219 goto error;
01220
01221 if (host != NULL &&
01222 (!_dbus_string_append (&address, "host=") ||
01223 !_dbus_string_append (&address, host)))
01224 goto error;
01225
01226 if (!_dbus_string_append (&address, ",port=") ||
01227 !_dbus_string_append_int (&address, port))
01228 goto error;
01229
01230 fd = _dbus_connect_tcp_socket (host, port, error);
01231 if (fd < 0)
01232 {
01233 _DBUS_ASSERT_ERROR_IS_SET (error);
01234 _dbus_string_free (&address);
01235 return NULL;
01236 }
01237
01238 _dbus_fd_set_close_on_exec (fd);
01239
01240 _dbus_verbose ("Successfully connected to tcp socket %s:%d\n",
01241 host, port);
01242
01243 transport = _dbus_transport_new_for_socket (fd, NULL, &address);
01244 if (transport == NULL)
01245 {
01246 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01247 _dbus_close_socket (fd, NULL);
01248 _dbus_string_free (&address);
01249 fd = -1;
01250 }
01251
01252 _dbus_string_free (&address);
01253
01254 return transport;
01255
01256 error:
01257 _dbus_string_free (&address);
01258 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01259 return NULL;
01260 }
01261
01270 DBusTransportOpenResult
01271 _dbus_transport_open_socket(DBusAddressEntry *entry,
01272 DBusTransport **transport_p,
01273 DBusError *error)
01274 {
01275 const char *method;
01276
01277 method = dbus_address_entry_get_method (entry);
01278 _dbus_assert (method != NULL);
01279
01280 if (strcmp (method, "tcp") == 0)
01281 {
01282 const char *host = dbus_address_entry_get_value (entry, "host");
01283 const char *port = dbus_address_entry_get_value (entry, "port");
01284 DBusString str;
01285 long lport;
01286 dbus_bool_t sresult;
01287
01288 if (port == NULL)
01289 {
01290 _dbus_set_bad_address (error, "tcp", "port", NULL);
01291 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
01292 }
01293
01294 _dbus_string_init_const (&str, port);
01295 sresult = _dbus_string_parse_int (&str, 0, &lport, NULL);
01296 _dbus_string_free (&str);
01297
01298 if (sresult == FALSE || lport <= 0 || lport > 65535)
01299 {
01300 _dbus_set_bad_address (error, NULL, NULL,
01301 "Port is not an integer between 0 and 65535");
01302 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
01303 }
01304
01305 *transport_p = _dbus_transport_new_for_tcp_socket (host, lport, error);
01306 if (*transport_p == NULL)
01307 {
01308 _DBUS_ASSERT_ERROR_IS_SET (error);
01309 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
01310 }
01311 else
01312 {
01313 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01314 return DBUS_TRANSPORT_OPEN_OK;
01315 }
01316 }
01317 else
01318 {
01319 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01320 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
01321 }
01322 }
01323