diff --git a/core/src/main/golang/proxy/http.go b/core/src/main/golang/proxy/http.go
index 589244f7c18755bcf23783b224c89572aa52cc27..aaa4be5d292c839ab4e4d717b787db79db9d9253 100644
--- a/core/src/main/golang/proxy/http.go
+++ b/core/src/main/golang/proxy/http.go
@@ -1,60 +1,27 @@
 package proxy
 
 import (
-	"bufio"
-	"net"
-	"net/http"
 	"sync"
 
-	"github.com/Dreamacro/clash/adapter/inbound"
-	"github.com/Dreamacro/clash/log"
+	"github.com/Dreamacro/clash/listener/http"
 	"github.com/Dreamacro/clash/tunnel"
 )
 
-var listener *httpListener
+var listener *http.Listener
 var lock sync.Mutex
 
-type httpListener struct {
-	net.Listener
-
-	closed bool
-}
-
 func Start(listen string) (listenAt string, err error) {
 	lock.Lock()
 	defer lock.Unlock()
 
 	stopLocked()
 
-	l, err := net.Listen("tcp", listen)
-	if err != nil {
-		log.Errorln("Listen HTTP proxy at: %s: %s", listen, err.Error())
-
-		return
+	listener, err = http.NewWithAuthenticate(listen, tunnel.TCPIn(), false)
+	if err == nil {
+		listenAt = listener.Listener().Addr().String()
 	}
 
-	h := &httpListener{
-		Listener: l,
-		closed:   false,
-	}
-
-	listener = h
-
-	go func() {
-		for !h.closed {
-			conn, err := h.Accept()
-			if err != nil {
-				log.Warnln("Accept connection: %s", err.Error())
-				continue
-			}
-
-			_ = conn.(*net.TCPConn).SetKeepAlive(false)
-
-			go h.handleConn(conn)
-		}
-	}()
-
-	return h.Addr().String(), nil
+	return
 }
 
 func Stop() {
@@ -66,36 +33,8 @@ func Stop() {
 
 func stopLocked() {
 	if listener != nil {
-		listener.closed = true
-		_ = listener.Close()
+		listener.Close()
 	}
 
 	listener = nil
 }
-
-func (l *httpListener) handleConn(conn net.Conn) {
-	br := bufio.NewReader(conn)
-	request, err := http.ReadRequest(br)
-
-	if err != nil || request.URL.Host == "" {
-		if err != nil {
-			log.Warnln("[HTTP] Connection closed: %s", err.Error())
-		} else {
-			log.Warnln("[HTTP] Connection closed: unknown host")
-		}
-
-		_ = conn.Close()
-		return
-	}
-
-	if request.Method == http.MethodConnect {
-		_, err := conn.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n"))
-		if err != nil {
-			return
-		}
-		tunnel.Add(inbound.NewHTTPS(request, conn))
-		return
-	}
-
-	tunnel.Add(inbound.NewHTTP(request, conn))
-}
diff --git a/core/src/main/golang/tun/tcp.go b/core/src/main/golang/tun/tcp.go
index b0e3b65d30223f5403e8143a8bb7714d92d3ea4f..67976a1dc57099faa1f1df69de814bf63ad90fa4 100644
--- a/core/src/main/golang/tun/tcp.go
+++ b/core/src/main/golang/tun/tcp.go
@@ -57,7 +57,7 @@ accept:
 			RawDstAddr: tAddr,
 		}
 
-		tunnel.Add(context.NewConnContext(conn, metadata))
+		tunnel.TCPIn() <- context.NewConnContext(conn, metadata)
 	}
 }
 
diff --git a/core/src/main/golang/tun/udp.go b/core/src/main/golang/tun/udp.go
index 6357282b1bbda0fe2144b3398a4ec6478a299a03..09c8f73fd420c0d22571428b13f9bb42c43e22b7 100644
--- a/core/src/main/golang/tun/udp.go
+++ b/core/src/main/golang/tun/udp.go
@@ -74,9 +74,7 @@ read:
 			data:  buf[:n],
 		}
 
-		adapter := inbound.NewPacket(socks5.ParseAddrToSocksAddr(tAddr), pkt, C.SOCKS)
-
-		tunnel.AddPacket(adapter)
+		tunnel.UDPIn() <- inbound.NewPacket(socks5.ParseAddrToSocksAddr(tAddr), pkt, C.SOCKS)
 	}
 }