Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b73e1f42e | ||
|
|
29d339b262 |
+54
-1
@@ -16,7 +16,7 @@
|
||||
|
||||
Aufrufen mit: node server/pruef-anruf.mjs
|
||||
===================================================================== */
|
||||
import { mkdtempSync, rmSync, writeFileSync, unlinkSync } from "node:fs";
|
||||
import { mkdtempSync, rmSync, writeFileSync, unlinkSync, readFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { request as httpAnfrage } from "node:http";
|
||||
@@ -1224,6 +1224,59 @@ melde("=== 8. Zu dritt ===");
|
||||
}
|
||||
}
|
||||
|
||||
/* =====================================================================
|
||||
EIN turn: OHNE ZUGANGSDATEN DARF DEN BROWSER NICHT ERREICHEN
|
||||
(25.09.2026)
|
||||
|
||||
Am selben Tag beim Bau des Podcast-Studios im echten Browser
|
||||
nachgemessen:
|
||||
|
||||
Failed to construct 'RTCPeerConnection': Both username and
|
||||
credential are required when the URL scheme is "turn" or "turns".
|
||||
|
||||
`new RTCPeerConnection(...)` WIRFT. Die Folge ist nicht "kein
|
||||
Vermittlungsserver", sondern KEIN ANRUF -- auch nicht der, der direkt
|
||||
zustande gekommen waere. Aus einem Randproblem (etwa jeder Fuenfte
|
||||
braucht Vermittlung) wuerde ein Totalausfall fuer alle, ausgeloest
|
||||
davon, dass eine Datei auf dem Server unlesbar ist.
|
||||
|
||||
Der Server laesst solche Eintraege bewusst stehen, damit der Grund
|
||||
nicht verschwindet -- das ist dort richtig. Aussortiert wird im
|
||||
Browser, in `workspace/assets/js/anruf.js`.
|
||||
|
||||
DIESE PRUEFUNG LIEST KEINEN TEXT, SONDERN FUEHRT DEN ECHTEN AUSDRUCK
|
||||
AUS. Eine Prüfung, die nur nachsieht, ob irgendwo das Wort "filter"
|
||||
steht, waere auch dann gruen, wenn der Filter das Falsche tut.
|
||||
===================================================================== */
|
||||
{
|
||||
const quelle = readFileSync(new URL("../workspace/assets/js/anruf.js", import.meta.url), "utf8");
|
||||
const t = /adressen = \(d\.adressen \|\| \[\]\)(\.filter\([\s\S]*?\n {8}\}\);)/.exec(quelle);
|
||||
ok(!!t, "in anruf.js wird die Adressliste ueberhaupt gefiltert");
|
||||
if (t) {
|
||||
/* Genau der Ausdruck aus der ausgelieferten Datei, ausgefuehrt. */
|
||||
const filtern = new Function("d", "return (d.adressen || [])" + t[1] + ";");
|
||||
const rein = {
|
||||
adressen: [
|
||||
{ urls: "stun:1.2.3.4:3478" },
|
||||
{ urls: "turn:1.2.3.4:3478?transport=udp", username: "1:a", credential: "x" },
|
||||
{ urls: "turn:1.2.3.4:3478?transport=tcp" },
|
||||
{ urls: "turns:1.2.3.4:5349", username: "1:a" },
|
||||
],
|
||||
};
|
||||
const raus = filtern(rein);
|
||||
ok(raus.length === 2, `es bleiben genau die zwei brauchbaren uebrig (${raus.length})`);
|
||||
ok(raus.some((a) => a.urls.startsWith("stun:")),
|
||||
"STUN bleibt drin -- es kennt gar keine Anmeldung und reicht meistens");
|
||||
ok(raus.every((a) => !/^turns?:/.test(a.urls) || (a.username && a.credential)),
|
||||
"kein turn: ohne Benutzer UND Passwort geht hinaus");
|
||||
/* GEGENPROBE: Wuerde der Filter alles durchlassen, waere die Zeile
|
||||
oben auch gruen. Hier wird bewiesen, dass er wirklich etwas
|
||||
wegnimmt. */
|
||||
ok(raus.length < rein.adressen.length,
|
||||
"Gegenprobe: der Filter nimmt tatsaechlich etwas weg");
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
melde("");
|
||||
melde(`${geprueft} Pruefungen, ${fehler} Fehler`
|
||||
|
||||
@@ -1259,8 +1259,25 @@
|
||||
immer kommt. */
|
||||
let telefonGehtHier = true;
|
||||
|
||||
/* Der Grund, den der Server zum Vermittlungsserver mitschickt --
|
||||
leer heisst "alles in Ordnung". Er steht hier oben, weil ihn
|
||||
`adressenFrisch()` braucht. */
|
||||
let turnGrund = '';
|
||||
|
||||
function adressenFrisch() {
|
||||
if (!adressenGeholt) return false;
|
||||
/* FEHLT DAS GEHEIMNIS, GILT DIE LISTE NIE ALS FRISCH.
|
||||
|
||||
Sonst waere sie es fuer immer: Ohne Zugangsdaten bleibt nach dem
|
||||
Aussortieren nur STUN uebrig, und ein STUN-Eintrag hat keinen
|
||||
Ablaufzeitpunkt -- `every()` sagt dann "alles noch gueltig" und
|
||||
es wird nie wieder gefragt. Waere die Datei auf dem Server
|
||||
zwischenzeitlich repariert, telefonierte trotzdem niemand mehr
|
||||
mit Vermittlung, bis er die Seite neu laedt.
|
||||
|
||||
(Nebenbei die zweite Falle derselben Zeile: `every()` auf einer
|
||||
LEEREN Liste ist `true`. Auch dagegen hilft diese Abfrage.) */
|
||||
if (turnGrund) return false;
|
||||
const jetzt = Math.floor(Date.now() / 1000);
|
||||
return adressen.every((a) => {
|
||||
const m = /^(\d{10,}):/.exec(a && a.username || '');
|
||||
@@ -1277,15 +1294,47 @@
|
||||
if (a.status === 404) { telefonGehtHier = false; return; }
|
||||
if (a.ok) {
|
||||
const d = await a.json();
|
||||
adressen = d.adressen || [];
|
||||
/* ═══════════════════════════════════════════════════════════
|
||||
EIN turn: OHNE ZUGANGSDATEN DARF NICHT IN DIE LISTE.
|
||||
|
||||
Am 25.09.2026 im echten Browser nachgemessen (beim Bau des
|
||||
Podcast-Studios, das dieselbe Rechnung benutzt):
|
||||
|
||||
Failed to construct 'RTCPeerConnection': Both username and
|
||||
credential are required when the URL scheme is "turn" or
|
||||
"turns".
|
||||
|
||||
`new RTCPeerConnection(...)` WIRFT. Die Folge ist nicht etwa
|
||||
"kein Vermittlungsserver", sondern KEIN ANRUF -- auch nicht
|
||||
der, der direkt zustande gekommen waere. Aus einem
|
||||
Randproblem (etwa jeder fuenfte braucht Vermittlung) wuerde
|
||||
ein Totalausfall fuer alle.
|
||||
|
||||
Der Server laesst solche Eintraege bewusst stehen, damit der
|
||||
Grund nicht verschwindet (server/workspace-turn.js, Absatz
|
||||
"KEIN STILLES WEGLASSEN"). Das ist dort richtig -- aber es
|
||||
heisst, dass HIER aussortiert werden muss, bevor gebaut wird.
|
||||
Der Grund geht nicht verloren: Er steht weiter unten in der
|
||||
Konsole.
|
||||
|
||||
STUN bleibt selbstverstaendlich drin -- STUN kennt gar keine
|
||||
Anmeldung, und es ist der Weg, der in den meisten Faellen
|
||||
reicht.
|
||||
═══════════════════════════════════════════════════════════ */
|
||||
adressen = (d.adressen || []).filter((e) => {
|
||||
if (!/^turns?:/.test(String(e && e.urls))) return true;
|
||||
return !!(e.username && e.credential);
|
||||
});
|
||||
nurGleichesNetz = !!d.nur_gleiches_netz;
|
||||
gruppeMax = d.gruppe_max || 4;
|
||||
adressenGeholt = true;
|
||||
/* Ein eingetragener Vermittlungsserver, der niemanden
|
||||
durchlässt, ist schlimmer als keiner -- er sieht aus, als
|
||||
wäre alles eingerichtet. Deshalb steht er in der Konsole. */
|
||||
if (d.turn_grund) {
|
||||
console.warn('[anruf] Vermittlungsserver ohne Zugangsdaten:', d.turn_grund);
|
||||
turnGrund = d.turn_grund || '';
|
||||
if (turnGrund) {
|
||||
console.warn('[anruf] Vermittlungsserver ohne Zugangsdaten:', turnGrund,
|
||||
'- Anrufe gehen nur noch direkt. Auf dem Server nachsehen: /etc/coturn-workspace.geheimnis');
|
||||
}
|
||||
}
|
||||
} catch { /* dann eben ohne -- im selben Netz geht es trotzdem */ }
|
||||
|
||||
+1
-1
@@ -756,7 +756,7 @@
|
||||
bereit, und chat.js baut die Knoepfe nur, wenn es das gibt.
|
||||
Andersherum waere die Reihenfolge eine stille Abhaengigkeit --
|
||||
die Knoepfe fehlten, und niemand wuesste warum. -->
|
||||
<script src="assets/js/anruf.js?v=202609251440"></script>
|
||||
<script src="assets/js/anruf.js?v=202609251711"></script>
|
||||
<!-- DIE BILDSCHAU (25.09.2026). Eigene Datei, weil sie nichts vom
|
||||
Chat weiss: Sie bekommt einen Weg und einen Namen und zeigt ein
|
||||
Bild. Jede andere Seite mit Fotos kann sie ebenso benutzen, ohne
|
||||
|
||||
Reference in New Issue
Block a user