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 goto out;
00750 else
00751 {
00752 _dbus_verbose ("Error reading from remote app: %s\n",
00753 _dbus_strerror (errno));
00754 do_io_error (transport);
00755 goto out;
00756 }
00757 }
00758 else if (bytes_read == 0)
00759 {
00760 _dbus_verbose ("Disconnected from remote app\n");
00761 do_io_error (transport);
00762 goto out;
00763 }
00764 else
00765 {
00766 _dbus_verbose (" read %d bytes\n", bytes_read);
00767
00768 total += bytes_read;
00769
00770 if (!_dbus_transport_queue_messages (transport))
00771 {
00772 oom = TRUE;
00773 _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
00774 goto out;
00775 }
00776
00777
00778
00779
00780
00781 goto again;
00782 }
00783
00784 out:
00785 if (oom)
00786 return FALSE;
00787 else
00788 return TRUE;
00789 }
00790
00791 static dbus_bool_t
00792 socket_handle_watch (DBusTransport *transport,
00793 DBusWatch *watch,
00794 unsigned int flags)
00795 {
00796 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00797
00798 _dbus_assert (watch == socket_transport->read_watch ||
00799 watch == socket_transport->write_watch);
00800 _dbus_assert (watch != NULL);
00801
00802
00803
00804
00805
00806
00807
00808 if ((flags & DBUS_WATCH_ERROR) ||
00809 ((flags & DBUS_WATCH_HANGUP) && !(flags & DBUS_WATCH_READABLE)))
00810 {
00811 _dbus_verbose ("Hang up or error on watch\n");
00812 _dbus_transport_disconnect (transport);
00813 return TRUE;
00814 }
00815
00816 if (watch == socket_transport->read_watch &&
00817 (flags & DBUS_WATCH_READABLE))
00818 {
00819 dbus_bool_t auth_finished;
00820 #if 1
00821 _dbus_verbose ("handling read watch %p flags = %x\n",
00822 watch, flags);
00823 #endif
00824 if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
00825 return FALSE;
00826
00827
00828
00829
00830
00831
00832
00833 if (!auth_finished)
00834 {
00835 if (!do_reading (transport))
00836 {
00837 _dbus_verbose ("no memory to read\n");
00838 return FALSE;
00839 }
00840 }
00841 else
00842 {
00843 _dbus_verbose ("Not reading anything since we just completed the authentication\n");
00844 }
00845 }
00846 else if (watch == socket_transport->write_watch &&
00847 (flags & DBUS_WATCH_WRITABLE))
00848 {
00849 #if 1
00850 _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
00851 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
00852 #endif
00853 if (!do_authentication (transport, FALSE, TRUE, NULL))
00854 return FALSE;
00855
00856 if (!do_writing (transport))
00857 {
00858 _dbus_verbose ("no memory to write\n");
00859 return FALSE;
00860 }
00861
00862
00863 check_write_watch (transport);
00864 }
00865 #ifdef DBUS_ENABLE_VERBOSE_MODE
00866 else
00867 {
00868 if (watch == socket_transport->read_watch)
00869 _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
00870 flags);
00871 else if (watch == socket_transport->write_watch)
00872 _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
00873 flags);
00874 else
00875 _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
00876 watch, dbus_watch_get_fd (watch));
00877 }
00878 #endif
00879
00880 return TRUE;
00881 }
00882
00883 static void
00884 socket_disconnect (DBusTransport *transport)
00885 {
00886 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00887
00888 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
00889
00890 free_watches (transport);
00891
00892 _dbus_close_socket (socket_transport->fd, NULL);
00893 socket_transport->fd = -1;
00894 }
00895
00896 static dbus_bool_t
00897 socket_connection_set (DBusTransport *transport)
00898 {
00899 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00900
00901 _dbus_watch_set_handler (socket_transport->write_watch,
00902 _dbus_connection_handle_watch,
00903 transport->connection, NULL);
00904
00905 _dbus_watch_set_handler (socket_transport->read_watch,
00906 _dbus_connection_handle_watch,
00907 transport->connection, NULL);
00908
00909 if (!_dbus_connection_add_watch_unlocked (transport->connection,
00910 socket_transport->write_watch))
00911 return FALSE;
00912
00913 if (!_dbus_connection_add_watch_unlocked (transport->connection,
00914 socket_transport->read_watch))
00915 {
00916 _dbus_connection_remove_watch_unlocked (transport->connection,
00917 socket_transport->write_watch);
00918 return FALSE;
00919 }
00920
00921 check_read_watch (transport);
00922 check_write_watch (transport);
00923
00924 return TRUE;
00925 }
00926
00934 static void
00935 socket_do_iteration (DBusTransport *transport,
00936 unsigned int flags,
00937 int timeout_milliseconds)
00938 {
00939 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
00940 DBusPollFD poll_fd;
00941 int poll_res;
00942 int poll_timeout;
00943
00944 _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
00945 flags & DBUS_ITERATION_DO_READING ? "read" : "",
00946 flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
00947 timeout_milliseconds,
00948 socket_transport->read_watch,
00949 socket_transport->write_watch,
00950 socket_transport->fd);
00951
00952
00953
00954
00955
00956
00957
00958 poll_fd.fd = socket_transport->fd;
00959 poll_fd.events = 0;
00960
00961 if (_dbus_transport_get_is_authenticated (transport))
00962 {
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973 if ((flags & DBUS_ITERATION_DO_WRITING) &&
00974 !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
00975 !transport->disconnected &&
00976 _dbus_connection_has_messages_to_send_unlocked (transport->connection))
00977 {
00978 do_writing (transport);
00979
00980 if (transport->disconnected ||
00981 !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
00982 goto out;
00983 }
00984
00985
00986 _dbus_assert (socket_transport->read_watch);
00987 if (flags & DBUS_ITERATION_DO_READING)
00988 poll_fd.events |= _DBUS_POLLIN;
00989
00990 _dbus_assert (socket_transport->write_watch);
00991 if (flags & DBUS_ITERATION_DO_WRITING)
00992 poll_fd.events |= _DBUS_POLLOUT;
00993 }
00994 else
00995 {
00996 DBusAuthState auth_state;
00997
00998 auth_state = _dbus_auth_do_work (transport->auth);
00999
01000 if (transport->receive_credentials_pending ||
01001 auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
01002 poll_fd.events |= _DBUS_POLLIN;
01003
01004 if (transport->send_credentials_pending ||
01005 auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
01006 poll_fd.events |= _DBUS_POLLOUT;
01007 }
01008
01009 if (poll_fd.events)
01010 {
01011 if (flags & DBUS_ITERATION_BLOCK)
01012 poll_timeout = timeout_milliseconds;
01013 else
01014 poll_timeout = 0;
01015
01016
01017
01018
01019
01020
01021 if (flags & DBUS_ITERATION_BLOCK)
01022 {
01023 _dbus_verbose ("unlock %s pre poll\n", _DBUS_FUNCTION_NAME);
01024 _dbus_connection_unlock (transport->connection);
01025 }
01026
01027 again:
01028 poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
01029
01030 if (poll_res < 0 && errno == EINTR)
01031 goto again;
01032
01033 if (flags & DBUS_ITERATION_BLOCK)
01034 {
01035 _dbus_verbose ("lock %s post poll\n", _DBUS_FUNCTION_NAME);
01036 _dbus_connection_lock (transport->connection);
01037 }
01038
01039 if (poll_res >= 0)
01040 {
01041 if (poll_res == 0)
01042 poll_fd.revents = 0;
01043
01044
01045
01046
01047 if (poll_fd.revents & _DBUS_POLLERR)
01048 do_io_error (transport);
01049 else
01050 {
01051 dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
01052 dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
01053 dbus_bool_t authentication_completed;
01054
01055 _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
01056 need_read, need_write);
01057 do_authentication (transport, need_read, need_write,
01058 &authentication_completed);
01059
01060
01061 if (authentication_completed)
01062 goto out;
01063
01064 if (need_read && (flags & DBUS_ITERATION_DO_READING))
01065 do_reading (transport);
01066 if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
01067 do_writing (transport);
01068 }
01069 }
01070 else
01071 {
01072 _dbus_verbose ("Error from _dbus_poll(): %s\n",
01073 _dbus_strerror (errno));
01074 }
01075 }
01076
01077
01078 out:
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089 check_write_watch (transport);
01090
01091 _dbus_verbose (" ... leaving do_iteration()\n");
01092 }
01093
01094 static void
01095 socket_live_messages_changed (DBusTransport *transport)
01096 {
01097
01098 check_read_watch (transport);
01099 }
01100
01101
01102 static dbus_bool_t
01103 socket_get_socket_fd (DBusTransport *transport,
01104 int *fd_p)
01105 {
01106 DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
01107
01108 *fd_p = socket_transport->fd;
01109
01110 return TRUE;
01111 }
01112
01113 static const DBusTransportVTable socket_vtable = {
01114 socket_finalize,
01115 socket_handle_watch,
01116 socket_disconnect,
01117 socket_connection_set,
01118 socket_do_iteration,
01119 socket_live_messages_changed,
01120 socket_get_socket_fd
01121 };
01122
01134 DBusTransport*
01135 _dbus_transport_new_for_socket (int fd,
01136 const DBusString *server_guid,
01137 const DBusString *address)
01138 {
01139 DBusTransportSocket *socket_transport;
01140
01141 socket_transport = dbus_new0 (DBusTransportSocket, 1);
01142 if (socket_transport == NULL)
01143 return NULL;
01144
01145 if (!_dbus_string_init (&socket_transport->encoded_outgoing))
01146 goto failed_0;
01147
01148 if (!_dbus_string_init (&socket_transport->encoded_incoming))
01149 goto failed_1;
01150
01151 socket_transport->write_watch = _dbus_watch_new (fd,
01152 DBUS_WATCH_WRITABLE,
01153 FALSE,
01154 NULL, NULL, NULL);
01155 if (socket_transport->write_watch == NULL)
01156 goto failed_2;
01157
01158 socket_transport->read_watch = _dbus_watch_new (fd,
01159 DBUS_WATCH_READABLE,
01160 FALSE,
01161 NULL, NULL, NULL);
01162 if (socket_transport->read_watch == NULL)
01163 goto failed_3;
01164
01165 if (!_dbus_transport_init_base (&socket_transport->base,
01166 &socket_vtable,
01167 server_guid, address))
01168 goto failed_4;
01169
01170 socket_transport->fd = fd;
01171 socket_transport->message_bytes_written = 0;
01172
01173
01174 socket_transport->max_bytes_read_per_iteration = 2048;
01175 socket_transport->max_bytes_written_per_iteration = 2048;
01176
01177 return (DBusTransport*) socket_transport;
01178
01179 failed_4:
01180 _dbus_watch_unref (socket_transport->read_watch);
01181 failed_3:
01182 _dbus_watch_unref (socket_transport->write_watch);
01183 failed_2:
01184 _dbus_string_free (&socket_transport->encoded_incoming);
01185 failed_1:
01186 _dbus_string_free (&socket_transport->encoded_outgoing);
01187 failed_0:
01188 dbus_free (socket_transport);
01189 return NULL;
01190 }
01191
01200 DBusTransport*
01201 _dbus_transport_new_for_tcp_socket (const char *host,
01202 dbus_int32_t port,
01203 DBusError *error)
01204 {
01205 int fd;
01206 DBusTransport *transport;
01207 DBusString address;
01208
01209 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01210
01211 if (!_dbus_string_init (&address))
01212 {
01213 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01214 return NULL;
01215 }
01216
01217 if (!_dbus_string_append (&address, "tcp:"))
01218 goto error;
01219
01220 if (host != NULL &&
01221 (!_dbus_string_append (&address, "host=") ||
01222 !_dbus_string_append (&address, host)))
01223 goto error;
01224
01225 if (!_dbus_string_append (&address, ",port=") ||
01226 !_dbus_string_append_int (&address, port))
01227 goto error;
01228
01229 fd = _dbus_connect_tcp_socket (host, port, error);
01230 if (fd < 0)
01231 {
01232 _DBUS_ASSERT_ERROR_IS_SET (error);
01233 _dbus_string_free (&address);
01234 return NULL;
01235 }
01236
01237 _dbus_fd_set_close_on_exec (fd);
01238
01239 _dbus_verbose ("Successfully connected to tcp socket %s:%d\n",
01240 host, port);
01241
01242 transport = _dbus_transport_new_for_socket (fd, NULL, &address);
01243 if (transport == NULL)
01244 {
01245 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01246 _dbus_close_socket (fd, NULL);
01247 _dbus_string_free (&address);
01248 fd = -1;
01249 }
01250
01251 _dbus_string_free (&address);
01252
01253 return transport;
01254
01255 error:
01256 _dbus_string_free (&address);
01257 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01258 return NULL;
01259 }
01260
01269 DBusTransportOpenResult
01270 _dbus_transport_open_socket(DBusAddressEntry *entry,
01271 DBusTransport **transport_p,
01272 DBusError *error)
01273 {
01274 const char *method;
01275
01276 method = dbus_address_entry_get_method (entry);
01277 _dbus_assert (method != NULL);
01278
01279 if (strcmp (method, "tcp") == 0)
01280 {
01281 const char *host = dbus_address_entry_get_value (entry, "host");
01282 const char *port = dbus_address_entry_get_value (entry, "port");
01283 DBusString str;
01284 long lport;
01285 dbus_bool_t sresult;
01286
01287 if (port == NULL)
01288 {
01289 _dbus_set_bad_address (error, "tcp", "port", NULL);
01290 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
01291 }
01292
01293 _dbus_string_init_const (&str, port);
01294 sresult = _dbus_string_parse_int (&str, 0, &lport, NULL);
01295 _dbus_string_free (&str);
01296
01297 if (sresult == FALSE || lport <= 0 || lport > 65535)
01298 {
01299 _dbus_set_bad_address (error, NULL, NULL,
01300 "Port is not an integer between 0 and 65535");
01301 return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
01302 }
01303
01304 *transport_p = _dbus_transport_new_for_tcp_socket (host, lport, error);
01305 if (*transport_p == NULL)
01306 {
01307 _DBUS_ASSERT_ERROR_IS_SET (error);
01308 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
01309 }
01310 else
01311 {
01312 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01313 return DBUS_TRANSPORT_OPEN_OK;
01314 }
01315 }
01316 else
01317 {
01318 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01319 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
01320 }
01321 }
01322