dialer.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. //go:build !confonly
  2. // +build !confonly
  3. package quic
  4. import (
  5. "context"
  6. "sync"
  7. "time"
  8. "github.com/lucas-clemente/quic-go"
  9. "github.com/v2fly/v2ray-core/v4/common"
  10. "github.com/v2fly/v2ray-core/v4/common/net"
  11. "github.com/v2fly/v2ray-core/v4/common/task"
  12. "github.com/v2fly/v2ray-core/v4/transport/internet"
  13. "github.com/v2fly/v2ray-core/v4/transport/internet/tls"
  14. )
  15. type sessionContext struct {
  16. rawConn *sysConn
  17. session quic.Session
  18. }
  19. var errSessionClosed = newError("session closed")
  20. func (c *sessionContext) openStream(destAddr net.Addr) (*interConn, error) {
  21. if !isActive(c.session) {
  22. return nil, errSessionClosed
  23. }
  24. stream, err := c.session.OpenStream()
  25. if err != nil {
  26. return nil, err
  27. }
  28. conn := &interConn{
  29. stream: stream,
  30. local: c.session.LocalAddr(),
  31. remote: destAddr,
  32. }
  33. return conn, nil
  34. }
  35. type clientSessions struct {
  36. access sync.Mutex
  37. sessions map[net.Destination][]*sessionContext
  38. cleanup *task.Periodic
  39. }
  40. func isActive(s quic.Session) bool {
  41. select {
  42. case <-s.Context().Done():
  43. return false
  44. default:
  45. return true
  46. }
  47. }
  48. func removeInactiveSessions(sessions []*sessionContext) []*sessionContext {
  49. activeSessions := make([]*sessionContext, 0, len(sessions))
  50. for _, s := range sessions {
  51. if isActive(s.session) {
  52. activeSessions = append(activeSessions, s)
  53. continue
  54. }
  55. if err := s.session.CloseWithError(0, ""); err != nil {
  56. newError("failed to close session").Base(err).WriteToLog()
  57. }
  58. if err := s.rawConn.Close(); err != nil {
  59. newError("failed to close raw connection").Base(err).WriteToLog()
  60. }
  61. }
  62. if len(activeSessions) < len(sessions) {
  63. return activeSessions
  64. }
  65. return sessions
  66. }
  67. func openStream(sessions []*sessionContext, destAddr net.Addr) *interConn {
  68. for _, s := range sessions {
  69. if !isActive(s.session) {
  70. continue
  71. }
  72. conn, err := s.openStream(destAddr)
  73. if err != nil {
  74. continue
  75. }
  76. return conn
  77. }
  78. return nil
  79. }
  80. func (s *clientSessions) cleanSessions() error {
  81. s.access.Lock()
  82. defer s.access.Unlock()
  83. if len(s.sessions) == 0 {
  84. return nil
  85. }
  86. newSessionMap := make(map[net.Destination][]*sessionContext)
  87. for dest, sessions := range s.sessions {
  88. sessions = removeInactiveSessions(sessions)
  89. if len(sessions) > 0 {
  90. newSessionMap[dest] = sessions
  91. }
  92. }
  93. s.sessions = newSessionMap
  94. return nil
  95. }
  96. func (s *clientSessions) openConnection(destAddr net.Addr, config *Config, tlsConfig *tls.Config, sockopt *internet.SocketConfig) (internet.Connection, error) {
  97. s.access.Lock()
  98. defer s.access.Unlock()
  99. if s.sessions == nil {
  100. s.sessions = make(map[net.Destination][]*sessionContext)
  101. }
  102. dest := net.DestinationFromAddr(destAddr)
  103. var sessions []*sessionContext
  104. if s, found := s.sessions[dest]; found {
  105. sessions = s
  106. }
  107. if true {
  108. conn := openStream(sessions, destAddr)
  109. if conn != nil {
  110. return conn, nil
  111. }
  112. }
  113. sessions = removeInactiveSessions(sessions)
  114. rawConn, err := internet.ListenSystemPacket(context.Background(), &net.UDPAddr{
  115. IP: []byte{0, 0, 0, 0},
  116. Port: 0,
  117. }, sockopt)
  118. if err != nil {
  119. return nil, err
  120. }
  121. quicConfig := &quic.Config{
  122. ConnectionIDLength: 12,
  123. HandshakeIdleTimeout: time.Second * 8,
  124. MaxIdleTimeout: time.Second * 30,
  125. KeepAlive: true,
  126. }
  127. conn, err := wrapSysConn(rawConn, config)
  128. if err != nil {
  129. rawConn.Close()
  130. return nil, err
  131. }
  132. session, err := quic.DialContext(context.Background(), conn, destAddr, "", tlsConfig.GetTLSConfig(tls.WithDestination(dest)), quicConfig)
  133. if err != nil {
  134. conn.Close()
  135. return nil, err
  136. }
  137. context := &sessionContext{
  138. session: session,
  139. rawConn: conn,
  140. }
  141. s.sessions[dest] = append(sessions, context)
  142. return context.openStream(destAddr)
  143. }
  144. var client clientSessions
  145. func init() {
  146. client.sessions = make(map[net.Destination][]*sessionContext)
  147. client.cleanup = &task.Periodic{
  148. Interval: time.Minute,
  149. Execute: client.cleanSessions,
  150. }
  151. common.Must(client.cleanup.Start())
  152. }
  153. func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {
  154. tlsConfig := tls.ConfigFromStreamSettings(streamSettings)
  155. if tlsConfig == nil {
  156. tlsConfig = &tls.Config{
  157. ServerName: internalDomain,
  158. AllowInsecure: true,
  159. }
  160. }
  161. var destAddr *net.UDPAddr
  162. if dest.Address.Family().IsIP() {
  163. destAddr = &net.UDPAddr{
  164. IP: dest.Address.IP(),
  165. Port: int(dest.Port),
  166. }
  167. } else {
  168. addr, err := net.ResolveUDPAddr("udp", dest.NetAddr())
  169. if err != nil {
  170. return nil, err
  171. }
  172. destAddr = addr
  173. }
  174. config := streamSettings.ProtocolSettings.(*Config)
  175. return client.openConnection(destAddr, config, tlsConfig, streamSettings.SocketSettings)
  176. }
  177. func init() {
  178. common.Must(internet.RegisterTransportDialer(protocolName, Dial))
  179. }