JVB and candidates

Hello here,

Thank for provide us this fantastic tool.
I’ve read multiples topics and check some repositories on Github and I am impressed.

Thank to Jitsi, I’ve learn new technologies and skills, but it’s a big work in progress on my side :grinning:

I’ve a working stack of Jitsi (web, prosody, jicofo and jvb), I’ve followed the configuration in order to running my stack behind a NAT instance (documentation here), WS has been configured.

After running me first conference, audio is good, video working with more than 2 participants (video is not good but not important for now), but Screen Sharing not working.
In the console, I have the common error “Bridge Channel send: no opened channel”. Interrested fact in [modules/RTC/BridgeChannel.js] <l._send>: Bridge Channel send: no opened channel - #13 by mstran someone say you will stuck on 180p if JVB not working. But configuration seems good on JVB (sip-communicator.properties):

org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS="100.10.1.14"
org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS="165.172.140.191"

NB: Yes my local address is public one, this coming from my cloud provider

After activate log XMPP part on JVB (logging.properties):

org.jitsi.videobridge.xmpp.XmppConnection.level=ALL

I can see when I have two participants the message send by the JVB to prosody:

<iq xmlns="jabber:client" to="jvbbrewery@internal-muc.foobar/focus" from="j
vb@auth.foobar/ZgKIa3_t" id="anZiQGF1dGgubWVldC5jYWxsaXR5LnRlY2gvWmdLSWEzX3QAN1k3NUgtMjQ1NwBF5p6j00Cu9qnBpATvKaiT" type="result">
	<conference xmlns="http://jitsi.org/protocol/colibri" id="67f0b53b9c60f35e" name="testingroom@muc.foobar" rtcstats-enabled="true" callstats-enabled="true">
		<content name="audio">
			<channel endpoint="fc12af3e" id="e1bb498a2bf8fc22" initiator="true" channel-bundle-id="fc12af3e" last-n="-1" rtp-level-relay-type="translator">
				<source xmlns="urn:xmpp:jingle:apps:rtp:ssma:0" ssrc="414761362" />
			</channel>
		</content>
		<content name="video">
			<channel endpoint="fc12af3e" id="76cbebbe0d2082e4" initia tor="true" channel-bundle-id="fc12af3e" last-n="-1" rtp-level-relay-type="translator">
				<source xmlns="urn:xmpp:jingle:apps:rtp:ssma:0" ssrc="3502538604" />
				<ssrc-group xmlns="urn:xmpp:jingle:apps:rtp:ssma:0" semantics="FID">
					<source ssrc="2567275508" />
					<source ssrc="3103636259" />
				</ssrc-group>
				<ssrc-group xmlns="urn:xmpp:jingle:apps:rtp:ssma:0" semantics="FID">
					<source ssrc="2483287022" />
					<source ssrc="3258118416" />
				</ssrc-group>
				<ssrc-group xmlns="urn:xmpp:jingle:apps:rtp:ssma:0" semantics="FID">
					<source ssrc="1987432807" />
					<source ssrc="4195797450" />
				</ssrc-group>
				<ssrc-group xmlns="urn:xmpp:jingle:apps:rtp:ssma:0" semantics="SIM">
					<source ssrc="2567275508" />
					<source ssrc="2483287022" />
					<source ssrc="1987432807" />
				</ssrc-group>
				<ssrc>
					2567275508
				</ssrc>
				<ssrc>
					3103636259
				</ssrc>
				<ssrc>
					2483287022
				</ssrc>
				<ssrc>
					3258118416
				</ssrc>
				<ssrc>
					1987432807
				</ssrc>
				<ssrc>
					419
					5797450
				</ssrc>
			</channel>
		</content>
		<channel-bundle id="fc12af3e">
			<transport xmlns="urn:xmpp:jingle:transports:ice-udp:1" pwd="4rd9farh1md1pvtanrqclo8clv" ufrag="56lon1fvsir71k">
				<rtcp-mux />
				<fingerprint xmlns="urn:
