github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/app/proxyman/inbound/always.go (about) 1 package inbound 2 3 import ( 4 "context" 5 6 "v2ray.com/core" 7 "v2ray.com/core/app/proxyman" 8 "v2ray.com/core/common" 9 "v2ray.com/core/common/dice" 10 "v2ray.com/core/common/errors" 11 "v2ray.com/core/common/mux" 12 "v2ray.com/core/common/net" 13 "v2ray.com/core/features/policy" 14 "v2ray.com/core/features/stats" 15 "v2ray.com/core/proxy" 16 "v2ray.com/core/transport/internet" 17 ) 18 19 func getStatCounter(v *core.Instance, tag string) (stats.Counter, stats.Counter) { 20 var uplinkCounter stats.Counter 21 var downlinkCounter stats.Counter 22 23 policy := v.GetFeature(policy.ManagerType()).(policy.Manager) 24 if len(tag) > 0 && policy.ForSystem().Stats.InboundUplink { 25 statsManager := v.GetFeature(stats.ManagerType()).(stats.Manager) 26 name := "inbound>>>" + tag + ">>>traffic>>>uplink" 27 c, _ := stats.GetOrRegisterCounter(statsManager, name) 28 if c != nil { 29 uplinkCounter = c 30 } 31 } 32 if len(tag) > 0 && policy.ForSystem().Stats.InboundDownlink { 33 statsManager := v.GetFeature(stats.ManagerType()).(stats.Manager) 34 name := "inbound>>>" + tag + ">>>traffic>>>downlink" 35 c, _ := stats.GetOrRegisterCounter(statsManager, name) 36 if c != nil { 37 downlinkCounter = c 38 } 39 } 40 41 return uplinkCounter, downlinkCounter 42 } 43 44 type AlwaysOnInboundHandler struct { 45 proxy proxy.Inbound 46 workers []worker 47 mux *mux.Server 48 tag string 49 } 50 51 func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *proxyman.ReceiverConfig, proxyConfig interface{}) (*AlwaysOnInboundHandler, error) { 52 rawProxy, err := common.CreateObject(ctx, proxyConfig) 53 if err != nil { 54 return nil, err 55 } 56 p, ok := rawProxy.(proxy.Inbound) 57 if !ok { 58 return nil, newError("not an inbound proxy.") 59 } 60 61 h := &AlwaysOnInboundHandler{ 62 proxy: p, 63 mux: mux.NewServer(ctx), 64 tag: tag, 65 } 66 67 uplinkCounter, downlinkCounter := getStatCounter(core.MustFromContext(ctx), tag) 68 69 nl := p.Network() 70 pr := receiverConfig.PortRange 71 address := receiverConfig.Listen.AsAddress() 72 if address == nil { 73 address = net.AnyIP 74 } 75 76 mss, err := internet.ToMemoryStreamConfig(receiverConfig.StreamSettings) 77 if err != nil { 78 return nil, newError("failed to parse stream config").Base(err).AtWarning() 79 } 80 81 if receiverConfig.ReceiveOriginalDestination { 82 if mss.SocketSettings == nil { 83 mss.SocketSettings = &internet.SocketConfig{} 84 } 85 if mss.SocketSettings.Tproxy == internet.SocketConfig_Off { 86 mss.SocketSettings.Tproxy = internet.SocketConfig_Redirect 87 } 88 mss.SocketSettings.ReceiveOriginalDestAddress = true 89 } 90 91 for port := pr.From; port <= pr.To; port++ { 92 if net.HasNetwork(nl, net.Network_TCP) { 93 newError("creating stream worker on ", address, ":", port).AtDebug().WriteToLog() 94 95 worker := &tcpWorker{ 96 address: address, 97 port: net.Port(port), 98 proxy: p, 99 stream: mss, 100 recvOrigDest: receiverConfig.ReceiveOriginalDestination, 101 tag: tag, 102 dispatcher: h.mux, 103 sniffingConfig: receiverConfig.GetEffectiveSniffingSettings(), 104 uplinkCounter: uplinkCounter, 105 downlinkCounter: downlinkCounter, 106 ctx: ctx, 107 } 108 h.workers = append(h.workers, worker) 109 } 110 111 if net.HasNetwork(nl, net.Network_UDP) { 112 worker := &udpWorker{ 113 tag: tag, 114 proxy: p, 115 address: address, 116 port: net.Port(port), 117 dispatcher: h.mux, 118 uplinkCounter: uplinkCounter, 119 downlinkCounter: downlinkCounter, 120 stream: mss, 121 } 122 h.workers = append(h.workers, worker) 123 } 124 } 125 126 return h, nil 127 } 128 129 // Start implements common.Runnable. 130 func (h *AlwaysOnInboundHandler) Start() error { 131 for _, worker := range h.workers { 132 if err := worker.Start(); err != nil { 133 return err 134 } 135 } 136 return nil 137 } 138 139 // Close implements common.Closable. 140 func (h *AlwaysOnInboundHandler) Close() error { 141 var errs []error 142 for _, worker := range h.workers { 143 errs = append(errs, worker.Close()) 144 } 145 errs = append(errs, h.mux.Close()) 146 if err := errors.Combine(errs...); err != nil { 147 return newError("failed to close all resources").Base(err) 148 } 149 return nil 150 } 151 152 func (h *AlwaysOnInboundHandler) GetRandomInboundProxy() (interface{}, net.Port, int) { 153 if len(h.workers) == 0 { 154 return nil, 0, 0 155 } 156 w := h.workers[dice.Roll(len(h.workers))] 157 return w.Proxy(), w.Port(), 9999 158 } 159 160 func (h *AlwaysOnInboundHandler) Tag() string { 161 return h.tag 162 } 163 164 func (h *AlwaysOnInboundHandler) GetInbound() proxy.Inbound { 165 return h.proxy 166 }