[Freeswitch-svn] [commit] r7819 - freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua

Freeswitch SVN mikej at freeswitch.org
Fri Mar 7 12:43:21 EST 2008


Author: mikej
Date: Fri Mar  7 12:43:21 2008
New Revision: 7819

Modified:
   freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.c
   freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.h

Log:
  * test_proxy: trying to support 200 OK retransmissions over TCP better
  
  Keeping INVITE transactions alive for 64*T1 after initial 200 OK.
  
  Added test_proxy_set_logging() for easier debugging.



Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.c
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.c	(original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.c	Fri Mar  7 12:43:21 2008
@@ -46,6 +46,7 @@
 #define NTA_LEG_MAGIC_T union proxy_or_domain
 #define NTA_OUTGOING_MAGIC_T struct client_tr
 #define NTA_INCOMING_MAGIC_T struct proxy_tr
+#define SU_TIMER_ARG_T struct proxy_tr
 
 #include <sofia-sip/su_wait.h>
 #include <sofia-sip/nta.h>
@@ -64,7 +65,7 @@
 
 #define LIST_PROTOS(STORAGE, PREFIX, T)			 \
 STORAGE void PREFIX ##_insert(T **list, T *node),	 \
-        PREFIX ##_remove(T *node)			 
+  PREFIX ##_remove(T *node)
 
 #define LIST_BODIES(STORAGE, PREFIX, T, NEXT, PREV)	  \
 STORAGE void PREFIX ##_insert(T **list, T *node)   \
@@ -110,10 +111,12 @@
 
   struct proxy_tr *stateless;
   struct proxy_tr *transactions;
+  struct proxy_tr *invite_waiting;
 
   struct domain *domains;
 
   struct {
+    unsigned t1x64;
     sip_time_t session_expires, min_se;
   } prefs;
 }; 
@@ -189,37 +192,40 @@
 
 LIST_PROTOS(static, proxy_tr, struct proxy_tr);
 struct proxy_tr *proxy_tr_new(struct proxy *);
+static void proxy_tr_timeout(struct proxy_tr *t);
 static void proxy_tr_destroy(struct proxy_tr *t);
 
 struct proxy_tr
 {
   struct proxy_tr *next, **prev;
 
-  struct proxy *proxy;		/* backpointer */
+  struct proxy *proxy;		/**< Backpointer to proxy */
 
-  struct domain *origin;	/* originating domain */
-  struct domain *domain;	/* destination domain */
+  struct domain *origin;	/**< Originating domain */
+  struct domain *domain;	/**< Destination domain */
 
-  sip_time_t now;		/* when received */
+  sip_time_t now;		/**< When received */
 
-  nta_incoming_t *server;	/* server transaction */
-  msg_t *msg;			/* request message */
-  sip_t *sip;			/* request headers */
+  nta_incoming_t *server;	/**< server transaction */
+  msg_t *msg;			/**< request message */
+  sip_t *sip;			/**< request headers */
 
-  sip_method_t method;		/* request method */
+  sip_method_t method;		/**< request method */
   char const *method_name;
-  int status;			/* best status */
-  url_t *target;		/* request-URI */
+  int status;			/**< best status */
+  url_t *target;		/**< request-URI */
 
-  struct client_tr *clients;	/* client transactions */
+  struct client_tr *clients;	/**< Client transactions */
 
   struct registration_entry *entry;
-				/* Registration entry */
+				/**< Registration entry */
 
-  auth_mod_t *am;		/* Authentication module */
-  auth_status_t *as;		/* Authentication status */
-  char const *realm;		/* Authentication realm to use */
-  unsigned use_auth;		/* Authentication method (401/407) to use */
+  auth_mod_t *am;		/**< Authentication module */
+  auth_status_t *as;		/**< Authentication status */
+  char const *realm;		/**< Authentication realm to use */
+  unsigned use_auth;		/**< Authentication method (401/407) to use */
+
+  su_timer_t *timer;		/**< Timer */
 
   unsigned rr:1;
 };
@@ -298,6 +304,9 @@
 				  NTATAG_CLIENT_RPORT(1),
 				  TAG_NEXT(proxy->tags));
 
+  if (!proxy->agent)
+    return -1;
+
   proxy->transport_contacts = create_transport_contacts(proxy);
 
   proxy->defleg = nta_leg_tcreate(proxy->agent,
@@ -308,6 +317,11 @@
 
   proxy->prefs.session_expires = 180;
   proxy->prefs.min_se = 90;
+  proxy->prefs.t1x64 = 64 * 500;
+
+  nta_agent_get_params(proxy->agent,
+		       NTATAG_SIP_T1X64_REF(proxy->prefs.t1x64),
+		       TAG_END());
 
   if (!proxy->defleg) 
     return -1;
@@ -417,6 +431,25 @@
   return p->lr_str;
 }
 
+struct _set_logging {
+  struct proxy *p;
+  int logging;
+};
+ 
+static int _set_logging(void *_a)
+{
+  struct _set_logging *a = _a;
+  return nta_agent_set_params(a->p->agent, TPTAG_LOG(a->logging), TAG_END());
+}
+
+void test_proxy_set_logging(struct proxy *p, int logging)
+{
+  if (p) {
+    struct _set_logging a[1] = {{ p, logging }};
+    su_task_execute(su_clone_task(p->clone), _set_logging, a, NULL);
+  }
+}
+
 void test_proxy_domain_set_expiration(struct domain *d,
 				      sip_time_t min_expires, 
 				      sip_time_t expires, 
@@ -1077,27 +1110,90 @@
 		   nta_outgoing_t *client,
 		   sip_t const *sip)
 {
-  int final;
+  int final, timeout = 0;
 
   assert(c->t);
 
   if (sip) {
     msg_t *response = nta_outgoing_getresponse(client);
-    final = sip->sip_status->st_status >= 200;
+    if (c->t->method == sip_method_invite)
+      final = sip->sip_status->st_status >= 300, 
+	timeout = sip->sip_status->st_status >= 200;
+    else
+      final = sip->sip_status->st_status >= 200;
     sip_via_remove(response, sip_object(response));
     nta_incoming_mreply(c->t->server, response);
   }
   else {
+    int status = nta_outgoing_status(c->client);
+    char const *phrase;
+
+    if (status < 300 || status > 699)
+      status = 500;
+    phrase = sip_status_phrase(status);
+    respond_transaction(c->t, status, phrase, TAG_END());
     final = 1;
-    respond_transaction(c->t, SIP_408_REQUEST_TIMEOUT, TAG_END());
   }
 
   if (final)
     proxy_tr_destroy(c->t);
+  else if (timeout)
+    proxy_tr_timeout(c->t);
 
   return 0;
 }
 
+int proxy_late_response(struct client_tr *c,
+			nta_outgoing_t *client,
+			sip_t const *sip)
+{
+  assert(c->t);
+
+  if (sip &&
+      sip->sip_status->st_status >= 200 && 
+      sip->sip_status->st_status < 300) {
+    msg_t *response = nta_outgoing_getresponse(client);
+    sip_via_remove(response, sip_object(response));
+    nta_incoming_mreply(c->t->server, response);
+  }
+
+  return 0;
+}
+
+static void proxy_tr_remove_late(su_root_magic_t *magic,
+				 su_timer_t *timer,
+				 struct proxy_tr *t)
+{
+  proxy_tr_destroy(t);
+}
+
+
+/** Proxy only late responses 
+ *
+ * Keeping the invite transactions live
+ */
+static void proxy_tr_timeout(struct proxy_tr *t)
+{
+  struct client_tr *c;
+
+  if (t == t->proxy->stateless)
+    return;
+
+  for (c = t->clients; c; c = c->next) {
+    if (c->client && c->status < 300) {
+      nta_outgoing_bind(c->client, proxy_late_response, c);
+      if (c->status < 200) {
+	nta_outgoing_tcancel(c->client, NULL, NULL, TAG_END());
+      }
+    }
+  }
+
+  t->timer = su_timer_create(su_root_task(t->proxy->root), t->proxy->prefs.t1x64);
+  if (su_timer_set(t->timer, proxy_tr_remove_late, t) < 0) {
+    proxy_tr_destroy(t);
+  }
+}
+
 struct proxy_tr *
 proxy_tr_new(struct proxy *proxy)
 {
@@ -1131,6 +1227,8 @@
     su_free(t->proxy->home, c);
   }
 
+  su_timer_destroy(t->timer), t->timer = NULL;
+
   msg_destroy(t->msg);
 
   nta_incoming_destroy(t->server);

Modified: freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.h
==============================================================================
--- freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.h	(original)
+++ freeswitch/trunk/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.h	Fri Mar  7 12:43:21 2008
@@ -46,6 +46,8 @@
 				     url_t const *domain,
 				     tag_type_t, tag_value_t, ...);
 
+void test_proxy_set_logging(struct proxy *, int logging);
+
 void test_proxy_domain_set_expiration(struct domain *,
 				      sip_time_t min_expires, 
 				      sip_time_t expires, 



More information about the Freeswitch-svn mailing list