router.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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. Handler: adapter.NewRouteContextHandler(router, logger),
  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. func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
  51. if metadata.Destination == mux.Destination {
  52. // TODO: check if WithContext is necessary
  53. return r.service.NewConnection(adapter.WithContext(ctx, &metadata), conn, adapter.UpstreamMetadata(metadata))
  54. } else {
  55. return r.router.RouteConnection(ctx, conn, metadata)
  56. }
  57. }
  58. func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
  59. return r.router.RoutePacketConnection(ctx, conn, metadata)
  60. }
  61. func (r *Router) RouteConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
  62. if metadata.Destination == mux.Destination {
  63. r.service.NewConnectionEx(adapter.WithContext(ctx, &metadata), conn, metadata.Source, metadata.Destination, onClose)
  64. return
  65. }
  66. r.router.RouteConnectionEx(ctx, conn, metadata, onClose)
  67. }
  68. func (r *Router) RoutePacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
  69. r.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
  70. }