Example #1
0
/*constructor for channels creating an outgoing connection
 * bindip local ip address to bind on, typically 0.0.0.0 or ::0
 * locaport locaport to use for binding, can be set to 0 if port doesn't matter
 * peer_cname canonical name of remote host, used for TLS verification
 * peername peer's hostname, either ip address or DNS name
 * pee_port peer's port to connect to.
 */
void belle_sip_channel_init(belle_sip_channel_t *obj, belle_sip_stack_t *stack,const char *bindip,int localport,const char *peer_cname, const char *peername, int peer_port){
	/*to initialize our base class:*/
	belle_sip_channel_set_socket(obj,-1,NULL);
	
	/*then initialize members*/
	obj->ai_family=AF_INET;
	obj->peer_cname=peer_cname ? belle_sip_strdup(peer_cname) : NULL;
	obj->peer_name=belle_sip_strdup(peername);
	obj->peer_port=peer_port;
	obj->stack=stack;
	if (bindip){
		if (strcmp(bindip,"::0")!=0 && strcmp(bindip,"0.0.0.0")!=0)
			obj->local_ip=belle_sip_strdup(bindip);
		if (strchr(bindip,':')!=NULL)
			obj->ai_family=AF_INET6;
	}
	obj->local_port=localport;
	obj->simulated_recv_return=1;/*not set*/
	if (peername){
		/*check if we are given a real dns name or just an ip address*/
		struct addrinfo *ai=belle_sip_ip_address_to_addrinfo(AF_UNSPEC,peername,peer_port);
		if (ai) freeaddrinfo(ai);
		else obj->has_name=TRUE;
	}
	belle_sip_channel_input_stream_reset(&obj->input_stream);
	update_inactivity_timer(obj,FALSE);
}
Example #2
0
belle_sip_hop_t* belle_sip_hop_new(const char* transport, const char *cname, const char* host,int port) {
	belle_sip_hop_t* hop = belle_sip_object_new(belle_sip_hop_t);
	if (transport) hop->transport=belle_sip_strdup(transport);
	if (host) hop->host=belle_sip_strdup(host);
	if (cname) hop->cname=belle_sip_strdup(cname);
	hop->port=port;
	return hop;
}
Example #3
0
static void belle_sip_hop_clone(belle_sip_hop_t *hop, const belle_sip_hop_t *orig){
	if (orig->host)
		hop->host=belle_sip_strdup(orig->host);
	if (orig->cname)
		hop->cname=belle_sip_strdup(orig->cname);
	if (orig->transport)
		hop->transport=belle_sip_strdup(orig->transport);
	
}
Example #4
0
static void set_to_tag(belle_sip_dialog_t *obj, belle_sip_header_to_t *to){
	const char *to_tag=belle_sip_header_to_get_tag(to);
	if (obj->is_server){
		if (to_tag && !obj->local_tag)
			obj->local_tag=belle_sip_strdup(to_tag);
	}else{
		if (to_tag && !obj->remote_tag)
			obj->remote_tag=belle_sip_strdup(to_tag);
	}
}
Example #5
0
belle_sip_dialog_t *belle_sip_dialog_new(belle_sip_transaction_t *t){
	belle_sip_dialog_t *obj;
	belle_sip_header_from_t *from;
	const char *from_tag;
	belle_sip_header_to_t *to;
	const char *to_tag=NULL;

	from=belle_sip_message_get_header_by_type(t->request,belle_sip_header_from_t);
	if (from==NULL){
		belle_sip_error("belle_sip_dialog_new(): no from!");
		return NULL;
	}
	from_tag=belle_sip_header_from_get_tag(from);
	if (from_tag==NULL){
		belle_sip_error("belle_sip_dialog_new(): no from tag!");
		return NULL;
	}

	if (t->last_response) {
		to=belle_sip_message_get_header_by_type(t->last_response,belle_sip_header_to_t);
		if (to==NULL){
			belle_sip_error("belle_sip_dialog_new(): no to!");
			return NULL;
		}
		to_tag=belle_sip_header_to_get_tag(to);
	}
	obj=belle_sip_object_new(belle_sip_dialog_t);
	obj->terminate_on_bye=1;
	obj->provider=t->provider;
	
	if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_server_transaction_t)){
		obj->remote_tag=belle_sip_strdup(from_tag);
		obj->local_tag=to_tag?belle_sip_strdup(to_tag):NULL; /*might be null at dialog creation*/
		obj->remote_party=(belle_sip_header_address_t*)belle_sip_object_ref(from);
		obj->is_server=TRUE;
	}else{
		const belle_sip_list_t *predefined_routes=NULL;
		obj->local_tag=belle_sip_strdup(from_tag);
		obj->remote_tag=to_tag?belle_sip_strdup(to_tag):NULL; /*might be null at dialog creation*/
		obj->local_party=(belle_sip_header_address_t*)belle_sip_object_ref(from);
		obj->is_server=FALSE;
		for(predefined_routes=belle_sip_message_get_headers((belle_sip_message_t*)t->request,BELLE_SIP_ROUTE);
			predefined_routes!=NULL;predefined_routes=predefined_routes->next){
			obj->route_set=belle_sip_list_append(obj->route_set,belle_sip_object_ref(predefined_routes->data));	
		}
	}
	belle_sip_message("New %s dialog [%p] , local tag [%s], remote tag [%s]"
			,obj->is_server?"server":"client"
			,obj
			,obj->local_tag?obj->local_tag:""
			,obj->remote_tag?obj->remote_tag:"");
	set_state(obj,BELLE_SIP_DIALOG_NULL);
	return obj;
}
Example #6
0
static void belle_sip_uri_clone(belle_sip_uri_t* uri, const belle_sip_uri_t *orig){
	uri->secure=orig->secure;
	uri->user=orig->user?belle_sip_strdup(orig->user):NULL;
	uri->user_password=orig->user_password?belle_sip_strdup(orig->user_password):NULL;
	uri->host=orig->host?belle_sip_strdup(orig->host):NULL;
	uri->port=orig->port;
	if (orig->header_list){
		uri->header_list=(belle_sip_parameters_t*)belle_sip_object_clone(BELLE_SIP_OBJECT(orig->header_list));
		belle_sip_object_ref(uri->header_list);
	}

}
Example #7
0
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END

