Consistently include <config.h> in all C source files and never in header files.
[platform/upstream/dbus.git] / dbus / dbus-transport-socket.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-transport-socket.c  Socket subclasses of DBusTransport
3  *
4  * Copyright (C) 2002, 2003, 2004, 2006  Red Hat Inc.
5  *
6  * Licensed under the Academic Free License version 2.1
7  * 
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  * 
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23
24 #include <config.h>
25 #include "dbus-internals.h"
26 #include "dbus-connection-internal.h"
27 #include "dbus-nonce.h"
28 #include "dbus-transport-socket.h"
29 #include "dbus-transport-protected.h"
30 #include "dbus-watch.h"
31 #include "dbus-credentials.h"
32
33 /**
34  * @defgroup DBusTransportSocket DBusTransport implementations for sockets
35  * @ingroup  DBusInternals
36  * @brief Implementation details of DBusTransport on sockets
37  *
38  * @{
39  */
40
41 /**
42  * Opaque object representing a socket file descriptor transport.
43  */
44 typedef struct DBusTransportSocket DBusTransportSocket;
45
46 /**
47  * Implementation details of DBusTransportSocket. All members are private.
48  */
49 struct DBusTransportSocket
50 {
51   DBusTransport base;                   /**< Parent instance */
52   int fd;                               /**< File descriptor. */
53   DBusWatch *read_watch;                /**< Watch for readability. */
54   DBusWatch *write_watch;               /**< Watch for writability. */
55
56   int max_bytes_read_per_iteration;     /**< To avoid blocking too long. */
57   int max_bytes_written_per_iteration;  /**< To avoid blocking too long. */
58
59   int message_bytes_written;            /**< Number of bytes of current
60                                          *   outgoing message that have
61                                          *   been written.
62                                          */
63   DBusString encoded_outgoing;          /**< Encoded version of current
64                                          *   outgoing message.
65                                          */
66   DBusString encoded_incoming;          /**< Encoded version of current
67                                          *   incoming data.
68                                          */
69 };
70
71 static void
72 free_watches (DBusTransport *transport)
73 {
74   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
75
76   _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
77   
78   if (socket_transport->read_watch)
79     {
80       if (transport->connection)
81         _dbus_connection_remove_watch_unlocked (transport->connection,
82                                                 socket_transport->read_watch);
83       _dbus_watch_invalidate (socket_transport->read_watch);
84       _dbus_watch_unref (socket_transport->read_watch);
85       socket_transport->read_watch = NULL;
86     }
87
88   if (socket_transport->write_watch)
89     {
90       if (transport->connection)
91         _dbus_connection_remove_watch_unlocked (transport->connection,
92                                                 socket_transport->write_watch);
93       _dbus_watch_invalidate (socket_transport->write_watch);
94       _dbus_watch_unref (socket_transport->write_watch);
95       socket_transport->write_watch = NULL;
96     }
97
98   _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
99 }
100
101 static void
102 socket_finalize (DBusTransport *transport)
103 {
104   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
105
106   _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
107   
108   free_watches (transport);
109
110   _dbus_string_free (&socket_transport->encoded_outgoing);
111   _dbus_string_free (&socket_transport->encoded_incoming);
112   
113   _dbus_transport_finalize_base (transport);
114
115   _dbus_assert (socket_transport->read_watch == NULL);
116   _dbus_assert (socket_transport->write_watch == NULL);
117   
118   dbus_free (transport);
119 }
120
121 static void
122 check_write_watch (DBusTransport *transport)
123 {
124   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
125   dbus_bool_t needed;
126
127   if (transport->connection == NULL)
128     return;
129
130   if (transport->disconnected)
131     {
132       _dbus_assert (socket_transport->write_watch == NULL);
133       return;
134     }
135   
136   _dbus_transport_ref (transport);
137
138   if (_dbus_transport_get_is_authenticated (transport))
139     needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
140   else
141     {
142       if (transport->send_credentials_pending)
143         needed = TRUE;
144       else
145         {
146           DBusAuthState auth_state;
147           
148           auth_state = _dbus_auth_do_work (transport->auth);
149           
150           /* If we need memory we install the write watch just in case,
151            * if there's no need for it, it will get de-installed
152            * next time we try reading.
153            */
154           if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND ||
155               auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
156             needed = TRUE;
157           else
158             needed = FALSE;
159         }
160     }
161
162   _dbus_verbose ("check_write_watch(): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
163                  needed, transport->connection, socket_transport->write_watch,
164                  socket_transport->fd,
165                  _dbus_connection_has_messages_to_send_unlocked (transport->connection));
166
167   _dbus_connection_toggle_watch_unlocked (transport->connection,
168                                           socket_transport->write_watch,
169                                           needed);
170
171   _dbus_transport_unref (transport);
172 }
173
174 static void
175 check_read_watch (DBusTransport *transport)
176 {
177   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
178   dbus_bool_t need_read_watch;
179
180   _dbus_verbose ("%s: fd = %d\n",
181                  _DBUS_FUNCTION_NAME, socket_transport->fd);
182   
183   if (transport->connection == NULL)
184     return;
185
186   if (transport->disconnected)
187     {
188       _dbus_assert (socket_transport->read_watch == NULL);
189       return;
190     }
191   
192   _dbus_transport_ref (transport);
193
194   if (_dbus_transport_get_is_authenticated (transport))
195     need_read_watch =
196       (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
197       (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
198   else
199     {
200       if (transport->receive_credentials_pending)
201         need_read_watch = TRUE;
202       else
203         {
204           /* The reason to disable need_read_watch when not WAITING_FOR_INPUT
205            * is to avoid spinning on the file descriptor when we're waiting
206            * to write or for some other part of the auth process
207            */
208           DBusAuthState auth_state;
209           
210           auth_state = _dbus_auth_do_work (transport->auth);
211
212           /* If we need memory we install the read watch just in case,
213            * if there's no need for it, it will get de-installed
214            * next time we try reading. If we're authenticated we
215            * install it since we normally have it installed while
216            * authenticated.
217            */
218           if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT ||
219               auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY ||
220               auth_state == DBUS_AUTH_STATE_AUTHENTICATED)
221             need_read_watch = TRUE;
222           else
223             need_read_watch = FALSE;
224         }
225     }
226
227   _dbus_verbose ("  setting read watch enabled = %d\n", need_read_watch);
228   _dbus_connection_toggle_watch_unlocked (transport->connection,
229                                           socket_transport->read_watch,
230                                           need_read_watch);
231
232   _dbus_transport_unref (transport);
233 }
234
235 static void
236 do_io_error (DBusTransport *transport)
237 {
238   _dbus_transport_ref (transport);
239   _dbus_transport_disconnect (transport);
240   _dbus_transport_unref (transport);
241 }
242
243 /* return value is whether we successfully read any new data. */
244 static dbus_bool_t
245 read_data_into_auth (DBusTransport *transport,
246                      dbus_bool_t   *oom)
247 {
248   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
249   DBusString *buffer;
250   int bytes_read;
251   
252   *oom = FALSE;
253
254   _dbus_auth_get_buffer (transport->auth, &buffer);
255   
256   bytes_read = _dbus_read_socket (socket_transport->fd,
257                                   buffer, socket_transport->max_bytes_read_per_iteration);
258
259   _dbus_auth_return_buffer (transport->auth, buffer,
260                             bytes_read > 0 ? bytes_read : 0);
261
262   if (bytes_read > 0)
263     {
264       _dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
265
266       return TRUE;
267     }
268   else if (bytes_read < 0)
269     {
270       /* EINTR already handled for us */
271
272       if (_dbus_get_is_errno_enomem ())
273         {
274           *oom = TRUE;
275         }
276       else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
277         ; /* do nothing, just return FALSE below */
278       else
279         {
280           _dbus_verbose ("Error reading from remote app: %s\n",
281                          _dbus_strerror_from_errno ());
282           do_io_error (transport);
283         }
284
285       return FALSE;
286     }
287   else
288     {
289       _dbus_assert (bytes_read == 0);
290       
291       _dbus_verbose ("Disconnected from remote app\n");
292       do_io_error (transport);
293
294       return FALSE;
295     }
296 }
297
298 /* Return value is whether we successfully wrote any bytes */
299 static dbus_bool_t
300 write_data_from_auth (DBusTransport *transport)
301 {
302   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
303   int bytes_written;
304   const DBusString *buffer;
305
306   if (!_dbus_auth_get_bytes_to_send (transport->auth,
307                                      &buffer))
308     return FALSE;
309   
310   bytes_written = _dbus_write_socket (socket_transport->fd,
311                                       buffer,
312                                       0, _dbus_string_get_length (buffer));
313
314   if (bytes_written > 0)
315     {
316       _dbus_auth_bytes_sent (transport->auth, bytes_written);
317       return TRUE;
318     }
319   else if (bytes_written < 0)
320     {
321       /* EINTR already handled for us */
322       
323       if (_dbus_get_is_errno_eagain_or_ewouldblock ())
324         ;
325       else
326         {
327           _dbus_verbose ("Error writing to remote app: %s\n",
328                          _dbus_strerror_from_errno ());
329           do_io_error (transport);
330         }
331     }
332
333   return FALSE;
334 }
335
336 /* FALSE on OOM */
337 static dbus_bool_t
338 exchange_credentials (DBusTransport *transport,
339                       dbus_bool_t    do_reading,
340                       dbus_bool_t    do_writing)
341 {
342   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
343   DBusError error = DBUS_ERROR_INIT;
344
345   _dbus_verbose ("exchange_credentials: do_reading = %d, do_writing = %d\n",
346                   do_reading, do_writing);
347
348   if (do_writing && transport->send_credentials_pending)
349     {
350       if (_dbus_send_credentials_socket (socket_transport->fd,
351                                          &error))
352         {
353           transport->send_credentials_pending = FALSE;
354         }
355       else
356         {
357           _dbus_verbose ("Failed to write credentials: %s\n", error.message);
358           dbus_error_free (&error);
359           do_io_error (transport);
360         }
361     }
362   
363   if (do_reading && transport->receive_credentials_pending)
364     {
365       /* FIXME this can fail due to IO error _or_ OOM, broken
366        * (somewhat tricky to fix since the OOM error can be set after
367        * we already read the credentials byte, so basically we need to
368        * separate reading the byte and storing it in the
369        * transport->credentials). Does not really matter for now
370        * because storing in credentials never actually fails on unix.
371        */      
372       if (_dbus_read_credentials_socket (socket_transport->fd,
373                                          transport->credentials,
374                                          &error))
375         {
376           transport->receive_credentials_pending = FALSE;
377         }
378       else
379         {
380           _dbus_verbose ("Failed to read credentials %s\n", error.message);
381           dbus_error_free (&error);
382           do_io_error (transport);
383         }
384     }
385
386   if (!(transport->send_credentials_pending ||
387         transport->receive_credentials_pending))
388     {
389       if (!_dbus_auth_set_credentials (transport->auth,
390                                        transport->credentials))
391         return FALSE;
392     }
393
394   return TRUE;
395 }
396
397 static dbus_bool_t
398 do_authentication (DBusTransport *transport,
399                    dbus_bool_t    do_reading,
400                    dbus_bool_t    do_writing,
401                    dbus_bool_t   *auth_completed)
402 {
403   dbus_bool_t oom;
404   dbus_bool_t orig_auth_state;
405
406   oom = FALSE;
407   
408   orig_auth_state = _dbus_transport_get_is_authenticated (transport);
409
410   /* This is essential to avoid the check_write_watch() at the end,
411    * we don't want to add a write watch in do_iteration before
412    * we try writing and get EAGAIN
413    */
414   if (orig_auth_state)
415     {
416       if (auth_completed)
417         *auth_completed = FALSE;
418       return TRUE;
419     }
420   
421   _dbus_transport_ref (transport);
422   
423   while (!_dbus_transport_get_is_authenticated (transport) &&
424          _dbus_transport_get_is_connected (transport))
425     {      
426       if (!exchange_credentials (transport, do_reading, do_writing))
427         {
428           /* OOM */
429           oom = TRUE;
430           goto out;
431         }
432       
433       if (transport->send_credentials_pending ||
434           transport->receive_credentials_pending)
435         {
436           _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
437                          transport->send_credentials_pending,
438                          transport->receive_credentials_pending);
439           goto out;
440         }
441
442 #define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client")
443       switch (_dbus_auth_do_work (transport->auth))
444         {
445         case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
446           _dbus_verbose (" %s auth state: waiting for input\n",
447                          TRANSPORT_SIDE (transport));
448           if (!do_reading || !read_data_into_auth (transport, &oom))
449             goto out;
450           break;
451       
452         case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
453           _dbus_verbose (" %s auth state: waiting for memory\n",
454                          TRANSPORT_SIDE (transport));
455           oom = TRUE;
456           goto out;
457           break;
458       
459         case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
460           _dbus_verbose (" %s auth state: bytes to send\n",
461                          TRANSPORT_SIDE (transport));
462           if (!do_writing || !write_data_from_auth (transport))
463             goto out;
464           break;
465       
466         case DBUS_AUTH_STATE_NEED_DISCONNECT:
467           _dbus_verbose (" %s auth state: need to disconnect\n",
468                          TRANSPORT_SIDE (transport));
469           do_io_error (transport);
470           break;
471       
472         case DBUS_AUTH_STATE_AUTHENTICATED:
473           _dbus_verbose (" %s auth state: authenticated\n",
474                          TRANSPORT_SIDE (transport));
475           break;
476         }
477     }
478
479  out:
480   if (auth_completed)
481     *auth_completed = (orig_auth_state != _dbus_transport_get_is_authenticated (transport));
482   
483   check_read_watch (transport);
484   check_write_watch (transport);
485   _dbus_transport_unref (transport);
486
487   if (oom)
488     return FALSE;
489   else
490     return TRUE;
491 }
492
493 /* returns false on oom */
494 static dbus_bool_t
495 do_writing (DBusTransport *transport)
496 {
497   int total;
498   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
499   dbus_bool_t oom;
500   
501   /* No messages without authentication! */
502   if (!_dbus_transport_get_is_authenticated (transport))
503     {
504       _dbus_verbose ("Not authenticated, not writing anything\n");
505       return TRUE;
506     }
507
508   if (transport->disconnected)
509     {
510       _dbus_verbose ("Not connected, not writing anything\n");
511       return TRUE;
512     }
513
514 #if 1
515   _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n",
516                  _dbus_connection_has_messages_to_send_unlocked (transport->connection),
517                  socket_transport->fd);
518 #endif
519   
520   oom = FALSE;
521   total = 0;
522
523   while (!transport->disconnected &&
524          _dbus_connection_has_messages_to_send_unlocked (transport->connection))
525     {
526       int bytes_written;
527       DBusMessage *message;
528       const DBusString *header;
529       const DBusString *body;
530       int header_len, body_len;
531       int total_bytes_to_write;
532       
533       if (total > socket_transport->max_bytes_written_per_iteration)
534         {
535           _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
536                          total, socket_transport->max_bytes_written_per_iteration);
537           goto out;
538         }
539       
540       message = _dbus_connection_get_message_to_send (transport->connection);
541       _dbus_assert (message != NULL);
542       dbus_message_lock (message);
543
544 #if 0
545       _dbus_verbose ("writing message %p\n", message);
546 #endif
547       
548       _dbus_message_get_network_data (message,
549                                       &header, &body);
550
551       header_len = _dbus_string_get_length (header);
552       body_len = _dbus_string_get_length (body);
553
554       if (_dbus_auth_needs_encoding (transport->auth))
555         {
556           /* Does fd passing even make sense with encoded data? */
557           _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport));
558
559           if (_dbus_string_get_length (&socket_transport->encoded_outgoing) == 0)
560             {
561               if (!_dbus_auth_encode_data (transport->auth,
562                                            header, &socket_transport->encoded_outgoing))
563                 {
564                   oom = TRUE;
565                   goto out;
566                 }
567               
568               if (!_dbus_auth_encode_data (transport->auth,
569                                            body, &socket_transport->encoded_outgoing))
570                 {
571                   _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
572                   oom = TRUE;
573                   goto out;
574                 }
575             }
576           
577           total_bytes_to_write = _dbus_string_get_length (&socket_transport->encoded_outgoing);
578
579 #if 0
580           _dbus_verbose ("encoded message is %d bytes\n",
581                          total_bytes_to_write);
582 #endif
583           
584           bytes_written =
585             _dbus_write_socket (socket_transport->fd,
586                                 &socket_transport->encoded_outgoing,
587                                 socket_transport->message_bytes_written,
588                                 total_bytes_to_write - socket_transport->message_bytes_written);
589         }
590       else
591         {
592           total_bytes_to_write = header_len + body_len;
593
594 #if 0
595           _dbus_verbose ("message is %d bytes\n",
596                          total_bytes_to_write);
597 #endif
598
599 #ifdef HAVE_UNIX_FD_PASSING
600           if (socket_transport->message_bytes_written <= 0 && DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport))
601             {
602               /* Send the fds along with the first byte of the message */
603               const int *unix_fds;
604               unsigned n;
605
606               _dbus_message_get_unix_fds(message, &unix_fds, &n);
607
608               bytes_written =
609                 _dbus_write_socket_with_unix_fds_two (socket_transport->fd,
610                                                       header,
611                                                       socket_transport->message_bytes_written,
612                                                       header_len - socket_transport->message_bytes_written,
613                                                       body,
614                                                       0, body_len,
615                                                       unix_fds,
616                                                       n);
617
618               if (bytes_written > 0 && n > 0)
619                 _dbus_verbose("Wrote %i unix fds\n", n);
620             }
621           else
622 #endif
623             {
624               if (socket_transport->message_bytes_written < header_len)
625                 {
626                   bytes_written =
627                     _dbus_write_socket_two (socket_transport->fd,
628                                             header,
629                                             socket_transport->message_bytes_written,
630                                             header_len - socket_transport->message_bytes_written,
631                                             body,
632                                             0, body_len);
633                 }
634               else
635                 {
636                   bytes_written =
637                     _dbus_write_socket (socket_transport->fd,
638                                         body,
639                                         (socket_transport->message_bytes_written - header_len),
640                                         body_len -
641                                         (socket_transport->message_bytes_written - header_len));
642                 }
643             }
644         }
645
646       if (bytes_written < 0)
647         {
648           /* EINTR already handled for us */
649           
650           /* For some discussion of why we also ignore EPIPE here, see
651            * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html
652            */
653           
654           if (_dbus_get_is_errno_eagain_or_ewouldblock () || _dbus_get_is_errno_epipe ())
655             goto out;
656           else
657             {
658               _dbus_verbose ("Error writing to remote app: %s\n",
659                              _dbus_strerror_from_errno ());
660               do_io_error (transport);
661               goto out;
662             }
663         }
664       else
665         {
666           _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
667                          total_bytes_to_write);
668           
669           total += bytes_written;
670           socket_transport->message_bytes_written += bytes_written;
671
672           _dbus_assert (socket_transport->message_bytes_written <=
673                         total_bytes_to_write);
674           
675           if (socket_transport->message_bytes_written == total_bytes_to_write)
676             {
677               socket_transport->message_bytes_written = 0;
678               _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
679               _dbus_string_compact (&socket_transport->encoded_outgoing, 2048);
680
681               _dbus_connection_message_sent (transport->connection,
682                                              message);
683             }
684         }
685     }
686
687  out:
688   if (oom)
689     return FALSE;
690   else
691     return TRUE;
692 }
693
694 /* returns false on out-of-memory */
695 static dbus_bool_t
696 do_reading (DBusTransport *transport)
697 {
698   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
699   DBusString *buffer;
700   int bytes_read;
701   int total;
702   dbus_bool_t oom;
703
704   _dbus_verbose ("%s: fd = %d\n", _DBUS_FUNCTION_NAME,
705                  socket_transport->fd);
706   
707   /* No messages without authentication! */
708   if (!_dbus_transport_get_is_authenticated (transport))
709     return TRUE;
710
711   oom = FALSE;
712   
713   total = 0;
714
715  again:
716   
717   /* See if we've exceeded max messages and need to disable reading */
718   check_read_watch (transport);
719   
720   if (total > socket_transport->max_bytes_read_per_iteration)
721     {
722       _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
723                      total, socket_transport->max_bytes_read_per_iteration);
724       goto out;
725     }
726
727   _dbus_assert (socket_transport->read_watch != NULL ||
728                 transport->disconnected);
729   
730   if (transport->disconnected)
731     goto out;
732
733   if (!dbus_watch_get_enabled (socket_transport->read_watch))
734     return TRUE;
735   
736   if (_dbus_auth_needs_decoding (transport->auth))
737     {
738       /* Does fd passing even make sense with encoded data? */
739       _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport));
740
741       if (_dbus_string_get_length (&socket_transport->encoded_incoming) > 0)
742         bytes_read = _dbus_string_get_length (&socket_transport->encoded_incoming);
743       else
744         bytes_read = _dbus_read_socket (socket_transport->fd,
745                                         &socket_transport->encoded_incoming,
746                                         socket_transport->max_bytes_read_per_iteration);
747
748       _dbus_assert (_dbus_string_get_length (&socket_transport->encoded_incoming) ==
749                     bytes_read);
750       
751       if (bytes_read > 0)
752         {
753           int orig_len;
754           
755           _dbus_message_loader_get_buffer (transport->loader,
756                                            &buffer);
757
758           orig_len = _dbus_string_get_length (buffer);
759           
760           if (!_dbus_auth_decode_data (transport->auth,
761                                        &socket_transport->encoded_incoming,
762                                        buffer))
763             {
764               _dbus_verbose ("Out of memory decoding incoming data\n");
765               _dbus_message_loader_return_buffer (transport->loader,
766                                               buffer,
767                                               _dbus_string_get_length (buffer) - orig_len);
768
769               oom = TRUE;
770               goto out;
771             }
772
773           _dbus_message_loader_return_buffer (transport->loader,
774                                               buffer,
775                                               _dbus_string_get_length (buffer) - orig_len);
776
777           _dbus_string_set_length (&socket_transport->encoded_incoming, 0);
778           _dbus_string_compact (&socket_transport->encoded_incoming, 2048);
779         }
780     }
781   else
782     {
783       _dbus_message_loader_get_buffer (transport->loader,
784                                        &buffer);
785
786 #ifdef HAVE_UNIX_FD_PASSING
787       if (DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport))
788         {
789           int *fds, n_fds;
790
791           if (!_dbus_message_loader_get_unix_fds(transport->loader, &fds, &n_fds))
792             {
793               _dbus_verbose ("Out of memory reading file descriptors\n");
794               _dbus_message_loader_return_buffer (transport->loader, buffer, 0);
795               oom = TRUE;
796               goto out;
797             }
798
799           bytes_read = _dbus_read_socket_with_unix_fds(socket_transport->fd,
800                                                        buffer,
801                                                        socket_transport->max_bytes_read_per_iteration,
802                                                        fds, &n_fds);
803
804           if (bytes_read >= 0 && n_fds > 0)
805             _dbus_verbose("Read %i unix fds\n", n_fds);
806
807           _dbus_message_loader_return_unix_fds(transport->loader, fds, bytes_read < 0 ? 0 : n_fds);
808         }
809       else
810 #endif
811         {
812           bytes_read = _dbus_read_socket (socket_transport->fd,
813                                           buffer, socket_transport->max_bytes_read_per_iteration);
814         }
815
816       _dbus_message_loader_return_buffer (transport->loader,
817                                           buffer,
818                                           bytes_read < 0 ? 0 : bytes_read);
819     }
820   
821   if (bytes_read < 0)
822     {
823       /* EINTR already handled for us */
824
825       if (_dbus_get_is_errno_enomem ())
826         {
827           _dbus_verbose ("Out of memory in read()/do_reading()\n");
828           oom = TRUE;
829           goto out;
830         }
831       else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
832         goto out;
833       else
834         {
835           _dbus_verbose ("Error reading from remote app: %s\n",
836                          _dbus_strerror_from_errno ());
837           do_io_error (transport);
838           goto out;
839         }
840     }
841   else if (bytes_read == 0)
842     {
843       _dbus_verbose ("Disconnected from remote app\n");
844       do_io_error (transport);
845       goto out;
846     }
847   else
848     {
849       _dbus_verbose (" read %d bytes\n", bytes_read);
850       
851       total += bytes_read;      
852
853       if (!_dbus_transport_queue_messages (transport))
854         {
855           oom = TRUE;
856           _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
857           goto out;
858         }
859       
860       /* Try reading more data until we get EAGAIN and return, or
861        * exceed max bytes per iteration.  If in blocking mode of
862        * course we'll block instead of returning.
863        */
864       goto again;
865     }
866
867  out:
868   if (oom)
869     return FALSE;
870   else
871     return TRUE;
872 }
873
874 static dbus_bool_t
875 unix_error_with_read_to_come (DBusTransport *itransport,
876                               DBusWatch     *watch,
877                               unsigned int   flags)
878 {
879   DBusTransportSocket *transport = (DBusTransportSocket *) itransport;
880
881   if (!(flags & DBUS_WATCH_HANGUP || flags & DBUS_WATCH_ERROR))
882     return FALSE;
883    
884   /* If we have a read watch enabled ...
885      we -might have data incoming ... => handle the HANGUP there */
886   if (watch != transport->read_watch &&
887       _dbus_watch_get_enabled (transport->read_watch))
888     return FALSE;
889       
890   return TRUE; 
891 }
892
893 static dbus_bool_t
894 socket_handle_watch (DBusTransport *transport,
895                    DBusWatch     *watch,
896                    unsigned int   flags)
897 {
898   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
899
900   _dbus_assert (watch == socket_transport->read_watch ||
901                 watch == socket_transport->write_watch);
902   _dbus_assert (watch != NULL);
903   
904   /* If we hit an error here on a write watch, don't disconnect the transport yet because data can
905    * still be in the buffer and do_reading may need several iteration to read
906    * it all (because of its max_bytes_read_per_iteration limit). 
907    */
908   if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags))
909     {
910       _dbus_verbose ("Hang up or error on watch\n");
911       _dbus_transport_disconnect (transport);
912       return TRUE;
913     }
914   
915   if (watch == socket_transport->read_watch &&
916       (flags & DBUS_WATCH_READABLE))
917     {
918       dbus_bool_t auth_finished;
919 #if 1
920       _dbus_verbose ("handling read watch %p flags = %x\n",
921                      watch, flags);
922 #endif
923       if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
924         return FALSE;
925
926       /* We don't want to do a read immediately following
927        * a successful authentication.  This is so we
928        * have a chance to propagate the authentication
929        * state further up.  Specifically, we need to
930        * process any pending data from the auth object.
931        */
932       if (!auth_finished)
933         {
934           if (!do_reading (transport))
935             {
936               _dbus_verbose ("no memory to read\n");
937               return FALSE;
938             }
939         }
940       else
941         {
942           _dbus_verbose ("Not reading anything since we just completed the authentication\n");
943         }
944     }
945   else if (watch == socket_transport->write_watch &&
946            (flags & DBUS_WATCH_WRITABLE))
947     {
948 #if 1
949       _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
950                      _dbus_connection_has_messages_to_send_unlocked (transport->connection));
951 #endif
952       if (!do_authentication (transport, FALSE, TRUE, NULL))
953         return FALSE;
954       
955       if (!do_writing (transport))
956         {
957           _dbus_verbose ("no memory to write\n");
958           return FALSE;
959         }
960
961       /* See if we still need the write watch */
962       check_write_watch (transport);
963     }
964 #ifdef DBUS_ENABLE_VERBOSE_MODE
965   else
966     {
967       if (watch == socket_transport->read_watch)
968         _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
969                        flags);
970       else if (watch == socket_transport->write_watch)
971         _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
972                        flags);
973       else
974         _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
975                        watch, dbus_watch_get_socket (watch));
976     }
977 #endif /* DBUS_ENABLE_VERBOSE_MODE */
978
979   return TRUE;
980 }
981
982 static void
983 socket_disconnect (DBusTransport *transport)
984 {
985   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
986
987   _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
988   
989   free_watches (transport);
990   
991   _dbus_close_socket (socket_transport->fd, NULL);
992   socket_transport->fd = -1;
993 }
994
995 static dbus_bool_t
996 socket_connection_set (DBusTransport *transport)
997 {
998   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
999
1000   _dbus_watch_set_handler (socket_transport->write_watch,
1001                            _dbus_connection_handle_watch,
1002                            transport->connection, NULL);
1003
1004   _dbus_watch_set_handler (socket_transport->read_watch,
1005                            _dbus_connection_handle_watch,
1006                            transport->connection, NULL);
1007   
1008   if (!_dbus_connection_add_watch_unlocked (transport->connection,
1009                                             socket_transport->write_watch))
1010     return FALSE;
1011
1012   if (!_dbus_connection_add_watch_unlocked (transport->connection,
1013                                             socket_transport->read_watch))
1014     {
1015       _dbus_connection_remove_watch_unlocked (transport->connection,
1016                                               socket_transport->write_watch);
1017       return FALSE;
1018     }
1019
1020   check_read_watch (transport);
1021   check_write_watch (transport);
1022
1023   return TRUE;
1024 }
1025
1026 /**
1027  * @todo We need to have a way to wake up the select sleep if
1028  * a new iteration request comes in with a flag (read/write) that
1029  * we're not currently serving. Otherwise a call that just reads
1030  * could block a write call forever (if there are no incoming
1031  * messages).
1032  */
1033 static  void
1034 socket_do_iteration (DBusTransport *transport,
1035                    unsigned int   flags,
1036                    int            timeout_milliseconds)
1037 {
1038   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1039   DBusPollFD poll_fd;
1040   int poll_res;
1041   int poll_timeout;
1042
1043   _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
1044                  flags & DBUS_ITERATION_DO_READING ? "read" : "",
1045                  flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
1046                  timeout_milliseconds,
1047                  socket_transport->read_watch,
1048                  socket_transport->write_watch,
1049                  socket_transport->fd);
1050   
1051   /* the passed in DO_READING/DO_WRITING flags indicate whether to
1052    * read/write messages, but regardless of those we may need to block
1053    * for reading/writing to do auth.  But if we do reading for auth,
1054    * we don't want to read any messages yet if not given DO_READING.
1055    */
1056
1057   poll_fd.fd = socket_transport->fd;
1058   poll_fd.events = 0;
1059   
1060   if (_dbus_transport_get_is_authenticated (transport))
1061     {
1062       /* This is kind of a hack; if we have stuff to write, then try
1063        * to avoid the poll. This is probably about a 5% speedup on an
1064        * echo client/server.
1065        *
1066        * If both reading and writing were requested, we want to avoid this
1067        * since it could have funky effects:
1068        *   - both ends spinning waiting for the other one to read
1069        *     data so they can finish writing
1070        *   - prioritizing all writing ahead of reading
1071        */
1072       if ((flags & DBUS_ITERATION_DO_WRITING) &&
1073           !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
1074           !transport->disconnected &&
1075           _dbus_connection_has_messages_to_send_unlocked (transport->connection))
1076         {
1077           do_writing (transport);
1078
1079           if (transport->disconnected ||
1080               !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
1081             goto out;
1082         }
1083
1084       /* If we get here, we decided to do the poll() after all */
1085       _dbus_assert (socket_transport->read_watch);
1086       if (flags & DBUS_ITERATION_DO_READING)
1087         poll_fd.events |= _DBUS_POLLIN;
1088
1089       _dbus_assert (socket_transport->write_watch);
1090       if (flags & DBUS_ITERATION_DO_WRITING)
1091         poll_fd.events |= _DBUS_POLLOUT;
1092     }
1093   else
1094     {
1095       DBusAuthState auth_state;
1096       
1097       auth_state = _dbus_auth_do_work (transport->auth);
1098
1099       if (transport->receive_credentials_pending ||
1100           auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
1101         poll_fd.events |= _DBUS_POLLIN;
1102
1103       if (transport->send_credentials_pending ||
1104           auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
1105         poll_fd.events |= _DBUS_POLLOUT;
1106     }
1107
1108   if (poll_fd.events)
1109     {
1110       if (flags & DBUS_ITERATION_BLOCK)
1111         poll_timeout = timeout_milliseconds;
1112       else
1113         poll_timeout = 0;
1114
1115       /* For blocking selects we drop the connection lock here
1116        * to avoid blocking out connection access during a potentially
1117        * indefinite blocking call. The io path is still protected
1118        * by the io_path_cond condvar, so we won't reenter this.
1119        */
1120       if (flags & DBUS_ITERATION_BLOCK)
1121         {
1122           _dbus_verbose ("unlock %s pre poll\n", _DBUS_FUNCTION_NAME);
1123           _dbus_connection_unlock (transport->connection);
1124         }
1125       
1126     again:
1127       poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
1128
1129       if (poll_res < 0 && _dbus_get_is_errno_eintr ())
1130         goto again;
1131
1132       if (flags & DBUS_ITERATION_BLOCK)
1133         {
1134           _dbus_verbose ("lock %s post poll\n", _DBUS_FUNCTION_NAME);
1135           _dbus_connection_lock (transport->connection);
1136         }
1137       
1138       if (poll_res >= 0)
1139         {
1140           if (poll_res == 0)
1141             poll_fd.revents = 0; /* some concern that posix does not guarantee this;
1142                                   * valgrind flags it as an error. though it probably
1143                                   * is guaranteed on linux at least.
1144                                   */
1145           
1146           if (poll_fd.revents & _DBUS_POLLERR)
1147             do_io_error (transport);
1148           else
1149             {
1150               dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
1151               dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
1152               dbus_bool_t authentication_completed;
1153
1154               _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
1155                              need_read, need_write);
1156               do_authentication (transport, need_read, need_write,
1157                                  &authentication_completed);
1158
1159               /* See comment in socket_handle_watch. */
1160               if (authentication_completed)
1161                 goto out;
1162                                  
1163               if (need_read && (flags & DBUS_ITERATION_DO_READING))
1164                 do_reading (transport);
1165               if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
1166                 do_writing (transport);
1167             }
1168         }
1169       else
1170         {
1171           _dbus_verbose ("Error from _dbus_poll(): %s\n",
1172                          _dbus_strerror_from_errno ());
1173         }
1174     }
1175
1176
1177  out:
1178   /* We need to install the write watch only if we did not
1179    * successfully write everything. Note we need to be careful that we
1180    * don't call check_write_watch *before* do_writing, since it's
1181    * inefficient to add the write watch, and we can avoid it most of
1182    * the time since we can write immediately.
1183    * 
1184    * However, we MUST always call check_write_watch(); DBusConnection code
1185    * relies on the fact that running an iteration will notice that
1186    * messages are pending.
1187    */
1188   check_write_watch (transport);
1189
1190   _dbus_verbose (" ... leaving do_iteration()\n");
1191 }
1192
1193 static void
1194 socket_live_messages_changed (DBusTransport *transport)
1195 {
1196   /* See if we should look for incoming messages again */
1197   check_read_watch (transport);
1198 }
1199
1200
1201 static dbus_bool_t
1202 socket_get_socket_fd (DBusTransport *transport,
1203                       int           *fd_p)
1204 {
1205   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1206   
1207   *fd_p = socket_transport->fd;
1208   
1209   return TRUE;
1210 }
1211
1212 static const DBusTransportVTable socket_vtable = {
1213   socket_finalize,
1214   socket_handle_watch,
1215   socket_disconnect,
1216   socket_connection_set,
1217   socket_do_iteration,
1218   socket_live_messages_changed,
1219   socket_get_socket_fd
1220 };
1221
1222 /**
1223  * Creates a new transport for the given socket file descriptor.  The file
1224  * descriptor must be nonblocking (use _dbus_set_fd_nonblocking() to
1225  * make it so). This function is shared by various transports that
1226  * boil down to a full duplex file descriptor.
1227  *
1228  * @param fd the file descriptor.
1229  * @param server_guid non-#NULL if this transport is on the server side of a connection
1230  * @param address the transport's address
1231  * @returns the new transport, or #NULL if no memory.
1232  */
1233 DBusTransport*
1234 _dbus_transport_new_for_socket (int               fd,
1235                                 const DBusString *server_guid,
1236                                 const DBusString *address)
1237 {
1238   DBusTransportSocket *socket_transport;
1239   
1240   socket_transport = dbus_new0 (DBusTransportSocket, 1);
1241   if (socket_transport == NULL)
1242     return NULL;
1243
1244   if (!_dbus_string_init (&socket_transport->encoded_outgoing))
1245     goto failed_0;
1246
1247   if (!_dbus_string_init (&socket_transport->encoded_incoming))
1248     goto failed_1;
1249   
1250   socket_transport->write_watch = _dbus_watch_new (fd,
1251                                                  DBUS_WATCH_WRITABLE,
1252                                                  FALSE,
1253                                                  NULL, NULL, NULL);
1254   if (socket_transport->write_watch == NULL)
1255     goto failed_2;
1256   
1257   socket_transport->read_watch = _dbus_watch_new (fd,
1258                                                 DBUS_WATCH_READABLE,
1259                                                 FALSE,
1260                                                 NULL, NULL, NULL);
1261   if (socket_transport->read_watch == NULL)
1262     goto failed_3;
1263
1264   if (!_dbus_transport_init_base (&socket_transport->base,
1265                                   &socket_vtable,
1266                                   server_guid, address))
1267     goto failed_4;
1268
1269 #ifdef HAVE_UNIX_FD_PASSING
1270   _dbus_auth_set_unix_fd_possible(socket_transport->base.auth, _dbus_socket_can_pass_unix_fd(fd));
1271 #endif
1272
1273   socket_transport->fd = fd;
1274   socket_transport->message_bytes_written = 0;
1275   
1276   /* These values should probably be tunable or something. */     
1277   socket_transport->max_bytes_read_per_iteration = 2048;
1278   socket_transport->max_bytes_written_per_iteration = 2048;
1279   
1280   return (DBusTransport*) socket_transport;
1281
1282  failed_4:
1283   _dbus_watch_unref (socket_transport->read_watch);
1284  failed_3:
1285   _dbus_watch_unref (socket_transport->write_watch);
1286  failed_2:
1287   _dbus_string_free (&socket_transport->encoded_incoming);
1288  failed_1:
1289   _dbus_string_free (&socket_transport->encoded_outgoing);
1290  failed_0:
1291   dbus_free (socket_transport);
1292   return NULL;
1293 }
1294
1295 /**
1296  * Creates a new transport for the given hostname and port.
1297  * If host is NULL, it will default to localhost
1298  *
1299  * @param host the host to connect to
1300  * @param port the port to connect to
1301  * @param family the address family to connect to
1302  * @param path to nonce file
1303  * @param error location to store reason for failure.
1304  * @returns a new transport, or #NULL on failure.
1305  */
1306 DBusTransport*
1307 _dbus_transport_new_for_tcp_socket (const char     *host,
1308                                     const char     *port,
1309                                     const char     *family,
1310                                     const char     *noncefile,
1311                                     DBusError      *error)
1312 {
1313   int fd;
1314   DBusTransport *transport;
1315   DBusString address;
1316   
1317   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1318
1319   if (!_dbus_string_init (&address))
1320     {
1321       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1322       return NULL;
1323     }
1324
1325   if (host == NULL)
1326     host = "localhost";
1327
1328   if (!_dbus_string_append (&address, noncefile ? "nonce-tcp:" : "tcp:"))
1329     goto error;
1330
1331   if (!_dbus_string_append (&address, "host=") ||
1332       !_dbus_string_append (&address, host))
1333     goto error;
1334
1335   if (!_dbus_string_append (&address, ",port=") ||
1336       !_dbus_string_append (&address, port))
1337     goto error;
1338
1339   if (family != NULL &&
1340       (!_dbus_string_append (&address, "family=") ||
1341        !_dbus_string_append (&address, family)))
1342     goto error;
1343
1344   if (noncefile != NULL &&
1345       (!_dbus_string_append (&address, "noncefile=") ||
1346        !_dbus_string_append (&address, noncefile)))
1347     goto error;
1348
1349   fd = _dbus_connect_tcp_socket_with_nonce (host, port, family, noncefile, error);
1350   if (fd < 0)
1351     {
1352       _DBUS_ASSERT_ERROR_IS_SET (error);
1353       _dbus_string_free (&address);
1354       return NULL;
1355     }
1356
1357   _dbus_verbose ("Successfully connected to tcp socket %s:%s\n",
1358                  host, port);
1359   
1360   transport = _dbus_transport_new_for_socket (fd, NULL, &address);
1361   _dbus_string_free (&address);
1362   if (transport == NULL)
1363     {
1364       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1365       _dbus_close_socket (fd, NULL);
1366       fd = -1;
1367     }
1368
1369   return transport;
1370
1371 error:
1372   _dbus_string_free (&address);
1373   dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1374   return NULL;
1375 }
1376
1377 /**
1378  * Opens a TCP socket transport.
1379  * 
1380  * @param entry the address entry to try opening as a tcp transport.
1381  * @param transport_p return location for the opened transport
1382  * @param error error to be set
1383  * @returns result of the attempt
1384  */
1385 DBusTransportOpenResult
1386 _dbus_transport_open_socket(DBusAddressEntry  *entry,
1387                             DBusTransport    **transport_p,                            
1388                             DBusError         *error)
1389 {
1390   const char *method;
1391   dbus_bool_t isTcp;
1392   dbus_bool_t isNonceTcp;
1393   
1394   method = dbus_address_entry_get_method (entry);
1395   _dbus_assert (method != NULL);
1396
1397   isTcp = strcmp (method, "tcp") == 0;
1398   isNonceTcp = strcmp (method, "nonce-tcp") == 0;
1399
1400   if (isTcp || isNonceTcp)
1401     {
1402       const char *host = dbus_address_entry_get_value (entry, "host");
1403       const char *port = dbus_address_entry_get_value (entry, "port");
1404       const char *family = dbus_address_entry_get_value (entry, "family");
1405       const char *noncefile = dbus_address_entry_get_value (entry, "noncefile");
1406
1407       if ((isNonceTcp == TRUE) != (noncefile != NULL)) {
1408           _dbus_set_bad_address (error, method, "noncefile", NULL);
1409           return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
1410       }
1411
1412       if (port == NULL)
1413         {
1414           _dbus_set_bad_address (error, method, "port", NULL);
1415           return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
1416         }
1417
1418       *transport_p = _dbus_transport_new_for_tcp_socket (host, port, family, noncefile, error);
1419       if (*transport_p == NULL)
1420         {
1421           _DBUS_ASSERT_ERROR_IS_SET (error);
1422           return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
1423         }
1424       else
1425         {
1426           _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1427           return DBUS_TRANSPORT_OPEN_OK;
1428         }
1429     }
1430   else
1431     {
1432       _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1433       return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
1434     }
1435 }
1436
1437 /** @} */
1438