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  }