Esempio n. 1
0
static int set_expires_from_trans(belle_sip_refresher_t* refresher) {
	belle_sip_transaction_t* transaction = BELLE_SIP_TRANSACTION(refresher->transaction);
	belle_sip_response_t*response=transaction->last_response;
	belle_sip_request_t*request=belle_sip_transaction_get_request(transaction);
	belle_sip_header_expires_t*  expires_header=belle_sip_message_get_header_by_type(request,belle_sip_header_expires_t);
	belle_sip_header_contact_t* contact_header;

	refresher->obtained_expires=-1;

	if (strcmp("REGISTER",belle_sip_request_get_method(request))==0
			|| expires_header /*if request has an expire header, refresher can always work*/) {

		if (expires_header)
			refresher->target_expires = belle_sip_header_expires_get_expires(expires_header);

		/*An "expires" parameter on the "Contact" header has no semantics for
		*   SUBSCRIBE and is explicitly not equivalent to an "Expires" header in
		*  a SUBSCRIBE request or response.
		*/
		if (strcmp("REGISTER",belle_sip_request_get_method(request))==0){
			if (!expires_header && (contact_header=belle_sip_message_get_header_by_type((belle_sip_message_t*)request,belle_sip_header_contact_t))){
				int ct_expires=belle_sip_header_contact_get_expires(BELLE_SIP_HEADER_CONTACT(contact_header));
				if (ct_expires!=-1) refresher->target_expires=ct_expires;
			}
			/*check in response also to get the obtained expires*/
			if ((contact_header=belle_sip_refresher_get_contact(refresher))!=NULL){
				/*matching contact, check for its possible expires param*/
				refresher->obtained_expires=belle_sip_header_contact_get_expires(BELLE_SIP_HEADER_CONTACT(contact_header));
			}
		}
		if (refresher->obtained_expires==-1){
			/*no contact with expire or not relevant, looking for Expires header*/
			if (response && (expires_header=(belle_sip_header_expires_t*)belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_EXPIRES))) {
				refresher->obtained_expires = belle_sip_header_expires_get_expires(expires_header);
			}
		}
		if (refresher->obtained_expires==-1) {
			belle_sip_message("Neither Expires header nor corresponding Contact header found, checking from original request");
			refresher->obtained_expires=refresher->target_expires;
		}else if (refresher->target_expires>0 && refresher->obtained_expires==0){
			const char* reason = response ? belle_sip_response_get_reason_phrase(response) : NULL;
			/*check this case because otherwise we are going to loop fast in sending refresh requests.*/
			/*"Test account created" is a special reason given by testers when we create temporary account.
			Since this is a bit of hack, we can ignore logging in that case*/
			if (reason && strcmp(reason, "Test account created") != 0) {
				belle_sip_warning("Server replied with 0 expires, what does that mean?");
			}
			/*suppose it's a server bug and assume our target_expires is understood.*/
			refresher->obtained_expires=refresher->target_expires;
		}
	} else if (strcmp("INVITE",belle_sip_request_get_method(request))==0) {
		belle_sip_error("Refresher does not support INVITE yet");
		return -1;
	} else {
		belle_sip_error("Refresher does not support [%s] yet",belle_sip_request_get_method(request));
		return -1;
	}
	return 0;
}
Esempio n. 2
0
static void register_refresher_listener (belle_sip_refresher_t* refresher
		,void* user_pointer
		,unsigned int status_code
		,const char* reason_phrase) {
	SalOp* op = (SalOp*)user_pointer;
	belle_sip_response_t* response=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(belle_sip_refresher_get_transaction(refresher)));
	ms_message("Register refresher [%i] reason [%s] for proxy [%s]",status_code,reason_phrase,sal_op_get_proxy(op));

	if (belle_sip_refresher_get_auth_events(refresher)) {
		if (op->auth_info) sal_auth_info_delete(op->auth_info);
		/*only take first one for now*/
		op->auth_info=sal_auth_info_create((belle_sip_auth_event_t*)(belle_sip_refresher_get_auth_events(refresher)->data));
	}
	sal_error_info_set(&op->error_info,SalReasonUnknown,status_code,reason_phrase,NULL);
	if (status_code>=200){
		sal_op_assign_recv_headers(op,(belle_sip_message_t*)response);
	}
	if(status_code == 200) {
		/*check service route rfc3608*/
		belle_sip_header_service_route_t* service_route;
		belle_sip_header_address_t* service_route_address=NULL;
		belle_sip_header_contact_t *contact = belle_sip_refresher_get_contact(refresher);
		if ((service_route=belle_sip_message_get_header_by_type(response,belle_sip_header_service_route_t))) {
			service_route_address=belle_sip_header_address_create(NULL,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(service_route)));
		}
		sal_op_set_service_route(op,(const SalAddress*)service_route_address);
		if (service_route_address) belle_sip_object_unref(service_route_address);

		sal_remove_pending_auth(op->base.root,op); /*just in case*/
		if (contact) {
			sal_op_set_contact_address(op,(SalAddress*)(BELLE_SIP_HEADER_ADDRESS(contact))); /*update contact with real value*/
		}
		op->base.root->callbacks.register_success(op,belle_sip_refresher_get_expires(op->refresher)>0);
	} else if (status_code>=400) {
		/* from rfc3608, 6.1.
				If the UA refreshes the registration, the stored value of the Service-
				   Route is updated according to the Service-Route header field of the
				   latest 200 class response.  If there is no Service-Route header field
				   in the response, the UA clears any service route for that address-
				   of-record previously stored by the UA.  If the re-registration
				   request is refused or if an existing registration expires and the UA
				   chooses not to re-register, the UA SHOULD discard any stored service
				   route for that address-of-record. */
		sal_op_set_service_route(op,NULL);
		sal_op_ref(op); /*take a ref while invoking the callback to make sure the operations done after are valid*/
		op->base.root->callbacks.register_failure(op);
		if (op->state!=SalOpStateTerminated && op->auth_info) {
			/*add pending auth*/
			sal_add_pending_auth(op->base.root,op);
			if (status_code==403 || status_code==401 || status_code==407 )
				op->base.root->callbacks.auth_failure(op,op->auth_info);
		}
		sal_op_unref(op);
	}
}