mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-30 05:56:54 -05:00
Added Transport Layer Chained Proxy Support
This commit is contained in:
parent
8980cf2fcc
commit
dd51d32250
@ -294,6 +294,19 @@ func sniffer(ctx context.Context, cReader *cachedReader, metadataOnly bool) (Sni
|
||||
func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.Link, destination net.Destination) {
|
||||
var handler outbound.Handler
|
||||
|
||||
if forcedOutboundTag := session.GetForcedOutboundTagFromContext(ctx); forcedOutboundTag != "" {
|
||||
session.SetForcedOutboundTagToContext(ctx, "")
|
||||
if h := d.ohm.GetHandler(forcedOutboundTag); h != nil {
|
||||
newError("taking platform initialized detour [", forcedOutboundTag, "] for [", destination, "]").WriteToLog(session.ExportIDToError(ctx))
|
||||
handler = h
|
||||
} else {
|
||||
newError("non existing tag for platform initialized detour: ", forcedOutboundTag).AtError().WriteToLog(session.ExportIDToError(ctx))
|
||||
common.Close(link.Writer)
|
||||
common.Interrupt(link.Reader)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if d.router != nil {
|
||||
if route, err := d.router.PickRoute(routing_session.AsRoutingContext(ctx)); err == nil {
|
||||
tag := route.GetOutboundTag()
|
||||
|
@ -159,7 +159,7 @@ func (h *Handler) Address() net.Address {
|
||||
// Dial implements internet.Dialer.
|
||||
func (h *Handler) Dial(ctx context.Context, dest net.Destination) (internet.Connection, error) {
|
||||
if h.senderSettings != nil {
|
||||
if h.senderSettings.ProxySettings.HasTag() {
|
||||
if h.senderSettings.ProxySettings.HasTag() && !h.senderSettings.ProxySettings.TransportLayerProxy {
|
||||
tag := h.senderSettings.ProxySettings.Tag
|
||||
handler := h.outboundManager.GetHandler(tag)
|
||||
if handler != nil {
|
||||
@ -196,6 +196,12 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (internet.Conn
|
||||
}
|
||||
}
|
||||
|
||||
if h.senderSettings.ProxySettings.HasTag() && h.senderSettings.ProxySettings.TransportLayerProxy {
|
||||
tag := h.senderSettings.ProxySettings.Tag
|
||||
newError("transport layer proxying to ", tag, " for dest ", dest).AtDebug().WriteToLog(session.ExportIDToError(ctx))
|
||||
session.SetTransportLayerProxyTagToContext(ctx, tag)
|
||||
}
|
||||
|
||||
conn, err := internet.Dial(ctx, dest, h.streamSettings)
|
||||
return h.getStatCouterConnection(conn), err
|
||||
}
|
||||
|
@ -84,3 +84,19 @@ func SockoptFromContext(ctx context.Context) *Sockopt {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetTransportLayerProxyTagFromContext(ctx context.Context) string {
|
||||
return ContentFromContext(ctx).Attribute("transportLayerOutgoingTag")
|
||||
}
|
||||
|
||||
func SetTransportLayerProxyTagToContext(ctx context.Context, tag string) {
|
||||
ContentFromContext(ctx).SetAttribute("transportLayerOutgoingTag", tag)
|
||||
}
|
||||
|
||||
func GetForcedOutboundTagFromContext(ctx context.Context) string {
|
||||
return ContentFromContext(ctx).Attribute("forcedOutboundTag")
|
||||
}
|
||||
|
||||
func SetForcedOutboundTagToContext(ctx context.Context, tag string) {
|
||||
ContentFromContext(ctx).SetAttribute("forcedOutboundTag", tag)
|
||||
}
|
||||
|
@ -485,7 +485,8 @@ func (c *StreamConfig) Build() (*internet.StreamConfig, error) {
|
||||
}
|
||||
|
||||
type ProxyConfig struct {
|
||||
Tag string `json:"tag"`
|
||||
Tag string `json:"tag"`
|
||||
TransportLayerProxy bool `json:"transportLayer"`
|
||||
}
|
||||
|
||||
// Build implements Buildable.
|
||||
@ -494,6 +495,7 @@ func (v *ProxyConfig) Build() (*internet.ProxyConfig, error) {
|
||||
return nil, newError("Proxy tag is not set.")
|
||||
}
|
||||
return &internet.ProxyConfig{
|
||||
Tag: v.Tag,
|
||||
Tag: v.Tag,
|
||||
TransportLayerProxy: v.TransportLayerProxy,
|
||||
}, nil
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package internet
|
||||
|
||||
import (
|
||||
"context"
|
||||
core "github.com/v2fly/v2ray-core/v4"
|
||||
"github.com/v2fly/v2ray-core/v4/features/routing"
|
||||
|
||||
"github.com/v2fly/v2ray-core/v4/common/net"
|
||||
"github.com/v2fly/v2ray-core/v4/common/session"
|
||||
@ -68,5 +70,37 @@ func DialSystem(ctx context.Context, dest net.Destination, sockopt *SocketConfig
|
||||
if outbound := session.OutboundFromContext(ctx); outbound != nil {
|
||||
src = outbound.Gateway
|
||||
}
|
||||
|
||||
if transportLayerOutgoingTag := session.GetTransportLayerProxyTagFromContext(ctx); transportLayerOutgoingTag != "" {
|
||||
return DialTaggedOutbound(ctx, dest, transportLayerOutgoingTag)
|
||||
}
|
||||
|
||||
return effectiveSystemDialer.Dial(ctx, src, dest, sockopt)
|
||||
}
|
||||
|
||||
func DialTaggedOutbound(ctx context.Context, dest net.Destination, tag string) (net.Conn, error) {
|
||||
var dispatcher routing.Dispatcher
|
||||
if err := core.RequireFeatures(ctx, func(dispatcherInstance routing.Dispatcher) {
|
||||
dispatcher = dispatcherInstance
|
||||
}); err != nil {
|
||||
return nil, newError("Required Feature dispatcher not resolved").Base(err)
|
||||
}
|
||||
|
||||
content := new(session.Content)
|
||||
content.SkipDNSResolve = true
|
||||
session.SetForcedOutboundTagToContext(ctx, tag)
|
||||
|
||||
ctx = session.ContextWithContent(ctx, content)
|
||||
|
||||
r, err := dispatcher.Dispatch(ctx, dest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var readerOpt net.ConnectionOption
|
||||
if dest.Network == net.Network_TCP {
|
||||
readerOpt = net.ConnectionOutputMulti(r.Reader)
|
||||
} else {
|
||||
readerOpt = net.ConnectionOutputMultiUDP(r.Reader)
|
||||
}
|
||||
return net.NewConnection(net.ConnectionInputMulti(r.Writer), readerOpt), nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user