/* process echo request */ static int __process_test_echo(char * buf, int size, int ent_id) { logdebug(_("sending echo reply ...\n")); logdebug(_("%s\n"), buf); int fd = ly_entity_fd(ent_id); return ly_packet_send(fd, PKT_TYPE_TEST_ECHO_REPLY, buf, size); }
/* process raw auth request from node */ int eh_process_node_auth(int is_reply, void * data, int ent_id) { logdebug(_("%s called\n"), __func__); int ret; AuthInfo * ai = data; AuthConfig * ac = ly_entity_auth(ent_id); if (is_reply) { loginfo(_("auth reply from node %d(tag)\n"), ai->tag); ret = lyauth_verify(ac, ai->data, LUOYUN_AUTH_DATA_LEN); if (ret < 0) { logerror(_("error in %s(%d)\n"), __func__, __LINE__); return -1; } if (ret) { loginfo(_("node %d(tag) is authenticated\n"), ai->tag); if (!ly_entity_is_authenticated(ent_id)) ly_entity_update(ent_id, -1, LY_ENTITY_FLAG_STATUS_AUTHENTICATED); } else { logwarn(_("chanllenge verification for node %d(tag) failed.\n"), ai->tag); return 1; } return 0; } loginfo(_("auth request from node %d(tag)\n"), ai->tag); LYNodeData * nd = ly_entity_data(ent_id); if (nd == NULL) { logerror(_("error in %s(%d)\n"), __func__, __LINE__); return -1; } NodeInfo * nf = &nd->node; /* get secret */ if (ac->secret == NULL) { logdebug(_("retrieve auth key for node %d(tag)\n"), ai->tag); ret = db_node_find_secret(DB_NODE_FIND_BY_ID, &ai->tag, &ac->secret); if (ret < 0) { logerror(_("error in %s(%d)\n"), __func__, __LINE__); return -1; } else if (ret == 0) { logerror(_("node(tag: %d) not in db\n"), ai->tag); return -1; } nf->host_tag = ai->tag; } /* update node status */ logdebug(_("update node status to %d\n"), NODE_STATUS_AUTHENTICATING); ret = db_node_update_status(DB_NODE_FIND_BY_ID, &ai->tag, NODE_STATUS_AUTHENTICATING); if (ret < 0) { logerror(_("error in %s(%d)\n"), __func__, __LINE__); return -1; } /* resolve challenge */ logdebug(_("answer auth request\n")); ret = lyauth_answer(ac, ai->data, LUOYUN_AUTH_DATA_LEN); if (ret < 0) { logerror(_("error in %s(%d)\n"), __func__, __LINE__); return -1; } /* send answer back */ int fd = ly_entity_fd(ent_id); if (ly_packet_send(fd, PKT_TYPE_NODE_AUTH_REPLY, ai, sizeof(AuthInfo)) < 0) { logerror(_("error in %s(%d)\n"), __func__, __LINE__); return -1; } /* request challenging */ logdebug(_("clc sends out auth request\n")); if (lyauth_prepare(ac) < 0) { logerror(_("error in %s(%d)\n"), __func__, __LINE__); return -1; } bzero(ai->data, LUOYUN_AUTH_DATA_LEN); strncpy((char *)ai->data, ac->challenge, LUOYUN_AUTH_DATA_LEN); if (ly_packet_send(fd, PKT_TYPE_NODE_AUTH_REQUEST, ai, sizeof(AuthInfo)) < 0) { logerror(_("error in %s(%d)\n"), __func__, __LINE__); return -1; } loginfo(_("node %d(tag) is online\n"), nf->host_tag); ly_entity_update(ent_id, nf->host_tag, LY_ENTITY_FLAG_STATUS_ONLINE); return 0; }
/* process xml request */ static int __process_node_xml_request(xmlDoc * doc, xmlNode * node, int ent_id) { loginfo(_("node request for entity %d\n"), ent_id); char *str = (char *) xmlGetProp(node, (const xmlChar *) "action"); int action = atoi(str); if (action != LY_A_CLC_REGISTER_NODE) { logerror(_("clc received non-register node request.\n")); free(str); return -1; } free(str); loginfo(_("node register request\n")); str = (char *) xmlGetProp(node, (const xmlChar *) "id"); if (str) logdebug("id = %s\n", str); else { logerror(_("error in %s(%d)\n"), __func__, __LINE__); return -1; } int id = atoi(str); free(str); int ret = __node_xml_register(doc, node, ent_id); if (ret < 0) logerror(_("node registeration failed.\n")); else if (ret == 0) { logdebug(_("node register not complete\n")); return 0; } LYNodeData * nd = ly_entity_data(ent_id); if (nd == NULL ) { logerror(_("error in %s(%d)\n"), __func__, __LINE__); return -1; } NodeInfo * nf = &nd->node; AuthConfig * ac = ly_entity_auth(ent_id); AuthInfo ai; ai.tag = nf->host_tag > 0 ? nf->host_tag : 0; if (ac->secret && ret == LY_S_REGISTERING_CONFIG) { bzero(ai.data, LUOYUN_AUTH_DATA_LEN); int len = strlen(ac->secret); strncpy((char *)ai.data, ac->secret, len > LUOYUN_AUTH_DATA_LEN ? LUOYUN_AUTH_DATA_LEN : len); } else ai.data[0] = '\0'; int fd = ly_entity_fd(ent_id); LYReply r; r.req_id = id; r.from = LY_ENTITY_CLC; r.to = LY_ENTITY_NODE; r.status = ret; r.data = &ai; char *response = lyxml_data_reply_auth_info(&r, NULL, 0); ret = ly_packet_send(fd, PKT_TYPE_NODE_REGISTER_REPLY, response, strlen(response)); free(response); return ret; }
/* clc work socket receives connection */ static int __epoll_work_recv(int ent_id) { int fd = ly_entity_fd(ent_id); if (fd == -1) return -255; struct sockaddr in_addr; socklen_t in_len; int infd; in_len = sizeof(in_addr); infd = accept(fd, &in_addr, &in_len); if (infd == -1) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { /* We have processed all incoming connections. */ logdebug(_("accept error(%d) ignored\n"), errno); return 0; } else { logerror(_("unexpected accept error(%d) in %s"), errno, __func__); return -1; } } char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; int ret = getnameinfo(&in_addr, in_len, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV); if (ret) logerror(_("error in %s(%d)\n"), __func__, __LINE__); else loginfo(_("accepted connection from %s:%s. open socket %d\n"), hbuf, sbuf, infd); /* keep alive */ if (lyutil_set_keepalive(infd, CLC_SOCKET_KEEPALIVE_INTVL, CLC_SOCKET_KEEPALIVE_INTVL, CLC_SOCKET_KEEPALIVE_PROBES) < 0) { logerror(_("error in %s(%d)\n"), __func__, __LINE__); close(infd); return -1; } int id = ly_entity_new(infd); if (id < 0) { logerror(_("error in %s(%d)\n"), __func__, __LINE__); close(infd); return -1; } struct epoll_event ev; ev.data.fd = id; ev.events = EPOLLIN; ret = epoll_ctl(g_efd, EPOLL_CTL_ADD, infd, &ev); if (ret == -1) { logerror(_("add socket to epoll error in %s.\n"), __func__); ly_entity_release(id); /* close(infd); closed in ly_entity_release */ return -1; } loginfo(_("entity %d registered in epoll.\n"), id); return 0; }
int ly_epoll_entity_recv(int ent_id) { if (ly_entity_type(ent_id) == LY_ENTITY_CLC) return __epoll_work_recv(ent_id); int fd = ly_entity_fd(ent_id); if (fd < 0) { logerror(_("fd for entity %d was closed. ignore event.\n"), ent_id); return 1; } LYPacketRecv *pkt = ly_entity_pkt(ent_id); if (pkt == NULL) return -255; int size; void * buf = ly_packet_buf(pkt, &size); if (buf == NULL) { logerror(_("ly_packet_buf returns NULL buffer. close socket\n")); return 1; } if (size == 0) { logerror(_("ly_packet_buf returns 0 size buffer. close socket\n")); return 1; } int len = recv(fd, buf, size, 0); if (len <= 0) { loginfo(_("socket %d recv returns %d. close socket\n"), fd, len); if (len < 0) loginfo(_("socket %d recv, errno %d\n"), fd, errno); int type = ly_entity_type(ent_id); int db_id = ly_entity_db_id(ent_id); if (type == LY_ENTITY_NODE) { logdebug(_("update node %d status in db to offline\n"), db_id); db_node_update_status(DB_NODE_FIND_BY_ID, &db_id, NODE_STATUS_OFFLINE); return 1; } if (ly_entity_type(ent_id) != LY_ENTITY_OSM) return 1; logdebug(_("update instance %d status in db\n"), db_id); InstanceInfo ii; ii.ip = NULL; ii.status = DOMAIN_S_NEED_QUERY; db_instance_update_status(db_id, &ii, -1); job_internal_query_instance(db_id); return 1; } logdebug(_("socket %d recv %d bytes\n"), fd, len); while(1) { int ret = ly_packet_recv(pkt, len); if (ret < 0) { logerror(_("package recv error in %s\n"), __func__); __print_recv_buf(buf, len); break; } /* currenly we only support processing a complete packet */ if (ret == 0) { if (pkt->pkt_buf_received > 0) { loginfo(_("socket %d recv partial packet(len %d)\n"), fd, pkt->pkt_buf_received); __print_recv_buf(buf, len); } break; } int type = ly_packet_type(pkt); loginfo(_("socket %d recv packet, type %d\n"), fd, type); /* if (type == PKT_TYPE_UNKNOW) break; */ buf = ly_packet_data(pkt, &size); if (type == PKT_TYPE_WEB_NEW_JOB_REQUEST) { ly_entity_init(ent_id, LY_ENTITY_WEB); ret = __process_web_job(buf, size, ent_id); if (ret < 0) logerror(_("web packet process error in %s.\n"), __func__); } else if (type == PKT_TYPE_NODE_REGISTER_REQUEST) { ly_entity_init(ent_id, LY_ENTITY_NODE); ret = eh_process_node_xml(buf, ent_id); if (ret < 0) logerror(_("node packet process error in %s.\n"), __func__); } else if (type == PKT_TYPE_NODE_AUTH_REQUEST || type == PKT_TYPE_NODE_AUTH_REPLY) { ly_entity_init(ent_id, LY_ENTITY_NODE); ret = eh_process_node_auth(type == PKT_TYPE_NODE_AUTH_REPLY ? 1 : 0, buf, ent_id); if (ret < 0) logerror(_("node auth packet process error in %s.\n"), __func__); } else if (type == PKT_TYPE_OSM_AUTH_REQUEST || type == PKT_TYPE_OSM_AUTH_REPLY) { ly_entity_init(ent_id, LY_ENTITY_OSM); ret = eh_process_osm_auth(type == PKT_TYPE_OSM_AUTH_REPLY ? 1 : 0, buf, ent_id); if (ret < 0) logerror(_("osm auth packet process error in %s.\n"), __func__); } else if (type == PKT_TYPE_CLC_OSM_QUERY_REPLY) { ret = eh_process_osm_query(ly_packet_data(pkt, NULL)); if (ret < 0) logerror(_("osm packet process error in %s\n"), __func__); } else if (PKT_TYPE_ENTITY_GROUP_CLC(type) || PKT_TYPE_ENTITY_GROUP_NODE(type)) { ret = eh_process_node_xml(buf, ent_id); if (ret < 0) logerror(_("node packet process error in %s.\n"), __func__); } else if (type == PKT_TYPE_OSM_REGISTER_REQUEST) { ly_entity_init(ent_id, LY_ENTITY_OSM); ret = eh_process_osm_register(buf, size, ent_id); if (ret < 0) logerror(_("osm packet process error in %s.\n"), __func__); } else if (type == PKT_TYPE_OSM_REPORT) { ret = eh_process_osm_report(buf, size, ent_id); if (ret < 0) logerror(_("osm packet process error in %s.\n"), __func__); } else if (type == PKT_TYPE_TEST_ECHO_REQUEST) { ret = __process_test_echo(buf, size, ent_id); if (ret < 0) logerror(_("echo packet process error in %s.\n"), __func__); } else { logerror(_("unrecognized packet type.\n")); } if (ly_packet_recv_done(pkt) < 0 || ret < 0) { logerror(_("%s return error\n"), __func__); return -1; } if (ret > 0) return ret; len = 0; /* continue processing data in buffer */ } return 0; }