belle_sip_multipart_body_handler_t *belle_sip_multipart_body_handler_new(belle_sip_body_handler_progress_callback_t progress_cb, void *data,
									 belle_sip_body_handler_t *first_part, const char *boundary){
	belle_sip_multipart_body_handler_t *obj=belle_sip_object_new(belle_sip_multipart_body_handler_t);
	belle_sip_body_handler_init((belle_sip_body_handler_t*)obj,progress_cb,data);
	if (boundary != NULL) {
		obj->boundary = belle_sip_strdup(boundary);
	} else {
		obj->boundary = belle_sip_strdup(BELLESIP_MULTIPART_BOUNDARY);
	}
	obj->base.expected_size = strlen(obj->boundary) + 8; /* body's length will be part length(including boundary) + multipart end. 8 is for "\r\n--" and "--\r\n" */
	if (first_part) belle_sip_multipart_body_handler_add_part(obj,first_part);
	return obj;
}
static void* test_object_data_string_clone(const char*name, void* data){
	clone_called++;
	if( strcmp(name, "test_str") == 0)
		return belle_sip_strdup(data);
	else
		return data;
}
Example #9
0
static LinphoneNatPolicy * _linphone_nat_policy_new_with_ref(LinphoneCore *lc, const char *ref) {
	LinphoneNatPolicy *policy = belle_sip_object_new(LinphoneNatPolicy);
	belle_sip_object_ref(policy);
	policy->lc = lc;
	policy->ref = belle_sip_strdup(ref);
	return policy;
}
belle_sip_request_t* try_register_user_at_domain(belle_sip_stack_t * stack
	,belle_sip_provider_t *prov
	,const char *transport
	,int use_transaction
	,const char* username
	,const char* domain
	,const char* outbound_proxy
	,int success_expected) {
	belle_sip_request_t *req,*copy;
	char identity[256];
	char uri[256];
	int i;
	char *outbound=NULL;

	number_of_challenge=0;
	if (transport)
		snprintf(uri,sizeof(uri),"sip:%s;transport=%s",domain,transport);
	else snprintf(uri,sizeof(uri),"sip:%s",domain);

	if (transport && strcasecmp("tls",transport)==0 && belle_sip_provider_get_listening_point(prov,"tls")==NULL){
		belle_sip_error("No TLS support, test skipped.");
		return NULL;
	}

	if (outbound_proxy){
		if (strstr(outbound_proxy,"sip:")==NULL && strstr(outbound_proxy,"sips:")==NULL){
			outbound=belle_sip_strdup_printf("sip:%s",outbound_proxy);
		}else outbound=belle_sip_strdup(outbound_proxy);
	}

	snprintf(identity,sizeof(identity),"Tester <sip:%s@%s>",username,domain);
	req=belle_sip_request_create(
						belle_sip_uri_parse(uri),
						"REGISTER",
						belle_sip_provider_create_call_id(prov),
						belle_sip_header_cseq_create(20,"REGISTER"),
						belle_sip_header_from_create2(identity,BELLE_SIP_RANDOM_TAG),
						belle_sip_header_to_create2(identity,NULL),
						belle_sip_header_via_new(),
						70);
	is_register_ok=0;
	io_error_count=0;
	using_transaction=0;
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(600)));
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_contact_new()));
	copy=(belle_sip_request_t*)belle_sip_object_ref(belle_sip_object_clone((belle_sip_object_t*)req));
	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_to(t,outbound?belle_sip_uri_parse(outbound):NULL);
	}else belle_sip_provider_send_request(prov,req);
	for(i=0;!is_register_ok && i<2 && io_error_count==0;i++)
		belle_sip_stack_sleep(stack,5000);
	CU_ASSERT_EQUAL(is_register_ok,success_expected);
	if (success_expected) CU_ASSERT_EQUAL(using_transaction,use_transaction);

	belle_sip_provider_remove_sip_listener(prov,l);
	if (outbound) belle_sip_free(outbound);
	return copy;
}
int belle_sip_object_data_set( belle_sip_object_t *obj, const char* name, void* data, belle_sip_data_destroy destroy_func )
{
	int ret = 0;
	struct _belle_sip_list*  list_entry = belle_sip_list_find_custom(obj->data_store, belle_sip_object_data_find, name);
	struct belle_sip_object_data* entry = (list_entry)? list_entry->data : NULL;

	if( entry == NULL){
		entry = belle_sip_malloc0(sizeof( struct belle_sip_object_data));
		obj->data_store = belle_sip_list_append(obj->data_store, entry);
	}
	else {
		// clean previous data
		if( entry->destroy_func ) entry->destroy_func(entry->data);
		belle_sip_free(entry->name);
		ret = 1;
	}

	if( entry ){
		entry->data = data;
		entry->name = belle_sip_strdup(name);
		entry->destroy_func = destroy_func;
	} else {
		ret = -1;
	}
	return ret;
}
Example #12
0
belle_http_provider_t *belle_http_provider_new(belle_sip_stack_t *s, const char *bind_ip){
	belle_http_provider_t *p=belle_sip_object_new(belle_http_provider_t);
	p->stack=s;
	p->bind_ip=belle_sip_strdup(bind_ip);
	p->ai_family=strchr(p->bind_ip,':') ? AF_INET6 : AF_INET;
	p->verify_ctx=belle_tls_verify_policy_new();
	return p;
}
void belle_sip_object_set_name(belle_sip_object_t* object,const char* name) {
	if (object->name) {
		belle_sip_free(object->name);
		object->name=NULL;
	}
	if (name)
		object->name=belle_sip_strdup(name);
}
Example #14
0
static LinphoneXmlRpcRequest * _linphone_xml_rpc_request_new(const char *method, LinphoneXmlRpcArgType return_type) {
    LinphoneXmlRpcRequest *request = belle_sip_object_new(LinphoneXmlRpcRequest);
    request->callbacks = linphone_xml_rpc_request_cbs_new();
    request->status = LinphoneXmlRpcStatusPending;
    request->response.type = return_type;
    request->method = belle_sip_strdup(method);
    return request;
}
Example #15
0
void sal_set_uuid(Sal *sal, const char *uuid){
	if (sal->uuid){
		belle_sip_free(sal->uuid);
		sal->uuid=NULL;
	}
	if (uuid)
		sal->uuid=belle_sip_strdup(uuid);
}
Example #16
0
void belle_sip_refresher_set_realm(belle_sip_refresher_t* refresher, const char* realm) {
	if (refresher->realm){
		belle_sip_free(refresher->realm);
		refresher->realm = NULL;
	}
	if (realm!=NULL){
		refresher->realm=belle_sip_strdup(realm);
	}
}
Example #17
0
void linphone_content_set_name(LinphoneContent *content, const char *name) {
	if (content->name != NULL) {
		belle_sip_free(content->name);
		content->name = NULL;
	}
	if (name != NULL) {
		content->name = belle_sip_strdup(name);
	}
}
Example #18
0
void linphone_nat_policy_set_stun_server_username(LinphoneNatPolicy *policy, const char *username) {
	char *new_username = NULL;

	if (username != NULL) new_username = belle_sip_strdup(username);
	if (policy->stun_server_username != NULL) {
		belle_sip_free(policy->stun_server_username);
		policy->stun_server_username = NULL;
	}
	if (new_username != NULL) policy->stun_server_username = new_username;
}
Example #19
0
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END

belle_sip_file_body_handler_t *belle_sip_file_body_handler_new(const char *filepath, belle_sip_body_handler_progress_callback_t progress_cb, void *data) {
	struct stat statbuf;
	belle_sip_file_body_handler_t *obj = belle_sip_object_new(belle_sip_file_body_handler_t);
	belle_sip_body_handler_init((belle_sip_body_handler_t*)obj, progress_cb, data);
	obj->filepath = belle_sip_strdup(filepath);
	if (stat(obj->filepath, &statbuf) == 0) {
		obj->base.expected_size = statbuf.st_size;
	}
	return obj;
}
Example #20
0
int belle_tls_verify_policy_set_root_ca(belle_tls_verify_policy_t *obj, const char *path){
	if (obj->root_ca){
		belle_sip_free(obj->root_ca);
		obj->root_ca=NULL;
	}
	if (path){
		obj->root_ca=belle_sip_strdup(path);
		belle_sip_message("Root ca path set to %s",obj->root_ca);
	} else {
		belle_sip_message("Root ca path disabled");
	}
	return 0;
}
Example #21
0
void linphone_nat_policy_set_stun_server(LinphoneNatPolicy *policy, const char *stun_server) {
	char *new_stun_server = NULL;

	if (stun_server != NULL) new_stun_server = belle_sip_strdup(stun_server);
	if (policy->stun_server != NULL) {
		belle_sip_free(policy->stun_server);
		policy->stun_server = NULL;
	}
	if (new_stun_server != NULL) {
		policy->stun_server = new_stun_server;
		linphone_nat_policy_resolve_stun_server(policy);
	}
}
int belle_sip_tls_listening_point_set_root_ca(belle_sip_tls_listening_point_t *lp, const char *path){
	if (lp->root_ca){
		belle_sip_free(lp->root_ca);
		lp->root_ca=NULL;
	}
	if (path){
		lp->root_ca=belle_sip_strdup(path);
		belle_sip_message("Root ca path set to %s",lp->root_ca);
	} else {
		belle_sip_message("Root ca path disabled");
	}
	return 0;
}
Example #23
0
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END

void belle_sip_server_transaction_init(belle_sip_server_transaction_t *t, belle_sip_provider_t *prov,belle_sip_request_t *req){
	const char *branch;
	belle_sip_header_via_t *via=BELLE_SIP_HEADER_VIA(belle_sip_message_get_header((belle_sip_message_t*)req,"via"));
	branch=belle_sip_header_via_get_branch(via);
	if (branch==NULL || strncmp(branch,BELLE_SIP_BRANCH_MAGIC_COOKIE,strlen(BELLE_SIP_BRANCH_MAGIC_COOKIE))!=0){
		branch=req->rfc2543_branch;
		if (branch==NULL) belle_sip_fatal("No computed branch for RFC2543 style of message, this should never happen.");
	}
	t->base.branch_id=belle_sip_strdup(branch);
	belle_sip_transaction_init((belle_sip_transaction_t*)t,prov,req);
	belle_sip_random_token(t->to_tag,sizeof(t->to_tag));
}
Example #24
0
belle_http_request_t *belle_http_request_create(const char *method, belle_generic_uri_t *url, ...){
	va_list vl;
	belle_http_request_t *obj=belle_http_request_new();
	belle_sip_header_t *header;
	
	obj->method=belle_sip_strdup(method);
	obj->req_uri=(belle_generic_uri_t*)belle_sip_object_ref(url);
	
	va_start(vl,url);
	while((header=va_arg(vl,belle_sip_header_t*))!=NULL){
		belle_sip_message_add_header(BELLE_SIP_MESSAGE(obj),header);
	}
	va_end(vl);
	return obj;
}
char* belle_sip_object_to_string(void* _obj) {
	belle_sip_object_t *obj=BELLE_SIP_OBJECT(_obj);
	if (obj->vptr->tostring_bufsize_hint!=0){
		return belle_sip_object_to_alloc_string(obj,obj->vptr->tostring_bufsize_hint);
	}else{
		char buff[BELLE_SIP_MAX_TO_STRING_SIZE];
		size_t offset=0;
		belle_sip_error_code error = belle_sip_object_marshal(obj,buff,sizeof(buff),&offset);
		if (error==BELLE_SIP_BUFFER_OVERFLOW){
			belle_sip_message("belle_sip_object_to_string(): temporary buffer is too short while doing to_string() for %s, retrying", obj->vptr->type_name);
			return belle_sip_object_to_alloc_string(obj,get_hint_size(2*offset));
		}
		buff[offset]='\0';
		obj->vptr->tostring_bufsize_hint=get_hint_size(2*offset);
		return belle_sip_strdup(buff);
	}
}
Example #26
0
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END

