mirror of
https://github.com/v2fly/v2ray-core.git
synced 2025-01-04 16:37:12 -05:00
move session based info into session package
This commit is contained in:
parent
f589769947
commit
94b880d060
@ -16,7 +16,6 @@ import (
|
|||||||
"v2ray.com/core/common/protocol"
|
"v2ray.com/core/common/protocol"
|
||||||
"v2ray.com/core/common/session"
|
"v2ray.com/core/common/session"
|
||||||
"v2ray.com/core/common/stats"
|
"v2ray.com/core/common/stats"
|
||||||
"v2ray.com/core/proxy"
|
|
||||||
"v2ray.com/core/transport/pipe"
|
"v2ray.com/core/transport/pipe"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -165,7 +164,10 @@ func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destin
|
|||||||
if !destination.IsValid() {
|
if !destination.IsValid() {
|
||||||
panic("Dispatcher: Invalid destination.")
|
panic("Dispatcher: Invalid destination.")
|
||||||
}
|
}
|
||||||
ctx = proxy.ContextWithTarget(ctx, destination)
|
ob := &session.Outbound{
|
||||||
|
Target: destination,
|
||||||
|
}
|
||||||
|
ctx = session.ContextWithOutbound(ctx, ob)
|
||||||
|
|
||||||
inbound, outbound := d.getLink(ctx)
|
inbound, outbound := d.getLink(ctx)
|
||||||
sniffingConfig := proxyman.SniffingConfigFromContext(ctx)
|
sniffingConfig := proxyman.SniffingConfigFromContext(ctx)
|
||||||
@ -185,7 +187,7 @@ func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destin
|
|||||||
domain := result.Domain()
|
domain := result.Domain()
|
||||||
newError("sniffed domain: ", domain).WriteToLog(session.ExportIDToError(ctx))
|
newError("sniffed domain: ", domain).WriteToLog(session.ExportIDToError(ctx))
|
||||||
destination.Address = net.ParseAddress(domain)
|
destination.Address = net.ParseAddress(domain)
|
||||||
ctx = proxy.ContextWithTarget(ctx, destination)
|
ob.Target = destination
|
||||||
}
|
}
|
||||||
d.routedDispatch(ctx, outbound, destination)
|
d.routedDispatch(ctx, outbound, destination)
|
||||||
}()
|
}()
|
||||||
|
@ -55,14 +55,16 @@ func (w *tcpWorker) callback(conn internet.Connection) {
|
|||||||
newError("failed to get original destination").Base(err).WriteToLog(session.ExportIDToError(ctx))
|
newError("failed to get original destination").Base(err).WriteToLog(session.ExportIDToError(ctx))
|
||||||
}
|
}
|
||||||
if dest.IsValid() {
|
if dest.IsValid() {
|
||||||
ctx = proxy.ContextWithOriginalTarget(ctx, dest)
|
ctx = session.ContextWithOutbound(ctx, &session.Outbound{
|
||||||
|
Target: dest,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(w.tag) > 0 {
|
ctx = session.ContextWithInbound(ctx, &session.Inbound{
|
||||||
ctx = proxy.ContextWithInboundTag(ctx, w.tag)
|
Source: net.DestinationFromAddr(conn.RemoteAddr()),
|
||||||
}
|
Gateway: net.TCPDestination(w.address, w.port),
|
||||||
ctx = proxy.ContextWithInboundEntryPoint(ctx, net.TCPDestination(w.address, w.port))
|
Tag: w.tag,
|
||||||
ctx = proxy.ContextWithSource(ctx, net.DestinationFromAddr(conn.RemoteAddr()))
|
})
|
||||||
if w.sniffingConfig != nil {
|
if w.sniffingConfig != nil {
|
||||||
ctx = proxyman.ContextWithSniffingConfig(ctx, w.sniffingConfig)
|
ctx = proxyman.ContextWithSniffingConfig(ctx, w.sniffingConfig)
|
||||||
}
|
}
|
||||||
@ -268,15 +270,17 @@ func (w *udpWorker) callback(b *buf.Buffer, source net.Destination, originalDest
|
|||||||
ctx = session.ContextWithID(ctx, sid)
|
ctx = session.ContextWithID(ctx, sid)
|
||||||
|
|
||||||
if originalDest.IsValid() {
|
if originalDest.IsValid() {
|
||||||
ctx = proxy.ContextWithOriginalTarget(ctx, originalDest)
|
ctx = session.ContextWithOutbound(ctx, &session.Outbound{
|
||||||
|
Target: originalDest,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
if len(w.tag) > 0 {
|
ctx = session.ContextWithInbound(ctx, &session.Inbound{
|
||||||
ctx = proxy.ContextWithInboundTag(ctx, w.tag)
|
Source: source,
|
||||||
}
|
Gateway: net.UDPDestination(w.address, w.port),
|
||||||
ctx = proxy.ContextWithSource(ctx, source)
|
Tag: w.tag,
|
||||||
ctx = proxy.ContextWithInboundEntryPoint(ctx, net.UDPDestination(w.address, w.port))
|
})
|
||||||
if err := w.proxy.Process(ctx, net.Network_UDP, conn, w.dispatcher); err != nil {
|
if err := w.proxy.Process(ctx, net.Network_UDP, conn, w.dispatcher); err != nil {
|
||||||
newError("connection ends").Base(err).WriteToLog()
|
newError("connection ends").Base(err).WriteToLog(session.ExportIDToError(ctx))
|
||||||
}
|
}
|
||||||
conn.Close() // nolint: errcheck
|
conn.Close() // nolint: errcheck
|
||||||
w.removeConn(id)
|
w.removeConn(id)
|
||||||
|
@ -88,7 +88,9 @@ var muxCoolPort = net.Port(9527)
|
|||||||
|
|
||||||
// NewClient creates a new mux.Client.
|
// NewClient creates a new mux.Client.
|
||||||
func NewClient(pctx context.Context, p proxy.Outbound, dialer proxy.Dialer, m *ClientManager) (*Client, error) {
|
func NewClient(pctx context.Context, p proxy.Outbound, dialer proxy.Dialer, m *ClientManager) (*Client, error) {
|
||||||
ctx := proxy.ContextWithTarget(context.Background(), net.TCPDestination(muxCoolAddress, muxCoolPort))
|
ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{
|
||||||
|
Target: net.TCPDestination(muxCoolAddress, muxCoolPort),
|
||||||
|
})
|
||||||
ctx, cancel := context.WithCancel(ctx)
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
|
|
||||||
opts := pipe.OptionsFromContext(pctx)
|
opts := pipe.OptionsFromContext(pctx)
|
||||||
@ -160,7 +162,7 @@ func writeFirstPayload(reader buf.Reader, writer *Writer) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func fetchInput(ctx context.Context, s *Session, output buf.Writer) {
|
func fetchInput(ctx context.Context, s *Session, output buf.Writer) {
|
||||||
dest, _ := proxy.TargetFromContext(ctx)
|
dest := session.OutboundFromContext(ctx).Target
|
||||||
transferType := protocol.TransferTypeStream
|
transferType := protocol.TransferTypeStream
|
||||||
if dest.Network == net.Network_UDP {
|
if dest.Network == net.Network_UDP {
|
||||||
transferType = protocol.TransferTypePacket
|
transferType = protocol.TransferTypePacket
|
||||||
@ -367,8 +369,8 @@ func (w *ServerWorker) handleStatusNew(ctx context.Context, meta *FrameMetadata,
|
|||||||
Status: log.AccessAccepted,
|
Status: log.AccessAccepted,
|
||||||
Reason: "",
|
Reason: "",
|
||||||
}
|
}
|
||||||
if src, f := proxy.SourceFromContext(ctx); f {
|
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() {
|
||||||
msg.From = src
|
msg.From = inbound.Source
|
||||||
}
|
}
|
||||||
log.Record(msg)
|
log.Record(msg)
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,9 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (internet.Conn
|
|||||||
handler := h.outboundManager.GetHandler(tag)
|
handler := h.outboundManager.GetHandler(tag)
|
||||||
if handler != nil {
|
if handler != nil {
|
||||||
newError("proxying to ", tag, " for dest ", dest).AtDebug().WriteToLog(session.ExportIDToError(ctx))
|
newError("proxying to ", tag, " for dest ", dest).AtDebug().WriteToLog(session.ExportIDToError(ctx))
|
||||||
ctx = proxy.ContextWithTarget(ctx, dest)
|
ctx = session.ContextWithOutbound(ctx, &session.Outbound{
|
||||||
|
Target: dest,
|
||||||
|
})
|
||||||
|
|
||||||
opts := pipe.OptionsFromContext(ctx)
|
opts := pipe.OptionsFromContext(ctx)
|
||||||
uplinkReader, uplinkWriter := pipe.New(opts...)
|
uplinkReader, uplinkWriter := pipe.New(opts...)
|
||||||
@ -121,7 +123,12 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (internet.Conn
|
|||||||
}
|
}
|
||||||
|
|
||||||
if h.senderSettings.Via != nil {
|
if h.senderSettings.Via != nil {
|
||||||
ctx = internet.ContextWithDialerSource(ctx, h.senderSettings.Via.AsAddress())
|
outbound := session.OutboundFromContext(ctx)
|
||||||
|
if outbound == nil {
|
||||||
|
outbound = new(session.Outbound)
|
||||||
|
ctx = session.ContextWithOutbound(ctx, outbound)
|
||||||
|
}
|
||||||
|
outbound.Gateway = h.senderSettings.Via.AsAddress()
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = internet.ContextWithStreamSettings(ctx, h.streamSettings)
|
ctx = internet.ContextWithStreamSettings(ctx, h.streamSettings)
|
||||||
|
@ -4,6 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"v2ray.com/core/common/session"
|
||||||
|
|
||||||
"v2ray.com/core/app/dispatcher"
|
"v2ray.com/core/app/dispatcher"
|
||||||
"v2ray.com/core/common/net"
|
"v2ray.com/core/common/net"
|
||||||
"v2ray.com/core/common/protocol"
|
"v2ray.com/core/common/protocol"
|
||||||
@ -110,11 +112,11 @@ func (m *DomainMatcher) ApplyDomain(domain string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *DomainMatcher) Apply(ctx context.Context) bool {
|
func (m *DomainMatcher) Apply(ctx context.Context) bool {
|
||||||
dest, ok := proxy.TargetFromContext(ctx)
|
outbound := session.OutboundFromContext(ctx)
|
||||||
if !ok {
|
if outbound == nil || !outbound.Target.IsValid() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
dest := outbound.Target
|
||||||
if !dest.Address.Family().IsDomain() {
|
if !dest.Address.Family().IsDomain() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -137,6 +139,22 @@ func NewCIDRMatcher(ip []byte, mask uint32, onSource bool) (*CIDRMatcher, error)
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sourceFromContext(ctx context.Context) net.Destination {
|
||||||
|
inbound := session.InboundFromContext(ctx)
|
||||||
|
if inbound == nil {
|
||||||
|
return net.Destination{}
|
||||||
|
}
|
||||||
|
return inbound.Source
|
||||||
|
}
|
||||||
|
|
||||||
|
func targetFromContent(ctx context.Context) net.Destination {
|
||||||
|
outbound := session.OutboundFromContext(ctx)
|
||||||
|
if outbound == nil {
|
||||||
|
return net.Destination{}
|
||||||
|
}
|
||||||
|
return outbound.Target
|
||||||
|
}
|
||||||
|
|
||||||
func (v *CIDRMatcher) Apply(ctx context.Context) bool {
|
func (v *CIDRMatcher) Apply(ctx context.Context) bool {
|
||||||
ips := make([]net.IP, 0, 4)
|
ips := make([]net.IP, 0, 4)
|
||||||
if resolver, ok := proxy.ResolvedIPsFromContext(ctx); ok {
|
if resolver, ok := proxy.ResolvedIPsFromContext(ctx); ok {
|
||||||
@ -150,14 +168,13 @@ func (v *CIDRMatcher) Apply(ctx context.Context) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var dest net.Destination
|
var dest net.Destination
|
||||||
var ok bool
|
|
||||||
if v.onSource {
|
if v.onSource {
|
||||||
dest, ok = proxy.SourceFromContext(ctx)
|
dest = sourceFromContext(ctx)
|
||||||
} else {
|
} else {
|
||||||
dest, ok = proxy.TargetFromContext(ctx)
|
dest = targetFromContent(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ok && dest.Address.Family().IsIPv6() {
|
if dest.IsValid() && dest.Address.Family().IsIPv6() {
|
||||||
ips = append(ips, dest.Address.IP())
|
ips = append(ips, dest.Address.IP())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,14 +211,13 @@ func (v *IPv4Matcher) Apply(ctx context.Context) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var dest net.Destination
|
var dest net.Destination
|
||||||
var ok bool
|
|
||||||
if v.onSource {
|
if v.onSource {
|
||||||
dest, ok = proxy.SourceFromContext(ctx)
|
dest = sourceFromContext(ctx)
|
||||||
} else {
|
} else {
|
||||||
dest, ok = proxy.TargetFromContext(ctx)
|
dest = targetFromContent(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ok && dest.Address.Family().IsIPv4() {
|
if dest.IsValid() && dest.Address.Family().IsIPv4() {
|
||||||
ips = append(ips, dest.Address.IP())
|
ips = append(ips, dest.Address.IP())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,11 +240,11 @@ func NewPortMatcher(portRange net.PortRange) *PortMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (v *PortMatcher) Apply(ctx context.Context) bool {
|
func (v *PortMatcher) Apply(ctx context.Context) bool {
|
||||||
dest, ok := proxy.TargetFromContext(ctx)
|
outbound := session.OutboundFromContext(ctx)
|
||||||
if !ok {
|
if outbound == nil || !outbound.Target.IsValid() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return v.port.Contains(dest.Port)
|
return v.port.Contains(outbound.Target.Port)
|
||||||
}
|
}
|
||||||
|
|
||||||
type NetworkMatcher struct {
|
type NetworkMatcher struct {
|
||||||
@ -242,11 +258,11 @@ func NewNetworkMatcher(network *net.NetworkList) *NetworkMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (v *NetworkMatcher) Apply(ctx context.Context) bool {
|
func (v *NetworkMatcher) Apply(ctx context.Context) bool {
|
||||||
dest, ok := proxy.TargetFromContext(ctx)
|
outbound := session.OutboundFromContext(ctx)
|
||||||
if !ok {
|
if outbound == nil || !outbound.Target.IsValid() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return v.network.HasNetwork(dest.Network)
|
return v.network.HasNetwork(outbound.Target.Network)
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserMatcher struct {
|
type UserMatcher struct {
|
||||||
@ -295,11 +311,11 @@ func NewInboundTagMatcher(tags []string) *InboundTagMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (v *InboundTagMatcher) Apply(ctx context.Context) bool {
|
func (v *InboundTagMatcher) Apply(ctx context.Context) bool {
|
||||||
tag, ok := proxy.InboundTagFromContext(ctx)
|
inbound := session.InboundFromContext(ctx)
|
||||||
if !ok {
|
if inbound == nil || len(inbound.Tag) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
tag := inbound.Tag
|
||||||
for _, t := range v.tags {
|
for _, t := range v.tags {
|
||||||
if t == tag {
|
if t == tag {
|
||||||
return true
|
return true
|
||||||
|
@ -8,6 +8,8 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"v2ray.com/core/common/session"
|
||||||
|
|
||||||
proto "github.com/golang/protobuf/proto"
|
proto "github.com/golang/protobuf/proto"
|
||||||
"v2ray.com/core/app/dispatcher"
|
"v2ray.com/core/app/dispatcher"
|
||||||
. "v2ray.com/core/app/router"
|
. "v2ray.com/core/app/router"
|
||||||
@ -17,11 +19,14 @@ import (
|
|||||||
"v2ray.com/core/common/platform"
|
"v2ray.com/core/common/platform"
|
||||||
"v2ray.com/core/common/protocol"
|
"v2ray.com/core/common/protocol"
|
||||||
"v2ray.com/core/common/protocol/http"
|
"v2ray.com/core/common/protocol/http"
|
||||||
"v2ray.com/core/proxy"
|
|
||||||
. "v2ray.com/ext/assert"
|
. "v2ray.com/ext/assert"
|
||||||
"v2ray.com/ext/sysio"
|
"v2ray.com/ext/sysio"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func withOutbound(outbound *session.Outbound) context.Context {
|
||||||
|
return session.ContextWithOutbound(context.Background(), outbound)
|
||||||
|
}
|
||||||
|
|
||||||
func TestRoutingRule(t *testing.T) {
|
func TestRoutingRule(t *testing.T) {
|
||||||
assert := With(t)
|
assert := With(t)
|
||||||
|
|
||||||
@ -53,27 +58,27 @@ func TestRoutingRule(t *testing.T) {
|
|||||||
},
|
},
|
||||||
test: []ruleTest{
|
test: []ruleTest{
|
||||||
{
|
{
|
||||||
input: proxy.ContextWithTarget(context.Background(), net.TCPDestination(net.DomainAddress("v2ray.com"), 80)),
|
input: withOutbound(&session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2ray.com"), 80)}),
|
||||||
output: true,
|
output: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: proxy.ContextWithTarget(context.Background(), net.TCPDestination(net.DomainAddress("www.v2ray.com.www"), 80)),
|
input: withOutbound(&session.Outbound{Target: net.TCPDestination(net.DomainAddress("www.v2ray.com.www"), 80)}),
|
||||||
output: true,
|
output: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: proxy.ContextWithTarget(context.Background(), net.TCPDestination(net.DomainAddress("v2ray.co"), 80)),
|
input: withOutbound(&session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2ray.co"), 80)}),
|
||||||
output: false,
|
output: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: proxy.ContextWithTarget(context.Background(), net.TCPDestination(net.DomainAddress("www.google.com"), 80)),
|
input: withOutbound(&session.Outbound{Target: net.TCPDestination(net.DomainAddress("www.google.com"), 80)}),
|
||||||
output: true,
|
output: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: proxy.ContextWithTarget(context.Background(), net.TCPDestination(net.DomainAddress("facebook.com"), 80)),
|
input: withOutbound(&session.Outbound{Target: net.TCPDestination(net.DomainAddress("facebook.com"), 80)}),
|
||||||
output: true,
|
output: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: proxy.ContextWithTarget(context.Background(), net.TCPDestination(net.DomainAddress("www.facebook.com"), 80)),
|
input: withOutbound(&session.Outbound{Target: net.TCPDestination(net.DomainAddress("www.facebook.com"), 80)}),
|
||||||
output: false,
|
output: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -101,15 +106,15 @@ func TestRoutingRule(t *testing.T) {
|
|||||||
},
|
},
|
||||||
test: []ruleTest{
|
test: []ruleTest{
|
||||||
{
|
{
|
||||||
input: proxy.ContextWithTarget(context.Background(), net.TCPDestination(net.ParseAddress("8.8.8.8"), 80)),
|
input: withOutbound(&session.Outbound{Target: net.TCPDestination(net.ParseAddress("8.8.8.8"), 80)}),
|
||||||
output: true,
|
output: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: proxy.ContextWithTarget(context.Background(), net.TCPDestination(net.ParseAddress("8.8.4.4"), 80)),
|
input: withOutbound(&session.Outbound{Target: net.TCPDestination(net.ParseAddress("8.8.4.4"), 80)}),
|
||||||
output: false,
|
output: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: proxy.ContextWithTarget(context.Background(), net.TCPDestination(net.ParseAddress("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), 80)),
|
input: withOutbound(&session.Outbound{Target: net.TCPDestination(net.ParseAddress("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), 80)}),
|
||||||
output: true,
|
output: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -5,6 +5,8 @@ package router
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"v2ray.com/core/common/session"
|
||||||
|
|
||||||
"v2ray.com/core"
|
"v2ray.com/core"
|
||||||
"v2ray.com/core/common"
|
"v2ray.com/core/common"
|
||||||
"v2ray.com/core/common/net"
|
"v2ray.com/core/common/net"
|
||||||
@ -75,9 +77,11 @@ func (r *Router) PickRoute(ctx context.Context) (string, error) {
|
|||||||
resolver := &ipResolver{
|
resolver := &ipResolver{
|
||||||
dns: r.dns,
|
dns: r.dns,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
outbound := session.OutboundFromContext(ctx)
|
||||||
if r.domainStrategy == Config_IpOnDemand {
|
if r.domainStrategy == Config_IpOnDemand {
|
||||||
if dest, ok := proxy.TargetFromContext(ctx); ok && dest.Address.Family().IsDomain() {
|
if outbound != nil && outbound.Target.IsValid() && outbound.Target.Address.Family().IsDomain() {
|
||||||
resolver.domain = dest.Address.Domain()
|
resolver.domain = outbound.Target.Address.Domain()
|
||||||
ctx = proxy.ContextWithResolveIPs(ctx, resolver)
|
ctx = proxy.ContextWithResolveIPs(ctx, resolver)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,11 +92,11 @@ func (r *Router) PickRoute(ctx context.Context) (string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dest, ok := proxy.TargetFromContext(ctx)
|
if outbound == nil || !outbound.Target.IsValid() {
|
||||||
if !ok {
|
|
||||||
return "", core.ErrNoClue
|
return "", core.ErrNoClue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dest := outbound.Target
|
||||||
if r.domainStrategy == Config_IpIfNonMatch && dest.Address.Family().IsDomain() {
|
if r.domainStrategy == Config_IpIfNonMatch && dest.Address.Family().IsDomain() {
|
||||||
resolver.domain = dest.Address.Domain()
|
resolver.domain = dest.Address.Domain()
|
||||||
ips := resolver.Resolve()
|
ips := resolver.Resolve()
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package router_test
|
package router_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"v2ray.com/core"
|
"v2ray.com/core"
|
||||||
@ -12,7 +11,7 @@ import (
|
|||||||
"v2ray.com/core/common"
|
"v2ray.com/core/common"
|
||||||
"v2ray.com/core/common/net"
|
"v2ray.com/core/common/net"
|
||||||
"v2ray.com/core/common/serial"
|
"v2ray.com/core/common/serial"
|
||||||
"v2ray.com/core/proxy"
|
"v2ray.com/core/common/session"
|
||||||
. "v2ray.com/ext/assert"
|
. "v2ray.com/ext/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -41,7 +40,7 @@ func TestSimpleRouter(t *testing.T) {
|
|||||||
|
|
||||||
r := v.Router()
|
r := v.Router()
|
||||||
|
|
||||||
ctx := proxy.ContextWithTarget(context.Background(), net.TCPDestination(net.DomainAddress("v2ray.com"), 80))
|
ctx := withOutbound(&session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2ray.com"), 80)})
|
||||||
tag, err := r.PickRoute(ctx)
|
tag, err := r.PickRoute(ctx)
|
||||||
assert(err, IsNil)
|
assert(err, IsNil)
|
||||||
assert(tag, Equals, "test")
|
assert(tag, Equals, "test")
|
||||||
|
46
common/session/context.go
Normal file
46
common/session/context.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package session
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
type sessionKey int
|
||||||
|
|
||||||
|
const (
|
||||||
|
idSessionKey sessionKey = iota
|
||||||
|
inboundSessionKey
|
||||||
|
outboundSessionKey
|
||||||
|
)
|
||||||
|
|
||||||
|
// ContextWithID returns a new context with the given ID.
|
||||||
|
func ContextWithID(ctx context.Context, id ID) context.Context {
|
||||||
|
return context.WithValue(ctx, idSessionKey, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDFromContext returns ID in this context, or 0 if not contained.
|
||||||
|
func IDFromContext(ctx context.Context) ID {
|
||||||
|
if id, ok := ctx.Value(idSessionKey).(ID); ok {
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func ContextWithInbound(ctx context.Context, inbound *Inbound) context.Context {
|
||||||
|
return context.WithValue(ctx, inboundSessionKey, inbound)
|
||||||
|
}
|
||||||
|
|
||||||
|
func InboundFromContext(ctx context.Context) *Inbound {
|
||||||
|
if inbound, ok := ctx.Value(inboundSessionKey).(*Inbound); ok {
|
||||||
|
return inbound
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ContextWithOutbound(ctx context.Context, outbound *Outbound) context.Context {
|
||||||
|
return context.WithValue(ctx, outboundSessionKey, outbound)
|
||||||
|
}
|
||||||
|
|
||||||
|
func OutboundFromContext(ctx context.Context) *Outbound {
|
||||||
|
if outbound, ok := ctx.Value(outboundSessionKey).(*Outbound); ok {
|
||||||
|
return outbound
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,6 +0,0 @@
|
|||||||
package session
|
|
||||||
|
|
||||||
type Request struct {
|
|
||||||
//Destination net.Destination
|
|
||||||
DecodedLayers []interface{}
|
|
||||||
}
|
|
@ -6,6 +6,7 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
|
|
||||||
"v2ray.com/core/common/errors"
|
"v2ray.com/core/common/errors"
|
||||||
|
"v2ray.com/core/common/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ID of a session.
|
// ID of a session.
|
||||||
@ -22,28 +23,21 @@ func NewID() ID {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type sessionKey int
|
|
||||||
|
|
||||||
const (
|
|
||||||
idSessionKey sessionKey = iota
|
|
||||||
)
|
|
||||||
|
|
||||||
// ContextWithID returns a new context with the given ID.
|
|
||||||
func ContextWithID(ctx context.Context, id ID) context.Context {
|
|
||||||
return context.WithValue(ctx, idSessionKey, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IDFromContext returns ID in this context, or 0 if not contained.
|
|
||||||
func IDFromContext(ctx context.Context) ID {
|
|
||||||
if id, ok := ctx.Value(idSessionKey).(ID); ok {
|
|
||||||
return id
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExportIDToError(ctx context.Context) errors.ExportOption {
|
func ExportIDToError(ctx context.Context) errors.ExportOption {
|
||||||
id := IDFromContext(ctx)
|
id := IDFromContext(ctx)
|
||||||
return func(h *errors.ExportOptionHolder) {
|
return func(h *errors.ExportOptionHolder) {
|
||||||
h.SessionID = uint32(id)
|
h.SessionID = uint32(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Inbound struct {
|
||||||
|
Source net.Destination
|
||||||
|
Gateway net.Destination
|
||||||
|
Tag string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Outbound struct {
|
||||||
|
Target net.Destination
|
||||||
|
Gateway net.Address
|
||||||
|
ResolvedIPs []net.IP
|
||||||
|
}
|
||||||
|
@ -6,64 +6,12 @@ import (
|
|||||||
"v2ray.com/core/common/net"
|
"v2ray.com/core/common/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
type key int
|
type key uint32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
sourceKey key = iota
|
resolvedIPsKey key = iota
|
||||||
targetKey
|
|
||||||
originalTargetKey
|
|
||||||
inboundEntryPointKey
|
|
||||||
inboundTagKey
|
|
||||||
resolvedIPsKey
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ContextWithSource creates a new context with given source.
|
|
||||||
func ContextWithSource(ctx context.Context, src net.Destination) context.Context {
|
|
||||||
return context.WithValue(ctx, sourceKey, src)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SourceFromContext retrieves source from the given context.
|
|
||||||
func SourceFromContext(ctx context.Context) (net.Destination, bool) {
|
|
||||||
v, ok := ctx.Value(sourceKey).(net.Destination)
|
|
||||||
return v, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func ContextWithOriginalTarget(ctx context.Context, dest net.Destination) context.Context {
|
|
||||||
return context.WithValue(ctx, originalTargetKey, dest)
|
|
||||||
}
|
|
||||||
|
|
||||||
func OriginalTargetFromContext(ctx context.Context) (net.Destination, bool) {
|
|
||||||
v, ok := ctx.Value(originalTargetKey).(net.Destination)
|
|
||||||
return v, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func ContextWithTarget(ctx context.Context, dest net.Destination) context.Context {
|
|
||||||
return context.WithValue(ctx, targetKey, dest)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TargetFromContext(ctx context.Context) (net.Destination, bool) {
|
|
||||||
v, ok := ctx.Value(targetKey).(net.Destination)
|
|
||||||
return v, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func ContextWithInboundEntryPoint(ctx context.Context, dest net.Destination) context.Context {
|
|
||||||
return context.WithValue(ctx, inboundEntryPointKey, dest)
|
|
||||||
}
|
|
||||||
|
|
||||||
func InboundEntryPointFromContext(ctx context.Context) (net.Destination, bool) {
|
|
||||||
v, ok := ctx.Value(inboundEntryPointKey).(net.Destination)
|
|
||||||
return v, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func ContextWithInboundTag(ctx context.Context, tag string) context.Context {
|
|
||||||
return context.WithValue(ctx, inboundTagKey, tag)
|
|
||||||
}
|
|
||||||
|
|
||||||
func InboundTagFromContext(ctx context.Context) (string, bool) {
|
|
||||||
v, ok := ctx.Value(inboundTagKey).(string)
|
|
||||||
return v, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
type IPResolver interface {
|
type IPResolver interface {
|
||||||
Resolve() []net.Address
|
Resolve() []net.Address
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@ import (
|
|||||||
"v2ray.com/core/common/session"
|
"v2ray.com/core/common/session"
|
||||||
"v2ray.com/core/common/signal"
|
"v2ray.com/core/common/signal"
|
||||||
"v2ray.com/core/common/task"
|
"v2ray.com/core/common/task"
|
||||||
"v2ray.com/core/proxy"
|
|
||||||
"v2ray.com/core/transport/internet"
|
"v2ray.com/core/transport/internet"
|
||||||
"v2ray.com/core/transport/pipe"
|
"v2ray.com/core/transport/pipe"
|
||||||
)
|
)
|
||||||
@ -65,8 +64,8 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
|
|||||||
Port: d.port,
|
Port: d.port,
|
||||||
}
|
}
|
||||||
if d.config.FollowRedirect {
|
if d.config.FollowRedirect {
|
||||||
if origDest, ok := proxy.OriginalTargetFromContext(ctx); ok {
|
if outbound := session.OutboundFromContext(ctx); outbound != nil && outbound.Target.IsValid() {
|
||||||
dest = origDest
|
dest = outbound.Target
|
||||||
} else if handshake, ok := conn.(hasHandshakeAddress); ok {
|
} else if handshake, ok := conn.(hasHandshakeAddress); ok {
|
||||||
addr := handshake.HandshakeAddress()
|
addr := handshake.HandshakeAddress()
|
||||||
if addr != nil {
|
if addr != nil {
|
||||||
@ -117,7 +116,7 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
|
|||||||
Tproxy: internet.SocketConfig_TProxy,
|
Tproxy: internet.SocketConfig_TProxy,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
tConn, err := internet.DialSystem(tCtx, nil, net.DestinationFromAddr(conn.RemoteAddr()))
|
tConn, err := internet.DialSystem(tCtx, net.DestinationFromAddr(conn.RemoteAddr()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,11 @@ func isValidAddress(addr *net.IPOrDomain) bool {
|
|||||||
|
|
||||||
// Process implements proxy.Outbound.
|
// Process implements proxy.Outbound.
|
||||||
func (h *Handler) Process(ctx context.Context, link *core.Link, dialer proxy.Dialer) error {
|
func (h *Handler) Process(ctx context.Context, link *core.Link, dialer proxy.Dialer) error {
|
||||||
destination, _ := proxy.TargetFromContext(ctx)
|
outbound := session.OutboundFromContext(ctx)
|
||||||
|
if outbound == nil || !outbound.Target.IsValid() {
|
||||||
|
return newError("target not specified.")
|
||||||
|
}
|
||||||
|
destination := outbound.Target
|
||||||
if h.config.DestinationOverride != nil {
|
if h.config.DestinationOverride != nil {
|
||||||
server := h.config.DestinationOverride.Server
|
server := h.config.DestinationOverride.Server
|
||||||
if isValidAddress(server.Address) {
|
if isValidAddress(server.Address) {
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"v2ray.com/core/common/buf"
|
"v2ray.com/core/common/buf"
|
||||||
"v2ray.com/core/common/crypto"
|
"v2ray.com/core/common/crypto"
|
||||||
"v2ray.com/core/common/net"
|
"v2ray.com/core/common/net"
|
||||||
|
"v2ray.com/core/common/session"
|
||||||
"v2ray.com/core/common/task"
|
"v2ray.com/core/common/task"
|
||||||
"v2ray.com/core/proxy"
|
"v2ray.com/core/proxy"
|
||||||
)
|
)
|
||||||
@ -20,11 +21,11 @@ func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) Process(ctx context.Context, link *core.Link, dialer proxy.Dialer) error {
|
func (c *Client) Process(ctx context.Context, link *core.Link, dialer proxy.Dialer) error {
|
||||||
dest, ok := proxy.TargetFromContext(ctx)
|
outbound := session.OutboundFromContext(ctx)
|
||||||
if !ok {
|
if outbound == nil || !outbound.Target.IsValid() {
|
||||||
return newError("unknown destination.")
|
return newError("unknown destination.")
|
||||||
}
|
}
|
||||||
|
dest := outbound.Target
|
||||||
if dest.Network != net.Network_TCP {
|
if dest.Network != net.Network_TCP {
|
||||||
return newError("not TCP traffic", dest)
|
return newError("not TCP traffic", dest)
|
||||||
}
|
}
|
||||||
|
@ -45,10 +45,11 @@ func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {
|
|||||||
|
|
||||||
// Process implements OutboundHandler.Process().
|
// Process implements OutboundHandler.Process().
|
||||||
func (c *Client) Process(ctx context.Context, link *core.Link, dialer proxy.Dialer) error {
|
func (c *Client) Process(ctx context.Context, link *core.Link, dialer proxy.Dialer) error {
|
||||||
destination, ok := proxy.TargetFromContext(ctx)
|
outbound := session.OutboundFromContext(ctx)
|
||||||
if !ok {
|
if outbound == nil || !outbound.Target.IsValid() {
|
||||||
return newError("target not specified")
|
return newError("target not specified")
|
||||||
}
|
}
|
||||||
|
destination := outbound.Target
|
||||||
network := destination.Network
|
network := destination.Network
|
||||||
|
|
||||||
var server *protocol.ServerSpec
|
var server *protocol.ServerSpec
|
||||||
|
@ -13,7 +13,6 @@ import (
|
|||||||
"v2ray.com/core/common/session"
|
"v2ray.com/core/common/session"
|
||||||
"v2ray.com/core/common/signal"
|
"v2ray.com/core/common/signal"
|
||||||
"v2ray.com/core/common/task"
|
"v2ray.com/core/common/task"
|
||||||
"v2ray.com/core/proxy"
|
|
||||||
"v2ray.com/core/transport/internet"
|
"v2ray.com/core/transport/internet"
|
||||||
"v2ray.com/core/transport/internet/udp"
|
"v2ray.com/core/transport/internet/udp"
|
||||||
"v2ray.com/core/transport/pipe"
|
"v2ray.com/core/transport/pipe"
|
||||||
@ -99,10 +98,10 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
|
|||||||
for _, payload := range mpayload {
|
for _, payload := range mpayload {
|
||||||
request, data, err := DecodeUDPPacket(s.user, payload)
|
request, data, err := DecodeUDPPacket(s.user, payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if source, ok := proxy.SourceFromContext(ctx); ok {
|
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() {
|
||||||
newError("dropping invalid UDP packet from: ", source).Base(err).WriteToLog(session.ExportIDToError(ctx))
|
newError("dropping invalid UDP packet from: ", inbound.Source).Base(err).WriteToLog(session.ExportIDToError(ctx))
|
||||||
log.Record(&log.AccessMessage{
|
log.Record(&log.AccessMessage{
|
||||||
From: source,
|
From: inbound.Source,
|
||||||
To: "",
|
To: "",
|
||||||
Status: log.AccessRejected,
|
Status: log.AccessRejected,
|
||||||
Reason: err,
|
Reason: err,
|
||||||
@ -125,9 +124,9 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
|
|||||||
}
|
}
|
||||||
|
|
||||||
dest := request.Destination()
|
dest := request.Destination()
|
||||||
if source, ok := proxy.SourceFromContext(ctx); ok {
|
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() {
|
||||||
log.Record(&log.AccessMessage{
|
log.Record(&log.AccessMessage{
|
||||||
From: source,
|
From: inbound.Source,
|
||||||
To: dest,
|
To: dest,
|
||||||
Status: log.AccessAccepted,
|
Status: log.AccessAccepted,
|
||||||
Reason: "",
|
Reason: "",
|
||||||
|
@ -47,10 +47,11 @@ func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {
|
|||||||
|
|
||||||
// Process implements proxy.Outbound.Process.
|
// Process implements proxy.Outbound.Process.
|
||||||
func (c *Client) Process(ctx context.Context, link *core.Link, dialer proxy.Dialer) error {
|
func (c *Client) Process(ctx context.Context, link *core.Link, dialer proxy.Dialer) error {
|
||||||
destination, ok := proxy.TargetFromContext(ctx)
|
outbound := session.OutboundFromContext(ctx)
|
||||||
if !ok {
|
if outbound == nil || !outbound.Target.IsValid() {
|
||||||
return newError("target not specified.")
|
return newError("target not specified.")
|
||||||
}
|
}
|
||||||
|
destination := outbound.Target
|
||||||
|
|
||||||
var server *protocol.ServerSpec
|
var server *protocol.ServerSpec
|
||||||
var conn internet.Connection
|
var conn internet.Connection
|
||||||
|
@ -14,7 +14,6 @@ import (
|
|||||||
"v2ray.com/core/common/session"
|
"v2ray.com/core/common/session"
|
||||||
"v2ray.com/core/common/signal"
|
"v2ray.com/core/common/signal"
|
||||||
"v2ray.com/core/common/task"
|
"v2ray.com/core/common/task"
|
||||||
"v2ray.com/core/proxy"
|
|
||||||
"v2ray.com/core/transport/internet"
|
"v2ray.com/core/transport/internet"
|
||||||
"v2ray.com/core/transport/internet/udp"
|
"v2ray.com/core/transport/internet/udp"
|
||||||
"v2ray.com/core/transport/pipe"
|
"v2ray.com/core/transport/pipe"
|
||||||
@ -73,21 +72,22 @@ func (s *Server) processTCP(ctx context.Context, conn internet.Connection, dispa
|
|||||||
newError("failed to set deadline").Base(err).WriteToLog(session.ExportIDToError(ctx))
|
newError("failed to set deadline").Base(err).WriteToLog(session.ExportIDToError(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
inboundDest, ok := proxy.InboundEntryPointFromContext(ctx)
|
inbound := session.InboundFromContext(ctx)
|
||||||
if !ok {
|
if inbound == nil || !inbound.Gateway.IsValid() {
|
||||||
return newError("inbound entry point not specified")
|
return newError("inbound gateway not specified")
|
||||||
}
|
}
|
||||||
|
|
||||||
svrSession := &ServerSession{
|
svrSession := &ServerSession{
|
||||||
config: s.config,
|
config: s.config,
|
||||||
port: inboundDest.Port,
|
port: inbound.Gateway.Port,
|
||||||
}
|
}
|
||||||
|
|
||||||
reader := &buf.BufferedReader{Reader: buf.NewReader(conn)}
|
reader := &buf.BufferedReader{Reader: buf.NewReader(conn)}
|
||||||
request, err := svrSession.Handshake(reader, conn)
|
request, err := svrSession.Handshake(reader, conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if source, ok := proxy.SourceFromContext(ctx); ok {
|
if inbound != nil && inbound.Source.IsValid() {
|
||||||
log.Record(&log.AccessMessage{
|
log.Record(&log.AccessMessage{
|
||||||
From: source,
|
From: inbound.Source,
|
||||||
To: "",
|
To: "",
|
||||||
Status: log.AccessRejected,
|
Status: log.AccessRejected,
|
||||||
Reason: err,
|
Reason: err,
|
||||||
@ -103,9 +103,9 @@ func (s *Server) processTCP(ctx context.Context, conn internet.Connection, dispa
|
|||||||
if request.Command == protocol.RequestCommandTCP {
|
if request.Command == protocol.RequestCommandTCP {
|
||||||
dest := request.Destination()
|
dest := request.Destination()
|
||||||
newError("TCP Connect request to ", dest).WriteToLog(session.ExportIDToError(ctx))
|
newError("TCP Connect request to ", dest).WriteToLog(session.ExportIDToError(ctx))
|
||||||
if source, ok := proxy.SourceFromContext(ctx); ok {
|
if inbound != nil && inbound.Source.IsValid() {
|
||||||
log.Record(&log.AccessMessage{
|
log.Record(&log.AccessMessage{
|
||||||
From: source,
|
From: inbound.Source,
|
||||||
To: dest,
|
To: dest,
|
||||||
Status: log.AccessAccepted,
|
Status: log.AccessAccepted,
|
||||||
Reason: "",
|
Reason: "",
|
||||||
@ -188,8 +188,8 @@ func (s *Server) handleUDPPayload(ctx context.Context, conn internet.Connection,
|
|||||||
conn.Write(udpMessage.Bytes()) // nolint: errcheck
|
conn.Write(udpMessage.Bytes()) // nolint: errcheck
|
||||||
})
|
})
|
||||||
|
|
||||||
if source, ok := proxy.SourceFromContext(ctx); ok {
|
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() {
|
||||||
newError("client UDP connection from ", source).WriteToLog(session.ExportIDToError(ctx))
|
newError("client UDP connection from ", inbound.Source).WriteToLog(session.ExportIDToError(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
reader := buf.NewReader(conn)
|
reader := buf.NewReader(conn)
|
||||||
@ -214,9 +214,9 @@ func (s *Server) handleUDPPayload(ctx context.Context, conn internet.Connection,
|
|||||||
}
|
}
|
||||||
|
|
||||||
newError("send packet to ", request.Destination(), " with ", payload.Len(), " bytes").AtDebug().WriteToLog(session.ExportIDToError(ctx))
|
newError("send packet to ", request.Destination(), " with ", payload.Len(), " bytes").AtDebug().WriteToLog(session.ExportIDToError(ctx))
|
||||||
if source, ok := proxy.SourceFromContext(ctx); ok {
|
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() {
|
||||||
log.Record(&log.AccessMessage{
|
log.Record(&log.AccessMessage{
|
||||||
From: source,
|
From: inbound.Source,
|
||||||
To: request.Destination(),
|
To: request.Destination(),
|
||||||
Status: log.AccessAccepted,
|
Status: log.AccessAccepted,
|
||||||
Reason: "",
|
Reason: "",
|
||||||
|
@ -68,10 +68,12 @@ func (v *Handler) Process(ctx context.Context, link *core.Link, dialer proxy.Dia
|
|||||||
}
|
}
|
||||||
defer conn.Close() //nolint: errcheck
|
defer conn.Close() //nolint: errcheck
|
||||||
|
|
||||||
target, ok := proxy.TargetFromContext(ctx)
|
outbound := session.OutboundFromContext(ctx)
|
||||||
if !ok {
|
if outbound == nil || !outbound.Target.IsValid() {
|
||||||
return newError("target not specified").AtError()
|
return newError("target not specified").AtError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
target := outbound.Target
|
||||||
newError("tunneling request to ", target, " via ", rec.Destination()).WriteToLog(session.ExportIDToError(ctx))
|
newError("tunneling request to ", target, " via ", rec.Destination()).WriteToLog(session.ExportIDToError(ctx))
|
||||||
|
|
||||||
command := protocol.RequestCommandTCP
|
command := protocol.RequestCommandTCP
|
||||||
|
@ -26,17 +26,6 @@ func StreamSettingsFromContext(ctx context.Context) *MemoryStreamConfig {
|
|||||||
return ss.(*MemoryStreamConfig)
|
return ss.(*MemoryStreamConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ContextWithDialerSource(ctx context.Context, addr net.Address) context.Context {
|
|
||||||
return context.WithValue(ctx, dialerSrcKey, addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func DialerSourceFromContext(ctx context.Context) net.Address {
|
|
||||||
if addr, ok := ctx.Value(dialerSrcKey).(net.Address); ok {
|
|
||||||
return addr
|
|
||||||
}
|
|
||||||
return net.AnyIP
|
|
||||||
}
|
|
||||||
|
|
||||||
func ContextWithBindAddress(ctx context.Context, dest net.Destination) context.Context {
|
func ContextWithBindAddress(ctx context.Context, dest net.Destination) context.Context {
|
||||||
return context.WithValue(ctx, bindAddrKey, dest)
|
return context.WithValue(ctx, bindAddrKey, dest)
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ package internet
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"v2ray.com/core/common/session"
|
||||||
|
|
||||||
"v2ray.com/core/common/net"
|
"v2ray.com/core/common/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -53,6 +55,10 @@ func Dial(ctx context.Context, dest net.Destination) (Connection, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DialSystem calls system dialer to create a network connection.
|
// DialSystem calls system dialer to create a network connection.
|
||||||
func DialSystem(ctx context.Context, src net.Address, dest net.Destination) (net.Conn, error) {
|
func DialSystem(ctx context.Context, dest net.Destination) (net.Conn, error) {
|
||||||
|
var src net.Address
|
||||||
|
if outbound := session.OutboundFromContext(ctx); outbound != nil {
|
||||||
|
src = outbound.Gateway
|
||||||
|
}
|
||||||
return effectiveSystemDialer.Dial(ctx, src, dest)
|
return effectiveSystemDialer.Dial(ctx, src, dest)
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ func TestDialWithLocalAddr(t *testing.T) {
|
|||||||
assert(err, IsNil)
|
assert(err, IsNil)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
conn, err := DialSystem(context.Background(), net.LocalHostIP, net.TCPDestination(net.LocalHostIP, dest.Port))
|
conn, err := DialSystem(context.Background(), net.TCPDestination(net.LocalHostIP, dest.Port))
|
||||||
assert(err, IsNil)
|
assert(err, IsNil)
|
||||||
assert(conn.RemoteAddr().String(), Equals, "127.0.0.1:"+dest.Port.String())
|
assert(conn.RemoteAddr().String(), Equals, "127.0.0.1:"+dest.Port.String())
|
||||||
conn.Close()
|
conn.Close()
|
||||||
|
@ -53,7 +53,7 @@ func getHTTPClient(ctx context.Context, dest net.Destination) (*http.Client, err
|
|||||||
}
|
}
|
||||||
address := net.ParseAddress(rawHost)
|
address := net.ParseAddress(rawHost)
|
||||||
|
|
||||||
pconn, err := internet.DialSystem(context.Background(), nil, net.TCPDestination(address, port))
|
pconn, err := internet.DialSystem(context.Background(), net.TCPDestination(address, port))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -49,8 +49,7 @@ func DialKCP(ctx context.Context, dest net.Destination) (internet.Connection, er
|
|||||||
dest.Network = net.Network_UDP
|
dest.Network = net.Network_UDP
|
||||||
newError("dialing mKCP to ", dest).WriteToLog()
|
newError("dialing mKCP to ", dest).WriteToLog()
|
||||||
|
|
||||||
src := internet.DialerSourceFromContext(ctx)
|
rawConn, err := internet.DialSystem(ctx, dest)
|
||||||
rawConn, err := internet.DialSystem(ctx, src, dest)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newError("failed to dial to dest: ", err).AtWarning().Base(err)
|
return nil, newError("failed to dial to dest: ", err).AtWarning().Base(err)
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,7 @@ func getTCPSettingsFromContext(ctx context.Context) *Config {
|
|||||||
// Dial dials a new TCP connection to the given destination.
|
// Dial dials a new TCP connection to the given destination.
|
||||||
func Dial(ctx context.Context, dest net.Destination) (internet.Connection, error) {
|
func Dial(ctx context.Context, dest net.Destination) (internet.Connection, error) {
|
||||||
newError("dialing TCP to ", dest).WriteToLog(session.ExportIDToError(ctx))
|
newError("dialing TCP to ", dest).WriteToLog(session.ExportIDToError(ctx))
|
||||||
src := internet.DialerSourceFromContext(ctx)
|
conn, err := internet.DialSystem(ctx, dest)
|
||||||
|
|
||||||
conn, err := internet.DialSystem(ctx, src, dest)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,7 @@ import (
|
|||||||
func init() {
|
func init() {
|
||||||
common.Must(internet.RegisterTransportDialer(protocolName,
|
common.Must(internet.RegisterTransportDialer(protocolName,
|
||||||
func(ctx context.Context, dest net.Destination) (internet.Connection, error) {
|
func(ctx context.Context, dest net.Destination) (internet.Connection, error) {
|
||||||
src := internet.DialerSourceFromContext(ctx)
|
conn, err := internet.DialSystem(ctx, dest)
|
||||||
conn, err := internet.DialSystem(ctx, src, dest)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -29,12 +29,11 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func dialWebsocket(ctx context.Context, dest net.Destination) (net.Conn, error) {
|
func dialWebsocket(ctx context.Context, dest net.Destination) (net.Conn, error) {
|
||||||
src := internet.DialerSourceFromContext(ctx)
|
|
||||||
wsSettings := internet.StreamSettingsFromContext(ctx).ProtocolSettings.(*Config)
|
wsSettings := internet.StreamSettingsFromContext(ctx).ProtocolSettings.(*Config)
|
||||||
|
|
||||||
dialer := &websocket.Dialer{
|
dialer := &websocket.Dialer{
|
||||||
NetDial: func(network, addr string) (net.Conn, error) {
|
NetDial: func(network, addr string) (net.Conn, error) {
|
||||||
return internet.DialSystem(ctx, src, dest)
|
return internet.DialSystem(ctx, dest)
|
||||||
},
|
},
|
||||||
ReadBufferSize: 4 * 1024,
|
ReadBufferSize: 4 * 1024,
|
||||||
WriteBufferSize: 4 * 1024,
|
WriteBufferSize: 4 * 1024,
|
||||||
|
Loading…
Reference in New Issue
Block a user