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; }
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; }
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; }