Skip to content

Commit

Permalink
fix data race casused by lock misuse
Browse files Browse the repository at this point in the history
  • Loading branch information
longxboy committed Apr 28, 2017
1 parent aa0a146 commit d646777
Show file tree
Hide file tree
Showing 10 changed files with 441 additions and 18 deletions.
8 changes: 7 additions & 1 deletion Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions cmd/lunnelSer/config-full-example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ health:
#心跳超时时间,单位秒
timeout: 40
#每个客户端的最大物理空闲连接数,不填写的话则默认为4
max_idle_pipes: 5
max_idle_pipes: 4
#单个物理连接所能承载的最大并发请求数,不填写的话则默认为6
max_streams: 6
max_streams: 6
#是否开启go profiling
pprof_enable: false
30 changes: 17 additions & 13 deletions server/manage.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,18 @@ import (
"net/http"
"sync/atomic"

"github.com/e-dard/netbug"
"github.com/longXboy/lunnel/log"
"github.com/longXboy/lunnel/msg"
"github.com/satori/go.uuid"
"gopkg.in/gin-gonic/gin.v1"
)

type tunnelsStateReq struct {
type tunnelStateReq struct {
PublicUrl string
}

type tunnelsStateResp struct {
type tunnelStateResp struct {
Tunnels []string
}

Expand All @@ -48,7 +49,7 @@ type tunnelState struct {
IsClosed bool
}

type clientsStateResp struct {
type clientStateResp struct {
Clients []clientState
}

Expand All @@ -59,30 +60,33 @@ func listenAndServeManage() {
gin.SetMode("release")
}
r := gin.New()

r.GET("/v1/tunnels", tunnelsQuery)
r.POST("/v1/tunnel", tunnelQuery)

r.POST("/v1/tunnels", tunnelQuery)
r.GET("/v1/clients", clientsQuery)
r.GET("/v1/clients/clientId", clientQuery)

log.WithFields(log.Fields{"addr": fmt.Sprintf("%s:%d", serverConf.ListenIP, serverConf.ManagePort)}).Infoln("start to listen and serve manage")
mux := http.NewServeMux()
if serverConf.PProfEnable {
netbug.RegisterHandler("/pprof/", mux)
}
mux.Handle("/v1/", r)

err := r.Run(fmt.Sprintf("%s:%d", serverConf.ListenIP, serverConf.ManagePort))
log.WithFields(log.Fields{"addr": fmt.Sprintf("%s:%d", serverConf.ListenIP, serverConf.ManagePort)}).Infoln("start to listen and serve manage")
err := http.ListenAndServe(fmt.Sprintf("%s:%d", serverConf.ListenIP, serverConf.ManagePort), mux)
if err != nil {
log.WithFields(log.Fields{"addr": fmt.Sprintf("%s:%d", serverConf.ListenIP, serverConf.ManagePort), "err": err.Error()}).Infoln("listen and serve manage failed!")
}
}

func tunnelQuery(c *gin.Context) {
var query tunnelsStateReq
var query tunnelStateReq
err := c.BindJSON(&query)
if err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("unmarshal req body failed!"))
return
}

var tunnelStats tunnelsStateResp = tunnelsStateResp{Tunnels: []string{}}
var tunnelStats tunnelStateResp = tunnelStateResp{Tunnels: []string{}}
if query.PublicUrl != "" {
TunnelMapLock.RLock()
tunnel, isok := TunnelMap[query.PublicUrl]
Expand All @@ -96,7 +100,7 @@ func tunnelQuery(c *gin.Context) {
}

func tunnelsQuery(c *gin.Context) {
var tunnelStats tunnelsStateResp = tunnelsStateResp{Tunnels: []string{}}
var tunnelStats tunnelStateResp = tunnelStateResp{Tunnels: []string{}}

TunnelMapLock.RLock()
for _, v := range TunnelMap {
Expand All @@ -114,7 +118,7 @@ func clientQuery(c *gin.Context) {
c.String(http.StatusBadRequest, fmt.Sprintf("invalid uuid"))
return
}
var clientStates clientsStateResp = clientsStateResp{Clients: []clientState{}}
var clientStates clientStateResp = clientStateResp{Clients: []clientState{}}
ControlMapLock.RLock()
ctlClient := ControlMap[uuid]
ControlMapLock.RUnlock()
Expand All @@ -136,7 +140,7 @@ func clientQuery(c *gin.Context) {
}

func clientsQuery(c *gin.Context) {
var clientStates clientsStateResp = clientsStateResp{Clients: []clientState{}}
var clientStates clientStateResp = clientStateResp{Clients: []clientState{}}
clients := make([]*Control, 0)
ControlMapLock.RLock()
for _, v := range ControlMap {
Expand Down
1 change: 1 addition & 0 deletions server/serConfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ type Config struct {
Health Health `yaml:"health,omitempty"`
MaxIdlePipes string `yaml:"max_idle_pipes,omitempty"`
MaxStreams string `yaml:"max_streams,omitempty"`
PProfEnable bool `yaml:"pprof_enable,omitempty"`
}

var serverConf Config
Expand Down
4 changes: 2 additions & 2 deletions server/serControl.go
Original file line number Diff line number Diff line change
Expand Up @@ -650,10 +650,10 @@ func (c *Control) ServerHandShake() error {
return errors.Wrap(err, "Write ClientId")
}

ControlMapLock.RLock()
ControlMapLock.Lock()
old, isok := ControlMap[c.ClientID]
ControlMap[c.ClientID] = c
ControlMapLock.RUnlock()
ControlMapLock.Unlock()
if isok {
oldTunnels := old.closeTunnels()
for _, oldTunnel := range oldTunnels {
Expand Down
24 changes: 24 additions & 0 deletions vendor/github.com/e-dard/netbug/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions vendor/github.com/e-dard/netbug/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

109 changes: 109 additions & 0 deletions vendor/github.com/e-dard/netbug/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit d646777

Please sign in to comment.