* 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
This commit is contained in:
parent
8ee7579dda
commit
b5f46db40b
|
@ -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>
|
||||
|
@ -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);
|
||||
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);
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue