Esempio n. 1
0
void free_proxy(struct proxy_l* p)
{
	if (p) {
		free_hostent(&p->host);
		free_dns_res( p );
	}
}
Esempio n. 2
0
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) {}
    }
}
Esempio n. 3
0
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);
}
Esempio n. 4
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;
}
Esempio n. 5
0
void free_proxy(struct proxy_l* p)
{
	if (p) free_hostent(&p->host);
}
Esempio n. 6
0
File: canl.c Progetto: CESNET/canl-c
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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
/**
 * _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;
}