This is an automated email from the ASF dual-hosted git repository. elecharny pushed a commit to branch 2.2.X in repository https://gitbox.apache.org/repos/asf/mina.git
The following commit(s) were added to refs/heads/2.2.X by this push: new c7230458d Fix for DIRMINA-1172 new 3e638d11b Merge remote-tracking branch 'origin/2.2.X' into 2.2.X c7230458d is described below commit c7230458d8cd238c88a7ffe360ba91ad0309fe0a Author: emmanuel lecharny <elecha...@apache.org> AuthorDate: Wed Aug 23 14:18:29 2023 +0200 Fix for DIRMINA-1172 --- .../mina/core/session/ExpiringSessionRecycler.java | 16 +- .../mina/core/session/IoSessionRecycler.java | 5 +- .../transport/socket/nio/NioDatagramAcceptor.java | 2 +- .../mina/transport/socket/nio/DIRMINA1172.java | 225 +++++++++++++++++++++ 4 files changed, 239 insertions(+), 9 deletions(-) diff --git a/mina-core/src/main/java/org/apache/mina/core/session/ExpiringSessionRecycler.java b/mina-core/src/main/java/org/apache/mina/core/session/ExpiringSessionRecycler.java index 54d58a2b1..445fbc204 100644 --- a/mina-core/src/main/java/org/apache/mina/core/session/ExpiringSessionRecycler.java +++ b/mina-core/src/main/java/org/apache/mina/core/session/ExpiringSessionRecycler.java @@ -19,6 +19,7 @@ */ package org.apache.mina.core.session; +import java.net.InetSocketAddress; import java.net.SocketAddress; import org.apache.mina.util.ExpirationListener; @@ -32,10 +33,10 @@ import org.apache.mina.util.ExpiringMap; */ public class ExpiringSessionRecycler implements IoSessionRecycler { /** A map used to store the session */ - private ExpiringMap<SocketAddress, IoSession> sessionMap; + private ExpiringMap<String, IoSession> sessionMap; /** A map used to keep a track of the expiration */ - private ExpiringMap<SocketAddress, IoSession>.Expirer mapExpirer; + private ExpiringMap<String, IoSession>.Expirer mapExpirer; /** * Create a new ExpiringSessionRecycler instance @@ -72,7 +73,9 @@ public class ExpiringSessionRecycler implements IoSessionRecycler { public void put(IoSession session) { mapExpirer.startExpiringIfNotStarted(); - SocketAddress key = session.getRemoteAddress(); + String key = session.getRemoteAddress() + ":" + ((InetSocketAddress)session.getLocalAddress()).getPort(); + + if (!sessionMap.containsKey(key)) { sessionMap.put(key, session); @@ -83,8 +86,9 @@ public class ExpiringSessionRecycler implements IoSessionRecycler { * {@inheritDoc} */ @Override - public IoSession recycle(SocketAddress remoteAddress) { - return sessionMap.get(remoteAddress); + public IoSession recycle(SocketAddress remoteAddress, int port) { + String key = remoteAddress + ":" + port; + return sessionMap.get(key); } /** @@ -92,7 +96,7 @@ public class ExpiringSessionRecycler implements IoSessionRecycler { */ @Override public void remove(IoSession session) { - sessionMap.remove(session.getRemoteAddress()); + sessionMap.remove(session.getRemoteAddress() + ":" + ((InetSocketAddress)session.getLocalAddress()).getPort()); } /** diff --git a/mina-core/src/main/java/org/apache/mina/core/session/IoSessionRecycler.java b/mina-core/src/main/java/org/apache/mina/core/session/IoSessionRecycler.java index f7c3b219c..1db3eba03 100644 --- a/mina-core/src/main/java/org/apache/mina/core/session/IoSessionRecycler.java +++ b/mina-core/src/main/java/org/apache/mina/core/session/IoSessionRecycler.java @@ -48,7 +48,7 @@ public interface IoSessionRecycler { * {@inheritDoc} */ @Override - public IoSession recycle(SocketAddress remoteAddress) { + public IoSession recycle(SocketAddress remoteAddress, int port) { return null; } @@ -72,9 +72,10 @@ public interface IoSessionRecycler { * Attempts to retrieve a recycled {@link IoSession}. * * @param remoteAddress the remote socket address of the {@link IoSession} the transport wants to recycle. + * @param port The port the Accpetor is listening on * @return a recycled {@link IoSession}, or null if one cannot be found. */ - IoSession recycle(SocketAddress remoteAddress); + IoSession recycle(SocketAddress remoteAddress, int port); /** * Called when an {@link IoSession} is explicitly closed. diff --git a/mina-core/src/main/java/org/apache/mina/transport/socket/nio/NioDatagramAcceptor.java b/mina-core/src/main/java/org/apache/mina/transport/socket/nio/NioDatagramAcceptor.java index 5455afe9b..52e5044a0 100644 --- a/mina-core/src/main/java/org/apache/mina/transport/socket/nio/NioDatagramAcceptor.java +++ b/mina-core/src/main/java/org/apache/mina/transport/socket/nio/NioDatagramAcceptor.java @@ -326,7 +326,7 @@ public final class NioDatagramAcceptor extends AbstractIoAcceptor implements Dat IoSession session; synchronized (sessionRecycler) { - session = sessionRecycler.recycle(remoteAddress); + session = sessionRecycler.recycle(remoteAddress, ((InetSocketAddress)localAddress).getPort()); if (session != null) { return session; diff --git a/mina-core/src/test/java/org/apache/mina/transport/socket/nio/DIRMINA1172.java b/mina-core/src/test/java/org/apache/mina/transport/socket/nio/DIRMINA1172.java new file mode 100644 index 000000000..e9b6001fe --- /dev/null +++ b/mina-core/src/test/java/org/apache/mina/transport/socket/nio/DIRMINA1172.java @@ -0,0 +1,225 @@ + +package org.apache.mina.transport.socket.nio; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.InetSocketAddress; + +import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder; +import org.apache.mina.core.service.AbstractIoService; +import org.apache.mina.core.service.IoHandler; +import org.apache.mina.core.session.IdleStatus; +import org.apache.mina.core.session.IoSession; +import org.apache.mina.filter.FilterEvent; +import org.apache.mina.filter.logging.LoggingFilter; +import org.junit.Before; +import org.junit.Test; + +public class DIRMINA1172 +{ + private static DatagramSocket socket; + private static InetAddress address; + private static byte[] buf; + + @Before + public void init() + { + AbstractIoService inputSource1 = new NioDatagramAcceptor(); + ((NioDatagramAcceptor) inputSource1).getSessionConfig().setReuseAddress(true); + DefaultIoFilterChainBuilder filterChainBuilderUDP = ((NioDatagramAcceptor)inputSource1).getFilterChain(); + filterChainBuilderUDP.addLast("logger", new LoggingFilter()); + + ((NioDatagramAcceptor) inputSource1).getSessionConfig().setIdleTime(IdleStatus.READER_IDLE, 100000); + ((NioDatagramAcceptor) inputSource1).setHandler( new IoHandler() + { + + @Override + public void sessionOpened( IoSession session ) throws Exception + { + // TODO Auto-generated method stub + + } + + + @Override + public void sessionIdle( IoSession session, IdleStatus status ) throws Exception + { + // TODO Auto-generated method stub + + } + + + @Override + public void sessionCreated( IoSession session ) throws Exception + { + // TODO Auto-generated method stub + + } + + + @Override + public void sessionClosed( IoSession session ) throws Exception + { + // TODO Auto-generated method stub + + } + + + @Override + public void messageSent( IoSession session, Object message ) throws Exception + { + // TODO Auto-generated method stub + + } + + + @Override + public void messageReceived( IoSession session, Object message ) throws Exception + { + // TODO Auto-generated method stub + System.out.println( "1"+session ); + + } + + + @Override + public void inputClosed( IoSession session ) throws Exception + { + // TODO Auto-generated method stub + + } + + + @Override + public void exceptionCaught( IoSession session, Throwable cause ) throws Exception + { + // TODO Auto-generated method stub + + } + + + @Override + public void event( IoSession session, FilterEvent event ) throws Exception + { + // TODO Auto-generated method stub + + } + }); + + AbstractIoService inputSource2 = new NioDatagramAcceptor(); + ((NioDatagramAcceptor) inputSource2).getSessionConfig().setReuseAddress(true); + DefaultIoFilterChainBuilder filterChainBuilderUDP2 = ((NioDatagramAcceptor)inputSource2).getFilterChain(); + filterChainBuilderUDP2.addLast("logger", new LoggingFilter()); + + ((NioDatagramAcceptor) inputSource2).getSessionConfig().setIdleTime(IdleStatus.READER_IDLE, 100000); + ((NioDatagramAcceptor) inputSource2).setHandler( new IoHandler() + { + + @Override + public void sessionOpened( IoSession session ) throws Exception + { + // TODO Auto-generated method stub + + } + + + @Override + public void sessionIdle( IoSession session, IdleStatus status ) throws Exception + { + // TODO Auto-generated method stub + + } + + + @Override + public void sessionCreated( IoSession session ) throws Exception + { + // TODO Auto-generated method stub + + } + + + @Override + public void sessionClosed( IoSession session ) throws Exception + { + // TODO Auto-generated method stub + + } + + + @Override + public void messageSent( IoSession session, Object message ) throws Exception + { + // TODO Auto-generated method stub + + } + + + @Override + public void messageReceived( IoSession session, Object message ) throws Exception + { + // TODO Auto-generated method stub + System.out.println( "2:"+session ); + + } + + + @Override + public void inputClosed( IoSession session ) throws Exception + { + // TODO Auto-generated method stub + + } + + + @Override + public void exceptionCaught( IoSession session, Throwable cause ) throws Exception + { + // TODO Auto-generated method stub + + } + + + @Override + public void event( IoSession session, FilterEvent event ) throws Exception + { + // TODO Auto-generated method stub + + } + }); + + try { + ((NioDatagramAcceptor)inputSource1).bind(new InetSocketAddress(9800)); + ((NioDatagramAcceptor)inputSource2).bind(new InetSocketAddress(9801)); + } catch (IOException e) { + //log.error("Failed to connect {}", e); + } + } + + @Test + public void test() throws InterruptedException, IOException + { + socket = new DatagramSocket(); + address = InetAddress.getByName("localhost"); + + int[] ports = new int[]{9800, 9801}; + + while(true) { + + for (int port : ports ) { + String msg = "TEST_" + port + " " + String.valueOf(System.currentTimeMillis()); + buf = msg.getBytes(); + DatagramPacket packet = new DatagramPacket(buf, buf.length, address, port); + socket.send(packet); + System.out.println("Send: " + msg); + } + + Thread.sleep(5000); + } + } + +}