From 816f3da4d3c04cdf6c277e9083238b1377a46c74 Mon Sep 17 00:00:00 2001 From: Rasmus Dahlberg Date: Sun, 2 Apr 2023 21:21:04 +0200 Subject: Annotate (non-)deadline more clearly Made sense to then split conn errors as well. --- internal/qna/qna.go | 57 +++++++++++++++++++++++++++++++++-------------------- main.go | 8 ++++++++ scripts/test.sh | 13 ++++++++---- 3 files changed, 53 insertions(+), 25 deletions(-) diff --git a/internal/qna/qna.go b/internal/qna/qna.go index 1a016b0..f8e6bd8 100644 --- a/internal/qna/qna.go +++ b/internal/qna/qna.go @@ -1,9 +1,7 @@ package qna import ( - "context" "crypto/tls" - "errors" "fmt" "net" "net/url" @@ -20,11 +18,15 @@ type Answer struct { HTTP string // value set in the Onion-Location HTTP header (if any) HTML string // value set in the Onion-Location HTML attribute (if any) + CtxErr bool // true if context deadline was exceeded ReqErr error // nil if HTTP GET request could be constructed DoErr error // nil if HTTP GET request could be executed } func (a Answer) String() string { + if a.CtxErr { + return fmt.Sprintf("%s: context deadline exteeded") + } if a.ReqErr != nil { return fmt.Sprintf("%s: %v", a.ReqErr) } @@ -45,10 +47,12 @@ type Progress struct { NumDNSNotFoundErr int NumDNSTimeoutErr int NumDNSOtherErr int - NumConnErr int + NumConnTimeoutErr int + NumConnSyscallErr int NumTLSCertErr int NumTLSOtherErr int Num3xxErr int + NumEOFErr int NumDeadlineErr int NumOtherErr int } @@ -60,9 +64,11 @@ func (p Progress) String() string { str += fmt.Sprintf(" Req: %d (Before sending request)\n", p.NumMakeReqErr) str += fmt.Sprintf(" DNS: %d (NotFound:%d Timeout:%d Other:%d)\n", p.NumDNSErr(), p.NumDNSNotFoundErr, p.NumDNSTimeoutErr, p.NumDNSOtherErr) - str += fmt.Sprintf(" TCP: %d (Connection error)\n", p.NumConnErr) + str += fmt.Sprintf(" TCP: %d (Timeout:%d Syscall:%d)\n", + p.NumConnErr(), p.NumConnTimeoutErr, p.NumConnSyscallErr) str += fmt.Sprintf(" TLS: %d (Cert:%d Other:%d)\n", p.NumTLSErr(), p.NumTLSCertErr, p.NumTLSOtherErr) str += fmt.Sprintf(" 3xx: %d (Too many redirects)\n", p.Num3xxErr) + str += fmt.Sprintf(" EOF: %d (Unclear meaning)\n", p.NumEOFErr) str += fmt.Sprintf(" CTX: %d (Deadline exceeded)\n", p.NumDeadlineErr) str += fmt.Sprintf(" ???: %d (Other errors)", p.NumOtherErr) return str @@ -72,12 +78,16 @@ func (p *Progress) NumDNSErr() int { return p.NumDNSNotFoundErr + p.NumDNSTimeoutErr + p.NumDNSOtherErr } +func (p *Progress) NumConnErr() int { + return p.NumConnTimeoutErr + p.NumConnSyscallErr +} + func (p *Progress) NumTLSErr() int { return p.NumTLSCertErr + p.NumTLSOtherErr } func (p *Progress) NumError() int { - return p.NumMakeReqErr + p.NumDNSErr() + p.NumConnErr + p.NumTLSErr() + p.Num3xxErr + p.NumDeadlineErr + p.NumOtherErr + return p.NumMakeReqErr + p.NumDNSErr() + p.NumConnErr() + p.NumTLSErr() + p.Num3xxErr + p.NumEOFErr + p.NumDeadlineErr + p.NumOtherErr } func (p *Progress) NumProcess() int { @@ -85,6 +95,10 @@ func (p *Progress) NumProcess() int { } func (p *Progress) AddAnswer(a Answer) { + if a.CtxErr { + p.NumDeadlineErr++ + return + } if err := a.ReqErr; err != nil { p.NumMakeReqErr++ return @@ -98,8 +112,10 @@ func (p *Progress) AddAnswer(a Answer) { } else { p.NumDNSOtherErr++ } - } else if isConnError(err) { - p.NumConnErr++ + } else if isConnTimeoutError(err) { + p.NumConnTimeoutErr++ + } else if isConnSyscallError(err) { + p.NumConnSyscallErr++ } else if isTLSError(err) { if isTLSCertError(err) { p.NumTLSCertErr++ @@ -108,8 +124,8 @@ func (p *Progress) AddAnswer(a Answer) { } } else if is3xxErr(err) { p.Num3xxErr++ - } else if isDeadlineError(err) { - p.NumDeadlineErr++ + } else if isEOFError(err) { + p.NumEOFErr++ } else { p.NumOtherErr++ } @@ -137,23 +153,26 @@ func dnsError(err error) *net.DNSError { return dnsErr } -func isConnError(err error) bool { +func isConnTimeoutError(err error) bool { urlErr, ok := err.(*url.Error) if !ok { return false } - if str := urlErr.Err.Error(); str == "EOF" || str == "unexpected EOF" { - return true - } opErr, ok := urlErr.Err.(*net.OpError) + return ok && opErr.Err.Error() == "i/o timeout" +} + +func isConnSyscallError(err error) bool { + urlErr, ok := err.(*url.Error) if !ok { return false } - syscallErr, ok := opErr.Err.(*os.SyscallError) + opErr, ok := urlErr.Err.(*net.OpError) if !ok { return false } - return syscallErr.Syscall == "connect" || syscallErr.Syscall == "read" + syscallErr, ok := opErr.Err.(*os.SyscallError) + return ok && (syscallErr.Syscall == "connect" || syscallErr.Syscall == "read") } func isTLSError(err error) bool { @@ -181,13 +200,9 @@ func is3xxErr(err error) bool { return ok && urlErr.Err.Error() == "stopped after 10 redirects" } -func isDeadlineError(err error) bool { +func isEOFError(err error) bool { urlErr, ok := err.(*url.Error) - if ok && errors.Is(urlErr.Err, context.DeadlineExceeded) { - return true - } - opErr, ok := urlErr.Err.(*net.OpError) - return ok && opErr.Err.Error() == "i/o timeout" + return ok && (urlErr.Err.Error() == "EOF" || urlErr.Err.Error() == "unexpected EOF") } func TrimWildcard(san string) string { diff --git a/main.go b/main.go index 5972132..a372fa1 100644 --- a/main.go +++ b/main.go @@ -109,6 +109,10 @@ func work(ctx context.Context, cli *http.Client, timeout time.Duration, question req, err := http.NewRequestWithContext(cctx, http.MethodGet, "https://"+question.Domain, nil) if err != nil { answer.ReqErr = err + if cctx.Err() != nil { + answer.CtxErr = true + } + answerCh <- answer return } @@ -116,6 +120,10 @@ func work(ctx context.Context, cli *http.Client, timeout time.Duration, question rsp, err := cli.Do(req) if err != nil { answer.DoErr = err + if cctx.Err() != nil { + answer.CtxErr = true + } + answerCh <- answer return } diff --git a/scripts/test.sh b/scripts/test.sh index 11a3a42..30c46d0 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -55,7 +55,7 @@ function main() { done now=$(date +%s) estimated_done=$(( $now + $runtime_s + $wait_mullvad_s + $wait_onion_grab_s )) - debug "estimated done? earliest $(date -d @$estimated_done +"%Y-%m-%d %H:%M:%S %Z")" + debug "estimated done? approximately $(date -d @$estimated_done +"%Y-%m-%d %H:%M:%S %Z")" i=1 for limit in ${limits[@]}; do @@ -105,13 +105,18 @@ function main() { failure_tcp=$(grep 'TCP:' "$stderr_file" | tail -n1 | xargs | cut -d' ' -f2) failure_tls=$(grep 'TLS:' "$stderr_file" | tail -n1 | xargs | cut -d' ' -f2) failure_3xx=$(grep '3xx:' "$stderr_file" | tail -n1 | xargs | cut -d' ' -f2) + failure_eof=$(grep 'EOF:' "$stderr_file" | tail -n1 | xargs | cut -d' ' -f2) failure_ctx=$(grep 'CTX:' "$stderr_file" | tail -n1 | xargs | cut -d' ' -f2) failure_qqq=$(grep '???:' "$stderr_file" | tail -n1 | xargs | cut -d' ' -f2) failure_dns_detailed=$(grep 'DNS:' "$stderr_file" | tail -n1 | xargs | cut -d' ' -f3-) + failure_tcp_detailed=$(grep 'TCP:' "$stderr_file" | tail -n1 | xargs | cut -d' ' -f3-) failure_tls_detailed=$(grep 'TLS:' "$stderr_file" | tail -n1 | xargs | cut -d' ' -f3-) - info "relay:$relay limit:$limit/s rate:$avg_rate onions:$num_onion connected:$success/$processed"\ - "freq:$failure_req fdns:$failure_dns $failure_dns_detailed ftcp:$failure_tcp"\ - "ftls:$failure_tls $failure_tls_detailed f3xx:$failure_3xx fctx:$failure_ctx f???:$failure_qqq" + info "relay:$relay limit:$limit/s rate:$avg_rate onions:$num_onion"\ + "connected:$success/$processed freq:$failure_req"\ + "fdns:$failure_dns $failure_dns_detailed"\ + "ftcp:$failure_tcp $failure_tcp_detailed"\ + "ftls:$failure_tls $failure_tls_detailed"\ + "f3xx:$failure_3xx feof:$failure_eof fctx:$failure_ctx f???:$failure_qqq" output_file=$out_dir/$relay-l$limit.txt mv "$stdout_file" "$output_file" -- cgit v1.2.3