1 /* 2 * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package java.net; 26 27 import java.io.IOException; 28 import java.io.FileDescriptor; 29 import sun.net.ResourceManager; 30 31 /** 32 * This class defines the plain DatagramSocketImpl that is used for all 33 * Windows versions lower than Vista. It adds support for IPv6 on 34 * these platforms where available. 35 * 36 * For backward compatibility windows platforms that do not have IPv6 37 * support also use this implementation, and fd1 gets set to null 38 * during socket creation. 39 * 40 * @author Chris Hegarty 41 */ 42 43 class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl 44 { 45 /* Used for IPv6 on Windows only */ 46 private FileDescriptor fd1; 47 48 /* 49 * Needed for ipv6 on windows because we need to know 50 * if the socket was bound to ::0 or 0.0.0.0, when a caller 51 * asks for it. In this case, both sockets are used, but we 52 * don't know whether the caller requested ::0 or 0.0.0.0 53 * and need to remember it here. 54 */ 55 private InetAddress anyLocalBoundAddr=null; 56 57 private int fduse=-1; /* saved between peek() and receive() calls */ 58 59 /* saved between successive calls to receive, if data is detected 60 * on both sockets at same time. To ensure that one socket is not 61 * starved, they rotate using this field 62 */ 63 private int lastfd=-1; 64 65 static { 66 init(); 67 } 68 69 protected synchronized void create() throws SocketException { 70 fd1 = new FileDescriptor(); 71 super.create(); 72 } 73 74 protected synchronized void bind(int lport, InetAddress laddr) 75 throws SocketException { 76 super.bind(lport, laddr); 77 if (laddr.isAnyLocalAddress()) { 78 anyLocalBoundAddr = laddr; 79 } 80 } 81 82 protected synchronized void receive(DatagramPacket p) 83 throws IOException { 84 try { 85 receive0(p); 86 } finally { 87 fduse = -1; 88 } 89 } 90 91 public Object getOption(int optID) throws SocketException { 92 if (isClosed()) { 93 throw new SocketException("Socket Closed"); 94 } 95 96 if (optID == SO_BINDADDR) { 97 if (fd != null && fd1 != null) { 98 return anyLocalBoundAddr; 99 } 100 return socketGetOption(optID); 101 } else 102 return super.getOption(optID); 103 } 104 105 protected boolean isClosed() { 106 return (fd == null && fd1 == null) ? true : false; 107 } 108 109 protected void close() { 110 if (fd != null || fd1 != null) { 111 datagramSocketClose(); 112 ResourceManager.afterUdpClose(); 113 fd = null; 114 fd1 = null; 115 } 116 } 117 118 /* Native methods */ 119 120 protected synchronized native void bind0(int lport, InetAddress laddr) 121 throws SocketException; 122 123 protected native void send(DatagramPacket p) throws IOException; 124 125 protected synchronized native int peek(InetAddress i) throws IOException; 126 127 protected synchronized native int peekData(DatagramPacket p) throws IOException; 128 129 protected synchronized native void receive0(DatagramPacket p) 130 throws IOException; 131 132 protected native void setTimeToLive(int ttl) throws IOException; 133 134 protected native int getTimeToLive() throws IOException; 135 136 protected native void setTTL(byte ttl) throws IOException; 137 138 protected native byte getTTL() throws IOException; 139 140 protected native void join(InetAddress inetaddr, NetworkInterface netIf) 141 throws IOException; 142 143 protected native void leave(InetAddress inetaddr, NetworkInterface netIf) 144 throws IOException; 145 146 protected native void datagramSocketCreate() throws SocketException; 147 148 protected native void datagramSocketClose(); 149 150 protected native void socketSetOption(int opt, Object val) 151 throws SocketException; 152 153 protected native Object socketGetOption(int opt) throws SocketException; 154 155 protected native void connect0(InetAddress address, int port) throws SocketException; 156 157 protected native void disconnect0(int family); 158 159 /** 160 * Perform class load-time initializations. 161 */ 162 private native static void init(); 163 }