001: /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
002: /*
003: Copyright (c) 2002-2008 ymnk, JCraft,Inc. All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without
006: modification, are permitted provided that the following conditions are met:
007:
008: 1. Redistributions of source code must retain the above copyright notice,
009: this list of conditions and the following disclaimer.
010:
011: 2. Redistributions in binary form must reproduce the above copyright
012: notice, this list of conditions and the following disclaimer in
013: the documentation and/or other materials provided with the distribution.
014:
015: 3. The names of the authors may not be used to endorse or promote products
016: derived from this software without specific prior written permission.
017:
018: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
019: INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
020: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
021: INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
022: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
023: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
024: OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025: LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026: NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
027: EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: */
029:
030: package com.jcraft.jsch;
031:
032: import java.net.*;
033: import java.io.*;
034:
035: class PortWatcher implements Runnable {
036: private static java.util.Vector pool = new java.util.Vector();
037: private static InetAddress anyLocalAddress = null;
038: static {
039: // 0.0.0.0
040: /*
041: try{ anyLocalAddress=InetAddress.getByAddress(new byte[4]); }
042: catch(UnknownHostException e){
043: }
044: */
045: try {
046: anyLocalAddress = InetAddress.getByName("0.0.0.0");
047: } catch (UnknownHostException e) {
048: }
049: }
050:
051: Session session;
052: int lport;
053: int rport;
054: String host;
055: InetAddress boundaddress;
056: Runnable thread;
057: ServerSocket ss;
058:
059: static String[] getPortForwarding(Session session) {
060: java.util.Vector foo = new java.util.Vector();
061: synchronized (pool) {
062: for (int i = 0; i < pool.size(); i++) {
063: PortWatcher p = (PortWatcher) (pool.elementAt(i));
064: if (p.session == session) {
065: foo.addElement(p.lport + ":" + p.host + ":"
066: + p.rport);
067: }
068: }
069: }
070: String[] bar = new String[foo.size()];
071: for (int i = 0; i < foo.size(); i++) {
072: bar[i] = (String) (foo.elementAt(i));
073: }
074: return bar;
075: }
076:
077: static PortWatcher getPort(Session session, String address,
078: int lport) throws JSchException {
079: InetAddress addr;
080: try {
081: addr = InetAddress.getByName(address);
082: } catch (UnknownHostException uhe) {
083: throw new JSchException("PortForwardingL: invalid address "
084: + address + " specified.", uhe);
085: }
086: synchronized (pool) {
087: for (int i = 0; i < pool.size(); i++) {
088: PortWatcher p = (PortWatcher) (pool.elementAt(i));
089: if (p.session == session && p.lport == lport) {
090: if (/*p.boundaddress.isAnyLocalAddress() ||*/
091: (anyLocalAddress != null && p.boundaddress
092: .equals(anyLocalAddress))
093: || p.boundaddress.equals(addr))
094: return p;
095: }
096: }
097: return null;
098: }
099: }
100:
101: static PortWatcher addPort(Session session, String address,
102: int lport, String host, int rport, ServerSocketFactory ssf)
103: throws JSchException {
104: if (getPort(session, address, lport) != null) {
105: throw new JSchException("PortForwardingL: local port "
106: + address + ":" + lport + " is already registered.");
107: }
108: PortWatcher pw = new PortWatcher(session, address, lport, host,
109: rport, ssf);
110: pool.addElement(pw);
111: return pw;
112: }
113:
114: static void delPort(Session session, String address, int lport)
115: throws JSchException {
116: PortWatcher pw = getPort(session, address, lport);
117: if (pw == null) {
118: throw new JSchException("PortForwardingL: local port "
119: + address + ":" + lport + " is not registered.");
120: }
121: pw.delete();
122: pool.removeElement(pw);
123: }
124:
125: static void delPort(Session session) {
126: synchronized (pool) {
127: PortWatcher[] foo = new PortWatcher[pool.size()];
128: int count = 0;
129: for (int i = 0; i < pool.size(); i++) {
130: PortWatcher p = (PortWatcher) (pool.elementAt(i));
131: if (p.session == session) {
132: p.delete();
133: foo[count++] = p;
134: }
135: }
136: for (int i = 0; i < count; i++) {
137: PortWatcher p = foo[i];
138: pool.removeElement(p);
139: }
140: }
141: }
142:
143: PortWatcher(Session session, String address, int lport,
144: String host, int rport, ServerSocketFactory factory)
145: throws JSchException {
146: this .session = session;
147: this .lport = lport;
148: this .host = host;
149: this .rport = rport;
150: try {
151: boundaddress = InetAddress.getByName(address);
152: ss = (factory == null) ? new ServerSocket(lport, 0,
153: boundaddress) : factory.createServerSocket(lport,
154: 0, boundaddress);
155: } catch (Exception e) {
156: //System.err.println(e);
157: String message = "PortForwardingL: local port " + address
158: + ":" + lport + " cannot be bound.";
159: if (e instanceof Throwable)
160: throw new JSchException(message, (Throwable) e);
161: throw new JSchException(message);
162: }
163: if (lport == 0) {
164: int assigned = ss.getLocalPort();
165: if (assigned != -1)
166: this .lport = assigned;
167: }
168: }
169:
170: public void run() {
171: thread = this ;
172: try {
173: while (thread != null) {
174: Socket socket = ss.accept();
175: socket.setTcpNoDelay(true);
176: InputStream in = socket.getInputStream();
177: OutputStream out = socket.getOutputStream();
178: ChannelDirectTCPIP channel = new ChannelDirectTCPIP();
179: channel.init();
180: channel.setInputStream(in);
181: channel.setOutputStream(out);
182: session.addChannel(channel);
183: ((ChannelDirectTCPIP) channel).setHost(host);
184: ((ChannelDirectTCPIP) channel).setPort(rport);
185: ((ChannelDirectTCPIP) channel).setOrgIPAddress(socket
186: .getInetAddress().getHostAddress());
187: ((ChannelDirectTCPIP) channel).setOrgPort(socket
188: .getPort());
189: channel.connect();
190: if (channel.exitstatus != -1) {
191: }
192: }
193: } catch (Exception e) {
194: //System.err.println("! "+e);
195: }
196:
197: delete();
198: }
199:
200: void delete() {
201: thread = null;
202: try {
203: if (ss != null)
204: ss.close();
205: ss = null;
206: } catch (Exception e) {
207: }
208: }
209: }
|