fix: race condition, tunnel relay, error handling

This commit is contained in:
Kreato 2026-06-01 00:36:44 +03:00
commit 336ec57507
No known key found for this signature in database

View file

@ -5,6 +5,7 @@ import (
"io"
"net"
"net/http"
"sync/atomic"
"time"
"github.com/kreatoo/ihtc/internal/log"
@ -12,7 +13,7 @@ import (
)
type Proxy struct {
listenAddr string
listenAddr atomic.Pointer[string]
obfuscateCfg obfuscate.Config
logger *log.Logger
srv *http.Server
@ -20,10 +21,10 @@ type Proxy struct {
func New(addr string, cfg obfuscate.Config, logger *log.Logger) *Proxy {
p := &Proxy{
listenAddr: addr,
obfuscateCfg: cfg,
logger: logger,
}
p.listenAddr.Store(&addr)
p.srv = &http.Server{
Addr: addr,
Handler: http.HandlerFunc(p.handle),
@ -32,16 +33,17 @@ func New(addr string, cfg obfuscate.Config, logger *log.Logger) *Proxy {
}
func (p *Proxy) ListenAddr() string {
return p.listenAddr
return *p.listenAddr.Load()
}
func (p *Proxy) Start() error {
l, err := net.Listen("tcp", p.listenAddr)
l, err := net.Listen("tcp", *p.listenAddr.Load())
if err != nil {
return err
}
p.listenAddr = l.Addr().String()
p.logger.Info("listening on %s", p.listenAddr)
resolved := l.Addr().String()
p.listenAddr.Store(&resolved)
p.logger.Info("listening on %s", resolved)
return p.srv.Serve(l)
}
@ -85,15 +87,18 @@ func (p *Proxy) handleConnect(w http.ResponseWriter, r *http.Request) {
defer clientConn.Close()
if _, err := bufrw.WriteString("HTTP/1.1 200 Connection Established\r\n\r\n"); err != nil {
p.logger.Debug("write CONNECT response: %v", err)
return
}
if err := bufrw.Flush(); err != nil {
p.logger.Debug("flush CONNECT response: %v", err)
return
}
n, err := obfuscate.HandleClientHello(dest, clientConn, p.obfuscateCfg)
if err != nil && err != io.EOF {
p.logger.Debug("ClientHello frag: wrote %d bytes, err: %v", n, err)
if err != nil {
p.logger.Debug("ClientHello frag failed: %v", err)
return
}
p.logger.Debug("tunnel %s established (%d byte ClientHello fragmented)", target, n)
@ -108,6 +113,7 @@ func (p *Proxy) handleConnect(w http.ResponseWriter, r *http.Request) {
done <- struct{}{}
}()
<-done
<-done
}
func (p *Proxy) handleHTTP(w http.ResponseWriter, r *http.Request) {