warn when attempting to write stanza to an unbound stream
This commit is contained in:
		
							parent
							
								
									72cf702e75
								
							
						
					
					
						commit
						e7094af9d5
					
				| @ -3583,7 +3583,7 @@ public class XmppConnectionService extends Service { | |||||||
| 		final XmppConnection connection = account.getXmppConnection(); | 		final XmppConnection connection = account.getXmppConnection(); | ||||||
| 		if (connection != null) { | 		if (connection != null) { | ||||||
| 			IqPacket request = mIqGenerator.generateCreateAccountWithCaptcha(account, id, data); | 			IqPacket request = mIqGenerator.generateCreateAccountWithCaptcha(account, id, data); | ||||||
| 			connection.sendUnmodifiedIqPacket(request, connection.registrationResponseListener); | 			connection.sendUnmodifiedIqPacket(request, connection.registrationResponseListener,true); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -107,9 +107,9 @@ public class XmppConnection implements Runnable { | |||||||
| 	private XmlReader tagReader; | 	private XmlReader tagReader; | ||||||
| 	private TagWriter tagWriter = new TagWriter(); | 	private TagWriter tagWriter = new TagWriter(); | ||||||
| 	private final Features features = new Features(this); | 	private final Features features = new Features(this); | ||||||
| 	private boolean needsBinding = true; |  | ||||||
| 	private boolean shouldAuthenticate = true; | 	private boolean shouldAuthenticate = true; | ||||||
| 	private boolean inSmacksSession = false; | 	private boolean inSmacksSession = false; | ||||||
|  | 	private boolean isBound = false; | ||||||
| 	private Element streamFeatures; | 	private Element streamFeatures; | ||||||
| 	private final HashMap<Jid, ServiceDiscoveryResult> disco = new HashMap<>(); | 	private final HashMap<Jid, ServiceDiscoveryResult> disco = new HashMap<>(); | ||||||
| 
 | 
 | ||||||
| @ -273,11 +273,12 @@ public class XmppConnection implements Runnable { | |||||||
| 		Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": connecting"); | 		Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": connecting"); | ||||||
| 		features.encryptionEnabled = false; | 		features.encryptionEnabled = false; | ||||||
| 		inSmacksSession = false; | 		inSmacksSession = false; | ||||||
|  | 		isBound = false; | ||||||
| 		this.attempt++; | 		this.attempt++; | ||||||
| 		this.verifiedHostname = null; //will be set if user entered hostname is being used or hostname was verified with dnssec | 		this.verifiedHostname = null; //will be set if user entered hostname is being used or hostname was verified with dnssec | ||||||
| 		try { | 		try { | ||||||
| 			Socket localSocket; | 			Socket localSocket; | ||||||
| 			shouldAuthenticate = needsBinding = !account.isOptionSet(Account.OPTION_REGISTER); | 			shouldAuthenticate = !account.isOptionSet(Account.OPTION_REGISTER); | ||||||
| 			this.changeStatus(Account.State.CONNECTING); | 			this.changeStatus(Account.State.CONNECTING); | ||||||
| 			final boolean useTor = mXmppConnectionService.useTorToConnect() || account.isOnion(); | 			final boolean useTor = mXmppConnectionService.useTorToConnect() || account.isOnion(); | ||||||
| 			final boolean extended = mXmppConnectionService.showExtendedConnectionOptions(); | 			final boolean extended = mXmppConnectionService.showExtendedConnectionOptions(); | ||||||
| @ -602,6 +603,7 @@ public class XmppConnection implements Runnable { | |||||||
| 				tagWriter.writeStanzaAsync(r); | 				tagWriter.writeStanzaAsync(r); | ||||||
| 			} else if (nextTag.isStart("resumed")) { | 			} else if (nextTag.isStart("resumed")) { | ||||||
| 				this.inSmacksSession = true; | 				this.inSmacksSession = true; | ||||||
|  | 				this.isBound = true; | ||||||
| 				this.tagWriter.writeStanzaAsync(new RequestPacket(smVersion)); | 				this.tagWriter.writeStanzaAsync(new RequestPacket(smVersion)); | ||||||
| 				lastPacketReceived = SystemClock.elapsedRealtime(); | 				lastPacketReceived = SystemClock.elapsedRealtime(); | ||||||
| 				final Element resumed = tagReader.readElement(nextTag); | 				final Element resumed = tagReader.readElement(nextTag); | ||||||
| @ -878,6 +880,7 @@ public class XmppConnection implements Runnable { | |||||||
| 	private void processStreamFeatures(final Tag currentTag) throws XmlPullParserException, IOException { | 	private void processStreamFeatures(final Tag currentTag) throws XmlPullParserException, IOException { | ||||||
| 		this.streamFeatures = tagReader.readElement(currentTag); | 		this.streamFeatures = tagReader.readElement(currentTag); | ||||||
| 		final boolean isSecure = features.encryptionEnabled || Config.ALLOW_NON_TLS_CONNECTIONS; | 		final boolean isSecure = features.encryptionEnabled || Config.ALLOW_NON_TLS_CONNECTIONS; | ||||||
|  | 		final boolean needsBinding = !isBound && !account.isOptionSet(Account.OPTION_REGISTER); | ||||||
| 		if (this.streamFeatures.hasChild("starttls") && !features.encryptionEnabled) { | 		if (this.streamFeatures.hasChild("starttls") && !features.encryptionEnabled) { | ||||||
| 			sendStartTLS(); | 			sendStartTLS(); | ||||||
| 		} else if (this.streamFeatures.hasChild("register") && account.isOptionSet(Account.OPTION_REGISTER)) { | 		} else if (this.streamFeatures.hasChild("register") && account.isOptionSet(Account.OPTION_REGISTER)) { | ||||||
| @ -975,7 +978,7 @@ public class XmppConnection implements Runnable { | |||||||
| 					register.query("jabber:iq:register").addChild(username); | 					register.query("jabber:iq:register").addChild(username); | ||||||
| 					register.query().addChild(password); | 					register.query().addChild(password); | ||||||
| 					register.setFrom(account.getJid().toBareJid()); | 					register.setFrom(account.getJid().toBareJid()); | ||||||
| 					sendUnmodifiedIqPacket(register, registrationResponseListener); | 					sendUnmodifiedIqPacket(register, registrationResponseListener, true); | ||||||
| 				} else if (query.hasChild("x", Namespace.DATA)) { | 				} else if (query.hasChild("x", Namespace.DATA)) { | ||||||
| 					final Data data = Data.parse(query.findChild("x", Namespace.DATA)); | 					final Data data = Data.parse(query.findChild("x", Namespace.DATA)); | ||||||
| 					final Element blob = query.findChild("data", "urn:xmpp:bob"); | 					final Element blob = query.findChild("data", "urn:xmpp:bob"); | ||||||
| @ -1025,7 +1028,7 @@ public class XmppConnection implements Runnable { | |||||||
| 					throw new StateChangingError(Account.State.REGISTRATION_FAILED); | 					throw new StateChangingError(Account.State.REGISTRATION_FAILED); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		}); | 		},true); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void setAccountCreationFailed(String url) { | 	private void setAccountCreationFailed(String url) { | ||||||
| @ -1065,7 +1068,6 @@ public class XmppConnection implements Runnable { | |||||||
| 			Log.d(Config.LOGTAG,account.getJid().toBareJid()+": interrupted while waiting for DB restore during bind"); | 			Log.d(Config.LOGTAG,account.getJid().toBareJid()+": interrupted while waiting for DB restore during bind"); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 		needsBinding = false; |  | ||||||
| 		clearIqCallbacks(); | 		clearIqCallbacks(); | ||||||
| 		final IqPacket iq = new IqPacket(IqPacket.TYPE.SET); | 		final IqPacket iq = new IqPacket(IqPacket.TYPE.SET); | ||||||
| 		iq.addChild("bind", Namespace.BIND).addChild("resource").setContent(account.getResource()); | 		iq.addChild("bind", Namespace.BIND).addChild("resource").setContent(account.getResource()); | ||||||
| @ -1077,6 +1079,7 @@ public class XmppConnection implements Runnable { | |||||||
| 				} | 				} | ||||||
| 				final Element bind = packet.findChild("bind"); | 				final Element bind = packet.findChild("bind"); | ||||||
| 				if (bind != null && packet.getType() == IqPacket.TYPE.RESULT) { | 				if (bind != null && packet.getType() == IqPacket.TYPE.RESULT) { | ||||||
|  | 					isBound = true; | ||||||
| 					final Element jid = bind.findChild("jid"); | 					final Element jid = bind.findChild("jid"); | ||||||
| 					if (jid != null && jid.getContent() != null) { | 					if (jid != null && jid.getContent() != null) { | ||||||
| 						try { | 						try { | ||||||
| @ -1114,7 +1117,7 @@ public class XmppConnection implements Runnable { | |||||||
| 				} | 				} | ||||||
| 				throw new StateChangingError(Account.State.BIND_FAILURE); | 				throw new StateChangingError(Account.State.BIND_FAILURE); | ||||||
| 			} | 			} | ||||||
| 		}); | 		},true); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void clearIqCallbacks() { | 	private void clearIqCallbacks() { | ||||||
| @ -1154,16 +1157,13 @@ public class XmppConnection implements Runnable { | |||||||
| 		Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": sending legacy session to outdated server"); | 		Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": sending legacy session to outdated server"); | ||||||
| 		final IqPacket startSession = new IqPacket(IqPacket.TYPE.SET); | 		final IqPacket startSession = new IqPacket(IqPacket.TYPE.SET); | ||||||
| 		startSession.addChild("session", "urn:ietf:params:xml:ns:xmpp-session"); | 		startSession.addChild("session", "urn:ietf:params:xml:ns:xmpp-session"); | ||||||
| 		this.sendUnmodifiedIqPacket(startSession, new OnIqPacketReceived() { | 		this.sendUnmodifiedIqPacket(startSession, (account, packet) -> { | ||||||
| 			@Override |  | ||||||
| 			public void onIqPacketReceived(Account account, IqPacket packet) { |  | ||||||
| 			if (packet.getType() == IqPacket.TYPE.RESULT) { | 			if (packet.getType() == IqPacket.TYPE.RESULT) { | ||||||
| 				sendPostBindInitialization(); | 				sendPostBindInitialization(); | ||||||
| 			} else if (packet.getType() != IqPacket.TYPE.TIMEOUT) { | 			} else if (packet.getType() != IqPacket.TYPE.TIMEOUT) { | ||||||
| 				throw new StateChangingError(Account.State.SESSION_FAILURE); | 				throw new StateChangingError(Account.State.SESSION_FAILURE); | ||||||
| 			} | 			} | ||||||
| 			} | 		},true); | ||||||
| 		}); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private void sendPostBindInitialization() { | 	private void sendPostBindInitialization() { | ||||||
| @ -1369,10 +1369,10 @@ public class XmppConnection implements Runnable { | |||||||
| 
 | 
 | ||||||
| 	public String sendIqPacket(final IqPacket packet, final OnIqPacketReceived callback) { | 	public String sendIqPacket(final IqPacket packet, final OnIqPacketReceived callback) { | ||||||
| 		packet.setFrom(account.getJid()); | 		packet.setFrom(account.getJid()); | ||||||
| 		return this.sendUnmodifiedIqPacket(packet, callback); | 		return this.sendUnmodifiedIqPacket(packet, callback, false); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public synchronized String sendUnmodifiedIqPacket(final IqPacket packet, final OnIqPacketReceived callback) { | 	public synchronized String sendUnmodifiedIqPacket(final IqPacket packet, final OnIqPacketReceived callback, boolean force) { | ||||||
| 		if (packet.getId() == null) { | 		if (packet.getId() == null) { | ||||||
| 			packet.setAttribute("id", nextRandomId()); | 			packet.setAttribute("id", nextRandomId()); | ||||||
| 		} | 		} | ||||||
| @ -1381,7 +1381,7 @@ public class XmppConnection implements Runnable { | |||||||
| 				packetCallbacks.put(packet.getId(), new Pair<>(packet, callback)); | 				packetCallbacks.put(packet.getId(), new Pair<>(packet, callback)); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		this.sendPacket(packet); | 		this.sendPacket(packet,force); | ||||||
| 		return packet.getId(); | 		return packet.getId(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -1394,13 +1394,21 @@ public class XmppConnection implements Runnable { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private synchronized void sendPacket(final AbstractStanza packet) { | 	private synchronized void sendPacket(final AbstractStanza packet) { | ||||||
|  | 		sendPacket(packet,false); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	private synchronized void sendPacket(final AbstractStanza packet, final boolean force) { | ||||||
| 		if (stanzasSent == Integer.MAX_VALUE) { | 		if (stanzasSent == Integer.MAX_VALUE) { | ||||||
| 			resetStreamId(); | 			resetStreamId(); | ||||||
| 			disconnect(true); | 			disconnect(true); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 		synchronized (this.mStanzaQueue) { | 		synchronized (this.mStanzaQueue) { | ||||||
|  | 			if (force || isBound) { | ||||||
| 				tagWriter.writeStanzaAsync(packet); | 				tagWriter.writeStanzaAsync(packet); | ||||||
|  | 			} else { | ||||||
|  | 				Log.d(Config.LOGTAG,account.getJid().toBareJid()+" do not write stanza to unbound stream "+packet.toString()); | ||||||
|  | 			} | ||||||
| 			if (packet instanceof AbstractAcknowledgeableStanza) { | 			if (packet instanceof AbstractAcknowledgeableStanza) { | ||||||
| 				AbstractAcknowledgeableStanza stanza = (AbstractAcknowledgeableStanza) packet; | 				AbstractAcknowledgeableStanza stanza = (AbstractAcknowledgeableStanza) packet; | ||||||
| 
 | 
 | ||||||
| @ -1413,7 +1421,7 @@ public class XmppConnection implements Runnable { | |||||||
| 
 | 
 | ||||||
| 				++stanzasSent; | 				++stanzasSent; | ||||||
| 				this.mStanzaQueue.append(stanzasSent, stanza); | 				this.mStanzaQueue.append(stanzasSent, stanza); | ||||||
| 				if (stanza instanceof MessagePacket && stanza.getId() != null && getFeatures().sm()) { | 				if (stanza instanceof MessagePacket && stanza.getId() != null && inSmacksSession) { | ||||||
| 					if (Config.EXTENDED_SM_LOGGING) { | 					if (Config.EXTENDED_SM_LOGGING) { | ||||||
| 						Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": requesting ack for message stanza #" + stanzasSent); | 						Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": requesting ack for message stanza #" + stanzasSent); | ||||||
| 					} | 					} | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Daniel Gultsch
						Daniel Gultsch