github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/infra/conf/transport_internet.go (about) 1 package conf 2 3 import ( 4 "encoding/json" 5 "strings" 6 7 "github.com/golang/protobuf/proto" 8 "v2ray.com/core/common/platform/filesystem" 9 "v2ray.com/core/common/protocol" 10 "v2ray.com/core/common/serial" 11 "v2ray.com/core/transport/internet" 12 "v2ray.com/core/transport/internet/domainsocket" 13 "v2ray.com/core/transport/internet/http" 14 "v2ray.com/core/transport/internet/kcp" 15 "v2ray.com/core/transport/internet/quic" 16 "v2ray.com/core/transport/internet/tcp" 17 "v2ray.com/core/transport/internet/tls" 18 "v2ray.com/core/transport/internet/websocket" 19 "v2ray.com/core/transport/internet/xtls" 20 ) 21 22 var ( 23 kcpHeaderLoader = NewJSONConfigLoader(ConfigCreatorCache{ 24 "none": func() interface{} { return new(NoOpAuthenticator) }, 25 "srtp": func() interface{} { return new(SRTPAuthenticator) }, 26 "utp": func() interface{} { return new(UTPAuthenticator) }, 27 "wechat-video": func() interface{} { return new(WechatVideoAuthenticator) }, 28 "dtls": func() interface{} { return new(DTLSAuthenticator) }, 29 "wireguard": func() interface{} { return new(WireguardAuthenticator) }, 30 }, "type", "") 31 32 tcpHeaderLoader = NewJSONConfigLoader(ConfigCreatorCache{ 33 "none": func() interface{} { return new(NoOpConnectionAuthenticator) }, 34 "http": func() interface{} { return new(HTTPAuthenticator) }, 35 }, "type", "") 36 ) 37 38 type KCPConfig struct { 39 Mtu *uint32 `json:"mtu"` 40 Tti *uint32 `json:"tti"` 41 UpCap *uint32 `json:"uplinkCapacity"` 42 DownCap *uint32 `json:"downlinkCapacity"` 43 Congestion *bool `json:"congestion"` 44 ReadBufferSize *uint32 `json:"readBufferSize"` 45 WriteBufferSize *uint32 `json:"writeBufferSize"` 46 HeaderConfig json.RawMessage `json:"header"` 47 Seed *string `json:"seed"` 48 } 49 50 // Build implements Buildable. 51 func (c *KCPConfig) Build() (proto.Message, error) { 52 config := new(kcp.Config) 53 54 if c.Mtu != nil { 55 mtu := *c.Mtu 56 if mtu < 576 || mtu > 1460 { 57 return nil, newError("invalid mKCP MTU size: ", mtu).AtError() 58 } 59 config.Mtu = &kcp.MTU{Value: mtu} 60 } 61 if c.Tti != nil { 62 tti := *c.Tti 63 if tti < 10 || tti > 100 { 64 return nil, newError("invalid mKCP TTI: ", tti).AtError() 65 } 66 config.Tti = &kcp.TTI{Value: tti} 67 } 68 if c.UpCap != nil { 69 config.UplinkCapacity = &kcp.UplinkCapacity{Value: *c.UpCap} 70 } 71 if c.DownCap != nil { 72 config.DownlinkCapacity = &kcp.DownlinkCapacity{Value: *c.DownCap} 73 } 74 if c.Congestion != nil { 75 config.Congestion = *c.Congestion 76 } 77 if c.ReadBufferSize != nil { 78 size := *c.ReadBufferSize 79 if size > 0 { 80 config.ReadBuffer = &kcp.ReadBuffer{Size: size * 1024 * 1024} 81 } else { 82 config.ReadBuffer = &kcp.ReadBuffer{Size: 512 * 1024} 83 } 84 } 85 if c.WriteBufferSize != nil { 86 size := *c.WriteBufferSize 87 if size > 0 { 88 config.WriteBuffer = &kcp.WriteBuffer{Size: size * 1024 * 1024} 89 } else { 90 config.WriteBuffer = &kcp.WriteBuffer{Size: 512 * 1024} 91 } 92 } 93 if len(c.HeaderConfig) > 0 { 94 headerConfig, _, err := kcpHeaderLoader.Load(c.HeaderConfig) 95 if err != nil { 96 return nil, newError("invalid mKCP header config.").Base(err).AtError() 97 } 98 ts, err := headerConfig.(Buildable).Build() 99 if err != nil { 100 return nil, newError("invalid mKCP header config").Base(err).AtError() 101 } 102 config.HeaderConfig = serial.ToTypedMessage(ts) 103 } 104 105 if c.Seed != nil { 106 config.Seed = &kcp.EncryptionSeed{Seed: *c.Seed} 107 } 108 109 return config, nil 110 } 111 112 type TCPConfig struct { 113 HeaderConfig json.RawMessage `json:"header"` 114 AcceptProxyProtocol bool `json:"acceptProxyProtocol"` 115 } 116 117 // Build implements Buildable. 118 func (c *TCPConfig) Build() (proto.Message, error) { 119 config := new(tcp.Config) 120 if len(c.HeaderConfig) > 0 { 121 headerConfig, _, err := tcpHeaderLoader.Load(c.HeaderConfig) 122 if err != nil { 123 return nil, newError("invalid TCP header config").Base(err).AtError() 124 } 125 ts, err := headerConfig.(Buildable).Build() 126 if err != nil { 127 return nil, newError("invalid TCP header config").Base(err).AtError() 128 } 129 config.HeaderSettings = serial.ToTypedMessage(ts) 130 } 131 if c.AcceptProxyProtocol { 132 config.AcceptProxyProtocol = c.AcceptProxyProtocol 133 } 134 return config, nil 135 } 136 137 type WebSocketConfig struct { 138 Path string `json:"path"` 139 Path2 string `json:"Path"` // The key was misspelled. For backward compatibility, we have to keep track the old key. 140 Headers map[string]string `json:"headers"` 141 AcceptProxyProtocol bool `json:"acceptProxyProtocol"` 142 } 143 144 // Build implements Buildable. 145 func (c *WebSocketConfig) Build() (proto.Message, error) { 146 path := c.Path 147 if path == "" && c.Path2 != "" { 148 path = c.Path2 149 } 150 header := make([]*websocket.Header, 0, 32) 151 for key, value := range c.Headers { 152 header = append(header, &websocket.Header{ 153 Key: key, 154 Value: value, 155 }) 156 } 157 config := &websocket.Config{ 158 Path: path, 159 Header: header, 160 } 161 if c.AcceptProxyProtocol { 162 config.AcceptProxyProtocol = c.AcceptProxyProtocol 163 } 164 return config, nil 165 } 166 167 type HTTPConfig struct { 168 Host *StringList `json:"host"` 169 Path string `json:"path"` 170 } 171 172 // Build implements Buildable. 173 func (c *HTTPConfig) Build() (proto.Message, error) { 174 config := &http.Config{ 175 Path: c.Path, 176 } 177 if c.Host != nil { 178 config.Host = []string(*c.Host) 179 } 180 return config, nil 181 } 182 183 type QUICConfig struct { 184 Header json.RawMessage `json:"header"` 185 Security string `json:"security"` 186 Key string `json:"key"` 187 } 188 189 // Build implements Buildable. 190 func (c *QUICConfig) Build() (proto.Message, error) { 191 config := &quic.Config{ 192 Key: c.Key, 193 } 194 195 if len(c.Header) > 0 { 196 headerConfig, _, err := kcpHeaderLoader.Load(c.Header) 197 if err != nil { 198 return nil, newError("invalid QUIC header config.").Base(err).AtError() 199 } 200 ts, err := headerConfig.(Buildable).Build() 201 if err != nil { 202 return nil, newError("invalid QUIC header config").Base(err).AtError() 203 } 204 config.Header = serial.ToTypedMessage(ts) 205 } 206 207 var st protocol.SecurityType 208 switch strings.ToLower(c.Security) { 209 case "aes-128-gcm": 210 st = protocol.SecurityType_AES128_GCM 211 case "chacha20-poly1305": 212 st = protocol.SecurityType_CHACHA20_POLY1305 213 default: 214 st = protocol.SecurityType_NONE 215 } 216 217 config.Security = &protocol.SecurityConfig{ 218 Type: st, 219 } 220 221 return config, nil 222 } 223 224 type DomainSocketConfig struct { 225 Path string `json:"path"` 226 Abstract bool `json:"abstract"` 227 Padding bool `json:"padding"` 228 AcceptProxyProtocol bool `json:"acceptProxyProtocol"` 229 } 230 231 // Build implements Buildable. 232 func (c *DomainSocketConfig) Build() (proto.Message, error) { 233 return &domainsocket.Config{ 234 Path: c.Path, 235 Abstract: c.Abstract, 236 Padding: c.Padding, 237 AcceptProxyProtocol: c.AcceptProxyProtocol, 238 }, nil 239 } 240 241 func readFileOrString(f string, s []string) ([]byte, error) { 242 if len(f) > 0 { 243 return filesystem.ReadFile(f) 244 } 245 if len(s) > 0 { 246 return []byte(strings.Join(s, "\n")), nil 247 } 248 return nil, newError("both file and bytes are empty.") 249 } 250 251 type TLSCertConfig struct { 252 CertFile string `json:"certificateFile"` 253 CertStr []string `json:"certificate"` 254 KeyFile string `json:"keyFile"` 255 KeyStr []string `json:"key"` 256 Usage string `json:"usage"` 257 } 258 259 // Build implements Buildable. 260 func (c *TLSCertConfig) Build() (*tls.Certificate, error) { 261 certificate := new(tls.Certificate) 262 263 cert, err := readFileOrString(c.CertFile, c.CertStr) 264 if err != nil { 265 return nil, newError("failed to parse certificate").Base(err) 266 } 267 certificate.Certificate = cert 268 269 if len(c.KeyFile) > 0 || len(c.KeyStr) > 0 { 270 key, err := readFileOrString(c.KeyFile, c.KeyStr) 271 if err != nil { 272 return nil, newError("failed to parse key").Base(err) 273 } 274 certificate.Key = key 275 } 276 277 switch strings.ToLower(c.Usage) { 278 case "encipherment": 279 certificate.Usage = tls.Certificate_ENCIPHERMENT 280 case "verify": 281 certificate.Usage = tls.Certificate_AUTHORITY_VERIFY 282 case "issue": 283 certificate.Usage = tls.Certificate_AUTHORITY_ISSUE 284 default: 285 certificate.Usage = tls.Certificate_ENCIPHERMENT 286 } 287 288 return certificate, nil 289 } 290 291 type TLSConfig struct { 292 Insecure bool `json:"allowInsecure"` 293 InsecureCiphers bool `json:"allowInsecureCiphers"` 294 Certs []*TLSCertConfig `json:"certificates"` 295 ServerName string `json:"serverName"` 296 ALPN *StringList `json:"alpn"` 297 DisableSessionResumption bool `json:"disableSessionResumption"` 298 DisableSystemRoot bool `json:"disableSystemRoot"` 299 } 300 301 // Build implements Buildable. 302 func (c *TLSConfig) Build() (proto.Message, error) { 303 config := new(tls.Config) 304 config.Certificate = make([]*tls.Certificate, len(c.Certs)) 305 for idx, certConf := range c.Certs { 306 cert, err := certConf.Build() 307 if err != nil { 308 return nil, err 309 } 310 config.Certificate[idx] = cert 311 } 312 serverName := c.ServerName 313 config.AllowInsecure = c.Insecure 314 config.AllowInsecureCiphers = c.InsecureCiphers 315 if len(c.ServerName) > 0 { 316 config.ServerName = serverName 317 } 318 if c.ALPN != nil && len(*c.ALPN) > 0 { 319 config.NextProtocol = []string(*c.ALPN) 320 } 321 config.DisableSessionResumption = c.DisableSessionResumption 322 config.DisableSystemRoot = c.DisableSystemRoot 323 return config, nil 324 } 325 326 type XTLSCertConfig struct { 327 CertFile string `json:"certificateFile"` 328 CertStr []string `json:"certificate"` 329 KeyFile string `json:"keyFile"` 330 KeyStr []string `json:"key"` 331 Usage string `json:"usage"` 332 } 333 334 // Build implements Buildable. 335 func (c *XTLSCertConfig) Build() (*xtls.Certificate, error) { 336 certificate := new(xtls.Certificate) 337 338 cert, err := readFileOrString(c.CertFile, c.CertStr) 339 if err != nil { 340 return nil, newError("failed to parse certificate").Base(err) 341 } 342 certificate.Certificate = cert 343 344 if len(c.KeyFile) > 0 || len(c.KeyStr) > 0 { 345 key, err := readFileOrString(c.KeyFile, c.KeyStr) 346 if err != nil { 347 return nil, newError("failed to parse key").Base(err) 348 } 349 certificate.Key = key 350 } 351 352 switch strings.ToLower(c.Usage) { 353 case "encipherment": 354 certificate.Usage = xtls.Certificate_ENCIPHERMENT 355 case "verify": 356 certificate.Usage = xtls.Certificate_AUTHORITY_VERIFY 357 case "issue": 358 certificate.Usage = xtls.Certificate_AUTHORITY_ISSUE 359 default: 360 certificate.Usage = xtls.Certificate_ENCIPHERMENT 361 } 362 363 return certificate, nil 364 } 365 366 type XTLSConfig struct { 367 Insecure bool `json:"allowInsecure"` 368 InsecureCiphers bool `json:"allowInsecureCiphers"` 369 Certs []*XTLSCertConfig `json:"certificates"` 370 ServerName string `json:"serverName"` 371 ALPN *StringList `json:"alpn"` 372 DisableSessionResumption bool `json:"disableSessionResumption"` 373 DisableSystemRoot bool `json:"disableSystemRoot"` 374 } 375 376 // Build implements Buildable. 377 func (c *XTLSConfig) Build() (proto.Message, error) { 378 config := new(xtls.Config) 379 config.Certificate = make([]*xtls.Certificate, len(c.Certs)) 380 for idx, certConf := range c.Certs { 381 cert, err := certConf.Build() 382 if err != nil { 383 return nil, err 384 } 385 config.Certificate[idx] = cert 386 } 387 serverName := c.ServerName 388 config.AllowInsecure = c.Insecure 389 config.AllowInsecureCiphers = c.InsecureCiphers 390 if len(c.ServerName) > 0 { 391 config.ServerName = serverName 392 } 393 if c.ALPN != nil && len(*c.ALPN) > 0 { 394 config.NextProtocol = []string(*c.ALPN) 395 } 396 config.DisableSessionResumption = c.DisableSessionResumption 397 config.DisableSystemRoot = c.DisableSystemRoot 398 return config, nil 399 } 400 401 type TransportProtocol string 402 403 // Build implements Buildable. 404 func (p TransportProtocol) Build() (string, error) { 405 switch strings.ToLower(string(p)) { 406 case "tcp": 407 return "tcp", nil 408 case "kcp", "mkcp": 409 return "mkcp", nil 410 case "ws", "websocket": 411 return "websocket", nil 412 case "h2", "http": 413 return "http", nil 414 case "ds", "domainsocket": 415 return "domainsocket", nil 416 case "quic": 417 return "quic", nil 418 default: 419 return "", newError("Config: unknown transport protocol: ", p) 420 } 421 } 422 423 type SocketConfig struct { 424 Mark int32 `json:"mark"` 425 TFO *bool `json:"tcpFastOpen"` 426 TProxy string `json:"tproxy"` 427 } 428 429 // Build implements Buildable. 430 func (c *SocketConfig) Build() (*internet.SocketConfig, error) { 431 var tfoSettings internet.SocketConfig_TCPFastOpenState 432 if c.TFO != nil { 433 if *c.TFO { 434 tfoSettings = internet.SocketConfig_Enable 435 } else { 436 tfoSettings = internet.SocketConfig_Disable 437 } 438 } 439 var tproxy internet.SocketConfig_TProxyMode 440 switch strings.ToLower(c.TProxy) { 441 case "tproxy": 442 tproxy = internet.SocketConfig_TProxy 443 case "redirect": 444 tproxy = internet.SocketConfig_Redirect 445 default: 446 tproxy = internet.SocketConfig_Off 447 } 448 449 return &internet.SocketConfig{ 450 Mark: c.Mark, 451 Tfo: tfoSettings, 452 Tproxy: tproxy, 453 }, nil 454 } 455 456 type StreamConfig struct { 457 Network *TransportProtocol `json:"network"` 458 Security string `json:"security"` 459 TLSSettings *TLSConfig `json:"tlsSettings"` 460 XTLSSettings *XTLSConfig `json:"xtlsSettings"` 461 TCPSettings *TCPConfig `json:"tcpSettings"` 462 KCPSettings *KCPConfig `json:"kcpSettings"` 463 WSSettings *WebSocketConfig `json:"wsSettings"` 464 HTTPSettings *HTTPConfig `json:"httpSettings"` 465 DSSettings *DomainSocketConfig `json:"dsSettings"` 466 QUICSettings *QUICConfig `json:"quicSettings"` 467 SocketSettings *SocketConfig `json:"sockopt"` 468 } 469 470 // Build implements Buildable. 471 func (c *StreamConfig) Build() (*internet.StreamConfig, error) { 472 config := &internet.StreamConfig{ 473 ProtocolName: "tcp", 474 } 475 if c.Network != nil { 476 protocol, err := (*c.Network).Build() 477 if err != nil { 478 return nil, err 479 } 480 config.ProtocolName = protocol 481 } 482 if strings.EqualFold(c.Security, "tls") { 483 tlsSettings := c.TLSSettings 484 if tlsSettings == nil { 485 if c.XTLSSettings != nil { 486 return nil, newError(`TLS: Please use "tlsSettings" instead of "xtlsSettings".`) 487 } 488 tlsSettings = &TLSConfig{} 489 } 490 ts, err := tlsSettings.Build() 491 if err != nil { 492 return nil, newError("Failed to build TLS config.").Base(err) 493 } 494 tm := serial.ToTypedMessage(ts) 495 config.SecuritySettings = append(config.SecuritySettings, tm) 496 config.SecurityType = tm.Type 497 } 498 if strings.EqualFold(c.Security, "xtls") { 499 if config.ProtocolName != "tcp" && config.ProtocolName != "mkcp" && config.ProtocolName != "domainsocket" { 500 return nil, newError("XTLS only supports TCP, mKCP and DomainSocket for now.") 501 } 502 xtlsSettings := c.XTLSSettings 503 if xtlsSettings == nil { 504 if c.TLSSettings != nil { 505 return nil, newError(`XTLS: Please use "xtlsSettings" instead of "tlsSettings".`) 506 } 507 xtlsSettings = &XTLSConfig{} 508 } 509 ts, err := xtlsSettings.Build() 510 if err != nil { 511 return nil, newError("Failed to build XTLS config.").Base(err) 512 } 513 tm := serial.ToTypedMessage(ts) 514 config.SecuritySettings = append(config.SecuritySettings, tm) 515 config.SecurityType = tm.Type 516 } 517 if c.TCPSettings != nil { 518 ts, err := c.TCPSettings.Build() 519 if err != nil { 520 return nil, newError("Failed to build TCP config.").Base(err) 521 } 522 config.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{ 523 ProtocolName: "tcp", 524 Settings: serial.ToTypedMessage(ts), 525 }) 526 } 527 if c.KCPSettings != nil { 528 ts, err := c.KCPSettings.Build() 529 if err != nil { 530 return nil, newError("Failed to build mKCP config.").Base(err) 531 } 532 config.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{ 533 ProtocolName: "mkcp", 534 Settings: serial.ToTypedMessage(ts), 535 }) 536 } 537 if c.WSSettings != nil { 538 ts, err := c.WSSettings.Build() 539 if err != nil { 540 return nil, newError("Failed to build WebSocket config.").Base(err) 541 } 542 config.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{ 543 ProtocolName: "websocket", 544 Settings: serial.ToTypedMessage(ts), 545 }) 546 } 547 if c.HTTPSettings != nil { 548 ts, err := c.HTTPSettings.Build() 549 if err != nil { 550 return nil, newError("Failed to build HTTP config.").Base(err) 551 } 552 config.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{ 553 ProtocolName: "http", 554 Settings: serial.ToTypedMessage(ts), 555 }) 556 } 557 if c.DSSettings != nil { 558 ds, err := c.DSSettings.Build() 559 if err != nil { 560 return nil, newError("Failed to build DomainSocket config.").Base(err) 561 } 562 config.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{ 563 ProtocolName: "domainsocket", 564 Settings: serial.ToTypedMessage(ds), 565 }) 566 } 567 if c.QUICSettings != nil { 568 qs, err := c.QUICSettings.Build() 569 if err != nil { 570 return nil, newError("Failed to build QUIC config").Base(err) 571 } 572 config.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{ 573 ProtocolName: "quic", 574 Settings: serial.ToTypedMessage(qs), 575 }) 576 } 577 if c.SocketSettings != nil { 578 ss, err := c.SocketSettings.Build() 579 if err != nil { 580 return nil, newError("Failed to build sockopt").Base(err) 581 } 582 config.SocketSettings = ss 583 } 584 return config, nil 585 } 586 587 type ProxyConfig struct { 588 Tag string `json:"tag"` 589 } 590 591 // Build implements Buildable. 592 func (v *ProxyConfig) Build() (*internet.ProxyConfig, error) { 593 if v.Tag == "" { 594 return nil, newError("Proxy tag is not set.") 595 } 596 return &internet.ProxyConfig{ 597 Tag: v.Tag, 598 }, nil 599 }