Calls Plugin does not work on mobile network

Hello, I’m having a very strange problem with the calls plugin, in principle everything is working fine, I’m using an ethernet network, or a Wi-Fi network connected to a router, the problem is if I connect to a call using mobile data , I have tried with 2 different mobile data providers and the same error occurs, the rtc closes and I receive the following error: “Error: unable to connect to the voice call: timed out waiting for peer connection.”.
I have Mattermost installed on a Docker with Linux, and hosted on AWS.
I have Mattermost version: 7.9.1
Calls plugin version: 0.14.0

These are the ports I have open on my AWS:

This is my Nginx configuration:

upstream backend {
    server mattermost:8065;
    keepalive 32;
 }
 
 proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mattermost_cache:10m max_size=3g inactive=120m use_temp_path=off;
 
 server {
   listen 80 default_server;
   server_name   myserver.mattermost.local;
   return 301 https://$server_name$request_uri;
 }
 
 server {
    listen 443 ssl http2;
    server_name    myserver.mattermost.local

    http2_push_preload on; # Enable HTTP/2 Server Push

    ssl_certificate /etc/nginx/certificates/myserver.mattermost.local.crt;
    ssl_certificate_key /etc/nginx/certificates/myserver.mattermost.local.private.key;
    ssl_session_timeout 1d;
 
    # Enable TLS versions (TLSv1.3 is required upcoming HTTP/3 QUIC).
    ssl_protocols TLSv1.2 TLSv1.3;
 
    # Enable TLSv1.3's 0-RTT. Use $ssl_early_data when reverse proxying to
    # prevent replay attacks.
    #
    # @see: https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_early_data
    ssl_early_data on;
 
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384';
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:50m;
    # HSTS (ngx_http_headers_module is required) (15768000 seconds = six months)
    add_header Strict-Transport-Security max-age=15768000;
    # OCSP Stapling ---
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;
 
    add_header X-Early-Data $tls1_3_early_data;
 
    location ~ /api/v[0-9]+/(users/)?websocket$ {
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        client_max_body_size 50M;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Frame-Options SAMEORIGIN;
        proxy_buffers 256 16k;
        proxy_buffer_size 16k;
        client_body_timeout 60;
        send_timeout 300;
        lingering_timeout 5;
        proxy_connect_timeout 90;
        proxy_send_timeout 300;
        proxy_read_timeout 90s;
        proxy_http_version 1.1;
        proxy_pass https://mattermost:8065;
    }
 
    location / {
        client_max_body_size 50M;
        proxy_set_header Connection "";
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Frame-Options SAMEORIGIN;
        proxy_buffers 256 16k;
        proxy_buffer_size 16k;
        proxy_read_timeout 600s;
        proxy_cache mattermost_cache;
        proxy_cache_revalidate on;
        proxy_cache_min_uses 2;
        proxy_cache_use_stale timeout;
        proxy_cache_lock on;
        proxy_http_version 1.1;
        proxy_pass https://mattermost:8065;
    }
 }
 
 # This block is useful for debugging TLS v1.3. Please feel free to remove this
 # and use the `$ssl_early_data` variable exposed by NGINX directly should you
 # wish to do so.
 map $ssl_early_data $tls1_3_early_data
 {
    "~." $ssl_early_data;
    default "";
 }

If you need more information tell me.
I don’t know what could be happening, since it works fine with wifi or ethernet, but not with the mobile network.
PS: I have tried to put the mobile as a router, and that the PC connects to the mobile via WIFI, but it does not work either because it uses mobile data.
Thanks for the help

Hi @franlucas92 and welcome to the Mattermost forums!

Just a wild guess, but is your server dual-stacked (IPv4 and IPv6) and is there also a hostname for the IPv6 address (AAAA record)? Calls does not support IPv6 at the moment, the integrated rtcd is only listening on an IPv4 address on port udp/8443.
What does your calls configuration look like? Are you using STUN/TURN servers or did you forward the UDP port 8443 directly to the Mattermost server? I’m not 100% sure if using the STUN/TURN servers will allow for bridging the protocol gap here, but if you’re forwarding udp/8443 directly to your Mattermost server, you could try to workaround that by specifying the IPv4 address of your server in the Calls plugin’s ICEHostOverride setting to check if that changes anything.
If not, we can at least rule out the IPv6 topic I guess.

Thanks for answering and sorry for the delay in responding. We have the server by default as it is created, we have no distinction between IPv6 or IPv4, this is the code of the 4 files that I have to create and configure the server, I don’t know if the problem is there.

env file:

# Domain of service
DOMAIN=cloud.myserver.com

# Container settings
## Timezone inside the containers. The value needs to be in the form 'Europe/Berlin'.
## A list of these tz database names can be looked up at Wikipedia
## https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
TZ=UTC
RESTART_POLICY=unless-stopped

# Postgres settings
## Documentation for this image and available settings can be found on hub.docker.com
## https://hub.docker.com/_/postgres
## Please keep in mind this will create a superuser and it's recommended to use a less privileged
## user to connect to the database.
## A guide on how to change the database user to a nonsuperuser can be found in docs/creation-of-nonsuperuser.md
POSTGRES_IMAGE_TAG=13-alpine
POSTGRES_DATA_PATH=./volumes/db/var/lib/postgresql/data

POSTGRES_USER=mmuser
POSTGRES_PASSWORD=dij524flsd6
POSTGRES_DB=mattermost

# Nginx
## The nginx container will use a configuration found at the NGINX_MATTERMOST_CONFIG. The config aims
## to be secure and uses a catch-all server vhost which will work out-of-the-box. For additional settings
## or changes ones can edit it or provide another config. Important note: inside the container, nginx sources
## every config file inside */etc/nginx/conf.d* ending with a *.conf* file extension.

## Inside the container the uid and gid is 101. The folder owner can be set with
## `sudo chown -R 101:101 ./nginx` if needed.
NGINX_IMAGE_TAG=alpine

## The folder containing server blocks and any additional config to nginx.conf
NGINX_CONFIG_PATH=./nginx/conf.d
NGINX_DHPARAMS_FILE=./nginx/dhparams4096.pem

CERT_PATH=./volumes/web/cert/cloud.myserver.com.crt
KEY_PATH=./volumes/web/cert/private.key
#GITLAB_PKI_CHAIN_PATH=<path_to_your_gitlab_pki>/pki_chain.pem
#CERT_PATH=./certs/etc/letsencrypt/live/${DOMAIN}/fullchain.pem
#KEY_PATH=./certs/etc/letsencrypt/live/${DOMAIN}/privkey.pem

## Exposed ports to the host. Inside the container 80, 443 and 8443 will be used
HTTPS_PORT=443
HTTP_PORT=80
CALLS_PORT=8443

# Mattermost settings
## Inside the container the uid and gid is 2000. The folder owner can be set with
## `sudo chown -R 2000:2000 ./volumes/app/mattermost`.
MATTERMOST_CONFIG_PATH=./volumes/app/mattermost/config
MATTERMOST_DATA_PATH=./volumes/app/mattermost/data
MATTERMOST_LOGS_PATH=./volumes/app/mattermost/logs
MATTERMOST_PLUGINS_PATH=./volumes/app/mattermost/plugins
MATTERMOST_CLIENT_PLUGINS_PATH=./volumes/app/mattermost/client/plugins
MATTERMOST_BLEVE_INDEXES_PATH=./volumes/app/mattermost/bleve-indexes

## Bleve index (inside the container)
MM_BLEVESETTINGS_INDEXDIR=/mattermost/bleve-indexes

## This will be 'mattermost-enterprise-edition' or 'mattermost-team-edition' based on the version of Mattermost you're installing.
MATTERMOST_IMAGE=mattermost-team-edition
MATTERMOST_IMAGE_TAG=7.9.1

## Make Mattermost container readonly. This interferes with the regeneration of root.html inside the container. Only use
## it if you know what you're doing.
## See https://github.com/mattermost/docker/issues/18
MATTERMOST_CONTAINER_READONLY=false

## The app port is only relevant for using Mattermost without the nginx container as reverse proxy. This is not meant
## to be used with the internal HTTP server exposed but rather in case one wants to host several services on one host
## or for using it behind another existing reverse proxy.
APP_PORT=8065

## Configuration settings for Mattermost. Documentation on the variables and the settings itself can be found at
## https://docs.mattermost.com/administration/config-settings.html
## Keep in mind that variables set here will take precedence over the same setting in config.json. This includes
## the system console as well and settings set with env variables will be greyed out.

## Below one can find necessary settings to spin up the Mattermost container
MM_SQLSETTINGS_DRIVERNAME=postgres
#MM_SQLSETTINGS_DATASOURCE=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?sslmode=disable&connect_timeout=10
MM_SQLSETTINGS_DATASOURCE=postgres://mmuser:dij524flsd6@postgres:5432/mattermost?sslmode=disable&connect_timeout=10

## Example settings (any additional setting added here also needs to be introduced in the docker-compose.yml)
MM_SERVICESETTINGS_SITEURL=https://cloud.myserver.com

docker-compose.yml file:

# https://docs.docker.com/compose/environment-variables/

version: "2.4"

services:
  postgres:
    image: postgres:${POSTGRES_IMAGE_TAG}
    container_name: postgres
    networks:
      - myservernet
    restart: ${RESTART_POLICY}
    security_opt:
      - no-new-privileges:true
    pids_limit: 100
    read_only: true
    tmpfs:
      - /tmp
      - /var/run/postgresql
    volumes:
      - ${POSTGRES_DATA_PATH}:/var/lib/postgresql/data
    environment:
      # timezone inside container
      - TZ

      # necessary Postgres options/variables
      - POSTGRES_USER
      - POSTGRES_PASSWORD
      - POSTGRES_DB

  mattermost:
    depends_on:
      - postgres
    image: mattermost/${MATTERMOST_IMAGE}:${MATTERMOST_IMAGE_TAG}
    container_name: mattermost
    networks:
      - myservernet
    restart: ${RESTART_POLICY}
    security_opt:
      - no-new-privileges:true
    pids_limit: 200
    read_only: ${MATTERMOST_CONTAINER_READONLY}
    tmpfs:
      - /tmp
    ports:
      - ${APP_PORT}:${APP_PORT}
      - ${CALLS_PORT}:${CALLS_PORT}
    volumes:
      - ${MATTERMOST_CONFIG_PATH}:/mattermost/config:rw
      - ${MATTERMOST_DATA_PATH}:/mattermost/data:rw
      - ${MATTERMOST_LOGS_PATH}:/mattermost/logs:rw
      - ${MATTERMOST_PLUGINS_PATH}:/mattermost/plugins:rw
      - ${MATTERMOST_CLIENT_PLUGINS_PATH}:/mattermost/client/plugins:rw
      - ${MATTERMOST_BLEVE_INDEXES_PATH}:/mattermost/bleve-indexes:rw
      - ${CERT_PATH}:/mattermost/cert/cloud.myserver.com.crt:ro
      - ${KEY_PATH}:/mattermost/cert/private.key:ro
      # When you want to use SSO with GitLab, you have to add the cert pki chain of GitLab inside Alpine
      # to avoid Token request failed: certificate signed by unknown authority 
      # (link: https://github.com/mattermost/mattermost-server/issues/13059 and https://github.com/mattermost/docker/issues/34)
      # - ${GITLAB_PKI_CHAIN_PATH}:/etc/ssl/certs/pki_chain.pem:ro
    environment:
      # timezone inside container
      - TZ


      - VIRTUAL_HOST=cloud.myserver.com
      
      # necessary Mattermost options/variables (see env.example)
      - MM_SQLSETTINGS_DRIVERNAME
      - MM_SQLSETTINGS_DATASOURCE

      # necessary for bleve
      - MM_BLEVESETTINGS_INDEXDIR

      # additional settings
      - MM_SERVICESETTINGS_SITEURL

