Unity-Technologies / com.unity.webrtc

WebRTC package for Unity
Other
753 stars 191 forks source link

[BUG]: CreateAnswer sometimes creates an offer #792

Closed streunerlein closed 1 year ago

streunerlein commented 2 years ago

Package version

2.4.0-exp.9

Environment

* OS: Windows10
* Unity version: Unity 2021.2
* UnityWebrtc 2.4.0-exp.6 through 2.4.0-exp.9

Steps To Reproduce

  1. Create offer on one Computer (createOffer), set it as local description (setLocalDescription) and send it to other Computer
  2. On other Computer, setRemoteDescription and then createAnswer on the connection. Try to setLocalDescription on this answer.

Current Behavior

Sometimes (here it's 6 out of 10 times), the last call setLocalDescription fails with wrong state: have-remote-offer. Debugging it shows that the createAnswer in that situation created an offer instead of an answer.

Expected Behavior

createAnswer should always create an answer, no?

Anything else?

Can someone explain any circumstances that would make createAnswer return an offer? I don't think it ever should...

See screenshot appended.

Screenshot 2022-08-02 165329

karasusan commented 2 years ago

createAnswer should always create an answer, no?

Yeah, definitely. It might be bugs in our code.

karasusan commented 2 years ago

@streunerlein I checked our code, surely I found the code which might occurs the issue. We add the issue into our backlog.

karasusan commented 2 years ago

memo: WRS-387

streunerlein commented 2 years ago

@karasusan Thank you very much.

October is a bit far away, I am thinking about a workaround. Do you have some more information on when this happens? Because I think the following naive solution is pretty much not going to work:

RTCSessionDescription desc = null;

while (desc == null || desc.type == RTCSdpType.Offer) {
  var op3 = pc.CreateAnswer();
  yield return op3;
  desc = op3.desc;
}
karasusan commented 2 years ago

@streunerlein I guess this issues might occur when running process of CreateOffer/CreateAnswer in parallel in native code.

streunerlein commented 2 years ago

@karasusan Ok, thank you. Then indeed the naive solution might work. I got better results using this code:

            while (true) {
                var op3 = pc.CreateAnswer();
                yield return op3;

                if (!op3.IsError)
                {
                    if (op3.Desc.type != RTCSdpType.Answer)
                    {
                        Debug.Log($"Received {op3.Desc.type} instead of answer, retrying...");
                        continue;
                    }
                    yield return OnCreateAnswerSuccess(pc, op3.Desc);
                    break;
                }
                else
                {
                    break;
                }
            }
streunerlein commented 2 years ago

Update: Of course, we've also done things wrong on our side creating these kind of race conditions. By correctly implementing perfect negotiation we haven't seen this phenomenon anymore.