diff --git a/README.md b/README.md index d0cf87e..87fcf95 100644 --- a/README.md +++ b/README.md @@ -112,10 +112,10 @@ server端配置(10.0.1.1): # natpass10路复用,读写均为1s超时 [ ID] Interval Transfer Bitrate Retr - [ 5] 0.00-60.00 sec 70.0 MBytes 9.79 Mbits/sec 28 sender - [ 5] 0.00-60.01 sec 58.4 MBytes 8.16 Mbits/sec receiver + [ 5] 0.00-60.00 sec 70.0 MBytes 9.79 Mbits/sec 22 sender + [ 5] 0.00-60.02 sec 57.9 MBytes 8.10 Mbits/sec receiver # frp10路复用stcp,tls [ ID] Interval Transfer Bitrate Retr - [ 5] 0.00-60.00 sec 67.4 MBytes 9.43 Mbits/sec 21 sender - [ 5] 0.00-60.29 sec 58.6 MBytes 8.15 Mbits/sec receiver \ No newline at end of file + [ 5] 0.00-60.00 sec 66.2 MBytes 9.26 Mbits/sec 31 sender + [ 5] 0.00-60.10 sec 57.7 MBytes 8.05 Mbits/sec receiver \ No newline at end of file diff --git a/code/client/main.go b/code/client/main.go index 50950c9..0bfd67b 100644 --- a/code/client/main.go +++ b/code/client/main.go @@ -99,7 +99,8 @@ func main() { linkID = msg.GetXData().GetLid() } if len(linkID) > 0 { - logging.Error("link of %s not found, type=%s", linkID, msg.GetXType().String()) + logging.Error("link of %s on connection %d not found, type=%s", + linkID, conn.Idx, msg.GetXType().String()) continue } } @@ -134,6 +135,7 @@ func connect(pool *pool.Pool, conn *pool.Conn, from, to string, fromIdx, toIdx u RemotePort: uint16(req.GetPort()), }) lk := tunnel.NewLink(tn, req.GetId(), from, link, conn) + lk.SetTargetIdx(fromIdx) conn.SendConnectOK(from, fromIdx, req.GetId()) lk.Forward() lk.OnWork <- struct{}{} diff --git a/code/client/pool/conn.go b/code/client/pool/conn.go index 6184526..cf1c82d 100644 --- a/code/client/pool/conn.go +++ b/code/client/pool/conn.go @@ -114,15 +114,7 @@ func (conn *Conn) loopRead(cancel context.CancelFunc) { if ch == nil { ch = conn.unknownRead } - select { - case ch <- msg: - case <-time.After(conn.parent.cfg.ReadTimeout): - logging.Error("write read channel for link %s timeouted", linkID) - if ch == conn.unknownRead { - continue - } - close(ch) - } + ch <- msg } } diff --git a/code/client/pool/pool.go b/code/client/pool/pool.go index 2334403..bd2f3dd 100644 --- a/code/client/pool/pool.go +++ b/code/client/pool/pool.go @@ -5,6 +5,7 @@ import ( "natpass/code/client/global" "natpass/code/network" "sync" + "sync/atomic" "time" "github.com/lwch/logging" @@ -58,12 +59,12 @@ func (p *Pool) Get(id ...string) *Conn { return conn } - p.idx++ - conn := p.connect(p.idx) + idx := atomic.AddUint32(&p.idx, 1) + conn := p.connect(idx) if conn == nil { return nil } - c := newConn(p, conn, p.idx) + c := newConn(p, conn, idx) p.Lock() p.conns[c.Idx] = c diff --git a/code/client/tunnel/link.go b/code/client/tunnel/link.go index 82305fd..b1467e6 100644 --- a/code/client/tunnel/link.go +++ b/code/client/tunnel/link.go @@ -23,7 +23,8 @@ type Link struct { func NewLink(parent *Tunnel, id, target string, local net.Conn, remote *pool.Conn) *Link { remote.AddLink(id) - logging.Info("create link %s for tunnel %s", id, parent.Name) + logging.Info("create link %s for tunnel %s on connection %d", + id, parent.Name, remote.Idx) return &Link{ parent: parent, id: id, @@ -89,7 +90,7 @@ func (link *Link) localRead() { if !link.closeFromRemote { link.remote.SendDisconnect(link.target, link.targetIdx, link.id) } - // logging.Error("read data on tunnel %s link %s failed, err=%v", link.parent.Name, link.id, err) + logging.Error("read data on tunnel %s link %s failed, err=%v", link.parent.Name, link.id, err) return } if n == 0 { @@ -99,3 +100,7 @@ func (link *Link) localRead() { link.remote.SendData(link.target, link.targetIdx, link.id, buf[:n]) } } + +func (link *Link) SetTargetIdx(idx uint32) { + link.targetIdx = idx +} diff --git a/code/server/handler/client.go b/code/server/handler/client.go index e131d71..5c58c95 100644 --- a/code/server/handler/client.go +++ b/code/server/handler/client.go @@ -86,3 +86,7 @@ func (c *client) closeLink(id string) { delete(c.links, id) c.Unlock() } + +func (c *client) is(id string, idx uint32) bool { + return c.parent.id == id && c.idx == idx +} diff --git a/code/server/handler/clients.go b/code/server/handler/clients.go index 21453c9..9d4601c 100644 --- a/code/server/handler/clients.go +++ b/code/server/handler/clients.go @@ -3,6 +3,7 @@ package handler import ( "natpass/code/network" "sync" + "sync/atomic" "time" "github.com/lwch/logging" @@ -13,7 +14,7 @@ type clients struct { parent *Handler id string data map[uint32]*client // idx => client - idx int + idx uint32 } func newClients(parent *Handler, id string) *clients { @@ -48,8 +49,8 @@ func (cs *clients) next() *client { } cs.RUnlock() if len(list) > 0 { - cli := list[cs.idx%len(list)] - cs.idx++ + idx := atomic.AddUint32(&cs.idx, 1) + cli := list[int(idx)%len(list)] return cli } return nil diff --git a/code/server/handler/handler.go b/code/server/handler/handler.go index 41b7b58..b24e709 100644 --- a/code/server/handler/handler.go +++ b/code/server/handler/handler.go @@ -18,7 +18,6 @@ type Handler struct { clients map[string]*clients // client id => client lockLinks sync.RWMutex links map[string][2]*client // link id => endpoints - idx int } // New create handler @@ -27,7 +26,6 @@ func New(cfg *global.Configure) *Handler { cfg: cfg, clients: make(map[string]*clients), links: make(map[string][2]*client), - idx: 0, } } @@ -101,10 +99,10 @@ func (h *Handler) getClient(linkID, to string, toIdx uint32) *client { pair := h.links[linkID] h.lockLinks.RUnlock() - if pair[0] != nil && pair[0].idx == toIdx { + if pair[0] != nil && pair[0].is(to, toIdx) { return pair[0] } - if pair[1] != nil && pair[1].idx == toIdx { + if pair[1] != nil && pair[1].is(to, toIdx) { return pair[1] } @@ -160,6 +158,21 @@ func (h *Handler) msgHook(msg *network.Msg, from, to *client) { h.lockLinks.Lock() h.links[id] = pair h.lockLinks.Unlock() + logging.Info("link %s name %s request from %s-%d to %s-%d", + id, msg.GetCreq().GetName(), from.parent.id, from.idx, to.parent.id, to.idx) + case network.Msg_connect_rep: + rep := msg.GetCrep() + if rep.GetOk() { + logging.Info("link %s from %s-%d to %s-%d connect successed", + rep.GetId(), from.parent.id, from.idx, to.parent.id, to.idx) + } else { + logging.Info("link %s from %s-%d to %s-%d connect failed, %s", + rep.GetId(), from.parent.id, from.idx, to.parent.id, to.idx, rep.GetMsg()) + } + case network.Msg_forward: + data := msg.GetXData() + logging.Debug("link %s forward %d bytes from %s-%d to %s-%d", + data.GetLid(), len(data.GetData()), from.parent.id, from.idx, to.parent.id, to.idx) case network.Msg_disconnect: id := msg.GetXDisconnect().GetId() if from != nil { @@ -171,6 +184,9 @@ func (h *Handler) msgHook(msg *network.Msg, from, to *client) { h.lockLinks.Lock() delete(h.links, id) h.lockLinks.Unlock() + disconnect := msg.GetXDisconnect() + logging.Info("link %s disconnect from %s-%d to %s-%d", + disconnect.GetId(), from.parent.id, from.idx, to.parent.id, to.idx) } msg.From = from.parent.id msg.FromIdx = from.idx