2013-02-07 15:19:47 +01:00
|
|
|
/**
|
|
|
|
*
|
2014-02-17 18:57:38 +01:00
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
2013-02-07 15:19:47 +01:00
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
2007-01-04 18:25:30 +01:00
|
|
|
package org.jivesoftware.smackx.jingle.nat;
|
|
|
|
|
2012-10-26 12:47:55 +02:00
|
|
|
import de.javawi.jstun.test.demo.StunServer;
|
2007-01-04 18:25:30 +01:00
|
|
|
import de.javawi.jstun.test.demo.ice.Candidate;
|
|
|
|
import de.javawi.jstun.test.demo.ice.ICENegociator;
|
|
|
|
import de.javawi.jstun.util.UtilityException;
|
|
|
|
import org.jivesoftware.smack.XMPPException;
|
|
|
|
import org.jivesoftware.smack.test.SmackTestCase;
|
2008-05-20 00:54:19 +02:00
|
|
|
import org.jivesoftware.smackx.jingle.JingleManager;
|
|
|
|
import org.jivesoftware.smackx.jingle.JingleSession;
|
|
|
|
import org.jivesoftware.smackx.jingle.JingleSessionRequest;
|
2007-01-04 18:25:30 +01:00
|
|
|
import org.jivesoftware.smackx.jingle.listeners.JingleSessionListener;
|
|
|
|
import org.jivesoftware.smackx.jingle.listeners.JingleSessionRequestListener;
|
2008-05-20 00:54:19 +02:00
|
|
|
import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
|
2007-01-04 18:25:30 +01:00
|
|
|
import org.jivesoftware.smackx.jingle.media.PayloadType;
|
2008-05-20 00:54:19 +02:00
|
|
|
import org.jivesoftware.smackx.jingle.mediaimpl.test.TestMediaManager;
|
2012-10-26 12:47:55 +02:00
|
|
|
import org.jivesoftware.smackx.jingle.nat.STUNResolver.STUNService;
|
2007-01-04 18:25:30 +01:00
|
|
|
|
2008-10-30 22:20:29 +01:00
|
|
|
import java.net.NetworkInterface;
|
|
|
|
import java.net.SocketException;
|
2007-01-04 18:25:30 +01:00
|
|
|
import java.net.UnknownHostException;
|
|
|
|
import java.util.ArrayList;
|
2008-10-30 22:20:29 +01:00
|
|
|
import java.util.Enumeration;
|
2008-05-20 00:54:19 +02:00
|
|
|
import java.util.List;
|
2007-01-04 18:25:30 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Test the STUN IP resolver.
|
|
|
|
*
|
2007-03-03 06:20:17 +01:00
|
|
|
* @author Thiago Camargo
|
2007-01-04 18:25:30 +01:00
|
|
|
*/
|
|
|
|
public class STUNResolverTest extends SmackTestCase {
|
|
|
|
|
|
|
|
// Counter management
|
|
|
|
|
|
|
|
public STUNResolverTest(final String arg) {
|
|
|
|
super(arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
private int counter;
|
|
|
|
|
|
|
|
private final Object mutex = new Object();
|
|
|
|
|
|
|
|
private void resetCounter() {
|
|
|
|
synchronized (mutex) {
|
|
|
|
counter = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void incCounter() {
|
|
|
|
synchronized (mutex) {
|
|
|
|
counter++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private int valCounter() {
|
|
|
|
int val;
|
|
|
|
synchronized (mutex) {
|
|
|
|
val = counter;
|
|
|
|
}
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Test for getPreferredCandidate()
|
|
|
|
*
|
2019-08-30 12:08:30 +02:00
|
|
|
* @throws Exception if an exception occurs.
|
2007-01-04 18:25:30 +01:00
|
|
|
*/
|
|
|
|
public void testGetPreferredCandidate() throws Exception {
|
|
|
|
int highestPref = 100;
|
|
|
|
|
2008-05-20 00:54:19 +02:00
|
|
|
TransportCandidate cand1 = new ICECandidate("192.168.2.1", 3, 2, "password", 3468, "username1", 1, ICECandidate.Type.prflx);
|
|
|
|
TransportCandidate cand2 = new ICECandidate("192.168.5.1", 2, 10, "password", 3469, "username2", 15,
|
|
|
|
ICECandidate.Type.prflx);
|
|
|
|
TransportCandidate candH = new ICECandidate("192.168.2.11", 1, 2, "password", 3468, "usernameH", highestPref,
|
|
|
|
ICECandidate.Type.prflx);
|
|
|
|
TransportCandidate cand3 = new ICECandidate("192.168.2.10", 2, 10, "password", 3469, "username3", 2,
|
|
|
|
ICECandidate.Type.prflx);
|
|
|
|
TransportCandidate cand4 = new ICECandidate("192.168.4.1", 3, 2, "password", 3468, "username4", 78, ICECandidate.Type.prflx);
|
2007-01-04 18:25:30 +01:00
|
|
|
|
|
|
|
STUNResolver stunResolver = new STUNResolver() {
|
|
|
|
};
|
|
|
|
stunResolver.addCandidate(cand1);
|
|
|
|
stunResolver.addCandidate(cand2);
|
|
|
|
stunResolver.addCandidate(candH);
|
|
|
|
stunResolver.addCandidate(cand3);
|
|
|
|
stunResolver.addCandidate(cand4);
|
|
|
|
|
|
|
|
assertEquals(stunResolver.getPreferredCandidate(), candH);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Test for getPreferredCandidate()
|
|
|
|
*
|
2019-08-30 12:08:30 +02:00
|
|
|
* @throws Exception if an exception occurs.
|
2007-01-04 18:25:30 +01:00
|
|
|
*/
|
|
|
|
public void testGetPreferredCandidateICE() throws Exception {
|
|
|
|
int highestPref = 100;
|
|
|
|
|
2008-05-20 00:54:19 +02:00
|
|
|
TransportCandidate cand1 = new ICECandidate("192.168.2.1", 3, 2, "password", 3468, "username1", 1, ICECandidate.Type.prflx);
|
|
|
|
TransportCandidate cand2 = new ICECandidate("192.168.5.1", 2, 10, "password", 3469, "username2", 15,
|
|
|
|
ICECandidate.Type.prflx);
|
|
|
|
TransportCandidate candH = new ICECandidate("192.168.2.11", 1, 2, "password", 3468, "usernameH", highestPref,
|
|
|
|
ICECandidate.Type.prflx);
|
|
|
|
TransportCandidate cand3 = new ICECandidate("192.168.2.10", 2, 10, "password", 3469, "username3", 2,
|
|
|
|
ICECandidate.Type.prflx);
|
|
|
|
TransportCandidate cand4 = new ICECandidate("192.168.4.1", 3, 2, "password", 3468, "username4", 78, ICECandidate.Type.prflx);
|
2007-01-04 18:25:30 +01:00
|
|
|
|
2007-01-30 00:45:13 +01:00
|
|
|
ICEResolver iceResolver = new ICEResolver(getConnection(0), "stun.xten.net", 3478) {
|
2007-01-04 18:25:30 +01:00
|
|
|
};
|
|
|
|
iceResolver.addCandidate(cand1);
|
|
|
|
iceResolver.addCandidate(cand2);
|
|
|
|
iceResolver.addCandidate(candH);
|
|
|
|
iceResolver.addCandidate(cand3);
|
|
|
|
iceResolver.addCandidate(cand4);
|
|
|
|
|
|
|
|
assertEquals(iceResolver.getPreferredCandidate(), candH);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Test priority generated by STUN lib
|
|
|
|
*
|
2019-08-30 12:08:30 +02:00
|
|
|
* @throws Exception if an exception occurs.
|
2007-01-04 18:25:30 +01:00
|
|
|
*/
|
|
|
|
public void testICEPriority() throws Exception {
|
|
|
|
|
|
|
|
String first = "";
|
|
|
|
|
|
|
|
for (int i = 0; i < 100; i++) {
|
|
|
|
|
|
|
|
ICENegociator cc = new ICENegociator((short) 1);
|
|
|
|
// gather candidates
|
|
|
|
cc.gatherCandidateAddresses();
|
|
|
|
// priorize candidates
|
|
|
|
cc.prioritizeCandidates();
|
|
|
|
// get SortedCandidates
|
|
|
|
|
2008-10-30 22:20:29 +01:00
|
|
|
for (Candidate candidate : cc.getSortedCandidates()) {
|
|
|
|
short nicNum = 0;
|
|
|
|
try {
|
|
|
|
Enumeration<NetworkInterface> nics = NetworkInterface.getNetworkInterfaces();
|
|
|
|
short tempNic = 0;
|
|
|
|
NetworkInterface nic = NetworkInterface.getByInetAddress(candidate.getAddress().getInetAddress());
|
|
|
|
while(nics.hasMoreElements()) {
|
|
|
|
NetworkInterface checkNIC = nics.nextElement();
|
|
|
|
if (checkNIC.equals(nic)) {
|
|
|
|
nicNum = tempNic;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
} catch (SocketException e1) {
|
|
|
|
// TODO Auto-generated catch block
|
|
|
|
e1.printStackTrace();
|
|
|
|
}
|
2015-03-17 11:33:02 +01:00
|
|
|
|
2007-01-04 18:25:30 +01:00
|
|
|
try {
|
2008-05-20 00:54:19 +02:00
|
|
|
TransportCandidate transportCandidate = new ICECandidate(candidate.getAddress().getInetAddress()
|
2008-10-30 22:20:29 +01:00
|
|
|
.getHostAddress(), 1, nicNum, "1", candidate.getPort(), "1", candidate.getPriority(),
|
2008-05-20 00:54:19 +02:00
|
|
|
ICECandidate.Type.prflx);
|
2007-01-04 18:25:30 +01:00
|
|
|
transportCandidate.setLocalIp(candidate.getBase().getAddress().getInetAddress().getHostAddress());
|
2008-05-20 00:54:19 +02:00
|
|
|
System.out.println("C: " + candidate.getAddress().getInetAddress() + "|"
|
|
|
|
+ candidate.getBase().getAddress().getInetAddress() + " p:" + candidate.getPriority());
|
|
|
|
} catch (UtilityException e) {
|
2015-03-17 21:19:06 +01:00
|
|
|
LOGGER.log(Level.WARNING, "exception", e);
|
2008-05-20 00:54:19 +02:00
|
|
|
} catch (UnknownHostException e) {
|
2015-03-17 21:19:06 +01:00
|
|
|
LOGGER.log(Level.WARNING, "exception", e);
|
2007-01-04 18:25:30 +01:00
|
|
|
}
|
2008-10-30 22:20:29 +01:00
|
|
|
}
|
2007-01-04 18:25:30 +01:00
|
|
|
Candidate candidate = cc.getSortedCandidates().get(0);
|
2008-05-20 00:54:19 +02:00
|
|
|
String temp = "C: " + candidate.getAddress().getInetAddress() + "|" + candidate.getBase().getAddress().getInetAddress()
|
|
|
|
+ " p:" + candidate.getPriority();
|
2007-01-04 18:25:30 +01:00
|
|
|
if (first.equals(""))
|
|
|
|
first = temp;
|
|
|
|
assertEquals(first, temp);
|
|
|
|
first = temp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Test for loadSTUNServers()
|
|
|
|
*
|
2019-08-30 12:08:30 +02:00
|
|
|
* @throws Exception if an exception occurs.
|
2007-01-04 18:25:30 +01:00
|
|
|
*/
|
|
|
|
public void testLoadSTUNServers() throws Exception {
|
|
|
|
STUNResolver stunResolver = new STUNResolver() {
|
|
|
|
};
|
2012-10-26 12:47:55 +02:00
|
|
|
ArrayList<STUNService> stunServers = stunResolver.loadSTUNServers();
|
2007-01-04 18:25:30 +01:00
|
|
|
|
|
|
|
assertTrue(stunServers.size() > 0);
|
|
|
|
System.out.println(stunServers.size() + " servers loaded");
|
|
|
|
}
|
|
|
|
|
2007-01-05 21:03:10 +01:00
|
|
|
public void testGetSTUNServer() {
|
|
|
|
|
|
|
|
System.out.println(STUN.serviceAvailable(getConnection(0)));
|
|
|
|
STUN stun = STUN.getSTUNServer(getConnection(0));
|
2007-03-22 20:57:50 +01:00
|
|
|
for (STUN.StunServerAddress stunServerAddress : stun.getServers())
|
|
|
|
System.out.println(stunServerAddress.getServer() + ":" + stunServerAddress.getPort());
|
2007-03-23 04:54:46 +01:00
|
|
|
|
|
|
|
System.out.println(stun.getPublicIp());
|
|
|
|
|
2007-01-05 21:03:10 +01:00
|
|
|
}
|
|
|
|
|
2007-01-04 18:25:30 +01:00
|
|
|
/**
|
|
|
|
* Test for resolve()
|
|
|
|
*
|
2019-08-30 12:08:30 +02:00
|
|
|
* @throws Exception if an exception occurs.
|
2007-01-04 18:25:30 +01:00
|
|
|
*/
|
|
|
|
public void testResolve() throws Exception {
|
|
|
|
|
|
|
|
final STUNResolver stunResolver = new STUNResolver() {
|
|
|
|
};
|
|
|
|
|
|
|
|
stunResolver.addListener(new TransportResolverListener.Resolver() {
|
|
|
|
|
|
|
|
public void candidateAdded(final TransportCandidate cand) {
|
|
|
|
incCounter();
|
|
|
|
|
|
|
|
String addr = cand.getIp();
|
|
|
|
int port = cand.getPort();
|
|
|
|
|
|
|
|
System.out.println("Addr: " + addr + " port:" + port);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public void init() {
|
|
|
|
System.out.println("Resolution started");
|
|
|
|
}
|
|
|
|
|
|
|
|
public void end() {
|
|
|
|
System.out.println("Resolution finished");
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
try {
|
2007-03-12 04:25:06 +01:00
|
|
|
stunResolver.initializeAndWait();
|
2007-01-04 18:25:30 +01:00
|
|
|
Thread.sleep(55000);
|
|
|
|
assertTrue(valCounter() > 0);
|
2008-05-20 00:54:19 +02:00
|
|
|
} catch (Exception e) {
|
2015-03-17 21:19:06 +01:00
|
|
|
LOGGER.log(Level.WARNING, "exception", e);
|
2007-01-04 18:25:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generate a list of payload types
|
|
|
|
*
|
|
|
|
* @return A testing list
|
|
|
|
*/
|
2012-10-26 12:47:55 +02:00
|
|
|
private ArrayList<PayloadType> getTestPayloads1() {
|
|
|
|
ArrayList<PayloadType> result = new ArrayList<PayloadType>();
|
2007-01-04 18:25:30 +01:00
|
|
|
|
|
|
|
result.add(new PayloadType.Audio(34, "supercodec-1", 2, 14000));
|
|
|
|
result.add(new PayloadType.Audio(56, "supercodec-2", 1, 44000));
|
|
|
|
result.add(new PayloadType.Audio(36, "supercodec-3", 2, 28000));
|
|
|
|
result.add(new PayloadType.Audio(45, "supercodec-4", 1, 98000));
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2012-10-26 12:47:55 +02:00
|
|
|
private ArrayList<PayloadType> getTestPayloads2() {
|
|
|
|
ArrayList<PayloadType> result = new ArrayList<PayloadType>();
|
2007-01-04 18:25:30 +01:00
|
|
|
|
|
|
|
result.add(new PayloadType.Audio(27, "supercodec-3", 2, 28000));
|
|
|
|
result.add(new PayloadType.Audio(56, "supercodec-2", 1, 44000));
|
|
|
|
result.add(new PayloadType.Audio(32, "supercodec-4", 1, 98000));
|
|
|
|
result.add(new PayloadType.Audio(34, "supercodec-1", 2, 14000));
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This is a simple test where the user_2 rejects the Jingle session.
|
|
|
|
*/
|
|
|
|
public void testSTUNJingleSession() {
|
|
|
|
|
|
|
|
resetCounter();
|
|
|
|
|
|
|
|
try {
|
|
|
|
TransportResolver tr1 = new STUNResolver() {
|
|
|
|
};
|
|
|
|
TransportResolver tr2 = new STUNResolver() {
|
|
|
|
};
|
|
|
|
|
|
|
|
// Explicit resolution
|
2007-03-12 04:25:06 +01:00
|
|
|
tr1.resolve(null);
|
|
|
|
tr2.resolve(null);
|
2007-01-04 18:25:30 +01:00
|
|
|
|
2008-05-20 00:54:19 +02:00
|
|
|
STUNTransportManager stm0 = new STUNTransportManager();
|
|
|
|
TestMediaManager tmm0 = new TestMediaManager(stm0);
|
|
|
|
tmm0.setPayloads(getTestPayloads1());
|
|
|
|
List<JingleMediaManager> trl0 = new ArrayList<JingleMediaManager>();
|
|
|
|
trl0.add(tmm0);
|
|
|
|
|
|
|
|
STUNTransportManager stm1 = new STUNTransportManager();
|
|
|
|
TestMediaManager tmm1 = new TestMediaManager(stm1);
|
|
|
|
tmm1.setPayloads(getTestPayloads2());
|
|
|
|
List<JingleMediaManager> trl1 = new ArrayList<JingleMediaManager>();
|
|
|
|
trl1.add(tmm1);
|
|
|
|
|
|
|
|
final JingleManager man0 = new JingleManager(getConnection(0), trl0);
|
|
|
|
final JingleManager man1 = new JingleManager(getConnection(1), trl1);
|
2007-01-04 18:25:30 +01:00
|
|
|
|
|
|
|
man1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
|
|
|
/**
|
|
|
|
* Called when a new session request is detected
|
|
|
|
*/
|
|
|
|
public void sessionRequested(final JingleSessionRequest request) {
|
2008-05-20 00:54:19 +02:00
|
|
|
System.out.println("Session request detected, from " + request.getFrom() + ": accepting.");
|
2007-01-04 18:25:30 +01:00
|
|
|
|
|
|
|
// We accept the request
|
2008-05-20 00:54:19 +02:00
|
|
|
JingleSession session1;
|
2007-01-04 18:25:30 +01:00
|
|
|
try {
|
2008-05-20 00:54:19 +02:00
|
|
|
session1 = request.accept();
|
2007-01-04 18:25:30 +01:00
|
|
|
session1.addListener(new JingleSessionListener() {
|
|
|
|
public void sessionClosed(String reason, JingleSession jingleSession) {
|
|
|
|
}
|
|
|
|
|
|
|
|
public void sessionClosedOnError(XMPPException e, JingleSession jingleSession) {
|
|
|
|
}
|
|
|
|
|
|
|
|
public void sessionDeclined(String reason, JingleSession jingleSession) {
|
|
|
|
}
|
|
|
|
|
2008-05-20 00:54:19 +02:00
|
|
|
public void sessionEstablished(PayloadType pt, TransportCandidate rc, TransportCandidate lc,
|
|
|
|
JingleSession jingleSession) {
|
2007-01-04 18:25:30 +01:00
|
|
|
incCounter();
|
2008-05-20 00:54:19 +02:00
|
|
|
System.out.println("Responder: the session is fully established.");
|
2007-01-04 18:25:30 +01:00
|
|
|
System.out.println("+ Payload Type: " + pt.getId());
|
2008-05-20 00:54:19 +02:00
|
|
|
System.out.println("+ Local IP/port: " + lc.getIp() + ":" + lc.getPort());
|
|
|
|
System.out.println("+ Remote IP/port: " + rc.getIp() + ":" + rc.getPort());
|
2007-01-04 18:25:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public void sessionRedirected(String redirection, JingleSession jingleSession) {
|
|
|
|
}
|
2007-04-06 06:37:44 +02:00
|
|
|
|
|
|
|
public void sessionMediaReceived(JingleSession jingleSession, String participant) {
|
|
|
|
// Do Nothing
|
|
|
|
}
|
2007-01-04 18:25:30 +01:00
|
|
|
});
|
2008-05-20 00:54:19 +02:00
|
|
|
session1.startIncoming();
|
|
|
|
} catch (XMPPException e) {
|
2015-03-17 21:19:06 +01:00
|
|
|
LOGGER.log(Level.WARNING, "exception", e);
|
2007-01-04 18:25:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Session 0 starts a request
|
|
|
|
System.out.println("Starting session request, to " + getFullJID(1) + "...");
|
2008-05-20 00:54:19 +02:00
|
|
|
JingleSession session0 = man0.createOutgoingJingleSession(getFullJID(1));
|
2007-01-04 18:25:30 +01:00
|
|
|
|
|
|
|
session0.addListener(new JingleSessionListener() {
|
|
|
|
public void sessionClosed(String reason, JingleSession jingleSession) {
|
|
|
|
}
|
|
|
|
|
|
|
|
public void sessionClosedOnError(XMPPException e, JingleSession jingleSession) {
|
|
|
|
}
|
|
|
|
|
|
|
|
public void sessionDeclined(String reason, JingleSession jingleSession) {
|
|
|
|
}
|
|
|
|
|
2008-05-20 00:54:19 +02:00
|
|
|
public void sessionEstablished(PayloadType pt, TransportCandidate rc, TransportCandidate lc,
|
|
|
|
JingleSession jingleSession) {
|
2007-01-04 18:25:30 +01:00
|
|
|
incCounter();
|
|
|
|
System.out.println("Initiator: the session is fully established.");
|
|
|
|
System.out.println("+ Payload Type: " + pt.getId());
|
2008-05-20 00:54:19 +02:00
|
|
|
System.out.println("+ Local IP/port: " + lc.getIp() + ":" + lc.getPort());
|
|
|
|
System.out.println("+ Remote IP/port: " + rc.getIp() + ":" + rc.getPort());
|
2007-01-04 18:25:30 +01:00
|
|
|
}
|
|
|
|
|
2007-04-06 06:37:44 +02:00
|
|
|
public void sessionMediaReceived(JingleSession jingleSession, String participant) {
|
|
|
|
// Do Nothing
|
|
|
|
}
|
|
|
|
|
2007-01-04 18:25:30 +01:00
|
|
|
public void sessionRedirected(String redirection, JingleSession jingleSession) {
|
|
|
|
}
|
|
|
|
});
|
2008-05-20 00:54:19 +02:00
|
|
|
session0.startOutgoing();
|
2007-01-04 18:25:30 +01:00
|
|
|
|
|
|
|
Thread.sleep(60000);
|
|
|
|
|
|
|
|
assertTrue(valCounter() == 2);
|
|
|
|
|
2008-05-20 00:54:19 +02:00
|
|
|
} catch (Exception e) {
|
2015-03-17 21:19:06 +01:00
|
|
|
LOGGER.log(Level.WARNING, "exception", e);
|
2019-10-30 12:02:36 +01:00
|
|
|
fail("An error occurred with Jingle");
|
2007-01-04 18:25:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected int getMaxConnections() {
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
}
|