コード例 #1
0
ファイル: events.c プロジェクト: alayasix/LuoYunCloud
/* 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);
}
コード例 #2
0
ファイル: ev_node.c プロジェクト: cloudcache/LuoYunCloud
/* 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;
}
コード例 #3
0
ファイル: ev_node.c プロジェクト: cloudcache/LuoYunCloud
/* 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;
}
コード例 #4
0
ファイル: events.c プロジェクト: alayasix/LuoYunCloud
/* 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;
}
コード例 #5
0
ファイル: events.c プロジェクト: alayasix/LuoYunCloud
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;
}