[sr-dev] git:carstenbock/ims DELETED: - 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)

Carsten Bock carsten at ng-voice.com
Thu Oct 17 17:38:26 CEST 2013


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 <carsten at bock.info>
Committer: Carsten Bock <carsten at 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 */




More information about the sr-dev mailing list