|
|
|
@ -30,7 +30,7 @@ type Handler struct {
|
|
|
|
|
func New(ctx context.Context, config *Config) (*Handler, error) {
|
|
|
|
|
space := app.SpaceFromContext(ctx)
|
|
|
|
|
if space == nil {
|
|
|
|
|
return nil, errors.New("VMess|Outbound: No space in context.")
|
|
|
|
|
return nil, errors.New("no space in context.").Path("Proxy", "VMess", "Outbound")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
serverList := protocol.NewServerList()
|
|
|
|
@ -61,15 +61,15 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
|
|
|
|
|
return nil
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
return errors.New("VMess|Outbound: Failed to find an available destination.").Base(err).AtWarning()
|
|
|
|
|
return errors.New("failed to find an available destination").Base(err).AtWarning().Path("Proxy", "VMess", "Outbound")
|
|
|
|
|
}
|
|
|
|
|
defer conn.Close()
|
|
|
|
|
|
|
|
|
|
target, ok := proxy.TargetFromContext(ctx)
|
|
|
|
|
if !ok {
|
|
|
|
|
return errors.New("VMess|Outbound: Target not specified.")
|
|
|
|
|
return errors.New("target not specified").Path("Proxy", "VMess", "Outbound").AtError()
|
|
|
|
|
}
|
|
|
|
|
log.Trace(errors.New("VMess|Outbound: Tunneling request to ", target, " via ", rec.Destination()))
|
|
|
|
|
log.Trace(errors.New("tunneling request to ", target, " via ", rec.Destination()).Path("Proxy", "VMess", "Outbound"))
|
|
|
|
|
|
|
|
|
|
command := protocol.RequestCommandTCP
|
|
|
|
|
if target.Network == net.Network_UDP {
|
|
|
|
@ -86,7 +86,7 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
|
|
|
|
|
|
|
|
|
|
rawAccount, err := request.User.GetTypedAccount()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return errors.New("VMess|Outbound: Failed to get user account.").Base(err).AtWarning()
|
|
|
|
|
return errors.New("failed to get user account").Base(err).AtWarning().Path("Proxy", "VMess", "Outbound")
|
|
|
|
|
}
|
|
|
|
|
account := rawAccount.(*vmess.InternalAccount)
|
|
|
|
|
request.Security = account.Security
|
|
|
|
@ -109,11 +109,11 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
|
|
|
|
|
bodyWriter := session.EncodeRequestBody(request, writer)
|
|
|
|
|
firstPayload, err := input.ReadTimeout(time.Millisecond * 500)
|
|
|
|
|
if err != nil && err != buf.ErrReadTimeout {
|
|
|
|
|
return errors.New("failed to get first payload").Base(err).Path("VMess", "Outbound")
|
|
|
|
|
return errors.New("failed to get first payload").Base(err).Path("Proxy", "VMess", "Outbound")
|
|
|
|
|
}
|
|
|
|
|
if !firstPayload.IsEmpty() {
|
|
|
|
|
if err := bodyWriter.Write(firstPayload); err != nil {
|
|
|
|
|
return errors.New("failed to write first payload").Base(err).Path("VMess", "Outbound")
|
|
|
|
|
return errors.New("failed to write first payload").Base(err).Path("Proxy", "VMess", "Outbound")
|
|
|
|
|
}
|
|
|
|
|
firstPayload.Release()
|
|
|
|
|
}
|
|
|
|
@ -159,7 +159,7 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil {
|
|
|
|
|
return errors.New("connection ends").Base(err).Path("VMess", "Outbound")
|
|
|
|
|
return errors.New("connection ends").Base(err).Path("Proxy", "VMess", "Outbound")
|
|
|
|
|
}
|
|
|
|
|
runtime.KeepAlive(timer)
|
|
|
|
|
|
|
|
|
|