chiark / gitweb /
bus-proxy: complain only once about queue overflows
[elogind.git] / src / bus-proxyd / proxy.c
index a07c4036dfdb944eeedae5db5d0c6f11a1c3879c..c6896188533b1cdca258a62e4c7d9267385a073e 100644 (file)
 ***/
 
 #include <sys/socket.h>
-#include <sys/un.h>
 #include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
 #include <string.h>
 #include <errno.h>
 #include <poll.h>
-#include <stddef.h>
-#include <getopt.h>
 
 #include "log.h"
 #include "util.h"
-#include "socket-util.h"
 #include "sd-daemon.h"
 #include "sd-bus.h"
 #include "bus-internal.h"
 #include "bus-message.h"
 #include "bus-util.h"
-#include "build.h"
 #include "strv.h"
-#include "def.h"
-#include "capability.h"
 #include "bus-control.h"
-#include "smack-util.h"
 #include "set.h"
 #include "bus-xml-policy.h"
 #include "driver.h"
@@ -81,14 +71,14 @@ static int proxy_create_destination(Proxy *p, const char *destination, const cha
                 b->fake_pids.pid = p->local_creds.pid;
                 b->fake_pids_valid = true;
 
-                b->fake_creds.uid = p->local_creds.uid;
+                b->fake_creds.uid = UID_INVALID;
                 b->fake_creds.euid = p->local_creds.uid;
-                b->fake_creds.suid = p->local_creds.uid;
-                b->fake_creds.fsuid = p->local_creds.uid;
-                b->fake_creds.gid = p->local_creds.gid;
+                b->fake_creds.suid = UID_INVALID;
+                b->fake_creds.fsuid = UID_INVALID;
+                b->fake_creds.gid = GID_INVALID;
                 b->fake_creds.egid = p->local_creds.gid;
-                b->fake_creds.sgid = p->local_creds.gid;
-                b->fake_creds.fsgid = p->local_creds.gid;
+                b->fake_creds.sgid = GID_INVALID;
+                b->fake_creds.fsgid = GID_INVALID;
                 b->fake_creds_valid = true;
         }
 
@@ -376,7 +366,7 @@ static int proxy_wait(Proxy *p) {
         }
 
         pollfd = (struct pollfd[3]) {
-                { .fd = fd,           .events = events_destination,            },
+                { .fd = fd,           .events = events_destination,     },
                 { .fd = p->local_in,  .events = events_local & POLLIN,  },
                 { .fd = p->local_out, .events = events_local & POLLOUT, },
         };
