From 9004554da35d1e6ab2a2431337dac84d3260f702 Mon Sep 17 00:00:00 2001 From: Joel Cunningham Date: Wed, 25 Feb 2015 21:59:21 +0100 Subject: [PATCH] fixed bug #43028 (IP_MULTICAST_TTL affects unicast datagrams) --- CHANGELOG | 4 ++++ src/api/sockets.c | 4 ++-- src/core/udp.c | 13 ++++++++++++- src/include/lwip/udp.h | 6 +++++- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index c57f4e52..f9d817eb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -202,6 +202,10 @@ HISTORY ++ Bugfixes: + 2015-02-25: patch by Joel Cunningham + * udp.h/.c, sockets.c: fixed bug #43028 (IP_MULTICAST_TTL affects unicast + datagrams) + 2015-02-25: patch by Greg Renda * ip4_frag.c: fixed bug #38210 (ip reassembly while remove oldest datagram) diff --git a/src/api/sockets.c b/src/api/sockets.c index dce155e8..a0795b7b 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -1803,7 +1803,7 @@ lwip_getsockopt_impl(int s, int level, int optname, void *optval, socklen_t *opt if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { return ENOPROTOOPT; } - *(u8_t*)optval = sock->conn->pcb.ip->ttl; + *(u8_t*)optval = sock->conn->pcb.udp->mcast_ttl; LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_TTL) = %d\n", s, *(int *)optval)); break; @@ -2160,7 +2160,7 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_ #if LWIP_IGMP case IP_MULTICAST_TTL: LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP); - sock->conn->pcb.udp->ttl = (u8_t)(*(u8_t*)optval); + sock->conn->pcb.udp->mcast_ttl = (u8_t)(*(u8_t*)optval); break; case IP_MULTICAST_IF: { diff --git a/src/core/udp.c b/src/core/udp.c index 155d8b5e..ed9bb28e 100644 --- a/src/core/udp.c +++ b/src/core/udp.c @@ -694,6 +694,7 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d err_t err; struct pbuf *q; /* q will be sent down the stack */ u8_t ip_proto; + u8_t ttl; #if IP_SOF_BROADCAST /* broadcast filter? */ @@ -848,11 +849,18 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d ip_proto = IP_PROTO_UDP; } + /* Determine TTL to use */ +#if LWIP_IGMP + ttl = (ip_addr_ismulticast(dst_ip) ? pcb->mcast_ttl : pcb->ttl); +#else + ttl = pcb->ttl; +#endif + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum)); LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,0x%02"X16_F",)\n", (u16_t)ip_proto)); /* output to IP */ NETIF_SET_HWADDRHINT(netif, &(pcb->addr_hint)); - err = ipX_output_if_src(PCB_ISIPV6(pcb), q, src_ip, dst_ip, pcb->ttl, pcb->tos, ip_proto, netif); + err = ipX_output_if_src(PCB_ISIPV6(pcb), q, src_ip, dst_ip, ttl, pcb->tos, ip_proto, netif); NETIF_SET_HWADDRHINT(netif, NULL); /* TODO: must this be increased even if error occurred? */ @@ -1117,6 +1125,9 @@ udp_new(void) /* initialize PCB to all zeroes */ memset(pcb, 0, sizeof(struct udp_pcb)); pcb->ttl = UDP_TTL; +#if LWIP_IGMP + pcb->mcast_ttl = UDP_TTL; +#endif } return pcb; } diff --git a/src/include/lwip/udp.h b/src/include/lwip/udp.h index 39c5a6a7..22a6f658 100644 --- a/src/include/lwip/udp.h +++ b/src/include/lwip/udp.h @@ -124,6 +124,8 @@ struct udp_pcb { #if LWIP_IGMP /** outgoing network interface for multicast packets */ ip_addr_t multicast_ip; + /** TTL for outgoing multicast packets */ + u8_t mcast_ttl; #endif /* LWIP_IGMP */ #if LWIP_UDPLITE @@ -207,8 +209,10 @@ struct udp_pcb * udp_new_ip6(void); #endif /* LWIP_IPV6 */ #if LWIP_IGMP -#define udp_set_multicast_netif_addr(pcb, ip4addr) ((pcb)->multicast_ip = *(ip4addr)) +#define udp_set_multicast_netif_addr(pcb, ip4addr) do { (pcb)->multicast_ip = *(ip4addr); } while(0) #define udp_get_multicast_netif_addr(pcb) (&(pcb)->multicast_ip) +#define udp_set_multicast_ttl(pcb, mcast_ttl) do { (pcb)->mcast_ttl = mcast_ttl; } while(0) +#define udp_get_multicast_ttl(pcb) ((pcb)->mcast_ttl) #endif /* LWIP_IGMP */ #if UDP_DEBUG