Skip to content

Commit

Permalink
lost: additions to <via> path element and corrected loop detection
Browse files Browse the repository at this point in the history
- LosT requests that allow recursion now include a <path> element that
  contains one or more <via> elements. A loop error is indicated if a
  returned target is already in the server list in the <path> element.
  • Loading branch information
wkampich committed Apr 1, 2023
1 parent c7e228e commit 757cb48
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 24 deletions.
73 changes: 53 additions & 20 deletions src/modules/lost/functions.c
Expand Up @@ -819,7 +819,9 @@ int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name,
str req = STR_NULL;
str con = STR_NULL;
str ret = STR_NULL;
str src = STR_NULL;
str pidf = STR_NULL;
str rereq = STR_NULL;
str oldurl = STR_NULL;
str losturl = STR_NULL;

Expand Down Expand Up @@ -1063,9 +1065,8 @@ int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name,
goto err;
}
/* assemble findService request */
req.s = lost_find_service_request(loc, &req.len);
lost_free_loc(&loc); /* clean up */

req.s = lost_find_service_request(loc, NULL, &req.len);

if(req.s == NULL && req.len == 0) {
LM_ERR("lost request failed\n");
goto err;
Expand Down Expand Up @@ -1113,7 +1114,7 @@ int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name,

LM_DBG("findService response: [%.*s]\n", ret.len, ret.s);

/* at least parse one request */
/* at least parse one response */
redirect = 1;
while(redirect) {
fsrdata = lost_parse_findServiceResponse(ret);
Expand Down Expand Up @@ -1186,6 +1187,39 @@ int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name,
tmp.len = strlen(fsrdata->redirect->target);
url.s = &(ustr[0]);
url.len = MAX_URI_SIZE;
/* check loop ... current response */
if(oldurl.s != NULL && oldurl.len > 0) {
if(str_strcasecmp(&tmp, &oldurl) == 0) {
LM_ERR("loop detected: "
"[%.*s]<-->[%.*s]\n",
oldurl.len, oldurl.s, tmp.len, tmp.s);
goto err;
}
}
/* add redirecting source to path list */
if((src.s = fsrdata->redirect->source) != NULL) {
src.len = strlen(fsrdata->redirect->source);
if(lost_append_response_list(&fsrdata->path, src) == 0) {
LM_ERR("could not append server to path elememt\n");
goto err;
}
}
/* clean up */
src.s = NULL;
src.len = 0;
/* check loop ... path elements */
char *via = NULL;
if(lost_search_response_list(&fsrdata->path, &via, tmp.s) > 0) {
LM_ERR("loop detected: "
"[%s]<-->[%.*s]\n",
via, tmp.len, tmp.s);
goto err;
}
/* remember the redirect target */
if(pkg_str_dup(&oldurl, &tmp) < 0) {
LM_ERR("could not copy: [%.*s]\n", tmp.len, tmp.s);
goto err;
}
/* get url string via NAPTR */
naptr = lost_naptr_lookup(tmp, &shttps, &url);
if(naptr == 0) {
Expand All @@ -1200,23 +1234,15 @@ int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name,
/* clean up */
tmp.s = NULL;
tmp.len = 0;
/* check loop */
if(oldurl.s != NULL && oldurl.len > 0) {
if(str_strcasecmp(&url, &oldurl) == 0) {
LM_ERR("loop detected: "
"[%.*s]<-->[%.*s]\n",
oldurl.len, oldurl.s, url.len, url.s);
goto err;
}
}
/* remember the redirect target */
if(pkg_str_dup(&oldurl, &url) < 0) {
LM_ERR("could not copy: [%.*s]\n", url.len, url.s);
goto err;
}

/* assemble new findService request including path element */
rereq.s = lost_find_service_request(loc, fsrdata->path, &rereq.len);
/* clean up */
lost_free_findServiceResponse(&fsrdata);
lost_free_string(&ret);

LM_DBG("findService request: [%.*s]\n", rereq.len, rereq.s);

/* copy url */
len = 0;
urlrep = lost_copy_string(url, &len);
Expand All @@ -1226,9 +1252,12 @@ int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name,
}
/* send request */
curl = httpapi.http_client_query(
_m, urlrep, &ret, req.s, mtlost);
pkg_free(urlrep); /*clean up */
_m, urlrep, &ret, rereq.s, mtlost);
/*clean up */
pkg_free(urlrep);
urlrep = NULL;
lost_free_string(&rereq);

/* only HTTP 2xx responses are accepted */
if(curl >= 300 || curl < 100) {
LM_ERR("POST [%.*s] failed with error: %d\n",
Expand Down Expand Up @@ -1260,6 +1289,7 @@ int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name,
lost_free_string(&ret);
lost_free_string(&req);
lost_free_string(&oldurl);
lost_free_loc(&loc);

/* set writable pvars */
pvname.rs = name;
Expand Down Expand Up @@ -1310,6 +1340,9 @@ int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name,
if(req.s != NULL && req.len > 0) {
lost_free_string(&req);
}
if(rereq.s != NULL && rereq.len > 0) {
lost_free_string(&rereq);
}
if(name.s != NULL && name.len > 0) {
lost_free_string(&name);
}
Expand Down
29 changes: 29 additions & 0 deletions src/modules/lost/response.c
Expand Up @@ -353,6 +353,35 @@ void lost_reverse_response_list(p_lost_list_t *head)
*head = prev;
}

/*
* lost_append_response_list(list, str)
* appends str value to list object and returns str len
*/
int lost_append_response_list(p_lost_list_t *head, str val)
{
int len = 0;
p_lost_list_t new = NULL;
p_lost_list_t current = *head;

new = lost_new_response_list();
if (new != NULL) {
new->value = lost_copy_string(val, &len);
new->next = NULL;

LM_DBG("### new list data [%.*s]\n", val.len, val.s);

if (current == NULL) {
*head = new;
return len;
}
while (current->next != NULL) {
current = current->next;
}
current->next = new;
}
return len;
}

/*
* lost_search_response_list(list, value, search)
* looks for search string in list object and returns pointer if found
Expand Down
4 changes: 3 additions & 1 deletion src/modules/lost/response.h
Expand Up @@ -121,7 +121,9 @@ typedef struct lost_fsr
/* read and parse response data */
p_lost_fsr_t lost_parse_findServiceResponse(str);
/* check response to dereferece request */
int lost_check_HeldResponse(xmlNodePtr);
int lost_check_HeldResponse(xmlNodePtr);
/* appends value to list objects */
int lost_append_response_list(p_lost_list_t *, str);
/* print the response */
void lost_print_findServiceResponse(p_lost_fsr_t);
/* remove response data from memory */
Expand Down
62 changes: 60 additions & 2 deletions src/modules/lost/utilities.c
Expand Up @@ -48,6 +48,7 @@

#include "pidf.h"
#include "utilities.h"
#include "response.h"

extern int lost_recursion;
extern int lost_profile;
Expand Down Expand Up @@ -1492,10 +1493,48 @@ char *lost_held_location_request(p_lost_held_t held, int *lgth)
}

/*
* lost_find_service_request(loc, lgth)
* lost_append_via_element(head, parent)
* appends via elements and returns the number of via elements added
*/
int lost_append_via_element(p_lost_list_t *head, xmlNodePtr *parent)
{
int cnt = 0;
int i;
p_lost_list_t current = NULL;

if (head == NULL) {
return 0;
}

/* at least one <via> element to add */
current = *head;
cnt++;

/* check for more <via> elements to add */
while (current->next != NULL) {
cnt++;
current = current->next;
}

current = *head;
xmlNodePtr ptrVia[cnt];

/* ad <via> elements to <path> element */
for (i = 0; i < cnt; i++) {
ptrVia[i] = xmlNewChild(*parent, NULL, BAD_CAST "via", NULL);
xmlNewProp(ptrVia[i], BAD_CAST "source", BAD_CAST current->value);
current = current->next;
}

return cnt;
}


/*
* lost_find_service_request(loc, path, lgth)
* assembles and returns findService request string (allocated in private memory)
*/
char *lost_find_service_request(p_lost_loc_t loc, int *lgth)
char *lost_find_service_request(p_lost_loc_t loc, p_lost_list_t path, int *lgth)
{
int buffersize = 0;

Expand All @@ -1511,6 +1550,7 @@ char *lost_find_service_request(p_lost_loc_t loc, int *lgth)
xmlNodePtr ptrCircle = NULL;
xmlNodePtr ptrRadius = NULL;
xmlNodePtr ptrNode = NULL;
xmlNodePtr ptrPath = NULL;

xmlKeepBlanksDefault(1);

Expand All @@ -1531,6 +1571,10 @@ char *lost_find_service_request(p_lost_loc_t loc, int *lgth)
</p2:Point>
</location>
<service>urn:service:sos.police</service>
<path>
<via source="resolver.example"/>
<via source="authoritative.example"/>
</path>
</findService>
*/
/* create request */
Expand Down Expand Up @@ -1623,6 +1667,20 @@ char *lost_find_service_request(p_lost_loc_t loc, int *lgth)
/* service - element */
snprintf(buf, BUFSIZE, "%s", loc->urn);
xmlNewChild(ptrFindService, NULL, BAD_CAST "service", BAD_CAST buf);
/* service - element */
if (path != NULL) {
ptrPath = xmlNewChild(ptrFindService, NULL, BAD_CAST "path", NULL);
if(ptrPath == NULL) {
LM_ERR("locationRequest xmlNewChild() failed\n");
xmlFreeDoc(request);
return doc;
}
if (lost_append_via_element(&path, &ptrPath) == 0) {
LM_ERR("appending <via> elements to <path> failed\n");
xmlFreeDoc(request);
return doc;
}
}

xmlDocDumpFormatMemory(request, &xmlbuff, &buffersize, 0);
if(xmlbuff == NULL) {
Expand Down
4 changes: 3 additions & 1 deletion src/modules/lost/utilities.h
Expand Up @@ -32,6 +32,8 @@
#ifndef LOST_UTILITIES_H
#define LOST_UTILITIES_H

#include "response.h"

#define LAQUOT '<'
#define COLON ':'

Expand Down Expand Up @@ -132,7 +134,7 @@ int lost_parse_host(const char *, str *, int *);
int lost_new_geoheader_list(p_lost_geolist_t *, str);
int lost_get_nameinfo(char *, str *, int);

char *lost_find_service_request(p_lost_loc_t, int *);
char *lost_find_service_request(p_lost_loc_t, p_lost_list_t, int *);
char *lost_held_location_request(p_lost_held_t, int *);
char *lost_held_post_request(int *, long, char *);
char *lost_get_content(xmlNodePtr, const char *, int *);
Expand Down

0 comments on commit 757cb48

Please sign in to comment.