123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- package client
- import (
- "io"
- "sync"
- "time"
- "github.com/fatedier/frp/models/config"
- "github.com/fatedier/frp/models/msg"
- frpIo "github.com/fatedier/frp/utils/io"
- "github.com/fatedier/frp/utils/log"
- frpNet "github.com/fatedier/frp/utils/net"
- "github.com/fatedier/frp/utils/util"
- )
- type Vistor interface {
- Run() error
- Close()
- log.Logger
- }
- func NewVistor(ctl *Control, pxyConf config.ProxyConf) (vistor Vistor) {
- baseVistor := BaseVistor{
- ctl: ctl,
- Logger: log.NewPrefixLogger(pxyConf.GetName()),
- }
- switch cfg := pxyConf.(type) {
- case *config.StcpProxyConf:
- vistor = &StcpVistor{
- BaseVistor: baseVistor,
- cfg: cfg,
- }
- }
- return
- }
- type BaseVistor struct {
- ctl *Control
- l frpNet.Listener
- closed bool
- mu sync.RWMutex
- log.Logger
- }
- type StcpVistor struct {
- BaseVistor
- cfg *config.StcpProxyConf
- }
- func (sv *StcpVistor) Run() (err error) {
- sv.l, err = frpNet.ListenTcp(sv.cfg.BindAddr, int64(sv.cfg.BindPort))
- if err != nil {
- return
- }
- go sv.worker()
- return
- }
- func (sv *StcpVistor) Close() {
- sv.l.Close()
- }
- func (sv *StcpVistor) worker() {
- for {
- conn, err := sv.l.Accept()
- if err != nil {
- sv.Warn("stcp local listener closed")
- return
- }
- go sv.handleConn(conn)
- }
- }
- func (sv *StcpVistor) handleConn(userConn frpNet.Conn) {
- defer userConn.Close()
- sv.Debug("get a new stcp user connection")
- vistorConn, err := sv.ctl.connectServer()
- if err != nil {
- return
- }
- defer vistorConn.Close()
- now := time.Now().Unix()
- newVistorConnMsg := &msg.NewVistorConn{
- ProxyName: sv.cfg.ServerName,
- SignKey: util.GetAuthKey(sv.cfg.Sk, now),
- Timestamp: now,
- UseEncryption: sv.cfg.UseEncryption,
- UseCompression: sv.cfg.UseCompression,
- }
- err = msg.WriteMsg(vistorConn, newVistorConnMsg)
- if err != nil {
- sv.Warn("send newVistorConnMsg to server error: %v", err)
- return
- }
- var newVistorConnRespMsg msg.NewVistorConnResp
- vistorConn.SetReadDeadline(time.Now().Add(10 * time.Second))
- err = msg.ReadMsgInto(vistorConn, &newVistorConnRespMsg)
- if err != nil {
- sv.Warn("get newVistorConnRespMsg error: %v", err)
- return
- }
- vistorConn.SetReadDeadline(time.Time{})
- if newVistorConnRespMsg.Error != "" {
- sv.Warn("start new vistor connection error: %s", newVistorConnRespMsg.Error)
- return
- }
- var remote io.ReadWriteCloser
- remote = vistorConn
- if sv.cfg.UseEncryption {
- remote, err = frpIo.WithEncryption(remote, []byte(sv.cfg.Sk))
- if err != nil {
- sv.Error("create encryption stream error: %v", err)
- return
- }
- }
- if sv.cfg.UseCompression {
- remote = frpIo.WithCompression(remote)
- }
- frpIo.Join(userConn, remote)
- }
|