github.com/sagernet/sing-box@v1.2.7/inbound/default_udp.go (about)

     1  package inbound
     2  
     3  import (
     4  	"net"
     5  	"os"
     6  	"time"
     7  
     8  	"github.com/sagernet/sing-box/adapter"
     9  	"github.com/sagernet/sing/common"
    10  	"github.com/sagernet/sing/common/buf"
    11  	"github.com/sagernet/sing/common/control"
    12  	E "github.com/sagernet/sing/common/exceptions"
    13  	M "github.com/sagernet/sing/common/metadata"
    14  	N "github.com/sagernet/sing/common/network"
    15  )
    16  
    17  func (a *myInboundAdapter) ListenUDP() (net.PacketConn, error) {
    18  	bindAddr := M.SocksaddrFrom(a.listenOptions.Listen.Build(), a.listenOptions.ListenPort)
    19  	var lc net.ListenConfig
    20  	var udpFragment bool
    21  	if a.listenOptions.UDPFragment != nil {
    22  		udpFragment = *a.listenOptions.UDPFragment
    23  	} else {
    24  		udpFragment = a.listenOptions.UDPFragmentDefault
    25  	}
    26  	if !udpFragment {
    27  		lc.Control = control.Append(lc.Control, control.DisableUDPFragment())
    28  	}
    29  	udpConn, err := lc.ListenPacket(a.ctx, M.NetworkFromNetAddr(N.NetworkUDP, bindAddr.Addr), bindAddr.String())
    30  	if err != nil {
    31  		return nil, err
    32  	}
    33  	a.udpConn = udpConn.(*net.UDPConn)
    34  	a.udpAddr = bindAddr
    35  	a.logger.Info("udp server started at ", udpConn.LocalAddr())
    36  	return udpConn, err
    37  }
    38  
    39  func (a *myInboundAdapter) loopUDPIn() {
    40  	defer close(a.packetOutboundClosed)
    41  	_buffer := buf.StackNewPacket()
    42  	defer common.KeepAlive(_buffer)
    43  	buffer := common.Dup(_buffer)
    44  	defer buffer.Release()
    45  	buffer.IncRef()
    46  	defer buffer.DecRef()
    47  	packetService := (*myInboundPacketAdapter)(a)
    48  	for {
    49  		buffer.Reset()
    50  		n, addr, err := a.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes())
    51  		if err != nil {
    52  			return
    53  		}
    54  		buffer.Truncate(n)
    55  		var metadata adapter.InboundContext
    56  		metadata.Inbound = a.tag
    57  		metadata.InboundType = a.protocol
    58  		metadata.InboundOptions = a.listenOptions.InboundOptions
    59  		metadata.Source = M.SocksaddrFromNetIP(addr).Unwrap()
    60  		metadata.OriginDestination = a.udpAddr
    61  		err = a.packetHandler.NewPacket(a.ctx, packetService, buffer, metadata)
    62  		if err != nil {
    63  			a.newError(E.Cause(err, "process packet from ", metadata.Source))
    64  		}
    65  	}
    66  }
    67  
    68  func (a *myInboundAdapter) loopUDPOOBIn() {
    69  	defer close(a.packetOutboundClosed)
    70  	_buffer := buf.StackNewPacket()
    71  	defer common.KeepAlive(_buffer)
    72  	buffer := common.Dup(_buffer)
    73  	defer buffer.Release()
    74  	buffer.IncRef()
    75  	defer buffer.DecRef()
    76  	packetService := (*myInboundPacketAdapter)(a)
    77  	oob := make([]byte, 1024)
    78  	for {
    79  		buffer.Reset()
    80  		n, oobN, _, addr, err := a.udpConn.ReadMsgUDPAddrPort(buffer.FreeBytes(), oob)
    81  		if err != nil {
    82  			return
    83  		}
    84  		buffer.Truncate(n)
    85  		var metadata adapter.InboundContext
    86  		metadata.Inbound = a.tag
    87  		metadata.InboundType = a.protocol
    88  		metadata.InboundOptions = a.listenOptions.InboundOptions
    89  		metadata.Source = M.SocksaddrFromNetIP(addr).Unwrap()
    90  		metadata.OriginDestination = a.udpAddr
    91  		err = a.oobPacketHandler.NewPacket(a.ctx, packetService, buffer, oob[:oobN], metadata)
    92  		if err != nil {
    93  			a.newError(E.Cause(err, "process packet from ", metadata.Source))
    94  		}
    95  	}
    96  }
    97  
    98  func (a *myInboundAdapter) loopUDPInThreadSafe() {
    99  	defer close(a.packetOutboundClosed)
   100  	packetService := (*myInboundPacketAdapter)(a)
   101  	for {
   102  		buffer := buf.NewPacket()
   103  		n, addr, err := a.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes())
   104  		if err != nil {
   105  			buffer.Release()
   106  			return
   107  		}
   108  		buffer.Truncate(n)
   109  		var metadata adapter.InboundContext
   110  		metadata.Inbound = a.tag
   111  		metadata.InboundType = a.protocol
   112  		metadata.InboundOptions = a.listenOptions.InboundOptions
   113  		metadata.Source = M.SocksaddrFromNetIP(addr).Unwrap()
   114  		metadata.OriginDestination = a.udpAddr
   115  		err = a.packetHandler.NewPacket(a.ctx, packetService, buffer, metadata)
   116  		if err != nil {
   117  			buffer.Release()
   118  			a.newError(E.Cause(err, "process packet from ", metadata.Source))
   119  		}
   120  	}
   121  }
   122  
   123  func (a *myInboundAdapter) loopUDPOOBInThreadSafe() {
   124  	defer close(a.packetOutboundClosed)
   125  	packetService := (*myInboundPacketAdapter)(a)
   126  	oob := make([]byte, 1024)
   127  	for {
   128  		buffer := buf.NewPacket()
   129  		n, oobN, _, addr, err := a.udpConn.ReadMsgUDPAddrPort(buffer.FreeBytes(), oob)
   130  		if err != nil {
   131  			buffer.Release()
   132  			return
   133  		}
   134  		buffer.Truncate(n)
   135  		var metadata adapter.InboundContext
   136  		metadata.Inbound = a.tag
   137  		metadata.InboundType = a.protocol
   138  		metadata.InboundOptions = a.listenOptions.InboundOptions
   139  		metadata.Source = M.SocksaddrFromNetIP(addr).Unwrap()
   140  		metadata.OriginDestination = a.udpAddr
   141  		err = a.oobPacketHandler.NewPacket(a.ctx, packetService, buffer, oob[:oobN], metadata)
   142  		if err != nil {
   143  			buffer.Release()
   144  			a.newError(E.Cause(err, "process packet from ", metadata.Source))
   145  		}
   146  	}
   147  }
   148  
   149  func (a *myInboundAdapter) loopUDPOut() {
   150  	for {
   151  		select {
   152  		case packet := <-a.packetOutbound:
   153  			err := a.writePacket(packet.buffer, packet.destination)
   154  			if err != nil && !E.IsClosed(err) {
   155  				a.newError(E.New("write back udp: ", err))
   156  			}
   157  			continue
   158  		case <-a.packetOutboundClosed:
   159  		}
   160  		for {
   161  			select {
   162  			case packet := <-a.packetOutbound:
   163  				packet.buffer.Release()
   164  			default:
   165  				return
   166  			}
   167  		}
   168  	}
   169  }
   170  
   171  func (a *myInboundAdapter) writePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
   172  	defer buffer.Release()
   173  	if destination.IsFqdn() {
   174  		udpAddr, err := net.ResolveUDPAddr(N.NetworkUDP, destination.String())
   175  		if err != nil {
   176  			return err
   177  		}
   178  		return common.Error(a.udpConn.WriteTo(buffer.Bytes(), udpAddr))
   179  	}
   180  	return common.Error(a.udpConn.WriteToUDPAddrPort(buffer.Bytes(), destination.AddrPort()))
   181  }
   182  
   183  type myInboundPacketAdapter myInboundAdapter
   184  
   185  func (s *myInboundPacketAdapter) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) {
   186  	n, addr, err := s.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes())
   187  	if err != nil {
   188  		return M.Socksaddr{}, err
   189  	}
   190  	buffer.Truncate(n)
   191  	return M.SocksaddrFromNetIP(addr), nil
   192  }
   193  
   194  func (s *myInboundPacketAdapter) WriteIsThreadUnsafe() {
   195  }
   196  
   197  type myInboundPacket struct {
   198  	buffer      *buf.Buffer
   199  	destination M.Socksaddr
   200  }
   201  
   202  func (s *myInboundPacketAdapter) Upstream() any {
   203  	return s.udpConn
   204  }
   205  
   206  func (s *myInboundPacketAdapter) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
   207  	select {
   208  	case s.packetOutbound <- &myInboundPacket{buffer, destination}:
   209  		return nil
   210  	case <-s.packetOutboundClosed:
   211  		return os.ErrClosed
   212  	}
   213  }
   214  
   215  func (s *myInboundPacketAdapter) Close() error {
   216  	return s.udpConn.Close()
   217  }
   218  
   219  func (s *myInboundPacketAdapter) LocalAddr() net.Addr {
   220  	return s.udpConn.LocalAddr()
   221  }
   222  
   223  func (s *myInboundPacketAdapter) SetDeadline(t time.Time) error {
   224  	return s.udpConn.SetDeadline(t)
   225  }
   226  
   227  func (s *myInboundPacketAdapter) SetReadDeadline(t time.Time) error {
   228  	return s.udpConn.SetReadDeadline(t)
   229  }
   230  
   231  func (s *myInboundPacketAdapter) SetWriteDeadline(t time.Time) error {
   232  	return s.udpConn.SetWriteDeadline(t)
   233  }