diff --git a/common/listener/listener_tcp.go b/common/listener/listener_tcp.go index 646d4017..61f73846 100644 --- a/common/listener/listener_tcp.go +++ b/common/listener/listener_tcp.go @@ -8,9 +8,11 @@ import ( "github.com/sagernet/sing-box/adapter" C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/log" + "github.com/sagernet/sing/common/control" E "github.com/sagernet/sing/common/exceptions" M "github.com/sagernet/sing/common/metadata" N "github.com/sagernet/sing/common/network" + "github.com/sagernet/sing/service" "github.com/metacubex/tfo-go" ) @@ -20,6 +22,15 @@ func (l *Listener) ListenTCP() (net.Listener, error) { bindAddr := M.SocksaddrFrom(l.listenOptions.Listen.Build(netip.AddrFrom4([4]byte{127, 0, 0, 1})), l.listenOptions.ListenPort) var tcpListener net.Listener var listenConfig net.ListenConfig + if l.listenOptions.BindInterface != "" { + listenConfig.Control = control.Append(listenConfig.Control, control.BindToInterface(service.FromContext[adapter.NetworkManager](l.ctx).InterfaceFinder(), l.listenOptions.BindInterface, -1)) + } + if l.listenOptions.RoutingMark != 0 { + listenConfig.Control = control.Append(listenConfig.Control, control.RoutingMark(uint32(l.listenOptions.RoutingMark))) + } + if l.listenOptions.ReuseAddr { + listenConfig.Control = control.Append(listenConfig.Control, control.ReuseAddr()) + } if l.listenOptions.TCPKeepAlive >= 0 { keepIdle := time.Duration(l.listenOptions.TCPKeepAlive) if keepIdle == 0 { diff --git a/common/listener/listener_udp.go b/common/listener/listener_udp.go index 10d6dc38..92f31a3c 100644 --- a/common/listener/listener_udp.go +++ b/common/listener/listener_udp.go @@ -5,16 +5,27 @@ import ( "net/netip" "os" + "github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing/common/buf" "github.com/sagernet/sing/common/control" E "github.com/sagernet/sing/common/exceptions" M "github.com/sagernet/sing/common/metadata" N "github.com/sagernet/sing/common/network" + "github.com/sagernet/sing/service" ) func (l *Listener) ListenUDP() (net.PacketConn, error) { bindAddr := M.SocksaddrFrom(l.listenOptions.Listen.Build(netip.AddrFrom4([4]byte{127, 0, 0, 1})), l.listenOptions.ListenPort) - var lc net.ListenConfig + var listenConfig net.ListenConfig + if l.listenOptions.BindInterface != "" { + listenConfig.Control = control.Append(listenConfig.Control, control.BindToInterface(service.FromContext[adapter.NetworkManager](l.ctx).InterfaceFinder(), l.listenOptions.BindInterface, -1)) + } + if l.listenOptions.RoutingMark != 0 { + listenConfig.Control = control.Append(listenConfig.Control, control.RoutingMark(uint32(l.listenOptions.RoutingMark))) + } + if l.listenOptions.ReuseAddr { + listenConfig.Control = control.Append(listenConfig.Control, control.ReuseAddr()) + } var udpFragment bool if l.listenOptions.UDPFragment != nil { udpFragment = *l.listenOptions.UDPFragment @@ -22,9 +33,9 @@ func (l *Listener) ListenUDP() (net.PacketConn, error) { udpFragment = l.listenOptions.UDPFragmentDefault } if !udpFragment { - lc.Control = control.Append(lc.Control, control.DisableUDPFragment()) + listenConfig.Control = control.Append(listenConfig.Control, control.DisableUDPFragment()) } - udpConn, err := lc.ListenPacket(l.ctx, M.NetworkFromNetAddr(N.NetworkUDP, bindAddr.Addr), bindAddr.String()) + udpConn, err := listenConfig.ListenPacket(l.ctx, M.NetworkFromNetAddr(N.NetworkUDP, bindAddr.Addr), bindAddr.String()) if err != nil { return nil, err } diff --git a/option/inbound.go b/option/inbound.go index 1cf16ff6..7f7e9e84 100644 --- a/option/inbound.go +++ b/option/inbound.go @@ -61,6 +61,9 @@ type InboundOptions struct { type ListenOptions struct { Listen *badoption.Addr `json:"listen,omitempty"` ListenPort uint16 `json:"listen_port,omitempty"` + BindInterface string `json:"bind_interface,omitempty"` + RoutingMark FwMark `json:"routing_mark,omitempty"` + ReuseAddr bool `json:"reuse_addr,omitempty"` TCPKeepAlive badoption.Duration `json:"tcp_keep_alive,omitempty"` TCPKeepAliveInterval badoption.Duration `json:"tcp_keep_alive_interval,omitempty"` TCPFastOpen bool `json:"tcp_fast_open,omitempty"`