/* Makes the current node find the successor node of an id. * * \param id the id to find * \return the id of the successor node, or -1 if the request failed */ int Node::findSuccessor(int id) { // is my successor the successor? if (is_in_interval(id, id_ + 1, fingers_[0])) { return fingers_[0]; } // otherwise, ask the closest preceding finger in my table return remoteFindSuccessor(closestPrecedingFinger(id), id); }
//--------------------------------------------------------------------- void Node::QueryUser() { /* REGISTER sip:[email protected] To: <sip:[email protected]> From: <sip:[email protected]> */ //char *aor="sip:[email protected]"; char buf[50]; printf("input the user aor you want to call\n"); gets(buf); char *aor=buf; unsigned int uid=uhash(aor); Constants constants(NULL); ChordId UserID(uid,&constants); ChordId pred=mynode->getFingerTable()->getPredecessor(); ChordId localnode=getChordId(); //for test if(UserID.BelongsRightInclusive(pred,localnode)) { printf("\nThe user infomation is on this node\n"); uinfo_t *user_info=uinfo_t::find_user_info_by_aor(aor,user_info_list); char *dest; osip_uri_to_str(user_info->bindings->contact->url,&dest); printf("user contact is %s\n",dest); osip_free(dest); return; } else { ChordId next_hop=closestPrecedingFinger(UserID); //ChordId next_hop=getChordId(); ChordId empty(-1,&constants); if(!next_hop.equals(empty)) { char *tmp=next_hop.GetAddress(); char *requri = (char *)osip_malloc (4 + strlen(tmp) + 1) ; sprintf (requri, "sip:%s", tmp); SndUserRegisterRequest(aor,requri); if(requri) osip_free(requri) ; } else //do not know where to send { return ; } } }
void Node::RegisterUser(REG_TYPE type,char * aor,char *contact,char *username,char * passwd) { /* REGISTER sip:[email protected] SIP/2.0 Via:SIP/2.0/UDP 192.168.1.61:15060;branch=z9hG4bkxxxxx To:liqq <sip:[email protected]> From:liqq <sip:[email protected]> Call-ID: CSeq: Contact:<sip:[email protected]> Content-Length:0 */ /*判断本节点是否对该用户信息负责, 如果负责,添加到user_info_list, 如果不负责,计算next-hop,并发送REGISTER请求*/ unsigned int uid; uid=uhash(aor); ChordId localnode=getChordId(); ChordId pred=getFingerTable()->getPredecessor(); Constants constants(NULL); ChordId UserID(uid,&constants); aor_t aaor(aor); binding_t abind(contact); uinfo_t *user_info=new uinfo_t(username,passwd); user_info->uinfo_set_aor(&aaor); user_info->uinfo_set_binding(&abind); ADD_ELEMENT(local_user_info_list,user_info); // int lid=localnode.GetId(); // int pid=predecessor.GetId(); //if((lid<pid && uid<=lid && uid>pid)||(lid>pid && (uid < lid || uid >=pid))) if(UserID.BelongsRightInclusive(pred,localnode)) { printf("Add a new local user\n"); uinfo_t *uinfo=new uinfo_t(username,passwd); uinfo->uinfo_set_aor(&aaor); uinfo->uinfo_set_binding(&abind); ADD_ELEMENT(user_info_list,uinfo); if(pred.equals(localnode)) { uinfo_t *ruinfo=new uinfo_t(username,passwd); ruinfo->uinfo_set_aor(&aaor); ruinfo->uinfo_set_binding(&abind); ADD_ELEMENT(red_user_info_list,ruinfo); } ChordId succ=getFingerTable()->getSuccessor(0); if(!succ.equals(getChordId())) { string next_hop="sip:"; next_hop+=succ.GetAddress(); SndUserRegisterRequest(RED_REGISTER,uinfo,next_hop.c_str() ,3600); } } else { ChordId node=closestPrecedingFinger(UserID); //ChordId node=getFingerTable()->getPredecessor(); //ChordId node=getChordId(); string registrar="sip:"; registrar+=node.GetAddress(); SndUserRegisterRequest(USER_REGISTRATION,user_info,registrar.c_str() ,3600); } }
/* This function is called when a node receives a message. * * \param message the message to handle (don't touch it afterward: it will be destroyed, reused or forwarded) */ void Node::handleMessage(ChordMessage* message) { switch (message->type) { case FIND_SUCCESSOR: XBT_DEBUG("Received a 'Find Successor' request from %s for id %d", message->issuer_host_name.c_str(), message->request_id); // is my successor the successor? if (is_in_interval(message->request_id, id_ + 1, fingers_[0])) { message->type = FIND_SUCCESSOR_ANSWER; message->answer_id = fingers_[0]; XBT_DEBUG("Sending back a 'Find Successor Answer' to %s (mailbox %s): the successor of %d is %d", message->issuer_host_name.c_str(), message->answer_to->get_cname(), message->request_id, message->answer_id); message->answer_to->put_init(message, 10)->detach(ChordMessage::destroy); } else { // otherwise, forward the request to the closest preceding finger in my table int closest = closestPrecedingFinger(message->request_id); XBT_DEBUG("Forwarding the 'Find Successor' request for id %d to my closest preceding finger %d", message->request_id, closest); simgrid::s4u::MailboxPtr mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(closest)); mailbox->put_init(message, 10)->detach(ChordMessage::destroy); } break; case GET_PREDECESSOR: XBT_DEBUG("Receiving a 'Get Predecessor' request from %s", message->issuer_host_name.c_str()); message->type = GET_PREDECESSOR_ANSWER; message->answer_id = pred_id_; XBT_DEBUG("Sending back a 'Get Predecessor Answer' to %s via mailbox '%s': my predecessor is %d", message->issuer_host_name.c_str(), message->answer_to->get_cname(), message->answer_id); message->answer_to->put_init(message, 10)->detach(ChordMessage::destroy); break; case NOTIFY: // someone is telling me that he may be my new predecessor XBT_DEBUG("Receiving a 'Notify' request from %s", message->issuer_host_name.c_str()); notify(message->request_id); delete message; break; case PREDECESSOR_LEAVING: // my predecessor is about to quit XBT_DEBUG("Receiving a 'Predecessor Leaving' message from %s", message->issuer_host_name.c_str()); // modify my predecessor setPredecessor(message->request_id); delete message; /*TODO : >> notify my new predecessor >> send a notify_predecessors !! */ break; case SUCCESSOR_LEAVING: // my successor is about to quit XBT_DEBUG("Receiving a 'Successor Leaving' message from %s", message->issuer_host_name.c_str()); // modify my successor FIXME : this should be implicit ? setFinger(0, message->request_id); delete message; /* TODO >> notify my new successor >> update my table & predecessors table */ break; case PREDECESSOR_ALIVE: XBT_DEBUG("Receiving a 'Predecessor Alive' request from %s", message->issuer_host_name.c_str()); message->type = PREDECESSOR_ALIVE_ANSWER; XBT_DEBUG("Sending back a 'Predecessor Alive Answer' to %s (mailbox %s)", message->issuer_host_name.c_str(), message->answer_to->get_cname()); message->answer_to->put_init(message, 10)->detach(ChordMessage::destroy); break; default: XBT_DEBUG("Ignoring unexpected message: %d from %s", message->type, message->issuer_host_name.c_str()); delete message; } }