1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.fourthline.cling.android;
17
18 import org.fourthline.cling.transport.impl.NetworkAddressFactoryImpl;
19 import org.fourthline.cling.transport.spi.InitializationException;
20
21 import java.lang.reflect.Field;
22 import java.net.Inet4Address;
23 import java.net.Inet6Address;
24 import java.net.InetAddress;
25 import java.net.NetworkInterface;
26 import java.util.logging.Level;
27 import java.util.logging.Logger;
28
29
30
31
32
33
34
35 public class AndroidNetworkAddressFactory extends NetworkAddressFactoryImpl {
36
37 final private static Logger log = Logger.getLogger(AndroidUpnpServiceConfiguration.class.getName());
38
39 public AndroidNetworkAddressFactory(int streamListenPort) {
40 super(streamListenPort);
41 }
42
43 @Override
44 protected boolean requiresNetworkInterface() {
45 return false;
46 }
47
48 @Override
49 protected boolean isUsableAddress(NetworkInterface networkInterface, InetAddress address) {
50 boolean result = super.isUsableAddress(networkInterface, address);
51 if (result) {
52
53
54 String hostName = address.getHostAddress();
55
56 Field field0 = null;
57 Object target = null;
58
59 try {
60
61 try {
62 field0 = InetAddress.class.getDeclaredField("holder");
63 field0.setAccessible(true);
64 target = field0.get(address);
65 field0 = target.getClass().getDeclaredField("hostName");
66 } catch( NoSuchFieldException e ) {
67
68 field0 = InetAddress.class.getDeclaredField("hostName");
69 target = address;
70 }
71
72 if (field0 != null && target != null && hostName != null) {
73 field0.setAccessible(true);
74 field0.set(target, hostName);
75 } else {
76 return false;
77 }
78
79 } catch (Exception ex) {
80 log.log(Level.SEVERE,
81 "Failed injecting hostName to work around Android InetAddress DNS bug: " + address,
82 ex
83 );
84 return false;
85 }
86 }
87 return result;
88 }
89
90 @Override
91 public InetAddress getLocalAddress(NetworkInterface networkInterface, boolean isIPv6, InetAddress remoteAddress) {
92
93 for (InetAddress localAddress : getInetAddresses(networkInterface)) {
94 if (isIPv6 && localAddress instanceof Inet6Address)
95 return localAddress;
96 if (!isIPv6 && localAddress instanceof Inet4Address)
97 return localAddress;
98 }
99 throw new IllegalStateException("Can't find any IPv4 or IPv6 address on interface: " + networkInterface.getDisplayName());
100 }
101
102 @Override
103 protected void discoverNetworkInterfaces() throws InitializationException {
104 try {
105 super.discoverNetworkInterfaces();
106 } catch (Exception ex) {
107
108
109 log.warning("Exception while enumerating network interfaces, trying once more: " + ex);
110 super.discoverNetworkInterfaces();
111 }
112 }
113 }