1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.newsclub.net.unix;
19
20 import java.io.IOException;
21 import java.net.InetAddress;
22 import java.net.Socket;
23 import java.net.SocketAddress;
24 import java.net.SocketException;
25 import java.util.Objects;
26
27 import javax.net.SocketFactory;
28
29 import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
30
31
32
33
34
35
36
37
38
39
40 @SuppressFBWarnings("UNENCRYPTED_SOCKET")
41 public abstract class AFSocketFactory<A extends AFSocketAddress> extends SocketFactory implements
42 AFSocketAddressFromHostname<A> {
43
44 private final Class<? extends AFSocketAddress> socketAddressClass;
45
46
47
48
49
50
51 protected AFSocketFactory(Class<? extends AFSocketAddress> socketAddressClass) {
52 super();
53 this.socketAddressClass = socketAddressClass;
54 }
55
56
57
58
59
60
61
62
63
64
65
66 protected final boolean isInetAddressSupported(InetAddress address) {
67 return address != null && isHostnameSupported(address.getHostName());
68 }
69
70 @Override
71 public abstract Socket createSocket() throws SocketException;
72
73
74
75
76
77
78
79
80 protected abstract Socket connectTo(A addr) throws IOException;
81
82 @SuppressWarnings("unchecked")
83 @SuppressFBWarnings("UNENCRYPTED_SOCKET")
84 private Socket connectTo(SocketAddress addr) throws IOException {
85 if (AFSocketAddress.canMap(addr, socketAddressClass)) {
86 return connectTo((A) AFSocketAddress.mapOrFail(addr, socketAddressClass));
87 } else {
88 Socket sock = new Socket();
89 sock.connect(addr);
90 return sock;
91 }
92 }
93
94 @Override
95 public final Socket createSocket(String host, int port) throws IOException {
96 if (!isHostnameSupported(host)) {
97 throw new SocketException("Unsupported hostname");
98 }
99 if (port < 0) {
100 throw new IllegalArgumentException("Illegal port");
101 }
102
103 SocketAddress socketAddress = addressFromHost(host, port);
104 return connectTo(socketAddress);
105 }
106
107 @Override
108 public final Socket createSocket(String host, int port, InetAddress localHost, int localPort)
109 throws IOException {
110 if (!isHostnameSupported(host)) {
111 throw new SocketException("Unsupported hostname");
112 }
113 if (localPort < 0) {
114 throw new IllegalArgumentException("Illegal local port");
115 }
116
117 return createSocket(host, port);
118 }
119
120 @Override
121 public final Socket createSocket(InetAddress address, int port) throws IOException {
122 if (!isInetAddressSupported(address)) {
123 throw new SocketException("Unsupported address");
124 }
125 String hostname = address.getHostName();
126 if (!isHostnameSupported(hostname)) {
127 throw new SocketException("Unsupported hostname");
128 }
129 return createSocket(hostname, port);
130 }
131
132 @Override
133 public final Socket createSocket(InetAddress address, int port, InetAddress localAddress,
134 int localPort) throws IOException {
135 if (!isInetAddressSupported(address)) {
136 throw new SocketException("Unsupported address");
137 }
138 if (localPort < 0) {
139 throw new IllegalArgumentException("Illegal local port");
140 }
141
142 return createSocket(address, port);
143 }
144
145
146
147
148 public static final class FixedAddressSocketFactory extends AFSocketFactory<AFSocketAddress> {
149 private final SocketAddress forceAddr;
150
151
152
153
154
155
156 public FixedAddressSocketFactory(SocketAddress address) {
157 super(AFSocketAddress.class);
158 this.forceAddr = Objects.requireNonNull(address);
159 }
160
161 @Override
162 public boolean isHostnameSupported(String host) {
163 return true;
164 }
165
166 @Override
167 public SocketAddress addressFromHost(String host, int port) throws SocketException {
168 return forceAddr;
169 }
170
171 @Override
172 public Socket createSocket() throws SocketException {
173 try {
174 if (AFSocketAddress.canMap(forceAddr)) {
175 AFSocket<?> socket = AFSocketAddress.mapOrFail(forceAddr).getAddressFamily().newSocket();
176 socket.forceConnectAddress(forceAddr);
177 return socket;
178 } else {
179 return new Socket() {
180 @Override
181 public void connect(SocketAddress endpoint) throws IOException {
182 super.connect(forceAddr);
183 }
184
185 @Override
186 public void connect(SocketAddress endpoint, int timeout) throws IOException {
187 super.connect(forceAddr, timeout);
188 }
189 };
190 }
191 } catch (SocketException e) {
192 throw e;
193 } catch (IOException e) {
194 throw (SocketException) new SocketException().initCause(e);
195 }
196 }
197
198 @Override
199 protected Socket connectTo(AFSocketAddress addr) throws IOException {
200 Socket sock = createSocket();
201 sock.connect(forceAddr);
202 return sock;
203 }
204 }
205 }