//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd
// +build aix darwin dragonfly freebsd linux netbsd openbsd

package dns

import (
	
	
	

	
)

const supportsReusePort = true

func reuseportControl(,  string,  syscall.RawConn) error {
	var  error
	 := .Control(func( uintptr) {
		 = unix.SetsockoptInt(int(), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1)
	})
	if  != nil {
		return 
	}

	return 
}

const supportsReuseAddr = true

func reuseaddrControl(,  string,  syscall.RawConn) error {
	var  error
	 := .Control(func( uintptr) {
		 = unix.SetsockoptInt(int(), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1)
	})
	if  != nil {
		return 
	}

	return 
}

func reuseaddrandportControl(,  string,  syscall.RawConn) error {
	 := reuseaddrControl(, , )
	if  != nil {
		return 
	}

	return reuseportControl(, , )
}

// this is just for test compatibility
func checkReuseport( uintptr) (bool, error) {
	,  := unix.GetsockoptInt(int(), unix.SOL_SOCKET, unix.SO_REUSEPORT)
	if  != nil {
		return false, 
	}

	return  == 1, nil
}

// this is just for test compatibility
func checkReuseaddr( uintptr) (bool, error) {
	,  := unix.GetsockoptInt(int(), unix.SOL_SOCKET, unix.SO_REUSEADDR)
	if  != nil {
		return false, 
	}

	return  == 1, nil
}

func listenTCP(,  string, ,  bool) (net.Listener, error) {
	var  net.ListenConfig
	switch {
	case  && :
		.Control = reuseaddrandportControl
	case :
		.Control = reuseportControl
	case :
		.Control = reuseaddrControl
	}

	return .Listen(context.Background(), , )
}

func listenUDP(,  string, ,  bool) (net.PacketConn, error) {
	var  net.ListenConfig
	switch {
	case  && :
		.Control = reuseaddrandportControl
	case :
		.Control = reuseportControl
	case :
		.Control = reuseaddrControl
	}

	return .ListenPacket(context.Background(), , )
}