networks:
  myservernet:
    external: true
# If you use rolling image tags and feel lucky watchtower can automatically pull new images and
# instantiate containers from it. https://containrrr.dev/watchtower/
# Please keep in mind watchtower will have access on the docker socket. This can be a security risk.
#
#  watchtower:
#    container_name: watchtower
#    image: containrrr/watchtower:latest
#    restart: unless-stopped
#    volumes:
#      - /var/run/docker.sock:/var/run/docker.sock

config.json file:

{
    "ServiceSettings": {
        "SiteURL": "https://cloud.myserver.com:8065",
        "WebsocketURL": "",
        "LicenseFileLocation": "",
        "ListenAddress": ":8065",
        "ConnectionSecurity": "TLS",
        "TLSCertFile": "/mattermost/cert/cloud.myserver.com.crt",
        "TLSKeyFile": "/mattermost/cert/private.key",
        "TLSMinVer": "1.2",
        "TLSStrictTransport": false,
        "TLSStrictTransportMaxAge": 63072000,
        "TLSOverwriteCiphers": [],
        "UseLetsEncrypt": false,
        "LetsEncryptCertificateCacheFile": "./config/letsencrypt.cache",
        "Forward80To443": false,
        "TrustedProxyIPHeader": [],
        "ReadTimeout": 300,
        "WriteTimeout": 300,
        "IdleTimeout": 60,
        "MaximumLoginAttempts": 10,
        "GoroutineHealthThreshold": -1,
        "EnableOAuthServiceProvider": false,
        "EnableIncomingWebhooks": true,
        "EnableOutgoingWebhooks": true,
        "EnableCommands": true,
        "EnablePostUsernameOverride": false,
        "EnablePostIconOverride": false,
        "GoogleDeveloperKey": "",
        "EnableLinkPreviews": true,
        "EnablePermalinkPreviews": true,
        "RestrictLinkPreviews": "",
        "EnableTesting": false,
        "EnableDeveloper": false,
        "DeveloperFlags": "",
        "EnableClientPerformanceDebugging": false,
        "EnableOpenTracing": false,
        "EnableSecurityFixAlert": true,
        "EnableInsecureOutgoingConnections": false,
        "AllowedUntrustedInternalConnections": "",
        "EnableMultifactorAuthentication": false,
        "EnforceMultifactorAuthentication": false,
        "EnableUserAccessTokens": false,
        "AllowCorsFrom": "",
        "CorsExposedHeaders": "",
        "CorsAllowCredentials": false,
        "CorsDebug": false,
        "AllowCookiesForSubdomains": false,
        "ExtendSessionLengthWithActivity": false,
        "SessionLengthWebInDays": 180,
        "SessionLengthWebInHours": 4320,
        "SessionLengthMobileInDays": 180,
        "SessionLengthMobileInHours": 4320,
        "SessionLengthSSOInDays": 30,
        "SessionLengthSSOInHours": 720,
        "SessionCacheInMinutes": 10,
        "SessionIdleTimeoutInMinutes": 43200,
        "WebsocketSecurePort": 443,
        "WebsocketPort": 80,
        "WebserverMode": "gzip",
        "EnableGifPicker": true,
        "GfycatAPIKey": "2_KtH_W5",
        "GfycatAPISecret": "3wLVZPiswc3DnaiaFoLkDvB4X0IV6CpMkj4tf2inJRsBY6-FnkT08zGmppWFgeof",
        "EnableCustomEmoji": true,
        "EnableEmojiPicker": true,
        "PostEditTimeLimit": -1,
        "TimeBetweenUserTypingUpdatesMilliseconds": 5000,
        "EnablePostSearch": true,
        "EnableFileSearch": true,
        "MinimumHashtagLength": 3,
        "EnableUserTypingMessages": true,
        "EnableChannelViewedMessages": true,
        "EnableUserStatuses": true,
        "ExperimentalEnableAuthenticationTransfer": true,
        "ClusterLogTimeoutMilliseconds": 2000,
        "EnablePreviewFeatures": true,
        "EnableTutorial": true,
        "EnableOnboardingFlow": true,
        "ExperimentalEnableDefaultChannelLeaveJoinMessages": true,
        "ExperimentalGroupUnreadChannels": "disabled",
        "EnableAPITeamDeletion": true,
        "EnableAPITriggerAdminNotifications": false,
        "EnableAPIUserDeletion": true,
        "ExperimentalEnableHardenedMode": false,
        "ExperimentalStrictCSRFEnforcement": false,
        "EnableEmailInvitations": true,
        "DisableBotsWhenOwnerIsDeactivated": true,
        "EnableBotAccountCreation": false,
        "EnableSVGs": true,
        "EnableLatex": true,
        "EnableInlineLatex": true,
        "PostPriority": true,
        "EnableAPIChannelDeletion": true,
        "EnableLocalMode": false,
        "LocalModeSocketLocation": "/var/tmp/mattermost_local.socket",
        "EnableAWSMetering": false,
        "SplitKey": "",
        "FeatureFlagSyncIntervalSeconds": 30,
        "DebugSplit": false,
        "ThreadAutoFollow": true,
        "CollapsedThreads": "always_on",
        "ManagedResourcePaths": "",
        "EnableCustomGroups": true,
        "SelfHostedPurchase": true,
        "AllowSyncedDrafts": true
    },
    "TeamSettings": {
        "SiteName": "Mattermost",
        "MaxUsersPerTeam": 50,
        "EnableUserCreation": true,
        "EnableOpenServer": false,
        "EnableUserDeactivation": false,
        "RestrictCreationToDomains": "",
        "EnableCustomUserStatuses": true,
        "EnableCustomBrand": false,
        "CustomBrandText": "",
        "CustomDescriptionText": "",
        "RestrictDirectMessage": "any",
        "EnableLastActiveTime": true,
        "UserStatusAwayTimeout": 300,
        "MaxChannelsPerTeam": 2000,
        "MaxNotificationsPerChannel": 1000,
        "EnableConfirmNotificationsToChannel": true,
        "TeammateNameDisplay": "username",
        "ExperimentalViewArchivedChannels": true,
        "ExperimentalEnableAutomaticReplies": false,
        "LockTeammateNameDisplay": false,
        "ExperimentalPrimaryTeam": "",
        "ExperimentalDefaultChannels": []
    },
    "ClientRequirements": {
        "AndroidLatestVersion": "",
        "AndroidMinVersion": "",
        "IosLatestVersion": "",
        "IosMinVersion": ""
    },
    "SqlSettings": {
        "DriverName": "postgres",
        "DataSource": "postgres://mmuser:mostest@localhost/mattermost_test?sslmode=disable\u0026connect_timeout=10\u0026binary_parameters=yes",
        "DataSourceReplicas": [],
        "DataSourceSearchReplicas": [],
        "MaxIdleConns": 20,
        "ConnMaxLifetimeMilliseconds": 3600000,
        "ConnMaxIdleTimeMilliseconds": 300000,
        "MaxOpenConns": 300,
        "Trace": false,
        "AtRestEncryptKey": "i6y1mtsqp5ui4cgmp39e9oozesysjg6h",
        "QueryTimeout": 30,
        "DisableDatabaseSearch": false,
        "MigrationsStatementTimeoutSeconds": 100000,
        "ReplicaLagSettings": []
    },
    "LogSettings": {
        "EnableConsole": true,
        "ConsoleLevel": "DEBUG",
        "ConsoleJson": true,
        "EnableColor": false,
        "EnableFile": true,
        "FileLevel": "INFO",
        "FileJson": true,
        "FileLocation": "",
        "EnableWebhookDebugging": true,
        "EnableDiagnostics": true,
        "VerboseDiagnostics": false,
        "EnableSentry": true,
        "AdvancedLoggingConfig": ""
    },
    "ExperimentalAuditSettings": {
        "FileEnabled": false,
        "FileName": "",
        "FileMaxSizeMB": 100,
        "FileMaxAgeDays": 0,
        "FileMaxBackups": 0,
        "FileCompress": false,
        "FileMaxQueueSize": 1000,
        "AdvancedLoggingConfig": ""
    },
    "NotificationLogSettings": {
        "EnableConsole": true,
        "ConsoleLevel": "DEBUG",
        "ConsoleJson": true,
        "EnableColor": false,
        "EnableFile": true,
        "FileLevel": "INFO",
        "FileJson": true,
        "FileLocation": "",
        "AdvancedLoggingConfig": ""
    },
    "PasswordSettings": {
        "MinimumLength": 8,
        "Lowercase": false,
        "Number": false,
        "Uppercase": false,
        "Symbol": false
    },
    "FileSettings": {
        "EnableFileAttachments": true,
        "EnableMobileUpload": true,
        "EnableMobileDownload": true,
        "MaxFileSize": 104857600,
        "MaxImageResolution": 33177600,
        "MaxImageDecoderConcurrency": -1,
        "DriverName": "local",
        "Directory": "./data/",
        "EnablePublicLink": false,
        "ExtractContent": true,
        "ArchiveRecursion": false,
        "PublicLinkSalt": "8xmpmtqy634wbu3ukwffhwh3zrjgpzxt",
        "InitialFont": "nunito-bold.ttf",
        "AmazonS3AccessKeyId": "",
        "AmazonS3SecretAccessKey": "",
        "AmazonS3Bucket": "",
        "AmazonS3PathPrefix": "",
        "AmazonS3Region": "",
        "AmazonS3Endpoint": "s3.amazonaws.com",
        "AmazonS3SSL": true,
        "AmazonS3SignV2": false,
        "AmazonS3SSE": false,
        "AmazonS3Trace": false,
        "AmazonS3RequestTimeoutMilliseconds": 30000
    },
    "EmailSettings": {
        "EnableSignUpWithEmail": true,
        "EnableSignInWithEmail": true,
        "EnableSignInWithUsername": true,
        "SendEmailNotifications": true,
        "UseChannelInEmailNotifications": false,
        "RequireEmailVerification": false,
        "FeedbackName": "myserver Team",
        "FeedbackEmail": "webmaster@cloud.myserver.com",
        "ReplyToAddress": "webmaster@cloud.myserver.com",
        "FeedbackOrganization": "myserver Studios, S.L.",
        "EnableSMTPAuth": false,
        "SMTPUsername": "",
        "SMTPPassword": "",
        "SMTPServer": "localhost",
        "SMTPPort": "10025",
        "SMTPServerTimeout": 10,
        "ConnectionSecurity": "",
        "SendPushNotifications": true,
        "PushNotificationServer": "https://push-test.mattermost.com",
        "PushNotificationContents": "full",
        "PushNotificationBuffer": 1000,
        "EnableEmailBatching": false,
        "EmailBatchingBufferSize": 256,
        "EmailBatchingInterval": 30,
        "EnablePreviewModeBanner": false,
        "SkipServerCertificateVerification": false,
        "EmailNotificationContentsType": "full",
        "LoginButtonColor": "#0000",
        "LoginButtonBorderColor": "#2389D7",
        "LoginButtonTextColor": "#2389D7",
        "EnableInactivityEmail": true
    },
    "RateLimitSettings": {
        "Enable": false,
        "PerSec": 10,
        "MaxBurst": 100,
        "MemoryStoreSize": 10000,
        "VaryByRemoteAddr": true,
        "VaryByUser": false,
        "VaryByHeader": ""
    },
    "PrivacySettings": {
        "ShowEmailAddress": true,
        "ShowFullName": true
    },
    "SupportSettings": {
        "TermsOfServiceLink": "https://mattermost.com/terms-of-use/",
        "PrivacyPolicyLink": "https://mattermost.com/privacy-policy/",
        "AboutLink": "https://docs.mattermost.com/about/product.html/",
        "HelpLink": "https://mattermost.com/default-help/",
        "ReportAProblemLink": "https://mattermost.com/default-report-a-problem/",
        "SupportEmail": "webmaster@cloud.myserver.com",
        "CustomTermsOfServiceEnabled": false,
        "CustomTermsOfServiceReAcceptancePeriod": 365,
        "EnableAskCommunityLink": true
    },
    "AnnouncementSettings": {
        "EnableBanner": false,
        "BannerText": "",
        "BannerColor": "#f2a93b",
        "BannerTextColor": "#333333",
        "AllowBannerDismissal": true,
        "AdminNoticesEnabled": false,
        "UserNoticesEnabled": false,
        "NoticesURL": "https://notices.mattermost.com/",
        "NoticesFetchFrequency": 3600,
        "NoticesSkipCache": false
    },
    "ThemeSettings": {
        "EnableThemeSelection": true,
        "DefaultTheme": "default",
        "AllowCustomThemes": true,
        "AllowedThemes": []
    },
    "GitLabSettings": {
        "Enable": false,
        "Secret": "",
        "Id": "",
        "Scope": "",
        "AuthEndpoint": "",
        "TokenEndpoint": "",
        "UserAPIEndpoint": "",
        "DiscoveryEndpoint": "",
        "ButtonText": "",
        "ButtonColor": ""
    },
    "GoogleSettings": {
        "Enable": false,
        "Secret": "",
        "Id": "",
        "Scope": "profile email",
        "AuthEndpoint": "https://accounts.google.com/o/oauth2/v2/auth",
        "TokenEndpoint": "https://www.googleapis.com/oauth2/v4/token",
        "UserAPIEndpoint": "https://people.googleapis.com/v1/people/me?personFields=names,emailAddresses,nicknames,metadata",
        "DiscoveryEndpoint": "",
        "ButtonText": "",
        "ButtonColor": ""
    },
    "Office365Settings": {
        "Enable": false,
        "Secret": "",
        "Id": "",
        "Scope": "User.Read",
        "AuthEndpoint": "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
        "TokenEndpoint": "https://login.microsoftonline.com/common/oauth2/v2.0/token",
        "UserAPIEndpoint": "https://graph.microsoft.com/v1.0/me",
        "DiscoveryEndpoint": "",
        "DirectoryId": ""
    },
    "OpenIdSettings": {
        "Enable": false,
        "Secret": "",
        "Id": "",
        "Scope": "profile openid email",
        "AuthEndpoint": "",
        "TokenEndpoint": "",
        "UserAPIEndpoint": "",
        "DiscoveryEndpoint": "",
        "ButtonText": "",
        "ButtonColor": "#145DBF"
    },
    "LdapSettings": {
        "Enable": false,
        "EnableSync": false,
        "LdapServer": "",
        "LdapPort": 389,
        "ConnectionSecurity": "",
        "BaseDN": "",
        "BindUsername": "",
        "BindPassword": "",
        "UserFilter": "",
        "GroupFilter": "",
        "GuestFilter": "",
        "EnableAdminFilter": false,
        "AdminFilter": "",
        "GroupDisplayNameAttribute": "",
        "GroupIdAttribute": "",
        "FirstNameAttribute": "",
        "LastNameAttribute": "",
        "EmailAttribute": "",
        "UsernameAttribute": "",
        "NicknameAttribute": "",
        "IdAttribute": "",
        "PositionAttribute": "",
        "LoginIdAttribute": "",
        "PictureAttribute": "",
        "SyncIntervalMinutes": 60,
        "SkipCertificateVerification": false,
        "PublicCertificateFile": "/mattermost/cert/cloud.myserver.com.crt",
        "PrivateKeyFile": "/mattermost/cert/private.key",
        "QueryTimeout": 60,
        "MaxPageSize": 0,
        "LoginFieldName": "",
        "LoginButtonColor": "#0000",
        "LoginButtonBorderColor": "#2389D7",
        "LoginButtonTextColor": "#2389D7",
        "Trace": false
    },
    "ComplianceSettings": {
        "Enable": false,
        "Directory": "./data/",
        "EnableDaily": false,
        "BatchSize": 30000
    },
    "LocalizationSettings": {
        "DefaultServerLocale": "es",
        "DefaultClientLocale": "es",
        "AvailableLocales": "es,en"
    },
    "SamlSettings": {
        "Enable": false,
        "EnableSyncWithLdap": false,
        "EnableSyncWithLdapIncludeAuth": false,
        "IgnoreGuestsLdapSync": false,
        "Verify": true,
        "Encrypt": true,
        "SignRequest": false,
        "IdpURL": "",
        "IdpDescriptorURL": "",
        "IdpMetadataURL": "",
        "ServiceProviderIdentifier": "",
        "AssertionConsumerServiceURL": "",
        "SignatureAlgorithm": "RSAwithSHA1",
        "CanonicalAlgorithm": "Canonical1.0",
        "ScopingIDPProviderId": "",
        "ScopingIDPName": "",
        "IdpCertificateFile": "",
        "PublicCertificateFile": "",
        "PrivateKeyFile": "",
        "IdAttribute": "",
        "GuestAttribute": "",
        "EnableAdminAttribute": false,
        "AdminAttribute": "",
        "FirstNameAttribute": "",
        "LastNameAttribute": "",
        "EmailAttribute": "",
        "UsernameAttribute": "",
        "NicknameAttribute": "",
        "LocaleAttribute": "",
        "PositionAttribute": "",
        "LoginButtonText": "SAML",
        "LoginButtonColor": "#34a28b",
        "LoginButtonBorderColor": "#2389D7",
        "LoginButtonTextColor": "#ffffff"
    },
    "NativeAppSettings": {
        "AppCustomURLSchemes": [
            "mmauth://",
            "mmauthbeta://"
        ],
        "AppDownloadLink": "https://mattermost.com/download/#mattermostApps",
        "AndroidAppDownloadLink": "https://mattermost.com/mattermost-android-app/",
        "IosAppDownloadLink": "https://mattermost.com/mattermost-ios-app/"
    },
    "ClusterSettings": {
        "Enable": false,
        "ClusterName": "",
        "OverrideHostname": "",
        "NetworkInterface": "",
        "BindAddress": "",
        "AdvertiseAddress": "",
        "UseIPAddress": true,
        "EnableGossipCompression": true,
        "EnableExperimentalGossipEncryption": false,
        "ReadOnlyConfig": true,
        "GossipPort": 8074,
        "StreamingPort": 8075,
        "MaxIdleConns": 100,
        "MaxIdleConnsPerHost": 128,
        "IdleConnTimeoutMilliseconds": 90000
    },
    "MetricsSettings": {
        "Enable": false,
        "BlockProfileRate": 0,
        "ListenAddress": ":8067"
    },
    "ExperimentalSettings": {
        "ClientSideCertEnable": false,
        "ClientSideCertCheck": "secondary",
        "LinkMetadataTimeoutMilliseconds": 5000,
        "RestrictSystemAdmin": false,
        "UseNewSAMLLibrary": false,
        "EnableSharedChannels": false,
        "EnableRemoteClusterService": false,
        "EnableAppBar": false,
        "PatchPluginsReactDOM": false
    },
    "AnalyticsSettings": {
        "MaxUsersForStatistics": 2500
    },
    "ElasticsearchSettings": {
        "ConnectionURL": "http://localhost:9200",
        "Username": "elastic",
        "Password": "changeme",
        "EnableIndexing": false,
        "EnableSearching": false,
        "EnableAutocomplete": false,
        "Sniff": true,
        "PostIndexReplicas": 1,
        "PostIndexShards": 1,
        "ChannelIndexReplicas": 1,
        "ChannelIndexShards": 1,
        "UserIndexReplicas": 1,
        "UserIndexShards": 1,
        "AggregatePostsAfterDays": 365,
        "PostsAggregatorJobStartTime": "03:00",
        "IndexPrefix": "",
        "LiveIndexingBatchSize": 1,
        "BatchSize": 10000,
        "RequestTimeoutSeconds": 30,
        "SkipTLSVerification": false,
        "CA": "",
        "ClientCert": "",
        "ClientKey": "",
        "Trace": ""
    },
    "BleveSettings": {
        "IndexDir": "",
        "EnableIndexing": false,
        "EnableSearching": false,
        "EnableAutocomplete": false,
        "BatchSize": 10000
    },
    "DataRetentionSettings": {
        "EnableMessageDeletion": false,
        "EnableFileDeletion": false,
        "EnableBoardsDeletion": false,
        "MessageRetentionDays": 365,
        "FileRetentionDays": 365,
        "BoardsRetentionDays": 365,
        "DeletionJobStartTime": "02:00",
        "BatchSize": 3000
    },
    "MessageExportSettings": {
        "EnableExport": false,
        "ExportFormat": "actiance",
        "DailyRunTime": "01:00",
        "ExportFromTimestamp": 0,
        "BatchSize": 10000,
        "DownloadExportResults": false,
        "GlobalRelaySettings": {
            "CustomerType": "A9",
            "SMTPUsername": "",
            "SMTPPassword": "",
            "EmailAddress": "",
            "SMTPServerTimeout": 1800
        }
    },
    "JobSettings": {
        "RunJobs": true,
        "RunScheduler": true,
        "CleanupJobsThresholdDays": -1,
        "CleanupConfigThresholdDays": -1
    },
    "ProductSettings": {
        "EnablePublicSharedBoards": false
    },
    "PluginSettings": {
        "Enable": true,
        "EnableUploads": true,
        "AllowInsecureDownloadURL": true,
        "EnableHealthCheck": true,
        "Directory": "./plugins",
        "ClientDirectory": "./client/plugins",
        "Plugins": {
            "com.mattermost.calls": {
                "allowenablecalls": true,
                "allowscreensharing": true,
                "defaultenabled": true,
                "enablerecordings": false,
                "icehostoverride": "",
                "iceserversconfigs": "[{\"urls\":[\"stun:stun.global.calls.mattermost.com:3478\"]}]",
                "jobserviceurl": null,
                "maxcallparticipants": 0,
                "maxrecordingduration": 60,
                "rtcdserviceurl": null,
                "serversideturn": false,
                "turncredentialsexpirationminutes": 1440,
                "turnstaticauthsecret": "",
                "udpserveraddress": "",
                "udpserverport": 8443
            },
            "playbooks": {
                "BotUserID": "8gcoect5rjb58jukxt1qai66zh"
            }
        },
        "PluginStates": {
            "com.mattermost.apps": {
                "Enable": true
            },
            "com.mattermost.calls": {
                "Enable": true
            },
            "com.mattermost.nps": {
                "Enable": true
            },
            "focalboard": {
                "Enable": true
            },
            "playbooks": {
                "Enable": true
            }
        },
        "EnableMarketplace": true,
        "EnableRemoteMarketplace": true,
        "AutomaticPrepackagedPlugins": true,
        "RequirePluginSignature": false,
        "MarketplaceURL": "https://api.integrations.mattermost.com",
        "SignaturePublicKeyFiles": [],
        "ChimeraOAuthProxyURL": ""
    },
    "DisplaySettings": {
        "CustomURLSchemes": [],
        "ExperimentalTimezone": true
    },
    "GuestAccountsSettings": {
        "Enable": false,
        "AllowEmailAccounts": true,
        "EnforceMultifactorAuthentication": false,
        "RestrictCreationToDomains": ""
    },
    "ImageProxySettings": {
        "Enable": false,
        "ImageProxyType": "local",
        "RemoteImageProxyURL": "",
        "RemoteImageProxyOptions": ""
    },
    "CloudSettings": {
        "CWSURL": "https://customers.mattermost.com",
        "CWSAPIURL": "https://portal.internal.prod.cloud.mattermost.com"
    },
    "ImportSettings": {
        "Directory": "./import",
        "RetentionDays": 30
    },
    "ExportSettings": {
        "Directory": "./export",
        "RetentionDays": 30
    }
}

