Skip to content

Commit

Permalink
Merge pull request #863 from mslehto/sdpops
Browse files Browse the repository at this point in the history
modules/sdpops - extend sdp_remove_line_by_prefix()
  • Loading branch information
miconda committed Nov 30, 2016
2 parents 1d5f39a + 892ab27 commit 44a87c1
Show file tree
Hide file tree
Showing 12 changed files with 404 additions and 50 deletions.
19 changes: 13 additions & 6 deletions modules/app_lua/app_lua_exp.c
Expand Up @@ -2157,7 +2157,8 @@ static int lua_sr_sdpops_remove_transport(lua_State *L)
static int lua_sr_sdpops_remove_line_by_prefix(lua_State *L)
{
int ret;
str media;
str prefix = STR_NULL;
str media = STR_NULL;
sr_lua_env_t *env_L;

env_L = sr_lua_env_get();
Expand All @@ -2174,16 +2175,22 @@ static int lua_sr_sdpops_remove_line_by_prefix(lua_State *L)
return app_lua_return_error(L);
}

if(lua_gettop(L)!=1)
if(lua_gettop(L)==1)
{
prefix.s = (char *) lua_tostring(L, -1);
prefix.len = strlen(prefix.s);
} else if(lua_gettop(L)==2)
{
prefix.s = (char *) lua_tostring(L, -2);
prefix.len = strlen(prefix.s);
media.s = (char *) lua_tostring(L, -1);
media.len = strlen(media.s);
} else {
LM_ERR("incorrect number of arguments\n");
return app_lua_return_error(L);
}

media.s = (char*)lua_tostring(L, -1);
media.len = strlen(media.s);

ret = _lua_sdpopsb.sdp_remove_line_by_prefix(env_L->msg, &media);
ret = _lua_sdpopsb.sdp_remove_line_by_prefix(env_L->msg, &prefix, &media);

return app_lua_return_int(L, ret);
}
Expand Down
2 changes: 1 addition & 1 deletion modules/sdpops/api.h
Expand Up @@ -41,7 +41,7 @@ typedef struct sdpops_binds {
sdp_keep_media_t sdp_keep_codecs_by_name;
sdp_remove_media_t sdp_remove_media;
sdp_remove_media_t sdp_remove_transport;
sdp_remove_media_t sdp_remove_line_by_prefix;
sdp_remove_media_type_t sdp_remove_line_by_prefix;
sdp_remove_media_type_t sdp_remove_codecs_by_id;
sdp_remove_media_type_t sdp_remove_codecs_by_name;
} sdpops_api_t;
Expand Down
2 changes: 1 addition & 1 deletion modules/sdpops/doc/sdpops_admin.xml
Expand Up @@ -126,7 +126,7 @@ sdp_remove_codecs_by_name("PCMU,PCMA,GSM");
</section>
<section id="sdpops.f.remove_line_by_prefix">
<title>
<function moreinfo="none">sdp_remove_line_by_prefix(string)</function>
<function moreinfo="none">sdp_remove_line_by_prefix(string [, mtype])</function>
</title>
<para>
Remove all SDP attribute lines beginning with 'string'
Expand Down
146 changes: 111 additions & 35 deletions modules/sdpops/sdpops_mod.c
Expand Up @@ -42,7 +42,7 @@

MODULE_VERSION

