예제 #1
0
static int publish_presentity(struct sip_msg* _m, struct pdomain* _d, struct presentity* presentity)
{
	event_t *parsed_event = NULL;
	int event_package = EVENT_OTHER;
	str callid = STR_STATIC_INIT("???");
	int res;
	
	if (_m->event) 
		parsed_event = (event_t *)_m->event->parsed;
	if (parsed_event)
		event_package = parsed_event->parsed;

	LOG(L_DBG, "publish_presentity: event_package=%d -1-\n", event_package);
	switch (event_package) {
		case EVENT_PRESENCE: 
			res = publish_presence(_m, presentity);
			break;
		default:
			if (_m->callid)	callid = _m->callid->body;
			LOG(L_WARN, "publish_presentity: no handler for event_package=%d"
					" callid=%.*s\n", event_package, callid.len, ZSW(callid.s));
			paerrno = PA_EVENT_UNSUPP;
			res = -1;
	}

	return res;
}
예제 #2
0
void bonjour_dns_sd_update_buddy_icon(BonjourDnsSd *data) {
	PurpleStoredImage *img;

	if ((img = purple_buddy_icons_find_account_icon(data->account))) {
		gconstpointer avatar_data;
		gsize avatar_len;

		avatar_data = purple_imgstore_get_data(img);
		avatar_len = purple_imgstore_get_size(img);

		if (_mdns_set_buddy_icon_data(data, avatar_data, avatar_len)) {
			/* The filename is a SHA-1 hash of the data (conveniently what we need) */
			const char *p, *filename = purple_imgstore_get_filename(img);

			g_free(data->phsh);
			data->phsh = NULL;

			/* Get rid of the extension */
			p = strchr(filename, '.');
			if (p)
				data->phsh = g_strndup(filename, p - filename);
			else
				purple_debug_error("bonjour", "account buddy icon returned unexpected filename (%s)"
								"; unable to extract hash. Clearing buddy icon\n", filename);

			/* Update our TXT record */
			publish_presence(data, PUBLISH_UPDATE);
		}

		purple_imgstore_unref(img);
	} else {
		/* We need to do this regardless of whether data->phsh is set so that we
		 * cancel any icons that are currently in the process of being set */
		_mdns_set_buddy_icon_data(data, NULL, 0);
		if (data->phsh != NULL) {
			/* Clear the buddy icon */
			g_free(data->phsh);
			data->phsh = NULL;
			/* Update our TXT record */
			publish_presence(data, PUBLISH_UPDATE);
		}
	}
}
예제 #3
0
/**
 * Send a new dns-sd packet updating our status.
 */
void bonjour_dns_sd_send_status(BonjourDnsSd *data, const char *status, const char *status_message) {
	g_free(data->status);
	g_free(data->msg);

	data->status = g_strdup(status);
	data->msg = g_strdup(status_message);

	/* Update our text record with the new status */
	publish_presence(data, PUBLISH_UPDATE);
}
예제 #4
0
/**
 * Advertise our presence within the dns-sd daemon and start browsing
 * for other bonjour peers.
 */
