Style: code style
This commit is contained in:
41
listener/mixed/conn.go
Normal file
41
listener/mixed/conn.go
Normal file
@ -0,0 +1,41 @@
|
||||
package mixed
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"net"
|
||||
)
|
||||
|
||||
type BufferedConn struct {
|
||||
r *bufio.Reader
|
||||
net.Conn
|
||||
}
|
||||
|
||||
func NewBufferedConn(c net.Conn) *BufferedConn {
|
||||
return &BufferedConn{bufio.NewReader(c), c}
|
||||
}
|
||||
|
||||
// Reader returns the internal bufio.Reader.
|
||||
func (c *BufferedConn) Reader() *bufio.Reader {
|
||||
return c.r
|
||||
}
|
||||
|
||||
// Peek returns the next n bytes without advancing the reader.
|
||||
func (c *BufferedConn) Peek(n int) ([]byte, error) {
|
||||
return c.r.Peek(n)
|
||||
}
|
||||
|
||||
func (c *BufferedConn) Read(p []byte) (int, error) {
|
||||
return c.r.Read(p)
|
||||
}
|
||||
|
||||
func (c *BufferedConn) ReadByte() (byte, error) {
|
||||
return c.r.ReadByte()
|
||||
}
|
||||
|
||||
func (c *BufferedConn) UnreadByte() error {
|
||||
return c.r.UnreadByte()
|
||||
}
|
||||
|
||||
func (c *BufferedConn) Buffered() int {
|
||||
return c.r.Buffered()
|
||||
}
|
66
listener/mixed/mixed.go
Normal file
66
listener/mixed/mixed.go
Normal file
@ -0,0 +1,66 @@
|
||||
package mixed
|
||||
|
||||
import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/Dreamacro/clash/common/cache"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
"github.com/Dreamacro/clash/listener/http"
|
||||
"github.com/Dreamacro/clash/listener/socks"
|
||||
"github.com/Dreamacro/clash/transport/socks5"
|
||||
)
|
||||
|
||||
type Listener struct {
|
||||
net.Listener
|
||||
address string
|
||||
closed bool
|
||||
cache *cache.Cache
|
||||
}
|
||||
|
||||
func New(addr string, in chan<- C.ConnContext) (*Listener, error) {
|
||||
l, err := net.Listen("tcp", addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ml := &Listener{l, addr, false, cache.New(30 * time.Second)}
|
||||
go func() {
|
||||
for {
|
||||
c, err := ml.Accept()
|
||||
if err != nil {
|
||||
if ml.closed {
|
||||
break
|
||||
}
|
||||
continue
|
||||
}
|
||||
go handleConn(c, in, ml.cache)
|
||||
}
|
||||
}()
|
||||
|
||||
return ml, nil
|
||||
}
|
||||
|
||||
func (l *Listener) Close() {
|
||||
l.closed = true
|
||||
l.Listener.Close()
|
||||
}
|
||||
|
||||
func (l *Listener) Address() string {
|
||||
return l.address
|
||||
}
|
||||
|
||||
func handleConn(conn net.Conn, in chan<- C.ConnContext, cache *cache.Cache) {
|
||||
bufConn := NewBufferedConn(conn)
|
||||
head, err := bufConn.Peek(1)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if head[0] == socks5.Version {
|
||||
socks.HandleSocks(bufConn, in)
|
||||
return
|
||||
}
|
||||
|
||||
http.HandleConn(bufConn, in, cache)
|
||||
}
|
Reference in New Issue
Block a user