From c9fcc7f14860777458153eb2d13c773ccfa1daa2 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 4 Sep 2013 18:02:09 +0200 Subject: system/resolver: convert to C++ --- src/ClientNew.cxx | 4 +- src/event/ServerSocket.cxx | 2 +- src/output/HttpdOutputPlugin.cxx | 2 +- src/system/Resolver.cxx | 140 +++++++++++++++++++++++++++++++++++++++ src/system/Resolver.hxx | 66 ++++++++++++++++++ src/system/resolver.c | 140 --------------------------------------- src/system/resolver.h | 74 --------------------- 7 files changed, 209 insertions(+), 219 deletions(-) create mode 100644 src/system/Resolver.cxx create mode 100644 src/system/Resolver.hxx delete mode 100644 src/system/resolver.c delete mode 100644 src/system/resolver.h (limited to 'src') diff --git a/src/ClientNew.cxx b/src/ClientNew.cxx index c277423ab..dd5aba318 100644 --- a/src/ClientNew.cxx +++ b/src/ClientNew.cxx @@ -23,9 +23,7 @@ #include "Partition.hxx" #include "Instance.hxx" #include "system/fd_util.h" -extern "C" { -#include "system/resolver.h" -} +#include "system/Resolver.hxx" #include "Permission.hxx" #include diff --git a/src/event/ServerSocket.cxx b/src/event/ServerSocket.cxx index a137e2d9a..d22790de5 100644 --- a/src/event/ServerSocket.cxx +++ b/src/event/ServerSocket.cxx @@ -27,7 +27,7 @@ #include "system/SocketUtil.hxx" #include "system/SocketError.hxx" #include "event/SocketMonitor.hxx" -#include "system/resolver.h" +#include "system/Resolver.hxx" #include "system/fd_util.h" #include diff --git a/src/output/HttpdOutputPlugin.cxx b/src/output/HttpdOutputPlugin.cxx index fbf25ca00..745ed26a2 100644 --- a/src/output/HttpdOutputPlugin.cxx +++ b/src/output/HttpdOutputPlugin.cxx @@ -24,7 +24,7 @@ #include "OutputAPI.hxx" #include "EncoderPlugin.hxx" #include "EncoderList.hxx" -#include "system/resolver.h" +#include "system/Resolver.hxx" #include "Page.hxx" #include "IcyMetaDataServer.hxx" #include "system/fd_util.h" diff --git a/src/system/Resolver.cxx b/src/system/Resolver.cxx new file mode 100644 index 000000000..a574e82c1 --- /dev/null +++ b/src/system/Resolver.cxx @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2003-2013 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "Resolver.hxx" + +#ifndef G_OS_WIN32 +#include +#include +#else /* G_OS_WIN32 */ +#include +#include +#endif /* G_OS_WIN32 */ + +#include + +char * +sockaddr_to_string(const struct sockaddr *sa, size_t length, GError **error) +{ +#if defined(HAVE_IPV6) && defined(IN6_IS_ADDR_V4MAPPED) + const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *)sa; + struct sockaddr_in a4; +#endif + int ret; + char host[NI_MAXHOST], serv[NI_MAXSERV]; + +#if defined(HAVE_IPV6) && defined(IN6_IS_ADDR_V4MAPPED) + if (sa->sa_family == AF_INET6 && + IN6_IS_ADDR_V4MAPPED(&a6->sin6_addr)) { + /* convert "::ffff:127.0.0.1" to "127.0.0.1" */ + + memset(&a4, 0, sizeof(a4)); + a4.sin_family = AF_INET; + memcpy(&a4.sin_addr, ((const char *)&a6->sin6_addr) + 12, + sizeof(a4.sin_addr)); + a4.sin_port = a6->sin6_port; + + sa = (const struct sockaddr *)&a4; + length = sizeof(a4); + } +#endif + + ret = getnameinfo(sa, length, host, sizeof(host), serv, sizeof(serv), + NI_NUMERICHOST|NI_NUMERICSERV); + if (ret != 0) { + g_set_error(error, g_quark_from_static_string("netdb"), ret, + "%s", gai_strerror(ret)); + return NULL; + } + +#ifdef HAVE_UN + if (sa->sa_family == AF_UNIX) + /* "serv" contains corrupt information with unix + sockets */ + return g_strdup(host); +#endif + +#ifdef HAVE_IPV6 + if (strchr(host, ':') != NULL) + return g_strconcat("[", host, "]:", serv, NULL); +#endif + + return g_strconcat(host, ":", serv, NULL); +} + +struct addrinfo * +resolve_host_port(const char *host_port, unsigned default_port, + int flags, int socktype, + GError **error_r) +{ + char *p = g_strdup(host_port); + const char *host = p, *port = NULL; + + if (host_port[0] == '[') { + /* IPv6 needs enclosing square braces, to + differentiate between IP colons and the port + separator */ + + char *q = strchr(p + 1, ']'); + if (q != NULL && q[1] == ':' && q[2] != 0) { + *q = 0; + ++host; + port = q + 2; + } + } + + if (port == NULL) { + /* port is after the colon, but only if it's the only + colon (don't split IPv6 addresses) */ + + char *q = strchr(p, ':'); + if (q != NULL && q[1] != 0 && strchr(q + 1, ':') == NULL) { + *q = 0; + port = q + 1; + } + } + + char buffer[32]; + if (port == NULL && default_port != 0) { + g_snprintf(buffer, sizeof(buffer), "%u", default_port); + port = buffer; + } + + if ((flags & AI_PASSIVE) != 0 && strcmp(host, "*") == 0) + host = NULL; + + addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = flags; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = socktype; + + struct addrinfo *ai; + int ret = getaddrinfo(host, port, &hints, &ai); + g_free(p); + if (ret != 0) { + g_set_error(error_r, resolver_quark(), ret, + "Failed to look up '%s': %s", + host_port, gai_strerror(ret)); + return NULL; + } + + return ai; +} diff --git a/src/system/Resolver.hxx b/src/system/Resolver.hxx new file mode 100644 index 000000000..a1cd00329 --- /dev/null +++ b/src/system/Resolver.hxx @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2003-2013 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_RESOLVER_HXX +#define MPD_RESOLVER_HXX + +#include "gcc.h" + +#include + +struct sockaddr; +struct addrinfo; + +gcc_const +static inline GQuark +resolver_quark(void) +{ + return g_quark_from_static_string("resolver"); +} + +/** + * Converts the specified socket address into a string in the form + * "IP:PORT". The return value must be freed with g_free() when you + * don't need it anymore. + * + * @param sa the sockaddr struct + * @param length the length of #sa in bytes + * @param error location to store the error occurring, or NULL to + * ignore errors + */ +gcc_malloc +char * +sockaddr_to_string(const struct sockaddr *sa, size_t length, GError **error); + +/** + * Resolve a specification in the form "host", "host:port", + * "[host]:port". This is a convenience wrapper for getaddrinfo(). + * + * @param default_port a default port number that will be used if none + * is given in the string (if applicable); pass 0 to go without a + * default + * @return an #addrinfo linked list that must be freed with + * freeaddrinfo(), or NULL on error + */ +struct addrinfo * +resolve_host_port(const char *host_port, unsigned default_port, + int flags, int socktype, + GError **error_r); + +#endif diff --git a/src/system/resolver.c b/src/system/resolver.c deleted file mode 100644 index 243b7cd02..000000000 --- a/src/system/resolver.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2003-2011 The Music Player Daemon Project - * http://www.musicpd.org - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" -#include "resolver.h" - -#ifndef G_OS_WIN32 -#include -#include -#else /* G_OS_WIN32 */ -#include -#include -#endif /* G_OS_WIN32 */ - -#include - -char * -sockaddr_to_string(const struct sockaddr *sa, size_t length, GError **error) -{ -#if defined(HAVE_IPV6) && defined(IN6_IS_ADDR_V4MAPPED) - const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *)sa; - struct sockaddr_in a4; -#endif - int ret; - char host[NI_MAXHOST], serv[NI_MAXSERV]; - -#if defined(HAVE_IPV6) && defined(IN6_IS_ADDR_V4MAPPED) - if (sa->sa_family == AF_INET6 && - IN6_IS_ADDR_V4MAPPED(&a6->sin6_addr)) { - /* convert "::ffff:127.0.0.1" to "127.0.0.1" */ - - memset(&a4, 0, sizeof(a4)); - a4.sin_family = AF_INET; - memcpy(&a4.sin_addr, ((const char *)&a6->sin6_addr) + 12, - sizeof(a4.sin_addr)); - a4.sin_port = a6->sin6_port; - - sa = (const struct sockaddr *)&a4; - length = sizeof(a4); - } -#endif - - ret = getnameinfo(sa, length, host, sizeof(host), serv, sizeof(serv), - NI_NUMERICHOST|NI_NUMERICSERV); - if (ret != 0) { - g_set_error(error, g_quark_from_static_string("netdb"), ret, - "%s", gai_strerror(ret)); - return NULL; - } - -#ifdef HAVE_UN - if (sa->sa_family == AF_UNIX) - /* "serv" contains corrupt information with unix - sockets */ - return g_strdup(host); -#endif - -#ifdef HAVE_IPV6 - if (strchr(host, ':') != NULL) - return g_strconcat("[", host, "]:", serv, NULL); -#endif - - return g_strconcat(host, ":", serv, NULL); -} - -struct addrinfo * -resolve_host_port(const char *host_port, unsigned default_port, - int flags, int socktype, - GError **error_r) -{ - char *p = g_strdup(host_port); - const char *host = p, *port = NULL; - - if (host_port[0] == '[') { - /* IPv6 needs enclosing square braces, to - differentiate between IP colons and the port - separator */ - - char *q = strchr(p + 1, ']'); - if (q != NULL && q[1] == ':' && q[2] != 0) { - *q = 0; - ++host; - port = q + 2; - } - } - - if (port == NULL) { - /* port is after the colon, but only if it's the only - colon (don't split IPv6 addresses) */ - - char *q = strchr(p, ':'); - if (q != NULL && q[1] != 0 && strchr(q + 1, ':') == NULL) { - *q = 0; - port = q + 1; - } - } - - char buffer[32]; - if (port == NULL && default_port != 0) { - g_snprintf(buffer, sizeof(buffer), "%u", default_port); - port = buffer; - } - - if ((flags & AI_PASSIVE) != 0 && strcmp(host, "*") == 0) - host = NULL; - - const struct addrinfo hints = { - .ai_flags = flags, - .ai_family = AF_UNSPEC, - .ai_socktype = socktype, - }; - - struct addrinfo *ai; - int ret = getaddrinfo(host, port, &hints, &ai); - g_free(p); - if (ret != 0) { - g_set_error(error_r, resolver_quark(), ret, - "Failed to look up '%s': %s", - host_port, gai_strerror(ret)); - return NULL; - } - - return ai; -} diff --git a/src/system/resolver.h b/src/system/resolver.h deleted file mode 100644 index af14f5f23..000000000 --- a/src/system/resolver.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2003-2011 The Music Player Daemon Project - * http://www.musicpd.org - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPD_RESOLVER_H -#define MPD_RESOLVER_H - -#include "gcc.h" - -#include - -struct sockaddr; -struct addrinfo; - -gcc_const -static inline GQuark -resolver_quark(void) -{ - return g_quark_from_static_string("resolver"); -} - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Converts the specified socket address into a string in the form - * "IP:PORT". The return value must be freed with g_free() when you - * don't need it anymore. - * - * @param sa the sockaddr struct - * @param length the length of #sa in bytes - * @param error location to store the error occurring, or NULL to - * ignore errors - */ -gcc_malloc -char * -sockaddr_to_string(const struct sockaddr *sa, size_t length, GError **error); - -/** - * Resolve a specification in the form "host", "host:port", - * "[host]:port". This is a convenience wrapper for getaddrinfo(). - * - * @param default_port a default port number that will be used if none - * is given in the string (if applicable); pass 0 to go without a - * default - * @return an #addrinfo linked list that must be freed with - * freeaddrinfo(), or NULL on error - */ -struct addrinfo * -resolve_host_port(const char *host_port, unsigned default_port, - int flags, int socktype, - GError **error_r); - -#ifdef __cplusplus -} -#endif - -#endif -- cgit v1.2.3