mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 20:23:06 +00:00
add socket.limit for defence
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
#define BACKLOG 32
|
#define BACKLOG 32
|
||||||
// 2 ** 12 == 4096
|
// 2 ** 12 == 4096
|
||||||
#define LARGE_PAGE_NODE 12
|
#define LARGE_PAGE_NODE 12
|
||||||
|
#define BUFFER_LIMIT (256 * 1024)
|
||||||
|
|
||||||
struct buffer_node {
|
struct buffer_node {
|
||||||
char * msg;
|
char * msg;
|
||||||
@@ -22,6 +23,7 @@ struct buffer_node {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct socket_buffer {
|
struct socket_buffer {
|
||||||
|
int limit;
|
||||||
int size;
|
int size;
|
||||||
int offset;
|
int offset;
|
||||||
struct buffer_node *head;
|
struct buffer_node *head;
|
||||||
@@ -64,6 +66,7 @@ lnewpool(lua_State *L, int sz) {
|
|||||||
static int
|
static int
|
||||||
lnewbuffer(lua_State *L) {
|
lnewbuffer(lua_State *L) {
|
||||||
struct socket_buffer * sb = lua_newuserdata(L, sizeof(*sb));
|
struct socket_buffer * sb = lua_newuserdata(L, sizeof(*sb));
|
||||||
|
sb->limit = luaL_optint(L,1,BUFFER_LIMIT);
|
||||||
sb->size = 0;
|
sb->size = 0;
|
||||||
sb->offset = 0;
|
sb->offset = 0;
|
||||||
sb->head = NULL;
|
sb->head = NULL;
|
||||||
@@ -126,6 +129,9 @@ lpushbuffer(lua_State *L) {
|
|||||||
sb->size += sz;
|
sb->size += sz;
|
||||||
|
|
||||||
lua_pushinteger(L, sb->size);
|
lua_pushinteger(L, sb->size);
|
||||||
|
if (sb->limit > 0 && sb->size > sb->limit) {
|
||||||
|
return luaL_error(L, "buffer overflow (limit = %d, size = %d)", sb->limit, sb->size);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ local driver = require "socketdriver"
|
|||||||
local skynet = require "skynet"
|
local skynet = require "skynet"
|
||||||
local assert = assert
|
local assert = assert
|
||||||
|
|
||||||
|
local buffer_limit = -1
|
||||||
local socket = {} -- api
|
local socket = {} -- api
|
||||||
local buffer_pool = {} -- store all message buffer object
|
local buffer_pool = {} -- store all message buffer object
|
||||||
local socket_pool = setmetatable( -- store all socket object
|
local socket_pool = setmetatable( -- store all socket object
|
||||||
@@ -47,7 +48,13 @@ socket_message[1] = function(id, size, data)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local sz = driver.push(s.buffer, buffer_pool, data, size)
|
local ok , sz = pcall(driver.push, s.buffer, buffer_pool, data, size)
|
||||||
|
if not ok then
|
||||||
|
skynet.error("socket: error on ", id , sz)
|
||||||
|
driver.clear(s.buffer,buffer_pool)
|
||||||
|
driver.close(id)
|
||||||
|
return
|
||||||
|
end
|
||||||
local rr = s.read_required
|
local rr = s.read_required
|
||||||
local rrt = type(rr)
|
local rrt = type(rr)
|
||||||
if rrt == "number" then
|
if rrt == "number" then
|
||||||
@@ -123,7 +130,7 @@ skynet.register_protocol {
|
|||||||
local function connect(id, func)
|
local function connect(id, func)
|
||||||
local newbuffer
|
local newbuffer
|
||||||
if func == nil then
|
if func == nil then
|
||||||
newbuffer = driver.buffer()
|
newbuffer = driver.buffer(buffer_limit)
|
||||||
end
|
end
|
||||||
local s = {
|
local s = {
|
||||||
id = id,
|
id = id,
|
||||||
@@ -318,4 +325,8 @@ function socket.abandon(id)
|
|||||||
socket_pool[id] = nil
|
socket_pool[id] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function socket.limit(limit)
|
||||||
|
buffer_limit = limit
|
||||||
|
end
|
||||||
|
|
||||||
return socket
|
return socket
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ if mode == "agent" then
|
|||||||
id = tonumber(id)
|
id = tonumber(id)
|
||||||
|
|
||||||
skynet.start(function()
|
skynet.start(function()
|
||||||
|
-- A small limit, if socket buffer overflow, close the client
|
||||||
|
socket.limit(64)
|
||||||
|
|
||||||
skynet.fork(function()
|
skynet.fork(function()
|
||||||
echo(id)
|
echo(id)
|
||||||
skynet.exit()
|
skynet.exit()
|
||||||
@@ -30,7 +33,7 @@ else
|
|||||||
local function accept(id)
|
local function accept(id)
|
||||||
socket.start(id)
|
socket.start(id)
|
||||||
socket.write(id, "Hello Skynet\n")
|
socket.write(id, "Hello Skynet\n")
|
||||||
skynet.newservice("testsocket", "agent", id)
|
skynet.newservice(SERVICE_NAME, "agent", id)
|
||||||
-- notice: Some data on this connection(id) may lost before new service start.
|
-- notice: Some data on this connection(id) may lost before new service start.
|
||||||
-- So, be careful when you want to use start / abandon / start .
|
-- So, be careful when you want to use start / abandon / start .
|
||||||
socket.abandon(id)
|
socket.abandon(id)
|
||||||
|
|||||||
Reference in New Issue
Block a user