client.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. package mux
  2. import (
  3. "context"
  4. "net"
  5. "github.com/sagernet/sing-box/adapter"
  6. C "github.com/sagernet/sing-box/constant"
  7. "github.com/sagernet/sing-box/option"
  8. "github.com/sagernet/sing-mux"
  9. E "github.com/sagernet/sing/common/exceptions"
  10. "github.com/sagernet/sing/common/logger"
  11. M "github.com/sagernet/sing/common/metadata"
  12. N "github.com/sagernet/sing/common/network"
  13. )
  14. type Client = mux.Client
  15. func NewClientWithOptions(dialer N.Dialer, logger logger.Logger, options option.OutboundMultiplexOptions) (*Client, error) {
  16. if !options.Enabled {
  17. return nil, nil
  18. }
  19. var brutalOptions mux.BrutalOptions
  20. if options.Brutal != nil && options.Brutal.Enabled {
  21. brutalOptions = mux.BrutalOptions{
  22. Enabled: true,
  23. SendBPS: uint64(options.Brutal.UpMbps * C.MbpsToBps),
  24. ReceiveBPS: uint64(options.Brutal.DownMbps * C.MbpsToBps),
  25. }
  26. if brutalOptions.SendBPS < mux.BrutalMinSpeedBPS {
  27. return nil, E.New("brutal: invalid upload speed")
  28. }
  29. if brutalOptions.ReceiveBPS < mux.BrutalMinSpeedBPS {
  30. return nil, E.New("brutal: invalid download speed")
  31. }
  32. }
  33. return mux.NewClient(mux.Options{
  34. Dialer: &clientDialer{dialer},
  35. Logger: logger,
  36. Protocol: options.Protocol,
  37. MaxConnections: options.MaxConnections,
  38. MinStreams: options.MinStreams,
  39. MaxStreams: options.MaxStreams,
  40. Padding: options.Padding,
  41. Brutal: brutalOptions,
  42. })
  43. }
  44. type clientDialer struct {
  45. N.Dialer
  46. }
  47. func (d *clientDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
  48. return d.Dialer.DialContext(adapter.OverrideContext(ctx), network, destination)
  49. }
  50. func (d *clientDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
  51. return d.Dialer.ListenPacket(adapter.OverrideContext(ctx), destination)
  52. }