static void
_update_address(struct master *m, int harbor_id, const char * buffer, size_t sz) {
	if (m->remote_fd[harbor_id] >= 0) {
		close_harbor(m, harbor_id);
	}
	skynet_free(m->remote_addr[harbor_id]);
	char * addr = (char*)skynet_malloc(sz+1);
	memcpy(addr, buffer, sz);
	addr[sz] = '\0';
	m->remote_addr[harbor_id] = addr;
	_connect_to(m, harbor_id);
}
Beispiel #2
0
void
harbor_release(struct harbor *h) {
	int i;
	for (i=1;i<REMOTE_MAX;i++) {
		struct slave *s = &h->s[i];
		if (s->fd && s->status != STATUS_DOWN) {
			close_harbor(h,i);
			report_harbor_down(h,i);
		}
	}
	hash_delete(h->map);
	skynet_free(h);
}
Beispiel #3
0
void
harbor_release(struct harbor *h) {
	int i;
	for (i=1;i<REMOTE_MAX;i++) {
		struct slave *s = &h->s[i];
		if (s->fd && s->status != STATUS_DOWN) {
			close_harbor(h,i);
			// don't call report_harbor_down.
			// never call skynet_send during module exit, because of dead lock
		}
	}
	hash_delete(h->map);
	skynet_free(h);
}
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;
	}
}
static int
_mainloop(struct skynet_context * context, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) {
	struct harbor * h = (struct harbor *)ud;
	switch (type) {
	case PTYPE_SOCKET: {
		const struct skynet_socket_message * message = (const struct skynet_socket_message *)msg;
		switch(message->type) {
		case SKYNET_SOCKET_TYPE_DATA:
			skynet_free(message->buffer);
			skynet_error(context, "recv invalid socket message (size=%d)", message->ud);
			break;
		case SKYNET_SOCKET_TYPE_ACCEPT:
			skynet_error(context, "recv invalid socket accept message");
			break;
		case SKYNET_SOCKET_TYPE_ERROR:
		case SKYNET_SOCKET_TYPE_CLOSE:
			close_harbor(h, message->id);
			break;
		case SKYNET_SOCKET_TYPE_CONNECT:
			open_harbor(h, message->id);
			break;
		}
		return 0;
	}
	case PTYPE_HARBOR: {
		// remote message in
		const char * cookie = (const char *)msg;
		cookie += sz - 12;
		struct remote_message_header header;
		_message_to_header((const uint32_t *)cookie, &header);
		if (header.source == 0) {
			if (header.destination < REMOTE_MAX) {
				// 1 byte harbor id (0~255)
				// update remote harbor address
				//char ip [sz - 11];
				char ip [100];
				memcpy(ip, msg, sz-12);
				ip[sz-11] = '\0';
				_update_remote_address(h, header.destination, ip);
			} else {
				// update global name
				if (sz - 12 > GLOBALNAME_LENGTH) {
					//char name[sz-11];
					char name[100];
					memcpy(name, msg, sz-12);
					name[sz-11] = '\0';
					skynet_error(context, "Global name is too long %s", name);
				}
				_update_remote_name(h, (const char*)msg, header.destination);
			}
		} else {
			uint32_t destination = header.destination;
			int type = (destination >> HANDLE_REMOTE_SHIFT) | PTYPE_TAG_DONTCOPY;
			destination = (destination & HANDLE_MASK) | ((uint32_t)h->id << HANDLE_REMOTE_SHIFT);
			skynet_send(context, header.source, destination, type, (int)header.session, (void *)msg, sz-12);
			return 1;
		}
		return 0;
	}
	case PTYPE_SYSTEM: {
		// register name message
		const struct remote_message *rmsg = (const struct remote_message *)msg;
		assert (sz == sizeof(rmsg->destination));
		_remote_register_name(h, rmsg->destination.name, rmsg->destination.handle);
		return 0;
	}
	default: {
		// remote message out
		const struct remote_message *rmsg = (const struct remote_message *)msg;
		if (rmsg->destination.handle == 0) {
			if (_remote_send_name(h, source , rmsg->destination.name, type, session, (const char*)rmsg->message, rmsg->sz)) {
				return 0;
			}
		} else {
			if (_remote_send_handle(h, source , rmsg->destination.handle, type, session, (const char *)rmsg->message, rmsg->sz)) {
				return 0;
			}
		}
		skynet_free((void *)rmsg->message);
		return 0;
	}
	}
}