Module: sip-router Branch: carstenbock/ims DELETED Commit: a80729125de45d2e147a970315c08df378626f64 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=a8072912...
Author: Carsten Bock carsten@bock.info Committer: Carsten Bock carsten@bock.info Date: Mon May 9 13:55:16 2011 +0200
- extended the API of Record-Route in order to retrieve the routeset and the remote URI (needed for later validation/enforcement of route-sets in requests)
---
modules_k/rr/api.c | 3 + modules_k/rr/api.h | 10 ++++ modules_k/rr/loose.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++- modules_k/rr/loose.h | 19 ++++++++ 4 files changed, 151 insertions(+), 1 deletions(-)
diff --git a/modules_k/rr/api.c b/modules_k/rr/api.c index 55af538..0835b72 100644 --- a/modules_k/rr/api.c +++ b/modules_k/rr/api.c @@ -64,6 +64,9 @@ int load_rr( struct rr_binds *rrb ) rrb->get_route_param = get_route_param; rrb->register_rrcb = register_rrcb; rrb->append_fromtag = append_fromtag; + rrb->get_remoteuri = get_remoteuri; + rrb->get_routeset = get_routeset; + rrb->rr_type = rr_type;
return 1; } diff --git a/modules_k/rr/api.h b/modules_k/rr/api.h index 09c9a4e..91da2ea 100644 --- a/modules_k/rr/api.h +++ b/modules_k/rr/api.h @@ -46,12 +46,19 @@ #include "loose.h" #include "rr_cb.h"
+#define RR_TYPE_STRICT_LOOSE (1<<1) +#define RR_TYPE_STRICT_STRICT (1<<2) +#define RR_TYPE_LOOSE_LOOSE (1<<3) +#define RR_TYPE_LOOSE_STRICT (1<<4) + typedef int (*add_rr_param_t)(struct sip_msg*, str*); typedef int (*check_route_param_t)(struct sip_msg*, regex_t*); typedef int (*is_direction_t)(struct sip_msg*, int); typedef int (*get_route_param_t)(struct sip_msg*, str*, str*); typedef int (*record_route_f)(struct sip_msg*, str*); typedef int (*loose_route_f)(struct sip_msg*); +typedef str* (*get_remoteuri_t)(struct sip_msg*); +typedef str* (*get_routeset_t)(struct sip_msg*, int *nr_routes);
/*! record-route API export binding */ typedef struct rr_binds { @@ -63,6 +70,9 @@ typedef struct rr_binds { get_route_param_t get_route_param; register_rrcb_t register_rrcb; int append_fromtag; + get_remoteuri_t get_remoteuri; + get_routeset_t get_routeset; + int rr_type; } rr_api_t;
typedef int (*load_rr_f)( struct rr_binds* ); diff --git a/modules_k/rr/loose.c b/modules_k/rr/loose.c index 9cf1ef9..5d0fccf 100644 --- a/modules_k/rr/loose.c +++ b/modules_k/rr/loose.c @@ -43,6 +43,7 @@ #include "loose.h" #include "rr_cb.h" #include "rr_mod.h" +#include "api.h"
#define RR_ERROR -1 /*!< An error occured while processing route set */ @@ -639,6 +640,8 @@ static inline int after_strict(struct sip_msg* _m)
if (is_strict(&puri.params)) { LM_DBG("Next hop: '%.*s' is strict router\n", uri.len, ZSW(uri.s)); + rr_type = RR_TYPE_STRICT_STRICT; + /* Previous hop was a strict router and the next hop is strict * router too. There is no need to save R-URI again because it * is saved already. In fact, in this case we will behave exactly @@ -671,6 +674,7 @@ static inline int after_strict(struct sip_msg* _m) } else { LM_DBG("Next hop: '%.*s' is loose router\n", uri.len, ZSW(uri.s)); + rr_type = RR_TYPE_STRICT_LOOSE;
if(get_maddr_uri(&uri, &puri)!=0) { LM_ERR("failed to check maddr\n"); @@ -800,6 +804,9 @@ static inline int after_loose(struct sip_msg* _m, int preloaded) if (res > 0) { /* No next route found */ LM_DBG("No next URI found\n"); status = (preloaded ? NOT_RR_DRIVEN : RR_DRIVEN); + + rr_type = RR_TYPE_LOOSE_LOOSE; + goto done; } rt = (rr_t*)hdr->parsed; @@ -835,6 +842,7 @@ static inline int after_loose(struct sip_msg* _m, int preloaded) if (res > 0) { /* No next route found */ LM_DBG("no next URI found\n"); status = (preloaded ? NOT_RR_DRIVEN : RR_DRIVEN); + rr_type = RR_TYPE_LOOSE_LOOSE; goto done; } rt = (rr_t*)hdr->parsed; @@ -858,6 +866,7 @@ static inline int after_loose(struct sip_msg* _m, int preloaded) LM_DBG("URI to be processed: '%.*s'\n", uri.len, ZSW(uri.s)); if (is_strict(&puri.params)) { LM_DBG("Next URI is a strict router\n"); + rr_type = RR_TYPE_LOOSE_STRICT; if (handle_sr(_m, hdr, rt) < 0) { LM_ERR("failed to handle strict router\n"); return RR_ERROR; @@ -865,7 +874,7 @@ static inline int after_loose(struct sip_msg* _m, int preloaded) } else { /* Next hop is loose router */ LM_DBG("Next URI is a loose router\n"); - + rr_type = RR_TYPE_LOOSE_LOOSE; if(get_maddr_uri(&uri, &puri)!=0) { LM_ERR("checking maddr failed\n"); return RR_ERROR; @@ -905,6 +914,7 @@ done: int loose_route(struct sip_msg* _m) { int ret; + rr_type = 0;
if (find_first_route(_m) != 0) { LM_DBG("There is no Route HF\n"); @@ -1133,3 +1143,111 @@ upstream: last_dir = RR_FLOW_UPSTREAM; return (dir==RR_FLOW_UPSTREAM)?0:-1; } + +/*! + * \brief Gets the URI of the remote destination, based on the route-set. + * + * \param msg - request that will have the Route header parameter searched + * \return A str with the URI of the remote target. + */ +str* get_remoteuri(struct sip_msg *msg) { + int res; + struct hdr_field *hdr; + rr_t *rt,*prev; + str *uri; + + if (msg == NULL) { + LM_ERR("No SIP-Message, internal error?!?!\n"); + return NULL; + } + /* If we are a loose-router, + we find the Remote URI in the Request URI. */ + if ((rr_type == RR_TYPE_LOOSE_LOOSE) + || (rr_type == RR_TYPE_LOOSE_STRICT)) { + return &msg->first_line.u.request.uri; + } else if (rr_type == RR_TYPE_STRICT_LOOSE) { + /* We are a strict router, so the loose_route() sets the + new URI from the previous strict routing. */ + return &msg->new_uri; + } else if (rr_type == RR_TYPE_STRICT_STRICT) { + res = find_rem_target(msg, &hdr, &rt, &prev); + if (res < 0) { + /* Failed to find the last route-target */ + LM_ERR("Failed to find the last route-target\n"); + return NULL; + } else if (res > 0) { + /* No remote target found */ + LM_ERR("No remote target found!\n"); + return NULL; + } + uri = &rt->nameaddr.uri; + if(get_maddr_uri(uri, 0)!=0) { + LM_ERR("failed to check maddr\n"); + return 0; + } + return uri; + } else { + LM_ERR("Unknown / invalid routing type %d\n", rr_type); + return 0; + } +} + +/*! + * \brief Returns a list of the URI's from the route-headers + * + * \param msg - request that will have the Route header parameter searched + * \return An array of str with the URI of the next hops. + */ +#define MAX_HDRS 32 +str* get_routeset(struct sip_msg *msg,int *nr_routes) { + /* The destination, where the URI's are stored */ + static str uris[MAX_HDRS]; + /* Iterator for all record-route headers */ + struct hdr_field *hdr; + /* The parsed route-header structure */ + rr_t * rr; + + if (msg == NULL || msg->route == NULL) { + LM_ERR("No SIP-Message or no route-headers!\n"); + return NULL; + } + + if (!nr_routes) { + LM_ERR("nr_routes parameter is invalid!\n"); + return NULL; + } + *nr_routes = 0; + + if ((rr_type == RR_TYPE_STRICT_STRICT) + || (rr_type == RR_TYPE_LOOSE_STRICT)) { + /* must manually insert RURI, as it was part + * of the route deleted to make up for strict routing */ + uris[(*nr_routes)++] = msg->new_uri; + } + + hdr = msg->route; + while (hdr != NULL) { + if (parse_rr(hdr) < 0) { + LM_ERR("Invalid Route-Header, failed to parse\n"); + return NULL; + } + /* Get the parsed content of the route-header */ + rr = (rr_t*)hdr->parsed; + while (rr) { + uris[(*nr_routes)++] = rr->nameaddr.uri; + if(*nr_routes==MAX_HDRS) { + LM_ERR("Too many route-headers!!!\n"); + return 0; + } + rr = rr->next; + } + hdr = hdr->next; + } + + + /* if SS - remove last route */ + if (rr_type == RR_TYPE_STRICT_STRICT) + (*nr_routes)--; + + return uris; +} diff --git a/modules_k/rr/loose.h b/modules_k/rr/loose.h index 6b1bdc9..31157d1 100644 --- a/modules_k/rr/loose.h +++ b/modules_k/rr/loose.h @@ -38,6 +38,10 @@ #define RR_FLOW_DOWNSTREAM (1<<0) #define RR_FLOW_UPSTREAM (1<<1)
+/*! + * \brief Next-Hop is a strict or loose-router? + */ +int rr_type;
/*! * \brief Do loose routing as per RFC3261 @@ -92,5 +96,20 @@ int is_direction(struct sip_msg *msg, int dir); */ int get_route_param( struct sip_msg *msg, str *name, str *val);
+/*! + * \brief Gets the URI of the remote destination, based on the route-set. + * + * \param msg - request that will have the Route header parameter searched + * \return A str with the URI of the remote target. + */ +str* get_remoteuri(struct sip_msg *msg); + +/*! + * \brief Returns a list of the URI's from the route-headers + * + * \param msg - request that will have the Route header parameter searched + * \return An array of str with the URI of the next hops. + */ +str* get_routeset(struct sip_msg *msg, int *nr_routes);
#endif /* LOOSE_H */