151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project 3519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.nio.ch; 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.FileDescriptor; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.IOException; 315ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.DatagramSocket; 325ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.Inet4Address; 335ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.Inet6Address; 345ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.InetAddress; 355ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.InetSocketAddress; 365ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.NetworkInterface; 375ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.PortUnreachableException; 385ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.ProtocolFamily; 395ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.SocketAddress; 405ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.SocketOption; 415ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.StandardProtocolFamily; 425ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.net.StandardSocketOptions; 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.nio.ByteBuffer; 445ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.AlreadyBoundException; 455ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.ClosedChannelException; 465ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.DatagramChannel; 475ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.MembershipKey; 485ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.NotYetConnectedException; 495ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.SelectionKey; 505ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.UnsupportedAddressTypeException; 515ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.spi.SelectorProvider; 525ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.util.Collections; 535ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.util.HashSet; 545ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.util.Set; 551d568d5e72820f7e487a49e3c57dee4f1e7f14bcNarayan Kamath 561d568d5e72820f7e487a49e3c57dee4f1e7f14bcNarayan Kamathimport dalvik.system.BlockGuard; 575ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport dalvik.system.CloseGuard; 58519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmeraimport sun.net.ExtendedOptionsImpl; 595ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport sun.net.ResourceManager; 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * An implementation of DatagramChannels. 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass DatagramChannelImpl 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski extends DatagramChannel 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski implements SelChImpl 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{ 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Used to make native read and write calls 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static NativeDispatcher nd = new DatagramDispatcher(); 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Our file descriptor 74e409de23a3281073142ff137b609778d6c70a31cYi Kong // Android-changed: Make the fd package visible so that we can expose it through DatagramSocketAdaptor. 75e409de23a3281073142ff137b609778d6c70a31cYi Kong final FileDescriptor fd; 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // fd value needed for dev/poll. This value will remain valid 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // even after the value in the file descriptor object has been set to -1 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final int fdVal; 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // The protocol family of the socket 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final ProtocolFamily family; 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // IDs of native threads doing reads and writes, for signalling 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private volatile long readerThread = 0; 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private volatile long writerThread = 0; 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Cached InetAddress and port for unconnected DatagramChannels 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // used by receive0 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private InetAddress cachedSenderInetAddress; 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int cachedSenderPort; 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Lock held by current reading or connecting thread 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final Object readLock = new Object(); 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Lock held by current writing or connecting thread 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final Object writeLock = new Object(); 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Lock held by any thread that modifies the state fields declared below 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // DO NOT invoke a blocking I/O operation while holding this lock! 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final Object stateLock = new Object(); 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // -- The following fields are protected by stateLock 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // State (does not necessarily increase monotonically) 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int ST_UNINITIALIZED = -1; 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int ST_UNCONNECTED = 0; 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int ST_CONNECTED = 1; 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int ST_KILLED = 2; 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int state = ST_UNINITIALIZED; 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Binding 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private InetSocketAddress localAddress; 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private InetSocketAddress remoteAddress; 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Our socket adaptor, if any 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private DatagramSocket socket; 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 119e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // Multicast support 120e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private MembershipRegistry registry; 121e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // set true when socket is bound and SO_REUSEADDRESS is emulated 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean reuseAddressEmulated; 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // set true/false when socket is already bound and SO_REUSEADDR is emulated 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean isReuseAddress; 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // -- End of fields protected by stateLock 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1305ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera // Android-changed: Add CloseGuard support. 1315ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera private final CloseGuard guard = CloseGuard.get(); 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DatagramChannelImpl(SelectorProvider sp) 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(sp); 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ResourceManager.beforeUdpCreate(); 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.family = Net.isIPv6Available() ? 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski StandardProtocolFamily.INET6 : StandardProtocolFamily.INET; 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fd = Net.socket(family, false); 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fdVal = IOUtil.fdVal(fd); 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.state = ST_UNCONNECTED; 1445ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera // Android-changed: Add CloseGuard support. 1455ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera // Net#socket will set |fd| if it succeeds. 1465ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera if (fd != null && fd.valid()) { 1475ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera guard.open("close"); 1485ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera } 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe) { 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ResourceManager.afterUdpClose(); 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw ioe; 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DatagramChannelImpl(SelectorProvider sp, ProtocolFamily family) 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(sp); 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((family != StandardProtocolFamily.INET) && 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (family != StandardProtocolFamily.INET6)) 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (family == null) 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException("'family' is null"); 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new UnsupportedOperationException("Protocol family not supported"); 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (family == StandardProtocolFamily.INET6) { 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!Net.isIPv6Available()) { 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new UnsupportedOperationException("IPv6 not available"); 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.family = family; 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fd = Net.socket(family, false); 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fdVal = IOUtil.fdVal(fd); 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.state = ST_UNCONNECTED; 1765ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera // Android-changed: Add CloseGuard support. 1775ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera // Net#socket will set |fd| if it succeeds. 1785ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera if (fd != null && fd.valid()) { 1795ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera guard.open("close"); 1805ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera } 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DatagramChannelImpl(SelectorProvider sp, FileDescriptor fd) 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(sp); 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.family = Net.isIPv6Available() ? 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski StandardProtocolFamily.INET6 : StandardProtocolFamily.INET; 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fd = fd; 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fdVal = IOUtil.fdVal(fd); 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.state = ST_UNCONNECTED; 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.localAddress = Net.localAddress(fd); 1935ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera // Android-changed: Add CloseGuard support. 1945ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera if (fd != null && fd.valid()) { 1955ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera guard.open("close"); 1965ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera } 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DatagramSocket socket() { 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (socket == null) 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski socket = DatagramSocketAdaptor.create(this); 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return socket; 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 207e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SocketAddress getLocalAddress() throws IOException { 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 212519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera // Perform security check before returning address 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return Net.getRevealedLocalAddress(localAddress); 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SocketAddress getRemoteAddress() throws IOException { 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return remoteAddress; 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public <T> DatagramChannel setOption(SocketOption<T> name, T value) 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name == null) 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!supportedOptions().contains(name)) 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new UnsupportedOperationException("'" + name + "' not supported"); 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 238519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (name == StandardSocketOptions.IP_TOS || 239519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera name == StandardSocketOptions.IP_MULTICAST_TTL || 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name == StandardSocketOptions.IP_MULTICAST_LOOP) 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // options are protocol dependent 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Net.setSocketOption(fd, family, name, value); 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this; 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name == StandardSocketOptions.IP_MULTICAST_IF) { 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (value == null) 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Cannot set IP_MULTICAST_IF to 'null'"); 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski NetworkInterface interf = (NetworkInterface)value; 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (family == StandardProtocolFamily.INET6) { 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int index = interf.getIndex(); 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (index == -1) 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("Network interface cannot be identified"); 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Net.setInterface6(fd, index); 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // need IPv4 address to identify interface 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Inet4Address target = Net.anyInet4Address(interf); 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (target == null) 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("Network interface not configured for IPv4"); 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int targetAddress = Net.inet4AsInt(target); 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Net.setInterface4(fd, targetAddress); 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this; 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name == StandardSocketOptions.SO_REUSEADDR && 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Net.useExclusiveBind() && localAddress != null) 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski reuseAddressEmulated = true; 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.isReuseAddress = (Boolean)value; 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // remaining options don't need any special handling 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Net.setSocketOption(fd, Net.UNSPEC, name, value); 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this; 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 279e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @SuppressWarnings("unchecked") 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public <T> T getOption(SocketOption<T> name) 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name == null) 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!supportedOptions().contains(name)) 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new UnsupportedOperationException("'" + name + "' not supported"); 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 292519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (name == StandardSocketOptions.IP_TOS || 293519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera name == StandardSocketOptions.IP_MULTICAST_TTL || 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski name == StandardSocketOptions.IP_MULTICAST_LOOP) 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (T) Net.getSocketOption(fd, family, name); 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name == StandardSocketOptions.IP_MULTICAST_IF) { 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (family == StandardProtocolFamily.INET) { 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int address = Net.getInterface4(fd); 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (address == 0) 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; // default interface 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetAddress ia = Net.inet4FromInt(address); 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski NetworkInterface ni = NetworkInterface.getByInetAddress(ia); 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ni == null) 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("Unable to map address to interface"); 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (T) ni; 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int index = Net.getInterface6(fd); 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (index == 0) 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; // default interface 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski NetworkInterface ni = NetworkInterface.getByIndex(index); 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ni == null) 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("Unable to map index to interface"); 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (T) ni; 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name == StandardSocketOptions.SO_REUSEADDR && 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski reuseAddressEmulated) 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (T)Boolean.valueOf(isReuseAddress); 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // no special handling 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (T) Net.getSocketOption(fd, Net.UNSPEC, name); 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static class DefaultOptionsHolder { 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static final Set<SocketOption<?>> defaultOptions = defaultOptions(); 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static Set<SocketOption<?>> defaultOptions() { 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski HashSet<SocketOption<?>> set = new HashSet<SocketOption<?>>(8); 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski set.add(StandardSocketOptions.SO_SNDBUF); 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski set.add(StandardSocketOptions.SO_RCVBUF); 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski set.add(StandardSocketOptions.SO_REUSEADDR); 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski set.add(StandardSocketOptions.SO_BROADCAST); 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski set.add(StandardSocketOptions.IP_TOS); 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski set.add(StandardSocketOptions.IP_MULTICAST_IF); 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski set.add(StandardSocketOptions.IP_MULTICAST_TTL); 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski set.add(StandardSocketOptions.IP_MULTICAST_LOOP); 346e573e88e89daf5efb323719c54117c5a423eb245Yi Kong if (ExtendedOptionsImpl.flowSupported()) { 347e573e88e89daf5efb323719c54117c5a423eb245Yi Kong set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA); 348e573e88e89daf5efb323719c54117c5a423eb245Yi Kong } 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return Collections.unmodifiableSet(set); 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 353e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final Set<SocketOption<?>> supportedOptions() { 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return DefaultOptionsHolder.defaultOptions; 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void ensureOpen() throws ClosedChannelException { 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private SocketAddress sender; // Set by receive0 (## ugh) 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SocketAddress receive(ByteBuffer dst) throws IOException { 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (dst.isReadOnly()) 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Read-only buffer"); 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (dst == null) 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 3706975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer // Android-changed: Do not attempt to bind to 0 (or 0.0.0.0) if there hasn't been 371396f2361ba82cce530a4ff8aa9ac0780af8d4d56Narayan Kamath // an explicit call to bind() yet. Fail fast and return null. 372396f2361ba82cce530a4ff8aa9ac0780af8d4d56Narayan Kamath if (localAddress == null) 373396f2361ba82cce530a4ff8aa9ac0780af8d4d56Narayan Kamath return null; 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (readLock) { 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Socket was not bound before attempting receive 377396f2361ba82cce530a4ff8aa9ac0780af8d4d56Narayan Kamath // if (localAddress() == null) 378396f2361ba82cce530a4ff8aa9ac0780af8d4d56Narayan Kamath // bind(null); 37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = 0; 38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ByteBuffer bb = null; 38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager security = System.getSecurityManager(); 38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readerThread = NativeThread.current(); 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isConnected() || (security == null)) { 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = receive(fd, dst); 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((n == IOStatus.INTERRUPTED) && isOpen()); 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n == IOStatus.UNAVAILABLE) 39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bb = Util.getTemporaryDirectBuffer(dst.remaining()); 39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (;;) { 39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = receive(fd, bb); 39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((n == IOStatus.INTERRUPTED) && isOpen()); 39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n == IOStatus.UNAVAILABLE) 40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetSocketAddress isa = (InetSocketAddress)sender; 40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski security.checkAccept( 40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isa.getAddress().getHostAddress(), 40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isa.getPort()); 40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (SecurityException se) { 40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Ignore packet 40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bb.clear(); 40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = 0; 41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bb.flip(); 41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski dst.put(bb); 41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return sender; 41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bb != null) 42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Util.releaseTemporaryDirectBuffer(bb); 42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readerThread = 0; 42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end((n > 0) || (n == IOStatus.UNAVAILABLE)); 42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int receive(FileDescriptor fd, ByteBuffer dst) 42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int pos = dst.position(); 43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int lim = dst.limit(); 43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert (pos <= lim); 43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int rem = (pos <= lim ? lim - pos : 0); 43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (dst instanceof DirectBuffer && rem > 0) 43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return receiveIntoNativeBuffer(fd, dst, rem, pos); 43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Substitute a native buffer. If the supplied buffer is empty 43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // we must instead use a nonempty buffer, otherwise the call 44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // will not block waiting for a datagram on some platforms. 44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int newSize = Math.max(rem, 1); 44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ByteBuffer bb = Util.getTemporaryDirectBuffer(newSize); 44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 4441d568d5e72820f7e487a49e3c57dee4f1e7f14bcNarayan Kamath BlockGuard.getThreadPolicy().onNetwork(); 4451d568d5e72820f7e487a49e3c57dee4f1e7f14bcNarayan Kamath 44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = receiveIntoNativeBuffer(fd, bb, newSize, 0); 44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bb.flip(); 44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n > 0 && rem > 0) 44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski dst.put(bb); 45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return n; 45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Util.releaseTemporaryDirectBuffer(bb); 45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int receiveIntoNativeBuffer(FileDescriptor fd, ByteBuffer bb, 45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int rem, int pos) 45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = receive0(fd, ((DirectBuffer)bb).address() + pos, rem, 46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isConnected()); 46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n > 0) 46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bb.position(pos + n); 46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return n; 46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int send(ByteBuffer src, SocketAddress target) 46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (src == null) 47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (writeLock) { 47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetSocketAddress isa = Net.checkAddress(target); 47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetAddress ia = isa.getAddress(); 47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ia == null) 47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("Target address not resolved"); 47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isConnected()) { 48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (target == null) 48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager sm = System.getSecurityManager(); 48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sm != null) { 48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ia.isMulticastAddress()) { 48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sm.checkMulticast(ia); 48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sm.checkConnect(ia.getHostAddress(), 48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isa.getPort()); 49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { // Connected case; Check address then write 49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!target.equals(remoteAddress)) { 49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException( 49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "Connected address not equal to target address"); 49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return write(src); 49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = 0; 50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski writerThread = NativeThread.current(); 5071d568d5e72820f7e487a49e3c57dee4f1e7f14bcNarayan Kamath BlockGuard.getThreadPolicy().onNetwork(); 5081d568d5e72820f7e487a49e3c57dee4f1e7f14bcNarayan Kamath 50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = send(fd, src, isa); 51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((n == IOStatus.INTERRUPTED) && isOpen()); 51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isOpen() && (localAddress == null)) { 51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski localAddress = Net.localAddress(fd); 51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(n); 51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski writerThread = 0; 52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end((n > 0) || (n == IOStatus.UNAVAILABLE)); 52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int send(FileDescriptor fd, ByteBuffer src, InetSocketAddress target) 52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (src instanceof DirectBuffer) 53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return sendFromNativeBuffer(fd, src, target); 53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Substitute a native buffer 53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int pos = src.position(); 53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int lim = src.limit(); 53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert (pos <= lim); 53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int rem = (pos <= lim ? lim - pos : 0); 53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ByteBuffer bb = Util.getTemporaryDirectBuffer(rem); 54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bb.put(src); 54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bb.flip(); 54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Do not update src until we see how many bytes were written 54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski src.position(pos); 54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = sendFromNativeBuffer(fd, bb, target); 54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n > 0) { 54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // now update src 54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski src.position(pos + n); 55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return n; 55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Util.releaseTemporaryDirectBuffer(bb); 55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int sendFromNativeBuffer(FileDescriptor fd, ByteBuffer bb, 55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetSocketAddress target) 55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int pos = bb.position(); 56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int lim = bb.limit(); 56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert (pos <= lim); 56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int rem = (pos <= lim ? lim - pos : 0); 56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean preferIPv6 = (family != StandardProtocolFamily.INET); 56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int written; 56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski written = send0(preferIPv6, fd, ((DirectBuffer)bb).address() + pos, 57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski rem, target.getAddress(), target.getPort()); 57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (PortUnreachableException pue) { 57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isConnected()) 57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw pue; 57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski written = rem; 57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (written > 0) 57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bb.position(pos + written); 57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return written; 57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int read(ByteBuffer buf) throws IOException { 58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (buf == null) 58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (readLock) { 58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isConnected()) 58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NotYetConnectedException(); 58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = 0; 59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readerThread = NativeThread.current(); 59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = IOUtil.read(fd, buf, -1, nd); 59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((n == IOStatus.INTERRUPTED) && isOpen()); 59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(n); 60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readerThread = 0; 60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end((n > 0) || (n == IOStatus.UNAVAILABLE)); 60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 60551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long read(ByteBuffer[] dsts, int offset, int length) 60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((offset < 0) || (length < 0) || (offset > dsts.length - length)) 61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IndexOutOfBoundsException(); 61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (readLock) { 61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isConnected()) 61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NotYetConnectedException(); 61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 61951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long n = 0; 62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 62151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 62251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 62351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 62451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readerThread = NativeThread.current(); 62551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = IOUtil.read(fd, dsts, offset, length, nd); 62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((n == IOStatus.INTERRUPTED) && isOpen()); 62851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(n); 62951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski readerThread = 0; 63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end((n > 0) || (n == IOStatus.UNAVAILABLE)); 63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int write(ByteBuffer buf) throws IOException { 63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (buf == null) 63951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (writeLock) { 64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isConnected()) 64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NotYetConnectedException(); 64551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = 0; 64751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 64851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 65151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski writerThread = NativeThread.current(); 65251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 65351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = IOUtil.write(fd, buf, -1, nd); 65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((n == IOStatus.INTERRUPTED) && isOpen()); 65551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(n); 65651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski writerThread = 0; 65851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end((n > 0) || (n == IOStatus.UNAVAILABLE)); 65951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 66051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 66251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 66351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long write(ByteBuffer[] srcs, int offset, int length) 66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 66651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((offset < 0) || (length < 0) || (offset > srcs.length - length)) 66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IndexOutOfBoundsException(); 66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (writeLock) { 67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isConnected()) 67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NotYetConnectedException(); 67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long n = 0; 67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 68051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski writerThread = NativeThread.current(); 68151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 68251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = IOUtil.write(fd, srcs, offset, length, nd); 68351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((n == IOStatus.INTERRUPTED) && isOpen()); 68451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(n); 68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski writerThread = 0; 68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end((n > 0) || (n == IOStatus.UNAVAILABLE)); 68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 69351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected void implConfigureBlocking(boolean block) throws IOException { 69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski IOUtil.configureBlocking(fd, block); 69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 69751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SocketAddress localAddress() { 69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return localAddress; 70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SocketAddress remoteAddress() { 70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return remoteAddress; 70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DatagramChannel bind(SocketAddress local) throws IOException { 71151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (readLock) { 71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (writeLock) { 71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (localAddress != null) 71651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new AlreadyBoundException(); 71751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetSocketAddress isa; 71851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (local == null) { 71951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // only Inet4Address allowed with IPv4 socket 72051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (family == StandardProtocolFamily.INET) { 72151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isa = new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 0); 72251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 72351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isa = new InetSocketAddress(0); 72451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 72551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 72651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isa = Net.checkAddress(local); 72751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 72851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // only Inet4Address allowed with IPv4 socket 72951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (family == StandardProtocolFamily.INET) { 73051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetAddress addr = isa.getAddress(); 73151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!(addr instanceof Inet4Address)) 73251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new UnsupportedAddressTypeException(); 73351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager sm = System.getSecurityManager(); 73651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sm != null) { 73751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sm.checkListen(isa.getPort()); 73851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Net.bind(family, fd, isa.getAddress(), isa.getPort()); 74051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski localAddress = Net.localAddress(fd); 74151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 74251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 74351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 74451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this; 74551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 74651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 74751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean isConnected() { 74851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 74951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (state == ST_CONNECTED); 75051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 75151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 75251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 75351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void ensureOpenAndUnconnected() throws IOException { // package-private 75451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 75551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 75651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 75751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (state != ST_UNCONNECTED) 75851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalStateException("Connect already invoked"); 75951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 76051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 76151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 76251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 76351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DatagramChannel connect(SocketAddress sa) throws IOException { 76451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int localPort = 0; 76551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 76651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized(readLock) { 76751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized(writeLock) { 76851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 76951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpenAndUnconnected(); 77051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetSocketAddress isa = Net.checkAddress(sa); 77151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager sm = System.getSecurityManager(); 77251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sm != null) 77351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sm.checkConnect(isa.getAddress().getHostAddress(), 77451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isa.getPort()); 77551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = Net.connect(family, 77651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski fd, 77751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isa.getAddress(), 77851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isa.getPort()); 77951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n <= 0) 78051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new Error(); // Can't happen 78151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 78251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Connection succeeded; disallow further invocation 78351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski state = ST_CONNECTED; 78451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski remoteAddress = isa; 78551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sender = isa; 78651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cachedSenderInetAddress = isa.getAddress(); 78751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cachedSenderPort = isa.getPort(); 78851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 78951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // set or refresh local address 79051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski localAddress = Net.localAddress(fd); 7916031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong 7926031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong // flush any packets already received. 7936031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong boolean blocking = false; 7946031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong synchronized (blockingLock()) { 7956031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong try { 7966031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong blocking = isBlocking(); 7976031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong // remainder of each packet thrown away 7986031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong ByteBuffer tmpBuf = ByteBuffer.allocate(1); 7996031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong if (blocking) { 8006031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong configureBlocking(false); 8016031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong } 8026031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong do { 8036031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong tmpBuf.clear(); 8048b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong } while (receive(tmpBuf) != null); 8056031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong } finally { 8066031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong if (blocking) { 8076031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong configureBlocking(true); 8086031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong } 8096031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong } 8106031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong } 81151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 81251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 81351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 81451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this; 81551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 81651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 81751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DatagramChannel disconnect() throws IOException { 81851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized(readLock) { 81951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized(writeLock) { 82051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 82151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isConnected() || !isOpen()) 82251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this; 82351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetSocketAddress isa = remoteAddress; 82451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager sm = System.getSecurityManager(); 82551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sm != null) 82651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sm.checkConnect(isa.getAddress().getHostAddress(), 82751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isa.getPort()); 82851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean isIPv6 = (family == StandardProtocolFamily.INET6); 82951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski disconnect0(fd, isIPv6); 83051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski remoteAddress = null; 83151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski state = ST_UNCONNECTED; 83251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 83351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // refresh local address 83451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski localAddress = Net.localAddress(fd); 83551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 83651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 83751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 83851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this; 83951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 84051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 841e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 842e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Joins channel's socket to the given group/interface and 843e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * optional source address. 844e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 845e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera private MembershipKey innerJoin(InetAddress group, 846e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera NetworkInterface interf, 847e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera InetAddress source) 848e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throws IOException 849e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 850e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!group.isMulticastAddress()) 851e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IllegalArgumentException("Group not a multicast address"); 852e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 853e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // check multicast address is compatible with this socket 854e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (group instanceof Inet4Address) { 855e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (family == StandardProtocolFamily.INET6 && !Net.canIPv6SocketJoinIPv4Group()) 856e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IllegalArgumentException("IPv6 socket cannot join IPv4 multicast group"); 857e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } else if (group instanceof Inet6Address) { 858e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (family != StandardProtocolFamily.INET6) 859e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IllegalArgumentException("Only IPv6 sockets can join IPv6 multicast group"); 860e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } else { 861e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IllegalArgumentException("Address type not supported"); 862e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 863e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 864e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // check source address 865e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (source != null) { 866e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (source.isAnyLocalAddress()) 867e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IllegalArgumentException("Source address is a wildcard address"); 868e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (source.isMulticastAddress()) 869e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IllegalArgumentException("Source address is multicast address"); 870e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (source.getClass() != group.getClass()) 871e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IllegalArgumentException("Source address is different type to group"); 872e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 873e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 874e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera SecurityManager sm = System.getSecurityManager(); 875e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (sm != null) 876e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera sm.checkMulticast(group); 877e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 878e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera synchronized (stateLock) { 879e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!isOpen()) 880e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new ClosedChannelException(); 881e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 882e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // check the registry to see if we are already a member of the group 883e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (registry == null) { 884e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera registry = new MembershipRegistry(); 885e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } else { 886e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // return existing membership key 887e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera MembershipKey key = registry.checkMembership(group, interf, source); 888e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (key != null) 889e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return key; 890e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 891e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 892e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera MembershipKeyImpl key; 893e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if ((family == StandardProtocolFamily.INET6) && 894e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera ((group instanceof Inet6Address) || Net.canJoin6WithIPv4Group())) 895e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 896e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera int index = interf.getIndex(); 897e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (index == -1) 898e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IOException("Network interface cannot be identified"); 899e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 900e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // need multicast and source address as byte arrays 901e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera byte[] groupAddress = Net.inet6AsByteArray(group); 902e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera byte[] sourceAddress = (source == null) ? null : 903e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.inet6AsByteArray(source); 904e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 905e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // join the group 906e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera int n = Net.join6(fd, groupAddress, index, sourceAddress); 907e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (n == IOStatus.UNAVAILABLE) 908e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new UnsupportedOperationException(); 909e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 910e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera key = new MembershipKeyImpl.Type6(this, group, interf, source, 911e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera groupAddress, index, sourceAddress); 912e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 913e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } else { 914e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // need IPv4 address to identify interface 915e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Inet4Address target = Net.anyInet4Address(interf); 916e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (target == null) 917e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IOException("Network interface not configured for IPv4"); 918e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 919e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera int groupAddress = Net.inet4AsInt(group); 920e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera int targetAddress = Net.inet4AsInt(target); 921e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera int sourceAddress = (source == null) ? 0 : Net.inet4AsInt(source); 922e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 923e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // join the group 924e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera int n = Net.join4(fd, groupAddress, targetAddress, sourceAddress); 925e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (n == IOStatus.UNAVAILABLE) 926e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new UnsupportedOperationException(); 927e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 928e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera key = new MembershipKeyImpl.Type4(this, group, interf, source, 929e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera groupAddress, targetAddress, sourceAddress); 930e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 931e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 932e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera registry.add(key); 933e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return key; 934e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 935e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 936e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 937e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 938e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public MembershipKey join(InetAddress group, 939e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera NetworkInterface interf) 940e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throws IOException 941e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 942e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return innerJoin(group, interf, null); 943e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 944e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 945e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera @Override 946e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera public MembershipKey join(InetAddress group, 947e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera NetworkInterface interf, 948e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera InetAddress source) 949e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throws IOException 950e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 951e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (source == null) 952e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new NullPointerException("source address is null"); 953e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return innerJoin(group, interf, source); 954e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 955e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 956e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // package-private 957e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera void drop(MembershipKeyImpl key) { 958e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera assert key.channel() == this; 959e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 960e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera synchronized (stateLock) { 961e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!key.isValid()) 962e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera return; 963e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 964e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera try { 965e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (key instanceof MembershipKeyImpl.Type6) { 966e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera MembershipKeyImpl.Type6 key6 = 967e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera (MembershipKeyImpl.Type6)key; 968e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.drop6(fd, key6.groupAddress(), key6.index(), key6.source()); 969e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } else { 970e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera MembershipKeyImpl.Type4 key4 = (MembershipKeyImpl.Type4)key; 971e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.drop4(fd, key4.groupAddress(), key4.interfaceAddress(), 972e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera key4.source()); 973e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 974e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } catch (IOException ioe) { 975e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // should not happen 976e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new AssertionError(ioe); 977e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 978e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 979e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera key.invalidate(); 980e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera registry.remove(key); 981e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 982e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 983e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 984e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 985e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Block datagrams from given source if a memory to receive all 986e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * datagrams. 987e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 988e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera void block(MembershipKeyImpl key, InetAddress source) 989e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throws IOException 990e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera { 991e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera assert key.channel() == this; 992e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera assert key.sourceAddress() == null; 993e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 994e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera synchronized (stateLock) { 995e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!key.isValid()) 996e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IllegalStateException("key is no longer valid"); 997e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (source.isAnyLocalAddress()) 998e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IllegalArgumentException("Source address is a wildcard address"); 999e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (source.isMulticastAddress()) 1000e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IllegalArgumentException("Source address is multicast address"); 1001e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (source.getClass() != key.group().getClass()) 1002e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IllegalArgumentException("Source address is different type to group"); 1003e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 1004e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera int n; 1005e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (key instanceof MembershipKeyImpl.Type6) { 1006e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera MembershipKeyImpl.Type6 key6 = 1007e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera (MembershipKeyImpl.Type6)key; 1008e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera n = Net.block6(fd, key6.groupAddress(), key6.index(), 1009e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.inet6AsByteArray(source)); 1010e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } else { 1011e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera MembershipKeyImpl.Type4 key4 = 1012e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera (MembershipKeyImpl.Type4)key; 1013e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera n = Net.block4(fd, key4.groupAddress(), key4.interfaceAddress(), 1014e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.inet4AsInt(source)); 1015e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 1016e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (n == IOStatus.UNAVAILABLE) { 1017e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // ancient kernel 1018e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new UnsupportedOperationException(); 1019e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 1020e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 1021e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 1022e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 1023e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera /** 1024e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera * Unblock given source. 1025e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera */ 1026e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera void unblock(MembershipKeyImpl key, InetAddress source) { 1027e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera assert key.channel() == this; 1028e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera assert key.sourceAddress() == null; 1029e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 1030e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera synchronized (stateLock) { 1031e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (!key.isValid()) 1032e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new IllegalStateException("key is no longer valid"); 1033e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 1034e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera try { 1035e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (key instanceof MembershipKeyImpl.Type6) { 1036e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera MembershipKeyImpl.Type6 key6 = 1037e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera (MembershipKeyImpl.Type6)key; 1038e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.unblock6(fd, key6.groupAddress(), key6.index(), 1039e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.inet6AsByteArray(source)); 1040e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } else { 1041e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera MembershipKeyImpl.Type4 key4 = 1042e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera (MembershipKeyImpl.Type4)key; 1043e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.unblock4(fd, key4.groupAddress(), key4.interfaceAddress(), 1044e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera Net.inet4AsInt(source)); 1045e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 1046e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } catch (IOException ioe) { 1047e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // should not happen 1048e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera throw new AssertionError(ioe); 1049e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 1050e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 1051e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera } 1052e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 105351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected void implCloseSelectableChannel() throws IOException { 105451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 10555ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera // Android-changed: Add CloseGuard support. 10565ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera guard.close(); 105751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (state != ST_KILLED) 105851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nd.preClose(fd); 105951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ResourceManager.afterUdpClose(); 106051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1061e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera // if member of mulitcast group then invalidate all keys 1062e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera if (registry != null) 1063e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera registry.invalidateAll(); 1064e318a0eaa02b186f9f135016e95a6282fe9a83cbShubham Ajmera 106551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long th; 106651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((th = readerThread) != 0) 106751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski NativeThread.signal(th); 106851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((th = writerThread) != 0) 106951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski NativeThread.signal(th); 107051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isRegistered()) 107151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski kill(); 107251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 107351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 107451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 107551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void kill() throws IOException { 107651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (stateLock) { 107751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (state == ST_KILLED) 107851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 107951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (state == ST_UNINITIALIZED) { 108051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski state = ST_KILLED; 108151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 108251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 108351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert !isOpen() && !isRegistered(); 108451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nd.close(fd); 108551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski state = ST_KILLED; 108651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 108751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 108851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10895ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera protected void finalize() throws Throwable { 10905ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera try { 1091ce821390b935d8005f1124002d839b2e0d88368aNarayan Kamath // Android-changed: Add CloseGuard support. 1092ce821390b935d8005f1124002d839b2e0d88368aNarayan Kamath if (guard != null) { 1093ce821390b935d8005f1124002d839b2e0d88368aNarayan Kamath guard.warnIfOpen(); 1094ce821390b935d8005f1124002d839b2e0d88368aNarayan Kamath } 10955ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera // fd is null if constructor threw exception 10965ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera if (fd != null) 10975ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera close(); 10985ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera } finally { 10995ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera super.finalize(); 11005ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera } 110151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 110251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 110351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 110451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Translates native poll revent set into a ready operation set 110551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 110651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean translateReadyOps(int ops, int initialOps, 110751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SelectionKeyImpl sk) { 110851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int intOps = sk.nioInterestOps(); // Do this just once, it synchronizes 110951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int oldOps = sk.nioReadyOps(); 111051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int newOps = initialOps; 111151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1112519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if ((ops & Net.POLLNVAL) != 0) { 111351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // This should only happen if this channel is pre-closed while a 111451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // selection operation is in progress 111551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // ## Throw an error if this channel has not been pre-closed 111651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 111751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 111851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1119519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if ((ops & (Net.POLLERR | Net.POLLHUP)) != 0) { 112051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski newOps = intOps; 112151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sk.nioReadyOps(newOps); 112251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (newOps & ~oldOps) != 0; 112351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 112451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1125519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (((ops & Net.POLLIN) != 0) && 112651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((intOps & SelectionKey.OP_READ) != 0)) 112751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski newOps |= SelectionKey.OP_READ; 112851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1129519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (((ops & Net.POLLOUT) != 0) && 113051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((intOps & SelectionKey.OP_WRITE) != 0)) 113151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski newOps |= SelectionKey.OP_WRITE; 113251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 113351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sk.nioReadyOps(newOps); 113451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (newOps & ~oldOps) != 0; 113551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 113651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 113751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk) { 113851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return translateReadyOps(ops, sk.nioReadyOps(), sk); 113951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 114051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 114151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk) { 114251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return translateReadyOps(ops, 0, sk); 114351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 114451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1145519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera // package-private 1146519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera int poll(int events, long timeout) throws IOException { 1147519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera assert Thread.holdsLock(blockingLock()) && !isBlocking(); 1148519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera 1149519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera synchronized (readLock) { 1150519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera int n = 0; 1151519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera try { 1152519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera begin(); 1153519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera synchronized (stateLock) { 1154519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (!isOpen()) 1155519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera return 0; 1156519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera readerThread = NativeThread.current(); 1157519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } 1158519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera n = Net.poll(fd, events, timeout); 1159519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } finally { 1160519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera readerThread = 0; 1161519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera end(n > 0); 1162519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } 1163519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera return n; 1164519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } 1165519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } 1166519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera 116751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 116851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Translates an interest operation set into a native poll event set 116951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 117051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void translateAndSetInterestOps(int ops, SelectionKeyImpl sk) { 117151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int newOps = 0; 117251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 117351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((ops & SelectionKey.OP_READ) != 0) 1174519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera newOps |= Net.POLLIN; 117551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((ops & SelectionKey.OP_WRITE) != 0) 1176519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera newOps |= Net.POLLOUT; 117751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((ops & SelectionKey.OP_CONNECT) != 0) 1178519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera newOps |= Net.POLLIN; 117951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sk.selector.putEventOps(sk, newOps); 118051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 118151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 118251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public FileDescriptor getFD() { 118351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return fd; 118451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 118551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 118651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int getFDVal() { 118751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return fdVal; 118851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 118951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 119051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 119151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // -- Native methods -- 119251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 119351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static native void initIDs(); 119451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 119551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static native void disconnect0(FileDescriptor fd, boolean isIPv6) 119651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException; 119751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 119851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private native int receive0(FileDescriptor fd, long address, int len, 119951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean connected) 120051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException; 120151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 120251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private native int send0(boolean preferIPv6, FileDescriptor fd, long address, 120351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int len, InetAddress addr, int port) 120451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException; 120551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 120651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static { 120751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski initIDs(); 120851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 120951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 121051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 1211