The branch, master has been updated
via 469aad38977e47574f019c8d69715dc7be74f92d (commit)
via aba84db96fb440403c162177d82e3f259db7432a (commit)
from aa91ae25b88e195e6af4248e0ab30605735ca1cd (commit)
- Log -----------------------------------------------------------------
commit 469aad38977e47574f019c8d69715dc7be74f92d
Author: Jack Lau <[email protected]>
AuthorDate: Wed Sep 10 15:26:22 2025 +0800
Commit: stevenliu <[email protected]>
CommitDate: Thu Oct 9 09:29:25 2025 +0000
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 <[email protected]>
Signed-off-by: Jack Lau <[email protected]>
diff --git a/libavformat/whip.c b/libavformat/whip.c
index b8350ff98c..dff2502afd 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -161,6 +161,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)
@@ -273,6 +284,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];
@@ -1338,6 +1351,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) {
@@ -1848,8 +1863,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,
@@ -1866,6 +1899,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");
@@ -1886,6 +1923,14 @@ static int whip_write_packet(AVFormatContext *s,
AVPacket *pkt)
handle_nack_rtx(s, ret);
}
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 (limited %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");
commit aba84db96fb440403c162177d82e3f259db7432a
Author: Jack Lau <[email protected]>
AuthorDate: Wed Sep 10 15:53:25 2025 +0800
Commit: stevenliu <[email protected]>
CommitDate: Thu Oct 9 09:29:25 2025 +0000
avformat/whip: add WHIP_US_PER_MS macro to replace 1000
Signed-off-by: Jack Lau <[email protected]>
diff --git a/libavformat/whip.c b/libavformat/whip.c
index 472c6dbf16..b8350ff98c 100644
--- a/libavformat/whip.c
+++ b/libavformat/whip.c
@@ -67,6 +67,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
@@ -1269,7 +1271,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);
@@ -1282,7 +1284,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");
-----------------------------------------------------------------------
Summary of changes:
libavformat/whip.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 51 insertions(+), 4 deletions(-)
hooks/post-receive
--
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]