*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
+#include <config.h>
#include "dbus-internals.h"
#include "dbus-connection-internal.h"
+#include "dbus-nonce.h"
#include "dbus-transport-socket.h"
#include "dbus-transport-protected.h"
#include "dbus-watch.h"
#include "dbus-credentials.h"
+#include <stdio.h> //todo to remove
/**
* @defgroup DBusTransportSocket DBusTransport implementations for sockets
{
DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
- _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
+ _dbus_verbose ("start\n");
if (socket_transport->read_watch)
{
socket_transport->write_watch = NULL;
}
- _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
+ _dbus_verbose ("end\n");
}
static void
{
DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
- _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
+ _dbus_verbose ("\n");
free_watches (transport);
DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
dbus_bool_t need_read_watch;
- _dbus_verbose ("%s: fd = %d\n",
- _DBUS_FUNCTION_NAME, socket_transport->fd);
+ _dbus_verbose ("fd = %d\n",socket_transport->fd);
if (transport->connection == NULL)
return;
int header_len, body_len;
int total_bytes_to_write;
+// int i;
+
if (total > socket_transport->max_bytes_written_per_iteration)
{
_dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
header_len = _dbus_string_get_length (header);
body_len = _dbus_string_get_length (body);
+ /* fprintf (stderr, "\nheader:\n"); //todo for test - to remove
+ for(i=0; i < header_len; i++)
+ {
+ fprintf (stderr, "%02x", _dbus_string_get_byte(header,i));
+ }
+ fprintf (stderr,"\n");
+ for(i=0; i < header_len; i++)
+ {
+ fprintf (stderr, "%c", _dbus_string_get_byte(header,i));
+ }
+ fprintf (stderr, "\nret size: %u, i: %u\n", header_len, i);
+
+
+ fprintf (stderr, "\nbody:\n");
+ for(i=0; i < body_len; i++)
+ {
+ fprintf (stderr, "%02x", _dbus_string_get_byte(body,i));
+ }
+ fprintf (stderr, "\nret size: %u, i: %u\n", body_len, i);
+ fprintf (stderr,"\n");
+ for(i=0; i < body_len; i++)
+ {
+ fprintf (stderr, "%c", _dbus_string_get_byte(body,i));
+ }
+ fprintf (stderr, "\nret size: %u, i: %u\n", body_len, i);*/
+
if (_dbus_auth_needs_encoding (transport->auth))
{
/* Does fd passing even make sense with encoded data? */
{
/* EINTR already handled for us */
- if (_dbus_get_is_errno_eagain_or_ewouldblock ())
+ /* For some discussion of why we also ignore EPIPE here, see
+ * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html
+ */
+
+ if (_dbus_get_is_errno_eagain_or_ewouldblock () || _dbus_get_is_errno_epipe ())
goto out;
else
{
_dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
_dbus_string_compact (&socket_transport->encoded_outgoing, 2048);
- _dbus_connection_message_sent (transport->connection,
- message);
+ _dbus_connection_message_sent_unlocked (transport->connection,
+ message);
}
}
}
int total;
dbus_bool_t oom;
- _dbus_verbose ("%s: fd = %d\n", _DBUS_FUNCTION_NAME,
- socket_transport->fd);
+ _dbus_verbose ("fd = %d\n",socket_transport->fd);
/* No messages without authentication! */
if (!_dbus_transport_get_is_authenticated (transport))
}
static dbus_bool_t
+unix_error_with_read_to_come (DBusTransport *itransport,
+ DBusWatch *watch,
+ unsigned int flags)
+{
+ DBusTransportSocket *transport = (DBusTransportSocket *) itransport;
+
+ if (!(flags & DBUS_WATCH_HANGUP || flags & DBUS_WATCH_ERROR))
+ return FALSE;
+
+ /* If we have a read watch enabled ...
+ we -might have data incoming ... => handle the HANGUP there */
+ if (watch != transport->read_watch &&
+ _dbus_watch_get_enabled (transport->read_watch))
+ return FALSE;
+
+ return TRUE;
+}
+
+static dbus_bool_t
socket_handle_watch (DBusTransport *transport,
DBusWatch *watch,
unsigned int flags)
watch == socket_transport->write_watch);
_dbus_assert (watch != NULL);
- /* Disconnect in case of an error. In case of hangup do not
- * disconnect the transport because data can still be in the buffer
- * and do_reading may need several iteration to read it all (because
- * of its max_bytes_read_per_iteration limit). The condition where
- * flags == HANGUP (without READABLE) probably never happen in fact.
+ /* If we hit an error here on a write watch, don't disconnect the transport yet because data can
+ * still be in the buffer and do_reading may need several iteration to read
+ * it all (because of its max_bytes_read_per_iteration limit).
*/
- if ((flags & DBUS_WATCH_ERROR) ||
- ((flags & DBUS_WATCH_HANGUP) && !(flags & DBUS_WATCH_READABLE)))
+ if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags))
{
_dbus_verbose ("Hang up or error on watch\n");
_dbus_transport_disconnect (transport);
{
DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
- _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
+ _dbus_verbose ("\n");
free_watches (transport);
*/
if (flags & DBUS_ITERATION_BLOCK)
{
- _dbus_verbose ("unlock %s pre poll\n", _DBUS_FUNCTION_NAME);
+ _dbus_verbose ("unlock pre poll\n");
_dbus_connection_unlock (transport->connection);
}
if (flags & DBUS_ITERATION_BLOCK)
{
- _dbus_verbose ("lock %s post poll\n", _DBUS_FUNCTION_NAME);
+ _dbus_verbose ("lock post poll\n");
_dbus_connection_lock (transport->connection);
}
return (DBusTransport*) socket_transport;
failed_4:
+ _dbus_watch_invalidate (socket_transport->read_watch);
_dbus_watch_unref (socket_transport->read_watch);
failed_3:
+ _dbus_watch_invalidate (socket_transport->write_watch);
_dbus_watch_unref (socket_transport->write_watch);
failed_2:
_dbus_string_free (&socket_transport->encoded_incoming);
* @param host the host to connect to
* @param port the port to connect to
* @param family the address family to connect to
+ * @param path to nonce file
* @param error location to store reason for failure.
* @returns a new transport, or #NULL on failure.
*/
_dbus_transport_new_for_tcp_socket (const char *host,
const char *port,
const char *family,
+ const char *noncefile,
DBusError *error)
{
int fd;
if (host == NULL)
host = "localhost";
- if (!_dbus_string_append (&address, "tcp:"))
+ if (!_dbus_string_append (&address, noncefile ? "nonce-tcp:" : "tcp:"))
goto error;
if (!_dbus_string_append (&address, "host=") ||
goto error;
if (family != NULL &&
- (!_dbus_string_append (&address, "family=") ||
+ (!_dbus_string_append (&address, ",family=") ||
!_dbus_string_append (&address, family)))
goto error;
- fd = _dbus_connect_tcp_socket (host, port, family, error);
+ if (noncefile != NULL &&
+ (!_dbus_string_append (&address, ",noncefile=") ||
+ !_dbus_string_append (&address, noncefile)))
+ goto error;
+
+ fd = _dbus_connect_tcp_socket_with_nonce (host, port, family, noncefile, error);
if (fd < 0)
{
_DBUS_ASSERT_ERROR_IS_SET (error);
host, port);
transport = _dbus_transport_new_for_socket (fd, NULL, &address);
+ _dbus_string_free (&address);
if (transport == NULL)
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
_dbus_close_socket (fd, NULL);
- _dbus_string_free (&address);
fd = -1;
}
- _dbus_string_free (&address);
-
return transport;
error:
DBusError *error)
{
const char *method;
+ dbus_bool_t isTcp;
+ dbus_bool_t isNonceTcp;
method = dbus_address_entry_get_method (entry);
_dbus_assert (method != NULL);
- if (strcmp (method, "tcp") == 0)
+ isTcp = strcmp (method, "tcp") == 0;
+ isNonceTcp = strcmp (method, "nonce-tcp") == 0;
+
+ if (isTcp || isNonceTcp)
{
const char *host = dbus_address_entry_get_value (entry, "host");
const char *port = dbus_address_entry_get_value (entry, "port");
const char *family = dbus_address_entry_get_value (entry, "family");
+ const char *noncefile = dbus_address_entry_get_value (entry, "noncefile");
+
+ if ((isNonceTcp == TRUE) != (noncefile != NULL)) {
+ _dbus_set_bad_address (error, method, "noncefile", NULL);
+ return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
+ }
if (port == NULL)
{
- _dbus_set_bad_address (error, "tcp", "port", NULL);
+ _dbus_set_bad_address (error, method, "port", NULL);
return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
}
- *transport_p = _dbus_transport_new_for_tcp_socket (host, port, family, error);
+ *transport_p = _dbus_transport_new_for_tcp_socket (host, port, family, noncefile, error);
if (*transport_p == NULL)
{
_DBUS_ASSERT_ERROR_IS_SET (error);