From 00d78f4853b44f28c1b257055a2dad2fbcde61a3 Mon Sep 17 00:00:00 2001 From: RyuJongJin <266630912+RyuJongJin@users.noreply.github.com> Date: Sun, 11 Oct 2026 23:13:30 +0900 Subject: [PATCH] =?UTF-8?q?dns=20TC=20=EC=8B=9C=ED=97=98:=20=EC=8B=A4?= =?UTF-8?q?=ED=8C=A8=ED=95=98=EB=A9=B4=20=EC=98=A4=EB=A5=98=20=C2=B7=20?= =?UTF-8?q?=EA=B0=80=EC=A7=9C=20DNS=20=EA=B8=B0=EB=A1=9D=EC=9D=84=20?= =?UTF-8?q?=EB=82=A8=EA=B9=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 전체 실행에서만 한 번씩 실패한 "잘린 답 (TC) 은 TCP 로 다시 묻는다" 의 원인을 잡으려고, 실패하면 예외 · 종류 · errno 와 가짜 DNS 의 bind 시도 · TCP 받음 기록 · 질문을 출력한다 (wt_mgr 세 번 · wt_tor 두 번 전체 실행에서는 재현되지 않음). Co-Authored-By: Claude Opus 5.5 --- test/dns_proxy_test.dart | 12 ++++++++++-- test/support/fake_dns.dart | 8 +++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/test/dns_proxy_test.dart b/test/dns_proxy_test.dart index 4017c48..a8ea5be 100644 --- a/test/dns_proxy_test.dart +++ b/test/dns_proxy_test.dart @@ -55,8 +55,16 @@ void main() { await t.start(); addTearDown(t.close); final r = DnsResolver(config: () => custom('127.0.0.1'), port: t.port); - expect((await r.lookup('big.test')).single.address, '10.9.9.9'); - expect(t.tcpQueries, greaterThan(0)); + // 전체 실행에서만 실패한 적이 있다 - 실패하면 실제 오류와 가짜 DNS 의 기록을 남긴다 + 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 { diff --git a/test/support/fake_dns.dart b/test/support/fake_dns.dart index c0f1032..83ef0ee 100644 --- a/test/support/fake_dns.dart +++ b/test/support/fake_dns.dart @@ -13,6 +13,9 @@ class FakeDns { final queries = []; int tcpQueries = 0; + /// 시작 · 응답 중에 생긴 일 (시험이 실패하면 남겨 원인을 본다) + final events = []; + FakeDns(this.records, {this.truncateUdp = false, this.ttl = 300}); int get port => _udp.port; @@ -29,8 +32,10 @@ class FakeDns { try { _udp = await RawDatagramSocket.bind(InternetAddress.loopbackIPv4, tcp.port); _tcp = tcp; + events.add('bound tcp+udp ${tcp.port} (try $i)'); break; - } on SocketException { + } on SocketException catch (e) { + events.add('udp bind ${tcp.port} failed: ${e.osError?.errorCode} ${e.message}'); await tcp.close(); if (i > 50) rethrow; } @@ -43,6 +48,7 @@ class FakeDns { _udp.send(_answer(d.data, tc: truncateUdp), d.address, d.port); }); _tcp?.listen((s) async { + events.add('tcp accepted ${s.remotePort}'); final buf = BytesBuilder(); await for (final c in s) { buf.add(c);