From b5f46db40b6e986e590d5e736189c61b7c95d07b Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Fri, 7 Mar 2008 17:43:21 +0000 Subject: [PATCH] * 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. git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7819 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- .../libsofia-sip-ua/nua/test_proxy.c | 138 +++++++++++++++--- .../libsofia-sip-ua/nua/test_proxy.h | 2 + 2 files changed, 120 insertions(+), 20 deletions(-) diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.c b/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.c index 1543811c2a..3d27627434 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.c @@ -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 #include @@ -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); diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.h b/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.h index 40dc50b2f1..7174cc1bd2 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.h +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_proxy.h @@ -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,