stcp.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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. frpIo "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. sv.l, err = net.Listen("tcp", net.JoinHostPort(sv.cfg.BindAddr, strconv.Itoa(sv.cfg.BindPort)))
  32. if err != nil {
  33. return
  34. }
  35. go sv.worker()
  36. return
  37. }
  38. func (sv *STCPVisitor) Close() {
  39. sv.l.Close()
  40. }
  41. func (sv *STCPVisitor) worker() {
  42. xl := xlog.FromContextSafe(sv.ctx)
  43. for {
  44. conn, err := sv.l.Accept()
  45. if err != nil {
  46. xl.Warn("stcp local listener closed")
  47. return
  48. }
  49. go sv.handleConn(conn)
  50. }
  51. }
  52. func (sv *STCPVisitor) handleConn(userConn net.Conn) {
  53. xl := xlog.FromContextSafe(sv.ctx)
  54. defer userConn.Close()
  55. xl.Debug("get a new stcp user connection")
  56. visitorConn, err := sv.connectServer()
  57. if err != nil {
  58. return
  59. }
  60. defer visitorConn.Close()
  61. now := time.Now().Unix()
  62. newVisitorConnMsg := &msg.NewVisitorConn{
  63. ProxyName: sv.cfg.ServerName,
  64. SignKey: util.GetAuthKey(sv.cfg.Sk, now),
  65. Timestamp: now,
  66. UseEncryption: sv.cfg.UseEncryption,
  67. UseCompression: sv.cfg.UseCompression,
  68. }
  69. err = msg.WriteMsg(visitorConn, newVisitorConnMsg)
  70. if err != nil {
  71. xl.Warn("send newVisitorConnMsg to server error: %v", err)
  72. return
  73. }
  74. var newVisitorConnRespMsg msg.NewVisitorConnResp
  75. _ = visitorConn.SetReadDeadline(time.Now().Add(10 * time.Second))
  76. err = msg.ReadMsgInto(visitorConn, &newVisitorConnRespMsg)
  77. if err != nil {
  78. xl.Warn("get newVisitorConnRespMsg error: %v", err)
  79. return
  80. }
  81. _ = visitorConn.SetReadDeadline(time.Time{})
  82. if newVisitorConnRespMsg.Error != "" {
  83. xl.Warn("start new visitor connection error: %s", newVisitorConnRespMsg.Error)
  84. return
  85. }
  86. var remote io.ReadWriteCloser
  87. remote = visitorConn
  88. if sv.cfg.UseEncryption {
  89. remote, err = frpIo.WithEncryption(remote, []byte(sv.cfg.Sk))
  90. if err != nil {
  91. xl.Error("create encryption stream error: %v", err)
  92. return
  93. }
  94. }
  95. if sv.cfg.UseCompression {
  96. remote = frpIo.WithCompression(remote)
  97. }
  98. frpIo.Join(userConn, remote)
  99. }