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

fix transaction memory leaks, implement loose routing

parent 67e1d559
......@@ -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_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_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);
......
......@@ -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_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);
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);
......
......@@ -21,8 +21,8 @@
#define belle_sip_stack_h
struct belle_sip_hop{
const char *host;
const char *transport;
char *host;
char *transport;
int port;
};
......@@ -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_hop_free(belle_sip_hop_t *hop);
BELLE_SIP_END_DECLS
#endif
......
......@@ -32,9 +32,9 @@ typedef enum {
BELLE_SIP_LOG_FATAL=1,
BELLE_SIP_LOG_ERROR=1<<1,
BELLE_SIP_LOG_WARNING=1<<2,
BELLE_SIP_LOG_MESSAGE=1<<3,
BELLE_SIP_LOG_DEBUG=1<<4,
BELLE_SIP_LOG_END=1<<5
BELLE_SIP_LOG_MESSAGE=1<<3,
BELLE_SIP_LOG_DEBUG=1<<4,
BELLE_SIP_LOG_END=1<<5
} belle_sip_log_level;
......
......@@ -119,7 +119,7 @@ int belle_sip_header_address_marshal(belle_sip_header_address_t* header, char* b
return current_offset-offset;
}
BELLE_SIP_NEW(header_address,parameters)
BELLE_SIP_NEW_HEADER(header_address,parameters,"header_address")
BELLE_SIP_PARSE(header_address)
GET_SET_STRING(belle_sip_header_address,displayname);
......
......@@ -381,16 +381,30 @@ belle_sip_##object_type##_t* belle_sip_##object_type##_parse (const char* value)
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_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) \
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_##object_type##_t); \
BELLE_SIP_INSTANCIATE_VPTR( belle_sip_##object_type##_t\
#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, TRUE); \
belle_sip_##object_type##_t* belle_sip_##object_type##_new () { \
, 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_INIT(object_type,super_type,name,init_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, TRUE); \
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_##init_type##_init((belle_sip_##init_type##_t*) l_object); \
......
......@@ -48,7 +48,7 @@ int belle_sip_parameters_marshal(belle_sip_parameters_t* params, char* buff,unsi
}
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) {
return obj->param_list;
}
......
......@@ -185,6 +185,13 @@ belle_sip_list_t* belle_sip_list_prepend(belle_sip_list_t* elem, void *data){
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* it=first;
......
......@@ -89,7 +89,7 @@ static int get_message_start_pos(char *buff, size_t bufflen) {
}
if (res==1) return i;
else {
res=sscanf(buff+i,"%16s %*s SIP/2.0 ",(char*)&method);
res=sscanf(buff+i,"%16s %*s SIP/2.0 ",method);
}
}
return -1;
......
......@@ -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,
NULL,
NULL
......
......@@ -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,
NULL,
NULL
......
......@@ -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;
}
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) {
unsigned int current_offset=offset;
......@@ -192,6 +219,9 @@ static void belle_sip_request_destroy(belle_sip_request_t* request) {
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){
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
}
return current_offset-offset;
}
BELLE_SIP_NEW(request,message)
BELLE_SIP_PARSE(request)
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
char *belle_sip_message_to_string(belle_sip_message_t *msg){
return belle_sip_object_to_string(BELLE_SIP_OBJECT(msg));
}
const char* belle_sip_message_get_body(belle_sip_message_t *msg) {
return msg->body;
}
void belle_sip_message_set_body(belle_sip_message_t *msg,char* body,unsigned int size) {
if (msg->body) {
belle_sip_free((void*)body);
......@@ -333,6 +366,9 @@ void belle_sip_response_destroy(belle_sip_response_t *resp){
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){
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);
......@@ -400,14 +436,14 @@ belle_sip_response_t *belle_sip_response_new_from_request(belle_sip_request_t *r
return resp;
}
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"));
hop->transport=belle_sip_header_via_get_protocol(via);
hop->host=belle_sip_header_via_get_received(via);
if (hop->host==NULL)
hop->host=belle_sip_header_via_get_host(via);
const char *host;
hop->transport=belle_sip_strdup(belle_sip_header_via_get_protocol(via));
host=belle_sip_header_via_get_received(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);
if (hop->port==-1)
hop->port=belle_sip_header_via_get_listening_port(via);
......
......@@ -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,
NULL,
NULL
......
......@@ -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,
NULL,
NULL
......
......@@ -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_listening_point_t *candidate=NULL,*lp;
belle_sip_channel_t *chan;
if (transport==NULL) transport="UDP";
for(l=p->lps;l!=NULL;l=l->next){
lp=(belle_sip_listening_point_t*)l->data;
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_
if (chan) {
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){
......@@ -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);
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));
belle_sip_hop_free(&hop);
}
......
......@@ -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){
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);
}
hop->transport=belle_sip_uri_get_transport_param(uri);
if (hop->transport==NULL) hop->transport="UDP";
hop->host=belle_sip_uri_get_host(uri);
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");
}
}
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 *
belle_sip_response_get_return_hop(resp,&hop);
base->channel=belle_sip_provider_get_channel(base->provider,hop.host, hop.port, hop.transport);
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 (base->last_response)
......@@ -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");
}
}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){
......
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