dialer.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package quic
  2. import (
  3. "context"
  4. "sync"
  5. "v2ray.com/core/transport/internet/tls"
  6. quic "github.com/lucas-clemente/quic-go"
  7. "v2ray.com/core/common"
  8. "v2ray.com/core/common/net"
  9. "v2ray.com/core/transport/internet"
  10. )
  11. type clientSessions struct {
  12. access sync.Mutex
  13. sessions map[net.Destination]quic.Session
  14. }
  15. func (s *clientSessions) getSession(destAddr net.Addr, config *Config, tlsConfig *tls.Config, sockopt *internet.SocketConfig) (quic.Session, error) {
  16. s.access.Lock()
  17. defer s.access.Unlock()
  18. if s.sessions == nil {
  19. s.sessions = make(map[net.Destination]quic.Session)
  20. }
  21. dest := net.DestinationFromAddr(destAddr)
  22. if session, found := s.sessions[dest]; found {
  23. return session, nil
  24. }
  25. rawConn, err := internet.ListenSystemPacket(context.Background(), &net.UDPAddr{
  26. IP: []byte{0, 0, 0, 0},
  27. Port: 0,
  28. }, sockopt)
  29. if err != nil {
  30. return nil, err
  31. }
  32. quicConfig := &quic.Config{
  33. Versions: []quic.VersionNumber{quic.VersionMilestone0_10_0},
  34. ConnectionIDLength: 12,
  35. KeepAlive: true,
  36. }
  37. conn, err := wrapSysConn(rawConn, config)
  38. if err != nil {
  39. rawConn.Close()
  40. return nil, err
  41. }
  42. session, err := quic.DialContext(context.Background(), conn, destAddr, "", tlsConfig.GetTLSConfig(tls.WithDestination(dest)), quicConfig)
  43. if err != nil {
  44. rawConn.Close()
  45. return nil, err
  46. }
  47. s.sessions[dest] = session
  48. return session, nil
  49. }
  50. var client clientSessions
  51. func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {
  52. tlsConfig := tls.ConfigFromStreamSettings(streamSettings)
  53. if tlsConfig == nil {
  54. tlsConfig = &tls.Config{
  55. ServerName: internalDomain,
  56. AllowInsecure: true,
  57. }
  58. }
  59. destAddr, err := net.ResolveUDPAddr("udp", dest.NetAddr())
  60. if err != nil {
  61. return nil, err
  62. }
  63. config := streamSettings.ProtocolSettings.(*Config)
  64. session, err := client.getSession(destAddr, config, tlsConfig, streamSettings.SocketSettings)
  65. if err != nil {
  66. return nil, err
  67. }
  68. conn, err := session.OpenStreamSync()
  69. if err != nil {
  70. return nil, err
  71. }
  72. return &interConn{
  73. stream: conn,
  74. local: session.LocalAddr(),
  75. remote: destAddr,
  76. }, nil
  77. }
  78. func init() {
  79. common.Must(internet.RegisterTransportDialer(protocolName, Dial))
  80. }