[lib] Comments
[platform/upstream/dbus.git] / dbus / dbus-transport-kdbus.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-transport-kdbus.c  kdbus subclasses of DBusTransport
3  *
4  * Copyright (C) 2002, 2003, 2004, 2006  Red Hat Inc
5  * Copyright (C) 2013  Samsung Electronics
6  *
7  * Licensed under the Academic Free License version 2.1
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version and under the terms of the GNU
13  * Lesser General Public License as published by the
14  * Free Software Foundation; either version 2.1 of the License, or (at
15  * your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
25  *
26  */
27 #include "dbus-transport.h"
28 #include "dbus-transport-kdbus.h"
29 #include "dbus-transport-protected.h"
30 #include "dbus-connection-internal.h"
31 #include "kdbus.h"
32 #include "dbus-watch.h"
33 #include "dbus-errors.h"
34 #include "dbus-bus.h"
35 #include "kdbus-common.h"
36 #include <linux/types.h>
37 #include <fcntl.h>
38 #include <errno.h>
39 #include <fcntl.h>
40 #include <sys/ioctl.h>
41 #include <stdio.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #include <unistd.h>
45 #include <sys/mman.h>
46 #include <limits.h>
47 #include <sys/stat.h>
48
49 #define RECEIVE_POOL_SIZE (10 * 1024LU * 1024LU) //size of the memory area for received non-memfd messages
50 #define MEMFD_SIZE_THRESHOLD (2 * 1024 * 1024LU) // over this memfd is used to send (if it is not broadcast)
51 //todo add compilation-time check if MEMFD_SIZE_THERSHOLD is lower than max payload vector size defined in kdbus.h
52
53 #define KDBUS_MSG_DECODE_DEBUG 0
54
55 #define ITER_APPEND_STR(string) \
56 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &string))   \
57 { \
58         ret_size = -1;  \
59         goto out;  \
60 }\
61
62 #define MSG_ITEM_BUILD_VEC(data, datasize)                                    \
63         item->type = KDBUS_MSG_PAYLOAD_VEC;                                     \
64         item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_vec);         \
65         item->vec.address = (unsigned long) data;                               \
66         item->vec.size = datasize;
67
68 #define KDBUS_PART_FOREACH(part, head, first)                           \
69         for (part = (head)->first;                                      \
70              (uint8_t *)(part) < (uint8_t *)(head) + (head)->size;      \
71              part = KDBUS_PART_NEXT(part))
72
73 /**
74  * Opaque object representing a transport.
75  */
76 typedef struct DBusTransportKdbus DBusTransportKdbus;
77
78 /**
79  * Implementation details of DBusTransportKdbus. All members are private.
80  */
81 struct DBusTransportKdbus
82 {
83   DBusTransport base;                   /**< Parent instance */
84   int fd;                               /**< File descriptor. */
85   DBusWatch *read_watch;                /**< Watch for readability. */
86   DBusWatch *write_watch;               /**< Watch for writability. */
87
88   int max_bytes_read_per_iteration;     /**< To avoid blocking too long. */
89   int max_bytes_written_per_iteration;  /**< To avoid blocking too long. */
90
91   void* kdbus_mmap_ptr;                 /**< Mapped memory where kdbus (kernel) writes
92                                          *   messages incoming to us.
93                                          */
94   int memfd;                            /**< File descriptor to special 
95                                          *   memory pool for bulk data
96                                          *   transfer. Retrieved from 
97                                          *   Kdbus kernel module. 
98                                          */
99   __u64 bloom_size;                                             /**< bloom filter field size */
100   char* sender;                         /**< unique name of the sender */
101 };
102
103 /**
104  *  Gets size in bytes of bloom filter field.
105  *  This size is got from the bus during connection procedure.
106  *  @param transport transport
107  *  @returns size of bloom
108  */
109 __u64 dbus_transport_get_bloom_size(DBusTransport* transport)
110 {
111   return ((DBusTransportKdbus*)transport)->bloom_size;
112 }
113
114 /**
115  * Puts locally generated message into received messages queue
116  * @param message message that will be added
117  * @param connection connection to which message will be added
118  * @returns TRUE on success, FALSE on memory allocation error
119  */
120 static dbus_bool_t add_message_to_received(DBusMessage *message, DBusConnection* connection)
121 {
122         DBusList *message_link;
123
124         message_link = _dbus_list_alloc_link (message);
125         if (message_link == NULL)
126         {
127                 dbus_message_unref (message);
128                 return FALSE;
129         }
130
131         _dbus_connection_queue_synthesized_message_link(connection, message_link);
132
133         return TRUE;
134 }
135
136 /**
137  * Generates local error message as a reply to message given as parameter
138  * and adds generated error message to received messages queue.
139  * @param error_Type type of error, preferably DBUS_ERROR_(...)
140  * @param template Template of error description. It can has formatting
141  *        characters to print object string into it. Can be NULL.
142  * @param object String to print into error description. Can be NULL.
143  *                If object is not NULL while template is NULL, the object string
144  *                will be the only error description.
145  * @param message Message for which the error reply is generated.
146  * @param connection The connection.
147  * @returns 0 on success, otherwise -1
148  */
149 static int reply_with_error(char* error_type, const char* template, const char* object, DBusMessage *message, DBusConnection* connection)
150 {
151         DBusMessage *errMessage;
152         char* error_msg = "";
153
154         if(template)
155         {
156                 error_msg = alloca(strlen(template) + strlen(object));
157                 sprintf(error_msg, template, object);
158         }
159         else if(object)
160                 error_msg = (char*)object;
161
162         errMessage = generate_local_error_message(dbus_message_get_serial(message), error_type, error_msg);
163         if(errMessage == NULL)
164                 return -1;
165         if (add_message_to_received(errMessage, connection))
166                 return 0;
167
168         return -1;
169 }
170
171 /**
172  *  Generates reply to the message given as a parameter with one item in the reply body
173  *  and adds generated reply message to received messages queue.
174  *  @param message The message we are replying to.
175  *  @param data_type Type of data sent in the reply.Use DBUS_TYPE_(...)
176  *  @param pData Address of data sent in the reply.
177  *  @param connection The connection
178  *  @returns 0 on success, otherwise -1
179  */
180 static int reply_1_data(DBusMessage *message, int data_type, void* pData, DBusConnection* connection)
181 {
182         DBusMessageIter args;
183         DBusMessage *reply;
184
185         reply = dbus_message_new_method_return(message);
186         if(reply == NULL)
187                 return -1;
188         dbus_message_set_sender(reply, DBUS_SERVICE_DBUS);
189     dbus_message_iter_init_append(reply, &args);
190     if (!dbus_message_iter_append_basic(&args, data_type, pData))
191     {
192         dbus_message_unref(reply);
193         return -1;
194     }
195     if(add_message_to_received(reply, connection))
196         return 0;
197
198     return -1;
199 }
200
201 /*
202 static int reply_ack(DBusMessage *message, DBusConnection* connection)
203 {
204         DBusMessage *reply;
205
206         reply = dbus_message_new_method_return(message);
207         if(reply == NULL)
208                 return -1;
209     if(add_message_to_received(reply, connection))
210         return 0;
211     return -1;
212 }*/
213
214 /**
215  * Retrieves file descriptor to memory pool from kdbus module and stores
216  * it in kdbus_transport->memfd. It is then used to send large message.
217  * Triggered when message payload is over MEMFD_SIZE_THRESHOLD
218  * @param kdbus_transport DBusTransportKdbus transport structure
219  * @returns 0 on success, otherwise -1
220  */
221 static int kdbus_init_memfd(DBusTransportKdbus* kdbus_transport)
222 {
223         int memfd;
224         
225                 if (ioctl(kdbus_transport->fd, KDBUS_CMD_MEMFD_NEW, &memfd) < 0) {
226                         _dbus_verbose("KDBUS_CMD_MEMFD_NEW failed: \n");
227                         return -1;
228                 }
229
230                 kdbus_transport->memfd = memfd;
231                 _dbus_verbose("kdbus_init_memfd: %d!!\n", kdbus_transport->memfd);
232         return 0;
233 }
234
235 /**
236  * Allocates and initializes kdbus message structure.
237  * @param name Well-known name or NULL. If NULL, dst_id must be supplied.
238  * @param dst_id Numeric id of recipient. Ignored if name is not NULL.
239  * @param body_size Size of message body (May be 0).
240  * @param use_memfd Flag to build memfd message.
241  * @param fds_count Number of file descriptors sent in the message.
242  * @param transport transport
243  * @returns initialized kdbus message or NULL if malloc failed
244  */
245 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, DBusTransportKdbus *transport)
246 {
247     struct kdbus_msg* msg;
248     uint64_t msg_size;
249
250     msg_size = sizeof(struct kdbus_msg);
251
252     if(use_memfd == TRUE)  // bulk data - memfd
253         msg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd));
254     else
255       {
256         msg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));  //header is a must
257         while(body_size > KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE)
258           {
259             msg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
260             body_size -= KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE;
261           }
262         if(body_size)
263           msg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
264       }
265
266     if(fds_count)
267         msg_size += KDBUS_ITEM_SIZE(sizeof(int)*fds_count);
268
269     if (name)
270         msg_size += KDBUS_ITEM_SIZE(strlen(name) + 1);
271     else if (dst_id == KDBUS_DST_ID_BROADCAST)
272         msg_size += KDBUS_PART_HEADER_SIZE + transport->bloom_size;
273
274     msg = malloc(msg_size);
275     if (!msg)
276     {
277         _dbus_verbose("Error allocating memory for: %s,%s\n", _dbus_strerror (errno), _dbus_error_from_errno (errno));
278                 return NULL;
279     }
280
281     memset(msg, 0, msg_size);
282     msg->size = msg_size;
283     msg->payload_type = KDBUS_PAYLOAD_DBUS1;
284     msg->dst_id = name ? 0 : dst_id;
285     msg->src_id = strtoull(dbus_bus_get_unique_name(transport->base.connection), NULL , 10);
286
287     return msg;
288 }
289
290 /**
291  * Sends DBus message using kdbus.
292  * Handles broadcasts and unicast messages, and passing of Unix fds.
293  * Also can locally generate error replies on some error returned by kernel.
294  *
295  * TODO refactor to be more compact - maybe we can send header always as a payload vector
296  *  and only message body as memfd if needed.
297  *
298  * @param transport Transport.
299  * @param message DBus message to be sent
300  * @param destination Destination of the message.
301  * @returns bytes sent or -1 if sending failed
302  */
303 static int kdbus_write_msg(DBusTransportKdbus *transport, DBusMessage *message, const char* destination)
304 {
305   struct kdbus_msg *msg;
306   struct kdbus_item *item;
307   uint64_t dst_id = KDBUS_DST_ID_BROADCAST;
308   const DBusString *header;
309   const DBusString *body;
310   uint64_t ret_size = 0;
311   uint64_t body_size = 0;
312   uint64_t header_size = 0;
313   dbus_bool_t use_memfd = FALSE;
314   const int *unix_fds;
315   unsigned fds_count;
316   dbus_bool_t autostart;
317
318   // determine destination and destination id
319   if(destination)
320     {
321       dst_id = KDBUS_DST_ID_WELL_KNOWN_NAME;
322       if((destination[0] == ':') && (destination[1] == '1') && (destination[2] == '.'))  /* if name starts with ":1." it is a unique name and should be send as number */
323         {
324           dst_id = strtoull(&destination[3], NULL, 10);
325           destination = NULL;
326         }
327     }
328
329   _dbus_message_get_network_data (message, &header, &body);
330   header_size = _dbus_string_get_length(header);
331   body_size = _dbus_string_get_length(body);
332   ret_size = header_size + body_size;
333
334   // check whether we can and should use memfd
335   if((dst_id != KDBUS_DST_ID_BROADCAST) && (ret_size > MEMFD_SIZE_THRESHOLD))
336     {
337       use_memfd = TRUE;
338       kdbus_init_memfd(transport);
339     }
340
341   _dbus_message_get_unix_fds(message, &unix_fds, &fds_count);
342
343   // init basic message fields
344   msg = kdbus_init_msg(destination, dst_id, body_size, use_memfd, fds_count, transport);
345   msg->cookie = dbus_message_get_serial(message);
346   autostart = dbus_message_get_auto_start (message);
347   if(!autostart)
348     msg->flags |= KDBUS_MSG_FLAGS_NO_AUTO_START;
349
350   // build message contents
351   item = msg->items;
352
353   if(use_memfd)
354     {
355       char *buf;
356
357       if(ioctl(transport->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 0) < 0)
358         {
359           _dbus_verbose("memfd sealing failed: \n");
360           goto out;
361         }
362
363       buf = mmap(NULL, ret_size, PROT_WRITE, MAP_SHARED, transport->memfd, 0);
364       if (buf == MAP_FAILED)
365         {
366           _dbus_verbose("mmap() fd=%i failed:%m", transport->memfd);
367           goto out;
368         }
369
370       memcpy(buf, _dbus_string_get_const_data(header), header_size);
371       if(body_size) {
372           buf+=header_size;
373           memcpy(buf, _dbus_string_get_const_data(body),  body_size);
374           buf-=header_size;
375       }
376
377       munmap(buf, ret_size);
378
379       // seal data - kdbus module needs it
380       if(ioctl(transport->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) < 0) {
381           _dbus_verbose("memfd sealing failed: %d (%m)\n", errno);
382           ret_size = -1;
383           goto out;
384       }
385
386       item->type = KDBUS_MSG_PAYLOAD_MEMFD;
387       item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_memfd);
388       item->memfd.size = ret_size;
389       item->memfd.fd = transport->memfd;
390     }
391   else
392     {
393       _dbus_verbose("sending normal vector data\n");
394       MSG_ITEM_BUILD_VEC(_dbus_string_get_const_data(header), header_size);
395
396       if(body_size)
397         {
398           const char* body_data;
399
400           body_data = _dbus_string_get_const_data(body);
401           while(body_size > KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE)
402             {
403               _dbus_verbose("body attaching\n");
404               item = KDBUS_PART_NEXT(item);
405               MSG_ITEM_BUILD_VEC(body_data, KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE);
406               body_data += KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE;
407               body_size -= KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE;
408             }
409           if(body_size)
410             {
411               _dbus_verbose("body attaching\n");
412               item = KDBUS_PART_NEXT(item);
413               MSG_ITEM_BUILD_VEC(body_data, body_size);
414             }
415         }
416     }
417
418   if(fds_count)
419     {
420       item = KDBUS_PART_NEXT(item);
421       item->type = KDBUS_MSG_FDS;
422       item->size = KDBUS_PART_HEADER_SIZE + (sizeof(int) * fds_count);
423       memcpy(item->fds, unix_fds, sizeof(int) * fds_count);
424     }
425
426   if (destination)
427     {
428       item = KDBUS_PART_NEXT(item);
429       item->type = KDBUS_MSG_DST_NAME;
430       item->size = KDBUS_PART_HEADER_SIZE + strlen(destination) + 1;
431       memcpy(item->str, destination, item->size - KDBUS_PART_HEADER_SIZE);
432     }
433   else if (dst_id == KDBUS_DST_ID_BROADCAST)
434     {
435       item = KDBUS_PART_NEXT(item);
436       item->type = KDBUS_MSG_BLOOM;
437       item->size = KDBUS_PART_HEADER_SIZE + transport->bloom_size;
438       strncpy(item->data, dbus_message_get_interface(message), transport->bloom_size);
439     }
440
441   again:
442   if (ioctl(transport->fd, KDBUS_CMD_MSG_SEND, msg))
443     {
444       if(errno == EINTR)
445         goto again;
446       else if(errno == ENXIO) //no such id on the bus
447         {
448           if(!reply_with_error(DBUS_ERROR_NAME_HAS_NO_OWNER, "Name \"%s\" does not exist", dbus_message_get_destination(message), message, transport->base.connection))
449             goto out;
450         }
451       else if((errno == ESRCH) || (errno = EADDRNOTAVAIL))  //when well known name is not available on the bus
452         {
453           if(autostart)
454             {
455               if(!reply_with_error(DBUS_ERROR_SERVICE_UNKNOWN, "The name %s was not provided by any .service files", dbus_message_get_destination(message), message, transport->base.connection))
456                 goto out;
457             }
458           else
459             if(!reply_with_error(DBUS_ERROR_NAME_HAS_NO_OWNER, "Name \"%s\" does not exist", dbus_message_get_destination(message), message, transport->base.connection))
460               goto out;
461         }
462       _dbus_verbose("kdbus error sending message: err %d (%m)\n", errno);
463       ret_size = -1;
464     }
465   out:
466   free(msg);
467   if(use_memfd)
468     close(transport->memfd);
469
470   return ret_size;
471 }
472
473 /**
474  * Performs kdbus hello - registration on the kdbus bus
475  * needed to send and receive messages on the bus,
476  * and configures transport.
477  * As a result unique id on he bus is obtained.
478  *
479  * @param name place to print id given by bus
480  * @param transportS transport structure
481  * @returns #TRUE on success
482  */
483 static dbus_bool_t bus_register_kdbus(char* name, DBusTransportKdbus* transportS)
484 {
485         struct kdbus_cmd_hello __attribute__ ((__aligned__(8))) hello;
486
487         hello.conn_flags = KDBUS_HELLO_ACCEPT_FD/* |
488                            KDBUS_HELLO_ATTACH_COMM |
489                            KDBUS_HELLO_ATTACH_EXE |
490                            KDBUS_HELLO_ATTACH_CMDLINE |
491                            KDBUS_HELLO_ATTACH_CAPS |
492                            KDBUS_HELLO_ATTACH_CGROUP |
493                            KDBUS_HELLO_ATTACH_SECLABEL |
494                            KDBUS_HELLO_ATTACH_AUDIT*/;
495         hello.size = sizeof(struct kdbus_cmd_hello);
496         hello.pool_size = RECEIVE_POOL_SIZE;
497
498         if (ioctl(transportS->fd, KDBUS_CMD_HELLO, &hello))
499         {
500                 _dbus_verbose ("Failed to send hello: %m, %d",errno);
501                 return FALSE;
502         }
503
504         sprintf(name, "%llu", (unsigned long long)hello.id);
505         _dbus_verbose("-- Our peer ID is: %s\n", name);
506         transportS->bloom_size = hello.bloom_size;
507
508         transportS->kdbus_mmap_ptr = mmap(NULL, RECEIVE_POOL_SIZE, PROT_READ, MAP_SHARED, transportS->fd, 0);
509         if (transportS->kdbus_mmap_ptr == MAP_FAILED)
510         {
511                 _dbus_verbose("Error when mmap: %m, %d",errno);
512                 return FALSE;
513         }
514
515         return TRUE;
516 }
517
518 /**
519  * Looks over messages sent to org.freedesktop.DBus. Hello message, which performs
520  * registration on the bus, is captured as it must be locally converted into
521  * appropriate ioctl. All the rest org.freedesktop.DBus methods are left untouched
522  * and they are sent to dbus-daemon in the same way as every other messages.
523  *
524  * @param transport Transport
525  * @param message Message being sent.
526  * @returns 1 if it is not Hello message and it should be passed to daemon
527  *                      0 if Hello message was handled correctly,
528  *                      -1 if Hello message was not handle correctly.
529  */
530 static int emulateOrgFreedesktopDBus(DBusTransport *transport, DBusMessage *message)
531 {
532   if(!strcmp(dbus_message_get_member(message), "Hello"))
533     {
534       char* name = NULL;
535
536       name = malloc(snprintf(name, 0, ":1.%llu0", ULLONG_MAX));
537       if(name == NULL)
538         return -1;
539       strcpy(name, ":1.");
540       if(!bus_register_kdbus(&name[3], (DBusTransportKdbus*)transport))
541         goto out;
542       if(!register_kdbus_policy(&name[3], transport, geteuid()))
543         goto out;
544
545       ((DBusTransportKdbus*)transport)->sender = name;
546
547       if(!reply_1_data(message, DBUS_TYPE_STRING, &name, transport->connection))
548         return 0;
549
550     out:
551       free(name);
552     }
553   else
554     return 1;  //send to daemon
555
556   return -1;
557 }
558
559 #if KDBUS_MSG_DECODE_DEBUG == 1
560 static char *msg_id(uint64_t id, char *buf)
561 {
562         if (id == 0)
563                 return "KERNEL";
564         if (id == ~0ULL)
565                 return "BROADCAST";
566         sprintf(buf, "%llu", (unsigned long long)id);
567         return buf;
568 }
569 #endif
570 struct kdbus_enum_table {
571         long long id;
572         const char *name;
573 };
574 #define _STRINGIFY(x) #x
575 #define STRINGIFY(x) _STRINGIFY(x)
576 #define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
577 #define TABLE(what) static struct kdbus_enum_table kdbus_table_##what[]
578 #define ENUM(_id) { .id=_id, .name=STRINGIFY(_id) }
579 #define LOOKUP(what)                                                            \
580         const char *enum_##what(long long id) {                                 \
581         size_t i; \
582                 for (i = 0; i < ELEMENTSOF(kdbus_table_##what); i++)    \
583                         if (id == kdbus_table_##what[i].id)                     \
584                                 return kdbus_table_##what[i].name;              \
585                 return "UNKNOWN";                                               \
586         }
587 const char *enum_MSG(long long id);
588 TABLE(MSG) = {
589         ENUM(_KDBUS_MSG_NULL),
590         ENUM(KDBUS_MSG_PAYLOAD_VEC),
591         ENUM(KDBUS_MSG_PAYLOAD_OFF),
592         ENUM(KDBUS_MSG_PAYLOAD_MEMFD),
593         ENUM(KDBUS_MSG_FDS),
594         ENUM(KDBUS_MSG_BLOOM),
595         ENUM(KDBUS_MSG_DST_NAME),
596         ENUM(KDBUS_MSG_SRC_CREDS),
597         ENUM(KDBUS_MSG_SRC_PID_COMM),
598         ENUM(KDBUS_MSG_SRC_TID_COMM),
599         ENUM(KDBUS_MSG_SRC_EXE),
600         ENUM(KDBUS_MSG_SRC_CMDLINE),
601         ENUM(KDBUS_MSG_SRC_CGROUP),
602         ENUM(KDBUS_MSG_SRC_CAPS),
603         ENUM(KDBUS_MSG_SRC_SECLABEL),
604         ENUM(KDBUS_MSG_SRC_AUDIT),
605         ENUM(KDBUS_MSG_SRC_NAMES),
606         ENUM(KDBUS_MSG_TIMESTAMP),
607         ENUM(KDBUS_MSG_NAME_ADD),
608         ENUM(KDBUS_MSG_NAME_REMOVE),
609         ENUM(KDBUS_MSG_NAME_CHANGE),
610         ENUM(KDBUS_MSG_ID_ADD),
611         ENUM(KDBUS_MSG_ID_REMOVE),
612         ENUM(KDBUS_MSG_REPLY_TIMEOUT),
613         ENUM(KDBUS_MSG_REPLY_DEAD),
614 };
615 LOOKUP(MSG);
616 const char *enum_PAYLOAD(long long id);
617 TABLE(PAYLOAD) = {
618         ENUM(KDBUS_PAYLOAD_KERNEL),
619         ENUM(KDBUS_PAYLOAD_DBUS1),
620         ENUM(KDBUS_PAYLOAD_GVARIANT),
621 };
622 LOOKUP(PAYLOAD);
623
624 /**
625  * Finalizes locally generated DBus message
626  * and puts it into data buffer.
627  *
628  * @param message Message to load.
629  * @param data Place to load message.
630  * @returns Size of message loaded.
631  */
632 static int put_message_into_data(DBusMessage *message, char* data)
633 {
634         int ret_size;
635     const DBusString *header;
636     const DBusString *body;
637     int size;
638
639     dbus_message_set_serial(message, 1);
640     dbus_message_lock (message);
641     _dbus_message_get_network_data (message, &header, &body);
642     ret_size = _dbus_string_get_length(header);
643         memcpy(data, _dbus_string_get_const_data(header), ret_size);
644         data += ret_size;
645         size = _dbus_string_get_length(body);
646         memcpy(data, _dbus_string_get_const_data(body), size);
647         ret_size += size;
648
649         return ret_size;
650 }
651
652 /**
653  * Calculates length of the kdbus message content (payload).
654  *
655  * @param msg kdbus message
656  * @return the length of the kdbus message's payload.
657  */
658 static int kdbus_message_size(const struct kdbus_msg* msg)
659 {
660         const struct kdbus_item *item;
661         int ret_size = 0;
662
663         KDBUS_PART_FOREACH(item, msg, items)
664         {
665                 if (item->size <= KDBUS_PART_HEADER_SIZE)
666                 {
667                         _dbus_verbose("  +%s (%llu bytes) invalid data record\n", enum_MSG(item->type), item->size);
668                         return -1;
669                 }
670                 switch (item->type)
671                 {
672                         case KDBUS_MSG_PAYLOAD_OFF:
673                                 ret_size += item->vec.size;
674                                 break;
675                         case KDBUS_MSG_PAYLOAD_MEMFD:
676                                 ret_size += item->memfd.size;
677                                 break;
678                         default:
679                                 break;
680                 }
681         }
682
683         return ret_size;
684 }
685
686 /**
687  * Decodes kdbus message in order to extract DBus message and puts it into received data buffer
688  * and file descriptor's buffer. Also captures kdbus error messages and kdbus kernel broadcasts
689  * and converts all of them into appropriate DBus messages.
690  *
691  * @param msg kdbus message
692  * @param data place to copy DBus message to
693  * @param kdbus_transport transport
694  * @param fds place to store file descriptors received
695  * @param n_fds place to store quantity of file descriptors received
696  * @return number of DBus message's bytes received or -1 on error
697  */
698 static int kdbus_decode_msg(const struct kdbus_msg* msg, char *data, DBusTransportKdbus* kdbus_transport, int* fds, int* n_fds)
699 {
700         const struct kdbus_item *item;
701         int ret_size = 0;
702         DBusMessage *message = NULL;
703         DBusMessageIter args;
704         const char* emptyString = "";
705     const char* pString = NULL;
706         char dbus_name[(unsigned int)(snprintf((char*)pString, 0, ":1.%llu0", ULLONG_MAX))];
707         const char* pDBusName = dbus_name;
708 #if KDBUS_MSG_DECODE_DEBUG == 1
709         char buf[32];
710 #endif
711
712 #if KDBUS_MSG_DECODE_DEBUG == 1
713         _dbus_verbose("MESSAGE: %s (%llu bytes) flags=0x%llx, %s â†’ %s, cookie=%llu, timeout=%llu\n",
714                 enum_PAYLOAD(msg->payload_type), (unsigned long long) msg->size,
715                 (unsigned long long) msg->flags,
716                 msg_id(msg->src_id, buf), msg_id(msg->dst_id, buf),
717                 (unsigned long long) msg->cookie, (unsigned long long) msg->timeout_ns);
718 #endif
719
720         *n_fds = 0;
721
722         KDBUS_PART_FOREACH(item, msg, items)
723         {
724                 if (item->size <= KDBUS_PART_HEADER_SIZE)
725                 {
726                         _dbus_verbose("  +%s (%llu bytes) invalid data record\n", enum_MSG(item->type), item->size);
727                         break;  //??? continue (because dbus will find error) or break
728                 }
729
730                 switch (item->type)
731                 {
732                         case KDBUS_MSG_PAYLOAD_OFF:
733                                 memcpy(data, (char *)kdbus_transport->kdbus_mmap_ptr + item->vec.offset, item->vec.size);
734                                 data += item->vec.size;
735                                 ret_size += item->vec.size;
736
737                                 _dbus_verbose("  +%s (%llu bytes) off=%llu size=%llu\n",
738                                         enum_MSG(item->type), item->size,
739                                         (unsigned long long)item->vec.offset,
740                                         (unsigned long long)item->vec.size);
741                         break;
742
743                         case KDBUS_MSG_PAYLOAD_MEMFD:
744                         {
745                                 char *buf;
746                                 uint64_t size;
747
748                                 size = item->memfd.size;
749                                 _dbus_verbose("memfd.size : %llu\n", (unsigned long long)size);
750
751                                 buf = mmap(NULL, size, PROT_READ , MAP_SHARED, item->memfd.fd, 0);
752                                 if (buf == MAP_FAILED)
753                                 {
754                                         _dbus_verbose("mmap() fd=%i failed:%m", item->memfd.fd);
755                                         return -1;
756                                 }
757
758                                 memcpy(data, buf, size);
759                                 data += size;
760                                 ret_size += size;
761
762                                 munmap(buf, size);
763
764                 _dbus_verbose("  +%s (%llu bytes) off=%llu size=%llu\n",
765                                            enum_MSG(item->type), item->size,
766                                            (unsigned long long)item->vec.offset,
767                                            (unsigned long long)item->vec.size);
768                         break;
769                         }
770
771                         case KDBUS_MSG_FDS:
772                         {
773                                 int i;
774
775                                 *n_fds = (item->size - KDBUS_PART_HEADER_SIZE) / sizeof(int);
776                                 memcpy(fds, item->fds, *n_fds * sizeof(int));
777                     for (i = 0; i < *n_fds; i++)
778                       _dbus_fd_set_close_on_exec(fds[i]);
779                         break;
780                         }
781
782 #if KDBUS_MSG_DECODE_DEBUG == 1
783                         case KDBUS_MSG_SRC_CREDS:
784                                 _dbus_verbose("  +%s (%llu bytes) uid=%lld, gid=%lld, pid=%lld, tid=%lld, starttime=%lld\n",
785                                         enum_MSG(item->type), item->size,
786                                         item->creds.uid, item->creds.gid,
787                                         item->creds.pid, item->creds.tid,
788                                         item->creds.starttime);
789                         break;
790
791                         case KDBUS_MSG_SRC_PID_COMM:
792                         case KDBUS_MSG_SRC_TID_COMM:
793                         case KDBUS_MSG_SRC_EXE:
794                         case KDBUS_MSG_SRC_CGROUP:
795                         case KDBUS_MSG_SRC_SECLABEL:
796                         case KDBUS_MSG_DST_NAME:
797                                 _dbus_verbose("  +%s (%llu bytes) '%s' (%zu)\n",
798                                            enum_MSG(item->type), item->size, item->str, strlen(item->str));
799                                 break;
800
801                         case KDBUS_MSG_SRC_CMDLINE:
802                         case KDBUS_MSG_SRC_NAMES: {
803                                 __u64 size = item->size - KDBUS_PART_HEADER_SIZE;
804                                 const char *str = item->str;
805                                 int count = 0;
806
807                                 _dbus_verbose("  +%s (%llu bytes) ", enum_MSG(item->type), item->size);
808                                 while (size) {
809                                         _dbus_verbose("'%s' ", str);
810                                         size -= strlen(str) + 1;
811                                         str += strlen(str) + 1;
812                                         count++;
813                                 }
814
815                                 _dbus_verbose("(%d string%s)\n", count, (count == 1) ? "" : "s");
816                                 break;
817                         }
818
819                         case KDBUS_MSG_SRC_AUDIT:
820                                 _dbus_verbose("  +%s (%llu bytes) loginuid=%llu sessionid=%llu\n",
821                                            enum_MSG(item->type), item->size,
822                                            (unsigned long long)item->data64[0],
823                                            (unsigned long long)item->data64[1]);
824                                 break;
825
826                         case KDBUS_MSG_SRC_CAPS: {
827                                 int n;
828                                 const uint32_t *cap;
829                                 int i;
830
831                                 _dbus_verbose("  +%s (%llu bytes) len=%llu bytes)\n",
832                                            enum_MSG(item->type), item->size,
833                                            (unsigned long long)item->size - KDBUS_PART_HEADER_SIZE);
834
835                                 cap = item->data32;
836                                 n = (item->size - KDBUS_PART_HEADER_SIZE) / 4 / sizeof(uint32_t);
837
838                                 _dbus_verbose("    CapInh=");
839                                 for (i = 0; i < n; i++)
840                                         _dbus_verbose("%08x", cap[(0 * n) + (n - i - 1)]);
841
842                                 _dbus_verbose(" CapPrm=");
843                                 for (i = 0; i < n; i++)
844                                         _dbus_verbose("%08x", cap[(1 * n) + (n - i - 1)]);
845
846                                 _dbus_verbose(" CapEff=");
847                                 for (i = 0; i < n; i++)
848                                         _dbus_verbose("%08x", cap[(2 * n) + (n - i - 1)]);
849
850                                 _dbus_verbose(" CapInh=");
851                                 for (i = 0; i < n; i++)
852                                         _dbus_verbose("%08x", cap[(3 * n) + (n - i - 1)]);
853                                 _dbus_verbose("\n");
854                                 break;
855                         }
856
857                         case KDBUS_MSG_TIMESTAMP:
858                                 _dbus_verbose("  +%s (%llu bytes) realtime=%lluns monotonic=%lluns\n",
859                                            enum_MSG(item->type), item->size,
860                                            (unsigned long long)item->timestamp.realtime_ns,
861                                            (unsigned long long)item->timestamp.monotonic_ns);
862                                 break;
863 #endif
864
865                         case KDBUS_MSG_REPLY_TIMEOUT:
866                                 _dbus_verbose("  +%s (%llu bytes) cookie=%llu\n",
867                                            enum_MSG(item->type), item->size, msg->cookie_reply);
868
869                                 message = generate_local_error_message(msg->cookie_reply, DBUS_ERROR_NO_REPLY, NULL);
870                                 if(message == NULL)
871                                 {
872                                         ret_size = -1;
873                                         goto out;
874                                 }
875
876                                 ret_size = put_message_into_data(message, data);
877                         break;
878
879                         case KDBUS_MSG_REPLY_DEAD:
880                                 _dbus_verbose("  +%s (%llu bytes) cookie=%llu\n",
881                                            enum_MSG(item->type), item->size, msg->cookie_reply);
882
883                                 message = generate_local_error_message(msg->cookie_reply, DBUS_ERROR_NAME_HAS_NO_OWNER, NULL);
884                                 if(message == NULL)
885                                 {
886                                         ret_size = -1;
887                                         goto out;
888                                 }
889
890                                 ret_size = put_message_into_data(message, data);
891                         break;
892
893                         case KDBUS_MSG_NAME_ADD:
894                                 _dbus_verbose("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
895                                         enum_MSG(item->type), (unsigned long long) item->size,
896                                         item->name_change.name, item->name_change.old_id,
897                                         item->name_change.new_id, item->name_change.flags);
898
899                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
900                                 if(message == NULL)
901                                 {
902                                         ret_size = -1;
903                                         goto out;
904                                 }
905
906                                 sprintf(dbus_name,":1.%llu",item->name_change.new_id);
907                                 pString = item->name_change.name;
908                                 _dbus_verbose ("Name added: %s\n", pString);
909                             dbus_message_iter_init_append(message, &args);
910                             ITER_APPEND_STR(pString)
911                             ITER_APPEND_STR(emptyString)
912                             ITER_APPEND_STR(pDBusName)
913                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
914
915                                 ret_size = put_message_into_data(message, data);
916                         break;
917
918                         case KDBUS_MSG_NAME_REMOVE:
919                                 _dbus_verbose("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
920                                         enum_MSG(item->type), (unsigned long long) item->size,
921                                         item->name_change.name, item->name_change.old_id,
922                                         item->name_change.new_id, item->name_change.flags);
923
924                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged"); // name of the signal
925                                 if(message == NULL)
926                                 {
927                                         ret_size = -1;
928                                         goto out;
929                                 }
930
931                                 sprintf(dbus_name,":1.%llu",item->name_change.old_id);
932                                 pString = item->name_change.name;
933                                 _dbus_verbose ("Name removed: %s\n", pString);
934                             dbus_message_iter_init_append(message, &args);
935                             ITER_APPEND_STR(pString)
936                             ITER_APPEND_STR(pDBusName)
937                             ITER_APPEND_STR(emptyString)
938                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
939
940                                 ret_size = put_message_into_data(message, data);
941                         break;
942
943                         case KDBUS_MSG_NAME_CHANGE:
944                                 _dbus_verbose("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
945                                         enum_MSG(item->type), (unsigned long long) item->size,
946                                         item->name_change.name, item->name_change.old_id,
947                                         item->name_change.new_id, item->name_change.flags);
948
949                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
950                                 if(message == NULL)
951                                 {
952                                         ret_size = -1;
953                                         goto out;
954                                 }
955
956                                 sprintf(dbus_name,":1.%llu",item->name_change.old_id);
957                                 pString = item->name_change.name;
958                                 _dbus_verbose ("Name changed: %s\n", pString);
959                             dbus_message_iter_init_append(message, &args);
960                             ITER_APPEND_STR(pString)
961                             ITER_APPEND_STR(pDBusName)
962                             sprintf(&dbus_name[3],"%llu",item->name_change.new_id);
963                             _dbus_verbose ("New id: %s\n", pDBusName);
964                             ITER_APPEND_STR(pDBusName)
965                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
966
967                                 ret_size = put_message_into_data(message, data);
968                         break;
969
970                         case KDBUS_MSG_ID_ADD:
971                                 _dbus_verbose("  +%s (%llu bytes) id=%llu flags=%llu\n",
972                                            enum_MSG(item->type), (unsigned long long) item->size,
973                                            (unsigned long long) item->id_change.id,
974                                            (unsigned long long) item->id_change.flags);
975
976                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
977                                 if(message == NULL)
978                                 {
979                                         ret_size = -1;
980                                         goto out;
981                                 }
982
983                                 sprintf(dbus_name,":1.%llu",item->id_change.id);
984                             dbus_message_iter_init_append(message, &args);
985                             ITER_APPEND_STR(pDBusName)
986                             ITER_APPEND_STR(emptyString)
987                             ITER_APPEND_STR(pDBusName)
988                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
989
990                                 ret_size = put_message_into_data(message, data);
991                         break;
992
993                         case KDBUS_MSG_ID_REMOVE:
994                                 _dbus_verbose("  +%s (%llu bytes) id=%llu flags=%llu\n",
995                                            enum_MSG(item->type), (unsigned long long) item->size,
996                                            (unsigned long long) item->id_change.id,
997                                            (unsigned long long) item->id_change.flags);
998
999                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
1000                                 if(message == NULL)
1001                                 {
1002                                         ret_size = -1;
1003                                         goto out;
1004                                 }
1005
1006                                 sprintf(dbus_name,":1.%llu",item->id_change.id);
1007                             dbus_message_iter_init_append(message, &args);
1008                             ITER_APPEND_STR(pDBusName)
1009                             ITER_APPEND_STR(pDBusName)
1010                             ITER_APPEND_STR(emptyString)
1011                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1012
1013                                 ret_size = put_message_into_data(message, data);
1014                         break;
1015 #if KDBUS_MSG_DECODE_DEBUG == 1
1016                         default:
1017                                 _dbus_verbose("  +%s (%llu bytes)\n", enum_MSG(item->type), item->size);
1018                         break;
1019 #endif
1020                 }
1021         }
1022
1023 #if KDBUS_MSG_DECODE_DEBUG == 1
1024
1025         if ((char *)item - ((char *)msg + msg->size) >= 8)
1026                 _dbus_verbose("invalid padding at end of message\n");
1027 #endif
1028
1029 out:
1030         if(message)
1031                 dbus_message_unref(message);
1032         return ret_size;
1033 }
1034
1035 /**
1036  * Reads message from kdbus and puts it into DBus buffers
1037  *
1038  * @param kdbus_transport transport
1039  * @param buffer place to copy received message to
1040  * @param fds place to store file descriptors received with the message
1041  * @param n_fds place to store quantity of file descriptors received
1042  * @return size of received message on success, -1 on error
1043  */
1044 static int kdbus_read_message(DBusTransportKdbus *kdbus_transport, DBusString *buffer, int* fds, int* n_fds)
1045 {
1046         int ret_size, buf_size;
1047         uint64_t __attribute__ ((__aligned__(8))) offset;
1048         struct kdbus_msg *msg;
1049         char *data;
1050         int start;
1051
1052         start = _dbus_string_get_length (buffer);
1053
1054         again:
1055         if (ioctl(kdbus_transport->fd, KDBUS_CMD_MSG_RECV, &offset) < 0)
1056         {
1057                 if(errno == EINTR)
1058                         goto again;
1059                 _dbus_verbose("kdbus error receiving message: %d (%m)\n", errno);
1060                 _dbus_string_set_length (buffer, start);
1061                 return -1;
1062         }
1063
1064         msg = (struct kdbus_msg *)((char*)kdbus_transport->kdbus_mmap_ptr + offset);
1065
1066         buf_size = kdbus_message_size(msg);
1067         if (buf_size == -1)
1068         {
1069                 _dbus_verbose("kdbus error - too short message: %d (%m)\n", errno);
1070                 return -1;
1071         }
1072
1073         /* What is the maximum size of the locally generated message?
1074            I just assume 2048 bytes */
1075         buf_size = MAX(buf_size, 2048);
1076
1077         if (!_dbus_string_lengthen (buffer, buf_size))
1078         {
1079                 errno = ENOMEM;
1080                 return -1;
1081         }
1082         data = _dbus_string_get_data_len (buffer, start, buf_size);
1083
1084         ret_size = kdbus_decode_msg(msg, data, kdbus_transport, fds, n_fds);
1085
1086         if(ret_size == -1) /* error */
1087         {
1088                 _dbus_string_set_length (buffer, start);
1089                 return -1;
1090         }
1091         else if (buf_size != ret_size) /* case of locally generated message */
1092         {
1093                 _dbus_string_set_length (buffer, start + ret_size);
1094         }
1095
1096         again2:
1097         if (ioctl(kdbus_transport->fd, KDBUS_CMD_MSG_RELEASE, &offset) < 0)
1098         {
1099                 if(errno == EINTR)
1100                         goto again2;
1101                 _dbus_verbose("kdbus error freeing message: %d (%m)\n", errno);
1102                 return -1;
1103         }
1104
1105         return ret_size;
1106 }
1107
1108 /**
1109  * Copy-paste from socket transport. Only renames done.
1110  */
1111 static void
1112 free_watches (DBusTransport *transport)
1113 {
1114   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
1115
1116   _dbus_verbose ("start\n");
1117
1118   if (kdbus_transport->read_watch)
1119     {
1120       if (transport->connection)
1121         _dbus_connection_remove_watch_unlocked (transport->connection,
1122                                                 kdbus_transport->read_watch);
1123       _dbus_watch_invalidate (kdbus_transport->read_watch);
1124       _dbus_watch_unref (kdbus_transport->read_watch);
1125       kdbus_transport->read_watch = NULL;
1126     }
1127
1128   if (kdbus_transport->write_watch)
1129     {
1130       if (transport->connection)
1131         _dbus_connection_remove_watch_unlocked (transport->connection,
1132                                                 kdbus_transport->write_watch);
1133       _dbus_watch_invalidate (kdbus_transport->write_watch);
1134       _dbus_watch_unref (kdbus_transport->write_watch);
1135       kdbus_transport->write_watch = NULL;
1136     }
1137
1138   _dbus_verbose ("end\n");
1139 }
1140
1141 /**
1142  * Copy-paste from socket transport. Only done needed renames and removed
1143  * lines related to encoded messages.
1144  */
1145 static void
1146 transport_finalize (DBusTransport *transport)
1147 {
1148   _dbus_verbose ("\n");
1149
1150   free_watches (transport);
1151
1152   _dbus_transport_finalize_base (transport);
1153
1154   _dbus_assert (((DBusTransportKdbus*) transport)->read_watch == NULL);
1155   _dbus_assert (((DBusTransportKdbus*) transport)->write_watch == NULL);
1156
1157   dbus_free (transport);
1158 }
1159
1160 /**
1161  * Copy-paste from socket transport. Removed code related to authentication,
1162  * socket_transport replaced by kdbus_transport.
1163  */
1164 static void
1165 check_write_watch (DBusTransport *transport)
1166 {
1167   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
1168   dbus_bool_t needed;
1169
1170   if (transport->connection == NULL)
1171     return;
1172
1173   if (transport->disconnected)
1174     {
1175       _dbus_assert (kdbus_transport->write_watch == NULL);
1176       return;
1177     }
1178
1179   _dbus_transport_ref (transport);
1180
1181   needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
1182
1183   _dbus_verbose ("check_write_watch(): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
1184                  needed, transport->connection, kdbus_transport->write_watch,
1185                  kdbus_transport->fd,
1186                  _dbus_connection_has_messages_to_send_unlocked (transport->connection));
1187
1188   _dbus_connection_toggle_watch_unlocked (transport->connection,
1189                                           kdbus_transport->write_watch,
1190                                           needed);
1191
1192   _dbus_transport_unref (transport);
1193 }
1194
1195 /**
1196  * Copy-paste from socket transport. Removed code related to authentication,
1197  * socket_transport replaced by kdbus_transport.
1198  */
1199 static void
1200 check_read_watch (DBusTransport *transport)
1201 {
1202   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
1203   dbus_bool_t need_read_watch;
1204
1205   _dbus_verbose ("fd = %d\n",kdbus_transport->fd);
1206
1207   if (transport->connection == NULL)
1208     return;
1209
1210   if (transport->disconnected)
1211     {
1212       _dbus_assert (kdbus_transport->read_watch == NULL);
1213       return;
1214     }
1215
1216   _dbus_transport_ref (transport);
1217
1218    need_read_watch =
1219       (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
1220       (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
1221
1222   _dbus_verbose ("  setting read watch enabled = %d\n", need_read_watch);
1223   _dbus_connection_toggle_watch_unlocked (transport->connection,
1224                                           kdbus_transport->read_watch,
1225                                           need_read_watch);
1226
1227   _dbus_transport_unref (transport);
1228 }
1229
1230 /**
1231  * Copy-paste from socket transport.
1232  */
1233 static void
1234 do_io_error (DBusTransport *transport)
1235 {
1236   _dbus_transport_ref (transport);
1237   _dbus_transport_disconnect (transport);
1238   _dbus_transport_unref (transport);
1239 }
1240
1241 /**
1242  *  Based on do_writing from socket transport.
1243  *  Removed authentication code and code related to encoded messages
1244  *  and adapted to kdbus transport.
1245  *  In socket transport returns false on out-of-memory. Here this won't happen,
1246  *  so it always returns TRUE.
1247  */
1248 static dbus_bool_t
1249 do_writing (DBusTransport *transport)
1250 {
1251   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
1252   int total = 0;
1253
1254   if (transport->disconnected)
1255     {
1256       _dbus_verbose ("Not connected, not writing anything\n");
1257       return TRUE;
1258     }
1259
1260   _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n",
1261       _dbus_connection_has_messages_to_send_unlocked (transport->connection),
1262       kdbus_transport->fd);
1263
1264   while (!transport->disconnected && _dbus_connection_has_messages_to_send_unlocked (transport->connection))
1265     {
1266       int bytes_written;
1267       DBusMessage *message;
1268       const DBusString *header;
1269       const DBusString *body;
1270       int total_bytes_to_write;
1271       const char* pDestination;
1272
1273       if (total > kdbus_transport->max_bytes_written_per_iteration)
1274         {
1275           _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
1276                          total, kdbus_transport->max_bytes_written_per_iteration);
1277           goto out;
1278         }
1279
1280       message = _dbus_connection_get_message_to_send (transport->connection);
1281       _dbus_assert (message != NULL);
1282       if(dbus_message_get_sender(message) == NULL)  //needed for daemon to pass pending activation messages
1283         {
1284           dbus_message_unlock(message);
1285           dbus_message_set_sender(message, kdbus_transport->sender);
1286           dbus_message_lock (message);
1287         }
1288       _dbus_message_get_network_data (message, &header, &body);
1289       total_bytes_to_write = _dbus_string_get_length(header) + _dbus_string_get_length(body);
1290       pDestination = dbus_message_get_destination(message);
1291
1292       if(pDestination)
1293         {
1294           if(!strcmp(pDestination, DBUS_SERVICE_DBUS))
1295             {
1296               if(!strcmp(dbus_message_get_interface(message), DBUS_INTERFACE_DBUS))
1297                 {
1298                   int ret;
1299
1300                   ret = emulateOrgFreedesktopDBus(transport, message);
1301                   if(ret < 0)
1302                     {
1303                       bytes_written = -1;
1304                       goto written;
1305                     }
1306                   else if(ret == 0)
1307                     {
1308                       bytes_written = total_bytes_to_write;
1309                       goto written;
1310                     }
1311                   //else send to "daemon" as to normal recipient
1312                 }
1313             }
1314         }
1315
1316       bytes_written = kdbus_write_msg(kdbus_transport, message, pDestination);
1317
1318       written:
1319       if (bytes_written < 0)
1320         {
1321           /* EINTR already handled for us */
1322
1323           /* For some discussion of why we also ignore EPIPE here, see
1324            * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html
1325            */
1326
1327           if (_dbus_get_is_errno_eagain_or_ewouldblock () || _dbus_get_is_errno_epipe ())
1328             goto out;
1329           else
1330             {
1331               _dbus_verbose ("Error writing to remote app: %s\n", _dbus_strerror_from_errno ());
1332               do_io_error (transport);
1333               goto out;
1334             }
1335         }
1336       else
1337         {
1338           _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
1339               total_bytes_to_write);
1340
1341           total += bytes_written;
1342
1343           _dbus_assert (bytes_written == total_bytes_to_write);
1344
1345           _dbus_connection_message_sent_unlocked (transport->connection,
1346                   message);
1347         }
1348     }
1349
1350   out:
1351   return TRUE;
1352 }
1353
1354 /**
1355  *  Based on do_reading from socket transport.
1356  *  Removed authentication code and code related to encoded messages
1357  *  and adapted to kdbus transport.
1358  *  returns false on out-of-memory
1359  */
1360 static dbus_bool_t
1361 do_reading (DBusTransport *transport)
1362 {
1363   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
1364   DBusString *buffer;
1365   int bytes_read;
1366   dbus_bool_t oom = FALSE;
1367   int *fds, n_fds;
1368   int total = 0;
1369
1370   _dbus_verbose ("fd = %d\n",kdbus_transport->fd);
1371
1372  again:
1373
1374   /* See if we've exceeded max messages and need to disable reading */
1375   check_read_watch (transport);
1376
1377   if (total > kdbus_transport->max_bytes_read_per_iteration)
1378     {
1379       _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
1380                      total, kdbus_transport->max_bytes_read_per_iteration);
1381       goto out;
1382     }
1383
1384   _dbus_assert (kdbus_transport->read_watch != NULL ||
1385                 transport->disconnected);
1386
1387   if (transport->disconnected)
1388     goto out;
1389
1390   if (!dbus_watch_get_enabled (kdbus_transport->read_watch))
1391     return TRUE;
1392
1393   if (!_dbus_message_loader_get_unix_fds(transport->loader, &fds, &n_fds))
1394   {
1395       _dbus_verbose ("Out of memory reading file descriptors\n");
1396       oom = TRUE;
1397       goto out;
1398   }
1399   _dbus_message_loader_get_buffer (transport->loader, &buffer);
1400
1401   bytes_read = kdbus_read_message(kdbus_transport, buffer, fds, &n_fds);
1402
1403   if (bytes_read >= 0 && n_fds > 0)
1404     _dbus_verbose("Read %i unix fds\n", n_fds);
1405
1406   _dbus_message_loader_return_buffer (transport->loader,
1407                                       buffer,
1408                                       bytes_read < 0 ? 0 : bytes_read);
1409   _dbus_message_loader_return_unix_fds(transport->loader, fds, bytes_read < 0 ? 0 : n_fds);
1410
1411   if (bytes_read < 0)
1412     {
1413       /* EINTR already handled for us */
1414
1415       if (_dbus_get_is_errno_enomem ())
1416         {
1417           _dbus_verbose ("Out of memory in read()/do_reading()\n");
1418           oom = TRUE;
1419           goto out;
1420         }
1421       else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
1422         goto out;
1423       else
1424         {
1425           _dbus_verbose ("Error reading from remote app: %s\n",
1426                          _dbus_strerror_from_errno ());
1427           do_io_error (transport);
1428           goto out;
1429         }
1430     }
1431   else if (bytes_read == 0)
1432     {
1433       _dbus_verbose ("Disconnected from remote app\n");
1434       do_io_error (transport);
1435       goto out;
1436     }
1437   else
1438     {
1439       _dbus_verbose (" read %d bytes\n", bytes_read);
1440
1441       total += bytes_read;
1442
1443       if (!_dbus_transport_queue_messages (transport))
1444         {
1445           oom = TRUE;
1446           _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
1447           goto out;
1448         }
1449
1450       /* Try reading more data until we get EAGAIN and return, or
1451        * exceed max bytes per iteration.  If in blocking mode of
1452        * course we'll block instead of returning.
1453        */
1454       goto again;
1455     }
1456
1457  out:
1458   if (oom)
1459     return FALSE;
1460   return TRUE;
1461 }
1462
1463 /**
1464  * Copy-paste from socket transport, with socket replaced by kdbus.
1465  */
1466 static dbus_bool_t
1467 unix_error_with_read_to_come (DBusTransport *itransport,
1468                               DBusWatch     *watch,
1469                               unsigned int   flags)
1470 {
1471    DBusTransportKdbus *transport = (DBusTransportKdbus *) itransport;
1472
1473    if (!((flags & DBUS_WATCH_HANGUP) || (flags & DBUS_WATCH_ERROR)))
1474       return FALSE;
1475
1476   /* If we have a read watch enabled ...
1477      we -might have data incoming ... => handle the HANGUP there */
1478    if (watch != transport->read_watch && _dbus_watch_get_enabled (transport->read_watch))
1479       return FALSE;
1480
1481    return TRUE;
1482 }
1483
1484 /**
1485  *  Copy-paste from socket transport. Removed authentication related code
1486  *  and renamed socket_transport to kdbus_transport.
1487  */
1488 static dbus_bool_t
1489 kdbus_handle_watch (DBusTransport *transport,
1490                    DBusWatch     *watch,
1491                    unsigned int   flags)
1492 {
1493   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
1494
1495   _dbus_assert (watch == kdbus_transport->read_watch ||
1496                 watch == kdbus_transport->write_watch);
1497   _dbus_assert (watch != NULL);
1498
1499   /* If we hit an error here on a write watch, don't disconnect the transport yet because data can
1500    * still be in the buffer and do_reading may need several iteration to read
1501    * it all (because of its max_bytes_read_per_iteration limit).
1502    */
1503   if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags))
1504     {
1505       _dbus_verbose ("Hang up or error on watch\n");
1506       _dbus_transport_disconnect (transport);
1507       return TRUE;
1508     }
1509
1510   if (watch == kdbus_transport->read_watch &&
1511       (flags & DBUS_WATCH_READABLE))
1512     {
1513       _dbus_verbose ("handling read watch %p flags = %x\n",
1514                      watch, flags);
1515
1516           if (!do_reading (transport))
1517             {
1518               _dbus_verbose ("no memory to read\n");
1519               return FALSE;
1520             }
1521
1522     }
1523   else if (watch == kdbus_transport->write_watch &&
1524            (flags & DBUS_WATCH_WRITABLE))
1525     {
1526       _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
1527                      _dbus_connection_has_messages_to_send_unlocked (transport->connection));
1528
1529       if (!do_writing (transport))
1530         {
1531           _dbus_verbose ("no memory to write\n");
1532           return FALSE;
1533         }
1534
1535       /* See if we still need the write watch */
1536       check_write_watch (transport);
1537     }
1538
1539   return TRUE;
1540 }
1541
1542 /**
1543  * Copy-paste from socket transport renamed to kdbus_transport.
1544  */
1545 static void
1546 kdbus_disconnect (DBusTransport *transport)
1547 {
1548   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
1549
1550   _dbus_verbose ("\n");
1551
1552   free_watches (transport);
1553
1554   _dbus_close_socket (kdbus_transport->fd, NULL);
1555   kdbus_transport->fd = -1;
1556 }
1557
1558 /**
1559  *  Copy-paste from socket transport. Renamed socket_transport to
1560  *  kdbus_transport and added dbus_connection_set_is_authenticated, because
1561  *  we do not perform authentication in kdbus, so we have mark is as already done
1562  *  to make everything work.
1563  */
1564 static dbus_bool_t
1565 kdbus_connection_set (DBusTransport *transport)
1566 {
1567   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
1568
1569   dbus_connection_set_is_authenticated(transport->connection); //now we don't have authentication in kdbus, so mark it done
1570
1571   _dbus_watch_set_handler (kdbus_transport->write_watch,
1572                            _dbus_connection_handle_watch,
1573                            transport->connection, NULL);
1574
1575   _dbus_watch_set_handler (kdbus_transport->read_watch,
1576                            _dbus_connection_handle_watch,
1577                            transport->connection, NULL);
1578
1579   if (!_dbus_connection_add_watch_unlocked (transport->connection,
1580                                             kdbus_transport->write_watch))
1581     return FALSE;
1582
1583   if (!_dbus_connection_add_watch_unlocked (transport->connection,
1584                                             kdbus_transport->read_watch))
1585     {
1586       _dbus_connection_remove_watch_unlocked (transport->connection,
1587                                               kdbus_transport->write_watch);
1588       return FALSE;
1589     }
1590
1591   check_read_watch (transport);
1592   check_write_watch (transport);
1593
1594   return TRUE;
1595 }
1596
1597 /**
1598  *  Copy-paste from socket_transport.
1599  *  Socket_transport renamed to kdbus_transport
1600  *
1601  *   Original dbus copy-pasted @todo comment below.
1602  * @todo We need to have a way to wake up the select sleep if
1603  * a new iteration request comes in with a flag (read/write) that
1604  * we're not currently serving. Otherwise a call that just reads
1605  * could block a write call forever (if there are no incoming
1606  * messages).
1607  */
1608 static  void
1609 kdbus_do_iteration (DBusTransport *transport,
1610                    unsigned int   flags,
1611                    int            timeout_milliseconds)
1612 {
1613         DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
1614         DBusPollFD poll_fd;
1615         int poll_res;
1616         int poll_timeout;
1617
1618         _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
1619                  flags & DBUS_ITERATION_DO_READING ? "read" : "",
1620                  flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
1621                  timeout_milliseconds,
1622                  kdbus_transport->read_watch,
1623                  kdbus_transport->write_watch,
1624                  kdbus_transport->fd);
1625
1626   /* the passed in DO_READING/DO_WRITING flags indicate whether to
1627    * read/write messages, but regardless of those we may need to block
1628    * for reading/writing to do auth.  But if we do reading for auth,
1629    * we don't want to read any messages yet if not given DO_READING.
1630    */
1631
1632    poll_fd.fd = kdbus_transport->fd;
1633    poll_fd.events = 0;
1634
1635    if (_dbus_transport_try_to_authenticate (transport))
1636    {
1637       /* This is kind of a hack; if we have stuff to write, then try
1638        * to avoid the poll. This is probably about a 5% speedup on an
1639        * echo client/server.
1640        *
1641        * If both reading and writing were requested, we want to avoid this
1642        * since it could have funky effects:
1643        *   - both ends spinning waiting for the other one to read
1644        *     data so they can finish writing
1645        *   - prioritizing all writing ahead of reading
1646        */
1647       if ((flags & DBUS_ITERATION_DO_WRITING) &&
1648           !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
1649           !transport->disconnected &&
1650           _dbus_connection_has_messages_to_send_unlocked (transport->connection))
1651       {
1652          do_writing (transport);
1653
1654          if (transport->disconnected ||
1655               !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
1656             goto out;
1657       }
1658
1659       /* If we get here, we decided to do the poll() after all */
1660       _dbus_assert (kdbus_transport->read_watch);
1661       if (flags & DBUS_ITERATION_DO_READING)
1662              poll_fd.events |= _DBUS_POLLIN;
1663
1664       _dbus_assert (kdbus_transport->write_watch);
1665       if (flags & DBUS_ITERATION_DO_WRITING)
1666          poll_fd.events |= _DBUS_POLLOUT;
1667    }
1668    else
1669    {
1670       DBusAuthState auth_state;
1671
1672       auth_state = _dbus_auth_do_work (transport->auth);
1673
1674       if (transport->receive_credentials_pending || auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
1675              poll_fd.events |= _DBUS_POLLIN;
1676
1677       if (transport->send_credentials_pending || auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
1678              poll_fd.events |= _DBUS_POLLOUT;
1679    }
1680
1681    if (poll_fd.events)
1682    {
1683       if (flags & DBUS_ITERATION_BLOCK)
1684              poll_timeout = timeout_milliseconds;
1685       else
1686              poll_timeout = 0;
1687
1688       /* For blocking selects we drop the connection lock here
1689        * to avoid blocking out connection access during a potentially
1690        * indefinite blocking call. The io path is still protected
1691        * by the io_path_cond condvar, so we won't reenter this.
1692        */
1693       if (flags & DBUS_ITERATION_BLOCK)
1694       {
1695          _dbus_verbose ("unlock pre poll\n");
1696          _dbus_connection_unlock (transport->connection);
1697       }
1698
1699     again:
1700       poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
1701
1702       if (poll_res < 0 && _dbus_get_is_errno_eintr ())
1703       {
1704          _dbus_verbose ("Error from _dbus_poll(): %s\n", _dbus_strerror_from_errno ());
1705          goto again;
1706       }
1707
1708       if (flags & DBUS_ITERATION_BLOCK)
1709       {
1710          _dbus_verbose ("lock post poll\n");
1711          _dbus_connection_lock (transport->connection);
1712       }
1713
1714       if (poll_res >= 0)
1715       {
1716          if (poll_res == 0)
1717             poll_fd.revents = 0; /* some concern that posix does not guarantee this;
1718                                   * valgrind flags it as an error. though it probably
1719                                   * is guaranteed on linux at least.
1720                                   */
1721
1722          if (poll_fd.revents & _DBUS_POLLERR)
1723             do_io_error (transport);
1724          else
1725          {
1726             dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
1727             dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
1728
1729             _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
1730                              need_read, need_write);
1731
1732             if (need_read && (flags & DBUS_ITERATION_DO_READING))
1733                do_reading (transport);
1734             if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
1735                do_writing (transport);
1736          }
1737       }
1738       else
1739          _dbus_verbose ("Error from _dbus_poll(): %s\n", _dbus_strerror_from_errno ());
1740    }
1741
1742  out:
1743   /* We need to install the write watch only if we did not
1744    * successfully write everything. Note we need to be careful that we
1745    * don't call check_write_watch *before* do_writing, since it's
1746    * inefficient to add the write watch, and we can avoid it most of
1747    * the time since we can write immediately.
1748    *
1749    * However, we MUST always call check_write_watch(); DBusConnection code
1750    * relies on the fact that running an iteration will notice that
1751    * messages are pending.
1752    */
1753    check_write_watch (transport);
1754
1755    _dbus_verbose (" ... leaving do_iteration()\n");
1756 }
1757
1758 /**
1759  * Copy-paste from socket transport.
1760  */
1761 static void
1762 kdbus_live_messages_changed (DBusTransport *transport)
1763 {
1764   /* See if we should look for incoming messages again */
1765   check_read_watch (transport);
1766 }
1767
1768 /**
1769  * Gets file descriptor of the kdbus bus.
1770  * @param transport transport
1771  * @param fd_p place to write fd to
1772  * @returns always TRUE
1773  */
1774 static dbus_bool_t
1775 kdbus_get_kdbus_fd (DBusTransport *transport,
1776                       int           *fd_p)
1777 {
1778   DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
1779
1780   *fd_p = kdbus_transport->fd;
1781
1782   return TRUE;
1783 }
1784
1785 static const DBusTransportVTable kdbus_vtable = {
1786   transport_finalize,
1787   kdbus_handle_watch,
1788   kdbus_disconnect,
1789   kdbus_connection_set,
1790   kdbus_do_iteration,
1791   kdbus_live_messages_changed,
1792   kdbus_get_kdbus_fd
1793 };
1794
1795 /**
1796  * Copy-paste from dbus_transport_socket with needed changes.
1797  *
1798  * Creates a new transport for the given kdbus file descriptor and address.
1799  * The file descriptor must be nonblocking.
1800  *
1801  * @param fd the file descriptor.
1802  * @param address the transport's address
1803  * @returns the new transport, or #NULL if no memory.
1804  */
1805 static DBusTransport*
1806 _dbus_transport_new_kdbus_transport (int fd, const DBusString *address)
1807 {
1808         DBusTransportKdbus *kdbus_transport;
1809
1810   kdbus_transport = dbus_new0 (DBusTransportKdbus, 1);
1811   if (kdbus_transport == NULL)
1812     return NULL;
1813
1814   kdbus_transport->write_watch = _dbus_watch_new (fd,
1815                                                  DBUS_WATCH_WRITABLE,
1816                                                  FALSE,
1817                                                  NULL, NULL, NULL);
1818   if (kdbus_transport->write_watch == NULL)
1819     goto failed_2;
1820
1821   kdbus_transport->read_watch = _dbus_watch_new (fd,
1822                                                 DBUS_WATCH_READABLE,
1823                                                 FALSE,
1824                                                 NULL, NULL, NULL);
1825   if (kdbus_transport->read_watch == NULL)
1826     goto failed_3;
1827
1828   if (!_dbus_transport_init_base (&kdbus_transport->base,
1829                                   &kdbus_vtable,
1830                                   NULL, address))
1831     goto failed_4;
1832
1833   kdbus_transport->fd = fd;
1834
1835   /* These values should probably be tunable or something. */
1836   kdbus_transport->max_bytes_read_per_iteration = 16384;
1837   kdbus_transport->max_bytes_written_per_iteration = 16384;
1838
1839   kdbus_transport->kdbus_mmap_ptr = NULL;
1840   kdbus_transport->memfd = -1;
1841   
1842   return (DBusTransport*) kdbus_transport;
1843
1844  failed_4:
1845   _dbus_watch_invalidate (kdbus_transport->read_watch);
1846   _dbus_watch_unref (kdbus_transport->read_watch);
1847  failed_3:
1848   _dbus_watch_invalidate (kdbus_transport->write_watch);
1849   _dbus_watch_unref (kdbus_transport->write_watch);
1850  failed_2:
1851   dbus_free (kdbus_transport);
1852   return NULL;
1853 }
1854
1855 /**
1856  * Opens a connection to the kdbus bus
1857  *
1858  * @param path the path to kdbus bus
1859  * @param error return location for error code
1860  * @returns connection file descriptor or -1 on error
1861  */
1862 static int _dbus_connect_kdbus (const char *path, DBusError *error)
1863 {
1864         int fd;
1865
1866         _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1867         _dbus_verbose ("connecting to kdbus bus %s\n", path);
1868
1869         fd = open(path, O_RDWR|O_CLOEXEC|O_NONBLOCK);
1870         if (fd < 0)
1871                 dbus_set_error(error, _dbus_error_from_errno (errno), "Failed to open file descriptor: %s", _dbus_strerror (errno));
1872
1873         return fd;
1874 }
1875
1876 /**
1877  * Connects to kdbus, creates and sets-up transport.
1878  *
1879  * @param path the path to the bus.
1880  * @param error address where an error can be returned.
1881  * @returns a new transport, or #NULL on failure.
1882  */
1883 static DBusTransport* _dbus_transport_new_for_kdbus (const char *path, DBusError *error)
1884 {
1885         int fd;
1886         DBusTransport *transport;
1887         DBusString address;
1888
1889         _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1890
1891         if (!_dbus_string_init (&address))
1892     {
1893                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1894                 return NULL;
1895     }
1896
1897         fd = -1;
1898
1899         if ((!_dbus_string_append (&address, "kdbus:path=")) || (!_dbus_string_append (&address, path)))
1900     {
1901                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1902                 goto failed_0;
1903     }
1904
1905         fd = _dbus_connect_kdbus (path, error);
1906         if (fd < 0)
1907     {
1908                 _DBUS_ASSERT_ERROR_IS_SET (error);
1909                 goto failed_0;
1910     }
1911
1912         _dbus_verbose ("Successfully connected to kdbus bus %s\n", path);
1913
1914         transport = _dbus_transport_new_kdbus_transport (fd, &address);
1915         if (transport == NULL)
1916     {
1917                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1918                 goto failed_1;
1919     }
1920
1921         _dbus_string_free (&address);
1922
1923         return transport;
1924
1925         failed_1:
1926                 _dbus_close_socket (fd, NULL);
1927         failed_0:
1928                 _dbus_string_free (&address);
1929         return NULL;
1930 }
1931
1932
1933 /**
1934  * Opens kdbus transport if method from address entry is kdbus
1935  *
1936  * @param entry the address entry to open
1937  * @param transport_p return location for the opened transport
1938  * @param error place to store error
1939  * @returns result of the attempt as a DBusTransportOpenResult enum
1940  */
1941 DBusTransportOpenResult _dbus_transport_open_kdbus(DBusAddressEntry  *entry,
1942                                                            DBusTransport    **transport_p,
1943                                                            DBusError         *error)
1944 {
1945         const char *method;
1946
1947         method = dbus_address_entry_get_method (entry);
1948         _dbus_assert (method != NULL);
1949
1950         if (strcmp (method, "kdbus") == 0)
1951     {
1952                 const char *path = dbus_address_entry_get_value (entry, "path");
1953
1954                 if (path == NULL)
1955         {
1956                         _dbus_set_bad_address (error, "kdbus", "path", NULL);
1957                         return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
1958         }
1959
1960         *transport_p = _dbus_transport_new_for_kdbus (path, error);
1961
1962         if (*transport_p == NULL)
1963         {
1964                 _DBUS_ASSERT_ERROR_IS_SET (error);
1965                 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
1966         }
1967         else
1968         {
1969                 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1970                 return DBUS_TRANSPORT_OPEN_OK;
1971         }
1972     }
1973         else
1974     {
1975                 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1976                 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
1977     }
1978 }