NGINX config file:

upstream backend {
  #server 10.10.10.2:8065;
  server mattermost:8065;
  keepalive 32;
}

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mattermost_cache:10m max_size=3g inactive=120m use_temp_path=off;

server {
 listen 80 default_server;
 server_name   cloud.myserver.com;
 return 301 https://$server_name$request_uri;
}

server {
  listen 443 ssl http2;
  server_name    cloud.myserver.com;

  http2_push_preload on; # Enable HTTP/2 Server Push

  

   ssl on;
   ssl_certificate /etc/nginx/certificates/cloud/cloud.myserver.com.crt;
   ssl_certificate_key /etc/nginx/certificates/cloud/private.key;
  	ssl_session_timeout 1d;

  # Enable TLS versions (TLSv1.3 is required upcoming HTTP/3 QUIC).
  ssl_protocols TLSv1.2 TLSv1.3;

  # Enable TLSv1.3's 0-RTT. Use $ssl_early_data when reverse proxying to
  # prevent replay attacks.
  #
  # @see: https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_early_data
  ssl_early_data on;

  ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384';
  ssl_prefer_server_ciphers on;
  ssl_session_cache shared:SSL:50m;
  # HSTS (ngx_http_headers_module is required) (15768000 seconds = six months)
  add_header Strict-Transport-Security max-age=15768000;
  # OCSP Stapling ---
  # fetch OCSP records from URL in ssl_certificate and cache them
  ssl_stapling on;
  ssl_stapling_verify on;

  add_header X-Early-Data $tls1_3_early_data;

  location ~ /api/v[0-9]+/(users/)?websocket$ {
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      client_max_body_size 50M;
      proxy_set_header Host $http_host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header X-Frame-Options SAMEORIGIN;
      proxy_buffers 256 16k;
      proxy_buffer_size 16k;
      client_body_timeout 60;
      send_timeout 300;
      lingering_timeout 5;
      proxy_connect_timeout 90;
      proxy_send_timeout 300;
      proxy_read_timeout 90s;
      proxy_http_version 1.1;
      proxy_pass https://mattermost:8065;
  }

  location / {
      client_max_body_size 50M;
      proxy_set_header Connection "";
      proxy_set_header Host $http_host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header X-Frame-Options SAMEORIGIN;
      proxy_buffers 256 16k;
      proxy_buffer_size 16k;
      proxy_read_timeout 600s;
      proxy_cache mattermost_cache;
      proxy_cache_revalidate on;
      proxy_cache_min_uses 2;
      proxy_cache_use_stale timeout;
      proxy_cache_lock on;
      proxy_http_version 1.1;
      proxy_pass https://mattermost:8065;
  }
}

