diff --git a/src/api/gramjs/apiBuilders/calls.ts b/src/api/gramjs/apiBuilders/calls.ts index 633867acc..066257c5e 100644 --- a/src/api/gramjs/apiBuilders/calls.ts +++ b/src/api/gramjs/apiBuilders/calls.ts @@ -140,7 +140,7 @@ export function buildPhoneCall(call: GramJs.TypePhoneCall): ApiPhoneCall { gAOrB: Array.from(gAOrB), keyFingerprint: keyFingerprint.toString(), startDate, - p2pAllowed, + isP2pAllowed: Boolean(p2pAllowed), connections: connections.map(buildApiCallConnection).filter(Boolean) as ApiPhoneCallConnection[], }; } diff --git a/src/api/types/calls.ts b/src/api/types/calls.ts index 5541bd540..72d33c867 100644 --- a/src/api/types/calls.ts +++ b/src/api/types/calls.ts @@ -45,6 +45,7 @@ export interface ApiPhoneCall { adminId?: string; participantId?: string; isVideo?: boolean; + isP2pAllowed?: boolean; date?: number; startDate?: number; receiveDate?: number; diff --git a/src/global/actions/apiUpdaters/calls.async.ts b/src/global/actions/apiUpdaters/calls.async.ts index b189e3721..4e447e2a7 100644 --- a/src/global/actions/apiUpdaters/calls.async.ts +++ b/src/global/actions/apiUpdaters/calls.async.ts @@ -169,7 +169,12 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => { })(); } void joinPhoneCall( - connections, actions.sendSignalingData, isOutgoing, Boolean(call?.isVideo), actions.apiUpdate, + connections, + actions.sendSignalingData, + isOutgoing, + Boolean(call?.isVideo), + Boolean(call.isP2pAllowed), + actions.apiUpdate, ); } diff --git a/src/lib/secret-sauce/p2p.ts b/src/lib/secret-sauce/p2p.ts index d809f1ef3..d05063f4f 100644 --- a/src/lib/secret-sauce/p2p.ts +++ b/src/lib/secret-sauce/p2p.ts @@ -5,8 +5,8 @@ import type { MediaContent, MediaStateMessage, P2pMessage } from './p2pMessage'; import { fromTelegramSource, IS_ECHO_CANCELLATION_SUPPORTED, - IS_NOISE_SUPPRESSION_SUPPORTED, - p2pPayloadTypeToConference, + IS_NOISE_SUPPRESSION_SUPPORTED, isRelayAddress, + p2pPayloadTypeToConference, removeRelatedAddress, } from './utils'; import buildSdp, { Conference } from './buildSdp'; import { getUserStreams, StreamType } from './secretsauce'; @@ -174,6 +174,7 @@ export async function joinPhoneCall( emitSignalingData: (data: P2pMessage) => void, isOutgoing: boolean, shouldStartVideo: boolean, + isP2p: boolean, onUpdate: (...args: any[]) => void, ) { const conn = new RTCPeerConnection({ @@ -200,10 +201,17 @@ export async function joinPhoneCall( conn.onicecandidate = (e) => { if (!e.candidate) return; + const { candidate } = e.candidate; + if(!isP2p && !isRelayAddress(candidate)) { + return; + } + + const candidateWithoutRelatedAddress = !isP2p ? removeRelatedAddress(candidate) : candidate; + emitSignalingData({ '@type': 'Candidates', candidates: [{ - sdpString: e.candidate.candidate, + sdpString: candidateWithoutRelatedAddress, }], }); }; diff --git a/src/lib/secret-sauce/utils.ts b/src/lib/secret-sauce/utils.ts index 63c73b900..b49e745fe 100644 --- a/src/lib/secret-sauce/utils.ts +++ b/src/lib/secret-sauce/utils.ts @@ -39,6 +39,27 @@ export function p2pPayloadTypeToConference(p: P2PPayloadType): PayloadType { }; } +export function isRelayAddress(candidate: string) { + const parts = candidate.split(' '); + return parts.some((part) => part === 'relay'); +} + +export function removeRelatedAddress(candidate: string) { + const parts = candidate.split(' '); + + const raddrIndex = parts.indexOf('raddr'); + if (raddrIndex !== -1) { + parts.splice(raddrIndex, 2); + } + + const rportIndex = parts.indexOf('rport'); + if (rportIndex !== -1) { + parts.splice(rportIndex, 2); + } + + return parts.join(' '); +} + export const THRESHOLD = 0.1; export const IS_SCREENSHARE_SUPPORTED = 'getDisplayMedia' in (navigator?.mediaDevices || {});