| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 | 
							- package core
 
- import (
 
- 	"context"
 
- 	"sync"
 
- 	"v2ray.com/core/common/errors"
 
- 	"v2ray.com/core/common/net"
 
- 	"v2ray.com/core/transport/ray"
 
- )
 
- // Dispatcher is a feature that dispatches inbound requests to outbound handlers based on rules.
 
- // Dispatcher is required to be registered in a V2Ray instance to make V2Ray function properly.
 
- type Dispatcher interface {
 
- 	Feature
 
- 	// Dispatch returns a Ray for transporting data for the given request.
 
- 	Dispatch(ctx context.Context, dest net.Destination) (ray.InboundRay, error)
 
- }
 
- type syncDispatcher struct {
 
- 	sync.RWMutex
 
- 	Dispatcher
 
- }
 
- func (d *syncDispatcher) Dispatch(ctx context.Context, dest net.Destination) (ray.InboundRay, error) {
 
- 	d.RLock()
 
- 	defer d.RUnlock()
 
- 	if d.Dispatcher == nil {
 
- 		return nil, newError("Dispatcher not set.").AtError()
 
- 	}
 
- 	return d.Dispatcher.Dispatch(ctx, dest)
 
- }
 
- func (d *syncDispatcher) Start() error {
 
- 	d.RLock()
 
- 	defer d.RUnlock()
 
- 	if d.Dispatcher == nil {
 
- 		return newError("Dispatcher not set.").AtError()
 
- 	}
 
- 	return d.Dispatcher.Start()
 
- }
 
- func (d *syncDispatcher) Close() {
 
- 	d.RLock()
 
- 	defer d.RUnlock()
 
- 	if d.Dispatcher != nil {
 
- 		d.Dispatcher.Close()
 
- 	}
 
- }
 
- func (d *syncDispatcher) Set(disp Dispatcher) {
 
- 	d.Lock()
 
- 	defer d.Unlock()
 
- 	d.Dispatcher = disp
 
- }
 
- var (
 
- 	// ErrNoClue is for the situation that existing information is not enough to make a decision. For example, Router may return this error when there is no suitable route.
 
- 	ErrNoClue = errors.New("not enough information for making a decision")
 
- )
 
- // Router is a feature to choose a outbound tag for the given request.
 
- type Router interface {
 
- 	Feature
 
- 	// PickRoute returns a tag of an OutboundHandler based on the given context.
 
- 	PickRoute(ctx context.Context) (string, error)
 
- }
 
- type syncRouter struct {
 
- 	sync.RWMutex
 
- 	Router
 
- }
 
- func (r *syncRouter) PickRoute(ctx context.Context) (string, error) {
 
- 	r.RLock()
 
- 	defer r.RUnlock()
 
- 	if r.Router == nil {
 
- 		return "", ErrNoClue
 
- 	}
 
- 	return r.Router.PickRoute(ctx)
 
- }
 
- func (r *syncRouter) Start() error {
 
- 	r.RLock()
 
- 	defer r.RUnlock()
 
- 	if r.Router == nil {
 
- 		return nil
 
- 	}
 
- 	return r.Router.Start()
 
- }
 
- func (r *syncRouter) Close() {
 
- 	r.RLock()
 
- 	defer r.RUnlock()
 
- 	if r.Router != nil {
 
- 		r.Router.Close()
 
- 	}
 
- }
 
- func (r *syncRouter) Set(router Router) {
 
- 	r.Lock()
 
- 	defer r.Unlock()
 
- 	r.Router = router
 
- }
 
 
  |