mirror of
https://github.com/cmz0228/hysteria-dev.git
synced 2025-09-21 07:26:02 +00:00
fix: ipv{4,6}-only listen on wildcard address
fix: #797 when listening on a wildcard address like "0.0.0.0" or "[::]", hysteria actually listened on both IPv4 and IPv6. this is a well-known bug of the golang net package. this commit introduces a fix for that, the intended behavior will be: 0.0.0.0:443 => listen on IPv4 only [::]:443 => listen on IPv6 only :443 => listen on both IPv4 and IPv6
This commit is contained in:
92
extras/correctnet/correctnet.go
Normal file
92
extras/correctnet/correctnet.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package correctnet
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func extractIPFamily(ip net.IP) (family string) {
|
||||
if len(ip) == 0 {
|
||||
// real family independent wildcard address, such as ":443"
|
||||
return ""
|
||||
}
|
||||
if p4 := ip.To4(); len(p4) == net.IPv4len {
|
||||
return "4"
|
||||
}
|
||||
return "6"
|
||||
}
|
||||
|
||||
func tcpAddrNetwork(addr *net.TCPAddr) (network string) {
|
||||
if addr == nil {
|
||||
return "tcp"
|
||||
}
|
||||
return "tcp" + extractIPFamily(addr.IP)
|
||||
}
|
||||
|
||||
func udpAddrNetwork(addr *net.UDPAddr) (network string) {
|
||||
if addr == nil {
|
||||
return "udp"
|
||||
}
|
||||
return "udp" + extractIPFamily(addr.IP)
|
||||
}
|
||||
|
||||
func ipAddrNetwork(addr *net.IPAddr) (network string) {
|
||||
if addr == nil {
|
||||
return "ip"
|
||||
}
|
||||
return "ip" + extractIPFamily(addr.IP)
|
||||
}
|
||||
|
||||
func Listen(network string, address string) (net.Listener, error) {
|
||||
if network == "tcp" {
|
||||
tcpAddr, err := net.ResolveTCPAddr(network, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ListenTCP(network, tcpAddr)
|
||||
}
|
||||
return net.Listen(network, address)
|
||||
}
|
||||
|
||||
func ListenTCP(network string, laddr *net.TCPAddr) (*net.TCPListener, error) {
|
||||
if network == "tcp" {
|
||||
return net.ListenTCP(tcpAddrNetwork(laddr), laddr)
|
||||
}
|
||||
return net.ListenTCP(network, laddr)
|
||||
}
|
||||
|
||||
func ListenPacket(network string, address string) (listener net.PacketConn, err error) {
|
||||
if network == "udp" {
|
||||
udpAddr, err := net.ResolveUDPAddr(network, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ListenUDP(network, udpAddr)
|
||||
}
|
||||
if strings.HasPrefix(network, "ip:") {
|
||||
proto := network[3:]
|
||||
ipAddr, err := net.ResolveIPAddr(proto, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return net.ListenIP(ipAddrNetwork(ipAddr)+":"+proto, ipAddr)
|
||||
}
|
||||
return net.ListenPacket(network, address)
|
||||
}
|
||||
|
||||
func ListenUDP(network string, laddr *net.UDPAddr) (*net.UDPConn, error) {
|
||||
if network == "udp" {
|
||||
return net.ListenUDP(udpAddrNetwork(laddr), laddr)
|
||||
}
|
||||
return net.ListenUDP(network, laddr)
|
||||
}
|
||||
|
||||
func HTTPListenAndServe(address string, handler http.Handler) (err error) {
|
||||
listener, err := Listen("tcp", address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer listener.Close()
|
||||
return http.Serve(listener, handler)
|
||||
}
|
Reference in New Issue
Block a user