diff --git a/sys/include/net/conn.h b/sys/include/net/conn.h index bd03991973dbf4e1f43ac9a00068936f85b3c079..8e5a45a776e9cd3c4b4ffcac2f8a0c6887623c74 100644 --- a/sys/include/net/conn.h +++ b/sys/include/net/conn.h @@ -31,6 +31,7 @@ * @brief Application connection API definitions * * @author Martine Lenders <mlenders@inf.fu-berlin.de> + * @author Oliver Hahm <oliver.hahm@inria.fr> */ #ifndef NET_CONN_H_ #define NET_CONN_H_ @@ -38,11 +39,24 @@ #include "net/conn/ip.h" #include "net/conn/tcp.h" #include "net/conn/udp.h" +#include "net/ipv6/addr.h" #ifdef __cplusplus extern "C" { #endif +/** + * @brief Find the best matching source address for a given prefix + * + * @param[in] dst Pointer to the IPv6 address to find a match for + * Must not be NULL + * + * @return NULL if no matching address on any interface could be found + * @return pointer to an IPv6 address configured on an interface with the best + * match to @p dst + */ +ipv6_addr_t *conn_find_best_source(const ipv6_addr_t *dst); + #ifdef __cplusplus } #endif diff --git a/sys/net/gnrc/conn/gnrc_conn.c b/sys/net/gnrc/conn/gnrc_conn.c index 9a835965bb9d7d5186367805c1e4572b3c68d1d1..80fe1c9481b3e6b12e70c88ccbe8422601ea98a9 100644 --- a/sys/net/gnrc/conn/gnrc_conn.c +++ b/sys/net/gnrc/conn/gnrc_conn.c @@ -11,6 +11,7 @@ * * @file * @author Martine Lenders <mlenders@inf.fu-berlin.de> + * @author Oliver Hahm <oliver.hahm@inria.fr> */ #include "net/conn.h" @@ -85,6 +86,13 @@ bool gnrc_conn6_set_local_addr(uint8_t *conn_addr, const ipv6_addr_t *addr) } return true; } + +ipv6_addr_t *conn_find_best_source(const ipv6_addr_t *dst) +{ + ipv6_addr_t *local = NULL; + gnrc_ipv6_netif_find_by_prefix(&local, dst); + return local; +} #endif /** @} */ diff --git a/sys/posix/sockets/posix_sockets.c b/sys/posix/sockets/posix_sockets.c index 623283e6364740938fc68852326908483e8f47aa..d01466dc909b6b76aef64d565346d73eb942f14a 100644 --- a/sys/posix/sockets/posix_sockets.c +++ b/sys/posix/sockets/posix_sockets.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2015 Freie Universität Berlin + * Copyright (C) 2015 INRIA * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -11,6 +12,7 @@ * @file * @brief Providing implementation for POSIX socket wrapper. * @author Martine Lenders <mlenders@inf.fu-berlin.de> + * @author Oliver Hahm <oliver.hahm@inria.fr> * @todo */ @@ -862,11 +864,15 @@ ssize_t sendto(int socket, const void *buffer, size_t length, int flags, sport, byteorder_ntohs(port)); } else if (address != NULL) { - ipv6_addr_t local; + ipv6_addr_t unspec; + ipv6_addr_t *best_match; s->src_port = (uint16_t)genrand_uint32_range(1LU << 10U, 1LU << 16U); - /* implicitly bind the socket here */ - ipv6_addr_set_unspecified(&local); - if ((res = conn_udp_create(&s->conn.udp, &local, sizeof(local), + /* find the best matching source address */ + if ((best_match = conn_find_best_source(addr)) == NULL) { + ipv6_addr_set_unspecified(&unspec); + best_match = &unspec; + } + if ((res = conn_udp_create(&s->conn.udp, best_match, sizeof(unspec), s->domain, s->src_port)) < 0) { errno = -res; return -1;