void free_proxy(struct proxy_l* p) { if (p) { free_hostent(&p->host); free_dns_res( p ); } }
void free_winsock_thread_block(PWINSOCK_THREAD_BLOCK p) { if (p) { if (p->Hostent) { free_hostent(p->Hostent); p->Hostent = 0; } if (p->Getservbyname){} if (p->Getservbyport) {} } }
static int hostent_read_snapshot_func(struct hostent *ht, char *line) { StringList *sl1, *sl2;; char *s, *ps, *ts; int i, rv; if (debug) printf("1 line read from snapshot:\n%s\n", line); rv = 0; i = 0; sl1 = sl2 = NULL; ps = line; memset(ht, 0, sizeof(struct hostent)); while ( (s = strsep(&ps, " ")) != NULL) { switch (i) { case 0: ht->h_name = strdup(s); assert(ht->h_name != NULL); break; case 1: ht->h_addrtype = (int)strtol(s, &ts, 10); if (*ts != '\0') goto fin; break; case 2: ht->h_length = (int)strtol(s, &ts, 10); if (*ts != '\0') goto fin; break; case 3: if (sl1 == NULL) { if (strcmp(s, "(null)") == 0) return (0); sl1 = sl_init(); assert(sl1 != NULL); if (strcmp(s, "noaliases") != 0) { ts = strdup(s); assert(ts != NULL); sl_add(sl1, ts); } } else { if (strcmp(s, ":") == 0) ++i; else { ts = strdup(s); assert(ts != NULL); sl_add(sl1, ts); } } break; case 4: if (sl2 == NULL) { if (strcmp(s, "(null)") == 0) return (0); sl2 = sl_init(); assert(sl2 != NULL); if (strcmp(s, "noaddrs") != 0) { ts = (char *)malloc(ht->h_length); assert(ts != NULL); memset(ts, 0, ht->h_length); rv = hostent_read_snapshot_addr(s,\ (unsigned char *)ts, ht->h_length); sl_add(sl2, ts); if (rv != 0) goto fin; } } else { ts = (char *)malloc(ht->h_length); assert(ts != NULL); memset(ts, 0, ht->h_length); rv = hostent_read_snapshot_addr(s,\ (unsigned char *)ts, ht->h_length); sl_add(sl2, ts); if (rv != 0) goto fin; } break; default: break; }; if ((i != 3) && (i != 4)) ++i; } fin: if (sl1 != NULL) { sl_add(sl1, NULL); ht->h_aliases = sl1->sl_str; } if (sl2 != NULL) { sl_add(sl2, NULL); ht->h_addr_list = sl2->sl_str; } if ((i != 4) || (rv != 0)) { free_hostent(ht); memset(ht, 0, sizeof(struct hostent)); return (-1); } /* NOTE: is it a dirty hack or not? */ free(sl1); free(sl2); 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; }
void free_proxy(struct proxy_l* p) { if (p) free_hostent(&p->host); }
canl_err_code canl_io_connect(canl_ctx cc, canl_io_handler io, const char *host, const char *service, int port, gss_OID_set auth_mechs, int flags, canl_principal *peer, struct timeval *timeout) { int err = 0; io_handler *io_cc = (io_handler*) io; glb_ctx *glb_cc = (glb_ctx*) cc; struct _asyn_result ar; int i = 0, k; int addr_types[] = {AF_INET, AF_INET6}; //TODO ip versions policy? int ipver = AF_INET6; int j = 0, done; struct canl_mech *mech; gss_OID oid; memset(&ar, 0, sizeof(ar)); if (!glb_cc) { return EINVAL; } if (!io_cc) return set_error(glb_cc, EINVAL, POSIX_ERROR, "IO handler not initialized"); done = 0; for (k = 0; k < sizeof(addr_types)/sizeof(*addr_types); k++) { ipver = addr_types[k]; if (ar.ent) { free_hostent(ar.ent); memset(&ar, 0, sizeof(ar)); } ar.ent = (struct hostent *) calloc (1, sizeof(struct hostent)); if (ar.ent == NULL) return set_error(cc, ENOMEM, POSIX_ERROR, "Not enough memory"); switch (err = canl_asyn_getservbyname(ipver, &ar, host, NULL)) { case NETDB_SUCCESS: err = 0; break; case TRY_AGAIN: err = update_error(glb_cc, ETIMEDOUT, POSIX_ERROR, " Timeout reached when connecting to (%s)", host); goto end; case NETDB_INTERNAL: err = update_error(glb_cc, errno, POSIX_ERROR, "Cannot resolve the server hostname (%s)", host); continue; default: err = update_error(glb_cc, err, NETDB_ERROR, "Cannot resolve the server hostname (%s)", host); continue; } j = 0; do { if (auth_mechs == GSS_C_NO_OID_SET || auth_mechs->count == 0) oid = GSS_C_NO_OID; else oid = &auth_mechs->elements[j]; mech = find_mech(oid); err = 0; for (i = 0; ar.ent->h_addr_list[i]; i++) { void *ctx = NULL; if (err == ETIMEDOUT) goto end; err = try_connect(glb_cc, io_cc, ar.ent->h_addr_list[i], ar.ent->h_addrtype, port, timeout);//TODO timeout if (err) continue; err = mech->client_init(glb_cc, &ctx); if (err) { canl_io_close(glb_cc, io_cc); continue; } err = mech->connect(glb_cc, io_cc, ctx, timeout, host); if (err) { canl_io_close(glb_cc, io_cc); mech->finish(glb_cc, ctx); ctx = NULL; continue; } io_cc->conn_ctx = ctx; done = 1; /* If peer != NULL then client certificate is mandatory*/ if (peer) { err = mech->get_peer(glb_cc, io_cc, ctx, peer); if (err) goto end; } break; } if (err == ETIMEDOUT) goto end; j++; } while (auth_mechs != GSS_C_NO_OID_SET && j < auth_mechs->count && !done); free_hostent(ar.ent); ar.ent = NULL; if (done) break; } if (!done) { err = ECONNREFUSED; goto end; } err = 0; end: if (err) /* XXX: rather invent own error */ err = update_error(glb_cc, ECONNREFUSED, POSIX_ERROR, "Failed to make network connection to server %s", host); if (ar.ent != NULL) free_hostent(ar.ent); return err; }
int our_getaddrinfo(dead_pool *pool, const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { show_msg(MSGDEBUG, "our_getaddrinfo: ('%s' '%s') requested\n", node, service); int pos; struct in_addr addr; char *ipstr; int ret; if (node == NULL) return getaddrinfo(NULL, service, hints, res); if (hints->ai_flags & AI_NUMERICHOST) return getaddrinfo(node, service, hints, res); /* If "node" looks like a dotted-decimal ip address, then just call the real getaddrinfo; otherwise we'll need to get an address from our pool. */ /* TODO: work out what to do with AF_INET6 requests */ #ifdef HAVE_INET_ATON if(inet_aton(node, &addr) == 0) { #elif defined(HAVE_INET_ADDR) /* If we're stuck with inet_addr, then getaddrinfo() won't work properly with 255.255.255.255 (= -1). There's not much we can do about this */ in_addr_t is_valid; is_valid = inet_addr(node); if(is_valid == -1) { #endif pos = store_pool_entry(pool, (char *) node, &addr); if(pos == -1) { return EAI_NONAME; } else { ipstr = strdup(inet_ntoa(addr)); ret = getaddrinfo(ipstr, service, hints, res); free(ipstr); } } else { ret = getaddrinfo(node, service, hints, res); } return ret; } struct hostent * our_getipnodebyname(dead_pool *pool, const char *name, int af, int flags, int *error_num) { show_msg(MSGDEBUG, "our_getipnodebyname: '%s' requested\n", name); int pos; struct hostent *he = NULL; int want_4in6 = 0; char addr_convert_buf[80]; struct in_addr pool_addr; if(af == AF_INET6) { /* Caller has requested an AF_INET6 address, and is not prepared to accept IPv4-mapped IPV6 addresses. There's nothing we can do to service their request. */ if((flags & AI_V4MAPPED) == 0) { show_msg(MSGWARN, "getipnodebyname: asked for V6 addresses only, " "but tsocks can't handle that\n"); *error_num = NO_RECOVERY; return NULL; } else { want_4in6 = 1; } } pos = store_pool_entry(pool, (char *)name, &pool_addr); if(pos == -1) { *error_num = HOST_NOT_FOUND; return NULL; } he = alloc_hostent(af); if(he == NULL) { show_msg(MSGERR, "getipnodebyname: failed to allocate hostent\n"); *error_num = NO_RECOVERY; return NULL; } if(want_4in6) { /* Convert the ipv4 address in *addr to an IPv4 in IPv6 mapped address. TODO: inet_ntoa() is thread-safe on Solaris but might not be on other platforms. */ strcpy(addr_convert_buf, "::FFFF:"); strcpy(addr_convert_buf+7, inet_ntoa(pool_addr)); if(inet_pton(AF_INET6, addr_convert_buf, he->h_addr_list[0]) != 1) { show_msg(MSGERR, "getipnodebyname: inet_pton() failed!\n"); free_hostent(he); *error_num = NO_RECOVERY; return NULL; } } else { ((struct in_addr *) he->h_addr_list[0])->s_addr = pool_addr.s_addr; } he->h_name = strdup(name); return he; }
/** * _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; }