示例#1
0
文件: sal_impl.c 项目: 42p/linphone
void sal_process_authentication(SalOp *op) {
	belle_sip_request_t* initial_request=belle_sip_transaction_get_request((belle_sip_transaction_t*)op->pending_auth_transaction);
	belle_sip_request_t* new_request;
	bool_t is_within_dialog=FALSE;
	belle_sip_list_t* auth_list=NULL;
	belle_sip_auth_event_t* auth_event;
	belle_sip_response_t *response=belle_sip_transaction_get_response((belle_sip_transaction_t*)op->pending_auth_transaction);
	belle_sip_header_from_t *from=belle_sip_message_get_header_by_type(initial_request,belle_sip_header_from_t);
	belle_sip_uri_t *from_uri=belle_sip_header_address_get_uri((belle_sip_header_address_t*)from);

	if (strcasecmp(belle_sip_uri_get_host(from_uri),"anonymous.invalid")==0){
		/*prefer using the from from the SalOp*/
		from_uri=belle_sip_header_address_get_uri((belle_sip_header_address_t*)sal_op_get_from_address(op));
	}

	if (op->dialog && belle_sip_dialog_get_state(op->dialog)==BELLE_SIP_DIALOG_CONFIRMED) {
		new_request = belle_sip_dialog_create_request_from(op->dialog,initial_request);
		if (!new_request)
			new_request = belle_sip_dialog_create_queued_request_from(op->dialog,initial_request);
		is_within_dialog=TRUE;
	} else {
		new_request=initial_request;
		belle_sip_message_remove_header(BELLE_SIP_MESSAGE(new_request),BELLE_SIP_AUTHORIZATION);
		belle_sip_message_remove_header(BELLE_SIP_MESSAGE(new_request),BELLE_SIP_PROXY_AUTHORIZATION);
	}
	if (new_request==NULL) {
		ms_error("sal_process_authentication() op=[%p] cannot obtain new request from dialog.",op);
		return;
	}

	if (belle_sip_provider_add_authorization(op->base.root->prov,new_request,response,from_uri,&auth_list,op->base.realm)) {
		if (is_within_dialog) {
			sal_op_send_request(op,new_request);
		} else {
			sal_op_resend_request(op,new_request);
		}
		sal_remove_pending_auth(op->base.root,op);
	}else {
		belle_sip_header_from_t *from=belle_sip_message_get_header_by_type(response,belle_sip_header_from_t);
		char *tmp=belle_sip_object_to_string(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from)));
		ms_message("No auth info found for [%s]",tmp);
		belle_sip_free(tmp);
		sal_add_pending_auth(op->base.root,op);

		if (is_within_dialog) {
			belle_sip_object_unref(new_request);
		}
	}
	/*always store auth info, for case of wrong credential*/
	if (op->auth_info) {
		sal_auth_info_delete(op->auth_info);
		op->auth_info=NULL;
	}
	if (auth_list){
		auth_event=(belle_sip_auth_event_t*)(auth_list->data);
		op->auth_info=sal_auth_info_create(auth_event);
		belle_sip_list_free_with_data(auth_list,(void (*)(void*))belle_sip_auth_event_destroy);
	}
}
static belle_sip_channel_t *tls_create_channel(belle_sip_listening_point_t *lp, const belle_sip_hop_t *hop){
	belle_sip_channel_t *chan=belle_sip_channel_new_tls(BELLE_SIP_TLS_LISTENING_POINT(lp)
				,belle_sip_uri_get_host(lp->listening_uri)
				,belle_sip_uri_get_port(lp->listening_uri)
				,hop->cname
				,hop->host,hop->port);
	return chan;
}
static belle_sip_channel_t *tls_create_channel(belle_sip_listening_point_t *lp, const belle_sip_hop_t *hop){
	belle_sip_channel_t *chan=belle_sip_channel_new_tls(lp->stack, ((belle_sip_tls_listening_point_t*) lp)->crypto_config
				,belle_sip_uri_get_host(lp->listening_uri)
				,belle_sip_uri_get_port(lp->listening_uri)
				,hop->cname
				,hop->host,hop->port);
	return chan;
}
示例#4
0
static belle_sip_channel_t *udp_create_channel(belle_sip_listening_point_t *lp, const belle_sip_hop_t *hop){
	belle_sip_channel_t *chan=belle_sip_channel_new_udp(lp->stack
														,((belle_sip_udp_listening_point_t*)lp)->sock
														,belle_sip_uri_get_host(lp->listening_uri)
														,belle_sip_uri_get_port(lp->listening_uri)
														,hop->host
														,hop->port);
	return chan;
}
示例#5
0
static void test_ip_host(void) {
	belle_sip_uri_t *  L_uri = belle_sip_uri_parse("sip:192.168.0.1");
	char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
	L_uri = belle_sip_uri_parse(l_raw_uri);
	belle_sip_free(l_raw_uri);
	CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri), "192.168.0.1");
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
}
bool_t sal_address_is_ipv6(const SalAddress *addr){
	belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);
	belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr);
	if (uri){
		const char *host=belle_sip_uri_get_host(uri);
		if (host && strchr(host,':')!=NULL)
			return TRUE;
	}
	return FALSE;
}
示例#7
0
belle_sip_auth_event_t* belle_sip_auth_event_create(belle_sip_object_t *source, const char* realm, const belle_sip_uri_t *from_uri) {
	belle_sip_auth_event_t* result = belle_sip_new0(belle_sip_auth_event_t);
	result->source=source;
	belle_sip_auth_event_set_realm(result,realm);
	
	if (from_uri){
		belle_sip_auth_event_set_username(result,belle_sip_uri_get_user(from_uri));
		belle_sip_auth_event_set_domain(result,belle_sip_uri_get_host(from_uri));
	}
	return result;
}
示例#8
0
static int belle_sip_udp_listening_point_init_socket(belle_sip_udp_listening_point_t *lp){
	lp->sock=create_udp_socket(belle_sip_uri_get_host(((belle_sip_listening_point_t*)lp)->listening_uri)
					,belle_sip_uri_get_port(((belle_sip_listening_point_t*)lp)->listening_uri),&lp->base.ai_family);
	if (lp->sock==(belle_sip_socket_t)-1){
		return -1;
	}
	if (lp->base.stack->dscp)
		belle_sip_socket_set_dscp(lp->sock,lp->base.ai_family,lp->base.stack->dscp);
	lp->source=belle_sip_socket_source_new((belle_sip_source_func_t)on_udp_data,lp,lp->sock,BELLE_SIP_EVENT_READ,-1);
	belle_sip_main_loop_add_source(((belle_sip_listening_point_t*)lp)->stack->ml,lp->source);
	return 0;
}
void belle_sip_stream_listening_point_setup_server_socket(belle_sip_stream_listening_point_t *obj, belle_sip_source_func_t on_new_connection_cb ){
	int port=belle_sip_uri_get_port(obj->base.listening_uri);
	
	obj->server_sock=create_server_socket(belle_sip_uri_get_host(obj->base.listening_uri),
		&port, &obj->base.ai_family);
	if (obj->server_sock==(belle_sip_socket_t)-1) return;
	belle_sip_uri_set_port(((belle_sip_listening_point_t*)obj)->listening_uri,port);
	if (obj->base.stack->dscp)
		belle_sip_socket_set_dscp(obj->server_sock,obj->base.ai_family,obj->base.stack->dscp);
	obj->source=belle_sip_socket_source_new(on_new_connection_cb,obj,obj->server_sock,BELLE_SIP_EVENT_READ,-1);
	belle_sip_main_loop_add_source(obj->base.stack->ml,obj->source);
}
示例#10
0
/*peek data from the master socket to see where it comes from, and dispatch to matching channel.
 * If the channel does not exist, create it */