void belle_sip_client_transaction_init(belle_sip_client_transaction_t *obj, belle_sip_provider_t *prov, belle_sip_request_t *req){
	belle_sip_header_via_t *via=BELLE_SIP_HEADER_VIA(belle_sip_message_get_header((belle_sip_message_t*)req,"via"));
	char token[BELLE_SIP_BRANCH_ID_LENGTH];

	if (!via){
		belle_sip_fatal("belle_sip_client_transaction_init(): No via in request.");
	}

	if (strcmp(belle_sip_request_get_method(req),"CANCEL")!=0){
		obj->base.branch_id=belle_sip_strdup_printf(BELLE_SIP_BRANCH_MAGIC_COOKIE ".%s",belle_sip_random_token(token,sizeof(token)));
		belle_sip_header_via_set_branch(via,obj->base.branch_id);
	}else{
		obj->base.branch_id=belle_sip_strdup(belle_sip_header_via_get_branch(via));
	}
	belle_sip_transaction_init((belle_sip_transaction_t*)obj, prov,req);
}
Example #27
0
static void split_request_url(belle_http_request_t *req){
	belle_generic_uri_t *uri=belle_http_request_get_uri(req);
	belle_generic_uri_t *new_uri;
	char *host_value;
	const char *path;

	if (belle_generic_uri_get_host(uri)==NULL && req->orig_uri!=NULL) return;/*already processed request uri*/
	path=belle_generic_uri_get_path(uri);
	if (path==NULL) path="/";
	new_uri=belle_generic_uri_new();

	belle_generic_uri_set_path(new_uri,path);
	belle_generic_uri_set_query(new_uri, belle_generic_uri_get_query(uri));
	if (belle_generic_uri_get_port(uri)>0)
		host_value=belle_sip_strdup_printf("%s:%i",belle_generic_uri_get_host(uri),belle_generic_uri_get_port(uri));
	else
		host_value=belle_sip_strdup(belle_generic_uri_get_host(uri));
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),belle_sip_header_create("Host",host_value));
	belle_sip_free(host_value);
	SET_OBJECT_PROPERTY(req,orig_uri,uri);
	belle_http_request_set_uri(req,new_uri);
}
Example #28
0
void belle_sip_channel_set_public_ip_port(belle_sip_channel_t *obj, const char *public_ip, int port){
	if (obj->public_ip){
		int ip_changed=0;
		int port_changed=0;
		
		if (public_ip && strcmp(obj->public_ip,public_ip)!=0){
			ip_changed=1;
		}
		if (port!=obj->public_port){
			port_changed=1;
		}
		if (ip_changed || port_changed){
			belle_sip_warning("channel [%p]: public ip is changed from [%s:%i] to [%s:%i]",obj,obj->public_ip,obj->public_port,public_ip,port);
		}
		belle_sip_free(obj->public_ip);
		obj->public_ip=NULL;
	}else if (public_ip){
		belle_sip_message("channel [%p]: discovered public ip and port are [%s:%i]",obj,public_ip,port);
	}
	if (public_ip){
		obj->public_ip=belle_sip_strdup(public_ip);
	}
	obj->public_port=port;
}
Example #29
0
void belle_sip_channel_set_ready(belle_sip_channel_t *obj, const struct sockaddr *addr, socklen_t slen){
	char name[NI_MAXHOST];
	char serv[NI_MAXSERV];

	if (obj->local_ip==NULL){
		struct sockaddr_storage saddr;
		socklen_t slen2=sizeof(saddr);
		int err;
		
		belle_sip_address_remove_v4_mapping(addr,(struct sockaddr*) &saddr,&slen2);
		
		err=getnameinfo((struct sockaddr*)&saddr,slen,name,sizeof(name),serv,sizeof(serv),NI_NUMERICHOST|NI_NUMERICSERV);
		if (err!=0){
			belle_sip_error("belle_sip_channel_set_ready(): getnameinfo() failed: %s",gai_strerror(err));
		}else{
			obj->local_ip=belle_sip_strdup(name);
			obj->local_port=atoi(serv);
			belle_sip_message("Channel has local address %s:%s",name,serv);
		}
	}
	channel_set_state(obj,BELLE_SIP_CHANNEL_READY);
	channel_process_queue(obj);
	channel_end_send_background_task(obj);
}
Example #30
0
static void parse_valid_xml_rpc_response(LinphoneXmlRpcRequest *request, const char *response_body) {
    xmlparsing_context_t *xml_ctx = linphone_xmlparsing_context_new();
    xmlSetGenericErrorFunc(xml_ctx, linphone_xmlparsing_genericxml_error);
    request->status = LinphoneXmlRpcStatusFailed;
    xml_ctx->doc = xmlReadDoc((const unsigned char*)response_body, 0, NULL, 0);
    if (xml_ctx->doc != NULL) {
        const char *response_str = NULL;
        if (linphone_create_xml_xpath_context(xml_ctx) < 0) goto end;
        switch (request->response.type) {
        case LinphoneXmlRpcArgInt:
            response_str = linphone_get_xml_text_content(xml_ctx, "/methodResponse/params/param/value/int");
            if (response_str != NULL) {
                request->response.data.i = atoi(response_str);
                request->status = LinphoneXmlRpcStatusOk;
            }
            break;
        case LinphoneXmlRpcArgString:
            response_str = linphone_get_xml_text_content(xml_ctx, "/methodResponse/params/param/value/string");
            if (response_str != NULL) {
                request->response.data.s = belle_sip_strdup(response_str);
                request->status = LinphoneXmlRpcStatusOk;
            }
            break;
        default:
            break;
        }
        if (response_str) linphone_free_xml_text_content(response_str);
    } else {
        ms_warning("Wrongly formatted XML-RPC response: %s", xml_ctx->errorBuffer);
    }
end:
    linphone_xmlparsing_context_destroy(xml_ctx);
    if (request->callbacks->response != NULL) {
        request->callbacks->response(request);
    }
}