factor out some shared code

This commit is contained in:
Shivaram Lingamneni 2021-09-18 21:28:16 -04:00
parent 657ce0f1a4
commit e0e4791f72
5 changed files with 66 additions and 52 deletions

View File

@ -488,40 +488,19 @@ func (client *Client) lookupHostname(session *Session, overwrite bool) {
if session.proxiedIP != nil {
ip = session.proxiedIP
}
ipString := ip.String()
var hostname, candidate string
var hostname string
lookupSuccessful := false
if config.Server.lookupHostnames {
session.Notice("*** Looking up your hostname...")
names, err := net.LookupAddr(ipString)
if err == nil && 0 < len(names) {
candidate = strings.TrimSuffix(names[0], ".")
}
if utils.IsHostname(candidate) {
if config.Server.ForwardConfirmHostnames {
addrs, err := net.LookupHost(candidate)
if err == nil {
for _, addr := range addrs {
if addr == ipString {
hostname = candidate // successful forward confirmation
break
}
}
}
} else {
hostname = candidate
}
}
}
if hostname != "" {
session.Notice("*** Found your hostname")
} else {
if config.Server.lookupHostnames {
hostname, lookupSuccessful = utils.LookupHostname(ip, config.Server.ForwardConfirmHostnames)
if lookupSuccessful {
session.Notice("*** Found your hostname")
} else {
session.Notice("*** Couldn't look up your hostname")
}
hostname = utils.IPStringToHostname(ipString)
} else {
hostname = utils.IPStringToHostname(ip.String())
}
session.rawHostname = hostname

View File

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

19
irc/panic.go Normal file
View File

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

View File

@ -12,7 +12,6 @@ import (
_ "net/http/pprof"
"os"
"os/signal"
"runtime/debug"
"strconv"
"strings"
"sync"
@ -245,14 +244,12 @@ func (server *Server) checkTorLimits() (banned bool, message string) {
func (server *Server) handleAlwaysOnExpirations() {
defer func() {
if r := recover(); r != nil {
server.logger.Error("internal",
fmt.Sprintf("Panic in always-on cleanup: %v\n%s", r, debug.Stack()))
}
// either way, reschedule
// reschedule whether or not there was a panic
time.AfterFunc(alwaysOnExpirationPollPeriod, server.handleAlwaysOnExpirations)
}()
defer server.HandlePanic()
config := server.Config()
deadline := time.Duration(config.Accounts.Multiclient.AlwaysOnExpiration)
if deadline == 0 {
@ -514,16 +511,7 @@ func (client *Client) getWhoisOf(target *Client, hasPrivs bool, rb *ResponseBuff
// rehash reloads the config and applies the changes from the config file.
func (server *Server) rehash() error {
// #1570; this needs its own panic handling because it can be invoked via SIGHUP
defer func() {
if r := recover(); r != nil {
if server.Config().Debug.recoverFromErrors {
server.logger.Error("internal",
fmt.Sprintf("Panic during rehash: %v\n%s", r, debug.Stack()))
} else {
panic(r)
}
}
}()
defer server.HandlePanic()
server.logger.Info("server", "Attempting rehash")

View File

@ -193,3 +193,37 @@ func HandleXForwardedFor(remoteAddr string, xForwardedFor string, whitelist []ne
// or nil:
return
}
// LookupHostname does an (optionally reverse-confirmed) hostname lookup
// suitable for use as an IRC hostname. It falls back to a string
// representation of the IP address (again suitable for use as an IRC
// hostname).
func LookupHostname(ip net.IP, forwardConfirm bool) (hostname string, lookupSuccessful bool) {
ipString := ip.String()
var candidate string
names, err := net.LookupAddr(ipString)
if err == nil && 0 < len(names) {
candidate = strings.TrimSuffix(names[0], ".")
}
if IsHostname(candidate) {
if forwardConfirm {
addrs, err := net.LookupHost(candidate)
if err == nil {
for _, addr := range addrs {
if forwardIP := net.ParseIP(addr); ip.Equal(forwardIP) {
hostname = candidate // successful forward confirmation
break
}
}
}
} else {
hostname = candidate
}
}
if hostname != "" {
return hostname, true
} else {
return IPStringToHostname(ipString), false
}
}