1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package goldengate.ftp.core.data;
22
23 import goldengate.common.command.exception.Reply425Exception;
24 import goldengate.ftp.core.command.FtpArgumentCode;
25 import goldengate.ftp.core.command.FtpArgumentCode.TransferMode;
26 import goldengate.ftp.core.command.FtpArgumentCode.TransferStructure;
27 import goldengate.ftp.core.command.FtpArgumentCode.TransferType;
28 import goldengate.ftp.core.config.FtpConfiguration;
29 import goldengate.ftp.core.data.handler.DataNetworkHandler;
30 import goldengate.ftp.core.exception.FtpNoConnectionException;
31 import goldengate.ftp.core.session.FtpSession;
32 import goldengate.ftp.core.utils.FtpChannelUtils;
33
34 import java.net.InetAddress;
35 import java.net.InetSocketAddress;
36
37 import org.jboss.netty.channel.Channel;
38 import org.jboss.netty.channel.Channels;
39
40
41
42
43
44
45
46
47 public class FtpDataAsyncConn {
48
49
50
51 private final FtpSession session;
52
53
54
55
56 private DataNetworkHandler dataNetworkHandler = null;
57
58
59
60
61 private Channel dataChannel = null;
62
63
64
65
66 private InetSocketAddress remoteAddress = null;
67
68
69
70
71 private InetSocketAddress localAddress = null;
72
73
74
75
76
77 private int remotePort = -1;
78
79
80
81
82
83
84 private int localPort = -1;
85
86
87
88
89 private boolean passiveMode = false;
90
91
92
93
94 private boolean isBind = false;
95
96
97
98
99 private final FtpTransferControl transferControl;
100
101
102
103
104 private FtpArgumentCode.TransferType transferType = FtpArgumentCode.TransferType.ASCII;
105
106
107
108
109 private FtpArgumentCode.TransferSubType transferSubType = FtpArgumentCode.TransferSubType.NONPRINT;
110
111
112
113
114 private FtpArgumentCode.TransferStructure transferStructure = FtpArgumentCode.TransferStructure.FILE;
115
116
117
118
119 private FtpArgumentCode.TransferMode transferMode = FtpArgumentCode.TransferMode.STREAM;
120
121
122
123
124
125
126 public FtpDataAsyncConn(FtpSession session) {
127 this.session = session;
128 dataChannel = null;
129 remoteAddress = FtpChannelUtils.getRemoteInetSocketAddress(this.session
130 .getControlChannel());
131 remotePort = remoteAddress.getPort();
132 setDefaultLocalPort();
133 localAddress = new InetSocketAddress(FtpChannelUtils
134 .getLocalInetAddress(this.session.getControlChannel()),
135 localPort);
136 passiveMode = false;
137 isBind = false;
138 transferControl = new FtpTransferControl(session);
139 }
140
141
142
143
144
145 public void clear() {
146 unbindPassive();
147 transferControl.clear();
148 passiveMode = false;
149 remotePort = -1;
150 localPort = -1;
151 }
152
153
154
155
156
157 private void setDefaultLocalPort() {
158 setLocalPort(session.getConfiguration().getServerPort() - 1);
159
160 }
161
162
163
164
165
166
167 public void setLocalPort(int localPort) {
168 this.localPort = localPort;
169 }
170
171
172
173
174 public InetSocketAddress getLocalAddress() {
175 return localAddress;
176 }
177
178
179
180
181 public InetSocketAddress getRemoteAddress() {
182 return remoteAddress;
183 }
184
185
186
187
188 public int getRemotePort() {
189 return remotePort;
190 }
191
192
193
194
195 public int getLocalPort() {
196 return localPort;
197 }
198
199
200
201
202
203
204
205 public void setActive(InetSocketAddress address) {
206 unbindPassive();
207 setDefaultLocalPort();
208 remoteAddress = address;
209 passiveMode = false;
210 isBind = false;
211 remotePort = remoteAddress.getPort();
212 }
213
214
215
216
217
218 public void setPassive() {
219 unbindPassive();
220 String address = session.getConfiguration().getServerAddress();
221 if (address == null) {
222 localAddress = new InetSocketAddress(FtpChannelUtils
223 .getLocalInetAddress(session.getControlChannel()), localPort);
224 } else {
225 localAddress = new InetSocketAddress(address, localPort);
226 }
227 passiveMode = true;
228 isBind = false;
229 }
230
231
232
233
234 public boolean isPassiveMode() {
235 return passiveMode;
236 }
237
238
239
240
241
242
243 public boolean isBind() {
244 return isBind;
245 }
246
247
248
249
250
251
252 public boolean isConnected() {
253 return dataChannel != null && dataChannel.isConnected();
254 }
255
256
257
258
259 public FtpArgumentCode.TransferMode getMode() {
260 return transferMode;
261 }
262
263
264
265
266
267 public void setMode(FtpArgumentCode.TransferMode transferMode) {
268 this.transferMode = transferMode;
269 setCorrectCodec();
270 }
271
272
273
274
275 public FtpArgumentCode.TransferStructure getStructure() {
276 return transferStructure;
277 }
278
279
280
281
282
283 public void setStructure(FtpArgumentCode.TransferStructure transferStructure) {
284 this.transferStructure = transferStructure;
285 setCorrectCodec();
286 }
287
288
289
290
291 public FtpArgumentCode.TransferSubType getSubType() {
292 return transferSubType;
293 }
294
295
296
297
298
299 public void setSubType(FtpArgumentCode.TransferSubType transferSubType) {
300 this.transferSubType = transferSubType;
301 setCorrectCodec();
302 }
303
304
305
306
307 public FtpArgumentCode.TransferType getType() {
308 return transferType;
309 }
310
311
312
313
314
315 public void setType(FtpArgumentCode.TransferType transferType) {
316 this.transferType = transferType;
317 setCorrectCodec();
318 }
319
320
321
322
323
324
325 public boolean isFileStreamBlockAsciiImage() {
326 return transferStructure == TransferStructure.FILE &&
327 (transferMode == TransferMode.STREAM || transferMode == TransferMode.BLOCK) &&
328 (transferType == TransferType.ASCII || transferType == TransferType.IMAGE);
329 }
330
331
332
333
334
335 public boolean isStreamFile() {
336 return transferMode == TransferMode.STREAM &&
337 transferStructure == TransferStructure.FILE;
338 }
339
340
341
342
343
344
345 private void setCorrectCodec() {
346 try {
347 getDataNetworkHandler().setCorrectCodec();
348 } catch (FtpNoConnectionException e) {
349 }
350 }
351
352
353
354
355
356
357 public void unbindPassive() {
358 if (isBind && passiveMode) {
359 isBind = false;
360 InetSocketAddress local = getLocalAddress();
361 if (dataChannel != null && dataChannel.isConnected()) {
362 Channels.close(dataChannel);
363 }
364 session.getConfiguration().getFtpInternalConfiguration()
365 .unbindPassive(local);
366
367
368 InetAddress remote = remoteAddress.getAddress();
369 session.getConfiguration().delFtpSession(remote, local);
370 }
371 dataChannel = null;
372 dataNetworkHandler = null;
373 }
374
375
376
377
378
379
380
381 public boolean initPassiveConnection() throws Reply425Exception {
382 unbindPassive();
383 if (passiveMode) {
384
385 session.getConfiguration().getFtpInternalConfiguration()
386 .bindPassive(getLocalAddress());
387 isBind = true;
388 return true;
389 }
390
391 return true;
392 }
393
394
395
396
397
398
399
400 public Channel getCurrentDataChannel() throws FtpNoConnectionException {
401 if (dataChannel == null) {
402 throw new FtpNoConnectionException("No Data Connection active");
403 }
404 return dataChannel;
405 }
406
407
408
409
410
411
412 public DataNetworkHandler getDataNetworkHandler()
413 throws FtpNoConnectionException {
414 if (dataNetworkHandler == null) {
415 throw new FtpNoConnectionException("No Data Connection active");
416 }
417 return dataNetworkHandler;
418 }
419
420
421
422
423
424
425 public void setDataNetworkHandler(DataNetworkHandler dataNetworkHandler) {
426 this.dataNetworkHandler = dataNetworkHandler;
427 }
428
429
430
431
432
433
434 public static int getNewPassivePort(FtpConfiguration configuration) {
435 return configuration.getNextRangePort();
436 }
437
438
439
440
441 public String getStatus() {
442 StringBuilder builder = new StringBuilder("Data connection: ");
443 builder.append((isConnected()? "connected " : "not connected "));
444 builder.append((isBind()? "bind " : "not bind "));
445 builder.append((isPassiveMode()? "passive mode" : "active mode"));
446 builder.append('\n');
447 builder.append("Mode: ");
448 builder.append(transferMode.name());
449 builder.append('\n');
450 builder.append("Structure: ");
451 builder.append(transferStructure.name());
452 builder.append('\n');
453 builder.append("Type: ");
454 builder.append(transferType.name());
455 builder.append(' ');
456 builder.append(transferSubType.name());
457 return builder.toString();
458 }
459
460
461
462
463 @Override
464 public String toString() {
465 return getStatus().replace('\n', ' ');
466 }
467
468
469
470
471
472 public FtpTransferControl getFtpTransferControl() {
473 return transferControl;
474 }
475
476
477
478
479
480
481
482
483
484 public void setNewOpenedDataChannel(Channel dataChannel)
485 throws InterruptedException, Reply425Exception {
486 this.dataChannel = dataChannel;
487 if (dataChannel == null) {
488 String curmode = null;
489 if (isPassiveMode()) {
490 curmode = "passive";
491 } else {
492 curmode = "active";
493 }
494
495 throw new Reply425Exception("Cannot open " + curmode +
496 " data connection");
497 }
498 isBind = true;
499 }
500 }