xmpp:jingle:apps:dtls:0" setup="passive" hash="sha-256">
					5B:0B:08:44:38:E2:1B:B9:AD:40:71:0E:9D:F1:63:EE:17:75:B4:94:0B:16:E8:1D:D5:F4:47:17:38:1D:D5:54
				</fingerprint>
				<web-socket xmlns="http://jitsi.org/protocol/colibri" url="wss://foobar/colibri-ws/shard-0/67f0b53b9c60f35e/fc12af3e?pwd=4rd9farh1md1pvtanrqclo8clv" />
				<candidate component="1" foundation="1" generation="0" id="2dfcd10bcefdcb0ffffffffd4e4815b" netw ork="0" priority="2130706431" protocol="udp" type="host" ip="100.10.1.14" port="30300" />
				<candidate component="1" foundation="2" generation="0" id="66a5764dcefdcb0145073e7" network="0" priority="1694498815" protocol="udp" type="srflx" ip="165.172.140.191" port="30300" rel-addr="100.10.1.14" rel-port="30300" />
			</transport>
		</channel-bundle>
	</conference>
</iq>

It’s quite strange on the first candidate it’s appear without the mapping of rel-addr.
From my computer and wireshark I can see requests to the public IP of JVB (NAT 165.172.140.191) on 30300 and response. And requests send to the local IP (100.10.1.14) on 30300 without any response.

I’ve no clue on why jitsi-meet try to open bridge on the local IP and why this candidate is not with the rel-addr.
I’ve also try to make the configuration on jvb.conf with the ice4j.harvest.mapping.static-mappings part.

Best

Bastien

Stack informations:

  • Running on k8s based on github/hpi-schul-cloud/jitsi-deployment: one shard one jvb
  • Version stable 7001
  • Client Chrome and Firefox up to date

It’s missing some links because since I’m new I can not make too much link in one post:
For WS, configuration with information in here, here

For bridge channel error, I’ve also check Bridge Channel send: no opened channel.

Hello Bastien and welcome to the community!

The bridge channel is key for high-definition video to work properly. The post that you have linked that says that your video will be stuck on low resolution (180p) if the bridge channel is not opened is accurate. This happens because without the bridge channel, the client has no way to inform the bridge who’s on stage.

The bridge channel will typically go through websockets and there may be some misconfiguration there? Could you please share your config.js file as well as the jvb configuration file (jvb.conf)? I see you’re running on k8s so there may be some complication because of that.

When you say that screen-sharing doesn’t work, what do you mean exactly? It could be helpful to share the full JavaScript console log, as there may be related errors. I don’t think the bridge channel not being established is necessarily related to the screen-sharing issue.

Cheers,
George

1 Like

Fixing the bridge channel will fix all the problems described.

1 Like

Hi @gpolitis ,

Thank for the reply

jvb.conf

videobridge {
    ice {
        udp {
            port = 30300
        }
    }
    apis {
        xmpp-client {
            configs {
                shard {
                    HOSTNAME = "shard-0-prosody"
                    DOMAIN = "auth.meet.bastien.fr"
                    USERNAME = "jvb"
                    PASSWORD = "foobar"
                    MUC_JIDS = "jvbbrewery@internal-muc.meet.bastien.fr"
                    MUC_NICKNAME = "shard-0-jvb-0"
                    DISABLE_CERTIFICATE_VERIFICATION = true
                }
            }
        }
        rest {
            enabled = true
        }
    }
    rest {
        shutdown {
            enabled = false
        }
    }
    stats {
        enabled = true
    }
    websockets {
        enabled = true
        domain = "meet.bastien.fr"
        tls = true
        server-id = "shard-0"
    }
    http-servers {
        private { 
          host = 0.0.0.0
        }
        public {
            host = 0.0.0.0
            port = 9090
        }
    }

    }

