Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
majora-go
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
majora
majora-go
Commits
942eb493
Commit
942eb493
authored
Mar 20, 2022
by
Tsaiilin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update
parent
25464140
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
210 additions
and
242 deletions
+210
-242
client.go
client/client.go
+9
-1
cluster.go
client/cluster.go
+15
-21
event.go
client/event.go
+66
-156
eventlistener.go
client/eventlistener.go
+3
-11
transfer.go
client/transfer.go
+108
-44
majora-dev.yaml
conf/majora-dev.yaml
+3
-3
majora.yaml
conf/majora.yaml
+6
-6
No files found.
client/client.go
View file @
942eb493
...
...
@@ -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
{}
}
client/cluster.go
View file @
942eb493
...
...
@@ -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
})
...
...
client/event.go
View file @
942eb493
...
...
@@ -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
()
}
}
client/eventlistener.go
View file @
942eb493
...
...
@@ -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
)
{
...
...
client/transfer.go
View file @
942eb493
...
...
@@ -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
transfer
ToUpstreamFunc
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
transfer
Chan
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
:
clien
t
,
upstreamConn
:
con
n
,
target
:
targe
t
,
session
:
sessio
n
,
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
.
transferToUpstream
Func
(
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
)
})
...
...
conf/majora-dev.yaml
View file @
942eb493
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
...
...
conf/majora.yaml
View file @
942eb493
...
...
@@ -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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment