github.com/metacubex/mihomo@v1.18.5/listener/inbound/vmess.go (about)

     1  package inbound
     2  
     3  import (
     4  	C "github.com/metacubex/mihomo/constant"
     5  	LC "github.com/metacubex/mihomo/listener/config"
     6  	"github.com/metacubex/mihomo/listener/sing_vmess"
     7  	"github.com/metacubex/mihomo/log"
     8  )
     9  
    10  type VmessOption struct {
    11  	BaseOption
    12  	Users       []VmessUser `inbound:"users"`
    13  	WsPath      string      `inbound:"ws-path,omitempty"`
    14  	Certificate string      `inbound:"certificate,omitempty"`
    15  	PrivateKey  string      `inbound:"private-key,omitempty"`
    16  	MuxOption   MuxOption   `inbound:"mux-option,omitempty"`
    17  }
    18  
    19  type VmessUser struct {
    20  	Username string `inbound:"username,omitempty"`
    21  	UUID     string `inbound:"uuid"`
    22  	AlterID  int    `inbound:"alterId"`
    23  }
    24  
    25  func (o VmessOption) Equal(config C.InboundConfig) bool {
    26  	return optionToString(o) == optionToString(config)
    27  }
    28  
    29  type Vmess struct {
    30  	*Base
    31  	config *VmessOption
    32  	l      C.MultiAddrListener
    33  	vs     LC.VmessServer
    34  }
    35  
    36  func NewVmess(options *VmessOption) (*Vmess, error) {
    37  	base, err := NewBase(&options.BaseOption)
    38  	if err != nil {
    39  		return nil, err
    40  	}
    41  	users := make([]LC.VmessUser, len(options.Users))
    42  	for i, v := range options.Users {
    43  		users[i] = LC.VmessUser{
    44  			Username: v.Username,
    45  			UUID:     v.UUID,
    46  			AlterID:  v.AlterID,
    47  		}
    48  	}
    49  	return &Vmess{
    50  		Base:   base,
    51  		config: options,
    52  		vs: LC.VmessServer{
    53  			Enable:      true,
    54  			Listen:      base.RawAddress(),
    55  			Users:       users,
    56  			WsPath:      options.WsPath,
    57  			Certificate: options.Certificate,
    58  			PrivateKey:  options.PrivateKey,
    59  			MuxOption:   options.MuxOption.Build(),
    60  		},
    61  	}, nil
    62  }
    63  
    64  // Config implements constant.InboundListener
    65  func (v *Vmess) Config() C.InboundConfig {
    66  	return v.config
    67  }
    68  
    69  // Address implements constant.InboundListener
    70  func (v *Vmess) Address() string {
    71  	if v.l != nil {
    72  		for _, addr := range v.l.AddrList() {
    73  			return addr.String()
    74  		}
    75  	}
    76  	return ""
    77  }
    78  
    79  // Listen implements constant.InboundListener
    80  func (v *Vmess) Listen(tunnel C.Tunnel) error {
    81  	var err error
    82  	users := make([]LC.VmessUser, len(v.config.Users))
    83  	for i, v := range v.config.Users {
    84  		users[i] = LC.VmessUser{
    85  			Username: v.Username,
    86  			UUID:     v.UUID,
    87  			AlterID:  v.AlterID,
    88  		}
    89  	}
    90  	v.l, err = sing_vmess.New(v.vs, tunnel, v.Additions()...)
    91  	if err != nil {
    92  		return err
    93  	}
    94  	log.Infoln("Vmess[%s] proxy listening at: %s", v.Name(), v.Address())
    95  	return nil
    96  }
    97  
    98  // Close implements constant.InboundListener
    99  func (v *Vmess) Close() error {
   100  	return v.l.Close()
   101  }
   102  
   103  var _ C.InboundListener = (*Vmess)(nil)