socks.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  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. v2net "github.com/v2ray/v2ray-core/net"
  8. )
  9. const (
  10. socksVersion = uint8(5)
  11. AuthNotRequired = byte(0x00)
  12. AuthGssApi = byte(0x01)
  13. AuthUserPass = byte(0x02)
  14. AuthNoMatchingMethod = byte(0xFF)
  15. )
  16. // Authentication request header of Socks5 protocol
  17. type Socks5AuthenticationRequest struct {
  18. version byte
  19. nMethods byte
  20. authMethods [256]byte
  21. }
  22. func (request *Socks5AuthenticationRequest) HasAuthMethod(method byte) bool {
  23. for i := 0; i < int(request.nMethods); i++ {
  24. if request.authMethods[i] == method {
  25. return true
  26. }
  27. }
  28. return false
  29. }
  30. func ReadAuthentication(reader io.Reader) (auth Socks5AuthenticationRequest, err error) {
  31. buffer := make([]byte, 256)
  32. nBytes, err := reader.Read(buffer)
  33. if err != nil {
  34. return
  35. }
  36. if nBytes < 2 {
  37. err = fmt.Errorf("Expected 2 bytes read, but actaully %d bytes read", nBytes)
  38. return
  39. }
  40. auth.version = buffer[0]
  41. if auth.version != socksVersion {
  42. err = fmt.Errorf("Unknown SOCKS version %d", auth.version)
  43. return
  44. }
  45. auth.nMethods = buffer[1]
  46. if auth.nMethods <= 0 {
  47. err = fmt.Errorf("Zero length of authentication methods")
  48. return
  49. }
  50. if nBytes - 2 != int(auth.nMethods) {
  51. err = fmt.Errorf("Unmatching number of auth methods, expecting %d, but got %d", auth.nMethods, nBytes)
  52. return
  53. }
  54. copy(auth.authMethods[:], buffer[2:nBytes])
  55. return
  56. }
  57. type Socks5AuthenticationResponse struct {
  58. version byte
  59. authMethod byte
  60. }
  61. func NewAuthenticationResponse(authMethod byte) *Socks5AuthenticationResponse {
  62. response := new(Socks5AuthenticationResponse)
  63. response.version = socksVersion
  64. response.authMethod = authMethod
  65. return response
  66. }
  67. func (r *Socks5AuthenticationResponse) ToBytes() []byte {
  68. return []byte{r.version, r.authMethod}
  69. }
  70. func WriteAuthentication(writer io.Writer, response *Socks5AuthenticationResponse) error {
  71. _, err := writer.Write(response.ToBytes())
  72. return err
  73. }
  74. const (
  75. AddrTypeIPv4 = byte(0x01)
  76. AddrTypeIPv6 = byte(0x04)
  77. AddrTypeDomain = byte(0x03)
  78. CmdConnect = byte(0x01)
  79. CmdBind = byte(0x02)
  80. CmdUdpAssociate = byte(0x03)
  81. )
  82. type Socks5Request struct {
  83. Version byte
  84. Command byte
  85. AddrType byte
  86. IPv4 [4]byte
  87. Domain string
  88. IPv6 [16]byte
  89. Port uint16
  90. }
  91. func ReadRequest(reader io.Reader) (request *Socks5Request, err error) {
  92. request = new(Socks5Request)
  93. buffer := make([]byte, 4)
  94. nBytes, err := reader.Read(buffer)
  95. if err != nil {
  96. return
  97. }
  98. if nBytes < len(buffer) {
  99. err = fmt.Errorf("Unable to read request.")
  100. return
  101. }
  102. request.Version = buffer[0]
  103. request.Command = buffer[1]
  104. // buffer[2] is a reserved field
  105. request.AddrType = buffer[3]
  106. switch request.AddrType {
  107. case AddrTypeIPv4:
  108. nBytes, err = reader.Read(request.IPv4[:])
  109. if err != nil {
  110. return
  111. }
  112. if nBytes != 4 {
  113. err = fmt.Errorf("Unable to read IPv4 address.")
  114. return
  115. }
  116. case AddrTypeDomain:
  117. buffer = make([]byte, 256)
  118. nBytes, err = reader.Read(buffer[0:1])
  119. if err != nil {
  120. return
  121. }
  122. domainLength := buffer[0]
  123. nBytes, err = reader.Read(buffer[:domainLength])
  124. if err != nil {
  125. return
  126. }
  127. if nBytes != int(domainLength) {
  128. err = fmt.Errorf("Unable to read domain with %d bytes, expecting %d bytes", nBytes, domainLength)
  129. return
  130. }
  131. request.Domain = string(buffer[:domainLength])
  132. case AddrTypeIPv6:
  133. nBytes, err = reader.Read(request.IPv6[:])
  134. if err != nil {
  135. return
  136. }
  137. if nBytes != 16 {
  138. err = fmt.Errorf("Unable to read IPv4 address.")
  139. return
  140. }
  141. default:
  142. err = fmt.Errorf("Unexpected address type %d", request.AddrType)
  143. return
  144. }
  145. buffer = make([]byte, 2)
  146. nBytes, err = reader.Read(buffer)
  147. if err != nil {
  148. return
  149. }
  150. if nBytes != 2 {
  151. err = fmt.Errorf("Unable to read port.")
  152. return
  153. }
  154. request.Port = binary.BigEndian.Uint16(buffer)
  155. return
  156. }
  157. func (request *Socks5Request) Destination() v2net.Address {
  158. switch request.AddrType {
  159. case AddrTypeIPv4:
  160. return v2net.IPAddress(request.IPv4[:], request.Port)
  161. case AddrTypeIPv6:
  162. return v2net.IPAddress(request.IPv6[:], request.Port)
  163. case AddrTypeDomain:
  164. return v2net.DomainAddress(request.Domain, request.Port)
  165. default:
  166. panic("Unknown address type")
  167. }
  168. }
  169. const (
  170. ErrorSuccess = byte(0x00)
  171. ErrorGeneralFailure = byte(0x01)
  172. ErrorConnectionNotAllowed = byte(0x02)
  173. ErrorNetworkUnreachable = byte(0x03)
  174. ErrorHostUnUnreachable = byte(0x04)
  175. ErrorConnectionRefused = byte(0x05)
  176. ErrorTTLExpired = byte(0x06)
  177. ErrorCommandNotSupported = byte(0x07)
  178. ErrorAddressTypeNotSupported = byte(0x08)
  179. )
  180. type Socks5Response struct {
  181. Version byte
  182. Error byte
  183. AddrType byte
  184. IPv4 [4]byte
  185. Domain string
  186. IPv6 [16]byte
  187. Port uint16
  188. }
  189. func NewSocks5Response() *Socks5Response {
  190. response := new(Socks5Response)
  191. response.Version = socksVersion
  192. return response
  193. }
  194. func (r *Socks5Response) SetIPv4(ipv4 []byte) {
  195. r.AddrType = AddrTypeIPv4
  196. copy(r.IPv4[:], ipv4)
  197. }
  198. func (r *Socks5Response) SetIPv6(ipv6 []byte) {
  199. r.AddrType = AddrTypeIPv6
  200. copy(r.IPv6[:], ipv6)
  201. }
  202. func (r *Socks5Response) SetDomain(domain string) {
  203. r.AddrType = AddrTypeDomain
  204. r.Domain = domain
  205. }
  206. func (r *Socks5Response) toBytes() []byte {
  207. buffer := make([]byte, 0, 300)
  208. buffer = append(buffer, r.Version)
  209. buffer = append(buffer, r.Error)
  210. buffer = append(buffer, 0x00) // reserved
  211. buffer = append(buffer, r.AddrType)
  212. switch r.AddrType {
  213. case 0x01:
  214. buffer = append(buffer, r.IPv4[:]...)
  215. case 0x03:
  216. buffer = append(buffer, byte(len(r.Domain)))
  217. buffer = append(buffer, []byte(r.Domain)...)
  218. case 0x04:
  219. buffer = append(buffer, r.IPv6[:]...)
  220. }
  221. portBuffer := make([]byte, 2)
  222. binary.BigEndian.PutUint16(portBuffer, r.Port)
  223. buffer = append(buffer, portBuffer...)
  224. return buffer
  225. }
  226. func WriteResponse(writer io.Writer, response *Socks5Response) error {
  227. _, err := writer.Write(response.toBytes())
  228. return err
  229. }