Check for disco support before file transfers

This commit is contained in:
vanitasvitae 2017-08-07 14:35:00 +02:00
parent 6fad0b9fab
commit cac35d74b4
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
6 changed files with 37 additions and 22 deletions

View File

@ -22,6 +22,7 @@ import java.util.WeakHashMap;
import java.util.logging.Logger;
import org.jivesoftware.smack.Manager;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.provider.ExtensionElementProvider;
import org.jivesoftware.smackx.ciphers.Aes256GcmNoPadding;
@ -82,6 +83,11 @@ public final class JetManager extends Manager implements JingleDescriptionManage
throw new IllegalArgumentException("File MUST NOT be null and MUST exist.");
}
ServiceDiscoveryManager disco = ServiceDiscoveryManager.getInstanceFor(connection());
if (!disco.supportsFeature(recipient, getNamespace()) || !disco.supportsFeature(recipient, method.getNamespace())) {
throw new SmackException.FeatureNotSupportedException(getNamespace(), recipient);
}
JingleSession session = jingleManager.createSession(Role.initiator, recipient);
JingleContent content = new JingleContent(JingleContentElement.Creator.initiator, JingleContentElement.Senders.initiator);
@ -90,7 +96,7 @@ public final class JetManager extends Manager implements JingleDescriptionManage
JingleOutgoingFileOffer offer = new JingleOutgoingFileOffer(file);
content.setDescription(offer);
JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager();
JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager(recipient);
content.setTransport(transportManager.createTransportForInitiator(content));
JetSecurity security = new JetSecurity(method, recipient, content.getName(), Aes256GcmNoPadding.NAMESPACE);

View File

