From e1421e66b973f4dd0e8f1f6058c60e7d02595166 Mon Sep 17 00:00:00 2001 From: Yilun Date: Tue, 21 Jun 2022 04:33:48 -0700 Subject: [PATCH] Add per ip rate limiter Signed-off-by: Yilun --- api/httpjson/RPCserver.go | 12 ++++++++++++ api/ratelimiter/ratelimiter.go | 26 ++++++++++++++++++++++++++ api/websocket/server/server.go | 11 +++++++++++ cmd/nknd/commands/root.go | 2 +- config/config.go | 12 ++++++++++++ go.mod | 2 +- go.sum | 20 ++++++++++++++------ node/localnode.go | 14 ++++++++++++++ web/sw.js | 2 +- 9 files changed, 92 insertions(+), 9 deletions(-) create mode 100644 api/ratelimiter/ratelimiter.go diff --git a/api/httpjson/RPCserver.go b/api/httpjson/RPCserver.go index dd8975058..2f811ca37 100644 --- a/api/httpjson/RPCserver.go +++ b/api/httpjson/RPCserver.go @@ -13,6 +13,7 @@ import ( "github.com/nknorg/nkn/v2/api/common" "github.com/nknorg/nkn/v2/api/common/errcode" + "github.com/nknorg/nkn/v2/api/ratelimiter" "github.com/nknorg/nkn/v2/chain" "github.com/nknorg/nkn/v2/config" "github.com/nknorg/nkn/v2/node" @@ -59,7 +60,18 @@ func NewServer(localNode *node.LocalNode, wallet *vault.Wallet) *RPCServer { // Handle is the funciton that should be called in order to answer an rpc call // should be registered like "http.HandleFunc("/", httpjsonrpc.Handle)" func (s *RPCServer) Handle(w http.ResponseWriter, r *http.Request) { + host, _, err := net.SplitHostPort(r.RemoteAddr) + if err == nil { + limiter := ratelimiter.GetLimiter("rpc:"+host, config.Parameters.RPCIPRateLimit, int(config.Parameters.RPCIPRateBurst)) + if !limiter.Allow() { + log.Infof("RPC connection limit of %s reached", host) + w.WriteHeader(http.StatusTooManyRequests) + return + } + } + if !s.limiter.Allow() { + log.Infof("RPC connection limit reached") w.WriteHeader(http.StatusTooManyRequests) return } diff --git a/api/ratelimiter/ratelimiter.go b/api/ratelimiter/ratelimiter.go new file mode 100644 index 000000000..c3e31c7a8 --- /dev/null +++ b/api/ratelimiter/ratelimiter.go @@ -0,0 +1,26 @@ +package ratelimiter + +import ( + "sync" + "time" + + "github.com/nknorg/nkn/v2/common" + "golang.org/x/time/rate" +) + +var rateLimiters = common.NewGoCache(10*time.Minute, 5*time.Minute) +var lock sync.Mutex + +func GetLimiter(key string, limit float64, burst int) *rate.Limiter { + lock.Lock() + defer lock.Unlock() + + if limiter, ok := rateLimiters.Get([]byte(key)); ok { + return limiter.(*rate.Limiter) + } + + limiter := rate.NewLimiter(rate.Limit(limit), burst) + rateLimiters.Set([]byte(key), limiter) + + return limiter +} diff --git a/api/websocket/server/server.go b/api/websocket/server/server.go index 99c4806f5..401605670 100644 --- a/api/websocket/server/server.go +++ b/api/websocket/server/server.go @@ -19,6 +19,7 @@ import ( "github.com/golang/protobuf/proto" api "github.com/nknorg/nkn/v2/api/common" "github.com/nknorg/nkn/v2/api/common/errcode" + "github.com/nknorg/nkn/v2/api/ratelimiter" "github.com/nknorg/nkn/v2/api/websocket/messagebuffer" "github.com/nknorg/nkn/v2/api/websocket/session" "github.com/nknorg/nkn/v2/chain" @@ -247,6 +248,16 @@ func (ws *WsServer) Stop() { //websocketHandler func (ws *WsServer) websocketHandler(w http.ResponseWriter, r *http.Request) { + host, _, err := net.SplitHostPort(r.RemoteAddr) + if err == nil { + limiter := ratelimiter.GetLimiter("ws:"+host, config.Parameters.WsIPRateLimit, int(config.Parameters.WsIPRateBurst)) + if !limiter.Allow() { + log.Infof("Ws connection limit of %s reached", host) + w.WriteHeader(http.StatusTooManyRequests) + return + } + } + wsConn, err := ws.Upgrader.Upgrade(w, r, nil) if err != nil { log.Error("websocket Upgrader: ", err) diff --git a/cmd/nknd/commands/root.go b/cmd/nknd/commands/root.go index ef7655cbf..adefab426 100644 --- a/cmd/nknd/commands/root.go +++ b/cmd/nknd/commands/root.go @@ -46,7 +46,7 @@ import ( ) const ( - NetVersionNum = 29 // This is temporary and will be removed soon after mainnet is stabilized + NetVersionNum = 30 // This is temporary and will be removed soon after mainnet is stabilized ) // rootCmd represents the base command when called without any subcommands diff --git a/config/config.go b/config/config.go index 04b35cb3f..78270c813 100644 --- a/config/config.go +++ b/config/config.go @@ -310,6 +310,12 @@ var ( RecentStateCount: 16384, RecentBlockCount: 32768, MinPruningCompactHeights: 32768, + NodeIPRateLimit: 1, + NodeIPRateBurst: 10, + WsIPRateLimit: 10, + WsIPRateBurst: 100, + RPCIPRateLimit: 10, + RPCIPRateBurst: 100, RPCRateLimit: 1024, RPCRateBurst: 4096, SyncBlockHeaderRateLimit: 8192, @@ -390,6 +396,12 @@ type Configuration struct { RecentStateCount uint32 `json:"RecentStateCount"` RecentBlockCount uint32 `json:"RecentBlockCount"` MinPruningCompactHeights uint32 `json:"MinPruningCompactHeights"` + NodeIPRateLimit float64 `json:"NodeIPRateLimit"` // requests per second + NodeIPRateBurst uint32 `json:"NodeIPRateBurst"` + WsIPRateLimit float64 `json:"WsIPRateLimit"` // requests per second + WsIPRateBurst uint32 `json:"WsIPRateBurst"` + RPCIPRateLimit float64 `json:"RPCIPRateLimit"` // requests per second + RPCIPRateBurst uint32 `json:"RPCIPRateBurst"` RPCRateLimit float64 `json:"RPCRateLimit"` // requests per second RPCRateBurst uint32 `json:"RPCRateBurst"` SyncBlockHeaderRateLimit float64 `json:"SyncBlockHeaderRateLimit"` // headers per second diff --git a/go.mod b/go.mod index f3ad96a4b..129a61af6 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/itchyny/base58-go v0.0.5 github.com/jpillora/backoff v1.0.0 // indirect github.com/nknorg/consequential v0.0.0-20190823093205-a45aff4a218a - github.com/nknorg/nnet v0.0.0-20220217113219-4d27780990b1 + github.com/nknorg/nnet v0.0.0-20220621093239-b22b80b04216 github.com/nknorg/portmapper v0.0.0-20200114081049-1c03cdccc283 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pbnjay/memory v0.0.0-20190104145345-974d429e7ae4 diff --git a/go.sum b/go.sum index b4c1baae9..ed22fa37f 100644 --- a/go.sum +++ b/go.sum @@ -114,8 +114,9 @@ github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0 h1:xU6/SpYbvkNYiptHJYEDRseDLvYE7wSqhYYNy0QSUzI= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -222,6 +223,7 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kidstuff/mongostore v0.0.0-20181113001930-e650cd85ee4b/go.mod h1:g2nVr8KZVXJSS97Jo8pJ0jgq29P6H7dG0oplUA86MQw= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= @@ -269,8 +271,8 @@ github.com/nknorg/consequential v0.0.0-20190823093205-a45aff4a218a h1:DXTCQnVV2E github.com/nknorg/consequential v0.0.0-20190823093205-a45aff4a218a/go.mod h1:H7XeI/XOPpWVmqM+ScT75RLMn7jWnlZDwHRahSxNxo0= github.com/nknorg/go-nat v1.0.1 h1:4dFK0oDyqkIE0it03Y4pMgBQpl1Y0mrYHEp+j/nZ910= github.com/nknorg/go-nat v1.0.1/go.mod h1:dblX1Ac2j08rTUGs5CKCAfjHGN5eDFhbeqt2rccSP3Y= -github.com/nknorg/nnet v0.0.0-20220217113219-4d27780990b1 h1:X8tbQoV6Yjy+DGtyO9mim6KFwXzsIQVF4q3XGzizaRo= -github.com/nknorg/nnet v0.0.0-20220217113219-4d27780990b1/go.mod h1:4DHEQEMhlRGIKGSyhATdjeusdqaHafDatadtpeHBpvI= +github.com/nknorg/nnet v0.0.0-20220621093239-b22b80b04216 h1:+5lcBTnhfQcVMtsY+CqcuaiJ3ebVYwrmYDnTabh/KBg= +github.com/nknorg/nnet v0.0.0-20220621093239-b22b80b04216/go.mod h1:rB1dMWGEjNncJjcmLVuXDXawGiD1gD/hwSR+vrr8Wp8= github.com/nknorg/portmapper v0.0.0-20200114081049-1c03cdccc283 h1:uS3/DvxCbi0zZau66ggQAgEjyGmql2mj77UQFgumq1I= github.com/nknorg/portmapper v0.0.0-20200114081049-1c03cdccc283/go.mod h1:dL4PQJ4670oTO6LqvkjrBQEkD+iMiOYjlKRBBw55Csg= github.com/nrdcg/auroradns v1.0.1/go.mod h1:y4pc0i9QXYlFCWrhWrUSIETnZgrf4KuwjDIWmmXo3JI= @@ -377,6 +379,8 @@ github.com/xtaci/kcp-go v4.3.1+incompatible h1:JU7DMiCsyj6S+LkR6/+tPQEgdwnihOgYt github.com/xtaci/kcp-go v4.3.1+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE= github.com/xtaci/smux v1.2.11 h1:QI4M2HgkkpsVU3Bfcmyx10qURBEeHfKi7xDhGEORfu0= github.com/xtaci/smux v1.2.11/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40 h1:dizWJqTWjwyD8KGcMOwgrkqu1JIkofYgKkmDeNE7oAs= gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40/go.mod h1:rOnSnoRyxMI3fe/7KIbVcsHRGxe30OONv8dEgo+vCfA= gitlab.com/NebulousLabs/go-upnp v0.0.0-20181011194642-3a71999ed0d3 h1:qXqiXDgeQxspR3reot1pWme00CX1pXbxesdzND+EjbU= @@ -394,7 +398,6 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -432,6 +435,7 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180611182652-db08ff08e862/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -446,7 +450,6 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190502183928-7f726cade0ab/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -462,6 +465,7 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -474,8 +478,9 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180622082034-63fc586f45fe/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -513,6 +518,7 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= @@ -562,6 +568,8 @@ golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/node/localnode.go b/node/localnode.go index 41b29e548..a7f4855a2 100644 --- a/node/localnode.go +++ b/node/localnode.go @@ -5,12 +5,14 @@ import ( "encoding/json" "errors" "fmt" + "net" "net/url" "sync" "sync/atomic" "time" "github.com/golang/protobuf/proto" + "github.com/nknorg/nkn/v2/api/ratelimiter" "github.com/nknorg/nkn/v2/chain" "github.com/nknorg/nkn/v2/chain/pool" "github.com/nknorg/nkn/v2/config" @@ -110,6 +112,18 @@ func NewLocalNode(wallet *vault.Wallet, nn *nnet.NNet) (*LocalNode, error) { event.Queue.Subscribe(event.BlockPersistCompleted, localNode.cleanupTransactions) event.Queue.Subscribe(event.NewBlockProduced, localNode.CheckIDChange) + nn.MustApplyMiddleware(nnetnode.ConnectionAccepted{func(conn net.Conn) (bool, bool) { + host, _, err := net.SplitHostPort(conn.RemoteAddr().String()) + if err == nil { + limiter := ratelimiter.GetLimiter("node:"+host, config.Parameters.NodeIPRateLimit, int(config.Parameters.NodeIPRateBurst)) + if !limiter.Allow() { + log.Infof("Node connection limit of %s reached", host) + return false, false + } + } + return true, true + }, 0}) + nn.MustApplyMiddleware(nnetnode.WillConnectToNode{func(n *nnetpb.Node) (bool, bool) { err := localNode.shouldConnectToNode(n) if err != nil { diff --git a/web/sw.js b/web/sw.js index 292f64537..952d8ee14 100644 --- a/web/sw.js +++ b/web/sw.js @@ -1,4 +1,4 @@ -const options = {"workboxURL":"https://cdn.jsdelivr.net/npm/workbox-cdn@5.1.4/workbox/workbox-sw.js","importScripts":[],"config":{"debug":false},"cacheOptions":{"cacheId":"nkn-web-prod","directoryIndex":"/","revision":"UV6mhORUDSwq"},"clientsClaim":true,"skipWaiting":true,"cleanupOutdatedCaches":true,"offlineAnalytics":false,"preCaching":[{"revision":"UV6mhORUDSwq","url":"/web/?standalone=true"}],"runtimeCaching":[{"urlPattern":"/web/_nuxt/","handler":"CacheFirst","method":"GET","strategyPlugins":[]},{"urlPattern":"/web/","handler":"NetworkFirst","method":"GET","strategyPlugins":[]}],"offlinePage":null,"pagesURLPattern":"/web/","offlineStrategy":"NetworkFirst"} +const options = {"workboxURL":"https://cdn.jsdelivr.net/npm/workbox-cdn@5.1.4/workbox/workbox-sw.js","importScripts":[],"config":{"debug":false},"cacheOptions":{"cacheId":"nkn-web-prod","directoryIndex":"/","revision":"b5AwicZw3mBc"},"clientsClaim":true,"skipWaiting":true,"cleanupOutdatedCaches":true,"offlineAnalytics":false,"preCaching":[{"revision":"b5AwicZw3mBc","url":"/web/?standalone=true"}],"runtimeCaching":[{"urlPattern":"/web/_nuxt/","handler":"CacheFirst","method":"GET","strategyPlugins":[]},{"urlPattern":"/web/","handler":"NetworkFirst","method":"GET","strategyPlugins":[]}],"offlinePage":null,"pagesURLPattern":"/web/","offlineStrategy":"NetworkFirst"} importScripts(...[options.workboxURL, ...options.importScripts])