2023-06-07 13:18:56 -04:00
|
|
|
package xray
|
|
|
|
|
|
|
|
import (
|
2023-10-19 01:18:07 -04:00
|
|
|
"fmt"
|
2023-07-21 14:38:07 -04:00
|
|
|
"os"
|
|
|
|
"sync"
|
|
|
|
|
2023-07-29 07:27:15 -04:00
|
|
|
"github.com/InazumaV/V2bX/conf"
|
|
|
|
vCore "github.com/InazumaV/V2bX/core"
|
|
|
|
"github.com/InazumaV/V2bX/core/xray/app/dispatcher"
|
|
|
|
_ "github.com/InazumaV/V2bX/core/xray/distro/all"
|
2023-06-07 13:18:56 -04:00
|
|
|
"github.com/goccy/go-json"
|
2023-06-29 23:07:27 -04:00
|
|
|
log "github.com/sirupsen/logrus"
|
2023-06-07 13:18:56 -04:00
|
|
|
"github.com/xtls/xray-core/app/proxyman"
|
|
|
|
"github.com/xtls/xray-core/app/stats"
|
|
|
|
"github.com/xtls/xray-core/common/serial"
|
|
|
|
"github.com/xtls/xray-core/core"
|
|
|
|
"github.com/xtls/xray-core/features/inbound"
|
|
|
|
"github.com/xtls/xray-core/features/outbound"
|
|
|
|
"github.com/xtls/xray-core/features/routing"
|
|
|
|
statsFeature "github.com/xtls/xray-core/features/stats"
|
|
|
|
coreConf "github.com/xtls/xray-core/infra/conf"
|
|
|
|
)
|
|
|
|
|
2023-10-26 01:06:43 -04:00
|
|
|
var _ vCore.Core = (*Xray)(nil)
|
|
|
|
|
2023-06-07 13:18:56 -04:00
|
|
|
func init() {
|
|
|
|
vCore.RegisterCore("xray", New)
|
|
|
|
}
|
|
|
|
|
2023-10-26 01:06:43 -04:00
|
|
|
// Xray Structure
|
|
|
|
type Xray struct {
|
2023-06-07 13:18:56 -04:00
|
|
|
access sync.Mutex
|
|
|
|
Server *core.Instance
|
|
|
|
ihm inbound.Manager
|
|
|
|
ohm outbound.Manager
|
|
|
|
shm statsFeature.Manager
|
|
|
|
dispatcher *dispatcher.DefaultDispatcher
|
|
|
|
}
|
|
|
|
|
|
|
|
func New(c *conf.CoreConfig) (vCore.Core, error) {
|
2023-10-26 01:06:43 -04:00
|
|
|
return &Xray{Server: getCore(c.XrayConfig)}, nil
|
2023-06-07 13:18:56 -04:00
|
|
|
}
|
|
|
|
|
2023-07-29 06:47:47 -04:00
|
|
|
func parseConnectionConfig(c *conf.XrayConnectionConfig) (policy *coreConf.Policy) {
|
2023-06-07 13:18:56 -04:00
|
|
|
policy = &coreConf.Policy{
|
|
|
|
StatsUserUplink: true,
|
|
|
|
StatsUserDownlink: true,
|
|
|
|
Handshake: &c.Handshake,
|
|
|
|
ConnectionIdle: &c.ConnIdle,
|
|
|
|
UplinkOnly: &c.UplinkOnly,
|
|
|
|
DownlinkOnly: &c.DownlinkOnly,
|
|
|
|
BufferSize: &c.BufferSize,
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func getCore(c *conf.XrayConfig) *core.Instance {
|
2023-06-09 09:20:41 -04:00
|
|
|
os.Setenv("XRAY_LOCATION_ASSET", c.AssetPath)
|
2023-06-07 13:18:56 -04:00
|
|
|
// Log Config
|
|
|
|
coreLogConfig := &coreConf.LogConfig{}
|
|
|
|
coreLogConfig.LogLevel = c.LogConfig.Level
|
|
|
|
coreLogConfig.AccessLog = c.LogConfig.AccessPath
|
|
|
|
coreLogConfig.ErrorLog = c.LogConfig.ErrorPath
|
|
|
|
// DNS config
|
|
|
|
coreDnsConfig := &coreConf.DNSConfig{}
|
2023-07-19 00:03:09 -04:00
|
|
|
os.Setenv("XRAY_DNS_PATH", "")
|
2023-06-07 13:18:56 -04:00
|
|
|
if c.DnsConfigPath != "" {
|
2023-10-19 01:18:07 -04:00
|
|
|
f, err := os.OpenFile(c.DnsConfigPath, os.O_RDWR|os.O_CREATE, 0755)
|
|
|
|
if err != nil {
|
|
|
|
log.Error("Failed to open or create xray dns config file: %v", err)
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
if err := json.NewDecoder(f).Decode(coreDnsConfig); err != nil {
|
|
|
|
log.Error(fmt.Sprintf("Failed to unmarshal xray dns config from file '%v': %v. Using default DNS options.", f.Name(), err))
|
|
|
|
coreDnsConfig = &coreConf.DNSConfig{}
|
2023-06-07 13:18:56 -04:00
|
|
|
}
|
2023-07-19 00:03:09 -04:00
|
|
|
os.Setenv("XRAY_DNS_PATH", c.DnsConfigPath)
|
2023-06-07 13:18:56 -04:00
|
|
|
}
|
|
|
|
dnsConfig, err := coreDnsConfig.Build()
|
|
|
|
if err != nil {
|
2023-06-29 23:07:27 -04:00
|
|
|
log.WithField("err", err).Panic("Failed to understand DNS config, Please check: https://xtls.github.io/config/dns.html for help")
|
2023-06-07 13:18:56 -04:00
|
|
|
}
|
|
|
|
// Routing config
|
|
|
|
coreRouterConfig := &coreConf.RouterConfig{}
|
|
|
|
if c.RouteConfigPath != "" {
|
|
|
|
if f, err := os.Open(c.RouteConfigPath); err != nil {
|
2023-06-29 23:07:27 -04:00
|
|
|
log.WithField("err", err).Panic("Failed to read Routing config file")
|
2023-06-07 13:18:56 -04:00
|
|
|
} else {
|
|
|
|
if err = json.NewDecoder(f).Decode(coreRouterConfig); err != nil {
|
2023-06-29 23:07:27 -04:00
|
|
|
log.WithField("err", err).Panic("Failed to unmarshal Routing config")
|
2023-06-07 13:18:56 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
routeConfig, err := coreRouterConfig.Build()
|
|
|
|
if err != nil {
|
2023-06-29 23:07:27 -04:00
|
|
|
log.WithField("err", err).Panic("Failed to understand Routing config Please check: https://xtls.github.io/config/routing.html")
|
2023-06-07 13:18:56 -04:00
|
|
|
}
|
|
|
|
// Custom Inbound config
|
|
|
|
var coreCustomInboundConfig []coreConf.InboundDetourConfig
|
|
|
|
if c.InboundConfigPath != "" {
|
|
|
|
if f, err := os.Open(c.InboundConfigPath); err != nil {
|
2023-06-29 23:07:27 -04:00
|
|
|
log.WithField("err", err).Panic("Failed to read Custom Inbound config file")
|
2023-06-07 13:18:56 -04:00
|
|
|
} else {
|
|
|
|
if err = json.NewDecoder(f).Decode(&coreCustomInboundConfig); err != nil {
|
2023-06-29 23:07:27 -04:00
|
|
|
log.WithField("err", err).Panic("Failed to unmarshal Custom Inbound config")
|
2023-06-07 13:18:56 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var inBoundConfig []*core.InboundHandlerConfig
|
|
|
|
for _, config := range coreCustomInboundConfig {
|
|
|
|
oc, err := config.Build()
|
|
|
|
if err != nil {
|
2023-06-29 23:07:27 -04:00
|
|
|
log.WithField("err", err).Panic("Failed to understand Inbound config, Please check: https://xtls.github.io/config/inbound.html for help")
|
2023-06-07 13:18:56 -04:00
|
|
|
}
|
|
|
|
inBoundConfig = append(inBoundConfig, oc)
|
|
|
|
}
|
|
|
|
// Custom Outbound config
|
|
|
|
var coreCustomOutboundConfig []coreConf.OutboundDetourConfig
|
|
|
|
if c.OutboundConfigPath != "" {
|
|
|
|
if f, err := os.Open(c.OutboundConfigPath); err != nil {
|
2023-06-29 23:07:27 -04:00
|
|
|
log.WithField("err", err).Panic("Failed to read Custom Outbound config file")
|
2023-06-07 13:18:56 -04:00
|
|
|
} else {
|
|
|
|
if err = json.NewDecoder(f).Decode(&coreCustomOutboundConfig); err != nil {
|
2023-06-29 23:07:27 -04:00
|
|
|
log.WithField("err", err).Panic("Failed to unmarshal Custom Outbound config")
|
2023-06-07 13:18:56 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var outBoundConfig []*core.OutboundHandlerConfig
|
|
|
|
for _, config := range coreCustomOutboundConfig {
|
|
|
|
oc, err := config.Build()
|
|
|
|
if err != nil {
|
2023-06-29 23:07:27 -04:00
|
|
|
log.WithField("err", err).Panic("Failed to understand Outbound config, Please check: https://xtls.github.io/config/outbound.html for help")
|
2023-06-07 13:18:56 -04:00
|
|
|
}
|
|
|
|
outBoundConfig = append(outBoundConfig, oc)
|
|
|
|
}
|
|
|
|
// Policy config
|
|
|
|
levelPolicyConfig := parseConnectionConfig(c.ConnectionConfig)
|
|
|
|
corePolicyConfig := &coreConf.PolicyConfig{}
|
|
|
|
corePolicyConfig.Levels = map[uint32]*coreConf.Policy{0: levelPolicyConfig}
|
|
|
|
policyConfig, _ := corePolicyConfig.Build()
|
2023-10-26 01:06:43 -04:00
|
|
|
// Build Xray conf
|
2023-06-07 13:18:56 -04:00
|
|
|
config := &core.Config{
|
|
|
|
App: []*serial.TypedMessage{
|
|
|
|
serial.ToTypedMessage(coreLogConfig.Build()),
|
|
|
|
serial.ToTypedMessage(&dispatcher.Config{}),
|
|
|
|
serial.ToTypedMessage(&stats.Config{}),
|
|
|
|
serial.ToTypedMessage(&proxyman.InboundConfig{}),
|
|
|
|
serial.ToTypedMessage(&proxyman.OutboundConfig{}),
|
|
|
|
serial.ToTypedMessage(policyConfig),
|
|
|
|
serial.ToTypedMessage(dnsConfig),
|
|
|
|
serial.ToTypedMessage(routeConfig),
|
|
|
|
},
|
|
|
|
Inbound: inBoundConfig,
|
|
|
|
Outbound: outBoundConfig,
|
|
|
|
}
|
|
|
|
server, err := core.New(config)
|
|
|
|
if err != nil {
|
2023-06-29 23:07:27 -04:00
|
|
|
log.WithField("err", err).Panic("failed to create instance")
|
2023-06-07 13:18:56 -04:00
|
|
|
}
|
2023-06-29 23:07:27 -04:00
|
|
|
log.Info("Xray Core Version: ", core.Version())
|
2023-06-07 13:18:56 -04:00
|
|
|
return server
|
|
|
|
}
|
|
|
|
|
2023-10-26 01:06:43 -04:00
|
|
|
// Start the Xray
|
|
|
|
func (c *Xray) Start() error {
|
2023-06-07 13:18:56 -04:00
|
|
|
c.access.Lock()
|
|
|
|
defer c.access.Unlock()
|
|
|
|
if err := c.Server.Start(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
c.shm = c.Server.GetFeature(statsFeature.ManagerType()).(statsFeature.Manager)
|
|
|
|
c.ihm = c.Server.GetFeature(inbound.ManagerType()).(inbound.Manager)
|
|
|
|
c.ohm = c.Server.GetFeature(outbound.ManagerType()).(outbound.Manager)
|
|
|
|
c.dispatcher = c.Server.GetFeature(routing.DispatcherType()).(*dispatcher.DefaultDispatcher)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Close the core
|
2023-10-26 01:06:43 -04:00
|
|
|
func (c *Xray) Close() error {
|
2023-06-07 13:18:56 -04:00
|
|
|
c.access.Lock()
|
|
|
|
defer c.access.Unlock()
|
|
|
|
c.ihm = nil
|
|
|
|
c.ohm = nil
|
|
|
|
c.shm = nil
|
|
|
|
c.dispatcher = nil
|
|
|
|
err := c.Server.Close()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2023-06-09 09:20:41 -04:00
|
|
|
|
2023-10-26 01:06:43 -04:00
|
|
|
func (c *Xray) Protocols() []string {
|
2023-06-09 09:20:41 -04:00
|
|
|
return []string{
|
2023-08-19 08:06:42 -04:00
|
|
|
"vmess",
|
|
|
|
"vless",
|
2023-06-09 09:20:41 -04:00
|
|
|
"shadowsocks",
|
|
|
|
"trojan",
|
|
|
|
}
|
|
|
|
}
|
2023-08-20 03:13:52 -04:00
|
|
|
|
2023-10-26 01:06:43 -04:00
|
|
|
func (c *Xray) Type() string {
|
2023-08-20 03:13:52 -04:00
|
|
|
return "xray"
|
|
|
|
}
|