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;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jivesoftware.smack.packet.NamedElement;
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.
*/
public class JingleFileTransferAdapter implements JingleDescriptionAdapter<JingleFileTransfer> {
private static final Logger LOGGER = Logger.getLogger(JingleFileTransferAdapter.class.getName());
@Override
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) {
return new JingleIncomingFileRequest(file);
} 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);
}
}

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.provider.JingleContentDescriptionProvider;
import org.jxmpp.util.XmppDateTime;
import org.xmlpull.v1.XmlPullParser;
/**
@ -55,7 +54,8 @@ public class JingleFileTransferProvider
if (tag == START_TAG) {
switch (elem) {
case JingleFileTransferChildElement.ELEM_DATE:
builder.setDate(XmppDateTime.parseXEP0082Date(parser.nextText()));
//builder.setDate(XmppDateTime.parseXEP0082Date(parser.nextText()));
parser.nextText();
break;
case JingleFileTransferChildElement.ELEM_DESC:

View File

@ -28,6 +28,7 @@ import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.util.Async;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
@ -169,19 +170,18 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
}
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) {
return IQ.createResultIQ(request);
return IQ.createErrorResponse(request, XMPPError.Condition.feature_not_implemented);
}
public void handleContentRemove(JingleSession session, 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) {
@ -211,6 +211,16 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
}
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);
}
@ -375,6 +385,7 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
}
public void onAccept(final XMPPConnection connection) {
LOGGER.log(Level.INFO, "Accepted content " + getName());
transport.prepare(connection);
if (security != null) {
@ -392,6 +403,9 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
} else if (isSending()) {
LOGGER.log(Level.INFO, "Establish outgoing bytestream.");
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) {
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 {
LOGGER.log(Level.INFO, "Accepted session.");
if (this.sessionState != SessionState.pending) {
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()) {
content.onAccept(connection);
}

View File

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

View File

@ -17,6 +17,7 @@
package org.jivesoftware.smackx.jingle.transport.jingle_s5b;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.TimeoutException;
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 {
JingleS5BTransport transport = (JingleS5BTransport) getParent();
Socks5Client client;
if (peersProposal) {
LOGGER.log(Level.INFO, "Connect to foreign candidate " + getCandidateId() + " using " + transport.getTheirDstAddr());
LOGGER.log(Level.INFO, getStreamHost().getAddress() + ":" + getStreamHost().getPort() + " " + getStreamHost().getJID().toString() + " " + getType());
client = new Socks5Client(getStreamHost(), transport.getTheirDstAddr());
}
else {
LOGGER.log(Level.INFO, "Connect to our candidate " + getCandidateId() + " using " + transport.getOurDstAddr());
LOGGER.log(Level.INFO, getStreamHost().getAddress() + ":" + getStreamHost().getPort() + " " + getStreamHost().getJID().toString() + " " + getType());
JingleContent content = transport.getParent();
JingleSession session = content.getParent();
client = new Socks5ClientForInitiator(getStreamHost(), transport.getOurDstAddr(), session.getJingleManager().getConnection(), transport.getSid(), session.getPeer());
switch (getType()) {
case proxy:
Socks5Client client;
if (peersProposal) {
LOGGER.log(Level.INFO, "Connect to foreign candidate " + getCandidateId() + " using " + transport.getTheirDstAddr());
LOGGER.log(Level.INFO, getStreamHost().getAddress() + ":" + getStreamHost().getPort() + " " + getStreamHost().getJID().toString() + " " + getType());
client = new Socks5Client(getStreamHost(), transport.getTheirDstAddr());
} else {
LOGGER.log(Level.INFO, "Connect to our candidate " + getCandidateId() + " using " + transport.getOurDstAddr());
LOGGER.log(Level.INFO, getStreamHost().getAddress() + ":" + getStreamHost().getPort() + " " + getStreamHost().getJID().toString() + " " + getType());
JingleContent content = transport.getParent();
JingleSession session = content.getParent();
client = new Socks5ClientForInitiator(getStreamHost(), transport.getOurDstAddr(), session.getJingleManager().getConnection(), transport.getSid(), session.getPeer());
}
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;
}
this.socket = client.getSocket(timeout);
return this;
}