Esempio n. 1
0
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;
}
Esempio n. 2
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;
}
Esempio n. 3
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);
	}
}
Esempio n. 4
0
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;
}
Esempio n. 5
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);
}
Esempio n. 6
0
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;
}
Esempio n. 7
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;
}
Esempio n. 8
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;
}
Esempio n. 9
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);
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
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);
	}
}
Esempio n. 12
0
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;
}
Esempio n. 13
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;
}
Esempio n. 14
0
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;
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
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;
}
Esempio n. 17
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);
    }
}
Esempio n. 18
0
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);
	}
}
Esempio n. 19
0
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;
}
Esempio n. 20
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;
}
Esempio n. 21
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;
	};
}
Esempio n. 22
0
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;
}
Esempio n. 23
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;
}
Esempio n. 24
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);
}
Esempio n. 25
0
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;
}
Esempio n. 26
0
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
}
Esempio n. 27
0
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;
}
Esempio n. 28
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);
}
Esempio n. 29
0
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);
}
Esempio n. 30
0
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;
	}
}