From c9637a8cc1594c708a9fd14f6015b52ee194d281 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 7 May 2015 13:50:30 -0400 Subject: [PATCH] restore ipv4/6 dual operation for control protocols --- daemon/control_ng.c | 12 ++++++++---- daemon/control_ng.h | 4 ++-- daemon/control_udp.c | 17 ++++++++++------- daemon/control_udp.h | 4 ++-- daemon/socket.h | 9 +++++++++ daemon/udp_listener.c | 4 ++-- daemon/udp_listener.h | 4 +++- 7 files changed, 36 insertions(+), 18 deletions(-) diff --git a/daemon/control_ng.c b/daemon/control_ng.c index e148dcffb..1f9735a47 100644 --- a/daemon/control_ng.c +++ b/daemon/control_ng.c @@ -75,7 +75,9 @@ struct control_ng_stats* get_control_ng_stats(struct control_ng* c, const sockad return cur; } -static void control_ng_incoming(struct obj *obj, str *buf, const endpoint_t *sin, char *addr) { +static void control_ng_incoming(struct obj *obj, str *buf, const endpoint_t *sin, char *addr, + struct udp_listener *ul) +{ struct control_ng *c = (void *) obj; bencode_buffer_t bencbuf; bencode_item_t *dict, *resp; @@ -205,7 +207,7 @@ send_only: iov[2].iov_base = to_send->s; iov[2].iov_len = to_send->len; - socket_sendiov(&c->udp_listener.sock, iov, iovlen, sin); + socket_sendiov(&ul->sock, iov, iovlen, sin); if (resp) cookie_cache_insert(&c->cookie_cache, &cookie, &reply); @@ -221,7 +223,7 @@ out: -struct control_ng *control_ng_new(struct poller *p, const endpoint_t *ep, struct callmaster *m) { +struct control_ng *control_ng_new(struct poller *p, endpoint_t *ep, struct callmaster *m) { struct control_ng *c; if (!p || !m) @@ -232,7 +234,9 @@ struct control_ng *control_ng_new(struct poller *p, const endpoint_t *ep, struct c->callmaster = m; cookie_cache_init(&c->cookie_cache); - if (udp_listener_init(&c->udp_listener, p, ep, control_ng_incoming, &c->obj)) + if (udp_listener_init(&c->udp_listeners[0], p, ep, control_ng_incoming, &c->obj)) + goto fail2; + if (ipv46_any_convert(ep) && udp_listener_init(&c->udp_listeners[1], p, ep, control_ng_incoming, &c->obj)) goto fail2; return c; diff --git a/daemon/control_ng.h b/daemon/control_ng.h index 8020643f0..919cd872a 100644 --- a/daemon/control_ng.h +++ b/daemon/control_ng.h @@ -25,9 +25,9 @@ struct control_ng { struct obj obj; struct callmaster *callmaster; struct cookie_cache cookie_cache; - struct udp_listener udp_listener; + struct udp_listener udp_listeners[2]; }; -struct control_ng *control_ng_new(struct poller *, const endpoint_t *, struct callmaster *); +struct control_ng *control_ng_new(struct poller *, endpoint_t *, struct callmaster *); #endif diff --git a/daemon/control_udp.c b/daemon/control_udp.c index d614aee6a..48ffa337a 100644 --- a/daemon/control_udp.c +++ b/daemon/control_udp.c @@ -20,7 +20,8 @@ #include "socket.h" -static void control_udp_incoming(struct obj *obj, str *buf, const endpoint_t *sin, char *addr) { +static void control_udp_incoming(struct obj *obj, str *buf, const endpoint_t *sin, char *addr, + struct udp_listener *ul) { struct control_udp *u = (void *) obj; int ret; int ovec[100]; @@ -58,7 +59,7 @@ static void control_udp_incoming(struct obj *obj, str *buf, const endpoint_t *si iovlen = 2; } - socket_sendiov(&u->udp_listener.sock, iov, iovlen, sin); + socket_sendiov(&ul->sock, iov, iovlen, sin); pcre_free(out); @@ -73,7 +74,7 @@ static void control_udp_incoming(struct obj *obj, str *buf, const endpoint_t *si reply = cookie_cache_lookup(&u->cookie_cache, &cookie); if (reply) { ilog(LOG_INFO, "Detected command from udp:%s as a duplicate", addr); - socket_sendto(&u->udp_listener.sock, reply->s, reply->len, sin); + socket_sendto(&ul->sock, reply->s, reply->len, sin); free(reply); goto out; } @@ -116,11 +117,11 @@ static void control_udp_incoming(struct obj *obj, str *buf, const endpoint_t *si iov[2].iov_len = 9; iovlen++; } - socket_sendiov(&u->udp_listener.sock, iov, iovlen, sin); + socket_sendiov(&ul->sock, iov, iovlen, sin); } if (reply) { - socket_sendto(&u->udp_listener.sock, reply->s, reply->len, sin); + socket_sendto(&ul->sock, reply->s, reply->len, sin); cookie_cache_insert(&u->cookie_cache, &cookie, reply); free(reply); } @@ -132,7 +133,7 @@ out: log_info_clear(); } -struct control_udp *control_udp_new(struct poller *p, const endpoint_t *ep, struct callmaster *m) { +struct control_udp *control_udp_new(struct poller *p, endpoint_t *ep, struct callmaster *m) { struct control_udp *c; const char *errptr; int erroff; @@ -164,7 +165,9 @@ struct control_udp *control_udp_new(struct poller *p, const endpoint_t *ep, stru cookie_cache_init(&c->cookie_cache); - if (udp_listener_init(&c->udp_listener, p, ep, control_udp_incoming, &c->obj)) + if (udp_listener_init(&c->udp_listeners[0], p, ep, control_udp_incoming, &c->obj)) + goto fail2; + if (ipv46_any_convert(ep) && udp_listener_init(&c->udp_listeners[1], p, ep, control_udp_incoming, &c->obj)) goto fail2; return c; diff --git a/daemon/control_udp.h b/daemon/control_udp.h index f38faf938..0381c39e0 100644 --- a/daemon/control_udp.h +++ b/daemon/control_udp.h @@ -50,7 +50,7 @@ struct control_udp { struct callmaster *callmaster; struct cookie_cache cookie_cache; - struct udp_listener udp_listener; + struct udp_listener udp_listeners[2]; pcre *parse_re; pcre_extra *parse_ree; @@ -61,7 +61,7 @@ struct control_udp { -struct control_udp *control_udp_new(struct poller *, const endpoint_t *, struct callmaster *); +struct control_udp *control_udp_new(struct poller *, endpoint_t *, struct callmaster *); diff --git a/daemon/socket.h b/daemon/socket.h index a8b912454..c00f5b85c 100644 --- a/daemon/socket.h +++ b/daemon/socket.h @@ -200,6 +200,15 @@ INLINE int endpoint_parse_port_any(endpoint_t *e, const char *p, unsigned int po e->port = port; return sockaddr_parse_any(&e->address, p); } +INLINE int ipv46_any_convert(endpoint_t *ep) { + if (ep->address.family->af != AF_INET) + return 0; + if (!is_addr_unspecified(&ep->address)) + return 0; + ep->address.family = __get_socket_family_enum(SF_IP6); + ZERO(ep->address.u.ipv6); + return 1; +} diff --git a/daemon/udp_listener.c b/daemon/udp_listener.c index 718decfdd..209038dc4 100644 --- a/daemon/udp_listener.c +++ b/daemon/udp_listener.c @@ -53,7 +53,7 @@ static void udp_listener_incoming(int fd, void *p, uintptr_t x) { endpoint_print(&sin, addr, sizeof(addr)); str.len = len; - cb->func(cb->p, &str, &sin, addr); + cb->func(cb->p, &str, &sin, addr, ul); } } @@ -71,7 +71,7 @@ int udp_listener_init(struct udp_listener *u, struct poller *p, const endpoint_t if (open_socket(&u->sock, SOCK_DGRAM, ep->port, &ep->address)) goto fail; - ipv6only(u->sock.fd, 0); + ipv6only(u->sock.fd, 1); ZERO(i); i.fd = u->sock.fd; diff --git a/daemon/udp_listener.h b/daemon/udp_listener.h index a865babc8..d69ef6d82 100644 --- a/daemon/udp_listener.h +++ b/daemon/udp_listener.h @@ -9,8 +9,10 @@ struct poller; struct obj; +struct udp_listener; -typedef void (*udp_listener_callback_t)(struct obj *p, str *buf, const endpoint_t *ep, char *addr); +typedef void (*udp_listener_callback_t)(struct obj *p, str *buf, const endpoint_t *ep, char *addr, + struct udp_listener *); struct udp_listener { socket_t sock;