diff --git a/examples/login/logind.lua b/examples/login/logind.lua index afaa3496..dd003f2f 100644 --- a/examples/login/logind.lua +++ b/examples/login/logind.lua @@ -19,7 +19,7 @@ function server.auth_handler(token) user = crypt.base64decode(user) server = crypt.base64decode(server) password = crypt.base64decode(password) - assert(password == "password") + assert(password == "password", "Invalid password") return server, user end diff --git a/lualib/snax/loginserver.lua b/lualib/snax/loginserver.lua index dfaa3ebd..37f335b6 100644 --- a/lualib/snax/loginserver.lua +++ b/lualib/snax/loginserver.lua @@ -49,9 +49,6 @@ end local function launch_slave(auth_handler) local function auth(fd, addr) - skynet.error(string.format("connect from %s (fd = %d)", addr, fd)) - socket.start(fd) - -- set socket buffer limit (8K) -- If the attacker send large package, close the socket socket.limit(fd, 8192) @@ -86,24 +83,32 @@ local function launch_slave(auth_handler) return ok, server, uid, secret end - local function ret_pack(fd, ok, err, ...) - socket.abandon(fd) + local function ret_pack(ok, err, ...) if ok then - skynet.ret(skynet.pack(err, ...)) + return skynet.pack(err, ...) else if err == socket_error then - skynet.ret(skynet.pack(nil, "socket error")) + return skynet.pack(nil, "socket error") else - skynet.ret(skynet.pack(false, err)) + return skynet.pack(false, err) end end end - skynet.dispatch("lua", function(_,_,fd,...) - if type(fd) ~= "number" then - skynet.ret(skynet.pack(false, "invalid fd type")) + local function auth_fd(fd, addr) + skynet.error(string.format("connect from %s (fd = %d)", addr, fd)) + socket.start(fd) -- may raise error here + local msg, len = ret_pack(pcall(auth, fd, addr)) + socket.abandon(fd) -- never raise error here + return msg, len + end + + skynet.dispatch("lua", function(_,_,...) + local ok, msg, len = pcall(auth_fd, ...) + if ok then + return skynet.ret(msg,len) else - ret_pack(fd,pcall(auth, fd, ...)) + return skynet.ret(skynet.pack(false, msg)) end end) end @@ -113,7 +118,7 @@ local user_login = {} local function accept(conf, s, fd, addr) -- call slave auth local ok, server, uid, secret = skynet.call(s, "lua", fd, addr) - socket.start(fd) + -- slave will accept(start) fd, so we can write to fd later if not ok then if ok ~= nil then @@ -173,9 +178,8 @@ local function launch_master(conf) if err ~= socket_error then skynet.error(string.format("invalid client (fd = %d) error = %s", fd, err)) end - socket.start(fd) end - socket.close(fd) + socket.close_fd(fd) -- We haven't call socket.start, so use socket.close_fd rather than socket.close. end) end diff --git a/lualib/socket.lua b/lualib/socket.lua index bc9701ae..b2f2ac15 100644 --- a/lualib/socket.lua +++ b/lualib/socket.lua @@ -227,6 +227,11 @@ function socket.shutdown(id) close_fd(id, driver.shutdown) end +function socket.close_fd(id) + assert(socket_pool[id] == nil,"Use socket.close instead") + driver.close(id) +end + function socket.close(id) local s = socket_pool[id] if s == nil then diff --git a/skynet-src/socket_server.c b/skynet-src/socket_server.c index a3326b05..89ba11f9 100644 --- a/skynet-src/socket_server.c +++ b/skynet-src/socket_server.c @@ -841,10 +841,12 @@ start_socket(struct socket_server *ss, struct request_start *request, struct soc result->data = "start"; return SOCKET_OPEN; } else if (s->type == SOCKET_TYPE_CONNECTED) { + // todo: maybe we should send a message SOCKET_TRANSFER to s->opaque s->opaque = request->opaque; result->data = "transfer"; return SOCKET_OPEN; } + // if s->type == SOCKET_TYPE_HALFCLOSE , SOCKET_CLOSE message will send later return -1; }