/** * @brief config file function for broadcasting dmq message */ int ki_dmq_bcast_message(sip_msg_t *msg, str *peer_str, str *body_str, str *ct_str) { LM_DBG("cfg_dmq_bcast_message: %.*s - %.*s - %.*s\n", peer_str->len, peer_str->s, body_str->len, body_str->s, ct_str->len, ct_str->s); dmq_peer_t *destination_peer = find_peer(*peer_str); if(!destination_peer) { LM_INFO("cannot find peer %.*s - adding it.\n", peer_str->len, peer_str->s); dmq_peer_t new_peer; new_peer.callback = empty_peer_callback; new_peer.description.s = ""; new_peer.description.len = 0; new_peer.peer_id = *peer_str; destination_peer = register_dmq_peer(&new_peer); if(!destination_peer) { LM_ERR("error in register_dmq_peer\n"); goto error; } } if(bcast_dmq_message(destination_peer, body_str, 0, ¬ification_callback, 1, ct_str) < 0) { LM_ERR("cannot send dmq message\n"); goto error; } return 1; error: return -1; }
/** * @brief request node list */ int request_nodelist(dmq_node_t* node, int forward) { str* body; int ret; body = build_notification_body(); if(body==NULL) { LM_ERR("no notification body\n"); return -1; } ret = bcast_dmq_message(dmq_notification_peer, body, NULL, ¬ification_callback, forward, ¬ification_content_type); pkg_free(body->s); pkg_free(body); return ret; }
/** * @brief config file function for broadcasting dmq message */ int cfg_dmq_bcast_message(struct sip_msg* msg, char* peer, char* body, char* content_type) { str peer_str; str body_str; str ct_str; if(get_str_fparam(&peer_str, msg, (fparam_t*)peer)<0) { LM_ERR("cannot get peer value\n"); return -1; } if(get_str_fparam(&body_str, msg, (fparam_t*)body)<0) { LM_ERR("cannot get body value\n"); return -1; } if(get_str_fparam(&ct_str, msg, (fparam_t*)content_type)<0) { LM_ERR("cannot get content-type value\n"); return -1; } LM_DBG("cfg_dmq_bcast_message: %.*s - %.*s - %.*s\n", peer_str.len, peer_str.s, body_str.len, body_str.s, ct_str.len, ct_str.s); dmq_peer_t* destination_peer = find_peer(peer_str); if(!destination_peer) { LM_INFO("cannot find peer %.*s - adding it.\n", peer_str.len, peer_str.s); dmq_peer_t new_peer; new_peer.callback = empty_peer_callback; new_peer.description.s = ""; new_peer.description.len = 0; new_peer.peer_id = peer_str; destination_peer = register_dmq_peer(&new_peer); if(!destination_peer) { LM_ERR("error in register_dmq_peer\n"); goto error; } } if(bcast_dmq_message(destination_peer, &body_str, 0, ¬ification_callback, 1, &ct_str) < 0) { LM_ERR("cannot send dmq message\n"); goto error; } return 1; error: return -1; }
/** * @brief dmq notification callback */ int dmq_notification_callback(struct sip_msg* msg, peer_reponse_t* resp, dmq_node_t* dmq_node) { int nodes_recv; str* response_body = NULL; int maxforwards = 0; /* received dmqnode list */ LM_DBG("dmq triggered from dmq_notification_callback\n"); /* extract the maxforwards value, if any */ if(msg->maxforwards) { if (msg->maxforwards->parsed > 0) { /* maxfwd module has parsed and decreased the value in the msg buf */ /* maxforwards->parsed contains the original value */ maxforwards = (int)(long)(msg->maxforwards->parsed) - 1; } else { str2sint(&msg->maxforwards->body, &maxforwards); maxforwards--; } } nodes_recv = extract_node_list(node_list, msg); LM_DBG("received %d new or changed nodes\n", nodes_recv); response_body = build_notification_body(); if(response_body==NULL) { LM_ERR("no response body\n"); goto error; } resp->content_type = notification_content_type; resp->reason = dmq_200_rpl; resp->body = *response_body; resp->resp_code = 200; /* if we received any new nodes tell about them to the others */ if(nodes_recv > 0 && maxforwards > 0) { /* maxforwards is set to 0 so that the message is will not be in a spiral */ bcast_dmq_message(dmq_notification_peer, response_body, 0, ¬ification_callback, maxforwards, ¬ification_content_type); } pkg_free(response_body); if (dmq_init_callback_done && !*dmq_init_callback_done) { *dmq_init_callback_done = 1; run_init_callbacks(); } return 0; error: return -1; }
/** * @brief pings the servers in the nodelist * * if the server does not reply to the ping, it is removed from the list * the ping messages are actualy notification requests * this way the ping will have two uses: * - checks if the servers in the list are up and running * - updates the list of servers from the other nodes */ void ping_servers(unsigned int ticks, void *param) { str* body; int ret; LM_DBG("ping_servers\n"); body = build_notification_body(); if (!body) { LM_ERR("could not build notification body\n"); return; } ret = bcast_dmq_message(dmq_notification_peer, body, notification_node, ¬ification_callback, 1, ¬ification_content_type); pkg_free(body->s); pkg_free(body); if(ret < 0) { LM_ERR("error broadcasting message\n"); } }
/** * @brief dmq notification callback */ int dmq_notification_callback(struct sip_msg* msg, peer_reponse_t* resp) { int nodes_recv; str* response_body = NULL; unsigned int maxforwards = 1; /* received dmqnode list */ LM_DBG("dmq triggered from dmq_notification_callback\n"); /* parse the message headers */ if(parse_headers(msg, HDR_EOH_F, 0) < 0) { LM_ERR("error parsing message headers\n"); goto error; } /* extract the maxforwards value, if any */ if(msg->maxforwards) { LM_DBG("max forwards: %.*s\n", STR_FMT(&msg->maxforwards->body)); str2int(&msg->maxforwards->body, &maxforwards); } maxforwards--; nodes_recv = extract_node_list(node_list, msg); LM_DBG("received %d new nodes\n", nodes_recv); response_body = build_notification_body(); if(response_body==NULL) { LM_ERR("no response body\n"); goto error; } resp->content_type = notification_content_type; resp->reason = dmq_200_rpl; resp->body = *response_body; resp->resp_code = 200; /* if we received any new nodes tell about them to the others */ if(nodes_recv > 0 && maxforwards > 0) { /* maxforwards is set to 0 so that the message is will not be in a spiral */ bcast_dmq_message(dmq_notification_peer, response_body, 0, ¬ification_callback, maxforwards, ¬ification_content_type); } LM_DBG("broadcasted message\n"); pkg_free(response_body); return 0; error: return -1; }