Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Snom patch: Last_ keywords extension #260

Open
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

pbertera
Copy link
Contributor

@pbertera pbertera commented Oct 1, 2016

This patch add the support for the following new scenario keywords:

  • Last_Contact_URI: returning the last Contact URI value
  • Last_From_Tag: extracting the last from-tag
  • Last_To_Tag: extracting the last to-tag

All the attribution for this patch should go to Snom Technology AG

pbertera added a commit to Snomio/sipp that referenced this pull request Oct 1, 2016
pbertera added a commit to Snomio/sipp that referenced this pull request Oct 1, 2016
@wdoekes
Copy link
Member

wdoekes commented Oct 2, 2016

This is not the way to move forward. If you look at the syntax suggested in #132, I would envision these to be called like:

[last_Contact.uri], [last_From.param.tag], [last_To.param.tag] or similar.

See https://www.opensips.org/Documentation/Script-Tran-2-2 for ideas.

I don't mind if only ".value", ".uri" and ".param.tag" are implemented, but at least it would provide a solid syntax to build more features on, instead of of adding E_Message* for every individually requested feature.

@pbertera
Copy link
Contributor Author

pbertera commented Oct 4, 2016

Yes, you are right, I agree with this more general approach instead of adding more E_Message*.

Here: master...Snomio:last_extensions I'm working on a solution for this, the patch implements:

  • last_XXX:value
  • last_XXX:param.tag
  • last_XXX:uri

So should cover this and #258, your feedback are appreciated,

Thanks,

Copy link
Contributor Author

@pbertera pbertera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you look at the code ?
If is sufficiently clean / correct I'll work on the documentation.

Thanks

fi
else
fail "process failure"
fi
Copy link
Member

@wdoekes wdoekes Oct 6, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be done without so much nesting with negative tests instead:

if test $status -ne 0; then
    fail "process failure"
elif ! grep -q '^LAST From: "Tom Jones" <sip:tom\.jones@wales.uk>;tag=SIPpTag001$' log.log; then
    fail "From header not found"
...

<log message="LAST To: [last_To:value]"/>
<log message="LAST To:uri: [last_To:uri]"/>
<log message="LAST Contact:uri: [last_Contact:uri]"/>
<log message="LAST From-tag: [last_From:param.tag]"/>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your "key names" don't correspond to the lookups:

Suggest:
LAST Contact|[last_Contact]
LAST Via:value|[last_Via:value]
etc..

src/call.cpp Outdated
return ret;
}
ERROR("Token %s not valid in %s", sep, name);
}
Copy link
Member

@wdoekes wdoekes Oct 6, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is too big. The code in the if(strcmp..){...} blocks should be delegated to helper methods and duplicate code should be avoided.

For example:

        if (!sep) { /* [last_Header] */
            sprintf(with_colon, "%s:", name);
            return get_header(last_recv_msg, with_colon, false);
        } 

        /* [last_Header:...] */
        sprintf(with_colon, "%.*s", (sep - name + 1), name);
        if (!strcmp(sep, ":")) {
            return get_header(last_recv_msg, with_colon, false);
        }

        char *value = get_header(last_recv_msg, with_colon, true);
        if (!strcmp(sep, ":value")) {
            ; /* done */
        } else if (!strcmp(sep, ":uri")) {
            extract_header_uri(value); /* reuse mem in value (memmove?) */
        } else if (....) {
            ...
        } else {
            ERROR("Token %s not valid in %s", sep, name);
        }

        return value;

include/call.hpp Outdated
@@ -291,7 +291,8 @@ class call : virtual public task, virtual public listener, public virtual socket

char * get_header_field_code(const char * msg, const char * code);
char * get_last_header(const char * name);
char * get_last_request_uri();
char * get_last_tag (const char *name);
char * get_last_request_uri(const char *name);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be called get_last_request_uri but get_last_uri_from or something.

src/call.cpp Outdated
snprintf(with_colon, len - 2, "%s", name);
char * last_header_uri = get_last_request_uri(with_colon);
char * ret;
if (!(ret = (char *)malloc(strlen(last_header_uri + 1)))){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_header() returns a static buffer (yuck, I know).

You can't start returning malloc'ed memory all of a sudden: memory leaks.

src/call.cpp Outdated
@@ -972,6 +1011,48 @@ char * call::get_last_request_uri()
return last_request_uri;
}

/* Return the last tag from the header line. On any error returns the
* empty string. The caller must free the result. */
char * call::get_last_tag(const char *name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be implemented in sip_parser.cpp instead. See get_peer_tag.

@pbertera
Copy link
Contributor Author

pbertera commented Oct 7, 2016

Thanks for all the hints, can you give me your feedback ?
Thanks a lot,

Copy link
Member

@wdoekes wdoekes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry for being picky. But if we're changing the source, it should be for the better.


if test $status -ne 0; then
fail "process failure"
elif ! grep -e ^LAST\ Contact\|Contact:\ \<sip:sipp@127.0.0.1:5060\> log.log > /dev/null; then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use single-quotes instead. And -q so you don't have to redirect to /dev/null. (And with -F you can do regular string comparisons without worrying about special regex tokens.)

grep -qF 'LAST Contact|Contact: <sip:sipp@127.0.0.1:5060>' log.log

@@ -109,6 +109,11 @@ char * get_peer_tag(const char *msg)
return tag;
}

char * get_peer_tag(const char *msg)
{
return get_param_tag(msg, "To", "t");
Copy link
Member

@wdoekes wdoekes Oct 8, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could also be:

get_param(msg, "tag", "To", "t");

That'd be even more generic.

src/call.cpp Outdated
@@ -2201,7 +2234,7 @@ char* call::createSendingMessage(SendingMessage *src, int P_index, char *msg_buf
}
break;
case E_Message_Last_Request_URI: {
char * last_request_uri = get_last_request_uri();
char * last_request_uri = get_last_header_uri("To:");
dest += sprintf(dest, "%s", last_request_uri);
free(last_request_uri);
Copy link
Member

@wdoekes wdoekes Oct 8, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not this?

dest += sprintf(dest, "%s", get_last_header("To:uri"));

And drop the entire get_last_header_uri() method.

The get_uri-code could be implemented in sip_parser.cpp instead as get_first_uri(const char *msg, const char *name, const char *shortname) or something, with the same semantics as the other get_* functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why you wrote get_first_uri ? maybe you are thinking about multiple URI in the header ?

src/call.cpp Outdated
char * last_tag = get_param_tag(last_recv_msg, header_name, "");
int last_tag_len = strlen(last_tag);
memmove(value, last_tag, last_tag_len);
value[last_tag_len] = '\0';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

memmove(value, last_tag, strlen(last_tag) + 1);

.. copies the NUL along.

src/call.cpp Outdated
if (name[len - 1] == ':') {
return get_header(last_recv_msg, name, false);
}
char *value = get_header(last_recv_msg, header_name, true);
Copy link
Member

@wdoekes wdoekes Oct 8, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently you're not using value get_header(last_recv_msg, header_name, true); here, move it to the ; /* done */ instead.

It would be only useful here if we used functions that operate on that single header directly later on, e.g.:

  • get_param(value, "tag"); or extract_param(value, "tag");
  • get_first_uri(value); or extract_first_uri(value);

They could certainly be implemented and would clean up things some more.

src/call.cpp Outdated
int uri_len = strlen(uri);
memmove(value, uri, uri_len);
value[uri_len] = '\0';
free(uri);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If get_last_header_uri is dropped, we get rid of this unusual free() here (because of the different semantics of get_last_header_uri).

@pbertera
Copy link
Contributor Author

@wdoekes no pickiness, unfortunately my programming skills are very weak. Your fine grained review is a warranty for the quality of SIPp, thanks a lot.
I hope the code now is an acceptable level of quality, if yes I'll write an example scenario and I'all add the note to the changelog.
Many thanks,

@wdoekes
Copy link
Member

wdoekes commented Nov 6, 2016

Sorry for the delay. I've been busy. I'll try to get to this in the coming week.

@wdoekes
Copy link
Member

wdoekes commented Dec 21, 2016

Note to self: this fails:

Testing github-#0152: failed (got 0 calls, and 0 failed)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants