mirror of
https://github.com/apernet/hysteria.git
synced 2025-04-03 04:27:39 +03:00
Merge pull request #842 from apernet/fix-wildcard-listen
fix: ipv{4,6}-only listen on wildcard address
This commit is contained in:
commit
21cd348c8b
4 changed files with 109 additions and 8 deletions
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/apernet/hysteria/app/internal/url"
|
||||
"github.com/apernet/hysteria/app/internal/utils"
|
||||
"github.com/apernet/hysteria/core/client"
|
||||
"github.com/apernet/hysteria/extras/correctnet"
|
||||
"github.com/apernet/hysteria/extras/obfs"
|
||||
"github.com/apernet/hysteria/extras/transport/udphop"
|
||||
)
|
||||
|
@ -504,7 +505,7 @@ func clientSOCKS5(config socks5Config, c client.Client) error {
|
|||
if config.Listen == "" {
|
||||
return configError{Field: "listen", Err: errors.New("listen address is empty")}
|
||||
}
|
||||
l, err := net.Listen("tcp", config.Listen)
|
||||
l, err := correctnet.Listen("tcp", config.Listen)
|
||||
if err != nil {
|
||||
return configError{Field: "listen", Err: err}
|
||||
}
|
||||
|
@ -529,7 +530,7 @@ func clientHTTP(config httpConfig, c client.Client) error {
|
|||
if config.Listen == "" {
|
||||
return configError{Field: "listen", Err: errors.New("listen address is empty")}
|
||||
}
|
||||
l, err := net.Listen("tcp", config.Listen)
|
||||
l, err := correctnet.Listen("tcp", config.Listen)
|
||||
if err != nil {
|
||||
return configError{Field: "listen", Err: err}
|
||||
}
|
||||
|
@ -562,7 +563,7 @@ func clientTCPForwarding(entries []tcpForwardingEntry, c client.Client) error {
|
|||
if e.Remote == "" {
|
||||
return configError{Field: "remote", Err: errors.New("remote address is empty")}
|
||||
}
|
||||
l, err := net.Listen("tcp", e.Listen)
|
||||
l, err := correctnet.Listen("tcp", e.Listen)
|
||||
if err != nil {
|
||||
return configError{Field: "listen", Err: err}
|
||||
}
|
||||
|
@ -589,7 +590,7 @@ func clientUDPForwarding(entries []udpForwardingEntry, c client.Client) error {
|
|||
if e.Remote == "" {
|
||||
return configError{Field: "remote", Err: errors.New("remote address is empty")}
|
||||
}
|
||||
l, err := net.ListenPacket("udp", e.Listen)
|
||||
l, err := correctnet.ListenPacket("udp", e.Listen)
|
||||
if err != nil {
|
||||
return configError{Field: "listen", Err: err}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/apernet/hysteria/app/internal/utils"
|
||||
"github.com/apernet/hysteria/core/server"
|
||||
"github.com/apernet/hysteria/extras/auth"
|
||||
"github.com/apernet/hysteria/extras/correctnet"
|
||||
"github.com/apernet/hysteria/extras/masq"
|
||||
"github.com/apernet/hysteria/extras/obfs"
|
||||
"github.com/apernet/hysteria/extras/outbounds"
|
||||
|
@ -219,7 +220,7 @@ func (c *serverConfig) fillConn(hyConfig *server.Config) error {
|
|||
if err != nil {
|
||||
return configError{Field: "listen", Err: err}
|
||||
}
|
||||
conn, err := net.ListenUDP("udp", uAddr)
|
||||
conn, err := correctnet.ListenUDP("udp", uAddr)
|
||||
if err != nil {
|
||||
return configError{Field: "listen", Err: err}
|
||||
}
|
||||
|
@ -752,7 +753,7 @@ func runServer(cmd *cobra.Command, args []string) {
|
|||
|
||||
func runTrafficStatsServer(listen string, handler http.Handler) {
|
||||
logger.Info("traffic stats server up and running", zap.String("listen", listen))
|
||||
if err := http.ListenAndServe(listen, handler); err != nil {
|
||||
if err := correctnet.HTTPListenAndServe(listen, handler); err != nil {
|
||||
logger.Fatal("failed to serve traffic stats", zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
|
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, 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, 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) error {
|
||||
listener, err := Listen("tcp", address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer listener.Close()
|
||||
return http.Serve(listener, handler)
|
||||
}
|
|
@ -6,6 +6,8 @@ import (
|
|||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/apernet/hysteria/extras/correctnet"
|
||||
)
|
||||
|
||||
// MasqTCPServer covers the TCP parts of a standard web server (TCP based HTTP/HTTPS).
|
||||
|
@ -20,7 +22,7 @@ type MasqTCPServer struct {
|
|||
}
|
||||
|
||||
func (s *MasqTCPServer) ListenAndServeHTTP(addr string) error {
|
||||
return http.ListenAndServe(addr, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
return correctnet.HTTPListenAndServe(addr, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if s.ForceHTTPS {
|
||||
if s.HTTPSPort == 0 || s.HTTPSPort == 443 {
|
||||
// Omit port if it's the default
|
||||
|
@ -42,7 +44,12 @@ func (s *MasqTCPServer) ListenAndServeHTTPS(addr string) error {
|
|||
}),
|
||||
TLSConfig: s.TLSConfig,
|
||||
}
|
||||
return server.ListenAndServeTLS("", "")
|
||||
listener, err := correctnet.Listen("tcp", addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer listener.Close()
|
||||
return server.ServeTLS(listener, "", "")
|
||||
}
|
||||
|
||||
var _ http.ResponseWriter = (*altSvcHijackResponseWriter)(nil)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue