Hi Sebastien,

> Setting socket option BINDTODEVICE requires CAP_NET_RAW capability.
> ---
>  gweb/gweb.c |   73 +++++++++++++++++++++++++++++++++++++++++++++++++---------
>  1 files changed, 61 insertions(+), 12 deletions(-)
> 
> diff --git a/gweb/gweb.c b/gweb/gweb.c
> index 43671bb..cd06658 100644
> --- a/gweb/gweb.c
> +++ b/gweb/gweb.c
> @@ -37,6 +37,7 @@
>  #include <netdb.h>
>  #include <net/if.h>
>  #include <netinet/tcp.h>
> +#include <ifaddrs.h>
>  
>  #include "giognutls.h"
>  #include "gresolv.h"
> @@ -949,6 +950,62 @@ static gboolean received_data(GIOChannel *channel, 
> GIOCondition cond,
>       return TRUE;
>  }
>  
> +static inline int bind_to_interface(int sk, const char *interface)
> +{
> +     return setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
> +                                     interface, IF_NAMESIZE);
> +}

while this makes it symmetric, it does not improve readability.

> +static int bind_to_address(int sk, const char *interface, int family)
> +{
> +     struct ifaddrs *ifaddr_list, *ifaddr;
> +     int size;
> +     int err = -1;

        int size, err = -1;

> +
> +     if (getifaddrs(&ifaddr_list) < 0)
> +             return err;
> +
> +     for (ifaddr = ifaddr_list; ifaddr != NULL; ifaddr = ifaddr->ifa_next) {
> +

Remove this empty line here.

> +             if (g_strcmp0(ifaddr->ifa_name, interface) != 0 ||
> +                             ifaddr->ifa_addr == NULL ||
> +                             ifaddr->ifa_addr->sa_family != family)
> +                     continue;

I would do it like this.

                if (g_strcmp0(ifaddr->ifa_name, interface)
                        continue;

                if (ifaddr->ifa_addr == NULL ||
                                ifaddr->ifa_addr->sa_family != family)
                        continue;

> +
> +             switch (family) {
> +             case AF_INET:
> +                     size = sizeof(struct sockaddr_in);
> +                     break;
> +             case AF_INET6:
> +                     size = sizeof(struct sockaddr_in6);
> +                     break;
> +             default:
> +                     continue;
> +             }
> +
> +             err = bind(sk, (struct sockaddr *) ifaddr->ifa_addr, size);
> +             break;
> +     }
> +
> +     freeifaddrs(ifaddr_list);
> +     return err;
> +}
> +
> +static inline int bind_socket(int sk, int index, int family)
> +{
> +     char interface[IF_NAMESIZE];
> +
> +     memset(interface, 0, IF_NAMESIZE);

Why do we need this memset?

> +
> +     if (if_indextoname(index, interface) == NULL)
> +             return -1;
> +

        err = setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
                                        interface, IF_NAMESIZE);
        if (err < 0)
                err = bind_to_address(sk, interface, family);

        return err;


> +     if (bind_to_interface(sk, interface) < 0)
> +             return bind_to_address(sk, interface, family);
> +
> +     return 0;
> +}
> +
>  static int connect_session_transport(struct web_session *session)
>  {
>       GIOFlags flags;
> @@ -960,18 +1017,10 @@ static int connect_session_transport(struct 
> web_session *session)
>               return -EIO;
>  
>       if (session->web->index > 0) {
> -             char interface[IF_NAMESIZE];
> -
> -             memset(interface, 0, IF_NAMESIZE);
> -
> -             if (if_indextoname(session->web->index, interface) != NULL) {
> -                     if (setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
> -                                             interface, IF_NAMESIZE) < 0) {
> -                             close(sk);
> -                             return -EIO;
> -                     }
> -
> -                     debug(session->web, "Use interface %s", interface);
> +             if (bind_socket(sk, session->web->index,
> +                             session->addr->ai_family) < 0) {
> +                     close(sk);
> +                     return -EIO;
>               }
>       }
>  

Regards

Marcel


_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to