udp.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package socks
  2. import (
  3. "math"
  4. "math/rand"
  5. "net"
  6. "sync"
  7. "github.com/v2ray/v2ray-core/common/collect"
  8. "github.com/v2ray/v2ray-core/common/log"
  9. v2net "github.com/v2ray/v2ray-core/common/net"
  10. "github.com/v2ray/v2ray-core/proxy/socks/protocol"
  11. )
  12. const (
  13. bufferSize = 2 * 1024
  14. )
  15. type portMap struct {
  16. access sync.Mutex
  17. data map[uint16]*net.UDPAddr
  18. removedPorts *collect.TimedQueue
  19. }
  20. func newPortMap() *portMap {
  21. m := &portMap{
  22. access: sync.Mutex{},
  23. data: make(map[uint16]*net.UDPAddr),
  24. removedPorts: collect.NewTimedQueue(1),
  25. }
  26. go m.removePorts(m.removedPorts.RemovedEntries())
  27. return m
  28. }
  29. func (m *portMap) assignAddressToken(addr *net.UDPAddr) uint16 {
  30. for {
  31. token := uint16(rand.Intn(math.MaxUint16))
  32. if _, used := m.data[token]; !used {
  33. m.access.Lock()
  34. if _, used = m.data[token]; !used {
  35. m.data[token] = addr
  36. m.access.Unlock()
  37. return token
  38. }
  39. m.access.Unlock()
  40. }
  41. }
  42. }
  43. func (m *portMap) removePorts(removedPorts <-chan interface{}) {
  44. for {
  45. rawToken := <-removedPorts
  46. m.access.Lock()
  47. delete(m.data, rawToken.(uint16))
  48. m.access.Unlock()
  49. }
  50. }
  51. func (m *portMap) popPort(token uint16) *net.UDPAddr {
  52. m.access.Lock()
  53. defer m.access.Unlock()
  54. addr, exists := m.data[token]
  55. if !exists {
  56. return nil
  57. }
  58. delete(m.data, token)
  59. return addr
  60. }
  61. var (
  62. ports *portMap
  63. udpConn *net.UDPConn
  64. )
  65. func (server *SocksServer) ListenUDP(port uint16) error {
  66. ports = newPortMap()
  67. addr := &net.UDPAddr{
  68. IP: net.IP{0, 0, 0, 0},
  69. Port: int(port),
  70. Zone: "",
  71. }
  72. conn, err := net.ListenUDP("udp", addr)
  73. if err != nil {
  74. log.Error("Socks failed to listen UDP on port %d: %v", port, err)
  75. return err
  76. }
  77. go server.AcceptPackets(conn)
  78. udpConn = conn
  79. return nil
  80. }
  81. func (server *SocksServer) AcceptPackets(conn *net.UDPConn) error {
  82. for {
  83. buffer := make([]byte, 0, bufferSize)
  84. nBytes, addr, err := conn.ReadFromUDP(buffer)
  85. if err != nil {
  86. log.Error("Socks failed to read UDP packets: %v", err)
  87. return err
  88. }
  89. request, err := protocol.ReadUDPRequest(buffer[:nBytes])
  90. if err != nil {
  91. log.Error("Socks failed to parse UDP request: %v", err)
  92. return err
  93. }
  94. if request.Fragment != 0 {
  95. // TODO handle fragments
  96. continue
  97. }
  98. token := ports.assignAddressToken(addr)
  99. udpPacket := v2net.NewUDPPacket(request.Destination(), request.Data, token)
  100. server.vPoint.DispatchToOutbound(udpPacket)
  101. }
  102. }
  103. func (server *SocksServer) Dispatch(packet v2net.Packet) {
  104. if udpPacket, ok := packet.(*v2net.UDPPacket); ok {
  105. token := udpPacket.Token()
  106. addr := ports.popPort(token)
  107. if udpConn != nil {
  108. udpConn.WriteToUDP(udpPacket.Chunk(), addr)
  109. }
  110. }
  111. // We don't expect TCP Packets here
  112. }