KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jcraft > jsch > ChannelForwardedTCPIP


1 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
2 /*
3 Copyright (c) 2002,2003,2004,2005,2006 ymnk, JCraft,Inc. All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8   1. Redistributions of source code must retain the above copyright notice,
9      this list of conditions and the following disclaimer.
10
11   2. Redistributions in binary form must reproduce the above copyright
12      notice, this list of conditions and the following disclaimer in
13      the documentation and/or other materials provided with the distribution.
14
15   3. The names of the authors may not be used to endorse or promote products
16      derived from this software without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
19 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
21 INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
22 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */

29
30 package com.jcraft.jsch;
31
32 import java.net.*;
33
34 public class ChannelForwardedTCPIP extends Channel{
35
36   static java.util.Vector JavaDoc pool=new java.util.Vector JavaDoc();
37
38   static private final int LOCAL_WINDOW_SIZE_MAX=0x20000;
39 //static private final int LOCAL_WINDOW_SIZE_MAX=0x100000;
40
static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000;
41
42   static private final int TIMEOUT=10*1000;
43
44   SocketFactory factory=null;
45   private Socket socket=null;
46   private ForwardedTCPIPDaemon daemon=null;
47   String JavaDoc target;
48   int lport;
49   int rport;
50
51   ChannelForwardedTCPIP(){
52     super();
53     setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
54     setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
55     setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
56     io=new IO();
57     connected=true;
58   }
59
60   public void run(){
61
62     try{
63       if(lport==-1){
64         Class JavaDoc c=Class.forName(target);
65         daemon=(ForwardedTCPIPDaemon)c.newInstance();
66         daemon.setChannel(this);
67         Object JavaDoc[] foo=getPort(session, rport);
68         daemon.setArg((Object JavaDoc[])foo[3]);
69         new Thread JavaDoc(daemon).start();
70       }
71       else{
72         socket=(factory==null) ?
73            Util.createSocket(target, lport, TIMEOUT) :
74           factory.createSocket(target, lport);
75         socket.setTcpNoDelay(true);
76         io.setInputStream(socket.getInputStream());
77         io.setOutputStream(socket.getOutputStream());
78       }
79       sendOpenConfirmation();
80     }
81     catch(Exception JavaDoc e){
82       sendOpenFailure(SSH_OPEN_ADMINISTRATIVELY_PROHIBITED);
83       close=true;
84       disconnect();
85       return;
86     }
87
88     thread=Thread.currentThread();
89     Buffer buf=new Buffer(rmpsize);
90     Packet packet=new Packet(buf);
91     int i=0;
92     try{
93       while(thread!=null &&
94             io!=null &&
95             io.in!=null){
96         i=io.in.read(buf.buffer,
97                      14,
98                      buf.buffer.length-14
99                      -32 -20 // padding and mac
100
);
101
102         if(i<=0){
103           eof();
104           break;
105         }
106         packet.reset();
107         if(close)break;
108         buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
109         buf.putInt(recipient);
110         buf.putInt(i);
111         buf.skip(i);
112         session.write(packet, this, i);
113       }
114     }
115     catch(Exception JavaDoc e){
116       //System.err.println(e);
117
}
118     //thread=null;
119
//eof();
120
disconnect();
121   }
122   void getData(Buffer buf){
123     setRecipient(buf.getInt());
124     setRemoteWindowSize(buf.getInt());
125     setRemotePacketSize(buf.getInt());
126     byte[] addr=buf.getString();
127     int port=buf.getInt();
128     byte[] orgaddr=buf.getString();
129     int orgport=buf.getInt();
130
131     /*
132     System.err.println("addr: "+new String(addr));
133     System.err.println("port: "+port);
134     System.err.println("orgaddr: "+new String(orgaddr));
135     System.err.println("orgport: "+orgport);
136     */

137
138     synchronized(pool){
139       for(int i=0; i<pool.size(); i++){
140         Object JavaDoc[] foo=(Object JavaDoc[])(pool.elementAt(i));
141         if(foo[0]!=session) continue;
142         if(((Integer JavaDoc)foo[1]).intValue()!=port) continue;
143         this.rport=port;
144         this.target=(String JavaDoc)foo[2];
145         if(foo[3]==null || (foo[3] instanceof Object JavaDoc[])){ this.lport=-1; }
146         else{ this.lport=((Integer JavaDoc)foo[3]).intValue(); }
147         if(foo.length>=5){
148           this.factory=((SocketFactory)foo[4]);
149         }
150         break;
151       }
152       if(target==null){
153         System.err.println("??");
154       }
155     }
156   }
157
158   static Object JavaDoc[] getPort(Session session, int rport){
159     synchronized(pool){
160       for(int i=0; i<pool.size(); i++){
161         Object JavaDoc[] bar=(Object JavaDoc[])(pool.elementAt(i));
162         if(bar[0]!=session) continue;
163         if(((Integer JavaDoc)bar[1]).intValue()!=rport) continue;
164         return bar;
165       }
166       return null;
167     }
168   }
169
170   static String JavaDoc[] getPortForwarding(Session session){
171     java.util.Vector JavaDoc foo=new java.util.Vector JavaDoc();
172     synchronized(pool){
173       for(int i=0; i<pool.size(); i++){
174         Object JavaDoc[] bar=(Object JavaDoc[])(pool.elementAt(i));
175         if(bar[0]!=session) continue;
176         if(bar[3]==null){ foo.addElement(bar[1]+":"+bar[2]+":"); }
177         else{ foo.addElement(bar[1]+":"+bar[2]+":"+bar[3]); }
178       }
179     }
180     String JavaDoc[] bar=new String JavaDoc[foo.size()];
181     for(int i=0; i<foo.size(); i++){
182       bar[i]=(String JavaDoc)(foo.elementAt(i));
183     }
184     return bar;
185   }
186
187   static void addPort(Session session, int port, String JavaDoc target, int lport, SocketFactory factory) throws JSchException{
188     synchronized(pool){
189       if(getPort(session, port)!=null){
190         throw new JSchException("PortForwardingR: remote port "+port+" is already registered.");
191       }
192       Object JavaDoc[] foo=new Object JavaDoc[5];
193       foo[0]=session; foo[1]=new Integer JavaDoc(port);
194       foo[2]=target; foo[3]=new Integer JavaDoc(lport);
195       foo[4]=factory;
196       pool.addElement(foo);
197     }
198   }
199   static void addPort(Session session, int port, String JavaDoc daemon, Object JavaDoc[] arg) throws JSchException{
200     synchronized(pool){
201       if(getPort(session, port)!=null){
202         throw new JSchException("PortForwardingR: remote port "+port+" is already registered.");
203       }
204       Object JavaDoc[] foo=new Object JavaDoc[4];
205       foo[0]=session; foo[1]=new Integer JavaDoc(port);
206       foo[2]=daemon; foo[3]=arg;
207       pool.addElement(foo);
208     }
209   }
210   static void delPort(ChannelForwardedTCPIP c){
211     delPort(c.session, c.rport);
212   }
213   static void delPort(Session session, int rport){
214     synchronized(pool){
215       Object JavaDoc[] foo=null;
216       for(int i=0; i<pool.size(); i++){
217         Object JavaDoc[] bar=(Object JavaDoc[])(pool.elementAt(i));
218         if(bar[0]!=session) continue;
219         if(((Integer JavaDoc)bar[1]).intValue()!=rport) continue;
220         foo=bar;
221         break;
222       }
223       if(foo==null)return;
224       pool.removeElement(foo);
225     }
226
227     Buffer buf=new Buffer(100); // ??
228
Packet packet=new Packet(buf);
229
230     try{
231       // byte SSH_MSG_GLOBAL_REQUEST 80
232
// string "cancel-tcpip-forward"
233
// boolean want_reply
234
// string address_to_bind (e.g. "127.0.0.1")
235
// uint32 port number to bind
236
packet.reset();
237       buf.putByte((byte) 80/*SSH_MSG_GLOBAL_REQUEST*/);
238       buf.putString("cancel-tcpip-forward".getBytes());
239       buf.putByte((byte)0);
240       buf.putString("0.0.0.0".getBytes());
241       buf.putInt(rport);
242       session.write(packet);
243     }
244     catch(Exception JavaDoc e){
245 // throw new JSchException(e.toString());
246
}
247   }
248   static void delPort(Session session){
249     int[] rport=null;
250     int count=0;
251     synchronized(pool){
252       rport=new int[pool.size()];
253       for(int i=0; i<pool.size(); i++){
254         Object JavaDoc[] bar=(Object JavaDoc[])(pool.elementAt(i));
255         if(bar[0]==session) {
256           rport[count++]=((Integer JavaDoc)bar[1]).intValue();
257         }
258       }
259     }
260     for(int i=0; i<count; i++){
261       delPort(session, rport[i]);
262     }
263   }
264   public int getRemotePort(){return rport;}
265   void setSocketFactory(SocketFactory factory){
266     this.factory=factory;
267   }
268 }
269
Popular Tags