Module: sip-router
Branch: carstenbock/ims DELETED
Commit: a80729125de45d2e147a970315c08df378626f64
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=a80729125de45d2e147a970315c08df378626f64

Author: Carsten Bock <[email protected]>
Committer: Carsten Bock <[email protected]>
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 */


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to