All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.helger.jsch.tunnel.Tunnel Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2016-2024 Philip Helger (www.helger.com)
 * philip[at]helger[dot]com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.helger.jsch.tunnel;

import java.util.Locale;

import javax.annotation.Nonnull;

import com.helger.commons.annotation.Nonempty;
import com.helger.commons.hashcode.HashCodeGenerator;
import com.helger.commons.string.StringHelper;
import com.helger.commons.string.ToStringGenerator;

/**
 * Tunnel stores all the information needed to define an ssh port-forwarding
 * tunnel.
 *
 * @see rfc4254
 */
public class Tunnel
{
  private String m_sSpec;
  private String m_sDestinationHostname;
  private int m_nDestinationPort;
  private String m_sLocalAlias;
  private int m_nLocalPort;
  private int m_nAssignedLocalPort;

  /**
   * Creates a Tunnel from a spec string. For details on this
   * string, see {@link #getSpec()}.
   * 

* Both localAlias and localPort are optional, in * which case they default to localhost and 0 * respectively. *

*

* Examples: * *

   * // Equivalaent to new Tunnel("localhost", 0, "foobar", 1234);
   * new Tunnel ("foobar:1234");
   * // Equivalaent to new Tunnel("localhost", 1234, "foobar", 1234);
   * new Tunnel ("1234:foobar:1234");
   * // Equivalaent to new Tunnel("local_foobar", 1234, "foobar", 1234);
   * new Tunnel ("local_foobar:1234:foobar:1234");
   * 
* * @param sSpec * A tunnel spec string * @see #Tunnel(String, int, String, int) * @see rfc4254 */ public Tunnel (@Nonnull @Nonempty final String sSpec) { final String [] aParts = StringHelper.getExplodedArray (':', sSpec, 4); if (aParts.length == 4) { m_sLocalAlias = aParts[0]; m_nLocalPort = Integer.parseInt (aParts[1]); m_sDestinationHostname = aParts[2]; m_nDestinationPort = Integer.parseInt (aParts[3]); } else if (aParts.length == 3) { m_nLocalPort = Integer.parseInt (aParts[0]); m_sDestinationHostname = aParts[1]; m_nDestinationPort = Integer.parseInt (aParts[2]); } else if (aParts.length == 2) { // dynamically assigned port m_nLocalPort = 0; m_sDestinationHostname = aParts[0]; m_nDestinationPort = Integer.parseInt (aParts[1]); } else throw new IllegalStateException ("Failed to parse Tunnel spec '" + sSpec + "'"); } /** * Creates a Tunnel to destinationPort on * destinationHostname from a dynamically assigned port on * localhost. Simply calls * * @param destinationHostname * The hostname to tunnel to * @param destinationPort * The port to tunnel to * @see #Tunnel(int, String, int) * @see rfc4254 */ public Tunnel (final String destinationHostname, final int destinationPort) { this (0, destinationHostname, destinationPort); } /** * Creates a Tunnel to destinationPort on * destinationHostname from localPort on * localhost. * * @param localPort * The local port to bind to * @param destinationHostname * The hostname to tunnel to * @param destinationPort * The port to tunnel to * @see #Tunnel(String, int, String, int) * @see rfc4254 */ public Tunnel (final int localPort, final String destinationHostname, final int destinationPort) { this (null, localPort, destinationHostname, destinationPort); } /** * Creates a Tunnel to destinationPort on * destinationHostname from localPort on * localAlias. *

* This is similar in behavior to the -L option in ssh, with the * exception that you can specify 0 for the local port in which * case the port will be dynamically allocated and you can * {@link #getAssignedLocalPort()} after the tunnel has been started. *

*

* A common use case for localAlias might be to link your * loopback interfaces to names via an entries in /etc/hosts * which would allow you to use the same port number for more than one tunnel. * For example: * *

   * 127.0.0.2 foo
   * 127.0.0.3 bar
   * 
* * Would allow you to have both of these open at the same time: * *
   * new Tunnel ("foo", 1234, "remote_foo", 1234);
   * new Tunnel ("bar", 1234, "remote_bar", 1234);
   * 
* * @param localAlias * The local interface to bind to * @param localPort * The local port to bind to * @param destinationHostname * The hostname to tunnel to * @param destinationPort * The port to tunnel to * @see com.jcraft.jsch.Session#setPortForwardingL(String, int, String, int) * @see rfc4254 */ public Tunnel (final String localAlias, final int localPort, final String destinationHostname, final int destinationPort) { m_sLocalAlias = localAlias; m_nLocalPort = localPort; m_sDestinationHostname = destinationHostname; m_nDestinationPort = destinationPort; } /** * Returns the local port currently bound to. If 0 was specified * as the port to bind to, this will return the dynamically allocated port, * otherwise it will return the port specified. * * @return The local port currently bound to */ public int getAssignedLocalPort () { return m_nAssignedLocalPort == 0 ? m_nLocalPort : m_nAssignedLocalPort; } /** * Returns the hostname of the destination. * * @return The hostname of the destination */ public String getDestinationHostname () { return m_sDestinationHostname; } /** * Returns the port of the destination. * * @return The port of the destination */ public int getDestinationPort () { return m_nDestinationPort; } /** * Returns the local alias bound to. See * rfc4254 for * details on acceptible values. * * @return The local alias bound to */ public String getLocalAlias () { return m_sLocalAlias; } /** * Returns the port this tunnel was configured with. If you want to get the * runtime port, use {@link #getAssignedLocalPort()}. * * @return The port this tunnel was configured with */ public int getLocalPort () { return m_nLocalPort; } /** * Returns the spec string (either calculated or specified) for this tunnel. *

* A spec string is composed of 4 parts separated by a colon (: * ): *

    *
  1. localAlias (optional)
  2. *
  3. localPort (optional)
  4. *
  5. destinationHostname
  6. *
  7. destinationPort
  8. *
* * @return The spec string */ @Nonnull public String getSpec () { if (m_sSpec == null) m_sSpec = getAsString ().toLowerCase (Locale.US); return m_sSpec; } void setAssignedLocalPort (final int port) { m_nAssignedLocalPort = port; } @Nonnull public String getAsString () { return (m_sLocalAlias == null ? "" : m_sLocalAlias + ":") + (m_nAssignedLocalPort == 0 ? Integer.toString (m_nLocalPort) : "(0)" + m_nAssignedLocalPort) + ":" + m_sDestinationHostname + ":" + m_nDestinationPort; } @Override public boolean equals (final Object o) { if (o == this) return true; if (o == null || !getClass ().equals (o.getClass ())) return false; final Tunnel rhs = (Tunnel) o; return getSpec ().equals (rhs.getSpec ()); } @Override public int hashCode () { return new HashCodeGenerator (this).append (getSpec ()).getHashCode (); } @Override public String toString () { return new ToStringGenerator (this).append ("Spec", m_sSpec) .append ("DestinationHostname", m_sDestinationHostname) .append ("DestinationPort", m_nDestinationPort) .append ("LocalAlias", m_sLocalAlias) .append ("LocalPort", m_nLocalPort) .append ("AssignedLocalPort", m_nAssignedLocalPort) .getToString (); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy