dns TC 시험: 실패하면 오류 · 가짜 DNS 기록을 남김

전체 실행에서만 한 번씩 실패한 "잘린 답 (TC) 은 TCP 로 다시 묻는다" 의 원인을 잡으려고, 실패하면 예외 · 종류 · errno 와
가짜 DNS 의 bind 시도 · TCP 받음 기록 · 질문을 출력한다 (wt_mgr 세 번 · wt_tor 두 번 전체 실행에서는 재현되지 않음).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tor_dns
RyuJongJin 2026-10-11 23:13:30 +09:00
parent e4b6e33a97
commit 00d78f4853
2 changed files with 17 additions and 3 deletions

View File

@ -55,8 +55,16 @@ void main() {
await t.start(); await t.start();
addTearDown(t.close); addTearDown(t.close);
final r = DnsResolver(config: () => custom('127.0.0.1'), port: t.port); final r = DnsResolver(config: () => custom('127.0.0.1'), port: t.port);
expect((await r.lookup('big.test')).single.address, '10.9.9.9'); // 전체 실행에서만 실패한 적이 있다 - 실패하면 실제 오류와 가짜 DNS 의 기록을 남긴다
expect(t.tcpQueries, greaterThan(0)); try {
expect((await r.lookup('big.test')).single.address, '10.9.9.9');
expect(t.tcpQueries, greaterThan(0));
} catch (e, st) {
// ignore: avoid_print
print('TC 시험 실패: $e (${e.runtimeType}${e is SocketException ? ', errno ${e.osError?.errorCode}' : ''})\n'
'가짜 DNS: port ${t.port}, ${t.events}, 질문 ${t.queries}\n$st');
rethrow;
}
}); });
test('서버에 닿지 않으면 unreachable 오류 (기기 DNS 로 바꾸지 않음)', () async { test('서버에 닿지 않으면 unreachable 오류 (기기 DNS 로 바꾸지 않음)', () async {

View File

@ -13,6 +13,9 @@ class FakeDns {
final queries = <String>[]; final queries = <String>[];
int tcpQueries = 0; int tcpQueries = 0;
/// 시작 · 응답 중에 생긴 일 (시험이 실패하면 남겨 원인을 본다)
final events = <String>[];
FakeDns(this.records, {this.truncateUdp = false, this.ttl = 300}); FakeDns(this.records, {this.truncateUdp = false, this.ttl = 300});
int get port => _udp.port; int get port => _udp.port;
@ -29,8 +32,10 @@ class FakeDns {
try { try {
_udp = await RawDatagramSocket.bind(InternetAddress.loopbackIPv4, tcp.port); _udp = await RawDatagramSocket.bind(InternetAddress.loopbackIPv4, tcp.port);
_tcp = tcp; _tcp = tcp;
events.add('bound tcp+udp ${tcp.port} (try $i)');
break; break;
} on SocketException { } on SocketException catch (e) {
events.add('udp bind ${tcp.port} failed: ${e.osError?.errorCode} ${e.message}');
await tcp.close(); await tcp.close();
if (i > 50) rethrow; if (i > 50) rethrow;
} }
@ -43,6 +48,7 @@ class FakeDns {
_udp.send(_answer(d.data, tc: truncateUdp), d.address, d.port); _udp.send(_answer(d.data, tc: truncateUdp), d.address, d.port);
}); });
_tcp?.listen((s) async { _tcp?.listen((s) async {
events.add('tcp accepted ${s.remotePort}');
final buf = BytesBuilder(); final buf = BytesBuilder();
await for (final c in s) { await for (final c in s) {
buf.add(c); buf.add(c);