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