[jitsi-users] StackOverflow


#1

I received no replies to my earlier report of this problem. Does that
mean that this is not considered a bug?

I have added the following to our firewall:

Accept If protocol is TCP and destination ports are 5222,5223,5269,5298

Accept If protocol is UDP and destination port is 5000:6000

Reject If protocol is TCP and destination port is 8010

When I start a new voice call to another user registered at Jit.Si I
frequently get the following diagnostic message indicating a stack
overflow. Subsequent call attempts are usually successful. But the
first often fails. The IRC works fine always.

net.java.sip.communicator.service.protocol.OperationFailedException:
Failed to create a call to caricatoc@jit.si/jitsi-1omdenl
  at
net.java.sip.communicator.impl.protocol.jabber.ProtocolProviderServiceJabberImpl.throwOperationFailedException(ProtocolProviderServiceJabberImpl.java:2676)
  at
net.java.sip.communicator.impl.protocol.jabber.OperationSetBasicTelephonyJabberImpl.createOutgoingCall(OperationSetBasicTelephonyJabberImpl.java:453)
  at
net.java.sip.communicator.impl.protocol.jabber.OperationSetBasicTelephonyJabberImpl.createOutgoingCall(OperationSetBasicTelephonyJabberImpl.java:272)
  at
net.java.sip.communicator.impl.protocol.jabber.OperationSetBasicTelephonyJabberImpl.createOutgoingCall(OperationSetBasicTelephonyJabberImpl.java:244)
  at
net.java.sip.communicator.impl.protocol.jabber.OperationSetBasicTelephonyJabberImpl.createCall(OperationSetBasicTelephonyJabberImpl.java:140)
  at
net.java.sip.communicator.service.protocol.media.AbstractOperationSetBasicTelephony.createCall(AbstractOperationSetBasicTelephony.java:111)
  at
net.java.sip.communicator.impl.gui.main.call.CallManager.internalCall(CallManager.java:2704)
  at
net.java.sip.communicator.impl.gui.main.call.CallManager.access$900(CallManager.java:49)
  at
net.java.sip.communicator.impl.gui.main.call.CallManager$CreateCallThread.run(CallManager.java:2585)
Caused by: java.lang.StackOverflowError
  at java.net.Inet6Address.equals(Inet6Address.java:876)
  at
java.net.InetSocketAddress$InetSocketAddressHolder.equals(InetSocketAddress.java:118)
  at java.net.InetSocketAddress.equals(InetSocketAddress.java:407)
  at
org.ice4j.TransportAddress.equalsTransportAddress(TransportAddress.java:218)
  at org.ice4j.TransportAddress.equals(TransportAddress.java:196)
  at org.ice4j.ice.Candidate.equals(Candidate.java:302)
  at org.ice4j.ice.Candidate.equals(Candidate.java:319)
  at org.ice4j.ice.Candidate.equals(Candidate.java:319)

···

--
*** e-Mail is NOT a SECURE channel ***
        Do NOT transmit sensitive data via e-Mail
James B. Byrne mailto:ByrneJB@Harte-Lyne.ca
Harte & Lyne Limited http://www.harte-lyne.ca
9 Brockley Drive vox: +1 905 561 1241
Hamilton, Ontario fax: +1 905 561 0757
Canada L8E 3C3


#2
···

