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 = ud; switch (type) { case PTYPE_HARBOR: { // remote message in const char * cookie = 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]; memcpy(ip, msg, sz-12); ip[sz-11] = '\0'; _update_remote_address(context, h, header.destination, ip); } else { // update global name if (sz - 12 > GLOBALNAME_LENGTH) { char name[sz-11]; memcpy(name, msg, sz-12); name[sz-11] = '\0'; skynet_error(context, "Global name is too long %s", name); } _update_remote_name(h, context, 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 = msg; assert (sz == sizeof(rmsg->destination)); _remote_register_name(h, context, rmsg->destination.name, rmsg->destination.handle); return 0; } default: { // remote message out const struct remote_message *rmsg = msg; if (rmsg->destination.handle == 0) { if (_remote_send_name(h, context, source , rmsg->destination.name, type, session, rmsg->message, rmsg->sz)) { return 0; } } else { if (_remote_send_handle(h, context, source , rmsg->destination.handle, type, session, rmsg->message, rmsg->sz)) { return 0; } } free((void *)rmsg->message); return 0; } } }
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; } } }