Skip to content

Releases: diad87/eMule-eSE-LiveTV

eMule eSE 9.1.0

Choose a tag to compare

@diad87 diad87 released this 02 Aug 16:26

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 blocked V91-I04 case 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 /64 while 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

  1. Stop eMule completely.
  2. Back up %APPDATA%\eMule, %APPDATA%\eSE, or the portable config
    directory, plus any configured temporary directory containing .part and
    .part.met files.
  3. Verify the SHA-256 file published with the ZIP.
  4. Extract 9.1.0 into a new empty directory. Do not merge executable or web
    assets from an older build.
  5. 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

Pre-release

Choose a tag to compare

@diad87 diad87 released this 24 Jul 16:29

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 BindAddr IPv4
    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_V2 implementa el campo Score definido por el wire y
    mantiene lectura compatible con el borrador emitido por beta.2.
  • OP_CALLBACK_V6 exige 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 el uint32 sintético.
  • El límite anti-Sybil de la cola se aplica por /64 en 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:

  1. Base: mediciones limitadas de IPv6, LowID, Punch2 y CGNAT con otros
    participantes de la beta.
  2. 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.
  3. 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=0

No 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 siguiente Tick.
  • 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
    T5 entre 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

  1. Copiar el directorio config completo y todos los .met.
  2. Probar primero con una copia del perfil.
  3. No abrir el mismo perfil con dos procesos.
  4. Mantener emule.exe y ese-server.exe del mismo paquete.
  5. 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

Choose a tag to compare

@diad87 diad87 released this 23 Jul 18:10

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.exe SHA-256: 7198329B4D992CC9C1A669A27117CFF0FEAFE06DCCF5852A125BF44AC6C960AC
  • BUILD_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

Choose a tag to compare

@diad87 diad87 released this 12 Jun 20:38

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. ⚠️ A 1 salto, el nodo exit sí ve al viewer (ver privacidad).

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 CSearch real 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_CAPS 0x6C, bits PRIVACY_TUNNELING/LIVE_CHUNK_FRAG). Un peer antiguo nunca los recibe.
  • Un opcode OP_EMULEPROT desconocido se descarta en silencio (sin OnError, 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.exe deben 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)

Choose a tag to compare

@diad87 diad87 released this 20 May 13:56

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)

Choose a tag to compare

@diad87 diad87 released this 20 May 10:00

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

Choose a tag to compare

@diad87 diad87 released this 19 May 12:46

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) en OP_HELLO — backward compat con v7.x
  • Cover traffic real con distribución Poisson (CELL_PADDING inyectado)
  • 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 bitmap
  • GET /api/live/privacy/peers — peers visibles + sus capabilities
  • GET /api/live/privacy/circuits — circuits activos + estado por hop
  • GET /api/live/privacy/test_circuit?hops=2 — construye circuito onion
  • GET /api/live/privacy/tunnel_ping?text=X — demo data plane (echo)
  • GET /api/live/privacy/tunnel_search?keyword=Y — Kad search anónima
  • GET /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:Adaptive en 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
  • streamKey self-certificante = sha1(pubkey)[:16]
  • Chunks firmados (OP_LIVE_CHUNK_V2 con Ed25519 signature)
  • OP_LIVE_END firmado (tombstone con signature sobre streamKey || 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: 1 confirmado vía REST en 800 ms
  • Handshake onion 2-hop: hop_count: 2 confirmado en 47 ms con cripto X25519 + HKDF separation por dirección
  • Data plane: tunnel_ping?text=hola devolvió 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_ping y tunnel_search van 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.iniIPv6Mode=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)

  1. Descarga el ZIP del asset abajo
  2. Descomprime en cualquier carpeta (p.ej. C:\eSE\)
  3. Doble click en emule.exe
  4. Espera a que conecte a eD2K + Kad (verás IDs verdes / amarillas en la barra de estado)
  5. Click en el botón eSE de la barra de herramientas de eMule
  6. 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, o ffmpeg.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)

Choose a tag to compare

@diad87 diad87 released this 18 May 10:36

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:

  1. PC2 reconnects → second OP_HELLOAttachToAlreadyKnown swap
  2. OLD CUpDownClient destructed → v7.1.8 calls OnPeerDisconnected
    → peer removed from m_broadcastPeers
  3. NEW CUpDownClient is now the live TCP owner, but isn't in the
    peer list
    OP_LIVE_JOIN was already sent (once, on first
    connect), only OP_LIVE_BITMAP heartbeats arrive now
  4. 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.exeD6C82FAA47DDEFBDE678E1AF8447F0C9A5ECFC4D3706D3AC17798836E83480ED
  • ese-server.exeA90C54E3FB6BE0A64F8B80400EBE33688AF2D87E121B370A5C8D9059F0A8C48A (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.

  1. Close emule (kill emule.exe, leftover ffmpeg.exe)
  2. Replace emule.exe from this release's assets
  3. 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 — ~CUpDownClientOnPeerDisconnected (use-after-free)
  • v7.1.7 — /live SyntaxError 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)

Choose a tag to compare

@diad87 diad87 released this 18 May 10:14

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:

  1. 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.
  2. The notification stopped at one hop — mesh peers, super-seeders,
    and anyone discovering via Kad never heard.
  3. If the broadcaster crashed instead of stopping cleanly,
    OP_LIVE_END was 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 by CLiveKadBridge::GetKnownStreams
    and OnKadSearchResult to 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:

  1. Tombstones the streamKey for 30 min.
  2. Leaves the stream if we were viewing it.
  3. 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 in UnpublishStream — could be extended
    to also publish on tombstone-from-gossip.

Hashes

  • emule.exe47139CB568A325F96A40B81E26893DE5788A52D151BEAF059BCC444B6B196B7C
  • ese-server.exeA90C54E3FB6BE0A64F8B80400EBE33688AF2D87E121B370A5C8D9059F0A8C48A

(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.

  1. Close emule (kill emule.exe, ese-server.exe, and any leftover
    ffmpeg.exe).
  2. Replace BOTH binaries from the assets (or re-extract the ZIP).
  3. 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 — ~CUpDownClientOnPeerDisconnected (use-after-free)
  • v7.1.7 — /live SyntaxError 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)

Choose a tag to compare

@diad87 diad87 released this 18 May 10:02

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.exe4B8298EFE7D52E08D8648F48876960A5B07C257F62A1902AF6E35470262DB66C
  • ese-server.exe4B6483D524D015D01A3765E724E7B5CD6688D22D6CABC7089D733F49C117811C

Upgrading from v7.1.8

Hot-swap supported, but both binaries changed this time:

  1. Close eMule fully (kill emule.exe, ese-server.exe, and any
    leftover ffmpeg.exe — emule does not own ffmpeg as a child
    process via job-object, so it can survive an emule kill).
  2. Replace BOTH emule.exe and ese-server.exe from this release's
    assets (or re-extract the full ZIP).
  3. 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 — ~CUpDownClientOnPeerDisconnected (use-after-free fix on viewer disconnect)
  • v7.1.7 — /live SyntaxError 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.