1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2026-06-20 18:00:02 -04:00

simplify dialer and dispatcher parameters

This commit is contained in:
Darien Raymond
2017-02-03 22:35:09 +01:00
parent 504ff4b0c4
commit c4d0227977
19 changed files with 152 additions and 147 deletions

View File

@@ -7,6 +7,7 @@ import (
"time"
"v2ray.com/core/common"
"v2ray.com/core/proxy"
"v2ray.com/core/transport/ray"
)
@@ -31,7 +32,7 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
}
// Dispatch implements OutboundHandler.Dispatch().
func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay) error {
func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dialer proxy.Dialer) error {
v.response.WriteTo(outboundRay.OutboundOutput())
// Sleep a little here to make sure the response is sent to client.
time.Sleep(time.Second)

View File

@@ -9,8 +9,7 @@ import (
type key int
const (
dialerKey key = iota
sourceKey
sourceKey key = iota
destinationKey
originalDestinationKey
inboundDestinationKey
@@ -18,20 +17,9 @@ const (
outboundTagKey
resolvedIPsKey
allowPassiveConnKey
dispatcherKey
)
func ContextWithDialer(ctx context.Context, dialer Dialer) context.Context {
return context.WithValue(ctx, dialerKey, dialer)
}
func DialerFromContext(ctx context.Context) Dialer {
v := ctx.Value(dialerKey)
if v == nil {
return nil
}
return v.(Dialer)
}
func ContextWithSource(ctx context.Context, src net.Destination) context.Context {
return context.WithValue(ctx, sourceKey, src)
}

View File

@@ -7,10 +7,10 @@ import (
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/log"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/errors"
"v2ray.com/core/app/log"
"v2ray.com/core/common/net"
"v2ray.com/core/common/signal"
"v2ray.com/core/proxy"
@@ -18,10 +18,9 @@ import (
)
type DokodemoDoor struct {
config *Config
address net.Address
port net.Port
packetDispatcher dispatcher.Interface
config *Config
address net.Address
port net.Port
}
func New(ctx context.Context, config *Config) (*DokodemoDoor, error) {
@@ -37,13 +36,6 @@ func New(ctx context.Context, config *Config) (*DokodemoDoor, error) {
address: config.GetPredefinedAddress(),
port: net.Port(config.Port),
}
space.OnInitialize(func() error {
d.packetDispatcher = dispatcher.FromSpace(space)
if d.packetDispatcher == nil {
return errors.New("Dokodemo: Dispatcher is not found in the space.")
}
return nil
})
return d, nil
}
@@ -51,7 +43,7 @@ func (d *DokodemoDoor) Network() net.NetworkList {
return *(d.config.NetworkList)
}
func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn internet.Connection) error {
func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher dispatcher.Interface) error {
log.Debug("Dokodemo: processing connection from: ", conn.RemoteAddr())
conn.SetReusable(false)
dest := net.Destination{
@@ -68,7 +60,6 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
log.Info("Dokodemo: Invalid destination. Discarding...")
return errors.New("Dokodemo: Unable to get destination.")
}
ctx = proxy.ContextWithDestination(ctx, dest)
ctx, cancel := context.WithCancel(ctx)
timeout := time.Second * time.Duration(d.config.Timeout)
if timeout == 0 {
@@ -76,7 +67,10 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
}
timer := signal.CancelAfterInactivity(ctx, cancel, timeout)
inboundRay := d.packetDispatcher.DispatchToOutbound(ctx)
inboundRay, err := dispatcher.Dispatch(ctx, dest)
if err != nil {
return err
}
requestDone := signal.ExecuteAsync(func() error {
defer inboundRay.InboundInput().Close()

View File

@@ -8,11 +8,11 @@ import (
"v2ray.com/core/app"
"v2ray.com/core/app/dns"
"v2ray.com/core/app/log"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/dice"
"v2ray.com/core/common/errors"
"v2ray.com/core/app/log"
"v2ray.com/core/common/net"
"v2ray.com/core/common/retry"
"v2ray.com/core/common/signal"
@@ -73,7 +73,7 @@ func (v *Handler) ResolveIP(destination net.Destination) net.Destination {
return newDest
}
func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay) error {
func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dialer proxy.Dialer) error {
destination := proxy.DestinationFromContext(ctx)
if v.destOverride != nil {
server := v.destOverride.Server
@@ -93,7 +93,6 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay) erro
destination = v.ResolveIP(destination)
}
dialer := proxy.DialerFromContext(ctx)
err := retry.ExponentialBackoff(5, 100).On(func() error {
rawConn, err := dialer.Dial(ctx, destination)
if err != nil {

View File

@@ -8,27 +8,23 @@ import (
"runtime"
"strconv"
"strings"
"sync"
"time"
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/log"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/bufio"
"v2ray.com/core/common/errors"
"v2ray.com/core/app/log"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/common/signal"
"v2ray.com/core/proxy"
"v2ray.com/core/transport/internet"
)
// Server is a HTTP proxy server.
type Server struct {
sync.Mutex
packetDispatcher dispatcher.Interface
config *ServerConfig
config *ServerConfig
}
// NewServer creates a new HTTP inbound handler.
@@ -40,13 +36,6 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
s := &Server{
config: config,
}
space.OnInitialize(func() error {
s.packetDispatcher = dispatcher.FromSpace(space)
if s.packetDispatcher == nil {
return errors.New("HTTP|Server: Dispatcher not found in space.")
}
return nil
})
return s, nil
}
@@ -79,7 +68,7 @@ func parseHost(rawHost string, defaultPort v2net.Port) (v2net.Destination, error
return v2net.TCPDestination(v2net.DomainAddress(host), port), nil
}
func (s *Server) Process(ctx context.Context, network v2net.Network, conn internet.Connection) error {
func (s *Server) Process(ctx context.Context, network v2net.Network, conn internet.Connection, dispatcher dispatcher.Interface) error {
conn.SetReusable(false)
conn.SetReadDeadline(time.Now().Add(time.Second * 8))
@@ -109,15 +98,15 @@ func (s *Server) Process(ctx context.Context, network v2net.Network, conn intern
return err
}
log.Access(conn.RemoteAddr(), request.URL, log.AccessAccepted, "")
ctx = proxy.ContextWithDestination(ctx, dest)
if strings.ToUpper(request.Method) == "CONNECT" {
return s.handleConnect(ctx, request, reader, conn)
return s.handleConnect(ctx, request, reader, conn, dest, dispatcher)
} else {
return s.handlePlainHTTP(ctx, request, reader, conn)
return s.handlePlainHTTP(ctx, request, reader, conn, dest, dispatcher)
}
}
func (s *Server) handleConnect(ctx context.Context, request *http.Request, reader io.Reader, writer io.Writer) error {
func (s *Server) handleConnect(ctx context.Context, request *http.Request, reader io.Reader, writer io.Writer, dest v2net.Destination, dispatcher dispatcher.Interface) error {
response := &http.Response{
Status: "200 OK",
StatusCode: 200,
@@ -140,7 +129,10 @@ func (s *Server) handleConnect(ctx context.Context, request *http.Request, reade
timeout = time.Minute * 2
}
timer := signal.CancelAfterInactivity(ctx, cancel, timeout)
ray := s.packetDispatcher.DispatchToOutbound(ctx)
ray, err := dispatcher.Dispatch(ctx, dest)
if err != nil {
return err
}
requestDone := signal.ExecuteAsync(func() error {
defer ray.InboundInput().Close()
@@ -213,7 +205,7 @@ func generateResponse(statusCode int, status string) *http.Response {
}
}
func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, reader io.Reader, writer io.Writer) error {
func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, reader io.Reader, writer io.Writer, dest v2net.Destination, dispatcher dispatcher.Interface) error {
if len(request.URL.Host) <= 0 {
response := generateResponse(400, "Bad Request")
return response.Write(writer)
@@ -222,7 +214,10 @@ func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, rea
request.Host = request.URL.Host
StripHopByHopHeaders(request)
ray := s.packetDispatcher.DispatchToOutbound(ctx)
ray, err := dispatcher.Dispatch(ctx, dest)
if err != nil {
return err
}
input := ray.InboundInput()
output := ray.InboundOutput()
defer input.Close()

View File

@@ -4,6 +4,7 @@ package proxy
import (
"context"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/common/net"
"v2ray.com/core/transport/internet"
"v2ray.com/core/transport/ray"
@@ -13,12 +14,12 @@ import (
type Inbound interface {
Network() net.NetworkList
Process(context.Context, net.Network, internet.Connection) error
Process(context.Context, net.Network, internet.Connection, dispatcher.Interface) error
}
// An Outbound process outbound connections.
type Outbound interface {
Process(context.Context, ray.OutboundRay) error
Process(context.Context, ray.OutboundRay, Dialer) error
}
// Dialer is used by OutboundHandler for creating outbound connections.

View File

@@ -7,10 +7,10 @@ import (
"runtime"
"v2ray.com/core/app/log"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/bufio"
"v2ray.com/core/app/log"
"v2ray.com/core/common/net"
"v2ray.com/core/common/protocol"
"v2ray.com/core/common/retry"
@@ -39,14 +39,13 @@ func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {
}
// Process implements OutboundHandler.Process().
func (v *Client) Process(ctx context.Context, outboundRay ray.OutboundRay) error {
func (v *Client) Process(ctx context.Context, outboundRay ray.OutboundRay, dialer proxy.Dialer) error {
destination := proxy.DestinationFromContext(ctx)
network := destination.Network
var server *protocol.ServerSpec
var conn internet.Connection
dialer := proxy.DialerFromContext(ctx)
err := retry.ExponentialBackoff(5, 100).On(func() error {
server = v.serverPicker.PickServer()
dest := server.Destination()

View File

@@ -2,17 +2,16 @@ package shadowsocks
import (
"context"
"time"
"runtime"
"time"
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/log"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/bufio"
"v2ray.com/core/common/errors"
"v2ray.com/core/app/log"
"v2ray.com/core/common/net"
"v2ray.com/core/common/protocol"
"v2ray.com/core/common/signal"
@@ -22,11 +21,9 @@ import (
)
type Server struct {
packetDispatcher dispatcher.Interface
config *ServerConfig
user *protocol.User
account *ShadowsocksAccount
udpServer *udp.Dispatcher
config *ServerConfig
user *protocol.User
account *ShadowsocksAccount
}
func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
@@ -50,14 +47,6 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
account: account,
}
space.OnInitialize(func() error {
s.packetDispatcher = dispatcher.FromSpace(space)
if s.packetDispatcher == nil {
return errors.New("Shadowsocks|Server: Dispatcher is not found in space.")
}
return nil
})
return s, nil
}
@@ -71,20 +60,21 @@ func (s *Server) Network() net.NetworkList {
return list
}
func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection) error {
func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher dispatcher.Interface) error {
conn.SetReusable(false)
switch network {
case net.Network_TCP:
return s.handleConnection(ctx, conn)
return s.handleConnection(ctx, conn, dispatcher)
case net.Network_UDP:
return s.handlerUDPPayload(ctx, conn)
return s.handlerUDPPayload(ctx, conn, dispatcher)
default:
return errors.New("Shadowsocks|Server: Unknown network: ", network)
}
}
func (v *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection) error {
func (v *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection, dispatcher dispatcher.Interface) error {
udpServer := udp.NewDispatcher(dispatcher)
source := proxy.SourceFromContext(ctx)
reader := buf.NewReader(conn)
@@ -119,7 +109,7 @@ func (v *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
log.Info("Shadowsocks|Server: Tunnelling request to ", dest)
ctx = protocol.ContextWithUser(ctx, request.User)
v.udpServer.Dispatch(ctx, dest, data, func(payload *buf.Buffer) {
udpServer.Dispatch(ctx, dest, data, func(payload *buf.Buffer) {
defer payload.Release()
data, err := EncodeUDPPacket(request, payload)
@@ -136,7 +126,7 @@ func (v *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
return nil
}
func (s *Server) handleConnection(ctx context.Context, conn internet.Connection) error {
func (s *Server) handleConnection(ctx context.Context, conn internet.Connection, dispatcher dispatcher.Interface) error {
conn.SetReadDeadline(time.Now().Add(time.Second * 8))
bufferedReader := bufio.NewReader(conn)
request, bodyReader, err := ReadTCPSession(s.user, bufferedReader)
@@ -153,13 +143,15 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection)
log.Access(conn.RemoteAddr(), dest, log.AccessAccepted, "")
log.Info("Shadowsocks|Server: Tunnelling request to ", dest)
ctx = proxy.ContextWithDestination(ctx, dest)
ctx = protocol.ContextWithUser(ctx, request.User)
ctx, cancel := context.WithCancel(ctx)
userSettings := s.user.GetSettings()
timer := signal.CancelAfterInactivity(ctx, cancel, userSettings.PayloadTimeout)
ray := s.packetDispatcher.DispatchToOutbound(ctx)
ray, err := dispatcher.Dispatch(ctx, dest)
if err != nil {
return err
}
requestDone := signal.ExecuteAsync(func() error {
bufferedWriter := bufio.NewWriter(conn)

View File

@@ -6,9 +6,9 @@ import (
"runtime"
"time"
"v2ray.com/core/app/log"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/app/log"
"v2ray.com/core/common/net"
"v2ray.com/core/common/protocol"
"v2ray.com/core/common/retry"
@@ -34,13 +34,12 @@ func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {
return client, nil
}
func (c *Client) Process(ctx context.Context, ray ray.OutboundRay) error {
func (c *Client) Process(ctx context.Context, ray ray.OutboundRay, dialer proxy.Dialer) error {
destination := proxy.DestinationFromContext(ctx)
var server *protocol.ServerSpec
var conn internet.Connection
dialer := proxy.DialerFromContext(ctx)
err := retry.ExponentialBackoff(5, 100).On(func() error {
server = c.serverPicker.PickServer()
dest := server.Destination()

View File

@@ -8,11 +8,11 @@ import (
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/log"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/bufio"
"v2ray.com/core/common/errors"
"v2ray.com/core/app/log"
"v2ray.com/core/common/net"
"v2ray.com/core/common/protocol"
"v2ray.com/core/common/signal"
@@ -23,9 +23,7 @@ import (
// Server is a SOCKS 5 proxy server
type Server struct {
packetDispatcher dispatcher.Interface
config *ServerConfig
udpServer *udp.Dispatcher
config *ServerConfig
}
// NewServer creates a new Server object.
@@ -37,14 +35,6 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
s := &Server{
config: config,
}
space.OnInitialize(func() error {
s.packetDispatcher = dispatcher.FromSpace(space)
if s.packetDispatcher == nil {
return errors.New("Socks|Server: Dispatcher is not found in the space.")
}
s.udpServer = udp.NewDispatcher(s.packetDispatcher)
return nil
})
return s, nil
}
@@ -58,20 +48,20 @@ func (s *Server) Network() net.NetworkList {
return list
}
func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection) error {
func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher dispatcher.Interface) error {
conn.SetReusable(false)
switch network {
case net.Network_TCP:
return s.processTCP(ctx, conn)
return s.processTCP(ctx, conn, dispatcher)
case net.Network_UDP:
return s.handleUDPPayload(ctx, conn)
return s.handleUDPPayload(ctx, conn, dispatcher)
default:
return errors.New("Socks|Server: Unknown network: ", network)
}
}
func (s *Server) processTCP(ctx context.Context, conn internet.Connection) error {
func (s *Server) processTCP(ctx context.Context, conn internet.Connection, dispatcher dispatcher.Interface) error {
conn.SetReadDeadline(time.Now().Add(time.Second * 8))
reader := bufio.NewReader(conn)
@@ -95,8 +85,7 @@ func (s *Server) processTCP(ctx context.Context, conn internet.Connection) error
log.Info("Socks|Server: TCP Connect request to ", dest)
log.Access(source, dest, log.AccessAccepted, "")
ctx = proxy.ContextWithDestination(ctx, dest)
return s.transport(ctx, reader, conn)
return s.transport(ctx, reader, conn, dest, dispatcher)
}
if request.Command == protocol.RequestCommandUDP {
@@ -115,7 +104,7 @@ func (*Server) handleUDP() error {
return nil
}
func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writer) error {
func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writer, dest net.Destination, dispatcher dispatcher.Interface) error {
ctx, cancel := context.WithCancel(ctx)
timeout := time.Second * time.Duration(v.config.Timeout)
if timeout == 0 {
@@ -123,7 +112,11 @@ func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writ
}
timer := signal.CancelAfterInactivity(ctx, cancel, timeout)
ray := v.packetDispatcher.DispatchToOutbound(ctx)
ray, err := dispatcher.Dispatch(ctx, dest)
if err != nil {
return err
}
input := ray.InboundInput()
output := ray.InboundOutput()
@@ -159,7 +152,9 @@ func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writ
return nil
}
func (v *Server) handleUDPPayload(ctx context.Context, conn internet.Connection) error {
func (v *Server) handleUDPPayload(ctx context.Context, conn internet.Connection, dispatcher dispatcher.Interface) error {
udpServer := udp.NewDispatcher(dispatcher)
source := proxy.SourceFromContext(ctx)
log.Info("Socks|Server: Client UDP connection from ", source)
@@ -185,7 +180,7 @@ func (v *Server) handleUDPPayload(ctx context.Context, conn internet.Connection)
dataBuf := buf.NewSmall()
dataBuf.Append(data)
v.udpServer.Dispatch(ctx, request.Destination(), dataBuf, func(payload *buf.Buffer) {
udpServer.Dispatch(ctx, request.Destination(), dataBuf, func(payload *buf.Buffer) {
defer payload.Release()
log.Info("Socks|Server: Writing back UDP response with ", payload.Len(), " bytes")

View File

@@ -10,18 +10,17 @@ import (
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/log"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/bufio"
"v2ray.com/core/common/errors"
"v2ray.com/core/app/log"
"v2ray.com/core/common/net"
"v2ray.com/core/common/protocol"
"v2ray.com/core/common/serial"
"v2ray.com/core/common/signal"
"v2ray.com/core/common/uuid"
"v2ray.com/core/proxy"
"v2ray.com/core/proxy/vmess"
"v2ray.com/core/proxy/vmess/encoding"
"v2ray.com/core/transport/internet"
@@ -75,8 +74,6 @@ func (v *userByEmail) Get(email string) (*protocol.User, bool) {
// Inbound connection handler that handles messages in VMess format.
type VMessInboundHandler struct {
sync.RWMutex
packetDispatcher dispatcher.Interface
inboundHandlerManager proxyman.InboundHandlerManager
clients protocol.UserValidator
usersByEmail *userByEmail
@@ -101,10 +98,6 @@ func New(ctx context.Context, config *Config) (*VMessInboundHandler, error) {
}
space.OnInitialize(func() error {
handler.packetDispatcher = dispatcher.FromSpace(space)
if handler.packetDispatcher == nil {
return errors.New("VMess|Inbound: Dispatcher is not found in space.")
}
handler.inboundHandlerManager = proxyman.InboundHandlerManagerFromSpace(space)
if handler.inboundHandlerManager == nil {
return errors.New("VMess|Inbound: InboundHandlerManager is not found is space.")
@@ -122,9 +115,6 @@ func (*VMessInboundHandler) Network() net.NetworkList {
}
func (v *VMessInboundHandler) GetUser(email string) *protocol.User {
v.RLock()
defer v.RUnlock()
user, existing := v.usersByEmail.Get(email)
if !existing {
v.clients.Add(user)
@@ -177,7 +167,7 @@ func transferResponse(timer *signal.ActivityTimer, session *encoding.ServerSessi
return nil
}
func (v *VMessInboundHandler) Process(ctx context.Context, network net.Network, connection internet.Connection) error {
func (v *VMessInboundHandler) Process(ctx context.Context, network net.Network, connection internet.Connection, dispatcher dispatcher.Interface) error {
connection.SetReadDeadline(time.Now().Add(time.Second * 8))
reader := bufio.NewReader(connection)
@@ -200,11 +190,13 @@ func (v *VMessInboundHandler) Process(ctx context.Context, network net.Network,
connection.SetReusable(request.Option.Has(protocol.RequestOptionConnectionReuse))
userSettings := request.User.GetSettings()
ctx = proxy.ContextWithDestination(ctx, request.Destination())
ctx = protocol.ContextWithUser(ctx, request.User)
ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, userSettings.PayloadTimeout)
ray := v.packetDispatcher.DispatchToOutbound(ctx)
ray, err := dispatcher.Dispatch(ctx, request.Destination())
if err != nil {
return err
}
input := ray.InboundInput()
output := ray.InboundOutput()

View File

@@ -6,11 +6,11 @@ import (
"time"
"v2ray.com/core/app"
"v2ray.com/core/app/log"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/bufio"
"v2ray.com/core/common/errors"
"v2ray.com/core/app/log"
"v2ray.com/core/common/net"
"v2ray.com/core/common/protocol"
"v2ray.com/core/common/retry"
@@ -47,11 +47,10 @@ func New(ctx context.Context, config *Config) (*VMessOutboundHandler, error) {
}
// Dispatch implements OutboundHandler.Dispatch().
func (v *VMessOutboundHandler) Process(ctx context.Context, outboundRay ray.OutboundRay) error {
func (v *VMessOutboundHandler) Process(ctx context.Context, outboundRay ray.OutboundRay, dialer proxy.Dialer) error {
var rec *protocol.ServerSpec
var conn internet.Connection
dialer := proxy.DialerFromContext(ctx)
err := retry.ExponentialBackoff(5, 100).On(func() error {
rec = v.serverPicker.PickServer()
rawConn, err := dialer.Dial(ctx, rec.Destination())