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