diff --git a/bootstrap.conf b/bootstrap.conf index 6e34c75a..d233bba9 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -60,6 +60,7 @@ gettime gitlog-to-changelog glob iconv +inet_pton inline inttypes ioctl diff --git a/docs/Makefile.am b/docs/Makefile.am index 807b4e35..1a832263 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -13,7 +13,8 @@ man3_MANS =\ $(builddir)/man/man3/libwget-base64.3\ $(builddir)/man/man3/libwget-parse_atom.3\ $(builddir)/man/man3/libwget-parse_sitemap.3\ - $(builddir)/man/man3/libwget-robots.3 + $(builddir)/man/man3/libwget-robots.3\ + $(builddir)/man/man3/libwget-ip.3 $(man3_MANS): doxy.stamp diff --git a/include/wget/wget.h b/include/wget/wget.h index 438bed29..25d7cfe7 100644 --- a/include/wget/wget.h +++ b/include/wget/wget.h @@ -829,6 +829,8 @@ typedef struct wget_iri_st { query_allocated : 1; // if set, free query in iri_free() unsigned int fragment_allocated : 1; // if set, free fragment in iri_free() + unsigned int + is_ip_address : 1; // if set, the hostname part is a literal IPv4 or IPv6 address } wget_iri_t; void @@ -1322,6 +1324,9 @@ ssize_t int wget_tcp_ready_2_transfer(wget_tcp_t *tcp, int flags) G_GNUC_WGET_NONNULL_ALL LIBWGET_EXPORT; +int + wget_ip_is_family(const char *host, int family) G_GNUC_WGET_PURE LIBWGET_EXPORT; + /* * SSL routines */ diff --git a/libwget/Makefile.am b/libwget/Makefile.am index 87254723..1331e136 100644 --- a/libwget/Makefile.am +++ b/libwget/Makefile.am @@ -4,7 +4,7 @@ lib_LTLIBRARIES = libwget.la libwget_la_SOURCES = \ atom_url.c bar.c buffer.c buffer_printf.c base64.c cookie.c\ css.c css_tokenizer.c css_tokenizer.h css_tokenizer.lex css_url.c\ - decompressor.c encoding.c hashfile.c hashmap.c io.c hsts.c html_url.c http.c init.c iri.c\ + decompressor.c encoding.c hashfile.c hashmap.c io.c hsts.c html_url.c http.c init.c ip.c iri.c\ list.c log.c logger.c md5.c mem.c metalink.c net.c net.h netrc.c ocsp.c pipe.c printf.c random.c \ robots.c rss_url.c sitemap_url.c ssl_gnutls.c stringmap.c strlcpy.c thread.c tls_session.c utils.c \ vector.c xalloc.c xml.c private.h http_highlevel.c diff --git a/libwget/ip.c b/libwget/ip.c new file mode 100644 index 00000000..fed18e1a --- /dev/null +++ b/libwget/ip.c @@ -0,0 +1,69 @@ +/* + * Copyright(c) 2016 Free Software Foundation, Inc. + * + * This file is part of libwget. + * + * Libwget is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libwget is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libwget. If not, see . + * + * + * IP address helper routines + * + */ + +#if HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include +#include "private.h" + +/** + * \file + * \brief IP address functions + * \defgroup libwget-ip IP address functions + * @{ + * + * Routines to check IP address formats. + */ + +/** + * \param[in] host Host/IP String + * \param[in] family IP address family + * \return + * 1 if \host matches is of \p family
+ * 0 if \p host does not match \p family
+ * + * This functions checks if \p host matches the given \p family or not. + */ +int wget_ip_is_family(const char *host, int family) +{ + struct sockaddr_storage dst; + + if (!host) + return 0; + + switch (family) { + case WGET_NET_FAMILY_IPV4: + return inet_pton(AF_INET, host, (struct in_addr *) &dst); + case WGET_NET_FAMILY_IPV6: + return inet_pton(AF_INET6, host, (struct in6_addr *) &dst); + default: + return 0; + } +} + +/**@}*/ diff --git a/libwget/iri.c b/libwget/iri.c index 3b156fca..ddf05c4f 100644 --- a/libwget/iri.c +++ b/libwget/iri.c @@ -373,6 +373,10 @@ wget_iri_t *wget_iri_parse(const char *url, const char *encoding) iri->host = p; iri->host_allocated = 1; } + + // Finally, if the host is a literal IPv4 or IPv6 address, mark it as so + if (wget_ip_is_family(iri->host, WGET_NET_FAMILY_IPV4) || wget_ip_is_family(iri->host, WGET_NET_FAMILY_IPV6)) + iri->is_ip_address = 1; } else { if (iri->scheme == WGET_IRI_SCHEME_HTTP || iri->scheme == WGET_IRI_SCHEME_HTTPS) { diff --git a/src/wget.c b/src/wget.c index 26f495c2..8b8faf09 100644 --- a/src/wget.c +++ b/src/wget.c @@ -1239,7 +1239,9 @@ static int process_response_header(wget_http_response_t *resp) wget_cookie_store_cookies(config.cookie_db, resp->cookies); // store cookies // care for HSTS feature - if (config.hsts && iri->scheme == WGET_IRI_SCHEME_HTTPS && resp->hsts) { + if (config.hsts && + iri->scheme == WGET_IRI_SCHEME_HTTPS && !iri->is_ip_address && + resp->hsts) { wget_hsts_db_add(config.hsts_db, wget_hsts_new(iri->host, atoi(iri->resolv_port), resp->hsts_maxage, resp->hsts_include_subdomains)); hsts_changed = 1; }