Commit e7668f38 authored by DanmeiChen's avatar DanmeiChen

add retry-after in refresher test

parent a4b077ae
......@@ -213,7 +213,10 @@ static void process_response_event(belle_sip_listener_t *user_ctx, const belle_s
int response_code = belle_sip_response_get_status_code(response);
belle_sip_refresher_t* refresher=(belle_sip_refresher_t*)user_ctx;
belle_sip_header_contact_t *contact;
belle_sip_header_retry_after_t *retry_after_header;
int will_retry = TRUE; /*most error codes are retryable*/
retry_after_header = belle_sip_message_get_header_by_type(response,belle_sip_header_retry_after_t);
int retry_after_time = retry_after_header ? belle_sip_header_retry_after_get_retry_after(retry_after_header):0;
if (refresher && (client_transaction !=refresher->transaction))
......@@ -341,6 +344,15 @@ static void process_response_event(belle_sip_listener_t *user_ctx, const belle_s
}
}
BCTBX_NO_BREAK; /*intentionally no break*/
case 404:
case 480:
case 500: {
if (refresher->target_expires>0) {
schedule_timer_at(refresher, retry_after_time * 1000, RETRY);
return; /*do not notify this kind of error*/
}
}
BCTBX_NO_BREAK; /*intentionally no break*/
case 505:
case 501:
/*irrecoverable errors, probably no need to retry later*/
......
......@@ -88,6 +88,7 @@ typedef struct endpoint {
bool_t bad_next_nonce;
const char *algo;
const char *ha1;
int retry_after;
} endpoint_t;
......@@ -174,6 +175,7 @@ static void server_process_request_event(void *obj, const belle_sip_request_even
belle_sip_header_www_authenticate_t *www_authenticate = NULL;
belle_sip_header_www_authenticate_t *two_www_authenticate = NULL;
belle_sip_header_retry_after_t *retry_after_header = NULL;
const char *auth_uri;
const char *qop;
unsigned char auth_ok = 0;
......@@ -183,6 +185,24 @@ static void server_process_request_event(void *obj, const belle_sip_request_even
belle_sip_message("caller_process_request_event received [%s] message", belle_sip_request_get_method(belle_sip_request_event_get_request(event)));
if (endpoint->retry_after) {
unsigned int response_code;
response_code = 404;
resp = belle_sip_response_create_from_request(belle_sip_request_event_get_request(event), response_code);
if (www_authenticate) {
if ((endpoint->algo != NULL) && (!strcmp(endpoint->algo, "MD_SHA"))) {
two_www_authenticate = BELLE_SIP_HEADER_WWW_AUTHENTICATE(belle_sip_object_clone(BELLE_SIP_OBJECT(www_authenticate)));
belle_sip_header_www_authenticate_set_algorithm(two_www_authenticate, algo_ref);
belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp), BELLE_SIP_HEADER(two_www_authenticate));
}
belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp), BELLE_SIP_HEADER(www_authenticate));
}
retry_after_header = BELLE_SIP_HEADER_RETRY_AFTER(belle_sip_header_retry_after_create(endpoint->retry_after));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp), BELLE_SIP_HEADER(retry_after_header));
endpoint->retry_after = 0;
} else {
switch (endpoint->auth) {
case none: {
auth_ok = 1;
......@@ -328,6 +348,8 @@ static void server_process_request_event(void *obj, const belle_sip_request_even
belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp), BELLE_SIP_HEADER(www_authenticate));
}
}
}
if (endpoint->received) {
via = belle_sip_message_get_header_by_type(req, belle_sip_header_via_t);
belle_sip_header_via_set_received(via, endpoint->received);
......@@ -442,6 +464,7 @@ static endpoint_t* create_endpoint(const char *ip, int port,const char* transpor
sprintf(endpoint->nonce,"%p",endpoint); /*initial nonce*/
endpoint->nonce_count=1;
endpoint->register_count=3;
endpoint->retry_after=0;
return endpoint;
}
......@@ -542,12 +565,13 @@ static belle_sip_refresher_t* refresher_base_with_body2( endpoint_t* client
if (BC_ASSERT_PTR_NOT_NULL(refresher)) {
belle_sip_object_unref(trans);
belle_sip_refresher_set_listener(refresher,belle_sip_refresher_listener,client);
int timeout = client->retry_after + client->register_count;
begin = belle_sip_time_ms();
BC_ASSERT_TRUE(wait_for(server->stack,client->stack,&client->stat.refreshOk,client->register_count+(client->early_refresher?1:0),client->register_count*1000 + 1000));
BC_ASSERT_TRUE(wait_for(server->stack,client->stack,&client->stat.refreshOk,client->register_count+(client->early_refresher?1:0), timeout*1000 + 1000));
end = belle_sip_time_ms();
BC_ASSERT_GREATER((long double)(end-begin),(client->register_count/number_active_refresher)*1000*.9,long double,"%Lf"); /*because refresh is at 90% of expire*/
BC_ASSERT_LOWER_STRICT(end-begin,(client->register_count*1000 + 2000),unsigned long long,"%llu");
BC_ASSERT_LOWER_STRICT(end-begin,(timeout*1000 + 2000),unsigned long long,"%llu");
}
return refresher;
}
......@@ -886,6 +910,27 @@ static void register_early_refresher(void) {
destroy_endpoint(server);
}
static void register_retry_after(void) {
belle_sip_listener_callbacks_t client_callbacks;
belle_sip_listener_callbacks_t server_callbacks;
endpoint_t* client,*server;
memset(&client_callbacks,0,sizeof(belle_sip_listener_callbacks_t));
memset(&server_callbacks,0,sizeof(belle_sip_listener_callbacks_t));
client_callbacks.process_response_event=client_process_response_event;
client_callbacks.process_auth_requested=client_process_auth_requested;
server_callbacks.process_request_event=server_process_request_event;
client = create_udp_endpoint(3452,&client_callbacks);
server = create_udp_endpoint(6788,&server_callbacks);
server->expire_in_contact=1;
server->auth=digest;
client->early_refresher=1;
server->retry_after = 2;
client->retry_after = 2;
register_base(client,server);
destroy_endpoint(client);
destroy_endpoint(server);
}
static int register_test_with_interfaces(const char *transport, const char *client_ip, const char *server_ip, int connection_family) {
int ret=0;
belle_sip_listener_callbacks_t client_callbacks;
......@@ -1124,6 +1169,7 @@ test_t refresher_tests[] = {
TEST_NO_TAG("REGISTER Expires in Contact digest auth MD_SHA-256 ha1", register_expires_in_contact_header_digest_md_sha256_ha1),
TEST_NO_TAG("REGISTER with failure", register_with_failure),
TEST_NO_TAG("REGISTER with early refresher", register_early_refresher),
TEST_NO_TAG("REGISTER with retry after", register_retry_after),
TEST_NO_TAG("SUBSCRIBE", subscribe_test),
TEST_NO_TAG("SUBSCRIBE of list" , subscribe_list_test),
TEST_NO_TAG("PUBLISH", simple_publish),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment