Skip to content

Commit

Permalink
Added regexp support for response codes
Browse files Browse the repository at this point in the history
Now the regexp_match attribute should also work for response codes.

Example:
<recv response="^18" regexp_match="true" optional="true">
  • Loading branch information
Petr Cisar authored and orgads committed Nov 7, 2024
1 parent 73c4cfe commit fd26ae5
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 25 deletions.
2 changes: 1 addition & 1 deletion include/scenario.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class message
char * peer_src;

/* If this is a recv */
int recv_response;
char * recv_response;
char * recv_request;
int optional;
bool advance_state;
Expand Down
16 changes: 16 additions & 0 deletions regress/github-#0769/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/sh
# This regression test is a part of SIPp.
# Author: Petr Cisar
. "`dirname "$0"`/../functions"; init

# uac.xml checks reception of regex-based responses
sippbg -sn uas -i 127.0.0.1 -p 5070 -m 1
sippbg -sf uac.xml -i 127.0.0.1 -m 1 127.0.0.1:5070
job2=$!

# If job2 did not finish, we have failure.
if /bin/kill -0 $job2 2>/dev/null; then
fail
else
ok
fi
77 changes: 77 additions & 0 deletions regress/github-#0769/uac.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE scenario SYSTEM "sipp.dtd">
<scenario>
<send retrans="500">
<![CDATA[
INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
To: [service] <sip:[service]@[remote_ip]:[remote_port]>
Call-ID: [call_id]
CSeq: 1 INVITE
Contact: sip:sipp@[local_ip]:[local_port]
Max-Forwards: 70
Content-Type: application/sdp
Content-Length: [len]
v=0
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
s=-
c=IN IP[media_ip_type] [media_ip]
t=0 0
m=audio [media_port] RTP/AVP 0
a=rtpmap:0 PCMU/8000
]]>
</send>

<!-- Test regular response code (no wildcard) -->
<recv response="100" optional="true"/>

<!-- Test regex 18x response code -->
<recv response="^18.$" regexp_match="true" optional="true"/>

<!-- Make sure that no match also works -->
<recv response="^6" regexp_match="true" optional="true"/>

<!-- Test a simple prefix match on response code, it should also work -->
<recv response="^2" regexp_match="true" rtd="true"></recv>

<send>
<![CDATA[
ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
To: [service] <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
Call-ID: [call_id]
CSeq: 1 ACK
Contact: sip:sipp@[local_ip]:[local_port]
Max-Forwards: 70
Content-Length: 0
]]>
</send>

<pause/>

<send retrans="500">
<![CDATA[
BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
To: [service] <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
Call-ID: [call_id]
CSeq: 4 BYE
Contact: sip:sipp@[local_ip]:[local_port]
Max-Forwards: 70
Content-Length: 0
]]>
</send>

<recv response="200" crlf="true"/>

</scenario>
2 changes: 1 addition & 1 deletion sipp.dtd
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

<!ELEMENT recv ( action? ) >
<!ATTLIST recv %messageCmdCommon; >
<!ATTLIST recv response NMTOKEN #IMPLIED >
<!ATTLIST recv response CDATA #IMPLIED >
<!ATTLIST recv request CDATA #IMPLIED >
<!ATTLIST recv optional (true|false) #IMPLIED >
<!ATTLIST recv ignosesdp (true|false) #IMPLIED >
Expand Down
57 changes: 39 additions & 18 deletions src/call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2348,7 +2348,7 @@ bool call::process_unexpected(const char* msg)
if (curmsg -> recv_request) {
desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "while expecting '%s' ", curmsg -> recv_request);
} else {
desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "while expecting '%d' ", curmsg -> recv_response);
desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "while expecting '%s' ", curmsg -> recv_response);
}
} else if (curmsg -> M_type == MSG_TYPE_SEND) {
desc += snprintf(desc, MAX_HEADER_LEN - (desc - buffer), "while sending ");
Expand Down Expand Up @@ -4451,24 +4451,45 @@ bool call::matches_scenario(unsigned int index, int reply_code, char * request,
} else {
return !strcmp(curmsg->recv_request, request);
}
} else if (curmsg->recv_response && (curmsg->recv_response == reply_code)) {
/* This is a potential candidate, we need to match transactions. */
if (curmsg->response_txn) {
if (transactions[curmsg->response_txn - 1].txnID && !strcmp(transactions[curmsg->response_txn - 1].txnID, txn)) {
return true;
} else {
return false;
} else if (curmsg->recv_response) {
if (curmsg->regexp_match) { // Match response code using regex
char reply_code_str[8];
snprintf(reply_code_str, 8, "%u", reply_code); // Convert the response code to string
if (curmsg->regexp_compile == nullptr) {
regex_t *re = new regex_t;
/* No regex match position needed (NOSUB), we're simply
* looking for the <request method="INVITE|REGISTER"../>
* regex. */
if (regcomp(re, curmsg->recv_response, REGCOMP_PARAMS|REG_NOSUB)) {
ERROR("Invalid regular expression for index %d: %s", index, curmsg->recv_response);
}
curmsg->regexp_compile = re;
}
} else if (index == 0) {
/* Always true for the first message. */
return true;
} else if (curmsg->recv_response_for_cseq_method_list &&
strstr(curmsg->recv_response_for_cseq_method_list, responsecseqmethod)) {
/* If we do not have a transaction defined, we just check the CSEQ method. */
return true;
} else {
return false;
}
if (regexec(curmsg->regexp_compile, reply_code_str, (size_t)0, nullptr, REGEXEC_PARAMS)) {
return false;
}
} else { // Exact numerical match
if (atoi(curmsg->recv_response) != reply_code) {
return false;
}
}
/* This is a potential candidate, we need to match transactions. */
if (curmsg->response_txn) {
if (transactions[curmsg->response_txn - 1].txnID && !strcmp(transactions[curmsg->response_txn - 1].txnID, txn)) {
return true;
} else {
return false;
}
} else if (index == 0) {
/* Always true for the first message. */
return true;
} else if (curmsg->recv_response_for_cseq_method_list &&
strstr(curmsg->recv_response_for_cseq_method_list, responsecseqmethod)) {
/* If we do not have a transaction defined, we just check the CSEQ method. */
return true;
} else {
return false;
}
}

return false;
Expand Down
2 changes: 1 addition & 1 deletion src/logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ void print_count_file(FILE* f, int header)
}
} else if (curmsg->recv_response) {
if (header) {
sprintf(temp_str, "%u_%d_", index, curmsg->recv_response);
sprintf(temp_str, "%u_%s_", index, curmsg->recv_response);

fprintf(f, "%sRecv%s", temp_str, stat_delimiter);
fprintf(f, "%sRetrans%s", temp_str, stat_delimiter);
Expand Down
5 changes: 3 additions & 2 deletions src/scenario.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ message::message(int index, const char *desc)
retrans_delay = 0;
timeout = 0;

recv_response = 0;
recv_response = nullptr; // free on exit
recv_request = nullptr; // free on exit
optional = 0;
advance_state = true;
Expand Down Expand Up @@ -116,6 +116,7 @@ message::~message()
free(pause_desc);
delete send_scheme;
free(recv_request);
free(recv_response);
if (regexp_compile != nullptr) {
regfree(regexp_compile);
}
Expand Down Expand Up @@ -891,7 +892,7 @@ scenario::scenario(char * filename, int deflt)
curmsg->M_type = MSG_TYPE_RECV;
/* Received messages descriptions */
if((cptr = xp_get_value("response"))) {
curmsg ->recv_response = get_long(cptr, "response code");
curmsg ->recv_response = strdup(cptr);
if (method_list) {
curmsg->recv_response_for_cseq_method_list = strdup(method_list);
}
Expand Down
4 changes: 2 additions & 2 deletions src/screen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -529,10 +529,10 @@ void ScreenPrinter::draw_scenario_screen()
} else if (curmsg->recv_response) {
if (creationMode == MODE_SERVER) {
buf_len += snprintf(buf + buf_len, bufsiz - buf_len,
" ----------> %-10d ", curmsg->recv_response);
" ----------> %-10s ", curmsg->recv_response);
} else {
buf_len += snprintf(buf + buf_len, bufsiz - buf_len,
" %10d <---------- ", curmsg->recv_response);
" %10s <---------- ", curmsg->recv_response);
}

if (curmsg->start_rtd) {
Expand Down

0 comments on commit fd26ae5

Please sign in to comment.