socks.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. // Package socks contains protocol definition and io lib for SOCKS5 protocol
  2. package socks
  3. import (
  4. "encoding/binary"
  5. "fmt"
  6. "io"
  7. )
  8. const (
  9. socksVersion = uint8(5)
  10. )
  11. // Authentication request header of Socks5 protocol
  12. type Socks5AuthenticationRequest struct {
  13. version byte
  14. nMethods byte
  15. authMethods [256]byte
  16. }
  17. func ReadAuthentication(reader io.Reader) (auth Socks5AuthenticationRequest, err error) {
  18. buffer := make([]byte, 2)
  19. nBytes, err := reader.Read(buffer)
  20. if err != nil {
  21. return
  22. }
  23. if nBytes < 2 {
  24. err = fmt.Errorf("Expected 2 bytes read, but actaully %d bytes read", nBytes)
  25. return
  26. }
  27. auth.version = buffer[0]
  28. if auth.version != socksVersion {
  29. err = fmt.Errorf("Unknown SOCKS version %d", auth.version)
  30. return
  31. }
  32. auth.nMethods = buffer[1]
  33. if auth.nMethods <= 0 {
  34. err = fmt.Errorf("Zero length of authentication methods")
  35. return
  36. }
  37. buffer = make([]byte, auth.nMethods)
  38. nBytes, err = reader.Read(buffer)
  39. if err != nil {
  40. return
  41. }
  42. if nBytes != int(auth.nMethods) {
  43. err = fmt.Errorf("Unmatching number of auth methods, expecting %d, but got %d", auth.nMethods, nBytes)
  44. return
  45. }
  46. copy(auth.authMethods[:nBytes], buffer)
  47. return
  48. }
  49. type Socks5AuthenticationResponse struct {
  50. version byte
  51. authMethod byte
  52. }
  53. func (r *Socks5AuthenticationResponse) ToBytes() []byte {
  54. buffer := make([]byte, 2 /* size of Socks5AuthenticationResponse */)
  55. buffer[0] = r.version
  56. buffer[1] = r.authMethod
  57. return buffer
  58. }
  59. func WriteAuthentication(writer io.Writer, response Socks5AuthenticationResponse) error {
  60. _, err := writer.Write(response.ToBytes())
  61. return err
  62. }
  63. const (
  64. AddrTypeIPv4 = byte(0x01)
  65. AddrTypeIPv6 = byte(0x04)
  66. AddrTypeDomain = byte(0x03)
  67. )
  68. type Socks5Request struct {
  69. version byte
  70. command byte
  71. addrType byte
  72. ipv4 [4]byte
  73. domain string
  74. ipv6 [16]byte
  75. port uint16
  76. }
  77. func ReadRequest(reader io.Reader) (request *Socks5Request, err error) {
  78. request = new(Socks5Request)
  79. buffer := make([]byte, 4)
  80. nBytes, err := reader.Read(buffer)
  81. if err != nil {
  82. return
  83. }
  84. if nBytes < len(buffer) {
  85. err = fmt.Errorf("Unable to read request.")
  86. return
  87. }
  88. request.version = buffer[0]
  89. request.command = buffer[1]
  90. // buffer[2] is a reserved field
  91. request.addrType = buffer[3]
  92. switch request.addrType {
  93. case 0x01:
  94. nBytes, err = reader.Read(request.ipv4[:])
  95. if err != nil {
  96. return
  97. }
  98. if nBytes != 4 {
  99. err = fmt.Errorf("Unable to read IPv4 address.")
  100. return
  101. }
  102. case 0x03:
  103. buffer = make([]byte, 257)
  104. nBytes, err = reader.Read(buffer)
  105. if err != nil {
  106. return
  107. }
  108. domainLength := buffer[0]
  109. if nBytes != int(domainLength)+1 {
  110. err = fmt.Errorf("Unable to read domain")
  111. return
  112. }
  113. request.domain = string(buffer[1 : domainLength+1])
  114. case 0x04:
  115. nBytes, err = reader.Read(request.ipv6[:])
  116. if err != nil {
  117. return
  118. }
  119. if nBytes != 16 {
  120. err = fmt.Errorf("Unable to read IPv4 address.")
  121. return
  122. }
  123. default:
  124. err = fmt.Errorf("Unexpected address type %d", request.addrType)
  125. return
  126. }
  127. buffer = make([]byte, 2)
  128. nBytes, err = reader.Read(buffer)
  129. if err != nil {
  130. return
  131. }
  132. if nBytes != 2 {
  133. err = fmt.Errorf("Unable to read port.")
  134. return
  135. }
  136. request.port = binary.BigEndian.Uint16(buffer)
  137. return
  138. }
  139. const (
  140. ErrorSuccess = byte(0x00)
  141. ErrorGeneralFailure = byte(0x01)
  142. ErrorConnectionNotAllowed = byte(0x02)
  143. ErrorNetworkUnreachable = byte(0x03)
  144. ErrorHostUnUnreachable = byte(0x04)
  145. ErrorConnectionRefused = byte(0x05)
  146. ErrorTTLExpired = byte(0x06)
  147. ErrorCommandNotSupported = byte(0x07)
  148. ErrorAddressTypeNotSupported = byte(0x08)
  149. )
  150. type Socks5Response struct {
  151. Version byte
  152. Error byte
  153. AddrType byte
  154. IPv4 [4]byte
  155. Domain string
  156. IPv6 [16]byte
  157. Port uint16
  158. }
  159. func (r Socks5Response) toBytes() []byte {
  160. buffer := make([]byte, 0, 300)
  161. buffer = append(buffer, r.Version)
  162. buffer = append(buffer, r.Error)
  163. buffer = append(buffer, 0x00) // reserved
  164. buffer = append(buffer, r.AddrType)
  165. switch r.AddrType {
  166. case 0x01:
  167. buffer = append(buffer, r.IPv4[:]...)
  168. case 0x03:
  169. buffer = append(buffer, byte(len(r.Domain)))
  170. buffer = append(buffer, []byte(r.Domain)...)
  171. case 0x04:
  172. buffer = append(buffer, r.IPv6[:]...)
  173. }
  174. portBuffer := make([]byte, 2)
  175. binary.BigEndian.PutUint16(portBuffer, r.Port)
  176. buffer = append(buffer, portBuffer...)
  177. return buffer
  178. }
  179. func WriteResponse(writer io.Writer, response Socks5Response) error {
  180. _, err := writer.Write(response.toBytes())
  181. return err
  182. }