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
26 package sun.nio.ch;
27
28 import java.io.FileDescriptor;
29 import java.io.IOException;
30 import java.net.*;
31 import java.nio.ByteBuffer;
32 import java.nio.channels.*;
33 import java.nio.channels.spi.*;
34 import java.util.*;
35 import sun.net.ResourceManager;
36
37
38 /**
39 * An implementation of DatagramChannels.
40 */
41
42 class DatagramChannelImpl
43 extends DatagramChannel
44 implements SelChImpl
45 {
46
47 // Used to make native read and write calls
48 private static NativeDispatcher nd = new DatagramDispatcher();
49
50 // Our file descriptor
51 private final FileDescriptor fd;
52
53 // fd value needed for dev/poll. This value will remain valid
54 // even after the value in the file descriptor object has been set to -1
55 private final int fdVal;
177 public SocketAddress getRemoteAddress() throws IOException {
178 synchronized (stateLock) {
179 if (!isOpen())
180 throw new ClosedChannelException();
181 return remoteAddress;
182 }
183 }
184
185 @Override
186 public <T> DatagramChannel setOption(SocketOption<T> name, T value)
187 throws IOException
188 {
189 if (name == null)
190 throw new NullPointerException();
191 if (!supportedOptions().contains(name))
192 throw new UnsupportedOperationException("'" + name + "' not supported");
193
194 synchronized (stateLock) {
195 ensureOpen();
196
197 if (name == StandardSocketOptions.IP_TOS) {
198 // IPv4 only; no-op for IPv6
199 if (family == StandardProtocolFamily.INET) {
200 Net.setSocketOption(fd, family, name, value);
201 }
202 return this;
203 }
204
205 if (name == StandardSocketOptions.IP_MULTICAST_TTL ||
206 name == StandardSocketOptions.IP_MULTICAST_LOOP)
207 {
208 // options are protocol dependent
209 Net.setSocketOption(fd, family, name, value);
210 return this;
211 }
212
213 if (name == StandardSocketOptions.IP_MULTICAST_IF) {
214 if (value == null)
215 throw new IllegalArgumentException("Cannot set IP_MULTICAST_IF to 'null'");
216 NetworkInterface interf = (NetworkInterface)value;
217 if (family == StandardProtocolFamily.INET6) {
218 int index = interf.getIndex();
219 if (index == -1)
220 throw new IOException("Network interface cannot be identified");
221 Net.setInterface6(fd, index);
222 } else {
223 // need IPv4 address to identify interface
224 Inet4Address target = Net.anyInet4Address(interf);
225 if (target == null)
238
239 // remaining options don't need any special handling
240 Net.setSocketOption(fd, Net.UNSPEC, name, value);
241 return this;
242 }
243 }
244
245 @Override
246 @SuppressWarnings("unchecked")
247 public <T> T getOption(SocketOption<T> name)
248 throws IOException
249 {
250 if (name == null)
251 throw new NullPointerException();
252 if (!supportedOptions().contains(name))
253 throw new UnsupportedOperationException("'" + name + "' not supported");
254
255 synchronized (stateLock) {
256 ensureOpen();
257
258 if (name == StandardSocketOptions.IP_TOS) {
259 // IPv4 only; always return 0 on IPv6
260 if (family == StandardProtocolFamily.INET) {
261 return (T) Net.getSocketOption(fd, family, name);
262 } else {
263 return (T) Integer.valueOf(0);
264 }
265 }
266
267 if (name == StandardSocketOptions.IP_MULTICAST_TTL ||
268 name == StandardSocketOptions.IP_MULTICAST_LOOP)
269 {
270 return (T) Net.getSocketOption(fd, family, name);
271 }
272
273 if (name == StandardSocketOptions.IP_MULTICAST_IF) {
274 if (family == StandardProtocolFamily.INET) {
275 int address = Net.getInterface4(fd);
276 if (address == 0)
277 return null; // default interface
278
279 InetAddress ia = Net.inet4FromInt(address);
280 NetworkInterface ni = NetworkInterface.getByInetAddress(ia);
281 if (ni == null)
282 throw new IOException("Unable to map address to interface");
283 return (T) ni;
284 } else {
285 int index = Net.getInterface6(fd);
286 if (index == 0)
287 return null; // default interface
300 }
301
302 // no special handling
303 return (T) Net.getSocketOption(fd, Net.UNSPEC, name);
304 }
305 }
306
307 private static class DefaultOptionsHolder {
308 static final Set<SocketOption<?>> defaultOptions = defaultOptions();
309
310 private static Set<SocketOption<?>> defaultOptions() {
311 HashSet<SocketOption<?>> set = new HashSet<SocketOption<?>>(8);
312 set.add(StandardSocketOptions.SO_SNDBUF);
313 set.add(StandardSocketOptions.SO_RCVBUF);
314 set.add(StandardSocketOptions.SO_REUSEADDR);
315 set.add(StandardSocketOptions.SO_BROADCAST);
316 set.add(StandardSocketOptions.IP_TOS);
317 set.add(StandardSocketOptions.IP_MULTICAST_IF);
318 set.add(StandardSocketOptions.IP_MULTICAST_TTL);
319 set.add(StandardSocketOptions.IP_MULTICAST_LOOP);
320 return Collections.unmodifiableSet(set);
321 }
322 }
323
324 @Override
325 public final Set<SocketOption<?>> supportedOptions() {
326 return DefaultOptionsHolder.defaultOptions;
327 }
328
329 private void ensureOpen() throws ClosedChannelException {
330 if (!isOpen())
331 throw new ClosedChannelException();
332 }
333
334 private SocketAddress sender; // Set by receive0 (## ugh)
335
336 public SocketAddress receive(ByteBuffer dst) throws IOException {
337 if (dst.isReadOnly())
338 throw new IllegalArgumentException("Read-only buffer");
339 if (dst == null)
|
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
26 package sun.nio.ch;
27
28 import java.io.FileDescriptor;
29 import java.io.IOException;
30 import java.net.*;
31 import java.nio.ByteBuffer;
32 import java.nio.channels.*;
33 import java.nio.channels.spi.*;
34 import java.util.*;
35 import sun.net.ResourceManager;
36 import sun.net.ExtendedOptionsImpl;
37
38
39 /**
40 * An implementation of DatagramChannels.
41 */
42
43 class DatagramChannelImpl
44 extends DatagramChannel
45 implements SelChImpl
46 {
47
48 // Used to make native read and write calls
49 private static NativeDispatcher nd = new DatagramDispatcher();
50
51 // Our file descriptor
52 private final FileDescriptor fd;
53
54 // fd value needed for dev/poll. This value will remain valid
55 // even after the value in the file descriptor object has been set to -1
56 private final int fdVal;
178 public SocketAddress getRemoteAddress() throws IOException {
179 synchronized (stateLock) {
180 if (!isOpen())
181 throw new ClosedChannelException();
182 return remoteAddress;
183 }
184 }
185
186 @Override
187 public <T> DatagramChannel setOption(SocketOption<T> name, T value)
188 throws IOException
189 {
190 if (name == null)
191 throw new NullPointerException();
192 if (!supportedOptions().contains(name))
193 throw new UnsupportedOperationException("'" + name + "' not supported");
194
195 synchronized (stateLock) {
196 ensureOpen();
197
198 if (name == StandardSocketOptions.IP_TOS ||
199 name == StandardSocketOptions.IP_MULTICAST_TTL ||
200 name == StandardSocketOptions.IP_MULTICAST_LOOP)
201 {
202 // options are protocol dependent
203 Net.setSocketOption(fd, family, name, value);
204 return this;
205 }
206
207 if (name == StandardSocketOptions.IP_MULTICAST_IF) {
208 if (value == null)
209 throw new IllegalArgumentException("Cannot set IP_MULTICAST_IF to 'null'");
210 NetworkInterface interf = (NetworkInterface)value;
211 if (family == StandardProtocolFamily.INET6) {
212 int index = interf.getIndex();
213 if (index == -1)
214 throw new IOException("Network interface cannot be identified");
215 Net.setInterface6(fd, index);
216 } else {
217 // need IPv4 address to identify interface
218 Inet4Address target = Net.anyInet4Address(interf);
219 if (target == null)
232
233 // remaining options don't need any special handling
234 Net.setSocketOption(fd, Net.UNSPEC, name, value);
235 return this;
236 }
237 }
238
239 @Override
240 @SuppressWarnings("unchecked")
241 public <T> T getOption(SocketOption<T> name)
242 throws IOException
243 {
244 if (name == null)
245 throw new NullPointerException();
246 if (!supportedOptions().contains(name))
247 throw new UnsupportedOperationException("'" + name + "' not supported");
248
249 synchronized (stateLock) {
250 ensureOpen();
251
252 if (name == StandardSocketOptions.IP_TOS ||
253 name == StandardSocketOptions.IP_MULTICAST_TTL ||
254 name == StandardSocketOptions.IP_MULTICAST_LOOP)
255 {
256 return (T) Net.getSocketOption(fd, family, name);
257 }
258
259 if (name == StandardSocketOptions.IP_MULTICAST_IF) {
260 if (family == StandardProtocolFamily.INET) {
261 int address = Net.getInterface4(fd);
262 if (address == 0)
263 return null; // default interface
264
265 InetAddress ia = Net.inet4FromInt(address);
266 NetworkInterface ni = NetworkInterface.getByInetAddress(ia);
267 if (ni == null)
268 throw new IOException("Unable to map address to interface");
269 return (T) ni;
270 } else {
271 int index = Net.getInterface6(fd);
272 if (index == 0)
273 return null; // default interface
286 }
287
288 // no special handling
289 return (T) Net.getSocketOption(fd, Net.UNSPEC, name);
290 }
291 }
292
293 private static class DefaultOptionsHolder {
294 static final Set<SocketOption<?>> defaultOptions = defaultOptions();
295
296 private static Set<SocketOption<?>> defaultOptions() {
297 HashSet<SocketOption<?>> set = new HashSet<SocketOption<?>>(8);
298 set.add(StandardSocketOptions.SO_SNDBUF);
299 set.add(StandardSocketOptions.SO_RCVBUF);
300 set.add(StandardSocketOptions.SO_REUSEADDR);
301 set.add(StandardSocketOptions.SO_BROADCAST);
302 set.add(StandardSocketOptions.IP_TOS);
303 set.add(StandardSocketOptions.IP_MULTICAST_IF);
304 set.add(StandardSocketOptions.IP_MULTICAST_TTL);
305 set.add(StandardSocketOptions.IP_MULTICAST_LOOP);
306 if (ExtendedOptionsImpl.flowSupported()) {
307 set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
308 }
309 return Collections.unmodifiableSet(set);
310 }
311 }
312
313 @Override
314 public final Set<SocketOption<?>> supportedOptions() {
315 return DefaultOptionsHolder.defaultOptions;
316 }
317
318 private void ensureOpen() throws ClosedChannelException {
319 if (!isOpen())
320 throw new ClosedChannelException();
321 }
322
323 private SocketAddress sender; // Set by receive0 (## ugh)
324
325 public SocketAddress receive(ByteBuffer dst) throws IOException {
326 if (dst.isReadOnly())
327 throw new IllegalArgumentException("Read-only buffer");
328 if (dst == null)
|