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:
030: /**
031: * This class defines the plain DatagramSocketImpl that is used for all
032: * Windows versions lower than Vista. It adds support for IPv6 on
033: * these platforms where available.
034: *
035: * For backward compatibility windows platforms that do not have IPv6
036: * support also use this implementation, and fd1 gets set to null
037: * during socket creation.
038: *
039: * @version 1.2, 06/11/07
040: * @author Chris Hegarty
041: */
042:
043: class TwoStacksPlainDatagramSocketImpl extends
044: AbstractPlainDatagramSocketImpl {
045: /* Used for IPv6 on Windows only */
046: private FileDescriptor fd1;
047:
048: /*
049: * Needed for ipv6 on windows because we need to know
050: * if the socket was bound to ::0 or 0.0.0.0, when a caller
051: * asks for it. In this case, both sockets are used, but we
052: * don't know whether the caller requested ::0 or 0.0.0.0
053: * and need to remember it here.
054: */
055: private InetAddress anyLocalBoundAddr = null;
056:
057: private int fduse = -1; /* saved between peek() and receive() calls */
058:
059: /* saved between successive calls to receive, if data is detected
060: * on both sockets at same time. To ensure that one socket is not
061: * starved, they rotate using this field
062: */
063: private int lastfd = -1;
064:
065: static {
066: init();
067: }
068:
069: protected synchronized void create() throws SocketException {
070: fd1 = new FileDescriptor();
071: super .create();
072: }
073:
074: protected synchronized void bind(int lport, InetAddress laddr)
075: throws SocketException {
076: super .bind(lport, laddr);
077: if (laddr.isAnyLocalAddress()) {
078: anyLocalBoundAddr = laddr;
079: }
080: }
081:
082: protected synchronized void receive(DatagramPacket p)
083: throws IOException {
084: try {
085: receive0(p);
086: } finally {
087: fduse = -1;
088: }
089: }
090:
091: public Object getOption(int optID) throws SocketException {
092: if (isClosed()) {
093: throw new SocketException("Socket Closed");
094: }
095:
096: if (optID == SO_BINDADDR) {
097: if (fd != null && fd1 != null) {
098: return anyLocalBoundAddr;
099: }
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: fd = null;
113: fd1 = null;
114: }
115: }
116:
117: /* Native methods */
118:
119: protected synchronized native void bind0(int lport,
120: InetAddress laddr) throws SocketException;
121:
122: protected native void send(DatagramPacket p) throws IOException;
123:
124: protected synchronized native int peek(InetAddress i)
125: throws IOException;
126:
127: protected synchronized native int peekData(DatagramPacket p)
128: throws IOException;
129:
130: protected synchronized native void receive0(DatagramPacket p)
131: throws IOException;
132:
133: protected native void setTimeToLive(int ttl) throws IOException;
134:
135: protected native int getTimeToLive() throws IOException;
136:
137: protected native void setTTL(byte ttl) throws IOException;
138:
139: protected native byte getTTL() throws IOException;
140:
141: protected native void join(InetAddress inetaddr,
142: NetworkInterface netIf) throws IOException;
143:
144: protected native void leave(InetAddress inetaddr,
145: NetworkInterface netIf) throws IOException;
146:
147: protected native void datagramSocketCreate() throws SocketException;
148:
149: protected native void datagramSocketClose();
150:
151: protected native void socketSetOption(int opt, Object val)
152: throws SocketException;
153:
154: protected native Object socketGetOption(int opt)
155: throws SocketException;
156:
157: protected native void connect0(InetAddress address, int port)
158: throws SocketException;
159:
160: protected native void disconnect0(int family);
161:
162: /**
163: * Perform class load-time initializations.
164: */
165: private native static void init();
166: }
|