# This block is useful for debugging TLS v1.3. Please feel free to remove this
# and use the `$ssl_early_data` variable exposed by NGINX directly should you
# wish to do so.
map $ssl_early_data $tls1_3_early_data {
 "~." $ssl_early_data;
 default "";
}

The call plugin has the default settings

We see the same behaviour: “Error: unable to connect to the voice call: timed out waiting for peer connection.”. Call plugin works on desktop, but on mobile we see the error.
It’s not the network thing I am afraid, my laptop is connected to the same Wi-Fi as my mobile.

1 Like

Hello, it seems that we have the same error but it works for me with the WIFI network on the mobile, it only fails if it is due to mobile data, another example of failure is if the mobile is acting as a router and the PC connects via WIFI to the mobile, it also fails on the PC, so it is a network problem in our case.

We have the same problem last few weeks: calls through mobile network end with the error “unable to connect to the voice call: timed out waiting for peer connection.” and calls through wired network periodically break with the same error.

No IPv6 (AAAA) record for our server, and icehostoverride is set to IPv4-address of our server.

Any solution? this error is quite strange

Same problem, for different mobile operators the same result. But when connected on the phone VPN or connected to WI-FI, there is no problem.
The problem also persists if you distribute the Internet from a phone to a laptop.

@franlucas92 The most likely problem is that the client cannot reach the MM instance on the configured UDP port (default is 8443) which may be blocked. This connection doesn’t go through the proxy (nginx) but directly to the MM instance which should have a client facing IP available. First thing to check would be to make sure to have the port exposed in the AWS security group.

