Skip to content

Commit

Permalink
Merge pull request fatedier#217 from fatedier/dev
Browse files Browse the repository at this point in the history
bump version to 0.9.2
  • Loading branch information
fatedier authored Jan 8, 2017
2 parents 044bb69 + 0c10279 commit edb97ab
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 29 deletions.
22 changes: 15 additions & 7 deletions Makefile.cross-compiles
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,23 @@ export GO15VENDOREXPERIMENT := 1

all: build

build: gox app more

gox:
go get github.com/mitchellh/gox
build: app

app:
gox -osarch "darwin/386 darwin/amd64 linux/386 linux/amd64 linux/arm windows/386 windows/amd64" ./src/...

more:
env GOOS=darwin GOARCH=386 go build -o ./frpc_darwin_386 ./src/cmd/frpc
env GOOS=darwin GOARCH=386 go build -o ./frps_darwin_386 ./src/cmd/frps
env GOOS=darwin GOARCH=amd64 go build -o ./frpc_darwin_amd64 ./src/cmd/frpc
env GOOS=darwin GOARCH=amd64 go build -o ./frps_darwin_amd64 ./src/cmd/frps
env GOOS=linux GOARCH=386 go build -o ./frpc_linux_386 ./src/cmd/frpc
env GOOS=linux GOARCH=386 go build -o ./frps_linux_386 ./src/cmd/frps
env GOOS=linux GOARCH=amd64 go build -o ./frpc_linux_amd64 ./src/cmd/frpc
env GOOS=linux GOARCH=amd64 go build -o ./frps_linux_amd64 ./src/cmd/frps
env GOOS=linux GOARCH=arm go build -o ./frpc_linux_arm ./src/cmd/frpc
env GOOS=linux GOARCH=arm go build -o ./frps_linux_arm ./src/cmd/frps
env GOOS=windows GOARCH=386 go build -o ./frpc_windows_386.exe ./src/cmd/frpc
env GOOS=windows GOARCH=386 go build -o ./frps_windows_386.exe ./src/cmd/frps
env GOOS=windows GOARCH=amd64 go build -o ./frpc_windows_amd64.exe ./src/cmd/frpc
env GOOS=windows GOARCH=amd64 go build -o ./frps_windows_amd64.exe ./src/cmd/frps
env GOOS=linux GOARCH=mips64 go build -o ./frpc_linux_mips64 ./src/cmd/frpc
env GOOS=linux GOARCH=mips64 go build -o ./frps_linux_mips64 ./src/cmd/frps
env GOOS=linux GOARCH=mips64le go build -o ./frpc_linux_mips64le ./src/cmd/frpc
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ Then visit `http://[server_addr]:7500` to see dashboard, default username and pa

Client that want's to register must set a global `auth_token` equals to frps.ini.

Note that time duration bewtween frpc and frps mustn't exceed 15 minutes because timestamp is used for authentication.
Note that time duration between frpc and frps mustn't exceed 15 minutes because timestamp is used for authentication.

Howerver, this timeout duration can be modified by setting `authentication_timeout` in frps's configure file. It's defalut value is 900, means 15 minutes. If it is equals 0, then frps will not check authentication timeout.

Expand Down Expand Up @@ -452,7 +452,6 @@ http_proxy = http://user:[email protected]:8080

## Development Plan

