mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-06-13 21:54:13 +08:00
Add systemd socket activation support
This commit is contained in:
parent
018ee8921e
commit
15ffe148d4
@ -14,6 +14,8 @@ import (
|
|||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ adapter.Inbound = (*myInboundAdapter)(nil)
|
var _ adapter.Inbound = (*myInboundAdapter)(nil)
|
||||||
@ -38,6 +40,8 @@ type myInboundAdapter struct {
|
|||||||
|
|
||||||
// internal
|
// internal
|
||||||
|
|
||||||
|
tcpFd int
|
||||||
|
udpFd int
|
||||||
tcpListener net.Listener
|
tcpListener net.Listener
|
||||||
udpConn *net.UDPConn
|
udpConn *net.UDPConn
|
||||||
udpAddr M.Socksaddr
|
udpAddr M.Socksaddr
|
||||||
@ -111,6 +115,24 @@ func (a *myInboundAdapter) Close() error {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *myInboundAdapter) initFds() {
|
||||||
|
if len(a.listenOptions.Fds) != 0 && a.tcpFd == 0 && a.udpFd == 0 {
|
||||||
|
for _, fd := range a.listenOptions.Fds {
|
||||||
|
sotype, err := unix.GetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_TYPE)
|
||||||
|
if err != nil {
|
||||||
|
a.logger.Error("fd:", fd, " get type error: ", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch sotype {
|
||||||
|
case unix.SOCK_STREAM:
|
||||||
|
a.tcpFd = fd
|
||||||
|
case unix.SOCK_DGRAM:
|
||||||
|
a.udpFd = fd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (a *myInboundAdapter) upstreamHandler(metadata adapter.InboundContext) adapter.UpstreamHandlerAdapter {
|
func (a *myInboundAdapter) upstreamHandler(metadata adapter.InboundContext) adapter.UpstreamHandlerAdapter {
|
||||||
return adapter.NewUpstreamHandler(metadata, a.newConnection, a.streamPacketConnection, a)
|
return adapter.NewUpstreamHandler(metadata, a.newConnection, a.streamPacketConnection, a)
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package inbound
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
"github.com/sagernet/sing-box/common/proxyproto"
|
"github.com/sagernet/sing-box/common/proxyproto"
|
||||||
@ -15,12 +16,25 @@ import (
|
|||||||
|
|
||||||
func (a *myInboundAdapter) ListenTCP() (net.Listener, error) {
|
func (a *myInboundAdapter) ListenTCP() (net.Listener, error) {
|
||||||
var err error
|
var err error
|
||||||
bindAddr := M.SocksaddrFrom(a.listenOptions.Listen.Build(), a.listenOptions.ListenPort)
|
|
||||||
var tcpListener net.Listener
|
var tcpListener net.Listener
|
||||||
if !a.listenOptions.TCPFastOpen {
|
a.initFds()
|
||||||
tcpListener, err = net.ListenTCP(M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr())
|
if a.tcpFd != 0 {
|
||||||
|
if a.listenOptions.TCPFastOpen {
|
||||||
|
err = tfo.SetTFOListener(uintptr(a.tcpFd))
|
||||||
|
if err != nil {
|
||||||
|
a.logger.Warn("fd:", a.tcpFd, " set tfo error: ", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f := os.NewFile(uintptr(a.tcpFd), "")
|
||||||
|
tcpListener, err = net.FileListener(f)
|
||||||
|
f.Close()
|
||||||
} else {
|
} else {
|
||||||
tcpListener, err = tfo.ListenTCP(M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr())
|
bindAddr := M.SocksaddrFrom(a.listenOptions.Listen.Build(), a.listenOptions.ListenPort)
|
||||||
|
if !a.listenOptions.TCPFastOpen {
|
||||||
|
tcpListener, err = net.ListenTCP(M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr())
|
||||||
|
} else {
|
||||||
|
tcpListener, err = tfo.ListenTCP(M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
a.logger.Info("tcp server started at ", tcpListener.Addr())
|
a.logger.Info("tcp server started at ", tcpListener.Addr())
|
||||||
|
@ -12,21 +12,49 @@ import (
|
|||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (a *myInboundAdapter) ListenUDP() (net.PacketConn, error) {
|
func (a *myInboundAdapter) ListenUDP() (net.PacketConn, error) {
|
||||||
bindAddr := M.SocksaddrFrom(a.listenOptions.Listen.Build(), a.listenOptions.ListenPort)
|
var bindAddr M.Socksaddr
|
||||||
var lc net.ListenConfig
|
|
||||||
var udpFragment bool
|
var udpFragment bool
|
||||||
if a.listenOptions.UDPFragment != nil {
|
if a.listenOptions.UDPFragment != nil {
|
||||||
udpFragment = *a.listenOptions.UDPFragment
|
udpFragment = *a.listenOptions.UDPFragment
|
||||||
} else {
|
} else {
|
||||||
udpFragment = a.listenOptions.UDPFragmentDefault
|
udpFragment = a.listenOptions.UDPFragmentDefault
|
||||||
}
|
}
|
||||||
if !udpFragment {
|
var udpConn net.PacketConn
|
||||||
lc.Control = control.Append(lc.Control, control.DisableUDPFragment())
|
var err error
|
||||||
|
a.initFds()
|
||||||
|
if a.udpFd != 0 {
|
||||||
|
if !udpFragment {
|
||||||
|
if err := unix.SetsockoptInt(a.udpFd, unix.IPPROTO_IP, unix.IP_MTU_DISCOVER, unix.IP_PMTUDISC_DO); err != nil {
|
||||||
|
a.logger.Warn("SETSOCKOPT IP_MTU_DISCOVER IP_PMTUDISC_DO: ", err)
|
||||||
|
}
|
||||||
|
sa, err := unix.Getsockname(a.udpFd)
|
||||||
|
if err == nil {
|
||||||
|
if _, isIpv6 := sa.(*unix.SockaddrInet6); isIpv6 {
|
||||||
|
if err := unix.SetsockoptInt(a.udpFd, unix.IPPROTO_IPV6, unix.IPV6_MTU_DISCOVER, unix.IP_PMTUDISC_DO); err != nil {
|
||||||
|
a.logger.Warn("SETSOCKOPT IPV6_MTU_DISCOVER IP_PMTUDISC_DO", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
a.logger.Error("fd:", a.udpFd, " get addr error: ", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f := os.NewFile(uintptr(a.udpFd), "")
|
||||||
|
udpConn, err = net.FilePacketConn(f)
|
||||||
|
f.Close()
|
||||||
|
bindAddr = M.SocksaddrFromNet(udpConn.LocalAddr())
|
||||||
|
} else {
|
||||||
|
var lc net.ListenConfig
|
||||||
|
bindAddr = M.SocksaddrFrom(a.listenOptions.Listen.Build(), a.listenOptions.ListenPort)
|
||||||
|
if !udpFragment {
|
||||||
|
lc.Control = control.Append(lc.Control, control.DisableUDPFragment())
|
||||||
|
}
|
||||||
|
udpConn, err = lc.ListenPacket(a.ctx, M.NetworkFromNetAddr(N.NetworkUDP, bindAddr.Addr), bindAddr.String())
|
||||||
}
|
}
|
||||||
udpConn, err := lc.ListenPacket(a.ctx, M.NetworkFromNetAddr(N.NetworkUDP, bindAddr.Addr), bindAddr.String())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -119,6 +119,7 @@ type InboundOptions struct {
|
|||||||
type ListenOptions struct {
|
type ListenOptions struct {
|
||||||
Listen *ListenAddress `json:"listen,omitempty"`
|
Listen *ListenAddress `json:"listen,omitempty"`
|
||||||
ListenPort uint16 `json:"listen_port,omitempty"`
|
ListenPort uint16 `json:"listen_port,omitempty"`
|
||||||
|
Fds []int `json:"fds,omitempty"`
|
||||||
TCPFastOpen bool `json:"tcp_fast_open,omitempty"`
|
TCPFastOpen bool `json:"tcp_fast_open,omitempty"`
|
||||||
UDPFragment *bool `json:"udp_fragment,omitempty"`
|
UDPFragment *bool `json:"udp_fragment,omitempty"`
|
||||||
UDPFragmentDefault bool `json:"-"`
|
UDPFragmentDefault bool `json:"-"`
|
||||||
|
Loading…
x
Reference in New Issue
Block a user