void vroute_srvc_space_deinit(struct vroute_srvc_space* space) { int i = 0; space->ops->clear(space); for (i = 0; i < NBUCKETS; i++) { varray_deinit(&space->bucket[i].srvcs); } return ; }
int AdtInit(int verbose, struct cfg *cfg, char *args[]) { char buf[0xFFFF]; struct allocator *suba; struct stack s; struct linkedlist l; struct varray va; if ((suba = suba_init(buf, 0xFFFF, 1, 0)) == NULL || stack_init(&s, 0, suba) == -1 || linkedlist_init(&l, 0, suba) == -1 || varray_init(&va, sizeof(int), suba) == -1) { AMSG(""); return -1; } linkedlist_add(&l, "two"); stack_push(&s, "two"); linkedlist_add(&l, "three"); stack_push(&s, "one"); varray_get(&va, 444); stack_push(&s, "three"); varray_get(&va, 4); varray_get(&va, 44); linkedlist_add(&l, "one"); if (varray_deinit(&va) != 0 || linkedlist_deinit(&l, NULL, NULL) != 0 || stack_deinit(&s, NULL, NULL) != 0) { AMSG(""); return -1; } tcase_printf(verbose, "done "); cfg = NULL; args[0] = NULL; return 0; }
/* * the routine to pack a @ping query and send it. * @route: * @conn: */ static int _vroute_dht_ping(struct vroute* route, vnodeConn* conn) { struct vroute_recr_space* recr_space = &route->recr_space; void* buf = NULL; vtoken token; int ret = 0; vassert(route); vassert(conn); retS((!(route->props & PROP_PING))); //ping disabled. buf = vdht_buf_alloc(); retE((!buf)); vtoken_make(&token); ret = route->enc_ops->ping(&token, &route->myid, buf, vdht_buf_len()); ret1E((ret < 0), vdht_buf_free(buf)); { struct vmsg_usr msg = { .addr = to_vsockaddr_from_sin(&conn->remote), .spec = to_vsockaddr_from_sin(&conn->local), .msgId = VMSG_DHT, .data = buf, .len = ret }; ret = route->msger->ops->push(route->msger, &msg); ret1E((ret < 0), vdht_buf_free(buf)); } route->ops->inspect(route, &token, VROUTE_INSP_SND_PING); // make a record according to the query, which will be used to // check invality of response msg. recr_space->ops->make(recr_space, &token); vlogD("send @ping"); return 0; } /* * the routine to pack and send a response to @ping query back to source node * where the ping query was from. * @route: * @conn: * @token: * @info : */ static int _vroute_dht_ping_rsp(struct vroute* route, vnodeConn* conn, vtoken* token, vnodeInfo* nodei) { void* buf = NULL; int ret = 0; vassert(route); vassert(conn); vassert(token); vassert(nodei); retS((!(route->props & PROP_PING_R))); buf = vdht_buf_alloc(); retE((!buf)); ret = route->enc_ops->ping_rsp(token, &route->myid, nodei, buf, vdht_buf_len()); ret1E((ret < 0), vdht_buf_free(buf)); { struct vmsg_usr msg = { .addr = to_vsockaddr_from_sin(&conn->remote), .spec = to_vsockaddr_from_sin(&conn->local), .msgId = VMSG_DHT, .data = buf, .len = ret }; ret = route->msger->ops->push(route->msger, &msg); ret1E((ret < 0), vdht_buf_free(buf)); } vlogD("send @ping_rsp"); return 0; } /* * the routine to pack and send @find_node query to specific node to get infos * of a given node. * @route: * @conn: * @target */ static int _vroute_dht_find_node(struct vroute* route, vnodeConn* conn, vnodeId* targetId) { struct vroute_recr_space* recr_space = &route->recr_space; void* buf = NULL; vtoken token; int ret = 0; vassert(route); vassert(conn); vassert(targetId); retS((!(route->props & PROP_FIND_NODE))); buf = vdht_buf_alloc(); retE((!buf)); vtoken_make(&token); ret = route->enc_ops->find_node(&token, &route->myid, targetId, buf, vdht_buf_len()); ret1E((ret < 0), vdht_buf_free(buf)); { struct vmsg_usr msg = { .addr = to_vsockaddr_from_sin(&conn->remote), .spec = to_vsockaddr_from_sin(&conn->local), .msgId = VMSG_DHT, .data = buf, .len = ret }; ret = route->msger->ops->push(route->msger, &msg); ret1E((ret < 0), vdht_buf_free(buf)); } route->ops->inspect(route, &token, VROUTE_INSP_SND_FIND_NODE); recr_space->ops->make(recr_space, &token); vlogD("send @find_node"); return 0; } /* * the routine to pack and send a response to @find_node query. * @route: * @conn: * @token: * @info: */ static int _vroute_dht_find_node_rsp(struct vroute* route, vnodeConn* conn, vtoken* token, vnodeInfo* nodei) { void* buf = NULL; int ret = 0; vassert(route); vassert(conn); vassert(token); vassert(nodei); retS((!(route->props & PROP_FIND_NODE_R))); buf = vdht_buf_alloc(); retE((!buf)); ret = route->enc_ops->find_node_rsp(token, &route->myid, nodei, buf, vdht_buf_len()); ret1E((ret < 0), vdht_buf_free(buf)); { struct vmsg_usr msg = { .addr = to_vsockaddr_from_sin(&conn->remote), .spec = to_vsockaddr_from_sin(&conn->local), .msgId = VMSG_DHT, .data = buf, .len = ret }; ret = route->msger->ops->push(route->msger, &msg); ret1E((ret < 0), vdht_buf_free(buf)); } vlogD("send @find_node_rsp"); return 0; } /* * the routine to pack and send a @find_closest_nodes query( closest to @targetId). * @route: * @conn: * @targetId: */ static int _vroute_dht_find_closest_nodes(struct vroute* route, vnodeConn* conn, vnodeId* targetId) { struct vroute_recr_space* recr_space = &route->recr_space; void* buf = NULL; vtoken token; int ret = 0; vassert(route); vassert(conn); vassert(targetId); retS((!(route->props & PROP_FIND_CLOSEST_NODES))); buf = vdht_buf_alloc(); retE((!buf)); vtoken_make(&token); ret = route->enc_ops->find_closest_nodes(&token, &route->myid, targetId, buf, vdht_buf_len()); ret1E((ret < 0), vdht_buf_free(buf)); { struct vmsg_usr msg = { .addr = to_vsockaddr_from_sin(&conn->remote), .spec = to_vsockaddr_from_sin(&conn->local), .msgId = VMSG_DHT, .data = buf, .len = ret }; ret = route->msger->ops->push(route->msger, &msg); ret1E((ret < 0), vdht_buf_free(buf)); } route->ops->inspect(route, &token, VROUTE_INSP_SND_FIND_CLOSEST_NODES); recr_space->ops->make(recr_space, &token); vlogD("send @find_closest_nodes"); return 0; } /* * the routine to pack and send back a response to @find_closest_nodes query. * @route: * @conn: * @token: * @closest: array of closest nodes (closest to given id); */ static int _vroute_dht_find_closest_nodes_rsp(struct vroute* route, vnodeConn* conn, vtoken* token, struct varray* closest) { void* buf = NULL; int ret = 0; vassert(route); vassert(conn); vassert(token); vassert(closest); retS((!(route->props & PROP_FIND_CLOSEST_NODES_R))); buf = vdht_buf_alloc(); retE((!buf)); ret = route->enc_ops->find_closest_nodes_rsp(token, &route->myid, closest, buf, vdht_buf_len()); ret1E((ret < 0), vdht_buf_free(buf)); { struct vmsg_usr msg = { .addr = to_vsockaddr_from_sin(&conn->remote), .spec = to_vsockaddr_from_sin(&conn->local), .msgId = VMSG_DHT, .data = buf, .len = ret }; ret = route->msger->ops->push(route->msger, &msg); ret1E((ret < 0), vdht_buf_free(buf)); } vlogD("send @find_closest_nodes_rsp"); return 0; } /* * the routine to pack and send a @reflex_addr query. * @route: * @conn: */ static int _vroute_dht_reflex(struct vroute* route, vnodeConn* conn) { struct vroute_recr_space* recr_space = &route->recr_space; void* buf = NULL; vtoken token; int ret = 0; vassert(route); vassert(conn); buf = vdht_buf_alloc(); retE((!buf)); vtoken_make(&token); ret = route->enc_ops->reflex(&token, &route->myid, buf, vdht_buf_len()); ret1E((ret < 0), vdht_buf_free(buf)); { struct vmsg_usr msg = { .addr = to_vsockaddr_from_sin(&conn->remote), .spec = to_vsockaddr_from_sin(&conn->local), .msgId = VMSG_DHT, .data = buf, .len = ret }; ret = route->msger->ops->push(route->msger, &msg); ret1E((ret < 0), vdht_buf_free(buf)); } route->ops->inspect(route, &token, VROUTE_INSP_SND_REFLEX); recr_space->ops->make(recr_space, &token); vlogD("send @reflex"); return 0; } /* * the routine to pack and send back a response to @reflex_addr query. * @route: * @conn: * @token: * @reflexive_addr: */ static int _vroute_dht_reflex_rsp(struct vroute* route, vnodeConn* conn, vtoken* token, struct sockaddr_in* reflexive_addr) { void* buf = NULL; int ret = 0; vassert(route); vassert(conn); vassert(token); vassert(reflexive_addr); buf = vdht_buf_alloc(); retE((!buf)); ret = route->enc_ops->reflex_rsp(token, &route->myid, reflexive_addr, buf, vdht_buf_len()); ret1E((ret < 0), vdht_buf_free(buf)); { struct vmsg_usr msg = { .addr = to_vsockaddr_from_sin(&conn->remote), .spec = to_vsockaddr_from_sin(&conn->local), .msgId = VMSG_DHT, .data = buf, .len = ret }; ret = route->msger->ops->push(route->msger, &msg); ret1E((ret < 0), vdht_buf_free(buf)); } vlogD("send @reflex_rsp"); return 0; } /* * the routine to pack and send a @probe_connectivity query * @route: * @conn: * @targetId: */ static int _vroute_dht_probe(struct vroute* route, vnodeConn* conn, vnodeId* targetId) { struct vroute_recr_space* recr_space = &route->recr_space; void* buf = NULL; vtoken token; int ret = 0; vassert(route); vassert(conn); vassert(targetId); buf = vdht_buf_alloc(); retE((!buf)); vtoken_make(&token); ret = route->enc_ops->probe(&token, &route->myid, targetId, buf, vdht_buf_len()); ret1E((ret < 0), vdht_buf_free(buf)); { struct vmsg_usr msg = { .addr = to_vsockaddr_from_sin(&conn->remote), .spec = to_vsockaddr_from_sin(&conn->local), .msgId = VMSG_DHT, .data = buf, .len = ret }; ret = route->msger->ops->push(route->msger, &msg); ret1E((ret < 0), vdht_buf_free(buf)); } route->ops->inspect(route, &token, VROUTE_INSP_SND_PROBE); recr_space->ops->make(recr_space, &token); vlogD("send @probe"); return 0; } /* * the routine to pack and send back a response to @probe_connectivity query. * @route: * @conn: * @token: */ static int _vroute_dht_probe_rsp(struct vroute* route, vnodeConn* conn, vtoken* token) { void* buf = NULL; int ret = 0; vassert(route); vassert(conn); vassert(token); buf = vdht_buf_alloc(); retE((!buf)); ret = route->enc_ops->probe_rsp(token, &route->myid, buf, vdht_buf_len()); ret1E((ret < 0), vdht_buf_free(buf)); { struct vmsg_usr msg = { .addr = to_vsockaddr_from_sin(&conn->remote), .spec = to_vsockaddr_from_sin(&conn->local), .msgId = VMSG_DHT, .data = buf, .len = ret }; ret = route->msger->ops->push(route->msger, &msg); ret1E((ret < 0), vdht_buf_free(buf)); } vlogD("send @probe_rsp"); return 0; } /* * the routine to pack and send @post_service indication. * @route: * @conn: * @srvc: */ static int _vroute_dht_post_service(struct vroute* route, vnodeConn* conn, vsrvcInfo* srvci) { void* buf = NULL; vtoken token; int ret = 0; vassert(route); vassert(conn); vassert(srvci); retS((!(route->props & PROP_POST_SERVICE))); buf = vdht_buf_alloc(); retE((!buf)); vtoken_make(&token); ret = route->enc_ops->post_service(&token, &route->myid, srvci, buf, vdht_buf_len()); ret1E((ret < 0), vdht_buf_free(buf)); { struct vmsg_usr msg = { .addr = to_vsockaddr_from_sin(&conn->remote), .spec = to_vsockaddr_from_sin(&conn->local), .msgId = VMSG_DHT, .data = buf, .len = ret }; ret = route->msger->ops->push(route->msger, &msg); ret1E((ret < 0), vdht_buf_free(buf)); } vlogD("send @post_service"); return 0; } /* * the routine to pack and send a @find_service query. * @route: * @conn: * @srvcId: */ static int _vroute_dht_find_service(struct vroute* route, vnodeConn* conn, vsrvcHash* hash) { struct vroute_recr_space* recr_space = &route->recr_space; void* buf = NULL; vtoken token; int ret = 0; vassert(route); vassert(conn); vassert(hash); retS((!(route->props & PROP_FIND_SERVICE))); buf = vdht_buf_alloc(); retE((!buf)); vtoken_make(&token); ret = route->enc_ops->find_service(&token, &route->myid, hash, buf, vdht_buf_len()); ret1E((ret < 0), vdht_buf_free(buf)); { struct vmsg_usr msg = { .addr = to_vsockaddr_from_sin(&conn->remote), .spec = to_vsockaddr_from_sin(&conn->local), .msgId = VMSG_DHT, .data = buf, .len = ret }; ret = route->msger->ops->push(route->msger, &msg); ret1E((ret < 0), vdht_buf_free(buf)); } route->ops->inspect(route, &token, VROUTE_INSP_SND_FIND_SERVICE); recr_space->ops->make(recr_space, &token); vlogD("send @find_service"); return 0; } /* * the routine to pack and send a response to @find_service query. * @route: * @conn: * @token: * @srvcs: */ static int _vroute_dht_find_service_rsp(struct vroute* route, vnodeConn* conn, vtoken* token, vsrvcInfo* srvc) { void* buf = NULL; int ret = 0; vassert(route); vassert(conn); vassert(token); vassert(srvc); retS((!(route->props & PROP_FIND_SERVICE_R))); buf = vdht_buf_alloc(); retE((!buf)); ret = route->enc_ops->find_service_rsp(token, &route->myid, srvc, buf, vdht_buf_len()); ret1E((ret < 0), vdht_buf_free(buf)); { struct vmsg_usr msg = { .addr = to_vsockaddr_from_sin(&conn->remote), .spec = to_vsockaddr_from_sin(&conn->local), .msgId = VMSG_DHT, .data = buf, .len = ret }; ret = route->msger->ops->push(route->msger, &msg); ret1E((ret < 0), vdht_buf_free(buf)); } vlogD("send @find_service_rsp"); return 0; } static struct vroute_dht_ops route_dht_ops = { .ping = _vroute_dht_ping, .ping_rsp = _vroute_dht_ping_rsp, .find_node = _vroute_dht_find_node, .find_node_rsp = _vroute_dht_find_node_rsp, .find_closest_nodes = _vroute_dht_find_closest_nodes, .find_closest_nodes_rsp = _vroute_dht_find_closest_nodes_rsp, .reflex = _vroute_dht_reflex, .reflex_rsp = _vroute_dht_reflex_rsp, .probe = _vroute_dht_probe, .probe_rsp = _vroute_dht_probe_rsp, .post_service = _vroute_dht_post_service, .find_service = _vroute_dht_find_service, .find_service_rsp = _vroute_dht_find_service_rsp }; static void _aux_vnodeInfo_free(void* item, void* cookie) { vnodeInfo_relax* nodei = (vnodeInfo_relax*)item; vassert(nodei); vnodeInfo_relax_free(nodei); return ; } /* the routine to call when receiving a @ping query. * * @route: * @conn: * @ctxt: dht decoder context. */ static int _vroute_cb_ping(struct vroute* route, vnodeConn* conn, void* ctxt) { struct vroute_node_space* node_space = &route->node_space; vnodeInfo_relax nodei_relax; vnodeInfo* nodei = (vnodeInfo*)&nodei_relax; vnodeId fromId; vtoken token; int ret = 0; vassert(route); vassert(conn); vassert(ctxt); ret =route->dec_ops->ping(ctxt, &token, &fromId); retE((ret < 0)); vnodeInfo_relax_init(&nodei_relax, &fromId, vnodeVer_unknown(), 0); vnodeInfo_add_addr(&nodei, &conn->remote); ret = node_space->ops->add_node(node_space, nodei, 1); retE((ret < 0)); route->ops->inspect(route, &token, VROUTE_INSP_RCV_PING); ret = route->dht_ops->ping_rsp(route, conn, &token, (vnodeInfo*)&route->node->nodei); retE((ret < 0)); return 0; } /* * the routine to call when receving a response to @ping query. * * @route: * @conn: * @ctxt: */ static int _vroute_cb_ping_rsp(struct vroute* route, vnodeConn* conn, void* ctxt) { struct vroute_node_space* node_space = &route->node_space; struct vroute_recr_space* recr_space = &route->recr_space; vnodeInfo_relax nodei; vtoken token; int ret = 0; ret = route->dec_ops->ping_rsp(ctxt, &token, (vnodeInfo*)&nodei); retE((ret < 0)); retE((!recr_space->ops->check(recr_space, &token))); // skip vicious response. ret = node_space->ops->add_node(node_space, (vnodeInfo*)&nodei, 1); retE((ret < 0)); route->ops->inspect(route, &token, VROUTE_INSP_RCV_PING_RSP); return 0; } /* * the routine to call when receiving a @find_node query. * * @route: * @conn: * @ctxt: */ static int _vroute_cb_find_node(struct vroute* route, vnodeConn* conn, void* ctxt) { struct vroute_node_space* node_space = &route->node_space; vnodeInfo_relax nodei; struct varray closest; vnodeId targetId; vnodeId fromId; vtoken token; int ret = 0; vassert(route); vassert(conn); vassert(ctxt); ret = route->dec_ops->find_node(ctxt, &token, &fromId, &targetId); retE((ret < 0)); ret = node_space->ops->get_node(node_space, &targetId, (vnodeInfo*)&nodei); retE((ret < 0)); if (ret == 1) { //means found ret = route->dht_ops->find_node_rsp(route, conn, &token, (vnodeInfo*)&nodei); retE((ret < 0)); return 0; } // otherwise, send @find_closest_nodes_rsp response instead. varray_init(&closest, MAX_CAPC); ret = node_space->ops->get_neighbors(node_space, &targetId, &closest, MAX_CAPC); ret1E((ret < 0), varray_deinit(&closest)); if (ret == 0) { //means no closest nodes. varray_deinit(&closest); return 0; } ret = route->dht_ops->find_closest_nodes_rsp(route, conn, &token, &closest); varray_zero(&closest, _aux_vnodeInfo_free, NULL); varray_deinit(&closest); retE((ret < 0)); return 0; } /* * the routine to call when receiving a response to @find_node query. * * @route: * @conn: * @ctxt: */ static int _vroute_cb_find_node_rsp(struct vroute* route, vnodeConn* conn, void* ctxt) { struct vroute_node_space* node_space = &route->node_space; struct vroute_recr_space* recr_space = &route->recr_space; vnodeInfo_relax nodei; vnodeId fromId; vtoken token; int ret = 0; vassert(route); vassert(conn); vassert(ctxt); ret = route->dec_ops->find_node_rsp(ctxt, &token, &fromId, (vnodeInfo*)&nodei); retE((ret < 0)); retE((!recr_space->ops->check(recr_space, &token))); ret = node_space->ops->add_node(node_space, (vnodeInfo*)&nodei, 0); retE((ret < 0)); route->ops->inspect(route, &token, VROUTE_INSP_RCV_FIND_NODE_RSP); return 0; } /* * the routine to call when receiving a @find_closest_nodes query. * * @route: * @conn: * @ctxt: */ static int _vroute_cb_find_closest_nodes(struct vroute* route, vnodeConn* conn, void* ctxt) { struct vroute_node_space* node_space = &route->node_space; struct varray closest; vnodeId targetId; vnodeId fromId; vtoken token; int ret = 0; vassert(route); vassert(conn); vassert(ctxt); ret = route->dec_ops->find_closest_nodes(ctxt, &token, &fromId, &targetId); retE((ret < 0)); varray_init(&closest, MAX_CAPC); ret = node_space->ops->get_neighbors(node_space, &targetId, &closest, MAX_CAPC); ret1E((ret < 0), varray_deinit(&closest)); if (ret == 0) { varray_deinit(&closest); return 0; // not response if no closest nodes found. } ret = route->dht_ops->find_closest_nodes_rsp(route, conn, &token, &closest); varray_zero(&closest, _aux_vnodeInfo_free, NULL); varray_deinit(&closest); retE((ret < 0)); return 0; } /* * the routine to call when receiving a response to @find_closest_nodes * * @route: * @conn: * @ctxt: */ static int _vroute_cb_find_closest_nodes_rsp(struct vroute* route, vnodeConn* conn, void* ctxt) { struct vroute_recr_space* recr_space = &route->recr_space; struct vroute_node_space* node_space = &route->node_space; struct varray closest; vnodeId fromId; vtoken token; int ret = 0; int i = 0; vassert(route); vassert(conn); vassert(ctxt); varray_init(&closest, MAX_CAPC); ret = route->dec_ops->find_closest_nodes_rsp(ctxt, &token, &fromId, &closest); ret1E((ret < 0), varray_deinit(&closest)); if (!recr_space->ops->check(recr_space, &token)) { varray_zero(&closest, _aux_vnodeInfo_free, NULL); varray_deinit(&closest); return -1; } for (i = 0; i < varray_size(&closest); i++) { node_space->ops->add_node(node_space, (vnodeInfo*)varray_get(&closest, i), 0); } varray_zero(&closest, _aux_vnodeInfo_free, NULL); varray_deinit(&closest); route->ops->inspect(route, &token, VROUTE_INSP_RCV_FIND_CLOSEST_NODES_RSP); return 0; } /* * the routine to call when receiving a @reflex query. * @route: * @conn: * @ctxt: */ static int _vroute_cb_reflex(struct vroute* route, vnodeConn* conn, void* ctxt) { vnodeId fromId; vtoken token; int ret = 0; vassert(route); vassert(conn); vassert(ctxt); ret = route->dec_ops->reflex(ctxt, &token, &fromId); retE((ret < 0)); ret = route->dht_ops->reflex_rsp(route, conn, &token, &conn->remote); retE((ret < 0)); return 0; } /* * the routine to call when receiving a response to @reflex * @route: * @conn: * @ctxt: */ static int _vroute_cb_reflex_rsp(struct vroute* route, vnodeConn* conn, void* ctxt) { struct vroute_recr_space* recr_space = &route->recr_space; struct vnode* node = route->node; struct sockaddr_in reflexive_addr; vnodeId fromId; vtoken token; int ret = 0; vassert(route); vassert(conn); vassert(ctxt); ret = route->dec_ops->reflex_rsp(ctxt, &token, &fromId, &reflexive_addr); retE((ret < 0)); retE((!recr_space->ops->check(recr_space, &token))); ret = node->ops->reflex_addr(node, &conn->local, &reflexive_addr); retE((ret < 0)); route->ops->inspect(route, &token, VROUTE_INSP_RCV_REFLEX_RSP); return 0; } /* * the routine to call when receiving a @probe query. * @route: * @conn: * @ctxt: */ static int _vroute_cb_probe(struct vroute* route, vnodeConn* conn, void* ctxt) { vnodeId targetId; vnodeId fromId; vtoken token; int ret = 0; vassert(route); vassert(conn); vassert(ctxt); ret = route->dec_ops->probe(ctxt, &token, &fromId, &targetId); retE((ret < 0)); retE((!vtoken_equal(&targetId, &route->myid))); ret = route->dht_ops->probe_rsp(route, conn, &token); retE((ret < 0)); return 0; } /* * the routine to call when receiving a response to @probe query. * @route: * @conn: * @ctxt: */ static int _vroute_cb_probe_rsp(struct vroute* route, vnodeConn* conn, void* ctxt) { struct vroute_recr_space* recr_space = &route->recr_space; struct vroute_node_space* node_space = &route->node_space; vnodeId fromId; vtoken token; int ret = 0; vassert(route); vassert(conn); vassert(ctxt); ret = route->dec_ops->probe_rsp(ctxt, &token, &fromId); retE((ret < 0)); retE((!recr_space->ops->check(recr_space, &token))); ret = node_space->ops->adjust_connectivity(node_space, &fromId, conn); retE((ret < 0)); route->ops->inspect(route, &token, VROUTE_INSP_RCV_PROBE_RSP); return 0; } /* * the routine to call when receiving a @post_service indication. * * @route: * @conn: * @ctxt: */ static int _vroute_cb_post_service(struct vroute* route, vnodeConn* conn, void* ctxt) { struct vroute_srvc_space* srvc_space = &route->srvc_space; vsrvcInfo_relax srvci; vnodeId fromId; vtoken token; int ret = 0; vassert(route); vassert(conn); vassert(ctxt); ret = route->dec_ops->post_service(ctxt, &token, &fromId, (vsrvcInfo*)&srvci); retE((ret < 0)); ret = srvc_space->ops->add_service(srvc_space, (vsrvcInfo*)&srvci); retE((ret < 0)); route->ops->inspect(route, &token, VROUTE_INSP_RCV_POST_SERVICE); return 0; } /* * the routine to call when receiving a @find_service query. * * @route: * @conn: * @ctxt: */ static int _vroute_cb_find_service(struct vroute* route, vnodeConn* conn, void* ctxt) { struct vroute_srvc_space* srvc_space = &route->srvc_space; vsrvcInfo_relax srvci; vsrvcHash srvcHash; vnodeId fromId; vtoken token; int ret = 0; vassert(route); vassert(conn); vassert(ctxt); memset(&srvci, 0, sizeof(srvci)); srvci.capc = VSRVCINFO_MAX_ADDRS; ret = route->dec_ops->find_service(ctxt, &token, &fromId, &srvcHash); retE((ret < 0)); ret = srvc_space->ops->get_service(srvc_space, &srvcHash, (vsrvcInfo*)&srvci); retE((ret < 0)); retS((ret == 0)); ret = route->dht_ops->find_service_rsp(route, conn, &token, (vsrvcInfo*)&srvci); retE((ret < 0)); return 0; } /* * the routine to call when receiving a response to @find_service. * * @route: * @conn: * @ctxt: */ static int _vroute_cb_find_service_rsp(struct vroute* route, vnodeConn* conn, void* ctxt) { struct vroute_srvc_probe_helper* probe_helper = &route->probe_helper; struct vroute_srvc_space* srvc_space = &route->srvc_space; struct vroute_recr_space* recr_space = &route->recr_space; struct vroute_node_space* node_space = &route->node_space; vsrvcInfo_relax srvci; vnodeId fromId; vtoken token; int ret = 0; vassert(route); vassert(ctxt); vassert(conn); ret = route->dec_ops->find_service_rsp(ctxt, &token, &fromId, (vsrvcInfo*)&srvci); retE((ret < 0)); retE((!recr_space->ops->check(recr_space, &token))); ret = srvc_space->ops->add_service(srvc_space, (vsrvcInfo*)&srvci); retE((ret < 0)); //try to add info of node hosting that service. ret = node_space->ops->probe_node(node_space, &srvci.hostid); retE((ret < 0)); route->ops->inspect(route, &token, VROUTE_INSP_RCV_FIND_SERVICE_RSP); probe_helper->ops->invoke(probe_helper, &srvci.hash, (vsrvcInfo*)&srvci); return 0; } static vroute_dht_cb_t route_cb_ops[] = { _vroute_cb_ping, _vroute_cb_ping_rsp, _vroute_cb_find_node, _vroute_cb_find_node_rsp, _vroute_cb_find_closest_nodes, _vroute_cb_find_closest_nodes_rsp, _vroute_cb_reflex, _vroute_cb_reflex_rsp, _vroute_cb_probe, _vroute_cb_probe_rsp, _vroute_cb_post_service, _vroute_cb_find_service, _vroute_cb_find_service_rsp, NULL }; static int _aux_route_msg_cb(void* cookie, struct vmsg_usr* mu) { struct vroute* route = (struct vroute*)cookie; vnodeConn conn; void* ctxt = NULL; int ret = 0; vassert(route); vassert(mu); ret = route->dec_ops->dec_begin(mu->data, mu->len, &ctxt); retE((ret >= VDHT_UNKNOWN)); retE((ret < 0)); vlogD("received @%s", vdht_get_desc(ret)); vnodeConn_set(&conn, to_sockaddr_sin(mu->spec), to_sockaddr_sin(mu->addr)); vlock_enter(&route->lock); ret = route->cb_ops[ret](route, &conn, ctxt); vlock_leave(&route->lock); route->dec_ops->dec_done(ctxt); retE((ret < 0)); return 0; } static int _aux_route_load_proto_caps(struct vconfig* cfg, uint32_t* props) { struct varray* tuple = NULL; int i = 0; vassert(cfg); vassert(props); tuple = cfg->ops->get_tuple_val(cfg, "dht.protocol"); if (!tuple) { *props |= PROP_PING; *props |= PROP_PING_R; return 0; } for (i = 0; i < varray_size(tuple); i++) { struct vcfg_item* item = NULL; int dht_id = -1; item = (struct vcfg_item*)varray_get(tuple, i); retE((item->type != CFG_STR)); dht_id = vdht_get_dhtId_by_desc(item->val.s); retE((dht_id < 0)); retE((dht_id >= VDHT_UNKNOWN)); *props |= (1 << dht_id); } return 0; } int vroute_init(struct vroute* route, struct vconfig* cfg, struct vhost* host, vnodeId* myid) { vassert(route); vassert(host); vassert(myid); vtoken_copy(&route->myid, myid); _aux_route_load_proto_caps(cfg, &route->props); vlock_init(&route->lock); vroute_node_space_init(&route->node_space, route, cfg, myid); vroute_srvc_space_init(&route->srvc_space, cfg); vroute_recr_space_init(&route->recr_space); vroute_srvc_probe_helper_init(&route->probe_helper); route->ops = &route_ops; route->dht_ops = &route_dht_ops; route->cb_ops = route_cb_ops; route->enc_ops = &dht_enc_ops; route->dec_ops = &dht_dec_ops; route->cfg = cfg; route->msger = &host->msger; route->node = &host->node; route->insp_cb = NULL; route->insp_cookie = NULL; route->msger->ops->add_cb(route->msger, route, _aux_route_msg_cb, VMSG_DHT); return 0; } void vroute_deinit(struct vroute* route) { vassert(route); vroute_srvc_probe_helper_deinit (&route->probe_helper); vroute_recr_space_deinit(&route->recr_space); vroute_node_space_deinit(&route->node_space); vroute_srvc_space_deinit(&route->srvc_space); vlock_deinit(&route->lock); return ; }
int DiffArray( const void *a,int aoff,int n, const void *b,int boff,int m, void *context,int dmax,struct varray *ses,int *sn,struct varray *buf) { MatchContext ctx; int d,x,y; DiffEdit *e=NULL; struct varray tmp; ctx.context=context; if(buf) { ctx.buf=buf; }else { varray_init(&tmp,sizeof(int),NULL); ctx.buf=&tmp; } ctx.DiffEditArray=ses; ctx.DiffEditArrayIndex=0; ctx.dmax=dmax?dmax:INT_MAX; if(ses&&sn) { if((e=(DiffEdit *)varray_get(ses,0))==NULL) { if(!buf) { varray_deinit(&tmp); } return -1; } e->op=0; } /* The CalculateSES function assumes the SES will begin or end with a delete * or insert. The following will insure this is true by eating any * beginning matches. This is also a quick to process sequences * that match entirely. */ x=y=0; const unsigned char *a0=(const unsigned char *)a+aoff; const unsigned char *b0=(const unsigned char *)b+boff; while(x<n && y<m && a0[x]==b0[y]) { x++; y++; } AddEdit(&ctx,DIFF_MATCH,aoff,x); if((d=CalculateSES(a,aoff+x,n-x,b,boff+y,m-y,&ctx))==-1) { if(!buf) { varray_deinit(&tmp); } return -1; } if(ses&&sn) { *sn=e->op ? ctx.DiffEditArrayIndex+1 : 0; } if(!buf) { varray_deinit(&tmp); } return d; }