socks.go 6.0 KB

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