]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Fri Jan 16 07:22:08 CST 2009 Pekka Pessi <first.last@nokia.com>
authorMichael Jerris <mike@jerris.com>
Wed, 11 Feb 2009 17:06:00 +0000 (17:06 +0000)
committerMichael Jerris <mike@jerris.com>
Wed, 11 Feb 2009 17:06:00 +0000 (17:06 +0000)
  * nta: added nta_leg_client_reroute()

  nta_leg_client_route() did not catch actually RFC 3261 section 12.1.2 feel
  and spirit, not to speak about letter.

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11833 d0543943-73ff-0310-b7d9-9358b9ac24b2

libs/sofia-sip/.update
libs/sofia-sip/libsofia-sip-ua/nta/nta.c
libs/sofia-sip/libsofia-sip-ua/nta/sofia-sip/nta.h

index 3887d0a6f0328ca5d12b0cc02c095eb3006bd0b7..1c24f9eb4507f560c8f666690a880971968ee51b 100644 (file)
@@ -1 +1 @@
-Wed Feb 11 11:05:09 CST 2009
+Wed Feb 11 11:05:49 CST 2009
index 163734d021c88a433acbaf93411e492032e13d37..27b74950b85ece59c631639aa6d82831b8c8f135 100644 (file)
@@ -363,6 +363,7 @@ struct nta_leg_s
 #else
   unsigned leg_loose_route : 1; /**< Topmost route in set is LR */
 #endif
+  unsigned leg_route_set : 1;  /**< Route set has been saved */
   unsigned leg_local_is_to : 1; /**< Backwards-compatibility. */
   unsigned leg_tagged : 1;     /**< Tagged after creation.
                                 *
@@ -3970,7 +3971,8 @@ static void leg_insert(nta_agent_t *agent, nta_leg_t *leg);
 static int leg_route(nta_leg_t *leg,
                     sip_record_route_t const *route,
                     sip_record_route_t const *reverse,
-                    sip_contact_t const *contact);
+                    sip_contact_t const *contact,
+                    int reroute);
 static int leg_callback_default(nta_leg_magic_t*, nta_leg_t*,
                                nta_incoming_t*, sip_t const *);
 #define HTABLE_HASH_LEG(leg) ((leg)->leg_hash)
@@ -4469,24 +4471,55 @@ uint32_t nta_leg_get_rseq(nta_leg_t const *leg)
 
 /** Save target and route set at UAC side.
  *
- * @sa nta_leg_server_route(), @RFC3261 section 12.1.2
+ * @sa nta_leg_client_reroute(), nta_leg_server_route(), @RFC3261 section 12.1.2
+ *
+ * @bug Allows modifying the route set after initial transaction, if initial
+ * transaction had no @RecordRoute headers.
+ *
+ * @deprecated Use nta_leg_client_reroute() instead.
  */
 int nta_leg_client_route(nta_leg_t *leg,
                         sip_record_route_t const *route,
                         sip_contact_t const *contact)
 {
-  return leg_route(leg, NULL, route, contact);
+  return leg_route(leg, NULL, route, contact, 0);
+}
+
+/** Save target and route set at UAC side.
+ *
+ * If @a initial is true, the route set is modified even if it has been set
+ * earlier.
+ *
+ * @param leg pointer to dialog leg
+ * @param route @RecordRoute headers from response
+ * @param contact @Contact header from response
+ * @param initial true if response to initial transaction
+ *
+ * @sa nta_leg_client_route(), nta_leg_server_route(), @RFC3261 section 12.1.2
+ *
+ * @NEW_1_12_11
+ */
+int nta_leg_client_reroute(nta_leg_t *leg,
+                          sip_record_route_t const *route,
+                          sip_contact_t const *contact,
+                          int initial)
+{
+  return leg_route(leg, NULL, route, contact, initial ? 2 : 1);
 }
 
 /** Save target and route set at UAS side.
  *
- * @sa nta_leg_client_route(), @RFC3261 section 12.1.1
+ * @param leg pointer to dialog leg
+ * @param route @RecordRoute headers from request
+ * @param contact @Contact header from request
+ *
+ * @sa nta_leg_client_reroute(), @RFC3261 section 12.1.1
  */
 int nta_leg_server_route(nta_leg_t *leg,
                         sip_record_route_t const *route,
                         sip_contact_t const *contact)
 {
-  return leg_route(leg, route, NULL, contact);
+  return leg_route(leg, route, NULL, contact, 1);
 }
 
 /** Return route components. */
@@ -4940,15 +4973,21 @@ nta_leg_t *dst_find(nta_agent_t const *sa,
  *
  * Sets the leg route and contact using the @RecordRoute and @Contact
  * headers.
+ *
+ * @param reroute - allow rerouting
+ * - if 1, follow @RFC3261 semantics
+ * - if 2, response to initial transaction)
  */
 static
 int leg_route(nta_leg_t *leg,
              sip_record_route_t const *route,
              sip_record_route_t const *reverse,
-             sip_contact_t const *contact)
+             sip_contact_t const *contact,
+             int reroute)
 {
   su_home_t *home = leg->leg_home;
-  sip_route_t *r, r0[1];
+  sip_route_t *r, r0[1], *old;
+  int route_is_set;
 
   if (!leg)
     return -1;
@@ -4958,7 +4997,9 @@ int leg_route(nta_leg_t *leg,
 
   sip_route_init(r0);
 
-  if (leg->leg_route) {
+  route_is_set = reroute ? leg->leg_route_set : leg->leg_route != NULL;
+
+  if (route_is_set && reroute <= 1) {
     r = leg->leg_route;
   }
   else if (route) {
@@ -5023,8 +5064,14 @@ int leg_route(nta_leg_t *leg,
   }
 #endif
 
+  old = leg->leg_route;
   leg->leg_route = r;
 
+  if (old && old != r)
+    msg_header_free(leg->leg_home, (msg_header_t *)old);
+
+  leg->leg_route_set = 1;
+
   return 0;
 }
 
index edd2ec63cb25c628cedf1e853d6deb0ce5555eb5..bc18fa75366c8f428ec5f4a17643021e06d6ca58 100644 (file)
@@ -216,12 +216,15 @@ SOFIAPUBFUN uint32_t nta_leg_get_seq(nta_leg_t const *leg);
 /** Get remote request sequence number. @NEW_1_12_9 */
 SOFIAPUBFUN uint32_t nta_leg_get_rseq(nta_leg_t const *leg);
 
-/** Set UAC route. */
 SOFIAPUBFUN int nta_leg_client_route(nta_leg_t *leg,
                                     sip_record_route_t const *route,
                                     sip_contact_t const *contact);
 
-/** Set UAS route */
+SOFIAPUBFUN int nta_leg_client_reroute(nta_leg_t *leg,
+                                      sip_record_route_t const *route,
+                                      sip_contact_t const *contact,
+                                      int initial);
+
 SOFIAPUBFUN int nta_leg_server_route(nta_leg_t *leg,
                                     sip_record_route_t const *route,
                                     sip_contact_t const *contact);