I have already gotten it to work, the problem was in the Docker configuration, in the docker-compose.yml file you have to put the /udp in the ports.

ports:
- 8443:8443/udp

Thanks for the update, will review the documentation on this :+1:

I have same issue:

netstat -nlptu |grep 8443
tcp        0      0 127.0.0.1:8443          0.0.0.0:*               LISTEN      277172/docker-proxy 
tcp        0      0 192.168.122.161:8443    0.0.0.0:*               LISTEN      1127038/nginx: mast 
udp        0      0 192.168.122.161:8443    0.0.0.0:*                           1127038/nginx: mast 
udp        0      0 127.0.0.1:8443          0.0.0.0:*                           277180/docker-proxy

my nginx.conf:

stream {
    # TCP Configuration
    upstream mattermost_rtc_tcp {
        server 127.0.0.1:8443;
    }

    server {
        listen 192.168.122.161:8443;
        proxy_pass mattermost_rtc_tcp;
    }

    # UDP Configuration
    upstream mattermost_rtc_udp {
        server 127.0.0.1:8443;
    }

    server {
        listen 192.168.122.161:8443 udp;
        proxy_pass mattermost_rtc_udp;
        proxy_responses 0;
    }
}

and then

DNAT       tcp  --  0.0.0.0/0           x.x.x.x       tcp dpt:8443 to:192.168.122.161:8443
DNAT       udp  --  0.0.0.0/0          x.x.x.x       udp dpt:8443 to:192.168.122.161:8443

