freedom.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. package freedom
  2. //go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg freedom -path Proxy,Freedom
  3. import (
  4. "context"
  5. "time"
  6. "v2ray.com/core/app"
  7. "v2ray.com/core/app/dns"
  8. "v2ray.com/core/app/log"
  9. "v2ray.com/core/common"
  10. "v2ray.com/core/common/buf"
  11. "v2ray.com/core/common/dice"
  12. "v2ray.com/core/common/net"
  13. "v2ray.com/core/common/retry"
  14. "v2ray.com/core/common/signal"
  15. "v2ray.com/core/proxy"
  16. "v2ray.com/core/transport/internet"
  17. "v2ray.com/core/transport/ray"
  18. )
  19. type Handler struct {
  20. domainStrategy Config_DomainStrategy
  21. timeout uint32
  22. dns dns.Server
  23. destOverride *DestinationOverride
  24. }
  25. func New(ctx context.Context, config *Config) (*Handler, error) {
  26. space := app.SpaceFromContext(ctx)
  27. if space == nil {
  28. return nil, newError("no space in context")
  29. }
  30. f := &Handler{
  31. domainStrategy: config.DomainStrategy,
  32. timeout: config.Timeout,
  33. destOverride: config.DestinationOverride,
  34. }
  35. space.OnInitialize(func() error {
  36. if config.DomainStrategy == Config_USE_IP {
  37. f.dns = dns.FromSpace(space)
  38. if f.dns == nil {
  39. return newError("DNS server is not found in the space")
  40. }
  41. }
  42. return nil
  43. })
  44. return f, nil
  45. }
  46. func (v *Handler) ResolveIP(destination net.Destination) net.Destination {
  47. if !destination.Address.Family().IsDomain() {
  48. return destination
  49. }
  50. ips := v.dns.Get(destination.Address.Domain())
  51. if len(ips) == 0 {
  52. log.Trace(newError("DNS returns nil answer. Keep domain as is."))
  53. return destination
  54. }
  55. ip := ips[dice.Roll(len(ips))]
  56. newDest := net.Destination{
  57. Network: destination.Network,
  58. Address: net.IPAddress(ip),
  59. Port: destination.Port,
  60. }
  61. log.Trace(newError("changing destination from ", destination, " to ", newDest))
  62. return newDest
  63. }
  64. func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dialer proxy.Dialer) error {
  65. destination, _ := proxy.TargetFromContext(ctx)
  66. if v.destOverride != nil {
  67. server := v.destOverride.Server
  68. destination = net.Destination{
  69. Network: destination.Network,
  70. Address: server.Address.AsAddress(),
  71. Port: net.Port(server.Port),
  72. }
  73. }
  74. log.Trace(newError("opening connection to ", destination))
  75. input := outboundRay.OutboundInput()
  76. output := outboundRay.OutboundOutput()
  77. var conn internet.Connection
  78. if v.domainStrategy == Config_USE_IP && destination.Address.Family().IsDomain() {
  79. destination = v.ResolveIP(destination)
  80. }
  81. err := retry.ExponentialBackoff(5, 100).On(func() error {
  82. rawConn, err := dialer.Dial(ctx, destination)
  83. if err != nil {
  84. return err
  85. }
  86. conn = rawConn
  87. return nil
  88. })
  89. if err != nil {
  90. return newError("failed to open connection to ", destination).Base(err)
  91. }
  92. defer conn.Close()
  93. timeout := time.Second * time.Duration(v.timeout)
  94. if timeout == 0 {
  95. timeout = time.Minute * 5
  96. }
  97. ctx, timer := signal.CancelAfterInactivity(ctx, timeout)
  98. requestDone := signal.ExecuteAsync(func() error {
  99. var writer buf.Writer
  100. if destination.Network == net.Network_TCP {
  101. writer = buf.NewWriter(conn)
  102. } else {
  103. writer = buf.NewSequentialWriter(conn)
  104. }
  105. if err := buf.Copy(input, writer, buf.UpdateActivity(timer)); err != nil {
  106. return newError("failed to process request").Base(err)
  107. }
  108. return nil
  109. })
  110. responseDone := signal.ExecuteAsync(func() error {
  111. defer output.Close()
  112. v2reader := buf.NewReader(conn)
  113. if err := buf.Copy(v2reader, output, buf.UpdateActivity(timer)); err != nil {
  114. return newError("failed to process response").Base(err)
  115. }
  116. return nil
  117. })
  118. if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil {
  119. input.CloseError()
  120. output.CloseError()
  121. return newError("connection ends").Base(err)
  122. }
  123. return nil
  124. }
  125. func init() {
  126. common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
  127. return New(ctx, config.(*Config))
  128. }))
  129. }