1d012387afef0ba02185ebe27bc6bb15551912e92Havoc Pennington/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
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
205baf2f856a9c6625993234855b07680da1c8916fTobias Mueller * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
218027efc97b4bec85f674570f878919cb72456745Havoc Pennington *
228027efc97b4bec85f674570f878919cb72456745Havoc Pennington */
238027efc97b4bec85f674570f878919cb72456745Havoc Pennington
24dbecdeabb20e0ce11121819c63373f0afba57c58Marcus Brinkmann#include <config.h>
258027efc97b4bec85f674570f878919cb72456745Havoc Pennington#include "dbus-internals.h"
268027efc97b4bec85f674570f878919cb72456745Havoc Pennington#include "dbus-connection-internal.h"
270617102b4b156e40591e7af2a936a1988ef4b4d7Frank Osterfeld#include "dbus-nonce.h"
288027efc97b4bec85f674570f878919cb72456745Havoc Pennington#include "dbus-transport-socket.h"
298027efc97b4bec85f674570f878919cb72456745Havoc Pennington#include "dbus-transport-protected.h"
308027efc97b4bec85f674570f878919cb72456745Havoc Pennington#include "dbus-watch.h"
3123832672266bb4ff23b66247c0cfa1a2ed0cc97bHavoc Pennington#include "dbus-credentials.h"
328027efc97b4bec85f674570f878919cb72456745Havoc Pennington
338027efc97b4bec85f674570f878919cb72456745Havoc Pennington/**
348027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @defgroup DBusTransportSocket DBusTransport implementations for sockets
358027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @ingroup  DBusInternals
368027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @brief Implementation details of DBusTransport on sockets
378027efc97b4bec85f674570f878919cb72456745Havoc Pennington *
388027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @{
398027efc97b4bec85f674570f878919cb72456745Havoc Pennington */
408027efc97b4bec85f674570f878919cb72456745Havoc Pennington
418027efc97b4bec85f674570f878919cb72456745Havoc Pennington/**
428027efc97b4bec85f674570f878919cb72456745Havoc Pennington * Opaque object representing a socket file descriptor transport.
438027efc97b4bec85f674570f878919cb72456745Havoc Pennington */
448027efc97b4bec85f674570f878919cb72456745Havoc Penningtontypedef struct DBusTransportSocket DBusTransportSocket;
458027efc97b4bec85f674570f878919cb72456745Havoc Pennington
468027efc97b4bec85f674570f878919cb72456745Havoc Pennington/**
478027efc97b4bec85f674570f878919cb72456745Havoc Pennington * Implementation details of DBusTransportSocket. All members are private.
488027efc97b4bec85f674570f878919cb72456745Havoc Pennington */
498027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstruct DBusTransportSocket
508027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
518027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransport base;                   /**< Parent instance */
528027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int fd;                               /**< File descriptor. */
538027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusWatch *read_watch;                /**< Watch for readability. */
548027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusWatch *write_watch;               /**< Watch for writability. */
558027efc97b4bec85f674570f878919cb72456745Havoc Pennington
568027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int max_bytes_read_per_iteration;     /**< To avoid blocking too long. */
578027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int max_bytes_written_per_iteration;  /**< To avoid blocking too long. */
588027efc97b4bec85f674570f878919cb72456745Havoc Pennington
598027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int message_bytes_written;            /**< Number of bytes of current
608027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                         *   outgoing message that have
618027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                         *   been written.
628027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                         */
638027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusString encoded_outgoing;          /**< Encoded version of current
648027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                         *   outgoing message.
658027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                         */
668027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusString encoded_incoming;          /**< Encoded version of current
678027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                         *   incoming data.
688027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                         */
698027efc97b4bec85f674570f878919cb72456745Havoc Pennington};
708027efc97b4bec85f674570f878919cb72456745Havoc Pennington
718027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic void
728027efc97b4bec85f674570f878919cb72456745Havoc Penningtonfree_watches (DBusTransport *transport)
738027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
748027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
758027efc97b4bec85f674570f878919cb72456745Havoc Pennington
76d5217348517e6b00a04e500ca460daf6cc928cd9Ralf Habacker  _dbus_verbose ("start\n");
778027efc97b4bec85f674570f878919cb72456745Havoc Pennington
788027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (socket_transport->read_watch)
798027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
808027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (transport->connection)
818027efc97b4bec85f674570f878919cb72456745Havoc Pennington        _dbus_connection_remove_watch_unlocked (transport->connection,
828027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                                socket_transport->read_watch);
838027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_watch_invalidate (socket_transport->read_watch);
848027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_watch_unref (socket_transport->read_watch);
858027efc97b4bec85f674570f878919cb72456745Havoc Pennington      socket_transport->read_watch = NULL;
868027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
878027efc97b4bec85f674570f878919cb72456745Havoc Pennington
888027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (socket_transport->write_watch)
898027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
908027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (transport->connection)
918027efc97b4bec85f674570f878919cb72456745Havoc Pennington        _dbus_connection_remove_watch_unlocked (transport->connection,
928027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                                socket_transport->write_watch);
938027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_watch_invalidate (socket_transport->write_watch);
948027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_watch_unref (socket_transport->write_watch);
958027efc97b4bec85f674570f878919cb72456745Havoc Pennington      socket_transport->write_watch = NULL;
968027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
978027efc97b4bec85f674570f878919cb72456745Havoc Pennington
98d5217348517e6b00a04e500ca460daf6cc928cd9Ralf Habacker  _dbus_verbose ("end\n");
998027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
1008027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1018027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic void
1028027efc97b4bec85f674570f878919cb72456745Havoc Penningtonsocket_finalize (DBusTransport *transport)
1038027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
1048027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1058027efc97b4bec85f674570f878919cb72456745Havoc Pennington
106d5217348517e6b00a04e500ca460daf6cc928cd9Ralf Habacker  _dbus_verbose ("\n");
1078027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1088027efc97b4bec85f674570f878919cb72456745Havoc Pennington  free_watches (transport);
1098027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1108027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_string_free (&socket_transport->encoded_outgoing);
1118027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_string_free (&socket_transport->encoded_incoming);
1128027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1138027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_transport_finalize_base (transport);
1148027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1158027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_assert (socket_transport->read_watch == NULL);
1168027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_assert (socket_transport->write_watch == NULL);
1178027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1188027efc97b4bec85f674570f878919cb72456745Havoc Pennington  dbus_free (transport);
1198027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
1208027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1218027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic void
1228027efc97b4bec85f674570f878919cb72456745Havoc Penningtoncheck_write_watch (DBusTransport *transport)
1238027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
1248027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1258027efc97b4bec85f674570f878919cb72456745Havoc Pennington  dbus_bool_t needed;
1268027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1278027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (transport->connection == NULL)
1288027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return;
1298027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1308027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (transport->disconnected)
1318027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
1328027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_assert (socket_transport->write_watch == NULL);
1338027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return;
1348027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
1358027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1368027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_transport_ref (transport);
1378027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1388027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (_dbus_transport_get_is_authenticated (transport))
1398027efc97b4bec85f674570f878919cb72456745Havoc Pennington    needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
1408027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else
1418027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
1428027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (transport->send_credentials_pending)
1438027efc97b4bec85f674570f878919cb72456745Havoc Pennington        needed = TRUE;
1448027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
1458027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
1468027efc97b4bec85f674570f878919cb72456745Havoc Pennington          DBusAuthState auth_state;
1478027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1488027efc97b4bec85f674570f878919cb72456745Havoc Pennington          auth_state = _dbus_auth_do_work (transport->auth);
1498027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1508027efc97b4bec85f674570f878919cb72456745Havoc Pennington          /* If we need memory we install the write watch just in case,
1518027efc97b4bec85f674570f878919cb72456745Havoc Pennington           * if there's no need for it, it will get de-installed
1528027efc97b4bec85f674570f878919cb72456745Havoc Pennington           * next time we try reading.
1538027efc97b4bec85f674570f878919cb72456745Havoc Pennington           */
1548027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND ||
1558027efc97b4bec85f674570f878919cb72456745Havoc Pennington              auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
1568027efc97b4bec85f674570f878919cb72456745Havoc Pennington            needed = TRUE;
1578027efc97b4bec85f674570f878919cb72456745Havoc Pennington          else
1588027efc97b4bec85f674570f878919cb72456745Havoc Pennington            needed = FALSE;
1598027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
1608027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
1618027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1628027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_verbose ("check_write_watch(): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
1638027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 needed, transport->connection, socket_transport->write_watch,
1648027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 socket_transport->fd,
1658027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
1668027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1678027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_connection_toggle_watch_unlocked (transport->connection,
1688027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                          socket_transport->write_watch,
1698027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                          needed);
1708027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1718027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_transport_unref (transport);
1728027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
1738027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1748027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic void
1758027efc97b4bec85f674570f878919cb72456745Havoc Penningtoncheck_read_watch (DBusTransport *transport)
1768027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
1778027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1788027efc97b4bec85f674570f878919cb72456745Havoc Pennington  dbus_bool_t need_read_watch;
1798027efc97b4bec85f674570f878919cb72456745Havoc Pennington
180d5217348517e6b00a04e500ca460daf6cc928cd9Ralf Habacker  _dbus_verbose ("fd = %d\n",socket_transport->fd);
1818027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1828027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (transport->connection == NULL)
1838027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return;
1848027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1858027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (transport->disconnected)
1868027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
1878027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_assert (socket_transport->read_watch == NULL);
1888027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return;
1898027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
1908027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1918027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_transport_ref (transport);
1928027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1938027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (_dbus_transport_get_is_authenticated (transport))
1948027efc97b4bec85f674570f878919cb72456745Havoc Pennington    need_read_watch =
195bfad32422f1f78bce4de1e88a4afb5cc295bb877Lennart Poettering      (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
196bfad32422f1f78bce4de1e88a4afb5cc295bb877Lennart Poettering      (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
1978027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else
1988027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
1998027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (transport->receive_credentials_pending)
2008027efc97b4bec85f674570f878919cb72456745Havoc Pennington        need_read_watch = TRUE;
2018027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
2028027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
2038027efc97b4bec85f674570f878919cb72456745Havoc Pennington          /* The reason to disable need_read_watch when not WAITING_FOR_INPUT
2048027efc97b4bec85f674570f878919cb72456745Havoc Pennington           * is to avoid spinning on the file descriptor when we're waiting
2058027efc97b4bec85f674570f878919cb72456745Havoc Pennington           * to write or for some other part of the auth process
2068027efc97b4bec85f674570f878919cb72456745Havoc Pennington           */
2078027efc97b4bec85f674570f878919cb72456745Havoc Pennington          DBusAuthState auth_state;
2088027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2098027efc97b4bec85f674570f878919cb72456745Havoc Pennington          auth_state = _dbus_auth_do_work (transport->auth);
2108027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2118027efc97b4bec85f674570f878919cb72456745Havoc Pennington          /* If we need memory we install the read watch just in case,
2128027efc97b4bec85f674570f878919cb72456745Havoc Pennington           * if there's no need for it, it will get de-installed
2138027efc97b4bec85f674570f878919cb72456745Havoc Pennington           * next time we try reading. If we're authenticated we
2148027efc97b4bec85f674570f878919cb72456745Havoc Pennington           * install it since we normally have it installed while
2158027efc97b4bec85f674570f878919cb72456745Havoc Pennington           * authenticated.
2168027efc97b4bec85f674570f878919cb72456745Havoc Pennington           */
2178027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT ||
2188027efc97b4bec85f674570f878919cb72456745Havoc Pennington              auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY ||
2198027efc97b4bec85f674570f878919cb72456745Havoc Pennington              auth_state == DBUS_AUTH_STATE_AUTHENTICATED)
2208027efc97b4bec85f674570f878919cb72456745Havoc Pennington            need_read_watch = TRUE;
2218027efc97b4bec85f674570f878919cb72456745Havoc Pennington          else
2228027efc97b4bec85f674570f878919cb72456745Havoc Pennington            need_read_watch = FALSE;
2238027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
2248027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
2258027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2268027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_verbose ("  setting read watch enabled = %d\n", need_read_watch);
2278027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_connection_toggle_watch_unlocked (transport->connection,
2288027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                          socket_transport->read_watch,
2298027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                          need_read_watch);
2308027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2318027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_transport_unref (transport);
2328027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
2338027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2348027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic void
2358027efc97b4bec85f674570f878919cb72456745Havoc Penningtondo_io_error (DBusTransport *transport)
2368027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
2378027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_transport_ref (transport);
2388027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_transport_disconnect (transport);
2398027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_transport_unref (transport);
2408027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
2418027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2428027efc97b4bec85f674570f878919cb72456745Havoc Pennington/* return value is whether we successfully read any new data. */
2438027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic dbus_bool_t
2448027efc97b4bec85f674570f878919cb72456745Havoc Penningtonread_data_into_auth (DBusTransport *transport,
2458027efc97b4bec85f674570f878919cb72456745Havoc Pennington                     dbus_bool_t   *oom)
2468027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
2478027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
2488027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusString *buffer;
2498027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int bytes_read;
2508027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2518027efc97b4bec85f674570f878919cb72456745Havoc Pennington  *oom = FALSE;
2528027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2538027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_auth_get_buffer (transport->auth, &buffer);
2548027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2558027efc97b4bec85f674570f878919cb72456745Havoc Pennington  bytes_read = _dbus_read_socket (socket_transport->fd,
2568027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                  buffer, socket_transport->max_bytes_read_per_iteration);
2578027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2588027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_auth_return_buffer (transport->auth, buffer,
2598027efc97b4bec85f674570f878919cb72456745Havoc Pennington                            bytes_read > 0 ? bytes_read : 0);
2608027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2618027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (bytes_read > 0)
2628027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
2638027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
2648027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2658027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return TRUE;
2668027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
2678027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else if (bytes_read < 0)
2688027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
2698027efc97b4bec85f674570f878919cb72456745Havoc Pennington      /* EINTR already handled for us */
2708027efc97b4bec85f674570f878919cb72456745Havoc Pennington
27143b944a0a6ea48e8a8b06ae3e638299f591cde8dHavoc Pennington      if (_dbus_get_is_errno_enomem ())
2728027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
2738027efc97b4bec85f674570f878919cb72456745Havoc Pennington          *oom = TRUE;
2748027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
27543b944a0a6ea48e8a8b06ae3e638299f591cde8dHavoc Pennington      else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
2768027efc97b4bec85f674570f878919cb72456745Havoc Pennington        ; /* do nothing, just return FALSE below */
2778027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
2788027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
2798027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("Error reading from remote app: %s\n",
28043b944a0a6ea48e8a8b06ae3e638299f591cde8dHavoc Pennington                         _dbus_strerror_from_errno ());
2818027efc97b4bec85f674570f878919cb72456745Havoc Pennington          do_io_error (transport);
2828027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
2838027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2848027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return FALSE;
2858027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
2868027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else
2878027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
2888027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_assert (bytes_read == 0);
2898027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2908027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose ("Disconnected from remote app\n");
2918027efc97b4bec85f674570f878919cb72456745Havoc Pennington      do_io_error (transport);
2928027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2938027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return FALSE;
2948027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
2958027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
2968027efc97b4bec85f674570f878919cb72456745Havoc Pennington
2978027efc97b4bec85f674570f878919cb72456745Havoc Pennington/* Return value is whether we successfully wrote any bytes */
2988027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic dbus_bool_t
2998027efc97b4bec85f674570f878919cb72456745Havoc Penningtonwrite_data_from_auth (DBusTransport *transport)
3008027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
3018027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
3028027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int bytes_written;
3038027efc97b4bec85f674570f878919cb72456745Havoc Pennington  const DBusString *buffer;
3048027efc97b4bec85f674570f878919cb72456745Havoc Pennington
3058027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_auth_get_bytes_to_send (transport->auth,
3068027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                     &buffer))
3078027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return FALSE;
3088027efc97b4bec85f674570f878919cb72456745Havoc Pennington
3098027efc97b4bec85f674570f878919cb72456745Havoc Pennington  bytes_written = _dbus_write_socket (socket_transport->fd,
3108027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                      buffer,
3118027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                      0, _dbus_string_get_length (buffer));
3128027efc97b4bec85f674570f878919cb72456745Havoc Pennington
3138027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (bytes_written > 0)
3148027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
3158027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_auth_bytes_sent (transport->auth, bytes_written);
3168027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return TRUE;
3178027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
3188027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else if (bytes_written < 0)
3198027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
3208027efc97b4bec85f674570f878919cb72456745Havoc Pennington      /* EINTR already handled for us */
3218027efc97b4bec85f674570f878919cb72456745Havoc Pennington
32243b944a0a6ea48e8a8b06ae3e638299f591cde8dHavoc Pennington      if (_dbus_get_is_errno_eagain_or_ewouldblock ())
3238027efc97b4bec85f674570f878919cb72456745Havoc Pennington        ;
3248027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
3258027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
3268027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("Error writing to remote app: %s\n",
32743b944a0a6ea48e8a8b06ae3e638299f591cde8dHavoc Pennington                         _dbus_strerror_from_errno ());
3288027efc97b4bec85f674570f878919cb72456745Havoc Pennington          do_io_error (transport);
3298027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
3308027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
3318027efc97b4bec85f674570f878919cb72456745Havoc Pennington
3328027efc97b4bec85f674570f878919cb72456745Havoc Pennington  return FALSE;
3338027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
3348027efc97b4bec85f674570f878919cb72456745Havoc Pennington
33523832672266bb4ff23b66247c0cfa1a2ed0cc97bHavoc Pennington/* FALSE on OOM */
33623832672266bb4ff23b66247c0cfa1a2ed0cc97bHavoc Penningtonstatic dbus_bool_t
3378027efc97b4bec85f674570f878919cb72456745Havoc Penningtonexchange_credentials (DBusTransport *transport,
3388027efc97b4bec85f674570f878919cb72456745Havoc Pennington                      dbus_bool_t    do_reading,
3398027efc97b4bec85f674570f878919cb72456745Havoc Pennington                      dbus_bool_t    do_writing)
3408027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
3418027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
342f55897af74ac072d3447e5cf513d0f4718b142c7Simon McVittie  DBusError error = DBUS_ERROR_INIT;
3438027efc97b4bec85f674570f878919cb72456745Havoc Pennington
344100bcd121242c131b55c68aecdacec19921b61d9John (J  _dbus_verbose ("exchange_credentials: do_reading = %d, do_writing = %d\n",
345100bcd121242c131b55c68aecdacec19921b61d9John (J                  do_reading, do_writing);
346100bcd121242c131b55c68aecdacec19921b61d9John (J
3478027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (do_writing && transport->send_credentials_pending)
3488027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
34923832672266bb4ff23b66247c0cfa1a2ed0cc97bHavoc Pennington      if (_dbus_send_credentials_socket (socket_transport->fd,
35023832672266bb4ff23b66247c0cfa1a2ed0cc97bHavoc Pennington                                         &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    {
364ded479fda43da9dbe5780d0a2b287b5b1dcac64eHavoc Pennington      /* FIXME this can fail due to IO error _or_ OOM, broken
365ded479fda43da9dbe5780d0a2b287b5b1dcac64eHavoc Pennington       * (somewhat tricky to fix since the OOM error can be set after
366ded479fda43da9dbe5780d0a2b287b5b1dcac64eHavoc Pennington       * we already read the credentials byte, so basically we need to
367ded479fda43da9dbe5780d0a2b287b5b1dcac64eHavoc Pennington       * separate reading the byte and storing it in the
368ded479fda43da9dbe5780d0a2b287b5b1dcac64eHavoc Pennington       * transport->credentials). Does not really matter for now
369ded479fda43da9dbe5780d0a2b287b5b1dcac64eHavoc Pennington       * because storing in credentials never actually fails on unix.
370ded479fda43da9dbe5780d0a2b287b5b1dcac64eHavoc Pennington       */
37123832672266bb4ff23b66247c0cfa1a2ed0cc97bHavoc Pennington      if (_dbus_read_credentials_socket (socket_transport->fd,
37223832672266bb4ff23b66247c0cfa1a2ed0cc97bHavoc Pennington                                         transport->credentials,
37323832672266bb4ff23b66247c0cfa1a2ed0cc97bHavoc Pennington                                         &error))
3748027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
3758027efc97b4bec85f674570f878919cb72456745Havoc Pennington          transport->receive_credentials_pending = FALSE;
3768027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
3778027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
3788027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
379100bcd121242c131b55c68aecdacec19921b61d9John (J          _dbus_verbose ("Failed to read credentials %s\n", error.message);
380100bcd121242c131b55c68aecdacec19921b61d9John (J          dbus_error_free (&error);
3818027efc97b4bec85f674570f878919cb72456745Havoc Pennington          do_io_error (transport);
3828027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
3838027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
3848027efc97b4bec85f674570f878919cb72456745Havoc Pennington
3858027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!(transport->send_credentials_pending ||
3868027efc97b4bec85f674570f878919cb72456745Havoc Pennington        transport->receive_credentials_pending))
3878027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
38823832672266bb4ff23b66247c0cfa1a2ed0cc97bHavoc Pennington      if (!_dbus_auth_set_credentials (transport->auth,
38923832672266bb4ff23b66247c0cfa1a2ed0cc97bHavoc Pennington                                       transport->credentials))
39023832672266bb4ff23b66247c0cfa1a2ed0cc97bHavoc Pennington        return FALSE;
3918027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
39223832672266bb4ff23b66247c0cfa1a2ed0cc97bHavoc Pennington
39323832672266bb4ff23b66247c0cfa1a2ed0cc97bHavoc Pennington  return TRUE;
3948027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
3958027efc97b4bec85f674570f878919cb72456745Havoc Pennington
3968027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic dbus_bool_t
3978027efc97b4bec85f674570f878919cb72456745Havoc Penningtondo_authentication (DBusTransport *transport,
3988027efc97b4bec85f674570f878919cb72456745Havoc Pennington                   dbus_bool_t    do_reading,
3998027efc97b4bec85f674570f878919cb72456745Havoc Pennington                   dbus_bool_t    do_writing,
4008027efc97b4bec85f674570f878919cb72456745Havoc Pennington		   dbus_bool_t   *auth_completed)
4018027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
4028027efc97b4bec85f674570f878919cb72456745Havoc Pennington  dbus_bool_t oom;
4038027efc97b4bec85f674570f878919cb72456745Havoc Pennington  dbus_bool_t orig_auth_state;
4048027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4058027efc97b4bec85f674570f878919cb72456745Havoc Pennington  oom = FALSE;
4068027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4078027efc97b4bec85f674570f878919cb72456745Havoc Pennington  orig_auth_state = _dbus_transport_get_is_authenticated (transport);
4088027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4098027efc97b4bec85f674570f878919cb72456745Havoc Pennington  /* This is essential to avoid the check_write_watch() at the end,
4108027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * we don't want to add a write watch in do_iteration before
4118027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * we try writing and get EAGAIN
4128027efc97b4bec85f674570f878919cb72456745Havoc Pennington   */
4138027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (orig_auth_state)
4148027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
4158027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (auth_completed)
4168027efc97b4bec85f674570f878919cb72456745Havoc Pennington        *auth_completed = FALSE;
4178027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return TRUE;
4188027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
4198027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4208027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_transport_ref (transport);
4218027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4228027efc97b4bec85f674570f878919cb72456745Havoc Pennington  while (!_dbus_transport_get_is_authenticated (transport) &&
4238027efc97b4bec85f674570f878919cb72456745Havoc Pennington         _dbus_transport_get_is_connected (transport))
4248027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
42523832672266bb4ff23b66247c0cfa1a2ed0cc97bHavoc Pennington      if (!exchange_credentials (transport, do_reading, do_writing))
42623832672266bb4ff23b66247c0cfa1a2ed0cc97bHavoc Pennington        {
42723832672266bb4ff23b66247c0cfa1a2ed0cc97bHavoc Pennington          /* OOM */
42823832672266bb4ff23b66247c0cfa1a2ed0cc97bHavoc Pennington          oom = TRUE;
42923832672266bb4ff23b66247c0cfa1a2ed0cc97bHavoc Pennington          goto out;
43023832672266bb4ff23b66247c0cfa1a2ed0cc97bHavoc Pennington        }
4318027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4328027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (transport->send_credentials_pending ||
4338027efc97b4bec85f674570f878919cb72456745Havoc Pennington          transport->receive_credentials_pending)
4348027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
4358027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
4368027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         transport->send_credentials_pending,
4378027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         transport->receive_credentials_pending);
4388027efc97b4bec85f674570f878919cb72456745Havoc Pennington          goto out;
4398027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
4408027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4418027efc97b4bec85f674570f878919cb72456745Havoc Pennington#define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client")
4428027efc97b4bec85f674570f878919cb72456745Havoc Pennington      switch (_dbus_auth_do_work (transport->auth))
4438027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
4448027efc97b4bec85f674570f878919cb72456745Havoc Pennington        case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
4458027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose (" %s auth state: waiting for input\n",
4468027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         TRANSPORT_SIDE (transport));
4478027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (!do_reading || !read_data_into_auth (transport, &oom))
4488027efc97b4bec85f674570f878919cb72456745Havoc Pennington            goto out;
4498027efc97b4bec85f674570f878919cb72456745Havoc Pennington          break;
4508027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4518027efc97b4bec85f674570f878919cb72456745Havoc Pennington        case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
4528027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose (" %s auth state: waiting for memory\n",
4538027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         TRANSPORT_SIDE (transport));
4548027efc97b4bec85f674570f878919cb72456745Havoc Pennington          oom = TRUE;
4558027efc97b4bec85f674570f878919cb72456745Havoc Pennington          goto out;
4568027efc97b4bec85f674570f878919cb72456745Havoc Pennington          break;
4578027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4588027efc97b4bec85f674570f878919cb72456745Havoc Pennington        case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
4598027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose (" %s auth state: bytes to send\n",
4608027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         TRANSPORT_SIDE (transport));
4618027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (!do_writing || !write_data_from_auth (transport))
4628027efc97b4bec85f674570f878919cb72456745Havoc Pennington            goto out;
4638027efc97b4bec85f674570f878919cb72456745Havoc Pennington          break;
4648027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4658027efc97b4bec85f674570f878919cb72456745Havoc Pennington        case DBUS_AUTH_STATE_NEED_DISCONNECT:
4668027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose (" %s auth state: need to disconnect\n",
4678027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         TRANSPORT_SIDE (transport));
4688027efc97b4bec85f674570f878919cb72456745Havoc Pennington          do_io_error (transport);
4698027efc97b4bec85f674570f878919cb72456745Havoc Pennington          break;
4708027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4718027efc97b4bec85f674570f878919cb72456745Havoc Pennington        case DBUS_AUTH_STATE_AUTHENTICATED:
4728027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose (" %s auth state: authenticated\n",
4738027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         TRANSPORT_SIDE (transport));
4748027efc97b4bec85f674570f878919cb72456745Havoc Pennington          break;
4758027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
4768027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
4778027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4788027efc97b4bec85f674570f878919cb72456745Havoc Pennington out:
4798027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (auth_completed)
4808027efc97b4bec85f674570f878919cb72456745Havoc Pennington    *auth_completed = (orig_auth_state != _dbus_transport_get_is_authenticated (transport));
4818027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4828027efc97b4bec85f674570f878919cb72456745Havoc Pennington  check_read_watch (transport);
4838027efc97b4bec85f674570f878919cb72456745Havoc Pennington  check_write_watch (transport);
4848027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_transport_unref (transport);
4858027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4868027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (oom)
4878027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return FALSE;
4888027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else
4898027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return TRUE;
4908027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
4918027efc97b4bec85f674570f878919cb72456745Havoc Pennington
4928027efc97b4bec85f674570f878919cb72456745Havoc Pennington/* returns false on oom */
4938027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic dbus_bool_t
4948027efc97b4bec85f674570f878919cb72456745Havoc Penningtondo_writing (DBusTransport *transport)
4958027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
4968027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int total;
4978027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
4988027efc97b4bec85f674570f878919cb72456745Havoc Pennington  dbus_bool_t oom;
4998027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5008027efc97b4bec85f674570f878919cb72456745Havoc Pennington  /* No messages without authentication! */
5018027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_transport_get_is_authenticated (transport))
5028027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
5038027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose ("Not authenticated, not writing anything\n");
5048027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return TRUE;
5058027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
5068027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5078027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (transport->disconnected)
5088027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
5098027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose ("Not connected, not writing anything\n");
5108027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return TRUE;
5118027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
5128027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5138027efc97b4bec85f674570f878919cb72456745Havoc Pennington#if 1
5148027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n",
5158027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 _dbus_connection_has_messages_to_send_unlocked (transport->connection),
5168027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 socket_transport->fd);
5178027efc97b4bec85f674570f878919cb72456745Havoc Pennington#endif
5188027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5198027efc97b4bec85f674570f878919cb72456745Havoc Pennington  oom = FALSE;
5208027efc97b4bec85f674570f878919cb72456745Havoc Pennington  total = 0;
5218027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5228027efc97b4bec85f674570f878919cb72456745Havoc Pennington  while (!transport->disconnected &&
5238027efc97b4bec85f674570f878919cb72456745Havoc Pennington         _dbus_connection_has_messages_to_send_unlocked (transport->connection))
5248027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
5258027efc97b4bec85f674570f878919cb72456745Havoc Pennington      int bytes_written;
5268027efc97b4bec85f674570f878919cb72456745Havoc Pennington      DBusMessage *message;
5278027efc97b4bec85f674570f878919cb72456745Havoc Pennington      const DBusString *header;
5288027efc97b4bec85f674570f878919cb72456745Havoc Pennington      const DBusString *body;
5298027efc97b4bec85f674570f878919cb72456745Havoc Pennington      int header_len, body_len;
5308027efc97b4bec85f674570f878919cb72456745Havoc Pennington      int total_bytes_to_write;
5318027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5328027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (total > socket_transport->max_bytes_written_per_iteration)
5338027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
5348027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
5358027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         total, socket_transport->max_bytes_written_per_iteration);
5368027efc97b4bec85f674570f878919cb72456745Havoc Pennington          goto out;
5378027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
5388027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5398027efc97b4bec85f674570f878919cb72456745Havoc Pennington      message = _dbus_connection_get_message_to_send (transport->connection);
5408027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_assert (message != NULL);
54116a947eedb7f7f2951fff4ebbf301af7776aa8dfWilliam Lachance      dbus_message_lock (message);
5428027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5438027efc97b4bec85f674570f878919cb72456745Havoc Pennington#if 0
5448027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose ("writing message %p\n", message);
5458027efc97b4bec85f674570f878919cb72456745Havoc Pennington#endif
5468027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5478027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_message_get_network_data (message,
5488027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                      &header, &body);
5498027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5508027efc97b4bec85f674570f878919cb72456745Havoc Pennington      header_len = _dbus_string_get_length (header);
5518027efc97b4bec85f674570f878919cb72456745Havoc Pennington      body_len = _dbus_string_get_length (body);
5528027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5538027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (_dbus_auth_needs_encoding (transport->auth))
5548027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
555a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering          /* Does fd passing even make sense with encoded data? */
556a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering          _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport));
557a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering
5588027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (_dbus_string_get_length (&socket_transport->encoded_outgoing) == 0)
5598027efc97b4bec85f674570f878919cb72456745Havoc Pennington            {
5608027efc97b4bec85f674570f878919cb72456745Havoc Pennington              if (!_dbus_auth_encode_data (transport->auth,
5618027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                           header, &socket_transport->encoded_outgoing))
5628027efc97b4bec85f674570f878919cb72456745Havoc Pennington                {
5638027efc97b4bec85f674570f878919cb72456745Havoc Pennington                  oom = TRUE;
5648027efc97b4bec85f674570f878919cb72456745Havoc Pennington                  goto out;
5658027efc97b4bec85f674570f878919cb72456745Havoc Pennington                }
5668027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5678027efc97b4bec85f674570f878919cb72456745Havoc Pennington              if (!_dbus_auth_encode_data (transport->auth,
5688027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                           body, &socket_transport->encoded_outgoing))
5698027efc97b4bec85f674570f878919cb72456745Havoc Pennington                {
5708027efc97b4bec85f674570f878919cb72456745Havoc Pennington                  _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
5718027efc97b4bec85f674570f878919cb72456745Havoc Pennington                  oom = TRUE;
5728027efc97b4bec85f674570f878919cb72456745Havoc Pennington                  goto out;
5738027efc97b4bec85f674570f878919cb72456745Havoc Pennington                }
5748027efc97b4bec85f674570f878919cb72456745Havoc Pennington            }
5758027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5768027efc97b4bec85f674570f878919cb72456745Havoc Pennington          total_bytes_to_write = _dbus_string_get_length (&socket_transport->encoded_outgoing);
5778027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5788027efc97b4bec85f674570f878919cb72456745Havoc Pennington#if 0
5798027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("encoded message is %d bytes\n",
5808027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         total_bytes_to_write);
5818027efc97b4bec85f674570f878919cb72456745Havoc Pennington#endif
5828027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5838027efc97b4bec85f674570f878919cb72456745Havoc Pennington          bytes_written =
5848027efc97b4bec85f674570f878919cb72456745Havoc Pennington            _dbus_write_socket (socket_transport->fd,
5858027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                &socket_transport->encoded_outgoing,
5868027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                socket_transport->message_bytes_written,
5878027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                total_bytes_to_write - socket_transport->message_bytes_written);
5888027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
5898027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
5908027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
5918027efc97b4bec85f674570f878919cb72456745Havoc Pennington          total_bytes_to_write = header_len + body_len;
5928027efc97b4bec85f674570f878919cb72456745Havoc Pennington
5938027efc97b4bec85f674570f878919cb72456745Havoc Pennington#if 0
5948027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("message is %d bytes\n",
595a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                         total_bytes_to_write);
5968027efc97b4bec85f674570f878919cb72456745Havoc Pennington#endif
597a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering
598a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering#ifdef HAVE_UNIX_FD_PASSING
599c200e0304d6f53a0fd47f524386b02b27c0c45f6Lennart Poettering          if (socket_transport->message_bytes_written <= 0 && DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport))
6008027efc97b4bec85f674570f878919cb72456745Havoc Pennington            {
601a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering              /* Send the fds along with the first byte of the message */
602a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering              const int *unix_fds;
603a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering              unsigned n;
604a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering
605a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering              _dbus_message_get_unix_fds(message, &unix_fds, &n);
606a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering
6078027efc97b4bec85f674570f878919cb72456745Havoc Pennington              bytes_written =
608a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                _dbus_write_socket_with_unix_fds_two (socket_transport->fd,
609a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                                                      header,
610a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                                                      socket_transport->message_bytes_written,
611a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                                                      header_len - socket_transport->message_bytes_written,
612a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                                                      body,
613a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                                                      0, body_len,
614a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                                                      unix_fds,
615a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                                                      n);
616a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering
617a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering              if (bytes_written > 0 && n > 0)
618a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                _dbus_verbose("Wrote %i unix fds\n", n);
6198027efc97b4bec85f674570f878919cb72456745Havoc Pennington            }
6208027efc97b4bec85f674570f878919cb72456745Havoc Pennington          else
621a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering#endif
6228027efc97b4bec85f674570f878919cb72456745Havoc Pennington            {
623a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering              if (socket_transport->message_bytes_written < header_len)
624a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                {
625a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                  bytes_written =
626a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                    _dbus_write_socket_two (socket_transport->fd,
627a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                                            header,
628a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                                            socket_transport->message_bytes_written,
629a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                                            header_len - socket_transport->message_bytes_written,
630a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                                            body,
631a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                                            0, body_len);
632a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                }
633a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering              else
634a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                {
635a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                  bytes_written =
636a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                    _dbus_write_socket (socket_transport->fd,
637a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                                        body,
638a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                                        (socket_transport->message_bytes_written - header_len),
639a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                                        body_len -
640a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                                        (socket_transport->message_bytes_written - header_len));
641a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                }
6428027efc97b4bec85f674570f878919cb72456745Havoc Pennington            }
6438027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
6448027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6458027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (bytes_written < 0)
6468027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
6478027efc97b4bec85f674570f878919cb72456745Havoc Pennington          /* EINTR already handled for us */
6488027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6490e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters          /* For some discussion of why we also ignore EPIPE here, see
6500e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters           * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html
6510e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters           */
6520e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters
6530e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters          if (_dbus_get_is_errno_eagain_or_ewouldblock () || _dbus_get_is_errno_epipe ())
6548027efc97b4bec85f674570f878919cb72456745Havoc Pennington            goto out;
6558027efc97b4bec85f674570f878919cb72456745Havoc Pennington          else
6568027efc97b4bec85f674570f878919cb72456745Havoc Pennington            {
6578027efc97b4bec85f674570f878919cb72456745Havoc Pennington              _dbus_verbose ("Error writing to remote app: %s\n",
65843b944a0a6ea48e8a8b06ae3e638299f591cde8dHavoc Pennington                             _dbus_strerror_from_errno ());
6598027efc97b4bec85f674570f878919cb72456745Havoc Pennington              do_io_error (transport);
6608027efc97b4bec85f674570f878919cb72456745Havoc Pennington              goto out;
6618027efc97b4bec85f674570f878919cb72456745Havoc Pennington            }
6628027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
6638027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
6648027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
6658027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
6668027efc97b4bec85f674570f878919cb72456745Havoc Pennington                         total_bytes_to_write);
6678027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6688027efc97b4bec85f674570f878919cb72456745Havoc Pennington          total += bytes_written;
6698027efc97b4bec85f674570f878919cb72456745Havoc Pennington          socket_transport->message_bytes_written += bytes_written;
6708027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6718027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_assert (socket_transport->message_bytes_written <=
6728027efc97b4bec85f674570f878919cb72456745Havoc Pennington                        total_bytes_to_write);
6738027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6748027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (socket_transport->message_bytes_written == total_bytes_to_write)
6758027efc97b4bec85f674570f878919cb72456745Havoc Pennington            {
6768027efc97b4bec85f674570f878919cb72456745Havoc Pennington              socket_transport->message_bytes_written = 0;
6778027efc97b4bec85f674570f878919cb72456745Havoc Pennington              _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
6788c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie              _dbus_string_compact (&socket_transport->encoded_outgoing, 2048);
6798027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6808027efc97b4bec85f674570f878919cb72456745Havoc Pennington              _dbus_connection_message_sent (transport->connection,
6818027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                             message);
6828027efc97b4bec85f674570f878919cb72456745Havoc Pennington            }
6838027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
6848027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
6858027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6868027efc97b4bec85f674570f878919cb72456745Havoc Pennington out:
6878027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (oom)
6888027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return FALSE;
6898027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else
6908027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return TRUE;
6918027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
6928027efc97b4bec85f674570f878919cb72456745Havoc Pennington
6938027efc97b4bec85f674570f878919cb72456745Havoc Pennington/* returns false on out-of-memory */
6948027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic dbus_bool_t
6958027efc97b4bec85f674570f878919cb72456745Havoc Penningtondo_reading (DBusTransport *transport)
6968027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
6978027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
6988027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusString *buffer;
6998027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int bytes_read;
7008027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int total;
7018027efc97b4bec85f674570f878919cb72456745Havoc Pennington  dbus_bool_t oom;
7028027efc97b4bec85f674570f878919cb72456745Havoc Pennington
703d5217348517e6b00a04e500ca460daf6cc928cd9Ralf Habacker  _dbus_verbose ("fd = %d\n",socket_transport->fd);
7048027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7058027efc97b4bec85f674570f878919cb72456745Havoc Pennington  /* No messages without authentication! */
7068027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_transport_get_is_authenticated (transport))
7078027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return TRUE;
7088027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7098027efc97b4bec85f674570f878919cb72456745Havoc Pennington  oom = FALSE;
7108027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7118027efc97b4bec85f674570f878919cb72456745Havoc Pennington  total = 0;
7128027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7138027efc97b4bec85f674570f878919cb72456745Havoc Pennington again:
7148027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7158027efc97b4bec85f674570f878919cb72456745Havoc Pennington  /* See if we've exceeded max messages and need to disable reading */
7168027efc97b4bec85f674570f878919cb72456745Havoc Pennington  check_read_watch (transport);
7178027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7188027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (total > socket_transport->max_bytes_read_per_iteration)
7198027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
7208027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
7218027efc97b4bec85f674570f878919cb72456745Havoc Pennington                     total, socket_transport->max_bytes_read_per_iteration);
7228027efc97b4bec85f674570f878919cb72456745Havoc Pennington      goto out;
7238027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
7248027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7258027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_assert (socket_transport->read_watch != NULL ||
7268027efc97b4bec85f674570f878919cb72456745Havoc Pennington                transport->disconnected);
7278027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7288027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (transport->disconnected)
7298027efc97b4bec85f674570f878919cb72456745Havoc Pennington    goto out;
7308027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7318027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!dbus_watch_get_enabled (socket_transport->read_watch))
7328027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return TRUE;
7338027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7348027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (_dbus_auth_needs_decoding (transport->auth))
7358027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
736a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering      /* Does fd passing even make sense with encoded data? */
737a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering      _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport));
738a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering
7398027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (_dbus_string_get_length (&socket_transport->encoded_incoming) > 0)
7408027efc97b4bec85f674570f878919cb72456745Havoc Pennington        bytes_read = _dbus_string_get_length (&socket_transport->encoded_incoming);
7418027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
7428027efc97b4bec85f674570f878919cb72456745Havoc Pennington        bytes_read = _dbus_read_socket (socket_transport->fd,
7438027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                        &socket_transport->encoded_incoming,
7448027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                        socket_transport->max_bytes_read_per_iteration);
7458027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7468027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_assert (_dbus_string_get_length (&socket_transport->encoded_incoming) ==
7478027efc97b4bec85f674570f878919cb72456745Havoc Pennington                    bytes_read);
7488027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7498027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (bytes_read > 0)
7508027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
7518027efc97b4bec85f674570f878919cb72456745Havoc Pennington          int orig_len;
7528027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7538027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_message_loader_get_buffer (transport->loader,
7548027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                           &buffer);
7558027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7568027efc97b4bec85f674570f878919cb72456745Havoc Pennington          orig_len = _dbus_string_get_length (buffer);
7578027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7588027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (!_dbus_auth_decode_data (transport->auth,
7598027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                       &socket_transport->encoded_incoming,
7608027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                       buffer))
7618027efc97b4bec85f674570f878919cb72456745Havoc Pennington            {
7628027efc97b4bec85f674570f878919cb72456745Havoc Pennington              _dbus_verbose ("Out of memory decoding incoming data\n");
763c8e29a910b33911a5d695976a78ae3705819745fJohn (J              _dbus_message_loader_return_buffer (transport->loader,
764c8e29a910b33911a5d695976a78ae3705819745fJohn (J                                              buffer,
765c8e29a910b33911a5d695976a78ae3705819745fJohn (J                                              _dbus_string_get_length (buffer) - orig_len);
766c8e29a910b33911a5d695976a78ae3705819745fJohn (J
7678027efc97b4bec85f674570f878919cb72456745Havoc Pennington              oom = TRUE;
7688027efc97b4bec85f674570f878919cb72456745Havoc Pennington              goto out;
7698027efc97b4bec85f674570f878919cb72456745Havoc Pennington            }
7708027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7718027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_message_loader_return_buffer (transport->loader,
7728027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                              buffer,
7738027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                              _dbus_string_get_length (buffer) - orig_len);
7748027efc97b4bec85f674570f878919cb72456745Havoc Pennington
7758027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_string_set_length (&socket_transport->encoded_incoming, 0);
7768c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie          _dbus_string_compact (&socket_transport->encoded_incoming, 2048);
7778027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
7788027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
7798027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else
7808027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
7818027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_message_loader_get_buffer (transport->loader,
7828027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                       &buffer);
783a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering
784a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering#ifdef HAVE_UNIX_FD_PASSING
785c200e0304d6f53a0fd47f524386b02b27c0c45f6Lennart Poettering      if (DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport))
786a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering        {
787a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering          int *fds, n_fds;
788a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering
789a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering          if (!_dbus_message_loader_get_unix_fds(transport->loader, &fds, &n_fds))
790a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering            {
791a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering              _dbus_verbose ("Out of memory reading file descriptors\n");
792a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering              _dbus_message_loader_return_buffer (transport->loader, buffer, 0);
793a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering              oom = TRUE;
794a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering              goto out;
795a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering            }
796a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering
797a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering          bytes_read = _dbus_read_socket_with_unix_fds(socket_transport->fd,
798a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                                                       buffer,
799a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                                                       socket_transport->max_bytes_read_per_iteration,
800a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                                                       fds, &n_fds);
801a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering
802a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering          if (bytes_read >= 0 && n_fds > 0)
803a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering            _dbus_verbose("Read %i unix fds\n", n_fds);
804a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering
805a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering          _dbus_message_loader_return_unix_fds(transport->loader, fds, bytes_read < 0 ? 0 : n_fds);
806a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering        }
807a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering      else
808a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering#endif
809a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering        {
810a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering          bytes_read = _dbus_read_socket (socket_transport->fd,
811a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering                                          buffer, socket_transport->max_bytes_read_per_iteration);
812a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering        }
813a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering
8148027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_message_loader_return_buffer (transport->loader,
8158027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                          buffer,
8168027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                          bytes_read < 0 ? 0 : bytes_read);
8178027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
8188027efc97b4bec85f674570f878919cb72456745Havoc Pennington
8198027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (bytes_read < 0)
8208027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
8218027efc97b4bec85f674570f878919cb72456745Havoc Pennington      /* EINTR already handled for us */
8228027efc97b4bec85f674570f878919cb72456745Havoc Pennington
82343b944a0a6ea48e8a8b06ae3e638299f591cde8dHavoc Pennington      if (_dbus_get_is_errno_enomem ())
8248027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
8258027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("Out of memory in read()/do_reading()\n");
8268027efc97b4bec85f674570f878919cb72456745Havoc Pennington          oom = TRUE;
8278027efc97b4bec85f674570f878919cb72456745Havoc Pennington          goto out;
8288027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
82943b944a0a6ea48e8a8b06ae3e638299f591cde8dHavoc Pennington      else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
8308027efc97b4bec85f674570f878919cb72456745Havoc Pennington        goto out;
8318027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
8328027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
8338027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("Error reading from remote app: %s\n",
83443b944a0a6ea48e8a8b06ae3e638299f591cde8dHavoc Pennington                         _dbus_strerror_from_errno ());
8358027efc97b4bec85f674570f878919cb72456745Havoc Pennington          do_io_error (transport);
8368027efc97b4bec85f674570f878919cb72456745Havoc Pennington          goto out;
8378027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
8388027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
8398027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else if (bytes_read == 0)
8408027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
8418027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose ("Disconnected from remote app\n");
8428027efc97b4bec85f674570f878919cb72456745Havoc Pennington      do_io_error (transport);
8438027efc97b4bec85f674570f878919cb72456745Havoc Pennington      goto out;
8448027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
8458027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else
8468027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
8478027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose (" read %d bytes\n", bytes_read);
8488027efc97b4bec85f674570f878919cb72456745Havoc Pennington
8498027efc97b4bec85f674570f878919cb72456745Havoc Pennington      total += bytes_read;
8508027efc97b4bec85f674570f878919cb72456745Havoc Pennington
8518027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (!_dbus_transport_queue_messages (transport))
8528027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
8538027efc97b4bec85f674570f878919cb72456745Havoc Pennington          oom = TRUE;
8548027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
8558027efc97b4bec85f674570f878919cb72456745Havoc Pennington          goto out;
8568027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
8578027efc97b4bec85f674570f878919cb72456745Havoc Pennington
8588027efc97b4bec85f674570f878919cb72456745Havoc Pennington      /* Try reading more data until we get EAGAIN and return, or
8598027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * exceed max bytes per iteration.  If in blocking mode of
8608027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * course we'll block instead of returning.
8618027efc97b4bec85f674570f878919cb72456745Havoc Pennington       */
8628027efc97b4bec85f674570f878919cb72456745Havoc Pennington      goto again;
8638027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
8648027efc97b4bec85f674570f878919cb72456745Havoc Pennington
8658027efc97b4bec85f674570f878919cb72456745Havoc Pennington out:
8668027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (oom)
8678027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return FALSE;
8688027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else
8698027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return TRUE;
8708027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
8718027efc97b4bec85f674570f878919cb72456745Havoc Pennington
8728027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic dbus_bool_t
8730e36cdd54964c4012acec2bb8e598b85e82d2846Colin Waltersunix_error_with_read_to_come (DBusTransport *itransport,
8740e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters                              DBusWatch     *watch,
8750e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters                              unsigned int   flags)
8760e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters{
8770e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters  DBusTransportSocket *transport = (DBusTransportSocket *) itransport;
8780e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters
8790e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters  if (!(flags & DBUS_WATCH_HANGUP || flags & DBUS_WATCH_ERROR))
8800e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters    return FALSE;
8810e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters
8820e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters  /* If we have a read watch enabled ...
8830e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters     we -might have data incoming ... => handle the HANGUP there */
8840e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters  if (watch != transport->read_watch &&
8850e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters      _dbus_watch_get_enabled (transport->read_watch))
8860e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters    return FALSE;
8870e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters
8880e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters  return TRUE;
8890e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters}
8900e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters
8910e36cdd54964c4012acec2bb8e598b85e82d2846Colin Waltersstatic dbus_bool_t
8928027efc97b4bec85f674570f878919cb72456745Havoc Penningtonsocket_handle_watch (DBusTransport *transport,
8938027efc97b4bec85f674570f878919cb72456745Havoc Pennington                   DBusWatch     *watch,
8948027efc97b4bec85f674570f878919cb72456745Havoc Pennington                   unsigned int   flags)
8958027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
8968027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
8978027efc97b4bec85f674570f878919cb72456745Havoc Pennington
8988027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_assert (watch == socket_transport->read_watch ||
8998027efc97b4bec85f674570f878919cb72456745Havoc Pennington                watch == socket_transport->write_watch);
9008027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_assert (watch != NULL);
9018027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9020e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters  /* If we hit an error here on a write watch, don't disconnect the transport yet because data can
9030e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters   * still be in the buffer and do_reading may need several iteration to read
9040e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters   * it all (because of its max_bytes_read_per_iteration limit).
9058027efc97b4bec85f674570f878919cb72456745Havoc Pennington   */
9060e36cdd54964c4012acec2bb8e598b85e82d2846Colin Walters  if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags))
9078027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
9088027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose ("Hang up or error on watch\n");
9098027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_transport_disconnect (transport);
9108027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return TRUE;
9118027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
9128027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9138027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (watch == socket_transport->read_watch &&
9148027efc97b4bec85f674570f878919cb72456745Havoc Pennington      (flags & DBUS_WATCH_READABLE))
9158027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
9168027efc97b4bec85f674570f878919cb72456745Havoc Pennington      dbus_bool_t auth_finished;
9178027efc97b4bec85f674570f878919cb72456745Havoc Pennington#if 1
9188027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose ("handling read watch %p flags = %x\n",
9198027efc97b4bec85f674570f878919cb72456745Havoc Pennington                     watch, flags);
9208027efc97b4bec85f674570f878919cb72456745Havoc Pennington#endif
9218027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
9228027efc97b4bec85f674570f878919cb72456745Havoc Pennington        return FALSE;
9238027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9248027efc97b4bec85f674570f878919cb72456745Havoc Pennington      /* We don't want to do a read immediately following
9258027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * a successful authentication.  This is so we
9268027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * have a chance to propagate the authentication
9278027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * state further up.  Specifically, we need to
9288027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * process any pending data from the auth object.
9298027efc97b4bec85f674570f878919cb72456745Havoc Pennington       */
9308027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (!auth_finished)
9318027efc97b4bec85f674570f878919cb72456745Havoc Pennington	{
9328027efc97b4bec85f674570f878919cb72456745Havoc Pennington	  if (!do_reading (transport))
9338027efc97b4bec85f674570f878919cb72456745Havoc Pennington	    {
9348027efc97b4bec85f674570f878919cb72456745Havoc Pennington	      _dbus_verbose ("no memory to read\n");
9358027efc97b4bec85f674570f878919cb72456745Havoc Pennington	      return FALSE;
9368027efc97b4bec85f674570f878919cb72456745Havoc Pennington	    }
9378027efc97b4bec85f674570f878919cb72456745Havoc Pennington	}
9388027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
9398027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
9408027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("Not reading anything since we just completed the authentication\n");
9418027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
9428027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
9438027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else if (watch == socket_transport->write_watch &&
9448027efc97b4bec85f674570f878919cb72456745Havoc Pennington           (flags & DBUS_WATCH_WRITABLE))
9458027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
9468027efc97b4bec85f674570f878919cb72456745Havoc Pennington#if 1
9478027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
9488027efc97b4bec85f674570f878919cb72456745Havoc Pennington                     _dbus_connection_has_messages_to_send_unlocked (transport->connection));
9498027efc97b4bec85f674570f878919cb72456745Havoc Pennington#endif
9508027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (!do_authentication (transport, FALSE, TRUE, NULL))
9518027efc97b4bec85f674570f878919cb72456745Havoc Pennington        return FALSE;
9528027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9538027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (!do_writing (transport))
9548027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
9558027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("no memory to write\n");
9568027efc97b4bec85f674570f878919cb72456745Havoc Pennington          return FALSE;
9578027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
9588027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9598027efc97b4bec85f674570f878919cb72456745Havoc Pennington      /* See if we still need the write watch */
9608027efc97b4bec85f674570f878919cb72456745Havoc Pennington      check_write_watch (transport);
9618027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
9628027efc97b4bec85f674570f878919cb72456745Havoc Pennington#ifdef DBUS_ENABLE_VERBOSE_MODE
9638027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else
9648027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
9658027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (watch == socket_transport->read_watch)
9668027efc97b4bec85f674570f878919cb72456745Havoc Pennington        _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
9678027efc97b4bec85f674570f878919cb72456745Havoc Pennington                       flags);
9688027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else if (watch == socket_transport->write_watch)
9698027efc97b4bec85f674570f878919cb72456745Havoc Pennington        _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
9708027efc97b4bec85f674570f878919cb72456745Havoc Pennington                       flags);
9718027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
9728027efc97b4bec85f674570f878919cb72456745Havoc Pennington        _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
97398f19852078cf03f8b50a93d49d83b85c0dd400bHavoc Pennington                       watch, dbus_watch_get_socket (watch));
9748027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
9758027efc97b4bec85f674570f878919cb72456745Havoc Pennington#endif /* DBUS_ENABLE_VERBOSE_MODE */
9768027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9778027efc97b4bec85f674570f878919cb72456745Havoc Pennington  return TRUE;
9788027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
9798027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9808027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic void
9818027efc97b4bec85f674570f878919cb72456745Havoc Penningtonsocket_disconnect (DBusTransport *transport)
9828027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
9838027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
9848027efc97b4bec85f674570f878919cb72456745Havoc Pennington
985d5217348517e6b00a04e500ca460daf6cc928cd9Ralf Habacker  _dbus_verbose ("\n");
9868027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9878027efc97b4bec85f674570f878919cb72456745Havoc Pennington  free_watches (transport);
9888027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9898027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_close_socket (socket_transport->fd, NULL);
9908027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_transport->fd = -1;
9918027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
9928027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9938027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic dbus_bool_t
9948027efc97b4bec85f674570f878919cb72456745Havoc Penningtonsocket_connection_set (DBusTransport *transport)
9958027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
9968027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
9978027efc97b4bec85f674570f878919cb72456745Havoc Pennington
9988027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_watch_set_handler (socket_transport->write_watch,
9998027efc97b4bec85f674570f878919cb72456745Havoc Pennington                           _dbus_connection_handle_watch,
10008027efc97b4bec85f674570f878919cb72456745Havoc Pennington                           transport->connection, NULL);
10018027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10028027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_watch_set_handler (socket_transport->read_watch,
10038027efc97b4bec85f674570f878919cb72456745Havoc Pennington                           _dbus_connection_handle_watch,
10048027efc97b4bec85f674570f878919cb72456745Havoc Pennington                           transport->connection, NULL);
10058027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10068027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_connection_add_watch_unlocked (transport->connection,
10078027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                            socket_transport->write_watch))
10088027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return FALSE;
10098027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10108027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_connection_add_watch_unlocked (transport->connection,
10118027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                            socket_transport->read_watch))
10128027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
10138027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_connection_remove_watch_unlocked (transport->connection,
10148027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                              socket_transport->write_watch);
10158027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return FALSE;
10168027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
10178027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10188027efc97b4bec85f674570f878919cb72456745Havoc Pennington  check_read_watch (transport);
10198027efc97b4bec85f674570f878919cb72456745Havoc Pennington  check_write_watch (transport);
10208027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10218027efc97b4bec85f674570f878919cb72456745Havoc Pennington  return TRUE;
10228027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
10238027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10248027efc97b4bec85f674570f878919cb72456745Havoc Pennington/**
10258027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @todo We need to have a way to wake up the select sleep if
10268027efc97b4bec85f674570f878919cb72456745Havoc Pennington * a new iteration request comes in with a flag (read/write) that
10278027efc97b4bec85f674570f878919cb72456745Havoc Pennington * we're not currently serving. Otherwise a call that just reads
10288027efc97b4bec85f674570f878919cb72456745Havoc Pennington * could block a write call forever (if there are no incoming
10298027efc97b4bec85f674570f878919cb72456745Havoc Pennington * messages).
10308027efc97b4bec85f674570f878919cb72456745Havoc Pennington */
10318027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic  void
10328027efc97b4bec85f674570f878919cb72456745Havoc Penningtonsocket_do_iteration (DBusTransport *transport,
10338027efc97b4bec85f674570f878919cb72456745Havoc Pennington                   unsigned int   flags,
10348027efc97b4bec85f674570f878919cb72456745Havoc Pennington                   int            timeout_milliseconds)
10358027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
10368027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
10378027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusPollFD poll_fd;
10388027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int poll_res;
10398027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int poll_timeout;
10408027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10418027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
10428027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 flags & DBUS_ITERATION_DO_READING ? "read" : "",
10438027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
10448027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 timeout_milliseconds,
10458027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 socket_transport->read_watch,
10468027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 socket_transport->write_watch,
10478027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 socket_transport->fd);
10488027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10498027efc97b4bec85f674570f878919cb72456745Havoc Pennington  /* the passed in DO_READING/DO_WRITING flags indicate whether to
10508027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * read/write messages, but regardless of those we may need to block
10518027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * for reading/writing to do auth.  But if we do reading for auth,
10528027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * we don't want to read any messages yet if not given DO_READING.
10538027efc97b4bec85f674570f878919cb72456745Havoc Pennington   */
10548027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10558027efc97b4bec85f674570f878919cb72456745Havoc Pennington  poll_fd.fd = socket_transport->fd;
10568027efc97b4bec85f674570f878919cb72456745Havoc Pennington  poll_fd.events = 0;
10578027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10588027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (_dbus_transport_get_is_authenticated (transport))
10598027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
10608027efc97b4bec85f674570f878919cb72456745Havoc Pennington      /* This is kind of a hack; if we have stuff to write, then try
10618027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * to avoid the poll. This is probably about a 5% speedup on an
10628027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * echo client/server.
10638027efc97b4bec85f674570f878919cb72456745Havoc Pennington       *
10648027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * If both reading and writing were requested, we want to avoid this
10658027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * since it could have funky effects:
10668027efc97b4bec85f674570f878919cb72456745Havoc Pennington       *   - both ends spinning waiting for the other one to read
10678027efc97b4bec85f674570f878919cb72456745Havoc Pennington       *     data so they can finish writing
10688027efc97b4bec85f674570f878919cb72456745Havoc Pennington       *   - prioritizing all writing ahead of reading
10698027efc97b4bec85f674570f878919cb72456745Havoc Pennington       */
10708027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if ((flags & DBUS_ITERATION_DO_WRITING) &&
10718027efc97b4bec85f674570f878919cb72456745Havoc Pennington          !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
10728027efc97b4bec85f674570f878919cb72456745Havoc Pennington          !transport->disconnected &&
10738027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_connection_has_messages_to_send_unlocked (transport->connection))
10748027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
10758027efc97b4bec85f674570f878919cb72456745Havoc Pennington          do_writing (transport);
10768027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10778027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (transport->disconnected ||
10788027efc97b4bec85f674570f878919cb72456745Havoc Pennington              !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
10798027efc97b4bec85f674570f878919cb72456745Havoc Pennington            goto out;
10808027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
10818027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10828027efc97b4bec85f674570f878919cb72456745Havoc Pennington      /* If we get here, we decided to do the poll() after all */
10838027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_assert (socket_transport->read_watch);
10848027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (flags & DBUS_ITERATION_DO_READING)
10858027efc97b4bec85f674570f878919cb72456745Havoc Pennington	poll_fd.events |= _DBUS_POLLIN;
10868027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10878027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_assert (socket_transport->write_watch);
10888027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (flags & DBUS_ITERATION_DO_WRITING)
10898027efc97b4bec85f674570f878919cb72456745Havoc Pennington        poll_fd.events |= _DBUS_POLLOUT;
10908027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
10918027efc97b4bec85f674570f878919cb72456745Havoc Pennington  else
10928027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
10938027efc97b4bec85f674570f878919cb72456745Havoc Pennington      DBusAuthState auth_state;
10948027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10958027efc97b4bec85f674570f878919cb72456745Havoc Pennington      auth_state = _dbus_auth_do_work (transport->auth);
10968027efc97b4bec85f674570f878919cb72456745Havoc Pennington
10978027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (transport->receive_credentials_pending ||
10988027efc97b4bec85f674570f878919cb72456745Havoc Pennington          auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
10998027efc97b4bec85f674570f878919cb72456745Havoc Pennington	poll_fd.events |= _DBUS_POLLIN;
11008027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11018027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (transport->send_credentials_pending ||
11028027efc97b4bec85f674570f878919cb72456745Havoc Pennington          auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
11038027efc97b4bec85f674570f878919cb72456745Havoc Pennington	poll_fd.events |= _DBUS_POLLOUT;
11048027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
11058027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11068027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (poll_fd.events)
11078027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
11088027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (flags & DBUS_ITERATION_BLOCK)
11098027efc97b4bec85f674570f878919cb72456745Havoc Pennington	poll_timeout = timeout_milliseconds;
11108027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
11118027efc97b4bec85f674570f878919cb72456745Havoc Pennington	poll_timeout = 0;
11128027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11138027efc97b4bec85f674570f878919cb72456745Havoc Pennington      /* For blocking selects we drop the connection lock here
11148027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * to avoid blocking out connection access during a potentially
11158027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * indefinite blocking call. The io path is still protected
11168027efc97b4bec85f674570f878919cb72456745Havoc Pennington       * by the io_path_cond condvar, so we won't reenter this.
11178027efc97b4bec85f674570f878919cb72456745Havoc Pennington       */
11188027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (flags & DBUS_ITERATION_BLOCK)
11198027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
1120d5217348517e6b00a04e500ca460daf6cc928cd9Ralf Habacker          _dbus_verbose ("unlock pre poll\n");
11218027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_connection_unlock (transport->connection);
11228027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
11238027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11248027efc97b4bec85f674570f878919cb72456745Havoc Pennington    again:
11258027efc97b4bec85f674570f878919cb72456745Havoc Pennington      poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
11268027efc97b4bec85f674570f878919cb72456745Havoc Pennington
112743b944a0a6ea48e8a8b06ae3e638299f591cde8dHavoc Pennington      if (poll_res < 0 && _dbus_get_is_errno_eintr ())
11288027efc97b4bec85f674570f878919cb72456745Havoc Pennington	goto again;
11298027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11308027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (flags & DBUS_ITERATION_BLOCK)
11318027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
1132d5217348517e6b00a04e500ca460daf6cc928cd9Ralf Habacker          _dbus_verbose ("lock post poll\n");
11338027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_connection_lock (transport->connection);
11348027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
11358027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11368027efc97b4bec85f674570f878919cb72456745Havoc Pennington      if (poll_res >= 0)
11378027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
11388027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (poll_res == 0)
11398027efc97b4bec85f674570f878919cb72456745Havoc Pennington            poll_fd.revents = 0; /* some concern that posix does not guarantee this;
11408027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                  * valgrind flags it as an error. though it probably
11418027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                  * is guaranteed on linux at least.
11428027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                  */
11438027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11448027efc97b4bec85f674570f878919cb72456745Havoc Pennington          if (poll_fd.revents & _DBUS_POLLERR)
11458027efc97b4bec85f674570f878919cb72456745Havoc Pennington            do_io_error (transport);
11468027efc97b4bec85f674570f878919cb72456745Havoc Pennington          else
11478027efc97b4bec85f674570f878919cb72456745Havoc Pennington            {
11488027efc97b4bec85f674570f878919cb72456745Havoc Pennington              dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
11498027efc97b4bec85f674570f878919cb72456745Havoc Pennington              dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
11508027efc97b4bec85f674570f878919cb72456745Havoc Pennington	      dbus_bool_t authentication_completed;
11518027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11528027efc97b4bec85f674570f878919cb72456745Havoc Pennington              _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
11538027efc97b4bec85f674570f878919cb72456745Havoc Pennington                             need_read, need_write);
11548027efc97b4bec85f674570f878919cb72456745Havoc Pennington              do_authentication (transport, need_read, need_write,
11558027efc97b4bec85f674570f878919cb72456745Havoc Pennington				 &authentication_completed);
11568027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11578027efc97b4bec85f674570f878919cb72456745Havoc Pennington	      /* See comment in socket_handle_watch. */
11588027efc97b4bec85f674570f878919cb72456745Havoc Pennington	      if (authentication_completed)
11598027efc97b4bec85f674570f878919cb72456745Havoc Pennington                goto out;
11608027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11618027efc97b4bec85f674570f878919cb72456745Havoc Pennington              if (need_read && (flags & DBUS_ITERATION_DO_READING))
11628027efc97b4bec85f674570f878919cb72456745Havoc Pennington                do_reading (transport);
11638027efc97b4bec85f674570f878919cb72456745Havoc Pennington              if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
11648027efc97b4bec85f674570f878919cb72456745Havoc Pennington                do_writing (transport);
11658027efc97b4bec85f674570f878919cb72456745Havoc Pennington            }
11668027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
11678027efc97b4bec85f674570f878919cb72456745Havoc Pennington      else
11688027efc97b4bec85f674570f878919cb72456745Havoc Pennington        {
11698027efc97b4bec85f674570f878919cb72456745Havoc Pennington          _dbus_verbose ("Error from _dbus_poll(): %s\n",
117043b944a0a6ea48e8a8b06ae3e638299f591cde8dHavoc Pennington                         _dbus_strerror_from_errno ());
11718027efc97b4bec85f674570f878919cb72456745Havoc Pennington        }
11728027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
11738027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11748027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11758027efc97b4bec85f674570f878919cb72456745Havoc Pennington out:
11768027efc97b4bec85f674570f878919cb72456745Havoc Pennington  /* We need to install the write watch only if we did not
11778027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * successfully write everything. Note we need to be careful that we
11788027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * don't call check_write_watch *before* do_writing, since it's
11798027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * inefficient to add the write watch, and we can avoid it most of
11808027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * the time since we can write immediately.
11818027efc97b4bec85f674570f878919cb72456745Havoc Pennington   *
11828027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * However, we MUST always call check_write_watch(); DBusConnection code
11838027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * relies on the fact that running an iteration will notice that
11848027efc97b4bec85f674570f878919cb72456745Havoc Pennington   * messages are pending.
11858027efc97b4bec85f674570f878919cb72456745Havoc Pennington   */
11868027efc97b4bec85f674570f878919cb72456745Havoc Pennington  check_write_watch (transport);
11878027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11888027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_verbose (" ... leaving do_iteration()\n");
11898027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
11908027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11918027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic void
11928027efc97b4bec85f674570f878919cb72456745Havoc Penningtonsocket_live_messages_changed (DBusTransport *transport)
11938027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
11948027efc97b4bec85f674570f878919cb72456745Havoc Pennington  /* See if we should look for incoming messages again */
11958027efc97b4bec85f674570f878919cb72456745Havoc Pennington  check_read_watch (transport);
11968027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
11978027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11988027efc97b4bec85f674570f878919cb72456745Havoc Pennington
11998027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic dbus_bool_t
12008027efc97b4bec85f674570f878919cb72456745Havoc Penningtonsocket_get_socket_fd (DBusTransport *transport,
12018027efc97b4bec85f674570f878919cb72456745Havoc Pennington                      int           *fd_p)
12028027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
12038027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
12048027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12058027efc97b4bec85f674570f878919cb72456745Havoc Pennington  *fd_p = socket_transport->fd;
12068027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12078027efc97b4bec85f674570f878919cb72456745Havoc Pennington  return TRUE;
12088027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
12098027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12108027efc97b4bec85f674570f878919cb72456745Havoc Penningtonstatic const DBusTransportVTable socket_vtable = {
12118027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_finalize,
12128027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_handle_watch,
12138027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_disconnect,
12148027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_connection_set,
12158027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_do_iteration,
12168027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_live_messages_changed,
12178027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_get_socket_fd
12188027efc97b4bec85f674570f878919cb72456745Havoc Pennington};
12198027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12208027efc97b4bec85f674570f878919cb72456745Havoc Pennington/**
12218027efc97b4bec85f674570f878919cb72456745Havoc Pennington * Creates a new transport for the given socket file descriptor.  The file
12228027efc97b4bec85f674570f878919cb72456745Havoc Pennington * descriptor must be nonblocking (use _dbus_set_fd_nonblocking() to
12238027efc97b4bec85f674570f878919cb72456745Havoc Pennington * make it so). This function is shared by various transports that
12248027efc97b4bec85f674570f878919cb72456745Havoc Pennington * boil down to a full duplex file descriptor.
12258027efc97b4bec85f674570f878919cb72456745Havoc Pennington *
12268027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @param fd the file descriptor.
12278027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @param server_guid non-#NULL if this transport is on the server side of a connection
12288027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @param address the transport's address
12298027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @returns the new transport, or #NULL if no memory.
12308027efc97b4bec85f674570f878919cb72456745Havoc Pennington */
12318027efc97b4bec85f674570f878919cb72456745Havoc PenningtonDBusTransport*
12328027efc97b4bec85f674570f878919cb72456745Havoc Pennington_dbus_transport_new_for_socket (int               fd,
12338027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                const DBusString *server_guid,
12348027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                const DBusString *address)
12358027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
12368027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransportSocket *socket_transport;
12378027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12388027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_transport = dbus_new0 (DBusTransportSocket, 1);
12398027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (socket_transport == NULL)
12408027efc97b4bec85f674570f878919cb72456745Havoc Pennington    return NULL;
12418027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12428027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_string_init (&socket_transport->encoded_outgoing))
12438027efc97b4bec85f674570f878919cb72456745Havoc Pennington    goto failed_0;
12448027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12458027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_string_init (&socket_transport->encoded_incoming))
12468027efc97b4bec85f674570f878919cb72456745Havoc Pennington    goto failed_1;
12478027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12488027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_transport->write_watch = _dbus_watch_new (fd,
12498027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                                 DBUS_WATCH_WRITABLE,
12508027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                                 FALSE,
12518027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                                 NULL, NULL, NULL);
12528027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (socket_transport->write_watch == NULL)
12538027efc97b4bec85f674570f878919cb72456745Havoc Pennington    goto failed_2;
12548027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12558027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_transport->read_watch = _dbus_watch_new (fd,
12568027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                                DBUS_WATCH_READABLE,
12578027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                                FALSE,
12588027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                                NULL, NULL, NULL);
12598027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (socket_transport->read_watch == NULL)
12608027efc97b4bec85f674570f878919cb72456745Havoc Pennington    goto failed_3;
126123832672266bb4ff23b66247c0cfa1a2ed0cc97bHavoc Pennington
12628027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_transport_init_base (&socket_transport->base,
12638027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                  &socket_vtable,
12648027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                  server_guid, address))
12658027efc97b4bec85f674570f878919cb72456745Havoc Pennington    goto failed_4;
1266a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering
1267a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering#ifdef HAVE_UNIX_FD_PASSING
1268c200e0304d6f53a0fd47f524386b02b27c0c45f6Lennart Poettering  _dbus_auth_set_unix_fd_possible(socket_transport->base.auth, _dbus_socket_can_pass_unix_fd(fd));
1269a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering#endif
1270a0cc21f8bb6752ffe0ee5f4f5b575dc50d6d46aeLennart Poettering
12718027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_transport->fd = fd;
12728027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_transport->message_bytes_written = 0;
12738027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12748027efc97b4bec85f674570f878919cb72456745Havoc Pennington  /* These values should probably be tunable or something. */
12758027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_transport->max_bytes_read_per_iteration = 2048;
12768027efc97b4bec85f674570f878919cb72456745Havoc Pennington  socket_transport->max_bytes_written_per_iteration = 2048;
12778027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12788027efc97b4bec85f674570f878919cb72456745Havoc Pennington  return (DBusTransport*) socket_transport;
12798027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12808027efc97b4bec85f674570f878919cb72456745Havoc Pennington failed_4:
12818027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_watch_unref (socket_transport->read_watch);
12828027efc97b4bec85f674570f878919cb72456745Havoc Pennington failed_3:
12838027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_watch_unref (socket_transport->write_watch);
12848027efc97b4bec85f674570f878919cb72456745Havoc Pennington failed_2:
12858027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_string_free (&socket_transport->encoded_incoming);
12868027efc97b4bec85f674570f878919cb72456745Havoc Pennington failed_1:
12878027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_string_free (&socket_transport->encoded_outgoing);
12888027efc97b4bec85f674570f878919cb72456745Havoc Pennington failed_0:
12898027efc97b4bec85f674570f878919cb72456745Havoc Pennington  dbus_free (socket_transport);
12908027efc97b4bec85f674570f878919cb72456745Havoc Pennington  return NULL;
12918027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
12928027efc97b4bec85f674570f878919cb72456745Havoc Pennington
12938027efc97b4bec85f674570f878919cb72456745Havoc Pennington/**
12948027efc97b4bec85f674570f878919cb72456745Havoc Pennington * Creates a new transport for the given hostname and port.
1295ee71e1ff6033ad1eb2385f11d4f3678259b8397bDaniel P. Berrange * If host is NULL, it will default to localhost
12968027efc97b4bec85f674570f878919cb72456745Havoc Pennington *
12978027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @param host the host to connect to
12988027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @param port the port to connect to
1299ee71e1ff6033ad1eb2385f11d4f3678259b8397bDaniel P. Berrange * @param family the address family to connect to
13005e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld * @param path to nonce file
13018027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @param error location to store reason for failure.
13028027efc97b4bec85f674570f878919cb72456745Havoc Pennington * @returns a new transport, or #NULL on failure.
13038027efc97b4bec85f674570f878919cb72456745Havoc Pennington */
13048027efc97b4bec85f674570f878919cb72456745Havoc PenningtonDBusTransport*
13058027efc97b4bec85f674570f878919cb72456745Havoc Pennington_dbus_transport_new_for_tcp_socket (const char     *host,
1306ee71e1ff6033ad1eb2385f11d4f3678259b8397bDaniel P. Berrange                                    const char     *port,
1307ee71e1ff6033ad1eb2385f11d4f3678259b8397bDaniel P. Berrange                                    const char     *family,
13085e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld                                    const char     *noncefile,
13098027efc97b4bec85f674570f878919cb72456745Havoc Pennington                                    DBusError      *error)
13108027efc97b4bec85f674570f878919cb72456745Havoc Pennington{
13118027efc97b4bec85f674570f878919cb72456745Havoc Pennington  int fd;
13128027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusTransport *transport;
13138027efc97b4bec85f674570f878919cb72456745Havoc Pennington  DBusString address;
13148027efc97b4bec85f674570f878919cb72456745Havoc Pennington
13158027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
13168027efc97b4bec85f674570f878919cb72456745Havoc Pennington
13178027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_string_init (&address))
13188027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
13198027efc97b4bec85f674570f878919cb72456745Havoc Pennington      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
13208027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return NULL;
13218027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
1322ee71e1ff6033ad1eb2385f11d4f3678259b8397bDaniel P. Berrange
1323ee71e1ff6033ad1eb2385f11d4f3678259b8397bDaniel P. Berrange  if (host == NULL)
1324ee71e1ff6033ad1eb2385f11d4f3678259b8397bDaniel P. Berrange    host = "localhost";
1325ee71e1ff6033ad1eb2385f11d4f3678259b8397bDaniel P. Berrange
13265e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld  if (!_dbus_string_append (&address, noncefile ? "nonce-tcp:" : "tcp:"))
13278027efc97b4bec85f674570f878919cb72456745Havoc Pennington    goto error;
13288027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1329ee71e1ff6033ad1eb2385f11d4f3678259b8397bDaniel P. Berrange  if (!_dbus_string_append (&address, "host=") ||
1330ee71e1ff6033ad1eb2385f11d4f3678259b8397bDaniel P. Berrange      !_dbus_string_append (&address, host))
13318027efc97b4bec85f674570f878919cb72456745Havoc Pennington    goto error;
13328027efc97b4bec85f674570f878919cb72456745Havoc Pennington
13338027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (!_dbus_string_append (&address, ",port=") ||
1334ee71e1ff6033ad1eb2385f11d4f3678259b8397bDaniel P. Berrange      !_dbus_string_append (&address, port))
13358027efc97b4bec85f674570f878919cb72456745Havoc Pennington    goto error;
13368027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1337ee71e1ff6033ad1eb2385f11d4f3678259b8397bDaniel P. Berrange  if (family != NULL &&
1338ee71e1ff6033ad1eb2385f11d4f3678259b8397bDaniel P. Berrange      (!_dbus_string_append (&address, "family=") ||
1339ee71e1ff6033ad1eb2385f11d4f3678259b8397bDaniel P. Berrange       !_dbus_string_append (&address, family)))
1340ee71e1ff6033ad1eb2385f11d4f3678259b8397bDaniel P. Berrange    goto error;
1341ee71e1ff6033ad1eb2385f11d4f3678259b8397bDaniel P. Berrange
13425e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld  if (noncefile != NULL &&
13435e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld      (!_dbus_string_append (&address, "noncefile=") ||
13445e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld       !_dbus_string_append (&address, noncefile)))
13455e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld    goto error;
13465e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld
13475e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld  fd = _dbus_connect_tcp_socket_with_nonce (host, port, family, noncefile, error);
13488027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (fd < 0)
13498027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
13508027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _DBUS_ASSERT_ERROR_IS_SET (error);
13518027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_string_free (&address);
13528027efc97b4bec85f674570f878919cb72456745Havoc Pennington      return NULL;
13538027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
13548027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1355ee71e1ff6033ad1eb2385f11d4f3678259b8397bDaniel P. Berrange  _dbus_verbose ("Successfully connected to tcp socket %s:%s\n",
13568027efc97b4bec85f674570f878919cb72456745Havoc Pennington                 host, port);
13578027efc97b4bec85f674570f878919cb72456745Havoc Pennington
13588027efc97b4bec85f674570f878919cb72456745Havoc Pennington  transport = _dbus_transport_new_for_socket (fd, NULL, &address);
13593c657579a0545af63b0286c3c901f7812149f6dcMarcus Brinkmann  _dbus_string_free (&address);
13608027efc97b4bec85f674570f878919cb72456745Havoc Pennington  if (transport == NULL)
13618027efc97b4bec85f674570f878919cb72456745Havoc Pennington    {
13628027efc97b4bec85f674570f878919cb72456745Havoc Pennington      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
13638027efc97b4bec85f674570f878919cb72456745Havoc Pennington      _dbus_close_socket (fd, NULL);
13648027efc97b4bec85f674570f878919cb72456745Havoc Pennington      fd = -1;
13658027efc97b4bec85f674570f878919cb72456745Havoc Pennington    }
13668027efc97b4bec85f674570f878919cb72456745Havoc Pennington
13678027efc97b4bec85f674570f878919cb72456745Havoc Pennington  return transport;
13688027efc97b4bec85f674570f878919cb72456745Havoc Pennington
13698027efc97b4bec85f674570f878919cb72456745Havoc Penningtonerror:
13708027efc97b4bec85f674570f878919cb72456745Havoc Pennington  _dbus_string_free (&address);
13718027efc97b4bec85f674570f878919cb72456745Havoc Pennington  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
13728027efc97b4bec85f674570f878919cb72456745Havoc Pennington  return NULL;
13738027efc97b4bec85f674570f878919cb72456745Havoc Pennington}
13748027efc97b4bec85f674570f878919cb72456745Havoc Pennington
137515ef0ef6fbba7827453b7973e62b6c1853576601Havoc Pennington/**
137615ef0ef6fbba7827453b7973e62b6c1853576601Havoc Pennington * Opens a TCP socket transport.
137715ef0ef6fbba7827453b7973e62b6c1853576601Havoc Pennington *
137815ef0ef6fbba7827453b7973e62b6c1853576601Havoc Pennington * @param entry the address entry to try opening as a tcp transport.
137915ef0ef6fbba7827453b7973e62b6c1853576601Havoc Pennington * @param transport_p return location for the opened transport
138015ef0ef6fbba7827453b7973e62b6c1853576601Havoc Pennington * @param error error to be set
138115ef0ef6fbba7827453b7973e62b6c1853576601Havoc Pennington * @returns result of the attempt
138215ef0ef6fbba7827453b7973e62b6c1853576601Havoc Pennington */
1383fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc PenningtonDBusTransportOpenResult
1384fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington_dbus_transport_open_socket(DBusAddressEntry  *entry,
1385fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington                            DBusTransport    **transport_p,
1386fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington                            DBusError         *error)
1387fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington{
1388fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington  const char *method;
13895e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld  dbus_bool_t isTcp;
13905e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld  dbus_bool_t isNonceTcp;
1391fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington
1392fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington  method = dbus_address_entry_get_method (entry);
1393fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington  _dbus_assert (method != NULL);
1394fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington
13955e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld  isTcp = strcmp (method, "tcp") == 0;
13965e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld  isNonceTcp = strcmp (method, "nonce-tcp") == 0;
13975e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld
13985e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld  if (isTcp || isNonceTcp)
1399fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington    {
1400fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      const char *host = dbus_address_entry_get_value (entry, "host");
1401fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      const char *port = dbus_address_entry_get_value (entry, "port");
1402ee71e1ff6033ad1eb2385f11d4f3678259b8397bDaniel P. Berrange      const char *family = dbus_address_entry_get_value (entry, "family");
14035e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld      const char *noncefile = dbus_address_entry_get_value (entry, "noncefile");
14045e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld
14055e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld      if ((isNonceTcp == TRUE) != (noncefile != NULL)) {
14065e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld          _dbus_set_bad_address (error, method, "noncefile", NULL);
14075e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld          return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
14085e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld      }
1409ee71e1ff6033ad1eb2385f11d4f3678259b8397bDaniel P. Berrange
1410fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      if (port == NULL)
1411fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington        {
14125e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld          _dbus_set_bad_address (error, method, "port", NULL);
1413fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington          return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
1414fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington        }
1415fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington
14165e2a99c12c7e3531d908ed4fca82caca9cb02825Frank Osterfeld      *transport_p = _dbus_transport_new_for_tcp_socket (host, port, family, noncefile, error);
1417fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      if (*transport_p == NULL)
1418fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington        {
1419c8f73b36a5b44eb97165b93d6b9d92e7fee0eae1Frank Osterfeld          _DBUS_ASSERT_ERROR_IS_SET (error);
1420fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington          return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
1421fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington        }
1422fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      else
1423fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington        {
1424fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington          _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1425fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington          return DBUS_TRANSPORT_OPEN_OK;
1426fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington        }
1427fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington    }
1428fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington  else
1429fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington    {
1430fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1431fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington      return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
1432fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington    }
1433fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington}
1434fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington
14358027efc97b4bec85f674570f878919cb72456745Havoc Pennington/** @} */
14368027efc97b4bec85f674570f878919cb72456745Havoc Pennington
1437