* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Authors: Christian Kellner <gicmo@gnome.org>
* Samuel Cormier-Iijima <sciyoshi@gmail.com>
/**
* GInetSocketAddress:flowinfo:
*
- * The <literal>sin6_flowinfo</literal> field, for IPv6 addresses.
+ * The `sin6_flowinfo` field, for IPv6 addresses.
*
* Since: 2.32
*/
/**
* GInetSocketAddress:scope_id:
*
- * The <literal>sin6_scope_id</literal> field, for IPv6 addresses.
+ * The `sin6_scope_id` field, for IPv6 addresses.
*
* Since: 2.32
*/
}
/**
+ * g_inet_socket_address_new_from_string:
+ * @address: the string form of an IP address
+ * @port: a port number
+ *
+ * Creates a new #GInetSocketAddress for @address and @port.
+ *
+ * If @address is an IPv6 address, it can also contain a scope ID
+ * (separated from the address by a "<literal>%</literal>").
+ *
+ * Returns: a new #GInetSocketAddress, or %NULL if @address cannot be
+ * parsed.
+ *
+ * Since: 2.40
+ */
+GSocketAddress *
+g_inet_socket_address_new_from_string (const char *address,
+ guint port)
+{
+ static struct addrinfo *hints, hints_struct;
+ GSocketAddress *saddr;
+ GInetAddress *iaddr;
+ struct addrinfo *res;
+ gint status;
+
+ if (strchr (address, ':'))
+ {
+ /* IPv6 address (or it's invalid). We use getaddrinfo() because
+ * it will handle parsing a scope_id as well.
+ */
+
+ if (G_UNLIKELY (g_once_init_enter (&hints)))
+ {
+ hints_struct.ai_family = AF_UNSPEC;
+ hints_struct.ai_socktype = SOCK_STREAM;
+ hints_struct.ai_protocol = 0;
+ hints_struct.ai_flags = AI_NUMERICHOST;
+ g_once_init_leave (&hints, &hints_struct);
+ }
+
+ status = getaddrinfo (address, NULL, hints, &res);
+ if (status != 0)
+ return NULL;
+
+ if (res->ai_family == AF_INET6 &&
+ res->ai_addrlen == sizeof (struct sockaddr_in6))
+ {
+ ((struct sockaddr_in6 *)res->ai_addr)->sin6_port = g_htons (port);
+ saddr = g_socket_address_new_from_native (res->ai_addr, res->ai_addrlen);
+ }
+ else
+ saddr = NULL;
+
+ freeaddrinfo (res);
+ }
+ else
+ {
+ /* IPv4 (or invalid). We don't want to use getaddrinfo() here,
+ * because it accepts the stupid "IPv4 numbers-and-dots
+ * notation" addresses that are never used for anything except
+ * phishing. Since we don't have to worry about scope IDs for
+ * IPv4, we can just use g_inet_address_new_from_string().
+ */
+ iaddr = g_inet_address_new_from_string (address);
+ if (!iaddr)
+ return NULL;
+
+ g_warn_if_fail (g_inet_address_get_family (iaddr) == G_SOCKET_FAMILY_IPV4);
+
+ saddr = g_inet_socket_address_new (iaddr, port);
+ g_object_unref (iaddr);
+ }
+
+ return saddr;
+}
+
+/**
* g_inet_socket_address_get_address:
* @address: a #GInetSocketAddress
*
* g_inet_socket_address_get_flowinfo:
* @address: a %G_SOCKET_FAMILY_IPV6 #GInetSocketAddress
*
- * Gets the <literal>sin6_flowinfo</literal> field from @address,
+ * Gets the `sin6_flowinfo` field from @address,
* which must be an IPv6 address.
*
- * Return value: the flowinfo field
+ * Returns: the flowinfo field
*
* Since: 2.32
*/
* g_inet_socket_address_get_scope_id:
* @address: a %G_SOCKET_FAMILY_IPV6 #GInetAddress
*
- * Gets the <literal>sin6_scope_id</literal> field from @address,
+ * Gets the `sin6_scope_id` field from @address,
* which must be an IPv6 address.
*
- * Return value: the scope id field
+ * Returns: the scope id field
*
* Since: 2.32
*/