chiark / gitweb /
polypath: change return type of ifname_wanted, to char
[secnet.git] / polypath.c
index 48d06a1308ef3924771285163c45922678a3c666..ac6a18b7e95d5972a6cdabbe45509df741edcaf4 100644 (file)
@@ -1,6 +1,24 @@
 /* polypath
  * send/receive module for secnet
  * for multi-route setups */
+/*
+ * This file is part of secnet.
+ * See README for full list of copyright holders.
+ *
+ * secnet is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version d of the License, or
+ * (at your option) any later version.
+ * 
+ * secnet is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * version 3 along with secnet; if not, see
+ * https://www.gnu.org/licenses/gpl.html.
+ */
 
 #include "secnet.h"
 #include "util.h"
@@ -65,7 +83,7 @@ static const char *polypath_addr_to_string(void *commst,
 }
 
 static bool_t ifname_search_pats(struct polypath *st, struct cloc loc,
-                                const char *ifname, bool_t *want_io,
+                                const char *ifname, char *want_io,
                                 const char *const *pats) {
     /* Returns True iff we found a list entry, in which case *want_io
      * is set to the sense of that entry.  Otherwise *want_io is set
@@ -75,9 +93,8 @@ static bool_t ifname_search_pats(struct polypath *st, struct cloc loc,
     const char *const *pati;
     for (pati=pats; *pati; pati++) {
        const char *pat=*pati;
-       if (*pat=='!') { *want_io=False; pat++; }
-       else if (*pat=='+') { *want_io=True; pat++; }
-       else if (*pat=='*' || isalnum((unsigned char)*pat)) { *want_io=True; }
+       if (*pat=='!' || *pat=='+') { *want_io=*pat; pat++; }
+       else if (*pat=='*' || isalnum((unsigned char)*pat)) { *want_io='+'; }
        else cfgfatal(loc,"polypath","invalid interface name pattern `%s'",pat);
        int match=fnmatch(pat,ifname,0);
        if (match==0) return True;
@@ -87,13 +104,13 @@ static bool_t ifname_search_pats(struct polypath *st, struct cloc loc,
     return False;
 }
 
-static bool_t ifname_wanted(struct polypath *st, struct cloc loc,
-                           const char *ifname) {
-    bool_t want=False; /* pretend an empty cfg ends with !<doesn'tmatch> */
+static char ifname_wanted(struct polypath *st, struct cloc loc,
+                         const char *ifname) {
+    char want='!'; /* pretend an empty cfg ends with !<doesn'tmatch> */
     if (ifname_search_pats(st,loc,ifname,&want, st->ifname_pats))
        return want;
-    if (want) /* last pattern was positive, do not search default */
-       return False;
+    if (want!='!') /* last pattern was positive, do not search default */
+       return '!';
     if (!st->permit_loopback &&
        ifname_search_pats(st,loc,ifname,&want, default_loopback_ifname_pats))
        return want;
@@ -127,10 +144,10 @@ static inline bool_t matches32(uint32_t word, uint32_t prefix, int prefixlen)
  * and
  *   out:
  */
-#define BAD(m)     do{ bad(st,badctx,m,0);  goto out; }while(0)
-#define BADE(m,ev) do{ bad(st,badctx,m,ev); goto out; }while(0)
+#define BAD(m)     do{ bad(st,badctx,M_WARNING,m,0);  goto out; }while(0)
+#define BADE(m,ev) do{ bad(st,badctx,M_WARNING,m,ev); goto out; }while(0)
 typedef void bad_fn_type(struct polypath *st, void *badctx,
-                        const char* m, int ev);
+                        int mclass, const char* m, int ev);
 
 typedef void polypath_ppml_callback_type(struct polypath *st,
           bad_fn_type *bad, void *badctx,
@@ -142,12 +159,13 @@ struct ppml_bad_ctx {
     char *undospace;
 };
 
-static void ppml_bad(struct polypath *st, void *badctx, const char *m, int ev)
+static void ppml_bad(struct polypath *st, void *badctx,
+                    int mclass, const char *m, int ev)
 {
     struct ppml_bad_ctx *bc=badctx;
     if (bc->undospace)
        *(bc->undospace)=' ';
-    lg_perror(LG,M_WARNING,ev,
+    lg_perror(LG,mclass,ev,
              "error processing polypath state change: %s"
              " (while processing `%s')",
              m,bc->orgl);
@@ -202,8 +220,9 @@ static void polypath_process_monitor_line(struct polypath *st, char *orgl,
        goto out;                                                       \
     }while(0)
 
-    if (!ifname_wanted(st,st->uc.cc.loc,ifname))
-       DONT("unwanted interface name");
+    char want=ifname_wanted(st,st->uc.cc.loc,ifname);
+    if (want=='!') DONT("unwanted interface name");
+    assert(want=='+');
 
     switch (ia.sa.sa_family) {
     case AF_INET6: {
@@ -225,6 +244,7 @@ static void polypath_process_monitor_line(struct polypath *st, char *orgl,
            DONT("IPv6 address is " m)
         DONTMASK( 100,   0,  8, "Discard-Only (RFC6666)");
        DONTMASK(2001,   0, 23, "in IETF protocol block (RFC2928)");
+       DONTMASK(fc00,   0,  7, "Uniqe Local unicast (RFC4193)");
 #undef DONTMASK
        break;
     }
@@ -321,8 +341,8 @@ static void polypath_record_ifaddr(struct polypath *st,
     interf->socks.n_socks=0;
     FILLZERO(interf->experienced_xmit_noaf);
     LIST_INSERT_HEAD(&st->interfs,interf,entry);
-    udp_socks_register(&st->uc,&interf->socks);
     interf->name=strdup(ifname);
+    udp_socks_register(&st->uc,&interf->socks,interf->name);
     if (!interf->name) BADE("strdup interface name",errno);
  found_interf:
 
@@ -336,21 +356,24 @@ static void polypath_record_ifaddr(struct polypath *st,
            bool_t ok=polypath_make_socket(st,bad,badctx, us,ifname);
            if (!ok) goto out;
        } else {
-           FILLZERO(us->experienced);
-           us->fd=fd;
+           bool_t ok=udp_import_socket(uc,us,M_WARNING,fd);
+           if (!ok) goto out;
            fd=-1;
        }
        interf->socks.n_socks++;
+       lg_perror(LG,M_INFO,0,"using %s %s",ifname,
+                 iaddr_to_string(&us->addr));
        us=0; /* do not destroy this socket during `out' */
-       lg_perror(LG,M_INFO,0,"using %s %s",ifname,ifaddr);
     } else {
        int i;
        for (i=0; i<interf->socks.n_socks; i++)
-           if (!memcmp(&interf->socks.socks[i].addr,ia,sizeof(*ia)))
+           if (iaddr_equal(&interf->socks.socks[i].addr,ia,True))
                goto address_remove_found;
-       BAD("address to remove not found");
+       bad(st,badctx,M_DEBUG,"address to remove not found",0);
+       goto out;
     address_remove_found:
-       lg_perror(LG,M_INFO,0,"removed %s %s",ifname,ifaddr);
+       lg_perror(LG,M_INFO,0,"removed %s %s",ifname,
+                 iaddr_to_string(&interf->socks.socks[i].addr));
        udp_destroy_socket(&st->uc,&interf->socks.socks[i]);
        interf->socks.socks[i]=
            interf->socks.socks[--interf->socks.n_socks];
@@ -420,7 +443,8 @@ static void polypath_afterpoll_monitor(void *state, struct pollfd *fds,
 
 /* Actual udp packet sending work */
 static bool_t polypath_sendmsg(void *commst, struct buffer_if *buf,
-                         const struct comm_addr *dest)
+                         const struct comm_addr *dest,
+                         struct comm_clientinfo *clientinfo)
 {
     struct polypath *st=commst;
     struct interf *interf;
@@ -437,8 +461,8 @@ static bool_t polypath_sendmsg(void *commst, struct buffer_if *buf,
            attempted=True;
            int r=sendto(us->fd,buf->start,buf->size,
                         0,&dest->ia.sa,iaddr_socklen(&dest->ia));
-           udp_sock_experienced(0,&st->uc, interf->name,us,
-                                1,af, r,errno);
+           udp_sock_experienced(0,&st->uc,&interf->socks,us,
+                                &dest->ia,af, r,errno);
            if (r>=0) {
                reasonable=True;
                break;
@@ -543,12 +567,13 @@ struct privsep_mdata {
     union iaddr ia;
 };
 
-static void papp_bad(struct polypath *st, void *badctx, const char *m, int ev)
+static void papp_bad(struct polypath *st, void *badctx,
+                    int mclass, const char *m, int ev)
 {
     const struct privsep_mdata *mdata=(const void*)st->lbuf.start;
     const char *addr_str=badctx;
 
-    lg_perror(LG,M_WARNING,ev,
+    lg_perror(LG,mclass,ev,
              "error processing polypath address change %s %s [%s]: %s",
              mdata->add ? "+" : "-",
              mdata->ifname, addr_str, m);