I think this behaviour is explained in the comments. @Lyubomir, it looks like you should at least know what this code does roughly.

  This is clearly not intended behaviour for equals. On second look, it seems that someone just missed a spot when adding the property emphasized below.

  My first impression is that something like the following should fix the issue. Though I'm just putting this out as a hint, since I don't know anything about ice4j, or this code, or have tested it, or have tried it out, or have compiled it. Basically, I was just curious.

          diff --git a/src/org/ice4j/ice/Candidate.java b/src/org/ice4j/ice/Candidate.java

    index f44e605..c771731 100644

    --- a/src/org/ice4j/ice/Candidate.java

    +++ b/src/org/ice4j/ice/Candidate.java

    @@ -307,7 +307,7 @@ public abstract class Candidate<T extends Candidate<?>>

             Candidate<?> candidateBase = candidate.getBase();

             boolean baseEqualsCandidateBase;

     

    -        if (base == null)

    +        if (base == null || base == this)

             {

                 if (candidateBase != null)

                     return false;

    @@ -995,4 +995,4 @@ public abstract class Candidate<T extends Candidate<?>>

         {

             this.tcpType = tcpType;

         }

    -}

    \ No newline at end of file

    +}

  The base variable:

      /**

         * The base of a server reflexive candidate is the host candidate

         * from which it was derived. **          A host candidate is also said to have** __* a base, equal to that candidate itself.__
    Similarly, the base of a

         * relayed candidate is that candidate itself.

         */

        private T base = null;

  The equals implementation:

      /**

         * Indicates whether some other Candidate is "equal to" this one. We

         * consider candidates equal when they are redundant, i.e.

         * <p>

         * @param obj the reference object with which to compare.

         * <p>

         * @return <code>true</code> if this <tt>Candidate</tt> is equal to the

         * obj argument; <code>false</code> otherwise.

         *

         * @throws java.lang.NullPointerException if <tt>obj</tt> is null;

         */

        @Override

        public boolean equals(Object obj)

            throws NullPointerException

        {

            if (obj == this)

                return true;

            if (! (obj instanceof Candidate))

                return false;

            Candidate<?> candidate = (Candidate<?>) obj;

            //compare candidate addresses

            if (! candidate.getTransportAddress().equals(getTransportAddress()))

                return false;

            //compare bases

            Candidate<?> base = getBase();

            Candidate<?> candidateBase = candidate.getBase();

            boolean baseEqualsCandidateBase;

            if (base == null)

            {

                if (candidateBase != null)

                    return false;

                else

                    baseEqualsCandidateBase = true;

            }

            else

            {

    ***            baseEqualsCandidateBase = base.equals(candidateBase);*** // <---------------- Infinite recursion in here!

            }

            //compare other properties

            return

                (baseEqualsCandidateBase

                        || (base == this && candidateBase == candidate))

                    && getPriority() == candidate.getPriority()

                    && getType() == candidate.getType()

                    && getFoundation().equals(candidate.getFoundation());

        }

  Danny

  On 19-06-15 16:04, James B. Byrne wrote:

I received no replies to my earlier report of this problem. Does that mean that this is not considered a bug? I have added the following to our firewall: Accept If protocol is TCP and destination ports are 5222,5223,5269,5298 Accept If protocol is UDP and destination port is 5000:6000 Reject If protocol is TCP and destination port is 8010 When I start a new voice call to another user registered at Jit.Si I frequently get the following diagnostic message indicating a stack overflow. Subsequent call attempts are usually successful. But the first often fails. The IRC works fine always. net.java.sip.communicator.service.protocol.OperationFailedException: Failed to create a call to at net.java.sip.communicator.impl.protocol.jabber.ProtocolProviderServiceJabberImpl.throwOperationFailedException(ProtocolProviderServiceJabberImpl.java:2676) at net.java.sip.communicator.impl.protocol.jabber.OperationSetBasicTelephonyJabberImpl.createOutgoingCall(OperationSetBasicTelephonyJabberImpl.java:453) at net.java.sip.communicator.impl.protocol.jabber.OperationSetBasicTelephonyJabberImpl.createOutgoingCall(OperationSetBasicTelephonyJabberImpl.java:272) at net.java.sip.communicator.impl.protocol.jabber.OperationSetBasicTelephonyJabberImpl.createOutgoingCall(OperationSetBasicTelephonyJabberImpl.java:244) at net.java.sip.communicator.impl.protocol.jabber.OperationSetBasicTelephonyJabberImpl.createCall(OperationSetBasicTelephonyJabberImpl.java:140) at net.java.sip.communicator.service.protocol.media.AbstractOperationSetBasicTelephony.createCall(AbstractOperationSetBasicTelephony.java:111) at net.java.sip.communicator.impl.gui.main.call.CallManager.internalCall(CallManager.java:2704) at net.java.sip.communicator.impl.gui.main.call.CallManager.access$900(CallManager.java:49) at net.java.sip.communicator.impl.gui.main.call.CallManager$CreateCallThread.run(CallManager.java:2585) Caused by: java.lang.StackOverflowError at java.net.Inet6Address.equals(Inet6Address.java:876) at java.net.InetSocketAddress$InetSocketAddressHolder.equals(InetSocketAddress.java:118) at java.net.InetSocketAddress.equals(InetSocketAddress.java:407) at org.ice4j.TransportAddress.equalsTransportAddress(TransportAddress.java:218) at org.ice4j.TransportAddress.equals(TransportAddress.java:196) at org.ice4j.ice.Candidate.equals(Candidate.java:302) at org.ice4j.ice.Candidate.equals(Candidate.java:319) at org.ice4j.ice.Candidate.equals(Candidate.java:319)

caricatoc@jit.si/jitsi-1omdenl


#3

Thank you very much, James and Danny! I believe I fixed it in ice4j
SVN revision 506, jitsi commit
a72da788d138f35f13eda114beb3fe9db5778657.