Next 2 org.freedesktop.DBus method, comments, cleanups
[platform/upstream/dbus.git] / dbus / dbus-transport-kdbus.c
1 /*
2  * dbus-transport-kdbus.c
3  *
4  * Transport layer using kdbus
5  *
6  *  Created on: Jun 20, 2013
7  *      Author: r.pajak
8  *
9  *
10  */
11
12 #include "dbus-transport.h"
13 #include "dbus-transport-kdbus.h"
14 #include <dbus/dbus-transport-protected.h>
15 #include "dbus-connection-internal.h"
16 #include "kdbus.h"
17 #include "dbus-watch.h"
18 #include "dbus-errors.h"
19 #include "dbus-bus.h"
20 #include <linux/types.h>
21 #include <fcntl.h>
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <sys/ioctl.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <sys/mman.h>
30 #include <limits.h>
31
32 #define KDBUS_ALIGN8(l) (((l) + 7) & ~7)
33 #define KDBUS_PART_HEADER_SIZE offsetof(struct kdbus_item, data)
34 #define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_PART_HEADER_SIZE)
35
36 #define KDBUS_PART_NEXT(part) \
37         (typeof(part))(((uint8_t *)part) + KDBUS_ALIGN8((part)->size))
38 #define KDBUS_PART_FOREACH(part, head, first)                           \
39         for (part = (head)->first;                                      \
40              (uint8_t *)(part) < (uint8_t *)(head) + (head)->size;      \
41              part = KDBUS_PART_NEXT(part))
42 #define RECEIVE_POOL_SIZE (10 * 1024LU * 1024LU)
43 #define MEMFD_SIZE_THRESHOLD (2 * 1024 * 1024LU) // over this memfd is used
44
45 #define KDBUS_MSG_DECODE_DEBUG 0
46
47 #define ITER_APPEND_STR(string) \
48 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &string))   \
49 { \
50         ret_size = -1;  \
51         goto out;  \
52 }\
53
54 /**
55  * Opaque object representing a socket file descriptor transport.
56  */
57 typedef struct DBusTransportSocket DBusTransportSocket;
58
59 /**
60  * Implementation details of DBusTransportSocket. All members are private.
61  */
62 struct DBusTransportSocket
63 {
64   DBusTransport base;                   /**< Parent instance */
65   int fd;                               /**< File descriptor. */
66   DBusWatch *read_watch;                /**< Watch for readability. */
67   DBusWatch *write_watch;               /**< Watch for writability. */
68
69   int max_bytes_read_per_iteration;     /**< In kdbus only to control overall message size*/
70   int max_bytes_written_per_iteration;  /**< In kdbus only to control overall message size*/
71
72   int message_bytes_written;            /**< Number of bytes of current
73                                          *   outgoing message that have
74                                          *   been written.
75                                          */
76   DBusString encoded_outgoing;          /**< Encoded version of current
77                                          *   outgoing message.
78                                          */
79   DBusString encoded_incoming;          /**< Encoded version of current
80                                          *   incoming data.
81                                          */
82   void* kdbus_mmap_ptr;                 /**< Mapped memory where Kdbus (kernel) writes
83                                          *   messages incoming to us.
84                                          */
85   int memfd;                            /**< File descriptor to special 
86                                          *   memory pool for bulk data
87                                          *   transfer. Retrieved from 
88                                          *   Kdbus kernel module. 
89                                          */
90   __u64 bloom_size;                                             /**<  bloom filter field size */
91 };
92
93 static dbus_bool_t
94 socket_get_socket_fd (DBusTransport *transport,
95                       int           *fd_p)
96 {
97   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
98
99   *fd_p = socket_transport->fd;
100
101   return TRUE;
102 }
103
104 /*
105  * Adds locally generated message to received messages queue
106  *
107  */
108 static dbus_bool_t add_message_to_received(DBusMessage *message, DBusConnection* connection)
109 {
110         DBusList *message_link;
111
112         message_link = _dbus_list_alloc_link (message);
113         if (message_link == NULL)
114         {
115                 dbus_message_unref (message);
116                 return FALSE;
117         }
118
119         _dbus_connection_queue_synthesized_message_link(connection, message_link);
120
121         return TRUE;
122 }
123
124 /**
125  * Retrieves file descriptor to memory pool from kdbus module.
126  * It is then used for bulk data sending.
127  * Triggered when message payload is over MEMFD_SIZE_THRESHOLD
128  * 
129  */
130 static int kdbus_init_memfd(DBusTransportSocket* socket_transport)
131 {
132         int memfd;
133         
134         if(socket_transport->memfd == -1) 
135         {
136                 if (ioctl(socket_transport->fd, KDBUS_CMD_MEMFD_NEW, &memfd) < 0) {
137                         _dbus_verbose("KDBUS_CMD_MEMFD_NEW failed: \n");
138                         return -1;
139                 }
140
141                 socket_transport->memfd = memfd;
142                 _dbus_verbose("kdbus_init_memfd: %d!!\n", socket_transport->memfd);
143         }
144         return 0;
145 }
146
147 /**
148  * Initiates Kdbus message structure. 
149  * Calculates it's size, allocates memory and fills some fields.
150  * @param name Well-known name or NULL
151  * @param dst_id Numeric id of recipient
152  * @param body_size size of message body if present
153  * @param use_memfd flag to build memfd message
154  * @param fds_count number of file descriptors used
155  * @param transport transport
156  * @return initialized kdbus message
157  */
158 static struct kdbus_msg* kdbus_init_msg(const char* name, __u64 dst_id, uint64_t body_size, dbus_bool_t use_memfd, int fds_count, DBusTransportSocket *transport)
159 {
160     struct kdbus_msg* msg;
161     uint64_t msg_size;
162
163     msg_size = sizeof(struct kdbus_msg);
164
165     if(use_memfd == TRUE)  // bulk data - memfd - encoded and plain
166         msg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd));
167     else {
168         msg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
169         if(body_size)
170                 msg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
171     }
172
173     if(fds_count)
174         msg_size += KDBUS_ITEM_SIZE(sizeof(int)*fds_count);
175
176     if (name)
177         msg_size += KDBUS_ITEM_SIZE(strlen(name) + 1);
178     else if (dst_id == KDBUS_DST_ID_BROADCAST)
179         msg_size += KDBUS_PART_HEADER_SIZE + transport->bloom_size;
180
181     msg = malloc(msg_size);
182     if (!msg)
183     {
184         _dbus_verbose("Error allocating memory for: %s,%s\n", _dbus_strerror (errno), _dbus_error_from_errno (errno));
185                 return NULL;
186     }
187
188     memset(msg, 0, msg_size);
189     msg->size = msg_size;
190     msg->payload_type = KDBUS_PAYLOAD_DBUS1;
191     msg->dst_id = name ? 0 : dst_id;
192     msg->src_id = strtoull(dbus_bus_get_unique_name(transport->base.connection), NULL , 10);
193
194     return msg;
195 }
196
197 /**
198  * Builds and sends kdbus message using Dbus message.
199  * Decide whether used payload vector or memfd memory pool.
200  * Handles broadcasts and unicast messages, and passing of Unix fds.
201  * Does error handling.
202  * TODO refactor to be more compact
203  *
204  * @param transport transport
205  * @param message DBus message to be sent
206  * @param encoded flag if the message is encoded
207  * @return size of data sent
208  */
209 static int kdbus_write_msg(DBusTransportSocket *transport, DBusMessage *message, dbus_bool_t encoded)
210 {
211     struct kdbus_msg *msg;
212     struct kdbus_item *item;
213     const char *name;
214     uint64_t dst_id = KDBUS_DST_ID_BROADCAST;
215     const DBusString *header;
216     const DBusString *body;
217     uint64_t ret_size = 0;
218     uint64_t body_size = 0;
219     uint64_t header_size = 0;
220     dbus_bool_t use_memfd;
221     const int *unix_fds;
222     unsigned fds_count;
223
224     // determine name and destination id
225     if((name = dbus_message_get_destination(message)))
226     {
227         dst_id = KDBUS_DST_ID_WELL_KNOWN_NAME;
228                 if((name[0] == ':') && (name[1] == '1') && (name[2] == '.'))  /* if name starts with ":1." it is a unique name and should be send as number */
229         {
230                 dst_id = strtoull(&name[3], NULL, 10);
231                 name = NULL;
232         }    
233     }
234     
235     // get size of data
236     if(encoded)
237         ret_size = _dbus_string_get_length (&transport->encoded_outgoing);
238     else
239     {
240         _dbus_message_get_network_data (message, &header, &body);
241         header_size = _dbus_string_get_length(header);
242         body_size = _dbus_string_get_length(body);
243         ret_size = header_size + body_size;
244     }
245
246     // check if message size is big enough to use memfd kdbus transport
247     use_memfd = ret_size > MEMFD_SIZE_THRESHOLD ? TRUE : FALSE;
248     if(use_memfd) kdbus_init_memfd(transport);
249     
250     _dbus_message_get_unix_fds(message, &unix_fds, &fds_count);
251
252     // init basic message fields
253     msg = kdbus_init_msg(name, dst_id, body_size, use_memfd, fds_count, transport);
254     msg->cookie = dbus_message_get_serial(message);
255     
256     // build message contents
257     item = msg->items;
258
259     // case 1 - bulk data transfer - memfd - encoded and plain
260     if(use_memfd)          
261     {
262         char *buf;
263
264         if(ioctl(transport->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 0) < 0)
265             {
266                         _dbus_verbose("memfd sealing failed: \n");
267                         goto out;
268             }
269
270             buf = mmap(NULL, ret_size, PROT_WRITE, MAP_SHARED, transport->memfd, 0);
271             if (buf == MAP_FAILED) 
272             {
273                         _dbus_verbose("mmap() fd=%i failed:%m", transport->memfd);
274                         goto out;
275             }
276
277                 if(encoded)
278                         memcpy(buf, &transport->encoded_outgoing, ret_size);
279                 else
280                 {
281                         memcpy(buf, _dbus_string_get_const_data(header), header_size);
282                         if(body_size) {
283                                 buf+=header_size;
284                                 memcpy(buf, _dbus_string_get_const_data(body),  body_size);
285                                 buf-=header_size;
286                         }
287                 }
288
289                 munmap(buf, ret_size);
290
291                 // seal data - kdbus module needs it
292                 if(ioctl(transport->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) < 0) {
293                         _dbus_verbose("memfd sealing failed: %d (%m)\n", errno);
294                         ret_size = -1;
295                         goto out;
296                 }
297
298             item->type = KDBUS_MSG_PAYLOAD_MEMFD;
299                 item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_memfd);
300                 item->memfd.size = ret_size;
301                 item->memfd.fd = transport->memfd;
302     // case 2 - small encoded - don't use memfd
303     } else if(encoded) { 
304         _dbus_verbose("sending encoded data\n");
305
306         item->type = KDBUS_MSG_PAYLOAD_VEC;
307         item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_vec);
308         item->vec.address = (unsigned long) &transport->encoded_outgoing;
309         item->vec.size = _dbus_string_get_length (&transport->encoded_outgoing);
310
311     // case 3 - small not encoded - don't use memfd
312     } else { 
313         _dbus_verbose("sending normal vector data\n");
314
315         item->type = KDBUS_MSG_PAYLOAD_VEC;
316         item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_vec);
317         item->vec.address = (unsigned long) _dbus_string_get_const_data(header);
318         item->vec.size = header_size;
319
320         if(body_size)
321         {
322             _dbus_verbose("body attaching\n");
323                 item = KDBUS_PART_NEXT(item);
324                 item->type = KDBUS_MSG_PAYLOAD_VEC;
325                 item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_vec);
326                 item->vec.address = (unsigned long) _dbus_string_get_const_data(body);
327                 item->vec.size = body_size;
328         }
329     }
330
331     if(fds_count)
332     {
333         item = KDBUS_PART_NEXT(item);
334         item->type = KDBUS_MSG_FDS;
335         item->size = KDBUS_PART_HEADER_SIZE + (sizeof(int) * fds_count);
336         memcpy(item->fds, unix_fds, sizeof(int) * fds_count);
337     }
338
339         if (name)
340         {
341                 item = KDBUS_PART_NEXT(item);
342                 item->type = KDBUS_MSG_DST_NAME;
343                 item->size = KDBUS_PART_HEADER_SIZE + strlen(name) + 1;
344                 strcpy(item->str, name);
345         }
346         else if (dst_id == KDBUS_DST_ID_BROADCAST)
347         {
348                 item = KDBUS_PART_NEXT(item);
349                 item->type = KDBUS_MSG_BLOOM;
350                 item->size = KDBUS_PART_HEADER_SIZE + transport->bloom_size;
351                 strncpy(item->data, dbus_message_get_interface(message), transport->bloom_size);
352         }
353
354         again:
355         if (ioctl(transport->fd, KDBUS_CMD_MSG_SEND, msg))
356         {
357                 if(errno == EINTR)
358                         goto again;
359                 if((errno == ESRCH) || (errno == ENXIO))  //when recipient is not available on the bus
360                 {
361                         DBusMessage *errMessage = NULL;
362                         dbus_uint32_t replySerial;
363
364                         errMessage = generate_local_error_message(msg->cookie, DBUS_ERROR_SERVICE_UNKNOWN, (char*)dbus_message_get_destination(message));
365                         if(errMessage == NULL)
366                         {
367                                 ret_size = -1;
368                                 goto out;
369                         }
370                         replySerial = dbus_message_get_reply_serial(message);
371                         if(replySerial)
372                                 dbus_message_set_reply_serial(errMessage, replySerial);
373                         if (!add_message_to_received(errMessage, transport->base.connection))
374                                 ret_size = -1;
375                         goto out;
376                 }
377                 _dbus_verbose("kdbus error sending message: err %d (%m)\n", errno);
378                 ret_size = -1;
379         }
380 out:
381     free(msg);
382
383     return ret_size;
384 }
385
386 struct nameInfo
387 {
388         __u64 uniqueId;
389         __u64 userId;
390         __u64 processId;
391 };
392
393 /**
394  * Performs kdbus query of id of the given name
395  *
396  * @param name name to query for
397  * @param fd bus file
398  * @param ownerID place to store id of the name
399  * @return 0 on success, -errno if failed
400  */
401 static int kdbus_NameQuery(char* name, int fd, struct nameInfo* pInfo)
402 {
403         struct kdbus_cmd_name_info *msg;
404         struct kdbus_item *item;
405         uint64_t size;
406         int ret;
407         uint64_t item_size;
408
409     item_size = KDBUS_PART_HEADER_SIZE + strlen(name) + 1;
410         item_size = (item_size < 56) ? 56 : item_size;  //56 bytes are needed by kernel to place a lot of unnecessary info about name, otherwise error
411     size = sizeof(struct kdbus_cmd_name_info) + item_size;
412
413         msg = malloc(size);
414         if (!msg)
415         {
416                 _dbus_verbose("Error allocating memory for: %s,%s\n", _dbus_strerror (errno), _dbus_error_from_errno (errno));
417                 return -1;
418         }
419
420         memset(msg, 0, size);
421         msg->size = size;
422         if((name[0] == ':') && (name[1] == '1') && (name[2] == '.'))  /* if name starts with ":1." it is a unique name and should be send as number */
423                 msg->id = strtoull(&name[3], NULL, 10);
424         else
425                 msg->id = 0;
426
427         item = msg->items;
428         item->type = KDBUS_NAME_INFO_ITEM_NAME;
429         item->size = item_size;
430         strcpy(item->str, name);
431
432         again:
433         if ((ret = ioctl(fd, KDBUS_CMD_NAME_QUERY, msg)))
434         {
435                 if(errno == EINTR)
436                         goto again;
437                 pInfo->uniqueId = 0;
438                 ret = -errno;
439         }
440         else
441         {
442                 pInfo->uniqueId = msg->id;
443                 pInfo->userId = msg->creds.uid;
444                 pInfo->processId = msg->creds.pid;
445         }
446
447         free(msg);
448         return ret;
449 }
450
451 /**
452  * Handles messages sent to bus daemon - "org.freedesktop.DBus" and translates them to appropriate
453  * kdbus ioctl commands. Than translate kdbus reply into dbus message and put it into recived messages queue.
454  *
455  * !!! Not all methods are handled !!! Doubt if it is even possible.
456  * If method is not handled, returns error reply org.freedesktop.DBus.Error.UnknownMethod
457  *
458  * Handled methods:
459  * - GetNameOwner
460  * - NameHasOwner
461  * - ListNames
462  *
463  * Not handled methods:
464  * - ListActivatableNames
465  * - StartServiceByName
466  * - UpdateActivationEnvironment
467  * - GetConnectionUnixUser
468  * - GetId
469  */
470 static dbus_bool_t emulateOrgFreedesktopDBus(DBusTransport *transport, DBusMessage *message)
471 {
472         int ret;
473
474         if(!strcmp(dbus_message_get_member(message), "GetNameOwner"))  //returns id of the well known name
475         {
476                 char* name = NULL;
477                 struct nameInfo info;
478
479                 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
480                 _dbus_verbose ("Name to discover: %s   !!!!             !!!!\n", name);
481                 ret = kdbus_NameQuery(name, ((DBusTransportSocket*)transport)->fd, &info);
482                 if(ret == 0) //unique id of the name
483                 {
484                         DBusMessage *reply;
485                         DBusMessageIter args;
486                         char unique_name[(unsigned int)(snprintf(name, 0, "%llu", ULLONG_MAX) + sizeof(":1."))];
487                         const char* pString = unique_name;
488
489                         sprintf(unique_name, ":1.%llu", (unsigned long long int)info.uniqueId);
490                         _dbus_verbose("Unique name discovered:%s!!!                       !!!!\n", unique_name);
491                         reply = dbus_message_new_method_return(message);
492                         if(reply == NULL)
493                                 return FALSE;
494                         dbus_message_set_sender(reply, DBUS_SERVICE_DBUS);
495                     dbus_message_iter_init_append(reply, &args);
496                     if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pString))
497                         return FALSE;
498                     if(add_message_to_received(reply, transport->connection))
499                         return TRUE;
500                 }
501                 else if(ret == -ENOENT)  //name has no owner
502                 {
503                         DBusMessage *errMessage;
504                         dbus_uint32_t replySerial;
505
506                         errMessage = generate_local_error_message(1, DBUS_ERROR_NAME_HAS_NO_OWNER, name);
507                         if(errMessage == NULL)
508                                 return FALSE;
509                         replySerial = dbus_message_get_reply_serial(message);
510                         if(replySerial)
511                                 dbus_message_set_reply_serial(errMessage, replySerial);
512                         if (add_message_to_received(errMessage, transport->connection))
513                                 return TRUE;
514                 }
515                 else
516                         _dbus_verbose("kdbus error sending name query: err %d (%m)\n", errno);
517         }
518         else if(!strcmp(dbus_message_get_member(message), "NameHasOwner"))   //returns if name is currently registered on the bus
519         {
520                 char* name = NULL;
521                 DBusMessage *reply;
522                 DBusMessageIter args;
523                 dbus_bool_t result;
524                 struct nameInfo info;
525
526                 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
527                 _dbus_verbose ("Name to discover: %s   !!!!             !!!!\n", name);
528                 ret = kdbus_NameQuery(name, ((DBusTransportSocket*)transport)->fd, &info);
529                 result = (ret == 0) ? TRUE : FALSE;
530                 _dbus_verbose("Discovery: %d !!!                       !!!!\n", (int)result);
531
532                 reply = dbus_message_new_method_return(message);
533                 if(reply == NULL)
534                         return FALSE;
535                 dbus_message_set_sender(reply, DBUS_SERVICE_DBUS);
536                 dbus_message_iter_init_append(reply, &args);
537                 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_BOOLEAN, &result))
538                         return FALSE;
539                 if(add_message_to_received(reply, transport->connection))
540                         return TRUE;
541         }
542         else if(!strcmp(dbus_message_get_member(message), "GetConnectionUnixUser"))
543         {
544                 char* name = NULL;
545                 struct nameInfo info;
546
547                 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
548                 _dbus_verbose ("Name to discover: %s   !!!!             !!!!\n", name);
549                 ret = kdbus_NameQuery(name, ((DBusTransportSocket*)transport)->fd, &info);
550                 if(ret == 0) //name found
551                 {
552                         DBusMessage *reply;
553                         DBusMessageIter args;
554
555                         _dbus_verbose("User id:%llu!!!                       !!!!\n", (unsigned long long) info.userId);
556                         reply = dbus_message_new_method_return(message);
557                         if(reply == NULL)
558                                 return FALSE;
559                         dbus_message_set_sender(reply, DBUS_SERVICE_DBUS);
560                     dbus_message_iter_init_append(reply, &args);
561                     if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT32, &info.userId))
562                         return FALSE;
563                     if(add_message_to_received(reply, transport->connection))
564                         return TRUE;
565                 }
566                 else if(ret == -ENOENT)  //name has no owner
567                 {
568                         DBusMessage *errMessage;
569                         dbus_uint32_t replySerial;
570                         char* error_msg = NULL;
571
572                         error_msg = alloca(sizeof("Could not determine UID for ''") + strlen(name));
573                         if(error_msg == NULL)
574                                 return FALSE;
575                         sprintf(error_msg, "Could not determine UID for '%s'", name);
576                         errMessage = generate_local_error_message(1, DBUS_ERROR_FAILED, error_msg);
577                         if(errMessage == NULL)
578                                 return FALSE;
579                         replySerial = dbus_message_get_reply_serial(message);
580                         if(replySerial)
581                                 dbus_message_set_reply_serial(errMessage, replySerial);
582                         if (add_message_to_received(errMessage, transport->connection))
583                                 return TRUE;
584                 }
585                 else
586                         _dbus_verbose("kdbus error querying ConnectionUnixUserID: err %d (%m)\n", errno);
587         }
588         else if(!strcmp(dbus_message_get_member(message), "GetConnectionUnixProcessID"))
589         {
590                 char* name = NULL;
591                 struct nameInfo info;
592
593                 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
594                 _dbus_verbose ("Name to discover: %s   !!!!             !!!!\n", name);
595                 ret = kdbus_NameQuery(name, ((DBusTransportSocket*)transport)->fd, &info);
596                 if(ret == 0) //name found
597                 {
598                         DBusMessage *reply;
599                         DBusMessageIter args;
600
601                         _dbus_verbose("Process id:%llu!!!                       !!!!\n", (unsigned long long) info.processId);
602                         reply = dbus_message_new_method_return(message);
603                         if(reply == NULL)
604                                 return FALSE;
605                         dbus_message_set_sender(reply, DBUS_SERVICE_DBUS);
606                     dbus_message_iter_init_append(reply, &args);
607                     if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT32, &info.processId))
608                         return FALSE;
609                     if(add_message_to_received(reply, transport->connection))
610                         return TRUE;
611                 }
612                 else if(ret == -ENOENT)  //name has no owner
613                 {
614                         DBusMessage *errMessage;
615                         dbus_uint32_t replySerial;
616
617                         errMessage = generate_local_error_message(1, DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN, name);
618                         if(errMessage == NULL)
619                                 return FALSE;
620                         replySerial = dbus_message_get_reply_serial(message);
621                         if(replySerial)
622                                 dbus_message_set_reply_serial(errMessage, replySerial);
623                         if (add_message_to_received(errMessage, transport->connection))
624                                 return TRUE;
625                 }
626                 else
627                         _dbus_verbose("kdbus error querying ConnectionUnixUserID: err %d (%m)\n", errno);
628         }
629         else if(!strcmp(dbus_message_get_member(message), "ListNames"))  //return all well known names on he bus
630         {
631                 struct kdbus_cmd_names* pCmd;
632                 uint64_t cmd_size;
633
634                 cmd_size = sizeof(struct kdbus_cmd_names) + KDBUS_ITEM_SIZE(1);
635                 pCmd = malloc(cmd_size);
636                 if(pCmd == NULL)
637                         goto out;
638                 pCmd->size = cmd_size;
639
640   again:
641                 cmd_size = 0;
642                 if(ioctl(((DBusTransportSocket*)transport)->fd, KDBUS_CMD_NAME_LIST, pCmd))
643                 {
644                         if(errno == EINTR)
645                                 goto again;
646                         if(errno == ENOBUFS)                    //buffer to small to put all names into it
647                                 cmd_size = pCmd->size;          //here kernel tells how much memory it needs
648                         else
649                         {
650                                 _dbus_verbose("kdbus error asking for name list: err %d (%m)\n",errno);
651                                 goto out;
652                         }
653                 }
654                 if(cmd_size)  //kernel needs more memory
655                 {
656                         pCmd = realloc(pCmd, cmd_size);  //prepare memory
657                         if(pCmd == NULL)
658                                 return FALSE;
659                         goto again;                                             //and try again
660                 }
661                 else
662                 {
663                         DBusMessage *reply;
664                         DBusMessageIter args;
665                         struct kdbus_cmd_name* pCmd_name;
666                         char* pName;
667
668                         reply = dbus_message_new_method_return(message);
669                         if(reply == NULL)
670                                 goto out;
671                         dbus_message_set_sender(reply, DBUS_SERVICE_DBUS);
672                         dbus_message_iter_init_append(reply, &args);
673
674                         for (pCmd_name = pCmd->names; (uint8_t *)(pCmd_name) < (uint8_t *)(pCmd) + pCmd->size; pCmd_name = KDBUS_PART_NEXT(pCmd_name))
675                         {
676                                 pName = pCmd_name->name;
677                                 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pName))
678                                 goto out;
679                         }
680
681                         if(add_message_to_received(reply, transport->connection))
682                         {
683                                 free(pCmd);
684                                 return TRUE;
685                         }
686                 }
687
688 out:
689                 if(pCmd)
690                         free(pCmd);
691         }
692         else  //temporarily we send that info but methods below should be implemented if possible
693         {
694                 DBusMessage *reply;
695                 dbus_uint32_t replySerial;
696
697                 reply = generate_local_error_message(1, DBUS_ERROR_UNKNOWN_METHOD, NULL);
698                 if(reply == NULL)
699                         return FALSE;
700                 replySerial = dbus_message_get_reply_serial(message);
701                 if(replySerial)
702                         dbus_message_set_reply_serial(reply, replySerial);
703                 if(add_message_to_received(reply, transport->connection))
704                         return TRUE;
705         }
706 /*      else if(!strcmp(dbus_message_get_member(message), "ListActivatableNames"))  //todo
707         {
708
709         }
710         else if(!strcmp(dbus_message_get_member(message), "StartServiceByName"))
711         {
712
713         }
714         else if(!strcmp(dbus_message_get_member(message), "UpdateActivationEnvironment"))
715         {
716
717         }
718         else if(!strcmp(dbus_message_get_member(message), "GetId"))
719         {
720
721         }*/
722
723         return FALSE;
724 }
725
726 #if KDBUS_MSG_DECODE_DEBUG == 1
727 static char *msg_id(uint64_t id, char *buf)
728 {
729         if (id == 0)
730                 return "KERNEL";
731         if (id == ~0ULL)
732                 return "BROADCAST";
733         sprintf(buf, "%llu", (unsigned long long)id);
734         return buf;
735 }
736 #endif
737 struct kdbus_enum_table {
738         long long id;
739         const char *name;
740 };
741 #define _STRINGIFY(x) #x
742 #define STRINGIFY(x) _STRINGIFY(x)
743 #define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
744 #define TABLE(what) static struct kdbus_enum_table kdbus_table_##what[]
745 #define ENUM(_id) { .id=_id, .name=STRINGIFY(_id) }
746 #define LOOKUP(what)                                                            \
747         const char *enum_##what(long long id) {                                 \
748         size_t i; \
749                 for (i = 0; i < ELEMENTSOF(kdbus_table_##what); i++)    \
750                         if (id == kdbus_table_##what[i].id)                     \
751                                 return kdbus_table_##what[i].name;              \
752                 return "UNKNOWN";                                               \
753         }
754 const char *enum_MSG(long long id);
755 TABLE(MSG) = {
756         ENUM(_KDBUS_MSG_NULL),
757         ENUM(KDBUS_MSG_PAYLOAD_VEC),
758         ENUM(KDBUS_MSG_PAYLOAD_OFF),
759         ENUM(KDBUS_MSG_PAYLOAD_MEMFD),
760         ENUM(KDBUS_MSG_FDS),
761         ENUM(KDBUS_MSG_BLOOM),
762         ENUM(KDBUS_MSG_DST_NAME),
763         ENUM(KDBUS_MSG_SRC_CREDS),
764         ENUM(KDBUS_MSG_SRC_PID_COMM),
765         ENUM(KDBUS_MSG_SRC_TID_COMM),
766         ENUM(KDBUS_MSG_SRC_EXE),
767         ENUM(KDBUS_MSG_SRC_CMDLINE),
768         ENUM(KDBUS_MSG_SRC_CGROUP),
769         ENUM(KDBUS_MSG_SRC_CAPS),
770         ENUM(KDBUS_MSG_SRC_SECLABEL),
771         ENUM(KDBUS_MSG_SRC_AUDIT),
772         ENUM(KDBUS_MSG_SRC_NAMES),
773         ENUM(KDBUS_MSG_TIMESTAMP),
774         ENUM(KDBUS_MSG_NAME_ADD),
775         ENUM(KDBUS_MSG_NAME_REMOVE),
776         ENUM(KDBUS_MSG_NAME_CHANGE),
777         ENUM(KDBUS_MSG_ID_ADD),
778         ENUM(KDBUS_MSG_ID_REMOVE),
779         ENUM(KDBUS_MSG_REPLY_TIMEOUT),
780         ENUM(KDBUS_MSG_REPLY_DEAD),
781 };
782 LOOKUP(MSG);
783 const char *enum_PAYLOAD(long long id);
784 TABLE(PAYLOAD) = {
785         ENUM(KDBUS_PAYLOAD_KERNEL),
786         ENUM(KDBUS_PAYLOAD_DBUS1),
787         ENUM(KDBUS_PAYLOAD_GVARIANT),
788 };
789 LOOKUP(PAYLOAD);
790
791 /**
792  * Puts locally generated message into received data buffer.
793  * Use only during receiving phase!
794  *
795  * @param message message to load
796  * @param data place to load message
797  * @return size of message
798  */
799 static int put_message_into_data(DBusMessage *message, char* data)
800 {
801         int ret_size;
802     const DBusString *header;
803     const DBusString *body;
804     int size;
805
806     dbus_message_lock (message);
807     _dbus_message_get_network_data (message, &header, &body);
808     ret_size = _dbus_string_get_length(header);
809         memcpy(data, _dbus_string_get_const_data(header), ret_size);
810         data += ret_size;
811         size = _dbus_string_get_length(body);
812         memcpy(data, _dbus_string_get_const_data(body), size);
813         ret_size += size;
814
815         return ret_size;
816 }
817 /**
818  * Decodes kdbus message in order to extract dbus message and put it into data and fds.
819  * Also captures and decodes kdbus error messages and kdbus kernel broadcasts and converts
820  * all of them into dbus messages.
821  *
822  * @param msg kdbus message
823  * @param data place to copy dbus message to
824  * @param socket_transport transport
825  * @param fds place to store file descriptors received
826  * @param n_fds place to store quantity of file descriptor
827  * @return number of dbus message's bytes received or -1 on error
828  */
829 static int kdbus_decode_msg(const struct kdbus_msg* msg, char *data, DBusTransportSocket* socket_transport, int* fds, int* n_fds)
830 {
831         const struct kdbus_item *item;
832         int ret_size = 0;
833         DBusMessage *message = NULL;
834         DBusMessageIter args;
835         const char* emptyString = "";
836     const char* pString = NULL;
837         char dbus_name[(unsigned int)(snprintf((char*)pString, 0, "%llu", ULLONG_MAX) + sizeof(":1."))];
838         const char* pDBusName = dbus_name;
839 #if KDBUS_MSG_DECODE_DEBUG == 1
840         char buf[32];
841 #endif
842
843 #if KDBUS_MSG_DECODE_DEBUG == 1
844         _dbus_verbose("MESSAGE: %s (%llu bytes) flags=0x%llx, %s â†’ %s, cookie=%llu, timeout=%llu\n",
845                 enum_PAYLOAD(msg->payload_type), (unsigned long long) msg->size,
846                 (unsigned long long) msg->flags,
847                 msg_id(msg->src_id, buf), msg_id(msg->dst_id, buf),
848                 (unsigned long long) msg->cookie, (unsigned long long) msg->timeout_ns);
849 #endif
850
851         *n_fds = 0;
852
853         KDBUS_PART_FOREACH(item, msg, items)
854         {
855                 if (item->size <= KDBUS_PART_HEADER_SIZE)
856                 {
857                         _dbus_verbose("  +%s (%llu bytes) invalid data record\n", enum_MSG(item->type), item->size);
858                         break;  //??? continue (because dbus will find error) or break
859                 }
860
861                 switch (item->type)
862                 {
863                         case KDBUS_MSG_PAYLOAD_OFF:
864                                 memcpy(data, (char *)socket_transport->kdbus_mmap_ptr + item->vec.offset, item->vec.size);
865                                 data += item->vec.size;
866                                 ret_size += item->vec.size;                     
867
868                                 _dbus_verbose("  +%s (%llu bytes) off=%llu size=%llu\n",
869                                         enum_MSG(item->type), item->size,
870                                         (unsigned long long)item->vec.offset,
871                                         (unsigned long long)item->vec.size);
872                         break;
873
874                         case KDBUS_MSG_PAYLOAD_MEMFD:
875                         {
876                                 char *buf;
877                                 uint64_t size;
878
879                 size = item->memfd.size;
880                                 _dbus_verbose("memfd.size : %llu\n", (unsigned long long)size);
881                                 
882                                 buf = mmap(NULL, size, PROT_READ , MAP_SHARED, item->memfd.fd, 0);
883                                 if (buf == MAP_FAILED) 
884                                 {
885                                         _dbus_verbose("mmap() fd=%i failed:%m", item->memfd.fd);
886                                         return -1;
887                                 }
888
889                                 memcpy(data, buf, size); 
890                                 data += size;
891                                 ret_size += size;
892
893                                 munmap(buf, size);
894
895                 _dbus_verbose("  +%s (%llu bytes) off=%llu size=%llu\n",
896                                            enum_MSG(item->type), item->size,
897                                            (unsigned long long)item->vec.offset,
898                                            (unsigned long long)item->vec.size);
899                         break;
900                         }
901
902                         case KDBUS_MSG_FDS:
903                         {
904                                 int i;
905
906                                 *n_fds = (item->size - KDBUS_PART_HEADER_SIZE) / sizeof(int);
907                                 memcpy(fds, item->fds, *n_fds * sizeof(int));
908                     for (i = 0; i < *n_fds; i++)
909                       _dbus_fd_set_close_on_exec(fds[i]);
910                         break;
911                         }
912
913 #if KDBUS_MSG_DECODE_DEBUG == 1
914                         case KDBUS_MSG_SRC_CREDS:
915                                 _dbus_verbose("  +%s (%llu bytes) uid=%lld, gid=%lld, pid=%lld, tid=%lld, starttime=%lld\n",
916                                         enum_MSG(item->type), item->size,
917                                         item->creds.uid, item->creds.gid,
918                                         item->creds.pid, item->creds.tid,
919                                         item->creds.starttime);
920                         break;
921
922                         case KDBUS_MSG_SRC_PID_COMM:
923                         case KDBUS_MSG_SRC_TID_COMM:
924                         case KDBUS_MSG_SRC_EXE:
925                         case KDBUS_MSG_SRC_CGROUP:
926                         case KDBUS_MSG_SRC_SECLABEL:
927                         case KDBUS_MSG_DST_NAME:
928                                 _dbus_verbose("  +%s (%llu bytes) '%s' (%zu)\n",
929                                            enum_MSG(item->type), item->size, item->str, strlen(item->str));
930                                 break;
931
932                         case KDBUS_MSG_SRC_CMDLINE:
933                         case KDBUS_MSG_SRC_NAMES: {
934                                 __u64 size = item->size - KDBUS_PART_HEADER_SIZE;
935                                 const char *str = item->str;
936                                 int count = 0;
937
938                                 _dbus_verbose("  +%s (%llu bytes) ", enum_MSG(item->type), item->size);
939                                 while (size) {
940                                         _dbus_verbose("'%s' ", str);
941                                         size -= strlen(str) + 1;
942                                         str += strlen(str) + 1;
943                                         count++;
944                                 }
945
946                                 _dbus_verbose("(%d string%s)\n", count, (count == 1) ? "" : "s");
947                                 break;
948                         }
949
950                         case KDBUS_MSG_SRC_AUDIT:
951                                 _dbus_verbose("  +%s (%llu bytes) loginuid=%llu sessionid=%llu\n",
952                                            enum_MSG(item->type), item->size,
953                                            (unsigned long long)item->data64[0],
954                                            (unsigned long long)item->data64[1]);
955                                 break;
956
957                         case KDBUS_MSG_SRC_CAPS: {
958                                 int n;
959                                 const uint32_t *cap;
960                                 int i;
961
962                                 _dbus_verbose("  +%s (%llu bytes) len=%llu bytes)\n",
963                                            enum_MSG(item->type), item->size,
964                                            (unsigned long long)item->size - KDBUS_PART_HEADER_SIZE);
965
966                                 cap = item->data32;
967                                 n = (item->size - KDBUS_PART_HEADER_SIZE) / 4 / sizeof(uint32_t);
968
969                                 _dbus_verbose("    CapInh=");
970                                 for (i = 0; i < n; i++)
971                                         _dbus_verbose("%08x", cap[(0 * n) + (n - i - 1)]);
972
973                                 _dbus_verbose(" CapPrm=");
974                                 for (i = 0; i < n; i++)
975                                         _dbus_verbose("%08x", cap[(1 * n) + (n - i - 1)]);
976
977                                 _dbus_verbose(" CapEff=");
978                                 for (i = 0; i < n; i++)
979                                         _dbus_verbose("%08x", cap[(2 * n) + (n - i - 1)]);
980
981                                 _dbus_verbose(" CapInh=");
982                                 for (i = 0; i < n; i++)
983                                         _dbus_verbose("%08x", cap[(3 * n) + (n - i - 1)]);
984                                 _dbus_verbose("\n");
985                                 break;
986                         }
987
988                         case KDBUS_MSG_TIMESTAMP:
989                                 _dbus_verbose("  +%s (%llu bytes) realtime=%lluns monotonic=%lluns\n",
990                                            enum_MSG(item->type), item->size,
991                                            (unsigned long long)item->timestamp.realtime_ns,
992                                            (unsigned long long)item->timestamp.monotonic_ns);
993                                 break;
994 #endif
995
996                         case KDBUS_MSG_REPLY_TIMEOUT:
997                         case KDBUS_MSG_REPLY_DEAD:
998                                 _dbus_verbose("  +%s (%llu bytes) cookie=%llu\n",
999                                            enum_MSG(item->type), item->size, msg->cookie_reply);
1000
1001                                 message = generate_local_error_message(msg->cookie_reply, DBUS_ERROR_NO_REPLY, NULL);
1002                                 if(message == NULL)
1003                                 {
1004                                         ret_size = -1;
1005                                         goto out;
1006                                 }
1007
1008                                 ret_size = put_message_into_data(message, data);
1009                         break;
1010
1011                         case KDBUS_MSG_NAME_ADD:
1012                                 _dbus_verbose("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
1013                                         enum_MSG(item->type), (unsigned long long) item->size,
1014                                         item->name_change.name, item->name_change.old_id,
1015                                         item->name_change.new_id, item->name_change.flags);
1016
1017                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
1018                                 if(message == NULL)
1019                                 {
1020                                         ret_size = -1;
1021                                         goto out;
1022                                 }
1023
1024                                 sprintf(dbus_name,":1.%llu",item->name_change.new_id);
1025                                 pString = item->name_change.name;
1026                                 _dbus_verbose ("Name added: %s\n", pString);
1027                             dbus_message_iter_init_append(message, &args);
1028                             ITER_APPEND_STR(pString)
1029                             ITER_APPEND_STR(emptyString)
1030                             ITER_APPEND_STR(pDBusName)
1031                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1032                                 dbus_message_set_serial(message, 1);
1033
1034                                 ret_size = put_message_into_data(message, data);
1035                         break;
1036
1037                         case KDBUS_MSG_NAME_REMOVE:
1038                                 _dbus_verbose("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
1039                                         enum_MSG(item->type), (unsigned long long) item->size,
1040                                         item->name_change.name, item->name_change.old_id,
1041                                         item->name_change.new_id, item->name_change.flags);
1042
1043                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged"); // name of the signal
1044                                 if(message == NULL)
1045                                 {
1046                                         ret_size = -1;
1047                                         goto out;
1048                                 }
1049
1050                                 sprintf(dbus_name,":1.%llu",item->name_change.old_id);
1051                                 pString = item->name_change.name;
1052                                 _dbus_verbose ("Name removed: %s\n", pString);
1053                             dbus_message_iter_init_append(message, &args);
1054                             ITER_APPEND_STR(pString)
1055                             ITER_APPEND_STR(pDBusName)
1056                             ITER_APPEND_STR(emptyString)
1057                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1058                                 dbus_message_set_serial(message, 1);
1059
1060                                 ret_size = put_message_into_data(message, data);
1061                         break;
1062
1063                         case KDBUS_MSG_NAME_CHANGE:
1064                                 _dbus_verbose("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
1065                                         enum_MSG(item->type), (unsigned long long) item->size,
1066                                         item->name_change.name, item->name_change.old_id,
1067                                         item->name_change.new_id, item->name_change.flags);
1068
1069                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
1070                                 if(message == NULL)
1071                                 {
1072                                         ret_size = -1;
1073                                         goto out;
1074                                 }
1075
1076                                 sprintf(dbus_name,":1.%llu",item->name_change.old_id);
1077                                 pString = item->name_change.name;
1078                                 _dbus_verbose ("Name changed: %s\n", pString);
1079                             dbus_message_iter_init_append(message, &args);
1080                             ITER_APPEND_STR(pString)
1081                             ITER_APPEND_STR(pDBusName)
1082                             sprintf(&dbus_name[3],"%llu",item->name_change.new_id);
1083                             _dbus_verbose ("New id: %s\n", pDBusName);
1084                             ITER_APPEND_STR(pDBusName)
1085                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1086                                 dbus_message_set_serial(message, 1);
1087
1088                                 ret_size = put_message_into_data(message, data);
1089                         break;
1090
1091                         case KDBUS_MSG_ID_ADD:
1092                                 _dbus_verbose("  +%s (%llu bytes) id=%llu flags=%llu\n",
1093                                            enum_MSG(item->type), (unsigned long long) item->size,
1094                                            (unsigned long long) item->id_change.id,
1095                                            (unsigned long long) item->id_change.flags);
1096
1097                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
1098                                 if(message == NULL)
1099                                 {
1100                                         ret_size = -1;
1101                                         goto out;
1102                                 }
1103
1104                                 sprintf(dbus_name,":1.%llu",item->id_change.id);
1105                             dbus_message_iter_init_append(message, &args);
1106                             ITER_APPEND_STR(pDBusName)
1107                             ITER_APPEND_STR(emptyString)
1108                             ITER_APPEND_STR(pDBusName)
1109                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1110                                 dbus_message_set_serial(message, 1);
1111
1112                                 ret_size = put_message_into_data(message, data);
1113                         break;
1114
1115                         case KDBUS_MSG_ID_REMOVE:
1116                                 _dbus_verbose("  +%s (%llu bytes) id=%llu flags=%llu\n",
1117                                            enum_MSG(item->type), (unsigned long long) item->size,
1118                                            (unsigned long long) item->id_change.id,
1119                                            (unsigned long long) item->id_change.flags);
1120
1121                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
1122                                 if(message == NULL)
1123                                 {
1124                                         ret_size = -1;
1125                                         goto out;
1126                                 }
1127
1128                                 sprintf(dbus_name,":1.%llu",item->id_change.id);
1129                             dbus_message_iter_init_append(message, &args);
1130                             ITER_APPEND_STR(pDBusName)
1131                             ITER_APPEND_STR(pDBusName)
1132                             ITER_APPEND_STR(emptyString)
1133                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1134                                 dbus_message_set_serial(message, 1);
1135
1136                                 ret_size = put_message_into_data(message, data);
1137                         break;
1138 #if KDBUS_MSG_DECODE_DEBUG == 1
1139                         default:
1140                                 _dbus_verbose("  +%s (%llu bytes)\n", enum_MSG(item->type), item->size);
1141                         break;
1142 #endif
1143                 }
1144         }
1145
1146 #if KDBUS_MSG_DECODE_DEBUG == 1
1147
1148         if ((char *)item - ((char *)msg + msg->size) >= 8)
1149                 _dbus_verbose("invalid padding at end of message\n");
1150 #endif
1151
1152 out:
1153         if(message)
1154                 dbus_message_unref(message);
1155         return ret_size;
1156 }
1157
1158 /**
1159  * Reads message from kdbus and puts it into dbus buffer and fds
1160  *
1161  * @param transport transport
1162  * @param buffer place to copy received message to
1163  * @param fds place to store file descriptors sent in the message
1164  * @param n_fds place  to store number of file descriptors
1165  * @return size of received message on success, -1 on error
1166  */
1167 static int kdbus_read_message(DBusTransportSocket *socket_transport, DBusString *buffer, int* fds, int* n_fds)
1168 {
1169         int ret_size;
1170         uint64_t __attribute__ ((__aligned__(8))) offset;
1171         struct kdbus_msg *msg;
1172         char *data;
1173
1174         _dbus_assert (socket_transport->max_bytes_read_per_iteration >= 0);
1175         if (!_dbus_string_lengthen (buffer, socket_transport->max_bytes_read_per_iteration))
1176         {
1177                 errno = ENOMEM;
1178             return -1;
1179         }
1180         data = _dbus_string_get_data_len (buffer, 0, socket_transport->max_bytes_read_per_iteration);
1181
1182         again:
1183         if (ioctl(socket_transport->fd, KDBUS_CMD_MSG_RECV, &offset) < 0)
1184         {
1185                 if(errno == EINTR)
1186                         goto again;
1187                 _dbus_verbose("kdbus error receiving message: %d (%m)\n", errno);
1188                 _dbus_string_set_length (buffer, 0);
1189                 return -1;
1190         }
1191
1192         msg = (struct kdbus_msg *)((char*)socket_transport->kdbus_mmap_ptr + offset);
1193
1194         ret_size = kdbus_decode_msg(msg, data, socket_transport, fds, n_fds);
1195         _dbus_string_set_length (buffer, ret_size);
1196
1197         again2:
1198         if (ioctl(socket_transport->fd, KDBUS_CMD_MSG_RELEASE, &offset) < 0)
1199         {
1200                 if(errno == EINTR)
1201                         goto again2;
1202                 _dbus_verbose("kdbus error freeing message: %d (%m)\n", errno);
1203                 return -1;
1204         }
1205
1206         return ret_size;
1207 }
1208
1209 static void
1210 free_watches (DBusTransport *transport)
1211 {
1212   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1213
1214   _dbus_verbose ("start\n");
1215
1216   if (socket_transport->read_watch)
1217     {
1218       if (transport->connection)
1219         _dbus_connection_remove_watch_unlocked (transport->connection,
1220                                                 socket_transport->read_watch);
1221       _dbus_watch_invalidate (socket_transport->read_watch);
1222       _dbus_watch_unref (socket_transport->read_watch);
1223       socket_transport->read_watch = NULL;
1224     }
1225
1226   if (socket_transport->write_watch)
1227     {
1228       if (transport->connection)
1229         _dbus_connection_remove_watch_unlocked (transport->connection,
1230                                                 socket_transport->write_watch);
1231       _dbus_watch_invalidate (socket_transport->write_watch);
1232       _dbus_watch_unref (socket_transport->write_watch);
1233       socket_transport->write_watch = NULL;
1234     }
1235
1236   _dbus_verbose ("end\n");
1237 }
1238
1239 static void
1240 socket_finalize (DBusTransport *transport)
1241 {
1242   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1243
1244   _dbus_verbose ("\n");
1245
1246   free_watches (transport);
1247
1248   _dbus_string_free (&socket_transport->encoded_outgoing);
1249   _dbus_string_free (&socket_transport->encoded_incoming);
1250
1251   _dbus_transport_finalize_base (transport);
1252
1253   _dbus_assert (socket_transport->read_watch == NULL);
1254   _dbus_assert (socket_transport->write_watch == NULL);
1255
1256   dbus_free (transport);
1257 }
1258
1259 static void
1260 check_write_watch (DBusTransport *transport)
1261 {
1262   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1263   dbus_bool_t needed;
1264
1265   if (transport->connection == NULL)
1266     return;
1267
1268   if (transport->disconnected)
1269     {
1270       _dbus_assert (socket_transport->write_watch == NULL);
1271       return;
1272     }
1273
1274   _dbus_transport_ref (transport);
1275
1276 #ifdef DBUS_AUTHENTICATION
1277   if (_dbus_transport_get_is_authenticated (transport))
1278 #endif
1279     needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
1280 #ifdef DBUS_AUTHENTICATION
1281   else
1282     {
1283       if (transport->send_credentials_pending)
1284         needed = TRUE;
1285       else
1286         {
1287           DBusAuthState auth_state;
1288
1289           auth_state = _dbus_auth_do_work (transport->auth);
1290
1291           /* If we need memory we install the write watch just in case,
1292            * if there's no need for it, it will get de-installed
1293            * next time we try reading.
1294            */
1295           if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND ||
1296               auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
1297             needed = TRUE;
1298           else
1299             needed = FALSE;
1300         }
1301     }
1302 #endif
1303   _dbus_verbose ("check_write_watch(): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
1304                  needed, transport->connection, socket_transport->write_watch,
1305                  socket_transport->fd,
1306                  _dbus_connection_has_messages_to_send_unlocked (transport->connection));
1307
1308   _dbus_connection_toggle_watch_unlocked (transport->connection,
1309                                           socket_transport->write_watch,
1310                                           needed);
1311
1312   _dbus_transport_unref (transport);
1313 }
1314
1315 static void
1316 check_read_watch (DBusTransport *transport)
1317 {
1318   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1319   dbus_bool_t need_read_watch;
1320
1321   _dbus_verbose ("fd = %d\n",socket_transport->fd);
1322
1323   if (transport->connection == NULL)
1324     return;
1325
1326   if (transport->disconnected)
1327     {
1328       _dbus_assert (socket_transport->read_watch == NULL);
1329       return;
1330     }
1331
1332   _dbus_transport_ref (transport);
1333
1334 #ifdef DBUS_AUTHENTICATION
1335   if (_dbus_transport_get_is_authenticated (transport))
1336 #endif
1337     need_read_watch =
1338       (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
1339       (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
1340 #ifdef DBUS_AUTHENTICATION
1341   else
1342     {
1343       if (transport->receive_credentials_pending)
1344         need_read_watch = TRUE;
1345       else
1346         {
1347           /* The reason to disable need_read_watch when not WAITING_FOR_INPUT
1348            * is to avoid spinning on the file descriptor when we're waiting
1349            * to write or for some other part of the auth process
1350            */
1351           DBusAuthState auth_state;
1352
1353           auth_state = _dbus_auth_do_work (transport->auth);
1354
1355           /* If we need memory we install the read watch just in case,
1356            * if there's no need for it, it will get de-installed
1357            * next time we try reading. If we're authenticated we
1358            * install it since we normally have it installed while
1359            * authenticated.
1360            */
1361           if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT ||
1362               auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY ||
1363               auth_state == DBUS_AUTH_STATE_AUTHENTICATED)
1364             need_read_watch = TRUE;
1365           else
1366             need_read_watch = FALSE;
1367         }
1368     }
1369 #endif
1370
1371   _dbus_verbose ("  setting read watch enabled = %d\n", need_read_watch);
1372   _dbus_connection_toggle_watch_unlocked (transport->connection,
1373                                           socket_transport->read_watch,
1374                                           need_read_watch);
1375
1376   _dbus_transport_unref (transport);
1377 }
1378
1379 static void
1380 do_io_error (DBusTransport *transport)
1381 {
1382   _dbus_transport_ref (transport);
1383   _dbus_transport_disconnect (transport);
1384   _dbus_transport_unref (transport);
1385 }
1386
1387 #ifdef DBUS_AUTHENTICATION
1388 /* return value is whether we successfully read any new data. */
1389 static dbus_bool_t
1390 read_data_into_auth (DBusTransport *transport,
1391                      dbus_bool_t   *oom)
1392 {
1393   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1394   DBusString *buffer;
1395   int bytes_read;
1396
1397   *oom = FALSE;
1398
1399   _dbus_auth_get_buffer (transport->auth, &buffer);
1400
1401   bytes_read = kdbus_read_message(socket_transport, buffer);
1402
1403   _dbus_auth_return_buffer (transport->auth, buffer,
1404                             bytes_read > 0 ? bytes_read : 0);
1405
1406   if (bytes_read > 0)
1407     {
1408       _dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
1409       return TRUE;
1410     }
1411   else if (bytes_read < 0)
1412     {
1413       /* EINTR already handled for us */
1414
1415       if (_dbus_get_is_errno_enomem ())
1416         {
1417           *oom = TRUE;
1418         }
1419       else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
1420         ; /* do nothing, just return FALSE below */
1421       else
1422         {
1423           _dbus_verbose ("Error reading from remote app: %s\n",
1424                          _dbus_strerror_from_errno ());
1425           do_io_error (transport);
1426         }
1427
1428       return FALSE;
1429     }
1430   else
1431     {
1432       _dbus_assert (bytes_read == 0);
1433
1434       _dbus_verbose ("Disconnected from remote app\n");
1435       do_io_error (transport);
1436
1437       return FALSE;
1438     }
1439 }
1440
1441 /* Return value is whether we successfully wrote any bytes */
1442 static dbus_bool_t
1443 write_data_from_auth (DBusTransport *transport)
1444 {
1445   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1446   int bytes_written;
1447   const DBusString *buffer;
1448
1449   if (!_dbus_auth_get_bytes_to_send (transport->auth,
1450                                      &buffer))
1451     return FALSE;
1452
1453   bytes_written = _dbus_write_socket (socket_transport->fd,
1454                                       buffer,
1455                                       0, _dbus_string_get_length (buffer));
1456
1457   if (bytes_written > 0)
1458     {
1459       _dbus_auth_bytes_sent (transport->auth, bytes_written);
1460       return TRUE;
1461     }
1462   else if (bytes_written < 0)
1463     {
1464       /* EINTR already handled for us */
1465
1466       if (_dbus_get_is_errno_eagain_or_ewouldblock ())
1467         ;
1468       else
1469         {
1470           _dbus_verbose ("Error writing to remote app: %s\n",
1471                          _dbus_strerror_from_errno ());
1472           do_io_error (transport);
1473         }
1474     }
1475
1476   return FALSE;
1477 }
1478
1479 /* FALSE on OOM */
1480 static dbus_bool_t
1481 exchange_credentials (DBusTransport *transport,
1482                       dbus_bool_t    do_reading,
1483                       dbus_bool_t    do_writing)
1484 {
1485   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1486   DBusError error = DBUS_ERROR_INIT;
1487
1488   _dbus_verbose ("exchange_credentials: do_reading = %d, do_writing = %d\n",
1489                   do_reading, do_writing);
1490
1491   if (do_writing && transport->send_credentials_pending)
1492     {
1493       if (_dbus_send_credentials_socket (socket_transport->fd,
1494                                          &error))
1495         {
1496           transport->send_credentials_pending = FALSE;
1497         }
1498       else
1499         {
1500           _dbus_verbose ("Failed to write credentials: %s\n", error.message);
1501           dbus_error_free (&error);
1502           do_io_error (transport);
1503         }
1504     }
1505
1506   if (do_reading && transport->receive_credentials_pending)
1507     {
1508       /* FIXME this can fail due to IO error _or_ OOM, broken
1509        * (somewhat tricky to fix since the OOM error can be set after
1510        * we already read the credentials byte, so basically we need to
1511        * separate reading the byte and storing it in the
1512        * transport->credentials). Does not really matter for now
1513        * because storing in credentials never actually fails on unix.
1514        */
1515       if (_dbus_read_credentials_socket (socket_transport->fd,
1516                                          transport->credentials,
1517                                          &error))
1518         {
1519           transport->receive_credentials_pending = FALSE;
1520         }
1521       else
1522         {
1523           _dbus_verbose ("Failed to read credentials %s\n", error.message);
1524           dbus_error_free (&error);
1525           do_io_error (transport);
1526         }
1527     }
1528
1529   if (!(transport->send_credentials_pending ||
1530         transport->receive_credentials_pending))
1531     {
1532       if (!_dbus_auth_set_credentials (transport->auth,
1533                                        transport->credentials))
1534         return FALSE;
1535     }
1536
1537   return TRUE;
1538 }
1539
1540 static dbus_bool_t
1541 do_authentication (DBusTransport *transport,
1542                    dbus_bool_t    do_reading,
1543                    dbus_bool_t    do_writing,
1544                    dbus_bool_t   *auth_completed)
1545 {
1546   dbus_bool_t oom;
1547   dbus_bool_t orig_auth_state;
1548
1549   oom = FALSE;
1550
1551   orig_auth_state = _dbus_transport_get_is_authenticated (transport);
1552
1553   /* This is essential to avoid the check_write_watch() at the end,
1554    * we don't want to add a write watch in do_iteration before
1555    * we try writing and get EAGAIN
1556    */
1557   if (orig_auth_state)
1558     {
1559       if (auth_completed)
1560         *auth_completed = FALSE;
1561       return TRUE;
1562     }
1563
1564   _dbus_transport_ref (transport);
1565
1566   while (!_dbus_transport_get_is_authenticated (transport) &&
1567          _dbus_transport_get_is_connected (transport))
1568     {
1569       if (!exchange_credentials (transport, do_reading, do_writing))
1570         {
1571           oom = TRUE;
1572           goto out;
1573         }
1574
1575       if (transport->send_credentials_pending ||
1576           transport->receive_credentials_pending)
1577         {
1578           _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
1579                          transport->send_credentials_pending,
1580                          transport->receive_credentials_pending);
1581           goto out;
1582         }
1583
1584 #define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client")
1585       switch (_dbus_auth_do_work (transport->auth))
1586         {
1587         case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
1588           _dbus_verbose (" %s auth state: waiting for input\n",
1589                          TRANSPORT_SIDE (transport));
1590           if (!do_reading || !read_data_into_auth (transport, &oom))
1591             goto out;
1592           break;
1593
1594         case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
1595           _dbus_verbose (" %s auth state: waiting for memory\n",
1596                          TRANSPORT_SIDE (transport));
1597           oom = TRUE;
1598           goto out;
1599           break;
1600
1601         case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
1602           _dbus_verbose (" %s auth state: bytes to send\n",
1603                          TRANSPORT_SIDE (transport));
1604           if (!do_writing || !write_data_from_auth (transport))
1605             goto out;
1606           break;
1607
1608         case DBUS_AUTH_STATE_NEED_DISCONNECT:
1609           _dbus_verbose (" %s auth state: need to disconnect\n",
1610                          TRANSPORT_SIDE (transport));
1611           do_io_error (transport);
1612           break;
1613
1614         case DBUS_AUTH_STATE_AUTHENTICATED:
1615           _dbus_verbose (" %s auth state: authenticated\n",
1616                          TRANSPORT_SIDE (transport));
1617           break;
1618         }
1619     }
1620
1621  out:
1622   if (auth_completed)
1623     *auth_completed = (orig_auth_state != _dbus_transport_get_is_authenticated (transport));
1624
1625   check_read_watch (transport);
1626   check_write_watch (transport);
1627   _dbus_transport_unref (transport);
1628
1629   if (oom)
1630     return FALSE;
1631   else
1632     return TRUE;
1633 }
1634 #endif
1635
1636 /* returns false on oom */
1637 static dbus_bool_t
1638 do_writing (DBusTransport *transport)
1639 {
1640         DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1641         dbus_bool_t oom;
1642
1643 #ifdef DBUS_AUTHENTICATION
1644         /* No messages without authentication! */
1645         if (!_dbus_transport_get_is_authenticated (transport))
1646     {
1647                 _dbus_verbose ("Not authenticated, not writing anything\n");
1648                 return TRUE;
1649     }
1650 #endif
1651
1652         if (transport->disconnected)
1653     {
1654                 _dbus_verbose ("Not connected, not writing anything\n");
1655                 return TRUE;
1656     }
1657
1658 #if 1
1659         _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n",
1660                  _dbus_connection_has_messages_to_send_unlocked (transport->connection),
1661                  socket_transport->fd);
1662 #endif
1663
1664         oom = FALSE;
1665
1666         while (!transport->disconnected && _dbus_connection_has_messages_to_send_unlocked (transport->connection))
1667     {
1668                 int bytes_written;
1669                 DBusMessage *message;
1670                 const DBusString *header;
1671                 const DBusString *body;
1672                 int total_bytes_to_write;
1673                 const char* pDestination;
1674
1675                 message = _dbus_connection_get_message_to_send (transport->connection);
1676                 _dbus_assert (message != NULL);
1677                 dbus_message_lock (message);
1678                 _dbus_message_get_network_data (message, &header, &body);
1679                 total_bytes_to_write = _dbus_string_get_length(header) + _dbus_string_get_length(body);
1680                 pDestination = dbus_message_get_destination(message);
1681
1682                 if(pDestination)
1683                 {
1684                         if(!strcmp(pDestination, "org.freedesktop.DBus"))
1685                         {
1686                                 if(emulateOrgFreedesktopDBus(transport, message))
1687                                         bytes_written = total_bytes_to_write;
1688                                 else
1689                                         bytes_written = -1;
1690                                 goto written;
1691                         }
1692                 }
1693                 if (_dbus_auth_needs_encoding (transport->auth))
1694         {
1695                         if (_dbus_string_get_length (&socket_transport->encoded_outgoing) == 0)
1696             {
1697                                 if (!_dbus_auth_encode_data (transport->auth,
1698                                            header, &socket_transport->encoded_outgoing))
1699                 {
1700                                         oom = TRUE;
1701                                         goto out;
1702                 }
1703
1704                                 if (!_dbus_auth_encode_data (transport->auth,
1705                                            body, &socket_transport->encoded_outgoing))
1706                 {
1707                                         _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
1708                                         oom = TRUE;
1709                                         goto out;
1710                 }
1711             }
1712
1713                         total_bytes_to_write = _dbus_string_get_length (&socket_transport->encoded_outgoing);
1714                         if(total_bytes_to_write > socket_transport->max_bytes_written_per_iteration)
1715                                 return -E2BIG;
1716
1717                         bytes_written = kdbus_write_msg(socket_transport, message, TRUE);
1718         }
1719                 else
1720                 {
1721                         if(total_bytes_to_write > socket_transport->max_bytes_written_per_iteration)
1722                                 return -E2BIG;
1723
1724                         bytes_written = kdbus_write_msg(socket_transport, message, FALSE);
1725                 }
1726
1727 written:
1728                 if (bytes_written < 0)
1729                 {
1730                         /* EINTR already handled for us */
1731
1732           /* For some discussion of why we also ignore EPIPE here, see
1733            * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html
1734            */
1735
1736                         if (_dbus_get_is_errno_eagain_or_ewouldblock () || _dbus_get_is_errno_epipe ())
1737                                 goto out;
1738                         else
1739                         {
1740                                 _dbus_verbose ("Error writing to remote app: %s\n", _dbus_strerror_from_errno ());
1741                                 do_io_error (transport);
1742                                 goto out;
1743                         }
1744                 }
1745                 else
1746                 {
1747                         _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
1748                          total_bytes_to_write);
1749
1750                         socket_transport->message_bytes_written += bytes_written;
1751
1752                         _dbus_assert (socket_transport->message_bytes_written <=
1753                         total_bytes_to_write);
1754
1755                           if (socket_transport->message_bytes_written == total_bytes_to_write)
1756                           {
1757                                   socket_transport->message_bytes_written = 0;
1758                                   _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
1759                                   _dbus_string_compact (&socket_transport->encoded_outgoing, 2048);
1760
1761                                   _dbus_connection_message_sent_unlocked (transport->connection,
1762                                                                                                                   message);
1763                           }
1764                 }
1765     }
1766
1767         out:
1768         if (oom)
1769                 return FALSE;
1770         else
1771                 return TRUE;
1772 }
1773
1774 /* returns false on out-of-memory */
1775 static dbus_bool_t
1776 do_reading (DBusTransport *transport)
1777 {
1778   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1779   DBusString *buffer;
1780   int bytes_read;
1781   dbus_bool_t oom = FALSE;
1782   int *fds, n_fds;
1783
1784   _dbus_verbose ("fd = %d\n",socket_transport->fd);
1785
1786 #ifdef DBUS_AUTHENTICATION
1787   /* No messages without authentication! */
1788   if (!_dbus_transport_get_is_authenticated (transport))
1789     return TRUE;
1790 #endif
1791
1792  again:
1793
1794   /* See if we've exceeded max messages and need to disable reading */
1795   check_read_watch (transport);
1796
1797   _dbus_assert (socket_transport->read_watch != NULL ||
1798                 transport->disconnected);
1799
1800   if (transport->disconnected)
1801     goto out;
1802
1803   if (!dbus_watch_get_enabled (socket_transport->read_watch))
1804     return TRUE;
1805
1806   if (!_dbus_message_loader_get_unix_fds(transport->loader, &fds, &n_fds))
1807   {
1808       _dbus_verbose ("Out of memory reading file descriptors\n");
1809       oom = TRUE;
1810       goto out;
1811   }
1812   _dbus_message_loader_get_buffer (transport->loader, &buffer);
1813
1814   if (_dbus_auth_needs_decoding (transport->auth))
1815   {
1816           bytes_read = kdbus_read_message(socket_transport,  &socket_transport->encoded_incoming, fds, &n_fds);
1817
1818       _dbus_assert (_dbus_string_get_length (&socket_transport->encoded_incoming) == bytes_read);
1819
1820       if (bytes_read > 0)
1821       {
1822           if (!_dbus_auth_decode_data (transport->auth,
1823                                        &socket_transport->encoded_incoming,
1824                                        buffer))
1825           {
1826               _dbus_verbose ("Out of memory decoding incoming data\n");
1827               _dbus_message_loader_return_buffer (transport->loader,
1828                                               buffer,
1829                                               _dbus_string_get_length (buffer));
1830               oom = TRUE;
1831               goto out;
1832           }
1833
1834           _dbus_string_set_length (&socket_transport->encoded_incoming, 0);
1835           _dbus_string_compact (&socket_transport->encoded_incoming, 2048);
1836       }
1837   }
1838   else
1839           bytes_read = kdbus_read_message(socket_transport, buffer, fds, &n_fds);
1840
1841   if (bytes_read >= 0 && n_fds > 0)
1842     _dbus_verbose("Read %i unix fds\n", n_fds);
1843
1844   _dbus_message_loader_return_buffer (transport->loader,
1845                                       buffer,
1846                                       bytes_read < 0 ? 0 : _dbus_string_get_length (buffer));
1847   _dbus_message_loader_return_unix_fds(transport->loader, fds, bytes_read < 0 ? 0 : n_fds);
1848
1849   if (bytes_read < 0)
1850     {
1851       /* EINTR already handled for us */
1852
1853       if (_dbus_get_is_errno_enomem ())
1854         {
1855           _dbus_verbose ("Out of memory in read()/do_reading()\n");
1856           oom = TRUE;
1857           goto out;
1858         }
1859       else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
1860         goto out;
1861       else
1862         {
1863           _dbus_verbose ("Error reading from remote app: %s\n",
1864                          _dbus_strerror_from_errno ());
1865           do_io_error (transport);
1866           goto out;
1867         }
1868     }
1869   else if (bytes_read == 0)
1870     {
1871       _dbus_verbose ("Disconnected from remote app\n");
1872       do_io_error (transport);
1873       goto out;
1874     }
1875   else
1876     {
1877       _dbus_verbose (" read %d bytes\n", bytes_read);
1878
1879       if (!_dbus_transport_queue_messages (transport))
1880         {
1881           oom = TRUE;
1882           _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
1883           goto out;
1884         }
1885
1886       /* Try reading more data until we get EAGAIN and return, or
1887        * exceed max bytes per iteration.  If in blocking mode of
1888        * course we'll block instead of returning.
1889        */
1890       goto again;
1891     }
1892
1893  out:
1894   if (oom)
1895     return FALSE;
1896   else
1897     return TRUE;
1898 }
1899
1900 static dbus_bool_t
1901 unix_error_with_read_to_come (DBusTransport *itransport,
1902                               DBusWatch     *watch,
1903                               unsigned int   flags)
1904 {
1905    DBusTransportSocket *transport = (DBusTransportSocket *) itransport;
1906
1907    if (!(flags & DBUS_WATCH_HANGUP || flags & DBUS_WATCH_ERROR))
1908       return FALSE;
1909
1910   /* If we have a read watch enabled ...
1911      we -might have data incoming ... => handle the HANGUP there */
1912    if (watch != transport->read_watch && _dbus_watch_get_enabled (transport->read_watch))
1913       return FALSE;
1914
1915    return TRUE;
1916 }
1917
1918 static dbus_bool_t
1919 socket_handle_watch (DBusTransport *transport,
1920                    DBusWatch     *watch,
1921                    unsigned int   flags)
1922 {
1923   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1924
1925   _dbus_assert (watch == socket_transport->read_watch ||
1926                 watch == socket_transport->write_watch);
1927   _dbus_assert (watch != NULL);
1928
1929   /* If we hit an error here on a write watch, don't disconnect the transport yet because data can
1930    * still be in the buffer and do_reading may need several iteration to read
1931    * it all (because of its max_bytes_read_per_iteration limit).
1932    */
1933   if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags))
1934     {
1935       _dbus_verbose ("Hang up or error on watch\n");
1936       _dbus_transport_disconnect (transport);
1937       return TRUE;
1938     }
1939
1940   if (watch == socket_transport->read_watch &&
1941       (flags & DBUS_WATCH_READABLE))
1942     {
1943 #ifdef DBUS_AUTHENTICATION
1944       dbus_bool_t auth_finished;
1945 #endif
1946 #if 1
1947       _dbus_verbose ("handling read watch %p flags = %x\n",
1948                      watch, flags);
1949 #endif
1950 #ifdef DBUS_AUTHENTICATION
1951       if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
1952         return FALSE;
1953
1954       /* We don't want to do a read immediately following
1955        * a successful authentication.  This is so we
1956        * have a chance to propagate the authentication
1957        * state further up.  Specifically, we need to
1958        * process any pending data from the auth object.
1959        */
1960       if (!auth_finished)
1961         {
1962 #endif
1963           if (!do_reading (transport))
1964             {
1965               _dbus_verbose ("no memory to read\n");
1966               return FALSE;
1967             }
1968 #ifdef DBUS_AUTHENTICATION
1969         }
1970       else
1971         {
1972           _dbus_verbose ("Not reading anything since we just completed the authentication\n");
1973         }
1974 #endif
1975     }
1976   else if (watch == socket_transport->write_watch &&
1977            (flags & DBUS_WATCH_WRITABLE))
1978     {
1979 #if 1
1980       _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
1981                      _dbus_connection_has_messages_to_send_unlocked (transport->connection));
1982 #endif
1983 #ifdef DBUS_AUTHENTICATION
1984       if (!do_authentication (transport, FALSE, TRUE, NULL))
1985         return FALSE;
1986 #endif
1987       if (!do_writing (transport))
1988         {
1989           _dbus_verbose ("no memory to write\n");
1990           return FALSE;
1991         }
1992
1993       /* See if we still need the write watch */
1994       check_write_watch (transport);
1995     }
1996 #ifdef DBUS_ENABLE_VERBOSE_MODE
1997   else
1998     {
1999       if (watch == socket_transport->read_watch)
2000         _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
2001                        flags);
2002       else if (watch == socket_transport->write_watch)
2003         _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
2004                        flags);
2005       else
2006         _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
2007                        watch, dbus_watch_get_socket (watch));
2008     }
2009 #endif /* DBUS_ENABLE_VERBOSE_MODE */
2010
2011   return TRUE;
2012 }
2013
2014 static void
2015 socket_disconnect (DBusTransport *transport)
2016 {
2017   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
2018
2019   _dbus_verbose ("\n");
2020
2021   free_watches (transport);
2022
2023   _dbus_close_socket (socket_transport->fd, NULL);
2024   socket_transport->fd = -1;
2025 }
2026
2027 static dbus_bool_t
2028 socket_connection_set (DBusTransport *transport)
2029 {
2030   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
2031
2032   _dbus_watch_set_handler (socket_transport->write_watch,
2033                            _dbus_connection_handle_watch,
2034                            transport->connection, NULL);
2035
2036   _dbus_watch_set_handler (socket_transport->read_watch,
2037                            _dbus_connection_handle_watch,
2038                            transport->connection, NULL);
2039
2040   if (!_dbus_connection_add_watch_unlocked (transport->connection,
2041                                             socket_transport->write_watch))
2042     return FALSE;
2043
2044   if (!_dbus_connection_add_watch_unlocked (transport->connection,
2045                                             socket_transport->read_watch))
2046     {
2047       _dbus_connection_remove_watch_unlocked (transport->connection,
2048                                               socket_transport->write_watch);
2049       return FALSE;
2050     }
2051
2052   check_read_watch (transport);
2053   check_write_watch (transport);
2054
2055   return TRUE;
2056 }
2057
2058 /**
2059  * @todo We need to have a way to wake up the select sleep if
2060  * a new iteration request comes in with a flag (read/write) that
2061  * we're not currently serving. Otherwise a call that just reads
2062  * could block a write call forever (if there are no incoming
2063  * messages).
2064  */
2065 static  void
2066 kdbus_do_iteration (DBusTransport *transport,
2067                    unsigned int   flags,
2068                    int            timeout_milliseconds)
2069 {
2070         DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
2071         DBusPollFD poll_fd;
2072         int poll_res;
2073         int poll_timeout;
2074
2075         _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
2076                  flags & DBUS_ITERATION_DO_READING ? "read" : "",
2077                  flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
2078                  timeout_milliseconds,
2079                  socket_transport->read_watch,
2080                  socket_transport->write_watch,
2081                  socket_transport->fd);
2082
2083   /* the passed in DO_READING/DO_WRITING flags indicate whether to
2084    * read/write messages, but regardless of those we may need to block
2085    * for reading/writing to do auth.  But if we do reading for auth,
2086    * we don't want to read any messages yet if not given DO_READING.
2087    */
2088
2089    poll_fd.fd = socket_transport->fd;
2090    poll_fd.events = 0;
2091
2092    if (_dbus_transport_get_is_authenticated (transport))
2093    {
2094       /* This is kind of a hack; if we have stuff to write, then try
2095        * to avoid the poll. This is probably about a 5% speedup on an
2096        * echo client/server.
2097        *
2098        * If both reading and writing were requested, we want to avoid this
2099        * since it could have funky effects:
2100        *   - both ends spinning waiting for the other one to read
2101        *     data so they can finish writing
2102        *   - prioritizing all writing ahead of reading
2103        */
2104       if ((flags & DBUS_ITERATION_DO_WRITING) &&
2105           !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
2106           !transport->disconnected &&
2107           _dbus_connection_has_messages_to_send_unlocked (transport->connection))
2108       {
2109          do_writing (transport);
2110
2111          if (transport->disconnected ||
2112               !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
2113             goto out;
2114       }
2115
2116       /* If we get here, we decided to do the poll() after all */
2117       _dbus_assert (socket_transport->read_watch);
2118       if (flags & DBUS_ITERATION_DO_READING)
2119              poll_fd.events |= _DBUS_POLLIN;
2120
2121       _dbus_assert (socket_transport->write_watch);
2122       if (flags & DBUS_ITERATION_DO_WRITING)
2123          poll_fd.events |= _DBUS_POLLOUT;
2124    }
2125    else
2126    {
2127       DBusAuthState auth_state;
2128
2129       auth_state = _dbus_auth_do_work (transport->auth);
2130
2131       if (transport->receive_credentials_pending || auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
2132              poll_fd.events |= _DBUS_POLLIN;
2133
2134       if (transport->send_credentials_pending || auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
2135              poll_fd.events |= _DBUS_POLLOUT;
2136    }
2137
2138    if (poll_fd.events)
2139    {
2140       if (flags & DBUS_ITERATION_BLOCK)
2141              poll_timeout = timeout_milliseconds;
2142       else
2143              poll_timeout = 0;
2144
2145       /* For blocking selects we drop the connection lock here
2146        * to avoid blocking out connection access during a potentially
2147        * indefinite blocking call. The io path is still protected
2148        * by the io_path_cond condvar, so we won't reenter this.
2149        */
2150       if (flags & DBUS_ITERATION_BLOCK)
2151       {
2152          _dbus_verbose ("unlock pre poll\n");
2153          _dbus_connection_unlock (transport->connection);
2154       }
2155
2156     again:
2157       poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
2158
2159       if (poll_res < 0 && _dbus_get_is_errno_eintr ())
2160       {
2161          _dbus_verbose ("Error from _dbus_poll(): %s\n", _dbus_strerror_from_errno ());
2162          goto again;
2163       }
2164
2165       if (flags & DBUS_ITERATION_BLOCK)
2166       {
2167          _dbus_verbose ("lock post poll\n");
2168          _dbus_connection_lock (transport->connection);
2169       }
2170
2171       if (poll_res >= 0)
2172       {
2173          if (poll_res == 0)
2174             poll_fd.revents = 0; /* some concern that posix does not guarantee this;
2175                                   * valgrind flags it as an error. though it probably
2176                                   * is guaranteed on linux at least.
2177                                   */
2178
2179          if (poll_fd.revents & _DBUS_POLLERR)
2180             do_io_error (transport);
2181          else
2182          {
2183             dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
2184             dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
2185 #ifdef DBUS_AUTHENTICATION
2186               dbus_bool_t authentication_completed;
2187 #endif
2188
2189             _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
2190                              need_read, need_write);
2191 #ifdef DBUS_AUTHENTICATION
2192               do_authentication (transport, need_read, need_write,
2193                                  &authentication_completed);
2194
2195               /* See comment in socket_handle_watch. */
2196               if (authentication_completed)
2197                 goto out;
2198 #endif
2199             if (need_read && (flags & DBUS_ITERATION_DO_READING))
2200                do_reading (transport);
2201             if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
2202                do_writing (transport);
2203          }
2204       }
2205       else
2206          _dbus_verbose ("Error from _dbus_poll(): %s\n", _dbus_strerror_from_errno ());
2207    }
2208
2209  out:
2210   /* We need to install the write watch only if we did not
2211    * successfully write everything. Note we need to be careful that we
2212    * don't call check_write_watch *before* do_writing, since it's
2213    * inefficient to add the write watch, and we can avoid it most of
2214    * the time since we can write immediately.
2215    *
2216    * However, we MUST always call check_write_watch(); DBusConnection code
2217    * relies on the fact that running an iteration will notice that
2218    * messages are pending.
2219    */
2220    check_write_watch (transport);
2221
2222    _dbus_verbose (" ... leaving do_iteration()\n");
2223 }
2224
2225 static void
2226 socket_live_messages_changed (DBusTransport *transport)
2227 {
2228   /* See if we should look for incoming messages again */
2229   check_read_watch (transport);
2230 }
2231
2232 static const DBusTransportVTable kdbus_vtable = {
2233   socket_finalize,
2234   socket_handle_watch,
2235   socket_disconnect,
2236   socket_connection_set,
2237   kdbus_do_iteration,
2238   socket_live_messages_changed,
2239   socket_get_socket_fd
2240 };
2241
2242 /**
2243  * Creates a new transport for the given kdbus file descriptor.  The file
2244  * descriptor must be nonblocking.
2245  *
2246  * @param fd the file descriptor.
2247  * @param address the transport's address
2248  * @returns the new transport, or #NULL if no memory.
2249  */
2250 static DBusTransport*
2251 _dbus_transport_new_for_socket_kdbus (int       fd,
2252                                           const DBusString *address)
2253 {
2254         DBusTransportSocket *socket_transport;
2255
2256   socket_transport = dbus_new0 (DBusTransportSocket, 1);
2257   if (socket_transport == NULL)
2258     return NULL;
2259
2260   if (!_dbus_string_init (&socket_transport->encoded_outgoing))
2261     goto failed_0;
2262
2263   if (!_dbus_string_init (&socket_transport->encoded_incoming))
2264     goto failed_1;
2265
2266   socket_transport->write_watch = _dbus_watch_new (fd,
2267                                                  DBUS_WATCH_WRITABLE,
2268                                                  FALSE,
2269                                                  NULL, NULL, NULL);
2270   if (socket_transport->write_watch == NULL)
2271     goto failed_2;
2272
2273   socket_transport->read_watch = _dbus_watch_new (fd,
2274                                                 DBUS_WATCH_READABLE,
2275                                                 FALSE,
2276                                                 NULL, NULL, NULL);
2277   if (socket_transport->read_watch == NULL)
2278     goto failed_3;
2279
2280   if (!_dbus_transport_init_base (&socket_transport->base,
2281                                   &kdbus_vtable,
2282                                   NULL, address))
2283     goto failed_4;
2284
2285 #ifdef DBUS_AUTHENTICATION
2286 #ifdef HAVE_UNIX_FD_PASSING
2287   _dbus_auth_set_unix_fd_possible(socket_transport->base.auth, _dbus_socket_can_pass_unix_fd(fd));
2288 #endif
2289 #endif
2290
2291   socket_transport->fd = fd;
2292   socket_transport->message_bytes_written = 0;
2293
2294   /* These values should probably be tunable or something. */
2295   socket_transport->max_bytes_read_per_iteration = DBUS_MAXIMUM_MESSAGE_LENGTH;
2296   socket_transport->max_bytes_written_per_iteration = DBUS_MAXIMUM_MESSAGE_LENGTH;
2297
2298   socket_transport->kdbus_mmap_ptr = NULL;
2299   socket_transport->memfd = -1;
2300   
2301   return (DBusTransport*) socket_transport;
2302
2303  failed_4:
2304   _dbus_watch_invalidate (socket_transport->read_watch);
2305   _dbus_watch_unref (socket_transport->read_watch);
2306  failed_3:
2307   _dbus_watch_invalidate (socket_transport->write_watch);
2308   _dbus_watch_unref (socket_transport->write_watch);
2309  failed_2:
2310   _dbus_string_free (&socket_transport->encoded_incoming);
2311  failed_1:
2312   _dbus_string_free (&socket_transport->encoded_outgoing);
2313  failed_0:
2314   dbus_free (socket_transport);
2315   return NULL;
2316 }
2317
2318
2319 /**
2320  * Opens a connection to the kdbus bus
2321  *
2322  * This will set FD_CLOEXEC for the socket returned.
2323  *
2324  * @param path the path to UNIX domain socket
2325  * @param error return location for error code
2326  * @returns connection file descriptor or -1 on error
2327  */
2328 static int _dbus_connect_kdbus (const char *path, DBusError *error)
2329 {
2330         int fd;
2331
2332         _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2333         _dbus_verbose ("connecting to kdbus bus %s\n", path);
2334
2335         fd = open(path, O_RDWR|O_CLOEXEC|O_NONBLOCK);
2336         if (fd < 0)
2337                 dbus_set_error(error, _dbus_error_from_errno (errno), "Failed to open file descriptor: %s", _dbus_strerror (errno));
2338
2339         return fd;
2340 }
2341
2342 /**
2343  * maps memory pool for messages received by the kdbus transport
2344  *
2345  * @param transport transport
2346  * @returns #TRUE on success, otherwise FALSE
2347  */
2348 static dbus_bool_t kdbus_mmap(DBusTransport* transport)
2349 {
2350         DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
2351
2352         socket_transport->kdbus_mmap_ptr = mmap(NULL, RECEIVE_POOL_SIZE, PROT_READ, MAP_SHARED, socket_transport->fd, 0);
2353         if (socket_transport->kdbus_mmap_ptr == MAP_FAILED)
2354                 return FALSE;
2355
2356         return TRUE;
2357 }
2358
2359 /**
2360  * Creates a new transport for kdbus.
2361  * This creates a client-side of a transport.
2362  *
2363  * @param path the path to the bus.
2364  * @param error address where an error can be returned.
2365  * @returns a new transport, or #NULL on failure.
2366  */
2367 static DBusTransport* _dbus_transport_new_for_kdbus (const char *path, DBusError *error)
2368 {
2369         int fd;
2370         DBusTransport *transport;
2371         DBusString address;
2372
2373         _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2374
2375         if (!_dbus_string_init (&address))
2376     {
2377                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2378                 return NULL;
2379     }
2380
2381         fd = -1;
2382
2383         if ((!_dbus_string_append (&address, "kdbus:path=")) || (!_dbus_string_append (&address, path)))
2384     {
2385                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2386                 goto failed_0;
2387     }
2388
2389         fd = _dbus_connect_kdbus (path, error);
2390         if (fd < 0)
2391     {
2392                 _DBUS_ASSERT_ERROR_IS_SET (error);
2393                 goto failed_0;
2394     }
2395
2396         _dbus_verbose ("Successfully connected to kdbus bus %s\n", path);
2397
2398         transport = _dbus_transport_new_for_socket_kdbus (fd, &address);
2399         if (transport == NULL)
2400     {
2401                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2402                 goto failed_1;
2403     }
2404
2405         _dbus_string_free (&address);
2406
2407         return transport;
2408
2409         failed_1:
2410                 _dbus_close_socket (fd, NULL);
2411         failed_0:
2412                 _dbus_string_free (&address);
2413         return NULL;
2414 }
2415
2416
2417 /**
2418  * Opens kdbus transport if method from address entry is kdbus
2419  *
2420  * @param entry the address entry to try opening
2421  * @param transport_p return location for the opened transport
2422  * @param error error to be set
2423  * @returns result of the attempt
2424  */
2425 DBusTransportOpenResult _dbus_transport_open_kdbus(DBusAddressEntry  *entry,
2426                                                            DBusTransport    **transport_p,
2427                                                            DBusError         *error)
2428 {
2429         const char *method;
2430
2431         method = dbus_address_entry_get_method (entry);
2432         _dbus_assert (method != NULL);
2433
2434         if (strcmp (method, "kdbus") == 0)
2435     {
2436                 const char *path = dbus_address_entry_get_value (entry, "path");
2437
2438                 if (path == NULL)
2439         {
2440                         _dbus_set_bad_address (error, "kdbus", "path", NULL);
2441                         return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
2442         }
2443
2444         *transport_p = _dbus_transport_new_for_kdbus (path, error);
2445
2446         if (*transport_p == NULL)
2447         {
2448                 _DBUS_ASSERT_ERROR_IS_SET (error);
2449                 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
2450         }
2451         else
2452         {
2453                 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2454                 return DBUS_TRANSPORT_OPEN_OK;
2455         }
2456     }
2457         else
2458     {
2459                 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2460                 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
2461     }
2462 }
2463
2464 static struct kdbus_policy *make_policy_name(const char *name)
2465 {
2466         struct kdbus_policy *p;
2467         __u64 size;
2468
2469         size = offsetof(struct kdbus_policy, name) + strlen(name) + 1;
2470         p = malloc(size);
2471         if (!p)
2472                 return NULL;
2473         memset(p, 0, size);
2474         p->size = size;
2475         p->type = KDBUS_POLICY_NAME;
2476         strcpy(p->name, name);
2477
2478         return p;
2479 }
2480
2481 static struct kdbus_policy *make_policy_access(__u64 type, __u64 bits, __u64 id)
2482 {
2483         struct kdbus_policy *p;
2484         __u64 size = sizeof(*p);
2485
2486         p = malloc(size);
2487         if (!p)
2488                 return NULL;
2489
2490         memset(p, 0, size);
2491         p->size = size;
2492         p->type = KDBUS_POLICY_ACCESS;
2493         p->access.type = type;
2494         p->access.bits = bits;
2495         p->access.id = id;
2496
2497         return p;
2498 }
2499
2500 static void append_policy(struct kdbus_cmd_policy *cmd_policy, struct kdbus_policy *policy, __u64 max_size)
2501 {
2502         struct kdbus_policy *dst = (struct kdbus_policy *) ((char *) cmd_policy + cmd_policy->size);
2503
2504         if (cmd_policy->size + policy->size > max_size)
2505                 return;
2506
2507         memcpy(dst, policy, policy->size);
2508         cmd_policy->size += KDBUS_ALIGN8(policy->size);
2509         free(policy);
2510 }
2511
2512 /**
2513  * Registers kdbus policy for given connection.
2514  *
2515  * Policy sets rights of the name (unique or well known) on the bus. Without policy it is
2516  * not possible to send or receive messages. It must be set separately for unique id and
2517  * well known name of the connection. It is set after registering on the bus, but before
2518  * requesting for name. The policy is valid for the given name, not for the connection.
2519  *
2520  * Name of the policy equals name on the bus.
2521  *
2522  * @param name name of the policy = name of the connection
2523  * @param connection the connection
2524  * @param error place to store errors
2525  *
2526  * @returns #TRUE on success
2527  */
2528 dbus_bool_t bus_register_policy_kdbus(const char* name, DBusConnection *connection, DBusError *error)
2529 {
2530         struct kdbus_cmd_policy *cmd_policy;
2531         struct kdbus_policy *policy;
2532         int size = 0xffff;
2533         int fd;
2534
2535         if(!dbus_connection_get_socket(connection, &fd))
2536         {
2537                 dbus_set_error (error, "Failed to get fd for registering policy", NULL);
2538                 return FALSE;
2539         }
2540
2541         cmd_policy = alloca(size);
2542         memset(cmd_policy, 0, size);
2543
2544         policy = (struct kdbus_policy *) cmd_policy->policies;
2545         cmd_policy->size = offsetof(struct kdbus_cmd_policy, policies);
2546
2547         policy = make_policy_name(name);
2548         append_policy(cmd_policy, policy, size);
2549
2550         policy = make_policy_access(KDBUS_POLICY_ACCESS_USER, KDBUS_POLICY_OWN, getuid());
2551         append_policy(cmd_policy, policy, size);
2552
2553         policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_RECV, 0);
2554         append_policy(cmd_policy, policy, size);
2555
2556         policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_SEND, 0);
2557         append_policy(cmd_policy, policy, size);
2558
2559         if (ioctl(fd, KDBUS_CMD_EP_POLICY_SET, cmd_policy) < 0)
2560         {
2561                 dbus_set_error(error,_dbus_error_from_errno (errno), "Error setting EP policy: %s", _dbus_strerror (errno));
2562                 return FALSE;
2563         }
2564
2565         _dbus_verbose("Policy %s set correctly\n", name);
2566         return TRUE;
2567 }
2568
2569 /**
2570  * Kdbus part of dbus_bus_register.
2571  * Shouldn't be used separately because it needs to be surrounded
2572  * by other functions as it is done in dbus_bus_register.
2573  *
2574  * @param name place to store unique name given by bus
2575  * @param connection the connection
2576  * @param error place to store errors
2577  * @returns #TRUE on success
2578  */
2579 dbus_bool_t bus_register_kdbus(char* name, DBusConnection *connection, DBusError *error)
2580 {
2581         struct kdbus_cmd_hello __attribute__ ((__aligned__(8))) hello;
2582         int fd;
2583
2584         hello.conn_flags = KDBUS_HELLO_ACCEPT_FD/* |
2585                            KDBUS_HELLO_ATTACH_COMM |
2586                            KDBUS_HELLO_ATTACH_EXE |
2587                            KDBUS_HELLO_ATTACH_CMDLINE |
2588                            KDBUS_HELLO_ATTACH_CAPS |
2589                            KDBUS_HELLO_ATTACH_CGROUP |
2590                            KDBUS_HELLO_ATTACH_SECLABEL |
2591                            KDBUS_HELLO_ATTACH_AUDIT*/;
2592         hello.size = sizeof(struct kdbus_cmd_hello);
2593         hello.pool_size = RECEIVE_POOL_SIZE;
2594
2595         if(!dbus_connection_get_socket(connection, &fd))
2596         {
2597                 dbus_set_error (error, "failed to get fd for bus registration", NULL);
2598                 return FALSE;
2599         }
2600         if (ioctl(fd, KDBUS_CMD_HELLO, &hello))
2601         {
2602                 dbus_set_error(error,_dbus_error_from_errno (errno), "Failed to send hello: %s", _dbus_strerror (errno));
2603                 return FALSE;
2604         }
2605
2606         sprintf(name, "%llu", (unsigned long long)hello.id);
2607         _dbus_verbose("-- Our peer ID is: %s\n", name);
2608         ((DBusTransportSocket*)dbus_connection_get_transport(connection))->bloom_size = hello.bloom_size;
2609
2610         if(!kdbus_mmap(dbus_connection_get_transport(connection)))
2611         {
2612                 dbus_set_error(error,_dbus_error_from_errno (errno), "Error when mmap: %s", _dbus_strerror (errno));
2613                 return FALSE;
2614         }
2615
2616         return TRUE;
2617 }
2618
2619 /**
2620  * kdbus version of dbus_bus_request_name.
2621  *
2622  * Asks the bus to assign the given name to this connection.
2623  *
2624  * Use same flags as original dbus version with one exception below.
2625  * Result flag #DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER is currently
2626  * never returned by kdbus, instead DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER
2627  * is returned by kdbus.
2628  *
2629  * @param connection the connection
2630  * @param name the name to request
2631  * @param flags flags
2632  * @param error location to store the error
2633  * @returns a result code, -1 if error is set
2634  */
2635 int bus_request_name_kdbus(DBusConnection *connection, const char *name, const uint64_t flags, DBusError *error)
2636 {
2637         struct kdbus_cmd_name *cmd_name;
2638         int fd;
2639         uint64_t size = sizeof(*cmd_name) + strlen(name) + 1;
2640         uint64_t flags_kdbus = 0;
2641
2642         cmd_name = alloca(size);
2643
2644         memset(cmd_name, 0, size);
2645         strcpy(cmd_name->name, name);
2646         cmd_name->size = size;
2647
2648         if(flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT)
2649                 flags_kdbus |= KDBUS_NAME_ALLOW_REPLACEMENT;
2650         if(!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE))
2651                 flags_kdbus |= KDBUS_NAME_QUEUE;
2652         if(flags & DBUS_NAME_FLAG_REPLACE_EXISTING)
2653                 flags_kdbus |= KDBUS_NAME_REPLACE_EXISTING;
2654
2655         cmd_name->conn_flags = flags_kdbus;
2656
2657         if(!dbus_connection_get_socket(connection, &fd))
2658         {
2659                 dbus_set_error (error, "failed to get fd for name request", NULL);
2660                 return -1;
2661         }
2662
2663         _dbus_verbose("Request name - flags sent: 0x%llx       !!!!!!!!!\n", cmd_name->conn_flags);
2664
2665         _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2666         if (ioctl(fd, KDBUS_CMD_NAME_ACQUIRE, cmd_name))
2667         {
2668                 dbus_set_error(error,_dbus_error_from_errno (errno), "error acquiring name: %s", _dbus_strerror (errno));
2669                 if(errno == EEXIST)
2670                         return DBUS_REQUEST_NAME_REPLY_EXISTS;
2671                 return -1;
2672         }
2673
2674         _dbus_verbose("Request name - received flag: 0x%llx       !!!!!!!!!\n", cmd_name->conn_flags);
2675
2676         if(cmd_name->conn_flags & KDBUS_NAME_IN_QUEUE)
2677                 return DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
2678         else
2679                 return DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
2680         /*todo now 1 code is never returned -  DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER
2681          * because kdbus never returns it now
2682          */
2683 }
2684
2685 /**
2686  * Checks if the connection's transport is kdbus on the basis of its address
2687  *
2688  * @param pointer to the connection
2689  * @returns TRUE if kdbus transport, otherwise FALSE
2690  */
2691 dbus_bool_t dbus_transport_is_kdbus(DBusConnection *connection)
2692 {
2693         const char* address = _dbus_connection_get_address(connection);
2694
2695         if(address == strstr(address, "kdbus:path="))
2696                 return TRUE;
2697         else
2698                 return FALSE;
2699 }
2700
2701 /**
2702  * Seeks key in rule string, and duplicates value of the key into pValue.
2703  * If value is "org.freedesktop.DBus" it is indicated by returning -1, because it
2704  * needs to be handled in different manner.
2705  * Value is duplicated from rule string to newly allocated memory pointe by pValue,
2706  * so it must be freed after use.
2707  *
2708  * @param rule rule to look through
2709  * @param key key to look for
2710  * @param pValue pointer to value of the key found
2711  * @return length of the value string, 0 means not found, -1 means "org.freedesktop.DBus"
2712  */
2713 static int parse_match_key(const char *rule, const char* key, char** pValue)
2714 {
2715         const char* pBegin;
2716         const char* pValueEnd;
2717         int value_length = 0;
2718
2719         pBegin = strstr(rule, key);
2720         if(pBegin)
2721         {
2722                 pBegin += strlen(key);
2723                 pValueEnd = strchr(pBegin, '\'');
2724                 if(pValueEnd)
2725                 {
2726                         value_length = pValueEnd - pBegin;
2727                         *pValue = strndup(pBegin, value_length);
2728                         if(*pValue)
2729                         {
2730                                 if(strcmp(*pValue, "org.freedesktop.DBus") == 0)
2731                                         value_length = -1;
2732                                 _dbus_verbose ("found for key: %s value:'%s'\n", key, *pValue);
2733                         }
2734                 }
2735         }
2736         return value_length;
2737 }
2738
2739 /**
2740  * Adds a match rule to match broadcast messages going through the message bus.
2741  * Do no affect messages addressed directly.
2742  *
2743  * The "rule" argument is the string form of a match rule.
2744  *
2745  * In kdbus function do not blocks.
2746  *
2747  * Upper function returns nothing because of blocking issues
2748  * so there is no point to return true or false here.
2749  *
2750  * Only part of the dbus's matching capabilities is implemented in kdbus now, because of different mechanism.
2751  * Current mapping:
2752  * interface match key mapped to bloom
2753  * sender match key mapped to src_name
2754  * also handled org.freedesktop.dbus members: NameOwnerChanged, NameLost, NameAcquired
2755  *
2756  * @param connection connection to the message bus
2757  * @param rule textual form of match rule
2758  * @param error location to store any errors - may be NULL
2759  */
2760 void dbus_bus_add_match_kdbus (DBusConnection *connection, const char *rule, DBusError *error)
2761 {
2762         struct kdbus_cmd_match* pCmd_match;
2763         struct kdbus_item *pItem;
2764         int fd;
2765         __u64 src_id = KDBUS_MATCH_SRC_ID_ANY;
2766         uint64_t size;
2767         unsigned int kernel_item = 0;
2768         int name_size;
2769         char* pName = NULL;
2770         char* pInterface = NULL;
2771         __u64 bloom_size = ((DBusTransportSocket*)dbus_connection_get_transport(connection))->bloom_size;
2772
2773         dbus_connection_get_socket(connection, &fd);
2774
2775         /*parsing rule and calculating size of command*/
2776         size = sizeof(struct kdbus_cmd_match);
2777
2778         if(strstr(rule, "member='NameOwnerChanged'"))
2779         {
2780                 kernel_item = KDBUS_MATCH_NAME_CHANGE;
2781                 size += KDBUS_ITEM_SIZE(1);
2782         }
2783         else if(strstr(rule, "member='NameLost'"))
2784         {
2785                 kernel_item = KDBUS_MATCH_NAME_REMOVE;
2786                 size += KDBUS_ITEM_SIZE(1);
2787         }
2788         else if(strstr(rule, "member='NameAcquired'"))
2789         {
2790                 kernel_item = KDBUS_MATCH_NAME_ADD;
2791                 size += KDBUS_ITEM_SIZE(1);
2792         }
2793
2794         name_size = parse_match_key(rule, "interface='", &pInterface);
2795         if((name_size == -1) && (kernel_item == 0))   //means org.freedesktop.DBus without specified member
2796         {
2797                 kernel_item = ~0;
2798                 size += KDBUS_ITEM_SIZE(1)*3 + KDBUS_ITEM_SIZE(sizeof(__u64))*2;  /* 3 above name related items plus 2 id related items*/
2799         }
2800         else if(name_size > 0)                  /*actual size is not important for interface because bloom size is defined by bus*/
2801                 size += KDBUS_PART_HEADER_SIZE + bloom_size;
2802
2803         name_size = parse_match_key(rule, "sender='", &pName);
2804         if((name_size == -1) && (kernel_item == 0))  //means org.freedesktop.DBus without specified name - same as interface few line above
2805         {
2806                 kernel_item = ~0;
2807                 size += KDBUS_ITEM_SIZE(1)*3 + KDBUS_ITEM_SIZE(sizeof(__u64))*2; /* 3 above     name related items plus 2 id related items*/
2808         }
2809         else if(name_size > 0)
2810         {
2811                 if(!strncmp(pName, ":1.", 3)) /*if name is unique name it must be converted to unique id*/
2812                 {
2813                         src_id = strtoull(&pName[3], NULL, 10);
2814                         free(pName);
2815                         pName = NULL;
2816                 }
2817                 else
2818                         size += KDBUS_ITEM_SIZE(name_size + 1);  //well known name
2819         }
2820
2821         pCmd_match = alloca(size);
2822         if(pCmd_match == NULL)
2823                 goto out;
2824
2825         pCmd_match->id = 0;
2826         pCmd_match->size = size;
2827         pCmd_match->cookie = strtoull(dbus_bus_get_unique_name(connection), NULL , 10);
2828
2829         pItem = pCmd_match->items;
2830         if(kernel_item == ~0)  //all signals from kernel
2831         {
2832                 pCmd_match->src_id = 0;
2833                 pItem->type = KDBUS_MATCH_NAME_CHANGE;
2834                 pItem->size = KDBUS_PART_HEADER_SIZE + 1;
2835                 pItem = KDBUS_PART_NEXT(pItem);
2836                 pItem->type = KDBUS_MATCH_NAME_ADD;
2837                 pItem->size = KDBUS_PART_HEADER_SIZE + 1;
2838                 pItem = KDBUS_PART_NEXT(pItem);
2839                 pItem->type = KDBUS_MATCH_NAME_REMOVE;
2840                 pItem->size = KDBUS_PART_HEADER_SIZE + 1;
2841                 pItem = KDBUS_PART_NEXT(pItem);
2842                 pItem->type = KDBUS_MATCH_ID_ADD;
2843                 pItem->size = KDBUS_PART_HEADER_SIZE + sizeof(__u64);
2844                 pItem = KDBUS_PART_NEXT(pItem);
2845                 pItem->type = KDBUS_MATCH_ID_REMOVE;
2846                 pItem->size = KDBUS_PART_HEADER_SIZE + sizeof(__u64);
2847         }
2848         else if(kernel_item) //only one item
2849         {
2850                 pCmd_match->src_id = 0;
2851                 pItem->type = kernel_item;
2852                 pItem->size = KDBUS_PART_HEADER_SIZE + 1;
2853         }
2854         else
2855         {
2856                 pCmd_match->src_id = src_id;
2857                 if(pName)
2858                 {
2859                         pItem->type = KDBUS_MATCH_SRC_NAME;
2860                         pItem->size = KDBUS_PART_HEADER_SIZE + name_size + 1;
2861                         strcpy(pItem->str, pName);
2862                         pItem = KDBUS_PART_NEXT(pItem);
2863                 }
2864
2865                 if(pInterface)
2866                 {
2867                         pItem->type = KDBUS_MATCH_BLOOM;
2868                         pItem->size = KDBUS_PART_HEADER_SIZE + bloom_size;
2869                         strncpy(pItem->data, pInterface, bloom_size);
2870                 }
2871         }
2872
2873         if(ioctl(fd, KDBUS_CMD_MATCH_ADD, pCmd_match))
2874         {
2875                 if(error)
2876                         dbus_set_error(error,_dbus_error_from_errno (errno), "error adding match: %s", _dbus_strerror (errno));
2877                 _dbus_verbose("Failed adding match bus rule %s,\nerror: %d, %m\n", rule, errno);
2878         }
2879         else
2880                 _dbus_verbose("Added match bus rule %s\n", rule);
2881
2882 out:
2883         if(pName)
2884                 free(pName);
2885         if(pInterface)
2886                 free(pInterface);
2887 }
2888
2889 /**
2890  * Opposing to dbus, in kdbus removes all match rules with given
2891  * cookie, which now is equal to uniqe id.
2892  *
2893  * In kdbus this function will not block
2894  *
2895  * @param connection connection to the message bus
2896  * @param error location to store any errors - may be NULL
2897  */
2898 void dbus_bus_remove_match_kdbus (DBusConnection *connection, DBusError *error)
2899 {
2900         struct kdbus_cmd_match __attribute__ ((__aligned__(8))) cmd;
2901         int fd;
2902
2903         dbus_connection_get_socket(connection, &fd);
2904         cmd.cookie = strtoull(dbus_bus_get_unique_name(connection), NULL , 10);
2905         cmd.id = cmd.cookie;
2906         cmd.size = sizeof(struct kdbus_cmd_match);
2907
2908         if(ioctl(fd, KDBUS_CMD_MATCH_ADD, &cmd))
2909         {
2910                 if(error)
2911                         dbus_set_error(error,_dbus_error_from_errno (errno), "error removing match: %s", _dbus_strerror (errno));
2912                 _dbus_verbose("Failed removing match rule; error: %d, %m\n", errno);
2913         }
2914         else
2915                 _dbus_verbose("Match rule removed correctly.\n");
2916 }