Browse Source

connection pool: ssh can't work when pool_count is set, fix #193

pull/200/head
fatedier 8 years ago
parent
commit
9faf4acd62
  1. 1
      src/models/server/server.go
  2. 83
      src/utils/conn/conn.go
  3. 4
      src/utils/vhost/vhost.go

1
src/models/server/server.go

@ -384,6 +384,7 @@ func (p *ProxyServer) getWorkConn() (workConn *conn.Conn, err error) {
err = fmt.Errorf("ProxyName [%s], no work connections available, control is closing", p.Name) err = fmt.Errorf("ProxyName [%s], no work connections available, control is closing", p.Name)
return return
} }
log.Debug("ProxyName [%s], get work connection from pool", p.Name)
default: default:
// no work connections available in the poll, send message to frpc to get more // no work connections available in the poll, send message to frpc to get more
p.ctlMsgChan <- 1 p.ctlMsgChan <- 1

83
src/utils/conn/conn.go

@ -16,6 +16,7 @@ package conn
import ( import (
"bufio" "bufio"
"bytes"
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"io" "io"
@ -25,6 +26,8 @@ import (
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/fatedier/frp/src/utils/pool"
) )
type Listener struct { type Listener struct {
@ -61,11 +64,7 @@ func Listen(bindAddr string, bindPort int64) (l *Listener, err error) {
continue continue
} }
c := &Conn{ c := NewConn(conn)
TcpConn: conn,
closeFlag: false,
}
c.Reader = bufio.NewReader(c.TcpConn)
l.accept <- c l.accept <- c
} }
}() }()
@ -95,20 +94,23 @@ func (l *Listener) Close() error {
type Conn struct { type Conn struct {
TcpConn net.Conn TcpConn net.Conn
Reader *bufio.Reader Reader *bufio.Reader
buffer *bytes.Buffer
closeFlag bool closeFlag bool
mutex sync.RWMutex
mutex sync.RWMutex
} }
func NewConn(conn net.Conn) (c *Conn) { func NewConn(conn net.Conn) (c *Conn) {
c = &Conn{} c = &Conn{
c.TcpConn = conn TcpConn: conn,
buffer: nil,
closeFlag: false,
}
c.Reader = bufio.NewReader(c.TcpConn) c.Reader = bufio.NewReader(c.TcpConn)
c.closeFlag = false return
return c
} }
func ConnectServer(addr string) (c *Conn, err error) { func ConnectServer(addr string) (c *Conn, err error) {
c = &Conn{}
servertAddr, err := net.ResolveTCPAddr("tcp", addr) servertAddr, err := net.ResolveTCPAddr("tcp", addr)
if err != nil { if err != nil {
return return
@ -117,9 +119,7 @@ func ConnectServer(addr string) (c *Conn, err error) {
if err != nil { if err != nil {
return return
} }
c.TcpConn = conn c = NewConn(conn)
c.Reader = bufio.NewReader(c.TcpConn)
c.closeFlag = false
return c, nil return c, nil
} }
@ -185,7 +185,23 @@ func (c *Conn) GetLocalAddr() (addr string) {
} }
func (c *Conn) Read(p []byte) (n int, err error) { func (c *Conn) Read(p []byte) (n int, err error) {
n, err = c.Reader.Read(p) c.mutex.RLock()
if c.buffer == nil {
c.mutex.RUnlock()
return c.Reader.Read(p)
}
c.mutex.RUnlock()
n, err = c.buffer.Read(p)
if err == io.EOF {
c.mutex.Lock()
c.buffer = nil
c.mutex.Unlock()
var n2 int
n2, err = c.Reader.Read(p[n:])
n += n2
}
return return
} }
@ -212,6 +228,16 @@ func (c *Conn) WriteString(content string) (err error) {
return err return err
} }
func (c *Conn) AppendReaderBuffer(content []byte) {
c.mutex.Lock()
defer c.mutex.Unlock()
if c.buffer == nil {
c.buffer = bytes.NewBuffer(make([]byte, 0, 2048))
}
c.buffer.Write(content)
}
func (c *Conn) SetDeadline(t time.Time) error { func (c *Conn) SetDeadline(t time.Time) error {
return c.TcpConn.SetDeadline(t) return c.TcpConn.SetDeadline(t)
} }
@ -238,22 +264,36 @@ func (c *Conn) IsClosed() (closeFlag bool) {
} }
// when you call this function, you should make sure that // when you call this function, you should make sure that
// remote client won't send any bytes to this socket // no bytes were read before
func (c *Conn) CheckClosed() bool { func (c *Conn) CheckClosed() bool {
c.mutex.RLock() c.mutex.RLock()
if c.closeFlag { if c.closeFlag {
c.mutex.RUnlock()
return true return true
} }
c.mutex.RUnlock() c.mutex.RUnlock()
tmp := pool.GetBuf(2048)
defer pool.PutBuf(tmp)
err := c.TcpConn.SetReadDeadline(time.Now().Add(time.Millisecond)) err := c.TcpConn.SetReadDeadline(time.Now().Add(time.Millisecond))
if err != nil { if err != nil {
c.Close() c.Close()
return true return true
} }
var tmp []byte = make([]byte, 1) n, err := c.TcpConn.Read(tmp)
_, err = c.TcpConn.Read(tmp) if err == io.EOF {
return true
}
var tmp2 []byte = make([]byte, 1)
err = c.TcpConn.SetReadDeadline(time.Now().Add(time.Millisecond))
if err != nil {
c.Close()
return true
}
n2, err := c.TcpConn.Read(tmp2)
if err == io.EOF { if err == io.EOF {
return true return true
} }
@ -263,5 +303,12 @@ func (c *Conn) CheckClosed() bool {
c.Close() c.Close()
return true return true
} }
if n > 0 {
c.AppendReaderBuffer(tmp[:n])
}
if n2 > 0 {
c.AppendReaderBuffer(tmp2[:n2])
}
return false return false
} }

4
src/utils/vhost/vhost.go

@ -205,16 +205,18 @@ func (sc *sharedConn) Read(p []byte) (n int, err error) {
sc.Unlock() sc.Unlock()
return sc.Conn.Read(p) return sc.Conn.Read(p)
} }
sc.Unlock()
n, err = sc.buff.Read(p) n, err = sc.buff.Read(p)
if err == io.EOF { if err == io.EOF {
sc.Lock()
sc.buff = nil sc.buff = nil
sc.Unlock()
var n2 int var n2 int
n2, err = sc.Conn.Read(p[n:]) n2, err = sc.Conn.Read(p[n:])
n += n2 n += n2
} }
sc.Unlock()
return return
} }

Loading…
Cancel
Save