ice4j {
    harvest {
        mapping {
            stun {
enabled = false
}
            static-mappings = [
]
        }
    }
}

and in the config.js: Jitsi · GitHub

In prosody configuration, like you mention, I have to enable cross domain, but it was quite clear in the log.

    cross_domain_websocket = { "http://meet.bastien.fr:5280", "https://meet.bastien.fr" }

I’m investigating on

BridgeChannel.js:84 WebSocket connection to 'wss://meet.bastien.fr/colibri-ws/shard-0/3e1478606ca95c06/109eaa9c?pwd=miaoub455q80' failed: 
_initWebSocket @ BridgeChannel.js:84
t @ BridgeChannel.js:103
Logger.js:154 2022-04-05T13:37:40.424Z [modules/RTC/BridgeChannel.js] <WebSocket.e.onclose>:  Channel closed by server
Logger.js:154 2022-04-05T13:37:40.424Z [modules/RTC/BridgeChannel.js] <WebSocket.e.onclose>:  Channel closed: 1006 

And in nginx:

"GET /colibri-ws/shard-0/3e1478606ca95c06/109eaa9c?pwd=miaoub455q80 HTTP/1.1" 503 592 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36" 566 0.000 [jitsi-shard-0-jvb-0-9090] [] - - - - 42dbb2406041c2f63cac66c5975d801d

FYI, I didn’t enable AUTH to simplify the bootstrap.

I hope this happen :slight_smile:

The websocket that you have a problem with is not hitting prosody. It is going to the bridge.
Normally the nginx that is fronting the deployment will forward the request “GET /colibri-ws/shard-0/…” to the bridge port 9090.
Like here: jitsi-meet/jitsi-meet.example at d7c8164b7494d06fb4cb908b5f539020bb12c851 · jitsi/jitsi-meet · GitHub

1 Like

Yes juste found it, I made a typo in service name so no resolution.

I can see now on the jvb ColibriWebSocketServlet.createWebSocket#152: Received request for an nonexistent conference: 3e1478606ca95c06

So right now I have new errors, but It’s more understable what it’s going on

jitsi/shard-0-jvb-0[jvb]: JVB 2022-04-05 16:05:21.632 WARNING: [113] [confId=10df1076f714542e gid=113018 stats_id=Austin-qFa conf_name=bastien4@muc.meet.bastien.fr ufrag=49l7f1fvt0mkk2 epId=bf4df090 local_ufrag=49l7f1fvt0mkk2] ConnectivityCheckClient.startCheckForPair#374: Failed to send BINDING-REQUEST(0x1)[attrib.count=6 len=92 tranID=0x5F570BFA7F0173787B082522]                                                      
jitsi/shard-0-jvb-0[jvb]: java.lang.IllegalArgumentException: No socket found for 100.64.174.52:30300/udp->192.168.20.129:44022/udp                                                                                
jitsi/shard-0-jvb-0[jvb]:       at org.ice4j.stack.NetAccessManager.sendMessage(NetAccessManager.java:631)                                                                                                         
jitsi/shard-0-jvb-0[jvb]:       at org.ice4j.stack.NetAccessManager.sendMessage(NetAccessManager.java:581)                                                                                                         
jitsi/shard-0-jvb-0[jvb]:       at org.ice4j.stack.StunClientTransaction.sendRequest0(StunClientTransaction.java:267)                                                                                              
jitsi/shard-0-jvb-0[jvb]:       at org.ice4j.stack.StunClientTransaction.sendRequest(StunClientTransaction.java:245)                                                                                               
jitsi/shard-0-jvb-0[jvb]:       at org.ice4j.stack.StunStack.sendRequest(StunStack.java:680)                                                                                                                       
jitsi/shard-0-jvb-0[jvb]:       at org.ice4j.ice.ConnectivityCheckClient.startCheckForPair(ConnectivityCheckClient.java:335)                                                                                       
jitsi/shard-0-jvb-0[jvb]:       at org.ice4j.ice.ConnectivityCheckClient.startCheckForPair(ConnectivityCheckClient.java:231)                                                                                       
jitsi/shard-0-jvb-0[jvb]:       at org.ice4j.ice.ConnectivityCheckClient$PaceMaker.run(ConnectivityCheckClient.java:938)                                                                                           
jitsi/shard-0-jvb-0[jvb]:       at org.ice4j.util.PeriodicRunnable.executeRun(PeriodicRunnable.java:206)
jitsi/shard-0-jvb-0[jvb]:       at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)                                                                                               
jitsi/shard-0-jvb-0[jvb]:       at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
jitsi/shard-0-jvb-0[jvb]:       at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)                                                                                       
jitsi/shard-0-jvb-0[jvb]:       at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
jitsi/shard-0-jvb-0[jvb]:       at java.base/java.lang.Thread.run(Thread.java:829)                                                                                                                                 
jitsi/shard-0-jvb-0[jvb]: JVB 2022-04-05 16:05:21.632 INFO: [113] [confId=10df1076f714542e gid=113018 stats_id=Austin-qFa conf_name=bastien4@muc.meet.bastien.fr ufrag=49l7f1fvt0mkk2 epId=bf4df090 local_ufrag=4
9l7f1fvt0mkk2] ConnectivityCheckClient$PaceMaker.run#942: Pair failed: 100.64.174.52:30300/udp/host -> 192.168.20.129:44022/udp/host (stream-bf4df090.RTP)

