mirror of
https://github.com/xjasonlyu/tun2socks.git
synced 2025-10-07 01:33:15 +08:00
Feature: add an option to set udp timeout
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/xjasonlyu/tun2socks/log"
|
"github.com/xjasonlyu/tun2socks/log"
|
||||||
"github.com/xjasonlyu/tun2socks/proxy"
|
"github.com/xjasonlyu/tun2socks/proxy"
|
||||||
"github.com/xjasonlyu/tun2socks/stats"
|
"github.com/xjasonlyu/tun2socks/stats"
|
||||||
|
"github.com/xjasonlyu/tun2socks/tunnel"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _engine = &engine{}
|
var _engine = &engine{}
|
||||||
@@ -30,15 +31,16 @@ func Insert(k *Key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Key struct {
|
type Key struct {
|
||||||
MTU int
|
MTU int
|
||||||
Mark int
|
Mark int
|
||||||
Proxy string
|
UDPTimeout int
|
||||||
Stats string
|
Proxy string
|
||||||
Token string
|
Stats string
|
||||||
Device string
|
Token string
|
||||||
LogLevel string
|
Device string
|
||||||
Interface string
|
LogLevel string
|
||||||
Version bool
|
Interface string
|
||||||
|
Version bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type engine struct {
|
type engine struct {
|
||||||
@@ -64,6 +66,7 @@ func (e *engine) start() error {
|
|||||||
e.setMark,
|
e.setMark,
|
||||||
e.setInterface,
|
e.setInterface,
|
||||||
e.setStats,
|
e.setStats,
|
||||||
|
e.setUDPTimeout,
|
||||||
e.setProxy,
|
e.setProxy,
|
||||||
e.setDevice,
|
e.setDevice,
|
||||||
e.setStack,
|
e.setStack,
|
||||||
@@ -123,6 +126,13 @@ func (e *engine) setStats() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *engine) setUDPTimeout() error {
|
||||||
|
if e.UDPTimeout > 0 {
|
||||||
|
tunnel.SetUDPTimeout(e.UDPTimeout)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (e *engine) setProxy() (err error) {
|
func (e *engine) setProxy() (err error) {
|
||||||
if e.Proxy == "" {
|
if e.Proxy == "" {
|
||||||
return errors.New("empty proxy")
|
return errors.New("empty proxy")
|
||||||
|
1
main.go
1
main.go
@@ -15,6 +15,7 @@ var key = new(engine.Key)
|
|||||||
func init() {
|
func init() {
|
||||||
flag.IntVar(&key.Mark, "fwmark", 0, "Set firewall MARK (Linux only)")
|
flag.IntVar(&key.Mark, "fwmark", 0, "Set firewall MARK (Linux only)")
|
||||||
flag.IntVar(&key.MTU, "mtu", 0, "Set device maximum transmission unit (MTU)")
|
flag.IntVar(&key.MTU, "mtu", 0, "Set device maximum transmission unit (MTU)")
|
||||||
|
flag.IntVar(&key.UDPTimeout, "udp-timeout", 0, "Set timeout for each UDP session")
|
||||||
flag.BoolVar(&key.Version, "version", false, "Show version information and quit")
|
flag.BoolVar(&key.Version, "version", false, "Show version information and quit")
|
||||||
flag.StringVar(&key.Device, "device", "", "Use this device [driver://]name")
|
flag.StringVar(&key.Device, "device", "", "Use this device [driver://]name")
|
||||||
flag.StringVar(&key.Interface, "interface", "", "Use network INTERFACE (Linux/MacOS only)")
|
flag.StringVar(&key.Interface, "interface", "", "Use network INTERFACE (Linux/MacOS only)")
|
||||||
|
@@ -16,16 +16,20 @@ import (
|
|||||||
"github.com/xjasonlyu/tun2socks/tunnel/statistic"
|
"github.com/xjasonlyu/tun2socks/tunnel/statistic"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
udpSessionTimeout = 60 * time.Second
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// _natTable uses source udp packet information
|
// _natTable uses source udp packet information
|
||||||
// as key to store destination udp packetConn.
|
// as key to store destination udp packetConn.
|
||||||
_natTable = nat.NewTable()
|
_natTable = nat.NewTable()
|
||||||
|
|
||||||
|
// _udpSessionTimeout is the default timeout for
|
||||||
|
// each UDP session.
|
||||||
|
_udpSessionTimeout = 60 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func SetUDPTimeout(v int) {
|
||||||
|
_udpSessionTimeout = time.Duration(v) * time.Second
|
||||||
|
}
|
||||||
|
|
||||||
func newUDPTracker(conn net.PacketConn, metadata *M.Metadata) net.PacketConn {
|
func newUDPTracker(conn net.PacketConn, metadata *M.Metadata) net.PacketConn {
|
||||||
return statistic.NewUDPTracker(conn, metadata, statistic.DefaultManager)
|
return statistic.NewUDPTracker(conn, metadata, statistic.DefaultManager)
|
||||||
}
|
}
|
||||||
@@ -115,7 +119,7 @@ func handleUDPToRemote(packet core.UDPPacket, pc net.PacketConn, remote net.Addr
|
|||||||
if _, err := pc.WriteTo(packet.Data() /* data */, remote); err != nil {
|
if _, err := pc.WriteTo(packet.Data() /* data */, remote); err != nil {
|
||||||
log.Warnf("[UDP] write to %s error: %v", remote, err)
|
log.Warnf("[UDP] write to %s error: %v", remote, err)
|
||||||
}
|
}
|
||||||
pc.SetReadDeadline(time.Now().Add(udpSessionTimeout)) /* reset timeout */
|
pc.SetReadDeadline(time.Now().Add(_udpSessionTimeout)) /* reset timeout */
|
||||||
|
|
||||||
log.Infof("[UDP] %s --> %s", packet.RemoteAddr(), remote)
|
log.Infof("[UDP] %s --> %s", packet.RemoteAddr(), remote)
|
||||||
}
|
}
|
||||||
@@ -125,7 +129,7 @@ func handleUDPToLocal(packet core.UDPPacket, pc net.PacketConn) {
|
|||||||
defer pool.Put(buf)
|
defer pool.Put(buf)
|
||||||
|
|
||||||
for /* just loop */ {
|
for /* just loop */ {
|
||||||
pc.SetReadDeadline(time.Now().Add(udpSessionTimeout))
|
pc.SetReadDeadline(time.Now().Add(_udpSessionTimeout))
|
||||||
n, from, err := pc.ReadFrom(buf)
|
n, from, err := pc.ReadFrom(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.Is(err, os.ErrDeadlineExceeded) /* ignore i/o timeout */ {
|
if !errors.Is(err, os.ErrDeadlineExceeded) /* ignore i/o timeout */ {
|
||||||
|
Reference in New Issue
Block a user