use of com.biglybt.core.networkmanager.VirtualChannelSelector in project BiglyBT by BiglySoftware.
the class NetworkAdminHTTPProxyImpl method getDetails.
@Override
public Details getDetails() throws NetworkAdminException {
final int RES_CONNECT_FAILED = 0;
final int RES_PROXY_FAILED = 1;
final int RES_OK = 3;
final AESemaphore sem = new AESemaphore("NetworkAdminSocksProxy:test");
final int[] result = { RES_CONNECT_FAILED };
final NetworkAdminException[] error = { null };
final ProxyDetails[] details = { null };
try {
InetSocketAddress socks_address = new InetSocketAddress(InetAddress.getByName(http_host), Integer.parseInt(http_port));
final InetSocketAddress target_address = new InetSocketAddress(TARGET_HOST, TARGET_PORT);
TCPConnectionManager.ConnectListener connect_listener = new TCPConnectionManager.ConnectListener() {
@Override
public int connectAttemptStarted(int default_connect_timeout) {
return (default_connect_timeout);
}
@Override
public void connectSuccess(SocketChannel channel) {
final TCPTransportImpl transport = new TCPTransportImpl((ProtocolEndpointTCP) ProtocolEndpointFactory.createEndpoint(ProtocolEndpoint.PROTOCOL_TCP, target_address), false, false, null);
transport.setFilter(TCPTransportHelperFilterFactory.createTransparentFilter(channel));
final long start_time = SystemTime.getCurrentTime();
try {
String get_str = VersionCheckClient.getSingleton().getHTTPGetString(true, false);
ByteBuffer request = ByteBuffer.wrap(get_str.getBytes());
while (request.hasRemaining()) {
if (transport.write(new ByteBuffer[] { request }, 0, 1) < 1) {
if (SystemTime.getCurrentTime() - start_time > 30 * 1000) {
String error = "proxy handshake message send timed out after 30sec";
Debug.out(error);
throw new IOException(error);
}
try {
Thread.sleep(50);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
TCPNetworkManager.getSingleton().getReadSelector().register(transport.getSocketChannel(), new VirtualChannelSelector.VirtualSelectorListener() {
private final byte[] reply_buffer = new byte[8192];
private final ByteBuffer reply = ByteBuffer.wrap(reply_buffer);
@Override
public boolean selectSuccess(VirtualChannelSelector selector, SocketChannel sc, Object attachment) {
try {
if (SystemTime.getCurrentTime() - start_time > 30 * 1000) {
throw (new Exception("Timeout"));
}
long len = transport.read(new ByteBuffer[] { reply }, 0, 1);
if (len <= 0) {
return (false);
}
String str = new String(reply_buffer, 0, reply.position());
if (str.contains(NL + NL)) {
System.out.println(str);
String server_name = "unknown";
String auth = "none";
String response = "unknown";
StringTokenizer tok = new StringTokenizer(str, "\n");
int line_num = 0;
while (tok.hasMoreTokens()) {
String token = tok.nextToken().trim();
if (token.length() == 0) {
continue;
}
line_num++;
if (line_num == 1) {
int pos = token.indexOf(' ');
if (pos != -1) {
response = token.substring(pos + 1).trim();
}
} else {
int pos = token.indexOf(':');
if (pos != -1) {
String lhs = token.substring(0, pos).trim().toLowerCase(MessageText.LOCALE_ENGLISH);
String rhs = token.substring(pos + 1).trim();
if (lhs.equals("server")) {
if (!response.startsWith("200")) {
server_name = rhs;
}
} else if (lhs.equals("via")) {
server_name = rhs;
int p = server_name.indexOf(' ');
if (p != -1) {
server_name = server_name.substring(p + 1).trim();
}
} else if (lhs.equals("proxy-authenticate")) {
auth = rhs;
}
}
}
}
details[0] = new ProxyDetails(server_name, response, auth);
transport.close("Done");
result[0] = RES_OK;
sem.release();
} else {
TCPNetworkManager.getSingleton().getReadSelector().resumeSelects(transport.getSocketChannel());
}
return (true);
} catch (Throwable t) {
return false;
}
}
@Override
public void selectFailure(VirtualChannelSelector selector, SocketChannel sc, Object attachment, Throwable msg) {
result[0] = RES_PROXY_FAILED;
error[0] = new NetworkAdminException("Proxy error", msg);
transport.close("Proxy error");
sem.release();
}
}, null);
} catch (Throwable t) {
result[0] = RES_PROXY_FAILED;
error[0] = new NetworkAdminException("Proxy connect failed", t);
sem.release();
}
}
@Override
public void connectFailure(Throwable failure_msg) {
result[0] = RES_CONNECT_FAILED;
error[0] = new NetworkAdminException("Connect failed", failure_msg);
sem.release();
}
};
TCPNetworkManager.getSingleton().getConnectDisconnectManager().requestNewConnection(socks_address, connect_listener, ProtocolEndpoint.CONNECT_PRIORITY_MEDIUM);
} catch (Throwable e) {
result[0] = RES_CONNECT_FAILED;
error[0] = new NetworkAdminException("Connect failed", e);
sem.release();
}
if (!sem.reserve(10000)) {
result[0] = RES_CONNECT_FAILED;
error[0] = new NetworkAdminException("Connect timeout");
}
if (result[0] == RES_OK) {
return (details[0]);
}
throw (error[0]);
}
use of com.biglybt.core.networkmanager.VirtualChannelSelector in project BiglyBT by BiglySoftware.
the class ProxyLoginHandler method doSocks5Login.
private void doSocks5Login() {
try {
final ArrayList data = new ArrayList(2);
ByteBuffer[] header = createSocks5Message();
// message
data.add(header[0]);
// reply buff
data.add(header[1]);
// send initial handshake to get things started
sendMessage((ByteBuffer) data.get(0));
// register for read ops
TCPNetworkManager.getSingleton().getReadSelector().register(proxy_connection.getSocketChannel(), new VirtualChannelSelector.VirtualSelectorListener() {
@Override
public boolean selectSuccess(VirtualChannelSelector selector, SocketChannel sc, Object attachment) {
try {
int result = readMessage((ByteBuffer) data.get(1));
if (result == READ_DONE) {
// will throw exception on error
boolean done = parseSocks5Reply((ByteBuffer) data.get(1));
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]);
// resume read ops
TCPNetworkManager.getSingleton().getReadSelector().resumeSelects(proxy_connection.getSocketChannel());
}
} else {
// resume read ops
TCPNetworkManager.getSingleton().getReadSelector().resumeSelects(proxy_connection.getSocketChannel());
}
return (result != READ_NO_PROGRESS);
} catch (Throwable t) {
// Debug.out( t );
TCPNetworkManager.getSingleton().getReadSelector().cancel(proxy_connection.getSocketChannel());
proxy_listener.connectFailure(t);
return false;
}
}
@Override
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);
}
}
use of com.biglybt.core.networkmanager.VirtualChannelSelector in project BiglyBT by BiglySoftware.
the class TCPConnectionManager method addNewRequest.
private void addNewRequest(final ConnectionRequest request) {
request.setConnectTimeout(request.listener.connectAttemptStarted(request.getConnectTimeout()));
boolean ipv6problem = false;
boolean bind_failed = false;
try {
request.channel = SocketChannel.open();
InetAddress bindIP = null;
try {
// advanced socket options
if (rcv_size > 0) {
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Setting socket receive buffer size" + " for outgoing connection [" + request.address + "] to: " + rcv_size));
request.channel.socket().setReceiveBufferSize(rcv_size);
}
if (snd_size > 0) {
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Setting socket send buffer size " + "for outgoing connection [" + request.address + "] to: " + snd_size));
request.channel.socket().setSendBufferSize(snd_size);
}
if (ip_tos.length() > 0) {
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Setting socket TOS field " + "for outgoing connection [" + request.address + "] to: " + ip_tos));
request.channel.socket().setTrafficClass(Integer.decode(ip_tos).intValue());
}
if (local_bind_port > 0) {
request.channel.socket().setReuseAddress(true);
}
try {
bindIP = NetworkAdmin.getSingleton().getMultiHomedOutgoingRoundRobinBindAddress(request.address.getAddress());
if (bindIP != null) {
if (bindIP.isAnyLocalAddress() || !AEProxyFactory.isPluginProxy(request.address)) {
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Binding outgoing connection [" + request.address + "] to local IP address: " + bindIP + ":" + local_bind_port));
request.channel.socket().bind(new InetSocketAddress(bindIP, local_bind_port));
}
} else if (local_bind_port > 0) {
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Binding outgoing connection [" + request.address + "] to local port #: " + local_bind_port));
request.channel.socket().bind(new InetSocketAddress(local_bind_port));
}
} catch (SocketException e) {
bind_failed = true;
String msg = e.getMessage().toLowerCase();
if ((msg.contains("address family not supported by protocol family") || msg.contains("protocol family unavailable")) && !NetworkAdmin.getSingleton().hasIPV6Potential(true)) {
ipv6problem = true;
}
throw e;
}
} catch (Throwable t) {
if (bind_failed && NetworkAdmin.getSingleton().mustBind()) {
throw (t);
} else if (!ipv6problem) {
// dont pass the exception outwards, so we will continue processing connection without advanced options set
String msg = "Error while processing advanced socket options (rcv=" + rcv_size + ", snd=" + snd_size + ", tos=" + ip_tos + ", port=" + local_bind_port + ", bind=" + bindIP + ")";
// Debug.out( msg, t );
Logger.log(new LogAlert(LogAlert.UNREPEATABLE, msg, t));
} else {
throw (t);
}
}
request.channel.configureBlocking(false);
request.connect_start_time = SystemTime.getMonotonousTime();
if (request.channel.connect(request.address)) {
// already connected
finishConnect(request);
} else {
try {
new_canceled_mon.enter();
pending_attempts.put(request, null);
} finally {
new_canceled_mon.exit();
}
connect_selector.register(request.channel, new VirtualChannelSelector.VirtualSelectorListener() {
@Override
public boolean selectSuccess(VirtualChannelSelector selector, SocketChannel sc, Object attachment) {
try {
new_canceled_mon.enter();
pending_attempts.remove(request);
} finally {
new_canceled_mon.exit();
}
finishConnect(request);
return true;
}
@Override
public void selectFailure(VirtualChannelSelector selector, SocketChannel sc, Object attachment, Throwable msg) {
try {
new_canceled_mon.enter();
pending_attempts.remove(request);
} finally {
new_canceled_mon.exit();
}
closeConnection(request.channel);
request.listener.connectFailure(msg);
}
}, null);
}
} catch (Throwable t) {
String full = request.address.toString();
String hostname = request.address.getHostName();
int port = request.address.getPort();
boolean unresolved = request.address.isUnresolved();
InetAddress inet_address = request.address.getAddress();
String full_sub = inet_address == null ? request.address.toString() : inet_address.toString();
String host_address = inet_address == null ? request.address.toString() : inet_address.getHostAddress();
String msg = "ConnectDisconnectManager::address exception: full=" + full + ", hostname=" + hostname + ", port=" + port + ", unresolved=" + unresolved + ", full_sub=" + full_sub + ", host_address=" + host_address;
if (request.channel != null) {
String channel = request.channel.toString();
Socket socket = request.channel.socket();
String socket_string = socket.toString();
InetAddress local_address = socket.getLocalAddress();
String local_address_string = local_address == null ? "<null>" : local_address.toString();
int local_port = socket.getLocalPort();
SocketAddress ra = socket.getRemoteSocketAddress();
String remote_address;
if (ra != null)
remote_address = ra.toString();
else
remote_address = "<null>";
int remote_port = socket.getPort();
msg += "\n channel=" + channel + ", socket=" + socket_string + ", local_address=" + local_address_string + ", local_port=" + local_port + ", remote_address=" + remote_address + ", remote_port=" + remote_port;
} else {
msg += "\n channel=<null>";
}
if (ipv6problem || t instanceof UnresolvedAddressException || t instanceof NoRouteToHostException) {
Logger.log(new LogEvent(LOGID, LogEvent.LT_WARNING, msg));
} else {
Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR, msg, t));
}
if (request.channel != null) {
closeConnection(request.channel);
}
request.listener.connectFailure(t);
}
}
Aggregations