Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

explain cryptic unix socket listener error related to process kill #4534

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions listeners.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package caddy
import (
"fmt"
"net"
"os"
"strconv"
"strings"
"sync"
Expand All @@ -39,6 +40,10 @@ func Listen(network, addr string) (net.Listener, error) {
sharedLn, _, err := listenerPool.LoadOrNew(lnKey, func() (Destructor, error) {
ln, err := net.Listen(network, addr)
if err != nil {
// https://github.com/caddyserver/caddy/pull/4534
if isUnixNetwork(network) && isListenBindAddressAlreadyInUseError(err) {
return nil, fmt.Errorf("%w: this can happen if Caddy was forcefully killed", err)
}
return nil, err
}
return &sharedListener{Listener: ln, key: lnKey}, nil
Expand All @@ -59,6 +64,10 @@ func ListenPacket(network, addr string) (net.PacketConn, error) {
sharedPc, _, err := listenerPool.LoadOrNew(lnKey, func() (Destructor, error) {
pc, err := net.ListenPacket(network, addr)
if err != nil {
// https://github.com/caddyserver/caddy/pull/4534
if isUnixNetwork(network) && isListenBindAddressAlreadyInUseError(err) {
return nil, fmt.Errorf("%w: this can happen if Caddy was forcefully killed", err)
}
return nil, err
}
return &sharedPacketConn{PacketConn: pc, key: lnKey}, nil
Expand Down Expand Up @@ -322,6 +331,20 @@ func isUnixNetwork(netw string) bool {
return netw == "unix" || netw == "unixgram" || netw == "unixpacket"
}

func isListenBindAddressAlreadyInUseError(err error) bool {
switch networkOperationError := err.(type) {
case *net.OpError:
switch syscallError := networkOperationError.Err.(type) {
case *os.SyscallError:
if syscallError.Syscall == "bind" {
return true
}
}
}

return false
}

// ParseNetworkAddress parses addr into its individual
// components. The input string is expected to be of
// the form "network/host:port-range" where any part is
Expand Down