From aa130f05d44611bb352b81c76b680e72a9573224 Mon Sep 17 00:00:00 2001 From: sbruens Date: Wed, 8 Jan 2025 13:04:38 -0500 Subject: [PATCH] Split `Service` interface into outline-ss-server and Caddy interfaces. --- caddy/shadowsocks_handler.go | 14 +++++++++----- cmd/outline-ss-server/main.go | 11 ++++++++++- service/shadowsocks.go | 19 +++++++++++++------ 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/caddy/shadowsocks_handler.go b/caddy/shadowsocks_handler.go index b5edb283..c7247ad9 100644 --- a/caddy/shadowsocks_handler.go +++ b/caddy/shadowsocks_handler.go @@ -16,6 +16,7 @@ package caddy import ( "container/list" + "context" "fmt" "log/slog" "net" @@ -32,6 +33,11 @@ const serverUDPBufferSize = 64 * 1024 const ssModuleName = "layer4.handlers.shadowsocks" +type OutlineService interface { + HandleStream(ctx context.Context, conn transport.StreamConn) + HandleAssociation(conn net.Conn) error +} + func init() { caddy.RegisterModule(ModuleRegistration{ ID: ssModuleName, @@ -48,7 +54,7 @@ type KeyConfig struct { type ShadowsocksHandler struct { Keys []KeyConfig `json:"keys,omitempty"` - service outline.Service + service OutlineService logger *slog.Logger } @@ -119,11 +125,9 @@ func (h *ShadowsocksHandler) Handle(cx *layer4.Connection, _ layer4.Handler) err case transport.StreamConn: h.service.HandleStream(cx.Context, conn) case net.Conn: - assoc, err := h.service.NewPacketAssociation(conn) - if err != nil { - return fmt.Errorf("failed to handle association: %v", err) + if err := h.service.HandleAssociation(conn); err != nil { + return err } - outline.HandleAssociation(conn, assoc) default: return fmt.Errorf("failed to handle unknown connection type: %t", conn) } diff --git a/cmd/outline-ss-server/main.go b/cmd/outline-ss-server/main.go index d41bf685..602a5b3f 100644 --- a/cmd/outline-ss-server/main.go +++ b/cmd/outline-ss-server/main.go @@ -16,6 +16,7 @@ package main import ( "container/list" + "context" "flag" "fmt" "log/slog" @@ -27,6 +28,7 @@ import ( "syscall" "time" + "github.com/Jigsaw-Code/outline-sdk/transport" "github.com/Jigsaw-Code/outline-sdk/transport/shadowsocks" "github.com/lmittmann/tint" "github.com/prometheus/client_golang/prometheus" @@ -60,6 +62,11 @@ func init() { ) } +type OutlineService interface { + HandleStream(ctx context.Context, conn transport.StreamConn) + NewPacketAssociation(conn net.Conn) (service.PacketAssociation, error) +} + type OutlineServer struct { stopConfig func() error lnManager service.ListenerManager @@ -223,6 +230,7 @@ func (s *OutlineServer) runConfig(config Config) (func() error, error) { ciphers := service.NewCipherList() ciphers.Update(cipherList) + var ssService OutlineService ssService, err := service.NewShadowsocksService( service.WithCiphers(ciphers), service.WithMetrics(s.serviceMetrics), @@ -250,7 +258,8 @@ func (s *OutlineServer) runConfig(config Config) (func() error, error) { if err != nil { return fmt.Errorf("failed to create cipher list from config: %v", err) } - ssService, err := service.NewShadowsocksService( + var ssService OutlineService + ssService, err = service.NewShadowsocksService( service.WithCiphers(ciphers), service.WithMetrics(s.serviceMetrics), service.WithReplayCache(&s.replayCache), diff --git a/service/shadowsocks.go b/service/shadowsocks.go index 062a7087..9137136d 100644 --- a/service/shadowsocks.go +++ b/service/shadowsocks.go @@ -16,6 +16,7 @@ package service import ( "context" + "fmt" "log/slog" "net" "time" @@ -41,11 +42,6 @@ type ServiceMetrics interface { AddCipherSearch(proto string, accessKeyFound bool, timeToCipher time.Duration) } -type Service interface { - HandleStream(ctx context.Context, conn transport.StreamConn) - NewPacketAssociation(conn net.Conn) (PacketAssociation, error) -} - // Option is a Shadowsocks service constructor option. type Option func(s *ssService) @@ -63,7 +59,7 @@ type ssService struct { } // NewShadowsocksService creates a new Shadowsocks service. -func NewShadowsocksService(opts ...Option) (Service, error) { +func NewShadowsocksService(opts ...Option) (*ssService, error) { s := &ssService{} for _, opt := range opts { @@ -146,6 +142,17 @@ func (s *ssService) HandleStream(ctx context.Context, conn transport.StreamConn) s.sh.Handle(ctx, conn, metrics) } +// HandleAssociation handles a Shadowsocks packet-based connection. +func (s *ssService) HandleAssociation(conn net.Conn) error { + assoc, err := s.NewPacketAssociation(conn) + if err != nil { + return fmt.Errorf("failed to handle association: %v", err) + } + HandleAssociation(conn, assoc) + return nil +} + + // NewPacketAssociation creates a new Shadowsocks packet-based association. func (s *ssService) NewPacketAssociation(conn net.Conn) (PacketAssociation, error) { var metrics UDPAssociationMetrics