mirror of
https://github.com/p4gefau1t/trojan-go.git
synced 2026-10-21 05:21:41 +00:00
95 lines
1.9 KiB
Go
95 lines
1.9 KiB
Go
package mux
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/xtaci/smux"
|
|
|
|
"github.com/p4gefau1t/trojan-go/common"
|
|
"github.com/p4gefau1t/trojan-go/log"
|
|
"github.com/p4gefau1t/trojan-go/tunnel"
|
|
)
|
|
|
|
// Server is a smux server
|
|
type Server struct {
|
|
underlay tunnel.Server
|
|
connChan chan tunnel.Conn
|
|
ctx context.Context
|
|
cancel context.CancelFunc
|
|
}
|
|
|
|
func (s *Server) acceptConnWorker() {
|
|
for {
|
|
conn, err := s.underlay.AcceptConn(&Tunnel{})
|
|
if err != nil {
|
|
log.Debug(err)
|
|
select {
|
|
case <-s.ctx.Done():
|
|
return
|
|
default:
|
|
}
|
|
continue
|
|
}
|
|
go func(conn tunnel.Conn) {
|
|
smuxConfig := smux.DefaultConfig()
|
|
// smuxConfig.KeepAliveDisabled = true
|
|
smuxSession, err := smux.Server(conn, smuxConfig)
|
|
if err != nil {
|
|
log.Error(err)
|
|
return
|
|
}
|
|
go func(session *smux.Session, conn tunnel.Conn) {
|
|
defer session.Close()
|
|
defer conn.Close()
|
|
for {
|
|
stream, err := session.AcceptStream()
|
|
if err != nil {
|
|
log.Error(err)
|
|
return
|
|
}
|
|
select {
|
|
case s.connChan <- &Conn{
|
|
rwc: stream,
|
|
Conn: conn,
|
|
}:
|
|
case <-s.ctx.Done():
|
|
log.Debug("exiting")
|
|
return
|
|
}
|
|
}
|
|
}(smuxSession, conn)
|
|
}(conn)
|
|
}
|
|
}
|
|
|
|
func (s *Server) AcceptConn(tunnel.Tunnel) (tunnel.Conn, error) {
|
|
select {
|
|
case conn := <-s.connChan:
|
|
return conn, nil
|
|
case <-s.ctx.Done():
|
|
return nil, common.NewError("mux server closed")
|
|
}
|
|
}
|
|
|
|
func (s *Server) AcceptPacket(tunnel.Tunnel) (tunnel.PacketConn, error) {
|
|
panic("not supported")
|
|
}
|
|
|
|
func (s *Server) Close() error {
|
|
s.cancel()
|
|
return s.underlay.Close()
|
|
}
|
|
|
|
func NewServer(ctx context.Context, underlay tunnel.Server) (*Server, error) {
|
|
ctx, cancel := context.WithCancel(ctx)
|
|
server := &Server{
|
|
underlay: underlay,
|
|
ctx: ctx,
|
|
cancel: cancel,
|
|
connChan: make(chan tunnel.Conn, 32),
|
|
}
|
|
go server.acceptConnWorker()
|
|
log.Debug("mux server created")
|
|
return server, nil
|
|
}
|