static int on_udp_data(belle_sip_udp_listening_point_t *lp, unsigned int events){
	int err;
	unsigned char buf[4096];
	sockaddr_x addr;
	socklen_t addrlen=sizeof(sockaddr_x);

	if (events & BELLE_SIP_EVENT_READ){
		belle_sip_debug("udp_listening_point: data to read.");
		err=Xrecvfrom(lp->sock,(char*)buf,sizeof(buf),MSG_PEEK,(struct sockaddr*)&addr,&addrlen);
		if (err==-1){
			char *tmp=belle_sip_object_to_string((belle_sip_object_t*) ((belle_sip_listening_point_t*)lp)->listening_uri);
			belle_sip_error("udp_listening_point: recvfrom() failed on [%s], : [%s] reopening server socket"
					,tmp
					,belle_sip_get_socket_error_string());
			belle_sip_free(tmp);
			belle_sip_udp_listening_point_uninit(lp);
			/*clean all udp channels that are actually sharing the server socket with the listening points*/
			belle_sip_listening_point_clean_channels((belle_sip_listening_point_t*)lp);
			belle_sip_udp_listening_point_init_socket(lp);
		}else{
			belle_sip_channel_t *chan;
			struct addrinfo ai={0};
			belle_sip_address_remove_v4_mapping((struct sockaddr*)&addr,(struct sockaddr*)&addr,&addrlen);
			ai.ai_family=((struct sockaddr*)&addr)->sa_family;
			ai.ai_addr=(struct sockaddr*)&addr;
			ai.ai_addrlen=addrlen;
			chan=_belle_sip_listening_point_get_channel((belle_sip_listening_point_t*)lp,NULL,&ai);
			if (chan==NULL){
				/*TODO: should rather create the channel with real local ip and port and not just 0.0.0.0"*/
				chan=belle_sip_channel_new_udp_with_addr(lp->base.stack
														,lp->sock
														,belle_sip_uri_get_host(lp->base.listening_uri)
														,belle_sip_uri_get_port(lp->base.listening_uri)
														,&ai);
				if (chan!=NULL){
					belle_sip_message("udp_listening_point: new channel created to %s:%i",chan->peer_name,chan->peer_port);
					chan->lp=(belle_sip_listening_point_t*)lp; /*FIXME, exactly the same code as for channel creation from provider. might be good to factorize*/
					belle_sip_listening_point_add_channel((belle_sip_listening_point_t*)lp,chan);
				}
			}
			if (chan){
				/*notify the channel*/
				belle_sip_debug("Notifying udp channel, local [%s:%i]  remote [%s:%i]"
						,chan->local_ip
						,chan->local_port
						,chan->peer_name
						,chan->peer_port);
				belle_sip_channel_process_data(chan,events);
			}
		}
	}
	return BELLE_SIP_CONTINUE;
}
示例#11
0
static void test_escaped_username(void) {
	belle_sip_uri_t* L_tmp;
	belle_sip_uri_t *  L_uri = belle_sip_uri_parse("sip:toto%[email protected]");
	char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
	L_tmp = belle_sip_uri_parse(l_raw_uri);
	L_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
	belle_sip_free(l_raw_uri);
	CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_user(L_uri), "*****@*****.**");
	CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri), "titi.com");
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
}
示例#12
0
static void test_escaped_parameter(void) {
	belle_sip_uri_t* L_tmp;
	belle_sip_uri_t *  L_uri = belle_sip_uri_parse("sip:[email protected];pa%3Dram=aa%40bb:5060[];o%40");
	char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
	L_tmp = belle_sip_uri_parse(l_raw_uri);
	L_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
	belle_sip_free(l_raw_uri);
	CU_ASSERT_STRING_EQUAL(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(L_uri), "pa=ram"), "aa@bb:5060[]");
	CU_ASSERT_TRUE(belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(L_uri), "o@"));
	CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri), "titi.com");
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
}
示例#13
0
static void testCOMPLEXURI(void) {
	belle_sip_uri_t* L_tmp;
	belle_sip_uri_t *  L_uri = belle_sip_uri_parse("sip:[email protected]:5060;transport=tcp");
	char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
	L_tmp = belle_sip_uri_parse(l_raw_uri);
	L_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
	belle_sip_free(l_raw_uri);
	CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_user(L_uri), "toto");
	CU_ASSERT_EQUAL(belle_sip_uri_get_port(L_uri), 5060);
	CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri), "titi.com");
	CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_transport_param(L_uri), "tcp");
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
}
示例#14
0
static void testSIMPLEURI(void) {
	belle_sip_uri_t* L_tmp;
	belle_sip_uri_t* L_uri = belle_sip_uri_parse("sip:sip.titi.com");
	char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
	L_tmp = belle_sip_uri_parse(l_raw_uri);
	L_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
	belle_sip_free(l_raw_uri);

	CU_ASSERT_PTR_NULL(belle_sip_uri_get_user(L_uri));
	CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri), "sip.titi.com");
	CU_ASSERT_PTR_NULL(belle_sip_uri_get_transport_param(L_uri));
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
}
示例#15
0
static void test_escaped_passwd(void) {
	belle_sip_uri_t* L_tmp;
	belle_sip_uri_t *  L_uri = belle_sip_uri_parse("sips:%22jehan%22%20%3cjehan%40sip2.linphone.org:544%[email protected]");
	char* l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
	L_tmp = belle_sip_uri_parse(l_raw_uri);
	L_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
	belle_sip_free(l_raw_uri);
	CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_user(L_uri), "\"jehan\" <*****@*****.**");
	CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri), "sip.linphone.org");
	CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_user_password(L_uri), "544>");

	belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));

}
示例#16
0
static void testIPV6URI_base(const char* ip6) {
	belle_sip_uri_t* L_tmp;
	belle_sip_uri_t * L_uri;
	char* l_raw_uri;
	char uri[256];
	snprintf(uri,sizeof(uri),"sip:toto@[%s]:5060;transport=tcp",ip6);
	L_uri = belle_sip_uri_parse(uri);
	l_raw_uri = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_uri));
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
	L_tmp = belle_sip_uri_parse(l_raw_uri);
	L_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
	belle_sip_free(l_raw_uri);
	CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_user(L_uri), "toto");
	CU_ASSERT_EQUAL(belle_sip_uri_get_port(L_uri), 5060);
	CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_host(L_uri),ip6);
	CU_ASSERT_STRING_EQUAL(belle_sip_uri_get_transport_param(L_uri), "tcp");
	belle_sip_object_unref(BELLE_SIP_OBJECT(L_uri));
}
示例#17
0
static void add_initial_route_set(belle_sip_request_t *request, const MSList *list){
	const MSList *elem;
	for (elem=list;elem!=NULL;elem=elem->next){
		SalAddress *addr=(SalAddress*)elem->data;
		belle_sip_header_route_t *route;
		belle_sip_uri_t *uri;
		/*Optimization: if the initial route set only contains one URI which is the same as the request URI, ommit it*/
		if (elem==list && list->next==NULL){
			belle_sip_uri_t *requri=belle_sip_request_get_uri(request);
			/*skip the first route it is the same as the request uri*/
			if (strcmp(sal_address_get_domain(addr),belle_sip_uri_get_host(requri))==0 ){
				ms_message("Skipping top route of initial route-set because same as request-uri.");
				continue;
			}
		}

		route=belle_sip_header_route_create((belle_sip_header_address_t*)addr);
		uri=belle_sip_header_address_get_uri((belle_sip_header_address_t*)route);
		belle_sip_uri_set_lr_param(uri,1);
		belle_sip_message_add_header((belle_sip_message_t*)request,(belle_sip_header_t*)route);
	}
}
示例#18
0
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END

