parser: const-correctness for some module utility functions
[sip-router] / dset.c
diff --git a/dset.c b/dset.c
index e3dc844..4ba5ccf 100644 (file)
--- a/dset.c
+++ b/dset.c
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-/*!
- * \file
- * \brief SIP-router core :: 
- * \ingroup core
- * Module: \ref core
+/** destination set / branches support.
+ * @file dset.c
+ * @ingroup core
+ * Module: @ref core
  */
 
 #include <string.h>
 #define Q_PARAM ">;q="
 #define Q_PARAM_LEN (sizeof(Q_PARAM) - 1)
 
-struct branch
-{
-       char uri[MAX_URI_SIZE];
-       unsigned int len;
-
-            /* Real destination of the request */
-       char dst_uri[MAX_URI_SIZE];
-       unsigned int dst_uri_len;
-
-       /* Path set */
-       char path[MAX_PATH_SIZE];
-       unsigned int path_len;
-
-       int q; /* Preference of the contact among
-               * contact within the array */
-       struct socket_info* force_send_socket;
-
-       /* Branch flags */
-       flag_t flags;
-};
-
 
 /* 
  * Where we store URIs of additional transaction branches
@@ -89,6 +67,9 @@ unsigned int nr_branches = 0;
 /* branch iterator */
 static int branch_iterator = 0;
 
+/* used to mark ruris "consumed" when branching (1 new, 0 consumed) */
+int ruri_is_new = 0;
+
 /* The q parameter of the Request-URI */
 static qvalue_t ruri_q = Q_UNSPECIFIED;
 
@@ -96,6 +77,54 @@ static qvalue_t ruri_q = Q_UNSPECIFIED;
 static flag_t ruri_bflags;
 
 
+/*! \brief
+ * Return pointer to branch[idx] structure
+ * @param idx - branch index
+ *
+ * @return  pointer to branch or NULL if invalid branch
+ */
+branch_t *get_sip_branch(int idx)
+{
+       if(nr_branches==0)
+               return NULL;
+       if(idx<0)
+       {
+               if(nr_branches + idx >= 0)
+                       return &branches[nr_branches+idx];
+               return NULL;
+       }
+       if(idx < nr_branches)
+               return &branches[idx];
+       return 0;
+}
+
+/*! \brief
+ * Drop branch[idx]
+ * @param idx - branch index
+ *
+ * @return  0 on success, -1 on error
+ */
+int drop_sip_branch(int idx)
+{
+       if(nr_branches==0 || idx>=nr_branches)
+               return 0;
+       if(idx<0 && nr_branches+idx<0)
+               return 0;
+       /* last branch */
+       if(idx==nr_branches-1)
+       {
+               nr_branches--;
+               return 0;
+       }
+       if(idx<0)
+               idx = nr_branches+idx;
+       /* shift back one position */
+       for(; idx<nr_branches-1; idx++)
+               memcpy(&branches[idx], &branches[idx+1], sizeof(branch_t));
+       nr_branches--;
+       return 0;
+}
+
 static inline flag_t* get_bflags_ptr(unsigned int branch)
 {
        if (branch == 0) return &ruri_bflags;
@@ -162,11 +191,21 @@ void init_branch_iterator(void)
        branch_iterator = 0;
 }
 
+/**
+ * return the value of current branch iterator
+ */
 int get_branch_iterator(void)
 {
        return branch_iterator;
 }
 
+/**
+ * set the value of current branch interator
+ */
+void set_branch_iterator(int n)
+{
+       branch_iterator = n;
+}
 
 
 /** \brief Get a branch from the destination set
@@ -239,6 +278,7 @@ void clear_branches(void)
        nr_branches = 0;
        ruri_q = Q_UNSPECIFIED;
        ruri_bflags = 0;
+       ruri_mark_consumed();
 }
 
 
@@ -259,11 +299,6 @@ int append_branch(struct sip_msg* msg, str* uri, str* dst_uri, str* path,
 {
        str luri;
 
-#ifdef USE_LOCAL_ROUTE
-       if (unlikely(dset_state==0))
-               return -1;
-#endif
-
        /* if we have already set up the maximum number
         * of branches, don't try new ones 
         */
@@ -341,6 +376,7 @@ char* print_dset(struct sip_msg* msg, int* len)
        qvalue_t q;
        str uri;
        char* p, *qbuf;
+       int crt_branch;
        static char dset[MAX_REDIRECTION_LEN];
 
        if (msg->new_uri.s) {
@@ -354,6 +390,9 @@ char* print_dset(struct sip_msg* msg, int* len)
                *len = 0;
        }
 
+       /* backup current branch index to restore it later */
+       crt_branch = get_branch_iterator();
+
        init_branch_iterator();
        while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0, 0))) {
                cnt++;
@@ -369,7 +408,7 @@ char* print_dset(struct sip_msg* msg, int* len)
 
        if (*len + 1 > MAX_REDIRECTION_LEN) {
                LOG(L_ERR, "ERROR: redirection buffer length exceed\n");
-               return 0;
+               goto error;
        }
 
        memcpy(dset, CONTACT, CONTACT_LEN);
@@ -420,7 +459,12 @@ char* print_dset(struct sip_msg* msg, int* len)
        }
 
        memcpy(p, CRLF " ", CRLF_LEN + 1);
+       set_branch_iterator(crt_branch);
        return dset;
+
+error:
+       set_branch_iterator(crt_branch);
+       return 0;
 }
 
 
@@ -466,6 +510,8 @@ int rewrite_uri(struct sip_msg* _m, str* _s)
 
         _m->new_uri.s = buf;
         _m->new_uri.len = _s->len;
+        /* mark ruri as new and available for forking */
+        ruri_mark_new();
 
         return 1;
 }