use of org.jivesoftware.smack.SmackException in project Smack by igniterealtime.
the class Socks5BytestreamRequest method accept.
/**
* Accepts the SOCKS5 Bytestream initialization request and returns the socket to send/receive
* data.
* <p>
* Before accepting the SOCKS5 Bytestream request you can set timeouts by invoking
* {@link #setTotalConnectTimeout(int)} and {@link #setMinimumConnectTimeout(int)}.
*
* @return the socket to send/receive data
* @throws InterruptedException if the current thread was interrupted while waiting
* @throws XMPPErrorException
* @throws SmackException
*/
@Override
public Socks5BytestreamSession accept() throws InterruptedException, XMPPErrorException, SmackException {
Collection<StreamHost> streamHosts = this.bytestreamRequest.getStreamHosts();
// throw exceptions if request contains no stream hosts
if (streamHosts.size() == 0) {
cancelRequest();
}
StreamHost selectedHost = null;
Socket socket = null;
String digest = Socks5Utils.createDigest(this.bytestreamRequest.getSessionID(), this.bytestreamRequest.getFrom(), this.manager.getConnection().getUser());
/*
* determine timeout for each connection attempt; each SOCKS5 proxy has the same amount of
* time so that the first does not consume the whole timeout
*/
int timeout = Math.max(getTotalConnectTimeout() / streamHosts.size(), getMinimumConnectTimeout());
for (StreamHost streamHost : streamHosts) {
String address = streamHost.getAddress() + ":" + streamHost.getPort();
// check to see if this address has been blacklisted
int failures = getConnectionFailures(address);
if (CONNECTION_FAILURE_THRESHOLD > 0 && failures >= CONNECTION_FAILURE_THRESHOLD) {
continue;
}
// establish socket
try {
// build SOCKS5 client
final Socks5Client socks5Client = new Socks5Client(streamHost, digest);
// connect to SOCKS5 proxy with a timeout
socket = socks5Client.getSocket(timeout);
// set selected host
selectedHost = streamHost;
break;
} catch (TimeoutException | IOException | SmackException | XMPPException e) {
incrementConnectionFailures(address);
}
}
// throw exception if connecting to all SOCKS5 proxies failed
if (selectedHost == null || socket == null) {
cancelRequest();
}
// send used-host confirmation
Bytestream response = createUsedHostResponse(selectedHost);
this.manager.getConnection().sendStanza(response);
return new Socks5BytestreamSession(socket, selectedHost.getJID().equals(this.bytestreamRequest.getFrom()));
}
use of org.jivesoftware.smack.SmackException in project Smack by igniterealtime.
the class Socks5Client method getSocket.
/**
* Returns the initialized socket that can be used to transfer data between peers via the SOCKS5
* proxy.
*
* @param timeout timeout to connect to SOCKS5 proxy in milliseconds
* @return socket the initialized socket
* @throws IOException if initializing the socket failed due to a network error
* @throws XMPPErrorException if establishing connection to SOCKS5 proxy failed
* @throws TimeoutException if connecting to SOCKS5 proxy timed out
* @throws InterruptedException if the current thread was interrupted while waiting
* @throws SmackException if the connection to the SOC
* @throws XMPPException
*/
public Socket getSocket(int timeout) throws IOException, XMPPErrorException, InterruptedException, TimeoutException, SmackException, XMPPException {
// wrap connecting in future for timeout
FutureTask<Socket> futureTask = new FutureTask<Socket>(new Callable<Socket>() {
@Override
public Socket call() throws IOException, SmackException {
// initialize socket
Socket socket = new Socket();
SocketAddress socketAddress = new InetSocketAddress(streamHost.getAddress(), streamHost.getPort());
socket.connect(socketAddress);
// initialize connection to SOCKS5 proxy
try {
establish(socket);
} catch (SmackException e) {
if (!socket.isClosed()) {
try {
socket.close();
} catch (IOException e2) {
LOGGER.log(Level.WARNING, "Could not close SOCKS5 socket", e2);
}
}
throw e;
}
return socket;
}
});
Thread executor = new Thread(futureTask);
executor.start();
// get connection to initiator with timeout
try {
return futureTask.get(timeout, TimeUnit.MILLISECONDS);
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause != null) {
// case exceptions to comply with method signature
if (cause instanceof IOException) {
throw (IOException) cause;
}
if (cause instanceof SmackException) {
throw (SmackException) cause;
}
}
// throw generic Smack exception if unexpected exception was thrown
throw new SmackException("Error while connecting to SOCKS5 proxy", e);
}
}
use of org.jivesoftware.smack.SmackException in project Smack by igniterealtime.
the class Socks5Client method establish.
/**
* Initializes the connection to the SOCKS5 proxy by negotiating authentication method and
* requesting a stream for the given digest. Currently only the no-authentication method is
* supported by the Socks5Client.
*
* @param socket connected to a SOCKS5 proxy
* @throws SmackException
* @throws IOException
*/
protected void establish(Socket socket) throws SmackException, IOException {
byte[] connectionRequest;
byte[] connectionResponse;
/*
* use DataInputStream/DataOutpuStream to assure read and write is completed in a single
* statement
*/
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
// authentication negotiation
byte[] cmd = new byte[3];
// protocol version 5
cmd[0] = (byte) 0x05;
// number of authentication methods supported
cmd[1] = (byte) 0x01;
// authentication method: no-authentication required
cmd[2] = (byte) 0x00;
out.write(cmd);
out.flush();
byte[] response = new byte[2];
in.readFully(response);
// check if server responded with correct version and no-authentication method
if (response[0] != (byte) 0x05 || response[1] != (byte) 0x00) {
throw new SmackException("Remote SOCKS5 server responsed with unexpected version: " + response[0] + ' ' + response[1] + ". Should be 0x05 0x00.");
}
// request SOCKS5 connection with given address/digest
connectionRequest = createSocks5ConnectRequest();
out.write(connectionRequest);
out.flush();
// receive response
connectionResponse = Socks5Utils.receiveSocks5Message(in);
// verify response
// set expected return status to 0
connectionRequest[1] = (byte) 0x00;
if (!Arrays.equals(connectionRequest, connectionResponse)) {
throw new SmackException("Connection request does not equal connection reponse. Response: " + Arrays.toString(connectionResponse) + ". Request: " + Arrays.toString(connectionRequest));
}
}
use of org.jivesoftware.smack.SmackException in project Smack by igniterealtime.
the class Socks5ClientForInitiator method getSocket.
@Override
public Socket getSocket(int timeout) throws IOException, InterruptedException, TimeoutException, XMPPException, SmackException {
Socket socket = null;
// check if stream host is the local SOCKS5 proxy
if (this.streamHost.getJID().equals(this.connection.get().getUser())) {
Socks5Proxy socks5Server = Socks5Proxy.getSocks5Proxy();
socket = socks5Server.getSocket(this.digest);
if (socket == null) {
throw new SmackException("target is not connected to SOCKS5 proxy");
}
} else {
socket = super.getSocket(timeout);
try {
activate();
} catch (XMPPException e1) {
socket.close();
throw e1;
} catch (NoResponseException e2) {
socket.close();
throw e2;
}
}
return socket;
}
use of org.jivesoftware.smack.SmackException in project Smack by igniterealtime.
the class ForwardedProvider method parse.
@Override
public Forwarded parse(XmlPullParser parser, int initialDepth) throws Exception {
DelayInformation di = null;
Stanza packet = null;
outerloop: while (true) {
int eventType = parser.next();
switch(eventType) {
case XmlPullParser.START_TAG:
String name = parser.getName();
String namespace = parser.getNamespace();
switch(name) {
case DelayInformation.ELEMENT:
if (DelayInformation.NAMESPACE.equals(namespace)) {
di = DelayInformationProvider.INSTANCE.parse(parser, parser.getDepth());
} else {
LOGGER.warning("Namespace '" + namespace + "' does not match expected namespace '" + DelayInformation.NAMESPACE + "'");
}
break;
case Message.ELEMENT:
packet = PacketParserUtils.parseMessage(parser);
break;
default:
LOGGER.warning("Unsupported forwarded packet type: " + name);
}
break;
case XmlPullParser.END_TAG:
if (parser.getDepth() == initialDepth) {
break outerloop;
}
break;
}
}
if (packet == null)
throw new SmackException("forwarded extension must contain a packet");
return new Forwarded(di, packet);
}
Aggregations