shadowsocksr.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. package outbound
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "net"
  7. "strconv"
  8. N "github.com/metacubex/mihomo/common/net"
  9. "github.com/metacubex/mihomo/component/dialer"
  10. "github.com/metacubex/mihomo/component/proxydialer"
  11. C "github.com/metacubex/mihomo/constant"
  12. "github.com/metacubex/mihomo/transport/shadowsocks/core"
  13. "github.com/metacubex/mihomo/transport/shadowsocks/shadowaead"
  14. "github.com/metacubex/mihomo/transport/shadowsocks/shadowstream"
  15. "github.com/metacubex/mihomo/transport/socks5"
  16. "github.com/metacubex/mihomo/transport/ssr/obfs"
  17. "github.com/metacubex/mihomo/transport/ssr/protocol"
  18. )
  19. type ShadowSocksR struct {
  20. *Base
  21. option *ShadowSocksROption
  22. cipher core.Cipher
  23. obfs obfs.Obfs
  24. protocol protocol.Protocol
  25. }
  26. type ShadowSocksROption struct {
  27. BasicOption
  28. Name string `proxy:"name"`
  29. Server string `proxy:"server"`
  30. Port int `proxy:"port"`
  31. Password string `proxy:"password"`
  32. Cipher string `proxy:"cipher"`
  33. Obfs string `proxy:"obfs"`
  34. ObfsParam string `proxy:"obfs-param,omitempty"`
  35. Protocol string `proxy:"protocol"`
  36. ProtocolParam string `proxy:"protocol-param,omitempty"`
  37. UDP bool `proxy:"udp,omitempty"`
  38. }
  39. // StreamConnContext implements C.ProxyAdapter
  40. func (ssr *ShadowSocksR) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.Metadata) (net.Conn, error) {
  41. c = ssr.obfs.StreamConn(c)
  42. c = ssr.cipher.StreamConn(c)
  43. var (
  44. iv []byte
  45. err error
  46. )
  47. switch conn := c.(type) {
  48. case *shadowstream.Conn:
  49. iv, err = conn.ObtainWriteIV()
  50. if err != nil {
  51. return nil, err
  52. }
  53. case *shadowaead.Conn:
  54. return nil, fmt.Errorf("invalid connection type")
  55. }
  56. c = ssr.protocol.StreamConn(c, iv)
  57. _, err = c.Write(serializesSocksAddr(metadata))
  58. return c, err
  59. }
  60. // DialContext implements C.ProxyAdapter
  61. func (ssr *ShadowSocksR) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (_ C.Conn, err error) {
  62. return ssr.DialContextWithDialer(ctx, dialer.NewDialer(ssr.Base.DialOptions(opts...)...), metadata)
  63. }
  64. // DialContextWithDialer implements C.ProxyAdapter
  65. func (ssr *ShadowSocksR) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.Conn, err error) {
  66. if len(ssr.option.DialerProxy) > 0 {
  67. dialer, err = proxydialer.NewByName(ssr.option.DialerProxy, dialer)
  68. if err != nil {
  69. return nil, err
  70. }
  71. }
  72. c, err := dialer.DialContext(ctx, "tcp", ssr.addr)
  73. if err != nil {
  74. return nil, fmt.Errorf("%s connect error: %w", ssr.addr, err)
  75. }
  76. N.TCPKeepAlive(c)
  77. defer func(c net.Conn) {
  78. safeConnClose(c, err)
  79. }(c)
  80. c, err = ssr.StreamConnContext(ctx, c, metadata)
  81. return NewConn(c, ssr), err
  82. }
  83. // ListenPacketContext implements C.ProxyAdapter
  84. func (ssr *ShadowSocksR) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.PacketConn, error) {
  85. return ssr.ListenPacketWithDialer(ctx, dialer.NewDialer(ssr.Base.DialOptions(opts...)...), metadata)
  86. }
  87. // ListenPacketWithDialer implements C.ProxyAdapter
  88. func (ssr *ShadowSocksR) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.PacketConn, err error) {
  89. if len(ssr.option.DialerProxy) > 0 {
  90. dialer, err = proxydialer.NewByName(ssr.option.DialerProxy, dialer)
  91. if err != nil {
  92. return nil, err
  93. }
  94. }
  95. addr, err := resolveUDPAddrWithPrefer(ctx, "udp", ssr.addr, ssr.prefer)
  96. if err != nil {
  97. return nil, err
  98. }
  99. pc, err := dialer.ListenPacket(ctx, "udp", "", addr.AddrPort())
  100. if err != nil {
  101. return nil, err
  102. }
  103. epc := ssr.cipher.PacketConn(N.NewEnhancePacketConn(pc))
  104. epc = ssr.protocol.PacketConn(epc)
  105. return newPacketConn(&ssrPacketConn{EnhancePacketConn: epc, rAddr: addr}, ssr), nil
  106. }
  107. // SupportWithDialer implements C.ProxyAdapter
  108. func (ssr *ShadowSocksR) SupportWithDialer() C.NetWork {
  109. return C.ALLNet
  110. }
  111. func NewShadowSocksR(option ShadowSocksROption) (*ShadowSocksR, error) {
  112. // SSR protocol compatibility
  113. // https://github.com/metacubex/mihomo/pull/2056
  114. if option.Cipher == "none" {
  115. option.Cipher = "dummy"
  116. }
  117. addr := net.JoinHostPort(option.Server, strconv.Itoa(option.Port))
  118. cipher := option.Cipher
  119. password := option.Password
  120. coreCiph, err := core.PickCipher(cipher, nil, password)
  121. if err != nil {
  122. return nil, fmt.Errorf("ssr %s initialize error: %w", addr, err)
  123. }
  124. var (
  125. ivSize int
  126. key []byte
  127. )
  128. if option.Cipher == "dummy" {
  129. ivSize = 0
  130. key = core.Kdf(option.Password, 16)
  131. } else {
  132. ciph, ok := coreCiph.(*core.StreamCipher)
  133. if !ok {
  134. return nil, fmt.Errorf("%s is not none or a supported stream cipher in ssr", cipher)
  135. }
  136. ivSize = ciph.IVSize()
  137. key = ciph.Key
  138. }
  139. obfs, obfsOverhead, err := obfs.PickObfs(option.Obfs, &obfs.Base{
  140. Host: option.Server,
  141. Port: option.Port,
  142. Key: key,
  143. IVSize: ivSize,
  144. Param: option.ObfsParam,
  145. })
  146. if err != nil {
  147. return nil, fmt.Errorf("ssr %s initialize obfs error: %w", addr, err)
  148. }
  149. protocol, err := protocol.PickProtocol(option.Protocol, &protocol.Base{
  150. Key: key,
  151. Overhead: obfsOverhead,
  152. Param: option.ProtocolParam,
  153. })
  154. if err != nil {
  155. return nil, fmt.Errorf("ssr %s initialize protocol error: %w", addr, err)
  156. }
  157. return &ShadowSocksR{
  158. Base: &Base{
  159. name: option.Name,
  160. addr: addr,
  161. tp: C.ShadowsocksR,
  162. udp: option.UDP,
  163. tfo: option.TFO,
  164. mpTcp: option.MPTCP,
  165. iface: option.Interface,
  166. rmark: option.RoutingMark,
  167. prefer: C.NewDNSPrefer(option.IPVersion),
  168. },
  169. option: &option,
  170. cipher: coreCiph,
  171. obfs: obfs,
  172. protocol: protocol,
  173. }, nil
  174. }
  175. type ssrPacketConn struct {
  176. N.EnhancePacketConn
  177. rAddr net.Addr
  178. }
  179. func (spc *ssrPacketConn) WriteTo(b []byte, addr net.Addr) (n int, err error) {
  180. packet, err := socks5.EncodeUDPPacket(socks5.ParseAddrToSocksAddr(addr), b)
  181. if err != nil {
  182. return
  183. }
  184. return spc.EnhancePacketConn.WriteTo(packet[3:], spc.rAddr)
  185. }
  186. func (spc *ssrPacketConn) ReadFrom(b []byte) (int, net.Addr, error) {
  187. n, _, e := spc.EnhancePacketConn.ReadFrom(b)
  188. if e != nil {
  189. return 0, nil, e
  190. }
  191. addr := socks5.SplitAddr(b[:n])
  192. if addr == nil {
  193. return 0, nil, errors.New("parse addr error")
  194. }
  195. udpAddr := addr.UDPAddr()
  196. if udpAddr == nil {
  197. return 0, nil, errors.New("parse addr error")
  198. }
  199. copy(b, b[len(addr):])
  200. return n - len(addr), udpAddr, e
  201. }
  202. func (spc *ssrPacketConn) WaitReadFrom() (data []byte, put func(), addr net.Addr, err error) {
  203. data, put, _, err = spc.EnhancePacketConn.WaitReadFrom()
  204. if err != nil {
  205. return nil, nil, nil, err
  206. }
  207. _addr := socks5.SplitAddr(data)
  208. if _addr == nil {
  209. if put != nil {
  210. put()
  211. }
  212. return nil, nil, nil, errors.New("parse addr error")
  213. }
  214. addr = _addr.UDPAddr()
  215. if addr == nil {
  216. if put != nil {
  217. put()
  218. }
  219. return nil, nil, nil, errors.New("parse addr error")
  220. }
  221. data = data[len(_addr):]
  222. return
  223. }