On Tue, Mar 26, 2019 at 03:52:47PM +0100, Michał Koc wrote:

> 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
> 
> 

Looks good to me,

Klemens, can you take a look?

        -Otto

> 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