socks.go 6.0 KB

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