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:
parent
bee9ef0f08
commit
6fad0b9fab
6 changed files with 73 additions and 26 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue