Beispiel #1
0
int new_pcontact(struct udomain* _d, str* _contact, struct pcontact_info* _ci, struct pcontact** _c)
{
	int i, has_rinstance=0;
	ppublic_t* ppublic_ptr;
	int is_default = 1, params_len;
	struct sip_uri sip_uri;
        char* p, *params, *sep;
        str rinstance = {0,0};
        
	*_c = (pcontact_t*)shm_malloc(sizeof(pcontact_t) + _contact->len + _ci->received_host.len + _ci->via_host.len);
	if (*_c == 0) {
		LM_ERR("no more shared memory\n");
		return -1;
	}
	memset(*_c, 0, sizeof(pcontact_t));

	LM_DBG("New contact [<%.*s>] with %d associated IMPUs in state: [%s]\n",
			_contact->len, _contact->s,
			_ci->num_public_ids,
			reg_state_to_string(_ci->reg_state));
        
        

        p = (char*)((struct pcontact*)(*_c) + 1);
        (*_c)->aor.s = p;
	memcpy(p, _contact->s, _contact->len);
        p += _contact->len;
	(*_c)->aor.len = _contact->len;
	(*_c)->domain = (str*)_d;

	if (parse_uri((*_c)->aor.s, (*_c)->aor.len, &sip_uri) != 0) {
		LM_ERR("unable to determine contact host from uri [%.*s\n", (*_c)->aor.len, (*_c)->aor.s);
		shm_free((*_c)->aor.s);
		shm_free(*_c);
		*_c = 0;
		return -2;
	}
        
        /* is there an rinstance param */
        LM_DBG("checking for rinstance");
        /*check for alias - NAT */
        params = sip_uri.sip_params.s;
        params_len = sip_uri.sip_params.len;
        while (params_len >= RINSTANCE_LEN) {
            if (strncmp(params, RINSTANCE, RINSTANCE_LEN) == 0) {
                has_rinstance = 1;
                break;
            }
            sep = memchr(params, 59 /* ; */, params_len);
            if (sep == NULL) {
                LM_DBG("no rinstance param\n");
                break;
            } else {
                params_len = params_len - (sep - params + 1);
                params = sep + 1;
            }
        }
        if (has_rinstance) {
            rinstance.s = params + RINSTANCE_LEN;
            rinstance.len = params_len - RINSTANCE_LEN;
            sep = (char*)memchr(rinstance.s, 59 /* ; */, rinstance.len);
            if (sep != NULL){
                rinstance.len = (sep-rinstance.s);
            }
        }
        (*_c)->rinstance.s = rinstance.s;
        (*_c)->rinstance.len = rinstance.len;
	(*_c)->contact_host.s = sip_uri.host.s;
	(*_c)->contact_host.len = sip_uri.host.len;
	(*_c)->contact_port = sip_uri.port_no?sip_uri.port_no:5060;
	(*_c)->contact_user.s = sip_uri.user.s;
	(*_c)->contact_user.len = sip_uri.user.len;

	(*_c)->expires = _ci->expires;
	(*_c)->reg_state = _ci->reg_state;

	// Add received Info:
	if (_ci->received_host.len > 0 && _ci->received_host.s) {
        (*_c)->received_host.s = p;
		memcpy(p, _ci->received_host.s, _ci->received_host.len);
                p += _ci->received_host.len;
		(*_c)->received_host.len = _ci->received_host.len;
		(*_c)->received_port = _ci->received_port;
		(*_c)->received_proto = _ci->received_proto;
	}
        
        if (_ci->via_host.len > 0 && _ci->via_host.s) {
            (*_c)->via_host.s = p;
            memcpy(p, _ci->via_host.s, _ci->via_host.len);
            p += _ci->via_host.len;
            (*_c)->via_host.len = _ci->via_host.len;
            (*_c)->via_port = _ci->via_port;
            (*_c)->via_proto = _ci->via_prot;
        }
        
        (*_c)->aorhash = get_aor_hash(_d, &_ci->via_host, _ci->via_port, _ci->via_prot);

	//setup public ids
	for (i=0; i<_ci->num_public_ids; i++) {
		if (i>0) is_default = 0; //only the first one is default - P-Associated-uri (first one is default)
		if (new_ppublic(&_ci->public_ids[i], is_default, &ppublic_ptr)!=0) {
			LM_ERR("unable to create new ppublic\n");
		} else {
			insert_ppublic(*_c, ppublic_ptr);
		}
	}
	//add the service routes
	if (_ci->num_service_routes > 0) {
		(*_c)->service_routes = shm_malloc(_ci->num_service_routes * sizeof(str));
		if (!(*_c)->service_routes) {
			LM_ERR("no more shm mem\n");
			goto out_of_memory;
		} else {
			for (i = 0; i < _ci->num_service_routes; i++) {
				STR_SHM_DUP((*_c)->service_routes[i], _ci->service_routes[i], "new_pcontact");
			}
			(*_c)->num_service_routes = _ci->num_service_routes;
		}
	}
        
        LM_DBG("New contact host:port [%.*s:%d]\n", (*_c)->contact_host.len, (*_c)->contact_host.s, (*_c)->contact_port);
        LM_DBG("New contact via host:port:proto: [%.*s:%d:%d]\n", (*_c)->via_host.len, (*_c)->via_host.s, (*_c)->via_port, (*_c)->via_proto);
        LM_DBG("New contact received host:port:proto: [%.*s:%d:%d]\n", (*_c)->received_host.len, (*_c)->received_host.s, (*_c)->received_port, (*_c)->received_proto);
        LM_DBG("New contact aorhash [%u]\n", (*_c)->aorhash);
        
	return 0;

out_of_memory:
	return -1;
}
Beispiel #2
0
int new_pcontact(struct udomain* _d, str* _contact, struct pcontact_info* _ci, struct pcontact** _c)
{
	int i;
	ppublic_t* ppublic_ptr;
	int is_default = 1;
	struct sip_uri sip_uri;


	*_c = (pcontact_t*)shm_malloc(sizeof(pcontact_t));
	if (*_c == 0) {
		LM_ERR("no more shared memory\n");
		return -1;
	}
	memset(*_c, 0, sizeof(pcontact_t));

	LM_DBG("New contact [<%.*s>] with %d associated IMPUs in state: [%s]\n",
			_contact->len, _contact->s,
			_ci->num_public_ids,
			reg_state_to_string(_ci->reg_state));

	(*_c)->aor.s = (char*) shm_malloc(_contact->len);
	if ((*_c)->aor.s == 0) {
		LM_ERR("no more shared memory\n");
		shm_free(*_c);
		*_c = 0;
		return -2;
	}
	memcpy((*_c)->aor.s, _contact->s, _contact->len);
	(*_c)->aor.len = _contact->len;
	(*_c)->domain = (str*)_d;

	if (parse_uri((*_c)->aor.s, (*_c)->aor.len, &sip_uri) != 0) {
		LM_ERR("unable to determine contact host from uri [%.*s\n", (*_c)->aor.len, (*_c)->aor.s);
		shm_free((*_c)->aor.s);
		shm_free(*_c);
		*_c = 0;
		return -2;
	}
	(*_c)->contact_host.s = sip_uri.host.s;
	(*_c)->contact_host.len = sip_uri.host.len;
	(*_c)->contact_port = sip_uri.port_no;
	(*_c)->contact_user.s = sip_uri.user.s;
	(*_c)->contact_user.len = sip_uri.user.len;

	if (hashing_type==0) {
		(*_c)->aorhash = core_hash(_contact, 0, 0);
	} else {
		(*_c)->aorhash = core_hash(&(*_c)->contact_host, 0, 0);
	}
	(*_c)->expires = _ci->expires;
	(*_c)->reg_state = _ci->reg_state;

	// Add received Info:
	if (_ci->received_host.len > 0 && _ci->received_host.s) {
		(*_c)->received_host.s = (char*) shm_malloc(_ci->received_host.len);
		if ((*_c)->received_host.s == 0) {
			LM_ERR("no more share memory\n");
			shm_free((*_c)->aor.s);
			shm_free(*_c);
			*_c = 0;
			return -2;
		}
		memcpy((*_c)->received_host.s, _ci->received_host.s, _ci->received_host.len);
		(*_c)->received_host.len = _ci->received_host.len;
		(*_c)->received_port = _ci->received_port;
		(*_c)->received_proto = _ci->received_proto;
	}

	//setup public ids
	for (i=0; i<_ci->num_public_ids; i++) {
		if (i>0) is_default = 0; //only the first one is default - P-Associated-uri (first one is default)
		if (new_ppublic(&_ci->public_ids[i], is_default, &ppublic_ptr)!=0) {
			LM_ERR("unable to create new ppublic\n");
		} else {
			insert_ppublic(*_c, ppublic_ptr);
		}
	}
	//add the service routes
	if (_ci->num_service_routes > 0) {
		(*_c)->service_routes = shm_malloc(_ci->num_service_routes * sizeof(str));
		if (!(*_c)->service_routes) {
			LM_ERR("no more shm mem\n");
			goto out_of_memory;
		} else {
			for (i = 0; i < _ci->num_service_routes; i++) {
				STR_SHM_DUP((*_c)->service_routes[i], _ci->service_routes[i], "new_pcontact");
			}
			(*_c)->num_service_routes = _ci->num_service_routes;
		}
	}
	return 0;

out_of_memory:
	return -1;
}
Beispiel #3
0
int update_pcontact(struct udomain* _d, struct pcontact_info* _ci, struct pcontact* _c) //TODO: should prob move this to pcontact
{
	int is_default = 1;
	ppublic_t* ppublic_ptr;
	int i;

	_c->reg_state = _ci->reg_state;

	if (_ci->expires > 0) {
		_c->expires = _ci->expires;
	}

	if (_ci->num_service_routes > 0 && _ci->service_routes) {
		//replace all existing service routes
		if (_c->service_routes) { //remove old service routes
			for (i=0; i<_c->num_service_routes; i++) {
				if (_c->service_routes[i].s)
					shm_free(_c->service_routes[i].s);
				shm_free(_c->service_routes);
				_c->service_routes=0;
				_c->num_service_routes=0;
			}
		}
		//now add the new service routes
		if (_ci->num_service_routes > 0) {
			_c->service_routes = shm_malloc(_ci->num_service_routes*sizeof(str));
			if (!_c->service_routes) {
				LM_ERR("no more shm mem trying to allocate [%ld bytes]\n", _ci->num_service_routes*sizeof(str));
				goto out_of_memory;
			} else {
				for (i=0; i<_ci->num_service_routes; i++) {
					STR_SHM_DUP(_c->service_routes[i], _ci->service_routes[i], "update_pcontact");
				}
				_c->num_service_routes = _ci->num_service_routes;
			}
		}
	}

	if (_ci->num_public_ids > 0 && _ci->public_ids) {
		if (_c->head) {
			LM_DBG("ppublic's already exist.... .not updating\n");
		} else {
			for (i = 0; i < _ci->num_public_ids; i++) {
				if (i > 0)
					is_default = 0; //only the first one is default - P-Associated-uri (first one is default)
				if (new_ppublic(&_ci->public_ids[i], is_default, &ppublic_ptr) != 0) {
					LM_ERR("unable to create new ppublic\n");
				} else {
					insert_ppublic(_c, ppublic_ptr);
				}
			}
		}
	}

	// update received info (if info is available):
	if (_ci->received_host.len > 0) {
		if (_c->received_host.s)
			shm_free(_c->received_host.s);
		STR_SHM_DUP(_c->received_host, _ci->received_host, "update_pcontact");
	}
	if (_ci->received_port > 0) _c->received_port = _ci->received_port;
	if (_ci->received_proto > 0) _c->received_proto = _ci->received_proto;

	//TODO: update path, etc
	run_ul_callbacks(PCSCF_CONTACT_UPDATE, _c);
	return 0;

out_of_memory:
	return -1;
}