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

Add Gajim fixes,

Return feature-not-implemented when suitable,
try next transport on transport-reject.
This commit is contained in:
vanitasvitae 2017-08-07 11:36:40 +02:00
parent bee9ef0f08
commit 6fad0b9fab
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
6 changed files with 73 additions and 26 deletions

View file

@ -17,6 +17,8 @@
package org.jivesoftware.smackx.jft.adapter; package org.jivesoftware.smackx.jft.adapter;
import java.util.List; import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jivesoftware.smack.packet.NamedElement; import org.jivesoftware.smack.packet.NamedElement;
import org.jivesoftware.smackx.jft.component.JingleFileTransfer; import org.jivesoftware.smackx.jft.component.JingleFileTransfer;
@ -32,6 +34,7 @@ import org.jivesoftware.smackx.jingle.element.JingleContentElement;
* Created by vanitas on 28.07.17. * Created by vanitas on 28.07.17.
*/ */
public class JingleFileTransferAdapter implements JingleDescriptionAdapter<JingleFileTransfer> { public class JingleFileTransferAdapter implements JingleDescriptionAdapter<JingleFileTransfer> {
private static final Logger LOGGER = Logger.getLogger(JingleFileTransferAdapter.class.getName());
@Override @Override
public JingleFileTransfer descriptionFromElement(JingleContentElement.Creator creator, JingleContentElement.Senders senders, public JingleFileTransfer descriptionFromElement(JingleContentElement.Creator creator, JingleContentElement.Senders senders,
@ -46,6 +49,10 @@ public class JingleFileTransferAdapter implements JingleDescriptionAdapter<Jingl
} else if (senders == JingleContentElement.Senders.responder) { } else if (senders == JingleContentElement.Senders.responder) {
return new JingleIncomingFileRequest(file); return new JingleIncomingFileRequest(file);
} else { } else {
if (senders == null) {
LOGGER.log(Level.INFO, "Senders is null. Gajim workaround: assume 'initiator'.");
return new JingleIncomingFileOffer(file);
}
throw new AssertionError("Senders attribute MUST be either initiator or responder. Is: " + senders); throw new AssertionError("Senders attribute MUST be either initiator or responder. Is: " + senders);
} }
} }

View file

