正在查看: Housing v14.7.8 应用的 XMPPTCPConnection.java JAVA 源代码文件
本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。
正在查看: Housing v14.7.8 应用的 XMPPTCPConnection.java JAVA 源代码文件
本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。
package org.jivesoftware.smack.tcp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.SocketFactory;
import org.jivesoftware.smack.AbstractConnectionListener;
import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.ConnectionCreationListener;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.StanzaListener;
import org.jivesoftware.smack.SynchronizationPoint;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.compress.packet.Compress;
import org.jivesoftware.smack.compression.XMPPInputOutputStream;
import org.jivesoftware.smack.filter.StanzaFilter;
import org.jivesoftware.smack.filter.StanzaIdFilter;
import org.jivesoftware.smack.packet.Bind;
import org.jivesoftware.smack.packet.Element;
import org.jivesoftware.smack.packet.PlainStreamElement;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.StartTls;
import org.jivesoftware.smack.packet.StreamOpen;
import org.jivesoftware.smack.sm.SMUtils;
import org.jivesoftware.smack.sm.StreamManagementException;
import org.jivesoftware.smack.sm.packet.StreamManagement;
import org.jivesoftware.smack.sm.predicates.Predicate;
import org.jivesoftware.smack.util.ArrayBlockingQueueWithShutdown;
import org.jivesoftware.smack.util.Async;
import org.jivesoftware.smack.util.PacketParserUtils;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.util.dns.HostAddress;
import org.jxmpp.util.XmppStringUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
public class XMPPTCPConnection extends AbstractXMPPConnection {
private static final String PLAIN_FAST_MECHANIM_NAME = "PLAIN_FAST";
private static final int QUEUE_SIZE = 500;
private static final int SECURE_PORT = 5223;
private static BundleAndDeferCallback defaultBundleAndDeferCallback;
private BundleAndDeferCallback bundleAndDeferCallback;
private long clientHandledStanzasCount;
private final SynchronizationPoint<XMPPException> compressSyncPoint;
private final XMPPTCPConnectionConfiguration config;
private boolean disconnectedButResumeable;
private final SynchronizationPoint<Exception> initalOpenStreamSend;
private final SynchronizationPoint<XMPPException> maybeCompressFeaturesReceived;
protected PacketReader packetReader;
protected PacketWriter packetWriter;
private final Set<StanzaFilter> requestAckPredicates;
private String resource;
private long serverHandledStanzasCount;
private int smClientMaxResumptionTime;
private final SynchronizationPoint<XMPPException> smEnabledSyncPoint;
private final SynchronizationPoint<XMPPException> smResumedSyncPoint;
private int smServerMaxResumptimTime;
private String smSessionId;
private boolean smWasEnabledAtLeastOnce;
private Socket socket;
private volatile boolean socketClosed;
private final Collection<StanzaListener> stanzaAcknowledgedListeners;
private final Map<String, StanzaListener> stanzaIdAcknowledgedListeners;
private BlockingQueue<Stanza> unacknowledgedStanzas;
private boolean useSm;
private boolean useSmResumption;
private boolean usingTLS;
private static final Logger LOGGER = Logger.getLogger(XMPPTCPConnection.class.getName());
private static boolean useSmDefault = false;
private static boolean useSmResumptionDefault = true;
public class PacketReader {
static final boolean $assertionsDisabled = false;
private volatile boolean done;
XmlPullParser parser;
public PacketReader() {
}
public void parsePackets() {
throw new UnsupportedOperationException("Method not decompiled: org.jivesoftware.smack.tcp.XMPPTCPConnection.PacketReader.parsePackets():void");
}
public void init() {
this.done = false;
Async.go(new Runnable() {
@Override
public void run() {
PacketReader.this.parsePackets();
}
}, "Smack Packet Reader (" + XMPPTCPConnection.this.getConnectionCounter() + ")");
}
public void shutdown() {
this.done = true;
}
}
public class PacketWriter {
public static final int QUEUE_SIZE = 500;
private volatile boolean instantShutdown;
private boolean shouldBundleAndDefer;
protected SynchronizationPoint<SmackException.NoResponseException> shutdownDone;
private final ArrayBlockingQueueWithShutdown<Element> queue = new ArrayBlockingQueueWithShutdown<>(500, true);
protected volatile Long shutdownTimestamp = null;
public PacketWriter() {
this.shutdownDone = new SynchronizationPoint<>(XMPPTCPConnection.this);
}
public boolean done() {
return this.shutdownTimestamp != null;
}
private void drainWriterQueueToUnacknowledgedStanzas() {
ArrayList arrayList = new ArrayList(this.queue.size());
this.queue.drainTo(arrayList);
Iterator it = arrayList.iterator();
while (it.hasNext()) {
Element element = (Element) it.next();
if (element instanceof Stanza) {
XMPPTCPConnection.this.unacknowledgedStanzas.add((Stanza) element);
}
}
}
private Element nextStreamElement() {
if (this.queue.isEmpty()) {
this.shouldBundleAndDefer = true;
}
try {
return this.queue.take();
} catch (InterruptedException e) {
if (this.queue.isShutdown()) {
return null;
}
XMPPTCPConnection.LOGGER.log(Level.WARNING, "Packet writer thread was interrupted. Don't do that. Use disconnect() instead.", (Throwable) e);
return null;
}
}
public void writePackets() {
Stanza stanza;
try {
try {
XMPPTCPConnection.this.openStream();
XMPPTCPConnection.this.initalOpenStreamSend.reportSuccess();
while (!done()) {
Element nextStreamElement = nextStreamElement();
if (nextStreamElement != null) {
BundleAndDeferCallback bundleAndDeferCallback = XMPPTCPConnection.this.bundleAndDeferCallback;
if (bundleAndDeferCallback != null && XMPPTCPConnection.this.isAuthenticated() && this.shouldBundleAndDefer) {
this.shouldBundleAndDefer = false;
AtomicBoolean atomicBoolean = new AtomicBoolean();
int bundleAndDeferMillis = bundleAndDeferCallback.getBundleAndDeferMillis(new BundleAndDefer(atomicBoolean));
if (bundleAndDeferMillis > 0) {
long j = bundleAndDeferMillis;
long currentTimeMillis = System.currentTimeMillis();
synchronized (atomicBoolean) {
for (long j2 = j; !atomicBoolean.get() && j2 > 0; j2 = j - (System.currentTimeMillis() - currentTimeMillis)) {
try {
atomicBoolean.wait(j2);
} finally {
}
}
}
}
}
if (nextStreamElement instanceof Stanza) {
stanza = (Stanza) nextStreamElement;
} else {
if (nextStreamElement instanceof StreamManagement.Enable) {
XMPPTCPConnection.this.unacknowledgedStanzas = new ArrayBlockingQueue(500);
}
stanza = null;
}
if (XMPPTCPConnection.this.unacknowledgedStanzas != null && stanza != null) {
if (XMPPTCPConnection.this.unacknowledgedStanzas.size() == 400.0d) {
((AbstractXMPPConnection) XMPPTCPConnection.this).writer.write(StreamManagement.AckRequest.INSTANCE.toXML().toString());
((AbstractXMPPConnection) XMPPTCPConnection.this).writer.flush();
}
try {
XMPPTCPConnection.this.unacknowledgedStanzas.put(stanza);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}
((AbstractXMPPConnection) XMPPTCPConnection.this).writer.write(nextStreamElement.toXML().toString());
if (this.queue.isEmpty()) {
((AbstractXMPPConnection) XMPPTCPConnection.this).writer.flush();
}
if (stanza != null) {
XMPPTCPConnection.this.firePacketSendingListeners(stanza);
}
}
}
if (!this.instantShutdown) {
while (!this.queue.isEmpty()) {
try {
((AbstractXMPPConnection) XMPPTCPConnection.this).writer.write(this.queue.remove().toXML().toString());
} catch (Exception e2) {
XMPPTCPConnection.LOGGER.log(Level.WARNING, "Exception flushing queue during shutdown, ignore and continue", (Throwable) e2);
}
}
((AbstractXMPPConnection) XMPPTCPConnection.this).writer.flush();
try {
((AbstractXMPPConnection) XMPPTCPConnection.this).writer.write("</stream:stream>");
((AbstractXMPPConnection) XMPPTCPConnection.this).writer.flush();
} catch (Exception e3) {
XMPPTCPConnection.LOGGER.log(Level.WARNING, "Exception writing closing stream element", (Throwable) e3);
}
this.queue.clear();
} else if (this.instantShutdown && XMPPTCPConnection.this.isSmEnabled()) {
drainWriterQueueToUnacknowledgedStanzas();
}
try {
((AbstractXMPPConnection) XMPPTCPConnection.this).writer.close();
} catch (Exception unused) {
}
} catch (Exception e4) {
if (done() || XMPPTCPConnection.this.isSocketClosed()) {
XMPPTCPConnection.LOGGER.log(Level.FINE, "Ignoring Exception in writePackets()", (Throwable) e4);
} else {
XMPPTCPConnection.this.notifyConnectionError(e4);
}
}
XMPPTCPConnection.LOGGER.fine("Reporting shutdownDone success in writer thread");
this.shutdownDone.reportSuccess();
} catch (Throwable th) {
XMPPTCPConnection.LOGGER.fine("Reporting shutdownDone success in writer thread");
this.shutdownDone.reportSuccess();
throw th;
}
}
public void init() {
this.shutdownDone.init();
this.shutdownTimestamp = null;
if (XMPPTCPConnection.this.unacknowledgedStanzas != null) {
drainWriterQueueToUnacknowledgedStanzas();
}
this.queue.start();
Async.go(new Runnable() {
@Override
public void run() {
PacketWriter.this.writePackets();
}
}, "Smack Packet Writer (" + XMPPTCPConnection.this.getConnectionCounter() + ")");
}
public void sendStreamElement(Element element) throws SmackException.NotConnectedException {
throwNotConnectedExceptionIfDoneAndResumptionNotPossible();
boolean z = false;
while (!z) {
try {
this.queue.put(element);
z = true;
} catch (InterruptedException e) {
throwNotConnectedExceptionIfDoneAndResumptionNotPossible();
XMPPTCPConnection.LOGGER.log(Level.WARNING, "Sending thread was interrupted", (Throwable) e);
}
}
}
public void shutdown(boolean z) {
this.instantShutdown = z;
this.shutdownTimestamp = Long.valueOf(System.currentTimeMillis());
this.queue.shutdown();
try {
this.shutdownDone.checkIfSuccessOrWait();
} catch (SmackException.NoResponseException e) {
XMPPTCPConnection.LOGGER.log(Level.WARNING, "shutdownDone was not marked as successful by the writer thread", (Throwable) e);
}
}
public void throwNotConnectedExceptionIfDoneAndResumptionNotPossible() throws SmackException.NotConnectedException {
if (done() && !XMPPTCPConnection.this.isSmResumptionPossible()) {
throw new SmackException.NotConnectedException();
}
}
}
public XMPPTCPConnection(CharSequence charSequence, String str) {
this(XmppStringUtils.parseLocalpart(charSequence.toString()), str, XmppStringUtils.parseDomain(charSequence.toString()));
}
private void connectUsingConfiguration() throws IOException, SmackException.ConnectionException {
Iterator it;
List<HostAddress> populateHostAddresses = populateHostAddresses();
SocketFactory socketFactory = this.config.getSocketFactory();
if (socketFactory == null) {
socketFactory = SocketFactory.getDefault();
}
for (HostAddress hostAddress : this.hostAddresses) {
String fqdn = hostAddress.getFQDN();
int port = hostAddress.getPort();
this.socket = socketFactory.createSocket();
try {
it = Arrays.asList(InetAddress.getAllByName(fqdn)).iterator();
} catch (Exception e) {
hostAddress.setException(e);
populateHostAddresses.add(hostAddress);
}
if (!it.hasNext()) {
LOGGER.warning("InetAddress.getAllByName() returned empty result array.");
throw new UnknownHostException(fqdn);
}
while (it.hasNext()) {
this.socket = socketFactory.createSocket();
InetAddress inetAddress = (InetAddress) it.next();
String str = inetAddress + " at port " + port;
Logger logger = LOGGER;
logger.finer("Trying to establish TCP connection to " + str);
try {
this.socket.connect(new InetSocketAddress(inetAddress, port), this.config.getConnectTimeout());
logger.finer("Established TCP connection to " + str);
this.host = fqdn;
this.port = port;
return;
} catch (Exception e2) {
if (!it.hasNext()) {
throw e2;
}
}
}
}
throw SmackException.ConnectionException.from(populateHostAddresses);
}
public void dropSmState() {
this.smSessionId = null;
this.unacknowledgedStanzas = null;
}
private void initConnection() throws IOException {
boolean z = this.packetReader == null || this.packetWriter == null;
this.compressionHandler = null;
initReaderAndWriter();
if (z) {
this.packetWriter = new PacketWriter();
this.packetReader = new PacketReader();
if (this.config.isDebuggerEnabled()) {
addAsyncStanzaListener(this.debugger.getReaderListener(), null);
if (this.debugger.getWriterListener() != null) {
addPacketSendingListener(this.debugger.getWriterListener(), null);
}
}
}
this.packetWriter.init();
this.packetReader.init();
if (z) {
Iterator<ConnectionCreationListener> it = AbstractXMPPConnection.getConnectionCreationListeners().iterator();
while (it.hasNext()) {
it.next().connectionCreated(this);
}
}
}
private void initCurrentUser(String str, String str2, String str3) {
this.user = XmppStringUtils.completeJidFrom(str, str2, str3);
}
public void initReaderAndWriter() throws IOException {
InputStream inputStream = this.socket.getInputStream();
OutputStream outputStream = this.socket.getOutputStream();
XMPPInputOutputStream xMPPInputOutputStream = this.compressionHandler;
if (xMPPInputOutputStream != null) {
inputStream = xMPPInputOutputStream.getInputStream(inputStream);
outputStream = this.compressionHandler.getOutputStream(outputStream);
}
this.writer = new OutputStreamWriter(outputStream, "UTF-8");
this.reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
initDebugger();
}
private XMPPInputOutputStream maybeGetCompressionHandler() {
Compress.Feature feature = (Compress.Feature) getFeature(Compress.Feature.ELEMENT, "http://jabber.org/protocol/compress");
if (feature == null) {
return null;
}
for (XMPPInputOutputStream xMPPInputOutputStream : SmackConfiguration.getCompresionHandlers()) {
if (feature.getMethods().contains(xMPPInputOutputStream.getCompressionMethod())) {
return xMPPInputOutputStream;
}
}
return null;
}
public synchronized void notifyConnectionError(Exception exc) {
try {
PacketReader packetReader = this.packetReader;
if (packetReader != null) {
if (packetReader.done) {
}
instantShutdown();
callConnectionClosedOnErrorListener(exc);
}
PacketWriter packetWriter = this.packetWriter;
if (packetWriter != null) {
if (packetWriter.done()) {
}
instantShutdown();
callConnectionClosedOnErrorListener(exc);
}
} finally {
}
}
public void proceedTLSReceived() throws java.security.NoSuchAlgorithmException, java.security.cert.CertificateException, java.io.IOException, java.security.KeyStoreException, java.security.NoSuchProviderException, java.security.UnrecoverableKeyException, java.security.KeyManagementException, org.jivesoftware.smack.SmackException {
throw new UnsupportedOperationException("Method not decompiled: org.jivesoftware.smack.tcp.XMPPTCPConnection.proceedTLSReceived():void");
}
public void processHandledCount(long j) throws StreamManagementException.StreamManagementCounterError {
long calculateDelta = SMUtils.calculateDelta(j, this.serverHandledStanzasCount);
final ArrayList arrayList = new ArrayList(calculateDelta <= 2147483647L ? (int) calculateDelta : Integer.MAX_VALUE);
for (long j2 = 0; j2 < calculateDelta; j2++) {
Stanza poll = this.unacknowledgedStanzas.poll();
if (poll == null) {
throw new StreamManagementException.StreamManagementCounterError(j, this.serverHandledStanzasCount, calculateDelta, arrayList);
}
arrayList.add(poll);
}
if (this.stanzaAcknowledgedListeners.isEmpty()) {
Iterator it = arrayList.iterator();
while (it.hasNext()) {
String stanzaId = ((Stanza) it.next()).getStanzaId();
if (stanzaId == null || !this.stanzaIdAcknowledgedListeners.containsKey(stanzaId)) {
}
}
this.serverHandledStanzasCount = j;
}
asyncGo(new Runnable() {
@Override
public void run() {
StanzaListener stanzaListener;
for (Stanza stanza : arrayList) {
Iterator it2 = XMPPTCPConnection.this.stanzaAcknowledgedListeners.iterator();
while (it2.hasNext()) {
try {
((StanzaListener) it2.next()).processPacket(stanza);
} catch (SmackException.NotConnectedException e) {
XMPPTCPConnection.LOGGER.log(Level.FINER, "Received not connected exception", (Throwable) e);
}
}
String stanzaId2 = stanza.getStanzaId();
if (!StringUtils.isNullOrEmpty(stanzaId2) && (stanzaListener = (StanzaListener) XMPPTCPConnection.this.stanzaIdAcknowledgedListeners.remove(stanzaId2)) != null) {
try {
stanzaListener.processPacket(stanza);
} catch (SmackException.NotConnectedException e2) {
XMPPTCPConnection.LOGGER.log(Level.FINER, "Received not connected exception", (Throwable) e2);
}
}
}
}
});
this.serverHandledStanzasCount = j;
}
public void requestSmAcknowledgementInternal() throws SmackException.NotConnectedException {
this.packetWriter.sendStreamElement(StreamManagement.AckRequest.INSTANCE);
}
public void sendSmAcknowledgementInternal() throws SmackException.NotConnectedException {
this.packetWriter.sendStreamElement(new StreamManagement.AckAnswer(this.clientHandledStanzasCount));
}
public static void setDefaultBundleAndDeferCallback(BundleAndDeferCallback bundleAndDeferCallback) {
defaultBundleAndDeferCallback = bundleAndDeferCallback;
}
public static void setUseStreamManagementDefault(boolean z) {
useSmDefault = z;
}
@Deprecated
public static void setUseStreamManagementResumptiodDefault(boolean z) {
setUseStreamManagementResumptionDefault(z);
}
public static void setUseStreamManagementResumptionDefault(boolean z) {
if (z) {
setUseStreamManagementDefault(z);
}
useSmResumptionDefault = z;
}
private void useCompression() throws SmackException.NotConnectedException, SmackException.NoResponseException, XMPPException {
this.maybeCompressFeaturesReceived.checkIfSuccessOrWait();
XMPPInputOutputStream maybeGetCompressionHandler = maybeGetCompressionHandler();
this.compressionHandler = maybeGetCompressionHandler;
if (maybeGetCompressionHandler != null) {
this.compressSyncPoint.sendAndWaitForResponseOrThrow(new Compress(maybeGetCompressionHandler.getCompressionMethod()));
} else {
LOGGER.warning("Could not enable compression because no matching handler/method pair was found");
}
}
public boolean addRequestAckPredicate(StanzaFilter stanzaFilter) {
boolean add;
synchronized (this.requestAckPredicates) {
add = this.requestAckPredicates.add(stanzaFilter);
}
return add;
}
public void addStanzaAcknowledgedListener(StanzaListener stanzaListener) {
this.stanzaAcknowledgedListeners.add(stanzaListener);
}
public StanzaListener addStanzaIdAcknowledgedListener(final String str, StanzaListener stanzaListener) throws StreamManagementException.StreamManagementNotEnabledException {
if (!this.smWasEnabledAtLeastOnce) {
throw new StreamManagementException.StreamManagementNotEnabledException();
}
schedule(new Runnable() {
@Override
public void run() {
XMPPTCPConnection.this.stanzaIdAcknowledgedListeners.remove(str);
}
}, Math.min(getMaxSmResumptionTime(), 43200), TimeUnit.SECONDS);
return this.stanzaIdAcknowledgedListeners.put(str, stanzaListener);
}
@Override
public void afterFeaturesReceived() throws SmackException.SecurityRequiredException, SmackException.NotConnectedException {
StartTls startTls = (StartTls) getFeature(StartTls.ELEMENT, StartTls.NAMESPACE);
if (startTls == null || 5223 == getPort()) {
if (5223 == getPort()) {
this.saslFeatureReceived.reportSuccess();
return;
}
} else if (startTls.required() && this.config.getSecurityMode() == ConnectionConfiguration.SecurityMode.disabled) {
notifyConnectionError(new SmackException.SecurityRequiredByServerException());
return;
} else if (this.config.getSecurityMode() != ConnectionConfiguration.SecurityMode.disabled) {
send(new StartTls());
}
if (!isSecureConnection() && startTls == null && getConfiguration().getSecurityMode() == ConnectionConfiguration.SecurityMode.required) {
throw new SmackException.SecurityRequiredByClientException();
}
if (getSASLAuthentication().authenticationSuccessful()) {
this.maybeCompressFeaturesReceived.reportSuccess();
}
}
@Override
public void afterSuccessfulLogin(boolean z) throws SmackException.NotConnectedException {
this.disconnectedButResumeable = false;
super.afterSuccessfulLogin(z);
}
@Override
public void bindResourceAndEstablishSession(String str) throws XMPPException.XMPPErrorException, IOException, SmackException {
if (5223 != getPort()) {
super.bindResourceAndEstablishSession(str);
} else {
Bind newSet = Bind.newSet(str);
this.user = ((Bind) createPacketCollectorAndSend(new StanzaIdFilter(newSet), newSet).nextResultOrThrow()).getJid();
}
}
@Override
public void connectInternal() throws SmackException, IOException, XMPPException {
connectUsingConfiguration();
this.socketClosed = false;
if (5223 == getPort()) {
try {
proceedTLSReceived();
} catch (Exception e) {
this.saslFeatureReceived.reportFailure(new SmackException(e));
}
}
initConnection();
this.saslFeatureReceived.checkIfSuccessOrWaitOrThrow();
this.connected = true;
callConnectionConnectedListener();
if (this.wasAuthenticated) {
login();
notifyReconnection();
}
}
public int getMaxSmResumptionTime() {
int i = this.smClientMaxResumptionTime;
if (i <= 0) {
i = Integer.MAX_VALUE;
}
int i2 = this.smServerMaxResumptimTime;
return Math.min(i, i2 > 0 ? i2 : Integer.MAX_VALUE);
}
public String getResource() {
return this.resource;
}
public synchronized void instantShutdown() {
shutdown(true);
}
public boolean isDisconnectedButSmResumptionPossible() {
return this.disconnectedButResumeable && isSmResumptionPossible();
}
@Override
public boolean isSecureConnection() {
return this.usingTLS;
}
public boolean isSmAvailable() {
return hasFeature(StreamManagement.StreamManagementFeature.ELEMENT, StreamManagement.NAMESPACE);
}
public boolean isSmEnabled() {
return this.smEnabledSyncPoint.wasSuccessful();
}
public boolean isSmResumptionPossible() {
if (this.smSessionId == null) {
return false;
}
Long l = this.packetWriter.shutdownTimestamp;
if (l == null) {
return true;
}
return System.currentTimeMillis() <= l.longValue() + (((long) getMaxSmResumptionTime()) * 1000);
}
public boolean isSocketClosed() {
return this.socketClosed;
}
@Override
public boolean isUsingCompression() {
return this.compressionHandler != null && this.compressSyncPoint.wasSuccessful();
}
@Override
public synchronized void loginAnonymously() throws XMPPException, SmackException, IOException {
try {
this.saslFeatureReceived.checkIfSuccessOrWaitOrThrow();
if (!this.saslAuthentication.hasAnonymousAuthentication()) {
throw new SmackException("No anonymous SASL authentication mechanism available");
}
this.saslAuthentication.authenticateAnonymously();
if (this.config.isCompressionEnabled()) {
useCompression();
}
bindResourceAndEstablishSession(null);
afterSuccessfulLogin(false);
} catch (Throwable th) {
throw th;
}
}
@Override
public synchronized void loginNonAnonymously(String str, String str2, String str3) throws XMPPException, SmackException, IOException {
try {
if (!this.saslAuthentication.hasNonAnonymousAuthentication()) {
throw new SmackException("No non-anonymous SASL authentication mechanism available");
}
this.resource = str3;
if (str2 != null) {
this.saslAuthentication.authenticate(str, str2, str3);
} else {
this.saslAuthentication.authenticate(str3, this.config.getCallbackHandler());
}
if (this.config.isCompressionEnabled()) {
useCompression();
}
if (isSmResumptionPossible()) {
this.smResumedSyncPoint.sendAndWaitForResponse(new StreamManagement.Resume(this.clientHandledStanzasCount, this.smSessionId));
if (this.smResumedSyncPoint.wasSuccessful()) {
afterSuccessfulLogin(true);
return;
}
LOGGER.fine("Stream resumption failed, continuing with normal stream establishment process");
}
LinkedList linkedList = new LinkedList();
BlockingQueue<Stanza> blockingQueue = this.unacknowledgedStanzas;
if (blockingQueue != null) {
blockingQueue.drainTo(linkedList);
dropSmState();
}
if (PLAIN_FAST_MECHANIM_NAME.equals(this.saslAuthentication.getCurrentMechanism().getName())) {
initCurrentUser(str, getServiceName(), str3);
} else {
bindResourceAndEstablishSession(str3);
}
if (isSmAvailable() && this.useSm) {
this.serverHandledStanzasCount = 0L;
this.smEnabledSyncPoint.sendAndWaitForResponseOrThrow(new StreamManagement.Enable(this.useSmResumption, this.smClientMaxResumptionTime));
synchronized (this.requestAckPredicates) {
try {
if (this.requestAckPredicates.isEmpty()) {
this.requestAckPredicates.add(Predicate.forMessagesOrAfter5Stanzas());
}
} finally {
}
}
}
Iterator it = linkedList.iterator();
while (it.hasNext()) {
sendStanzaInternal((Stanza) it.next());
}
afterSuccessfulLogin(false);
} catch (Throwable th) {
throw th;
}
}
public void openStream() throws SmackException {
String serviceName = getServiceName();
CharSequence username = this.config.getUsername();
send(new StreamOpen(serviceName, username != null ? XmppStringUtils.completeJidFrom(username, serviceName) : null, getStreamId()));
try {
this.packetReader.parser = PacketParserUtils.newXmppParser(this.reader);
} catch (XmlPullParserException e) {
throw new SmackException(e);
}
}
public void removeAllRequestAckPredicates() {
synchronized (this.requestAckPredicates) {
this.requestAckPredicates.clear();
}
}
public void removeAllStanzaAcknowledgedListeners() {
this.stanzaAcknowledgedListeners.clear();
}
public void removeAllStanzaIdAcknowledgedListeners() {
this.stanzaIdAcknowledgedListeners.clear();
}
public boolean removeRequestAckPredicate(StanzaFilter stanzaFilter) {
boolean remove;
synchronized (this.requestAckPredicates) {
remove = this.requestAckPredicates.remove(stanzaFilter);
}
return remove;
}
public boolean removeStanzaAcknowledgedListener(StanzaListener stanzaListener) {
return this.stanzaAcknowledgedListeners.remove(stanzaListener);
}
public StanzaListener removeStanzaIdAcknowledgedListener(String str) {
return this.stanzaIdAcknowledgedListeners.remove(str);
}
public void requestSmAcknowledgement() throws StreamManagementException.StreamManagementNotEnabledException, SmackException.NotConnectedException {
if (!isSmEnabled()) {
throw new StreamManagementException.StreamManagementNotEnabledException();
}
requestSmAcknowledgementInternal();
}
@Override
public void send(PlainStreamElement plainStreamElement) throws SmackException.NotConnectedException {
this.packetWriter.sendStreamElement(plainStreamElement);
}
public void sendSmAcknowledgement() throws StreamManagementException.StreamManagementNotEnabledException, SmackException.NotConnectedException {
if (!isSmEnabled()) {
throw new StreamManagementException.StreamManagementNotEnabledException();
}
sendSmAcknowledgementInternal();
}
@Override
public void sendStanzaInternal(Stanza stanza) throws SmackException.NotConnectedException {
this.packetWriter.sendStreamElement(stanza);
if (isSmEnabled()) {
Iterator<StanzaFilter> it = this.requestAckPredicates.iterator();
while (it.hasNext()) {
if (it.next().accept(stanza)) {
requestSmAcknowledgementInternal();
return;
}
}
}
}
public void setBundleandDeferCallback(BundleAndDeferCallback bundleAndDeferCallback) {
this.bundleAndDeferCallback = bundleAndDeferCallback;
}
public void setPreferredResumptionTime(int i) {
this.smClientMaxResumptionTime = i;
}
public void setUseStreamManagement(boolean z) {
this.useSm = z;
}
public void setUseStreamManagementResumption(boolean z) {
if (z) {
setUseStreamManagement(z);
}
this.useSmResumption = z;
}
public void setWriter(Writer writer) {
this.writer = writer;
}
@Override
public void shutdown() {
if (isSmEnabled()) {
try {
sendSmAcknowledgementInternal();
} catch (SmackException.NotConnectedException e) {
LOGGER.log(Level.FINE, "Can not send final SM ack as connection is not connected", (Throwable) e);
}
}
shutdown(false);
}
public boolean streamWasResumed() {
return this.smResumedSyncPoint.wasSuccessful();
}
@Override
public void throwAlreadyConnectedExceptionIfAppropriate() throws SmackException.AlreadyConnectedException {
if (isConnected() && !this.disconnectedButResumeable) {
throw new SmackException.AlreadyConnectedException();
}
}
@Override
public void throwAlreadyLoggedInExceptionIfAppropriate() throws SmackException.AlreadyLoggedInException {
if (isAuthenticated() && !this.disconnectedButResumeable) {
throw new SmackException.AlreadyLoggedInException();
}
}
@Override
public void throwNotConnectedExceptionIfAppropriate() throws SmackException.NotConnectedException {
PacketWriter packetWriter = this.packetWriter;
if (packetWriter == null) {
throw new SmackException.NotConnectedException();
}
packetWriter.throwNotConnectedExceptionIfDoneAndResumptionNotPossible();
}
public XMPPTCPConnection(CharSequence charSequence, String str, String str2) {
this(XMPPTCPConnectionConfiguration.builder().setUsernameAndPassword(charSequence, str).setServiceName(str2).build());
}
private void shutdown(boolean z) {
if (this.disconnectedButResumeable) {
return;
}
PacketReader packetReader = this.packetReader;
if (packetReader != null) {
packetReader.shutdown();
}
PacketWriter packetWriter = this.packetWriter;
if (packetWriter != null) {
packetWriter.shutdown(z);
}
this.socketClosed = true;
try {
this.socket.close();
} catch (Exception e) {
LOGGER.log(Level.WARNING, "shutdown", (Throwable) e);
}
setWasAuthenticated();
if (isSmResumptionPossible() && z) {
this.disconnectedButResumeable = true;
} else {
this.disconnectedButResumeable = false;
this.smSessionId = null;
}
this.authenticated = false;
this.connected = false;
this.usingTLS = false;
this.reader = null;
this.writer = null;
this.maybeCompressFeaturesReceived.init();
this.compressSyncPoint.init();
this.smResumedSyncPoint.init();
this.smEnabledSyncPoint.init();
this.initalOpenStreamSend.init();
}
public XMPPTCPConnection(XMPPTCPConnectionConfiguration xMPPTCPConnectionConfiguration) {
super(xMPPTCPConnectionConfiguration);
this.disconnectedButResumeable = false;
this.socketClosed = false;
this.usingTLS = false;
this.initalOpenStreamSend = new SynchronizationPoint<>(this);
this.maybeCompressFeaturesReceived = new SynchronizationPoint<>(this);
this.compressSyncPoint = new SynchronizationPoint<>(this);
this.bundleAndDeferCallback = defaultBundleAndDeferCallback;
this.smResumedSyncPoint = new SynchronizationPoint<>(this);
this.smEnabledSyncPoint = new SynchronizationPoint<>(this);
this.smClientMaxResumptionTime = -1;
this.smServerMaxResumptimTime = -1;
this.useSm = useSmDefault;
this.useSmResumption = useSmResumptionDefault;
this.serverHandledStanzasCount = 0L;
this.clientHandledStanzasCount = 0L;
this.smWasEnabledAtLeastOnce = false;
this.stanzaAcknowledgedListeners = new ConcurrentLinkedQueue();
this.stanzaIdAcknowledgedListeners = new ConcurrentHashMap();
this.requestAckPredicates = new LinkedHashSet();
this.config = xMPPTCPConnectionConfiguration;
addConnectionListener(new AbstractConnectionListener() {
@Override
public void connectionClosedOnError(Exception exc) {
if (exc instanceof XMPPException.StreamErrorException) {
XMPPTCPConnection.this.dropSmState();
}
}
});
}
}