blob: 8a4fd5df5018872d64b94a0aeb858baa1f22d823 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2007 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25package java.net;
26
27import java.io.IOException;
28import java.io.FileDescriptor;
29
30/**
31 * This class defines the plain DatagramSocketImpl that is used for all
32 * Windows versions lower than Vista. It adds support for IPv6 on
33 * these platforms where available.
34 *
35 * For backward compatibility windows platforms that do not have IPv6
36 * support also use this implementation, and fd1 gets set to null
37 * during socket creation.
38 *
39 * @author Chris Hegarty
40 */
41
42class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
43{
44 /* Used for IPv6 on Windows only */
45 private FileDescriptor fd1;
46
47 /*
48 * Needed for ipv6 on windows because we need to know
49 * if the socket was bound to ::0 or 0.0.0.0, when a caller
50 * asks for it. In this case, both sockets are used, but we
51 * don't know whether the caller requested ::0 or 0.0.0.0
52 * and need to remember it here.
53 */
54 private InetAddress anyLocalBoundAddr=null;
55
56 private int fduse=-1; /* saved between peek() and receive() calls */
57
58 /* saved between successive calls to receive, if data is detected
59 * on both sockets at same time. To ensure that one socket is not
60 * starved, they rotate using this field
61 */
62 private int lastfd=-1;
63
64 static {
65 init();
66 }
67
68 protected synchronized void create() throws SocketException {
69 fd1 = new FileDescriptor();
70 super.create();
71 }
72
73 protected synchronized void bind(int lport, InetAddress laddr)
74 throws SocketException {
75 super.bind(lport, laddr);
76 if (laddr.isAnyLocalAddress()) {
77 anyLocalBoundAddr = laddr;
78 }
79 }
80
81 protected synchronized void receive(DatagramPacket p)
82 throws IOException {
83 try {
84 receive0(p);
85 } finally {
86 fduse = -1;
87 }
88 }
89
90 public Object getOption(int optID) throws SocketException {
91 if (isClosed()) {
92 throw new SocketException("Socket Closed");
93 }
94
95 if (optID == SO_BINDADDR) {
96 if (fd != null && fd1 != null) {
97 return anyLocalBoundAddr;
98 }
99 return socketGetOption(optID);
100 } else
101 return super.getOption(optID);
102 }
103
104 protected boolean isClosed() {
105 return (fd == null && fd1 == null) ? true : false;
106 }
107
108 protected void close() {
109 if (fd != null || fd1 != null) {
110 datagramSocketClose();
111 fd = null;
112 fd1 = null;
113 }
114 }
115
116 /* Native methods */
117
118 protected synchronized native void bind0(int lport, InetAddress laddr)
119 throws SocketException;
120
121 protected native void send(DatagramPacket p) throws IOException;
122
123 protected synchronized native int peek(InetAddress i) throws IOException;
124
125 protected synchronized native int peekData(DatagramPacket p) throws IOException;
126
127 protected synchronized native void receive0(DatagramPacket p)
128 throws IOException;
129
130 protected native void setTimeToLive(int ttl) throws IOException;
131
132 protected native int getTimeToLive() throws IOException;
133
134 protected native void setTTL(byte ttl) throws IOException;
135
136 protected native byte getTTL() throws IOException;
137
138 protected native void join(InetAddress inetaddr, NetworkInterface netIf)
139 throws IOException;
140
141 protected native void leave(InetAddress inetaddr, NetworkInterface netIf)
142 throws IOException;
143
144 protected native void datagramSocketCreate() throws SocketException;
145
146 protected native void datagramSocketClose();
147
148 protected native void socketSetOption(int opt, Object val)
149 throws SocketException;
150
151 protected native Object socketGetOption(int opt) throws SocketException;
152
153 protected native void connect0(InetAddress address, int port) throws SocketException;
154
155 protected native void disconnect0(int family);
156
157 /**
158 * Perform class load-time initializations.
159 */
160 private native static void init();
161}