github.com/ipfans/trojan-go@v0.11.0/tunnel/mux/server.go (about) 1 package mux 2 3 import ( 4 "context" 5 6 "github.com/xtaci/smux" 7 8 "github.com/ipfans/trojan-go/common" 9 "github.com/ipfans/trojan-go/log" 10 "github.com/ipfans/trojan-go/tunnel" 11 ) 12 13 // Server is a smux server 14 type Server struct { 15 underlay tunnel.Server 16 connChan chan tunnel.Conn 17 ctx context.Context 18 cancel context.CancelFunc 19 } 20 21 func (s *Server) acceptConnWorker() { 22 for { 23 conn, err := s.underlay.AcceptConn(&Tunnel{}) 24 if err != nil { 25 log.Debug(err) 26 select { 27 case <-s.ctx.Done(): 28 return 29 default: 30 } 31 continue 32 } 33 go func(conn tunnel.Conn) { 34 smuxConfig := smux.DefaultConfig() 35 // smuxConfig.KeepAliveDisabled = true 36 smuxSession, err := smux.Server(conn, smuxConfig) 37 if err != nil { 38 log.Error(err) 39 return 40 } 41 go func(session *smux.Session, conn tunnel.Conn) { 42 defer session.Close() 43 defer conn.Close() 44 for { 45 stream, err := session.AcceptStream() 46 if err != nil { 47 log.Error(err) 48 return 49 } 50 select { 51 case s.connChan <- &Conn{ 52 rwc: stream, 53 Conn: conn, 54 }: 55 case <-s.ctx.Done(): 56 log.Debug("exiting") 57 return 58 } 59 } 60 }(smuxSession, conn) 61 }(conn) 62 } 63 } 64 65 func (s *Server) AcceptConn(tunnel.Tunnel) (tunnel.Conn, error) { 66 select { 67 case conn := <-s.connChan: 68 return conn, nil 69 case <-s.ctx.Done(): 70 return nil, common.NewError("mux server closed") 71 } 72 } 73 74 func (s *Server) AcceptPacket(tunnel.Tunnel) (tunnel.PacketConn, error) { 75 panic("not supported") 76 } 77 78 func (s *Server) Close() error { 79 s.cancel() 80 return s.underlay.Close() 81 } 82 83 func NewServer(ctx context.Context, underlay tunnel.Server) (*Server, error) { 84 ctx, cancel := context.WithCancel(ctx) 85 server := &Server{ 86 underlay: underlay, 87 ctx: ctx, 88 cancel: cancel, 89 connChan: make(chan tunnel.Conn, 32), 90 } 91 go server.acceptConnWorker() 92 log.Debug("mux server created") 93 return server, nil 94 }