and

ACCEPT     tcp  --  0.0.0.0/0            192.168.122.161      tcp dpt:8443
ACCEPT     udp  --  0.0.0.0/0           192.168.122.161      udp dpt:8443

I see on tcpdump traffic passes firewall and reaches to .161 internal vm but get same error:

Error: Unable to connect to the voice call: timed out waiting for peer connection

Logs:

{
  "timestamp": "2024-08-02 22:07:00.608 +01:00",
  "level": "warn",
  "msg": "undeclaredMediaProcessor failed to open SrtcpSession: the DTLS transport has not started yet",
  "caller": "app/plugin_api.go:1014",
  "plugin_id": "com.mattermost.calls",
  "origin": "webrtc/v3.(*PeerConnection).undeclaredRTCPMediaProcessor github.com/pion/webrtc/v3@v3.2.40/peerconnection.go:1696"
}

{
  "timestamp": "2024-08-02 22:07:00.602 +01:00",
  "level": "info",
  "msg": "Failed to dial TCP address 192.168.50.227:50056: dial tcp 172.18.0.4:41231->192.168.50.227:50056: run was canceled by done",
  "caller": "app/plugin_api.go:1008",
  "plugin_id": "com.mattermost.calls",
  "origin": "ice/v2.newActiveTCPConn.func1 github.com/pion/ice/v2@v2.3.24/active_tcp.go:47"
}
{

it sees internal IP addresses of my mobile phone and docker image…