dbus-transport-socket.c revision 100bcd121242c131b55c68aecdacec19921b61d9
18027efc97b4bec85f674570f878919cb72456745Havoc Pennington/* -*- mode: C; c-file-style: "gnu" -*- */
28027efc97b4bec85f674570f878919cb72456745Havoc Pennington/* dbus-transport-socket.c  Socket subclasses of DBusTransport
38027efc97b4bec85f674570f878919cb72456745Havoc Pennington *
48027efc97b4bec85f674570f878919cb72456745Havoc Pennington * Copyright (C) 2002, 2003, 2004, 2006  Red Hat Inc.
58027efc97b4bec85f674570f878919cb72456745Havoc Pennington *
68027efc97b4bec85f674570f878919cb72456745Havoc Pennington * Licensed under the Academic Free License version 2.1
78027efc97b4bec85f674570f878919cb72456745Havoc Pennington *
88027efc97b4bec85f674570f878919cb72456745Havoc Pennington * This program is free software; you can redistribute it and/or modify
98027efc97b4bec85f674570f878919cb72456745Havoc Pennington * it under the terms of the GNU General Public License as published by
108027efc97b4bec85f674570f878919cb72456745Havoc Pennington * the Free Software Foundation; either version 2 of the License, or
118027efc97b4bec85f674570f878919cb72456745Havoc Pennington * (at your option) any later version.
128027efc97b4bec85f674570f878919cb72456745Havoc Pennington *
138027efc97b4bec85f674570f878919cb72456745Havoc Pennington * This program is distributed in the hope that it will be useful,
148027efc97b4bec85f674570f878919cb72456745Havoc Pennington * but WITHOUT ANY WARRANTY; without even the implied warranty of
158027efc97b4bec85f674570f878919cb72456745Havoc Pennington * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
168027efc97b4bec85f674570f878919cb72456745Havoc Pennington * GNU General Public License for more details.
178027efc97b4bec85f674570f878919cb72456745Havoc Pennington *
188027efc97b4bec85f674570f878919cb72456745Havoc Pennington * You should have received a copy of the GNU General Public License
198027efc97b4bec85f674570f878919cb72456745Havoc Pennington * along with this program; if not, write to the Free Software
208027efc97b4bec85f674570f878919cb72456745Havoc Pennington * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
218027efc97b4bec85f674570f878919cb72456745Havoc Pennington *
228027efc97b4bec85f674570f878919cb72456745Havoc Pennington */
238027efc97b4bec85f674570f878919cb72456745Havoc Pennington
248027efc97b4bec85f674570f878919cb72456745Havoc Pennington#include "dbus-internals.h"
258027efc97b4bec85f674570f878919cb72456745Havoc Pennington#include "dbus-connection-internal.h"
268027efc97b4bec85f674570f878919cb72456745Havoc Pennington#include "dbus-transport-socket.h"
278027efc97b4bec85f674570f878919cb72456745Havoc Pennington#include "dbus-transport-protected.h"
288027efc97b4bec85f674570f878919cb72456745Havoc Pennington#include "dbus-watch.h"
298027efc97b4bec85f674570f878919cb72456745Havoc Pennington
308027efc97b4bec85f674570f878919cb72456745Havoc Pennington
318027efc97b4bec85f674570f878919cb72456745Havoc Pennington/**
328027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @defgroup DBusTransportSocket DBusTransport implementations for sockets
338027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @ingroup  DBusInternals
348027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @brief Implementation details of DBusTransport on sockets
358027efc97b4bec85f674570f878919cb72456745Havoc Pennington *
368027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @{
378027efc97b4bec85f674570f878919cb72456745Havoc Pennington */
388027efc97b4bec85f674570f878919cb72456745Havoc Pennington
398027efc97b4bec85f674570f878919cb72456745Havoc Pennington/**
408027efc97b4bec85f674570f878919cb72456745Havoc Pennington * Opaque object representing a socket file descriptor transport.
418027efc97b4bec85f674570f878919cb72456745Havoc Pennington */
428027efc97b4bec85f674570f878919cb72456745Havoc Penningtontypedef struct DBusTransportSocket DBusTransportSocket;
438027efc97b4bec85f674570f878919cb72456745Havoc Pennington
448027efc97b4bec85f674570f878919cb72456745Havoc Pennington/**
458027efc97b4bec85f674570f878919cb72456745Havoc Pennington * Implementation details of DBusTransportSocket. All members are private.
468027efc97b4bec85f674570f878919cb72456745Havoc Pennington */
478027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstruct DBusTransportSocket
488027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
498027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransport base;                   /**< Parent instance */
508027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int fd;                               /**< File descriptor. */
518027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusWatch *read_watch;                /**< Watch for readability. */
528027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusWatch *write_watch;               /**< Watch for writability. */
538027efc97b4bec85f674570f878919cb72456745Havoc Pennington
548027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int max_bytes_read_per_iteration;     /**< To avoid blocking too long. */
558027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int max_bytes_written_per_iteration;  /**< To avoid blocking too long. */
568027efc97b4bec85f674570f878919cb72456745Havoc Pennington
578027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int message_bytes_written;            /**< Number of bytes of current
588027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                         *   outgoing message that have
598027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                         *   been written.
608027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                         */
618027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusString encoded_outgoing;          /**< Encoded version of current
628027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                         *   outgoing message.
638027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                         */
648027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusString encoded_incoming;          /**< Encoded version of current
658027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                         *   incoming data.
668027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                         */
678027efc97b4bec85f674570f878919cb72456745Havoc Pennington};
688027efc97b4bec85f674570f878919cb72456745Havoc Pennington
698027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic void
708027efc97b4bec85f674570f878919cb72456745Havoc Penningtonfree_watches (DBusTransport *transport)
718027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
728027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
738027efc97b4bec85f674570f878919cb72456745Havoc Pennington
748027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
758027efc97b4bec85f674570f878919cb72456745Havoc Pennington
768027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (socket_transport->read_watch)
778027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
788027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (transport->connection)
798027efc97b4bec85f674570f878919cb72456745Havoc Pennington        _dbus_connection_remove_watch_unlocked (transport->connection,
808027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                                socket_transport->read_watch);
818027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_watch_invalidate (socket_transport->read_watch);
828027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_watch_unref (socket_transport->read_watch);
838027efc97b4bec85f674570f878919cb72456745Havoc Pennington      socket_transport->read_watch = NULL;
848027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
858027efc97b4bec85f674570f878919cb72456745Havoc Pennington
868027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (socket_transport->write_watch)
878027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
888027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (transport->connection)
898027efc97b4bec85f674570f878919cb72456745Havoc Pennington        _dbus_connection_remove_watch_unlocked (transport->connection,
908027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                                socket_transport->write_watch);
918027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_watch_invalidate (socket_transport->write_watch);
928027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_watch_unref (socket_transport->write_watch);
938027efc97b4bec85f674570f878919cb72456745Havoc Pennington      socket_transport->write_watch = NULL;
948027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
958027efc97b4bec85f674570f878919cb72456745Havoc Pennington
968027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
978027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
988027efc97b4bec85f674570f878919cb72456745Havoc Pennington
998027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic void
1008027efc97b4bec85f674570f878919cb72456745Havoc Penningtonsocket_finalize (DBusTransport *transport)
1018027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
1028027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1038027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1048027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
1058027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1068027efc97b4bec85f674570f878919cb72456745Havoc Pennington  free_watches (transport);
1078027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1088027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_string_free (&socket_transport->encoded_outgoing);
1098027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_string_free (&socket_transport->encoded_incoming);
1108027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1118027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_transport_finalize_base (transport);
1128027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1138027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_assert (socket_transport->read_watch == NULL);
1148027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_assert (socket_transport->write_watch == NULL);
1158027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1168027efc97b4bec85f674570f878919cb72456745Havoc Pennington  dbus_free (transport);
1178027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
1188027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1198027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic void
1208027efc97b4bec85f674570f878919cb72456745Havoc Penningtoncheck_write_watch (DBusTransport *transport)
1218027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
1228027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1238027efc97b4bec85f674570f878919cb72456745Havoc Pennington  dbus_bool_t needed;
1248027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1258027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (transport->connection == NULL)
1268027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return;
1278027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1288027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (transport->disconnected)
1298027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
1308027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_assert (socket_transport->write_watch == NULL);
1318027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return;
1328027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
1338027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1348027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_transport_ref (transport);
1358027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1368027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (_dbus_transport_get_is_authenticated (transport))
1378027efc97b4bec85f674570f878919cb72456745Havoc Pennington    needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
1388027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else
1398027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
1408027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (transport->send_credentials_pending)
1418027efc97b4bec85f674570f878919cb72456745Havoc Pennington        needed = TRUE;
1428027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
1438027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
1448027efc97b4bec85f674570f878919cb72456745Havoc Pennington          DBusAuthState auth_state;
1458027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1468027efc97b4bec85f674570f878919cb72456745Havoc Pennington          auth_state = _dbus_auth_do_work (transport->auth);
1478027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1488027efc97b4bec85f674570f878919cb72456745Havoc Pennington          /* If we need memory we install the write watch just in case,
1498027efc97b4bec85f674570f878919cb72456745Havoc Pennington           * if there's no need for it, it will get de-installed
1508027efc97b4bec85f674570f878919cb72456745Havoc Pennington           * next time we try reading.
1518027efc97b4bec85f674570f878919cb72456745Havoc Pennington           */
1528027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND ||
1538027efc97b4bec85f674570f878919cb72456745Havoc Pennington              auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
1548027efc97b4bec85f674570f878919cb72456745Havoc Pennington            needed = TRUE;
1558027efc97b4bec85f674570f878919cb72456745Havoc Pennington          else
1568027efc97b4bec85f674570f878919cb72456745Havoc Pennington            needed = FALSE;
1578027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
1588027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
1598027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1608027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_verbose ("check_write_watch(): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
1618027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 needed, transport->connection, socket_transport->write_watch,
1628027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 socket_transport->fd,
1638027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
1648027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1658027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_connection_toggle_watch_unlocked (transport->connection,
1668027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                          socket_transport->write_watch,
1678027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                          needed);
1688027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1698027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_transport_unref (transport);
1708027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
1718027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1728027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic void
1738027efc97b4bec85f674570f878919cb72456745Havoc Penningtoncheck_read_watch (DBusTransport *transport)
1748027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
1758027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1768027efc97b4bec85f674570f878919cb72456745Havoc Pennington  dbus_bool_t need_read_watch;
1778027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1788027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_verbose ("%s: fd = %d\n",
1798027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 _DBUS_FUNCTION_NAME, socket_transport->fd);
1808027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1818027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (transport->connection == NULL)
1828027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return;
1838027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1848027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (transport->disconnected)
1858027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
1868027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_assert (socket_transport->read_watch == NULL);
1878027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return;
1888027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
1898027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1908027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_transport_ref (transport);
1918027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1928027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (_dbus_transport_get_is_authenticated (transport))
1938027efc97b4bec85f674570f878919cb72456745Havoc Pennington    need_read_watch =
1948027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_counter_get_value (transport->live_messages_size) < transport->max_live_messages_size;
1958027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else
1968027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
1978027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (transport->receive_credentials_pending)
1988027efc97b4bec85f674570f878919cb72456745Havoc Pennington        need_read_watch = TRUE;
1998027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
2008027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
2018027efc97b4bec85f674570f878919cb72456745Havoc Pennington          /* The reason to disable need_read_watch when not WAITING_FOR_INPUT
2028027efc97b4bec85f674570f878919cb72456745Havoc Pennington           * is to avoid spinning on the file descriptor when we're waiting
2038027efc97b4bec85f674570f878919cb72456745Havoc Pennington           * to write or for some other part of the auth process
2048027efc97b4bec85f674570f878919cb72456745Havoc Pennington           */
2058027efc97b4bec85f674570f878919cb72456745Havoc Pennington          DBusAuthState auth_state;
2068027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2078027efc97b4bec85f674570f878919cb72456745Havoc Pennington          auth_state = _dbus_auth_do_work (transport->auth);
2088027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2098027efc97b4bec85f674570f878919cb72456745Havoc Pennington          /* If we need memory we install the read watch just in case,
2108027efc97b4bec85f674570f878919cb72456745Havoc Pennington           * if there's no need for it, it will get de-installed
2118027efc97b4bec85f674570f878919cb72456745Havoc Pennington           * next time we try reading. If we're authenticated we
2128027efc97b4bec85f674570f878919cb72456745Havoc Pennington           * install it since we normally have it installed while
2138027efc97b4bec85f674570f878919cb72456745Havoc Pennington           * authenticated.
2148027efc97b4bec85f674570f878919cb72456745Havoc Pennington           */
2158027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT ||
2168027efc97b4bec85f674570f878919cb72456745Havoc Pennington              auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY ||
2178027efc97b4bec85f674570f878919cb72456745Havoc Pennington              auth_state == DBUS_AUTH_STATE_AUTHENTICATED)
2188027efc97b4bec85f674570f878919cb72456745Havoc Pennington            need_read_watch = TRUE;
2198027efc97b4bec85f674570f878919cb72456745Havoc Pennington          else
2208027efc97b4bec85f674570f878919cb72456745Havoc Pennington            need_read_watch = FALSE;
2218027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
2228027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
2238027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2248027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_verbose ("  setting read watch enabled = %d\n", need_read_watch);
2258027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_connection_toggle_watch_unlocked (transport->connection,
2268027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                          socket_transport->read_watch,
2278027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                          need_read_watch);
2288027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2298027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_transport_unref (transport);
2308027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
2318027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2328027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic void
2338027efc97b4bec85f674570f878919cb72456745Havoc Penningtondo_io_error (DBusTransport *transport)
2348027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
2358027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_transport_ref (transport);
2368027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_transport_disconnect (transport);
2378027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_transport_unref (transport);
2388027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
2398027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2408027efc97b4bec85f674570f878919cb72456745Havoc Pennington/* return value is whether we successfully read any new data. */
2418027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic dbus_bool_t
2428027efc97b4bec85f674570f878919cb72456745Havoc Penningtonread_data_into_auth (DBusTransport *transport,
2438027efc97b4bec85f674570f878919cb72456745Havoc Pennington                     dbus_bool_t   *oom)
2448027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
2458027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
2468027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusString *buffer;
2478027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int bytes_read;
2488027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2498027efc97b4bec85f674570f878919cb72456745Havoc Pennington  *oom = FALSE;
2508027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2518027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_auth_get_buffer (transport->auth, &buffer);
2528027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2538027efc97b4bec85f674570f878919cb72456745Havoc Pennington  bytes_read = _dbus_read_socket (socket_transport->fd,
2548027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                  buffer, socket_transport->max_bytes_read_per_iteration);
2558027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2568027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_auth_return_buffer (transport->auth, buffer,
2578027efc97b4bec85f674570f878919cb72456745Havoc Pennington                            bytes_read > 0 ? bytes_read : 0);
2588027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2598027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (bytes_read > 0)
2608027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
2618027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
2628027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2638027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return TRUE;
2648027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
2658027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else if (bytes_read < 0)
2668027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
2678027efc97b4bec85f674570f878919cb72456745Havoc Pennington      /* EINTR already handled for us */
2688027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2698027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (errno == ENOMEM)
2708027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
2718027efc97b4bec85f674570f878919cb72456745Havoc Pennington          *oom = TRUE;
2728027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
2738027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else if (errno == EAGAIN ||
2748027efc97b4bec85f674570f878919cb72456745Havoc Pennington               errno == EWOULDBLOCK)
2758027efc97b4bec85f674570f878919cb72456745Havoc Pennington        ; /* do nothing, just return FALSE below */
2768027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
2778027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
2788027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("Error reading from remote app: %s\n",
2798027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         _dbus_strerror (errno));
2808027efc97b4bec85f674570f878919cb72456745Havoc Pennington          do_io_error (transport);
2818027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
2828027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2838027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return FALSE;
2848027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
2858027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else
2868027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
2878027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_assert (bytes_read == 0);
2888027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2898027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose ("Disconnected from remote app\n");
2908027efc97b4bec85f674570f878919cb72456745Havoc Pennington      do_io_error (transport);
2918027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2928027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return FALSE;
2938027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
2948027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
2958027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2968027efc97b4bec85f674570f878919cb72456745Havoc Pennington/* Return value is whether we successfully wrote any bytes */
2978027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic dbus_bool_t
2988027efc97b4bec85f674570f878919cb72456745Havoc Penningtonwrite_data_from_auth (DBusTransport *transport)
2998027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
3008027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
3018027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int bytes_written;
3028027efc97b4bec85f674570f878919cb72456745Havoc Pennington  const DBusString *buffer;
3038027efc97b4bec85f674570f878919cb72456745Havoc Pennington
3048027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_auth_get_bytes_to_send (transport->auth,
3058027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                     &buffer))
3068027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return FALSE;
3078027efc97b4bec85f674570f878919cb72456745Havoc Pennington
3088027efc97b4bec85f674570f878919cb72456745Havoc Pennington  bytes_written = _dbus_write_socket (socket_transport->fd,
3098027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                      buffer,
3108027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                      0, _dbus_string_get_length (buffer));
3118027efc97b4bec85f674570f878919cb72456745Havoc Pennington
3128027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (bytes_written > 0)
3138027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
3148027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_auth_bytes_sent (transport->auth, bytes_written);
3158027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return TRUE;
3168027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
3178027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else if (bytes_written < 0)
3188027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
3198027efc97b4bec85f674570f878919cb72456745Havoc Pennington      /* EINTR already handled for us */
3208027efc97b4bec85f674570f878919cb72456745Havoc Pennington
3218027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (errno == EAGAIN ||
3228027efc97b4bec85f674570f878919cb72456745Havoc Pennington          errno == EWOULDBLOCK)
3238027efc97b4bec85f674570f878919cb72456745Havoc Pennington        ;
3248027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
3258027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
3268027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("Error writing to remote app: %s\n",
3278027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         _dbus_strerror (errno));
3288027efc97b4bec85f674570f878919cb72456745Havoc Pennington          do_io_error (transport);
3298027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
3308027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
3318027efc97b4bec85f674570f878919cb72456745Havoc Pennington
3328027efc97b4bec85f674570f878919cb72456745Havoc Pennington  return FALSE;
3338027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
3348027efc97b4bec85f674570f878919cb72456745Havoc Pennington
3358027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic void
3368027efc97b4bec85f674570f878919cb72456745Havoc Penningtonexchange_credentials (DBusTransport *transport,
3378027efc97b4bec85f674570f878919cb72456745Havoc Pennington                      dbus_bool_t    do_reading,
3388027efc97b4bec85f674570f878919cb72456745Havoc Pennington                      dbus_bool_t    do_writing)
3398027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
3408027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
341100bcd121242c131b55c68aecdacec19921b61d9John (J  DBusError error;
3428027efc97b4bec85f674570f878919cb72456745Havoc Pennington
343100bcd121242c131b55c68aecdacec19921b61d9John (J  _dbus_verbose ("exchange_credentials: do_reading = %d, do_writing = %d\n",
344100bcd121242c131b55c68aecdacec19921b61d9John (J                  do_reading, do_writing);
345100bcd121242c131b55c68aecdacec19921b61d9John (J
346100bcd121242c131b55c68aecdacec19921b61d9John (J  dbus_error_init (&error);
3478027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (do_writing && transport->send_credentials_pending)
3488027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
3498027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (_dbus_send_credentials_unix_socket (socket_transport->fd,
350100bcd121242c131b55c68aecdacec19921b61d9John (J                                              &error))
3518027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
3528027efc97b4bec85f674570f878919cb72456745Havoc Pennington          transport->send_credentials_pending = FALSE;
3538027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
3548027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
3558027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
356100bcd121242c131b55c68aecdacec19921b61d9John (J          _dbus_verbose ("Failed to write credentials: %s\n", error.message);
357100bcd121242c131b55c68aecdacec19921b61d9John (J          dbus_error_free (&error);
3588027efc97b4bec85f674570f878919cb72456745Havoc Pennington          do_io_error (transport);
3598027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
3608027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
3618027efc97b4bec85f674570f878919cb72456745Havoc Pennington
3628027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (do_reading && transport->receive_credentials_pending)
3638027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
3648027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (_dbus_read_credentials_unix_socket (socket_transport->fd,
3658027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                              &transport->credentials,
366100bcd121242c131b55c68aecdacec19921b61d9John (J                                              &error))
3678027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
3688027efc97b4bec85f674570f878919cb72456745Havoc Pennington          transport->receive_credentials_pending = FALSE;
3698027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
3708027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
3718027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
372100bcd121242c131b55c68aecdacec19921b61d9John (J          _dbus_verbose ("Failed to read credentials %s\n", error.message);
373100bcd121242c131b55c68aecdacec19921b61d9John (J          dbus_error_free (&error);
3748027efc97b4bec85f674570f878919cb72456745Havoc Pennington          do_io_error (transport);
3758027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
3768027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
3778027efc97b4bec85f674570f878919cb72456745Havoc Pennington
3788027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!(transport->send_credentials_pending ||
3798027efc97b4bec85f674570f878919cb72456745Havoc Pennington        transport->receive_credentials_pending))
3808027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
3818027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_auth_set_credentials (transport->auth,
3828027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                  &transport->credentials);
3838027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
3848027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
3858027efc97b4bec85f674570f878919cb72456745Havoc Pennington
3868027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic dbus_bool_t
3878027efc97b4bec85f674570f878919cb72456745Havoc Penningtondo_authentication (DBusTransport *transport,
3888027efc97b4bec85f674570f878919cb72456745Havoc Pennington                   dbus_bool_t    do_reading,
3898027efc97b4bec85f674570f878919cb72456745Havoc Pennington                   dbus_bool_t    do_writing,
3908027efc97b4bec85f674570f878919cb72456745Havoc Pennington		   dbus_bool_t   *auth_completed)
3918027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
3928027efc97b4bec85f674570f878919cb72456745Havoc Pennington  dbus_bool_t oom;
3938027efc97b4bec85f674570f878919cb72456745Havoc Pennington  dbus_bool_t orig_auth_state;
3948027efc97b4bec85f674570f878919cb72456745Havoc Pennington
3958027efc97b4bec85f674570f878919cb72456745Havoc Pennington  oom = FALSE;
3968027efc97b4bec85f674570f878919cb72456745Havoc Pennington
3978027efc97b4bec85f674570f878919cb72456745Havoc Pennington  orig_auth_state = _dbus_transport_get_is_authenticated (transport);
3988027efc97b4bec85f674570f878919cb72456745Havoc Pennington
3998027efc97b4bec85f674570f878919cb72456745Havoc Pennington  /* This is essential to avoid the check_write_watch() at the end,
4008027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * we don't want to add a write watch in do_iteration before
4018027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * we try writing and get EAGAIN
4028027efc97b4bec85f674570f878919cb72456745Havoc Pennington   */
4038027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (orig_auth_state)
4048027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
4058027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (auth_completed)
4068027efc97b4bec85f674570f878919cb72456745Havoc Pennington        *auth_completed = FALSE;
4078027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return TRUE;
4088027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
4098027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4108027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_transport_ref (transport);
4118027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4128027efc97b4bec85f674570f878919cb72456745Havoc Pennington  while (!_dbus_transport_get_is_authenticated (transport) &&
4138027efc97b4bec85f674570f878919cb72456745Havoc Pennington         _dbus_transport_get_is_connected (transport))
4148027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
4158027efc97b4bec85f674570f878919cb72456745Havoc Pennington      exchange_credentials (transport, do_reading, do_writing);
4168027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4178027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (transport->send_credentials_pending ||
4188027efc97b4bec85f674570f878919cb72456745Havoc Pennington          transport->receive_credentials_pending)
4198027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
4208027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
4218027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         transport->send_credentials_pending,
4228027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         transport->receive_credentials_pending);
4238027efc97b4bec85f674570f878919cb72456745Havoc Pennington          goto out;
4248027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
4258027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4268027efc97b4bec85f674570f878919cb72456745Havoc Pennington#define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client")
4278027efc97b4bec85f674570f878919cb72456745Havoc Pennington      switch (_dbus_auth_do_work (transport->auth))
4288027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
4298027efc97b4bec85f674570f878919cb72456745Havoc Pennington        case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
4308027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose (" %s auth state: waiting for input\n",
4318027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         TRANSPORT_SIDE (transport));
4328027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (!do_reading || !read_data_into_auth (transport, &oom))
4338027efc97b4bec85f674570f878919cb72456745Havoc Pennington            goto out;
4348027efc97b4bec85f674570f878919cb72456745Havoc Pennington          break;
4358027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4368027efc97b4bec85f674570f878919cb72456745Havoc Pennington        case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
4378027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose (" %s auth state: waiting for memory\n",
4388027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         TRANSPORT_SIDE (transport));
4398027efc97b4bec85f674570f878919cb72456745Havoc Pennington          oom = TRUE;
4408027efc97b4bec85f674570f878919cb72456745Havoc Pennington          goto out;
4418027efc97b4bec85f674570f878919cb72456745Havoc Pennington          break;
4428027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4438027efc97b4bec85f674570f878919cb72456745Havoc Pennington        case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
4448027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose (" %s auth state: bytes to send\n",
4458027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         TRANSPORT_SIDE (transport));
4468027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (!do_writing || !write_data_from_auth (transport))
4478027efc97b4bec85f674570f878919cb72456745Havoc Pennington            goto out;
4488027efc97b4bec85f674570f878919cb72456745Havoc Pennington          break;
4498027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4508027efc97b4bec85f674570f878919cb72456745Havoc Pennington        case DBUS_AUTH_STATE_NEED_DISCONNECT:
4518027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose (" %s auth state: need to disconnect\n",
4528027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         TRANSPORT_SIDE (transport));
4538027efc97b4bec85f674570f878919cb72456745Havoc Pennington          do_io_error (transport);
4548027efc97b4bec85f674570f878919cb72456745Havoc Pennington          break;
4558027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4568027efc97b4bec85f674570f878919cb72456745Havoc Pennington        case DBUS_AUTH_STATE_AUTHENTICATED:
4578027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose (" %s auth state: authenticated\n",
4588027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         TRANSPORT_SIDE (transport));
4598027efc97b4bec85f674570f878919cb72456745Havoc Pennington          break;
4608027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
4618027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
4628027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4638027efc97b4bec85f674570f878919cb72456745Havoc Pennington out:
4648027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (auth_completed)
4658027efc97b4bec85f674570f878919cb72456745Havoc Pennington    *auth_completed = (orig_auth_state != _dbus_transport_get_is_authenticated (transport));
4668027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4678027efc97b4bec85f674570f878919cb72456745Havoc Pennington  check_read_watch (transport);
4688027efc97b4bec85f674570f878919cb72456745Havoc Pennington  check_write_watch (transport);
4698027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_transport_unref (transport);
4708027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4718027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (oom)
4728027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return FALSE;
4738027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else
4748027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return TRUE;
4758027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
4768027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4778027efc97b4bec85f674570f878919cb72456745Havoc Pennington/* returns false on oom */
4788027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic dbus_bool_t
4798027efc97b4bec85f674570f878919cb72456745Havoc Penningtondo_writing (DBusTransport *transport)
4808027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
4818027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int total;
4828027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
4838027efc97b4bec85f674570f878919cb72456745Havoc Pennington  dbus_bool_t oom;
4848027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4858027efc97b4bec85f674570f878919cb72456745Havoc Pennington  /* No messages without authentication! */
4868027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_transport_get_is_authenticated (transport))
4878027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
4888027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose ("Not authenticated, not writing anything\n");
4898027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return TRUE;
4908027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
4918027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4928027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (transport->disconnected)
4938027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
4948027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose ("Not connected, not writing anything\n");
4958027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return TRUE;
4968027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
4978027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4988027efc97b4bec85f674570f878919cb72456745Havoc Pennington#if 1
4998027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n",
5008027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 _dbus_connection_has_messages_to_send_unlocked (transport->connection),
5018027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 socket_transport->fd);
5028027efc97b4bec85f674570f878919cb72456745Havoc Pennington#endif
5038027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5048027efc97b4bec85f674570f878919cb72456745Havoc Pennington  oom = FALSE;
5058027efc97b4bec85f674570f878919cb72456745Havoc Pennington  total = 0;
5068027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5078027efc97b4bec85f674570f878919cb72456745Havoc Pennington  while (!transport->disconnected &&
5088027efc97b4bec85f674570f878919cb72456745Havoc Pennington         _dbus_connection_has_messages_to_send_unlocked (transport->connection))
5098027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
5108027efc97b4bec85f674570f878919cb72456745Havoc Pennington      int bytes_written;
5118027efc97b4bec85f674570f878919cb72456745Havoc Pennington      DBusMessage *message;
5128027efc97b4bec85f674570f878919cb72456745Havoc Pennington      const DBusString *header;
5138027efc97b4bec85f674570f878919cb72456745Havoc Pennington      const DBusString *body;
5148027efc97b4bec85f674570f878919cb72456745Havoc Pennington      int header_len, body_len;
5158027efc97b4bec85f674570f878919cb72456745Havoc Pennington      int total_bytes_to_write;
5168027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5178027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (total > socket_transport->max_bytes_written_per_iteration)
5188027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
5198027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
5208027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         total, socket_transport->max_bytes_written_per_iteration);
5218027efc97b4bec85f674570f878919cb72456745Havoc Pennington          goto out;
5228027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
5238027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5248027efc97b4bec85f674570f878919cb72456745Havoc Pennington      message = _dbus_connection_get_message_to_send (transport->connection);
5258027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_assert (message != NULL);
5268027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_message_lock (message);
5278027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5288027efc97b4bec85f674570f878919cb72456745Havoc Pennington#if 0
5298027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose ("writing message %p\n", message);
5308027efc97b4bec85f674570f878919cb72456745Havoc Pennington#endif
5318027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5328027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_message_get_network_data (message,
5338027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                      &header, &body);
5348027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5358027efc97b4bec85f674570f878919cb72456745Havoc Pennington      header_len = _dbus_string_get_length (header);
5368027efc97b4bec85f674570f878919cb72456745Havoc Pennington      body_len = _dbus_string_get_length (body);
5378027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5388027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (_dbus_auth_needs_encoding (transport->auth))
5398027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
5408027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (_dbus_string_get_length (&socket_transport->encoded_outgoing) == 0)
5418027efc97b4bec85f674570f878919cb72456745Havoc Pennington            {
5428027efc97b4bec85f674570f878919cb72456745Havoc Pennington              if (!_dbus_auth_encode_data (transport->auth,
5438027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                           header, &socket_transport->encoded_outgoing))
5448027efc97b4bec85f674570f878919cb72456745Havoc Pennington                {
5458027efc97b4bec85f674570f878919cb72456745Havoc Pennington                  oom = TRUE;
5468027efc97b4bec85f674570f878919cb72456745Havoc Pennington                  goto out;
5478027efc97b4bec85f674570f878919cb72456745Havoc Pennington                }
5488027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5498027efc97b4bec85f674570f878919cb72456745Havoc Pennington              if (!_dbus_auth_encode_data (transport->auth,
5508027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                           body, &socket_transport->encoded_outgoing))
5518027efc97b4bec85f674570f878919cb72456745Havoc Pennington                {
5528027efc97b4bec85f674570f878919cb72456745Havoc Pennington                  _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
5538027efc97b4bec85f674570f878919cb72456745Havoc Pennington                  oom = TRUE;
5548027efc97b4bec85f674570f878919cb72456745Havoc Pennington                  goto out;
5558027efc97b4bec85f674570f878919cb72456745Havoc Pennington                }
5568027efc97b4bec85f674570f878919cb72456745Havoc Pennington            }
5578027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5588027efc97b4bec85f674570f878919cb72456745Havoc Pennington          total_bytes_to_write = _dbus_string_get_length (&socket_transport->encoded_outgoing);
5598027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5608027efc97b4bec85f674570f878919cb72456745Havoc Pennington#if 0
5618027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("encoded message is %d bytes\n",
5628027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         total_bytes_to_write);
5638027efc97b4bec85f674570f878919cb72456745Havoc Pennington#endif
5648027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5658027efc97b4bec85f674570f878919cb72456745Havoc Pennington          bytes_written =
5668027efc97b4bec85f674570f878919cb72456745Havoc Pennington            _dbus_write_socket (socket_transport->fd,
5678027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                &socket_transport->encoded_outgoing,
5688027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                socket_transport->message_bytes_written,
5698027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                total_bytes_to_write - socket_transport->message_bytes_written);
5708027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
5718027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
5728027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
5738027efc97b4bec85f674570f878919cb72456745Havoc Pennington          total_bytes_to_write = header_len + body_len;
5748027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5758027efc97b4bec85f674570f878919cb72456745Havoc Pennington#if 0
5768027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("message is %d bytes\n",
5778027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         total_bytes_to_write);
5788027efc97b4bec85f674570f878919cb72456745Havoc Pennington#endif
5798027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5808027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (socket_transport->message_bytes_written < header_len)
5818027efc97b4bec85f674570f878919cb72456745Havoc Pennington            {
5828027efc97b4bec85f674570f878919cb72456745Havoc Pennington              bytes_written =
5838027efc97b4bec85f674570f878919cb72456745Havoc Pennington                _dbus_write_socket_two (socket_transport->fd,
5848027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                        header,
5858027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                        socket_transport->message_bytes_written,
5868027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                        header_len - socket_transport->message_bytes_written,
5878027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                        body,
5888027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                        0, body_len);
5898027efc97b4bec85f674570f878919cb72456745Havoc Pennington            }
5908027efc97b4bec85f674570f878919cb72456745Havoc Pennington          else
5918027efc97b4bec85f674570f878919cb72456745Havoc Pennington            {
5928027efc97b4bec85f674570f878919cb72456745Havoc Pennington              bytes_written =
5938027efc97b4bec85f674570f878919cb72456745Havoc Pennington                _dbus_write_socket (socket_transport->fd,
5948027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                    body,
5958027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                    (socket_transport->message_bytes_written - header_len),
5968027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                    body_len -
5978027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                    (socket_transport->message_bytes_written - header_len));
5988027efc97b4bec85f674570f878919cb72456745Havoc Pennington            }
5998027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
6008027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6018027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (bytes_written < 0)
6028027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
6038027efc97b4bec85f674570f878919cb72456745Havoc Pennington          /* EINTR already handled for us */
6048027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6058027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (errno == EAGAIN ||
6068027efc97b4bec85f674570f878919cb72456745Havoc Pennington              errno == EWOULDBLOCK)
6078027efc97b4bec85f674570f878919cb72456745Havoc Pennington            goto out;
6088027efc97b4bec85f674570f878919cb72456745Havoc Pennington          else
6098027efc97b4bec85f674570f878919cb72456745Havoc Pennington            {
6108027efc97b4bec85f674570f878919cb72456745Havoc Pennington              _dbus_verbose ("Error writing to remote app: %s\n",
6118027efc97b4bec85f674570f878919cb72456745Havoc Pennington                             _dbus_strerror (errno));
6128027efc97b4bec85f674570f878919cb72456745Havoc Pennington              do_io_error (transport);
6138027efc97b4bec85f674570f878919cb72456745Havoc Pennington              goto out;
6148027efc97b4bec85f674570f878919cb72456745Havoc Pennington            }
6158027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
6168027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
6178027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
6188027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
6198027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         total_bytes_to_write);
6208027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6218027efc97b4bec85f674570f878919cb72456745Havoc Pennington          total += bytes_written;
6228027efc97b4bec85f674570f878919cb72456745Havoc Pennington          socket_transport->message_bytes_written += bytes_written;
6238027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6248027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_assert (socket_transport->message_bytes_written <=
6258027efc97b4bec85f674570f878919cb72456745Havoc Pennington                        total_bytes_to_write);
6268027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6278027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (socket_transport->message_bytes_written == total_bytes_to_write)
6288027efc97b4bec85f674570f878919cb72456745Havoc Pennington            {
6298027efc97b4bec85f674570f878919cb72456745Havoc Pennington              socket_transport->message_bytes_written = 0;
6308027efc97b4bec85f674570f878919cb72456745Havoc Pennington              _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
6318027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6328027efc97b4bec85f674570f878919cb72456745Havoc Pennington              _dbus_connection_message_sent (transport->connection,
6338027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                             message);
6348027efc97b4bec85f674570f878919cb72456745Havoc Pennington            }
6358027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
6368027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
6378027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6388027efc97b4bec85f674570f878919cb72456745Havoc Pennington out:
6398027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (oom)
6408027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return FALSE;
6418027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else
6428027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return TRUE;
6438027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
6448027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6458027efc97b4bec85f674570f878919cb72456745Havoc Pennington/* returns false on out-of-memory */
6468027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic dbus_bool_t
6478027efc97b4bec85f674570f878919cb72456745Havoc Penningtondo_reading (DBusTransport *transport)
6488027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
6498027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
6508027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusString *buffer;
6518027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int bytes_read;
6528027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int total;
6538027efc97b4bec85f674570f878919cb72456745Havoc Pennington  dbus_bool_t oom;
6548027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6558027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_verbose ("%s: fd = %d\n", _DBUS_FUNCTION_NAME,
6568027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 socket_transport->fd);
6578027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6588027efc97b4bec85f674570f878919cb72456745Havoc Pennington  /* No messages without authentication! */
6598027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_transport_get_is_authenticated (transport))
6608027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return TRUE;
6618027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6628027efc97b4bec85f674570f878919cb72456745Havoc Pennington  oom = FALSE;
6638027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6648027efc97b4bec85f674570f878919cb72456745Havoc Pennington  total = 0;
6658027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6668027efc97b4bec85f674570f878919cb72456745Havoc Pennington again:
6678027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6688027efc97b4bec85f674570f878919cb72456745Havoc Pennington  /* See if we've exceeded max messages and need to disable reading */
6698027efc97b4bec85f674570f878919cb72456745Havoc Pennington  check_read_watch (transport);
6708027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6718027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (total > socket_transport->max_bytes_read_per_iteration)
6728027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
6738027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
6748027efc97b4bec85f674570f878919cb72456745Havoc Pennington                     total, socket_transport->max_bytes_read_per_iteration);
6758027efc97b4bec85f674570f878919cb72456745Havoc Pennington      goto out;
6768027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
6778027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6788027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_assert (socket_transport->read_watch != NULL ||
6798027efc97b4bec85f674570f878919cb72456745Havoc Pennington                transport->disconnected);
6808027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6818027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (transport->disconnected)
6828027efc97b4bec85f674570f878919cb72456745Havoc Pennington    goto out;
6838027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6848027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!dbus_watch_get_enabled (socket_transport->read_watch))
6858027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return TRUE;
6868027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6878027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (_dbus_auth_needs_decoding (transport->auth))
6888027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
6898027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (_dbus_string_get_length (&socket_transport->encoded_incoming) > 0)
6908027efc97b4bec85f674570f878919cb72456745Havoc Pennington        bytes_read = _dbus_string_get_length (&socket_transport->encoded_incoming);
6918027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
6928027efc97b4bec85f674570f878919cb72456745Havoc Pennington        bytes_read = _dbus_read_socket (socket_transport->fd,
6938027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                        &socket_transport->encoded_incoming,
6948027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                        socket_transport->max_bytes_read_per_iteration);
6958027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6968027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_assert (_dbus_string_get_length (&socket_transport->encoded_incoming) ==
6978027efc97b4bec85f674570f878919cb72456745Havoc Pennington                    bytes_read);
6988027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6998027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (bytes_read > 0)
7008027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
7018027efc97b4bec85f674570f878919cb72456745Havoc Pennington          int orig_len;
7028027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7038027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_message_loader_get_buffer (transport->loader,
7048027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                           &buffer);
7058027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7068027efc97b4bec85f674570f878919cb72456745Havoc Pennington          orig_len = _dbus_string_get_length (buffer);
7078027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7088027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (!_dbus_auth_decode_data (transport->auth,
7098027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                       &socket_transport->encoded_incoming,
7108027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                       buffer))
7118027efc97b4bec85f674570f878919cb72456745Havoc Pennington            {
7128027efc97b4bec85f674570f878919cb72456745Havoc Pennington              _dbus_verbose ("Out of memory decoding incoming data\n");
7138027efc97b4bec85f674570f878919cb72456745Havoc Pennington              oom = TRUE;
7148027efc97b4bec85f674570f878919cb72456745Havoc Pennington              goto out;
7158027efc97b4bec85f674570f878919cb72456745Havoc Pennington            }
7168027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7178027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_message_loader_return_buffer (transport->loader,
7188027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                              buffer,
7198027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                              _dbus_string_get_length (buffer) - orig_len);
7208027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7218027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_string_set_length (&socket_transport->encoded_incoming, 0);
7228027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
7238027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
7248027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else
7258027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
7268027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_message_loader_get_buffer (transport->loader,
7278027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                       &buffer);
7288027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7298027efc97b4bec85f674570f878919cb72456745Havoc Pennington      bytes_read = _dbus_read_socket (socket_transport->fd,
7308027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                      buffer, socket_transport->max_bytes_read_per_iteration);
7318027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7328027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_message_loader_return_buffer (transport->loader,
7338027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                          buffer,
7348027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                          bytes_read < 0 ? 0 : bytes_read);
7358027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
7368027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7378027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (bytes_read < 0)
7388027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
7398027efc97b4bec85f674570f878919cb72456745Havoc Pennington      /* EINTR already handled for us */
7408027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7418027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (errno == ENOMEM)
7428027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
7438027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("Out of memory in read()/do_reading()\n");
7448027efc97b4bec85f674570f878919cb72456745Havoc Pennington          oom = TRUE;
7458027efc97b4bec85f674570f878919cb72456745Havoc Pennington          goto out;
7468027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
7478027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else if (errno == EAGAIN ||
7488027efc97b4bec85f674570f878919cb72456745Havoc Pennington               errno == EWOULDBLOCK)
7498027efc97b4bec85f674570f878919cb72456745Havoc Pennington        goto out;
7508027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
7518027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
7528027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("Error reading from remote app: %s\n",
7538027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         _dbus_strerror (errno));
7548027efc97b4bec85f674570f878919cb72456745Havoc Pennington          do_io_error (transport);
7558027efc97b4bec85f674570f878919cb72456745Havoc Pennington          goto out;
7568027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
7578027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
7588027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else if (bytes_read == 0)
7598027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
7608027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose ("Disconnected from remote app\n");
7618027efc97b4bec85f674570f878919cb72456745Havoc Pennington      do_io_error (transport);
7628027efc97b4bec85f674570f878919cb72456745Havoc Pennington      goto out;
7638027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
7648027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else
7658027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
7668027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose (" read %d bytes\n", bytes_read);
7678027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7688027efc97b4bec85f674570f878919cb72456745Havoc Pennington      total += bytes_read;
7698027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7708027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (!_dbus_transport_queue_messages (transport))
7718027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
7728027efc97b4bec85f674570f878919cb72456745Havoc Pennington          oom = TRUE;
7738027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
7748027efc97b4bec85f674570f878919cb72456745Havoc Pennington          goto out;
7758027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
7768027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7778027efc97b4bec85f674570f878919cb72456745Havoc Pennington      /* Try reading more data until we get EAGAIN and return, or
7788027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * exceed max bytes per iteration.  If in blocking mode of
7798027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * course we'll block instead of returning.
7808027efc97b4bec85f674570f878919cb72456745Havoc Pennington       */
7818027efc97b4bec85f674570f878919cb72456745Havoc Pennington      goto again;
7828027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
7838027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7848027efc97b4bec85f674570f878919cb72456745Havoc Pennington out:
7858027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (oom)
7868027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return FALSE;
7878027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else
7888027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return TRUE;
7898027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
7908027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7918027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic dbus_bool_t
7928027efc97b4bec85f674570f878919cb72456745Havoc Penningtonsocket_handle_watch (DBusTransport *transport,
7938027efc97b4bec85f674570f878919cb72456745Havoc Pennington                   DBusWatch     *watch,
7948027efc97b4bec85f674570f878919cb72456745Havoc Pennington                   unsigned int   flags)
7958027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
7968027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
7978027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7988027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_assert (watch == socket_transport->read_watch ||
7998027efc97b4bec85f674570f878919cb72456745Havoc Pennington                watch == socket_transport->write_watch);
8008027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_assert (watch != NULL);
8018027efc97b4bec85f674570f878919cb72456745Havoc Pennington
8028027efc97b4bec85f674570f878919cb72456745Havoc Pennington  /* Disconnect in case of an error.  In case of hangup do not
8038027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * disconnect the transport because data can still be in the buffer
8048027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * and do_reading may need several iteration to read it all (because
8058027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * of its max_bytes_read_per_iteration limit).  The condition where
8068027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * flags == HANGUP (without READABLE) probably never happen in fact.
8078027efc97b4bec85f674570f878919cb72456745Havoc Pennington   */
8088027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if ((flags & DBUS_WATCH_ERROR) ||
8098027efc97b4bec85f674570f878919cb72456745Havoc Pennington      ((flags & DBUS_WATCH_HANGUP) && !(flags & DBUS_WATCH_READABLE)))
8108027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
8118027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose ("Hang up or error on watch\n");
8128027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_transport_disconnect (transport);
8138027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return TRUE;
8148027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
8158027efc97b4bec85f674570f878919cb72456745Havoc Pennington
8168027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (watch == socket_transport->read_watch &&
8178027efc97b4bec85f674570f878919cb72456745Havoc Pennington      (flags & DBUS_WATCH_READABLE))
8188027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
8198027efc97b4bec85f674570f878919cb72456745Havoc Pennington      dbus_bool_t auth_finished;
8208027efc97b4bec85f674570f878919cb72456745Havoc Pennington#if 1
8218027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose ("handling read watch %p flags = %x\n",
8228027efc97b4bec85f674570f878919cb72456745Havoc Pennington                     watch, flags);
8238027efc97b4bec85f674570f878919cb72456745Havoc Pennington#endif
8248027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
8258027efc97b4bec85f674570f878919cb72456745Havoc Pennington        return FALSE;
8268027efc97b4bec85f674570f878919cb72456745Havoc Pennington
8278027efc97b4bec85f674570f878919cb72456745Havoc Pennington      /* We don't want to do a read immediately following
8288027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * a successful authentication.  This is so we
8298027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * have a chance to propagate the authentication
8308027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * state further up.  Specifically, we need to
8318027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * process any pending data from the auth object.
8328027efc97b4bec85f674570f878919cb72456745Havoc Pennington       */
8338027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (!auth_finished)
8348027efc97b4bec85f674570f878919cb72456745Havoc Pennington	{
8358027efc97b4bec85f674570f878919cb72456745Havoc Pennington	  if (!do_reading (transport))
8368027efc97b4bec85f674570f878919cb72456745Havoc Pennington	    {
8378027efc97b4bec85f674570f878919cb72456745Havoc Pennington	      _dbus_verbose ("no memory to read\n");
8388027efc97b4bec85f674570f878919cb72456745Havoc Pennington	      return FALSE;
8398027efc97b4bec85f674570f878919cb72456745Havoc Pennington	    }
8408027efc97b4bec85f674570f878919cb72456745Havoc Pennington	}
8418027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
8428027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
8438027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("Not reading anything since we just completed the authentication\n");
8448027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
8458027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
8468027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else if (watch == socket_transport->write_watch &&
8478027efc97b4bec85f674570f878919cb72456745Havoc Pennington           (flags & DBUS_WATCH_WRITABLE))
8488027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
8498027efc97b4bec85f674570f878919cb72456745Havoc Pennington#if 1
8508027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
8518027efc97b4bec85f674570f878919cb72456745Havoc Pennington                     _dbus_connection_has_messages_to_send_unlocked (transport->connection));
8528027efc97b4bec85f674570f878919cb72456745Havoc Pennington#endif
8538027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (!do_authentication (transport, FALSE, TRUE, NULL))
8548027efc97b4bec85f674570f878919cb72456745Havoc Pennington        return FALSE;
8558027efc97b4bec85f674570f878919cb72456745Havoc Pennington
8568027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (!do_writing (transport))
8578027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
8588027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("no memory to write\n");
8598027efc97b4bec85f674570f878919cb72456745Havoc Pennington          return FALSE;
8608027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
8618027efc97b4bec85f674570f878919cb72456745Havoc Pennington
8628027efc97b4bec85f674570f878919cb72456745Havoc Pennington      /* See if we still need the write watch */
8638027efc97b4bec85f674570f878919cb72456745Havoc Pennington      check_write_watch (transport);
8648027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
8658027efc97b4bec85f674570f878919cb72456745Havoc Pennington#ifdef DBUS_ENABLE_VERBOSE_MODE
8668027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else
8678027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
8688027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (watch == socket_transport->read_watch)
8698027efc97b4bec85f674570f878919cb72456745Havoc Pennington        _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
8708027efc97b4bec85f674570f878919cb72456745Havoc Pennington                       flags);
8718027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else if (watch == socket_transport->write_watch)
8728027efc97b4bec85f674570f878919cb72456745Havoc Pennington        _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
8738027efc97b4bec85f674570f878919cb72456745Havoc Pennington                       flags);
8748027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
8758027efc97b4bec85f674570f878919cb72456745Havoc Pennington        _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
8768027efc97b4bec85f674570f878919cb72456745Havoc Pennington                       watch, dbus_watch_get_fd (watch));
8778027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
8788027efc97b4bec85f674570f878919cb72456745Havoc Pennington#endif /* DBUS_ENABLE_VERBOSE_MODE */
8798027efc97b4bec85f674570f878919cb72456745Havoc Pennington
8808027efc97b4bec85f674570f878919cb72456745Havoc Pennington  return TRUE;
8818027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
8828027efc97b4bec85f674570f878919cb72456745Havoc Pennington
8838027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic void
8848027efc97b4bec85f674570f878919cb72456745Havoc Penningtonsocket_disconnect (DBusTransport *transport)
8858027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
8868027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
8878027efc97b4bec85f674570f878919cb72456745Havoc Pennington
8888027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
8898027efc97b4bec85f674570f878919cb72456745Havoc Pennington
8908027efc97b4bec85f674570f878919cb72456745Havoc Pennington  free_watches (transport);
8918027efc97b4bec85f674570f878919cb72456745Havoc Pennington
8928027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_close_socket (socket_transport->fd, NULL);
8938027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_transport->fd = -1;
8948027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
8958027efc97b4bec85f674570f878919cb72456745Havoc Pennington
8968027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic dbus_bool_t
8978027efc97b4bec85f674570f878919cb72456745Havoc Penningtonsocket_connection_set (DBusTransport *transport)
8988027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
8998027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
9008027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9018027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_watch_set_handler (socket_transport->write_watch,
9028027efc97b4bec85f674570f878919cb72456745Havoc Pennington                           _dbus_connection_handle_watch,
9038027efc97b4bec85f674570f878919cb72456745Havoc Pennington                           transport->connection, NULL);
9048027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9058027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_watch_set_handler (socket_transport->read_watch,
9068027efc97b4bec85f674570f878919cb72456745Havoc Pennington                           _dbus_connection_handle_watch,
9078027efc97b4bec85f674570f878919cb72456745Havoc Pennington                           transport->connection, NULL);
9088027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9098027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_connection_add_watch_unlocked (transport->connection,
9108027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                            socket_transport->write_watch))
9118027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return FALSE;
9128027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9138027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_connection_add_watch_unlocked (transport->connection,
9148027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                            socket_transport->read_watch))
9158027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
9168027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_connection_remove_watch_unlocked (transport->connection,
9178027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                              socket_transport->write_watch);
9188027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return FALSE;
9198027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
9208027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9218027efc97b4bec85f674570f878919cb72456745Havoc Pennington  check_read_watch (transport);
9228027efc97b4bec85f674570f878919cb72456745Havoc Pennington  check_write_watch (transport);
9238027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9248027efc97b4bec85f674570f878919cb72456745Havoc Pennington  return TRUE;
9258027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
9268027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9278027efc97b4bec85f674570f878919cb72456745Havoc Pennington/**
9288027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @todo We need to have a way to wake up the select sleep if
9298027efc97b4bec85f674570f878919cb72456745Havoc Pennington * a new iteration request comes in with a flag (read/write) that
9308027efc97b4bec85f674570f878919cb72456745Havoc Pennington * we're not currently serving. Otherwise a call that just reads
9318027efc97b4bec85f674570f878919cb72456745Havoc Pennington * could block a write call forever (if there are no incoming
9328027efc97b4bec85f674570f878919cb72456745Havoc Pennington * messages).
9338027efc97b4bec85f674570f878919cb72456745Havoc Pennington */
9348027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic  void
9358027efc97b4bec85f674570f878919cb72456745Havoc Penningtonsocket_do_iteration (DBusTransport *transport,
9368027efc97b4bec85f674570f878919cb72456745Havoc Pennington                   unsigned int   flags,
9378027efc97b4bec85f674570f878919cb72456745Havoc Pennington                   int            timeout_milliseconds)
9388027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
9398027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
9408027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusPollFD poll_fd;
9418027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int poll_res;
9428027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int poll_timeout;
9438027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9448027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
9458027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 flags & DBUS_ITERATION_DO_READING ? "read" : "",
9468027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
9478027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 timeout_milliseconds,
9488027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 socket_transport->read_watch,
9498027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 socket_transport->write_watch,
9508027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 socket_transport->fd);
9518027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9528027efc97b4bec85f674570f878919cb72456745Havoc Pennington  /* the passed in DO_READING/DO_WRITING flags indicate whether to
9538027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * read/write messages, but regardless of those we may need to block
9548027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * for reading/writing to do auth.  But if we do reading for auth,
9558027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * we don't want to read any messages yet if not given DO_READING.
9568027efc97b4bec85f674570f878919cb72456745Havoc Pennington   */
9578027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9588027efc97b4bec85f674570f878919cb72456745Havoc Pennington  poll_fd.fd = socket_transport->fd;
9598027efc97b4bec85f674570f878919cb72456745Havoc Pennington  poll_fd.events = 0;
9608027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9618027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (_dbus_transport_get_is_authenticated (transport))
9628027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
9638027efc97b4bec85f674570f878919cb72456745Havoc Pennington      /* This is kind of a hack; if we have stuff to write, then try
9648027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * to avoid the poll. This is probably about a 5% speedup on an
9658027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * echo client/server.
9668027efc97b4bec85f674570f878919cb72456745Havoc Pennington       *
9678027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * If both reading and writing were requested, we want to avoid this
9688027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * since it could have funky effects:
9698027efc97b4bec85f674570f878919cb72456745Havoc Pennington       *   - both ends spinning waiting for the other one to read
9708027efc97b4bec85f674570f878919cb72456745Havoc Pennington       *     data so they can finish writing
9718027efc97b4bec85f674570f878919cb72456745Havoc Pennington       *   - prioritizing all writing ahead of reading
9728027efc97b4bec85f674570f878919cb72456745Havoc Pennington       */
9738027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if ((flags & DBUS_ITERATION_DO_WRITING) &&
9748027efc97b4bec85f674570f878919cb72456745Havoc Pennington          !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
9758027efc97b4bec85f674570f878919cb72456745Havoc Pennington          !transport->disconnected &&
9768027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_connection_has_messages_to_send_unlocked (transport->connection))
9778027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
9788027efc97b4bec85f674570f878919cb72456745Havoc Pennington          do_writing (transport);
9798027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9808027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (transport->disconnected ||
9818027efc97b4bec85f674570f878919cb72456745Havoc Pennington              !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
9828027efc97b4bec85f674570f878919cb72456745Havoc Pennington            goto out;
9838027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
9848027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9858027efc97b4bec85f674570f878919cb72456745Havoc Pennington      /* If we get here, we decided to do the poll() after all */
9868027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_assert (socket_transport->read_watch);
9878027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (flags & DBUS_ITERATION_DO_READING)
9888027efc97b4bec85f674570f878919cb72456745Havoc Pennington	poll_fd.events |= _DBUS_POLLIN;
9898027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9908027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_assert (socket_transport->write_watch);
9918027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (flags & DBUS_ITERATION_DO_WRITING)
9928027efc97b4bec85f674570f878919cb72456745Havoc Pennington        poll_fd.events |= _DBUS_POLLOUT;
9938027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
9948027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else
9958027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
9968027efc97b4bec85f674570f878919cb72456745Havoc Pennington      DBusAuthState auth_state;
9978027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9988027efc97b4bec85f674570f878919cb72456745Havoc Pennington      auth_state = _dbus_auth_do_work (transport->auth);
9998027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10008027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (transport->receive_credentials_pending ||
10018027efc97b4bec85f674570f878919cb72456745Havoc Pennington          auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
10028027efc97b4bec85f674570f878919cb72456745Havoc Pennington	poll_fd.events |= _DBUS_POLLIN;
10038027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10048027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (transport->send_credentials_pending ||
10058027efc97b4bec85f674570f878919cb72456745Havoc Pennington          auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
10068027efc97b4bec85f674570f878919cb72456745Havoc Pennington	poll_fd.events |= _DBUS_POLLOUT;
10078027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
10088027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10098027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (poll_fd.events)
10108027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
10118027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (flags & DBUS_ITERATION_BLOCK)
10128027efc97b4bec85f674570f878919cb72456745Havoc Pennington	poll_timeout = timeout_milliseconds;
10138027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
10148027efc97b4bec85f674570f878919cb72456745Havoc Pennington	poll_timeout = 0;
10158027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10168027efc97b4bec85f674570f878919cb72456745Havoc Pennington      /* For blocking selects we drop the connection lock here
10178027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * to avoid blocking out connection access during a potentially
10188027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * indefinite blocking call. The io path is still protected
10198027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * by the io_path_cond condvar, so we won't reenter this.
10208027efc97b4bec85f674570f878919cb72456745Havoc Pennington       */
10218027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (flags & DBUS_ITERATION_BLOCK)
10228027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
10238027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("unlock %s pre poll\n", _DBUS_FUNCTION_NAME);
10248027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_connection_unlock (transport->connection);
10258027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
10268027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10278027efc97b4bec85f674570f878919cb72456745Havoc Pennington    again:
10288027efc97b4bec85f674570f878919cb72456745Havoc Pennington      poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
10298027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10308027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (poll_res < 0 && errno == EINTR)
10318027efc97b4bec85f674570f878919cb72456745Havoc Pennington	goto again;
10328027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10338027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (flags & DBUS_ITERATION_BLOCK)
10348027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
10358027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("lock %s post poll\n", _DBUS_FUNCTION_NAME);
10368027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_connection_lock (transport->connection);
10378027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
10388027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10398027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (poll_res >= 0)
10408027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
10418027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (poll_res == 0)
10428027efc97b4bec85f674570f878919cb72456745Havoc Pennington            poll_fd.revents = 0; /* some concern that posix does not guarantee this;
10438027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                  * valgrind flags it as an error. though it probably
10448027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                  * is guaranteed on linux at least.
10458027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                  */
10468027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10478027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (poll_fd.revents & _DBUS_POLLERR)
10488027efc97b4bec85f674570f878919cb72456745Havoc Pennington            do_io_error (transport);
10498027efc97b4bec85f674570f878919cb72456745Havoc Pennington          else
10508027efc97b4bec85f674570f878919cb72456745Havoc Pennington            {
10518027efc97b4bec85f674570f878919cb72456745Havoc Pennington              dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
10528027efc97b4bec85f674570f878919cb72456745Havoc Pennington              dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
10538027efc97b4bec85f674570f878919cb72456745Havoc Pennington	      dbus_bool_t authentication_completed;
10548027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10558027efc97b4bec85f674570f878919cb72456745Havoc Pennington              _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
10568027efc97b4bec85f674570f878919cb72456745Havoc Pennington                             need_read, need_write);
10578027efc97b4bec85f674570f878919cb72456745Havoc Pennington              do_authentication (transport, need_read, need_write,
10588027efc97b4bec85f674570f878919cb72456745Havoc Pennington				 &authentication_completed);
10598027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10608027efc97b4bec85f674570f878919cb72456745Havoc Pennington	      /* See comment in socket_handle_watch. */
10618027efc97b4bec85f674570f878919cb72456745Havoc Pennington	      if (authentication_completed)
10628027efc97b4bec85f674570f878919cb72456745Havoc Pennington                goto out;
10638027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10648027efc97b4bec85f674570f878919cb72456745Havoc Pennington              if (need_read && (flags & DBUS_ITERATION_DO_READING))
10658027efc97b4bec85f674570f878919cb72456745Havoc Pennington                do_reading (transport);
10668027efc97b4bec85f674570f878919cb72456745Havoc Pennington              if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
10678027efc97b4bec85f674570f878919cb72456745Havoc Pennington                do_writing (transport);
10688027efc97b4bec85f674570f878919cb72456745Havoc Pennington            }
10698027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
10708027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
10718027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
10728027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("Error from _dbus_poll(): %s\n",
10738027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         _dbus_strerror (errno));
10748027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
10758027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
10768027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10778027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10788027efc97b4bec85f674570f878919cb72456745Havoc Pennington out:
10798027efc97b4bec85f674570f878919cb72456745Havoc Pennington  /* We need to install the write watch only if we did not
10808027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * successfully write everything. Note we need to be careful that we
10818027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * don't call check_write_watch *before* do_writing, since it's
10828027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * inefficient to add the write watch, and we can avoid it most of
10838027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * the time since we can write immediately.
10848027efc97b4bec85f674570f878919cb72456745Havoc Pennington   *
10858027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * However, we MUST always call check_write_watch(); DBusConnection code
10868027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * relies on the fact that running an iteration will notice that
10878027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * messages are pending.
10888027efc97b4bec85f674570f878919cb72456745Havoc Pennington   */
10898027efc97b4bec85f674570f878919cb72456745Havoc Pennington  check_write_watch (transport);
10908027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10918027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_verbose (" ... leaving do_iteration()\n");
10928027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
10938027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10948027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic void
10958027efc97b4bec85f674570f878919cb72456745Havoc Penningtonsocket_live_messages_changed (DBusTransport *transport)
10968027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
10978027efc97b4bec85f674570f878919cb72456745Havoc Pennington  /* See if we should look for incoming messages again */
10988027efc97b4bec85f674570f878919cb72456745Havoc Pennington  check_read_watch (transport);
10998027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
11008027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11018027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11028027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic dbus_bool_t
11038027efc97b4bec85f674570f878919cb72456745Havoc Penningtonsocket_get_socket_fd (DBusTransport *transport,
11048027efc97b4bec85f674570f878919cb72456745Havoc Pennington                      int           *fd_p)
11058027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
11068027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
11078027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11088027efc97b4bec85f674570f878919cb72456745Havoc Pennington  *fd_p = socket_transport->fd;
11098027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11108027efc97b4bec85f674570f878919cb72456745Havoc Pennington  return TRUE;
11118027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
11128027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11138027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic const DBusTransportVTable socket_vtable = {
11148027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_finalize,
11158027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_handle_watch,
11168027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_disconnect,
11178027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_connection_set,
11188027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_do_iteration,
11198027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_live_messages_changed,
11208027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_get_socket_fd
11218027efc97b4bec85f674570f878919cb72456745Havoc Pennington};
11228027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11238027efc97b4bec85f674570f878919cb72456745Havoc Pennington/**
11248027efc97b4bec85f674570f878919cb72456745Havoc Pennington * Creates a new transport for the given socket file descriptor.  The file
11258027efc97b4bec85f674570f878919cb72456745Havoc Pennington * descriptor must be nonblocking (use _dbus_set_fd_nonblocking() to
11268027efc97b4bec85f674570f878919cb72456745Havoc Pennington * make it so). This function is shared by various transports that
11278027efc97b4bec85f674570f878919cb72456745Havoc Pennington * boil down to a full duplex file descriptor.
11288027efc97b4bec85f674570f878919cb72456745Havoc Pennington *
11298027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @param fd the file descriptor.
11308027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @param server_guid non-#NULL if this transport is on the server side of a connection
11318027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @param address the transport's address
11328027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @returns the new transport, or #NULL if no memory.
11338027efc97b4bec85f674570f878919cb72456745Havoc Pennington */
11348027efc97b4bec85f674570f878919cb72456745Havoc PenningtonDBusTransport*
11358027efc97b4bec85f674570f878919cb72456745Havoc Pennington_dbus_transport_new_for_socket (int               fd,
11368027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                const DBusString *server_guid,
11378027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                const DBusString *address)
11388027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
11398027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport;
11408027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11418027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_transport = dbus_new0 (DBusTransportSocket, 1);
11428027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (socket_transport == NULL)
11438027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return NULL;
11448027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11458027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_string_init (&socket_transport->encoded_outgoing))
11468027efc97b4bec85f674570f878919cb72456745Havoc Pennington    goto failed_0;
11478027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11488027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_string_init (&socket_transport->encoded_incoming))
11498027efc97b4bec85f674570f878919cb72456745Havoc Pennington    goto failed_1;
11508027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11518027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_transport->write_watch = _dbus_watch_new (fd,
11528027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                                 DBUS_WATCH_WRITABLE,
11538027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                                 FALSE,
11548027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                                 NULL, NULL, NULL);
11558027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (socket_transport->write_watch == NULL)
11568027efc97b4bec85f674570f878919cb72456745Havoc Pennington    goto failed_2;
11578027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11588027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_transport->read_watch = _dbus_watch_new (fd,
11598027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                                DBUS_WATCH_READABLE,
11608027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                                FALSE,
11618027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                                NULL, NULL, NULL);
11628027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (socket_transport->read_watch == NULL)
11638027efc97b4bec85f674570f878919cb72456745Havoc Pennington    goto failed_3;
11648027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11658027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_transport_init_base (&socket_transport->base,
11668027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                  &socket_vtable,
11678027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                  server_guid, address))
11688027efc97b4bec85f674570f878919cb72456745Havoc Pennington    goto failed_4;
11698027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11708027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_transport->fd = fd;
11718027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_transport->message_bytes_written = 0;
11728027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11738027efc97b4bec85f674570f878919cb72456745Havoc Pennington  /* These values should probably be tunable or something. */
11748027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_transport->max_bytes_read_per_iteration = 2048;
11758027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_transport->max_bytes_written_per_iteration = 2048;
11768027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11778027efc97b4bec85f674570f878919cb72456745Havoc Pennington  return (DBusTransport*) socket_transport;
11788027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11798027efc97b4bec85f674570f878919cb72456745Havoc Pennington failed_4:
11808027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_watch_unref (socket_transport->read_watch);
11818027efc97b4bec85f674570f878919cb72456745Havoc Pennington failed_3:
11828027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_watch_unref (socket_transport->write_watch);
11838027efc97b4bec85f674570f878919cb72456745Havoc Pennington failed_2:
11848027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_string_free (&socket_transport->encoded_incoming);
11858027efc97b4bec85f674570f878919cb72456745Havoc Pennington failed_1:
11868027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_string_free (&socket_transport->encoded_outgoing);
11878027efc97b4bec85f674570f878919cb72456745Havoc Pennington failed_0:
11888027efc97b4bec85f674570f878919cb72456745Havoc Pennington  dbus_free (socket_transport);
11898027efc97b4bec85f674570f878919cb72456745Havoc Pennington  return NULL;
11908027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
11918027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11928027efc97b4bec85f674570f878919cb72456745Havoc Pennington/**
11938027efc97b4bec85f674570f878919cb72456745Havoc Pennington * Creates a new transport for the given hostname and port.
11948027efc97b4bec85f674570f878919cb72456745Havoc Pennington *
11958027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @param host the host to connect to
11968027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @param port the port to connect to
11978027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @param error location to store reason for failure.
11988027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @returns a new transport, or #NULL on failure.
11998027efc97b4bec85f674570f878919cb72456745Havoc Pennington */
12008027efc97b4bec85f674570f878919cb72456745Havoc PenningtonDBusTransport*
12018027efc97b4bec85f674570f878919cb72456745Havoc Pennington_dbus_transport_new_for_tcp_socket (const char     *host,
12028027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                    dbus_int32_t    port,
12038027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                    DBusError      *error)
12048027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
12058027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int fd;
12068027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransport *transport;
12078027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusString address;
12088027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12098027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
12108027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12118027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_string_init (&address))
12128027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
12138027efc97b4bec85f674570f878919cb72456745Havoc Pennington      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
12148027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return NULL;
12158027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
12168027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12178027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_string_append (&address, "tcp:"))
12188027efc97b4bec85f674570f878919cb72456745Havoc Pennington    goto error;
12198027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12208027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (host != NULL &&
12218027efc97b4bec85f674570f878919cb72456745Havoc Pennington       (!_dbus_string_append (&address, "host=") ||
12228027efc97b4bec85f674570f878919cb72456745Havoc Pennington        !_dbus_string_append (&address, host)))
12238027efc97b4bec85f674570f878919cb72456745Havoc Pennington    goto error;
12248027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12258027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_string_append (&address, ",port=") ||
12268027efc97b4bec85f674570f878919cb72456745Havoc Pennington      !_dbus_string_append_int (&address, port))
12278027efc97b4bec85f674570f878919cb72456745Havoc Pennington    goto error;
12288027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12298027efc97b4bec85f674570f878919cb72456745Havoc Pennington  fd = _dbus_connect_tcp_socket (host, port, error);
12308027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (fd < 0)
12318027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
12328027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _DBUS_ASSERT_ERROR_IS_SET (error);
12338027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_string_free (&address);
12348027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return NULL;
12358027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
12368027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12378027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_fd_set_close_on_exec (fd);
12388027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12398027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_verbose ("Successfully connected to tcp socket %s:%d\n",
12408027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 host, port);
12418027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12428027efc97b4bec85f674570f878919cb72456745Havoc Pennington  transport = _dbus_transport_new_for_socket (fd, NULL, &address);
12438027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (transport == NULL)
12448027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
12458027efc97b4bec85f674570f878919cb72456745Havoc Pennington      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
12468027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_close_socket (fd, NULL);
12478027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_string_free (&address);
12488027efc97b4bec85f674570f878919cb72456745Havoc Pennington      fd = -1;
12498027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
12508027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12518027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_string_free (&address);
12528027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12538027efc97b4bec85f674570f878919cb72456745Havoc Pennington  return transport;
12548027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12558027efc97b4bec85f674570f878919cb72456745Havoc Penningtonerror:
12568027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_string_free (&address);
12578027efc97b4bec85f674570f878919cb72456745Havoc Pennington  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
12588027efc97b4bec85f674570f878919cb72456745Havoc Pennington  return NULL;
12598027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
12608027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1261fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc PenningtonDBusTransportOpenResult
1262fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington_dbus_transport_open_socket(DBusAddressEntry  *entry,
1263fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington                            DBusTransport    **transport_p,
1264fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington                            DBusError         *error)
1265fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington{
1266fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington  const char *method;
1267fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington
1268fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington  method = dbus_address_entry_get_method (entry);
1269fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington  _dbus_assert (method != NULL);
1270fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington
1271fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington  if (strcmp (method, "tcp") == 0)
1272fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington    {
1273fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      const char *host = dbus_address_entry_get_value (entry, "host");
1274fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      const char *port = dbus_address_entry_get_value (entry, "port");
1275fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      DBusString  str;
1276fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      long lport;
1277fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      dbus_bool_t sresult;
1278fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington
1279fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      if (port == NULL)
1280fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington        {
1281fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington          _dbus_set_bad_address (error, "tcp", "port", NULL);
1282fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington          return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
1283fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington        }
1284fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington
1285fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      _dbus_string_init_const (&str, port);
1286fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      sresult = _dbus_string_parse_int (&str, 0, &lport, NULL);
1287fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      _dbus_string_free (&str);
1288fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington
1289fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      if (sresult == FALSE || lport <= 0 || lport > 65535)
1290fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington        {
1291fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington          _dbus_set_bad_address (error, NULL, NULL,
1292fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington                                 "Port is not an integer between 0 and 65535");
1293fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington          return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
1294fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington        }
1295fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington
1296fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      *transport_p = _dbus_transport_new_for_tcp_socket (host, lport, error);
1297fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      if (*transport_p == NULL)
1298fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington        {
1299fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington          _DBUS_ASSERT_ERROR_IS_SET (error);
1300fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington          return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
1301fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington        }
1302fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      else
1303fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington        {
1304fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington          _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1305fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington          return DBUS_TRANSPORT_OPEN_OK;
1306fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington        }
1307fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington    }
1308fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington  else
1309fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington    {
1310fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1311fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
1312fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington    }
1313fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington}
1314fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington
13158027efc97b4bec85f674570f878919cb72456745Havoc Pennington/** @} */
13168027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1317