gboolean bonjour_dns_sd_start(BonjourDnsSd *data) {

	/* Initialize the dns-sd data and session */
	if (!_mdns_init_session(data))
		return FALSE;

	/* Publish our bonjour IM client at the mDNS daemon */
	if (!publish_presence(data, PUBLISH_START))
		return FALSE;

	/* Advise the daemon that we are waiting for connections */
	if (!_mdns_browse(data)) {
		purple_debug_error("bonjour", "Unable to get service.\n");
		return FALSE;
	}

	return TRUE;
}
예제 #5
0
void t_phone_user::handle_response_register(t_response *r, bool &re_register) {
	t_contact_param *c;
	unsigned long expires;
	unsigned long e;
	bool first_failure, first_success;

	re_register = false;
	
	// Store the destination IP address/port of the REGISTER message.
	// To this destination the NAT keep alive packets will be sent.
	t_request *req = r_register->get_request();
	req->get_destination(register_ip_port, *user_config);

        switch(r->get_class()) {
        case R_2XX:
                last_reg_failed = false;

                // Stop registration timer if one was running
                phone->stop_timer(PTMR_REGISTRATION, this);

                c = r->hdr_contact.find_contact(req->hdr_contact.contact_list.front().uri);
                if (!c) {               	
	               	if (!user_config->get_allow_missing_contact_reg()) {
				is_registered = false;

	              		log_file->write_report(
        	       			"Contact header is missing.",
               				"t_phone_user::handle_response_register",
               				LOG_NORMAL, LOG_WARNING);
				
				ui->cb_invalid_reg_resp(user_config,
					r, "Contact header missing.");
				cleanup_registration_data();
				return;
                        } else {
                        	log_file->write_report(
                        		"Cannot find matching contact header.",
                        		"t_phone_user::handle_response_register",
                        		LOG_NORMAL, LOG_DEBUG);
                        }
                }

                if (c && c->is_expires_present() && c->get_expires() != 0) {
                        expires = c->get_expires();
                }
                else if (r->hdr_expires.is_populated() &&
                         r->hdr_expires.time != 0)
                {
                        expires = r->hdr_expires.time;
                }
                else {	
               		if (!user_config->get_allow_missing_contact_reg()) {
				is_registered = false;
				
               			log_file->write_report(
               				"Expires parameter/header mising.",
               				"t_phone_user::handle_response_register",
               				LOG_NORMAL, LOG_WARNING);
				
				ui->cb_invalid_reg_resp(user_config,
					r, "Expires parameter/header mising.");
				cleanup_registration_data();
				return;
                        }
                        
                        expires = user_config->get_registration_time();
                        
                        // Assume a default expiration of 3600 sec if no expiry
                        // time was returned.
                        if (expires == 0) expires = 3600;
                }

                // Start new registration timer
                // The maximum value of the timer can be 2^32-1 s
                // The maximum timer that we can handle however is 2^31-1 ms
                e = (expires > 2147483 ? 2147483 : expires);
                phone->start_set_timer(PTMR_REGISTRATION, e * 1000, this);
		// Save the Service-Route if present the response contains any

		// RFC 3608 6
		// Collect the service route to route later initial requests.
		if (r->hdr_service_route.is_populated()) {
			service_route = r->hdr_service_route.route_list;
			log_file->write_header("t_phone_user::handle_response_register");
			log_file->write_raw("Store service route:\n");
			for (list<t_route>::const_iterator it = service_route.begin();
			     it != service_route.end(); ++it)
			{
				log_file->write_raw(it->encode());
				log_file->write_endl();
			}
			log_file->write_footer();
		} else {
			if (!service_route.empty())
			{
				log_file->write_report("Clear service route.",
					"t_phone_user::handle_response_register");
				service_route.clear();
			}
		}

		first_success = !is_registered;
                is_registered = true;
		ui->cb_register_success(user_config, r, expires, first_success);
		
		// Start sending NAT keepalive packets when STUN is used
		// (or in case of symmetric firewall)
		if (use_nat_keepalive && id_nat_keepalive == 0) {
			// Just start the NAT keepalive timer. The REGISTER
			// message itself created the NAT binding. So there is
			// no need to send a NAT keep alive packet now.
			phone->start_timer(PTMR_NAT_KEEPALIVE, this);
		}
		
		// Start sending TCP ping packets on persistent TCP connections.
		if (user_config->get_persistent_tcp() && id_tcp_ping == 0) {
			phone->start_timer(PTMR_TCP_PING, this);
		}
		
		// Registration succeeded. If sollicited MWI is provisioned
		// and no MWI subscription is established yet, then subscribe
		// to MWI.
		if (user_config->get_mwi_sollicited() && !mwi_auto_resubscribe) {
			subscribe_mwi();
		}
		
		// Publish presence state if not yet published.
		if (user_config->get_pres_publish_startup() && 
		    presence_epa->get_epa_state() == t_epa::EPA_UNPUBLISHED)
		{
			publish_presence(t_presence_state::ST_BASIC_OPEN);
		}
		
		// Subscribe to buddy list presence if not done so.
		if (!buddy_list->get_is_subscribed()) {
			subscribe_presence();
		}

                break;
        case R_4XX:
                is_registered = false;

                // RFC 3261 10.3
                if (r->code == R_423_INTERVAL_TOO_BRIEF) {
                        if (!r->hdr_min_expires.is_populated()) {
                                // Violation of RFC 3261 10.3 item 7
				log_file->write_report("Min-Expires header missing from 423 response.",
					"t_phone_user::handle_response_register",
					LOG_NORMAL, LOG_WARNING);
                                ui->cb_invalid_reg_resp(user_config, r,
                                        "Min-Expires header missing.");
				cleanup_registration_data();
                                return;
                        }

                        if (r->hdr_min_expires.time <= registration_time) {
                                // Wrong Min-Expires time
                                string s = "Min-Expires (";
                                s += ulong2str(r->hdr_min_expires.time);
                                s += ") is smaller than the requested ";
                                s += "time (";
                                s += ulong2str(registration_time);
                                s += ")";
                                log_file->write_report(s, "t_phone_user::handle_response_register",
                                	LOG_NORMAL, LOG_WARNING);
                                ui->cb_invalid_reg_resp(user_config, r, s);
				cleanup_registration_data();
                                return;
                        }

                        // Automatic re-register with Min-Expires time
                        registration_time = r->hdr_min_expires.time;
                        re_register = true;
                        // No need to cleanup STUN data as a new REGISTER will be
                        // sent immediately.
                        return;
                }

		// If authorization failed, then do not start the continuous
		// re-attempts. When authorization fails the user is asked
		// for credentials (in GUI). So the user cancelled these
		// questions and should not be bothered with the same question
		// again every 30 seconds. The user does not have the
		// credentials.
		if (r->code == R_401_UNAUTHORIZED ||
		    r->code == R_407_PROXY_AUTH_REQUIRED)
		{
			last_reg_failed = true;
			ui->cb_register_failed(user_config, r, true);			
	
			cleanup_registration_data();
			return;
		}

                // fall thru
        default:
		first_failure = !last_reg_failed;
                last_reg_failed = true;
                is_registered = false;
                authorizor.remove_from_cache(""); // Clear credentials cache
		ui->cb_register_failed(user_config, r, first_failure);
                phone->start_set_timer(PTMR_REGISTRATION, DUR_REG_FAILURE * 1000, this);

		cleanup_registration_data();
        }
}