Skip to content

fixed ipv6 address join ipv4 group failed#11015

Merged
chrisvest merged 4 commits intonetty:4.1from
wineway:4.1
Feb 16, 2021
Merged

fixed ipv6 address join ipv4 group failed#11015
chrisvest merged 4 commits intonetty:4.1from
wineway:4.1

Conversation

@wineway
Copy link
Copy Markdown
Contributor

@wineway wineway commented Feb 10, 2021

Motivation:

#10995

when io.netty.channel.unix.Socket is ipv6 and join a multicast group with ipv4 address will cause io.netty.channel.ChannelException: setsockopt() failed: Invalid argument (at least in Linux centos.dev 4.18.0-240.10.1.el8_3.x86_64 #1 SMP Mon Jan 18 17:05:51 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux)

Modification:

check if target group address is ipv6 before call io.netty.channel.epoll.LinuxSocket#joinGroup(java.net.InetAddress, java.net.NetworkInterface, java.net.InetAddress)

I'm not sure if this modification is currect, but i checked source code of java NIO

Java_sun_nio_ch_Net_canJoin6WithIPv4Group0(JNIEnv* env, jclass cl)
{
#if defined(__APPLE__)
    /* IPV6_ADD_MEMBERSHIP can be used to join IPv4 multicast groups */
    return JNI_TRUE;
#else
    /* IPV6_ADD_MEMBERSHIP cannot be used to join IPv4 multicast groups */
    return JNI_FALSE;
#endif
}

seems ipv6 address can't join ipv4 group except osx

Result:

test on Linux 3.10.0-514.el7.x86_64 #1 SMP Tue Nov 22 16:42:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux exception setsockopt() failed: Invalid argument has fixed

Fixes #10995

@normanmaurer
Copy link
Copy Markdown
Member

@wineway did you verify this really fixed the issue ? Maybe you could also add a unit test ?

@wineway
Copy link
Copy Markdown
Contributor Author

wineway commented Feb 10, 2021

@wineway did you verify this really fixed the issue ? Maybe you could also add a unit test ?

of cource my manual test has passed, and i would try to add proper unit test

I can explain why this modification can work;

refer to java nio implementation; on linux, ipv6 socket can join ipv4 multicast group

Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0(JNIEnv* env, jclass cl)
{
#if defined(__linux__) || defined(__APPLE__)
    /* IPv6 sockets can join IPv4 multicast groups */
    return JNI_TRUE;
#else
    /* IPv6 sockets cannot join IPv4 multicast groups */
    return JNI_FALSE;
#endif
}

but IPV6_ADD_MEMBERSHIP can't be used to join ipv4

Java_sun_nio_ch_Net_canJoin6WithIPv4Group0(JNIEnv* env, jclass cl)
{
#if defined(__APPLE__)
    /* IPV6_ADD_MEMBERSHIP can be used to join IPv4 multicast groups */
    return JNI_TRUE;
#else
    /* IPV6_ADD_MEMBERSHIP cannot be used to join IPv4 multicast groups */
    return JNI_FALSE;
#endif
}

so we should use IP_ADD_MEMBERSHIP instead of IPV6_ADD_MEMBERSHIP or IPV6_JOIN_GROUP

the original bool ipv6 depend on if local socket is instance of ipv6,
when ipv4 group pass in, it will initialize as sockaddr_in6 by netty_unix_socket_initSockaddr function, and will be set option IPV6_JOIN_GROUP, this will cause an exception

and in fact, when isIpv6 == true , no matter group addr or interface addr is Inet4Adder, we shouldn't pass ipv6 = true to netty_epoll_linuxsocket_joinGroup

and also, in joinSsmGroup , java nio implement will check if source is same type with group

        if (source != null) {
            if (source.isAnyLocalAddress())
                throw new IllegalArgumentException("Source address is a wildcard address");
            if (source.isMulticastAddress())
                throw new IllegalArgumentException("Source address is multicast address");
            if (source.getClass() != group.getClass())
                throw new IllegalArgumentException("Source address is different type to group");
        }

but netty's implementation didn't do this, I am not sure if we should add this check or just let it go

@normanmaurer
Copy link
Copy Markdown
Member

@wineway did you sign our icla ?

https://netty.io/s/icla

add group type check
@wineway
Copy link
Copy Markdown
Contributor Author

wineway commented Feb 12, 2021

@wineway did you sign our icla ?

https://netty.io/s/icla

ci failed, i would try to fix it


@normanmaurer sure

and I have add tests, PTAL

thx

@normanmaurer
Copy link
Copy Markdown
Member

@wineway the unit test fails... please check

@wineway wineway force-pushed the 4.1 branch 3 times, most recently from e12ca2f to b5f27bf Compare February 12, 2021 09:22
@chrisvest chrisvest merged commit 5d01295 into netty:4.1 Feb 16, 2021
@chrisvest
Copy link
Copy Markdown
Member

@wineway Thanks!

chrisvest pushed a commit that referenced this pull request Feb 16, 2021
Motivation:

#10995 

when `io.netty.channel.unix.Socket` is ipv6 and join a multicast group with ipv4 address will cause `io.netty.channel.ChannelException: setsockopt() failed: Invalid argument` (at least in `Linux centos.dev 4.18.0-240.10.1.el8_3.x86_64 #1 SMP Mon Jan 18 17:05:51 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux`)


Modification:

check if target group address is ipv6 before call  `io.netty.channel.epoll.LinuxSocket#joinGroup(java.net.InetAddress, java.net.NetworkInterface, java.net.InetAddress)` 

I'm not sure if this modification is currect, but i checked source code of java NIO

```
Java_sun_nio_ch_Net_canJoin6WithIPv4Group0(JNIEnv* env, jclass cl)
{
#if defined(__APPLE__)
    /* IPV6_ADD_MEMBERSHIP can be used to join IPv4 multicast groups */
    return JNI_TRUE;
#else
    /* IPV6_ADD_MEMBERSHIP cannot be used to join IPv4 multicast groups */
    return JNI_FALSE;
#endif
}
```
seems ipv6 address can't join ipv4 group except osx

Result:

test on `Linux 3.10.0-514.el7.x86_64 #1 SMP Tue Nov 22 16:42:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux` exception  ` setsockopt() failed: Invalid argument` has fixed

Fixes #10995
raidyue pushed a commit to raidyue/netty that referenced this pull request Jul 8, 2022
Motivation:

netty#10995 

when `io.netty.channel.unix.Socket` is ipv6 and join a multicast group with ipv4 address will cause `io.netty.channel.ChannelException: setsockopt() failed: Invalid argument` (at least in `Linux centos.dev 4.18.0-240.10.1.el8_3.x86_64 netty#1 SMP Mon Jan 18 17:05:51 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux`)


Modification:

check if target group address is ipv6 before call  `io.netty.channel.epoll.LinuxSocket#joinGroup(java.net.InetAddress, java.net.NetworkInterface, java.net.InetAddress)` 

I'm not sure if this modification is currect, but i checked source code of java NIO

```
Java_sun_nio_ch_Net_canJoin6WithIPv4Group0(JNIEnv* env, jclass cl)
{
#if defined(__APPLE__)
    /* IPV6_ADD_MEMBERSHIP can be used to join IPv4 multicast groups */
    return JNI_TRUE;
#else
    /* IPV6_ADD_MEMBERSHIP cannot be used to join IPv4 multicast groups */
    return JNI_FALSE;
#endif
}
```
seems ipv6 address can't join ipv4 group except osx

Result:

test on `Linux 3.10.0-514.el7.x86_64 netty#1 SMP Tue Nov 22 16:42:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux` exception  ` setsockopt() failed: Invalid argument` has fixed

Fixes netty#10995
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Netty UDP multicast using Epoll throws Exception while joining multicast group

3 participants