@ -90,12 +90,16 @@ public final class JingleFileTransferManager extends Manager implements JingleDe
public OutgoingFileOfferController sendFile(File file, FullJid to)
throws SmackException.NotConnectedException, InterruptedException, XMPPException.XMPPErrorException,
SmackException.NoResponseException {
SmackException.NoResponseException, SmackException.FeatureNotSupportedException {
if (file == null || !file.exists()) {
throw new IllegalArgumentException("File MUST NOT be null and MUST exist.");
}
if (!ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(to, getNamespace())) {
throw new SmackException.FeatureNotSupportedException(getNamespace(), to);
}
JingleSession session = jingleManager.createSession(Role.initiator, to);
JingleContent content = new JingleContent(JingleContentElement.Creator.initiator, JingleContentElement.Senders.initiator);
@ -104,7 +108,7 @@ public final class JingleFileTransferManager extends Manager implements JingleDe
JingleOutgoingFileOffer offer = new JingleOutgoingFileOffer(file);
content.setDescription(offer);
JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager();
JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager(to);
content.setTransport(transportManager.createTransportForInitiator(content));
session.initiate(connection());

View File

@ -28,11 +28,14 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.jivesoftware.smack.Manager;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
import org.jivesoftware.smack.iqrequest.IQRequestHandler;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.jingle.adapter.JingleDescriptionAdapter;
import org.jivesoftware.smackx.jingle.adapter.JingleSecurityAdapter;
import org.jivesoftware.smackx.jingle.adapter.JingleTransportAdapter;
@ -50,6 +53,7 @@ import org.jivesoftware.smackx.jingle.util.FullJidAndSessionId;
import org.jivesoftware.smackx.jingle.util.Role;
import org.jxmpp.jid.FullJid;
import org.jxmpp.jid.Jid;
/**
* Manager for Jingle (XEP-0166).
@ -213,17 +217,19 @@ public final class JingleManager extends Manager {
return securityManagers.get(namespace);
}
public List<JingleTransportManager> getAvailableTransportManagers() {
return getAvailableTransportManagers(Collections.<String>emptySet());
public List<JingleTransportManager> getAvailableTransportManagers(Jid to) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
return getAvailableTransportManagers(to, Collections.<String>emptySet());
}
public List<JingleTransportManager> getAvailableTransportManagers(Set<String> except) {
public List<JingleTransportManager> getAvailableTransportManagers(Jid to, Set<String> except) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
Set<String> available = new HashSet<>(transportManagers.keySet());
available.removeAll(except);
List<JingleTransportManager> remaining = new ArrayList<>();
for (String namespace : available) {
remaining.add(transportManagers.get(namespace));
if (ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(to, namespace)) {
remaining.add(transportManagers.get(namespace));
}
}
Collections.sort(remaining, new Comparator<JingleTransportManager>() {
@ -236,12 +242,12 @@ public final class JingleManager extends Manager {
return remaining;
}
public JingleTransportManager getBestAvailableTransportManager() {
return getBestAvailableTransportManager(Collections.<String>emptySet());
public JingleTransportManager getBestAvailableTransportManager(Jid to) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
return getBestAvailableTransportManager(to, Collections.<String>emptySet());
}
public JingleTransportManager getBestAvailableTransportManager(Set<String> except) {
List<JingleTransportManager> managers = getAvailableTransportManagers(except);
public JingleTransportManager getBestAvailableTransportManager(Jid to, Set<String> except) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
List<JingleTransportManager> managers = getAvailableTransportManagers(to, except);
if (managers.size() > 0) {
return managers.get(0);

View File

@ -146,7 +146,7 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
}
public void handleContentAccept(JingleElement request, XMPPConnection connection) {
onAccept(connection);
start(connection);
}
@ -165,7 +165,7 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
}
getTransport().handleSessionAccept(contentElement.getTransport(), connection);
onAccept(connection);
start(connection);
return IQ.createResultIQ(request);
}
@ -198,7 +198,7 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
transport = pendingReplacingTransport;
pendingReplacingTransport = null;
onAccept(connection);
start(connection);
return IQ.createResultIQ(request);
}
@ -285,7 +285,7 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
}
}
});
onAccept(connection);
start(connection);
}
return IQ.createResultIQ(request);
@ -384,8 +384,7 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
getSenders() == JingleContentElement.Senders.both;
}
public void onAccept(final XMPPConnection connection) {
LOGGER.log(Level.INFO, "Accepted content " + getName());
public void start(final XMPPConnection connection) {
transport.prepare(connection);
if (security != null) {
@ -416,7 +415,7 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
@Override
public void onTransportReady(BytestreamSession bytestreamSession) {
LOGGER.log(Level.INFO, "TransportReady: " + (isReceiving() ? "Send" : "Receive"));
LOGGER.log(Level.INFO, "TransportReady: " + (isReceiving() ? "Receive" : "Send"));
if (bytestreamSession == null) {
throw new AssertionError("bytestreamSession MUST NOT be null at this point.");
}
@ -469,7 +468,7 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
JingleSession session = getParent();
JingleManager jingleManager = session.getJingleManager();
JingleTransportManager rManager = jingleManager.getBestAvailableTransportManager(blacklist);
JingleTransportManager rManager = jingleManager.getBestAvailableTransportManager(getParent().getPeer(), blacklist);
if (rManager == null) {
JingleElement failedTransport = JingleElement.createSessionTerminate(session.getPeer(),
session.getSessionId(), JingleReasonElement.Reason.failed_transport);

View File

@ -111,7 +111,7 @@ public class JingleSession {
}
for (JingleContent content : contents.values()) {
content.onAccept(connection);
content.start(connection);
}
connection.createStanzaCollectorAndSend(createSessionAccept()).nextResultOrThrow();

View File

@ -113,10 +113,10 @@ public class JingleS5BTransportCandidate extends JingleTransportCandidate<Jingle
case direct:
if (peersProposal) {
LOGGER.log(Level.INFO, "Connect to foreign direct candidate " + getCandidateId());
LOGGER.log(Level.INFO, "Connect to foreign direct candidate " + getCandidateId() + " Address: " + getStreamHost().getAddress() + ":" + getStreamHost().getPort());
this.socket = new Socket(getStreamHost().getAddress(), getStreamHost().getPort());
} else {
LOGGER.log(Level.INFO, "Connect to our direct candidate " + getCandidateId());
LOGGER.log(Level.INFO, "Connect to our direct candidate " + getCandidateId() + " at port " + getStreamHost().getPort());
this.socket = new ServerSocket(getStreamHost().getPort()).accept();
}
break;