dispatcher_packetaddr.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package udp
  2. import (
  3. "context"
  4. "github.com/v2fly/v2ray-core/v5/common/buf"
  5. "github.com/v2fly/v2ray-core/v5/common/net"
  6. "github.com/v2fly/v2ray-core/v5/common/net/packetaddr"
  7. "github.com/v2fly/v2ray-core/v5/common/protocol/udp"
  8. "github.com/v2fly/v2ray-core/v5/features/routing"
  9. )
  10. type PacketAddrDispatcher struct {
  11. conn net.PacketConn
  12. callback ResponseCallback
  13. ctx context.Context
  14. }
  15. func (p PacketAddrDispatcher) Close() error {
  16. if p.ctx.Value(DispatcherConnectionTerminationSignalReceiverMark) != nil {
  17. p.ctx.Value(DispatcherConnectionTerminationSignalReceiverMark).(DispatcherConnectionTerminationSignalReceiver).Close()
  18. }
  19. return p.conn.Close()
  20. }
  21. func (p PacketAddrDispatcher) Dispatch(ctx context.Context, destination net.Destination, payload *buf.Buffer) {
  22. if destination.Network != net.Network_UDP {
  23. return
  24. }
  25. // Processing of domain address is unsupported as it adds unpredictable overhead, it will be dropped.
  26. if destination.Address.Family().IsDomain() {
  27. return
  28. }
  29. p.conn.WriteTo(payload.Bytes(), &net.UDPAddr{IP: destination.Address.IP(), Port: int(destination.Port.Value())})
  30. }
  31. func (p PacketAddrDispatcher) readWorker() {
  32. for {
  33. readBuf := buf.New()
  34. n, addr, err := p.conn.ReadFrom(readBuf.Extend(2048))
  35. if err != nil {
  36. return
  37. }
  38. readBuf.Resize(0, int32(n))
  39. p.callback(p.ctx, &udp.Packet{Payload: readBuf, Source: net.DestinationFromAddr(addr)})
  40. }
  41. }
  42. type PacketAddrDispatcherCreator struct {
  43. ctx context.Context
  44. }
  45. func NewPacketAddrDispatcherCreator(ctx context.Context) PacketAddrDispatcherCreator {
  46. return PacketAddrDispatcherCreator{ctx: ctx}
  47. }
  48. func (pdc *PacketAddrDispatcherCreator) NewPacketAddrDispatcher(
  49. dispatcher routing.Dispatcher, callback ResponseCallback,
  50. ) DispatcherI {
  51. packetConn, _ := packetaddr.CreatePacketAddrConn(pdc.ctx, dispatcher, false)
  52. pd := &PacketAddrDispatcher{conn: packetConn, callback: callback, ctx: pdc.ctx}
  53. go pd.readWorker()
  54. return pd
  55. }