* Url router.
* Log http request information in frps.
* Direct reverse proxy, like haproxy.
* Load balance to different service in frpc.
Expand Down Expand Up @@ -497,3 +496,4 @@ Donate money by [paypal](https://www.paypal.me/fatedier) to my account **fatedie
* [Damon Zhao](https://github.com/se77en)
* [Manfred Touron](https://github.com/moul)
* [xuebing1110](https://github.com/xuebing1110)
* [Anbitioner](https://github.com/bingtianbaihua)
2 changes: 1 addition & 1 deletion README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,6 @@ http_proxy = http://user:[email protected]:8080

计划在后续版本中加入的功能与优化,排名不分先后,如果有其他功能建议欢迎在 [issues](https://github.com/fatedier/frp/issues) 中反馈。

* 支持 url 路由转发。
* frps 记录 http 请求日志。
* frps 支持直接反向代理,类似 haproxy。
* frpc 支持负载均衡到后端不同服务。
Expand Down Expand Up @@ -516,3 +515,4 @@ frp 交流群:606194980 (QQ 群号)
* [Damon Zhao](https://github.com/se77en)
* [Manfred Touron](https://github.com/moul)
* [xuebing1110](https://github.com/xuebing1110)
* [Anbitioner](https://github.com/bingtianbaihua)
4 changes: 4 additions & 0 deletions conf/frpc.ini
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ auth_token = 123
# for privilege mode
privilege_token = 12345678

# heartbeat configure, it's not recommended to modify the default value
# the default value of heartbeat_interval is 10 and heartbeat_timeout is 30
# heartbeat_interval = 10
# heartbeat_timeout = 30

# ssh is the proxy name same as server's configuration
[ssh]
Expand Down
4 changes: 4 additions & 0 deletions conf/frps.ini
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ log_max_days = 3
privilege_mode = true
privilege_token = 12345678

# heartbeat configure, it's not recommended to modify the default value
# the default value of heartbeat_timeout is 30
# heartbeat_timeout = 30

# only allow frpc to bind ports you list, if you set nothing, there won't be any limit
privilege_allow_ports = 2000-3000,3001,3003,4000-50000

Expand Down
18 changes: 15 additions & 3 deletions src/cmd/frpc/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,24 @@ func msgReader(cli *client.ProxyClient, c *conn.Conn, msgSendChan chan interface
var heartbeatTimeout bool = false
timer := time.AfterFunc(time.Duration(client.HeartBeatTimeout)*time.Second, func() {
heartbeatTimeout = true
c.Close()
if c != nil {
c.Close()
}
if cli != nil {
// if it's not udp type, nothing will happen
cli.CloseUdpTunnel()
cli.SetCloseFlag(true)
}
log.Error("ProxyName [%s], heartbeatRes from frps timeout", cli.Name)
})
defer timer.Stop()

for {
buf, err := c.ReadLine()
if err == io.EOF || c == nil || c.IsClosed() {
if err == io.EOF || c.IsClosed() {
timer.Stop()
c.Close()
cli.SetCloseFlag(true)
log.Warn("ProxyName [%s], frps close this control conn!", cli.Name)
var delayTime time.Duration = 1

Expand All @@ -76,11 +85,14 @@ func msgReader(cli *client.ProxyClient, c *conn.Conn, msgSendChan chan interface
msgSendChan = make(chan interface{}, 1024)
go heartbeatSender(c, msgSendChan)
go msgSender(cli, c, msgSendChan)
cli.SetCloseFlag(false)
break
}

if delayTime < 60 {
if delayTime < 30 {
delayTime = delayTime * 2
} else {
delayTime = 30
}
time.Sleep(delayTime * time.Second)
}
Expand Down
4 changes: 3 additions & 1 deletion src/cmd/frps/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ func controlWorker(c *conn.Conn) {
return
}
} else {
closeFlag = false
if ret == 0 {
closeFlag = false
}
return
}

Expand Down
30 changes: 28 additions & 2 deletions src/models/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ type ProxyClient struct {

udpTunnel *conn.Conn
once sync.Once
closeFlag bool

mutex sync.RWMutex
}

// if proxy type is udp, keep a tcp connection for transferring udp packages
Expand All @@ -48,7 +51,7 @@ func (pc *ProxyClient) StartUdpTunnelOnce(addr string, port int64) {
var c *conn.Conn
udpProcessor := NewUdpProcesser(nil, pc.LocalIp, pc.LocalPort)
for {
if pc.udpTunnel == nil || pc.udpTunnel.IsClosed() {
if !pc.IsClosed() && (pc.udpTunnel == nil || pc.udpTunnel.IsClosed()) {
if HttpProxy == "" {
c, err = conn.ConnectServer(fmt.Sprintf("%s:%d", addr, port))
} else {
Expand All @@ -59,7 +62,7 @@ func (pc *ProxyClient) StartUdpTunnelOnce(addr string, port int64) {
time.Sleep(10 * time.Second)
continue
}
log.Info("ProxyName [%s], udp tunnel reconnect to server [%s:%d] success", pc.Name, addr, port)
log.Info("ProxyName [%s], udp tunnel connect to server [%s:%d] success", pc.Name, addr, port)

nowTime := time.Now().Unix()
req := &msg.ControlReq{
Expand All @@ -82,15 +85,26 @@ func (pc *ProxyClient) StartUdpTunnelOnce(addr string, port int64) {
time.Sleep(1 * time.Second)
continue
}
pc.mutex.Lock()
pc.udpTunnel = c
udpProcessor.UpdateTcpConn(pc.udpTunnel)
pc.mutex.Unlock()

udpProcessor.Run()
}
time.Sleep(1 * time.Second)
}
})
}

func (pc *ProxyClient) CloseUdpTunnel() {
pc.mutex.RLock()
defer pc.mutex.RUnlock()
if pc.udpTunnel != nil {
pc.udpTunnel.Close()
}
}

func (pc *ProxyClient) GetLocalConn() (c *conn.Conn, err error) {
c, err = conn.ConnectServer(fmt.Sprintf("%s:%d", pc.LocalIp, pc.LocalPort))
if err != nil {
Expand Down Expand Up @@ -158,3 +172,15 @@ func (pc *ProxyClient) StartTunnel(serverAddr string, serverPort int64) (err err

return nil
}

func (pc *ProxyClient) SetCloseFlag(closeFlag bool) {
pc.mutex.Lock()
defer pc.mutex.Unlock()
pc.closeFlag = closeFlag
}

func (pc *ProxyClient) IsClosed() bool {
pc.mutex.RLock()
defer pc.mutex.RUnlock()
return pc.closeFlag
}
32 changes: 30 additions & 2 deletions src/models/client/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ var (
LogLevel string = "info"
LogMaxDays int64 = 3
PrivilegeToken string = ""
HeartBeatInterval int64 = 20
HeartBeatTimeout int64 = 90
HeartBeatInterval int64 = 10
HeartBeatTimeout int64 = 30
)

var ProxyClients map[string]*ProxyClient = make(map[string]*ProxyClient)
Expand Down Expand Up @@ -98,6 +98,34 @@ func LoadConf(confFile string) (err error) {
authToken = tmpStr
}

tmpStr, ok = conf.Get("common", "heartbeat_timeout")
if ok {
v, err := strconv.ParseInt(tmpStr, 10, 64)
if err != nil {
return fmt.Errorf("Parse conf error: heartbeat_timeout is incorrect")
} else {
HeartBeatTimeout = v
}
}

tmpStr, ok = conf.Get("common", "heartbeat_interval")
if ok {
v, err := strconv.ParseInt(tmpStr, 10, 64)
if err != nil {
return fmt.Errorf("Parse conf error: heartbeat_interval is incorrect")
} else {
HeartBeatInterval = v
}
}

if HeartBeatInterval <= 0 {
return fmt.Errorf("Parse conf error: heartbeat_interval is incorrect")
}

if HeartBeatTimeout < HeartBeatInterval {
return fmt.Errorf("Parse conf error: heartbeat_timeout is incorrect, heartbeat_timeout is less than heartbeat_interval")
}

// proxies
for name, section := range conf {
if name != "common" {
Expand Down
15 changes: 13 additions & 2 deletions src/models/server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ var (
// if PrivilegeAllowPorts is not nil, tcp proxies which remote port exist in this map can be connected
PrivilegeAllowPorts map[int64]struct{}
MaxPoolCount int64 = 100
HeartBeatTimeout int64 = 90
HeartBeatTimeout int64 = 30
UserConnTimeout int64 = 10

VhostHttpMuxer *vhost.HttpMuxer
Expand Down Expand Up @@ -237,6 +237,16 @@ func loadCommonConf(confFile string) error {
if ok {
SubDomainHost = strings.ToLower(strings.TrimSpace(SubDomainHost))
}

tmpStr, ok = conf.Get("common", "heartbeat_timeout")
if ok {
v, err := strconv.ParseInt(tmpStr, 10, 64)
if err != nil {
return fmt.Errorf("Parse conf error: heartbeat_timeout is incorrect")
} else {
HeartBeatTimeout = v
}
}
return nil
}

Expand Down Expand Up @@ -395,15 +405,16 @@ func CreateProxy(s *ProxyServer) error {
if oldServer.Status == consts.Working {
return fmt.Errorf("this proxy is already working now")
}
oldServer.Lock()
oldServer.Release()
oldServer.Unlock()
if oldServer.PrivilegeMode {
delete(ProxyServers, s.Name)
}
}
ProxyServers[s.Name] = s
metric.SetProxyInfo(s.Name, s.Type, s.BindAddr, s.UseEncryption, s.UseGzip,
s.PrivilegeMode, s.CustomDomains, s.Locations, s.ListenPort)
s.Init()
return nil
}

Expand Down
31 changes: 23 additions & 8 deletions src/models/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ func NewProxyServerFromCtlMsg(req *msg.ControlReq) (p *ProxyServer) {
p.HostHeaderRewrite = req.HostHeaderRewrite
p.HttpUserName = req.HttpUserName
p.HttpPassWord = req.HttpPassWord

p.Init()
return
}

Expand Down Expand Up @@ -276,31 +278,44 @@ func (p *ProxyServer) Start(c *conn.Conn) (err error) {
}

func (p *ProxyServer) Close() {
p.Lock()
defer p.Unlock()

oldStatus := p.Status
p.Release()

// if the proxy created by PrivilegeMode, delete it when closed
if p.PrivilegeMode {
if p.PrivilegeMode && oldStatus != consts.Closed {
// NOTE: this will take the global ProxyServerMap's lock
// if we only want to release resources, use Release() instead
DeleteProxy(p.Name)
}
}

func (p *ProxyServer) Release() {
p.Lock()
defer p.Unlock()

if p.Status != consts.Closed {
p.Status = consts.Closed
for _, l := range p.listeners {
if l != nil {
l.Close()
}
}
close(p.ctlMsgChan)
close(p.workConnChan)
close(p.udpSenderChan)
close(p.closeChan)
if p.ctlMsgChan != nil {
close(p.ctlMsgChan)
p.ctlMsgChan = nil
}
if p.workConnChan != nil {
close(p.workConnChan)
p.workConnChan = nil
}
if p.udpSenderChan != nil {
close(p.udpSenderChan)
p.udpSenderChan = nil
}
if p.closeChan != nil {
close(p.closeChan)
p.closeChan = nil
}
if p.CtlConn != nil {
p.CtlConn.Close()
}
Expand Down
2 changes: 1 addition & 1 deletion src/utils/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
"strings"
)

var version string = "0.9.1"
var version string = "0.9.2"

func Full() string {
return version
Expand Down

0 comments on commit edb97ab

Please sign in to comment.