mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-09-16 06:20:28 +00:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8562dcb19f | ||
|
|
fdb9b616fc | ||
|
|
d792fba59c | ||
|
|
55956f8d70 |
@@ -11,6 +11,7 @@ on:
|
||||
jobs:
|
||||
check-assets:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
|
||||
steps:
|
||||
- name: Restore Geodat Cache
|
||||
uses: actions/cache/restore@v5
|
||||
@@ -75,6 +76,7 @@ jobs:
|
||||
fail-fast: false
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
|
||||
env:
|
||||
GOOS: ${{ matrix.goos}}
|
||||
GOARCH: ${{ matrix.goarch }}
|
||||
|
||||
@@ -11,6 +11,7 @@ on:
|
||||
jobs:
|
||||
check-assets:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
|
||||
steps:
|
||||
- name: Restore Geodat Cache
|
||||
uses: actions/cache/restore@v5
|
||||
@@ -161,6 +162,7 @@ jobs:
|
||||
fail-fast: false
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
|
||||
env:
|
||||
GOOS: ${{ matrix.goos }}
|
||||
GOARCH: ${{ matrix.goarch }}
|
||||
|
||||
@@ -145,6 +145,8 @@
|
||||
- [v2rayN](https://github.com/2dust/v2rayN)
|
||||
- [GenyConnect](https://github.com/genyleap/GenyConnect)
|
||||
- [OneXray](https://github.com/OneXray/OneXray)
|
||||
- HarmonyOS
|
||||
- [Hey](https://github.com/popsiclelmlm/Hey)
|
||||
|
||||
## Others that support VLESS, XTLS, REALITY, XUDP, PLUX...
|
||||
|
||||
|
||||
@@ -57,6 +57,26 @@ func NewMetricsHandler(ctx context.Context, config *Config) (*MetricsHandler, er
|
||||
})
|
||||
return resp
|
||||
}))
|
||||
expvar.Publish("online", expvar.Func(func() interface{} {
|
||||
resp := map[string]interface{}{}
|
||||
c.statsManager.VisitOnlineMaps(func(name string, om feature_stats.OnlineMap) bool {
|
||||
user := name
|
||||
if parts := strings.Split(name, ">>>"); len(parts) >= 2 {
|
||||
user = parts[1]
|
||||
}
|
||||
ips := map[string]int64{}
|
||||
om.ForEach(func(ip string, lastSeen int64) bool {
|
||||
ips[ip] = lastSeen
|
||||
return true
|
||||
})
|
||||
resp[user] = map[string]interface{}{
|
||||
"count": om.Count(),
|
||||
"ips": ips,
|
||||
}
|
||||
return true
|
||||
})
|
||||
return resp
|
||||
}))
|
||||
expvar.Publish("observatory", expvar.Func(func() interface{} {
|
||||
if c.observatory == nil {
|
||||
common.Must(core.RequireFeatures(ctx, func(observatory extension.Observatory) error {
|
||||
|
||||
@@ -273,7 +273,8 @@ type udpWorker struct {
|
||||
checker *task.Periodic
|
||||
activeConn map[connID]*udpConn
|
||||
|
||||
ctx context.Context
|
||||
ctx context.Context
|
||||
cone bool
|
||||
}
|
||||
|
||||
func (w *udpWorker) getConnection(id connID) (*udpConn, bool) {
|
||||
@@ -315,6 +316,9 @@ func (w *udpWorker) callback(b *buf.Buffer, source net.Destination, originalDest
|
||||
src: source,
|
||||
}
|
||||
if originalDest.IsValid() {
|
||||
if !w.cone {
|
||||
id.dest = originalDest
|
||||
}
|
||||
b.UDP = &originalDest
|
||||
}
|
||||
conn, existing := w.getConnection(id)
|
||||
@@ -414,6 +418,8 @@ func (w *udpWorker) Start() error {
|
||||
return err
|
||||
}
|
||||
|
||||
w.cone = w.ctx.Value("cone").(bool)
|
||||
|
||||
w.checker = &task.Periodic{
|
||||
Interval: time.Minute,
|
||||
Execute: w.clean,
|
||||
|
||||
@@ -16,6 +16,7 @@ const (
|
||||
UseReadV = "xray.buf.readv"
|
||||
UseFreedomSplice = "xray.buf.splice"
|
||||
UseVmessPadding = "xray.vmess.padding"
|
||||
UseCone = "xray.cone.disabled"
|
||||
UseStrictJSON = "xray.json.strict"
|
||||
|
||||
BufferSize = "xray.ray.buffer.size"
|
||||
|
||||
@@ -49,6 +49,9 @@ func init() {
|
||||
}
|
||||
|
||||
func GetGlobalID(ctx context.Context) (globalID [8]byte) {
|
||||
if cone := ctx.Value("cone"); cone == nil || !cone.(bool) { // cone is nil only in some unit tests
|
||||
return
|
||||
}
|
||||
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.Network == net.Network_UDP &&
|
||||
(inbound.Name == "dokodemo-door" || inbound.Name == "socks" || inbound.Name == "shadowsocks" || inbound.Name == "tun") {
|
||||
h := blake3.New(8, BaseKey)
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/xtls/xray-core/common"
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
"github.com/xtls/xray-core/common/platform"
|
||||
"github.com/xtls/xray-core/common/serial"
|
||||
"github.com/xtls/xray-core/features"
|
||||
"github.com/xtls/xray-core/features/dns"
|
||||
@@ -186,6 +187,9 @@ func NewWithContext(ctx context.Context, config *Config) (*Instance, error) {
|
||||
}
|
||||
|
||||
func initInstanceWithConfig(config *Config, server *Instance) (bool, error) {
|
||||
server.ctx = context.WithValue(server.ctx, "cone",
|
||||
platform.NewEnvFlag(platform.UseCone).GetValue(func() string { return "" }) != "true")
|
||||
|
||||
for _, appSettings := range config.App {
|
||||
settings, err := appSettings.GetInstance()
|
||||
if err != nil {
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/xtls/xray-core/common"
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
@@ -651,10 +650,8 @@ type TLSConfig struct {
|
||||
MasterKeyLog string `json:"masterKeyLog"`
|
||||
PinnedPeerCertSha256 string `json:"pinnedPeerCertSha256"`
|
||||
VerifyPeerCertByName string `json:"verifyPeerCertByName"`
|
||||
VerifyPeerCertInNames []string `json:"verifyPeerCertInNames"`
|
||||
ECHServerKeys string `json:"echServerKeys"`
|
||||
ECHConfigList string `json:"echConfigList"`
|
||||
ECHForceQuery string `json:"echForceQuery"`
|
||||
ECHSocketSettings *SocketConfig `json:"echSockopt"`
|
||||
}
|
||||
|
||||
@@ -699,12 +696,7 @@ func (c *TLSConfig) Build() (proto.Message, error) {
|
||||
config.MasterKeyLog = c.MasterKeyLog
|
||||
|
||||
if c.AllowInsecure {
|
||||
if time.Now().After(time.Date(2026, 6, 1, 0, 0, 0, 0, time.UTC)) {
|
||||
return nil, errors.PrintRemovedFeatureError(`"allowInsecure"`, `"pinnedPeerCertSha256"`)
|
||||
} else {
|
||||
errors.LogWarning(context.Background(), `"allowInsecure" will be removed automatically after 2026-06-01, please use "pinnedPeerCertSha256"(pcs) and "verifyPeerCertByName"(vcn) instead, PLEASE CONTACT YOUR SERVICE PROVIDER (AIRPORT)`)
|
||||
config.AllowInsecure = true
|
||||
}
|
||||
return nil, errors.PrintRemovedFeatureError(`"allowInsecure"`, `"pinnedPeerCertSha256"(pcs) and "verifyPeerCertByName"(vcn)`)
|
||||
}
|
||||
if c.PinnedPeerCertSha256 != "" {
|
||||
for v := range strings.SplitSeq(c.PinnedPeerCertSha256, ",") {
|
||||
@@ -723,10 +715,6 @@ func (c *TLSConfig) Build() (proto.Message, error) {
|
||||
config.PinnedPeerCertSha256 = append(config.PinnedPeerCertSha256, hashValue)
|
||||
}
|
||||
}
|
||||
|
||||
if c.VerifyPeerCertInNames != nil {
|
||||
return nil, errors.PrintRemovedFeatureError(`"verifyPeerCertInNames"`, `"verifyPeerCertByName"`)
|
||||
}
|
||||
if c.VerifyPeerCertByName != "" {
|
||||
for v := range strings.SplitSeq(c.VerifyPeerCertByName, ",") {
|
||||
v = strings.TrimSpace(v)
|
||||
@@ -744,13 +732,6 @@ func (c *TLSConfig) Build() (proto.Message, error) {
|
||||
}
|
||||
config.EchServerKeys = EchPrivateKey
|
||||
}
|
||||
switch c.ECHForceQuery {
|
||||
case "none", "half", "full", "":
|
||||
config.EchForceQuery = c.ECHForceQuery
|
||||
default:
|
||||
return nil, errors.New(`invalid "echForceQuery": `, c.ECHForceQuery)
|
||||
}
|
||||
config.EchForceQuery = c.ECHForceQuery
|
||||
config.EchConfigList = c.ECHConfigList
|
||||
if c.ECHSocketSettings != nil {
|
||||
ss, err := c.ECHSocketSettings.Build()
|
||||
|
||||
@@ -25,6 +25,7 @@ type Server struct {
|
||||
config *ServerConfig
|
||||
validator *Validator
|
||||
policyManager policy.Manager
|
||||
cone bool
|
||||
}
|
||||
|
||||
// NewServer create a new Shadowsocks server.
|
||||
@@ -46,6 +47,7 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
|
||||
config: config,
|
||||
validator: validator,
|
||||
policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
|
||||
cone: ctx.Value("cone").(bool),
|
||||
}
|
||||
|
||||
return s, nil
|
||||
@@ -183,7 +185,7 @@ func (s *Server) handleUDPPayload(ctx context.Context, conn stat.Connection, dis
|
||||
|
||||
data.UDP = &destination
|
||||
|
||||
if dest == nil {
|
||||
if !s.cone || dest == nil {
|
||||
dest = &destination
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import (
|
||||
type Server struct {
|
||||
config *ServerConfig
|
||||
policyManager policy.Manager
|
||||
cone bool
|
||||
httpServer *http.Server
|
||||
}
|
||||
|
||||
@@ -37,6 +38,7 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
|
||||
s := &Server{
|
||||
config: config,
|
||||
policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
|
||||
cone: ctx.Value("cone").(bool),
|
||||
}
|
||||
httpConfig := &http.ServerConfig{
|
||||
UserLevel: config.UserLevel,
|
||||
@@ -255,7 +257,7 @@ func (s *Server) handleUDPPayload(ctx context.Context, conn stat.Connection, dis
|
||||
|
||||
payload.UDP = &destination
|
||||
|
||||
if dest == nil {
|
||||
if !s.cone || dest == nil {
|
||||
dest = &destination
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ type Server struct {
|
||||
policyManager policy.Manager
|
||||
validator *Validator
|
||||
fallbacks map[string]map[string]map[string]*Fallback // or nil
|
||||
cone bool
|
||||
}
|
||||
|
||||
// NewServer creates a new trojan inbound handler.
|
||||
@@ -58,6 +59,7 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
|
||||
server := &Server{
|
||||
policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
|
||||
validator: validator,
|
||||
cone: ctx.Value("cone").(bool),
|
||||
}
|
||||
|
||||
if config.Fallbacks != nil {
|
||||
@@ -300,7 +302,7 @@ func (s *Server) handleUDPPayload(ctx context.Context, sessionPolicy policy.Sess
|
||||
}
|
||||
errors.LogInfo(ctx, "tunnelling request to ", destination)
|
||||
|
||||
if dest == nil {
|
||||
if !s.cone || dest == nil {
|
||||
dest = &destination
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ func init() {
|
||||
type Handler struct {
|
||||
server *protocol.ServerSpec
|
||||
policyManager policy.Manager
|
||||
cone bool
|
||||
encryption *encryption.ClientInstance
|
||||
reverse *Reverse
|
||||
|
||||
@@ -79,6 +80,7 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
|
||||
handler := &Handler{
|
||||
server: server,
|
||||
policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
|
||||
cone: ctx.Value("cone").(bool),
|
||||
}
|
||||
|
||||
a := handler.server.User.Account.(*vless.MemoryAccount)
|
||||
@@ -310,7 +312,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
||||
clientReader := link.Reader // .(*pipe.Reader)
|
||||
clientWriter := link.Writer // .(*pipe.Writer)
|
||||
trafficState := proxy.NewTrafficState(account.ID.Bytes())
|
||||
if request.Command == protocol.RequestCommandUDP && (requestAddons.Flow == vless.XRV || (request.Port != 53 && request.Port != 443)) {
|
||||
if request.Command == protocol.RequestCommandUDP && (requestAddons.Flow == vless.XRV || (h.cone && request.Port != 53 && request.Port != 443)) {
|
||||
request.Command = protocol.RequestCommandMux
|
||||
request.Address = net.DomainAddress("v1.mux.cool")
|
||||
request.Port = net.Port(666)
|
||||
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
type Handler struct {
|
||||
server *protocol.ServerSpec
|
||||
policyManager policy.Manager
|
||||
cone bool
|
||||
}
|
||||
|
||||
// New creates a new VMess outbound handler.
|
||||
@@ -47,6 +48,7 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
|
||||
handler := &Handler{
|
||||
server: server,
|
||||
policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
|
||||
cone: ctx.Value("cone").(bool),
|
||||
}
|
||||
|
||||
return handler, nil
|
||||
@@ -146,7 +148,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
||||
}
|
||||
}, sessionPolicy.Timeouts.ConnectionIdle)
|
||||
|
||||
if request.Command == protocol.RequestCommandUDP && request.Port != 53 && request.Port != 443 {
|
||||
if request.Command == protocol.RequestCommandUDP && h.cone && request.Port != 53 && request.Port != 443 {
|
||||
request.Command = protocol.RequestCommandMux
|
||||
request.Address = net.DomainAddress("v1.mux.cool")
|
||||
request.Port = net.Port(666)
|
||||
|
||||
@@ -381,7 +381,6 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
|
||||
PinnedPeerCertSha256: c.PinnedPeerCertSha256,
|
||||
}
|
||||
config := &tls.Config{
|
||||
InsecureSkipVerify: c.AllowInsecure,
|
||||
Rand: randCarrier,
|
||||
ClientSessionCache: globalSessionCache,
|
||||
RootCAs: root,
|
||||
|
||||
@@ -177,8 +177,7 @@ func (x *Certificate) GetBuildChain() bool {
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
AllowInsecure bool `protobuf:"varint,1,opt,name=allow_insecure,json=allowInsecure,proto3" json:"allow_insecure,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// List of certificates to be served on server.
|
||||
Certificate []*Certificate `protobuf:"bytes,2,rep,name=certificate,proto3" json:"certificate,omitempty"`
|
||||
// Override server name.
|
||||
@@ -205,7 +204,6 @@ type Config struct {
|
||||
VerifyPeerCertByName []string `protobuf:"bytes,17,rep,name=verify_peer_cert_by_name,json=verifyPeerCertByName,proto3" json:"verify_peer_cert_by_name,omitempty"`
|
||||
EchServerKeys []byte `protobuf:"bytes,18,opt,name=ech_server_keys,json=echServerKeys,proto3" json:"ech_server_keys,omitempty"`
|
||||
EchConfigList string `protobuf:"bytes,19,opt,name=ech_config_list,json=echConfigList,proto3" json:"ech_config_list,omitempty"`
|
||||
EchForceQuery string `protobuf:"bytes,20,opt,name=ech_force_query,json=echForceQuery,proto3" json:"ech_force_query,omitempty"`
|
||||
EchSocketSettings *internet.SocketConfig `protobuf:"bytes,21,opt,name=ech_socket_settings,json=echSocketSettings,proto3" json:"ech_socket_settings,omitempty"`
|
||||
PinnedPeerCertSha256 [][]byte `protobuf:"bytes,22,rep,name=pinned_peer_cert_sha256,json=pinnedPeerCertSha256,proto3" json:"pinned_peer_cert_sha256,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
@@ -242,13 +240,6 @@ func (*Config) Descriptor() ([]byte, []int) {
|
||||
return file_transport_internet_tls_config_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *Config) GetAllowInsecure() bool {
|
||||
if x != nil {
|
||||
return x.AllowInsecure
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *Config) GetCertificate() []*Certificate {
|
||||
if x != nil {
|
||||
return x.Certificate
|
||||
@@ -354,13 +345,6 @@ func (x *Config) GetEchConfigList() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Config) GetEchForceQuery() string {
|
||||
if x != nil {
|
||||
return x.EchForceQuery
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Config) GetEchSocketSettings() *internet.SocketConfig {
|
||||
if x != nil {
|
||||
return x.EchSocketSettings
|
||||
@@ -393,9 +377,8 @@ const file_transport_internet_tls_config_proto_rawDesc = "" +
|
||||
"\x05Usage\x12\x10\n" +
|
||||
"\fENCIPHERMENT\x10\x00\x12\x14\n" +
|
||||
"\x10AUTHORITY_VERIFY\x10\x01\x12\x13\n" +
|
||||
"\x0fAUTHORITY_ISSUE\x10\x02\"\xf5\x06\n" +
|
||||
"\x06Config\x12%\n" +
|
||||
"\x0eallow_insecure\x18\x01 \x01(\bR\rallowInsecure\x12J\n" +
|
||||
"\x0fAUTHORITY_ISSUE\x10\x02\"\xa6\x06\n" +
|
||||
"\x06Config\x12J\n" +
|
||||
"\vcertificate\x18\x02 \x03(\v2(.xray.transport.internet.tls.CertificateR\vcertificate\x12\x1f\n" +
|
||||
"\vserver_name\x18\x03 \x01(\tR\n" +
|
||||
"serverName\x12#\n" +
|
||||
@@ -413,8 +396,7 @@ const file_transport_internet_tls_config_proto_rawDesc = "" +
|
||||
"\x11curve_preferences\x18\x10 \x03(\tR\x10curvePreferences\x126\n" +
|
||||
"\x18verify_peer_cert_by_name\x18\x11 \x03(\tR\x14verifyPeerCertByName\x12&\n" +
|
||||
"\x0fech_server_keys\x18\x12 \x01(\fR\rechServerKeys\x12&\n" +
|
||||
"\x0fech_config_list\x18\x13 \x01(\tR\rechConfigList\x12&\n" +
|
||||
"\x0fech_force_query\x18\x14 \x01(\tR\rechForceQuery\x12U\n" +
|
||||
"\x0fech_config_list\x18\x13 \x01(\tR\rechConfigList\x12U\n" +
|
||||
"\x13ech_socket_settings\x18\x15 \x01(\v2%.xray.transport.internet.SocketConfigR\x11echSocketSettings\x125\n" +
|
||||
"\x17pinned_peer_cert_sha256\x18\x16 \x03(\fR\x14pinnedPeerCertSha256Bs\n" +
|
||||
"\x1fcom.xray.transport.internet.tlsP\x01Z0github.com/xtls/xray-core/transport/internet/tls\xaa\x02\x1bXray.Transport.Internet.Tlsb\x06proto3"
|
||||
|
||||
@@ -38,7 +38,7 @@ message Certificate {
|
||||
}
|
||||
|
||||
message Config {
|
||||
bool allow_insecure = 1;
|
||||
// Number 1 was assigned and used by an legacy option.
|
||||
|
||||
// List of certificates to be served on server.
|
||||
repeated Certificate certificate = 2;
|
||||
@@ -81,8 +81,7 @@ message Config {
|
||||
|
||||
string ech_config_list = 19;
|
||||
|
||||
// Deprecated
|
||||
string ech_force_query = 20;
|
||||
// Number 20 was assigned and used by an legacy option.
|
||||
|
||||
SocketConfig ech_socket_settings = 21;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user