mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 20:23:06 +00:00
Compare commits
71 Commits
v1.0.0-alp
...
v1.0.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8214c53891 | ||
|
|
5e642b15a4 | ||
|
|
ac093c7142 | ||
|
|
01dcc45827 | ||
|
|
d3ac522dc6 | ||
|
|
55d0d57d5c | ||
|
|
1fec2e6063 | ||
|
|
cc4756de35 | ||
|
|
7fb109dbb0 | ||
|
|
7f578be649 | ||
|
|
69946d75c5 | ||
|
|
24f6994b50 | ||
|
|
07dbfd8651 | ||
|
|
ca50a5f518 | ||
|
|
b8c54cbac2 | ||
|
|
3a2c43e9e0 | ||
|
|
205824ab12 | ||
|
|
4ac047b274 | ||
|
|
987a90af8b | ||
|
|
250531c9a7 | ||
|
|
7b471ae27d | ||
|
|
4f93054f3a | ||
|
|
65fad89794 | ||
|
|
286c0f2c23 | ||
|
|
de57064b96 | ||
|
|
6c43e90708 | ||
|
|
1f25b79722 | ||
|
|
6a9080157f | ||
|
|
5cc2ef3ac8 | ||
|
|
3baeb62b0b | ||
|
|
9e27f59033 | ||
|
|
82fa2f979c | ||
|
|
07d7324332 | ||
|
|
d92adda2c9 | ||
|
|
0587400e2d | ||
|
|
35c8c63793 | ||
|
|
c7f5145e9e | ||
|
|
9452169f0a | ||
|
|
a15f43e0f8 | ||
|
|
0eb4754b31 | ||
|
|
f987ff8199 | ||
|
|
64a5d1ca24 | ||
|
|
fa17081012 | ||
|
|
856cb0737d | ||
|
|
f61e3f46e8 | ||
|
|
6b6b943b73 | ||
|
|
75d9b07158 | ||
|
|
8682f7f82f | ||
|
|
35a5b99bed | ||
|
|
98af25d109 | ||
|
|
cd3391461c | ||
|
|
e3b7f86075 | ||
|
|
86d5865457 | ||
|
|
7b783076e5 | ||
|
|
57c0ad694c | ||
|
|
f55a31c24f | ||
|
|
843095afc6 | ||
|
|
a6bad52181 | ||
|
|
012d98380d | ||
|
|
0298997d23 | ||
|
|
678a94bf71 | ||
|
|
03399e86a9 | ||
|
|
22364bac89 | ||
|
|
9188b5451c | ||
|
|
c7ed527911 | ||
|
|
5a1132101b | ||
|
|
ca33bf8b3e | ||
|
|
7d8c80c9a0 | ||
|
|
c6f993428e | ||
|
|
f6118b858d | ||
|
|
ec1bca238e |
@@ -94,6 +94,7 @@ typedef struct CallInfo {
|
|||||||
#define CIST_YPCALL (1<<4) /* call is a yieldable protected call */
|
#define CIST_YPCALL (1<<4) /* call is a yieldable protected call */
|
||||||
#define CIST_TAIL (1<<5) /* call was tail called */
|
#define CIST_TAIL (1<<5) /* call was tail called */
|
||||||
#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */
|
#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */
|
||||||
|
#define CIST_LEQ (1<<7) /* using __lt for __le */
|
||||||
|
|
||||||
#define isLua(ci) ((ci)->callstatus & CIST_LUA)
|
#define isLua(ci) ((ci)->callstatus & CIST_LUA)
|
||||||
|
|
||||||
|
|||||||
@@ -798,7 +798,8 @@ static int str_gsub (lua_State *L) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
|
/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
|
||||||
#define MAX_ITEM 512
|
#define MAX_ITEM \
|
||||||
|
(sizeof(lua_Number) <= 4 ? 150 : sizeof(lua_Number) <= 8 ? 450 : 5050)
|
||||||
|
|
||||||
/* valid flags in a format specification */
|
/* valid flags in a format specification */
|
||||||
#define FLAGS "-+ #0"
|
#define FLAGS "-+ #0"
|
||||||
|
|||||||
@@ -460,7 +460,7 @@ struct lua_Debug {
|
|||||||
|
|
||||||
/* Add by skynet */
|
/* Add by skynet */
|
||||||
|
|
||||||
extern lua_State * skynet_sig_L;
|
LUA_API lua_State * skynet_sig_L;
|
||||||
LUA_API void (lua_checksig_)(lua_State *L);
|
LUA_API void (lua_checksig_)(lua_State *L);
|
||||||
#define lua_checksig(L) if (skynet_sig_L) { lua_checksig_(L); }
|
#define lua_checksig(L) if (skynet_sig_L) { lua_checksig_(L); }
|
||||||
|
|
||||||
|
|||||||
@@ -303,12 +303,18 @@ int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
|
|||||||
return l_strcmp(tsvalue(l), tsvalue(r)) <= 0;
|
return l_strcmp(tsvalue(l), tsvalue(r)) <= 0;
|
||||||
else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* first try 'le' */
|
else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* first try 'le' */
|
||||||
return res;
|
return res;
|
||||||
else if ((res = luaT_callorderTM(L, r, l, TM_LT)) < 0) /* else try 'lt' */
|
else { /* try 'lt': */
|
||||||
luaG_ordererror(L, l, r);
|
L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */
|
||||||
return !res;
|
res = luaT_callorderTM(L, r, l, TM_LT);
|
||||||
|
L->ci->callstatus ^= CIST_LEQ; /* clear mark */
|
||||||
|
if (res < 0)
|
||||||
|
luaG_ordererror(L, l, r);
|
||||||
|
return !res; /* result is negated */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Main operation for equality of Lua values; return 't1 == t2'.
|
** Main operation for equality of Lua values; return 't1 == t2'.
|
||||||
** L == NULL means raw equality (no metamethods)
|
** L == NULL means raw equality (no metamethods)
|
||||||
@@ -564,11 +570,11 @@ void luaV_finishOp (lua_State *L) {
|
|||||||
case OP_LE: case OP_LT: case OP_EQ: {
|
case OP_LE: case OP_LT: case OP_EQ: {
|
||||||
int res = !l_isfalse(L->top - 1);
|
int res = !l_isfalse(L->top - 1);
|
||||||
L->top--;
|
L->top--;
|
||||||
/* metamethod should not be called when operand is K */
|
if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */
|
||||||
lua_assert(!ISK(GETARG_B(inst)));
|
lua_assert(op == OP_LE);
|
||||||
if (op == OP_LE && /* "<=" using "<" instead? */
|
ci->callstatus ^= CIST_LEQ; /* clear mark */
|
||||||
ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE)))
|
res = !res; /* negate result */
|
||||||
res = !res; /* invert result */
|
}
|
||||||
lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
|
lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
|
||||||
if (res != GETARG_A(inst)) /* condition failed? */
|
if (res != GETARG_A(inst)) /* condition failed? */
|
||||||
ci->u.l.savedpc++; /* skip jump instruction */
|
ci->u.l.savedpc++; /* skip jump instruction */
|
||||||
|
|||||||
40
HISTORY.md
40
HISTORY.md
@@ -1,3 +1,43 @@
|
|||||||
|
v1.0.0-alpha7 (2015-6-8)
|
||||||
|
-----------
|
||||||
|
* console support launch snax service
|
||||||
|
* Add cluster.snax
|
||||||
|
* Add nodelay in clusterd
|
||||||
|
* Merge sproto bugfix patch
|
||||||
|
* Move some skynet api into skynet.manager
|
||||||
|
* DNS support underscore
|
||||||
|
* Add logservice in config file for user defined log service
|
||||||
|
* skynet.fork returns coroutine
|
||||||
|
* Fix a few of bugs , see the commits log
|
||||||
|
|
||||||
|
v1.0.0-alpha6 (2015-5-18)
|
||||||
|
-----------
|
||||||
|
* bugfix: httpc.get
|
||||||
|
* bugfix: seri lib stack overflow
|
||||||
|
* bugfix: udp send
|
||||||
|
* bugfix: udp address
|
||||||
|
* bugfix: sproto dump
|
||||||
|
* add: sproto default
|
||||||
|
* improve: skynet.wakeup (can wakeup skynet.call by raise an error)
|
||||||
|
* improve: skynet.exit (raise error when uncall response)
|
||||||
|
* remove: task overload warning
|
||||||
|
* move: some skynet api move into skynet.manager
|
||||||
|
|
||||||
|
v1.0.0-alpha5 (2015-4-27)
|
||||||
|
-----------
|
||||||
|
* merge lua 5.3 offical bugfix
|
||||||
|
* improve sproto rpc api
|
||||||
|
* fix a deadlock bug when service retire
|
||||||
|
* improve cluster config reload
|
||||||
|
* add skynet.pcall for calling a function with `require`
|
||||||
|
* better error log in loginserver
|
||||||
|
|
||||||
|
v1.0.0-alpha4 (2015-4-13)
|
||||||
|
-----------
|
||||||
|
* sproto can share c struct between states
|
||||||
|
* udp api changed (use lua string now)
|
||||||
|
* fix memory leak in dns module
|
||||||
|
|
||||||
v1.0.0-alpha3 (2015-3-30)
|
v1.0.0-alpha3 (2015-3-30)
|
||||||
-----------
|
-----------
|
||||||
* Update sproto (bugfix)
|
* Update sproto (bugfix)
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2012-2014 codingnow.com
|
Copyright (c) 2012-2015 codingnow.com
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
local skynet = require "skynet"
|
local skynet = require "skynet"
|
||||||
|
require "skynet.manager" -- import skynet.abort
|
||||||
|
|
||||||
skynet.abort()
|
skynet.abort()
|
||||||
@@ -4,6 +4,7 @@ local socket = require "socket"
|
|||||||
local sproto = require "sproto"
|
local sproto = require "sproto"
|
||||||
local sprotoloader = require "sprotoloader"
|
local sprotoloader = require "sprotoloader"
|
||||||
|
|
||||||
|
local WATCHDOG
|
||||||
local host
|
local host
|
||||||
local send_request
|
local send_request
|
||||||
|
|
||||||
@@ -26,6 +27,10 @@ function REQUEST:handshake()
|
|||||||
return { msg = "Welcome to skynet, I will send heartbeat every 5 sec." }
|
return { msg = "Welcome to skynet, I will send heartbeat every 5 sec." }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function REQUEST:quit()
|
||||||
|
skynet.call(WATCHDOG, "lua", "close", client_fd)
|
||||||
|
end
|
||||||
|
|
||||||
local function request(name, args, response)
|
local function request(name, args, response)
|
||||||
local f = assert(REQUEST[name])
|
local f = assert(REQUEST[name])
|
||||||
local r = f(args)
|
local r = f(args)
|
||||||
@@ -62,7 +67,10 @@ skynet.register_protocol {
|
|||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
function CMD.start(gate, fd)
|
function CMD.start(conf)
|
||||||
|
local fd = conf.client
|
||||||
|
local gate = conf.gate
|
||||||
|
WATCHDOG = conf.watchdog
|
||||||
-- slot 1,2 set at main.lua
|
-- slot 1,2 set at main.lua
|
||||||
host = sprotoloader.load(1):host "package"
|
host = sprotoloader.load(1):host "package"
|
||||||
send_request = host:attach(sprotoloader.load(2))
|
send_request = host:attach(sprotoloader.load(2))
|
||||||
@@ -77,6 +85,11 @@ function CMD.start(gate, fd)
|
|||||||
skynet.call(gate, "lua", "forward", fd)
|
skynet.call(gate, "lua", "forward", fd)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function CMD.disconnect()
|
||||||
|
-- todo: do something before exit
|
||||||
|
skynet.exit()
|
||||||
|
end
|
||||||
|
|
||||||
skynet.start(function()
|
skynet.start(function()
|
||||||
skynet.dispatch("lua", function(_,_, command, ...)
|
skynet.dispatch("lua", function(_,_, command, ...)
|
||||||
local f = CMD[command]
|
local f = CMD[command]
|
||||||
|
|||||||
@@ -104,7 +104,11 @@ while true do
|
|||||||
dispatch_package()
|
dispatch_package()
|
||||||
local cmd = socket.readstdin()
|
local cmd = socket.readstdin()
|
||||||
if cmd then
|
if cmd then
|
||||||
send_request("get", { what = cmd })
|
if cmd == "quit" then
|
||||||
|
send_request("quit")
|
||||||
|
else
|
||||||
|
send_request("get", { what = cmd })
|
||||||
|
end
|
||||||
else
|
else
|
||||||
socket.usleep(100)
|
socket.usleep(100)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
local skynet = require "skynet"
|
local skynet = require "skynet"
|
||||||
local cluster = require "cluster"
|
local cluster = require "cluster"
|
||||||
|
require "skynet.manager" -- import skynet.name
|
||||||
|
local snax = require "snax"
|
||||||
|
|
||||||
skynet.start(function()
|
skynet.start(function()
|
||||||
local sdb = skynet.newservice("simpledb")
|
local sdb = skynet.newservice("simpledb")
|
||||||
skynet.name(".simpledb", sdb)
|
skynet.name(".simpledb", sdb)
|
||||||
print(skynet.call(".simpledb", "lua", "SET", "a", "foobar"))
|
print(skynet.call(".simpledb", "lua", "SET", "a", "foobar"))
|
||||||
|
print(skynet.call(".simpledb", "lua", "SET", "b", "foobar2"))
|
||||||
print(skynet.call(".simpledb", "lua", "GET", "a"))
|
print(skynet.call(".simpledb", "lua", "GET", "a"))
|
||||||
|
print(skynet.call(".simpledb", "lua", "GET", "b"))
|
||||||
cluster.open "db"
|
cluster.open "db"
|
||||||
|
cluster.open "db2"
|
||||||
|
-- unique snax service
|
||||||
|
snax.uniqueservice "pingserver"
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -5,4 +5,9 @@ skynet.start(function()
|
|||||||
local proxy = cluster.proxy("db", ".simpledb")
|
local proxy = cluster.proxy("db", ".simpledb")
|
||||||
print(skynet.call(proxy, "lua", "GET", "a"))
|
print(skynet.call(proxy, "lua", "GET", "a"))
|
||||||
print(cluster.call("db", ".simpledb", "GET", "a"))
|
print(cluster.call("db", ".simpledb", "GET", "a"))
|
||||||
|
print(cluster.call("db2", ".simpledb", "GET", "b"))
|
||||||
|
|
||||||
|
-- test snax service
|
||||||
|
local pingserver = cluster.snax("db", "pingserver")
|
||||||
|
print(pingserver.req.ping "hello")
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
db = "127.0.0.1:2528"
|
db = "127.0.0.1:2528"
|
||||||
|
db2 = "127.0.0.1:2529"
|
||||||
|
|||||||
@@ -6,4 +6,5 @@ bootstrap = "snlua bootstrap" -- The service for bootstrap
|
|||||||
luaservice = "./service/?.lua;./test/?.lua;./examples/?.lua"
|
luaservice = "./service/?.lua;./test/?.lua;./examples/?.lua"
|
||||||
lualoader = "lualib/loader.lua"
|
lualoader = "lualib/loader.lua"
|
||||||
cpath = "./cservice/?.so"
|
cpath = "./cservice/?.so"
|
||||||
cluster = "./examples/clustername.lua"
|
cluster = "./examples/clustername.lua"
|
||||||
|
snax = "./test/?.lua"
|
||||||
|
|||||||
@@ -6,4 +6,5 @@ bootstrap = "snlua bootstrap" -- The service for bootstrap
|
|||||||
luaservice = "./service/?.lua;./test/?.lua;./examples/?.lua"
|
luaservice = "./service/?.lua;./test/?.lua;./examples/?.lua"
|
||||||
lualoader = "lualib/loader.lua"
|
lualoader = "lualib/loader.lua"
|
||||||
cpath = "./cservice/?.so"
|
cpath = "./cservice/?.so"
|
||||||
cluster = "./examples/clustername.lua"
|
cluster = "./examples/clustername.lua"
|
||||||
|
snax = "./test/?.lua"
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
local skynet = require "skynet"
|
local skynet = require "skynet"
|
||||||
|
require "skynet.manager" -- import skynet.register
|
||||||
|
|
||||||
skynet.start(function()
|
skynet.start(function()
|
||||||
skynet.dispatch("lua", function(session, address, ...)
|
skynet.dispatch("lua", function(session, address, ...)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
local skynet = require "skynet"
|
local skynet = require "skynet"
|
||||||
local harbor = require "skynet.harbor"
|
local harbor = require "skynet.harbor"
|
||||||
|
require "skynet.manager" -- import skynet.monitor
|
||||||
|
|
||||||
local function monitor_master()
|
local function monitor_master()
|
||||||
harbor.linkmaster()
|
harbor.linkmaster()
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ set 3 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
quit 4 {}
|
||||||
|
|
||||||
]]
|
]]
|
||||||
|
|
||||||
proto.s2c = sprotoparser.parse [[
|
proto.s2c = sprotoparser.parse [[
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
local skynet = require "skynet"
|
local skynet = require "skynet"
|
||||||
|
require "skynet.manager" -- import skynet.register
|
||||||
local db = {}
|
local db = {}
|
||||||
|
|
||||||
local command = {}
|
local command = {}
|
||||||
|
|||||||
@@ -9,14 +9,16 @@ local agent = {}
|
|||||||
function SOCKET.open(fd, addr)
|
function SOCKET.open(fd, addr)
|
||||||
skynet.error("New client from : " .. addr)
|
skynet.error("New client from : " .. addr)
|
||||||
agent[fd] = skynet.newservice("agent")
|
agent[fd] = skynet.newservice("agent")
|
||||||
skynet.call(agent[fd], "lua", "start", gate, fd)
|
skynet.call(agent[fd], "lua", "start", { gate = gate, client = fd, watchdog = skynet.self() })
|
||||||
end
|
end
|
||||||
|
|
||||||
local function close_agent(fd)
|
local function close_agent(fd)
|
||||||
local a = agent[fd]
|
local a = agent[fd]
|
||||||
|
agent[fd] = nil
|
||||||
if a then
|
if a then
|
||||||
skynet.kill(a)
|
skynet.call(gate, "lua", "kick", fd)
|
||||||
agent[fd] = nil
|
-- disconnect never return
|
||||||
|
skynet.send(a, "lua", "disconnect")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -37,6 +39,10 @@ function CMD.start(conf)
|
|||||||
skynet.call(gate, "lua", "open" , conf)
|
skynet.call(gate, "lua", "open" , conf)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function CMD.close(fd)
|
||||||
|
close_agent(fd)
|
||||||
|
end
|
||||||
|
|
||||||
skynet.start(function()
|
skynet.start(function()
|
||||||
skynet.dispatch("lua", function(session, source, cmd, subcmd, ...)
|
skynet.dispatch("lua", function(session, source, cmd, subcmd, ...)
|
||||||
if cmd == "socket" then
|
if cmd == "socket" then
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
/* the eight DES S-boxes */
|
/* the eight DES S-boxes */
|
||||||
|
|
||||||
uint32_t SB1[64] = {
|
static uint32_t SB1[64] = {
|
||||||
0x01010400, 0x00000000, 0x00010000, 0x01010404,
|
0x01010400, 0x00000000, 0x00010000, 0x01010404,
|
||||||
0x01010004, 0x00010404, 0x00000004, 0x00010000,
|
0x01010004, 0x00010404, 0x00000004, 0x00010000,
|
||||||
0x00000400, 0x01010400, 0x01010404, 0x00000400,
|
0x00000400, 0x01010400, 0x01010404, 0x00000400,
|
||||||
@@ -602,11 +602,7 @@ read64(lua_State *L, uint32_t xx[2], uint32_t yy[2]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
lhmac64(lua_State *L) {
|
pushqword(lua_State *L, uint32_t result[2]) {
|
||||||
uint32_t x[2], y[2];
|
|
||||||
read64(L, x, y);
|
|
||||||
uint32_t result[2];
|
|
||||||
hmac(x,y,result);
|
|
||||||
uint8_t tmp[8];
|
uint8_t tmp[8];
|
||||||
tmp[0] = result[0] & 0xff;
|
tmp[0] = result[0] & 0xff;
|
||||||
tmp[1] = (result[0] >> 8 )& 0xff;
|
tmp[1] = (result[0] >> 8 )& 0xff;
|
||||||
@@ -621,6 +617,40 @@ lhmac64(lua_State *L) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
lhmac64(lua_State *L) {
|
||||||
|
uint32_t x[2], y[2];
|
||||||
|
read64(L, x, y);
|
||||||
|
uint32_t result[2];
|
||||||
|
hmac(x,y,result);
|
||||||
|
return pushqword(L, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
8bytes key
|
||||||
|
string text
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
lhmac_hash(lua_State *L) {
|
||||||
|
uint32_t key[2];
|
||||||
|
size_t sz = 0;
|
||||||
|
const uint8_t *x = (const uint8_t *)luaL_checklstring(L, 1, &sz);
|
||||||
|
if (sz != 8) {
|
||||||
|
luaL_error(L, "Invalid uint64 key");
|
||||||
|
}
|
||||||
|
key[0] = x[0] | x[1]<<8 | x[2]<<16 | x[3]<<24;
|
||||||
|
key[1] = x[4] | x[5]<<8 | x[6]<<16 | x[7]<<24;
|
||||||
|
const char * text = luaL_checklstring(L, 2, &sz);
|
||||||
|
uint8_t h[8];
|
||||||
|
Hash(text,(int)sz,h);
|
||||||
|
uint32_t htext[2];
|
||||||
|
htext[0] = h[0] | h[1]<<8 | h[2]<<16 | h[3]<<24;
|
||||||
|
htext[1] = h[4] | h[5]<<8 | h[6]<<16 | h[7]<<24;
|
||||||
|
uint32_t result[2];
|
||||||
|
hmac(htext,key,result);
|
||||||
|
return pushqword(L, result);
|
||||||
|
}
|
||||||
|
|
||||||
// powmodp64 for DH-key exchange
|
// powmodp64 for DH-key exchange
|
||||||
|
|
||||||
// The biggest 64bit prime
|
// The biggest 64bit prime
|
||||||
@@ -858,6 +888,7 @@ luaopen_crypt(lua_State *L) {
|
|||||||
{ "base64decode", lb64decode },
|
{ "base64decode", lb64decode },
|
||||||
{ "sha1", lsha1 },
|
{ "sha1", lsha1 },
|
||||||
{ "hmac_sha1", lhmac_sha1 },
|
{ "hmac_sha1", lhmac_sha1 },
|
||||||
|
{ "hmac_hash", lhmac_hash },
|
||||||
{ NULL, NULL },
|
{ NULL, NULL },
|
||||||
};
|
};
|
||||||
luaL_newlib(L,l);
|
luaL_newlib(L,l);
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ channel_release(struct channel *c) {
|
|||||||
free(p);
|
free(p);
|
||||||
p = next;
|
p = next;
|
||||||
}
|
}
|
||||||
|
free(c);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -210,6 +210,16 @@ push_more(lua_State *L, int fd, uint8_t *buffer, int size) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
close_uncomplete(lua_State *L, int fd) {
|
||||||
|
struct queue *q = lua_touserdata(L,1);
|
||||||
|
struct uncomplete * uc = find_uncomplete(q, fd);
|
||||||
|
if (uc) {
|
||||||
|
skynet_free(uc->pack.buffer);
|
||||||
|
skynet_free(uc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
filter_data_(lua_State *L, int fd, uint8_t * buffer, int size) {
|
filter_data_(lua_State *L, int fd, uint8_t * buffer, int size) {
|
||||||
struct queue *q = lua_touserdata(L,1);
|
struct queue *q = lua_touserdata(L,1);
|
||||||
@@ -343,6 +353,8 @@ lfilter(lua_State *L) {
|
|||||||
// ignore listen fd connect
|
// ignore listen fd connect
|
||||||
return 1;
|
return 1;
|
||||||
case SKYNET_SOCKET_TYPE_CLOSE:
|
case SKYNET_SOCKET_TYPE_CLOSE:
|
||||||
|
// no more data in fd (message->id)
|
||||||
|
close_uncomplete(L, message->id);
|
||||||
lua_pushvalue(L, lua_upvalueindex(TYPE_CLOSE));
|
lua_pushvalue(L, lua_upvalueindex(TYPE_CLOSE));
|
||||||
lua_pushinteger(L, message->id);
|
lua_pushinteger(L, message->id);
|
||||||
return 3;
|
return 3;
|
||||||
@@ -353,6 +365,8 @@ lfilter(lua_State *L) {
|
|||||||
pushstring(L, buffer, size);
|
pushstring(L, buffer, size);
|
||||||
return 4;
|
return 4;
|
||||||
case SKYNET_SOCKET_TYPE_ERROR:
|
case SKYNET_SOCKET_TYPE_ERROR:
|
||||||
|
// no more data in fd (message->id)
|
||||||
|
close_uncomplete(L, message->id);
|
||||||
lua_pushvalue(L, lua_upvalueindex(TYPE_ERROR));
|
lua_pushvalue(L, lua_upvalueindex(TYPE_ERROR));
|
||||||
lua_pushinteger(L, message->id);
|
lua_pushinteger(L, message->id);
|
||||||
pushstring(L, buffer, size);
|
pushstring(L, buffer, size);
|
||||||
|
|||||||
@@ -256,6 +256,7 @@ wb_table_hash(lua_State *L, struct write_block * wb, int index, int depth, int a
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
wb_table(lua_State *L, struct write_block *wb, int index, int depth) {
|
wb_table(lua_State *L, struct write_block *wb, int index, int depth) {
|
||||||
|
luaL_checkstack(L, LUA_MINSTACK, NULL);
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
index = lua_gettop(L) + index + 1;
|
index = lua_gettop(L) + index + 1;
|
||||||
}
|
}
|
||||||
@@ -416,6 +417,7 @@ unpack_table(lua_State *L, struct read_block *rb, int array_size) {
|
|||||||
}
|
}
|
||||||
array_size = get_integer(L,rb,cookie);
|
array_size = get_integer(L,rb,cookie);
|
||||||
}
|
}
|
||||||
|
luaL_checkstack(L,LUA_MINSTACK,NULL);
|
||||||
lua_createtable(L,array_size,0);
|
lua_createtable(L,array_size,0);
|
||||||
int i;
|
int i;
|
||||||
for (i=1;i<=array_size;i++) {
|
for (i=1;i<=array_size;i++) {
|
||||||
@@ -549,8 +551,8 @@ _luaseri_unpack(lua_State *L) {
|
|||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i=0;;i++) {
|
for (i=0;;i++) {
|
||||||
if (i%16==15) {
|
if (i%8==7) {
|
||||||
lua_checkstack(L,i);
|
luaL_checkstack(L,LUA_MINSTACK,NULL);
|
||||||
}
|
}
|
||||||
uint8_t type = 0;
|
uint8_t type = 0;
|
||||||
uint8_t *t = rb_read(&rb, sizeof(type));
|
uint8_t *t = rb_read(&rb, sizeof(type));
|
||||||
|
|||||||
@@ -190,7 +190,10 @@ pop_lstring(lua_State *L, struct socket_buffer *sb, int sz, int skip) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
luaL_addlstring(&b, current->msg + sb->offset, (sz - skip < bytes) ? sz - skip : bytes);
|
int real_sz = sz - skip;
|
||||||
|
if (real_sz > 0) {
|
||||||
|
luaL_addlstring(&b, current->msg + sb->offset, (real_sz < bytes) ? real_sz : bytes);
|
||||||
|
}
|
||||||
return_free_node(L,2,sb);
|
return_free_node(L,2,sb);
|
||||||
sz-=bytes;
|
sz-=bytes;
|
||||||
if (sz==0)
|
if (sz==0)
|
||||||
@@ -534,12 +537,6 @@ lnodelay(lua_State *L) {
|
|||||||
skynet_socket_nodelay(ctx,id);
|
skynet_socket_nodelay(ctx,id);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
int skynet_socket_udp(struct skynet_context *ctx, const char * addr, int port);
|
|
||||||
int skynet_socket_udp_connect(struct skynet_context *ctx, int id, const char * addr, int port);
|
|
||||||
int skynet_socket_udp_send(struct skynet_context *ctx, int id, const char * address, const void *buffer, int sz);
|
|
||||||
const char * skynet_socket_udp_address(struct skynet_context *ctx, struct skynet_socket_message *, int *addrsz);
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ludp(lua_State *L) {
|
ludp(lua_State *L) {
|
||||||
@@ -599,7 +596,9 @@ static int
|
|||||||
ludp_address(lua_State *L) {
|
ludp_address(lua_State *L) {
|
||||||
size_t sz = 0;
|
size_t sz = 0;
|
||||||
const uint8_t * addr = (const uint8_t *)luaL_checklstring(L, 1, &sz);
|
const uint8_t * addr = (const uint8_t *)luaL_checklstring(L, 1, &sz);
|
||||||
int port = addr[1] * 256 + addr[2];
|
uint16_t port = 0;
|
||||||
|
memcpy(&port, addr+1, sizeof(uint16_t));
|
||||||
|
port = ntohs(port);
|
||||||
const void * src = addr+3;
|
const void * src = addr+3;
|
||||||
char tmp[256];
|
char tmp[256];
|
||||||
int family;
|
int family;
|
||||||
|
|||||||
@@ -48,15 +48,9 @@ LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
lnewproto(lua_State *L) {
|
lnewproto(lua_State *L) {
|
||||||
size_t sz = 0;
|
|
||||||
void * buffer;
|
|
||||||
struct sproto * sp;
|
struct sproto * sp;
|
||||||
if (lua_isuserdata(L,1)) {
|
size_t sz;
|
||||||
buffer = lua_touserdata(L,1);
|
void * buffer = (void *)luaL_checklstring(L,1,&sz);
|
||||||
sz = luaL_checkinteger(L,2);
|
|
||||||
} else {
|
|
||||||
buffer = (void *)luaL_checklstring(L,1,&sz);
|
|
||||||
}
|
|
||||||
sp = sproto_create(buffer, sz);
|
sp = sproto_create(buffer, sz);
|
||||||
if (sp) {
|
if (sp) {
|
||||||
lua_pushlightuserdata(L, sp);
|
lua_pushlightuserdata(L, sp);
|
||||||
@@ -199,7 +193,7 @@ encode(const struct sproto_arg *args) {
|
|||||||
return -1;
|
return -1;
|
||||||
memcpy(args->value, str, sz);
|
memcpy(args->value, str, sz);
|
||||||
lua_pop(L,1);
|
lua_pop(L,1);
|
||||||
return sz;
|
return sz + 1; // The length of empty string is 1.
|
||||||
}
|
}
|
||||||
case SPROTO_TSTRUCT: {
|
case SPROTO_TSTRUCT: {
|
||||||
struct encode_ud sub;
|
struct encode_ud sub;
|
||||||
@@ -545,48 +539,98 @@ lprotocol(lua_State *L) {
|
|||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* global sproto pointer for multi states */
|
/* global sproto pointer for multi states
|
||||||
struct sproto_bin {
|
NOTICE : It is not thread safe
|
||||||
void *ptr;
|
*/
|
||||||
size_t sz;
|
static struct sproto * G_sproto[MAX_GLOBALSPROTO];
|
||||||
};
|
|
||||||
|
|
||||||
static struct sproto_bin G_sproto[MAX_GLOBALSPROTO];
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
lsaveproto(lua_State *L) {
|
lsaveproto(lua_State *L) {
|
||||||
size_t sz;
|
struct sproto * sp = lua_touserdata(L, 1);
|
||||||
void * buffer = (void *)luaL_checklstring(L,1,&sz);
|
|
||||||
int index = luaL_optinteger(L, 2, 0);
|
int index = luaL_optinteger(L, 2, 0);
|
||||||
void * tmp;
|
|
||||||
struct sproto_bin * sbin = &G_sproto[index];
|
|
||||||
if (index < 0 || index >= MAX_GLOBALSPROTO) {
|
if (index < 0 || index >= MAX_GLOBALSPROTO) {
|
||||||
return luaL_error(L, "Invalid global slot index %d", index);
|
return luaL_error(L, "Invalid global slot index %d", index);
|
||||||
}
|
}
|
||||||
tmp = malloc(sz);
|
/* TODO : release old object (memory leak now, but thread safe)*/
|
||||||
memcpy(tmp, buffer, sz);
|
G_sproto[index] = sp;
|
||||||
if (sbin->ptr) {
|
|
||||||
free(sbin->ptr);
|
|
||||||
}
|
|
||||||
sbin->ptr = tmp;
|
|
||||||
sbin->sz = sz;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
lloadproto(lua_State *L) {
|
lloadproto(lua_State *L) {
|
||||||
int index = luaL_optinteger(L, 1, 0);
|
int index = luaL_optinteger(L, 1, 0);
|
||||||
struct sproto_bin * sbin = &G_sproto[index];
|
struct sproto * sp;
|
||||||
if (index < 0 || index >= MAX_GLOBALSPROTO) {
|
if (index < 0 || index >= MAX_GLOBALSPROTO) {
|
||||||
return luaL_error(L, "Invalid global slot index %d", index);
|
return luaL_error(L, "Invalid global slot index %d", index);
|
||||||
}
|
}
|
||||||
if (sbin->ptr == NULL) {
|
sp = G_sproto[index];
|
||||||
|
if (sp == NULL) {
|
||||||
return luaL_error(L, "nil sproto at index %d", index);
|
return luaL_error(L, "nil sproto at index %d", index);
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pushlightuserdata(L, sbin->ptr);
|
lua_pushlightuserdata(L, sp);
|
||||||
lua_pushinteger(L, sbin->sz);
|
|
||||||
return 2;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
encode_default(const struct sproto_arg *args) {
|
||||||
|
lua_State *L = args->ud;
|
||||||
|
lua_pushstring(L, args->tagname);
|
||||||
|
if (args->index > 0) {
|
||||||
|
lua_newtable(L);
|
||||||
|
} else {
|
||||||
|
switch(args->type) {
|
||||||
|
case SPROTO_TINTEGER:
|
||||||
|
lua_pushinteger(L, 0);
|
||||||
|
break;
|
||||||
|
case SPROTO_TBOOLEAN:
|
||||||
|
lua_pushboolean(L, 0);
|
||||||
|
break;
|
||||||
|
case SPROTO_TSTRING:
|
||||||
|
lua_pushliteral(L, "");
|
||||||
|
break;
|
||||||
|
case SPROTO_TSTRUCT:
|
||||||
|
lua_createtable(L, 0, 1);
|
||||||
|
lua_pushstring(L, sproto_name(args->subtype));
|
||||||
|
lua_setfield(L, -2, "__type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lua_rawset(L, -3);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
lightuserdata sproto_type
|
||||||
|
return default table
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
ldefault(lua_State *L) {
|
||||||
|
int ret;
|
||||||
|
// 64 is always enough for dummy buffer, except the type has many fields ( > 27).
|
||||||
|
char dummy[64];
|
||||||
|
struct sproto_type * st = lua_touserdata(L, 1);
|
||||||
|
if (st == NULL) {
|
||||||
|
return luaL_argerror(L, 1, "Need a sproto_type object");
|
||||||
|
}
|
||||||
|
lua_newtable(L);
|
||||||
|
ret = sproto_encode(st, dummy, sizeof(dummy), encode_default, L);
|
||||||
|
if (ret<0) {
|
||||||
|
// try again
|
||||||
|
int sz = sizeof(dummy) * 2;
|
||||||
|
void * tmp = lua_newuserdata(L, sz);
|
||||||
|
lua_insert(L, -2);
|
||||||
|
for (;;) {
|
||||||
|
ret = sproto_encode(st, tmp, sz, encode_default, L);
|
||||||
|
if (ret >= 0)
|
||||||
|
break;
|
||||||
|
sz *= 2;
|
||||||
|
tmp = lua_newuserdata(L, sz);
|
||||||
|
lua_replace(L, -3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -603,6 +647,7 @@ luaopen_sproto_core(lua_State *L) {
|
|||||||
{ "protocol", lprotocol },
|
{ "protocol", lprotocol },
|
||||||
{ "loadproto", lloadproto },
|
{ "loadproto", lloadproto },
|
||||||
{ "saveproto", lsaveproto },
|
{ "saveproto", lsaveproto },
|
||||||
|
{ "default", ldefault },
|
||||||
{ NULL, NULL },
|
{ NULL, NULL },
|
||||||
};
|
};
|
||||||
luaL_newlib(L,l);
|
luaL_newlib(L,l);
|
||||||
|
|||||||
@@ -500,7 +500,11 @@ sproto_dump(struct sproto *s) {
|
|||||||
printf("=== %d protocol ===\n", s->protocol_n);
|
printf("=== %d protocol ===\n", s->protocol_n);
|
||||||
for (i=0;i<s->protocol_n;i++) {
|
for (i=0;i<s->protocol_n;i++) {
|
||||||
struct protocol *p = &s->proto[i];
|
struct protocol *p = &s->proto[i];
|
||||||
printf("\t%s (%d) request:%s", p->name, p->tag, p->p[SPROTO_REQUEST]->name);
|
if (p->p[SPROTO_REQUEST]) {
|
||||||
|
printf("\t%s (%d) request:%s", p->name, p->tag, p->p[SPROTO_REQUEST]->name);
|
||||||
|
} else {
|
||||||
|
printf("\t%s (%d) request:(null)", p->name, p->tag);
|
||||||
|
}
|
||||||
if (p->p[SPROTO_RESPONSE]) {
|
if (p->p[SPROTO_RESPONSE]) {
|
||||||
printf(" response:%s", p->p[SPROTO_RESPONSE]->name);
|
printf(" response:%s", p->p[SPROTO_RESPONSE]->name);
|
||||||
}
|
}
|
||||||
@@ -510,7 +514,7 @@ sproto_dump(struct sproto *s) {
|
|||||||
|
|
||||||
// query
|
// query
|
||||||
int
|
int
|
||||||
sproto_prototag(struct sproto *sp, const char * name) {
|
sproto_prototag(const struct sproto *sp, const char * name) {
|
||||||
int i;
|
int i;
|
||||||
for (i=0;i<sp->protocol_n;i++) {
|
for (i=0;i<sp->protocol_n;i++) {
|
||||||
if (strcmp(name, sp->proto[i].name) == 0) {
|
if (strcmp(name, sp->proto[i].name) == 0) {
|
||||||
@@ -521,7 +525,7 @@ sproto_prototag(struct sproto *sp, const char * name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct protocol *
|
static struct protocol *
|
||||||
query_proto(struct sproto *sp, int tag) {
|
query_proto(const struct sproto *sp, int tag) {
|
||||||
int begin = 0, end = sp->protocol_n;
|
int begin = 0, end = sp->protocol_n;
|
||||||
while(begin<end) {
|
while(begin<end) {
|
||||||
int mid = (begin+end)/2;
|
int mid = (begin+end)/2;
|
||||||
@@ -539,7 +543,7 @@ query_proto(struct sproto *sp, int tag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct sproto_type *
|
struct sproto_type *
|
||||||
sproto_protoquery(struct sproto *sp, int proto, int what) {
|
sproto_protoquery(const struct sproto *sp, int proto, int what) {
|
||||||
struct protocol * p;
|
struct protocol * p;
|
||||||
if (what <0 || what >1) {
|
if (what <0 || what >1) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -552,7 +556,7 @@ sproto_protoquery(struct sproto *sp, int proto, int what) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
sproto_protoname(struct sproto *sp, int proto) {
|
sproto_protoname(const struct sproto *sp, int proto) {
|
||||||
struct protocol * p = query_proto(sp, proto);
|
struct protocol * p = query_proto(sp, proto);
|
||||||
if (p) {
|
if (p) {
|
||||||
return p->name;
|
return p->name;
|
||||||
@@ -561,7 +565,7 @@ sproto_protoname(struct sproto *sp, int proto) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct sproto_type *
|
struct sproto_type *
|
||||||
sproto_type(struct sproto *sp, const char * type_name) {
|
sproto_type(const struct sproto *sp, const char * type_name) {
|
||||||
int i;
|
int i;
|
||||||
for (i=0;i<sp->type_n;i++) {
|
for (i=0;i<sp->type_n;i++) {
|
||||||
if (strcmp(type_name, sp->type[i].name) == 0) {
|
if (strcmp(type_name, sp->type[i].name) == 0) {
|
||||||
@@ -577,7 +581,7 @@ sproto_name(struct sproto_type * st) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct field *
|
static struct field *
|
||||||
findtag(struct sproto_type *st, int tag) {
|
findtag(const struct sproto_type *st, int tag) {
|
||||||
int begin, end;
|
int begin, end;
|
||||||
if (st->base >=0 ) {
|
if (st->base >=0 ) {
|
||||||
tag -= st->base;
|
tag -= st->base;
|
||||||
@@ -609,10 +613,6 @@ findtag(struct sproto_type *st, int tag) {
|
|||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
fill_size(uint8_t * data, int sz) {
|
fill_size(uint8_t * data, int sz) {
|
||||||
if (sz < 0)
|
|
||||||
return -1;
|
|
||||||
if (sz == 0)
|
|
||||||
return 0;
|
|
||||||
data[0] = sz & 0xff;
|
data[0] = sz & 0xff;
|
||||||
data[1] = (sz >> 8) & 0xff;
|
data[1] = (sz >> 8) & 0xff;
|
||||||
data[2] = (sz >> 16) & 0xff;
|
data[2] = (sz >> 16) & 0xff;
|
||||||
@@ -677,6 +677,11 @@ encode_object(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int si
|
|||||||
args->value = data+SIZEOF_LENGTH;
|
args->value = data+SIZEOF_LENGTH;
|
||||||
args->length = size-SIZEOF_LENGTH;
|
args->length = size-SIZEOF_LENGTH;
|
||||||
sz = cb(args);
|
sz = cb(args);
|
||||||
|
if (sz <= 0)
|
||||||
|
return sz;
|
||||||
|
if (args->type == SPROTO_TSTRING) {
|
||||||
|
--sz; // the length of null string is 1
|
||||||
|
}
|
||||||
return fill_size(data, sz);
|
return fill_size(data, sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -718,7 +723,7 @@ encode_integer_array(sproto_callback cb, struct sproto_arg *args, uint8_t *buffe
|
|||||||
sz = cb(args);
|
sz = cb(args);
|
||||||
if (sz < 0)
|
if (sz < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (sz == 0)
|
if (sz == 0) // nil object, end of array
|
||||||
break;
|
break;
|
||||||
if (size < sizeof(uint64_t))
|
if (size < sizeof(uint64_t))
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -798,7 +803,7 @@ encode_array(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int siz
|
|||||||
sz = cb(args);
|
sz = cb(args);
|
||||||
if (sz < 0)
|
if (sz < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (sz == 0)
|
if (sz == 0) // nil object , end of array
|
||||||
break;
|
break;
|
||||||
if (size < 1)
|
if (size < 1)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -817,10 +822,13 @@ encode_array(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int siz
|
|||||||
args->value = buffer+SIZEOF_LENGTH;
|
args->value = buffer+SIZEOF_LENGTH;
|
||||||
args->length = size;
|
args->length = size;
|
||||||
sz = cb(args);
|
sz = cb(args);
|
||||||
if (sz < 0)
|
|
||||||
return -1;
|
|
||||||
if (sz == 0)
|
if (sz == 0)
|
||||||
break;
|
break;
|
||||||
|
if (sz < 0)
|
||||||
|
return -1;
|
||||||
|
if (args->type == SPROTO_TSTRING) {
|
||||||
|
--sz;
|
||||||
|
}
|
||||||
fill_size(buffer, sz);
|
fill_size(buffer, sz);
|
||||||
buffer += SIZEOF_LENGTH+sz;
|
buffer += SIZEOF_LENGTH+sz;
|
||||||
size -=sz;
|
size -=sz;
|
||||||
@@ -829,13 +837,13 @@ encode_array(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int siz
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sz = buffer - (data + SIZEOF_LENGTH);
|
sz = buffer - (data + SIZEOF_LENGTH);
|
||||||
if (sz == 0)
|
if (sz == 0) // empty array
|
||||||
return 0;
|
return 0;
|
||||||
return fill_size(data, sz);
|
return fill_size(data, sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sproto_encode(struct sproto_type *st, void * buffer, int size, sproto_callback cb, void *ud) {
|
sproto_encode(const struct sproto_type *st, void * buffer, int size, sproto_callback cb, void *ud) {
|
||||||
struct sproto_arg args;
|
struct sproto_arg args;
|
||||||
uint8_t * header = buffer;
|
uint8_t * header = buffer;
|
||||||
uint8_t * data;
|
uint8_t * data;
|
||||||
@@ -878,7 +886,7 @@ sproto_encode(struct sproto_type *st, void * buffer, int size, sproto_callback c
|
|||||||
sz = cb(&args);
|
sz = cb(&args);
|
||||||
if (sz < 0)
|
if (sz < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (sz == 0)
|
if (sz == 0) // nil object
|
||||||
continue;
|
continue;
|
||||||
if (sz == sizeof(uint32_t)) {
|
if (sz == sizeof(uint32_t)) {
|
||||||
if (u.u32 < 0x7fff) {
|
if (u.u32 < 0x7fff) {
|
||||||
@@ -895,11 +903,10 @@ sproto_encode(struct sproto_type *st, void * buffer, int size, sproto_callback c
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPROTO_TSTRUCT:
|
case SPROTO_TSTRUCT:
|
||||||
case SPROTO_TSTRING: {
|
case SPROTO_TSTRING:
|
||||||
sz = encode_object(cb, &args, data, size);
|
sz = encode_object(cb, &args, data, size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (sz < 0)
|
if (sz < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1032,7 +1039,7 @@ decode_array(sproto_callback cb, struct sproto_arg *args, uint8_t * stream) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sproto_decode(struct sproto_type *st, const void * data, int size, sproto_callback cb, void *ud) {
|
sproto_decode(const struct sproto_type *st, const void * data, int size, sproto_callback cb, void *ud) {
|
||||||
struct sproto_arg args;
|
struct sproto_arg args;
|
||||||
int total = size;
|
int total = size;
|
||||||
uint8_t * stream;
|
uint8_t * stream;
|
||||||
|
|||||||
@@ -17,12 +17,12 @@ struct sproto_type;
|
|||||||
struct sproto * sproto_create(const void * proto, size_t sz);
|
struct sproto * sproto_create(const void * proto, size_t sz);
|
||||||
void sproto_release(struct sproto *);
|
void sproto_release(struct sproto *);
|
||||||
|
|
||||||
int sproto_prototag(struct sproto *, const char * name);
|
int sproto_prototag(const struct sproto *, const char * name);
|
||||||
const char * sproto_protoname(struct sproto *, int proto);
|
const char * sproto_protoname(const struct sproto *, int proto);
|
||||||
// SPROTO_REQUEST(0) : request, SPROTO_RESPONSE(1): response
|
// SPROTO_REQUEST(0) : request, SPROTO_RESPONSE(1): response
|
||||||
struct sproto_type * sproto_protoquery(struct sproto *, int proto, int what);
|
struct sproto_type * sproto_protoquery(const struct sproto *, int proto, int what);
|
||||||
|
|
||||||
struct sproto_type * sproto_type(struct sproto *, const char * type_name);
|
struct sproto_type * sproto_type(const struct sproto *, const char * type_name);
|
||||||
|
|
||||||
int sproto_pack(const void * src, int srcsz, void * buffer, int bufsz);
|
int sproto_pack(const void * src, int srcsz, void * buffer, int bufsz);
|
||||||
int sproto_unpack(const void * src, int srcsz, void * buffer, int bufsz);
|
int sproto_unpack(const void * src, int srcsz, void * buffer, int bufsz);
|
||||||
@@ -41,8 +41,8 @@ struct sproto_arg {
|
|||||||
|
|
||||||
typedef int (*sproto_callback)(const struct sproto_arg *args);
|
typedef int (*sproto_callback)(const struct sproto_arg *args);
|
||||||
|
|
||||||
int sproto_decode(struct sproto_type *, const void * data, int size, sproto_callback cb, void *ud);
|
int sproto_decode(const struct sproto_type *, const void * data, int size, sproto_callback cb, void *ud);
|
||||||
int sproto_encode(struct sproto_type *, void * buffer, int size, sproto_callback cb, void *ud);
|
int sproto_encode(const struct sproto_type *, void * buffer, int size, sproto_callback cb, void *ud);
|
||||||
|
|
||||||
// for debug use
|
// for debug use
|
||||||
void sproto_dump(struct sproto *);
|
void sproto_dump(struct sproto *);
|
||||||
|
|||||||
@@ -24,6 +24,15 @@ function cluster.proxy(node, name)
|
|||||||
return skynet.call(clusterd, "lua", "proxy", node, name)
|
return skynet.call(clusterd, "lua", "proxy", node, name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function cluster.snax(node, name, address)
|
||||||
|
local snax = require "snax"
|
||||||
|
if not address then
|
||||||
|
address = cluster.call(node, ".service", "QUERY", "snaxd" , name)
|
||||||
|
end
|
||||||
|
local handle = skynet.call(clusterd, "lua", "proxy", node, address)
|
||||||
|
return snax.bind(handle, name)
|
||||||
|
end
|
||||||
|
|
||||||
skynet.init(function()
|
skynet.init(function()
|
||||||
clusterd = skynet.uniqueservice("clusterd")
|
clusterd = skynet.uniqueservice("clusterd")
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -88,10 +88,10 @@ local function verify_domain_name(name)
|
|||||||
if #name > MAX_DOMAIN_LEN then
|
if #name > MAX_DOMAIN_LEN then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
if not name:match("^[%l%d-%.]+$") then
|
if not name:match("^[_%l%d%-%.]+$") then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
for w in name:gmatch("([%w-]+)%.?") do
|
for w in name:gmatch("([_%w%-]+)%.?") do
|
||||||
if #w > MAX_LABEL_LEN then
|
if #w > MAX_LABEL_LEN then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
@@ -113,7 +113,7 @@ end
|
|||||||
|
|
||||||
local function pack_question(name, qtype, qclass)
|
local function pack_question(name, qtype, qclass)
|
||||||
local labels = {}
|
local labels = {}
|
||||||
for w in name:gmatch("([%w-]+)%.?") do
|
for w in name:gmatch("([_%w%-]+)%.?") do
|
||||||
table.insert(labels, string.pack("s1",w))
|
table.insert(labels, string.pack("s1",w))
|
||||||
end
|
end
|
||||||
table.insert(labels, '\0')
|
table.insert(labels, '\0')
|
||||||
@@ -249,8 +249,8 @@ function dns.server(server, port)
|
|||||||
end
|
end
|
||||||
assert(server, "Can't get nameserver")
|
assert(server, "Can't get nameserver")
|
||||||
end
|
end
|
||||||
dns_server = socket.udp(function(data, sz, from)
|
dns_server = socket.udp(function(str, from)
|
||||||
resolve(skynet.tostring(data,sz))
|
resolve(str)
|
||||||
end)
|
end)
|
||||||
socket.udp_connect(dns_server, server, port or 53)
|
socket.udp_connect(dns_server, server, port or 53)
|
||||||
return server
|
return server
|
||||||
@@ -282,7 +282,7 @@ function dns.resolve(name, ipv6)
|
|||||||
qdcount = 1,
|
qdcount = 1,
|
||||||
}
|
}
|
||||||
local req = pack_header(question_header) .. pack_question(name, qtype, QCLASS.IN)
|
local req = pack_header(question_header) .. pack_question(name, qtype, QCLASS.IN)
|
||||||
assert(dns_server, "Call dns.server fist")
|
assert(dns_server, "Call dns.server first")
|
||||||
socket.write(dns_server, req)
|
socket.write(dns_server, req)
|
||||||
return suspend(question_header.tid, name, qtype)
|
return suspend(question_header.tid, name, qtype)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -11,21 +11,21 @@ local function request(fd, method, host, url, recvheader, header, content)
|
|||||||
local write = socket.writefunc(fd)
|
local write = socket.writefunc(fd)
|
||||||
local header_content = ""
|
local header_content = ""
|
||||||
if header then
|
if header then
|
||||||
|
if not header.host then
|
||||||
|
header.host = host
|
||||||
|
end
|
||||||
for k,v in pairs(header) do
|
for k,v in pairs(header) do
|
||||||
header_content = string.format("%s%s:%s\r\n", header_content, k, v)
|
header_content = string.format("%s%s:%s\r\n", header_content, k, v)
|
||||||
end
|
end
|
||||||
if header.host then
|
|
||||||
host = ""
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
host = string.format("host:%s\r\n",host)
|
header_content = string.format("host:%s\r\n",host)
|
||||||
end
|
end
|
||||||
|
|
||||||
if content then
|
if content then
|
||||||
local data = string.format("%s %s HTTP/1.1\r\n%scontent-length:%d\r\n%s\r\n%s", method, url, host, #content, header_content, content)
|
local data = string.format("%s %s HTTP/1.1\r\n%scontent-length:%d\r\n\r\n%s", method, url, header_content, #content, content)
|
||||||
write(data)
|
write(data)
|
||||||
else
|
else
|
||||||
local request_header = string.format("%s %s HTTP/1.1\r\nhost:%s\r\ncontent-length:0\r\n%s\r\n", method, url, host, header_content)
|
local request_header = string.format("%s %s HTTP/1.1\r\n%scontent-length:0\r\n\r\n", method, url, header_content)
|
||||||
write(request_header)
|
write(request_header)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -30,12 +30,14 @@ function sharemap.writer(typename, obj)
|
|||||||
local sp = loadsp()
|
local sp = loadsp()
|
||||||
obj = obj or {}
|
obj = obj or {}
|
||||||
local stmobj = stm.new(sp:encode(typename,obj))
|
local stmobj = stm.new(sp:encode(typename,obj))
|
||||||
obj.__typename = typename
|
local ret = {
|
||||||
obj.__obj = stmobj
|
__typename = typename,
|
||||||
obj.__data = obj
|
__obj = stmobj,
|
||||||
obj.commit = sharemap.commit
|
__data = obj,
|
||||||
obj.copy = sharemap.copy
|
commit = sharemap.commit,
|
||||||
return setmetatable(obj, { __index = obj.__data, __newindex = obj.__data })
|
copy = sharemap.copy,
|
||||||
|
}
|
||||||
|
return setmetatable(ret, { __index = obj, __newindex = obj })
|
||||||
end
|
end
|
||||||
|
|
||||||
local function decode(msg, sz, self)
|
local function decode(msg, sz, self)
|
||||||
@@ -63,7 +65,7 @@ function sharemap.reader(typename, stmcpy)
|
|||||||
__data = data,
|
__data = data,
|
||||||
update = sharemap.update,
|
update = sharemap.update,
|
||||||
}
|
}
|
||||||
return setmetatable(obj, { __index = obj.__data, __newindex = error })
|
return setmetatable(obj, { __index = data, __newindex = error })
|
||||||
end
|
end
|
||||||
|
|
||||||
return sharemap
|
return sharemap
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ local session_id_coroutine = {}
|
|||||||
local session_coroutine_id = {}
|
local session_coroutine_id = {}
|
||||||
local session_coroutine_address = {}
|
local session_coroutine_address = {}
|
||||||
local session_response = {}
|
local session_response = {}
|
||||||
|
local unresponse = {}
|
||||||
|
|
||||||
local wakeup_session = {}
|
local wakeup_session = {}
|
||||||
local sleep_session = {}
|
local sleep_session = {}
|
||||||
@@ -96,7 +97,6 @@ end
|
|||||||
|
|
||||||
local coroutine_pool = {}
|
local coroutine_pool = {}
|
||||||
local coroutine_yield = coroutine.yield
|
local coroutine_yield = coroutine.yield
|
||||||
local coroutine_count = 0
|
|
||||||
|
|
||||||
local function co_create(f)
|
local function co_create(f)
|
||||||
local co = table.remove(coroutine_pool)
|
local co = table.remove(coroutine_pool)
|
||||||
@@ -110,11 +110,6 @@ local function co_create(f)
|
|||||||
f(coroutine_yield())
|
f(coroutine_yield())
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
coroutine_count = coroutine_count + 1
|
|
||||||
if coroutine_count > 1024 then
|
|
||||||
skynet.error("May overload, create 1024 task")
|
|
||||||
coroutine_count = 0
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
coroutine.resume(co, f)
|
coroutine.resume(co, f)
|
||||||
end
|
end
|
||||||
@@ -128,7 +123,7 @@ local function dispatch_wakeup()
|
|||||||
local session = sleep_session[co]
|
local session = sleep_session[co]
|
||||||
if session then
|
if session then
|
||||||
session_id_coroutine[session] = "BREAK"
|
session_id_coroutine[session] = "BREAK"
|
||||||
return suspend(co, coroutine.resume(co, true, "BREAK"))
|
return suspend(co, coroutine.resume(co, false, "BREAK"))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -175,7 +170,11 @@ function suspend(co, result, command, param, size)
|
|||||||
local ret
|
local ret
|
||||||
if not dead_service[co_address] then
|
if not dead_service[co_address] then
|
||||||
ret = c.send(co_address, skynet.PTYPE_RESPONSE, co_session, param, size) ~= nil
|
ret = c.send(co_address, skynet.PTYPE_RESPONSE, co_session, param, size) ~= nil
|
||||||
elseif size == nil then
|
if not ret then
|
||||||
|
-- If the package is too large, returns nil. so we should report error back
|
||||||
|
c.send(co_address, skynet.PTYPE_ERROR, co_session, "")
|
||||||
|
end
|
||||||
|
elseif size ~= nil then
|
||||||
c.trash(param, size)
|
c.trash(param, size)
|
||||||
ret = false
|
ret = false
|
||||||
end
|
end
|
||||||
@@ -209,6 +208,10 @@ function suspend(co, result, command, param, size)
|
|||||||
if not dead_service[co_address] then
|
if not dead_service[co_address] then
|
||||||
if ok then
|
if ok then
|
||||||
ret = c.send(co_address, skynet.PTYPE_RESPONSE, co_session, f(...)) ~= nil
|
ret = c.send(co_address, skynet.PTYPE_RESPONSE, co_session, f(...)) ~= nil
|
||||||
|
if not ret then
|
||||||
|
-- If the package is too large, returns false. so we should report error back
|
||||||
|
c.send(co_address, skynet.PTYPE_ERROR, co_session, "")
|
||||||
|
end
|
||||||
else
|
else
|
||||||
ret = c.send(co_address, skynet.PTYPE_ERROR, co_session, "") ~= nil
|
ret = c.send(co_address, skynet.PTYPE_ERROR, co_session, "") ~= nil
|
||||||
end
|
end
|
||||||
@@ -216,11 +219,13 @@ function suspend(co, result, command, param, size)
|
|||||||
ret = false
|
ret = false
|
||||||
end
|
end
|
||||||
release_watching(co_address)
|
release_watching(co_address)
|
||||||
|
unresponse[response] = nil
|
||||||
f = nil
|
f = nil
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
watching_service[co_address] = watching_service[co_address] + 1
|
watching_service[co_address] = watching_service[co_address] + 1
|
||||||
session_response[co] = response
|
session_response[co] = response
|
||||||
|
unresponse[response] = true
|
||||||
return suspend(co, coroutine.resume(co, response))
|
return suspend(co, coroutine.resume(co, response))
|
||||||
elseif command == "EXIT" then
|
elseif command == "EXIT" then
|
||||||
-- coroutine exit
|
-- coroutine exit
|
||||||
@@ -257,9 +262,13 @@ function skynet.sleep(ti)
|
|||||||
session = tonumber(session)
|
session = tonumber(session)
|
||||||
local succ, ret = coroutine_yield("SLEEP", session)
|
local succ, ret = coroutine_yield("SLEEP", session)
|
||||||
sleep_session[coroutine.running()] = nil
|
sleep_session[coroutine.running()] = nil
|
||||||
assert(succ, ret)
|
if succ then
|
||||||
|
return
|
||||||
|
end
|
||||||
if ret == "BREAK" then
|
if ret == "BREAK" then
|
||||||
return "BREAK"
|
return "BREAK"
|
||||||
|
else
|
||||||
|
error(ret)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -269,41 +278,12 @@ end
|
|||||||
|
|
||||||
function skynet.wait()
|
function skynet.wait()
|
||||||
local session = c.genid()
|
local session = c.genid()
|
||||||
coroutine_yield("SLEEP", session)
|
local ret, msg = coroutine_yield("SLEEP", session)
|
||||||
local co = coroutine.running()
|
local co = coroutine.running()
|
||||||
sleep_session[co] = nil
|
sleep_session[co] = nil
|
||||||
session_id_coroutine[session] = nil
|
session_id_coroutine[session] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local function globalname(name, handle)
|
|
||||||
local c = string.sub(name,1,1)
|
|
||||||
assert(c ~= ':')
|
|
||||||
if c == '.' then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
assert(#name <= 16) -- GLOBALNAME_LENGTH is 16, defined in skynet_harbor.h
|
|
||||||
assert(tonumber(name) == nil) -- global name can't be number
|
|
||||||
|
|
||||||
local harbor = require "skynet.harbor"
|
|
||||||
|
|
||||||
harbor.globalname(name, handle)
|
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
function skynet.register(name)
|
|
||||||
if not globalname(name) then
|
|
||||||
c.command("REG", name)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function skynet.name(name, handle)
|
|
||||||
if not globalname(name, handle) then
|
|
||||||
c.command("NAME", name .. " " .. skynet.address(handle))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local self_handle
|
local self_handle
|
||||||
function skynet.self()
|
function skynet.self()
|
||||||
if self_handle then
|
if self_handle then
|
||||||
@@ -320,13 +300,6 @@ function skynet.localname(name)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function skynet.launch(...)
|
|
||||||
local addr = c.command("LAUNCH", table.concat({...}," "))
|
|
||||||
if addr then
|
|
||||||
return string_to_handle(addr)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function skynet.now()
|
function skynet.now()
|
||||||
return tonumber(c.command("NOW"))
|
return tonumber(c.command("NOW"))
|
||||||
end
|
end
|
||||||
@@ -349,6 +322,9 @@ function skynet.exit()
|
|||||||
c.redirect(address, 0, skynet.PTYPE_ERROR, session, "")
|
c.redirect(address, 0, skynet.PTYPE_ERROR, session, "")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
for resp in pairs(unresponse) do
|
||||||
|
resp(false)
|
||||||
|
end
|
||||||
-- report the sources I call but haven't return
|
-- report the sources I call but haven't return
|
||||||
local tmp = {}
|
local tmp = {}
|
||||||
for session, address in pairs(watching_session) do
|
for session, address in pairs(watching_session) do
|
||||||
@@ -362,14 +338,6 @@ function skynet.exit()
|
|||||||
coroutine_yield "QUIT"
|
coroutine_yield "QUIT"
|
||||||
end
|
end
|
||||||
|
|
||||||
function skynet.kill(name)
|
|
||||||
if type(name) == "number" then
|
|
||||||
skynet.send(".launcher","lua","REMOVE",name, true)
|
|
||||||
name = skynet.address(name)
|
|
||||||
end
|
|
||||||
c.command("KILL",name)
|
|
||||||
end
|
|
||||||
|
|
||||||
function skynet.getenv(key)
|
function skynet.getenv(key)
|
||||||
local ret = c.command("GETENV",key)
|
local ret = c.command("GETENV",key)
|
||||||
if ret == "" then
|
if ret == "" then
|
||||||
@@ -398,13 +366,14 @@ skynet.pack = assert(c.pack)
|
|||||||
skynet.packstring = assert(c.packstring)
|
skynet.packstring = assert(c.packstring)
|
||||||
skynet.unpack = assert(c.unpack)
|
skynet.unpack = assert(c.unpack)
|
||||||
skynet.tostring = assert(c.tostring)
|
skynet.tostring = assert(c.tostring)
|
||||||
|
skynet.trash = assert(c.trash)
|
||||||
|
|
||||||
local function yield_call(service, session)
|
local function yield_call(service, session)
|
||||||
watching_session[session] = service
|
watching_session[session] = service
|
||||||
local succ, msg, sz = coroutine_yield("CALL", session)
|
local succ, msg, sz = coroutine_yield("CALL", session)
|
||||||
watching_session[session] = nil
|
watching_session[session] = nil
|
||||||
if not succ then
|
if not succ then
|
||||||
error(debug.traceback())
|
error "call failed"
|
||||||
end
|
end
|
||||||
return msg,sz
|
return msg,sz
|
||||||
end
|
end
|
||||||
@@ -463,7 +432,7 @@ function skynet.dispatch_unknown_request(unknown)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function unknown_response(session, address, msg, sz)
|
local function unknown_response(session, address, msg, sz)
|
||||||
skynet.error(string.format("Response message :" , c.tostring(msg,sz)))
|
skynet.error(string.format("Response message : %s" , c.tostring(msg,sz)))
|
||||||
error(string.format("Unknown session : %d from %x", session, address))
|
error(string.format("Unknown session : %d from %x", session, address))
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -481,6 +450,7 @@ function skynet.fork(func,...)
|
|||||||
func(tunpack(args))
|
func(tunpack(args))
|
||||||
end)
|
end)
|
||||||
table.insert(fork_queue, co)
|
table.insert(fork_queue, co)
|
||||||
|
return co
|
||||||
end
|
end
|
||||||
|
|
||||||
local function raw_dispatch_message(prototype, msg, sz, session, source, ...)
|
local function raw_dispatch_message(prototype, msg, sz, session, source, ...)
|
||||||
@@ -510,12 +480,12 @@ local function raw_dispatch_message(prototype, msg, sz, session, source, ...)
|
|||||||
session_coroutine_address[co] = source
|
session_coroutine_address[co] = source
|
||||||
suspend(co, coroutine.resume(co, session,source, p.unpack(msg,sz, ...)))
|
suspend(co, coroutine.resume(co, session,source, p.unpack(msg,sz, ...)))
|
||||||
else
|
else
|
||||||
unknown_request(session, source, msg, sz, proto[prototype])
|
unknown_request(session, source, msg, sz, proto[prototype].name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function dispatch_message(...)
|
function skynet.dispatch_message(...)
|
||||||
local succ, err = pcall(raw_dispatch_message,...)
|
local succ, err = pcall(raw_dispatch_message,...)
|
||||||
while true do
|
while true do
|
||||||
local key,co = next(fork_queue)
|
local key,co = next(fork_queue)
|
||||||
@@ -619,8 +589,10 @@ end
|
|||||||
local function init_all()
|
local function init_all()
|
||||||
local funcs = init_func
|
local funcs = init_func
|
||||||
init_func = nil
|
init_func = nil
|
||||||
for k,v in pairs(funcs) do
|
if funcs then
|
||||||
v()
|
for k,v in pairs(funcs) do
|
||||||
|
v()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -631,8 +603,12 @@ local function init_template(start)
|
|||||||
init_all()
|
init_all()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function init_service(start)
|
function skynet.pcall(start)
|
||||||
local ok, err = xpcall(init_template, debug.traceback, start)
|
return xpcall(init_template, debug.traceback, start)
|
||||||
|
end
|
||||||
|
|
||||||
|
function skynet.init_service(start)
|
||||||
|
local ok, err = skynet.pcall(start)
|
||||||
if not ok then
|
if not ok then
|
||||||
skynet.error("init service failed: " .. tostring(err))
|
skynet.error("init service failed: " .. tostring(err))
|
||||||
skynet.send(".launcher","lua", "ERROR")
|
skynet.send(".launcher","lua", "ERROR")
|
||||||
@@ -643,33 +619,9 @@ local function init_service(start)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function skynet.start(start_func)
|
function skynet.start(start_func)
|
||||||
c.callback(dispatch_message)
|
c.callback(skynet.dispatch_message)
|
||||||
skynet.timeout(0, function()
|
skynet.timeout(0, function()
|
||||||
init_service(start_func)
|
skynet.init_service(start_func)
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
function skynet.filter(f ,start_func)
|
|
||||||
c.callback(function(...)
|
|
||||||
dispatch_message(f(...))
|
|
||||||
end)
|
|
||||||
skynet.timeout(0, function()
|
|
||||||
init_service(start_func)
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
function skynet.forward_type(map, start_func)
|
|
||||||
c.callback(function(ptype, msg, sz, ...)
|
|
||||||
local prototype = map[ptype]
|
|
||||||
if prototype then
|
|
||||||
dispatch_message(prototype, msg, sz, ...)
|
|
||||||
else
|
|
||||||
dispatch_message(ptype, msg, sz, ...)
|
|
||||||
c.trash(msg, sz)
|
|
||||||
end
|
|
||||||
end, true)
|
|
||||||
skynet.timeout(0, function()
|
|
||||||
init_service(start_func)
|
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -677,22 +629,6 @@ function skynet.endless()
|
|||||||
return c.command("ENDLESS")~=nil
|
return c.command("ENDLESS")~=nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function skynet.abort()
|
|
||||||
c.command("ABORT")
|
|
||||||
end
|
|
||||||
|
|
||||||
function skynet.monitor(service, query)
|
|
||||||
local monitor
|
|
||||||
if query then
|
|
||||||
monitor = skynet.queryservice(true, service)
|
|
||||||
else
|
|
||||||
monitor = skynet.uniqueservice(true, service)
|
|
||||||
end
|
|
||||||
assert(monitor, "Monitor launch failed")
|
|
||||||
c.command("MONITOR", string.format(":%08x", monitor))
|
|
||||||
return monitor
|
|
||||||
end
|
|
||||||
|
|
||||||
function skynet.mqlen()
|
function skynet.mqlen()
|
||||||
return tonumber(c.command "MQLEN")
|
return tonumber(c.command "MQLEN")
|
||||||
end
|
end
|
||||||
@@ -719,7 +655,7 @@ end
|
|||||||
-- Inject internal debug framework
|
-- Inject internal debug framework
|
||||||
local debug = require "skynet.debug"
|
local debug = require "skynet.debug"
|
||||||
debug(skynet, {
|
debug(skynet, {
|
||||||
dispatch = dispatch_message,
|
dispatch = skynet.dispatch_message,
|
||||||
clear = clear_pool,
|
clear = clear_pool,
|
||||||
suspend = suspend,
|
suspend = suspend,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ end
|
|||||||
|
|
||||||
function dbgcmd.RUN(source, filename)
|
function dbgcmd.RUN(source, filename)
|
||||||
local inject = require "skynet.inject"
|
local inject = require "skynet.inject"
|
||||||
local output = inject(source, filename , export.dispatch, skynet.register_protocol)
|
local output = inject(skynet, source, filename , export.dispatch, skynet.register_protocol)
|
||||||
collectgarbage "collect"
|
collectgarbage "collect"
|
||||||
skynet.ret(skynet.pack(table.concat(output, "\n")))
|
skynet.ret(skynet.pack(table.concat(output, "\n")))
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
local function getupvaluetable(u, func, unique)
|
local function getupvaluetable(u, func, unique)
|
||||||
i = 1
|
local i = 1
|
||||||
while true do
|
while true do
|
||||||
local name, value = debug.getupvalue(func, i)
|
local name, value = debug.getupvalue(func, i)
|
||||||
if name == nil then
|
if name == nil then
|
||||||
@@ -18,7 +18,7 @@ local function getupvaluetable(u, func, unique)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return function(source, filename , ...)
|
return function(skynet, source, filename , ...)
|
||||||
if filename then
|
if filename then
|
||||||
filename = "@" .. filename
|
filename = "@" .. filename
|
||||||
else
|
else
|
||||||
@@ -44,7 +44,7 @@ return function(source, filename , ...)
|
|||||||
if proto then
|
if proto then
|
||||||
for k,v in pairs(proto) do
|
for k,v in pairs(proto) do
|
||||||
local name, dispatch = v.name, v.dispatch
|
local name, dispatch = v.name, v.dispatch
|
||||||
if name and dispatch then
|
if name and dispatch and not p[name] then
|
||||||
local pp = {}
|
local pp = {}
|
||||||
p[name] = pp
|
p[name] = pp
|
||||||
getupvaluetable(pp, dispatch, unique)
|
getupvaluetable(pp, dispatch, unique)
|
||||||
@@ -56,7 +56,7 @@ return function(source, filename , ...)
|
|||||||
if not func then
|
if not func then
|
||||||
return { err }
|
return { err }
|
||||||
end
|
end
|
||||||
local ok, err = xpcall(func, debug.traceback)
|
local ok, err = skynet.pcall(func)
|
||||||
if not ok then
|
if not ok then
|
||||||
table.insert(output, err)
|
table.insert(output, err)
|
||||||
end
|
end
|
||||||
|
|||||||
90
lualib/skynet/manager.lua
Normal file
90
lualib/skynet/manager.lua
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
local skynet = require "skynet"
|
||||||
|
local c = require "skynet.core"
|
||||||
|
|
||||||
|
function skynet.launch(...)
|
||||||
|
local addr = c.command("LAUNCH", table.concat({...}," "))
|
||||||
|
if addr then
|
||||||
|
return tonumber("0x" .. string.sub(addr , 2))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function skynet.kill(name)
|
||||||
|
if type(name) == "number" then
|
||||||
|
skynet.send(".launcher","lua","REMOVE",name, true)
|
||||||
|
name = skynet.address(name)
|
||||||
|
end
|
||||||
|
c.command("KILL",name)
|
||||||
|
end
|
||||||
|
|
||||||
|
function skynet.abort()
|
||||||
|
c.command("ABORT")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function globalname(name, handle)
|
||||||
|
local c = string.sub(name,1,1)
|
||||||
|
assert(c ~= ':')
|
||||||
|
if c == '.' then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(#name <= 16) -- GLOBALNAME_LENGTH is 16, defined in skynet_harbor.h
|
||||||
|
assert(tonumber(name) == nil) -- global name can't be number
|
||||||
|
|
||||||
|
local harbor = require "skynet.harbor"
|
||||||
|
|
||||||
|
harbor.globalname(name, handle)
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function skynet.register(name)
|
||||||
|
if not globalname(name) then
|
||||||
|
c.command("REG", name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function skynet.name(name, handle)
|
||||||
|
if not globalname(name, handle) then
|
||||||
|
c.command("NAME", name .. " " .. skynet.address(handle))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local dispatch_message = skynet.dispatch_message
|
||||||
|
|
||||||
|
function skynet.forward_type(map, start_func)
|
||||||
|
c.callback(function(ptype, msg, sz, ...)
|
||||||
|
local prototype = map[ptype]
|
||||||
|
if prototype then
|
||||||
|
dispatch_message(prototype, msg, sz, ...)
|
||||||
|
else
|
||||||
|
dispatch_message(ptype, msg, sz, ...)
|
||||||
|
c.trash(msg, sz)
|
||||||
|
end
|
||||||
|
end, true)
|
||||||
|
skynet.timeout(0, function()
|
||||||
|
skynet.init_service(start_func)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
function skynet.filter(f ,start_func)
|
||||||
|
c.callback(function(...)
|
||||||
|
dispatch_message(f(...))
|
||||||
|
end)
|
||||||
|
skynet.timeout(0, function()
|
||||||
|
skynet.init_service(start_func)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
function skynet.monitor(service, query)
|
||||||
|
local monitor
|
||||||
|
if query then
|
||||||
|
monitor = skynet.queryservice(true, service)
|
||||||
|
else
|
||||||
|
monitor = skynet.uniqueservice(true, service)
|
||||||
|
end
|
||||||
|
assert(monitor, "Monitor launch failed")
|
||||||
|
c.command("MONITOR", string.format(":%08x", monitor))
|
||||||
|
return monitor
|
||||||
|
end
|
||||||
|
|
||||||
|
return skynet
|
||||||
@@ -162,4 +162,8 @@ function snax.hotfix(obj, source, ...)
|
|||||||
return test_result(skynet_call(obj.handle, "snax", t.system.hotfix, source, ...))
|
return test_result(skynet_call(obj.handle, "snax", t.system.hotfix, source, ...))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function snax.printf(fmt, ...)
|
||||||
|
skynet.error(string.format(fmt, ...))
|
||||||
|
end
|
||||||
|
|
||||||
return snax
|
return snax
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ return function (name , G, loader)
|
|||||||
local pattern
|
local pattern
|
||||||
|
|
||||||
do
|
do
|
||||||
local path = skynet.getenv "snax"
|
local path = assert(skynet.getenv "snax" , "please set snax in config file")
|
||||||
|
|
||||||
local errlist = {}
|
local errlist = {}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
local skynet = require "skynet"
|
local skynet = require "skynet"
|
||||||
|
require "skynet.manager"
|
||||||
local socket = require "socket"
|
local socket = require "socket"
|
||||||
local crypt = require "crypt"
|
local crypt = require "crypt"
|
||||||
local table = table
|
local table = table
|
||||||
@@ -33,17 +34,17 @@ Success:
|
|||||||
]]
|
]]
|
||||||
|
|
||||||
local socket_error = {}
|
local socket_error = {}
|
||||||
local function assert_socket(v, fd)
|
local function assert_socket(service, v, fd)
|
||||||
if v then
|
if v then
|
||||||
return v
|
return v
|
||||||
else
|
else
|
||||||
skynet.error(string.format("auth failed: socket (fd = %d) closed", fd))
|
skynet.error(string.format("%s failed: socket (fd = %d) closed", service, fd))
|
||||||
error(socket_error)
|
error(socket_error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function write(fd, text)
|
local function write(service, fd, text)
|
||||||
assert_socket(socket.write(fd, text), fd)
|
assert_socket(service, socket.write(fd, text), fd)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function launch_slave(auth_handler)
|
local function launch_slave(auth_handler)
|
||||||
@@ -57,27 +58,27 @@ local function launch_slave(auth_handler)
|
|||||||
socket.limit(fd, 8192)
|
socket.limit(fd, 8192)
|
||||||
|
|
||||||
local challenge = crypt.randomkey()
|
local challenge = crypt.randomkey()
|
||||||
write(fd, crypt.base64encode(challenge).."\n")
|
write("auth", fd, crypt.base64encode(challenge).."\n")
|
||||||
|
|
||||||
local handshake = assert_socket(socket.readline(fd), fd)
|
local handshake = assert_socket("auth", socket.readline(fd), fd)
|
||||||
local clientkey = crypt.base64decode(handshake)
|
local clientkey = crypt.base64decode(handshake)
|
||||||
if #clientkey ~= 8 then
|
if #clientkey ~= 8 then
|
||||||
error "Invalid client key"
|
error "Invalid client key"
|
||||||
end
|
end
|
||||||
local serverkey = crypt.randomkey()
|
local serverkey = crypt.randomkey()
|
||||||
write(fd, crypt.base64encode(crypt.dhexchange(serverkey)).."\n")
|
write("auth", fd, crypt.base64encode(crypt.dhexchange(serverkey)).."\n")
|
||||||
|
|
||||||
local secret = crypt.dhsecret(clientkey, serverkey)
|
local secret = crypt.dhsecret(clientkey, serverkey)
|
||||||
|
|
||||||
local response = assert_socket(socket.readline(fd), fd)
|
local response = assert_socket("auth", socket.readline(fd), fd)
|
||||||
local hmac = crypt.hmac64(challenge, secret)
|
local hmac = crypt.hmac64(challenge, secret)
|
||||||
|
|
||||||
if hmac ~= crypt.base64decode(response) then
|
if hmac ~= crypt.base64decode(response) then
|
||||||
write(fd, "400 Bad Request\n")
|
write("auth", fd, "400 Bad Request\n")
|
||||||
error "challenge failed"
|
error "challenge failed"
|
||||||
end
|
end
|
||||||
|
|
||||||
local etoken = assert_socket(socket.readline(fd),fd)
|
local etoken = assert_socket("auth", socket.readline(fd),fd)
|
||||||
|
|
||||||
local token = crypt.desdecode(secret, crypt.base64decode(etoken))
|
local token = crypt.desdecode(secret, crypt.base64decode(etoken))
|
||||||
|
|
||||||
@@ -91,7 +92,11 @@ local function launch_slave(auth_handler)
|
|||||||
if ok then
|
if ok then
|
||||||
skynet.ret(skynet.pack(err, ...))
|
skynet.ret(skynet.pack(err, ...))
|
||||||
else
|
else
|
||||||
error(err)
|
if err == socket_error then
|
||||||
|
skynet.ret(skynet.pack(nil, "socket error"))
|
||||||
|
else
|
||||||
|
skynet.ret(skynet.pack(false, err))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -108,13 +113,15 @@ local function accept(conf, s, fd, addr)
|
|||||||
socket.start(fd)
|
socket.start(fd)
|
||||||
|
|
||||||
if not ok then
|
if not ok then
|
||||||
write(fd, "401 Unauthorized\n")
|
if ok ~= nil then
|
||||||
|
write("response 401", fd, "401 Unauthorized\n")
|
||||||
|
end
|
||||||
error(server)
|
error(server)
|
||||||
end
|
end
|
||||||
|
|
||||||
if not conf.multilogin then
|
if not conf.multilogin then
|
||||||
if user_login[uid] then
|
if user_login[uid] then
|
||||||
write(fd, "406 Not Acceptable\n")
|
write("response 406", fd, "406 Not Acceptable\n")
|
||||||
error(string.format("User %s is already login", uid))
|
error(string.format("User %s is already login", uid))
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -127,9 +134,9 @@ local function accept(conf, s, fd, addr)
|
|||||||
|
|
||||||
if ok then
|
if ok then
|
||||||
err = err or ""
|
err = err or ""
|
||||||
write(fd, "200 "..crypt.base64encode(err).."\n")
|
write("response 200",fd, "200 "..crypt.base64encode(err).."\n")
|
||||||
else
|
else
|
||||||
write(fd, "403 Forbidden\n")
|
write("response 403",fd, "403 Forbidden\n")
|
||||||
error(err)
|
error(err)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ function server.start(conf)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local text = string.format("%s:%s", username, index)
|
local text = string.format("%s:%s", username, index)
|
||||||
local v = crypt.hmac64(crypt.hashkey(text), u.secret)
|
local v = crypt.hmac_hash(u.secret, text) -- equivalent to crypt.hmac64(crypt.hashkey(text), u.secret)
|
||||||
if v ~= hmac then
|
if v ~= hmac then
|
||||||
return "401 Unauthorized"
|
return "401 Unauthorized"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
local driver = require "socketdriver"
|
local driver = require "socketdriver"
|
||||||
local skynet = require "skynet"
|
local skynet = require "skynet"
|
||||||
|
local skynet_core = require "skynet.core"
|
||||||
local assert = assert
|
local assert = assert
|
||||||
|
|
||||||
local socket = {} -- api
|
local socket = {} -- api
|
||||||
@@ -127,7 +128,9 @@ socket_message[6] = function(id, size, data, address)
|
|||||||
driver.drop(data, size)
|
driver.drop(data, size)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
s.callback(data, size, address)
|
local str = skynet.tostring(data, size)
|
||||||
|
skynet_core.trash(data, size)
|
||||||
|
s.callback(str, address)
|
||||||
end
|
end
|
||||||
|
|
||||||
skynet.register_protocol {
|
skynet.register_protocol {
|
||||||
|
|||||||
@@ -13,14 +13,23 @@ function sproto_mt:__gc()
|
|||||||
core.deleteproto(self.__cobj)
|
core.deleteproto(self.__cobj)
|
||||||
end
|
end
|
||||||
|
|
||||||
function sproto.new(bin,sz,nogc)
|
function sproto.new(bin)
|
||||||
local cobj = assert(core.newproto(bin,sz))
|
local cobj = assert(core.newproto(bin))
|
||||||
local self = {
|
local self = {
|
||||||
__cobj = cobj,
|
__cobj = cobj,
|
||||||
__tcache = setmetatable( {} , weak_mt ),
|
__tcache = setmetatable( {} , weak_mt ),
|
||||||
__pcache = setmetatable( {} , weak_mt ),
|
__pcache = setmetatable( {} , weak_mt ),
|
||||||
}
|
}
|
||||||
return setmetatable(self, nogc and sproto_nogc or sproto_mt)
|
return setmetatable(self, sproto_mt)
|
||||||
|
end
|
||||||
|
|
||||||
|
function sproto.sharenew(cobj)
|
||||||
|
local self = {
|
||||||
|
__cobj = cobj,
|
||||||
|
__tcache = setmetatable( {} , weak_mt ),
|
||||||
|
__pcache = setmetatable( {} , weak_mt ),
|
||||||
|
}
|
||||||
|
return setmetatable(self, sproto_nogc)
|
||||||
end
|
end
|
||||||
|
|
||||||
function sproto.parse(ptext)
|
function sproto.parse(ptext)
|
||||||
@@ -90,6 +99,66 @@ local function queryproto(self, pname)
|
|||||||
return v
|
return v
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function sproto:request_encode(protoname, tbl)
|
||||||
|
local p = queryproto(self, protoname)
|
||||||
|
local request = p.request
|
||||||
|
if request then
|
||||||
|
return core.encode(request,tbl) , p.tag
|
||||||
|
else
|
||||||
|
return "" , p.tag
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function sproto:response_encode(protoname, tbl)
|
||||||
|
local p = queryproto(self, protoname)
|
||||||
|
local response = p.response
|
||||||
|
if response then
|
||||||
|
return core.encode(response,tbl)
|
||||||
|
else
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function sproto:request_decode(protoname, ...)
|
||||||
|
local p = queryproto(self, protoname)
|
||||||
|
local request = p.request
|
||||||
|
if request then
|
||||||
|
return core.decode(request,...) , p.name
|
||||||
|
else
|
||||||
|
return nil, p.name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function sproto:response_decode(protoname, ...)
|
||||||
|
local p = queryproto(self, protoname)
|
||||||
|
local response = p.response
|
||||||
|
if response then
|
||||||
|
return core.decode(response,...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
sproto.pack = core.pack
|
||||||
|
sproto.unpack = core.unpack
|
||||||
|
|
||||||
|
function sproto:default(typename, type)
|
||||||
|
if type == nil then
|
||||||
|
return core.default(querytype(self, typename))
|
||||||
|
else
|
||||||
|
local p = queryproto(self, typename)
|
||||||
|
if type == "REQUEST" then
|
||||||
|
if p.request then
|
||||||
|
return core.default(p.request)
|
||||||
|
end
|
||||||
|
elseif type == "RESPONSE" then
|
||||||
|
if p.response then
|
||||||
|
return core.default(p.response)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error "Invalid type"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local header_tmp = {}
|
local header_tmp = {}
|
||||||
|
|
||||||
local function gen_response(self, response, session)
|
local function gen_response(self, response, session)
|
||||||
|
|||||||
@@ -8,16 +8,19 @@ function loader.register(filename, index)
|
|||||||
local f = assert(io.open(filename), "Can't open sproto file")
|
local f = assert(io.open(filename), "Can't open sproto file")
|
||||||
local data = f:read "a"
|
local data = f:read "a"
|
||||||
f:close()
|
f:close()
|
||||||
local bin = parser.parse(data)
|
local sp = core.newproto(parser.parse(data))
|
||||||
core.saveproto(bin, index)
|
core.saveproto(sp, index)
|
||||||
end
|
end
|
||||||
|
|
||||||
loader.save = core.saveproto
|
function loader.save(bin, index)
|
||||||
|
local sp = core.newproto(bin)
|
||||||
|
core.saveproto(sp, index)
|
||||||
|
end
|
||||||
|
|
||||||
function loader.load(index)
|
function loader.load(index)
|
||||||
local bin, sz = core.loadproto(index)
|
local sp = core.loadproto(index)
|
||||||
-- no __gc in metatable
|
-- no __gc in metatable
|
||||||
return sproto.new(bin,sz, true)
|
return sproto.sharenew(sp)
|
||||||
end
|
end
|
||||||
|
|
||||||
return loader
|
return loader
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ local function check_protocol(r)
|
|||||||
local request = v.request
|
local request = v.request
|
||||||
local response = v.response
|
local response = v.response
|
||||||
local p = map[tag]
|
local p = map[tag]
|
||||||
|
|
||||||
if p then
|
if p then
|
||||||
error(string.format("redefined protocol tag %d at %s", tag, name))
|
error(string.format("redefined protocol tag %d at %s", tag, name))
|
||||||
end
|
end
|
||||||
@@ -340,9 +340,6 @@ local function packtype(name, t, alltypes)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function packproto(name, p, alltypes)
|
local function packproto(name, p, alltypes)
|
||||||
-- if p.request == nil then
|
|
||||||
-- error(string.format("Protocol %s need request", name))
|
|
||||||
-- end
|
|
||||||
if p.request then
|
if p.request then
|
||||||
local request = alltypes[p.request]
|
local request = alltypes[p.request]
|
||||||
if request == nil then
|
if request == nil then
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ _ctrl(struct gate * g, const void * msg, int sz) {
|
|||||||
skynet_socket_start(ctx, g->listen_id);
|
skynet_socket_start(ctx, g->listen_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (memcmp(command, "close", i) == 0) {
|
if (memcmp(command, "close", i) == 0) {
|
||||||
if (g->listen_id >= 0) {
|
if (g->listen_id >= 0) {
|
||||||
skynet_socket_close(ctx, g->listen_id);
|
skynet_socket_close(ctx, g->listen_id);
|
||||||
g->listen_id = -1;
|
g->listen_id = -1;
|
||||||
|
|||||||
@@ -365,6 +365,7 @@ dispatch_name_queue(struct harbor *h, struct keyvalue * node) {
|
|||||||
while ((m = pop_queue(queue)) != NULL) {
|
while ((m = pop_queue(queue)) != NULL) {
|
||||||
m->header.destination |= (handle & HANDLE_MASK);
|
m->header.destination |= (handle & HANDLE_MASK);
|
||||||
send_remote(context, fd, m->buffer, m->size, &m->header);
|
send_remote(context, fd, m->buffer, m->size, &m->header);
|
||||||
|
skynet_free(m->buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,6 +382,7 @@ dispatch_queue(struct harbor *h, int id) {
|
|||||||
struct harbor_msg * m;
|
struct harbor_msg * m;
|
||||||
while ((m = pop_queue(queue)) != NULL) {
|
while ((m = pop_queue(queue)) != NULL) {
|
||||||
send_remote(h->ctx, fd, m->buffer, m->size, &m->header);
|
send_remote(h->ctx, fd, m->buffer, m->size, &m->header);
|
||||||
|
skynet_free(m->buffer);
|
||||||
}
|
}
|
||||||
release_queue(queue);
|
release_queue(queue);
|
||||||
s->queue = NULL;
|
s->queue = NULL;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
local skynet = require "skynet"
|
local skynet = require "skynet"
|
||||||
local harbor = require "skynet.harbor"
|
local harbor = require "skynet.harbor"
|
||||||
|
require "skynet.manager" -- import skynet.launch, ...
|
||||||
|
|
||||||
skynet.start(function()
|
skynet.start(function()
|
||||||
local standalone = skynet.getenv "standalone"
|
local standalone = skynet.getenv "standalone"
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
local skynet = require "skynet"
|
local skynet = require "skynet"
|
||||||
|
require "skynet.manager" -- import skynet.launch, ...
|
||||||
|
|
||||||
local globalname = {}
|
local globalname = {}
|
||||||
local queryname = {}
|
local queryname = {}
|
||||||
|
|||||||
@@ -5,14 +5,6 @@ local cluster = require "cluster.core"
|
|||||||
|
|
||||||
local config_name = skynet.getenv "cluster"
|
local config_name = skynet.getenv "cluster"
|
||||||
local node_address = {}
|
local node_address = {}
|
||||||
|
|
||||||
local function loadconfig()
|
|
||||||
local f = assert(io.open(config_name))
|
|
||||||
local source = f:read "*a"
|
|
||||||
f:close()
|
|
||||||
assert(load(source, "@"..config_name, "t", node_address))()
|
|
||||||
end
|
|
||||||
|
|
||||||
local node_session = {}
|
local node_session = {}
|
||||||
local command = {}
|
local command = {}
|
||||||
|
|
||||||
@@ -28,6 +20,7 @@ local function open_channel(t, key)
|
|||||||
host = host,
|
host = host,
|
||||||
port = tonumber(port),
|
port = tonumber(port),
|
||||||
response = read_response,
|
response = read_response,
|
||||||
|
nodelay = true,
|
||||||
}
|
}
|
||||||
assert(c:connect(true))
|
assert(c:connect(true))
|
||||||
t[key] = c
|
t[key] = c
|
||||||
@@ -37,6 +30,24 @@ end
|
|||||||
|
|
||||||
local node_channel = setmetatable({}, { __index = open_channel })
|
local node_channel = setmetatable({}, { __index = open_channel })
|
||||||
|
|
||||||
|
local function loadconfig()
|
||||||
|
local f = assert(io.open(config_name))
|
||||||
|
local source = f:read "*a"
|
||||||
|
f:close()
|
||||||
|
local tmp = {}
|
||||||
|
assert(load(source, "@"..config_name, "t", tmp))()
|
||||||
|
for name,address in pairs(tmp) do
|
||||||
|
assert(type(address) == "string")
|
||||||
|
if node_address[name] ~= address then
|
||||||
|
-- address changed
|
||||||
|
if rawget(node_channel, name) then
|
||||||
|
node_channel[name] = nil -- reset connection
|
||||||
|
end
|
||||||
|
node_address[name] = address
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function command.reload()
|
function command.reload()
|
||||||
loadconfig()
|
loadconfig()
|
||||||
skynet.ret(skynet.pack(nil))
|
skynet.ret(skynet.pack(nil))
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
local skynet = require "skynet"
|
local skynet = require "skynet"
|
||||||
local cluster = require "cluster"
|
local cluster = require "cluster"
|
||||||
|
require "skynet.manager" -- inject skynet.forward_type
|
||||||
|
|
||||||
local node, address = ...
|
local node, address = ...
|
||||||
|
|
||||||
@@ -10,6 +11,7 @@ skynet.register_protocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
local forward_map = {
|
local forward_map = {
|
||||||
|
[skynet.PTYPE_SNAX] = skynet.PTYPE_SYSTEM,
|
||||||
[skynet.PTYPE_LUA] = skynet.PTYPE_SYSTEM,
|
[skynet.PTYPE_LUA] = skynet.PTYPE_SYSTEM,
|
||||||
[skynet.PTYPE_RESPONSE] = skynet.PTYPE_RESPONSE, -- don't free response message
|
[skynet.PTYPE_RESPONSE] = skynet.PTYPE_RESPONSE, -- don't free response message
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,26 @@
|
|||||||
local skynet = require "skynet"
|
local skynet = require "skynet"
|
||||||
|
local snax = require "snax"
|
||||||
local socket = require "socket"
|
local socket = require "socket"
|
||||||
|
|
||||||
|
local function split_cmdline(cmdline)
|
||||||
|
local split = {}
|
||||||
|
for i in string.gmatch(cmdline, "%S+") do
|
||||||
|
table.insert(split,i)
|
||||||
|
end
|
||||||
|
return split
|
||||||
|
end
|
||||||
|
|
||||||
local function console_main_loop()
|
local function console_main_loop()
|
||||||
local stdin = socket.stdin()
|
local stdin = socket.stdin()
|
||||||
socket.lock(stdin)
|
socket.lock(stdin)
|
||||||
while true do
|
while true do
|
||||||
local cmdline = socket.readline(stdin, "\n")
|
local cmdline = socket.readline(stdin, "\n")
|
||||||
if cmdline ~= "" then
|
local split = split_cmdline(cmdline)
|
||||||
pcall(skynet.newservice,cmdline)
|
local command = split[1]
|
||||||
|
if command == "snax" then
|
||||||
|
pcall(snax.newservice, select(2, table.unpack(split)))
|
||||||
|
elseif cmdline ~= "" then
|
||||||
|
pcall(skynet.newservice, cmdline)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
socket.unlock(stdin)
|
socket.unlock(stdin)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
local skynet = require "skynet"
|
local skynet = require "skynet"
|
||||||
local socket = require "socket"
|
local socket = require "socket"
|
||||||
|
require "skynet.manager" -- import skynet.launch, ...
|
||||||
local table = table
|
local table = table
|
||||||
|
|
||||||
local slaves = {}
|
local slaves = {}
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ end
|
|||||||
|
|
||||||
local function adjust_address(address)
|
local function adjust_address(address)
|
||||||
if address:sub(1,1) ~= ":" then
|
if address:sub(1,1) ~= ":" then
|
||||||
address = tonumber("0x" .. address) | (skynet.harbor(skynet.self()) << 24)
|
address = assert(tonumber("0x" .. address), "Need an address") | (skynet.harbor(skynet.self()) << 24)
|
||||||
end
|
end
|
||||||
return address
|
return address
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
local skynet = require "skynet"
|
local skynet = require "skynet"
|
||||||
local core = require "skynet.core"
|
local core = require "skynet.core"
|
||||||
|
require "skynet.manager" -- import manager apis
|
||||||
local string = string
|
local string = string
|
||||||
|
|
||||||
local services = {}
|
local services = {}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
local skynet = require "skynet"
|
local skynet = require "skynet"
|
||||||
|
require "skynet.manager" -- import skynet.register
|
||||||
local snax = require "snax"
|
local snax = require "snax"
|
||||||
|
|
||||||
local cmd = {}
|
local cmd = {}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ function CMD.new(name, t)
|
|||||||
elseif dt == "string" then
|
elseif dt == "string" then
|
||||||
value = setmetatable({}, env_mt)
|
value = setmetatable({}, env_mt)
|
||||||
local f = load(t, "=" .. name, "t", value)
|
local f = load(t, "=" .. name, "t", value)
|
||||||
f()
|
assert(skynet.pcall(f))
|
||||||
setmetatable(value, nil)
|
setmetatable(value, nil)
|
||||||
elseif dt == "nil" then
|
elseif dt == "nil" then
|
||||||
value = {}
|
value = {}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ end
|
|||||||
|
|
||||||
skynet.start(function()
|
skynet.start(function()
|
||||||
local init = false
|
local init = false
|
||||||
skynet.dispatch("snax", function ( session , source , id, ...)
|
local function dispatcher( session , source , id, ...)
|
||||||
local method = func[id]
|
local method = func[id]
|
||||||
|
|
||||||
if method[2] == "system" then
|
if method[2] == "system" then
|
||||||
@@ -84,5 +84,11 @@ skynet.start(function()
|
|||||||
assert(init, "Init first")
|
assert(init, "Init first")
|
||||||
timing(method, ...)
|
timing(method, ...)
|
||||||
end
|
end
|
||||||
end)
|
end
|
||||||
|
skynet.dispatch("snax", dispatcher)
|
||||||
|
|
||||||
|
-- set lua dispatcher
|
||||||
|
function snax.enablecluster()
|
||||||
|
skynet.dispatch("lua", dispatcher)
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef __MALLOC_HOOK_H
|
#ifndef SKYNET_MALLOC_HOOK_H
|
||||||
#define __MALLOC_HOOK_H
|
#define SKYNET_MALLOC_HOOK_H
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@@ -10,5 +10,5 @@ extern size_t mallctl_int64(const char* name, size_t* newval);
|
|||||||
extern int mallctl_opt(const char* name, int* newval);
|
extern int mallctl_opt(const char* name, int* newval);
|
||||||
extern void dump_c_mem(void);
|
extern void dump_c_mem(void);
|
||||||
|
|
||||||
#endif /* __MALLOC_HOOK_H */
|
#endif /* SKYNET_MALLOC_HOOK_H */
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef _RWLOCK_H_
|
#ifndef SKYNET_RWLOCK_H
|
||||||
#define _RWLOCK_H_
|
#define SKYNET_RWLOCK_H
|
||||||
|
|
||||||
struct rwlock {
|
struct rwlock {
|
||||||
int write;
|
int write;
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ skynet_handle_retire(uint32_t handle) {
|
|||||||
struct skynet_context * ctx = s->slot[hash];
|
struct skynet_context * ctx = s->slot[hash];
|
||||||
|
|
||||||
if (ctx != NULL && skynet_context_handle(ctx) == handle) {
|
if (ctx != NULL && skynet_context_handle(ctx) == handle) {
|
||||||
skynet_context_release(ctx);
|
|
||||||
s->slot[hash] = NULL;
|
s->slot[hash] = NULL;
|
||||||
ret = 1;
|
ret = 1;
|
||||||
int i;
|
int i;
|
||||||
@@ -92,10 +91,17 @@ skynet_handle_retire(uint32_t handle) {
|
|||||||
++j;
|
++j;
|
||||||
}
|
}
|
||||||
s->name_count = j;
|
s->name_count = j;
|
||||||
|
} else {
|
||||||
|
ctx = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rwlock_wunlock(&s->lock);
|
rwlock_wunlock(&s->lock);
|
||||||
|
|
||||||
|
if (ctx) {
|
||||||
|
// release ctx may call skynet_handle_* , so wunlock first.
|
||||||
|
skynet_context_release(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ struct skynet_config {
|
|||||||
const char * module_path;
|
const char * module_path;
|
||||||
const char * bootstrap;
|
const char * bootstrap;
|
||||||
const char * logger;
|
const char * logger;
|
||||||
|
const char * logservice;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define THREAD_WORKER 0
|
#define THREAD_WORKER 0
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ main(int argc, char *argv[]) {
|
|||||||
config.bootstrap = optstring("bootstrap","snlua bootstrap");
|
config.bootstrap = optstring("bootstrap","snlua bootstrap");
|
||||||
config.daemon = optstring("daemon", NULL);
|
config.daemon = optstring("daemon", NULL);
|
||||||
config.logger = optstring("logger", NULL);
|
config.logger = optstring("logger", NULL);
|
||||||
|
config.logservice = optstring("logservice", "logger");
|
||||||
|
|
||||||
lua_close(L);
|
lua_close(L);
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ skynet_current_handle(void) {
|
|||||||
void * handle = pthread_getspecific(G_NODE.handle_key);
|
void * handle = pthread_getspecific(G_NODE.handle_key);
|
||||||
return (uint32_t)(uintptr_t)handle;
|
return (uint32_t)(uintptr_t)handle;
|
||||||
} else {
|
} else {
|
||||||
uintptr_t v = (uint32_t)(-THREAD_MAIN);
|
uint32_t v = (uint32_t)(-THREAD_MAIN);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -223,9 +223,9 @@ skynet_start(struct skynet_config * config) {
|
|||||||
skynet_timer_init();
|
skynet_timer_init();
|
||||||
skynet_socket_init();
|
skynet_socket_init();
|
||||||
|
|
||||||
struct skynet_context *ctx = skynet_context_new("logger", config->logger);
|
struct skynet_context *ctx = skynet_context_new(config->logservice, config->logger);
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
fprintf(stderr, "Can't launch logger service\n");
|
fprintf(stderr, "Can't launch %s service\n", config->logservice);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -508,7 +508,7 @@ udp_socket_address(struct socket *s, const uint8_t udp_address[UDP_ADDRESS_SIZE]
|
|||||||
memset(&sa->v6, 0, sizeof(sa->v6));
|
memset(&sa->v6, 0, sizeof(sa->v6));
|
||||||
sa->s.sa_family = AF_INET6;
|
sa->s.sa_family = AF_INET6;
|
||||||
sa->v6.sin6_port = port;
|
sa->v6.sin6_port = port;
|
||||||
memcpy(&sa->v6.sin6_addr, udp_address + 1 + sizeof(uint16_t), sizeof(sa->v6.sin6_addr)); // ipv4 address is 128 bits
|
memcpy(&sa->v6.sin6_addr, udp_address + 1 + sizeof(uint16_t), sizeof(sa->v6.sin6_addr)); // ipv6 address is 128 bits
|
||||||
return sizeof(sa->v6);
|
return sizeof(sa->v6);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -720,6 +720,7 @@ send_socket(struct socket_server *ss, struct request_send * request, struct sock
|
|||||||
append_sendbuffer_udp(ss,s,priority,request,udp_address);
|
append_sendbuffer_udp(ss,s,priority,request,udp_address);
|
||||||
} else {
|
} else {
|
||||||
so.free_func(request->buffer);
|
so.free_func(request->buffer);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sp_write(ss->event_fd, s->fd, s, true);
|
sp_write(ss->event_fd, s->fd, s, true);
|
||||||
@@ -887,6 +888,7 @@ add_udp_socket(struct socket_server *ss, struct request_udp *udp) {
|
|||||||
if (ns == NULL) {
|
if (ns == NULL) {
|
||||||
close(udp->fd);
|
close(udp->fd);
|
||||||
ss->slot[HASH_ID(id)].type = SOCKET_TYPE_INVALID;
|
ss->slot[HASH_ID(id)].type = SOCKET_TYPE_INVALID;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
ns->type = SOCKET_TYPE_CONNECTED;
|
ns->type = SOCKET_TYPE_CONNECTED;
|
||||||
memset(ns->p.udp_address, 0, sizeof(ns->p.udp_address));
|
memset(ns->p.udp_address, 0, sizeof(ns->p.udp_address));
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ end
|
|||||||
|
|
||||||
function init( ... )
|
function init( ... )
|
||||||
print ("ping server start:", ...)
|
print ("ping server start:", ...)
|
||||||
|
snax.enablecluster() -- enable cluster call
|
||||||
-- init queue
|
-- init queue
|
||||||
lock = queue()
|
lock = queue()
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,16 +3,15 @@ local socket = require "socket"
|
|||||||
|
|
||||||
local function server()
|
local function server()
|
||||||
local host
|
local host
|
||||||
host = socket.udp(function(data, sz, from)
|
host = socket.udp(function(str, from)
|
||||||
local str = skynet.tostring(data,sz) -- skynet.tostring should call only once, because it will free the pointer data
|
|
||||||
print("server recv", str, socket.udp_address(from))
|
print("server recv", str, socket.udp_address(from))
|
||||||
socket.sendto(host, from, "OK " .. str)
|
socket.sendto(host, from, "OK " .. str)
|
||||||
end , "127.0.0.1", 8765) -- bind an address
|
end , "127.0.0.1", 8765) -- bind an address
|
||||||
end
|
end
|
||||||
|
|
||||||
local function client()
|
local function client()
|
||||||
local c = socket.udp(function(data, sz, from)
|
local c = socket.udp(function(str, from)
|
||||||
print("client recv", skynet.tostring(data,sz), socket.udp_address(from))
|
print("client recv", str, socket.udp_address(from))
|
||||||
end)
|
end)
|
||||||
socket.udp_connect(c, "127.0.0.1", 8765)
|
socket.udp_connect(c, "127.0.0.1", 8765)
|
||||||
for i=1,20 do
|
for i=1,20 do
|
||||||
|
|||||||
Reference in New Issue
Block a user