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; }
/* same as add_proxy, but it doesn't add the proxy to the list * uses also SRV if possible & port==0 (quick hack) works in shared memory */ struct proxy_l* mk_shm_proxy(str* name, unsigned short port, unsigned short proto, int is_sips) { struct proxy_l* p; struct hostent* he; p=(struct proxy_l*) shm_malloc(sizeof(struct proxy_l)); if (p==0){ ser_error=E_OUT_OF_MEM; LM_CRIT("shm 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); shm_free(p); goto error; } if (hostent_shm_cpy(&(p->host), he)!=0){ free_dns_res( p ); shm_free(p); goto error; } return p; error: return 0; }
int update_sock_struct_from_via( union sockaddr_union* to, struct sip_msg* msg, struct via_body* via ) { struct hostent* he; str* name; int err; unsigned short port; port=0; if(via==msg->via1){ /* _local_ reply, we ignore any rport or received value * (but we will send back to the original port if rport is * present) */ if ((msg->msg_flags&FL_FORCE_RPORT)||(via->rport)) port=msg->rcv.src_port; else port=via->port; if(via->maddr) name= &(via->maddr->value); else name=&(via->host); /* received=ip in 1st via is ignored (it's not added by us so it's bad) */ }else{ /* "normal" reply, we use rport's & received value if present */ if (via->rport && via->rport->value.s){ LM_DBG("using 'rport'\n"); port=str2s(via->rport->value.s, via->rport->value.len, &err); if (err){ LM_NOTICE("bad rport value(%.*s)\n", via->rport->value.len,via->rport->value.s); port=0; } } if (via->maddr){ name= &(via->maddr->value); if (port==0) port=via->port?via->port:SIP_PORT; } else if (via->received){ LM_DBG("using 'received'\n"); name=&(via->received->value); /* making sure that we won't do SRV lookup on "received" */ if (port==0) port=via->port?via->port:SIP_PORT; }else{ LM_DBG("using via host\n"); name=&(via->host); if (port==0) port=via->port; } } LM_DBG("trying SRV lookup\n"); he=sip_resolvehost(name, &port, &via->proto, 0, 0); if (he==0){ LM_NOTICE("resolve_host(%.*s) failure\n", name->len, name->s); return -1; } hostent2su( to, he, 0, port); return 1; }
int update_sock_struct_from_via( union sockaddr_union* to, struct sip_msg* msg, struct via_body* via ) { struct hostent* he; str* name; int err; unsigned short port; char proto; port=0; if(via==msg->via1){ /* _local_ reply, we ignore any rport or received value * (but we will send back to the original port if rport is * present) */ if ((msg->msg_flags&FL_FORCE_RPORT)||(via->rport)) port=msg->rcv.src_port; else port=via->port; name=&(via->host); /* received=ip in 1st via is ignored (it's * not added by us so it's bad) */ }else{ /* "normal" reply, we use rport's & received value if present */ if (via->rport && via->rport->value.s){ LM_DBG("using 'rport'\n"); port=str2s(via->rport->value.s, via->rport->value.len, &err); if (err){ LM_ERR("bad rport value(%.*s)\n", via->rport->value.len, via->rport->value.s); port=0; } } if (via->received){ LM_DBG("using 'received'\n"); name=&(via->received->value); /* making sure that we won't do SRV lookup on "received" * (possible if no DNS_IP_HACK is used)*/ if (port==0) port=via->port?via->port:SIP_PORT; }else{ LM_DBG("using via host\n"); name=&(via->host); if (port==0) port=via->port; } } /* we do now a malloc/memcpy because gethostbyname loves \0-terminated * strings; but only if host is not null terminated (host.s[len] will * always be ok for a via) */ LM_DBG("trying SRV lookup\n"); proto=via->proto; he=sip_resolvehost(name, &port, &proto); if (he==0){ LM_NOTICE("resolve_host(%.*s) failure\n", name->len, name->s); return -1; } hostent2su(to, he, 0, port); return 1; }
int rl_add_repl_dst(modparam_t type, void *val) { char *host; int hlen, port; int proto; struct hostent *he; str st; rl_dests = pkg_realloc(rl_dests, (rl_dests_nr + 1) * sizeof(rl_repl_dst_t)); if (!rl_dests) { LM_ERR("oom\n"); return -1; } if (parse_phostport(val, strlen(val), &host, &hlen, &port, &proto) < 0) { LM_ERR("Bad replication destination IP!\n"); return -1; } if (proto == PROTO_NONE) proto = PROTO_UDP; st.s = host; st.len = hlen; he = sip_resolvehost(&st, (unsigned short *)&port, (unsigned short *)&proto, 0, 0); if (!he) { LM_ERR("Cannot resolve host: %.*s\n", hlen, host); return -1; } if (!port) { LM_ERR("no port specified for host %.*s\n", hlen, host); return -1; } rl_dests[rl_dests_nr].id = rl_dests_nr; rl_dests[rl_dests_nr].dst.s = (char *)val; rl_dests[rl_dests_nr].dst.len = strlen(rl_dests[rl_dests_nr].dst.s); hostent2su(&rl_dests[rl_dests_nr].to, he, 0, port); LM_DBG("Added destination <%.*s>\n", rl_dests[rl_dests_nr].dst.len, rl_dests[rl_dests_nr].dst.s); /* init done */ rl_dests_nr++; return 1; }
int natping_contact(str contact, struct dest_info *dst) { struct sip_uri curi; struct hostent *he; str p_method, p_from; if (natping_method != NULL) { /* XXX: add send_sock handling */ p_method.s = natping_method; p_method.len = strlen(p_method.s); p_from.s = "sip:registrar"; /* XXX */ p_from.len = strlen(p_from.s); if (tmb.t_request(&p_method, &contact, &contact, &p_from, NULL, NULL, NULL, NULL, NULL) == -1) { LOG(L_ERR, "ERROR: nathelper::natping(): t_request() failed\n"); return -1; } } else { if (parse_uri(contact.s, contact.len, &curi) < 0) { LOG(L_ERR, "ERROR: nathelper::natping: can't parse contact uri\n"); return -1; } if (curi.proto != PROTO_UDP && curi.proto != PROTO_NONE) return -1; if (curi.port_no == 0) curi.port_no = SIP_PORT; he = sip_resolvehost(&curi.host, &curi.port_no, PROTO_UDP); if (he == NULL){ LOG(L_ERR, "ERROR: nathelper::natping: can't resolve host\n"); return -1; } hostent2su(&dst->to, he, 0, curi.port_no); if (dst->send_sock == NULL) { dst->send_sock = force_socket ? force_socket : get_send_socket(0, &dst->to, PROTO_UDP); } if (dst->send_sock == NULL) { LOG(L_ERR, "ERROR: nathelper::natping: can't get sending socket\n"); return -1; } dst->proto=PROTO_UDP; udp_send(dst, (char *)sbuf, sizeof(sbuf)); } return 1; }
static int add_replication_dest(modparam_t type, void *val) { struct replication_dest *rd; char *host; int hlen, port; int proto; struct hostent *he; str st; rd = pkg_malloc(sizeof(*rd)); memset(rd, 0, sizeof(*rd)); if (parse_phostport(val, strlen(val), &host, &hlen, &port, &proto) < 0) { LM_ERR("Bad replication destination IP!\n"); return -1; } if (proto == PROTO_NONE) proto = PROTO_UDP; if (proto != PROTO_UDP) { LM_ERR("Dialog replication only supports UDP packets!\n"); return -1; } st.s = host; st.len = hlen; he = sip_resolvehost(&st, (unsigned short *)&port, (unsigned short *)&proto, 0, 0); if (!he) { LM_ERR("Cannot resolve host: %.*s\n", hlen, host); return -1; } hostent2su(&rd->to, he, 0, port); rd->next = replication_dests; replication_dests = rd; return 1; }
/* resolve host, port, proto using sip rules (e.g. use SRV if port=0 a.s.o) * and write the result in the sockaddr_union to * returns -1 on error (resolve failed), 0 on success */ int sip_hostport2su(union sockaddr_union* su, str* name, unsigned short port, char* proto) { struct hostent* he; he=sip_resolvehost(name, &port, proto); if (he==0){ ser_error=E_BAD_ADDRESS; LOG(L_ERR, "ERROR: sip_hostport2su: could not resolve hostname:" " \"%.*s\"\n", name->len, name->s); goto error; } /* port filled by sip_resolvehost if empty*/ if (hostent2su(su, he, 0, port)<0){ ser_error=E_BAD_ADDRESS; goto error; } return 0; error: return -1; }
/* * Check if from user is a valid enum based user, and check to make sure * that the src_ip == an srv record that maps to the enum from user. */ int is_from_user_enum_2(struct sip_msg* _msg, char* _suffix, char* _service) { struct ip_addr addr; struct hostent* he; unsigned short zp; unsigned short proto; char *user_s; int user_len, i, j; char name[MAX_DOMAIN_SIZE]; char uri[MAX_URI_SIZE]; struct sip_uri *furi; struct sip_uri luri; struct rdata* head; str* suffix; str* service; struct rdata* l; struct naptr_rdata* naptr; str pattern, replacement, result; char string[17]; if (parse_from_header(_msg) < 0) { LM_ERR("Failed to parse From header\n"); return -1; } if(_msg->from==NULL || get_from(_msg)==NULL) { LM_DBG("No From header\n"); return -1; } if ((furi = parse_from_uri(_msg)) == NULL) { LM_ERR("Failed to parse From URI\n"); return -1; } suffix = (str*)_suffix; service = (str*)_service; if (is_e164(&(furi->user)) == -1) { LM_ERR("From URI user is not an E164 number\n"); return -1; } /* assert: the from user is a valid formatted e164 string */ user_s = furi->user.s; user_len = furi->user.len; j = 0; for (i = user_len - 1; i > 0; i--) { name[j] = user_s[i]; name[j + 1] = '.'; j = j + 2; } memcpy(name + j, suffix->s, suffix->len + 1); head = get_record(name, T_NAPTR); if (head == 0) { LM_DBG("No NAPTR record found for %s.\n", name); return -3; } /* we have the naptr records, loop and find an srv record with */ /* same ip address as source ip address, if we do then true is returned */ for (l = head; l; l = l->next) { if (l->type != T_NAPTR) continue; /*should never happen*/ naptr = (struct naptr_rdata*)l->rdata; if (naptr == 0) { LM_ERR("Null rdata in DNS response\n"); free_rdata_list(head); return -4; } LM_DBG("ENUM query on %s: order %u, pref %u, flen %u, flags " "'%.*s', slen %u, services '%.*s', rlen %u, " "regexp '%.*s'\n", name, naptr->order, naptr->pref, naptr->flags_len, (int)(naptr->flags_len), ZSW(naptr->flags), naptr->services_len, (int)(naptr->services_len), ZSW(naptr->services), naptr->regexp_len, (int)(naptr->regexp_len), ZSW(naptr->regexp)); if (sip_match(naptr, service) != 0) { if (parse_naptr_regexp(&(naptr->regexp[0]), naptr->regexp_len, &pattern, &replacement) < 0) { free_rdata_list(head); /*clean up*/ LM_ERR("Parsing of NAPTR regexp failed\n"); return -5; } #ifdef LATER if ((pattern.len == 4) && (strncmp(pattern.s, "^.*$", 4) == 0)) { LM_DBG("Resulted in replacement: '%.*s'\n", replacement.len, ZSW(replacement.s)); retval = set_uri(_msg, replacement.s, replacement.len); free_rdata_list(head); /*clean up*/ return retval; } #endif result.s = &(uri[0]); result.len = MAX_URI_SIZE; /* Avoid making copies of pattern and replacement */ pattern.s[pattern.len] = (char)0; replacement.s[replacement.len] = (char)0; /* We have already checked the size of _msg->parsed_uri.user.s */ memcpy(&(string[0]), user_s, user_len); string[user_len] = (char)0; if (reg_replace(pattern.s, replacement.s, &(string[0]), &result) < 0) { pattern.s[pattern.len] = '!'; replacement.s[replacement.len] = '!'; LM_ERR("Regexp replace failed\n"); free_rdata_list(head); /*clean up*/ return -6; } LM_DBG("Resulted in replacement: '%.*s'\n", result.len, ZSW(result.s)); if(parse_uri(result.s, result.len, &luri) < 0) { LM_ERR("Parsing of URI <%.*s> failed\n", result.len, result.s); free_rdata_list(head); /*clean up*/ return -7; } pattern.s[pattern.len] = '!'; replacement.s[replacement.len] = '!'; zp = 0; proto = PROTO_NONE; he = sip_resolvehost(&luri.host, &zp, &proto, (luri.type==SIPS_URI_T)?1:0 , 0); hostent2ip_addr(&addr, he, 0); if(ip_addr_cmp(&addr, &_msg->rcv.src_ip)) { free_rdata_list(head); return(1); } } } free_rdata_list(head); /*clean up*/ LM_DBG("FAIL\n"); /* must not have found the record */ return(-8); }
/* add a new information in the backend list*/ int add_info(table_entry_t **data, int *int_vals, unsigned long last_attempt, char **str_vals) { char *host; int hlen, port; struct hostent *he; struct module_list *module; struct module_timestamp *new_timestamp; uint64_t ctime; int proto; int cluster_id; table_entry_t *head = NULL; table_entry_info_t *info_head = NULL; table_entry_value_t *value = NULL; str st; char *url; char *description; if (int_vals[INT_VALS_MACHINE_ID_COL] == server_id) { return 0; } url = str_vals[STR_VALS_URL_COL]; if (url == NULL) { LM_ERR("no path specified\n"); goto error; } if (parse_phostport(url, strlen(url), &host, &hlen, &port, &proto) < 0) { LM_ERR("Bad replication destination IP!\n"); goto error; } if (proto == PROTO_NONE) proto = PROTO_UDP; cluster_id = int_vals[INT_VALS_CLUSTER_ID_COL]; for (head = *data; head; head = head->next) { if (head->cluster_id == cluster_id) { info_head = head->info; while (info_head && info_head->proto != proto) info_head = info_head->next; if (!info_head) { info_head = shm_malloc(sizeof *info_head); if (!info_head) { LM_ERR("no more shm memory\n"); goto error; } info_head->proto = proto; info_head->next = head->info; info_head->value = NULL; head->info = info_head; } break; } } if (!head) { head = shm_malloc(sizeof *head); if (!head) { LM_ERR("no more shm memory\n"); goto error; } head->cluster_id = cluster_id; head->info = shm_malloc(sizeof(table_entry_info_t)); if (!head->info) { LM_ERR("no more shm memory\n"); goto error; } head->info->proto = proto; head->info->next = NULL; head->info->value = NULL; info_head = head->info; info_head->proto = proto; head->next = *data; *data = head; } /* allocating memory*/ value = shm_malloc(sizeof *value); if (!value) { LM_ERR("no more shm memory\n"); goto error; } value->machine_id = int_vals[INT_VALS_MACHINE_ID_COL]; value->id = int_vals[INT_VALS_CLUSTERER_ID_COL]; value->state = int_vals[INT_VALS_STATE_COL]; value->last_attempt = last_attempt; value->duration = int_vals[INT_VALS_DURATION_COL]; value->failed_attempts = int_vals[INT_VALS_FAILED_ATTEMPTS_COL]; value->no_tries = int_vals[INT_VALS_NO_TRIES_COL]; value->dirty_bit = 0; value->prev_no_tries = -1; value->in_timestamps = NULL; description = str_vals[STR_VALS_DESCRIPTION_COL]; value->path.s = shm_malloc(strlen(url) * sizeof(char)); if (!value->path.s) { LM_ERR("insufficient shm memory\n"); goto error; } st.s = host; st.len = hlen; he = sip_resolvehost(&st, (unsigned short *) &port, (unsigned short *) &proto, 0, 0); if (!he) { LM_ERR("Cannot resolve host: %.*s\n", hlen, host); goto error; } hostent2su(&value->addr, he, 0, port); value->path.len = strlen(url); memcpy(value->path.s, url, value->path.len); if (strlen(description) != 0) { value->description.len = strlen(description); value->description.s = shm_malloc(value->description.len * sizeof(char)); if (value->description.s == NULL) { LM_ERR("no more shm memory\n"); goto error; } memcpy(value->description.s, description, value->description.len); } else { value->description.s = NULL; value->description.len = 0; } ctime = time(0); for (module = clusterer_modules; module; module = module->next) { if (cluster_id == module->accept_cluster_id && proto == module->proto) { new_timestamp = create_module_timestamp(ctime, module); if (new_timestamp == NULL) break; new_timestamp->next = value->in_timestamps; value->in_timestamps = new_timestamp; } } value->next = info_head->value; info_head->value = value; /* everything ok */ return 0; error: if (value) { if (value->description.s) shm_free(value->description.s); if (value->path.s) shm_free(value->path.s); shm_free(value); } if (info_head) { if (info_head->value == NULL) { if (head != NULL) head->info = head->info->next; shm_free(info_head); } } if (head) { if (head->info == NULL) { *tdata = (*tdata)->next; shm_free(head); } } return -1; }
/** * _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; }
int add_node_info(node_info_t **new_info, cluster_info_t **cl_list, int *int_vals, char **str_vals) { char *host; int hlen, port; int proto; struct hostent *he; int cluster_id; cluster_info_t *cluster = NULL; struct timeval t; str st; str seed_flag = str_init(SEED_NODE_FLAG_STR); cluster_id = int_vals[INT_VALS_CLUSTER_ID_COL]; /* new_info is checked whether it is initialized or not in case of error, * so we have to initialize it as soon as possible */ *new_info = NULL; for (cluster = *cl_list; cluster && cluster->cluster_id != cluster_id; cluster = cluster->next) ; if (!cluster) { cluster = shm_malloc(sizeof *cluster); if (!cluster) { LM_ERR("no more shm memory\n"); goto error; } memset(cluster, 0, sizeof *cluster); cluster->cluster_id = cluster_id; cluster->next = *cl_list; if ((cluster->lock = lock_alloc()) == NULL) { LM_CRIT("Failed to allocate lock\n"); goto error; } if (!lock_init(cluster->lock)) { lock_dealloc(cluster->lock); LM_CRIT("Failed to init lock\n"); goto error; } *cl_list = cluster; } *new_info = shm_malloc(sizeof **new_info); if (!*new_info) { LM_ERR("no more shm memory\n"); goto error; } memset(*new_info, 0, sizeof **new_info); (*new_info)->flags = 0; (*new_info)->id = int_vals[INT_VALS_ID_COL]; (*new_info)->node_id = int_vals[INT_VALS_NODE_ID_COL]; if (int_vals[INT_VALS_STATE_COL]) (*new_info)->flags |= NODE_STATE_ENABLED; else (*new_info)->flags &= ~NODE_STATE_ENABLED; if (int_vals[INT_VALS_NODE_ID_COL] != current_id) (*new_info)->link_state = LS_RESTART_PINGING; else (*new_info)->link_state = LS_UP; if (str_vals[STR_VALS_DESCRIPTION_COL] && strlen(str_vals[STR_VALS_DESCRIPTION_COL]) != 0) { (*new_info)->description.len = strlen(str_vals[STR_VALS_DESCRIPTION_COL]); (*new_info)->description.s = shm_malloc((*new_info)->description.len * sizeof(char)); if ((*new_info)->description.s == NULL) { LM_ERR("no more shm memory\n"); goto error; } memcpy((*new_info)->description.s, str_vals[STR_VALS_DESCRIPTION_COL], (*new_info)->description.len); } else { (*new_info)->description.s = NULL; (*new_info)->description.len = 0; } if (str_vals[STR_VALS_SIP_ADDR_COL] && strlen(str_vals[STR_VALS_SIP_ADDR_COL]) != 0) { (*new_info)->sip_addr.len = strlen(str_vals[STR_VALS_SIP_ADDR_COL]); (*new_info)->sip_addr.s = shm_malloc((*new_info)->sip_addr.len * sizeof(char)); if ((*new_info)->sip_addr.s == NULL) { LM_ERR("no more shm memory\n"); goto error; } memcpy((*new_info)->sip_addr.s, str_vals[STR_VALS_SIP_ADDR_COL], (*new_info)->sip_addr.len); } else { (*new_info)->sip_addr.s = NULL; (*new_info)->sip_addr.len = 0; } if (str_vals[STR_VALS_FLAGS_COL] && strlen(str_vals[STR_VALS_FLAGS_COL]) != 0) if (memcmp(str_vals[STR_VALS_FLAGS_COL], seed_flag.s, seed_flag.len) == 0) (*new_info)->flags |= NODE_IS_SEED; if (str_vals[STR_VALS_URL_COL] == NULL) { LM_ERR("no url specified in DB\n"); return 1; } (*new_info)->url.len = strlen(str_vals[STR_VALS_URL_COL]); (*new_info)->url.s = shm_malloc(strlen(str_vals[STR_VALS_URL_COL]) * sizeof(char)); if (!(*new_info)->url.s) { LM_ERR("no more shm memory\n"); goto error; } memcpy((*new_info)->url.s, str_vals[STR_VALS_URL_COL], (*new_info)->url.len); if (int_vals[INT_VALS_NODE_ID_COL] != current_id) { if (parse_phostport((*new_info)->url.s, (*new_info)->url.len, &host, &hlen, &port, &proto) < 0) { LM_ERR("Bad URL!\n"); return 1; } if (proto == PROTO_NONE) proto = clusterer_proto; if (proto != clusterer_proto) { LM_ERR("Clusterer currently supports only BIN protocol, but node: %d " "has proto=%d\n", int_vals[INT_VALS_NODE_ID_COL], proto); return 1; } st.s = host; st.len = hlen; he = sip_resolvehost(&st, (unsigned short *) &port, (unsigned short *)&proto, 0, 0); if (!he) { LM_ERR("Cannot resolve host: %.*s\n", hlen, host); return 1; } hostent2su(&((*new_info)->addr), he, 0, port); t.tv_sec = 0; t.tv_usec = 0; (*new_info)->last_ping = t; (*new_info)->last_pong = t; } (*new_info)->priority = int_vals[INT_VALS_PRIORITY_COL]; (*new_info)->no_ping_retries = int_vals[INT_VALS_NO_PING_RETRIES_COL]; (*new_info)->cluster = cluster; (*new_info)->ls_seq_no = -1; (*new_info)->top_seq_no = -1; (*new_info)->ls_timestamp = 0; (*new_info)->top_timestamp = 0; (*new_info)->sp_info = shm_malloc(sizeof(struct node_search_info)); if (!(*new_info)->sp_info) { LM_ERR("no more shm memory\n"); goto error; } (*new_info)->sp_info->node = *new_info; if (int_vals[INT_VALS_NODE_ID_COL] != current_id) { (*new_info)->next = cluster->node_list; cluster->node_list = *new_info; cluster->no_nodes++; if (cluster->no_nodes > MAX_NO_NODES) { LM_ERR("Defined: %d nodes for cluster: %d, maximum number of nodes " "supported(%d) exceeded\n", cluster->no_nodes, cluster->cluster_id, MAX_NO_NODES); goto error; } } else { (*new_info)->next = NULL; cluster->current_node = *new_info; } if (((*new_info)->lock = lock_alloc()) == NULL) { LM_CRIT("Failed to allocate lock\n"); goto error; } if (!lock_init((*new_info)->lock)) { lock_dealloc((*new_info)->lock); LM_CRIT("Failed to init lock\n"); goto error; } return 0; error: if (*new_info) { if ((*new_info)->sip_addr.s) shm_free((*new_info)->sip_addr.s); if ((*new_info)->description.s) shm_free((*new_info)->description.s); if ((*new_info)->url.s) shm_free((*new_info)->url.s); if ((*new_info)->sp_info) shm_free((*new_info)->sp_info); shm_free(*new_info); } return -1; }
static void timer(unsigned int ticks, void *param) { int rval; void *buf, *cp; str c; struct sip_uri curi; union sockaddr_union to; struct hostent* he; struct socket_info* send_sock; buf = NULL; if (cblen > 0) { buf = pkg_malloc(cblen); if (buf == NULL) { LOG(L_ERR, "ERROR: nathelper::timer: out of memory\n"); return; } } rval = get_all_ucontacts(buf, cblen); if (rval > 0) { if (buf != NULL) pkg_free(buf); cblen = rval * 2; buf = pkg_malloc(cblen); if (buf == NULL) { LOG(L_ERR, "ERROR: nathelper::timer: out of memory\n"); return; } rval = get_all_ucontacts(buf, cblen); if (rval != 0) { pkg_free(buf); return; } } if (buf == NULL) return; cp = buf; while (1) { memcpy(&(c.len), cp, sizeof(c.len)); if (c.len == 0) break; c.s = (char*)cp + sizeof(c.len); cp = (char*)cp + sizeof(c.len) + c.len; if (parse_uri(c.s, c.len, &curi) < 0) { LOG(L_ERR, "ERROR: nathelper::timer: can't parse contact uri\n"); continue; } if (curi.proto != PROTO_UDP && curi.proto != PROTO_NONE) continue; if (curi.port_no == 0) curi.port_no = SIP_PORT; he = sip_resolvehost(&curi.host, &curi.port_no, PROTO_UDP); if (he == NULL){ LOG(L_ERR, "ERROR: nathelper::timer: can't resolve_hos\n"); continue; } hostent2su(&to, he, 0, curi.port_no); send_sock = get_send_socket(&to, PROTO_UDP); if (send_sock == NULL) { LOG(L_ERR, "ERROR: nathelper::timer: can't get sending socket\n"); continue; } udp_send(send_sock, (char *)sbuf, sizeof(sbuf), &to); } pkg_free(buf); }
int add_dst( rt_data_t *r, /* id */ int id, /* ip address */ char* ip, /* strip len */ int strip, /* pri prefix */ char* pri, /* dst type*/ int type, /* dst attrs*/ char* attrs ) { pgw_t *pgw=NULL, *tmp=NULL; pgw_addr_t *tmpa=NULL; struct hostent* he; struct sip_uri uri; struct ip_addr ipa; int l_ip,l_pri,l_attrs; #define GWABUF_MAX_SIZE 512 char gwabuf[GWABUF_MAX_SIZE]; str gwas; if (NULL==r || NULL==ip) { LM_ERR("invalid parametres\n"); goto err_exit; } l_ip = strlen(ip); l_pri = pri?strlen(pri):0; l_attrs = attrs?strlen(attrs):0; pgw = (pgw_t*)shm_malloc(sizeof(pgw_t) + l_ip + l_pri + l_attrs); if (NULL==pgw) { LM_ERR("no more shm mem (%u)\n", (unsigned int)(sizeof(pgw_t)+l_ip+l_pri +l_attrs)); goto err_exit; } memset(pgw,0,sizeof(pgw_t)); pgw->ip.len= l_ip; pgw->ip.s = (char*)(pgw+1); memcpy(pgw->ip.s, ip, l_ip); if (pri) { pgw->pri.len = l_pri; pgw->pri.s = ((char*)(pgw+1))+l_ip; memcpy(pgw->pri.s, pri, l_pri); } if (attrs) { pgw->attrs.len = l_attrs; pgw->attrs.s = ((char*)(pgw+1))+l_ip+l_pri; memcpy(pgw->attrs.s, attrs, l_attrs); } pgw->id = id; pgw->strip = strip; pgw->type = type; /* add address in the list */ if(pgw->ip.len<5 || (strncasecmp("sip:", ip, 4) &&strncasecmp("sips:", ip, 5))) { if(pgw->ip.len+4>=GWABUF_MAX_SIZE) { LM_ERR("GW address (%d) longer " "than %d\n",pgw->ip.len+4,GWABUF_MAX_SIZE); goto err_exit; } memcpy(gwabuf, "sip:", 4); memcpy(gwabuf+4, ip, pgw->ip.len); gwas.s = gwabuf; gwas.len = 4+pgw->ip.len; } else { gwas.s = ip; gwas.len = pgw->ip.len; } memset(&uri, 0, sizeof(struct sip_uri)); if(parse_uri(gwas.s, gwas.len, &uri)!=0) { LM_ERR("invalid uri <%.*s>\n", gwas.len, gwas.s); goto err_exit; } /* note we discard the port discovered by the resolve function - we are interested only in the port that was actually configured. */ if ((he=sip_resolvehost( &uri.host, NULL, (char*)(void*)&uri.proto))==0 ) { if(dr_force_dns) { LM_ERR("cannot resolve <%.*s>\n", uri.host.len, uri.host.s); goto err_exit; } else { LM_DBG("cannot resolve <%.*s> - won't be used" " by is_from_gw()\n", uri.host.len, uri.host.s); goto done; } } hostent2ip_addr(&ipa, he, 0); tmpa = r->pgw_addr_l; while(tmpa) { if(tmpa->type==type && uri.port_no==tmpa->port && ip_addr_cmp(&ipa, &tmpa->ip)) { LM_DBG("gw ip addr [%s]:%d loaded\n", ip_addr2a(&ipa), uri.port_no); goto done; } tmpa = tmpa->next; } LM_DBG("new gw ip addr [%s]\n", ip); tmpa = (pgw_addr_t*)shm_malloc(sizeof(pgw_addr_t)); if(tmpa==NULL) { LM_ERR("no more shm mem (%u)\n", (unsigned int)sizeof(pgw_addr_t)); goto err_exit; } memset(tmpa, 0, sizeof(pgw_addr_t)); memcpy(&tmpa->ip, &ipa, sizeof(struct ip_addr)); tmpa->port = uri.port_no; tmpa->type = type; tmpa->strip = strip; tmpa->next = r->pgw_addr_l; r->pgw_addr_l = tmpa; done: if(NULL==r->pgw_l) r->pgw_l = pgw; else { tmp = r->pgw_l; while(NULL != tmp->next) tmp = tmp->next; tmp->next = pgw; } return 0; err_exit: if(NULL!=pgw) shm_free(pgw); return -1; }
/** * _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; }