mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-22 02:53:09 +00:00
Compare commits
23 Commits
v1.0.0-alp
...
v1.0.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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_TAIL (1<<5) /* call was tail called */
|
||||
#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)
|
||||
|
||||
|
||||
@@ -798,7 +798,8 @@ static int str_gsub (lua_State *L) {
|
||||
*/
|
||||
|
||||
/* 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 */
|
||||
#define FLAGS "-+ #0"
|
||||
|
||||
@@ -303,12 +303,18 @@ int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
|
||||
return l_strcmp(tsvalue(l), tsvalue(r)) <= 0;
|
||||
else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* first try 'le' */
|
||||
return res;
|
||||
else if ((res = luaT_callorderTM(L, r, l, TM_LT)) < 0) /* else try 'lt' */
|
||||
luaG_ordererror(L, l, r);
|
||||
return !res;
|
||||
else { /* try 'lt': */
|
||||
L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */
|
||||
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'.
|
||||
** 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: {
|
||||
int res = !l_isfalse(L->top - 1);
|
||||
L->top--;
|
||||
/* metamethod should not be called when operand is K */
|
||||
lua_assert(!ISK(GETARG_B(inst)));
|
||||
if (op == OP_LE && /* "<=" using "<" instead? */
|
||||
ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE)))
|
||||
res = !res; /* invert result */
|
||||
if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */
|
||||
lua_assert(op == OP_LE);
|
||||
ci->callstatus ^= CIST_LEQ; /* clear mark */
|
||||
res = !res; /* negate result */
|
||||
}
|
||||
lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
|
||||
if (res != GETARG_A(inst)) /* condition failed? */
|
||||
ci->u.l.savedpc++; /* skip jump instruction */
|
||||
|
||||
15
HISTORY.md
15
HISTORY.md
@@ -1,3 +1,18 @@
|
||||
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)
|
||||
-----------
|
||||
* Update sproto (bugfix)
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
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
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
|
||||
@@ -5,6 +5,9 @@ skynet.start(function()
|
||||
local sdb = skynet.newservice("simpledb")
|
||||
skynet.name(".simpledb", sdb)
|
||||
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", "b"))
|
||||
cluster.open "db"
|
||||
cluster.open "db2"
|
||||
end)
|
||||
|
||||
@@ -5,4 +5,5 @@ skynet.start(function()
|
||||
local proxy = cluster.proxy("db", ".simpledb")
|
||||
print(skynet.call(proxy, "lua", "GET", "a"))
|
||||
print(cluster.call("db", ".simpledb", "GET", "a"))
|
||||
print(cluster.call("db2", ".simpledb", "GET", "b"))
|
||||
end)
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
db = "127.0.0.1:2528"
|
||||
db2 = "127.0.0.1:2529"
|
||||
|
||||
@@ -602,11 +602,7 @@ read64(lua_State *L, uint32_t xx[2], uint32_t yy[2]) {
|
||||
}
|
||||
|
||||
static int
|
||||
lhmac64(lua_State *L) {
|
||||
uint32_t x[2], y[2];
|
||||
read64(L, x, y);
|
||||
uint32_t result[2];
|
||||
hmac(x,y,result);
|
||||
pushqword(lua_State *L, uint32_t result[2]) {
|
||||
uint8_t tmp[8];
|
||||
tmp[0] = result[0] & 0xff;
|
||||
tmp[1] = (result[0] >> 8 )& 0xff;
|
||||
@@ -621,6 +617,40 @@ lhmac64(lua_State *L) {
|
||||
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
|
||||
|
||||
// The biggest 64bit prime
|
||||
@@ -858,6 +888,7 @@ luaopen_crypt(lua_State *L) {
|
||||
{ "base64decode", lb64decode },
|
||||
{ "sha1", lsha1 },
|
||||
{ "hmac_sha1", lhmac_sha1 },
|
||||
{ "hmac_hash", lhmac_hash },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
luaL_newlib(L,l);
|
||||
|
||||
@@ -48,15 +48,9 @@ LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
|
||||
|
||||
static int
|
||||
lnewproto(lua_State *L) {
|
||||
size_t sz = 0;
|
||||
void * buffer;
|
||||
struct sproto * sp;
|
||||
if (lua_isuserdata(L,1)) {
|
||||
buffer = lua_touserdata(L,1);
|
||||
sz = luaL_checkinteger(L,2);
|
||||
} else {
|
||||
buffer = (void *)luaL_checklstring(L,1,&sz);
|
||||
}
|
||||
size_t sz;
|
||||
void * buffer = (void *)luaL_checklstring(L,1,&sz);
|
||||
sp = sproto_create(buffer, sz);
|
||||
if (sp) {
|
||||
lua_pushlightuserdata(L, sp);
|
||||
@@ -199,7 +193,7 @@ encode(const struct sproto_arg *args) {
|
||||
return -1;
|
||||
memcpy(args->value, str, sz);
|
||||
lua_pop(L,1);
|
||||
return sz;
|
||||
return sz + 1; // The length of empty string is 1.
|
||||
}
|
||||
case SPROTO_TSTRUCT: {
|
||||
struct encode_ud sub;
|
||||
@@ -545,48 +539,38 @@ lprotocol(lua_State *L) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
/* global sproto pointer for multi states */
|
||||
struct sproto_bin {
|
||||
void *ptr;
|
||||
size_t sz;
|
||||
};
|
||||
|
||||
static struct sproto_bin G_sproto[MAX_GLOBALSPROTO];
|
||||
/* global sproto pointer for multi states
|
||||
NOTICE : It is not thread safe
|
||||
*/
|
||||
static struct sproto * G_sproto[MAX_GLOBALSPROTO];
|
||||
|
||||
static int
|
||||
lsaveproto(lua_State *L) {
|
||||
size_t sz;
|
||||
void * buffer = (void *)luaL_checklstring(L,1,&sz);
|
||||
struct sproto * sp = lua_touserdata(L, 1);
|
||||
int index = luaL_optinteger(L, 2, 0);
|
||||
void * tmp;
|
||||
struct sproto_bin * sbin = &G_sproto[index];
|
||||
if (index < 0 || index >= MAX_GLOBALSPROTO) {
|
||||
return luaL_error(L, "Invalid global slot index %d", index);
|
||||
}
|
||||
tmp = malloc(sz);
|
||||
memcpy(tmp, buffer, sz);
|
||||
if (sbin->ptr) {
|
||||
free(sbin->ptr);
|
||||
}
|
||||
sbin->ptr = tmp;
|
||||
sbin->sz = sz;
|
||||
/* TODO : release old object (memory leak now, but thread safe)*/
|
||||
G_sproto[index] = sp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
lloadproto(lua_State *L) {
|
||||
int index = luaL_optinteger(L, 1, 0);
|
||||
struct sproto_bin * sbin = &G_sproto[index];
|
||||
struct sproto * sp;
|
||||
if (index < 0 || index >= MAX_GLOBALSPROTO) {
|
||||
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);
|
||||
}
|
||||
|
||||
lua_pushlightuserdata(L, sbin->ptr);
|
||||
lua_pushinteger(L, sbin->sz);
|
||||
return 2;
|
||||
lua_pushlightuserdata(L, sp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -510,7 +510,7 @@ sproto_dump(struct sproto *s) {
|
||||
|
||||
// query
|
||||
int
|
||||
sproto_prototag(struct sproto *sp, const char * name) {
|
||||
sproto_prototag(const struct sproto *sp, const char * name) {
|
||||
int i;
|
||||
for (i=0;i<sp->protocol_n;i++) {
|
||||
if (strcmp(name, sp->proto[i].name) == 0) {
|
||||
@@ -521,7 +521,7 @@ sproto_prototag(struct sproto *sp, const char * name) {
|
||||
}
|
||||
|
||||
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;
|
||||
while(begin<end) {
|
||||
int mid = (begin+end)/2;
|
||||
@@ -539,7 +539,7 @@ query_proto(struct sproto *sp, int tag) {
|
||||
}
|
||||
|
||||
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;
|
||||
if (what <0 || what >1) {
|
||||
return NULL;
|
||||
@@ -552,7 +552,7 @@ sproto_protoquery(struct sproto *sp, int proto, int what) {
|
||||
}
|
||||
|
||||
const char *
|
||||
sproto_protoname(struct sproto *sp, int proto) {
|
||||
sproto_protoname(const struct sproto *sp, int proto) {
|
||||
struct protocol * p = query_proto(sp, proto);
|
||||
if (p) {
|
||||
return p->name;
|
||||
@@ -561,7 +561,7 @@ sproto_protoname(struct sproto *sp, int proto) {
|
||||
}
|
||||
|
||||
struct sproto_type *
|
||||
sproto_type(struct sproto *sp, const char * type_name) {
|
||||
sproto_type(const struct sproto *sp, const char * type_name) {
|
||||
int i;
|
||||
for (i=0;i<sp->type_n;i++) {
|
||||
if (strcmp(type_name, sp->type[i].name) == 0) {
|
||||
@@ -577,7 +577,7 @@ sproto_name(struct sproto_type * st) {
|
||||
}
|
||||
|
||||
static struct field *
|
||||
findtag(struct sproto_type *st, int tag) {
|
||||
findtag(const struct sproto_type *st, int tag) {
|
||||
int begin, end;
|
||||
if (st->base >=0 ) {
|
||||
tag -= st->base;
|
||||
@@ -609,10 +609,6 @@ findtag(struct sproto_type *st, int tag) {
|
||||
|
||||
static inline int
|
||||
fill_size(uint8_t * data, int sz) {
|
||||
if (sz < 0)
|
||||
return -1;
|
||||
if (sz == 0)
|
||||
return 0;
|
||||
data[0] = sz & 0xff;
|
||||
data[1] = (sz >> 8) & 0xff;
|
||||
data[2] = (sz >> 16) & 0xff;
|
||||
@@ -677,6 +673,11 @@ encode_object(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int si
|
||||
args->value = data+SIZEOF_LENGTH;
|
||||
args->length = size-SIZEOF_LENGTH;
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -718,7 +719,7 @@ encode_integer_array(sproto_callback cb, struct sproto_arg *args, uint8_t *buffe
|
||||
sz = cb(args);
|
||||
if (sz < 0)
|
||||
return NULL;
|
||||
if (sz == 0)
|
||||
if (sz == 0) // nil object, end of array
|
||||
break;
|
||||
if (size < sizeof(uint64_t))
|
||||
return NULL;
|
||||
@@ -798,7 +799,7 @@ encode_array(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int siz
|
||||
sz = cb(args);
|
||||
if (sz < 0)
|
||||
return -1;
|
||||
if (sz == 0)
|
||||
if (sz == 0) // nil object , end of array
|
||||
break;
|
||||
if (size < 1)
|
||||
return -1;
|
||||
@@ -817,10 +818,13 @@ encode_array(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int siz
|
||||
args->value = buffer+SIZEOF_LENGTH;
|
||||
args->length = size;
|
||||
sz = cb(args);
|
||||
if (sz < 0)
|
||||
return -1;
|
||||
if (sz == 0)
|
||||
break;
|
||||
if (sz < 0)
|
||||
return -1;
|
||||
if (args->type == SPROTO_TSTRING) {
|
||||
--sz;
|
||||
}
|
||||
fill_size(buffer, sz);
|
||||
buffer += SIZEOF_LENGTH+sz;
|
||||
size -=sz;
|
||||
@@ -829,13 +833,13 @@ encode_array(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int siz
|
||||
break;
|
||||
}
|
||||
sz = buffer - (data + SIZEOF_LENGTH);
|
||||
if (sz == 0)
|
||||
if (sz == 0) // empty array
|
||||
return 0;
|
||||
return fill_size(data, sz);
|
||||
}
|
||||
|
||||
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;
|
||||
uint8_t * header = buffer;
|
||||
uint8_t * data;
|
||||
@@ -878,7 +882,7 @@ sproto_encode(struct sproto_type *st, void * buffer, int size, sproto_callback c
|
||||
sz = cb(&args);
|
||||
if (sz < 0)
|
||||
return -1;
|
||||
if (sz == 0)
|
||||
if (sz == 0) // nil object
|
||||
continue;
|
||||
if (sz == sizeof(uint32_t)) {
|
||||
if (u.u32 < 0x7fff) {
|
||||
@@ -895,11 +899,10 @@ sproto_encode(struct sproto_type *st, void * buffer, int size, sproto_callback c
|
||||
break;
|
||||
}
|
||||
case SPROTO_TSTRUCT:
|
||||
case SPROTO_TSTRING: {
|
||||
case SPROTO_TSTRING:
|
||||
sz = encode_object(cb, &args, data, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sz < 0)
|
||||
return -1;
|
||||
@@ -1032,7 +1035,7 @@ decode_array(sproto_callback cb, struct sproto_arg *args, uint8_t * stream) {
|
||||
}
|
||||
|
||||
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;
|
||||
int total = size;
|
||||
uint8_t * stream;
|
||||
|
||||
@@ -17,12 +17,12 @@ struct sproto_type;
|
||||
struct sproto * sproto_create(const void * proto, size_t sz);
|
||||
void sproto_release(struct sproto *);
|
||||
|
||||
int sproto_prototag(struct sproto *, const char * name);
|
||||
const char * sproto_protoname(struct sproto *, int proto);
|
||||
int sproto_prototag(const struct sproto *, const char * name);
|
||||
const char * sproto_protoname(const struct sproto *, int proto);
|
||||
// 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_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);
|
||||
|
||||
int sproto_decode(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_decode(const struct sproto_type *, const void * data, 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
|
||||
void sproto_dump(struct sproto *);
|
||||
|
||||
@@ -249,8 +249,8 @@ function dns.server(server, port)
|
||||
end
|
||||
assert(server, "Can't get nameserver")
|
||||
end
|
||||
dns_server = socket.udp(function(data, sz, from)
|
||||
resolve(skynet.tostring(data,sz))
|
||||
dns_server = socket.udp(function(str, from)
|
||||
resolve(str)
|
||||
end)
|
||||
socket.udp_connect(dns_server, server, port or 53)
|
||||
return server
|
||||
|
||||
@@ -16,6 +16,8 @@ local function request(fd, method, host, url, recvheader, header, content)
|
||||
end
|
||||
if header.host then
|
||||
host = ""
|
||||
else
|
||||
host = string.format("host:%s\r\n", host)
|
||||
end
|
||||
else
|
||||
host = string.format("host:%s\r\n",host)
|
||||
|
||||
@@ -30,12 +30,14 @@ function sharemap.writer(typename, obj)
|
||||
local sp = loadsp()
|
||||
obj = obj or {}
|
||||
local stmobj = stm.new(sp:encode(typename,obj))
|
||||
obj.__typename = typename
|
||||
obj.__obj = stmobj
|
||||
obj.__data = obj
|
||||
obj.commit = sharemap.commit
|
||||
obj.copy = sharemap.copy
|
||||
return setmetatable(obj, { __index = obj.__data, __newindex = obj.__data })
|
||||
local ret = {
|
||||
__typename = typename,
|
||||
__obj = stmobj,
|
||||
__data = obj,
|
||||
commit = sharemap.commit,
|
||||
copy = sharemap.copy,
|
||||
}
|
||||
return setmetatable(ret, { __index = obj, __newindex = obj })
|
||||
end
|
||||
|
||||
local function decode(msg, sz, self)
|
||||
@@ -63,7 +65,7 @@ function sharemap.reader(typename, stmcpy)
|
||||
__data = data,
|
||||
update = sharemap.update,
|
||||
}
|
||||
return setmetatable(obj, { __index = obj.__data, __newindex = error })
|
||||
return setmetatable(obj, { __index = data, __newindex = error })
|
||||
end
|
||||
|
||||
return sharemap
|
||||
|
||||
@@ -398,6 +398,7 @@ skynet.pack = assert(c.pack)
|
||||
skynet.packstring = assert(c.packstring)
|
||||
skynet.unpack = assert(c.unpack)
|
||||
skynet.tostring = assert(c.tostring)
|
||||
skynet.trash = assert(c.trash)
|
||||
|
||||
local function yield_call(service, session)
|
||||
watching_session[session] = service
|
||||
@@ -619,8 +620,10 @@ end
|
||||
local function init_all()
|
||||
local funcs = init_func
|
||||
init_func = nil
|
||||
for k,v in pairs(funcs) do
|
||||
v()
|
||||
if funcs then
|
||||
for k,v in pairs(funcs) do
|
||||
v()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -631,8 +634,12 @@ local function init_template(start)
|
||||
init_all()
|
||||
end
|
||||
|
||||
function skynet.pcall(start)
|
||||
return xpcall(init_template, debug.traceback, start)
|
||||
end
|
||||
|
||||
local function init_service(start)
|
||||
local ok, err = xpcall(init_template, debug.traceback, start)
|
||||
local ok, err = skynet.pcall(start)
|
||||
if not ok then
|
||||
skynet.error("init service failed: " .. tostring(err))
|
||||
skynet.send(".launcher","lua", "ERROR")
|
||||
|
||||
@@ -49,7 +49,7 @@ end
|
||||
|
||||
function dbgcmd.RUN(source, filename)
|
||||
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"
|
||||
skynet.ret(skynet.pack(table.concat(output, "\n")))
|
||||
end
|
||||
|
||||
@@ -18,7 +18,7 @@ local function getupvaluetable(u, func, unique)
|
||||
end
|
||||
end
|
||||
|
||||
return function(source, filename , ...)
|
||||
return function(skynet, source, filename , ...)
|
||||
if filename then
|
||||
filename = "@" .. filename
|
||||
else
|
||||
@@ -56,7 +56,7 @@ return function(source, filename , ...)
|
||||
if not func then
|
||||
return { err }
|
||||
end
|
||||
local ok, err = xpcall(func, debug.traceback)
|
||||
local ok, err = skynet.pcall(func)
|
||||
if not ok then
|
||||
table.insert(output, err)
|
||||
end
|
||||
|
||||
@@ -162,4 +162,8 @@ function snax.hotfix(obj, source, ...)
|
||||
return test_result(skynet_call(obj.handle, "snax", t.system.hotfix, source, ...))
|
||||
end
|
||||
|
||||
function snax.printf(fmt, ...)
|
||||
skynet.error(string.format(fmt, ...))
|
||||
end
|
||||
|
||||
return snax
|
||||
|
||||
@@ -33,17 +33,17 @@ Success:
|
||||
]]
|
||||
|
||||
local socket_error = {}
|
||||
local function assert_socket(v, fd)
|
||||
local function assert_socket(service, v, fd)
|
||||
if v then
|
||||
return v
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
local function write(fd, text)
|
||||
assert_socket(socket.write(fd, text), fd)
|
||||
local function write(service, fd, text)
|
||||
assert_socket(service, socket.write(fd, text), fd)
|
||||
end
|
||||
|
||||
local function launch_slave(auth_handler)
|
||||
@@ -57,27 +57,27 @@ local function launch_slave(auth_handler)
|
||||
socket.limit(fd, 8192)
|
||||
|
||||
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)
|
||||
if #clientkey ~= 8 then
|
||||
error "Invalid client key"
|
||||
end
|
||||
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 response = assert_socket(socket.readline(fd), fd)
|
||||
local response = assert_socket("auth", socket.readline(fd), fd)
|
||||
local hmac = crypt.hmac64(challenge, secret)
|
||||
|
||||
if hmac ~= crypt.base64decode(response) then
|
||||
write(fd, "400 Bad Request\n")
|
||||
write("auth", fd, "400 Bad Request\n")
|
||||
error "challenge failed"
|
||||
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))
|
||||
|
||||
@@ -91,7 +91,11 @@ local function launch_slave(auth_handler)
|
||||
if ok then
|
||||
skynet.ret(skynet.pack(err, ...))
|
||||
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
|
||||
|
||||
@@ -108,13 +112,15 @@ local function accept(conf, s, fd, addr)
|
||||
socket.start(fd)
|
||||
|
||||
if not ok then
|
||||
write(fd, "401 Unauthorized\n")
|
||||
if ok ~= nil then
|
||||
write("response 401", fd, "401 Unauthorized\n")
|
||||
end
|
||||
error(server)
|
||||
end
|
||||
|
||||
if not conf.multilogin 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))
|
||||
end
|
||||
|
||||
@@ -127,9 +133,9 @@ local function accept(conf, s, fd, addr)
|
||||
|
||||
if ok then
|
||||
err = err or ""
|
||||
write(fd, "200 "..crypt.base64encode(err).."\n")
|
||||
write("response 200",fd, "200 "..crypt.base64encode(err).."\n")
|
||||
else
|
||||
write(fd, "403 Forbidden\n")
|
||||
write("response 403",fd, "403 Forbidden\n")
|
||||
error(err)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -178,7 +178,7 @@ function server.start(conf)
|
||||
end
|
||||
|
||||
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
|
||||
return "401 Unauthorized"
|
||||
end
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
local driver = require "socketdriver"
|
||||
local skynet = require "skynet"
|
||||
local skynet_core = require "skynet.core"
|
||||
local assert = assert
|
||||
|
||||
local socket = {} -- api
|
||||
@@ -127,7 +128,9 @@ socket_message[6] = function(id, size, data, address)
|
||||
driver.drop(data, size)
|
||||
return
|
||||
end
|
||||
s.callback(data, size, address)
|
||||
local str = skynet.tostring(data, size)
|
||||
skynet_core.trash(data, size)
|
||||
s.callback(str, address)
|
||||
end
|
||||
|
||||
skynet.register_protocol {
|
||||
|
||||
@@ -13,14 +13,23 @@ function sproto_mt:__gc()
|
||||
core.deleteproto(self.__cobj)
|
||||
end
|
||||
|
||||
function sproto.new(bin,sz,nogc)
|
||||
local cobj = assert(core.newproto(bin,sz))
|
||||
function sproto.new(bin)
|
||||
local cobj = assert(core.newproto(bin))
|
||||
local self = {
|
||||
__cobj = cobj,
|
||||
__tcache = 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
|
||||
|
||||
function sproto.parse(ptext)
|
||||
@@ -90,6 +99,29 @@ local function queryproto(self, pname)
|
||||
return v
|
||||
end
|
||||
|
||||
function sproto:request_encode(protoname, tbl)
|
||||
local p = queryproto(self, protoname)
|
||||
return core.encode(p.request,tbl) , p.tag
|
||||
end
|
||||
|
||||
function sproto:response_encode(protoname, tbl)
|
||||
local p = queryproto(self, protoname)
|
||||
return core.encode(p.response,tbl)
|
||||
end
|
||||
|
||||
function sproto:request_decode(protoname, ...)
|
||||
local p = queryproto(self, protoname)
|
||||
return core.decode(p.request,...) , p.name
|
||||
end
|
||||
|
||||
function sproto:response_decode(protoname, ...)
|
||||
local p = queryproto(self, protoname)
|
||||
return core.decode(p.response,...)
|
||||
end
|
||||
|
||||
sproto.pack = core.pack
|
||||
sproto.unpack = core.unpack
|
||||
|
||||
local header_tmp = {}
|
||||
|
||||
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 data = f:read "a"
|
||||
f:close()
|
||||
local bin = parser.parse(data)
|
||||
core.saveproto(bin, index)
|
||||
local sp = core.newproto(parser.parse(data))
|
||||
core.saveproto(sp, index)
|
||||
end
|
||||
|
||||
loader.save = core.saveproto
|
||||
function loader.save(bin, index)
|
||||
local sp = core.newproto(bin)
|
||||
core.saveproto(sp, index)
|
||||
end
|
||||
|
||||
function loader.load(index)
|
||||
local bin, sz = core.loadproto(index)
|
||||
local sp = core.loadproto(index)
|
||||
-- no __gc in metatable
|
||||
return sproto.new(bin,sz, true)
|
||||
return sproto.sharenew(sp)
|
||||
end
|
||||
|
||||
return loader
|
||||
|
||||
@@ -5,14 +5,6 @@ local cluster = require "cluster.core"
|
||||
|
||||
local config_name = skynet.getenv "cluster"
|
||||
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 command = {}
|
||||
|
||||
@@ -37,6 +29,24 @@ end
|
||||
|
||||
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()
|
||||
loadconfig()
|
||||
skynet.ret(skynet.pack(nil))
|
||||
|
||||
@@ -44,7 +44,7 @@ function CMD.new(name, t)
|
||||
elseif dt == "string" then
|
||||
value = setmetatable({}, env_mt)
|
||||
local f = load(t, "=" .. name, "t", value)
|
||||
f()
|
||||
assert(skynet.pcall(f))
|
||||
setmetatable(value, nil)
|
||||
elseif dt == "nil" then
|
||||
value = {}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef __MALLOC_HOOK_H
|
||||
#define __MALLOC_HOOK_H
|
||||
#ifndef SKYNET_MALLOC_HOOK_H
|
||||
#define SKYNET_MALLOC_HOOK_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 void dump_c_mem(void);
|
||||
|
||||
#endif /* __MALLOC_HOOK_H */
|
||||
#endif /* SKYNET_MALLOC_HOOK_H */
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef _RWLOCK_H_
|
||||
#define _RWLOCK_H_
|
||||
#ifndef SKYNET_RWLOCK_H
|
||||
#define SKYNET_RWLOCK_H
|
||||
|
||||
struct rwlock {
|
||||
int write;
|
||||
|
||||
@@ -77,7 +77,6 @@ skynet_handle_retire(uint32_t handle) {
|
||||
struct skynet_context * ctx = s->slot[hash];
|
||||
|
||||
if (ctx != NULL && skynet_context_handle(ctx) == handle) {
|
||||
skynet_context_release(ctx);
|
||||
s->slot[hash] = NULL;
|
||||
ret = 1;
|
||||
int i;
|
||||
@@ -92,10 +91,17 @@ skynet_handle_retire(uint32_t handle) {
|
||||
++j;
|
||||
}
|
||||
s->name_count = j;
|
||||
} else {
|
||||
ctx = NULL;
|
||||
}
|
||||
|
||||
rwlock_wunlock(&s->lock);
|
||||
|
||||
if (ctx) {
|
||||
// release ctx may call skynet_handle_* , so wunlock first.
|
||||
skynet_context_release(ctx);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,16 +3,15 @@ local socket = require "socket"
|
||||
|
||||
local function server()
|
||||
local host
|
||||
host = socket.udp(function(data, sz, from)
|
||||
local str = skynet.tostring(data,sz) -- skynet.tostring should call only once, because it will free the pointer data
|
||||
host = socket.udp(function(str, from)
|
||||
print("server recv", str, socket.udp_address(from))
|
||||
socket.sendto(host, from, "OK " .. str)
|
||||
end , "127.0.0.1", 8765) -- bind an address
|
||||
end
|
||||
|
||||
local function client()
|
||||
local c = socket.udp(function(data, sz, from)
|
||||
print("client recv", skynet.tostring(data,sz), socket.udp_address(from))
|
||||
local c = socket.udp(function(str, from)
|
||||
print("client recv", str, socket.udp_address(from))
|
||||
end)
|
||||
socket.udp_connect(c, "127.0.0.1", 8765)
|
||||
for i=1,20 do
|
||||
|
||||
Reference in New Issue
Block a user