Commit b3818f30 authored by jehan's avatar jehan

start io error management for refresher

parent 98196343
......@@ -71,6 +71,34 @@ void belle_sip_auth_event_set_passwd(belle_sip_auth_event_t* event, const char*
const char* belle_sip_auth_event_get_ha1(const belle_sip_auth_event_t* event);
void belle_sip_auth_event_set_ha1(belle_sip_auth_event_t* event, const char* value);
/*Io error event*/
/*
* Give access to the remote host
* @param event object
* @return host value the socket is pointing to
* */
const char* belle_sip_io_error_event_get_host(const belle_sip_io_error_event_t* event);
/*
* Give access to the used transport
* @param event object
* @return host value the socket is pointing to
* */
const char* belle_sip_io_error_event_get_transport(const belle_sip_io_error_event_t* event);
/*
* Give access to the remote port
* @param event object
* @return port value the socket is pointing to
* */
unsigned int belle_sip_io_error_event_port(const belle_sip_io_error_event_t* event);
/*
* Get access to the object involved in this error, can be either belle_sip_dialog_t or belle_sip_transaction_t or belle_sip_provider_t
* @param event
* @return belle_sip_object_t source, use belle_sip_object_is_instance_of to check returns type
* */
belle_sip_object_t* belle_sip_io_error_event_get_source(const belle_sip_io_error_event_t* event);
struct belle_sip_listener_callbacks{
void (*process_dialog_terminated)(void *user_ctx, const belle_sip_dialog_terminated_event_t *event);
......
......@@ -46,5 +46,16 @@ int belle_sip_refresher_start(belle_sip_refresher_t* refresher);
*/
void belle_sip_refresher_stop(belle_sip_refresher_t* refresher);
/**
* Manually initiate a new transaction .
* @param refresher object
* @param expires -1 means value extrated from the transaction
* @return 0 if succeed
*/
int belle_sip_refresher_refresh(belle_sip_refresher_t* refresher,int expires);
/**
* returns current expires value;
*/
int belle_sip_refresher_get_expires(const belle_sip_refresher_t* refresher);
#endif /* REFRESHER_HELPER_H_ */
......@@ -55,6 +55,7 @@ void belle_sip_stack_sleep(belle_sip_stack_t *stack, unsigned int milliseconds);
int belle_sip_stack_get_transport_timeout(const belle_sip_stack_t *stack);
void belle_sip_hop_free(belle_sip_hop_t *hop);
/**
......
......@@ -46,6 +46,13 @@ void belle_sip_server_transaction_send_response(belle_sip_server_transaction_t *
belle_sip_request_t * belle_sip_client_transaction_create_cancel(belle_sip_client_transaction_t *t);
int belle_sip_client_transaction_send_request(belle_sip_client_transaction_t *t);
/*
* Same as #belle_sip_client_transaction_send_request but with a predefined route.
* @param t belle_sip_client_transaction_t
* @param outbound_proxy uri use to directly send the request, useful for outbound proxy.
* */
int belle_sip_client_transaction_send_request_to(belle_sip_client_transaction_t *t,belle_sip_uri_t* outbound_proxy);
/**
* Creates an a sip refresher for transaction like REGISTER/SUBSCRIBE or INVITE which could be refreshed.
* Transaction must in be in stated BELLE_SIP_TRANSACTION_COMPLETED. Refresher is created and started. A ref is taken on object transaction
......
......@@ -450,7 +450,9 @@ struct belle_sip_stack{
int send_error; /* used to simulate network error. if <0, channel_send will return this value*/
};
void belle_sip_stack_get_next_hop(belle_sip_stack_t *stack, belle_sip_request_t *req, belle_sip_hop_t *hop);
belle_sip_hop_t* belle_sip_hop_create(const char* transport, const char* host,int port);
belle_sip_hop_t * belle_sip_stack_create_next_hop(belle_sip_stack_t *stack, belle_sip_request_t *req);
const belle_sip_timer_config_t *belle_sip_stack_get_timer_config(const belle_sip_stack_t *stack);
......@@ -484,6 +486,7 @@ void belle_sip_provider_add_dialog(belle_sip_provider_t *prov, belle_sip_dialog_
void belle_sip_provider_remove_dialog(belle_sip_provider_t *prov, belle_sip_dialog_t *dialog);
void belle_sip_provider_release_channel(belle_sip_provider_t *p, belle_sip_channel_t *chan);
void belle_sip_provider_add_internal_sip_listener(belle_sip_provider_t *p, belle_sip_listener_t *l);
void belle_sip_provider_remove_internal_sip_listener(belle_sip_provider_t *p, belle_sip_listener_t *l);
typedef struct listener_ctx{
belle_sip_listener_t *listener;
......@@ -547,7 +550,7 @@ void belle_sip_transaction_set_dialog(belle_sip_transaction_t *t, belle_sip_dial
struct belle_sip_client_transaction{
belle_sip_transaction_t base;
belle_sip_header_route_t* preset_route; /*use to store first remove route header, will be helpful for refresher*/
belle_sip_uri_t* preset_route; /*use to store outbound proxy, will be helpful for refresher*/
};
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_client_transaction_t,belle_sip_transaction_t)
......@@ -747,10 +750,10 @@ struct belle_sip_dialog_terminated_event{
};
struct belle_sip_io_error_event{
belle_sip_provider_t *source;
belle_sip_object_t *source; /*the object impacted by this error*/
const char *transport;
const char *host;
int port;
unsigned int port;
};
struct belle_sip_request_event{
......
......@@ -68,13 +68,14 @@ static void belle_sip_provider_uninit(belle_sip_provider_t *p){
static void channel_state_changed(belle_sip_channel_listener_t *obj, belle_sip_channel_t *chan, belle_sip_channel_state_t state){
belle_sip_io_error_event_t ev;
belle_sip_provider_t* prov=BELLE_SIP_PROVIDER(obj);
if (state == BELLE_SIP_CHANNEL_ERROR || state == BELLE_SIP_CHANNEL_DISCONNECTED) {
belle_sip_provider_release_channel(ev.source,chan);
ev.transport=belle_sip_channel_get_transport_name(chan);
ev.source=(belle_sip_provider_t*)obj;
ev.source=BELLE_SIP_OBJECT(obj); /*FIXME, must be either trans, dialog or provider, but not only prov */
ev.port=chan->peer_port;
ev.host=chan->peer_name;
BELLE_SIP_PROVIDER_INVOKE_LISTENERS(ev.source->listeners,process_io_error,&ev);
BELLE_SIP_PROVIDER_INVOKE_LISTENERS(prov->listeners,process_io_error,&ev);
belle_sip_provider_release_channel(prov,chan);
}
}
......@@ -493,14 +494,14 @@ void belle_sip_provider_clean_channels(belle_sip_provider_t *p){
}
void belle_sip_provider_send_request(belle_sip_provider_t *p, belle_sip_request_t *req){
belle_sip_hop_t hop={0};
belle_sip_hop_t* hop;
belle_sip_channel_t *chan;
belle_sip_stack_get_next_hop(p->stack,req,&hop);
chan=belle_sip_provider_get_channel(p,hop.host, hop.port, hop.transport);
hop=belle_sip_stack_create_next_hop(p->stack,req);
chan=belle_sip_provider_get_channel(p,hop->host, hop->port, hop->transport);
if (chan) {
belle_sip_channel_queue_message(chan,BELLE_SIP_MESSAGE(req));
}
belle_sip_hop_free(&hop);
belle_sip_hop_free(hop);
}
void belle_sip_provider_send_response(belle_sip_provider_t *p, belle_sip_response_t *resp){
......
......@@ -35,11 +35,25 @@ static void process_dialog_terminated(void *user_ctx, const belle_sip_dialog_ter
/*nop*/
}
static void process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){
belle_sip_fatal("Refresher process_io_error not implemented yet");
belle_sip_refresher_t* refresher=(belle_sip_refresher_t*)user_ctx;
belle_sip_client_transaction_t*client_transaction;
if (belle_sip_object_is_instance_of(BELLE_SIP_OBJECT(belle_sip_io_error_event_get_source(event)),BELLE_SIP_TYPE_ID(belle_sip_client_transaction_t))) {
client_transaction=BELLE_SIP_CLIENT_TRANSACTION(belle_sip_io_error_event_get_source(event));
if (refresher && (client_transaction !=refresher->transaction))
return; /*not for me*/
/*first stop timer if any*/
belle_sip_refresher_stop(refresher);
refresher->listener(refresher,refresher->user_data,503, "io error");
return;
} else {
belle_sip_error("Refresher process_io_error not implemented yet for non transaction source");
}
}
static int set_expires_from_trans(belle_sip_refresher_t* refresher);
static int refresh(belle_sip_refresher_t* refresher);
static int timer_cb(void *user_data, unsigned int events) ;
static void schedule_timer(belle_sip_refresher_t* refresher) {
......@@ -73,7 +87,7 @@ static void process_response_event(void *user_ctx, const belle_sip_response_even
}
case 401:
case 407:{
refresh(refresher); /*authorization is supposed to be available immediately*/
belle_sip_refresher_refresh(refresher,refresher->expires); /*authorization is supposed to be available immediately*/
return;
}
default:
......@@ -91,19 +105,15 @@ static void process_timeout(void *user_ctx, const belle_sip_timeout_event_t *eve
belle_sip_fatal("Unhandled event timeout [%p]",event);
}
static void process_transaction_terminated(void *user_ctx, const belle_sip_transaction_terminated_event_t *event) {
/* belle_sip_client_transaction_t* client_transaction = belle_sip_response_event_get_client_transaction(event);
belle_sip_refresher_t* refresher=(belle_sip_refresher_t*)user_ctx;
if (refresher && (client_transaction !=refresher->transaction))
return;*/ /*not for me*/
belle_sip_fatal("Unhandled transaction terminated [%p]",event);
belle_sip_message("process_transaction_terminated Transaction terminated [%p]",event);
}
static void destroy(belle_sip_refresher_t *refresher){
if (refresher->transaction) belle_sip_object_unref(refresher->transaction);
if (refresher->sip_listener) belle_sip_object_unref(refresher->sip_listener);
belle_sip_provider_remove_internal_sip_listener(refresher->transaction->base.provider,refresher->sip_listener);
belle_sip_object_unref(refresher->transaction);
belle_sip_object_unref(refresher->sip_listener);
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_refresher_t);
BELLE_SIP_INSTANCIATE_VPTR(belle_sip_refresher_t, belle_sip_object_t,destroy, NULL, NULL,FALSE);
......@@ -113,13 +123,18 @@ void belle_sip_refresher_set_listener(belle_sip_refresher_t* refresher, belle_si
refresher->user_data=user_pointer;
}
static int refresh(belle_sip_refresher_t* refresher) {
int belle_sip_refresher_refresh(belle_sip_refresher_t* refresher,int expires) {
belle_sip_request_t*old_request=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(refresher->transaction));
belle_sip_dialog_t* dialog = belle_sip_transaction_get_dialog(BELLE_SIP_TRANSACTION(refresher->transaction));
belle_sip_client_transaction_t* client_transaction;
belle_sip_request_t* request;
belle_sip_header_expires_t* expires_header;
belle_sip_uri_t* preset_route=refresher->transaction->preset_route;
belle_sip_provider_t* prov=refresher->transaction->base.provider;
belle_sip_header_contact_t* contact;
/*first remove timer if any*/
belle_sip_refresher_stop(refresher);
if (!dialog) {
/*create new request*/
request=belle_sip_client_transaction_create_authenticated_request(refresher->transaction);
......@@ -131,7 +146,7 @@ static int refresh(belle_sip_refresher_t* refresher) {
expires_header = belle_sip_header_expires_new();
belle_sip_message_add_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(expires_header));
}
belle_sip_header_expires_set_expires(expires_header,refresher->expires);
}
belle_sip_provider_add_authorization(prov,request,NULL,NULL);
......@@ -142,6 +157,14 @@ static int refresh(belle_sip_refresher_t* refresher) {
,belle_sip_request_get_method(old_request));
return -1;
}
/*update expires in any cases*/
expires_header = belle_sip_message_get_header_by_type(request,belle_sip_header_expires_t);
if (expires_header)
belle_sip_header_expires_set_expires(expires_header,expires);
contact=belle_sip_message_get_header_by_type(request,belle_sip_header_contact_t);
if (belle_sip_header_contact_get_expires(contact)>=0)
belle_sip_header_contact_set_expires(contact,expires);
client_transaction = belle_sip_provider_create_client_transaction(prov,request);
client_transaction->base.is_internal=1;
belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(client_transaction),refresher);
......@@ -150,7 +173,7 @@ static int refresh(belle_sip_refresher_t* refresher) {
refresher->transaction=client_transaction;
belle_sip_object_ref(refresher->transaction);
if (belle_sip_client_transaction_send_request(client_transaction)) {
if (belle_sip_client_transaction_send_request_to(client_transaction,preset_route)) {
belle_sip_error("Cannot send refresh method [%s] for refresher [%p]"
,belle_sip_request_get_method(old_request)
,refresher);
......@@ -159,12 +182,13 @@ static int refresh(belle_sip_refresher_t* refresher) {
return 0;
}
static int timer_cb(void *user_data, unsigned int events) {
belle_sip_refresher_t* refresher = (belle_sip_refresher_t*)user_data;
refresh(refresher);
belle_sip_refresher_refresh(refresher,refresher->expires);
return BELLE_SIP_STOP;
}
/*return 0 if succeeded*/
static belle_sip_header_contact_t* get_matching_contact(const belle_sip_transaction_t* transaction) {
belle_sip_request_t*request=belle_sip_transaction_get_request(transaction);
belle_sip_response_t*response=transaction->last_response;
......@@ -176,7 +200,7 @@ static belle_sip_header_contact_t* get_matching_contact(const belle_sip_transact
/*first fix contact using received/rport*/
belle_sip_response_fix_contact(response,local_contact);
/*FIXME contact may not be fixed by proxy*/
/*now, we have a *NAT* aware contact*/
contact_header_list = belle_sip_message_get_headers(BELLE_SIP_MESSAGE(response),BELLE_SIP_CONTACT);
if (contact_header_list) {
......@@ -190,7 +214,7 @@ static belle_sip_header_contact_t* get_matching_contact(const belle_sip_transact
belle_sip_object_unref(local_contact);
return NULL;
} else {
return BELLE_SIP_HEADER_CONTACT(local_contact);
return BELLE_SIP_HEADER_CONTACT(contact_header_list->data);
}
} else {
return NULL;
......@@ -215,8 +239,6 @@ static int set_expires_from_trans(belle_sip_refresher_t* refresher) {
&& (contact_header=get_matching_contact(transaction))!=NULL){
refresher->expires=belle_sip_header_contact_get_expires(BELLE_SIP_HEADER_CONTACT(contact_header));
/*great, we have an expire param from contact header*/
belle_sip_object_unref(contact_header);
contact_header=NULL;
}
if (refresher->expires==-1){
/*no contact with expire or not relevant, looking for Expires header*/
......@@ -282,3 +304,6 @@ belle_sip_refresher_t* belle_sip_refresher_new(belle_sip_client_transaction_t* t
}
return refresher;
}
int belle_sip_refresher_get_expires(const belle_sip_refresher_t* refresher) {
return refresher->expires;
}
......@@ -46,6 +46,22 @@ belle_sip_dialog_t* belle_sip_dialog_terminated_get_dialog(const belle_sip_dialo
return event->dialog;
}
const char* belle_sip_io_error_event_get_host(const belle_sip_io_error_event_t* event) {
return event->host;
}
const char* belle_sip_io_error_event_get_transport(const belle_sip_io_error_event_t* event) {
return event->transport;
}
unsigned int belle_sip_io_error_event_port(const belle_sip_io_error_event_t* event) {
return event->port;
}
belle_sip_object_t* belle_sip_io_error_event_get_source(const belle_sip_io_error_event_t* event) {
return event->source;
}
typedef struct belle_sip_callbacks belle_sip_callbacks_t;
struct belle_sip_callbacks{
......
......@@ -84,25 +84,25 @@ void belle_sip_stack_sleep(belle_sip_stack_t *stack, unsigned int milliseconds){
belle_sip_main_loop_sleep (stack->ml,milliseconds);
}
void belle_sip_stack_get_next_hop(belle_sip_stack_t *stack, belle_sip_request_t *req, belle_sip_hop_t *hop){
belle_sip_hop_t * belle_sip_stack_create_next_hop(belle_sip_stack_t *stack, belle_sip_request_t *req) {
belle_sip_header_route_t *route=BELLE_SIP_HEADER_ROUTE(belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"route"));
belle_sip_uri_t *uri;
const char *transport;
if (route!=NULL){
uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(route));
}else{
uri=belle_sip_request_get_uri(req);
}
transport=belle_sip_uri_get_transport_param(uri);
if (transport!=NULL) hop->transport=belle_sip_strdup(transport);
else hop->transport=NULL;
hop->host=belle_sip_strdup(belle_sip_uri_get_host(uri));
hop->port=belle_sip_uri_get_listening_port(uri);
if (route){
belle_sip_message_remove_first((belle_sip_message_t*)req,"route");
}
return belle_sip_hop_create( belle_sip_uri_get_transport_param(uri)
,belle_sip_uri_get_host(uri)
,belle_sip_uri_get_listening_port(uri));
}
belle_sip_hop_t* belle_sip_hop_create(const char* transport, const char* host,int port) {
belle_sip_hop_t* hop = belle_sip_new0(belle_sip_hop_t);
if (transport) hop->transport=belle_sip_strdup(transport);
if (host) hop->host=belle_sip_strdup(host);
hop->port=port;
return hop;
}
void belle_sip_hop_free(belle_sip_hop_t *hop){
if (hop->host) {
belle_sip_free(hop->host);
......
......@@ -241,7 +241,11 @@ belle_sip_request_t * belle_sip_client_transaction_create_cancel(belle_sip_clien
int belle_sip_client_transaction_send_request(belle_sip_client_transaction_t *t){
belle_sip_hop_t hop={0};
return belle_sip_client_transaction_send_request_to(t,NULL);
}
int belle_sip_client_transaction_send_request_to(belle_sip_client_transaction_t *t,belle_sip_uri_t* outbound_proxy) {
belle_sip_hop_t* hop;
belle_sip_channel_t *chan;
belle_sip_provider_t *prov=t->base.provider;
......@@ -250,11 +254,17 @@ int belle_sip_client_transaction_send_request(belle_sip_client_transaction_t *t)
return -1;
}
/*store preset route for future use by refresher*/
t->preset_route=BELLE_SIP_HEADER_ROUTE(belle_sip_message_get_header(BELLE_SIP_MESSAGE(t->base.request),"route"));
t->preset_route=outbound_proxy;
if (t->preset_route) belle_sip_object_ref(t->preset_route);
if (outbound_proxy) {
hop=belle_sip_hop_create( belle_sip_uri_get_transport_param(outbound_proxy)
,belle_sip_uri_get_host(outbound_proxy)
,belle_sip_uri_get_listening_port(outbound_proxy));
} else {
hop = belle_sip_stack_create_next_hop(prov->stack,t->base.request);
}
belle_sip_stack_get_next_hop(prov->stack,t->base.request,&hop);
chan=belle_sip_provider_get_channel(prov,hop.host, hop.port, hop.transport);
chan=belle_sip_provider_get_channel(prov,hop->host, hop->port, hop->transport);
if (chan){
belle_sip_provider_add_client_transaction(t->base.provider,t);
belle_sip_object_ref(chan);
......@@ -269,7 +279,7 @@ int belle_sip_client_transaction_send_request(belle_sip_client_transaction_t *t)
BELLE_SIP_OBJECT_VPTR(t,belle_sip_client_transaction_t)->send_request(t);
}
}else belle_sip_error("belle_sip_client_transaction_send_request(): no channel available");
belle_sip_hop_free(&hop);
belle_sip_hop_free(hop);
return 0;
}
......@@ -329,11 +339,20 @@ static void client_transaction_destroy(belle_sip_client_transaction_t *t ){
static void on_channel_state_changed(belle_sip_channel_listener_t *l, belle_sip_channel_t *chan, belle_sip_channel_state_t state){
belle_sip_client_transaction_t *t=(belle_sip_client_transaction_t*)l;
belle_sip_io_error_event_t ev;
belle_sip_message("transaction on_channel_state_changed");
switch(state){
case BELLE_SIP_CHANNEL_READY:
BELLE_SIP_OBJECT_VPTR(t,belle_sip_client_transaction_t)->send_request(t);
break;
case BELLE_SIP_CHANNEL_DISCONNECTED:
case BELLE_SIP_CHANNEL_ERROR:
ev.transport=belle_sip_channel_get_transport_name(chan);
ev.source=BELLE_SIP_OBJECT(t);
ev.port=chan->peer_port;
ev.host=chan->peer_name;
BELLE_SIP_PROVIDER_INVOKE_LISTENERS_FOR_TRANSACTION(((belle_sip_transaction_t*)t),process_io_error,&ev);
break;
default:
/*ignored*/
break;
......@@ -390,8 +409,9 @@ belle_sip_request_t* belle_sip_client_transaction_create_authenticated_request(b
belle_sip_request_t* req=BELLE_SIP_REQUEST(belle_sip_object_clone(BELLE_SIP_OBJECT(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(t)))));
belle_sip_header_cseq_t* cseq=belle_sip_message_get_header_by_type(req,belle_sip_header_cseq_t);
belle_sip_header_cseq_set_seq_number(cseq,belle_sip_header_cseq_get_seq_number(cseq)+1);
if (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(t)) != BELLE_SIP_TRANSACTION_COMPLETED) {
belle_sip_error("Invalid state [%s] for transaction [%p], should be BELLE_SIP_TRANSACTION_COMPLETED"
if (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(t)) != BELLE_SIP_TRANSACTION_COMPLETED
&& belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(t)) != BELLE_SIP_TRANSACTION_TERMINATED) {
belle_sip_error("Invalid state [%s] for transaction [%p], should be BELLE_SIP_TRANSACTION_COMPLETED|BELLE_SIP_TRANSACTION_TERMINATED"
,belle_sip_transaction_state_to_string(belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(t)))
,t);
return NULL;
......@@ -399,10 +419,7 @@ belle_sip_request_t* belle_sip_client_transaction_create_authenticated_request(b
/*remove auth headers*/
belle_sip_message_remove_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_AUTHORIZATION);
belle_sip_message_remove_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_PROXY_AUTHORIZATION);
/*add preset route if any*/
if (t->preset_route) {
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(t->preset_route));
}
/*put auth header*/
belle_sip_provider_add_authorization(t->base.provider,req,t->base.last_response,NULL);
return req;
......
......@@ -47,6 +47,8 @@ typedef struct endpoint {
unsigned char expire_in_contact;
char nonce[32];
unsigned int nonce_count;
const char* received;
int rport;
} endpoint_t;
static unsigned int wait_for(belle_sip_stack_t*s1, belle_sip_stack_t*s2,int* counter,int value,int timeout) {
......@@ -104,6 +106,7 @@ static void server_process_request_event(void *obj, const belle_sip_request_even
belle_sip_header_contact_t* contact;
belle_sip_header_expires_t* expires;
belle_sip_header_authorization_t* authorization;
belle_sip_header_via_t* via;
const char* raw_authenticate_digest = "WWW-Authenticate: Digest "
"algorithm=MD5, realm=\"" SIPDOMAIN "\", opaque=\"1bc7f9097684320\"";
......@@ -185,6 +188,10 @@ static void server_process_request_event(void *obj, const belle_sip_request_even
if (www_authenticate)
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);
}
belle_sip_server_transaction_send_response(server_transaction,resp);
}
static void client_process_response_event(void *obj, const belle_sip_response_event_t *event){
......@@ -319,6 +326,9 @@ static void register_test_with_param(unsigned char expire_in_contact,auth_mode_t
gettimeofday(&end, NULL);
CU_ASSERT_TRUE(end.tv_sec-begin.tv_sec>=3);
CU_ASSERT_TRUE(end.tv_sec-begin.tv_sec<5);
/*unregister*/
belle_sip_refresher_refresh(refresher,0);
CU_ASSERT_TRUE(wait_for(server->stack,client->stack,&client->stat.refreshOk,4,1000));
belle_sip_refresher_stop(refresher);
belle_sip_object_unref(refresher);
destroy_endpoint(client);
......
......@@ -167,6 +167,7 @@ belle_sip_request_t* try_register_user_at_domain(belle_sip_stack_t * stack
,int use_transaction
,const char* username
,const char* domain
,const char* outband
,int success_expected) {
belle_sip_request_t *req,*copy;
char identity[256];
......@@ -199,13 +200,13 @@ belle_sip_request_t* try_register_user_at_domain(belle_sip_stack_t * stack
belle_sip_provider_add_sip_listener(prov,l=BELLE_SIP_LISTENER(listener));
if (use_transaction){
belle_sip_client_transaction_t *t=belle_sip_provider_create_client_transaction(prov,req);
belle_sip_client_transaction_send_request(t);
belle_sip_client_transaction_send_request_to(t,outband?belle_sip_uri_parse(outband):NULL);
}else belle_sip_provider_send_request(prov,req);
int i;
for(i=0;!is_register_ok && i<2 ;i++)
belle_sip_stack_sleep(stack,5000);
CU_ASSERT_EQUAL(is_register_ok,success_expected);
CU_ASSERT_EQUAL(using_transaction,use_transaction);
if (success_expected) CU_ASSERT_EQUAL(using_transaction,use_transaction);
belle_sip_provider_remove_sip_listener(prov,l);
......@@ -216,27 +217,31 @@ belle_sip_request_t* register_user_at_domain(belle_sip_stack_t * stack
,const char *transport
,int use_transaction
,const char* username
,const char* domain) {
return try_register_user_at_domain(stack,prov,transport,use_transaction,username,domain,1);
,const char* domain
,const char* outband) {
return try_register_user_at_domain(stack,prov,transport,use_transaction,username,domain,outband,1);
}
belle_sip_request_t* register_user(belle_sip_stack_t * stack
,belle_sip_provider_t *prov
,const char *transport
,int use_transaction
,const char* username) {
return register_user_at_domain(stack,prov,transport,use_transaction,username,test_domain);
,const char* username
,const char* outband) {
return register_user_at_domain(stack,prov,transport,use_transaction,username,test_domain,outband);
}
static void register_test(const char *transport, int use_transaction) {
static void register_with_outband(const char *transport, int use_transaction,const char* outband ) {
belle_sip_request_t *req;
req=register_user(stack, prov, transport,use_transaction,"tester");
req=register_user(stack, prov, transport,use_transaction,"tester",outband);
if (req) {
unregister_user(stack,prov,req,use_transaction);
belle_sip_object_unref(req);
}
}
static void register_test(const char *transport, int use_transaction) {
register_with_outband(transport,use_transaction,NULL);
}
static void stateless_register_udp(void){
register_test(NULL,0);
}
......@@ -253,6 +258,10 @@ static void stateful_register_udp(void){
register_test(NULL,1);
}
static void stateful_register_udp_with_outband_proxy(void){
register_with_outband("udp",1,test_domain);
}
static void stateful_register_udp_delayed(void){
belle_sip_stack_set_tx_delay(stack,3000);
register_test(NULL,1);
......@@ -261,8 +270,7 @@ static void stateful_register_udp_delayed(void){
static void stateful_register_udp_with_send_error(void){
belle_sip_stack_set_send_error(stack,-1);
belle_sip_request_t *req;
try_register_user(stack, prov, NULL,1,"tester",0);
try_register_user_at_domain(stack, prov, NULL,1,"tester",test_domain,NULL,0);
belle_sip_stack_set_send_error(stack,0);
}
......@@ -322,7 +330,7 @@ static void test_register_authenticate() {
belle_sip_request_t *reg;
number_of_challenge=0;
authorized_request=NULL;
reg=register_user_at_domain(stack, prov, "udp",1,"bellesip",auth_domain);
reg=register_user_at_domain(stack, prov, "udp",1,"bellesip",auth_domain,NULL);
if (authorized_request) {
unregister_user(stack,prov,authorized_request,1);
belle_sip_object_unref(authorized_request);
......@@ -363,6 +371,9 @@ int belle_sip_register_test_suite(){
if (NULL == CU_add_test(pSuite, "stateful_register_udp_with_send_error", stateful_register_udp_with_send_error)) {
return CU_get_error();
}
if (NULL == CU_add_test(pSuite, "stateful_register_udp_with_outband_proxy", stateful_register_udp_with_outband_proxy)) {
return CU_get_error();
}
return 0;
}
......
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