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