1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2024-11-23 20:42:06 +01:00

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 java.util.logging.Logger;
import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.Manager;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.provider.ExtensionElementProvider; import org.jivesoftware.smack.provider.ExtensionElementProvider;
import org.jivesoftware.smackx.ciphers.Aes256GcmNoPadding; 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."); 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); JingleSession session = jingleManager.createSession(Role.initiator, recipient);
JingleContent content = new JingleContent(JingleContentElement.Creator.initiator, JingleContentElement.Senders.initiator); 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); JingleOutgoingFileOffer offer = new JingleOutgoingFileOffer(file);
content.setDescription(offer); content.setDescription(offer);
JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager(); JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager(recipient);
content.setTransport(transportManager.createTransportForInitiator(content)); content.setTransport(transportManager.createTransportForInitiator(content));
JetSecurity security = new JetSecurity(method, recipient, content.getName(), Aes256GcmNoPadding.NAMESPACE); 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) public OutgoingFileOfferController sendFile(File file, FullJid to)
throws SmackException.NotConnectedException, InterruptedException, XMPPException.XMPPErrorException, throws SmackException.NotConnectedException, InterruptedException, XMPPException.XMPPErrorException,
SmackException.NoResponseException { SmackException.NoResponseException, SmackException.FeatureNotSupportedException {
if (file == null || !file.exists()) { if (file == null || !file.exists()) {
throw new IllegalArgumentException("File MUST NOT be null and MUST exist."); 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); JingleSession session = jingleManager.createSession(Role.initiator, to);
JingleContent content = new JingleContent(JingleContentElement.Creator.initiator, JingleContentElement.Senders.initiator); 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); JingleOutgoingFileOffer offer = new JingleOutgoingFileOffer(file);
content.setDescription(offer); content.setDescription(offer);
JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager(); JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager(to);
content.setTransport(transportManager.createTransportForInitiator(content)); content.setTransport(transportManager.createTransportForInitiator(content));
session.initiate(connection()); session.initiate(connection());

View file

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

View file

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

View file

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

View file

@ -113,10 +113,10 @@ public class JingleS5BTransportCandidate extends JingleTransportCandidate<Jingle
case direct: case direct:
if (peersProposal) { 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()); this.socket = new Socket(getStreamHost().getAddress(), getStreamHost().getPort());
} else { } 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(); this.socket = new ServerSocket(getStreamHost().getPort()).accept();
} }
break; break;