router.go 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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/log"
  8. "github.com/sagernet/sing-box/option"
  9. "github.com/sagernet/sing-mux"
  10. E "github.com/sagernet/sing/common/exceptions"
  11. "github.com/sagernet/sing/common/logger"
  12. N "github.com/sagernet/sing/common/network"
  13. )
  14. type Router struct {
  15. router adapter.ConnectionRouterEx
  16. service *mux.Service
  17. }
  18. func NewRouterWithOptions(router adapter.ConnectionRouterEx, logger logger.ContextLogger, options option.InboundMultiplexOptions) (adapter.ConnectionRouterEx, error) {
  19. if !options.Enabled {
  20. return router, nil
  21. }
  22. var brutalOptions mux.BrutalOptions
  23. if options.Brutal != nil && options.Brutal.Enabled {
  24. brutalOptions = mux.BrutalOptions{
  25. Enabled: true,
  26. SendBPS: uint64(options.Brutal.UpMbps * C.MbpsToBps),
  27. ReceiveBPS: uint64(options.Brutal.DownMbps * C.MbpsToBps),
  28. }
  29. if brutalOptions.SendBPS < mux.BrutalMinSpeedBPS {
  30. return nil, E.New("brutal: invalid upload speed")
  31. }
  32. if brutalOptions.ReceiveBPS < mux.BrutalMinSpeedBPS {
  33. return nil, E.New("brutal: invalid download speed")
  34. }
  35. }
  36. service, err := mux.NewService(mux.ServiceOptions{
  37. NewStreamContext: func(ctx context.Context, conn net.Conn) context.Context {
  38. return log.ContextWithNewID(ctx)
  39. },
  40. Logger: logger,
  41. HandlerEx: adapter.NewRouteContextHandlerEx(router),
  42. Padding: options.Padding,
  43. Brutal: brutalOptions,
  44. })
  45. if err != nil {
  46. return nil, err
  47. }
  48. return &Router{router, service}, nil
  49. }
  50. // Deprecated: Use RouteConnectionEx instead.
  51. func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
  52. if metadata.Destination == mux.Destination {
  53. // TODO: check if WithContext is necessary
  54. return r.service.NewConnection(adapter.WithContext(ctx, &metadata), conn, adapter.UpstreamMetadata(metadata))
  55. } else {
  56. return r.router.RouteConnection(ctx, conn, metadata)
  57. }
  58. }
  59. // Deprecated: Use RoutePacketConnectionEx instead.
  60. func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
  61. return r.router.RoutePacketConnection(ctx, conn, metadata)
  62. }
  63. func (r *Router) RouteConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
  64. if metadata.Destination == mux.Destination {
  65. r.service.NewConnectionEx(adapter.WithContext(ctx, &metadata), conn, metadata.Source, metadata.Destination, onClose)
  66. return
  67. }
  68. r.router.RouteConnectionEx(ctx, conn, metadata, onClose)
  69. }
  70. func (r *Router) RoutePacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
  71. r.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
  72. }