# HG changeset patch # User chegar # Date 1571414939 -3600 # Node ID 2b1e684c3ce6f6b4c5946c2cce0aeadf2a4749e7 # Parent 7e9e2f10a050871915fc311ca2608e3ebfd61427 datagramsocketimpl-branch: fix issue with receive packet buf size diff -r 7e9e2f10a050 -r 2b1e684c3ce6 src/java.base/share/classes/java/net/DatagramPacket.java --- a/src/java.base/share/classes/java/net/DatagramPacket.java Thu Oct 17 21:15:33 2019 +0100 +++ b/src/java.base/share/classes/java/net/DatagramPacket.java Fri Oct 18 17:08:59 2019 +0100 @@ -25,6 +25,9 @@ package java.net; +import jdk.internal.access.JavaNetDatagramPacketAccess; +import jdk.internal.access.SharedSecrets; + /** * This class represents a datagram packet. *

@@ -367,12 +370,36 @@ * @since 1.1 */ public synchronized void setLength(int length) { + setLengthField(length); + this.bufLength = this.length; + } + + private synchronized void setLengthField(int length) { if ((length + offset) > buf.length || length < 0 || - (length + offset) < 0) { + (length + offset) < 0) { throw new IllegalArgumentException("illegal length"); } this.length = length; - this.bufLength = this.length; + } + + private synchronized int getBufLength() { + return bufLength; + } + + static { + SharedSecrets.setJavaNetDatagrtamPacketAccess( + new JavaNetDatagramPacketAccess() { + @Override + public int getBufLengthField(DatagramPacket packet) { + return packet.getBufLength(); + } + + @Override + public void setLengthField(DatagramPacket packet, int length) { + packet.setLengthField(length); + } + } + ); } /** diff -r 7e9e2f10a050 -r 2b1e684c3ce6 src/java.base/share/classes/jdk/internal/access/JavaNetDatagramPacketAccess.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.base/share/classes/jdk/internal/access/JavaNetDatagramPacketAccess.java Fri Oct 18 17:08:59 2019 +0100 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.internal.access; + +import java.net.DatagramPacket; + +public interface JavaNetDatagramPacketAccess { + int getBufLengthField(DatagramPacket packet); + void setLengthField(DatagramPacket packet, int length); +} diff -r 7e9e2f10a050 -r 2b1e684c3ce6 src/java.base/share/classes/jdk/internal/access/SharedSecrets.java --- a/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java Thu Oct 17 21:15:33 2019 +0100 +++ b/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java Fri Oct 18 17:08:59 2019 +0100 @@ -64,6 +64,7 @@ private static JavaIORandomAccessFileAccess javaIORandomAccessFileAccess; private static JavaObjectInputStreamAccess javaObjectInputStreamAccess; private static JavaObjectInputFilterAccess javaObjectInputFilterAccess; + private static JavaNetDatagramPacketAccess javaNetDatagramPacketAccess; private static JavaNetInetAddressAccess javaNetInetAddressAccess; private static JavaNetHttpCookieAccess javaNetHttpCookieAccess; private static JavaNetUriAccess javaNetUriAccess; @@ -138,6 +139,16 @@ return javaLangReflectAccess; } + public static void setJavaNetDatagrtamPacketAccess(JavaNetDatagramPacketAccess jndpa) { + javaNetDatagramPacketAccess = jndpa; + } + + public static JavaNetDatagramPacketAccess getJavaNetDatagramPacketAccess() { + if (javaNetDatagramPacketAccess == null) + unsafe.ensureClassInitialized(java.net.DatagramPacket.class); + return javaNetDatagramPacketAccess; + } + public static void setJavaNetUriAccess(JavaNetUriAccess jnua) { javaNetUriAccess = jnua; } diff -r 7e9e2f10a050 -r 2b1e684c3ce6 src/java.base/share/classes/sun/nio/ch/NioDatagramSocketImpl.java --- a/src/java.base/share/classes/sun/nio/ch/NioDatagramSocketImpl.java Thu Oct 17 21:15:33 2019 +0100 +++ b/src/java.base/share/classes/sun/nio/ch/NioDatagramSocketImpl.java Fri Oct 18 17:08:59 2019 +0100 @@ -48,6 +48,8 @@ import java.util.Objects; import java.util.Set; import java.util.concurrent.locks.ReentrantLock; +import jdk.internal.access.JavaNetDatagramPacketAccess; +import jdk.internal.access.SharedSecrets; import jdk.internal.ref.CleanerFactory; import sun.net.PlatformDatagramSocketImpl; import sun.net.ResourceManager; @@ -65,6 +67,9 @@ private static final NativeDispatcher nd = new SocketDispatcher(); + private static final JavaNetDatagramPacketAccess DATAGRAM_PACKET_ACCESS = + SharedSecrets.getJavaNetDatagramPacketAccess(); + private static final int MAX_PACKET_LEN = 65536; private static final ProtocolFamily family = family(); @@ -410,7 +415,7 @@ Objects.requireNonNull(p); byte[] b = p.getData(); int off = p.getOffset(); - int len = b.length - off; + int len = DATAGRAM_PACKET_ACCESS.getBufLengthField(p); assert len >= 0; if (len > MAX_PACKET_LEN) len = MAX_PACKET_LEN; @@ -441,7 +446,7 @@ p.setAddress(sender.getAddress()); if (p.getPort() != sender.getPort()) p.setPort(sender.getPort()); - p.setLength(n); + DATAGRAM_PACKET_ACCESS.setLengthField(p, n); } catch (IOException e) { // #### reset packet offset and length! ?? throw e; diff -r 7e9e2f10a050 -r 2b1e684c3ce6 test/jdk/java/net/DatagramPacket/ReuseBuf.java --- a/test/jdk/java/net/DatagramPacket/ReuseBuf.java Thu Oct 17 21:15:33 2019 +0100 +++ b/test/jdk/java/net/DatagramPacket/ReuseBuf.java Fri Oct 18 17:08:59 2019 +0100 @@ -21,14 +21,16 @@ * questions. */ -/** +/* * @test - * * @bug 4424096 - * * @summary DatagramPacket spec needs clarification (reuse buf) + * @run main ReuseBuf + * @run main/othervm -Djava.net.preferIPv4Stack=true ReuseBuf + * @run main/othervm -Djdk.net.usePlainDatagramSocketImpl=true ReuseBuf */ import java.net.*; +import static java.lang.System.out; public class ReuseBuf { static String msgs[] = {"Hello World", "Java", "Good Bye"}; @@ -54,8 +56,12 @@ try { ds.receive(dp); String reply = new String(dp.getData(), dp.getOffset(), dp.getLength()); - ds.send(new DatagramPacket(reply.getBytes(),reply.length(), - dp.getAddress(),dp.getPort())); + out.println("server: received [" + reply + "]"); + for (int i=0; i<2; i++) { + out.println("server: sending [" + reply + "]"); + ds.send(new DatagramPacket(reply.getBytes(), reply.length(), + dp.getAddress(), dp.getPort())); + } if (reply.equals(msgs[msgs.length-1])) { break; } @@ -76,16 +82,32 @@ byte b[] = new byte[100]; DatagramPacket dp = new DatagramPacket(b,b.length); for (int i = 0; i < msgs.length; i++) { + out.println("client: sending [" + msgs[i] + "]"); ds.send(new DatagramPacket(msgs[i].getBytes(),msgs[i].length(), InetAddress.getLocalHost(), port)); ds.receive(dp); - if (!msgs[i].equals(new String(dp.getData(), dp.getOffset(), dp.getLength()))) { - throw new RuntimeException("Msg expected: "+msgs[i] +msgs[i].length()+ - "msg received: "+new String(dp.getData(), dp.getOffset(), dp.getLength())+dp.getLength()); + String recvmsg = new String(dp.getData(), dp.getOffset(), dp.getLength()); + out.println("client: received [" + recvmsg + "]"); + if (!msgs[i].equals(recvmsg)) { + throw new RuntimeException("Msg expected: " + msgs[i] + + ", msg received: " + recvmsg); + } + + byte ba[] = new byte[1]; + DatagramPacket dp2 = new DatagramPacket(ba, ba.length); + dp2.setData(new byte[99], 5, 3); // only 3 bytes + ds.receive(dp2); + String expectedMsg = msgs[i].substring(0, 3); + recvmsg = new String(dp2.getData(), dp2.getOffset(), dp2.getLength()); + out.println("client: received [" + recvmsg + "]"); + if (!expectedMsg.equals(recvmsg)) { + throw new RuntimeException("Msg truncated expected: " + expectedMsg + + ", msg received: "+ recvmsg); } } ds.close(); - System.out.println("Test Passed!!!"); + out.println("Test Passed!!!"); + st.join(); } }