@@ -16,20 +16,16 @@ package main
16
16
17
17
import (
18
18
"container/list"
19
- "context"
20
19
"flag"
21
20
"fmt"
22
- "net"
23
21
"net/http"
24
22
"os"
25
23
"os/signal"
26
24
"strings"
27
25
"syscall"
28
26
"time"
29
27
30
- "github.com/Jigsaw-Code/outline-sdk/transport"
31
28
"github.com/Jigsaw-Code/outline-sdk/transport/shadowsocks"
32
-
33
29
"github.com/Jigsaw-Code/outline-ss-server/ipinfo"
34
30
"github.com/Jigsaw-Code/outline-ss-server/service"
35
31
"github.com/op/go-logging"
@@ -60,159 +56,11 @@ func init() {
60
56
logger = logging .MustGetLogger ("" )
61
57
}
62
58
63
- // The implementations of listeners for different network types are not
64
- // interchangeable. The type of listener depends on the network type.
65
- // TODO(sbruens): Create a custom `Listener` type so we can share serving logic,
66
- // dispatching to the handlers based on connection type instead of on the
67
- // listener type.
68
- type Listener = any
69
-
70
- type Service struct {
71
- natTimeout time.Duration
72
- m * outlineMetrics
73
- replayCache * service.ReplayCache
74
- Listeners []Listener
75
- Ciphers * list.List // Values are *List of *CipherEntry.
76
- }
77
-
78
- func (s * Service ) Serve (addr NetworkAddr , listener Listener , cipherList service.CipherList ) error {
79
- switch ln := listener .(type ) {
80
- case net.Listener :
81
- authFunc := service .NewShadowsocksStreamAuthenticator (cipherList , s .replayCache , s .m )
82
- // TODO: Register initial data metrics at zero.
83
- tcpHandler := service .NewTCPHandler (addr .Key (), authFunc , s .m , tcpReadTimeout )
84
- accept := func () (transport.StreamConn , error ) {
85
- c , err := ln .Accept ()
86
- if err == nil {
87
- return c .(transport.StreamConn ), err
88
- }
89
- return nil , err
90
- }
91
- go service .StreamServe (accept , tcpHandler .Handle )
92
- case net.PacketConn :
93
- packetHandler := service .NewPacketHandler (s .natTimeout , cipherList , s .m )
94
- go packetHandler .Handle (ln )
95
- default :
96
- return fmt .Errorf ("unknown listener type: %v" , ln )
97
- }
98
- return nil
99
- }
100
-
101
- func (s * Service ) Stop () error {
102
- for _ , listener := range s .Listeners {
103
- switch ln := listener .(type ) {
104
- case net.Listener :
105
- if err := ln .Close (); err != nil {
106
- //lint:ignore ST1005 Shadowsocks is capitalized.
107
- return fmt .Errorf ("Shadowsocks %s service on address %s failed to stop: %w" , ln .Addr ().Network (), ln .Addr ().String (), err )
108
- }
109
- case net.PacketConn :
110
- if err := ln .Close (); err != nil {
111
- //lint:ignore ST1005 Shadowsocks is capitalized.
112
- return fmt .Errorf ("Shadowsocks %s service on address %s failed to stop: %w" , ln .LocalAddr ().Network (), ln .LocalAddr ().String (), err )
113
- }
114
- default :
115
- return fmt .Errorf ("unknown listener type: %v" , ln )
116
- }
117
- }
118
- return nil
119
- }
120
-
121
- // AddListener adds a new listener to the service.
122
- func (s * Service ) AddListener (addr NetworkAddr ) error {
123
- // Create new listeners based on the configured network addresses.
124
- cipherList := service .NewCipherList ()
125
- cipherList .Update (s .Ciphers )
126
-
127
- listener , err := addr .Listen (context .TODO (), net.ListenConfig {KeepAlive : 0 })
128
- if err != nil {
129
- //lint:ignore ST1005 Shadowsocks is capitalized.
130
- return fmt .Errorf ("Shadowsocks %s service failed to start on address %s: %w" , addr .Network (), addr .String (), err )
131
- }
132
- s .Listeners = append (s .Listeners , listener )
133
- logger .Infof ("Shadowsocks %s service listening on %s" , addr .Network (), addr .String ())
134
- if err = s .Serve (addr , listener , cipherList ); err != nil {
135
- return fmt .Errorf ("failed to serve on %s listener on address %s: %w" , addr .Network (), addr .String (), err )
136
- }
137
- return nil
138
- }
139
-
140
- // NewService creates a new Service.
141
- func NewService (config ServiceConfig , natTimeout time.Duration , m * outlineMetrics , replayCache * service.ReplayCache ) (* Service , error ) {
142
- s := Service {
143
- natTimeout : natTimeout ,
144
- m : m ,
145
- replayCache : replayCache ,
146
- Ciphers : list .New (),
147
- }
148
-
149
- type cipherKey struct {
150
- cipher string
151
- secret string
152
- }
153
- existingCiphers := make (map [cipherKey ]bool )
154
- for _ , keyConfig := range config .Keys {
155
- key := cipherKey {keyConfig .Cipher , keyConfig .Secret }
156
- if _ , exists := existingCiphers [key ]; exists {
157
- logger .Debugf ("encryption key already exists for ID=`%v`. Skipping." , keyConfig .ID )
158
- continue
159
- }
160
- cryptoKey , err := shadowsocks .NewEncryptionKey (keyConfig .Cipher , keyConfig .Secret )
161
- if err != nil {
162
- return nil , fmt .Errorf ("failed to create encyption key for key %v: %w" , keyConfig .ID , err )
163
- }
164
- entry := service .MakeCipherEntry (keyConfig .ID , cryptoKey , keyConfig .Secret )
165
- s .Ciphers .PushBack (& entry )
166
- existingCiphers [key ] = true
167
- }
168
-
169
- for _ , listener := range config .Listeners {
170
- addr , err := ParseNetworkAddr (listener .Address )
171
- if err != nil {
172
- return nil , fmt .Errorf ("error parsing listener address `%s`: %v" , listener .Address , err )
173
- }
174
- if err := s .AddListener (addr ); err != nil {
175
- return nil , err
176
- }
177
- }
178
-
179
- return & s , nil
180
- }
181
-
182
- func NewLegacyKeyService (config LegacyKeyServiceConfig , natTimeout time.Duration , m * outlineMetrics , replayCache * service.ReplayCache ) (* Service , error ) {
183
- s := Service {
184
- natTimeout : natTimeout ,
185
- m : m ,
186
- replayCache : replayCache ,
187
- Ciphers : list .New (),
188
- }
189
-
190
- cryptoKey , err := shadowsocks .NewEncryptionKey (config .Cipher , config .Secret )
191
- if err != nil {
192
- return nil , fmt .Errorf ("failed to create encyption key for key %v: %w" , config .ID , err )
193
- }
194
- entry := service .MakeCipherEntry (config .ID , cryptoKey , config .Secret )
195
- s .Ciphers .PushBack (& entry )
196
-
197
- for _ , network := range []string {"tcp" , "udp" } {
198
- addr := NetworkAddr {
199
- network : network ,
200
- Host : "::" ,
201
- Port : uint (config .Port ),
202
- }
203
- if err := s .AddListener (addr ); err != nil {
204
- return nil , err
205
- }
206
- }
207
-
208
- return & s , nil
209
- }
210
-
211
59
type SSServer struct {
212
60
natTimeout time.Duration
213
61
m * outlineMetrics
214
62
replayCache service.ReplayCache
215
- services []Service
63
+ services []* Service
216
64
}
217
65
218
66
func (s * SSServer ) loadConfig (filename string ) error {
@@ -231,39 +79,64 @@ func (s *SSServer) loadConfig(filename string) error {
231
79
// We hot swap the services by having them both live at the same time. This
232
80
// means we create services for the new config first, and then take down the
233
81
// services from the old config.
234
- newServices := make ([]Service , 0 )
82
+ newServices := make ([]* Service , 0 )
83
+
84
+ legacyPortService := make (map [int ]* Service ) // Values are *List of *CipherEntry.
235
85
for _ , legacyKeyServiceConfig := range config .Keys {
236
- service , err := NewLegacyKeyService (legacyKeyServiceConfig , s .natTimeout , s .m , & s .replayCache )
86
+ legacyService , ok := legacyPortService [legacyKeyServiceConfig .Port ]
87
+ if ! ok {
88
+ legacyService = & Service {
89
+ natTimeout : s .natTimeout ,
90
+ m : s .m ,
91
+ replayCache : & s .replayCache ,
92
+ ciphers : list .New (),
93
+ }
94
+ for _ , network := range []string {"tcp" , "udp" } {
95
+ addr := NetworkAddr {
96
+ network : network ,
97
+ Host : "::" ,
98
+ Port : uint (legacyKeyServiceConfig .Port ),
99
+ }
100
+ if err := legacyService .AddListener (addr ); err != nil {
101
+ return err
102
+ }
103
+ }
104
+ newServices = append (newServices , legacyService )
105
+ legacyPortService [legacyKeyServiceConfig .Port ] = legacyService
106
+ }
107
+ cryptoKey , err := shadowsocks .NewEncryptionKey (legacyKeyServiceConfig .Cipher , legacyKeyServiceConfig .Secret )
237
108
if err != nil {
238
- return fmt .Errorf ("Failed to create new service: %v" , err )
109
+ return fmt .Errorf ("failed to create encyption key for key %v: %w" , legacyKeyServiceConfig . ID , err )
239
110
}
240
- newServices = append (newServices , * service )
111
+ entry := service .MakeCipherEntry (legacyKeyServiceConfig .ID , cryptoKey , legacyKeyServiceConfig .Secret )
112
+ legacyService .AddCipher (& entry )
241
113
}
114
+
242
115
for _ , serviceConfig := range config .Services {
243
116
service , err := NewService (serviceConfig , s .natTimeout , s .m , & s .replayCache )
244
117
if err != nil {
245
118
return fmt .Errorf ("Failed to create new service: %v" , err )
246
119
}
247
- newServices = append (newServices , * service )
120
+ newServices = append (newServices , service )
248
121
}
122
+ logger .Infof ("Loaded %d new services" , len (newServices ))
249
123
250
124
// Take down the old services now that the new ones are created and serving.
251
125
if err := s .Stop (); err != nil {
252
126
logger .Errorf ("Failed to stop old services: %w" , err )
253
127
}
254
128
s .services = newServices
255
129
256
- // Gather some basic stats for logging.
257
130
var (
258
131
listenerCount int
259
132
cipherCount int
260
133
)
261
134
for _ , service := range s .services {
262
- listenerCount += len ( service .Listeners )
263
- cipherCount += service .Ciphers . Len ()
135
+ listenerCount += service .NumListeners ( )
136
+ cipherCount += service .NumCiphers ()
264
137
}
265
- logger .Infof ("Loaded %d services with %d access keys over %d listeners" , len (s .services ), cipherCount , listenerCount )
266
- s .m .SetNumAccessKeys (cipherCount , len ( s . services ) )
138
+ logger .Infof ("%d services active: %d access keys over %d listeners" , len (s .services ), cipherCount , listenerCount )
139
+ s .m .SetNumAccessKeys (cipherCount , listenerCount )
267
140
return nil
268
141
}
269
142
@@ -272,13 +145,13 @@ func (s *SSServer) Stop() error {
272
145
if len (s .services ) == 0 {
273
146
return nil
274
147
}
275
-
276
148
for _ , service := range s .services {
277
149
if err := service .Stop (); err != nil {
278
150
return err
279
151
}
280
152
}
281
153
logger .Infof ("Stopped %d old services" , len (s .services ))
154
+ s .services = nil
282
155
return nil
283
156
}
284
157
0 commit comments