From: Sebastian Dröge Date: Fri, 13 Jan 2012 11:48:02 +0000 (+0100) Subject: GSocket: Add function for setting unicast TTL X-Git-Tag: 2.31.10~8 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5560d9b8800de1144d77ed924286759286b7d27e;p=platform%2Fupstream%2Fglib.git GSocket: Add function for setting unicast TTL --- diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt index 110e7d0..b370044 100644 --- a/docs/reference/gio/gio-sections.txt +++ b/docs/reference/gio/gio-sections.txt @@ -1814,6 +1814,8 @@ g_socket_get_keepalive g_socket_set_keepalive g_socket_get_timeout g_socket_set_timeout +g_socket_set_ttl +g_socket_get_ttl g_socket_get_family g_socket_get_fd g_socket_get_local_address diff --git a/gio/gio.symbols b/gio/gio.symbols index 5f71700..47347da 100644 --- a/gio/gio.symbols +++ b/gio/gio.symbols @@ -953,6 +953,7 @@ g_socket_get_blocking g_socket_get_family g_socket_get_fd g_socket_get_timeout +g_socket_get_ttl g_socket_get_keepalive g_socket_get_listen_backlog g_socket_get_local_address @@ -978,6 +979,7 @@ g_socket_send_to g_socket_send_with_blocking g_socket_set_blocking g_socket_set_timeout +g_socket_set_ttl g_socket_set_keepalive g_socket_set_listen_backlog g_socket_set_multicast_loopback diff --git a/gio/gsocket.c b/gio/gsocket.c index 814035e..49e4194 100644 --- a/gio/gsocket.c +++ b/gio/gsocket.c @@ -138,6 +138,7 @@ enum PROP_LOCAL_ADDRESS, PROP_REMOTE_ADDRESS, PROP_TIMEOUT, + PROP_TTL, PROP_MULTICAST_LOOPBACK, PROP_MULTICAST_TTL }; @@ -615,6 +616,10 @@ g_socket_get_property (GObject *object, g_value_set_uint (value, socket->priv->timeout); break; + case PROP_TTL: + g_value_set_uint (value, g_socket_get_ttl (socket)); + break; + case PROP_MULTICAST_LOOPBACK: g_value_set_boolean (value, g_socket_get_multicast_loopback (socket)); break; @@ -670,6 +675,10 @@ g_socket_set_property (GObject *object, g_socket_set_timeout (socket, g_value_get_uint (value)); break; + case PROP_TTL: + g_socket_set_ttl (socket, g_value_get_uint (value)); + break; + case PROP_MULTICAST_LOOPBACK: g_socket_set_multicast_loopback (socket, g_value_get_boolean (value)); break; @@ -837,6 +846,21 @@ g_socket_class_init (GSocketClass *klass) G_PARAM_STATIC_STRINGS)); /** + * GSocket:ttl: + * + * Time-to-live for outgoing unicast packets + * + * Since: 2.32 + */ + g_object_class_install_property (gobject_class, PROP_TTL, + g_param_spec_uint ("ttl", + P_("TTL"), + P_("Time-to-live of outgoing unicast packets"), + 0, G_MAXUINT, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** * GSocket:multicast-loopback: * * Whether outgoing multicast packets loop back to the local host. @@ -1212,6 +1236,96 @@ g_socket_set_timeout (GSocket *socket, } /** + * g_socket_get_ttl: + * @socket: a #GSocket. + * + * Gets the unicast time-to-live setting on @socket; see + * g_socket_set_ttl() for more details. + * + * Returns: the time-to-live setting on @socket + * + * Since: 2.32 + */ +guint +g_socket_get_ttl (GSocket *socket) +{ + int result; + guint value, optlen; + + g_return_val_if_fail (G_IS_SOCKET (socket), FALSE); + + if (socket->priv->family == G_SOCKET_FAMILY_IPV4) + { + guchar optval; + + optlen = sizeof (optval); + result = getsockopt (socket->priv->fd, IPPROTO_IP, IP_TTL, + &optval, &optlen); + value = optval; + } + else if (socket->priv->family == G_SOCKET_FAMILY_IPV6) + { + optlen = sizeof (value); + result = getsockopt (socket->priv->fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, + &value, &optlen); + } + else + g_return_val_if_reached (FALSE); + + if (result < 0) + { + int errsv = get_socket_errno (); + g_warning ("error getting unicast ttl: %s", socket_strerror (errsv)); + return FALSE; + } + + return value; +} + +/** + * g_socket_set_ttl: + * @socket: a #GSocket. + * @ttl: the time-to-live value for all unicast packets on @socket + * + * Sets the time-to-live for outgoing unicast packets on @socket. + * By default the platform-specific default value is used. + * + * Since: 2.32 + */ +void +g_socket_set_ttl (GSocket *socket, + guint ttl) +{ + int result; + + g_return_if_fail (G_IS_SOCKET (socket)); + + if (socket->priv->family == G_SOCKET_FAMILY_IPV4) + { + guchar optval = (guchar)ttl; + + result = setsockopt (socket->priv->fd, IPPROTO_IP, IP_TTL, + &optval, sizeof (optval)); + } + else if (socket->priv->family == G_SOCKET_FAMILY_IPV6) + { + result = setsockopt (socket->priv->fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, + &ttl, sizeof (ttl)); + } + else + g_return_if_reached (); + + if (result < 0) + { + int errsv = get_socket_errno (); + g_warning ("error setting unicast ttl: %s", socket_strerror (errsv)); + return; + } + + g_object_notify (G_OBJECT (socket), "ttl"); +} + +/** * g_socket_get_multicast_loopback: * @socket: a #GSocket. * diff --git a/gio/gsocket.h b/gio/gsocket.h index 1596bf0..30f1816 100644 --- a/gio/gsocket.h +++ b/gio/gsocket.h @@ -100,6 +100,11 @@ void g_socket_set_listen_backlog (GSocket guint g_socket_get_timeout (GSocket *socket); void g_socket_set_timeout (GSocket *socket, guint timeout); + +guint g_socket_get_ttl (GSocket *socket); +void g_socket_set_ttl (GSocket *socket, + guint ttl); + gboolean g_socket_get_multicast_loopback (GSocket *socket); void g_socket_set_multicast_loopback (GSocket *socket, gboolean loopback);