static int start_listen(struct gate *g, char * listen_addr) { struct skynet_context * ctx = g->ctx; char * portstr = strchr(listen_addr,':'); const char * host = ""; int port; if (portstr == NULL) { port = strtol(listen_addr, NULL, 10); if (port <= 0) { skynet_error(ctx, "Invalid gate address %s",listen_addr); return 1; } } else { port = strtol(portstr + 1, NULL, 10); if (port <= 0) { skynet_error(ctx, "Invalid gate address %s",listen_addr); return 1; } portstr[0] = '\0'; host = listen_addr; } g->listen_id = skynet_socket_listen(ctx, host, port, BACKLOG); if (g->listen_id < 0) { return 1; } return 0; }
static int _cb(struct skynet_context * ctx, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) { struct gate *g = ud; switch(type) { case PTYPE_TEXT: _ctrl(g , msg , (int)sz); break; case PTYPE_CLIENT: { if (sz <=4 ) { skynet_error(ctx, "Invalid client message from %x",source); break; } // The last 4 bytes in msg are the id of socket, write following bytes to it const uint8_t * idbuf = msg + sz - 4; uint32_t uid = idbuf[0] | idbuf[1] << 8 | idbuf[2] << 16 | idbuf[3] << 24; int id = hashid_lookup(&g->hash, uid); if (id>=0) { // don't send id (last 4 bytes) skynet_socket_send(ctx, uid, (void*)msg, sz-4); // return 1 means don't free msg return 1; } else { skynet_error(ctx, "Invalid client id %d from %x",(int)uid,source); break; } } case PTYPE_SOCKET: // recv socket message from skynet_socket dispatch_socket_message(g, msg, (int)(sz-sizeof(struct skynet_socket_message))); break; } return 0; }
static void _dispatch_queue(struct harbor *h, struct skynet_context * context, struct msg_queue * queue, uint32_t handle, const char name[GLOBALNAME_LENGTH] ) { int harbor_id = handle >> HANDLE_REMOTE_SHIFT; assert(harbor_id != 0); int fd = h->remote_fd[harbor_id]; if (fd < 0) { char tmp [GLOBALNAME_LENGTH+1]; memcpy(tmp, name , GLOBALNAME_LENGTH); tmp[GLOBALNAME_LENGTH] = '\0'; skynet_error(context, "Drop message to %s (in harbor %d)",tmp,harbor_id); return; } struct msg * m = _pop_queue(queue); while (m) { struct remote_message_header * cookie = (struct remote_message_header *)(m->buffer + m->size - sizeof(*cookie)); cookie->destination |= (handle & HANDLE_MASK); _header_to_message(cookie, (uint32_t *)cookie); int err = _send_package(fd, m->buffer, m->size); if (err) { close(fd); h->remote_fd[harbor_id] = _connect_to(context, h->remote_addr[harbor_id]); if (h->remote_fd[harbor_id] < 0) { skynet_error(context, "Reconnect to harbor %d %s failed",harbor_id, h->remote_addr[harbor_id]); return; } } free(m->buffer); m = _pop_queue(queue); } }
static int start_service(struct otu *u, char * service_addr) { struct skynet_context * ctx = u->ctx; char * portstr = strchr(service_addr,':'); const char * host = ""; int port; if (portstr == NULL) { port = strtol(service_addr, NULL, 10); if (port <= 0) { skynet_error(ctx, "Invalid gate address %s",service_addr); return 1; } } else { port = strtol(portstr + 1, NULL, 10); if (port <= 0) { skynet_error(ctx, "Invalid gate address %s",service_addr); return 1; } portstr[0] = '\0'; host = service_addr; } u->service_id = skynet_socket_udp(ctx, host, port) ; if (u->service_id < 0) { return 1; } skynet_socket_start(ctx, u->service_id); return 0; }
int gate_init(struct gate *g , struct skynet_context * ctx, char * parm) { if (parm == NULL) return 1; int max = 0; int buffer = 0; int sz = strlen(parm)+1; char watchdog[sz]; char binding[sz]; int client_tag = 0; char header; int n = sscanf(parm, "%c %s %s %d %d %d",&header,watchdog, binding,&client_tag , &max,&buffer); if (n<4) { skynet_error(ctx, "Invalid gate parm %s",parm); return 1; } if (max <=0 ) { skynet_error(ctx, "Need max connection"); return 1; } if (header != 'S' && header !='L') { skynet_error(ctx, "Invalid data header style"); return 1; } if (client_tag == 0) { client_tag = PTYPE_CLIENT; } if (watchdog[0] == '!') { g->watchdog = 0; } else { g->watchdog = skynet_queryname(ctx, watchdog); if (g->watchdog == 0) { skynet_error(ctx, "Invalid watchdog %s",watchdog); return 1; } } g->ctx = ctx; int cap = 16; while (cap < max) { cap *= 2; } hashid_init(&g->hash, max, cap); g->conn = malloc(max * sizeof(struct connection)); memset(g->conn, 0, max *sizeof(struct connection)); g->max_connection = max; int i; for (i=0;i<max;i++) { g->conn[i].id = -1; } g->client_tag = client_tag; g->header_size = header=='S' ? 2 : 4; skynet_callback(ctx,g,_cb); return start_listen(g,binding); }
MASTER_API int master_init(struct master *m, struct skynet_context *ctx, const char * args) { //char tmp[strlen(args) + 32]; char tmp[256]; sprintf(tmp,"gate L ! %s %d %d 0",args,PTYPE_HARBOR,REMOTE_MAX); const char * gate_addr = skynet_command(ctx, "LAUNCH", tmp); if (gate_addr == NULL) { skynet_error(ctx, "Master : launch gate failed"); return 1; } uint32_t gate = strtoul(gate_addr+1, NULL, 16); if (gate == 0) { skynet_error(ctx, "Master : launch gate invalid %s", gate_addr); return 1; } const char * self_addr = skynet_command(ctx, "REG", NULL); int n = sprintf(tmp,"broker %s",self_addr); skynet_send(ctx, 0, gate, PTYPE_TEXT, 0, tmp, n); skynet_send(ctx, 0, gate, PTYPE_TEXT, 0, "start", 5); skynet_callback(ctx, m, _mainloop); m->ctx = ctx; return 0; }
static int _remote_send_handle(struct harbor *h, struct skynet_context * context, uint32_t source, uint32_t destination, int type, int session, const char * msg, size_t sz) { int harbor_id = destination >> HANDLE_REMOTE_SHIFT; assert(harbor_id != 0); if (harbor_id == h->id) { // local message skynet_send(context, source, destination , type | PTYPE_TAG_DONTCOPY, session, (void *)msg, sz); return 1; } int fd = h->remote_fd[harbor_id]; if (fd >= 0) { struct remote_message_header cookie; cookie.source = source; cookie.destination = (destination & HANDLE_MASK) | ((uint32_t)type << HANDLE_REMOTE_SHIFT); cookie.session = (uint32_t)session; int err = _send_remote(fd, msg,sz,&cookie); if (err) { close(fd); h->remote_fd[harbor_id] = _connect_to(context, h->remote_addr[harbor_id]); if (h->remote_fd[harbor_id] < 0) { skynet_error(context, "Reconnect to harbor %d : %s failed", harbor_id, h->remote_addr[harbor_id]); return 0; } } } else { _request_master(h, context, NULL, 0, harbor_id); skynet_error(context, "Drop message to harbor %d from %x to %x (session = %d, msgsz = %d)",harbor_id, source, destination,session,(int)sz); } return 0; }
static int init_cb(struct snlua *l, struct skynet_context *ctx, const char * args, size_t sz) { lua_State *L = l->L; l->ctx = ctx; lua_gc(L, LUA_GCSTOP, 0); lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */ lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); luaL_openlibs(L); lua_pushlightuserdata(L, ctx); lua_setfield(L, LUA_REGISTRYINDEX, "skynet_context"); luaL_requiref(L, "skynet.codecache", codecache , 0); lua_pop(L,1); const char *path = optstring(ctx, "lua_path","./lualib/?.lua;./lualib/?/init.lua"); lua_pushstring(L, path); lua_setglobal(L, "LUA_PATH"); const char *cpath = optstring(ctx, "lua_cpath","./luaclib/?.so"); lua_pushstring(L, cpath); lua_setglobal(L, "LUA_CPATH"); const char *service = optstring(ctx, "luaservice", "./service/?.lua"); lua_pushstring(L, service); lua_setglobal(L, "LUA_SERVICE"); const char *preload = skynet_command(ctx, "GETENV", "preload"); lua_pushstring(L, preload); lua_setglobal(L, "LUA_PRELOAD"); lua_pushcfunction(L, traceback); assert(lua_gettop(L) == 1); const char * loader = optstring(ctx, "lualoader", "./lualib/loader.lua"); int r = luaL_loadfile(L,loader); if (r != LUA_OK) { skynet_error(ctx, "Can't load %s : %s", loader, lua_tostring(L, -1)); report_launcher_error(ctx); return 1; } lua_pushlstring(L, args, sz); r = lua_pcall(L,1,0,1); if (r != LUA_OK) { skynet_error(ctx, "lua loader error : %s", lua_tostring(L, -1)); report_launcher_error(ctx); return 1; } lua_settop(L,0); if (lua_getfield(L, LUA_REGISTRYINDEX, "memlimit") == LUA_TNUMBER) { size_t limit = lua_tointeger(L, -1); l->mem_limit = limit; skynet_error(ctx, "Set memory limit to %.2f M", (float)limit / (1024 * 1024)); lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, "memlimit"); } lua_pop(L, 1); lua_gc(L, LUA_GCRESTART, 0); return 0; }
int otu_init(struct otu *u , struct skynet_context * ctx, char * parm) { if (parm == NULL) return 1; int max = 0; int sz = strlen(parm)+1; char watchdog[sz]; char binding[sz]; int client_tag = 0; int n = sscanf(parm, "%s %s %d %d", watchdog, binding, &client_tag, &max); if (n<4) { skynet_error(ctx, "Invalid otu parm %s", parm); return 1; } skynet_error(ctx, "Watchdog:%s, Binding:%s, Protocol:%d, MaxPeer:%d", watchdog, binding, client_tag, max); if (max <=0 ) { skynet_error(ctx, "Need max connection"); return 1; } if (client_tag == 0) { client_tag = PTYPE_CLIENT; } if (watchdog[0] == '!') { u->watchdog = 0; } else { u->watchdog = skynet_queryname(ctx, watchdog); if (u->watchdog == 0) { skynet_error(ctx, "Invalid watchdog %s",watchdog); return 1; } } u->ctx = ctx; hashid64_init(&u->hash, max); u->peer = skynet_malloc(max * sizeof(struct udp_peer)); memset(u->peer, 0, max *sizeof(struct udp_peer)); u->max_peer = max; int i; for (i=0;i<max;i++) { // u->peer[i].id = -1; } u->client_tag = client_tag; skynet_callback(ctx,u,_cb_otu); return start_service(u,binding); }
static int _init(struct snlua *l, struct skynet_context *ctx, const char * args) { lua_State *L = l->L; l->ctx = ctx; luaL_init(L); lua_gc(L, LUA_GCSTOP, 0); luaL_openlibs(L); lua_pushlightuserdata(L, l); lua_setfield(L, LUA_REGISTRYINDEX, "skynet_lua"); #ifndef NOCODECACHE luaL_requiref(L, "skynet.codecache", luacode_lib , 0); lua_pop(L,1); #endif lua_gc(L, LUA_GCRESTART, 0); char tmp[strlen(args)+1]; char *parm = tmp; strcpy(parm,args); lua_pushcfunction(L, traceback); int traceback_index = lua_gettop(L); assert(traceback_index == 1); const char * filename = parm; int r = _load(L, &parm); if (r != 0) { if (r<0) { skynet_error(ctx, "lua parser [%s] load error", filename); } else { skynet_error(ctx, "lua parser [%s] error : %s", filename, lua_tostring(L,-1)); } _report_launcher_error(ctx); return 1; } int n=0; while(parm) { const char * arg = strsep(&parm, " \r\n"); if (arg && arg[0]!='\0') { lua_pushstring(L, arg); ++n; } } r = lua_pcall(L,n,0,traceback_index); if (r == LUA_OK) { r = lua_gc(L, LUA_GCCOLLECT, 0); if (r == LUA_OK) { return 0; } } _report_error(L, ctx, filename, r); _report_launcher_error(ctx); return 1; }
void snlua_signal(struct snlua *l, int signal) { skynet_error(l->ctx, "recv a signal %d", signal); if (signal == 0) { #ifdef lua_checksig // If our lua support signal (modified lua version by skynet), trigger it. skynet_sig_L = l->L; #endif } else if (signal == 1) { skynet_error(l->ctx, "Current Memory %.3fK", (float)l->mem / 1024); } }
static int _cb(struct skynet_context * context, void * ud, int session, const char * addr, const void * msg, size_t sz) { lua_State *L = ud; int trace = 1; int top = lua_gettop(L); if (top == 1) { lua_rawgetp(L, LUA_REGISTRYINDEX, _cb); } else { assert(top == 2); lua_pushvalue(L,2); } int r; if (msg == NULL) { if (addr == NULL) { lua_pushinteger(L, session); r = lua_pcall(L, 1, 0 , trace); } else { lua_pushinteger(L, session); lua_pushstring(L, addr); r = lua_pcall(L, 2, 0 , trace); } } else { lua_pushinteger(L, session); lua_pushstring(L, addr); lua_pushlightuserdata(L,(void *)msg); lua_pushinteger(L,sz); r = lua_pcall(L, 4, 0 , trace); } if (r == LUA_OK) return 0; const char * self = skynet_command(context, "REG", NULL); switch (r) { case LUA_ERRRUN: skynet_error(context, "lua call [%s to %s : %d msgsz = %d] error : %s", addr , self, session, sz, lua_tostring(L,-1)); break; case LUA_ERRMEM: skynet_error(context, "lua memory error : [%s to %s : %d]", addr , self, session); break; case LUA_ERRERR: skynet_error(context, "lua error in error : [%s to %s : %d]", addr , self, session); break; case LUA_ERRGCMM: skynet_error(context, "lua gc error : [%s to %s : %d]", addr , self, session); break; }; lua_pop(L,1); return 0; }
int snlua_init(lua_State *L, struct skynet_context *ctx, const char * args) { lua_gc(L, LUA_GCSTOP, 0); luaL_openlibs(L); lua_pushlightuserdata(L, ctx); lua_setfield(L, LUA_REGISTRYINDEX, "skynet_context"); lua_gc(L, LUA_GCRESTART, 0); char tmp[strlen(args)+1]; char *parm = tmp; strcpy(parm,args); lua_pushcfunction(L, traceback); int traceback_index = lua_gettop(L); const char * filename = parm; int r = _load(L, &parm); if (r) { skynet_error(ctx, "lua parser [%s] error : %s", filename, lua_tostring(L,-1)); return 1; } int n=0; while(parm) { const char * arg = strsep(&parm, " \r\n"); if (arg && arg[0]!='\0') { lua_pushstring(L, arg); ++n; } } r = lua_pcall(L,n,0,traceback_index); switch (r) { case LUA_OK: return 0; case LUA_ERRRUN: skynet_error(ctx, "lua do [%s] error : %s", filename, lua_tostring(L,-1)); break; case LUA_ERRMEM: skynet_error(ctx, "lua memory error : %s",filename); break; case LUA_ERRERR: skynet_error(ctx, "lua message error : %s",filename); break; case LUA_ERRGCMM: skynet_error(ctx, "lua gc error : %s",filename); break; }; lua_pop(L,1); return 1; }
static int _connect_to(struct skynet_context *ctx, const char *ipaddress) { int fd = socket(AF_INET,SOCK_STREAM,0); struct sockaddr_in my_addr; char * port = strchr(ipaddress,':'); if (port==NULL) { return -1; } int sz = port - ipaddress; char tmp[sz + 1]; memcpy(tmp,ipaddress,sz); tmp[sz] = '\0'; my_addr.sin_addr.s_addr=inet_addr(tmp); my_addr.sin_family=AF_INET; my_addr.sin_port=htons(strtol(port+1,NULL,10)); int r = connect(fd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr_in)); if (r == -1) { close(fd); skynet_error(ctx, "Connect to %s error", ipaddress); return -1; } return fd; }
int skynet_socket_poll() { struct socket_server *ss = SOCKET_SERVER; assert(ss); struct socket_message result; int more = 1; int type = socket_server_poll(ss, &result, &more); switch (type) { case SOCKET_EXIT: return 0; case SOCKET_DATA: forward_message(SKYNET_SOCKET_TYPE_DATA, false, &result); break; case SOCKET_CLOSE: forward_message(SKYNET_SOCKET_TYPE_CLOSE, false, &result); break; case SOCKET_OPEN: forward_message(SKYNET_SOCKET_TYPE_CONNECT, true, &result); break; case SOCKET_ERROR: forward_message(SKYNET_SOCKET_TYPE_ERROR, false, &result); break; case SOCKET_ACCEPT: forward_message(SKYNET_SOCKET_TYPE_ACCEPT, true, &result); break; default: skynet_error(NULL, "Unknown socket message type %d.",type); return -1; } if (more) { return -1; } return 1; }
static int _remote_send_handle(struct harbor *h, uint32_t source, uint32_t destination, int type, int session, const char * msg, size_t sz) { int harbor_id = destination >> HANDLE_REMOTE_SHIFT; assert(harbor_id != 0); struct skynet_context * context = h->ctx; if (harbor_id == h->id) { // local message skynet_send(context, source, destination , type | PTYPE_TAG_DONTCOPY, session, (void *)msg, sz); return 1; } int fd = h->remote_fd[harbor_id]; if (fd >= 0 && h->connected[harbor_id]) { struct remote_message_header cookie; cookie.source = source; cookie.destination = (destination & HANDLE_MASK) | ((uint32_t)type << HANDLE_REMOTE_SHIFT); cookie.session = (uint32_t)session; _send_remote(context, fd, msg,sz,&cookie); } else { // throw an error return to source if (session != 0) { skynet_send(context, destination, source, PTYPE_RESERVED_ERROR, session, NULL, 0); } skynet_error(context, "Drop message to harbor %d from %x to %x (session = %d, msgsz = %d)",harbor_id, source, destination,session,(int)sz); } return 0; }
static int _connect_to(struct harbor *h, const char *ipaddress, bool blocking) { char * port = strchr(ipaddress, ':'); if (port == NULL) { return -1; } int sz = port - ipaddress; char tmp[sz + 1]; memcpy(tmp, ipaddress, sz); tmp[sz] = '\0'; int portid = strtol(port + 1, NULL, 10); skynet_error(h->ctx, "Harbor(%d) connect to %s:%d", h->id, tmp, portid); if (blocking) { return skynet_socket_block_connect(h->ctx, tmp, portid); } else { return skynet_socket_connect(h->ctx, tmp, portid); } }
static void _update_address(struct skynet_context * context, struct master *m, int harbor_id, const char * buffer, size_t sz) { if (m->remote_fd[harbor_id] >= 0) { close(m->remote_fd[harbor_id]); m->remote_fd[harbor_id] = -1; } free(m->remote_addr[harbor_id]); char * addr = malloc(sz+1); memcpy(addr, buffer, sz); addr[sz] = '\0'; m->remote_addr[harbor_id] = addr; int fd = _connect_to(addr); if (fd<0) { skynet_error(context, "Can't connect to harbor %d : %s", harbor_id, addr); return; } m->remote_fd[harbor_id] = fd; _broadcast(context, m, addr, sz, harbor_id); int i; for (i=1;i<REMOTE_MAX;i++) { if (i == harbor_id) continue; const char * addr = m->remote_addr[i]; if (addr == NULL) { continue; } _send_to(fd, addr, strlen(addr), i); } }
int broker_init(struct broker *b, struct skynet_context *ctx, const char * args) { b->launcher = skynet_queryname(ctx, LAUNCHER); if (b->launcher == 0) { skynet_error(ctx, "Can't query %s", LAUNCHER); return 1; } char * service = strchr(args,' '); if (service == NULL) { return 1; } int len = service - args; if (len>0) { b->name = malloc(len +1); memcpy(b->name, args, len); b->name[len] = '\0'; } service++; int i; len = strlen(service); if (len == 0) return 1; for (i=0;i<DEFAULT_NUMBER;i++) { int id = skynet_send(ctx, 0, b->launcher , -1, service , len, 0); assert(id > 0 && id <= DEFAULT_NUMBER); } skynet_callback(ctx, b, _cb); return 0; }
static int _error(lua_State *L) { struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1)); const char *p = luaL_checkstring(L, 1); skynet_error(context, "%s", p); return 0; }
static void command(struct skynet_context *ctx, struct package *P, int session, uint32_t source, const char *msg, size_t sz) { switch (msg[0]) { case 'R': // request a package if (P->closed) { skynet_send(ctx, 0, source, PTYPE_ERROR, session, NULL, 0); break; } if (!queue_empty(&P->response)) { assert(queue_empty(&P->request)); struct response resp; queue_pop(&P->response, &resp); skynet_send(ctx, 0, source, PTYPE_RESPONSE | PTYPE_TAG_DONTCOPY, session, resp.msg, resp.sz); } else { struct request req; req.source = source; req.session = session; queue_push(&P->request, &req); } break; case 'K': // shutdown the connection skynet_socket_shutdown(ctx, P->fd); break; case 'I': report_info(ctx, P, session, source); break; default: // invalid command skynet_error(ctx, "Invalid command %.*s", (int)sz, msg); skynet_send(ctx, 0, source, PTYPE_ERROR, session, NULL, 0); break; }; }
static int _mainloop(struct skynet_context * context, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) { if (type == PTYPE_SOCKET) { dispatch_socket((struct master *)ud, (const skynet_socket_message *)msg, (int)sz); return 0; } if (type != PTYPE_HARBOR) { skynet_error(context, "None harbor message recv from %x (type = %d)", source, type); return 0; } assert(sz >= 4); struct master *m = (struct master*)ud; const uint8_t *handlen = (const uint8_t *)msg; uint32_t handle = handlen[0]<<24 | handlen[1]<<16 | handlen[2]<<8 | handlen[3]; sz -= 4; const char * name = (const char *)msg; name += 4; if (handle == 0) { _request_name(m , name, sz); } else if (handle < REMOTE_MAX) { _update_address(m , handle, name, sz); } else { _update_name(m , handle, name, sz); } return 0; }
/* string tag string userstring thread co (default nil) integer level */ static int ltrace(lua_State *L) { struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1)); const char * tag = luaL_checkstring(L, 1); const char * user = luaL_checkstring(L, 2); if (lua_isthread(L, 3)) { lua_State * co = lua_tothread (L, 3); struct source_info si[MAX_LEVEL]; lua_Debug d; int level = luaL_checkinteger(L, 4); int index = 0; do { if (!lua_getstack(co, level, &d)) break; lua_getinfo(co, "Sl", &d); level++; si[index].source = d.source; si[index].line = d.currentline; if (d.currentline >= 0) ++index; } while (index < MAX_LEVEL); switch (index) { case 1: skynet_error(context, "<TRACE %s> %" PRId64 " %s : %s:%d", tag, get_time(), user, si[0].source, si[0].line); break; case 2: skynet_error(context, "<TRACE %s> %" PRId64 " %s : %s:%d %s:%d", tag, get_time(), user, si[0].source, si[0].line, si[1].source, si[1].line ); break; case 3: skynet_error(context, "<TRACE %s> %" PRId64 " %s : %s:%d %s:%d %s:%d", tag, get_time(), user, si[0].source, si[0].line, si[1].source, si[1].line, si[2].source, si[2].line ); break; default: skynet_error(context, "<TRACE %s> %" PRId64 " %s", tag, get_time(), user); break; } return 0; } skynet_error(context, "<TRACE %s> %" PRId64 " %s", tag, get_time(), user); return 0; }
static void _ctrl(struct gate * g, const void * msg, int sz) { struct skynet_context * ctx = g->ctx; char tmp[sz+1]; memcpy(tmp, msg, sz); tmp[sz] = '\0'; char * command = tmp; int i; if (sz == 0) return; for (i=0;i<sz;i++) { if (command[i]==' ') { break; } } if (memcmp(command,"kick",i)==0) { _parm(tmp, sz, i); int uid = strtol(command , NULL, 10); int id = hashid_lookup(&g->hash, uid); if (id>=0) { skynet_socket_close(ctx, uid); } return; } if (memcmp(command,"forward",i)==0) { _parm(tmp, sz, i); char * client = tmp; char * idstr = strsep(&client, " "); if (client == NULL) { return; } int id = strtol(idstr , NULL, 10); char * agent = strsep(&client, " "); if (client == NULL) { return; } uint32_t agent_handle = strtoul(agent+1, NULL, 16); uint32_t client_handle = strtoul(client+1, NULL, 16); _forward_agent(g, id, agent_handle, client_handle); return; } if (memcmp(command,"broker",i)==0) { _parm(tmp, sz, i); g->broker = skynet_queryname(ctx, command); return; } if (memcmp(command,"start",i) == 0) { skynet_socket_start(ctx, g->listen_id); return; } if (memcmp(command, "close", i) == 0) { if (g->listen_id >= 0) { skynet_socket_close(ctx, g->listen_id); g->listen_id = -1; } return; } skynet_error(ctx, "[gate] Unkown command : %s", command); }
int mallctl_opt(const char* name, int* newval) { int v = 0; size_t len = sizeof(v); if(newval) { int ret = je_mallctl(name, &v, &len, newval, sizeof(int)); if(ret == 0) { skynet_error(NULL, "set new value(%d) for (%s) succeed\n", *newval, name); } else { skynet_error(NULL, "set new value(%d) for (%s) failed: error -> %d\n", *newval, name, ret); } } else { je_mallctl(name, &v, &len, NULL, 0); } return v; }
void snlua_signal(struct snlua *l, int signal) { skynet_error(l->ctx, "recv a signal %d", signal); #ifdef lua_checksig // If our lua support signal (modified lua version by skynet), trigger it. skynet_sig_L = l->L; #endif }
static int _cb(struct skynet_context * context, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) { lua_State *L = ud; int trace = 1; int r; int top = lua_gettop(L); if (top == 0) { lua_pushcfunction(L, traceback); lua_rawgetp(L, LUA_REGISTRYINDEX, _cb); } else { assert(top == 2); } lua_pushvalue(L,2); lua_pushinteger(L, type); lua_pushlightuserdata(L, (void *)msg); lua_pushinteger(L,sz); lua_pushinteger(L, session); lua_pushnumber(L, source); r = lua_pcall(L, 5, 0 , trace); if (r == LUA_OK) { return 0; } const char * self = skynet_command(context, "REG", NULL); switch (r) { case LUA_ERRRUN: skynet_error(context, "lua call [%x to %s : %d msgsz = %d] error : " KRED "%s" KNRM, source , self, session, sz, lua_tostring(L,-1)); break; case LUA_ERRMEM: skynet_error(context, "lua memory error : [%x to %s : %d]", source , self, session); break; case LUA_ERRERR: skynet_error(context, "lua error in error : [%x to %s : %d]", source , self, session); break; case LUA_ERRGCMM: skynet_error(context, "lua gc error : [%x to %s : %d]", source , self, session); break; }; lua_pop(L,1); return 0; }
static void _connect_to(struct master *m, int id) { assert(m->connected[id] == false); struct skynet_context * ctx = m->ctx; const char *ipaddress = m->remote_addr[id]; char * portstr = strchr(ipaddress,':'); if (portstr==NULL) { skynet_error(ctx, "Harbor %d : address invalid (%s)",id, ipaddress); return; } int sz = portstr - ipaddress; char tmp[sz + 1]; memcpy(tmp,ipaddress,sz); tmp[sz] = '\0'; int port = strtol(portstr+1,NULL,10); skynet_error(ctx, "Master connect to harbor(%d) %s:%d", id, tmp, port); m->remote_fd[id] = skynet_socket_connect(ctx, tmp, port); }
static void _report_error(lua_State *L, struct skynet_context *ctx, const char *filename, int err) { switch (err) { case LUA_ERRRUN: skynet_error(ctx, "lua do [%s] error : %s", filename, lua_tostring(L,-1)); break; case LUA_ERRMEM: skynet_error(ctx, "lua memory error : %s",filename); break; case LUA_ERRERR: skynet_error(ctx, "lua message error : %s",filename); break; case LUA_ERRGCMM: skynet_error(ctx, "lua gc error : %s",filename); break; }; lua_pop(L,1); }
static void dispatch_socket(struct master *m, const struct skynet_socket_message *msg, int sz) { int id = socket_id(m, msg->id); switch(msg->type) { case SKYNET_SOCKET_TYPE_CONNECT: assert(id); on_connected(m, id); break; case SKYNET_SOCKET_TYPE_ERROR: skynet_error(m->ctx, "socket error on harbor %d", id); // go though, close socket case SKYNET_SOCKET_TYPE_CLOSE: close_harbor(m, id); break; default: skynet_error(m->ctx, "Invalid socket message type %d", msg->type); break; } }