1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.waarp.ftp.core.utils;
21
22 import io.netty.channel.Channel;
23 import org.waarp.common.crypto.ssl.WaarpSslUtility;
24 import org.waarp.common.logging.SysErrLogger;
25 import org.waarp.common.logging.WaarpLogger;
26 import org.waarp.common.logging.WaarpLoggerFactory;
27 import org.waarp.common.utility.WaarpShutdownHook;
28 import org.waarp.ftp.core.config.FtpConfiguration;
29
30 import java.net.InetAddress;
31 import java.net.InetSocketAddress;
32 import java.net.UnknownHostException;
33 import java.util.Timer;
34
35
36
37
38 public class FtpChannelUtils implements Runnable {
39
40
41
42 private static final WaarpLogger logger =
43 WaarpLoggerFactory.getLogger(FtpChannelUtils.class);
44
45
46
47
48
49
50
51
52 public static InetAddress getRemoteInetAddress(final Channel channel) {
53 InetSocketAddress socketAddress =
54 (InetSocketAddress) channel.remoteAddress();
55 if (socketAddress == null) {
56 socketAddress = new InetSocketAddress(20);
57 }
58 return socketAddress.getAddress();
59 }
60
61
62
63
64
65
66
67
68 public static InetAddress getLocalInetAddress(final Channel channel) {
69 final InetSocketAddress socketAddress =
70 (InetSocketAddress) channel.localAddress();
71 return socketAddress.getAddress();
72 }
73
74
75
76
77
78
79
80
81 public static InetSocketAddress getRemoteInetSocketAddress(
82 final Channel channel) {
83 return (InetSocketAddress) channel.remoteAddress();
84 }
85
86
87
88
89
90
91
92
93 public static InetSocketAddress getLocalInetSocketAddress(
94 final Channel channel) {
95 return (InetSocketAddress) channel.localAddress();
96 }
97
98
99
100
101
102
103
104
105 public static InetSocketAddress getInetSocketAddress(final String arg) {
106 final String[] elements = arg.split(",");
107 if (elements.length != 6) {
108 return null;
109 }
110 final byte[] address = { 0, 0, 0, 0 };
111 final int[] iElements = new int[6];
112 for (int i = 0; i < 6; i++) {
113 try {
114 iElements[i] = Integer.parseInt(elements[i]);
115 } catch (final NumberFormatException e) {
116 return null;
117 }
118 if (iElements[i] < 0 || iElements[i] > 255) {
119 return null;
120 }
121 }
122 for (int i = 0; i < 4; i++) {
123 address[i] = (byte) iElements[i];
124 }
125 final int port = iElements[4] << 8 | iElements[5];
126 final InetAddress inetAddress;
127 try {
128 inetAddress = InetAddress.getByAddress(address);
129 } catch (final UnknownHostException e) {
130 return null;
131 }
132 return new InetSocketAddress(inetAddress, port);
133 }
134
135
136
137
138
139
140
141
142
143 public static String getAddress(final String address, final int port) {
144 return address.replace('.', ',') + ',' + (port >> 8) + ',' + (port & 0xFF);
145 }
146
147
148
149
150
151
152
153
154 public static String getAddress(final InetSocketAddress address) {
155 final InetAddress servAddr = address.getAddress();
156 final int servPort = address.getPort();
157 return servAddr.getHostAddress().replace('.', ',') + ',' + (servPort >> 8) +
158 ',' + (servPort & 0xFF);
159 }
160
161
162
163
164
165
166
167
168
169 public static InetSocketAddress get2428InetSocketAddress(final String arg) {
170
171
172 if (arg == null || arg.length() == 0) {
173
174 return null;
175 }
176 final String delim = arg.substring(0, 1);
177 final String[] infos = arg.split('\\' + delim);
178 if (infos.length != 3 && infos.length != 4) {
179
180 logger.error("Bad address format: " + infos.length);
181 return null;
182 }
183 int start = 0;
184 if (infos.length == 4) {
185 start = 1;
186 }
187 boolean isIPV4 = true;
188 if ("1".equals(infos[start])) {
189 isIPV4 = true;
190 } else if ("2".equals(infos[start])) {
191 isIPV4 = false;
192 } else {
193
194 logger.error("Bad 1 or 2 format in address: " + infos[start]);
195 return null;
196 }
197 start++;
198 final InetAddress inetAddress;
199 if (isIPV4) {
200
201 try {
202 inetAddress = InetAddress.getByName(infos[start]);
203 } catch (final UnknownHostException e) {
204 logger.error("Bad IPV4 format: {}", e.getMessage());
205 return null;
206 }
207 } else {
208
209 try {
210 inetAddress = InetAddress.getByName(infos[start]);
211 } catch (final UnknownHostException e) {
212 logger.error("Bad IPV6 format: {}", e.getMessage());
213 return null;
214 }
215 }
216 start++;
217 final int port;
218 try {
219 port = Integer.parseInt(infos[start]);
220 } catch (final NumberFormatException e) {
221 logger.error("Bad port number format: " + infos[start]);
222 return null;
223 }
224 return new InetSocketAddress(inetAddress, port);
225 }
226
227
228
229
230
231
232
233
234 public static String get2428Address(final InetSocketAddress address) {
235 final InetAddress servAddr = address.getAddress();
236 final int servPort = address.getPort();
237 final StringBuilder builder = new StringBuilder();
238 final String hostaddress = servAddr.getHostAddress();
239 builder.append('|');
240 if (hostaddress.contains(":")) {
241 builder.append('2');
242 } else {
243 builder.append('1');
244 }
245 builder.append('|').append(hostaddress).append('|').append(servPort)
246 .append('|');
247 return builder.toString();
248 }
249
250
251
252
253
254
255
256
257 static int terminateCommandChannels(final FtpConfiguration configuration) {
258 final int result =
259 configuration.getFtpInternalConfiguration().getCommandChannelGroup()
260 .size();
261 configuration.getFtpInternalConfiguration().getCommandChannelGroup()
262 .close();
263 return result;
264 }
265
266
267
268
269
270
271
272
273 private static int terminateDataChannels(
274 final FtpConfiguration configuration) {
275 final int result =
276 configuration.getFtpInternalConfiguration().getDataChannelGroup()
277 .size();
278 configuration.getFtpInternalConfiguration().getDataChannelGroup().close();
279 return result;
280 }
281
282
283
284
285
286
287
288
289 public static int nbCommandChannels(final FtpConfiguration configuration) {
290 return configuration.getFtpInternalConfiguration().getCommandChannelGroup()
291 .size();
292 }
293
294
295
296
297
298
299
300
301 public static int nbDataChannels(final FtpConfiguration configuration) {
302 return configuration.getFtpInternalConfiguration().getDataChannelGroup()
303 .size();
304 }
305
306
307
308
309
310
311
312
313 public static int validCommandChannels(final FtpConfiguration configuration) {
314 int result = 0;
315 Channel channel;
316 for (final Channel value : configuration.getFtpInternalConfiguration()
317 .getCommandChannelGroup()) {
318 channel = value;
319 if (channel.parent() != null) {
320
321 if (channel.isActive()) {
322
323 result++;
324 } else {
325 WaarpSslUtility.closingSslChannel(channel);
326 }
327 } else {
328
329 result++;
330 }
331 }
332 return result;
333 }
334
335
336
337
338
339
340 protected static void exit(final FtpConfiguration configuration) {
341 configuration.setShutdown(true);
342 final long delay = configuration.getTimeoutCon() / 2;
343 logger.warn("Exit: Give a delay of " + delay + " ms");
344 configuration.inShutdownProcess();
345 try {
346 Thread.sleep(delay);
347 } catch (final InterruptedException e) {
348 SysErrLogger.FAKE_LOGGER.ignoreLog(e);
349 }
350 final Timer timer = new Timer(true);
351 final FtpTimerTask timerTask = new FtpTimerTask(FtpTimerTask.TIMER_CONTROL);
352 timerTask.setConfiguration(configuration);
353 timer.schedule(timerTask, delay / 2);
354 configuration.getFtpInternalConfiguration().getGlobalTrafficShapingHandler()
355 .release();
356 configuration.releaseResources();
357 logger.info("Exit Shutdown Data");
358 terminateDataChannels(configuration);
359 logger.warn("Exit end of Data Shutdown");
360 }
361
362
363
364
365
366
367
368 public static void teminateServer(final FtpConfiguration configuration) {
369 FtpShutdownHook.configuration = configuration;
370 WaarpShutdownHook.terminate(false);
371 }
372
373
374
375
376
377
378
379 public static void addCommandChannel(final Channel channel,
380 final FtpConfiguration configuration) {
381 configuration.getFtpInternalConfiguration().getCommandChannelGroup()
382 .add(channel);
383 }
384
385
386
387
388
389
390
391 public static void addDataChannel(final Channel channel,
392 final FtpConfiguration configuration) {
393 configuration.getFtpInternalConfiguration().getDataChannelGroup()
394 .add(channel);
395 }
396
397
398
399
400 private final FtpConfiguration configuration;
401
402 public FtpChannelUtils(final FtpConfiguration configuration) {
403 this.configuration = configuration;
404 }
405
406 @Override
407 public void run() {
408 exit(configuration);
409 }
410
411 }