| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- package tun
- import (
- "context"
- "github.com/xtls/xray-core/common"
- "github.com/xtls/xray-core/common/buf"
- c "github.com/xtls/xray-core/common/ctx"
- "github.com/xtls/xray-core/common/errors"
- "github.com/xtls/xray-core/common/net"
- "github.com/xtls/xray-core/common/protocol"
- "github.com/xtls/xray-core/common/session"
- "github.com/xtls/xray-core/core"
- "github.com/xtls/xray-core/features/policy"
- "github.com/xtls/xray-core/features/routing"
- "github.com/xtls/xray-core/transport"
- "github.com/xtls/xray-core/transport/internet/stat"
- )
- // Handler is managing object that tie together tun interface, ip stack and dispatch connections to the routing
- type Handler struct {
- ctx context.Context
- config *Config
- stack Stack
- policyManager policy.Manager
- dispatcher routing.Dispatcher
- }
- // ConnectionHandler interface with the only method that stack is going to push new connections to
- type ConnectionHandler interface {
- HandleConnection(conn net.Conn, destination net.Destination)
- }
- // Handler implements ConnectionHandler
- var _ ConnectionHandler = (*Handler)(nil)
- func (t *Handler) policy() policy.Session {
- p := t.policyManager.ForLevel(t.config.UserLevel)
- return p
- }
- // Init the Handler instance with necessary parameters
- func (t *Handler) Init(ctx context.Context, pm policy.Manager, dispatcher routing.Dispatcher) error {
- var err error
- t.ctx = core.ToBackgroundDetachedContext(ctx)
- t.policyManager = pm
- t.dispatcher = dispatcher
- tunName := t.config.Name
- tunOptions := TunOptions{
- Name: tunName,
- MTU: t.config.MTU,
- }
- tunInterface, err := NewTun(tunOptions)
- if err != nil {
- return err
- }
- errors.LogInfo(t.ctx, tunName, " created")
- tunStackOptions := StackOptions{
- Tun: tunInterface,
- IdleTimeout: pm.ForLevel(t.config.UserLevel).Timeouts.ConnectionIdle,
- }
- tunStack, err := NewStack(t.ctx, tunStackOptions, t)
- if err != nil {
- _ = tunInterface.Close()
- return err
- }
- err = tunStack.Start()
- if err != nil {
- _ = tunStack.Close()
- _ = tunInterface.Close()
- return err
- }
- err = tunInterface.Start()
- if err != nil {
- _ = tunStack.Close()
- _ = tunInterface.Close()
- return err
- }
- t.stack = tunStack
- errors.LogInfo(t.ctx, tunName, " up")
- return nil
- }
- // HandleConnection pass the connection coming from the ip stack to the routing dispatcher
- func (t *Handler) HandleConnection(conn net.Conn, destination net.Destination) {
- sid := session.NewID()
- ctx := c.ContextWithID(t.ctx, sid)
- errors.LogInfo(ctx, "processing connection from: ", conn.RemoteAddr())
- inbound := session.Inbound{}
- inbound.Name = "tun"
- inbound.CanSpliceCopy = 1
- inbound.Source = net.DestinationFromAddr(conn.RemoteAddr())
- inbound.User = &protocol.MemoryUser{
- Level: t.config.UserLevel,
- }
- ctx = session.ContextWithInbound(ctx, &inbound)
- ctx = session.SubContextFromMuxInbound(ctx)
- link := &transport.Link{
- Reader: &buf.TimeoutWrapperReader{Reader: buf.NewReader(conn)},
- Writer: buf.NewWriter(conn),
- }
- if err := t.dispatcher.DispatchLink(ctx, destination, link); err != nil {
- errors.LogError(ctx, errors.New("connection closed").Base(err))
- return
- }
- errors.LogInfo(ctx, "connection completed")
- }
- // Network implements proxy.Inbound
- // and exists only to comply to proxy interface, declaring it doesn't listen on any network,
- // making the process not open any port for this inbound (input will be network interface)
- func (t *Handler) Network() []net.Network {
- return []net.Network{}
- }
- // Process implements proxy.Inbound
- // and exists only to comply to proxy interface, which should never get any inputs due to no listening ports
- func (t *Handler) Process(ctx context.Context, network net.Network, conn stat.Connection, dispatcher routing.Dispatcher) error {
- return nil
- }
- func init() {
- common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
- t := &Handler{config: config.(*Config)}
- err := core.RequireFeatures(ctx, func(pm policy.Manager, dispatcher routing.Dispatcher) error {
- return t.Init(ctx, pm, dispatcher)
- })
- return t, err
- }))
- }
|