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); }
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 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); }
/* unsigned address string address integer type integer session string message lightuserdata message_ptr integer len */ static int _send(lua_State *L) { struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1)); int addr_type = lua_type(L,1); uint32_t dest = 0; switch(addr_type) { case LUA_TNUMBER: dest = lua_tounsigned(L,1); break; case LUA_TSTRING: { const char * addrname = lua_tostring(L,1); if (addrname[0] == '.' || addrname[0] == ':') { dest = skynet_queryname(context, addrname); if (dest == 0) { luaL_error(L, "Invalid name %s", addrname); } } else if ('0' <= addrname[0] && addrname[0] <= '9') { luaL_error(L, "Invalid name %s: must not start with a digit", addrname); } else { return _sendname(L, context, addrname); } break; } default: return luaL_error(L, "address must be number or string, got %s",lua_typename(L,addr_type)); } int type = luaL_checkinteger(L, 2); int session = 0; if (lua_isnil(L,3)) { type |= PTYPE_TAG_ALLOCSESSION; } else { session = luaL_checkinteger(L,3); } int mtype = lua_type(L,4); switch (mtype) { case LUA_TSTRING: { size_t len = 0; void * msg = (void *)lua_tolstring(L,4,&len); if (len == 0) { msg = NULL; } session = skynet_send(context, 0, dest, type, session , msg, len); break; } case LUA_TLIGHTUSERDATA: { void * msg = lua_touserdata(L,4); int size = luaL_checkinteger(L,5); session = skynet_send(context, 0, dest, type | PTYPE_TAG_DONTCOPY, session, msg, size); break; } default: luaL_error(L, "skynet.send invalid param %s", lua_type(L,4)); } lua_pushinteger(L,session); return 1; }
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); }
int tunnel_init(void * dummy, struct skynet_context *ctx, const char * args) { uint32_t dest = skynet_queryname(ctx, args); if (dest == 0) { skynet_error(ctx, "Can't create tunnel to %s",args); return 1; } skynet_callback(ctx, (void*)(intptr_t)dest, _cb); return 0; }
static void _ctrl(struct skynet_context * ctx, struct gate * g, const void * msg, int sz) { 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); struct connection * agent = _id_to_agent(g,uid); if (agent) { int connection_id = agent->connection_id; mread_close_client(g->pool,connection_id); } 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_command(ctx,"TIMEOUT","0"); return; } skynet_error(ctx, "[gate] Unkown command : %s", command); }
int gate_init(struct gate *g , struct skynet_context * ctx, char * parm) { int port = 0; int max = 0; int buffer = 0; int sz = strlen(parm)+1; char watchdog[sz]; char binding[sz]; int client_tag = 0; int n = sscanf(parm, "%s %s %d %d %d",watchdog, binding,&client_tag , &max,&buffer); if (n<3) { skynet_error(ctx, "Invalid gate parm %s",parm); return 1; } if (client_tag == 0) { client_tag = PTYPE_CLIENT; } char * portstr = strchr(binding,':'); uint32_t addr = INADDR_ANY; if (portstr == NULL) { port = strtol(binding, NULL, 10); if (port <= 0) { skynet_error(ctx, "Invalid gate address %s",parm); return 1; } } else { port = strtol(portstr + 1, NULL, 10); if (port <= 0) { skynet_error(ctx, "Invalid gate address %s",parm); return 1; } portstr[0] = '\0'; addr=inet_addr(binding); } struct mread_pool * pool = mread_create(addr, port, max, buffer); if (pool == NULL) { skynet_error(ctx, "Create gate %s failed",parm); return 1; } 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->pool = pool; int cap = 1; while (cap < max) { cap *= 2; } g->cap = cap; g->max_connection = max; g->id_index = 0; g->client_tag = client_tag; g->agent = malloc(cap * sizeof(struct connection *)); memset(g->agent, 0, cap * sizeof(struct connection *)); g->map = malloc(max * sizeof(struct connection)); memset(g->map, 0, max * sizeof(struct connection)); int i; for (i=0;i<max;i++) { g->map[i].connection_id = i; } skynet_callback(ctx,g,_cb); return 0; }