static int w_sdp_remove_line_by_prefix(sip_msg_t* msg, char* prefix, char* bar);
static int w_sdp_remove_line_by_prefix(sip_msg_t* msg, char* prefix, char* media);
static int w_sdp_remove_codecs_by_id(sip_msg_t* msg, char* codecs, char *media);
static int w_sdp_remove_codecs_by_name(sip_msg_t* msg, char* codecs, char *media);
static int w_sdp_keep_codecs_by_id(sip_msg_t* msg, char* codecs, char *media);
Expand Down Expand Up @@ -73,6 +73,8 @@ static int mod_init(void);
static cmd_export_t cmds[] = {
{"sdp_remove_line_by_prefix", (cmd_function)w_sdp_remove_line_by_prefix,
1, fixup_spve_null, 0, ANY_ROUTE},
{"sdp_remove_line_by_prefix", (cmd_function)w_sdp_remove_line_by_prefix,
2, fixup_spve_spve, 0, ANY_ROUTE},
{"sdp_remove_codecs_by_id", (cmd_function)w_sdp_remove_codecs_by_id,
1, fixup_spve_null, 0, ANY_ROUTE},
{"sdp_remove_codecs_by_id", (cmd_function)w_sdp_remove_codecs_by_id,
Expand Down Expand Up @@ -390,39 +392,15 @@ int sdp_remove_codecs_by_id(sip_msg_t* msg, str* codecs, str* media)
return 0;
}

/**
* @brief remove all SDP lines that begin with prefix
* @return -1 - error; 0 - no lines found ; 1..N - N lines deleted
*/
int sdp_remove_line_by_prefix(sip_msg_t* msg, str* prefix)
{
str body = {NULL, 0};

if(parse_sdp(msg) != 0) {
LM_ERR("Unable to parse SDP\n");
return -1;
}

body.s = ((sdp_info_t*)msg->body)->raw_sdp.s;
body.len = ((sdp_info_t*)msg->body)->raw_sdp.len;

if (body.s==NULL) {
LM_ERR("failed to get the message body\n");
return -1;
}

if (body.len==0) {
LM_DBG("message body has zero length\n");
return -1;
}
int sdp_remove_line_lump_by_prefix(sip_msg_t* msg, str* body, str* prefix) {

char *ptr = NULL;
str line = {NULL, 0};
str remove = {NULL, 0};
int found = 0;
struct lump *anchor = NULL;

ptr = find_sdp_line(body.s, body.s + body.len, prefix->s[0]);
ptr = find_sdp_line(body->s, body->s + body->len, prefix->s[0]);
while (ptr)
{
if (sdp_locate_line(msg, ptr, &line) != 0)
Expand All @@ -431,9 +409,9 @@ int sdp_remove_line_by_prefix(sip_msg_t* msg, str* prefix)
return -1;
}

if (body.s + body.len < line.s + prefix->len) // check if strncmp would run too far
if (body->s + body->len < line.s + prefix->len) // check if strncmp would run too far
{
//LM_DBG("done searching, prefix string >%.*s< (%d) does not fit into remaining buffer space (%ld) \n", prefix->len, prefix->s, prefix->len, body.s + body.len - line.s);
//LM_DBG("done searching, prefix string >%.*s< (%d) does not fit into remaining buffer space (%ld) \n", prefix->len, prefix->s, prefix->len, body->s + body->len - line.s);
break;
}

Expand Down Expand Up @@ -465,7 +443,7 @@ int sdp_remove_line_by_prefix(sip_msg_t* msg, str* prefix)
//LM_DBG("updated remove >%.*s< (%d)\n", remove.len, remove.s, remove.len);

}
ptr = find_next_sdp_line(ptr, body.s + body.len, prefix->s[0], NULL);
ptr = find_next_sdp_line(ptr, body->s + body->len, prefix->s[0], NULL);
}

if (found) {
Expand All @@ -483,28 +461,126 @@ int sdp_remove_line_by_prefix(sip_msg_t* msg, str* prefix)
return 0;
}

/**
* @brief remove all SDP lines that begin with prefix
* @return -1 - error; 0 - no lines found ; 1..N - N lines deleted
*/
int sdp_remove_line_by_prefix(sip_msg_t* msg, str* prefix, str* media)
{
str body = {NULL, 0};
int sdp_session_num = 0;
int sdp_stream_num = 0;
int found = 0;

if(parse_sdp(msg) != 0) {
LM_ERR("Unable to parse SDP\n");
return -1;
}

body.s = ((sdp_info_t*)msg->body)->raw_sdp.s;
body.len = ((sdp_info_t*)msg->body)->raw_sdp.len;

if (body.s==NULL) {
LM_ERR("failed to get the message body\n");
return -1;
}

if (body.len==0) {
LM_DBG("message body has zero length\n");
return -1;
}

if (media->s==NULL || media->len==0 ) {
LM_DBG("media type filter not set\n");
found = sdp_remove_line_lump_by_prefix(msg, &body, prefix);
} else {
LM_DBG("using media type filter: %.*s\n",media->len, media->s);

sdp_session_cell_t* sdp_session;
sdp_stream_cell_t* sdp_stream;

sdp_session_num = 0;
for (;;) {
sdp_session = get_sdp_session(msg, sdp_session_num);
if(!sdp_session) break;
sdp_stream_num = 0;
for (;;) {
sdp_stream = get_sdp_stream(msg, sdp_session_num, sdp_stream_num);
if(!sdp_stream) break;
if( sdp_stream->media.len == media->len &&
strncasecmp(sdp_stream->media.s, media->s, media->len) == 0) {

LM_DBG("range for media type %.*s: %ld - %ld\n",
sdp_stream->media.len, sdp_stream->media.s,
sdp_stream->raw_stream.s - body.s,
sdp_stream->raw_stream.s + sdp_stream->raw_stream.len - body.s
);

found += sdp_remove_line_lump_by_prefix(msg,&(sdp_stream->raw_stream),prefix);

}
sdp_stream_num++;
}
sdp_session_num++;
}
}
return found;
}


/*
int sdp_remove_str_codec_id_attrs(sip_msg_t* msg, sdp_stream_cell_t* sdp_stream, str *rm_codec)
str aline = {0, 0};
sdp_payload_attr_t *payload;
struct lump *anchor;
payload = sdp_stream->payload_attr;
while (payload) {
LM_DBG("a= ... for codec %.*s/%.*s\n",
payload->rtp_payload.len, payload->rtp_payload.s,
payload->rtp_enc.len, payload->rtp_enc.s);
if(rm_codec->len==payload->rtp_payload.len
&& strncmp(payload->rtp_payload.s, rm_codec->s,
rm_codec->len)==0) {
if(payload->rtp_enc.s!=NULL) {
if(sdp_locate_line(msg, payload->rtp_enc.s, &aline)==0)
*/


/**
* removes all SDP lines that begin with script provided prefix
* @return -1 - error; 1 - found
*/
static int w_sdp_remove_line_by_prefix(sip_msg_t* msg, char* prefix, char* bar)
static int w_sdp_remove_line_by_prefix(sip_msg_t* msg, char* prefix, char* media)
{
str prfx = {NULL, 0};
str lprefix = {NULL, 0};
str lmedia = {NULL, 0};

if(prefix==0)
{
LM_ERR("invalid parameters\n");
return -1;
}

if (get_str_fparam(&prfx, msg, (fparam_t*)prefix))
if (get_str_fparam(&lprefix, msg, (fparam_t*)prefix))
{
LM_ERR("unable to determine prefix\n");
return -1;
}
LM_DBG("Removing SDP lines with prefix: %.*s\n", prfx.len, prfx.s);

if ( sdp_remove_line_by_prefix(msg, &prfx) < 0)
if (media != NULL) {
if (get_str_fparam(&lmedia, msg, (fparam_t*)media))
{
LM_ERR("unable to get the media type\n");
return -1;
}
}

LM_DBG("Removing SDP lines with prefix: %.*s\n", lprefix.len, lprefix.s);

if ( sdp_remove_line_by_prefix(msg, &lprefix, &lmedia) < 0)
return -1;
return 1;
}
Expand Down
31 changes: 31 additions & 0 deletions test/unit/60-message-sdp9.sip
@@ -0,0 +1,31 @@
MESSAGE sip:bob@example.invalid SIP/2.0
From: sip:alice@example.invalid;tag=45dfdf49
To: sip:bob@example.invalid
Call-ID: 1172299593a
CSeq: 1 MESSAGE
Content-Type: application/sdp
Max-Forwards: 2
X-Case: 60-test9
X-Info: sdpops remove_line_by_prefix test9 - filter video attribute

v=0
o=FreeSWITCH 1447318678 1447318679 IN IP4 10.0.0.145
s=FreeSWITCH
c=IN IP4 10.0.0.145
t=0 0
m=audio 28504 RTP/AVP 96 101
a=rtpmap:96 opus/48000/2
a=fmtp:96 useinbandfec=1; maxaveragebitrate=14400; maxplaybackrate=8000
a=rtpmap:101 telephone-event/48000
a=fmtp:101 0-16
a=ptime:20
a=sendrecv
a=rtcp:28505 IN IP4 10.0.0.145
a=rtcp-fb:101 nack
m=video 21992 RTP/SAVPF 100
a=rtpmap:100 VP8/90000
a=rtcp:21992 IN IP4 10.0.0.150
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli

7 changes: 7 additions & 0 deletions test/unit/60.cfg
Expand Up @@ -26,6 +26,13 @@ route {
sl_send_reply(200,"OK");
exit;
}
if ($hdr(X-Case) == '60-test9') {
sdp_remove_line_by_prefix("a=rtcp","video");
msg_apply_changes();
set_reply_body($rb,"application/sdp");
sl_send_reply(200,"OK");
exit;
}
sl_send_reply(500,"Unknown test case");
exit;

Expand Down
36 changes: 29 additions & 7 deletions test/unit/60.sh
Expand Up @@ -20,26 +20,27 @@
. include/common
. include/require.sh

CFG=60.cfg
CFGFILE=60.cfg
TMPFILE=$(mktemp -t kamailio-test.XXXXXXXXXX)
SIPSAKOPTS="-H localhost -s sip:127.0.0.1 -v"

if ! (check_sipsak && check_kamailio && check_module "sdpops"); then
exit 0
fi

${BIN} -w . -f ${CFG} > /dev/null
${BIN} -w ${RUN_DIR} -Y ${RUN_DIR} -P ${PIDFILE} -f ${CFGFILE} > /dev/null
ret=$?

sleep 1
if [ "${ret}" -ne 0 ] ; then
echo "start fail"
${KILL}
kill_kamailio
exit ${ret}
fi

# Borken SDP should give 500 response
FILE="60-message-sdp0.sip"
sipsak -f ${FILE} -L -s sip:127.0.0.1 -v > ${TMPFILE}
sipsak ${SIPSAKOPTS} -f ${FILE} > ${TMPFILE}
ret=$?
if [ "${ret}" -eq 1 ] ; then
ret=0
Expand All @@ -55,7 +56,7 @@ for i in 1 2 3 4 5 6 7; do
TOTALBEFORE=$(awk '/^v=0/,/^$/ {total++; if ($0 ~ /^a=X-cap/ ) { prefix++;} else { other++} } END {if (prefix) {print other " + " prefix} else { print other " + 0"} }' ${FILE})
OTHERBEFORE=$(echo ${TOTALBEFORE}|cut -d+ -f1)

sipsak -f ${FILE} -L -s sip:127.0.0.1 -v > ${TMPFILE}
sipsak ${SIPSAKOPTS} -f ${FILE} > ${TMPFILE}
ret=$?
if [ "${ret}" -eq 0 ] ; then
TOTALAFTER=$(awk '/^v=0/,/^$/ {total++; if ($0 ~ /^a=X-cap/ ) { prefix++;} else { other++} } END {if (prefix) {print other " + " prefix} else { print other " + 0"} }' ${TMPFILE})
Expand All @@ -74,7 +75,7 @@ done

# Empty body should get 500 response
FILE="60-message-sdp8.sip"
sipsak -f ${FILE} -L -s sip:127.0.0.1 -v > ${TMPFILE}
sipsak ${SIPSAKOPTS} -f ${FILE} > ${TMPFILE}
ret=$?
if [ "${ret}" -eq 1 ] ; then
ret=0
Expand All @@ -84,7 +85,28 @@ else
exit ${ret}
fi

${KILL}
# Filter only video stream attributes
FILE="60-message-sdp9.sip"
TOTALBEFORE=$(awk '/^v=0/,/^$/ {total++; if ($0 ~ /^a=rtcp/ ) { prefix++;} else { other++} } END {if (prefix) {print other " + " prefix} else { print other " + 0"} }' ${FILE})
OTHERBEFORE=$(echo ${TOTALBEFORE}|cut -d+ -f1)
PREFIXBEFORE=$(echo ${TOTALBEFORE}|cut -d+ -f2)
sipsak ${SIPSAKOPTS} -f ${FILE} > ${TMPFILE}
ret=$?
if [ "${ret}" -eq 0 ] ; then
TOTALAFTER=$(awk '/^v=0/,/^$/ {total++; if ($0 ~ /^a=rtcp:/ ) { prefix++;} else { other++} } END {if (prefix) {print other " + " prefix} else { print other " + 0"} }' ${TMPFILE})
OTHERAFTER=$(echo ${TOTALBEFORE}|cut -d+ -f1)
PREFIXAFTER=$(echo ${TOTALAFTER}|cut -d+ -f2)
if [ ${PREFIXAFTER} -eq 1 ] && [ ${OTHERBEFORE} -eq ${OTHERAFTER} ]; then
ret=0
else
ret=1
echo "found ${PREFIXAFTER} lines with prefix \"a=rtcp\", was expecting 1 (in m=audio)(${FILE})"
fi
else
echo "invalid sipsak return: ${ret}"
fi

kill_kamailio
rm ${TMPFILE}
exit ${ret}

0 comments on commit 44a87c1

Please sign in to comment.