123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- package shadowtls
- import (
- "context"
- "os"
- "github.com/sagernet/sing-shadowtls"
- sing_common "github.com/sagernet/sing/common"
- "github.com/sagernet/sing/common/auth"
- E "github.com/sagernet/sing/common/exceptions"
- M "github.com/sagernet/sing/common/metadata"
- N "github.com/sagernet/sing/common/network"
- "github.com/xtls/xray-core/common"
- "github.com/xtls/xray-core/common/log"
- "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/common/singbridge"
- "github.com/xtls/xray-core/core"
- "github.com/xtls/xray-core/features/inbound"
- "github.com/xtls/xray-core/features/routing"
- "github.com/xtls/xray-core/proxy"
- "github.com/xtls/xray-core/transport/internet/stat"
- )
- func init() {
- common.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
- return NewServer(ctx, config.(*ServerConfig))
- }))
- }
- type Inbound struct {
- service *shadowtls.Service
- inboundManager inbound.Manager
- detour string
- }
- func NewServer(ctx context.Context, config *ServerConfig) (*Inbound, error) {
- v := core.MustFromContext(ctx)
- inbound := &Inbound{
- inboundManager: v.GetFeature(inbound.ManagerType()).(inbound.Manager),
- detour: config.Detour,
- }
- var handshakeForServerName map[string]shadowtls.HandshakeConfig
- if config.Version > 1 {
- handshakeForServerName = make(map[string]shadowtls.HandshakeConfig)
- for serverName, serverConfig := range config.HandshakeForServerName {
- handshakeForServerName[serverName] = shadowtls.HandshakeConfig{
- Server: singbridge.ToSocksaddr(net.Destination{
- Address: serverConfig.Address.AsAddress(),
- Port: net.Port(serverConfig.Port),
- }),
- Dialer: N.SystemDialer,
- }
- }
- }
- service, err := shadowtls.NewService(shadowtls.ServiceConfig{
- Version: int(config.Version),
- Password: config.Password,
- Users: sing_common.Map(config.Users, func(it *User) shadowtls.User {
- return shadowtls.User{
- Name: it.Email,
- Password: it.Password,
- }
- }),
- Handshake: shadowtls.HandshakeConfig{
- Server: singbridge.ToSocksaddr(net.Destination{
- Address: config.Handshake.Address.AsAddress(),
- Port: net.Port(config.Handshake.Port),
- }),
- Dialer: N.SystemDialer,
- },
- HandshakeForServerName: handshakeForServerName,
- StrictMode: config.StrictMode,
- Handler: inbound,
- Logger: singbridge.NewLogger(newError),
- })
- if err != nil {
- return nil, E.Cause(err, "create service")
- }
- inbound.service = service
- return inbound, nil
- }
- func (i *Inbound) Network() []net.Network {
- return []net.Network{net.Network_TCP}
- }
- func (i *Inbound) Process(ctx context.Context, network net.Network, connection stat.Connection, dispatcher routing.Dispatcher) error {
- inbound := session.InboundFromContext(ctx)
- var metadata M.Metadata
- if inbound.Source.IsValid() {
- metadata.Source = M.ParseSocksaddr(inbound.Source.NetAddr())
- }
- ctx = session.ContextWithDispatcher(ctx, dispatcher)
- return singbridge.ReturnError(i.service.NewConnection(ctx, connection, metadata))
- }
- func (i *Inbound) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
- inboundHandler, err := i.inboundManager.GetHandler(ctx, i.detour)
- if err != nil {
- return E.Cause(err, "detour not found")
- }
- inboundWrapper, loaded := inboundHandler.(proxy.GetInbound)
- if !loaded {
- return newError("can't get inbound proxy from handler.")
- }
- inboundDetour := inboundWrapper.GetInbound()
- email, _ := auth.UserFromContext[string](ctx)
- inbound := session.InboundFromContext(ctx)
- inbound.User = &protocol.MemoryUser{
- Email: email,
- }
- ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
- From: metadata.Source,
- To: metadata.Destination,
- Status: log.AccessAccepted,
- Email: email,
- })
- newError("tunnelling request to detour").WriteToLog(session.ExportIDToError(ctx))
- return inboundDetour.Process(ctx, net.Network_TCP, conn, session.DispatcherFromContext(ctx))
- }
- func (i *Inbound) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
- return os.ErrInvalid
- }
- func (i *Inbound) NewError(ctx context.Context, err error) {
- if E.IsClosed(err) {
- return
- }
- newError(err).AtWarning().WriteToLog()
- }
|