use of org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream 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.smackx.bytestreams.socks5.packet.Bytestream in project Smack by igniterealtime.
the class Socks5ClientForInitiator method createStreamHostActivation.
/**
* Returns a SOCKS5 Bytestream activation packet.
*
* @return SOCKS5 Bytestream activation packet
*/
private Bytestream createStreamHostActivation() {
Bytestream activate = new Bytestream(this.sessionID);
activate.setMode(null);
activate.setType(IQ.Type.set);
activate.setTo(this.streamHost.getJID());
activate.setToActivate(this.target);
return activate;
}
use of org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream in project Smack by igniterealtime.
the class BytestreamsProvider method parse.
@Override
public Bytestream parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException {
boolean done = false;
Bytestream toReturn = new Bytestream();
String id = parser.getAttributeValue("", "sid");
String mode = parser.getAttributeValue("", "mode");
// streamhost
Jid JID = null;
String host = null;
String port = null;
int eventType;
String elementName;
while (!done) {
eventType = parser.next();
elementName = parser.getName();
if (eventType == XmlPullParser.START_TAG) {
if (elementName.equals(Bytestream.StreamHost.ELEMENTNAME)) {
JID = ParserUtils.getJidAttribute(parser);
host = parser.getAttributeValue("", "host");
port = parser.getAttributeValue("", "port");
} else if (elementName.equals(Bytestream.StreamHostUsed.ELEMENTNAME)) {
toReturn.setUsedHost(ParserUtils.getJidAttribute(parser));
} else if (elementName.equals(Bytestream.Activate.ELEMENTNAME)) {
toReturn.setToActivate(ParserUtils.getJidAttribute(parser));
}
} else if (eventType == XmlPullParser.END_TAG) {
if (elementName.equals("streamhost")) {
if (port == null) {
toReturn.addStreamHost(JID, host);
} else {
toReturn.addStreamHost(JID, host, Integer.parseInt(port));
}
JID = null;
host = null;
port = null;
} else if (elementName.equals("query")) {
done = true;
}
}
}
if (mode == null) {
toReturn.setMode(Mode.tcp);
} else {
toReturn.setMode((Bytestream.Mode.fromName(mode)));
}
toReturn.setSessionID(id);
return toReturn;
}
use of org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream in project Smack by igniterealtime.
the class InitiationListener method processRequest.
private void processRequest(Stanza packet) throws NotConnectedException, InterruptedException {
Bytestream byteStreamRequest = (Bytestream) packet;
StreamNegotiator.signal(byteStreamRequest.getFrom().toString() + '\t' + byteStreamRequest.getSessionID(), byteStreamRequest);
// ignore request if in ignore list
if (this.manager.getIgnoredBytestreamRequests().remove(byteStreamRequest.getSessionID())) {
return;
}
// build bytestream request from packet
Socks5BytestreamRequest request = new Socks5BytestreamRequest(this.manager, byteStreamRequest);
// notify listeners for bytestream initiation from a specific user
BytestreamListener userListener = this.manager.getUserListener(byteStreamRequest.getFrom());
if (userListener != null) {
userListener.incomingBytestreamRequest(request);
} else if (!this.manager.getAllRequestListeners().isEmpty()) {
/*
* if there is no user specific listener inform listeners for all initiation requests
*/
for (BytestreamListener listener : this.manager.getAllRequestListeners()) {
listener.incomingBytestreamRequest(request);
}
} else {
/*
* if there is no listener for this initiation request, reply with reject message
*/
this.manager.replyRejectPacket(byteStreamRequest);
}
}
use of org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream in project Smack by igniterealtime.
the class Socks5BytestreamRequest method createUsedHostResponse.
/**
* Returns the response to the SOCKS5 Bytestream request containing the SOCKS5 proxy used.
*
* @param selectedHost the used SOCKS5 proxy
* @return the response to the SOCKS5 Bytestream request
*/
private Bytestream createUsedHostResponse(StreamHost selectedHost) {
Bytestream response = new Bytestream(this.bytestreamRequest.getSessionID());
response.setTo(this.bytestreamRequest.getFrom());
response.setType(IQ.Type.result);
response.setStanzaId(this.bytestreamRequest.getStanzaId());
response.setUsedHost(selectedHost.getJID());
return response;
}
Aggregations