udp.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. package udp
  2. import (
  3. "net"
  4. "github.com/v2ray/v2ray-core/common/alloc"
  5. v2net "github.com/v2ray/v2ray-core/common/net"
  6. )
  7. type UDPPayloadHandler func(*alloc.Buffer, v2net.Destination)
  8. type UDPHub struct {
  9. conn *net.UDPConn
  10. callback UDPPayloadHandler
  11. accepting bool
  12. }
  13. func ListenUDP(address v2net.Address, port v2net.Port, callback UDPPayloadHandler) (*UDPHub, error) {
  14. udpConn, err := net.ListenUDP("udp", &net.UDPAddr{
  15. IP: address.IP(),
  16. Port: int(port),
  17. })
  18. if err != nil {
  19. return nil, err
  20. }
  21. hub := &UDPHub{
  22. conn: udpConn,
  23. callback: callback,
  24. }
  25. go hub.start()
  26. return hub, nil
  27. }
  28. func (this *UDPHub) Close() {
  29. this.accepting = false
  30. this.conn.Close()
  31. }
  32. func (this *UDPHub) WriteTo(payload []byte, dest v2net.Destination) (int, error) {
  33. return this.conn.WriteToUDP(payload, &net.UDPAddr{
  34. IP: dest.Address().IP(),
  35. Port: int(dest.Port()),
  36. })
  37. }
  38. func (this *UDPHub) start() {
  39. this.accepting = true
  40. for this.accepting {
  41. buffer := alloc.NewBuffer()
  42. nBytes, addr, err := this.conn.ReadFromUDP(buffer.Value)
  43. if err != nil {
  44. buffer.Release()
  45. continue
  46. }
  47. buffer.Slice(0, nBytes)
  48. dest := v2net.UDPDestination(v2net.IPAddress(addr.IP), v2net.Port(addr.Port))
  49. go this.callback(buffer, dest)
  50. }
  51. }