273
|
1 /*
|
|
2 * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
|
|
3 * Please refer to the LICENSE.txt for licensing details.
|
|
4 */
|
|
5 package ch.ethz.ssh2.channel;
|
|
6
|
|
7 import java.io.IOException;
|
|
8 import java.net.InetSocketAddress;
|
|
9 import java.net.ServerSocket;
|
|
10 import java.net.Socket;
|
|
11
|
|
12 /**
|
|
13 * LocalAcceptThread.
|
307
|
14 *
|
273
|
15 * @author Christian Plattner
|
|
16 * @version 2.50, 03/15/10
|
|
17 */
|
307
|
18 public class LocalAcceptThread extends Thread implements IChannelWorkerThread {
|
|
19 ChannelManager cm;
|
|
20 String host_to_connect;
|
|
21 int port_to_connect;
|
273
|
22
|
307
|
23 final ServerSocket ss;
|
273
|
24
|
307
|
25 public LocalAcceptThread(ChannelManager cm, int local_port, String host_to_connect, int port_to_connect)
|
|
26 throws IOException {
|
|
27 this.cm = cm;
|
|
28 this.host_to_connect = host_to_connect;
|
|
29 this.port_to_connect = port_to_connect;
|
|
30 ss = new ServerSocket(local_port);
|
|
31 }
|
273
|
32
|
307
|
33 public LocalAcceptThread(ChannelManager cm, InetSocketAddress localAddress, String host_to_connect,
|
|
34 int port_to_connect) throws IOException {
|
|
35 this.cm = cm;
|
|
36 this.host_to_connect = host_to_connect;
|
|
37 this.port_to_connect = port_to_connect;
|
|
38 ss = new ServerSocket();
|
|
39 ss.bind(localAddress);
|
|
40 }
|
273
|
41
|
307
|
42 public ServerSocket getServerSocket() {
|
|
43 return ss;
|
|
44 }
|
273
|
45
|
307
|
46 @Override
|
|
47 public void run() {
|
|
48 try {
|
|
49 cm.registerThread(this);
|
|
50 }
|
|
51 catch (IOException e) {
|
|
52 stopWorking();
|
|
53 return;
|
|
54 }
|
273
|
55
|
307
|
56 while (true) {
|
|
57 Socket s = null;
|
|
58
|
|
59 try {
|
|
60 s = ss.accept();
|
|
61 }
|
|
62 catch (IOException e) {
|
|
63 stopWorking();
|
|
64 return;
|
|
65 }
|
273
|
66
|
307
|
67 Channel cn = null;
|
|
68 StreamForwarder r2l = null;
|
|
69 StreamForwarder l2r = null;
|
273
|
70
|
307
|
71 try {
|
|
72 /* This may fail, e.g., if the remote port is closed (in optimistic terms: not open yet) */
|
|
73 cn = cm.openDirectTCPIPChannel(host_to_connect, port_to_connect, s.getInetAddress().getHostAddress(), s
|
|
74 .getPort());
|
|
75 }
|
|
76 catch (IOException e) {
|
|
77 /* Simply close the local socket and wait for the next incoming connection */
|
|
78 try {
|
|
79 s.close();
|
|
80 }
|
|
81 catch (IOException ignore) {
|
|
82 }
|
273
|
83
|
307
|
84 continue;
|
|
85 }
|
273
|
86
|
307
|
87 try {
|
|
88 r2l = new StreamForwarder(cn, null, null, cn.stdoutStream, s.getOutputStream(), "RemoteToLocal");
|
|
89 l2r = new StreamForwarder(cn, r2l, s, s.getInputStream(), cn.stdinStream, "LocalToRemote");
|
|
90 }
|
|
91 catch (IOException e) {
|
|
92 try {
|
|
93 /* This message is only visible during debugging, since we discard the channel immediatelly */
|
|
94 cn.cm.closeChannel(cn, e, true);
|
|
95 }
|
|
96 catch (IOException ignore) {
|
|
97 }
|
273
|
98
|
307
|
99 continue;
|
|
100 }
|
273
|
101
|
307
|
102 r2l.setDaemon(true);
|
|
103 l2r.setDaemon(true);
|
|
104 r2l.start();
|
|
105 l2r.start();
|
|
106 }
|
|
107 }
|
273
|
108
|
307
|
109 public void stopWorking() {
|
|
110 try {
|
|
111 /* This will lead to an IOException in the ss.accept() call */
|
|
112 ss.close();
|
|
113 }
|
|
114 catch (IOException ignored) {
|
|
115 }
|
|
116 }
|
273
|
117 }
|