Releases: diad87/eMule-eSE-LiveTV
Release list
eMule eSE 9.1.0
eMule eSE 9.1.0
eSE 9.1.0 is the final Windows x64 release of the v9.1 line. It promotes the
RC.3 direct-link fix together with the accepted post-RC3 IPv6, Kad6, LiveTV
and stability changes.
Qualification status
The cumulative v9.1 campaign records 22 PASS, 0 FAIL and 5 BLOCKED across
27 cases. The remaining cases are:
V91-I03: public dual-stack route selection.V91-I04: silent native-IPv6 DROP and bounded IPv4 fallback.V91-I07: native public mobile-IPv6 LiveTV after mobility qualification.V91-D01: controlled public A+AAAA DNS fallback.V91-R01: LAN-to-mobile-hotspot address change and reconnection.
The required end-to-end physical conditions for these five cases could not be
completed in the final campaign. In R01, the router was reached but returned
UPnP error 501 before the simultaneous-mapping and inbound-probe sequence.
They are unverified coverage, not recorded product failures. Under the strict
matrix definition the gate therefore remains NO_GO; this release is an
explicit maintainer publication with those gaps disclosed.
The 22 accepted results span the immutable RC.3 package and hash-pinned
post-RC3 candidates. They were not all rerun against one final binary. The
published package is produced only after passing the clean build,
unit/integration, manifest and package-smoke pipeline. The detailed provenance boundary is
recorded in the cumulative campaign report.
Highlights
- Native IPv6 transport between capable eSE peers without reducing addresses
to synthetic IPv4 identities. - Independently selectable Kad2 and Kad6 planes with separate routing state.
- Direct IPv6 LiveTV joins, IPv6-aware SOCKS5 and HTTP CONNECT, and an
offline-qualified bounded IPv6-to-IPv4 fallback. The physical silent-DROP
path remains the blockedV91-I04case described above. - Direct HighID sources supplied by an eD2K link remain usable when eD2K
server and Kad discovery are intentionally disconnected. - IPv6 queue and credit accounting groups endpoints by
/64while preserving
compatibility with classic IPv4 peers. - Kad6 source publication, signed contact persistence and authenticated
anti-amplification handling. - Improved simultaneous broadcasting/viewing isolation, bounded queues and
large-transfer handling. - Safe shared-file intake and the frozen eMule AI 1.5.2 comparison gates.
Safe defaults and scope
- Dashboard, native API and received-HLS routes remain loopback-only.
- Port 8080 is never mapped automatically through UPnP.
- NetLab contribution, Punch3, port prediction, relay contribution, KRP and
Kad6 Beta Exit remain separately consent-gated and OFF by default. - No remote dashboard or remote launcher is shipped in v9.1.
- Automatic updating remains disabled; no updater executable is included.
- eSE 9.1 does not claim universal High ID, universal CGNAT traversal, strong
anonymity or compatibility with every ISP/router IPv6 deployment.
Install or update
- Stop eMule completely.
- Back up
%APPDATA%\eMule,%APPDATA%\eSE, or the portableconfig
directory, plus any configured temporary directory containing.partand
.part.metfiles. - Verify the SHA-256 file published with the ZIP.
- Extract 9.1.0 into a new empty directory. Do not merge executable or web
assets from an older build. - Start
emule.exe, connect to eD2K/Kad as desired and open the eSE dashboard
from the toolbar.
Rollback
Stop 9.1.0 and restore the previous application directory together with its
matching profile/download snapshot. Never run two versions concurrently over
the same profile or partial downloads.
Platform
- Windows 10 or 11 x64.
- Portable ZIP; no installer and no automatic updater.
- GPL-2.0-only.
eMule eSE 9.1.0-beta.1
eMule eSE 9.1.0-beta.1
Status: beta pública de laboratorio para Windows x64.
Esta es la primera beta de la serie 9.1. Promociona el transporte IPv6 y el
cliente Kad6 a una superficie utilizable entre peers eSE, pero no es todavía
el RC ni afirma compatibilidad con todos los ISP, routers, proxies o escenarios
IPv6-only.
Cambios principales
IPv6 y Kad6
- Kad2 y Kad6 siguen seleccionados por defecto en perfiles nuevos
(KadNetworkMask=3), con estado y persistencia separados. - Listener dual-stack con fallback IPv4 y respeto del
BindAddrIPv4
configurado: IPv6 no amplía silenciosamente la escucha a otras interfaces. - Fuentes, conexiones directas y listas de peers LiveTV conservan los 128 bits
de la dirección. - El direct-join LiveTV acepta un endpoint nativo
[IPv6]:puerto, permitiendo
aislar y medir el plano de vídeo sin un bootstrap ni fallback IPv4. OP_LIVE_PEER_LIST_V2implementa el campoScoredefinido por el wire y
mantiene lectura compatible con el borrador emitido por beta.2.OP_CALLBACK_V6exige negociación, longitud exacta y un endpoint previamente
conocido; un buddy no puede provocar una conexión a un destino arbitrario.- SOCKS5 y HTTP CONNECT admiten destinos IPv6; SOCKS4/4A los rechazan
explícitamente. - Las respuestas SOCKS5 de longitud variable usan bytes sin signo y un BIND
no compatible se rechaza sin reinterpretar memoria como IPv4. - Una dirección IPv4 de bind explícita conserva el comportamiento IPv4 puro.
Equidad, identidad y antiabuso
- Un peer IPv6 nuevo ya no recibe antigüedad artificial en la cola de subida.
- Los peers IPv6-only usan espera local neutral y no reciben multiplicador de
créditos IPv4. - Bans, historial de hashes y peticiones incorrectas usan la dirección nativa,
nunca eluint32sintético. - El límite anti-Sybil de la cola se aplica por
/64en IPv6. - Se restauró la política de eMule 0.70b para archivos de la cola de descarga:
solo un archivo completo de una parte puede responder como fuente.
Laboratorio con consentimiento explícito
El primer arranque ofrece tres decisiones independientes:
- Base: mediciones limitadas de IPv6, LowID, Punch2 y CGNAT con otros
participantes de la beta. - Avanzado: Punch3, predicción acotada de puertos, selector de ruta,
funciones avanzadas de Kad6, túneles autenticados, Bulk y FEC. El cliente
Kad6 nativo conserva su selección de red independiente. - Contribución: relay Live y Kad6 Beta Exit; KRP solo si el paquete dispone
además de endpoint, CA y token válidos.
Rechazar o no contestar deja cada nivel apagado. El apagado general persiste y
detiene todos los niveles. Kad6 Beta Exit no sustituye el gate firmado de una
salida pública estable.
El paquete se entrega con estos valores cerrados:
[eSE]
EseNetLabConsent=0
EseNetLabAdvancedConsent=0
EseNetLabContributionConsent=0
EseNetLabEnabled=0
EseV9Experimental=0
EseKad3Rendezvous=0
EseAutoKeepalive=0
EseRelayAccept=0
EseRelayEgress=0
EseReachSelector=0
EseHolePunchPortPredict=0
EseEd2kPunch3=0
Kad6PublicExitOptIn=0
Kad6BetaExitOptIn=0
[KRPRelay]
KrpRelayEnabled=0
KrpRelayKillSwitch=1
ExperimentalTcpDataPlane=0No se sube telemetría automáticamente. El informe NetLab permanece local y
está saneado.
Relay y reconexión
- La cola de envío Live se limita por peer: un receptor lento pierde chunks
recuperables en vez de hacer crecer la RAM sin límite. - El throttle de ratio libera el paquete rechazado y evita una fuga por cada
petición descartada. - El asignador del edge reclama una lease cuyo tiempo de reutilización ya
venció aunque una reconexión llegue antes del siguienteTick. - Se conserva el retardo de reutilización y la defensa anti-replay.
- KRP puede aplicar un apagado o una configuración local aceptada sin requerir
reiniciar eMule; una configuración incompleta falla cerrada.
Evidencia disponible antes de esta beta
- Suite standalone eMule: PASS, incluidas 21.659 comprobaciones FEC.
- Relay edge: PASS, 30.145 comprobaciones con TLS/WSS real en loopback.
- Build Windows x64 y enlace completo: PASS.
- Archivo de 12.000.000.000 bytes: corte abrupto, recodificación, reanudación
desde el 88 % y SHA-256 final idéntico. - Soak local: Kad conectado sin muestras de desconexión durante más de 14 h;
LiveTV creció de 47 a 28.648 chunks durante más de 12,7 h, con cero chunks
perdidos observados. - LiveTV sobre plano de datos IPv6 estricto: PASS durante 2 h a 12 Mbps entre
dos instancias Windows aisladas en el mismo host, con 468 muestras válidas,
playlist y segmentos MPEG-TS correctos, búfer sin huecos y cero fallback
IPv4. La comprobación final confirmó una conexión TCP IPv6 global directa.
Esta evidencia valida el plano de datos, pero no sustituye el caso normativo
T5entre dos equipos físicos. - Consentimiento rechazado/aceptado, seguridad web local y kill switch:
validados. - Camino directo beta.2 -> eSE 8.1: validado.
La prueba física de tres nodos, el cambio LAN -> tethering y las matrices
IPv6-only que requieren el portátil se publicarán como evidencia adicional.
No se contabilizan como PASS mientras el equipo no esté disponible. Un overlay
como Tailscale se etiqueta como overlay y no como prueba de ruta IPv6 pública.
Límites conocidos
- No garantiza High ID ni atravesar cualquier CGNAT.
- No ofrece salida Kad6 estable ni infraestructura KRP pública por defecto.
- La identidad eSE ligada a clave pública para créditos IPv6 queda para una
beta posterior; esta beta usa la política neutral, sin atribuir créditos
IPv4 a un endpoint IPv6-only. - La resolución A/AAAA conserva ambas familias, pero la migración completa del
getaddrinfo(AF_UNSPEC)a un worker no bloqueante sigue pendiente. - No hay cliente Android y no es necesario instalar nada en Android.
Actualización y rollback
- Copiar el directorio
configcompleto y todos los.met. - Probar primero con una copia del perfil.
- No abrir el mismo perfil con dos procesos.
- Mantener
emule.exeyese-server.exedel mismo paquete. - Para volver atrás: desactivar NetLab, cerrar eMule y restaurar la copia del
perfil anterior.
eMule eSE 9.0.0-beta.1 — beta pública de laboratorio de red
eMule eSE 9.0.0-beta.1
Beta pública para probar Live TV P2P y las nuevas rutas de conectividad en redes reales. No sustituye a la versión estable eSE 8.1.0.
En el primer inicio, eSE solicita consentimiento antes de participar en NetLab. Rechazarlo no impide usar eMule ni Live TV. Relay, donación de ancho de banda, KRP y Kad6 public exit requieren controles independientes y permanecen desactivados de forma predeterminada.
Incluye
- emisión HLS desde OBS/RTMP, pantalla, archivo o patrón de prueba;
- distribución y descubrimiento P2P mediante eD2K, Kad, PEX y LAN;
- reproductor y panel web local incluidos en el paquete portable;
- selección comprobada de NVENC, Intel QSV o AMD AMF, con alternativa segura por CPU;
- recuperación acotada de fuentes y rechazo de chunks duplicados o manipulados;
- soporte IPv6 y mediciones NetLab con consentimiento.
Artefacto verificado
- Commit:
d835eef6d2a877c02d0411e58f27d5afb5008fa8 - ZIP SHA-256:
BE2EADA6916433D7D576C9689D01B02CD4B6FE8829A9D6FB6CAE1F3DD7B8B282 emule.exeSHA-256:7198329B4D992CC9C1A669A27117CFF0FEAFE06DCCF5852A125BF44AC6C960ACBUILD_INFO.txt:dirty: false- Manifiesto interno: 142/142 archivos verificados
Validación
- Compilación limpia
Release|x64: PASS - Core, Integration y ASan: PASS
- Registro de protocolo: 180/180 símbolos
- Pruebas web: 22/22 PASS; 0 vulnerabilidades de nivel alto
- Arranque del paquete, FFmpeg 8.1 y
emule.exe --portable --selftest: PASS
Actualización y vuelta atrás
Extrae el ZIP en una carpeta nueva y conserva una copia de tu perfil antes de probarlo. Para volver a eSE 8.1.0, cierra eMule, desactiva primero cualquier función experimental habilitada y restaura la copia del perfil.
Consulta el README y RELEASE_NOTES.md incluidos en el ZIP para más detalles.
v0.70b-eSE 8.1.0 — Anonymous LiveTV control plane
v0.70b-eSE 8.1.0 — Plano de control tunelizado para LiveTV
⚠️ Corrección de honestidad (2026-06-13)Estas notas originales daban a entender un anonimato del viewer más fuerte del que v8.1 entrega. Una
auditoría posterior del código encontró que los circuitos de v8.1 son de UN SOLO SALTO. A 1 salto el
exit está conectado directo al viewer y ve su IP (y qué canal pide). v8.1 oculta al viewer del
emisor y de la red Kad, pero NO del exit. El anonimato onion real exige ≥2 saltos — eso llega en
v8.1.1 ("reenvío 2-hop real"). Lee la sección de privacidad, corregida abajo. Disculpas por el
optimismo de la primera versión.
v8.1.0 — validado en vivo el 2026-06-12 con 3 PCs (Tailscale). Plano de control tunelizado (1 salto), estable a 12000 kbps. Backward-compatible con vanilla 0.70b y v8.0.0.
En una frase
v8.1 añade un plano de control tunelizado al P2P LiveTV: la búsqueda Kad por palabra clave y la suscripción a un canal pueden viajar por un circuito onion dentro de la propia red eD2K/Kad, ocultando quién busca qué y quién se suscribe a quién al emisor y a la red — sin VPS, sin dominios, sin terceros.
Qué es nuevo
- Transporte onion tunelizado (Sprint A): celdas multi-cell sobre
OP_EMULEPROT, dispatcher en el exit, API asíncrona, sweeper de buffers abandonados. - Búsqueda Kad por el túnel (Sprint B): el exit ejecuta una
CSearchreal en nombre del viewer; los resultados vuelven por el circuito. La IP del que busca no se expone al emisor ni a la red Kad (pero sí al exit, a 1 salto). - Suscripción y control de LiveTV por el túnel (Sprint C): el exit hace de proxy multicast (C7) — se suscribe UNA vez al emisor en nombre de N viewers tunelizados; el emisor ve al exit, nunca al viewer.
⚠️ A 1 salto, el exit sí ve la IP del viewer. - Selector de modo de privacidad (Sprint D):
Directo/Tunelizado/Adaptive, persistente, con política de fallback (strict/balanced/best-effort) y panel web. - Estabilidad a bitrate alto: fragmentación de chunks por encima del límite de 2 MB de eMule (
OP_LIVE_CHUNK_FRAG, gated por capacidad) + segmentos HLS de 2 s → emisión fluida validada a 12000 kbps (4K) en malla de varios viewers.
⚠️ Alcance honesto de la privacidad (léelo) — CORREGIDO 2026-06-13
A 1 salto no hay separación de relés: el exit es el único relé y está conectado directo al viewer,
así que ve su IP y sabe qué canal pide. El anonimato onion real exige ≥2 saltos para que ningún relé
vea a la vez quién eres y qué pides. Por eso v8.1 oculta al viewer del emisor y de la red Kad, pero
NO del exit. Un exit malicioso/comprometido desanonimiza al viewer por completo.
| Qué | ¿Oculto frente a…? | Estado real v8.1 (1 salto) |
|---|---|---|
| Quién BUSCA un canal | emisor + red Kad | 🟢 oculto · 🔴 el exit ve la IP + la keyword |
| Quién se SUSCRIBE a un canal | emisor (broadcaster) | 🟢 el emisor ve al exit, no a V · 🔴 el exit ve la IP de V |
| La IP del viewer al recibir los CHUNKS | — | 🔴 visible (el plano de datos sigue directo) |
El modo Tunelizado NO satisface G1 (anonimato real del viewer) por dos razones: (1) los datos van
directos, y (2) el exit ve al viewer (1 salto). Ambas las cierra el roadmap:
- v8.1.1 "Reenvío 2-hop real": circuitos de 2 saltos de verdad (hop1 ≠ exit) → el exit deja de ver la IP del viewer en el plano de control.
- v8.1.2 (Sprint E / E-α): chunks por el túnel de 2 saltos a bitrate nativo → cierra G1 también en los datos.
Hasta entonces, usa Tunelizado entendiendo que confías en el nodo exit. No es anonimato fuerte todavía.
Compatibilidad hacia atrás (F2 — auditado, PASA)
Todo el wire/formato de v8.1 degrada con gracia frente a eMule vanilla 0.70b y al fork previo v8.0.0:
- Las celdas de túnel (
OP_LIVE_TUNNEL_CELL) y los chunks fragmentados (OP_LIVE_CHUNK_FRAG) solo se envían a peers que anunciaron la capacidad (TAG_ESE_CAPS0x6C, bitsPRIVACY_TUNNELING/LIVE_CHUNK_FRAG). Un peer antiguo nunca los recibe. - Un opcode
OP_EMULEPROTdesconocido se descarta en silencio (sinOnError, sin desconexión). - Los registros Kad usan tags estándar (
TAG_SOURCEIP/TAG_SOURCEPORT) + tags eSE con nombre-string que los holders desconocidos ignoran y conservan. Por debajo del umbral de fragmentación el wire es byte-idéntico al de hoy.
Rendimiento (F5 — coste del anonimato)
Honestidad sobre el coste: el túnel es más lento que la búsqueda directa. Medido en vivo (3 PCs, Tailscale):
| Métrica | Directo | Tunelizado (1 hop) |
|---|---|---|
| Latencia búsqueda Kad (inicio → 1er lote de resultados) | ~3-5 s (rango típico Kad) † | ~8 s (medido) ‡ |
† No medible de forma limpia en el banco de 3 PCs (la única stream queda cacheada en el directorio local + cooldown de búsqueda); el valor es el rango habitual de una búsqueda Kad por keyword.
‡ Medido en vivo: Search BEGIN [tunneled] → Tunneled search fed 15 result(s) = 8 s. Incluye que el exit ejecuta una CSearch real, espera su ventana de acumulación, y devuelve los resultados por el circuito. El sobrecoste (~3-4 s sobre el directo) es el precio del anonimato del control.
Problemas conocidos
- Solo 1 salto: el nodo exit ve la IP del viewer y el canal que pide. El anonimato real frente al exit llega en v8.1.1 (reenvío 2-hop real).
- Datos directos: la IP del viewer se expone al servir chunks (ver alcance). → v8.1.2.
- Duplicados de malla: con varios viewers, un segmento puede pedirse a 2 fuentes y llegar 2× (se descarta, desperdicia ancho de banda). Optimización pendiente (dedup PUSH/PULL).
- Steering de exit: para que el circuito NO salga por el propio emisor, el emisor debe arrancar en modo
Directo(la capacidad se fija al arranque). Si arrancó en otro modo, reinícialo en Directo.
Despliegue
emule.exe+ese-server.exedeben ser del mismo build en todos los nodos.- Solo
Release x64.
eMule eSE LiveTV v0.70b-eSE8.0.27 (hero, fuga de ffmpeg y reproductor)
Versión de estabilización. Recoge los arreglos de v8.0.26 y v8.0.27. Sin funciones nuevas — solo que lo que ya hay funcione bien.
Qué se arregla
- El hero ya no se queda en negro. La portada de Inicio mostraba solo el texto "eSE" sobre un fondo negro. Ahora muestra siempre una película destacada — con una lista de respaldo incorporada si la fuente online falla — y se actualiza a "tendencias de la semana" cuando carga.
- Adiós a la fuga de ffmpeg. Al reproducir películas locales se acumulaban procesos
ffmpeg.exe(8 o más, ~1 GB de RAM cada uno, CPU al 90 %) que no morían ni al cerrar el reproductor. Ahora cada reproducción usa exactamente un ffmpeg, que se cierra solo al salir; y un barredor cada 25 s caza cualquier proceso huérfano. - Vuelven las carátulas e info de las películas. Arreglado el proxy de TMDB — un fallo de descompresión (gzip) dejaba los datos ilegibles para el navegador.
- Duración real de las películas. El reproductor ponía siempre "2:00:00" en archivos a medio descargar o con el contenedor dañado. Ahora lee la duración real de las etiquetas de pista del archivo.
- "Auto" ya no se ahoga con 4K. La calidad "Auto" reescala a 1080p como tope — muchísima menos CPU en equipos modestos. Las calidades elegidas a mano se respetan tal cual.
- El aviso de "nueva versión" deja de molestar. El comprobador no sabía leer la versión instalada y avisaba siempre. Ahora compara los números de versión de verdad.
Descarga
eSE-LiveTV-v0.70b-eSE8.0.27-x64.zip — portable, 64 bits, sin instalación. Descomprime y ejecuta emule.exe.
| Componente | Versión |
|---|---|
| emule.exe | build v8.0.24 (sin cambios C++ desde v8.0.24) |
| ese-server.exe | build v8.0.27 |
| config | v8.0.25 — preferences.ini sin límite de velocidad de descarga |
Conocido / pendiente
El streaming Live (emisión P2P entre máquinas) tiene microcortes por un problema en la capa de transporte del relay — ya diagnosticado, pendiente de un arreglo de fondo en una próxima versión.
Código fuente
Rama claude/smart-playback-v8.0.16 (cambios Node/JS de v8.0.16–v8.0.27). El emule.exe C++ procede de la rama feature/ipv6-integration.
eMule eSE LiveTV v0.70b-eSE8.0.25 (estabilidad: cuelgues, RAM, descargas)
Versión de estabilización. Sin funciones nuevas: esta tanda se centra en que lo que ya hay funcione estable, rápido y sin cuelgues. Recoge todos los arreglos acumulados desde la v8.0.0.
Qué notarás
- Se acabaron los cuelgues — al comprobar la conexión a internet y al iniciar una emisión en directo.
- Adiós a la memoria disparada — ya no se "come" hasta 6 GB de RAM hasta ralentizarse.
- Descargas nuevas otra vez rápidas — un ajuste de fábrica las dejaba casi a 0 KB/s en instalaciones nuevas.
- Progreso real — se acabó el "39 GB de 39 GB" cuando la descarga apenas había empezado.
- Películas terminadas bien marcadas como "completada", no "descargando".
- Vuelven las carátulas e info de las películas.
- Ver mientras se descarga, mejor — la reproducción anticipada arranca antes y prioriza las primeras partes del archivo.
Gracias a todos los que reportasteis estos fallos: esta versión es vuestra.
Descarga
eSE-LiveTV-v0.70b-eSE8.0.25-x64.zip — portable, 64 bits, sin instalación. Descomprime y ejecuta emule.exe.
| Componente | Versión |
|---|---|
| emule.exe | build v8.0.24 (sondas IPv6 + Live off-thread + preview-prio + backpressure RAM) |
| ese-server.exe | build v8.0.20 (Smart Playback + suite de tests) |
| config | v8.0.25 — preferences.ini con MaxUpload/MaxDownload=-1 (sin límite) |
Código fuente
Los cambios van en dos ramas (aún sin fusionar a main):
feature/ipv6-integration— cambios C++ de emule.exe (v8.0.21–v8.0.25)claude/smart-playback-v8.0.16— cambios Node/JS + documentación (v8.0.16–v8.0.20 + v8.0.25)
v0.70b-eSE 8.0.0 — Privacy V1
v0.70b-eSE 8.0.0 — Privacy V1
First release with onion routing 2-hop privacy layer verified empirically between two physical machines. Compatible 100% con la red eD2K + Kad existente (TLV-additive, backward compat con eMule 0.70b vanilla).
⚠️ La pila de privacidad onion es V1 — funcional pero no auditada externamente todavía. La criptografía está implementada con primitivos estándar (CryptoPP) y verificada empíricamente, pero hasta que pase auditoría externa + ProVerif, no es válida para casos de uso donde la vida dependa de ello.
🧅 Privacy V1 — onion routing (NUEVO)
- Cripto onion: X25519 ECDH + HKDF-SHA256 + ChaCha20-Poly1305 AEAD
- 2-hop circuits con self-loopback para setups de testing con 2 PCs
- Auto-discovery vía
TAG_ESE_CAPS(0x6C) enOP_HELLO— backward compat con v7.x - Cover traffic real con distribución Poisson (
CELL_PADDINGinyectado) - Identity binding hash en
CELL_CREATE/EXTEND(anti-redirection MITM) - Tunneled Kad search — el destino nunca sabe quién pregunta
- Suscripciones cifradas con DPAPI + REST CRUD API
- 3 modos elegibles: Directo / Tunelizado / Adaptativo
🔍 Verifiabilidad — REST API para auditar el stack en vivo
GET /api/live/privacy— estado runtime + capabilities bitmapGET /api/live/privacy/peers— peers visibles + sus capabilitiesGET /api/live/privacy/circuits— circuits activos + estado por hopGET /api/live/privacy/test_circuit?hops=2— construye circuito onionGET /api/live/privacy/tunnel_ping?text=X— demo data plane (echo)GET /api/live/privacy/tunnel_search?keyword=Y— Kad search anónimaGET /api/live/privacy/subscriptions— CRUD canales suscritos
🖥 UI mejoras
- Nuevo bloque "Privacidad (eSE V1)" en Información propia
— auto-refresca cada 2s con estado real - Nuevo pane
P:Adaptiveen barra de estado — modo + circuits activos/pendientes - Todos los contadores leen de los singletons vivos, no de config cacheada
🌐 IPv6
- Detección automática de IP pública v6 vía
api6.ipify.org(HTTPS, 5s timeout) - Modos: Off / Auto (default) / Preferido (experimental)
- Etiquetas honestas en GUI: el checkbox dice exactamente lo que hace
🔐 Stream integrity (v7.6/v7.7)
- Ed25519 long-term keypair por broadcaster
streamKeyself-certificante =sha1(pubkey)[:16]- Chunks firmados (
OP_LIVE_CHUNK_V2con Ed25519 signature) OP_LIVE_ENDfirmado (tombstone con signature sobrestreamKey || reason)- Pubkey pinning en receivers — un atacante no puede inyectar chunks falsos
📡 Verificación empírica end-to-end
LiveTV PC1→PC2 entre dos NATs distintas (validado hace días):
- PC1 HighID, testpattern 3000 kbps vía FFmpeg → RTMP ingest → publicado en Kad
- PC2 LowID, pegó enlace
|live|, reproducido primero en VLC (fase 1), después en el reproductor cinema integrado del propio eSE (fase 2) - Sin VPS, sin Cloudflare, sin terceros
Privacy V1 entre dos máquinas reales (hoy):
- Auto-discovery TAG_ESE_CAPS: PC1 vio a PC2 con
eseCaps: 0x00000F35, recíproco confirmado - Handshake onion 1-hop:
circuitsActive: 1confirmado vía REST en 800 ms - Handshake onion 2-hop:
hop_count: 2confirmado en 47 ms con cripto X25519 + HKDF separation por dirección - Data plane:
tunnel_ping?text=holadevolvióreceived: "echo:hola"a través del onion 2-hop. Bytes reales atravesaron la cebolla ida y vuelta.
⚠ Limitaciones conocidas (honestidad ante todo)
-
Identity binding es "lite", no full ntor. Defensa contra redirección por hop1, no contra MITM activo con clave long-term. Full ntor con per-node Ed25519 identity en roadmap.
-
2-hop verificado en loopback (2 PCs). Con solo 2 nodos del fork, hop1 = hop2 = mismo nodo físico → anonimato real = 0, protocolo válido. Anonimato real requiere 3+ nodos del fork en la red.
-
Data plane parcial. Solo
tunnel_pingytunnel_searchvan por la cebolla. Kad search nativo, LiveTV subscribe y chunks reales todavía van por path eD2K directo. v8.1 lo cablea. -
Listener IPv6 dual-stack (modo Preferido) rompe HighID en eD2K. Reproducido en 2 redes distintas — bug fundamental. Default Auto NO se ve afectado. Para experimentar dual-stack: editar
preferences.ini→IPv6Mode=2. -
WebServer clásico de eMule (puerto 4711) tiene un bug raro de bind en algunos equipos. Workaround: el panel Node sirve los segmentos HLS directamente.
-
Búsqueda Kad clásica sigue siendo la del eMule original. El rediseño Kad Search v2 está parcialmente implementado (M3 vivo, M1/M5/M6 con bits seteados pero handlers parciales).
-
USER_GUIDE.md dentro del ZIP tiene una nota desactualizada que menciona
eSE.vbs— ese launcher YA NO EXISTE. El método correcto está en el README.md y abajo en este release.
🚀 Migración desde v7.x
Drop-in replacement. No hay cambios de formato. nodes.dat, known.met, preferences.ini, server.met siguen funcionando tal cual. El único fichero nuevo es subscriptions.dat en %APPDATA%\eMule\ese\ (DPAPI cifrado, vacío al primer arranque).
📋 Roadmap próximo
- v8.1: cablear Kad search + LiveTV subscribe a través del tunnel en modo Tunelizado
- v8.2: MFC dialog nativo para gestión de suscripciones + import/export invite tokens base32
- v8.x: full ntor con identidad Ed25519 long-term por nodo
- v9.0: ProVerif validation + auditoría externa cerrada + 3-hop opt-in
🚀 Cómo arrancar (corregido)
- Descarga el ZIP del asset abajo
- Descomprime en cualquier carpeta (p.ej.
C:\eSE\) - Doble click en
emule.exe - Espera a que conecte a eD2K + Kad (verás IDs verdes / amarillas en la barra de estado)
- Click en el botón
eSEde la barra de herramientas de eMule - Tu navegador por defecto se abre automáticamente en
http://localhost:8080/live
No hay instalador. No toca registro. Toda la config va a %APPDATA%\eMule\ y %APPDATA%\eSE\.
Si el firewall de Windows pide permiso para
emule.exe,ese-server.exe, offmpeg.exe— acéptalo. Son los tres procesos que necesita el bundle.
🧪 Cómo verificar la pila de privacidad
# Estado general (puerto del eMule classic web admin, NO el panel Node 8080)
curl http://127.0.0.1:4711/api/live/privacy | ConvertFrom-Json | Select -Expand runtime
# Construir circuito 2-hop (necesita otro nodo fork conectado vía eD2K)
curl 'http://127.0.0.1:4711/api/live/privacy/test_circuit?hops=2'
# Esperar y verificar hop_count=2
Start-Sleep -Seconds 2
curl http://127.0.0.1:4711/api/live/privacy/circuits | ConvertFrom-Json | ConvertTo-Json -Depth 4
# Demo data plane atravesando la cebolla
curl 'http://127.0.0.1:4711/api/live/privacy/tunnel_ping?text=hola'
# Esperado: {ok:true, sent:"hola", received:"echo:hola"}GPLv2. Windows 10/11 x64. Hecho con asistencia de Gemini 3.1 Pro + Claude Code.
eMule eSE LiveTV v0.70b-eSE7.2.1 (viewer-count regression fix)
eMule eSE LiveTV v0.70b-eSE7.2.1 — 2026-05-18
Hotfix for a regression in v7.1.8: the viewer counter on the
broadcaster's UI showed 0 even when several TCP connections were
actively receiving chunks. Same root cause family as v7.1.8 itself —
the interaction between CClientList's connection-merging behaviour
and our peer lists.
emule.exe only. ese-server.exe is byte-identical to v7.2.0.
The regression
v7.1.8 fixed a use-after-free by calling OnPeerDisconnected from
CUpDownClient's destructor. Correct for the "TCP closed, client
genuinely gone" case. Also fires for a less obvious one:
CClientList::AttachToAlreadyKnown merges two CUpDownClient
objects when the same peer sends a second OP_HELLO (e.g. after a
silent reconnect). The OLD object is destroyed, the NEW object keeps
the live TCP socket.
Result with v7.1.8 / v7.2.0:
- PC2 reconnects → second
OP_HELLO→AttachToAlreadyKnownswap - OLD
CUpDownClientdestructed → v7.1.8 callsOnPeerDisconnected
→ peer removed fromm_broadcastPeers - NEW
CUpDownClientis now the live TCP owner, but isn't in the
peer list —OP_LIVE_JOINwas already sent (once, on first
connect), onlyOP_LIVE_BITMAPheartbeats arrive now - Internal viewer count:
0. Actual TCP-connected viewers: 4.
Confirmed empirically:
m_broadcastPeers count: 0
ESTABLISHED TCP connections to port 38362: 4
subscribeAccepted: 138 peerDisconnects: 134 (delta = 4)
138 unique subscribes − 134 disconnect events = 4 live peers. But the
broadcaster's list shows 0 because each peer was disconnected from
the LIST while staying connected on TCP.
The fix
Self-heal the peer lists from the regular heartbeat. OnPeerBitmap
arrives every 1 s for every active peer. If we are broadcasting AND
the streamKey matches AND the peer is NOT in m_broadcastPeers, we
re-add them. Same for the viewer side with m_viewPeers:
if (m_bBroadcasting && m_broadcastPeers.Find(peer) == NULL) {
m_broadcastPeers.AddTail(peer);
m_streamInfo.viewerCount = (uint32)m_broadcastPeers.GetCount();
LIVE_LOG("PEER", "REJOIN viewer=... total=%u", ...);
}
if (m_bViewing && m_viewPeers.Find(peer) == NULL) {
m_viewPeers.AddTail(peer);
}Now any spurious removal — whether by ~CUpDownClient after a
client-list swap, a future regression, or anything else — recovers
on the next heartbeat tick.
The streamKey check that gates this entire function still applies:
re-adding only happens for peers actively transmitting bitmaps for
OUR current streamKey, so a stale peer from a previous broadcast
won't be revived.
Hashes
emule.exe→D6C82FAA47DDEFBDE678E1AF8447F0C9A5ECFC4D3706D3AC17798836E83480EDese-server.exe→A90C54E3FB6BE0A64F8B80400EBE33688AF2D87E121B370A5C8D9059F0A8C48A(unchanged from v7.2.0)
Upgrading from v7.2.0
Just hot-swap emule.exe. ese-server.exe is unchanged so no need
to touch it.
- Close emule (kill
emule.exe, leftoverffmpeg.exe) - Replace
emule.exefrom this release's assets - Reopen emule
The viewer counter will start populating correctly on the next
heartbeat tick (1 s) after a peer connects.
Carried over
- v7.2.0 — OP_LIVE_END tombstone + mesh gossip + crash-detect watchdog
- v7.1.9 — ghost-channel + stale-Kad-entry cleanup
- v7.1.8 —
~CUpDownClient→OnPeerDisconnected(use-after-free) - v7.1.7 —
/liveSyntaxError fix + Cache-Control - v7.1.6 — bitrate-driven ABR variant + muted autoplay
- v7.1.5 — orphan ffmpeg reap
- v7.1.4 — paste-link redirect
- v7.1.3 — preflight badges SyntaxError
- v7.1.2 — Kad publish TAG_SOURCEIP
- v7.1.1 — IPv4 localhost
GPL-2.0-only.
eMule eSE LiveTV v0.70b-eSE7.2.0 (tombstone + gossip + watchdog)
eMule eSE LiveTV v0.70b-eSE7.2.0 — 2026-05-18
Minor-version bump (7.1.x → 7.2.0) because this adds a real network
feature, not just a fix: peer-to-peer gossip of dead-stream
notifications plus a local watchdog that catches broadcaster
crashes (which by definition can't send the notification themselves).
Both emule.exe and ese-server.exe changed.
Why
After yesterday's full day of crash-driven ghost streams, the
constraint became clear: Kad caches outlive the broadcaster by
hours. Every node that learned about your stream keeps echoing it
back to fresh searchers for ~5 h after you die. Local-only fixes
(TTL, registry sweep, prune intervals) help the broadcaster's own
machine but not anyone else's. To kill a ghost across the network
you need active propagation of the death signal.
OP_LIVE_END was already a defined opcode (0xC8) and the broadcaster
already sent it from StopBroadcast to its direct viewers. What was
missing:
- Receivers didn't do anything useful with it — they just removed
the sender from their peer list, but kept the streamKey in their
Kad directory. - The notification stopped at one hop — mesh peers, super-seeders,
and anyone discovering via Kad never heard. - If the broadcaster crashed instead of stopping cleanly,
OP_LIVE_ENDwas never sent at all. Most ghost streams come from
this path, not from graceful stops.
Changes
1. Tombstone map per peer
CLiveStreamManager now keeps a CMap<CString, DWORD> m_streamTombstones
mapping hex streamKeys to expiration tick (default 30 min TTL).
Lookups:
IsStreamTombstoned(streamKey)— called byCLiveKadBridge::GetKnownStreams
andOnKadSearchResultto discard cached Kad echoes that try to
resurrect streams we already know are dead.
Writes:
OnStreamEnded(streamKey, reason, fromPeer)— single entry point
used by both the OP_LIVE_END handler and the watchdog.- Pruned each
Process()tick (every minute).
2. OP_LIVE_END handler now does the work
ListenSocket.cpp:OP_LIVE_END
now reads <streamKey 16><reason 1> from the packet (was: just
removing the sender), then calls OnStreamEnded which:
- Tombstones the streamKey for 30 min.
- Leaves the stream if we were viewing it.
- Gossips the END to our mesh peers (broadcastPeers ∪ viewPeers,
excluding the peer that informed us). Each receiver tombstones
first and ignores duplicates, so propagation is bounded — no
storms.
3. Crash-detection watchdog
CLiveStreamManager::Process
now tracks m_dwLastLiveActivity — refreshed on every chunk receive
AND every bitmap heartbeat. If we are viewing and the clock goes
silent for >90 s, we fabricate a synthetic OP_LIVE_END(reason=error)
locally:
OnStreamEnded(deadKey, ESE_END_ERROR, /*fromPeer=*/ NULL);Tombstones locally and gossips to the mesh. Broadcaster crashed
silently → 90 s later, every direct viewer notices → 90+ε seconds
later, every mesh peer of those viewers notices → fan-out, no
caching node ever sees a fresh lastSeen because nobody's still
publishing the stream.
The 90 s threshold is generous on purpose: heartbeats fire every 1 s
and chunks every 2-4 s, so 22-90 missed beats = unambiguously dead,
not a 4G blip.
4. StopBroadcast notifies wider
CLiveStreamManager::StopBroadcast
used to send OP_LIVE_END only to m_broadcastPeers (direct viewers
subscribed via OP_LIVE_SUBSCRIBE). Now it ALSO sends to m_viewPeers
(in case we were a relay) and to every key in m_peerCounters (every
mesh peer we've talked to). Covers super-seeders that were
redistributing to others.
Also pre-tombstones our own streamKey before gossiping so an echo
that bounces back through the mesh doesn't trigger another round.
5. Kad result filter on read
CLiveKadBridge::OnKadSearchResult
and GetKnownStreams consult
IsStreamTombstoned and drop matching entries. Stale Kad echoes from
other nodes can no longer resurrect a stream we've already buried.
What this does NOT fix
Cold Kad nodes — machines that learned about a stream from a
search result but never connected to the mesh — won't receive the
gossip. They keep echoing the dead stream to fresh searchers until
their own local TTL expires (~5 h with vanilla eMule's
KADEMLIAREPUBLISHTIMEK = 24h and indexer-side prune at
~5 h half-life).
For those nodes, only time plus everyone's local
IsStreamTombstoned check on incoming results eventually evicts
the entry. Anyone running 7.2.0 won't display it; anyone running
older clients will, until Kad TTL.
Listed for v7.2.x if it bites:
- Publish a deliberate "deprecated" Kad entry (bitrate=0 sentinel)
more aggressively to overwrite the active one in cold caches.
Partially exists already inUnpublishStream— could be extended
to also publish on tombstone-from-gossip.
Hashes
emule.exe→47139CB568A325F96A40B81E26893DE5788A52D151BEAF059BCC444B6B196B7Cese-server.exe→A90C54E3FB6BE0A64F8B80400EBE33688AF2D87E121B370A5C8D9059F0A8C48A
(ese-server.exe rebuilt as part of the emule.sln pre-build step.
No source-level changes from v7.1.9 in the Node side.)
Upgrading from v7.1.9
Hot-swap supported. Both binaries changed.
- Close emule (kill
emule.exe,ese-server.exe, and any leftover
ffmpeg.exe). - Replace BOTH binaries from the assets (or re-extract the ZIP).
- Reopen emule.
If you were broadcasting when you stopped, expect a tombstone to be
sent to whoever was watching as part of StopBroadcast. They'll
hide your channel from their lists for 30 min — which is correct,
because the streamKey of your next broadcast will be different.
Wire compatibility
OP_LIVE_END (opcode 0xC8) was already eSE-only. Vanilla eMule
0.70b ignores it. Older eSE versions process it (remove peer) but
don't gossip; they're consumers, not propagators. v7.2.0+ peers
form the gossip-active subset of the mesh, which is enough — most
networks will converge to all-7.2.0 within days as people update.
Carried over
- v7.1.9 — ghost-channel + stale-Kad-entry cleanup
- v7.1.8 —
~CUpDownClient→OnPeerDisconnected(use-after-free) - v7.1.7 —
/liveSyntaxError fix (final) + Cache-Control - v7.1.6 — bitrate-driven ABR variant + muted autoplay
- v7.1.5 — orphan ffmpeg reap
- v7.1.4 — paste-link redirect
- v7.1.3 — preflight badges SyntaxError
- v7.1.2 — Kad publish TAG_SOURCEIP
- v7.1.1 — IPv4 localhost
GPL-2.0-only.
eMule eSE LiveTV v0.70b-eSE7.1.9 (ghost cleanup)
eMule eSE LiveTV v0.70b-eSE7.1.9 — 2026-05-18
Cleanup release. Kills ghost channel entries (own + remote) and stale
Kad directory entries that survived broadcast stops, streamKey changes,
or eMule restarts. Also makes the remote-channel uptime stop resetting
to "0min" on every Kad poll.
Both emule.exe and ese-server.exe changed.
What this fixes
Ghost local channels in the directory
channel_search.js::registerChannel now sweeps every other isLocal
entry from the in-memory channel registry before inserting the new
broadcast. Previously each Start broadcast added a new entry keyed
by streamKey; old local_<ts> / obs_<ts> / external_<ts> entries
from prior sessions piled up and stayed visible because the
"pipeline-active" liveness flag in search() is GLOBAL, not
per-streamKey. After many broadcasts the same machine showed itself
3-4 times in the channel list.
Uptime reset on every Kad poll
channel_search.js::addRemoteChannel preserves the original started
timestamp across updates. The C++ Kad layer doesn't emit a stable
start time, so each poll passed new Date().toISOString() through
Object.assign, overwriting the existing one. Result: every remote
broadcast in the directory had its uptime reset to 0min 4 times a
minute, instead of growing as expected.
Immortal own-stream entries in Kad directory
LiveKadBridge::PublishStream now sweeps any prior isOwnStream
entries from m_streamDirectory when the streamKey changes. Before
this, m_streamDirectory[strKey] = entry just added the new one and
the previous own entries stuck around forever — until v7.1.9
PruneStaleEntries also explicitly skipped them. So any user who
broadcast more than once per session showed up multiple times in
their own directory.
PruneStaleEntries no longer skips own entries
The if (entry.isOwnStream) continue; early-skip is replaced with
keep only the currently-published own entry; everything else (including own-but-stale) gets pruned. Together with the new
PublishStream sweep, this guarantees the directory has AT MOST one
own entry at all times — the one for the active broadcast (or zero
if nothing is broadcasting).
Kad TTL shortened
ESE_KAD_ENTRY_TTL from 180 s (3 min) → 120 s (2 min). The
broadcaster republishes every 60 s, so any remote entry that misses
two consecutive republishes is presumed dead and pruned. (Original
upstream eMule was 10 min.) ESE_KAD_PRUNE_INTERVAL stays at 30 s.
Still pending (not urgent)
Remote-broadcaster entries in other Kad nodes' caches can still
outlive the broadcaster by hours — their lastSeen gets refreshed
locally by every echo of the original Kad publish even after the
broadcaster's emule has exited. Truly killing those requires a
separate lastVerifiedAlive field updated only when a heartbeat or
chunk arrives directly from the broadcaster. Bigger change, deferred
to v7.2.
Hashes
emule.exe→4B8298EFE7D52E08D8648F48876960A5B07C257F62A1902AF6E35470262DB66Cese-server.exe→4B6483D524D015D01A3765E724E7B5CD6688D22D6CABC7089D733F49C117811C
Upgrading from v7.1.8
Hot-swap supported, but both binaries changed this time:
- Close eMule fully (kill
emule.exe,ese-server.exe, and any
leftoverffmpeg.exe— emule does not own ffmpeg as a child
process via job-object, so it can survive an emule kill). - Replace BOTH
emule.exeandese-server.exefrom this release's
assets (or re-extract the full ZIP). - Reopen eMule.
Don't forget to also clean %TEMP%\eMule_RTMP\ if you had failed
broadcasts earlier — stale seg_*.ts files give the watcher a
misleading baseSeg start point.
Carried over
- v7.1.8 —
~CUpDownClient→OnPeerDisconnected(use-after-free fix on viewer disconnect) - v7.1.7 —
/liveSyntaxError fix (real one) + Cache-Control headers - v7.1.6 — bitrate-driven ABR variant + muted autoplay
- v7.1.5 — orphan ffmpeg reap on broadcast start
- v7.1.4 — paste-link redirect fix
- v7.1.3 — preflight badges SyntaxError + ilimitada cosmetic
- v7.1.2 — Kad publish TAG_SOURCEIP
- v7.1.1 — IPv4 localhost for login
GPL-2.0-only.