Browse Source

Merge remote-tracking branch 'slingmann/recovery'

tags/v0.10.1
Daniel Oaks 6 years ago
parent
commit
c6b6a25906
5 changed files with 37 additions and 8 deletions
  1. 14
    3
      irc/client.go
  2. 2
    1
      irc/config.go
  3. 6
    0
      irc/getters.go
  4. 7
    4
      irc/server.go
  5. 8
    0
      oragono.yaml

+ 14
- 3
irc/client.go View File

197
 	var line string
197
 	var line string
198
 	var msg ircmsg.IrcMessage
198
 	var msg ircmsg.IrcMessage
199
 
199
 
200
+	defer func() {
201
+		if r := recover(); r != nil {
202
+			client.server.logger.Error("internal",
203
+				fmt.Sprintf("Client caused panic: %v\n%s", r, debug.Stack()))
204
+			if client.server.RecoverFromErrors() {
205
+				client.server.logger.Error("internal", "Disconnecting client and attempting to recover")
206
+			} else {
207
+				panic(r)
208
+			}
209
+		}
210
+		// ensure client connection gets closed
211
+		client.destroy()
212
+	}()
213
+
200
 	client.idletimer = NewIdleTimer(client)
214
 	client.idletimer = NewIdleTimer(client)
201
 	client.idletimer.Start()
215
 	client.idletimer.Start()
202
 
216
 
238
 			break
252
 			break
239
 		}
253
 		}
240
 	}
254
 	}
241
-
242
-	// ensure client connection gets closed
243
-	client.destroy()
244
 }
255
 }
245
 
256
 
246
 //
257
 //

+ 2
- 1
irc/config.go View File

188
 	Logging []logger.LoggingConfig
188
 	Logging []logger.LoggingConfig
189
 
189
 
190
 	Debug struct {
190
 	Debug struct {
191
-		StackImpact StackImpactConfig
191
+		RecoverFromErrors *bool `yaml:"recover-from-errors"`
192
+		StackImpact       StackImpactConfig
192
 	}
193
 	}
193
 
194
 
194
 	Limits struct {
195
 	Limits struct {

+ 6
- 0
irc/getters.go View File

23
 	return server.password
23
 	return server.password
24
 }
24
 }
25
 
25
 
26
+func (server *Server) RecoverFromErrors() bool {
27
+	server.configurableStateMutex.RLock()
28
+	defer server.configurableStateMutex.RUnlock()
29
+	return server.recoverFromErrors
30
+}
31
+
26
 func (server *Server) ProxyAllowedFrom() []string {
32
 func (server *Server) ProxyAllowedFrom() []string {
27
 	server.configurableStateMutex.RLock()
33
 	server.configurableStateMutex.RLock()
28
 	defer server.configurableStateMutex.RUnlock()
34
 	defer server.configurableStateMutex.RUnlock()

+ 7
- 4
irc/server.go View File

109
 	operclasses                  map[string]OperClass
109
 	operclasses                  map[string]OperClass
110
 	password                     []byte
110
 	password                     []byte
111
 	passwords                    *passwd.SaltedManager
111
 	passwords                    *passwd.SaltedManager
112
+	recoverFromErrors            bool
112
 	registeredChannels           map[string]*RegisteredChannel
113
 	registeredChannels           map[string]*RegisteredChannel
113
 	registeredChannelsMutex      sync.RWMutex
114
 	registeredChannelsMutex      sync.RWMutex
114
 	rehashMutex                  sync.Mutex
115
 	rehashMutex                  sync.Mutex
1239
 		server.name = config.Server.Name
1240
 		server.name = config.Server.Name
1240
 		server.nameCasefolded = casefoldedName
1241
 		server.nameCasefolded = casefoldedName
1241
 	}
1242
 	}
1242
-	server.networkName = config.Network.Name
1243
 
1243
 
1244
 	server.configurableStateMutex.Lock()
1244
 	server.configurableStateMutex.Lock()
1245
+	server.networkName = config.Network.Name
1245
 	if config.Server.Password != "" {
1246
 	if config.Server.Password != "" {
1246
 		server.password = config.Server.PasswordBytes()
1247
 		server.password = config.Server.PasswordBytes()
1247
 	} else {
1248
 	} else {
1248
 		server.password = nil
1249
 		server.password = nil
1249
 	}
1250
 	}
1250
-	server.configurableStateMutex.Unlock()
1251
-
1252
 	// apply new WebIRC command restrictions
1251
 	// apply new WebIRC command restrictions
1253
 	server.webirc = config.Server.WebIRC
1252
 	server.webirc = config.Server.WebIRC
1254
-
1255
 	// apply new PROXY command restrictions
1253
 	// apply new PROXY command restrictions
1256
 	server.proxyAllowedFrom = config.Server.ProxyAllowedFrom
1254
 	server.proxyAllowedFrom = config.Server.ProxyAllowedFrom
1255
+	server.recoverFromErrors = true
1256
+	if config.Debug.RecoverFromErrors != nil {
1257
+		server.recoverFromErrors = *config.Debug.RecoverFromErrors
1258
+	}
1259
+	server.configurableStateMutex.Unlock()
1257
 
1260
 
1258
 	err = server.connectionLimiter.ApplyConfig(config.Server.ConnectionLimiter)
1261
 	err = server.connectionLimiter.ApplyConfig(config.Server.ConnectionLimiter)
1259
 	if err != nil {
1262
 	if err != nil {

+ 8
- 0
oragono.yaml View File

267
 
267
 
268
 # debug options
268
 # debug options
269
 debug:
269
 debug:
270
+    # when enabled, oragono will attempt to recover from certain kinds of
271
+    # client-triggered runtime errors that would normally crash the server.
272
+    # this makes the server more resilient to DoS, but could result in incorrect
273
+    # behavior. deployments that would prefer to "start from scratch", e.g., by
274
+    # letting the process crash and auto-restarting it with systemd, can set
275
+    # this to false.
276
+    recover-from-errors: true
277
+
270
     # enabling StackImpact profiling
278
     # enabling StackImpact profiling
271
     stackimpact:
279
     stackimpact:
272
         # whether to use StackImpact
280
         # whether to use StackImpact

Loading…
Cancel
Save