mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-04-30 01:08:33 +00:00
v1.0.0
This commit is contained in:
parent
47d23e9972
commit
c7f7c08ead
711 changed files with 82154 additions and 2 deletions
40
features/routing/context.go
Normal file
40
features/routing/context.go
Normal file
|
@ -0,0 +1,40 @@
|
|||
package routing
|
||||
|
||||
import (
|
||||
"github.com/xtls/xray-core/v1/common/net"
|
||||
)
|
||||
|
||||
// Context is a feature to store connection information for routing.
|
||||
//
|
||||
// xray:api:stable
|
||||
type Context interface {
|
||||
// GetInboundTag returns the tag of the inbound the connection was from.
|
||||
GetInboundTag() string
|
||||
|
||||
// GetSourcesIPs returns the source IPs bound to the connection.
|
||||
GetSourceIPs() []net.IP
|
||||
|
||||
// GetSourcePort returns the source port of the connection.
|
||||
GetSourcePort() net.Port
|
||||
|
||||
// GetTargetIPs returns the target IP of the connection or resolved IPs of target domain.
|
||||
GetTargetIPs() []net.IP
|
||||
|
||||
// GetTargetPort returns the target port of the connection.
|
||||
GetTargetPort() net.Port
|
||||
|
||||
// GetTargetDomain returns the target domain of the connection, if exists.
|
||||
GetTargetDomain() string
|
||||
|
||||
// GetNetwork returns the network type of the connection.
|
||||
GetNetwork() net.Network
|
||||
|
||||
// GetProtocol returns the protocol from the connection content, if sniffed out.
|
||||
GetProtocol() string
|
||||
|
||||
// GetUser returns the user email from the connection content, if exists.
|
||||
GetUser() string
|
||||
|
||||
// GetAttributes returns extra attributes from the conneciont content.
|
||||
GetAttributes() map[string]string
|
||||
}
|
27
features/routing/dispatcher.go
Normal file
27
features/routing/dispatcher.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
package routing
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/xtls/xray-core/v1/common/net"
|
||||
"github.com/xtls/xray-core/v1/features"
|
||||
"github.com/xtls/xray-core/v1/transport"
|
||||
)
|
||||
|
||||
// Dispatcher is a feature that dispatches inbound requests to outbound handlers based on rules.
|
||||
// Dispatcher is required to be registered in a Xray instance to make Xray function properly.
|
||||
//
|
||||
// xray:api:stable
|
||||
type Dispatcher interface {
|
||||
features.Feature
|
||||
|
||||
// Dispatch returns a Ray for transporting data for the given request.
|
||||
Dispatch(ctx context.Context, dest net.Destination) (*transport.Link, error)
|
||||
}
|
||||
|
||||
// DispatcherType returns the type of Dispatcher interface. Can be used to implement common.HasType.
|
||||
//
|
||||
// xray:api:stable
|
||||
func DispatcherType() interface{} {
|
||||
return (*Dispatcher)(nil)
|
||||
}
|
44
features/routing/dns/context.go
Normal file
44
features/routing/dns/context.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
package dns
|
||||
|
||||
//go:generate go run github.com/xtls/xray-core/v1/common/errors/errorgen
|
||||
|
||||
import (
|
||||
"github.com/xtls/xray-core/v1/common/net"
|
||||
"github.com/xtls/xray-core/v1/features/dns"
|
||||
"github.com/xtls/xray-core/v1/features/routing"
|
||||
)
|
||||
|
||||
// ResolvableContext is an implementation of routing.Context, with domain resolving capability.
|
||||
type ResolvableContext struct {
|
||||
routing.Context
|
||||
dnsClient dns.Client
|
||||
resolvedIPs []net.IP
|
||||
}
|
||||
|
||||
// GetTargetIPs overrides original routing.Context's implementation.
|
||||
func (ctx *ResolvableContext) GetTargetIPs() []net.IP {
|
||||
if ips := ctx.Context.GetTargetIPs(); len(ips) != 0 {
|
||||
return ips
|
||||
}
|
||||
|
||||
if len(ctx.resolvedIPs) > 0 {
|
||||
return ctx.resolvedIPs
|
||||
}
|
||||
|
||||
if domain := ctx.GetTargetDomain(); len(domain) != 0 {
|
||||
ips, err := ctx.dnsClient.LookupIP(domain)
|
||||
if err == nil {
|
||||
ctx.resolvedIPs = ips
|
||||
return ips
|
||||
}
|
||||
newError("resolve ip for ", domain).Base(err).WriteToLog()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextWithDNSClient creates a new routing context with domain resolving capability.
|
||||
// Resolved domain IPs can be retrieved by GetTargetIPs().
|
||||
func ContextWithDNSClient(ctx routing.Context, client dns.Client) routing.Context {
|
||||
return &ResolvableContext{Context: ctx, dnsClient: client}
|
||||
}
|
9
features/routing/dns/errors.generated.go
Normal file
9
features/routing/dns/errors.generated.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
package dns
|
||||
|
||||
import "github.com/xtls/xray-core/v1/common/errors"
|
||||
|
||||
type errPathObjHolder struct{}
|
||||
|
||||
func newError(values ...interface{}) *errors.Error {
|
||||
return errors.New(values...).WithPathObj(errPathObjHolder{})
|
||||
}
|
60
features/routing/router.go
Normal file
60
features/routing/router.go
Normal file
|
@ -0,0 +1,60 @@
|
|||
package routing
|
||||
|
||||
import (
|
||||
"github.com/xtls/xray-core/v1/common"
|
||||
"github.com/xtls/xray-core/v1/features"
|
||||
)
|
||||
|
||||
// Router is a feature to choose an outbound tag for the given request.
|
||||
//
|
||||
// xray:api:stable
|
||||
type Router interface {
|
||||
features.Feature
|
||||
|
||||
// PickRoute returns a route decision based on the given routing context.
|
||||
PickRoute(ctx Context) (Route, error)
|
||||
}
|
||||
|
||||
// Route is the routing result of Router feature.
|
||||
//
|
||||
// xray:api:stable
|
||||
type Route interface {
|
||||
// A Route is also a routing context.
|
||||
Context
|
||||
|
||||
// GetOutboundGroupTags returns the detoured outbound group tags in sequence before a final outbound is chosen.
|
||||
GetOutboundGroupTags() []string
|
||||
|
||||
// GetOutboundTag returns the tag of the outbound the connection was dispatched to.
|
||||
GetOutboundTag() string
|
||||
}
|
||||
|
||||
// RouterType return the type of Router interface. Can be used to implement common.HasType.
|
||||
//
|
||||
// xray:api:stable
|
||||
func RouterType() interface{} {
|
||||
return (*Router)(nil)
|
||||
}
|
||||
|
||||
// DefaultRouter is an implementation of Router, which always returns ErrNoClue for routing decisions.
|
||||
type DefaultRouter struct{}
|
||||
|
||||
// Type implements common.HasType.
|
||||
func (DefaultRouter) Type() interface{} {
|
||||
return RouterType()
|
||||
}
|
||||
|
||||
// PickRoute implements Router.
|
||||
func (DefaultRouter) PickRoute(ctx Context) (Route, error) {
|
||||
return nil, common.ErrNoClue
|
||||
}
|
||||
|
||||
// Start implements common.Runnable.
|
||||
func (DefaultRouter) Start() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close implements common.Closable.
|
||||
func (DefaultRouter) Close() error {
|
||||
return nil
|
||||
}
|
119
features/routing/session/context.go
Normal file
119
features/routing/session/context.go
Normal file
|
@ -0,0 +1,119 @@
|
|||
package session
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/xtls/xray-core/v1/common/net"
|
||||
"github.com/xtls/xray-core/v1/common/session"
|
||||
"github.com/xtls/xray-core/v1/features/routing"
|
||||
)
|
||||
|
||||
// Context is an implementation of routing.Context, which is a wrapper of context.context with session info.
|
||||
type Context struct {
|
||||
Inbound *session.Inbound
|
||||
Outbound *session.Outbound
|
||||
Content *session.Content
|
||||
}
|
||||
|
||||
// GetInboundTag implements routing.Context.
|
||||
func (ctx *Context) GetInboundTag() string {
|
||||
if ctx.Inbound == nil {
|
||||
return ""
|
||||
}
|
||||
return ctx.Inbound.Tag
|
||||
}
|
||||
|
||||
// GetSourceIPs implements routing.Context.
|
||||
func (ctx *Context) GetSourceIPs() []net.IP {
|
||||
if ctx.Inbound == nil || !ctx.Inbound.Source.IsValid() {
|
||||
return nil
|
||||
}
|
||||
dest := ctx.Inbound.Source
|
||||
if dest.Address.Family().IsDomain() {
|
||||
return nil
|
||||
}
|
||||
|
||||
return []net.IP{dest.Address.IP()}
|
||||
}
|
||||
|
||||
// GetSourcePort implements routing.Context.
|
||||
func (ctx *Context) GetSourcePort() net.Port {
|
||||
if ctx.Inbound == nil || !ctx.Inbound.Source.IsValid() {
|
||||
return 0
|
||||
}
|
||||
return ctx.Inbound.Source.Port
|
||||
}
|
||||
|
||||
// GetTargetIPs implements routing.Context.
|
||||
func (ctx *Context) GetTargetIPs() []net.IP {
|
||||
if ctx.Outbound == nil || !ctx.Outbound.Target.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if ctx.Outbound.Target.Address.Family().IsIP() {
|
||||
return []net.IP{ctx.Outbound.Target.Address.IP()}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetTargetPort implements routing.Context.
|
||||
func (ctx *Context) GetTargetPort() net.Port {
|
||||
if ctx.Outbound == nil || !ctx.Outbound.Target.IsValid() {
|
||||
return 0
|
||||
}
|
||||
return ctx.Outbound.Target.Port
|
||||
}
|
||||
|
||||
// GetTargetDomain implements routing.Context.
|
||||
func (ctx *Context) GetTargetDomain() string {
|
||||
if ctx.Outbound == nil || !ctx.Outbound.Target.IsValid() {
|
||||
return ""
|
||||
}
|
||||
dest := ctx.Outbound.Target
|
||||
if !dest.Address.Family().IsDomain() {
|
||||
return ""
|
||||
}
|
||||
return dest.Address.Domain()
|
||||
}
|
||||
|
||||
// GetNetwork implements routing.Context.
|
||||
func (ctx *Context) GetNetwork() net.Network {
|
||||
if ctx.Outbound == nil {
|
||||
return net.Network_Unknown
|
||||
}
|
||||
return ctx.Outbound.Target.Network
|
||||
}
|
||||
|
||||
// GetProtocol implements routing.Context.
|
||||
func (ctx *Context) GetProtocol() string {
|
||||
if ctx.Content == nil {
|
||||
return ""
|
||||
}
|
||||
return ctx.Content.Protocol
|
||||
}
|
||||
|
||||
// GetUser implements routing.Context.
|
||||
func (ctx *Context) GetUser() string {
|
||||
if ctx.Inbound == nil || ctx.Inbound.User == nil {
|
||||
return ""
|
||||
}
|
||||
return ctx.Inbound.User.Email
|
||||
}
|
||||
|
||||
// GetAttributes implements routing.Context.
|
||||
func (ctx *Context) GetAttributes() map[string]string {
|
||||
if ctx.Content == nil {
|
||||
return nil
|
||||
}
|
||||
return ctx.Content.Attributes
|
||||
}
|
||||
|
||||
// AsRoutingContext creates a context from context.context with session info.
|
||||
func AsRoutingContext(ctx context.Context) routing.Context {
|
||||
return &Context{
|
||||
Inbound: session.InboundFromContext(ctx),
|
||||
Outbound: session.OutboundFromContext(ctx),
|
||||
Content: session.ContentFromContext(ctx),
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue