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