001: /*
002: * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025: package java.net;
026:
027: import java.io.IOException;
028: import java.io.FileDescriptor;
029: import sun.misc.SharedSecrets;
030: import sun.misc.JavaIOFileDescriptorAccess;
031:
032: /**
033: * This class defines the plain DatagramSocketImpl that is used on
034: * Windows platforms greater than or equal to Windows Vista. These
035: * platforms have a dual layer TCP/IP stack and can handle both IPv4
036: * and IPV6 through a single file descriptor.
037: * <p>
038: * Note: Multicasting on a dual layer TCP/IP stack is always done with
039: * TwoStacksPlainDatagramSocketImpl. This is to overcome the lack
040: * of behavior defined for multicasting over a dual layer socket by the RFC.
041: *
042: * @version 1.2, 06/11/07
043: * @author Chris Hegarty
044: */
045:
046: class DualStackPlainDatagramSocketImpl extends
047: AbstractPlainDatagramSocketImpl {
048: static JavaIOFileDescriptorAccess fdAccess = SharedSecrets
049: .getJavaIOFileDescriptorAccess();
050:
051: protected void datagramSocketCreate() throws SocketException {
052: if (fd == null)
053: throw new SocketException("Socket closed");
054:
055: int newfd = socketCreate(false /* v6Only */);
056:
057: fdAccess.set(fd, newfd);
058: }
059:
060: protected synchronized void bind0(int lport, InetAddress laddr)
061: throws SocketException {
062: int nativefd = checkAndReturnNativeFD();
063:
064: if (laddr == null)
065: throw new NullPointerException("argument address");
066:
067: socketBind(nativefd, laddr, lport);
068: if (lport == 0) {
069: localPort = socketLocalPort(nativefd);
070: } else {
071: localPort = lport;
072: }
073: }
074:
075: protected synchronized int peek(InetAddress address)
076: throws IOException {
077: int nativefd = checkAndReturnNativeFD();
078:
079: if (address == null)
080: throw new NullPointerException("Null address in peek()");
081:
082: // Use peekData()
083: DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1);
084: int peekPort = peekData(peekPacket);
085: address = peekPacket.getAddress();
086: return peekPort;
087: }
088:
089: protected synchronized int peekData(DatagramPacket p)
090: throws IOException {
091: int nativefd = checkAndReturnNativeFD();
092:
093: if (p == null)
094: throw new NullPointerException("packet");
095: if (p.getData() == null)
096: throw new NullPointerException("packet buffer");
097:
098: return socketReceiveOrPeekData(nativefd, p, timeout, connected,
099: true /*peek*/);
100: }
101:
102: protected synchronized void receive0(DatagramPacket p)
103: throws IOException {
104: int nativefd = checkAndReturnNativeFD();
105:
106: if (p == null)
107: throw new NullPointerException("packet");
108: if (p.getData() == null)
109: throw new NullPointerException("packet buffer");
110:
111: socketReceiveOrPeekData(nativefd, p, timeout, connected, false /*receive*/);
112: }
113:
114: protected void send(DatagramPacket p) throws IOException {
115: int nativefd = checkAndReturnNativeFD();
116:
117: if (p == null)
118: throw new NullPointerException("null packet");
119:
120: if (p.getAddress() == null || p.getData() == null)
121: throw new NullPointerException(
122: "null address || null buffer");
123:
124: socketSend(nativefd, p.getData(), p.getOffset(), p.getLength(),
125: p.getAddress(), p.getPort(), connected);
126: }
127:
128: protected void connect0(InetAddress address, int port)
129: throws SocketException {
130: int nativefd = checkAndReturnNativeFD();
131:
132: if (address == null)
133: throw new NullPointerException("address");
134:
135: socketConnect(nativefd, address, port);
136: }
137:
138: protected void disconnect0(int family /*unused*/) {
139: if (fd == null || !fd.valid())
140: return; // disconnect doesn't throw any exceptions
141:
142: socketDisconnect(fdAccess.get(fd));
143: }
144:
145: protected void datagramSocketClose() {
146: if (fd == null || !fd.valid())
147: return; // close doesn't throw any exceptions
148:
149: socketClose(fdAccess.get(fd));
150: fdAccess.set(fd, -1);
151: }
152:
153: protected void socketSetOption(int opt, Object val)
154: throws SocketException {
155: int nativefd = checkAndReturnNativeFD();
156:
157: int optionValue = 0;
158:
159: switch (opt) {
160: case IP_TOS:
161: case SO_RCVBUF:
162: case SO_SNDBUF:
163: optionValue = ((Integer) val).intValue();
164: break;
165: case SO_REUSEADDR:
166: case SO_BROADCAST:
167: optionValue = ((Boolean) val).booleanValue() ? 1 : 0;
168: break;
169: default: /* shouldn't get here */
170: throw new SocketException("Option not supported");
171: }
172:
173: socketSetIntOption(nativefd, opt, optionValue);
174: }
175:
176: protected Object socketGetOption(int opt) throws SocketException {
177: int nativefd = checkAndReturnNativeFD();
178:
179: // SO_BINDADDR is not a socket option.
180: if (opt == SO_BINDADDR) {
181: return socketLocalAddress(nativefd);
182: }
183:
184: int value = socketGetIntOption(nativefd, opt);
185: Object returnValue = null;
186:
187: switch (opt) {
188: case SO_REUSEADDR:
189: case SO_BROADCAST:
190: returnValue = (value == 0) ? Boolean.FALSE : Boolean.TRUE;
191: break;
192: case IP_TOS:
193: case SO_RCVBUF:
194: case SO_SNDBUF:
195: returnValue = new Integer(value);
196: break;
197: default: /* shouldn't get here */
198: throw new SocketException("Option not supported");
199: }
200:
201: return returnValue;
202: }
203:
204: /* Multicast specific methods.
205: * Multicasting on a dual layer TCP/IP stack is always done with
206: * TwoStacksPlainDatagramSocketImpl. This is to overcome the lack
207: * of behavior defined for multicasting over a dual layer socket by the RFC.
208: */
209: protected void join(InetAddress inetaddr, NetworkInterface netIf)
210: throws IOException {
211: throw new IOException("Method not implemented!");
212: }
213:
214: protected void leave(InetAddress inetaddr, NetworkInterface netIf)
215: throws IOException {
216: throw new IOException("Method not implemented!");
217: }
218:
219: protected void setTimeToLive(int ttl) throws IOException {
220: throw new IOException("Method not implemented!");
221: }
222:
223: protected int getTimeToLive() throws IOException {
224: throw new IOException("Method not implemented!");
225: }
226:
227: protected void setTTL(byte ttl) throws IOException {
228: throw new IOException("Method not implemented!");
229: }
230:
231: protected byte getTTL() throws IOException {
232: throw new IOException("Method not implemented!");
233: }
234:
235: /* END Multicast specific methods */
236:
237: private int checkAndReturnNativeFD() throws SocketException {
238: if (fd == null || !fd.valid())
239: throw new SocketException("Socket closed");
240:
241: return fdAccess.get(fd);
242: }
243:
244: /* Native methods */
245:
246: private static native void initIDs();
247:
248: private static native int socketCreate(boolean v6Only);
249:
250: private static native void socketBind(int fd,
251: InetAddress localAddress, int localport)
252: throws SocketException;
253:
254: private static native void socketConnect(int fd,
255: InetAddress address, int port) throws SocketException;
256:
257: private static native void socketDisconnect(int fd);
258:
259: private static native void socketClose(int fd);
260:
261: private static native int socketLocalPort(int fd)
262: throws SocketException;
263:
264: private static native Object socketLocalAddress(int fd)
265: throws SocketException;
266:
267: private static native int socketReceiveOrPeekData(int fd,
268: DatagramPacket packet, int timeout, boolean connected,
269: boolean peek) throws IOException;
270:
271: private static native void socketSend(int fd, byte[] data,
272: int offset, int length, InetAddress address, int port,
273: boolean connected) throws IOException;
274:
275: private static native void socketSetIntOption(int fd, int cmd,
276: int optionValue) throws SocketException;
277:
278: private static native int socketGetIntOption(int fd, int cmd)
279: throws SocketException;
280: }
|