New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Support for TUN-based Channels (kqueue/epoll) #12960
base: 4.1
Are you sure you want to change the base?
Conversation
Motivation: I want to develop a mesh VPN. Since I love netty, I would love to use it for this project. Therefore I need a TUN-based Channel implementation. Modifications: - Added native methods to io.netty.channel.kqueue.BsdSocket and io.netty.channel.epoll.LinuxSocket, allowing the creation of TUN devices and setting/getting the network interface MTU on macOS and Linux. - Implemented io.netty.channel.kqueue.KQueueTunChannel and io.netty.channel.epoll.EpollTunChannel, allowing the creation of TUN-based channels using epoll and kqueue. - Defined and implemented io.netty.channel.socket.TunChannelConfig, allowing setting/getting the network interface MTU. - Modified io.netty.channel.unix.Socket to avoid Socket#isIPv6(fd) call that is not supported on TUN sockets. - Modified io.netty.channel.epoll.AbstractEpollChannel allowing to set AbstractEpollChannel#local in EpollTunChannel#doBind as io.netty.channel.kqueue.Native#epollCtlAdd must be called after TUN device has been bound. - Renamed io.netty.channel.kqueue.AbstractKQueueDatagramChannel to io.netty.channel.kqueue.AbstractKQueueMessageChannel because KQueueTunChannel needs to implement this class but is not datagram related. As this rename may break the API, I re-added AbstractKQueueDatagramChannel for legacy reasons. - Added io.netty.channel.socket.Tun4Packet and io.netty.channel.socket.Tun6Packet to help work with IPv4 and IPv6 packets. - Added io.netty.example.tun.TunPingDevice example creating a TUN device that will reply to IPMC/IPv6-ICMP echo ping requests. - Added io.netty.example.tun.TunEchoDevice example that echoes all received IP packets (e.g., suitable for performance tests). - Added native dependencies to example/pom.xml (might require changes to your release workflow). - Modified run-example.sh to activate platform-dependent native transport maven profile. Result: Support for TUN-based Channels on kqueue- and epoll-enabled platforms. Co-authored-by: Kevin Röbert <dev@roebert.eu>
This is something that I'd love to work on. I'll review in sometime and get back to you. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First round of small changes
transport-classes-kqueue/src/main/java/io/netty/channel/kqueue/KQueueTunChannel.java
Show resolved
Hide resolved
transport-classes-kqueue/src/main/java/io/netty/channel/kqueue/BsdSocket.java
Show resolved
Hide resolved
transport-classes-epoll/src/main/java/io/netty/channel/epoll/EpollTunChannel.java
Show resolved
Hide resolved
@chrisvest Can you please trigger CI? |
I'll do benchmarking and testing today. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add test cases that test actual traffic flow because the current one only test packet level? Can we do an ICMP ping or a UDP echo?
transport/src/main/java/io/netty/channel/socket/TunAddress.java
Outdated
Show resolved
Hide resolved
This works like charm. Successfully built a bridge-tunnel connection between 2 EC2. But my main concern is regarding performance since we are only using 1 thread for handling all I/O. Is there any way? |
Co-authored-by: Kevin Röbert <dev@roebert.eu>
Co-authored-by: Kevin Röbert <dev@roebert.eu>
Co-authored-by: Kevin Röbert <dev@roebert.eu>
Co-authored-by: Kevin Röbert <dev@roebert.eu>
Co-authored-by: Kevin Röbert <dev@roebert.eu>
I will try to implement an ICMP ping test
The multiqueue feature looks interesting! |
You can use the UDP You can use multi-queue to accept multiple packet streams using different channels but on the same Handler. |
Co-authored-by: Kevin Röbert <dev@roebert.eu>
I followed your advice and added Earlier, you suggested writing some tests: Have you thought of a fully automated test (e.g., JUnit) or a new testsuite Maven module to help with manually testing? |
Looks good but we need more test cases to cover all functionality. |
We don't need an extra module I guess. |
I am thinking on an integration test creating a Is this in line with your expectation? |
Sounds good. Also, a little bit of TCP tunneling tests will be good too. |
@normanmaurer Is it fine if we create a workflow for testing this on macOS? |
Co-authored-by: Kevin Röbert <dev@roebert.eu>
Co-authored-by: Kevin Röbert <dev@roebert.eu>
Co-authored-by: Kevin Röbert <dev@roebert.eu>
|
Co-authored-by: Kevin Röbert <dev@roebert.eu>
@chrisvest Please add this to your TO-DO :) |
This seems a bit exotic, so I'm wondering if we can get by with the minimum JNI changes in core Netty, and have the rest of the implementation in a contrib repository? It's also a big change in general, which makes me wonder if Netty 5 is a better target (fewer versions to maintain; would have to be ported anyway). |
Sounds good. @chrisvest If you can review the code then I can create a contrib repository and begin working with @HeikoBornholdt on porting this. |
I would love to see TUN support added to Netty 4.1. |
I'll be closely maintaining this module with @HeikoBornholdt if merged in 4.1. You can rely on us for maintenance. @chrisvest |
+1 As a co-author, I am also willing to maintain the module. |
@normanmaurer @chrisvest Can we do this folks? |
I would like to know the progress of this thing as I happen to have a need to develop a TUN interface :) |
@chrisvest Gentle ping... :) |
Moin @normanmaurer 👋, I remember your delight about similar PR https://twitter.com/normanmaurer/status/830336283683721217. |
@normanmaurer @hyperxpro Is there any update on the review? Anything we can help with? |
Unfortunately I dont feel we have the resources at the moment to maintain this and so put it in the main project. The best bet for now would be to either make it part of the Netty-incubator or make it a separate repository under your own username. |
Thank you for replying, I understand that. Would it be acceptable to put the necessary C methods (see changes in netty_epoll_linuxsocket.c, netty_epoll_native.c, netty_kqueue_bsdsocket.c) into the main project? |
@normanmaurer @hyperxpro Do we get the okay for that? |
We are having an internal discussion on this. Will get back soon with an update. |
There you go folks: https://github.com/netty-contrib/transport-tun Please do a PR and tag everyone for review. |
Motivation
I want to develop a mesh VPN. Since I love netty, I would love to use it for this project. Therefore I need a TUN-based
Channel
implementation.Modifications
io.netty.channel.kqueue.BsdSocket
andio.netty.channel.epoll.LinuxSocket
, allowing the creation of TUN devices and setting/getting the network interface MTU on macOS and Linux.io.netty.channel.kqueue.KQueueTunChannel
andio.netty.channel.epoll.EpollTunChannel
, allowing the creation of TUN-based channels using epoll and kqueue.io.netty.channel.socket.TunChannelConfig
, allowing setting/getting the network interface MTU.io.netty.channel.unix.Socket
to avoidSocket#isIPv6(fd)
call that is not supported on TUN sockets.io.netty.channel.epoll.AbstractEpollChannel
allowing to setAbstractEpollChannel#local
inEpollTunChannel#doBind
asio.netty.channel.kqueue.Native#epollCtlAdd
must be called after TUN device has been bound.io.netty.channel.kqueue.AbstractKQueueDatagramChannel
toio.netty.channel.kqueue.AbstractKQueueMessageChannel
becauseKQueueTunChannel
needs to implement this class but is not datagram related. As this rename may break the API, I re-addedAbstractKQueueDatagramChannel
for legacy reasons.io.netty.channel.socket.Tun4Packet
andio.netty.channel.socket.Tun6Packet
to help work with IPv4 and IPv6 packets.io.netty.example.tun.TunPingDevice
example creating a TUN device that will reply to IPMC/IPv6-ICMP echo ping requests.io.netty.example.tun.TunEchoDevice
example that echoes all received IP packets (e.g., suitable for performance tests).example/pom.xml
(might require changes to your release workflow).run-example.sh
to activate platform-dependent native transport maven profile.Result
Support for TUN-based
Channel
s on kqueue- and epoll-enabled platforms.Additional Nodes
If desired, I can also provide a
TunChannel
for Windows based on Wintun. I already prototyped it, but I'm not sure if the Wintun license is compatible with netty.