On Fri, Feb 10, 2017 at 10:36:07PM +0800, Antonio Quartulli wrote:
> diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c
> index 82d0967d..55ff7737 100644
> --- a/src/openvpn/socket.c
> +++ b/src/openvpn/socket.c
> @@ -75,12 +75,102 @@ sf2gaf(const unsigned int getaddr_flags,
>  /*
>   * Functions related to the translation of DNS names to IP addresses.
>   */
> +static int
> +get_addr_generic(sa_family_t af, unsigned int flags, const char *hostname,
> +                 void *network, unsigned int *netbits,
> +                 int resolve_retry_seconds, volatile int *signal_received,
> +                 int msglevel)
> +{
> +    char *endp, *sep, *var_host;
> +    uint8_t bits, max_bits;
> +    struct addrinfo *ai;
> +    int ret = -1;
> +
> +    ASSERT(hostname);
> +
> +    /* assign family specific default values */
> +    switch (af)
> +    {
> +        case AF_INET:
> +            bits = 0;
> +            max_bits = sizeof(in_addr_t) * 8;
> +            break;
> +        case AF_INET6:
> +            bits = 64;
> +            max_bits = sizeof(struct in6_addr) * 8;
> +            break;
> +        default:
> +            ASSERT(0);
> +    }
> +
> +    /* we need to modify the hostname received as input, but we don't want to
> +     * touch it directly as it might be a constant string.
> +     *
> +     * Therefore, we clone the string here and free it at the end of the
> +     * function */
> +    var_host = strdup(hostname);
> +    ASSERT(var_host);
> +
> +    /* check if this hostname has a /bits suffix */
> +    sep = strchr(var_host , '/');
> +    if (sep)
> +    {
> +        bits = strtoul(sep + 1, &endp, 10);
> +        if ((*endp != '\0') || (bits > max_bits))
> +        {
> +            msg(msglevel, "IP prefix '%s': invalid '/bits' spec", hostname);
> +            goto out;
> +        }
> +        /* temporary truncate string at '/'. This allows the IP
> +         * parsing routines to properly work. Will be restored later.
> +         */
> +        *sep = '\0';
> +    }
> +
> +    ret = openvpn_getaddrinfo(flags & ~GETADDR_HOST_ORDER, var_host, NULL,
> +                              resolve_retry_seconds, signal_received, af, 
> &ai);
> +    if ((ret == 0) && network)
> +    {
> +        struct in6_addr *ip6;
> +        in_addr_t *ip4;
> +
> +        switch (af)
> +        {
> +            case AF_INET:
> +                ip4 = network;
> +                *ip4 = ((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr;
> +
> +                if (flags & GETADDR_HOST_ORDER)
> +                {
> +                    *ip4 = ntohl(*ip4);
> +                }
> +                break;
> +            case AF_INET6:
> +                ip6 = network;
> +                *ip6 = ((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr;
> +                break;
> +            default:
> +                ASSERT(0);
> +        }
> +        freeaddrinfo(ai);
> +    }
> +
> +    if (netbits)
> +    {
> +        *netbits = bits;
> +    }
> +
> +    /* restore '/' separator, if any */
> +    if (sep)
> +    {
> +        *sep = '/';
> +    }

Actually this part is useless. sep points somewhere inside var_host, but
var_host is going to be free'd at the next line, therefore the block above can
be removed.


Cheers,

-- 
Antonio Quartulli

Attachment: signature.asc
Description: Digital signature

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

Reply via email to