Browse Source

Merge pull request #1796 from slingamn/reverseproxy_exportable.1

factor out some shared code
tags/v2.8.0-rc1
Shivaram Lingamneni 2 years ago
parent
commit
3cf1583aed
No account linked to committer's email address
6 changed files with 68 additions and 57 deletions
  1. 8
    29
      irc/client.go
  2. 1
    1
      irc/config.go
  3. 1
    7
      irc/histserv.go
  4. 19
    0
      irc/panic.go
  5. 5
    20
      irc/server.go
  6. 34
    0
      irc/utils/net.go

+ 8
- 29
irc/client.go View File

@@ -488,40 +488,19 @@ func (client *Client) lookupHostname(session *Session, overwrite bool) {
488 488
 	if session.proxiedIP != nil {
489 489
 		ip = session.proxiedIP
490 490
 	}
491
-	ipString := ip.String()
492 491
 
493
-	var hostname, candidate string
492
+	var hostname string
493
+	lookupSuccessful := false
494 494
 	if config.Server.lookupHostnames {
495 495
 		session.Notice("*** Looking up your hostname...")
496
-
497
-		names, err := net.LookupAddr(ipString)
498
-		if err == nil && 0 < len(names) {
499
-			candidate = strings.TrimSuffix(names[0], ".")
500
-		}
501
-		if utils.IsHostname(candidate) {
502
-			if config.Server.ForwardConfirmHostnames {
503
-				addrs, err := net.LookupHost(candidate)
504
-				if err == nil {
505
-					for _, addr := range addrs {
506
-						if addr == ipString {
507
-							hostname = candidate // successful forward confirmation
508
-							break
509
-						}
510
-					}
511
-				}
512
-			} else {
513
-				hostname = candidate
514
-			}
515
-		}
516
-	}
517
-
518
-	if hostname != "" {
519
-		session.Notice("*** Found your hostname")
520
-	} else {
521
-		if config.Server.lookupHostnames {
496
+		hostname, lookupSuccessful = utils.LookupHostname(ip, config.Server.ForwardConfirmHostnames)
497
+		if lookupSuccessful {
498
+			session.Notice("*** Found your hostname")
499
+		} else {
522 500
 			session.Notice("*** Couldn't look up your hostname")
523 501
 		}
524
-		hostname = utils.IPStringToHostname(ipString)
502
+	} else {
503
+		hostname = utils.IPStringToHostname(ip.String())
525 504
 	}
526 505
 
527 506
 	session.rawHostname = hostname

+ 1
- 1
irc/config.go View File

@@ -650,7 +650,7 @@ type Config struct {
650 650
 	Debug struct {
651 651
 		RecoverFromErrors *bool `yaml:"recover-from-errors"`
652 652
 		recoverFromErrors bool
653
-		PprofListener     *string `yaml:"pprof-listener"`
653
+		PprofListener     string `yaml:"pprof-listener"`
654 654
 	}
655 655
 
656 656
 	Limits Limits

+ 1
- 7
irc/histserv.go View File

@@ -7,7 +7,6 @@ import (
7 7
 	"bufio"
8 8
 	"fmt"
9 9
 	"os"
10
-	"runtime/debug"
11 10
 	"strconv"
12 11
 	"time"
13 12
 
@@ -156,12 +155,7 @@ func histservExportHandler(service *ircService, server *Server, client *Client,
156 155
 }
157 156
 
158 157
 func histservExportAndNotify(service *ircService, server *Server, cfAccount string, outfile *os.File, filename, alertNick string) {
159
-	defer func() {
160
-		if r := recover(); r != nil {
161
-			server.logger.Error("history",
162
-				fmt.Sprintf("Panic in history export routine: %v\n%s", r, debug.Stack()))
163
-		}
164
-	}()
158
+	defer server.HandlePanic()
165 159
 
166 160
 	defer outfile.Close()
167 161
 	writer := bufio.NewWriter(outfile)

+ 19
- 0
irc/panic.go View File

@@ -0,0 +1,19 @@
1
+// Copyright (c) 2021 Shivaram Lingamneni
2
+// released under the MIT license
3
+
4
+package irc
5
+
6
+import (
7
+	"fmt"
8
+	"runtime/debug"
9
+)
10
+
11
+// HandlePanic is a general-purpose panic handler for ad-hoc goroutines.
12
+// Because of the semantics of `recover`, it must be called directly
13
+// from the routine on whose call stack the panic would occur, with `defer`,
14
+// e.g. `defer server.HandlePanic()`
15
+func (server *Server) HandlePanic() {
16
+	if r := recover(); r != nil {
17
+		server.logger.Error("internal", fmt.Sprintf("Panic encountered: %v\n%s", r, debug.Stack()))
18
+	}
19
+}

+ 5
- 20
irc/server.go View File

@@ -12,7 +12,6 @@ import (
12 12
 	_ "net/http/pprof"
13 13
 	"os"
14 14
 	"os/signal"
15
-	"runtime/debug"
16 15
 	"strconv"
17 16
 	"strings"
18 17
 	"sync"
@@ -245,14 +244,12 @@ func (server *Server) checkTorLimits() (banned bool, message string) {
245 244
 
246 245
 func (server *Server) handleAlwaysOnExpirations() {
247 246
 	defer func() {
248
-		if r := recover(); r != nil {
249
-			server.logger.Error("internal",
250
-				fmt.Sprintf("Panic in always-on cleanup: %v\n%s", r, debug.Stack()))
251
-		}
252
-		// either way, reschedule
247
+		// reschedule whether or not there was a panic
253 248
 		time.AfterFunc(alwaysOnExpirationPollPeriod, server.handleAlwaysOnExpirations)
254 249
 	}()
255 250
 
251
+	defer server.HandlePanic()
252
+
256 253
 	config := server.Config()
257 254
 	deadline := time.Duration(config.Accounts.Multiclient.AlwaysOnExpiration)
258 255
 	if deadline == 0 {
@@ -514,16 +511,7 @@ func (client *Client) getWhoisOf(target *Client, hasPrivs bool, rb *ResponseBuff
514 511
 // rehash reloads the config and applies the changes from the config file.
515 512
 func (server *Server) rehash() error {
516 513
 	// #1570; this needs its own panic handling because it can be invoked via SIGHUP
517
-	defer func() {
518
-		if r := recover(); r != nil {
519
-			if server.Config().Debug.recoverFromErrors {
520
-				server.logger.Error("internal",
521
-					fmt.Sprintf("Panic during rehash: %v\n%s", r, debug.Stack()))
522
-			} else {
523
-				panic(r)
524
-			}
525
-		}
526
-	}()
514
+	defer server.HandlePanic()
527 515
 
528 516
 	server.logger.Info("server", "Attempting rehash")
529 517
 
@@ -745,10 +733,7 @@ func (server *Server) applyConfig(config *Config) (err error) {
745 733
 }
746 734
 
747 735
 func (server *Server) setupPprofListener(config *Config) {
748
-	pprofListener := ""
749
-	if config.Debug.PprofListener != nil {
750
-		pprofListener = *config.Debug.PprofListener
751
-	}
736
+	pprofListener := config.Debug.PprofListener
752 737
 	if server.pprofServer != nil {
753 738
 		if pprofListener == "" || (pprofListener != server.pprofServer.Addr) {
754 739
 			server.logger.Info("server", "Stopping pprof listener", server.pprofServer.Addr)

+ 34
- 0
irc/utils/net.go View File

@@ -193,3 +193,37 @@ func HandleXForwardedFor(remoteAddr string, xForwardedFor string, whitelist []ne
193 193
 	// or nil:
194 194
 	return
195 195
 }
196
+
197
+// LookupHostname does an (optionally reverse-confirmed) hostname lookup
198
+// suitable for use as an IRC hostname. It falls back to a string
199
+// representation of the IP address (again suitable for use as an IRC
200
+// hostname).
201
+func LookupHostname(ip net.IP, forwardConfirm bool) (hostname string, lookupSuccessful bool) {
202
+	ipString := ip.String()
203
+	var candidate string
204
+	names, err := net.LookupAddr(ipString)
205
+	if err == nil && 0 < len(names) {
206
+		candidate = strings.TrimSuffix(names[0], ".")
207
+	}
208
+	if IsHostname(candidate) {
209
+		if forwardConfirm {
210
+			addrs, err := net.LookupHost(candidate)
211
+			if err == nil {
212
+				for _, addr := range addrs {
213
+					if forwardIP := net.ParseIP(addr); ip.Equal(forwardIP) {
214
+						hostname = candidate // successful forward confirmation
215
+						break
216
+					}
217
+				}
218
+			}
219
+		} else {
220
+			hostname = candidate
221
+		}
222
+	}
223
+
224
+	if hostname != "" {
225
+		return hostname, true
226
+	} else {
227
+		return IPStringToHostname(ipString), false
228
+	}
229
+}

Loading…
Cancel
Save