1 /*
2  * Copyright (c) 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.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /*
25  * @test
26  * @bug 8233307
27  * @library /test/lib
28  * @run main/othervm NoSetNetworkInterface
29  * @run main/othervm -Djava.net.preferIPv4Stack=true NoSetNetworkInterface
30  * @run main/othervm -Djava.net.preferIPv6Addresses=true NoSetNetworkInterface
31  * @run main/othervm -Djdk.net.usePlainDatagramSocketImpl NoSetNetworkInterface
32  * @summary Check that methods that are used to set and get the NetworkInterface
33  *  for a MulticastSocket work as expected. This test also checks that getOption
34  *  returns null correctly when a NetworkInterface has not been set
35  */
36 
37 import jdk.test.lib.NetworkConfiguration;
38 
39 import java.io.IOException;
40 import java.io.UncheckedIOException;
41 import java.net.InetAddress;
42 import java.net.MulticastSocket;
43 import java.net.NetworkInterface;
44 import java.net.StandardSocketOptions;
45 import java.util.Optional;
46 import java.util.function.Predicate;
47 
48 public class NoSetNetworkInterface {
main(String[] args)49     public static void main(String[] args) throws Exception {
50 
51         NetworkConfiguration nc = NetworkConfiguration.probe();
52 
53         // check set and get methods work as expected
54         nc.multicastInterfaces(true).forEach(ni -> {
55             checkSetInterface(ni);
56             checkSetNetworkInterface(ni);
57             checkSetOption(ni);
58         });
59 
60         // Check that dummy NetworkInterface is returned when not set
61         checkDummyNetworkInterface();
62     }
63 
checkSetInterface(NetworkInterface ni)64     public static void checkSetInterface(NetworkInterface ni) {
65         try (MulticastSocket ms = new MulticastSocket()) {
66             Optional<InetAddress> iAddr = ni.inetAddresses()
67                     .filter(Predicate.not(InetAddress::isAnyLocalAddress))
68                     .findFirst();
69             if (iAddr.isPresent()) {
70                 ms.setInterface(iAddr.get());
71                 checkForCorrectNetworkInterface("setInterface", ms, ni);
72             }
73         } catch (IOException e) {
74             throw new UncheckedIOException(e);
75         }
76     }
77 
checkSetNetworkInterface(NetworkInterface ni)78     public static void checkSetNetworkInterface(NetworkInterface ni) {
79         try (MulticastSocket ms = new MulticastSocket()) {
80             ms.setNetworkInterface(ni);
81             checkForCorrectNetworkInterface("setNetworkInterface", ms, ni);
82         } catch (IOException e) {
83             throw new UncheckedIOException(e);
84         }
85     }
86 
checkSetOption(NetworkInterface ni)87     public static void checkSetOption(NetworkInterface ni) {
88         try (MulticastSocket ms = new MulticastSocket()) {
89             ms.setOption(StandardSocketOptions.IP_MULTICAST_IF, ni);
90             checkForCorrectNetworkInterface("setOption", ms, ni);
91         } catch (IOException e) {
92             throw new UncheckedIOException(e);
93         }
94     }
95 
checkForCorrectNetworkInterface(String setterMethod, MulticastSocket ms, NetworkInterface ni)96     public static void checkForCorrectNetworkInterface(String setterMethod,
97                                                        MulticastSocket ms,
98                                                        NetworkInterface ni) throws IOException {
99 
100         // getInterface
101         InetAddress testAddr = ms.getInterface();
102         if (!ni.inetAddresses().anyMatch(i -> i.equals(testAddr))) {
103             throw new RuntimeException(setterMethod + " != getInterface");
104         }
105 
106         // getNetworkInterface
107         if (!ni.equals(ms.getNetworkInterface())) {
108             throw new RuntimeException(setterMethod + " != getNetworkInterface");
109         }
110 
111         // getOption
112         if (!ni.equals(ms.getOption(StandardSocketOptions.IP_MULTICAST_IF))) {
113             throw new RuntimeException(setterMethod + " != getOption");
114         }
115     }
116 
checkDummyNetworkInterface()117     public static void checkDummyNetworkInterface() throws IOException {
118 
119         try(MulticastSocket ms = new MulticastSocket()) {
120 
121             // getOption with no Network Interface set
122             NetworkInterface n0 = ms.getOption(StandardSocketOptions.IP_MULTICAST_IF);
123             if (n0 != null) {
124                 throw new RuntimeException("NetworkInterface should be null");
125             }
126 
127             // getNetworkInterface with no Network Interface set
128             NetworkInterface n1 = ms.getNetworkInterface();
129             if (n1 == null) {
130                 throw new RuntimeException("getNetworkInterface() should not return null");
131             } else if (!((n1.getName().equals("0.0.0.0") || n1.getName().equals("::"))
132                     && (n1.getIndex() == 0)
133                     && (n1.inetAddresses().count() == 1))) {
134 
135                 throw new RuntimeException("Dummy NetworkInterface not returned as expected");
136             }
137 
138             // getInterface with no Network Interface set
139             InetAddress iaddr = ms.getInterface();
140             if (iaddr == null) {
141                 throw new RuntimeException("getInterface() should not return null");
142             } else if (!iaddr.isAnyLocalAddress()) {
143                 throw new RuntimeException("getInterface() should return anyLocalAddress");
144             }
145         }
146     }
147 }
148 
149