WebRTC: tiempo y ciclo del pool ICE
Distingue la precaptura ICE, la entrega de candidatos y el reinicio; un evento ausente no demuestra que antes no hubiera actividad de red.
BotBrowser Team
Quieres la documentación estructurada de Huella digital?
Este artículo forma parte de la biblioteca editorial. Para pasos de configuración, material de referencia y actualizaciones continuas, entra en la sección de docs.
El pool de candidatos ICE cambia cuándo puede realizarse cierto trabajo; no convierte la recopilación, los eventos de página, la descripción local y un reinicio posterior en una sola observación. Un registro silencioso no demuestra actividad previa del servidor. BotBrowser documenta las políticas de direcciones WebRTC, pero no garantiza un control del tamaño del pool ni la reversión de actividad de red anterior.
Resumen
- Un
iceCandidatePoolSizedistinto de cero solicita pre-recogida; no demuestra que el pool esté listo. setLocalDescription()es una fase de entrega de candidatos, no la hora de la primera actividad de red.- El pool inicial sirve para el primer intercambio;
restartIce()solicita otra negociación y no revierte actividad anterior.
Ver el vídeo
Este vídeo en inglés sigue la misma pregunta del artículo: una traza WebRTC contiene varios relojes, así que el tamaño de pool configurado, un evento de candidato en la página, una descripción local y un registro del servidor no pueden sustituirse por un único instante llamado "ICE iniciado". Muestra un fixture local controlado en Ubuntu Chrome: se crea una peer connection con un tamaño de pool distinto de cero y un cambio posterior devuelve InvalidModificationError; una segunda sonda cuenta eventos de candidato dentro de una ventana declarada y lee el estado de recogida. El conteo sigue siendo una observación de la página, no un registro del servidor; el vídeo no afirma haber medido ningún sitio real ni que BotBrowser controle el tamaño del pool. El audio es en inglés.
Contenido
- Ver el vídeo
- Por qué el tiempo cambia la pregunta de privacidad
- El pool tiene un ciclo de vida acotado
- Separa las capas de observación
- Diagnostica una cronología incompleta
- Límite de la política de BotBrowser
- Conclusión práctica
BotBrowser puede aplicar políticas de direcciones WebRTC documentadas en sesiones controladas, pero la documentación pública no promete un control del tamaño del pool ni la reversión de actividad anterior. La guía de prevención de fugas WebRTC explica los tipos de candidatos y las políticas de ruta; la guía de candidatos mDNS explica cómo se representa el candidato host. La cuestión más acotada aquí es cuándo puede observarse cada fase ICE.
Por qué el tiempo cambia la pregunta de privacidad
Una traza WebRTC puede incluir varios relojes: creación de la conexión, precaptura opcional de candidatos, llamada a una descripción local, eventos de candidatos entregados a la página, intercambio offer/answer y un reinicio posterior. Tratar todo como un instante llamado «inicio de ICE» oculta diferencias útiles al interpretar un informe de privacidad. La recomendación WebRTC define iceCandidatePoolSize como el tamaño del pool precargado y establece cero como valor predeterminado. Un valor distinto de cero solicita un pool; no es un registro temporal de lo que recibió la página.
| Límite de API | Registrar | No inferir |
|---|---|---|
RTCPeerConnection(configuration) | Valor solicitado de iceCandidatePoolSize e inicio de captura | Que terminó la pre-recogida |
setLocalDescription() | Hora de llamada y eventos entregados | Que la red empezó en esa llamada |
restartIce() | Solicitud y negociación siguiente | Que se restauró el pool inicial |
La diferencia importa porque un evento de página describe un punto de entrega visible para la aplicación. No marca todas las operaciones DNS, STUN o TURN que pudieron ocurrir antes. También importa el caso inverso: si el registro de la aplicación no contiene un evento de candidato, esa ausencia por sí sola no demuestra que no hubiera recopilación ni actividad frente a servidores. La captura puede haber empezado tarde, la aplicación puede haber filtrado su propio registro o la observación puede proceder de otra capa. Son motivos para delimitar la evidencia, no para inventar un evento ausente.
En una revisión autorizada de compatibilidad o privacidad, mantén separadas cuatro observaciones:
- El tamaño del pool configurado y el momento en que se capturó esa configuración.
- La actividad de red observada mediante un registro independiente y autorizado del servidor, si existe.
- Los eventos de candidatos entregados a la aplicación, con el intervalo de captura indicado.
- La descripción local y la fase offer/answer registradas por la aplicación.
Estos registros responden preguntas diferentes. Un ajuste indica qué solicitó la aplicación. Un evento de página indica qué se entregó al script. Una descripción local indica qué proporcionó la aplicación al API de negociación. Un registro de servidor indica qué observó ese servidor en particular. Ninguno prueba por sí solo que una política de direcciones precediera a toda acción de red pertinente. Antes de comparar dos marcas temporales, identifica el reloj y el punto de observación de cada fuente.
El pool tampoco es un recuento de candidatos visible para la página. El tamaño configurado no demuestra que la implementación terminara de recopilar ese número de candidatos utilizables antes de otra llamada. RFC 9429 contempla expresamente que el pool se agote porque se necesiten más componentes ICE o porque la recopilación no haya tenido tiempo suficiente. En ese caso, los candidatos restantes se recopilan normalmente. Por tanto, el valor configurado, el número de eventos de página y el contenido de una descripción local no son mediciones intercambiables.
Esta separación evita dos afirmaciones excesivas. «No se registró ningún evento de candidato antes de la descripción local» habla de un registro concreto y de su cobertura. «No hubo actividad de red antes de la descripción local» es una afirmación más amplia que requiere evidencia del punto de observación de red pertinente. Del mismo modo, un valor distinto de cero permite precapturar candidatos; no prueba por sí solo que se contactara con un servidor concreto en un momento determinado. Registra lo que muestra cada fuente y deja el resto como desconocido.
El pool tiene un ciclo de vida acotado
El pool cumple una función definida en la negociación; no es una caché que se reutilice en todos los intercambios posteriores. La sección 3.5.4 de RFC 9429 describe la secuencia: cuando setLocalDescription inicia la recopilación necesaria para el primer intercambio offer/answer, la implementación debería comprobar primero si ya hay candidatos disponibles en el pool. Los candidatos disponibles deberían entregarse a la aplicación mediante eventos de candidatos. Si el pool se agota porque el intercambio requiere más componentes o no ha tenido tiempo suficiente para recopilar, los restantes se recopilan de forma normal. RFC 9429 indica que este comportamiento del pool corresponde al primer intercambio offer/answer; después el pool se vacía y deja de utilizarse.
La RFC usa «SHOULD» para la entrega de candidatos disponibles. Conserva esa modalidad: es una recomendación normativa, no una prueba de que un pool concreto terminara antes de una hora determinada. La misma sección explica que mantener candidatos precargados puede consumir recursos en los servidores STUN o TURN configurados. Es una consecuencia de recursos descrita por la RFC, no un volumen de tráfico medido ni una promesa sobre la duración de retención en una compilación específica del navegador.
El momento de configuración también está limitado. El algoritmo WebRTC para establecer la configuración rechaza cambiar iceCandidatePoolSize una vez que ya se llamó a setLocalDescription. El método informa InvalidModificationError para ese cambio restringido, pero el nombre de la excepción no diagnostica la causa: otros cambios de configuración pueden producirla. Un registro útil del incidente necesita las configuraciones anterior y solicitada, el orden de llamadas y el contexto de la excepción. Sin esos datos, atribuirla al tamaño del pool es una conjetura.
| Fase | Interpretación del pool | Evidencia visible para la aplicación | Lo que el registro no puede establecer |
|---|---|---|---|
| Creación con tamaño 0 | Este ajuste no solicitó precaptura | Instantánea de configuración inicial | Que no habrá recopilación posterior |
| Creación con tamaño distinto de cero | Se permite precapturar mientras se preparan candidatos | Tamaño solicitado; observación separada del servidor si existe | Que el pool se llenara o ya se emitiera un evento de página |
| Antes de la descripción local | El tamaño puede elegirse o cambiarse dentro de las reglas del API | Instantáneas de configuración y orden de llamadas | Que el pool solicitado esté listo |
| Recopilación de la primera descripción local | Se deberían entregar los candidatos disponibles; el resto se recopila normalmente | Eventos y ciclo de la descripción local | La cronología completa de red anterior solo con eventos de página |
| Después del primer intercambio | El pool inicial está vacío y deja de utilizarse | Historial de negociación | Que un reinicio posterior recree el pool precargado |
| Reinicio ICE posterior | Se solicita una nueva generación ICE mediante negociación | Llamada de reinicio y señalización posterior | Que la actividad previa se haya borrado |
La matriz sirve para interpretar registros de una aplicación propia; no es una receta de detección. Captura etiquetas de fase y orden aproximado en lugar de contenido de candidatos. Distingue entre una configuración solicitada y una operación completada. Si no existe observación de red independiente, indícalo; no conviertas la secuencia de eventos de página en un sustituto de la actividad del servidor.
Un reinicio ICE es una acción posterior de negociación, no un botón para volver atrás. restartIce() solicita un reinicio para una negociación posterior. No elimina retroactivamente un evento previo, no borra un registro de servidor ni restaura el pool inicial después de que el primer intercambio offer/answer lo haya consumido. Si un informe abarca más de una generación, etiqueta la fase de cada registro. De lo contrario, un candidato observado después del reinicio podría asociarse incorrectamente a evidencia del intercambio inicial.
Separa las capas de observación
Un conjunto de evidencias debe indicar qué capa produjo cada observación y qué intervalo temporal cubre. Una instantánea de configuración registra los valores solicitados por la aplicación. Un evento de página registra la entrega al script. Una descripción local registra lo que la aplicación proporcionó en el límite de esa API. Un registro de servidor, cuando el propietario del sistema está autorizado a consultarlo, registra lo que observó ese servidor. Los relojes pueden diferir, la retención puede diferir y la cobertura puede empezar en momentos distintos. Una comparación que omite estos datos puede parecer más concluyente que los registros originales.
| Observación | Permite afirmar | No permite afirmar por sí sola |
|---|---|---|
iceCandidatePoolSize: 0 antes de negociar | Ese ajuste no solicitó precaptura | Que nunca puedan recopilarse candidatos |
| Pool configurado distinto de cero | Se solicitó precaptura | Que la recopilación terminara o el pool siguiera disponible |
| Marca temporal de un evento de candidato | La página recibió ese evento a la hora registrada | Que entonces ocurriera la primera actividad de red |
Llamada a setLocalDescription | La aplicación entró en la fase de descripción local | Que ya se hubieran recopilado todos los candidatos |
Llamada a restartIce() | La aplicación solicitó el reinicio para una negociación posterior | Que se restaurara el pool inicial o se borrara el historial |
| Evento ausente en una traza parcial | La traza no contiene ese evento | Que no hubiera actividad fuera del intervalo capturado |
Un registro práctico conserva la hora inicial de captura, los marcadores ordenados de las fases API, la versión del navegador y si el registro está completo. El objetivo es interpretar diagnósticos autorizados, no recoger más datos de los necesarios. Las cadenas de candidatos, direcciones, bytes SDP, credenciales de servidor e identificadores por usuario no son necesarios para las distinciones del ciclo de vida descritas aquí. Si otro incidente autorizado requiere datos sensibles, gestiónalos conforme a la política de acceso y retención de ese sistema en vez de copiarlos a un informe general.
Evita asociar la hora de un evento de página con una hora supuesta de petición STUN cuando no hay observación de red independiente. Esa asociación podría servir como hipótesis de investigación, pero no es un hecho observado. La misma cautela se aplica a una exportación que elimina campos: un campo ausente puede significar que el exportador lo omitió, no que el navegador nunca lo produjera. Conserva la procedencia de cada registro: capa de origen, intervalo de captura, pasos de transformación y punto en que se retuvo.
Para comparar de forma repetible, usa las mismas definiciones de observación en ambas ejecuciones. Si una registra llamadas API desde la creación de la conexión y otra empieza al primer callback de candidato, las cronologías aparentes no están alineadas. Antes de comparar, crea una tabla pequeña con la definición del evento, la fuente del reloj, el límite inicial y la regla para datos ausentes. Es un método de revisión para sistemas de prueba propios; no requiere exponer valores de candidatos ni sondear endpoints de terceros.
Diagnostica una cronología incompleta
Cuando un informe describe una dirección como «tardía», define primero qué significa. Puede ser el primer evento de candidato visto por el código de página, el primer candidato representado en la descripción local, el primer evento retenido por una exportación o la primera observación en un registro de servidor autorizado. Esas marcas no son intercambiables. Comprueba primero si la captura comenzó antes de construir la conexión y si se registró la configuración inicial. Después comprueba si la aplicación ya había llamado a setLocalDescription cuando intentó cambiar el tamaño del pool.
| Síntoma | Comprobar primero | Evitar concluir |
|---|---|---|
| No hay evento antes de la descripción local | Si se solicitó recopilación y la captura cubre actividad previa | Que no hubiera precaptura ni contacto con servidores |
| Menos eventos de los esperados después de la descripción | Si el pool tuvo capacidad o preparación suficientes; puede continuar la recopilación normal | Que la conexión falló únicamente porque el pool era pequeño |
InvalidModificationError durante la configuración | Qué campo cambió y si ya se había llamado a setLocalDescription | Que necesariamente se rechazara el tamaño del pool |
Eventos después de restartIce() | Llamada de reinicio, orden de renegociación y cobertura | Que desapareciera la generación anterior o su actividad |
| Discrepan los registros de servidor y página | Reloj, límites de captura, filtrado y punto de observación | Que un registro describa la otra capa |
Esta secuencia mantiene el diagnóstico ligado a la evidencia. Empieza por el orden de llamadas y la cobertura de captura. Compara el valor solicitado con el valor realmente registrado antes de la descripción local. Separa las excepciones de configuración de la entrega de eventos. Solo después compara registros de página y servidor si ambos se recopilaron con autorización. Si falta un elemento, registra la brecha en vez de completarla con un valor predeterminado supuesto o una hora de evento inventada.
Si no se dispone de la configuración inicial o del intervalo de captura, marca la cronología como incompleta. No reconstruyas la intención original a partir de una lista final de candidatos. La lista final es un resultado retenido, no una cronología completa de cómo se obtuvo. Si la exportación carece de procedencia, indica que la historia de transformación es desconocida. Así el informe es menos absoluto, pero más útil: otro ingeniero puede ver qué dato ausente cambiaría la interpretación.
Al comparar ejecuciones, las diferencias pueden deberse a cobertura de captura, respuesta de red, orden de llamadas de la aplicación o límites de los registros del servidor, además del tamaño del pool. Registra esas condiciones junto a la comparación. No afirmes que el cambio de tamaño causó la diferencia a menos que la evidencia aísle ese cambio y la fuente aplicable respalde el mecanismo propuesto. Las normas citadas describen el API y su ciclo de vida; no aportan mediciones para una configuración de navegador que no se ejecutó.
El mismo método sirve cuando falla un cambio de configuración. Conserva las configuraciones anterior y nueva con secretos eliminados, anota si ya se llamó a la descripción local y guarda el tipo exacto de excepción y la fase. Después consulta el algoritmo para los campos modificados. InvalidModificationError indica que el cambio no se aceptó conforme a las reglas del API; sin el registro circundante no identifica qué campo causó el problema. Esta conclusión acotada evita enviar al ingeniero hacia una hipótesis de red no relacionada.
Límite de la política de BotBrowser
La documentación WebRTC de BotBrowser describe opciones de política de direcciones y su configuración para sesiones gestionadas. Es la fuente del producto para esos controles. El valor predeterminado del pool, su ciclo en el primer intercambio y el momento de procesar la descripción local proceden de la recomendación WebRTC y JSEP. La documentación pública del producto no promete un control dedicado del tamaño del pool, que todos los candidatos se precarguen ni que cambiar una política después elimine actividad previa en servidores.
En una comparación controlada, registra la política de producto elegida por separado de la evidencia de fases API y atribuye cada afirmación a su fuente. No trates una referencia de configuración como prueba desde la red. No interpretes la falta de un evento como prueba de que el host nunca contactó un servicio. La guía de prevención de fugas WebRTC sigue siendo la referencia operativa para configurar políticas de dirección; las tablas de ciclo de vida de aquí añaden una capa de interpretación del tiempo y del alcance de la evidencia. No se afirma ningún resultado para una compilación, ruta de red o despliegue que no se haya ejecutado.
Preguntas frecuentes
¿Un pool distinto de cero garantiza que los candidatos estén listos antes de negociar?
No. Solicita la pre-recogida, pero RFC 9429 contempla que el pool se agote o que falte tiempo para recopilar. Los candidatos disponibles deberían entregarse cuando empieza la recopilación; el ajuste no es un recibo de finalización.
¿Cambiar el tamaño después de la descripción local corrige una captura anterior?
No. El algoritmo set-configuration de W3C restringe ese cambio después de llamar a setLocalDescription(). Una configuración posterior no reescribe un registro previo ni una observación del servidor.
¿restartIce() restaura el pool inicial?
No. Solicita un reinicio ICE para una negociación posterior. El reinicio tiene su propia ventana de evidencia y no elimina actividad de red anterior.
Fuentes
- Recomendación WebRTC del W3C: RTCConfiguration y algoritmo de configuración
- RFC 9429, sección 3.5.4: ICE Candidate Pool
- MDN: RTCPeerConnection.setConfiguration()
- MDN: RTCPeerConnection.restartIce()
- BotBrowser: prevención de fugas WebRTC
Conclusión práctica
Mantén configuración, eventos de página y observaciones del servidor como evidencias distintas. Conserva el intervalo de captura y el orden de llamadas; si falta cualquiera, declara incompleta la cronología en lugar de inferir que no hubo actividad de red anterior.
Este artículo forma parte de la guía: ¿Qué es una fuga de IP por WebRTC? Protección y privacidad
Artículos Relacionados
¿Qué es una fuga de IP por WebRTC? Protección y privacidad
RedCandidatos mDNS de WebRTC y privacidad de la red local
RedIdentidad de red y privacidad en WebRTC
RedCoherencia de proxy, DNS y WebRTC en una identidad de navegador
Huella digitalQué hace y qué no hace la navegación privada
Huella digitalFingerprinting de codecs WebRTC: fuga de capacidades
Lleva BotBrowser de la investigación a producción
Usa estas guías para entender el modelo y después avanzar hacia validación multiplataforma, contextos aislados y despliegue de navegador preparado para escalar.