github.com/sagernet/sing-box@v1.9.0-rc.20/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.NewPacket() 42 defer buffer.Release() 43 buffer.IncRef() 44 defer buffer.DecRef() 45 packetService := (*myInboundPacketAdapter)(a) 46 for { 47 buffer.Reset() 48 n, addr, err := a.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes()) 49 if err != nil { 50 return 51 } 52 buffer.Truncate(n) 53 var metadata adapter.InboundContext 54 metadata.Inbound = a.tag 55 metadata.InboundType = a.protocol 56 metadata.InboundOptions = a.listenOptions.InboundOptions 57 metadata.Source = M.SocksaddrFromNetIP(addr).Unwrap() 58 metadata.OriginDestination = a.udpAddr 59 err = a.packetHandler.NewPacket(a.ctx, packetService, buffer, metadata) 60 if err != nil { 61 a.newError(E.Cause(err, "process packet from ", metadata.Source)) 62 } 63 } 64 } 65 66 func (a *myInboundAdapter) loopUDPOOBIn() { 67 defer close(a.packetOutboundClosed) 68 buffer := buf.NewPacket() 69 defer buffer.Release() 70 buffer.IncRef() 71 defer buffer.DecRef() 72 packetService := (*myInboundPacketAdapter)(a) 73 oob := make([]byte, 1024) 74 for { 75 buffer.Reset() 76 n, oobN, _, addr, err := a.udpConn.ReadMsgUDPAddrPort(buffer.FreeBytes(), oob) 77 if err != nil { 78 return 79 } 80 buffer.Truncate(n) 81 var metadata adapter.InboundContext 82 metadata.Inbound = a.tag 83 metadata.InboundType = a.protocol 84 metadata.InboundOptions = a.listenOptions.InboundOptions 85 metadata.Source = M.SocksaddrFromNetIP(addr).Unwrap() 86 metadata.OriginDestination = a.udpAddr 87 err = a.oobPacketHandler.NewPacket(a.ctx, packetService, buffer, oob[:oobN], metadata) 88 if err != nil { 89 a.newError(E.Cause(err, "process packet from ", metadata.Source)) 90 } 91 } 92 } 93 94 func (a *myInboundAdapter) loopUDPInThreadSafe() { 95 defer close(a.packetOutboundClosed) 96 packetService := (*myInboundPacketAdapter)(a) 97 for { 98 buffer := buf.NewPacket() 99 n, addr, err := a.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes()) 100 if err != nil { 101 buffer.Release() 102 return 103 } 104 buffer.Truncate(n) 105 var metadata adapter.InboundContext 106 metadata.Inbound = a.tag 107 metadata.InboundType = a.protocol 108 metadata.InboundOptions = a.listenOptions.InboundOptions 109 metadata.Source = M.SocksaddrFromNetIP(addr).Unwrap() 110 metadata.OriginDestination = a.udpAddr 111 err = a.packetHandler.NewPacket(a.ctx, packetService, buffer, metadata) 112 if err != nil { 113 buffer.Release() 114 a.newError(E.Cause(err, "process packet from ", metadata.Source)) 115 } 116 } 117 } 118 119 func (a *myInboundAdapter) loopUDPOOBInThreadSafe() { 120 defer close(a.packetOutboundClosed) 121 packetService := (*myInboundPacketAdapter)(a) 122 oob := make([]byte, 1024) 123 for { 124 buffer := buf.NewPacket() 125 n, oobN, _, addr, err := a.udpConn.ReadMsgUDPAddrPort(buffer.FreeBytes(), oob) 126 if err != nil { 127 buffer.Release() 128 return 129 } 130 buffer.Truncate(n) 131 var metadata adapter.InboundContext 132 metadata.Inbound = a.tag 133 metadata.InboundType = a.protocol 134 metadata.InboundOptions = a.listenOptions.InboundOptions 135 metadata.Source = M.SocksaddrFromNetIP(addr).Unwrap() 136 metadata.OriginDestination = a.udpAddr 137 err = a.oobPacketHandler.NewPacket(a.ctx, packetService, buffer, oob[:oobN], metadata) 138 if err != nil { 139 buffer.Release() 140 a.newError(E.Cause(err, "process packet from ", metadata.Source)) 141 } 142 } 143 } 144 145 func (a *myInboundAdapter) loopUDPOut() { 146 for { 147 select { 148 case packet := <-a.packetOutbound: 149 err := a.writePacket(packet.buffer, packet.destination) 150 if err != nil && !E.IsClosed(err) { 151 a.newError(E.New("write back udp: ", err)) 152 } 153 continue 154 case <-a.packetOutboundClosed: 155 } 156 for { 157 select { 158 case packet := <-a.packetOutbound: 159 packet.buffer.Release() 160 default: 161 return 162 } 163 } 164 } 165 } 166 167 func (a *myInboundAdapter) writePacket(buffer *buf.Buffer, destination M.Socksaddr) error { 168 defer buffer.Release() 169 if destination.IsFqdn() { 170 udpAddr, err := net.ResolveUDPAddr(N.NetworkUDP, destination.String()) 171 if err != nil { 172 return err 173 } 174 return common.Error(a.udpConn.WriteTo(buffer.Bytes(), udpAddr)) 175 } 176 return common.Error(a.udpConn.WriteToUDPAddrPort(buffer.Bytes(), destination.AddrPort())) 177 } 178 179 type myInboundPacketAdapter myInboundAdapter 180 181 func (s *myInboundPacketAdapter) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) { 182 n, addr, err := s.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes()) 183 if err != nil { 184 return M.Socksaddr{}, err 185 } 186 buffer.Truncate(n) 187 return M.SocksaddrFromNetIP(addr), nil 188 } 189 190 func (s *myInboundPacketAdapter) WriteIsThreadUnsafe() { 191 } 192 193 type myInboundPacket struct { 194 buffer *buf.Buffer 195 destination M.Socksaddr 196 } 197 198 func (s *myInboundPacketAdapter) Upstream() any { 199 return s.udpConn 200 } 201 202 func (s *myInboundPacketAdapter) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error { 203 select { 204 case s.packetOutbound <- &myInboundPacket{buffer, destination}: 205 return nil 206 case <-s.packetOutboundClosed: 207 return os.ErrClosed 208 } 209 } 210 211 func (s *myInboundPacketAdapter) Close() error { 212 return s.udpConn.Close() 213 } 214 215 func (s *myInboundPacketAdapter) LocalAddr() net.Addr { 216 return s.udpConn.LocalAddr() 217 } 218 219 func (s *myInboundPacketAdapter) SetDeadline(t time.Time) error { 220 return s.udpConn.SetDeadline(t) 221 } 222 223 func (s *myInboundPacketAdapter) SetReadDeadline(t time.Time) error { 224 return s.udpConn.SetReadDeadline(t) 225 } 226 227 func (s *myInboundPacketAdapter) SetWriteDeadline(t time.Time) error { 228 return s.udpConn.SetWriteDeadline(t) 229 }