dialer.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package hub
  2. import (
  3. "errors"
  4. "net"
  5. "time"
  6. v2net "github.com/v2ray/v2ray-core/common/net"
  7. "github.com/v2ray/v2ray-core/proxy"
  8. "github.com/v2ray/v2ray-core/transport"
  9. )
  10. var (
  11. ErrorInvalidHost = errors.New("Invalid Host.")
  12. globalCache = NewConnectionCache()
  13. )
  14. func Dial(src v2net.Address, dest v2net.Destination) (*Connection, error) {
  15. if src == nil {
  16. src = v2net.AnyIP
  17. }
  18. id := src.String() + "-" + dest.NetAddr()
  19. var conn net.Conn
  20. if dest.IsTCP() && transport.IsConnectionReusable() {
  21. conn = globalCache.Get(id)
  22. }
  23. if conn == nil {
  24. var err error
  25. conn, err = DialWithoutCache(src, dest)
  26. if err != nil {
  27. return nil, err
  28. }
  29. }
  30. return &Connection{
  31. dest: id,
  32. conn: conn,
  33. listener: globalCache,
  34. }, nil
  35. }
  36. func DialWithoutCache(src v2net.Address, dest v2net.Destination) (net.Conn, error) {
  37. dialer := &net.Dialer{
  38. Timeout: time.Second * 60,
  39. DualStack: true,
  40. }
  41. if src != nil && src != v2net.AnyIP {
  42. var addr net.Addr
  43. if dest.IsTCP() {
  44. addr = &net.TCPAddr{
  45. IP: src.IP(),
  46. Port: 0,
  47. }
  48. } else {
  49. addr = &net.UDPAddr{
  50. IP: src.IP(),
  51. Port: 0,
  52. }
  53. }
  54. dialer.LocalAddr = addr
  55. }
  56. return dialer.Dial(dest.Network().String(), dest.NetAddr())
  57. }
  58. func Dial3(src v2net.Address, dest v2net.Destination, proxyMeta *proxy.OutboundHandlerMeta) (*Connection, error) {
  59. if proxyMeta.KcpSupported && transport.IsKcpEnabled() {
  60. return DialKCP3(src, dest, proxyMeta)
  61. }
  62. return Dial(src, dest)
  63. }
  64. func DialWithoutCache3(src v2net.Address, dest v2net.Destination, proxyMeta *proxy.OutboundHandlerMeta) (net.Conn, error) {
  65. if proxyMeta.KcpSupported && transport.IsKcpEnabled() {
  66. return DialKCPWithoutCache(src, dest)
  67. }
  68. return DialWithoutCache(src, dest)
  69. }
  70. func DialKCP3(src v2net.Address, dest v2net.Destination, proxyMeta *proxy.OutboundHandlerMeta) (*Connection, error) {
  71. if src == nil {
  72. src = v2net.AnyIP
  73. }
  74. id := src.String() + "-" + dest.NetAddr()
  75. conn, err := DialWithoutCache3(src, dest, proxyMeta)
  76. if err != nil {
  77. return nil, err
  78. }
  79. return &Connection{
  80. dest: id,
  81. conn: conn,
  82. listener: globalCache,
  83. }, nil
  84. }
  85. /*DialKCPWithoutCache Dial KCP connection
  86. This Dialer will ignore src this is a restriction
  87. due to github.com/xtaci/kcp-go.DialWithOptions
  88. */
  89. func DialKCPWithoutCache(src v2net.Address, dest v2net.Destination) (net.Conn, error) {
  90. return DialKCP(dest)
  91. }