Commit 298277a4 authored by Simon Morlat's avatar Simon Morlat
Browse files

fix transaction memory leaks, implement loose routing

parent 67e1d559
...@@ -27,6 +27,7 @@ typedef struct _belle_sip_list belle_sip_list_t; ...@@ -27,6 +27,7 @@ typedef struct _belle_sip_list belle_sip_list_t;
belle_sip_list_t * belle_sip_list_append(belle_sip_list_t * elem, void * data); belle_sip_list_t * belle_sip_list_append(belle_sip_list_t * elem, void * data);
belle_sip_list_t * belle_sip_list_prepend(belle_sip_list_t * elem, void * data); belle_sip_list_t * belle_sip_list_prepend(belle_sip_list_t * elem, void * data);
belle_sip_list_t * belle_sip_list_last_elem(const belle_sip_list_t *l);
belle_sip_list_t * belle_sip_list_free(belle_sip_list_t * elem); belle_sip_list_t * belle_sip_list_free(belle_sip_list_t * elem);
belle_sip_list_t * belle_sip_list_concat(belle_sip_list_t * first, belle_sip_list_t * second); belle_sip_list_t * belle_sip_list_concat(belle_sip_list_t * first, belle_sip_list_t * second);
belle_sip_list_t * belle_sip_list_remove(belle_sip_list_t * first, void *data); belle_sip_list_t * belle_sip_list_remove(belle_sip_list_t * first, void *data);
......
...@@ -73,6 +73,12 @@ void belle_sip_message_add_headers(belle_sip_message_t *message, const belle_sip ...@@ -73,6 +73,12 @@ void belle_sip_message_add_headers(belle_sip_message_t *message, const belle_sip
void belle_sip_message_set_header(belle_sip_message_t *msg, belle_sip_header_t* header); void belle_sip_message_set_header(belle_sip_message_t *msg, belle_sip_header_t* header);
void belle_sip_message_remove_first(belle_sip_message_t *msg, const char *header_name);
void belle_sip_message_remove_last(belle_sip_message_t *msg, const char *header_name);
void belle_sip_message_remove_header(belle_sip_message_t *msg, const char *header_name);
char *belle_sip_message_to_string(belle_sip_message_t *msg); char *belle_sip_message_to_string(belle_sip_message_t *msg);
const char* belle_sip_message_get_body(belle_sip_message_t *msg); const char* belle_sip_message_get_body(belle_sip_message_t *msg);
void belle_sip_message_set_body(belle_sip_message_t *msg,char* body,unsigned int size); void belle_sip_message_set_body(belle_sip_message_t *msg,char* body,unsigned int size);
......
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
#define belle_sip_stack_h #define belle_sip_stack_h
struct belle_sip_hop{ struct belle_sip_hop{
const char *host; char *host;
const char *transport; char *transport;
int port; int port;
}; };
...@@ -53,6 +53,8 @@ void belle_sip_stack_main(belle_sip_stack_t *stack); ...@@ -53,6 +53,8 @@ void belle_sip_stack_main(belle_sip_stack_t *stack);
void belle_sip_stack_sleep(belle_sip_stack_t *stack, unsigned int milliseconds); void belle_sip_stack_sleep(belle_sip_stack_t *stack, unsigned int milliseconds);
void belle_sip_hop_free(belle_sip_hop_t *hop);
BELLE_SIP_END_DECLS BELLE_SIP_END_DECLS
#endif #endif
......
...@@ -119,7 +119,7 @@ int belle_sip_header_address_marshal(belle_sip_header_address_t* header, char* b ...@@ -119,7 +119,7 @@ int belle_sip_header_address_marshal(belle_sip_header_address_t* header, char* b
return current_offset-offset; return current_offset-offset;
} }
BELLE_SIP_NEW(header_address,parameters) BELLE_SIP_NEW_HEADER(header_address,parameters,"header_address")
BELLE_SIP_PARSE(header_address) BELLE_SIP_PARSE(header_address)
GET_SET_STRING(belle_sip_header_address,displayname); GET_SET_STRING(belle_sip_header_address,displayname);
......
...@@ -381,7 +381,21 @@ belle_sip_##object_type##_t* belle_sip_##object_type##_parse (const char* value) ...@@ -381,7 +381,21 @@ belle_sip_##object_type##_t* belle_sip_##object_type##_parse (const char* value)
return l_parsed_object;\ return l_parsed_object;\
} }
#define BELLE_SIP_NEW(object_type,super_type) BELLE_SIP_NEW_HEADER(object_type,super_type,NULL) #define BELLE_SIP_NEW(object_type,super_type) \
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_##object_type##_t); \
BELLE_SIP_INSTANCIATE_VPTR( belle_sip_##object_type##_t\
, belle_sip_##super_type##_t\
, belle_sip_##object_type##_destroy\
, belle_sip_##object_type##_clone\
, belle_sip_##object_type##_marshal, FALSE); \
belle_sip_##object_type##_t* belle_sip_##object_type##_new () { \
belle_sip_##object_type##_t* l_object = belle_sip_object_new(belle_sip_##object_type##_t);\
belle_sip_##super_type##_init((belle_sip_##super_type##_t*)l_object); \
belle_sip_##object_type##_init((belle_sip_##object_type##_t*) l_object); \
return l_object;\
}
#define BELLE_SIP_NEW_HEADER(object_type,super_type,name) BELLE_SIP_NEW_HEADER_INIT(object_type,super_type,name,header) #define BELLE_SIP_NEW_HEADER(object_type,super_type,name) BELLE_SIP_NEW_HEADER_INIT(object_type,super_type,name,header)
#define BELLE_SIP_NEW_HEADER_INIT(object_type,super_type,name,init_type) \ #define BELLE_SIP_NEW_HEADER_INIT(object_type,super_type,name,init_type) \
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_##object_type##_t); \ BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_##object_type##_t); \
......
...@@ -48,7 +48,7 @@ int belle_sip_parameters_marshal(belle_sip_parameters_t* params, char* buff,unsi ...@@ -48,7 +48,7 @@ int belle_sip_parameters_marshal(belle_sip_parameters_t* params, char* buff,unsi
} }
return curent_offset-offset; return curent_offset-offset;
} }
BELLE_SIP_NEW(parameters,header) BELLE_SIP_NEW_HEADER(parameters,header,"parameters")
const belle_sip_list_t * belle_sip_parameters_get_parameters(belle_sip_parameters_t* obj) { const belle_sip_list_t * belle_sip_parameters_get_parameters(belle_sip_parameters_t* obj) {
return obj->param_list; return obj->param_list;
} }
......
...@@ -185,6 +185,13 @@ belle_sip_list_t* belle_sip_list_prepend(belle_sip_list_t* elem, void *data){ ...@@ -185,6 +185,13 @@ belle_sip_list_t* belle_sip_list_prepend(belle_sip_list_t* elem, void *data){
return new_elem; return new_elem;
} }
belle_sip_list_t * belle_sip_list_last_elem(const belle_sip_list_t *l){
if (l==NULL) return NULL;
while(l->next){
l=l->next;
}
return (belle_sip_list_t*)l;
}
belle_sip_list_t* belle_sip_list_concat(belle_sip_list_t* first, belle_sip_list_t* second){ belle_sip_list_t* belle_sip_list_concat(belle_sip_list_t* first, belle_sip_list_t* second){
belle_sip_list_t* it=first; belle_sip_list_t* it=first;
......
...@@ -89,7 +89,7 @@ static int get_message_start_pos(char *buff, size_t bufflen) { ...@@ -89,7 +89,7 @@ static int get_message_start_pos(char *buff, size_t bufflen) {
} }
if (res==1) return i; if (res==1) return i;
else { else {
res=sscanf(buff+i,"%16s %*s SIP/2.0 ",(char*)&method); res=sscanf(buff+i,"%16s %*s SIP/2.0 ",method);
} }
} }
return -1; return -1;
......
...@@ -163,7 +163,7 @@ BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(belle_sip_ict_t)={ ...@@ -163,7 +163,7 @@ BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(belle_sip_ict_t)={
{ {
{ {
{ {
BELLE_SIP_VPTR_INIT(belle_sip_ict_t,belle_sip_client_transaction_t,FALSE), BELLE_SIP_VPTR_INIT(belle_sip_ict_t,belle_sip_client_transaction_t,TRUE),
(belle_sip_object_destroy_t)ict_destroy, (belle_sip_object_destroy_t)ict_destroy,
NULL, NULL,
NULL NULL
......
...@@ -37,7 +37,7 @@ BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(belle_sip_ist_t)={ ...@@ -37,7 +37,7 @@ BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(belle_sip_ist_t)={
{ {
{ {
{ {
BELLE_SIP_VPTR_INIT(belle_sip_ist_t,belle_sip_server_transaction_t,FALSE), BELLE_SIP_VPTR_INIT(belle_sip_ist_t,belle_sip_server_transaction_t,TRUE),
(belle_sip_object_destroy_t)ist_destroy, (belle_sip_object_destroy_t)ist_destroy,
NULL, NULL,
NULL NULL
......
...@@ -140,6 +140,33 @@ const belle_sip_list_t* belle_sip_message_get_headers(belle_sip_message_t *messa ...@@ -140,6 +140,33 @@ const belle_sip_list_t* belle_sip_message_get_headers(belle_sip_message_t *messa
return headers_container ? headers_container->header_list:NULL; return headers_container ? headers_container->header_list:NULL;
} }
void belle_sip_message_remove_first(belle_sip_message_t *msg, const char *header_name){
headers_container_t* headers_container = belle_sip_headers_container_get(msg,header_name);
if (headers_container && headers_container->header_list){
belle_sip_list_t *to_be_removed=headers_container->header_list;
headers_container->header_list=belle_sip_list_remove_link(headers_container->header_list,to_be_removed);
belle_sip_list_free_with_data(to_be_removed,belle_sip_object_unref);
}
}
void belle_sip_message_remove_last(belle_sip_message_t *msg, const char *header_name){
headers_container_t* headers_container = belle_sip_headers_container_get(msg,header_name);
if (headers_container && headers_container->header_list){
belle_sip_list_t *to_be_removed=belle_sip_list_last_elem(headers_container->header_list);
headers_container->header_list=belle_sip_list_remove_link(headers_container->header_list,to_be_removed);
belle_sip_list_free_with_data(to_be_removed,belle_sip_object_unref);
}
}
void belle_sip_message_remove_header(belle_sip_message_t *msg, const char *header_name){
headers_container_t* headers_container = belle_sip_headers_container_get(msg,header_name);
if (headers_container){
belle_sip_headers_container_delete(headers_container);
belle_sip_list_remove(msg->header_list,headers_container);
}
}
/* /*
int belle_sip_message_named_headers_marshal(belle_sip_message_t *message, const char* header_name, char* buff,unsigned int offset,unsigned int buff_size) { int belle_sip_message_named_headers_marshal(belle_sip_message_t *message, const char* header_name, char* buff,unsigned int offset,unsigned int buff_size) {
unsigned int current_offset=offset; unsigned int current_offset=offset;
...@@ -192,6 +219,9 @@ static void belle_sip_request_destroy(belle_sip_request_t* request) { ...@@ -192,6 +219,9 @@ static void belle_sip_request_destroy(belle_sip_request_t* request) {
if (request->uri) belle_sip_object_unref(request->uri); if (request->uri) belle_sip_object_unref(request->uri);
} }
static void belle_sip_request_init(belle_sip_request_t *message){
}
static void belle_sip_request_clone(belle_sip_request_t *request, const belle_sip_request_t *orig){ static void belle_sip_request_clone(belle_sip_request_t *request, const belle_sip_request_t *orig){
if (orig->method) request->method=belle_sip_strdup(orig->method); if (orig->method) request->method=belle_sip_strdup(orig->method);
} }
...@@ -206,6 +236,7 @@ int belle_sip_request_marshal(belle_sip_request_t* request, char* buff,unsigned ...@@ -206,6 +236,7 @@ int belle_sip_request_marshal(belle_sip_request_t* request, char* buff,unsigned
} }
return current_offset-offset; return current_offset-offset;
} }
BELLE_SIP_NEW(request,message) BELLE_SIP_NEW(request,message)
BELLE_SIP_PARSE(request) BELLE_SIP_PARSE(request)
GET_SET_STRING(belle_sip_request,method); GET_SET_STRING(belle_sip_request,method);
...@@ -240,9 +271,11 @@ belle_sip_header_t *belle_sip_message_get_header(belle_sip_message_t *msg, const ...@@ -240,9 +271,11 @@ belle_sip_header_t *belle_sip_message_get_header(belle_sip_message_t *msg, const
char *belle_sip_message_to_string(belle_sip_message_t *msg){ char *belle_sip_message_to_string(belle_sip_message_t *msg){
return belle_sip_object_to_string(BELLE_SIP_OBJECT(msg)); return belle_sip_object_to_string(BELLE_SIP_OBJECT(msg));
} }
const char* belle_sip_message_get_body(belle_sip_message_t *msg) { const char* belle_sip_message_get_body(belle_sip_message_t *msg) {
return msg->body; return msg->body;
} }
void belle_sip_message_set_body(belle_sip_message_t *msg,char* body,unsigned int size) { void belle_sip_message_set_body(belle_sip_message_t *msg,char* body,unsigned int size) {
if (msg->body) { if (msg->body) {
belle_sip_free((void*)body); belle_sip_free((void*)body);
...@@ -333,6 +366,9 @@ void belle_sip_response_destroy(belle_sip_response_t *resp){ ...@@ -333,6 +366,9 @@ void belle_sip_response_destroy(belle_sip_response_t *resp){
if (resp->reason_phrase) belle_sip_free(resp->reason_phrase); if (resp->reason_phrase) belle_sip_free(resp->reason_phrase);
} }
static void belle_sip_response_init(belle_sip_response_t *resp){
}
static void belle_sip_response_clone(belle_sip_response_t *resp, const belle_sip_response_t *orig){ static void belle_sip_response_clone(belle_sip_response_t *resp, const belle_sip_response_t *orig){
if (orig->sip_version) resp->sip_version=belle_sip_strdup(orig->sip_version); if (orig->sip_version) resp->sip_version=belle_sip_strdup(orig->sip_version);
if (orig->reason_phrase) resp->reason_phrase=belle_sip_strdup(orig->reason_phrase); if (orig->reason_phrase) resp->reason_phrase=belle_sip_strdup(orig->reason_phrase);
...@@ -400,14 +436,14 @@ belle_sip_response_t *belle_sip_response_new_from_request(belle_sip_request_t *r ...@@ -400,14 +436,14 @@ belle_sip_response_t *belle_sip_response_new_from_request(belle_sip_request_t *r
return resp; return resp;
} }
void belle_sip_response_get_return_hop(belle_sip_response_t *msg, belle_sip_hop_t *hop){ void belle_sip_response_get_return_hop(belle_sip_response_t *msg, belle_sip_hop_t *hop){
belle_sip_header_via_t *via=BELLE_SIP_HEADER_VIA(belle_sip_message_get_header(BELLE_SIP_MESSAGE(msg),"via")); belle_sip_header_via_t *via=BELLE_SIP_HEADER_VIA(belle_sip_message_get_header(BELLE_SIP_MESSAGE(msg),"via"));
hop->transport=belle_sip_header_via_get_protocol(via); const char *host;
hop->host=belle_sip_header_via_get_received(via); hop->transport=belle_sip_strdup(belle_sip_header_via_get_protocol(via));
if (hop->host==NULL) host=belle_sip_header_via_get_received(via);
hop->host=belle_sip_header_via_get_host(via); if (host==NULL)
host=belle_sip_header_via_get_host(via);
hop->host=belle_sip_strdup(host);
hop->port=belle_sip_header_via_get_rport(via); hop->port=belle_sip_header_via_get_rport(via);
if (hop->port==-1) if (hop->port==-1)
hop->port=belle_sip_header_via_get_listening_port(via); hop->port=belle_sip_header_via_get_listening_port(via);
......
...@@ -146,7 +146,7 @@ BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(belle_sip_nict_t)={ ...@@ -146,7 +146,7 @@ BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(belle_sip_nict_t)={
{ {
{ {
{ {
BELLE_SIP_VPTR_INIT(belle_sip_nict_t,belle_sip_client_transaction_t,FALSE), BELLE_SIP_VPTR_INIT(belle_sip_nict_t,belle_sip_client_transaction_t,TRUE),
(belle_sip_object_destroy_t)nict_destroy, (belle_sip_object_destroy_t)nict_destroy,
NULL, NULL,
NULL NULL
......
...@@ -98,7 +98,7 @@ BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(belle_sip_nist_t)={ ...@@ -98,7 +98,7 @@ BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(belle_sip_nist_t)={
{ {
{ {
{ {
BELLE_SIP_VPTR_INIT(belle_sip_nist_t,belle_sip_server_transaction_t,FALSE), BELLE_SIP_VPTR_INIT(belle_sip_nist_t,belle_sip_server_transaction_t,TRUE),
(belle_sip_object_destroy_t)nist_destroy, (belle_sip_object_destroy_t)nist_destroy,
NULL, NULL,
NULL NULL
......
...@@ -253,6 +253,9 @@ belle_sip_channel_t * belle_sip_provider_get_channel(belle_sip_provider_t *p, co ...@@ -253,6 +253,9 @@ belle_sip_channel_t * belle_sip_provider_get_channel(belle_sip_provider_t *p, co
belle_sip_list_t *l; belle_sip_list_t *l;
belle_sip_listening_point_t *candidate=NULL,*lp; belle_sip_listening_point_t *candidate=NULL,*lp;
belle_sip_channel_t *chan; belle_sip_channel_t *chan;
if (transport==NULL) transport="UDP";
for(l=p->lps;l!=NULL;l=l->next){ for(l=p->lps;l!=NULL;l=l->next){
lp=(belle_sip_listening_point_t*)l->data; lp=(belle_sip_listening_point_t*)l->data;
if (strcasecmp(belle_sip_listening_point_get_transport(lp),transport)==0){ if (strcasecmp(belle_sip_listening_point_get_transport(lp),transport)==0){
...@@ -279,6 +282,7 @@ void belle_sip_provider_send_request(belle_sip_provider_t *p, belle_sip_request_ ...@@ -279,6 +282,7 @@ void belle_sip_provider_send_request(belle_sip_provider_t *p, belle_sip_request_
if (chan) { if (chan) {
belle_sip_channel_queue_message(chan,BELLE_SIP_MESSAGE(req)); belle_sip_channel_queue_message(chan,BELLE_SIP_MESSAGE(req));
} }
belle_sip_hop_free(&hop);
} }
void belle_sip_provider_send_response(belle_sip_provider_t *p, belle_sip_response_t *resp){ void belle_sip_provider_send_response(belle_sip_provider_t *p, belle_sip_response_t *resp){
...@@ -287,6 +291,7 @@ void belle_sip_provider_send_response(belle_sip_provider_t *p, belle_sip_respons ...@@ -287,6 +291,7 @@ void belle_sip_provider_send_response(belle_sip_provider_t *p, belle_sip_respons
belle_sip_response_get_return_hop(resp,&hop); belle_sip_response_get_return_hop(resp,&hop);
chan=belle_sip_provider_get_channel(p,hop.host, hop.port, hop.transport); chan=belle_sip_provider_get_channel(p,hop.host, hop.port, hop.transport);
if (chan) belle_sip_channel_queue_message(chan,BELLE_SIP_MESSAGE(resp)); if (chan) belle_sip_channel_queue_message(chan,BELLE_SIP_MESSAGE(resp));
belle_sip_hop_free(&hop);
} }
......
...@@ -113,15 +113,30 @@ void belle_sip_stack_sleep(belle_sip_stack_t *stack, unsigned int milliseconds){ ...@@ -113,15 +113,30 @@ void belle_sip_stack_sleep(belle_sip_stack_t *stack, unsigned int milliseconds){
void belle_sip_stack_get_next_hop(belle_sip_stack_t *stack, belle_sip_request_t *req, belle_sip_hop_t *hop){ void belle_sip_stack_get_next_hop(belle_sip_stack_t *stack, belle_sip_request_t *req, belle_sip_hop_t *hop){
belle_sip_header_route_t *route=BELLE_SIP_HEADER_ROUTE(belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"route")); 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; belle_sip_uri_t *uri;
const char *transport;
if (route!=NULL){ if (route!=NULL){
uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(route)); uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(route));
}else{ }else{
uri=belle_sip_request_get_uri(req); uri=belle_sip_request_get_uri(req);
} }
hop->transport=belle_sip_uri_get_transport_param(uri); transport=belle_sip_uri_get_transport_param(uri);
if (hop->transport==NULL) hop->transport="UDP"; if (transport!=NULL) hop->transport=belle_sip_strdup(transport);
hop->host=belle_sip_uri_get_host(uri); else hop->transport=NULL;
hop->host=belle_sip_strdup(belle_sip_uri_get_host(uri));
hop->port=belle_sip_uri_get_listening_port(uri); hop->port=belle_sip_uri_get_listening_port(uri);
if (route){
belle_sip_message_remove_first((belle_sip_message_t*)req,"route");
}
} }
void belle_sip_hop_free(belle_sip_hop_t *hop){
if (hop->host) {
belle_sip_free(hop->host);
hop->host=NULL;
}
if (hop->transport){
belle_sip_free(hop->transport);
hop->transport=NULL;
}
}
...@@ -129,6 +129,7 @@ void belle_sip_server_transaction_send_response(belle_sip_server_transaction_t * ...@@ -129,6 +129,7 @@ void belle_sip_server_transaction_send_response(belle_sip_server_transaction_t *
belle_sip_response_get_return_hop(resp,&hop); belle_sip_response_get_return_hop(resp,&hop);
base->channel=belle_sip_provider_get_channel(base->provider,hop.host, hop.port, hop.transport); base->channel=belle_sip_provider_get_channel(base->provider,hop.host, hop.port, hop.transport);
belle_sip_object_ref(base->channel); belle_sip_object_ref(base->channel);
belle_sip_hop_free(&hop);
} }
if (BELLE_SIP_OBJECT_VPTR(t,belle_sip_server_transaction_t)->send_new_response(t,resp)==0){ if (BELLE_SIP_OBJECT_VPTR(t,belle_sip_server_transaction_t)->send_new_response(t,resp)==0){
if (base->last_response) if (base->last_response)
...@@ -202,6 +203,7 @@ void belle_sip_client_transaction_send_request(belle_sip_client_transaction_t *t ...@@ -202,6 +203,7 @@ void belle_sip_client_transaction_send_request(belle_sip_client_transaction_t *t
belle_sip_message("belle_sip_client_transaction_send_request(): waiting channel to be ready"); belle_sip_message("belle_sip_client_transaction_send_request(): waiting channel to be ready");
} }
}else belle_sip_error("belle_sip_client_transaction_send_request(): no channel available"); }else belle_sip_error("belle_sip_client_transaction_send_request(): no channel available");
belle_sip_hop_free(&hop);
} }
void belle_sip_client_transaction_notify_response(belle_sip_client_transaction_t *t, belle_sip_response_t *resp){ void belle_sip_client_transaction_notify_response(belle_sip_client_transaction_t *t, belle_sip_response_t *resp){
......
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