EDIT:
and after waiting with 2 participants in the room I’ve got


JVB 2022-04-05 16:51:20.760 INFO: [66] [confId=dcfdb9dcd9e718de epId=bc4505ab gid=112141 stats_id=Austin-qFa conf_name=bastien4@muc.meet.bastien.fr] AbstractEndpoint.expire#301: Expiring.
JVB 2022-04-05 16:51:20.761 INFO: [66] [confId=dcfdb9dcd9e718de epId=bc4505ab gid=112141 stats_id=Austin-qFa conf_name=bastien4@muc.meet.bastien.fr] Endpoint.expire#1016: Spent 0 seconds oversending
JVB 2022-04-05 16:51:20.761 INFO: [66] [confId=dcfdb9dcd9e718de epId=bc4505ab gid=112141 stats_id=Austin-qFa conf_name=bastien4@muc.meet.bastien.fr] Transceiver.teardown#348: Tearing down
JVB 2022-04-05 16:51:20.762 INFO: [66] [confId=dcfdb9dcd9e718de epId=bc4505ab gid=112141 stats_id=Austin-qFa conf_name=bastien4@muc.meet.bastien.fr] RtpReceiverImpl.tearDown#344: Tearing down                  JVB 2022-04-05 16:51:20.762 INFO: [66] [confId=dcfdb9dcd9e718de epId=bc4505ab gid=112141 stats_id=Austin-qFa conf_name=bastien4@muc.meet.bastien.fr] RtpSenderImpl.tearDown#314: Tearing down
JVB 2022-04-05 16:51:20.763 INFO: [66] [confId=dcfdb9dcd9e718de epId=bc4505ab gid=112141 stats_id=Austin-qFa conf_name=bastien4@muc.meet.bastien.fr] DtlsTransport.stop#186: Stopping     

and starting to get

JVB 2022-04-05 16:51:21.787 WARNING: [31] ColibriWebSocketServlet.createWebSocket#185: Received request for a nonexistent endpoint: bc4505ab (conference dcfdb9dcd9e718de)

I could be wrong but I suspect that these low-level socket exceptions have something to do with your k8s setup, so it may be useful to share your k8s configuration.

I suppose you have enabled inbound and outbound traffic because you mention audio and basic video works but do any of the networking parameters change dynamically at runtime? Have you made sure to properly expose port 30300 and disable any firewall rules on that port?

Okay since I started this thread; ofc audio and video are gone.

