conn.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. package v2raywebsocket
  2. import (
  3. "encoding/base64"
  4. "io"
  5. "net"
  6. "net/http"
  7. "os"
  8. "time"
  9. C "github.com/sagernet/sing-box/constant"
  10. E "github.com/sagernet/sing/common/exceptions"
  11. "github.com/gorilla/websocket"
  12. )
  13. type WebsocketConn struct {
  14. *websocket.Conn
  15. remoteAddr net.Addr
  16. reader io.Reader
  17. }
  18. func (c *WebsocketConn) Close() error {
  19. err := c.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""), time.Now().Add(C.TCPTimeout))
  20. if err != nil {
  21. return c.Conn.Close()
  22. }
  23. return nil
  24. }
  25. func (c *WebsocketConn) Read(b []byte) (n int, err error) {
  26. for {
  27. if c.reader == nil {
  28. _, c.reader, err = c.NextReader()
  29. if err != nil {
  30. err = wrapError(err)
  31. return
  32. }
  33. }
  34. n, err = c.reader.Read(b)
  35. if E.IsMulti(err, io.EOF) {
  36. c.reader = nil
  37. continue
  38. }
  39. err = wrapError(err)
  40. return
  41. }
  42. }
  43. func (c *WebsocketConn) Write(b []byte) (n int, err error) {
  44. err = wrapError(c.WriteMessage(websocket.BinaryMessage, b))
  45. if err != nil {
  46. return
  47. }
  48. return len(b), nil
  49. }
  50. func (c *WebsocketConn) RemoteAddr() net.Addr {
  51. if c.remoteAddr != nil {
  52. return c.remoteAddr
  53. }
  54. return c.Conn.RemoteAddr()
  55. }
  56. func (c *WebsocketConn) SetDeadline(t time.Time) error {
  57. return os.ErrInvalid
  58. }
  59. type EarlyWebsocketConn struct {
  60. *Client
  61. conn *WebsocketConn
  62. create chan struct{}
  63. }
  64. func (c *EarlyWebsocketConn) Read(b []byte) (n int, err error) {
  65. if c.conn == nil {
  66. <-c.create
  67. }
  68. return c.conn.Read(b)
  69. }
  70. func (c *EarlyWebsocketConn) Write(b []byte) (n int, err error) {
  71. if c.conn != nil {
  72. return c.conn.Write(b)
  73. }
  74. var (
  75. earlyData []byte
  76. lateData []byte
  77. conn *websocket.Conn
  78. response *http.Response
  79. )
  80. if len(earlyData) > int(c.maxEarlyData) {
  81. earlyData = earlyData[:c.maxEarlyData]
  82. lateData = lateData[c.maxEarlyData:]
  83. } else {
  84. earlyData = b
  85. }
  86. if len(earlyData) > 0 {
  87. earlyDataString := base64.RawURLEncoding.EncodeToString(earlyData)
  88. if c.earlyDataHeaderName == "" {
  89. conn, response, err = c.dialer.Dial(c.uri+earlyDataString, c.headers)
  90. } else {
  91. headers := c.headers.Clone()
  92. headers.Set(c.earlyDataHeaderName, earlyDataString)
  93. conn, response, err = c.dialer.Dial(c.uri, headers)
  94. }
  95. } else {
  96. conn, response, err = c.dialer.Dial(c.uri, c.headers)
  97. }
  98. if err != nil {
  99. return 0, wrapDialError(response, err)
  100. }
  101. c.conn = &WebsocketConn{Conn: conn}
  102. close(c.create)
  103. if len(lateData) > 0 {
  104. _, err = c.conn.Write(lateData)
  105. }
  106. if err != nil {
  107. return
  108. }
  109. return len(b), nil
  110. }
  111. func (c *EarlyWebsocketConn) Close() error {
  112. if c.conn == nil {
  113. return nil
  114. }
  115. return c.conn.Close()
  116. }
  117. func (c *EarlyWebsocketConn) LocalAddr() net.Addr {
  118. if c.conn == nil {
  119. return nil
  120. }
  121. return c.conn.LocalAddr()
  122. }
  123. func (c *EarlyWebsocketConn) RemoteAddr() net.Addr {
  124. if c.conn == nil {
  125. return nil
  126. }
  127. return c.conn.RemoteAddr()
  128. }
  129. func (c *EarlyWebsocketConn) SetDeadline(t time.Time) error {
  130. if c.conn == nil {
  131. return os.ErrInvalid
  132. }
  133. return c.conn.SetDeadline(t)
  134. }
  135. func (c *EarlyWebsocketConn) SetReadDeadline(t time.Time) error {
  136. if c.conn == nil {
  137. return os.ErrInvalid
  138. }
  139. return c.conn.SetReadDeadline(t)
  140. }
  141. func (c *EarlyWebsocketConn) SetWriteDeadline(t time.Time) error {
  142. if c.conn == nil {
  143. return os.ErrInvalid
  144. }
  145. return c.conn.SetWriteDeadline(t)
  146. }
  147. func wrapError(err error) error {
  148. if websocket.IsCloseError(err, websocket.CloseNormalClosure) {
  149. return net.ErrClosed
  150. }
  151. return err
  152. }