stcp.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. // Copyright 2017 fatedier, fatedier@gmail.com
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package visitor
  15. import (
  16. "io"
  17. "net"
  18. "strconv"
  19. "time"
  20. libio "github.com/fatedier/golib/io"
  21. "github.com/fatedier/frp/pkg/config"
  22. "github.com/fatedier/frp/pkg/msg"
  23. "github.com/fatedier/frp/pkg/util/util"
  24. "github.com/fatedier/frp/pkg/util/xlog"
  25. )
  26. type STCPVisitor struct {
  27. *BaseVisitor
  28. cfg *config.STCPVisitorConf
  29. }
  30. func (sv *STCPVisitor) Run() (err error) {
  31. if sv.cfg.BindPort > 0 {
  32. sv.l, err = net.Listen("tcp", net.JoinHostPort(sv.cfg.BindAddr, strconv.Itoa(sv.cfg.BindPort)))
  33. if err != nil {
  34. return
  35. }
  36. go sv.worker()
  37. }
  38. go sv.internalConnWorker()
  39. return
  40. }
  41. func (sv *STCPVisitor) Close() {
  42. sv.BaseVisitor.Close()
  43. }
  44. func (sv *STCPVisitor) worker() {
  45. xl := xlog.FromContextSafe(sv.ctx)
  46. for {
  47. conn, err := sv.l.Accept()
  48. if err != nil {
  49. xl.Warn("stcp local listener closed")
  50. return
  51. }
  52. go sv.handleConn(conn)
  53. }
  54. }
  55. func (sv *STCPVisitor) internalConnWorker() {
  56. xl := xlog.FromContextSafe(sv.ctx)
  57. for {
  58. conn, err := sv.internalLn.Accept()
  59. if err != nil {
  60. xl.Warn("stcp internal listener closed")
  61. return
  62. }
  63. go sv.handleConn(conn)
  64. }
  65. }
  66. func (sv *STCPVisitor) handleConn(userConn net.Conn) {
  67. xl := xlog.FromContextSafe(sv.ctx)
  68. defer userConn.Close()
  69. xl.Debug("get a new stcp user connection")
  70. visitorConn, err := sv.connectServer()
  71. if err != nil {
  72. return
  73. }
  74. defer visitorConn.Close()
  75. now := time.Now().Unix()
  76. newVisitorConnMsg := &msg.NewVisitorConn{
  77. ProxyName: sv.cfg.ServerName,
  78. SignKey: util.GetAuthKey(sv.cfg.Sk, now),
  79. Timestamp: now,
  80. UseEncryption: sv.cfg.UseEncryption,
  81. UseCompression: sv.cfg.UseCompression,
  82. }
  83. err = msg.WriteMsg(visitorConn, newVisitorConnMsg)
  84. if err != nil {
  85. xl.Warn("send newVisitorConnMsg to server error: %v", err)
  86. return
  87. }
  88. var newVisitorConnRespMsg msg.NewVisitorConnResp
  89. _ = visitorConn.SetReadDeadline(time.Now().Add(10 * time.Second))
  90. err = msg.ReadMsgInto(visitorConn, &newVisitorConnRespMsg)
  91. if err != nil {
  92. xl.Warn("get newVisitorConnRespMsg error: %v", err)
  93. return
  94. }
  95. _ = visitorConn.SetReadDeadline(time.Time{})
  96. if newVisitorConnRespMsg.Error != "" {
  97. xl.Warn("start new visitor connection error: %s", newVisitorConnRespMsg.Error)
  98. return
  99. }
  100. var remote io.ReadWriteCloser
  101. remote = visitorConn
  102. if sv.cfg.UseEncryption {
  103. remote, err = libio.WithEncryption(remote, []byte(sv.cfg.Sk))
  104. if err != nil {
  105. xl.Error("create encryption stream error: %v", err)
  106. return
  107. }
  108. }
  109. if sv.cfg.UseCompression {
  110. remote = libio.WithCompression(remote)
  111. }
  112. libio.Join(userConn, remote)
  113. }