For the k8s part, I’m using nodePort through service:

apiVersion: v1
kind: Service
metadata:
  name: shard-0-jvb-0
spec:
  ports:
  - nodePort: 30300
    port: 30300
    protocol: UDP
    targetPort: 30300
  selector:
    statefulset.kubernetes.io/pod-name: shard-0-jvb-0
  sessionAffinity: None
  type: NodePort

And on cloud provider side:

Inbound Rules (default policy accept):
ID                                    PROTOCOL  ACTION  IP RANGE   DEST
c3ce10ec-06ed-48ed-8eb5-54045a8bae17  UDP       accept  0.0.0.0/0  30300
98e8c8d0-6b79-4c1e-b94e-ce3c17d8ff06  TCP       accept  0.0.0.0/0  30300

Just to be sure; when these variables are set:

org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS="100.10.1.14"
org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS="165.172.140.191"

No need to put STUN configuration ?

you need to check in the log what are the values for the static mapping. I don’t know what could happen when you have an empty set in jvb.conf and values set in sip-communicator.properties. Maybe it could be interesting to comment out the values in sip-communicator.properties and set the mapping in the ice4j section of jvb.conf.

ice4j {
  harvest {
     mapping {
        aws {
          enabled = false
        }
        static-mappings = [
           {
             local-address = "100.10.1.14"
             public-address = "165.172.140.191"
           }
        ]
     }
  }
}

Your setup with a public address natted seems strange to me but I don’t know your setup.

Hello,

I can see in log with sip-communication.properties directives:

jitsi/shard-0-jvb-0[jvb]: JVB 2022-04-06 09:58:10.444 INFO: [11] org.ice4j.ice.harvest.MappingCandidateHarvesters.initialize: Adding a static mapping: StaticMapping(localAddress="100.10.1.14", publicAddress="165.172.140.191", localPort=null, publicPort=null, name=null)                                                                                                                                                       jitsi/shard-0-jvb-0[jvb]: JVB 2022-04-06 09:58:10.457 INFO: [11] org.ice4j.ice.harvest.MappingCandidateHarvesters.initialize: Using org.ice4j.ice.harvest.StaticMappingCandidateHarvester(face="100.10.1.14":9/ud
p, mask="165.172.140.191":9/udp)

The behavior is quite the same when using static-mapping only (I for port in order to be sure it’s taking care of my configuration):

jitsi/shard-0-jvb-0[jvb]: JVB 2022-04-06 10:02:20.991 INFO: [11] org.ice4j.ice.harvest.MappingCandidateHarvesters.initialize: Adding a static mapping: StaticMapping(localAddress=100.10.1.14, publicAddress=163.
172.160.191, localPort=null, publicPort=null, name=null)
jitsi/shard-0-jvb-0[jvb]: JVB 2022-04-06 10:02:21.042 INFO: [11] org.ice4j.ice.harvest.MappingCandidateHarvesters.initialize: Using org.ice4j.ice.harvest.StaticMappingCandidateHarvester(face=100.10.1.14:9/
udp, mask=163.
172.160.191:9/udp)

I don’t think quote can be a problem ? Moreover the port 9 it’s not corresponding to my 30300, this can be a problem or not ?

best

Yes, I’m running on Scaleway (DC in French for RGPD concern), I don’t understand why they are doing that.

I think quote make something wrong, because right now it’s working. Quality is good, audio is clear, screen sharing is good.

I’ll continue to test it and activate authentification part.
I’ll try to make a resume / schema for the next people.

Glad to hear it is working well for you Bastien! Just a nit-pick, it seems you are using two JVB config files (jvb.conf and sip-communicator.properties). You may want to save everything in a single file, preferably the jvb.conf file (and remove the sip-communicator.properties file) which is newer. Let us know if you need any help with that.

Quick news.

I put coturn in place for the people who have aggressive firewall.

Big thank to this thread and more precisely this response

Time to put all this stuff under automation