@ -31,7 +31,6 @@ import org.jivesoftware.smackx.jft.element.Range;
import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionChildElement; import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionChildElement;
import org.jivesoftware.smackx.jingle.provider.JingleContentDescriptionProvider; import org.jivesoftware.smackx.jingle.provider.JingleContentDescriptionProvider;
import org.jxmpp.util.XmppDateTime;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
/** /**
@ -55,7 +54,8 @@ public class JingleFileTransferProvider
if (tag == START_TAG) { if (tag == START_TAG) {
switch (elem) { switch (elem) {
case JingleFileTransferChildElement.ELEM_DATE: case JingleFileTransferChildElement.ELEM_DATE:
builder.setDate(XmppDateTime.parseXEP0082Date(parser.nextText())); //builder.setDate(XmppDateTime.parseXEP0082Date(parser.nextText()));
parser.nextText();
break; break;
case JingleFileTransferChildElement.ELEM_DESC: case JingleFileTransferChildElement.ELEM_DESC:

View file

@ -28,6 +28,7 @@ import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.util.Async; import org.jivesoftware.smack.util.Async;
import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.bytestreams.BytestreamSession; import org.jivesoftware.smackx.bytestreams.BytestreamSession;
@ -169,19 +170,18 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
} }
public IQ handleContentModify(JingleElement request, XMPPConnection connection) { public IQ handleContentModify(JingleElement request, XMPPConnection connection) {
return IQ.createResultIQ(request); return IQ.createErrorResponse(request, XMPPError.Condition.feature_not_implemented);
} }
public IQ handleDescriptionInfo(JingleElement request, XMPPConnection connection) { public IQ handleDescriptionInfo(JingleElement request, XMPPConnection connection) {
return IQ.createResultIQ(request); return IQ.createErrorResponse(request, XMPPError.Condition.feature_not_implemented);
} }
public void handleContentRemove(JingleSession session, XMPPConnection connection) { public void handleContentRemove(JingleSession session, XMPPConnection connection) {
} }
public IQ handleSecurityInfo(JingleElement request, XMPPConnection connection) { public IQ handleSecurityInfo(JingleElement request, XMPPConnection connection) {
return IQ.createResultIQ(request); return IQ.createErrorResponse(request, XMPPError.Condition.feature_not_implemented);
} }
public IQ handleSessionInfo(JingleElement request, XMPPConnection connection) { public IQ handleSessionInfo(JingleElement request, XMPPConnection connection) {
@ -211,6 +211,16 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
} }
public IQ handleTransportReject(JingleElement request, XMPPConnection connection) { public IQ handleTransportReject(JingleElement request, XMPPConnection connection) {
if (pendingReplacingTransport == null) {
throw new AssertionError("We didn't try to replace the transport.");
}
transportBlacklist.add(pendingReplacingTransport.getNamespace());
pendingReplacingTransport = null;
try {
replaceTransport(transportBlacklist, connection);
} catch (SmackException.NotConnectedException | SmackException.NoResponseException | XMPPException.XMPPErrorException | InterruptedException e) {
LOGGER.log(Level.SEVERE, "Could not replace transport: " + e, e);
}
return IQ.createResultIQ(request); return IQ.createResultIQ(request);
} }
@ -375,6 +385,7 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
} }
public void onAccept(final XMPPConnection connection) { public void onAccept(final XMPPConnection connection) {
LOGGER.log(Level.INFO, "Accepted content " + getName());
transport.prepare(connection); transport.prepare(connection);
if (security != null) { if (security != null) {
@ -392,6 +403,9 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
} else if (isSending()) { } else if (isSending()) {
LOGGER.log(Level.INFO, "Establish outgoing bytestream."); LOGGER.log(Level.INFO, "Establish outgoing bytestream.");
getTransport().establishOutgoingBytestreamSession(connection, JingleContent.this, getParent()); getTransport().establishOutgoingBytestreamSession(connection, JingleContent.this, getParent());
} else {
LOGGER.log(Level.INFO, "Neither receiving, nor sending. For the sake of Gajim assume receiving.");
getTransport().establishIncomingBytestreamSession(connection, JingleContent.this, getParent());
} }
} catch (SmackException.NotConnectedException | InterruptedException e) { } catch (SmackException.NotConnectedException | InterruptedException e) {
LOGGER.log(Level.SEVERE, "Error establishing connection: " + e, e); LOGGER.log(Level.SEVERE, "Error establishing connection: " + e, e);

View file

@ -101,10 +101,15 @@ public class JingleSession {
} }
public void accept(XMPPConnection connection) throws SmackException.NotConnectedException, InterruptedException, XMPPException.XMPPErrorException, SmackException.NoResponseException { public void accept(XMPPConnection connection) throws SmackException.NotConnectedException, InterruptedException, XMPPException.XMPPErrorException, SmackException.NoResponseException {
LOGGER.log(Level.INFO, "Accepted session.");
if (this.sessionState != SessionState.pending) { if (this.sessionState != SessionState.pending) {
throw new IllegalStateException("Session is not in pending state."); throw new IllegalStateException("Session is not in pending state.");
} }
if (contents.values().size() == 0) {
LOGGER.log(Level.WARNING, "0 contents!");
}
for (JingleContent content : contents.values()) { for (JingleContent content : contents.values()) {
content.onAccept(connection); content.onAccept(connection);
} }

View file

@ -198,13 +198,6 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
return NAMESPACE; return NAMESPACE;
} }
@Override
public void establishIncomingBytestreamSession(XMPPConnection connection, JingleTransportCallback callback, JingleSession session)
throws SmackException.NotConnectedException, InterruptedException {
this.callback = callback;
establishBytestreamSession(connection);
}
@Override @Override
public void prepare(XMPPConnection connection) { public void prepare(XMPPConnection connection) {
JingleSession session = getParent().getParent(); JingleSession session = getParent().getParent();
@ -225,9 +218,18 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
} }
} }
@Override
public void establishIncomingBytestreamSession(XMPPConnection connection, JingleTransportCallback callback, JingleSession session)
throws SmackException.NotConnectedException, InterruptedException {
LOGGER.log(Level.INFO, "Establishing incoming bytestream.");
this.callback = callback;
establishBytestreamSession(connection);
}
@Override @Override
public void establishOutgoingBytestreamSession(XMPPConnection connection, JingleTransportCallback callback, JingleSession session) public void establishOutgoingBytestreamSession(XMPPConnection connection, JingleTransportCallback callback, JingleSession session)
throws SmackException.NotConnectedException, InterruptedException { throws SmackException.NotConnectedException, InterruptedException {
LOGGER.log(Level.INFO, "Establishing outgoing bytestream.");
this.callback = callback; this.callback = callback;
establishBytestreamSession(connection); establishBytestreamSession(connection);
} }
@ -256,6 +258,7 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
public JingleS5BTransportCandidate connectToCandidates(int timeout) { public JingleS5BTransportCandidate connectToCandidates(int timeout) {
if (getTheirCandidates().size() == 0) { if (getTheirCandidates().size() == 0) {
LOGGER.log(Level.INFO, "They provided 0 candidates.");
return CANDIDATE_FAILURE; return CANDIDATE_FAILURE;
} }

View file

@ -17,6 +17,7 @@
package org.jivesoftware.smackx.jingle.transport.jingle_s5b; package org.jivesoftware.smackx.jingle.transport.jingle_s5b;
import java.io.IOException; import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.logging.Level; import java.util.logging.Level;
@ -93,21 +94,38 @@ public class JingleS5BTransportCandidate extends JingleTransportCandidate<Jingle
public JingleS5BTransportCandidate connect(int timeout, boolean peersProposal) throws InterruptedException, TimeoutException, SmackException, XMPPException, IOException { public JingleS5BTransportCandidate connect(int timeout, boolean peersProposal) throws InterruptedException, TimeoutException, SmackException, XMPPException, IOException {
JingleS5BTransport transport = (JingleS5BTransport) getParent(); JingleS5BTransport transport = (JingleS5BTransport) getParent();
switch (getType()) {
case proxy:
Socks5Client client; Socks5Client client;
if (peersProposal) { if (peersProposal) {
LOGGER.log(Level.INFO, "Connect to foreign candidate " + getCandidateId() + " using " + transport.getTheirDstAddr()); LOGGER.log(Level.INFO, "Connect to foreign candidate " + getCandidateId() + " using " + transport.getTheirDstAddr());
LOGGER.log(Level.INFO, getStreamHost().getAddress() + ":" + getStreamHost().getPort() + " " + getStreamHost().getJID().toString() + " " + getType()); LOGGER.log(Level.INFO, getStreamHost().getAddress() + ":" + getStreamHost().getPort() + " " + getStreamHost().getJID().toString() + " " + getType());
client = new Socks5Client(getStreamHost(), transport.getTheirDstAddr()); client = new Socks5Client(getStreamHost(), transport.getTheirDstAddr());
} } else {
else {
LOGGER.log(Level.INFO, "Connect to our candidate " + getCandidateId() + " using " + transport.getOurDstAddr()); LOGGER.log(Level.INFO, "Connect to our candidate " + getCandidateId() + " using " + transport.getOurDstAddr());
LOGGER.log(Level.INFO, getStreamHost().getAddress() + ":" + getStreamHost().getPort() + " " + getStreamHost().getJID().toString() + " " + getType()); LOGGER.log(Level.INFO, getStreamHost().getAddress() + ":" + getStreamHost().getPort() + " " + getStreamHost().getJID().toString() + " " + getType());
JingleContent content = transport.getParent(); JingleContent content = transport.getParent();
JingleSession session = content.getParent(); JingleSession session = content.getParent();
client = new Socks5ClientForInitiator(getStreamHost(), transport.getOurDstAddr(), session.getJingleManager().getConnection(), transport.getSid(), session.getPeer()); client = new Socks5ClientForInitiator(getStreamHost(), transport.getOurDstAddr(), session.getJingleManager().getConnection(), transport.getSid(), session.getPeer());
} }
this.socket = client.getSocket(timeout); this.socket = client.getSocket(timeout);
break;
case direct:
if (peersProposal) {
LOGGER.log(Level.INFO, "Connect to foreign direct candidate " + getCandidateId());
this.socket = new Socket(getStreamHost().getAddress(), getStreamHost().getPort());
} else {
LOGGER.log(Level.INFO, "Connect to our direct candidate " + getCandidateId());
this.socket = new ServerSocket(getStreamHost().getPort()).accept();
}
break;
default:
LOGGER.log(Level.INFO, "Unsupported candidate type: " + getType());
break;
}
return this; return this;
} }