📄 proxyloginhandler.java
字号:
/*
* Created on Feb 1, 2005
* Created by Alon Rohter
* Copyright (C) 2004-2005 Aelitis, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* AELITIS, SAS au capital de 46,603.30 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/
package com.aelitis.azureus.core.networkmanager.impl.tcp;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import org.gudy.azureus2.core3.config.COConfigurationListener;
import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.util.*;
import com.aelitis.azureus.core.networkmanager.*;
import com.aelitis.azureus.core.proxy.AEProxyFactory;
/**
* Handles the process of proxy login/authentication/setup.
*/
public class ProxyLoginHandler {
private static final int READ_DONE = 0;
private static final int READ_NOT_DONE = 1;
private static final int READ_NO_PROGRESS = 2;
public static InetSocketAddress DEFAULT_SOCKS_SERVER_ADDRESS;
private static String default_socks_version;
private static String default_socks_user;
private static String default_socks_password;
static{
COConfigurationManager.addListener(
new COConfigurationListener()
{
public void
configurationSaved()
{
readConfig();
}
});
readConfig();
}
static void
readConfig()
{
boolean socks_same = COConfigurationManager.getBooleanParameter( "Proxy.Data.Same" );
String socks_host = COConfigurationManager.getStringParameter( socks_same ? "Proxy.Host" : "Proxy.Data.Host" );
int socks_port = 0;
try{
String socks_port_str = COConfigurationManager.getStringParameter( socks_same ? "Proxy.Port" : "Proxy.Data.Port" );
socks_port_str = socks_port_str.trim();
if ( socks_port_str.length() > 0 ){
socks_port = Integer.parseInt( COConfigurationManager.getStringParameter( socks_same ? "Proxy.Port" : "Proxy.Data.Port" ) );
}
}catch( Throwable e ){ Debug.printStackTrace(e); }
DEFAULT_SOCKS_SERVER_ADDRESS = new InetSocketAddress( socks_host, socks_port );
default_socks_version = COConfigurationManager.getStringParameter( "Proxy.Data.SOCKS.version" );
default_socks_user = COConfigurationManager.getStringParameter( socks_same ? "Proxy.Username" : "Proxy.Data.Username" );
if ( default_socks_user.trim().equalsIgnoreCase("<none>")){
default_socks_user = "";
}
default_socks_password = COConfigurationManager.getStringParameter( socks_same ? "Proxy.Password" : "Proxy.Data.Password" );
}
private final TCPTransportImpl proxy_connection;
private final InetSocketAddress remote_address;
private final ProxyListener proxy_listener;
private final String mapped_ip;
private int socks5_handshake_phase = 0;
private int socks5_address_length;
private long read_start_time = 0;
private final String socks_version;
private final String socks_user;
private final String socks_password;
/**
* Do proxy login.
* @param proxy_connection transport connected to proxy server
* @param remote_address address to proxy to
* @param listener for proxy login success or faulure
*/
public
ProxyLoginHandler(
TCPTransportImpl proxy_connection,
InetSocketAddress remote_address,
ProxyListener listener )
{
this( proxy_connection, remote_address, listener, default_socks_version, default_socks_user, default_socks_password );
}
public
ProxyLoginHandler(
TCPTransportImpl _proxy_connection,
InetSocketAddress _remote_address,
ProxyListener _listener,
String _socks_version,
String _socks_user,
String _socks_password )
{
proxy_connection = _proxy_connection;
remote_address = _remote_address;
proxy_listener = _listener;
socks_version = _socks_version;
socks_user = _socks_user;
socks_password = _socks_password;
if ( remote_address.isUnresolved() || remote_address.getAddress() == null ){
// deal with long "hostnames" that we get for, e.g., I2P destinations
mapped_ip = AEProxyFactory.getAddressMapper().internalise( remote_address.getHostName() );
}
else{
mapped_ip = remote_address.getAddress().getHostName();
}
if( socks_version.equals( "V4" ) ) {
try{
doSocks4Login( createSocks4Message() );
}
catch( Throwable t ) {
Debug.out( t );
proxy_listener.connectFailure( t );
}
}
else if( socks_version.equals( "V4a" ) ) {
try{
doSocks4Login( createSocks4aMessage() );
}
catch( Throwable t ) {
Debug.out( t );
proxy_listener.connectFailure( t );
}
}
else { //"V5"
doSocks5Login();
}
}
private void doSocks4Login( final ByteBuffer[] data ) {
try {
sendMessage( data[0] ); //send initial handshake to get things started
//register for read ops
TCPNetworkManager.getSingleton().getReadSelector().register( proxy_connection.getSocketChannel(), new VirtualChannelSelector.VirtualSelectorListener() {
public boolean selectSuccess( VirtualChannelSelector selector, SocketChannel sc,Object attachment ) {
try {
int result = readMessage( data[1] );
if( result == READ_DONE ) {
TCPNetworkManager.getSingleton().getReadSelector().cancel( proxy_connection.getSocketChannel() );
parseSocks4Reply( data[1] ); //will throw exception on error
proxy_listener.connectSuccess();
}
else {
TCPNetworkManager.getSingleton().getReadSelector().resumeSelects( proxy_connection.getSocketChannel() ); //resume read ops
}
return( result != READ_NO_PROGRESS );
}
catch( Throwable t ) {
//Debug.out( t );
TCPNetworkManager.getSingleton().getReadSelector().cancel( proxy_connection.getSocketChannel() );
proxy_listener.connectFailure( t );
return false;
}
}
public void selectFailure( VirtualChannelSelector selector, SocketChannel sc,Object attachment, Throwable msg ) {
Debug.out( msg );
TCPNetworkManager.getSingleton().getReadSelector().cancel( proxy_connection.getSocketChannel() );
proxy_listener.connectFailure( msg );
}
}, null );
}
catch( Throwable t ) {
Debug.out( t );
TCPNetworkManager.getSingleton().getReadSelector().cancel( proxy_connection.getSocketChannel() );
proxy_listener.connectFailure( t );
}
}
private void doSocks5Login() {
try {
final ArrayList data = new ArrayList(2);
ByteBuffer[] header = createSocks5Message();
data.add( header[0] ); //message
data.add( header[1] ); //reply buff
sendMessage( (ByteBuffer)data.get(0) ); //send initial handshake to get things started
//register for read ops
TCPNetworkManager.getSingleton().getReadSelector().register( proxy_connection.getSocketChannel(), new VirtualChannelSelector.VirtualSelectorListener() {
public boolean selectSuccess( VirtualChannelSelector selector, SocketChannel sc,Object attachment ) {
try {
int result = readMessage( (ByteBuffer)data.get(1) );
if( result == READ_DONE ) {
boolean done = parseSocks5Reply( (ByteBuffer)data.get(1) ); //will throw exception on error
if( done ) {
TCPNetworkManager.getSingleton().getReadSelector().cancel( proxy_connection.getSocketChannel() );
proxy_listener.connectSuccess();
}
else {
ByteBuffer[] raw = createSocks5Message();
data.set( 0, raw[0] );
data.set( 1, raw[1] );
if( raw[0] != null ) sendMessage( raw[0] );
TCPNetworkManager.getSingleton().getReadSelector().resumeSelects( proxy_connection.getSocketChannel() ); //resume read ops
}
}
else {
TCPNetworkManager.getSingleton().getReadSelector().resumeSelects( proxy_connection.getSocketChannel() ); //resume read ops
}
return( result != READ_NO_PROGRESS );
}
catch( Throwable t ) {
//Debug.out( t );
TCPNetworkManager.getSingleton().getReadSelector().cancel( proxy_connection.getSocketChannel() );
proxy_listener.connectFailure( t );
return false;
}
}
public void selectFailure( VirtualChannelSelector selector, SocketChannel sc,Object attachment, Throwable msg ) {
Debug.out( msg );
TCPNetworkManager.getSingleton().getReadSelector().cancel( proxy_connection.getSocketChannel() );
proxy_listener.connectFailure( msg );
}
}, null );
}
catch( Throwable t ) {
Debug.out( t );
SocketChannel chan = proxy_connection.getSocketChannel();
if ( chan != null ){
TCPNetworkManager.getSingleton().getReadSelector().cancel( chan );
}
proxy_listener.connectFailure( t );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -