The proc.c code sets up some socketpair for the communication between
authorreyk <reyk@openbsd.org>
Fri, 18 Apr 2014 12:02:37 +0000 (12:02 +0000)
committerreyk <reyk@openbsd.org>
Fri, 18 Apr 2014 12:02:37 +0000 (12:02 +0000)
different privsep processes.  The implementation is using
multi-dimensional arrays and and some complicated process to process
relations.  This is the first attempt of cleaning it up and to allow
N:N communications for the upcoming "CA" processes.

Discussed with some, but nobody dared to comment on the code.

usr.sbin/relayd/proc.c
usr.sbin/relayd/relayd.h

index a5dad66..77ab3ec 100644 (file)
@@ -1,7 +1,7 @@
-/*     $OpenBSD: proc.c,v 1.8 2014/04/14 07:18:05 blambert Exp $       */
+/*     $OpenBSD: proc.c,v 1.9 2014/04/18 12:02:37 reyk Exp $   */
 
 /*
- * Copyright (c) 2010,2011 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2010 - 2014 Reyk Floeter <reyk@openbsd.org>
  * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -48,6 +48,7 @@ int    proc_ispeer(struct privsep_proc *, u_int, enum privsep_procid);
 void    proc_shutdown(struct privsep_proc *);
 void    proc_sig_handler(int, short, void *);
 void    proc_range(struct privsep *, enum privsep_procid, int *, int *);
+u_int   proc_instances(struct privsep *, u_int, u_int);
 
 int
 proc_ispeer(struct privsep_proc *p, u_int nproc, enum privsep_procid type)
@@ -116,19 +117,9 @@ proc_setup(struct privsep *ps)
 
        for (i = 0; i < PROC_MAX; i++)
                for (j = 0; j < PROC_MAX; j++) {
-                       /*
-                        * find out how many instances of this peer there are.
-                        */
-                       if (i >= j || ps->ps_instances[i] == 0 ||
-                           ps->ps_instances[j] == 0)
+                       if ((count = proc_instances(ps, i, j)) == 0)
                                continue;
 
-                       if (ps->ps_instances[i] > 1 &&
-                           ps->ps_instances[j] > 1)
-                               fatalx("N:M peering not supported");
-
-                       count = ps->ps_instances[i] * ps->ps_instances[j];
-
                        if ((ps->ps_pipes[i][j] =
                            calloc(count, sizeof(int))) == NULL ||
                            (ps->ps_pipes[j][i] =
@@ -165,13 +156,9 @@ proc_config(struct privsep *ps, struct privsep_proc *p, u_int nproc)
         */
        for (i = 0; i < PROC_MAX; i++) {
                for (j = 0; j < PROC_MAX; j++) {
-                       if (i == j ||
-                           ps->ps_instances[i] == 0 ||
-                           ps->ps_instances[j] == 0)
+                       if ((count = proc_instances(ps, i, j)) == 0)
                                continue;
 
-                       count = ps->ps_instances[i] * ps->ps_instances[j];
-
                        for (n = 0; n < count; n++) {
                                instance = ps->ps_instances[i] > 1 ? n : 0;
                                if (i == src &&
@@ -197,7 +184,8 @@ proc_config(struct privsep *ps, struct privsep_proc *p, u_int nproc)
                if (src == dst)
                        fatal("proc_config: cannot peer with oneself");
 
-               count = ps->ps_instances[src] * ps->ps_instances[dst];
+               if ((count = proc_instances(ps, src, dst)) == 0)
+                       continue;
 
                if ((ps->ps_ievs[dst] = calloc(count,
                    sizeof(struct imsgev))) == NULL)
@@ -234,11 +222,10 @@ proc_clear(struct privsep *ps, int purge)
                return;
 
        for (dst = 0; dst < PROC_MAX; dst++) {
-               if (src == dst || ps->ps_ievs[dst] == NULL)
+               if ((count = proc_instances(ps, src, dst)) == 0 ||
+                   ps->ps_ievs[dst] == NULL)
                        continue;
 
-               count = ps->ps_instances[src] * ps->ps_instances[dst];
-
                for (n = 0; n < count; n++) {
                        if (ps->ps_pipes[src][dst][n] == -1)
                                continue;
@@ -254,6 +241,26 @@ proc_clear(struct privsep *ps, int purge)
        }
 }
 
+u_int
+proc_instances(struct privsep *ps, u_int src, u_int dst)
+{
+       u_int    count;
+
+       if (ps->ps_instances[src] > 1 &&
+           ps->ps_instances[dst] > 1 &&
+           ps->ps_instances[src] != ps->ps_instances[dst])
+               fatalx("N:M peering not supported");
+
+       if (src == dst ||
+           ps->ps_instances[src] == 0 ||
+           ps->ps_instances[dst] == 0)
+               return (0);
+
+       count = MAX(ps->ps_instances[src], ps->ps_instances[dst]);
+
+       return (count);
+}
+
 void
 proc_shutdown(struct privsep_proc *p)
 {
@@ -597,3 +604,12 @@ proc_ibuf(struct privsep *ps, enum privsep_procid id, int n)
        proc_range(ps, id, &n, &m);
        return (&ps->ps_ievs[id][n].ibuf);
 }
+
+struct imsgev *
+proc_iev(struct privsep *ps, enum privsep_procid id, int n)
+{
+       int      m;
+
+       proc_range(ps, id, &n, &m);
+       return (&ps->ps_ievs[id][n]);
+}
index e95cf3a..ddc120b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: relayd.h,v 1.173 2014/04/14 12:58:04 blambert Exp $   */
+/*     $OpenBSD: relayd.h,v 1.174 2014/04/18 12:02:37 reyk Exp $       */
 
 /*
  * Copyright (c) 2006 - 2012 Reyk Floeter <reyk@openbsd.org>
@@ -1170,6 +1170,8 @@ int        proc_forward_imsg(struct privsep *, struct imsg *,
            enum privsep_procid, int);
 struct imsgbuf *
         proc_ibuf(struct privsep *, enum privsep_procid, int);
+struct imsgev *
+        proc_iev(struct privsep *, enum privsep_procid, int);
 void    imsg_event_add(struct imsgev *);
 int     imsg_compose_event(struct imsgev *, u_int16_t, u_int32_t,
            pid_t, int, void *, u_int16_t);