snowflake.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. package snowflake
  2. import (
  3. "errors"
  4. "fmt"
  5. "net"
  6. "net/url"
  7. "strconv"
  8. "strings"
  9. pt "gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/goptlib"
  10. "gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/lyrebird/transports/base"
  11. sf "gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/client/lib"
  12. "gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/event"
  13. "gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/proxy"
  14. )
  15. const transportName = "snowflake"
  16. type sfEventLogger struct {
  17. onEventCallback func(e base.TransportEvent)
  18. }
  19. func (el *sfEventLogger) OnNewSnowflakeEvent(e event.SnowflakeEvent) {
  20. if el.onEventCallback != nil {
  21. el.onEventCallback(e)
  22. }
  23. }
  24. type Transport struct{}
  25. // Name returns the name of the snowflake transport protocol.
  26. func (t *Transport) Name() string {
  27. return transportName
  28. }
  29. // ClientFactory returns a new snowflakeClientFactory instance.
  30. func (t *Transport) ClientFactory(stateDir string) (base.ClientFactory, error) {
  31. cf := &snowflakeClientFactory{transport: t}
  32. cf.eventLogger = &sfEventLogger{}
  33. return cf, nil
  34. }
  35. // ServerFactory is not implemented for snowflake
  36. func (t *Transport) ServerFactory(stateDir string, args *pt.Args) (base.ServerFactory, error) {
  37. return nil, errors.New("ServerFactory not implemented for the snowflake transport")
  38. }
  39. type snowflakeClientFactory struct {
  40. transport base.Transport
  41. eventLogger *sfEventLogger
  42. }
  43. func (cf *snowflakeClientFactory) Transport() base.Transport {
  44. return cf.transport
  45. }
  46. func (cf *snowflakeClientFactory) ParseArgs(args *pt.Args) (interface{}, error) {
  47. config := sf.ClientConfig{}
  48. if arg, ok := args.Get("ampcache"); ok {
  49. config.AmpCacheURL = arg
  50. }
  51. if arg, ok := args.Get("sqsqueue"); ok {
  52. config.SQSQueueURL = arg
  53. }
  54. if arg, ok := args.Get("sqscreds"); ok {
  55. config.SQSCredsStr = arg
  56. }
  57. if arg, ok := args.Get("fronts"); ok {
  58. if arg != "" {
  59. config.FrontDomains = strings.Split(strings.TrimSpace(arg), ",")
  60. }
  61. } else if arg, ok := args.Get("front"); ok {
  62. config.FrontDomains = strings.Split(strings.TrimSpace(arg), ",")
  63. }
  64. if arg, ok := args.Get("ice"); ok {
  65. config.ICEAddresses = strings.Split(strings.TrimSpace(arg), ",")
  66. }
  67. if arg, ok := args.Get("max"); ok {
  68. max, err := strconv.Atoi(arg)
  69. if err != nil {
  70. return nil, fmt.Errorf("Invalid SOCKS arg: max=%s", arg)
  71. }
  72. config.Max = max
  73. }
  74. if arg, ok := args.Get("url"); ok {
  75. config.BrokerURL = arg
  76. }
  77. if arg, ok := args.Get("utls-nosni"); ok {
  78. switch strings.ToLower(arg) {
  79. case "true", "yes":
  80. config.UTLSRemoveSNI = true
  81. }
  82. }
  83. if arg, ok := args.Get("utls-imitate"); ok {
  84. config.UTLSClientID = arg
  85. }
  86. if arg, ok := args.Get("fingerprint"); ok {
  87. config.BridgeFingerprint = arg
  88. }
  89. if arg, ok := args.Get("proxy"); ok {
  90. outboundProxy, err := url.Parse(arg)
  91. if err != nil {
  92. return nil, fmt.Errorf("Invalid SOCKS arg: proxy=%s", arg)
  93. }
  94. if err := proxy.CheckProxyProtocolSupport(outboundProxy); err != nil {
  95. return nil, fmt.Errorf("proxy is not supported: %s", err.Error())
  96. }
  97. client := proxy.NewSocks5UDPClient(outboundProxy)
  98. conn, err := client.ListenPacket("udp", nil)
  99. if err != nil {
  100. return nil, fmt.Errorf("proxy test failure: %s", err.Error())
  101. }
  102. conn.Close()
  103. config.CommunicationProxy = outboundProxy
  104. }
  105. return config, nil
  106. }
  107. func (cf *snowflakeClientFactory) OnEvent(f func(e base.TransportEvent)) {
  108. cf.eventLogger.onEventCallback = f
  109. }
  110. func (cf *snowflakeClientFactory) Dial(network, address string, dialFn base.DialFunc, args interface{}) (net.Conn, error) {
  111. config, ok := args.(sf.ClientConfig)
  112. if !ok {
  113. return nil, errors.New("invalid type for args")
  114. }
  115. transport, err := sf.NewSnowflakeClient(config)
  116. if err != nil {
  117. return nil, err
  118. }
  119. transport.AddSnowflakeEventListener(cf.eventLogger)
  120. return transport.Dial()
  121. }