@@ -673,7 +663,7 @@ static int proxy_process_destination_to_local(Proxy *p) {
         assert(p);
 
         r = sd_bus_process(p->destination_bus, &m);
-        if (r == -ECONNRESET) /* Treat 'connection reset by peer' as clean exit condition */
+        if (r == -ECONNRESET || r == -ENOTCONN) /* Treat 'connection reset by peer' as clean exit condition */
                 return r;
         if (r < 0) {
                 log_error_errno(r, "Failed to process destination bus: %m");
@@ -689,6 +679,8 @@ static int proxy_process_destination_to_local(Proxy *p) {
                 return -ECONNRESET;
 
         r = synthesize_name_acquired(p->destination_bus, p->local_bus, m);
+        if (r == -ECONNRESET || r == -ENOTCONN)
+                return r;
         if (r < 0)
                 return log_error_errno(r, "Failed to synthesize message: %m");
 
@@ -696,6 +688,8 @@ static int proxy_process_destination_to_local(Proxy *p) {
 
         if (p->policy) {
                 r = process_policy(p->destination_bus, p->local_bus, m, p->policy, &p->local_creds, p->owned_names);
+                if (r == -ECONNRESET || r == -ENOTCONN)
+                        return r;
                 if (r < 0)
                         return log_error_errno(r, "Failed to process policy: %m");
                 if (r > 0)
@@ -704,7 +698,7 @@ static int proxy_process_destination_to_local(Proxy *p) {
 
         r = sd_bus_send(p->local_bus, m, NULL);
         if (r < 0) {
-                if (r == -ECONNRESET)
+                if (r == -ECONNRESET || r == -ENOTCONN)
                         return r;
 
                 /* If the peer tries to send a reply and it is
@@ -725,10 +719,21 @@ static int proxy_process_destination_to_local(Proxy *p) {
 
                 /* Return the error to the client, if we can */
                 synthetic_reply_method_errnof(m, r, "Failed to forward message we got from destination: %m");
-                log_error_errno(r, "Failed to send message to client, ignoring: %m");
+                if (r == -ENOBUFS) {
+                        /* if local dbus1 peer does not dispatch its queue, warn only once */
+                        if (!p->queue_overflow)
+                                log_error("Dropped messages due to queue overflow of local peer (pid: "PID_FMT" uid: "UID_FMT")", p->local_creds.pid, p->local_creds.uid);
+                        p->queue_overflow = true;
+                } else
+                        log_error_errno(r,
+                                 "Failed to forward message we got from destination: uid=" UID_FMT " gid=" GID_FMT" message=%s destination=%s path=%s interface=%s member=%s: %m",
+                                 p->local_creds.uid, p->local_creds.gid, bus_message_type_to_string(m->header->type),
+                                 strna(m->destination), strna(m->path), strna(m->interface), strna(m->member));
+
                 return 1;
         }
 
+        p->queue_overflow = false;
         return 1;
 }
 
@@ -739,7 +744,7 @@ static int proxy_process_local_to_destination(Proxy *p) {
         assert(p);
 
         r = sd_bus_process(p->local_bus, &m);
-        if (r == -ECONNRESET) /* Treat 'connection reset by peer' as clean exit condition */
+        if (r == -ECONNRESET || r == -ENOTCONN) /* Treat 'connection reset by peer' as clean exit condition */
                 return r;
         if (r < 0) {
                 log_error_errno(r, "Failed to process local bus: %m");
@@ -755,12 +760,16 @@ static int proxy_process_local_to_destination(Proxy *p) {
                 return -ECONNRESET;
 
         r = process_hello(p, m);
+        if (r == -ECONNRESET || r == -ENOTCONN)
+                return r;
         if (r < 0)
                 return log_error_errno(r, "Failed to process HELLO: %m");
         if (r > 0)
                 return 1;
 
         r = bus_proxy_process_driver(p->destination_bus, p->local_bus, m, p->policy, &p->local_creds, p->owned_names);
+        if (r == -ECONNRESET || r == -ENOTCONN)
+                return r;
         if (r < 0)
                 return log_error_errno(r, "Failed to process driver calls: %m");
         if (r > 0)
@@ -769,15 +778,17 @@ static int proxy_process_local_to_destination(Proxy *p) {
         for (;;) {
                 if (p->policy) {
                         r = process_policy(p->local_bus, p->destination_bus, m, p->policy, &p->local_creds, p->owned_names);
+                        if (r == -ECONNRESET || r == -ENOTCONN)
+                                return r;
                         if (r < 0)
                                 return log_error_errno(r, "Failed to process policy: %m");
-                        else if (r > 0)
+                        if (r > 0)
                                 return 1;
                 }
 
                 r = sd_bus_send(p->destination_bus, m, NULL);
                 if (r < 0) {
-                        if (r == -ECONNRESET)
+                        if (r == -ECONNRESET || r == -ENOTCONN)
                                 return r;
 
                         /* The name database changed since the policy check, hence let's check again */
@@ -789,7 +800,10 @@ static int proxy_process_local_to_destination(Proxy *p) {
                                 return 1;
 
                         synthetic_reply_method_errnof(m, r, "Failed to forward message we got from local: %m");
-                        log_error_errno(r, "Failed to send message to bus: %m");
+                        log_error_errno(r,
+                                 "Failed to forward message we got from local: uid=" UID_FMT " gid=" GID_FMT" message=%s destination=%s path=%s interface=%s member=%s: %m",
+                                 p->local_creds.uid, p->local_creds.gid, bus_message_type_to_string(m->header->type),
+                                 strna(m->destination), strna(m->path), strna(m->interface), strna(m->member));
                         return 1;
                 }
 
@@ -810,7 +824,7 @@ int proxy_run(Proxy *p) {
                 if (p->got_hello) {
                         /* Read messages from bus, to pass them on to our client */
                         r = proxy_process_destination_to_local(p);
-                        if (r == -ECONNRESET)
+                        if (r == -ECONNRESET || r == -ENOTCONN)
                                 return 0;
                         if (r < 0)
                                 return r;
@@ -820,7 +834,7 @@ int proxy_run(Proxy *p) {
 
                 /* Read messages from our client, to pass them on to the bus */
                 r = proxy_process_local_to_destination(p);
-                if (r == -ECONNRESET)
+                if (r == -ECONNRESET || r == -ENOTCONN)
                         return 0;
                 if (r < 0)
                         return r;
@@ -829,6 +843,8 @@ int proxy_run(Proxy *p) {
 
                 if (!busy) {
                         r = proxy_wait(p);
+                        if (r == -ECONNRESET || r == -ENOTCONN)
+                                return 0;
                         if (r < 0)
                                 return r;
                 }