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"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var _ adapter.Inbound = (*myInboundAdapter)(nil)
|
||||
@ -38,6 +40,8 @@ type myInboundAdapter struct {
|
||||
|
||||
// internal
|
||||
|
||||
tcpFd int
|
||||
udpFd int
|
||||
tcpListener net.Listener
|
||||
udpConn *net.UDPConn
|
||||
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 {
|
||||
return adapter.NewUpstreamHandler(metadata, a.newConnection, a.streamPacketConnection, a)
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package inbound
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/common/proxyproto"
|
||||
@ -15,13 +16,26 @@ import (
|
||||
|
||||
func (a *myInboundAdapter) ListenTCP() (net.Listener, error) {
|
||||
var err error
|
||||
bindAddr := M.SocksaddrFrom(a.listenOptions.Listen.Build(), a.listenOptions.ListenPort)
|
||||
var tcpListener net.Listener
|
||||
a.initFds()
|
||||
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 {
|
||||
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 {
|
||||
a.logger.Info("tcp server started at ", tcpListener.Addr())
|
||||
}
|
||||
|
@ -12,21 +12,49 @@ import (
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func (a *myInboundAdapter) ListenUDP() (net.PacketConn, error) {
|
||||
bindAddr := M.SocksaddrFrom(a.listenOptions.Listen.Build(), a.listenOptions.ListenPort)
|
||||
var lc net.ListenConfig
|
||||
var bindAddr M.Socksaddr
|
||||
var udpFragment bool
|
||||
if a.listenOptions.UDPFragment != nil {
|
||||
udpFragment = *a.listenOptions.UDPFragment
|
||||
} else {
|
||||
udpFragment = a.listenOptions.UDPFragmentDefault
|
||||
}
|
||||
var udpConn net.PacketConn
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -119,6 +119,7 @@ type InboundOptions struct {
|
||||
type ListenOptions struct {
|
||||
Listen *ListenAddress `json:"listen,omitempty"`
|
||||
ListenPort uint16 `json:"listen_port,omitempty"`
|
||||
Fds []int `json:"fds,omitempty"`
|
||||
TCPFastOpen bool `json:"tcp_fast_open,omitempty"`
|
||||
UDPFragment *bool `json:"udp_fragment,omitempty"`
|
||||
UDPFragmentDefault bool `json:"-"`
|
||||
|
Loading…
x
Reference in New Issue
Block a user