struct proxy_l* mk_proxy(str* name, unsigned short port, unsigned short proto, int is_sips) { struct proxy_l* p; struct hostent* he; p=(struct proxy_l*) pkg_malloc(sizeof(struct proxy_l)); if (p==0){ ser_error=E_OUT_OF_MEM; LM_CRIT("pkg memory allocation failure\n"); goto error; } memset(p,0,sizeof(struct proxy_l)); p->name=*name; p->port=port; p->proto=proto; LM_DBG("doing DNS lookup...\n"); he = sip_resolvehost(name, &(p->port), &p->proto, is_sips, disable_dns_failover?0:&p->dn ); if (he==0){ ser_error=E_BAD_ADDRESS; LM_CRIT("could not resolve hostname: \"%.*s\"\n", name->len, name->s); pkg_free(p); goto error; } if (hostent_cpy(&(p->host), he)!=0){ free_dns_res( p ); pkg_free(p); goto error; } return p; error: return 0; }
struct proxy_l* mk_proxy(str* name, unsigned short port, int proto) { struct proxy_l* p; struct hostent* he; p=(struct proxy_l*) pkg_malloc(sizeof(struct proxy_l)); if (p==0){ ser_error=E_OUT_OF_MEM; LOG(L_CRIT, "ERROR: mk_proxy: memory allocation failure\n"); goto error; } memset(p,0,sizeof(struct proxy_l)); p->name=*name; p->port=port; p->proto=proto; DBG("DEBUG: mk_proxy: doing DNS lookup...\n"); he=sip_resolvehost(name, &(p->port), proto); if (he==0){ ser_error=E_BAD_ADDRESS; LOG(L_CRIT, "ERROR: mk_proxy: could not resolve hostname:" " \"%.*s\"\n", name->len, name->s); pkg_free(p); goto error; } if (hostent_cpy(&(p->host), he)!=0){ pkg_free(p); goto error; } p->ok=1; return p; error: return 0; }
/** * _remove - Delete an entire AOR entry or just one or more of its Contacts * Parameter format: _remove(domain, AOR[, Contact URI or plain hostname]) * * @udomain: (udomain_t *) * @aor_gp: address-of-record as a SIP URI (plain string or pvar) * @contact_gp: contact to be deleted or domain in front of multiple contacts * * @return: 1 on success, negative on failure */ int _remove(struct sip_msg *msg, char *udomain, char *aor_gp, char *contact_gp) { struct sip_uri puri; struct hostent delete_he, *he; urecord_t *record; ucontact_t *contact, *it; str uri, aor_user, delete_user = { NULL, 0 }; int err, count = 0; int delete_by_hostname = 0; unsigned short delete_port; memset(&delete_he, 0, sizeof delete_he); if (fixup_get_svalue(msg, (gparam_p)aor_gp, &uri) != 0) { LM_ERR("failed to get gparam_t value\n"); return E_UNSPEC; } if (extract_aor( &uri, &aor_user,0,0) < 0) { LM_ERR("failed to extract Address Of Record\n"); return E_BAD_URI; } ul.lock_udomain((udomain_t *)udomain, &aor_user); if (ul.get_urecord((udomain_t *)udomain, &aor_user, &record) != 0) { LM_DBG("no record '%.*s' found!\n", aor_user.len, aor_user.s); err = 1; goto out_unlock; } /* if no contact uri param is given, delete the whole urecord entry */ if (!contact_gp) { if (ul.delete_urecord((udomain_t *)udomain, &aor_user, record, 0) != 0) { LM_ERR("failed to delete urecord for aor '%.*s'\n", aor_user.len, aor_user.s); err = E_UNSPEC; goto out_unlock; } err = 1; goto out_unlock; } if (fixup_get_svalue(msg, (gparam_p)contact_gp, &uri) != 0) { LM_ERR("failed to retrieve value of contact pv\n"); err = E_UNSPEC; goto out_unlock; } /* minimum two-letters for the domain name */ if (uri.len < 5) { LM_ERR("Invalid domain given: '%.*s'\n", uri.len, uri.s); err = E_INVALID_PARAMS; goto out_unlock; } /* a domain/IP address was given instead of a SIP contact URI */ if (uri.s[0] != 's' || uri.s[1] != 'i' || uri.s[2] != 'p' || (uri.s[3] != ':' && (uri.s[3] != 's' || uri.s[4] != ':'))) { delete_by_hostname = 1; he = sip_resolvehost(&uri, &delete_port, NULL, 0, NULL); if (!he) { LM_ERR("cannot resolve given host: '%.*s'\n", uri.len, uri.s); err = E_UNSPEC; goto out_unlock; } LM_DBG("Delete by host: '%s'\n", inet_ntoa(*(struct in_addr *)(he->h_addr_list[0]))); } else { LM_DBG("parsing uri: %.*s\n", uri.len, uri.s); if (parse_uri(uri.s, uri.len, &puri) != 0) { LM_ERR("failed to parse contact uri: '%.*s'\n", uri.len, uri.s); err = E_BAD_URI; goto out_unlock; } delete_user = puri.user; he = sip_resolvehost(&puri.host, &delete_port, &puri.proto, 0, NULL); if (!he) { LM_ERR("cannot resolve given uri: '%.*s'\n", uri.len, uri.s); err = E_UNSPEC; goto out_unlock; } if (puri.port_no > 0) delete_port = puri.port_no; LM_DBG("Delete by contact: [ User %.*s | Host %s | Port %d ]\n", delete_user.len, delete_user.s, inet_ntoa(*(struct in_addr *)(he->h_addr_list[0])), delete_port); } if (hostent_cpy(&delete_he, he) != 0) { LM_ERR("no more pkg mem\n"); err = E_OUT_OF_MEM; goto out_unlock; } for (it = record->contacts; it; ) { contact = it; it = it->next; count++; LM_DBG("parsing contact uri '%.*s'\n", contact->c.len, contact->c.s); if (parse_uri(contact->c.s, contact->c.len, &puri) != 0) { LM_ERR("failed to parse contact uri: '%.*s'\n", contact->c.len, contact->c.s); err = E_BAD_URI; goto out_unlock; } /* if necessary, solve the next_hop towards the contact */ he = sip_resolvehost(&contact->next_hop.name, &contact->next_hop.port, &contact->next_hop.proto, 0, NULL); if (!he) { LM_ERR("failed to resolve next hop of contact '%.*s'\n", contact->c.len, contact->c.s); continue; } LM_DBG("Contact: [ User %.*s | Host %s | Port %d ]\n", puri.user.len, puri.user.s, inet_ntoa(*(struct in_addr *)(he->h_addr_list[0])), puri.port_no); if (delete_by_hostname) { if (!memcmp(delete_he.h_addr_list[0], he->h_addr_list[0], he->h_length)) { ul.delete_ucontact(record, contact, 0); count--; } } else { if (delete_user.len == puri.user.len && delete_port == puri.port_no && !memcmp(delete_he.h_addr_list[0], he->h_addr_list[0], he->h_length) && !memcmp(delete_user.s, puri.user.s, puri.user.len)) { ul.delete_ucontact(record, contact, 0); count--; } } } err = 1; /* remove the AOR if no more contacts are attached */ if (count == 0) { if (ul.delete_urecord((udomain_t *)udomain, &aor_user, record, 0) != 0) { LM_ERR("failed to delete urecord for aor '%.*s'\n", aor_user.len, aor_user.s); err = 1; } } out_unlock: ul.unlock_udomain((udomain_t *)udomain, &aor_user); free_hostent(&delete_he); return err; }
/** * _remove - Delete an entire AOR entry or one or more of its Contacts * * @domain: logical domain name (usually name of location table) * @aor_gp: address-of-record as a SIP URI (plain string or pvar) * @contact_gp: contact URI to be deleted * @next_hop_gp: IP/domain in front of contacts to be deleted * @sip_instance_gp: delete contacts with given "+sip_instance" * * @return: 1 on success, negative on failure */ int _remove(struct sip_msg *msg, void *udomain, str *aor_uri, str *match_ct, str *match_next_hop, str *match_sin) { struct hostent delete_nh_he, *he; urecord_t *record; ucontact_t *contact, *it; str aor_user; int ret = 1; unsigned short delete_port = 0; if (extract_aor(aor_uri, &aor_user, 0, 0) < 0) { LM_ERR("failed to extract Address Of Record\n"); return E_BAD_URI; } ul.lock_udomain((udomain_t *)udomain, &aor_user); if (ul.get_urecord((udomain_t *)udomain, &aor_user, &record) != 0) { LM_DBG("no record '%.*s' found!\n", aor_user.len, aor_user.s); goto out_unlock; } /* without any additional filtering, delete the whole urecord entry */ if (!match_ct && !match_next_hop && !match_sin) { if (ul.delete_urecord((udomain_t *)udomain, &aor_user, record, 0) != 0) { LM_ERR("failed to delete urecord for aor '%.*s'\n", aor_user.len, aor_user.s); ret = E_UNSPEC; goto out_unlock; } goto out_unlock; } if (match_ct && match_ct->s) LM_DBG("Delete by contact: [%.*s]\n", match_ct->len, match_ct->s); if (match_sin && match_sin->s) LM_DBG("Delete by sip_instance: [%.*s]\n", match_sin->len, match_sin->s); if (match_next_hop->s) { he = sip_resolvehost(match_next_hop, &delete_port, NULL, 0, NULL); if (!he) { LM_ERR("cannot resolve given host: '%.*s'\n", match_next_hop->len, match_next_hop->s); ret = E_UNSPEC; goto out_unlock; } LM_DBG("Delete by host: '%s'\n", inet_ntoa(*(struct in_addr *)(he->h_addr_list[0]))); if (hostent_cpy(&delete_nh_he, he) != 0) { LM_ERR("no more pkg mem\n"); ret = E_OUT_OF_MEM; goto out_unlock; } } for (it = record->contacts; it; ) { contact = it; it = it->next; LM_DBG("checking contact uri '%.*s'\n", contact->c.len, contact->c.s); he = sip_resolvehost(&contact->next_hop.name, &contact->next_hop.port, &contact->next_hop.proto, 0, NULL); if (!he) { LM_ERR("failed to resolve next hop %.*s of contact '%.*s'\n", contact->next_hop.name.len, contact->next_hop.name.s, contact->c.len, contact->c.s); continue; } LM_DBG("next hop is [%.*s] resolving to [%s]\n", contact->next_hop.name.len, contact->next_hop.name.s, inet_ntoa(*(struct in_addr *)(he->h_addr_list[0]))); if (match_next_hop->s) { if (memcmp(delete_nh_he.h_addr_list[0], he->h_addr_list[0], he->h_length)) continue; } if (match_ct->s) { if (match_ct->len != contact->c.len || memcmp(match_ct->s, contact->c.s, match_ct->len)) continue; } if (match_sin->s) { if (str_strcmp(match_sin, &contact->instance)) continue; } ul.delete_ucontact(record, contact, 0); } ul.release_urecord(record, 0); out_unlock: ul.unlock_udomain((udomain_t *)udomain, &aor_user); if (match_next_hop->s) free_hostent(&delete_nh_he); return ret; }