W dniu 25.03.2019 o 15:08, Otto Moerbeek pisze:
On Sat, Mar 23, 2019 at 06:07:02PM +0100, Michał Koc wrote:

... [snip]
This is almost good. You might fold host_ip() into net_set_sa(). the
double malloc and copy isn't really needed.

        -Otto

Done, patch follows

Best regards
M.K


Index: conf.y
===================================================================
RCS file: /cvs/src/usr.sbin/sasyncd/conf.y,v
retrieving revision 1.19
diff -u -p -r1.19 conf.y
--- conf.y      9 Apr 2017 02:40:24 -0000       1.19
+++ conf.y      26 Mar 2019 14:51:52 -0000
@@ -32,6 +32,7 @@
 #include <sys/socket.h>
 #include <ctype.h>
 #include <fcntl.h>
+#include <ifaddrs.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -48,6 +49,7 @@ struct cfgstate       cfgstate;
 int    conflen = 0;
 char   *confbuf, *confptr;
 
+int    check_peer_addr(const char *);
 int    yyparse(void);
 int    yylex(void);
 void   yyerror(const char *);
@@ -172,29 +174,21 @@ setting           : INTERFACE STRING
                | PEER STRING
                {
                        struct syncpeer *peer;
-                       int              duplicate = 0;
 
-                       for (peer = LIST_FIRST(&cfgstate.peerlist); peer;
-                            peer = LIST_NEXT(peer, link))
-                               if (strcmp($2, peer->name) == 0) {
-                                       duplicate++;
-                                       break;
-                               }
-                       if (duplicate)
-                               free($2);
-                       else {
+                       if (check_peer_addr($2)) {
                                peer = calloc(1, sizeof *peer);
-                               if (!peer) {
+                               if (peer == NULL) {
                                        log_err("config: calloc(1, %lu) "
                                            "failed", sizeof *peer);
                                        free($2);
                                        YYERROR;
                                }
                                peer->name = $2;
-                       }
-                       LIST_INSERT_HEAD(&cfgstate.peerlist, peer, link);
-                       cfgstate.peercnt++;
-                       log_msg(2, "config: add peer %s", peer->name);
+                               LIST_INSERT_HEAD(&cfgstate.peerlist, peer, 
link);
+                               cfgstate.peercnt++;
+                               log_msg(2, "config: add peer %s", peer->name);
+                       } else
+                               free($2);
                }
                | LISTEN ON STRING af port
                {
@@ -281,6 +275,46 @@ match(char *token)
            sizeof keywords[0], match_cmp);
 
        return k ? k->value : STRING;
+}
+
+int
+check_peer_addr(const char *peer_addr)
+{
+       struct ifaddrs          *ifap = 0, *ifa;
+       struct syncpeer         *peer;
+       struct sockaddr_storage  ss, peer_ss;
+
+       if(net_set_sa((struct sockaddr *)&ss, peer_addr, 0) == -1) {
+               log_msg(2, "config: skip unparseable peer %s", peer_addr);
+               return 0;
+       }
+
+       if (getifaddrs(&ifap) == 0) {
+               for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
+                       if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family 
!= ss.ss_family)
+                               continue;
+
+                       if (ss.ss_len == ifa->ifa_addr->sa_len && memcmp(&ss, 
ifa->ifa_addr, ss.ss_len) == 0) {
+                               log_msg(2, "config: skip local peer %s", 
peer_addr);
+                               freeifaddrs(ifap);
+                               return 0;
+                       }
+               }
+               freeifaddrs(ifap);
+       }
+
+       for (peer = LIST_FIRST(&cfgstate.peerlist); peer != NULL; peer = 
LIST_NEXT(peer, link)) {
+           if(net_set_sa((struct sockaddr *)&peer_ss, peer->name, 0) == -1) {
+               log_msg(2, "config: net_set_sa(%s) failed", peer->name);
+               continue;
+           }
+           if (ss.ss_len == peer_ss.ss_len && memcmp(&ss, &peer_ss, ss.ss_len) 
== 0) {
+               log_msg(2, "config: skip duplicate peer %s", peer_addr);
+               return 0;
+           }
+       }
+
+       return 1;
 }
 
 int
Index: net.c
===================================================================
RCS file: /cvs/src/usr.sbin/sasyncd/net.c,v
retrieving revision 1.23
diff -u -p -r1.23 net.c
--- net.c       12 Dec 2015 20:04:23 -0000      1.23
+++ net.c       26 Mar 2019 14:51:52 -0000
@@ -71,7 +71,6 @@ AES_KEY       aes_key[2];
 
 /* Local prototypes. */
 static u_int8_t *net_read(struct syncpeer *, u_int32_t *, u_int32_t *);
-static int      net_set_sa(struct sockaddr *, char *, in_port_t);
 static void     net_check_peers(void *);
 
 /* Pretty-print a buffer. */
@@ -752,35 +751,30 @@ net_read(struct syncpeer *p, u_int32_t *
        return msg;
 }
 
-static int
-net_set_sa(struct sockaddr *sa, char *name, in_port_t port)
+int
+net_set_sa(struct sockaddr *sa, const char *name, in_port_t port)
 {
-       struct sockaddr_in      *sin = (struct sockaddr_in *)sa;
-       struct sockaddr_in6     *sin6 = (struct sockaddr_in6 *)sa;
-
-       if (!name) {
-               /* XXX Assume IPv4 */
-               sa->sa_family = AF_INET;
-               sin->sin_port = htons(port);
-               sin->sin_len = sizeof *sin;
-               return 0;
-       }
+       struct addrinfo         *ai = NULL;
 
-       if (inet_pton(AF_INET, name, &sin->sin_addr) == 1) {
-               sa->sa_family = AF_INET;
-               sin->sin_port = htons(port);
-               sin->sin_len = sizeof *sin;
-               return 0;
-       }
-
-       if (inet_pton(AF_INET6, name, &sin6->sin6_addr) == 1) {
-               sa->sa_family = AF_INET6;
-               sin6->sin6_port = htons(port);
-               sin6->sin6_len = sizeof *sin6;
-               return 0;
+       if (getaddrinfo(name, NULL, NULL, &ai) == 0) {
+           memcpy(sa, ai->ai_addr, ai->ai_addr->sa_len);
+           freeaddrinfo(ai);
+
+           switch(sa->sa_family) {
+           case AF_INET:
+               ((struct sockaddr_in *)sa)->sin_port = htons(port);
+               break;
+
+           case AF_INET6:
+               ((struct sockaddr_in6 *)sa)->sin6_port = htons(port);
+               break;
+               
+           default:
+               return -1;
+           }
        }
 
-       return -1;
+       return ai == NULL ? -1 : 0;
 }
 
 static void
Index: net.h
===================================================================
RCS file: /cvs/src/usr.sbin/sasyncd/net.h,v
retrieving revision 1.5
diff -u -p -r1.5 net.h
--- net.h       2 Jun 2006 20:09:43 -0000       1.5
+++ net.h       26 Mar 2019 14:51:52 -0000
@@ -53,6 +53,7 @@ enum CTLTYPE { RESERVED = 0, CTL_STATE, 
 /* net.c */
 void   net_connect(void);
 void   net_disconnect_peer(struct syncpeer *);
+int    net_set_sa(struct sockaddr *, const char *, in_port_t);
 
 /* net_ctl.c */
 void   net_ctl_handle_msg(struct syncpeer *, u_int8_t *, u_int32_t);

Reply via email to