]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
* test_proxy: trying to support 200 OK retransmissions over TCP better
authorMichael Jerris <mike@jerris.com>
Fri, 7 Mar 2008 17:43:21 +0000 (17:43 +0000)
committerMichael Jerris <mike@jerris.com>
Fri, 7 Mar 2008 17:43:21 +0000 (17:43 +0000)
  Keeping INVITE transactions alive for 64*T1 after initial 200 OK.

  Added test_proxy_set_logging() for easier debugging.

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

libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.c
libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.h

index 1543811c2a58a46221a44f1886410b62446255fc..3d27627434456b8c5742406d8f65f2c08ca3914b 100644 (file)
@@ -46,6 +46,7 @@ struct binding;
 #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 @@ struct binding;
 
 #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 {
 
   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 @@ static int binding_is_active(struct binding const *b)
 
 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 @@ test_proxy_init(su_root_t *root, struct proxy *proxy)
                                  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 @@ test_proxy_init(su_root_t *root, struct proxy *proxy)
 
   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 @@ char const *test_proxy_route_uri(struct proxy const *p,
   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 @@ int proxy_response(struct client_tr *c,
                   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 @@ void proxy_tr_destroy(struct proxy_tr *t)
     su_free(t->proxy->home, c);
   }
 
+  su_timer_destroy(t->timer), t->timer = NULL;
+
   msg_destroy(t->msg);
 
   nta_incoming_destroy(t->server);
index 40dc50b2f1c7b8c20bad70d8826b8a9a7f702cbd..7174cc1bd27e52caa39f4e64861cd04cf785f0d1 100644 (file)
@@ -46,6 +46,8 @@ struct domain *test_proxy_add_domain(struct proxy *,
                                     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,