From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.ffmpeg.org (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id 61B0A4C698 for ; Wed, 10 Sep 2025 08:08:23 +0000 (UTC) Authentication-Results: ffbox; dkim=fail (body hash mismatch (got b'bUxCUEKO7EKktV6+6z3VhO7b0nbqwsBDbkzvsPPonOg=', expected b'iB4MA+aQOsJz5IL80znewWoVvcc2e18NKC5pK4L1zCE=')) header.d=ffmpeg.org header.i=@ffmpeg.org header.a=rsa-sha256 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ffmpeg.org; i=@ffmpeg.org; q=dns/txt; s=mail; t=1757491698; h=mime-version : to : date : message-id : reply-to : subject : list-id : list-archive : list-archive : list-help : list-owner : list-post : list-subscribe : list-unsubscribe : from : cc : content-type : content-transfer-encoding : from; bh=bUxCUEKO7EKktV6+6z3VhO7b0nbqwsBDbkzvsPPonOg=; b=4Bjn4ABKCKBWhDvWVYtks3tEt/SPY3x+OqognUneitL407GRWwJcYKmomvU4/3rzXT22m pKtR7erTjcsezSyBophELNGY4VrxYvJUYWJX/P8GJNF7gAMNJ2kqo771eWaeCAJpkhSRTCV /62cvW9KHiG5MrnKdp/ciZwy4do6Id4ndzxnAdE2KktpYAEXx4BJOMFkKwD4fky/4cmHEYp ey506NnkFYBBDboBxW8BbrYcJHwf0SYMAoe+TjlYUndL9jCX4Y6iOJerMDSft1cLJpP/VRl /+1pG6BMSTapU8Hd4XoSrBSH+WvW4ZWAbp+P3psmwEXXhH9KuydwSKmUDy0Q== Received: from [172.19.0.4] (unknown [172.19.0.4]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id B44EC68E752; Wed, 10 Sep 2025 11:08:18 +0300 (EEST) ARC-Seal: i=1; cv=none; a=rsa-sha256; d=ffmpeg.org; s=arc; t=1757491697; b=fMCtmxnsIOpQOfTtxFkXunnLZelk12QTx8naUZIj0tNW9AK/MuKBs+/lDUK8tB82gLEDq hMpn9hIQRcKwPRemG8ta/05or2amieAzCLSz0bGkv3IWe/sA89cv80/Lp1WoFIGQSIcRE+l x0K5b6FPXOjIRPtppWwQengIzT4f5AMzAXi1doLG78XAy0yjXgAsRLSArpe58SAQ0jfXjS2 J/B2/s2CrZSf84K9ctQZFQDPVR0N1UIbHbWIiqLaso26Zx/iA+6IFHQkbU4K1bGEa8FmCAM 7ax3TDVvm9hwOU+chypqtaky+Jm4L3xOg+aftkislAkRlDylrTqzTWK2EDmw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=ffmpeg.org; s=arc; t=1757491697; h=from : sender : reply-to : subject : date : message-id : to : cc : mime-version : content-type : content-transfer-encoding : content-id : content-description : resent-date : resent-from : resent-sender : resent-to : resent-cc : resent-message-id : in-reply-to : references : list-id : list-help : list-unsubscribe : list-subscribe : list-post : list-owner : list-archive; bh=iE/dVUcqR4Cpk6VurM3E268FbymsAA81/a3viP1thFE=; b=SCj6fP3um2bdulhBcCQmO8l3RoJJ2wmn6Vt+fZb+kc2j13SFY0MHYmjioTKjsQU6mAvIZ tbIJM/1M5S7vTDM/GTVxy1icJgvYeWbjt9P85lR0G8o4FtaNEZBjTsPpyVWukS0nhKQqIf8 FMBa6r0leqCJVW2HZG1nguK/MqNiIZQLt44LceWNQzBN19SX3fIBQm3uqlHE4ZtSH76pQ+4 SAz0gaEGd37fX17bQmhTxUnRvdNW1YCZZ0YJjuK68pf/kHXI4gRykPcLNCIHFd4YgZ8bjhY xBPuAL8dO0A3NXxQnOaAFVrsK5vjvfpFmeu+BdmvUj2HqxRuAHag8S3gwF6Q== ARC-Authentication-Results: i=1; ffmpeg.org; dkim=pass header.d=ffmpeg.org header.i=@ffmpeg.org; arc=none; dmarc=none Authentication-Results: ffmpeg.org; dkim=pass header.d=ffmpeg.org header.i=@ffmpeg.org; arc=none (Message is not ARC signed); dmarc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ffmpeg.org; i=@ffmpeg.org; q=dns/txt; s=mail; t=1757491690; h=content-type : mime-version : content-transfer-encoding : from : to : reply-to : subject : date : from; bh=iB4MA+aQOsJz5IL80znewWoVvcc2e18NKC5pK4L1zCE=; b=q+3rwW9jRaQXKnerw1JQbPjwx0BGqqIoijipI0qBRvU6tvPGKb7Cr9Rl1ebLdsJRbydM2 kmT3lx2GYjnqYGe7+eOoQ2jTL+kshz2zWnCHlCKSYVtn66E2kh6BxxQuwaCkrOavUCw1H6s hxLMQ4BnCVeLCvRJYcHYEaxtbt272tPj8kWrROFGnLhrPa5JQibcUsKehstagBHCmHkkrXz jU5MfKZYIx3kSXbtAP3N5+Q/1+1DPjDGjBw3xvKJVhBLsqvLadtZLwc7S1cSiDPmm8mV7KQ s5U7xZxuW4dNP8sadIW1M1Eo3ecgkVriRqX4uc+XIR4WhHV1VsG5zfXrkrtA== Received: from 3f9d35a0eedc (code.ffmpeg.org [188.245.149.3]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id 3B9B068B0FB for ; Wed, 10 Sep 2025 11:08:10 +0300 (EEST) MIME-Version: 1.0 To: ffmpeg-devel@ffmpeg.org Date: Wed, 10 Sep 2025 08:08:09 -0000 Message-ID: <175749169039.25.1792615083287656948@463a07221176> Message-ID-Hash: GNWH6RHMLVUITZPCNRCIHHTQEH5ESEK6 X-Message-ID-Hash: GNWH6RHMLVUITZPCNRCIHHTQEH5ESEK6 X-MailFrom: code@ffmpeg.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-ffmpeg-devel.ffmpeg.org-0; header-match-ffmpeg-devel.ffmpeg.org-1; header-match-ffmpeg-devel.ffmpeg.org-2; header-match-ffmpeg-devel.ffmpeg.org-3; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list Reply-To: FFmpeg development discussions and patches Subject: [FFmpeg-devel] [PATCH] avformat/whip: add ICE consent freshness support (PR #20482) List-Id: FFmpeg development discussions and patches Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Jack Lau via ffmpeg-devel Cc: Jack Lau Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Archived-At: List-Archive: List-Post: PR #20482 opened by Jack Lau (JackLau) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20482 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20482.patch Refer to RFC 9725 4.2, "Once a session is set up, consent freshness as per [RFC7675] SHALL be used to detect non-graceful disconnection by full ICE implementations and DTLS teardown for session termination by either side" Refer to RFC 7675, send STUN Binding request every 5s, expire consent after 30s without response, terminate session when the consent expired. TODO: Random consent check interval (4-6s) will be added later. Co-authored-by: Sergio Garcia Murillo Signed-off-by: Jack Lau >>From 456f08ce82d1a1af3e03d9296f48e9b88a133a57 Mon Sep 17 00:00:00 2001 From: Jack Lau Date: Wed, 10 Sep 2025 15:53:25 +0800 Subject: [PATCH 1/2] avformat/whip: add WHIP_US_PER_MS macro to replace 1000 Signed-off-by: Jack Lau --- libavformat/whip.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavformat/whip.c b/libavformat/whip.c index 20db03a239..ef5890fc7d 100644 --- a/libavformat/whip.c +++ b/libavformat/whip.c @@ -66,6 +66,8 @@ */ #define DTLS_SRTP_CHECKSUM_LEN 16 +#define WHIP_US_PER_MS 1000 + /** * When sending ICE or DTLS messages, responses are received via UDP. However, the peer * may not be ready and return EAGAIN, in which case we should wait for a short duration @@ -1251,7 +1253,7 @@ next_packet: break; now = av_gettime_relative(); - if (now - starttime >= whip->handshake_timeout * 1000) { + if (now - starttime >= whip->handshake_timeout * WHIP_US_PER_MS) { av_log(whip, AV_LOG_ERROR, "DTLS handshake timeout=%dms, cost=%.2fms, elapsed=%.2fms, state=%d\n", whip->handshake_timeout, ELAPSED(starttime, now), ELAPSED(whip->whip_starttime, now), whip->state); ret = AVERROR(ETIMEDOUT); @@ -1264,7 +1266,7 @@ next_packet: if (ret > 0) break; if (ret == AVERROR(EAGAIN)) { - av_usleep(5 * 1000); + av_usleep(5 * WHIP_US_PER_MS); continue; } av_log(whip, AV_LOG_ERROR, "Failed to read message\n"); -- 2.49.1 >>From f84805f59cb1d515a8492d64b5c15c02bc39263b Mon Sep 17 00:00:00 2001 From: Jack Lau Date: Wed, 10 Sep 2025 15:26:22 +0800 Subject: [PATCH 2/2] avformat/whip: add ICE consent freshness support Refer to RFC 9725 4.2, "Once a session is set up, consent freshness as per [RFC7675] SHALL be used to detect non-graceful disconnection by full ICE implementations and DTLS teardown for session termination by either side" Refer to RFC 7675, send STUN Binding request every 5s, expire consent after 30s without response, terminate session when the consent expired. TODO: Random consent check interval (4-6s) will be added later. Co-authored-by: Sergio Garcia Murillo Signed-off-by: Jack Lau --- libavformat/whip.c | 49 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/libavformat/whip.c b/libavformat/whip.c index ef5890fc7d..e10c3cacd1 100644 --- a/libavformat/whip.c +++ b/libavformat/whip.c @@ -159,6 +159,17 @@ #define WHIP_SDP_SESSION_ID "4489045141692799359" #define WHIP_SDP_CREATOR_IP "127.0.0.1" +/** + * Refer to RFC 7675 5.1, + * + * To prevent expiry of consent, a STUN binding request can be sent periodically. + * Implementations SHOULD set a default interval of 5 seconds(5000ms). + * + * Consent expires after 30 seconds(30000ms). + */ +#define WHIP_ICE_CONSENT_CHECK_INTERVAL 5000 +#define WHIP_ICE_CONSENT_EXPIRED_TIMER 30000 + /* Calculate the elapsed time from starttime to endtime in milliseconds. */ #define ELAPSED(starttime, endtime) ((float)(endtime - starttime) / 1000) @@ -269,6 +280,8 @@ typedef struct WHIPContext { int64_t whip_ice_time; int64_t whip_dtls_time; int64_t whip_srtp_time; + int64_t whip_last_consent_tx_time; + int64_t whip_last_consent_rx_time; /* The certificate and private key content used for DTLS handshake */ char cert_buf[MAX_CERTIFICATE_SIZE]; @@ -1320,6 +1333,8 @@ next_packet: /* If got any DTLS messages, handle it. */ if (is_dtls_packet(whip->buf, ret) && whip->state >= WHIP_STATE_ICE_CONNECTED || whip->state == WHIP_STATE_DTLS_CONNECTING) { + /* Start consent timer when ICE selected */ + whip->whip_last_consent_tx_time = whip->whip_last_consent_rx_time = av_gettime_relative(); whip->state = WHIP_STATE_DTLS_CONNECTING; ret = ffurl_handshake(whip->dtls_uc); if (ret < 0) { @@ -1787,8 +1802,26 @@ static int whip_write_packet(AVFormatContext *s, AVPacket *pkt) WHIPContext *whip = s->priv_data; AVStream *st = s->streams[pkt->stream_index]; AVFormatContext *rtp_ctx = st->priv_data; - - /* TODO: Send binding request every 1s as WebRTC heartbeat. */ + int64_t now = av_gettime_relative(); + /** + * Refer to RFC 7675 + * Periodically send Consent Freshness STUN Binding Request + */ + if (now - whip->whip_last_consent_tx_time > WHIP_ICE_CONSENT_CHECK_INTERVAL * WHIP_US_PER_MS) { + int size; + ret = ice_create_request(s, whip->buf, sizeof(whip->buf), &size); + if (ret < 0) { + av_log(whip, AV_LOG_ERROR, "Failed to create STUN binding request, size=%d\n", size); + goto end; + } + ret = ffurl_write(whip->udp, whip->buf, size); + if (ret < 0) { + av_log(whip, AV_LOG_ERROR, "Failed to send STUN binding request, size=%d\n", size); + goto end; + } + whip->whip_last_consent_tx_time = now; + av_log(whip, AV_LOG_DEBUG, "Consent Freshness check sent\n"); + } /** * Receive packets from the server such as ICE binding requests, DTLS messages, @@ -1805,6 +1838,10 @@ static int whip_write_packet(AVFormatContext *s, AVPacket *pkt) av_log(whip, AV_LOG_ERROR, "Receive EOF from UDP socket\n"); goto end; } + if (ice_is_binding_response(whip->buf, ret)) { + whip->whip_last_consent_rx_time = av_gettime_relative(); + av_log(whip, AV_LOG_DEBUG, "Consent Freshness check received\n"); + } if (is_dtls_packet(whip->buf, ret)) { if ((ret = ffurl_write(whip->dtls_uc, whip->buf, ret)) < 0) { av_log(whip, AV_LOG_ERROR, "Failed to handle DTLS message\n"); @@ -1812,6 +1849,14 @@ static int whip_write_packet(AVFormatContext *s, AVPacket *pkt) } } write_packet: + now = av_gettime_relative(); + if (now - whip->whip_last_consent_rx_time > WHIP_ICE_CONSENT_EXPIRED_TIMER * WHIP_US_PER_MS) { + av_log(whip, AV_LOG_ERROR, + "Consent Freshness expired after %.2fms (limted %dms), terminate session\n", + ELAPSED(now, whip->whip_last_consent_rx_time), WHIP_ICE_CONSENT_EXPIRED_TIMER); + ret = AVERROR(ETIMEDOUT); + goto end; + } if (whip->h264_annexb_insert_sps_pps && st->codecpar->codec_id == AV_CODEC_ID_H264) { if ((ret = h264_annexb_insert_sps_pps(s, pkt)) < 0) { av_log(whip, AV_LOG_ERROR, "Failed to insert SPS/PPS before IDR\n"); -- 2.49.1 _______________________________________________ ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org