Skip to content

proposal: net: Add control callback before connection creation to Dialer and ListenConfig #54314

@leonshaw

Description

@leonshaw

Background

Sometimes we need to dial inside another net namespace and switch back. On linux, namespace is thread-level, so a thread lock is needed.

With "github.com/vishvananda/netns" for example:

func connect(target string, network, addr string) net.Conn {
	dialer := &net.Dialer{}
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()
	origNS, _ := netns.Get()
	targetNS, _ := netns.GetFromName(target)
	netns.Set(targetNS)
	defer netns.Set(origNS)
	conn, _ := dialer.Dial(network, addr)
	return conn
}

However, this blocks the current thread until Dial() returns. A workaround may be moving the unlocking stuff into dialer.Control:

	dialer.Control = func(network, address string, c syscall.RawConn) error {
		netns.Set(origNS)
		runtime.UnlockOSThread()
		return nil
	}

This doesn't work well because dialParallel() dials in new goroutines which are out of control.

Proposal

Add callback before and after the connection (socket) is created in net.Dialer:

type Dialer struct {
	PreControl func(network, address string) error
	PostControl func(network, address string) error
}

The call of PreControl - PostControl pair should be in the same goroutine and surround the socket syscall. PostControl should be called regardless of whether the conn is successfully created.

Similar thing can be done with net.ListenConfig.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    Incoming

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions