< prev index next >

src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java

Print this page
rev 57619 : [mq]: MulticastSocketAdaptor
   1 /*
   2  * Copyright (c) 2001, 2019, 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 
  26 package sun.nio.ch;
  27 
  28 import java.io.IOException;

  29 import java.lang.invoke.MethodHandles;
  30 import java.lang.invoke.MethodHandles.Lookup;

  31 import java.lang.invoke.VarHandle;
  32 import java.net.DatagramPacket;
  33 import java.net.DatagramSocket;
  34 import java.net.DatagramSocketImpl;
  35 import java.net.InetAddress;
  36 import java.net.InetSocketAddress;
  37 import java.net.NetworkInterface;

  38 import java.net.SocketAddress;
  39 import java.net.SocketException;
  40 import java.net.SocketOption;
  41 import java.net.StandardSocketOptions;
  42 import java.nio.ByteBuffer;
  43 import java.nio.channels.AlreadyConnectedException;
  44 import java.nio.channels.ClosedChannelException;
  45 import java.nio.channels.DatagramChannel;

  46 import java.security.AccessController;
  47 import java.security.PrivilegedAction;


  48 import java.util.Set;

  49 
  50 import static java.util.concurrent.TimeUnit.MILLISECONDS;
  51 
  52 // Make a datagram-socket channel look like a datagram socket.
  53 //
  54 // The methods in this class are defined in exactly the same order as in
  55 // java.net.DatagramSocket so as to simplify tracking future changes to that
  56 // class.
  57 //
  58 
  59 class DatagramSocketAdaptor
  60     extends DatagramSocket

  61 {
  62     // The channel being adapted
  63     private final DatagramChannelImpl dc;
  64 
  65     // Timeout "option" value for receives
  66     private volatile int timeout;
  67 
  68     // create DatagramSocket with useless impl
  69     private DatagramSocketAdaptor(DatagramChannelImpl dc) {
  70         super(new DummyDatagramSocketImpl());
  71         this.dc = dc;
  72     }
  73 
  74     static DatagramSocket create(DatagramChannelImpl dc) {

  75         return new DatagramSocketAdaptor(dc);



  76     }
  77 
  78     private void connectInternal(SocketAddress remote) throws SocketException {
  79         try {
  80             dc.connect(remote, false); // skips check for already connected
  81         } catch (ClosedChannelException e) {
  82             // ignore
  83         } catch (Exception x) {
  84             Net.translateToSocketException(x);
  85         }
  86     }
  87 
  88     @Override
  89     public void bind(SocketAddress local) throws SocketException {
  90         if (local != null) {
  91             local = Net.asInetSocketAddress(local);
  92         } else {
  93             local = new InetSocketAddress(0);
  94         }
  95         try {


 392     public DatagramChannel getChannel() {
 393         return dc;
 394     }
 395 
 396     @Override
 397     public <T> DatagramSocket setOption(SocketOption<T> name, T value) throws IOException {
 398         dc.setOption(name, value);
 399         return this;
 400     }
 401 
 402     @Override
 403     public <T> T getOption(SocketOption<T> name) throws IOException {
 404         return dc.getOption(name);
 405     }
 406 
 407     @Override
 408     public Set<SocketOption<?>> supportedOptions() {
 409         return dc.supportedOptions();
 410     }
 411 

 412 
 413     /**
 414      * DatagramSocketImpl implementation where all methods throw an error.
 415      */
 416     private static class DummyDatagramSocketImpl extends DatagramSocketImpl {
 417         private static <T> T shouldNotGetHere() {
 418             throw new InternalError("Should not get here");
 419         }
 420 
 421         @Override
 422         protected void create() {
 423             shouldNotGetHere();
 424         }
 425 
 426         @Override
 427         protected void bind(int lport, InetAddress laddr) {
 428             shouldNotGetHere();

 429         }
 430 
 431         @Override
 432         protected void send(DatagramPacket p) {
 433             shouldNotGetHere();





 434         }
 435 
 436         @Override
 437         protected int peek(InetAddress address) {
 438             return shouldNotGetHere();

 439         }
 440 
 441         @Override
 442         protected int peekData(DatagramPacket p) {
 443             return shouldNotGetHere();





 444         }
 445 
 446         @Override
 447         protected void receive(DatagramPacket p) {
 448             shouldNotGetHere();







 449         }
 450 

 451         @Deprecated
 452         protected void setTTL(byte ttl) {
 453             shouldNotGetHere();






 454         }
 455 
 456         @Deprecated
 457         protected byte getTTL() {
 458             return shouldNotGetHere();














 459         }
 460 
 461         @Override
 462         protected void setTimeToLive(int ttl) {
 463             shouldNotGetHere();














 464         }
 465 
 466         @Override
 467         protected int getTimeToLive() {
 468             return shouldNotGetHere();












 469         }
 470 
 471         @Override
 472         protected void join(InetAddress group) {
 473             shouldNotGetHere();













 474         }
 475 
 476         @Override
 477         protected void leave(InetAddress inetaddr) {
 478             shouldNotGetHere();

















 479         }
 480 
 481         @Override
 482         protected void joinGroup(SocketAddress group, NetworkInterface netIf) {
 483             shouldNotGetHere();
 484         }
 485 
 486         @Override
 487         protected void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf) {
 488             shouldNotGetHere();




 489         }
 490 
 491         @Override
 492         protected void close() {
 493             shouldNotGetHere();





 494         }
 495 
 496         @Override
 497         public Object getOption(int optID) {
 498             return shouldNotGetHere();


 499         }
 500 
 501         @Override
 502         public void setOption(int optID, Object value) {
 503             shouldNotGetHere();


 504         }
 505 
 506         @Override
 507         protected <T> void setOption(SocketOption<T> name, T value) {
 508             shouldNotGetHere();












 509         }
 510 
 511         @Override
 512         protected <T> T getOption(SocketOption<T> name) {
 513             return shouldNotGetHere();







 514         }
 515 
 516         @Override
 517         protected Set<SocketOption<?>> supportedOptions() {
 518             return shouldNotGetHere();




















 519         }






 520     }
 521 
 522     /**
 523      * Defines static methods to get/set DatagramPacket fields and workaround
 524      * DatagramPacket deficiencies.
 525      */
 526     private static class DatagramPackets {
 527         private static final VarHandle LENGTH;
 528         private static final VarHandle BUF_LENGTH;
 529         static {
 530             try {
 531                 PrivilegedAction<Lookup> pa = () -> {
 532                     try {
 533                         return MethodHandles.privateLookupIn(DatagramPacket.class, MethodHandles.lookup());
 534                     } catch (Exception e) {
 535                         throw new ExceptionInInitializerError(e);
 536                     }
 537                 };
 538                 MethodHandles.Lookup l = AccessController.doPrivileged(pa);
 539                 LENGTH = l.findVarHandle(DatagramPacket.class, "length", int.class);
 540                 BUF_LENGTH = l.findVarHandle(DatagramPacket.class, "bufLength", int.class);
 541             } catch (Exception e) {
 542                 throw new ExceptionInInitializerError(e);
 543             }
 544         }
 545 
 546         /**
 547          * Sets the DatagramPacket.length field. DatagramPacket.setLength cannot be
 548          * used at this time because it sets both the length and bufLength fields.
 549          */
 550         static void setLength(DatagramPacket p, int value) {
 551             synchronized (p) {
 552                 LENGTH.set(p, value);
 553             }
 554         }
 555 
 556         /**
 557          * Returns the value of the DatagramPacket.bufLength field.
 558          */
 559         static int getBufLength(DatagramPacket p) {
 560             synchronized (p) {
 561                 return (int) BUF_LENGTH.get(p);
 562             }
 563         }
 564     }











































 565 }
   1 /*
   2  * Copyright (c) 2001, 2020, 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 
  26 package sun.nio.ch;
  27 
  28 import java.io.IOException;
  29 import java.lang.invoke.MethodHandle;
  30 import java.lang.invoke.MethodHandles;
  31 import java.lang.invoke.MethodHandles.Lookup;
  32 import java.lang.invoke.MethodType;
  33 import java.lang.invoke.VarHandle;
  34 import java.net.DatagramPacket;
  35 import java.net.DatagramSocket;

  36 import java.net.InetAddress;
  37 import java.net.InetSocketAddress;
  38 import java.net.NetworkInterface;
  39 import java.net.MulticastSocket;
  40 import java.net.SocketAddress;
  41 import java.net.SocketException;
  42 import java.net.SocketOption;
  43 import java.net.StandardSocketOptions;
  44 import java.nio.ByteBuffer;
  45 import java.nio.channels.AlreadyConnectedException;
  46 import java.nio.channels.ClosedChannelException;
  47 import java.nio.channels.DatagramChannel;
  48 import java.nio.channels.MembershipKey;
  49 import java.security.AccessController;
  50 import java.security.PrivilegedAction;
  51 import java.security.PrivilegedExceptionAction;
  52 import java.util.Objects;
  53 import java.util.Set;
  54 import java.util.concurrent.locks.ReentrantLock;
  55 
  56 import static java.util.concurrent.TimeUnit.MILLISECONDS;
  57 
  58 /**
  59  * A multicast datagram socket based on a datagram channel.
  60  *
  61  * This class overrides every public method defined by java.net.DatagramSocket
  62  * and java.net.MulticastSocket. The methods in this class are defined in exactly
  63  * the same order as in java.net.DatagramSocket and java.net.MulticastSocket so
  64  * as to simplify tracking changes.
  65  */
  66 public class DatagramSocketAdaptor
  67     extends MulticastSocket
  68 {
  69     // The channel being adapted
  70     private final DatagramChannelImpl dc;
  71 
  72     // Timeout "option" value for receives
  73     private volatile int timeout;
  74 
  75     private DatagramSocketAdaptor(DatagramChannelImpl dc) throws IOException {
  76         super(/*SocketAddress*/null);

  77         this.dc = dc;
  78     }
  79 
  80     static DatagramSocket create(DatagramChannelImpl dc) {
  81         try {
  82             return new DatagramSocketAdaptor(dc);
  83         } catch (IOException e) {
  84             throw new Error(e);
  85         }
  86     }
  87 
  88     private void connectInternal(SocketAddress remote) throws SocketException {
  89         try {
  90             dc.connect(remote, false); // skips check for already connected
  91         } catch (ClosedChannelException e) {
  92             // ignore
  93         } catch (Exception x) {
  94             Net.translateToSocketException(x);
  95         }
  96     }
  97 
  98     @Override
  99     public void bind(SocketAddress local) throws SocketException {
 100         if (local != null) {
 101             local = Net.asInetSocketAddress(local);
 102         } else {
 103             local = new InetSocketAddress(0);
 104         }
 105         try {


 402     public DatagramChannel getChannel() {
 403         return dc;
 404     }
 405 
 406     @Override
 407     public <T> DatagramSocket setOption(SocketOption<T> name, T value) throws IOException {
 408         dc.setOption(name, value);
 409         return this;
 410     }
 411 
 412     @Override
 413     public <T> T getOption(SocketOption<T> name) throws IOException {
 414         return dc.getOption(name);
 415     }
 416 
 417     @Override
 418     public Set<SocketOption<?>> supportedOptions() {
 419         return dc.supportedOptions();
 420     }
 421 
 422     // -- java.net.MulticastSocket --
 423 
 424     // used to coordinate changing TTL with the deprecated send method
 425     private final ReentrantLock sendLock = new ReentrantLock();





 426 
 427     // cached outgoing interface (for use by setInterface/getInterface)
 428     private final Object outgoingInterfaceLock = new Object();
 429     private NetworkInterface outgoingNetworkInterface;
 430     private InetAddress outgoingInetAddress;
 431 
 432     @Override
 433     @Deprecated
 434     public void setTTL(byte ttl) throws IOException {
 435         setTimeToLive(Byte.toUnsignedInt(ttl));
 436     }
 437 
 438     @Override
 439     public void setTimeToLive(int ttl) throws IOException {
 440         sendLock.lock();
 441         try {
 442             setIntOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl);
 443         } finally {
 444             sendLock.unlock();
 445         }
 446     }
 447 
 448     @Override
 449     @Deprecated
 450     public byte getTTL() throws IOException {
 451         return (byte) getTimeToLive();
 452     }
 453 
 454     @Override
 455     public int getTimeToLive() throws IOException {
 456         sendLock.lock();
 457         try {
 458             return getIntOption(StandardSocketOptions.IP_MULTICAST_TTL);
 459         } finally {
 460             sendLock.unlock();
 461         }
 462     }
 463 
 464     @Override
 465     @Deprecated
 466     public void joinGroup(InetAddress group) throws IOException {
 467         Objects.requireNonNull(group);
 468         try {
 469             joinGroup(new InetSocketAddress(group, 0), null);
 470         } catch (IllegalArgumentException iae) {
 471             // 1-arg joinGroup does not specify IllegalArgumentException
 472             throw (SocketException) new SocketException("joinGroup failed").initCause(iae);
 473         }
 474     }
 475 
 476     @Override
 477     @Deprecated
 478     public void leaveGroup(InetAddress group) throws IOException {
 479         Objects.requireNonNull(group);
 480         try {
 481             leaveGroup(new InetSocketAddress(group, 0), null);
 482         } catch (IllegalArgumentException iae) {
 483             // 1-arg leaveGroup does not specify IllegalArgumentException
 484             throw (SocketException) new SocketException("leaveGroup failed").initCause(iae);
 485         }
 486     }
 487 
 488     /**
 489      * Checks a SocketAddress to ensure that it is a multicast address.
 490      *
 491      * @return the multicast group
 492      * @throws IllegalArgumentException if group is null, an unsupported address
 493      *         type, or an unresolved address
 494      * @throws SocketException if group is not a multicast address
 495      */
 496     private static InetAddress checkGroup(SocketAddress mcastaddr) throws SocketException {
 497         if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
 498             throw new IllegalArgumentException("Unsupported address type");
 499         InetAddress group = ((InetSocketAddress) mcastaddr).getAddress();
 500         if (group == null)
 501             throw new IllegalArgumentException("Unresolved address");
 502         if (!group.isMulticastAddress())
 503             throw new SocketException("Not a multicast address");
 504         return group;
 505     }
 506 
 507     @Override
 508     public void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf) throws IOException {
 509         InetAddress group = checkGroup(mcastaddr);
 510         NetworkInterface ni = (netIf != null) ? netIf : defaultNetworkInterface();
 511         if (isClosed())
 512             throw new SocketException("Socket is closed");
 513         synchronized (this) {
 514             MembershipKey key = dc.findMembership(group, ni);
 515             if (key != null) {
 516                 // already a member but need to check permission anyway
 517                 SecurityManager sm = System.getSecurityManager();
 518                 if (sm != null)
 519                     sm.checkMulticast(group);
 520                 throw new SocketException("Already a member of group");
 521             }
 522             dc.join(group, ni);  // checks permission
 523         }
 524     }
 525 
 526     @Override
 527     public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf) throws IOException {
 528         InetAddress group = checkGroup(mcastaddr);
 529         NetworkInterface ni = (netIf != null) ? netIf : defaultNetworkInterface();
 530         if (isClosed())
 531             throw new SocketException("Socket is closed");
 532         SecurityManager sm = System.getSecurityManager();
 533         if (sm != null)
 534             sm.checkMulticast(group);
 535         synchronized (this) {
 536             MembershipKey key = dc.findMembership(group, ni);
 537             if (key == null)
 538                 throw new SocketException("Not a member of group");
 539             key.drop();
 540         }
 541     }
 542 
 543     @Override
 544     @Deprecated
 545     public void setInterface(InetAddress inf) throws SocketException {
 546         if (inf == null)
 547             throw new SocketException("Invalid value 'null'");
 548         NetworkInterface ni = NetworkInterface.getByInetAddress(inf);
 549         if (ni == null) {
 550             String address = inf.getHostAddress();
 551             throw new SocketException("No network interface with address " + address);
 552         }
 553         synchronized (outgoingInterfaceLock) {
 554             // set interface and update cached values
 555             setNetworkInterface(ni);
 556             outgoingNetworkInterface = ni;
 557             outgoingInetAddress = inf;
 558         }
 559     }
 560 
 561     @Override
 562     @Deprecated
 563     public InetAddress getInterface() throws SocketException {
 564         synchronized (outgoingInterfaceLock) {
 565             NetworkInterface ni = outgoingNetworkInterface();
 566             if (ni != null) {
 567                 if (ni.equals(outgoingNetworkInterface)) {
 568                     return outgoingInetAddress;
 569                 } else {
 570                     // network interface has changed so update cached values
 571                     PrivilegedAction<InetAddress> pa;
 572                     pa = () -> ni.inetAddresses().findFirst().orElse(null);
 573                     InetAddress ia = AccessController.doPrivileged(pa);
 574                     if (ia == null)
 575                         throw new SocketException("Network interface has no IP address");
 576                     outgoingNetworkInterface = ni;
 577                     outgoingInetAddress = ia;
 578                     return ia;
 579                 }
 580             }
 581         }
 582 
 583         // no interface set
 584         return anyInetAddress();

 585     }
 586 
 587     @Override
 588     public void setNetworkInterface(NetworkInterface netIf) throws SocketException {
 589         try {
 590             setOption(StandardSocketOptions.IP_MULTICAST_IF, netIf);
 591         } catch (IOException e) {
 592             Net.translateToSocketException(e);
 593         }
 594     }
 595 
 596     @Override
 597     public NetworkInterface getNetworkInterface() throws SocketException {
 598         NetworkInterface ni = outgoingNetworkInterface();
 599         if (ni == null) {
 600             // return NetworkInterface with index == 0 as placeholder
 601             ni = anyNetworkInterface();
 602         }
 603         return ni;
 604     }
 605 
 606     @Override
 607     @Deprecated
 608     public void setLoopbackMode(boolean disable) throws SocketException {
 609         boolean enable = !disable;
 610         setBooleanOption(StandardSocketOptions.IP_MULTICAST_LOOP, enable);
 611     }
 612 
 613     @Override
 614     @Deprecated
 615     public boolean getLoopbackMode() throws SocketException {
 616         boolean enabled = getBooleanOption(StandardSocketOptions.IP_MULTICAST_LOOP);
 617         return !enabled;
 618     }
 619 
 620     @Override
 621     @Deprecated
 622     public void send(DatagramPacket p, byte ttl) throws IOException {
 623         sendLock.lock();
 624         try {
 625             int oldValue = getTimeToLive();
 626             try {
 627                 setTTL(ttl);
 628                 send(p);
 629             } finally {
 630                 setTimeToLive(oldValue);
 631             }
 632         } finally {
 633             sendLock.unlock();
 634         }
 635     }
 636 
 637     /**
 638      * Returns the outgoing NetworkInterface or null if not set.
 639      */
 640     private NetworkInterface outgoingNetworkInterface() throws SocketException {
 641         try {
 642             return getOption(StandardSocketOptions.IP_MULTICAST_IF);
 643         } catch (IOException e) {
 644             Net.translateToSocketException(e);
 645             return null; // keep compiler happy
 646         }
 647     }
 648 
 649     /**
 650      * Returns the default NetworkInterface to use when joining or leaving a
 651      * multicast group and a network interface is not specified.
 652      * This method will return the outgoing NetworkInterface if set, otherwise
 653      * the result of NetworkInterface.getDefault(), otherwise a NetworkInterface
 654      * with index == 0 as a placeholder for "any network interface".
 655      */
 656     private NetworkInterface defaultNetworkInterface() throws SocketException {
 657         NetworkInterface ni = outgoingNetworkInterface();
 658         if (ni == null)
 659             ni = NetworkInterfaces.getDefault();   // macOS
 660         if (ni == null)
 661             ni = anyNetworkInterface();
 662         return ni;
 663     }
 664 
 665     /**
 666      * Returns the placeholder for "any network interface", its index is 0.
 667      */
 668     private NetworkInterface anyNetworkInterface() {
 669         InetAddress[] addrs = new InetAddress[1];
 670         addrs[0] = anyInetAddress();
 671         return NetworkInterfaces.newNetworkInterface(addrs[0].getHostName(), 0, addrs);
 672     }
 673 
 674     /**
 675      * Returns the InetAddress representing anyLocalAddress.
 676      */
 677     private InetAddress anyInetAddress() {
 678         return new InetSocketAddress(0).getAddress();
 679     }
 680 
 681     /**
 682      * Defines static methods to get/set DatagramPacket fields and workaround
 683      * DatagramPacket deficiencies.
 684      */
 685     private static class DatagramPackets {
 686         private static final VarHandle LENGTH;
 687         private static final VarHandle BUF_LENGTH;
 688         static {
 689             try {
 690                 PrivilegedExceptionAction<Lookup> pa = () ->
 691                     MethodHandles.privateLookupIn(DatagramPacket.class, MethodHandles.lookup());





 692                 MethodHandles.Lookup l = AccessController.doPrivileged(pa);
 693                 LENGTH = l.findVarHandle(DatagramPacket.class, "length", int.class);
 694                 BUF_LENGTH = l.findVarHandle(DatagramPacket.class, "bufLength", int.class);
 695             } catch (Exception e) {
 696                 throw new ExceptionInInitializerError(e);
 697             }
 698         }
 699 
 700         /**
 701          * Sets the DatagramPacket.length field. DatagramPacket.setLength cannot be
 702          * used at this time because it sets both the length and bufLength fields.
 703          */
 704         static void setLength(DatagramPacket p, int value) {
 705             synchronized (p) {
 706                 LENGTH.set(p, value);
 707             }
 708         }
 709 
 710         /**
 711          * Returns the value of the DatagramPacket.bufLength field.
 712          */
 713         static int getBufLength(DatagramPacket p) {
 714             synchronized (p) {
 715                 return (int) BUF_LENGTH.get(p);
 716             }
 717         }
 718     }
 719 
 720     /**
 721      * Defines static methods to invoke non-public NetworkInterface methods.
 722      */
 723     private static class NetworkInterfaces {
 724         static final MethodHandle GET_DEFAULT;
 725         static final MethodHandle CONSTRUCTOR;
 726         static {
 727             try {
 728                 PrivilegedExceptionAction<Lookup> pa = () ->
 729                     MethodHandles.privateLookupIn(NetworkInterface.class, MethodHandles.lookup());
 730                 MethodHandles.Lookup l = AccessController.doPrivileged(pa);
 731                 MethodType methodType = MethodType.methodType(NetworkInterface.class);
 732                 GET_DEFAULT = l.findStatic(NetworkInterface.class, "getDefault", methodType);
 733                 methodType = MethodType.methodType(void.class, String.class, int.class, InetAddress[].class);
 734                 CONSTRUCTOR = l.findConstructor(NetworkInterface.class, methodType);
 735             } catch (Exception e) {
 736                 throw new ExceptionInInitializerError(e);
 737             }
 738         }
 739 
 740         /**
 741          * Returns the default network interface or null.
 742          */
 743         static NetworkInterface getDefault() {
 744             try {
 745                 return (NetworkInterface) GET_DEFAULT.invokeExact();
 746             } catch (Throwable e) {
 747                 throw new InternalError(e);
 748             }
 749         }
 750 
 751         /**
 752          * Creates a NetworkInterface with the given name index and addresses.
 753          */
 754         static NetworkInterface newNetworkInterface(String name, int index, InetAddress[] addrs) {
 755             try {
 756                 return (NetworkInterface) CONSTRUCTOR.invoke(name, index, addrs);
 757             } catch (Throwable e) {
 758                 throw new InternalError(e);
 759             }
 760         }
 761     }
 762 }
< prev index next >