const char *belle_sip_listening_point_get_ip_address(const belle_sip_listening_point_t *lp){
	return belle_sip_uri_get_host(lp->listening_uri);
}
示例#19
0
static void process_response_event(void *user_ctx, const belle_sip_response_event_t *event){
	belle_sip_client_transaction_t* client_transaction = belle_sip_response_event_get_client_transaction(event);
	belle_sip_response_t* response = belle_sip_response_event_get_response(event);
	int response_code = belle_sip_response_get_status_code(response);
	if (!client_transaction) {
		ms_warning("Discarding stateless response [%i]",response_code);
		return;
	} else {
		SalOp* op = (SalOp*)belle_sip_transaction_get_application_data(BELLE_SIP_TRANSACTION(client_transaction));
		belle_sip_request_t* request=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction));
		belle_sip_header_contact_t* original_contact;
		belle_sip_header_address_t* contact_address=NULL;
		belle_sip_header_via_t* via_header;
		belle_sip_uri_t* contact_uri;
		unsigned int contact_port;
		const char* received;
		int rport;
		bool_t contact_updated=FALSE;
		char* new_contact;

		if (op->state == SalOpStateTerminated) {
			belle_sip_message("Op is terminated, nothing to do with this [%i]",response_code);
			return;
		}
		if (!op->base.remote_ua) {
			sal_op_set_remote_ua(op,BELLE_SIP_MESSAGE(response));
		}
		if (!op->base.call_id) {
			op->base.call_id=ms_strdup(belle_sip_header_call_id_get_call_id(BELLE_SIP_HEADER_CALL_ID(belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(response), belle_sip_header_call_id_t))));
		}

		sal_op_assign_recv_headers(op,(belle_sip_message_t*)response);
		
		if (op->callbacks.process_response_event) {

			if (op->base.root->nat_helper_enabled) {
				/*Fix contact if needed*/
				via_header= (belle_sip_header_via_t*)belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_VIA);
				received = belle_sip_header_via_get_received(via_header);
				rport = belle_sip_header_via_get_rport(via_header);
				if ((original_contact=belle_sip_message_get_header_by_type(request,belle_sip_header_contact_t))) {
					/*update contact with sent values in any cases*/
					contact_address=belle_sip_header_address_create(NULL,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(original_contact)));
					sal_op_set_contact_address(op,(const SalAddress *)contact_address);
					belle_sip_object_unref(contact_address);
				}
				if (sal_op_get_contact(op)){
					if (received!=NULL || rport>0) {
						contact_address = BELLE_SIP_HEADER_ADDRESS(sal_address_clone(sal_op_get_contact_address(op)));
						contact_uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(contact_address));
						if (received && strcmp(received,belle_sip_uri_get_host(contact_uri))!=0) {
							/*need to update host*/
							belle_sip_uri_set_host(contact_uri,received);
							contact_updated=TRUE;
						}
						contact_port =  belle_sip_uri_get_port(contact_uri);
						if (rport>0 && rport!=contact_port && (contact_port+rport)!=5060) {
							/*need to update port*/
							belle_sip_uri_set_port(contact_uri,rport);
							contact_updated=TRUE;
						}

						/*try to fix transport if needed (very unlikely)*/
						if (strcasecmp(belle_sip_header_via_get_transport(via_header),"UDP")!=0) {
							if (!belle_sip_uri_get_transport_param(contact_uri)
									||strcasecmp(belle_sip_uri_get_transport_param(contact_uri),belle_sip_header_via_get_transport(via_header))!=0) {
								belle_sip_uri_set_transport_param(contact_uri,belle_sip_header_via_get_transport_lowercase(via_header));
								contact_updated=TRUE;
							}
						} else {
							if (belle_sip_uri_get_transport_param(contact_uri)) {
								contact_updated=TRUE;
								belle_sip_uri_set_transport_param(contact_uri,NULL);
							}
						}
						if (contact_updated) {
							char* old_contact=belle_sip_object_to_string(BELLE_SIP_OBJECT(sal_op_get_contact_address(op)));
							new_contact=belle_sip_object_to_string(BELLE_SIP_OBJECT(contact_address));
							ms_message("Updating contact from [%s] to [%s] for [%p]",old_contact,new_contact,op);
							sal_op_set_contact_address(op,(const SalAddress *)contact_address);
							belle_sip_free(new_contact);
							belle_sip_free(old_contact);
						}
						if (contact_address)belle_sip_object_unref(contact_address);
					}
				}
			}
			
			/*handle authorization*/
			switch (response_code) {
				case 200: {
					break;
				}
				case 401:
				case 407:{
					
					/*belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(client_transaction),NULL);*//*remove op from trans*/
					if (op->state == SalOpStateTerminating && strcmp("BYE",belle_sip_request_get_method(request))!=0) {
						/*only bye are completed*/
						belle_sip_message("Op is in state terminating, nothing else to do ");
					} else {
						if (op->pending_auth_transaction){
							belle_sip_object_unref(op->pending_auth_transaction);
							op->pending_auth_transaction=NULL;
						}
						op->pending_auth_transaction=(belle_sip_client_transaction_t*)belle_sip_object_ref(client_transaction);
						sal_process_authentication(op);
						return;
					}
				}
			}
			op->callbacks.process_response_event(op,event);
		} else {
			ms_error("Unhandled event response [%p]",event);
		}
	}

}