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 }