Skip to content

http: listeners won't be closed if caddy fails to bind some of the addresses #7175

@WeidiDeng

Description

@WeidiDeng

It's possible to specify multiple addresses for caddy to bind using both Caddyfile and json, however caddy won't release those sockets if one of them fails to bind.

Consider the following Caddyfile,

{
    # debug
	skip_install_trust
	local_certs
    grace_period 10s
    servers :5001 {
        protocols h1 h2
    }
}

localhost:5001 {
}

Let's first run a program that binds port 5004,

package main

import (
	"net"
	"time"
)

func main() {
	_, err := net.Listen("tcp", "0.0.0.0:5004")
	if err != nil {
		panic(err)
	}
	time.Sleep(time.Minute)
}

While it's running, change the caddy config to this:

{
    # debug
	skip_install_trust
	local_certs
    grace_period 10s
    servers :5001 {
        protocols h1 h2
    }
}

localhost:5001 localhost:5002 localhost:5003 localhost:5004 {
}

caddy will refuse to use the new config with "error":"loading config: loading new config: http app module: start: listening on :5004: listen tcp :5004: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted."

Now it's impossible to bind to 5002 and 5003 because caddy uses them. Can be tested by

package main

import (
	"net"
	"time"
)

func main() {
	_, err := net.Listen("tcp", "0.0.0.0:5002")
	if err != nil {
		panic(err)
	}
	time.Sleep(time.Minute)
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug 🐞Something isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions