netpackager.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. package common
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "errors"
  6. "io"
  7. "io/ioutil"
  8. "net"
  9. "strconv"
  10. )
  11. type NetPackager interface {
  12. Pack(writer io.Writer) (err error)
  13. UnPack(reader io.Reader) (err error)
  14. }
  15. const (
  16. ipV4 = 1
  17. domainName = 3
  18. ipV6 = 4
  19. )
  20. type UDPHeader struct {
  21. Rsv uint16
  22. Frag uint8
  23. Addr *Addr
  24. }
  25. func NewUDPHeader(rsv uint16, frag uint8, addr *Addr) *UDPHeader {
  26. return &UDPHeader{
  27. Rsv: rsv,
  28. Frag: frag,
  29. Addr: addr,
  30. }
  31. }
  32. type Addr struct {
  33. Type uint8
  34. Host string
  35. Port uint16
  36. }
  37. func (addr *Addr) String() string {
  38. return net.JoinHostPort(addr.Host, strconv.Itoa(int(addr.Port)))
  39. }
  40. func (addr *Addr) Decode(b []byte) error {
  41. addr.Type = b[0]
  42. pos := 1
  43. switch addr.Type {
  44. case ipV4:
  45. addr.Host = net.IP(b[pos : pos+net.IPv4len]).String()
  46. pos += net.IPv4len
  47. case ipV6:
  48. addr.Host = net.IP(b[pos : pos+net.IPv6len]).String()
  49. pos += net.IPv6len
  50. case domainName:
  51. addrlen := int(b[pos])
  52. pos++
  53. addr.Host = string(b[pos : pos+addrlen])
  54. pos += addrlen
  55. default:
  56. return errors.New("decode error")
  57. }
  58. addr.Port = binary.BigEndian.Uint16(b[pos:])
  59. return nil
  60. }
  61. func (addr *Addr) Encode(b []byte) (int, error) {
  62. b[0] = addr.Type
  63. pos := 1
  64. switch addr.Type {
  65. case ipV4:
  66. ip4 := net.ParseIP(addr.Host).To4()
  67. if ip4 == nil {
  68. ip4 = net.IPv4zero.To4()
  69. }
  70. pos += copy(b[pos:], ip4)
  71. case domainName:
  72. b[pos] = byte(len(addr.Host))
  73. pos++
  74. pos += copy(b[pos:], []byte(addr.Host))
  75. case ipV6:
  76. ip16 := net.ParseIP(addr.Host).To16()
  77. if ip16 == nil {
  78. ip16 = net.IPv6zero.To16()
  79. }
  80. pos += copy(b[pos:], ip16)
  81. default:
  82. b[0] = ipV4
  83. copy(b[pos:pos+4], net.IPv4zero.To4())
  84. pos += 4
  85. }
  86. binary.BigEndian.PutUint16(b[pos:], addr.Port)
  87. pos += 2
  88. return pos, nil
  89. }
  90. func (h *UDPHeader) Write(w io.Writer) error {
  91. b := BufPoolUdp.Get().([]byte)
  92. defer BufPoolUdp.Put(b)
  93. binary.BigEndian.PutUint16(b[:2], h.Rsv)
  94. b[2] = h.Frag
  95. addr := h.Addr
  96. if addr == nil {
  97. addr = &Addr{}
  98. }
  99. length, _ := addr.Encode(b[3:])
  100. _, err := w.Write(b[:3+length])
  101. return err
  102. }
  103. type UDPDatagram struct {
  104. Header *UDPHeader
  105. Data []byte
  106. }
  107. func ReadUDPDatagram(r io.Reader) (*UDPDatagram, error) {
  108. b := BufPoolUdp.Get().([]byte)
  109. defer BufPoolUdp.Put(b)
  110. // when r is a streaming (such as TCP connection), we may read more than the required data,
  111. // but we don't know how to handle it. So we use io.ReadFull to instead of io.ReadAtLeast
  112. // to make sure that no redundant data will be discarded.
  113. n, err := io.ReadFull(r, b[:5])
  114. if err != nil {
  115. return nil, err
  116. }
  117. header := &UDPHeader{
  118. Rsv: binary.BigEndian.Uint16(b[:2]),
  119. Frag: b[2],
  120. }
  121. atype := b[3]
  122. hlen := 0
  123. switch atype {
  124. case ipV4:
  125. hlen = 10
  126. case ipV6:
  127. hlen = 22
  128. case domainName:
  129. hlen = 7 + int(b[4])
  130. default:
  131. return nil, errors.New("addr not support")
  132. }
  133. dlen := int(header.Rsv)
  134. if dlen == 0 { // standard SOCKS5 UDP datagram
  135. extra, err := ioutil.ReadAll(r) // we assume no redundant data
  136. if err != nil {
  137. return nil, err
  138. }
  139. copy(b[n:], extra)
  140. n += len(extra) // total length
  141. dlen = n - hlen // data length
  142. } else { // extended feature, for UDP over TCP, using reserved field as data length
  143. if _, err := io.ReadFull(r, b[n:hlen+dlen]); err != nil {
  144. return nil, err
  145. }
  146. n = hlen + dlen
  147. }
  148. header.Addr = new(Addr)
  149. if err := header.Addr.Decode(b[3:hlen]); err != nil {
  150. return nil, err
  151. }
  152. data := make([]byte, dlen)
  153. copy(data, b[hlen:n])
  154. d := &UDPDatagram{
  155. Header: header,
  156. Data: data,
  157. }
  158. return d, nil
  159. }
  160. func NewUDPDatagram(header *UDPHeader, data []byte) *UDPDatagram {
  161. return &UDPDatagram{
  162. Header: header,
  163. Data: data,
  164. }
  165. }
  166. func (d *UDPDatagram) Write(w io.Writer) error {
  167. h := d.Header
  168. if h == nil {
  169. h = &UDPHeader{}
  170. }
  171. buf := bytes.Buffer{}
  172. if err := h.Write(&buf); err != nil {
  173. return err
  174. }
  175. if _, err := buf.Write(d.Data); err != nil {
  176. return err
  177. }
  178. _, err := buf.WriteTo(w)
  179. return err
  180. }
  181. func ToSocksAddr(addr net.Addr) *Addr {
  182. host := "0.0.0.0"
  183. port := 0
  184. if addr != nil {
  185. h, p, _ := net.SplitHostPort(addr.String())
  186. host = h
  187. port, _ = strconv.Atoi(p)
  188. }
  189. return &Addr{
  190. Type: ipV4,
  191. Host: host,
  192. Port: uint16(port),
  193. }
  194. }