Commit 942eb493 authored by Tsaiilin's avatar Tsaiilin

update

parent 25464140
......@@ -19,7 +19,6 @@ type Client struct {
session getty.Session
transferStore sync.Map
dnsCache *freecache.Cache
close chan struct{}
}
func NewClientWithConf(cfg *model.Configure, host string, port int) *Client {
......@@ -49,3 +48,12 @@ func NewCli(cfg *model.Configure, host string, port int) *Client {
func (client *Client) StartUp() {
client.connect()
}
func (client *Client) Close() {
client.transferStore.Range(func(key, value interface{}) bool {
t := value.(*Transfer)
t.Close()
return true
})
client.transferStore = sync.Map{}
}
......@@ -29,21 +29,21 @@ func (c *ClusterClient) Start() {
timer.Reset(5 * time.Minute)
}
})
if global.Config.Redial.Valid() {
_ = taskPool.Submit(func() {
// 加上随机 防止vps在同时间重启
duration := c.randomDuration()
log.Run().Infof("Redial interval %+v", duration)
var timer = time.NewTimer(duration)
for {
<-timer.C
c.StartRedial("cron", true)
duration = c.randomDuration()
log.Run().Infof("Redial interval %+v", duration)
timer.Reset(duration)
}
})
}
//if global.Config.Redial.Valid() {
// _ = taskPool.Submit(func() {
// // 加上随机 防止vps在同时间重启
// duration := c.randomDuration()
// log.Run().Infof("Redial interval %+v", duration)
// var timer = time.NewTimer(duration)
// for {
// <-timer.C
// c.StartRedial("cron", true)
// duration = c.randomDuration()
// log.Run().Infof("Redial interval %+v", duration)
// timer.Reset(duration)
// }
// })
//}
}
func (c *ClusterClient) connectNatServers() {
......@@ -88,7 +88,6 @@ func (c *ClusterClient) connectNatServers() {
log.Error().Error("[connectNatServers] client already remove")
}
needCloseClient := load.(*Client)
needCloseClient.CloseAll()
needCloseClient.natTunnel.Close()
return true
})
......@@ -118,7 +117,6 @@ func (c *ClusterClient) StartRedial(tag string, replay bool) {
log.Run().Info("[Redial %s ] start close local session", tag)
c.clients.Range(func(host, c interface{}) bool {
client, _ := c.(*Client)
client.close = make(chan struct{})
client.natTunnel.Close()
return true
})
......@@ -126,11 +124,7 @@ func (c *ClusterClient) StartRedial(tag string, replay bool) {
c.clients.Range(func(host, c interface{}) bool {
client, _ := c.(*Client)
_ = taskPool.Submit(func() {
select {
case <-client.close:
client.connect()
client.close = nil
}
})
return true
})
......
......@@ -3,12 +3,11 @@ package client
import (
"bytes"
"encoding/binary"
"errors"
"fmt"
"github.com/adamweixuan/getty"
"net"
"strings"
"sync"
"virjar.com/majora-go/common"
"virjar.com/majora-go/global"
"virjar.com/majora-go/log"
......@@ -50,26 +49,14 @@ func (client *Client) handleConnect(packet *protocol.MajoraPacket, session getty
recorder.RecordEvent(trace.ConnectEvent, fmt.Sprintf("Start handle connect to %s (sn:%d)",
packet.Extra, packet.SerialNumber))
if session.IsClosed() {
log.Run().Warnf("[handleConnect] %d -> nat server is closed", packet.SerialNumber)
recorder.RecordErrorEvent(trace.ConnectEvent, fmt.Sprintf("NatServer is closed (sn:%d)", packet.SerialNumber), nil)
client.closeVirtualConnection(session, packet.SerialNumber)
return
}
hostPort := strings.Split(packet.Extra, ":")
if len(packet.Extra) == 0 || len(hostPort) != 2 {
log.Error().Errorf("[handleConnect] invalid extra %s", packet.Extra)
recorder.RecordErrorEvent(trace.ConnectEvent,
fmt.Sprintf("Connect extra invalid %s (%d)", packet.Extra, packet.SerialNumber), nil)
client.closeVirtualConnection(session, packet.SerialNumber)
return
}
dialer := net.Dialer{
Timeout: common.UpstreamTimeout,
LocalAddr: client.localAddr,
}
target := hostPort[0]
ip, err := client.dnsCache.Get([]byte(hostPort[0]))
if err != nil {
......@@ -77,7 +64,6 @@ func (client *Client) handleConnect(packet *protocol.MajoraPacket, session getty
hosts, dnsErr := net.LookupHost(hostPort[0])
if dnsErr != nil {
recorder.RecordErrorEvent(trace.DnsResolveEvent, fmt.Sprintf("Resolve %s ip error", hostPort[0]), dnsErr)
client.closeVirtualConnection(session, packet.SerialNumber)
return
}
err := client.dnsCache.Set([]byte(hostPort[0]), []byte(hosts[0]), int(global.Config.DnsCacheDuration.Seconds()))
......@@ -90,48 +76,7 @@ func (client *Client) handleConnect(packet *protocol.MajoraPacket, session getty
recorder.RecordEvent(trace.DnsResolveEvent, fmt.Sprintf("Dns cache hit %s -> %s", hostPort[0], target))
}
conn, err := dialer.Dial(common.TCP, fmt.Sprintf("%s:%s", target, hostPort[1]))
if err != nil {
log.Error().Errorf("[handleConnect] %d->connect to %s->%s", packet.SerialNumber, packet.Extra, err.Error())
recorder.RecordErrorEvent(trace.ConnectEvent,
fmt.Sprintf("Connect to %s failed (sn:%d)", packet.Extra, packet.SerialNumber), err)
client.closeVirtualConnection(session, packet.SerialNumber)
return
}
tcpConn := conn.(*net.TCPConn)
_ = tcpConn.SetNoDelay(true)
_ = tcpConn.SetKeepAlive(true)
t := NewTransfer(packet.SerialNumber, client, tcpConn, recorder)
t.SetTransferToUpstreamFunc(client.transferToUpstream)
t.SetTransferToDownstreamFunc(client.transferToDownstream)
client.AddTransfer(packet.SerialNumber, t, packet.Extra)
recorder.RecordEvent(trace.ConnectEvent, fmt.Sprintf("Connect to %s success, local: %s -> remote:%s (aaasn:%d)",
packet.Extra, tcpConn.LocalAddr(), tcpConn.RemoteAddr(), packet.SerialNumber))
recorder.RecordEvent(trace.ConnectEvent, fmt.Sprintf("Start replay natServer connect ready (sn:%d)", packet.SerialNumber))
majoraPacket := protocol.TypeConnectReady.CreatePacket()
majoraPacket.SerialNumber = packet.SerialNumber
majoraPacket.Extra = client.config.ClientID
if session.IsClosed() {
log.Run().Warnf("[handleConnect] %d -> nat server is closed", packet.SerialNumber)
recorder.RecordErrorEvent(trace.ConnectEvent, fmt.Sprintf("NatServer is closed (sn:%d)", packet.SerialNumber),
nil)
client.closeVirtualConnection(session, packet.SerialNumber)
return
}
if _, _, err := session.WritePkg(majoraPacket, 0); err != nil {
log.Error().Errorf("[handleConnect] %d->write pkg to nat server with error %s", packet.SerialNumber,
err.Error())
recorder.RecordErrorEvent(trace.ConnectEvent, fmt.Sprintf("Write pkg to natServer failed (sn:%d)",
packet.SerialNumber), err)
client.closeVirtualConnection(session, packet.SerialNumber)
return
} else {
t.Start()
log.Run().Debugf("[handleConnect] %d->connect success to %s ", packet.SerialNumber, packet.Extra)
recorder.RecordEvent(trace.ConnectEvent, fmt.Sprintf("Replay natServer connect ready success (sn:%d)", packet.SerialNumber))
}
NewTransfer(packet.SerialNumber, fmt.Sprintf("%s:%s", target, hostPort[1]), session, client, recorder).Start()
}
func decodeMap(data []byte) map[string]string {
......@@ -173,7 +118,7 @@ func (client *Client) handleTransfer(packet *protocol.MajoraPacket, session gett
}
t.recorder.RecordEvent(trace.TransferEvent,
fmt.Sprintf("Receive transfer packet from natServer,start to be forward to target, len:%d (%d)", len(packet.Data), packet.SerialNumber))
t.TransferToUpstream(packet)
t.TransferToUpstream(packet.Data)
}
func (client *Client) handleDisconnectMessage(session getty.Session, packet *protocol.MajoraPacket) {
......@@ -184,6 +129,7 @@ func (client *Client) handleDisconnectMessage(session getty.Session, packet *pro
log.Run().Debug("handleDisconnectMessage can't find transfer")
return
}
t.recorder.RecordEvent(trace.DisconnectEvent, fmt.Sprintf("Received disconnect packet (sn:%d)", t.serialNumber))
t.Close()
}
......@@ -217,122 +163,86 @@ func (client *Client) GetTransfer(sn int64) (*Transfer, bool) {
return transfer, true
}
func (client *Client) AddTransfer(sn int64, transfer *Transfer, addr string) {
func (client *Client) AddTransfer(sn int64, transfer *Transfer) error {
if _, ok := client.transferStore.Load(sn); ok {
log.Error().Errorf("[AddTransfer] %d->error, has one", sn)
return
return errors.New(fmt.Sprintf("Already has serialNumber:%d transfer", sn))
}
client.transferStore.Store(sn, transfer)
log.Run().Debugf("[AddTransfer] %d->%s success", sn, addr)
}
// OnClose 1. 本地缓存删除 2. 关闭连接 3. 通知natserver
func (client *Client) OnClose(natSession getty.Session, upStreamSession net.Conn, serialNumber int64) {
defer func() {
if err := recover(); err != nil {
log.Error().Errorf("OnClose %+v", err)
}
}()
client.closeVirtualConnection(natSession, serialNumber)
_ = upStreamSession.Close()
return nil
}
//closeVirtualConnection disconnect to server
func (client *Client) closeVirtualConnection(session getty.Session, serialNumber int64) {
traceRecorder := client.GetRecorder(serialNumber)
log.Run().Debugf("[closeVirtualConnection] %d->session closed %v", serialNumber, session.IsClosed())
if session.IsClosed() {
log.Run().Warnf("[closeVirtualConnection] %d->session is closed", serialNumber)
func (client *Client) OnUpStreamConnectSuccess(t *Transfer) {
t.recorder.RecordEvent(trace.ConnectEvent, fmt.Sprintf("Start replay natServer connect ready (sn:%d)", t.serialNumber))
majoraPacket := protocol.TypeConnectReady.CreatePacket()
majoraPacket.SerialNumber = t.serialNumber
majoraPacket.Extra = client.config.ClientID
if client.session.IsClosed() {
log.Run().Warnf("[handleConnect] %d -> nat server is closed", t.serialNumber)
t.recorder.RecordErrorEvent(trace.ConnectEvent, fmt.Sprintf("NatServer is closed (sn:%d)", t.serialNumber),
nil)
return
}
traceRecorder.RecordEvent(trace.DisconnectEvent, fmt.Sprintf("Start send disconnect to natServer (sn:%d)", serialNumber))
majoraPacket := protocol.TypeDisconnect.CreatePacket()
majoraPacket.SerialNumber = serialNumber
majoraPacket.Extra = client.config.ClientID
if allCnt, sendCnt, err := session.WritePkg(majoraPacket, 0); err != nil {
log.Run().Warnf("[closeVirtualConnection] ->%d error %s session closed %v allCnt %d sendCnt %d",
serialNumber, err.Error(), session.IsClosed(), allCnt, sendCnt)
traceRecorder.RecordErrorEvent(trace.DisconnectEvent,
fmt.Sprintf("send disconnect to natServer failed closed:%v allCnt %d sendCnt %d (sn:%d)",
session.IsClosed(), allCnt, sendCnt, serialNumber), err)
session.Close()
if _, _, err := client.session.WritePkg(majoraPacket, 0); err != nil {
log.Error().Errorf("[handleConnect] %d->write pkg to nat server with error %+v", t.serialNumber,
err)
t.recorder.RecordErrorEvent(trace.ConnectEvent, fmt.Sprintf("Write pkg to natServer failed (sn:%d)",
t.serialNumber), err)
return
}
log.Run().Debugf("[handleConnect] %d->connect success to %s ", t.serialNumber, t.target)
t.recorder.RecordEvent(trace.ConnectEvent, fmt.Sprintf("Replay natServer connect ready success (sn:%d)", t.serialNumber))
err := client.AddTransfer(t.serialNumber, t)
if err != nil {
t.recorder.RecordErrorEvent(trace.UpStreamEvent, "Add transfer error: %+v", err)
return
}
client.transferStore.Delete(serialNumber)
traceRecorder.RecordEvent(trace.DisconnectEvent, fmt.Sprintf("Send disconnect to natServer success (sn:%d)", serialNumber))
}
func (client *Client) CloseAll() {
defer func() {
if err := recover(); err != nil {
log.Error().Errorf("OnClose %+v", err)
}
}()
client.transferStore.Range(func(key, value interface{}) bool {
serialNumber := key.(int64)
t, _ := value.(*Transfer)
log.Run().Debugf("[CloseAll] close serialNumber -> %d", serialNumber)
client.OnClose(client.session, t.upstreamConn, serialNumber)
return true
})
client.transferStore = sync.Map{}
func (client *Client) OnUpStreamConnectFailed(t *Transfer, err error) {
t.recorder.RecordErrorEvent(trace.UpStreamEvent, "Connect upstream failed", err)
}
func (client *Client) transferToUpstream(t *Transfer, p *protocol.MajoraPacket) {
cnt, err := t.upstreamConn.Write(p.Data)
if err != nil {
log.Error().Errorf("[handleTransfer] %d->write to upstream fail for %s", p.SerialNumber, err)
traceMessage := fmt.Sprintf("Write to upstream failed (%d)", p.SerialNumber)
t.recorder.RecordErrorEvent(trace.TransferEvent, traceMessage, err)
client.closeVirtualConnection(client.session, p.SerialNumber)
func (client *Client) OnUpStreamWriteError(t *Transfer, err error) {
t.recorder.RecordErrorEvent(trace.DisconnectEvent, fmt.Sprintf("UpStream write error (sn:%d)", t.serialNumber), err)
client.transferStore.Delete(t.serialNumber)
t.Close()
majoraPacket := protocol.TypeDisconnect.CreatePacket()
majoraPacket.SerialNumber = t.serialNumber
majoraPacket.Extra = client.config.ClientID
if allCnt, sendCnt, err := client.session.WritePkg(majoraPacket, 0); err != nil {
log.Run().Warnf("[closeVirtualConnection] ->%d error %s session closed %v allCnt %d sendCnt %d",
t.serialNumber, err.Error(), client.session, allCnt, sendCnt)
t.recorder.RecordErrorEvent(trace.DisconnectEvent,
fmt.Sprintf("send disconnect to natServer failed closed:%v allCnt %d sendCnt %d (sn:%d)",
client.session.IsClosed(), allCnt, sendCnt, t.serialNumber), err)
return
}
t.recorder.RecordEvent(trace.DisconnectEvent, fmt.Sprintf("Send disconnect to natServer success (sn:%d)", t.serialNumber))
}
if cnt != len(p.Data) {
log.Error().Errorf("[handleTransfer] %d-> write not all data for expect->%d/%d",
p.SerialNumber, len(p.Data), cnt)
traceMessage := fmt.Sprintf("Write not all data for expect -> %d/%d (sn:%d)", len(p.Data), cnt, p.SerialNumber)
t.recorder.RecordErrorEvent(trace.TransferEvent, traceMessage, nil)
client.closeVirtualConnection(client.session, p.SerialNumber)
func (client *Client) OnUpStreamReadError(t *Transfer, err error) {
t.recorder.RecordErrorEvent(trace.DisconnectEvent, fmt.Sprintf("UpStream read error (sn:%d)", t.serialNumber), err)
client.transferStore.Delete(t.serialNumber)
t.Close()
majoraPacket := protocol.TypeDisconnect.CreatePacket()
majoraPacket.SerialNumber = t.serialNumber
majoraPacket.Extra = client.config.ClientID
if allCnt, sendCnt, err := client.session.WritePkg(majoraPacket, 0); err != nil {
log.Run().Warnf("[closeVirtualConnection] ->%d error %s session closed %v allCnt %d sendCnt %d",
t.serialNumber, err.Error(), client.session, allCnt, sendCnt)
t.recorder.RecordErrorEvent(trace.DisconnectEvent,
fmt.Sprintf("send disconnect to natServer failed closed:%v allCnt %d sendCnt %d (sn:%d)",
client.session.IsClosed(), allCnt, sendCnt, t.serialNumber), err)
return
}
log.Run().Debugf("[handleTransfer] %d-> success dataLen: %d", p.SerialNumber, len(p.Data))
traceMessage := fmt.Sprintf("transfer data success (%d)", p.SerialNumber)
t.recorder.RecordEvent(trace.TransferEvent, traceMessage)
t.recorder.RecordEvent(trace.DisconnectEvent, fmt.Sprintf("Send disconnect to natServer success (sn:%d)", t.serialNumber))
}
func (client *Client) transferToDownstream(t *Transfer, data []byte, err error) {
if err != nil {
opErr, ok := err.(*net.OpError)
if ok && opErr.Err.Error() == "i/o timeout" {
recorderMessage := fmt.Sprintf("Upstream deadDeadline start close (sn:%d)", t.serialNumber)
t.recorder.RecordEvent(trace.UpStreamEvent, recorderMessage)
} else {
log.Run().Debugf("[handleUpStream] %d->read with error:%+v,l:%s->r:%s",
t.serialNumber, err, t.upstreamConn.LocalAddr(), t.upstreamConn.RemoteAddr())
recorderMessage := fmt.Sprintf("Read with l:%s->r:%s (sn:%d) ",
t.upstreamConn.LocalAddr(), t.upstreamConn.RemoteAddr(), t.serialNumber)
t.recorder.RecordErrorEvent(trace.UpStreamEvent, recorderMessage, err)
}
t.client.OnClose(t.client.session, t.upstreamConn, t.serialNumber)
} else {
t.recorder.RecordEvent(trace.UpStreamEvent, fmt.Sprintf("read count: %d (sn:%d)",
len(data), t.serialNumber))
t.recorder.RecordEvent(trace.UpStreamEvent, fmt.Sprintf("Start write to natServer (sn:%d)", t.serialNumber))
pack := protocol.TypeTransfer.CreatePacket()
pack.Data = data
pack.SerialNumber = t.serialNumber
if _, _, err := t.client.session.WritePkg(pack, 0); err != nil {
log.Error().Errorf("[handleUpStream] %d-> write to server fail %+v", t.client, err.Error())
t.recorder.RecordErrorEvent(trace.UpStreamEvent,
fmt.Sprintf("Write to natServer failed (sn:%d)", t.serialNumber), err)
t.client.OnClose(t.client.session, t.upstreamConn, t.serialNumber)
} else {
log.Run().Debugf("[handleUpStream] %d->success dataLen:%d ", t.serialNumber, len(pack.Data))
t.recorder.RecordEvent(trace.UpStreamEvent,
fmt.Sprintf("Write to natServer success(sn:%d)", pack.SerialNumber))
}
func (client *Client) OnDownStreamWriteError(t *Transfer, err error) {
t.recorder.RecordErrorEvent(trace.DisconnectEvent, fmt.Sprintf("DownStrwam error (sn:%d)", t.serialNumber), err)
client.Close()
if !client.session.IsClosed() {
client.session.Close()
}
}
......@@ -31,20 +31,12 @@ func (m *MajoraEventListener) OnOpen(session getty.Session) error {
}
func (m *MajoraEventListener) OnClose(session getty.Session) {
_ = taskPool.Submit(func() {
log.Run().Infof("OnClose-> session closed %v", session.IsClosed())
m.client.CloseAll()
if m.client.close != nil {
m.client.close <- struct{}{}
}
})
m.client.Close()
log.Run().Infof("OnClose-> session closed %v", session.IsClosed())
}
func (m *MajoraEventListener) OnError(session getty.Session, err error) {
_ = taskPool.Submit(func() {
log.Error().Errorf("OnError %s", err.Error())
m.client.CloseAll()
})
log.Error().Errorf("OnError %s", err.Error())
}
func (m *MajoraEventListener) OnCron(session getty.Session) {
......
......@@ -3,6 +3,7 @@ package client
import (
"errors"
"fmt"
"github.com/adamweixuan/getty"
"net"
"sync"
"time"
......@@ -12,87 +13,150 @@ import (
"virjar.com/majora-go/trace"
)
type TransferListener interface {
OnUpStreamConnectSuccess(t *Transfer)
OnUpStreamConnectFailed(t *Transfer, err error)
OnUpStreamWriteError(t *Transfer, err error)
OnUpStreamReadError(t *Transfer, err error)
OnDownStreamWriteError(t *Transfer, err error)
}
type Transfer struct {
serialNumber int64
client *Client
upstreamConn *net.TCPConn
recorder trace.Recorder
transferChan chan *protocol.MajoraPacket
transferToUpstreamFunc func(t *Transfer, p *protocol.MajoraPacket)
transferToDownstreamFunc func(t *Transfer, data []byte, err error)
once sync.Once
cancel chan struct{}
serialNumber int64
target string
upstreamConn *net.TCPConn
session getty.Session
recorder trace.Recorder
transferChan chan []byte
once sync.Once
listener TransferListener
cancel chan struct{}
}
func NewTransfer(serialNumber int64, client *Client, conn *net.TCPConn, recorder trace.Recorder) *Transfer {
func NewTransfer(serialNumber int64, target string, session getty.Session, listener TransferListener, recorder trace.Recorder) *Transfer {
return &Transfer{
serialNumber: serialNumber,
client: client,
upstreamConn: conn,
target: target,
session: session,
recorder: recorder,
transferChan: make(chan *protocol.MajoraPacket, 10),
listener: listener,
transferChan: make(chan []byte, 10),
once: sync.Once{},
cancel: make(chan struct{}, 0),
}
}
func (t *Transfer) SetTransferToUpstreamFunc(f func(t *Transfer, p *protocol.MajoraPacket)) {
t.transferToUpstreamFunc = f
func (t *Transfer) transferToUpstream(data []byte) {
cnt, err := t.upstreamConn.Write(data)
if err != nil {
log.Error().Errorf("[handleTransfer] %d->write to upstream fail for %s", t.serialNumber, err)
traceMessage := fmt.Sprintf("Write to upstream failed (%d)", t.serialNumber)
t.recorder.RecordErrorEvent(trace.TransferEvent, traceMessage, err)
t.listener.OnUpStreamWriteError(t, err)
return
}
if cnt != len(data) {
log.Error().Errorf("[handleTransfer] %d-> write not all data for expect->%d/%d",
t.session, len(data), cnt)
traceMessage := fmt.Sprintf("Write not all data for expect -> %d/%d (sn:%d)", len(data), cnt, t.serialNumber)
t.recorder.RecordErrorEvent(trace.TransferEvent, traceMessage, nil)
t.listener.OnUpStreamWriteError(t, err)
return
}
log.Run().Debugf("[handleTransfer] %d-> success dataLen: %d", t.serialNumber, len(data))
traceMessage := fmt.Sprintf("transfer data success (%d)", t.serialNumber)
t.recorder.RecordEvent(trace.TransferEvent, traceMessage)
}
func (t *Transfer) SetTransferToDownstreamFunc(f func(t *Transfer, data []byte, err error)) {
t.transferToDownstreamFunc = f
func (t *Transfer) transferToDownStream() {
_ = taskPool.Submit(func() {
traceRecorder := t.recorder
traceRecorder.RecordEvent(trace.UpStreamEvent, fmt.Sprintf("Ready read from upstream (sn:%d)", t.serialNumber))
log.Run().Debugf("[handleUpStream] %d-> handleUpStream start...", t.serialNumber)
for {
buf := make([]byte, common.BufSize)
cnt, err := t.upstreamConn.Read(buf)
if t.session.IsClosed() {
t.recorder.RecordErrorEvent(trace.UpStreamEvent, fmt.Sprintf("DownStream closed(sn:%d)", t.serialNumber),
errors.New("closed"))
return
}
if err != nil {
log.Run().Debugf("[handleUpStream] %d->read with error:%+v,l:%s->r:%s",
t.serialNumber, err, t.upstreamConn.LocalAddr(), t.upstreamConn.RemoteAddr())
recorderMessage := fmt.Sprintf("Read with l:%s->r:%s (sn:%d) ",
t.upstreamConn.LocalAddr(), t.upstreamConn.RemoteAddr(), t.serialNumber)
t.recorder.RecordErrorEvent(trace.UpStreamEvent, recorderMessage, err)
t.listener.OnUpStreamReadError(t, err)
break
} else {
t.recorder.RecordEvent(trace.UpStreamEvent, fmt.Sprintf("read count: %d (sn:%d)",
cnt, t.serialNumber))
t.recorder.RecordEvent(trace.UpStreamEvent, fmt.Sprintf("Start write to natServer (sn:%d)", t.serialNumber))
pack := protocol.TypeTransfer.CreatePacket()
pack.Data = buf[0:cnt]
pack.SerialNumber = t.serialNumber
if _, _, err := t.session.WritePkg(pack, 0); err != nil {
log.Error().Errorf("[handleUpStream] %d-> write to server fail %+v", t.serialNumber, err.Error())
t.recorder.RecordErrorEvent(trace.UpStreamEvent,
fmt.Sprintf("Write to natServer failed (sn:%d)", t.serialNumber), err)
t.listener.OnDownStreamWriteError(t, err)
} else {
log.Run().Debugf("[handleUpStream] %d->success dataLen:%d ", t.serialNumber, len(pack.Data))
t.recorder.RecordEvent(trace.UpStreamEvent,
fmt.Sprintf("Write to natServer success(sn:%d)", pack.SerialNumber))
}
}
}
})
}
func (t *Transfer) TransferToUpstream(p *protocol.MajoraPacket) {
t.transferChan <- p
func (t *Transfer) TransferToUpstream(data []byte) {
t.transferChan <- data
}
func (t *Transfer) Start() {
if t.transferToUpstreamFunc == nil {
panic(errors.New("transferToUpstreamFunc is nil"))
}
if t.transferToDownstreamFunc == nil {
panic(errors.New("transferToDownstreamFunc is nil"))
dialer := net.Dialer{
Timeout: common.UpstreamTimeout,
}
conn, err := dialer.Dial(common.TCP, t.target)
if err != nil {
log.Error().Errorf("[handleConnect] %d->connect to %s->%s", t.serialNumber, t.target, err.Error())
t.recorder.RecordErrorEvent(trace.ConnectEvent,
fmt.Sprintf("Connect to %s failed (sn:%d)", t.target, t.serialNumber), err)
t.listener.OnUpStreamConnectFailed(t, err)
return
}
t.upstreamConn = conn.(*net.TCPConn)
_ = t.upstreamConn.SetDeadline(time.Now().Add(45 * time.Second))
_ = t.upstreamConn.SetNoDelay(true)
_ = t.upstreamConn.SetKeepAlive(true)
t.listener.OnUpStreamConnectSuccess(t)
_ = taskPool.Submit(func() {
for {
select {
case p := <-t.transferChan:
t.transferToUpstreamFunc(t, p)
case data := <-t.transferChan:
t.transferToUpstream(data)
case <-t.cancel:
return
}
}
})
_ = taskPool.Submit(func() {
traceRecorder := t.recorder
traceRecorder.RecordEvent(trace.UpStreamEvent, fmt.Sprintf("Ready read from upstream (sn:%d)", t.serialNumber))
log.Run().Debugf("[handleUpStream] %d-> handleUpStream start...", t.serialNumber)
for {
buf := make([]byte, common.BufSize)
cnt, err := t.upstreamConn.Read(buf)
t.transferToDownstreamFunc(t, buf[0:cnt], err)
if err != nil {
break
}
}
})
_ = taskPool.Submit(t.transferToDownStream)
}
func (t *Transfer) Close() {
t.once.Do(func() {
readDeadLine := time.Now().Add(3 * time.Millisecond)
t.recorder.RecordEvent(trace.DisconnectEvent, fmt.Sprintf("Set upstream read deadline:%s (sn:%d)",
readDeadLine.Format("2006-01-02 15:04:05.000000"), t.serialNumber))
err := t.upstreamConn.SetReadDeadline(readDeadLine)
err := t.upstreamConn.Close()
if err != nil {
t.recorder.RecordErrorEvent(trace.DisconnectEvent,
fmt.Sprintf("Set upstream read deadline failed (sn:%d)", t.serialNumber), err)
_ = t.upstreamConn.Close()
}
close(t.cancel)
})
......
tunnel_addr: 127.0.0.1:5879
tunnel_addr: majora-vps.virjar.com:5879
dns_server: 114.114.114.114:53
#daemon: true
log_level: info
log_level: debug
log_path: ./majora-log/
reconn_intervalz: 5s
net_check_interval: 5s
#net_check_interval: 5s
dns_cache_duration: 10m
net_check_url: https://www.baidu.com
......
......@@ -4,15 +4,15 @@ log_level: info
log_path: ./majora-log/
daemon: true
reconn_interval: 5s
net_check_interval: 5s
#net_check_interval: 5s
net_check_url: https://www.baidu.com
dns_cache_duration: 10m
redial:
command: /bin/bash
exec_path: /root/ppp_redial.sh
redial_duration: 5m
wait_time: 15s
#redial:
# command: /bin/bash
# exec_path: /root/ppp_redial.sh
# redial_duration: 5m
# wait_time: 15s
extra:
account: superman
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment