Usage as a library
Opened this issue · 3 comments
Discussion thread of #43
The use case as simple as possible: an ability to create and manager a single server without external HTTP API.
Server configuration example:
sc := ss.Config{
Servers: []ss.ServerConfig{
{
Name: "foo",
Protocol: "2022-blake3-aes-256-gcm",
MTU: 1500,
Listen: ":43333",
EnableTCP: true,
EnableUDP: true,
ListenerTFO: true,
UDPRelayBatchSize: 8,
PSK: "mypassword",
UPSKStorePath: "/dev/zero",
},
},
}
Now we need an ability to add/remove/list users of that server via Manager
.
You probably want to use /dev/null
as the uPSK store path.
Actually, you don't even need a ServerConfig
. cred.Manager
was written to manage the credential file, and you don't need that. All you need is access to ss2022.CredStore
, which was embedded into ss2022.TCPServer
and ss2022.UDPServer
and can be accessed directly.
When you omit the need for multiple servers and clients and routing rules, the initialization process is actually not that complex, and should be easy to implement in your own code. You could do something like:
cc := ClientConfig{
Name: "direct",
Protocol: "direct",
EnableTCP: true,
DialerTFO: true,
EnableUDP: true,
MTU: 1500,
}
err := cc.Initialize(nil, nil, logger)
// error handling
tcpClient, err := cc.TCPClient()
// error handling
udpClient, err := cc.UDPClient()
// error handling
router, err := router.Config{}.Router(logger, nil, nil, map[string]zerocopy.TCPClient{"direct": tcpClient}, map[string]zerocopy.UDPClient{"direct": udpClient}, nil)
// error handling
// Then you copy the logic you need from service/server.go
I guess that will work, buy anyway, I would prefer not to touch internals and have some high-level API for all those initialization/creation things.
server := Config{}
server.Start(ctx)
...
server.UserAdd("foo", key)
server.UserRemove("foo")
...
server.Stop()
What you are proposing might look nice at first glance, but it's going to create a lot of mess when you start implementing it. It's fundamentally incompatible with shadowsocks-go's architecture.
The relay services (service.TCPRelay
, service.UDPNATRelay
, service.UDPSessionRelay
, service.UDPTransparentRelay
) don't create, own, or care about which protocol server they are running. You just hand it a server, and start the service. So it would look really out of place when you add protocol-specific methods to relay services.