Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b73e1f42e | ||
|
|
29d339b262 |
+54
-1
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
Aufrufen mit: node server/pruef-anruf.mjs
|
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 { tmpdir } from "node:os";
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
import { request as httpAnfrage } from "node:http";
|
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("");
|
||||||
melde(`${geprueft} Pruefungen, ${fehler} Fehler`
|
melde(`${geprueft} Pruefungen, ${fehler} Fehler`
|
||||||
|
|||||||
@@ -1259,8 +1259,25 @@
|
|||||||
immer kommt. */
|
immer kommt. */
|
||||||
let telefonGehtHier = true;
|
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() {
|
function adressenFrisch() {
|
||||||
if (!adressenGeholt) return false;
|
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);
|
const jetzt = Math.floor(Date.now() / 1000);
|
||||||
return adressen.every((a) => {
|
return adressen.every((a) => {
|
||||||
const m = /^(\d{10,}):/.exec(a && a.username || '');
|
const m = /^(\d{10,}):/.exec(a && a.username || '');
|
||||||
@@ -1277,15 +1294,47 @@
|
|||||||
if (a.status === 404) { telefonGehtHier = false; return; }
|
if (a.status === 404) { telefonGehtHier = false; return; }
|
||||||
if (a.ok) {
|
if (a.ok) {
|
||||||
const d = await a.json();
|
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;
|
nurGleichesNetz = !!d.nur_gleiches_netz;
|
||||||
gruppeMax = d.gruppe_max || 4;
|
gruppeMax = d.gruppe_max || 4;
|
||||||
adressenGeholt = true;
|
adressenGeholt = true;
|
||||||
/* Ein eingetragener Vermittlungsserver, der niemanden
|
/* Ein eingetragener Vermittlungsserver, der niemanden
|
||||||
durchlässt, ist schlimmer als keiner -- er sieht aus, als
|
durchlässt, ist schlimmer als keiner -- er sieht aus, als
|
||||||
wäre alles eingerichtet. Deshalb steht er in der Konsole. */
|
wäre alles eingerichtet. Deshalb steht er in der Konsole. */
|
||||||
if (d.turn_grund) {
|
turnGrund = d.turn_grund || '';
|
||||||
console.warn('[anruf] Vermittlungsserver ohne Zugangsdaten:', 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 */ }
|
} 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.
|
bereit, und chat.js baut die Knoepfe nur, wenn es das gibt.
|
||||||
Andersherum waere die Reihenfolge eine stille Abhaengigkeit --
|
Andersherum waere die Reihenfolge eine stille Abhaengigkeit --
|
||||||
die Knoepfe fehlten, und niemand wuesste warum. -->
|
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
|
<!-- DIE BILDSCHAU (25.09.2026). Eigene Datei, weil sie nichts vom
|
||||||
Chat weiss: Sie bekommt einen Weg und einen Namen und zeigt ein
|
Chat weiss: Sie bekommt einen Weg und einen Namen und zeigt ein
|
||||||
Bild. Jede andere Seite mit Fotos kann sie ebenso benutzen, ohne
|
Bild. Jede andere Seite mit Fotos kann sie ebenso benutzen, ohne
|
||||||
|
|||||||
Reference in New Issue
Block a user