dbus daemon emulation exteneded
[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 #include <stdio.h>  //todo to remove
33
34
35 /**
36  * @defgroup DBusTransportSocket DBusTransport implementations for sockets
37  * @ingroup  DBusInternals
38  * @brief Implementation details of DBusTransport on sockets
39  *
40  * @{
41  */
42
43 /**
44  * Opaque object representing a socket file descriptor transport.
45  */
46 typedef struct DBusTransportSocket DBusTransportSocket;
47
48 /**
49  * Implementation details of DBusTransportSocket. All members are private.
50  */
51 struct DBusTransportSocket
52 {
53   DBusTransport base;                   /**< Parent instance */
54   int fd;                               /**< File descriptor. */
55   DBusWatch *read_watch;                /**< Watch for readability. */
56   DBusWatch *write_watch;               /**< Watch for writability. */
57
58   int max_bytes_read_per_iteration;     /**< To avoid blocking too long. */
59   int max_bytes_written_per_iteration;  /**< To avoid blocking too long. */
60
61   int message_bytes_written;            /**< Number of bytes of current
62                                          *   outgoing message that have
63                                          *   been written.
64                                          */
65   DBusString encoded_outgoing;          /**< Encoded version of current
66                                          *   outgoing message.
67                                          */
68   DBusString encoded_incoming;          /**< Encoded version of current
69                                          *   incoming data.
70                                          */
71 };
72
73 static void
74 free_watches (DBusTransport *transport)
75 {
76   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
77
78   _dbus_verbose ("start\n");
79   
80   if (socket_transport->read_watch)
81     {
82       if (transport->connection)
83         _dbus_connection_remove_watch_unlocked (transport->connection,
84                                                 socket_transport->read_watch);
85       _dbus_watch_invalidate (socket_transport->read_watch);
86       _dbus_watch_unref (socket_transport->read_watch);
87       socket_transport->read_watch = NULL;
88     }
89
90   if (socket_transport->write_watch)
91     {
92       if (transport->connection)
93         _dbus_connection_remove_watch_unlocked (transport->connection,
94                                                 socket_transport->write_watch);
95       _dbus_watch_invalidate (socket_transport->write_watch);
96       _dbus_watch_unref (socket_transport->write_watch);
97       socket_transport->write_watch = NULL;
98     }
99
100   _dbus_verbose ("end\n");
101 }
102
103 static void
104 socket_finalize (DBusTransport *transport)
105 {
106   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
107
108   _dbus_verbose ("\n");
109   
110   free_watches (transport);
111
112   _dbus_string_free (&socket_transport->encoded_outgoing);
113   _dbus_string_free (&socket_transport->encoded_incoming);
114   
115   _dbus_transport_finalize_base (transport);
116
117   _dbus_assert (socket_transport->read_watch == NULL);
118   _dbus_assert (socket_transport->write_watch == NULL);
119   
120   dbus_free (transport);
121 }
122
123 static void
124 check_write_watch (DBusTransport *transport)
125 {
126   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
127   dbus_bool_t needed;
128
129   if (transport->connection == NULL)
130     return;
131
132   if (transport->disconnected)
133     {
134       _dbus_assert (socket_transport->write_watch == NULL);
135       return;
136     }
137   
138   _dbus_transport_ref (transport);
139
140   if (_dbus_transport_get_is_authenticated (transport))
141     needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
142   else
143     {
144       if (transport->send_credentials_pending)
145         needed = TRUE;
146       else
147         {
148           DBusAuthState auth_state;
149           
150           auth_state = _dbus_auth_do_work (transport->auth);
151           
152           /* If we need memory we install the write watch just in case,
153            * if there's no need for it, it will get de-installed
154            * next time we try reading.
155            */
156           if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND ||
157               auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
158             needed = TRUE;
159           else
160             needed = FALSE;
161         }
162     }
163
164   _dbus_verbose ("check_write_watch(): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
165                  needed, transport->connection, socket_transport->write_watch,
166                  socket_transport->fd,
167                  _dbus_connection_has_messages_to_send_unlocked (transport->connection));
168
169   _dbus_connection_toggle_watch_unlocked (transport->connection,
170                                           socket_transport->write_watch,
171                                           needed);
172
173   _dbus_transport_unref (transport);
174 }
175
176 static void
177 check_read_watch (DBusTransport *transport)
178 {
179   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
180   dbus_bool_t need_read_watch;
181
182   _dbus_verbose ("fd = %d\n",socket_transport->fd);
183   
184   if (transport->connection == NULL)
185     return;
186
187   if (transport->disconnected)
188     {
189       _dbus_assert (socket_transport->read_watch == NULL);
190       return;
191     }
192   
193   _dbus_transport_ref (transport);
194
195   if (_dbus_transport_get_is_authenticated (transport))
196     need_read_watch =
197       (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
198       (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
199   else
200     {
201       if (transport->receive_credentials_pending)
202         need_read_watch = TRUE;
203       else
204         {
205           /* The reason to disable need_read_watch when not WAITING_FOR_INPUT
206            * is to avoid spinning on the file descriptor when we're waiting
207            * to write or for some other part of the auth process
208            */
209           DBusAuthState auth_state;
210           
211           auth_state = _dbus_auth_do_work (transport->auth);
212
213           /* If we need memory we install the read watch just in case,
214            * if there's no need for it, it will get de-installed
215            * next time we try reading. If we're authenticated we
216            * install it since we normally have it installed while
217            * authenticated.
218            */
219           if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT ||
220               auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY ||
221               auth_state == DBUS_AUTH_STATE_AUTHENTICATED)
222             need_read_watch = TRUE;
223           else
224             need_read_watch = FALSE;
225         }
226     }
227
228   _dbus_verbose ("  setting read watch enabled = %d\n", need_read_watch);
229   _dbus_connection_toggle_watch_unlocked (transport->connection,
230                                           socket_transport->read_watch,
231                                           need_read_watch);
232
233   _dbus_transport_unref (transport);
234 }
235
236 static void
237 do_io_error (DBusTransport *transport)
238 {
239   _dbus_transport_ref (transport);
240   _dbus_transport_disconnect (transport);
241   _dbus_transport_unref (transport);
242 }
243
244 /* return value is whether we successfully read any new data. */
245 static dbus_bool_t
246 read_data_into_auth (DBusTransport *transport,
247                      dbus_bool_t   *oom)
248 {
249   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
250   DBusString *buffer;
251   int bytes_read;
252   
253   *oom = FALSE;
254
255   _dbus_auth_get_buffer (transport->auth, &buffer);
256   
257   bytes_read = _dbus_read_socket (socket_transport->fd,
258                                   buffer, socket_transport->max_bytes_read_per_iteration);
259
260   _dbus_auth_return_buffer (transport->auth, buffer,
261                             bytes_read > 0 ? bytes_read : 0);
262
263   if (bytes_read > 0)
264     {
265       _dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
266
267       return TRUE;
268     }
269   else if (bytes_read < 0)
270     {
271       /* EINTR already handled for us */
272
273       if (_dbus_get_is_errno_enomem ())
274         {
275           *oom = TRUE;
276         }
277       else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
278         ; /* do nothing, just return FALSE below */
279       else
280         {
281           _dbus_verbose ("Error reading from remote app: %s\n",
282                          _dbus_strerror_from_errno ());
283           do_io_error (transport);
284         }
285
286       return FALSE;
287     }
288   else
289     {
290       _dbus_assert (bytes_read == 0);
291       
292       _dbus_verbose ("Disconnected from remote app\n");
293       do_io_error (transport);
294
295       return FALSE;
296     }
297 }
298
299 /* Return value is whether we successfully wrote any bytes */
300 static dbus_bool_t
301 write_data_from_auth (DBusTransport *transport)
302 {
303   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
304   int bytes_written;
305   const DBusString *buffer;
306
307   if (!_dbus_auth_get_bytes_to_send (transport->auth,
308                                      &buffer))
309     return FALSE;
310   
311   bytes_written = _dbus_write_socket (socket_transport->fd,
312                                       buffer,
313                                       0, _dbus_string_get_length (buffer));
314
315   if (bytes_written > 0)
316     {
317       _dbus_auth_bytes_sent (transport->auth, bytes_written);
318       return TRUE;
319     }
320   else if (bytes_written < 0)
321     {
322       /* EINTR already handled for us */
323       
324       if (_dbus_get_is_errno_eagain_or_ewouldblock ())
325         ;
326       else
327         {
328           _dbus_verbose ("Error writing to remote app: %s\n",
329                          _dbus_strerror_from_errno ());
330           do_io_error (transport);
331         }
332     }
333
334   return FALSE;
335 }
336
337 /* FALSE on OOM */
338 static dbus_bool_t
339 exchange_credentials (DBusTransport *transport,
340                       dbus_bool_t    do_reading,
341                       dbus_bool_t    do_writing)
342 {
343   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
344   DBusError error = DBUS_ERROR_INIT;
345
346   _dbus_verbose ("exchange_credentials: do_reading = %d, do_writing = %d\n",
347                   do_reading, do_writing);
348
349   if (do_writing && transport->send_credentials_pending)
350     {
351       if (_dbus_send_credentials_socket (socket_transport->fd,
352                                          &error))
353         {
354           transport->send_credentials_pending = FALSE;
355         }
356       else
357         {
358           _dbus_verbose ("Failed to write credentials: %s\n", error.message);
359           dbus_error_free (&error);
360           do_io_error (transport);
361         }
362     }
363   
364   if (do_reading && transport->receive_credentials_pending)
365     {
366       /* FIXME this can fail due to IO error _or_ OOM, broken
367        * (somewhat tricky to fix since the OOM error can be set after
368        * we already read the credentials byte, so basically we need to
369        * separate reading the byte and storing it in the
370        * transport->credentials). Does not really matter for now
371        * because storing in credentials never actually fails on unix.
372        */      
373       if (_dbus_read_credentials_socket (socket_transport->fd,
374                                          transport->credentials,
375                                          &error))
376         {
377           transport->receive_credentials_pending = FALSE;
378         }
379       else
380         {
381           _dbus_verbose ("Failed to read credentials %s\n", error.message);
382           dbus_error_free (&error);
383           do_io_error (transport);
384         }
385     }
386
387   if (!(transport->send_credentials_pending ||
388         transport->receive_credentials_pending))
389     {
390       if (!_dbus_auth_set_credentials (transport->auth,
391                                        transport->credentials))
392         return FALSE;
393     }
394
395   return TRUE;
396 }
397
398 static dbus_bool_t
399 do_authentication (DBusTransport *transport,
400                    dbus_bool_t    do_reading,
401                    dbus_bool_t    do_writing,
402                    dbus_bool_t   *auth_completed)
403 {
404   dbus_bool_t oom;
405   dbus_bool_t orig_auth_state;
406
407   oom = FALSE;
408   
409   orig_auth_state = _dbus_transport_get_is_authenticated (transport);
410
411   /* This is essential to avoid the check_write_watch() at the end,
412    * we don't want to add a write watch in do_iteration before
413    * we try writing and get EAGAIN
414    */
415   if (orig_auth_state)
416     {
417       if (auth_completed)
418         *auth_completed = FALSE;
419       return TRUE;
420     }
421   
422   _dbus_transport_ref (transport);
423   
424   while (!_dbus_transport_get_is_authenticated (transport) &&
425          _dbus_transport_get_is_connected (transport))
426     {      
427       if (!exchange_credentials (transport, do_reading, do_writing))
428         {
429           /* OOM */
430           oom = TRUE;
431           goto out;
432         }
433       
434       if (transport->send_credentials_pending ||
435           transport->receive_credentials_pending)
436         {
437           _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
438                          transport->send_credentials_pending,
439                          transport->receive_credentials_pending);
440           goto out;
441         }
442
443 #define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client")
444       switch (_dbus_auth_do_work (transport->auth))
445         {
446         case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
447           _dbus_verbose (" %s auth state: waiting for input\n",
448                          TRANSPORT_SIDE (transport));
449           if (!do_reading || !read_data_into_auth (transport, &oom))
450             goto out;
451           break;
452       
453         case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
454           _dbus_verbose (" %s auth state: waiting for memory\n",
455                          TRANSPORT_SIDE (transport));
456           oom = TRUE;
457           goto out;
458           break;
459       
460         case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
461           _dbus_verbose (" %s auth state: bytes to send\n",
462                          TRANSPORT_SIDE (transport));
463           if (!do_writing || !write_data_from_auth (transport))
464             goto out;
465           break;
466       
467         case DBUS_AUTH_STATE_NEED_DISCONNECT:
468           _dbus_verbose (" %s auth state: need to disconnect\n",
469                          TRANSPORT_SIDE (transport));
470           do_io_error (transport);
471           break;
472       
473         case DBUS_AUTH_STATE_AUTHENTICATED:
474           _dbus_verbose (" %s auth state: authenticated\n",
475                          TRANSPORT_SIDE (transport));
476           break;
477         }
478     }
479
480  out:
481   if (auth_completed)
482     *auth_completed = (orig_auth_state != _dbus_transport_get_is_authenticated (transport));
483   
484   check_read_watch (transport);
485   check_write_watch (transport);
486   _dbus_transport_unref (transport);
487
488   if (oom)
489     return FALSE;
490   else
491     return TRUE;
492 }
493
494 /* returns false on oom */
495 static dbus_bool_t
496 do_writing (DBusTransport *transport)
497 {
498   int total;
499   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
500   dbus_bool_t oom;
501   
502   /* No messages without authentication! */
503   if (!_dbus_transport_get_is_authenticated (transport))
504     {
505       _dbus_verbose ("Not authenticated, not writing anything\n");
506       return TRUE;
507     }
508
509   if (transport->disconnected)
510     {
511       _dbus_verbose ("Not connected, not writing anything\n");
512       return TRUE;
513     }
514
515 #if 1
516   _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n",
517                  _dbus_connection_has_messages_to_send_unlocked (transport->connection),
518                  socket_transport->fd);
519 #endif
520   
521   oom = FALSE;
522   total = 0;
523
524   while (!transport->disconnected &&
525          _dbus_connection_has_messages_to_send_unlocked (transport->connection))
526     {
527       int bytes_written;
528       DBusMessage *message;
529       const DBusString *header;
530       const DBusString *body;
531       int header_len, body_len;
532       int total_bytes_to_write;
533       
534       if (total > socket_transport->max_bytes_written_per_iteration)
535         {
536           _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
537                          total, socket_transport->max_bytes_written_per_iteration);
538           goto out;
539         }
540       
541       message = _dbus_connection_get_message_to_send (transport->connection);
542       _dbus_assert (message != NULL);
543       dbus_message_lock (message);
544
545 #if 0
546       _dbus_verbose ("writing message %p\n", message);
547 #endif
548       
549       _dbus_message_get_network_data (message,
550                                       &header, &body);
551
552       header_len = _dbus_string_get_length (header);
553       body_len = _dbus_string_get_length (body);
554
555       if (_dbus_auth_needs_encoding (transport->auth))
556         {
557           /* Does fd passing even make sense with encoded data? */
558           _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport));
559
560           if (_dbus_string_get_length (&socket_transport->encoded_outgoing) == 0)
561             {
562               if (!_dbus_auth_encode_data (transport->auth,
563                                            header, &socket_transport->encoded_outgoing))
564                 {
565                   oom = TRUE;
566                   goto out;
567                 }
568               
569               if (!_dbus_auth_encode_data (transport->auth,
570                                            body, &socket_transport->encoded_outgoing))
571                 {
572                   _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
573                   oom = TRUE;
574                   goto out;
575                 }
576             }
577           
578           total_bytes_to_write = _dbus_string_get_length (&socket_transport->encoded_outgoing);
579
580 #if 0
581           _dbus_verbose ("encoded message is %d bytes\n",
582                          total_bytes_to_write);
583 #endif
584           
585           bytes_written =
586             _dbus_write_socket (socket_transport->fd,
587                                 &socket_transport->encoded_outgoing,
588                                 socket_transport->message_bytes_written,
589                                 total_bytes_to_write - socket_transport->message_bytes_written);
590         }
591       else
592         {
593           total_bytes_to_write = header_len + body_len;
594
595 #if 0
596           _dbus_verbose ("message is %d bytes\n",
597                          total_bytes_to_write);
598 #endif
599
600 #ifdef HAVE_UNIX_FD_PASSING
601           if (socket_transport->message_bytes_written <= 0 && DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport))
602             {
603               /* Send the fds along with the first byte of the message */
604               const int *unix_fds;
605               unsigned n;
606
607               _dbus_message_get_unix_fds(message, &unix_fds, &n);
608
609               bytes_written =
610                 _dbus_write_socket_with_unix_fds_two (socket_transport->fd,
611                                                       header,
612                                                       socket_transport->message_bytes_written,
613                                                       header_len - socket_transport->message_bytes_written,
614                                                       body,
615                                                       0, body_len,
616                                                       unix_fds,
617                                                       n);
618
619               if (bytes_written > 0 && n > 0)
620                 _dbus_verbose("Wrote %i unix fds\n", n);
621             }
622           else
623 #endif
624             {
625               if (socket_transport->message_bytes_written < header_len)
626                 {
627                   bytes_written =
628                     _dbus_write_socket_two (socket_transport->fd,
629                                             header,
630                                             socket_transport->message_bytes_written,
631                                             header_len - socket_transport->message_bytes_written,
632                                             body,
633                                             0, body_len);
634                 }
635               else
636                 {
637                   bytes_written =
638                     _dbus_write_socket (socket_transport->fd,
639                                         body,
640                                         (socket_transport->message_bytes_written - header_len),
641                                         body_len -
642                                         (socket_transport->message_bytes_written - header_len));
643                 }
644             }
645         }
646
647       if (bytes_written < 0)
648         {
649           /* EINTR already handled for us */
650           
651           /* For some discussion of why we also ignore EPIPE here, see
652            * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html
653            */
654           
655           if (_dbus_get_is_errno_eagain_or_ewouldblock () || _dbus_get_is_errno_epipe ())
656             goto out;
657           else
658             {
659               _dbus_verbose ("Error writing to remote app: %s\n",
660                              _dbus_strerror_from_errno ());
661               do_io_error (transport);
662               goto out;
663             }
664         }
665       else
666         {
667           _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
668                          total_bytes_to_write);
669           
670           total += bytes_written;
671           socket_transport->message_bytes_written += bytes_written;
672
673           _dbus_assert (socket_transport->message_bytes_written <=
674                         total_bytes_to_write);
675           
676           if (socket_transport->message_bytes_written == total_bytes_to_write)
677             {
678               socket_transport->message_bytes_written = 0;
679               _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
680               _dbus_string_compact (&socket_transport->encoded_outgoing, 2048);
681
682               _dbus_connection_message_sent_unlocked (transport->connection,
683                                                       message);
684             }
685         }
686     }
687
688  out:
689   if (oom)
690     return FALSE;
691   else
692     return TRUE;
693 }
694
695 /* returns false on out-of-memory */
696 static dbus_bool_t
697 do_reading (DBusTransport *transport)
698 {
699   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
700   DBusString *buffer;
701   int bytes_read;
702   int total;
703   dbus_bool_t oom;
704
705   _dbus_verbose ("fd = %d\n",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 ("\n");
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 pre poll\n");
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 post poll\n");
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_invalidate (socket_transport->read_watch);
1284   _dbus_watch_unref (socket_transport->read_watch);
1285  failed_3:
1286   _dbus_watch_invalidate (socket_transport->write_watch);
1287   _dbus_watch_unref (socket_transport->write_watch);
1288  failed_2:
1289   _dbus_string_free (&socket_transport->encoded_incoming);
1290  failed_1:
1291   _dbus_string_free (&socket_transport->encoded_outgoing);
1292  failed_0:
1293   dbus_free (socket_transport);
1294   return NULL;
1295 }
1296
1297 /**
1298  * Creates a new transport for the given hostname and port.
1299  * If host is NULL, it will default to localhost
1300  *
1301  * @param host the host to connect to
1302  * @param port the port to connect to
1303  * @param family the address family to connect to
1304  * @param path to nonce file
1305  * @param error location to store reason for failure.
1306  * @returns a new transport, or #NULL on failure.
1307  */
1308 DBusTransport*
1309 _dbus_transport_new_for_tcp_socket (const char     *host,
1310                                     const char     *port,
1311                                     const char     *family,
1312                                     const char     *noncefile,
1313                                     DBusError      *error)
1314 {
1315   int fd;
1316   DBusTransport *transport;
1317   DBusString address;
1318   
1319   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1320
1321   if (!_dbus_string_init (&address))
1322     {
1323       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1324       return NULL;
1325     }
1326
1327   if (host == NULL)
1328     host = "localhost";
1329
1330   if (!_dbus_string_append (&address, noncefile ? "nonce-tcp:" : "tcp:"))
1331     goto error;
1332
1333   if (!_dbus_string_append (&address, "host=") ||
1334       !_dbus_string_append (&address, host))
1335     goto error;
1336
1337   if (!_dbus_string_append (&address, ",port=") ||
1338       !_dbus_string_append (&address, port))
1339     goto error;
1340
1341   if (family != NULL &&
1342       (!_dbus_string_append (&address, ",family=") ||
1343        !_dbus_string_append (&address, family)))
1344     goto error;
1345
1346   if (noncefile != NULL &&
1347       (!_dbus_string_append (&address, ",noncefile=") ||
1348        !_dbus_string_append (&address, noncefile)))
1349     goto error;
1350
1351   fd = _dbus_connect_tcp_socket_with_nonce (host, port, family, noncefile, error);
1352   if (fd < 0)
1353     {
1354       _DBUS_ASSERT_ERROR_IS_SET (error);
1355       _dbus_string_free (&address);
1356       return NULL;
1357     }
1358
1359   _dbus_verbose ("Successfully connected to tcp socket %s:%s\n",
1360                  host, port);
1361   
1362   transport = _dbus_transport_new_for_socket (fd, NULL, &address);
1363   _dbus_string_free (&address);
1364   if (transport == NULL)
1365     {
1366       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1367       _dbus_close_socket (fd, NULL);
1368       fd = -1;
1369     }
1370
1371   return transport;
1372
1373 error:
1374   _dbus_string_free (&address);
1375   dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1376   return NULL;
1377 }
1378
1379 /**
1380  * Opens a TCP socket transport.
1381  * 
1382  * @param entry the address entry to try opening as a tcp transport.
1383  * @param transport_p return location for the opened transport
1384  * @param error error to be set
1385  * @returns result of the attempt
1386  */
1387 DBusTransportOpenResult
1388 _dbus_transport_open_socket(DBusAddressEntry  *entry,
1389                             DBusTransport    **transport_p,                            
1390                             DBusError         *error)
1391 {
1392   const char *method;
1393   dbus_bool_t isTcp;
1394   dbus_bool_t isNonceTcp;
1395   
1396   method = dbus_address_entry_get_method (entry);
1397   _dbus_assert (method != NULL);
1398
1399   isTcp = strcmp (method, "tcp") == 0;
1400   isNonceTcp = strcmp (method, "nonce-tcp") == 0;
1401
1402   if (isTcp || isNonceTcp)
1403     {
1404       const char *host = dbus_address_entry_get_value (entry, "host");
1405       const char *port = dbus_address_entry_get_value (entry, "port");
1406       const char *family = dbus_address_entry_get_value (entry, "family");
1407       const char *noncefile = dbus_address_entry_get_value (entry, "noncefile");
1408
1409       if ((isNonceTcp == TRUE) != (noncefile != NULL)) {
1410           _dbus_set_bad_address (error, method, "noncefile", NULL);
1411           return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
1412       }
1413
1414       if (port == NULL)
1415         {
1416           _dbus_set_bad_address (error, method, "port", NULL);
1417           return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
1418         }
1419
1420       *transport_p = _dbus_transport_new_for_tcp_socket (host, port, family, noncefile, error);
1421       if (*transport_p == NULL)
1422         {
1423           _DBUS_ASSERT_ERROR_IS_SET (error);
1424           return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
1425         }
1426       else
1427         {
1428           _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1429           return DBUS_TRANSPORT_OPEN_OK;
1430         }
1431     }
1432   else
1433     {
1434       _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1435       return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
1436     }
1437 }
1438
1439 /** @} */
1440