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