📄 call.cpp
字号:
} } TRACE_MSG((s, "-----------------------------------------------\n" "Unexpected %s message received:\n\n%s\n", TRANSPORT_TO_STRING(transport), msg)); if (default_behavior) {#ifdef __3PCC__ // if twin socket call => reset the other part here if (twinSippSocket && (msg_index > 0)) { //WARNING_P2("call-ID '%s', internal-cmd: abort_call %s",id, ""); res = sendCmdBuffer (createSendingMessage((char*)"call-id: [call_id]\ninternal-cmd: abort_call\n", -1)); }#endif /* __3PCC__ */ // usage of last_ keywords => for call aborting last_recv_msg = (char *) realloc(last_recv_msg, strlen(msg) + 1); strcpy(last_recv_msg, msg); CStat::instance()->computeStat(CStat::E_CALL_FAILED); CStat::instance()->computeStat(CStat::E_FAILED_UNEXPECTED_MSG); return (abortCall()); } else { // Do not abort call nor send anything in reply if default behavior is disabled return true; }}bool call::abortCall(){ int res ; if ((toolMode != MODE_SERVER) && (msg_index > 0)) { if (call_established == false) { char * src = last_recv_msg ; char * dest ; char L_msg_buffer[SIPP_MAX_MSG_SIZE]; L_msg_buffer[0] = '\0'; char * L_param = L_msg_buffer; // Answer unexpected errors (4XX, 5XX and beyond) with an ACK // Contributed by F. Tarek Rogers if((src) && (get_reply_code(src) > 400)) { sendBuffer(createSendingMessage( (char*)"ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n" "Via: SIP/2.0/[transport] [local_ip]:[local_port]\n" "From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]\n" "To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]\n" "Call-ID: [call_id]\n" "CSeq: 1 ACK\n" "Contact: sip:sipp@[local_ip]:[local_port]\n" "Max-Forwards: 70\n" "Subject: Performance Test\n" "Content-Length: 0\n\n" , -1)); } else if (src) { /* Call is not established and the reply is not a 4XX, 5XX */ /* And we already received a message. */ if (ack_is_pending == true) { /* If an ACK is expected from the other side, send it * and send a BYE afterwards */ ack_is_pending = false; /* Send an ACK */ strcpy(L_param, "ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"); sprintf(L_param, "%s%s", L_param, "[last_Via:]\n"); sprintf(L_param, "%s%s", L_param, "[last_From:]\n"); sprintf(L_param, "%s%s", L_param, "[last_To:]\n"); sprintf(L_param, "%s%s", L_param, "[last_Call-ID:]\n"); /* The CSeq of an ACK relating to an INVITE must be the same as */ /* the one from the INVITE. */ /* Let's simplify this by putting 1 (no support for re-invite in */ /* 3PCC?) */ /* FIXME: store CSeq from last INVITE and re-use it */ sprintf(L_param, "%sCSeq: 1 ACK\n", L_param); sprintf(L_param, "%s%s", L_param, "Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"); sprintf(L_param, "%s%s", L_param, "Content-Length: 0\n"); res = sendBuffer(createSendingMessage((char*)(L_param),-1)); /* Send the BYE */ strcpy(L_param, "BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"); sprintf(L_param, "%s%s", L_param, "[last_Via:]\n"); sprintf(L_param, "%s%s", L_param, "[last_From:]\n"); sprintf(L_param, "%s%s", L_param, "[last_To:]\n"); sprintf(L_param, "%s%s", L_param, "[last_Call-ID:]\n"); char * cseq; cseq = compute_cseq(src); if (cseq != NULL) { sprintf(L_param, "%s%s BYE\n", L_param, compute_cseq(src)); } sprintf(L_param, "%s%s", L_param, "Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"); sprintf(L_param, "%s%s", L_param, "Content-Length: 0\n"); res = sendBuffer(createSendingMessage((char*)(L_param),-1)); } else { /* Send a CANCEL */ strcpy(L_param, "CANCEL sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"); sprintf(L_param, "%s%s", L_param, "[last_Via:]\n"); sprintf(L_param, "%s%s", L_param, "[last_From:]\n"); sprintf(L_param, "%s%s", L_param, "[last_To:]\n"); sprintf(L_param, "%s%s", L_param, "[last_Call-ID:]\n"); char * cseq; cseq = compute_cseq(src); if (cseq != NULL) { sprintf(L_param, "%s%s CANCEL\n", L_param, compute_cseq(src)); } sprintf(L_param, "%s%s", L_param, "Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"); sprintf(L_param, "%s%s", L_param, "Content-Length: 0\n"); res = sendBuffer(createSendingMessage((char*)(L_param),-1)); } } else { /* Call is not established and the reply is not a 4XX, 5XX */ /* and we didn't received any message. This is the case when */ /* we are aborting after having send an INVITE and not received */ /* any answer. */ /* Do nothing ! */ } } else { /* Call is established */ char * src = last_recv_msg ; char L_msg_buffer[SIPP_MAX_MSG_SIZE]; L_msg_buffer[0] = '\0'; char * L_param = L_msg_buffer; strcpy(L_param, "BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0\n"); sprintf(L_param, "%s%s", L_param, "[last_Via:]\n"); sprintf(L_param, "%s%s", L_param, "[last_From:]\n"); sprintf(L_param, "%s%s", L_param, "[last_To:]\n"); sprintf(L_param, "%s%s", L_param, "[last_Call-ID:]\n"); char * cseq; cseq = compute_cseq(src); if (cseq != NULL) { sprintf(L_param, "%s%s BYE\n", L_param, compute_cseq(src)); } sprintf(L_param, "%s%s", L_param, "Contact: <sip:[local_ip]:[local_port];transport=[transport]>\n"); sprintf(L_param, "%s%s", L_param, "Content-Length: 0\n"); res = sendBuffer(createSendingMessage((char*)(L_param),-1)); } } delete_call(id); return false;}bool call::rejectCall(){ CStat::instance()->computeStat(CStat::E_CALL_FAILED); CStat::instance()->computeStat(CStat::E_FAILED_CALL_REJECTED); delete_call(id); return false;}#ifdef __3PCC__int call::sendCmdMessage(int index){ char * dest; char delimitor[2]; delimitor[0]=27; delimitor[1]=0; if(scenario[index] -> M_sendCmdData) { // WARNING_P1("---PREPARING_TWIN_CMD---%s---", scenario[index] -> M_sendCmdData); dest = createSendingMessage(scenario[index] -> M_sendCmdData, -2); strcat(dest, delimitor); //WARNING_P1("---SEND_TWIN_CMD---%s---", dest); int rc; rc = send(twinSippSocket, dest, strlen(dest), 0); if(rc < 0) { CStat::instance()->computeStat(CStat::E_CALL_FAILED); CStat::instance()->computeStat(CStat::E_FAILED_CMD_NOT_SENT); delete_call(id); return(-1); } return(0); } else return(-1);}int call::sendCmdBuffer(char* cmd){ char * dest; char delimitor[2]; int rc; delimitor[0]=27; delimitor[1]=0; dest = cmd ; strcat(dest, delimitor); rc = send(twinSippSocket, dest, strlen(dest), 0); if(rc < 0) { CStat::instance()->computeStat(CStat::E_CALL_FAILED); CStat::instance()->computeStat(CStat::E_FAILED_CMD_NOT_SENT); delete_call(id); return(-1); } return(0);}#endifchar* call::createSendingMessage(char * src, int P_index){ static char msg_buffer[SIPP_MAX_MSG_SIZE+2]; if(src != NULL) { char * dest = msg_buffer; char * key; char * length_marker = NULL; int offset = 0; while(*src) { if(*src == '[') { char keyword [KEYWORD_SIZE+1]; src++; key = strchr(src, ']'); if((!key) || ((key - src) > KEYWORD_SIZE) || (!(key - src))){ ERROR("Syntax error or invalid [keyword] in scenario"); } memcpy(keyword, src, key - src); keyword[key - src] = 0; src = key + 1; // allow +n for numeric variables if ((key = strchr(keyword,'+'))) { offset = atoi(key); *key = 0; } if(!strcmp(keyword, "remote_ip")) { dest += sprintf(dest, "%s", remote_ip_escaped); } else if(!strcmp(keyword, "remote_port")) { dest += sprintf(dest, "%u", remote_port + offset); } else if(!strcmp(keyword, "transport")) { dest += sprintf(dest, "%s", TRANSPORT_TO_STRING(transport)); } else if(!strcmp(keyword, "local_ip")) { dest += sprintf(dest, "%s", local_ip_escaped); } else if(!strcmp(keyword, "local_port")) { if((transport == T_UDP) && (multisocket)) { dest += sprintf(dest, "%u", call_port + offset); } else { dest += sprintf(dest, "%u", local_port + offset); } } else if(!strcmp(keyword, "media_ip")) { dest += sprintf(dest, "%s", media_ip_escaped); } else if(!strcmp(keyword, "media_port")) { dest += sprintf(dest, "%u", media_port + offset); } else if(!strcmp(keyword, "call_number")) { dest += sprintf(dest, "%lu", number); } else if(!strcmp(keyword, "call_id")) { dest += sprintf(dest, "%s", id); } else if(!strcmp(keyword, "pid")) { dest += sprintf(dest, "%u", pid); } else if(!strcmp(keyword, "service")) { dest += sprintf(dest, "%s", service); } else if(!strncmp(keyword, "field", 5)) { char* local_dest = dest; getFieldFromInputFile(keyword, m_localLineNumber, dest); if (dest == local_dest && ('\r' == *(local_dest-1) || '\n' == *(local_dest-1))) { /* If the line begins with a field value and there * is nothing to add for this field, * Jump to the end of line in scenario. SN */ while((*src) && (*src != '\n')) { src++; } if(*src == '\n') { src++; } } } else if(!strcmp(keyword, "peer_tag_param")) { if(peer_tag && strlen(peer_tag)) { dest += sprintf(dest, ";tag=%s", peer_tag); } } else if(strstr(keyword, "$")) { int varId = atoi(keyword+1); if(varId < SCEN_VARIABLE_SIZE) { if(M_callVariableTable[varId] != NULL) { if(M_callVariableTable[varId]->isSet()) { dest += sprintf(dest, "%s", M_callVariableTable[varId]-> getMatchingValue()); // WARNING_P1("VARIABLE --%s--", M_callVariableTable[varId]->getMatchingValue()); } else { dest += sprintf(dest, "%s", ""); } } } } else if(strstr(keyword, "last_")) { char * last_header = get_last_header(keyword+5); if(last_header) { dest += sprintf(dest, "%s", last_header); } else { /* Jump to the end of line in scenario if nothing * to insert in place of this header. */ while((*src) && (*src != '\n')) { src++; } if(*src == '\n') { src++; } } } else if(strstr(keyword, "routes")) { if (dialog_route_set) { dest += sprintf(dest, "Route: %s", dialog_route_set); }#ifdef _USE_OPENSSL } else if(strstr(keyword, "authentication")) { /* This keyword is substituted below */ dest += sprintf(dest, "[%s]", keyword);#endif } else if(strstr(keyword, "len")) { length_marker = dest; // dest += sprintf(dest, " 0"); dest += sprintf(dest, " "); } else { ERROR_P1("Unsupported keyword '%s' in xml scenario file", keyword); } } else if (*src == '\n') { *dest++ = '\r'; *dest++ = *src++; } else { *dest++ = *src++; } } *dest = 0;#ifdef _USE_OPENSSL /* * The authentication substitution must be done outside the above * loop because auth-int will use the body (which must have already * been keyword substituted) to build the md5 hash */ if((src = strstr(msg_buffer, "[authentication")) && dialog_authentication) { char my_auth_user[KEYWORD_SIZE]; char my_auth_pass[KEYWORD_SIZE]; char * tmp; strcpy(my_auth_user, service); strcpy(my_auth_pass, auth_password); /* Look for optional username and password paramaters */ if(tmp = strstr(src, "username=")) { tmp += strlen("username="); key = tmp; while (*key) { if (((key - src) > KEYWORD_SIZE) || (!(key - src))) { ERROR("Syntax error parsing authentication paramaters"); } else if (*key == ']' || *key < 33 || *key > 126) { memset(my_auth_user, 0, sizeof(my_auth_user)); strncpy(my_auth_user, tmp, key-tmp); break; } key++; } } if(tmp = strstr(src, "password=")) { tmp += strlen("password="); key = tmp; while (*key) { if (((key - src) > KEYWORD_SIZE) || (!(key - src))) { ERROR("Syntax error parsing authentication paramaters"); } else if (*key == ']' || *key < 33 || *key > 126) { memset(my_auth_pass, 0, sizeof(my_auth_pass)); strncpy(my_auth_pass, tmp, key-tmp); break; } key++; } } /* Need the Method name from the CSeq of the Challenge */ char method[MAX_HEADER_LEN]; tmp = get_last_header("CSeq") + 5; if(!tmp) { ERROR("Could not extract method from cseq of challenge"); } while(isspace(*tmp) || isdigit(*tmp)) tmp++; sscanf(tmp,"%s", &method); /* Need the body for auth-int calculation */ char body[SIPP_MAX_MSG_SIZE]; memset(body, 0, sizeof(body)); tmp = msg_buffer; while(*(tmp+4)) { if (*tmp == '\r' && *(tmp + 1) == '\n' && *(tmp + 2) == '\r' && *(tmp + 3) == '\n') { sprintf(body, "%s", tmp+4); break; } tmp++; } /* Build the auth credenticals */ char result[MAX_HEADER_LEN]; if (createAuthHeader(my_auth_user, my_auth_pass, method, remote_ip, body, dialog_authentication, result) == 0) { ERROR_P1("%s", result); } char tmp_buffer[SIPP_MAX_MSG_SIZE]; dest = strncpy(tmp_buffer, msg_buffer, src - msg_buffer); dest += src - msg_buffer; key = strchr(src, ']'); src += key - src + 1; if (dialog_challenge_type == 401) { /* Registrars use Authorization */ dest += sprintf(dest, "Authorization: %s", result); } else { /* Proxies use Proxy-Authorization */ dest += sprintf(dest, "Proxy-Authorization: %s", result); } dest += sprintf(dest, "%s", src); strcpy(msg_buffer, tmp_buffer); }#endif // Remove all \r, \n but 1 at the end of a message to send int len = strlen(msg_buffer); while ( (msg_buffer[len-1] == '\n') &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -